|
|
@@ -9,7 +9,7 @@
|
|
|
:pagination="pagination"
|
|
|
:datasource="datasource"
|
|
|
:page-size="20"
|
|
|
- :cache-key="useNewColumns ? 'routed_detailed_list_v2' : 'routed_detailed_list'"
|
|
|
+ :cache-key="useNewColumns ? 'routed_detailed_list_v3' : 'routed_detailed_list'"
|
|
|
class="dict-table"
|
|
|
tool-class="ele-toolbar-actions"
|
|
|
:height="tableHeight"
|
|
|
@@ -76,9 +76,17 @@
|
|
|
</el-input>
|
|
|
</template>
|
|
|
|
|
|
+ <!-- 序号:与新 columns 方案绑定。新方案按层级单独计数(同层 1、2、3…),老方案用连续行号 -->
|
|
|
+ <template v-slot:rowIndex="{ row, $index }">
|
|
|
+ {{ rowIndexText(row, $index) }}
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 总重:前端按 用量 × 单重 计算(用量/单重改了立即跟着变) -->
|
|
|
+ <template v-slot:totalWeight="{ row }">{{ totalWeightOf(row) }}</template>
|
|
|
+
|
|
|
<template v-slot:versions="{ row }">
|
|
|
+ <!-- 版本为空就留空,不显示"无" -->
|
|
|
<template v-if="row.versions">V{{ row.versions }}.0</template>
|
|
|
- <template v-else>无</template>
|
|
|
</template>
|
|
|
|
|
|
<template v-slot:rootCategoryLevelId="{ row }"
|
|
|
@@ -154,7 +162,7 @@
|
|
|
v-for="item in row.resourceBomVersionList"
|
|
|
:key="item.versions"
|
|
|
:value="item.versions"
|
|
|
- :label="'V' + item.versions + '.0'"
|
|
|
+ :label="item.versions ? 'V' + item.versions + '.0' : ''"
|
|
|
></el-option>
|
|
|
</el-select>
|
|
|
</div>
|
|
|
@@ -292,9 +300,15 @@
|
|
|
|
|
|
data() {
|
|
|
return {
|
|
|
+ // 当前分页位置
|
|
|
+ currentPage: 1,
|
|
|
+ currentLimit: 20,
|
|
|
+ // 层级序号:rowId -> 该行在“同层级”里的序号(跨页连续)
|
|
|
+ levelSeqMap: {},
|
|
|
+ levelSeqKey: '',
|
|
|
produceTypeList,
|
|
|
clientEnvironmentId: this.$store.state.user.info.clientEnvironmentId,
|
|
|
- // 是否启用新 columns 方案(true=新方案,false=老方案)
|
|
|
+ // 是否启用新 columns 方案(true=新方案,false=老方案);序号方案与新 columns 方案绑定
|
|
|
useNewColumns: false,
|
|
|
pagination: {
|
|
|
tableTotal: 0
|
|
|
@@ -488,23 +502,27 @@
|
|
|
width: 100
|
|
|
},
|
|
|
{
|
|
|
- prop: 'sn',
|
|
|
- label: '明细表序号',
|
|
|
+ // 序号:普通列 + 前端插槽渲染行号(见模板 v-slot:rowIndex),不绑定 sn;
|
|
|
+ // 也不能用 type: 'index':index 列不在列设置缓存里,会被 ele-pro-table 排到最前面。
|
|
|
+ prop: 'rowIndex',
|
|
|
+ columnKey: 'rowIndex',
|
|
|
+ label: '序号',
|
|
|
align: 'center',
|
|
|
- width: 120,
|
|
|
- showOverflowTooltip: true
|
|
|
+ width: 90,
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ slot: 'rowIndex'
|
|
|
},
|
|
|
{
|
|
|
prop: 'categoryCode',
|
|
|
label: '物料编码',
|
|
|
showOverflowTooltip: true,
|
|
|
- width: 120
|
|
|
+ width: 180
|
|
|
},
|
|
|
{
|
|
|
prop: 'imgCode',
|
|
|
label: '零部件图号(规格型号)',
|
|
|
showOverflowTooltip: true,
|
|
|
- width: 150
|
|
|
+ width: 120
|
|
|
},
|
|
|
{
|
|
|
prop: 'versions',
|
|
|
@@ -556,6 +574,7 @@
|
|
|
{
|
|
|
prop: 'totalWeight',
|
|
|
label: '总重',
|
|
|
+ slot: 'totalWeight',
|
|
|
showOverflowTooltip: true,
|
|
|
align: 'right',
|
|
|
width: 100
|
|
|
@@ -719,6 +738,9 @@
|
|
|
// this.getZeroPartPros('zeroPartPros');
|
|
|
this.getContactList();
|
|
|
this.getRuntianConfig();
|
|
|
+ // 打开组件时自愈一次列缓存(新老两套列方案各一份),避免“列配置变了 → 新列被顶到第一列”
|
|
|
+ this.healColumnsCache('routed_detailed_list', this.oldColumnsConfig);
|
|
|
+ this.healColumnsCache('routed_detailed_list_v3', this.newColumnsConfig);
|
|
|
},
|
|
|
|
|
|
props: {
|
|
|
@@ -820,6 +842,107 @@
|
|
|
},
|
|
|
|
|
|
methods: {
|
|
|
+ // 序号方案与新 columns 方案绑定:老方案用连续行号,新方案按层级计数
|
|
|
+ rowIndexText(row, index) {
|
|
|
+ if (!this.useNewColumns) {
|
|
|
+ return (this.currentPage - 1) * this.currentLimit + index + 1;
|
|
|
+ }
|
|
|
+ return this.levelSeqMap[row.id] != null
|
|
|
+ ? this.levelSeqMap[row.id]
|
|
|
+ : this.levelSeq(row, index);
|
|
|
+ },
|
|
|
+
|
|
|
+ // 拉整棵树的清单,算出每行在“同层级”里的序号(跨页也连续)
|
|
|
+ async ensureLevelSeqMap(where) {
|
|
|
+ const attr = this.attributeData || {};
|
|
|
+ const key = [attr.id, attr.bomType, JSON.stringify(where || {})].join('|');
|
|
|
+ if (this.levelSeqKey === key) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ const res = await getBomPageCategoryId({
|
|
|
+ ...(where || {}),
|
|
|
+ pageNum: 1,
|
|
|
+ size: 100000,
|
|
|
+ id: attr.id,
|
|
|
+ bomType: attr.bomType
|
|
|
+ });
|
|
|
+ const map = {};
|
|
|
+ const counters = {};
|
|
|
+ ((res && res.list) || []).forEach((item) => {
|
|
|
+ const level = String(item.level == null ? '' : item.level);
|
|
|
+ counters[level] = (counters[level] || 0) + 1;
|
|
|
+ map[item.id] = counters[level];
|
|
|
+ });
|
|
|
+ this.levelSeqMap = map;
|
|
|
+ this.levelSeqKey = key;
|
|
|
+ } catch (e) {
|
|
|
+ // 取不到就退化成“当前页内按层级计数”
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 兜底:当前页内按层级计数(同层 1、2、3…,层级变了重新从 1 开始)
|
|
|
+ // 例:层级 1、1、2、2 → 序号 1、2、1、2
|
|
|
+ levelSeq(row, index) {
|
|
|
+ const table = this.$refs.table;
|
|
|
+ const rows = (table && typeof table.getData === 'function' && table.getData()) || [];
|
|
|
+ const level = row ? String(row.level == null ? '' : row.level) : '';
|
|
|
+ let seq = 0;
|
|
|
+ const end = Math.min(index, rows.length - 1);
|
|
|
+ for (let i = 0; i <= end; i++) {
|
|
|
+ const current = rows[i];
|
|
|
+ const currentLevel = current ? String(current.level == null ? '' : current.level) : '';
|
|
|
+ if (currentLevel === level) {
|
|
|
+ seq += 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return seq;
|
|
|
+ },
|
|
|
+
|
|
|
+ // 总重 = 单台用量 × 单重(前端计算)
|
|
|
+ totalWeightOf(row) {
|
|
|
+ const toNumber = (v) =>
|
|
|
+ v === null || v === undefined || v === '' ? null : Number(v);
|
|
|
+ const dosage = toNumber(row && row.dosage);
|
|
|
+ const netWeight = toNumber(row && row.netWeight);
|
|
|
+ if (dosage === null || netWeight === null) {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ if (isNaN(dosage) || isNaN(netWeight)) {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ return (dosage * netWeight).toFixed(2);
|
|
|
+ },
|
|
|
+
|
|
|
+ // ele-pro-table 的列顺序是按 localStorage 里的列缓存恢复的:配置里新增/删除列之后,
|
|
|
+ // 旧缓存里没有新列 → 新列会被排到第一列(表现为“序号跑到第一列,点列重置才恢复”)。
|
|
|
+ // 这里做一次自愈:缓存的列集合与当前配置不一致就清掉,让列顺序回到配置顺序。
|
|
|
+ healColumnsCache(cacheKey, columns) {
|
|
|
+ const key = cacheKey + 'Cols';
|
|
|
+ try {
|
|
|
+ const raw = localStorage.getItem(key);
|
|
|
+ if (!raw) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const cached = JSON.parse(raw);
|
|
|
+ if (!Array.isArray(cached) || !cached.length) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const wanted = (columns || [])
|
|
|
+ .filter((c) => c && c.type !== 'index' && c.columnKey !== 'index')
|
|
|
+ .map((c) => c.columnKey || c.prop)
|
|
|
+ .filter((k) => !!k);
|
|
|
+ const cachedKeys = cached.map((c) => c.id);
|
|
|
+ // 只判断“配置里有、缓存里没有”的列(这类列才会被 ele-pro-table 排到第一列);
|
|
|
+ // 缓存里多出来的列(比如操作列)不用管。
|
|
|
+ const missing = wanted.filter((k) => !cachedKeys.includes(k));
|
|
|
+ if (missing.length) {
|
|
|
+ localStorage.removeItem(key);
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ localStorage.removeItem(key);
|
|
|
+ }
|
|
|
+ },
|
|
|
attributeTypeText(v) {
|
|
|
if (v) {
|
|
|
let a = this.attributeList.find((item) => item.value == v);
|
|
|
@@ -838,7 +961,7 @@
|
|
|
});
|
|
|
},
|
|
|
|
|
|
- // 根据系统参数 is_runtian 判断是否启用新 columns 方案
|
|
|
+ // 根据系统参数 is_runtian 判断是否启用新 columns 方案;序号方案随之切换
|
|
|
// 兼容常见返回:'1' / 1 / { value: 1 } / { paramValue: '1' } / true
|
|
|
async getRuntianConfig() {
|
|
|
try {
|
|
|
@@ -926,6 +1049,9 @@
|
|
|
|
|
|
/* 表格数据源 */
|
|
|
async datasource({ where, page, limit }) {
|
|
|
+ // 序号跨页连续用
|
|
|
+ this.currentPage = page || 1;
|
|
|
+ this.currentLimit = limit || 20;
|
|
|
// let that = this;
|
|
|
// console.log(getBomPageCategoryId({
|
|
|
// ...where,
|
|
|
@@ -984,6 +1110,11 @@
|
|
|
bomType: this.attributeData.bomType
|
|
|
});
|
|
|
|
|
|
+ // 新 columns 方案下序号按层级计数且跨页连续:拉一次整棵树的清单算出每行在同层级里的序号
|
|
|
+ if (this.useNewColumns) {
|
|
|
+ await this.ensureLevelSeqMap(where);
|
|
|
+ }
|
|
|
+
|
|
|
if (this.isList) {
|
|
|
data = this.listTow;
|
|
|
}
|