feat: 新增多类功能并优化现有流程
1. 工序工位支持0号上线位,更新解析逻辑与注释 2. 物料清单模块重命名为产品物料清单并优化文案 3. WMS与工位端新增用户/角色详情抽屉组件 4. 工单模块新增自动生成工单号、工位分组选择器 5. 日排产支持批量生成与详情查看 6. 工单列表重构操作菜单与表单优化
This commit is contained in:
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user