Compare commits

...

8 Commits

@ -13,6 +13,7 @@ export interface TicketManagementVO {
jobUser?: string jobUser?: string
taskTime?: string taskTime?: string
taskEndTime?: string taskEndTime?: string
cancelReason?: string
remark?: string remark?: string
creator?: string creator?: string
createTime?: string createTime?: string
@ -41,7 +42,7 @@ export const TicketManagementApi = {
return await request.download({ url: `/mes/ticket-management/export-excel`, params }) return await request.download({ url: `/mes/ticket-management/export-excel`, params })
}, },
batchUpdateTicketStatus: async (data: { ids: string; jobStatus: string | number }) => { batchUpdateTicketStatus: async (data: { ids: string; jobStatus: string | number; cancelReason?: string }) => {
return await request.put({ url: `/mes/ticket-management/batchUpdateStatus`, data }) return await request.put({ url: `/mes/ticket-management/batchUpdateStatus`, data })
}, },

@ -15,6 +15,7 @@ export interface ZjTaskVO {
executorId: string executorId: string
executorName: string executorName: string
status: string status: string
cancelReason?: string
result: string result: string
createTime: string createTime: string
roleIds?: number[] roleIds?: number[]
@ -54,6 +55,10 @@ export const ZjTaskApi = {
return await request.download({ url: `/mes/zj-task/export-excel`, params }) return await request.download({ url: `/mes/zj-task/export-excel`, params })
}, },
batchUpdateZjTaskStatus: async (data: { ids: string; status: string | number; cancelReason?: string }) => {
return await request.put({ url: `/mes/zj-task/batchUpdateStatus`, data })
},
getZjTaskResultPage: async (params: any) => { getZjTaskResultPage: async (params: any) => {
return await request.get({ url: `/mes/zj-task-results/page`, params }) return await request.get({ url: `/mes/zj-task-results/page`, params })
}, },

@ -50,6 +50,10 @@ export const MoldRepairApi = {
return await request.download({ url: `/mes/mold-repair/export-excel`, params }) return await request.download({ url: `/mes/mold-repair/export-excel`, params })
}, },
updateMoldRepairStatus: async (data: any) => {
return await request.put({ url: `/mes/mold-repair/updateMoldRepairStatus`, data })
},
getMoldRepairLineListByRepairId: async (repairId) => { getMoldRepairLineListByRepairId: async (repairId) => {
return await request.get({ url: `/mes/mold-repair/mold-repair-line/list-by-repair-id?repairId=` + repairId }) return await request.get({ url: `/mes/mold-repair/mold-repair-line/list-by-repair-id?repairId=` + repairId })
}, },

@ -13,6 +13,7 @@ export interface TicketManagementVO {
jobUser?: string jobUser?: string
taskTime?: string taskTime?: string
taskEndTime?: string taskEndTime?: string
cancelReason?: string
remark?: string remark?: string
creator?: string creator?: string
createTime?: string createTime?: string
@ -37,7 +38,7 @@ export const TicketManagementApi = {
return await request.get({ url: `/mes/mold-ticket-management/page`, params }) return await request.get({ url: `/mes/mold-ticket-management/page`, params })
}, },
batchUpdateTicketStatus: async (data: { ids: string; jobStatus: string | number }) => { batchUpdateTicketStatus: async (data: { ids: string; jobStatus: string | number; cancelReason?: string }) => {
return await request.put({ url: `/mes/mold-ticket-management/batchUpdateStatus`, data }) return await request.put({ url: `/mes/mold-ticket-management/batchUpdateStatus`, data })
}, },

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

@ -1886,6 +1886,10 @@ export default {
finishDate: 'Finish Date', finishDate: 'Finish Date',
confirmDate: 'Acceptance Date', confirmDate: 'Acceptance Date',
repairResult: 'Repair Result', repairResult: 'Repair Result',
repairResultPending: 'Pending Repair',
repairResultOk: 'Pass',
repairResultNg: 'Fail',
repairStatus: 'Result',
status: 'Order Status', status: 'Order Status',
statusPending: 'Pending', statusPending: 'Pending',
statusDone: 'Completed', statusDone: 'Completed',
@ -1942,10 +1946,15 @@ export default {
subjectCode: 'Repair Code', subjectCode: 'Repair Code',
subjectName: 'Repair Name', subjectName: 'Repair Name',
subjectContent: 'Repair Content', subjectContent: 'Repair Content',
remark: 'Remark',
result: 'Result',
resultOk: 'Pass',
resultNg: 'Fail',
addLine: 'Add Repair Item', addLine: 'Add Repair Item',
placeholderSubjectCode: 'Please input repair code', placeholderSubjectCode: 'Please input repair code',
placeholderSubjectName: 'Please input repair name', placeholderSubjectName: 'Please input repair name',
placeholderSubjectContent: 'Please input repair content', placeholderSubjectContent: 'Please input repair content',
placeholderRemark: 'Please input remark',
validatorRepairIdRequired: 'Repair order id can not be empty', validatorRepairIdRequired: 'Repair order id can not be empty',
validatorSubjectIdRequired: 'Item id can not be empty', validatorSubjectIdRequired: 'Item id can not be empty',
validatorSubjectCodeRequired: 'Item code can not be empty', validatorSubjectCodeRequired: 'Item code can not be empty',
@ -2169,6 +2178,8 @@ export default {
createTime: 'Create Time', createTime: 'Create Time',
operate: 'Operate', operate: 'Operate',
inspect: 'Inspect', inspect: 'Inspect',
cancelTask: 'Cancel Task',
cancelSuccess: 'Cancel task successfully',
exportFilename: 'Quality-InspectionTask.xls', exportFilename: 'Quality-InspectionTask.xls',
placeholderCode: 'Please input code', placeholderCode: 'Please input code',
placeholderType: 'Please select inspection category', placeholderType: 'Please select inspection category',
@ -2418,5 +2429,631 @@ export default {
manualTableReferColumn: 'Reference Value', manualTableReferColumn: 'Reference Value',
manualTableRemarkColumn: 'Remark' manualTableRemarkColumn: 'Remark'
} }
},
ProductionPlan: {
Task: {
moduleName: 'Production Task',
searchCodeLabel: 'Code',
searchCodePlaceholder: 'Please enter code',
searchOrderLabel: 'Order',
searchOrderStartPlaceholder: 'Start Date',
searchOrderEndPlaceholder: 'End Date',
searchDeliveryLabel: 'Delivery',
searchDeliveryStartPlaceholder: 'Start Date',
searchDeliveryEndPlaceholder: 'End Date',
searchRemarkLabel: 'Remark',
searchRemarkPlaceholder: 'Please enter remark',
searchCreateTimeLabel: 'Create Time',
searchCreateTimeStartPlaceholder: 'Start Date',
searchCreateTimeEndPlaceholder: 'End Date',
buttonSearchText: 'Search',
buttonResetText: 'Reset',
buttonCreateText: 'Add',
buttonExportText: 'Export',
tabAllLabel: 'All',
tabDraftLabel: 'Draft',
tabSubmitLabel: 'To Submit',
tabIssuedLabel: 'Issued',
tabPlanLabel: 'Planned',
tabStartLabel: 'Started',
tabFinishedLabel: 'Finished',
tabStoredLabel: 'Stored',
tableCodeColumn: 'Code',
tableOrderDateColumn: 'Order Date',
tableDeliveryDateColumn: 'Delivery Date',
tableTaskTypeColumn: 'Type',
tableStatusColumn: 'Status',
tableRemarkColumn: 'Remark',
tableOperateColumn: 'Operate',
actionSubmitLabel: 'Submit',
actionApproveLabel: 'Approve',
actionMaterialLabel: 'Material',
actionEditLabel: 'Edit',
actionDeleteLabel: 'Delete',
detailTabTaskDetailLabel: 'Task Detail',
dialogCodeLabel: 'Task Code',
dialogCodeTooltip: 'Task code',
dialogCodePlaceholder: 'Code will be generated automatically after saving',
dialogDeliveryDateLabel: 'Delivery Date',
dialogDeliveryDatePlaceholder: 'Select delivery date',
dialogTaskTypeLabel: 'Task Type',
dialogTaskTypeTooltip: 'Source: Data Dictionary - Task Type',
dialogRemarkLabel: 'Remark',
dialogRemarkPlaceholder: 'Please enter remark',
dialogSubmitButtonText: 'Confirm',
dialogCancelButtonText: 'Cancel',
validatorDeliveryDateRequired: 'Delivery date cannot be empty',
validatorTaskTypeRequired: 'Task type cannot be empty',
saleDialogCodeLabel: 'Code',
saleDialogCodePlaceholder: 'Please enter task code',
saleDialogDeliveryDateLabel: 'Delivery Date',
saleDialogDeliveryDatePlaceholder: 'Select delivery date',
saleDialogRemarkLabel: 'Remark',
saleDialogRemarkPlaceholder: 'Please enter remark',
saleDialogTaskTypeLabel: 'Task Type',
saleDetailTabTaskDetailLabel: 'Production Task Detail',
saleValidatorCodeRequired: 'Code cannot be empty',
saleValidatorDeliveryDateRequired: 'Delivery date cannot be empty',
saleValidatorTaskTypeRequired: 'Task type cannot be empty',
detailListCreateButtonText: 'Add',
detailListProductCodeColumn: 'Product Code',
detailListProductNameColumn: 'Product Name',
detailListUnitColumn: 'Unit',
detailListNumberColumn: 'Quantity',
detailListPlanNumberColumn: 'Planned',
detailListFinishDateColumn: 'Delivery Date',
detailListTechRequirementsColumn: 'Technical Requirement',
detailListOperateColumn: 'Operate',
detailListViewActionText: 'Detail',
detailListMaterialActionText: 'Material',
detailListEditActionText: 'Edit',
detailListDeleteActionText: 'Delete',
detailDialogProductLabel: 'Product',
detailDialogProductPlaceholder: 'Please select product',
detailDialogUnitLabel: 'Unit',
detailDialogUnitPlaceholder: 'Please select product',
detailDialogNumberLabel: 'Quantity',
detailDialogNumberPlaceholder: 'Please enter quantity',
detailDialogProjectLabel: 'Project',
detailDialogProjectPlaceholder: 'Please enter project name',
detailDialogPackageSizeLabel: 'Quantity per Package',
detailDialogPackageSizePlaceholder: 'Please enter packing requirement',
detailDialogPackageNumberLabel: 'Package Quantity',
detailDialogPackageNumberPlaceholder: 'Please enter quantity',
detailDialogTechRequirementsLabel: 'Technical Requirement',
detailDialogTechRequirementsPlaceholder: 'Please enter technical requirement',
detailDialogFinishDateLabel: 'Factory Completion',
detailDialogFinishDatePlaceholder: 'Select factory completion date',
detailFormDeliveryDateLabel: 'Delivery Date',
detailFormDeliveryDatePlaceholder: 'Select delivery date',
detailDialogBoxingDateLabel: 'Boxing Date',
detailDialogBoxingDatePlaceholder: 'Select boxing date',
detailDialogArriveDateLabel: 'Arrival Date',
detailDialogArriveDatePlaceholder: 'Select arrival date',
detailDialogRemarkLabel: 'Remark:',
detailDialogSubmitButtonText: 'Confirm',
detailDialogCancelButtonText: 'Cancel',
validatorDetailProductIdRequired: 'Product ID cannot be empty',
validatorDetailUnitIdRequired: 'Unit ID cannot be empty',
validatorDetailTaskIdRequired: 'Task ID cannot be empty',
validatorDetailNumberRequired: 'Quantity cannot be empty',
validatorDetailPackageSizeRequired: 'Packing requirement cannot be empty',
saleDetailTableIndexColumn: 'No.',
saleDetailTableProductColumn: 'Product',
saleDetailTableUnitColumn: 'Unit',
saleDetailTableNumberColumn: 'Quantity',
saleDetailTablePackageSizeColumn: 'Per Package',
saleDetailTablePackageNumberColumn: 'Package Quantity',
saleDetailTableProjectNameColumn: 'Project Name',
saleDetailTableTechRequirementsColumn: 'Technical Requirement',
saleDetailTableRemarkColumn: 'Remark',
saleDetailTableFinishDateColumn: 'Factory Completion',
saleDetailTableBoxingDateColumn: 'Boxing Time',
saleDetailTableArriveDateColumn: 'Arrival Time',
saleDetailTableBarCodeColumn: 'Barcode',
saleDetailTableOperateColumn: 'Operate',
saleDetailAddRowButtonText: '+ Add Task Detail',
saleDetailAddFromOrderButtonText: '+ Add From Sales Order',
saleDetailProductPlaceholder: 'Please select',
validatorRowProductRequired: 'Product cannot be empty',
validatorRowUnitRequired: 'Unit cannot be empty',
validatorRowTaskRequired: 'Production task cannot be empty',
validatorRowNumberRequired: 'Quantity cannot be empty',
itemNeedDialogTitlePrefix: 'Material Requirement: ',
itemNeedTableItemNameColumn: 'Material',
itemNeedTableUnitNameColumn: 'Unit',
itemNeedTableNumberColumn: 'Required Qty',
itemNeedTableStockNumberColumn: 'Stock',
itemNeedDialogCloseButtonText: 'Close',
itemNeedDialogUnknownTypeMessage: 'Unknown material analysis type!',
planDialogTaskCodeLabel: 'Product',
planDialogTaskCodePlaceholder: 'Please enter',
planDialogNumberLabel: 'Total',
planDialogNumberPlaceholder: 'Please enter',
planDialogPlanNumberLabel: 'Unfinished',
planDialogPlanNumberPlaceholder: 'Please enter',
planDialogProductsOfPlanLabel: 'Planned Output',
planDialogPlanDateLabel: 'Date',
planDialogPlanDatePlaceholder: 'Please select scheduling dates',
planDialogAutoButtonText: 'Auto Schedule',
planDialogResetButtonText: 'Clear Result',
planDialogTabPlanLabel: 'Pre-schedule Plan',
planDialogTabFinishPlanLabel: 'Scheduled Plan',
planDialogSubmitButtonText: 'Submit',
planDialogCancelButtonText: 'Cancel',
validatorPlanTaskIdRequired: 'Task order cannot be empty',
validatorPlanProductsOfPlanRequired: 'Planned quantity per plan cannot be empty',
planDialogTitlePrefix: 'Product Scheduling: ',
planDialogEmptyPlanMessage: 'Please do not submit empty plan!',
selectTaskTip: 'Please select a production task order'
},
TaskSummary: {
moduleName: 'Task Order Scheduling',
searchCodeLabel: 'Task Order Code',
searchCodePlaceholder: 'Please input code',
searchOrderLabel: 'Order Date',
searchOrderStartPlaceholder: 'Start Date',
searchOrderEndPlaceholder: 'End Date',
searchDeliveryLabel: 'Delivery Date',
searchDeliveryStartPlaceholder: 'Start Date',
searchDeliveryEndPlaceholder: 'End Date',
searchRemarkLabel: 'Remark',
searchRemarkPlaceholder: 'Please input remark',
searchCreateTimeLabel: 'Create Time',
searchCreateTimeStartPlaceholder: 'Start Date',
searchCreateTimeEndPlaceholder: 'End Date',
buttonSearchText: 'Search',
buttonResetText: 'Reset',
buttonExportText: 'Export',
tabAllLabel: 'All',
tabIssuedLabel: 'Issued',
tabPlanLabel: 'Planned',
tabStartLabel: 'Started',
tabFinishedLabel: 'Finished',
tabStoredLabel: 'Stored',
tableTaskCodeColumn: 'Task Order',
tableOrderDateColumn: 'Order Date',
tableDeliveryDateColumn: 'Delivery Date',
tableStatusColumn: 'Status',
tableRemarkColumn: 'Remark',
tableOperateColumn: 'Operate',
actionMaterialLabel: 'Material',
actionViewPlanLabel: 'View Plan',
detailTabSummaryLabel: 'Task Order Summary Details',
detailTableTaskCodeColumn: 'Task Order',
detailTableProductCodeColumn: 'Product Code',
detailTableProductNameColumn: 'Product Name',
detailTableTotalNumberColumn: 'Total Quantity',
detailTablePlanNumberColumn: 'Planned',
detailTableUnplanNumberColumn: 'Unplanned',
detailTableOperateColumn: 'Operate',
detailActionMaterialLabel: 'Material',
detailActionViewPlanLabel: 'View Plan',
detailActionCreatePlanLabel: 'Add Plan',
detailSelectTaskTip: 'Please select a production task order',
planDialogTaskIdLabel: 'Task Order',
planDialogTaskCodeLabel: 'Task Order',
planDialogProductsOfPlanLabel: 'Planned Output',
planDialogPlanDateLabel: 'Date',
planDialogPlanDatePlaceholder: 'Please select scheduling date',
planDialogAutoButtonText: 'Auto Schedule',
planDialogResetButtonText: 'Clear Result',
planDialogTabPlanLabel: 'Pre-scheduling Plan',
planDialogTabFinishPlanLabel: 'Scheduled Plan',
planDialogSubmitButtonText: 'Submit',
planDialogCancelButtonText: 'Cancel',
planDialogTitlePrefix: 'Task Order Scheduling: ',
validatorPlanTaskIdRequired: 'Task order can not be empty',
validatorPlanProductsOfPlanRequired: 'Planned quantity per batch can not be empty',
planDialogEmptyPlanMessage: 'Please do not submit empty plan!',
planFormIndexColumn: 'No.',
planFormCodeColumn: 'Plan Code',
planFormCodePlaceholder: 'Please input plan code',
planFormProductColumn: 'Product',
planFormProductIdPlaceholder: 'Please input product ID',
planFormProductNamePlaceholder: 'Please input product',
planFormPlanNumberColumn: 'Quantity',
planFormPlanNumberPlaceholder: 'Please input quantity',
planFormPlanStartTimeColumn: 'Plan Start Time',
planFormPlanStartTimePlaceholder: 'Select plan start time',
planFormPlanEndTimeColumn: 'Plan End Time',
planFormPlanEndTimePlaceholder: 'Select plan end time',
planFormRemarkColumn: 'Remark',
planFormOperateColumn: 'Operate',
planFormCopyButtonText: 'Copy',
planFormDeleteButtonText: 'Delete',
validatorPlanFormProductIdRequired: 'Product can not be empty',
validatorPlanFormTaskIdRequired: 'Task order can not be empty',
validatorPlanFormPlanNumberRequired: 'Quantity can not be empty',
validatorPlanFormPlanStartTimeRequired: 'Plan start time can not be empty',
validatorPlanFormPlanEndTimeRequired: 'Plan end time can not be empty'
},
Plan: {
moduleName: 'Production Plan',
searchTaskLabel: 'Task Order',
searchTaskPlaceholder: 'Please select task order',
searchCodeLabel: 'Plan Code',
searchCodePlaceholder: 'Please enter plan code',
searchProductLabel: 'Product',
searchProductPlaceholder: 'Please select product',
searchRemarkLabel: 'Remark',
searchRemarkPlaceholder: 'Please enter remark',
searchPlanStartLabel: 'Plan Start',
searchPlanStartStartPlaceholder: 'Start Date',
searchPlanStartEndPlaceholder: 'End Date',
searchPlanEndLabel: 'Plan End',
searchPlanEndStartPlaceholder: 'Start Date',
searchPlanEndEndPlaceholder: 'End Date',
buttonSearchText: 'Search',
buttonResetText: 'Reset',
buttonExportText: 'Export',
tabPlannedLabel: 'Scheduled',
tabTrialLabel: 'Trial',
tabMassLabel: 'Mass Production',
tabPausedLabel: 'Paused',
tabToStoreLabel: 'To Store',
tabStoredLabel: 'Stored',
detailItemRequisitionTabLabel: 'Material Details',
detailInspectTabLabel: 'Inspection Details',
detailBaogongRecordTabLabel: 'Report Records',
tableCodeColumn: 'Plan Code',
tableProductColumn: 'Product',
tableFeedingPipelineColumn: 'Production Line',
tablePlanNumberColumn: 'Planned Qty',
tableFinishNumberColumn: 'Finished Qty',
tablePassRateColumn: 'Pass Rate(%)',
tablePlanStartTimeColumn: 'Plan Start Time',
tablePlanEndTimeColumn: 'Plan End Time',
tableStatusColumn: 'Status',
tableIsZjColumn: 'Inspected',
tableOperateColumn: 'Operate',
actionDetailLabel: 'Detail',
actionEditLabel: 'Edit',
actionMaterialLabel: 'Material',
actionDispatchFeedingLabel: 'Feeding Dispatch',
actionDispatchProcessLabel: 'Process Dispatch',
actionTrialLabel: 'Trial',
actionInspectLabel: 'Inspect',
actionMassLabel: 'Mass Production',
actionBaogongLabel: 'Report',
actionPauseLabel: 'Pause',
actionFinishLabel: 'Finish',
actionStoreLabel: 'Store',
actionDeleteLabel: 'Delete',
statusConfirmTitle: 'Prompt',
statusConfirmMessage: 'Plan: {code} confirm {action}?',
inspectConfirmTitle: 'Prompt',
inspectConfirmMessage: 'Plan: {code} confirm inspection?',
dialogTaskLabel: 'Task Order',
dialogTaskPlaceholder: 'Please select task order',
dialogTaskDetailLabel: 'Detail Item',
dialogTaskDetailPlaceholder: 'Please select detail item',
dialogCodeLabel: 'Plan Code',
dialogCodeTooltip: 'Production plan code',
dialogCodePlaceholder: 'Code will be generated automatically after saving',
dialogFeedingPipelineLabel: 'Production Line',
dialogFeedingPipelinePlaceholder: 'Please select production line',
dialogWorkerLabel: 'Feeding Worker',
dialogWorkerPlaceholder: 'Please select worker',
dialogPlanNumberLabel: 'Quantity',
dialogPreProductionLabel: 'Trial Production',
dialogPlanStartLabel: 'Plan Start',
dialogPlanStartPlaceholder: 'Select plan start time',
dialogPlanEndLabel: 'Plan End',
dialogPlanEndPlaceholder: 'Select plan end time',
dialogRemarkLabel: 'Remark',
dialogRemarkPlaceholder: 'Please enter remark',
dialogSubmitButtonText: 'Confirm',
dialogCancelButtonText: 'Cancel',
validatorTaskDetailRequired: 'Detail item cannot be empty',
validatorTaskRequired: 'Task order cannot be empty',
validatorPlanNumberRequired: 'Quantity cannot be empty',
validatorPlanStartRequired: 'Plan start time cannot be empty',
validatorPlanEndRequired: 'Plan end time cannot be empty',
validatorFeedingPipelineRequired: 'Production line cannot be empty',
validatorWorkerRequired: 'Feeding worker cannot be empty',
validatorPreProductionRequired: 'Trial production cannot be empty',
dispatchDialogPlanLabel: 'Plan',
dispatchDialogPlanPlaceholder: 'Please enter plan ID',
dispatchDialogFeedingPipelineLabel: 'Pulp Line',
dispatchDialogFeedingPipelinePlaceholder: 'Please select pulp line',
dispatchDialogWorkerLabel: 'Worker',
dispatchDialogWorkerPlaceholder: 'Please select worker',
dispatchDialogRequisitionDateLabel: 'Planned Feeding',
dispatchDialogRequisitionDatePlaceholder: 'Select feeding time',
dispatchDialogRemarkLabel: 'Remark',
dispatchDialogRemarkPlaceholder: 'Please enter remark',
dispatchDialogSubmitButtonText: 'Submit',
dispatchDialogCancelButtonText: 'Cancel',
dispatchDialogTitle: 'Plan Dispatch: {code}',
dispatchSuccessMessage: 'Dispatch succeeded!',
typeDispatchDialogPipelineLabel: 'Production Line',
typeDispatchDialogPipelinePlaceholder: 'Please select production line',
typeDispatchDialogPaigongNumLabel: 'Dispatch Quantity',
typeDispatchDialogPaigongNumPlaceholder: 'Please enter quantity',
typeDispatchDialogPreProductionLabel: 'Trial Production',
typeDispatchDialogSubmitButtonText: 'Submit',
typeDispatchDialogCancelButtonText: 'Cancel',
validatorDispatchPlanRequired: 'Plan cannot be empty',
validatorDispatchFeedingPipelineRequired: 'Pulp line cannot be empty',
validatorDispatchWorkerRequired: 'Feeding worker cannot be empty',
validatorTypeDispatchPipelineRequired: 'Production line cannot be empty',
validatorTypeDispatchPreProductionRequired: 'Trial production cannot be empty',
validatorTypeDispatchPaigongNumRequired: 'Dispatch quantity cannot be empty',
baogongDialogPlanLabel: 'Plan',
baogongDialogPlanPlaceholder: 'Please enter plan ID',
baogongDialogQualifiedNumberLabel: 'Qualified Qty',
baogongDialogQualifiedNumberPlaceholder: 'Please enter quantity',
baogongDialogUnqualifiedNumberLabel: 'Unqualified Qty',
baogongDialogUnqualifiedNumberPlaceholder: 'Please enter quantity',
baogongDialogReasonLabel: 'Reason',
baogongDialogReasonPlaceholder: 'Please enter reason',
baogongDialogSubmitButtonText: 'Submit',
baogongDialogCancelButtonText: 'Cancel',
baogongDialogTitle: 'Plan Report: {code}',
validatorBaogongQualifiedRequired: 'Quantity cannot be empty',
validatorBaogongUnqualifiedRequired: 'Quantity cannot be empty',
baogongSuccessMessage: 'Report succeeded!',
detailDialogTitle: 'Detail',
detailDialogTaskLabel: 'Task Order',
detailDialogTaskPlaceholder: 'Please enter task order',
detailDialogProductLabel: 'Detail Item',
detailDialogProductPlaceholder: 'Please enter product',
detailDialogCodeLabel: 'Plan Code',
detailDialogCodePlaceholder: 'Please enter plan code',
detailDialogFeedingPipelineLabel: 'Production Line',
detailDialogFeedingPipelinePlaceholder: 'Please enter production line name',
detailDialogWorkerLabel: 'Worker',
detailDialogWorkerPlaceholder: 'Please enter worker',
detailDialogPlanNumberLabel: 'Quantity',
detailDialogPreProductionLabel: 'Trial Production',
detailDialogPlanStartLabel: 'Plan Start',
detailDialogPlanStartPlaceholder: 'Select plan start time',
detailDialogPlanEndLabel: 'Plan End',
detailDialogPlanEndPlaceholder: 'Select plan end time',
detailDialogRemarkLabel: 'Remark',
detailDialogRemarkPlaceholder: 'Please enter remark',
detailDialogCloseButtonText: 'Close',
itemNeedDialogPlanTitlePrefix: 'Plan-',
treeRootLabel: 'Top Production Line Station',
exportFilename: 'ProductionPlan.xls'
},
FeedingRecord: {
moduleName: 'Production Feeding',
searchCodeLabel: 'Record No.',
searchCodePlaceholder: 'Please enter record No.',
searchPipelineLabel: 'Pulp Line',
searchPipelinePlaceholder: 'Please select pulp line',
searchFeedingTimeLabel: 'Feeding Time',
searchFeedingTimeStartPlaceholder: 'Start Date',
searchFeedingTimeEndPlaceholder: 'End Date',
searchUserLabel: 'Recorder',
searchUserPlaceholder: 'Please enter recorder',
searchRemarkLabel: 'Remark',
searchRemarkPlaceholder: 'Please enter remark',
buttonSearchText: 'Search',
buttonResetText: 'Reset',
buttonCreateText: 'Add',
buttonExportText: 'Export',
tabAllLabel: 'All',
tabOrgLabel: 'Material',
tabDryLabel: 'Dry Scrap',
tabWetLabel: 'Wet Scrap',
detailTabFeedingDetailLabel: 'Feeding Detail',
tableCodeColumn: 'Record No.',
tablePipelineColumn: 'Pulp Line',
tableFeedingTypeColumn: 'Feeding Type',
tableWeightColumn: 'Quantity',
tableUserColumn: 'Recorder',
tableRemarkColumn: 'Remark',
tableFeedingTimeColumn: 'Feeding Time',
tableOperateColumn: 'Operate',
actionDeleteLabel: 'Delete',
actionFeedingLabel: 'Feed',
updateStatusConfirmMessage: 'Confirm to submit feeding record?',
updateStatusConfirmTitle: 'Once submitted, it cannot be undone!',
updateStatusSuccessMessage: 'Submitted successfully!',
dialogCodeLabel: 'Record No.',
dialogCodeTooltip: 'Record No.',
dialogCodePlaceholder: 'Code will be generated automatically after saving',
dialogFeedingTypeLabel: 'Feeding Type',
dialogFeedingTypeTooltip: 'Source: Data Dictionary - Production Feeding Type',
dialogPlanLabel: 'Production Plan',
dialogPlanPlaceholder: 'Please select production plan',
dialogPipelineLabel: 'Pulp Line',
dialogPipelinePlaceholder: 'Please select pulp line',
dialogProductLabel: 'Product',
dialogProductPlaceholder: 'Please select product',
dialogWeightLabel: 'Weight(kg)',
dialogWeightPlaceholder: 'Please enter weight',
dialogFeedingTimeLabel: 'Feeding Time',
dialogFeedingTimePlaceholder: 'Select feeding time',
dialogRemarkLabel: 'Remark',
dialogRemarkPlaceholder: 'Please enter remark',
dialogSubmitButtonText: 'Confirm',
dialogCancelButtonText: 'Cancel',
validatorFeedingTypeRequired: 'Feeding type cannot be empty',
validatorPipelineRequired: 'Pulp line cannot be empty',
validatorPlanRequired: 'Production plan cannot be empty',
validatorDetailWeightRequired: 'Quantity cannot be empty',
validatorDetailItemRequired: 'Material cannot be empty',
validatorDetailUnitRequired: 'Unit cannot be empty',
detailTableIndexColumn: 'No.',
detailTableItemColumn: 'Material',
detailTableUnitColumn: 'Unit',
detailTableWeightColumn: 'Quantity',
detailListItemColumn: 'Material',
detailListWeightColumn: 'Quantity',
detailListUnitColumn: 'Unit',
detailListFeedingTimeColumn: 'Feeding Time',
treeRootLabel: 'Top Production Line Station',
exportFilename: 'FeedingRecord.xls'
},
FormingRecord: {
moduleName: 'Forming Record',
searchOrganizationLabel: 'Station',
searchOrganizationPlaceholder: 'Please enter station',
searchMachineLabel: 'Machine',
searchMachinePlaceholder: 'Please enter machine',
searchTeamLabel: 'Team',
searchTeamPlaceholder: 'Please enter team',
searchRemarkLabel: 'Remark',
searchRemarkPlaceholder: 'Please enter remark',
searchStartTimeLabel: 'Start Time',
searchStartTimeStartPlaceholder: 'Start Date',
searchStartTimeEndPlaceholder: 'End Date',
searchEndTimeLabel: 'End Time',
searchEndTimeStartPlaceholder: 'Start Date',
searchEndTimeEndPlaceholder: 'End Date',
buttonSearchText: 'Search',
buttonResetText: 'Reset',
buttonCreateText: 'Add',
buttonExportText: 'Export',
tableNameColumn: 'Name',
tableOrganizationColumn: 'Station',
tableMachineColumn: 'Machine',
tableTeamColumn: 'Team',
tableStartTimeColumn: 'Start Time',
tableEndTimeColumn: 'End Time',
tableStatusColumn: 'Status',
tableProcessColumn: 'Process',
tableRemarkColumn: 'Remark',
tableCreateTimeColumn: 'Create Time',
tableOperateColumn: 'Operate',
tabFormingRecordLabel: 'Forming Record',
dialogTeamLabel: 'Team',
dialogTeamPlaceholder: 'Please enter team',
dialogOrganizationLabel: 'Station',
dialogOrganizationPlaceholder: 'Please enter station',
dialogMachineLabel: 'Machine',
dialogMachinePlaceholder: 'Please enter machine',
dialogStartTimeLabel: 'Start Time',
dialogStartTimePlaceholder: 'Select start time',
dialogEndTimeLabel: 'End Time',
dialogEndTimePlaceholder: 'Select end time',
dialogStatusLabel: 'Status',
dialogProcessLabel: 'Process',
dialogProcessPlaceholder: 'Please select process',
dialogRemarkLabel: 'Remark',
dialogRemarkPlaceholder: 'Please enter remark',
validatorOrganizationRequired: 'Station cannot be empty',
validatorStartTimeRequired: 'Start time cannot be empty',
validatorEndTimeRequired: 'End time cannot be empty',
validatorProcessRequired: 'Process cannot be empty',
detailListCreateTimeColumn: 'Create Time',
detailListCreatorColumn: 'Creator',
detailListXijiangColumn: 'Pulp Suction Time(S)',
detailListTuoshuiColumn: 'Dehydration Time(S)',
detailListXimuColumn: 'Mold Washing Time(S)',
detailListProductColumn: 'Product',
detailListAppearanceColumn: 'Product Appearance',
detailListProductWeightColumn: 'Wet Weight(g)',
detailListRemarkColumn: 'Remark',
detailListStartTimeColumn: 'Start-up Time',
detailListEndTimeColumn: 'Shutdown Time',
detailListOperateColumn: 'Operate',
detailDialogStartTimeLabel: 'Start-up Time',
detailDialogStartTimePlaceholder: 'Select start-up time',
detailDialogEndTimeLabel: 'Shutdown Time',
detailDialogEndTimePlaceholder: 'Select shutdown time',
detailDialogXijiangLabel: 'Pulp Suction Time(S)',
detailDialogXijiangPlaceholder: 'Please enter pulp suction time(S)',
detailDialogTuoshuiLabel: 'Dehydration Time(S)',
detailDialogTuoshuiPlaceholder: 'Please enter dehydration time(S)',
detailDialogXimuLabel: 'Mold Washing Time(S)',
detailDialogXimuPlaceholder: 'Please enter mold washing time(S)',
detailDialogProductLabel: 'Product',
detailDialogProductPlaceholder: 'Please select product',
detailDialogAppearanceLabel: 'Product Appearance',
detailDialogAppearancePlaceholder: 'Please enter product appearance',
detailDialogProductWeightLabel: 'Wet Weight(g)',
detailDialogProductWeightPlaceholder: 'Please enter wet weight(g)',
detailDialogRemarkLabel: 'Remark',
detailDialogRemarkPlaceholder: 'Please enter remark',
dialogSubmitButtonText: 'Confirm',
dialogCancelButtonText: 'Cancel',
detailValidatorRecordIdRequired: 'Record id cannot be empty',
detailValidatorXijiangRequired: 'Pulp suction time(S) cannot be empty',
detailValidatorTuoshuiRequired: 'Dehydration time(S) cannot be empty',
detailValidatorXimuRequired: 'Mold washing time(S) cannot be empty',
detailValidatorProductRequired: 'Product cannot be empty',
detailValidatorAppearanceRequired: 'Product appearance cannot be empty',
detailValidatorProductWeightRequired: 'Wet weight(g) cannot be empty',
messageSelectRecordRequired: 'Please select a record table',
actionEditLabel: 'Edit',
actionDeleteLabel: 'Delete',
exportFilename: 'FormingRecord.xls'
}
} }
} }

@ -1469,6 +1469,10 @@ export default {
finishDate: '完成日期', finishDate: '完成日期',
confirmDate: '验收日期', confirmDate: '验收日期',
repairResult: '维修结果', repairResult: '维修结果',
repairResultPending: '待维修',
repairResultOk: '通过',
repairResultNg: '不通过',
repairStatus: '结果',
status: '单据状态', status: '单据状态',
statusPending: '待完成', statusPending: '待完成',
statusDone: '已完成', statusDone: '已完成',
@ -1525,10 +1529,15 @@ export default {
subjectCode: '维修编码', subjectCode: '维修编码',
subjectName: '维修名称', subjectName: '维修名称',
subjectContent: '维修内容', subjectContent: '维修内容',
remark: '备注',
result: '结果',
resultOk: '通过',
resultNg: '不通过',
addLine: '添加维修项目', addLine: '添加维修项目',
placeholderSubjectCode: '请输入维修编码', placeholderSubjectCode: '请输入维修编码',
placeholderSubjectName: '请输入维修名称', placeholderSubjectName: '请输入维修名称',
placeholderSubjectContent: '请输入维修内容', placeholderSubjectContent: '请输入维修内容',
placeholderRemark: '请输入备注',
validatorRepairIdRequired: '维修单ID不能为空', validatorRepairIdRequired: '维修单ID不能为空',
validatorSubjectIdRequired: '项目ID不能为空', validatorSubjectIdRequired: '项目ID不能为空',
validatorSubjectCodeRequired: '项目编码不能为空', validatorSubjectCodeRequired: '项目编码不能为空',
@ -1752,6 +1761,8 @@ export default {
createTime: '创建时间', createTime: '创建时间',
operate: '操作', operate: '操作',
inspect: '检验', inspect: '检验',
cancelTask: '取消任务',
cancelSuccess: '取消任务成功',
exportFilename: '质量管理-检验任务.xls', exportFilename: '质量管理-检验任务.xls',
placeholderCode: '请输入单号', placeholderCode: '请输入单号',
placeholderType: '请选择质检分类', placeholderType: '请选择质检分类',
@ -2410,5 +2421,628 @@ export default {
validatorStatusRequired: '单位状态不能为空', validatorStatusRequired: '单位状态不能为空',
validatorPrimaryFlagRequired: '是否主单位不能为空' validatorPrimaryFlagRequired: '是否主单位不能为空'
} }
},
ProductionPlan: {
Task: {
moduleName: '生产任务单',
searchCodeLabel: '编码',
searchCodePlaceholder: '请输入编码',
searchOrderLabel: '下达',
searchOrderStartPlaceholder: '开始日期',
searchOrderEndPlaceholder: '结束日期',
searchDeliveryLabel: '交货',
searchDeliveryStartPlaceholder: '开始日期',
searchDeliveryEndPlaceholder: '结束日期',
searchRemarkLabel: '备注',
searchRemarkPlaceholder: '请输入备注',
searchCreateTimeLabel: '创建时间',
searchCreateTimeStartPlaceholder: '开始日期',
searchCreateTimeEndPlaceholder: '结束日期',
buttonSearchText: '搜索',
buttonResetText: '重置',
buttonCreateText: '新增',
buttonExportText: '导出',
tabAllLabel: '所有',
tabDraftLabel: '草稿',
tabSubmitLabel: '送审',
tabIssuedLabel: '下达',
tabPlanLabel: '计划',
tabStartLabel: '开工',
tabFinishedLabel: '完工',
tabStoredLabel: '入库',
tableCodeColumn: '编码',
tableOrderDateColumn: '下达日期',
tableDeliveryDateColumn: '交货日期',
tableTaskTypeColumn: '类型',
tableStatusColumn: '状态',
tableRemarkColumn: '备注',
tableOperateColumn: '操作',
actionSubmitLabel: '送审',
actionApproveLabel: '审核',
actionMaterialLabel: '物料',
actionEditLabel: '编辑',
actionDeleteLabel: '删除',
detailTabTaskDetailLabel: '任务单明细',
dialogCodeLabel: '任务单编码',
dialogCodeTooltip: '任务单编码',
dialogCodePlaceholder: '编码保存后自动生成',
dialogDeliveryDateLabel: '交货日期',
dialogDeliveryDatePlaceholder: '选择交货日期',
dialogTaskTypeLabel: '任务类型',
dialogTaskTypeTooltip: '来源:数据字典-任务单类型',
dialogRemarkLabel: '备注',
dialogRemarkPlaceholder: '请输入备注',
dialogSubmitButtonText: '确 定',
dialogCancelButtonText: '取 消',
validatorDeliveryDateRequired: '交货日期不能为空',
validatorTaskTypeRequired: '任务类型不能为空',
saleDialogCodeLabel: '编码',
saleDialogCodePlaceholder: '请输入任务单编码',
saleDialogDeliveryDateLabel: '交货日期',
saleDialogDeliveryDatePlaceholder: '选择交货日期',
saleDialogRemarkLabel: '备注',
saleDialogRemarkPlaceholder: '请输入备注',
saleDialogTaskTypeLabel: '任务类型',
saleDetailTabTaskDetailLabel: '生产任务单明细',
saleValidatorCodeRequired: '编码不能为空',
saleValidatorDeliveryDateRequired: '交货日期不能为空',
saleValidatorTaskTypeRequired: '任务类型不能为空',
detailListCreateButtonText: '新增',
detailListProductCodeColumn: '产品编码',
detailListProductNameColumn: '产品名称',
detailListUnitColumn: '单位',
detailListNumberColumn: '数量',
detailListPlanNumberColumn: '已计划',
detailListFinishDateColumn: '交货日期',
detailListTechRequirementsColumn: '技术要求',
detailListOperateColumn: '操作',
detailListViewActionText: '详情',
detailListMaterialActionText: '物料',
detailListEditActionText: '编辑',
detailListDeleteActionText: '删除',
detailDialogProductLabel: '产品',
detailDialogProductPlaceholder: '请选择产品',
detailDialogUnitLabel: '单位',
detailDialogUnitPlaceholder: '请选择产品',
detailDialogNumberLabel: '数量',
detailDialogNumberPlaceholder: '请输入数量',
detailDialogProjectLabel: '项目',
detailDialogProjectPlaceholder: '请输入项目名称',
detailDialogPackageSizeLabel: '每包数量',
detailDialogPackageSizePlaceholder: '请输入打包要求',
detailDialogPackageNumberLabel: '打包数量',
detailDialogPackageNumberPlaceholder: '请输入数量',
detailDialogTechRequirementsLabel: '技术要求',
detailDialogTechRequirementsPlaceholder: '请输入技术要求',
detailDialogFinishDateLabel: '工厂完成',
detailDialogFinishDatePlaceholder: '选择工厂完成日期',
detailFormDeliveryDateLabel: '交货日期',
detailFormDeliveryDatePlaceholder: '选择交货日期',
detailDialogBoxingDateLabel: '装柜日期',
detailDialogBoxingDatePlaceholder: '选择装柜日期',
detailDialogArriveDateLabel: '到达日期',
detailDialogArriveDatePlaceholder: '选择到达日期',
detailDialogRemarkLabel: '备注:',
detailDialogSubmitButtonText: '确 定',
detailDialogCancelButtonText: '取 消',
validatorDetailProductIdRequired: '产品ID不能为空',
validatorDetailUnitIdRequired: '单位ID不能为空',
validatorDetailTaskIdRequired: 'task ID不能为空',
validatorDetailNumberRequired: '数量不能为空',
validatorDetailPackageSizeRequired: '打包要求(每包/个)不能为空',
saleDetailTableIndexColumn: '序号',
saleDetailTableProductColumn: '产品',
saleDetailTableUnitColumn: '单位',
saleDetailTableNumberColumn: '数量',
saleDetailTablePackageSizeColumn: '每包/个',
saleDetailTablePackageNumberColumn: '打包数量',
saleDetailTableProjectNameColumn: '项目名称',
saleDetailTableTechRequirementsColumn: '技术要求',
saleDetailTableRemarkColumn: '备注',
saleDetailTableFinishDateColumn: '工厂完成',
saleDetailTableBoxingDateColumn: '装柜时间',
saleDetailTableArriveDateColumn: '到达时间',
saleDetailTableBarCodeColumn: '条码',
saleDetailTableOperateColumn: '操作',
saleDetailAddRowButtonText: '+ 添加任务单明细',
saleDetailAddFromOrderButtonText: '+ 从销售单添加',
saleDetailProductPlaceholder: '请选择',
validatorRowProductRequired: '产品不能为空',
validatorRowUnitRequired: '单位不能为空',
validatorRowTaskRequired: '生产任务不能为空',
validatorRowNumberRequired: '数量不能为空',
itemNeedDialogTitlePrefix: '物料需求:',
itemNeedTableItemNameColumn: '原料',
itemNeedTableUnitNameColumn: '单位',
itemNeedTableNumberColumn: '需求量',
itemNeedTableStockNumberColumn: '库存',
itemNeedDialogCloseButtonText: '关 闭',
itemNeedDialogUnknownTypeMessage: '无法识别的物料分析类型!',
planDialogTaskCodeLabel: '产品',
planDialogTaskCodePlaceholder: '请输入',
planDialogNumberLabel: '总数',
planDialogNumberPlaceholder: '请输入',
planDialogPlanNumberLabel: '未完成数',
planDialogPlanNumberPlaceholder: '请输入',
planDialogProductsOfPlanLabel: '计划产量',
planDialogPlanDateLabel: '日期',
planDialogPlanDatePlaceholder: '请选择排产日期',
planDialogAutoButtonText: '自动排产',
planDialogResetButtonText: '清空结果',
planDialogTabPlanLabel: '预排产计划',
planDialogTabFinishPlanLabel: '已排产计划',
planDialogSubmitButtonText: '提 交',
planDialogCancelButtonText: '取 消',
validatorPlanTaskIdRequired: '任务单不能为空',
validatorPlanProductsOfPlanRequired: '单个计划生产数量不能为空',
planDialogTitlePrefix: '产品排产:',
planDialogEmptyPlanMessage: '请勿提交空计划!',
selectTaskTip: '请选择一个生产任务单'
},
TaskSummary: {
moduleName: '任务单排产',
searchCodeLabel: '任务单编码',
searchCodePlaceholder: '请输入编码',
searchOrderLabel: '下达时间',
searchOrderStartPlaceholder: '开始日期',
searchOrderEndPlaceholder: '结束日期',
searchDeliveryLabel: '交货时间',
searchDeliveryStartPlaceholder: '开始日期',
searchDeliveryEndPlaceholder: '结束日期',
searchRemarkLabel: '备注',
searchRemarkPlaceholder: '请输入备注',
searchCreateTimeLabel: '创建时间',
searchCreateTimeStartPlaceholder: '开始日期',
searchCreateTimeEndPlaceholder: '结束日期',
buttonSearchText: '搜索',
buttonResetText: '重置',
buttonExportText: '导出',
tabAllLabel: '所有',
tabIssuedLabel: '下达',
tabPlanLabel: '计划',
tabStartLabel: '开工',
tabFinishedLabel: '完工',
tabStoredLabel: '入库',
tableTaskCodeColumn: '任务单',
tableOrderDateColumn: '下达日期',
tableDeliveryDateColumn: '交货日期',
tableStatusColumn: '状态',
tableRemarkColumn: '备注',
tableOperateColumn: '操作',
actionMaterialLabel: '物料',
actionViewPlanLabel: '查看计划',
detailTabSummaryLabel: '任务单汇总明细',
detailTableTaskCodeColumn: '任务单',
detailTableProductCodeColumn: '产品编码',
detailTableProductNameColumn: '产品名称',
detailTableTotalNumberColumn: '任务总数',
detailTablePlanNumberColumn: '已计划',
detailTableUnplanNumberColumn: '未计划',
detailTableOperateColumn: '操作',
detailActionMaterialLabel: '物料',
detailActionViewPlanLabel: '查看计划',
detailActionCreatePlanLabel: '新增计划',
detailSelectTaskTip: '请选择一个生产任务单',
planDialogTaskIdLabel: '任务单',
planDialogTaskCodeLabel: '任务单',
planDialogProductsOfPlanLabel: '计划产量',
planDialogPlanDateLabel: '日期',
planDialogPlanDatePlaceholder: '请选择排产日期',
planDialogAutoButtonText: '自动排产',
planDialogResetButtonText: '清空结果',
planDialogTabPlanLabel: '预排产计划',
planDialogTabFinishPlanLabel: '已排产计划',
planDialogSubmitButtonText: '提 交',
planDialogCancelButtonText: '取 消',
planDialogTitlePrefix: '任务单排产:',
validatorPlanTaskIdRequired: '任务单不能为空',
validatorPlanProductsOfPlanRequired: '单个计划生产数量不能为空',
planDialogEmptyPlanMessage: '请勿提交空计划!',
planFormIndexColumn: '序号',
planFormCodeColumn: '计划编码',
planFormCodePlaceholder: '请输入计划编码',
planFormProductColumn: '产品',
planFormProductIdPlaceholder: '请输入产品ID',
planFormProductNamePlaceholder: '请输入产品',
planFormPlanNumberColumn: '数量',
planFormPlanNumberPlaceholder: '请输入数量',
planFormPlanStartTimeColumn: '计划开始时间',
planFormPlanStartTimePlaceholder: '选择计划开始时间',
planFormPlanEndTimeColumn: '计划结束时间',
planFormPlanEndTimePlaceholder: '选择计划结束时间',
planFormRemarkColumn: '备注',
planFormOperateColumn: '操作',
planFormCopyButtonText: '复制',
planFormDeleteButtonText: '删除',
validatorPlanFormProductIdRequired: '产品不能为空',
validatorPlanFormTaskIdRequired: '任务单不能为空',
validatorPlanFormPlanNumberRequired: '数量不能为空',
validatorPlanFormPlanStartTimeRequired: '计划开始时间不能为空',
validatorPlanFormPlanEndTimeRequired: '计划结束时间不能为空'
},
Plan: {
moduleName: '生产计划',
searchTaskLabel: '任务单',
searchTaskPlaceholder: '请选择任务单',
searchCodeLabel: '计划编码',
searchCodePlaceholder: '请输入计划编码',
searchProductLabel: '产品',
searchProductPlaceholder: '请选择产品',
searchRemarkLabel: '备注',
searchRemarkPlaceholder: '请输入备注',
searchPlanStartLabel: '计划开始',
searchPlanStartStartPlaceholder: '开始日期',
searchPlanStartEndPlaceholder: '结束日期',
searchPlanEndLabel: '计划结束',
searchPlanEndStartPlaceholder: '开始日期',
searchPlanEndEndPlaceholder: '结束日期',
buttonSearchText: '搜索',
buttonResetText: '重置',
buttonExportText: '导出',
tabPlannedLabel: '已排产',
tabTrialLabel: '试产',
tabMassLabel: '量产',
tabPausedLabel: '暂停',
tabToStoreLabel: '待入库',
tabStoredLabel: '已入库',
detailItemRequisitionTabLabel: '投料明细',
detailInspectTabLabel: '检验明细',
detailBaogongRecordTabLabel: '报工记录',
tableCodeColumn: '计划编码',
tableProductColumn: '产品',
tableFeedingPipelineColumn: '生产线',
tablePlanNumberColumn: '计划数量',
tableFinishNumberColumn: '完工数量',
tablePassRateColumn: '合格率(%)',
tablePlanStartTimeColumn: '计划开始时间',
tablePlanEndTimeColumn: '计划结束时间',
tableStatusColumn: '状态',
tableIsZjColumn: '是否检验',
tableOperateColumn: '操作',
actionDetailLabel: '详情',
actionEditLabel: '编辑',
actionMaterialLabel: '物料',
actionDispatchFeedingLabel: '下料派工',
actionDispatchProcessLabel: '工序派工',
actionTrialLabel: '试产',
actionInspectLabel: '检验',
actionMassLabel: '量产',
actionBaogongLabel: '报工',
actionPauseLabel: '暂停',
actionFinishLabel: '完工',
actionStoreLabel: '入库',
actionDeleteLabel: '删除',
statusConfirmTitle: '提示',
statusConfirmMessage: '计划:{code}确定{action}吗?',
inspectConfirmTitle: '提示',
inspectConfirmMessage: '计划:{code}确定质检吗?',
dialogTaskLabel: '任务单',
dialogTaskPlaceholder: '请选择任务单',
dialogTaskDetailLabel: '明细项',
dialogTaskDetailPlaceholder: '请选择明细项',
dialogCodeLabel: '计划编码',
dialogCodeTooltip: '生产计划编码',
dialogCodePlaceholder: '编码保存后自动生成',
dialogFeedingPipelineLabel: '生产线',
dialogFeedingPipelinePlaceholder: '请选择生产线',
dialogWorkerLabel: '领料人',
dialogWorkerPlaceholder: '请选择领料人',
dialogPlanNumberLabel: '数量',
dialogPreProductionLabel: '是否试生产',
dialogPlanStartLabel: '计划开始',
dialogPlanStartPlaceholder: '选择计划开始时间',
dialogPlanEndLabel: '计划结束',
dialogPlanEndPlaceholder: '选择计划结束时间',
dialogRemarkLabel: '备注',
dialogRemarkPlaceholder: '请输入备注',
dialogSubmitButtonText: '确 定',
dialogCancelButtonText: '取 消',
validatorTaskDetailRequired: '明细项不能为空',
validatorTaskRequired: '任务单不能为空',
validatorPlanNumberRequired: '数量不能为空',
validatorPlanStartRequired: '计划开始时间不能为空',
validatorPlanEndRequired: '计划结束时间不能为空',
validatorFeedingPipelineRequired: '生产线不能为空',
validatorWorkerRequired: '下料工人不能为空',
validatorPreProductionRequired: '试生产不能为空',
dispatchDialogPlanLabel: '计划',
dispatchDialogPlanPlaceholder: '请输入计划ID',
dispatchDialogFeedingPipelineLabel: '制浆线',
dispatchDialogFeedingPipelinePlaceholder: '请选择制浆线',
dispatchDialogWorkerLabel: '领料人',
dispatchDialogWorkerPlaceholder: '请选择工人',
dispatchDialogRequisitionDateLabel: '计划下料',
dispatchDialogRequisitionDatePlaceholder: '选择下料时间',
dispatchDialogRemarkLabel: '备注',
dispatchDialogRemarkPlaceholder: '请输入备注',
dispatchDialogSubmitButtonText: '提 交',
dispatchDialogCancelButtonText: '取 消',
dispatchDialogTitle: '计划派工:{code}',
dispatchSuccessMessage: '派工成功!',
typeDispatchDialogPipelineLabel: '生产线',
typeDispatchDialogPipelinePlaceholder: '请选择生产线',
typeDispatchDialogPaigongNumLabel: '派工数量',
typeDispatchDialogPaigongNumPlaceholder: '请输入数量',
typeDispatchDialogPreProductionLabel: '是否试生产',
typeDispatchDialogSubmitButtonText: '提 交',
typeDispatchDialogCancelButtonText: '取 消',
validatorDispatchPlanRequired: '计划不能为空',
validatorDispatchFeedingPipelineRequired: '制浆线不能为空',
validatorDispatchWorkerRequired: '下料工人不能为空',
validatorTypeDispatchPipelineRequired: '生产线不能为空',
validatorTypeDispatchPreProductionRequired: '试生产不能为空',
validatorTypeDispatchPaigongNumRequired: '派工数量不能为空',
baogongDialogPlanLabel: '计划',
baogongDialogPlanPlaceholder: '请输入计划ID',
baogongDialogQualifiedNumberLabel: '合格数量',
baogongDialogQualifiedNumberPlaceholder: '请输入数量',
baogongDialogUnqualifiedNumberLabel: '不合格数量',
baogongDialogUnqualifiedNumberPlaceholder: '请输入数量',
baogongDialogReasonLabel: '原因',
baogongDialogReasonPlaceholder: '请输入原因',
baogongDialogSubmitButtonText: '提 交',
baogongDialogCancelButtonText: '取 消',
baogongDialogTitle: '计划报工:{code}',
validatorBaogongQualifiedRequired: '数量不能为空',
validatorBaogongUnqualifiedRequired: '数量不能为空',
baogongSuccessMessage: '报工成功!',
detailDialogTitle: '详情',
detailDialogTaskLabel: '任务单',
detailDialogTaskPlaceholder: '请输入任务单',
detailDialogProductLabel: '明细项',
detailDialogProductPlaceholder: '请输入产品',
detailDialogCodeLabel: '计划编码',
detailDialogCodePlaceholder: '请输入计划编码',
detailDialogFeedingPipelineLabel: '生产线',
detailDialogFeedingPipelinePlaceholder: '请输入生产线名称',
detailDialogWorkerLabel: '领料人',
detailDialogWorkerPlaceholder: '请输入领料人',
detailDialogPlanNumberLabel: '数量',
detailDialogPreProductionLabel: '是否试生产',
detailDialogPlanStartLabel: '计划开始',
detailDialogPlanStartPlaceholder: '选择计划开始时间',
detailDialogPlanEndLabel: '计划结束',
detailDialogPlanEndPlaceholder: '选择计划结束时间',
detailDialogRemarkLabel: '备注',
detailDialogRemarkPlaceholder: '请输入备注',
detailDialogCloseButtonText: '关 闭',
itemNeedDialogPlanTitlePrefix: '计划-',
treeRootLabel: '顶级产线工位',
exportFilename: '生产计划.xls'
},
FeedingRecord: {
moduleName: '生产投料',
searchCodeLabel: '单号',
searchCodePlaceholder: '请输入单号',
searchPipelineLabel: '制浆线',
searchPipelinePlaceholder: '请选择制浆线',
searchFeedingTimeLabel: '投料时间',
searchFeedingTimeStartPlaceholder: '开始日期',
searchFeedingTimeEndPlaceholder: '结束日期',
searchUserLabel: '记录人',
searchUserPlaceholder: '请输入记录人',
searchRemarkLabel: '备注',
searchRemarkPlaceholder: '请输入备注',
buttonSearchText: '搜索',
buttonResetText: '重置',
buttonCreateText: '新增',
buttonExportText: '导出',
tabAllLabel: '所有',
tabOrgLabel: '领料',
tabDryLabel: '干废品',
tabWetLabel: '湿废品',
detailTabFeedingDetailLabel: '投料明细',
tableCodeColumn: '单号',
tablePipelineColumn: '制浆线',
tableFeedingTypeColumn: '投料类型',
tableWeightColumn: '数量',
tableUserColumn: '记录人',
tableRemarkColumn: '备注',
tableFeedingTimeColumn: '投料时间',
tableOperateColumn: '操作',
actionDeleteLabel: '删除',
actionFeedingLabel: '投料',
updateStatusConfirmMessage: '确认提交投料记录?',
updateStatusConfirmTitle: '一旦提交成功无法撤回!',
updateStatusSuccessMessage: '提交成功!',
dialogCodeLabel: '单号',
dialogCodeTooltip: '单号',
dialogCodePlaceholder: '编码保存后自动生成',
dialogFeedingTypeLabel: '投料类型',
dialogFeedingTypeTooltip: '来源:数据字典-生产投料类型',
dialogPlanLabel: '生产计划',
dialogPlanPlaceholder: '请选择生产计划',
dialogPipelineLabel: '制浆线',
dialogPipelinePlaceholder: '请选择制浆线',
dialogProductLabel: '产品',
dialogProductPlaceholder: '请选择产品',
dialogWeightLabel: '重量(kg)',
dialogWeightPlaceholder: '请输入重量',
dialogFeedingTimeLabel: '投料时间',
dialogFeedingTimePlaceholder: '选择投料时间',
dialogRemarkLabel: '备注',
dialogRemarkPlaceholder: '请输入备注',
dialogSubmitButtonText: '确 定',
dialogCancelButtonText: '取 消',
validatorFeedingTypeRequired: '投料类型不能为空',
validatorPipelineRequired: '制浆线不能为空',
validatorPlanRequired: '生产计划不能为空',
validatorDetailWeightRequired: '数量不能为空',
validatorDetailItemRequired: '原料不能为空',
validatorDetailUnitRequired: '单位不能为空',
detailTableIndexColumn: '序号',
detailTableItemColumn: '原料',
detailTableUnitColumn: '单位',
detailTableWeightColumn: '数量',
detailListItemColumn: '原料',
detailListWeightColumn: '数量',
detailListUnitColumn: '单位',
detailListFeedingTimeColumn: '投料时间',
treeRootLabel: '顶级产线工位',
exportFilename: '投料记录.xls'
},
FormingRecord: {
moduleName: '成型记录',
searchOrganizationLabel: '工位',
searchOrganizationPlaceholder: '请输入工位',
searchMachineLabel: '机台',
searchMachinePlaceholder: '请输入机台',
searchTeamLabel: '班组',
searchTeamPlaceholder: '请输入班组',
searchRemarkLabel: '备注',
searchRemarkPlaceholder: '请输入备注',
searchStartTimeLabel: '开始时间',
searchStartTimeStartPlaceholder: '开始日期',
searchStartTimeEndPlaceholder: '结束日期',
searchEndTimeLabel: '结束时间',
searchEndTimeStartPlaceholder: '开始日期',
searchEndTimeEndPlaceholder: '结束日期',
buttonSearchText: '搜索',
buttonResetText: '重置',
buttonCreateText: '新增',
buttonExportText: '导出',
tableNameColumn: '名称',
tableOrganizationColumn: '工位',
tableMachineColumn: '机台',
tableTeamColumn: '班组',
tableStartTimeColumn: '开始时间',
tableEndTimeColumn: '结束时间',
tableStatusColumn: '状态',
tableProcessColumn: '工序',
tableRemarkColumn: '备注',
tableCreateTimeColumn: '创建时间',
tableOperateColumn: '操作',
tabFormingRecordLabel: '成型记录',
dialogTeamLabel: '班组',
dialogTeamPlaceholder: '请输入班组',
dialogOrganizationLabel: '工位',
dialogOrganizationPlaceholder: '请输入工位',
dialogMachineLabel: '机台',
dialogMachinePlaceholder: '请输入机台',
dialogStartTimeLabel: '开始时间',
dialogStartTimePlaceholder: '选择开始时间',
dialogEndTimeLabel: '结束时间',
dialogEndTimePlaceholder: '选择结束时间',
dialogStatusLabel: '状态',
dialogProcessLabel: '工序',
dialogProcessPlaceholder: '请选择工序',
dialogRemarkLabel: '备注',
dialogRemarkPlaceholder: '请输入备注',
validatorOrganizationRequired: '工位不能为空',
validatorStartTimeRequired: '开始时间不能为空',
validatorEndTimeRequired: '结束时间不能为空',
validatorProcessRequired: '工序不能为空',
detailListCreateTimeColumn: '创建时间',
detailListCreatorColumn: '创建者',
detailListXijiangColumn: '吸浆时间(S)',
detailListTuoshuiColumn: '脱水时间(S)',
detailListXimuColumn: '洗模时间(S)',
detailListProductColumn: '产品',
detailListAppearanceColumn: '产品外观',
detailListProductWeightColumn: '湿重(g)',
detailListRemarkColumn: '备注',
detailListStartTimeColumn: '开机时间',
detailListEndTimeColumn: '停机时间',
detailListOperateColumn: '操作',
detailDialogStartTimeLabel: '开机时间',
detailDialogStartTimePlaceholder: '选择开机时间',
detailDialogEndTimeLabel: '停机时间',
detailDialogEndTimePlaceholder: '选择停机时间',
detailDialogXijiangLabel: '吸浆时间(S)',
detailDialogXijiangPlaceholder: '请输入吸浆时间(S)',
detailDialogTuoshuiLabel: '脱水时间(S)',
detailDialogTuoshuiPlaceholder: '请输入脱水时间(S)',
detailDialogXimuLabel: '洗模时间(S)',
detailDialogXimuPlaceholder: '请输入洗模时间(S)',
detailDialogProductLabel: '产品',
detailDialogProductPlaceholder: '请选择产品',
detailDialogAppearanceLabel: '产品外观',
detailDialogAppearancePlaceholder: '请输入产品外观',
detailDialogProductWeightLabel: '湿重(g)',
detailDialogProductWeightPlaceholder: '请输入湿重(g)',
detailDialogRemarkLabel: '备注',
detailDialogRemarkPlaceholder: '请输入备注',
dialogSubmitButtonText: '确 定',
dialogCancelButtonText: '取 消',
detailValidatorRecordIdRequired: '记录id不能为空',
detailValidatorXijiangRequired: '吸浆时间(S)不能为空',
detailValidatorTuoshuiRequired: '脱水时间(S)不能为空',
detailValidatorXimuRequired: '洗模时间(S)不能为空',
detailValidatorProductRequired: '产品不能为空',
detailValidatorAppearanceRequired: '产品外观不能为空',
detailValidatorProductWeightRequired: '湿重(g)不能为空',
messageSelectRecordRequired: '请选择一个记录表',
actionEditLabel: '编辑',
actionDeleteLabel: '删除',
exportFilename: '成型记录.xls'
}
} }
} }

@ -766,6 +766,24 @@ const getKanban = async () => {
getAllApi() getAllApi()
</script> </script>
<style scoped> <style scoped>
@media (width <= 768px) {
.home-welcome {
flex-direction: column;
align-items: flex-start;
}
.home-welcome-left {
max-width: 100%;
margin-bottom: 12px;
}
.home-welcome-right img {
width: 100%;
}
}
.home-page { .home-page {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -945,10 +963,12 @@ getAllApi()
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
} }
/* 左箭头往右移动 */ /* 左箭头往右移动 */
.progress-carousel :deep(.el-carousel__arrow--left) { .progress-carousel :deep(.el-carousel__arrow--left) {
transform: translate(30px, -50%); /* X轴移动30pxY轴居中 */ transform: translate(30px, -50%); /* X轴移动30pxY轴居中 */
} }
/* 右箭头往左移动 */ /* 右箭头往左移动 */
.progress-carousel :deep(.el-carousel__arrow--right) { .progress-carousel :deep(.el-carousel__arrow--right) {
transform: translate(-30px, -50%); /* X轴移动-30pxY轴居中 */ transform: translate(-30px, -50%); /* X轴移动-30pxY轴居中 */
@ -1055,20 +1075,4 @@ getAllApi()
font-size: 12px; font-size: 12px;
color: #909399; color: #909399;
} }
@media (width <= 768px) {
.home-welcome {
flex-direction: column;
align-items: flex-start;
}
.home-welcome-left {
max-width: 100%;
margin-bottom: 12px;
}
.home-welcome-right img {
width: 100%;
}
}
</style> </style>

@ -2,15 +2,15 @@
<Dialog :title="dialogTitle" v-model="dialogVisible" width="1000px"> <Dialog :title="dialogTitle" v-model="dialogVisible" width="1000px">
<!-- 列表 --> <!-- 列表 -->
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="原料" align="center" prop="itemName" /> <el-table-column :label="t('ProductionPlan.Task.itemNeedTableItemNameColumn')" align="center" prop="itemName" />
<el-table-column label="单位" align="center" prop="unitName" /> <el-table-column :label="t('ProductionPlan.Task.itemNeedTableUnitNameColumn')" align="center" prop="unitName" />
<el-table-column label="需求量" align="center" prop="number" /> <el-table-column :label="t('ProductionPlan.Task.itemNeedTableNumberColumn')" align="center" prop="number" />
<el-table-column label="库存" align="center" prop="stockNumber" /> <el-table-column :label="t('ProductionPlan.Task.itemNeedTableStockNumberColumn')" align="center" prop="stockNumber" />
<!-- <el-table-column label="车间仓库存" align="center" prop="stockWorkshopNumber" /> --> <!-- <el-table-column label="车间仓库存" align="center" prop="stockWorkshopNumber" /> -->
</el-table> </el-table>
<template #footer> <template #footer>
<!-- <el-button @click="openForm" type="primary" :disabled="loading"> </el-button> --> <!-- <el-button @click="openForm" type="primary" :disabled="loading"> </el-button> -->
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.Task.itemNeedDialogCloseButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
<!-- 表单弹窗添加/修改 --> <!-- 表单弹窗添加/修改 -->
@ -45,7 +45,7 @@ const dialogTitle = ref('') // 弹窗的标题
/** 打开弹窗 */ /** 打开弹窗 */
const open = async (type: string, title: string, id: number, number?:number) => { const open = async (type: string, title: string, id: number, number?:number) => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = '物料需求:'+title dialogTitle.value = t('ProductionPlan.Task.itemNeedDialogTitlePrefix') + title
loading.value = true loading.value = true
try { try {
if (type === 'order') { if (type === 'order') {
@ -60,7 +60,7 @@ const open = async (type: string, title: string, id: number, number?:number) =>
else if (type === 'product') { else if (type === 'product') {
list.value = await TaskApi.getProductItemNeedList(id, number) list.value = await TaskApi.getProductItemNeedList(id, number)
} }
else message.error("无法识别的物料分析类型!") else message.error(t('ProductionPlan.Task.itemNeedDialogUnknownTypeMessage'))
} finally { } finally {
loading.value = false loading.value = false
} }

@ -150,41 +150,35 @@
</el-col> </el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item :label="t('EquipmentManagement.EquipmentLedger.criticalComponent')" prop="componentIds"> <el-form-item :label="t('EquipmentManagement.EquipmentLedger.criticalComponent')" prop="componentIds">
<el-select <el-cascader
v-model="formData.componentIds" v-model="criticalComponentCascaderValue"
multiple :options="criticalComponentPagedOptions"
:props="cascaderProps"
filterable filterable
clearable clearable
collapse-tags
:show-all-levels="false"
:placeholder="t('EquipmentManagement.EquipmentLedger.placeholderComponentIds')" :placeholder="t('EquipmentManagement.EquipmentLedger.placeholderComponentIds')"
class="!w-full" class="!w-full"
> @change="handleCriticalComponentChange"
<el-option />
v-for="item in criticalComponentOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item :label="t('EquipmentManagement.EquipmentLedger.sparePart')" prop="beijianIds"> <el-form-item :label="t('EquipmentManagement.EquipmentLedger.sparePart')" prop="beijianIds">
<el-select <el-cascader
v-model="formData.beijianIds" v-model="beijianCascaderValue"
multiple :options="beijianPagedOptions"
:props="cascaderProps"
filterable filterable
clearable clearable
collapse-tags
:show-all-levels="false"
:placeholder="t('EquipmentManagement.EquipmentLedger.placeholderBeijianIds')" :placeholder="t('EquipmentManagement.EquipmentLedger.placeholderBeijianIds')"
class="!w-full" class="!w-full"
> @change="handleBeijianChange"
<el-option />
v-for="item in beijianOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -294,6 +288,31 @@ const deviceTypeTree = ref<DeviceTypeTreeVO[]>([])
const users = ref<UserVO[]>([]) const users = ref<UserVO[]>([])
const criticalComponentOptions = ref<{ label: string; value: number }[]>([]) const criticalComponentOptions = ref<{ label: string; value: number }[]>([])
const beijianOptions = ref<{ label: string; value: number }[]>([]) const beijianOptions = ref<{ label: string; value: number }[]>([])
const PAGE_SIZE = 10
const buildPagedOptions = (options: { label: string; value: number }[]) => {
const result: { label: string; value: string; children: { label: string; value: number }[] }[] = []
for (let i = 0; i < options.length; i += PAGE_SIZE) {
const pageIndex = result.length + 1
result.push({
label: String(pageIndex),
value: `page-${pageIndex}`,
children: options.slice(i, i + PAGE_SIZE).map((item) => ({
label: item.label,
value: item.value
}))
})
}
return result
}
const cascaderProps = { multiple: true, emitPath: false, checkStrictly: false }
const criticalComponentCascaderValue = ref<(number | string)[]>([])
const beijianCascaderValue = ref<(number | string)[]>([])
const criticalComponentPagedOptions = computed(() => buildPagedOptions(criticalComponentOptions.value))
const beijianPagedOptions = computed(() => buildPagedOptions(beijianOptions.value))
const ensureOptionsLoaded = async () => { const ensureOptionsLoaded = async () => {
const [deviceTypeRes, userRes, criticalRes, beijianRes] = await Promise.all([ const [deviceTypeRes, userRes, criticalRes, beijianRes] = await Promise.all([
@ -318,6 +337,48 @@ const ensureOptionsLoaded = async () => {
}) })
} }
watch(
() => formData.value.componentIds,
(ids) => {
criticalComponentCascaderValue.value = Array.isArray(ids) ? [...ids] : []
},
{ immediate: true }
)
watch(
() => formData.value.beijianIds,
(ids) => {
beijianCascaderValue.value = Array.isArray(ids) ? [...ids] : []
},
{ immediate: true }
)
const handleCriticalComponentChange = (values: (number | string)[]) => {
const validIds = new Set<number>()
const validMap = new Set(criticalComponentOptions.value.map((item) => item.value))
for (const v of values) {
const num = Number(v)
if (!Number.isNaN(num) && validMap.has(num)) {
validIds.add(num)
}
}
formData.value.componentIds = Array.from(validIds)
criticalComponentCascaderValue.value = Array.from(validIds)
}
const handleBeijianChange = (values: (number | string)[]) => {
const validIds = new Set<number>()
const validMap = new Set(beijianOptions.value.map((item) => item.value))
for (const v of values) {
const num = Number(v)
if (!Number.isNaN(num) && validMap.has(num)) {
validIds.add(num)
}
}
formData.value.beijianIds = Array.from(validIds)
beijianCascaderValue.value = Array.from(validIds)
}
/** 打开弹窗 */ /** 打开弹窗 */
const open = async (type: string, id?: number, defaultDeviceTypeId?: number) => { const open = async (type: string, id?: number, defaultDeviceTypeId?: number) => {
dialogVisible.value = true dialogVisible.value = true

@ -10,8 +10,8 @@
<el-form-item prop="feedingRecordCode"> <el-form-item prop="feedingRecordCode">
<template #label> <template #label>
<span> <span>
单号 {{ t('ProductionPlan.FeedingRecord.dialogCodeLabel') }}
<el-tooltip content="单号" placement="top"> <el-tooltip :content="t('ProductionPlan.FeedingRecord.dialogCodeTooltip')" placement="top">
<Icon icon="ep:question-filled" /> <Icon icon="ep:question-filled" />
</el-tooltip> </el-tooltip>
</span> </span>
@ -21,7 +21,7 @@
<el-input <el-input
:disabled="formData.isCode == true || formType === 'update'" :disabled="formData.isCode == true || formType === 'update'"
v-model="formData.feedingRecordCode" v-model="formData.feedingRecordCode"
placeholder="编码保存后自动生成" :placeholder="t('ProductionPlan.FeedingRecord.dialogCodePlaceholder')"
/> />
</el-col> </el-col>
<el-col :xs="24" :sm="6" :md="4" :lg="3" :xl="2"> <el-col :xs="24" :sm="6" :md="4" :lg="3" :xl="2">
@ -48,8 +48,8 @@
<el-form-item prop="feedingType"> <el-form-item prop="feedingType">
<template #label> <template #label>
<span> <span>
投料类型 {{ t('ProductionPlan.FeedingRecord.dialogFeedingTypeLabel') }}
<el-tooltip content="来源:数据字典-生产投料类型" placement="top"> <el-tooltip :content="t('ProductionPlan.FeedingRecord.dialogFeedingTypeTooltip')" placement="top">
<Icon icon="ep:question-filled" /> <Icon icon="ep:question-filled" />
</el-tooltip> </el-tooltip>
</span> </span>
@ -64,13 +64,13 @@
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="生产计划" prop="planId" v-if = "formData.feedingType == 'org'"> <el-form-item :label="t('ProductionPlan.FeedingRecord.dialogPlanLabel')" prop="planId" v-if = "formData.feedingType == 'org'">
<el-select <el-select
v-model="formData.planId" v-model="formData.planId"
@change="handleQuery(formData.planId)" @change="handleQuery(formData.planId)"
clearable clearable
filterable filterable
placeholder="请选择生产计划" :placeholder="t('ProductionPlan.FeedingRecord.dialogPlanPlaceholder')"
> >
<el-option <el-option
v-for="item in planList" v-for="item in planList"
@ -80,22 +80,22 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="制浆线:" prop="feedingPipeline" v-if = "formData.feedingType != 'org'"> <el-form-item :label="t('ProductionPlan.FeedingRecord.dialogPipelineLabel') + ':'" prop="feedingPipeline" v-if = "formData.feedingType != 'org'">
<el-tree-select <el-tree-select
v-model="formData.feedingPipeline" v-model="formData.feedingPipeline"
:data="organizationTree" :data="organizationTree"
:props="defaultProps" :props="defaultProps"
check-strictly check-strictly
default-expand-all default-expand-all
placeholder="请选择制浆线" :placeholder="t('ProductionPlan.FeedingRecord.dialogPipelinePlaceholder')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="产品" prop="productId" v-if="formData.feedingType !='org'"> <el-form-item :label="t('ProductionPlan.FeedingRecord.dialogProductLabel')" prop="productId" v-if="formData.feedingType !='org'">
<el-select <el-select
v-model="formData.productId" v-model="formData.productId"
clearable clearable
filterable filterable
placeholder="请选择产品" :placeholder="t('ProductionPlan.FeedingRecord.dialogProductPlaceholder')"
class="!w-1/1" class="!w-1/1"
> >
<el-option <el-option
@ -106,27 +106,27 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="重量(kg):" prop="weight" v-if="formData.feedingType !='org'"> <el-form-item :label="t('ProductionPlan.FeedingRecord.dialogWeightLabel') + ':'" prop="weight" v-if="formData.feedingType !='org'">
<el-input-number v-model="formData.weight" :min="0" :precision="2" class="!w-1/1" placeholder="请输入重量" <el-input-number v-model="formData.weight" :min="0" :precision="2" class="!w-1/1" :placeholder="t('ProductionPlan.FeedingRecord.dialogWeightPlaceholder')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="投料时间:" prop="feedingTime"> <el-form-item :label="t('ProductionPlan.FeedingRecord.dialogFeedingTimeLabel') + ':'" prop="feedingTime">
<el-date-picker <el-date-picker
v-model="formData.feedingTime" v-model="formData.feedingTime"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择投料时间" :placeholder="t('ProductionPlan.FeedingRecord.dialogFeedingTimePlaceholder')"
class="!w-full" class="!w-full"
/> />
</el-form-item> </el-form-item>
<el-form-item label="备注:" prop="remark"> <el-form-item :label="t('ProductionPlan.FeedingRecord.dialogRemarkLabel') + ':'" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" /> <el-input v-model="formData.remark" :placeholder="t('ProductionPlan.FeedingRecord.dialogRemarkPlaceholder')" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- 子表的表单 --> <!-- 子表的表单 -->
<el-tabs v-model="subTabsName" v-if="formData.feedingType=='org'"> <el-tabs v-model="subTabsName" v-if="formData.feedingType=='org'">
<el-tab-pane label="投料明细" name="feedingRecordDetail"> <el-tab-pane :label="t('ProductionPlan.FeedingRecord.detailTabFeedingDetailLabel')" name="feedingRecordDetail">
<!-- <FeedingRecordDetailForm ref="feedingRecordDetailFormRef" :record-id="formData.id" /> --> <!-- <FeedingRecordDetailForm ref="feedingRecordDetailFormRef" :record-id="formData.id" /> -->
<el-form <el-form
ref="recordFormRef" ref="recordFormRef"
@ -137,10 +137,10 @@
:inline-message="true" :inline-message="true"
> >
<el-table :data="recordData" class="-mt-10px"> <el-table :data="recordData" class="-mt-10px">
<el-table-column label="序号" type="index" width="100" /> <el-table-column :label="t('ProductionPlan.FeedingRecord.detailTableIndexColumn')" type="index" width="100" />
<el-table-column label="原料" prop="productName" width="100" /> <el-table-column :label="t('ProductionPlan.FeedingRecord.detailTableItemColumn')" prop="productName" width="100" />
<el-table-column label="单位" prop="unitName" width="100" /> <el-table-column :label="t('ProductionPlan.FeedingRecord.detailTableUnitColumn')" prop="unitName" width="100" />
<el-table-column label="数量" min-width="150"> <el-table-column :label="t('ProductionPlan.FeedingRecord.detailTableWeightColumn')" min-width="150">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.weight`" :rules="recordFormRules.weight"> <el-form-item :prop="`${$index}.weight`" :rules="recordFormRules.weight">
<el-input-number v-model="row.weight" :min="0" :precision="2" class="!w-1/1" placeholder="" <el-input-number v-model="row.weight" :min="0" :precision="2" class="!w-1/1" placeholder=""
@ -160,8 +160,8 @@
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('ProductionPlan.FeedingRecord.dialogSubmitButtonText') }}</el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.FeedingRecord.dialogCancelButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -203,12 +203,12 @@ const formData = ref({
isCode: undefined isCode: undefined
}) })
const formRules = reactive({ const formRules = reactive({
feedingType: [{ required: true, message: '投料类型不能为空', trigger: 'blur' }], feedingType: [{ required: true, message: t('ProductionPlan.FeedingRecord.validatorFeedingTypeRequired'), trigger: 'blur' }],
feedingPipeline: [{ required: true, message: '制浆线不能为空', trigger: 'blur' }], feedingPipeline: [{ required: true, message: t('ProductionPlan.FeedingRecord.validatorPipelineRequired'), trigger: 'blur' }],
planId: [{ required: true, message: '生产计划不能为空', trigger: 'change' }] planId: [{ required: true, message: t('ProductionPlan.FeedingRecord.validatorPlanRequired'), trigger: 'change' }]
}) })
const recordFormRules = reactive({ const recordFormRules = reactive({
weight: [{ required: true, message: '数量不能为空', trigger: 'blur' }] weight: [{ required: true, message: t('ProductionPlan.FeedingRecord.validatorDetailWeightRequired'), trigger: 'blur' }]
}) })
const formRef = ref() // Ref const formRef = ref() // Ref

@ -6,68 +6,68 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" label-width="auto"
> >
<el-form-item label="单号" prop="feedingRecordCode"> <el-form-item :label="t('ProductionPlan.FeedingRecord.searchCodeLabel')" prop="feedingRecordCode">
<el-input <el-input
v-model="queryParams.feedingRecordCode" v-model="queryParams.feedingRecordCode"
placeholder="请输入单号" :placeholder="t('ProductionPlan.FeedingRecord.searchCodePlaceholder')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="制浆线" prop="feedingPipeline"> <el-form-item :label="t('ProductionPlan.FeedingRecord.searchPipelineLabel')" prop="feedingPipeline">
<el-tree-select <el-tree-select
v-model="queryParams.feedingPipeline" v-model="queryParams.feedingPipeline"
:data="organizationTree" :data="organizationTree"
:props="defaultProps" :props="defaultProps"
check-strictly check-strictly
default-expand-all default-expand-all
placeholder="请选择制浆线" :placeholder="t('ProductionPlan.FeedingRecord.searchPipelinePlaceholder')"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="投料时间" prop="feedingTime"> <el-form-item :label="t('ProductionPlan.FeedingRecord.searchFeedingTimeLabel')" prop="feedingTime">
<el-date-picker <el-date-picker
v-model="queryParams.feedingTime" v-model="queryParams.feedingTime"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" type="daterange"
@change="handleQuery" @change="handleQuery"
start-placeholder="开始日期" :start-placeholder="t('ProductionPlan.FeedingRecord.searchFeedingTimeStartPlaceholder')"
end-placeholder="结束日期" :end-placeholder="t('ProductionPlan.FeedingRecord.searchFeedingTimeEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="记录人" prop="userId"> <el-form-item :label="t('ProductionPlan.FeedingRecord.searchUserLabel')" prop="userId">
<el-input <el-input
v-model="queryParams.userId" v-model="queryParams.userId"
placeholder="请输入记录人" :placeholder="t('ProductionPlan.FeedingRecord.searchUserPlaceholder')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item :label="t('ProductionPlan.FeedingRecord.searchRemarkLabel')" prop="remark">
<el-input <el-input
v-model="queryParams.remark" v-model="queryParams.remark"
placeholder="请输入备注" :placeholder="t('ProductionPlan.FeedingRecord.searchRemarkPlaceholder')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> {{ t('ProductionPlan.FeedingRecord.buttonSearchText') }}</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> {{ t('ProductionPlan.FeedingRecord.buttonResetText') }}</el-button>
<el-button <el-button
type="primary" type="primary"
plain plain
@click="openForm('create')" @click="openForm('create')"
v-hasPermi="['mes:feeding-record:create']" v-hasPermi="['mes:feeding-record:create']"
> >
<Icon icon="ep:plus" class="mr-5px" /> 新增 <Icon icon="ep:plus" class="mr-5px" /> {{ t('ProductionPlan.FeedingRecord.buttonCreateText') }}
</el-button> </el-button>
<el-button <el-button
type="success" type="success"
@ -76,7 +76,7 @@
:loading="exportLoading" :loading="exportLoading"
v-hasPermi="['mes:feeding-record:export']" v-hasPermi="['mes:feeding-record:export']"
> >
<Icon icon="ep:download" class="mr-5px" /> 导出 <Icon icon="ep:download" class="mr-5px" /> {{ t('ProductionPlan.FeedingRecord.buttonExportText') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -85,46 +85,46 @@
<!-- 列表 --> <!-- 列表 -->
<ContentWrap> <ContentWrap>
<el-tabs v-model="activeName" @tab-click="handleTabClick"> <el-tabs v-model="activeName" @tab-click="handleTabClick">
<el-tab-pane label="所有" name="" /> <el-tab-pane :label="t('ProductionPlan.FeedingRecord.tabAllLabel')" name="" />
<el-tab-pane label="领料" name="org" /> <el-tab-pane :label="t('ProductionPlan.FeedingRecord.tabOrgLabel')" name="org" />
<el-tab-pane label="干废品" name="dry" /> <el-tab-pane :label="t('ProductionPlan.FeedingRecord.tabDryLabel')" name="dry" />
<el-tab-pane label="湿废品" name="wet" /> <el-tab-pane :label="t('ProductionPlan.FeedingRecord.tabWetLabel')" name="wet" />
</el-tabs> </el-tabs>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<!-- 子表的列表 --> <!-- 子表的列表 -->
<el-table-column type="expand"> <el-table-column type="expand">
<template #default="scope"> <template #default="scope">
<el-tabs model-value="feedingRecordDetail"> <el-tabs model-value="feedingRecordDetail">
<el-tab-pane label="投料明细" name="feedingRecordDetail"> <el-tab-pane :label="t('ProductionPlan.FeedingRecord.detailTabFeedingDetailLabel')" name="feedingRecordDetail">
<FeedingRecordDetailList :record-id="scope.row.id" /> <FeedingRecordDetailList :record-id="scope.row.id" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="单号" align="center" prop="feedingRecordCode" width="150px"/> <el-table-column :label="t('ProductionPlan.FeedingRecord.tableCodeColumn')" align="center" prop="feedingRecordCode" width="150px"/>
<el-table-column label="制浆线" align="center" prop="feedingPipelineName" sortable/> <el-table-column :label="t('ProductionPlan.FeedingRecord.tablePipelineColumn')" align="center" prop="feedingPipelineName" sortable/>
<el-table-column label="投料类型" align="center" prop="feedingType" sortable> <el-table-column :label="t('ProductionPlan.FeedingRecord.tableFeedingTypeColumn')" align="center" prop="feedingType" sortable>
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.MES_FEEDING_TYPE" :value="scope.row.feedingType" /> <dict-tag :type="DICT_TYPE.MES_FEEDING_TYPE" :value="scope.row.feedingType" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="数量" align="center" prop="weight" /> <el-table-column :label="t('ProductionPlan.FeedingRecord.tableWeightColumn')" align="center" prop="weight" />
<el-table-column label="记录人" align="center" prop="userName" /> <el-table-column :label="t('ProductionPlan.FeedingRecord.tableUserColumn')" align="center" prop="userName" />
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column :label="t('ProductionPlan.FeedingRecord.tableRemarkColumn')" align="center" prop="remark" />
<!-- <el-table-column label="状态" align="center" prop="recordStatus"> <!-- <el-table-column label="状态" align="center" prop="recordStatus">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.MES_FEEDING_RECORD_STATUS" :value="scope.row.recordStatus" /> <dict-tag :type="DICT_TYPE.MES_FEEDING_RECORD_STATUS" :value="scope.row.recordStatus" />
</template> </template>
</el-table-column> --> </el-table-column> -->
<el-table-column <el-table-column
label="投料时间" :label="t('ProductionPlan.FeedingRecord.tableFeedingTimeColumn')"
align="center" align="center"
prop="feedingTime" prop="feedingTime"
:formatter="dateFormatter" :formatter="dateFormatter"
width="180px" width="180px"
/> />
<el-table-column label="操作" align="center" width="200px"> <el-table-column :label="t('ProductionPlan.FeedingRecord.tableOperateColumn')" align="center" width="200px">
<template #default="scope"> <template #default="scope">
<!-- <el-button <!-- <el-button
link link
@ -142,7 +142,7 @@
v-hasPermi="['mes:feeding-record:delete']" v-hasPermi="['mes:feeding-record:delete']"
v-if="scope.row.recordStatus=='1'" v-if="scope.row.recordStatus=='1'"
> >
删除 {{ t('ProductionPlan.FeedingRecord.actionDeleteLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
@ -151,7 +151,7 @@
v-hasPermi="['mes:feeding-record:update']" v-hasPermi="['mes:feeding-record:update']"
v-if="scope.row.recordStatus=='1'" v-if="scope.row.recordStatus=='1'"
> >
投料 {{ t('ProductionPlan.FeedingRecord.actionFeedingLabel') }}
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -257,7 +257,7 @@ const handleExport = async () => {
// //
exportLoading.value = true exportLoading.value = true
const data = await FeedingRecordApi.exportFeedingRecord(queryParams) const data = await FeedingRecordApi.exportFeedingRecord(queryParams)
download.excel(data, '投料记录.xls') download.excel(data, t('ProductionPlan.FeedingRecord.exportFilename'))
} catch { } catch {
} finally { } finally {
exportLoading.value = false exportLoading.value = false
@ -274,9 +274,12 @@ onMounted(() => {
const handleUpdateStatus = async (id: number, status:string) => { const handleUpdateStatus = async (id: number, status:string) => {
try { try {
// //
await message.confirm("确认提交投料记录?", "一旦提交成功无法撤回!") await message.confirm(
t('ProductionPlan.FeedingRecord.updateStatusConfirmMessage'),
t('ProductionPlan.FeedingRecord.updateStatusConfirmTitle')
)
await FeedingRecordApi.updateFeedingRecordStatus(id,status) await FeedingRecordApi.updateFeedingRecordStatus(id,status)
message.success("提交成功!") message.success(t('ProductionPlan.FeedingRecord.updateStatusSuccessMessage'))
// //
await getList() await getList()
} catch {} } catch {}

@ -7,13 +7,13 @@
label-width="100px" label-width="100px"
v-loading="formLoading" v-loading="formLoading"
> >
<el-form-item label="任务单" prop="taskId"> <el-form-item :label="t('ProductionPlan.Plan.dialogTaskLabel')" prop="taskId">
<el-select <el-select
disabled disabled
v-model="formData.taskId" v-model="formData.taskId"
clearable clearable
filterable filterable
placeholder="请选择" :placeholder="t('ProductionPlan.Plan.dialogTaskPlaceholder')"
@change="handleTaskChange" @change="handleTaskChange"
> >
<el-option <el-option
@ -24,13 +24,13 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="明细项" prop="taskId"> <el-form-item :label="t('ProductionPlan.Plan.dialogTaskDetailLabel')" prop="taskId">
<el-select <el-select
disabled disabled
v-model="formData.taskDetailId" v-model="formData.taskDetailId"
clearable clearable
filterable filterable
placeholder="请选择" :placeholder="t('ProductionPlan.Plan.dialogTaskDetailPlaceholder')"
@change="handleTaskDetailChange" @change="handleTaskDetailChange"
> >
<el-option <el-option
@ -44,8 +44,8 @@
<el-form-item prop="code"> <el-form-item prop="code">
<template #label> <template #label>
<span> <span>
计划编码 {{ t('ProductionPlan.Plan.dialogCodeLabel') }}
<el-tooltip content="生产计划编码" placement="top"> <el-tooltip :content="t('ProductionPlan.Plan.dialogCodeTooltip')" placement="top">
<Icon icon="ep:question-filled" /> <Icon icon="ep:question-filled" />
</el-tooltip> </el-tooltip>
</span> </span>
@ -55,7 +55,7 @@
<el-input <el-input
:disabled="formData.isCode == true || formType === 'update'" :disabled="formData.isCode == true || formType === 'update'"
v-model="formData.code" v-model="formData.code"
placeholder="编码保存后自动生成" :placeholder="t('ProductionPlan.Plan.dialogCodePlaceholder')"
/> />
</el-col> </el-col>
<el-col :xs="24" :sm="6" :md="4" :lg="3" :xl="2"> <el-col :xs="24" :sm="6" :md="4" :lg="3" :xl="2">
@ -68,22 +68,22 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="生产线" prop="feedingPipeline"> <el-form-item :label="t('ProductionPlan.Plan.dialogFeedingPipelineLabel')" prop="feedingPipeline">
<el-tree-select <el-tree-select
v-model="formData.feedingPipeline" v-model="formData.feedingPipeline"
:data="organizationTree" :data="organizationTree"
:props="defaultProps" :props="defaultProps"
check-strictly check-strictly
default-expand-all default-expand-all
placeholder="请选择生产线" :placeholder="t('ProductionPlan.Plan.dialogFeedingPipelinePlaceholder')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="领料人" prop="workerId"> <el-form-item :label="t('ProductionPlan.Plan.dialogWorkerLabel')" prop="workerId">
<el-select <el-select
v-model="formData.workerId" v-model="formData.workerId"
clearable clearable
filterable filterable
placeholder="请选择领料人" :placeholder="t('ProductionPlan.Plan.dialogWorkerPlaceholder')"
> >
<el-option <el-option
v-for="item in userList" v-for="item in userList"
@ -110,10 +110,10 @@
<!-- />--> <!-- />-->
<!-- </el-select>--> <!-- </el-select>-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
<el-form-item label="数量" prop="planNumber"> <el-form-item :label="t('ProductionPlan.Plan.dialogPlanNumberLabel')" prop="planNumber">
<el-input v-model="formData.planNumber" /> <el-input v-model="formData.planNumber" />
</el-form-item> </el-form-item>
<el-form-item label="是否试生产" prop="isPreProduction"> <el-form-item :label="t('ProductionPlan.Plan.dialogPreProductionLabel')" prop="isPreProduction">
<el-radio-group v-model="formData.isPreProduction"> <el-radio-group v-model="formData.isPreProduction">
<el-radio <el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.MES_PRE_PRODUCTION)" v-for="dict in getIntDictOptions(DICT_TYPE.MES_PRE_PRODUCTION)"
@ -127,21 +127,21 @@
<!-- <el-form-item label="热压数量" prop="reyaNumber"> <!-- <el-form-item label="热压数量" prop="reyaNumber">
<el-input v-model="formData.reyaNumber" /> <el-input v-model="formData.reyaNumber" />
</el-form-item> --> </el-form-item> -->
<el-form-item label="计划开始" prop="planStartTime"> <el-form-item :label="t('ProductionPlan.Plan.dialogPlanStartLabel')" prop="planStartTime">
<el-date-picker <el-date-picker
v-model="formData.planStartTime" v-model="formData.planStartTime"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择计划开始时间" :placeholder="t('ProductionPlan.Plan.dialogPlanStartPlaceholder')"
class="!w-full" class="!w-full"
/> />
</el-form-item> </el-form-item>
<el-form-item label="计划结束" prop="planEndTime"> <el-form-item :label="t('ProductionPlan.Plan.dialogPlanEndLabel')" prop="planEndTime">
<el-date-picker <el-date-picker
v-model="formData.planEndTime" v-model="formData.planEndTime"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择计划结束时间" :placeholder="t('ProductionPlan.Plan.dialogPlanEndPlaceholder')"
class="!w-full" class="!w-full"
/> />
</el-form-item> </el-form-item>
@ -156,13 +156,13 @@
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> --> </el-form-item> -->
<el-form-item label="备注" prop="remark"> <el-form-item :label="t('ProductionPlan.Plan.dialogRemarkLabel')" prop="remark">
<el-input type="textarea" v-model="formData.remark" placeholder="请输入备注" /> <el-input type="textarea" v-model="formData.remark" :placeholder="t('ProductionPlan.Plan.dialogRemarkPlaceholder')" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('ProductionPlan.Plan.dialogSubmitButtonText') }}</el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.Plan.dialogCancelButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -219,15 +219,15 @@ const formData = ref({
isCode: undefined isCode: undefined
}) })
const formRules = reactive({ const formRules = reactive({
taskDetailId: [{ required: true, message: '明细项不能为空', trigger: 'blur' }], taskDetailId: [{ required: true, message: t('ProductionPlan.Plan.validatorTaskDetailRequired'), trigger: 'blur' }],
taskId: [{ required: true, message: '任务单不能为空', trigger: 'blur' }], taskId: [{ required: true, message: t('ProductionPlan.Plan.validatorTaskRequired'), trigger: 'blur' }],
planNumber: [{ required: true, message: '数量不能为空', trigger: 'blur' }], planNumber: [{ required: true, message: t('ProductionPlan.Plan.validatorPlanNumberRequired'), trigger: 'blur' }],
// reyaNumber: [{ required: true, message: '', trigger: 'blur' }], // reyaNumber: [{ required: true, message: t('ProductionPlan.Plan.validatorReyaNumberRequired'), trigger: 'blur' }],
planStartTime: [{ required: true, message: '计划开始时间不能为空', trigger: 'blur' }], planStartTime: [{ required: true, message: t('ProductionPlan.Plan.validatorPlanStartRequired'), trigger: 'blur' }],
planEndTime: [{ required: true, message: '计划结束时间不能为空', trigger: 'blur' }], planEndTime: [{ required: true, message: t('ProductionPlan.Plan.validatorPlanEndRequired'), trigger: 'blur' }],
feedingPipeline: [{ required: true, message: '生产线不能为空', trigger: 'blur' }], feedingPipeline: [{ required: true, message: t('ProductionPlan.Plan.validatorFeedingPipelineRequired'), trigger: 'blur' }],
workerId: [{ required: true, message: '下料工人不能为空', trigger: 'blur' }], workerId: [{ required: true, message: t('ProductionPlan.Plan.validatorWorkerRequired'), trigger: 'blur' }],
isPreProduction: [{ required: true, message: '试生产不能为空', trigger: 'blur' }], isPreProduction: [{ required: true, message: t('ProductionPlan.Plan.validatorPreProductionRequired'), trigger: 'blur' }],
}) })
const formRef = ref() // Ref const formRef = ref() // Ref

@ -7,23 +7,23 @@
label-width="100px" label-width="100px"
v-loading="formLoading" v-loading="formLoading"
> >
<el-form-item v-show="false" label="计划" prop="planId"> <el-form-item v-show="false" :label="t('ProductionPlan.Plan.baogongDialogPlanLabel')" prop="planId">
<el-input v-model="formData.planId" placeholder="请输入计划ID" /> <el-input v-model="formData.planId" :placeholder="t('ProductionPlan.Plan.baogongDialogPlanPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item label="合格数量" prop="num"> <el-form-item :label="t('ProductionPlan.Plan.baogongDialogQualifiedNumberLabel')" prop="num">
<el-input-number v-model="formData.num" placeholder="请输入数量" class="!w-240px"/> <el-input-number v-model="formData.num" :placeholder="t('ProductionPlan.Plan.baogongDialogQualifiedNumberPlaceholder')" class="!w-240px"/>
</el-form-item> </el-form-item>
<el-form-item label="不合格数量" prop="noPassNum"> <el-form-item :label="t('ProductionPlan.Plan.baogongDialogUnqualifiedNumberLabel')" prop="noPassNum">
<el-input-number v-model="formData.noPassNum" placeholder="请输入数量" class="!w-240px"/> <el-input-number v-model="formData.noPassNum" :placeholder="t('ProductionPlan.Plan.baogongDialogUnqualifiedNumberPlaceholder')" class="!w-240px"/>
</el-form-item> </el-form-item>
<el-form-item label="原因" prop="remark"> <el-form-item :label="t('ProductionPlan.Plan.baogongDialogReasonLabel')" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入原因"/> <el-input v-model="formData.remark" :placeholder="t('ProductionPlan.Plan.baogongDialogReasonPlaceholder')"/>
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('ProductionPlan.Plan.baogongDialogSubmitButtonText') }}</el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.Plan.baogongDialogCancelButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -50,15 +50,15 @@ const formData = ref({
remark: undefined, remark: undefined,
}) })
const formRules = reactive({ const formRules = reactive({
num: [{ required: true, message: '数量不能为空', trigger: 'blur' }], num: [{ required: true, message: t('ProductionPlan.Plan.validatorBaogongQualifiedRequired'), trigger: 'blur' }],
noPassNum: [{ required: true, message: '数量不能为空', trigger: 'blur' }], noPassNum: [{ required: true, message: t('ProductionPlan.Plan.validatorBaogongUnqualifiedRequired'), trigger: 'blur' }],
}) })
const formRef = ref() // Ref const formRef = ref() // Ref
/** 打开弹窗 */ /** 打开弹窗 */
const open = async (planCode: string, planId: number) => { const open = async (planCode: string, planId: number) => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = "计划报工:"+planCode dialogTitle.value = t('ProductionPlan.Plan.baogongDialogTitle', { code: planCode })
resetForm() resetForm()
formLoading.value = true formLoading.value = true
try { try {
@ -81,13 +81,8 @@ const submitForm = async () => {
try { try {
const data = formData.value as unknown as BaogongRecordVO const data = formData.value as unknown as BaogongRecordVO
await BaogongRecordApi.createBaogongRecord(data) await BaogongRecordApi.createBaogongRecord(data)
message.success(t('common.createSuccess')) message.success(t('ProductionPlan.Plan.baogongSuccessMessage'))
dialogVisible.value = false dialogVisible.value = false
//
emit('success')
message.success("派工成功!")
dialogVisible.value = false
//
emit('success') emit('success')
} finally { } finally {
formLoading.value = false formLoading.value = false

@ -7,25 +7,25 @@
label-width="100px" label-width="100px"
v-loading="formLoading" v-loading="formLoading"
> >
<el-form-item v-show="false" label="计划" prop="planId"> <el-form-item v-show="false" :label="t('ProductionPlan.Plan.dispatchDialogPlanLabel')" prop="planId">
<el-input v-model="formData.planId" placeholder="请输入计划ID" /> <el-input v-model="formData.planId" :placeholder="t('ProductionPlan.Plan.dispatchDialogPlanPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item label="制浆线" prop="feedingPipeline"> <el-form-item :label="t('ProductionPlan.Plan.dispatchDialogFeedingPipelineLabel')" prop="feedingPipeline">
<el-tree-select <el-tree-select
v-model="formData.feedingPipeline" v-model="formData.feedingPipeline"
:data="organizationTree" :data="organizationTree"
:props="defaultProps" :props="defaultProps"
check-strictly check-strictly
default-expand-all default-expand-all
placeholder="请选择制浆线" :placeholder="t('ProductionPlan.Plan.dispatchDialogFeedingPipelinePlaceholder')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="领料人" prop="workerId"> <el-form-item :label="t('ProductionPlan.Plan.dispatchDialogWorkerLabel')" prop="workerId">
<el-select <el-select
v-model="formData.workerId" v-model="formData.workerId"
clearable clearable
filterable filterable
placeholder="请选择工人" :placeholder="t('ProductionPlan.Plan.dispatchDialogWorkerPlaceholder')"
> >
<el-option <el-option
v-for="item in userList" v-for="item in userList"
@ -35,22 +35,22 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="计划下料" prop="requisitionDate"> <el-form-item :label="t('ProductionPlan.Plan.dispatchDialogRequisitionDateLabel')" prop="requisitionDate">
<el-date-picker <el-date-picker
v-model="formData.requisitionDate" v-model="formData.requisitionDate"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择下料时间" :placeholder="t('ProductionPlan.Plan.dispatchDialogRequisitionDatePlaceholder')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item :label="t('ProductionPlan.Plan.dispatchDialogRemarkLabel')" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" /> <el-input v-model="formData.remark" :placeholder="t('ProductionPlan.Plan.dispatchDialogRemarkPlaceholder')" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('ProductionPlan.Plan.dispatchDialogSubmitButtonText') }}</el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.Plan.dispatchDialogCancelButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -87,16 +87,16 @@ const formData = ref({
isPreProduction: undefined isPreProduction: undefined
}) })
const formRules = reactive({ const formRules = reactive({
planId: [{ required: true, message: '计划不能为空', trigger: 'blur' }], planId: [{ required: true, message: t('ProductionPlan.Plan.validatorDispatchPlanRequired'), trigger: 'blur' }],
feedingPipeline: [{ required: true, message: '制浆线不能为空', trigger: 'blur' }], feedingPipeline: [{ required: true, message: t('ProductionPlan.Plan.validatorDispatchFeedingPipelineRequired'), trigger: 'blur' }],
workerId: [{ required: true, message: '下料工人不能为空', trigger: 'blur' }], workerId: [{ required: true, message: t('ProductionPlan.Plan.validatorDispatchWorkerRequired'), trigger: 'blur' }],
}) })
const formRef = ref() // Ref const formRef = ref() // Ref
/** 打开弹窗 */ /** 打开弹窗 */
const open = async (planCode: string, planId: number) => { const open = async (planCode: string, planId: number) => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = "计划派工:"+planCode dialogTitle.value = t('ProductionPlan.Plan.dispatchDialogTitle', { code: planCode })
resetForm() resetForm()
formLoading.value = true formLoading.value = true
try { try {
@ -122,7 +122,7 @@ const submitForm = async () => {
const data = formData.value as unknown as ItemRequisitionVO const data = formData.value as unknown as ItemRequisitionVO
await PlanApi.arrangePlan(data) await PlanApi.arrangePlan(data)
message.success("派工成功!") message.success(t('ProductionPlan.Plan.dispatchSuccessMessage'))
dialogVisible.value = false dialogVisible.value = false
// //
emit('success') emit('success')

@ -7,8 +7,8 @@
label-width="100px" label-width="100px"
v-loading="formLoading" v-loading="formLoading"
> >
<el-form-item label="任务单" prop="taskCode"> <el-form-item :label="t('ProductionPlan.Plan.detailDialogTaskLabel')" prop="taskCode">
<el-input disabled v-model="formData.taskCode" placeholder="请输入任务单" /> <el-input disabled v-model="formData.taskCode" :placeholder="t('ProductionPlan.Plan.detailDialogTaskPlaceholder')" />
</el-form-item> </el-form-item>
<!-- <el-form-item label="明细项" prop="taskId"> <!-- <el-form-item label="明细项" prop="taskId">
<el-select <el-select
@ -27,17 +27,17 @@
/> />
</el-select> </el-select>
</el-form-item> --> </el-form-item> -->
<el-form-item label="明细项" prop="productName"> <el-form-item :label="t('ProductionPlan.Plan.detailDialogProductLabel')" prop="productName">
<el-input disabled v-model="formData.productName" placeholder="请输入产品" /> <el-input disabled v-model="formData.productName" :placeholder="t('ProductionPlan.Plan.detailDialogProductPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item label="计划编码" prop="code"> <el-form-item :label="t('ProductionPlan.Plan.detailDialogCodeLabel')" prop="code">
<el-input disabled v-model="formData.code" placeholder="请输入计划编码" /> <el-input disabled v-model="formData.code" :placeholder="t('ProductionPlan.Plan.detailDialogCodePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item label="生产线" prop="feedingPipelineName"> <el-form-item :label="t('ProductionPlan.Plan.detailDialogFeedingPipelineLabel')" prop="feedingPipelineName">
<el-input disabled v-model="formData.feedingPipelineName" placeholder="请输入生产线名称" /> <el-input disabled v-model="formData.feedingPipelineName" :placeholder="t('ProductionPlan.Plan.detailDialogFeedingPipelinePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item label="领料人" prop="worker"> <el-form-item :label="t('ProductionPlan.Plan.detailDialogWorkerLabel')" prop="worker">
<el-input disabled v-model="formData.worker" placeholder="请输入领料人" /> <el-input disabled v-model="formData.worker" :placeholder="t('ProductionPlan.Plan.detailDialogWorkerPlaceholder')" />
</el-form-item> </el-form-item>
<!-- <el-form-item label="产品" prop="productId">--> <!-- <el-form-item label="产品" prop="productId">-->
<!-- <el-select--> <!-- <el-select-->
@ -56,10 +56,10 @@
<!-- />--> <!-- />-->
<!-- </el-select>--> <!-- </el-select>-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
<el-form-item label="数量" prop="planNumber"> <el-form-item :label="t('ProductionPlan.Plan.detailDialogPlanNumberLabel')" prop="planNumber">
<el-input disabled v-model="formData.planNumber" /> <el-input disabled v-model="formData.planNumber" />
</el-form-item> </el-form-item>
<el-form-item label="是否试生产" prop="isPreProduction"> <el-form-item :label="t('ProductionPlan.Plan.detailDialogPreProductionLabel')" prop="isPreProduction">
<el-radio-group disabled v-model="formData.isPreProduction"> <el-radio-group disabled v-model="formData.isPreProduction">
<el-radio <el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.MES_PRE_PRODUCTION)" v-for="dict in getIntDictOptions(DICT_TYPE.MES_PRE_PRODUCTION)"
@ -73,22 +73,22 @@
<!-- <el-form-item label="热压数量" prop="reyaNumber"> <!-- <el-form-item label="热压数量" prop="reyaNumber">
<el-input v-model="formData.reyaNumber" /> <el-input v-model="formData.reyaNumber" />
</el-form-item> --> </el-form-item> -->
<el-form-item label="计划开始" prop="planStartTime"> <el-form-item :label="t('ProductionPlan.Plan.detailDialogPlanStartLabel')" prop="planStartTime">
<el-date-picker <el-date-picker
disabled disabled
v-model="formData.planStartTime" v-model="formData.planStartTime"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择计划开始时间" :placeholder="t('ProductionPlan.Plan.detailDialogPlanStartPlaceholder')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="计划结束" prop="planEndTime"> <el-form-item :label="t('ProductionPlan.Plan.detailDialogPlanEndLabel')" prop="planEndTime">
<el-date-picker <el-date-picker
disabled disabled
v-model="formData.planEndTime" v-model="formData.planEndTime"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择计划结束时间" :placeholder="t('ProductionPlan.Plan.detailDialogPlanEndPlaceholder')"
/> />
</el-form-item> </el-form-item>
<!-- <el-form-item label="班别" prop="groupType"> <!-- <el-form-item label="班别" prop="groupType">
@ -102,13 +102,13 @@
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> --> </el-form-item> -->
<el-form-item label="备注" prop="remark"> <el-form-item :label="t('ProductionPlan.Plan.detailDialogRemarkLabel')" prop="remark">
<el-input disabled type="textarea" v-model="formData.remark" placeholder="请输入备注" /> <el-input disabled type="textarea" v-model="formData.remark" :placeholder="t('ProductionPlan.Plan.detailDialogRemarkPlaceholder')" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<!-- <el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> --> <!-- <el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> -->
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.Plan.detailDialogCloseButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -167,7 +167,7 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */ /** 打开弹窗 */
const open = async (id?: number) => { const open = async (id?: number) => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = t('详情') dialogTitle.value = t('ProductionPlan.Plan.detailDialogTitle')
// formType.value = type // formType.value = type
editDisable.value = false editDisable.value = false
resetForm() resetForm()

@ -7,20 +7,20 @@
label-width="100px" label-width="100px"
v-loading="formLoading" v-loading="formLoading"
> >
<el-form-item label="生产线" prop="pipeline"> <el-form-item :label="t('ProductionPlan.Plan.typeDispatchDialogPipelineLabel')" prop="pipeline">
<el-tree-select <el-tree-select
v-model="formData.pipeline" v-model="formData.pipeline"
:data="organizationTree" :data="organizationTree"
:props="defaultProps" :props="defaultProps"
check-strictly check-strictly
default-expand-all default-expand-all
placeholder="请选择生产线" :placeholder="t('ProductionPlan.Plan.typeDispatchDialogPipelinePlaceholder')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="派工数量" prop="paigongNum"> <el-form-item :label="t('ProductionPlan.Plan.typeDispatchDialogPaigongNumLabel')" prop="paigongNum">
<el-input v-model="formData.paigongNum" placeholder="请输入数量" /> <el-input v-model="formData.paigongNum" :placeholder="t('ProductionPlan.Plan.typeDispatchDialogPaigongNumPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item label="是否试生产" prop="isPreProduction"> <el-form-item :label="t('ProductionPlan.Plan.typeDispatchDialogPreProductionLabel')" prop="isPreProduction">
<el-radio-group v-model="formData.isPreProduction"> <el-radio-group v-model="formData.isPreProduction">
<el-radio <el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.MES_PRE_PRODUCTION)" v-for="dict in getIntDictOptions(DICT_TYPE.MES_PRE_PRODUCTION)"
@ -34,8 +34,8 @@
</el-form> </el-form>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('ProductionPlan.Plan.typeDispatchDialogSubmitButtonText') }}</el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.Plan.typeDispatchDialogCancelButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -73,16 +73,16 @@ const formData = ref({
isPreProduction: undefined isPreProduction: undefined
}) })
const formRules = reactive({ const formRules = reactive({
pipeline: [{ required: true, message: '生产线不能为空', trigger: 'blur' }], pipeline: [{ required: true, message: t('ProductionPlan.Plan.validatorTypeDispatchPipelineRequired'), trigger: 'blur' }],
isPreProduction: [{ required: true, message: '试生产不能为空', trigger: 'blur' }], isPreProduction: [{ required: true, message: t('ProductionPlan.Plan.validatorTypeDispatchPreProductionRequired'), trigger: 'blur' }],
paigongNum: [{ required: true, message: '派工数量不能为空', trigger: 'blur' }], paigongNum: [{ required: true, message: t('ProductionPlan.Plan.validatorTypeDispatchPaigongNumRequired'), trigger: 'blur' }],
}) })
const formRef = ref() // Ref const formRef = ref() // Ref
/** 打开弹窗 */ /** 打开弹窗 */
const open = async (planCode: string, planId: number) => { const open = async (planCode: string, planId: number) => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = "计划派工:"+planCode dialogTitle.value = t('ProductionPlan.Plan.dispatchDialogTitle', { code: planCode })
resetForm() resetForm()
formLoading.value = true formLoading.value = true
try { try {
@ -108,7 +108,7 @@ const submitForm = async () => {
const data = formData.value as unknown as ItemRequisitionVO const data = formData.value as unknown as ItemRequisitionVO
await PlanApi.arrangePlanNum(data) await PlanApi.arrangePlanNum(data)
message.success("派工成功!") message.success(t('ProductionPlan.Plan.dispatchSuccessMessage'))
dialogVisible.value = false dialogVisible.value = false
// //
emit('success') emit('success')

@ -6,15 +6,15 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" label-width="auto"
> >
<el-form-item label="任务单" prop="taskId"> <el-form-item :label="t('ProductionPlan.Plan.searchTaskLabel')" prop="taskId">
<el-select <el-select
v-model="queryParams.taskId" v-model="queryParams.taskId"
@change="handleQuery" @change="handleQuery"
clearable clearable
filterable filterable
placeholder="请选择" :placeholder="t('ProductionPlan.Plan.searchTaskPlaceholder')"
class="!w-180px" class="!w-180px"
> >
<el-option <el-option
@ -25,22 +25,22 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="计划编码" prop="code"> <el-form-item :label="t('ProductionPlan.Plan.searchCodeLabel')" prop="code">
<el-input <el-input
v-model="queryParams.code" v-model="queryParams.code"
placeholder="请输入计划编码" :placeholder="t('ProductionPlan.Plan.searchCodePlaceholder')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
class="!w-180px" class="!w-180px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="产品" prop="productId"> <el-form-item :label="t('ProductionPlan.Plan.searchProductLabel')" prop="productId">
<el-select <el-select
v-model="queryParams.productId" v-model="queryParams.productId"
@change="handleQuery" @change="handleQuery"
clearable clearable
filterable filterable
placeholder="请选择产品" :placeholder="t('ProductionPlan.Plan.searchProductPlaceholder')"
class="!w-180px" class="!w-180px"
> >
<el-option <el-option
@ -51,42 +51,42 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item :label="t('ProductionPlan.Plan.searchRemarkLabel')" prop="remark">
<el-input <el-input
v-model="queryParams.remark" v-model="queryParams.remark"
placeholder="请输入备注" :placeholder="t('ProductionPlan.Plan.searchRemarkPlaceholder')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
class="!w-180px" class="!w-180px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="计划开始" prop="planStartTime"> <el-form-item :label="t('ProductionPlan.Plan.searchPlanStartLabel')" prop="planStartTime">
<el-date-picker <el-date-picker
v-model="queryParams.planStartTime" v-model="queryParams.planStartTime"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" type="daterange"
@change="handleQuery" @change="handleQuery"
start-placeholder="开始日期" :start-placeholder="t('ProductionPlan.Plan.searchPlanStartStartPlaceholder')"
end-placeholder="结束日期" :end-placeholder="t('ProductionPlan.Plan.searchPlanStartEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="计划结束" prop="planEndTime"> <el-form-item :label="t('ProductionPlan.Plan.searchPlanEndLabel')" prop="planEndTime">
<el-date-picker <el-date-picker
v-model="queryParams.planEndTime" v-model="queryParams.planEndTime"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" type="daterange"
@change="handleQuery" @change="handleQuery"
start-placeholder="开始日期" :start-placeholder="t('ProductionPlan.Plan.searchPlanEndStartPlaceholder')"
end-placeholder="结束日期" :end-placeholder="t('ProductionPlan.Plan.searchPlanEndEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> {{ t('ProductionPlan.Plan.buttonSearchText') }}</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> {{ t('ProductionPlan.Plan.buttonResetText') }}</el-button>
<!-- <el-button <!-- <el-button
type="primary" type="primary"
plain plain
@ -102,7 +102,7 @@
:loading="exportLoading" :loading="exportLoading"
v-hasPermi="['mes:plan:export']" v-hasPermi="['mes:plan:export']"
> >
<Icon icon="ep:download" class="mr-5px" /> 导出 <Icon icon="ep:download" class="mr-5px" /> {{ t('ProductionPlan.Plan.buttonExportText') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -113,19 +113,19 @@
<el-tabs v-model="activeName" @tab-click="handleTabClick"> <el-tabs v-model="activeName" @tab-click="handleTabClick">
<!-- <el-tab-pane label="所有" name="" /> --> <!-- <el-tab-pane label="所有" name="" /> -->
<!-- <el-tab-pane label="派工" name="0" /> --> <!-- <el-tab-pane label="派工" name="0" /> -->
<el-tab-pane label="已排产" name="1" /> <el-tab-pane :label="t('ProductionPlan.Plan.tabPlannedLabel')" name="1" />
<el-tab-pane label="试产" name="6" /> <el-tab-pane :label="t('ProductionPlan.Plan.tabTrialLabel')" name="6" />
<el-tab-pane label="量产" name="2" /> <el-tab-pane :label="t('ProductionPlan.Plan.tabMassLabel')" name="2" />
<el-tab-pane label="暂停" name="3" /> <el-tab-pane :label="t('ProductionPlan.Plan.tabPausedLabel')" name="3" />
<el-tab-pane label="待入库" name="4" /> <el-tab-pane :label="t('ProductionPlan.Plan.tabToStoreLabel')" name="4" />
<el-tab-pane label="已入库" name="5" /> <el-tab-pane :label="t('ProductionPlan.Plan.tabStoredLabel')" name="5" />
</el-tabs> </el-tabs>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<!-- 投料进度子表的列表 --> <!-- 投料进度子表的列表 -->
<el-table-column type="expand"> <el-table-column type="expand">
<template #default="scope"> <template #default="scope">
<el-tabs v-if="scope.row.status <= 1 && scope.row.status != 6" model-value="itemRequisitionDetail"> <el-tabs v-if="scope.row.status <= 1 && scope.row.status != 6" model-value="itemRequisitionDetail">
<el-tab-pane label="投料明细" name="itemRequisitionDetail" > <el-tab-pane :label="t('ProductionPlan.Plan.detailItemRequisitionTabLabel')" name="itemRequisitionDetail" >
<ItemRequisitionDetailList :item-requisition-id="scope.row.requisitionId" /> <ItemRequisitionDetailList :item-requisition-id="scope.row.requisitionId" />
</el-tab-pane> </el-tab-pane>
<!-- <el-tab-pane label="派工记录" name="paigongRecord"> <!-- <el-tab-pane label="派工记录" name="paigongRecord">
@ -138,29 +138,29 @@
</el-tab-pane> </el-tab-pane>
</el-tabs> --> </el-tabs> -->
<el-tabs v-if="scope.row.status == 6" model-value="zj"> <el-tabs v-if="scope.row.status == 6" model-value="zj">
<el-tab-pane label="检验明细" name="zj"> <el-tab-pane :label="t('ProductionPlan.Plan.detailInspectTabLabel')" name="zj">
<ZjProductPreList :product-id="scope.row.productId"/> <ZjProductPreList :product-id="scope.row.productId"/>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<el-tabs v-if="scope.row.status >= 2 && scope.row.status != 6" model-value="itemRequisitionDetail"> <el-tabs v-if="scope.row.status >= 2 && scope.row.status != 6" model-value="itemRequisitionDetail">
<el-tab-pane label="投料明细" name="itemRequisitionDetail" > <el-tab-pane :label="t('ProductionPlan.Plan.detailItemRequisitionTabLabel')" name="itemRequisitionDetail" >
<ItemRequisitionDetailList :item-requisition-id="scope.row.requisitionId" /> <ItemRequisitionDetailList :item-requisition-id="scope.row.requisitionId" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="报工记录" name="baogongRecord"> <el-tab-pane :label="t('ProductionPlan.Plan.detailBaogongRecordTabLabel')" name="baogongRecord">
<BaogongRecordList :plan-id="scope.row.id"/> <BaogongRecordList :plan-id="scope.row.id"/>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="计划编码" align="center" prop="code" min-width="180px" /> <el-table-column :label="t('ProductionPlan.Plan.tableCodeColumn')" align="center" prop="code" min-width="180px" />
<el-table-column label="产品" align="center" prop="productName" min-width="200px" sortable/> <el-table-column :label="t('ProductionPlan.Plan.tableProductColumn')" align="center" prop="productName" min-width="200px" sortable/>
<!-- <el-table-column label="任务单" align="center" prop="taskCode" min-width="150px" />--> <!-- <el-table-column label="任务单" align="center" prop="taskCode" min-width="150px" />-->
<el-table-column label="生产线" align="center" prop="feedingPipelineName"/> <el-table-column :label="t('ProductionPlan.Plan.tableFeedingPipelineColumn')" align="center" prop="feedingPipelineName"/>
<el-table-column label="计划数量" align="center" prop="planNumber" /> <el-table-column :label="t('ProductionPlan.Plan.tablePlanNumberColumn')" align="center" prop="planNumber" />
<el-table-column label="完工数量" align="center" prop="wangongNumber" /> <el-table-column :label="t('ProductionPlan.Plan.tableFinishNumberColumn')" align="center" prop="wangongNumber" />
<el-table-column label="合格率(%)" align="center" prop="passRate" /> <el-table-column :label="t('ProductionPlan.Plan.tablePassRateColumn')" align="center" prop="passRate" />
<!-- <el-table-column label="热压数量" align="center" prop="reyaNumber" /> --> <!-- <el-table-column label="热压数量" align="center" prop="reyaNumber" /> -->
<el-table-column label="状态" align="center" prop="status" sortable> <el-table-column :label="t('ProductionPlan.Plan.tableStatusColumn')" align="center" prop="status" sortable>
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.MES_PLAN_STATUS" :value="scope.row.status" /> <dict-tag :type="DICT_TYPE.MES_PLAN_STATUS" :value="scope.row.status" />
</template> </template>
@ -171,15 +171,15 @@
</template> </template>
</el-table-column> --> </el-table-column> -->
<!-- <el-table-column label="领料人" align="center" prop="productionManagerName" /> --> <!-- <el-table-column label="领料人" align="center" prop="productionManagerName" /> -->
<el-table-column label="计划开始时间" align="center" sortable prop="planStartTime" :formatter="dateFormatter2" width="150px"/> <el-table-column :label="t('ProductionPlan.Plan.tablePlanStartTimeColumn')" align="center" sortable prop="planStartTime" :formatter="dateFormatter2" width="150px"/>
<el-table-column label="计划结束时间" align="center" sortable prop="planEndTime" :formatter="dateFormatter2" width="150px"/> <el-table-column :label="t('ProductionPlan.Plan.tablePlanEndTimeColumn')" align="center" sortable prop="planEndTime" :formatter="dateFormatter2" width="150px"/>
<el-table-column label="是否检验" align="center" prop="isZj" v-if="activeName === '6'"> <el-table-column :label="t('ProductionPlan.Plan.tableIsZjColumn')" align="center" prop="isZj" v-if="activeName === '6'">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.MES_ZJ_PRODUCT" :value="scope.row.isZj" /> <dict-tag :type="DICT_TYPE.MES_ZJ_PRODUCT" :value="scope.row.isZj" />
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column label="备注" align="center" prop="remark" /> --> <!-- <el-table-column :label="t('ProductionPlan.Plan.tableRemarkColumn')" align="center" prop="remark" /> -->
<el-table-column label="操作" align="center" fixed="right" width="350"> <el-table-column :label="t('ProductionPlan.Plan.tableOperateColumn')" align="center" fixed="right" width="350">
<template #default="scope"> <template #default="scope">
<el-button <el-button
link link
@ -187,8 +187,8 @@
@click="openDetail(scope.row.id)" @click="openDetail(scope.row.id)"
v-hasPermi="['mes:plan:query']" v-hasPermi="['mes:plan:query']"
> >
详情 {{ t('ProductionPlan.Plan.actionDetailLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
type="primary" type="primary"
@ -196,7 +196,7 @@
v-hasPermi="['mes:plan:update']" v-hasPermi="['mes:plan:update']"
v-if="scope.row.status === 0" v-if="scope.row.status === 0"
> >
编辑 {{ t('ProductionPlan.Plan.actionEditLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
@ -204,7 +204,7 @@
@click="openItemNeed(scope.row.code, scope.row.id)" @click="openItemNeed(scope.row.code, scope.row.id)"
v-hasPermi="['mes:task:query']" v-hasPermi="['mes:task:query']"
> >
物料 {{ t('ProductionPlan.Plan.actionMaterialLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
@ -213,7 +213,7 @@
v-hasPermi="['mes:plan:update']" v-hasPermi="['mes:plan:update']"
v-if="scope.row.status === 0" v-if="scope.row.status === 0"
> >
下料派工 {{ t('ProductionPlan.Plan.actionDispatchFeedingLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
@ -222,16 +222,16 @@
v-hasPermi="['mes:plan:update']" v-hasPermi="['mes:plan:update']"
v-if="scope.row.status === 0" v-if="scope.row.status === 0"
> >
工序派工 {{ t('ProductionPlan.Plan.actionDispatchProcessLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
type="primary" type="primary"
@click="handleStatus(scope.row.code, scope.row.id, 'pre',6,'试产', scope.row.isZj)" @click="handleStatus(scope.row.code, scope.row.id, 'pre',6, t('ProductionPlan.Plan.actionTrialLabel'), scope.row.isZj)"
v-hasPermi="['mes:plan:update']" v-hasPermi="['mes:plan:update']"
v-if="scope.row.status === 1 && scope.row.isPreProduction === 1" v-if="scope.row.status === 1 && scope.row.isPreProduction === 1"
> >
试产 {{ t('ProductionPlan.Plan.actionTrialLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
@ -239,16 +239,16 @@
@click="openZjProductForm(scope.row.productId,'pre',6,scope.row.id,scope.row.isZj)" @click="openZjProductForm(scope.row.productId,'pre',6,scope.row.id,scope.row.isZj)"
v-if="scope.row.status === 6" v-if="scope.row.status === 6"
> >
检验 {{ t('ProductionPlan.Plan.actionInspectLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
type="primary" type="primary"
@click="handleStatus(scope.row.code, scope.row.id, 'start',2,'量产', scope.row.isZj)" @click="handleStatus(scope.row.code, scope.row.id, 'start',2, t('ProductionPlan.Plan.actionMassLabel'), scope.row.isZj)"
v-hasPermi="['mes:plan:update']" v-hasPermi="['mes:plan:update']"
v-if="(scope.row.status === 1 && scope.row.isPreProduction === 0) || scope.row.status === 6" v-if="(scope.row.status === 1 && scope.row.isPreProduction === 0) || scope.row.status === 6"
> >
量产 {{ t('ProductionPlan.Plan.actionMassLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
@ -257,34 +257,34 @@
@click="openBaogongForm(scope.row.code, scope.row.id)" @click="openBaogongForm(scope.row.code, scope.row.id)"
v-if="scope.row.status === 2" v-if="scope.row.status === 2"
> >
报工 {{ t('ProductionPlan.Plan.actionBaogongLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
type="primary" type="primary"
@click="handleStatus(scope.row.code,scope.row.id, 'pause',3,'暂停', scope.row.isZj)" @click="handleStatus(scope.row.code,scope.row.id, 'pause',3, t('ProductionPlan.Plan.actionPauseLabel'), scope.row.isZj)"
v-hasPermi="['mes:plan:update']" v-hasPermi="['mes:plan:update']"
v-if="scope.row.status === 2" v-if="scope.row.status === 2"
> >
暂停 {{ t('ProductionPlan.Plan.actionPauseLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
type="primary" type="primary"
@click="handleStatus(scope.row.code, scope.row.id, 'end',4,'完工', scope.row.isZj)" @click="handleStatus(scope.row.code, scope.row.id, 'end',4, t('ProductionPlan.Plan.actionFinishLabel'), scope.row.isZj)"
v-hasPermi="['mes:plan:update']" v-hasPermi="['mes:plan:update']"
v-if="scope.row.status === 2 || scope.row.status === 3" v-if="scope.row.status === 2 || scope.row.status === 3"
> >
完工 {{ t('ProductionPlan.Plan.actionFinishLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
type="primary" type="primary"
@click="handleStatus(scope.row.code, scope.row.id, 'store',5,'入库', scope.row.isZj)" @click="handleStatus(scope.row.code, scope.row.id, 'store',5, t('ProductionPlan.Plan.actionStoreLabel'), scope.row.isZj)"
v-hasPermi="['mes:plan:update']" v-hasPermi="['mes:plan:update']"
v-if="scope.row.status === 4" v-if="scope.row.status === 4"
> >
入库 {{ t('ProductionPlan.Plan.actionStoreLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
@ -293,7 +293,7 @@
v-hasPermi="['mes:plan:delete']" v-hasPermi="['mes:plan:delete']"
v-if="scope.row.status === 0" v-if="scope.row.status === 0"
> >
删除 {{ t('ProductionPlan.Plan.actionDeleteLabel') }}
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -439,7 +439,7 @@ const handleExport = async () => {
// //
exportLoading.value = true exportLoading.value = true
const data = await PlanApi.exportPlan(queryParams) const data = await PlanApi.exportPlan(queryParams)
download.excel(data, '生产计划.xls') download.excel(data, t('ProductionPlan.Plan.exportFilename'))
} catch { } catch {
} finally { } finally {
exportLoading.value = false exportLoading.value = false
@ -465,7 +465,7 @@ onMounted(async () => {
/** 物料需求 */ /** 物料需求 */
const itemFormRef = ref() const itemFormRef = ref()
const openItemNeed = (planCode:string, planId: number) => { const openItemNeed = (planCode:string, planId: number) => {
itemFormRef.value.open("plan","计划-"+planCode, planId) itemFormRef.value.open('plan', t('ProductionPlan.Plan.itemNeedDialogPlanTitlePrefix') + planCode, planId)
} }
/** 派工 */ /** 派工 */
@ -502,7 +502,10 @@ const handleStatus = async (planCode:string, id: number,
// await message.confirm(""+planCode+""+tip+"?",planCode) // await message.confirm(""+planCode+""+tip+"?",planCode)
// } // }
// //
await message.confirm("计划:"+planCode+"确定"+tip+"吗?",planCode) await message.confirm(
t('ProductionPlan.Plan.statusConfirmMessage', { code: planCode, action: tip }),
t('ProductionPlan.Plan.statusConfirmTitle')
)
// //
const data ={ const data ={
id: id, id: id,
@ -520,7 +523,10 @@ const handleStatus = async (planCode:string, id: number,
const handleZjStatus = async (planCode:string, id: number) => { const handleZjStatus = async (planCode:string, id: number) => {
try { try {
// //
await message.confirm("计划:"+planCode+"确定质检吗?",planCode) await message.confirm(
t('ProductionPlan.Plan.inspectConfirmMessage', { code: planCode }),
t('ProductionPlan.Plan.inspectConfirmTitle')
)
// //
const data ={ const data ={
id: id id: id

@ -4,36 +4,36 @@
ref="formRef" ref="formRef"
:model="formData" :model="formData"
:rules="formRules" :rules="formRules"
label-width="100px" label-width="auto"
v-loading="formLoading" v-loading="formLoading"
> >
<el-form-item label="班组" prop="workTeamId"> <el-form-item :label="t('ProductionPlan.FormingRecord.dialogTeamLabel')" prop="workTeamId">
<el-input v-model="formData.workTeamId" placeholder="请输入班组" /> <el-input v-model="formData.workTeamId" :placeholder="t('ProductionPlan.FormingRecord.dialogTeamPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item label="工位" prop="organizationId"> <el-form-item :label="t('ProductionPlan.FormingRecord.dialogOrganizationLabel')" prop="organizationId">
<el-input v-model="formData.organizationId" placeholder="请输入工位" /> <el-input v-model="formData.organizationId" :placeholder="t('ProductionPlan.FormingRecord.dialogOrganizationPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item label="机台" prop="machineId"> <el-form-item :label="t('ProductionPlan.FormingRecord.dialogMachineLabel')" prop="machineId">
<el-input v-model="formData.machineId" placeholder="请输入机台" /> <el-input v-model="formData.machineId" :placeholder="t('ProductionPlan.FormingRecord.dialogMachinePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item label="开始时间" prop="startTime"> <el-form-item :label="t('ProductionPlan.FormingRecord.dialogStartTimeLabel')" prop="startTime">
<el-date-picker <el-date-picker
v-model="formData.startTime" v-model="formData.startTime"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择开始时间" :placeholder="t('ProductionPlan.FormingRecord.dialogStartTimePlaceholder')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="结束时间" prop="endTime"> <el-form-item :label="t('ProductionPlan.FormingRecord.dialogEndTimeLabel')" prop="endTime">
<el-date-picker <el-date-picker
v-model="formData.endTime" v-model="formData.endTime"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择结束时间" :placeholder="t('ProductionPlan.FormingRecord.dialogEndTimePlaceholder')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="状态" prop="status"> <el-form-item :label="t('ProductionPlan.FormingRecord.dialogStatusLabel')" prop="status">
<el-radio-group v-model="formData.status"> <el-radio-group v-model="formData.status">
<el-radio <el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.MES_RECORD_STATUS)" v-for="dict in getIntDictOptions(DICT_TYPE.MES_RECORD_STATUS)"
@ -44,8 +44,8 @@
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="工序" prop="recordType"> <el-form-item :label="t('ProductionPlan.FormingRecord.dialogProcessLabel')" prop="recordType">
<el-select v-model="formData.recordType" placeholder="请选择工序"> <el-select v-model="formData.recordType" :placeholder="t('ProductionPlan.FormingRecord.dialogProcessPlaceholder')">
<el-option <el-option
v-for="dict in getStrDictOptions(DICT_TYPE.MES_ORG_TYPE)" v-for="dict in getStrDictOptions(DICT_TYPE.MES_ORG_TYPE)"
:key="dict.value" :key="dict.value"
@ -54,14 +54,14 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item :label="t('ProductionPlan.FormingRecord.dialogRemarkLabel')" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" /> <el-input v-model="formData.remark" :placeholder="t('ProductionPlan.FormingRecord.dialogRemarkPlaceholder')" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('ProductionPlan.FormingRecord.dialogSubmitButtonText') }}</el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.FormingRecord.dialogCancelButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -98,10 +98,10 @@ const formData = ref({
isEnable: undefined, isEnable: undefined,
}) })
const formRules = reactive({ const formRules = reactive({
organizationId: [{ required: true, message: '工位不能为空', trigger: 'blur' }], organizationId: [{ required: true, message: t('ProductionPlan.FormingRecord.validatorOrganizationRequired'), trigger: 'blur' }],
startTime: [{ required: true, message: '开始时间不能为空', trigger: 'blur' }], startTime: [{ required: true, message: t('ProductionPlan.FormingRecord.validatorStartTimeRequired'), trigger: 'blur' }],
endTime: [{ required: true, message: '结束时间不能为空', trigger: 'blur' }], endTime: [{ required: true, message: t('ProductionPlan.FormingRecord.validatorEndTimeRequired'), trigger: 'blur' }],
recordType: [{ required: true, message: '工序不能为空', trigger: 'change' }], recordType: [{ required: true, message: t('ProductionPlan.FormingRecord.validatorProcessRequired'), trigger: 'change' }],
}) })
const formRef = ref() // Ref const formRef = ref() // Ref

@ -4,52 +4,52 @@
ref="formRef" ref="formRef"
:model="formData" :model="formData"
:rules="formRules" :rules="formRules"
label-width="100px" label-width="auto"
v-loading="formLoading" v-loading="formLoading"
> >
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="开机时间" prop="startTime"> <el-form-item :label="t('ProductionPlan.FormingRecord.detailDialogStartTimeLabel')" prop="startTime">
<el-date-picker <el-date-picker
v-model="formData.startTime" v-model="formData.startTime"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择开机时间" :placeholder="t('ProductionPlan.FormingRecord.detailDialogStartTimePlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="停机时间" prop="endTime"> <el-form-item :label="t('ProductionPlan.FormingRecord.detailDialogEndTimeLabel')" prop="endTime">
<el-date-picker <el-date-picker
v-model="formData.endTime" v-model="formData.endTime"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择停机时间" :placeholder="t('ProductionPlan.FormingRecord.detailDialogEndTimePlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="吸浆时间(S)" prop="xijiang"> <el-form-item :label="t('ProductionPlan.FormingRecord.detailDialogXijiangLabel')" prop="xijiang">
<el-input v-model="formData.xijiang" placeholder="请输入吸浆时间(S)" /> <el-input v-model="formData.xijiang" :placeholder="t('ProductionPlan.FormingRecord.detailDialogXijiangPlaceholder')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="脱水时间(S)" prop="tuoshui"> <el-form-item :label="t('ProductionPlan.FormingRecord.detailDialogTuoshuiLabel')" prop="tuoshui">
<el-input v-model="formData.tuoshui" placeholder="请输入脱水时间(S)" /> <el-input v-model="formData.tuoshui" :placeholder="t('ProductionPlan.FormingRecord.detailDialogTuoshuiPlaceholder')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="洗模时间(S)" prop="ximu"> <el-form-item :label="t('ProductionPlan.FormingRecord.detailDialogXimuLabel')" prop="ximu">
<el-input v-model="formData.ximu" placeholder="请输入洗模时间(S)" /> <el-input v-model="formData.ximu" :placeholder="t('ProductionPlan.FormingRecord.detailDialogXimuPlaceholder')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="产品" prop="productId"> <el-form-item :label="t('ProductionPlan.FormingRecord.detailDialogProductLabel')" prop="productId">
<el-select v-model="formData.productId" clearable filterable placeholder="请选择" > <el-select v-model="formData.productId" clearable filterable :placeholder="t('ProductionPlan.FormingRecord.detailDialogProductPlaceholder')" >
<el-option <el-option
v-for="item in productList" v-for="item in productList"
:key="item.id" :key="item.id"
@ -63,23 +63,23 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="产品外观" prop="appearance"> <el-form-item :label="t('ProductionPlan.FormingRecord.detailDialogAppearanceLabel')" prop="appearance">
<el-input v-model="formData.appearance" placeholder="请输入产品外观" /> <el-input v-model="formData.appearance" :placeholder="t('ProductionPlan.FormingRecord.detailDialogAppearancePlaceholder')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="湿重(g)" prop="productWeight"> <el-form-item :label="t('ProductionPlan.FormingRecord.detailDialogProductWeightLabel')" prop="productWeight">
<el-input v-model="formData.productWeight" placeholder="请输入湿重(g)" /> <el-input v-model="formData.productWeight" :placeholder="t('ProductionPlan.FormingRecord.detailDialogProductWeightPlaceholder')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-form-item label="备注" prop="remark"> <el-form-item :label="t('ProductionPlan.FormingRecord.detailDialogRemarkLabel')" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" /> <el-input v-model="formData.remark" :placeholder="t('ProductionPlan.FormingRecord.detailDialogRemarkPlaceholder')" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('ProductionPlan.FormingRecord.dialogSubmitButtonText') }}</el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.FormingRecord.dialogCancelButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -111,13 +111,13 @@ const formData = ref({
isEnable: undefined, isEnable: undefined,
}) })
const formRules = reactive({ const formRules = reactive({
recordId: [{ required: true, message: '记录id不能为空', trigger: 'blur' }], recordId: [{ required: true, message: t('ProductionPlan.FormingRecord.detailValidatorRecordIdRequired'), trigger: 'blur' }],
xijiang: [{ required: true, message: '吸浆时间(S)不能为空', trigger: 'blur' }], xijiang: [{ required: true, message: t('ProductionPlan.FormingRecord.detailValidatorXijiangRequired'), trigger: 'blur' }],
tuoshui: [{ required: true, message: '脱水时间(S)不能为空', trigger: 'blur' }], tuoshui: [{ required: true, message: t('ProductionPlan.FormingRecord.detailValidatorTuoshuiRequired'), trigger: 'blur' }],
ximu: [{ required: true, message: '洗模时间(S)不能为空', trigger: 'blur' }], ximu: [{ required: true, message: t('ProductionPlan.FormingRecord.detailValidatorXimuRequired'), trigger: 'blur' }],
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }], productId: [{ required: true, message: t('ProductionPlan.FormingRecord.detailValidatorProductRequired'), trigger: 'blur' }],
appearance: [{ required: true, message: '产品外观不能为空', trigger: 'blur' }], appearance: [{ required: true, message: t('ProductionPlan.FormingRecord.detailValidatorAppearanceRequired'), trigger: 'blur' }],
productWeight: [{ required: true, message: '湿重(g)不能为空', trigger: 'blur' }], productWeight: [{ required: true, message: t('ProductionPlan.FormingRecord.detailValidatorProductWeightRequired'), trigger: 'blur' }],
}) })
const formRef = ref() // Ref const formRef = ref() // Ref
const productList = ref<ProductVO[]>([]) // const productList = ref<ProductVO[]>([]) //

@ -7,40 +7,40 @@
@click="openForm('create')" @click="openForm('create')"
v-hasPermi="['mes:record-template:create']" v-hasPermi="['mes:record-template:create']"
> >
<Icon icon="ep:plus" class="mr-5px" /> 新增 <Icon icon="ep:plus" class="mr-5px" /> {{ t('ProductionPlan.FormingRecord.buttonCreateText') }}
</el-button> </el-button>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column <el-table-column
label="创建时间" :label="t('ProductionPlan.FormingRecord.detailListCreateTimeColumn')"
align="center" align="center"
prop="createTime" prop="createTime"
:formatter="dateFormatter" :formatter="dateFormatter"
width="180px" width="180px"
sortable sortable
/> />
<el-table-column label="创建者" align="center" prop="creator" /> <el-table-column :label="t('ProductionPlan.FormingRecord.detailListCreatorColumn')" align="center" prop="creator" />
<el-table-column label="吸浆时间(S)" align="center" prop="xijiang" /> <el-table-column :label="t('ProductionPlan.FormingRecord.detailListXijiangColumn')" align="center" prop="xijiang" />
<el-table-column label="脱水时间(S)" align="center" prop="tuoshui" /> <el-table-column :label="t('ProductionPlan.FormingRecord.detailListTuoshuiColumn')" align="center" prop="tuoshui" />
<el-table-column label="洗模时间(S)" align="center" prop="ximu" /> <el-table-column :label="t('ProductionPlan.FormingRecord.detailListXimuColumn')" align="center" prop="ximu" />
<el-table-column label="产品" align="center" prop="productId" /> <el-table-column :label="t('ProductionPlan.FormingRecord.detailListProductColumn')" align="center" prop="productId" />
<el-table-column label="产品外观" align="center" prop="appearance" /> <el-table-column :label="t('ProductionPlan.FormingRecord.detailListAppearanceColumn')" align="center" prop="appearance" />
<el-table-column label="湿重(g)" align="center" prop="productWeight" /> <el-table-column :label="t('ProductionPlan.FormingRecord.detailListProductWeightColumn')" align="center" prop="productWeight" />
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column :label="t('ProductionPlan.FormingRecord.detailListRemarkColumn')" align="center" prop="remark" />
<el-table-column <el-table-column
label="开机时间" :label="t('ProductionPlan.FormingRecord.detailListStartTimeColumn')"
align="center" align="center"
prop="startTime" prop="startTime"
:formatter="dateFormatter" :formatter="dateFormatter"
width="180px" width="180px"
/> />
<el-table-column <el-table-column
label="停机时间" :label="t('ProductionPlan.FormingRecord.detailListEndTimeColumn')"
align="center" align="center"
prop="endTime" prop="endTime"
:formatter="dateFormatter" :formatter="dateFormatter"
width="180px" width="180px"
/> />
<el-table-column label="操作" align="center" fixed="right" width="120px"> <el-table-column :label="t('ProductionPlan.FormingRecord.detailListOperateColumn')" align="center" fixed="right" width="120px">
<template #default="scope"> <template #default="scope">
<el-button <el-button
link link
@ -48,7 +48,7 @@
@click="openForm('update', scope.row.id)" @click="openForm('update', scope.row.id)"
v-hasPermi="['mes:record-template:update']" v-hasPermi="['mes:record-template:update']"
> >
编辑 {{ t('common.edit') }}
</el-button> </el-button>
<el-button <el-button
link link
@ -56,7 +56,7 @@
@click="handleDelete(scope.row.id)" @click="handleDelete(scope.row.id)"
v-hasPermi="['mes:record-template:delete']" v-hasPermi="['mes:record-template:delete']"
> >
删除 {{ t('common.del') }}
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -128,7 +128,7 @@ const handleQuery = () => {
const formRef = ref() const formRef = ref()
const openForm = (type: string, id?: number) => { const openForm = (type: string, id?: number) => {
if (!props.recordId) { if (!props.recordId) {
message.error('请选择一个记录表') message.error(t('ProductionPlan.FormingRecord.messageSelectRecordRequired'))
return return
} }
formRef.value.open(type, id, props.recordId) formRef.value.open(type, id, props.recordId)

@ -6,14 +6,14 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" label-width="auto"
> >
<el-row> <el-row>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="工位" prop="organizationId"> <el-form-item :label="t('ProductionPlan.FormingRecord.searchOrganizationLabel')" prop="organizationId">
<el-input <el-input
v-model="queryParams.organizationId" v-model="queryParams.organizationId"
placeholder="请输入工位" :placeholder="t('ProductionPlan.FormingRecord.searchOrganizationPlaceholder')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
class="!w-240px" class="!w-240px"
@ -21,10 +21,10 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="机台" prop="machineId"> <el-form-item :label="t('ProductionPlan.FormingRecord.searchMachineLabel')" prop="machineId">
<el-input <el-input
v-model="queryParams.machineId" v-model="queryParams.machineId"
placeholder="请输入机台" :placeholder="t('ProductionPlan.FormingRecord.searchMachinePlaceholder')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
class="!w-240px" class="!w-240px"
@ -32,10 +32,10 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="班组" prop="workTeamId"> <el-form-item :label="t('ProductionPlan.FormingRecord.searchTeamLabel')" prop="workTeamId">
<el-input <el-input
v-model="queryParams.workTeamId" v-model="queryParams.workTeamId"
placeholder="请输入班组" :placeholder="t('ProductionPlan.FormingRecord.searchTeamPlaceholder')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
class="!w-240px" class="!w-240px"
@ -43,10 +43,10 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="备注" prop="remark"> <el-form-item :label="t('ProductionPlan.FormingRecord.searchRemarkLabel')" prop="remark">
<el-input <el-input
v-model="queryParams.remark" v-model="queryParams.remark"
placeholder="请输入备注" :placeholder="t('ProductionPlan.FormingRecord.searchRemarkPlaceholder')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
class="!w-240px" class="!w-240px"
@ -56,26 +56,26 @@
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="开始时间" prop="startTime"> <el-form-item :label="t('ProductionPlan.FormingRecord.searchStartTimeLabel')" prop="startTime">
<el-date-picker <el-date-picker
v-model="queryParams.startTime" v-model="queryParams.startTime"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" type="daterange"
start-placeholder="开始日期" :start-placeholder="t('ProductionPlan.FormingRecord.searchStartTimeStartPlaceholder')"
end-placeholder="结束日期" :end-placeholder="t('ProductionPlan.FormingRecord.searchStartTimeEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="结束时间" prop="endTime"> <el-form-item :label="t('ProductionPlan.FormingRecord.searchEndTimeLabel')" prop="endTime">
<el-date-picker <el-date-picker
v-model="queryParams.endTime" v-model="queryParams.endTime"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" type="daterange"
start-placeholder="开始日期" :start-placeholder="t('ProductionPlan.FormingRecord.searchEndTimeStartPlaceholder')"
end-placeholder="结束日期" :end-placeholder="t('ProductionPlan.FormingRecord.searchEndTimeEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px" class="!w-240px"
/> />
@ -83,15 +83,15 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item> <el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> {{ t('ProductionPlan.FormingRecord.buttonSearchText') }}</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> {{ t('ProductionPlan.FormingRecord.buttonResetText') }}</el-button>
<el-button <el-button
type="primary" type="primary"
plain plain
@click="openForm('create')" @click="openForm('create')"
v-hasPermi="['mes:record-template:create']" v-hasPermi="['mes:record-template:create']"
> >
<Icon icon="ep:plus" class="mr-5px" /> 新增 <Icon icon="ep:plus" class="mr-5px" /> {{ t('ProductionPlan.FormingRecord.buttonCreateText') }}
</el-button> </el-button>
<el-button <el-button
type="success" type="success"
@ -100,7 +100,7 @@
:loading="exportLoading" :loading="exportLoading"
v-hasPermi="['mes:record-template:export']" v-hasPermi="['mes:record-template:export']"
> >
<Icon icon="ep:download" class="mr-5px" /> 导出 <Icon icon="ep:download" class="mr-5px" /> {{ t('ProductionPlan.FormingRecord.buttonExportText') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -118,43 +118,43 @@
highlight-current-row highlight-current-row
@current-change="handleCurrentChange" @current-change="handleCurrentChange"
> >
<el-table-column label="名称" align="center" prop="name" /> <el-table-column :label="t('ProductionPlan.FormingRecord.tableNameColumn')" align="center" prop="name" />
<el-table-column label="工位" align="center" prop="organizationId" /> <el-table-column :label="t('ProductionPlan.FormingRecord.tableOrganizationColumn')" align="center" prop="organizationId" />
<el-table-column label="机台" align="center" prop="machineId" /> <el-table-column :label="t('ProductionPlan.FormingRecord.tableMachineColumn')" align="center" prop="machineId" />
<el-table-column label="班组" align="center" prop="workTeamId" /> <el-table-column :label="t('ProductionPlan.FormingRecord.tableTeamColumn')" align="center" prop="workTeamId" />
<el-table-column <el-table-column
label="开始时间" :label="t('ProductionPlan.FormingRecord.tableStartTimeColumn')"
align="center" align="center"
prop="startTime" prop="startTime"
:formatter="dateFormatter" :formatter="dateFormatter"
width="180px" width="180px"
/> />
<el-table-column <el-table-column
label="结束时间" :label="t('ProductionPlan.FormingRecord.tableEndTimeColumn')"
align="center" align="center"
prop="endTime" prop="endTime"
:formatter="dateFormatter" :formatter="dateFormatter"
width="180px" width="180px"
/> />
<el-table-column label="状态" align="center" prop="status"> <el-table-column :label="t('ProductionPlan.FormingRecord.tableStatusColumn')" align="center" prop="status">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.MES_RECORD_STATUS" :value="scope.row.status" /> <dict-tag :type="DICT_TYPE.MES_RECORD_STATUS" :value="scope.row.status" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="工序" align="center" prop="recordType"> <el-table-column :label="t('ProductionPlan.FormingRecord.tableProcessColumn')" align="center" prop="recordType">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.MES_ORG_TYPE" :value="scope.row.recordType" /> <dict-tag :type="DICT_TYPE.MES_ORG_TYPE" :value="scope.row.recordType" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column :label="t('ProductionPlan.FormingRecord.tableRemarkColumn')" align="center" prop="remark" />
<el-table-column <el-table-column
label="创建时间" :label="t('ProductionPlan.FormingRecord.tableCreateTimeColumn')"
align="center" align="center"
prop="createTime" prop="createTime"
:formatter="dateFormatter" :formatter="dateFormatter"
width="180px" width="180px"
/> />
<el-table-column label="操作" align="center" fixed="right" width="130px"> <el-table-column :label="t('ProductionPlan.FormingRecord.tableOperateColumn')" align="center" fixed="right" width="130px">
<template #default="scope"> <template #default="scope">
<el-button <el-button
link link
@ -162,7 +162,7 @@
@click="openForm('update', scope.row.id)" @click="openForm('update', scope.row.id)"
v-hasPermi="['mes:record-template:update']" v-hasPermi="['mes:record-template:update']"
> >
编辑 {{ t('ProductionPlan.FormingRecord.actionEditLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
@ -170,7 +170,7 @@
@click="handleDelete(scope.row.id)" @click="handleDelete(scope.row.id)"
v-hasPermi="['mes:record-template:delete']" v-hasPermi="['mes:record-template:delete']"
> >
删除 {{ t('ProductionPlan.FormingRecord.actionDeleteLabel') }}
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -189,7 +189,7 @@
<!-- 子表的列表 --> <!-- 子表的列表 -->
<ContentWrap> <ContentWrap>
<el-tabs model-value="recordChengxing"> <el-tabs model-value="recordChengxing">
<el-tab-pane label="成型记录" name="recordChengxing"> <el-tab-pane :label="t('ProductionPlan.FormingRecord.tabFormingRecordLabel')" name="recordChengxing">
<RecordChengxingList :record-id="currentRow.id" /> <RecordChengxingList :record-id="currentRow.id" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>

@ -4,32 +4,32 @@
ref="formRef" ref="formRef"
:model="formData" :model="formData"
:rules="formRules" :rules="formRules"
label-width="80px" label-width="100px"
v-loading="formLoading" v-loading="formLoading"
> >
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="编码" prop="code"> <el-form-item :label="t('ProductionPlan.Task.saleDialogCodeLabel')" prop="code">
<el-input v-model="formData.code" placeholder="请输入任务单编码" /> <el-input v-model="formData.code" :placeholder="t('ProductionPlan.Task.saleDialogCodePlaceholder')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="交货日期" prop="deliveryDate"> <el-form-item :label="t('ProductionPlan.Task.saleDialogDeliveryDateLabel')" prop="deliveryDate">
<el-date-picker <el-date-picker
v-model="formData.deliveryDate" v-model="formData.deliveryDate"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择交货日期" :placeholder="t('ProductionPlan.Task.saleDialogDeliveryDatePlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="备注" prop="remark"> <el-form-item :label="t('ProductionPlan.Task.saleDialogRemarkLabel')" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" /> <el-input v-model="formData.remark" :placeholder="t('ProductionPlan.Task.saleDialogRemarkPlaceholder')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-form-item label="任务类型" prop="taskType"> <el-form-item :label="t('ProductionPlan.Task.saleDialogTaskTypeLabel')" prop="taskType">
<el-radio-group v-model="formData.taskType"> <el-radio-group v-model="formData.taskType">
<el-radio <el-radio
v-for="dict in getStrDictOptions(DICT_TYPE.MES_TASK_TYPE)" v-for="dict in getStrDictOptions(DICT_TYPE.MES_TASK_TYPE)"
@ -43,13 +43,13 @@
</el-form> </el-form>
<!-- 子表的表单 --> <!-- 子表的表单 -->
<el-tabs v-model="subTabsName"> <el-tabs v-model="subTabsName">
<el-tab-pane label="生产任务单明细" name="taskDetail"> <el-tab-pane :label="t('ProductionPlan.Task.saleDetailTabTaskDetailLabel')" name="taskDetail">
<TaskAddSaleDetailForm ref="taskDetailFormRef" :task-id="formData.id" /> <TaskAddSaleDetailForm ref="taskDetailFormRef" :task-id="formData.id" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('ProductionPlan.Task.dialogSubmitButtonText') }}</el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.Task.dialogCancelButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -80,9 +80,9 @@ const formData = ref({
isEnable: undefined, isEnable: undefined,
}) })
const formRules = reactive({ const formRules = reactive({
code: [{ required: true, message: '编码不能为空', trigger: 'blur' }], code: [{ required: true, message: t('ProductionPlan.Task.saleValidatorCodeRequired'), trigger: 'blur' }],
deliveryDate: [{ required: true, message: '交货日期不能为空', trigger: 'blur' }], deliveryDate: [{ required: true, message: t('ProductionPlan.Task.saleValidatorDeliveryDateRequired'), trigger: 'blur' }],
taskType: [{ required: true, message: '任务类型不能为空', trigger: 'blur' }], taskType: [{ required: true, message: t('ProductionPlan.Task.saleValidatorTaskTypeRequired'), trigger: 'blur' }],
}) })
const formRef = ref() // Ref const formRef = ref() // Ref

@ -10,8 +10,8 @@
<el-form-item prop="code"> <el-form-item prop="code">
<template #label> <template #label>
<span> <span>
任务单编码 {{ t('ProductionPlan.Task.dialogCodeLabel') }}
<el-tooltip content="任务单编码" placement="top"> <el-tooltip :content="t('ProductionPlan.Task.dialogCodeTooltip')" placement="top">
<Icon icon="ep:question-filled" /> <Icon icon="ep:question-filled" />
</el-tooltip> </el-tooltip>
</span> </span>
@ -21,7 +21,7 @@
<el-input <el-input
:disabled="formData.isCode == true || formType === 'update'" :disabled="formData.isCode == true || formType === 'update'"
v-model="formData.code" v-model="formData.code"
placeholder="编码保存后自动生成" :placeholder="t('ProductionPlan.Task.dialogCodePlaceholder')"
/> />
</el-col> </el-col>
<el-col :xs="24" :sm="6" :md="4" :lg="3" :xl="2"> <el-col :xs="24" :sm="6" :md="4" :lg="3" :xl="2">
@ -34,20 +34,20 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="交货日期" prop="deliveryDate"> <el-form-item :label="t('ProductionPlan.Task.dialogDeliveryDateLabel')" prop="deliveryDate">
<el-date-picker <el-date-picker
v-model="formData.deliveryDate" v-model="formData.deliveryDate"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择交货日期" :placeholder="t('ProductionPlan.Task.dialogDeliveryDatePlaceholder')"
class="!w-full" class="!w-full"
/> />
</el-form-item> </el-form-item>
<el-form-item label="任务类型" prop="taskType"> <el-form-item :label="t('ProductionPlan.Task.dialogTaskTypeLabel')" prop="taskType">
<template #label> <template #label>
<span> <span>
类型 {{ t('ProductionPlan.Task.dialogTaskTypeLabel') }}
<el-tooltip content="来源:数据字典-任务单类型" placement="top"> <el-tooltip :content="t('ProductionPlan.Task.dialogTaskTypeTooltip')" placement="top">
<Icon icon="ep:question-filled" /> <Icon icon="ep:question-filled" />
</el-tooltip> </el-tooltip>
</span> </span>
@ -63,14 +63,14 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item :label="t('ProductionPlan.Task.dialogRemarkLabel')" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" /> <el-input v-model="formData.remark" :placeholder="t('ProductionPlan.Task.dialogRemarkPlaceholder')" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('ProductionPlan.Task.dialogSubmitButtonText') }}</el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.Task.dialogCancelButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -101,8 +101,8 @@ const formData = ref({
isCode: undefined isCode: undefined
}) })
const formRules = reactive({ const formRules = reactive({
deliveryDate: [{ required: true, message: '交货日期不能为空', trigger: 'blur' }], deliveryDate: [{ required: true, message: t('ProductionPlan.Task.validatorDeliveryDateRequired'), trigger: 'blur' }],
taskType: [{ required: true, message: '任务类型不能为空', trigger: 'blur' }], taskType: [{ required: true, message: t('ProductionPlan.Task.validatorTaskTypeRequired'), trigger: 'blur' }],
}) })
const formRef = ref() // Ref const formRef = ref() // Ref

@ -8,35 +8,35 @@
> >
<el-row> <el-row>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="产品" prop="taskCode"> <el-form-item :label="t('ProductionPlan.Task.planDialogTaskCodeLabel')" prop="taskCode">
<el-input disabled v-model="formData.taskCode" placeholder="请输入"/> <el-input disabled v-model="formData.taskCode" :placeholder="t('ProductionPlan.Task.planDialogTaskCodePlaceholder')"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="总数" prop="number"> <el-form-item :label="t('ProductionPlan.Task.planDialogNumberLabel')" prop="number">
<el-input disabled v-model="formData.number" placeholder="请输入"/> <el-input disabled v-model="formData.number" :placeholder="t('ProductionPlan.Task.planDialogNumberPlaceholder')"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="未完成数" prop="planNumber"> <el-form-item :label="t('ProductionPlan.Task.planDialogPlanNumberLabel')" prop="planNumber">
<el-input v-model="formData.planNumber" placeholder="请输入"/> <el-input v-model="formData.planNumber" :placeholder="t('ProductionPlan.Task.planDialogPlanNumberPlaceholder')"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="6"> <el-col :span="6">
<el-form-item label="计划产量" prop="productsOfPlan"> <el-form-item :label="t('ProductionPlan.Task.planDialogProductsOfPlanLabel')" prop="productsOfPlan">
<el-input-number v-model="formData.productsOfPlan" :min="0" class="!w-1/1"/> <el-input-number v-model="formData.productsOfPlan" :min="0" class="!w-1/1"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="日期" prop="planDate"> <el-form-item :label="t('ProductionPlan.Task.planDialogPlanDateLabel')" prop="planDate">
<el-date-picker <el-date-picker
v-model="formData.planDate" v-model="formData.planDate"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
type="dates" type="dates"
placeholder="请选择排产日期" :placeholder="t('ProductionPlan.Task.planDialogPlanDatePlaceholder')"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
@ -47,7 +47,7 @@
<el-form-item> <el-form-item>
<el-button type="success" @click="handleQuery"> <el-button type="success" @click="handleQuery">
<Icon icon="ep:calendar" class="mr-5px"/> <Icon icon="ep:calendar" class="mr-5px"/>
自动排产 {{ t('ProductionPlan.Task.planDialogAutoButtonText') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -55,7 +55,7 @@
<el-form-item> <el-form-item>
<el-button type="danger" @click="resetQuery"> <el-button type="danger" @click="resetQuery">
<Icon icon="ep:delete" class="mr-5px"/> <Icon icon="ep:delete" class="mr-5px"/>
清空结果 {{ t('ProductionPlan.Task.planDialogResetButtonText') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -63,16 +63,16 @@
</el-form> </el-form>
<!-- 子表的表单 --> <!-- 子表的表单 -->
<el-tabs v-model="subTabsName"> <el-tabs v-model="subTabsName">
<el-tab-pane label="预排产计划" name="plan"> <el-tab-pane :label="t('ProductionPlan.Task.planDialogTabPlanLabel')" name="plan">
<PlanForm ref="planFormRef" :task-id="formData.id"/> <PlanForm ref="planFormRef" :task-id="formData.id"/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="已排产计划" name="finishPlan"> <el-tab-pane :label="t('ProductionPlan.Task.planDialogTabFinishPlanLabel')" name="finishPlan">
<el-text>hello</el-text> <el-text>hello</el-text>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('ProductionPlan.Task.planDialogSubmitButtonText') }}</el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.Task.planDialogCancelButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -101,8 +101,8 @@ const formData = ref({
}) })
const formRules = reactive({ const formRules = reactive({
taskId: [{required: true, message: '任务单不能为空', trigger: 'blur'}], taskId: [{required: true, message: t('ProductionPlan.Task.validatorPlanTaskIdRequired'), trigger: 'blur'}],
productsOfPlan: [{required: true, message: '单个计划生产数量不能为空', trigger: 'blur'}], productsOfPlan: [{required: true, message: t('ProductionPlan.Task.validatorPlanProductsOfPlanRequired'), trigger: 'blur'}],
}) })
const formRef = ref() // Ref const formRef = ref() // Ref
@ -114,7 +114,7 @@ const planFormRef = ref()
/** 打开弹窗 */ /** 打开弹窗 */
const open = async (taskId: number, taskDetailId: number, productId: number, productName:string, num:number,finishNumber:number) => { const open = async (taskId: number, taskDetailId: number, productId: number, productName:string, num:number,finishNumber:number) => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = "产品排产:" + productName dialogTitle.value = t('ProductionPlan.Task.planDialogTitlePrefix') + productName
formData.value.taskId = taskId formData.value.taskId = taskId
formData.value.taskDetailId = taskDetailId formData.value.taskDetailId = taskDetailId
formData.value.taskCode = productName formData.value.taskCode = productName
@ -151,7 +151,7 @@ const submitForm = async () => {
// //
emit('success') emit('success')
} }
else message.alert("请勿提交空计划!") else message.alert(t('ProductionPlan.Task.planDialogEmptyPlanMessage'))
} finally { } finally {
formLoading.value = false formLoading.value = false
} }

@ -8,15 +8,15 @@
:inline-message="true" :inline-message="true"
> >
<el-table :data="formData" class="-mt-10px" :show-overflow-tooltip="true" highlight-current-row> <el-table :data="formData" class="-mt-10px" :show-overflow-tooltip="true" highlight-current-row>
<el-table-column label="序号" type="index" width="80" /> <el-table-column :label="t('ProductionPlan.Task.saleDetailTableIndexColumn')" type="index" width="80" />
<el-table-column label="产品" min-width="150"> <el-table-column :label="t('ProductionPlan.Task.saleDetailTableProductColumn')" min-width="150">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.productId`" :rules="formRules.productId" class="mb-0px!"> <el-form-item :prop="`${$index}.productId`" :rules="formRules.productId" class="mb-0px!">
<el-select <el-select
v-model="row.productId" v-model="row.productId"
clearable clearable
filterable filterable
placeholder="请选择" :placeholder="t('ProductionPlan.Task.saleDetailProductPlaceholder')"
> >
<el-option <el-option
v-for="item in productList" v-for="item in productList"
@ -28,7 +28,7 @@
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="单位" min-width="100"> <el-table-column :label="t('ProductionPlan.Task.saleDetailTableUnitColumn')" min-width="100">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.unitId`" :rules="formRules.unitId" class="mb-0px!"> <el-form-item :prop="`${$index}.unitId`" :rules="formRules.unitId" class="mb-0px!">
<el-select v-model="row.unitId" clearable filterable placeholder="" class="w-1/1"> <el-select v-model="row.unitId" clearable filterable placeholder="" class="w-1/1">
@ -43,49 +43,49 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="数量" min-width="180"> <el-table-column :label="t('ProductionPlan.Task.saleDetailTableNumberColumn')" min-width="180">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.number`" :rules="formRules.number" class="mb-0px!"> <el-form-item :prop="`${$index}.number`" :rules="formRules.number" class="mb-0px!">
<el-input-number v-model="row.number" :min="0" class="!w-1/1" /> <el-input-number v-model="row.number" :min="0" class="!w-1/1" />
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="每包/个" min-width="150"> <el-table-column :label="t('ProductionPlan.Task.saleDetailTablePackageSizeColumn')" min-width="150">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.packageSize`" :rules="formRules.packageSize" class="mb-0px!"> <el-form-item :prop="`${$index}.packageSize`" :rules="formRules.packageSize" class="mb-0px!">
<el-input-number v-model="row.packageSize" :min="0" class="!w-1/1" /> <el-input-number v-model="row.packageSize" :min="0" class="!w-1/1" />
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="打包数量" min-width="150"> <el-table-column :label="t('ProductionPlan.Task.saleDetailTablePackageNumberColumn')" min-width="150">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.packageNumber`" :rules="formRules.packageNumber" class="mb-0px!"> <el-form-item :prop="`${$index}.packageNumber`" :rules="formRules.packageNumber" class="mb-0px!">
<el-input-number v-model="row.packageNumber" :min="0" class="!w-1/1" /> <el-input-number v-model="row.packageNumber" :min="0" class="!w-1/1" />
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="项目名称" min-width="100"> <el-table-column :label="t('ProductionPlan.Task.saleDetailTableProjectNameColumn')" min-width="100">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.projectName`" :rules="formRules.projectName" class="mb-0px!"> <el-form-item :prop="`${$index}.projectName`" :rules="formRules.projectName" class="mb-0px!">
<el-input v-model="row.projectName" placeholder="" /> <el-input v-model="row.projectName" placeholder="" />
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="技术要求" min-width="150"> <el-table-column :label="t('ProductionPlan.Task.saleDetailTableTechRequirementsColumn')" min-width="150">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.techRequirements`" :rules="formRules.techRequirements" class="mb-0px!"> <el-form-item :prop="`${$index}.techRequirements`" :rules="formRules.techRequirements" class="mb-0px!">
<el-input v-model="row.techRequirements" placeholder="" /> <el-input v-model="row.techRequirements" placeholder="" />
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="备注" min-width="150"> <el-table-column :label="t('ProductionPlan.Task.saleDetailTableRemarkColumn')" min-width="150">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.remark`" :rules="formRules.remark" class="mb-0px!"> <el-form-item :prop="`${$index}.remark`" :rules="formRules.remark" class="mb-0px!">
<el-input v-model="row.remark" placeholder="" /> <el-input v-model="row.remark" placeholder="" />
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="工厂完成" min-width="150"> <el-table-column :label="t('ProductionPlan.Task.saleDetailTableFinishDateColumn')" min-width="150">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.finishDate`" :rules="formRules.finishDate" class="mb-0px!"> <el-form-item :prop="`${$index}.finishDate`" :rules="formRules.finishDate" class="mb-0px!">
<el-date-picker <el-date-picker
@ -97,7 +97,7 @@
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="装柜时间" min-width="150"> <el-table-column :label="t('ProductionPlan.Task.saleDetailTableBoxingDateColumn')" min-width="150">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.boxingDate`" :rules="formRules.boxingDate" class="mb-0px!"> <el-form-item :prop="`${$index}.boxingDate`" :rules="formRules.boxingDate" class="mb-0px!">
<el-date-picker <el-date-picker
@ -109,7 +109,7 @@
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="到达时间" min-width="150"> <el-table-column :label="t('ProductionPlan.Task.saleDetailTableArriveDateColumn')" min-width="150">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.arriveDate`" :rules="formRules.arriveDate" class="mb-0px!"> <el-form-item :prop="`${$index}.arriveDate`" :rules="formRules.arriveDate" class="mb-0px!">
<el-date-picker <el-date-picker
@ -121,7 +121,7 @@
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="条码" min-width="150"> <el-table-column :label="t('ProductionPlan.Task.saleDetailTableBarCodeColumn')" min-width="150">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.barCode`" :rules="formRules.barCode" class="mb-0px!"> <el-form-item :prop="`${$index}.barCode`" :rules="formRules.barCode" class="mb-0px!">
<el-input v-model="row.barCode" placeholder="" /> <el-input v-model="row.barCode" placeholder="" />
@ -129,7 +129,7 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" fixed="right" label="操作" width="60"> <el-table-column align="center" fixed="right" :label="t('ProductionPlan.Task.saleDetailTableOperateColumn')" width="60">
<template #default="{ $index }"> <template #default="{ $index }">
<el-button type="danger" @click="handleDelete($index)" link> <el-button type="danger" @click="handleDelete($index)" link>
<Icon icon="ep:delete" /> <Icon icon="ep:delete" />
@ -139,8 +139,8 @@
</el-table> </el-table>
</el-form> </el-form>
<el-row justify="center" class="mt-3"> <el-row justify="center" class="mt-3">
<el-button @click="handleAdd" round>+ 添加任务单明细</el-button> <el-button @click="handleAdd" round>{{ t('ProductionPlan.Task.saleDetailAddRowButtonText') }}</el-button>
<el-button @click="openOrderItemsList" round>+ 从销售单添加</el-button> <el-button @click="openOrderItemsList" round>{{ t('ProductionPlan.Task.saleDetailAddFromOrderButtonText') }}</el-button>
</el-row> </el-row>
<el-row> <el-row>
<SaleOrderIndex ref="orderItemsRef" @success="dealOrder"/> <SaleOrderIndex ref="orderItemsRef" @success="dealOrder"/>
@ -156,16 +156,18 @@ import {SaleOrderApi, SaleOrderItemsVO, SaleOrderVO} from "@/api/mes/saleorder";
const unitList = ref<ProductUnitVO[]>([]) // const unitList = ref<ProductUnitVO[]>([]) //
const productList = ref<ProductVO[]>([]) // const productList = ref<ProductVO[]>([]) //
const { t } = useI18n()
const props = defineProps<{ const props = defineProps<{
taskId?: undefined // task ID taskId?: undefined // task ID
}>() }>()
const formLoading = ref(false) // const formLoading = ref(false) //
const formData = ref([]) const formData = ref([])
const formRules = reactive({ const formRules = reactive({
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }], productId: [{ required: true, message: t('ProductionPlan.Task.validatorRowProductRequired'), trigger: 'blur' }],
unitId: [{ required: true, message: '单位不能为空', trigger: 'blur' }], unitId: [{ required: true, message: t('ProductionPlan.Task.validatorRowUnitRequired'), trigger: 'blur' }],
taskId: [{ required: true, message: '生产任务不能为空', trigger: 'blur' }], taskId: [{ required: true, message: t('ProductionPlan.Task.validatorRowTaskRequired'), trigger: 'blur' }],
number: [{ required: true, message: '数量不能为空', trigger: 'blur' }], number: [{ required: true, message: t('ProductionPlan.Task.validatorRowNumberRequired'), trigger: 'blur' }],
}) })
const formRef = ref() // Ref const formRef = ref() // Ref

@ -10,13 +10,13 @@
> >
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="产品" prop="productId"> <el-form-item :label="t('ProductionPlan.Task.detailDialogProductLabel')" prop="productId">
<el-select <el-select
v-model="formData.productId" v-model="formData.productId"
clearable clearable
filterable filterable
@change="onChangeProduct(formData.productId)" @change="onChangeProduct(formData.productId)"
placeholder="请选择产品" :placeholder="t('ProductionPlan.Task.detailDialogProductPlaceholder')"
> >
<el-option <el-option
v-for="item in productList" v-for="item in productList"
@ -28,44 +28,44 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="单位" prop="unitName"> <el-form-item :label="t('ProductionPlan.Task.detailDialogUnitLabel')" prop="unitName">
<el-input v-model="formData.unitName" disabled/> <el-input v-model="formData.unitName" disabled/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="数量" prop="number"> <el-form-item :label="t('ProductionPlan.Task.detailDialogNumberLabel')" prop="number">
<el-input-number <el-input-number
v-model="formData.number" v-model="formData.number"
:min="0" :min="0"
class="!w-1/1" class="!w-1/1"
placeholder="请输入数量" :placeholder="t('ProductionPlan.Task.detailDialogNumberPlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="项目" prop="projectName"> <el-form-item :label="t('ProductionPlan.Task.detailDialogProjectLabel')" prop="projectName">
<el-input v-model="formData.projectName" placeholder="请输入项目名称" /> <el-input v-model="formData.projectName" :placeholder="t('ProductionPlan.Task.detailDialogProjectPlaceholder')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="每包数量" prop="packageSize"> <el-form-item :label="t('ProductionPlan.Task.detailDialogPackageSizeLabel')" prop="packageSize">
<el-input-number <el-input-number
v-model="formData.packageSize" v-model="formData.packageSize"
:min="0" :min="0"
class="!w-1/1" class="!w-1/1"
placeholder="请输入打包要求" :placeholder="t('ProductionPlan.Task.detailDialogPackageSizePlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="打包数量" prop="packageNumber"> <el-form-item :label="t('ProductionPlan.Task.detailDialogPackageNumberLabel')" prop="packageNumber">
<el-input-number <el-input-number
v-model="formData.packageNumber" v-model="formData.packageNumber"
:min="0" :min="0"
class="!w-1/1" class="!w-1/1"
placeholder="请输入数量" :placeholder="t('ProductionPlan.Task.detailDialogPackageNumberPlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -77,53 +77,53 @@
</el-form-item> </el-form-item>
</el-col> --> </el-col> -->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="技术要求" prop="techRequirements"> <el-form-item :label="t('ProductionPlan.Task.detailDialogTechRequirementsLabel')" prop="techRequirements">
<el-input v-model="formData.techRequirements" placeholder="请输入技术要求" /> <el-input v-model="formData.techRequirements" :placeholder="t('ProductionPlan.Task.detailDialogTechRequirementsPlaceholder')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="交货日期" prop="finishDate"> <el-form-item :label="t('ProductionPlan.Task.detailFormDeliveryDateLabel')" prop="finishDate">
<el-date-picker <el-date-picker
v-model="formData.finishDate" v-model="formData.finishDate"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择交货日期" :placeholder="t('ProductionPlan.Task.detailFormDeliveryDatePlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="装柜日期" prop="boxingDate"> <el-form-item :label="t('ProductionPlan.Task.detailDialogBoxingDateLabel')" prop="boxingDate">
<el-date-picker <el-date-picker
v-model="formData.boxingDate" v-model="formData.boxingDate"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择装柜日期" :placeholder="t('ProductionPlan.Task.detailDialogBoxingDatePlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="到达日期" prop="arriveDate"> <el-form-item :label="t('ProductionPlan.Task.detailDialogArriveDateLabel')" prop="arriveDate">
<el-date-picker <el-date-picker
v-model="formData.arriveDate" v-model="formData.arriveDate"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择到达日期" :placeholder="t('ProductionPlan.Task.detailDialogArriveDatePlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-form-item label="备注" prop="remark"> <el-form-item :label="t('ProductionPlan.Task.detailDialogRemarkLabel')" prop="remark">
<Editor disabled="disabled" v-model="formData.remark" height="500px" /> <Editor disabled="disabled" v-model="formData.remark" height="500px" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('ProductionPlan.Task.detailDialogSubmitButtonText') }}</el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.Task.detailDialogCancelButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -159,11 +159,11 @@ const formData = ref({
arriveDate: undefined, arriveDate: undefined,
}) })
const formRules = reactive({ const formRules = reactive({
productId: [{ required: true, message: '产品ID不能为空', trigger: 'blur' }], productId: [{ required: true, message: t('ProductionPlan.Task.validatorDetailProductIdRequired'), trigger: 'blur' }],
unitId: [{ required: true, message: '单位ID不能为空', trigger: 'blur' }], unitId: [{ required: true, message: t('ProductionPlan.Task.validatorDetailUnitIdRequired'), trigger: 'blur' }],
taskId: [{ required: true, message: 'task ID不能为空', trigger: 'blur' }], taskId: [{ required: true, message: t('ProductionPlan.Task.validatorDetailTaskIdRequired'), trigger: 'blur' }],
number: [{ required: true, message: '数量不能为空', trigger: 'blur' }], number: [{ required: true, message: t('ProductionPlan.Task.validatorDetailNumberRequired'), trigger: 'blur' }],
packageSize: [{ required: true, message: '打包要求(每包/个)不能为空', trigger: 'blur' }] packageSize: [{ required: true, message: t('ProductionPlan.Task.validatorDetailPackageSizeRequired'), trigger: 'blur' }]
}) })
const formRef = ref() // Ref const formRef = ref() // Ref

@ -7,33 +7,33 @@
@click="openForm('create')" @click="openForm('create')"
v-hasPermi="['mes:task:create']" v-hasPermi="['mes:task:create']"
> >
<Icon icon="ep:plus" class="mr-5px" /> 新增 <Icon icon="ep:plus" class="mr-5px" /> {{ t('ProductionPlan.Task.detailListCreateButtonText') }}
</el-button> </el-button>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="产品编码" prop="barCode"/> <el-table-column :label="t('ProductionPlan.Task.detailListProductCodeColumn')" prop="barCode"/>
<el-table-column label="产品名称" prop="productName" sortable/> <el-table-column :label="t('ProductionPlan.Task.detailListProductNameColumn')" prop="productName" sortable/>
<el-table-column label="单位" align="center" prop="unitName" /> <el-table-column :label="t('ProductionPlan.Task.detailListUnitColumn')" align="center" prop="unitName" />
<el-table-column label="数量" align="center" prop="number" /> <el-table-column :label="t('ProductionPlan.Task.detailListNumberColumn')" align="center" prop="number" />
<el-table-column label="已计划" align="center" prop="planNumber" /> <el-table-column :label="t('ProductionPlan.Task.detailListPlanNumberColumn')" align="center" prop="planNumber" />
<!-- <el-table-column label="每包/个" align="center" prop="packageSize" />--> <!-- <el-table-column :label="t('ProductionPlan.Task.detailListPackageSizeColumn')" align="center" prop="packageSize" />-->
<el-table-column label="交货日期" align="center" prop="finishDate" :formatter="dateFormatter2"/> <el-table-column :label="t('ProductionPlan.Task.detailListFinishDateColumn')" align="center" prop="finishDate" :formatter="dateFormatter2"/>
<!-- <el-table-column label="项目名称" align="center" prop="projectName" /> --> <!-- <el-table-column label="项目名称" align="center" prop="projectName" /> -->
<el-table-column label="技术要求" align="center" prop="techRequirements" /> <el-table-column :label="t('ProductionPlan.Task.detailListTechRequirementsColumn')" align="center" prop="techRequirements" />
<el-table-column label="操作" align="center" width="300px"> <el-table-column :label="t('ProductionPlan.Task.detailListOperateColumn')" align="center" width="300px">
<template #default="scope"> <template #default="scope">
<el-button <el-button
link link
@click="openFormView('detail', scope.row.id)" @click="openFormView('detail', scope.row.id)"
> >
详情 {{ t('ProductionPlan.Task.detailListViewActionText') }}
</el-button> </el-button>
<el-button <el-button
link link
type="info" type="info"
@click="openItemNeed(scope.row.productName, scope.row.productId, scope.row.number)" @click="openItemNeed(scope.row.productName, scope.row.productId, scope.row.number)"
> >
物料 {{ t('ProductionPlan.Task.detailListMaterialActionText') }}
</el-button> </el-button>
<!-- <el-button <!-- <el-button
link link
@ -58,7 +58,7 @@
@click="openForm('update', scope.row.id)" @click="openForm('update', scope.row.id)"
v-hasPermi="['mes:task:update']" v-hasPermi="['mes:task:update']"
> >
编辑 {{ t('ProductionPlan.Task.detailListEditActionText') }}
</el-button> </el-button>
<el-button <el-button
link link
@ -66,7 +66,7 @@
@click="handleDelete(scope.row.id)" @click="handleDelete(scope.row.id)"
v-hasPermi="['mes:task:delete']" v-hasPermi="['mes:task:delete']"
> >
删除 {{ t('ProductionPlan.Task.detailListDeleteActionText') }}
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -153,7 +153,7 @@ const handleQuery = () => {
const formRef = ref() const formRef = ref()
const openForm = (type: string, id?: number) => { const openForm = (type: string, id?: number) => {
if (!props.taskId) { if (!props.taskId) {
message.error('请选择一个生产任务单') message.error(t('ProductionPlan.Task.selectTaskTip'))
return return
} }
formRef.value.open(type, id, props.taskId) formRef.value.open(type, id, props.taskId)
@ -191,7 +191,7 @@ const openItemNeed = (productName:string, productId: number, number:number) => {
const planFormRef = ref() const planFormRef = ref()
const addPlanForm = (taskId: number,taskDetailId: number, productId: number, number?: number) => { const addPlanForm = (taskId: number,taskDetailId: number, productId: number, number?: number) => {
if (!props.taskId) { if (!props.taskId) {
message.error('请选择一个生产任务单') message.error(t('ProductionPlan.Task.selectTaskTip'))
return return
} }
planFormRef.value.open("create",null,taskId, productId, number, taskDetailId) planFormRef.value.open("create",null,taskId, productId, number, taskDetailId)

@ -10,12 +10,12 @@
> >
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="产品" prop="productId"> <el-form-item :label="t('ProductionPlan.Task.detailDialogProductLabel')" prop="productId">
<el-select <el-select
v-model="formData.productId" v-model="formData.productId"
clearable clearable
filterable filterable
placeholder="请选择产品" :placeholder="t('ProductionPlan.Task.detailDialogProductPlaceholder')"
> >
<el-option <el-option
v-for="item in productList" v-for="item in productList"
@ -27,13 +27,13 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="单位" prop="unitId"> <el-form-item :label="t('ProductionPlan.Task.detailDialogUnitLabel')" prop="unitId">
<el-select <el-select
disabled disabled
v-model="formData.unitId" v-model="formData.unitId"
clearable clearable
filterable filterable
placeholder="请选择产品" :placeholder="t('ProductionPlan.Task.detailDialogUnitPlaceholder')"
> >
<el-option <el-option
v-for="item in unitList" v-for="item in unitList"
@ -45,39 +45,39 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="数量" prop="number"> <el-form-item :label="t('ProductionPlan.Task.detailDialogNumberLabel')" prop="number">
<el-input-number <el-input-number
v-model="formData.number" v-model="formData.number"
:min="0" :min="0"
class="!w-1/1" class="!w-1/1"
placeholder="请输入数量" :placeholder="t('ProductionPlan.Task.detailDialogNumberPlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="项目" prop="projectName"> <el-form-item :label="t('ProductionPlan.Task.detailDialogProjectLabel')" prop="projectName">
<el-input v-model="formData.projectName" placeholder="请输入项目名称" /> <el-input v-model="formData.projectName" :placeholder="t('ProductionPlan.Task.detailDialogProjectPlaceholder')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="每包数量" prop="packageSize"> <el-form-item :label="t('ProductionPlan.Task.detailDialogPackageSizeLabel')" prop="packageSize">
<el-input-number <el-input-number
v-model="formData.packageSize" v-model="formData.packageSize"
:min="0" :min="0"
class="!w-1/1" class="!w-1/1"
placeholder="请输入打包要求" :placeholder="t('ProductionPlan.Task.detailDialogPackageSizePlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="打包数量" prop="packageNumber"> <el-form-item :label="t('ProductionPlan.Task.detailDialogPackageNumberLabel')" prop="packageNumber">
<el-input-number <el-input-number
v-model="formData.packageNumber" v-model="formData.packageNumber"
:min="0" :min="0"
class="!w-1/1" class="!w-1/1"
placeholder="请输入数量" :placeholder="t('ProductionPlan.Task.detailDialogPackageNumberPlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -89,52 +89,52 @@
</el-form-item> </el-form-item>
</el-col> --> </el-col> -->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="技术要求" prop="techRequirements"> <el-form-item :label="t('ProductionPlan.Task.detailDialogTechRequirementsLabel')" prop="techRequirements">
<el-input v-model="formData.techRequirements" placeholder="请输入技术要求" /> <el-input v-model="formData.techRequirements" :placeholder="t('ProductionPlan.Task.detailDialogTechRequirementsPlaceholder')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="工厂完成" prop="finishDate"> <el-form-item :label="t('ProductionPlan.Task.detailDialogFinishDateLabel')" prop="finishDate">
<el-date-picker <el-date-picker
v-model="formData.finishDate" v-model="formData.finishDate"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择工厂完成日期" :placeholder="t('ProductionPlan.Task.detailDialogFinishDatePlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="装柜日期" prop="boxingDate"> <el-form-item :label="t('ProductionPlan.Task.detailDialogBoxingDateLabel')" prop="boxingDate">
<el-date-picker <el-date-picker
v-model="formData.boxingDate" v-model="formData.boxingDate"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择装柜日期" :placeholder="t('ProductionPlan.Task.detailDialogBoxingDatePlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="到达日期" prop="arriveDate"> <el-form-item :label="t('ProductionPlan.Task.detailDialogArriveDateLabel')" prop="arriveDate">
<el-date-picker <el-date-picker
v-model="formData.arriveDate" v-model="formData.arriveDate"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择到达日期" :placeholder="t('ProductionPlan.Task.detailDialogArriveDatePlaceholder')"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<div> <div>
<label>备注</label> <label>{{ t('ProductionPlan.Task.detailDialogRemarkLabel') }}</label>
<div v-html="formData.remark"></div> <div v-html="formData.remark"></div>
</div> </div>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('ProductionPlan.Task.detailDialogSubmitButtonText') }}</el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.Task.detailDialogCancelButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -169,11 +169,11 @@ const formData = ref({
arriveDate: undefined, arriveDate: undefined,
}) })
const formRules = reactive({ const formRules = reactive({
productId: [{ required: true, message: '产品ID不能为空', trigger: 'blur' }], productId: [{ required: true, message: t('ProductionPlan.Task.validatorDetailProductIdRequired'), trigger: 'blur' }],
unitId: [{ required: true, message: '单位ID不能为空', trigger: 'blur' }], unitId: [{ required: true, message: t('ProductionPlan.Task.validatorDetailUnitIdRequired'), trigger: 'blur' }],
taskId: [{ required: true, message: 'task ID不能为空', trigger: 'blur' }], taskId: [{ required: true, message: t('ProductionPlan.Task.validatorDetailTaskIdRequired'), trigger: 'blur' }],
number: [{ required: true, message: '数量不能为空', trigger: 'blur' }], number: [{ required: true, message: t('ProductionPlan.Task.validatorDetailNumberRequired'), trigger: 'blur' }],
packageSize: [{ required: true, message: '打包要求(每包/个)不能为空', trigger: 'blur' }] packageSize: [{ required: true, message: t('ProductionPlan.Task.validatorDetailPackageSizeRequired'), trigger: 'blur' }]
}) })
const formRef = ref() // Ref const formRef = ref() // Ref

@ -2,77 +2,77 @@
<ContentWrap> <ContentWrap>
<!-- 搜索工作栏 --> <!-- 搜索工作栏 -->
<el-form <el-form
class="-mb-15px" class="-mb-15px task-search-form"
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px" label-width="auto"
> >
<el-form-item label="编码" prop="code"> <el-form-item :label="t('ProductionPlan.Task.searchCodeLabel')" prop="code">
<el-input <el-input
v-model="queryParams.code" v-model="queryParams.code"
placeholder="请输入编码" :placeholder="t('ProductionPlan.Task.searchCodePlaceholder')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
class="!w-180px" class="!w-180px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="下达" prop="orderDate"> <el-form-item :label="t('ProductionPlan.Task.searchOrderLabel')" prop="orderDate">
<el-date-picker <el-date-picker
v-model="queryParams.orderDate" v-model="queryParams.orderDate"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
@change="handleQuery" @change="handleQuery"
type="daterange" type="daterange"
start-placeholder="开始日期" :start-placeholder="t('ProductionPlan.Task.searchOrderStartPlaceholder')"
end-placeholder="结束日期" :end-placeholder="t('ProductionPlan.Task.searchOrderEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-180px" class="!w-180px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="交货" prop="deliveryDate"> <el-form-item :label="t('ProductionPlan.Task.searchDeliveryLabel')" prop="deliveryDate">
<el-date-picker <el-date-picker
v-model="queryParams.deliveryDate" v-model="queryParams.deliveryDate"
@change="handleQuery" @change="handleQuery"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" type="daterange"
start-placeholder="开始日期" :start-placeholder="t('ProductionPlan.Task.searchDeliveryStartPlaceholder')"
end-placeholder="结束日期" :end-placeholder="t('ProductionPlan.Task.searchDeliveryEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-180px" class="!w-180px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item :label="t('ProductionPlan.Task.searchRemarkLabel')" prop="remark">
<el-input <el-input
v-model="queryParams.remark" v-model="queryParams.remark"
placeholder="请输入备注" :placeholder="t('ProductionPlan.Task.searchRemarkPlaceholder')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
class="!w-180px" class="!w-180px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="创建时间" prop="createTime"> <el-form-item :label="t('ProductionPlan.Task.searchCreateTimeLabel')" prop="createTime">
<el-date-picker <el-date-picker
v-model="queryParams.createTime" v-model="queryParams.createTime"
@change="handleQuery" @change="handleQuery"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" type="daterange"
start-placeholder="开始日期" :start-placeholder="t('ProductionPlan.Task.searchCreateTimeStartPlaceholder')"
end-placeholder="结束日期" :end-placeholder="t('ProductionPlan.Task.searchCreateTimeEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> {{ t('ProductionPlan.Task.buttonSearchText') }}</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> {{ t('ProductionPlan.Task.buttonResetText') }}</el-button>
<el-button <el-button
type="primary" type="primary"
plain plain
@click="openForm('create')" @click="openForm('create')"
v-hasPermi="['mes:task:create']" v-hasPermi="['mes:task:create']"
> >
<Icon icon="ep:plus" class="mr-5px" /> 新增 <Icon icon="ep:plus" class="mr-5px" /> {{ t('ProductionPlan.Task.buttonCreateText') }}
</el-button> </el-button>
<el-button <el-button
type="success" type="success"
@ -81,7 +81,7 @@
:loading="exportLoading" :loading="exportLoading"
v-hasPermi="['mes:task:export']" v-hasPermi="['mes:task:export']"
> >
<Icon icon="ep:download" class="mr-5px" /> 导出 <Icon icon="ep:download" class="mr-5px" /> {{ t('ProductionPlan.Task.buttonExportText') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -90,14 +90,14 @@
<!-- 列表 --> <!-- 列表 -->
<ContentWrap> <ContentWrap>
<el-tabs v-model="activeName" @tab-click="handleTabClick"> <el-tabs v-model="activeName" @tab-click="handleTabClick">
<el-tab-pane label="所有" name="" /> <el-tab-pane :label="t('ProductionPlan.Task.tabAllLabel')" name="" />
<el-tab-pane label="草稿" name="0" /> <el-tab-pane :label="t('ProductionPlan.Task.tabDraftLabel')" name="0" />
<el-tab-pane label="送审" name="1" /> <el-tab-pane :label="t('ProductionPlan.Task.tabSubmitLabel')" name="1" />
<el-tab-pane label="下达" name="2" /> <el-tab-pane :label="t('ProductionPlan.Task.tabIssuedLabel')" name="2" />
<el-tab-pane label="计划" name="3" /> <el-tab-pane :label="t('ProductionPlan.Task.tabPlanLabel')" name="3" />
<el-tab-pane label="开工" name="4" /> <el-tab-pane :label="t('ProductionPlan.Task.tabStartLabel')" name="4" />
<el-tab-pane label="完工" name="5" /> <el-tab-pane :label="t('ProductionPlan.Task.tabFinishedLabel')" name="5" />
<el-tab-pane label="入库" name="6" /> <el-tab-pane :label="t('ProductionPlan.Task.tabStoredLabel')" name="6" />
</el-tabs> </el-tabs>
<el-table <el-table
v-loading="loading" v-loading="loading"
@ -107,41 +107,41 @@
highlight-current-row highlight-current-row
@current-change="handleCurrentChange" @current-change="handleCurrentChange"
> >
<el-table-column label="编码" align="center" prop="code" width="150px"/> <el-table-column :label="t('ProductionPlan.Task.tableCodeColumn')" align="center" prop="code" width="150px"/>
<el-table-column label="下达日期" align="center" prop="orderDate" :formatter="dateFormatter2" /> <el-table-column :label="t('ProductionPlan.Task.tableOrderDateColumn')" align="center" prop="orderDate" :formatter="dateFormatter2" />
<el-table-column label="交货日期" align="center" prop="deliveryDate" :formatter="dateFormatter2"/> <el-table-column :label="t('ProductionPlan.Task.tableDeliveryDateColumn')" align="center" prop="deliveryDate" :formatter="dateFormatter2"/>
<el-table-column label="类型" align="center" prop="taskType"> <el-table-column :label="t('ProductionPlan.Task.tableTaskTypeColumn')" align="center" prop="taskType">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.MES_TASK_TYPE" :value="scope.row.taskType" /> <dict-tag :type="DICT_TYPE.MES_TASK_TYPE" :value="scope.row.taskType" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="状态" align="center" prop="status"> <el-table-column :label="t('ProductionPlan.Task.tableStatusColumn')" align="center" prop="status">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.MES_TASK_STATUS" :value="scope.row.status" /> <dict-tag :type="DICT_TYPE.MES_TASK_STATUS" :value="scope.row.status" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column :label="t('ProductionPlan.Task.tableRemarkColumn')" align="center" prop="remark" />
<el-table-column label="操作" align="center" min-width="200px"> <el-table-column :label="t('ProductionPlan.Task.tableOperateColumn')" align="center" min-width="200px">
<template #default="scope"> <template #default="scope">
<el-button v-if="scope.row.status==0" link type="primary" @click="changeStatus('送审',1, scope.row.id)" v-hasPermi="['mes:task:update']"> <el-button v-if="scope.row.status==0" link type="primary" @click="changeStatus(t('ProductionPlan.Task.actionSubmitLabel'),1, scope.row.id)" v-hasPermi="['mes:task:update']">
送审 {{ t('ProductionPlan.Task.actionSubmitLabel') }}
</el-button> </el-button>
<el-button v-if="scope.row.status==1" link type="primary" @click="changeStatus('审核',2, scope.row.id)" v-hasPermi="['mes:task:approve']"> <el-button v-if="scope.row.status==1" link type="primary" @click="changeStatus(t('ProductionPlan.Task.actionApproveLabel'),2, scope.row.id)" v-hasPermi="['mes:task:approve']">
审核 {{ t('ProductionPlan.Task.actionApproveLabel') }}
</el-button> </el-button>
<el-button link type="info" @click="openItemNeed(scope.row.code, scope.row.id)" v-hasPermi="['mes:task:update']"> <el-button link type="info" @click="openItemNeed(scope.row.code, scope.row.id)" v-hasPermi="['mes:task:update']">
物料 {{ t('ProductionPlan.Task.actionMaterialLabel') }}
</el-button> </el-button>
<!-- 下达后不可更改--> <!-- 下达后不可更改-->
<!-- <el-button v-if="scope.row.status<2" link type="success" @click="openSaleForm(scope.row.id)" v-hasPermi="['mes:task:update']"> <!-- <el-button v-if="scope.row.status<2" link type="success" @click="openSaleForm(scope.row.id)" v-hasPermi="['mes:task:update']">
销售单 销售单
</el-button> --> </el-button> -->
<el-button v-if="scope.row.status<2" link type="primary" @click="openForm('update', scope.row.id)" v-hasPermi="['mes:task:update']"> <el-button v-if="scope.row.status<2" link type="primary" @click="openForm('update', scope.row.id)" v-hasPermi="['mes:task:update']">
编辑 {{ t('ProductionPlan.Task.actionEditLabel') }}
</el-button> </el-button>
<el-button v-if="scope.row.status<2" link type="danger" @click="handleDelete(scope.row.id)" v-hasPermi="['mes:task:delete']"> <el-button v-if="scope.row.status<2" link type="danger" @click="handleDelete(scope.row.id)" v-hasPermi="['mes:task:delete']">
删除 {{ t('ProductionPlan.Task.actionDeleteLabel') }}
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -162,7 +162,7 @@
<!-- 子表的列表 --> <!-- 子表的列表 -->
<ContentWrap> <ContentWrap>
<el-tabs model-value="taskDetail" v-model="activeListName" @tab-click="handleListTabClick"> <el-tabs model-value="taskDetail" v-model="activeListName" @tab-click="handleListTabClick">
<el-tab-pane label="任务单明细" name="taskDetail"> <el-tab-pane :label="t('ProductionPlan.Task.detailTabTaskDetailLabel')" name="taskDetail">
<TaskDetailList v-if="activeListName ==='taskDetail'" :task-id="currentRow.id" :task-status="currentRow.status"/> <TaskDetailList v-if="activeListName ==='taskDetail'" :task-id="currentRow.id" :task-status="currentRow.status"/>
</el-tab-pane> </el-tab-pane>
<!-- <el-tab-pane label="任务单明细进度" name="taskDetailProgress">--> <!-- <el-tab-pane label="任务单明细进度" name="taskDetailProgress">-->

@ -9,58 +9,58 @@
:default-sort="{ prop: 'sort_date', order: 'descending' }" :default-sort="{ prop: 'sort_date', order: 'descending' }"
> >
<el-table :data="formData" class="-mt-10px" :stripe="true" :show-overflow-tooltip="true"> <el-table :data="formData" class="-mt-10px" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="序号" type="index" width="60" /> <el-table-column :label="t('ProductionPlan.TaskSummary.planFormIndexColumn')" type="index" width="60" />
<el-table-column disabled label="计划编码" min-width="170"> <el-table-column disabled :label="t('ProductionPlan.TaskSummary.planFormCodeColumn')" min-width="170">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.code`" :rules="formRules.code" class="mb-0px!"> <el-form-item :prop="`${$index}.code`" :rules="formRules.code" class="mb-0px!">
<el-input disabled v-model="row.code" placeholder="请输入计划编码" /> <el-input disabled v-model="row.code" :placeholder="t('ProductionPlan.TaskSummary.planFormCodePlaceholder')" />
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column disabled="true" label="产品" min-width="150"> <el-table-column disabled="true" :label="t('ProductionPlan.TaskSummary.planFormProductColumn')" min-width="150">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item v-show="false" :prop="`${$index}.productId`" :rules="formRules.productId" class="mb-0px!"> <el-form-item v-show="false" :prop="`${$index}.productId`" :rules="formRules.productId" class="mb-0px!">
<el-input disabled v-model="row.productId" placeholder="请输入产品ID" /> <el-input disabled v-model="row.productId" :placeholder="t('ProductionPlan.TaskSummary.planFormProductIdPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :prop="`${$index}.productName`" :rules="formRules.productName" class="mb-0px!"> <el-form-item :prop="`${$index}.productName`" :rules="formRules.productName" class="mb-0px!">
<el-input disabled v-model="row.productName" placeholder="请输入产品" /> <el-input disabled v-model="row.productName" :placeholder="t('ProductionPlan.TaskSummary.planFormProductNamePlaceholder')" />
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="数量" min-width="120"> <el-table-column :label="t('ProductionPlan.TaskSummary.planFormPlanNumberColumn')" min-width="120">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.planNumber`" :rules="formRules.planNumber" class="mb-0px!"> <el-form-item :prop="`${$index}.planNumber`" :rules="formRules.planNumber" class="mb-0px!">
<el-input v-model="row.planNumber" placeholder="请输入数量" /> <el-input v-model="row.planNumber" :placeholder="t('ProductionPlan.TaskSummary.planFormPlanNumberPlaceholder')" />
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="sort_date" sortable label="计划开始时间" min-width="150"> <el-table-column prop="sort_date" sortable :label="t('ProductionPlan.TaskSummary.planFormPlanStartTimeColumn')" min-width="150">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.planStartTime`" :rules="formRules.planStartTime" class="mb-0px!"> <el-form-item :prop="`${$index}.planStartTime`" :rules="formRules.planStartTime" class="mb-0px!">
<el-date-picker <el-date-picker
v-model="row.planStartTime" v-model="row.planStartTime"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择计划开始时间" :placeholder="t('ProductionPlan.TaskSummary.planFormPlanStartTimePlaceholder')"
/> />
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="计划结束时间" min-width="150"> <el-table-column :label="t('ProductionPlan.TaskSummary.planFormPlanEndTimeColumn')" min-width="150">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.planEndTime`" :rules="formRules.planEndTime" class="mb-0px!"> <el-form-item :prop="`${$index}.planEndTime`" :rules="formRules.planEndTime" class="mb-0px!">
<el-date-picker <el-date-picker
v-model="row.planEndTime" v-model="row.planEndTime"
type="date" type="date"
value-format="x" value-format="x"
placeholder="选择计划结束时间" :placeholder="t('ProductionPlan.TaskSummary.planFormPlanEndTimePlaceholder')"
/> />
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="备注" min-width="150"> <el-table-column :label="t('ProductionPlan.TaskSummary.planFormRemarkColumn')" min-width="150">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.remark`" :rules="formRules.remark" class="mb-0px!"> <el-form-item :prop="`${$index}.remark`" :rules="formRules.remark" class="mb-0px!">
<el-input v-model="row.remark" placeholder="" /> <el-input v-model="row.remark" placeholder="" />
@ -68,7 +68,7 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" fixed="right" label="操作" width="100"> <el-table-column align="center" fixed="right" :label="t('ProductionPlan.TaskSummary.planFormOperateColumn')" width="100">
<template #default="{row, $index }"> <template #default="{row, $index }">
<el-button type="success" @click="handleCopy(row)" link> <el-button type="success" @click="handleCopy(row)" link>
<Icon icon="ep:document-copy" class="mr-5px"/> <Icon icon="ep:document-copy" class="mr-5px"/>
@ -91,12 +91,14 @@ const props = defineProps<{
}>() }>()
const formLoading = ref(false) // const formLoading = ref(false) //
const formData = ref([]) const formData = ref([])
const { t } = useI18n() //
const formRules = reactive({ const formRules = reactive({
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }], productId: [{ required: true, message: t('ProductionPlan.TaskSummary.validatorPlanFormProductIdRequired'), trigger: 'blur' }],
taskId: [{ required: true, message: '任务单不能为空', trigger: 'blur' }], taskId: [{ required: true, message: t('ProductionPlan.TaskSummary.validatorPlanFormTaskIdRequired'), trigger: 'blur' }],
planNumber: [{ required: true, message: '数量不能为空', trigger: 'blur' }], planNumber: [{ required: true, message: t('ProductionPlan.TaskSummary.validatorPlanFormPlanNumberRequired'), trigger: 'blur' }],
planStartTime: [{ required: true, message: '计划开始时间不能为空', trigger: 'blur' }], planStartTime: [{ required: true, message: t('ProductionPlan.TaskSummary.validatorPlanFormPlanStartTimeRequired'), trigger: 'blur' }],
planEndTime: [{ required: true, message: '计划结束时间不能为空', trigger: 'blur' }], planEndTime: [{ required: true, message: t('ProductionPlan.TaskSummary.validatorPlanFormPlanEndTimeRequired'), trigger: 'blur' }],
}) })
const formRef = ref() // Ref const formRef = ref() // Ref

@ -3,19 +3,19 @@
<!-- 列表 --> <!-- 列表 -->
<ContentWrap> <ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="任务单" align="center" prop="taskCode" /> <el-table-column :label="t('ProductionPlan.TaskSummary.detailTableTaskCodeColumn')" align="center" prop="taskCode" />
<el-table-column label="产品编码" align="center" prop="barCode" /> <el-table-column :label="t('ProductionPlan.TaskSummary.detailTableProductCodeColumn')" align="center" prop="barCode" />
<el-table-column label="产品名称" align="center" prop="productName" sortable/> <el-table-column :label="t('ProductionPlan.TaskSummary.detailTableProductNameColumn')" align="center" prop="productName" sortable/>
<el-table-column label="任务总数" align="center" prop="totalNumber" /> <el-table-column :label="t('ProductionPlan.TaskSummary.detailTableTotalNumberColumn')" align="center" prop="totalNumber" />
<el-table-column label="已计划" align="center" prop="planNumber" /> <el-table-column :label="t('ProductionPlan.TaskSummary.detailTablePlanNumberColumn')" align="center" prop="planNumber" />
<el-table-column label="未计划" align="center"> <el-table-column :label="t('ProductionPlan.TaskSummary.detailTableUnplanNumberColumn')" align="center">
<template #default="scope"> <template #default="scope">
<span class="el-alert--warning" style="color: #e66126"> <span class="el-alert--warning" style="color: #e66126">
{{scope.row.totalNumber-scope.row.planNumber>0 ? scope.row.totalNumber-scope.row.planNumber : 0}} {{scope.row.totalNumber-scope.row.planNumber>0 ? scope.row.totalNumber-scope.row.planNumber : 0}}
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" width="220px"> <el-table-column :label="t('ProductionPlan.TaskSummary.detailTableOperateColumn')" align="center" width="220px">
<template #default="scope"> <template #default="scope">
<el-button <el-button
link link
@ -24,7 +24,7 @@
scope.row.totalNumber-scope.row.planNumber)" scope.row.totalNumber-scope.row.planNumber)"
v-hasPermi="['mes:task:query']" v-hasPermi="['mes:task:query']"
> >
物料 {{ t('ProductionPlan.TaskSummary.detailActionMaterialLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
@ -32,7 +32,7 @@
@click="openPlan(scope.row.taskId, scope.row.productId)" @click="openPlan(scope.row.taskId, scope.row.productId)"
v-hasPermi="['mes:plan:query']" v-hasPermi="['mes:plan:query']"
> >
查看计划 {{ t('ProductionPlan.TaskSummary.detailActionViewPlanLabel') }}
</el-button> </el-button>
<el-button <el-button
link link
@ -41,7 +41,7 @@
scope.row.totalNumber - scope.row.planNumber,scope.row.taskDetailIds)" scope.row.totalNumber - scope.row.planNumber,scope.row.taskDetailIds)"
v-hasPermi="['mes:task:plan']" v-hasPermi="['mes:task:plan']"
> >
新增计划 {{ t('ProductionPlan.TaskSummary.detailActionCreatePlanLabel') }}
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -106,7 +106,7 @@ const handleQuery = () => {
const formRef = ref() const formRef = ref()
const addPlanForm = (taskId: number, productId: number, number?: number, taskDetailIds?: string) => { const addPlanForm = (taskId: number, productId: number, number?: number, taskDetailIds?: string) => {
if (!props.taskId) { if (!props.taskId) {
message.error('请选择一个生产任务单') message.error(t('ProductionPlan.TaskSummary.detailSelectTaskTip'))
return return
} }
formRef.value.open('create', undefined, taskId, productId, number,taskDetailIds) formRef.value.open('create', undefined, taskId, productId, number,taskDetailIds)

@ -8,20 +8,20 @@
> >
<el-row :gutter="20" v-show="false"> <el-row :gutter="20" v-show="false">
<el-col :span="6"> <el-col :span="6">
<el-form-item label="任务单" prop="taskId"> <el-form-item :label="t('ProductionPlan.TaskSummary.planDialogTaskIdLabel')" prop="taskId">
<el-input readonly v-model="formData.taskId" placeholder="请输入"/> <el-input readonly v-model="formData.taskId" :placeholder="t('ProductionPlan.TaskSummary.searchCodePlaceholder')"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="任务单" prop="taskCode"> <el-form-item :label="t('ProductionPlan.TaskSummary.planDialogTaskCodeLabel')" prop="taskCode">
<el-input readonly v-model="formData.taskCode" placeholder="请输入"/> <el-input readonly v-model="formData.taskCode" :placeholder="t('ProductionPlan.TaskSummary.searchCodePlaceholder')"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="6"> <el-col :span="6">
<el-form-item label="计划产量" prop="productsOfPlan"> <el-form-item :label="t('ProductionPlan.TaskSummary.planDialogProductsOfPlanLabel')" prop="productsOfPlan">
<el-input-number v-model="formData.productsOfPlan" :min="0" class="!w-1/1"/> <el-input-number v-model="formData.productsOfPlan" :min="0" class="!w-1/1"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -31,12 +31,12 @@
<!-- </el-form-item>--> <!-- </el-form-item>-->
<!-- </el-col>--> <!-- </el-col>-->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="日期" prop="planDate"> <el-form-item :label="t('ProductionPlan.TaskSummary.planDialogPlanDateLabel')" prop="planDate">
<el-date-picker <el-date-picker
v-model="formData.planDate" v-model="formData.planDate"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
type="dates" type="dates"
placeholder="请选择排产日期" :placeholder="t('ProductionPlan.TaskSummary.planDialogPlanDatePlaceholder')"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
@ -47,7 +47,7 @@
<el-form-item> <el-form-item>
<el-button type="success" @click="handleQuery"> <el-button type="success" @click="handleQuery">
<Icon icon="ep:calendar" class="mr-5px"/> <Icon icon="ep:calendar" class="mr-5px"/>
自动排产 {{ t('ProductionPlan.TaskSummary.planDialogAutoButtonText') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -55,7 +55,7 @@
<el-form-item> <el-form-item>
<el-button type="danger" @click="resetQuery"> <el-button type="danger" @click="resetQuery">
<Icon icon="ep:delete" class="mr-5px"/> <Icon icon="ep:delete" class="mr-5px"/>
清空结果 {{ t('ProductionPlan.TaskSummary.planDialogResetButtonText') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -63,16 +63,16 @@
</el-form> </el-form>
<!-- 子表的表单 --> <!-- 子表的表单 -->
<el-tabs v-model="subTabsName"> <el-tabs v-model="subTabsName">
<el-tab-pane label="预排产计划" name="plan"> <el-tab-pane :label="t('ProductionPlan.TaskSummary.planDialogTabPlanLabel')" name="plan">
<PlanForm ref="planFormRef" :task-id="formData.id"/> <PlanForm ref="planFormRef" :task-id="formData.id"/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="已排产计划" name="finishPlan"> <el-tab-pane :label="t('ProductionPlan.TaskSummary.planDialogTabFinishPlanLabel')" name="finishPlan">
<el-text>hello</el-text> <el-text>hello</el-text>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button> <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('ProductionPlan.TaskSummary.planDialogSubmitButtonText') }}</el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">{{ t('ProductionPlan.TaskSummary.planDialogCancelButtonText') }}</el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -100,8 +100,8 @@ const formData = ref({
}) })
const formRules = reactive({ const formRules = reactive({
taskId: [{required: true, message: '任务单不能为空', trigger: 'blur'}], taskId: [{required: true, message: t('ProductionPlan.TaskSummary.validatorPlanTaskIdRequired'), trigger: 'blur'}],
productsOfPlan: [{required: true, message: '单个计划生产数量不能为空', trigger: 'blur'}], productsOfPlan: [{required: true, message: t('ProductionPlan.TaskSummary.validatorPlanProductsOfPlanRequired'), trigger: 'blur'}],
}) })
const formRef = ref() // Ref const formRef = ref() // Ref
@ -113,7 +113,7 @@ const planFormRef = ref()
/** 打开弹窗 */ /** 打开弹窗 */
const open = async (taskCode: string, taskId: number) => { const open = async (taskCode: string, taskId: number) => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = "任务单排产:" + taskCode dialogTitle.value = t('ProductionPlan.TaskSummary.planDialogTitlePrefix') + taskCode
formData.value.taskId = taskId formData.value.taskId = taskId
formData.value.taskCode = taskCode formData.value.taskCode = taskCode
@ -146,7 +146,7 @@ const submitForm = async () => {
// //
emit('success') emit('success')
} }
else message.alert("请勿提交空计划!") else message.alert(t('ProductionPlan.TaskSummary.planDialogEmptyPlanMessage'))
} finally { } finally {
formLoading.value = false formLoading.value = false
} }

@ -6,65 +6,66 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="85px" label-width="auto"
label-position="left"
> >
<el-form-item label="任务单编码" prop="code"> <el-form-item :label="t('ProductionPlan.TaskSummary.searchCodeLabel')" prop="code">
<el-input <el-input
v-model="queryParams.code" v-model="queryParams.code"
placeholder="请输入编码" :placeholder="t('ProductionPlan.TaskSummary.searchCodePlaceholder')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="下达时间" prop="orderDate"> <el-form-item :label="t('ProductionPlan.TaskSummary.searchOrderLabel')" prop="orderDate">
<el-date-picker <el-date-picker
v-model="queryParams.orderDate" v-model="queryParams.orderDate"
@change="handleQuery" @change="handleQuery"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" type="daterange"
start-placeholder="开始日期" :start-placeholder="t('ProductionPlan.TaskSummary.searchOrderStartPlaceholder')"
end-placeholder="结束日期" :end-placeholder="t('ProductionPlan.TaskSummary.searchOrderEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="交货时间" prop="deliveryDate"> <el-form-item :label="t('ProductionPlan.TaskSummary.searchDeliveryLabel')" prop="deliveryDate">
<el-date-picker <el-date-picker
v-model="queryParams.deliveryDate" v-model="queryParams.deliveryDate"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
@change="handleQuery" @change="handleQuery"
type="daterange" type="daterange"
start-placeholder="开始日期" :start-placeholder="t('ProductionPlan.TaskSummary.searchDeliveryStartPlaceholder')"
end-placeholder="结束日期" :end-placeholder="t('ProductionPlan.TaskSummary.searchDeliveryEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item :label="t('ProductionPlan.TaskSummary.searchRemarkLabel')" prop="remark">
<el-input <el-input
v-model="queryParams.remark" v-model="queryParams.remark"
placeholder="请输入备注" :placeholder="t('ProductionPlan.TaskSummary.searchRemarkPlaceholder')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="创建时间" prop="createTime"> <el-form-item :label="t('ProductionPlan.TaskSummary.searchCreateTimeLabel')" prop="createTime">
<el-date-picker <el-date-picker
v-model="queryParams.createTime" v-model="queryParams.createTime"
@change="handleQuery" @change="handleQuery"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" type="daterange"
start-placeholder="开始日期" :start-placeholder="t('ProductionPlan.TaskSummary.searchCreateTimeStartPlaceholder')"
end-placeholder="结束日期" :end-placeholder="t('ProductionPlan.TaskSummary.searchCreateTimeEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px" class="!w-240px"
/> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> {{ t('ProductionPlan.TaskSummary.buttonSearchText') }}</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> {{ t('ProductionPlan.TaskSummary.buttonResetText') }}</el-button>
<el-button <el-button
type="success" type="success"
@ -73,7 +74,7 @@
:loading="exportLoading" :loading="exportLoading"
v-hasPermi="['mes:task:export']" v-hasPermi="['mes:task:export']"
> >
<Icon icon="ep:download" class="mr-5px" /> 导出 <Icon icon="ep:download" class="mr-5px" /> {{ t('ProductionPlan.TaskSummary.buttonExportText') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -82,12 +83,12 @@
<!-- 列表 --> <!-- 列表 -->
<ContentWrap> <ContentWrap>
<el-tabs v-model="activeName" @tab-click="handleTabClick"> <el-tabs v-model="activeName" @tab-click="handleTabClick">
<el-tab-pane label="所有" name="" /> <el-tab-pane :label="t('ProductionPlan.TaskSummary.tabAllLabel')" name="" />
<el-tab-pane label="下达" name="2" /> <el-tab-pane :label="t('ProductionPlan.TaskSummary.tabIssuedLabel')" name="2" />
<el-tab-pane label="计划" name="3" /> <el-tab-pane :label="t('ProductionPlan.TaskSummary.tabPlanLabel')" name="3" />
<el-tab-pane label="开工" name="4" /> <el-tab-pane :label="t('ProductionPlan.TaskSummary.tabStartLabel')" name="4" />
<el-tab-pane label="完工" name="5" /> <el-tab-pane :label="t('ProductionPlan.TaskSummary.tabFinishedLabel')" name="5" />
<el-tab-pane label="入库" name="6" /> <el-tab-pane :label="t('ProductionPlan.TaskSummary.tabStoredLabel')" name="6" />
</el-tabs> </el-tabs>
<el-table <el-table
v-loading="loading" v-loading="loading"
@ -97,23 +98,23 @@
highlight-current-row highlight-current-row
@current-change="handleCurrentChange" @current-change="handleCurrentChange"
> >
<el-table-column label="任务单" align="center" prop="code" width="150px"/> <el-table-column :label="t('ProductionPlan.TaskSummary.tableTaskCodeColumn')" align="center" prop="code" width="150px"/>
<el-table-column label="下达日期" align="center" prop="orderDate" :formatter="dateFormatter2" /> <el-table-column :label="t('ProductionPlan.TaskSummary.tableOrderDateColumn')" align="center" prop="orderDate" :formatter="dateFormatter2" />
<el-table-column label="交货日期" align="center" prop="deliveryDate" :formatter="dateFormatter2"/> <el-table-column :label="t('ProductionPlan.TaskSummary.tableDeliveryDateColumn')" align="center" prop="deliveryDate" :formatter="dateFormatter2"/>
<el-table-column label="状态" align="center" prop="status"> <el-table-column :label="t('ProductionPlan.TaskSummary.tableStatusColumn')" align="center" prop="status">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.MES_TASK_STATUS" :value="scope.row.status" /> <dict-tag :type="DICT_TYPE.MES_TASK_STATUS" :value="scope.row.status" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column :label="t('ProductionPlan.TaskSummary.tableRemarkColumn')" align="center" prop="remark" />
<el-table-column label="操作" align="center" min-width="200px"> <el-table-column :label="t('ProductionPlan.TaskSummary.tableOperateColumn')" align="center" min-width="200px">
<template #default="scope"> <template #default="scope">
<el-button link type="info" @click="openItemNeed(scope.row.code, scope.row.id)" v-hasPermi="['mes:task:query']"> <el-button link type="info" @click="openItemNeed(scope.row.code, scope.row.id)" v-hasPermi="['mes:task:query']">
物料 {{ t('ProductionPlan.TaskSummary.actionMaterialLabel') }}
</el-button> </el-button>
<el-button link type="primary" @click="openPlan(scope.row.id)" v-hasPermi="['mes:plan:query']"> <el-button link type="primary" @click="openPlan(scope.row.id)" v-hasPermi="['mes:plan:query']">
查看计划 {{ t('ProductionPlan.TaskSummary.actionViewPlanLabel') }}
</el-button> </el-button>
<!-- <el-button link v-if="scope.row.status<5" type="success" @click="openTaskPlanForm(scope.row.id, scope.row.code)" v-hasPermi="['mes:task:plan']"> <!-- <el-button link v-if="scope.row.status<5" type="success" @click="openTaskPlanForm(scope.row.id, scope.row.code)" v-hasPermi="['mes:task:plan']">
排产 排产
@ -133,7 +134,7 @@
<!-- 子表的列表 --> <!-- 子表的列表 -->
<ContentWrap> <ContentWrap>
<el-tabs model-value="taskDetail"> <el-tabs model-value="taskDetail">
<el-tab-pane label="任务单汇总明细" name="taskDetail"> <el-tab-pane :label="t('ProductionPlan.TaskSummary.detailTabSummaryLabel')" name="taskDetail">
<TaskDetailList :task-id="currentRow.id" /> <TaskDetailList :task-id="currentRow.id" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>

@ -102,6 +102,13 @@
@size-change="handleSizeChange" @size-change="handleSizeChange"
@current-change="handleCurrentChange" /> @current-change="handleCurrentChange" />
<div v-if="String(jobStatus) === '4'" class="mt-10px text-14px">
<span>{{ t('EquipmentManagement.WorkOrderManagement.jobStatus') }}</span>
<dict-tag :type="'job_status'" :value="jobStatus" />
<span class="ml-20px">取消原因</span>
<span>{{ cancelReason || '-' }}</span>
</div>
<template #footer> <template #footer>
<el-button @click="dialogVisible = false">{{ t('EquipmentManagement.WorkOrderManagement.dialogCancel') }}</el-button> <el-button @click="dialogVisible = false">{{ t('EquipmentManagement.WorkOrderManagement.dialogCancel') }}</el-button>
<el-button <el-button
@ -133,6 +140,8 @@ const submitLoading = ref(false)
const list = ref<TicketResultVO[]>([]) const list = ref<TicketResultVO[]>([])
const total = ref(0) const total = ref(0)
const managementId = ref<number | undefined>(undefined) const managementId = ref<number | undefined>(undefined)
const jobStatus = ref<string | number | undefined>(undefined)
const cancelReason = ref<string | undefined>(undefined)
const decisionMap = reactive<Record<string, '1' | '2' | undefined>>({}) const decisionMap = reactive<Record<string, '1' | '2' | undefined>>({})
const imageMap = reactive<Record<string, string>>({}) const imageMap = reactive<Record<string, string>>({})
@ -141,10 +150,12 @@ const queryParams = reactive({
pageSize: 10 pageSize: 10
}) })
const open = async (options: { managementId: number; title?: string }) => { const open = async (options: { managementId: number; title?: string; jobStatus?: string | number; cancelReason?: string }) => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = options.title || t('EquipmentManagement.WorkOrderManagement.dialogTitleDefault') dialogTitle.value = options.title || t('EquipmentManagement.WorkOrderManagement.dialogTitleDefault')
managementId.value = options.managementId managementId.value = options.managementId
jobStatus.value = options.jobStatus
cancelReason.value = options.cancelReason
for (const key of Object.keys(decisionMap)) delete decisionMap[key] for (const key of Object.keys(decisionMap)) delete decisionMap[key]
for (const key of Object.keys(imageMap)) delete imageMap[key] for (const key of Object.keys(imageMap)) delete imageMap[key]
queryParams.pageNo = 1 queryParams.pageNo = 1

@ -260,9 +260,18 @@ const handleSelectionChange = (rows: TicketManagementVO[]) => {
const handleBatchCancel = async () => { const handleBatchCancel = async () => {
if (!selectedIds.value.length) return if (!selectedIds.value.length) return
try { try {
await message.confirm(t('EquipmentManagement.WorkOrderManagement.cancelConfirm')) const { value } = await ElMessageBox.prompt('请输入取消原因', t('EquipmentManagement.WorkOrderManagement.cancelTask'), {
confirmButtonText: t('common.ok'),
cancelButtonText: t('common.cancel'),
inputPattern: /^[\s\S]*.*\S[\s\S]*$/,
inputErrorMessage: '取消原因不能为空'
})
cancelLoading.value = true cancelLoading.value = true
await TicketManagementApi.batchUpdateTicketStatus({ ids: selectedIds.value.join(','), jobStatus: '2' }) await TicketManagementApi.batchUpdateTicketStatus({
ids: selectedIds.value.join(','),
jobStatus: '4',
cancelReason: value
})
message.success(t('EquipmentManagement.WorkOrderManagement.cancelSuccess')) message.success(t('EquipmentManagement.WorkOrderManagement.cancelSuccess'))
selectedIds.value = [] selectedIds.value = []
await getList() await getList()
@ -297,6 +306,8 @@ const handleRowClick = async (row: TicketManagementVO, column: any) => {
if (!row?.id) return if (!row?.id) return
await resultDialogRef.value?.open({ await resultDialogRef.value?.open({
managementId: row.id, managementId: row.id,
jobStatus: row.jobStatus,
cancelReason: row.cancelReason,
title: row.planNo title: row.planNo
? `${t('EquipmentManagement.WorkOrderManagement.dialogTitleDefault')}-${row.planNo}` ? `${t('EquipmentManagement.WorkOrderManagement.dialogTitleDefault')}-${row.planNo}`
: t('EquipmentManagement.WorkOrderManagement.dialogTitleDefault') : t('EquipmentManagement.WorkOrderManagement.dialogTitleDefault')

@ -133,6 +133,13 @@
@current-change="handleCurrentChange" @current-change="handleCurrentChange"
/> />
<div v-if="String(status) === '4'" class="mt-10px text-14px">
<span>{{ t('QualityManagement.ZjTask.status') }}</span>
<DictTag :type="'job_status'" :value="status" />
<span class="ml-20px">取消原因</span>
<span>{{ cancelReason || '-' }}</span>
</div>
<template #footer> <template #footer>
<el-button @click="dialogVisible = false"> <el-button @click="dialogVisible = false">
{{ t('QualityManagement.TicketResultDialog.cancel') }} {{ t('QualityManagement.TicketResultDialog.cancel') }}
@ -152,6 +159,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ZjTaskResultVO } from '@/api/mes/zjtask' import type { ZjTaskResultVO } from '@/api/mes/zjtask'
import { ZjTaskApi } from '@/api/mes/zjtask' import { ZjTaskApi } from '@/api/mes/zjtask'
import { DictTag } from '@/components/DictTag'
defineOptions({ name: 'ZjTaskResultDialog' }) defineOptions({ name: 'ZjTaskResultDialog' })
@ -167,6 +175,8 @@ const message = useMessage()
const list = ref<ZjTaskResultVO[]>([]) const list = ref<ZjTaskResultVO[]>([])
const total = ref(0) const total = ref(0)
const taskId = ref<number | undefined>(undefined) const taskId = ref<number | undefined>(undefined)
const status = ref<string | number | undefined>(undefined)
const cancelReason = ref<string | undefined>(undefined)
const decisionMap = reactive<Record<string, number | undefined>>({}) const decisionMap = reactive<Record<string, number | undefined>>({})
const imageMap = reactive<Record<string, string>>({}) const imageMap = reactive<Record<string, string>>({})
@ -175,10 +185,12 @@ const queryParams = reactive({
pageSize: 10, pageSize: 10,
}) })
const open = async (id: number) => { const open = async (options: { id: number; status?: string | number; cancelReason?: string }) => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = t('QualityManagement.TicketResultDialog.moduleName') dialogTitle.value = t('QualityManagement.TicketResultDialog.moduleName')
taskId.value = id taskId.value = options.id
status.value = options.status
cancelReason.value = options.cancelReason
for (const key of Object.keys(decisionMap)) delete decisionMap[key] for (const key of Object.keys(decisionMap)) delete decisionMap[key]
for (const key of Object.keys(imageMap)) delete imageMap[key] for (const key of Object.keys(imageMap)) delete imageMap[key]
queryParams.pageNo = 1 queryParams.pageNo = 1

@ -90,6 +90,17 @@ type="success" plain @click="handleExport" :loading="exportLoading"
</ContentWrap> </ContentWrap>
<ContentWrap> <ContentWrap>
<div class="mb-10px">
<el-button
type="warning"
plain
@click="handleBatchCancel"
:disabled="!selectedIds.length"
>
{{ t('QualityManagement.ZjTask.cancelTask') }}
</el-button>
</div>
<el-table <el-table
v-loading="loading" v-loading="loading"
:data="list" :data="list"
@ -216,6 +227,7 @@ const exportLoading = ref(false)
const orgTypeOptions = getStrDictOptions(DICT_TYPE.MES_ORG_TYPE) const orgTypeOptions = getStrDictOptions(DICT_TYPE.MES_ORG_TYPE)
const selectedIds = ref<number[]>([]) const selectedIds = ref<number[]>([])
const cancelLoading = ref(false)
const getList = async () => { const getList = async () => {
loading.value = true loading.value = true
@ -247,7 +259,7 @@ const openForm = (type: string, row?: ZjTaskVO) => {
const handleRowClick = (row: ZjTaskVO) => { const handleRowClick = (row: ZjTaskVO) => {
if (!row?.id) return if (!row?.id) return
resultDialogRef.value?.open(row.id) resultDialogRef.value?.open({ id: row.id, status: row.status, cancelReason: row.cancelReason })
} }
const handleDelete = async (id: number) => { const handleDelete = async (id: number) => {
@ -263,6 +275,30 @@ const handleSelectionChange = (rows: ZjTaskVO[]) => {
selectedIds.value = (rows.map((row) => row.id).filter((id) => id !== undefined && id !== null) as number[]) selectedIds.value = (rows.map((row) => row.id).filter((id) => id !== undefined && id !== null) as number[])
} }
const handleBatchCancel = async () => {
if (!selectedIds.value.length) return
try {
const { value } = await ElMessageBox.prompt('请输入取消原因', t('QualityManagement.ZjTask.cancelTask'), {
confirmButtonText: t('common.ok'),
cancelButtonText: t('common.cancel'),
inputPattern: /^[\s\S]*.*\S[\s\S]*$/,
inputErrorMessage: '取消原因不能为空',
})
cancelLoading.value = true
await ZjTaskApi.batchUpdateZjTaskStatus({
ids: selectedIds.value.join(','),
status: '4',
cancelReason: value,
})
message.success(t('QualityManagement.ZjTask.cancelSuccess'))
selectedIds.value = []
await getList()
} catch {
} finally {
cancelLoading.value = false
}
}
const handleExport = async () => { const handleExport = async () => {
try { try {
await message.exportConfirm() await message.exportConfirm()

@ -135,7 +135,7 @@
</el-form> </el-form>
<el-tabs v-model="subTabsName"> <el-tabs v-model="subTabsName">
<el-tab-pane :label="t('MoldManagement.MoldRepair.tabMoldRepairLine')" name="moldRepairLine"> <el-tab-pane :label="t('MoldManagement.MoldRepair.tabMoldRepairLine')" name="moldRepairLine">
<MoldRepairLineForm ref="moldRepairLineFormRef" :repair-id="formData.id" /> <MoldRepairLineForm ref="moldRepairLineFormRef" :repair-id="formData.id" :line-mode="lineMode" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<template #footer> <template #footer>
@ -189,6 +189,17 @@ const moldLoading = ref(false)
const moldOptions = ref<{ label: string; value: number; raw?: MoldVO }[]>([]) const moldOptions = ref<{ label: string; value: number; raw?: MoldVO }[]>([])
const moldOptionsLoaded = ref(false) const moldOptionsLoaded = ref(false)
const lineMode = computed(() => {
if (formType.value === 'repair') return 'repair' as const
if (formType.value === 'update') {
const v = formData.value.status === '' || formData.value.status === null || formData.value.status === undefined
? undefined
: String(formData.value.status)
if (v === '1') return 'readonlyWithResult' as const
}
return 'edit' as const
})
const users = ref<UserVO[]>([]) const users = ref<UserVO[]>([])
const ensureUsersLoaded = async () => { const ensureUsersLoaded = async () => {
@ -265,6 +276,54 @@ const formRules = reactive({
repairCode: [{ required: true, message: t('MoldManagement.MoldRepair.validatorRepairCodeRequired'), trigger: 'blur' }], repairCode: [{ required: true, message: t('MoldManagement.MoldRepair.validatorRepairCodeRequired'), trigger: 'blur' }],
repairName: [{ required: true, message: t('MoldManagement.MoldRepair.validatorRepairNameRequired'), trigger: 'blur' }], repairName: [{ required: true, message: t('MoldManagement.MoldRepair.validatorRepairNameRequired'), trigger: 'blur' }],
moldId: [{ required: true, message: t('MoldManagement.MoldRepair.validatorMoldRequired'), trigger: 'change' }], moldId: [{ required: true, message: t('MoldManagement.MoldRepair.validatorMoldRequired'), trigger: 'change' }],
requireDate: [
{
validator: (_: any, value: any, callback: any) => {
if (formType.value === 'repair' && !value) {
callback(new Error(t('MoldManagement.MoldRepair.validatorRequireDateRequired')))
return
}
callback()
},
trigger: 'change',
},
],
finishDate: [
{
validator: (_: any, value: any, callback: any) => {
if (formType.value === 'repair' && !value) {
callback(new Error(t('MoldManagement.MoldRepair.validatorFinishDateRequired')))
return
}
callback()
},
trigger: 'change',
},
],
confirmDate: [
{
validator: (_: any, value: any, callback: any) => {
if (formType.value === 'repair' && !value) {
callback(new Error(t('MoldManagement.MoldRepair.validatorConfirmDateRequired')))
return
}
callback()
},
trigger: 'change',
},
],
repairResult: [
{
validator: (_: any, value: any, callback: any) => {
if (formType.value === 'repair' && !value) {
callback(new Error(t('MoldManagement.MoldRepair.validatorRepairResultRequired')))
return
}
callback()
},
trigger: 'blur',
},
],
}) })
const formRef = ref() const formRef = ref()
@ -400,13 +459,32 @@ const submitForm = async () => {
;(data as any).status = 1 ;(data as any).status = 1
} }
;(data as any).moldId = formData.value.moldId ;(data as any).moldId = formData.value.moldId
;(data as any).moldRepairLines = moldRepairLineFormRef.value.getData() const lineList = moldRepairLineFormRef.value.getData() || []
if (formType.value === 'create') {
await MoldRepairApi.createMoldRepair(data) if (formType.value === 'repair') {
message.success(t('common.createSuccess')) const requireDate = (data as any).requireDate
} else { const finishDate = (data as any).finishDate
await MoldRepairApi.updateMoldRepair(data) const confirmDate = (data as any).confirmDate
const repairResult = (data as any).repairResult
const updateReqVOList = lineList
await MoldRepairApi.updateMoldRepairStatus({
id: (data as any).id,
requireDate,
finishDate,
confirmDate,
repairResult,
updateReqVOList,
})
message.success(t('common.updateSuccess')) message.success(t('common.updateSuccess'))
} else {
;(data as any).moldRepairLines = lineList
if (formType.value === 'create') {
await MoldRepairApi.createMoldRepair(data)
message.success(t('common.createSuccess'))
} else {
await MoldRepairApi.updateMoldRepair(data)
message.success(t('common.updateSuccess'))
}
} }
dialogVisible.value = false dialogVisible.value = false
emit('success') emit('success')

@ -40,6 +40,35 @@
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column
v-if="props.lineMode === 'repair' || props.lineMode === 'readonlyWithResult'"
:label="t('MoldManagement.MoldRepairLine.remark')"
min-width="180"
>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.remark`" :rules="formRules.remark" class="mb-0px!">
<el-input
v-model="row.remark"
:placeholder="t('MoldManagement.MoldRepairLine.placeholderRemark')"
:disabled="props.lineMode !== 'repair'"
/>
</el-form-item>
</template>
</el-table-column>
<el-table-column
v-if="props.lineMode === 'repair' || props.lineMode === 'readonlyWithResult'"
:label="t('MoldManagement.MoldRepairLine.result')"
min-width="170"
>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.result`" :rules="formRules.result" class="mb-0px!">
<el-radio-group v-model="row.result" :disabled="props.lineMode !== 'repair'">
<el-radio :value="1">{{ t('MoldManagement.MoldRepairLine.resultOk') }}</el-radio>
<el-radio :value="2">{{ t('MoldManagement.MoldRepairLine.resultNg') }}</el-radio>
</el-radio-group>
</el-form-item>
</template>
</el-table-column>
</el-table> </el-table>
</el-form> </el-form>
<el-row justify="center" class="mt-3"> <el-row justify="center" class="mt-3">
@ -53,6 +82,7 @@ const { t } = useI18n()
const props = defineProps<{ const props = defineProps<{
repairId: undefined repairId: undefined
lineMode?: 'edit' | 'repair' | 'readonlyWithResult'
}>() }>()
const formLoading = ref(false) const formLoading = ref(false)
const formData = ref([]) const formData = ref([])
@ -61,6 +91,30 @@ const formRules = reactive({
subjectId: [{ required: true, message: t('MoldManagement.MoldRepairLine.validatorSubjectIdRequired'), trigger: 'blur' }], subjectId: [{ required: true, message: t('MoldManagement.MoldRepairLine.validatorSubjectIdRequired'), trigger: 'blur' }],
subjectCode: [{ required: true, message: t('MoldManagement.MoldRepairLine.validatorSubjectCodeRequired'), trigger: 'blur' }], subjectCode: [{ required: true, message: t('MoldManagement.MoldRepairLine.validatorSubjectCodeRequired'), trigger: 'blur' }],
subjectContent: [{ required: true, message: t('MoldManagement.MoldRepairLine.validatorSubjectContentRequired'), trigger: 'blur' }], subjectContent: [{ required: true, message: t('MoldManagement.MoldRepairLine.validatorSubjectContentRequired'), trigger: 'blur' }],
remark: [
{
validator: (_: any, value: any, callback: any) => {
if (props.lineMode === 'repair' && !value) {
callback(new Error(t('MoldManagement.MoldRepairLine.validatorRemarkRequired')))
return
}
callback()
},
trigger: 'blur',
},
],
result: [
{
validator: (_: any, value: any, callback: any) => {
if (props.lineMode === 'repair' && (value === undefined || value === null || value === '')) {
callback(new Error(t('MoldManagement.MoldRepairLine.validatorResultRequired')))
return
}
callback()
},
trigger: 'change',
},
],
}) })
const formRef = ref() const formRef = ref()
@ -95,6 +149,7 @@ const handleAdd = () => {
malfunctionUrl: undefined, malfunctionUrl: undefined,
repairDes: undefined, repairDes: undefined,
remark: undefined, remark: undefined,
result: undefined,
} }
row.repairId = props.repairId row.repairId = props.repairId
formData.value.push(row) formData.value.push(row)

@ -137,6 +137,13 @@
:formatter="dateFormatter2" min-width="130" :formatter="dateFormatter2" min-width="130"
/> />
<el-table-column :label="t('MoldManagement.MoldRepair.repairResult')" align="center" prop="repairResult" min-width="160" /> <el-table-column :label="t('MoldManagement.MoldRepair.repairResult')" align="center" prop="repairResult" min-width="160" />
<el-table-column :label="t('MoldManagement.MoldRepair.repairStatus')" align="center" prop="repairStatus" min-width="120">
<template #default="scope">
<el-tag :type="getResultTagType(scope.row.repairStatus)" effect="light">
{{ getResultLabel(scope.row.repairStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column :label="t('MoldManagement.MoldRepair.acceptUser')" align="center" prop="acceptedBy" min-width="140" /> <el-table-column :label="t('MoldManagement.MoldRepair.acceptUser')" align="center" prop="acceptedBy" min-width="140" />
<el-table-column :label="t('MoldManagement.MoldRepair.confirmUserShort')" align="center" prop="confirmBy" min-width="140" /> <el-table-column :label="t('MoldManagement.MoldRepair.confirmUserShort')" align="center" prop="confirmBy" min-width="140" />
<el-table-column :label="t('MoldManagement.MoldRepair.status')" align="center" prop="status" min-width="130"> <el-table-column :label="t('MoldManagement.MoldRepair.status')" align="center" prop="status" min-width="130">
@ -220,6 +227,22 @@ const statusOptions = [
{ label: t('MoldManagement.MoldRepair.statusDone'), value: '1' } { label: t('MoldManagement.MoldRepair.statusDone'), value: '1' }
] ]
const getResultLabel = (value: any) => {
const v = value === '' || value === null || value === undefined ? undefined : String(value)
if (v === '0') return t('MoldManagement.MoldRepair.repairResultPending')
if (v === '1') return t('MoldManagement.MoldRepair.repairResultOk')
if (v === '2') return t('MoldManagement.MoldRepair.repairResultNg')
return '-'
}
const getResultTagType = (value: any) => {
const v = value === '' || value === null || value === undefined ? undefined : String(value)
if (v === '1') return 'success'
if (v === '2') return 'danger'
if (v === '0') return 'info'
return 'info'
}
const getStatusLabel = (value: any) => { const getStatusLabel = (value: any) => {
const v = value === '' || value === null || value === undefined ? undefined : String(value) const v = value === '' || value === null || value === undefined ? undefined : String(value)
if (v === '0') return t('MoldManagement.MoldRepair.statusPending') if (v === '0') return t('MoldManagement.MoldRepair.statusPending')

@ -42,10 +42,17 @@ v-else-if="scope.row.images" :src="parseFirstImage(scope.row.images)"
</el-table> </el-table>
<el-pagination <el-pagination
v-show="total > 0" v-model:current-page="queryParams.pageNo" v-model:page-size="queryParams.pageSize" v-show="total > 0" v-model:current-page="queryParams.pageNo" v-model:page-size="queryParams.pageSize"
:background="true" :page-sizes="[10, 20, 30, 50, 100]" :pager-count="7" :total="total" :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" class="mt-15px mb-15px flex justify-end" layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange" @current-change="handleCurrentChange" /> @size-change="handleSizeChange" @current-change="handleCurrentChange" />
<div v-if="String(jobStatus) === '4'" class="mt-10px text-14px">
<span>{{ t('MoldManagement.MoldWorkOrderInquiry.jobStatus') }}</span>
<dict-tag :type="'job_status'" :value="jobStatus" />
<span class="ml-20px">取消原因</span>
<span>{{ cancelReason || '-' }}</span>
</div>
<template #footer> <template #footer>
<el-button @click="dialogVisible = false">{{ t('MoldManagement.TicketResultDialog.cancel') }}</el-button> <el-button @click="dialogVisible = false">{{ t('MoldManagement.TicketResultDialog.cancel') }}</el-button>
@ -70,6 +77,8 @@ const submitLoading = ref(false)
const list = ref<TicketResultVO[]>([]) const list = ref<TicketResultVO[]>([])
const total = ref(0) const total = ref(0)
const managementId = ref<number | undefined>(undefined) const managementId = ref<number | undefined>(undefined)
const jobStatus = ref<string | number | undefined>(undefined)
const cancelReason = ref<string | undefined>(undefined)
const decisionMap = reactive<Record<string, '1' | '2' | undefined>>({}) const decisionMap = reactive<Record<string, '1' | '2' | undefined>>({})
const imageMap = reactive<Record<string, string>>({}) const imageMap = reactive<Record<string, string>>({})
@ -78,10 +87,12 @@ const queryParams = reactive({
pageSize: 10 pageSize: 10
}) })
const open = async (options: { managementId: number; title?: string }) => { const open = async (options: { managementId: number; title?: string; jobStatus?: string | number; cancelReason?: string }) => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = options.title || t('MoldManagement.TicketResultDialog.moduleName') dialogTitle.value = options.title || t('MoldManagement.TicketResultDialog.moduleName')
managementId.value = options.managementId managementId.value = options.managementId
jobStatus.value = options.jobStatus
cancelReason.value = options.cancelReason
for (const key of Object.keys(decisionMap)) delete decisionMap[key] for (const key of Object.keys(decisionMap)) delete decisionMap[key]
for (const key of Object.keys(imageMap)) delete imageMap[key] for (const key of Object.keys(imageMap)) delete imageMap[key]
queryParams.pageNo = 1 queryParams.pageNo = 1

@ -173,9 +173,18 @@ const handleSelectionChange = (rows: TicketManagementVO[]) => {
const handleBatchCancel = async () => { const handleBatchCancel = async () => {
if (!selectedIds.value.length) return if (!selectedIds.value.length) return
try { try {
await message.confirm(t('MoldManagement.MoldWorkOrderInquiry.cancelConfirm')) const { value } = await ElMessageBox.prompt('请输入取消原因', t('MoldManagement.MoldWorkOrderInquiry.cancelTask'), {
confirmButtonText: t('common.ok'),
cancelButtonText: t('common.cancel'),
inputPattern: /^[\s\S]*.*\S[\s\S]*$/,
inputErrorMessage: '取消原因不能为空'
})
cancelLoading.value = true cancelLoading.value = true
await TicketManagementApi.batchUpdateTicketStatus({ ids: selectedIds.value.join(','), jobStatus: '2' }) await TicketManagementApi.batchUpdateTicketStatus({
ids: selectedIds.value.join(','),
jobStatus: '4',
cancelReason: value
})
message.success(t('MoldManagement.MoldWorkOrderInquiry.cancelSuccess')) message.success(t('MoldManagement.MoldWorkOrderInquiry.cancelSuccess'))
selectedIds.value = [] selectedIds.value = []
await getList() await getList()
@ -192,6 +201,8 @@ const handleRowClick = async (row: TicketManagementVO, column: any) => {
if (!row?.id) return if (!row?.id) return
await resultDialogRef.value?.open({ await resultDialogRef.value?.open({
managementId: row.id, managementId: row.id,
jobStatus: row.jobStatus,
cancelReason: row.cancelReason,
title: row.planNo title: row.planNo
? `${t('MoldManagement.MoldWorkOrderInquiry.inspectResultTitlePrefix')}${row.planNo}` ? `${t('MoldManagement.MoldWorkOrderInquiry.inspectResultTitlePrefix')}${row.planNo}`
: t('MoldManagement.MoldWorkOrderInquiry.inspectResultTitle') : t('MoldManagement.MoldWorkOrderInquiry.inspectResultTitle')

@ -72,7 +72,7 @@
<div class="dashboard-card-image-wrapper" @click="handlePreview(item)"> <div class="dashboard-card-image-wrapper" @click="handlePreview(item)">
<img <img
class="dashboard-card-image" class="dashboard-card-image"
:src="item.indexImage || defaultImage" :src="getDashboardImage(item)"
alt="封面图" alt="封面图"
/> />
<div class="dashboard-card-state"> <div class="dashboard-card-state">
@ -208,6 +208,8 @@
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict' import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import request from '@/config/axios' import request from '@/config/axios'
import defaultImage from '@/assets/imgs/logo.png' import defaultImage from '@/assets/imgs/logo.png'
import dashboardImage1 from '@/assets/imgs/dashboard1.png'
import dashboardImage2 from '@/assets/imgs/dashboard2.png'
import { OrganizationApi } from '@/api/mes/organization' import { OrganizationApi } from '@/api/mes/organization'
import { handleTree } from '@/utils/tree' import { handleTree } from '@/utils/tree'
import { DeviceApi } from '@/api/iot/device' import { DeviceApi } from '@/api/iot/device'
@ -235,6 +237,16 @@ const loading = ref(false)
const list = ref<DashboardItem[]>([]) const list = ref<DashboardItem[]>([])
const total = ref(0) const total = ref(0)
const getDashboardImage = (item: DashboardItem) => {
if (item.name === '智能制造产线任务总览') {
return dashboardImage1
}
if (item.name === '产线运行看板') {
return dashboardImage2
}
return item.indexImage || defaultImage
}
const queryParams = reactive({ const queryParams = reactive({
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
@ -516,21 +528,21 @@ onMounted(() => {
} }
.dashboard-card-title { .dashboard-card-title {
margin-bottom: 4px;
overflow: hidden;
font-size: 14px; font-size: 14px;
font-weight: 600; font-weight: 600;
color: var(--el-text-color-primary); color: var(--el-text-color-primary);
margin-bottom: 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap;
} }
.dashboard-card-remark { .dashboard-card-remark {
overflow: hidden;
font-size: 12px; font-size: 12px;
color: var(--el-text-color-secondary); color: var(--el-text-color-secondary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap;
} }
.dashboard-card-actions { .dashboard-card-actions {

@ -103,22 +103,22 @@ onUnmounted(() => {
<style scoped> <style scoped>
header { header {
height: var(--header-h);
position: relative; position: relative;
z-index: 2; z-index: 2;
display: flex; display: flex;
align-items: center; height: var(--header-h);
padding: 0 18px; padding: 0 18px;
background: background:
linear-gradient(to bottom, rgba(15, 23, 42, 0.95), rgba(15, 23, 42, 0.85)), linear-gradient(to bottom, rgb(15 23 42 / 95%), rgb(15 23 42 / 85%)),
radial-gradient(circle at 50% 0, rgba(56, 189, 248, 0.22), transparent 60%); radial-gradient(circle at 50% 0, rgb(56 189 248 / 22%), transparent 60%);
border-bottom: 1px solid rgba(148, 163, 184, 0.35); border-bottom: 1px solid rgb(148 163 184 / 35%);
box-shadow: 0 10px 35px rgba(15, 23, 42, 0.9); box-shadow: 0 10px 35px rgb(15 23 42 / 90%);
align-items: center;
} }
.header-inner { .header-inner {
width: 100%;
display: grid; display: grid;
width: 100%;
grid-template-columns: 320px 1fr 320px; grid-template-columns: 320px 1fr 320px;
align-items: center; align-items: center;
gap: 12px; gap: 12px;
@ -134,8 +134,8 @@ header {
.time { .time {
font-size: 22px; font-size: 22px;
font-weight: 800; font-weight: 800;
color: #e0f2fe;
letter-spacing: 1px; letter-spacing: 1px;
color: #e0f2fe;
} }
.date { .date {
@ -153,9 +153,9 @@ header {
.title-wrap { .title-wrap {
position: relative; position: relative;
display: flex;
width: min(980px, 100%); width: min(980px, 100%);
height: 64px; height: 64px;
display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
@ -175,10 +175,10 @@ header {
font-size: 28px; font-size: 28px;
font-weight: 900; font-weight: 900;
letter-spacing: 3px; letter-spacing: 3px;
text-shadow: 0 0 20px rgb(56 189 248 / 65%);
background: linear-gradient(to bottom, #e0f2fe, #60a5fa); background: linear-gradient(to bottom, #e0f2fe, #60a5fa);
-webkit-background-clip: text; background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
text-shadow: 0 0 20px rgba(56, 189, 248, 0.65);
} }
.header-right { .header-right {
@ -191,22 +191,22 @@ header {
.back-btn { .back-btn {
display: flex; display: flex;
align-items: center;
gap: 6px;
padding: 6px 16px; padding: 6px 16px;
border-radius: 4px;
background: rgba(30, 64, 175, 0.3);
border: 1px solid rgba(56, 189, 248, 0.3);
color: #e0f2fe;
font-size: 14px; font-size: 14px;
color: #e0f2fe;
cursor: pointer; cursor: pointer;
background: rgb(30 64 175 / 30%);
border: 1px solid rgb(56 189 248 / 30%);
border-radius: 4px;
transition: all 0.3s; transition: all 0.3s;
align-items: center;
gap: 6px;
} }
.back-btn:hover { .back-btn:hover {
background: rgba(30, 64, 175, 0.6); background: rgb(30 64 175 / 60%);
border-color: rgba(56, 189, 248, 0.8); border-color: rgb(56 189 248 / 80%);
box-shadow: 0 0 10px rgba(56, 189, 248, 0.4); box-shadow: 0 0 10px rgb(56 189 248 / 40%);
} }
.weather { .weather {
@ -238,7 +238,7 @@ header {
color: var(--muted); color: var(--muted);
} }
@media (max-width: 1600px) { @media (width <= 1600px) {
.title { .title {
font-size: 24px; font-size: 24px;
} }
@ -252,7 +252,7 @@ header {
} }
} }
@media (max-width: 1366px) { @media (width <= 1366px) {
.title { .title {
font-size: 20px; font-size: 20px;
letter-spacing: 3px; letter-spacing: 3px;

@ -141,31 +141,31 @@ onMounted(() => {
<style scoped> <style scoped>
.card { .card {
position: relative;
display: flex;
height: 100%; height: 100%;
background: linear-gradient(135deg, rgba(15,23,42,0.96), rgba(15,23,42,0.88)); min-height: 0;
overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 8px; border-radius: 8px;
border: 1px solid rgba(30,64,175,0.85);
box-shadow: box-shadow:
0 18px 45px rgba(15,23,42,0.95), 0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgba(15,23,42,1), 0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgba(56,189,248,0.05); inset 0 0 0 1px rgb(56 189 248 / 5%);
position: relative;
display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden;
min-height: 0;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 12px; width: 12px;
height: 12px; height: 12px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -178,27 +178,27 @@ onMounted(() => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.panel-title { .panel-title {
display: flex; display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px; padding: 10px 12px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
font-size: 16px; font-size: 16px;
font-weight: 900; font-weight: 900;
color: #e5f0ff; color: #e5f0ff;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
gap: 10px;
} }
.title-dot { .title-dot {
width: 10px; width: 10px;
height: 10px; height: 10px;
border: 1px solid rgb(56 189 248 / 95%);
border-radius: 50%; border-radius: 50%;
border: 1px solid rgba(56,189,248,0.95); box-shadow: 0 0 12px rgb(56 189 248 / 45%);
box-shadow: 0 0 12px rgba(56,189,248,0.45);
} }
.panel-body { .panel-body {
@ -222,23 +222,23 @@ onMounted(() => {
.gauge { .gauge {
width: 110px; width: 110px;
height: 110px; height: 110px;
border-radius: 50%;
padding: 8px; padding: 8px;
border-radius: 50%;
box-sizing: border-box; box-sizing: border-box;
} }
.gauge-inner { .gauge-inner {
display: flex;
width: 100%; width: 100%;
height: 100%; height: 100%;
text-align: center;
background: rgb(2 6 23 / 92%);
border: 1px solid rgb(148 163 184 / 25%);
border-radius: 50%; border-radius: 50%;
background: rgba(2,6,23,0.92);
border: 1px solid rgba(148,163,184,0.25);
display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 2px; gap: 2px;
text-align: center;
} }
.gauge-value { .gauge-value {
@ -249,10 +249,10 @@ onMounted(() => {
.gauge-label { .gauge-label {
font-size: 11px; font-size: 11px;
color: rgba(148,163,184,0.95); color: rgb(148 163 184 / 95%);
} }
@media (max-width: 1366px) { @media (width <= 1366px) {
.gauge { .gauge {
width: 96px; width: 96px;
height: 96px; height: 96px;

@ -134,8 +134,8 @@ onUnmounted(() => {
<style scoped> <style scoped>
:deep(.el-select .el-input__wrapper) { :deep(.el-select .el-input__wrapper) {
background-color: rgba(2, 6, 23, 0.3); background-color: rgb(2 6 23 / 30%);
box-shadow: 0 0 0 1px rgba(56, 189, 248, 0.4) inset; box-shadow: 0 0 0 1px rgb(56 189 248 / 40%) inset;
} }
:deep(.el-select .el-input__inner) { :deep(.el-select .el-input__inner) {
@ -143,35 +143,35 @@ onUnmounted(() => {
} }
:deep(.el-select .el-input.is-focus .el-input__wrapper) { :deep(.el-select .el-input.is-focus .el-input__wrapper) {
box-shadow: 0 0 0 1px rgba(56, 189, 248, 0.9) inset !important; box-shadow: 0 0 0 1px rgb(56 189 248 / 90%) inset !important;
} }
.card { .card {
position: relative;
display: flex;
height: 100%; height: 100%;
background: linear-gradient(135deg, rgba(15, 23, 42, 0.96), rgba(15, 23, 42, 0.88)); min-height: 0;
overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 8px; border-radius: 8px;
border: 1px solid rgba(30, 64, 175, 0.85);
box-shadow: box-shadow:
0 18px 45px rgba(15, 23, 42, 0.95), 0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgba(15, 23, 42, 1), 0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgba(56, 189, 248, 0.05); inset 0 0 0 1px rgb(56 189 248 / 5%);
position: relative;
display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden;
min-height: 0;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 12px; width: 12px;
height: 12px; height: 12px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56, 189, 248, 0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -184,19 +184,19 @@ onUnmounted(() => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.panel-title { .panel-title {
display: flex; display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px; padding: 10px 12px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
font-size: 16px; font-size: 16px;
font-weight: 900; font-weight: 900;
color: #e5f0ff; color: #e5f0ff;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
gap: 10px;
} }
.panel-title-between { .panel-title-between {
@ -212,9 +212,9 @@ onUnmounted(() => {
.title-dot { .title-dot {
width: 10px; width: 10px;
height: 10px; height: 10px;
border: 1px solid rgb(56 189 248 / 95%);
border-radius: 50%; border-radius: 50%;
border: 1px solid rgba(56, 189, 248, 0.95); box-shadow: 0 0 12px rgb(56 189 248 / 45%);
box-shadow: 0 0 12px rgba(56, 189, 248, 0.45);
} }
.tabs { .tabs {
@ -223,22 +223,22 @@ onUnmounted(() => {
gap: 10px; gap: 10px;
font-size: 11px; font-size: 11px;
font-weight: 600; font-weight: 600;
color: rgba(148, 163, 184, 0.95); color: rgb(148 163 184 / 95%);
} }
.tab { .tab {
cursor: pointer;
user-select: none;
padding: 2px 8px; padding: 2px 8px;
cursor: pointer;
background: rgb(2 6 23 / 20%);
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px; border-radius: 999px;
border: 1px solid rgba(148, 163, 184, 0.4); user-select: none;
background: rgba(2, 6, 23, 0.2);
} }
.tab.active { .tab.active {
border-color: rgba(56, 189, 248, 0.85);
color: #e0f2fe; color: #e0f2fe;
box-shadow: 0 0 14px rgba(56, 189, 248, 0.35); border-color: rgb(56 189 248 / 85%);
box-shadow: 0 0 14px rgb(56 189 248 / 35%);
} }
.panel-body { .panel-body {
@ -254,10 +254,10 @@ onUnmounted(() => {
} }
:deep(.el-select__wrapper) { :deep(.el-select__wrapper) {
background-color: transparent;
border: 1px solid rgba(56, 189, 248, 0.55);
box-shadow: 0 0 18px rgba(56, 189, 248, 0.35);
color: #94a3b8; color: #94a3b8;
background-color: transparent;
border: 1px solid rgb(56 189 248 / 55%);
box-shadow: 0 0 18px rgb(56 189 248 / 35%);
} }
:deep(.el-select__placeholder) { :deep(.el-select__placeholder) {

@ -177,31 +177,31 @@ onUnmounted(() => {
<style scoped> <style scoped>
.card { .card {
position: relative;
display: flex;
height: 100%; height: 100%;
background: linear-gradient(135deg, rgba(15,23,42,0.96), rgba(15,23,42,0.88)); min-height: 0;
overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 8px; border-radius: 8px;
border: 1px solid rgba(30,64,175,0.85);
box-shadow: box-shadow:
0 18px 45px rgba(15,23,42,0.95), 0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgba(15,23,42,1), 0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgba(56,189,248,0.05); inset 0 0 0 1px rgb(56 189 248 / 5%);
position: relative;
display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden;
min-height: 0;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 12px; width: 12px;
height: 12px; height: 12px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -214,20 +214,20 @@ onUnmounted(() => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.panel-title { .panel-title {
display: flex; display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
padding: 10px 12px; padding: 10px 12px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
font-size: 16px; font-size: 16px;
font-weight: 900; font-weight: 900;
color: #e5f0ff; color: #e5f0ff;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
justify-content: space-between;
gap: 10px;
} }
.panel-title-left { .panel-title-left {
@ -238,12 +238,12 @@ onUnmounted(() => {
.panel-title-right { .panel-title-right {
display: inline-flex; display: inline-flex;
align-items: center;
gap: 6px;
padding: 2px 4px; padding: 2px 4px;
background: radial-gradient(circle at 0 0, rgb(56 189 248 / 18%), transparent 70%);
border: 1px solid rgb(56 189 248 / 50%);
border-radius: 999px; border-radius: 999px;
border: 1px solid rgba(56, 189, 248, 0.5); align-items: center;
background: radial-gradient(circle at 0 0, rgba(56, 189, 248, 0.18), transparent 70%); gap: 6px;
} }
.panel-title-right :deep(.el-radio-group) { .panel-title-right :deep(.el-radio-group) {
@ -251,27 +251,27 @@ onUnmounted(() => {
} }
.panel-title-right :deep(.el-radio-button__inner) { .panel-title-right :deep(.el-radio-button__inner) {
border: none;
box-shadow: none;
background: transparent;
color: rgba(148, 163, 184, 0.95);
padding: 4px 10px; padding: 4px 10px;
font-size: 12px; font-size: 12px;
color: rgb(148 163 184 / 95%);
background: transparent;
border: none;
box-shadow: none;
} }
.panel-title-right :deep(.el-radio-button__original-radio:checked + .el-radio-button__inner) { .panel-title-right :deep(.el-radio-button__original-radio:checked + .el-radio-button__inner) {
background: rgba(15, 23, 42, 0.9);
color: #e5f0ff; color: #e5f0ff;
box-shadow: 0 0 0 1px rgba(56, 189, 248, 0.85); background: rgb(15 23 42 / 90%);
border-radius: 999px; border-radius: 999px;
box-shadow: 0 0 0 1px rgb(56 189 248 / 85%);
} }
.title-dot { .title-dot {
width: 10px; width: 10px;
height: 10px; height: 10px;
border: 1px solid rgb(56 189 248 / 95%);
border-radius: 50%; border-radius: 50%;
border: 1px solid rgba(56,189,248,0.95); box-shadow: 0 0 12px rgb(56 189 248 / 45%);
box-shadow: 0 0 12px rgba(56,189,248,0.45);
} }
.panel-body { .panel-body {
@ -295,12 +295,12 @@ onUnmounted(() => {
.event-row { .event-row {
display: flex; display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 10px; padding: 8px 10px;
background: rgb(15 23 42 / 70%);
border: 1px solid rgb(30 64 175 / 70%);
border-radius: 6px; border-radius: 6px;
border: 1px solid rgba(30,64,175,0.7); align-items: center;
background: rgba(15,23,42,0.7); justify-content: space-between;
} }
.event-name { .event-name {
@ -314,8 +314,8 @@ onUnmounted(() => {
.event-bullet { .event-bullet {
width: 12px; width: 12px;
height: 12px; height: 12px;
border-radius: 50%;
border: 3px solid; border: 3px solid;
border-radius: 50%;
box-sizing: border-box; box-sizing: border-box;
} }
@ -325,19 +325,19 @@ onUnmounted(() => {
} }
.event-chart { .event-chart {
display: flex;
height: 100%; height: 100%;
min-height: 170px; min-height: 170px;
display: flex;
min-height: 0; min-height: 0;
} }
.chart-container { .chart-container {
display: flex;
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; min-height: 0;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
min-height: 0;
} }
.chart { .chart {
@ -345,7 +345,7 @@ onUnmounted(() => {
height: 100%; height: 100%;
} }
@media (max-width: 1366px) { @media (width <= 1366px) {
.body { .body {
grid-template-columns: 0.8fr 1.2fr; grid-template-columns: 0.8fr 1.2fr;
} }

@ -108,29 +108,29 @@ onUnmounted(() => {
<style scoped> <style scoped>
.card { .card {
background: linear-gradient(135deg, rgba(15,23,42,0.96), rgba(15,23,42,0.88));
border-radius: 8px;
border: 1px solid rgba(30,64,175,0.85);
box-shadow:
0 18px 45px rgba(15,23,42,0.95),
0 0 0 1px rgba(15,23,42,1),
inset 0 0 0 1px rgba(56,189,248,0.05);
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column;
overflow: hidden; overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 8px;
box-shadow:
0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgb(56 189 248 / 5%);
flex-direction: column;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 12px; width: 12px;
height: 12px; height: 12px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -143,17 +143,17 @@ onUnmounted(() => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.card-header { .card-header {
display: flex; display: flex;
padding: 10px 12px 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 8px;
padding: 10px 12px 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
} }
.card-title { .card-title {
@ -170,61 +170,61 @@ onUnmounted(() => {
} }
.card-body { .card-body {
flex: 1;
min-height: 0;
display: flex; display: flex;
flex-direction: column; min-height: 0;
gap: 8px;
padding: 10px 12px 12px; padding: 10px 12px 12px;
overflow: hidden; overflow: hidden;
flex: 1;
flex-direction: column;
gap: 8px;
} }
.tag { .tag {
border-radius: 999px;
padding: 2px 6px; padding: 2px 6px;
font-size: 10px; font-size: 10px;
border: 1px solid rgba(148,163,184,0.4);
color: #94a3b8; color: #94a3b8;
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
} }
.alarm-list { .alarm-list {
list-style: none;
margin: 0;
padding: 0;
display: flex; display: flex;
flex-direction: column;
gap: 6px;
height: 100%; height: 100%;
padding: 0;
margin: 0;
overflow: hidden; overflow: hidden;
list-style: none;
flex-direction: column;
gap: 6px;
} }
.alarm-item { .alarm-item {
display: flex; display: flex;
align-items: center;
gap: 8px;
padding: 7px 8px; padding: 7px 8px;
border-radius: 6px;
background: rgba(15,23,42,0.92);
border: 1px solid rgba(30,64,175,0.9);
font-size: 11px; font-size: 11px;
color: #e5f0ff; color: #e5f0ff;
background: rgb(15 23 42 / 92%);
border: 1px solid rgb(30 64 175 / 90%);
border-radius: 6px;
transition: background 0.3s, box-shadow 0.3s; transition: background 0.3s, box-shadow 0.3s;
align-items: center;
gap: 8px;
flex-shrink: 0; flex-shrink: 0;
} }
.alarm-item.danger { .alarm-item.danger {
border-left: 3px solid #ef4444; border-left: 3px solid #ef4444;
box-shadow: 0 0 18px rgba(239,68,68,0.4); box-shadow: 0 0 18px rgb(239 68 68 / 40%);
} }
.alarm-item.warn { .alarm-item.warn {
border-left: 3px solid #f59e0b; border-left: 3px solid #f59e0b;
box-shadow: 0 0 14px rgba(245,158,11,0.35); box-shadow: 0 0 14px rgb(245 158 11 / 35%);
} }
.alarm-item.safe { .alarm-item.safe {
border-left: 3px solid #22c55e; border-left: 3px solid #22c55e;
box-shadow: 0 0 12px rgba(34,197,94,0.35); box-shadow: 0 0 12px rgb(34 197 94 / 35%);
} }
.alarm-time { .alarm-time {
@ -234,23 +234,23 @@ onUnmounted(() => {
} }
.alarm-msg { .alarm-msg {
flex: 1;
white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
} }
.alarm-level { .alarm-level {
flex: 0 0 auto;
border-radius: 999px;
padding: 2px 6px; padding: 2px 6px;
border: 1px solid rgba(148,163,184,0.6);
font-size: 10px; font-size: 10px;
border: 1px solid rgb(148 163 184 / 60%);
border-radius: 999px;
flex: 0 0 auto;
} }
.animating-out { .animating-out {
transition: all 0.35s;
transform: translateY(-48px);
opacity: 0; opacity: 0;
transform: translateY(-48px);
transition: all 0.35s;
} }
</style> </style>

@ -104,31 +104,31 @@ onUnmounted(() => {
<style scoped> <style scoped>
.card { .card {
position: relative;
display: flex;
height: 100%; height: 100%;
background: linear-gradient(135deg, rgba(15,23,42,0.96), rgba(15,23,42,0.88)); min-height: 0;
overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 8px; border-radius: 8px;
border: 1px solid rgba(30,64,175,0.85);
box-shadow: box-shadow:
0 18px 45px rgba(15,23,42,0.95), 0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgba(15,23,42,1), 0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgba(56,189,248,0.05); inset 0 0 0 1px rgb(56 189 248 / 5%);
position: relative;
display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden;
min-height: 0;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 12px; width: 12px;
height: 12px; height: 12px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -141,38 +141,38 @@ onUnmounted(() => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.panel-title { .panel-title {
display: flex; display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px; padding: 10px 12px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
font-size: 16px; font-size: 16px;
font-weight: 900; font-weight: 900;
color: #e5f0ff; color: #e5f0ff;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
gap: 10px;
} }
.title-dot { .title-dot {
width: 10px; width: 10px;
height: 10px; height: 10px;
border: 1px solid rgb(56 189 248 / 95%);
border-radius: 50%; border-radius: 50%;
border: 1px solid rgba(56,189,248,0.95); box-shadow: 0 0 12px rgb(56 189 248 / 45%);
box-shadow: 0 0 12px rgba(56,189,248,0.45);
} }
.tag { .tag {
margin-left: auto;
border-radius: 999px;
padding: 2px 8px; padding: 2px 8px;
margin-left: auto;
font-size: 11px; font-size: 11px;
font-weight: 700; font-weight: 700;
border: 1px solid rgba(148,163,184,0.4); color: rgb(148 163 184 / 95%);
color: rgba(148,163,184,0.95); background: rgb(2 6 23 / 20%);
background: rgba(2,6,23,0.2); border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
} }
.panel-body { .panel-body {

@ -171,31 +171,31 @@ onUnmounted(() => {
<style scoped> <style scoped>
.card { .card {
position: relative;
display: flex;
height: 100%; height: 100%;
background: linear-gradient(135deg, rgba(15,23,42,0.96), rgba(15,23,42,0.88)); min-height: 0;
overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 8px; border-radius: 8px;
border: 1px solid rgba(30,64,175,0.85);
box-shadow: box-shadow:
0 18px 45px rgba(15,23,42,0.95), 0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgba(15,23,42,1), 0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgba(56,189,248,0.05); inset 0 0 0 1px rgb(56 189 248 / 5%);
position: relative;
display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden;
min-height: 0;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 12px; width: 12px;
height: 12px; height: 12px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -208,27 +208,27 @@ onUnmounted(() => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.panel-title { .panel-title {
display: flex; display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px; padding: 10px 12px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
font-size: 16px; font-size: 16px;
font-weight: 900; font-weight: 900;
color: #e5f0ff; color: #e5f0ff;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
gap: 10px;
} }
.title-dot { .title-dot {
width: 10px; width: 10px;
height: 10px; height: 10px;
border: 1px solid rgb(56 189 248 / 95%);
border-radius: 50%; border-radius: 50%;
border: 1px solid rgba(56,189,248,0.95); box-shadow: 0 0 12px rgb(56 189 248 / 45%);
box-shadow: 0 0 12px rgba(56,189,248,0.45);
} }
.panel-body { .panel-body {
@ -239,22 +239,22 @@ onUnmounted(() => {
.table-body { .table-body {
padding: 0; padding: 0;
overflow-x: auto; overflow: auto hidden;
overflow-y: hidden;
} }
.task-table { .task-table {
width: 100%;
min-width: 450px;
font-size: 12px;
/* Element Plus Table Variables Override */ /* Element Plus Table Variables Override */
--el-table-bg-color: transparent; --el-table-bg-color: transparent;
--el-table-tr-bg-color: transparent; --el-table-tr-bg-color: transparent;
--el-table-header-bg-color: transparent; --el-table-header-bg-color: transparent;
--el-table-text-color: #e5f0ff; --el-table-text-color: #e5f0ff;
--el-table-header-text-color: #22d3ee; --el-table-header-text-color: #22d3ee;
--el-table-row-hover-bg-color: rgba(56, 189, 248, 0.12); --el-table-row-hover-bg-color: rgb(56 189 248 / 12%);
--el-table-border-color: rgba(30, 64, 175, 0.3); --el-table-border-color: rgb(30 64 175 / 30%);
width: 100%;
min-width: 450px;
font-size: 12px;
background-color: transparent !important; background-color: transparent !important;
} }
@ -274,52 +274,52 @@ onUnmounted(() => {
} }
.table-body::-webkit-scrollbar-track { .table-body::-webkit-scrollbar-track {
background: rgba(15, 23, 42, 0.9); background: rgb(15 23 42 / 90%);
border-radius: 999px; border-radius: 999px;
} }
.table-body::-webkit-scrollbar-thumb { .table-body::-webkit-scrollbar-thumb {
background: linear-gradient(to right, rgba(56, 189, 248, 0.85), rgba(59, 130, 246, 0.8)); background: linear-gradient(to right, rgb(56 189 248 / 85%), rgb(59 130 246 / 80%));
border-radius: 999px; border-radius: 999px;
box-shadow: 0 0 10px rgba(56, 189, 248, 0.4); box-shadow: 0 0 10px rgb(56 189 248 / 40%);
} }
/* Header Styles */ /* Header Styles */
.task-table :deep(thead th.el-table__cell) { .task-table :deep(thead th.el-table__cell) {
background: radial-gradient(circle at 0 0, rgba(56,189,248,0.18), transparent 90%) !important;
font-weight: 700;
border-bottom: 1px solid rgba(51,65,85,0.9) !important;
padding: 8px 0; padding: 8px 0;
font-weight: 700;
background: radial-gradient(circle at 0 0, rgb(56 189 248 / 18%), transparent 90%) !important;
border-bottom: 1px solid rgb(51 65 85 / 90%) !important;
} }
/* Cell Styles */ /* Cell Styles */
.task-table :deep(td.el-table__cell) { .task-table :deep(td.el-table__cell) {
background-color: transparent !important;
border-bottom: 1px solid rgba(30,64,175,0.3) !important;
padding: 8px 0; padding: 8px 0;
white-space: nowrap; white-space: nowrap;
background-color: transparent !important;
border-bottom: 1px solid rgb(30 64 175 / 30%) !important;
} }
/* Ensure code, name, type columns show ellipsis */ /* Ensure code, name, type columns show ellipsis */
.task-table :deep(td.el-table__cell:nth-child(1) .cell), .task-table :deep(td.el-table__cell:nth-child(1) .cell),
.task-table :deep(td.el-table__cell:nth-child(2) .cell), .task-table :deep(td.el-table__cell:nth-child(2) .cell),
.task-table :deep(td.el-table__cell:nth-child(3) .cell) { .task-table :deep(td.el-table__cell:nth-child(3) .cell) {
white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap;
} }
/* Ensure finishStatus and result columns DO NOT show ellipsis */ /* Ensure finishStatus and result columns DO NOT show ellipsis */
.task-table :deep(td.el-table__cell:nth-child(4) .cell), .task-table :deep(td.el-table__cell:nth-child(4) .cell),
.task-table :deep(td.el-table__cell:nth-child(5) .cell) { .task-table :deep(td.el-table__cell:nth-child(5) .cell) {
white-space: nowrap;
overflow: visible; overflow: visible;
text-overflow: clip; text-overflow: clip;
white-space: nowrap;
} }
/* Hover Styles */ /* Hover Styles */
.task-table :deep(tbody tr:hover > td.el-table__cell) { .task-table :deep(tbody tr:hover > td.el-table__cell) {
background-color: rgba(56,189,248,0.1) !important; background-color: rgb(56 189 248 / 10%) !important;
} }
.status-cell { .status-cell {
@ -328,8 +328,8 @@ onUnmounted(() => {
.status-tag { .status-tag {
min-width: 60px; min-width: 60px;
padding: 0 10px;
text-align: center; text-align: center;
border-radius: 999px; border-radius: 999px;
padding: 0 10px;
} }
</style> </style>

@ -160,12 +160,19 @@ onMounted(() => {
</script> </script>
<style scoped> <style scoped>
/* Define CSS Variables locally for this dashboard */
@keyframes scanDown {
0% { transform: translateY(-100%); }
100% { transform: translateY(260%); }
}
.dashboard-container { .dashboard-container {
--bg: #050816; --bg: #050816;
--bg-deep: #020617; --bg-deep: #020617;
--card-bg: rgba(15, 23, 42, 0.86); --card-bg: rgb(15 23 42 / 86%);
--border: rgba(56, 189, 248, 0.35); --border: rgb(56 189 248 / 35%);
--text: #e5f0ff; --text: #e5f0ff;
--muted: #94a3b8; --muted: #94a3b8;
--primary: #38bdf8; --primary: #38bdf8;
@ -179,37 +186,37 @@ onMounted(() => {
--header-h: 86px; --header-h: 86px;
position: relative; position: relative;
display: flex;
width: 100%; width: 100%;
min-height: 100vh; min-height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden; overflow: hidden;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Microsoft Yahei", Arial, sans-serif; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Microsoft Yahei", Arial, sans-serif;
color: var(--text); color: var(--text);
background-color: var(--bg-deep); background-color: var(--bg-deep);
background-image: background-image:
radial-gradient(circle at 20% 0, rgba(56, 189, 248, 0.26) 0, transparent 48%), radial-gradient(circle at 20% 0, rgb(56 189 248 / 26%) 0, transparent 48%),
radial-gradient(circle at 80% 110%, rgba(129, 140, 248, 0.22) 0, transparent 52%), radial-gradient(circle at 80% 110%, rgb(129 140 248 / 22%) 0, transparent 52%),
linear-gradient(135deg, #020617 0%, #020617 45%, #020617 100%); linear-gradient(135deg, #020617 0%, #020617 45%, #020617 100%);
flex-direction: column;
} }
.bg-grid { .bg-grid {
position: absolute; position: absolute;
inset: 0; z-index: 0;
pointer-events: none; pointer-events: none;
background-image: linear-gradient(rgba(15,23,42,0.8) 1px, transparent 1px), background-image: linear-gradient(rgb(15 23 42 / 80%) 1px, transparent 1px),
linear-gradient(90deg, rgba(15,23,42,0.8) 1px, transparent 1px); linear-gradient(90deg, rgb(15 23 42 / 80%) 1px, transparent 1px);
background-size: 70px 70px; background-size: 70px 70px;
opacity: 0.55; opacity: 0.55;
z-index: 0; inset: 0;
} }
.bg-scan { .bg-scan {
position: absolute; position: absolute;
inset: 0; z-index: 0;
overflow: hidden; overflow: hidden;
pointer-events: none; pointer-events: none;
z-index: 0; inset: 0;
} }
.scan-line { .scan-line {
@ -218,37 +225,32 @@ onMounted(() => {
left: 0; left: 0;
width: 100%; width: 100%;
height: 40%; height: 40%;
background: radial-gradient(circle at 50% 0, rgba(56, 189, 248, 0.38), transparent 70%); background: radial-gradient(circle at 50% 0, rgb(56 189 248 / 38%), transparent 70%);
opacity: 0.5; opacity: 0.5;
filter: blur(32px); filter: blur(32px);
animation: scanDown 16s linear infinite; animation: scanDown 16s linear infinite;
} }
@keyframes scanDown {
0% { transform: translateY(-100%); }
100% { transform: translateY(260%); }
}
main { main {
height: calc(100vh - var(--header-h));
padding: var(--gap);
box-sizing: border-box;
position: relative; position: relative;
z-index: 1; z-index: 1;
display: flex; display: flex;
height: calc(100vh - var(--header-h));
min-height: 0;
padding: var(--gap);
box-sizing: border-box;
flex-direction: column; flex-direction: column;
gap: var(--gap); gap: var(--gap);
min-height: 0;
} }
.layout { .layout {
flex: 1;
height: 100%;
display: flex; display: flex;
flex-direction: column;
gap: var(--gap);
width: 100%; width: 100%;
height: 100%;
min-height: 0; min-height: 0;
flex: 1;
flex-direction: column;
gap: var(--gap);
} }
.main-row { .main-row {
@ -258,17 +260,17 @@ main {
} }
.col { .col {
display: flex;
height: 100%; height: 100%;
min-height: 0; min-height: 0;
display: flex;
flex-direction: column; flex-direction: column;
gap: var(--gap); gap: var(--gap);
} }
.col-item { .col-item {
flex: 1;
min-height: 0;
display: flex; display: flex;
min-height: 0;
flex: 1;
} }
.col-item :deep(> *) { .col-item :deep(> *) {
@ -277,53 +279,53 @@ main {
} }
.center-shell { .center-shell {
flex: 1; position: relative; /* 用于定位内部绝对定位的设备卡片 */
min-height: 0;
display: flex; display: flex;
min-height: 0;
padding: 10px;
background: rgb(2 6 23 / 18%);
border: 1px solid rgb(30 64 175 / 55%);
border-radius: 8px;
flex: 1;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
border-radius: 8px;
border: 1px solid rgba(30,64,175,0.55);
background: rgba(2,6,23,0.18);
padding: 10px;
position: relative; /* 用于定位内部绝对定位的设备卡片 */
} }
.device-card { .device-card {
position: absolute; position: absolute;
width: 18%; /* 约占宽度的1/5留出间隔 */ width: 18%; /* 约占宽度的1/5留出间隔 */
min-width: 120px; min-width: 120px;
background: rgba(15, 23, 42, 0.85);
border: 1px solid rgba(56, 189, 248, 0.4);
border-radius: 6px;
padding: 8px; padding: 8px;
color: #fff; color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); background: rgb(15 23 42 / 85%);
border: 1px solid rgb(56 189 248 / 40%);
border-radius: 6px;
box-shadow: 0 0 10px rgb(0 0 0 / 50%);
} }
.top-card { .top-card {
top: 6%; top: 5%;
} }
.bottom-card { .bottom-card {
bottom: 5%; bottom: 4%;
} }
.device-header { .device-header {
display: flex; display: flex;
padding-bottom: 4px;
margin-bottom: 6px;
border-bottom: 1px solid rgb(56 189 248 / 30%);
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 6px;
border-bottom: 1px solid rgba(56, 189, 248, 0.3);
padding-bottom: 4px;
} }
.header-left { .header-left {
display: flex; display: flex;
align-items: center; margin-right: 8px;
overflow: hidden; overflow: hidden;
align-items: center;
flex: 1; flex: 1;
margin-right: 8px;
} }
.header-right { .header-right {
@ -333,20 +335,20 @@ main {
.device-dot { .device-dot {
width: 0; width: 0;
height: 0; height: 0;
margin-right: 6px;
border-color: transparent transparent transparent #38bdf8;
border-style: solid; border-style: solid;
border-width: 4px 0 4px 6px; border-width: 4px 0 4px 6px;
border-color: transparent transparent transparent #38bdf8;
margin-right: 6px;
flex-shrink: 0; flex-shrink: 0;
} }
.device-name { .device-name {
overflow: hidden;
font-size: 14px; font-size: 14px;
font-weight: bold; font-weight: bold;
color: #e5f0ff; color: #e5f0ff;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap;
} }
.device-id { .device-id {
@ -355,10 +357,11 @@ main {
} }
.device-body { .device-body {
font-size: 12px; min-height: 60px; /* 固定高度,内容不足留白,内容多则滚动 */
height: 100px; /* 固定高度,内容不足留白,内容多则滚动 */ height: 7vh;
overflow-y: auto; /* 启用垂直滚动 */
padding-right: 4px; /* 防止滚动条遮挡内容 */ padding-right: 4px; /* 防止滚动条遮挡内容 */
overflow-y: auto; /* 启用垂直滚动 */
font-size: 12px;
} }
/* 滚动条样式 */ /* 滚动条样式 */
@ -367,7 +370,7 @@ main {
} }
.device-body::-webkit-scrollbar-thumb { .device-body::-webkit-scrollbar-thumb {
background: rgba(56, 189, 248, 0.3); background: rgb(56 189 248 / 30%);
border-radius: 2px; border-radius: 2px;
} }
@ -383,27 +386,29 @@ main {
} }
.device-row .label { .device-row .label {
color: #94a3b8; max-width: 60%;
margin-right: 8px; margin-right: 8px;
white-space: nowrap;
overflow: hidden; overflow: hidden;
color: #94a3b8;
text-overflow: ellipsis; text-overflow: ellipsis;
max-width: 60%; white-space: nowrap;
} }
.device-row .value { .device-row .value {
overflow: hidden;
color: #cbd5e1; color: #cbd5e1;
text-align: right; text-align: right;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
} }
.dashboard-center-image { .dashboard-center-image {
max-width: 100%; max-width: 100%;
max-height: 100%; max-height: 75%;
object-fit: contain; object-fit: contain;
} }
/* Define CSS Variables locally for this dashboard */
</style> </style>

@ -64,24 +64,24 @@ onUnmounted(() => {
<style scoped> <style scoped>
header { header {
height: var(--header-h);
position: relative; position: relative;
z-index: 2; z-index: 2;
display: flex; display: flex;
align-items: center; height: var(--header-h);
justify-content: center;
padding: 0 24px; padding: 0 24px;
background: background:
linear-gradient(to bottom, rgba(15, 23, 42, 0.95), rgba(15, 23, 42, 0.85)), linear-gradient(to bottom, rgb(15 23 42 / 95%), rgb(15 23 42 / 85%)),
radial-gradient(circle at 50% 0, rgba(56, 189, 248, 0.22), transparent 60%); radial-gradient(circle at 50% 0, rgb(56 189 248 / 22%), transparent 60%);
border-bottom: 1px solid rgba(148, 163, 184, 0.35); border-bottom: 1px solid rgb(148 163 184 / 35%);
box-shadow: 0 10px 35px rgba(15, 23, 42, 0.9); box-shadow: 0 10px 35px rgb(15 23 42 / 90%);
align-items: center;
justify-content: center;
} }
.header-inner { .header-inner {
max-width: 1920px;
width: 100%;
display: flex; display: flex;
width: 100%;
max-width: 1920px;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
} }
@ -93,37 +93,37 @@ header {
} }
.title-mark { .title-mark {
display: flex;
width: 42px; width: 42px;
height: 42px; height: 42px;
background: radial-gradient(circle at 30% 30%, rgb(56 189 248 / 35%), transparent 70%);
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 50%; border-radius: 50%;
border: 1px solid rgba(56, 189, 248, 0.75); box-shadow: 0 0 24px rgb(56 189 248 / 55%);
display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: radial-gradient(circle at 30% 30%, rgba(56, 189, 248, 0.35), transparent 70%);
box-shadow: 0 0 24px rgba(56, 189, 248, 0.55);
} }
.title-mark-icon { .title-mark-icon {
color: var(--accent);
font-size: 20px; font-size: 20px;
color: var(--accent);
} }
.title { .title {
font-size: 32px; font-size: 32px;
font-weight: 900; font-weight: 900;
letter-spacing: 4px; letter-spacing: 4px;
text-shadow: 0 0 20px rgb(56 189 248 / 65%);
background: linear-gradient(to bottom, #e0f2fe, #60a5fa); background: linear-gradient(to bottom, #e0f2fe, #60a5fa);
-webkit-background-clip: text; background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
text-shadow: 0 0 20px rgba(56, 189, 248, 0.65);
} }
.sub-title { .sub-title {
font-size: 12px;
color: var(--muted);
margin-top: 3px; margin-top: 3px;
font-size: 12px;
letter-spacing: 2px; letter-spacing: 2px;
color: var(--muted);
} }
.header-right { .header-right {
@ -136,19 +136,19 @@ header {
.back-btn { .back-btn {
display: inline-flex; display: inline-flex;
align-items: center;
gap: 4px;
padding: 4px 12px; padding: 4px 12px;
border-radius: 999px;
border-color: rgba(56, 189, 248, 0.85);
background: radial-gradient(circle at 0 0, rgba(56, 189, 248, 0.22), transparent 70%);
color: #e0f2fe; color: #e0f2fe;
box-shadow: 0 0 18px rgba(56, 189, 248, 0.45); background: radial-gradient(circle at 0 0, rgb(56 189 248 / 22%), transparent 70%);
border-color: rgb(56 189 248 / 85%);
border-radius: 999px;
box-shadow: 0 0 18px rgb(56 189 248 / 45%);
align-items: center;
gap: 4px;
} }
.back-btn:hover { .back-btn:hover {
border-color: rgba(96, 165, 250, 0.95); background: radial-gradient(circle at 0 0, rgb(59 130 246 / 35%), transparent 70%);
background: radial-gradient(circle at 0 0, rgba(59, 130, 246, 0.35), transparent 70%); border-color: rgb(96 165 250 / 95%);
} }
.back-icon { .back-icon {
@ -157,13 +157,13 @@ header {
} }
.chip { .chip {
border-radius: 999px;
border: 1px solid rgba(148, 163, 184, 0.5);
padding: 4px 10px;
display: inline-flex; display: inline-flex;
padding: 4px 10px;
background: rgb(15 23 42 / 75%);
border: 1px solid rgb(148 163 184 / 50%);
border-radius: 999px;
align-items: center; align-items: center;
gap: 6px; gap: 6px;
background: rgba(15, 23, 42, 0.75);
} }
.chip-icon { .chip-icon {
@ -171,18 +171,18 @@ header {
} }
.chip-strong { .chip-strong {
border-color: rgba(56, 189, 248, 0.8);
background: radial-gradient(circle at 0 0, rgba(56, 189, 248, 0.35), transparent 70%);
color: #e0f2fe; color: #e0f2fe;
background: radial-gradient(circle at 0 0, rgb(56 189 248 / 35%), transparent 70%);
border-color: rgb(56 189 248 / 80%);
} }
@media (max-width: 1600px) { @media (width <= 1600px) {
.title { .title {
font-size: 26px; font-size: 26px;
} }
} }
@media (max-width: 1366px) { @media (width <= 1366px) {
.title { .title {
font-size: 22px; font-size: 22px;
letter-spacing: 3px; letter-spacing: 3px;

@ -136,30 +136,30 @@ onUnmounted(() => {
<style scoped> <style scoped>
.card { .card {
background: linear-gradient(135deg, rgba(15,23,42,0.96), rgba(15,23,42,0.88));
border-radius: 10px;
border: 1px solid rgba(30,64,175,0.85);
box-shadow:
0 18px 45px rgba(15,23,42,0.95),
0 0 0 1px rgba(15,23,42,1),
inset 0 0 0 1px rgba(56,189,248,0.05);
padding: 10px 10px 10px 10px;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; padding: 10px;
overflow: hidden; overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 10px;
box-shadow:
0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgb(56 189 248 / 5%);
flex-direction: column;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 13px; width: 13px;
height: 13px; height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -172,17 +172,17 @@ onUnmounted(() => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.card-header { .card-header {
display: flex; display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
} }
.card-title { .card-title {
@ -199,9 +199,9 @@ onUnmounted(() => {
} }
.card-body { .card-body {
flex: 1;
min-height: 0;
display: flex; display: flex;
min-height: 0;
flex: 1;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
} }
@ -219,11 +219,11 @@ onUnmounted(() => {
} }
.tag { .tag {
border-radius: 999px;
padding: 2px 6px; padding: 2px 6px;
font-size: 10px; font-size: 10px;
border: 1px solid rgba(148,163,184,0.4);
color: #94a3b8; color: #94a3b8;
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
} }
.metrics-grid { .metrics-grid {
@ -234,11 +234,11 @@ onUnmounted(() => {
} }
.metric-card { .metric-card {
background: radial-gradient(circle at 0 0, rgba(56,189,248,0.16), transparent 70%);
border-radius: 8px;
border: 1px solid rgba(30,64,175,0.9);
padding: 6px 8px;
display: flex; display: flex;
padding: 6px 8px;
background: radial-gradient(circle at 0 0, rgb(56 189 248 / 16%), transparent 70%);
border: 1px solid rgb(30 64 175 / 90%);
border-radius: 8px;
flex-direction: column; flex-direction: column;
gap: 4px; gap: 4px;
} }
@ -255,13 +255,15 @@ onUnmounted(() => {
} }
.metric-value.accent { color: #22d3ee; } .metric-value.accent { color: #22d3ee; }
.metric-value.warn { color: #f59e0b; } .metric-value.warn { color: #f59e0b; }
.metric-value.ok { color: #22c55e; } .metric-value.ok { color: #22c55e; }
.metric-extra { .metric-extra {
display: flex;
font-size: 11px; font-size: 11px;
color: #94a3b8; color: #94a3b8;
display: flex;
justify-content: space-between; justify-content: space-between;
} }
@ -271,7 +273,7 @@ onUnmounted(() => {
min-height: 180px; min-height: 180px;
} }
@media (max-width: 1600px) { @media (width <= 1600px) {
.chart { min-height: 160px; } .chart { min-height: 160px; }
} }
</style> </style>

@ -135,30 +135,30 @@ onUnmounted(() => {
<style scoped> <style scoped>
.card { .card {
background: linear-gradient(135deg, rgba(15, 23, 42, 0.96), rgba(15, 23, 42, 0.88));
border-radius: 10px;
border: 1px solid rgba(30, 64, 175, 0.85);
box-shadow:
0 18px 45px rgba(15, 23, 42, 0.95),
0 0 0 1px rgba(15, 23, 42, 1),
inset 0 0 0 1px rgba(56, 189, 248, 0.05);
padding: 10px 10px 10px 10px;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; padding: 10px;
overflow: hidden; overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 10px;
box-shadow:
0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgb(56 189 248 / 5%);
flex-direction: column;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 13px; width: 13px;
height: 13px; height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56, 189, 248, 0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -171,17 +171,17 @@ onUnmounted(() => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.card-header { .card-header {
display: flex; display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
} }
.card-title { .card-title {
@ -204,19 +204,19 @@ onUnmounted(() => {
} }
.card-body { .card-body {
flex: 1;
min-height: 0;
display: flex; display: flex;
min-height: 0;
flex: 1;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
} }
.tag { .tag {
border-radius: 999px;
padding: 2px 6px; padding: 2px 6px;
font-size: 10px; font-size: 10px;
border: 1px solid rgba(148, 163, 184, 0.4);
color: #94a3b8; color: #94a3b8;
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
} }
.chart { .chart {
@ -230,10 +230,10 @@ onUnmounted(() => {
} }
:deep(.el-select__wrapper) { :deep(.el-select__wrapper) {
background-color: transparent;
border: 1px solid rgba(56, 189, 248, 0.55);
box-shadow: 0 0 18px rgba(56, 189, 248, 0.35);
color: #94a3b8; color: #94a3b8;
background-color: transparent;
border: 1px solid rgb(56 189 248 / 55%);
box-shadow: 0 0 18px rgb(56 189 248 / 35%);
} }
:deep(.el-select__placeholder) { :deep(.el-select__placeholder) {
@ -241,22 +241,22 @@ onUnmounted(() => {
} }
:deep(.energy-type-select .el-input__wrapper) { :deep(.energy-type-select .el-input__wrapper) {
background: radial-gradient(circle at 0 0, rgb(56 189 248 / 22%), transparent 70%);
border-color: rgb(56 189 248 / 85%);
border-radius: 999px; border-radius: 999px;
border-color: rgba(56, 189, 248, 0.85); box-shadow: 0 0 18px rgb(56 189 248 / 45%);
background: radial-gradient(circle at 0 0, rgba(56, 189, 248, 0.22), transparent 70%);
box-shadow: 0 0 18px rgba(56, 189, 248, 0.45);
} }
:deep(.energy-type-select .el-input__wrapper.is-focus) { :deep(.energy-type-select .el-input__wrapper.is-focus) {
border-color: rgba(96, 165, 250, 0.95); background: radial-gradient(circle at 0 0, rgb(59 130 246 / 35%), transparent 70%);
background: radial-gradient(circle at 0 0, rgba(59, 130, 246, 0.35), transparent 70%); border-color: rgb(96 165 250 / 95%);
} }
:deep(.energy-type-select .el-input__inner) { :deep(.energy-type-select .el-input__inner) {
color: #e0f2fe; color: #e0f2fe;
} }
@media (max-width: 1600px) { @media (width <= 1600px) {
.chart { .chart {
min-height: 160px; min-height: 160px;
} }

@ -136,30 +136,30 @@ onUnmounted(() => {
<style scoped> <style scoped>
.card { .card {
background: linear-gradient(135deg, rgba(15,23,42,0.96), rgba(15,23,42,0.88));
border-radius: 10px;
border: 1px solid rgba(30,64,175,0.85);
box-shadow:
0 18px 45px rgba(15,23,42,0.95),
0 0 0 1px rgba(15,23,42,1),
inset 0 0 0 1px rgba(56,189,248,0.05);
padding: 10px 10px 10px 10px;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; padding: 10px;
overflow: hidden; overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 10px;
box-shadow:
0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgb(56 189 248 / 5%);
flex-direction: column;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 13px; width: 13px;
height: 13px; height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -172,17 +172,17 @@ onUnmounted(() => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.card-header { .card-header {
display: flex; display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
} }
.card-title { .card-title {
@ -199,9 +199,9 @@ onUnmounted(() => {
} }
.card-body { .card-body {
flex: 1;
min-height: 0;
display: flex; display: flex;
min-height: 0;
flex: 1;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
} }
@ -219,11 +219,11 @@ onUnmounted(() => {
} }
.tag { .tag {
border-radius: 999px;
padding: 2px 6px; padding: 2px 6px;
font-size: 10px; font-size: 10px;
border: 1px solid rgba(148,163,184,0.4);
color: #94a3b8; color: #94a3b8;
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
} }
.metrics-grid { .metrics-grid {
@ -234,11 +234,11 @@ onUnmounted(() => {
} }
.metric-card { .metric-card {
background: radial-gradient(circle at 0 0, rgba(56,189,248,0.16), transparent 70%);
border-radius: 8px;
border: 1px solid rgba(30,64,175,0.9);
padding: 6px 8px;
display: flex; display: flex;
padding: 6px 8px;
background: radial-gradient(circle at 0 0, rgb(56 189 248 / 16%), transparent 70%);
border: 1px solid rgb(30 64 175 / 90%);
border-radius: 8px;
flex-direction: column; flex-direction: column;
gap: 4px; gap: 4px;
} }
@ -255,13 +255,15 @@ onUnmounted(() => {
} }
.metric-value.accent { color: #22d3ee; } .metric-value.accent { color: #22d3ee; }
.metric-value.warn { color: #f59e0b; } .metric-value.warn { color: #f59e0b; }
.metric-value.ok { color: #22c55e; } .metric-value.ok { color: #22c55e; }
.metric-extra { .metric-extra {
display: flex;
font-size: 11px; font-size: 11px;
color: #94a3b8; color: #94a3b8;
display: flex;
justify-content: space-between; justify-content: space-between;
} }
@ -271,7 +273,7 @@ onUnmounted(() => {
min-height: 180px; min-height: 180px;
} }
@media (max-width: 1600px) { @media (width <= 1600px) {
.chart { min-height: 160px; } .chart { min-height: 160px; }
} }
</style> </style>

@ -132,30 +132,30 @@ onUnmounted(() => {
<style scoped> <style scoped>
.card { .card {
background: linear-gradient(135deg, rgba(15,23,42,0.96), rgba(15,23,42,0.88));
border-radius: 10px;
border: 1px solid rgba(30,64,175,0.85);
box-shadow:
0 18px 45px rgba(15,23,42,0.95),
0 0 0 1px rgba(15,23,42,1),
inset 0 0 0 1px rgba(56,189,248,0.05);
padding: 10px 10px 10px 10px;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; padding: 10px;
overflow: hidden; overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 10px;
box-shadow:
0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgb(56 189 248 / 5%);
flex-direction: column;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 13px; width: 13px;
height: 13px; height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -168,17 +168,17 @@ onUnmounted(() => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.card-header { .card-header {
display: flex; display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
} }
.card-title { .card-title {
@ -195,19 +195,19 @@ onUnmounted(() => {
} }
.card-body { .card-body {
flex: 1;
min-height: 0;
display: flex; display: flex;
min-height: 0;
flex: 1;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
} }
.tag { .tag {
border-radius: 999px;
padding: 2px 6px; padding: 2px 6px;
font-size: 10px; font-size: 10px;
border: 1px solid rgba(148,163,184,0.4);
color: #94a3b8; color: #94a3b8;
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
} }
.chart { .chart {
@ -216,7 +216,7 @@ onUnmounted(() => {
min-height: 180px; min-height: 180px;
} }
@media (max-width: 1600px) { @media (width <= 1600px) {
.chart { min-height: 160px; } .chart { min-height: 160px; }
} }
@ -237,27 +237,27 @@ onUnmounted(() => {
} }
.tab-btn { .tab-btn {
cursor: pointer;
user-select: none;
border-radius: 999px;
border: 1px solid rgba(148, 163, 184, 0.55);
background: rgba(2, 6, 23, 0.28);
color: var(--muted);
padding: 3px 8px; padding: 3px 8px;
font-size: 10px; font-size: 10px;
line-height: 1; line-height: 1;
color: var(--muted);
cursor: pointer;
background: rgb(2 6 23 / 28%);
border: 1px solid rgb(148 163 184 / 55%);
border-radius: 999px;
transition: border-color 0.25s, box-shadow 0.25s, color 0.25s, background 0.25s; transition: border-color 0.25s, box-shadow 0.25s, color 0.25s, background 0.25s;
user-select: none;
} }
.tab-btn:hover { .tab-btn:hover {
border-color: rgba(56, 189, 248, 0.9);
color: #e0f2fe; color: #e0f2fe;
border-color: rgb(56 189 248 / 90%);
} }
.tab-btn.active { .tab-btn.active {
border-color: rgba(34, 211, 238, 0.9);
color: #e0f2fe; color: #e0f2fe;
box-shadow: 0 0 14px rgba(34, 211, 238, 0.45); background: radial-gradient(circle at 0 0, rgb(34 211 238 / 32%), rgb(2 6 23 / 20%) 60%);
background: radial-gradient(circle at 0 0, rgba(34, 211, 238, 0.32), rgba(2, 6, 23, 0.2) 60%); border-color: rgb(34 211 238 / 90%);
box-shadow: 0 0 14px rgb(34 211 238 / 45%);
} }
</style> </style>

@ -118,30 +118,30 @@ onMounted(async () => {
<style scoped> <style scoped>
.card { .card {
background: linear-gradient(135deg, rgba(15,23,42,0.96), rgba(15,23,42,0.88));
border-radius: 10px;
border: 1px solid rgba(30,64,175,0.85);
box-shadow:
0 18px 45px rgba(15,23,42,0.95),
0 0 0 1px rgba(15,23,42,1),
inset 0 0 0 1px rgba(56,189,248,0.05);
padding: 10px 10px 10px 10px;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; padding: 10px;
overflow: hidden; overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 10px;
box-shadow:
0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgb(56 189 248 / 5%);
flex-direction: column;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 13px; width: 13px;
height: 13px; height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -154,17 +154,17 @@ onMounted(async () => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.card-header { .card-header {
display: flex; display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
} }
.card-title { .card-title {
@ -181,19 +181,19 @@ onMounted(async () => {
} }
.card-body { .card-body {
flex: 1;
min-height: 0;
display: flex; display: flex;
min-height: 0;
flex: 1;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
} }
.tag { .tag {
border-radius: 999px;
padding: 2px 6px; padding: 2px 6px;
font-size: 10px; font-size: 10px;
border: 1px solid rgba(148,163,184,0.4);
color: #94a3b8; color: #94a3b8;
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
} }
.chart { .chart {
@ -202,7 +202,7 @@ onMounted(async () => {
min-height: 180px; min-height: 180px;
} }
@media (max-width: 1600px) { @media (width <= 1600px) {
.chart { min-height: 160px; } .chart { min-height: 160px; }
} }
</style> </style>

@ -114,30 +114,30 @@ onUnmounted(() => {
<style scoped> <style scoped>
.card { .card {
background: linear-gradient(135deg, rgba(15,23,42,0.96), rgba(15,23,42,0.88));
border-radius: 10px;
border: 1px solid rgba(30,64,175,0.85);
box-shadow:
0 18px 45px rgba(15,23,42,0.95),
0 0 0 1px rgba(15,23,42,1),
inset 0 0 0 1px rgba(56,189,248,0.05);
padding: 10px 10px 10px 10px;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; padding: 10px;
overflow: hidden; overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 10px;
box-shadow:
0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgb(56 189 248 / 5%);
flex-direction: column;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 13px; width: 13px;
height: 13px; height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -150,17 +150,17 @@ onUnmounted(() => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.card-header { .card-header {
display: flex; display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
} }
.card-title { .card-title {
@ -177,50 +177,52 @@ onUnmounted(() => {
} }
.card-body { .card-body {
flex: 1;
min-height: 0;
display: flex; display: flex;
min-height: 0;
overflow: hidden; /* Ensure list stays within */
flex: 1;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
overflow: hidden; /* Ensure list stays within */
} }
.tag { .tag {
border-radius: 999px;
padding: 2px 6px; padding: 2px 6px;
font-size: 10px; font-size: 10px;
border: 1px solid rgba(148,163,184,0.4);
color: #94a3b8; color: #94a3b8;
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
} }
.alarm-list { .alarm-list {
list-style: none;
margin: 0;
padding: 0;
display: flex; display: flex;
flex-direction: column;
gap: 6px;
height: 100%; height: 100%;
padding: 0;
margin: 0;
overflow: hidden; overflow: hidden;
list-style: none;
flex-direction: column;
gap: 6px;
} }
.alarm-item { .alarm-item {
display: flex; display: flex;
align-items: center;
gap: 8px;
padding: 7px 8px; padding: 7px 8px;
border-radius: 6px;
background: rgba(15,23,42,0.92);
border: 1px solid rgba(30,64,175,0.9);
font-size: 11px; font-size: 11px;
color: #e5f0ff; color: #e5f0ff;
background: rgb(15 23 42 / 92%);
border: 1px solid rgb(30 64 175 / 90%);
border-radius: 6px;
transition: background 0.3s, box-shadow 0.3s; transition: background 0.3s, box-shadow 0.3s;
align-items: center;
gap: 8px;
flex-shrink: 0; /* Prevent shrinking */ flex-shrink: 0; /* Prevent shrinking */
} }
.alarm-item.danger { border-left: 3px solid #ef4444; box-shadow: 0 0 18px rgba(239,68,68,0.4); } .alarm-item.danger { border-left: 3px solid #ef4444; box-shadow: 0 0 18px rgb(239 68 68 / 40%); }
.alarm-item.warn { border-left: 3px solid #f59e0b; box-shadow: 0 0 14px rgba(245,158,11,0.35); }
.alarm-item.safe { border-left: 3px solid #22c55e; box-shadow: 0 0 12px rgba(34,197,94,0.35); } .alarm-item.warn { border-left: 3px solid #f59e0b; box-shadow: 0 0 14px rgb(245 158 11 / 35%); }
.alarm-item.safe { border-left: 3px solid #22c55e; box-shadow: 0 0 12px rgb(34 197 94 / 35%); }
.alarm-time { .alarm-time {
width: 64px; width: 64px;
@ -229,24 +231,24 @@ onUnmounted(() => {
} }
.alarm-msg { .alarm-msg {
flex: 1;
white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
} }
.alarm-level { .alarm-level {
flex: 0 0 auto;
border-radius: 999px;
padding: 2px 6px; padding: 2px 6px;
border: 1px solid rgba(148,163,184,0.6);
font-size: 10px; font-size: 10px;
border: 1px solid rgb(148 163 184 / 60%);
border-radius: 999px;
flex: 0 0 auto;
} }
/* Animation class */ /* Animation class */
.animating-out { .animating-out {
transition: all 0.35s;
transform: translateY(-48px);
opacity: 0; opacity: 0;
transform: translateY(-48px);
transition: all 0.35s;
} }
</style> </style>

@ -125,30 +125,30 @@ onUnmounted(() => {
<style scoped> <style scoped>
.card { .card {
background: linear-gradient(135deg, rgba(15,23,42,0.96), rgba(15,23,42,0.88));
border-radius: 10px;
border: 1px solid rgba(30,64,175,0.85);
box-shadow:
0 18px 45px rgba(15,23,42,0.95),
0 0 0 1px rgba(15,23,42,1),
inset 0 0 0 1px rgba(56,189,248,0.05);
padding: 10px 10px 10px 10px;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; padding: 10px;
overflow: hidden; overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 10px;
box-shadow:
0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgb(56 189 248 / 5%);
flex-direction: column;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 13px; width: 13px;
height: 13px; height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -161,17 +161,17 @@ onUnmounted(() => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.card-header { .card-header {
display: flex; display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
} }
.card-title { .card-title {
@ -188,9 +188,9 @@ onUnmounted(() => {
} }
.card-body { .card-body {
flex: 1;
min-height: 0;
display: flex; display: flex;
min-height: 0;
flex: 1;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
} }
@ -204,11 +204,11 @@ onUnmounted(() => {
} }
.tag { .tag {
border-radius: 999px;
padding: 2px 6px; padding: 2px 6px;
font-size: 10px; font-size: 10px;
border: 1px solid rgba(148,163,184,0.4);
color: #94a3b8; color: #94a3b8;
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
} }
.dot { .dot {
@ -219,30 +219,30 @@ onUnmounted(() => {
/* Scoped styles specific to this component but we expect common styles from parent */ /* Scoped styles specific to this component but we expect common styles from parent */
.table-shell { .table-shell {
flex: 1; position: relative;
min-height: 0; min-height: 0;
overflow: hidden; overflow: hidden;
position: relative; flex: 1;
} }
.task-table { .task-table {
width: 100%; width: 100%;
font-size: 12px;
border-collapse: separate; border-collapse: separate;
border-spacing: 0 5px; border-spacing: 0 5px;
table-layout: fixed; table-layout: fixed;
font-size: 12px;
} }
.task-table thead { .task-table thead {
background: radial-gradient(circle at 0 0, rgba(56, 189, 248, 0.18), transparent 70%); background: radial-gradient(circle at 0 0, rgb(56 189 248 / 18%), transparent 70%);
} }
.task-table thead th { .task-table thead th {
padding: 6px 4px; padding: 6px 4px;
color: var(--accent);
font-weight: 600; font-weight: 600;
color: var(--accent);
text-align: center; text-align: center;
border-bottom: 1px solid rgba(51, 65, 85, 0.9); border-bottom: 1px solid rgb(51 65 85 / 90%);
} }
.task-table tbody { .task-table tbody {
@ -260,28 +260,28 @@ onUnmounted(() => {
.task-table tbody td { .task-table tbody td {
padding: 6px 4px; padding: 6px 4px;
text-align: center;
color: var(--text); color: var(--text);
background: rgba(15, 23, 42, 0.88); text-align: center;
background: rgb(15 23 42 / 88%);
border: 1px solid rgb(30 64 175 / 70%);
border-radius: 4px; border-radius: 4px;
border: 1px solid rgba(30, 64, 175, 0.7);
} }
.task-table tbody tr:nth-child(even) td { .task-table tbody tr:nth-child(even) td {
background: rgba(15, 23, 42, 0.96); background: rgb(15 23 42 / 96%);
} }
.task-table tbody tr:hover td { .task-table tbody tr:hover td {
border-color: rgba(56, 189, 248, 0.95); border-color: rgb(56 189 248 / 95%);
box-shadow: 0 0 14px rgba(56, 189, 248, 0.45); box-shadow: 0 0 14px rgb(56 189 248 / 45%);
} }
.progress-bar { .progress-bar {
height: 6px; height: 6px;
background: rgba(15, 23, 42, 1);
border-radius: 999px;
overflow: hidden; overflow: hidden;
border: 1px solid rgba(148, 163, 184, 0.45); background: rgb(15 23 42 / 100%);
border: 1px solid rgb(148 163 184 / 45%);
border-radius: 999px;
} }
.progress-fill { .progress-fill {

@ -108,30 +108,30 @@ onUnmounted(() => {
<style scoped> <style scoped>
.card { .card {
background: linear-gradient(135deg, rgba(15,23,42,0.96), rgba(15,23,42,0.88));
border-radius: 10px;
border: 1px solid rgba(30,64,175,0.85);
box-shadow:
0 18px 45px rgba(15,23,42,0.95),
0 0 0 1px rgba(15,23,42,1),
inset 0 0 0 1px rgba(56,189,248,0.05);
padding: 10px 10px 10px 10px;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; padding: 10px;
overflow: hidden; overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 10px;
box-shadow:
0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgb(56 189 248 / 5%);
flex-direction: column;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 13px; width: 13px;
height: 13px; height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -144,17 +144,17 @@ onUnmounted(() => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.card-header { .card-header {
display: flex; display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
} }
.card-title { .card-title {
@ -171,23 +171,23 @@ onUnmounted(() => {
} }
.card-body { .card-body {
flex: 1;
min-height: 0;
display: flex; display: flex;
min-height: 0;
flex: 1;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
} }
.chip { .chip {
border-radius: 999px;
border: 1px solid rgba(148,163,184,0.5);
padding: 4px 10px;
display: inline-flex; display: inline-flex;
padding: 4px 10px;
font-size: 12px;
color: #94a3b8;
background: rgb(15 23 42 / 75%);
border: 1px solid rgb(148 163 184 / 50%);
border-radius: 999px;
align-items: center; align-items: center;
gap: 6px; gap: 6px;
background: rgba(15,23,42,0.75);
color: #94a3b8;
font-size: 12px;
} }
.chart { .chart {
@ -196,7 +196,7 @@ onUnmounted(() => {
min-height: 180px; min-height: 180px;
} }
@media (max-width: 1600px) { @media (width <= 1600px) {
.chart { min-height: 160px; } .chart { min-height: 160px; }
} }
</style> </style>

@ -96,30 +96,30 @@ onUnmounted(() => {
<style scoped> <style scoped>
.card { .card {
background: linear-gradient(135deg, rgba(15,23,42,0.96), rgba(15,23,42,0.88));
border-radius: 10px;
border: 1px solid rgba(30,64,175,0.85);
box-shadow:
0 18px 45px rgba(15,23,42,0.95),
0 0 0 1px rgba(15,23,42,1),
inset 0 0 0 1px rgba(56,189,248,0.05);
padding: 10px 10px 10px 10px;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; padding: 10px;
overflow: hidden; overflow: hidden;
background: linear-gradient(135deg, rgb(15 23 42 / 96%), rgb(15 23 42 / 88%));
border: 1px solid rgb(30 64 175 / 85%);
border-radius: 10px;
box-shadow:
0 18px 45px rgb(15 23 42 / 95%),
0 0 0 1px rgb(15 23 42 / 100%),
inset 0 0 0 1px rgb(56 189 248 / 5%);
flex-direction: column;
} }
.card::before, .card::before,
.card::after { .card::after {
content: "";
position: absolute; position: absolute;
width: 13px; width: 13px;
height: 13px; height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px; border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75); content: "";
opacity: 0.6; opacity: 0.6;
pointer-events: none;
} }
.card::before { .card::before {
@ -132,17 +132,17 @@ onUnmounted(() => {
.card::after { .card::after {
right: -1px; right: -1px;
bottom: -1px; bottom: -1px;
border-left: none;
border-top: none; border-top: none;
border-left: none;
} }
.card-header { .card-header {
display: flex; display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
} }
.card-title { .card-title {
@ -159,9 +159,9 @@ onUnmounted(() => {
} }
.card-body { .card-body {
flex: 1;
min-height: 0;
display: flex; display: flex;
min-height: 0;
flex: 1;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
} }
@ -186,7 +186,7 @@ onUnmounted(() => {
min-height: 180px; min-height: 180px;
} }
@media (max-width: 1600px) { @media (width <= 1600px) {
.chart { min-height: 160px; } .chart { min-height: 160px; }
} }
</style> </style>

@ -73,12 +73,23 @@ import EnergyTrend from './components/EnergyTrend.vue'
</script> </script>
<style scoped> <style scoped>
/* Define CSS Variables locally for this dashboard */
@keyframes scanDown {
0% { transform: translateY(-100%); }
100% { transform: translateY(260%); }
}
@media (width <= 1366px) {
/* Adjust if needed, but flex: 1 should handle it automatically */
}
.dashboard-container { .dashboard-container {
--bg: #050816; --bg: #050816;
--bg-deep: #020617; --bg-deep: #020617;
--card-bg: rgba(15, 23, 42, 0.86); --card-bg: rgb(15 23 42 / 86%);
--border: rgba(56, 189, 248, 0.35); --border: rgb(56 189 248 / 35%);
--text: #e5f0ff; --text: #e5f0ff;
--muted: #94a3b8; --muted: #94a3b8;
--primary: #38bdf8; --primary: #38bdf8;
@ -92,37 +103,37 @@ import EnergyTrend from './components/EnergyTrend.vue'
--header-h: 86px; --header-h: 86px;
position: relative; position: relative;
display: flex;
width: 100%; width: 100%;
min-height: 100vh; min-height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden; overflow: hidden;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Microsoft Yahei", Arial, sans-serif; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Microsoft Yahei", Arial, sans-serif;
color: var(--text); color: var(--text);
background-color: var(--bg-deep); background-color: var(--bg-deep);
background-image: background-image:
radial-gradient(circle at 20% 0, rgba(56, 189, 248, 0.26) 0, transparent 48%), radial-gradient(circle at 20% 0, rgb(56 189 248 / 26%) 0, transparent 48%),
radial-gradient(circle at 80% 110%, rgba(129, 140, 248, 0.22) 0, transparent 52%), radial-gradient(circle at 80% 110%, rgb(129 140 248 / 22%) 0, transparent 52%),
linear-gradient(135deg, #020617 0%, #020617 45%, #020617 100%); linear-gradient(135deg, #020617 0%, #020617 45%, #020617 100%);
flex-direction: column;
} }
.bg-grid { .bg-grid {
position: absolute; position: absolute;
inset: 0; z-index: 0;
pointer-events: none; pointer-events: none;
background-image: linear-gradient(rgba(15,23,42,0.8) 1px, transparent 1px), background-image: linear-gradient(rgb(15 23 42 / 80%) 1px, transparent 1px),
linear-gradient(90deg, rgba(15,23,42,0.8) 1px, transparent 1px); linear-gradient(90deg, rgb(15 23 42 / 80%) 1px, transparent 1px);
background-size: 70px 70px; background-size: 70px 70px;
opacity: 0.55; opacity: 0.55;
z-index: 0; inset: 0;
} }
.bg-scan { .bg-scan {
position: absolute; position: absolute;
inset: 0; z-index: 0;
overflow: hidden; overflow: hidden;
pointer-events: none; pointer-events: none;
z-index: 0; inset: 0;
} }
.scan-line { .scan-line {
@ -131,37 +142,32 @@ import EnergyTrend from './components/EnergyTrend.vue'
left: 0; left: 0;
width: 100%; width: 100%;
height: 40%; height: 40%;
background: radial-gradient(circle at 50% 0, rgba(56, 189, 248, 0.38), transparent 70%); background: radial-gradient(circle at 50% 0, rgb(56 189 248 / 38%), transparent 70%);
opacity: 0.5; opacity: 0.5;
filter: blur(32px); filter: blur(32px);
animation: scanDown 16s linear infinite; animation: scanDown 16s linear infinite;
} }
@keyframes scanDown {
0% { transform: translateY(-100%); }
100% { transform: translateY(260%); }
}
main { main {
flex: 1;
padding: 8px var(--gap) var(--gap);
position: relative; position: relative;
z-index: 1; z-index: 1;
display: flex; display: flex;
min-height: 0;
padding: 8px var(--gap) var(--gap);
flex: 1;
flex-direction: column; flex-direction: column;
gap: var(--gap); gap: var(--gap);
min-height: 0;
} }
.layout { .layout {
flex: 1;
display: flex; display: flex;
flex-direction: column;
gap: var(--gap);
max-width: 1920px;
margin: 0 auto;
width: 100%; /* Ensure full width */ width: 100%; /* Ensure full width */
max-width: 1920px;
min-height: 0; min-height: 0;
margin: 0 auto;
flex: 1;
flex-direction: column;
gap: var(--gap);
} }
.row-1, .row-2, .row-3 { .row-1, .row-2, .row-3 {
@ -188,7 +194,5 @@ main {
height: 100% !important; height: 100% !important;
} }
@media (max-width: 1366px) { /* Define CSS Variables locally for this dashboard */
/* Adjust if needed, but flex: 1 should handle it automatically */
}
</style> </style>

Loading…
Cancel
Save