Compare commits

...

8 Commits

@ -13,6 +13,7 @@ export interface TicketManagementVO {
jobUser?: string
taskTime?: string
taskEndTime?: string
cancelReason?: string
remark?: string
creator?: string
createTime?: string
@ -41,7 +42,7 @@ export const TicketManagementApi = {
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 })
},

@ -15,6 +15,7 @@ export interface ZjTaskVO {
executorId: string
executorName: string
status: string
cancelReason?: string
result: string
createTime: string
roleIds?: number[]
@ -54,6 +55,10 @@ export const ZjTaskApi = {
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) => {
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 })
},
updateMoldRepairStatus: async (data: any) => {
return await request.put({ url: `/mes/mold-repair/updateMoldRepairStatus`, data })
},
getMoldRepairLineListByRepairId: async (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
taskTime?: string
taskEndTime?: string
cancelReason?: string
remark?: string
creator?: string
createTime?: string
@ -37,7 +38,7 @@ export const TicketManagementApi = {
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 })
},

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',
confirmDate: 'Acceptance Date',
repairResult: 'Repair Result',
repairResultPending: 'Pending Repair',
repairResultOk: 'Pass',
repairResultNg: 'Fail',
repairStatus: 'Result',
status: 'Order Status',
statusPending: 'Pending',
statusDone: 'Completed',
@ -1942,10 +1946,15 @@ export default {
subjectCode: 'Repair Code',
subjectName: 'Repair Name',
subjectContent: 'Repair Content',
remark: 'Remark',
result: 'Result',
resultOk: 'Pass',
resultNg: 'Fail',
addLine: 'Add Repair Item',
placeholderSubjectCode: 'Please input repair code',
placeholderSubjectName: 'Please input repair name',
placeholderSubjectContent: 'Please input repair content',
placeholderRemark: 'Please input remark',
validatorRepairIdRequired: 'Repair order id can not be empty',
validatorSubjectIdRequired: 'Item id can not be empty',
validatorSubjectCodeRequired: 'Item code can not be empty',
@ -2169,6 +2178,8 @@ export default {
createTime: 'Create Time',
operate: 'Operate',
inspect: 'Inspect',
cancelTask: 'Cancel Task',
cancelSuccess: 'Cancel task successfully',
exportFilename: 'Quality-InspectionTask.xls',
placeholderCode: 'Please input code',
placeholderType: 'Please select inspection category',
@ -2418,5 +2429,631 @@ export default {
manualTableReferColumn: 'Reference Value',
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: '完成日期',
confirmDate: '验收日期',
repairResult: '维修结果',
repairResultPending: '待维修',
repairResultOk: '通过',
repairResultNg: '不通过',
repairStatus: '结果',
status: '单据状态',
statusPending: '待完成',
statusDone: '已完成',
@ -1525,10 +1529,15 @@ export default {
subjectCode: '维修编码',
subjectName: '维修名称',
subjectContent: '维修内容',
remark: '备注',
result: '结果',
resultOk: '通过',
resultNg: '不通过',
addLine: '添加维修项目',
placeholderSubjectCode: '请输入维修编码',
placeholderSubjectName: '请输入维修名称',
placeholderSubjectContent: '请输入维修内容',
placeholderRemark: '请输入备注',
validatorRepairIdRequired: '维修单ID不能为空',
validatorSubjectIdRequired: '项目ID不能为空',
validatorSubjectCodeRequired: '项目编码不能为空',
@ -1752,6 +1761,8 @@ export default {
createTime: '创建时间',
operate: '操作',
inspect: '检验',
cancelTask: '取消任务',
cancelSuccess: '取消任务成功',
exportFilename: '质量管理-检验任务.xls',
placeholderCode: '请输入单号',
placeholderType: '请选择质检分类',
@ -2410,5 +2421,628 @@ export default {
validatorStatusRequired: '单位状态不能为空',
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()
</script>
<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 {
display: flex;
flex-direction: column;
@ -945,10 +963,12 @@ getAllApi()
top: 50%;
transform: translateY(-50%);
}
/* 左箭头往右移动 */
.progress-carousel :deep(.el-carousel__arrow--left) {
transform: translate(30px, -50%); /* X轴移动30pxY轴居中 */
}
/* 右箭头往左移动 */
.progress-carousel :deep(.el-carousel__arrow--right) {
transform: translate(-30px, -50%); /* X轴移动-30pxY轴居中 */
@ -1055,20 +1075,4 @@ getAllApi()
font-size: 12px;
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>

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

@ -150,41 +150,35 @@
</el-col>
<el-col :span="24">
<el-form-item :label="t('EquipmentManagement.EquipmentLedger.criticalComponent')" prop="componentIds">
<el-select
v-model="formData.componentIds"
multiple
<el-cascader
v-model="criticalComponentCascaderValue"
:options="criticalComponentPagedOptions"
:props="cascaderProps"
filterable
clearable
collapse-tags
:show-all-levels="false"
:placeholder="t('EquipmentManagement.EquipmentLedger.placeholderComponentIds')"
class="!w-full"
>
<el-option
v-for="item in criticalComponentOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
@change="handleCriticalComponentChange"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="t('EquipmentManagement.EquipmentLedger.sparePart')" prop="beijianIds">
<el-select
v-model="formData.beijianIds"
multiple
<el-cascader
v-model="beijianCascaderValue"
:options="beijianPagedOptions"
:props="cascaderProps"
filterable
clearable
collapse-tags
:show-all-levels="false"
:placeholder="t('EquipmentManagement.EquipmentLedger.placeholderBeijianIds')"
class="!w-full"
>
<el-option
v-for="item in beijianOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
@change="handleBeijianChange"
/>
</el-form-item>
</el-col>
@ -294,6 +288,31 @@ const deviceTypeTree = ref<DeviceTypeTreeVO[]>([])
const users = ref<UserVO[]>([])
const criticalComponentOptions = 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 [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) => {
dialogVisible.value = true

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -8,15 +8,15 @@
:inline-message="true"
>
<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="产品" min-width="150">
<el-table-column :label="t('ProductionPlan.Task.saleDetailTableIndexColumn')" type="index" width="80" />
<el-table-column :label="t('ProductionPlan.Task.saleDetailTableProductColumn')" min-width="150">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.productId`" :rules="formRules.productId" class="mb-0px!">
<el-select
v-model="row.productId"
clearable
filterable
placeholder="请选择"
:placeholder="t('ProductionPlan.Task.saleDetailProductPlaceholder')"
>
<el-option
v-for="item in productList"
@ -28,7 +28,7 @@
</el-form-item>
</template>
</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 }">
<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">
@ -43,49 +43,49 @@
</template>
</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 }">
<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-form-item>
</template>
</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 }">
<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-form-item>
</template>
</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 }">
<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-form-item>
</template>
</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 }">
<el-form-item :prop="`${$index}.projectName`" :rules="formRules.projectName" class="mb-0px!">
<el-input v-model="row.projectName" placeholder="" />
</el-form-item>
</template>
</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 }">
<el-form-item :prop="`${$index}.techRequirements`" :rules="formRules.techRequirements" class="mb-0px!">
<el-input v-model="row.techRequirements" placeholder="" />
</el-form-item>
</template>
</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 }">
<el-form-item :prop="`${$index}.remark`" :rules="formRules.remark" class="mb-0px!">
<el-input v-model="row.remark" placeholder="" />
</el-form-item>
</template>
</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 }">
<el-form-item :prop="`${$index}.finishDate`" :rules="formRules.finishDate" class="mb-0px!">
<el-date-picker
@ -97,7 +97,7 @@
</el-form-item>
</template>
</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 }">
<el-form-item :prop="`${$index}.boxingDate`" :rules="formRules.boxingDate" class="mb-0px!">
<el-date-picker
@ -109,7 +109,7 @@
</el-form-item>
</template>
</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 }">
<el-form-item :prop="`${$index}.arriveDate`" :rules="formRules.arriveDate" class="mb-0px!">
<el-date-picker
@ -121,7 +121,7 @@
</el-form-item>
</template>
</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 }">
<el-form-item :prop="`${$index}.barCode`" :rules="formRules.barCode" class="mb-0px!">
<el-input v-model="row.barCode" placeholder="" />
@ -129,7 +129,7 @@
</template>
</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 }">
<el-button type="danger" @click="handleDelete($index)" link>
<Icon icon="ep:delete" />
@ -139,8 +139,8 @@
</el-table>
</el-form>
<el-row justify="center" class="mt-3">
<el-button @click="handleAdd" round>+ 添加任务单明细</el-button>
<el-button @click="openOrderItemsList" round>+ 从销售单添加</el-button>
<el-button @click="handleAdd" round>{{ t('ProductionPlan.Task.saleDetailAddRowButtonText') }}</el-button>
<el-button @click="openOrderItemsList" round>{{ t('ProductionPlan.Task.saleDetailAddFromOrderButtonText') }}</el-button>
</el-row>
<el-row>
<SaleOrderIndex ref="orderItemsRef" @success="dealOrder"/>
@ -156,16 +156,18 @@ import {SaleOrderApi, SaleOrderItemsVO, SaleOrderVO} from "@/api/mes/saleorder";
const unitList = ref<ProductUnitVO[]>([]) //
const productList = ref<ProductVO[]>([]) //
const { t } = useI18n()
const props = defineProps<{
taskId?: undefined // task ID
}>()
const formLoading = ref(false) //
const formData = ref([])
const formRules = reactive({
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }],
unitId: [{ required: true, message: '单位不能为空', trigger: 'blur' }],
taskId: [{ required: true, message: '生产任务不能为空', trigger: 'blur' }],
number: [{ required: true, message: '数量不能为空', trigger: 'blur' }],
productId: [{ required: true, message: t('ProductionPlan.Task.validatorRowProductRequired'), trigger: 'blur' }],
unitId: [{ required: true, message: t('ProductionPlan.Task.validatorRowUnitRequired'), trigger: 'blur' }],
taskId: [{ required: true, message: t('ProductionPlan.Task.validatorRowTaskRequired'), trigger: 'blur' }],
number: [{ required: true, message: t('ProductionPlan.Task.validatorRowNumberRequired'), trigger: 'blur' }],
})
const formRef = ref() // Ref

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

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

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

@ -2,77 +2,77 @@
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
class="-mb-15px task-search-form"
:model="queryParams"
ref="queryFormRef"
: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
v-model="queryParams.code"
placeholder="请输入编码"
:placeholder="t('ProductionPlan.Task.searchCodePlaceholder')"
clearable
@keyup.enter="handleQuery"
class="!w-180px"
/>
</el-form-item>
<el-form-item label="下达" prop="orderDate">
<el-form-item :label="t('ProductionPlan.Task.searchOrderLabel')" prop="orderDate">
<el-date-picker
v-model="queryParams.orderDate"
value-format="YYYY-MM-DD HH:mm:ss"
@change="handleQuery"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
:start-placeholder="t('ProductionPlan.Task.searchOrderStartPlaceholder')"
:end-placeholder="t('ProductionPlan.Task.searchOrderEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-180px"
/>
</el-form-item>
<el-form-item label="交货" prop="deliveryDate">
<el-form-item :label="t('ProductionPlan.Task.searchDeliveryLabel')" prop="deliveryDate">
<el-date-picker
v-model="queryParams.deliveryDate"
@change="handleQuery"
value-format="YYYY-MM-DD HH:mm:ss"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
:start-placeholder="t('ProductionPlan.Task.searchDeliveryStartPlaceholder')"
:end-placeholder="t('ProductionPlan.Task.searchDeliveryEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-180px"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-form-item :label="t('ProductionPlan.Task.searchRemarkLabel')" prop="remark">
<el-input
v-model="queryParams.remark"
placeholder="请输入备注"
:placeholder="t('ProductionPlan.Task.searchRemarkPlaceholder')"
clearable
@keyup.enter="handleQuery"
class="!w-180px"
/>
</el-form-item>
<el-form-item label="创建时间" prop="createTime">
<el-form-item :label="t('ProductionPlan.Task.searchCreateTimeLabel')" prop="createTime">
<el-date-picker
v-model="queryParams.createTime"
@change="handleQuery"
value-format="YYYY-MM-DD HH:mm:ss"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
:start-placeholder="t('ProductionPlan.Task.searchCreateTimeStartPlaceholder')"
:end-placeholder="t('ProductionPlan.Task.searchCreateTimeEndPlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" 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" /> {{ t('ProductionPlan.Task.buttonResetText') }}</el-button>
<el-button
type="primary"
plain
@click="openForm('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
type="success"
@ -81,7 +81,7 @@
:loading="exportLoading"
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-form-item>
</el-form>
@ -90,14 +90,14 @@
<!-- 列表 -->
<ContentWrap>
<el-tabs v-model="activeName" @tab-click="handleTabClick">
<el-tab-pane label="所有" name="" />
<el-tab-pane label="草稿" name="0" />
<el-tab-pane label="送审" name="1" />
<el-tab-pane label="下达" name="2" />
<el-tab-pane label="计划" name="3" />
<el-tab-pane label="开工" name="4" />
<el-tab-pane label="完工" name="5" />
<el-tab-pane label="入库" name="6" />
<el-tab-pane :label="t('ProductionPlan.Task.tabAllLabel')" name="" />
<el-tab-pane :label="t('ProductionPlan.Task.tabDraftLabel')" name="0" />
<el-tab-pane :label="t('ProductionPlan.Task.tabSubmitLabel')" name="1" />
<el-tab-pane :label="t('ProductionPlan.Task.tabIssuedLabel')" name="2" />
<el-tab-pane :label="t('ProductionPlan.Task.tabPlanLabel')" name="3" />
<el-tab-pane :label="t('ProductionPlan.Task.tabStartLabel')" name="4" />
<el-tab-pane :label="t('ProductionPlan.Task.tabFinishedLabel')" name="5" />
<el-tab-pane :label="t('ProductionPlan.Task.tabStoredLabel')" name="6" />
</el-tabs>
<el-table
v-loading="loading"
@ -107,41 +107,41 @@
highlight-current-row
@current-change="handleCurrentChange"
>
<el-table-column label="编码" align="center" prop="code" width="150px"/>
<el-table-column label="下达日期" align="center" prop="orderDate" :formatter="dateFormatter2" />
<el-table-column label="交货日期" align="center" prop="deliveryDate" :formatter="dateFormatter2"/>
<el-table-column label="类型" align="center" prop="taskType">
<el-table-column :label="t('ProductionPlan.Task.tableCodeColumn')" align="center" prop="code" width="150px"/>
<el-table-column :label="t('ProductionPlan.Task.tableOrderDateColumn')" align="center" prop="orderDate" :formatter="dateFormatter2" />
<el-table-column :label="t('ProductionPlan.Task.tableDeliveryDateColumn')" align="center" prop="deliveryDate" :formatter="dateFormatter2"/>
<el-table-column :label="t('ProductionPlan.Task.tableTaskTypeColumn')" align="center" prop="taskType">
<template #default="scope">
<dict-tag :type="DICT_TYPE.MES_TASK_TYPE" :value="scope.row.taskType" />
</template>
</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">
<dict-tag :type="DICT_TYPE.MES_TASK_STATUS" :value="scope.row.status" />
</template>
</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">
<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 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 link type="info" @click="openItemNeed(scope.row.code, scope.row.id)" v-hasPermi="['mes:task:update']">
物料
{{ t('ProductionPlan.Task.actionMaterialLabel') }}
</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> -->
<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 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>
</template>
</el-table-column>
@ -162,7 +162,7 @@
<!-- 子表的列表 -->
<ContentWrap>
<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"/>
</el-tab-pane>
<!-- <el-tab-pane label="任务单明细进度" name="taskDetailProgress">-->

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

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

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

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

@ -102,6 +102,13 @@
@size-change="handleSizeChange"
@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>
<el-button @click="dialogVisible = false">{{ t('EquipmentManagement.WorkOrderManagement.dialogCancel') }}</el-button>
<el-button
@ -133,6 +140,8 @@ const submitLoading = ref(false)
const list = ref<TicketResultVO[]>([])
const total = ref(0)
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 imageMap = reactive<Record<string, string>>({})
@ -141,10 +150,12 @@ const queryParams = reactive({
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
dialogTitle.value = options.title || t('EquipmentManagement.WorkOrderManagement.dialogTitleDefault')
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(imageMap)) delete imageMap[key]
queryParams.pageNo = 1

@ -260,9 +260,18 @@ const handleSelectionChange = (rows: TicketManagementVO[]) => {
const handleBatchCancel = async () => {
if (!selectedIds.value.length) return
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
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'))
selectedIds.value = []
await getList()
@ -297,6 +306,8 @@ const handleRowClick = async (row: TicketManagementVO, column: any) => {
if (!row?.id) return
await resultDialogRef.value?.open({
managementId: row.id,
jobStatus: row.jobStatus,
cancelReason: row.cancelReason,
title: row.planNo
? `${t('EquipmentManagement.WorkOrderManagement.dialogTitleDefault')}-${row.planNo}`
: t('EquipmentManagement.WorkOrderManagement.dialogTitleDefault')

@ -133,6 +133,13 @@
@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>
<el-button @click="dialogVisible = false">
{{ t('QualityManagement.TicketResultDialog.cancel') }}
@ -152,6 +159,7 @@
<script setup lang="ts">
import type { ZjTaskResultVO } from '@/api/mes/zjtask'
import { ZjTaskApi } from '@/api/mes/zjtask'
import { DictTag } from '@/components/DictTag'
defineOptions({ name: 'ZjTaskResultDialog' })
@ -167,6 +175,8 @@ const message = useMessage()
const list = ref<ZjTaskResultVO[]>([])
const total = ref(0)
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 imageMap = reactive<Record<string, string>>({})
@ -175,10 +185,12 @@ const queryParams = reactive({
pageSize: 10,
})
const open = async (id: number) => {
const open = async (options: { id: number; status?: string | number; cancelReason?: string }) => {
dialogVisible.value = true
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(imageMap)) delete imageMap[key]
queryParams.pageNo = 1

@ -90,6 +90,17 @@ type="success" plain @click="handleExport" :loading="exportLoading"
</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
v-loading="loading"
:data="list"
@ -216,6 +227,7 @@ const exportLoading = ref(false)
const orgTypeOptions = getStrDictOptions(DICT_TYPE.MES_ORG_TYPE)
const selectedIds = ref<number[]>([])
const cancelLoading = ref(false)
const getList = async () => {
loading.value = true
@ -247,7 +259,7 @@ const openForm = (type: string, row?: ZjTaskVO) => {
const handleRowClick = (row: ZjTaskVO) => {
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) => {
@ -263,6 +275,30 @@ const handleSelectionChange = (rows: ZjTaskVO[]) => {
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 () => {
try {
await message.exportConfirm()

@ -135,7 +135,7 @@
</el-form>
<el-tabs v-model="subTabsName">
<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-tabs>
<template #footer>
@ -189,6 +189,17 @@ const moldLoading = ref(false)
const moldOptions = ref<{ label: string; value: number; raw?: MoldVO }[]>([])
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 ensureUsersLoaded = async () => {
@ -265,6 +276,54 @@ const formRules = reactive({
repairCode: [{ required: true, message: t('MoldManagement.MoldRepair.validatorRepairCodeRequired'), trigger: 'blur' }],
repairName: [{ required: true, message: t('MoldManagement.MoldRepair.validatorRepairNameRequired'), trigger: 'blur' }],
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()
@ -400,13 +459,32 @@ const submitForm = async () => {
;(data as any).status = 1
}
;(data as any).moldId = formData.value.moldId
;(data as any).moldRepairLines = moldRepairLineFormRef.value.getData()
if (formType.value === 'create') {
await MoldRepairApi.createMoldRepair(data)
message.success(t('common.createSuccess'))
} else {
await MoldRepairApi.updateMoldRepair(data)
const lineList = moldRepairLineFormRef.value.getData() || []
if (formType.value === 'repair') {
const requireDate = (data as any).requireDate
const finishDate = (data as any).finishDate
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'))
} 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
emit('success')

@ -40,6 +40,35 @@
</el-form-item>
</template>
</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-form>
<el-row justify="center" class="mt-3">
@ -53,6 +82,7 @@ const { t } = useI18n()
const props = defineProps<{
repairId: undefined
lineMode?: 'edit' | 'repair' | 'readonlyWithResult'
}>()
const formLoading = ref(false)
const formData = ref([])
@ -61,6 +91,30 @@ const formRules = reactive({
subjectId: [{ required: true, message: t('MoldManagement.MoldRepairLine.validatorSubjectIdRequired'), trigger: 'blur' }],
subjectCode: [{ required: true, message: t('MoldManagement.MoldRepairLine.validatorSubjectCodeRequired'), 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()
@ -95,6 +149,7 @@ const handleAdd = () => {
malfunctionUrl: undefined,
repairDes: undefined,
remark: undefined,
result: undefined,
}
row.repairId = props.repairId
formData.value.push(row)

@ -137,6 +137,13 @@
: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.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.confirmUserShort')" align="center" prop="confirmBy" min-width="140" />
<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' }
]
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 v = value === '' || value === null || value === undefined ? undefined : String(value)
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-pagination
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"
class="mt-15px mb-15px flex justify-end" layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange" @current-change="handleCurrentChange" />
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"
class="mt-15px mb-15px flex justify-end" layout="total, sizes, prev, pager, next, jumper"
@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>
<el-button @click="dialogVisible = false">{{ t('MoldManagement.TicketResultDialog.cancel') }}</el-button>
@ -70,6 +77,8 @@ const submitLoading = ref(false)
const list = ref<TicketResultVO[]>([])
const total = ref(0)
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 imageMap = reactive<Record<string, string>>({})
@ -78,10 +87,12 @@ const queryParams = reactive({
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
dialogTitle.value = options.title || t('MoldManagement.TicketResultDialog.moduleName')
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(imageMap)) delete imageMap[key]
queryParams.pageNo = 1

@ -173,9 +173,18 @@ const handleSelectionChange = (rows: TicketManagementVO[]) => {
const handleBatchCancel = async () => {
if (!selectedIds.value.length) return
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
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'))
selectedIds.value = []
await getList()
@ -192,6 +201,8 @@ const handleRowClick = async (row: TicketManagementVO, column: any) => {
if (!row?.id) return
await resultDialogRef.value?.open({
managementId: row.id,
jobStatus: row.jobStatus,
cancelReason: row.cancelReason,
title: row.planNo
? `${t('MoldManagement.MoldWorkOrderInquiry.inspectResultTitlePrefix')}${row.planNo}`
: t('MoldManagement.MoldWorkOrderInquiry.inspectResultTitle')

@ -72,7 +72,7 @@
<div class="dashboard-card-image-wrapper" @click="handlePreview(item)">
<img
class="dashboard-card-image"
:src="item.indexImage || defaultImage"
:src="getDashboardImage(item)"
alt="封面图"
/>
<div class="dashboard-card-state">
@ -208,6 +208,8 @@
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import request from '@/config/axios'
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 { handleTree } from '@/utils/tree'
import { DeviceApi } from '@/api/iot/device'
@ -235,6 +237,16 @@ const loading = ref(false)
const list = ref<DashboardItem[]>([])
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({
pageNo: 1,
pageSize: 10,
@ -516,21 +528,21 @@ onMounted(() => {
}
.dashboard-card-title {
margin-bottom: 4px;
overflow: hidden;
font-size: 14px;
font-weight: 600;
color: var(--el-text-color-primary);
margin-bottom: 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dashboard-card-remark {
overflow: hidden;
font-size: 12px;
color: var(--el-text-color-secondary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dashboard-card-actions {

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

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

@ -134,8 +134,8 @@ onUnmounted(() => {
<style scoped>
:deep(.el-select .el-input__wrapper) {
background-color: rgba(2, 6, 23, 0.3);
box-shadow: 0 0 0 1px rgba(56, 189, 248, 0.4) inset;
background-color: rgb(2 6 23 / 30%);
box-shadow: 0 0 0 1px rgb(56 189 248 / 40%) inset;
}
:deep(.el-select .el-input__inner) {
@ -143,35 +143,35 @@ onUnmounted(() => {
}
: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 {
position: relative;
display: flex;
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: 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;
display: flex;
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;
overflow: hidden;
min-height: 0;
}
.card::before,
.card::after {
content: "";
position: absolute;
width: 12px;
height: 12px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px;
border: 1px solid rgba(56, 189, 248, 0.75);
content: "";
opacity: 0.6;
pointer-events: none;
}
.card::before {
@ -184,19 +184,19 @@ onUnmounted(() => {
.card::after {
right: -1px;
bottom: -1px;
border-left: none;
border-top: none;
border-left: none;
}
.panel-title {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
font-size: 16px;
font-weight: 900;
color: #e5f0ff;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
gap: 10px;
}
.panel-title-between {
@ -212,9 +212,9 @@ onUnmounted(() => {
.title-dot {
width: 10px;
height: 10px;
border: 1px solid rgb(56 189 248 / 95%);
border-radius: 50%;
border: 1px solid rgba(56, 189, 248, 0.95);
box-shadow: 0 0 12px rgba(56, 189, 248, 0.45);
box-shadow: 0 0 12px rgb(56 189 248 / 45%);
}
.tabs {
@ -223,22 +223,22 @@ onUnmounted(() => {
gap: 10px;
font-size: 11px;
font-weight: 600;
color: rgba(148, 163, 184, 0.95);
color: rgb(148 163 184 / 95%);
}
.tab {
cursor: pointer;
user-select: none;
padding: 2px 8px;
cursor: pointer;
background: rgb(2 6 23 / 20%);
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
border: 1px solid rgba(148, 163, 184, 0.4);
background: rgba(2, 6, 23, 0.2);
user-select: none;
}
.tab.active {
border-color: rgba(56, 189, 248, 0.85);
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 {
@ -254,10 +254,10 @@ onUnmounted(() => {
}
: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;
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) {

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

@ -108,29 +108,29 @@ onUnmounted(() => {
<style scoped>
.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;
display: flex;
flex-direction: column;
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::after {
content: "";
position: absolute;
width: 12px;
height: 12px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75);
content: "";
opacity: 0.6;
pointer-events: none;
}
.card::before {
@ -143,17 +143,17 @@ onUnmounted(() => {
.card::after {
right: -1px;
bottom: -1px;
border-left: none;
border-top: none;
border-left: none;
}
.card-header {
display: flex;
padding: 10px 12px 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
padding: 10px 12px 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
}
.card-title {
@ -170,61 +170,61 @@ onUnmounted(() => {
}
.card-body {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
gap: 8px;
min-height: 0;
padding: 10px 12px 12px;
overflow: hidden;
flex: 1;
flex-direction: column;
gap: 8px;
}
.tag {
border-radius: 999px;
padding: 2px 6px;
font-size: 10px;
border: 1px solid rgba(148,163,184,0.4);
color: #94a3b8;
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
}
.alarm-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 6px;
height: 100%;
padding: 0;
margin: 0;
overflow: hidden;
list-style: none;
flex-direction: column;
gap: 6px;
}
.alarm-item {
display: flex;
align-items: center;
gap: 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;
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;
align-items: center;
gap: 8px;
flex-shrink: 0;
}
.alarm-item.danger {
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 {
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 {
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 {
@ -234,23 +234,23 @@ onUnmounted(() => {
}
.alarm-msg {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
}
.alarm-level {
flex: 0 0 auto;
border-radius: 999px;
padding: 2px 6px;
border: 1px solid rgba(148,163,184,0.6);
font-size: 10px;
border: 1px solid rgb(148 163 184 / 60%);
border-radius: 999px;
flex: 0 0 auto;
}
.animating-out {
transition: all 0.35s;
transform: translateY(-48px);
opacity: 0;
transform: translateY(-48px);
transition: all 0.35s;
}
</style>

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

@ -171,31 +171,31 @@ onUnmounted(() => {
<style scoped>
.card {
position: relative;
display: flex;
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: 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;
display: flex;
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;
overflow: hidden;
min-height: 0;
}
.card::before,
.card::after {
content: "";
position: absolute;
width: 12px;
height: 12px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75);
content: "";
opacity: 0.6;
pointer-events: none;
}
.card::before {
@ -208,27 +208,27 @@ onUnmounted(() => {
.card::after {
right: -1px;
bottom: -1px;
border-left: none;
border-top: none;
border-left: none;
}
.panel-title {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
font-size: 16px;
font-weight: 900;
color: #e5f0ff;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
gap: 10px;
}
.title-dot {
width: 10px;
height: 10px;
border: 1px solid rgb(56 189 248 / 95%);
border-radius: 50%;
border: 1px solid rgba(56,189,248,0.95);
box-shadow: 0 0 12px rgba(56,189,248,0.45);
box-shadow: 0 0 12px rgb(56 189 248 / 45%);
}
.panel-body {
@ -239,22 +239,22 @@ onUnmounted(() => {
.table-body {
padding: 0;
overflow-x: auto;
overflow-y: hidden;
overflow: auto hidden;
}
.task-table {
width: 100%;
min-width: 450px;
font-size: 12px;
/* Element Plus Table Variables Override */
--el-table-bg-color: transparent;
--el-table-tr-bg-color: transparent;
--el-table-header-bg-color: transparent;
--el-table-text-color: #e5f0ff;
--el-table-header-text-color: #22d3ee;
--el-table-row-hover-bg-color: rgba(56, 189, 248, 0.12);
--el-table-border-color: rgba(30, 64, 175, 0.3);
--el-table-row-hover-bg-color: rgb(56 189 248 / 12%);
--el-table-border-color: rgb(30 64 175 / 30%);
width: 100%;
min-width: 450px;
font-size: 12px;
background-color: transparent !important;
}
@ -274,52 +274,52 @@ onUnmounted(() => {
}
.table-body::-webkit-scrollbar-track {
background: rgba(15, 23, 42, 0.9);
background: rgb(15 23 42 / 90%);
border-radius: 999px;
}
.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;
box-shadow: 0 0 10px rgba(56, 189, 248, 0.4);
box-shadow: 0 0 10px rgb(56 189 248 / 40%);
}
/* Header Styles */
.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;
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 */
.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;
white-space: nowrap;
background-color: transparent !important;
border-bottom: 1px solid rgb(30 64 175 / 30%) !important;
}
/* 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(2) .cell),
.task-table :deep(td.el-table__cell:nth-child(3) .cell) {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 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(5) .cell) {
white-space: nowrap;
overflow: visible;
text-overflow: clip;
white-space: nowrap;
}
/* Hover Styles */
.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 {
@ -328,8 +328,8 @@ onUnmounted(() => {
.status-tag {
min-width: 60px;
padding: 0 10px;
text-align: center;
border-radius: 999px;
padding: 0 10px;
}
</style>

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

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

@ -136,30 +136,30 @@ onUnmounted(() => {
<style scoped>
.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;
display: flex;
flex-direction: column;
padding: 10px;
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::after {
content: "";
position: absolute;
width: 13px;
height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75);
content: "";
opacity: 0.6;
pointer-events: none;
}
.card::before {
@ -172,17 +172,17 @@ onUnmounted(() => {
.card::after {
right: -1px;
bottom: -1px;
border-left: none;
border-top: none;
border-left: none;
}
.card-header {
display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
}
.card-title {
@ -199,9 +199,9 @@ onUnmounted(() => {
}
.card-body {
flex: 1;
min-height: 0;
display: flex;
min-height: 0;
flex: 1;
flex-direction: column;
gap: 8px;
}
@ -219,11 +219,11 @@ onUnmounted(() => {
}
.tag {
border-radius: 999px;
padding: 2px 6px;
font-size: 10px;
border: 1px solid rgba(148,163,184,0.4);
color: #94a3b8;
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
}
.metrics-grid {
@ -234,11 +234,11 @@ onUnmounted(() => {
}
.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;
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;
gap: 4px;
}
@ -255,13 +255,15 @@ onUnmounted(() => {
}
.metric-value.accent { color: #22d3ee; }
.metric-value.warn { color: #f59e0b; }
.metric-value.ok { color: #22c55e; }
.metric-extra {
display: flex;
font-size: 11px;
color: #94a3b8;
display: flex;
justify-content: space-between;
}
@ -271,7 +273,7 @@ onUnmounted(() => {
min-height: 180px;
}
@media (max-width: 1600px) {
@media (width <= 1600px) {
.chart { min-height: 160px; }
}
</style>

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

@ -136,30 +136,30 @@ onUnmounted(() => {
<style scoped>
.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;
display: flex;
flex-direction: column;
padding: 10px;
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::after {
content: "";
position: absolute;
width: 13px;
height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75);
content: "";
opacity: 0.6;
pointer-events: none;
}
.card::before {
@ -172,17 +172,17 @@ onUnmounted(() => {
.card::after {
right: -1px;
bottom: -1px;
border-left: none;
border-top: none;
border-left: none;
}
.card-header {
display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
}
.card-title {
@ -199,9 +199,9 @@ onUnmounted(() => {
}
.card-body {
flex: 1;
min-height: 0;
display: flex;
min-height: 0;
flex: 1;
flex-direction: column;
gap: 8px;
}
@ -219,11 +219,11 @@ onUnmounted(() => {
}
.tag {
border-radius: 999px;
padding: 2px 6px;
font-size: 10px;
border: 1px solid rgba(148,163,184,0.4);
color: #94a3b8;
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
}
.metrics-grid {
@ -234,11 +234,11 @@ onUnmounted(() => {
}
.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;
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;
gap: 4px;
}
@ -255,13 +255,15 @@ onUnmounted(() => {
}
.metric-value.accent { color: #22d3ee; }
.metric-value.warn { color: #f59e0b; }
.metric-value.ok { color: #22c55e; }
.metric-extra {
display: flex;
font-size: 11px;
color: #94a3b8;
display: flex;
justify-content: space-between;
}
@ -271,7 +273,7 @@ onUnmounted(() => {
min-height: 180px;
}
@media (max-width: 1600px) {
@media (width <= 1600px) {
.chart { min-height: 160px; }
}
</style>

@ -132,30 +132,30 @@ onUnmounted(() => {
<style scoped>
.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;
display: flex;
flex-direction: column;
padding: 10px;
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::after {
content: "";
position: absolute;
width: 13px;
height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75);
content: "";
opacity: 0.6;
pointer-events: none;
}
.card::before {
@ -168,17 +168,17 @@ onUnmounted(() => {
.card::after {
right: -1px;
bottom: -1px;
border-left: none;
border-top: none;
border-left: none;
}
.card-header {
display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
}
.card-title {
@ -195,19 +195,19 @@ onUnmounted(() => {
}
.card-body {
flex: 1;
min-height: 0;
display: flex;
min-height: 0;
flex: 1;
flex-direction: column;
gap: 8px;
}
.tag {
border-radius: 999px;
padding: 2px 6px;
font-size: 10px;
border: 1px solid rgba(148,163,184,0.4);
color: #94a3b8;
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
}
.chart {
@ -216,7 +216,7 @@ onUnmounted(() => {
min-height: 180px;
}
@media (max-width: 1600px) {
@media (width <= 1600px) {
.chart { min-height: 160px; }
}
@ -237,27 +237,27 @@ onUnmounted(() => {
}
.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;
font-size: 10px;
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;
user-select: none;
}
.tab-btn:hover {
border-color: rgba(56, 189, 248, 0.9);
color: #e0f2fe;
border-color: rgb(56 189 248 / 90%);
}
.tab-btn.active {
border-color: rgba(34, 211, 238, 0.9);
color: #e0f2fe;
box-shadow: 0 0 14px rgba(34, 211, 238, 0.45);
background: radial-gradient(circle at 0 0, rgba(34, 211, 238, 0.32), rgba(2, 6, 23, 0.2) 60%);
background: radial-gradient(circle at 0 0, rgb(34 211 238 / 32%), rgb(2 6 23 / 20%) 60%);
border-color: rgb(34 211 238 / 90%);
box-shadow: 0 0 14px rgb(34 211 238 / 45%);
}
</style>

@ -118,30 +118,30 @@ onMounted(async () => {
<style scoped>
.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;
display: flex;
flex-direction: column;
padding: 10px;
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::after {
content: "";
position: absolute;
width: 13px;
height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75);
content: "";
opacity: 0.6;
pointer-events: none;
}
.card::before {
@ -154,17 +154,17 @@ onMounted(async () => {
.card::after {
right: -1px;
bottom: -1px;
border-left: none;
border-top: none;
border-left: none;
}
.card-header {
display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
}
.card-title {
@ -181,19 +181,19 @@ onMounted(async () => {
}
.card-body {
flex: 1;
min-height: 0;
display: flex;
min-height: 0;
flex: 1;
flex-direction: column;
gap: 8px;
}
.tag {
border-radius: 999px;
padding: 2px 6px;
font-size: 10px;
border: 1px solid rgba(148,163,184,0.4);
color: #94a3b8;
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
}
.chart {
@ -202,7 +202,7 @@ onMounted(async () => {
min-height: 180px;
}
@media (max-width: 1600px) {
@media (width <= 1600px) {
.chart { min-height: 160px; }
}
</style>

@ -114,30 +114,30 @@ onUnmounted(() => {
<style scoped>
.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;
display: flex;
flex-direction: column;
padding: 10px;
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::after {
content: "";
position: absolute;
width: 13px;
height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75);
content: "";
opacity: 0.6;
pointer-events: none;
}
.card::before {
@ -150,17 +150,17 @@ onUnmounted(() => {
.card::after {
right: -1px;
bottom: -1px;
border-left: none;
border-top: none;
border-left: none;
}
.card-header {
display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
}
.card-title {
@ -177,50 +177,52 @@ onUnmounted(() => {
}
.card-body {
flex: 1;
min-height: 0;
display: flex;
min-height: 0;
overflow: hidden; /* Ensure list stays within */
flex: 1;
flex-direction: column;
gap: 8px;
overflow: hidden; /* Ensure list stays within */
}
.tag {
border-radius: 999px;
padding: 2px 6px;
font-size: 10px;
border: 1px solid rgba(148,163,184,0.4);
color: #94a3b8;
border: 1px solid rgb(148 163 184 / 40%);
border-radius: 999px;
}
.alarm-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 6px;
height: 100%;
padding: 0;
margin: 0;
overflow: hidden;
list-style: none;
flex-direction: column;
gap: 6px;
}
.alarm-item {
display: flex;
align-items: center;
gap: 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;
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;
align-items: center;
gap: 8px;
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.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.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 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 {
width: 64px;
@ -229,24 +231,24 @@ onUnmounted(() => {
}
.alarm-msg {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
}
.alarm-level {
flex: 0 0 auto;
border-radius: 999px;
padding: 2px 6px;
border: 1px solid rgba(148,163,184,0.6);
font-size: 10px;
border: 1px solid rgb(148 163 184 / 60%);
border-radius: 999px;
flex: 0 0 auto;
}
/* Animation class */
.animating-out {
transition: all 0.35s;
transform: translateY(-48px);
opacity: 0;
transform: translateY(-48px);
transition: all 0.35s;
}
</style>

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

@ -108,30 +108,30 @@ onUnmounted(() => {
<style scoped>
.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;
display: flex;
flex-direction: column;
padding: 10px;
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::after {
content: "";
position: absolute;
width: 13px;
height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75);
content: "";
opacity: 0.6;
pointer-events: none;
}
.card::before {
@ -144,17 +144,17 @@ onUnmounted(() => {
.card::after {
right: -1px;
bottom: -1px;
border-left: none;
border-top: none;
border-left: none;
}
.card-header {
display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
}
.card-title {
@ -171,23 +171,23 @@ onUnmounted(() => {
}
.card-body {
flex: 1;
min-height: 0;
display: flex;
min-height: 0;
flex: 1;
flex-direction: column;
gap: 8px;
}
.chip {
border-radius: 999px;
border: 1px solid rgba(148,163,184,0.5);
padding: 4px 10px;
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;
gap: 6px;
background: rgba(15,23,42,0.75);
color: #94a3b8;
font-size: 12px;
}
.chart {
@ -196,7 +196,7 @@ onUnmounted(() => {
min-height: 180px;
}
@media (max-width: 1600px) {
@media (width <= 1600px) {
.chart { min-height: 160px; }
}
</style>

@ -96,30 +96,30 @@ onUnmounted(() => {
<style scoped>
.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;
display: flex;
flex-direction: column;
padding: 10px;
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::after {
content: "";
position: absolute;
width: 13px;
height: 13px;
pointer-events: none;
border: 1px solid rgb(56 189 248 / 75%);
border-radius: 2px;
border: 1px solid rgba(56,189,248,0.75);
content: "";
opacity: 0.6;
pointer-events: none;
}
.card::before {
@ -132,17 +132,17 @@ onUnmounted(() => {
.card::after {
right: -1px;
bottom: -1px;
border-left: none;
border-top: none;
border-left: none;
}
.card-header {
display: flex;
padding-bottom: 4px;
margin-bottom: 8px;
border-bottom: 1px solid rgb(41 54 95 / 90%);
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid rgba(41, 54, 95, 0.9);
}
.card-title {
@ -159,9 +159,9 @@ onUnmounted(() => {
}
.card-body {
flex: 1;
min-height: 0;
display: flex;
min-height: 0;
flex: 1;
flex-direction: column;
gap: 8px;
}
@ -186,7 +186,7 @@ onUnmounted(() => {
min-height: 180px;
}
@media (max-width: 1600px) {
@media (width <= 1600px) {
.chart { min-height: 160px; }
}
</style>

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

Loading…
Cancel
Save