|
|
@@ -84,7 +84,12 @@
|
|
|
import GanttFilterBar from './components/GanttFilterBar.vue';
|
|
|
import ResourcePanel from './components/ResourcePanel.vue';
|
|
|
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css';
|
|
|
- import { DAY_MS, RESOURCE_TABS, WEEK_MAP } from './project-gantt.constants';
|
|
|
+ import {
|
|
|
+ DAY_MS,
|
|
|
+ PLAN_COLOR_PALETTE,
|
|
|
+ RESOURCE_TABS,
|
|
|
+ WEEK_MAP
|
|
|
+ } from './project-gantt.constants';
|
|
|
import {
|
|
|
buildCalendarTooltipHtml,
|
|
|
buildTooltipHtml,
|
|
|
@@ -200,14 +205,9 @@
|
|
|
: RESOURCE_TABS;
|
|
|
},
|
|
|
resourceList() {
|
|
|
- const source =
|
|
|
- this.activeTab === 'line'
|
|
|
- ? this.ganttTasks
|
|
|
- .map((item) => this.getLineResourceName(item))
|
|
|
- .filter(Boolean)
|
|
|
- : this.ganttTasks
|
|
|
- .map((item) => this.getTeamResourceName(item))
|
|
|
- .filter(Boolean);
|
|
|
+ const source = this.ganttTasks
|
|
|
+ .map((item) => this.getActiveResourceName(item))
|
|
|
+ .filter(Boolean);
|
|
|
const result = [];
|
|
|
const cache = new Set();
|
|
|
source.forEach((name, index) => {
|
|
|
@@ -248,6 +248,39 @@
|
|
|
return result;
|
|
|
}, {});
|
|
|
},
|
|
|
+ orderPlanColorMap() {
|
|
|
+ if (this.resourceLabelMode !== 'order') {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ const result = {};
|
|
|
+ const planKeys = [];
|
|
|
+ const assignColor = (primaryKey, aliases = []) => {
|
|
|
+ if (!primaryKey) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const existingKey = [primaryKey, ...aliases].find(
|
|
|
+ (key) => key && result[key]
|
|
|
+ );
|
|
|
+ const color =
|
|
|
+ (existingKey && result[existingKey]) ||
|
|
|
+ PLAN_COLOR_PALETTE[planKeys.length % PLAN_COLOR_PALETTE.length];
|
|
|
+ if (!existingKey) {
|
|
|
+ planKeys.push(primaryKey);
|
|
|
+ }
|
|
|
+ [primaryKey, ...aliases].forEach((key) => {
|
|
|
+ if (key) {
|
|
|
+ result[key] = color;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+ this.ganttTasks.forEach((item) => {
|
|
|
+ assignColor(item.planId || item.planCode, [
|
|
|
+ item.planId,
|
|
|
+ item.planCode
|
|
|
+ ]);
|
|
|
+ });
|
|
|
+ return result;
|
|
|
+ },
|
|
|
calendarTaskSource() {
|
|
|
if (
|
|
|
Array.isArray(this.calendarSourceData) &&
|
|
|
@@ -258,12 +291,19 @@
|
|
|
const resourceList = Array.isArray(item.resourceList)
|
|
|
? item.resourceList
|
|
|
: [];
|
|
|
+ const resourceName = item.resourceName || item.name || '';
|
|
|
+ const resourceCode = item.resourceCode || item.code || '';
|
|
|
const dayEntryMap = {};
|
|
|
const periodDates = [];
|
|
|
const searchEntries = [];
|
|
|
resourceList.forEach((resourceItem, resourceIndex) => {
|
|
|
searchEntries.push({
|
|
|
planCode: resourceItem.planCode || '',
|
|
|
+ productionOrderNumber:
|
|
|
+ resourceItem.productionOrderNumber ||
|
|
|
+ resourceItem.apsWorkOrderCode ||
|
|
|
+ resourceItem.workOrderCode ||
|
|
|
+ '',
|
|
|
productName: resourceItem.productName || '',
|
|
|
routingName:
|
|
|
resourceItem.routingName ||
|
|
|
@@ -295,6 +335,18 @@
|
|
|
planId: resourceItem.planId || '',
|
|
|
planCode:
|
|
|
resourceItem.planCode || resourceItem.productCode || '',
|
|
|
+ productionOrderNumber:
|
|
|
+ resourceItem.productionOrderNumber ||
|
|
|
+ resourceItem.apsWorkOrderCode ||
|
|
|
+ resourceItem.workOrderCode ||
|
|
|
+ '',
|
|
|
+ displayCode:
|
|
|
+ resourceItem.productionOrderNumber ||
|
|
|
+ resourceItem.apsWorkOrderCode ||
|
|
|
+ resourceItem.workOrderCode ||
|
|
|
+ resourceItem.planCode ||
|
|
|
+ resourceItem.productCode ||
|
|
|
+ '',
|
|
|
qty: period.todayRequiredFormingNum ?? '',
|
|
|
productName: resourceItem.productName || '',
|
|
|
routingName:
|
|
|
@@ -304,7 +356,9 @@
|
|
|
productCode: resourceItem.productCode || '',
|
|
|
specification: resourceItem.specification || '',
|
|
|
batchNo: resourceItem.batchNo || '',
|
|
|
- modeType: resourceItem.modeType || ''
|
|
|
+ modeType: resourceItem.modeType || '',
|
|
|
+ resourceName,
|
|
|
+ resourceCode
|
|
|
});
|
|
|
});
|
|
|
});
|
|
|
@@ -315,7 +369,7 @@
|
|
|
return {
|
|
|
id: `${item.resourceId || 'resource'}-${item.taskId || index}`,
|
|
|
code: item.taskId || item.sourceTaskId || '',
|
|
|
- groupLabel: this.getCalendarTeamGroupName(item),
|
|
|
+ groupLabel: this.getActiveCalendarGroupName(item),
|
|
|
productionLineName:
|
|
|
this.getCalendarProductionLineName(item, resourceList) ||
|
|
|
this.getPlanProductionLineName(resourceList[0]?.planCode) ||
|
|
|
@@ -352,7 +406,11 @@
|
|
|
return {
|
|
|
id: item.id || `${item.code || 'task'}-${index}`,
|
|
|
code: item.code || '',
|
|
|
- groupLabel: item.teamName || planMeta.teamName || '未分组',
|
|
|
+ groupLabel:
|
|
|
+ this.getActiveResourceName(item) ||
|
|
|
+ item.teamName ||
|
|
|
+ planMeta.teamName ||
|
|
|
+ '未分组',
|
|
|
productionLineName:
|
|
|
item.productionLineName || planMeta.productionLineName || '',
|
|
|
factoryName: planMeta.factoryName || '',
|
|
|
@@ -521,7 +579,9 @@
|
|
|
return result;
|
|
|
},
|
|
|
calendarGroupLabel() {
|
|
|
- const tab = this.resourceTabs.find((item) => item.key === this.activeTab);
|
|
|
+ const tab = this.resourceTabs.find(
|
|
|
+ (item) => item.key === this.activeTab
|
|
|
+ );
|
|
|
return tab?.label ? `${tab.label}名称` : '资源名称';
|
|
|
}
|
|
|
},
|
|
|
@@ -569,12 +629,18 @@
|
|
|
if (!this.selectedResource) {
|
|
|
return true;
|
|
|
}
|
|
|
- const currentLabel =
|
|
|
- this.activeTab === 'line'
|
|
|
- ? this.getLineResourceName(item)
|
|
|
- : this.getTeamResourceName(item);
|
|
|
+ const currentLabel = this.getActiveResourceName(item);
|
|
|
return String(currentLabel || '').trim() === this.selectedResource;
|
|
|
},
|
|
|
+ resolveGanttPlanColor(planKey) {
|
|
|
+ if (
|
|
|
+ this.resourceLabelMode === 'order' &&
|
|
|
+ this.orderPlanColorMap[planKey]
|
|
|
+ ) {
|
|
|
+ return this.orderPlanColorMap[planKey];
|
|
|
+ }
|
|
|
+ return resolvePlanColor(planKey);
|
|
|
+ },
|
|
|
matchesCalendarResourceFilter(item) {
|
|
|
if (!this.selectedResource) {
|
|
|
return true;
|
|
|
@@ -585,6 +651,12 @@
|
|
|
: item.groupLabel || item.teamName || '';
|
|
|
return String(currentLabel || '').trim() === this.selectedResource;
|
|
|
},
|
|
|
+ getActiveCalendarGroupName(item) {
|
|
|
+ if (this.activeTab === 'person') {
|
|
|
+ return this.getCalendarPersonGroupName(item);
|
|
|
+ }
|
|
|
+ return this.getCalendarTeamGroupName(item);
|
|
|
+ },
|
|
|
getCalendarTeamGroupName(item) {
|
|
|
if (this.resourceLabelMode === 'order') {
|
|
|
return (
|
|
|
@@ -601,6 +673,12 @@
|
|
|
}
|
|
|
return item.name || item.teamName || '未分组';
|
|
|
},
|
|
|
+ getCalendarPersonGroupName(item) {
|
|
|
+ if (this.resourceLabelMode === 'order') {
|
|
|
+ return this.getTaskPersonName(item) || '未分组';
|
|
|
+ }
|
|
|
+ return this.getTaskPersonName(item) || '未分组';
|
|
|
+ },
|
|
|
getCalendarProductionLineName(item, resourceList = []) {
|
|
|
if (this.resourceLabelMode === 'order') {
|
|
|
return (
|
|
|
@@ -647,18 +725,56 @@
|
|
|
return String(
|
|
|
item.equipmentName ||
|
|
|
item.deviceName ||
|
|
|
+ item.deviceCode ||
|
|
|
item.assetName ||
|
|
|
item.machineName ||
|
|
|
item.productionLineName ||
|
|
|
''
|
|
|
).trim();
|
|
|
},
|
|
|
+ getTaskPersonName(item) {
|
|
|
+ const directValue = String(
|
|
|
+ item.executionObjectType === 'person'
|
|
|
+ ? item.executionObjectName || ''
|
|
|
+ : ''
|
|
|
+ ).trim();
|
|
|
+ const name =
|
|
|
+ directValue ||
|
|
|
+ item.assigneeUserName ||
|
|
|
+ item.assigneeUser?.[0]?.userName ||
|
|
|
+ item.assigneeUser?.[0]?.name ||
|
|
|
+ item.executionUserName ||
|
|
|
+ item.executionAssigneeName ||
|
|
|
+ item.assigneeName ||
|
|
|
+ item.operatorName ||
|
|
|
+ item.userName ||
|
|
|
+ item.executionTeamLeader ||
|
|
|
+ item.leaderUserName ||
|
|
|
+ '';
|
|
|
+ return String(name || '')
|
|
|
+ .replace(/^人员[::]/, '')
|
|
|
+ .trim();
|
|
|
+ },
|
|
|
+ getActiveResourceName(item) {
|
|
|
+ if (this.activeTab === 'line') {
|
|
|
+ return this.getLineResourceName(item);
|
|
|
+ }
|
|
|
+ if (this.activeTab === 'person') {
|
|
|
+ return this.getPersonResourceName(item);
|
|
|
+ }
|
|
|
+ return this.getTeamResourceName(item);
|
|
|
+ },
|
|
|
getTeamResourceName(item) {
|
|
|
if (this.resourceLabelMode === 'order') {
|
|
|
- return this.getTaskWorkstationName(item) || this.getTaskTeamName(item);
|
|
|
+ return (
|
|
|
+ this.getTaskWorkstationName(item) || this.getTaskTeamName(item)
|
|
|
+ );
|
|
|
}
|
|
|
return this.getTaskTeamName(item);
|
|
|
},
|
|
|
+ getPersonResourceName(item) {
|
|
|
+ return this.getTaskPersonName(item);
|
|
|
+ },
|
|
|
getLineResourceName(item) {
|
|
|
if (this.resourceLabelMode === 'order') {
|
|
|
return (
|
|
|
@@ -715,7 +831,12 @@
|
|
|
}
|
|
|
this.hoverTooltip = {
|
|
|
visible: true,
|
|
|
- content: buildTooltipHtml(task, this.planMetaByCode, this.activeTab),
|
|
|
+ content: buildTooltipHtml(
|
|
|
+ task,
|
|
|
+ this.planMetaByCode,
|
|
|
+ this.activeTab,
|
|
|
+ this.resourceLabelMode
|
|
|
+ ),
|
|
|
style: {
|
|
|
left: `${event.clientX + 16}px`,
|
|
|
top: `${event.clientY + 16}px`
|
|
|
@@ -797,6 +918,7 @@
|
|
|
'',
|
|
|
productName: entry.productName || planMeta.productName || '',
|
|
|
planCode:
|
|
|
+ entry.productionOrderNumber ||
|
|
|
entry.planCode ||
|
|
|
entry.code ||
|
|
|
planMeta.code ||
|
|
|
@@ -1032,7 +1154,12 @@
|
|
|
});
|
|
|
// 自定义tooltip内容
|
|
|
gantt.templates.tooltip_text = function (start, end, task) {
|
|
|
- return buildTooltipHtml(task, _this.planMetaByCode, _this.activeTab);
|
|
|
+ return buildTooltipHtml(
|
|
|
+ task,
|
|
|
+ _this.planMetaByCode,
|
|
|
+ _this.activeTab,
|
|
|
+ _this.resourceLabelMode
|
|
|
+ );
|
|
|
};
|
|
|
gantt.attachEvent('onTaskClick', function (id, e) {
|
|
|
let box = document.querySelector('.gantt_tooltip');
|
|
|
@@ -1119,7 +1246,7 @@
|
|
|
mergedCurrent.code ||
|
|
|
mergedCurrent.id;
|
|
|
newObj = Object.assign({}, mergedCurrent, {
|
|
|
- color: resolvePlanColor(planKey),
|
|
|
+ color: this.resolveGanttPlanColor(planKey),
|
|
|
title: mergedCurrent.title || '任务',
|
|
|
customClass: 'task-child-plan'
|
|
|
});
|