|
|
@@ -48,6 +48,20 @@ import {
|
|
|
|
|
|
/**
|
|
|
* @typedef {import('./types').OrderFormModel} OrderFormModel
|
|
|
+ * @description 订单表单数据模型类型
|
|
|
+ */
|
|
|
+
|
|
|
+/**
|
|
|
+ * @typedef {import('./types').OrderFormRules} OrderFormRules
|
|
|
+ * @description 订单表单验证规则类型
|
|
|
+ */
|
|
|
+
|
|
|
+/**
|
|
|
+ * @typedef {import('./types').OrderFormMethods} OrderFormMethods
|
|
|
+ * @description 订单表单方法类型
|
|
|
+ */
|
|
|
+
|
|
|
+/**
|
|
|
* @typedef {import('smallwei__avue/form').AvueFormOption<OrderFormModel>} AvueFormOption
|
|
|
* @typedef {import('smallwei__avue/form').AvueFormColumn<OrderFormModel>} AvueFormColumn
|
|
|
* @typedef {import('smallwei__avue/form').AvueFormGroup<OrderFormModel>} AvueFormGroup
|
|
|
@@ -72,11 +86,6 @@ import {
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
- * @typedef {import('./types').OrderFormMixinData} OrderFormMixinData
|
|
|
- * @description 订单表单混入数据类型
|
|
|
- */
|
|
|
-
|
|
|
-/**
|
|
|
* @typedef {import('@/api/types/order').SalesOrderCreateForm} SalesOrderCreateForm
|
|
|
* @description 销售订单创建表单类型
|
|
|
*/
|
|
|
@@ -105,7 +114,8 @@ export default {
|
|
|
/**
|
|
|
* 组件响应式数据
|
|
|
* @description 定义组件的响应式数据状态
|
|
|
- * @returns {OrderFormMixinData} 组件数据对象
|
|
|
+ * @returns {import('./types').OrderFormMixinData} 组件数据对象
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
data() {
|
|
|
return {
|
|
|
@@ -124,6 +134,20 @@ export default {
|
|
|
saveLoading: false,
|
|
|
|
|
|
/**
|
|
|
+ * 表单加载状态
|
|
|
+ * @description 控制表单整体的加载状态,用于数据获取时的UI反馈
|
|
|
+ * @type {boolean}
|
|
|
+ */
|
|
|
+ formLoading: false,
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 物料明细列表
|
|
|
+ * @description 存储当前订单的物料明细数据,包含数据来源和删除权限标识
|
|
|
+ * @type {MaterialDetailRecord[]}
|
|
|
+ */
|
|
|
+ materialDetails: [],
|
|
|
+
|
|
|
+ /**
|
|
|
* 订单类型选项列表
|
|
|
* @description 订单类型下拉选择器的选项数据
|
|
|
* @type {typeof ORDER_TYPE_OPTIONS}
|
|
|
@@ -135,7 +159,12 @@ export default {
|
|
|
* @description 订单状态下拉选择器的选项数据
|
|
|
* @type {typeof ORDER_STATUS_OPTIONS}
|
|
|
*/
|
|
|
- orderStatusOptions: ORDER_STATUS_OPTIONS
|
|
|
+ orderStatusOptions: ORDER_STATUS_OPTIONS,
|
|
|
+
|
|
|
+ // 事件常量,用于模板中的动态事件绑定
|
|
|
+ CUSTOMER_SELECT_EVENTS: ORDER_FORM_EVENTS.CUSTOMER_SELECT,
|
|
|
+ ADDRESS_SELECT_EVENTS: ORDER_FORM_EVENTS.ADDRESS_SELECT,
|
|
|
+ MATERIAL_DETAIL_EVENTS: ORDER_FORM_EVENTS.MATERIAL_DETAIL
|
|
|
}
|
|
|
},
|
|
|
|
|
|
@@ -148,6 +177,7 @@ export default {
|
|
|
* 订单表单验证规则
|
|
|
* @description 定义订单表单各字段的验证规则,支持必填、长度、格式等验证
|
|
|
* @returns {OrderFormRules} 完整的表单验证规则对象
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
formRules() {
|
|
|
return {
|
|
|
@@ -329,6 +359,67 @@ export default {
|
|
|
}
|
|
|
]
|
|
|
}
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 表单标题
|
|
|
+ * @description 根据编辑模式动态显示表单标题
|
|
|
+ * @returns {string} 表单标题文本
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
+ */
|
|
|
+ formTitle() {
|
|
|
+ return this.isEdit ? '编辑订单' : '新增订单'
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 物料明细表格配置
|
|
|
+ * @description 获取物料明细表格的配置选项
|
|
|
+ * @returns {Object} 表格配置对象
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
+ */
|
|
|
+ materialDetailTableOption() {
|
|
|
+ return {
|
|
|
+ border: true,
|
|
|
+ stripe: true,
|
|
|
+ menuAlign: 'center',
|
|
|
+ align: 'center',
|
|
|
+ addBtn: false,
|
|
|
+ editBtn: false,
|
|
|
+ delBtn: true,
|
|
|
+ viewBtn: false,
|
|
|
+ column: [
|
|
|
+ {
|
|
|
+ label: '物料编码',
|
|
|
+ prop: 'itemCode',
|
|
|
+ width: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '物料名称',
|
|
|
+ prop: 'itemName',
|
|
|
+ width: 150
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '规格型号',
|
|
|
+ prop: 'specs',
|
|
|
+ width: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '订单数量',
|
|
|
+ prop: 'orderQuantity',
|
|
|
+ width: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '单价',
|
|
|
+ prop: 'unitPrice',
|
|
|
+ width: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '总金额',
|
|
|
+ prop: 'totalAmount',
|
|
|
+ width: 120
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
}
|
|
|
},
|
|
|
|
|
|
@@ -342,6 +433,7 @@ export default {
|
|
|
* @description 创建订单表单的初始数据结构
|
|
|
* @returns {OrderFormModel} 初始化的表单数据对象
|
|
|
* @private
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
createInitialFormData() {
|
|
|
return {
|
|
|
@@ -371,6 +463,7 @@ export default {
|
|
|
* @returns {Promise<void>}
|
|
|
* @throws {Error} 当初始化过程中发生错误时抛出异常
|
|
|
* @public
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
async initForm() {
|
|
|
try {
|
|
|
@@ -395,6 +488,7 @@ export default {
|
|
|
* @returns {Promise<void>}
|
|
|
* @throws {Error} 当重置过程中发生严重错误时抛出异常
|
|
|
* @public
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
async resetForm() {
|
|
|
try {
|
|
|
@@ -430,6 +524,7 @@ export default {
|
|
|
* @returns {Promise<void>}
|
|
|
* @throws {Error} 当订单ID无效、API调用失败或数据格式错误时抛出异常
|
|
|
* @public
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
async loadOrderDetail(orderId) {
|
|
|
// 参数验证
|
|
|
@@ -439,9 +534,6 @@ export default {
|
|
|
|
|
|
try {
|
|
|
// 并行加载订单详情和物料明细数据以提高性能
|
|
|
- /**
|
|
|
- * @type {[import('axios').AxiosResponse<ApiResponse<import('@/api/types/order').OrderRecord>>, MaterialDetailRecord[]]}
|
|
|
- */
|
|
|
const [orderResponse, materialResponse] = await Promise.all([
|
|
|
getDetail(orderId),
|
|
|
this.loadMaterialDetails(orderId)
|
|
|
@@ -482,6 +574,7 @@ export default {
|
|
|
* @returns {Promise<MaterialDetailRecord[]>} 格式化后的物料明细数组,数值字段已进行精度处理
|
|
|
* @throws {Error} 当订单ID无效或API调用失败时抛出异常
|
|
|
* @private
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
async loadMaterialDetails(orderId) {
|
|
|
// 参数验证
|
|
|
@@ -573,6 +666,7 @@ export default {
|
|
|
* @param {import('@/api/types/order').OrderRecord} orderData - 从API获取的原始订单数据
|
|
|
* @returns {OrderFormModel} 格式化后的表单数据
|
|
|
* @private
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
mapOrderDataToForm(orderData) {
|
|
|
// 验证和格式化数字字段
|
|
|
@@ -608,6 +702,7 @@ export default {
|
|
|
* @returns {void}
|
|
|
* @public
|
|
|
* @emits back 返回列表事件
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
handleBack() {
|
|
|
/**
|
|
|
@@ -626,6 +721,7 @@ export default {
|
|
|
* @throws {Error} 当表单验证失败或API调用失败时抛出异常
|
|
|
* @public
|
|
|
* @emits save-success 保存成功事件
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
async handleSave() {
|
|
|
if (this.saveLoading) {
|
|
|
@@ -682,6 +778,7 @@ export default {
|
|
|
* @param {OrderFormModel} submitData - 要提交的订单数据
|
|
|
* @returns {Promise<import('axios').AxiosResponse<ApiResponse<import('@/api/types/order').OrderRecord>>>} API响应结果
|
|
|
* @private
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
async submitOrderData(submitData) {
|
|
|
if (this.isEdit) {
|
|
|
@@ -699,6 +796,7 @@ export default {
|
|
|
* @param {OrderFormModel} formData - 表单数据
|
|
|
* @returns {SalesOrderCreateForm} 销售订单创建数据
|
|
|
* @private
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
prepareSalesOrderData(formData) {
|
|
|
// 转换物料明细数据为API所需格式
|
|
|
@@ -747,6 +845,7 @@ export default {
|
|
|
* @description 使用AvueJS表单的验证功能验证所有字段
|
|
|
* @returns {Promise<boolean>} 验证结果,true表示验证通过,false表示验证失败
|
|
|
* @public
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
async validateForm() {
|
|
|
if (!this.$refs.orderForm) {
|
|
|
@@ -773,10 +872,11 @@ export default {
|
|
|
* @description 验证AvueJS表单的所有字段,确保数据有效性
|
|
|
* @returns {Promise<boolean>} 验证结果
|
|
|
* @private
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
async validateFormFields() {
|
|
|
return new Promise((resolve) => {
|
|
|
- this.$refs.orderForm.validate((valid) => {
|
|
|
+ this.$refs?.orderForm?.validate((valid) => {
|
|
|
resolve(Boolean(valid))
|
|
|
})
|
|
|
})
|
|
|
@@ -787,6 +887,7 @@ export default {
|
|
|
* @description 复制表单数据并进行清理和格式化处理
|
|
|
* @returns {OrderFormModel} 准备好的提交数据
|
|
|
* @private
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
prepareSubmitData() {
|
|
|
const submitData = { ...this.formData }
|
|
|
@@ -801,6 +902,7 @@ export default {
|
|
|
* @param {OrderFormModel} data - 原始表单数据
|
|
|
* @returns {OrderFormModel} 清理后的数据对象
|
|
|
* @private
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
cleanAndFormatSubmitData(data) {
|
|
|
const cleanedData = {}
|
|
|
@@ -841,6 +943,7 @@ export default {
|
|
|
* @returns {Promise<void>}
|
|
|
* @throws {Error} 当物料明细保存失败时抛出异常
|
|
|
* @private
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
async saveMaterialDetails() {
|
|
|
if (!this.materialDetails || this.materialDetails.length === 0) {
|
|
|
@@ -890,6 +993,7 @@ export default {
|
|
|
* @param {MaterialDetailRecord} material - 物料明细数据
|
|
|
* @returns {SalesOrderItemCreateForm} 格式化后的物料明细数据
|
|
|
* @private
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
prepareMaterialItemData(material) {
|
|
|
return {
|
|
|
@@ -915,15 +1019,16 @@ export default {
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
- * 处理物料删除事件
|
|
|
- * @description 从物料明细列表中删除指定的物料记录,仅允许删除可删除的物料
|
|
|
- * @param {MaterialDeleteEventData} deleteData - 删除数据对象
|
|
|
- * @param {MaterialDetailRecord} deleteData.row - 要删除的物料记录
|
|
|
- * @param {number} deleteData.index - 记录在当前页的索引
|
|
|
- * @returns {void}
|
|
|
- * @public
|
|
|
- */
|
|
|
- handleMaterialDelete({ row, index }) {
|
|
|
+ * 处理物料删除事件
|
|
|
+ * @description 从物料明细列表中删除指定的物料记录,仅允许删除可删除的物料
|
|
|
+ * @param {MaterialDeleteEventData} deleteData - 删除数据对象
|
|
|
+ * @param {MaterialDetailRecord} deleteData.row - 要删除的物料记录
|
|
|
+ * @param {number} deleteData.index - 记录在当前页的索引
|
|
|
+ * @returns {void}
|
|
|
+ * @public
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
+ */
|
|
|
+ handleMaterialDelete({ row, index }) {
|
|
|
if (!row) {
|
|
|
this.$message.warning('删除数据无效')
|
|
|
return
|
|
|
@@ -960,6 +1065,7 @@ export default {
|
|
|
* @param {MaterialDetailRecord[]} importedMaterials - 导入的物料数据数组
|
|
|
* @returns {void}
|
|
|
* @public
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
*/
|
|
|
handleMaterialImport(importedMaterials) {
|
|
|
if (!Array.isArray(importedMaterials) || importedMaterials.length === 0) {
|
|
|
@@ -1000,6 +1106,166 @@ export default {
|
|
|
this.$message.error('导入物料失败,请重试')
|
|
|
console.error('导入物料失败:', error)
|
|
|
}
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理表单提交事件
|
|
|
+ * @description AvueJS表单提交时的回调处理
|
|
|
+ * @param {OrderFormModel} formData - 表单数据
|
|
|
+ * @param {Function} done - 完成回调函数
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
+ */
|
|
|
+ handleFormSubmit(formData, done) {
|
|
|
+ this.handleSave().finally(() => {
|
|
|
+ if (typeof done === 'function') {
|
|
|
+ done()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理表单重置事件
|
|
|
+ * @description AvueJS表单重置时的回调处理
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
+ */
|
|
|
+ handleFormReset() {
|
|
|
+ this.resetForm()
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理物料明细数据变化
|
|
|
+ * @description 当物料明细表格数据发生变化时的回调处理,自动重新计算订单总金额和总数量
|
|
|
+ * @param {MaterialDetailRecord[]} materialDetails - 更新后的物料明细列表
|
|
|
+ * @returns {void}
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
+ */
|
|
|
+ handleMaterialChange(materialDetails) {
|
|
|
+ this.materialDetails = materialDetails
|
|
|
+ // 可以在这里添加其他业务逻辑,如计算订单总金额等
|
|
|
+ this.calculateOrderTotal()
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理物料明细更新事件
|
|
|
+ * @description 当物料明细表格中的数据被编辑时的回调处理,自动重新计算订单总金额和总数量
|
|
|
+ * @param {MaterialUpdateEventData} updateData - 更新数据对象
|
|
|
+ * @returns {void}
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
+ */
|
|
|
+ handleMaterialUpdate({ row, index }) {
|
|
|
+ // 如果有有效的索引,更新物料明细列表中对应的记录
|
|
|
+ if (index >= 0 && index < this.materialDetails.length) {
|
|
|
+ this.$set(this.materialDetails, index, { ...row })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 无论索引是否有效,都重新计算订单总金额
|
|
|
+ this.calculateOrderTotal()
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算订单总金额和总数量
|
|
|
+ * @description 根据物料明细计算订单总金额、总数量、总税额并更新表单数据
|
|
|
+ * @returns {void}
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
+ */
|
|
|
+ calculateOrderTotal() {
|
|
|
+ // 计算订单总金额
|
|
|
+ const totalAmount = this.materialDetails.reduce((sum, item) => {
|
|
|
+ return sum + (Number(item.totalAmount) || 0)
|
|
|
+ }, 0)
|
|
|
+
|
|
|
+ // 计算订单总数量
|
|
|
+ const totalQuantity = this.materialDetails.reduce((sum, item) => {
|
|
|
+ return sum + (Number(item.orderQuantity) || 0)
|
|
|
+ }, 0)
|
|
|
+
|
|
|
+ // 计算总税额
|
|
|
+ const totalTaxAmount = this.materialDetails.reduce((sum, item) => {
|
|
|
+ return sum + (Number(item.taxAmount) || 0)
|
|
|
+ }, 0)
|
|
|
+
|
|
|
+ // 更新表单中的总金额、总数量和税额字段
|
|
|
+ if (this.formData) {
|
|
|
+ this.$set(this.formData, 'totalAmount', Math.round(totalAmount * 100) / 100)
|
|
|
+ this.$set(this.formData, 'totalQuantity', Math.round(totalQuantity))
|
|
|
+ this.$set(this.formData, 'totalTaxAmount', Math.round(totalTaxAmount * 100) / 100)
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理客户选择事件
|
|
|
+ * @description 当客户选择组件选择客户时的回调处理,自动填充客户编码和客户名称,并清空地址相关字段
|
|
|
+ * @param {Object} customerData - 客户数据对象
|
|
|
+ * @param {string|number} customerData.customerId - 客户ID
|
|
|
+ * @param {string} customerData.customerCode - 客户编码
|
|
|
+ * @param {string} customerData.customerName - 客户名称
|
|
|
+ * @returns {void}
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
+ */
|
|
|
+ handleCustomerSelected(customerData) {
|
|
|
+ if (this.formData) {
|
|
|
+ // 更新客户相关字段
|
|
|
+ this.$set(this.formData, 'customerId', customerData.customerId)
|
|
|
+ this.$set(this.formData, 'customerCode', customerData.customerCode)
|
|
|
+ this.$set(this.formData, 'customerName', customerData.customerName)
|
|
|
+
|
|
|
+ // 清空地址相关字段
|
|
|
+ this.$set(this.formData, 'addressId', '')
|
|
|
+ this.$set(this.formData, 'receiverName', '')
|
|
|
+ this.$set(this.formData, 'receiverPhone', '')
|
|
|
+ this.$set(this.formData, 'receiverRegion', '')
|
|
|
+ this.$set(this.formData, 'receiverAddress', '')
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理地址选择事件
|
|
|
+ * @description 当地址选择组件选择地址时的回调处理,自动填充收货人相关信息
|
|
|
+ * @param {Object} addressData - 地址数据对象
|
|
|
+ * @param {string|number} addressData.addressId - 地址ID
|
|
|
+ * @param {string} addressData.receiverName - 收货人姓名
|
|
|
+ * @param {string} addressData.receiverPhone - 收货人电话
|
|
|
+ * @param {string} addressData.regionCode - 地区编码
|
|
|
+ * @param {string} addressData.regionName - 地区名称
|
|
|
+ * @param {string} addressData.detailAddress - 详细地址
|
|
|
+ * @param {string} addressData.postalCode - 邮政编码
|
|
|
+ * @returns {void}
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
+ */
|
|
|
+ handleAddressSelected(addressData) {
|
|
|
+ if (this.formData) {
|
|
|
+ // 更新地址相关字段
|
|
|
+ this.$set(this.formData, 'addressId', addressData.addressId)
|
|
|
+ this.$set(this.formData, 'receiverName', addressData.receiverName || '')
|
|
|
+ this.$set(this.formData, 'receiverPhone', addressData.receiverPhone || '')
|
|
|
+ this.$set(this.formData, 'receiverRegion', addressData.regionName || '')
|
|
|
+ this.$set(this.formData, 'receiverAddress', addressData.detailAddress || '')
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理地址回显
|
|
|
+ * @description 在编辑模式下,根据表单中的地址信息在地址选择组件中进行回显
|
|
|
+ * @returns {void}
|
|
|
+ * @this {import('./types').OrderFormMixin}
|
|
|
+ */
|
|
|
+ handleAddressEcho() {
|
|
|
+ // 查找地址选择组件的引用
|
|
|
+ const addressSelectRefs = this.$refs.orderForm?.$refs?.addressId
|
|
|
+ const addressSelectComponent = Array.isArray(addressSelectRefs) ? addressSelectRefs[0] : addressSelectRefs
|
|
|
+
|
|
|
+ if (addressSelectComponent && typeof addressSelectComponent.setEchoValue === 'function') {
|
|
|
+ // 构建地址信息对象用于匹配
|
|
|
+ const addressInfo = {
|
|
|
+ receiverName: this.formData.receiverName,
|
|
|
+ receiverPhone: this.formData.receiverPhone,
|
|
|
+ regionName: this.formData.receiverRegion,
|
|
|
+ detailAddress: this.formData.receiverAddress
|
|
|
+ }
|
|
|
+
|
|
|
+ // 调用地址选择组件的回显方法
|
|
|
+ addressSelectComponent.setEchoValue(addressInfo)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|