商品导出
This commit is contained in:
@@ -13,12 +13,14 @@ import com.alibaba.fastjson2.JSONWriter;
|
||||
import com.czg.constant.CacheConstant;
|
||||
import com.czg.constants.SystemConstants;
|
||||
import com.czg.excel.ExcelExportUtil;
|
||||
import com.czg.excel.SheetData;
|
||||
import com.czg.exception.CzgException;
|
||||
import com.czg.product.dto.*;
|
||||
import com.czg.product.entity.*;
|
||||
import com.czg.product.enums.*;
|
||||
import com.czg.product.param.*;
|
||||
import com.czg.product.service.*;
|
||||
import com.czg.product.vo.ProductGroupVo;
|
||||
import com.czg.product.vo.ProductStatisticsVo;
|
||||
import com.czg.sa.StpKit;
|
||||
import com.czg.service.RedisService;
|
||||
@@ -47,6 +49,7 @@ import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.TextStyle;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.czg.constant.CacheConstant.ADMIN_CLIENT_PRODUCT_LIST;
|
||||
@@ -141,6 +144,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
||||
private void buildProductExtInfo(List<ProductDTO> records) {
|
||||
records.forEach(record -> {
|
||||
record.setIsSaleTime(calcIsSaleTime(record.getDays(), record.getStartTime(), record.getEndTime()));
|
||||
record.setProGroupVo(JSONArray.parseArray(record.getGroupSnap().toString(), ProductGroupVo.class));
|
||||
List<ProdSkuDTO> skuList = prodSkuMapper.selectListByQueryAs(query().eq(ProdSku::getProductId, record.getId()).eq(ProdSku::getIsDel, SystemConstants.OneZero.ZERO), ProdSkuDTO.class);
|
||||
if (CollUtil.isNotEmpty(skuList)) {
|
||||
Optional<BigDecimal> lowPriceIsPresent = skuList.stream().map(obj -> NumberUtil.nullToZero(obj.getSalePrice())).min(BigDecimal::compareTo);
|
||||
@@ -180,53 +184,151 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
|
||||
|
||||
@Override
|
||||
public void exportProductList(ProductDTO param, HttpServletResponse response) {
|
||||
// 1. 查询并构建完整数据
|
||||
QueryWrapper queryWrapper = buildFullQueryWrapper(param);
|
||||
List<ProductDTO> records = super.listAs(queryWrapper, ProductDTO.class);
|
||||
buildProductExtInfo(records);
|
||||
|
||||
// 2. 分别处理普通商品和套餐商品
|
||||
SheetData normalSheet = buildNormalProductSheet(records);
|
||||
SheetData packageSheet = buildPackageProductSheet(records);
|
||||
|
||||
// 3. 导出
|
||||
List<SheetData> dataList = List.of(normalSheet, packageSheet);
|
||||
ExcelExportUtil.exportMultipleSheetsToResponse(dataList, "商品列表", response);
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// 普通商品处理
|
||||
// -----------------------------
|
||||
private SheetData buildNormalProductSheet(List<ProductDTO> records) {
|
||||
List<SheetWriteHandler> handlers = new ArrayList<>();
|
||||
|
||||
List<ProductExportDTO> dataList = new ArrayList<>();
|
||||
records.forEach(exportDTO -> {
|
||||
int first = dataList.size() + 1;
|
||||
if (exportDTO.getSkuList() != null && !exportDTO.getSkuList().isEmpty()) {
|
||||
exportDTO.getSkuList().forEach(sku -> {
|
||||
ProductExportDTO dto = new ProductExportDTO();
|
||||
BeanUtil.copyProperties(exportDTO, dto);
|
||||
dto.setSpecFullName(sku.getSpecInfo());
|
||||
dto.setPrice(sku.getSalePrice());
|
||||
dto.setMemberPrice(sku.getMemberPrice());
|
||||
dto.setIsSale(sku.getIsGrounding());
|
||||
dto.setBarCode(sku.getBarCode());
|
||||
dataList.add(dto);
|
||||
});
|
||||
|
||||
if (exportDTO.getSkuList().size() > 1) {
|
||||
OnceAbsoluteMergeStrategy name = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 0, 0);
|
||||
handlers.add(name);
|
||||
OnceAbsoluteMergeStrategy category = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 1, 1);
|
||||
handlers.add(category);
|
||||
OnceAbsoluteMergeStrategy unit = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 6, 6);
|
||||
handlers.add(unit);
|
||||
OnceAbsoluteMergeStrategy type = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 7, 7);
|
||||
handlers.add(type);
|
||||
OnceAbsoluteMergeStrategy groupType = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 8, 8);
|
||||
handlers.add(groupType);
|
||||
OnceAbsoluteMergeStrategy startTime = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 9, 9);
|
||||
handlers.add(startTime);
|
||||
OnceAbsoluteMergeStrategy endTime = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 10, 10);
|
||||
handlers.add(endTime);
|
||||
OnceAbsoluteMergeStrategy stockNumber = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 11, 11);
|
||||
handlers.add(stockNumber);
|
||||
OnceAbsoluteMergeStrategy createTime = new OnceAbsoluteMergeStrategy(first, first + exportDTO.getSkuList().size() - 1, 12, 12);
|
||||
handlers.add(createTime);
|
||||
for (ProductDTO dto : records) {
|
||||
if ("package".equals(dto.getType())) continue; // 跳过套餐
|
||||
|
||||
int firstRow = dataList.size() + 1;
|
||||
|
||||
if (dto.getSkuList() != null && !dto.getSkuList().isEmpty()) {
|
||||
for (ProdSkuDTO sku : dto.getSkuList()) {
|
||||
ProductExportDTO exportDto = new ProductExportDTO();
|
||||
BeanUtil.copyProperties(dto, exportDto);
|
||||
exportDto.setSpecFullName(sku.getSpecInfo());
|
||||
exportDto.setPrice(sku.getSalePrice());
|
||||
exportDto.setMemberPrice(sku.getMemberPrice());
|
||||
exportDto.setIsSale(sku.getIsGrounding());
|
||||
exportDto.setBarCode(sku.getBarCode());
|
||||
exportDto.setCostPrice(sku.getCostPrice());
|
||||
dataList.add(exportDto);
|
||||
}
|
||||
|
||||
int skuCount = dto.getSkuList().size();
|
||||
if (skuCount > 1) {
|
||||
mergeColumns(handlers, firstRow, firstRow + skuCount - 1,
|
||||
0, 1, 7, 8, 9, 10, 11); // 多列合并
|
||||
}
|
||||
} else {
|
||||
dataList.add(BeanUtil.copyProperties(exportDTO, ProductExportDTO.class));
|
||||
dataList.add(BeanUtil.copyProperties(dto, ProductExportDTO.class));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ExcelExportUtil.exportProductWithMergeToResponse(dataList, ProductExportDTO.class, "商品列表", response, handlers);
|
||||
return new SheetData()
|
||||
.setSheetName("普通商品")
|
||||
.setData(dataList)
|
||||
.setClazz(ProductExportDTO.class)
|
||||
.setHandlers(handlers);
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// 套餐商品处理
|
||||
// -----------------------------
|
||||
private SheetData buildPackageProductSheet(List<ProductDTO> records) {
|
||||
List<SheetWriteHandler> handlers = new ArrayList<>();
|
||||
List<ProductPackageExportDTO> dataList = new ArrayList<>();
|
||||
|
||||
for (ProductDTO exportDTO : records) {
|
||||
if (!"package".equals(exportDTO.getType())) continue;
|
||||
|
||||
if (exportDTO.getProGroupVo() == null || exportDTO.getProGroupVo().isEmpty()) {
|
||||
dataList.add(BeanUtil.copyProperties(exportDTO, ProductPackageExportDTO.class));
|
||||
continue;
|
||||
}
|
||||
|
||||
int sheetFirstRow = dataList.size() + 1;
|
||||
boolean needOuterMerge = exportDTO.getProGroupVo().size() > 1;
|
||||
|
||||
for (ProductGroupVo proGroupDTO : exportDTO.getProGroupVo()) {
|
||||
int groupFirstRow = dataList.size() + 1;
|
||||
List<ProductGroupVo.Food> goods = proGroupDTO.getGoods();
|
||||
int groupSize = goods.size();
|
||||
|
||||
// 添加每条商品记录
|
||||
for (ProductGroupVo.Food good : goods) {
|
||||
ProductPackageExportDTO pkgDto = new ProductPackageExportDTO()
|
||||
.setName(exportDTO.getName())
|
||||
.setCategoryName(exportDTO.getCategoryName())
|
||||
.setUnitName(exportDTO.getUnitName())
|
||||
.setPrice(getMainSkuPrice(exportDTO))
|
||||
.setMemberPrice(getMainSkuMemberPrice(exportDTO))
|
||||
.setType(exportDTO.getType())
|
||||
.setGroupType(exportDTO.getGroupType())
|
||||
.setStockNumber(exportDTO.getStockNumber())
|
||||
.setIsSale(getMainSkuIsSale(exportDTO))
|
||||
.setGroupTitleName(proGroupDTO.getTitle())
|
||||
.setGroupProductNumber(Optional.ofNullable(proGroupDTO.getNumber()).map(String::valueOf).orElse(""))
|
||||
.setGroupProductName(good.getProName() + " " + good.getSkuName());
|
||||
dataList.add(pkgDto);
|
||||
}
|
||||
|
||||
// 组内合并:如果该组有多个商品
|
||||
if (groupSize > 1) {
|
||||
needOuterMerge = true;
|
||||
mergeColumns(handlers, groupFirstRow, groupFirstRow + groupSize - 1, 5, 8);
|
||||
}
|
||||
}
|
||||
|
||||
// 外层合并:整个套餐的信息(名称、分类等)
|
||||
if (needOuterMerge) {
|
||||
int lastRow = dataList.size();
|
||||
mergeColumns(handlers, sheetFirstRow, lastRow, 0, 1, 2, 3, 4);
|
||||
}
|
||||
}
|
||||
|
||||
return new SheetData()
|
||||
.setSheetName("套餐商品")
|
||||
.setData(dataList)
|
||||
.setClazz(ProductPackageExportDTO.class)
|
||||
.setHandlers(handlers);
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// 辅助方法:提取主 SKU 信息(避免重复 getFirst())
|
||||
// -----------------------------
|
||||
private BigDecimal getMainSkuPrice(ProductDTO dto) {
|
||||
return dto.getSkuList().isEmpty() ? null : dto.getSkuList().getFirst().getSalePrice();
|
||||
}
|
||||
|
||||
private BigDecimal getMainSkuMemberPrice(ProductDTO dto) {
|
||||
return dto.getSkuList().isEmpty() ? null : dto.getSkuList().getFirst().getMemberPrice();
|
||||
}
|
||||
|
||||
private Integer getMainSkuIsSale(ProductDTO dto) {
|
||||
return dto.getSkuList().isEmpty() ? null : dto.getSkuList().getFirst().getIsSale();
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// 合并工具方法:支持多列合并
|
||||
// -----------------------------
|
||||
private void mergeColumns(List<SheetWriteHandler> handlers, int firstRow, int lastRow, int... columns) {
|
||||
for (int col : columns) {
|
||||
addMergeHandler(handlers, firstRow, lastRow, col, col);
|
||||
}
|
||||
}
|
||||
|
||||
private void addMergeHandler(List<SheetWriteHandler> handlers, int firstRow, int lastRow, int firstCol, int lastCol) {
|
||||
OnceAbsoluteMergeStrategy strategy = new OnceAbsoluteMergeStrategy(firstRow, lastRow, firstCol, lastCol);
|
||||
handlers.add(strategy);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user