|
|
|
@ -110,8 +110,8 @@ |
|
|
|
</el-table-column> |
|
|
|
|
|
|
|
<el-table-column |
|
|
|
v-for="item in visibleProcessColumns" |
|
|
|
:key="item.code" |
|
|
|
v-for="(item, processColumnIndex) in visibleProcessColumns" |
|
|
|
:key="`${item.code}_${item.sortNo || ''}_${processColumnIndex}`" |
|
|
|
:label="item.label" |
|
|
|
width="120" |
|
|
|
align="center" |
|
|
|
@ -239,19 +239,33 @@ |
|
|
|
:close-on-click-modal="false" |
|
|
|
custom-class="bu-process-config-dialog" |
|
|
|
> |
|
|
|
<div class="bu-process-config-tip"> |
|
|
|
<i class="el-icon-info"></i> |
|
|
|
<span>拖动可调整顺序,勾选控制可见列</span> |
|
|
|
</div> |
|
|
|
<el-table :data="buProcessConfigRows" border stripe max-height="560"> |
|
|
|
<el-table-column prop="buDesc" label="事业部名称" width="100" show-overflow-tooltip /> |
|
|
|
<el-table-column label="可见进度列表" min-width="450" class-name="bu-process-list-column"> |
|
|
|
<template slot-scope="scope"> |
|
|
|
<el-checkbox-group |
|
|
|
v-model="scope.row.processCodes" |
|
|
|
class="bu-process-order-list" |
|
|
|
@change="handleBuProcessCodesChange(scope.row)" |
|
|
|
> |
|
|
|
<el-checkbox |
|
|
|
v-for="column in processColumns" |
|
|
|
:key="`${scope.row.buNo}_${column.code}`" |
|
|
|
:label="column.code" |
|
|
|
>{{ column.label }}</el-checkbox> |
|
|
|
<div |
|
|
|
v-for="(processCode, processCodeIndex) in scope.row.processOrderCodes" |
|
|
|
:key="`${scope.row.buNo}_${processCode}_${processCodeIndex}`" |
|
|
|
:class="['bu-process-order-item', isProcessOrderDraggingItem(scope.row, processCodeIndex) ? 'is-dragging' : '']" |
|
|
|
draggable="true" |
|
|
|
@dragstart="handleProcessOrderDragStart(scope.row, processCodeIndex, $event)" |
|
|
|
@dragover.prevent |
|
|
|
@dragenter.prevent |
|
|
|
@drop.prevent="handleProcessOrderDrop(scope.row, processCodeIndex, $event)" |
|
|
|
@dragend="handleProcessOrderDragEnd" |
|
|
|
> |
|
|
|
<i class="el-icon-rank process-order-handle"></i> |
|
|
|
<el-checkbox :label="processCode">{{ getProcessLabelByCode(processCode) }}</el-checkbox> |
|
|
|
</div> |
|
|
|
</el-checkbox-group> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
@ -524,7 +538,7 @@ |
|
|
|
|
|
|
|
<el-row :gutter="16"> |
|
|
|
<el-col :span="6" v-show="isOneKeyCreateFieldVisible('requiredDeliveryDate')"> |
|
|
|
<el-form-item label="预计交付日期"> |
|
|
|
<el-form-item label="完成日期"> |
|
|
|
<el-date-picker |
|
|
|
v-model="oneKeyForm.requiredDeliveryDate" |
|
|
|
type="date" |
|
|
|
@ -809,6 +823,7 @@ import { |
|
|
|
oneKeyCreateProofTracking, |
|
|
|
oneKeyUpdateProofTracking, |
|
|
|
queryProofTrackingBuProcessConfig, |
|
|
|
queryProofTrackingProcessColumns, |
|
|
|
queryProofTrackingProcessHistory, |
|
|
|
saveProofTrackingBuProcessConfig, |
|
|
|
searchProjectInfoTracking, |
|
|
|
@ -859,6 +874,26 @@ function focusCommentsNativeInput (el, vnode) { |
|
|
|
setTimeout(doFocus, 100) |
|
|
|
} |
|
|
|
|
|
|
|
const DEFAULT_PROCESS_COLUMNS = [ |
|
|
|
{ label: 'Raw Material', code: 'rawMaterial', planField: 'rawMaterialPlanDate', actualField: 'rawMaterialActualDate', statusField: 'rawMaterialStatus' }, |
|
|
|
{ label: 'Cylinder/Cutter', code: 'cylinderCutter', planField: 'cylinderCutterPlanDate', actualField: 'cylinderCutterActualDate', statusField: 'cylinderCutterStatus' }, |
|
|
|
{ label: 'Lamination', code: 'lamination', planField: 'laminationPlanDate', actualField: 'laminationActualDate', statusField: 'laminationStatus' }, |
|
|
|
{ label: 'Printing', code: 'printing', planField: 'printingPlanDate', actualField: 'printingActualDate', statusField: 'printingStatus' }, |
|
|
|
{ label: 'Etching', code: 'etching', planField: 'etchingPlanDate', actualField: 'etchingActualDate', statusField: 'etchingStatus' }, |
|
|
|
{ label: 'Slitting&Packing', code: 'slittingPacking', planField: 'slittingPackingPlanDate', actualField: 'slittingPackingActualDate', statusField: 'slittingPackingStatus' }, |
|
|
|
{ label: 'Bonding', code: 'bonding', planField: 'bondingPlanDate', actualField: 'bondingActualDate', statusField: 'bondingStatus' }, |
|
|
|
{ label: 'CL60/CL822', code: 'cl60Cl822', planField: 'cl60Cl822PlanDate', actualField: 'cl60Cl822ActualDate', statusField: 'cl60Cl822Status' }, |
|
|
|
{ label: 'Spotting', code: 'spotting', planField: 'spottingPlanDate', actualField: 'spottingActualDate', statusField: 'spottingStatus' }, |
|
|
|
{ label: 'Encoding', code: 'encoding', planField: 'encodingPlanDate', actualField: 'encodingActualDate', statusField: 'encodingStatus' }, |
|
|
|
{ label: 'Die cut', code: 'dieCut', planField: 'dieCutPlanDate', actualField: 'dieCutActualDate', statusField: 'dieCutStatus' }, |
|
|
|
{ label: 'Inspection', code: 'inspection', planField: 'inspectionPlanDate', actualField: 'inspectionActualDate', statusField: 'inspectionStatus' }, |
|
|
|
{ label: 'Delivery&Package', code: 'deliveryPackage', planField: 'deliveryPackagePlanDate', actualField: 'deliveryPackageActualDate', statusField: 'deliveryPackageStatus' } |
|
|
|
] |
|
|
|
|
|
|
|
function cloneDefaultProcessColumns () { |
|
|
|
return DEFAULT_PROCESS_COLUMNS.map(item => Object.assign({}, item)) |
|
|
|
} |
|
|
|
|
|
|
|
export default { |
|
|
|
name: 'ProjectProofTracking', |
|
|
|
directives: { |
|
|
|
@ -894,24 +929,14 @@ export default { |
|
|
|
proofSyncFlag: '', |
|
|
|
proofingStatus: '' |
|
|
|
}, |
|
|
|
processColumns: [ |
|
|
|
{ label: 'Raw Material', code: 'rawMaterial', planField: 'rawMaterialPlanDate', actualField: 'rawMaterialActualDate', statusField: 'rawMaterialStatus' }, |
|
|
|
{ label: 'Cylinder/Cutter', code: 'cylinderCutter', planField: 'cylinderCutterPlanDate', actualField: 'cylinderCutterActualDate', statusField: 'cylinderCutterStatus' }, |
|
|
|
{ label: 'Lamination', code: 'lamination', planField: 'laminationPlanDate', actualField: 'laminationActualDate', statusField: 'laminationStatus' }, |
|
|
|
{ label: 'Printing', code: 'printing', planField: 'printingPlanDate', actualField: 'printingActualDate', statusField: 'printingStatus' }, |
|
|
|
{ label: 'Etching', code: 'etching', planField: 'etchingPlanDate', actualField: 'etchingActualDate', statusField: 'etchingStatus' }, |
|
|
|
{ label: 'Slitting&Packing', code: 'slittingPacking', planField: 'slittingPackingPlanDate', actualField: 'slittingPackingActualDate', statusField: 'slittingPackingStatus' }, |
|
|
|
{ label: 'Bonding', code: 'bonding', planField: 'bondingPlanDate', actualField: 'bondingActualDate', statusField: 'bondingStatus' }, |
|
|
|
{ label: 'CL60/CL822', code: 'cl60Cl822', planField: 'cl60Cl822PlanDate', actualField: 'cl60Cl822ActualDate', statusField: 'cl60Cl822Status' }, |
|
|
|
{ label: 'Spotting', code: 'spotting', planField: 'spottingPlanDate', actualField: 'spottingActualDate', statusField: 'spottingStatus' }, |
|
|
|
{ label: 'Encoding', code: 'encoding', planField: 'encodingPlanDate', actualField: 'encodingActualDate', statusField: 'encodingStatus' }, |
|
|
|
{ label: 'Die cut', code: 'dieCut', planField: 'dieCutPlanDate', actualField: 'dieCutActualDate', statusField: 'dieCutStatus' }, |
|
|
|
{ label: 'Inspection', code: 'inspection', planField: 'inspectionPlanDate', actualField: 'inspectionActualDate', statusField: 'inspectionStatus' }, |
|
|
|
{ label: 'Delivery&Package', code: 'deliveryPackage', planField: 'deliveryPackagePlanDate', actualField: 'deliveryPackageActualDate', statusField: 'deliveryPackageStatus' } |
|
|
|
], |
|
|
|
processColumns: cloneDefaultProcessColumns(), |
|
|
|
buProcessConfigDialogVisible: false, |
|
|
|
buProcessConfigRows: [], |
|
|
|
buProcessConfigMap: {}, |
|
|
|
processOrderDragState: { |
|
|
|
buNo: '', |
|
|
|
fromIndex: -1 |
|
|
|
}, |
|
|
|
projectCategoryList: ['Low Risk', 'High Risk', 'Sustaining'], |
|
|
|
cProjectRegionList: [ |
|
|
|
{ cProjectRegion: 'Global' }, |
|
|
|
@ -1056,7 +1081,7 @@ export default { |
|
|
|
} |
|
|
|
}, |
|
|
|
activated () { |
|
|
|
this.loadUserBuList().then(() => { |
|
|
|
Promise.all([this.loadUserBuList(), this.queryProcessColumns()]).then(() => { |
|
|
|
this.queryBuProcessConfig() |
|
|
|
}) |
|
|
|
this.getDataList() |
|
|
|
@ -1099,9 +1124,168 @@ export default { |
|
|
|
return [] |
|
|
|
}) |
|
|
|
}, |
|
|
|
queryProcessColumns () { |
|
|
|
const selectedBuNo = this.getSelectedSearchBuNo() |
|
|
|
const queryBuNo = selectedBuNo || '*' |
|
|
|
// 列顺序来源规则: |
|
|
|
// 1) 未选择查询 BU:固定按 bu='*' 读取默认工序顺序; |
|
|
|
// 2) 已选择查询 BU:按该 BU 读取;若无配置由后端回退到 bu='*'。 |
|
|
|
const inData = { |
|
|
|
site: this.$store.state.user.site, |
|
|
|
userName: this.$store.state.user.name, |
|
|
|
buNo: queryBuNo |
|
|
|
} |
|
|
|
return queryProofTrackingProcessColumns(inData).then(({ data }) => { |
|
|
|
if (!(data && data.code === 0)) { |
|
|
|
this.$message.error((data && data.msg) || '加载工序列配置失败,已使用默认配置') |
|
|
|
this.processColumns = cloneDefaultProcessColumns() |
|
|
|
this.ensureBuProcessConfigRows() |
|
|
|
this.refreshTrackingTableLayout() |
|
|
|
return this.processColumns |
|
|
|
} |
|
|
|
const rows = Array.isArray(data.rows) ? data.rows : [] |
|
|
|
// 防御性排序:即使后端 SQL 已 ORDER BY sort_no,前端仍按 sortNo 二次排序,确保展示稳定。 |
|
|
|
const sortedRows = rows |
|
|
|
.map((item, index) => { |
|
|
|
const parsedSortNo = parseInt(item && item.sortNo, 10) |
|
|
|
return { |
|
|
|
item: item, |
|
|
|
sourceIndex: index, |
|
|
|
sortNo: Number.isNaN(parsedSortNo) ? Number.MAX_SAFE_INTEGER : parsedSortNo |
|
|
|
} |
|
|
|
}) |
|
|
|
.sort((a, b) => { |
|
|
|
if (a.sortNo !== b.sortNo) { |
|
|
|
return a.sortNo - b.sortNo |
|
|
|
} |
|
|
|
return a.sourceIndex - b.sourceIndex |
|
|
|
}) |
|
|
|
const nextColumns = [] |
|
|
|
const usedCodeMap = {} |
|
|
|
sortedRows.forEach(({ item, sortNo }) => { |
|
|
|
if (!item) { |
|
|
|
return |
|
|
|
} |
|
|
|
const code = item.code == null ? '' : String(item.code).trim() |
|
|
|
const label = item.label == null ? '' : String(item.label).trim() |
|
|
|
const planField = item.planField == null ? '' : String(item.planField).trim() |
|
|
|
const actualField = item.actualField == null ? '' : String(item.actualField).trim() |
|
|
|
const statusField = item.statusField == null ? '' : String(item.statusField).trim() |
|
|
|
if (!code || !label || !planField || !actualField || !statusField || usedCodeMap[code]) { |
|
|
|
return |
|
|
|
} |
|
|
|
usedCodeMap[code] = true |
|
|
|
nextColumns.push({ |
|
|
|
label: label, |
|
|
|
code: code, |
|
|
|
planField: planField, |
|
|
|
actualField: actualField, |
|
|
|
statusField: statusField, |
|
|
|
sortNo: sortNo === Number.MAX_SAFE_INTEGER ? null : sortNo |
|
|
|
}) |
|
|
|
}) |
|
|
|
// 保障切换期可用性:当表里无有效配置时继续使用前端兜底工序定义。 |
|
|
|
this.processColumns = nextColumns.length > 0 ? nextColumns : cloneDefaultProcessColumns() |
|
|
|
this.syncDataListProcessValues() |
|
|
|
this.ensureBuProcessConfigRows() |
|
|
|
this.refreshTrackingTableLayout() |
|
|
|
return this.processColumns |
|
|
|
}).catch(() => { |
|
|
|
this.$message.error('加载工序列配置异常,已使用默认配置') |
|
|
|
this.processColumns = cloneDefaultProcessColumns() |
|
|
|
this.syncDataListProcessValues() |
|
|
|
this.ensureBuProcessConfigRows() |
|
|
|
this.refreshTrackingTableLayout() |
|
|
|
return this.processColumns |
|
|
|
}) |
|
|
|
}, |
|
|
|
getRowProcessValue (row, processCode) { |
|
|
|
if (!row || !processCode) { |
|
|
|
return null |
|
|
|
} |
|
|
|
const processMap = row.processValueMap && typeof row.processValueMap === 'object' |
|
|
|
? row.processValueMap |
|
|
|
: null |
|
|
|
if (!processMap) { |
|
|
|
return null |
|
|
|
} |
|
|
|
return processMap[processCode] || null |
|
|
|
}, |
|
|
|
applyProcessValuesToRow (row) { |
|
|
|
if (!row || !this.processColumns || this.processColumns.length === 0) { |
|
|
|
return |
|
|
|
} |
|
|
|
this.processColumns.forEach(item => { |
|
|
|
if (!item) { |
|
|
|
return |
|
|
|
} |
|
|
|
const processValue = this.getRowProcessValue(row, item.code) |
|
|
|
const planDate = processValue ? this.formatDate(processValue.planDate) : '' |
|
|
|
const actualDate = processValue ? this.formatDate(processValue.actualDate) : '' |
|
|
|
const status = processValue && processValue.status ? String(processValue.status).trim() : '' |
|
|
|
this.$set(row, item.planField, planDate) |
|
|
|
this.$set(row, item.actualField, actualDate) |
|
|
|
this.$set(row, item.statusField, status) |
|
|
|
}) |
|
|
|
}, |
|
|
|
syncDataListProcessValues () { |
|
|
|
if (!Array.isArray(this.dataList) || this.dataList.length === 0) { |
|
|
|
return |
|
|
|
} |
|
|
|
this.dataList.forEach(row => { |
|
|
|
this.applyProcessValuesToRow(row) |
|
|
|
}) |
|
|
|
}, |
|
|
|
updateRowProcessValue (row, processCol, status, actualDate) { |
|
|
|
if (!row || !processCol) { |
|
|
|
return |
|
|
|
} |
|
|
|
if (!row.processValueMap || typeof row.processValueMap !== 'object') { |
|
|
|
this.$set(row, 'processValueMap', {}) |
|
|
|
} |
|
|
|
const prevValue = this.getRowProcessValue(row, processCol.code) || {} |
|
|
|
this.$set(row.processValueMap, processCol.code, Object.assign({}, prevValue, { |
|
|
|
processCode: processCol.code, |
|
|
|
status: status, |
|
|
|
actualDate: actualDate || null |
|
|
|
})) |
|
|
|
this.$set(row, processCol.statusField, status) |
|
|
|
this.$set(row, processCol.actualField, actualDate) |
|
|
|
}, |
|
|
|
getAllProcessCodes () { |
|
|
|
return this.processColumns.map(item => item.code) |
|
|
|
}, |
|
|
|
getProcessLabelByCode (processCode) { |
|
|
|
if (!processCode) { |
|
|
|
return '' |
|
|
|
} |
|
|
|
const matched = this.processColumns.find(item => item && item.code === processCode) |
|
|
|
if (matched && matched.label) { |
|
|
|
return matched.label |
|
|
|
} |
|
|
|
const defaultMatched = DEFAULT_PROCESS_COLUMNS.find(item => item && item.code === processCode) |
|
|
|
return defaultMatched && defaultMatched.label ? defaultMatched.label : processCode |
|
|
|
}, |
|
|
|
getValidProcessOrderCodes (codes) { |
|
|
|
// 顺序列表不能因为“当前 BU 不可见”而丢项:先保留后端返回顺序,再补齐当前已知工序。 |
|
|
|
const orderedCodes = [] |
|
|
|
if (Array.isArray(codes)) { |
|
|
|
codes.forEach(code => { |
|
|
|
const codeVal = code == null ? '' : String(code).trim() |
|
|
|
if (!codeVal || orderedCodes.indexOf(codeVal) > -1) { |
|
|
|
return |
|
|
|
} |
|
|
|
orderedCodes.push(codeVal) |
|
|
|
}) |
|
|
|
} |
|
|
|
const allCodes = this.getAllProcessCodes() |
|
|
|
allCodes.forEach(code => { |
|
|
|
if (orderedCodes.indexOf(code) === -1) { |
|
|
|
orderedCodes.push(code) |
|
|
|
} |
|
|
|
}) |
|
|
|
return orderedCodes |
|
|
|
}, |
|
|
|
normalizeBuNo (buNo, site) { |
|
|
|
const rawBuNo = buNo == null ? '' : String(buNo).trim() |
|
|
|
if (!rawBuNo) { |
|
|
|
@ -1114,11 +1298,15 @@ export default { |
|
|
|
// BU统一按“去掉site前缀”展示与保存,例如 2_01-Label -> 01-Label。 |
|
|
|
return rawBuNo.substring(splitIdx + 1) |
|
|
|
}, |
|
|
|
getValidProcessCodes (codes) { |
|
|
|
getValidProcessCodes (codes, allowedCodes) { |
|
|
|
if (!Array.isArray(codes) || codes.length === 0) { |
|
|
|
return [] |
|
|
|
} |
|
|
|
const allCodes = this.getAllProcessCodes() |
|
|
|
const allCodes = Array.isArray(allowedCodes) && allowedCodes.length > 0 |
|
|
|
? allowedCodes |
|
|
|
.map(code => (code == null ? '' : String(code).trim())) |
|
|
|
.filter(code => !!code) |
|
|
|
: this.getAllProcessCodes() |
|
|
|
const normalizedCodes = [] |
|
|
|
codes.forEach(code => { |
|
|
|
const codeVal = code == null ? '' : String(code).trim() |
|
|
|
@ -1147,7 +1335,9 @@ export default { |
|
|
|
}, |
|
|
|
handleSearchBuChange () { |
|
|
|
// BU筛选变化(含清空)后立即重新查询,并回到第一页。 |
|
|
|
this.getDataList('Y') |
|
|
|
this.queryProcessColumns().then(() => { |
|
|
|
this.getDataList('Y') |
|
|
|
}) |
|
|
|
}, |
|
|
|
getProcessVisibleCodesByBuNo (buNo, site) { |
|
|
|
const configEntry = this.getBuProcessConfigEntry(buNo, site) |
|
|
|
@ -1188,19 +1378,24 @@ export default { |
|
|
|
} |
|
|
|
const rows = data.rows || [] |
|
|
|
const nextMap = {} |
|
|
|
const allCodeCount = this.processColumns.length |
|
|
|
rows.forEach(item => { |
|
|
|
const buNo = this.normalizeBuNo(item && item.buNo ? item.buNo : '', this.$store.state.user.site) |
|
|
|
if (!buNo) { |
|
|
|
return |
|
|
|
} |
|
|
|
const processCodes = this.getValidProcessCodes(item.processCodes) |
|
|
|
const showAll = item.showAll !== false || processCodes.length === 0 || processCodes.length >= allCodeCount |
|
|
|
if (!showAll) { |
|
|
|
nextMap[buNo] = { |
|
|
|
showAll: false, |
|
|
|
processCodes: processCodes |
|
|
|
} |
|
|
|
const processOrderCodes = this.getValidProcessOrderCodes(item.processOrderCodes) |
|
|
|
const processCodes = this.getValidProcessCodes(item.processCodes, processOrderCodes) |
|
|
|
const showAll = item && item.showAll === true |
|
|
|
? true |
|
|
|
: processCodes.length >= processOrderCodes.length |
|
|
|
const selectedCodeMap = {} |
|
|
|
processCodes.forEach(code => { |
|
|
|
selectedCodeMap[code] = true |
|
|
|
}) |
|
|
|
nextMap[buNo] = { |
|
|
|
showAll: showAll, |
|
|
|
processOrderCodes: processOrderCodes, |
|
|
|
processCodes: showAll ? processOrderCodes.slice() : processOrderCodes.filter(code => selectedCodeMap[code]) |
|
|
|
} |
|
|
|
}) |
|
|
|
this.buProcessConfigMap = nextMap |
|
|
|
@ -1224,12 +1419,23 @@ export default { |
|
|
|
const row = { |
|
|
|
buNo: key, |
|
|
|
buDesc: buDesc || key, |
|
|
|
processOrderCodes: allCodes.slice(), |
|
|
|
processCodes: allCodes.slice() |
|
|
|
} |
|
|
|
if (cfg && cfg.showAll === false) { |
|
|
|
const validCodes = this.getValidProcessCodes(cfg.processCodes) |
|
|
|
if (validCodes.length > 0 && validCodes.length < allCodes.length) { |
|
|
|
row.processCodes = validCodes |
|
|
|
if (cfg) { |
|
|
|
const validOrderCodes = this.getValidProcessOrderCodes(cfg.processOrderCodes) |
|
|
|
row.processOrderCodes = validOrderCodes |
|
|
|
if (cfg.showAll === false) { |
|
|
|
const validCodes = this.getValidProcessCodes(cfg.processCodes, validOrderCodes) |
|
|
|
if (validCodes.length > 0 && validCodes.length < validOrderCodes.length) { |
|
|
|
const selectedCodeMap = {} |
|
|
|
validCodes.forEach(code => { |
|
|
|
selectedCodeMap[code] = true |
|
|
|
}) |
|
|
|
row.processCodes = validOrderCodes.filter(code => selectedCodeMap[code]) |
|
|
|
} |
|
|
|
} else { |
|
|
|
row.processCodes = validOrderCodes.slice() |
|
|
|
} |
|
|
|
} |
|
|
|
rows.push(row) |
|
|
|
@ -1247,6 +1453,10 @@ export default { |
|
|
|
}, |
|
|
|
openBuProcessConfigDialog () { |
|
|
|
this.ensureBuProcessConfigRows() |
|
|
|
this.processOrderDragState = { |
|
|
|
buNo: '', |
|
|
|
fromIndex: -1 |
|
|
|
} |
|
|
|
this.buProcessConfigDialogVisible = true |
|
|
|
}, |
|
|
|
refreshTrackingTableLayout () { |
|
|
|
@ -1261,7 +1471,68 @@ export default { |
|
|
|
if (!row) { |
|
|
|
return |
|
|
|
} |
|
|
|
row.processCodes = this.getValidProcessCodes(row.processCodes) |
|
|
|
const validOrderCodes = this.getValidProcessOrderCodes(row.processOrderCodes) |
|
|
|
const validCodes = this.getValidProcessCodes(row.processCodes, validOrderCodes) |
|
|
|
const selectedCodeMap = {} |
|
|
|
validCodes.forEach(code => { |
|
|
|
selectedCodeMap[code] = true |
|
|
|
}) |
|
|
|
row.processOrderCodes = validOrderCodes |
|
|
|
row.processCodes = validOrderCodes.filter(code => selectedCodeMap[code]) |
|
|
|
}, |
|
|
|
isProcessOrderDraggingItem (row, index) { |
|
|
|
if (!row || index == null) { |
|
|
|
return false |
|
|
|
} |
|
|
|
return this.processOrderDragState.buNo === row.buNo && this.processOrderDragState.fromIndex === index |
|
|
|
}, |
|
|
|
handleProcessOrderDragStart (row, index, event) { |
|
|
|
if (!row || index == null || index < 0) { |
|
|
|
return |
|
|
|
} |
|
|
|
this.processOrderDragState = { |
|
|
|
buNo: row.buNo || '', |
|
|
|
fromIndex: index |
|
|
|
} |
|
|
|
if (event && event.dataTransfer) { |
|
|
|
event.dataTransfer.effectAllowed = 'move' |
|
|
|
} |
|
|
|
}, |
|
|
|
handleProcessOrderDrop (row, targetIndex, event) { |
|
|
|
if (event && event.dataTransfer) { |
|
|
|
event.dataTransfer.dropEffect = 'move' |
|
|
|
} |
|
|
|
if (!row || targetIndex == null || targetIndex < 0) { |
|
|
|
this.handleProcessOrderDragEnd() |
|
|
|
return |
|
|
|
} |
|
|
|
const dragBuNo = this.processOrderDragState.buNo |
|
|
|
const fromIndex = Number(this.processOrderDragState.fromIndex) |
|
|
|
if (!dragBuNo || dragBuNo !== row.buNo || Number.isNaN(fromIndex) || fromIndex < 0) { |
|
|
|
this.handleProcessOrderDragEnd() |
|
|
|
return |
|
|
|
} |
|
|
|
const validOrderCodes = this.getValidProcessOrderCodes(row.processOrderCodes) |
|
|
|
if (fromIndex >= validOrderCodes.length || targetIndex >= validOrderCodes.length) { |
|
|
|
this.handleProcessOrderDragEnd() |
|
|
|
return |
|
|
|
} |
|
|
|
if (fromIndex === targetIndex) { |
|
|
|
this.handleProcessOrderDragEnd() |
|
|
|
return |
|
|
|
} |
|
|
|
const movedCode = validOrderCodes.splice(fromIndex, 1)[0] |
|
|
|
const insertIndex = targetIndex |
|
|
|
validOrderCodes.splice(insertIndex, 0, movedCode) |
|
|
|
row.processOrderCodes = validOrderCodes |
|
|
|
this.handleBuProcessCodesChange(row) |
|
|
|
this.handleProcessOrderDragEnd() |
|
|
|
}, |
|
|
|
handleProcessOrderDragEnd () { |
|
|
|
this.processOrderDragState = { |
|
|
|
buNo: '', |
|
|
|
fromIndex: -1 |
|
|
|
} |
|
|
|
}, |
|
|
|
saveBuProcessConfig () { |
|
|
|
if (!this.buProcessConfigRows || this.buProcessConfigRows.length === 0) { |
|
|
|
@ -1269,7 +1540,6 @@ export default { |
|
|
|
return |
|
|
|
} |
|
|
|
const nextMap = {} |
|
|
|
const allCodeCount = this.processColumns.length |
|
|
|
const submitRows = [] |
|
|
|
for (let i = 0; i < this.buProcessConfigRows.length; i++) { |
|
|
|
const row = this.buProcessConfigRows[i] |
|
|
|
@ -1277,22 +1547,27 @@ export default { |
|
|
|
if (!buNo) { |
|
|
|
continue |
|
|
|
} |
|
|
|
const validCodes = this.getValidProcessCodes(row.processCodes) |
|
|
|
const validOrderCodes = this.getValidProcessOrderCodes(row.processOrderCodes) |
|
|
|
const selectedCodeMap = {} |
|
|
|
this.getValidProcessCodes(row.processCodes, validOrderCodes).forEach(code => { |
|
|
|
selectedCodeMap[code] = true |
|
|
|
}) |
|
|
|
const validCodes = validOrderCodes.filter(code => selectedCodeMap[code]) |
|
|
|
if (validCodes.length === 0) { |
|
|
|
this.$message.warning(`事业部【${row.buDesc || buNo}】至少需要选择一个可见进度`) |
|
|
|
return |
|
|
|
} |
|
|
|
const showAll = validCodes.length >= allCodeCount |
|
|
|
if (!showAll) { |
|
|
|
nextMap[buNo] = { |
|
|
|
showAll: false, |
|
|
|
processCodes: validCodes |
|
|
|
} |
|
|
|
const showAll = validCodes.length >= validOrderCodes.length |
|
|
|
nextMap[buNo] = { |
|
|
|
showAll: showAll, |
|
|
|
processOrderCodes: validOrderCodes, |
|
|
|
processCodes: showAll ? validOrderCodes.slice() : validCodes |
|
|
|
} |
|
|
|
submitRows.push({ |
|
|
|
buNo: buNo, |
|
|
|
showAll: showAll, |
|
|
|
processCodes: validCodes |
|
|
|
processCodes: validCodes, |
|
|
|
processOrderCodes: validOrderCodes |
|
|
|
}) |
|
|
|
} |
|
|
|
const inData = { |
|
|
|
@ -1309,7 +1584,11 @@ export default { |
|
|
|
this.ensureBuProcessConfigRows() |
|
|
|
this.buProcessConfigDialogVisible = false |
|
|
|
this.$message.success(data.msg || '事业部进度展示设置已保存') |
|
|
|
this.refreshTrackingTableLayout() |
|
|
|
// 保存后重新拉取工序列和列表,确保页面立即按最新可见性与顺序刷新。 |
|
|
|
this.queryProcessColumns().then(() => { |
|
|
|
this.getDataList() |
|
|
|
this.refreshTrackingTableLayout() |
|
|
|
}) |
|
|
|
}).catch(() => { |
|
|
|
this.$message.error('事业部进度展示设置保存异常') |
|
|
|
}) |
|
|
|
@ -1614,6 +1893,7 @@ export default { |
|
|
|
this.resetProcessTooltip() |
|
|
|
if (data && data.code === 0) { |
|
|
|
this.dataList = (data.page && data.page.list) || [] |
|
|
|
this.syncDataListProcessValues() |
|
|
|
this.totalPage = (data.page && data.page.totalCount) || 0 |
|
|
|
if (this.commentsEditingTrackingId) { |
|
|
|
const hasEditingRow = this.dataList.some(item => item.trackingId === this.commentsEditingTrackingId) |
|
|
|
@ -1667,7 +1947,9 @@ export default { |
|
|
|
this.searchData.projectPartSyncFlag = '' |
|
|
|
this.searchData.proofSyncFlag = '' |
|
|
|
this.searchData.proofingStatus = '' |
|
|
|
this.getDataList('Y') |
|
|
|
this.queryProcessColumns().then(() => { |
|
|
|
this.getDataList('Y') |
|
|
|
}) |
|
|
|
}, |
|
|
|
selectionChange (rows) { |
|
|
|
this.selectionRows = rows || [] |
|
|
|
@ -2432,10 +2714,12 @@ export default { |
|
|
|
return |
|
|
|
} |
|
|
|
const actualDate = this.formatDate(dateVal) |
|
|
|
// 工序日期被清空时,状态必须回退为“未完成”,避免出现“无日期但已完成”的脏状态。 |
|
|
|
const nextStatus = actualDate ? '已完成' : '未完成' |
|
|
|
this.updateProcessFromTable(row, processCol, { |
|
|
|
status: '已完成', |
|
|
|
status: nextStatus, |
|
|
|
actualDate: actualDate, |
|
|
|
remark: '表格直接选择日期' |
|
|
|
remark: actualDate ? '表格直接选择日期' : '表格清空实际完成日期' |
|
|
|
}, true) |
|
|
|
}, |
|
|
|
markProcessComplete (row, processCol) { |
|
|
|
@ -2471,8 +2755,7 @@ export default { |
|
|
|
} |
|
|
|
updateProofTrackingProcess(inData).then(({ data }) => { |
|
|
|
if (data && data.code === 0) { |
|
|
|
row[processCol.statusField] = status |
|
|
|
row[processCol.actualField] = actualDate |
|
|
|
this.updateRowProcessValue(row, processCol, status, actualDate) |
|
|
|
const cacheKey = `${row.trackingId}_${processCol.code}` |
|
|
|
if (this.processHistoryMap[cacheKey]) { |
|
|
|
this.$delete(this.processHistoryMap, cacheKey) |
|
|
|
@ -2828,7 +3111,7 @@ export default { |
|
|
|
flex-wrap: wrap; |
|
|
|
} |
|
|
|
|
|
|
|
.bu-process-config-dialog .el-checkbox-group { |
|
|
|
.bu-process-config-dialog .bu-process-order-list { |
|
|
|
display: grid; |
|
|
|
grid-template-columns: repeat(5, minmax(110px, 1fr)); |
|
|
|
column-gap: 12px; |
|
|
|
@ -2849,16 +3132,60 @@ export default { |
|
|
|
vertical-align: top; |
|
|
|
} |
|
|
|
|
|
|
|
.bu-process-config-dialog .bu-process-list-column .el-checkbox, |
|
|
|
.bu-process-config-dialog .bu-process-list-column .el-checkbox + .el-checkbox { |
|
|
|
.bu-process-config-dialog .bu-process-order-item { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
min-height: 28px; |
|
|
|
padding: 2px 6px; |
|
|
|
border: 1px solid transparent; |
|
|
|
border-radius: 4px; |
|
|
|
cursor: move; |
|
|
|
transition: border-color .2s ease, background-color .2s ease; |
|
|
|
} |
|
|
|
|
|
|
|
.bu-process-config-dialog .bu-process-order-item:hover { |
|
|
|
border-color: #7cc4ff; |
|
|
|
background: #f5fbff; |
|
|
|
} |
|
|
|
|
|
|
|
.bu-process-config-dialog .bu-process-order-item.is-dragging { |
|
|
|
opacity: .55; |
|
|
|
border-color: #409eff; |
|
|
|
background: #ecf5ff; |
|
|
|
} |
|
|
|
|
|
|
|
.bu-process-config-dialog .process-order-handle { |
|
|
|
margin-right: 6px; |
|
|
|
color: #909399; |
|
|
|
font-size: 14px; |
|
|
|
} |
|
|
|
|
|
|
|
.bu-process-config-dialog .bu-process-order-item .el-checkbox, |
|
|
|
.bu-process-config-dialog .bu-process-order-item .el-checkbox + .el-checkbox { |
|
|
|
width: 100%; |
|
|
|
margin: 0 !important; |
|
|
|
} |
|
|
|
|
|
|
|
.bu-process-config-dialog .bu-process-list-column .el-checkbox__label { |
|
|
|
.bu-process-config-dialog .bu-process-order-item .el-checkbox__label { |
|
|
|
white-space: nowrap; |
|
|
|
} |
|
|
|
|
|
|
|
.bu-process-config-dialog .bu-process-config-tip { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
gap: 6px; |
|
|
|
margin-bottom: 8px; |
|
|
|
padding: 6px 10px; |
|
|
|
border-radius: 4px; |
|
|
|
background: #f4f8ff; |
|
|
|
color: #5f6b7a; |
|
|
|
font-size: 12px; |
|
|
|
} |
|
|
|
|
|
|
|
.bu-process-config-dialog .bu-process-config-tip i { |
|
|
|
color: #409eff; |
|
|
|
} |
|
|
|
|
|
|
|
.button-col { |
|
|
|
margin-bottom: 8px; |
|
|
|
} |
|
|
|
|