|
@@ -2,7 +2,7 @@
|
|
|
|
|
|
/**
|
|
|
* @typedef {import('@/api/forecast/types').ForecastSummaryQueryParams} ForecastSummaryQueryParams
|
|
|
- * @typedef {import('@/api/forecast/types').SalesForecastMainListItemRecord} SalesForecastMainListItemRecord
|
|
|
+ * @typedef {import('@/api/forecast/types').SalesForecastMainRecord} SalesForecastMainRecord
|
|
|
* @typedef {import('./types').PageConfig} PageConfig
|
|
|
* @typedef {import('./types').ForecastSummaryComponent} ForecastSummaryComponent
|
|
|
*/
|
|
@@ -59,14 +59,14 @@ export default {
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
- * 表格数据
|
|
|
- * @type {Array<SalesForecastMainListItemRecord>}
|
|
|
+ * 表格数据(主表记录)
|
|
|
+ * @type {Array<SalesForecastMainRecord>}
|
|
|
*/
|
|
|
data: [],
|
|
|
|
|
|
/**
|
|
|
- * 选中的行数据
|
|
|
- * @type {Array<SalesForecastMainListItemRecord>}
|
|
|
+ * 选中的行数据(主表记录)
|
|
|
+ * @type {Array<SalesForecastMainRecord>}
|
|
|
*/
|
|
|
selectionList: [],
|
|
|
|
|
@@ -89,6 +89,10 @@ export default {
|
|
|
selection: false,
|
|
|
dialogClickModal: false,
|
|
|
menu: false,
|
|
|
+ // 启用行展开,展示子表格
|
|
|
+ expand: true,
|
|
|
+ expandRowKeys: [],
|
|
|
+ defaultExpandAll: false,
|
|
|
column: [
|
|
|
{
|
|
|
label: '年月',
|
|
@@ -135,59 +139,9 @@ export default {
|
|
|
{
|
|
|
label: '客户名称',
|
|
|
prop: 'customerName',
|
|
|
- minWidth: 180,
|
|
|
- search: true,
|
|
|
- searchSpan: 6,
|
|
|
- overHidden: true
|
|
|
- },
|
|
|
- {
|
|
|
- label: '品牌编码',
|
|
|
- prop: 'brandCode',
|
|
|
- minWidth: 120,
|
|
|
- search: true,
|
|
|
- searchSpan: 6
|
|
|
- },
|
|
|
- {
|
|
|
- label: '品牌名称',
|
|
|
- prop: 'brandName',
|
|
|
- minWidth: 120,
|
|
|
- search: true,
|
|
|
- searchSpan: 6
|
|
|
- },
|
|
|
- {
|
|
|
- label: '物料编码',
|
|
|
- prop: 'itemCode',
|
|
|
- minWidth: 140,
|
|
|
- search: true,
|
|
|
- searchSpan: 6
|
|
|
- },
|
|
|
- {
|
|
|
- label: '物料名称',
|
|
|
- prop: 'itemName',
|
|
|
minWidth: 200,
|
|
|
search: true,
|
|
|
- searchSpan: 6,
|
|
|
- overHidden: true
|
|
|
- },
|
|
|
- {
|
|
|
- label: '规格',
|
|
|
- prop: 'specs',
|
|
|
- minWidth: 120,
|
|
|
- overHidden: true
|
|
|
- },
|
|
|
- {
|
|
|
- label: '花纹',
|
|
|
- prop: 'pattern',
|
|
|
- minWidth: 100,
|
|
|
- overHidden: true
|
|
|
- },
|
|
|
- {
|
|
|
- label: '预测数量',
|
|
|
- prop: 'forecastQuantity',
|
|
|
- minWidth: 120,
|
|
|
- sortable: true,
|
|
|
- slot: true,
|
|
|
- align: 'right'
|
|
|
+ searchSpan: 6
|
|
|
},
|
|
|
{
|
|
|
label: '审批状态',
|
|
@@ -220,6 +174,31 @@ export default {
|
|
|
slot: true
|
|
|
}
|
|
|
]
|
|
|
+ },
|
|
|
+
|
|
|
+ // 子表(展开区)表格配置:展示 pcBladeSalesForecastSummaryList
|
|
|
+ childOption: {
|
|
|
+ height: 'auto',
|
|
|
+ calcHeight: 0,
|
|
|
+ tip: false,
|
|
|
+ searchShow: false,
|
|
|
+ border: true,
|
|
|
+ index: true,
|
|
|
+ viewBtn: false,
|
|
|
+ editBtn: false,
|
|
|
+ delBtn: false,
|
|
|
+ addBtn: false,
|
|
|
+ selection: false,
|
|
|
+ menu: false,
|
|
|
+ expand: false,
|
|
|
+ column: [
|
|
|
+ { label: '商品编码', prop: 'itemCode', minWidth: 120 },
|
|
|
+ { label: '商品名称', prop: 'itemName', minWidth: 180, overHidden: true },
|
|
|
+ { label: '规格型号', prop: 'specs', minWidth: 140, overHidden: true },
|
|
|
+ { label: '花型/图案', prop: 'pattern', minWidth: 120, overHidden: true },
|
|
|
+ { label: '品牌名称', prop: 'brandName', minWidth: 120, overHidden: true },
|
|
|
+ { label: '预测数量', prop: 'forecastQuantity', minWidth: 120, align: 'right', slot: true }
|
|
|
+ ]
|
|
|
}
|
|
|
}
|
|
|
},
|
|
@@ -260,7 +239,7 @@ export default {
|
|
|
/**
|
|
|
* 获取审批状态配置
|
|
|
* @param {number} status - 审批状态值
|
|
|
- * @returns {Object} 状态配置对象
|
|
|
+ * @returns {{label: string, type: string}} 状态配置对象
|
|
|
*/
|
|
|
getApprovalStatusConfig(status) {
|
|
|
const config = APPROVAL_STATUS_CONFIG[status]
|
|
@@ -351,7 +330,7 @@ export default {
|
|
|
/**
|
|
|
* 选择变化处理
|
|
|
* @this {ForecastSummaryComponent & Vue}
|
|
|
- * @param {Array<SalesForecastMainListItemRecord>} selection - 选中的行数据
|
|
|
+ * @param {Array<SalesForecastMainRecord>} selection - 选中的行数据
|
|
|
*/
|
|
|
selectionChange(selection) {
|
|
|
this.selectionList = selection
|
|
@@ -420,17 +399,26 @@ export default {
|
|
|
if (response && response.data && response.data.code === 200 && response.data.data) {
|
|
|
const pageData = response.data.data
|
|
|
const records = Array.isArray(pageData.records) ? pageData.records : []
|
|
|
- // 扁平化子列表供表格展示(保持ID为后端返回的原样,避免大整数精度丢失)
|
|
|
- const flat = []
|
|
|
- for (const rec of records) {
|
|
|
- const list = Array.isArray(rec.pcBladeSalesForecastSummaryList) ? rec.pcBladeSalesForecastSummaryList : []
|
|
|
- for (const item of list) {
|
|
|
- // 通过浅拷贝确保不会意外修改原对象
|
|
|
- flat.push({ ...item })
|
|
|
+ // 字段类型转换与BigInt处理
|
|
|
+ this.data = records.map(r => {
|
|
|
+ const children = Array.isArray(r.pcBladeSalesForecastSummaryList)
|
|
|
+ ? r.pcBladeSalesForecastSummaryList.map(it => ({
|
|
|
+ ...it,
|
|
|
+ idBigint: this.safeBigInt(it.id),
|
|
|
+ forecastMainIdBigint: it.forecastMainId != null ? this.safeBigInt(it.forecastMainId) : null,
|
|
|
+ year: Number(it.year),
|
|
|
+ month: Number(it.month),
|
|
|
+ forecastQuantity: typeof it.forecastQuantity === 'string' ? Number(it.forecastQuantity) : Number(it.forecastQuantity)
|
|
|
+ }))
|
|
|
+ : []
|
|
|
+ return {
|
|
|
+ ...r,
|
|
|
+ idBigint: this.safeBigInt(r.id),
|
|
|
+ year: Number(r.year),
|
|
|
+ month: Number(r.month),
|
|
|
+ pcBladeSalesForecastSummaryList: children
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- this.data = flat
|
|
|
+ })
|
|
|
this.page.total = Number(pageData.total) || 0
|
|
|
this.page.currentPage = Number(pageData.current) || 1
|
|
|
this.page.pageSize = Number(pageData.size) || 10
|
|
@@ -450,6 +438,20 @@ export default {
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
+ * 安全将值转换为BigInt
|
|
|
+ * @param {string|number|null|undefined} v
|
|
|
+ * @returns {bigint|null}
|
|
|
+ */
|
|
|
+ safeBigInt(v) {
|
|
|
+ try {
|
|
|
+ if (v === null || v === undefined || v === '') return null
|
|
|
+ return BigInt(v)
|
|
|
+ } catch (e) {
|
|
|
+ return null
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
* 获取预测汇总详情
|
|
|
* @this {ForecastSummaryComponent & Vue}
|
|
|
* @param {string|number} id - 预测汇总ID
|