1. 生产模块按工序拆分为两个一级菜单 - 生产-前缫(落丝记录)、生产-后缫(纤度检验、黑板检验) - 旧的「生产管理」(/prod) 目录及子菜单由种子自动清理,页面组件与权限标识保持不变 - 消息中心跳转路径、首页快捷入口路径同步更新 2. 职工管理独立为一级菜单(原挂在「基础数据」目录下),并清理历史子菜单 3. 修复侧边栏菜单展开卡顿(基础数据等子项较多的目录尤其明显) - 去掉 Element Plus 的 height 过渡动画(会逐帧重排全部子项) - 收起时改用 height:0 + visibility:hidden 而非 display:none,子项提前完成布局 - 菜单区独立滚动并预留滚动条宽度(scrollbar-gutter),消除展开时的横向抖动 - 菜单项增加 contain 布局隔离,淡入动画改为容器级 4. 修复页面首次打开重复请求 - 分页组件挂载时会触发一次 current-change,页码未变化时不再重复加载(18 个页面) - 职工管理去掉 onMounted 与默认选中部门的重复加载 - 工种管理、原料庄口的注册表下拉由按 key 多次请求改为一次全量拉取 5. 后端增加前端静态托管与 SPA 路由回退,支持 IIS 单站点部署(前后端同源) 6. 新增部署脚本 deploy-iis.ps1(首次部署)与 update-iis.ps1(更新发布)
171 lines
6.8 KiB
Vue
171 lines
6.8 KiB
Vue
<script setup>
|
|
import { ref, reactive, onMounted } from 'vue';
|
|
import request from '../../../utils/request';
|
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
|
|
|
const list = ref([]);
|
|
const total = ref(0);
|
|
const loading = ref(false);
|
|
const guigeOptions = ref([]);
|
|
const query = reactive({ pageIndex: 1, pageSize: 20, keyword: '', standard: null, guige: '' });
|
|
|
|
const dialogVisible = ref(false);
|
|
const dialogTitle = ref('新增指标');
|
|
const isEdit = ref(false);
|
|
const editId = ref(null);
|
|
const form = reactive({
|
|
standard: 0, guige: '', grade: '', gradeScore: 0, piancha: 0, dacha: 0, erdu: 0, sandu: 0, qingjie: 0, jiejing: 0
|
|
});
|
|
|
|
const standardOptions = [
|
|
{ label: '厂标', value: 0 },
|
|
{ label: '国标', value: 1 },
|
|
{ label: '个人', value: 2 }
|
|
];
|
|
|
|
async function load() {
|
|
loading.value = true;
|
|
try {
|
|
const res = await request.get('/shengsidingjizhibiao', { params: query });
|
|
list.value = res.data.items;
|
|
total.value = res.data.total;
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
}
|
|
|
|
async function loadGuige() {
|
|
const res = await request.get('/shengsiguige/all');
|
|
guigeOptions.value = res.data;
|
|
}
|
|
|
|
function openCreate() {
|
|
isEdit.value = false;
|
|
dialogTitle.value = '新增指标';
|
|
Object.assign(form, { standard: 0, guige: guigeOptions.value[0] || '', grade: '', gradeScore: 0, piancha: 0, dacha: 0, erdu: 0, sandu: 0, qingjie: 0, jiejing: 0 });
|
|
dialogVisible.value = true;
|
|
}
|
|
|
|
function openEdit(row) {
|
|
isEdit.value = true;
|
|
editId.value = row.id;
|
|
dialogTitle.value = '编辑指标';
|
|
const { id, standardName, ...rest } = row;
|
|
Object.assign(form, rest);
|
|
dialogVisible.value = true;
|
|
}
|
|
|
|
async function save() {
|
|
if (!form.grade) { ElMessage.warning('请输入等级'); return; }
|
|
try {
|
|
if (isEdit.value) {
|
|
await request.put(`/shengsidingjizhibiao/${editId.value}`, form);
|
|
ElMessage.success('更新成功');
|
|
} else {
|
|
await request.post('/shengsidingjizhibiao', form);
|
|
ElMessage.success('创建成功');
|
|
}
|
|
dialogVisible.value = false;
|
|
load();
|
|
} catch (e) {}
|
|
}
|
|
|
|
async function del(row) {
|
|
await ElMessageBox.confirm(`确定删除等级「${row.grade}」吗?`, '提示', { type: 'warning' });
|
|
try {
|
|
await request.delete(`/shengsidingjizhibiao/${row.id}`);
|
|
ElMessage.success('删除成功');
|
|
load();
|
|
} catch (e) {}
|
|
}
|
|
|
|
function handlePageChange(p) {
|
|
// 分页组件挂载时会触发一次 current-change,页码未变化时忽略,避免首次打开重复请求
|
|
if (p === query.pageIndex) return;
|
|
query.pageIndex = p;
|
|
load();
|
|
}
|
|
onMounted(() => { load(); loadGuige(); });
|
|
</script>
|
|
|
|
<template>
|
|
<el-card shadow="never">
|
|
<template #header>
|
|
<div class="card-header">
|
|
<span>生丝定级指标</span>
|
|
<el-button type="primary" @click="openCreate">新增指标</el-button>
|
|
</div>
|
|
</template>
|
|
|
|
<div class="search-bar">
|
|
<el-select v-model="query.standard" clearable placeholder="标准" style="width: 120px">
|
|
<el-option v-for="s in standardOptions" :key="s.value" :label="s.label" :value="s.value" />
|
|
</el-select>
|
|
<el-select v-model="query.guige" clearable placeholder="规格" style="width: 140px">
|
|
<el-option v-for="g in guigeOptions" :key="g" :label="g" :value="g" />
|
|
</el-select>
|
|
<el-input v-model="query.keyword" placeholder="等级" clearable style="width: 140px" @keyup.enter="query.pageIndex=1;load()" />
|
|
<el-button type="primary" @click="query.pageIndex=1;load()">搜索</el-button>
|
|
<el-button @click="Object.assign(query,{keyword:'',standard:null,guige:'',pageIndex:1});load()">重置</el-button>
|
|
</div>
|
|
|
|
<el-table v-loading="loading" :data="list" border stripe>
|
|
<el-table-column label="标准" width="80">
|
|
<template #default="{ row }">
|
|
<el-tag size="small">{{ row.standardName }}</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="guige" label="规格" width="90" />
|
|
<el-table-column prop="grade" label="等级" width="90" />
|
|
<el-table-column prop="gradeScore" label="等级分值" width="90" />
|
|
<el-table-column prop="piancha" label="偏差" width="80" />
|
|
<el-table-column prop="dacha" label="大差" width="80" />
|
|
<el-table-column prop="erdu" label="二度变化" width="90" />
|
|
<el-table-column prop="sandu" label="三度变化" width="90" />
|
|
<el-table-column prop="qingjie" label="清洁" width="80" />
|
|
<el-table-column prop="jiejing" label="洁净" width="80" />
|
|
<el-table-column label="操作" width="140" fixed="right">
|
|
<template #default="{ row }">
|
|
<el-button size="small" type="primary" @click="openEdit(row)">编辑</el-button>
|
|
<el-button size="small" type="danger" @click="del(row)">删除</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
|
|
<el-pagination class="pagination" :current-page="query.pageIndex" :page-size="query.pageSize" :total="total" layout="total, prev, pager, next" @current-change="handlePageChange" />
|
|
|
|
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="560px">
|
|
<el-form :model="form" label-width="100px">
|
|
<el-form-item label="标准">
|
|
<el-radio-group v-model="form.standard">
|
|
<el-radio-button v-for="s in standardOptions" :key="s.value" :value="s.value">{{ s.label }}</el-radio-button>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
<el-form-item label="规格">
|
|
<el-select v-model="form.guige" style="width: 100%">
|
|
<el-option v-for="g in guigeOptions" :key="g" :label="g" :value="g" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="等级"><el-input v-model="form.grade" /></el-form-item>
|
|
<el-form-item label="等级分值"><el-input-number v-model="form.gradeScore" :precision="1" /></el-form-item>
|
|
<el-form-item label="偏差"><el-input-number v-model="form.piancha" :precision="2" /></el-form-item>
|
|
<el-form-item label="大差"><el-input-number v-model="form.dacha" :precision="2" /></el-form-item>
|
|
<el-form-item label="二度变化"><el-input-number v-model="form.erdu" :precision="1" /></el-form-item>
|
|
<el-form-item label="三度变化"><el-input-number v-model="form.sandu" :precision="1" /></el-form-item>
|
|
<el-form-item label="清洁"><el-input-number v-model="form.qingjie" :precision="1" /></el-form-item>
|
|
<el-form-item label="洁净"><el-input-number v-model="form.jiejing" :precision="1" /></el-form-item>
|
|
</el-form>
|
|
<template #footer>
|
|
<el-button @click="dialogVisible = false">取消</el-button>
|
|
<el-button type="primary" @click="save">确定</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
</el-card>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.card-header { display: flex; justify-content: space-between; align-items: center; }
|
|
.search-bar { display: flex; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
|
|
.pagination { margin-top: 16px; justify-content: flex-end; }
|
|
</style>
|