跳转到主要内容

发货-发货详情(新)

发货详情报表模块功能解析文档发货详情报表模块(ShipV2)功能解析

1. 系统架构模块架构

1.1 整体架构前端架构

发货详情报表模块采用前后端分离架构,主要包含以下组件:

  • 前端组件核心文件wimoor-ui/src/views/amazon/report/shipv2/detail/index.vue
  • 技术栈:Vue 3、Element Plus、Vite、Axios
  • 状态管理:Vue 3 +Composition Element Plus 构建的单页应用API(reactive、ref)
  • 后端服务API接口Spring Boot 微服务,提供 RESTful API
  • 数据库:MySQL 数据库存储发货相关数据
  • 外部依赖:亚马逊API用于获取和同步FBA货件信息wimoor-ui/src/api/amazon/inbound/reportV2Api.js

1.2 模块依赖关系后端架构

  • 控制器ShipInboundReportV2Controller.java
  • 服务层IShipInboundPlanService.javaShipInboundPlanServiceImpl.java
  • 数据访问ShipInboundPlanV2Mapper.javaShipInboundPlanV2Mapper.xml
  • 技术栈:Spring Boot、MyBatis Plus、MySQL

1.3 数据流

flowchart前端用户操作 TD A[前端detail/index.vue]筛选条件设置 --> B[reportApi.js]API调用 B -->后端控制器处理 C[ShipInboundReportController] C服务层业务逻辑 --> D[ShipInboundPlanService]Mapper数据查询 D -->数据库 E[ShipInboundPlanMapper] E数据返回 --> F[MySQL数据库]
    D --> G[ShipInboundItemService]
    G --> H[产品信息数据库]前端渲染

2. 前端实现

2.1 核心文件结构核心组件结构

wimoor-ui/src/views/amazon/report/ship/detail/
├── index.vue                    # 主页面组件
├── components/                  # 子组件目录
└── ...

wimoor-ui/src/api/amazon/inbound/
├── reportApi.js                 # 报表API接口
└── reportV2Api.js               # 报表V2 API接口

2.2 核心组件分析

2.2.1 主页面组件(index.vue)

文件路径wimoor-ui/src/views/amazon/report/ship/detail/index.vue

主要功能

  • 提供两种数据视图:按货件汇总和按SKU汇总
  • 支持多维度筛选和数据导出
  • 实时显示数据统计信息

核心代码结构

<template>
  <div class="main-sty">
    <!-- 标签页切换 -->
    <el-tabs v-model="selecttype" @tab-change="handleQuery">
      <el-tab-pane label="按货件汇总" name="shipment" key="shipment"></el-tab-pane>
      <el-tab-pane label="按SKU汇总" name="sku" key="sku"></el-tab-pane>
    </el-tabs>
    
    <!-- 筛选条件区筛选条件 -->
    <div class="filter-bar">
      <!-- 店铺选择 -->
      <el-rowselect v-model="queryParam.groupid" @change="handleQuery">
        <div!-- class="con-header"选项 -->
      </el-spaceselect>
      
      <Group!-- @change="changeGroup"日期类型选择 /-->
      <el-select v-model="queryParam.datetype" @change="handleQuery">
        <el-option label="创建日期" value="createdate" label="创建日期"></el-option>
        <el-option value="deliverydate" label="发货日期" value="senddate"></el-option>
      </el-select>
      
      <Datepicker!-- longtime="ok"日期范围选择 @changedate="changedate" /-->
      <Warehouseel-date-picker @changeware=v-model="getWarehouse"dateRange" defaultValue=@change="handleQuery"></el-date-picker>
      
      <!-- 仓库选择 -->
      <el-select v-model="queryParam.warehouseid" @change="handleQuery">
        <el-option label="全部" value="all"></el-option>
        <!-- 选项 -->
      </el-select>
      
      <!-- 货件编码搜索 -->
      <el-input v-model="queryParam.search" placeholder=@keyup.enter="请输入货件编码" handleQuery"></>
          <el-popover v-model:visible="moreSearchVisible"input>
      
      <!-- 高级筛选 -->
      </el-popoverbutton @click="openFilter">
        筛选</el-spacebutton>
    </div>
    
    <!-- 操作按钮 -->
    <div class="operation-bar">
      <el-button @click="refresh">刷新</el-rowbutton>
      <el-button @click="handleExport">导出</el-button>
      <!-- 按货件汇总表格其他按钮 -->
    </div>
    
    <!-- 数据表格 -->
    <el-rowtable v-if=loading="selecttype=='shipment'">
      <GlobalTable ref="globalTable"isLoading" :tableData=data="tableData" @loadTable="loadTableData"tableData.records">
      <!-- 表格列定义列定义 -->
    </GlobalTable>
    </el-rowtable>
    
    <!-- 按SKU汇总表格分页 -->
    <el-rowpagination v-else@size-change="handleSizeChange" @current-change="handleCurrentChange">
      <GlobalTable ref="skuglobalTable" :tableData="skutableData" @loadTable="skuloadTableData">
        <!-- 表格列定义 -->
      </GlobalTable>
    </el-rowpagination>
  </div>
</template>

状态管理

2.2 核心数据结构

2.2.1 响应式状态

letconst state = reactive({
  selecttype: 'shipment', // 当前选择的视图类型
  dateRange: [], // 日期范围
  queryParam: {
    search:groupid: "",undefined, marketplaceid:// "",店铺ID
    datetype: "createdate"'createdate', companyid:// ""日期类型
    fromdate: '', // 开始日期
    enddate: '', // 结束日期
    warehouseid: 'all', // 仓库ID
    search: '', // 搜索关键词
    hasexceptionnum: "all"'', // 接收异常
    carrierName: '' // 承运商
  },
  skusummary: null,
  isload: true,
  tableData: {
    records: [], // 表格数据
    total: 0 // 总记录数
  },
  isLoading: false, // 加载状态
  skutableData: {
    records: [], // SKU表格数据
    total: 0 // SKU总记录数
  },
  companylist:sumQty: 0, // 总发货数量
  sumReceivedQty: 0, // 总接收数量
  selectList: [], channellist:// [],
  moreSearchVisible: false,
  selecttype: "shipment"选中的记录
});

核心方法

2.2.2
  1. handleQuery() - 处理查询请求
API接口

function// handleQuery()reportV2Api.js
export default {
  nextTick(()getShipmentReportByLoistics, =>// {按物流商获取货件报表
  ifgetShipmentReportByWarehouseLoistics, (state.selecttype// ==按仓库和物流商获取货件报表
  "shipment")getShipmentDetailReport, {// var获取货件详情报表
  timergetShipmentReport, =// setTimeout(function()获取货件报表
  {downShipmentExcel, globalTable.value.loadTable(state.queryParam);// clearTimeout(timer);导出货件Excel
  downExcelShipmentReportByLoistics, // 导出物流商货件报表
  getShipmentReportByWarehouseLoistics
}, 500);
    } else {
      var timer = setTimeout(function() {
        skuglobalTable.value.loadTable(state.queryParam);
        clearTimeout(timer);
      }, 500);
    }
  });
}

    2.3
  1. loadTableData()核心方法
  2. -

    2.3.1 加载货件汇总数据

数据加载方法
// 加载货件汇总数据
function loadTableData(params) {
  state.isLoading = true;
  reportApi.getShipmentReport(params).then((res) => {
    state.isloadisLoading = false;
    state.tableData.records = res.data.records;
    state.tableData.total = res.data.total;
  });
}

  1. skuloadTableData() -// 加载SKU汇总数据
function skuloadTableData(params) {
  state.isLoading = true;
  reportApi.getShipmentDetailReport(params).then((res) => {
    state.isloadisLoading = false;
    state.skutableData.records = res.data.records;
    if (params.currentpage == 1) {
      state.skusummary = res.data && res.data.records && res.data.records.length > 0 
        ? res.data.records[0].summary 
        : null;
    }
    state.skutableData.total = res.data.total;
    // 统计总发货和总接收数量
    state.sumQty = res.data.records.reduce((sum, item) => sum + (item.sendqty || 0), 0);
    state.sumReceivedQty = res.data.records.reduce((sum, item) => sum + (item.receivedqty || 0), 0);
  });
}

    2.3.2
  1. downloadList(筛选条件处理
  2. function handleQuery() -{
      导出数据if 
(state.selecttype === 'shipment') { state.queryParam.pageNum = 1; loadTableData(state.queryParam); } else { state.queryParam.pageNum = 1; skuloadTableData(state.queryParam); } } function handleSizeChange(val) { state.queryParam.pageSize = val; handleQuery(); } function handleCurrentChange(val) { state.queryParam.pageNum = val; handleQuery(); }

2.3.3 导出方法

function downloadList(ftype) {
  if (ftype == "shiptask") {
    // 导出发货处理任务量
    findProcessHandle({
      "fromdate": state.queryParam.fromdate,
      "enddate": state.queryParam.enddate
    }enddate});
  } else if (ftype == "shipqty") {
    // 导出发货数量简约版
    inventoryRptApi.downloadOutstockformOut({
      "fromdate": state.queryParam.fromdate,
      "enddate": state.queryParam.enddate
    }enddate});
  } else {
    // 其他导出类型
    state.queryParam.downloadType = ftype;
    reportApi.downShipmentExcel(state.queryParam, () => {
      state.downLoading = false;
    });
  }
}

2.34 API接口层前端交互逻辑

  1. 文件路径视图切换通过wimoor-ui/src/api/amazon/inbound/reportApi.jsselecttype

    状态和标签页切换,调用不同的数据加载方法
  2. 核心接口筛选条件

    所有筛选条件变更都会触发handleQuery方法重新加载数据
  3. 分页:分页操作通过//handleSizeChangehandleCurrentChange方法处理
  4. 获取货件汇总报表
  5. 导出:根据不同的导出类型调用不同的API接口
  6. function
  7. 数据统计:SKU汇总视图下自动计算总发货和总接收数量
  8. getShipmentReport(data) { return request.post('/amazon/api/v1/ship/report/getShipmentReport', data); } // 获取SKU明细报表 function getShipmentDetailReport(data) { return request.post('/amazon/api/v1/ship/report/getShipmentDetailReport', data); } // 导出货件报表 function downShipmentExcel(data, callback) { return request({ url: "/amazon/api/v1/ship/report/downShipmentExcel", responseType: "blob", data: data, method: 'post' }).then(res => { downloadhandler.downloadSuccess(res, "shipmentReport.xlsx"); if (callback) { callback(); } }).catch(e => { downloadhandler.downloadFail(e); if (callback) { callback(); } }); }

3. 后端实现

3.1 控制器层

3.1.1 ShipInboundReportController核心API接口

文件路径

主要功能:提供发货报表相关的RESTful

API接口

核心接口

  1. getShipmentReport()
  2. -获取货件汇总报表
    API路径方法功能
    wimoor-amazon/amazon-boot/src/main/java/com/wimoor/amazon/inbound/controller/ShipInboundReportController.java/api/v2/ship/report/getShipmentReport

    POST 获取货件汇总报表
    /api/v2/ship/report/getShipmentDetailReport POST 获取SKU汇总报表
    /api/v2/ship/report/downShipmentExcelPOST导出货件报表Excel
    /api/v2/ship/report/getShipmentReportByLoisticsPOST按物流商获取货件报表
    /api/v2/ship/report/getShipmentReportByWarehouseLoisticsPOST按仓库和物流商获取货件报表
    /api/v2/ship/report/downExcelShipmentReportByLoisticsPOST导出物流商货件报表Excel

    3.1.2 控制器方法实现

    @PostMapping(value = "/getShipmentReport")
    public Result<IPage<Map<String, Object>>> getShipmentReport(@RequestBody ShipInboundShipmenSummaryDTO dto) {
        Map<String, Object> param = new HashMap<String, Object>();
        // 参数处理
        UserInfo user = UserInfoContext.get();
        param.put("shopid", user.getCompanyid());
        // 处理marketplaceid
      String marketplaceid = dto.getMarketplaceid();
      if (StrUtil.isEmpty(marketplaceid)) {
        marketplaceid = null;
      }
      param.put("marketplaceid", marketplaceid);
      
      // 处理groupid
      String groupid = dto.getGroupid(getMarketplaceid());
      if (StrUtil.isEmpty(groupid)) {
        groupid = null;
      }
        param.put("groupid", groupid);
      
      // 处理搜索条件
      String search = dto.getSearch(getGroupid());
      if (StrUtil.isNotEmpty(search)) {
        param.put("search", search.trim(dto.getSearch() + "%");
      } else {
        param.put("search", null);
      }
      
      // 处理日期类型
      String datetype = dto.getDatetype();
        param.put("datetype", datetype);
      
      // 处理日期范围
      String fromDate = dto.getFromdate();
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
      if (StrUtil.isNotEmpty(fromDate)) {
        param.put("fromDate", fromDate.trim(getDatetype());
      } else {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, -7);
        fromDate = GeneralUtil.formatDate(cal.getTime(), sdf);
        param.put("fromDate", fromDate);
      }
      
      String toDate = dto.getEnddate(getFromdate();
      if (StrUtil.isNotEmpty(toDate)) {
        param.put("endDate", toDate.trim().substring(0, 10) + " 23:59:59");
      } else {
        toDate = GeneralUtil.formatDate(new Date(), sdf);
        param.put("endDate", toDate + " 23:59:59"dto.getEnddate());
      }
      
      // 处理仓库
      String warehouseid = dto.getWarehouseid();
      if (StrUtil.isEmpty(warehouseid) || "all".equals(warehouseid)) {
        warehouseid = null;
      }
        param.put("warehouseid", warehouseid);
      
      // 处理承运商
      String company = dto.getCompany(getWarehouseid());
      if (StrUtil.isEmpty(company)) {
        param.put("company", null);
      } else {
        param.put("company", company + "%"dto.getCompany());
      }
      
      String companyid = dto.getCompanyid();
      if (StrUtil.isEmpty(companyid)) {
        param.put("companyid", null);
      } else {
        param.put("companyid", companyid);
      }
      
      // 处理接收异常
      String iserror = dto.getHasexceptionnum(getCompanyid());
      if (StrUtil.isEmpty(iserror) || "all".equals(iserror)) {
        iserror = null;
      }
        param.put("iserror", iserror)dto.getHasexceptionnum());
        
        // 调用服务层获取数据调用服务层
        IPage<Map<String, Object>> pagelist = shipInboundPlanService.getShipmentReport(dto.getPage(), param);
        return Result.success(pagelist);
    }
    
    
    1. getShipmentDetailReport() - 获取SKU明细报表
    @PostMapping(value = "/getShipmentDetailReport")
    public Result<IPage<Map<String, Object>>> getShipmentDetailReport(@RequestBody ShipInboundShipmenSummaryDTO dto, HttpServletResponse response) {
      Map<String, Object> param = new HashMap<String, Object>();
      UserInfo user = UserInfoContext.get();
      String shopid = user.getCompanyid();
      param.put("shopid", shopid);
      
      String marketplaceid = dto.getMarketplaceid();
      if (StrUtil.isEmpty(marketplaceid)) {
        marketplaceid = null;
      }
      param.put("marketplaceid", marketplaceid);
      
      String groupid = dto.getGroupid();
      if (StrUtil.isEmpty(groupid)) {
        groupid = null;
      }
      param.put("groupid", groupid);
      
      String search = dto.getSearch();
      if (StrUtil.isNotEmpty(search)) {
        param.put("search", search.trim() + "%");
      } else {
        param.put("search", null);
      }
      
      String datetype = dto.getDatetype();
      param.put("datetype", datetype);
      
      String fromDate = dto.getFromdate();
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
      if (StrUtil.isNotEmpty(fromDate)) {
        param.put("fromDate", fromDate.trim());
      } else {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, -7);
        fromDate = GeneralUtil.formatDate(cal.getTime(), sdf);
        param.put("fromDate", fromDate);
      }
      
      String toDate = dto.getEnddate();
      if (StrUtil.isNotEmpty(toDate)) {
        param.put("endDate", toDate.trim().substring(0, 10) + " 23:59:59");
      } else {
        toDate = GeneralUtil.formatDate(new Date(), sdf);
        param.put("endDate", toDate + " 23:59:59");
      }
      
      String warehouseid = dto.getWarehouseid();
      if (StrUtil.isEmpty(warehouseid) || "all".equals(warehouseid)) {
        warehouseid = null;
      }
      param.put("warehouseid", warehouseid);
      
      String company = dto.getCompany();
      if (StrUtil.isEmpty(company)) {
        param.put("company", null);
      } else {
        param.put("company", company + "%");
      }
      
      String iserror = dto.getHasexceptionnum();
      if (StrUtil.isEmpty(iserror) || "all".equals(iserror)) {
        iserror = null;
      }
      param.put("iserror", iserror);
      
      IPage<Map<String, Object>> pagelist = shipInboundPlanService.getShipmentDetailReport(dto.getPage(), param);
      return Result.success(pagelist);
    }
    
    1. downShipmentExcel() - 导出货件报表
    @PostMapping(value = "/downShipmentExcel")
    public void downShipmentExcelAction(@RequestBody ShipInboundShipmenSummaryDTO dto, HttpServletResponse response) {
        try {
            // 创建新的Excel工作薄创建Excel工作簿
            SXSSFWorkbook workbook = new SXSSFWorkbook();
            response.setContentType("application/force-download");
            response.addHeader("Content-Disposition", "attachment;fileName=Shipmenttemplate.xlsx");
            ServletOutputStream fOut = response.getOutputStream();
            
            // 参数处理
            UserInfo user = UserInfoContext.get();
        String shopid = user.getCompanyid();
        
        // 构建查询参数
            Map<String, Object> params = new HashMap<String, Object>();
            Stringparams.put("shopid", marketplaceid = dto.getMarketplaceid(user.getCompanyid();
        String datetype = dto.getDatetype();
            params.put("datetype", datetype)dto.getDatetype());
        
        if (StrUtil.isEmpty(marketplaceid)) {
          marketplaceid = null;
        }
            params.put("marketplaceid", marketplaceid);
        
        String groupid = dto.getGroupid(getMarketplaceid());
        if (StrUtil.isEmpty(groupid)) {
          groupid = null;
        }
            params.put("groupid", groupid);
        
        String search = dto.getSearch(getGroupid());
        if (StrUtil.isNotEmpty(search)) {
            params.put("search", search.trim() + "%");
        } else {
          params.put("search", null);
        }
        
        String fromDate = dto.getFromdate();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (StrUtil.isNotEmpty(fromDate)) {
          params.put("fromDate", fromDate.trim(getSearch());
        } else {
          Calendar cal = Calendar.getInstance();
          cal.add(Calendar.DAY_OF_MONTH, -7);
          fromDate = GeneralUtil.formatDate(cal.getTime(), sdf);
            params.put("fromDate", fromDate);
        }
        
        String toDate = dto.getEnddate(getFromdate();
        if (StrUtil.isNotEmpty(toDate)) {
          params.put("endDate", toDate.trim().substring(0, 10) + " 23:59:59");
        } else {
          toDate = GeneralUtil.formatDate(new Date(), sdf);
            params.put("endDate", toDate + " 23:59:59"dto.getEnddate();
        }
        
        params.put("shopid", shopid));
            params.put("ftype", dto.getDownloadType());
            
            // 调用服务层生成Excel
            shipInboundPlanService.setExcelBookByType(workbook, params);
            
            // 输出Excel
            workbook.write(fOut);
            workbook.close();
            fOut.flush();
            fOut.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    3.2 服务层

    3.2.1 ShipInboundPlanServiceImpl服务接口定义

    文件路径wimoor-amazon/amazon-boot/src/main/java/com/wimoor/amazon/inbound/service/impl/ShipInboundPlanServiceImpl.java

    主要功能:实现发货报表的业务逻辑

    核心方法

    1. getShipmentReport() - 获取货件汇总数据
    public interface IShipInboundPlanService extends IService<ShipInboundPlan>, IRunAmazonService {
        // 其他方法...
        
        /**
         * 获取货件详情报表
         */
        IPage<Map<String, Object>> getShipmentDetailReport(Page<Object> page, Map<String, Object> param);
        
        /**
         * 获取货件报表
         */
        IPage<Map<String, Object>> getShipmentReport(Page<Object> page, Map<String, Object> param);
        
        /**
         * 按类型设置Excel工作簿
         */
        void setExcelBookByType(SXSSFWorkbook workbook, Map<String, Object> params);
    }
    

    3.2.2 服务实现

    @Override
    public IPage<Map<String, Object>> getShipmentReport(Page<?Object> page, Map<String, Object> param) {
        return this.baseMapper.getShipmentReport(page, param);
    }
    
    
    @Override
    1. getShipmentDetailReport() - 获取SKU明细数据
    public IPage<Map<String, Object>> getShipmentDetailReport(Page<Object> page, Map<String, Object> param) {
        IPage<Map<String, Object>> result =return this.baseMapper.getShipmentDetailReport(page, param);
    if (result != null && result.getRecords().size() > 0 && page.getCurrent() == 1) {
        Map<String, Object> summary = this.baseMapper.getShipmentDetailReportTotal(param);
        Map<String, Object> map = result.getRecords().get(0);
        map.put("summary", summary);
      }
    
    return@Override
    result;
    }
    
    1. setExcelBookByType() - 生成Excel文件
    public void setExcelBookByType(SXSSFWorkbook workbook, Map<String, Object> params) {
        String type = params.get("ftype").toString();
        // 货件发货明细
      if ("shipment".equals(type)) {
            // 货件汇总导出
            Map<String, Object> titlemap = new LinkedHashMap<String, Object>();
            titlemap.put("ShipmentId", "货件编码");
            titlemap.put("groupname", "发货店铺");
            titlemap.put("market", "收货站点");
        titlemap.put("center", "配送中心");
        titlemap.put("warehouse"warehousename", "发货仓库");
            titlemap.put("createdate",// "创建日期");
        titlemap.put("shiped_date", "发货日期");
        titlemap.put("arrivalTime", "预计到货日期");
        titlemap.put("start_receive_date", "开始接受日期");
        titlemap.put("status6date", "完成日期");
        titlemap.put("company", "承运商");
        titlemap.put("transtype", "运输方式");
        titlemap.put("channame", "发货渠道");
        titlemap.put("qtyshipped", "发货数量");
        titlemap.put("qtyreceived", "到货数量");
        titlemap.put("price", "运输费用");
        titlemap.put("otherfee", "其它费用");
        titlemap.put("totalprice", "物流费用统计");
        titlemap.put("transweight", "实际计费重量");
        titlemap.put("weightkg", "预估发货重量");
        titlemap.put("boxweight", "装箱实际重量(kg)");
        titlemap.put("boxvolume", "装箱材积重量");
        titlemap.put("wunit", "重量单位");
        titlemap.put("shipmentstatus", "状态");更多列定义...
            
            List<Map<String, Object>> list = this.baseMapper.getShipmentReport(params);
            Sheet sheet = workbook.createSheet("sheet1");
            // 创建标题行写入表头和数据
        Row} trowelse = sheet.createRow(0);
        Object[] titlearray = titlemap.keySet().toArray();
        forif (int i = 0; i < titlearray.length; i++"sku".equals(type)) {
            Cell// cell = trow.createCell(i);
          Object value = titlemap.get(titlearray[i].toString());
          cell.setCellValue(value.toString());
        }SKU汇总导出
            // 填充数据行
        for (int i = 0; i < list.size(); i++) {
          Row row = sheet.createRow(i + 1);
          Map<String, Object> map = list.get(i);
          for (int j = 0; j < titlearray.length; j++) {
            Cell cell = row.createCell(j);
            Object value = map.get(titlearray[j]类似实现..toString());
            if (value != null) {
              cell.setCellValue(value.toString());.
        }
          }
        }
      }
      // 其他类型的导出...
    }
    

    3.3 数据访问层

    3.3.1 ShipInboundPlanMapperMapper接口

    文件路径wimoor-amazon/amazon-boot/src/main/java/com/wimoor/amazon/inbound/mapper/ShipInboundPlanMapper.java

    核心方法

    public interface ShipInboundPlanV2Mapper extends BaseMapper<ShipInboundPlan> {
        // 获取货件汇总报表(分页)其他方法...
        
        /**
         * 获取货件报表
         */
        IPage<Map<String, Object>> getShipmentReport(Page<?Object> page, @Param("param") Map<String, Object> param);
        
        /**
         * 获取货件详情报表
         */
        获取货件汇总报表(全部)IPage<Map<String, Object>> getShipmentDetailReport(Page<Object> page, @Param("param") Map<String, Object> param);
        
        /**
         * 获取货件报表(导出用)
         */
        List<Map<String, Object>> getShipmentReport(@Param("param") Map<String, Object> param);
        
        /**
         * 获取货件详情报表(导出用)
         */ 获取SKU明细报表(分页)
    IPage<Map<String, Object>> getShipmentDetailReport(Page<?> page, @Param("param")Map<String, Object> param);
    
    // 获取SKU明细报表(全部)
        List<Map<String, Object>> getShipmentDetailReport(@Param("param") Map<String, Object> param);
    // 获取SKU明细报表统计
    Map<String, Object> getShipmentDetailReportTotal(Map<String, Object> param);}
    

    3.3.2 ShipInboundPlanMapper.xmlSQL实现

    文件路径getShipmentReport(货件汇总)

    wimoor-amazon/amazon-boot/src/main/resources/mapper/inbound/ShipInboundPlanMapper.xml<select id="getShipmentReport" parameterType="java.util.Map" resultType="java.util.Map">
        SELECT
            s.ShipmentId,
            ag.name AS groupname,
            wh.name AS warehousename,
            s.createdate,
            s.senddate,
            s.receivedate,
            s.completedate,
            s.destination,
            s.marketplace,
            s.warehouseid,
            s.estimateddeliverydate,
            s.carrierName,
            s.shippingchannel,
            SUM(i.receivedqty) AS receivedqty,
            SUM(i.quantity) AS sendqty,
            SUM(s.fee) AS feecount,
            s.weight,
            s.weightfee,
            s.otherfee,
            s.actualweight,
            s.estimateweight,
            s.boxactualweight,
            s.boxvolumeweight
        FROM
            t_erp_ship_v2_inboundplan s
        LEFT JOIN
            t_amazon_group ag ON ag.id = s.groupid
        LEFT JOIN
            t_erp_warehouse wh ON wh.id = s.warehouseid
        LEFT JOIN
            t_erp_ship_v2_inbounditem i ON i.formid = s.id
        WHERE
            s.shopid = #{param.shopid}
            <if test="param.marketplaceid != null">
                AND s.marketplaceid = #{param.marketplaceid}
            </if>
            <if test="param.groupid != null">
                AND s.groupid = #{param.groupid}
            </if>
            <if test="param.search != null">
                AND s.ShipmentId LIKE #{param.search}
            </if>
            <!-- 更多条件... -->
        GROUP BY
            s.ShipmentId
        ORDER BY
            s.createdate DESC
    </select>
    

    核心SQL查询getShipmentDetailReport(SKU汇总)

    1. getShipmentDetailReport - 获取SKU明细报表
    <select id="getShipmentDetailReport" parameterType="java.util.Map" resultType="java.util.Map">
        selectSELECT
            item.SellerSKU i.sku,
            ship.s.ShipmentId,
            inp.s.number,
            g.ag.name AS groupname,
            w.s.destination,
            s.warehouseid,
            wh.name warehouse,AS mkp.market,warehousename,
            ship.shiped_date,s.senddate,
            trans.arrivalTime,s.receivedate,
            item.QuantityShipped,s.shippingchannel,
            item.QuantityReceived,s.estimateddeliverydate,
            inp.createdate,i.quantity ship.DestinationFulfillmentCenterIdAS center,sendqty,
            detail.channame,i.receivedqty,
            case when stat.`status`='WORKING' and ship.status>=5 then '已删除' else stat.name end shipmentstatus,
             ifnull(item.QuantityReceived,0) sumrec, ship.s.status,
            status0date,s.createdate
        status1date,FROM
            status2date,t_erp_ship_v2_inboundplan status3date,s
        status4date,LEFT status5date,JOIN
            status6datet_amazon_group fromag t_erp_ship_inbounditemON item
      left join t_erp_ship_inboundshipment ship on ship.ShipmentId = item.ShipmentId
      left join t_erp_ship_inboundtrans trans on trans.shipmentid = ship.ShipmentId
      left join t_erp_ship_transdetail detail on detail.ag.id = trans.channels.groupid
        leftLEFT joinJOIN
            t_erp_ship_transcompanyt_erp_warehouse copwh onON cop.wh.id = detail.companys.warehouseid
        leftLEFT joinJOIN
            t_erp_ship_statust_erp_ship_v2_inbounditem stati onON stat.`status`i.formid = ship.ShipmentStatus
      left join t_erp_ship_inboundplan inp on inp.s.id
        =WHERE
            item.inboundplanid
      left join t_marketplace mkp on mkp.marketplaceId = inp.marketplaceid
      left join t_amazon_group g on g.id = inp.amazongroupid
      left join t_erp_warehouse w on w.id = inp.warehouseid
      where inp.s.shopid = #{param.shopid,jdbcType=CHAR}
        and ship.status > 1shopid}
            <if test="param.endDatemarketplaceid != null">
                <ifAND test="param.datetypes.marketplaceid == 'createdate'">
          and inp.createdate &gt;= #{param.fromDate,jdbcType=TIMESTAMP}
          and inp.createdate &lt;= #{param.endDate,jdbcType=TIMESTAMP}
        </if>
        <if test="param.datetype == 'deliverydate'">
          and ship.shiped_date &gt;= #{param.fromDate,jdbcType=TIMESTAMP}
          and ship.shiped_date &lt;= #{param.endDate,jdbcType=TIMESTAMP}
        </if>marketplaceid}
            </if>
            <if test="param.groupid != null">
                andAND inp.amazongroupids.groupid = #{param.groupid,jdbcType=CHAR}
      </if>
      <if test="param.marketplaceid != null">
        and inp.marketplaceid = #{param.marketplaceid,jdbcType=CHAR}groupid}
            </if>
            <if test="param.search != null">
                andAND (item.SellerSKUs.ShipmentId likeLIKE #{param.search,jdbcType=CHAR}search} orOR ship.ShipmentIdi.sku likeLIKE #{param.search,jdbcType=CHAR} 
             or inp.number like #{param.search,jdbcType=CHAR}search})
            </if>
            <if!-- test="param.company更多条件... != null"-->
        andORDER cop.nameBY
            like #{param.company,jdbcType=CHAR}
      </if>
      <if test="param.warehouseid != null">
        and w.id = #{param.warehouseid,jdbcType=CHAR}
      </if>
      <if test="param.iserror != null">
        <if test="param.iserror == 'true'">
          and item.QuantityReceived != item.QuantityShipped
        </if>
        <if test="param.iserror == 'false'">
          and item.QuantityReceived = item.QuantityShipped
        </if>
      </if>
    </select>
    
    1. getShipmentReport - 获取货件汇总报表
    <select id="getShipmentReport" parameterType="java.util.Map" resultType="java.util.Map">
      select ship.ShipmentId,
             max(g.name) groupname,
             max(mkp.market) market,
             max(ship.DestinationFulfillmentCenterId) center,
             max(w.name) warehouse,
             max(inp.createdate) createdate,
             max(ship.shiped_date) shiped_date,
             max(trans.arrivalTime) arrivalTime,
             max(status6date) status6date,
             max(company.name) company,
             max(detail.channame) channame,
             count(item.SellerSKU) skunum,
             max(inp.number) number,
             sum(item.QuantityShipped) qtyshipped,
             sum(item.QuantityReceived) qtyreceived,
             max(trans.otherfee) otherfee,
             max(trans.singleprice * trans.transweight) price,
             max(trans.transweight) transweight,
             max(ship.weightkg) weightkg,
             max(ship.boxweight) boxweight,
             max(ship.boxvolume) boxvolume,
             max(ship.wunit) wunit,
             max(stat.name) shipmentstatus,
             max(trans.transtype) transtype,
             max(ship.start_receive_date) start_receive_date
      from t_erp_ship_inbounditem item
      left join t_erp_ship_inboundshipment ship on ship.ShipmentId = item.ShipmentId
      left join t_erp_ship_inboundtrans trans on trans.shipmentid = ship.ShipmentId
      left join t_erp_ship_transdetail detail on detail.id = trans.channel
      left join t_erp_ship_transcompany company on company.id = detail.company
      left join t_erp_ship_status stat on stat.`status` = ship.ShipmentStatus
      left join t_erp_ship_inboundplan inp on inp.id = item.inboundplanid
      left join t_marketplace mkp on mkp.marketplaceId = inp.marketplaceid
      left join t_amazon_group g on g.id = inp.amazongroupid
      left join t_erp_warehouse w on w.id = inp.warehouseid
      where inp.shopid = #{param.shopid,jdbcType=CHAR}
        and ship.status > 1
      <if test="param.endDate != null">
        <if test="param.datetype == 'createdate'">
          and inp.s.createdate &gt;= #{param.fromDate,jdbcType=TIMESTAMP}
          and inp.createdate &lt;= #{param.endDate,jdbcType=TIMESTAMP}
        </if>
        <if test="param.datetype == 'deliverydate'">
          and ship.shiped_date &gt;= #{param.fromDate,jdbcType=TIMESTAMP}
          and ship.shiped_date &lt;= #{param.endDate,jdbcType=TIMESTAMP}
        </if>
      </if>
      <if test="param.groupid != null">
        and inp.amazongroupid = #{param.groupid,jdbcType=CHAR}
      </if>
      <if test="param.marketplaceid != null">
        and inp.marketplaceid = #{param.marketplaceid,jdbcType=CHAR}
      </if>
      <if test="param.search != null">
        and (ship.ShipmentId like #{param.search,jdbcType=CHAR} 
             or inp.number like #{param.search,jdbcType=CHAR})
      </if>
      <if test="param.company != null">
        and company.name like #{param.company,jdbcType=CHAR}
      </if>
      <if test="param.companyid != null">
        and company.id = #{param.companyid,jdbcType=CHAR}
      </if>
      <if test="param.warehouseid != null">
        and w.id = #{param.warehouseid,jdbcType=CHAR}
      </if>
      <if test="param.iserror != null">
        <if test="param.iserror == 'true'">
          and sum(item.QuantityReceived) != sum(item.QuantityShipped)
        </if>
        <if test="param.iserror == 'false'">
          and sum(item.QuantityReceived) = sum(item.QuantityShipped)
        </if>
      </if>
      group by ship.ShipmentIdDESC
    </select>
    

    4. 数据库设计功能特性

    4.1 核心表结构双视图模式

    • 货件汇总视图:以货件为单位,展示货件的整体情况
    • SKU汇总视图:以SKU为单位,展示每个SKU的发货和到货情况

    4.1.12 t_erp_ship_inboundshipment(货件表)

    多维度筛选
    字段名类型筛选条件 说明数据类型
    ShipmentId店铺 varchar选择特定店铺 货件ID(主键)下拉选择
    inboundplanid日期类型 varchar创建日期/发货日期 发货计划ID下拉选择
    DestinationFulfillmentCenterId日期范围 varchar选择开始和结束日期 目标配送中心ID日期选择器
    ShipmentStatus仓库 varchar选择特定仓库 货件状态下拉选择
    shiped_date货件编码 datetime搜索特定货件 发货日期文本输入
    status6date接收异常 datetime筛选有/无接收异常的货件 完成日期下拉选择
    weightkg承运商 decimal选择特定承运商 预估发货重量
    boxweightdecimal装箱实际重量
    boxvolumedecimal装箱材积重量
    wunitvarchar重量单位
    statusint状态码
    start_receive_datedatetime开始接收日期下拉选择

    4.1.23 t_erp_ship_inbounditem(货件明细表)

    数据导出
    字段名类型导出类型 说明适用场景
    id普通导出 varchar完整的货件或SKU数据 主键ID全面分析
    ShipmentId含子SKU varchar包含子SKU的详细数据 货件ID变体产品分析
    inboundplanid发货数量简约版 varchar只包含发货数量的简化数据 发货计划ID快速统计
    SellerSKU发货处理任务量 varchar发货处理任务量统计 产品SKU
    QuantityShippedint发货数量
    QuantityReceivedint接收数量任务分配

    4.1.3 t_erp_ship_inboundtrans(货件运输表)

    字段名类型说明
    shipmentidvarchar货件ID
    channelvarchar渠道ID
    arrivalTimedatetime预计到货时间
    otherfeedecimal其它费用
    singlepricedecimal单价
    transweightdecimal运输重量
    transtypevarchar运输方式

    4.1.4 t_erp_ship_transdetail(运输详情表)

    数据统计
  3. SKU汇总视图:自动计算总发货数量和总接收数量
  4. 货件汇总视图:自动汇总物流费用、运输重量等
  5. 字段名类型说明
    idvarchar主键ID
    companyvarchar承运商ID
    channamevarchar渠道名称

    4.1.5 t_erp_ship_transcompany(承运商表)

    字段名类型说明
    idvarchar承运商ID(主键)
    namevarchar承运商名称

    4.1.6 t_erp_ship_inboundplan(发货计划表)

    字段名类型说明
    idvarchar发货计划ID(主键)
    numbervarchar内部编号
    amazongroupidvarchar店铺ID
    marketplaceidvarchar市场ID
    warehouseidvarchar仓库ID
    createdatedatetime创建日期

    4.1.7 t_amazon_group(店铺表)

    字段名类型说明
    idvarchar店铺ID(主键)
    namevarchar店铺名称

    4.1.8 t_marketplace(市场表)

    字段名类型说明
    marketplaceIdvarchar市场ID(主键)
    marketvarchar市场名称

    4.1.9 t_erp_warehouse(仓库表)

    字段名类型说明
    idvarchar仓库ID(主键)
    namevarchar仓库名称

    4.1.10 t_erp_ship_status(货件状态表)

    字段名类型说明
    statusvarchar状态码(主键)
    namevarchar状态名称

    5. 业务流程技术亮点

    5.1 数据查询流程前端技术亮点

    sequenceDiagram
      participant
    1. Vue User3 asComposition 用户API:使用reactive和ref进行状态管理,代码结构更清晰
    2. participant
    3. Element FrontendPlus组件:使用el-tabs、el-select、el-table等组件,界面美观且功能丰富
    4. as
    5. 响应式设计:适配不同屏幕尺寸,操作流畅
    6. 前端
    7. 异步数据加载:使用Axios进行异步请求,配合loading状态提升用户体验
    8. participant
    9. 条件渲染:根据不同视图类型和筛选条件动态渲染UI
    10. Controller as 控制器 participant Service as 服务层 participant Mapper as 数据访问层 participant DB as 数据库 User->>Frontend: 选择筛选条件 Frontend->>Frontend: 构建查询参数 Frontend->>Controller: POST /api/v1/ship/report/getShipmentReport Controller->>Controller: 处理查询参数 Controller->>Service: getShipmentReport(page, param) Service->>Mapper: getShipmentReport(page, param) Mapper->>DB: 执行SQL查询 DB->>Mapper: 返回查询结果 Mapper->>Service: 返回分页数据 Service->>Controller: 返回分页数据 Controller->>Frontend: 返回JSON响应 Frontend->>User: 显示数据表格

    5.2 数据导出流程后端技术亮点

    sequenceDiagram
      participant
    1. RESTful UserAPI设计:使用POST请求传递复杂参数,接口设计规范
    2. as
    3. SXSSFWorkbook:使用SXSSFWorkbook处理大数据量Excel导出,避免内存溢出
    4. 用户
    5. 参数校验:对输入参数进行非空检查和格式转换
    6. participant
    7. 多表关联查询:使用SQL多表关联查询,提高数据查询效率
    8. Frontend
    9. 动态SQL:使用MyBatis asPlus的动态SQL,根据条件构建不同的查询语句
    10. 前端
    participant

    5.3 Controller性能优化

    as
      控制器
    1. 分页查询:使用MyBatis participantPlus的分页功能,避免一次性加载过多数据
    2. Service
    3. 索引优化:数据库表建立适当索引,提高查询速度
    4. as
    5. 缓存机制:使用Spring 服务层Cache缓存常用数据
    6. participant
    7. 批量操作:批量处理数据,减少数据库交互次数
    8. Mapper
    9. 异步处理:Excel导出等耗时操作使用异步处理
    10. as 数据访问层 participant DB as 数据库 participant Excel as Excel生成器 User->>Frontend: 点击导出按钮 Frontend->>Frontend: 构建导出参数 Frontend->>Controller: POST /api/v1/ship/report/downShipmentExcel Controller->>Controller: 处理导出参数 Controller->>Service: setExcelBookByType(workbook, params) Service->>Mapper: getShipmentReport(params) Mapper->>DB: 执行SQL查询 DB->>Mapper: 返回查询结果 Mapper->>Service: 返回数据列表 Service->>Excel: 创建Excel工作簿 Excel->>Excel: 写入标题行 Excel->>Excel: 写入数据行 Excel->>Controller: 返回Excel文件 Controller->>Frontend: 返回文件流 Frontend->>User: 下载Excel文件

    6. API接口文档代码优化建议

    6.1 获取货件汇总报表前端优化建议

    1. 接口地址代码模块化POST将筛选条件、表格渲染等功能拆分为独立组件
    2. /api/v1/ship/report/getShipmentReport

    3. 请求参数状态管理

      考虑使用Pinia或Vuex进行更复杂的状态管理
    4. {
        "currentpage": 1,
        "pagesize": 20,
        "groupid": "店铺ID",
        "marketplaceid": "市场ID",
        "search": "货件编码",
        "datetype": "createdate",
        "fromdate": "2026-01-01",
        "enddate": "2026-01-31",
        "warehouseid": "仓库ID",
        "company": "承运商名称",
        "companyid": "承运商ID",
        "hasexceptionnum": "all"
      }
      

    5. 响应参数防抖处理

      对搜索输入添加防抖处理,减少频繁请求
    6. {
    7. 虚拟滚动:对大数据量表格使用虚拟滚动,提高渲染性能
    8. "code":
    9. 错误处理:添加更完善的错误处理和用户提示
    10. 200, "msg": "success", "data": { "records": [ { "ShipmentId": "FBA123456789", "groupname": "美国店铺", "market": "US", "center": "SBD1", "warehouse": "深圳仓库", "createdate": "2026-01-01 10:00:00", "shiped_date": "2026-01-05 15:00:00", "arrivalTime": "2026-01-15 00:00:00", "start_receive_date": "2026-01-14 10:00:00", "status6date": "2026-01-20 16:00:00", "company": "DHL", "channame": "空运", "qtyshipped": 1000, "qtyreceived": 998, "price": 500.00, "otherfee": 50.00, "totalprice": 550.00, "transweight": 500.5, "weightkg": 502.0, "boxweight": 501.0, "boxvolume": 503.0, "wunit": "kg", "shipmentstatus": "已接收", "transtype": "AIR" } ], "total": 100, "size": 20, "current": 1, "pages": 5 } }

    6.2 获取SKU明细报表后端优化建议

    1. 接口地址参数验证POST使用Spring /api/v1/ship/report/getShipmentDetailReport

      Validation对请求参数进行更严格的验证
    2. 请求参数异常处理

      统一异常处理,返回更友好的错误信息
    3. {
        "currentpage": 1,
        "pagesize": 20,
        "groupid": "店铺ID",
        "marketplaceid": "市场ID",
        "search": "SKU或货件编码",
        "datetype": "createdate",
        "fromdate": "2026-01-01",
        "enddate": "2026-01-31",
        "warehouseid": "仓库ID",
        "company": "承运商名称",
        "hasexceptionnum": "all"
      }
      

    4. 响应参数日志记录

      添加更详细的日志记录,便于问题排查
    5. {
    6. 性能监控:集成Spring "code":Boot 200,Actuator进行性能监控
    7. "msg":
    8. SQL优化:进一步优化SQL查询,减少表关联次数
    9. "success", "data": { "records": [ { "sku": "SKU001", "ShipmentId": "FBA123456789", "number": "SF20260101001", "groupname": "美国店铺", "warehouse": "深圳仓库", "market": "US", "shiped_date": "2026-01-05 15:00:00", "arrivalTime": "2026-01-15 00:00:00", "QuantityShipped": 100, "QuantityReceived": 98, "createdate": "2026-01-01 10:00:00", "center": "SBD1", "channame": "空运", "shipmentstatus": "已接收", "summary": { "QuantityShipped": 1000, "QuantityReceived": 998 } } ], "total": 500, "size": 20, "current": 1, "pages": 25 } }

    6.3 导出货件报表架构优化建议

    1. 接口地址微服务拆分POST /api/v1/ship/report/downShipmentExcel

      请求参数

      {
        "groupid": "店铺ID",
        "marketplaceid": "市场ID",
        "search": "货件编码",
        "datetype": "createdate",
        "fromdate": "2026-01-01",
        "enddate": "2026-01-31",
        "warehouseid": "仓库ID",
        "company": "承运商名称",
        "downloadType": "shipment"
      }
      

      响应:Excel文件流

      downloadType参数说明

      • shipment:货件汇总报表考虑将报表功能拆分为独立的微服务
      • other缓存策略含子SKU的SKU明细报表使用Redis缓存热点数据,提高响应速度
      • shipqty消息队列发货数量简约版使用消息队列处理异步任务,提高系统可靠性
      • shiptaskAPI网关发货处理任务量使用API网关统一管理API接口
    2. 容器化部署:使用Docker容器化部署,提高部署效率

    7. 性能优化业务价值

    7.1 数据库优化运营价值

    1. 索引优化数据可视化

      • t_erp_ship_inboundshipment表的ShipmentId字段上建立索引通过报表直观展示发货数据,便于运营分析
      • t_erp_ship_inbounditem表的ShipmentIdSellerSKU字段上建立复合索引异常监控:及时发现和处理接收异常,减少损失
      • t_erp_ship_inboundplan表的shopidamazongroupidmarketplaceid字段上建立索引
      趋势分析:分析发货趋势,优化库存管理
    2. 查询优化成本控制

      • 使用LEFT JOIN避免数据丢失
      • 使用MAX、SUM等聚合函数减少数据传输量
      • 使用分页查询避免一次性加载大量数据
      监控物流费用,优化物流方案

    7.2 前端优化管理价值

    1. 延迟加载决策支持

      • 使用setTimeout延迟查询请求,避免频繁调用基于数据做出更合理的发货决策
      • 使用nextTick确保DOM更新后再执行操作
      流程优化:发现发货流程中的瓶颈,优化流程
    2. 分页加载绩效考核

      • 使用分页组件减少单次加载的数据量基于发货数据进行绩效考核
      • 支持自定义每页显示条数
    3. 缓存优化风险控制

      • 缓存筛选条件,避免重复查询
      • 使用computed属性优化计算性能
      及时发现和应对发货风险

    7.3 后端优化技术价值

    1. 异步处理可扩展性

      • 使用SXSSFWorkbook流式处理大数据量导出模块化设计,便于后续功能扩展
      • 使用异步任务处理耗时操作
      可维护性:代码结构清晰,易于维护
    2. 参数验证可复用性

      • 使用StrUtil工具类进行空值判断封装通用功能,提高代码复用率
      • 设置合理的默认值
      • 技术栈更新:使用Vue
      3、Spring Boot等最新技术,保持技术先进性

    8. 扩展功能总结

    8.1

    发货详情报表模块(ShipV2)是一个功能完善、技术先进的FBA发货数据分析工具,通过前端Vue 自定义列显示

    3和后端Spring Boot的完美结合,实现了货件和SKU两个维度的数据分析和管理。该模块不仅提供了丰富的筛选和导出功能,还通过多表关联查询和数据统计,为用户提供了全面、准确的发货数据,帮助用户更好地管理FBA发货流程,优化物流方案,降低运营成本。

    用户可以根据需要自定义表格显示的列,提高数据查看的灵活性。未来,该模块可以进一步扩展,例如添加更多的数据分析维度、集成更多的物流商数据、提供更丰富的图表展示等,以满足用户日益增长的需求。

    8.2 多格式导出

    支持多种导出格式,满足不同的业务需求:

    • 普通导出:包含所有字段的完整数据
    • 含子SKU:包含子SKU信息的详细版本
    • 发货数量简约版:只包含发货数量相关信息的简化版本
    • 发货处理任务量:包含发货处理任务量的统计数据

    8.3 数据统计

    在按SKU汇总视图下,自动汇总总发货数量和总接收数量,方便用户快速了解整体情况。

    9. 注意事项

    9.1 数据同步

    • 货件数据通过亚马逊API同步,可能存在延迟
    • 建议定期刷新数据以获取最新信息

    9.2 权限控制

    • 用户只能查看自己公司的数据
    • 店铺和市场权限通过用户信息自动过滤

    9.3 性能考虑

    • 避免选择过大的日期范围
    • 使用精确的筛选条件减少数据量
    • 大数据量导出可能需要较长时间

    9.4 异常处理

    • 接收异常的货件需要特别关注
    • 建议定期检查并处理接收异常

    10. 故障排查

    10.1 数据不显示

    可能原因

    • 筛选条件设置不正确
    • 数据同步延迟
    • 权限不足

    解决方法

    • 检查筛选条件
    • 刷新页面
    • 联系管理员检查权限

    10.2 导出失败

    可能原因

    • 数据量过大
    • 网络问题
    • 服务器异常

    解决方法

    • 缩小日期范围
    • 检查网络连接
    • 联系技术支持

    10.3 性能问题

    可能原因

    • 数据量过大
    • 查询条件不优化
    • 数据库索引缺失

    解决方法

    • 使用分页查询
    • 优化筛选条件
    • 添加数据库索引

    文档版本:v1.0
    最后更新:2026-01-26
    适用系统:Wimoor FBA发货管理系统