Browse Source

feat(订单): 新增订单表单组件并重构订单管理页面

yz 2 months ago
parent
commit
28aa4542a7

File diff suppressed because it is too large
+ 0 - 0
order-form-example.html


+ 321 - 0
src/components/order-form/form-option.js

@@ -0,0 +1,321 @@
+import { ORDER_TYPE_OPTIONS, ORDER_STATUS_OPTIONS } from '@/constants'
+
+/**
+ * AvueJS 表单字段配置接口
+ * @typedef {Object} AvueFormColumn
+ * @property {string} label - 字段标签
+ * @property {string} prop - 字段属性名
+ * @property {'input'|'select'|'number'|'textarea'|'date'|'datetime'} type - 字段类型
+ * @property {number} span - 栅格占位格数(1-24)
+ * @property {string} [placeholder] - 占位符文本
+ * @property {boolean} [required] - 是否必填
+ * @property {boolean} [disabled] - 是否禁用
+ * @property {boolean} [display] - 是否显示
+ * @property {number} [precision] - 数字精度
+ * @property {string} [prepend] - 前置内容
+ * @property {number} [minRows] - 最小行数(textarea)
+ * @property {number} [maxRows] - 最大行数(textarea)
+ * @property {number} [maxlength] - 最大长度
+ * @property {boolean} [showWordLimit] - 是否显示字数统计
+ * @property {RegExp} [pattern] - 正则验证模式
+ * @property {Array<{label: string, value: string|number}>} [dicData] - 选项数据
+ * @property {Array<{required?: boolean, message: string, trigger: string, type?: string, min?: number, pattern?: RegExp}>} [rules] - 验证规则
+ */
+
+/**
+ * AvueJS 表单分组配置接口
+ * @typedef {Object} AvueFormGroup
+ * @property {string} label - 分组标签
+ * @property {string} icon - 分组图标
+ * @property {string} prop - 分组属性名
+ * @property {Array<AvueFormColumn>} column - 分组内的字段配置
+ */
+
+/**
+ * AvueJS 表单完整配置接口
+ * @typedef {Object} AvueFormOption
+ * @property {boolean} submitBtn - 是否显示提交按钮
+ * @property {boolean} emptyBtn - 是否显示清空按钮
+ * @property {number} labelWidth - 标签宽度(px)
+ * @property {number} gutter - 栅格间隔(px)
+ * @property {boolean} menuBtn - 是否显示菜单按钮
+ * @property {'small'|'medium'|'mini'} [size] - 组件尺寸
+ * @property {Array<AvueFormGroup>} group - 表单分组配置
+ */
+
+/**
+ * 订单表单 AvueJS 配置
+ * @description 基于示例HTML结构设计的订单表单配置,采用分组折叠布局和小尺寸组件
+ * @type {AvueFormOption}
+ */
+export const orderFormOption = {
+  // 表单基础配置 - 参照示例HTML中的小尺寸组件设计
+  submitBtn: false, // 不显示默认提交按钮
+  emptyBtn: false,  // 不显示默认清空按钮
+  labelWidth: 100,  // 标签宽度,参照示例中的100px设计
+  gutter: 20,       // 栅格间隔
+  menuBtn: false,   // 不显示菜单按钮
+  size: 'small',    // 使用小尺寸组件,与示例HTML保持一致
+  
+  // 表单分组配置
+  group: [
+    {
+      label: '基本信息',
+      icon: 'el-icon-document',
+      prop: 'basic',
+      column: [
+        {
+          label: '订单编码',
+          prop: 'orderCode',
+          type: 'input',
+          span: 8,
+          placeholder: '请输入订单编码',
+          rules: [{
+            required: true,
+            message: '请输入订单编码',
+            trigger: 'blur'
+          }]
+        },
+        {
+          label: '组织编码',
+          prop: 'orgCode',
+          type: 'input',
+          span: 8,
+          placeholder: '请输入组织编码',
+          rules: [{
+            required: true,
+            message: '请输入组织编码',
+            trigger: 'blur'
+          }]
+        },
+        {
+          label: '组织名称',
+          prop: 'orgName',
+          type: 'input',
+          span: 8,
+          placeholder: '请输入组织名称',
+          rules: [{
+            required: true,
+            message: '请输入组织名称',
+            trigger: 'blur'
+          }]
+        },
+        {
+          label: '客户编码',
+          prop: 'customerCode',
+          type: 'input',
+          span: 8,
+          placeholder: '请输入客户编码',
+          rules: [{
+            required: true,
+            message: '请输入客户编码',
+            trigger: 'blur'
+          }]
+        },
+        {
+          label: '客户名称',
+          prop: 'customerName',
+          type: 'input',
+          span: 8,
+          placeholder: '请输入客户名称',
+          rules: [{
+            required: true,
+            message: '请输入客户名称',
+            trigger: 'blur'
+          }]
+        },
+        {
+          label: '订单类型',
+          prop: 'orderType',
+          type: 'select',
+          span: 8,
+          placeholder: '请选择订单类型',
+          dicData: ORDER_TYPE_OPTIONS,
+          rules: [{
+            required: true,
+            message: '请选择订单类型',
+            trigger: 'change'
+          }]
+        }
+      ]
+    },
+    {
+      label: '金额信息',
+      icon: 'el-icon-money',
+      prop: 'amount',
+      column: [
+        {
+          label: '订单总金额',
+          prop: 'totalAmount',
+          type: 'number',
+          span: 8,
+          precision: 2,
+          placeholder: '请输入订单总金额',
+          prepend: '¥',
+          rules: [{
+            required: true,
+            message: '请输入订单总金额',
+            trigger: 'blur'
+          }, {
+            type: 'number',
+            min: 0,
+            message: '金额不能小于0',
+            trigger: 'blur'
+          }]
+        },
+        {
+          label: '订单总数量',
+          prop: 'totalQuantity',
+          type: 'number',
+          span: 8,
+          precision: 4,
+          placeholder: '请输入订单总数量',
+          rules: [{
+            required: true,
+            message: '请输入订单总数量',
+            trigger: 'blur'
+          }, {
+            type: 'number',
+            min: 0,
+            message: '数量不能小于0',
+            trigger: 'blur'
+          }]
+        }
+      ]
+    },
+    {
+      label: '收货信息',
+      icon: 'el-icon-location',
+      prop: 'receiver',
+      column: [
+        {
+          label: '收货人姓名',
+          prop: 'receiverName',
+          type: 'input',
+          span: 8,
+          placeholder: '请输入收货人姓名',
+          rules: [{
+            required: true,
+            message: '请输入收货人姓名',
+            trigger: 'blur'
+          }]
+        },
+        {
+          label: '收货人电话',
+          prop: 'receiverPhone',
+          type: 'input',
+          span: 8,
+          placeholder: '请输入收货人电话',
+          rules: [{
+            required: true,
+            message: '请输入收货人电话',
+            trigger: 'blur'
+          }, {
+            pattern: /^1[3-9]\d{9}$/,
+            message: '请输入正确的手机号码',
+            trigger: 'blur'
+          }]
+        },
+        {
+          label: '收货地址',
+          prop: 'receiverAddress',
+          type: 'textarea',
+          span: 24,
+          placeholder: '请输入收货地址',
+          minRows: 3,
+          maxRows: 5,
+          rules: [{
+            required: true,
+            message: '请输入收货地址',
+            trigger: 'blur'
+          }]
+        }
+      ]
+    },
+    {
+      label: '其他信息',
+      icon: 'el-icon-more',
+      prop: 'other',
+      column: [
+        {
+          label: '订单状态',
+          prop: 'status',
+          type: 'select',
+          span: 8,
+          placeholder: '请选择订单状态',
+          dicData: ORDER_STATUS_OPTIONS,
+          disabled: true, // 状态由系统控制,不允许手动修改
+          display: false  // 新增时不显示
+        },
+        {
+          label: '备注',
+          prop: 'remark',
+          type: 'textarea',
+          span: 24,
+          placeholder: '请输入备注信息',
+          minRows: 3,
+          maxRows: 5,
+          maxlength: 500,
+          showWordLimit: true
+        }
+      ]
+    }
+  ]
+}
+
+/**
+ * 根据编辑模式动态调整表单配置
+ * @description 基于业务逻辑动态调整表单字段的显示和编辑状态
+ * @param {boolean} [isEdit=false] - 是否为编辑模式
+ * @returns {AvueFormOption} 调整后的表单配置对象
+ * @throws {Error} 当配置对象结构异常时抛出错误
+ * @example
+ * // 获取新增模式的表单配置
+ * const createOption = getFormOption(false)
+ * 
+ * // 获取编辑模式的表单配置
+ * const editOption = getFormOption(true)
+ */
+export function getFormOption(isEdit = false) {
+  try {
+    // 深拷贝配置对象,避免修改原始配置
+    /** @type {AvueFormOption} */
+    const option = JSON.parse(JSON.stringify(orderFormOption))
+    
+    if (isEdit) {
+      // 编辑模式下的字段调整
+      adjustFieldsForEditMode(option)
+    }
+    
+    return option
+  } catch (error) {
+    console.error('获取表单配置失败:', error)
+    throw new Error(`表单配置生成失败: ${error.message}`)
+  }
+}
+
+/**
+ * 调整编辑模式下的字段配置
+ * @description 在编辑模式下禁用某些字段并显示状态字段
+ * @param {AvueFormOption} option - 表单配置对象
+ * @private
+ */
+function adjustFieldsForEditMode(option) {
+  // 编辑模式下,订单编码不可编辑
+  const basicGroup = option.group.find(group => group.prop === 'basic')
+  if (basicGroup) {
+    const orderCodeField = basicGroup.column.find(column => column.prop === 'orderCode')
+    if (orderCodeField) {
+      orderCodeField.disabled = true
+    }
+  }
+  
+  // 编辑模式下显示订单状态字段
+  const otherGroup = option.group.find(group => group.prop === 'other')
+  if (otherGroup) {
+    const statusField = otherGroup.column.find(column => column.prop === 'status')
+    if (statusField) {
+      statusField.display = true
+    }
+  }
+}

+ 539 - 0
src/components/order-form/order-form-mixin.js

@@ -0,0 +1,539 @@
+import { add, update, getDetail } from '@/api/order/order'
+import {
+  ORDER_TYPES,
+  ORDER_STATUS,
+  ORDER_TYPE_OPTIONS,
+  ORDER_STATUS_OPTIONS
+} from '@/constants/order'
+
+/**
+ * @typedef {Object} OrderFormModel
+ * @property {string|number|null} id - 订单唯一标识
+ * @property {string} orderCode - 订单编码
+ * @property {string} orgCode - 组织编码
+ * @property {string} orgName - 组织名称
+ * @property {string} customerCode - 客户编码
+ * @property {string} customerName - 客户名称
+ * @property {number} orderType - 订单类型
+ * @property {number|null} totalAmount - 订单总金额
+ * @property {number|null} totalQuantity - 订单总数量
+ * @property {string} receiverName - 收货人姓名
+ * @property {string} receiverPhone - 收货人电话
+ * @property {string} receiverAddress - 收货地址
+ * @property {number} status - 订单状态
+ * @property {string} remark - 备注信息
+ */
+
+/**
+ * @typedef {Object} ValidationRule
+ * @property {boolean} [required] - 是否必填
+ * @property {string} [message] - 验证失败提示信息
+ * @property {string} [trigger] - 触发验证的事件
+ * @property {number} [min] - 最小长度
+ * @property {number} [max] - 最大长度
+ * @property {string} [type] - 数据类型
+ * @property {number} [minimum] - 最小值
+ * @property {number} [maximum] - 最大值
+ */
+
+/**
+ * @typedef {Object.<string, ValidationRule[]>} OrderFormRules
+ */
+
+/**
+ * @typedef {Object} ApiResponse
+ * @property {number} code - 响应状态码
+ * @property {string} message - 响应消息
+ * @property {*} data - 响应数据
+ */
+
+/**
+ * @typedef {Object} OrderSelectOption
+ * @property {string} label - 显示标签
+ * @property {number} value - 选项值
+ */
+
+/**
+ * 订单表单混入组件
+ * @description 提供订单表单的数据管理、验证规则和业务逻辑的混入组件
+ * @author 系统开发团队
+ * @version 2.0.0
+ * @since 2024-01-15
+ * @mixin
+ */
+export default {
+  /**
+   * 组件响应式数据
+   * @description 定义组件的响应式数据状态
+   * @returns {Object} 组件数据对象
+   */
+  data() {
+    return {
+      /**
+       * 订单表单数据模型
+       * @description 存储订单表单的所有字段数据
+       * @type {OrderFormModel}
+       */
+      formData: this.createInitialFormData(),
+
+      /**
+       * 保存操作加载状态
+       * @description 控制保存按钮的加载状态,防止重复提交
+       * @type {boolean}
+       */
+      saveLoading: false,
+
+      /**
+       * 订单类型选项列表
+       * @description 订单类型下拉选择器的选项数据
+       * @type {OrderSelectOption[]}
+       */
+      orderTypeOptions: Object.freeze([...ORDER_TYPE_OPTIONS]),
+
+      /**
+       * 订单状态选项列表
+       * @description 订单状态下拉选择器的选项数据
+       * @type {OrderSelectOption[]}
+       */
+      orderStatusOptions: Object.freeze([...ORDER_STATUS_OPTIONS])
+    }
+  },
+
+  /**
+   * 计算属性
+   * @description 组件的响应式计算属性
+   */
+  computed: {
+    /**
+     * 订单表单验证规则
+     * @description 定义订单表单各字段的验证规则,支持必填、长度、格式等验证
+     * @returns {OrderFormRules} 完整的表单验证规则对象
+     */
+    formRules() {
+      return {
+        orderCode: [
+          {
+            required: true,
+            message: '请输入订单编码',
+            trigger: 'blur'
+          },
+          {
+            min: 3,
+            max: 50,
+            message: '订单编码长度在 3 到 50 个字符',
+            trigger: 'blur'
+          }
+        ],
+        orgCode: [
+          {
+            required: true,
+            message: '请输入组织编码',
+            trigger: 'blur'
+          },
+          {
+            min: 2,
+            max: 20,
+            message: '组织编码长度在 2 到 20 个字符',
+            trigger: 'blur'
+          }
+        ],
+        orgName: [
+          {
+            required: true,
+            message: '请输入组织名称',
+            trigger: 'blur'
+          },
+          {
+            min: 2,
+            max: 100,
+            message: '组织名称长度在 2 到 100 个字符',
+            trigger: 'blur'
+          }
+        ],
+        customerCode: [
+          {
+            required: true,
+            message: '请输入客户编码',
+            trigger: 'blur'
+          },
+          {
+            min: 3,
+            max: 50,
+            message: '客户编码长度在 3 到 50 个字符',
+            trigger: 'blur'
+          }
+        ],
+        customerName: [
+          {
+            required: true,
+            message: '请输入客户名称',
+            trigger: 'blur'
+          },
+          {
+            min: 2,
+            max: 100,
+            message: '客户名称长度在 2 到 100 个字符',
+            trigger: 'blur'
+          }
+        ],
+        orderType: [
+          {
+            required: true,
+            message: '请选择订单类型',
+            trigger: 'change'
+          }
+        ],
+        totalAmount: [
+          {
+            required: true,
+            message: '请输入订单总金额',
+            trigger: 'blur'
+          },
+          {
+            type: 'number',
+            min: 0.01,
+            message: '订单总金额必须大于0',
+            trigger: 'blur'
+          }
+        ],
+        totalQuantity: [
+          {
+            required: true,
+            message: '请输入订单总数量',
+            trigger: 'blur'
+          },
+          {
+            type: 'number',
+            min: 0.0001,
+            message: '订单总数量必须大于0',
+            trigger: 'blur'
+          }
+        ],
+        receiverName: [
+          {
+            required: true,
+            message: '请输入收货人姓名',
+            trigger: 'blur'
+          },
+          {
+            min: 2,
+            max: 50,
+            message: '收货人姓名长度在 2 到 50 个字符',
+            trigger: 'blur'
+          }
+        ],
+        receiverPhone: [
+          {
+            required: true,
+            message: '请输入收货人电话',
+            trigger: 'blur'
+          },
+          {
+            pattern: /^1[3-9]\d{9}$/,
+            message: '请输入正确的手机号码',
+            trigger: 'blur'
+          }
+        ],
+        receiverAddress: [
+          {
+            required: true,
+            message: '请输入收货地址',
+            trigger: 'blur'
+          },
+          {
+            min: 5,
+            max: 500,
+            message: '收货地址长度在 5 到 500 个字符',
+            trigger: 'blur'
+          }
+        ],
+        remark: [
+          {
+            max: 1000,
+            message: '备注信息不能超过 1000 个字符',
+            trigger: 'blur'
+          }
+        ]
+      }
+    }
+  },
+
+  /**
+   * 组件方法
+   * @description 组件的业务逻辑方法集合
+   */
+  methods: {
+    /**
+     * 创建初始表单数据
+     * @description 创建订单表单的初始数据结构
+     * @returns {OrderFormModel} 初始化的表单数据对象
+     * @private
+     */
+    createInitialFormData() {
+      return {
+        id: null,
+        orderCode: '',
+        orgCode: '',
+        orgName: '',
+        customerCode: '',
+        customerName: '',
+        orderType: ORDER_TYPES.NORMAL,
+        totalAmount: null,
+        totalQuantity: null,
+        receiverName: '',
+        receiverPhone: '',
+        receiverAddress: '',
+        status: ORDER_STATUS.DRAFT,
+        remark: ''
+      }
+    },
+
+    /**
+     * 初始化表单数据
+     * @description 根据编辑模式初始化表单,编辑模式加载数据,新增模式重置表单
+     * @returns {Promise<void>}
+     * @public
+     */
+    async initForm() {
+      try {
+        if (this.isEdit && this.orderId) {
+          await this.loadOrderDetail(this.orderId)
+        } else {
+          this.resetForm()
+        }
+      } catch (error) {
+        console.error('初始化表单失败:', error)
+        this.$message.error('初始化表单失败,请刷新页面重试')
+      }
+    },
+
+    /**
+     * 重置表单数据
+     * @description 将表单数据重置为初始状态,并清除所有验证错误信息
+     * @returns {Promise<void>}
+     * @public
+     */
+    async resetForm() {
+      try {
+        // 重置表单数据为初始状态
+        this.formData = this.createInitialFormData()
+
+        // 等待DOM更新后清除表单验证
+        await this.$nextTick()
+        
+        if (this.$refs.orderForm && typeof this.$refs.orderForm.clearValidate === 'function') {
+          this.$refs.orderForm.clearValidate()
+        }
+      } catch (error) {
+        console.warn('重置表单时发生错误:', error)
+      }
+    },
+
+    /**
+     * 加载订单详情数据
+     * @description 根据订单ID从服务器获取订单详情并填充到表单中
+     * @param {string|number} orderId - 订单唯一标识
+     * @returns {Promise<void>}
+     * @throws {Error} 当API调用失败或数据格式错误时抛出异常
+     * @public
+     */
+    async loadOrderDetail(orderId) {
+      if (!orderId) {
+        throw new Error('订单ID不能为空')
+      }
+
+      try {
+        const response = await getDetail(orderId)
+        
+        if (!response || !response.data || !response.data.data) {
+          throw new Error('服务器返回数据格式错误')
+        }
+
+        const orderData = response.data.data
+        
+        // 安全地映射订单数据到表单,确保数据类型正确
+        this.formData = this.mapOrderDataToForm(orderData)
+        
+      } catch (error) {
+        const errorMessage = error.message || '加载订单详情失败'
+        console.error('加载订单详情失败:', error)
+        this.$message.error(`${errorMessage},请重试`)
+        throw error
+      }
+    },
+
+    /**
+     * 映射订单数据到表单格式
+     * @description 将API返回的订单数据安全地映射为表单数据格式
+     * @param {Object} orderData - 从API获取的原始订单数据
+     * @returns {OrderFormModel} 格式化后的表单数据
+     * @private
+     */
+    mapOrderDataToForm(orderData) {
+      return {
+        id: orderData.id || null,
+        orderCode: String(orderData.orderCode || ''),
+        orgCode: String(orderData.orgCode || ''),
+        orgName: String(orderData.orgName || ''),
+        customerCode: String(orderData.customerCode || ''),
+        customerName: String(orderData.customerName || ''),
+        orderType: Number(orderData.orderType) || ORDER_TYPES.NORMAL,
+        totalAmount: orderData.totalAmount ? Number(orderData.totalAmount) : null,
+        totalQuantity: orderData.totalQuantity ? Number(orderData.totalQuantity) : null,
+        receiverName: String(orderData.receiverName || ''),
+        receiverPhone: String(orderData.receiverPhone || ''),
+        receiverAddress: String(orderData.receiverAddress || ''),
+        status: Number(orderData.status) || ORDER_STATUS.DRAFT,
+        remark: String(orderData.remark || '')
+      }
+    },
+
+    /**
+     * 处理返回列表操作
+     * @description 触发返回列表事件,通知父组件关闭表单
+     * @returns {void}
+     * @public
+     * @emits back 返回列表事件
+     */
+    handleBack() {
+      /**
+       * 返回列表事件
+       * @event back
+       * @description 用户点击返回按钮时触发
+       */
+      this.$emit('back')
+    },
+
+    /**
+     * 处理表单保存操作
+     * @description 验证表单数据并提交到服务器,支持新增和编辑模式
+     * @returns {Promise<void>}
+     * @throws {Error} 当表单验证失败或API调用失败时抛出异常
+     * @public
+     * @emits save-success 保存成功事件
+     */
+    async handleSave() {
+      if (this.saveLoading) {
+        return // 防止重复提交
+      }
+
+      try {
+        // 表单验证
+        const isValid = await this.validateForm()
+        if (!isValid) {
+          return
+        }
+
+        this.saveLoading = true
+
+        // 准备提交数据
+        const submitData = this.prepareSubmitData()
+
+        // 调用相应的API
+        const response = await this.submitOrderData(submitData)
+
+        // 显示成功提示
+        const successMessage = this.isEdit ? '订单更新成功' : '订单创建成功'
+        this.$message.success(successMessage)
+
+        /**
+         * 保存成功事件
+         * @event save-success
+         * @param {Object} data - 保存后的订单数据
+         * @description 订单保存成功后触发,携带最新的订单数据
+         */
+        this.$emit('save-success', response.data.data)
+
+        // 返回列表
+        this.handleBack()
+
+      } catch (error) {
+        const errorMessage = this.isEdit ? '订单更新失败,请重试' : '订单创建失败,请重试'
+        console.error('保存订单失败:', error)
+        this.$message.error(errorMessage)
+        throw error
+      } finally {
+        this.saveLoading = false
+      }
+    },
+
+    /**
+     * 提交订单数据到服务器
+     * @description 根据编辑模式调用相应的API接口
+     * @param {Object} submitData - 要提交的订单数据
+     * @returns {Promise<ApiResponse>} API响应结果
+     * @private
+     */
+    async submitOrderData(submitData) {
+      if (this.isEdit) {
+        return await update(submitData)
+      } else {
+        return await add(submitData)
+      }
+    },
+
+    /**
+     * 验证表单数据
+     * @description 使用AvueJS表单的验证功能验证所有字段
+     * @returns {Promise<boolean>} 验证结果,true表示验证通过,false表示验证失败
+     * @public
+     */
+    async validateForm() {
+      if (!this.$refs.orderForm) {
+        console.warn('表单引用不存在,无法进行验证')
+        return false
+      }
+
+      try {
+        const valid = await this.$refs.orderForm.validate()
+        return Boolean(valid)
+      } catch (error) {
+        console.warn('表单验证失败:', error)
+        this.$message.warning('请检查表单填写是否正确')
+        return false
+      }
+    },
+
+    /**
+     * 准备提交数据
+     * @description 处理表单数据,移除空值字段并确保数据类型正确
+     * @returns {Object} 格式化后的提交数据对象
+     * @public
+     */
+    prepareSubmitData() {
+      const submitData = { ...this.formData }
+
+      // 清理和格式化数据
+      return this.cleanAndFormatSubmitData(submitData)
+    },
+
+    /**
+     * 清理和格式化提交数据
+     * @description 移除空值字段并确保数据类型正确
+     * @param {OrderFormModel} data - 原始表单数据
+     * @returns {Object} 清理后的数据对象
+     * @private
+     */
+    cleanAndFormatSubmitData(data) {
+      const cleanedData = {}
+
+      Object.keys(data).forEach(key => {
+        const value = data[key]
+        
+        // 跳过null、undefined和空字符串,但保留备注字段
+        if (value === null || value === undefined || (value === '' && key !== 'remark')) {
+          return
+        }
+
+        // 确保数字类型字段的正确性
+        if (['totalAmount', 'totalQuantity', 'orderType', 'status'].includes(key)) {
+          cleanedData[key] = Number(value) || 0
+        } else {
+          cleanedData[key] = value
+        }
+      })
+
+      return cleanedData
+    }
+  }
+}

+ 440 - 0
src/components/order-form/order-form.scss

@@ -0,0 +1,440 @@
+/**
+ * 订单表单组件样式
+ * @description 订单表单的样式定义,包含布局、颜色、动画等
+ */
+
+// 变量定义
+$header-height: 60px;
+$header-bg: #ffffff;
+$header-border: #e4e7ed;
+$primary-color: #409eff;
+$text-primary: #303133;
+$text-regular: #606266;
+$text-secondary: #909399;
+$border-color: #dcdfe6;
+$bg-color: #f5f7fa;
+$section-bg: #ffffff;
+$shadow-light: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+$border-radius: 6px;
+$transition-duration: 0.3s;
+
+// 订单表单容器
+.order-form-container {
+  position: relative;
+  width: 100%;
+  height: calc(100vh - 200px);
+  min-height: 600px;
+  background-color: $bg-color;
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
+  border-radius: $border-radius;
+  box-shadow: $shadow-light;
+
+  // 动画效果
+  animation: fadeIn $transition-duration ease-out;
+
+  @keyframes fadeIn {
+    from {
+      opacity: 0;
+      transform: translateY(20px);
+    }
+    to {
+      opacity: 1;
+      transform: translateY(0);
+    }
+  }
+}
+
+// 表单头部导航条
+.order-form-header {
+  height: $header-height;
+  background-color: $header-bg;
+  border-bottom: 1px solid $header-border;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 0 24px;
+  box-shadow: $shadow-light;
+  position: relative;
+  z-index: 10;
+
+  .header-left {
+    display: flex;
+    align-items: center;
+
+    .back-btn {
+      font-size: 16px;
+      color: $primary-color;
+      margin-right: 16px;
+      padding: 8px 12px;
+      border-radius: $border-radius;
+      transition: all $transition-duration;
+
+      &:hover {
+        background-color: rgba($primary-color, 0.1);
+        color: darken($primary-color, 10%);
+      }
+
+      .el-icon-arrow-left {
+        margin-right: 4px;
+      }
+    }
+
+    .form-title {
+      font-size: 18px;
+      font-weight: 600;
+      color: $text-primary;
+      margin: 0;
+    }
+  }
+
+  .header-right {
+    .el-button {
+      padding: 10px 20px;
+      font-size: 14px;
+      border-radius: $border-radius;
+      transition: all $transition-duration;
+
+      &.el-button--primary {
+        background-color: $primary-color;
+        border-color: $primary-color;
+
+        &:hover {
+          background-color: darken($primary-color, 10%);
+          border-color: darken($primary-color, 10%);
+        }
+      }
+    }
+  }
+}
+
+// 表单内容区域
+.order-form-content {
+  flex: 1;
+  overflow-y: auto;
+  padding: 24px;
+
+  // 自定义滚动条
+  &::-webkit-scrollbar {
+    width: 6px;
+  }
+
+  &::-webkit-scrollbar-track {
+    background: #f1f1f1;
+    border-radius: 3px;
+  }
+
+  &::-webkit-scrollbar-thumb {
+    background: #c1c1c1;
+    border-radius: 3px;
+
+    &:hover {
+      background: #a8a8a8;
+    }
+  }
+}
+
+// 表单主体
+.order-form {
+//   max-width: 1200px;
+  margin: 0 auto;
+
+  // 表单项样式
+  .el-form-item {
+    margin-bottom: 22px;
+
+    .el-form-item__label {
+      color: $text-primary;
+      font-weight: 500;
+      line-height: 32px;
+    }
+
+    .el-form-item__content {
+      .el-input,
+      .el-select,
+      .el-input-number {
+        .el-input__inner,
+        .el-input__wrapper {
+          border-radius: $border-radius;
+          transition: all $transition-duration;
+
+          &:focus {
+            border-color: $primary-color;
+            box-shadow: 0 0 0 2px rgba($primary-color, 0.2);
+          }
+        }
+      }
+
+      .el-textarea {
+        .el-textarea__inner {
+          border-radius: $border-radius;
+          transition: all $transition-duration;
+
+          &:focus {
+            border-color: $primary-color;
+            box-shadow: 0 0 0 2px rgba($primary-color, 0.2);
+          }
+        }
+      }
+
+      .el-input-number {
+        width: 100%;
+
+        .el-input-number__decrease,
+        .el-input-number__increase {
+          border-radius: 0;
+
+          &:hover {
+            color: $primary-color;
+          }
+        }
+      }
+    }
+  }
+}
+
+// 表单分组样式
+.form-section {
+  background-color: $section-bg;
+  border-radius: $border-radius;
+  padding: 24px;
+  margin-bottom: 24px;
+  box-shadow: $shadow-light;
+  border: 1px solid $border-color;
+  transition: all $transition-duration;
+
+  &:hover {
+    box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.12);
+  }
+
+  .section-title {
+    display: flex;
+    align-items: center;
+    font-size: 16px;
+    font-weight: 600;
+    color: $text-primary;
+    margin-bottom: 20px;
+    padding-bottom: 12px;
+    border-bottom: 2px solid $border-color;
+    position: relative;
+
+    i {
+      font-size: 18px;
+      color: $primary-color;
+      margin-right: 8px;
+    }
+
+    &::after {
+      content: '';
+      position: absolute;
+      bottom: -2px;
+      left: 0;
+      width: 40px;
+      height: 2px;
+      background-color: $primary-color;
+      border-radius: 1px;
+    }
+  }
+}
+
+// 响应式设计
+@media (max-width: 1200px) {
+  .order-form {
+    max-width: 100%;
+    padding: 0 16px;
+  }
+
+  .form-section {
+    padding: 20px;
+    margin-bottom: 20px;
+  }
+}
+
+@media (max-width: 768px) {
+  .order-form-header {
+    padding: 0 16px;
+
+    .header-left {
+      .form-title {
+        font-size: 16px;
+      }
+    }
+
+    .header-right {
+      .el-button {
+        padding: 8px 16px;
+        font-size: 13px;
+      }
+    }
+  }
+
+  .order-form-content {
+    padding: 16px;
+  }
+
+  .form-section {
+    padding: 16px;
+    margin-bottom: 16px;
+
+    .section-title {
+      font-size: 15px;
+      margin-bottom: 16px;
+    }
+  }
+
+  .order-form {
+    .el-form-item {
+      margin-bottom: 18px;
+
+      .el-form-item__label {
+        font-size: 14px;
+      }
+    }
+  }
+
+  // 移动端表单布局调整
+  .el-row {
+    .el-col {
+      &.el-col-8 {
+        width: 100% !important;
+        max-width: 100% !important;
+      }
+
+      &.el-col-12 {
+        width: 100% !important;
+        max-width: 100% !important;
+      }
+    }
+  }
+}
+
+@media (max-width: 480px) {
+  .order-form-header {
+    height: 50px;
+
+    .header-left {
+      .back-btn {
+        padding: 6px 8px;
+        font-size: 14px;
+        margin-right: 8px;
+      }
+
+      .form-title {
+        font-size: 14px;
+      }
+    }
+
+    .header-right {
+      .el-button {
+        padding: 6px 12px;
+        font-size: 12px;
+      }
+    }
+  }
+
+  .order-form-content {
+    padding: 12px;
+  }
+
+  .form-section {
+    padding: 12px;
+    margin-bottom: 12px;
+
+    .section-title {
+      font-size: 14px;
+      margin-bottom: 12px;
+
+      i {
+        font-size: 16px;
+      }
+    }
+  }
+}
+
+// 加载状态样式
+.order-form-container {
+  &.loading {
+    .order-form-content {
+      opacity: 0.6;
+      pointer-events: none;
+    }
+  }
+}
+
+// 错误状态样式
+.el-form-item {
+  &.is-error {
+    .el-input__inner,
+    .el-input__wrapper,
+    .el-textarea__inner {
+      border-color: #f56c6c !important;
+
+      &:focus {
+        box-shadow: 0 0 0 2px rgba(245, 108, 108, 0.2) !important;
+      }
+    }
+  }
+}
+
+// 成功状态样式
+.el-form-item {
+  &.is-success {
+    .el-input__inner,
+    .el-input__wrapper,
+    .el-textarea__inner {
+      border-color: #67c23a;
+
+      &:focus {
+        box-shadow: 0 0 0 2px rgba(103, 194, 58, 0.2);
+      }
+    }
+  }
+}
+
+// 禁用状态样式
+.el-form-item {
+  .el-input.is-disabled,
+  .el-select.is-disabled,
+  .el-input-number.is-disabled {
+    .el-input__inner,
+    .el-input__wrapper {
+      background-color: #f5f7fa;
+      border-color: #e4e7ed;
+      color: #c0c4cc;
+      cursor: not-allowed;
+    }
+  }
+}
+
+// 字数统计样式
+.el-input {
+  .el-input__count {
+    color: $text-secondary;
+    font-size: 12px;
+  }
+}
+
+// 表单验证提示样式
+.el-form-item__error {
+  color: #f56c6c;
+  font-size: 12px;
+  line-height: 1;
+  padding-top: 4px;
+  position: absolute;
+  top: 100%;
+  left: 0;
+}
+
+// 必填项标识
+.el-form-item {
+  &.is-required {
+    .el-form-item__label {
+      &::before {
+        content: '*';
+        color: #f56c6c;
+        margin-right: 4px;
+      }
+    }
+  }
+}

+ 307 - 0
src/components/order-form/order-form.vue

@@ -0,0 +1,307 @@
+<template>
+  <!-- 订单表单容器 - 参照示例HTML的基础容器结构 -->
+  <div class="order-form-container basic-container">
+    <!-- 表单头部导航 -->
+    <div class="order-form-header">
+      <div class="header-left">
+        <el-button
+          type="text"
+          icon="el-icon-arrow-left"
+          size="small"
+          class="back-btn"
+          @click="handleBack"
+        >
+          返回列表
+        </el-button>
+        <span class="form-title">{{ formTitle }}</span>
+      </div>
+      <div class="header-right">
+        <el-button
+          type="primary"
+          icon="el-icon-check"
+          size="small"
+          :loading="saveLoading"
+          @click="handleSave"
+        >
+          保存
+        </el-button>
+      </div>
+    </div>
+
+    <!-- 表单内容区域 - 参照示例HTML的avue-form结构 -->
+    <div class="order-form-content">
+      <avue-form
+        ref="orderForm"
+        v-model="formData"
+        :option="formOption"
+        class="order-form"
+        @submit="handleFormSubmit"
+        @reset-change="handleFormReset"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import orderFormMixin from './order-form-mixin'
+import { getFormOption } from './form-option'
+
+/**
+ * @typedef {Object} OrderFormData
+ * @property {string} orderCode - 订单编码
+ * @property {string} customerName - 客户名称
+ * @property {string} orderType - 订单类型
+ * @property {string} orderStatus - 订单状态
+ * @property {number} totalAmount - 订单总金额
+ * @property {number} paidAmount - 已付金额
+ * @property {string} receiverName - 收货人姓名
+ * @property {string} receiverPhone - 收货人电话
+ * @property {string} receiverAddress - 收货地址
+ * @property {string} remark - 备注信息
+ * @property {string} createTime - 创建时间
+ * @property {string} updateTime - 更新时间
+ */
+
+/**
+ * @typedef {Object} OrderFormProps
+ * @property {boolean} visible - 表单是否可见
+ * @property {boolean} isEdit - 是否为编辑模式
+ * @property {string|number|null} orderId - 订单ID(编辑模式时使用)
+ */
+
+/**
+ * 订单表单组件
+ * @description 基于AvueJS的订单表单组件,支持新增和编辑订单功能
+ * @author 系统开发团队
+ * @version 2.0.0
+ * @since 2024-01-15
+ */
+export default {
+  name: 'OrderForm',
+  mixins: [orderFormMixin],
+
+  /**
+   * 计算属性
+   * @description 组件的响应式计算属性
+   */
+  computed: {
+    /**
+     * 获取表单配置选项
+     * @description 根据编辑模式动态生成AvueJS表单配置
+     * @returns {AvueFormOption} AvueJS表单配置对象
+     */
+    formOption() {
+      return getFormOption(this.isEdit)
+    },
+
+    /**
+     * 表单标题
+     * @description 根据编辑模式动态显示表单标题
+     * @returns {string} 表单标题文本
+     */
+    formTitle() {
+      return this.isEdit ? '编辑订单' : '新增订单'
+    }
+  },
+
+  /**
+   * 组件属性定义
+   * @description 定义组件接收的外部属性及其类型约束
+   */
+  props: {
+    /**
+     * 表单可见性控制
+     * @description 控制订单表单的显示和隐藏状态
+     * @type {boolean}
+     * @default false
+     */
+    visible: {
+      type: Boolean,
+      default: false,
+      validator: (value) => typeof value === 'boolean'
+    },
+
+    /**
+     * 编辑模式标识
+     * @description 标识当前表单是新增模式还是编辑模式
+     * @type {boolean}
+     * @default false
+     */
+    isEdit: {
+      type: Boolean,
+      default: false,
+      validator: (value) => typeof value === 'boolean'
+    },
+
+    /**
+     * 订单唯一标识
+     * @description 编辑模式下用于标识要编辑的订单记录
+     * @type {string|number|null}
+     * @default null
+     */
+    orderId: {
+      type: [String, Number],
+      default: null,
+      validator: (value) => {
+        return value === null ||
+               typeof value === 'string' ||
+               typeof value === 'number'
+      }
+    }
+  },
+
+  /**
+   * 属性监听器
+   * @description 监听组件属性变化并执行相应的响应逻辑
+   */
+  watch: {
+    /**
+     * 监听表单可见性变化
+     * @description 当表单从隐藏变为可见时,初始化表单数据
+     * @param {boolean} newVal - 新的可见性状态
+     * @param {boolean} oldVal - 旧的可见性状态
+     */
+    visible: {
+      handler(newVal, oldVal) {
+        if (newVal && !oldVal) {
+          this.initForm()
+        }
+      },
+      immediate: true
+    },
+
+    /**
+     * 监听订单ID变化
+     * @description 当订单ID变化且处于编辑模式时,加载订单详情数据
+     * @param {string|number|null} newVal - 新的订单ID
+     * @param {string|number|null} oldVal - 旧的订单ID
+     */
+    orderId: {
+      handler(newVal, oldVal) {
+        if (newVal && this.isEdit && newVal !== oldVal) {
+          this.loadOrderDetail(newVal)
+        }
+      },
+      immediate: true
+    }
+  },
+
+  /**
+   * 组件方法
+   * @description 组件的业务逻辑方法
+   */
+  methods: {
+    /**
+     * 处理表单提交事件
+     * @description AvueJS表单提交时的回调处理
+     * @param {OrderFormData} formData - 表单数据
+     * @param {Function} done - 完成回调函数
+     */
+    handleFormSubmit(formData, done) {
+      this.handleSave().finally(() => {
+        if (typeof done === 'function') {
+          done()
+        }
+      })
+    },
+
+    /**
+     * 处理表单重置事件
+     * @description AvueJS表单重置时的回调处理
+     */
+    handleFormReset() {
+      this.resetForm()
+    }
+  }
+}
+</script>
+
+<style scoped>
+.el-card__body {
+    padding: 0;
+}
+.order-form-container {
+  /* padding: 20px; */
+  background-color: #f5f5f5;
+  min-height: 100vh;
+  /* max-width: 1200px; */
+  margin: 0 auto;
+}
+
+.order-form-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 16px 20px;
+  background-color: #ffffff;
+  border-radius: 8px 8px 0 0;
+  border-bottom: 1px solid #ebeef5;
+  margin-bottom: 0;
+}
+
+.header-left {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+}
+
+.back-btn {
+  color: #409eff;
+  font-size: 14px;
+  padding: 0;
+}
+
+.back-btn:hover {
+  color: #66b1ff;
+}
+
+.form-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #303133;
+  margin: 0;
+}
+
+.header-right {
+  display: flex;
+  gap: 8px;
+}
+
+.order-form-content {
+  background-color: #ffffff;
+  padding: 20px;
+  border-radius: 0 0 8px 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.order-form {
+  max-width: 100%;
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+  .order-form-container {
+    padding: 10px;
+  }
+
+  .order-form-header {
+    flex-direction: column;
+    gap: 12px;
+    align-items: flex-start;
+    padding: 12px 16px;
+  }
+
+  .header-right {
+    width: 100%;
+    justify-content: flex-end;
+  }
+
+  .form-title {
+    font-size: 16px;
+  }
+
+  .order-form-content {
+    padding: 16px;
+  }
+}
+</style>

+ 375 - 0
src/components/order-form/types.d.ts

@@ -0,0 +1,375 @@
+/**
+ * 订单表单组件类型定义文件
+ * @description 为订单表单相关组件提供完整的TypeScript类型定义
+ */
+
+/**
+ * 订单类型枚举
+ */
+export enum OrderType {
+  /** 普通订单 */
+  NORMAL = 1,
+  /** 紧急订单 */
+  URGENT = 2,
+  /** 预订订单 */
+  RESERVATION = 3
+}
+
+/**
+ * 订单状态枚举
+ */
+export enum OrderStatus {
+  /** 草稿 */
+  DRAFT = 0,
+  /** 待审核 */
+  PENDING = 1,
+  /** 已审核 */
+  APPROVED = 2,
+  /** 已发货 */
+  SHIPPED = 3,
+  /** 已完成 */
+  COMPLETED = 4,
+  /** 已取消 */
+  CANCELLED = 5
+}
+
+/**
+ * 表单验证规则接口
+ */
+export interface ValidationRule {
+  /** 是否必填 */
+  required?: boolean;
+  /** 验证失败提示信息 */
+  message?: string;
+  /** 触发验证的事件类型 */
+  trigger?: 'blur' | 'change' | 'submit';
+  /** 最小长度 */
+  min?: number;
+  /** 最大长度 */
+  max?: number;
+  /** 数据类型 */
+  type?: 'string' | 'number' | 'boolean' | 'method' | 'regexp' | 'integer' | 'float' | 'array' | 'object' | 'enum' | 'date' | 'url' | 'hex' | 'email';
+  /** 最小值(数字类型) */
+  minimum?: number;
+  /** 最大值(数字类型) */
+  maximum?: number;
+  /** 正则表达式模式 */
+  pattern?: RegExp;
+  /** 自定义验证函数 */
+  validator?: (rule: ValidationRule, value: any, callback: (error?: Error) => void) => void;
+}
+
+/**
+ * 订单表单数据模型接口
+ */
+export interface OrderFormModel {
+  /** 订单唯一标识 */
+  id: string | number | null;
+  /** 订单编码 */
+  orderCode: string;
+  /** 组织编码 */
+  orgCode: string;
+  /** 组织名称 */
+  orgName: string;
+  /** 客户编码 */
+  customerCode: string;
+  /** 客户名称 */
+  customerName: string;
+  /** 订单类型 */
+  orderType: OrderType;
+  /** 订单总金额 */
+  totalAmount: number | null;
+  /** 订单总数量 */
+  totalQuantity: number | null;
+  /** 收货人姓名 */
+  receiverName: string;
+  /** 收货人电话 */
+  receiverPhone: string;
+  /** 收货地址 */
+  receiverAddress: string;
+  /** 订单状态 */
+  status: OrderStatus;
+  /** 备注信息 */
+  remark: string;
+}
+
+/**
+ * 订单表单验证规则类型
+ */
+export type OrderFormRules = {
+  [K in keyof OrderFormModel]?: ValidationRule[];
+};
+
+/**
+ * 下拉选择器选项接口
+ */
+export interface SelectOption<T = any> {
+  /** 显示标签 */
+  label: string;
+  /** 选项值 */
+  value: T;
+  /** 是否禁用 */
+  disabled?: boolean;
+  /** 选项描述 */
+  description?: string;
+}
+
+/**
+ * 订单类型选项类型
+ */
+export type OrderTypeOption = SelectOption<OrderType>;
+
+/**
+ * 订单状态选项类型
+ */
+export type OrderStatusOption = SelectOption<OrderStatus>;
+
+/**
+ * AvueJS表单列配置接口
+ */
+export interface AvueFormColumn {
+  /** 字段标签 */
+  label: string;
+  /** 字段属性名 */
+  prop: string;
+  /** 字段类型 */
+  type?: 'input' | 'select' | 'radio' | 'checkbox' | 'textarea' | 'number' | 'date' | 'datetime' | 'time' | 'switch' | 'slider' | 'rate' | 'upload' | 'tree' | 'cascader';
+  /** 栅格占位格数 */
+  span?: number;
+  /** 输入提示 */
+  placeholder?: string;
+  /** 验证规则 */
+  rules?: ValidationRule[];
+  /** 是否禁用 */
+  disabled?: boolean;
+  /** 是否只读 */
+  readonly?: boolean;
+  /** 是否显示 */
+  display?: boolean;
+  /** 默认值 */
+  value?: any;
+  /** 选项数据(select、radio、checkbox类型使用) */
+  dicData?: SelectOption[];
+  /** 字段组 */
+  group?: string;
+  /** 排序 */
+  order?: number;
+  /** 最小值(number类型使用) */
+  min?: number;
+  /** 最大值(number类型使用) */
+  max?: number;
+  /** 步长(number类型使用) */
+  step?: number;
+  /** 精度(number类型使用) */
+  precision?: number;
+  /** 最大长度 */
+  maxlength?: number;
+  /** 最小长度 */
+  minlength?: number;
+  /** 行数(textarea类型使用) */
+  rows?: number;
+  /** 是否可调整大小(textarea类型使用) */
+  resize?: 'none' | 'both' | 'horizontal' | 'vertical';
+}
+
+/**
+ * AvueJS表单分组配置接口
+ */
+export interface AvueFormGroup {
+  /** 分组标题 */
+  title: string;
+  /** 分组图标 */
+  icon?: string;
+  /** 是否可折叠 */
+  collapse?: boolean;
+  /** 默认是否展开 */
+  active?: boolean;
+  /** 分组字段列表 */
+  column: AvueFormColumn[];
+}
+
+/**
+ * AvueJS表单配置接口
+ */
+export interface AvueFormOption {
+  /** 表单列配置 */
+  column?: AvueFormColumn[];
+  /** 分组配置 */
+  group?: AvueFormGroup[];
+  /** 标签宽度 */
+  labelWidth?: number;
+  /** 标签位置 */
+  labelPosition?: 'left' | 'right' | 'top';
+  /** 表单尺寸 */
+  size?: 'large' | 'default' | 'small';
+  /** 是否显示提交按钮 */
+  submitBtn?: boolean;
+  /** 提交按钮文本 */
+  submitText?: string;
+  /** 是否显示清空按钮 */
+  emptyBtn?: boolean;
+  /** 清空按钮文本 */
+  emptyText?: string;
+  /** 栅格间隔 */
+  gutter?: number;
+  /** 是否显示必填星号 */
+  asterisk?: boolean;
+  /** 表单验证规则 */
+  rules?: OrderFormRules;
+  /** 是否内联表单 */
+  inline?: boolean;
+  /** 表单项默认span */
+  span?: number;
+}
+
+/**
+ * API响应基础接口
+ */
+export interface ApiResponse<T = any> {
+  /** 响应状态码 */
+  code: number;
+  /** 响应消息 */
+  message: string;
+  /** 响应数据 */
+  data: T;
+  /** 是否成功 */
+  success?: boolean;
+  /** 时间戳 */
+  timestamp?: number;
+}
+
+/**
+ * 分页数据接口
+ */
+export interface PaginationData<T = any> {
+  /** 数据列表 */
+  records: T[];
+  /** 当前页码 */
+  current: number;
+  /** 每页大小 */
+  size: number;
+  /** 总记录数 */
+  total: number;
+  /** 总页数 */
+  pages: number;
+}
+
+/**
+ * 订单详情API响应类型
+ */
+export type OrderDetailResponse = ApiResponse<OrderFormModel>;
+
+/**
+ * 订单列表API响应类型
+ */
+export type OrderListResponse = ApiResponse<PaginationData<OrderFormModel>>;
+
+/**
+ * 订单保存API响应类型
+ */
+export type OrderSaveResponse = ApiResponse<OrderFormModel>;
+
+/**
+ * 组件事件类型定义
+ */
+export interface OrderFormEvents {
+  /** 返回列表事件 */
+  back: () => void;
+  /** 保存成功事件 */
+  'save-success': (data: OrderFormModel) => void;
+  /** 表单提交事件 */
+  submit: (formData: OrderFormModel, done: () => void) => void;
+  /** 表单重置事件 */
+  'reset-change': () => void;
+}
+
+/**
+ * 组件属性接口
+ */
+export interface OrderFormProps {
+  /** 表单是否可见 */
+  visible: boolean;
+  /** 是否为编辑模式 */
+  isEdit: boolean;
+  /** 订单ID(编辑模式时使用) */
+  orderId: string | number | null;
+}
+
+/**
+ * 组件数据接口
+ */
+export interface OrderFormData {
+  /** 表单数据 */
+  formData: OrderFormModel;
+  /** 保存加载状态 */
+  saveLoading: boolean;
+  /** 订单类型选项 */
+  orderTypeOptions: OrderTypeOption[];
+  /** 订单状态选项 */
+  orderStatusOptions: OrderStatusOption[];
+}
+
+/**
+ * 组件计算属性接口
+ */
+export interface OrderFormComputed {
+  /** 表单配置选项 */
+  formOption: AvueFormOption;
+  /** 表单标题 */
+  formTitle: string;
+  /** 表单验证规则 */
+  formRules: OrderFormRules;
+}
+
+/**
+ * 组件方法接口
+ */
+export interface OrderFormMethods {
+  /** 创建初始表单数据 */
+  createInitialFormData(): OrderFormModel;
+  /** 初始化表单 */
+  initForm(): Promise<void>;
+  /** 重置表单 */
+  resetForm(): Promise<void>;
+  /** 加载订单详情 */
+  loadOrderDetail(orderId: string | number): Promise<void>;
+  /** 映射订单数据到表单格式 */
+  mapOrderDataToForm(orderData: any): OrderFormModel;
+  /** 处理返回操作 */
+  handleBack(): void;
+  /** 处理保存操作 */
+  handleSave(): Promise<void>;
+  /** 提交订单数据 */
+  submitOrderData(submitData: any): Promise<ApiResponse>;
+  /** 验证表单 */
+  validateForm(): Promise<boolean>;
+  /** 准备提交数据 */
+  prepareSubmitData(): any;
+  /** 清理和格式化提交数据 */
+  cleanAndFormatSubmitData(data: OrderFormModel): any;
+  /** 处理表单提交事件 */
+  handleFormSubmit(formData: OrderFormModel, done: () => void): void;
+  /** 处理表单重置事件 */
+  handleFormReset(): void;
+}
+
+/**
+ * Vue组件实例类型
+ */
+export interface OrderFormComponent extends OrderFormProps, OrderFormData, OrderFormComputed, OrderFormMethods {
+  /** Vue组件引用 */
+  $refs: {
+    orderForm: any;
+  };
+  /** Vue事件发射器 */
+  $emit: <K extends keyof OrderFormEvents>(event: K, ...args: Parameters<OrderFormEvents[K]>) => void;
+  /** Vue消息提示 */
+  $message: {
+    success(message: string): void;
+    error(message: string): void;
+    warning(message: string): void;
+    info(message: string): void;
+  };
+  /** Vue下一个tick */
+  $nextTick(): Promise<void>;
+}

+ 63 - 7
src/views/order/order/index-avue.vue

@@ -1,6 +1,18 @@
 <template>
   <basic-container>
+    <!-- 订单表单组件 -->
+    <order-form
+      v-if="orderFormVisible"
+      :visible="orderFormVisible"
+      :is-edit="isEditMode"
+      :order-id="editOrderId"
+      @back="handleFormBack"
+      @save-success="handleFormSaveSuccess"
+    />
+    
+    <!-- 订单列表 -->
     <avue-crud
+      v-else
       :option="option"
       :table-loading="loading"
       :data="data"
@@ -119,13 +131,15 @@ import {
 } from '@/constants'
 import OrderItemManagement from '@/components/order-item-management'
 import OrderItemTable from '@/components/order-item-table'
+import OrderForm from '@/components/order-form/order-form.vue'
 import { mapGetters } from 'vuex'
 
 export default {
   name: 'OrderAvue',
   components: {
     OrderItemManagement,
-    OrderItemTable
+    OrderItemTable,
+    OrderForm
   },
   data() {
     return {
@@ -141,7 +155,11 @@ export default {
       },
       itemDialogVisible: false,
       currentOrderId: null,
-      currentOrderInfo: null
+      currentOrderInfo: null,
+      // 订单表单相关状态
+      orderFormVisible: false,
+      isEditMode: false,
+      editOrderId: null
     }
   },
   computed: {
@@ -238,12 +256,25 @@ export default {
      * @returns {void}
      */
     beforeOpen(done, type) {
+      if (type === 'edit') {
+        // 编辑模式使用新的表单组件
+        this.isEditMode = true
+        this.editOrderId = this.form.id
+        this.orderFormVisible = true
+        // 不调用done(),阻止默认弹窗打开
+        return
+      }
+      
       if (type === 'add') {
-        this.form = {
-          orderType: ORDER_TYPES.NORMAL,
-          status: ORDER_STATUS.DRAFT
-        }
+        // 新增模式也使用新的表单组件
+        this.isEditMode = false
+        this.editOrderId = null
+        this.orderFormVisible = true
+        // 不调用done(),阻止默认弹窗打开
+        return
       }
+      
+      // 其他模式(如查看)使用默认弹窗
       done()
     },
 
@@ -289,7 +320,9 @@ export default {
      * @returns {void}
      */
     handleAdd() {
-      this.$refs.crud.rowAdd()
+      this.isEditMode = false
+      this.editOrderId = null
+      this.orderFormVisible = true
     },
 
     /**
@@ -319,6 +352,29 @@ export default {
       this.currentOrderInfo = null
     },
 
+    /**
+     * 处理表单返回
+     * @returns {void}
+     */
+    handleFormBack() {
+      this.orderFormVisible = false
+      this.isEditMode = false
+      this.editOrderId = null
+    },
+
+    /**
+     * 处理表单保存成功
+     * @param {OrderItem} orderData - 保存后的订单数据
+     * @returns {void}
+     */
+    handleFormSaveSuccess(orderData) {
+      this.orderFormVisible = false
+      this.isEditMode = false
+      this.editOrderId = null
+      // 刷新列表数据
+      this.onLoad(this.page)
+    },
+
     // 工具方法
     getOrderTypeLabel,
     getOrderTypeTagType,

Some files were not shown because too many files changed in this diff