Ver código fonte

Merge branch 'mp-server-test' into 'master'

Mp server test

See merge request quanshu/mp-server!996
jiang hao 2 anos atrás
pai
commit
f921819491
45 arquivos alterados com 2398 adições e 1303 exclusões
  1. 281 271
      mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/ChannelMgrController.java
  2. 62 0
      mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/PromoterMsgController.java
  3. 709 649
      mp-admin/src/main/java/com/qs/mp/web/controller/api/channel/ChannelController.java
  4. 1 1
      mp-admin/src/main/java/com/qs/mp/web/controller/api/channel/ChannelCouponVerifyController.java
  5. 16 1
      mp-admin/src/main/java/com/qs/mp/web/controller/api/channel/ChannelInviteController.java
  6. 221 0
      mp-admin/src/main/java/com/qs/mp/web/controller/api/channel/PromoterController.java
  7. 11 0
      mp-admin/src/main/java/com/qs/mp/web/controller/api/user/UserTicketController.java
  8. 17 0
      mp-admin/src/main/java/com/qs/mp/web/controller/api/user/UserTicketOrderController.java
  9. 2 1
      mp-common/src/main/java/com/qs/mp/common/enums/ChannelRoleEnum.java
  10. 3 1
      mp-framework/src/main/java/com/qs/mp/framework/config/SecurityConfig.java
  11. 2 0
      mp-framework/src/main/java/com/qs/mp/framework/web/service/SysLoginService.java
  12. 3 0
      mp-service/src/main/java/com/qs/mp/admin/domain/vo/TicketVO.java
  13. 3 0
      mp-service/src/main/java/com/qs/mp/admin/domain/vo/UserTicketOrderDetailVO.java
  14. 14 1
      mp-service/src/main/java/com/qs/mp/channel/domain/Channel.java
  15. 78 0
      mp-service/src/main/java/com/qs/mp/channel/domain/PromoterUser.java
  16. 3 0
      mp-service/src/main/java/com/qs/mp/channel/domain/param/ChannelCommParam.java
  17. 48 0
      mp-service/src/main/java/com/qs/mp/channel/domain/param/PromoterCreateParam.java
  18. 25 0
      mp-service/src/main/java/com/qs/mp/channel/domain/param/PromoterDataQueryParam.java
  19. 36 0
      mp-service/src/main/java/com/qs/mp/channel/domain/param/PromoterEditParam.java
  20. 32 0
      mp-service/src/main/java/com/qs/mp/channel/domain/param/PromoterListQueryParam.java
  21. 23 0
      mp-service/src/main/java/com/qs/mp/channel/domain/param/PromoterQueryParam.java
  22. 11 1
      mp-service/src/main/java/com/qs/mp/channel/domain/vo/ChannelOperDataVO.java
  23. 45 0
      mp-service/src/main/java/com/qs/mp/channel/domain/vo/PromoterListVO.java
  24. 26 0
      mp-service/src/main/java/com/qs/mp/channel/domain/vo/PromoterVO.java
  25. 9 0
      mp-service/src/main/java/com/qs/mp/channel/mapper/ChannelMapper.java
  26. 19 0
      mp-service/src/main/java/com/qs/mp/channel/mapper/PromoterUserMapper.java
  27. 108 72
      mp-service/src/main/java/com/qs/mp/channel/service/IChannelService.java
  28. 20 0
      mp-service/src/main/java/com/qs/mp/channel/service/IPromoterUserService.java
  29. 317 185
      mp-service/src/main/java/com/qs/mp/channel/service/impl/ChannelServiceImpl.java
  30. 27 0
      mp-service/src/main/java/com/qs/mp/channel/service/impl/PromoterUserServiceImpl.java
  31. 2 2
      mp-service/src/main/java/com/qs/mp/framework/service/impl/AsyncTaskServiceImpl.java
  32. 1 1
      mp-service/src/main/java/com/qs/mp/framework/service/impl/WxUrlLinkServiceImpl.java
  33. 73 111
      mp-service/src/main/java/com/qs/mp/system/service/impl/SysRoleServiceImpl.java
  34. 4 0
      mp-service/src/main/java/com/qs/mp/user/domain/UserTicketOrder.java
  35. 3 0
      mp-service/src/main/java/com/qs/mp/user/domain/param/TicketOrderParam.java
  36. 6 0
      mp-service/src/main/java/com/qs/mp/user/domain/vo/TicketOrderSettleVO.java
  37. 5 1
      mp-service/src/main/java/com/qs/mp/user/domain/vo/UserPrizeStorageVO.java
  38. 4 0
      mp-service/src/main/java/com/qs/mp/user/domain/vo/UserShareVO.java
  39. 1 0
      mp-service/src/main/java/com/qs/mp/user/mapper/UserTicketOrderMapper.java
  40. 2 0
      mp-service/src/main/java/com/qs/mp/user/service/IUserTicketOrderService.java
  41. 5 0
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserDeliverOrderServiceImpl.java
  42. 55 4
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserTicketOrderServiceImpl.java
  43. 24 0
      mp-service/src/main/resources/mapper/channel/ChannelMapper.xml
  44. 30 0
      mp-service/src/main/resources/mapper/channel/PromoterUserMapper.xml
  45. 11 1
      mp-service/src/main/resources/mapper/user/UserTicketOrderMapper.xml

+ 281 - 271
mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/ChannelMgrController.java

@@ -51,132 +51,138 @@ import org.springframework.web.bind.annotation.RestController;
 @Component
 public class ChannelMgrController extends BaseApiController {
 
-	@Autowired
-	private IChannelService channelService;
+    @Autowired
+    private IChannelService channelService;
 
-	@Autowired
-	private IChannelUserRelService channelUserRelService;
+    @Autowired
+    private IChannelUserRelService channelUserRelService;
 
-	@Autowired
-	private IChannelOrderService channelOrderService;
+    @Autowired
+    private IChannelOrderService channelOrderService;
 
-	@Autowired
-	private IUserTicketOrderService userTicketOrderService;
+    @Autowired
+    private IUserTicketOrderService userTicketOrderService;
 
-	@Autowired
-	private ISysUserService userService;
+    @Autowired
+    private ISysUserService userService;
 
-	@Autowired
-	private MapperFacade mapperFacade;
+    @Autowired
+    private MapperFacade mapperFacade;
 
-	/**
-	 * 获取我的下级渠道列表信息,LIMIT 50
-	 *
-	 * @return
-	 */
-	@PostMapping("/tree")
-	@PreAuthorize("@ss.hasPermi('business:channel:list')")
-	public AjaxResult treeChannel(@RequestBody Channel channel) {
-		List<ChannelVO> list = new ArrayList<ChannelVO>();
-		QueryWrapper<Channel> queryWrapper = new QueryWrapper<>();
-		queryWrapper.eq("t1.parent_id", null!=channel && null != channel.getParentId()?channel.getParentId():0);
-		queryWrapper.gt("t1.level", 0);
-		queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getMobile()), "t1.mobile", channel.getMobile());
-		queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getName()), "t1.name", channel.getName());
-		queryWrapper.orderByAsc("t1.level").orderByDesc("t1.channel_id");
-		queryWrapper.last("limit 50");
-		list = channelService.selectChannelVoList(queryWrapper);
-		if(null != list && list.size() > 0) {
-			for(ChannelVO channelVO : list) {
-				if(null != channelVO && StringUtils.isNotBlank(channelVO.getChannelNo())) {
+    /**
+     * 获取我的下级渠道列表信息,LIMIT 50
+     *
+     * @return
+     */
+    @PostMapping("/tree")
+    @PreAuthorize("@ss.hasPermi('business:channel:list')")
+    public AjaxResult treeChannel(@RequestBody Channel channel) {
+        List<ChannelVO> list = new ArrayList<ChannelVO>();
+        QueryWrapper<Channel> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("t1.parent_id", null != channel && null != channel.getParentId() ? channel.getParentId() : 0);
+        queryWrapper.gt("t1.level", 0);
+        queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getMobile()), "t1.mobile",
+            channel.getMobile());
+        queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getName()), "t1.name",
+            channel.getName());
+        queryWrapper.orderByAsc("t1.level").orderByDesc("t1.channel_id");
+        queryWrapper.last("limit 50");
+        list = channelService.selectChannelVoList(queryWrapper);
+        if (null != list && list.size() > 0) {
+            for (ChannelVO channelVO : list) {
+                if (null != channelVO && StringUtils.isNotBlank(channelVO.getChannelNo())) {
 //					int siteCnt = channelService.getChannelSiteCnt(channelVO.getChannelNo());
 //					int userCnt = channelUserRelService.getChannelUserCnt(channelVO.getChannelNo());
 //					channelVO.setSiteCnt(siteCnt);
 //					channelVO.setUserCnt(userCnt);
-					// 查询子渠道数量
-					int childCnt = channelService.count(
-							new LambdaQueryWrapper<Channel>().eq(Channel::getParentId, channelVO.getChannelId())
-							.gt(Channel::getLevel, 0));
-					channelVO.setChildCnt(childCnt);
-				}
-			}
-		}
-		return AjaxResult.success(list);
-	}
+                    // 查询子渠道数量
+                    int childCnt = channelService.count(
+                        new LambdaQueryWrapper<Channel>().eq(Channel::getParentId, channelVO.getChannelId())
+                            .gt(Channel::getLevel, 0));
+                    channelVO.setChildCnt(childCnt);
+                }
+            }
+        }
+        return AjaxResult.success(list);
+    }
 
 
-	/**
-	 * 查询所有渠道列表
-	 *
-	 * @return
-	 */
-	@PostMapping("/listAll")
-	@PreAuthorize("@ss.hasPermi('business:channel:list')")
-	public AjaxResult listAllChannel() {
-		List<Channel> list = new ArrayList<Channel>();
-		LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<Channel>();
-		queryWrapper.gt(Channel::getLevel, 0);
-		queryWrapper.orderByAsc(Channel::getLevel).orderByDesc(Channel::getChannelId);
-		list = channelService.list(queryWrapper);
-		return AjaxResult.success(list);
-	}
+    /**
+     * 查询所有渠道列表
+     *
+     * @return
+     */
+    @PostMapping("/listAll")
+    @PreAuthorize("@ss.hasPermi('business:channel:list')")
+    public AjaxResult listAllChannel() {
+        List<Channel> list = new ArrayList<Channel>();
+        LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<Channel>();
+        queryWrapper.gt(Channel::getLevel, 0);
+        queryWrapper.orderByAsc(Channel::getLevel).orderByDesc(Channel::getChannelId);
+        list = channelService.list(queryWrapper);
+        return AjaxResult.success(list);
+    }
 
 
-	/**
-	 * 获取我的下级渠道列表信息,支持翻页
-	 *
-	 * @return
-	 */
-	@PostMapping("/list")
-	@PreAuthorize("@ss.hasPermi('business:channel:list')")
-	public TableDataInfo listChannel(@RequestBody ChannelVO channel) {
-		List<ChannelVO> list = new ArrayList<ChannelVO>();
-		startPage();
-		QueryWrapper<Channel> queryWrapper = new QueryWrapper<>();
-		if(null!=channel && null != channel.getParentId()) {
-			queryWrapper.eq("t1.parent_id", channel.getParentId());
-		}
-		queryWrapper.gt("t1.level", 0);
-		queryWrapper.eq(null != channel && null != channel.getLevel(),"t1.level", channel.getLevel());
-		queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getMobile()), "t1.mobile", channel.getMobile());
-		queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getName()), "t1.name", channel.getName());
-		queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getParentName()), "t2.name", channel.getParentName());
-		queryWrapper.eq(null != channel && null != channel.getProvinceId(), "t1.province_id", channel.getProvinceId());
-		queryWrapper.eq(null != channel && null != channel.getCityId(), "t1.city_id", channel.getCityId());
-		queryWrapper.eq(null != channel && null != channel.getAreaId(), "t1.area_id", channel.getAreaId());
-		list = channelService.selectChannelList(queryWrapper);
-		return getDataTable(list);
-	}
+    /**
+     * 获取我的下级渠道列表信息,支持翻页
+     *
+     * @return
+     */
+    @PostMapping("/list")
+    @PreAuthorize("@ss.hasPermi('business:channel:list')")
+    public TableDataInfo listChannel(@RequestBody ChannelVO channel) {
+        List<ChannelVO> list = new ArrayList<ChannelVO>();
+        startPage();
+        QueryWrapper<Channel> queryWrapper = new QueryWrapper<>();
+        if (null != channel && null != channel.getParentId()) {
+            queryWrapper.eq("t1.parent_id", channel.getParentId());
+        }
+        queryWrapper.gt("t1.level", 0);
+        queryWrapper.eq(null != channel && null != channel.getLevel(), "t1.level", channel.getLevel());
+        queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getMobile()), "t1.mobile",
+            channel.getMobile());
+        queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getName()), "t1.name",
+            channel.getName());
+        queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getParentName()), "t2.name",
+            channel.getParentName());
+        queryWrapper.eq(null != channel && null != channel.getProvinceId(), "t1.province_id", channel.getProvinceId());
+        queryWrapper.eq(null != channel && null != channel.getCityId(), "t1.city_id", channel.getCityId());
+        queryWrapper.eq(null != channel && null != channel.getAreaId(), "t1.area_id", channel.getAreaId());
+        list = channelService.selectChannelList(queryWrapper);
+        return getDataTable(list);
+    }
 
 
-	/**
-	 * 渠道管理新增一级渠道信息
-	 * @param
-	 * @return
-	 */
-	@Log(title = "新增渠道", businessType = BusinessType.INSERT)
-	@ApiOperation(value = "新增子渠道信息", notes = "渠道端新增子渠道")
-	@PostMapping("/create")
-	@PreAuthorize("@ss.hasPermi('business:channel:add')")
-	public AjaxResult channelCreate(@Validated @RequestBody ChannelParam channelParam) {
-		if (channelParam.getChannelId() != null && channelParam.getChannelId() != 0) {
-			return AjaxResult.error("该渠道已存在");
-		}
-		Channel channel = mapperFacade.map(channelParam, Channel.class);
-		// 1、校验名称是否重复、手机号是否存在(渠道表)
-		LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<>();
-		queryWrapper.eq(Channel::getName, channel.getName());
-		queryWrapper.gt(Channel::getLevel, 0);
-		int nameCount = channelService.count(queryWrapper);
-		if(nameCount > 0) {
-			return AjaxResult.error("渠道名称" + channel.getName() + "已存在!");
-		}
-		int mobileCount = channelService.count(
-		        new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, channel.getMobile()));
-		if(mobileCount > 0) {
-			 return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
-		}
-		// 2.校验佣金比例,不能高于其父渠道的佣金比例
+    /**
+     * 渠道管理新增一级渠道信息
+     *
+     * @param
+     * @return
+     */
+    @Log(title = "新增渠道", businessType = BusinessType.INSERT)
+    @ApiOperation(value = "新增子渠道信息", notes = "渠道端新增子渠道")
+    @PostMapping("/create")
+    @PreAuthorize("@ss.hasPermi('business:channel:add')")
+    public AjaxResult channelCreate(@Validated @RequestBody ChannelParam channelParam) {
+        if (channelParam.getChannelId() != null && channelParam.getChannelId() != 0) {
+            return AjaxResult.error("该渠道已存在");
+        }
+        Channel channel = mapperFacade.map(channelParam, Channel.class);
+        // 1、校验名称是否重复、手机号是否存在(渠道表)
+        LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(Channel::getName, channel.getName());
+        queryWrapper.gt(Channel::getLevel, 0);
+        int nameCount = channelService.count(queryWrapper);
+        if (nameCount > 0) {
+            return AjaxResult.error("渠道名称" + channel.getName() + "已存在!");
+        }
+        int mobileCount = channelService.count(
+            new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, channel.getMobile()));
+        if (mobileCount > 0) {
+            return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
+        }
+        // 2.校验佣金比例,不能高于其父渠道的佣金比例
 //		if(null != channel.getParentId() && channel.getParentId() != 0) {
 //			Channel parentChannel = channelService.getById(channel.getParentId());
 //			if(null != parentChannel) {
@@ -193,62 +199,63 @@ public class ChannelMgrController extends BaseApiController {
 //			channel.setLevel(1);
 //			channel.setChannelNo("");
 //		}
-		channel.setParentId(0L);
-		channel.setLevel(1);
-		channel.setChannelNo("");
-		// 3.插入数据
-		try {
-			channelService.saveChannel(channel,ChannelRoleEnum.CHANNEL);
-		} catch (Exception e) {
-			return AjaxResult.error("渠道'" + channel.getName() + "'新增失败" + e.getMessage());
-		}
+        channel.setParentId(0L);
+        channel.setLevel(1);
+        channel.setChannelNo("");
+        // 3.插入数据
+        try {
+            channelService.saveChannel(channel, ChannelRoleEnum.CHANNEL);
+        } catch (Exception e) {
+            return AjaxResult.error("渠道'" + channel.getName() + "'新增失败" + e.getMessage());
+        }
 
-		return AjaxResult.success("渠道'" + channel.getName() + "'新增成功");
-	}
+        return AjaxResult.success("渠道'" + channel.getName() + "'新增成功");
+    }
 
-	/**
-	 * 编辑一级子渠道信息
-	 * @param
-	 * @return
-	 */
-	@Log(title = "修改渠道", businessType = BusinessType.UPDATE)
-	@ApiOperation(value = "编辑子渠道信息", notes = "渠道端编辑子渠道")
-	@PostMapping("/update")
-	@PreAuthorize("@ss.hasPermi('business:channel:edit')")
-	public AjaxResult channelUpdate(@Validated @RequestBody ChannelParam channelParam) {
-		if (null == channelParam || null == channelParam.getChannelId()) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		Channel channel = mapperFacade.map(channelParam, Channel.class);
-		// 1、校验修改子渠道是否为当前用户的子渠道
-		Channel oldChannel = channelService.getById(channel.getChannelId());
-		if(null == oldChannel || null == oldChannel.getChannelId()) {
-			return AjaxResult.error("渠道'" + oldChannel.getName() + "'编辑失败,渠道ID异常");
-		}
-		// 2.校验名称是否重复、手机号是否存在(渠道表);
-		if(!channel.getName().equals(oldChannel.getName())) {
-			LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<>();
-			queryWrapper.eq(Channel::getName, channel.getName());
-			queryWrapper.gt(Channel::getLevel, 0);
-			int nameCount = channelService.count(queryWrapper);
-			if(nameCount > 0) {
-				return AjaxResult.error("渠道名称" + channel.getName() + "已存在!");
-			}
-		}
-		boolean mobileChange = false;  // 手机号码是否有变更
-		if(!channel.getMobile().equals(oldChannel.getMobile())) {
+    /**
+     * 编辑一级子渠道信息
+     *
+     * @param
+     * @return
+     */
+    @Log(title = "修改渠道", businessType = BusinessType.UPDATE)
+    @ApiOperation(value = "编辑子渠道信息", notes = "渠道端编辑子渠道")
+    @PostMapping("/update")
+    @PreAuthorize("@ss.hasPermi('business:channel:edit')")
+    public AjaxResult channelUpdate(@Validated @RequestBody ChannelParam channelParam) {
+        if (null == channelParam || null == channelParam.getChannelId()) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+        Channel channel = mapperFacade.map(channelParam, Channel.class);
+        // 1、校验修改子渠道是否为当前用户的子渠道
+        Channel oldChannel = channelService.getById(channel.getChannelId());
+        if (null == oldChannel || null == oldChannel.getChannelId()) {
+            return AjaxResult.error("渠道'" + oldChannel.getName() + "'编辑失败,渠道ID异常");
+        }
+        // 2.校验名称是否重复、手机号是否存在(渠道表);
+        if (!channel.getName().equals(oldChannel.getName())) {
+            LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(Channel::getName, channel.getName());
+            queryWrapper.gt(Channel::getLevel, 0);
+            int nameCount = channelService.count(queryWrapper);
+            if (nameCount > 0) {
+                return AjaxResult.error("渠道名称" + channel.getName() + "已存在!");
+            }
+        }
+        boolean mobileChange = false;  // 手机号码是否有变更
+        if (!channel.getMobile().equals(oldChannel.getMobile())) {
 
-			int mobileCount = channelService.count(
-			        new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, channel.getMobile()));
-			if(mobileCount > 0) {
-				return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
-			}
-			if(UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(channel.getMobile()))) {
-				return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
-			}
-			mobileChange = true;
-		}
-		// 3.校验佣金比例,不能高于其父渠道的佣金比例,不能低于其子渠道的最大佣金比例
+            int mobileCount = channelService.count(
+                new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, channel.getMobile()));
+            if (mobileCount > 0) {
+                return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
+            }
+            if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(channel.getMobile()))) {
+                return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
+            }
+            mobileChange = true;
+        }
+        // 3.校验佣金比例,不能高于其父渠道的佣金比例,不能低于其子渠道的最大佣金比例
 //		Channel parentChannel = channelService.getById(oldChannel.getParentId());
 //		if(null != parentChannel) {
 //			 if(null != parentChannel.getCommRate()
@@ -260,120 +267,123 @@ public class ChannelMgrController extends BaseApiController {
 //		}else {
 //			return AjaxResult.error("父渠道不存在");
 //		}
-		// 查询子渠道的最大佣金比例
-		QueryWrapper<Channel> queryWrapper = new QueryWrapper<Channel>();
-		queryWrapper.select("IFNULL(max(comm_rate),0) as commRate");
-		queryWrapper.lambda().eq(Channel::getParentId, channel.getChannelId());
-		Map<String, Object> map = channelService.getMap(queryWrapper);
-		if(null != map && map.containsKey("commRate")) {
-			BigDecimal commRate = new BigDecimal(map.get("commRate").toString());
-			if(!commRate.equals(BigDecimal.ZERO) && channel.getCommRate().compareTo(commRate) < 0) {
-				return AjaxResult.error("不能低于其子渠道的最大佣金比例");
-			}
-		}
-		try {
-			channel.setUserId(oldChannel.getUserId());
-			channelService.updateChannel(channel, mobileChange);
-		} catch (Exception e) {
-			return AjaxResult.error(e.getMessage());
-		}
-		return AjaxResult.success("渠道'" + channel.getName() + "'编辑成功");
-	}
+        // 查询子渠道的最大佣金比例
+        QueryWrapper<Channel> queryWrapper = new QueryWrapper<Channel>();
+        queryWrapper.select("IFNULL(max(comm_rate),0) as commRate");
+        queryWrapper.lambda().eq(Channel::getParentId, channel.getChannelId());
+        Map<String, Object> map = channelService.getMap(queryWrapper);
+        if (null != map && map.containsKey("commRate")) {
+            BigDecimal commRate = new BigDecimal(map.get("commRate").toString());
+            if (!commRate.equals(BigDecimal.ZERO) && channel.getCommRate().compareTo(commRate) < 0) {
+                return AjaxResult.error("不能低于其子渠道的最大佣金比例");
+            }
+        }
+        try {
+            channel.setUserId(oldChannel.getUserId());
+            channelService.updateChannel(channel, mobileChange);
+        } catch (Exception e) {
+            return AjaxResult.error(e.getMessage());
+        }
+        return AjaxResult.success("渠道'" + channel.getName() + "'编辑成功");
+    }
 
 
-	/**
-	 * 停用、启用渠道
-	 * @param
-	 * @return
-	 */
-	@Log(title = "启停渠道", businessType = BusinessType.UPDATE)
-	@ApiOperation(value = "停用、启用渠道信息", notes = "渠道管理编辑子渠道")
-	@PostMapping("/status")
-	@PreAuthorize("@ss.hasPermi('business:channel:edit')")
-	public AjaxResult channelStatus(@RequestBody JSONObject jsonObject) {
-		String channelId = jsonObject.containsKey("channelId")?jsonObject.get("channelId").toString():"";
-		String status = jsonObject.containsKey("status")?jsonObject.get("status").toString():"";
-		if (null == jsonObject || StringUtils.isBlank(channelId)
-				|| StringUtils.isBlank(status)) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		try {
-			channelService.lambdaUpdate().set(Channel::getStatus, status).eq(Channel::getChannelId, channelId).update();
-		} catch (Exception e) {
-			return AjaxResult.error("操作失败");
-		}
-		return AjaxResult.success("操作成功");
-	}
+    /**
+     * 停用、启用渠道
+     *
+     * @param
+     * @return
+     */
+    @Log(title = "启停渠道", businessType = BusinessType.UPDATE)
+    @ApiOperation(value = "停用、启用渠道信息", notes = "渠道管理编辑子渠道")
+    @PostMapping("/status")
+    @PreAuthorize("@ss.hasPermi('business:channel:edit')")
+    public AjaxResult channelStatus(@RequestBody JSONObject jsonObject) {
+        String channelId = jsonObject.containsKey("channelId") ? jsonObject.get("channelId").toString() : "";
+        String status = jsonObject.containsKey("status") ? jsonObject.get("status").toString() : "";
+        if (null == jsonObject || StringUtils.isBlank(channelId)
+            || StringUtils.isBlank(status)) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+        try {
+            channelService.lambdaUpdate().set(Channel::getStatus, status).eq(Channel::getChannelId, channelId).update();
+        } catch (Exception e) {
+            return AjaxResult.error("操作失败");
+        }
+        return AjaxResult.success("操作成功");
+    }
 
 
-	/**
-	 * 查询渠道详情
-	 * @param
-	 * @return
-	 */
-	@ApiOperation(value = "查询渠道详情信息", notes = "渠道管理编辑子渠道查询渠道详情")
-	@PostMapping("/detail")
-	@PreAuthorize("@ss.hasPermi('business:channel:query')")
-	public AjaxResult getChannelDetail(@RequestBody JSONObject jsonObject) {
-		String channelId = (null != jsonObject && jsonObject.containsKey("channelId"))?jsonObject.getString("channelId"):"";
-		if (StringUtils.isBlank(channelId)) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		ChannelVO channelVO = channelService.getChannelVoById(Long.valueOf(channelId));
-		if(null == channelVO || null == channelVO.getChannelId()) {
-			 return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		if(null != channelVO && StringUtils.isNotBlank(channelVO.getChannelNo())) {
-			int siteCnt = channelService.getChannelSiteCnt(channelVO.getChannelNo());
-			int userCnt = channelUserRelService.getChannelTotalUserCnt(channelVO.getChannelNo());
-			channelVO.setSiteCnt(siteCnt);
-			channelVO.setUserCnt(userCnt);
-			channelVO.setParentsName(getParentsName(channelVO.getChannelNo()));
-		}
-	    // 查询渠道销售额、佣金收入、订单数等
-	    ChannelOperDataVO channelOperDataVO = channelService.getChannelTotalOperData(channelVO.getChannelNo());
-		// LambdaQueryWrapper<ChannelOrder> queryWrapper = new LambdaQueryWrapper<ChannelOrder>();
-		//queryWrapper.eq(ChannelOrder::getChannelId, channelId);
-		//int orderCnt = channelOrderService.count(queryWrapper);
-		//channelOperDataVO.setOrderCnt(orderCnt);
+    /**
+     * 查询渠道详情
+     *
+     * @param
+     * @return
+     */
+    @ApiOperation(value = "查询渠道详情信息", notes = "渠道管理编辑子渠道查询渠道详情")
+    @PostMapping("/detail")
+    @PreAuthorize("@ss.hasPermi('business:channel:query')")
+    public AjaxResult getChannelDetail(@RequestBody JSONObject jsonObject) {
+        String channelId =
+            (null != jsonObject && jsonObject.containsKey("channelId")) ? jsonObject.getString("channelId") : "";
+        if (StringUtils.isBlank(channelId)) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+        ChannelVO channelVO = channelService.getChannelVoById(Long.valueOf(channelId));
+        if (null == channelVO || null == channelVO.getChannelId()) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+        if (null != channelVO && StringUtils.isNotBlank(channelVO.getChannelNo())) {
+            int siteCnt = channelService.getChannelSiteCnt(channelVO.getChannelNo());
+            int userCnt = channelUserRelService.getChannelTotalUserCnt(channelVO.getChannelNo());
+            channelVO.setSiteCnt(siteCnt);
+            channelVO.setUserCnt(userCnt);
+            channelVO.setParentsName(getParentsName(channelVO.getChannelNo()));
+        }
+        // 查询渠道销售额、佣金收入、订单数等
+        ChannelOperDataVO channelOperDataVO = channelService.getChannelTotalOperData(channelVO.getChannelNo());
+        // LambdaQueryWrapper<ChannelOrder> queryWrapper = new LambdaQueryWrapper<ChannelOrder>();
+        //queryWrapper.eq(ChannelOrder::getChannelId, channelId);
+        //int orderCnt = channelOrderService.count(queryWrapper);
+        //channelOperDataVO.setOrderCnt(orderCnt);
 
-		// 盲票销量
-		int ticketSaleCnt = userTicketOrderService.getChannelTotalTicketNumCnt(channelVO.getChannelNo());
-		channelOperDataVO.setTicketSaleCnt(ticketSaleCnt);
-	    channelVO.setOperData(channelOperDataVO);
-		return AjaxResult.success(channelVO);
-	}
+        // 盲票销量
+        int ticketSaleCnt = userTicketOrderService.getChannelTotalTicketNumCnt(channelVO.getChannelNo());
+        channelOperDataVO.setTicketSaleCnt(ticketSaleCnt);
+        channelVO.setOperData(channelOperDataVO);
+        return AjaxResult.success(channelVO);
+    }
 
 
-	// 获取上级渠道迭代
-	private String getParentsName(String channelNo) {
-		if(StringUtils.isNotBlank(channelNo)) {
-			String[] noArray = channelNo.split("\\.");
-			if(null != noArray && noArray.length > 0) {
-				List<String> noList = new ArrayList<String>();
-				String parentNo = "";
-				for (int i = 0; i < noArray.length; i++) {
-					if(null != noArray[i] && StringUtils.isNotBlank(noArray[i])) {
-						parentNo += (i>0?".":"")+noArray[i];
-						if(StringUtils.isNotBlank(parentNo) && !parentNo.equals(channelNo)) {
-							noList.add(parentNo);
-						}
-					}
-				}
-				if(noList.size() > 0 ) {
-					LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<Channel>();
-					queryWrapper.gt(Channel::getLevel, 0);
-					queryWrapper.in(Channel::getChannelNo,noList);
-					queryWrapper.orderByAsc(Channel::getLevel);
-					List<Channel> list = channelService.list(queryWrapper);
-					if(null != list && list.size() >0) {
-						String names = list.stream().map(Channel::getName).collect(Collectors.joining(" > "));
-						return names;
-					}
-				}
-			}
-		}
-		return "";
-	}
+    // 获取上级渠道迭代
+    private String getParentsName(String channelNo) {
+        if (StringUtils.isNotBlank(channelNo)) {
+            String[] noArray = channelNo.split("\\.");
+            if (null != noArray && noArray.length > 0) {
+                List<String> noList = new ArrayList<String>();
+                String parentNo = "";
+                for (int i = 0; i < noArray.length; i++) {
+                    if (null != noArray[i] && StringUtils.isNotBlank(noArray[i])) {
+                        parentNo += (i > 0 ? "." : "") + noArray[i];
+                        if (StringUtils.isNotBlank(parentNo) && !parentNo.equals(channelNo)) {
+                            noList.add(parentNo);
+                        }
+                    }
+                }
+                if (noList.size() > 0) {
+                    LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<Channel>();
+                    queryWrapper.gt(Channel::getLevel, 0);
+                    queryWrapper.in(Channel::getChannelNo, noList);
+                    queryWrapper.orderByAsc(Channel::getLevel);
+                    List<Channel> list = channelService.list(queryWrapper);
+                    if (null != list && list.size() > 0) {
+                        String names = list.stream().map(Channel::getName).collect(Collectors.joining(" > "));
+                        return names;
+                    }
+                }
+            }
+        }
+        return "";
+    }
 
 }

+ 62 - 0
mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/PromoterMsgController.java

@@ -0,0 +1,62 @@
+package com.qs.mp.web.controller.api.admin;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.qs.mp.channel.domain.Channel;
+import com.qs.mp.channel.domain.param.PromoterListQueryParam;
+import com.qs.mp.channel.domain.vo.PromoterListVO;
+import com.qs.mp.channel.service.IChannelService;
+import com.qs.mp.common.core.domain.AjaxResult;
+import com.qs.mp.common.core.page.TableDataInfo;
+import com.qs.mp.web.controller.common.BaseApiController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.number.AbstractNumberFormatter;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 推广员管理API
+ *
+ * @author Cup
+ * @date 2022/8/9
+ */
+@Api(tags = "推广员管理API")
+@RestController
+@RequestMapping("/api/v1/mp/admin/promoter")
+public class PromoterMsgController extends BaseApiController {
+
+
+    @Autowired
+    private IChannelService channelService;
+
+    @PostMapping("/list")
+    @ApiOperation("推广员列表")
+    @ApiResponses(
+        @ApiResponse(code = 200, message = "推广员列表", response = PromoterListVO.class)
+    )
+    public TableDataInfo list(@RequestBody PromoterListQueryParam param) {
+        startPage();
+        QueryWrapper<Channel> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("t1.level", -1);
+        queryWrapper.eq("t1.is_deleted", 0);
+
+        queryWrapper.like(StringUtils.isNotBlank(param.getSiteName()), "t2.site_name", param.getSiteName());
+        queryWrapper.like(StringUtils.isNotBlank(param.getName()), "t1.name", param.getName());
+        queryWrapper.eq(StringUtils.isNotBlank(param.getMobile()), "t1.mobile", param.getMobile());
+
+        if (param.getStartDate() != null && param.getEndDate() != null) {
+            queryWrapper.between("t1.created_time", param.getStartDate(), param.getEndDate());
+        }
+
+        List<PromoterListVO> list = channelService.listPromoterByQueryWrapper(queryWrapper);
+        return getDataTable(list);
+    }
+
+}

+ 709 - 649
mp-admin/src/main/java/com/qs/mp/web/controller/api/channel/ChannelController.java

@@ -1,5 +1,6 @@
 package com.qs.mp.web.controller.api.channel;
 
+import com.alibaba.druid.sql.visitor.functions.If;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -10,6 +11,8 @@ import com.qs.mp.channel.domain.ChannelCommission;
 import com.qs.mp.channel.domain.ChannelOrderDetail;
 import com.qs.mp.channel.domain.ChannelUserRel;
 import com.qs.mp.channel.domain.param.ChannelParam;
+import com.qs.mp.channel.domain.param.PromoterCreateParam;
+import com.qs.mp.channel.domain.param.PromoterQueryParam;
 import com.qs.mp.channel.domain.param.SiteQueryParam;
 import com.qs.mp.channel.domain.param.VerifyParam;
 import com.qs.mp.channel.domain.vo.ChannelOperDataVO;
@@ -28,6 +31,7 @@ import com.qs.mp.common.enums.ErrorCodeEnum;
 import com.qs.mp.common.exception.ServiceException;
 import com.qs.mp.common.exception.base.BaseException;
 import com.qs.mp.common.utils.DateUtils;
+import com.qs.mp.system.domain.SysUser;
 import com.qs.mp.system.service.ISysUserService;
 import com.qs.mp.user.domain.UserAddr;
 import com.qs.mp.user.domain.UserTicketOrder;
@@ -37,6 +41,8 @@ import com.qs.mp.utils.SecurityUtils;
 import com.qs.mp.web.controller.common.BaseApiController;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
 import ma.glasnost.orika.MapperFacade;
 
 import java.math.BigDecimal;
@@ -51,9 +57,11 @@ import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.parameters.P;
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
 import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -64,664 +72,716 @@ import org.springframework.web.bind.annotation.RestController;
  * @create 2022-02-28 16:17:48
  * @describe 渠道管理前端控制器
  */
-@Api("渠道管理API")
+@Api(tags = "渠道管理API")
 @RestController
 @RequestMapping("/api/v1/mp/channel/*")
 @Component
 public class ChannelController extends BaseApiController {
 
-	@Autowired
-	private IChannelService channelService;
+    @Autowired
+    private IChannelService channelService;
 
-	@Autowired
-	private IChannelCommissionService channelCommissionService;
+    @Autowired
+    private IChannelCommissionService channelCommissionService;
 
-	@Autowired
-	private IChannelUserRelService channelUserRelService;
+    @Autowired
+    private IChannelUserRelService channelUserRelService;
 
     @Autowired
     private ISysUserService userService;
 
-	@Autowired
-	private IUserTicketOrderService userTicketOrderService;
-
-	@Autowired
-	private ITicketService ticketService;
-
-	@Autowired
-	private MapperFacade mapperFacade;
-
-	@Autowired
-	private IUserAddrService userAddrService;
-
-	/**
-	 * 获取我的下级渠道列表信息,支持翻页
-	 *
-	 * @return
-	 */
-	@PostMapping("subchannel/list")
-	public TableDataInfo listChannel(@RequestBody Channel channel) {
-		Long channelId = SecurityUtils.getLoginUser().getChannelId();
-		List<ChannelVO> list = new ArrayList<ChannelVO>();
-		if(null != channelId) {
-			channel.setParentId(channelId);
-			startPage();
-			QueryWrapper<Channel> queryWrapper = new QueryWrapper<>();
-			queryWrapper.eq("t1.parent_id", channel.getParentId());
-			queryWrapper.gt("t1.level", 0);
-			queryWrapper.orderByAsc("t1.channel_id");
-			list = channelService.selectChannelVoList(queryWrapper);
-			if(null != list && list.size() > 0) {
-				for(ChannelVO channelVO : list) {
-					if(null != channelVO && StringUtils.isNotBlank(channelVO.getChannelNo())) {
-						int siteCnt = channelService.getChannelSiteCnt(channelVO.getChannelNo());
-						int userCnt = channelUserRelService.getChannelTotalUserCnt(channelVO.getChannelNo());
-						channelVO.setSiteCnt(siteCnt);
-						channelVO.setUserCnt(userCnt);
-					}
-				}
-			}
-		}
-		return getDataTable(list);
-	}
-
-	/**
-	 * 获取我的下级渠道详情信息
-	 *
-	 * @param
-	 * @return
-	 */
-	@PostMapping(value = "subchannel/detail")
-	public AjaxResult getChannelDetail(@RequestBody Channel channel) {
-		if (null == channel || null == channel.getChannelId()) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		Long parentlId = SecurityUtils.getLoginUser().getChannelId();
-		ChannelVO channelVO = new ChannelVO();
-		Channel queryChannel = channelService.getById(channel.getChannelId());
-		if(null == queryChannel || null == queryChannel.getChannelId()) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		if(!parentlId.equals(queryChannel.getParentId())) {
-			return AjaxResult.error("非当前用户的下级,查询失败");
-		}
-	    BeanUtils.copyProperties(queryChannel, channelVO);
-	    // 查询今日的销售额、佣金收入、新增用户数
-	    ChannelOperDataVO channelOperDataVO = channelService.getChannelOperData(channelVO.getChannelNo(), 1);
-	    channelVO.setOperData(channelOperDataVO);
-		return AjaxResult.success(channelVO);
-	}
-
-	/**
-	 * 新增子渠道信息
-	 * @param
-	 * @return
-	 */
-	@ApiOperation(value = "新增子渠道信息", notes = "渠道端新增子渠道")
-	@PostMapping("subchannel/create")
-	public AjaxResult channelCreate(@Validated @RequestBody ChannelParam channelParam) {
-		if (channelParam.getChannelId() != null && channelParam.getChannelId() != 0) {
-			return AjaxResult.error("该代理已存在");
-		}
-		Long channelId = SecurityUtils.getLoginUser().getChannelId();
-		Channel existChannel = channelService.getById(channelId);
-		if (existChannel.getStatus() == ChannelStatusEnum.OFF) {
-			return AjaxResult.error("账号异常");
-		}
-		Channel channel = mapperFacade.map(channelParam, Channel.class);
-		channel.setParentId(channelId);
-		// 1、校验名称是否重复、手机号是否存在(渠道表)
-		LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<>();
-		queryWrapper.eq(Channel::getName, channel.getName());
-		queryWrapper.gt(Channel::getLevel, 0);
-		int nameCount = channelService.count(queryWrapper);
-		if(nameCount > 0) {
-			return AjaxResult.error("代理名称" + channel.getName() + "已存在!");
-		}
-		int mobileCount = channelService.count(
-		        new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, channel.getMobile()));
-		if(mobileCount > 0) {
-			 return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
-		}
-		// 2.校验佣金比例,不能高于其父渠道的佣金比例
-		Channel parentChannel = channelService.getById(channel.getParentId());
-		if(null != parentChannel && null != parentChannel.getCommRate()) {
-			 if(channel.getCommRate().compareTo(parentChannel.getCommRate()) > 0) {
-				 return AjaxResult.error("佣金比例不能高于上级代理的佣金比例");
-			 }
-		}
-		channel.setLevel(parentChannel.getLevel()+1);
-		// 3.插入数据
-		channel.setChannelNo(parentChannel.getChannelNo()+".");
-		try {
-			channelService.saveChannel(channel, ChannelRoleEnum.CHANNEL);
-		} catch (Exception e) {
-			return AjaxResult.error("代理'" + channel.getName() + "'新增失败" + e.getMessage());
-		}
-
-		return AjaxResult.success("代理'" + channel.getName() + "'新增成功");
-	}
-
-	/**
-	 * 编辑子渠道信息
-	 * @param
-	 * @return
-	 */
-	@ApiOperation(value = "编辑子渠道信息", notes = "渠道端编辑子渠道")
-	@PostMapping("subchannel/update")
-	public AjaxResult channelUpdate(@Validated @RequestBody ChannelParam channelParam) {
-
-		if (null == channelParam || null == channelParam.getChannelId()) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-
-		Channel channel = mapperFacade.map(channelParam, Channel.class);
-		// 1、校验修改子渠道是否为当前用户的子渠道
-		Channel oldChannel = channelService.getById(channel.getChannelId());
-		if(null == oldChannel || null == oldChannel.getChannelId()) {
-			return AjaxResult.error("代理'" + oldChannel.getName() + "'编辑失败");
-		}
-		Long channelId = SecurityUtils.getLoginUser().getChannelId();
-		Channel existChannel = channelService.getById(channelId);
-		if (existChannel.getStatus() == ChannelStatusEnum.OFF) {
-			return AjaxResult.error("账号异常");
-		}
-		if(!oldChannel.getParentId().equals(channelId)) {
-			return AjaxResult.error("代理'" + oldChannel.getName() + "'编辑失败");
-		}
-		// 2.校验名称是否重复、手机号是否存在(渠道表);
-		if(!channel.getName().equals(oldChannel.getName())) {
-			LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<>();
-			queryWrapper.eq(Channel::getName, channel.getName());
-			queryWrapper.gt(Channel::getLevel, 0);
-			int nameCount = channelService.count(queryWrapper);
-			if(nameCount > 0) {
-				return AjaxResult.error("代理名称" + channel.getName() + "已存在!");
-			}
-		}
-		boolean mobileChange = false;  // 手机号码是否有变更
-		if(!channel.getMobile().equals(oldChannel.getMobile())) {
-			int mobileCount = channelService.count(
-			        new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, channel.getMobile()));
-			if(mobileCount > 0) {
-				return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
-			}
-			if(UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(channel.getMobile()))) {
-				return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
-			}
-			mobileChange = true;
-		}
-		// 3.校验佣金比例,不能高于其父渠道的佣金比例,不能低于其子渠道的最大佣金比例
-		Channel parentChannel = channelService.getById(oldChannel.getParentId());
-		if(null != parentChannel && null != parentChannel.getCommRate()) {
-			 if(channel.getCommRate().compareTo(parentChannel.getCommRate()) > 0) {
-				 return AjaxResult.error("佣金比例不能高于上级代理的佣金比例");
-			 }
-		}
-		// 查询子渠道的最大佣金比例
-		QueryWrapper<Channel> queryWrapper = new QueryWrapper<Channel>();
-		queryWrapper.select("IFNULL(max(comm_rate),0) as commRate");
-		queryWrapper.lambda().eq(Channel::getParentId, channel.getChannelId());
-		Map<String, Object> map = channelService.getMap(queryWrapper);
-		if(null != map && map.containsKey("commRate")) {
-			BigDecimal commRate = new BigDecimal(map.get("commRate").toString());
-			if(!commRate.equals(BigDecimal.ZERO) && channel.getCommRate().compareTo(commRate) < 0) {
-				return AjaxResult.error("不能低于其下级的最大佣金比例");
-			}
-		}
-		try {
-			channel.setUserId(oldChannel.getUserId());
-			channelService.updateChannel(channel, mobileChange);
-		} catch (Exception e) {
-			return AjaxResult.error(e.getMessage());
-		}
-		return AjaxResult.success("代理'" + channel.getName() + "'编辑成功");
-	}
-
-
-	/**
-	 *获取当前用户渠道或者某个子渠道的经营数据
-	 *
-	 * @param
-	 * @return
-	 */
-	@PostMapping(value = "subchannel/operdata/query")
-	public AjaxResult getOperData(@RequestBody JSONObject jsonObject) {
-		if (null == jsonObject) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		Long channelId = SecurityUtils.getLoginUser().getChannelId();
-		int days = jsonObject.getIntValue("days");;
-		if(StringUtils.isNotBlank(jsonObject.getString("channelId"))) {
-			Long _channelId = jsonObject.getLong("channelId");
-			Channel queryChannel = channelService.getById(_channelId);
-			if(null == queryChannel || null == queryChannel.getChannelId()) {
-				return error(ErrorCodeEnum.ERROR_CODE_1001);
-			}
-			if(!channelId.equals(queryChannel.getParentId())) {
-				return AjaxResult.error("非当前用户的下级,查询失败");
-			}
-			channelId = _channelId;
-		}
-		days = days > 0?days:1;
-		Channel channel = channelService.getById(channelId);
-		// 查询今日的销售额、佣金收入、新增用户数
-		ChannelOperDataVO channelOperDataVO = channelService.getChannelOperData(channel.getChannelNo(), days);
-		return AjaxResult.success(channelOperDataVO);
-	}
-
-	/**
-	 * 获取子渠道的经营数据列表
-	 *
-	 * @param
-	 * @return
-	 */
-	@PostMapping(value = "subchannel/operdata/list")
-	public TableDataInfo getOperDataList(@RequestBody JSONObject jsonObject) {
-		Long channelId = SecurityUtils.getLoginUser().getChannelId();
-		int days = jsonObject.getIntValue("days");;
-		if(StringUtils.isNotBlank(jsonObject.getString("channelId"))) {
-			channelId = jsonObject.getLong("channelId");
-		}
-		days = days > 0?days:1;
-		startPage();
-		List<Channel> list = channelService.list(
-		        new LambdaQueryWrapper<Channel>().eq(Channel::getParentId, channelId).gt(Channel::getLevel, 0)
-		            .orderByDesc(Channel::getChannelId));
-
-		List<ChannelOperDataVO> dataList = new ArrayList<ChannelOperDataVO>();
-		if(null != list && list.size() > 0) {
-			for(Channel channel : list) {
-				if(null != channel && null != channel.getChannelNo()) {
-				    // 查询今日的销售额、佣金收入、新增用户数
-				    ChannelOperDataVO channelOperDataVO = channelService.getChannelOperData(channel.getChannelNo(), days);
-				    if(null != channelOperDataVO) {
-				    	channelOperDataVO.setName(channel.getName());
-							channelOperDataVO.setMobile(channel.getMobile());
-				    	dataList.add(channelOperDataVO);
-				    }
-				}
-			}
-		}
-		TableDataInfo resData = getDataTable(list);
-		resData.setRows(dataList);
-		return resData;
-	}
-
-
-	/**
-	 * 获取我的经销商列表信息,支持翻页
-	 *
-	 * @return
-	 */
-	@PostMapping("site/list")
-	public TableDataInfo listSite(@RequestBody SiteQueryParam siteParam) {
-		Long channelId = SecurityUtils.getLoginUser().getChannelId();
-		List<ChannelVO> list = new ArrayList<ChannelVO>();
-		if(null != channelId) {
-			startPage();
-			QueryWrapper<Channel> queryWrapper = new QueryWrapper<>();
-			queryWrapper.eq("t1.parent_id", channelId);
-			queryWrapper.eq("t1.level", 0);
-			if(!CollectionUtils.isEmpty(siteParam.getVerifyStatus())) {
-				queryWrapper.in("t1.verify_status", siteParam.getVerifyStatus());
-			}
-			if(StringUtils.isNotBlank(siteParam.getCertifyStatus())) {
-				queryWrapper.eq("t1.certify_status", siteParam.getCertifyStatus());
-			}
-			list = channelService.selectChannelVoList(queryWrapper);
-
-			List<Long> channelIds = new ArrayList<Long>();
-			if(null != list && list.size() > 0) {
-				for(ChannelVO channelVO : list) {
-					if(null != channelVO && null != channelVO.getChannelId()
-							&& StringUtils.isNotBlank(channelVO.getChannelNo())) {
-						channelIds.add(channelVO.getChannelId());
-	 				}
-				}
-			}
-			List<TicketCntVO>  qtyCntList = new ArrayList<TicketCntVO>();
-			List<TicketCntVO>  saleCntList = new ArrayList<TicketCntVO>();
-			if(null != channelIds && channelIds.size() > 0) {
-				QueryWrapper<ChannelOrderDetail> ticketQtyCntQueryWrapper = new QueryWrapper<ChannelOrderDetail>();
-				ticketQtyCntQueryWrapper.in("t1.channel_id", channelIds);
-				qtyCntList = ticketService.listTicketQtyCnt(ticketQtyCntQueryWrapper);
-
-		    	QueryWrapper<UserTicketOrder> ticketSaleCntQueryWrapper = new QueryWrapper<UserTicketOrder>();
-		    	ticketSaleCntQueryWrapper.in("t1.channel_id", channelIds);
-		    	ticketSaleCntQueryWrapper.eq("t1.`status`", 1);
-		    	saleCntList = userTicketOrderService.listTicketSaleCnt(ticketSaleCntQueryWrapper);
-			}
-
-			if(null != list && list.size() > 0) {
-				for(ChannelVO channelVO : list) {
-					if(null != channelVO && null != channelVO.getChannelId()
-							&& StringUtils.isNotBlank(channelVO.getChannelNo())) {
-						// int siteCnt = channelService.getChannelSiteCnt(channelVO.getChannelNo());
-						LambdaQueryWrapper<ChannelUserRel> userCntQueryWrapper = new LambdaQueryWrapper<ChannelUserRel>();
-						userCntQueryWrapper.eq(ChannelUserRel::getChannelId, channelVO.getChannelId());
-						int userCnt = channelUserRelService.count(userCntQueryWrapper);
-						channelVO.setUserCnt(userCnt);
-						// 统计盲票库存, 销量
-						if(null != qtyCntList && qtyCntList.size() > 0) {
-							List<TicketCntVO> voList =  qtyCntList.stream().filter(item  -> item.getChannelId().equals(channelVO.getChannelId()))
-					                .collect(Collectors.toList());
-							if(null != voList && voList.size() > 0) {
-								TicketCntVO ticketQtyCnt =  voList.get(0);
-								channelVO.setOffLineQtyCnt(null != ticketQtyCnt?ticketQtyCnt.getOffLineQtyCnt():0);
-							}
-						}
-						if(null != saleCntList && saleCntList.size() > 0) {
-							List<TicketCntVO> voList =  saleCntList.stream().filter(item  -> item.getChannelId().equals(channelVO.getChannelId()))
-					                .collect(Collectors.toList());
-							if(null != voList && voList.size() > 0) {
-								TicketCntVO ticketSaleCnt =  voList.get(0);
-								channelVO.setOffLineSaleCnt(null != ticketSaleCnt?ticketSaleCnt.getOffLineSaleCnt():0);
-								channelVO.setOnLineSaleCnt(null != ticketSaleCnt?ticketSaleCnt.getOnLineSaleCnt():0);
-							}
-						}
-	 				}
-				}
-			}
-
-		}
-		return getDataTable(list);
-	}
-
-	/**
-	 * 获取我的下级渠道详情信息
-	 *
-	 * @param
-	 * @return
-	 */
-	@PostMapping(value = "site/detail")
-	public AjaxResult getSiteDetail(@RequestBody Channel channel) {
-		if (null == channel || null == channel.getChannelId()) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		Long parentlId = SecurityUtils.getLoginUser().getChannelId();
-		ChannelVO channelVO = new ChannelVO();
-		Channel queryChannel = channelService.getById(channel.getChannelId());
-		if(null == queryChannel || null == queryChannel.getChannelId()) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		if(!parentlId.equals(queryChannel.getParentId())) {
-			return AjaxResult.error("非当前用户的门店,查询失败");
-		}
-	    BeanUtils.copyProperties(queryChannel, channelVO);
-	    // 查询今日的销售额、佣金收入、新增用户数
-	    ChannelOperDataVO channelOperDataVO = channelService.getChannelOperData(channelVO.getChannelNo(), 1);
-	    channelVO.setOperData(channelOperDataVO);
-	    if(null != channelVO && null != channelVO.getChannelId()) {
-
-	    	LambdaQueryWrapper<ChannelUserRel> userCntQueryWrapper = new LambdaQueryWrapper<ChannelUserRel>();
-			userCntQueryWrapper.eq(ChannelUserRel::getChannelId, channelVO.getChannelId());
-			int userCnt = channelUserRelService.count(userCntQueryWrapper);
-			channelVO.setUserCnt(userCnt);
-
-	    	int ticketQtyCnt = ticketService.getTicketQtyCnt(channelVO.getChannelId());
-	    	channelVO.setOffLineQtyCnt(ticketQtyCnt);
-
-	    	TicketCntVO ticketSaleCnt = userTicketOrderService.getTicketSaleCnt(channelVO.getChannelId());
-			channelVO.setOffLineSaleCnt(null != ticketSaleCnt?ticketSaleCnt.getOffLineSaleCnt():0);
-			channelVO.setOnLineSaleCnt(null != ticketSaleCnt?ticketSaleCnt.getOnLineSaleCnt():0);
-	    }
-
-		return AjaxResult.success(channelVO);
-	}
-
-	/**
-	 * 新增经销商信息
-	 * @param
-	 * @return
-	 */
-	@ApiOperation(value = "渠道端新增经销商", notes = "渠道端新增经销商")
-	@PostMapping("site/create")
-	public AjaxResult siteCreate(@Validated @RequestBody ChannelParam channelParam) {
-		if (channelParam.getChannelId() != null && channelParam.getChannelId() != 0) {
-			return AjaxResult.error("该门店已存在");
-		}
-		Long channelId = SecurityUtils.getLoginUser().getChannelId();
-		Channel existChannel = channelService.getById(channelId);
-		if (existChannel.getStatus() == ChannelStatusEnum.OFF) {
-			return AjaxResult.error("账号异常");
-		}
-
-		Channel channel = mapperFacade.map(channelParam, Channel.class);
-		channel.setParentId(channelId);
-		// 1、校验名称是否重复、手机号是否存在(渠道表)
-		LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<>();
-		queryWrapper.eq(Channel::getName, channel.getName());
-		queryWrapper.eq(Channel::getLevel, 0);
-		int nameCount = channelService.count(queryWrapper);
-		if(nameCount > 0) {
-			return AjaxResult.error("门店名称" + channel.getName() + "已存在!");
-		}
-		int mobileCount = channelService.count(
-		        new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, channel.getMobile()));
-		if(mobileCount > 0) {
-			 return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
-		}
-		// 2.校验佣金比例,不能高于其父渠道的佣金比例
-		Channel parentChannel = channelService.getById(channel.getParentId());
-		if(null != parentChannel && null != parentChannel.getCommRate()) {
-			 if(channel.getCommRate().compareTo(parentChannel.getCommRate()) > 0) {
-				 return AjaxResult.error("佣金比例不能高于上级代理的佣金比例");
-			 }
-		}
-		channel.setLevel(0);
-		// 3.插入数据
-		channel.setChannelNo(parentChannel.getChannelNo()+".");
-		try {
-			channelService.saveChannel(channel,ChannelRoleEnum.SALESITE);
-		} catch (Exception e) {
-			return AjaxResult.error("门店'" + channel.getName() + "'新增失败"+e.getMessage());
-		}
-		return AjaxResult.success("门店'" + channel.getName() + "'新增成功");
-	}
-
-	/**
-	 * 编辑经销商信息
-	 * @param
-	 * @return
-	 */
-	@ApiOperation(value = "编辑经销商信息", notes = "渠道端编辑经销商")
-	@PostMapping("site/update")
-	public AjaxResult siteUpdate(@Validated @RequestBody ChannelParam channelParam) {
-
-		if (null == channelParam || null == channelParam.getChannelId()) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		Channel channel = mapperFacade.map(channelParam, Channel.class);
-
-		// 1、校验修改子渠道是否为当前用户的子渠道
-		Channel oldChannel = channelService.getById(channel.getChannelId());
-		if(null == oldChannel || null == oldChannel.getChannelId()) {
-			return AjaxResult.error("门店'" + oldChannel.getName() + "'编辑失败");
-		}
-		Long channelId = SecurityUtils.getLoginUser().getChannelId();
-		Channel existChannel = channelService.getById(channelId);
-		if (existChannel.getStatus() == ChannelStatusEnum.OFF) {
-			return AjaxResult.error("账号异常");
-		}
-		if(!oldChannel.getParentId().equals(channelId)) {
-			return AjaxResult.error("门店'" + oldChannel.getName() + "'编辑失败");
-		}
-		// 2.校验名称是否重复、手机号是否存在(渠道表);
-		if(!channel.getName().equals(oldChannel.getName())) {
-
-			LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<>();
-			queryWrapper.eq(Channel::getName, channel.getName());
-			queryWrapper.eq(Channel::getLevel, 0);
-			int nameCount = channelService.count(queryWrapper);
-			if(nameCount > 0) {
-				return AjaxResult.error("门店名称" + channel.getName() + "已存在!");
-			}
-		}
-		boolean mobileChange = false;  // 手机号码是否有变更
-		if(!channel.getMobile().equals(oldChannel.getMobile())) {
-			int mobileCount = channelService.count(
-			        new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, channel.getMobile()));
-			if(mobileCount > 0) {
-				return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
-			}
-			if(UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(channel.getMobile()))) {
-				return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
-			}
-			mobileChange = true;
-		}
-		// 3.校验佣金比例,不能高于其父渠道的佣金比例,不能低于其子渠道的最大佣金比例
-		Channel parentChannel = channelService.getById(oldChannel.getParentId());
-		if(null != parentChannel && null != parentChannel.getCommRate()) {
-			 if(channel.getCommRate().compareTo(parentChannel.getCommRate()) > 0) {
-				 return AjaxResult.error("佣金比例不能高于上级代理的佣金比例");
-			 }
-		}
-		try {
-			channel.setUserId(oldChannel.getUserId());
-			channelService.updateChannel(channel, mobileChange);
-		} catch (Exception e) {
-			return AjaxResult.error("门店'" + channel.getName() + "'编辑失败");
-		}
-		return AjaxResult.success("门店'" + channel.getName() + "'编辑成功");
-	}
-
-
-	/**
-	 * 经销商认证审核
-	 * @param
-	 * @return
-	 */
-	@ApiOperation(value = "经销商认证审核", notes = "经销商认证审核")
-	@PostMapping("site/verify")
-	public AjaxResult siteVerify(@RequestBody Channel channel) {
-
-		if (null == channel || null == channel.getChannelId() || null == channel.getVerifyStatus()) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-
-		Long parentlId = SecurityUtils.getLoginUser().getChannelId();
-		Channel existChannel = channelService.getById(parentlId);
-		if (existChannel.getStatus() == ChannelStatusEnum.OFF) {
-			return AjaxResult.error("账号异常");
-		}
-		Channel queryChannel = channelService.getById(channel.getChannelId());
-		if(null == queryChannel || null == queryChannel.getChannelId()) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		if(!parentlId.equals(queryChannel.getParentId())) {
-			return AjaxResult.error(queryChannel.getName() + "非当前用户的门店, 认证审核失败");
-		}
-		try {
-			channelService.siteVerify(channel);
-		} catch (Exception e) {
-			return AjaxResult.error("门店'" + channel.getName() + "'认证审核失败");
-		}
-		return AjaxResult.success("门店'" + channel.getName() + "'认证审核成功");
-	}
-
-	/**
-	 * 经销商认证页面点提交
-	 * @param
-	 * @return
-	 */
-	@ApiOperation(value = "经销商认证信息提交", notes = "经销商认证页面点提交")
-	@PostMapping("site/verify/submit")
-	public AjaxResult siteVerifySubmit(@Validated @RequestBody VerifyParam verifyParam) {
-
-		if (null == verifyParam || null == verifyParam.getChannelId()) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		Channel channel = mapperFacade.map(verifyParam, Channel.class);
-		try {
-			channel.setVerifyStatus(ChannelVerifyStatusEnum.WAIT);
-			channelService.updateById(channel);
-		} catch (Exception e) {
-			return AjaxResult.error("门店'" + channel.getName() + "'提交认证信息失败");
-		}
-		return AjaxResult.success("门店'" + channel.getName() + "'提交认证信息成功");
-	}
-
-
-	/**
-	 * 我的(经销商)
-	 *
-	 * @param
-	 * @return
-	 */
-	@PostMapping(value = "/site/mine/detail")
-	@ApiOperation(value = "经销商查看我的信息", notes = "经销商端点击我的")
-	public AjaxResult getSiteMineDetail() {
-		Long channelId = SecurityUtils.getLoginUser().getChannelId();
-		if (null == channelId) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		ChannelVO channelVO = new ChannelVO();
-		Channel queryChannel = channelService.getById(channelId);
-	    BeanUtils.copyProperties(queryChannel, channelVO);
-	    // 查询今日的销售额、佣金收入、新增用户数
-	    Channel parentChannel = channelService.getById(queryChannel.getParentId());
-	    channelVO.setParentName(parentChannel.getName());
-		return AjaxResult.success(channelVO);
-	}
-
-	/**
-	 * 我的(渠道)
-	 *
-	 * @param
-	 * @return
-	 */
-	@PostMapping(value = "/mine/detail")
-	@ApiOperation(value = "渠道端查看我的信息", notes = "渠道端点击我的")
-	public AjaxResult getChannelMineDetail() {
-		Long channelId = SecurityUtils.getLoginUser().getChannelId();
-		if (null == channelId) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		ChannelVO channelVO = new ChannelVO();
-		Channel queryChannel = channelService.getById(channelId);
-		BeanUtils.copyProperties(queryChannel, channelVO);
-		// 查询今日的销售额、佣金收入、新增用户数
-		Channel parentChannel = channelService.getById(queryChannel.getParentId());
-		if (null != parentChannel) {
-			channelVO.setParentName(parentChannel.getName());
-		}
-		// 统计今天的分润金额
-		Date zero = DateUtils.getToday(); // 获取当天零点零分时间
-		QueryWrapper<ChannelCommission> queryWrapper = new QueryWrapper<ChannelCommission>();
-		queryWrapper.select("IFNULL(sum(comm_amt) ,0) as commAmt");
-		queryWrapper.lambda().eq(ChannelCommission::getChannelId, channelId);
-		queryWrapper.lambda().gt(ChannelCommission::getCreatedTime, zero);
-		Map<String, Object> map = channelCommissionService.getMap(queryWrapper);
-		if(null != map && map.containsKey("commAmt")) {
-			BigDecimal commAmt = new BigDecimal(map.get("commAmt").toString());
-			ChannelOperDataVO channelOperDataVO = new ChannelOperDataVO();
-			channelOperDataVO.setCommAmt(commAmt.longValue());
-			channelVO.setOperData(channelOperDataVO);
-		}
-		return AjaxResult.success(channelVO);
-	}
-
-
-	/**
-	 * 场景是这里要显示待审核数量
-	 *
-	 * @param
-	 * @return
-	 */
-	@PostMapping(value = "subchannel/index")
-	public AjaxResult getChannelIndex() {
-		int waitVerifyNum = 0;
-		Long channelId = SecurityUtils.getLoginUser().getChannelId();
-		if(null != channelId && 0 != channelId) {
-			LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<Channel>();
-			queryWrapper.eq(Channel::getParentId, channelId);
-			queryWrapper.eq(Channel::getVerifyStatus, ChannelVerifyStatusEnum.WAIT);
-			queryWrapper.eq(Channel::getLevel, 0);
-			waitVerifyNum = channelService.count(queryWrapper);
-		}
-	    Map<String,Object> map = new HashMap<String,Object>();
-	    map.put("waitVerifyNum", waitVerifyNum);
-		return AjaxResult.success(map);
-	}
+    @Autowired
+    private IUserTicketOrderService userTicketOrderService;
+
+    @Autowired
+    private ITicketService ticketService;
+
+    @Autowired
+    private MapperFacade mapperFacade;
+
+    @Autowired
+    private IUserAddrService userAddrService;
+
+
+    @PostMapping("/saleSite/info/{channelId}")
+    @ApiOperation("查询门店基本信息")
+    @ApiResponses(
+        @ApiResponse(code = 200, message = "查询成功", response = ChannelVO.class)
+    )
+    public AjaxResult saleSiteInfo(@PathVariable("channelId") Long channelId) {
+        if (channelId == null || channelId <= 0) {
+            return AjaxResult.error("门店id不正确");
+        }
+
+        Channel channel = channelService.getById(channelId);
+        if (channel == null) {
+            return AjaxResult.error("门店信息不存在");
+        }
+
+        return AjaxResult.success("操作成功", channel.getSiteName());
+    }
+
+
+    /**
+     * 获取我的下级渠道列表信息,支持翻页
+     *
+     * @return
+     */
+    @PostMapping("subchannel/list")
+    @ApiOperation("获取我的下级渠道列表信息,支持翻页")
+    @ApiResponses(
+        @ApiResponse(code = 200, message = "成功", response = ChannelVO.class)
+    )
+    public TableDataInfo listChannel(@RequestBody Channel channel) {
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        List<ChannelVO> list = new ArrayList<ChannelVO>();
+        if (null != channelId) {
+            channel.setParentId(channelId);
+            startPage();
+            QueryWrapper<Channel> queryWrapper = new QueryWrapper<>();
+            queryWrapper.eq("t1.parent_id", channel.getParentId());
+            queryWrapper.gt("t1.level", 0);
+            queryWrapper.orderByAsc("t1.channel_id");
+            list = channelService.selectChannelVoList(queryWrapper);
+            if (null != list && list.size() > 0) {
+                for (ChannelVO channelVO : list) {
+                    if (null != channelVO && StringUtils.isNotBlank(channelVO.getChannelNo())) {
+                        int siteCnt = channelService.getChannelSiteCnt(channelVO.getChannelNo());
+                        int userCnt = channelUserRelService.getChannelTotalUserCnt(channelVO.getChannelNo());
+                        channelVO.setSiteCnt(siteCnt);
+                        channelVO.setUserCnt(userCnt);
+                    }
+                }
+            }
+        }
+        return getDataTable(list);
+    }
+
+    /**
+     * 获取我的下级渠道详情信息
+     *
+     * @param
+     * @return
+     */
+    @PostMapping(value = "subchannel/detail")
+    @ApiOperation("获取我的下级渠道详情信息")
+    @ApiResponses(
+        @ApiResponse(code = 200, message = "成功", response = ChannelVO.class)
+    )
+    public AjaxResult getChannelDetail(@RequestBody Channel channel) {
+        if (null == channel || null == channel.getChannelId()) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+        Long parentlId = SecurityUtils.getLoginUser().getChannelId();
+        ChannelVO channelVO = new ChannelVO();
+        Channel queryChannel = channelService.getById(channel.getChannelId());
+        if (null == queryChannel || null == queryChannel.getChannelId()) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+        if (!parentlId.equals(queryChannel.getParentId())) {
+            return AjaxResult.error("非当前用户的下级,查询失败");
+        }
+        BeanUtils.copyProperties(queryChannel, channelVO);
+        // 查询今日的销售额、佣金收入、新增用户数
+        ChannelOperDataVO channelOperDataVO = channelService.getChannelOperData(channelVO.getChannelNo(), 1);
+        channelVO.setOperData(channelOperDataVO);
+        return AjaxResult.success(channelVO);
+    }
+
+    /**
+     * 新增子渠道信息
+     *
+     * @param
+     * @return
+     */
+    @ApiOperation(value = "新增子渠道信息", notes = "渠道端新增子渠道")
+    @PostMapping("subchannel/create")
+    public AjaxResult channelCreate(@Validated @RequestBody ChannelParam channelParam) {
+        if (channelParam.getChannelId() != null && channelParam.getChannelId() != 0) {
+            return AjaxResult.error("该代理已存在");
+        }
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        Channel existChannel = channelService.getById(channelId);
+        if (existChannel.getStatus() == ChannelStatusEnum.OFF) {
+            return AjaxResult.error("账号异常");
+        }
+        Channel channel = mapperFacade.map(channelParam, Channel.class);
+        channel.setParentId(channelId);
+        // 1、校验名称是否重复、手机号是否存在(渠道表)
+        LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(Channel::getName, channel.getName());
+        queryWrapper.gt(Channel::getLevel, 0);
+        int nameCount = channelService.count(queryWrapper);
+        if (nameCount > 0) {
+            return AjaxResult.error("代理名称" + channel.getName() + "已存在!");
+        }
+        int mobileCount = channelService.count(
+            new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, channel.getMobile()));
+        if (mobileCount > 0) {
+            return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
+        }
+        // 2.校验佣金比例,不能高于其父渠道的佣金比例
+        Channel parentChannel = channelService.getById(channel.getParentId());
+        if (null != parentChannel && null != parentChannel.getCommRate()) {
+            if (channel.getCommRate().compareTo(parentChannel.getCommRate()) > 0) {
+                return AjaxResult.error("佣金比例不能高于上级代理的佣金比例");
+            }
+        }
+        channel.setLevel(parentChannel.getLevel() + 1);
+        // 3.插入数据
+        channel.setChannelNo(parentChannel.getChannelNo() + ".");
+        try {
+            channelService.saveChannel(channel, ChannelRoleEnum.CHANNEL);
+        } catch (Exception e) {
+            return AjaxResult.error("代理'" + channel.getName() + "'新增失败" + e.getMessage());
+        }
+
+        return AjaxResult.success("代理'" + channel.getName() + "'新增成功");
+    }
+
+    /**
+     * 编辑子渠道信息
+     *
+     * @param
+     * @return
+     */
+    @ApiOperation(value = "编辑子渠道信息", notes = "渠道端编辑子渠道")
+    @PostMapping("subchannel/update")
+    public AjaxResult channelUpdate(@Validated @RequestBody ChannelParam channelParam) {
+
+        if (null == channelParam || null == channelParam.getChannelId()) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+
+        Channel channel = mapperFacade.map(channelParam, Channel.class);
+        // 1、校验修改子渠道是否为当前用户的子渠道
+        Channel oldChannel = channelService.getById(channel.getChannelId());
+        if (null == oldChannel || null == oldChannel.getChannelId()) {
+            return AjaxResult.error("代理'" + oldChannel.getName() + "'编辑失败");
+        }
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        Channel existChannel = channelService.getById(channelId);
+        if (existChannel.getStatus() == ChannelStatusEnum.OFF) {
+            return AjaxResult.error("账号异常");
+        }
+        if (!oldChannel.getParentId().equals(channelId)) {
+            return AjaxResult.error("代理'" + oldChannel.getName() + "'编辑失败");
+        }
+        // 2.校验名称是否重复、手机号是否存在(渠道表);
+        if (!channel.getName().equals(oldChannel.getName())) {
+            LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(Channel::getName, channel.getName());
+            queryWrapper.gt(Channel::getLevel, 0);
+            int nameCount = channelService.count(queryWrapper);
+            if (nameCount > 0) {
+                return AjaxResult.error("代理名称" + channel.getName() + "已存在!");
+            }
+        }
+        boolean mobileChange = false;  // 手机号码是否有变更
+        if (!channel.getMobile().equals(oldChannel.getMobile())) {
+            int mobileCount = channelService.count(
+                new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, channel.getMobile()));
+            if (mobileCount > 0) {
+                return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
+            }
+            if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(channel.getMobile()))) {
+                return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
+            }
+            mobileChange = true;
+        }
+        // 3.校验佣金比例,不能高于其父渠道的佣金比例,不能低于其子渠道的最大佣金比例
+        Channel parentChannel = channelService.getById(oldChannel.getParentId());
+        if (null != parentChannel && null != parentChannel.getCommRate()) {
+            if (channel.getCommRate().compareTo(parentChannel.getCommRate()) > 0) {
+                return AjaxResult.error("佣金比例不能高于上级代理的佣金比例");
+            }
+        }
+        // 查询子渠道的最大佣金比例
+        QueryWrapper<Channel> queryWrapper = new QueryWrapper<Channel>();
+        queryWrapper.select("IFNULL(max(comm_rate),0) as commRate");
+        queryWrapper.lambda().eq(Channel::getParentId, channel.getChannelId());
+        Map<String, Object> map = channelService.getMap(queryWrapper);
+        if (null != map && map.containsKey("commRate")) {
+            BigDecimal commRate = new BigDecimal(map.get("commRate").toString());
+            if (!commRate.equals(BigDecimal.ZERO) && channel.getCommRate().compareTo(commRate) < 0) {
+                return AjaxResult.error("不能低于其下级的最大佣金比例");
+            }
+        }
+        try {
+            channel.setUserId(oldChannel.getUserId());
+            channelService.updateChannel(channel, mobileChange);
+        } catch (Exception e) {
+            return AjaxResult.error(e.getMessage());
+        }
+        return AjaxResult.success("代理'" + channel.getName() + "'编辑成功");
+    }
+
+
+    /**
+     * 获取当前用户渠道或者某个子渠道的经营数据
+     *
+     * @param
+     * @return
+     */
+    @ApiOperation("获取当前用户渠道或者某个子渠道的经营数据")
+    @PostMapping(value = "subchannel/operdata/query")
+    public AjaxResult getOperData(@RequestBody JSONObject jsonObject) {
+        if (null == jsonObject) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        int days = jsonObject.getIntValue("days");
+        ;
+        if (StringUtils.isNotBlank(jsonObject.getString("channelId"))) {
+            Long _channelId = jsonObject.getLong("channelId");
+            Channel queryChannel = channelService.getById(_channelId);
+            if (null == queryChannel || null == queryChannel.getChannelId()) {
+                return error(ErrorCodeEnum.ERROR_CODE_1001);
+            }
+            if (!channelId.equals(queryChannel.getParentId())) {
+                return AjaxResult.error("非当前用户的下级,查询失败");
+            }
+            channelId = _channelId;
+        }
+        days = days > 0 ? days : 1;
+        Channel channel = channelService.getById(channelId);
+        // 查询今日的销售额、佣金收入、新增用户数
+        ChannelOperDataVO channelOperDataVO = channelService.getChannelOperData(channel.getChannelNo(), days);
+        return AjaxResult.success(channelOperDataVO);
+    }
+
+    /**
+     * 获取子渠道的经营数据列表
+     *
+     * @param
+     * @return
+     */
+    @ApiOperation("获取子渠道的经营数据列表")
+    @PostMapping(value = "subchannel/operdata/list")
+    public TableDataInfo getOperDataList(@RequestBody JSONObject jsonObject) {
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        int days = jsonObject.getIntValue("days");
+        ;
+        if (StringUtils.isNotBlank(jsonObject.getString("channelId"))) {
+            channelId = jsonObject.getLong("channelId");
+        }
+        days = days > 0 ? days : 1;
+        startPage();
+        List<Channel> list = channelService.list(
+            new LambdaQueryWrapper<Channel>().eq(Channel::getParentId, channelId).gt(Channel::getLevel, 0)
+                .orderByDesc(Channel::getChannelId));
+
+        List<ChannelOperDataVO> dataList = new ArrayList<ChannelOperDataVO>();
+        if (null != list && list.size() > 0) {
+            for (Channel channel : list) {
+                if (null != channel && null != channel.getChannelNo()) {
+                    // 查询今日的销售额、佣金收入、新增用户数
+                    ChannelOperDataVO channelOperDataVO = channelService.getChannelOperData(channel.getChannelNo(),
+                        days);
+                    if (null != channelOperDataVO) {
+                        channelOperDataVO.setName(channel.getName());
+                        channelOperDataVO.setMobile(channel.getMobile());
+                        dataList.add(channelOperDataVO);
+                    }
+                }
+            }
+        }
+        TableDataInfo resData = getDataTable(list);
+        resData.setRows(dataList);
+        return resData;
+    }
+
+
+    /**
+     * 获取我的经销商列表信息,支持翻页
+     *
+     * @return
+     */
+    @ApiOperation("获取我的经销商列表信息,支持翻页")
+    @PostMapping("site/list")
+    @ApiResponses(
+        @ApiResponse(code = 200, message = "成功", response = ChannelVO.class)
+    )
+    public TableDataInfo listSite(@RequestBody SiteQueryParam siteParam) {
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        List<ChannelVO> list = new ArrayList<ChannelVO>();
+        if (null != channelId) {
+            startPage();
+            QueryWrapper<Channel> queryWrapper = new QueryWrapper<>();
+            queryWrapper.eq("t1.parent_id", channelId);
+            queryWrapper.eq("t1.level", 0);
+            if (!CollectionUtils.isEmpty(siteParam.getVerifyStatus())) {
+                queryWrapper.in("t1.verify_status", siteParam.getVerifyStatus());
+            }
+            if (StringUtils.isNotBlank(siteParam.getCertifyStatus())) {
+                queryWrapper.eq("t1.certify_status", siteParam.getCertifyStatus());
+            }
+            list = channelService.selectChannelVoList(queryWrapper);
+
+            List<Long> channelIds = new ArrayList<Long>();
+            if (null != list && list.size() > 0) {
+                for (ChannelVO channelVO : list) {
+                    if (null != channelVO && null != channelVO.getChannelId()
+                        && StringUtils.isNotBlank(channelVO.getChannelNo())) {
+                        channelIds.add(channelVO.getChannelId());
+                    }
+                }
+            }
+            List<TicketCntVO> qtyCntList = new ArrayList<TicketCntVO>();
+            List<TicketCntVO> saleCntList = new ArrayList<TicketCntVO>();
+            if (null != channelIds && channelIds.size() > 0) {
+                QueryWrapper<ChannelOrderDetail> ticketQtyCntQueryWrapper = new QueryWrapper<ChannelOrderDetail>();
+                ticketQtyCntQueryWrapper.in("t1.channel_id", channelIds);
+                qtyCntList = ticketService.listTicketQtyCnt(ticketQtyCntQueryWrapper);
+
+                QueryWrapper<UserTicketOrder> ticketSaleCntQueryWrapper = new QueryWrapper<UserTicketOrder>();
+                ticketSaleCntQueryWrapper.in("t1.channel_id", channelIds);
+                ticketSaleCntQueryWrapper.eq("t1.`status`", 1);
+                saleCntList = userTicketOrderService.listTicketSaleCnt(ticketSaleCntQueryWrapper);
+            }
+
+            if (null != list && list.size() > 0) {
+                for (ChannelVO channelVO : list) {
+                    if (null != channelVO && null != channelVO.getChannelId()
+                        && StringUtils.isNotBlank(channelVO.getChannelNo())) {
+                        // int siteCnt = channelService.getChannelSiteCnt(channelVO.getChannelNo());
+                        LambdaQueryWrapper<ChannelUserRel> userCntQueryWrapper = new LambdaQueryWrapper<ChannelUserRel>();
+                        userCntQueryWrapper.eq(ChannelUserRel::getChannelId, channelVO.getChannelId());
+                        int userCnt = channelUserRelService.count(userCntQueryWrapper);
+                        channelVO.setUserCnt(userCnt);
+                        // 统计盲票库存, 销量
+                        if (null != qtyCntList && qtyCntList.size() > 0) {
+                            List<TicketCntVO> voList = qtyCntList.stream()
+                                .filter(item -> item.getChannelId().equals(channelVO.getChannelId()))
+                                .collect(Collectors.toList());
+                            if (null != voList && voList.size() > 0) {
+                                TicketCntVO ticketQtyCnt = voList.get(0);
+                                channelVO.setOffLineQtyCnt(null != ticketQtyCnt ? ticketQtyCnt.getOffLineQtyCnt() : 0);
+                            }
+                        }
+                        if (null != saleCntList && saleCntList.size() > 0) {
+                            List<TicketCntVO> voList = saleCntList.stream()
+                                .filter(item -> item.getChannelId().equals(channelVO.getChannelId()))
+                                .collect(Collectors.toList());
+                            if (null != voList && voList.size() > 0) {
+                                TicketCntVO ticketSaleCnt = voList.get(0);
+                                channelVO.setOffLineSaleCnt(
+                                    null != ticketSaleCnt ? ticketSaleCnt.getOffLineSaleCnt() : 0);
+                                channelVO.setOnLineSaleCnt(
+                                    null != ticketSaleCnt ? ticketSaleCnt.getOnLineSaleCnt() : 0);
+                            }
+                        }
+                    }
+                }
+            }
+
+        }
+        return getDataTable(list);
+    }
+
+    /**
+     * 获取我的下级渠道详情信息
+     *
+     * @param
+     * @return
+     */
+    @PostMapping(value = "site/detail")
+    @ApiOperation("获取我的下级渠道详细信息")
+    @ApiResponses(
+        @ApiResponse(code = 200, message = "成功", response = ChannelVO.class)
+    )
+    public AjaxResult getSiteDetail(@RequestBody Channel channel) {
+        if (null == channel || null == channel.getChannelId()) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+        Long parentlId = SecurityUtils.getLoginUser().getChannelId();
+        ChannelVO channelVO = new ChannelVO();
+        Channel queryChannel = channelService.getById(channel.getChannelId());
+        if (null == queryChannel || null == queryChannel.getChannelId()) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+        if (!parentlId.equals(queryChannel.getParentId())) {
+            return AjaxResult.error("非当前用户的门店,查询失败");
+        }
+        BeanUtils.copyProperties(queryChannel, channelVO);
+        // 查询今日的销售额、佣金收入、新增用户数
+        ChannelOperDataVO channelOperDataVO = channelService.getChannelOperData(channelVO.getChannelNo(), 1);
+        channelVO.setOperData(channelOperDataVO);
+        if (null != channelVO && null != channelVO.getChannelId()) {
+
+            LambdaQueryWrapper<ChannelUserRel> userCntQueryWrapper = new LambdaQueryWrapper<ChannelUserRel>();
+            userCntQueryWrapper.eq(ChannelUserRel::getChannelId, channelVO.getChannelId());
+            int userCnt = channelUserRelService.count(userCntQueryWrapper);
+            channelVO.setUserCnt(userCnt);
+
+            int ticketQtyCnt = ticketService.getTicketQtyCnt(channelVO.getChannelId());
+            channelVO.setOffLineQtyCnt(ticketQtyCnt);
+
+            TicketCntVO ticketSaleCnt = userTicketOrderService.getTicketSaleCnt(channelVO.getChannelId());
+            channelVO.setOffLineSaleCnt(null != ticketSaleCnt ? ticketSaleCnt.getOffLineSaleCnt() : 0);
+            channelVO.setOnLineSaleCnt(null != ticketSaleCnt ? ticketSaleCnt.getOnLineSaleCnt() : 0);
+        }
+
+        return AjaxResult.success(channelVO);
+    }
+
+    /**
+     * 新增经销商信息
+     *
+     * @param
+     * @return
+     */
+    @ApiOperation(value = "渠道端新增经销商", notes = "渠道端新增经销商")
+    @PostMapping("site/create")
+    public AjaxResult siteCreate(@Validated @RequestBody ChannelParam channelParam) {
+        if (channelParam.getChannelId() != null && channelParam.getChannelId() != 0) {
+            return AjaxResult.error("该门店已存在");
+        }
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        Channel existChannel = channelService.getById(channelId);
+        if (existChannel.getStatus() == ChannelStatusEnum.OFF) {
+            return AjaxResult.error("账号异常");
+        }
+
+        Channel channel = mapperFacade.map(channelParam, Channel.class);
+        channel.setParentId(channelId);
+        // 1、校验名称是否重复、手机号是否存在(渠道表)
+        LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(Channel::getName, channel.getName());
+        queryWrapper.eq(Channel::getLevel, 0);
+        int nameCount = channelService.count(queryWrapper);
+        if (nameCount > 0) {
+            return AjaxResult.error("门店名称" + channel.getName() + "已存在!");
+        }
+        int mobileCount = channelService.count(
+            new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, channel.getMobile()));
+        if (mobileCount > 0) {
+            return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
+        }
+        // 2.校验佣金比例,不能高于其父渠道的佣金比例
+        Channel parentChannel = channelService.getById(channel.getParentId());
+        if (null != parentChannel && null != parentChannel.getCommRate()) {
+            if (channel.getCommRate().compareTo(parentChannel.getCommRate()) > 0) {
+                return AjaxResult.error("佣金比例不能高于上级代理的佣金比例");
+            }
+        }
+        channel.setLevel(0);
+        // 3.插入数据
+        channel.setChannelNo(parentChannel.getChannelNo() + ".");
+        try {
+            channelService.saveChannel(channel, ChannelRoleEnum.SALESITE);
+        } catch (Exception e) {
+            return AjaxResult.error("门店'" + channel.getName() + "'新增失败" + e.getMessage());
+        }
+        return AjaxResult.success("门店'" + channel.getName() + "'新增成功");
+    }
+
+    /**
+     * 编辑经销商信息
+     *
+     * @param
+     * @return
+     */
+    @ApiOperation(value = "编辑经销商信息", notes = "渠道端编辑经销商")
+    @PostMapping("site/update")
+    public AjaxResult siteUpdate(@Validated @RequestBody ChannelParam channelParam) {
+
+        if (null == channelParam || null == channelParam.getChannelId()) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+        Channel channel = mapperFacade.map(channelParam, Channel.class);
+
+        // 1、校验修改子渠道是否为当前用户的子渠道
+        Channel oldChannel = channelService.getById(channel.getChannelId());
+        if (null == oldChannel || null == oldChannel.getChannelId()) {
+            return AjaxResult.error("门店'" + oldChannel.getName() + "'编辑失败");
+        }
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        Channel existChannel = channelService.getById(channelId);
+        if (existChannel.getStatus() == ChannelStatusEnum.OFF) {
+            return AjaxResult.error("账号异常");
+        }
+        if (!oldChannel.getParentId().equals(channelId)) {
+            return AjaxResult.error("门店'" + oldChannel.getName() + "'编辑失败");
+        }
+        // 2.校验名称是否重复、手机号是否存在(渠道表);
+        if (!channel.getName().equals(oldChannel.getName())) {
+
+            LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(Channel::getName, channel.getName());
+            queryWrapper.eq(Channel::getLevel, 0);
+            int nameCount = channelService.count(queryWrapper);
+            if (nameCount > 0) {
+                return AjaxResult.error("门店名称" + channel.getName() + "已存在!");
+            }
+        }
+        boolean mobileChange = false;  // 手机号码是否有变更
+        if (!channel.getMobile().equals(oldChannel.getMobile())) {
+            int mobileCount = channelService.count(
+                new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, channel.getMobile()));
+            if (mobileCount > 0) {
+                return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
+            }
+            if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(channel.getMobile()))) {
+                return AjaxResult.error("手机号码" + channel.getMobile() + "已注册!");
+            }
+            mobileChange = true;
+        }
+        // 3.校验佣金比例,不能高于其父渠道的佣金比例,不能低于其子渠道的最大佣金比例
+        Channel parentChannel = channelService.getById(oldChannel.getParentId());
+        if (null != parentChannel && null != parentChannel.getCommRate()) {
+            if (channel.getCommRate().compareTo(parentChannel.getCommRate()) > 0) {
+                return AjaxResult.error("佣金比例不能高于上级代理的佣金比例");
+            }
+        }
+        try {
+            channel.setUserId(oldChannel.getUserId());
+            channelService.updateChannel(channel, mobileChange);
+        } catch (Exception e) {
+            return AjaxResult.error("门店'" + channel.getName() + "'编辑失败");
+        }
+        return AjaxResult.success("门店'" + channel.getName() + "'编辑成功");
+    }
+
+
+    /**
+     * 经销商认证审核
+     *
+     * @param
+     * @return
+     */
+    @ApiOperation(value = "经销商认证审核", notes = "经销商认证审核")
+    @PostMapping("site/verify")
+    public AjaxResult siteVerify(@RequestBody Channel channel) {
+
+        if (null == channel || null == channel.getChannelId() || null == channel.getVerifyStatus()) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+
+        Long parentlId = SecurityUtils.getLoginUser().getChannelId();
+        Channel existChannel = channelService.getById(parentlId);
+        if (existChannel.getStatus() == ChannelStatusEnum.OFF) {
+            return AjaxResult.error("账号异常");
+        }
+        Channel queryChannel = channelService.getById(channel.getChannelId());
+        if (null == queryChannel || null == queryChannel.getChannelId()) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+        if (!parentlId.equals(queryChannel.getParentId())) {
+            return AjaxResult.error(queryChannel.getName() + "非当前用户的门店, 认证审核失败");
+        }
+        try {
+            channelService.siteVerify(channel);
+        } catch (Exception e) {
+            return AjaxResult.error("门店'" + channel.getName() + "'认证审核失败");
+        }
+        return AjaxResult.success("门店'" + channel.getName() + "'认证审核成功");
+    }
+
+    /**
+     * 经销商认证页面点提交
+     *
+     * @param
+     * @return
+     */
+    @ApiOperation(value = "经销商认证信息提交", notes = "经销商认证页面点提交")
+    @PostMapping("site/verify/submit")
+    public AjaxResult siteVerifySubmit(@Validated @RequestBody VerifyParam verifyParam) {
+
+        if (null == verifyParam || null == verifyParam.getChannelId()) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+        Channel channel = mapperFacade.map(verifyParam, Channel.class);
+        try {
+            channel.setVerifyStatus(ChannelVerifyStatusEnum.WAIT);
+            channelService.updateById(channel);
+        } catch (Exception e) {
+            return AjaxResult.error("门店'" + channel.getName() + "'提交认证信息失败");
+        }
+        return AjaxResult.success("门店'" + channel.getName() + "'提交认证信息成功");
+    }
+
+
+    /**
+     * 我的(经销商)
+     *
+     * @param
+     * @return
+     */
+    @PostMapping(value = "/site/mine/detail")
+    @ApiOperation(value = "经销商查看我的信息", notes = "经销商端点击我的")
+    public AjaxResult getSiteMineDetail() {
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        if (null == channelId) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+        ChannelVO channelVO = new ChannelVO();
+        Channel queryChannel = channelService.getById(channelId);
+        BeanUtils.copyProperties(queryChannel, channelVO);
+        // 查询今日的销售额、佣金收入、新增用户数
+        Channel parentChannel = channelService.getById(queryChannel.getParentId());
+        channelVO.setParentName(parentChannel.getName());
+        return AjaxResult.success(channelVO);
+    }
+
+    /**
+     * 我的(渠道)
+     *
+     * @param
+     * @return
+     */
+    @PostMapping(value = "/mine/detail")
+    @ApiOperation(value = "渠道端查看我的信息", notes = "渠道端点击我的")
+    public AjaxResult getChannelMineDetail() {
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        if (null == channelId) {
+            return error(ErrorCodeEnum.ERROR_CODE_1001);
+        }
+        ChannelVO channelVO = new ChannelVO();
+        Channel queryChannel = channelService.getById(channelId);
+        BeanUtils.copyProperties(queryChannel, channelVO);
+        // 查询今日的销售额、佣金收入、新增用户数
+        Channel parentChannel = channelService.getById(queryChannel.getParentId());
+        if (null != parentChannel) {
+            channelVO.setParentName(parentChannel.getName());
+        }
+        // 统计今天的分润金额
+        Date zero = DateUtils.getToday(); // 获取当天零点零分时间
+        QueryWrapper<ChannelCommission> queryWrapper = new QueryWrapper<ChannelCommission>();
+        queryWrapper.select("IFNULL(sum(comm_amt) ,0) as commAmt");
+        queryWrapper.lambda().eq(ChannelCommission::getChannelId, channelId);
+        queryWrapper.lambda().gt(ChannelCommission::getCreatedTime, zero);
+        Map<String, Object> map = channelCommissionService.getMap(queryWrapper);
+        if (null != map && map.containsKey("commAmt")) {
+            BigDecimal commAmt = new BigDecimal(map.get("commAmt").toString());
+            ChannelOperDataVO channelOperDataVO = new ChannelOperDataVO();
+            channelOperDataVO.setCommAmt(commAmt.longValue());
+            channelVO.setOperData(channelOperDataVO);
+        }
+        return AjaxResult.success(channelVO);
+    }
+
+
+    /**
+     * 场景是这里要显示待审核数量
+     *
+     * @param
+     * @return
+     */
+    @PostMapping(value = "subchannel/index")
+    @ApiOperation("渠道端查看子渠道列表")
+    public AjaxResult getChannelIndex() {
+        int waitVerifyNum = 0;
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        if (null != channelId && 0 != channelId) {
+            LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<Channel>();
+            queryWrapper.eq(Channel::getParentId, channelId);
+            queryWrapper.eq(Channel::getVerifyStatus, ChannelVerifyStatusEnum.WAIT);
+            queryWrapper.eq(Channel::getLevel, 0);
+            waitVerifyNum = channelService.count(queryWrapper);
+        }
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put("waitVerifyNum", waitVerifyNum);
+        return AjaxResult.success(map);
+    }
 }

+ 1 - 1
mp-admin/src/main/java/com/qs/mp/web/controller/api/channel/ChannelCouponVerifyController.java

@@ -41,7 +41,7 @@ import org.springframework.web.bind.annotation.RestController;
  * @create 2022-02-28 16:17:48
  * @describe 渠道优惠券核销前端控制器
  */
-@Api("渠道管理API")
+@Api(tags = "渠道优惠券核销API")
 @RestController
 @RequestMapping("/api/v1/mp/channel/*")
 @Component

+ 16 - 1
mp-admin/src/main/java/com/qs/mp/web/controller/api/channel/ChannelInviteController.java

@@ -16,6 +16,7 @@ import com.qs.mp.framework.web.service.SysLoginService;
 import com.qs.mp.utils.SecurityUtils;
 import com.qs.mp.web.controller.common.BaseApiController;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 import java.util.Map;
 import ma.glasnost.orika.MapperFacade;
 import org.apache.commons.lang3.StringUtils;
@@ -32,7 +33,7 @@ import org.springframework.web.bind.annotation.RestController;
  * @create 2022-02-28 16:17:48
  * @describe 渠道邀请前端控制器
  */
-@Api("渠道邀请API")
+@Api(tags = "渠道邀请API")
 @RestController
 @RequestMapping("/api/v1/mp/channel/*")
 @Component
@@ -53,6 +54,20 @@ public class ChannelInviteController extends BaseApiController {
 	@Autowired
 	private SysLoginService sysLoginService;
 
+	@PostMapping("promoter/generate")
+	@ApiOperation("生成推广员邀请注册链接")
+	public AjaxResult generatePromoterRegistry(@RequestBody  JSONObject jsonObject) {
+		Long channelId = SecurityUtils.getLoginUser().getChannelId();
+		Channel channel = channelService.getById(channelId);
+		if (channel == null) {
+			return AjaxResult.error("门店信息不正确");
+		}
+		String type = jsonObject.getString("type");
+		String commRate = jsonObject.getString("commRate");
+		String rst = wxUrlLinkService.generateCode("pages/login/invitation", "id=" + channelId + "&type=" + type + "&commRate=" + commRate, channelAppId);
+		return AjaxResult.success("", rst);
+	}
+
 	/**
 	 * 生成邀请码
 	 *

+ 221 - 0
mp-admin/src/main/java/com/qs/mp/web/controller/api/channel/PromoterController.java

@@ -0,0 +1,221 @@
+package com.qs.mp.web.controller.api.channel;
+
+import cn.jsms.api.ValidSMSResult;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.qs.mp.channel.domain.Channel;
+import com.qs.mp.channel.domain.param.PromoterCreateParam;
+import com.qs.mp.channel.domain.param.PromoterDataQueryParam;
+import com.qs.mp.channel.domain.param.PromoterEditParam;
+import com.qs.mp.channel.domain.param.PromoterQueryParam;
+import com.qs.mp.channel.domain.vo.ChannelOperDataVO;
+import com.qs.mp.channel.service.IChannelService;
+import com.qs.mp.common.core.domain.AjaxResult;
+import com.qs.mp.common.core.page.TableDataInfo;
+import com.qs.mp.common.jsms.JSMSUtils;
+import com.qs.mp.utils.SecurityUtils;
+import com.qs.mp.web.controller.common.BaseApiController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import java.math.BigDecimal;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.checkerframework.checker.units.qual.C;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author Cup
+ * @date 2022/8/9
+ */
+@Api(tags = "推广员相关API")
+@RestController
+@RequestMapping("/api/v1/mp/channel/promoter")
+public class PromoterController extends BaseApiController {
+
+    @Autowired
+    private IChannelService channelService;
+
+
+    @PostMapping("/operdata/query")
+    @ApiOperation("获取推广员的销售数据")
+    @ApiResponses(
+        @ApiResponse(code = 200, message = "成功", response = ChannelOperDataVO.class)
+    )
+    public AjaxResult saleDetail(@Validated @RequestBody PromoterDataQueryParam param) {
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        if (param.getChannelId() == null) {
+            param.setChannelId(channelId);
+        }
+        Channel channel = channelService.getById(param.getChannelId());
+        if (channel == null) {
+            return AjaxResult.error("推广员不存在");
+        }
+
+        Integer days = param.getDays();
+        days = days > 0 ? days : 1;
+
+        return AjaxResult.success(channelService.getPromoterOperData(channel.getChannelNo(), days));
+    }
+
+    @PostMapping("/edit")
+    @ApiOperation("编辑推广员信息")
+    public AjaxResult edit(@Validated @RequestBody PromoterEditParam param) {
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        Channel channel = channelService.getById(channelId);
+        if (channel == null) {
+            return AjaxResult.error("门店信息不正确");
+        }
+
+        int count = channelService.count(
+            new LambdaQueryWrapper<Channel>().eq(Channel::getChannelId, param.getChannelId())
+                .eq(Channel::getParentId, channelId));
+
+        if (count <= 0) {
+            return AjaxResult.error("您没有权限编辑该推广员信息");
+        }
+
+        if (param.getCommRate().compareTo(channel.getCommRate()) > 0) {
+            return AjaxResult.error("佣金比例不能大于门店的佣金比例");
+        }
+
+        if (param.getCommRate().compareTo(BigDecimal.ZERO) < 0) {
+            return AjaxResult.error("佣金比例不能小于0");
+        }
+
+        // 更新推广员信息
+        channelService.update(new LambdaUpdateWrapper<Channel>()
+            .set(Channel::getWorkNo, param.getWorkNo())
+            .set(Channel::getName, param.getName())
+            .set(Channel::getCommRate, param.getCommRate())
+            .eq(Channel::getChannelId, param.getChannelId()));
+
+        return AjaxResult.success();
+    }
+
+
+    @PostMapping("/delete/{id}")
+    @ApiOperation("删除推广员")
+    @ApiImplicitParams(
+        @ApiImplicitParam(name = "id", value = "推广员id", required = true, dataType = "Long", paramType = "path")
+    )
+    public AjaxResult delete(@PathVariable("id") Long id) {
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        int count = channelService.count(
+            new LambdaQueryWrapper<Channel>().eq(Channel::getChannelId, id)
+                .eq(Channel::getParentId, channelId));
+        if (count <= 0) {
+            return AjaxResult.error("您没有权限删除该推广员");
+        }
+
+        channelService.deletePromoter(id);
+        return AjaxResult.success();
+    }
+
+
+    @PostMapping("/list")
+    @ApiOperation("门店下推广员列表")
+    @ApiResponses(
+        @ApiResponse(code = 200, message = "OK", response = Channel.class)
+    )
+    public TableDataInfo promoterList(@RequestBody PromoterQueryParam param) {
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+
+        if (param.getChannelId() == null) {
+            param.setChannelId(channelId);
+        }
+
+        Channel channel = channelService.getById(param.getChannelId());
+        if (channel == null) {
+            getErrorDataTable("门店信息不正确");
+        }
+
+        startPage();
+        List<Channel> list = channelService.list(new LambdaQueryWrapper<Channel>()
+            .eq(Channel::getParentId, param.getChannelId())
+            .nested(StringUtils.isNotBlank(param.getSearchValue()), queryWrapper -> {
+                queryWrapper.like(Channel::getName, param.getSearchValue())
+                    .or()
+                    .like(Channel::getWorkNo, param.getSearchValue());
+            }));
+
+        return getDataTable(list);
+    }
+
+
+    @PostMapping("/create")
+    @ApiOperation("门店创建推广员接口")
+    @ApiResponses(
+        @ApiResponse(code = 200, message = "成功")
+    )
+    public AjaxResult promoterCreate(@Validated @RequestBody PromoterCreateParam param) {
+        Long channelId = SecurityUtils.getLoginUser().getChannelId();
+        param.setChannelId(channelId);
+
+
+        int mobileCount = channelService.count(new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, param.getMobile()));
+        if (mobileCount > 0) {
+            return AjaxResult.error("手机号码" + param.getMobile() + "已注册!");
+        }
+
+        // 校验推广员信息合法性
+        String checkRes = channelService.checkPromoter(param);
+        if (StringUtils.isNotBlank(checkRes)) {
+            return AjaxResult.error(checkRes);
+        }
+
+        // 创建推广员
+        channelService.createPromoter(param);
+
+        return AjaxResult.success();
+    }
+
+
+    @PostMapping("/register")
+    @ApiOperation("邀请链接注册推广员接口")
+    @ApiResponses(
+        @ApiResponse(code = 200, message = "成功")
+    )
+    public AjaxResult promoterRegister(@Validated @RequestBody PromoterCreateParam param) {
+        Long channelId = param.getChannelId();
+        Channel channel = channelService.getById(channelId);
+        if (channel == null) {
+            return AjaxResult.error("门店信息不正确");
+        }
+
+        // 校验短信
+        ValidSMSResult res = JSMSUtils.sendValidSMSCode(param.getMessageId(), param.getCode());
+        if (res == null || !res.getIsValid()) {
+            return AjaxResult.error("短信验证码错误");
+        }
+
+        int mobileCount = channelService.count(new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, param.getMobile()));
+        if (mobileCount > 0) {
+            return AjaxResult.error("手机号码" + param.getMobile() + "已注册!");
+        }
+
+
+        // 校验推广员信息合法性
+        String checkRes = channelService.checkPromoter(param);
+        if (StringUtils.isNotBlank(checkRes)) {
+            return AjaxResult.error(checkRes);
+        }
+
+        // 创建推广员
+        channelService.createPromoter(param);
+
+        return AjaxResult.success();
+    }
+
+
+}

+ 11 - 0
mp-admin/src/main/java/com/qs/mp/web/controller/api/user/UserTicketController.java

@@ -15,6 +15,8 @@ import com.qs.mp.admin.domain.param.TicketParam;
 import com.qs.mp.admin.domain.vo.*;
 import com.qs.mp.admin.service.*;
 import com.qs.mp.channel.domain.Channel;
+import com.qs.mp.channel.domain.ChannelOrderDetail;
+import com.qs.mp.channel.service.IChannelOrderDetailService;
 import com.qs.mp.channel.service.IChannelService;
 import com.qs.mp.common.core.domain.AjaxResult;
 import com.qs.mp.common.core.page.TableDataInfo;
@@ -99,6 +101,9 @@ public class UserTicketController extends BaseApiController {
     @Autowired
     private IChannelService channelService;
 
+    @Autowired
+    private IChannelOrderDetailService channelOrderDetailService;
+
     @PostMapping("/isJump")
     @ApiOperation("是否跳转")
     public AjaxResult isJump() {
@@ -419,6 +424,9 @@ public class UserTicketController extends BaseApiController {
             return AjaxResult.error(ErrorCodeEnum.ERROR_CODE_1023);
         }
 
+        ChannelOrderDetail channelOrderDetail = channelOrderDetailService.getOne(
+            new LambdaQueryWrapper<ChannelOrderDetail>().eq(ChannelOrderDetail::getPkgId, ticketPackage.getPkgId()));
+
         TicketVO ticketVO = new TicketVO();
         ticketVO.setPrizeList(ticketAwardsPrizeService.listPrizeVO(ticket.getBoxId()));
         ticketVO.setTicketId(ticket.getTicketId());
@@ -430,6 +438,9 @@ public class UserTicketController extends BaseApiController {
         ticketVO.setPlainLuckyNum(ticket.getPlainLuckyNum());
         ticketVO.setStatus(ticket.getStatus().getValue());
         ticketVO.setPicUrl(ticketBox.getPicUrl());
+        if (channelOrderDetail != null) {
+            ticketVO.setChannelId(channelOrderDetail.getChannelId());
+        }
 
         // 设置奖项名
         if (Objects.nonNull(ticket.getPlainLuckyNum())) {

+ 17 - 0
mp-admin/src/main/java/com/qs/mp/web/controller/api/user/UserTicketOrderController.java

@@ -12,8 +12,11 @@ import com.qs.mp.admin.service.ITicketBoxGoodsService;
 import com.qs.mp.admin.service.ITicketBoxService;
 import com.qs.mp.admin.service.ITicketPackageService;
 import com.qs.mp.admin.service.ITicketService;
+import com.qs.mp.channel.domain.Channel;
 import com.qs.mp.channel.domain.ChannelOrder;
 import com.qs.mp.channel.domain.param.OrderPayParam;
+import com.qs.mp.channel.domain.vo.PromoterVO;
+import com.qs.mp.channel.service.IPromoterUserService;
 import com.qs.mp.common.core.domain.AjaxResult;
 import com.qs.mp.common.core.page.TableDataInfo;
 import com.qs.mp.common.core.redis.RedisCache;
@@ -101,6 +104,9 @@ public class UserTicketOrderController extends BaseApiController {
     @Autowired
     private ITicketBoxGoodsService ticketBoxGoodsService;
 
+    @Autowired
+    private IPromoterUserService promoterUserService;
+
 
     /**
      * 订单结算,每次更换优惠券时需重新请求此接口
@@ -133,6 +139,17 @@ public class UserTicketOrderController extends BaseApiController {
             if (ticketPackage.getIsPre() == 1) {
                 orderAmt = 0;
             }
+
+
+            // 设置用户关联的推广员信息
+            QueryWrapper<Channel> promoterQueryWrapper = new QueryWrapper<>();
+            promoterQueryWrapper.eq("t1.is_deleted", 0);
+            promoterQueryWrapper.eq("t1.user_id", userId);
+            promoterQueryWrapper.eq("t4.ticket_id", ticket.getTicketId());
+            promoterQueryWrapper.eq("t5.is_deleted", 0);
+            PromoterVO promoter = promoterUserService.getPromoterByQueryWrapper(promoterQueryWrapper);
+            orderSettleVO.setPromoter(promoter);
+
         } else {
             // 线上购票
             ticketBox = ticketBoxService.getById(param.getBoxId());

+ 2 - 1
mp-common/src/main/java/com/qs/mp/common/enums/ChannelRoleEnum.java

@@ -14,7 +14,8 @@ import com.qs.mp.common.json.EnumValueDeserializer;
 public enum ChannelRoleEnum implements IEnum<String> {
 
   CHANNEL("channel", "渠道"),
-  SALESITE("salesite", "经销商");
+  SALESITE("salesite", "经销商"),
+  PROMOTER("promoter", "推广员");
 
   private final String value;
   private final String desc;

+ 3 - 1
mp-framework/src/main/java/com/qs/mp/framework/config/SecurityConfig.java

@@ -152,7 +152,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                     "/api/v1/mp/user/mall/ticket/detail/new",
                     "/api/v1/mp/user/ticket/prize/list/*",
                     "/api/v1/mp/user/isJump",
-                    "/api/v1/mp/user/mall/ticket/goods/list"
+                    "/api/v1/mp/user/mall/ticket/goods/list",
+                    "/api/v1/mp/channel/promoter/register",
+                    "/api/v1/mp/channel//saleSite/info/*"
                 ).permitAll()
                 // 除上面外的所有请求全部需要鉴权认证
                 .anyRequest().authenticated()

+ 2 - 0
mp-framework/src/main/java/com/qs/mp/framework/web/service/SysLoginService.java

@@ -210,6 +210,8 @@ public class SysLoginService
           loginUser.setChannelNo(channel.getChannelNo());
           if (channel.getLevel() == 0) {
               return ChannelRoleEnum.SALESITE;
+          } else if (channel.getLevel() == -1) {
+              return ChannelRoleEnum.PROMOTER;
           } else {
               return ChannelRoleEnum.CHANNEL;
           }

+ 3 - 0
mp-service/src/main/java/com/qs/mp/admin/domain/vo/TicketVO.java

@@ -76,4 +76,7 @@ public class TicketVO {
   @ApiModelProperty("盲票状态(未付款、已激活、已兑奖、付款中)")
   private Integer status;
 
+  @ApiModelProperty("关联的门店id")
+  private Long channelId;
+
 }

+ 3 - 0
mp-service/src/main/java/com/qs/mp/admin/domain/vo/UserTicketOrderDetailVO.java

@@ -47,6 +47,9 @@ public class UserTicketOrderDetailVO {
     @ApiModelProperty("渠道商名称")
     private String channelName;
 
+    @ApiModelProperty("推广员名字")
+    private String promoterName;
+
     @ApiModelProperty("盲票组标题")
     private String ticketBoxTitle;
 

+ 14 - 1
mp-service/src/main/java/com/qs/mp/channel/domain/Channel.java

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.qs.mp.common.enums.ChannelCertifyStatusEnum;
 import com.qs.mp.common.enums.ChannelStatusEnum;
@@ -44,6 +45,10 @@ public class Channel implements Serializable {
   @ApiModelProperty("渠道编码")
   private String channelNo;
 
+  @TableField("work_no")
+  @ApiModelProperty("工号")
+  private String workNo;
+
   /**
    * 渠道名称
    */
@@ -62,7 +67,7 @@ public class Channel implements Serializable {
    * 渠道级别,0:经销商;1:一级渠道;2:二级渠道
    */
   @TableField("level")
-  @ApiModelProperty("渠道级别,0:经销商;1:一级渠道;2:二级渠道")
+  @ApiModelProperty("渠道级别,-1推广员; 0:经销商;1:一级渠道;2:二级渠道")
   private Integer level;
 
   /**
@@ -238,5 +243,13 @@ public class Channel implements Serializable {
   @ApiModelProperty("更新时间")
   private Date updatedTime;
 
+  /**
+   * 逻辑删除标识
+   */
+  @ApiModelProperty("逻辑删除标识")
+  @TableField("is_deleted")
+  @TableLogic
+  private Integer isDeleted;
+
 
 }

+ 78 - 0
mp-service/src/main/java/com/qs/mp/channel/domain/PromoterUser.java

@@ -0,0 +1,78 @@
+package com.qs.mp.channel.domain;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+
+/**
+ * @describe 推广员用户关联表实体类
+ * @auther quanshu
+ * @create 2022-08-08 17:45:00
+ */
+@TableName("mp_promoter_user")
+@Data
+@ApiModel("推广员用户关联表实体类")
+public class PromoterUser implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @ApiModelProperty("主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 推广员id
+     */
+    @ApiModelProperty("推广员id")
+    @TableField("promoter_id")
+    private Long promoterId;
+
+    /**
+     * 用户id
+     */
+    @ApiModelProperty("用户id")
+    @TableField("user_id")
+    private Long userId;
+
+    /**
+     * 门店id
+     */
+    @ApiModelProperty("门店id")
+    @TableField("channel_id")
+    private Long channelId;
+
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty("创建时间")
+    @TableField("created_time")
+    private Date createdTime;
+
+    /**
+     * 更新时间
+     */
+    @ApiModelProperty("更新时间")
+    @TableField("updated_time")
+    private Date updatedTime;
+
+    /**
+     * 逻辑删除标识
+     */
+    @ApiModelProperty("逻辑删除标识")
+    @TableField("is_deleted")
+    @TableLogic
+    private Integer isDeleted;
+
+
+}

+ 3 - 0
mp-service/src/main/java/com/qs/mp/channel/domain/param/ChannelCommParam.java

@@ -26,6 +26,9 @@ public class ChannelCommParam {
     @ApiModelProperty("渠道id")
     private Long channelId;
 
+    @ApiModelProperty("推广员id")
+    private Long promoterId;
+
     @ApiModelProperty("用户id")
     private Long userId;
 

+ 48 - 0
mp-service/src/main/java/com/qs/mp/channel/domain/param/PromoterCreateParam.java

@@ -0,0 +1,48 @@
+package com.qs.mp.channel.domain.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import java.math.BigDecimal;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+/**
+ * 推广员添加入参类
+ *
+ * @author Cup
+ * @date 2022/8/9
+ */
+@ApiModel("推广员添加入参类")
+@Data
+public class PromoterCreateParam {
+
+    @ApiModelProperty("推广员所属门店id")
+    private Long channelId;
+
+    @ApiModelProperty("手机号")
+    @NotBlank(message = "手机号不能为空")
+    @Length(min = 11, max = 11, message = "手机号格式不正确")
+    private String mobile;
+
+    @ApiModelProperty("名字")
+    @NotBlank(message = "名字不能为空")
+    private String name;
+
+    @ApiModelProperty("工号")
+    @NotBlank(message = "工号不能为空")
+    private String workNo;
+
+    @ApiModelProperty("佣金比例")
+    @NotNull(message = "佣金比例不能为空")
+    private BigDecimal commRate;
+
+    @ApiModelProperty("短信id")
+    private String messageId;
+
+    @ApiModelProperty("验证码")
+    private String code;
+
+
+}

+ 25 - 0
mp-service/src/main/java/com/qs/mp/channel/domain/param/PromoterDataQueryParam.java

@@ -0,0 +1,25 @@
+package com.qs.mp.channel.domain.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import javax.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 推广员销售数据查询入参类
+ * @author Cup
+ * @date 2022/8/10
+ */
+@ApiModel("推广员销售数据查询入参类")
+@Data
+public class PromoterDataQueryParam {
+
+
+    @ApiModelProperty("推广员id")
+    private Long channelId;
+
+    @NotNull(message = "天数不能为空")
+    @ApiModelProperty("天数")
+    private Integer days;
+
+}

+ 36 - 0
mp-service/src/main/java/com/qs/mp/channel/domain/param/PromoterEditParam.java

@@ -0,0 +1,36 @@
+package com.qs.mp.channel.domain.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import java.math.BigDecimal;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 推广员编辑入参类
+ * @author Cup
+ * @date 2022/8/9
+ */
+@ApiModel("推广员编辑入参类")
+@Data
+public class PromoterEditParam {
+
+
+    @NotNull(message = "推广员id不能为空")
+    @ApiModelProperty("推广员id")
+    private Long channelId;
+
+    @NotBlank(message = "推广员名字不能为空")
+    @ApiModelProperty("推广员名字")
+    private String name;
+
+    @NotBlank(message = "推广员工号不能为空")
+    @ApiModelProperty("推广员工号")
+    private String workNo;
+
+    @NotNull(message = "推广员佣金比例不能为空")
+    @ApiModelProperty("推广员的分佣比例")
+    private BigDecimal commRate;
+
+}

+ 32 - 0
mp-service/src/main/java/com/qs/mp/channel/domain/param/PromoterListQueryParam.java

@@ -0,0 +1,32 @@
+package com.qs.mp.channel.domain.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * 推广员列表查询入参类
+ * @author Cup
+ * @date 2022/8/9
+ */
+@ApiModel("推广员列表查询入参类")
+@Data
+public class PromoterListQueryParam {
+
+    @ApiModelProperty("上级门店名字")
+    private String siteName;
+
+    @ApiModelProperty("推广员名字")
+    private String name;
+
+    @ApiModelProperty("推广员手机号")
+    private String mobile;
+
+    @ApiModelProperty("开始时间")
+    private Date startDate;
+
+    @ApiModelProperty("结束时间")
+    private Date endDate;
+
+}

+ 23 - 0
mp-service/src/main/java/com/qs/mp/channel/domain/param/PromoterQueryParam.java

@@ -0,0 +1,23 @@
+package com.qs.mp.channel.domain.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 推广员查询入参类
+ *
+ * @author Cup
+ * @date 2022/8/9
+ */
+@ApiModel("推广员查询入参类")
+@Data
+public class PromoterQueryParam {
+
+    @ApiModelProperty("推广员所属门店id")
+    private Long channelId;
+
+    @ApiModelProperty("名字")
+    private String searchValue;
+
+}

+ 11 - 1
mp-service/src/main/java/com/qs/mp/channel/domain/vo/ChannelOperDataVO.java

@@ -1,5 +1,7 @@
 package com.qs.mp.channel.domain.vo;
 
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 /**
@@ -8,13 +10,21 @@ import lombok.Data;
  * @Date 2022/3/1
  */
 @Data
+@ApiModel("经营数据")
 public class ChannelOperDataVO {
+
+  @ApiModelProperty("销售额")
   long saleAmt; // 销售额
+  @ApiModelProperty("佣金收入")
   long commAmt; // 佣金收入
+  @ApiModelProperty("新增用户数")
   long newUserCnt; // 新增用户数
+  @ApiModelProperty("渠道名称")
   String name; // 渠道名称
+  @ApiModelProperty("手机号")
   String mobile; // 手机号
+  @ApiModelProperty("订单数")
   int orderCnt; // 订单数
-  
+  @ApiModelProperty("盲票销量")
   long ticketSaleCnt; // 盲票销量
 }

+ 45 - 0
mp-service/src/main/java/com/qs/mp/channel/domain/vo/PromoterListVO.java

@@ -0,0 +1,45 @@
+package com.qs.mp.channel.domain.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * 推广员列表出参类
+ * @author Cup
+ * @date 2022/8/9
+ */
+@ApiModel("推广员列表出参类")
+@Data
+public class PromoterListVO {
+
+    @ApiModelProperty("推广员id")
+    private Long channelId;
+
+    @ApiModelProperty("推广员名字")
+    private String name;
+
+    @ApiModelProperty("推广员手机号")
+    private String mobile;
+
+    @ApiModelProperty("分佣比例")
+    private BigDecimal commRate;
+
+    @ApiModelProperty("门店名称")
+    private String siteName;
+
+    @ApiModelProperty("盲票销量")
+    private Integer saleNum;
+
+    @ApiModelProperty("销售额")
+    private Integer saleAmt;
+
+    @ApiModelProperty("佣金")
+    private Integer commAmt;
+
+    @ApiModelProperty("创建时间")
+    private Date createdTime;
+
+}

+ 26 - 0
mp-service/src/main/java/com/qs/mp/channel/domain/vo/PromoterVO.java

@@ -0,0 +1,26 @@
+package com.qs.mp.channel.domain.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 推广员出参类
+ *
+ * @author Cup
+ * @date 2022/8/10
+ */
+@ApiModel("推广员出参类")
+@Data
+public class PromoterVO {
+
+    @ApiModelProperty("推广员id")
+    private Long channelId;
+
+    @ApiModelProperty("名字")
+    private String name;
+
+    @ApiModelProperty("工号")
+    private String workNo;
+
+}

+ 9 - 0
mp-service/src/main/java/com/qs/mp/channel/mapper/ChannelMapper.java

@@ -1,9 +1,11 @@
 package com.qs.mp.channel.mapper;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.qs.mp.admin.domain.vo.IndexVO;
 import com.qs.mp.channel.domain.Channel;
 import com.qs.mp.channel.domain.vo.ChannelVO;
 
+import com.qs.mp.channel.domain.vo.PromoterListVO;
 import java.util.List;
 
 import org.apache.ibatis.annotations.Param;
@@ -58,4 +60,11 @@ public interface ChannelMapper extends BaseMapper<Channel> {
      * @return
      */
  	List<IndexVO> selectIndexSiteIncreaseList(@Param(Constants.WRAPPER) Wrapper<Channel> wrapper);
+
+	/**
+	 * 根据查询条件查询推广员列表信息
+	 * @param queryWrapper
+	 * @return
+	 */
+    List<PromoterListVO> listPromoterByQueryWrapper(@Param(Constants.WRAPPER) QueryWrapper<Channel> queryWrapper);
 }

+ 19 - 0
mp-service/src/main/java/com/qs/mp/channel/mapper/PromoterUserMapper.java

@@ -0,0 +1,19 @@
+package com.qs.mp.channel.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.qs.mp.channel.domain.Channel;
+import com.qs.mp.channel.domain.PromoterUser;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qs.mp.channel.domain.vo.PromoterVO;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * @auther quanshu
+ * @create 2022-08-08 17:45:00
+ * @describe 推广员用户关联表mapper类
+ */
+public interface PromoterUserMapper extends BaseMapper<PromoterUser> {
+
+    PromoterVO getPromoterByQueryWrapper(@Param(Constants.WRAPPER) QueryWrapper<Channel> queryWrapper);
+}

+ 108 - 72
mp-service/src/main/java/com/qs/mp/channel/service/IChannelService.java

@@ -1,10 +1,14 @@
 package com.qs.mp.channel.service;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.qs.mp.admin.domain.vo.IndexVO;
 import com.qs.mp.channel.domain.Channel;
+import com.qs.mp.channel.domain.param.PromoterCreateParam;
+import com.qs.mp.channel.domain.param.PromoterDataQueryParam;
 import com.qs.mp.channel.domain.vo.ChannelOperDataVO;
 import com.qs.mp.channel.domain.vo.ChannelVO;
 
+import com.qs.mp.channel.domain.vo.PromoterListVO;
 import com.qs.mp.common.enums.ChannelRoleEnum;
 import com.qs.mp.user.domain.UserDeliverOrder;
 
@@ -23,97 +27,129 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IChannelService extends IService<Channel> {
 
-	/**
-	 * 新增子渠道、经销商信息
-	 *
-	 * @param channel
-	 * @param channelRole channel:子渠道  site: 经销商
-	 * @return
-	 */
+    /**
+     * 新增子渠道、经销商信息
+     *
+     * @param channel
+     * @param channelRole channel:子渠道  site: 经销商
+     * @return
+     */
     public void saveChannel(Channel channel, ChannelRoleEnum channelRole);
 
     /**
-	 * 编辑子渠道、经销商信息
-	 *
-	 * @param channel
-	 * @param mobileChange 手机号码是否发生变更
-	 * @return
-	 */
+     * 编辑子渠道、经销商信息
+     *
+     * @param channel
+     * @param mobileChange 手机号码是否发生变更
+     * @return
+     */
     public void updateChannel(Channel channel, boolean mobileChange);
 
 
-	/**
-	 * 获取我的下级渠道信息,支持翻页
-	 *
-	 * @param queryWrapper
-	 * @return
-	 */
-	public List<ChannelVO> selectChannelVoList(Wrapper<Channel> queryWrapper);
-
-	/**
-	 * 获取我的下级渠道信息,统计经销商数和用户数,支持翻页
-	 *
-	 * @param queryWrapper
-	 * @return
-	 */
-	public List<ChannelVO> selectChannelList(Wrapper<Channel> queryWrapper);
-
-	/**
-	 * 获取经销商列表信息,支持翻页
-	 *
-	 * @param queryWrapper
-	 * @return
-	 */
-	public List<ChannelVO> selectSaleSiteList(Wrapper<Channel> queryWrapper);
-
-	/**
-	 * 根据用户ID查询渠道
-	 *
-	 * @param userId
-	 * @return
-	 */
-	public Channel getChannelByUserId(Long userId);
+    /**
+     * 获取我的下级渠道信息,支持翻页
+     *
+     * @param queryWrapper
+     * @return
+     */
+    public List<ChannelVO> selectChannelVoList(Wrapper<Channel> queryWrapper);
+
+    /**
+     * 获取我的下级渠道信息,统计经销商数和用户数,支持翻页
+     *
+     * @param queryWrapper
+     * @return
+     */
+    public List<ChannelVO> selectChannelList(Wrapper<Channel> queryWrapper);
+
+    /**
+     * 获取经销商列表信息,支持翻页
+     *
+     * @param queryWrapper
+     * @return
+     */
+    public List<ChannelVO> selectSaleSiteList(Wrapper<Channel> queryWrapper);
+
+    /**
+     * 根据用户ID查询渠道
+     *
+     * @param userId
+     * @return
+     */
+    public Channel getChannelByUserId(Long userId);
 
     /**
      * 查询渠道及其子渠道经销商总数
+     *
      * @param channelNo
      * @return
      */
-	public int getChannelSiteCnt(String channelNo);
-
-	/**
-	 * 根据channelNo统计最近几天days的经营数据
-	 */
-	public ChannelOperDataVO getChannelOperData(String channelNo, int days);
+    public int getChannelSiteCnt(String channelNo);
 
+    /**
+     * 根据channelNo统计最近几天days的经营数据
+     */
+    public ChannelOperDataVO getChannelOperData(String channelNo, int days);
 
-	/**
-	 * 根据ID查询渠道VO
-	 *
-	 * @param userId
-	 * @return
-	 */
-	public ChannelVO getChannelVoById(Long channelId);
 
+    /**
+     * 根据ID查询渠道VO
+     *
+     * @param userId
+     * @return
+     */
+    public ChannelVO getChannelVoById(Long channelId);
 
 
-	/**
-	 * 根据channelNo统计全部的经营数据
-	 */
-	public ChannelOperDataVO getChannelTotalOperData(String channelNo);
+    /**
+     * 根据channelNo统计全部的经营数据
+     */
+    public ChannelOperDataVO getChannelTotalOperData(String channelNo);
 
 
-   /**
-    * 统计新增的经销商数
-    * @param wrapper
-    * @return
-    */
-	List<IndexVO> selectIndexSiteIncreaseList(Wrapper<Channel> wrapper);
+    /**
+     * 统计新增的经销商数
+     *
+     * @param wrapper
+     * @return
+     */
+    List<IndexVO> selectIndexSiteIncreaseList(Wrapper<Channel> wrapper);
 
-	/**
-	 * 审核通过的经销商
-	 * @param channel
-	 * @return
-	 */
+    /**
+     * 审核通过的经销商
+     *
+     * @param channel
+     * @return
+     */
     boolean siteVerify(Channel channel);
+
+    /**
+     * 推广员信息合法性校验
+     *
+     * @param param
+     */
+    String checkPromoter(PromoterCreateParam param);
+
+    /**
+     * 创建推广员
+     *
+     * @param param
+     */
+    void createPromoter(PromoterCreateParam param);
+
+    /**
+     * 根据查询条件查询推广员列表信息
+     * @param queryWrapper
+     * @return
+     */
+    List<PromoterListVO> listPromoterByQueryWrapper(QueryWrapper<Channel> queryWrapper);
+
+
+    ChannelOperDataVO getPromoterOperData(String channelNo, Integer days);
+
+    /**
+     * 删除推广员
+     * @param channelId 推广员id
+     */
+    void deletePromoter(Long channelId);
 }

+ 20 - 0
mp-service/src/main/java/com/qs/mp/channel/service/IPromoterUserService.java

@@ -0,0 +1,20 @@
+package com.qs.mp.channel.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.qs.mp.channel.domain.Channel;
+import com.qs.mp.channel.domain.PromoterUser;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qs.mp.channel.domain.vo.PromoterVO;
+
+/**
+ * <p>
+ * 推广员用户关联表 服务类
+ * </p>
+ *
+ * @author quanshu
+ * @since 2022-08-08
+ */
+public interface IPromoterUserService extends IService<PromoterUser> {
+
+    PromoterVO getPromoterByQueryWrapper(QueryWrapper<Channel> queryWrapper);
+}

+ 317 - 185
mp-service/src/main/java/com/qs/mp/channel/service/impl/ChannelServiceImpl.java

@@ -3,15 +3,22 @@ package com.qs.mp.channel.service.impl;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qs.mp.admin.domain.vo.IndexVO;
 import com.qs.mp.channel.domain.Channel;
+import com.qs.mp.channel.domain.PromoterUser;
+import com.qs.mp.channel.domain.param.PromoterCreateParam;
+import com.qs.mp.channel.domain.param.PromoterDataQueryParam;
 import com.qs.mp.channel.domain.vo.ChannelOperDataVO;
 import com.qs.mp.channel.domain.vo.ChannelVO;
+import com.qs.mp.channel.domain.vo.PromoterListVO;
 import com.qs.mp.channel.mapper.ChannelMapper;
 import com.qs.mp.channel.service.IChannelCommissionService;
 import com.qs.mp.channel.service.IChannelService;
 import com.qs.mp.channel.service.IChannelUserRelService;
+import com.qs.mp.channel.service.IPromoterUserService;
+import com.qs.mp.common.core.domain.AjaxResult;
 import com.qs.mp.common.enums.ChannelCertifyStatusEnum;
 import com.qs.mp.common.enums.ChannelRoleEnum;
 import com.qs.mp.common.enums.ChannelVerifyStatusEnum;
@@ -24,7 +31,9 @@ import com.qs.mp.system.service.ISysRoleService;
 import com.qs.mp.system.service.ISysUserService;
 import com.qs.mp.user.domain.UserAddr;
 import com.qs.mp.user.service.IUserAddrService;
+import com.qs.mp.user.service.IUserTicketOrderService;
 import com.qs.mp.utils.SecurityUtils;
+import java.math.BigDecimal;
 import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -43,191 +52,314 @@ import org.springframework.util.CollectionUtils;
 public class ChannelServiceImpl extends ServiceImpl<ChannelMapper, Channel> implements
     IChannelService {
 
-  @Autowired
-  private IChannelService channelService;
-
-  @Autowired
-  private IChannelUserRelService channelUserRelService;
-
-  @Autowired
-  private IChannelCommissionService channelCommissionService;
-
-  @Autowired
-  private ISysUserService userService;
-
-  @Autowired
-  private ISysRoleService roleService;
-
-  @Autowired
-  private IUserAddrService userAddrService;
-
-  @Override
-  @Transactional
-  public void saveChannel(Channel channel, ChannelRoleEnum channelRole) {
-    boolean res = channelService.save(channel);
-    if (res && null != channel.getChannelId()) {
-      channel.setChannelNo(channel.getChannelNo() + channel.getChannelId());
-			SysUser sysUser = userService.selectUserByUserName(channel.getMobile());
-			if (null == sysUser) {
-				// 生成用户
-				sysUser = new SysUser();
-				sysUser.setUserName(channel.getMobile());
-				sysUser.setPhonenumber(channel.getMobile());
-				sysUser.setNickName(channel.getMobile());
+    @Autowired
+    private IChannelService channelService;
+
+    @Autowired
+    private IChannelUserRelService channelUserRelService;
+
+    @Autowired
+    private IChannelCommissionService channelCommissionService;
+
+    @Autowired
+    private ISysUserService userService;
+
+    @Autowired
+    private ISysRoleService roleService;
+
+    @Autowired
+    private IUserAddrService userAddrService;
+
+
+    @Autowired
+    private ISysUserService sysUserService;
+
+    @Autowired
+    private IUserTicketOrderService userTicketOrderService;
+
+    @Autowired
+    private IPromoterUserService promoterUserService;
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void deletePromoter(Long channelId) {
+
+        // 推广员是否有关联用户
+        int count = promoterUserService.count(
+            new LambdaQueryWrapper<PromoterUser>().eq(PromoterUser::getPromoterId, channelId));
+
+        if (count > 0) {
+            boolean rtn = promoterUserService.remove(
+                new LambdaQueryWrapper<PromoterUser>().eq(PromoterUser::getPromoterId, channelId));
+            if (!rtn) {
+                throw new ServiceException("删除推广员和用户关联信息失败");
+            }
+        }
+        boolean rtn = this.removeById(channelId);
+        if (!rtn) {
+            throw new ServiceException("删除推广员信息失败");
+        }
+    }
+
+    @Override
+    public List<PromoterListVO> listPromoterByQueryWrapper(QueryWrapper<Channel> queryWrapper) {
+        return getBaseMapper().listPromoterByQueryWrapper(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void createPromoter(PromoterCreateParam param) {
+
+        // 判断用户是否已经注册了盲票
+        SysUser sysUser = sysUserService.selectUserByUserName(param.getMobile());
+        if (sysUser == null) {
+            sysUser = new SysUser();
+            // 直接注册新用户
+            sysUser.setUserName(param.getMobile());
+            sysUser.setNickName(param.getMobile());
+            sysUser.setPhonenumber(param.getMobile());
+            sysUserService.registerUser(sysUser);
+        }
+
+        Channel channel = this.getById(param.getChannelId());
+
+        // 创建推广员
+        Channel promoter = new Channel();
+        promoter.setUserId(sysUser.getUserId());
+        promoter.setWorkNo(param.getWorkNo());
+        promoter.setName(param.getName());
+        promoter.setLevel(-1);
+        promoter.setCommRate(param.getCommRate());
+        promoter.setMobile(param.getMobile());
+        promoter.setParentId(channel.getChannelId());
+        promoter.setChannelNo("");
+
+        boolean res = this.save(promoter);
+        if (!res) {
+            throw new ServiceException("创建推广员失败");
+        }
+
+        // 更新关系链编码
+        boolean rtn = this.update(new LambdaUpdateWrapper<Channel>()
+            .set(Channel::getChannelNo, channel.getChannelNo() + "." + promoter.getChannelId())
+            .eq(Channel::getChannelId, promoter.getChannelId()));
+        if (!rtn) {
+            throw new ServiceException("更新关系链编码失败");
+        }
+    }
+
+    @Override
+    public String checkPromoter(PromoterCreateParam param) {
+
+        // 校验门店
+        Channel channel = this.getById(param.getChannelId());
+        if (channel == null) {
+            return "门店不存在";
+        }
+
+        // 校验佣金比例
+        if (param.getCommRate().compareTo(channel.getCommRate()) > 0) {
+            return "佣金比例不能大于门店的佣金比例";
+        }
+
+        if (param.getCommRate().compareTo(BigDecimal.ZERO) < 0) {
+            return "佣金比例不能小于0";
+        }
+
+        // 校验用户是否已经是渠道或门店或推广员
+        int count = channelService.count(
+            new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, param.getMobile()));
+        if (count > 0) {
+            return "该手机号已存在角色";
+        }
+
+        return null;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void saveChannel(Channel channel, ChannelRoleEnum channelRole) {
+        boolean res = channelService.save(channel);
+        if (res && null != channel.getChannelId()) {
+            channel.setChannelNo(channel.getChannelNo() + channel.getChannelId());
+            SysUser sysUser = userService.selectUserByUserName(channel.getMobile());
+            if (null == sysUser) {
+                // 生成用户
+                sysUser = new SysUser();
+                sysUser.setUserName(channel.getMobile());
+                sysUser.setPhonenumber(channel.getMobile());
+                sysUser.setNickName(channel.getMobile());
 //		    sysUser.setDeptId(SecurityUtils.getDeptId());
 //			sysUser.setCreateBy(SecurityUtils.getUsername());
-				// 获取默认的角色
-				SysRole sysRole = roleService.selectDefaultRoleByType(
-						channelRole == ChannelRoleEnum.CHANNEL ? RoleTypeEnum.CHANNEL_ROLE.getValue()
-								: RoleTypeEnum.SALESITE_ROLE.getValue());
-				if (null == sysRole || null == sysRole.getRoleId()) {
-					throw new ServiceException(
-							"未设置默认角色,请联系管理员");
-				}
-				Long[] roleIds = new Long[1];
-				roleIds[0] = sysRole.getRoleId();
-				sysUser.setRoleIds(roleIds);
-				int userNum = userService.insertUser(sysUser);
-				if (userNum == 0 || null == sysUser.getUserId()) {
-					throw new ServiceException("账号创建失败,请联系管理员");
-				}
-			}
-      channel.setUserId(sysUser.getUserId());
-      boolean ures = channelService.updateById(channel);
-      if (!ures) {
-        throw new ServiceException("请联系管理员");
-      }
-      // 4.发送账号创建成功短信
-      JSMSUtils.sendChannelActNotify(channel.getMobile());
-    } else {
-      throw new ServiceException("请联系管理员");
-    }
-  }
-
-
-  @Override
-  @Transactional
-  public void updateChannel(Channel channel, boolean mobileChange) {
-    // 4.更新入库
-    boolean editRes = channelService.updateById(channel);
-    if (editRes && mobileChange
-        && null != channel.getUserId()) {
-      SysUser sysUser = new SysUser();
-      sysUser.setUserId(channel.getUserId());
-      sysUser.setUserName(channel.getMobile());
-      sysUser.setPhonenumber(channel.getMobile());
-      sysUser.setNickName(channel.getName());
-      sysUser.setDeptId(SecurityUtils.getDeptId());
-      int userNum = userService.updateUser(sysUser);
-      if (userNum == 0 || null == sysUser.getUserId()) {
-        throw new ServiceException("更新失败,请联系管理员");
-      }
-      // 发送账号更新成功短信
-    }
-  }
-
-  @Override
-  public List<ChannelVO> selectChannelVoList(Wrapper<Channel> queryWrapper) {
-    return getBaseMapper().selectChannelVoList(queryWrapper);
-  }
-
-  @Override
-  public List<ChannelVO> selectChannelList(Wrapper<Channel> queryWrapper) {
-    return getBaseMapper().selectChannelList(queryWrapper);
-  }
-
-  @Override
-  public List<ChannelVO> selectSaleSiteList(Wrapper<Channel> queryWrapper) {
-    return getBaseMapper().selectSaleSiteList(queryWrapper);
-  }
-
-  @Override
-  public Channel getChannelByUserId(Long userId) {
-    return getBaseMapper().selectOne(
-        new LambdaQueryWrapper<Channel>().eq(Channel::getUserId, userId));
-  }
-
-  @Override
-  public int getChannelSiteCnt(String channelNo) {
-    return getBaseMapper().getChannelSiteCnt(channelNo);
-  }
-
-  @Override
-  public ChannelVO getChannelVoById(Long channelId) {
-    List<ChannelVO> channelVOList = getBaseMapper().selectChannelVoList(new QueryWrapper<Channel>().eq("t1.channel_id", channelId));
-    if (CollectionUtils.isEmpty(channelVOList)) {
-      return null;
-    }
-    return channelVOList.get(0);
-  }
-
-  @Override
-  public ChannelOperDataVO getChannelOperData(String channelNo, int days) {
-    ChannelOperDataVO channelOperData = new ChannelOperDataVO();
-    // 查询销售金额
-    channelOperData.setSaleAmt(channelCommissionService.getChannelSaleAmtCnt(channelNo, days));
-    // 查询佣金金额
-    channelOperData.setCommAmt(channelCommissionService.getChannelCommAmtCnt(channelNo, days));
-    // 查询新增用户数
-    int newUserCnt = channelUserRelService.getChannelNewUserCnt(channelNo, days);
-    channelOperData.setNewUserCnt(newUserCnt);
-    return channelOperData;
-  }
-
-
-  @Override
-  public ChannelOperDataVO getChannelTotalOperData(String channelNo) {
-    ChannelOperDataVO channelOperData = new ChannelOperDataVO();
-    // 查询销售金额
-    channelOperData.setSaleAmt(channelCommissionService.getChannelTotalSaleAmtCnt(channelNo));
-    // 查询佣金金额
-    channelOperData.setCommAmt(channelCommissionService.getChannelTotalCommAmtCnt(channelNo));
-    // 查询新增用户数
-    // int newUserCnt = channelUserRelService.getChannelNewUserCnt(channelNo, days);
-    // channelOperData.setNewUserCnt(newUserCnt);
-    return channelOperData;
-  }
-
-
-  @Override
-  public List<IndexVO> selectIndexSiteIncreaseList(Wrapper<Channel> wrapper) {
-	 return getBaseMapper().selectIndexSiteIncreaseList(wrapper);
-  }
-
-  @Override
-  @Transactional(rollbackFor = Exception.class)
-  public boolean siteVerify(Channel channel) {
-
-    if(channel.getVerifyStatus() == ChannelVerifyStatusEnum.ACCEPT) {
-      channel.setCertifyStatus(ChannelCertifyStatusEnum.CERTIFIED);
-
-      // 获取经销商信息
-      Channel param = this.getById(channel.getChannelId());
-      // 设置保存地址信息
-      UserAddr userAddr = new UserAddr();
-      userAddr.setUserId(param.getUserId());
-      userAddr.setReceiver(param.getContact());
-      userAddr.setProvince(param.getProvince());
-      userAddr.setProvinceId(param.getProvinceId());
-      userAddr.setCity(param.getCity());
-      userAddr.setCityId(param.getCityId());
-      userAddr.setArea(param.getArea());
-      userAddr.setAreaId(param.getAreaId());
-      userAddr.setAddr(param.getAddress());
-      userAddr.setMobile(param.getMobile());
-      userAddr.setStatus(1);
-      int count = userAddrService.count(new LambdaQueryWrapper<UserAddr>().eq(UserAddr::getUserId, channel.getUserId()));
-      if (count == 0) {
-        userAddr.setCommonAddr(1);
-      }
-      userAddrService.save(userAddr);
-
-    }else {
-      channel.setCertifyStatus(ChannelCertifyStatusEnum.NOT_CERTIFIED);
-    }
-    // 更新经销商信息
-    channelService.updateById(channel);
-
-    return true;
-  }
+                // 获取默认的角色
+                SysRole sysRole = roleService.selectDefaultRoleByType(
+                    channelRole == ChannelRoleEnum.CHANNEL ? RoleTypeEnum.CHANNEL_ROLE.getValue()
+                        : RoleTypeEnum.SALESITE_ROLE.getValue());
+                if (null == sysRole || null == sysRole.getRoleId()) {
+                    throw new ServiceException(
+                        "未设置默认角色,请联系管理员");
+                }
+                Long[] roleIds = new Long[1];
+                roleIds[0] = sysRole.getRoleId();
+                sysUser.setRoleIds(roleIds);
+                int userNum = userService.insertUser(sysUser);
+                if (userNum == 0 || null == sysUser.getUserId()) {
+                    throw new ServiceException("账号创建失败,请联系管理员");
+                }
+            }
+            channel.setUserId(sysUser.getUserId());
+            boolean ures = channelService.updateById(channel);
+            if (!ures) {
+                throw new ServiceException("请联系管理员");
+            }
+            // 4.发送账号创建成功短信
+            JSMSUtils.sendChannelActNotify(channel.getMobile());
+        } else {
+            throw new ServiceException("请联系管理员");
+        }
+    }
+
+
+    @Override
+    @Transactional
+    public void updateChannel(Channel channel, boolean mobileChange) {
+        // 4.更新入库
+        boolean editRes = channelService.updateById(channel);
+        if (editRes && mobileChange
+            && null != channel.getUserId()) {
+            SysUser sysUser = new SysUser();
+            sysUser.setUserId(channel.getUserId());
+            sysUser.setUserName(channel.getMobile());
+            sysUser.setPhonenumber(channel.getMobile());
+            sysUser.setNickName(channel.getName());
+            sysUser.setDeptId(SecurityUtils.getDeptId());
+            int userNum = userService.updateUser(sysUser);
+            if (userNum == 0 || null == sysUser.getUserId()) {
+                throw new ServiceException("更新失败,请联系管理员");
+            }
+            // 发送账号更新成功短信
+        }
+    }
+
+    @Override
+    public List<ChannelVO> selectChannelVoList(Wrapper<Channel> queryWrapper) {
+        return getBaseMapper().selectChannelVoList(queryWrapper);
+    }
+
+    @Override
+    public List<ChannelVO> selectChannelList(Wrapper<Channel> queryWrapper) {
+        return getBaseMapper().selectChannelList(queryWrapper);
+    }
+
+    @Override
+    public List<ChannelVO> selectSaleSiteList(Wrapper<Channel> queryWrapper) {
+        return getBaseMapper().selectSaleSiteList(queryWrapper);
+    }
+
+    @Override
+    public Channel getChannelByUserId(Long userId) {
+        return getBaseMapper().selectOne(
+            new LambdaQueryWrapper<Channel>().eq(Channel::getUserId, userId));
+    }
+
+    @Override
+    public int getChannelSiteCnt(String channelNo) {
+        return getBaseMapper().getChannelSiteCnt(channelNo);
+    }
+
+    @Override
+    public ChannelVO getChannelVoById(Long channelId) {
+        List<ChannelVO> channelVOList = getBaseMapper().selectChannelVoList(
+            new QueryWrapper<Channel>().eq("t1.channel_id", channelId));
+        if (CollectionUtils.isEmpty(channelVOList)) {
+            return null;
+        }
+        return channelVOList.get(0);
+    }
+
+    @Override
+    public ChannelOperDataVO getPromoterOperData(String channelNo, Integer days) {
+        ChannelOperDataVO channelOperData = new ChannelOperDataVO();
+        // 查询销售金额
+        channelOperData.setSaleAmt(channelCommissionService.getChannelSaleAmtCnt(channelNo, days));
+        // 查询佣金金额
+        channelOperData.setCommAmt(channelCommissionService.getChannelCommAmtCnt(channelNo, days));
+
+        // 盲票销量
+        channelOperData.setTicketSaleCnt(userTicketOrderService.getPromoterTicketSaleCnt(channelNo, days));
+
+        return channelOperData;
+    }
+
+    @Override
+    public ChannelOperDataVO getChannelOperData(String channelNo, int days) {
+        ChannelOperDataVO channelOperData = new ChannelOperDataVO();
+        // 查询销售金额
+        channelOperData.setSaleAmt(channelCommissionService.getChannelSaleAmtCnt(channelNo, days));
+        // 查询佣金金额
+        channelOperData.setCommAmt(channelCommissionService.getChannelCommAmtCnt(channelNo, days));
+        // 查询新增用户数
+        int newUserCnt = channelUserRelService.getChannelNewUserCnt(channelNo, days);
+        channelOperData.setNewUserCnt(newUserCnt);
+        return channelOperData;
+    }
+
+
+    @Override
+    public ChannelOperDataVO getChannelTotalOperData(String channelNo) {
+        ChannelOperDataVO channelOperData = new ChannelOperDataVO();
+        // 查询销售金额
+        channelOperData.setSaleAmt(channelCommissionService.getChannelTotalSaleAmtCnt(channelNo));
+        // 查询佣金金额
+        channelOperData.setCommAmt(channelCommissionService.getChannelTotalCommAmtCnt(channelNo));
+        // 查询新增用户数
+        // int newUserCnt = channelUserRelService.getChannelNewUserCnt(channelNo, days);
+        // channelOperData.setNewUserCnt(newUserCnt);
+        return channelOperData;
+    }
+
+
+    @Override
+    public List<IndexVO> selectIndexSiteIncreaseList(Wrapper<Channel> wrapper) {
+        return getBaseMapper().selectIndexSiteIncreaseList(wrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean siteVerify(Channel channel) {
+
+        if (channel.getVerifyStatus() == ChannelVerifyStatusEnum.ACCEPT) {
+            channel.setCertifyStatus(ChannelCertifyStatusEnum.CERTIFIED);
+
+            // 获取经销商信息
+            Channel param = this.getById(channel.getChannelId());
+            // 设置保存地址信息
+            UserAddr userAddr = new UserAddr();
+            userAddr.setUserId(param.getUserId());
+            userAddr.setReceiver(param.getContact());
+            userAddr.setProvince(param.getProvince());
+            userAddr.setProvinceId(param.getProvinceId());
+            userAddr.setCity(param.getCity());
+            userAddr.setCityId(param.getCityId());
+            userAddr.setArea(param.getArea());
+            userAddr.setAreaId(param.getAreaId());
+            userAddr.setAddr(param.getAddress());
+            userAddr.setMobile(param.getMobile());
+            userAddr.setStatus(1);
+            int count = userAddrService.count(
+                new LambdaQueryWrapper<UserAddr>().eq(UserAddr::getUserId, channel.getUserId()));
+            if (count == 0) {
+                userAddr.setCommonAddr(1);
+            }
+            userAddrService.save(userAddr);
+
+        } else {
+            channel.setCertifyStatus(ChannelCertifyStatusEnum.NOT_CERTIFIED);
+        }
+        // 更新经销商信息
+        channelService.updateById(channel);
+
+        return true;
+    }
 }

+ 27 - 0
mp-service/src/main/java/com/qs/mp/channel/service/impl/PromoterUserServiceImpl.java

@@ -0,0 +1,27 @@
+package com.qs.mp.channel.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.qs.mp.channel.domain.Channel;
+import com.qs.mp.channel.domain.PromoterUser;
+import com.qs.mp.channel.domain.vo.PromoterVO;
+import com.qs.mp.channel.mapper.PromoterUserMapper;
+import com.qs.mp.channel.service.IPromoterUserService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 推广员用户关联表 服务实现类
+ * </p>
+ *
+ * @author quanshu
+ * @since 2022-08-08
+ */
+@Service
+public class PromoterUserServiceImpl extends ServiceImpl<PromoterUserMapper, PromoterUser> implements IPromoterUserService {
+
+    @Override
+    public PromoterVO getPromoterByQueryWrapper(QueryWrapper<Channel> queryWrapper) {
+        return getBaseMapper().getPromoterByQueryWrapper(queryWrapper);
+    }
+}

+ 2 - 2
mp-service/src/main/java/com/qs/mp/framework/service/impl/AsyncTaskServiceImpl.java

@@ -207,7 +207,7 @@ public class AsyncTaskServiceImpl extends ServiceImpl<AsyncTaskMapper, AsyncTask
     @Transactional(rollbackFor = Exception.class)
     public void cardOrderDeliver(AsyncTask asyncTask) {
         String orderId = asyncTask.getBizId();
-        LogUtil.error(logger, "收到卡密订单自动发货任务。orderId=" + orderId);
+        LogUtil.info(logger, "收到卡密订单自动发货任务。orderId=" + orderId);
         UserDeliverOrder userDeliverOrder = userDeliverOrderService.getById(orderId);
         // 如果是普通订单或者订单不为待发货则不处理
         if (DeliverOrderTypeEnum.ORDINARY.getValue().equals(userDeliverOrder.getType())
@@ -233,7 +233,7 @@ public class AsyncTaskServiceImpl extends ServiceImpl<AsyncTaskMapper, AsyncTask
                 .orderByAsc("rand()")
                 .last("limit " + userDeliverOrderItem.getGoodsNum()));
             if (CollectionUtils.isEmpty(goodsCardList) || goodsCardList.size() < userDeliverOrderItem.getGoodsNum()) {
-                LogUtil.error(logger,"卡密不足,无法发货。orderId:{0},itemId:{1},goodsId:{2}",userDeliverOrderItem.getOrderId(),
+                LogUtil.info(logger,"卡密不足,无法发货。orderId:{0},itemId:{1},goodsId:{2}",userDeliverOrderItem.getOrderId(),
                     userDeliverOrderItem.getItemId(), userDeliverOrderItem.getGoodsId());
                 throw new ServiceException("卡密不足,无法发货");
             }

+ 1 - 1
mp-service/src/main/java/com/qs/mp/framework/service/impl/WxUrlLinkServiceImpl.java

@@ -106,7 +106,7 @@ public class WxUrlLinkServiceImpl implements IWxUrlLinkService {
     param.put("path", path + "?" + scene); // 页面路径
     //param.put("scene", scene); // 参数
 //    param.put("check_path", true);// 为 true 时 page 必须是已经发布的小程序存在的页面(否则报错);为 false 时允许小程序未发布或者 page 不存在
-//    param.put("env_version", envVersion);
+    param.put("env_version", envVersion);
     // 获取access_token
     String accessToken = appTokenService.getAccessToken(appId);
     InputStream in = HttpUtils.sendImagePost(

+ 73 - 111
mp-service/src/main/java/com/qs/mp/system/service/impl/SysRoleServiceImpl.java

@@ -27,12 +27,12 @@ import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 角色 业务层处理
- * 
+ *
  * @author ygp
  */
 @Service
-public class SysRoleServiceImpl implements ISysRoleService
-{
+public class SysRoleServiceImpl implements ISysRoleService {
+
     @Autowired
     private SysRoleMapper roleMapper;
 
@@ -47,34 +47,29 @@ public class SysRoleServiceImpl implements ISysRoleService
 
     /**
      * 根据条件分页查询角色数据
-     * 
+     *
      * @param role 角色信息
      * @return 角色数据集合信息
      */
     @Override
     @DataScope(deptAlias = "d")
-    public List<SysRole> selectRoleList(SysRole role)
-    {
+    public List<SysRole> selectRoleList(SysRole role) {
         return roleMapper.selectRoleList(role);
     }
 
     /**
      * 根据用户ID查询角色
-     * 
+     *
      * @param userId 用户ID
      * @return 角色列表
      */
     @Override
-    public List<SysRole> selectRolesByUserId(Long userId)
-    {
+    public List<SysRole> selectRolesByUserId(Long userId) {
         List<SysRole> userRoles = roleMapper.selectRolePermissionByUserId(userId);
         List<SysRole> roles = selectRoleAll();
-        for (SysRole role : roles)
-        {
-            for (SysRole userRole : userRoles)
-            {
-                if (role.getRoleId().longValue() == userRole.getRoleId().longValue())
-                {
+        for (SysRole role : roles) {
+            for (SysRole userRole : userRoles) {
+                if (role.getRoleId().longValue() == userRole.getRoleId().longValue()) {
                     role.setFlag(true);
                     break;
                 }
@@ -85,19 +80,16 @@ public class SysRoleServiceImpl implements ISysRoleService
 
     /**
      * 根据用户ID查询权限
-     * 
+     *
      * @param userId 用户ID
      * @return 权限列表
      */
     @Override
-    public Set<String> selectRolePermissionByUserId(Long userId)
-    {
+    public Set<String> selectRolePermissionByUserId(Long userId) {
         List<SysRole> perms = roleMapper.selectRolePermissionByUserId(userId);
         Set<String> permsSet = new HashSet<>();
-        for (SysRole perm : perms)
-        {
-            if (StringUtils.isNotNull(perm))
-            {
+        for (SysRole perm : perms) {
+            if (StringUtils.isNotNull(perm)) {
                 permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(",")));
             }
         }
@@ -106,52 +98,47 @@ public class SysRoleServiceImpl implements ISysRoleService
 
     /**
      * 查询所有角色
-     * 
+     *
      * @return 角色列表
      */
     @Override
-    public List<SysRole> selectRoleAll()
-    {
+    public List<SysRole> selectRoleAll() {
         return SpringUtils.getAopProxy(this).selectRoleList(new SysRole());
     }
 
     /**
      * 根据用户ID获取角色选择框列表
-     * 
+     *
      * @param userId 用户ID
      * @return 选中角色ID列表
      */
     @Override
-    public List<Integer> selectRoleListByUserId(Long userId)
-    {
+    public List<Integer> selectRoleListByUserId(Long userId) {
         return roleMapper.selectRoleListByUserId(userId);
     }
 
     /**
      * 通过角色ID查询角色
-     * 
+     *
      * @param roleId 角色ID
      * @return 角色对象信息
      */
     @Override
-    public SysRole selectRoleById(Long roleId)
-    {
+    public SysRole selectRoleById(Long roleId) {
         return roleMapper.selectRoleById(roleId);
     }
 
     /**
      * 校验角色名称是否唯一
-     * 
+     *
      * @param role 角色信息
      * @return 结果
      */
     @Override
-    public String checkRoleNameUnique(SysRole role)
-    {
+    public String checkRoleNameUnique(SysRole role) {
         Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId();
         SysRole info = roleMapper.checkRoleNameUnique(role.getRoleName());
-        if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue())
-        {
+        if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) {
             return UserConstants.NOT_UNIQUE;
         }
         return UserConstants.UNIQUE;
@@ -159,17 +146,15 @@ public class SysRoleServiceImpl implements ISysRoleService
 
     /**
      * 校验角色权限是否唯一
-     * 
+     *
      * @param role 角色信息
      * @return 结果
      */
     @Override
-    public String checkRoleKeyUnique(SysRole role)
-    {
+    public String checkRoleKeyUnique(SysRole role) {
         Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId();
         SysRole info = roleMapper.checkRoleKeyUnique(role.getRoleKey());
-        if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue())
-        {
+        if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) {
             return UserConstants.NOT_UNIQUE;
         }
         return UserConstants.UNIQUE;
@@ -177,12 +162,11 @@ public class SysRoleServiceImpl implements ISysRoleService
 
     /**
      * 校验角色是否允许操作
-     * 
+     *
      * @param role 角色信息
      */
     @Override
-    public void checkRoleAllowed(SysRole role)
-    {
+    public void checkRoleAllowed(SysRole role) {
 //        if (StringUtils.isNotNull(role.getRoleId()) && role.isAdmin())
 //        {
 //            throw new ServiceException("不允许操作超级管理员角色");
@@ -191,19 +175,16 @@ public class SysRoleServiceImpl implements ISysRoleService
 
     /**
      * 校验角色是否有数据权限
-     * 
+     *
      * @param roleId 角色id
      */
     @Override
-    public void checkRoleDataScope(Long roleId)
-    {
-        if (!SysUser.isAdmin(SecurityUtils.getUserId()))
-        {
+    public void checkRoleDataScope(Long roleId) {
+        if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
             SysRole role = new SysRole();
             role.setRoleId(roleId);
             List<SysRole> roles = SpringUtils.getAopProxy(this).selectRoleList(role);
-            if (StringUtils.isEmpty(roles))
-            {
+            if (StringUtils.isEmpty(roles)) {
                 throw new ServiceException("没有权限访问角色数据!");
             }
         }
@@ -211,26 +192,24 @@ public class SysRoleServiceImpl implements ISysRoleService
 
     /**
      * 通过角色ID查询角色使用数量
-     * 
+     *
      * @param roleId 角色ID
      * @return 结果
      */
     @Override
-    public int countUserRoleByRoleId(Long roleId)
-    {
+    public int countUserRoleByRoleId(Long roleId) {
         return userRoleMapper.countUserRoleByRoleId(roleId);
     }
 
     /**
      * 新增保存角色信息
-     * 
+     *
      * @param role 角色信息
      * @return 结果
      */
     @Override
     @Transactional
-    public int insertRole(SysRole role)
-    {
+    public int insertRole(SysRole role) {
         // 新增角色信息
         roleMapper.insertRole(role);
         return insertRoleMenu(role);
@@ -238,14 +217,13 @@ public class SysRoleServiceImpl implements ISysRoleService
 
     /**
      * 修改保存角色信息
-     * 
+     *
      * @param role 角色信息
      * @return 结果
      */
     @Override
     @Transactional
-    public int updateRole(SysRole role)
-    {
+    public int updateRole(SysRole role) {
         // 修改角色信息
         roleMapper.updateRole(role);
         // 删除角色与菜单关联
@@ -255,26 +233,24 @@ public class SysRoleServiceImpl implements ISysRoleService
 
     /**
      * 修改角色状态
-     * 
+     *
      * @param role 角色信息
      * @return 结果
      */
     @Override
-    public int updateRoleStatus(SysRole role)
-    {
+    public int updateRoleStatus(SysRole role) {
         return roleMapper.updateRole(role);
     }
 
     /**
      * 修改数据权限信息
-     * 
+     *
      * @param role 角色信息
      * @return 结果
      */
     @Override
     @Transactional
-    public int authDataScope(SysRole role)
-    {
+    public int authDataScope(SysRole role) {
         // 修改角色信息
         roleMapper.updateRole(role);
         // 删除角色与部门关联
@@ -285,23 +261,20 @@ public class SysRoleServiceImpl implements ISysRoleService
 
     /**
      * 新增角色菜单信息
-     * 
+     *
      * @param role 角色对象
      */
-    public int insertRoleMenu(SysRole role)
-    {
+    public int insertRoleMenu(SysRole role) {
         int rows = 1;
         // 新增用户与角色管理
         List<SysRoleMenu> list = new ArrayList<SysRoleMenu>();
-        for (Long menuId : role.getMenuIds())
-        {
+        for (Long menuId : role.getMenuIds()) {
             SysRoleMenu rm = new SysRoleMenu();
             rm.setRoleId(role.getRoleId());
             rm.setMenuId(menuId);
             list.add(rm);
         }
-        if (list.size() > 0)
-        {
+        if (list.size() > 0) {
             rows = roleMenuMapper.batchRoleMenu(list);
         }
         return rows;
@@ -312,20 +285,17 @@ public class SysRoleServiceImpl implements ISysRoleService
      *
      * @param role 角色对象
      */
-    public int insertRoleDept(SysRole role)
-    {
+    public int insertRoleDept(SysRole role) {
         int rows = 1;
         // 新增角色与部门(数据权限)管理
         List<SysRoleDept> list = new ArrayList<SysRoleDept>();
-        for (Long deptId : role.getDeptIds())
-        {
+        for (Long deptId : role.getDeptIds()) {
             SysRoleDept rd = new SysRoleDept();
             rd.setRoleId(role.getRoleId());
             rd.setDeptId(deptId);
             list.add(rd);
         }
-        if (list.size() > 0)
-        {
+        if (list.size() > 0) {
             rows = roleDeptMapper.batchRoleDept(list);
         }
         return rows;
@@ -333,14 +303,13 @@ public class SysRoleServiceImpl implements ISysRoleService
 
     /**
      * 通过角色ID删除角色
-     * 
+     *
      * @param roleId 角色ID
      * @return 结果
      */
     @Override
     @Transactional
-    public int deleteRoleById(Long roleId)
-    {
+    public int deleteRoleById(Long roleId) {
         // 删除角色与菜单关联
         roleMenuMapper.deleteRoleMenuByRoleId(roleId);
         // 删除角色与部门关联
@@ -350,20 +319,17 @@ public class SysRoleServiceImpl implements ISysRoleService
 
     /**
      * 批量删除角色信息
-     * 
+     *
      * @param roleIds 需要删除的角色ID
      * @return 结果
      */
     @Override
     @Transactional
-    public int deleteRoleByIds(Long[] roleIds)
-    {
-        for (Long roleId : roleIds)
-        {
+    public int deleteRoleByIds(Long[] roleIds) {
+        for (Long roleId : roleIds) {
             checkRoleAllowed(new SysRole(roleId));
             SysRole role = selectRoleById(roleId);
-            if (countUserRoleByRoleId(roleId) > 0)
-            {
+            if (countUserRoleByRoleId(roleId) > 0) {
                 throw new ServiceException(String.format("%1$s已分配,不能删除", role.getRoleName()));
             }
         }
@@ -376,43 +342,39 @@ public class SysRoleServiceImpl implements ISysRoleService
 
     /**
      * 取消授权用户角色
-     * 
+     *
      * @param userRole 用户和角色关联信息
      * @return 结果
      */
     @Override
-    public int deleteAuthUser(SysUserRole userRole)
-    {
+    public int deleteAuthUser(SysUserRole userRole) {
         return userRoleMapper.deleteUserRoleInfo(userRole);
     }
 
     /**
      * 批量取消授权用户角色
-     * 
-     * @param roleId 角色ID
+     *
+     * @param roleId  角色ID
      * @param userIds 需要取消授权的用户数据ID
      * @return 结果
      */
     @Override
-    public int deleteAuthUsers(Long roleId, Long[] userIds)
-    {
+    public int deleteAuthUsers(Long roleId, Long[] userIds) {
         return userRoleMapper.deleteUserRoleInfos(roleId, userIds);
     }
 
     /**
      * 批量选择授权用户角色
-     * 
-     * @param roleId 角色ID
+     *
+     * @param roleId  角色ID
      * @param userIds 需要删除的用户数据ID
      * @return 结果
      */
     @Override
-    public int insertAuthUsers(Long roleId, Long[] userIds)
-    {
+    public int insertAuthUsers(Long roleId, Long[] userIds) {
         // 新增用户与角色管理
         List<SysUserRole> list = new ArrayList<SysUserRole>();
-        for (Long userId : userIds)
-        {
+        for (Long userId : userIds) {
             SysUserRole ur = new SysUserRole();
             ur.setUserId(userId);
             ur.setRoleId(roleId);
@@ -421,14 +383,14 @@ public class SysRoleServiceImpl implements ISysRoleService
         return userRoleMapper.batchUserRole(list);
     }
 
-	@Override
-	public SysRole selectDefaultRoleByType(String roleType) {
-		return roleMapper.selectDefaultRoleByType(roleType);
-	}
+    @Override
+    public SysRole selectDefaultRoleByType(String roleType) {
+        return roleMapper.selectDefaultRoleByType(roleType);
+    }
+
+    @Override
+    public List<SysRole> selectRoleListByType(String roleType) {
+        return roleMapper.selectRoleListByType(roleType);
+    }
 
-	@Override
-	public List<SysRole> selectRoleListByType(String roleType) {
-		return roleMapper.selectRoleListByType(roleType);
-	}
-    
 }

+ 4 - 0
mp-service/src/main/java/com/qs/mp/user/domain/UserTicketOrder.java

@@ -147,6 +147,10 @@ public class UserTicketOrder implements Serializable {
   @TableField("channel_id")
   private Long channelId;
 
+  @ApiModelProperty("推广员id")
+  @TableField("promoter_id")
+  private Long promoterId;
+
 
   @ApiModelProperty("来源小程序id")
   @TableField("app_id")

+ 3 - 0
mp-service/src/main/java/com/qs/mp/user/domain/param/TicketOrderParam.java

@@ -26,4 +26,7 @@ public class TicketOrderParam {
 
 	@ApiModelProperty("小程序,1盲票,2码上兑券,3支付宝盲票")
 	private Integer appSource;
+
+	@ApiModelProperty("门店id")
+	private Long channelId;
 }

+ 6 - 0
mp-service/src/main/java/com/qs/mp/user/domain/vo/TicketOrderSettleVO.java

@@ -1,5 +1,6 @@
 package com.qs.mp.user.domain.vo;
 
+import com.qs.mp.channel.domain.vo.PromoterVO;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import java.util.ArrayList;
@@ -72,6 +73,11 @@ public class TicketOrderSettleVO {
     @ApiModelProperty("小程序appId")
     private String appId;
 
+
+    @ApiModelProperty("用户关联的推广员")
+    private PromoterVO promoter;
+
+
     /**
      * 使用优惠券列表
      */

+ 5 - 1
mp-service/src/main/java/com/qs/mp/user/domain/vo/UserPrizeStorageVO.java

@@ -16,7 +16,7 @@ import java.math.BigDecimal;
  * @author Cup
  * @date 2022/5/24
  */
-@ApiModel("用户事务奖品库出参类")
+@ApiModel("用户实物奖品库出参类")
 @Data
 public class UserPrizeStorageVO extends UserPrizeStorage {
 
@@ -33,4 +33,8 @@ public class UserPrizeStorageVO extends UserPrizeStorage {
     @ApiModelProperty("盲票形式(线上或线下)")
     @JSONField(serialzeFeatures = SerializerFeature.WriteEnumUsingToString)
     private TicketTypeEnum type;
+
+
+    @ApiModelProperty("回收开关")
+    private boolean recovery = true;
 }

+ 4 - 0
mp-service/src/main/java/com/qs/mp/user/domain/vo/UserShareVO.java

@@ -20,4 +20,8 @@ public class UserShareVO {
   public static final String SHARE_TYPE_USER = "1";
   @ApiModelProperty("经销商分享")
   public static final String SHARE_TYPE_SITE = "2";
+
+  @ApiModelProperty("推广员id")
+  private Long promoterId;
+
 }

+ 1 - 0
mp-service/src/main/java/com/qs/mp/user/mapper/UserTicketOrderMapper.java

@@ -118,4 +118,5 @@ public interface UserTicketOrderMapper extends BaseMapper<UserTicketOrder> {
 	 */
     List<IndexVO> selectIndexTicketSiteTopByTicketOrderAndChannelOrder(@Param("param") IndexTicketSiteTopQueryParam indexTicketSiteTopQueryParam);
 
+    long getPromoterTicketSaleCnt(@Param("channelNo") String channelNo,@Param("days") int days);
 }

+ 2 - 0
mp-service/src/main/java/com/qs/mp/user/service/IUserTicketOrderService.java

@@ -173,4 +173,6 @@ public interface IUserTicketOrderService extends IService<UserTicketOrder> {
      * @return
      */
     List<IndexVO> selectIndexTicketSiteTopByTicketOrderAndChannelOrder(IndexTicketSiteTopQueryParam indexTicketSiteTopQueryParam);
+
+    long getPromoterTicketSaleCnt(String channelNo, Integer days);
 }

+ 5 - 0
mp-service/src/main/java/com/qs/mp/user/service/impl/UserDeliverOrderServiceImpl.java

@@ -107,6 +107,11 @@ public class UserDeliverOrderServiceImpl extends ServiceImpl<UserDeliverOrderMap
         userDeliverOrder.setFreightAmt(orderSettleVO.getFreightAmt());
         userDeliverOrder.setAppId(orderSettleVO.getAppId());
         userDeliverOrder.setMemo(memo);
+
+        if (userDeliverOrder.getOrderNum() <= 0) {
+            throw new ServiceException("订单商品数量不能为0");
+        }
+
         if (orderSettleVO.getPayAmt() > 0) {
             userDeliverOrder.setStatus(DeliverOrderStatusEnum.NOT_PAY);
         } else {

+ 55 - 4
mp-service/src/main/java/com/qs/mp/user/service/impl/UserTicketOrderServiceImpl.java

@@ -59,6 +59,8 @@ import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.http.util.Asserts;
+import org.apache.poi.ss.formula.functions.T;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.aop.framework.AopContext;
@@ -150,6 +152,10 @@ public class UserTicketOrderServiceImpl extends
     @Autowired
     private ICouponPkgService couponPkgService;
 
+
+    @Autowired
+    private IPromoterUserService promoterUserService;
+
     @Override
     public String submitOrder(Long userId, TicketOrderSettleVO orderSettleVO,
         UserShareVO userShareVO) {
@@ -167,7 +173,7 @@ public class UserTicketOrderServiceImpl extends
         }
 
         // 线下票不需锁库存,待付款成功后再更新票组销量
-        return proxy.createOfflineOrder(userId, orderSettleVO);
+        return proxy.createOfflineOrder(userId, orderSettleVO, userShareVO);
     }
 
     @Transactional(rollbackFor = Exception.class)
@@ -280,7 +286,7 @@ public class UserTicketOrderServiceImpl extends
     }
 
     @Transactional(rollbackFor = Exception.class)
-    public String createOfflineOrder(Long userId, TicketOrderSettleVO orderSettleVO) {
+    public String createOfflineOrder(Long userId, TicketOrderSettleVO orderSettleVO, UserShareVO userShareVO) {
         Ticket ticket = ticketService.getById(orderSettleVO.getTicketId());
         Assert.isTrue(ticket.getStatus() == TicketStatusEnum.NOT_PAY,
             "盲票已付款,ticketId:" + ticket.getTicketId());
@@ -313,6 +319,10 @@ public class UserTicketOrderServiceImpl extends
         ticketOrder.setResource(TicketTypeEnum.OFFLINE);
         ticketOrder.setCouponInfo(couponIds);
         ticketOrder.setStatus(UserTicketOrderStatusEnum.NOT_PAY);
+        // 设置推广员id
+        if (userShareVO.getPromoterId() != null && userShareVO.getPromoterId() > 0) {
+            ticketOrder.setPromoterId(userShareVO.getPromoterId());
+        }
         if (orderSettleVO.getPayAmt() == 0) {
             ticketOrder.setCommStatus(CommStatusEnum.YES); // 无需结佣,直接置为已结佣
         }
@@ -508,6 +518,30 @@ public class UserTicketOrderServiceImpl extends
 
         }
 
+        // 绑定用户和推广员的关系
+        if (ticketOrder.getPromoterId() != null) {
+            int count = promoterUserService.count(new LambdaQueryWrapper<PromoterUser>()
+                .eq(PromoterUser::getUserId, ticketOrder.getUserId())
+                .eq(PromoterUser::getChannelId, ticketOrder.getChannelId()));
+
+            if (count > 0) {
+                // 清除原来的关系
+                boolean remove = promoterUserService.remove(new LambdaUpdateWrapper<PromoterUser>()
+                    .eq(PromoterUser::getUserId, ticketOrder.getUserId())
+                    .eq(PromoterUser::getChannelId, ticketOrder.getChannelId()));
+                if (!remove) {
+                    throw new ServiceException("支付回调清除用户和原推广员的关系失败,orderId:" + ticketOrder.getOrderId());
+                }
+            }
+
+            PromoterUser promoterUser = new PromoterUser();
+            promoterUser.setPromoterId(ticketOrder.getPromoterId());
+            promoterUser.setUserId(ticketOrder.getUserId());
+            promoterUser.setChannelId(ticketOrder.getChannelId());
+            Assert.isTrue(promoterUserService.save(promoterUser), "支付回调,保存用户和推广员关系失败,orderId:" + ticketOrder.getOrderId());
+        }
+
+
         // 更新订单状态为已完成
         boolean updateRst = update(
             new LambdaUpdateWrapper<UserTicketOrder>().set(UserTicketOrder::getStatus,
@@ -524,7 +558,7 @@ public class UserTicketOrderServiceImpl extends
             new LambdaQueryWrapper<UserTicketOrderItem>().eq(UserTicketOrderItem::getOrderId, ticketOrder.getOrderId()));
         for (UserTicketOrderItem orderItem : userTicketOrderItemList) {
             Ticket ticket = ticketService.getById(orderItem.getTicketId());
-            // TODO: 线上和线下票如果有关联商品,都要发送关联商品到用户的仓库中
+            // 线上和线下票如果有关联商品,都要发送关联商品到用户的仓库中
             List<TicketBoxGoods> ticketBoxGoodsList = ticketBoxGoodsService.list(new LambdaQueryWrapper<TicketBoxGoods>()
                 .eq(TicketBoxGoods::getBoxId, ticketOrder.getBoxId()));
             if (CollectionUtils.isNotEmpty(ticketBoxGoodsList)) {
@@ -573,7 +607,18 @@ public class UserTicketOrderServiceImpl extends
         if (null != channelCommParam.getChannelId()) {
             // 线下购票,优先给当前票的经销商渠道分润
             TicketBox ticketBox = ticketBoxService.getById(channelCommParam.getBoxId());
-            Channel channel = channelService.getById(channelCommParam.getChannelId());
+
+            // 如果有推广员则先给推广员分佣
+            Channel channel = new Channel();
+            if (channelCommParam.getPromoterId() != null && channelCommParam.getPromoterId() > 0) {
+                channel = channelService.getById(channelCommParam.getPromoterId());
+                if (channel == null) {
+                    channel = channelService.getById(channelCommParam.getChannelId());
+                }
+            } else {
+                channel = channelService.getById(channelCommParam.getChannelId());
+            }
+
             ChannelCommission siteCommission = saveSiteCommAmt(channelCommParam, ticketBox, channel);
             // 经销商账户余额增加
             changeMoney(channel, siteCommission);
@@ -707,6 +752,12 @@ public class UserTicketOrderServiceImpl extends
         return getBaseMapper().selectIndexTicketSiteTopByTicketOrderAndChannelOrder(indexTicketSiteTopQueryParam);
     }
 
+
+    @Override
+    public long getPromoterTicketSaleCnt(String channelNo, Integer days) {
+        return getBaseMapper().getPromoterTicketSaleCnt(channelNo, days == 1?0:days);
+    }
+
     @Override
     public UserTicketOrderDetailVO detail(String orderId) {
         QueryWrapper<UserTicketOrder> queryWrapper = new QueryWrapper<>();

+ 24 - 0
mp-service/src/main/resources/mapper/channel/ChannelMapper.xml

@@ -117,4 +117,28 @@
 		GROUP BY time
 	</select>
 
+    <select id="listPromoterByQueryWrapper" resultType="com.qs.mp.channel.domain.vo.PromoterListVO">
+      select t1.channel_id,
+             t1.name,
+             t1.mobile,
+             t1.comm_rate,
+             t1.created_time,
+             t2.site_name,
+            if(t3.sale_num is null ,0,t3.sale_num) as sale_num,
+            if(t3.sale_amt is null ,0,t3.sale_amt) as sale_amt,
+            if(t4.comm_amt is null ,0,t4.comm_amt) as comm_amt
+      from mp_channel t1
+             left join mp_channel t2 on t1.parent_id = t2.channel_id
+             left join (select promoter_id,
+                               sum(ticket_num) as sale_num,
+                               sum(pay_amt) as sale_amt
+                        from mp_user_ticket_order
+                        where status = 1
+                        group by promoter_id) t3 on t1.channel_id = t3.promoter_id
+             left join (select channel_id,
+                               sum(comm_amt) as comm_amt
+                        from mp_channel_commission
+                        group by channel_id) t4 on t1.channel_id = t4.channel_id
+      ${ew.customSqlSegment}
+  </select>
 </mapper>

+ 30 - 0
mp-service/src/main/resources/mapper/channel/PromoterUserMapper.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qs.mp.channel.mapper.PromoterUserMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qs.mp.channel.domain.PromoterUser">
+        <id column="id" property="id" />
+        <result column="promoter_id" property="promoterId" />
+        <result column="user_id" property="userId" />
+        <result column="channel_id" property="channelId" />
+        <result column="created_time" property="createdTime" />
+        <result column="updated_time" property="updatedTime" />
+        <result column="is_deleted" property="isDeleted" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, promoter_id, user_id, channel_id, created_time, updated_time, is_deleted
+    </sql>
+
+    <select id="getPromoterByQueryWrapper" resultType="com.qs.mp.channel.domain.vo.PromoterVO">
+        select t5.*
+        from mp_promoter_user t1
+            left join mp_channel t2 on t1.channel_id = t2.channel_id
+            left join mp_channel_order_detail t3 on t2.channel_id = t3.channel_id
+            left join mp_ticket t4 on t3.pkg_id = t4.pkg_id
+            left join mp_channel t5 on t1.promoter_id = t5.channel_id
+        ${ew.customSqlSegment}
+    </select>
+</mapper>

+ 11 - 1
mp-service/src/main/resources/mapper/user/UserTicketOrderMapper.xml

@@ -167,11 +167,13 @@
 				t2.nick_name,
 				t2.phonenumber phone,
 				t3.name channelName,
-				t4.type ticketBoxType
+				t4.type ticketBoxType,
+				t5.name as promoterName
 		from mp_user_ticket_order t1
 			left join sys_user t2 on t1.user_id = t2.user_id
 			left join mp_channel t3 on t1.channel_id = t3.channel_id
 			left join mp_ticket_box t4 on t1.box_id = t4.box_id
+			left join mp_channel t5 on t1.promoter_id = t5.channel_id
 		${ew.customSqlSegment}
 	</select>
 
@@ -236,4 +238,12 @@
 		order by payAmt desc
 		limit 10;
 	</select>
+
+    <select id="getPromoterTicketSaleCnt" resultType="long">
+			select IFNULL(SUM(t1.ticket_num), 0) as ticketNum
+			from mp_user_ticket_order t1
+						 left join mp_channel t2 on t1.promoter_id = t2.channel_id
+			where (t2.channel_no like concat(#{channelNo},'.%') or t2.channel_no = #{channelNo})
+				AND t1.created_time > DATE_SUB(CURDATE(),INTERVAL #{days} DAY);
+  </select>
 </mapper>