feat: 完成产线与仓储系统多模块迭代升级
本次迭代覆盖MES与WMS核心业务: 1. 新增接驳台托盘传感器读取与AGV对接能力 2. 完善工单排产、备料流程与权限体系拆分 3. 优化看板接口与前端路由、样式 4. 新增操作日志、库存盘点与角色保护逻辑 5. 修复代理地址、BOM保存等已知问题
This commit is contained in:
@@ -20,8 +20,16 @@
|
||||
<el-table-column prop="planDate" label="排产日期" width="120" />
|
||||
<el-table-column prop="planQty" label="计划数量" width="100" />
|
||||
<el-table-column prop="completedQty" label="已完成" width="90" />
|
||||
<el-table-column label="状态" width="100">
|
||||
<template #default="{ row }">{{ statusText(row.status) }}</template>
|
||||
<el-table-column label="送达接驳台" min-width="150">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-for="d in (row.dockCodes||[])" :key="d" size="small" class="dock-tag">{{ d }}</el-tag>
|
||||
<span v-if="!(row.dockCodes||[]).length" class="dock-empty">未指定</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="执行状态" width="110">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="planStatusTag(row.status)" size="small">{{ statusText(row.status) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="operator" label="操作人" min-width="90" />
|
||||
<el-table-column label="操作" width="160">
|
||||
@@ -32,10 +40,10 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-dialog v-model="dialog.show" title="新建/编辑排产" width="460px">
|
||||
<el-dialog v-model="dialog.show" title="新建/编辑排产" width="520px">
|
||||
<el-form :model="dialog" label-width="90px">
|
||||
<el-form-item label="工单号">
|
||||
<el-select v-model="dialog.orderNo" filterable allow-create placeholder="请选择/输入工单号" style="width:100%">
|
||||
<el-select v-model="dialog.orderNo" filterable allow-create placeholder="请选择/输入工单号" style="width:100%" @change="loadSuggest">
|
||||
<el-option v-for="w in workOrders" :key="w.workOrderNo" :label="w.workOrderNo" :value="w.workOrderNo" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -45,6 +53,17 @@
|
||||
<el-form-item label="计划数量">
|
||||
<el-input-number v-model="dialog.planQty" :min="1" style="width:100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="送达接驳台" prop="dockCodes">
|
||||
<el-select v-model="dialog.dockCodes" multiple filterable clearable placeholder="该工单物料送达哪些接驳台(可多选)" style="width:100%">
|
||||
<el-option-group label="产线接驳台(DOCK n↔工位n)">
|
||||
<el-option v-for="n in 20" :key="n" :label="`DOCK${String(n).padStart(2,'0')} · 工位${n}`" :value="`DOCK${String(n).padStart(2,'0')}`" />
|
||||
</el-option-group>
|
||||
<el-option-group label="库房">
|
||||
<el-option label="DOCK21 · 库房收货" value="DOCK21" />
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
<div class="dock-tip">选需送达的接驳台;建议为当前工单上次使用的接驳台</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialog.show=false">取消</el-button>
|
||||
@@ -55,6 +74,12 @@
|
||||
<PageHelp :data="helpDailyPlan" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.dock-tag { margin-right: 4px; }
|
||||
.dock-empty { color: #999; font-size: 12px; }
|
||||
.dock-tip { width: 100%; font-size: 12px; color: #888780; line-height: 1.5; }
|
||||
</style>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
@@ -66,26 +91,40 @@ import { helpDailyPlan } from '../help'
|
||||
const query = reactive({ orderNo: '', planDate: '' })
|
||||
const list = ref([])
|
||||
const workOrders = ref([])
|
||||
const dialog = reactive({ show: false, id: 0, orderNo: '', planDate: '', planQty: 1 })
|
||||
const dialog = reactive({ show: false, id: 0, orderNo: '', planDate: '', planQty: 1, dockCodes: [] })
|
||||
|
||||
const dockOptions = [...Array.from({ length: 20 }, (_, i) => `DOCK${String(i + 1).padStart(2, '0')}`), 'DOCK21']
|
||||
const statusOptions = [
|
||||
{ v: 'PENDING', l: '待排产' }, { v: 'CONFIRMED', l: '已确认' }
|
||||
{ v: 'PENDING', l: '待执行' }, { v: 'PROCESSING', l: '执行中' },
|
||||
{ v: 'DONE', l: '已完成' }, { v: 'CANCELLED', l: '已取消' }
|
||||
]
|
||||
const statusText = (s) => (statusOptions.find((x) => x.v === s) || {}).l || s
|
||||
const planStatusTag = (s) =>
|
||||
s === 'DONE' ? 'success' : s === 'CANCELLED' ? 'info' : s === 'PROCESSING' ? 'warning' : 'primary'
|
||||
|
||||
async function load() {
|
||||
list.value = (await request.get('/daily-plans', { params: query })) || []
|
||||
}
|
||||
// 推荐:该工单上次使用的接驳台
|
||||
async function loadSuggest() {
|
||||
if (!dialog.orderNo) return
|
||||
try {
|
||||
const d = await request.get('/daily-plans/suggest-docks', { params: { orderNo: dialog.orderNo } })
|
||||
dialog.dockCodes = d?.dockCodes || []
|
||||
} catch { dialog.dockCodes = [] }
|
||||
}
|
||||
function openAdd() {
|
||||
Object.assign(dialog, { show: true, id: 0, orderNo: '', planDate: new Date().toISOString().slice(0, 10), planQty: 1 })
|
||||
Object.assign(dialog, { show: true, id: 0, orderNo: '', planDate: new Date().toISOString().slice(0, 10), planQty: 1, dockCodes: [] })
|
||||
}
|
||||
function openEdit(row) {
|
||||
Object.assign(dialog, { show: true, id: row.id, orderNo: row.orderNo, planDate: row.planDate, planQty: row.planQty })
|
||||
Object.assign(dialog, { show: true, id: row.id, orderNo: row.orderNo, planDate: row.planDate, planQty: row.planQty, dockCodes: row.dockCodes || [] })
|
||||
}
|
||||
async function save() {
|
||||
if (!dialog.orderNo || !dialog.planDate) return ElMessage.warning('请选择工单号和排产日期')
|
||||
if (dialog.id) await request.put(`/daily-plans/${dialog.id}`, { ...dialog })
|
||||
else await request.post('/daily-plans', { orderNo: dialog.orderNo, planDate: dialog.planDate, planQty: dialog.planQty })
|
||||
if (!dialog.dockCodes.length) return ElMessage.warning('请确认送达接驳台(AGV 配送目标)')
|
||||
const payload = { orderNo: dialog.orderNo, planDate: dialog.planDate, planQty: dialog.planQty, dockCodes: dialog.dockCodes }
|
||||
if (dialog.id) await request.put(`/daily-plans/${dialog.id}`, payload)
|
||||
else await request.post('/daily-plans', payload)
|
||||
ElMessage.success('保存成功')
|
||||
dialog.show = false
|
||||
load()
|
||||
|
||||
Reference in New Issue
Block a user