diff --git a/src/api/mes/taskManagement/index.ts b/src/api/mes/taskManagement/index.ts index fe87f63c..c9ee580b 100644 --- a/src/api/mes/taskManagement/index.ts +++ b/src/api/mes/taskManagement/index.ts @@ -10,6 +10,8 @@ export interface TaskManagementVO { endDate?: string cronExpression?: string operableUsers?: string + operator?: string + taskTime?: string enabled?: boolean execFrequency?: string frequencyValue?: string diff --git a/src/api/mes/ticketManagement/index.ts b/src/api/mes/ticketManagement/index.ts index 49c76f18..a4fe5397 100644 --- a/src/api/mes/ticketManagement/index.ts +++ b/src/api/mes/ticketManagement/index.ts @@ -11,6 +11,8 @@ export interface TicketManagementVO { jobStatus?: string | number jobResult?: string jobUser?: string + operator?: string + operatorName?: string taskTime?: string taskEndTime?: string cancelReason?: string diff --git a/src/locales/en.ts b/src/locales/en.ts index f34c16bc..81b7d0c5 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -2141,6 +2141,7 @@ export default { moldList: 'Mold List', dateRange: 'Date Range', operableUsers: 'Responsible Person', + taskTime: 'Job Start Time', createWorkOrder: 'Create Work Order', placeholderName: 'Please input name', placeholderTaskType: 'Please select type', @@ -2151,6 +2152,7 @@ export default { placeholderEndDate: 'Please select end date', placeholderDateRange: 'Please select date range', placeholderOperableUsers: 'Please select responsible person', + placeholderTaskTime: 'Please select job start time', placeholderCronExpression: 'Please input cron expression', placeholderEnabled: 'Please select enabled status', selectDeviceDialogTitle: 'Select Devices', @@ -2179,8 +2181,9 @@ export default { deviceName: 'Device Name', configName: 'Plan Config Name', operatorName: 'Operator', - taskTime: 'Job Time', - taskEndTime: 'Planned End Time', + taskTimeRange: 'Job Time', + taskTime: 'Job Start Time', + taskEndTime: 'Job End Time', createTime: 'Create Time', index: 'No.', cancelTask: 'Cancel Task', @@ -2199,6 +2202,7 @@ export default { cancelConfirm: 'Confirm to cancel selected tasks?', cancelSuccess: 'Cancel task successfully', cancelFail: 'Cancel task failed', + cancelOnlyUnworkedTip: 'Only unworked work orders can be canceled', selectAllDecisionError: 'Please select pass or fail for all pending records first', placeholderInputValue: 'Please input', imageLimitExceed: 'Maximum 3 images', @@ -2213,6 +2217,9 @@ 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', ok: 'Pass', ng: 'Fail', dialogCancel: 'Cancel', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 91283700..54c42029 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -2136,6 +2136,7 @@ export default { moldList: '模具列表', dateRange: '起止日期', operableUsers: '责任人', + taskTime: '作业开始时间', createWorkOrder: '新增工单', placeholderName: '请输入名称', placeholderTaskType: '请选择类型', @@ -2146,6 +2147,7 @@ export default { placeholderEndDate: '请选择结束日期', placeholderDateRange: '请选择起止日期', placeholderOperableUsers: '请选择责任人', + placeholderTaskTime: '请选择作业开始时间', placeholderCronExpression: '请输入 cron 表达式', placeholderEnabled: '请选择是否启用', selectDeviceDialogTitle: '选择设备', @@ -2175,8 +2177,9 @@ export default { deviceName: '设备名称', configName: '计划配置名称', operatorName: '作业人', - taskTime: '作业时间', - taskEndTime: '计划结束作业时间', + taskTimeRange: '作业时间', + taskTime: '作业开始时间', + taskEndTime: '作业结束时间', createTime: '创建时间', index: '序号', cancelTask: '取消任务', @@ -2196,6 +2199,7 @@ export default { cancelConfirm: '确认取消选中的任务吗?', cancelSuccess: '取消任务成功', cancelFail: '取消任务失败', + cancelOnlyUnworkedTip: '只有未作业状态的工单才能取消任务', selectAllDecisionError: '请先为所有待检测记录选择通过或不通过', selectDecisionError: '请先为待检测记录选择通过或不通过', updateSuccess: '更新成功', @@ -2206,6 +2210,9 @@ export default { placeholderPlanType: '请选择类型', placeholderJobStatus: '请选择作业状态', placeholderJobResult: '请选择结果', + placeholderOperatorName: '请选择作业人', + placeholderTaskTime: '请选择作业开始时间', + placeholderTaskEndTime: '请选择作业结束时间', ok: '通过', ng: '不通过', dialogCancel: '取 消', diff --git a/src/views/mes/taskManagement/index.vue b/src/views/mes/taskManagement/index.vue index 50503d0d..32d5f635 100644 --- a/src/views/mes/taskManagement/index.vue +++ b/src/views/mes/taskManagement/index.vue @@ -57,6 +57,27 @@ /> + + + + + + + + @@ -243,6 +264,7 @@ import download from '@/utils/download' import { TaskManagementApi, TaskManagementVO } from '@/api/mes/taskManagement' import { DeviceLedgerApi, DeviceLedgerVO } from '@/api/mes/deviceledger' import { PlanMaintenanceApi } from '@/api/mes/planmaintenance' +import { getSimpleUserList, UserVO } from '@/api/system/user' import TaskManagementForm from './TaskManagementForm.vue' defineOptions({ name: 'TaskManagement' }) @@ -280,6 +302,7 @@ type PlanOption = { const planOptions = ref([]) const deviceOptions = ref<{ id: number; label: string; raw?: DeviceLedgerVO }[]>([]) +const users = ref([]) const queryParams = reactive({ pageNo: 1, @@ -287,7 +310,9 @@ const queryParams = reactive({ name: undefined as string | undefined, taskType: undefined as number | undefined, projectForm: [] as string[], - deviceIds: [] as number[] + deviceIds: [] as number[], + operator: undefined as string | undefined, + taskTime: undefined as string | undefined }) const queryFormRef = ref() @@ -322,6 +347,10 @@ const ensureDeviceOptionsLoaded = async () => { })) } +const ensureUserOptionsLoaded = async () => { + users.value = await getSimpleUserList() +} + const getDeviceNames = (value: any) => { const ids = parseIdsValue(value) if (!ids.length) return '-' @@ -458,7 +487,7 @@ const handleExport = async () => { } onMounted(async () => { - await Promise.all([ensurePlanOptionsLoaded(), ensureDeviceOptionsLoaded(), getList()]) + await Promise.all([ensurePlanOptionsLoaded(), ensureDeviceOptionsLoaded(), ensureUserOptionsLoaded(), getList()]) updatePlanTableMaxHeight() window.addEventListener('resize', updatePlanTableMaxHeight) }) diff --git a/src/views/mes/workOrderManagement/components/TicketResultDialog.vue b/src/views/mes/workOrderManagement/components/TicketResultDialog.vue index e4e1dc4d..3c364ad3 100644 --- a/src/views/mes/workOrderManagement/components/TicketResultDialog.vue +++ b/src/views/mes/workOrderManagement/components/TicketResultDialog.vue @@ -4,6 +4,17 @@
{{ t('common.back') }} {{ pageTitle }} +
+ + {{ t('EquipmentManagement.WorkOrderManagement.dialogSave') }} + +
@@ -141,13 +152,6 @@ :total="total" class="mt-15px mb-15px flex justify-end" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> - - @@ -393,9 +397,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/mes/workOrderManagement/index.vue b/src/views/mes/workOrderManagement/index.vue index 5b621fc0..4f32f172 100644 --- a/src/views/mes/workOrderManagement/index.vue +++ b/src/views/mes/workOrderManagement/index.vue @@ -44,6 +44,27 @@
+ + + + + + + + @@ -73,7 +94,7 @@ type="warning" plain @click="handleBatchCancel" - :disabled="!selectedIds.length" + :disabled="isCancelDisabled" :loading="cancelLoading" > {{ t('EquipmentManagement.WorkOrderManagement.cancelTask') }} @@ -213,6 +234,7 @@ import { dateFormatter } from '@/utils/formatTime' import { getStrDictOptions } from '@/utils/dict' import { useDictStoreWithOut } from '@/store/modules/dict' import { TicketManagementApi, TicketManagementVO } from '@/api/mes/ticketManagement' +import { getSimpleUserList, UserVO } from '@/api/system/user' import TicketResultDialog from './components/TicketResultDialog.vue' defineOptions({ name: 'WorkOrderManagement' }) @@ -246,8 +268,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(() => { @@ -264,22 +288,40 @@ 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 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 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 { @@ -299,6 +341,7 @@ const resetQuery = () => { } const handleSelectionChange = (rows: TicketManagementVO[]) => { + selectedRows.value = rows selectedIds.value = rows .map((r) => r.id) .filter((id): id is number => typeof id === 'number') @@ -306,6 +349,10 @@ const handleSelectionChange = (rows: TicketManagementVO[]) => { const handleBatchCancel = async () => { if (!selectedIds.value.length) return + if (hasUncancelableSelection.value) { + message.warning(t('EquipmentManagement.WorkOrderManagement.cancelOnlyUnworkedTip')) + return + } try { const { value } = await ElMessageBox.prompt('请输入取消原因', t('EquipmentManagement.WorkOrderManagement.cancelTask'), { confirmButtonText: t('common.ok'), @@ -316,11 +363,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('EquipmentManagement.WorkOrderManagement.cancelSuccess')) selectedIds.value = [] + selectedRows.value = [] await getList() } catch { } finally { @@ -333,7 +381,7 @@ const handleExport = async () => { await message.exportConfirm() exportLoading.value = true const params: any = { - ...queryParams, + ...buildQueryParams(), ids: selectedIds.value.length ? selectedIds.value.join(',') : undefined } const data = await TicketManagementApi.exportTicketManagement(params) @@ -367,6 +415,7 @@ const handleResultSuccess = async () => { onMounted(async () => { await dictStore.setDictMap() + users.value = await getSimpleUserList() await getList() updatePlanTableMaxHeight() window.addEventListener("resize", updatePlanTableMaxHeight)