Переглянути джерело

feat(数据导出): 重构订单数据处理器和Excel导出工具

yz 5 днів тому
батько
коміт
4538b11dcc
2 змінених файлів з 119 додано та 61 видалено
  1. 78 21
      src/utils/export/data-processor.js
  2. 41 40
      src/utils/export/excel-export-util.js

+ 78 - 21
src/utils/export/data-processor.js

@@ -9,14 +9,18 @@
  */
 class DataProcessor {
   constructor() {
+    // 基于实际页面表头的字段映射
     this.fieldMapping = {
-      '订单号': 'orderCode',
-      '项目名称': 'orgName',
-      '供应商': 'customerName',
-      '采购数量': 'totalQuantity',
-      '采购单价': 'unitPrice',
-      '采购金额': 'totalAmount',
-      '付款金额': 'totalAmount'
+      '订单编码': 'orderCode',
+      '组织名称': 'orgName',
+      '客户名称': 'customerName',
+      '订单类型': 'orderType',
+      '订单状态': 'status',
+      '订单总金额': 'totalAmount',
+      '订单总数量': 'totalQuantity',
+      '收货人姓名': 'receiverName',
+      '收货人电话': 'receiverPhone',
+      '创建时间': 'createTime'
     };
   }
 
@@ -26,14 +30,17 @@ class DataProcessor {
    */
   transformOrderData(ordersWithDetails) {
     return ordersWithDetails.map(order => ({
-      orderCode: order.orderCode,
-      orgName: order.orgName,
-      supplierName: order.customerName, // 工厂订单中客户=供应商
-      totalQuantity: this.parseNumber(order.totalQuantity),
-      unitPrice: this.calculateAveragePrice(order.details),
-      totalAmount: this.parseNumber(order.totalAmount),
-      paymentAmount: this.parseNumber(order.totalAmount), // 暂使用总金额
-      orderItems: this.transformOrderItems(order.details)
+      '订单编码': order.orderCode || '',
+      '组织名称': order.orgName || '',
+      '客户名称': order.customerName || '',
+      '订单类型': this.getOrderTypeLabel(order.orderType) || '',
+      '订单状态': this.getOrderStatusLabel(order.status) || '',
+      '订单总金额': this.parseNumber(order.totalAmount),
+      '订单总数量': this.parseNumber(order.totalQuantity),
+      '收货人姓名': order.receiverName || '',
+      '收货人电话': order.receiverPhone || '',
+      '创建时间': this.formatDateTime(order.createTime),
+      '订单明细': this.transformOrderItems(order.details)
     }));
   }
 
@@ -42,13 +49,16 @@ class DataProcessor {
    * @param {Array} details 订单明细
    */
   transformOrderItems(details) {
+    if (!details || !Array.isArray(details)) return [];
+
     return details.map(item => ({
-      itemCode: item.itemCode,
-      itemName: item.itemName,
-      specs: item.specs,
-      quantity: this.parseNumber(item.orderQuantity),
-      unitPrice: this.parseNumber(item.unitPrice),
-      totalAmount: this.parseNumber(item.totalAmount)
+      '商品编码': item.itemCode || '',
+      '商品名称': item.itemName || '',
+      '规格型号': item.specs || '',
+      '单位': item.unit || '个', // 如果没有单位字段,使用默认值
+      '数量': this.parseNumber(item.orderQuantity), // 使用 orderQuantity 字段
+      '单价': this.parseNumber(item.unitPrice),
+      '总金额': this.parseNumber(item.totalAmount) // 使用 totalAmount 字段
     }));
   }
 
@@ -77,6 +87,53 @@ class DataProcessor {
     const num = parseFloat(value);
     return isNaN(num) ? 0 : num;
   }
+
+  /**
+   * 获取订单类型标签
+   * @param {string|number} orderType 订单类型
+   */
+  getOrderTypeLabel(orderType) {
+    const orderTypeMap = {
+      0: '未知类型',
+      1: '普通订单'
+    };
+    return orderTypeMap[orderType] || orderType || '';
+  }
+
+  /**
+   * 获取订单状态标签
+   * @param {string|number} status 订单状态
+   */
+  getOrderStatusLabel(status) {
+    const statusMap = {
+      0: '草稿',
+      1: '待审核',
+      2: '已审核',
+      3: '已发货',
+      4: '已完成',
+      5: '已取消'
+    };
+    return statusMap[status] || status || '';
+  }
+
+  /**
+   * 格式化日期时间
+   * @param {string} dateTime 日期时间字符串
+   */
+  formatDateTime(dateTime) {
+    if (!dateTime) return '';
+    try {
+      // 如果已经是格式化的日期,直接返回
+      if (dateTime.includes('-')) {
+        return dateTime;
+      }
+      // 如果是时间戳,格式化
+      const date = new Date(dateTime);
+      return date.toISOString().slice(0, 19).replace('T', ' ');
+    } catch (error) {
+      return dateTime || '';
+    }
+  }
 }
 
 // 导出单例实例

+ 41 - 40
src/utils/export/excel-export-util.js

@@ -48,7 +48,7 @@ class ExcelExportUtil {
     // 为每个订单创建工作表
     for (let i = 0; i < ordersData.length; i++) {
       const orderData = ordersData[i];
-      const worksheet = workbook.addWorksheet(this.sanitizeSheetName(orderData.orderCode));
+      const worksheet = workbook.addWorksheet(this.sanitizeSheetName(orderData['订单编码']));
 
       // 生成订单Sheet内容
       this.generateOrderSheet(worksheet, orderData);
@@ -71,22 +71,25 @@ class ExcelExportUtil {
    */
   generateOrderSheet(worksheet, orderData) {
     let rowIndex = 1;
-    const maxColumns = 7; // 7个字段
+    const maxColumns = 10; // 10个主要字段
 
     // 1. 设置列宽
     worksheet.columns = [
-      { width: 15 }, // 订单号
-      { width: 20 }, // 项目名称
-      { width: 15 }, // 供应商
-      { width: 12 }, // 采购数量
-      { width: 12 }, // 采购单价
-      { width: 15 }, // 采购金额
-      { width: 15 }  // 付款金额
+      { width: 15 }, // 订单编码
+      { width: 20 }, // 组织名称
+      { width: 20 }, // 客户名称
+      { width: 12 }, // 订单类型
+      { width: 12 }, // 订单状态
+      { width: 15 }, // 订单总金额
+      { width: 15 }, // 订单总数量
+      { width: 15 }, // 收货人姓名
+      { width: 15 }, // 收货人电话
+      { width: 20 }  // 创建时间
     ];
 
     // 2. 标题行
     const titleRow = worksheet.getRow(rowIndex++);
-    titleRow.values = [`订单采购汇总 - ${orderData.orderCode}`];
+    titleRow.values = [`订单汇总 - ${orderData['订单编码']}`];
     titleRow.font = { size: 14, bold: true };
     titleRow.alignment = { horizontal: 'center', vertical: 'middle' };
     titleRow.height = 40;
@@ -97,19 +100,25 @@ class ExcelExportUtil {
 
     // 4. 表头行
     const headerRow = worksheet.getRow(rowIndex++);
-    headerRow.values = ['订单号', '项目名称', '供应商', '采购数量', '采购单价', '采购金额', '付款金额'];
+    headerRow.values = [
+      '订单编码', '组织名称', '客户名称', '订单类型', '订单状态',
+      '订单总金额', '订单总数量', '收货人姓名', '收货人电话', '创建时间'
+    ];
     this.applyHeaderStyle(headerRow);
 
     // 5. 订单主信息行
     const mainInfoRow = worksheet.getRow(rowIndex++);
     mainInfoRow.values = [
-      orderData.orderCode,
-      orderData.orgName,
-      orderData.supplierName,
-      orderData.totalQuantity,
-      orderData.unitPrice.toFixed(2),
-      orderData.totalAmount.toFixed(2),
-      orderData.paymentAmount.toFixed(2)
+      orderData['订单编码'],
+      orderData['组织名称'],
+      orderData['客户名称'],
+      orderData['订单类型'],
+      orderData['订单状态'],
+      orderData['订单总金额'],
+      orderData['订单总数量'],
+      orderData['收货人姓名'],
+      orderData['收货人电话'],
+      orderData['创建时间']
     ];
     this.applyDataStyle(mainInfoRow);
 
@@ -121,44 +130,36 @@ class ExcelExportUtil {
     detailTitleRow.values = ['订单明细信息'];
     detailTitleRow.font = { size: 12, bold: true };
     detailTitleRow.height = 30;
-    worksheet.mergeCells(rowIndex - 1, 1, rowIndex - 1, maxColumns);
+    worksheet.mergeCells(rowIndex - 1, 1, rowIndex - 1, 7); // 明细表7列
 
     // 8. 空行
     rowIndex++;
 
     // 9. 明细表头行
     const detailHeaderRow = worksheet.getRow(rowIndex++);
-    detailHeaderRow.values = ['物料编码', '物料名称', '规格', '数量', '单价', '金额'];
+    detailHeaderRow.values = ['商品编码', '商品名称', '规格型号', '单位', '数量', '单价', '总金额'];
     this.applyHeaderStyle(detailHeaderRow);
 
     // 10. 明细数据行
-    orderData.orderItems.forEach(item => {
+    const orderItems = orderData['订单明细'] || [];
+    orderItems.forEach(item => {
       const dataRow = worksheet.getRow(rowIndex++);
       dataRow.values = [
-        item.itemCode,
-        item.itemName,
-        item.specs,
-        item.quantity,
-        item.unitPrice.toFixed(2),
-        item.totalAmount.toFixed(2)
+        item['商品编码'],
+        item['商品名称'],
+        item['规格型号'],
+        item['单位'],
+        item['数量'],
+        item['单价'],
+        item['总金额']
       ];
       this.applyDataStyle(dataRow);
 
       // 设置数字格式
-      dataRow.getCell(4).numFmt = '#,##0';    // 数量
-      dataRow.getCell(5).numFmt = '#,##0.00'; // 单价
-      dataRow.getCell(6).numFmt = '#,##0.00'; // 金额
+      dataRow.getCell(5).numFmt = '#,##0.0000'; // 数量(4位小数)
+      dataRow.getCell(6).numFmt = '#,##0.00';  // 单价(2位小数)
+      dataRow.getCell(7).numFmt = '#,##0.00';  // 总金额(2位小数)
     });
-
-    // 11. 合计行
-    const totalRow = worksheet.getRow(rowIndex++);
-    const totalQuantity = orderData.orderItems.reduce((sum, item) => sum + item.quantity, 0);
-    const totalAmount = orderData.orderItems.reduce((sum, item) => sum + item.totalAmount, 0);
-
-    totalRow.values = ['合计', '', '', totalQuantity, '', totalAmount.toFixed(2), ''];
-    this.applyTotalStyle(totalRow);
-    totalRow.getCell(4).numFmt = '#,##0';
-    totalRow.getCell(6).numFmt = '#,##0.00';
   }
 
   /**