feat: 新增多类功能并优化现有流程

1. 工序工位支持0号上线位,更新解析逻辑与注释
2. 物料清单模块重命名为产品物料清单并优化文案
3. WMS与工位端新增用户/角色详情抽屉组件
4. 工单模块新增自动生成工单号、工位分组选择器
5. 日排产支持批量生成与详情查看
6. 工单列表重构操作菜单与表单优化
This commit is contained in:
SunYF
2026-09-18 13:54:30 +08:00
parent bf3a408839
commit 672cd23329
17 changed files with 780 additions and 207 deletions
@@ -0,0 +1,55 @@
<template>
<el-drawer v-model="vis" :title="title" :size="size" destroy-on-close append-to-body>
<el-descriptions v-if="data" :column="column" border size="small">
<el-descriptions-item v-for="f in fields" :key="f.key" :label="f.label">
<slot v-if="f.slot" :name="f.slot" :row="data" />
<template v-else>{{ fmt(f, data) }}</template>
</el-descriptions-item>
</el-descriptions>
<el-empty v-else description="暂无数据" />
</el-drawer>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
visible: { type: Boolean, default: false },
title: { type: String, default: '详情' },
fields: { type: Array, default: () => [] },
data: { type: Object, default: null },
size: { type: String, default: '480px' },
column: { type: Number, default: 1 }
})
const emit = defineEmits(['update:visible'])
const vis = computed({
get: () => props.visible,
set: (v) => emit('update:visible', v)
})
function fmtTime(v) {
if (v === null || v === undefined || v === '') return '-'
let n = typeof v === 'string' ? Number(v) : v
if (isNaN(n)) return v
if (n > 1e12) n = Math.floor(n / 1000)
if (n <= 0) return '-'
const d = new Date(n * 1000)
const p = (x) => String(x).padStart(2, '0')
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`
}
function fmt(f, data) {
if (!data) return '-'
const v = data[f.key]
if (f.format && typeof f.format === 'function') {
const r = f.format(v, data)
return r === null || r === undefined || r === '' ? '-' : r
}
let out = v
if (f.type === 'time') out = fmtTime(v)
else if (f.type === 'bool') out = v ? '是' : '否'
else if (f.type === 'enum' && f.map) out = (f.map[v] ?? v)
if (out === null || out === undefined || out === '') return '-'
return out
}
</script>
+19 -1
View File
@@ -6,6 +6,7 @@ import request from '../utils/request'
import { fmtTime } from '../utils/format'
import { can } from '../utils/perm'
import PageHelp from '../components/PageHelp.vue'
import DetailDrawer from '../components/DetailDrawer.vue'
import { helpRole } from '../help'
const loading = ref(false)
@@ -153,6 +154,22 @@ function permSummary(arr) {
const names = codes.map((c) => codeName.value[c] || c)
return names.length > 8 ? `${names.slice(0, 8).join('、')}${names.length}` : names.join('、')
}
// 角色详情抽屉
const detail = reactive({ show: false, title: '', fields: [], row: null })
function openDetail(row) {
detail.row = row
detail.title = `角色详情 · ${row.name}`
detail.fields = [
{ key: 'id', label: 'ID' },
{ key: 'code', label: '编码' },
{ key: 'name', label: '名称' },
{ key: 'remark', label: '备注' },
{ key: 'permissionCodes', label: '权限数', format: (v) => (Array.isArray(v) ? (v.includes('*') ? '全部' : v.length + ' 项') : '-') },
{ key: 'createdAt', label: '创建时间', type: 'time' }
]
detail.show = true
}
</script>
<template>
@@ -192,8 +209,9 @@ function permSummary(arr) {
<el-table-column label="创建时间" width="160" align="center">
<template #default="{ row }">{{ fmtTime(row.createdAt) }}</template>
</el-table-column>
<el-table-column label="操作" width="140" align="center" fixed="right">
<el-table-column label="操作" width="200" align="center" fixed="right">
<template #default="{ row }">
<el-button link type="primary" size="small" @click="openDetail(row)">详情</el-button>
<el-button v-if="can('role:edit')" link type="primary" size="small" :disabled="row.code === 'admin'" @click="openEdit(row)">编辑权限</el-button>
<el-button v-if="can('role:delete')" link type="danger" size="small"
:disabled="['admin', 'operator', 'inspector'].includes(row.code)" @click="removeRole(row)">删除</el-button>
@@ -5,6 +5,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
import request from '../utils/request'
import { fmtTime } from '../utils/format'
import { can } from '../utils/perm'
import DetailDrawer from '../components/DetailDrawer.vue'
// 角色数据源:实时取自角色表(含自定义角色),code/name 与 RoleManage 同源
const roles = ref([])
@@ -187,8 +188,9 @@ onMounted(() => {
<el-table-column label="创建时间" width="155" align="center">
<template #default="{ row }">{{ row.createdAt ? fmtTime(row.createdAt) : '-' }}</template>
</el-table-column>
<el-table-column label="操作" width="150" align="center" fixed="right">
<el-table-column label="操作" width="210" align="center" fixed="right">
<template #default="{ row }">
<el-button link type="primary" size="small" @click="openDetail(row)">详情</el-button>
<el-button v-if="can('user:edit')" link type="primary" size="small" :disabled="row.username === 'admin'"
@click="openEdit(row)">编辑</el-button>
<el-button v-if="can('user:delete')" link type="danger" size="small" :disabled="row.username === 'admin'"
@@ -231,6 +233,9 @@ onMounted(() => {
<el-button type="primary" :loading="saving" @click="save">保存</el-button>
</template>
</el-dialog>
<DetailDrawer :visible="detail.show" @update:visible="detail.show = $event"
:title="detail.title" :fields="detail.fields" :data="detail.row" />
</div>
</template>