|
@@ -285,7 +285,13 @@ export default {
|
|
|
selectedStockId: null,
|
|
|
|
|
|
/** 当前库存 */
|
|
|
- currentInventory: null
|
|
|
+ currentInventory: null,
|
|
|
+
|
|
|
+ // 分页状态
|
|
|
+ /** 当前页(从1开始) */
|
|
|
+ currentPage: 1,
|
|
|
+ /** 每页条数(默认10) */
|
|
|
+ pageSize: 10
|
|
|
}
|
|
|
},
|
|
|
|
|
@@ -305,6 +311,27 @@ export default {
|
|
|
return this.title
|
|
|
}
|
|
|
return this.isEdit ? '编辑销售预测' : '新增销售预测'
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 物料总数(用于分页 total)
|
|
|
+ * @returns {number}
|
|
|
+ */
|
|
|
+ total() {
|
|
|
+ return Array.isArray(this.stockTableData) ? this.stockTableData.length : 0
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 当前页数据(前端分页)
|
|
|
+ * @returns {Array<import('@/api/types/order').PjpfStockDesc & { forecastQuantity: number, brandCode?: string, storeInventory?: string }>}
|
|
|
+ */
|
|
|
+ pagedStockTableData() {
|
|
|
+ const list = Array.isArray(this.stockTableData) ? this.stockTableData : []
|
|
|
+ const size = Number(this.pageSize) > 0 ? Number(this.pageSize) : 10
|
|
|
+ const page = Number(this.currentPage) > 0 ? Number(this.currentPage) : 1
|
|
|
+ const start = (page - 1) * size
|
|
|
+ const end = start + size
|
|
|
+ return list.slice(start, end)
|
|
|
}
|
|
|
},
|
|
|
|
|
@@ -444,6 +471,8 @@ export default {
|
|
|
if (this.visible && !this.isEdit) {
|
|
|
this.checkForecastByMonthAndEmit && this.checkForecastByMonthAndEmit()
|
|
|
}
|
|
|
+ // 年份变更重置分页到第一页
|
|
|
+ this.currentPage = 1
|
|
|
}
|
|
|
},
|
|
|
'formData.month': {
|
|
@@ -451,6 +480,8 @@ export default {
|
|
|
if (this.visible && !this.isEdit) {
|
|
|
this.checkForecastByMonthAndEmit && this.checkForecastByMonthAndEmit()
|
|
|
}
|
|
|
+ // 月份变更重置分页到第一页
|
|
|
+ this.currentPage = 1
|
|
|
}
|
|
|
},
|
|
|
|
|
@@ -1237,41 +1268,46 @@ export default {
|
|
|
this.stockTableData.push({ ...stock, forecastQuantity: 0 })
|
|
|
// 清空已选
|
|
|
this.selectedStockId = null
|
|
|
+
|
|
|
+ // 导入后保持当前页不变;无需校正页码(不会超过最大页)
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
- * 删除物料行
|
|
|
- * @description 在下方物料表格中删除指定行,包含二次确认流程;删除后保持数据与UI同步。
|
|
|
- * @param {import('./types').ForecastFormMixinData['stockTableData'][number]} row - 待删除的表格行数据
|
|
|
- * @param {number} index - 行索引
|
|
|
+ * 删除物料行(分页适配)
|
|
|
+ * @param {import('./types').ForecastFormMixinData['stockTableData'][number]} row
|
|
|
+ * @param {number} index - 当前页内索引
|
|
|
* @returns {Promise<void>}
|
|
|
- * @this {import('./types').ForecastFormMixinComponent & Vue}
|
|
|
*/
|
|
|
async handleDelete(row, index) {
|
|
|
try {
|
|
|
- // 索引校验,必要时根据唯一标识兜底定位
|
|
|
- let removeIndex = typeof index === 'number' ? index : -1
|
|
|
- if (removeIndex < 0 || removeIndex >= this.stockTableData.length) {
|
|
|
- const keyId = row && (row.id != null ? row.id : row.goodsId)
|
|
|
+ // 先通过唯一键定位(优先 id,其次 goodsId)
|
|
|
+ const keyId = row && (row.id != null ? row.id : row.goodsId)
|
|
|
+ let removeIndex = -1
|
|
|
+ if (keyId != null) {
|
|
|
removeIndex = this.stockTableData.findIndex(r => (r.id != null ? r.id : r.goodsId) === keyId)
|
|
|
}
|
|
|
+ // 如果无唯一键或未找到,则按分页换算全局索引
|
|
|
+ if (removeIndex < 0 && typeof index === 'number') {
|
|
|
+ const globalIndex = (Math.max(1, Number(this.currentPage)) - 1) * Math.max(1, Number(this.pageSize)) + index
|
|
|
+ if (globalIndex >= 0 && globalIndex < this.stockTableData.length) {
|
|
|
+ removeIndex = globalIndex
|
|
|
+ }
|
|
|
+ }
|
|
|
if (removeIndex < 0) {
|
|
|
this.$message && this.$message.warning('未定位到要删除的记录')
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- // 二次确认
|
|
|
await this.$confirm('确认删除该物料吗?删除后可重新通过上方选择器导入。', '提示', {
|
|
|
type: 'warning',
|
|
|
confirmButtonText: '删除',
|
|
|
cancelButtonText: '取消'
|
|
|
})
|
|
|
|
|
|
- // 使用 Vue.set/delete 保持响应式
|
|
|
this.$delete(this.stockTableData, removeIndex)
|
|
|
|
|
|
- // 如有需要,清理与该行相关的临时状态(当前实现无行级临时状态)
|
|
|
- // 例如:this.currentInventory = null
|
|
|
+ // 删除后校正页码:若当前页无数据则回退到上一页
|
|
|
+ this.normalizePageAfterMutations()
|
|
|
|
|
|
this.$message && this.$message.success('已删除')
|
|
|
} catch (e) {
|
|
@@ -1284,6 +1320,44 @@ export default {
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
+ * 页容量变更(el-pagination: size-change)
|
|
|
+ * @param {number} size
|
|
|
+ * @returns {void}
|
|
|
+ */
|
|
|
+ handleSizeChange(size) {
|
|
|
+ const newSize = Number(size) > 0 ? Number(size) : 10
|
|
|
+ this.pageSize = newSize
|
|
|
+ // 变更每页大小后,将页码重置为 1
|
|
|
+ this.currentPage = 1
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 页码变更(el-pagination: current-change)
|
|
|
+ * @param {number} page
|
|
|
+ * @returns {void}
|
|
|
+ */
|
|
|
+ handlePageChange(page) {
|
|
|
+ const newPage = Number(page) > 0 ? Number(page) : 1
|
|
|
+ this.currentPage = newPage
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 变更后校正页码(删除/导入后调用)
|
|
|
+ * @returns {void}
|
|
|
+ */
|
|
|
+ normalizePageAfterMutations() {
|
|
|
+ const total = this.total
|
|
|
+ const size = Math.max(1, Number(this.pageSize) || 10)
|
|
|
+ const maxPage = Math.max(1, Math.ceil(total / size))
|
|
|
+ if (this.currentPage > maxPage) {
|
|
|
+ this.currentPage = maxPage
|
|
|
+ }
|
|
|
+ if (this.currentPage < 1) {
|
|
|
+ this.currentPage = 1
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
* 品牌变更处理
|
|
|
* @param {number} brandId - 品牌ID
|
|
|
* @returns {void}
|