refactor: 重构工艺工序相关命名与数据模型
1. 全局替换"工序"为"工艺"统一术语,包括页面文案、枚举、注释
2. 重构工单与工件工艺数据模型:
- 新增工艺组合表flow_material作为备料/齐套唯一源头
- 新增工位状态表station_state支持自主停单/恢复接单
- 移除station_process派工表,改用工单工艺组合作为路线唯一源头
- 替换processCode为flowId作为工艺关联标识
- 重构工件当前进度字段为currentStationNo
3. 删除冗余的静态备份资源文件
4. 调整物料选择组件默认启用仅显示激活物料
5. 优化工单创建/编辑逻辑,新增工艺组合校验与保存
This commit is contained in:
@@ -10,13 +10,13 @@ export const getConfig = () => request.get('/api/config')
|
||||
export const getTaskCurrent = (stationNo) =>
|
||||
request.get('/api/task/current', { params: { stationNo } })
|
||||
|
||||
// 装机绑定面板(代理 MES):sn+processCode → 应绑/已绑清单
|
||||
// 装机绑定面板(代理 MES):sn+flowId → 应绑/已绑清单
|
||||
export const getBindPanel = (params) => request.get('/api/bind/panel', { params })
|
||||
|
||||
// 装机绑定一条(代理 MES):{sn, processCode, stationNo, items:[{materialCode, bindValue}]}
|
||||
// 装机绑定一条(代理 MES):{sn, flowId, stationNo, items:[{materialCode, bindValue}]}
|
||||
export const bindRecord = (data) => request.post('/api/bind/record', data)
|
||||
|
||||
// 撤销一条绑定(代理 MES):{sn, processCode, materialCode, bindValue}
|
||||
// 撤销一条绑定(代理 MES):{sn, flowId, materialCode, bindValue}
|
||||
export const bindRemove = (data) => request.post('/api/bind/remove', data)
|
||||
|
||||
// 我的工作量(代理 MES,按当前登录人查询)
|
||||
@@ -29,7 +29,7 @@ export const getTighteningList = (params) => request.get('/api/tightening/list',
|
||||
// {sn, workOrderNo, stepId, stepName, screwNo, torque, angle, result, operator}
|
||||
export const submitTorque = (data) => request.post('/api/tightening/record', data)
|
||||
|
||||
// 工序完成上报
|
||||
// 工艺完成上报
|
||||
export const reportProcessDone = (data) => request.post('/api/report/process-done', data)
|
||||
|
||||
// 暂存退库上报
|
||||
@@ -109,11 +109,18 @@ export const getBom = (params) => request.get('/api/bom', { params })
|
||||
// 工单查询(选工单带出产品编码/名称):{orderNo}
|
||||
export const queryOrder = (params) => request.get('/api/order/query', { params })
|
||||
|
||||
// 工件追溯(下线完工扫SN展示状态/工序时间线/拧紧):{sn}
|
||||
// 工件追溯(下线完工扫SN展示状态/工艺时间线/拧紧):{sn}
|
||||
export const getTrace = (params) => request.get('/api/trace', { params })
|
||||
|
||||
// 上线建档:{sn, orderNo, workOrderId, processSeq, operator}
|
||||
export const onlineRegister = (data) => request.post('/api/workpiece/online', data)
|
||||
|
||||
// 下线完工入库:{sn, batchItems, serialItems, operator}
|
||||
export const offlineFinish = (data) => request.post('/api/workpiece/done', data)
|
||||
export const offlineFinish = (data) => request.post('/api/workpiece/done', data)
|
||||
|
||||
// ---------- 工位停单 / 恢复接单(代理 MES 内部 API) ----------
|
||||
// 停单/恢复:{stationNo, paused, reason}(paused=true 停止接单,false 恢复)
|
||||
export const pauseStation = (data) => request.post('/api/station/pause', data)
|
||||
|
||||
// 当天停单状态:?date=yyyy-MM-dd(缺省当天)→ [{stationNo,paused,reason,operator}]
|
||||
export const getStationState = (params) => request.get('/api/station/state', { params })
|
||||
@@ -5,14 +5,14 @@
|
||||
export const helpWorkstation = {
|
||||
title: '工位终端 使用说明',
|
||||
overview:
|
||||
'工位终端运行在 DOCK01~21 各工序工位的触屏设备上,是产线最一线的执行入口。\n\n标准流程:①确认本工位号 → ②扫描工件 SN → ③照工艺图纸用拧紧枪打螺丝 → ④看拧紧结果是否全部 OK → ⑤点「工序完成上报」→ 工件流转到下一工序。\n\n数据链路:下发任务(MES) → 扫码(MES工位任务) → 拧紧结果(丹尼科尔拧紧枪采集,本地SQLite缓存) → 工序完成上报(MES) → 拧紧/追溯数据回到 MES 管理后台。',
|
||||
'工位终端运行在 DOCK01~21 各工艺工位的触屏设备上,是产线最一线的执行入口。\n\n标准流程:①确认本工位号 → ②扫描工件 SN → ③照工艺图纸用拧紧枪打螺丝 → ④看拧紧结果是否全部 OK → ⑤点「报工完成」→ 工件流转到下一工位。\n\n数据链路:下发任务(MES) → 扫码(MES工位任务) → 拧紧结果(丹尼科尔拧紧枪采集,本地SQLite缓存) → 工艺完成上报(MES) → 拧紧/追溯数据回到 MES 管理后台。',
|
||||
sections: [
|
||||
{
|
||||
title: '顶部与工位',
|
||||
overview: '顶部显示当前工位号、登录人、离线同步状态。',
|
||||
fields: [
|
||||
{ name: '工位号', source: '下拉选择/固定。数据来自本机配置或固定的 DOCK01~21。', purpose: '当前所在工位,决定读取哪道工序的任务', fill: '固定工位由配置锁定不可改;否则选与实际工位一致编号' },
|
||||
{ name: '待同步 N 条', source: '系统统计。数据来自本地 SQLite 中尚未上传的记录数。', purpose: '标记有拧紧/工序数据没上报 MES(离线缓存)', fill: '点「重试同步」立即补传;消红为正常' },
|
||||
{ name: '工位号', source: '下拉选择/固定。数据来自本机配置或固定的 DOCK01~21。', purpose: '当前所在工位,决定读取哪道工艺的任务', fill: '固定工位由配置锁定不可改;否则选与实际工位一致编号' },
|
||||
{ name: '待同步 N 条', source: '系统统计。数据来自本地 SQLite 中尚未上传的记录数。', purpose: '标记有拧紧/工艺数据没上报 MES(离线缓存)', fill: '点「重试同步」立即补传;消红为正常' },
|
||||
{ name: '登录人', source: '登录账号。来自工位终端登录时输入。', purpose: '当前操作员,上报记录会带此名字溯源', fill: '开机登入本人账号,勿共用' }
|
||||
]
|
||||
},
|
||||
@@ -25,13 +25,13 @@ export const helpWorkstation = {
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '当前工单与工序',
|
||||
overview: '左栏显示本工位当前装配任务的工单号、产品型号、整件进度和工序清单。',
|
||||
title: '当前工单与工艺',
|
||||
overview: '左栏显示本工位当前装配任务的工单号、产品型号、整件进度和工艺步骤。',
|
||||
fields: [
|
||||
{ name: '工单号', source: 'MES 派发。数据来自 MES 下发给本工位的当前任务。', purpose: '正在装配的生产工单,工序/工艺都按它来', fill: '不可改,随任务自动带出' },
|
||||
{ name: '工序清单', source: 'MES 工艺配置。数据来自工单的工序组合(MES下发)。', purpose: '12 道工序任务,✔=已完成,高亮=当前应做工序', fill: '照高亮工序执行,不用手工勾选' },
|
||||
{ name: '工艺图纸', source: 'MES 下发 PDF。工单配置的工艺文件。', purpose: '当前工序的工艺图/拧紧点位,指导怎么打螺丝', fill: '点「放大查看」全屏看图,照图示点位顺序拧' },
|
||||
{ name: '查看本步骤图纸', source: 'MES 工艺配置。每道工序步骤绑定的图纸附件(MES 下发)。', purpose: '按当前步骤精准调出对应图纸,避免看错工序的图', fill: '在对应步骤上点「查看本步骤图纸」弹窗查看,照图施工' }
|
||||
{ name: '工单号', source: 'MES 派发。数据来自 MES 下发给本工位的当前任务。', purpose: '正在装配的生产工单,工艺路线都按它来', fill: '不可改,随任务自动带出' },
|
||||
{ name: '工艺步骤', source: 'MES 工艺配置。数据来自工位绑定工艺+工单工艺组合(MES下发)。', purpose: '工艺步骤任务,✔=已完成,高亮=当前应做步骤', fill: '照高亮步骤执行,不用手工勾选' },
|
||||
{ name: '工艺图纸', source: 'MES 下发 PDF。工单配置的工艺文件。', purpose: '当前工艺的图纸/拧紧点位,指导怎么打螺丝', fill: '点「放大查看」全屏看图,照图示点位顺序拧' },
|
||||
{ name: '查看本步骤图纸', source: 'MES 工艺配置。每道工艺步骤绑定的图纸附件(MES 下发)。', purpose: '按当前步骤精准调出对应图纸,避免看错步骤的图', fill: '在对应步骤上点「查看本步骤图纸」弹窗查看,照图施工' }
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -39,7 +39,7 @@ export const helpWorkstation = {
|
||||
overview: '作业页 SN 卡片下方列出当前工位正在加工/等待的工件,点击可快速切换继续填报。',
|
||||
fields: [
|
||||
{ name: '在制品列表', source: 'MES 实时查询。数据来自 MES「在制工件」接口按本工位号过滤。', purpose: '看清本工位还有哪些工件在做/待做,防止漏件', fill: '点列表中某一行即把该 SN 带入扫码框,继续未完成步骤的填报' },
|
||||
{ name: '进度 N/M', source: 'MES 统计。已完成步骤数 / 该工序总步骤数。', purpose: '一眼看出每件在制品做到第几步', fill: '只读展示,随填报自动更新' }
|
||||
{ name: '进度 N/M', source: 'MES 统计。已完成步骤数 / 该工艺总步骤数。', purpose: '一眼看出每件在制品做到第几步', fill: '只读展示,随填报自动更新' }
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -54,25 +54,25 @@ export const helpWorkstation = {
|
||||
{
|
||||
title: '底部三大按钮',
|
||||
fields: [
|
||||
{ name: '工序完成上报', source: '按钮操作 + 确认框。数据上报到 MES。', purpose: '本工位这道工序做完,通知 MES 流转到下一工序', fill: '点后输入当前工序号(如 OP10)确认;联网失败自动离线缓存' },
|
||||
{ name: '暂存退库', source: '按钮操作 + 确认框。数据上报到 MES(记录已完成工序)。', purpose: '工件本工序不做完,退回库房暂存', fill: '点击并二次确认;系统记录已完成工序,重上线从下一工序继续' },
|
||||
{ name: '报工完成', source: '按钮操作 + 确认框。数据上报到 MES。', purpose: '本工位这道工艺做完,通知 MES 流转到下一工位', fill: '点「报工完成」二次确认;联网失败自动离线缓存' },
|
||||
{ name: '暂存退库', source: '按钮操作 + 确认框。数据上报到 MES(记录已完成工艺)。', purpose: '工件本工艺不做完,退回库房暂存', fill: '点击并二次确认;系统记录已完成工艺,重上线从下一工位继续' },
|
||||
{ name: '重试同步', source: '按钮操作。数据从本地 SQLite 补传到 MES。', purpose: '把离线缓存的数据立即补传给 MES', fill: '看到「待同步」非 0 时点一下即可' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// 工艺文件页(按工序步骤展示图纸,5.1)
|
||||
// 工艺文件页(按工艺步骤展示图纸,5.1)
|
||||
export const helpPdf = {
|
||||
title: '工艺文件 使用说明',
|
||||
overview:
|
||||
'工艺文件页把本工序的每一道步骤对应的图纸附件按顺序列出,左侧步骤列表、右侧图纸预览。\n\n当前应做步骤会自动高亮并定位到对应图纸,也支持整流程工艺 PDF 兜底查看。',
|
||||
'工艺文件页把本工艺的每一道步骤对应的图纸附件按顺序列出,左侧步骤列表、右侧图纸预览。\n\n当前应做步骤会自动高亮并定位到对应图纸,也支持整流程工艺 PDF 兜底查看。',
|
||||
sections: [
|
||||
{
|
||||
title: '步骤图纸',
|
||||
overview: '每道工序步骤绑定的图纸附件由 MES 工艺配置下发。',
|
||||
overview: '每道工艺步骤绑定的图纸附件由 MES 工艺配置下发。',
|
||||
fields: [
|
||||
{ name: '步骤列表', source: 'MES 工艺配置。工序步骤 + 每步骤绑定的图纸附件。', purpose: '按工序顺序逐步骤查看对应图纸,照图施工', fill: '点左侧任一步骤即在右侧预览该步骤图纸;当前步骤自动高亮' },
|
||||
{ name: '步骤列表', source: 'MES 工艺配置。工艺步骤 + 每步骤绑定的图纸附件。', purpose: '按步骤顺序逐步骤查看对应图纸,照图施工', fill: '点左侧任一步骤即在右侧预览该步骤图纸;当前步骤自动高亮' },
|
||||
{ name: '图纸预览', source: 'MES 文件服务。工位终端代理拉取并本地缓存。', purpose: '查看当前步骤的装配图/拧紧点位图', fill: '右侧自动加载,无需操作;网络异常时稍候自动重试' },
|
||||
{ name: '整流程 PDF', source: 'MES 下发。工单配置的整份工艺文件。', purpose: '当步骤无单独图纸时,兜底查看整份工艺 PDF', fill: '无步骤图纸时自动展示整流程 PDF' }
|
||||
]
|
||||
@@ -106,7 +106,7 @@ export const helpOnline = {
|
||||
title: '工件 SN 与建档提交',
|
||||
overview: 'SN 是成品唯一编号,进线登记即系统发号,全程可追溯。',
|
||||
fields: [
|
||||
{ name: '工件 SN', source: '扫码枪扫描 / 系统自动生成。', purpose: '唯一识别本台成品,拧紧/工序/追溯都挂在此 SN 下', fill: '用扫码枪扫条码,或点「自动生成」由系统发号' },
|
||||
{ name: '工件 SN', source: '扫码枪扫描 / 系统自动生成。', purpose: '唯一识别本台成品,拧紧/工艺/追溯都挂在此 SN 下', fill: '用扫码枪扫条码,或点「自动生成」由系统发号' },
|
||||
{ name: '上线位在制品', source: 'MES 实时查询。工位号 0 的在制工件。', purpose: '看清已建档待流转的工件,防止重复建档', fill: '只读展示,点「刷新」更新' },
|
||||
{ name: '确认建档上线', source: '按钮操作 + 确认框。数据上报到 MES。', purpose: '正式建档上线,工件进入产线待第 1 工位加工', fill: '满足工单/SN/领料核对后点击并二次确认;MES 不可达时自动离线缓存重传' }
|
||||
]
|
||||
@@ -118,14 +118,14 @@ export const helpOnline = {
|
||||
export const helpOffline = {
|
||||
title: '下线完工 使用说明',
|
||||
overview:
|
||||
'下线完工运行在产线出料口(工位号 13)。工件走完全部装配工序后在此核对完工状态、终检结果,确认合格后入库并回流 WMS 成品库存。\n\n标准流程:①扫描工件 SN → ②查看完工状态/工序时间线/拧紧结果/步骤不合格项 → ③确认合格后点「确认完工入库(回流 WMS)」。\n\n数据链路:追溯/拧紧/工序(MES) → 完工确认(MES 置 DONE) → 成品库存回流(WMS)。',
|
||||
'下线完工运行在产线出料口(工位号 13)。工件走完全部装配工艺后在此核对完工状态、终检结果,确认合格后入库并回流 WMS 成品库存。\n\n标准流程:①扫描工件 SN → ②查看完工状态/工艺时间线/拧紧结果/步骤不合格项 → ③确认合格后点「确认完工入库(回流 WMS)」。\n\n数据链路:追溯/拧紧/工艺(MES) → 完工确认(MES 置 DONE) → 成品库存回流(WMS)。',
|
||||
sections: [
|
||||
{
|
||||
title: '完工状态核对',
|
||||
overview: '扫描 SN 后汇总展示该工件的全流程完工情况,作为入库判定依据。',
|
||||
fields: [
|
||||
{ name: '工件状态', source: 'MES 查询。工件当前流转状态。', purpose: '确认工件是否已完工,避免重复入库', fill: '只读;显示「已完工」则无需再操作' },
|
||||
{ name: '已完成工序', source: 'MES 工序时间线。', purpose: '核对是否走完全部应做工序', fill: '只读;工序数应与工艺路线一致' },
|
||||
{ name: '已完成工艺', source: 'MES 工艺时间线。', purpose: '核对是否走完全部应做工艺', fill: '只读;工艺数应与工艺路线一致' },
|
||||
{ name: '拧紧 N/M 合格', source: 'MES 拧紧记录汇总。', purpose: '确认全部螺丝拧紧合格', fill: '只读;有不合格需先返修复检再入库' },
|
||||
{ name: '步骤不合格 N 项', source: 'MES 步骤采集数据。', purpose: '提示过程检中是否存在不合格步骤', fill: '只读;大于 0 时须确认已处理再入库' }
|
||||
]
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
// 工位终端全局状态(模块级单例)
|
||||
// 终端一个工位一个进程:工位号由服务端配置固定,前端不可修改。
|
||||
// 状态集中在这里,作业/物料/移料/工艺各面板共享,避免多份轮询与状态不一致。
|
||||
import { computed, reactive } from 'vue'
|
||||
import { computed, reactive, watch } from 'vue'
|
||||
import {
|
||||
getBindPanel,
|
||||
getConfig,
|
||||
getLineMoves,
|
||||
getLinePoints,
|
||||
getStationState,
|
||||
getSyncStats,
|
||||
getTaskCurrent,
|
||||
getTighteningList,
|
||||
getWip,
|
||||
issueLineMove,
|
||||
occupyLinePoint,
|
||||
pauseStation,
|
||||
submitTorque
|
||||
} from '../api'
|
||||
import { getUser } from '../utils/request'
|
||||
@@ -32,6 +34,8 @@ export const state = reactive({
|
||||
stepChecks: {},
|
||||
bindInputs: {},
|
||||
startedAt: '',
|
||||
paused: false,
|
||||
pauseReason: '',
|
||||
lastError: ''
|
||||
})
|
||||
|
||||
@@ -54,6 +58,9 @@ export const tightRows = computed(() => state.tightRows)
|
||||
export const wip = computed(() => state.wip)
|
||||
// 进工位(上料)时刻——作业时长起点(P0-3),报工时随载荷上传 MES
|
||||
export const startedAt = computed(() => state.startedAt)
|
||||
// 停单状态(当天):工人可停止/恢复接单,停单期间阻止新的报工提交
|
||||
export const paused = computed(() => state.paused)
|
||||
export const pauseReason = computed(() => state.pauseReason)
|
||||
|
||||
// 当前步骤(5.1 工艺文件高亮):第一个尚未录入的手填步骤;全部录入后回退到首个步骤
|
||||
export const currentStep = computed(() => {
|
||||
@@ -85,6 +92,8 @@ export const missingTorqueSteps = computed(
|
||||
export const orderNos = computed(() => (Array.isArray(state.task?.orderNos) ? state.task.orderNos : []))
|
||||
export const flowName = computed(() => state.task?.flow?.name || '-')
|
||||
export const flowActive = computed(() => !!state.task?.flowActive)
|
||||
// 本工位绑定的工艺 ID(station.flowId,随任务下发):装机绑定/报工一律按 flowId 查询与上报
|
||||
export const flowId = computed(() => Number(state.task?.flowId || 0))
|
||||
|
||||
// 本工位的产线点位台账(唯一事实源:本工位当前是否有工件)
|
||||
export const myPoint = computed(() =>
|
||||
@@ -133,7 +142,7 @@ export const missingSteps = computed(() =>
|
||||
return v === null || v === undefined || v === ''
|
||||
})
|
||||
)
|
||||
// 绑定是否齐套(本工序未配置需绑物料时不拦截)
|
||||
// 绑定是否齐套(本工艺未配置需绑物料时不拦截)
|
||||
export const bindBlocking = computed(
|
||||
() => !!(state.bindPanel && state.bindPanel.enabled && !state.bindPanel.complete)
|
||||
)
|
||||
@@ -141,6 +150,8 @@ export const canReport = computed(
|
||||
() =>
|
||||
!!state.currentSn &&
|
||||
!!state.orderNo &&
|
||||
flowId.value > 0 &&
|
||||
!state.paused &&
|
||||
!bindBlocking.value &&
|
||||
missingSteps.value.length === 0 &&
|
||||
missingChecks.value.length === 0 &&
|
||||
@@ -259,13 +270,13 @@ export async function submitTorqueStep(step, torque, angle) {
|
||||
}
|
||||
|
||||
export async function loadBind() {
|
||||
const code = Number(state.stationNo)
|
||||
if (!state.currentSn || !code) {
|
||||
const fid = flowId.value
|
||||
if (!state.currentSn || !fid) {
|
||||
state.bindPanel = null
|
||||
return
|
||||
}
|
||||
try {
|
||||
const p = await getBindPanel({ sn: state.currentSn, processCode: code })
|
||||
const p = await getBindPanel({ sn: state.currentSn, flowId: fid })
|
||||
state.bindPanel = p
|
||||
;(p?.required || []).forEach((r) => {
|
||||
if (state.bindInputs[r.materialCode] === undefined) state.bindInputs[r.materialCode] = ''
|
||||
@@ -294,7 +305,35 @@ export async function loadWip(atStation) {
|
||||
}
|
||||
|
||||
export function refreshAll() {
|
||||
return Promise.all([loadTask(), loadTight(), loadStats(), loadPoints(), loadWip()])
|
||||
return Promise.all([loadTask(), loadTight(), loadStats(), loadPoints(), loadWip(), loadStationState()])
|
||||
}
|
||||
|
||||
// loadStationState 拉取本工位当天的停单状态(MES /api/internal/station/state),刷新横幅与按钮。
|
||||
// 拉取失败保持现状,避免网络抖动误清停单横幅。
|
||||
export async function loadStationState() {
|
||||
if (!state.stationNo) return
|
||||
try {
|
||||
const list = await getStationState()
|
||||
const rows = Array.isArray(list) ? list : (list?.list || [])
|
||||
const mine = rows.find((s) => Number(s.stationNo) === Number(state.stationNo))
|
||||
if (mine) {
|
||||
state.paused = !!mine.paused
|
||||
state.pauseReason = mine.reason || ''
|
||||
}
|
||||
} catch { /* 静默 */ }
|
||||
}
|
||||
|
||||
// setPaused 停止接单/恢复接单:调 MES /api/internal/station/pause,成功后同步本地状态。
|
||||
// 恢复不要求原因(物料是否齐套由工人自行判断,系统不拦截恢复)。
|
||||
export async function setPaused(next, reason) {
|
||||
await pauseStation({
|
||||
stationNo: Number(state.stationNo),
|
||||
paused: !!next,
|
||||
reason: next ? (reason || '') : '',
|
||||
operator: operatorName()
|
||||
})
|
||||
state.paused = !!next
|
||||
state.pauseReason = next ? (reason || '') : ''
|
||||
}
|
||||
|
||||
// 切换工件:清空步骤录入与绑定缓存,重新加载拧紧/绑定
|
||||
@@ -347,6 +386,11 @@ export async function moveOut(sn, toPoint) {
|
||||
|
||||
export const operatorName = () => user.name || user.username || ''
|
||||
|
||||
// flowId 随任务到达后再触发一次绑定加载(上线位/首次拉到任务时 flowId 才有值)
|
||||
watch(flowId, (v) => {
|
||||
if (v > 0 && state.currentSn && !state.bindPanel) loadBind()
|
||||
})
|
||||
|
||||
// markStationArrival 记录「进工位 / 上料到本工位」时刻(作业时长起点,P0-3)。
|
||||
// 仅在尚未记录时写入,同一工件重复扫码/确认不会重置起点。
|
||||
export function markStationArrival() {
|
||||
|
||||
@@ -27,6 +27,13 @@
|
||||
<el-button size="large" type="danger" plain @click="logout">退出</el-button>
|
||||
</header>
|
||||
|
||||
<!-- 停单横幅(醒目置顶:已停止接单 + 原因,恢复接单即关闭) -->
|
||||
<transition name="fade">
|
||||
<div v-if="paused" class="pause-banner">
|
||||
⛔ 已停止接单{{ pauseReason ? ':' + pauseReason : '' }}(本工位暂停新的报工提交,作业信息不受影响)
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<!-- 不合格告警横幅 -->
|
||||
<transition name="fade">
|
||||
<div v-if="hasNg" class="alert-banner">⚠ 存在不合格,请复检!</div>
|
||||
@@ -40,7 +47,7 @@
|
||||
<OfflinePanel />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="!isVirtual" label="作业" name="work">
|
||||
<WorkPanel ref="workRef" />
|
||||
<WorkPanel ref="workRef" @call-material="tab = 'material'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="物料 / 叫料" name="material">
|
||||
<MaterialPanel />
|
||||
@@ -93,10 +100,13 @@ import {
|
||||
loadMoves,
|
||||
loadPoints,
|
||||
loadStats,
|
||||
loadStationState,
|
||||
loadTight,
|
||||
loadTask,
|
||||
loadWip,
|
||||
orderNo,
|
||||
paused,
|
||||
pauseReason,
|
||||
pendingTotal,
|
||||
refreshAll,
|
||||
sn,
|
||||
@@ -172,6 +182,7 @@ onMounted(async () => {
|
||||
loadPoints() // 点位台账 10 秒
|
||||
loadMoves()
|
||||
loadWip() // 在制品 10 秒
|
||||
loadStationState() // 停单状态 10 秒
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
@@ -233,6 +244,15 @@ onBeforeUnmount(() => {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.pause-banner {
|
||||
background: #f56c6c;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 12px;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.main-tabs {
|
||||
margin: 12px;
|
||||
min-height: calc(100vh - 140px);
|
||||
|
||||
@@ -114,8 +114,8 @@
|
||||
<el-table :data="pending" border size="large" class="call-table" v-loading="pendingLoading">
|
||||
<el-table-column label="图号" prop="materialCode" min-width="130" />
|
||||
<el-table-column label="物料名称" prop="materialName" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="工序" width="80" align="center">
|
||||
<template #default="{ row }">{{ row.processCode || '-' }}</template>
|
||||
<el-table-column label="工艺" width="80" align="center">
|
||||
<template #default="{ row }">{{ row.flowId || row.processCode || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="接驳台" prop="targetDock" width="110" align="center" />
|
||||
<el-table-column label="需求" width="100" align="center">
|
||||
@@ -148,6 +148,7 @@ import { ElMessage } from 'element-plus'
|
||||
import { bindRecord, bindRemove, callLineMaterial, getMaterialRequests, receiveMaterialRequest } from '../../api'
|
||||
import {
|
||||
bindInputs,
|
||||
flowId,
|
||||
loadBind,
|
||||
myDocks,
|
||||
operatorName,
|
||||
@@ -257,7 +258,7 @@ async function doBind(r) {
|
||||
await bindRecord({
|
||||
sn: sn.value,
|
||||
orderNo: orderNo.value || '',
|
||||
processCode: Number(stationNo.value),
|
||||
flowId: flowId.value,
|
||||
stationNo: stationNo.value,
|
||||
items: [{ materialCode: r.materialCode, bindValue: v }]
|
||||
})
|
||||
@@ -272,7 +273,7 @@ async function removeBind(r, b) {
|
||||
try {
|
||||
await bindRemove({
|
||||
sn: sn.value,
|
||||
processCode: Number(stationNo.value),
|
||||
flowId: flowId.value,
|
||||
materialCode: r.materialCode,
|
||||
bindValue: b
|
||||
})
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<b>{{ workpiece.orderNo || '-' }}</b>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="k">已完成工序</span>
|
||||
<span class="k">已完成工艺</span>
|
||||
<b>{{ doneProcessCount }} 道</b>
|
||||
</div>
|
||||
<div class="stat">
|
||||
@@ -53,10 +53,10 @@
|
||||
title="存在不合格项,请确认已完成返修/复检后再入库。" style="margin:10px 0"
|
||||
/>
|
||||
|
||||
<div class="sub-title">工序时间线</div>
|
||||
<div class="sub-title">工艺时间线</div>
|
||||
<el-table :data="processTimeline" border size="large" max-height="260">
|
||||
<el-table-column label="工序" min-width="120">
|
||||
<template #default="{ row }">{{ row.processName || ('工序' + row.processCode) }}</template>
|
||||
<el-table-column label="工艺" min-width="120">
|
||||
<template #default="{ row }">{{ row.processName || ('工艺' + (row.flowId || row.processCode || '')) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="结果" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="pdf-panel">
|
||||
<section class="card">
|
||||
<div class="card-title">
|
||||
工艺文件(按工序步骤)
|
||||
工艺文件(按工艺步骤)
|
||||
<el-tag v-if="flowName && flowName !== '-'" type="success" size="large" effect="dark">{{ flowName }}</el-tag>
|
||||
<span class="tip">点击左侧步骤查看本步骤图纸,当前步骤高亮</span>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
<template>
|
||||
<div class="work-panel">
|
||||
<!-- ⓪ 头部操作区:停止接单/恢复接单(停单仅阻止新报工,不隐藏作业信息) + 叫料 -->
|
||||
<header class="ops-bar">
|
||||
<span class="ops-lab">接单状态</span>
|
||||
<el-tag :type="paused ? 'danger' : 'success'" effect="dark" size="large">
|
||||
{{ paused ? '已停止接单' : '接单中' }}
|
||||
</el-tag>
|
||||
<el-button
|
||||
size="large"
|
||||
:type="paused ? 'success' : 'danger'"
|
||||
:loading="pauseBusy"
|
||||
@click="onTogglePause"
|
||||
>{{ paused ? '恢复接单' : '停止接单' }}</el-button>
|
||||
<el-button size="large" type="primary" plain @click="emit('call-material')">叫料</el-button>
|
||||
<span v-if="paused && state.pauseReason" class="ops-reason">原因:{{ state.pauseReason }}</span>
|
||||
</header>
|
||||
|
||||
<!-- ① 工件区:扫码上料 / 取料 -->
|
||||
<section class="card sn-card">
|
||||
<div class="card-title">当前工件</div>
|
||||
@@ -196,6 +212,7 @@ import {
|
||||
canReport,
|
||||
criterionOk,
|
||||
flowActive,
|
||||
flowId,
|
||||
flowName,
|
||||
hasNg,
|
||||
loadBind,
|
||||
@@ -215,7 +232,9 @@ import {
|
||||
operatorName,
|
||||
orderNos,
|
||||
orderNo,
|
||||
paused,
|
||||
setCurrentSn,
|
||||
setPaused,
|
||||
sn,
|
||||
startedAt,
|
||||
state,
|
||||
@@ -232,9 +251,56 @@ import {
|
||||
wip
|
||||
} from '../../store/station'
|
||||
|
||||
const emit = defineEmits(['call-material'])
|
||||
|
||||
const scanRef = ref()
|
||||
const scanInput = ref('')
|
||||
const taking = ref(false)
|
||||
const pauseBusy = ref(false)
|
||||
|
||||
// 停止接单/恢复接单:停单时可填原因(可空),恢复不需要原因
|
||||
async function onTogglePause() {
|
||||
if (!paused.value) {
|
||||
let reason = ''
|
||||
try {
|
||||
const { value } = await ElMessageBox.prompt(
|
||||
'停止接单后本工位暂停新的报工提交,可随时恢复;作业信息不受影响。',
|
||||
'停止接单',
|
||||
{
|
||||
confirmButtonText: '停止接单',
|
||||
cancelButtonText: '取消',
|
||||
inputPlaceholder: '停止原因(可空)',
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
reason = (value || '').trim()
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
pauseBusy.value = true
|
||||
try {
|
||||
await setPaused(true, reason)
|
||||
ElMessage.warning('已停止接单' + (reason ? ':' + reason : ''))
|
||||
} catch { /* 统一错误提示 */ }
|
||||
pauseBusy.value = false
|
||||
} else {
|
||||
try {
|
||||
await ElMessageBox.confirm('确认恢复本工位接单?', '恢复接单', {
|
||||
confirmButtonText: '恢复接单',
|
||||
cancelButtonText: '取消',
|
||||
type: 'success'
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
pauseBusy.value = true
|
||||
try {
|
||||
await setPaused(false, '')
|
||||
ElMessage.success('已恢复接单')
|
||||
} catch { /* 统一错误提示 */ }
|
||||
pauseBusy.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const myPointLabel = computed(() => (myPoint.value ? myPoint.value.label || myPoint.value.pointNo : '工位' + stationNo.value))
|
||||
|
||||
@@ -246,8 +312,10 @@ const stepSummaryText = computed(() => {
|
||||
const stepSummaryType = computed(() => (missingSteps.value.length ? 'warning' : 'success'))
|
||||
|
||||
const blockTip = computed(() => {
|
||||
if (paused.value) return '已停止接单' + (state.pauseReason ? ':' + state.pauseReason : '') + ',恢复接单后才能报工'
|
||||
if (!sn.value) return '请先扫描工件 SN'
|
||||
if (!orderNo.value) return '请选择工单号'
|
||||
if (!flowId.value) return '本工位未绑定工艺流程,无法报工'
|
||||
if (bindBlocking.value) return '装配物料未绑齐:' + (state.bindPanel?.missing || '缺料')
|
||||
if (missingSteps.value.length) return '还有步骤未录入:' + (missingSteps.value[0].name || '未命名步骤')
|
||||
if (missingChecks.value.length) return '还有步骤未做检测确认:' + (missingChecks.value[0].name || '未命名步骤')
|
||||
@@ -459,7 +527,7 @@ async function onProcessDone() {
|
||||
const data = await reportProcessDone({
|
||||
sn: sn.value,
|
||||
orderNo: orderNo.value,
|
||||
processCode: Number(stationNo.value),
|
||||
flowId: flowId.value,
|
||||
stationNo: stationNo.value,
|
||||
steps: buildStepsPayload(),
|
||||
operator: operatorName(),
|
||||
@@ -494,7 +562,7 @@ async function onTempStore() {
|
||||
sn: sn.value,
|
||||
orderNo: orderNo.value || '',
|
||||
stationNo: stationNo.value,
|
||||
processCode: Number(stationNo.value),
|
||||
flowId: flowId.value,
|
||||
operator: operatorName()
|
||||
})
|
||||
ElMessage.success(data?.queued ? 'MES 暂不可达,已离线缓存' : '暂存退库已上报')
|
||||
@@ -560,6 +628,28 @@ defineExpose({ focusScan })
|
||||
padding: 14px 16px;
|
||||
box-shadow: 0 1px 6px rgba(0, 21, 41, 0.08);
|
||||
}
|
||||
.ops-bar {
|
||||
grid-column: 1 / -1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 10px 16px;
|
||||
box-shadow: 0 1px 6px rgba(0, 21, 41, 0.08);
|
||||
}
|
||||
.ops-bar .ops-lab {
|
||||
color: #909399;
|
||||
font-size: 15px;
|
||||
}
|
||||
.ops-bar .ops-reason {
|
||||
color: #f56c6c;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.card-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<el-table :data="rows" border size="large" height="420">
|
||||
<el-table-column prop="date" label="日期" width="130" />
|
||||
<el-table-column prop="stationNo" label="工位" width="90" />
|
||||
<el-table-column prop="processName" label="工序" min-width="160" />
|
||||
<el-table-column prop="processName" label="工艺" min-width="160" />
|
||||
<el-table-column prop="operator" label="操作人" width="120" />
|
||||
<el-table-column prop="doneCount" label="完成" width="90" />
|
||||
<el-table-column prop="okCount" label="合格" width="90" />
|
||||
|
||||
Reference in New Issue
Block a user