From f6eec42c0aa3d6314dedeca526475a32d92073d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Sat, 6 Sep 2025 02:19:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(shop):=20=E6=B7=BB=E5=8A=A0=E5=88=86?= =?UTF-8?q?=E9=94=80=E5=95=86=E7=94=B3=E8=AF=B7=E8=AE=B0=E5=BD=95=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E5=AF=BC=E5=85=A5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 Excel 批量导入分销商申请记录的功能 - 添加分销商申请记录导入模板下载功能 - 实现将导入参数转换为实体类的方法 - 优化关键词搜索,支持手机号、姓名和分销商名称 --- .../controller/ShopDealerApplyController.java | 178 ++++++++++++++++++ .../shop/mapper/xml/ShopDealerApplyMapper.xml | 4 +- .../param/ShopDealerApplyImportParam.java | 60 ++++++ 3 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/gxwebsoft/shop/param/ShopDealerApplyImportParam.java diff --git a/src/main/java/com/gxwebsoft/shop/controller/ShopDealerApplyController.java b/src/main/java/com/gxwebsoft/shop/controller/ShopDealerApplyController.java index a2fd323..41cde3a 100644 --- a/src/main/java/com/gxwebsoft/shop/controller/ShopDealerApplyController.java +++ b/src/main/java/com/gxwebsoft/shop/controller/ShopDealerApplyController.java @@ -1,11 +1,16 @@ package com.gxwebsoft.shop.controller; +import cn.afterturn.easypoi.excel.ExcelImportUtil; +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ImportParams; +import cn.afterturn.easypoi.excel.entity.ExportParams; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.gxwebsoft.common.core.web.BaseController; import com.gxwebsoft.shop.entity.ShopDealerUser; import com.gxwebsoft.shop.service.ShopDealerApplyService; import com.gxwebsoft.shop.entity.ShopDealerApply; import com.gxwebsoft.shop.param.ShopDealerApplyParam; +import com.gxwebsoft.shop.param.ShopDealerApplyImportParam; import com.gxwebsoft.common.core.web.ApiResult; import com.gxwebsoft.common.core.web.PageResult; import com.gxwebsoft.common.core.web.BatchParam; @@ -14,11 +19,18 @@ import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.shop.service.ShopDealerUserService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import org.apache.poi.ss.usermodel.Workbook; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; import java.util.List; /** @@ -161,4 +173,170 @@ public class ShopDealerApplyController extends BaseController { return fail("删除失败"); } + /** + * excel批量导入分销商申请记录 + * Excel表头格式:类型、用户ID、姓名、分销商名称、分销商编码、手机号、合同金额、详细地址、推荐人用户ID、申请方式、审核状态、合同时间、驳回原因、商城ID + */ + @PreAuthorize("hasAuthority('shop:shopDealerApply:save')") + @Transactional(rollbackFor = {Exception.class}) + @Operation(summary = "批量导入分销商申请记录") + @PostMapping("/import") + public ApiResult> importBatch(MultipartFile file) { + ImportParams importParams = new ImportParams(); + // 设置标题行,跳过第一行表头 + importParams.setTitleRows(1); + importParams.setHeadRows(1); + List errorMessages = new ArrayList<>(); + int successCount = 0; + + try { + List list = ExcelImportUtil.importExcel(file.getInputStream(), ShopDealerApplyImportParam.class, importParams); + + // 获取当前登录用户 + User loginUser = getLoginUser(); + Integer currentUserId = loginUser != null ? loginUser.getUserId() : null; + + for (int i = 0; i < list.size(); i++) { + ShopDealerApplyImportParam param = list.get(i); + try { + // 手动转换对象,避免JSON序列化问题 + ShopDealerApply item = convertImportParamToEntity(param); + + // 设置必填字段的默认值 + if (item.getUserId() == null && currentUserId != null) { + item.setUserId(currentUserId); + } + if (item.getApplyStatus() == null) { + item.setApplyStatus(10); // 默认状态为待审核 + } + if (item.getApplyType() == null) { + item.setApplyType(10); // 默认需要后台审核 + } + if (item.getType() == null) { + item.setType(0); // 默认类型为经销商 + } + + // 设置申请时间 + item.setApplyTime(LocalDateTime.now()); + + // 验证必填字段 + if (item.getRealName() == null || item.getRealName().trim().isEmpty()) { + errorMessages.add("第" + (i + 1) + "行:姓名不能为空"); + continue; + } + if (item.getDealerName() == null || item.getDealerName().trim().isEmpty()) { + errorMessages.add("第" + (i + 1) + "行:企业名称不能为空"); + continue; + } + if (item.getMobile() == null || item.getMobile().trim().isEmpty()) { + errorMessages.add("第" + (i + 1) + "行:手机号不能为空"); + continue; + } + + // 验证推荐人是否存在 + if (item.getRefereeId() != null) { + if (shopDealerUserService.getByIdRel(item.getRefereeId()) == null) { + errorMessages.add("第" + (i + 1) + "行:推荐人不存在"); + continue; + } + } + + // 保存数据 + if (shopDealerApplyService.save(item)) { + successCount++; + } else { + errorMessages.add("第" + (i + 1) + "行:保存失败"); + } + + } catch (Exception e) { + errorMessages.add("第" + (i + 1) + "行:" + e.getMessage()); + System.err.println("导入第" + (i + 1) + "行数据失败: " + e.getMessage()); + e.printStackTrace(); + } + } + + // 返回结果 + if (errorMessages.isEmpty()) { + return success("成功导入" + successCount + "条数据", null); + } else { + return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "条", errorMessages); + } + + } catch (Exception e) { + System.err.println("批量导入分销商申请记录失败: " + e.getMessage()); + e.printStackTrace(); + return fail("导入失败:" + e.getMessage(), null); + } + } + + /** + * 下载分销商申请记录导入模板 + */ + @Operation(summary = "下载分销商申请记录导入模板") + @GetMapping("/import/template") + public void downloadTemplate(HttpServletResponse response) throws IOException { + // 创建空的导入参数列表作为模板 + List templateList = new ArrayList<>(); + + // 添加一行示例数据 + ShopDealerApplyImportParam example = new ShopDealerApplyImportParam(); + example.setType(0); + example.setRealName("宗馥莉"); + example.setDealerName("娃哈哈有限公司"); + example.setDealerCode("WaHaHa"); + example.setMobile("13800138000"); + example.setApplyType(10); + example.setApplyStatus(10); + example.setContractTime("2025-09-05 10:00:00"); + templateList.add(example); + + // 设置导出参数 + ExportParams exportParams = new ExportParams("分销商申请记录导入模板", "分销商申请记录"); + + // 生成Excel + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, ShopDealerApplyImportParam.class, templateList); + + // 设置响应头 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setHeader("Content-Disposition", "attachment; filename=shop_dealer_apply_import_template.xlsx"); + + // 输出到响应流 + workbook.write(response.getOutputStream()); + workbook.close(); + } + + /** + * 将ShopDealerApplyImportParam转换为ShopDealerApply实体 + */ + private ShopDealerApply convertImportParamToEntity(ShopDealerApplyImportParam param) { + ShopDealerApply entity = new ShopDealerApply(); + + // 基本字段转换 + entity.setType(param.getType()); + entity.setUserId(param.getUserId()); + entity.setRealName(param.getRealName()); + entity.setDealerName(param.getDealerName()); + entity.setDealerCode(param.getDealerCode()); + entity.setMobile(param.getMobile()); + entity.setMoney(param.getMoney()); + entity.setAddress(param.getAddress()); + entity.setRefereeId(param.getRefereeId()); + entity.setApplyType(param.getApplyType()); + entity.setApplyStatus(param.getApplyStatus()); + entity.setRejectReason(param.getRejectReason()); + entity.setTenantId(param.getTenantId()); + + // 处理合同时间 + if (param.getContractTime() != null && !param.getContractTime().trim().isEmpty()) { + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + entity.setContractTime(LocalDateTime.parse(param.getContractTime(), formatter)); + } catch (Exception e) { + System.err.println("合同时间格式错误: " + param.getContractTime()); + } + } + + return entity; + } + } diff --git a/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopDealerApplyMapper.xml b/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopDealerApplyMapper.xml index 5ced30c..779f01b 100644 --- a/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopDealerApplyMapper.xml +++ b/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopDealerApplyMapper.xml @@ -47,7 +47,9 @@ AND a.create_time <= #{param.createTimeEnd} - AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%') + AND (a.mobile = #{param.keywords} + OR a.real_name LIKE CONCAT('%', #{param.keywords}, '%') + OR a.dealer_name LIKE CONCAT('%', #{param.keywords}, '%') ) diff --git a/src/main/java/com/gxwebsoft/shop/param/ShopDealerApplyImportParam.java b/src/main/java/com/gxwebsoft/shop/param/ShopDealerApplyImportParam.java new file mode 100644 index 0000000..50ff384 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/param/ShopDealerApplyImportParam.java @@ -0,0 +1,60 @@ +package com.gxwebsoft.shop.param; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 分销商申请记录导入参数 + * + * @author 科技小王子 + * @since 2025-09-05 + */ +@Data +public class ShopDealerApplyImportParam implements Serializable { + private static final long serialVersionUID = 1L; + + @Excel(name = "类型", replace = {"经销商_0", "企业_1", "集团_2"}) + private Integer type; + + @Excel(name = "用户ID") + private Integer userId; + + @Excel(name = "姓名") + private String realName; + + @Excel(name = "分销商名称") + private String dealerName; + + @Excel(name = "分销商编码") + private String dealerCode; + + @Excel(name = "手机号") + private String mobile; + + @Excel(name = "合同金额") + private BigDecimal money; + + @Excel(name = "详细地址") + private String address; + + @Excel(name = "推荐人用户ID") + private Integer refereeId; + + @Excel(name = "申请方式", replace = {"需后台审核_10", "无需审核_20"}) + private Integer applyType; + + @Excel(name = "审核状态", replace = {"待审核_10", "审核通过_20", "驳回_30"}) + private Integer applyStatus; + + @Excel(name = "合同时间", format = "yyyy-MM-dd HH:mm:ss") + private String contractTime; + + @Excel(name = "驳回原因") + private String rejectReason; + + @Excel(name = "商城ID") + private Integer tenantId; +}