Commit 529e593ac0a15dd2cf4cc9ddf46a090f6f2ae209

Authored by 张志伟
2 parents a1c7aea8 c996bfe8

Merge branch 'test' into 'main'

考评并列第一计算方式、配置修改

考评并列第一计算方式、配置修改

See merge request !68
Showing 35 changed files with 1084 additions and 141 deletions
doc/2023_update.sql 0 → 100644
  1 +-- 2023年3月7日
  2 +ALTER TABLE `fw_morax`.`eval_group_reward_ladders`
  3 + ADD COLUMN `rank_order_type` tinyint(4) NULL DEFAULT 1 COMMENT '排名顺序类型 1:正 2:负' AFTER `upper`;
  4 +
  5 +CREATE TABLE `eval_group_reward_rank_log` (
  6 + `id` bigint(20) NOT NULL AUTO_INCREMENT,
  7 + `name` varchar(512) NOT NULL COMMENT '名称',
  8 + `pool_id` bigint(20) DEFAULT NULL COMMENT '人员id 、门店id',
  9 + `scope_type` tinyint(4) NOT NULL COMMENT '考评范围; 1:门店考评 2:人员考评',
  10 + `refer_id` bigint(20) DEFAULT NULL COMMENT '考评奖惩 前置条件 配置id',
  11 + `target_type` tinyint(4) DEFAULT NULL COMMENT '1:参数 2:前置条件',
  12 + `value` decimal(18,4) DEFAULT NULL COMMENT '原始值',
  13 + `reach_value` decimal(18,4) DEFAULT NULL COMMENT '达成目标',
  14 + `rank` int(10) DEFAULT NULL COMMENT '排名',
  15 + `hit` tinyint(1) DEFAULT NULL COMMENT '是否命中',
  16 + `data_date` date NOT NULL COMMENT '数据日期',
  17 + `group_id` bigint(20) NOT NULL COMMENT '集团',
  18 + `create_time` datetime DEFAULT NULL,
  19 + `update_time` datetime DEFAULT NULL,
  20 + `yn` tinyint(1) DEFAULT '1',
  21 + PRIMARY KEY (`id`)
  22 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='考评指标达成目标记录';
0 23 \ No newline at end of file
... ...
fw-morax-dao/src/main/java/cn/fw/morax/dao/eval/EvalGroupRewardHitLogDao.java
... ... @@ -2,7 +2,12 @@ package cn.fw.morax.dao.eval;
2 2  
3 3  
4 4 import cn.fw.morax.domain.db.eval.EvalGroupRewardHitLog;
  5 +import cn.fw.morax.domain.vo.eval.EvalGroupRewardHitLogVO;
5 6 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  7 +import org.apache.ibatis.annotations.Param;
  8 +
  9 +import java.time.LocalDate;
  10 +import java.util.List;
6 11  
7 12 /**
8 13 * <p>
... ... @@ -14,4 +19,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
14 19 */
15 20 public interface EvalGroupRewardHitLogDao extends BaseMapper<EvalGroupRewardHitLog> {
16 21  
  22 + List<EvalGroupRewardHitLogVO> getUserHitLogs(@Param("evalGroupRewardId")Long evalGroupRewardId, @Param("dataDate")LocalDate dataDate);
  23 +
  24 + List<EvalGroupRewardHitLogVO> getShopHitLogs(@Param("evalGroupRewardId")Long evalGroupRewardId, @Param("dataDate")LocalDate dataDate);
  25 +
17 26 }
... ...
fw-morax-dao/src/main/java/cn/fw/morax/dao/eval/EvalGroupRewardRankLogDao.java 0 → 100644
  1 +package cn.fw.morax.dao.eval;
  2 +
  3 +
  4 +import cn.fw.morax.domain.db.eval.EvalGroupRewardRankLog;
  5 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  6 +
  7 +/**
  8 + * <p>
  9 + * 考评指标达成目标记录 Mapper 接口
  10 + * </p>
  11 + *
  12 + * @author jiangchao
  13 + * @since 2022-12-09
  14 + */
  15 +public interface EvalGroupRewardRankLogDao extends BaseMapper<EvalGroupRewardRankLog> {
  16 +
  17 +
  18 +}
... ...
fw-morax-dao/src/main/resources/mapper/eval/EvalGroupRewardHitLogMapper.xml
... ... @@ -2,6 +2,50 @@
2 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 3 <mapper namespace="cn.fw.morax.dao.eval.EvalGroupRewardHitLogDao">
4 4  
  5 + <select id="getUserHitLogs" resultType="cn.fw.morax.domain.vo.eval.EvalGroupRewardHitLogVO">
  6 + SELECT
  7 + t1.id,
  8 + t1.pool_id,
  9 + t1.eval_group_reward_id,
  10 + t1.eval_group_reward_ladders_id,
  11 + t1.scope_type,
  12 + t1.reward_value,
  13 + t1.hit_ladder_value,
  14 + t1.hit_commission_value,
  15 + t1.proportion_value,
  16 + t1.data_date,
  17 + t1.group_id,
  18 + t2.user_name as name
  19 + FROM
  20 + eval_group_reward_hit_log t1
  21 + LEFT JOIN eval_user_pool t2 ON t1.pool_id = t2.id
  22 + WHERE
  23 + t1.eval_group_reward_id = #{evalGroupRewardId}
  24 + AND t1.data_date = #{dataDate}
  25 + AND t1.yn = 1
  26 + </select>
5 27  
  28 + <select id="getShopHitLogs" resultType="cn.fw.morax.domain.vo.eval.EvalGroupRewardHitLogVO">
  29 + SELECT
  30 + t1.id,
  31 + t1.pool_id,
  32 + t1.eval_group_reward_id,
  33 + t1.eval_group_reward_ladders_id,
  34 + t1.scope_type,
  35 + t1.reward_value,
  36 + t1.hit_ladder_value,
  37 + t1.hit_commission_value,
  38 + t1.proportion_value,
  39 + t1.data_date,
  40 + t1.group_id,
  41 + t2.shop_name as name
  42 + FROM
  43 + eval_group_reward_hit_log t1
  44 + LEFT JOIN eval_shop_pool t2 ON t1.pool_id = t2.id
  45 + WHERE
  46 + t1.eval_group_reward_id = #{evalGroupRewardId}
  47 + AND t1.data_date = #{dataDate}
  48 + AND t1.yn = 1
  49 + </select>
6 50  
7 51 </mapper>
8 52 \ No newline at end of file
... ...
fw-morax-domain/src/main/java/cn/fw/morax/domain/bo/eval/EvalGroupUserShop.java
... ... @@ -48,6 +48,11 @@ public class EvalGroupUserShop {
48 48 private Long poolId;
49 49  
50 50 /**
  51 + * 名称
  52 + */
  53 + private String name;
  54 +
  55 + /**
51 56 * 用户id、门店id
52 57 */
53 58 private Long referId;
... ...
fw-morax-domain/src/main/java/cn/fw/morax/domain/db/eval/EvalGroupRewardLadders.java
1 1 package cn.fw.morax.domain.db.eval;
2 2  
3 3 import cn.fw.common.data.entity.BaseAuditableTimeEntity;
  4 +import cn.fw.morax.domain.enums.RankOrderTypeEnum;
4 5 import com.baomidou.mybatisplus.annotation.TableLogic;
5 6 import com.baomidou.mybatisplus.annotation.TableName;
6 7 import lombok.Data;
... ... @@ -52,6 +53,11 @@ public class EvalGroupRewardLadders extends BaseAuditableTimeEntity&lt;EvalGroupRew
52 53 private BigDecimal money;
53 54  
54 55 /**
  56 + * 排名顺序类型 1:正 2:负
  57 + */
  58 + private RankOrderTypeEnum rankOrderType;
  59 +
  60 + /**
55 61 * 封顶金额/台
56 62 */
57 63 private BigDecimal capMoney;
... ...
fw-morax-domain/src/main/java/cn/fw/morax/domain/db/eval/EvalGroupRewardRankLog.java 0 → 100644
  1 +package cn.fw.morax.domain.db.eval;
  2 +
  3 +import cn.fw.common.data.entity.BaseAuditableTimeEntity;
  4 +import cn.fw.morax.domain.dto.eval.EvalGroupIndicatorPreconditionLaddersDTO;
  5 +import cn.fw.morax.domain.enums.EvalScopeEnum;
  6 +import cn.fw.morax.domain.enums.IndicatorTypeEnum;
  7 +import cn.fw.morax.domain.enums.RankIndicatorTypeEnum;
  8 +import com.baomidou.mybatisplus.annotation.TableName;
  9 +import lombok.*;
  10 +
  11 +import java.math.BigDecimal;
  12 +import java.time.LocalDate;
  13 +
  14 +/**
  15 + * <p>
  16 + * 奖惩排名日志
  17 + * </p>
  18 + *
  19 + * @author jiangchao
  20 + * @since 2022-12-13
  21 + */
  22 +@Data
  23 +@EqualsAndHashCode(callSuper = false)
  24 +@TableName(autoResultMap = true)
  25 +@AllArgsConstructor
  26 +@NoArgsConstructor
  27 +@Builder
  28 +public class EvalGroupRewardRankLog extends BaseAuditableTimeEntity<EvalGroupRewardRankLog, Long>
  29 + implements Comparable<EvalGroupRewardRankLog>{
  30 +
  31 + private static final long serialVersionUID = 1L;
  32 +
  33 + /**
  34 + * 员工id
  35 + */
  36 + private Long poolId;
  37 +
  38 + /**
  39 + * 考评范围; 1:门店考评 2:人员考评
  40 + */
  41 + private EvalScopeEnum scopeType;
  42 +
  43 + /**
  44 + * 名称
  45 + */
  46 + private String name;
  47 +
  48 + /**
  49 + * 考评奖惩 前置条件 配置id
  50 + */
  51 + private Long referId;
  52 + /**
  53 + * 指标类型 1.奖惩提成 2.前置条件指标
  54 + */
  55 + private RankIndicatorTypeEnum targetType;
  56 + /**
  57 + * 原始值
  58 + */
  59 + private BigDecimal value;
  60 + /**
  61 + * 达成目标
  62 + */
  63 + private BigDecimal reachValue;
  64 + /**
  65 + * 排名
  66 + */
  67 + private Integer rank;
  68 + /**
  69 + * 命中
  70 + */
  71 + private Boolean hit;
  72 +
  73 + /**
  74 + * 数据日期
  75 + */
  76 + private LocalDate dataDate;
  77 +
  78 + /**
  79 + * 集团
  80 + */
  81 + private Long groupId;
  82 +
  83 + private Boolean yn;
  84 +
  85 + @Override
  86 + public int compareTo(EvalGroupRewardRankLog other) {
  87 + return other.reachValue.compareTo(this.reachValue);
  88 + }
  89 +}
... ...
fw-morax-domain/src/main/java/cn/fw/morax/domain/dto/eval/EvalGroupRewardLaddersDTO.java
... ... @@ -4,6 +4,7 @@ import cn.fw.common.data.entity.BaseAuditableTimeEntity;
4 4 import cn.fw.morax.common.utils.PublicUtil;
5 5 import cn.fw.morax.domain.dto.AbstractLaddersDto;
6 6 import cn.fw.morax.domain.dto.kpi.KpiGroupIndicatorLaddersDTO;
  7 +import cn.fw.morax.domain.enums.RankOrderTypeEnum;
7 8 import com.baomidou.mybatisplus.annotation.TableLogic;
8 9 import com.baomidou.mybatisplus.annotation.TableName;
9 10 import lombok.Data;
... ... @@ -38,6 +39,11 @@ public class EvalGroupRewardLaddersDTO extends AbstractLaddersDto implements Com
38 39 // private BigDecimal upper;
39 40  
40 41 /**
  42 + * 排名顺序类型 1:正 2:负
  43 + */
  44 + private RankOrderTypeEnum rankOrderType;
  45 +
  46 + /**
41 47 * 金额
42 48 */
43 49 @NotNull(message = "金额不能为空")
... ...
fw-morax-domain/src/main/java/cn/fw/morax/domain/enums/RankIndicatorTypeEnum.java 0 → 100644
  1 +package cn.fw.morax.domain.enums;
  2 +
  3 +import com.baomidou.mybatisplus.core.enums.IEnum;
  4 +import com.fasterxml.jackson.annotation.JsonCreator;
  5 +import com.fasterxml.jackson.annotation.JsonValue;
  6 +import lombok.Getter;
  7 +
  8 +/**
  9 + * 指标类型
  10 + *
  11 + * @author kurisu
  12 + */
  13 +public enum RankIndicatorTypeEnum implements IEnum<Integer> {
  14 + /**
  15 + * 指标类型 1.奖惩提成 2.前置条件指标
  16 + */
  17 + REWARD_COMMISSION(1, "奖惩提成"),
  18 + PRE(2, "前置条件指标"),
  19 + ;
  20 +
  21 + /**
  22 + * 值
  23 + */
  24 + private final Integer value;
  25 + /**
  26 + * 名称
  27 + */
  28 + @Getter
  29 + private final String name;
  30 +
  31 + RankIndicatorTypeEnum(final Integer value, final String name) {
  32 + this.value = value;
  33 + this.name = name;
  34 + }
  35 +
  36 + /**
  37 + * 根据枚举值获取枚举对象
  38 + */
  39 + @JsonCreator
  40 + public static RankIndicatorTypeEnum ofValue(final Integer value) {
  41 + for (final RankIndicatorTypeEnum _enum : RankIndicatorTypeEnum.values()) {
  42 + if (_enum.value.equals(value)) {
  43 + return _enum;
  44 + }
  45 + }
  46 + return null;
  47 + }
  48 +
  49 + /**
  50 + * 获取值
  51 + *
  52 + * @return 值
  53 + */
  54 + @JsonValue
  55 + @Override
  56 + public Integer getValue() {
  57 + return value;
  58 + }
  59 +
  60 + /**
  61 + * 获取描述
  62 + *
  63 + * @return 值
  64 + */
  65 + @JsonCreator
  66 + public static String getNameByVale(final Integer value) {
  67 + for (final RankIndicatorTypeEnum _enum : RankIndicatorTypeEnum.values()) {
  68 + if (_enum.value.equals(value)) {
  69 + return _enum.getName();
  70 + }
  71 + }
  72 + return "";
  73 + }
  74 +}
... ...
fw-morax-domain/src/main/java/cn/fw/morax/domain/enums/RankOrderTypeEnum.java 0 → 100644
  1 +package cn.fw.morax.domain.enums;
  2 +
  3 +import com.baomidou.mybatisplus.core.enums.IEnum;
  4 +import com.fasterxml.jackson.annotation.JsonCreator;
  5 +import com.fasterxml.jackson.annotation.JsonValue;
  6 +import lombok.Getter;
  7 +
  8 +/**
  9 + * 数据范围范围类型
  10 + *
  11 + * @author kurisu
  12 + */
  13 +public enum RankOrderTypeEnum implements IEnum<Integer> {
  14 + /**
  15 + * 排名顺序类型 1:正 2:负
  16 + */
  17 + POSITIVE(1, "正数"),
  18 + NEGATIVE(2, "负数"),
  19 + ;
  20 +
  21 + /**
  22 + * 值
  23 + */
  24 + private final Integer value;
  25 + /**
  26 + * 名称
  27 + */
  28 + @Getter
  29 + private final String name;
  30 +
  31 + RankOrderTypeEnum(final Integer value, final String name) {
  32 + this.value = value;
  33 + this.name = name;
  34 + }
  35 +
  36 + /**
  37 + * 根据枚举值获取枚举对象
  38 + */
  39 + @JsonCreator
  40 + public static RankOrderTypeEnum ofValue(final Integer value) {
  41 + for (final RankOrderTypeEnum _enum : RankOrderTypeEnum.values()) {
  42 + if (_enum.value.equals(value)) {
  43 + return _enum;
  44 + }
  45 + }
  46 + return null;
  47 + }
  48 +
  49 + /**
  50 + * 获取值
  51 + *
  52 + * @return 值
  53 + */
  54 + @JsonValue
  55 + @Override
  56 + public Integer getValue() {
  57 + return value;
  58 + }
  59 +
  60 + /**
  61 + * 获取描述
  62 + *
  63 + * @return 值
  64 + */
  65 + @JsonCreator
  66 + public static String getNameByVale(final Integer value) {
  67 + for (final RankOrderTypeEnum _enum : RankOrderTypeEnum.values()) {
  68 + if (_enum.value.equals(value)) {
  69 + return _enum.getName();
  70 + }
  71 + }
  72 + return "";
  73 + }
  74 +}
... ...
fw-morax-domain/src/main/java/cn/fw/morax/domain/vo/eval/EvalGroupRewardHitLogVO.java 0 → 100644
  1 +package cn.fw.morax.domain.vo.eval;
  2 +
  3 +import cn.fw.morax.common.constant.Constant;
  4 +import cn.fw.morax.domain.enums.DataTypeEnum;
  5 +import cn.fw.morax.domain.enums.EvalScopeEnum;
  6 +import cn.fw.morax.domain.enums.TargetTypeEnum;
  7 +import lombok.Data;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.time.LocalDate;
  11 +
  12 +/**
  13 + * 指标命中记录
  14 + *
  15 + * @author : kurisu
  16 + * @version : 2.0
  17 + * @className : KpiGroupIndicatorHitLog
  18 + * @description : 指标命中记录
  19 + * @date : 2022-12-13 10:27
  20 + */
  21 +@Data
  22 +public class EvalGroupRewardHitLogVO {
  23 + /**
  24 + * id
  25 + */
  26 + private Long id;
  27 + /**
  28 + * 名称
  29 + */
  30 + private String name;
  31 + /**
  32 + * 员工id
  33 + */
  34 + private Long poolId;
  35 +
  36 + /**
  37 + * 考评范围; 1:门店考评 2:人员考评
  38 + */
  39 + private EvalScopeEnum scopeType;
  40 + /**
  41 + * 奖惩项id
  42 + */
  43 + private Long evalGroupRewardId;
  44 + /**
  45 + * 命中的奖惩配置项
  46 + */
  47 + private Long evalGroupRewardLaddersId;
  48 + /**
  49 + * 奖惩值
  50 + */
  51 + private BigDecimal rewardValue;
  52 + /**
  53 + * 命中的台阶指标值
  54 + */
  55 + private BigDecimal hitLadderValue;
  56 + /**
  57 + * 命中的提成指标值
  58 + */
  59 + private BigDecimal hitCommissionValue;
  60 + /**
  61 + * 占比
  62 + */
  63 + private BigDecimal proportionValue;
  64 + /**
  65 + * 数据日期
  66 + */
  67 + private LocalDate dataDate;
  68 + /**
  69 + * 集团id
  70 + */
  71 + private Long groupId;
  72 + /**
  73 + * 逻辑删除
  74 + */
  75 + private Boolean yn;
  76 +
  77 +
  78 + /**
  79 + * 转换为百分数展示
  80 + */
  81 + public void convertValueToPercent(DataTypeEnum laddersType){
  82 + this.setProportionValue(this.getProportionValue().multiply(Constant.ONE_HUNDRED));
  83 +// if (DataTypeEnum.RATIO.equals(laddersType)) {
  84 +// this.setHitCommissionValue(this.getHitCommissionValue().multiply(Constant.ONE_HUNDRED));
  85 +// }
  86 + }
  87 +
  88 +
  89 +}
... ...
fw-morax-domain/src/main/java/cn/fw/morax/domain/vo/eval/EvalGroupRewardLaddersVO.java
... ... @@ -3,10 +3,7 @@ package cn.fw.morax.domain.vo.eval;
3 3 import cn.fw.common.data.entity.BaseAuditableTimeEntity;
4 4 import cn.fw.morax.common.constant.Constant;
5 5 import cn.fw.morax.common.utils.PublicUtil;
6   -import cn.fw.morax.domain.enums.DataTypeEnum;
7   -import cn.fw.morax.domain.enums.EvalRewardCalMethodEnum;
8   -import cn.fw.morax.domain.enums.RankTypeEnum;
9   -import cn.fw.morax.domain.enums.TargetTypeEnum;
  6 +import cn.fw.morax.domain.enums.*;
10 7 import com.baomidou.mybatisplus.annotation.TableLogic;
11 8 import com.baomidou.mybatisplus.annotation.TableName;
12 9 import lombok.Data;
... ... @@ -65,6 +62,11 @@ public class EvalGroupRewardLaddersVO {
65 62 private Boolean hit;
66 63  
67 64 /**
  65 + * 排名顺序类型 1:正 2:负
  66 + */
  67 + private RankOrderTypeEnum rankOrderType;
  68 +
  69 + /**
68 70 * 转换为百分数展示
69 71 */
70 72 public void processPercent(EvalRewardCalMethodEnum calMethod, RankTypeEnum rankType, DataTypeEnum laddersType){
... ...
fw-morax-domain/src/main/java/cn/fw/morax/domain/vo/eval/EvalGroupRewardRankLogVO.java 0 → 100644
  1 +package cn.fw.morax.domain.vo.eval;
  2 +
  3 +import cn.fw.morax.common.constant.Constant;
  4 +import cn.fw.morax.common.utils.PublicUtil;
  5 +import cn.fw.morax.domain.enums.DataTypeEnum;
  6 +import cn.fw.morax.domain.enums.EvalScopeEnum;
  7 +import cn.fw.morax.domain.enums.RankIndicatorTypeEnum;
  8 +import cn.fw.morax.domain.enums.TargetTypeEnum;
  9 +import lombok.Data;
  10 +import lombok.EqualsAndHashCode;
  11 +
  12 +import java.math.BigDecimal;
  13 +import java.time.LocalDate;
  14 +
  15 +/**
  16 + * <p>
  17 + * 奖惩排名日志
  18 + * </p>
  19 + *
  20 + * @author jiangchao
  21 + * @since 2022-12-13
  22 + */
  23 +@Data
  24 +@EqualsAndHashCode(callSuper = false)
  25 +public class EvalGroupRewardRankLogVO {
  26 +
  27 + private static final long serialVersionUID = 1L;
  28 + /**
  29 + * id
  30 + */
  31 + private Long id;
  32 +
  33 + /**
  34 + * 名称
  35 + */
  36 + private String name;
  37 +
  38 + /**
  39 + * 员工id
  40 + */
  41 + private Long poolId;
  42 +
  43 + /**
  44 + * 考评范围; 1:门店考评 2:人员考评
  45 + */
  46 + private EvalScopeEnum scopeType;
  47 +
  48 + /**
  49 + * 考评奖惩 前置条件 配置id
  50 + */
  51 + private Long referId;
  52 + /**
  53 + * 指标类型 1.奖惩提成 2.前置条件指标
  54 + */
  55 + private RankIndicatorTypeEnum targetType;
  56 + /**
  57 + * 原始值
  58 + */
  59 + private BigDecimal value;
  60 + /**
  61 + * 达成目标
  62 + */
  63 + private BigDecimal reachValue;
  64 + /**
  65 + * 排名
  66 + */
  67 + private Integer rank;
  68 + /**
  69 + * 命中
  70 + */
  71 + private Boolean hit;
  72 +
  73 + /**
  74 + * 数据日期
  75 + */
  76 + private LocalDate dataDate;
  77 +
  78 + /**
  79 + * 集团
  80 + */
  81 + private Long groupId;
  82 +
  83 + /**
  84 + * 转换为百分数展示(条件使用)
  85 + */
  86 + public void convertPercentForCond(DataTypeEnum dataType, TargetTypeEnum targetType){
  87 + if (DataTypeEnum.RATIO.equals(dataType)) {
  88 + this.setValue(this.getValue().multiply(Constant.ONE_HUNDRED));
  89 + }
  90 + //有目标
  91 + if (! TargetTypeEnum.NO.equals(targetType)) {
  92 + this.setReachValue(this.getReachValue().multiply(Constant.ONE_HUNDRED));
  93 + }
  94 + }
  95 +
  96 + /**
  97 + * 转换为百分数展示(条件使用)
  98 + */
  99 + public void convertPercentForCommission(DataTypeEnum dataType, TargetTypeEnum targetType){
  100 + if (DataTypeEnum.RATIO.equals(dataType)) {
  101 + this.setValue(this.getValue().multiply(Constant.ONE_HUNDRED));
  102 + }
  103 + //有目标
  104 + if (! TargetTypeEnum.NO.equals(targetType)) {
  105 + this.setReachValue(this.getReachValue().multiply(Constant.ONE_HUNDRED));
  106 + }
  107 + }
  108 +
  109 +}
... ...
fw-morax-server/src/main/java/cn/fw/morax/server/controller/app/EvalPoolController.java
... ... @@ -14,7 +14,6 @@ import cn.fw.morax.domain.enums.EvalScopeEnum;
14 14 import cn.fw.morax.domain.vo.SelectorVO;
15 15 import cn.fw.morax.domain.vo.eval.*;
16 16 import cn.fw.morax.domain.vo.kpi.KpiIndicatorRankVO;
17   -import cn.fw.morax.service.biz.SettingDraftBizService;
18 17 import cn.fw.morax.service.biz.eval.*;
19 18 import cn.fw.security.auth.client.annotation.Authorization;
20 19 import cn.fw.security.auth.client.annotation.IgnoreAuth;
... ... @@ -28,12 +27,11 @@ import org.springframework.web.bind.annotation.*;
28 27 import javax.validation.constraints.NotNull;
29 28 import java.time.LocalDate;
30 29 import java.time.YearMonth;
31   -import java.time.temporal.ChronoField;
32   -import java.time.temporal.TemporalAdjuster;
33   -import java.time.temporal.TemporalAdjusters;
  30 +import java.util.List;
34 31 import java.util.Objects;
35 32 import java.util.Set;
36 33  
  34 +import static cn.fw.common.businessvalidator.Validator.BV;
37 35 import static cn.fw.common.web.util.ResultBuilder.success;
38 36  
39 37 /**
... ... @@ -195,6 +193,52 @@ public class EvalPoolController {
195 193 return success(evalGroupPoolService.queryIndicatorRank(dto, EvalScopeEnum.SHOP));
196 194 }
197 195  
  196 + /**
  197 + * 门店、人员考评条件指标排名(排名条件使用)
  198 + *
  199 + * @param preconditionId
  200 + * @param dataDate
  201 + * @return
  202 + */
  203 + @GetMapping("/reward-cond-rank")
  204 + @ControllerMethod("门店、人员考评条件指标排名")
  205 + public Message<List<EvalGroupRewardRankLogVO>> queryRewardCondRank(Long preconditionId,
  206 + @NotNull(message = "日期不能为空") @RequestParam("dataDate") LocalDate dataDate) {
  207 + return success(evalGroupPoolService.getRewardCondRankLogs(preconditionId, dataDate));
  208 + }
  209 +
  210 + /**
  211 + * 门店、人员考评提成指标排名(排名计算使用)
  212 + *
  213 + * @param evalGroupRewardId
  214 + * @param dataDate
  215 + * @return
  216 + */
  217 + @GetMapping("/reward-rank")
  218 + @ControllerMethod("门店、人员考评奖惩排名")
  219 + public Message<List<EvalGroupRewardRankLogVO>> queryRewardCommissionRank(Long evalGroupRewardId,
  220 + @NotNull(message = "日期不能为空") @RequestParam("dataDate") LocalDate dataDate) {
  221 + return success(evalGroupPoolService.queryRewardCommissionRank(evalGroupRewardId, dataDate));
  222 + }
  223 +
  224 + /**
  225 + * 门店、人员考评奖惩占比(占比计算使用)
  226 + *
  227 + * @param evalGroupRewardId
  228 + * @param dataDate
  229 + * @return
  230 + */
  231 + @GetMapping("/reward-proportion")
  232 + @ControllerMethod("门店、人员考评奖惩占比")
  233 + public Message<List<EvalGroupRewardHitLogVO>> queryUserRewardProportion(@NotNull(message = "奖惩id不能为空") Long evalGroupRewardId,
  234 + @NotNull(message = "类型不能为空") Integer scopeType,
  235 + @NotNull(message = "日期不能为空") @RequestParam("dataDate") LocalDate dataDate) {
  236 + EvalScopeEnum scopeTypeEnum = EvalScopeEnum.ofValue(scopeType);
  237 + BV.notNull(scopeTypeEnum, "参数错误");
  238 + return success(evalGroupPoolService.queryRewardProportion(scopeTypeEnum, evalGroupRewardId, dataDate));
  239 + }
  240 +
  241 +
198 242  
199 243 /**
200 244 * 门店考评池列表
... ...
fw-morax-server/src/main/java/cn/fw/morax/server/controller/erp/EvalIndicatorController.java
... ... @@ -15,6 +15,7 @@ import cn.fw.morax.service.biz.eval.EvalIndicatorBizService;
15 15 import cn.fw.morax.service.biz.eval.EvalIndicatorReportService;
16 16 import cn.fw.security.auth.client.annotation.Authorization;
17 17 import cn.fw.security.auth.client.annotation.IgnoreAuth;
  18 +import cn.fw.security.auth.client.annotation.IgnoreUserToken;
18 19 import cn.fw.security.auth.client.enums.AuthType;
19 20 import lombok.RequiredArgsConstructor;
20 21 import lombok.extern.slf4j.Slf4j;
... ... @@ -89,7 +90,7 @@ public class EvalIndicatorController {
89 90 *
90 91 * @return
91 92 */
92   - @IgnoreAuth
  93 + @IgnoreUserToken
93 94 @GetMapping("/staff/template-file")
94 95 @ControllerMethod("人员模板文件")
95 96 public Message<Void> staffTemplateFile(HttpServletRequest request, HttpServletResponse response) {
... ... @@ -102,7 +103,7 @@ public class EvalIndicatorController {
102 103 *
103 104 * @return
104 105 */
105   - @IgnoreAuth
  106 + @IgnoreUserToken
106 107 @GetMapping("/shop/template-file")
107 108 @ControllerMethod("门店模板文件")
108 109 public Message<Void> shopTemplateFile(HttpServletRequest request, HttpServletResponse response) {
... ...
fw-morax-server/src/main/java/cn/fw/morax/server/task/EvalGroupTask.java
... ... @@ -50,21 +50,14 @@ import java.util.stream.Collectors;
50 50 @ConditionalOnProperty(prefix = "task", name = "switch", havingValue = "on")
51 51 public class EvalGroupTask {
52 52  
53   - private final EvalRewardService evalRewardService;
54 53 private final EvalShopPoolService evalShopPoolService;
55   - private final EvalGroupRewardService evalGroupRewardService;
56   - private final EvalGroupDataService evalGroupDataService;
57   - private final EvalGroupBizService evalGroupBizService;
58 54 private final EvalGroupService evalGroupService;
59 55 private final EvalService evalService;
60 56 private final DistributedLocker distributedLocker;
61   - private final StringRedisTemplate stringRedisTemplate;
62 57  
63   - @Value("${spring.cache.custom.global-prefix}:distr:eval-group")
  58 + @Value("${spring.cache.custom.global-prefix}:eval:group")
64 59 @Getter
65   - private String distributionKey;
66   - private final static String LOCK_KEY = "eval:group";
67   - private final static String REWARD_LOCK_KEY = "eval:group:reward";
  60 + private String evalGroupDistKey;
68 61  
69 62 /**
70 63 * 每天凌晨3点
... ... @@ -75,7 +68,7 @@ public class EvalGroupTask {
75 68 @Scheduled(cron = TimeTaskConstant.EVAL)
76 69 @Transactional(rollbackFor = Exception.class)
77 70 public void processCurMonthEffectEvals() {
78   - Lock lock = distributedLocker.lock(LOCK_KEY);
  71 + Lock lock = distributedLocker.lock(getEvalGroupDistKey());
79 72 if (! ((RLock) lock).isLocked()) {
80 73 return;
81 74 }
... ...
fw-morax-server/src/main/java/cn/fw/morax/server/task/EvalGroupUserTask.java
... ... @@ -11,9 +11,11 @@ import cn.fw.morax.service.data.eval.EvalGroupUserService;
11 11 import cn.hutool.core.date.StopWatch;
12 12 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
13 13 import com.google.common.collect.Lists;
  14 +import lombok.Getter;
14 15 import lombok.RequiredArgsConstructor;
15 16 import lombok.extern.slf4j.Slf4j;
16 17 import org.redisson.api.RLock;
  18 +import org.springframework.beans.factory.annotation.Value;
17 19 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
18 20 import org.springframework.scheduling.annotation.Scheduled;
19 21 import org.springframework.stereotype.Component;
... ... @@ -41,10 +43,11 @@ public class EvalGroupUserTask {
41 43  
42 44 private final EvalGroupUserBizService evalGroupUserBizService;
43 45 private final EvalGroupUserService evalGroupUserService;
44   - private final EvalGroupBizService evalGroupBizService;
45 46 private final DistributedLocker distributedLocker;
46 47  
47   - private final static String LOCK_KEY = "eval:group:user";
  48 + @Value("${spring.cache.custom.global-prefix}:eval:group:user")
  49 + @Getter
  50 + private String evalGroupUserDistKey;
48 51  
49 52 /**
50 53 * 每天凌晨30分执行(人事角色、岗位调整在5点执行)
... ... @@ -55,7 +58,7 @@ public class EvalGroupUserTask {
55 58 @Scheduled(cron = TimeTaskConstant.EVAL_GROUP_USER)
56 59 @Transactional(rollbackFor = Exception.class)
57 60 public void processEvalUser() {
58   - Lock lock = distributedLocker.lock(LOCK_KEY);
  61 + Lock lock = distributedLocker.lock(getEvalGroupUserDistKey());
59 62 if (((RLock) lock).isLocked()) {
60 63 try {
61 64 log.info("定时任务【考评组人员更新】开始执行");
... ...
fw-morax-server/src/main/java/cn/fw/morax/server/task/KpiGroupUserTask.java
... ... @@ -14,9 +14,11 @@ import com.alibaba.fastjson.JSON;
14 14 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
15 15 import com.google.common.collect.Lists;
16 16 import com.google.common.collect.Maps;
  17 +import lombok.Getter;
17 18 import lombok.RequiredArgsConstructor;
18 19 import lombok.extern.slf4j.Slf4j;
19 20 import org.redisson.api.RLock;
  21 +import org.springframework.beans.factory.annotation.Value;
20 22 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
21 23 import org.springframework.scheduling.annotation.Scheduled;
22 24 import org.springframework.stereotype.Component;
... ... @@ -45,8 +47,9 @@ public class KpiGroupUserTask {
45 47 private final KpiGroupBizService kpiGroupBizService;
46 48 private final DistributedLocker distributedLocker;
47 49  
48   - private final static String LOCK_KEY = "kpi:group:user";
49   -
  50 + @Value("${spring.cache.custom.global-prefix}:kpi:group:user")
  51 + @Getter
  52 + private String kpiGroupUserDistKey;
50 53 /**
51 54 * 每天凌晨30分执行(人事角色、岗位调整在5点执行)
52 55 * 1. 将待生效数据改为生效中
... ... @@ -56,7 +59,7 @@ public class KpiGroupUserTask {
56 59 @Scheduled(cron = TimeTaskConstant.KPI_GROUP_USER)
57 60 @Transactional(rollbackFor = Exception.class)
58 61 public void processKpiUser() {
59   - Lock lock = distributedLocker.lock(LOCK_KEY);
  62 + Lock lock = distributedLocker.lock(getKpiGroupUserDistKey());
60 63 if (((RLock) lock).isLocked()) {
61 64 try {
62 65 log.info("定时任务【绩效组人员更新】开始执行");
... ...
fw-morax-server/src/main/java/cn/fw/morax/server/task/KpiReportRatioTask.java
... ... @@ -19,10 +19,12 @@ import cn.fw.morax.service.data.kpi.KpiPoolService;
19 19 import cn.fw.morax.service.data.kpi.KpiRatioService;
20 20 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
21 21 import com.google.common.collect.Lists;
  22 +import lombok.Getter;
22 23 import lombok.RequiredArgsConstructor;
23 24 import lombok.extern.slf4j.Slf4j;
24 25 import org.apache.commons.collections4.map.MultiKeyMap;
25 26 import org.redisson.api.RLock;
  27 +import org.springframework.beans.factory.annotation.Value;
26 28 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
27 29 import org.springframework.scheduling.annotation.Scheduled;
28 30 import org.springframework.stereotype.Component;
... ... @@ -58,7 +60,9 @@ public class KpiReportRatioTask {
58 60 private final EhrRpcService ehrRpcService;
59 61 private final OopRpcService oopRpcService;
60 62  
61   - private final static String LOCK_KEY = "kpi:group:report";
  63 + @Value("${spring.cache.custom.global-prefix}:kpi:group:report")
  64 + @Getter
  65 + private String kpiGroupReportDistKey;
62 66  
63 67 /**
64 68 * 绩效报表定时任务
... ... @@ -77,7 +81,7 @@ public class KpiReportRatioTask {
77 81 */
78 82 @Transactional(rollbackFor = Exception.class)
79 83 public void kpiReport(LocalDate date) {
80   - Lock lock = distributedLocker.lock(LOCK_KEY);
  84 + Lock lock = distributedLocker.lock(getKpiGroupReportDistKey());
81 85 if (! ((RLock) lock).isLocked()) {
82 86 return;
83 87 }
... ...
fw-morax-server/src/main/java/cn/fw/morax/server/task/PayoffTask.java
... ... @@ -6,9 +6,11 @@ import cn.fw.morax.rpc.oop.OopRpcService;
6 6 import cn.fw.morax.rpc.oop.dto.GroupDTO;
7 7 import cn.fw.morax.service.biz.salary.PayoffBizService;
8 8 import cn.fw.morax.service.biz.salary.SalaryConfirmBizService;
  9 +import lombok.Getter;
9 10 import lombok.extern.slf4j.Slf4j;
10 11 import org.redisson.api.RLock;
11 12 import org.springframework.beans.factory.annotation.Autowired;
  13 +import org.springframework.beans.factory.annotation.Value;
12 14 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
13 15 import org.springframework.scheduling.annotation.Scheduled;
14 16 import org.springframework.stereotype.Component;
... ... @@ -31,11 +33,14 @@ import java.util.concurrent.locks.Lock;
31 33 @ConditionalOnProperty(prefix = "task", name = "switch", havingValue = "on")
32 34 public class PayoffTask {
33 35 private final PayoffBizService payoffBizService;
34   - private final static String LOCK_KEY = ":createSalarySheet";
35 36 private final DistributedLocker distributedLocker;
36 37 private final OopRpcService oopRpcService;
37 38 private final SalaryConfirmBizService salaryConfirmBizService;
38 39  
  40 + @Value("${spring.cache.custom.global-prefix}:createSalarySheet")
  41 + @Getter
  42 + private String createSalarySheetKey;
  43 +
39 44 @Autowired
40 45 public PayoffTask(final PayoffBizService payoffBizService,
41 46 final DistributedLocker distributedLocker,
... ... @@ -71,7 +76,7 @@ public class PayoffTask {
71 76 */
72 77 @Scheduled(cron = "0 0 0/2 * * ?")
73 78 public void createSalarySheet() {
74   - Lock lock = distributedLocker.lock(LOCK_KEY);
  79 + Lock lock = distributedLocker.lock(getCreateSalarySheetKey());
75 80 if (((RLock) lock).isLocked()) {
76 81 List<GroupDTO> list = oopRpcService.allGroups();
77 82 if (!CollectionUtils.isEmpty(list)) {
... ...
fw-morax-server/src/main/java/cn/fw/morax/server/task/SalaryGroupTask.java
... ... @@ -12,9 +12,11 @@ import cn.fw.morax.service.biz.salary.SalaryGroupUserBizService;
12 12 import cn.fw.morax.service.data.salary.SalaryGroupService;
13 13 import cn.hutool.core.date.StopWatch;
14 14 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  15 +import lombok.Getter;
15 16 import lombok.RequiredArgsConstructor;
16 17 import lombok.extern.slf4j.Slf4j;
17 18 import org.redisson.api.RLock;
  19 +import org.springframework.beans.factory.annotation.Value;
18 20 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
19 21 import org.springframework.scheduling.annotation.Scheduled;
20 22 import org.springframework.stereotype.Component;
... ... @@ -44,7 +46,9 @@ public class SalaryGroupTask {
44 46 private final SalaryGroupService salaryGroupService;
45 47 private final DistributedLocker distributedLocker;
46 48  
47   - private final static String LOCK_KEY = "salary:group";
  49 + @Value("${spring.cache.custom.global-prefix}:salary:group")
  50 + @Getter
  51 + private String salaryGroupKey;
48 52  
49 53 /**
50 54 * 每个月1号凌晨3点执行
... ... @@ -55,7 +59,7 @@ public class SalaryGroupTask {
55 59 @Scheduled(cron = TimeTaskConstant.SALARY_GROUP)
56 60 @Transactional(rollbackFor = Exception.class)
57 61 public void processCurMonthEffectSalaryGroup() {
58   - Lock lock = distributedLocker.lock(LOCK_KEY);
  62 + Lock lock = distributedLocker.lock(getSalaryGroupKey());
59 63 if (((RLock) lock).isLocked()) {
60 64 try {
61 65 log.info("定时任务【每月薪酬组配置状态改变】开始执行");
... ...
fw-morax-server/src/main/java/cn/fw/morax/server/task/SalaryPoolFundShopTask.java
... ... @@ -11,9 +11,11 @@ import cn.fw.morax.rpc.ehr.dto.StaffShopInfoDTO;
11 11 import cn.fw.morax.service.data.salary.SalaryPoolService;
12 12 import com.google.common.base.Functions;
13 13 import com.google.common.collect.Lists;
  14 +import lombok.Getter;
14 15 import lombok.RequiredArgsConstructor;
15 16 import lombok.extern.slf4j.Slf4j;
16 17 import org.redisson.api.RLock;
  18 +import org.springframework.beans.factory.annotation.Value;
17 19 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
18 20 import org.springframework.scheduling.annotation.Scheduled;
19 21 import org.springframework.stereotype.Component;
... ... @@ -43,7 +45,9 @@ public class SalaryPoolFundShopTask {
43 45 private final SalaryPoolService salaryPoolService;
44 46 private final EhrRpcService ehrRpcService;
45 47  
46   - private final static String LOCK_KEY = "salary:pool:fund";
  48 + @Value("${spring.cache.custom.global-prefix}:salary:pool:fund")
  49 + @Getter
  50 + private String salaryPoolFundKey;
47 51  
48 52 /**
49 53 * 每月第一天凌晨执行,薪酬池写入社保公积金门店
... ... @@ -53,7 +57,7 @@ public class SalaryPoolFundShopTask {
53 57 @Scheduled(cron = TimeTaskConstant.SALARY_POOL_FUND_SHOP)
54 58 @Transactional(rollbackFor = Exception.class)
55 59 public void dealSalaryPoolFundShop() {
56   - Lock lock = distributedLocker.lock(LOCK_KEY);
  60 + Lock lock = distributedLocker.lock(getSalaryPoolFundKey());
57 61 if (((RLock) lock).isLocked()) {
58 62 try {
59 63 log.info("定时任务【酬池写入社保公积金门店】开始执行");
... ...
fw-morax-server/src/main/java/cn/fw/morax/server/task/SalaryReportTask.java
... ... @@ -21,10 +21,12 @@ import cn.fw.morax.service.data.salary.SalaryRewardService;
21 21 import com.alibaba.fastjson.JSON;
22 22 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
23 23 import com.google.common.collect.Lists;
  24 +import lombok.Getter;
24 25 import lombok.RequiredArgsConstructor;
25 26 import lombok.extern.slf4j.Slf4j;
26 27 import org.apache.commons.collections4.map.MultiKeyMap;
27 28 import org.redisson.api.RLock;
  29 +import org.springframework.beans.factory.annotation.Value;
28 30 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
29 31 import org.springframework.scheduling.annotation.Scheduled;
30 32 import org.springframework.stereotype.Component;
... ... @@ -60,7 +62,9 @@ public class SalaryReportTask {
60 62 private final OopRpcService oopRpcService;
61 63 private final DistributedLocker distributedLocker;
62 64  
63   - private final static String LOCK_KEY = "kpi:group:report";
  65 + @Value("${spring.cache.custom.global-prefix}:salary:group:report")
  66 + @Getter
  67 + private String salaryGroupReport;
64 68  
65 69 /**
66 70 * 绩效报表定时任务
... ... @@ -78,7 +82,7 @@ public class SalaryReportTask {
78 82 */
79 83 @Transactional(rollbackFor = Exception.class)
80 84 public void salaryReport(LocalDate date) {
81   - Lock lock = distributedLocker.lock(LOCK_KEY);
  85 + Lock lock = distributedLocker.lock(getSalaryGroupReport());
82 86 if (!((RLock) lock).isLocked()) {
83 87 return;
84 88 }
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/CommonService.java
... ... @@ -6,6 +6,7 @@ import cn.fw.morax.common.constant.Constant;
6 6 import cn.fw.morax.common.utils.ExcelDataUtil;
7 7 import cn.fw.morax.common.utils.PublicUtil;
8 8 import cn.fw.morax.domain.db.SettingDraft;
  9 +import cn.fw.morax.domain.db.eval.EvalGroupRewardRankLog;
9 10 import cn.fw.morax.domain.db.eval.EvalIndicatorValue;
10 11 import cn.fw.morax.domain.db.kpi.IndicatorUserValue;
11 12 import cn.fw.morax.domain.db.kpi.KpiGroup;
... ... @@ -15,6 +16,7 @@ import cn.fw.morax.domain.enums.IndicatorValueTypeEnum;
15 16 import cn.fw.morax.domain.enums.SettingDraftStatusEnum;
16 17 import cn.fw.morax.domain.enums.SettingDraftTypeEnum;
17 18 import cn.fw.morax.domain.vo.kpi.IndicatorUserValueVO;
  19 +import cn.fw.morax.domain.vo.kpi.KpiIndicatorRankStaffVO;
18 20 import cn.fw.morax.rpc.ehr.EhrRpcService;
19 21 import cn.fw.morax.rpc.ehr.dto.StaffBaseInfoDTO;
20 22 import cn.fw.morax.service.data.SettingDraftService;
... ... @@ -368,4 +370,27 @@ public class CommonService {
368 370 return settingDrafts;
369 371 }
370 372  
  373 + /**
  374 + * 设置排名序号
  375 + *
  376 + * @return
  377 + */
  378 + public void calcRank(List<EvalGroupRewardRankLog> rankLogs) {
  379 + int rank = 1;
  380 + BigDecimal lastIndicatorValue = null;
  381 + for (EvalGroupRewardRankLog rankLog : rankLogs) {
  382 + //初始化
  383 + if (PublicUtil.isEmpty(lastIndicatorValue)) {
  384 + rankLog.setRank(rank);
  385 + lastIndicatorValue = rankLog.getReachValue();
  386 + continue;
  387 + }
  388 + if (lastIndicatorValue.compareTo(rankLog.getReachValue()) != 0) {
  389 + rank++;
  390 + }
  391 + rankLog.setRank(rank);
  392 + lastIndicatorValue = rankLog.getReachValue();
  393 + }
  394 + }
  395 +
371 396 }
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/calculator/eval/reward/EvalRewardBaseCalculator.java
... ... @@ -6,12 +6,15 @@ import cn.fw.morax.domain.bo.eval.EvalGroupUserShop;
6 6 import cn.fw.morax.domain.db.eval.*;
7 7 import cn.fw.morax.domain.db.kpi.IndicatorUserValue;
8 8 import cn.fw.morax.domain.enums.*;
  9 +import cn.fw.morax.service.biz.CommonService;
9 10 import cn.fw.morax.service.biz.calculator.Calculator;
10 11 import cn.fw.morax.service.data.eval.*;
11 12 import cn.fw.morax.service.data.kpi.IndicatorUserValueService;
  13 +import com.alibaba.fastjson.JSON;
12 14 import com.alibaba.fastjson.JSONObject;
13 15 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
14 16 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  17 +import com.google.common.collect.Lists;
15 18 import lombok.Getter;
16 19 import lombok.extern.slf4j.Slf4j;
17 20 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -29,7 +32,6 @@ import java.time.LocalDateTime;
29 32 import java.time.temporal.ChronoUnit;
30 33 import java.util.*;
31 34 import java.util.concurrent.atomic.AtomicInteger;
32   -import java.util.concurrent.atomic.AtomicReference;
33 35 import java.util.function.Consumer;
34 36 import java.util.function.Function;
35 37 import java.util.stream.Collectors;
... ... @@ -47,6 +49,8 @@ import java.util.stream.Collectors;
47 49 public abstract class EvalRewardBaseCalculator implements Calculator<EvalGroupUserShop, EvalGroupReward, BigDecimal> {
48 50  
49 51 @Autowired
  52 + protected EvalGroupRewardRankLogService evalGroupRewardRankLogService;
  53 + @Autowired
50 54 protected EvalGroupRewardHitLogService evalGroupRewardHitLogService;
51 55 @Autowired
52 56 protected EvalGroupRewardPreconditionHitLogService evalGroupRewardPreconditionHitLogService;
... ... @@ -68,6 +72,8 @@ public abstract class EvalRewardBaseCalculator implements Calculator&lt;EvalGroupUs
68 72 protected EvalGroupRewardService evalGroupRewardService;
69 73 @Autowired
70 74 private StringRedisTemplate stringRedisTemplate;
  75 + @Autowired
  76 + private CommonService commonService;
71 77 @Value("${spring.cache.custom.global-prefix}:eval:reward:cond:rank")
72 78 @Getter
73 79 private String preconditionRank;
... ... @@ -119,7 +125,8 @@ public abstract class EvalRewardBaseCalculator implements Calculator&lt;EvalGroupUs
119 125 protected List<EvalGroupRewardLadders> queryRewardLadders(final Long evalGroupRewardId) {
120 126 List<EvalGroupRewardLadders> ladders = evalGroupRewardLaddersService.list(Wrappers.<EvalGroupRewardLadders>lambdaQuery()
121 127 .eq(EvalGroupRewardLadders::getEvalGroupRewardId, evalGroupRewardId)
122   - .eq(EvalGroupRewardLadders::getYn, Boolean.TRUE));
  128 + .eq(EvalGroupRewardLadders::getYn, Boolean.TRUE)
  129 + );
123 130 if (CollectionUtils.isEmpty(ladders)) {
124 131 return Collections.emptyList();
125 132 }
... ... @@ -168,54 +175,50 @@ public abstract class EvalRewardBaseCalculator implements Calculator&lt;EvalGroupUs
168 175 *
169 176 * @return
170 177 */
  178 + @Transactional(rollbackFor = Exception.class)
171 179 protected void examineRankPreconditions(List<EvalGroupUserShop> userShops, List<EvalGroupRewardPrecondition> preconditions) {
172 180 if (CollectionUtils.isEmpty(preconditions)) {
173 181 return;
174 182 }
175 183 for (EvalGroupRewardPrecondition precondition : preconditions) {
176   - final String indicatorCode = precondition.getCode();
177 184 final Long preconditionId = precondition.getId();
178   - final TargetTypeEnum targetType = precondition.getTargetType();
179   - final BigDecimal targetValue = precondition.getTargetValue();
180   - final TargetCalcTypeEnum targetCalcType = precondition.getTargetCalcType();
181 185 final BigDecimal personCount = BigDecimal.valueOf(userShops.size());
182   - final Integer startIndex = 0;
183 186 final BigDecimal condValue = precondition.getCondValue();
  187 + final Integer startIndex = 0;
184 188 final Integer endIndex = condValue.multiply(personCount).divide(BigDecimal.ONE, 0, RoundingMode.FLOOR).intValue() - 1;
185 189  
186   - String key = getPreconditionRank() + ":" + precondition.getId();
187   - BoundZSetOperations<String, String> zSetOps = stringRedisTemplate.boundZSetOps(key);
188   - stringRedisTemplate.expireAt(key, DateUtil.localDateTime2Date(LocalDateTime.now().plus(2L, ChronoUnit.HOURS)));
189   - for (EvalGroupUserShop userShop : userShops) {
190   - final BigDecimal indicatorValue = queryValue(userShop, precondition.getCodeType(), indicatorCode).orElse(BigDecimal.ZERO);
191   - BigDecimal reachValue = indicatorValue;
192   - if (!TargetTypeEnum.NO.equals(targetType)) {
193   - reachValue = calculateTargetValue(targetCalcType, targetValue, indicatorValue);
194   - }
195   - saveTargetHitLog(userShop, preconditionId, IndicatorTypeEnum.PRE, indicatorValue, reachValue);
196   - zSetOps.add(userShop.getPoolId().toString(), reachValue.doubleValue());
197   - }
  190 + //计算排名
  191 + List<EvalGroupRewardRankLog> rankLogs = calculateRankPreconditionValue(userShops, precondition);
  192 + Collections.sort(rankLogs);
  193 + commonService.calcRank(rankLogs);
  194 + saveRankLogs(preconditionId, rankLogs, RankIndicatorTypeEnum.PRE);
  195 + Map<Long, EvalGroupUserShop> poolUserShopMap = userShops.stream().collect(Collectors.toMap(EvalGroupUserShop::getPoolId,
  196 + Function.identity(), (v1, v2) -> v1));
198 197  
199 198 if (startIndex > endIndex) {
200 199 continue;
201 200 }
202 201  
203   - Map<Long, EvalGroupUserShop> userShopMap = userShops.stream().collect(Collectors.toMap(EvalGroupUserShop::getPoolId, Function.identity(), (v1, v2) -> v1));
204   - Set<ZSetOperations.TypedTuple<String>> referIdStrs = zSetOps.reverseRangeWithScores(startIndex, endIndex);
  202 + Integer _startIndex = startIndex, _endIndex = endIndex;;
  203 + List<EvalGroupRewardRankLog> matchRankLogs = rankLogs.stream().filter(rankLog -> {
  204 + return rankLog.getRank() > _startIndex && rankLog.getRank() <= _endIndex;
  205 + }).collect(Collectors.toList());
  206 + updateHitRankLog(matchRankLogs);
  207 +
205 208 AtomicInteger rank = new AtomicInteger(0);
206   - referIdStrs.stream().forEach(stringTypedTuple -> {
207   - EvalGroupUserShop userShop = userShopMap.get(Long.parseLong(stringTypedTuple.getValue()));
  209 + for (EvalGroupRewardRankLog rankLog : matchRankLogs) {
  210 + EvalGroupUserShop userShop = poolUserShopMap.get(rankLog.getPoolId());
208 211 if (PublicUtil.isNotEmpty(userShop)) {
209 212 List<Long> meetRankCondIds = Optional.ofNullable(userShop.getMeetRankCondIds()).orElse(new ArrayList<>());
210 213 meetRankCondIds.add(preconditionId);
211 214 userShop.setMeetRankCondIds(meetRankCondIds);
212 215 savePreHitLog(userShop, precondition, log -> {
213   - log.setReachValue(new BigDecimal(stringTypedTuple.getScore().toString()));
  216 + log.setReachValue(rankLog.getReachValue());
214 217 log.setCondValue(new BigDecimal(endIndex + 1));
215 218 log.setRank(rank.incrementAndGet());
216 219 });
217 220 }
218   - });
  221 + }
219 222 }
220 223 }
221 224  
... ... @@ -238,6 +241,7 @@ public abstract class EvalRewardBaseCalculator implements Calculator&lt;EvalGroupUs
238 241 return params;
239 242 }
240 243  
  244 + @Transactional(rollbackFor = Exception.class)
241 245 protected void saveTargetHitLog(EvalGroupUserShop userShop, Long rewardReferId, IndicatorTypeEnum targetType, BigDecimal value, BigDecimal reachValue) {
242 246 evalGroupRewardTargetHitLogService.remove(Wrappers.<EvalGroupRewardTargetHitLog>lambdaQuery()
243 247 .eq(EvalGroupRewardTargetHitLog::getPoolId, userShop.getPoolId())
... ... @@ -259,6 +263,7 @@ public abstract class EvalRewardBaseCalculator implements Calculator&lt;EvalGroupUs
259 263 evalGroupRewardTargetHitLogService.save(log);
260 264 }
261 265  
  266 + @Transactional(rollbackFor = Exception.class)
262 267 protected void savePreHitLog(EvalGroupUserShop userShop, EvalGroupRewardPrecondition precondition, Consumer<EvalGroupRewardPreconditionHitLog> consumer) {
263 268 evalGroupRewardPreconditionHitLogService.remove(Wrappers.<EvalGroupRewardPreconditionHitLog>lambdaQuery()
264 269 .eq(EvalGroupRewardPreconditionHitLog::getPoolId, userShop.getPoolId())
... ... @@ -435,6 +440,115 @@ public abstract class EvalRewardBaseCalculator implements Calculator&lt;EvalGroupUs
435 440 }
436 441  
437 442 /**
  443 + * 计算排名提成参数最终值
  444 + *
  445 + * @param userShops
  446 + * @param evalGroupRewardId
  447 + * @param params
  448 + * @return
  449 + */
  450 + protected List<EvalGroupRewardRankLog> calculateRankParamValue(List<EvalGroupUserShop> userShops, Long evalGroupRewardId, List<EvalGroupRewardParam> params) {
  451 + List<EvalGroupRewardRankLog> rankLogs = Lists.newArrayListWithCapacity(userShops.size());
  452 + for (EvalGroupUserShop userShop : userShops) {
  453 + BigDecimal commissionValue = BigDecimal.ZERO;
  454 + for (EvalGroupRewardParam param: params) {
  455 + String indicatorCode = param.getCode();
  456 + boolean isCap = Boolean.TRUE.equals(param.getCap());
  457 + BigDecimal proportion = param.getProportion();
  458 + TargetTypeEnum targetType = param.getTargetType();
  459 + final BigDecimal userOriginValue = queryValue(userShop, param.getCodeType(), indicatorCode).orElse(BigDecimal.ZERO);
  460 + BigDecimal _calcValue = userOriginValue;
  461 + if (!TargetTypeEnum.NO.equals(targetType)) {
  462 + _calcValue = calculateTargetValue(param.getTargetCalcType(), param.getTargetValue(), _calcValue);
  463 + saveTargetHitLog(userShop, param.getId(), IndicatorTypeEnum.EXAMINE, userOriginValue, _calcValue);
  464 + }
  465 + if (isCap) {
  466 + _calcValue = _calcValue.compareTo(BigDecimal.ONE) > 0 ? BigDecimal.ONE : _calcValue;
  467 + }
  468 + commissionValue = commissionValue.add(proportion.multiply(_calcValue));
  469 + }
  470 + EvalGroupRewardRankLog rankLog = EvalGroupRewardRankLog.builder()
  471 + .poolId(userShop.getPoolId())
  472 + .name(userShop.getName())
  473 + .scopeType(userShop.getScopeType())
  474 + .referId(evalGroupRewardId)
  475 + .targetType(RankIndicatorTypeEnum.REWARD_COMMISSION)
  476 + .value(commissionValue)
  477 + .reachValue(commissionValue)
  478 + .hit(Boolean.FALSE)
  479 + .dataDate(userShop.getDataDate())
  480 + .groupId(userShop.getGroupId())
  481 + .build();
  482 + rankLogs.add(rankLog);
  483 + }
  484 + return rankLogs;
  485 + }
  486 +
  487 + /**
  488 + * 计算排名条件最终值
  489 + *
  490 + * @param userShops
  491 + * @param precondition
  492 + * @return
  493 + */
  494 + protected List<EvalGroupRewardRankLog> calculateRankPreconditionValue(List<EvalGroupUserShop> userShops, EvalGroupRewardPrecondition precondition) {
  495 + final String indicatorCode = precondition.getCode();
  496 + final Long preconditionId = precondition.getId();
  497 + final TargetTypeEnum targetType = precondition.getTargetType();
  498 + final BigDecimal targetValue = precondition.getTargetValue();
  499 + final TargetCalcTypeEnum targetCalcType = precondition.getTargetCalcType();
  500 +
  501 + List<EvalGroupRewardRankLog> rankLogs = Lists.newArrayListWithCapacity(userShops.size());
  502 + for (EvalGroupUserShop userShop : userShops) {
  503 + final BigDecimal indicatorValue = queryValue(userShop, precondition.getCodeType(), indicatorCode).orElse(BigDecimal.ZERO);
  504 + BigDecimal reachValue = indicatorValue;
  505 + if (!TargetTypeEnum.NO.equals(targetType)) {
  506 + reachValue = calculateTargetValue(targetCalcType, targetValue, indicatorValue);
  507 + }
  508 +
  509 + EvalGroupRewardRankLog rankLog = EvalGroupRewardRankLog.builder()
  510 + .name(userShop.getName())
  511 + .poolId(userShop.getPoolId())
  512 + .scopeType(userShop.getScopeType())
  513 + .referId(preconditionId)
  514 + .targetType(RankIndicatorTypeEnum.PRE)
  515 + .value(indicatorValue)
  516 + .reachValue(reachValue)
  517 + .dataDate(userShop.getDataDate())
  518 + .groupId(userShop.getGroupId())
  519 + .build();
  520 + rankLogs.add(rankLog);
  521 + }
  522 + return rankLogs;
  523 + }
  524 +
  525 + @Transactional(rollbackFor = Exception.class)
  526 + public void saveRankLogs(Long evalGroupRewardId, List<EvalGroupRewardRankLog> rankLogs, RankIndicatorTypeEnum targetType) {
  527 + Set<Long> poolIds = rankLogs.stream().map(EvalGroupRewardRankLog::getPoolId).collect(Collectors.toSet());
  528 + EvalGroupRewardRankLog rankLog = rankLogs.stream().findFirst().get();
  529 + evalGroupRewardRankLogService.remove(Wrappers.<EvalGroupRewardRankLog>lambdaQuery()
  530 + .in(EvalGroupRewardRankLog::getPoolId, poolIds)
  531 + .eq(EvalGroupRewardRankLog::getScopeType, rankLog.getScopeType())
  532 + .eq(EvalGroupRewardRankLog::getReferId, evalGroupRewardId)
  533 + .eq(EvalGroupRewardRankLog::getTargetType, targetType)
  534 + .eq(EvalGroupRewardRankLog::getGroupId, rankLog.getGroupId())
  535 + );
  536 +
  537 + evalGroupRewardRankLogService.saveBatch(rankLogs);
  538 + }
  539 +
  540 + @Transactional(rollbackFor = Exception.class)
  541 + public void updateHitRankLog(List<EvalGroupRewardRankLog> matchRankLogs) {
  542 + if (PublicUtil.isEmpty(matchRankLogs)) {
  543 + return;
  544 + }
  545 + evalGroupRewardRankLogService.update(Wrappers.<EvalGroupRewardRankLog>lambdaUpdate()
  546 + .in(EvalGroupRewardRankLog::getId, matchRankLogs.stream().map(EvalGroupRewardRankLog::getId).collect(Collectors.toList()))
  547 + .set(EvalGroupRewardRankLog::getHit, Boolean.TRUE)
  548 + );
  549 + }
  550 +
  551 + /**
438 552 * 初始化奖惩值
439 553 *
440 554 * @param userShops
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/calculator/eval/reward/EvalRewardProportionCalculator.java
... ... @@ -69,25 +69,8 @@ public class EvalRewardProportionCalculator extends EvalRewardBaseCalculator {
69 69 referValueMap.put(poolId, commissionValue);
70 70 }
71 71  
72   - if (BigDecimal.ZERO.compareTo(totalCommissionValue) == 0) {
73   - for (EvalGroupUserShop userShop : userShops) {
74   - BigDecimal proportion = BigDecimal.ZERO;
75   - BigDecimal rewardValue = BigDecimal.ZERO;
76   - userShop.setEvalGroupRewardAmount(rewardValue);
77   - clearProjectHitLog(evalGroupRewardId, userShop);
78   - saveProjectHitLog(evalGroupRewardId, userShop, log -> {
79   - log.setRewardValue(rewardValue);
80   - log.setHitCommissionValue(proportion);
81   - });
82   - }
83   - }
84   -
85 72 for (EvalGroupUserShop userShop : userShops) {
86 73 boolean examined = examinePrecondition(userShop, preconditions);
87   - if (!examined) {
88   - userShop.setEvalGroupRewardAmount(BigDecimal.ZERO);
89   - continue;
90   - }
91 74  
92 75 BigDecimal commissionValue = referValueMap.getOrDefault(userShop.getPoolId(), BigDecimal.ZERO);
93 76  
... ... @@ -98,6 +81,11 @@ public class EvalRewardProportionCalculator extends EvalRewardBaseCalculator {
98 81 rewardValue = proportion.multiply(money).divide(BigDecimal.ONE, 2, RoundingMode.DOWN);
99 82 }
100 83  
  84 + //未通过条件,奖惩为0,保存日志
  85 + if (!examined) {
  86 + rewardValue = BigDecimal.ZERO;
  87 + }
  88 +
101 89 userShop.setEvalGroupRewardAmount(rewardValue);
102 90 clearProjectHitLog(evalGroupRewardId, userShop);
103 91 BigDecimal finalRewardValue = rewardValue;
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/calculator/eval/reward/EvalRewardRankCalculator.java
1 1 package cn.fw.morax.service.biz.calculator.eval.reward;
2 2  
3   -import cn.fw.morax.common.utils.DateUtil;
4 3 import cn.fw.morax.common.utils.PublicUtil;
5 4 import cn.fw.morax.domain.bo.eval.EvalGroupUserShop;
6   -import cn.fw.morax.domain.db.eval.EvalGroupReward;
7   -import cn.fw.morax.domain.db.eval.EvalGroupRewardLadders;
8   -import cn.fw.morax.domain.db.eval.EvalGroupRewardParam;
9   -import cn.fw.morax.domain.db.eval.EvalGroupRewardPrecondition;
10   -import cn.fw.morax.domain.enums.EvalRewardCalMethodEnum;
11   -import cn.fw.morax.domain.enums.ParamTypeEnum;
12   -import cn.fw.morax.domain.enums.RankTypeEnum;
  5 +import cn.fw.morax.domain.db.eval.*;
  6 +import cn.fw.morax.domain.enums.*;
  7 +import cn.fw.morax.service.biz.CommonService;
  8 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  9 +import com.sun.org.apache.regexp.internal.RE;
13 10 import lombok.Getter;
14 11 import lombok.RequiredArgsConstructor;
15 12 import lombok.extern.slf4j.Slf4j;
16 13 import org.springframework.beans.factory.annotation.Value;
17   -import org.springframework.data.redis.core.BoundZSetOperations;
18 14 import org.springframework.data.redis.core.StringRedisTemplate;
19 15 import org.springframework.stereotype.Component;
20 16 import org.springframework.util.CollectionUtils;
21 17  
22 18 import java.math.BigDecimal;
23 19 import java.math.RoundingMode;
24   -import java.time.LocalDate;
25   -import java.time.LocalDateTime;
26   -import java.time.temporal.ChronoUnit;
27   -import java.util.HashMap;
28   -import java.util.List;
29   -import java.util.Map;
30   -import java.util.Set;
  20 +import java.util.*;
  21 +import java.util.function.Function;
  22 +import java.util.stream.Collectors;
31 23  
32 24 /**
33 25 * @author jiangchao
... ... @@ -39,11 +31,7 @@ import java.util.Set;
39 31 @RequiredArgsConstructor
40 32 public class EvalRewardRankCalculator extends EvalRewardBaseCalculator {
41 33  
42   - private final StringRedisTemplate stringRedisTemplate;
43   -
44   - @Value("${spring.cache.custom.global-prefix}:eval:reward:rank")
45   - @Getter
46   - private String rank;
  34 + private final CommonService commonService;
47 35  
48 36 @Override
49 37 public EvalRewardCalMethodEnum getCalMethod() {
... ... @@ -62,7 +50,6 @@ public class EvalRewardRankCalculator extends EvalRewardBaseCalculator {
62 50 }
63 51 initReward(userShops);
64 52 final Long evalGroupRewardId = reward.getId();
65   - final String key = getRank() + evalGroupRewardId;
66 53 RankTypeEnum rankType = reward.getRankType();
67 54 List<EvalGroupRewardPrecondition> preconditions = queryPrecondition(evalGroupRewardId);
68 55 List<EvalGroupRewardParam> params = queryProjectParam(evalGroupRewardId, ParamTypeEnum.LADDER);
... ... @@ -70,48 +57,32 @@ public class EvalRewardRankCalculator extends EvalRewardBaseCalculator {
70 57 return;
71 58 }
72 59  
73   - BoundZSetOperations<String, String> zSetOps = stringRedisTemplate.boundZSetOps(key);
74   - stringRedisTemplate.expireAt(key, DateUtil.localDateTime2Date(LocalDateTime.now().plus(2L, ChronoUnit.HOURS)));
75   -
76   - Map<String, EvalGroupUserShop> rewardObjectBOMap = new HashMap<>();
77   - Map<String, BigDecimal> referCommonMap = new HashMap<>();
78   - for (EvalGroupUserShop rewardObject : userShops) {
79   - BigDecimal commissionValue = calculateParamValue(rewardObject, params);
80   - zSetOps.add(rewardObject.getReferId().toString(), commissionValue.doubleValue());
81   -
82   - referCommonMap.put(rewardObject.getReferId().toString(), commissionValue);
83   - rewardObjectBOMap.put(rewardObject.getReferId().toString(), rewardObject);
84   - }
  60 + //计算排名
  61 + List<EvalGroupRewardRankLog> rankLogs = calculateRankParamValue(userShops, evalGroupRewardId, params);
  62 + Collections.sort(rankLogs);
  63 + commonService.calcRank(rankLogs);
  64 + saveRankLogs(evalGroupRewardId, rankLogs, RankIndicatorTypeEnum.REWARD_COMMISSION);
  65 + Map<Long, EvalGroupUserShop> poolUserShopMap = userShops.stream().collect(Collectors.toMap(EvalGroupUserShop::getPoolId,
  66 + Function.identity(), (v1, v2) -> v1));
85 67  
  68 + //计算金额
86 69 final BigDecimal personCount = BigDecimal.valueOf(userShops.size());
87 70 List<EvalGroupRewardLadders> ladders = queryRewardLadders(evalGroupRewardId);
88 71 for (EvalGroupRewardLadders ladder : ladders) {
89 72 final BigDecimal money = ladder.getMoney();
90   - Integer startIndex = null;
91   - Integer endIndex = null;
92   -
93   - if (RankTypeEnum.PERCENT.equals(rankType)) {
94   - startIndex = ladder.getLower().multiply(personCount).divide(BigDecimal.ONE, 0, RoundingMode.FLOOR).intValue();
95   - endIndex = ladder.getUpper().multiply(personCount).divide(BigDecimal.ONE, 0, RoundingMode.FLOOR).intValue() - 1;
96   - } else {
97   - startIndex = ladder.getLower().intValue() - 1;
98   - endIndex = ladder.getUpper().intValue()- 1;
99   - }
100 73  
101   - if (startIndex > endIndex) {
102   - continue;
103   - }
  74 + List<EvalGroupRewardRankLog> matchRankLogs = matchRank(rankType, personCount, ladder, rankLogs);
  75 + updateHitRankLog(matchRankLogs);
104 76  
105   - Set<String> referIdStrs = zSetOps.reverseRange(startIndex, endIndex);
106   - for (String referIdStr : referIdStrs) {
107   - EvalGroupUserShop userShop = rewardObjectBOMap.get(referIdStr);
  77 + for (EvalGroupRewardRankLog rankLog : matchRankLogs) {
  78 + EvalGroupUserShop userShop = poolUserShopMap.get(rankLog.getPoolId());
108 79 boolean examined = examinePrecondition(userShop, preconditions);
109 80 if (!examined) {
110 81 userShop.setEvalGroupRewardAmount(BigDecimal.ZERO);
111 82 continue;
112 83 }
113 84 userShop.setEvalGroupRewardAmount(money);
114   - BigDecimal hitCommissionValue = referCommonMap.get(referIdStr);
  85 + BigDecimal hitCommissionValue = rankLog.getReachValue();
115 86 clearProjectHitLog(evalGroupRewardId, userShop);
116 87 saveProjectHitLog(evalGroupRewardId, userShop, log -> {
117 88 log.setRewardValue(money);
... ... @@ -124,5 +95,65 @@ public class EvalRewardRankCalculator extends EvalRewardBaseCalculator {
124 95  
125 96 }
126 97  
  98 + /**
  99 + * 匹配排名
  100 + *
  101 + * @param rankType
  102 + * @param personCount
  103 + * @param ladder
  104 + * @param rankLogs
  105 + * @return
  106 + */
  107 + public List<EvalGroupRewardRankLog> matchRank(final RankTypeEnum rankType,
  108 + final BigDecimal personCount,
  109 + EvalGroupRewardLadders ladder,
  110 + List<EvalGroupRewardRankLog> rankLogs) {
  111 + BigDecimal lower = ladder.getLower();
  112 + BigDecimal upper = ladder.getUpper();
  113 + RankOrderTypeEnum rankOrderType = ladder.getRankOrderType();
  114 + Integer startIndex ;
  115 + Integer endIndex ;
  116 +
  117 + //百分比
  118 + if (RankTypeEnum.PERCENT.equals(rankType)) {
  119 + if (RankOrderTypeEnum.NEGATIVE.equals(rankOrderType)) {
  120 + lower = BigDecimal.ONE.subtract(ladder.getUpper());
  121 + upper = BigDecimal.ONE.subtract(ladder.getLower());
  122 + }
  123 + startIndex = lower.multiply(personCount).divide(BigDecimal.ONE, 0, RoundingMode.FLOOR).intValue();
  124 + endIndex = upper.multiply(personCount).divide(BigDecimal.ONE, 0, RoundingMode.FLOOR).intValue();
  125 +
  126 + if (startIndex > endIndex) {
  127 + return new ArrayList<>();
  128 + }
  129 +
  130 + Integer finalEndIndex = endIndex,finalStartIndex = startIndex;
  131 + List<EvalGroupRewardRankLog> matchRankLogs = rankLogs.stream().filter(rankLog -> {
  132 + return rankLog.getRank() > finalStartIndex && rankLog.getRank() <= finalEndIndex;
  133 + }).collect(Collectors.toList());
  134 + return matchRankLogs;
  135 + }
  136 +
  137 + //名次
  138 + if (RankOrderTypeEnum.NEGATIVE.equals(rankOrderType)) {
  139 + startIndex = personCount.subtract(upper).intValue() + 1;
  140 + endIndex = personCount.subtract(lower).intValue() + 1;
  141 + } else {
  142 + startIndex = ladder.getLower().intValue();
  143 + endIndex = ladder.getUpper().intValue();
  144 + }
  145 +
  146 + if (startIndex > endIndex) {
  147 + return new ArrayList<>();
  148 + }
  149 +
  150 + Integer finalEndIndex = endIndex,finalStartIndex = startIndex;
  151 + List<EvalGroupRewardRankLog> matchRankLogs = rankLogs.stream().filter(rankLog -> {
  152 + return rankLog.getRank() >= finalStartIndex && rankLog.getRank() <= finalEndIndex;
  153 + }).collect(Collectors.toList());
  154 +
  155 + return matchRankLogs;
  156 + }
  157 +
127 158  
128 159 }
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/calculator/kpi/KpiAbsBaseCalculator.java
... ... @@ -8,19 +8,19 @@ import cn.fw.morax.domain.enums.TargetCalcTypeEnum;
8 8 import cn.fw.morax.domain.enums.TargetTypeEnum;
9 9 import cn.fw.morax.service.biz.calculator.Calculator;
10 10 import cn.fw.morax.service.data.kpi.*;
  11 +import com.alibaba.fastjson.JSON;
11 12 import com.alibaba.fastjson.JSONObject;
12 13 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
13 14 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  15 +import com.google.common.base.Strings;
14 16 import lombok.extern.slf4j.Slf4j;
  17 +import org.apache.commons.lang3.StringUtils;
15 18 import org.springframework.beans.factory.annotation.Autowired;
16 19  
17 20 import java.math.BigDecimal;
18 21 import java.math.RoundingMode;
19 22 import java.time.LocalDate;
20   -import java.util.ArrayList;
21   -import java.util.List;
22   -import java.util.Objects;
23   -import java.util.Optional;
  23 +import java.util.*;
24 24 import java.util.function.Consumer;
25 25  
26 26 /**
... ... @@ -47,6 +47,20 @@ public abstract class KpiAbsBaseCalculator implements Calculator&lt;KpiGroupUser, K
47 47 @Autowired
48 48 protected KpiGroupIndicatorTargetHitLogService kpiGroupIndicatorTargetHitLogService;
49 49  
  50 + public static void main(String[] args) {
  51 + Set<Long> set = new HashSet<>();
  52 + set.add(1L);
  53 + set.add(2L);
  54 + set.add(3L);
  55 + String json = JSON.toJSONString(set);
  56 + System.out.println(json);
  57 + List<Long> set2 = JSON.parseArray(json, Long.class);
  58 + System.out.println(set2.toString());
  59 + System.out.println(Arrays.toString(set2.toArray()));
  60 + String join = StringUtils.join(",", set);
  61 + System.out.println(join);
  62 + }
  63 +
50 64 /**
51 65 * 获取设置类型
52 66 *
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/eval/EvalCalculateService.java
... ... @@ -413,6 +413,7 @@ public class EvalCalculateService {
413 413  
414 414 public EvalGroupUserShop convertBO(EvalGroupUser user, EvalUserPool userPool) {
415 415 EvalGroupUserShop userShop = new EvalGroupUserShop();
  416 + userShop.setName(user.getUserName());
416 417 userShop.setScopeType(EvalScopeEnum.STAFF);
417 418 userShop.setEvalGroupId(user.getEvalGroupId());
418 419 userShop.setPoolId(userPool.getId());
... ... @@ -426,6 +427,7 @@ public class EvalCalculateService {
426 427  
427 428 public EvalGroupUserShop convertBO(EvalShopPool shopPool, EvalGroup evalGroup, LocalDate dataDate) {
428 429 EvalGroupUserShop userShop = new EvalGroupUserShop();
  430 + userShop.setName(shopPool.getShopName());
429 431 userShop.setReferId(shopPool.getShopId());
430 432 userShop.setPoolId(shopPool.getId());
431 433 userShop.setScopeType(EvalScopeEnum.SHOP);
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/eval/EvalGroupBizService.java
... ... @@ -100,6 +100,7 @@ public class EvalGroupBizService {
100 100 checkReward(evalGroupDTO);
101 101 checkEvalIndicatorLadders(evalGroupDTO.getIndicators());
102 102 checkEvalRewardLadders(evalGroupDTO.getRewards());
  103 + sortRewardRankLadders(evalGroupDTO.getRewards());
103 104 setTargetVos(evalGroupDTO);
104 105 }
105 106 SettingDraft settingDraft = getSettingDraft(dto, isSubmit);
... ... @@ -316,7 +317,7 @@ public class EvalGroupBizService {
316 317 * @param dto
317 318 */
318 319 public void checkTime(EvalGroupDTO dto) {
319   - BV.isTrue(dto.getBeginTime().isBefore(dto.getOverTime()), "考评组【" + dto.getName()+ "】生效时间必须在结束时间之前");
  320 +// BV.isTrue(dto.getBeginTime().isBefore(dto.getOverTime()), "考评组【" + dto.getName()+ "】生效时间必须在结束时间之前");
320 321  
321 322 if (PublicUtil.isNotEmpty(dto.getId())) {
322 323 List<EvalGroup> evalGroups = evalGroupService.list(Wrappers.<EvalGroup>lambdaQuery()
... ... @@ -424,6 +425,39 @@ public class EvalGroupBizService {
424 425 }
425 426  
426 427 /**
  428 + * 检查阶梯分值
  429 + * @param rewards
  430 + */
  431 + private void sortRewardRankLadders(List<EvalGroupRewardDTO> rewards) {
  432 + for (EvalGroupRewardDTO reward : rewards) {
  433 + if (! EvalRewardCalMethodEnum.RANK.equals(reward.getCalMethod())) {
  434 + continue;
  435 + }
  436 +
  437 + List<EvalGroupRewardLaddersDTO> ladders = reward.getLadders();
  438 + Collections.sort(ladders, new Comparator<EvalGroupRewardLaddersDTO>() {
  439 + @Override
  440 + public int compare(EvalGroupRewardLaddersDTO o1, EvalGroupRewardLaddersDTO o2) {
  441 + if (PublicUtil.isEmpty(o1.getRankOrderType())) {
  442 + return -1;
  443 + }
  444 + if (PublicUtil.isEmpty(o2.getRankOrderType())) {
  445 + return 1;
  446 + }
  447 + //正数在前 负数在后
  448 + Integer order = o1.getRankOrderType().compareTo(o2.getRankOrderType());
  449 + if (order == 0) {
  450 + //大的在后
  451 + return o1.getLower().subtract(o2.getLower()).intValue();
  452 + }
  453 + return order;
  454 + }
  455 + });
  456 +
  457 + }
  458 + }
  459 +
  460 + /**
427 461 * 检查考评组指标
428 462 *
429 463 * @param evalGroupDTO
... ... @@ -619,10 +653,10 @@ public class EvalGroupBizService {
619 653 reward.setLadderParams(paramTypeMap.getOrDefault(ParamTypeEnum.LADDER, new ArrayList<>()));
620 654 reward.setConds(rewardCondMap.getOrDefault(rewardId, new ArrayList<>()));
621 655  
622   -
623 656 List<EvalGroupRewardLadders> rewardLadders = evalGroupRewardLaddersService.list(Wrappers.<EvalGroupRewardLadders>lambdaQuery()
624 657 .eq(EvalGroupRewardLadders::getEvalGroupRewardId, rewardId)
625 658 .eq(EvalGroupRewardLadders::getYn, Boolean.TRUE)
  659 + .last("order by rank_order_type ASC, lower ASC")
626 660 );
627 661 List<EvalGroupRewardLaddersVO> rewardLaddersVOS = new ArrayList<>();
628 662 for (EvalGroupRewardLadders rewardLadder : rewardLadders) {
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/eval/EvalGroupPoolService.java
1 1 package cn.fw.morax.service.biz.eval;
2 2  
3 3 import cn.fw.common.exception.BusinessException;
4   -import cn.fw.morax.common.config.FlowVal;
5 4 import cn.fw.morax.common.constant.Constant;
6 5 import cn.fw.morax.common.utils.DateUtil;
7 6 import cn.fw.morax.common.utils.PublicUtil;
... ... @@ -14,12 +13,7 @@ import cn.fw.morax.domain.vo.eval.*;
14 13 import cn.fw.morax.domain.vo.kpi.IndicatorUserValueVO;
15 14 import cn.fw.morax.domain.vo.kpi.KpiIndicatorRankStaffVO;
16 15 import cn.fw.morax.domain.vo.kpi.KpiIndicatorRankVO;
17   -import cn.fw.morax.rpc.approval.FlowApproveRpc;
18   -import cn.fw.morax.service.biz.ApprovalBizService;
19 16 import cn.fw.morax.service.biz.CommonService;
20   -import cn.fw.morax.service.biz.kpi.KpiGroupUserBizService;
21   -import cn.fw.morax.service.data.ApprovalRecordService;
22   -import cn.fw.morax.service.data.SettingDraftService;
23 17 import cn.fw.morax.service.data.eval.*;
24 18 import cn.fw.morax.service.data.kpi.IndicatorUserValueService;
25 19 import com.alibaba.fastjson.JSON;
... ... @@ -60,10 +54,13 @@ public class EvalGroupPoolService {
60 54 private final EvalGroupRewardLaddersService evalGroupRewardLaddersService;
61 55 private final EvalPoolRewardDetailService evalPoolRewardDetailService;
62 56 private final EvalGroupRewardParamService evalGroupRewardParamService;
  57 + private final EvalGroupRewardRankLogService evalGroupRewardRankLogService;
63 58 private final EvalGroupRewardHitLogService evalGroupRewardHitLogService;
64 59 private final IndicatorUserValueService indicatorUserValueService;
65 60 private final EvalIndicatorValueService evalIndicatorValueService;
66 61 private final EvalGroupUserService evalGroupUserService;
  62 + private final EvalGroupRewardService evalGroupRewardService;
  63 + private final EvalGroupService evalGroupService;
67 64 private final EvalUserPoolService evalUserPoolService;
68 65 private final EvalShopPoolService evalShopPoolService;
69 66 private final CommonService commonService;
... ... @@ -656,6 +653,7 @@ public class EvalGroupPoolService {
656 653 List<EvalGroupRewardLadders> rewardLadders = evalGroupRewardLaddersService.list(Wrappers.<EvalGroupRewardLadders>lambdaQuery()
657 654 .eq(EvalGroupRewardLadders::getEvalGroupRewardId, reward.getEvalGroupRewardId())
658 655 .eq(EvalGroupRewardLadders::getYn, Boolean.TRUE)
  656 + .last("order by rank_order_type ASC, lower ASC")
659 657 );
660 658 List<EvalGroupRewardLaddersVO> rewardLaddersVOS = new ArrayList<>();
661 659 for (EvalGroupRewardLadders rewardLadder : rewardLadders) {
... ... @@ -1226,4 +1224,49 @@ public class EvalGroupPoolService {
1226 1224 }
1227 1225 }
1228 1226  
  1227 + public List<EvalGroupRewardRankLogVO> getRewardCondRankLogs(Long preconditionId, LocalDate dataDate) {
  1228 + EvalGroupRewardPrecondition precondition = evalGroupRewardPreconditionService.getById(preconditionId);
  1229 + BV.notNull(precondition, "奖惩条件不存在");
  1230 + BV.isTrue(ConditionTypeEnum.RANK.equals(precondition.getCondType()), "满足排名率条件才能查询排名情况");
  1231 + final DataTypeEnum dataType = precondition.getDataType();
  1232 + final TargetTypeEnum targetType = precondition.getTargetType();
  1233 + List<EvalGroupRewardRankLog> rankLogs = evalGroupRewardRankLogService.list(Wrappers.<EvalGroupRewardRankLog>lambdaQuery()
  1234 + .eq(EvalGroupRewardRankLog::getDataDate, dataDate)
  1235 + .eq(EvalGroupRewardRankLog::getReferId, preconditionId)
  1236 + .eq(EvalGroupRewardRankLog::getTargetType, RankIndicatorTypeEnum.PRE)
  1237 + .eq(EvalGroupRewardRankLog::getYn, Boolean.TRUE)
  1238 + );
  1239 + Collections.sort(rankLogs);
  1240 +
  1241 + List<EvalGroupRewardRankLogVO> rankLogVOs = PublicUtil.copyList(rankLogs, EvalGroupRewardRankLogVO.class);
  1242 + rankLogVOs.stream().forEach(rankLog -> rankLog.convertPercentForCond(dataType, targetType));
  1243 + return rankLogVOs;
  1244 + }
  1245 +
  1246 + public List<EvalGroupRewardRankLogVO> queryRewardCommissionRank(Long evalGroupRewardId, LocalDate dataDate) {
  1247 + EvalGroupReward reward = evalGroupRewardService.getById(evalGroupRewardId);
  1248 + BV.notNull(reward, "奖惩不存在");
  1249 + List<EvalGroupRewardRankLog> rankLogs = evalGroupRewardRankLogService.list(Wrappers.<EvalGroupRewardRankLog>lambdaQuery()
  1250 + .eq(EvalGroupRewardRankLog::getDataDate, dataDate)
  1251 + .eq(EvalGroupRewardRankLog::getReferId, evalGroupRewardId)
  1252 + .eq(EvalGroupRewardRankLog::getTargetType, RankIndicatorTypeEnum.REWARD_COMMISSION)
  1253 + .eq(EvalGroupRewardRankLog::getYn, Boolean.TRUE)
  1254 + );
  1255 + Collections.sort(rankLogs);
  1256 + List<EvalGroupRewardRankLogVO> rankLogVOs = PublicUtil.copyList(rankLogs, EvalGroupRewardRankLogVO.class);
  1257 + return rankLogVOs;
  1258 + }
  1259 +
  1260 + public List<EvalGroupRewardHitLogVO> queryRewardProportion(EvalScopeEnum scopeType, Long evalGroupRewardId, LocalDate dataDate) {
  1261 + EvalGroupReward reward = evalGroupRewardService.getById(evalGroupRewardId);
  1262 + BV.notNull(reward, "奖惩不存在");
  1263 + List<EvalGroupRewardHitLogVO> hitLogVOS = null;
  1264 + if (EvalScopeEnum.STAFF.equals(scopeType)) {
  1265 + hitLogVOS = evalGroupRewardHitLogService.getUserHitLogs(evalGroupRewardId, dataDate);
  1266 + } else {
  1267 + hitLogVOS = evalGroupRewardHitLogService.getShopHitLogs(evalGroupRewardId, dataDate);
  1268 + }
  1269 + hitLogVOS.stream().forEach(hitLog -> hitLog.convertValueToPercent(reward.getLaddersType()));
  1270 + return hitLogVOS;
  1271 + }
1229 1272 }
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/data/eval/EvalGroupRewardHitLogService.java
... ... @@ -3,8 +3,12 @@ package cn.fw.morax.service.data.eval;
3 3  
4 4 import cn.fw.morax.domain.db.eval.EvalGroupReward;
5 5 import cn.fw.morax.domain.db.eval.EvalGroupRewardHitLog;
  6 +import cn.fw.morax.domain.vo.eval.EvalGroupRewardHitLogVO;
6 7 import com.baomidou.mybatisplus.extension.service.IService;
7 8  
  9 +import java.time.LocalDate;
  10 +import java.util.List;
  11 +
8 12 /**
9 13 * <p>
10 14 * 考评奖惩 服务类
... ... @@ -15,4 +19,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
15 19 */
16 20 public interface EvalGroupRewardHitLogService extends IService<EvalGroupRewardHitLog> {
17 21  
  22 + List<EvalGroupRewardHitLogVO> getUserHitLogs(Long evalGroupRewardId, LocalDate dataDate);
  23 +
  24 + List<EvalGroupRewardHitLogVO> getShopHitLogs(Long evalGroupRewardId, LocalDate dataDate);
  25 +
18 26 }
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/data/eval/EvalGroupRewardRankLogService.java 0 → 100644
  1 +package cn.fw.morax.service.data.eval;
  2 +
  3 +
  4 +import cn.fw.morax.domain.db.eval.EvalGroupRewardRankLog;
  5 +import cn.fw.morax.domain.db.eval.EvalGroupRewardTargetHitLog;
  6 +import cn.fw.morax.domain.enums.EvalScopeEnum;
  7 +import cn.fw.morax.domain.enums.IndicatorTypeEnum;
  8 +import cn.fw.morax.domain.vo.eval.EvalGroupRewardTargetHitLogVO;
  9 +import com.baomidou.mybatisplus.extension.service.IService;
  10 +
  11 +import java.time.YearMonth;
  12 +import java.util.List;
  13 +import java.util.Set;
  14 +
  15 +/**
  16 + * <p>
  17 + * 考评奖惩 服务类
  18 + * </p>
  19 + *
  20 + * @author jiangchao
  21 + * @since 2022-12-09
  22 + */
  23 +public interface EvalGroupRewardRankLogService extends IService<EvalGroupRewardRankLog> {
  24 +
  25 +
  26 +}
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/data/eval/impl/EvalGroupRewardHitLogServiceImpl.java
... ... @@ -5,11 +5,15 @@ import cn.fw.morax.dao.eval.EvalGroupRewardHitLogDao;
5 5 import cn.fw.morax.dao.eval.EvalGroupRewardTargetHitLogDao;
6 6 import cn.fw.morax.domain.db.eval.EvalGroupRewardHitLog;
7 7 import cn.fw.morax.domain.db.eval.EvalGroupRewardTargetHitLog;
  8 +import cn.fw.morax.domain.vo.eval.EvalGroupRewardHitLogVO;
8 9 import cn.fw.morax.service.data.eval.EvalGroupRewardHitLogService;
9 10 import cn.fw.morax.service.data.eval.EvalGroupRewardTargetHitLogService;
10 11 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
11 12 import org.springframework.stereotype.Service;
12 13  
  14 +import java.time.LocalDate;
  15 +import java.util.List;
  16 +
13 17 /**
14 18 * <p>
15 19 * 考评指标达成目标记录 服务实现类
... ... @@ -23,4 +27,13 @@ public class EvalGroupRewardHitLogServiceImpl
23 27 extends ServiceImpl<EvalGroupRewardHitLogDao, EvalGroupRewardHitLog>
24 28 implements EvalGroupRewardHitLogService {
25 29  
  30 + @Override
  31 + public List<EvalGroupRewardHitLogVO> getUserHitLogs(Long evalGroupRewardId, LocalDate dataDate) {
  32 + return this.baseMapper.getUserHitLogs(evalGroupRewardId, dataDate);
  33 + }
  34 +
  35 + @Override
  36 + public List<EvalGroupRewardHitLogVO> getShopHitLogs(Long evalGroupRewardId, LocalDate dataDate) {
  37 + return this.baseMapper.getShopHitLogs(evalGroupRewardId, dataDate);
  38 + }
26 39 }
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/data/eval/impl/EvalGroupRewardRankLogServiceImpl.java 0 → 100644
  1 +package cn.fw.morax.service.data.eval.impl;
  2 +
  3 +
  4 +import cn.fw.morax.dao.eval.EvalGroupRewardRankLogDao;
  5 +import cn.fw.morax.dao.eval.EvalGroupRewardTargetHitLogDao;
  6 +import cn.fw.morax.domain.db.eval.EvalGroupRewardRankLog;
  7 +import cn.fw.morax.domain.db.eval.EvalGroupRewardTargetHitLog;
  8 +import cn.fw.morax.domain.enums.EvalScopeEnum;
  9 +import cn.fw.morax.domain.enums.IndicatorTypeEnum;
  10 +import cn.fw.morax.domain.vo.eval.EvalGroupRewardTargetHitLogVO;
  11 +import cn.fw.morax.service.data.eval.EvalGroupRewardRankLogService;
  12 +import cn.fw.morax.service.data.eval.EvalGroupRewardTargetHitLogService;
  13 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  14 +import org.springframework.stereotype.Service;
  15 +
  16 +import java.time.YearMonth;
  17 +import java.util.List;
  18 +import java.util.Set;
  19 +
  20 +/**
  21 + * <p>
  22 + * 考评指标达成目标记录 服务实现类
  23 + * </p>
  24 + *
  25 + * @author jiangchao
  26 + * @since 2022-12-09
  27 + */
  28 +@Service
  29 +public class EvalGroupRewardRankLogServiceImpl
  30 + extends ServiceImpl<EvalGroupRewardRankLogDao, EvalGroupRewardRankLog>
  31 + implements EvalGroupRewardRankLogService {
  32 +
  33 +}
... ...