diff --git a/src/api/iot/device/index.ts b/src/api/iot/device/index.ts
index 3e85b97c..6b5407cc 100644
--- a/src/api/iot/device/index.ts
+++ b/src/api/iot/device/index.ts
@@ -99,6 +99,9 @@ export const DeviceApi = {
getDeviceList2ByNoUsed: async (id: number) => {
return await request.get({ url: `/iot/device/noUsedlist2?id=` + id })
},
+ getAvailableList: async () => {
+ return await request.get({ url: `/iot/device/available-list` })
+ },
// 新增物联设备
createDevice: async (data: DeviceVO) => {
return await request.post({ url: `/iot/device/create`, data })
diff --git a/src/locales/en.ts b/src/locales/en.ts
index d59d88e7..4769f483 100644
--- a/src/locales/en.ts
+++ b/src/locales/en.ts
@@ -3755,7 +3755,7 @@ export default {
tableNameColumn: 'Name',
tableOrganizationColumn: 'Station',
- tableMachineColumn: 'Machine',
+ tableMachineColumn: 'Related Collection Device',
tableTeamColumn: 'Team',
tableStartTimeColumn: 'Start Time',
tableEndTimeColumn: 'End Time',
diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts
index 64f5a418..e64a15fd 100644
--- a/src/locales/zh-CN.ts
+++ b/src/locales/zh-CN.ts
@@ -3599,7 +3599,7 @@ export default {
tableNameColumn: '名称',
tableOrganizationColumn: '工位',
- tableMachineColumn: '机台',
+ tableMachineColumn: '关联采集设备',
tableTeamColumn: '班组',
tableStartTimeColumn: '开始时间',
tableEndTimeColumn: '结束时间',
diff --git a/src/views/mes/components/ScheduleGanttPanel.vue b/src/views/mes/components/ScheduleGanttPanel.vue
index e5476e2e..0bf5399d 100644
--- a/src/views/mes/components/ScheduleGanttPanel.vue
+++ b/src/views/mes/components/ScheduleGanttPanel.vue
@@ -3,6 +3,17 @@
计划信息
+
+
+
+ {{ item.label }}
+
+
{{ activePreviewDevice.deviceName }}
@@ -21,6 +32,13 @@
>
{{ plan.productCode ?? '-' }} / {{ plan.productName ?? '-' }}
+
+ {{ PLAN_STATUS_COLOR_MAP[plan.planStatus].label }}
+
计划编码:{{ plan.taskCode ?? '-' }}
计划数量:{{ plan.planNumber ?? '-' }}
@@ -87,6 +105,19 @@ import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'
defineOptions({ name: 'ScheduleGanttPanel' })
+// 计划状态颜色映射表
+const PLAN_STATUS_COLOR_MAP = {
+ 1: { label: '已排产', color: '#409eff', textColor: '#ffffff', sort: 1 },
+ 8: { label: '已开工', color: '#67c23a', textColor: '#ffffff', sort: 2 },
+ 3: { label: '暂停', color: '#e6a23c', textColor: '#ffffff', sort: 3 },
+ 4: { label: '待入库', color: '#f56c6c', textColor: '#ffffff', sort: 4 },
+ 5: { label: '已入库', color: '#8e7cc3', textColor: '#ffffff', sort: 5 },
+}
+
+const sortedPlanStatusList = Object.entries(PLAN_STATUS_COLOR_MAP)
+ .map(([key, val]) => ({ key: Number(key), ...val }))
+ .sort((a, b) => a.sort - b.sort)
+
const props = withDefaults(
defineProps<{
scheduleList: any[]
@@ -726,7 +757,30 @@ const initGanttPreview = () => {
gantt.templates.tooltip_text = (start, end, task: any) => buildTaskTooltipHtml(task, start, end)
gantt.templates.task_class = (_start, _end, task: any) => {
if (!task?._planData) return ''
- return String(task?._planData?.sourceType ?? '').toUpperCase() === 'HISTORY' ? 'schedule-plan-task-history' : 'schedule-plan-task'
+
+ // 当 editable 为 false 时,根据 planStatus 显示对应的颜色
+ if (!props.editable) {
+ const planStatus = task._planData?.planStatus
+ const statusMap: Record = {
+ '1': 'schedule-plan-task-status-1',
+ 1: 'schedule-plan-task-status-1',
+ '8': 'schedule-plan-task-status-8',
+ 8: 'schedule-plan-task-status-8',
+ '3': 'schedule-plan-task-status-3',
+ 3: 'schedule-plan-task-status-3',
+ '4': 'schedule-plan-task-status-4',
+ 4: 'schedule-plan-task-status-4',
+ '5': 'schedule-plan-task-status-5',
+ 5: 'schedule-plan-task-status-5',
+ '2': 'schedule-plan-task-status-2',
+ 2: 'schedule-plan-task-status-2'
+ }
+ return statusMap[planStatus] || 'schedule-plan-task-default'
+ }
+
+ // 当 editable 为 true 时,使用原来的逻辑
+ const sourceType = String(task?._planData?.sourceType ?? '').toUpperCase()
+ return sourceType === 'HISTORY' ? 'schedule-plan-task-history' : 'schedule-plan-task'
}
const globalRange = getGlobalDateRange(previewScheduleList.value)
@@ -737,6 +791,12 @@ const initGanttPreview = () => {
const ganttData = buildPreviewGanttData(previewScheduleList.value)
gantt.parse(ganttData)
+
+ // 强制刷新所有任务的样式,确保颜色正确应用
+ gantt.eachTask((task: any) => {
+ gantt.refreshTask(task.id)
+ })
+
initTaskTooltips()
if (ganttData.data.length) {
@@ -946,6 +1006,39 @@ onBeforeUnmount(() => {
font-weight: 600;
}
+.schedule-status-legend {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
+ gap: 8px;
+ margin-bottom: 12px;
+ padding: 8px;
+ background: var(--el-fill-color-light);
+ border-radius: 4px;
+}
+
+.legend-item {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ padding: 4px 8px;
+ border-left: 3px solid;
+ font-size: 12px;
+}
+
+.legend-color {
+ display: inline-block;
+ width: 12px;
+ height: 12px;
+ border-radius: 2px;
+ flex-shrink: 0;
+}
+
+.legend-label {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
.schedule-plan-list-title {
margin-top: 14px;
margin-bottom: 10px;
@@ -979,6 +1072,17 @@ onBeforeUnmount(() => {
text-overflow: ellipsis;
white-space: nowrap;
}
+
+.plan-status-tag {
+ display: inline-block;
+ padding: 2px 8px;
+ border-radius: 2px;
+ font-size: 12px;
+ color: #ffffff;
+ font-weight: 600;
+ white-space: nowrap;
+ flex-shrink: 0;
+}
.schedule-plan-item-active {
border: 1px solid var(--el-color-success-light-5);
background: var(--el-color-success-light-9);
@@ -1016,6 +1120,76 @@ onBeforeUnmount(() => {
color: #ffffff;
}
+/* 已排产状态 - 蓝色 */
+.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-status-1) {
+ background: #409eff !important;
+ border-color: #409eff !important;
+}
+
+.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-status-1 .gantt_task_content) {
+ color: #ffffff !important;
+}
+
+/* 已开工状态 - 绿色 */
+.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-status-8) {
+ background: #67c23a !important;
+ border-color: #67c23a !important;
+}
+
+.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-status-8 .gantt_task_content) {
+ color: #ffffff !important;
+}
+
+/* 暂停状态 - 橙色 */
+.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-status-3) {
+ background: #e6a23c !important;
+ border-color: #e6a23c !important;
+}
+
+.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-status-3 .gantt_task_content) {
+ color: #ffffff !important;
+}
+
+/* 待入库状态 - 红色 */
+.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-status-4) {
+ background: #f56c6c !important;
+ border-color: #f56c6c !important;
+}
+
+.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-status-4 .gantt_task_content) {
+ color: #ffffff !important;
+}
+
+/* 已入库状态 - 紫色 */
+.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-status-5) {
+ background: #8e7cc3 !important;
+ border-color: #8e7cc3 !important;
+}
+
+.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-status-5 .gantt_task_content) {
+ color: #ffffff !important;
+}
+
+/* 其他状态 - 深灰 */
+.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-status-2) {
+ background: #606266 !important;
+ border-color: #606266 !important;
+}
+
+.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-status-2 .gantt_task_content) {
+ color: #ffffff !important;
+}
+
+/* 默认状态 */
+.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-default) {
+ background: #909399;
+ border-color: #909399;
+}
+
+.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-default .gantt_task_content) {
+ color: #ffffff;
+}
+
.schedule-gantt-container :deep(.gantt_task_line.schedule-plan-task-history) {
background: #909399;
border-color: #909399;
diff --git a/src/views/mes/organization/OrganizationForm.vue b/src/views/mes/organization/OrganizationForm.vue
index efd2addb..74f247f6 100644
--- a/src/views/mes/organization/OrganizationForm.vue
+++ b/src/views/mes/organization/OrganizationForm.vue
@@ -113,6 +113,7 @@
:key="item.id"
:label="item.deviceName"
:value="item.id"
+ :disabled="item.selected === true"
/>
@@ -162,6 +163,7 @@ const formData = ref({
sort: undefined,
workerUserId: undefined,
machineId: undefined,
+ machineName: undefined,
phone: undefined,
email: undefined,
isEnable: undefined,
@@ -169,7 +171,8 @@ const formData = ref({
orgClass: undefined,
orgType: undefined,
isCode: undefined,
- dvId: undefined
+ dvId: undefined,
+ dvName: undefined
})
const formRules = reactive({
name: [{ required: true, message: t('FactoryModeling.FactoryStructure.validatorNameRequired'), trigger: 'blur' }],
@@ -198,12 +201,18 @@ const open = async (type: string, id?: number) => {
deviceList.value = await DeviceLedgerApi.getDeviceLedgerListByNoUsed()
} else {
deviceList.value = await DeviceLedgerApi.getDeviceLedgerList2ByNoUsed(formData.value.machineId)
+ const exists = deviceList.value.some((item) => item.id === formData.value.machineId)
+ if (!exists && formData.value.machineName) {
+ deviceList.value.unshift({ id: formData.value.machineId, deviceName: formData.value.machineName } as DeviceLedgerVO)
+ }
}
//await getMachineComponentTree()
- if (type == 'create' || typeof formData.value.dvId != 'number') {
- dvList.value = await DeviceApi.getDeviceListByNoUsed()
- } else {
- dvList.value = await DeviceApi.getDeviceList2ByNoUsed(formData.value.dvId)
+ dvList.value = await DeviceApi.getAvailableList()
+ if (type !== 'create' && typeof formData.value.dvId === 'number') {
+ const exists = dvList.value.some((item) => item.id === formData.value.dvId)
+ if (!exists && formData.value.dvName) {
+ dvList.value.unshift({ id: formData.value.dvId, deviceName: formData.value.dvName, selected: true } as DeviceVO)
+ }
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
@@ -242,6 +251,7 @@ const resetForm = () => {
sort: 0,
workerUserId: undefined,
machineId: undefined,
+ machineName: undefined,
phone: undefined,
email: undefined,
isEnable: undefined,
@@ -249,7 +259,8 @@ const resetForm = () => {
orgClass: undefined,
orgType: undefined,
isCode: true,
- dvId: undefined
+ dvId: undefined,
+ dvName: undefined
}
formRef.value?.resetFields()
}
diff --git a/src/views/mes/plan/index.vue b/src/views/mes/plan/index.vue
index d2df198a..3e2ce662 100644
--- a/src/views/mes/plan/index.vue
+++ b/src/views/mes/plan/index.vue
@@ -204,7 +204,7 @@
{{ t('ProductionPlan.Plan.actionFinishLabel') }}
{{ t('ProductionPlan.Plan.actionStoreLabel') }}
@@ -237,6 +237,26 @@
+
+
+