|
|
|
@ -1,6 +1,16 @@ |
|
|
|
<template> |
|
|
|
<div class="mod-config"> |
|
|
|
<el-form :inline="true" :model="searchData" label-position="top" class="search-form"> |
|
|
|
<el-form-item label="BU"> |
|
|
|
<el-select v-model="searchData.buNo" clearable filterable placeholder="全部" style="width: 130px" @change="handleSearchBuChange"> |
|
|
|
<el-option |
|
|
|
v-for="item in userBuList" |
|
|
|
:key="`searchBu_${item.buNo}`" |
|
|
|
:label="item.buDesc ? `${normalizeBuNo(item.buNo, searchData.site)}-${item.buDesc}` : normalizeBuNo(item.buNo, searchData.site)" |
|
|
|
:value="normalizeBuNo(item.buNo, searchData.site)" |
|
|
|
/> |
|
|
|
</el-select> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="项目编码"> |
|
|
|
<el-input v-model="searchData.projectNo" clearable placeholder="请输入项目编码" style="width: 140px" /> |
|
|
|
</el-form-item> |
|
|
|
@ -48,6 +58,7 @@ |
|
|
|
<el-button type="warning" @click="openCreateProofDialog()">新增打样</el-button> |
|
|
|
<el-button type="success" plain :loading="syncNpiLoading" @click="syncToNpi()">同步项目物料到NPI</el-button> |
|
|
|
<el-button type="success" plain :loading="syncProofLoading" @click="syncProofToNpi()">同步打样到NPI</el-button> |
|
|
|
<el-button type="info" v-if="isAuth('833001005:set')" plain @click="openBuProcessConfigDialog">事业部进度设置</el-button> |
|
|
|
</el-row> |
|
|
|
</el-form-item> |
|
|
|
</el-form> |
|
|
|
@ -99,7 +110,7 @@ |
|
|
|
</el-table-column> |
|
|
|
|
|
|
|
<el-table-column |
|
|
|
v-for="item in processColumns" |
|
|
|
v-for="item in visibleProcessColumns" |
|
|
|
:key="item.code" |
|
|
|
:label="item.label" |
|
|
|
width="120" |
|
|
|
@ -107,7 +118,10 @@ |
|
|
|
header-align="center" |
|
|
|
> |
|
|
|
<template slot-scope="scope"> |
|
|
|
<div :class="['process-cell', isProcessComplete(scope.row, item) ? 'is-complete' : '']"> |
|
|
|
<div |
|
|
|
v-if="isProcessColumnVisibleForRow(scope.row, item)" |
|
|
|
:class="['process-cell', isProcessComplete(scope.row, item) ? 'is-complete' : '']" |
|
|
|
> |
|
|
|
<el-date-picker |
|
|
|
v-if="batchEditMode" |
|
|
|
v-model="scope.row[item.actualField]" |
|
|
|
@ -143,6 +157,7 @@ |
|
|
|
>√</el-button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div v-else class="process-cell process-cell--masked"></div> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
|
|
|
|
@ -217,6 +232,37 @@ |
|
|
|
}" |
|
|
|
>{{ processTooltip.content }}</div> |
|
|
|
|
|
|
|
<el-dialog |
|
|
|
title="事业部进度展示设置" |
|
|
|
:visible.sync="buProcessConfigDialogVisible" |
|
|
|
width="900px" |
|
|
|
:close-on-click-modal="false" |
|
|
|
custom-class="bu-process-config-dialog" |
|
|
|
> |
|
|
|
<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" |
|
|
|
@change="handleBuProcessCodesChange(scope.row)" |
|
|
|
> |
|
|
|
<el-checkbox |
|
|
|
v-for="column in processColumns" |
|
|
|
:key="`${scope.row.buNo}_${column.code}`" |
|
|
|
:label="column.code" |
|
|
|
>{{ column.label }}</el-checkbox> |
|
|
|
</el-checkbox-group> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
</el-table> |
|
|
|
|
|
|
|
<div slot="footer"> |
|
|
|
<el-button @click="buProcessConfigDialogVisible = false">取消</el-button> |
|
|
|
<el-button type="primary" @click="saveBuProcessConfig">保存设置</el-button> |
|
|
|
</div> |
|
|
|
</el-dialog> |
|
|
|
|
|
|
|
<el-dialog :title="oneKeyDialogMode === 'edit' ? '修改项目/物料/打样' : '一键创建项目/物料/打样'" :visible.sync="oneKeyDialogVisible" :close-on-click-modal="false" width="1000px"> |
|
|
|
<el-form :model="oneKeyForm" label-position="top" class="one-key-grid-form"> |
|
|
|
<el-row :gutter="16"> |
|
|
|
@ -762,7 +808,9 @@ import { |
|
|
|
finishProofTracking, |
|
|
|
oneKeyCreateProofTracking, |
|
|
|
oneKeyUpdateProofTracking, |
|
|
|
queryProofTrackingBuProcessConfig, |
|
|
|
queryProofTrackingProcessHistory, |
|
|
|
saveProofTrackingBuProcessConfig, |
|
|
|
searchProjectInfoTracking, |
|
|
|
searchProjectPartTracking, |
|
|
|
searchProofTracking, |
|
|
|
@ -837,6 +885,7 @@ export default { |
|
|
|
userName: this.$store.state.user.name, |
|
|
|
projectNo: '', |
|
|
|
projectDesc: '', |
|
|
|
buNo: '', |
|
|
|
testPartNo: '', |
|
|
|
partDesc: '', |
|
|
|
customerNo: '', |
|
|
|
@ -860,6 +909,9 @@ export default { |
|
|
|
{ label: 'Inspection', code: 'inspection', planField: 'inspectionPlanDate', actualField: 'inspectionActualDate', statusField: 'inspectionStatus' }, |
|
|
|
{ label: 'Delivery&Package', code: 'deliveryPackage', planField: 'deliveryPackagePlanDate', actualField: 'deliveryPackageActualDate', statusField: 'deliveryPackageStatus' } |
|
|
|
], |
|
|
|
buProcessConfigDialogVisible: false, |
|
|
|
buProcessConfigRows: [], |
|
|
|
buProcessConfigMap: {}, |
|
|
|
projectCategoryList: ['Low Risk', 'High Risk', 'Sustaining'], |
|
|
|
cProjectRegionList: [ |
|
|
|
{ cProjectRegion: 'Global' }, |
|
|
|
@ -1004,19 +1056,262 @@ export default { |
|
|
|
} |
|
|
|
}, |
|
|
|
activated () { |
|
|
|
this.loadUserBuList() |
|
|
|
this.loadUserBuList().then(() => { |
|
|
|
this.queryBuProcessConfig() |
|
|
|
}) |
|
|
|
this.getDataList() |
|
|
|
}, |
|
|
|
computed: { |
|
|
|
visibleProcessColumns () { |
|
|
|
const searchBuNo = this.getSelectedSearchBuNo() |
|
|
|
// 指定了查询BU时,整表进度列按该BU配置展示。 |
|
|
|
if (!searchBuNo) { |
|
|
|
return this.processColumns |
|
|
|
} |
|
|
|
const visibleCodes = this.getProcessVisibleCodesByBuNo(searchBuNo) |
|
|
|
if (!visibleCodes) { |
|
|
|
return this.processColumns |
|
|
|
} |
|
|
|
const visibleColumns = this.processColumns.filter(item => visibleCodes.indexOf(item.code) > -1) |
|
|
|
return visibleColumns.length > 0 ? visibleColumns : this.processColumns |
|
|
|
} |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
loadUserBuList () { |
|
|
|
if (this.userBuList.length > 0) { |
|
|
|
return |
|
|
|
this.ensureBuProcessConfigRows() |
|
|
|
return Promise.resolve(this.userBuList) |
|
|
|
} |
|
|
|
const params = { username: this.$store.state.user.name } |
|
|
|
getSiteAndBuByUserName(params).then(({ data }) => { |
|
|
|
return getSiteAndBuByUserName(params).then(({ data }) => { |
|
|
|
if (data && data.code === 0) { |
|
|
|
this.userBuList = data.rows || [] |
|
|
|
const excludedBuNoList = ['3_02-Hardtag', '4_04-MHM', '5_05-Alpha'] |
|
|
|
this.userBuList = (data.rows || []).filter(item => { |
|
|
|
const buNo = item && item.buNo ? String(item.buNo).trim() : '' |
|
|
|
return excludedBuNoList.indexOf(buNo) === -1 |
|
|
|
}) |
|
|
|
this.ensureBuProcessConfigRows() |
|
|
|
} |
|
|
|
return this.userBuList |
|
|
|
}).catch(() => { |
|
|
|
this.userBuList = [] |
|
|
|
this.ensureBuProcessConfigRows() |
|
|
|
return [] |
|
|
|
}) |
|
|
|
}, |
|
|
|
getAllProcessCodes () { |
|
|
|
return this.processColumns.map(item => item.code) |
|
|
|
}, |
|
|
|
normalizeBuNo (buNo, site) { |
|
|
|
const rawBuNo = buNo == null ? '' : String(buNo).trim() |
|
|
|
if (!rawBuNo) { |
|
|
|
return '' |
|
|
|
} |
|
|
|
const splitIdx = rawBuNo.indexOf('_') |
|
|
|
if (splitIdx < 1 || splitIdx >= rawBuNo.length - 1) { |
|
|
|
return rawBuNo |
|
|
|
} |
|
|
|
// BU统一按“去掉site前缀”展示与保存,例如 2_01-Label -> 01-Label。 |
|
|
|
return rawBuNo.substring(splitIdx + 1) |
|
|
|
}, |
|
|
|
getValidProcessCodes (codes) { |
|
|
|
if (!Array.isArray(codes) || codes.length === 0) { |
|
|
|
return [] |
|
|
|
} |
|
|
|
const allCodes = this.getAllProcessCodes() |
|
|
|
const normalizedCodes = [] |
|
|
|
codes.forEach(code => { |
|
|
|
const codeVal = code == null ? '' : String(code).trim() |
|
|
|
if (!codeVal || allCodes.indexOf(codeVal) === -1) { |
|
|
|
return |
|
|
|
} |
|
|
|
if (normalizedCodes.indexOf(codeVal) === -1) { |
|
|
|
normalizedCodes.push(codeVal) |
|
|
|
} |
|
|
|
}) |
|
|
|
return normalizedCodes |
|
|
|
}, |
|
|
|
getBuProcessConfigEntry (buNo, site) { |
|
|
|
const normalizedBuNo = this.normalizeBuNo(buNo, site) |
|
|
|
if (!normalizedBuNo) { |
|
|
|
return null |
|
|
|
} |
|
|
|
const config = this.buProcessConfigMap[normalizedBuNo] |
|
|
|
if (config) { |
|
|
|
return { key: normalizedBuNo, config: config } |
|
|
|
} |
|
|
|
return null |
|
|
|
}, |
|
|
|
getSelectedSearchBuNo () { |
|
|
|
return this.normalizeBuNo(this.searchData.buNo, this.searchData.site) |
|
|
|
}, |
|
|
|
handleSearchBuChange () { |
|
|
|
// BU筛选变化(含清空)后立即重新查询,并回到第一页。 |
|
|
|
this.getDataList('Y') |
|
|
|
}, |
|
|
|
getProcessVisibleCodesByBuNo (buNo, site) { |
|
|
|
const configEntry = this.getBuProcessConfigEntry(buNo, site) |
|
|
|
const config = configEntry ? configEntry.config : null |
|
|
|
// 没有配置或配置为全部显示时,返回 null 表示该 BU 工序列不过滤。 |
|
|
|
if (!config || config.showAll !== false) { |
|
|
|
return null |
|
|
|
} |
|
|
|
const validCodes = this.getValidProcessCodes(config.processCodes) |
|
|
|
if (validCodes.length === 0 || validCodes.length >= this.processColumns.length) { |
|
|
|
return null |
|
|
|
} |
|
|
|
return validCodes |
|
|
|
}, |
|
|
|
isProcessColumnVisibleForRow (row, processCol) { |
|
|
|
if (!row || !processCol) { |
|
|
|
return true |
|
|
|
} |
|
|
|
// 已指定查询BU时,列集合已经按查询BU过滤,不再按行二次隐藏。 |
|
|
|
if (this.getSelectedSearchBuNo()) { |
|
|
|
return true |
|
|
|
} |
|
|
|
const visibleCodes = this.getProcessVisibleCodesByBuNo(row.buNo, row.site) |
|
|
|
if (!visibleCodes) { |
|
|
|
return true |
|
|
|
} |
|
|
|
return visibleCodes.indexOf(processCol.code) > -1 |
|
|
|
}, |
|
|
|
queryBuProcessConfig () { |
|
|
|
const inData = { |
|
|
|
site: this.$store.state.user.site, |
|
|
|
userName: this.$store.state.user.name |
|
|
|
} |
|
|
|
queryProofTrackingBuProcessConfig(inData).then(({ data }) => { |
|
|
|
if (!(data && data.code === 0)) { |
|
|
|
this.$message.error((data && data.msg) || '加载事业部进度展示配置失败') |
|
|
|
return |
|
|
|
} |
|
|
|
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 |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
this.buProcessConfigMap = nextMap |
|
|
|
this.ensureBuProcessConfigRows() |
|
|
|
this.refreshTrackingTableLayout() |
|
|
|
}).catch(() => { |
|
|
|
this.$message.error('加载事业部进度展示配置异常') |
|
|
|
}) |
|
|
|
}, |
|
|
|
ensureBuProcessConfigRows () { |
|
|
|
const allCodes = this.getAllProcessCodes() |
|
|
|
const rows = [] |
|
|
|
const usedBuMap = {} |
|
|
|
const appendRow = (buNo, buDesc, site) => { |
|
|
|
const key = this.normalizeBuNo(buNo, site || this.$store.state.user.site) |
|
|
|
if (!key || usedBuMap[key]) { |
|
|
|
return |
|
|
|
} |
|
|
|
usedBuMap[key] = true |
|
|
|
const cfg = this.buProcessConfigMap[key] |
|
|
|
const row = { |
|
|
|
buNo: key, |
|
|
|
buDesc: buDesc || key, |
|
|
|
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 |
|
|
|
} |
|
|
|
} |
|
|
|
rows.push(row) |
|
|
|
} |
|
|
|
this.userBuList.forEach(item => { |
|
|
|
if (!item || !item.buNo) { |
|
|
|
return |
|
|
|
} |
|
|
|
appendRow(item.buNo, item.buDesc || this.normalizeBuNo(item.buNo, this.$store.state.user.site), this.$store.state.user.site) |
|
|
|
}) |
|
|
|
Object.keys(this.buProcessConfigMap).forEach(buNo => { |
|
|
|
appendRow(buNo, buNo, this.$store.state.user.site) |
|
|
|
}) |
|
|
|
this.buProcessConfigRows = rows |
|
|
|
}, |
|
|
|
openBuProcessConfigDialog () { |
|
|
|
this.ensureBuProcessConfigRows() |
|
|
|
this.buProcessConfigDialogVisible = true |
|
|
|
}, |
|
|
|
refreshTrackingTableLayout () { |
|
|
|
this.$nextTick(() => { |
|
|
|
const tableRef = this.$refs.trackingTable |
|
|
|
if (tableRef && tableRef.doLayout) { |
|
|
|
tableRef.doLayout() |
|
|
|
} |
|
|
|
}) |
|
|
|
}, |
|
|
|
handleBuProcessCodesChange (row) { |
|
|
|
if (!row) { |
|
|
|
return |
|
|
|
} |
|
|
|
row.processCodes = this.getValidProcessCodes(row.processCodes) |
|
|
|
}, |
|
|
|
saveBuProcessConfig () { |
|
|
|
if (!this.buProcessConfigRows || this.buProcessConfigRows.length === 0) { |
|
|
|
this.$message.warning('暂无可配置的事业部') |
|
|
|
return |
|
|
|
} |
|
|
|
const nextMap = {} |
|
|
|
const allCodeCount = this.processColumns.length |
|
|
|
const submitRows = [] |
|
|
|
for (let i = 0; i < this.buProcessConfigRows.length; i++) { |
|
|
|
const row = this.buProcessConfigRows[i] |
|
|
|
const buNo = this.normalizeBuNo(row && row.buNo ? row.buNo : '', this.$store.state.user.site) |
|
|
|
if (!buNo) { |
|
|
|
continue |
|
|
|
} |
|
|
|
const validCodes = this.getValidProcessCodes(row.processCodes) |
|
|
|
if (validCodes.length === 0) { |
|
|
|
this.$message.warning(`事业部【${row.buDesc || buNo}】至少需要选择一个可见进度`) |
|
|
|
return |
|
|
|
} |
|
|
|
const showAll = validCodes.length >= allCodeCount |
|
|
|
if (!showAll) { |
|
|
|
nextMap[buNo] = { |
|
|
|
showAll: false, |
|
|
|
processCodes: validCodes |
|
|
|
} |
|
|
|
} |
|
|
|
submitRows.push({ |
|
|
|
buNo: buNo, |
|
|
|
showAll: showAll, |
|
|
|
processCodes: validCodes |
|
|
|
}) |
|
|
|
} |
|
|
|
const inData = { |
|
|
|
site: this.$store.state.user.site, |
|
|
|
updateBy: this.$store.state.user.name, |
|
|
|
rows: submitRows |
|
|
|
} |
|
|
|
saveProofTrackingBuProcessConfig(inData).then(({ data }) => { |
|
|
|
if (!(data && data.code === 0)) { |
|
|
|
this.$message.error((data && data.msg) || '事业部进度展示设置保存失败') |
|
|
|
return |
|
|
|
} |
|
|
|
this.buProcessConfigMap = nextMap |
|
|
|
this.ensureBuProcessConfigRows() |
|
|
|
this.buProcessConfigDialogVisible = false |
|
|
|
this.$message.success(data.msg || '事业部进度展示设置已保存') |
|
|
|
this.refreshTrackingTableLayout() |
|
|
|
}).catch(() => { |
|
|
|
this.$message.error('事业部进度展示设置保存异常') |
|
|
|
}) |
|
|
|
}, |
|
|
|
getRoleApi (apiKey) { |
|
|
|
@ -1312,6 +1607,7 @@ export default { |
|
|
|
page: this.pageIndex, |
|
|
|
limit: this.pageSize |
|
|
|
}) |
|
|
|
inData.buNo = this.normalizeBuNo(inData.buNo, inData.site) |
|
|
|
this.dataListLoading = true |
|
|
|
searchProofTracking(inData).then(({ data }) => { |
|
|
|
this.dataListLoading = false |
|
|
|
@ -1363,6 +1659,7 @@ export default { |
|
|
|
resetSearch () { |
|
|
|
this.searchData.projectNo = '' |
|
|
|
this.searchData.projectDesc = '' |
|
|
|
this.searchData.buNo = '' |
|
|
|
this.searchData.testPartNo = '' |
|
|
|
this.searchData.partDesc = '' |
|
|
|
this.searchData.customerNo = '' |
|
|
|
@ -2531,6 +2828,37 @@ export default { |
|
|
|
flex-wrap: wrap; |
|
|
|
} |
|
|
|
|
|
|
|
.bu-process-config-dialog .el-checkbox-group { |
|
|
|
display: grid; |
|
|
|
grid-template-columns: repeat(5, minmax(110px, 1fr)); |
|
|
|
column-gap: 12px; |
|
|
|
row-gap: 8px; |
|
|
|
align-items: center; |
|
|
|
} |
|
|
|
|
|
|
|
.bu-process-config-dialog .bu-process-list-column .cell { |
|
|
|
white-space: normal !important; |
|
|
|
height: auto !important; |
|
|
|
line-height: 20px; |
|
|
|
padding-top: 6px; |
|
|
|
padding-bottom: 6px; |
|
|
|
overflow: hidden; |
|
|
|
} |
|
|
|
|
|
|
|
.bu-process-config-dialog .bu-process-list-column { |
|
|
|
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 { |
|
|
|
width: 100%; |
|
|
|
margin: 0 !important; |
|
|
|
} |
|
|
|
|
|
|
|
.bu-process-config-dialog .bu-process-list-column .el-checkbox__label { |
|
|
|
white-space: nowrap; |
|
|
|
} |
|
|
|
|
|
|
|
.button-col { |
|
|
|
margin-bottom: 8px; |
|
|
|
} |
|
|
|
@ -2587,6 +2915,10 @@ export default { |
|
|
|
color: #8c8c8c; |
|
|
|
} |
|
|
|
|
|
|
|
.process-cell--masked { |
|
|
|
background: transparent !important; |
|
|
|
} |
|
|
|
|
|
|
|
.process-content { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
|