|
@@ -7,7 +7,7 @@
|
|
|
* @typedef {import('./types').ForecastSummaryComponent} ForecastSummaryComponent
|
|
|
*/
|
|
|
|
|
|
-import { getSalesForecastMainList, getForecastSummaryDetail, exportSalesForecastTemplate, exportSalesForecastByMonth } from '@/api/forecast/forecast-summary'
|
|
|
+import { getSalesForecastMainList, getForecastSummaryDetail, exportSalesForecastTemplate, exportSalesForecastByMonth, exportSalesForecastByMainId } from '@/api/forecast/forecast-summary'
|
|
|
import {
|
|
|
APPROVAL_STATUS,
|
|
|
APPROVAL_STATUS_CONFIG,
|
|
@@ -88,12 +88,26 @@ import { mapGetters } from 'vuex'
|
|
|
addBtn: false,
|
|
|
selection: false,
|
|
|
dialogClickModal: false,
|
|
|
- menu: false,
|
|
|
+ // menu: true,
|
|
|
+ // menuWidth: 120,
|
|
|
+ menu: true,
|
|
|
+ menuWidth: 160,
|
|
|
+ menuFixed: false,
|
|
|
// 启用行展开,展示子表格
|
|
|
expand: true,
|
|
|
expandRowKeys: [],
|
|
|
defaultExpandAll: false,
|
|
|
column: [
|
|
|
+ // 新增:ID 列(放在序号后,年月前)
|
|
|
+ {
|
|
|
+ label: 'ID',
|
|
|
+ prop: 'id',
|
|
|
+ width: 140,
|
|
|
+ overHidden: false,
|
|
|
+ sortable: true,
|
|
|
+ // 兼容 idBigint/id 的展示
|
|
|
+ slot: true
|
|
|
+ },
|
|
|
{
|
|
|
label: '年月',
|
|
|
prop: 'yearMonth',
|
|
@@ -172,6 +186,13 @@ import { mapGetters } from 'vuex'
|
|
|
minWidth: 160,
|
|
|
sortable: true,
|
|
|
slot: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '更新时间',
|
|
|
+ prop: 'updateTime',
|
|
|
+ minWidth: 160,
|
|
|
+ sortable: true,
|
|
|
+ slot: true
|
|
|
}
|
|
|
]
|
|
|
},
|
|
@@ -198,7 +219,6 @@ import { mapGetters } from 'vuex'
|
|
|
{ label: '花型/图案', prop: 'pattern', minWidth: 120, overHidden: true },
|
|
|
{ label: '品牌名称', prop: 'brandName', minWidth: 120, overHidden: true },
|
|
|
{ label: '预测数量', prop: 'forecastQuantity', minWidth: 120, align: 'right', slot: true },
|
|
|
- // 新增列:审核状态、客户名称、年份、月份、审批人、审批时间
|
|
|
{ label: '审核状态', prop: 'approvalStatus', minWidth: 100, type: 'select', dicData: APPROVAL_STATUS_OPTIONS, slot: true },
|
|
|
{ label: '客户名称', prop: 'customerName', minWidth: 160, overHidden: true },
|
|
|
{ label: '年份', prop: 'year', minWidth: 80 },
|
|
@@ -224,7 +244,10 @@ import { mapGetters } from 'vuex'
|
|
|
month: [ { required: true, message: '请选择月份', trigger: 'change' } ]
|
|
|
},
|
|
|
/** 月份选项(用于模板渲染) */
|
|
|
- monthOptions: MONTH_OPTIONS
|
|
|
+ monthOptions: MONTH_OPTIONS,
|
|
|
+
|
|
|
+ /** 行导出加载状态映射(按主表ID) */
|
|
|
+ rowExporting: {}
|
|
|
}
|
|
|
},
|
|
|
|
|
@@ -572,6 +595,54 @@ import { mapGetters } from 'vuex'
|
|
|
console.error('获取明细失败:', e)
|
|
|
return []
|
|
|
}
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 按主表ID导出当前行的销售预测汇总
|
|
|
+ * @param {SalesForecastMainRecord} row - 主表行记录
|
|
|
+ * @returns {Promise<void>}
|
|
|
+ */
|
|
|
+ async handleExportByMainId(row) {
|
|
|
+ try {
|
|
|
+ if (!row) return
|
|
|
+ const mainId = row.idBigint || row.id
|
|
|
+ if (!mainId) {
|
|
|
+ this.$message.warning('无法获取该行主键ID,导出失败')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 标记该行导出中
|
|
|
+ this.$set(this.rowExporting, String(mainId), true)
|
|
|
+
|
|
|
+ const res = await exportSalesForecastByMainId(mainId)
|
|
|
+
|
|
|
+ // 处理文件名:优先从响应头解析,其次使用“客户名称_yyyy-MM.xlsx”
|
|
|
+ const disposition = res?.headers?.['content-disposition'] || res?.headers?.['Content-Disposition']
|
|
|
+ const ym = this.formatYearMonth(Number(row.year), Number(row.month))
|
|
|
+ const defaultName = `${row.customerName ? row.customerName + '_' : ''}${ym || ''}销售预测汇总.xlsx`
|
|
|
+ let filename = defaultName
|
|
|
+ if (disposition) {
|
|
|
+ const utf8Match = /filename\*=UTF-8''([^;\n]+)/i.exec(disposition)
|
|
|
+ const plainMatch = /filename="?([^;\n"]+)"?/i.exec(disposition)
|
|
|
+ const raw = utf8Match ? decodeURIComponent(utf8Match[1]) : (plainMatch ? plainMatch[1] : '')
|
|
|
+ if (raw) filename = raw
|
|
|
+ }
|
|
|
+
|
|
|
+ const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
|
|
|
+ const url = window.URL.createObjectURL(blob)
|
|
|
+ const a = document.createElement('a')
|
|
|
+ a.href = url
|
|
|
+ a.download = filename
|
|
|
+ document.body.appendChild(a)
|
|
|
+ a.click()
|
|
|
+ document.body.removeChild(a)
|
|
|
+ window.URL.revokeObjectURL(url)
|
|
|
+ } catch (e) {
|
|
|
+ console.error('按主表ID导出失败:', e)
|
|
|
+ this.$message.error('导出失败,请稍后重试')
|
|
|
+ } finally {
|
|
|
+ const key = String((row && (row.idBigint || row.id)) || '')
|
|
|
+ if (key) this.$set(this.rowExporting, key, false)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|