From 598777b8b05496bbd6466f140bc95b990d94b104 Mon Sep 17 00:00:00 2001 From: wjt Date: Thu, 17 Aug 2023 11:03:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0elastic-job?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ad-distribute-starter-job/pom.xml | 15 +- .../common/job/XxlJobAutoConfiguration.java | 96 ------ .../job/properties/XxlAdminProperties.java | 19 -- .../job/properties/XxlExecutorProperties.java | 43 --- .../job/properties/XxlJobProperties.java | 33 -- .../main/resources/META-INF/spring.factories | 4 - ...ot.autoconfigure.AutoConfiguration.imports | 1 - .../baiye/system/service/SysUserService.java | 6 + .../service/impl/SysUserServiceImpl.java | 45 ++- admin/pom.xml | 5 + .../baiye/job/DistributeRecordReportJob.java | 34 ++ .../DistributeReportController.java | 37 +++ .../entity/DistributeReportChannelEntity.java | 67 ++++ .../entity/DistributeReportEntity.java | 60 ++++ .../entity/DistributeReportUserEntity.java | 63 ++++ .../mapper/DistributeReportChannelMapper.java | 11 + .../mapper/DistributeReportMapper.java | 11 + .../mapper/DistributeReportUserMapper.java | 11 + .../distribute/service/ClueRecordService.java | 8 + .../service/DistributeReportService.java | 23 ++ .../service/impl/ClueRecordServiceImpl.java | 8 + .../impl/DistributeReportServiceImpl.java | 303 ++++++++++++++++++ .../modules/distribute/vo/ReportFlowVO.java | 25 ++ admin/src/main/resources/application.yml | 11 +- 24 files changed, 712 insertions(+), 227 deletions(-) delete mode 100644 ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/XxlJobAutoConfiguration.java delete mode 100644 ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/properties/XxlAdminProperties.java delete mode 100644 ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/properties/XxlExecutorProperties.java delete mode 100644 ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/properties/XxlJobProperties.java delete mode 100644 ad-distribute-starters/ad-distribute-starter-job/src/main/resources/META-INF/spring.factories delete mode 100644 ad-distribute-starters/ad-distribute-starter-job/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 admin/src/main/java/com/baiye/job/DistributeRecordReportJob.java create mode 100644 admin/src/main/java/com/baiye/modules/distribute/controller/DistributeReportController.java create mode 100644 admin/src/main/java/com/baiye/modules/distribute/entity/DistributeReportChannelEntity.java create mode 100644 admin/src/main/java/com/baiye/modules/distribute/entity/DistributeReportEntity.java create mode 100644 admin/src/main/java/com/baiye/modules/distribute/entity/DistributeReportUserEntity.java create mode 100644 admin/src/main/java/com/baiye/modules/distribute/mapper/DistributeReportChannelMapper.java create mode 100644 admin/src/main/java/com/baiye/modules/distribute/mapper/DistributeReportMapper.java create mode 100644 admin/src/main/java/com/baiye/modules/distribute/mapper/DistributeReportUserMapper.java create mode 100644 admin/src/main/java/com/baiye/modules/distribute/service/DistributeReportService.java create mode 100644 admin/src/main/java/com/baiye/modules/distribute/service/impl/DistributeReportServiceImpl.java create mode 100644 admin/src/main/java/com/baiye/modules/distribute/vo/ReportFlowVO.java diff --git a/ad-distribute-starters/ad-distribute-starter-job/pom.xml b/ad-distribute-starters/ad-distribute-starter-job/pom.xml index 572578f..5c3b158 100644 --- a/ad-distribute-starters/ad-distribute-starter-job/pom.xml +++ b/ad-distribute-starters/ad-distribute-starter-job/pom.xml @@ -16,19 +16,10 @@ 8 - - com.xuxueli - xxl-job-core - - - org.springframework.boot - spring-boot-autoconfigure - - - org.springframework.boot - spring-boot-configuration-processor - true + com.example + elastic-job-springboot-core + 3.0-SNAPSHOT \ No newline at end of file diff --git a/ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/XxlJobAutoConfiguration.java b/ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/XxlJobAutoConfiguration.java deleted file mode 100644 index 375b029..0000000 --- a/ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/XxlJobAutoConfiguration.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.baiye.ballcat.common.job; - - -import com.baiye.ballcat.common.job.properties.XxlExecutorProperties; -import com.baiye.ballcat.common.job.properties.XxlJobProperties; -import com.xxl.job.core.executor.impl.XxlJobSpringExecutor; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.core.env.Environment; -import org.springframework.util.StringUtils; - -/** - * @author lengleng - * @date 2019-09-18 - *

- * xxl 初始化 - */ -@Slf4j -@AutoConfiguration -@EnableConfigurationProperties(XxlJobProperties.class) -@ConditionalOnProperty(prefix = XxlJobProperties.PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) -@RequiredArgsConstructor -public class XxlJobAutoConfiguration { - - private final Environment environment; - - @Bean - public XxlJobSpringExecutor xxlJobSpringExecutor(XxlJobProperties xxlJobProperties) { - if (log.isInfoEnabled()) { - log.info(">>>>>>>>>>> xxl-job config init."); - } - XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); - xxlJobSpringExecutor.setAdminAddresses(xxlJobProperties.getAdmin().getAddresses()); - XxlExecutorProperties executorProperties = xxlJobProperties.getExecutor(); - xxlJobSpringExecutor.setAppname(getExecutorName(executorProperties)); - xxlJobSpringExecutor.setIp(executorProperties.getIp()); - xxlJobSpringExecutor.setPort(executorProperties.getPort()); - xxlJobSpringExecutor.setAccessToken(getAccessToken(xxlJobProperties)); - xxlJobSpringExecutor.setLogPath(getLogPath(executorProperties)); - xxlJobSpringExecutor.setLogRetentionDays(executorProperties.getLogRetentionDays()); - xxlJobSpringExecutor.setAddress(executorProperties.getAddress()); - return xxlJobSpringExecutor; - } - - /** - * 获取执行器名称,缺省为Spring Boot应用名称 - * - * @param properties 执行器配置 - * @return 执行期名称 - */ - private String getExecutorName(XxlExecutorProperties properties) { - String appName = properties.getAppname(); - if (StringUtils.hasText(appName)) { - return appName; - } else { - return environment.getProperty("spring.application.name"); - } - } - - /** - * 获取xxl-job执行器通讯令牌 - * - * @param properties 主配置文件 - * @return - */ - private String getAccessToken(XxlJobProperties properties) { - if (StringUtils.hasText(properties.getAccessToken())) { - return properties.getAccessToken(); - } else { - log.warn("为提升系统安全性,生产环境建议启用调度中心和执行器安全性校验!可通过配置项 “xxl.job.accessToken” 进行AccessToken的设置"); - return null; - } - } - - /** - * 获取日志路径 - * - * @param properties 执行器配置文件 - * @return - */ - private String getLogPath(XxlExecutorProperties properties) { - String logPath = properties.getLogPath(); - if (StringUtils.hasText(logPath)) { - return logPath; - } - return environment.getProperty("logging.file.path", "logs") - .concat("/") - .concat(environment.getProperty("spring.application.name")) - .concat("/jobs"); - } - -} diff --git a/ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/properties/XxlAdminProperties.java b/ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/properties/XxlAdminProperties.java deleted file mode 100644 index b7c28cc..0000000 --- a/ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/properties/XxlAdminProperties.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.baiye.ballcat.common.job.properties; - -import lombok.Data; - -/** - * @author lengleng - * @date 2019-09-18 - *

- * xxl 管控台相关属性 - */ -@Data -public class XxlAdminProperties { - - /** - * 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。 执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册; - */ - private String addresses; - -} diff --git a/ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/properties/XxlExecutorProperties.java b/ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/properties/XxlExecutorProperties.java deleted file mode 100644 index fd8123f..0000000 --- a/ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/properties/XxlExecutorProperties.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.baiye.ballcat.common.job.properties; - -import lombok.Data; - -/** - * @author lengleng - * @date 2019-09-18 - */ -@Data -public class XxlExecutorProperties { - - /** - * 执行器AppName [选填]:执行器心跳注册分组依据;为空则取spring应用名 - */ - private String appname; - - /** - * 优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址 从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。 - */ - private String address; - - /** - * 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP ,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 - * "调度中心请求并触发任务" - */ - private String ip; - - /** - * 执行器端口号 [选填]:小于等于0则自动获取;单机部署多个执行器且非自动获取端口时,注意要配置不同执行器端口; - */ - private Integer port = 0; - - /** - * 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径; - */ - private String logPath; - - /** - * 执行器日志保存天数 [选填] :值大于3时生效,启用执行器Log文件定期清理功能,否则, 如-1, 关闭自动清理功能; - */ - private Integer logRetentionDays = 30; - -} diff --git a/ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/properties/XxlJobProperties.java b/ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/properties/XxlJobProperties.java deleted file mode 100644 index 41ee524..0000000 --- a/ad-distribute-starters/ad-distribute-starter-job/src/main/java/com/baiye/ballcat/common/job/properties/XxlJobProperties.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.baiye.ballcat.common.job.properties; - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.NestedConfigurationProperty; - -/** - * @author lengleng - * @date 2019-09-18 - */ -@Data -@ConfigurationProperties(prefix = XxlJobProperties.PREFIX) -public class XxlJobProperties { - - public static final String PREFIX = "ballcat.xxl.job"; - - /** - * 是否启用分布式调度任务,默认:开启 - */ - private boolean enabled = true; - - /** - * 执行器通讯TOKEN [选填]:非空时启用; - */ - private String accessToken; - - @NestedConfigurationProperty - private XxlAdminProperties admin = new XxlAdminProperties(); - - @NestedConfigurationProperty - private XxlExecutorProperties executor = new XxlExecutorProperties(); - -} \ No newline at end of file diff --git a/ad-distribute-starters/ad-distribute-starter-job/src/main/resources/META-INF/spring.factories b/ad-distribute-starters/ad-distribute-starter-job/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 857a151..0000000 --- a/ad-distribute-starters/ad-distribute-starter-job/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,4 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.baiye.ballcat.common.job.XxlJobAutoConfiguration - - diff --git a/ad-distribute-starters/ad-distribute-starter-job/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ad-distribute-starters/ad-distribute-starter-job/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index 9a5aef6..0000000 --- a/ad-distribute-starters/ad-distribute-starter-job/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1 +0,0 @@ -com.baiye.ballcat.common.job.XxlJobAutoConfiguration \ No newline at end of file diff --git a/ad-distribute-system/system-biz/src/main/java/com/baiye/system/service/SysUserService.java b/ad-distribute-system/system-biz/src/main/java/com/baiye/system/service/SysUserService.java index a07c194..5f6404b 100644 --- a/ad-distribute-system/system-biz/src/main/java/com/baiye/system/service/SysUserService.java +++ b/ad-distribute-system/system-biz/src/main/java/com/baiye/system/service/SysUserService.java @@ -157,4 +157,10 @@ public interface SysUserService extends ExtendService { */ boolean existsForOrganization(Long organizationId); + /** + * 根据id查询 + * @param id + * @return + */ + SysUser findById(Long id); } diff --git a/ad-distribute-system/system-biz/src/main/java/com/baiye/system/service/impl/SysUserServiceImpl.java b/ad-distribute-system/system-biz/src/main/java/com/baiye/system/service/impl/SysUserServiceImpl.java index b673aee..c951eca 100644 --- a/ad-distribute-system/system-biz/src/main/java/com/baiye/system/service/impl/SysUserServiceImpl.java +++ b/ad-distribute-system/system-biz/src/main/java/com/baiye/system/service/impl/SysUserServiceImpl.java @@ -37,6 +37,7 @@ import com.baiye.extend.mybatis.plus.service.impl.ExtendServiceImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.springframework.cache.annotation.CacheEvict; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -75,8 +76,9 @@ public class SysUserServiceImpl extends ExtendServiceImpl 分页数据 */ @Override @@ -86,7 +88,7 @@ public class SysUserServiceImpl extends ExtendServiceImpl sysUsers = baseMapper.selectList(new LambdaQueryWrapper<>()); List userAll = Convert.toList(SysUserPageVO.class, sysUsers); Map> userGroup = userAll.stream() - .collect(Collectors.groupingBy(SysUserPageVO::getWhichUserId)); + .collect(Collectors.groupingBy(SysUserPageVO::getWhichUserId)); result.getRecords().forEach(user -> { List byWhichUserId = userGroup.get(user.getUserId()); @@ -104,6 +106,7 @@ public class SysUserServiceImpl extends ExtendServiceImpl roleList; if (adminUserChecker.isAdminUser(sysUser)) { roleList = sysRoleService.list(); - } - else { + } else { roleList = sysUserRoleService.listRoles(sysUser.getUserId()); } @@ -146,9 +149,9 @@ public class SysUserServiceImpl extends ExtendServiceImpl sysMenuList = sysMenuService.listByRoleCode(roleCode); menus.addAll(sysMenuList); List permissionList = sysMenuList.stream() - .map(SysMenu::getPermission) - .filter(StrUtil::isNotEmpty) - .collect(Collectors.toList()); + .map(SysMenu::getPermission) + .filter(StrUtil::isNotEmpty) + .collect(Collectors.toList()); permissions.addAll(permissionList); } userInfoDTO.setMenus(menus); @@ -159,6 +162,7 @@ public class SysUserServiceImpl extends ExtendServiceImpl userMap = userList.stream() - .collect(Collectors.toMap(SysUser::getUserId, Function.identity())); + .collect(Collectors.toMap(SysUser::getUserId, Function.identity())); userIds.removeIf(id -> !adminUserChecker.hasModifyPermission(userMap.get(id))); Assert.notEmpty(userIds, "更新用户状态失败,无权限更新用户"); @@ -315,6 +324,7 @@ public class SysUserServiceImpl extends ExtendServiceImpl */ @@ -335,6 +346,7 @@ public class SysUserServiceImpl extends ExtendServiceImpl username value => userId - * @return List + * * @param userTypes 用户类型 + * @return List */ @Override public List> listSelectData(Collection userTypes) { @@ -376,6 +391,7 @@ public class SysUserServiceImpl extends ExtendServiceImpl */ @@ -386,6 +402,7 @@ public class SysUserServiceImpl extends ExtendServiceImpl + + ad-distribute-starter-job + com.baiye + 1.1.0 + com.baiye diff --git a/admin/src/main/java/com/baiye/job/DistributeRecordReportJob.java b/admin/src/main/java/com/baiye/job/DistributeRecordReportJob.java new file mode 100644 index 0000000..7fa2c8c --- /dev/null +++ b/admin/src/main/java/com/baiye/job/DistributeRecordReportJob.java @@ -0,0 +1,34 @@ +package com.baiye.job; + +import cn.hutool.core.date.DateUtil; +import com.baiye.modules.distribute.service.DistributeReportService; +import com.dangdang.ddframe.job.api.ShardingContext; +import com.dangdang.ddframe.job.api.simple.SimpleJob; +import com.example.jobInstance.ElasticSimpleJob; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * @author wjt + * @date 2023/8/14 + * 导入分配统计 + * 0/5 * * * * ? + */ +@Component +@Slf4j +@ElasticSimpleJob( + jobName = "DistributeRecordReportJob", cron = "0 30 23 * * ?") +public class DistributeRecordReportJob implements SimpleJob { + + @Resource + private DistributeReportService distributeReportService; + + @Override + public void execute(ShardingContext shardingContext) { + log.info("流量分布定时任务开始-----{}", DateUtil.date()); + distributeReportService.distributeReport(); + log.info("流量分布定时任务结束-----{}", DateUtil.date()); + } +} diff --git a/admin/src/main/java/com/baiye/modules/distribute/controller/DistributeReportController.java b/admin/src/main/java/com/baiye/modules/distribute/controller/DistributeReportController.java new file mode 100644 index 0000000..369f085 --- /dev/null +++ b/admin/src/main/java/com/baiye/modules/distribute/controller/DistributeReportController.java @@ -0,0 +1,37 @@ +package com.baiye.modules.distribute.controller; + +import com.baiye.modules.distribute.service.DistributeReportService; +import com.baiye.result.R; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author wjt + * @date 2023/8/11 + */ +@RequiredArgsConstructor +@RestController +@Tag(name = "分配信息统计") +@RequestMapping("/report") +public class DistributeReportController { + private final DistributeReportService distributeReportService; + + @GetMapping("/report") + public void distributeReport() { + distributeReportService.distributeReport(); + } + + @GetMapping("/flow") + @Operation(summary = "流量分布统计") + public R reportFlow(@RequestParam(value = "userId", required = false) Long userId, + @RequestParam(value = "channel", required = false) String channel, + @RequestParam(value = "type", required = true) Integer type + ) { + return R.ok(distributeReportService.reportFlow(userId, channel, type)); + } +} diff --git a/admin/src/main/java/com/baiye/modules/distribute/entity/DistributeReportChannelEntity.java b/admin/src/main/java/com/baiye/modules/distribute/entity/DistributeReportChannelEntity.java new file mode 100644 index 0000000..1f5811d --- /dev/null +++ b/admin/src/main/java/com/baiye/modules/distribute/entity/DistributeReportChannelEntity.java @@ -0,0 +1,67 @@ +package com.baiye.modules.distribute.entity; + +import cn.hutool.core.date.DateUtil; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.io.Serializable; +import java.util.Date; + +/** + * @author wjt + * @date 2023/8/11 + */ +@Getter +@Setter +@ToString +@TableName("tb_distribute_report_channel") +@Schema(title = "导入线索分配统计-渠道") +public class DistributeReportChannelEntity implements Serializable { + @TableId + @Schema(title = "ID") + private Long id; + + @Schema(title = "用户id") + private Long userId; + + @Schema(title = "用户名") + private String username; + + @Schema(title = "渠道") + private String channel; + + @Schema(title = "当日量") + private Integer todayNum=0; + + @Schema(title = "总量") + private Integer totalNum=0; + + @Schema(title = "分配量") + private Integer distributeNum=0; + + @Schema(title = "占比") + private double ratio; + + @Schema(title = "日环比") + private double ratioDay; + + @Schema(title = "统计日期") + private Date createTime; + + public DistributeReportChannelEntity createDistributeReportChannel(Long userId, String username, String channel, Integer todayNum, Integer totalNum, Integer distributeNum, Double ratio, Double ratioDay) { + this.setUserId(userId); + this.setUsername(username); + this.setChannel(channel); + this.setTodayNum(todayNum); + this.setTotalNum(totalNum); + this.setDistributeNum(distributeNum); + this.setRatio(ratio); + this.setRatioDay(ratioDay); + this.setCreateTime(DateUtil.date()); + return this; + } +} diff --git a/admin/src/main/java/com/baiye/modules/distribute/entity/DistributeReportEntity.java b/admin/src/main/java/com/baiye/modules/distribute/entity/DistributeReportEntity.java new file mode 100644 index 0000000..5c8be32 --- /dev/null +++ b/admin/src/main/java/com/baiye/modules/distribute/entity/DistributeReportEntity.java @@ -0,0 +1,60 @@ +package com.baiye.modules.distribute.entity; + +import cn.hutool.core.date.DateUtil; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.io.Serializable; +import java.util.Date; + +/** + * @author wjt + * @date 2023/8/11 + */ +@Getter +@Setter +@ToString +@TableName("tb_distribute_report") +@Schema(title = "导入线索分配统计") +public class DistributeReportEntity implements Serializable { + + @TableId + @Schema(title = "ID") + private Long id; + + @Schema(title = "用户id") + private Long userId; + + @Schema(title = "用户名") + private String username; + + @Schema(title = "渠道") + private String channel; + + @Schema(title = "总量") + private Integer todayNum = 0; + + @Schema(title = "占比") + private double ratio; + + @Schema(title = "日环比") + private double ratioDay; + + @Schema(title = "统计日期") + private Date createTime; + + public DistributeReportEntity createDistributeReport(Long userId, String username, String channel, Integer todayNum, Double ratio, Double ratioDay) { + this.setUserId(userId); + this.setUsername(username); + this.setChannel(channel); + this.setTodayNum(todayNum); + this.setRatio(ratio); + this.setRatioDay(ratioDay); + this.setCreateTime(DateUtil.date()); + return this; + } +} diff --git a/admin/src/main/java/com/baiye/modules/distribute/entity/DistributeReportUserEntity.java b/admin/src/main/java/com/baiye/modules/distribute/entity/DistributeReportUserEntity.java new file mode 100644 index 0000000..2668bdd --- /dev/null +++ b/admin/src/main/java/com/baiye/modules/distribute/entity/DistributeReportUserEntity.java @@ -0,0 +1,63 @@ +package com.baiye.modules.distribute.entity; + +import cn.hutool.core.date.DateUtil; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.io.Serializable; +import java.util.Date; + +/** + * @author wjt + * @date 2023/8/11 + */ +@Getter +@Setter +@ToString +@TableName("tb_distribute_report_user") +@Schema(title = "导入线索分配统计-用户") +public class DistributeReportUserEntity implements Serializable { + @TableId + @Schema(title = "ID") + private Long id; + + @Schema(title = "用户id") + private Long userId; + + @Schema(title = "用户名") + private String username; + + @Schema(title = "当日量") + private Integer todayNum=0; + + @Schema(title = "总量") + private Integer totalNum=0; + + @Schema(title = "分配量") + private Integer distributeNum=0; + + @Schema(title = "占比") + private double ratio; + + @Schema(title = "日环比") + private double ratioDay; + + @Schema(title = "统计日期") + private Date createTime; + + public DistributeReportUserEntity createDistributeReportUser(Long userId, String username, Integer todayNum, Integer totalNum, Integer distributeNum, Double ratio, Double ratioDay) { + this.setUserId(userId); + this.setUsername(username); + this.setTodayNum(todayNum); + this.setTotalNum(totalNum); + this.setDistributeNum(distributeNum); + this.setRatio(ratio); + this.setRatioDay(ratioDay); + this.setCreateTime(DateUtil.date()); + return this; + } +} diff --git a/admin/src/main/java/com/baiye/modules/distribute/mapper/DistributeReportChannelMapper.java b/admin/src/main/java/com/baiye/modules/distribute/mapper/DistributeReportChannelMapper.java new file mode 100644 index 0000000..600bf61 --- /dev/null +++ b/admin/src/main/java/com/baiye/modules/distribute/mapper/DistributeReportChannelMapper.java @@ -0,0 +1,11 @@ +package com.baiye.modules.distribute.mapper; + +import com.baiye.extend.mybatis.plus.mapper.ExtendMapper; +import com.baiye.modules.distribute.entity.DistributeReportChannelEntity; + +/** + * @author wjt + * @date 2023/8/11 + */ +public interface DistributeReportChannelMapper extends ExtendMapper { +} diff --git a/admin/src/main/java/com/baiye/modules/distribute/mapper/DistributeReportMapper.java b/admin/src/main/java/com/baiye/modules/distribute/mapper/DistributeReportMapper.java new file mode 100644 index 0000000..5ab8f9f --- /dev/null +++ b/admin/src/main/java/com/baiye/modules/distribute/mapper/DistributeReportMapper.java @@ -0,0 +1,11 @@ +package com.baiye.modules.distribute.mapper; + +import com.baiye.extend.mybatis.plus.mapper.ExtendMapper; +import com.baiye.modules.distribute.entity.DistributeReportEntity; + +/** + * @author wjt + * @date 2023/8/11 + */ +public interface DistributeReportMapper extends ExtendMapper { +} diff --git a/admin/src/main/java/com/baiye/modules/distribute/mapper/DistributeReportUserMapper.java b/admin/src/main/java/com/baiye/modules/distribute/mapper/DistributeReportUserMapper.java new file mode 100644 index 0000000..0751e26 --- /dev/null +++ b/admin/src/main/java/com/baiye/modules/distribute/mapper/DistributeReportUserMapper.java @@ -0,0 +1,11 @@ +package com.baiye.modules.distribute.mapper; + +import com.baiye.extend.mybatis.plus.mapper.ExtendMapper; +import com.baiye.modules.distribute.entity.DistributeReportUserEntity; + +/** + * @author wjt + * @date 2023/8/11 + */ +public interface DistributeReportUserMapper extends ExtendMapper { +} diff --git a/admin/src/main/java/com/baiye/modules/distribute/service/ClueRecordService.java b/admin/src/main/java/com/baiye/modules/distribute/service/ClueRecordService.java index 2e56be1..f8da6c2 100644 --- a/admin/src/main/java/com/baiye/modules/distribute/service/ClueRecordService.java +++ b/admin/src/main/java/com/baiye/modules/distribute/service/ClueRecordService.java @@ -6,6 +6,9 @@ import com.baiye.modules.distribute.qo.ClueRecordQo; import com.baiye.domain.PageParam; import com.baiye.domain.PageResult; import com.baiye.extend.mybatis.plus.service.ExtendService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; + +import java.util.List; public interface ClueRecordService extends ExtendService { @@ -19,4 +22,9 @@ public interface ClueRecordService extends ExtendService { */ boolean deleteByUserId(Long clueRecordId); + /** + * 按条件查询导入记录 + */ + List selectByWrapper(LambdaQueryWrapper wrapper); + } diff --git a/admin/src/main/java/com/baiye/modules/distribute/service/DistributeReportService.java b/admin/src/main/java/com/baiye/modules/distribute/service/DistributeReportService.java new file mode 100644 index 0000000..bc179a9 --- /dev/null +++ b/admin/src/main/java/com/baiye/modules/distribute/service/DistributeReportService.java @@ -0,0 +1,23 @@ +package com.baiye.modules.distribute.service; + +import com.baiye.extend.mybatis.plus.service.ExtendService; +import com.baiye.modules.distribute.entity.DistributeReportEntity; + +import java.util.Map; + +/** + * @author wjt + * @date 2023/8/11 + */ +public interface DistributeReportService extends ExtendService { + + /** + * 流量分布查询 + */ + Map reportFlow(Long userId, String channel, Integer type); + + /** + * 线索定时统计 + */ + void distributeReport(); +} diff --git a/admin/src/main/java/com/baiye/modules/distribute/service/impl/ClueRecordServiceImpl.java b/admin/src/main/java/com/baiye/modules/distribute/service/impl/ClueRecordServiceImpl.java index 2041923..f3a161a 100644 --- a/admin/src/main/java/com/baiye/modules/distribute/service/impl/ClueRecordServiceImpl.java +++ b/admin/src/main/java/com/baiye/modules/distribute/service/impl/ClueRecordServiceImpl.java @@ -6,6 +6,7 @@ import com.baiye.modules.distribute.service.ClueRecordService; import com.baiye.modules.distribute.vo.ClueRecordVO; import com.baiye.modules.distribute.qo.ClueRecordQo; import com.baiye.security.util.SecurityUtils; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import com.baiye.util.FileUtil; import com.baiye.domain.PageParam; @@ -16,6 +17,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; + /** * @Author YQY * @Date 2023/8/1 @@ -40,4 +43,9 @@ public class ClueRecordServiceImpl extends ExtendServiceImpl selectByWrapper(LambdaQueryWrapper wrapper) { + return baseMapper.selectList(wrapper); + } + } diff --git a/admin/src/main/java/com/baiye/modules/distribute/service/impl/DistributeReportServiceImpl.java b/admin/src/main/java/com/baiye/modules/distribute/service/impl/DistributeReportServiceImpl.java new file mode 100644 index 0000000..79b867c --- /dev/null +++ b/admin/src/main/java/com/baiye/modules/distribute/service/impl/DistributeReportServiceImpl.java @@ -0,0 +1,303 @@ +package com.baiye.modules.distribute.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUnit; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baiye.exception.BadRequestException; +import com.baiye.extend.mybatis.plus.service.impl.ExtendServiceImpl; +import com.baiye.modules.distribute.entity.ClueRecordEntity; +import com.baiye.modules.distribute.entity.DistributeReportChannelEntity; +import com.baiye.modules.distribute.entity.DistributeReportEntity; +import com.baiye.modules.distribute.entity.DistributeReportUserEntity; +import com.baiye.modules.distribute.mapper.DistributeReportChannelMapper; +import com.baiye.modules.distribute.mapper.DistributeReportMapper; +import com.baiye.modules.distribute.mapper.DistributeReportUserMapper; +import com.baiye.modules.distribute.service.ClueRecordService; +import com.baiye.modules.distribute.service.DistributeReportService; +import com.baiye.modules.distribute.vo.ReportFlowVO; +import com.baiye.system.model.entity.SysUser; +import com.baiye.system.service.SysUserService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author wjt + * @date 2023/8/11 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class DistributeReportServiceImpl extends ExtendServiceImpl implements DistributeReportService { + + private final ClueRecordService clueRecordService; + + private final DistributeReportChannelMapper distributeReportChannelMapper; + + private final DistributeReportUserMapper distributeReportUserMapper; + + private final SysUserService sysUserService; + + @Override + public Map reportFlow(Long userId, String channel, Integer type) { + + Map map = getHomeReport(type, userId); + + List reportFlowList = new ArrayList<>(); + if (userId != null) { + if (StrUtil.isNotBlank(channel)) { + //查询近7天 + Date date = DateUtil.offsetDay(DateUtil.yesterday(), -6); + Date beginTime = DateUtil.beginOfDay(date); + Date endTime = DateUtil.endOfDay(DateUtil.yesterday()); + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.between(DistributeReportEntity::getCreateTime, beginTime, endTime); + wrapper.eq(DistributeReportEntity::getUserId, userId); + wrapper.eq(DistributeReportEntity::getChannel, channel); + List distributeReportEntityList = baseMapper.selectList(wrapper); + if (CollUtil.isEmpty(distributeReportEntityList)) { + return map; + } + reportFlowList = getReportFlowList(distributeReportEntityList, beginTime, endTime); + map.put("type", 3); + map.put("data", reportFlowList); + return map; + } + map.put("type", 2); + LambdaQueryWrapper wrapperChannel = new LambdaQueryWrapper<>(); + wrapperChannel.eq(DistributeReportChannelEntity::getUserId, userId); + List channelList = distributeReportChannelMapper.selectList(wrapperChannel); + + for (DistributeReportChannelEntity channelEntity : channelList) { + ReportFlowVO reportFlowVO = new ReportFlowVO(); + reportFlowVO.setName(channelEntity.getChannel()); + reportFlowVO.setRatio(channelEntity.getRatio()); + reportFlowVO.setRatioDay(channelEntity.getRatioDay()); + reportFlowVO.setTotalNum(channelEntity.getTotalNum()); + reportFlowList.add(reportFlowVO); + } + map.put("data", reportFlowList); + } else { + List distributeReportUserList = distributeReportUserMapper.selectList(null); + for (DistributeReportUserEntity distributeReportUserEntity : distributeReportUserList) { + ReportFlowVO reportFlowVO = new ReportFlowVO(); + reportFlowVO.setName(distributeReportUserEntity.getUsername()); + reportFlowVO.setRatio(distributeReportUserEntity.getRatio()); + reportFlowVO.setRatioDay(distributeReportUserEntity.getRatioDay()); + reportFlowVO.setTotalNum(distributeReportUserEntity.getTotalNum()); + reportFlowList.add(reportFlowVO); + } + map.put("data", reportFlowList); + map.put("type", 1); + return map; + } + return map; + } + + + /** + * 获取昨日导入和分配数 + */ + private Map getHomeReport(Integer type, Long userId) { + Map map = new HashMap<>(8); + LambdaQueryWrapper wrapperUser = new LambdaQueryWrapper<>(); + DateTime dateTime = DateUtil.beginOfDay(DateUtil.yesterday()); + DateTime dateTime1 = DateUtil.endOfDay(DateUtil.yesterday()); + wrapperUser.between(DistributeReportUserEntity::getCreateTime, dateTime, dateTime1); + int yesterdayImportNum = 0; + int yesterdayDistributeNum = 0; + if (type == 1) { + List distributeReportUserList = distributeReportUserMapper.selectList(wrapperUser); + if (CollUtil.isNotEmpty(distributeReportUserList)) { + for (DistributeReportUserEntity distributeReportUserEntity : distributeReportUserList) { + yesterdayImportNum += distributeReportUserEntity.getTodayNum(); + yesterdayDistributeNum += distributeReportUserEntity.getDistributeNum(); + } + } + } else { + if (userId == null) { + throw new BadRequestException("参数异常"); + } + wrapperUser.eq(DistributeReportUserEntity::getUserId, userId); + DistributeReportUserEntity distributeReportUserEntity = distributeReportUserMapper.selectOne(wrapperUser); + + if (distributeReportUserEntity != null) { + yesterdayImportNum = distributeReportUserEntity.getTodayNum(); + yesterdayDistributeNum = distributeReportUserEntity.getDistributeNum(); + } + } + map.put("yesterdayImportNum", yesterdayImportNum); + map.put("yesterdayDistributeNum", yesterdayDistributeNum); + return map; + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void distributeReport() { + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.between(ClueRecordEntity::getCreateTime, DateUtil.beginOfDay(DateUtil.date()), DateUtil.endOfDay(DateUtil.date())); + wrapper.eq(ClueRecordEntity::getStatus, 2); + List allRecordInTodayList = clueRecordService.selectByWrapper(wrapper); + if (CollUtil.isEmpty(allRecordInTodayList)) { + return; + } + //提取所有用户 + Set collect = allRecordInTodayList.stream().map(ClueRecordEntity::getCreateBy).collect(Collectors.toSet()); + Map userNameList = getUserName(collect); + + //1.按公司分组 + Map> recordByUserMap = allRecordInTodayList.stream().collect( + Collectors.groupingBy(ClueRecordEntity::getCreateBy)); + if (ObjectUtil.isEmpty(recordByUserMap)) { + return; + } + List distributeReportUserList = new ArrayList<>(); + //之前的总量 + Long historyTotal = distributeReportUserMapper.selectCount(new LambdaQueryWrapper().select(DistributeReportUserEntity::getTotalNum)); + int sum = allRecordInTodayList.stream().mapToInt(ClueRecordEntity::getSuccessNum).sum(); + int totalAll = historyTotal.intValue() + sum; + //记录之前得统计id + List ids = new ArrayList<>(); + for (Map.Entry> entry : recordByUserMap.entrySet()) { + Long userId = entry.getKey(); + List clueRecordByUserList = entry.getValue(); + //今日新增数 + int sumByUser = clueRecordByUserList.stream().mapToInt(ClueRecordEntity::getSuccessNum).sum(); + //上次对象 + DistributeReportUserEntity distributeReportUserByYesterday = distributeReportUserMapper.selectOne(new LambdaQueryWrapper() + .eq(DistributeReportUserEntity::getUserId, userId) + ); + int yesterdayNum = 0; + int yesterdayTotalNum = 0; + if (distributeReportUserByYesterday != null) { + //上次新增数 + if (DateUtil.betweenDay(distributeReportUserByYesterday.getCreateTime(), DateUtil.yesterday(), true) == 0) { + + yesterdayNum = distributeReportUserByYesterday.getTodayNum(); + } + yesterdayTotalNum = distributeReportUserByYesterday.getTotalNum(); + ids.add(distributeReportUserByYesterday.getId()); + } else { + distributeReportUserByYesterday = new DistributeReportUserEntity(); + } + //总数 + int totalNum = yesterdayTotalNum + sumByUser; + //分发数 + int distributeNum = clueRecordByUserList.stream().filter(c -> c.getAllocationStatus() == 1).mapToInt(ClueRecordEntity::getSuccessNum).sum(); + double ratio; + ratio = NumberUtil.div(totalNum, totalAll); + double ratioDay = 0.0; + if (yesterdayNum > 0) { + ratioDay = NumberUtil.div(NumberUtil.min(sumByUser, yesterdayNum), yesterdayNum); + } + String userName = userNameList.get(userId) == null ? "" : userNameList.get(userId); + distributeReportUserByYesterday.createDistributeReportUser(userId, userName, sumByUser, totalNum, distributeNum, ratio, ratioDay); + distributeReportUserList.add(distributeReportUserByYesterday); + + //按渠道统计 + dealByChannel(clueRecordByUserList, userId, totalNum, userName); + } + if (CollUtil.isNotEmpty(ids)) { + distributeReportUserMapper.deleteBatchIds(ids); + } + distributeReportUserMapper.insertBatchSomeColumn(distributeReportUserList); + } + + + private void dealByChannel(List clueRecordByUserList, Long userId, Integer totalNumByUser, String userName) { + List list = new ArrayList<>(); + List distributeReportEntityList = new ArrayList<>(); + //.按渠道分组 + Map> recordByChannelMap = clueRecordByUserList.stream().filter(c -> StrUtil.isNotBlank(c.getChannelIdentifying())).collect( + Collectors.groupingBy(ClueRecordEntity::getChannelIdentifying)); + if (ObjectUtil.isEmpty(recordByChannelMap)) { + return; + } + List ids = new ArrayList<>(); + for (Map.Entry> entryByChannel : recordByChannelMap.entrySet()) { + String channel = entryByChannel.getKey(); + List clueRecordByChannel = entryByChannel.getValue(); + int sumByUser = clueRecordByChannel.stream().mapToInt(ClueRecordEntity::getSuccessNum).sum(); + //查询昨日信息 + DistributeReportChannelEntity distributeReportUserByYesterday = distributeReportChannelMapper.selectOne(new LambdaQueryWrapper() + .eq(DistributeReportChannelEntity::getUserId, userId) + .eq(DistributeReportChannelEntity::getChannel, channel) + ); + int yesterdayNum = 0; + int yesterdayTotalNum = 0; + if (distributeReportUserByYesterday != null) { + if (DateUtil.betweenDay(distributeReportUserByYesterday.getCreateTime(), DateUtil.yesterday(), true) == 0) { + yesterdayNum = distributeReportUserByYesterday.getTodayNum(); + } + yesterdayTotalNum = distributeReportUserByYesterday.getTotalNum(); + ids.add(distributeReportUserByYesterday.getId()); + } else { + distributeReportUserByYesterday = new DistributeReportChannelEntity(); + } + int totalNum = yesterdayTotalNum + sumByUser; + int distributeNum = clueRecordByChannel.stream().filter(c -> c.getAllocationStatus() == 1).mapToInt(ClueRecordEntity::getSuccessNum).sum(); + double ratio = NumberUtil.div(totalNum, totalNumByUser.intValue()); + double ratioDay = 0.0; + if (yesterdayNum > 0) { + ratioDay = NumberUtil.div(NumberUtil.min(sumByUser, yesterdayNum), yesterdayNum); + } + + distributeReportUserByYesterday.createDistributeReportChannel(userId, userName, channel, sumByUser, totalNum, distributeNum, ratio, ratioDay); + list.add(distributeReportUserByYesterday); + + DistributeReportEntity distributeReport = new DistributeReportEntity().createDistributeReport(userId, userName, channel, sumByUser, NumberUtil.div(sumByUser, totalNum), ratioDay); + distributeReportEntityList.add(distributeReport); + } + if (CollUtil.isNotEmpty(ids)) { + distributeReportChannelMapper.deleteBatchIds(ids); + } + distributeReportChannelMapper.insertBatchSomeColumn(list); + baseMapper.insertBatchSomeColumn(distributeReportEntityList); + } + + private List getReportFlowList(List distributeReportEntityList, Date beginTime, Date endTime) { + Map callMap = new HashMap<>(8); + for (DistributeReportEntity reportDeduct : distributeReportEntityList) { + callMap.put(reportDeduct.getCreateTime().toString(), reportDeduct); + } + List list = new ArrayList<>(); + long betweenDay = DateUtil.between(beginTime, endTime, DateUnit.DAY); + for (int i = 0; i <= betweenDay; i++) { + String time = DateUtil.format(DateUtil.offsetDay(beginTime, i), "yyyy-MM-dd"); + ReportFlowVO reportFlowVO = new ReportFlowVO(); + if (callMap.containsKey(time)) { + DistributeReportEntity reportDeduct = callMap.get(time); + reportFlowVO.setRatioDay(reportDeduct.getRatioDay()); + reportFlowVO.setRatio(reportDeduct.getRatio()); + reportFlowVO.setTotalNum(reportDeduct.getTodayNum()); + } else { + reportFlowVO.setRatioDay(0.0); + reportFlowVO.setRatio(0.0); + reportFlowVO.setTotalNum(0); + } + reportFlowVO.setName(time); + list.add(reportFlowVO); + } + return list; + } + + public Map getUserName(Set ids) { + List sysUsers = sysUserService.listByUserIds(ids); + Map map = new HashMap<>(8); + for (SysUser sysUser : sysUsers) { + map.put(sysUser.getUserId(), sysUser.getUsername()); + } + return map; + } +} diff --git a/admin/src/main/java/com/baiye/modules/distribute/vo/ReportFlowVO.java b/admin/src/main/java/com/baiye/modules/distribute/vo/ReportFlowVO.java new file mode 100644 index 0000000..0213212 --- /dev/null +++ b/admin/src/main/java/com/baiye/modules/distribute/vo/ReportFlowVO.java @@ -0,0 +1,25 @@ +package com.baiye.modules.distribute.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * @author wjt + * @date 2023/8/2 + */ +@Data +@Schema(title = "标签组VO") +public class ReportFlowVO { + + @Schema(title = "公司名/渠道/日期") + private String name; + + @Schema(title = "总量") + private Integer totalNum; + + @Schema(title = "占比") + private Double ratio; + + @Schema(title = "日环比") + private Double ratioDay; +} diff --git a/admin/src/main/resources/application.yml b/admin/src/main/resources/application.yml index a7ebc95..2c62301 100644 --- a/admin/src/main/resources/application.yml +++ b/admin/src/main/resources/application.yml @@ -123,10 +123,7 @@ file: maxSize: 300 avatarMaxSize: 5 - - - - - - - +elasticjob: + zookeeper: + namespace: springboot-elasticjob + server-list: localhost:2181 \ No newline at end of file