|
@@ -1,7 +1,7 @@
|
|
|
import { getForecastList, addForecast, updateForecast } from '@/api/forecast'
|
|
|
import { getCustomerList } from '@/api/common'
|
|
|
import { getItemList } from '@/api/common'
|
|
|
-import { getSalesForecastSummaryPage } from '@/api/forecast/forecast-summary'
|
|
|
+import { getSalesForecastMainList } from '@/api/forecast/forecast-summary'
|
|
|
import {
|
|
|
APPROVAL_STATUS,
|
|
|
APPROVAL_STATUS_CONFIG,
|
|
@@ -10,7 +10,9 @@ import {
|
|
|
getApprovalStatusType,
|
|
|
canEdit,
|
|
|
FORECAST_FORM_RULES,
|
|
|
- DEFAULT_FORECAST_FORM
|
|
|
+ DEFAULT_FORECAST_FORM,
|
|
|
+ // 数字格式化
|
|
|
+ formatNumber as formatNum
|
|
|
} from '@/constants/forecast'
|
|
|
import { mapGetters } from 'vuex'
|
|
|
import ForecastFormAvue from '@/components/forecast-form/index'
|
|
@@ -100,7 +102,11 @@ export default {
|
|
|
addBtnText: '新增预测申报',
|
|
|
editBtnText: '编辑',
|
|
|
// 添加这个配置来完全隐藏操作列
|
|
|
+ // 并启用行展开功能以展示子表
|
|
|
menu: false,
|
|
|
+ expand: true,
|
|
|
+ expandRowKeys: [],
|
|
|
+ defaultExpandAll: false,
|
|
|
column: [
|
|
|
{
|
|
|
label: '年份',
|
|
@@ -134,51 +140,11 @@ export default {
|
|
|
width: 100
|
|
|
},
|
|
|
{
|
|
|
- label: '物料名称',
|
|
|
- prop: 'itemName',
|
|
|
- search: false,
|
|
|
- width: 200,
|
|
|
- overHidden: true
|
|
|
- },
|
|
|
- {
|
|
|
- label: '物料编码',
|
|
|
- prop: 'itemCode',
|
|
|
- search: false,
|
|
|
- width: 150,
|
|
|
- overHidden: true
|
|
|
- },
|
|
|
- {
|
|
|
- label: '规格',
|
|
|
- prop: 'specs',
|
|
|
- search: false,
|
|
|
- width: 150,
|
|
|
- overHidden: true
|
|
|
- },
|
|
|
- {
|
|
|
- label: '预测数量',
|
|
|
- prop: 'forecastQuantity',
|
|
|
- type: 'number',
|
|
|
- precision: 0,
|
|
|
- search: false,
|
|
|
- width: 120,
|
|
|
- align: 'right',
|
|
|
- slot: true
|
|
|
- },
|
|
|
- {
|
|
|
- label: '当前库存',
|
|
|
- prop: 'currentInventory',
|
|
|
- type: 'number',
|
|
|
- precision: 0,
|
|
|
- search: false,
|
|
|
- width: 120,
|
|
|
- align: 'right',
|
|
|
- slot: true
|
|
|
- },
|
|
|
- {
|
|
|
- label: '品牌名称',
|
|
|
- prop: 'brandName',
|
|
|
- search: false,
|
|
|
- width: 120,
|
|
|
+ label: '客户名称',
|
|
|
+ prop: 'customerName',
|
|
|
+ search: true,
|
|
|
+ searchSpan: 6,
|
|
|
+ width: 180,
|
|
|
overHidden: true
|
|
|
},
|
|
|
{
|
|
@@ -207,29 +173,6 @@ export default {
|
|
|
width: 160
|
|
|
},
|
|
|
{
|
|
|
- label: '预测编码',
|
|
|
- prop: 'forecastCode',
|
|
|
- search: false,
|
|
|
- searchSpan: 6,
|
|
|
- width: 150,
|
|
|
- overHidden: true
|
|
|
- },
|
|
|
- {
|
|
|
- label: '客户名称',
|
|
|
- prop: 'customerName',
|
|
|
- search: true,
|
|
|
- searchSpan: 6,
|
|
|
- width: 180,
|
|
|
- overHidden: true
|
|
|
- },
|
|
|
- {
|
|
|
- label: '客户编码',
|
|
|
- prop: 'customerCode',
|
|
|
- search: false,
|
|
|
- width: 150,
|
|
|
- overHidden: true
|
|
|
- },
|
|
|
- {
|
|
|
label: '创建时间',
|
|
|
prop: 'createTime',
|
|
|
type: 'datetime',
|
|
@@ -237,7 +180,7 @@ export default {
|
|
|
search: false,
|
|
|
width: 160
|
|
|
},
|
|
|
- // 添加自定义编辑按钮列
|
|
|
+ // 自定义操作列(保持占位,不可编辑)
|
|
|
{
|
|
|
label: '操作',
|
|
|
prop: 'editBtn',
|
|
@@ -247,6 +190,30 @@ export default {
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
+ // 子表(展开区)表格配置:展示 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 }
|
|
|
+ ]
|
|
|
+ },
|
|
|
/** @type {Record<string, Array<ValidationRule>>} 表单验证规则 */
|
|
|
formRules: FORECAST_FORM_RULES
|
|
|
}
|
|
@@ -470,6 +437,25 @@ export default {
|
|
|
*/
|
|
|
getApprovalStatusType,
|
|
|
|
|
|
+ // 数字格式化(用于子表数量显示)
|
|
|
+ formatNumber(value) {
|
|
|
+ return formatNum(value)
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 安全将值转换为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
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
/**
|
|
|
* 检查是否可以编辑
|
|
|
* @param {ForecastRecord|ForecastItem} row - 行数据
|
|
@@ -533,8 +519,8 @@ export default {
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
- * 加载数据
|
|
|
- * @this {Vue & {loading: boolean, page: {pageSize: number, currentPage: number, total: number}, query: Record<string, any>, data: Array<ForecastRecord>, $message: any}}
|
|
|
+ * 加载数据(切换为主表 main-list)
|
|
|
+ * @this {Vue & {loading: boolean, page: {pageSize: number, currentPage: number, total: number}, query: Record<string, any>, data: Array<any>, $message: any}}
|
|
|
* @param {{currentPage: number, pageSize: number}} page - 分页参数
|
|
|
* @param {Record<string, any>} params - 查询参数
|
|
|
* @returns {Promise<void>}
|
|
@@ -542,44 +528,54 @@ export default {
|
|
|
async onLoad(page, params = {}) {
|
|
|
this.loading = true
|
|
|
try {
|
|
|
- // 将 year/month 搜索条件转换为 startMonth/endMonth
|
|
|
- const q = { ...this.query, ...params }
|
|
|
- const year = q.year
|
|
|
- const month = q.month
|
|
|
- const pad = (n) => String(n).padStart(2, '0')
|
|
|
- /** @type {Record<string, any>} */
|
|
|
- const filterParams = {}
|
|
|
- if (year && month) {
|
|
|
- filterParams.startMonth = `${year}-${pad(month)}`
|
|
|
- filterParams.endMonth = `${year}-${pad(month)}`
|
|
|
- } else if (year && !month) {
|
|
|
- filterParams.startMonth = `${year}-01`
|
|
|
- filterParams.endMonth = `${year}-12`
|
|
|
+ // 仅挑选 main-list 支持的查询参数
|
|
|
+ const merged = { ...this.query, ...params }
|
|
|
+ const safeParams = {
|
|
|
+ year: merged.year,
|
|
|
+ month: merged.month,
|
|
|
+ customerName: merged.customerName
|
|
|
}
|
|
|
- if (q.startDate) filterParams.startDate = q.startDate
|
|
|
- if (q.endDate) filterParams.endDate = q.endDate
|
|
|
- if (q.brandName) filterParams.brandName = q.brandName
|
|
|
-
|
|
|
- const res = await getSalesForecastSummaryPage(page.currentPage, page.pageSize, filterParams)
|
|
|
- if (res.data && (res.data.success || res.data.code === 200)) {
|
|
|
- const data = res.data.data || {}
|
|
|
- const records = Array.isArray(data.records) ? data.records : []
|
|
|
- this.page.total = Number(data.total || 0)
|
|
|
- // 字段兼容转换:确保页面所需字段存在
|
|
|
- this.data = records.map(r => ({
|
|
|
- ...r,
|
|
|
- // 兼容旧列表字段:部分接口无此字段则回退
|
|
|
- forecastCode: r.forecastCode || '',
|
|
|
- currentInventory: r.currentInventory != null ? r.currentInventory : 0
|
|
|
- }))
|
|
|
+
|
|
|
+ const response = await getSalesForecastMainList(
|
|
|
+ page.currentPage || 1,
|
|
|
+ page.pageSize || 10,
|
|
|
+ safeParams
|
|
|
+ )
|
|
|
+
|
|
|
+ if (response && response.data && response.data.code === 200 && response.data.data) {
|
|
|
+ const pageData = response.data.data
|
|
|
+ const records = Array.isArray(pageData.records) ? pageData.records : []
|
|
|
+ // 字段类型转换与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.page.total = Number(pageData.total) || 0
|
|
|
+ this.page.currentPage = Number(pageData.current) || 1
|
|
|
+ this.page.pageSize = Number(pageData.size) || 10
|
|
|
} else {
|
|
|
- this.$message.error(res.data?.msg || '加载数据失败')
|
|
|
+ this.$message.error(response?.data?.message || '获取数据失败')
|
|
|
this.data = []
|
|
|
this.page.total = 0
|
|
|
}
|
|
|
} catch (error) {
|
|
|
- console.error('加载数据失败:', error)
|
|
|
- this.$message.error('加载数据失败,请稍后重试')
|
|
|
+ console.error('获取预测主表分页列表失败:', error)
|
|
|
+ this.$message.error('获取数据失败,请稍后重试')
|
|
|
this.data = []
|
|
|
this.page.total = 0
|
|
|
} finally {
|