diff --git a/README.md b/README.md index 78402f6d3..c69f3bdb5 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ##前端部署 修改前端访问后端地址 -在 yudao-ui-admin 目录下,执行 npm run build:dev 命令,编译前端项目 +在 yudao-ui-admin 目录下,执行 npm run build:prod 命令,编译前端项目 将打包的dist文件内容放nginx服务访问 diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/RechargeOrderController.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/RechargeOrderController.java index 875832e69..0c4f5a820 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/RechargeOrderController.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/RechargeOrderController.java @@ -1,5 +1,9 @@ package cn.iocoder.yudao.module.shop.controller.admin.recharge; +import cn.iocoder.yudao.module.shop.controller.admin.recharge.method.Excel; +import cn.iocoder.yudao.module.shop.convert.recharge.RechargeOrderInfoConvert; +import cn.iocoder.yudao.module.shop.dal.dataobject.recharge.RechargeOrderInfoDO; +import cn.iocoder.yudao.module.shop.service.recharge.RechargeOrderInfoService; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import org.springframework.validation.annotation.Validated; @@ -36,6 +40,8 @@ public class RechargeOrderController { @Resource private RechargeOrderService rechargeOrderService; + @Resource + private RechargeOrderInfoService rechargeOrderInfoService; @PostMapping("/create") @Operation(summary = "创建订单") @@ -87,6 +93,7 @@ public class RechargeOrderController { return success(RechargeOrderConvert.INSTANCE.convertPage(pageResult)); } + @GetMapping("/export-excel") @Operation(summary = "导出订单 Excel") @PreAuthorize("@ss.hasPermission('shop:recharge-order:export')") @@ -94,9 +101,15 @@ public class RechargeOrderController { public void exportRechargeOrderExcel(@Valid RechargeOrderExportReqVO exportReqVO, HttpServletResponse response) throws IOException { List list = rechargeOrderService.getRechargeOrderList(exportReqVO); + ArrayList s = new ArrayList<>(); + list.forEach(x -> { + s.add(x.getOrderId()); + }); + List infoList = rechargeOrderInfoService.getRechargeOrderInfoList(s); // 导出 Excel List datas = RechargeOrderConvert.INSTANCE.convertList02(list); - ExcelUtils.write(response, "订单.xls", "数据", RechargeOrderExcelVO.class, datas); - } + List infoDatas = RechargeOrderInfoConvert.INSTANCE.convertList02(infoList); + Excel.orderExport(response, datas, infoDatas); + } } diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/method/Excel.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/method/Excel.java new file mode 100644 index 000000000..0b9ebffdd --- /dev/null +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/method/Excel.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.shop.controller.admin.recharge.method; + +import cn.iocoder.yudao.module.shop.controller.admin.recharge.vo.RechargeOrderExcelVO; +import cn.iocoder.yudao.module.shop.controller.admin.recharge.vo.RechargeOrderInfoExcelVO; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.write.builder.ExcelWriterBuilder; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; +import com.google.common.net.HttpHeaders; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + * @Author: ignite + * @Date: 2023/5/16 18:25 + * @Description: + */ +public class Excel { + + public static ExcelWriter orderExport(HttpServletResponse response, List z, List x) throws IOException { + + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + // 这里URLEncoder.encode可以防止中文乱码 + String encodedFileName = URLEncoder.encode(System.currentTimeMillis() + "", StandardCharsets.UTF_8.name()).replaceAll("\\+", "%20"); + response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename*=utf-8''" + encodedFileName + ".xlsx"); + + + ExcelWriterBuilder writerBuilder = EasyExcel.write(response.getOutputStream()) + .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()); + ExcelWriter excelWriter = writerBuilder.build(); + + WriteSheet writeSheet1 = EasyExcel.writerSheet(0, "订单列表").head(RechargeOrderExcelVO.class).build(); + WriteSheet writeSheet2 = EasyExcel.writerSheet(1, "订单明细表").head(RechargeOrderInfoExcelVO.class).build(); + + excelWriter.write(z, writeSheet1); + excelWriter.write(x, writeSheet2); + + excelWriter.finish(); + return excelWriter; + } +} diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/vo/RechargeOrderExcelVO.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/vo/RechargeOrderExcelVO.java index 5d80cd479..de6e69d19 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/vo/RechargeOrderExcelVO.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/vo/RechargeOrderExcelVO.java @@ -1,21 +1,10 @@ package cn.iocoder.yudao.module.shop.controller.admin.recharge.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import java.util.*; -import java.math.BigDecimal; -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.time.LocalDateTime; -import java.time.LocalDateTime; -import java.time.LocalDateTime; -import java.math.BigDecimal; -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.math.BigDecimal; -import java.math.BigDecimal; - import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; /** * 订单 Excel VO @@ -25,14 +14,23 @@ import com.alibaba.excel.annotation.ExcelProperty; @Data public class RechargeOrderExcelVO { - @ExcelProperty("订单ID") - private Integer id; - @ExcelProperty("订单号") private String orderId; - @ExcelProperty("用户id") - private Integer uid; + @ExcelProperty("第三方支付流水号") + private String paySerialNumber; + + @ExcelProperty("支付时间") + private LocalDateTime payTime; + //:0-普通订单,1-视频号订单 + @ExcelProperty("订单类型") + private Integer type; + //(0:待发货;1:待收货;2:已收货,待评价;3:已完成;) + @ExcelProperty("订单状态") + private String status; + + @ExcelProperty("配送方式") + private String deliveryType; @ExcelProperty("用户姓名") private String realName; @@ -42,89 +40,40 @@ public class RechargeOrderExcelVO { @ExcelProperty("确认手机号") private String confirmPhone; - - @ExcelProperty("订单商品总数") - private Integer totalNum; - - @ExcelProperty("订单总价") - private BigDecimal totalPrice; - - @ExcelProperty("实际支付金额") - private BigDecimal payPrice; - - @ExcelProperty("支付状态") - private Byte paid; - - @ExcelProperty("支付截止时间") - private LocalDateTime payTime; - - @ExcelProperty("支付截止时间") - private LocalDateTime payEndTime; - - @ExcelProperty("支付方式") - private String payType; - - @ExcelProperty("创建时间") - private LocalDateTime createTime; - - @ExcelProperty("订单状态(0:待发货;1:待收货;2:已收货,待评价;3:已完成;)") - private Boolean status; - - @ExcelProperty("0 未退款 1 申请中 2 已退款 3 退款中") - private Byte refundStatus; - - @ExcelProperty("退款图片") - private String refundReasonWapImg; - - @ExcelProperty("退款用户说明") - private String refundReasonWapExplain; - - @ExcelProperty("前台退款原因") - private String refundReasonWap; - - @ExcelProperty("不退款的理由") - private String refundReason; - - @ExcelProperty("退款时间") - private LocalDateTime refundReasonTime; - - @ExcelProperty("退款金额") - private BigDecimal refundPrice; + @ExcelProperty("地址") + private String address; @ExcelProperty("备注") private String mark; - @ExcelProperty("管理员备注") + @ExcelProperty("取货地址") + private String pickUpAddr; + + @ExcelProperty("自提地址") + private String SelfPickupAddr; + + @ExcelProperty("支付方式") + private String payType; + + @ExcelProperty("订单备注") private String remark; - @ExcelProperty("成本价") - private BigDecimal cost; - - @ExcelProperty("支付渠道(0微信公众号1微信小程序2余额)") - private Byte isChannel; - - @ExcelProperty("消息提醒") - private Byte isRemind; - - @ExcelProperty("后台是否删除") - private Boolean isSystemDel; - - @ExcelProperty("订单类型:0-普通订单,1-视频号订单") - private Integer type; - - @ExcelProperty("商品总价") + @ExcelProperty("产品合计金额") private BigDecimal proTotalPrice; - @ExcelProperty("改价前支付金额") - private BigDecimal beforePayPrice; + @ExcelProperty("运费") + private BigDecimal shipPrice; - @ExcelProperty("是否改价,0-否,1-是") - private Boolean isAlterPrice; + @ExcelProperty("会员账号") + private String vipAccount; - @ExcelProperty("商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号") - private String outTradeNo; + @ExcelProperty("会员姓名") + private String vipName; - @ExcelProperty("第三方支付流水号") - private String paySerialNumber; + @ExcelProperty("推广员") + private String promoter; + + @ExcelProperty("组织名称") + private Integer depName; } diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/vo/RechargeOrderInfoExcelVO.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/vo/RechargeOrderInfoExcelVO.java index 9662629ae..e5908d7e0 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/vo/RechargeOrderInfoExcelVO.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/recharge/vo/RechargeOrderInfoExcelVO.java @@ -18,30 +18,59 @@ import com.alibaba.excel.annotation.ExcelProperty; @Data public class RechargeOrderInfoExcelVO { - @ExcelProperty("主键") - private Integer id; - - @ExcelProperty("充值订单id") - private Integer rechargeOrderId; - - @ExcelProperty("充值档位") - private Integer rechargeGearId; - - @ExcelProperty("创建时间") - private LocalDateTime createTime; - @ExcelProperty("订单号") private String orderNo; - @ExcelProperty("商品名称") + @ExcelProperty("商户名称") + private String shopName; + + @ExcelProperty("产品名称") private String productName; - @ExcelProperty("商品价格") + @ExcelProperty("购物选项") + private String shopOption; + + @ExcelProperty("产品分类") + private String productCategory; + + @ExcelProperty("产品价格") private BigDecimal price; - @ExcelProperty("购买数量") + @ExcelProperty("产品数量") private Integer payNum; + @ExcelProperty("合计金额") + private BigDecimal proTotalPrice; + + @ExcelProperty("支付金额") + private BigDecimal payPrice; + + @ExcelProperty("售后状态") + private String afterStatus; + + @ExcelProperty("退款金额") + private BigDecimal refundPrice; + + @ExcelProperty("会员账号") + private String vipAccount; + + @ExcelProperty("会员姓名") + private String vipName; + //(0:待发货;1:待收货;2:已收货,待评价;3:已完成;) + @ExcelProperty("订单状态") + private String status; + + @ExcelProperty("地址") + private String address; + + @ExcelProperty("订单备注") + private String mark; + + + + + + @ExcelProperty("赠送积分") private Integer giveIntegral; diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/dataobject/recharge/RechargeOrderDO.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/dataobject/recharge/RechargeOrderDO.java index 4db369218..6ad3696b0 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/dataobject/recharge/RechargeOrderDO.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/dataobject/recharge/RechargeOrderDO.java @@ -165,4 +165,8 @@ public class RechargeOrderDO extends BaseDO { */ private String paySerialNumber; + private String creator; + private String updater; + private Boolean deleted; + } diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/dataobject/recharge/RechargeOrderInfoDO.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/dataobject/recharge/RechargeOrderInfoDO.java index 5afe858d6..9abb9b89c 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/dataobject/recharge/RechargeOrderInfoDO.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/dataobject/recharge/RechargeOrderInfoDO.java @@ -70,4 +70,9 @@ public class RechargeOrderInfoDO extends BaseDO { */ private Integer productType; + private String creator; + private String updater; + private LocalDateTime createTime; + private LocalDateTime updateTime; + } diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/mysql/recharge/RechargeOrderInfoMapper.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/mysql/recharge/RechargeOrderInfoMapper.java index 185710d14..83e868442 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/mysql/recharge/RechargeOrderInfoMapper.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/dal/mysql/recharge/RechargeOrderInfoMapper.java @@ -49,4 +49,9 @@ public interface RechargeOrderInfoMapper extends BaseMapperX selectList(List s) { + return selectList(new LambdaQueryWrapperX().in(RechargeOrderInfoDO::getOrderNo, s)); + + } + } diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/recharge/RechargeOrderInfoService.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/recharge/RechargeOrderInfoService.java index d34582d5e..07247bf0c 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/recharge/RechargeOrderInfoService.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/recharge/RechargeOrderInfoService.java @@ -67,4 +67,6 @@ public interface RechargeOrderInfoService { */ List getRechargeOrderInfoList(RechargeOrderInfoExportReqVO exportReqVO); + List getRechargeOrderInfoList(List ids); + } diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/recharge/RechargeOrderInfoServiceImpl.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/recharge/RechargeOrderInfoServiceImpl.java index 833d1c99b..16a7e0063 100644 --- a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/recharge/RechargeOrderInfoServiceImpl.java +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/recharge/RechargeOrderInfoServiceImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.shop.service.recharge; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import org.springframework.stereotype.Service; import javax.annotation.Resource; import org.springframework.validation.annotation.Validated; @@ -79,4 +80,9 @@ public class RechargeOrderInfoServiceImpl implements RechargeOrderInfoService { return rechargeOrderInfoMapper.selectList(exportReqVO); } + @Override + public List getRechargeOrderInfoList(List s) { + return rechargeOrderInfoMapper.selectList(s); + } + } diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java index 76edabeae..493dbb58f 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java @@ -13,6 +13,9 @@ public interface ErrorCodeConstants { ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在"); ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1004001001, "密码校验失败"); ErrorCode PROMOTER_NOT_EXISTS = new ErrorCode(1004001002, "推广员不存在"); + + ErrorCode PROMOTER_EXISTS = new ErrorCode(1004001003, "推广员存在"); + ErrorCode PROMOTER_IMPORT_LIST_IS_EMPTY = new ErrorCode(1002003004, "导入推广员数据不能为空!"); // ========== AUTH 模块 1004003000 ========== ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1004003000, "登录失败,账号密码不正确"); ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1004003001, "登录失败,账号被禁用"); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/promoter/PromoterController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/promoter/PromoterController.java index 8a651b0cd..05dba656b 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/promoter/PromoterController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/promoter/PromoterController.java @@ -1,5 +1,8 @@ package cn.iocoder.yudao.module.member.controller.admin.promoter; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.module.system.enums.common.SexEnum; +import io.swagger.v3.oas.annotations.Parameters; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import org.springframework.validation.annotation.Validated; @@ -27,6 +30,7 @@ import cn.iocoder.yudao.module.member.controller.admin.promoter.vo.*; import cn.iocoder.yudao.module.member.dal.dataobject.promoter.PromoterDO; import cn.iocoder.yudao.module.member.convert.promoter.PromoterConvert; import cn.iocoder.yudao.module.member.service.promoter.PromoterService; +import org.springframework.web.multipart.MultipartFile; @Tag(name = "管理后台 - 推广员") @RestController @@ -98,5 +102,27 @@ public class PromoterController { List datas = PromoterConvert.INSTANCE.convertList02(list); ExcelUtils.write(response, "推广员.xls", "数据", PromoterExcelVO.class, datas); } + @GetMapping("/get-import-template") + @Operation(summary = "获得导入推广员模板") + public void importTemplate(HttpServletResponse response) throws IOException { + // 手动创建导出 demo + List list = Arrays.asList( + PromoterImportExcelVO.builder().nickName("yunai").orgName("创盈云网络>重庆总公司>研发部门").mobile("15601691300").build() + ); + // 输出 + ExcelUtils.write(response, "推广员导入模板.xls", "推广员列表", PromoterImportExcelVO.class, list); + } + @PostMapping("/import") + @Operation(summary = "导入推广员") + @Parameters({ + @Parameter(name = "file", description = "Excel 文件", required = true), + @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true") + }) +// @PreAuthorize("@ss.hasPermission('system:user:import')") + public CommonResult importExcel(@RequestParam("file") MultipartFile file, + @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { + List list = ExcelUtils.read(file, PromoterImportExcelVO.class); + return success(promoterService.importUserList(list, updateSupport)); + } } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/promoter/vo/PromoterImportExcelVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/promoter/vo/PromoterImportExcelVO.java new file mode 100644 index 000000000..7684fc9ee --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/promoter/vo/PromoterImportExcelVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.member.controller.admin.promoter.vo; + +import cn.iocoder.yudao.framework.common.validation.Mobile; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotEmpty; + +/** + * 推广员 Excel VO + * + * @author 创盈云 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Accessors(chain = false) +public class PromoterImportExcelVO { + + @ExcelProperty("手机号码") + @Mobile + @NotEmpty(message = "手机号码不能为空") + private String mobile; + @ExcelProperty("组织全称") + @NotEmpty(message = "组织全称不能为空") + private String orgName; + + @ExcelProperty("姓名") + @NotEmpty(message = "姓名不能为空") + private String nickName; + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/promoter/vo/PromoterImportRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/promoter/vo/PromoterImportRespVO.java new file mode 100644 index 000000000..9940158a6 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/promoter/vo/PromoterImportRespVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.member.controller.admin.promoter.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +@Schema(description = "管理后台 - 推广员导入 Response VO") +@Data +@Builder +public class PromoterImportRespVO { + + @Schema(description = "导入成功的推广员数组", required = true) + private List createUsernames; + + @Schema(description = "更新成功的推广员数组", required = true) + private List updateUsernames; + + @Schema(description = "导入失败的推广员", required = true) + private Map failureUsernames; + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/promoter/PromoterDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/promoter/PromoterDO.java index 57eb9db96..01d631f2d 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/promoter/PromoterDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/promoter/PromoterDO.java @@ -32,7 +32,7 @@ public class PromoterDO implements Serializable { /** * 组织id */ - private String orgId; + private Long orgId; /** * 会员id */ diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/promoter/PromoterService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/promoter/PromoterService.java index a648673de..756dadfe3 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/promoter/PromoterService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/promoter/PromoterService.java @@ -67,4 +67,13 @@ public interface PromoterService { */ List getPromoterList(PromoterExportReqVO exportReqVO); + /** + * 批量导入推广员列表 + * + * @param importUsers 批量导入推广员列表 + * @param isUpdateSupport 是否支持更新 + * @return 导入结果 + */ + PromoterImportRespVO importUserList(List importUsers, boolean isUpdateSupport); + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/promoter/PromoterServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/promoter/PromoterServiceImpl.java index d168f73eb..3e47b5889 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/promoter/PromoterServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/promoter/PromoterServiceImpl.java @@ -1,10 +1,19 @@ package cn.iocoder.yudao.module.member.service.promoter; +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; import cn.iocoder.yudao.module.member.service.user.MemberUserService; +import cn.iocoder.yudao.module.system.api.dept.DeptApi; +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import javax.validation.Validator; + import org.springframework.validation.annotation.Validated; import java.util.*; @@ -18,6 +27,9 @@ import cn.iocoder.yudao.module.member.dal.mysql.promoter.PromoterMapper; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_IMPORT_LIST_IS_EMPTY; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_USERNAME_EXISTS; +import static java.util.stream.Collectors.toMap; /** * 推广员 Service 实现类 @@ -30,10 +42,14 @@ public class PromoterServiceImpl implements PromoterService { @Resource private PromoterMapper promoterMapper; - + @Resource + private DeptApi deptApi; + @Resource + private Validator validator; @Resource private MemberUserService memberUserService; - + @Resource + private PasswordEncoder passwordEncoder; @Override public Long createPromoter(PromoterCreateReqVO createReqVO) { @@ -45,11 +61,16 @@ public class PromoterServiceImpl implements PromoterService { memberUserDO.setNickname(createReqVO.getNickName()); memberUserDO.setMobile(createReqVO.getMobile()); memberUserDO.setStatus(createReqVO.getStatus()); + memberUserDO.setPassword(createReqVO.getMobile().substring(createReqVO.getMobile().length()-6)); memberUserService.createUserIfAbsent(createReqVO.getMobile(),createReqVO.getNickName(),getClientIP()); } // 插入 PromoterDO promoter = PromoterConvert.INSTANCE.convert(createReqVO); promoter.setTenantId(SecurityFrameworkUtils.getLoginUser().getTenantId()); + Long count = promoterMapper.selectCount(Wrappers.lambdaQuery(PromoterDO.class).eq(PromoterDO::getUserId,memberUserDO.getId())); + if(count>0){ + throw new ServiceException(PROMOTER_EXISTS); + } promoter.setUserId(memberUserDO.getId()); promoterMapper.insert(promoter); // 返回 @@ -99,4 +120,68 @@ public class PromoterServiceImpl implements PromoterService { return promoterMapper.selectList(exportReqVO); } + /** + * 批量导入推广员列表 + * + * @param importUsers 批量导入推广员列表 + * @param isUpdateSupport 是否支持更新 + * @return 导入结果 + */ + @Override + public PromoterImportRespVO importUserList(List importUsers, boolean isUpdateSupport) { + if (CollUtil.isEmpty(importUsers)) { + throw exception(PROMOTER_IMPORT_LIST_IS_EMPTY); + } + PromoterImportRespVO respVO = PromoterImportRespVO.builder().createUsernames(new ArrayList<>()) + .updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build(); + List deptRespDTOList = deptApi.getDeptList(); + Map nameList = deptRespDTOList.stream().collect(toMap(DeptRespDTO::getParentOrganizationName, value -> value,(value1,value2)->value1)); + importUsers.forEach(importUser -> { + try { + ValidationUtils.validate(validator,importUser); + } catch (ServiceException ex) { + respVO.getFailureUsernames().put(importUser.getNickName(), ex.getMessage()); + return; + } + //判断手机号是否注册 + MemberUserDO memberUserDO = memberUserService.getUserByMobile(importUser.getMobile()); + if(memberUserDO==null){ + //创建用户 + memberUserDO = new MemberUserDO(); + memberUserDO.setNickname(importUser.getNickName()); + memberUserDO.setMobile(importUser.getMobile()); + memberUserDO.setPassword(importUser.getMobile().substring(importUser.getMobile().length()-6)); + memberUserDO.setStatus(1); + memberUserService.createUserIfAbsent(importUser.getMobile(),importUser.getNickName(),getClientIP()); + } + // 插入 + PromoterDO promoter = new PromoterDO(); + promoter.setTenantId(SecurityFrameworkUtils.getLoginUser().getTenantId()); + promoter.setUserId(memberUserDO.getId()); + Long count = promoterMapper.selectCount(Wrappers.lambdaQuery(PromoterDO.class).eq(PromoterDO::getUserId,memberUserDO.getId())); + if(count>0){ + respVO.getFailureUsernames().put(importUser.getNickName(), "已经是推广员"); + return; + } + DeptRespDTO deptRespDTO = nameList.get(importUser.getOrgName()); + if(deptRespDTO==null){ + respVO.getFailureUsernames().put(importUser.getNickName(), "组织不存在"); + return; + } + promoter.setOrgId(deptRespDTO.getId()); + promoterMapper.insert(promoter); + respVO.getCreateUsernames().add(importUser.getNickName()); + return; + }); + return respVO; + } + /** + * 对密码进行加密 + * + * @param password 密码 + * @return 加密后的密码 + */ + private String encodePassword(String password) { + return passwordEncoder.encode(password); + } } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApi.java index c3d143e46..ebefd9756 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApi.java @@ -31,6 +31,14 @@ public interface DeptApi { */ List getDeptList(Collection ids); + /** + * 获得部门信息数组 + * + * @param ids 部门编号数组 + * @return 部门信息数组 + */ + List getDeptList(); + /** * 校验部门们是否有效。如下情况,视为无效: * 1. 部门编号不存在 diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/dto/DeptRespDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/dto/DeptRespDTO.java index d3e66fdd8..531bff4d4 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/dto/DeptRespDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/dto/DeptRespDTO.java @@ -34,4 +34,14 @@ public class DeptRespDTO { */ private Integer status; + /** + * 父级组织链 + */ + private String parentOrganizationIds; + + /** + * 父级组织链名称 + */ + private String parentOrganizationName; + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java index c1676ca53..bf679107d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.system.api.dept; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; +import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO; import cn.iocoder.yudao.module.system.convert.dept.DeptConvert; import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; import cn.iocoder.yudao.module.system.service.dept.DeptService; @@ -32,7 +33,11 @@ public class DeptApiImpl implements DeptApi { List depts = deptService.getDeptList(ids); return DeptConvert.INSTANCE.convertList03(depts); } - + @Override + public List getDeptList() { + List depts = deptService.getDeptList(new DeptListReqVO()); + return DeptConvert.INSTANCE.convertList03(depts); + } @Override public void validateDeptList(Collection ids) { deptService.validateDeptList(ids); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java index 512a4a761..de547fff7 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java @@ -1,10 +1,12 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant; import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.validation.Mobile; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import org.hibernate.validator.constraints.Length; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; @@ -24,11 +26,24 @@ public class TenantPageReqVO extends PageParam { private String contactName; @Schema(description = "联系手机", example = "15601691300") + @Mobile private String contactMobile; @Schema(description = "租户状态(0正常 1停用)", example = "1") private Integer status; + /** + * 销售负责人 + */ + @Schema(description = "销售负责人", example = "https://www.iocoder.cn") + @Length( max = 10, message = "销售负责人长度为 {max}位") + private String saleContactName; + /** + * 销售负责人联系电话 + */ + @Schema(description = "销售负责人联系电话", example = "https://www.iocoder.cn") + @Mobile + private String saleContactMobile; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @Schema(description = "创建时间") private LocalDateTime[] createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenant/TenantMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenant/TenantMapper.java index 8731e4628..611e3af0e 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenant/TenantMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenant/TenantMapper.java @@ -23,6 +23,8 @@ public interface TenantMapper extends BaseMapperX { .likeIfPresent(TenantDO::getName, reqVO.getName()) .likeIfPresent(TenantDO::getContactName, reqVO.getContactName()) .likeIfPresent(TenantDO::getContactMobile, reqVO.getContactMobile()) + .likeIfPresent(TenantDO::getSaleContactName, reqVO.getSaleContactName()) + .likeIfPresent(TenantDO::getSaleContactMobile, reqVO.getSaleContactMobile()) .eqIfPresent(TenantDO::getStatus, reqVO.getStatus()) .betweenIfPresent(TenantDO::getCreateTime, reqVO.getCreateTime()) .orderByDesc(TenantDO::getId)); diff --git a/yudao-ui-admin/.env.prod b/yudao-ui-admin/.env.prod index 46be158eb..df0e4935c 100644 --- a/yudao-ui-admin/.env.prod +++ b/yudao-ui-admin/.env.prod @@ -5,7 +5,7 @@ ENV = 'production' VUE_APP_TITLE = 创盈商户管理系统 # 创盈管理系统/生产环境 -VUE_APP_BASE_API = '/prod-api' +VUE_APP_BASE_API = 'https://cmx.bskies.cc:8000/cyyywl-api' # 根据服务器或域名修改 PUBLIC_PATH = 'http://my-pi.com:8888/yudao-admin/' @@ -22,4 +22,4 @@ VUE_APP_CAPTCHA_ENABLE = true VUE_APP_DOC_ENABLE = false # 百度统计 -VUE_APP_BAIDU_CODE = fadc1bd5db1a1d6f581df60a1807f8ab +VUE_APP_BAIDU_CODE = diff --git a/yudao-ui-admin/src/api/member/promoter.js b/yudao-ui-admin/src/api/member/promoter.js new file mode 100644 index 000000000..07abc6860 --- /dev/null +++ b/yudao-ui-admin/src/api/member/promoter.js @@ -0,0 +1,62 @@ +import request from '@/utils/request' + +// 创建推广员 +export function createPromoter(data) { + return request({ + url: '/member/promoter/create', + method: 'post', + data: data + }) +} + +// 更新推广员 +export function updatePromoter(data) { + return request({ + url: '/member/promoter/update', + method: 'put', + data: data + }) +} + +// 删除推广员 +export function deletePromoter(id) { + return request({ + url: '/member/promoter/delete?id=' + id, + method: 'delete' + }) +} + +// 获得推广员 +export function getPromoter(id) { + return request({ + url: '/member/promoter/get?id=' + id, + method: 'get' + }) +} + +// 获得推广员分页 +export function getPromoterPage(query) { + return request({ + url: '/member/promoter/page', + method: 'get', + params: query + }) +} + +// 导出推广员 Excel +export function exportPromoterExcel(query) { + return request({ + url: '/member/promoter/export-excel', + method: 'get', + params: query, + responseType: 'blob' + }) +} +// 下载用户导入模板 +export function importTemplate() { + return request({ + url: '/member/promoter/get-import-template', + method: 'get', + responseType: 'blob' + }) +} diff --git a/yudao-ui-admin/src/views/member/promoter/index.vue b/yudao-ui-admin/src/views/member/promoter/index.vue new file mode 100644 index 000000000..7ba9a6739 --- /dev/null +++ b/yudao-ui-admin/src/views/member/promoter/index.vue @@ -0,0 +1,289 @@ + + + diff --git a/yudao-ui-admin/src/views/system/tenant/index.vue b/yudao-ui-admin/src/views/system/tenant/index.vue index ff70cead4..b3654ebfd 100755 --- a/yudao-ui-admin/src/views/system/tenant/index.vue +++ b/yudao-ui-admin/src/views/system/tenant/index.vue @@ -2,29 +2,31 @@
- - - + + + - - - - - - - - + + - - + + + + + + + + + + + 搜索 @@ -202,11 +204,12 @@ export default { queryParams: { pageNo: 1, pageSize: 10, - name: null, - contactName: null, - contactMobile: null, - status: undefined, - createTime: [] + name: '', + contactName: '', + contactMobile: '', + status: '', + saleContactName: '', + saleContactMobile: '' }, // 表单参数 form: {}, @@ -276,17 +279,7 @@ export default { }, /** 表单重置 */ reset() { - this.form = { - id: undefined, - name: undefined, - packageId: undefined, - contactName: undefined, - contactMobile: undefined, - accountCount: undefined, - expireTime: undefined, - domain: undefined, - status: CommonStatusEnum.ENABLE, - }; + this.form = {} this.resetForm('form'); }, /** 搜索按钮操作 */ @@ -365,23 +358,14 @@ export default { params.pageNo = undefined; params.pageSize = undefined; // 执行导出 - this.$modal.confirm('是否确认导出所有租户数据项?').then(() => { + this.$modal.confirm('是否确认导出所有店铺数据项?').then(() => { this.exportLoading = true; return exportTenantExcel(params); }).then(response => { - this.$download.excel(response, '租户.xls'); + this.$download.excel(response, '店铺.xls'); this.exportLoading = false; }).catch(() => { }); - }, - /** 套餐名格式化 */ - getPackageName(packageId) { - for (const item of this.packageList) { - if (item.id === packageId) { - return item.name; - } - } - return '未知套餐'; } } };