|
|
@@ -2031,16 +2031,19 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
|
|
|
|
|
String[] headers = {
|
|
|
"序号", "订单编号", "下单时间", "付款时间", "订单状态", "订单类型",
|
|
|
- "商品名称", "规格", "单价(元)", "数量", "小计(元)",
|
|
|
+ "商品名称", "海博商品ID", "商品编码", "规格", "单价(元)", "数量", "小计(元)",
|
|
|
"商品总数量", "商品总额(元)", "运费(元)", "积分抵扣(元)",
|
|
|
"实付金额", "所属企业", "买家姓名", "买家电话"
|
|
|
};
|
|
|
// 创建合并单元格的表头
|
|
|
- ExportUtils.createMergedHeader(sheet, headerStyle, "正常订单",18);
|
|
|
+ ExportUtils.createMergedHeader(sheet, headerStyle, "正常订单",20);
|
|
|
|
|
|
// 创建列标题行
|
|
|
ExportUtils.createColumnHeaders(sheet, headerStyle, headers);
|
|
|
|
|
|
+ // 计算并创建总计行
|
|
|
+ createSummaryRow(sheet, orderList, dataStyle, numberStyle);
|
|
|
+
|
|
|
// 填充数据
|
|
|
fillOrderData(sheet, orderList, dataStyle, numberStyle, dateStyle, context);
|
|
|
// 写入文件
|
|
|
@@ -2087,18 +2090,81 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
|
|
sheet.setColumnWidth(4, 10 * 256); // 订单状态
|
|
|
sheet.setColumnWidth(5, 8 * 256); // 订单类型
|
|
|
sheet.setColumnWidth(6, 25 * 256); // 商品名称
|
|
|
- sheet.setColumnWidth(7, 20 * 256); // 规格
|
|
|
- sheet.setColumnWidth(8, 10 * 256); // 单价
|
|
|
- sheet.setColumnWidth(9, 8 * 256); // 数量
|
|
|
- sheet.setColumnWidth(10, 10 * 256); // 小计
|
|
|
- sheet.setColumnWidth(11, 12 * 256); // 商品总数量
|
|
|
- sheet.setColumnWidth(12, 12 * 256); // 商品总额
|
|
|
- sheet.setColumnWidth(13, 8 * 256); // 运费
|
|
|
- sheet.setColumnWidth(14, 12 * 256); // 积分抵扣
|
|
|
- sheet.setColumnWidth(15, 10 * 256); // 实付金额
|
|
|
- sheet.setColumnWidth(16, 15 * 256); // 所属企业
|
|
|
- sheet.setColumnWidth(17, 10 * 256); // 买家姓名
|
|
|
- sheet.setColumnWidth(18, 15 * 256); // 买家电话
|
|
|
+ sheet.setColumnWidth(7, 15 * 256); // 海博商品ID
|
|
|
+ sheet.setColumnWidth(8, 15 * 256); // 商品编码
|
|
|
+ sheet.setColumnWidth(9, 20 * 256); // 规格
|
|
|
+ sheet.setColumnWidth(10, 10 * 256); // 单价
|
|
|
+ sheet.setColumnWidth(11, 8 * 256); // 数量
|
|
|
+ sheet.setColumnWidth(12, 10 * 256); // 小计
|
|
|
+ sheet.setColumnWidth(13, 12 * 256); // 商品总数量
|
|
|
+ sheet.setColumnWidth(14, 12 * 256); // 商品总额
|
|
|
+ sheet.setColumnWidth(15, 8 * 256); // 运费
|
|
|
+ sheet.setColumnWidth(16, 12 * 256); // 积分抵扣
|
|
|
+ sheet.setColumnWidth(17, 10 * 256); // 实付金额
|
|
|
+ sheet.setColumnWidth(18, 15 * 256); // 所属企业
|
|
|
+ sheet.setColumnWidth(19, 10 * 256); // 买家姓名
|
|
|
+ sheet.setColumnWidth(20, 15 * 256); // 买家电话
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建总计行
|
|
|
+ */
|
|
|
+ private void createSummaryRow(Sheet sheet, List<Order> orderList, CellStyle dataStyle, CellStyle numberStyle) {
|
|
|
+ // 计算总计值
|
|
|
+ int totalProductCount = 0; // 商品总数量
|
|
|
+ double totalAmount = 0; // 商品总额
|
|
|
+ double totalFreight = 0; // 运费
|
|
|
+ double totalOffsetPoints = 0; // 积分抵扣
|
|
|
+ double totalActualAmount = 0; // 实付金额
|
|
|
+
|
|
|
+ for (Order order : orderList) {
|
|
|
+ for (OrderItem item : order.getOrderItems()) {
|
|
|
+ // 商品总数量(每行的商品数量)
|
|
|
+ totalProductCount += item.getProdCount() != null ? item.getProdCount() : 0;
|
|
|
+
|
|
|
+ // 商品总额(每行的商品总额是订单总额,需要按商品数量比例分摊)
|
|
|
+ if (order.getTotal() != null && order.getProductNums() > 0) {
|
|
|
+ totalAmount += Arith.div(order.getTotal(), order.getProductNums()) * item.getProdCount();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 运费(按商品数量比例分摊)
|
|
|
+ if (order.getFreightAmount() != null && order.getProductNums() > 0) {
|
|
|
+ totalFreight += Arith.div(order.getFreightAmount(), order.getProductNums()) * item.getProdCount();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 积分抵扣(按商品数量比例分摊)
|
|
|
+ if (order.getOffsetPoints() != null && order.getProductNums() > 0) {
|
|
|
+ totalOffsetPoints += Arith.div(Arith.div(Double.valueOf(order.getOffsetPoints()), 100), order.getProductNums()) * item.getProdCount();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 实付金额(按商品数量比例分摊)
|
|
|
+ if (order.getActualTotal() != null && order.getProductNums() > 0) {
|
|
|
+ totalActualAmount += Arith.div(order.getActualTotal(), order.getProductNums()) * item.getProdCount();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建总计行(第3行,索引2)
|
|
|
+ Row summaryRow = sheet.createRow(2);
|
|
|
+ summaryRow.setHeightInPoints(20);
|
|
|
+
|
|
|
+ // 序号列显示"总计"
|
|
|
+ ExportUtils.createCell(sheet, summaryRow, 0, 0, 2, "总计", dataStyle);
|
|
|
+
|
|
|
+ // 商品总数量(索引13)
|
|
|
+ ExportUtils.createCell(sheet, summaryRow, 13, 0, 2, totalProductCount, numberStyle);
|
|
|
+
|
|
|
+ // 商品总额(索引14)
|
|
|
+ ExportUtils.createCell(sheet, summaryRow, 14, 0, 2, totalAmount, numberStyle);
|
|
|
+
|
|
|
+ // 运费(索引15)
|
|
|
+ ExportUtils.createCell(sheet, summaryRow, 15, 0, 2, totalFreight, numberStyle);
|
|
|
+
|
|
|
+ // 积分抵扣(索引16,显示为负数)
|
|
|
+ ExportUtils.createCell(sheet, summaryRow, 16, 0, 2, "-" + totalOffsetPoints, numberStyle);
|
|
|
+
|
|
|
+ // 实付金额(索引17)
|
|
|
+ ExportUtils.createCell(sheet, summaryRow, 17, 0, 2, totalActualAmount, numberStyle);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -2108,7 +2174,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
|
|
CellStyle dataStyle, CellStyle numberStyle, CellStyle dateStyle,ExportContext context) throws InterruptedException{
|
|
|
int batchSize = 100; // 每批处理1000条
|
|
|
int totalRows = orderList.size();
|
|
|
- int rowNum = 2; // 从第3行开始(0-based索引)
|
|
|
+ int rowNum = 3; // 从第4行开始(0-based索引),第3行是总计行
|
|
|
int indexNum = 1; //序号
|
|
|
for (int i = 0; i < totalRows; i += batchSize) {
|
|
|
int end = Math.min(i + batchSize, totalRows);
|
|
|
@@ -2120,13 +2186,16 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
|
|
break;
|
|
|
// throw new InterruptedException("导出被中断");
|
|
|
}
|
|
|
- Row row = sheet.createRow(rowNum++);
|
|
|
- row.setHeightInPoints(18);
|
|
|
- //序号
|
|
|
- ExportUtils.createCell(sheet, row, 0, order.getOrderItems().size(), rowNum, indexNum, dataStyle);
|
|
|
- fillOrderRowData(sheet, rowNum, row, order, dataStyle, numberStyle, dateStyle);
|
|
|
- rowNum += order.getOrderItems().size() - 1;
|
|
|
- indexNum++;
|
|
|
+ // 为每个订单项创建单独的行
|
|
|
+ for (int itemIndex = 0; itemIndex < order.getOrderItems().size(); itemIndex++) {
|
|
|
+ Row row = sheet.createRow(rowNum++);
|
|
|
+ row.setHeightInPoints(18);
|
|
|
+ OrderItem item = order.getOrderItems().get(itemIndex);
|
|
|
+ // 序号(每行独立)
|
|
|
+ ExportUtils.createCell(sheet, row, 0, 0, rowNum, indexNum++, dataStyle);
|
|
|
+ // 填充订单数据和商品数据
|
|
|
+ fillOrderRowDataWithItem(sheet, rowNum, row, order, item, dataStyle, numberStyle, dateStyle);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 定期刷新到磁盘
|
|
|
@@ -2143,80 +2212,74 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 填充单行订单数据
|
|
|
+ * 填充单行订单数据(包含订单信息和单个商品信息,每行独立不合并)
|
|
|
*/
|
|
|
- private void fillOrderRowData (Sheet sheet,int rowNum, Row row, Order order,
|
|
|
- CellStyle dataStyle, CellStyle numberStyle, CellStyle dateStyle){
|
|
|
+ private void fillOrderRowDataWithItem(Sheet sheet, int rowNum, Row row, Order order,
|
|
|
+ OrderItem item, CellStyle dataStyle, CellStyle numberStyle, CellStyle dateStyle) {
|
|
|
|
|
|
// 订单编号
|
|
|
- ExportUtils.createCell(sheet, row, 1, order.getOrderItems().size(), rowNum, order.getOrderNumber(), dataStyle);
|
|
|
+ ExportUtils.createCell(sheet, row, 1, 0, rowNum, order.getOrderNumber(), dataStyle);
|
|
|
|
|
|
// 下单时间
|
|
|
- ExportUtils.createCell(sheet, row, 2, order.getOrderItems().size(), rowNum, ExportUtils.formatDate(order.getCreateTime()), dateStyle);
|
|
|
+ ExportUtils.createCell(sheet, row, 2, 0, rowNum, ExportUtils.formatDate(order.getCreateTime()), dateStyle);
|
|
|
|
|
|
// 付款时间
|
|
|
- ExportUtils.createCell(sheet, row, 3, order.getOrderItems().size(), rowNum, ExportUtils.formatDate(order.getPayTime()), dateStyle);
|
|
|
+ ExportUtils.createCell(sheet, row, 3, 0, rowNum, ExportUtils.formatDate(order.getPayTime()), dateStyle);
|
|
|
|
|
|
// 订单状态
|
|
|
- ExportUtils.createCell(sheet, row, 4, order.getOrderItems().size(), rowNum, getHbOrderStatus(order.getHbOrderStatus()), dataStyle);
|
|
|
+ ExportUtils.createCell(sheet, row, 4, 0, rowNum, getHbOrderStatus(order.getHbOrderStatus()), dataStyle);
|
|
|
|
|
|
// 订单类型
|
|
|
- ExportUtils.createCell(sheet, row, 5, order.getOrderItems().size(), rowNum, getDvyType(order.getDvyType()), dataStyle);
|
|
|
- // 商品明细行(每个订单项一行)
|
|
|
- fillOrderItems(sheet, rowNum, row, order, dataStyle, numberStyle);
|
|
|
+ ExportUtils.createCell(sheet, row, 5, 0, rowNum, getDvyType(order.getDvyType()), dataStyle);
|
|
|
|
|
|
- // 商品总数量
|
|
|
- ExportUtils.createCell(sheet, row, 11, order.getOrderItems().size(), rowNum, order.getProductNums(), dataStyle);
|
|
|
+ // 商品名称
|
|
|
+ ExportUtils.createCell(sheet, row, 6, 0, rowNum, item.getProdName(), dataStyle);
|
|
|
|
|
|
- // 商品总额(元)
|
|
|
- ExportUtils.createCell(sheet, row, 12, order.getOrderItems().size(), rowNum, order.getTotal(), numberStyle);
|
|
|
+ // 海博商品ID
|
|
|
+ ExportUtils.createCell(sheet, row, 7, 0, rowNum, item.getHbSkuId(), dataStyle);
|
|
|
|
|
|
- // 运费(元)
|
|
|
- ExportUtils.createCell(sheet, row, 13, order.getOrderItems().size(), rowNum, order.getFreightAmount(), numberStyle);
|
|
|
+ // 商品编码
|
|
|
+ ExportUtils.createCell(sheet, row, 8, 0, rowNum, item.getSkuCode(), dataStyle);
|
|
|
|
|
|
- // 积分抵扣(元) - 显示为负数
|
|
|
- ExportUtils.createCell(sheet, row, 14, order.getOrderItems().size(), rowNum, "-" + (order.getOffsetPoints() == null ? 0 : Arith.div(Double.valueOf(order.getOffsetPoints()), 100)), numberStyle);
|
|
|
+ // 规格
|
|
|
+ ExportUtils.createCell(sheet, row, 9, 0, rowNum, item.getSpec(), dataStyle);
|
|
|
|
|
|
- // 实付金额
|
|
|
- ExportUtils.createCell(sheet, row, 15, order.getOrderItems().size(), rowNum, order.getActualTotal(), numberStyle);
|
|
|
+ // 单价(元)
|
|
|
+ ExportUtils.createCell(sheet, row, 10, 0, rowNum, item.getPrice(), numberStyle);
|
|
|
|
|
|
- // 所属企业
|
|
|
- ExportUtils.createCell(sheet, row, 16, order.getOrderItems().size(), rowNum, order.getChannelName(), dataStyle);
|
|
|
+ // 数量
|
|
|
+ ExportUtils.createCell(sheet, row, 11, 0, rowNum, item.getProdCount(), dataStyle);
|
|
|
|
|
|
- // 买家姓名
|
|
|
- ExportUtils.createCell(sheet, row, 17, order.getOrderItems().size(), rowNum, order.getReceiver(), dataStyle);
|
|
|
+ // 小计(元)
|
|
|
+ ExportUtils.createCell(sheet, row, 12, 0, rowNum, item.getProductTotalAmount(), numberStyle);
|
|
|
|
|
|
- // 买家电话
|
|
|
- ExportUtils.createCell(sheet, row, 18, order.getOrderItems().size(), rowNum, order.getUserMobile(), dataStyle);
|
|
|
- }
|
|
|
+ // 商品总数量(使用当前商品数量)
|
|
|
+ ExportUtils.createCell(sheet, row, 13, 0, rowNum, item.getProdCount(), dataStyle);
|
|
|
|
|
|
- /**
|
|
|
- * 填充订单项明细
|
|
|
- */
|
|
|
- private void fillOrderItems (Sheet sheet,int rowNum, Row row, Order order,
|
|
|
- CellStyle dataStyle, CellStyle numberStyle){
|
|
|
- int itemSize = order.getOrderItems().size();
|
|
|
-
|
|
|
- for (int i = 0; i < itemSize; i++) {
|
|
|
- Row currentRow = (i < 1) ? row : sheet.createRow(rowNum + (i - 1));
|
|
|
- OrderItem item = order.getOrderItems().get(i);
|
|
|
+ // 商品总额(元)
|
|
|
+ ExportUtils.createCell(sheet, row, 14, 0, rowNum, order.getTotal(), numberStyle);
|
|
|
|
|
|
- // 商品名称
|
|
|
- ExportUtils.createCell(sheet, currentRow, 6, 0, rowNum, item.getProdName(), dataStyle);
|
|
|
+ // 运费(元) - 按商品数量比例分摊
|
|
|
+ double freightPerItem = order.getProductNums() > 0 ? Arith.div(order.getFreightAmount(), order.getProductNums()) * item.getProdCount() : 0;
|
|
|
+ ExportUtils.createCell(sheet, row, 15, 0, rowNum, freightPerItem, numberStyle);
|
|
|
|
|
|
- // 规格
|
|
|
- ExportUtils.createCell(sheet, currentRow, 7, 0, rowNum, item.getSpec(), dataStyle);
|
|
|
+ // 积分抵扣(元) - 按商品数量比例分摊,显示为负数
|
|
|
+ double offsetPointsPerItem = (order.getOffsetPoints() != null && order.getProductNums() > 0)
|
|
|
+ ? Arith.div(Arith.div(Double.valueOf(order.getOffsetPoints()), 100), order.getProductNums()) * item.getProdCount() : 0;
|
|
|
+ ExportUtils.createCell(sheet, row, 16, 0, rowNum, "-" + offsetPointsPerItem, numberStyle);
|
|
|
|
|
|
- // 单价(元)
|
|
|
- ExportUtils.createCell(sheet, currentRow, 8, 0, rowNum, item.getPrice(), numberStyle);
|
|
|
+ // 实付金额 - 按商品数量比例分摊
|
|
|
+ double actualTotalPerItem = order.getProductNums() > 0 ? Arith.div(order.getActualTotal(), order.getProductNums()) * item.getProdCount() : 0;
|
|
|
+ ExportUtils.createCell(sheet, row, 17, 0, rowNum, actualTotalPerItem, numberStyle);
|
|
|
|
|
|
- // 数量
|
|
|
- ExportUtils.createCell(sheet, currentRow, 9, 0, rowNum, item.getProdCount(), dataStyle);
|
|
|
+ // 所属企业
|
|
|
+ ExportUtils.createCell(sheet, row, 18, 0, rowNum, order.getChannelName(), dataStyle);
|
|
|
|
|
|
- // 小计(元)
|
|
|
- ExportUtils.createCell(sheet, currentRow, 10, 0, rowNum, item.getProductTotalAmount(), numberStyle);
|
|
|
+ // 买家姓名
|
|
|
+ ExportUtils.createCell(sheet, row, 19, 0, rowNum, order.getReceiver(), dataStyle);
|
|
|
|
|
|
- }
|
|
|
+ // 买家电话
|
|
|
+ ExportUtils.createCell(sheet, row, 20, 0, rowNum, order.getUserMobile(), dataStyle);
|
|
|
}
|
|
|
|
|
|
/**
|