From ba0cfccff96520fa464f352c2ccb8f0d5766ffdc Mon Sep 17 00:00:00 2001 From: zhongwenkai <3478244299@qq.com> Date: Thu, 9 Jul 2026 10:53:22 +0800 Subject: [PATCH 1/4] =?UTF-8?q?style:=E6=A8=A1=E5=85=B7=E7=BB=84=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E7=BB=B4=E6=8A=A4=E9=A1=B5=E9=9D=A2=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E4=B8=8D=E5=85=A8=E4=BF=AE=E6=94=B9=EF=BC=8C=E6=A8=A1=E5=85=B7?= =?UTF-8?q?=E7=AE=A1=E7=90=86-=E4=BB=BB=E5=8A=A1=E8=AE=A1=E5=88=92-?= =?UTF-8?q?=E6=96=B0=E5=A2=9E/=E7=BC=96=E8=BE=91-=E6=A8=A1=E5=85=B7?= =?UTF-8?q?=E5=88=97=E8=A1=A8/=E9=A1=B9=E7=9B=AE=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E5=BC=B9=E6=A1=86=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../erp/mold/components/MoldMaintainView.vue | 6 +- .../device/components/DeviceAttributeList.vue | 2 +- src/views/iot/deviceattributetype/index.vue | 2 +- src/views/iot/historyData/index.vue | 2 +- .../TaskConfigurationForm.vue | 511 ++++++++++++++++-- src/views/mold/taskConfiguration/index.vue | 29 +- 6 files changed, 508 insertions(+), 44 deletions(-) diff --git a/src/views/erp/mold/components/MoldMaintainView.vue b/src/views/erp/mold/components/MoldMaintainView.vue index f82b8a28..764bf7b6 100644 --- a/src/views/erp/mold/components/MoldMaintainView.vue +++ b/src/views/erp/mold/components/MoldMaintainView.vue @@ -129,7 +129,7 @@ - - + + + + + + + + + + + {{ t('common.query') }} + + + + {{ t('common.reset') }} + + + + + + + + + + + + + + + + + +
+
+ 已选择 {{ moldDialogSelectedIds.length }} 个模具 +
+ +
+ + +
+ + + + + + + + + + + + + + + + {{ t('common.query') }} + + + + {{ t('common.reset') }} + + + + + + + + + + + + + + + + +
+ +
+ + +
+ + diff --git a/src/views/mold/taskConfiguration/index.vue b/src/views/mold/taskConfiguration/index.vue index cc5029d7..fbbb0779 100644 --- a/src/views/mold/taskConfiguration/index.vue +++ b/src/views/mold/taskConfiguration/index.vue @@ -107,7 +107,8 @@ {{ t('EquipmentManagement.TaskManagement.createWorkOrder') }} @@ -164,7 +165,7 @@ const planPaginationRef = ref() const updatePlanTableMaxHeight = async () => { await nextTick() const tableTop = tableRef.value?.$el?.getBoundingClientRect().top ?? 0 - const paginationHeight = planPaginationRef.value?.getBoundingClientRect().height ?? 72 + const paginationHeight = planPaginationRef.value?.$el?.getBoundingClientRect().height ?? 72 const pageBottomGap = 56 const availableHeight = window.innerHeight - tableTop - paginationHeight - pageBottomGap planTableMaxHeight.value = Math.min(window.innerHeight, Math.max(240, Math.floor(availableHeight))) @@ -253,6 +254,8 @@ const openForm = (type: string, row?: TaskManagementVO) => { formRef.value.open(type, row) } +const isTaskEnabled = (row: TaskManagementVO) => row.enabled === true || (row.enabled as any) === 'true' + const handleDelete = async (id?: number) => { if (!id) return try { @@ -264,11 +267,25 @@ const handleDelete = async (id?: number) => { } const ticketLoadingId = ref(undefined) -const handleCreateTicket = async (id?: number) => { - if (!id) return - ticketLoadingId.value = id +const handleCreateTicket = async (row?: TaskManagementVO) => { + if (!row?.id) return + if (!isTaskEnabled(row)) { + message.warning(t('EquipmentManagement.TaskManagement.createTicketDisabledTip')) + return + } + + try { + await message.confirm( + t('EquipmentManagement.TaskManagement.createTicketConfirm'), + t('common.reminder') + ) + } catch { + return + } + + ticketLoadingId.value = row.id try { - await TaskManagementApi.createTaskManagementTicket(id) + await TaskManagementApi.createTaskManagementTicket(row.id) message.success(t('EquipmentManagement.TaskManagement.createTicketSuccess')) } catch { message.error(t('EquipmentManagement.TaskManagement.createTicketFail')) From 26b59f9ad2411a0f0d498ae91c938264c3d17b1c Mon Sep 17 00:00:00 2001 From: zhongwenkai <3478244299@qq.com> Date: Thu, 9 Jul 2026 12:45:11 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E7=82=B9=E6=A3=80=E4=BF=9D=E5=85=BB-?= =?UTF-8?q?=E7=82=B9=E6=A3=80=E4=BF=9D=E5=85=BB=E8=AE=B0=E5=BD=95-?= =?UTF-8?q?=E6=A8=A1=E5=85=B7=E5=B7=A5=E5=8D=95=E5=88=97=E8=A1=A8=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=9F=A5=E8=AF=A2=E6=9D=A1=E4=BB=B6=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=8F=96=E6=B6=88=E9=80=BB=E8=BE=91=E5=92=8C=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E9=A1=B5=E6=8C=89=E9=92=AE=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/mold/ticketManagement/index.ts | 4 + src/locales/en.ts | 7 ++ src/locales/zh-CN.ts | 8 ++ .../components/TicketResultDialog.vue | 23 +++-- src/views/mold/workOrderInquiry/index.vue | 87 +++++++++++++++++-- 5 files changed, 112 insertions(+), 17 deletions(-) diff --git a/src/api/mold/ticketManagement/index.ts b/src/api/mold/ticketManagement/index.ts index e85bc695..50ab32dc 100644 --- a/src/api/mold/ticketManagement/index.ts +++ b/src/api/mold/ticketManagement/index.ts @@ -54,6 +54,10 @@ export const TicketManagementApi = { return await request.put({ url: `/mes/mold-ticket-results/batchUpdate`, data }) }, + exportTicketManagement: async (params: any) => { + return await request.download({ url: `/mes/mold-ticket-management/export-excel`, params }) + }, + getInspectionByMoldId: async (params: { moldId: number; startTime?: string; endTime?: string }) => { return await request.get({ url: `/mes/mold-ticket-management/getInspectionByMoldId`, params }) }, diff --git a/src/locales/en.ts b/src/locales/en.ts index 81b7d0c5..11efe055 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -3828,6 +3828,7 @@ export default { operatorName: 'Operator', taskTime: 'Job Time', taskEndTime: 'Planned End Time', + taskTimeRange: 'Job Time', createTime: 'Create Time', index: 'Index', remark: 'Remark', @@ -3837,10 +3838,16 @@ export default { placeholderPlanType: 'Please select type', placeholderJobStatus: 'Please select job status', placeholderJobResult: 'Please select result', + placeholderOperatorName: 'Please select operator', + placeholderTaskTime: 'Please select job start time', + placeholderTaskEndTime: 'Please select job end time', query: 'Query', reset: 'Reset', cancelConfirm: 'Confirm cancel selected tasks?', cancelSuccess: 'Cancel task successful', + cancelOnlyUnworkedTip: 'Only unworked tickets can be canceled', + export: 'Export', + exportFilename: 'Mold Work Order Inquiry.xls', inspectResultTitlePrefix: 'Inspection Result-', inspectResultTitle: 'Inspection Result' }, diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 54c42029..99168640 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -2198,6 +2198,7 @@ export default { cancelReason: '取消原因', cancelConfirm: '确认取消选中的任务吗?', cancelSuccess: '取消任务成功', + cancelOnlyUnworkedTip: '只有未作业状态的工单才能取消任务', cancelFail: '取消任务失败', cancelOnlyUnworkedTip: '只有未作业状态的工单才能取消任务', selectAllDecisionError: '请先为所有待检测记录选择通过或不通过', @@ -3298,6 +3299,7 @@ export default { operatorName: '作业人', taskTime: '作业时间', taskEndTime: '计划结束作业时间', + taskTimeRange: '作业时间', createTime: '创建时间', index: '序号', remark: '备注', @@ -3307,10 +3309,16 @@ export default { placeholderPlanType: '请选择类型', placeholderJobStatus: '请选择作业状态', placeholderJobResult: '请选择结果', + placeholderOperatorName: '请选择作业人', + placeholderTaskTime: '请选择作业开始时间', + placeholderTaskEndTime: '请选择作业结束时间', query: '查询', reset: '重置', cancelConfirm: '确认取消选中的任务吗?', cancelSuccess: '取消任务成功', + cancelOnlyUnworkedTip: '只有未作业状态的工单才能取消任务', + export: '导出', + exportFilename: '模具工单查询.xls', inspectResultTitlePrefix: '检验结果-', inspectResultTitle: '检验结果' }, diff --git a/src/views/mold/workOrderInquiry/components/TicketResultDialog.vue b/src/views/mold/workOrderInquiry/components/TicketResultDialog.vue index 32d1f6cb..365c68e1 100644 --- a/src/views/mold/workOrderInquiry/components/TicketResultDialog.vue +++ b/src/views/mold/workOrderInquiry/components/TicketResultDialog.vue @@ -4,6 +4,17 @@
{{ t('common.back') }} {{ pageTitle }} +
+ + {{ t('MoldManagement.TicketResultDialog.save') }} + +
@@ -141,14 +152,8 @@ v-model:page-size="queryParams.pageSize" :background="true" :page-sizes="[10, 20, 30, 50, 100]" :pager-count="7" :total="total" class="mt-15px mb-15px flex justify-end" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> - - + @@ -386,9 +391,9 @@ const parseImages = (value: any): string[] => { color: var(--el-text-color-primary); } -.ticket-result-footer { +.ticket-result-actions { + margin-left: auto; display: flex; - justify-content: flex-end; gap: 12px; } diff --git a/src/views/mold/workOrderInquiry/index.vue b/src/views/mold/workOrderInquiry/index.vue index 3439990a..9ab5c258 100644 --- a/src/views/mold/workOrderInquiry/index.vue +++ b/src/views/mold/workOrderInquiry/index.vue @@ -41,6 +41,27 @@ + + + + + + + + @@ -54,13 +75,16 @@ {{ t('MoldManagement.MoldWorkOrderInquiry.query') }} + + {{ t('MoldManagement.MoldWorkOrderInquiry.export') }} +
- + {{ t('MoldManagement.MoldWorkOrderInquiry.cancelTask') }}
@@ -125,6 +149,7 @@ import { dateFormatter } from '@/utils/formatTime' import { getStrDictOptions } from '@/utils/dict' import { useDictStoreWithOut } from '@/store/modules/dict' import { TicketManagementApi, TicketManagementVO } from '@/api/mold/ticketManagement' +import { getSimpleUserList, UserVO } from '@/api/system/user' import TicketResultDialog from '@/views/mold/workOrderInquiry/components/TicketResultDialog.vue' const { t } = useI18n() @@ -139,8 +164,8 @@ const planTypeOptions = [ { label: t('MoldManagement.MoldWorkOrderInquiry.planTypeMaintain'), value: '2' } ] const jobResultOptions = [ - { label: t('MoldManagement.MoldWorkOrderInquiry.jobResultOk'), value: 'OK' }, - { label: t('MoldManagement.MoldWorkOrderInquiry.jobResultNg'), value: 'NG' } + { label: t('MoldManagement.MoldWorkOrderInquiry.jobResultOk'), value: '1' }, + { label: t('MoldManagement.MoldWorkOrderInquiry.jobResultNg'), value: '2' } ] const loading = ref(true) @@ -159,7 +184,10 @@ const updatePlanTableMaxHeight = async () => { planTableMaxHeight.value = Math.min(window.innerHeight, Math.max(240, Math.floor(availableHeight))) } const selectedIds = ref([]) +const selectedRows = ref([]) const cancelLoading = ref(false) +const exportLoading = ref(false) +const users = ref([]) const resultVisible = ref(false) const selectedResultRow = ref() const resultTitle = computed(() => { @@ -175,22 +203,36 @@ const queryParams = reactive({ pageSize: 10, planNo: undefined as string | undefined, planType: undefined as string | undefined, - jobStatus: undefined as string | undefined, - jobResult: undefined as string | undefined + jobStatus: '0' as string | undefined, + jobResult: undefined as string | undefined, + operator: undefined as string | undefined, + taskTimeRange: [] as string[] }) const queryFormRef = ref() const showAllFilters = ref(false) -const filterCount = 4 +const filterCount = 6 +const UNWORKED_JOB_STATUS = '0' +const CANCELED_JOB_STATUS = '4' + const toggleFilters = () => { showAllFilters.value = !showAllFilters.value updatePlanTableMaxHeight() } +const buildQueryParams = () => { + const { taskTimeRange, ...params } = queryParams + return { + ...params, + taskTime: taskTimeRange?.[0], + taskEndTime: taskTimeRange?.[1] + } +} + const getList = async () => { loading.value = true try { - const data = await TicketManagementApi.getTicketManagementPage(queryParams) + const data = await TicketManagementApi.getTicketManagementPage(buildQueryParams()) list.value = data.list total.value = data.total } finally { @@ -210,13 +252,22 @@ const resetQuery = () => { } const handleSelectionChange = (rows: TicketManagementVO[]) => { + selectedRows.value = rows selectedIds.value = rows .map((r) => r.id) .filter((id): id is number => typeof id === 'number') } +const isUnworkedTicket = (row?: TicketManagementVO) => String(row?.jobStatus ?? '') === UNWORKED_JOB_STATUS +const hasUncancelableSelection = computed(() => selectedRows.value.some((row) => !isUnworkedTicket(row))) +const isCancelDisabled = computed(() => !selectedIds.value.length || hasUncancelableSelection.value) + const handleBatchCancel = async () => { if (!selectedIds.value.length) return + if (hasUncancelableSelection.value) { + message.warning(t('MoldManagement.MoldWorkOrderInquiry.cancelOnlyUnworkedTip')) + return + } try { const { value } = await ElMessageBox.prompt('请输入取消原因', t('MoldManagement.MoldWorkOrderInquiry.cancelTask'), { confirmButtonText: t('common.ok'), @@ -227,11 +278,12 @@ const handleBatchCancel = async () => { cancelLoading.value = true await TicketManagementApi.batchUpdateTicketStatus({ ids: selectedIds.value.join(','), - jobStatus: '4', + jobStatus: CANCELED_JOB_STATUS, cancelReason: value }) message.success(t('MoldManagement.MoldWorkOrderInquiry.cancelSuccess')) selectedIds.value = [] + selectedRows.value = [] await getList() } catch { } finally { @@ -239,6 +291,23 @@ const handleBatchCancel = async () => { } } +const handleExport = async () => { + try { + await message.exportConfirm() + exportLoading.value = true + const params: any = { + ...buildQueryParams(), + ids: selectedIds.value.length ? selectedIds.value.join(',') : undefined + } + const data = await TicketManagementApi.exportTicketManagement(params) + const download = (await import('@/utils/download')).default + download.excel(data, t('MoldManagement.MoldWorkOrderInquiry.exportFilename')) + } catch { + } finally { + exportLoading.value = false + } +} + const handleRowClick = (row: TicketManagementVO, column: any) => { if (column?.type === 'selection') return if (!row?.id) return @@ -259,6 +328,7 @@ const handleResultSuccess = async () => { onMounted(async () => { await dictStore.setDictMap() + users.value = await getSimpleUserList() await getList() updatePlanTableMaxHeight() window.addEventListener("resize", updatePlanTableMaxHeight) @@ -268,3 +338,4 @@ onBeforeUnmount(() => { window.removeEventListener("resize", updatePlanTableMaxHeight) }) + From 52e9f0ef9e54c4e60e7f7f293bd6bb1e839b2313 Mon Sep 17 00:00:00 2001 From: zhongwenkai <3478244299@qq.com> Date: Thu, 9 Jul 2026 14:22:35 +0800 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20=E6=A8=A1=E5=85=B7=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E6=A8=A1=E6=96=B0=E5=A2=9E=E5=BC=B9=E6=A1=86=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E4=B8=8E=E4=BA=A4=E4=BA=92=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/mes/moldoperate/MoldOperateForm.vue | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/views/mes/moldoperate/MoldOperateForm.vue b/src/views/mes/moldoperate/MoldOperateForm.vue index 125e1ad9..4d0734b6 100644 --- a/src/views/mes/moldoperate/MoldOperateForm.vue +++ b/src/views/mes/moldoperate/MoldOperateForm.vue @@ -19,13 +19,12 @@ @click="openCriticalComponentDialog" /> - + - + ({ remark: undefined, }) -const validateMoldId = (_rule: any, value: any, callback: (error?: Error) => void) => { - if (String(formData.value.operateType) !== '1') { - callback() - return - } - const hasValue = value !== undefined && value !== null && value !== '' - if (!hasValue) { - callback(new Error(t('MoldManagement.MoldOperate.validatorMoldRequired'))) - } else { - callback() - } -} - -const formRules = reactive({ +const formRules = computed(() => ({ operateType: [{ required: true, message: t('MoldManagement.MoldOperate.validatorOperateTypeRequired'), trigger: 'blur' }], deviceId: [{ required: true, message: t('MoldManagement.MoldOperate.validatorDeviceRequired'), trigger: 'change' }], - moldId: [{ validator: validateMoldId, trigger: 'change' }], + moldId: [{ required: true, message: formType.value === 'create' ? '关联模具不能为空' : t('MoldManagement.MoldOperate.validatorMoldRequired'), trigger: 'change' }], operateTime: [{ required: true, message: t('MoldManagement.MoldOperate.validatorOperateTimeRequired'), trigger: 'blur' }], operatorId: [{ required: true, message: t('MoldManagement.MoldOperate.validatorOperatorRequired'), trigger: 'change' }], -}) +})) const formRef = ref() // 表单 Ref /** 打开弹窗 */ @@ -409,11 +395,13 @@ watch( return } formData.value.deviceId = undefined as any + formData.value.lineId = undefined as any formData.value.moldId = undefined as any ids.value = [] moldIds.value = [] selectedDeviceRows.value = [] selectedMoldRows.value = [] + displayTopCategory.value = '' if (!val) { return } @@ -599,7 +587,9 @@ const handleDeviceSelectConfirm = async (payload: { ids: (number | string)[]; ro } else { selectedDeviceRows.value = [] formData.value.deviceId = undefined + formData.value.lineId = undefined ids.value = [] + displayTopCategory.value = '' } nextTick(() => { formRef.value?.clearValidate?.('deviceId') @@ -792,8 +782,12 @@ const openCriticalComponentDialog = async () => { } const openMoldSelectDialog = () => { - searchMoldParams.code='' - searchMoldParams.name='' + if (!formData.value.deviceId) { + message.warning('请先选择设备') + return + } + searchMoldParams.code = '' + searchMoldParams.name = '' const rows = selectedMoldRows.value.map((item) => ({ ...item, id: Number(item.id) })) moldSelectDialogRef.value?.open(rows) } From da25b84dbba5cf0aab1967515da1868e5661dbca Mon Sep 17 00:00:00 2001 From: zhongwenkai <3478244299@qq.com> Date: Thu, 9 Jul 2026 14:39:54 +0800 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=E8=83=BD=E8=80=97=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=8D=95=E4=BD=8D=E5=AD=97=E6=AE=B5=E5=85=B3=E8=81=94?= =?UTF-8?q?=E5=8D=95=E4=BD=8D=E7=AE=A1=E7=90=86=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/mes/energytype/EnergyTypeForm.vue | 70 +++++++++++++++++++-- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/src/views/mes/energytype/EnergyTypeForm.vue b/src/views/mes/energytype/EnergyTypeForm.vue index 3372d4dd..a7b871f3 100644 --- a/src/views/mes/energytype/EnergyTypeForm.vue +++ b/src/views/mes/energytype/EnergyTypeForm.vue @@ -21,10 +21,24 @@ /> - + + + + @@ -57,6 +71,8 @@