feat(shop): 添加分销商申请记录批量导入功能
- 新增 Excel 批量导入分销商申请记录的功能 - 添加分销商申请记录导入模板下载功能 - 实现将导入参数转换为实体类的方法 - 优化关键词搜索,支持手机号、姓名和分销商名称
This commit is contained in:
@@ -1,11 +1,16 @@
|
|||||||
package com.gxwebsoft.shop.controller;
|
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.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.gxwebsoft.common.core.web.BaseController;
|
import com.gxwebsoft.common.core.web.BaseController;
|
||||||
import com.gxwebsoft.shop.entity.ShopDealerUser;
|
import com.gxwebsoft.shop.entity.ShopDealerUser;
|
||||||
import com.gxwebsoft.shop.service.ShopDealerApplyService;
|
import com.gxwebsoft.shop.service.ShopDealerApplyService;
|
||||||
import com.gxwebsoft.shop.entity.ShopDealerApply;
|
import com.gxwebsoft.shop.entity.ShopDealerApply;
|
||||||
import com.gxwebsoft.shop.param.ShopDealerApplyParam;
|
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.ApiResult;
|
||||||
import com.gxwebsoft.common.core.web.PageResult;
|
import com.gxwebsoft.common.core.web.PageResult;
|
||||||
import com.gxwebsoft.common.core.web.BatchParam;
|
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 com.gxwebsoft.shop.service.ShopDealerUserService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
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.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -161,4 +173,170 @@ public class ShopDealerApplyController extends BaseController {
|
|||||||
return fail("删除失败");
|
return fail("删除失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* excel批量导入分销商申请记录
|
||||||
|
* Excel表头格式:类型、用户ID、姓名、分销商名称、分销商编码、手机号、合同金额、详细地址、推荐人用户ID、申请方式、审核状态、合同时间、驳回原因、商城ID
|
||||||
|
*/
|
||||||
|
@PreAuthorize("hasAuthority('shop:shopDealerApply:save')")
|
||||||
|
@Transactional(rollbackFor = {Exception.class})
|
||||||
|
@Operation(summary = "批量导入分销商申请记录")
|
||||||
|
@PostMapping("/import")
|
||||||
|
public ApiResult<List<String>> importBatch(MultipartFile file) {
|
||||||
|
ImportParams importParams = new ImportParams();
|
||||||
|
// 设置标题行,跳过第一行表头
|
||||||
|
importParams.setTitleRows(1);
|
||||||
|
importParams.setHeadRows(1);
|
||||||
|
List<String> errorMessages = new ArrayList<>();
|
||||||
|
int successCount = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<ShopDealerApplyImportParam> 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<ShopDealerApplyImportParam> 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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,9 @@
|
|||||||
AND a.create_time <= #{param.createTimeEnd}
|
AND a.create_time <= #{param.createTimeEnd}
|
||||||
</if>
|
</if>
|
||||||
<if test="param.keywords != null">
|
<if test="param.keywords != null">
|
||||||
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}, '%')
|
||||||
)
|
)
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user