From b4243dac46564af1cf57929dcfad9728d76c4b7c Mon Sep 17 00:00:00 2001 From: yinq Date: Tue, 13 Jan 2026 18:14:55 +0800 Subject: [PATCH 1/4] =?UTF-8?q?update=20=E6=8A=A5=E5=B7=A5=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E4=BC=98=E5=8C=96=E5=8A=A0=E9=A6=96=E6=A3=80=E3=80=81?= =?UTF-8?q?=E6=8A=A5=E5=B7=A5=E8=AE=B0=E5=BD=95=E3=80=81=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=B4=A8=E6=A3=80=E8=AE=B0=E5=BD=95=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/qms/QcInspectionMain/types.ts | 3 + .../mes/prodReport/components/CurrentTask.vue | 62 +++++++- .../components/InspectionRecord.vue | 144 ++++++++++++++++++ .../prodReport/components/PendingTasks.vue | 3 +- .../components/WorkReportRecord.vue | 13 +- src/views/mes/prodReport/index.vue | 41 ++--- 6 files changed, 229 insertions(+), 37 deletions(-) create mode 100644 src/views/mes/prodReport/components/InspectionRecord.vue diff --git a/src/api/qms/QcInspectionMain/types.ts b/src/api/qms/QcInspectionMain/types.ts index a6d1424..0d645ee 100644 --- a/src/api/qms/QcInspectionMain/types.ts +++ b/src/api/qms/QcInspectionMain/types.ts @@ -398,6 +398,9 @@ export interface QcInspectionMainQuery extends PageQuery { * 日期范围参数 */ params?: any; + + + planDetailId?: number; } diff --git a/src/views/mes/prodReport/components/CurrentTask.vue b/src/views/mes/prodReport/components/CurrentTask.vue index f367a7c..7058389 100644 --- a/src/views/mes/prodReport/components/CurrentTask.vue +++ b/src/views/mes/prodReport/components/CurrentTask.vue @@ -112,7 +112,7 @@ 首检 @@ -127,6 +127,8 @@ import { listPlanInfo, updatePlanInfo, stopPlanInfo, resumePlanInfo, reportPlanI import { PlanInfoVO, PlanInfoQuery } from '@/api/mes/planInfo/types'; import { getProdProductPlanDetailList, listProductPlanDetail } from '@/api/mes/productPlanDetail'; import { ProductPlanDetailQuery } from '@/api/mes/productPlanDetail/types'; +import { listQcInspectionMain } from '@/api/qms/QcInspectionMain'; +import { QcInspectionMainQuery } from '@/api/qms/QcInspectionMain/types'; import { parseTime } from '@/utils/ruoyi'; const { proxy } = getCurrentInstance() as any; @@ -141,6 +143,7 @@ const emit = defineEmits<{ const loading = ref(false); const currentWorkOrder = ref(null); +const hasPendingInspection = ref(false); // 是否有未处理的首检任务 const reportForm = ref({ reportQuantity: 0, @@ -166,6 +169,29 @@ const getStatusText = (status: string) => { return statusMap[status] || '未知'; }; +// 检查首检任务状态 +const checkInspectionTask = async (planCode: string, planDetailId: string | number) => { + try { + const query: QcInspectionMainQuery = { + pageNum: 1, + pageSize: 1, + inspectionType: 0, // 首检 + status: 0, // 未处理 + planDetailId: planDetailId + }; + + const res = await listQcInspectionMain(query); + const inspectionList = res.rows || []; + + // 检查是否有未处理的首检任务 + // 如果有未处理的首检任务,则禁用按钮 + hasPendingInspection.value = inspectionList.length > 0; + } catch (error) { + console.error('查询首检任务状态失败:', error); + hasPendingInspection.value = false; + } +}; + // 获取当前工单 const getCurrentWorkOrder = async () => { loading.value = true; @@ -184,12 +210,26 @@ const getCurrentWorkOrder = async () => { const res = await listPlanInfo(query as PlanInfoQuery); if (res.rows && res.rows.length > 0) { currentWorkOrder.value = res.rows[0]; + + // 获取生产信息明细,用于检查首检任务 + const detailRes = await getProdProductPlanDetailList({ planId: currentWorkOrder.value.planId }); + const detailList = detailRes.data || []; + + if (detailList && detailList.length > 0) { + const firstDetail = detailList[detailList.length - 1]; + // 检查首检任务状态 + await checkInspectionTask(currentWorkOrder.value.planCode, firstDetail.planDetailId); + } else { + hasPendingInspection.value = false; + } } else { currentWorkOrder.value = null; + hasPendingInspection.value = false; } } catch (error) { console.error('获取当前工单失败:', error); currentWorkOrder.value = null; + hasPendingInspection.value = false; } finally { loading.value = false; } @@ -319,9 +359,7 @@ const handleFirstInspection = async () => { if (!currentWorkOrder.value) return; try { - await proxy?.$modal.confirm('确认生成首检任务?'); - loading.value = true; - + // 先检查是否已存在未处理的首检任务 const detailRes = await getProdProductPlanDetailList({ planId: currentWorkOrder.value.planId }); const detailList = detailRes.data || []; @@ -330,9 +368,21 @@ const handleFirstInspection = async () => { proxy?.$modal.msgWarning('本工单尚未生成生产信息,无法进行首检'); return; } + const firstDetail = detailList[detailList.length - 1]; const planDetailId = firstDetail.planDetailId; + // 检查是否已存在未处理的首检任务 + await checkInspectionTask(currentWorkOrder.value.planCode, planDetailId); + + if (hasPendingInspection.value) { + proxy?.$modal.msgWarning('已存在未处理的首检任务,无法重复生成'); + return; + } + + await proxy?.$modal.confirm('确认生成首检任务?'); + loading.value = true; + // 调用首检接口 const inspectionData = { planDetailId: planDetailId, @@ -342,9 +392,11 @@ const handleFirstInspection = async () => { await generateInspectionTask(inspectionData); proxy?.$modal.msgSuccess('首检任务生成成功'); + + // 刷新首检任务状态 + await checkInspectionTask(currentWorkOrder.value.planCode, planDetailId); } catch (error: any) { if (error !== 'cancel') { - proxy?.$modal.msgError('首检任务生成失败'); console.error('首检任务生成失败:', error); } } finally { diff --git a/src/views/mes/prodReport/components/InspectionRecord.vue b/src/views/mes/prodReport/components/InspectionRecord.vue new file mode 100644 index 0000000..423154b --- /dev/null +++ b/src/views/mes/prodReport/components/InspectionRecord.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/src/views/mes/prodReport/components/PendingTasks.vue b/src/views/mes/prodReport/components/PendingTasks.vue index 232a0aa..0f2ae28 100644 --- a/src/views/mes/prodReport/components/PendingTasks.vue +++ b/src/views/mes/prodReport/components/PendingTasks.vue @@ -14,12 +14,13 @@ + - + diff --git a/src/views/mes/prodReport/components/WorkReportRecord.vue b/src/views/mes/prodReport/components/WorkReportRecord.vue index 553f8e6..e0ea5f6 100644 --- a/src/views/mes/prodReport/components/WorkReportRecord.vue +++ b/src/views/mes/prodReport/components/WorkReportRecord.vue @@ -18,7 +18,7 @@ - + @@ -50,7 +50,7 @@ import { PlanInfoQuery } from '@/api/mes/planInfo/types'; import { parseTime } from '@/utils/ruoyi'; const props = defineProps<{ - workstationId?: string | number; + workstationId?: number; }>(); const loading = ref(false); @@ -59,7 +59,8 @@ const total = ref(0); const queryParams = ref({ pageNum: 1, - pageSize: 10 + pageSize: 10, + stationId: props.workstationId }); // 获取报工记录列表 @@ -83,9 +84,9 @@ const getList = async () => { processName: (item as any).processName || '-', reportQuantity: item.completeAmount || 0, remainingAmount: (item as any).remainingAmount || 0, - reportTime: item.realBeginTime || item.realEndTime || '', - reportUser: item.userName || '-', - workstation: (item as any).workstationName || '-', + reportTime: item.realBeginTime, + reportUser: item.reportUser , + stationName: (item as any).stationName || '-', remark: item.remark || '-' })); diff --git a/src/views/mes/prodReport/index.vue b/src/views/mes/prodReport/index.vue index 11fe45d..b6a57a0 100644 --- a/src/views/mes/prodReport/index.vue +++ b/src/views/mes/prodReport/index.vue @@ -17,19 +17,14 @@ :disabled='activeTab !== "pending"' filterable clearable - :filter-method='filterWorkstation' @change='handleWorkstationChange' > - {{ item.stationName || item.stationCode }} - - ({{ item.stationCode }}) - @@ -52,6 +47,7 @@ + @@ -67,6 +63,9 @@
+
+ +
@@ -91,6 +90,7 @@ import { ArrowLeft, Menu } from '@element-plus/icons-vue'; import PendingTasks from './components/PendingTasks.vue'; import CurrentTask from './components/CurrentTask.vue'; import WorkReportRecord from './components/WorkReportRecord.vue'; +import InspectionRecord from './components/InspectionRecord.vue'; import ProcessDocuments from './components/ProcessDocuments.vue'; import { parseTime } from '@/utils/ruoyi'; import useUserStore from '@/store/modules/user'; @@ -107,11 +107,12 @@ const activeTab = ref('pending'); const pendingTasksRef = ref(); const currentTaskRef = ref(); const recordRef = ref(); +const inspectionRef = ref(); const documentRef = ref(); // 工位信息(可以从路由参数或用户信息中获取) const productionLine = ref('DJ01'); -const workstation = ref('DJ01-01'); // 工位编码,用于显示 +const workstation = ref(''); // 工位名称 const workstationId = ref(''); // 工位ID,用于查询 const currentShift = ref('白班'); const workstationList = ref([]); @@ -146,6 +147,9 @@ const handleTabChange = (tabName: string) => { } else if (tabName === 'record') { // 切换到报工记录时刷新数据 recordRef.value?.refresh?.(); + } else if (tabName === 'inspection') { + // 切换到质检记录时刷新数据 + inspectionRef.value?.refresh?.(); } }; @@ -159,13 +163,13 @@ const getWorkstationList = async () => { filteredWorkstationList.value = data; // 如果列表不为空且当前工位不在列表中,设置默认工位 if (data.length > 0) { - const foundWorkstation = data.find(item => item.stationCode === workstation.value); + const foundWorkstation = data.find(item => item.stationName === workstation.value); if (foundWorkstation) { // 如果找到匹配的工位编码,设置对应的工位ID(watch会自动触发刷新) workstationId.value = foundWorkstation.stationId; } else { // 如果找不到匹配的工位,设置第一个工位为默认值(watch会自动触发刷新) - workstation.value = data[0].stationCode; + workstation.value = data[0].stationName; workstationId.value = data[0].stationId; } } @@ -175,21 +179,6 @@ const getWorkstationList = async () => { } }; -// 工位搜索过滤 -const filterWorkstation = (query: string) => { - workstationSearchText.value = query; - if (!query) { - filteredWorkstationList.value = workstationList.value; - return; - } - const lowerQuery = query.toLowerCase(); - filteredWorkstationList.value = workstationList.value.filter(item => { - const stationName = (item.stationName || '').toLowerCase(); - const stationCode = (item.stationCode || '').toLowerCase(); - return stationName.includes(lowerQuery) || stationCode.includes(lowerQuery); - }); -}; - // 刷新所有组件数据 const refreshAllData = () => { // 刷新待处理任务 @@ -198,6 +187,8 @@ const refreshAllData = () => { currentTaskRef.value?.refresh?.(); // 刷新报工记录 recordRef.value?.refresh?.(); + // 刷新质检记录 + inspectionRef.value?.refresh?.(); // 刷新工艺文件(如果需要) documentRef.value?.refresh?.(); }; @@ -207,7 +198,7 @@ const handleWorkstationChange = (stationId: string | number) => { // 根据工位ID找到对应的工位编码 const selectedWorkstation = workstationList.value.find(item => item.stationId === stationId); if (selectedWorkstation) { - workstation.value = selectedWorkstation.stationCode; + workstation.value = selectedWorkstation.stationName; } // 更新工位ID(不在这里刷新,由watch统一处理,避免重复调用) workstationId.value = stationId; From bd68f66384337c60bdcdc7be8fdcd383984f6ac5 Mon Sep 17 00:00:00 2001 From: yinq Date: Wed, 14 Jan 2026 10:33:48 +0800 Subject: [PATCH 2/4] =?UTF-8?q?update=20=E8=BD=AE=E8=83=8E=E8=A1=8C?= =?UTF-8?q?=E4=B8=9A=E6=96=B0=E5=A2=9E=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/mes/planInfo/index.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/views/mes/planInfo/index.vue b/src/views/mes/planInfo/index.vue index 7704228..f4e3045 100644 --- a/src/views/mes/planInfo/index.vue +++ b/src/views/mes/planInfo/index.vue @@ -1243,6 +1243,7 @@ const submitForm = () => { let assemblyData = batchesAddAssemblyData(); if (machineIds.value.length == 0) { proxy?.$modal.msgWarning('请选择机台!'); + buttonLoading.value = false return; } await orderAddProductPlanList({ From 4510f3440e8abd44be1fc49b1caf990862bfb817 Mon Sep 17 00:00:00 2001 From: "zangch@mesnac.com" Date: Wed, 14 Jan 2026 14:14:12 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat(dms):=20=E6=9B=B4=E6=96=B0=E6=95=85?= =?UTF-8?q?=E9=9A=9C=E5=AE=9E=E4=BE=8B=E6=B4=BB=E5=8A=A8=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加审批状态、申请时间、要求完成时间字段(注释状态) - 新增设备位置、实际开始时间、实际完成时间、确认状态字段 - 添加确认人和确认时间字段 - 集成维修零件列表表格显示 - 引入任务权限检查逻辑,判断当前用户是否为任务办理人 - 实现查看模式,根据不同模式控制按钮和输入框显示 - 添加表单验证逻辑,包括审批状态和处理意见必填检查 - 扩展状态映射功能,支持审批状态和确认状态文本转换 - 优化审批按钮显示逻辑,结合用户权限和查看模式控制 - 添加主管确认按钮的权限检查和显示条件 - 实现外协单位列表加载和表单初始化逻辑 --- .../dms/dmsFaultInstanceActivity/index.vue | 175 +++++++++++++++++- 1 file changed, 168 insertions(+), 7 deletions(-) diff --git a/src/views/dms/dmsFaultInstanceActivity/index.vue b/src/views/dms/dmsFaultInstanceActivity/index.vue index 34b665f..9f782b9 100644 --- a/src/views/dms/dmsFaultInstanceActivity/index.vue +++ b/src/views/dms/dmsFaultInstanceActivity/index.vue @@ -47,11 +47,28 @@ + + + + @@ -65,8 +82,37 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -184,6 +230,17 @@ + + +

维修更换零件

+ + + + + + +
+ >({}); const workOrder = ref({}); const workOrderStatusText = ref(''); +const approveStatusText = ref(''); +const confirmStatusText = ref(''); const outsourceList = ref([]); const outsourcingName = ref(''); + // 表单相关 const processFormRef = ref(); const submitVerifyRef = ref>(); @@ -229,6 +290,9 @@ const approvalRecordRef = ref>(); // 任务变量 const taskVariables = ref({}); +// 当前用户是否为任务办理人 +const isCurrentUserTaskAssignee = ref(false); + // 表单数据 const initFormData = { repairInstanceId: undefined, @@ -255,8 +319,15 @@ const rules = reactive({ processHandleResolution: [{ required: false, message: '处理意见不能为空', trigger: 'blur' }] }); +// 是否为查看模式 +const isViewMode = computed(() => { + return routeParams.value.type === 'view'; +}); + // 计算属性 const needProcessResolution = computed(() => { + // 查看模式不显示处理意见输入框 + if (isViewMode.value) return false; return isApprovalStage.value || confirmButtonShow.value; }); @@ -268,8 +339,10 @@ const currentStepName = computed(() => { }); const approvalButtonShow = computed(() => { - // 显示审批按钮的条件:工单审批状态为待审批(1) - return workOrder.value?.approveStatus === '1'; + // 查看模式不显示审批按钮 + if (isViewMode.value) return false; + // 显示审批按钮的条件:工单审批状态为待审批(1) && 当前用户是任务办理人 + return workOrder.value?.approveStatus === '1' && isCurrentUserTaskAssignee.value; }); const confirmButtonShow = computed(() => { @@ -290,20 +363,26 @@ const confirmButtonShow = computed(() => { const approveStatusMatches = String(workOrder.value?.approveStatus) === '2'; const repairConfirmMatches = String(workOrder.value?.repairConfirm) === '0'; - const shouldShow = billsStatusMatches && approveStatusMatches && repairConfirmMatches; + // 查看模式不显示主管确认按钮 + if (isViewMode.value) return false; + + // 同时需要当前用户是任务办理人 + const shouldShow = billsStatusMatches && approveStatusMatches && repairConfirmMatches && isCurrentUserTaskAssignee.value; console.log('主管确认按钮显示结果:', { billsStatusMatches, approveStatusMatches, repairConfirmMatches, + isCurrentUserTaskAssignee: isCurrentUserTaskAssignee.value, shouldShow }); return shouldShow; }); -// 是否为审批阶段 +// 是否为审批阶段(查看模式不显示审批状态选择框) const isApprovalStage = computed(() => { + if (isViewMode.value) return false; return workOrder.value?.approveStatus === '1'; }); @@ -319,6 +398,9 @@ onMounted(async () => { // 获取外协单位列表 await getOutsourceList(); + // 检查当前用户是否为任务办理人 + await checkCurrentUserTaskPermission(); + // 初始化表单数据 initializeFormData(); @@ -333,6 +415,40 @@ onMounted(async () => { } }); +// 检查当前用户是否为任务办理人 +const checkCurrentUserTaskPermission = async () => { + try { + const businessId = routeParams.value.id; + if (!businessId) { + isCurrentUserTaskAssignee.value = false; + return; + } + + // 查询当前用户的待办任务列表,筛选出匹配当前工单的任务 + const taskRes = await pageByTaskWait({ + pageNum: 1, + pageSize: 100, + flowCode: 'Fault01' // 故障维修流程代码 + }); + + // 检查是否有匹配当前业务ID的待办任务 + const matchingTask = taskRes.rows?.find( + (task: any) => String(task.businessId) === String(businessId) + ); + + isCurrentUserTaskAssignee.value = !!matchingTask; + + console.log('用户任务权限检查:', { + businessId, + hasMatchingTask: !!matchingTask, + isCurrentUserTaskAssignee: isCurrentUserTaskAssignee.value + }); + } catch (error) { + console.error('检查用户任务权限失败:', error); + isCurrentUserTaskAssignee.value = false; + } +}; + // 加载工单信息 const loadWorkOrderInfo = async () => { // 从query参数获取businessId @@ -348,6 +464,8 @@ const loadWorkOrderInfo = async () => { // 设置状态显示文本 - 添加安全检查 workOrderStatusText.value = getStatusText(workOrder.value.billsStatus || ''); + approveStatusText.value = getApproveStatusText(workOrder.value.approveStatus || ''); + confirmStatusText.value = getConfirmStatusText(workOrder.value.repairConfirm || ''); }; // 初始化表单数据 @@ -385,7 +503,25 @@ const approvalVerifyOpen = async () => { if (!processFormRef.value) return; try { + // 先进行表单验证 const valid = await processFormRef.value.validate(); + if (!valid) { + (proxy as any)?.$modal.msgWarning('请填写必填项'); + return; + } + + // 检查审批状态是否已选择 + if (!form.approveStatus || form.approveStatus === '1') { + (proxy as any)?.$modal.msgWarning('请选择审批状态(通过或拒绝)'); + return; + } + + // 检查处理意见是否已填写 + if (!form.processHandleResolution || form.processHandleResolution.trim() === '') { + (proxy as any)?.$modal.msgWarning('请填写处理意见'); + return; + } + if (valid) { await (proxy as any)?.$modal.confirm('是否确认提交审批?'); @@ -433,6 +569,12 @@ const submitCallback = async (approvalResult?: any) => { // 主管确认处理 const handleConfirm = async () => { + // 检查处理意见是否已填写 + if (!form.processHandleResolution || form.processHandleResolution.trim() === '') { + (proxy as any)?.$modal.msgWarning('请填写处理意见'); + return; + } + try { // 使用自定义按钮的确认对话框 const result = await ElMessageBox.confirm( @@ -528,7 +670,7 @@ const setDynamicValidationRules = () => { // 工具函数 const getStatusText = (status: string) => { - const statusMap = { + const statusMap: Record = { '0': '待维修', '1': '维修中', '2': '维修完成', @@ -537,6 +679,25 @@ const getStatusText = (status: string) => { }; return statusMap[status] || '未知状态'; }; + +const getApproveStatusText = (status: string) => { + const statusMap: Record = { + '0': '未提交', + '1': '待审批', + '2': '审批通过', + '3': '审批拒绝' + }; + return statusMap[status] || '未知状态'; +}; + +const getConfirmStatusText = (status: string) => { + const statusMap: Record = { + '0': '待确认', + '1': '确认通过', + '2': '确认不通过' + }; + return statusMap[status] || '未知状态'; +}; diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index 1c36b99..064f035 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -710,8 +710,8 @@ const sharedData = computed(() => sharedStore.dynamicValue) watch( () => sharedStore.dynamicValue, (newValue, oldValue) => { - if (newValue !== oldValue) { - ElMessage.info('收到新数据更新') + if (newValue!=null && newValue.message!=null && newValue !== oldValue) { + // ElMessage.info('收到新数据更新') console.log('数据更新:', newValue) // 这里可以执行数据更新后的业务逻辑 // handleDataUpdate(newValue)