|
@@ -2,6 +2,15 @@
|
|
|
* @fileoverview 物料明细表格组件
|
|
|
* @description 基于AvueJS的物料明细数据展示和操作组件,支持分页、搜索、删除等功能
|
|
|
* @typedef {import('./types').MaterialDetailTableComponent} MaterialDetailTableComponent
|
|
|
+ * @typedef {import('./types').MaterialDetailRecord} MaterialDetailRecord
|
|
|
+ * @typedef {import('./types').MaterialUpdateEventData} MaterialUpdateEventData
|
|
|
+ * @typedef {import('./types').MaterialDeleteEventData} MaterialDeleteEventData
|
|
|
+ * @typedef {import('./types').MaterialDetailQueryParams} MaterialDetailQueryParams
|
|
|
+ * @typedef {import('./types').MaterialOption} MaterialOption
|
|
|
+ * @typedef {import('./types').PaginationConfig} PaginationConfig
|
|
|
+ * @typedef {import('smallwei__avue/crud').AvueCrudOption} AvueCrudOption
|
|
|
+ * @typedef {import('smallwei__avue/crud').AvueCrudColumn} AvueCrudColumn
|
|
|
+ * @typedef {import('smallwei__avue/crud').PageOption} PageOption
|
|
|
*/
|
|
|
|
|
|
import { getMaterialDetailOption, DEFAULT_PAGINATION_CONFIG } from './material-detail-option'
|
|
@@ -28,25 +37,15 @@ import {
|
|
|
NUMBER_TYPES
|
|
|
} from './number-format-utils'
|
|
|
|
|
|
-/**
|
|
|
- * @typedef {import('./types').MaterialDetailRecord} MaterialDetailRecord
|
|
|
- * @typedef {import('./types').MaterialUpdateEventData} MaterialUpdateEventData
|
|
|
- * @typedef {import('./types').MaterialDeleteEventData} MaterialDeleteEventData
|
|
|
- * @typedef {import('./types').MaterialDetailQueryParams} MaterialDetailQueryParams
|
|
|
- * @typedef {import('smallwei__avue/crud').AvueCrudOption} AvueCrudOption
|
|
|
- * @typedef {import('smallwei__avue/crud').AvueCrudColumn} AvueCrudColumn
|
|
|
- * @typedef {import('smallwei__avue/crud').PageOption} PageOption
|
|
|
- */
|
|
|
-
|
|
|
|
|
|
|
|
|
-// 使用@types/smallwei__avue/crud中的PageOption类型代替PaginationConfig
|
|
|
+// 使用本地 PaginationConfig 作为分页数据结构描述
|
|
|
|
|
|
/**
|
|
|
* 组件数据类型定义
|
|
|
* @typedef {Object} MaterialDetailTableData
|
|
|
* @property {Partial<MaterialDetailRecord>} formData - 表单数据
|
|
|
- * @property {PageOption} page - 分页配置
|
|
|
+ * @property {PaginationConfig} page - 分页配置
|
|
|
* @property {boolean} importDialogVisible - 导入弹窗显示状态
|
|
|
*/
|
|
|
|
|
@@ -72,7 +71,7 @@ export default {
|
|
|
props: {
|
|
|
/**
|
|
|
* 是否为编辑模式 - 控制表格是否可编辑
|
|
|
- * @type {boolean}
|
|
|
+ * @type {import('vue').PropOptions<boolean>}
|
|
|
*/
|
|
|
editMode: {
|
|
|
type: Boolean,
|
|
@@ -80,7 +79,7 @@ export default {
|
|
|
},
|
|
|
/**
|
|
|
* 订单ID - 关联的订单唯一标识符
|
|
|
- * @type {string|number|null}
|
|
|
+ * @type {import('vue').PropOptions<string|number|null>}
|
|
|
*/
|
|
|
orderId: {
|
|
|
type: [String, Number],
|
|
@@ -90,7 +89,7 @@ export default {
|
|
|
|
|
|
/**
|
|
|
* 物料明细列表 - 要展示的物料明细数据
|
|
|
- * @type {MaterialDetailRecord[]} 物料明细数据数组,每个元素包含物料的详细信息
|
|
|
+ * @type {import('vue').PropOptions<MaterialDetailRecord[]>} 物料明细数据数组,每个元素包含物料的详细信息
|
|
|
*/
|
|
|
materialDetails: {
|
|
|
type: Array,
|
|
@@ -118,7 +117,7 @@ export default {
|
|
|
formData: {},
|
|
|
|
|
|
/**
|
|
|
- * 分页配置 - AvueJS表格分页相关配置
|
|
|
+ * 分页配置 - 表格分页相关配置
|
|
|
* @type {PaginationConfig} 包含currentPage、pageSize、total等属性的分页配置对象
|
|
|
*/
|
|
|
page: {
|
|
@@ -135,7 +134,7 @@ export default {
|
|
|
|
|
|
/**
|
|
|
* 物料选项列表 - 远程搜索返回的物料选项
|
|
|
- * @type {ItemRecord[]}
|
|
|
+ * @type {MaterialOption[]}
|
|
|
*/
|
|
|
materialOptions: [],
|
|
|
|
|
@@ -185,6 +184,7 @@ export default {
|
|
|
|
|
|
/**
|
|
|
* 当前页显示的数据 - 根据分页配置计算当前页应显示的数据
|
|
|
+ * @this {MaterialDetailTableComponent}
|
|
|
* @returns {MaterialDetailRecord[]} 当前页的物料明细数据
|
|
|
*/
|
|
|
currentPageData() {
|
|
@@ -206,6 +206,9 @@ export default {
|
|
|
* @returns {void}
|
|
|
*/
|
|
|
materialDetails: {
|
|
|
+ /**
|
|
|
+ * @this {MaterialDetailTableComponent}
|
|
|
+ */
|
|
|
handler(newVal) {
|
|
|
this.page.total = newVal.length
|
|
|
},
|
|
@@ -346,6 +349,7 @@ export default {
|
|
|
* @description 根据关键词远程搜索物料数据,支持防抖处理
|
|
|
* @param {string} query - 搜索关键词
|
|
|
* @returns {void}
|
|
|
+ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
remoteSearchMaterial(query) {
|
|
|
// 清除之前的定时器
|
|
@@ -374,6 +378,7 @@ export default {
|
|
|
* @param {string} keyword - 搜索关键词
|
|
|
* @returns {Promise<void>}
|
|
|
* @throws {Error} 当API调用失败时抛出异常
|
|
|
++ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
async searchMaterials(keyword) {
|
|
|
try {
|
|
@@ -490,6 +495,7 @@ export default {
|
|
|
* 处理导入选中物料
|
|
|
* @description 将选中的物料导入到物料明细表中
|
|
|
* @returns {void}
|
|
|
+ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
handleImportSelectedMaterial() {
|
|
|
if (!this.selectedMaterialId) {
|
|
@@ -529,7 +535,7 @@ export default {
|
|
|
/**
|
|
|
* 准备物料明细数据
|
|
|
* @description 将选中的物料数据转换为物料明细表所需的格式
|
|
|
- * @param {import('@/api/types/order').SalesOrderItemListRecord} material - 物料数据(来自getMaterialFullList API)
|
|
|
+ * @param {import('./types').MaterialOption} material - 物料数据(来自getMaterialFullList API)
|
|
|
* @returns {MaterialDetailRecord} 格式化后的物料明细数据
|
|
|
* @private
|
|
|
*/
|
|
@@ -539,8 +545,9 @@ export default {
|
|
|
itemCode: material.itemCode,
|
|
|
itemName: material.itemName,
|
|
|
specs: material.specs || '',
|
|
|
- specification: material.specs || '',
|
|
|
+ // 移除不在 MaterialDetailItem 中的 specification 字段
|
|
|
unit: material.unit || '',
|
|
|
+ // 使用标准化字段,兼容后备旧字段
|
|
|
mainItemCategoryName: material.mainItemCategoryName || material.MainItemCategory_Name || '',
|
|
|
mainItemCategoryId: material.mainItemCategoryId || material.MainItemCategory_ID,
|
|
|
mainItemCategoryCode: material.mainItemCategoryCode || material.MainItemCategory_Code || '',
|
|
@@ -580,6 +587,7 @@ export default {
|
|
|
* @description 触发刷新事件,通知父组件重新加载数据
|
|
|
* @returns {void}
|
|
|
* @emits refresh
|
|
|
++ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
handleRefresh() {
|
|
|
this.$emit(MATERIAL_DETAIL_EVENTS.REFRESH)
|
|
@@ -591,6 +599,7 @@ export default {
|
|
|
* 处理分页页码变化事件
|
|
|
* @description 当用户切换页码时触发,更新当前页码
|
|
|
* @param {number} currentPage - 新的页码,从1开始
|
|
|
+ * @this {MaterialDetailTableComponent}
|
|
|
* @returns {void}
|
|
|
*/
|
|
|
handleCurrentChange(currentPage) {
|
|
@@ -601,6 +610,7 @@ export default {
|
|
|
* 处理分页大小变化事件
|
|
|
* @description 当用户改变每页显示条数时触发,重置到第一页
|
|
|
* @param {number} pageSize - 新的每页显示条数
|
|
|
+ * @this {MaterialDetailTableComponent}
|
|
|
* @returns {void}
|
|
|
*/
|
|
|
handleSizeChange(pageSize) {
|
|
@@ -645,7 +655,7 @@ export default {
|
|
|
/**
|
|
|
* 获取状态标签类型
|
|
|
* @description 根据物料明细状态值返回对应的Element UI标签类型
|
|
|
- * @param {typeof MaterialDetailStatus[keyof typeof MaterialDetailStatus]} itemStatus - 物料明细状态值
|
|
|
+ * @param {import('@/api/types/order').OrderItemStatus} itemStatus - 物料明细状态值
|
|
|
* @returns {string} Element UI标签类型
|
|
|
* @example
|
|
|
* getStatusTagType(0) // 返回 'warning'
|
|
@@ -658,7 +668,7 @@ export default {
|
|
|
/**
|
|
|
* 获取状态文本
|
|
|
* @description 根据物料明细状态值返回对应的中文描述
|
|
|
- * @param {number} itemStatus - 物料明细状态值
|
|
|
+ * @param {import('@/api/types/order').OrderItemStatus} itemStatus - 物料明细状态值
|
|
|
* @returns {string} 状态的中文描述文本
|
|
|
* @example
|
|
|
* getStatusText(0) // 返回 '待确认'
|
|
@@ -669,13 +679,14 @@ export default {
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
- * 处理删除物料操作
|
|
|
- * @description 删除指定的物料明细记录,仅允许删除可删除的物料
|
|
|
- * @param {MaterialDetailRecord} row - 要删除的物料明细记录
|
|
|
- * @param {number} index - 记录在当前页的索引位置
|
|
|
- * @returns {void}
|
|
|
- * @emits material-delete
|
|
|
- */
|
|
|
+ * 处理删除物料操作
|
|
|
+ * @description 删除指定的物料明细记录,仅允许删除可删除的物料
|
|
|
+ * @param {MaterialDetailRecord} row - 要删除的物料明细记录
|
|
|
+ * @param {number} index - 记录在当前页的索引位置
|
|
|
+ * @returns {Promise<void>}
|
|
|
+ * @emits material-delete
|
|
|
+ * @this {MaterialDetailTableComponent}
|
|
|
+ */
|
|
|
async handleDeleteMaterial(row, index) {
|
|
|
try {
|
|
|
await this.$confirm(
|
|
@@ -705,6 +716,7 @@ export default {
|
|
|
* @param {MaterialDetailRecord} row - 要删除的行数据
|
|
|
* @param {number} index - 行索引
|
|
|
* @returns {void}
|
|
|
++ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
handleRowDelete(row, index) {
|
|
|
this.handleDeleteMaterial(row, index)
|
|
@@ -715,11 +727,12 @@ export default {
|
|
|
* @description 当用户编辑表格行数据时触发,执行自动计算逻辑
|
|
|
* @param {MaterialDetailRecord} row - 更新后的行数据
|
|
|
* @param {number} index - 行索引
|
|
|
- * @param {boolean} done - 完成回调函数
|
|
|
+ * @param {(result: any) => void} done - 完成回调函数
|
|
|
* @returns {void}
|
|
|
* @emits material-update
|
|
|
+ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
- async handleRowUpdate(row, index, done) {
|
|
|
+ handleRowUpdate(row, index, done) {
|
|
|
try {
|
|
|
// 执行自动计算
|
|
|
const calculatedRow = this.calculateAmounts(row)
|
|
@@ -743,6 +756,7 @@ export default {
|
|
|
* @param {MaterialDetailRecord} row - 行数据
|
|
|
* @param {number} index - 行索引
|
|
|
* @returns {void}
|
|
|
++ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
handleQuantityBlur(row, index) {
|
|
|
// 如果 index 无效,尝试通过 row 数据找到正确的索引
|
|
@@ -756,6 +770,7 @@ export default {
|
|
|
* @param {MaterialDetailRecord} row - 行数据
|
|
|
* @param {number} index - 行索引
|
|
|
* @returns {void}
|
|
|
++ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
handleQuantityChange(row, index) {
|
|
|
const calculatedRow = this.calculateAmounts(row)
|
|
@@ -769,6 +784,7 @@ export default {
|
|
|
* @param {MaterialDetailRecord} row - 行数据
|
|
|
* @param {number} index - 行索引
|
|
|
* @returns {void}
|
|
|
++ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
handleTaxRateChange(row, index) {
|
|
|
this.calculateTaxAmount(row)
|
|
@@ -781,6 +797,7 @@ export default {
|
|
|
* @param {MaterialDetailRecord} row - 行数据
|
|
|
* @param {number} index - 行索引
|
|
|
* @returns {void}
|
|
|
++ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
handleUnitPriceBlur(row, index) {
|
|
|
// 先格式化数值
|
|
@@ -797,6 +814,7 @@ export default {
|
|
|
* @param {MaterialDetailRecord} row - 行数据
|
|
|
* @param {number} index - 行索引
|
|
|
* @returns {void}
|
|
|
++ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
handleUnitPriceChange(row, index) {
|
|
|
const calculatedRow = this.calculateAmounts(row)
|
|
@@ -810,11 +828,15 @@ export default {
|
|
|
* @param {MaterialDetailRecord} row - 行数据
|
|
|
* @param {number} index - 行索引
|
|
|
* @returns {void}
|
|
|
++ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
handleTaxAmountChange(row, index) {
|
|
|
// 当税额手动修改时,反推税率
|
|
|
- if (row.totalAmount && row.totalAmount > 0) {
|
|
|
- row.taxRate = ((row.taxAmount || 0) / row.totalAmount * 100).toFixed(2)
|
|
|
+ // 使用数值转换,避免字符串参与算术导致的类型错误
|
|
|
+ const totalAmountNum = Number(row.totalAmount) || 0
|
|
|
+ const taxAmountNum = Number(row.taxAmount) || 0
|
|
|
+ if (totalAmountNum > 0) {
|
|
|
+ row.taxRate = ((taxAmountNum / totalAmountNum) * 100).toFixed(2)
|
|
|
}
|
|
|
this.$emit('material-update', { row, index })
|
|
|
},
|
|
@@ -825,6 +847,7 @@ export default {
|
|
|
* @param {MaterialDetailRecord} row - 行数据
|
|
|
* @param {number} index - 行索引
|
|
|
* @returns {void}
|
|
|
++ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
handleTotalAmountChange(row, index) {
|
|
|
// 当总金额手动修改时,重新计算税额
|
|
@@ -839,6 +862,7 @@ export default {
|
|
|
* @param {string} prop - 编辑的属性名
|
|
|
* @param {*} value - 当前值
|
|
|
* @returns {void}
|
|
|
++ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
handleCellEditStart(row, prop, value) {
|
|
|
// 记录编辑前的值,用于计算变化
|
|
@@ -853,6 +877,7 @@ export default {
|
|
|
* @param {string} prop - 编辑的属性名
|
|
|
* @param {*} value - 新值
|
|
|
* @returns {void}
|
|
|
++ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
handleCellEditEnd(row, prop, value) {
|
|
|
// 如果编辑的是影响计算的字段,执行自动计算
|
|
@@ -923,9 +948,12 @@ export default {
|
|
|
* @description 根据行数据获取在当前页中的索引
|
|
|
* @param {MaterialDetailRecord} row - 行数据
|
|
|
* @returns {number} 行索引
|
|
|
+ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
getCurrentRowIndex(row) {
|
|
|
- return this.currentPageData.findIndex(item => item.id === row.id)
|
|
|
+ /** @type {MaterialDetailRecord[]} */
|
|
|
+ const list = this.currentPageData || []
|
|
|
+ return list.findIndex((item) => item.id === row.id)
|
|
|
},
|
|
|
|
|
|
/**
|
|
@@ -934,6 +962,7 @@ export default {
|
|
|
* @param {MaterialDetailRecord} row - 行数据
|
|
|
* @param {number} providedIndex - 提供的索引
|
|
|
* @returns {number} 实际索引
|
|
|
+ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
findRowIndex(row, providedIndex) {
|
|
|
// 如果提供的索引有效,直接使用
|
|
@@ -942,7 +971,9 @@ export default {
|
|
|
}
|
|
|
|
|
|
// 否则通过行数据查找索引
|
|
|
- const index = this.materialDetails.findIndex(item => {
|
|
|
+ /** @type {MaterialDetailRecord[]} */
|
|
|
+ const details = this.materialDetails || []
|
|
|
+ const index = details.findIndex((item) => {
|
|
|
// 优先使用 id 进行匹配
|
|
|
if (row.id && item.id) {
|
|
|
return row.id === item.id
|
|
@@ -962,6 +993,7 @@ export default {
|
|
|
/**
|
|
|
* 组件销毁前的清理工作
|
|
|
* @description 清除定时器,避免内存泄漏
|
|
|
+ * @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
beforeDestroy() {
|
|
|
if (this.searchTimer) {
|