xiaoyong931011
2023-04-03 d5a96c3122c136d4b0c585d08e61b42e8a123743
按照商品的来设置补贴额度的系数
16 files added
24 files modified
1814 ■■■■■ changed files
src/main/java/cc/mrbird/febs/common/enumerates/FlowTypeEnum.java 6 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/enumerates/GreenScoreEnum.java 59 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/enumerates/MoneyFlowTypeEnum.java 27 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/AdminMallMemberController.java 60 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java 52 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/ViewMallMemberController.java 65 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java 77 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/dto/AdminRoleReleaseDto.java 11 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/dto/HlmVoucherSetDto.java 46 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/entity/MallMember.java 20 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/entity/MallMemberWallet.java 10 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/entity/MallMoneyFlow.java 7 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/entity/MallScoreAchieveRelease.java 31 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/entity/MallScoreRecord.java 39 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/mapper/MallAchieveRecordMapper.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/mapper/MallMemberMapper.java 8 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/mapper/MallMemberWalletMapper.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/mapper/MallScoreAchieveReleaseMapper.java 16 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/mapper/MallScoreRecordMapper.java 23 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java 19 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/IAdminMallMemberService.java 21 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java 4 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallMemberServiceImpl.java 89 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java 10 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java 301 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/MallAchieveRecordMapper.xml 7 ●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/MallMemberMapper.xml 14 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/MallMemberWalletMapper.xml 17 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/MallScoreAchieveReleaseMapper.xml 24 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/MallScoreRecordMapper.xml 44 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/mallMember/mallMemberList.html 60 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/mallMember/scoreAchieveRelease.html 107 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/mallMember/scoreAchieveReleaseList.html 55 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/mallMember/scoreRoleRelease.html 123 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/mallMember/scoreRoleReleaseList.html 39 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/mallMember/voucherUpdate.html 91 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/system/hlmVoucherButton.html 74 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/system/hlmVoucherSet.html 142 ●●●●● patch | view | raw | blame | history
src/test/java/cc/mrbird/febs/AgentTest.java 2 ●●● patch | view | raw | blame | history
src/test/java/cc/mrbird/febs/ProfitTest.java 6 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/enumerates/FlowTypeEnum.java
@@ -33,7 +33,11 @@
    /**
     * 补贴额度
     */
    TOTAL_SCORE(6);
    TOTAL_SCORE(6),
    /**
     * 凭证数量
     */
    VOUCHER_CNT(7);
    private final int value;
src/main/java/cc/mrbird/febs/common/enumerates/GreenScoreEnum.java
New file
@@ -0,0 +1,59 @@
package cc.mrbird.febs.common.enumerates;
import lombok.Getter;
/**
 * 绿色积分
 */
@Getter
public enum GreenScoreEnum {
    /**
     * 绿色凭证价格
     */
    SCORE_PRICE("GREEN_SCORE", "SCORE_PRICE"),
    /**
     * 业绩产生凭证给星级的比例
     */
    LEVEL_ACHIEVE_PERCENT("GREEN_SCORE", "LEVEL_ACHIEVE_PERCENT"),
    /**
     * 业绩产生凭证给贡献点的比例
     */
    STAR_ACHIEVE_PERCENT("GREEN_SCORE", "STAR_ACHIEVE_PERCENT"),
    /**
     * 业绩产生凭证给创世的比例
     */
    ROLE_ACHIEVE_PERCENT("GREEN_SCORE", "ROLE_ACHIEVE_PERCENT"),
    /**
     * 业绩的最小值
     */
    ACHIEVE_MIN("GREEN_SCORE", "ACHIEVE_MIN"),
    /**
     * 业绩的最大值
     */
    ACHIEVE_MAX("GREEN_SCORE", "ACHIEVE_MAX"),
    /**
     * 产生业绩的释放积分比例(万分之几)
     */
    ACHIEVE_RELEASE_PERCENT("GREEN_SCORE", "ACHIEVE_RELEASE_PERCENT"),
    /**
     * 创始角色的每日释放积分比例(千分之几)
     */
    ROLE_RELEASE_PERCENT("GREEN_SCORE", "ROLE_RELEASE_PERCENT"),
    /**
     * 绿色积分剩余数量
     */
    SURPLUS_CNT("GREEN_SCORE", "SURPLUS_CNT"),
    /**
     * 绿色积分总数
     */
    TOTAL_CNT("GREEN_SCORE", "TOTAL_CNT");
    private String type;
    private String code;
    GreenScoreEnum(String type, String code) {
        this.type = type;
        this.code = code;
    }
}
src/main/java/cc/mrbird/febs/common/enumerates/MoneyFlowTypeEnum.java
@@ -153,7 +153,32 @@
    /**
     * 代理商补贴
     */
    AGENT_PERK(30);
    AGENT_PERK(30),
    /**
     * 联创合伙人释放凭证
     */
    ROLE_RELEASE_SCORE(31),
    /**
     * 业绩释放联创凭证
     */
    ACHIEVE_RELEASE_SCORE_LC(32),
    /**
     * 业绩释放合伙人凭证
     */
    ACHIEVE_RELEASE_SCORE_HHR(33),
    /**
     * 业绩释放贡献点凭证
     */
    ACHIEVE_RELEASE_SCORE_GXD(34),
    /**
     * 业绩释放星级凭证
     */
    ACHIEVE_RELEASE_SCORE_XJ(35);
    private final int value;
src/main/java/cc/mrbird/febs/mall/controller/AdminMallMemberController.java
@@ -117,6 +117,16 @@
    }
    /**
     * 会员列表-系统拨付绿色凭证
     */
    @PostMapping("updateVoucher")
    @ControllerEndpoint(operation = "会员列表-系统拨付绿色凭证", exceptionMessage = "操作失败")
    public FebsResponse updateVoucher(@Valid MallSystemPayDto mallSystemPayDto) {
//        return mallMemberService.updateSystemPay(mallSystemPayDto);
        return mallMemberService.updateVoucher(mallSystemPayDto);
    }
    /**
     * 会员列表-详情更新
     */
    @PostMapping("updateMemberInfo")
@@ -374,4 +384,54 @@
        return new FebsResponse().success();
    }
    /**
     * 创世释放记录-列表
     * @param roleReleaseDto
     * @param request
     * @return
     */
    @GetMapping("gerRoleRelease")
    public FebsResponse gerRoleRelease(AdminRoleReleaseDto roleReleaseDto, QueryRequest request) {
        Map<String, Object> data = getDataTable(mallMemberService.gerRoleReleaseList(roleReleaseDto, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * 创世释放记录-全部记录
     */
    @GetMapping("/roleReleaseChild")
    public FebsResponse roleReleaseChild(QueryRequest request, MallScoreRecord mallScoreRecord, Integer parentId) {
        if (parentId == null) {
            ViewMallMemberController.idFromScoreRoleRelease = 0;
        }
        mallScoreRecord.setId(ViewMallMemberController.idFromScoreRoleRelease);
        Map<String, Object> dataTable = getDataTable(mallMemberService.roleReleaseChild(request, mallScoreRecord));
        return new FebsResponse().success().data(dataTable);
    }
    /**
     * 业绩释放记录-列表
     * @param roleReleaseDto
     * @param request
     * @return
     */
    @GetMapping("gerAchieveRelease")
    public FebsResponse gerAchieveRelease(AdminRoleReleaseDto roleReleaseDto, QueryRequest request) {
        Map<String, Object> data = getDataTable(mallMemberService.gerAchieveReleaseList(roleReleaseDto, request));
        return new FebsResponse().success().data(data);
    }
    /**
     * 业绩释放记录-全部记录
     */
    @GetMapping("/achieveReleaseChild")
    public FebsResponse achieveReleaseChild(QueryRequest request, MallScoreAchieveRelease mallScoreAchieveRelease, Integer parentId) {
        if (parentId == null) {
            ViewMallMemberController.idFromScoreAchieveRelease = 0;
        }
        mallScoreAchieveRelease.setId(ViewMallMemberController.idFromScoreAchieveRelease);
        Map<String, Object> dataTable = getDataTable(mallMemberService.achieveReleaseChild(request, mallScoreAchieveRelease));
        return new FebsResponse().success().data(dataTable);
    }
}
src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java
@@ -2,10 +2,8 @@
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.enumerates.DataDictionaryEnum;
import cc.mrbird.febs.mall.dto.CashOutSettingDto;
import cc.mrbird.febs.mall.dto.HlmBasicPerkDto;
import cc.mrbird.febs.mall.dto.HlmScoreSetDto;
import cc.mrbird.febs.mall.dto.ScorePoorDto;
import cc.mrbird.febs.common.enumerates.GreenScoreEnum;
import cc.mrbird.febs.mall.dto.*;
import cc.mrbird.febs.mall.service.ICommonService;
import cc.mrbird.febs.mall.service.ISystemService;
import lombok.RequiredArgsConstructor;
@@ -17,6 +15,7 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.Map;
@Slf4j
@@ -102,4 +101,49 @@
                hlmBasicPerkDto.getAgentPerk());
        return new FebsResponse().success();
    }
    @PostMapping(value = "/hlmVoucherSet")
    public FebsResponse hlmVoucherSet(HlmVoucherSetDto hlmVoucherSetDto) {
        BigDecimal roleReleasePercent = new BigDecimal(hlmVoucherSetDto.getRoleReleasePercent());
        if(roleReleasePercent.compareTo(BigDecimal.ZERO) <= 0
        || roleReleasePercent.compareTo(new BigDecimal(1000)) >= 0){
            return new FebsResponse().fail().message("请输入合理的比例");
        }
        commonService.updateDataDic(
                GreenScoreEnum.ROLE_RELEASE_PERCENT.getType(),
                GreenScoreEnum.ROLE_RELEASE_PERCENT.getCode(),
                hlmVoucherSetDto.getRoleReleasePercent());
        commonService.updateDataDic(
                GreenScoreEnum.ACHIEVE_RELEASE_PERCENT.getType(),
                GreenScoreEnum.ACHIEVE_RELEASE_PERCENT.getCode(),
                hlmVoucherSetDto.getAchieveReleasePercent());
        commonService.updateDataDic(
                GreenScoreEnum.ACHIEVE_MAX.getType(),
                GreenScoreEnum.ACHIEVE_MAX.getCode(),
                hlmVoucherSetDto.getAchieveMax());
        commonService.updateDataDic(
                GreenScoreEnum.ACHIEVE_MIN.getType(),
                GreenScoreEnum.ACHIEVE_MIN.getCode(),
                hlmVoucherSetDto.getAchieveMin());
        commonService.updateDataDic(
                GreenScoreEnum.ROLE_ACHIEVE_PERCENT.getType(),
                GreenScoreEnum.ROLE_ACHIEVE_PERCENT.getCode(),
                hlmVoucherSetDto.getRoleAchievePercent());
        commonService.updateDataDic(
                GreenScoreEnum.STAR_ACHIEVE_PERCENT.getType(),
                GreenScoreEnum.STAR_ACHIEVE_PERCENT.getCode(),
                hlmVoucherSetDto.getStarAchievePercent());
        commonService.updateDataDic(
                GreenScoreEnum.LEVEL_ACHIEVE_PERCENT.getType(),
                GreenScoreEnum.LEVEL_ACHIEVE_PERCENT.getCode(),
                hlmVoucherSetDto.getLevelAchievePercent());
        return new FebsResponse().success();
    }
}
src/main/java/cc/mrbird/febs/mall/controller/ViewMallMemberController.java
@@ -28,6 +28,10 @@
    public static long idFromAgentAllMember;
    public static long idFromScoreRoleRelease;
    public static long idFromScoreAchieveRelease;
    /**
     * 平台账单
     * @return
@@ -85,6 +89,21 @@
        model.addAttribute("systemPay", data);
        model.addAttribute("type", type);
        return FebsUtil.view("modules/mallMember/mallSystemPay");
    }
    /**
     * 会员列表-系统拨付绿色凭证
     * @param id
     * @param model
     * @return
     */
    @GetMapping("voucherUpdate/{type}/{id}")
    @RequiresPermissions("voucherUpdate:update")
    public String voucherUpdate(@PathVariable long id, @PathVariable Integer type, Model model) {
        MallMemberVo data = mallMemberService.getMallMemberInfoById(id);
        model.addAttribute("systemPay", data);
        model.addAttribute("type", type);
        return FebsUtil.view("modules/mallMember/voucherUpdate");
    }
    /**
@@ -304,6 +323,52 @@
    }
    /**
     * 创世释放记录-列表
     * @return
     */
    @GetMapping("scoreRoleRelease")
    @RequiresPermissions("scoreRoleRelease:view")
    public String scoreRoleRelease() {
        return FebsUtil.view("modules/mallMember/scoreRoleRelease");
    }
    /**
     * 创世释放记录-全部记录
     * @param id
     * @param model
     * @return
     */
    @GetMapping("scoreRoleReleaseList/{id}")
    public String scoreRoleReleaseList(@PathVariable long id, Model model) {
        idFromScoreRoleRelease = id;
        return FebsUtil.view("modules/mallMember/scoreRoleReleaseList");
    }
    /**
     * 业绩释放记录-列表
     * @return
     */
    @GetMapping("scoreAchieveRelease")
    @RequiresPermissions("scoreAchieveRelease:view")
    public String scoreAchieveRelease() {
        return FebsUtil.view("modules/mallMember/scoreAchieveRelease");
    }
    /**
     * 业绩释放记录-全部记录
     * @param id
     * @param model
     * @return
     */
    @GetMapping("scoreAchieveReleaseList/{id}")
    public String scoreAchieveReleaseList(@PathVariable long id, Model model) {
        idFromScoreAchieveRelease = id;
        return FebsUtil.view("modules/mallMember/scoreAchieveReleaseList");
    }
}
src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java
@@ -3,6 +3,7 @@
import cc.mrbird.febs.common.entity.FebsConstant;
import cc.mrbird.febs.common.enumerates.AgentLevelEnum;
import cc.mrbird.febs.common.enumerates.DataDictionaryEnum;
import cc.mrbird.febs.common.enumerates.GreenScoreEnum;
import cc.mrbird.febs.common.enumerates.OrderPayMethodEnum;
import cc.mrbird.febs.common.service.ValidateCodeService;
import cc.mrbird.febs.common.utils.FebsUtil;
@@ -217,4 +218,80 @@
        model.addAttribute("hlmBasicPerk", hlmBasicPerkDto);
        return FebsUtil.view("modules/system/hlmBasicPerk");
    }
    /**
     * 积分凭证设置
     * @param model
     * @return
     */
    @GetMapping("hlmVoucherSet")
    @RequiresPermissions("hlmVoucherSet:view")
    public String hlmVoucherSet(Model model) {
        HlmVoucherSetDto hlmVoucherSetDto = new HlmVoucherSetDto();
        DataDictionaryCustom totalCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.TOTAL_CNT.getType(),
                GreenScoreEnum.TOTAL_CNT.getCode());
        if (totalCntDic != null) {
            String totalCnt = ObjectUtil.isEmpty(totalCntDic.getValue()) ? "0" : totalCntDic.getValue();
            hlmVoucherSetDto.setTotalCnt(totalCnt);
        }
        DataDictionaryCustom surplusCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.SURPLUS_CNT.getType(),
                GreenScoreEnum.SURPLUS_CNT.getCode());
        if (surplusCntDic != null) {
            String surplusCnt = ObjectUtil.isEmpty(surplusCntDic.getValue()) ? "0" : surplusCntDic.getValue();
            hlmVoucherSetDto.setSurplusCnt(surplusCnt);
        }
        DataDictionaryCustom roleReleasePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ROLE_RELEASE_PERCENT.getType(),
                GreenScoreEnum.ROLE_RELEASE_PERCENT.getCode());
        if (roleReleasePercentDic != null) {
            String roleReleasePercent = ObjectUtil.isEmpty(roleReleasePercentDic.getValue()) ? "0" : roleReleasePercentDic.getValue();
            hlmVoucherSetDto.setRoleReleasePercent(roleReleasePercent);
        }
        DataDictionaryCustom achieveReleasePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ACHIEVE_RELEASE_PERCENT.getType(),
                GreenScoreEnum.ACHIEVE_RELEASE_PERCENT.getCode());
        if (achieveReleasePercentDic != null) {
            String achieveReleasePercent = ObjectUtil.isEmpty(achieveReleasePercentDic.getValue()) ? "0" : achieveReleasePercentDic.getValue();
            hlmVoucherSetDto.setAchieveReleasePercent(achieveReleasePercent);
        }
        DataDictionaryCustom achieveMaxDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ACHIEVE_MAX.getType(),
                GreenScoreEnum.ACHIEVE_MAX.getCode());
        if (achieveMaxDic != null) {
            String achieveMax = ObjectUtil.isEmpty(achieveMaxDic.getValue()) ? "0" : achieveMaxDic.getValue();
            hlmVoucherSetDto.setAchieveMax(achieveMax);
        }
        DataDictionaryCustom achieveMinDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ACHIEVE_MIN.getType(),
                GreenScoreEnum.ACHIEVE_MIN.getCode());
        if (achieveMinDic != null) {
            String achieveMin = ObjectUtil.isEmpty(achieveMinDic.getValue()) ? "0" : achieveMinDic.getValue();
            hlmVoucherSetDto.setAchieveMin(achieveMin);
        }
        DataDictionaryCustom roleAchievePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ROLE_ACHIEVE_PERCENT.getType(),
                GreenScoreEnum.ROLE_ACHIEVE_PERCENT.getCode());
        if (roleAchievePercentDic != null) {
            String roleAchievePercent = ObjectUtil.isEmpty(roleAchievePercentDic.getValue()) ? "0" : roleAchievePercentDic.getValue();
            hlmVoucherSetDto.setRoleAchievePercent(roleAchievePercent);
        }
        DataDictionaryCustom starAchievePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.STAR_ACHIEVE_PERCENT.getType(),
                GreenScoreEnum.STAR_ACHIEVE_PERCENT.getCode());
        if (starAchievePercentDic != null) {
            String starAchievePercent = ObjectUtil.isEmpty(starAchievePercentDic.getValue()) ? "0" : starAchievePercentDic.getValue();
            hlmVoucherSetDto.setStarAchievePercent(starAchievePercent);
        }
        DataDictionaryCustom levelAchievePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.LEVEL_ACHIEVE_PERCENT.getType(),
                GreenScoreEnum.LEVEL_ACHIEVE_PERCENT.getCode());
        if (levelAchievePercentDic != null) {
            String levelAchievePercent = ObjectUtil.isEmpty(levelAchievePercentDic.getValue()) ? "0" : levelAchievePercentDic.getValue();
            hlmVoucherSetDto.setLevelAchievePercent(levelAchievePercent);
        }
        model.addAttribute("hlmVoucherSetDto", hlmVoucherSetDto);
        return FebsUtil.view("modules/system/hlmVoucherSet");
    }
}
src/main/java/cc/mrbird/febs/mall/dto/AdminRoleReleaseDto.java
New file
@@ -0,0 +1,11 @@
package cc.mrbird.febs.mall.dto;
import lombok.Data;
@Data
public class AdminRoleReleaseDto {
    private String name;
    private String account;
}
src/main/java/cc/mrbird/febs/mall/dto/HlmVoucherSetDto.java
New file
@@ -0,0 +1,46 @@
package cc.mrbird.febs.mall.dto;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@Data
@ApiModel(value = "HlmVoucherSetDto", description = "绿色凭证设置")
public class HlmVoucherSetDto {
    /**
     * 绿色积分总数
     */
    private String totalCnt;
    /**
     * 绿色积分剩余数量
     */
    private String surplusCnt;
    /**
     * 创始角色的每日释放积分比例(千分之几)
     */
    private String roleReleasePercent;
    /**
     * 业绩最大值
     */
    private String achieveMax;
    /**
     * 业绩最小值
     */
    private String achieveMin;
    /**
     * 每日总释放积分凭证比例(万分之几)
     */
    private String achieveReleasePercent;
    /**
     * 业绩积分凭证每日释放联创、合伙人的比例
     */
    private String roleAchievePercent;
    /**
     * 业绩积分凭证按贡献点比例
     */
    private String starAchievePercent;
    /**
     * 业绩积分凭证按用户星级比例
     */
    private String levelAchievePercent;
}
src/main/java/cc/mrbird/febs/mall/entity/MallMember.java
@@ -138,4 +138,24 @@
     */
    private Integer storeMaster;
    /**
     * 联创  1-是 2-否
     */
    private Integer creater;
    /**
     * 合伙人 1-是 2-否
     */
    private Integer partner;
    /**
     * 绿色凭证
     */
    @TableField(exist = false)
    private BigDecimal voucherCnt;
    /**
     * 凭证现金
     */
    @TableField(exist = false)
    private BigDecimal voucherAmount;
}
src/main/java/cc/mrbird/febs/mall/entity/MallMemberWallet.java
@@ -48,4 +48,14 @@
     * 贡献点
     */
    private Integer star;
    /**
     * 凭证数量
     */
    private BigDecimal voucherCnt;
    /**
     * 凭证金额
     */
    private BigDecimal voucherAmount;
}
src/main/java/cc/mrbird/febs/mall/entity/MallMoneyFlow.java
@@ -1,6 +1,7 @@
package cc.mrbird.febs.mall.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@@ -46,4 +47,10 @@
     * 流水类型 1-余额 2-赠送积分 3-竞猜积分 4-佣金
     */
    private Integer flowType;
    @TableField(exist = false)
    private String name;
    @TableField(exist = false)
    private String phone;
}
src/main/java/cc/mrbird/febs/mall/entity/MallScoreAchieveRelease.java
New file
@@ -0,0 +1,31 @@
package cc.mrbird.febs.mall.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
/**
 * 业绩释放凭证记录
 */
@Data
@TableName("mall_score_achieve_release")
public class MallScoreAchieveRelease extends BaseEntity {
    /**
     * 编号
     */
    private String releaseNo;
    /**
     * 业绩总数
     */
    private BigDecimal achieve;
    /**
     * 预期产生凭证数量
     */
    private BigDecimal voucherExpect;
    /**
     * 实际产生凭证数量
     */
    private BigDecimal voucherReal;
}
src/main/java/cc/mrbird/febs/mall/entity/MallScoreRecord.java
New file
@@ -0,0 +1,39 @@
package cc.mrbird.febs.mall.entity;
import cc.mrbird.febs.common.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
/**
 * 会员购买绿色凭证(绿色积分)
 */
@Data
@TableName("mall_score_record")
public class MallScoreRecord extends BaseEntity {
    private Long memberId;
    /**
     * 编号
     */
    private String scoreNo;
    /**
     * 积分数量
     */
    private BigDecimal scoreCnt;
    /**
     * 剩余数量
     */
    private BigDecimal surplusCnt;
    @TableField(exist = false)
    private String name;
    @TableField(exist = false)
    private String phone;
    @TableField(exist = false)
    private String inviteId;
}
src/main/java/cc/mrbird/febs/mall/mapper/MallAchieveRecordMapper.java
@@ -18,4 +18,6 @@
    BigDecimal selectAchieveTotal(@Param("type") String type, @Param("date") Date date);
    BigDecimal selectSumAchieveByMemberIds(@Param("list")List<Long> mallMembersOffLinePerkIds, @Param("date") Date date);
    List<MallAchieveRecord> selectListByDate(@Param("date")Date profitDate);
}
src/main/java/cc/mrbird/febs/mall/mapper/MallMemberMapper.java
@@ -93,4 +93,12 @@
    List<MallMember> selectMemberByDirector(@Param("state")Integer state);
    List<MallMember> selectMemberByStoreMaster(@Param("state")Integer state);
    /**
     * 根据type查询对应的角色的集合
     * @param type 3:联创 4:合伙人
     * @param state 1:是 2:否
     * @return
     */
    List<MallMember> selectByRole(@Param("type") int type, @Param("state")int state);
}
src/main/java/cc/mrbird/febs/mall/mapper/MallMemberWalletMapper.java
@@ -41,4 +41,10 @@
    void addStarByMemberId(@Param("star")Integer starSum,  @Param("memberId")Long memberId);
    void reduceStarByMemberId(@Param("star")int i, @Param("memberId")Long memberId);
    void addVorCherCntByMemberId(@Param("voucherCnt")BigDecimal voucherCnt, @Param("memberId")Long memberId);
    BigDecimal selectSumStar();
    List<MallMemberWallet> selectStar();
}
src/main/java/cc/mrbird/febs/mall/mapper/MallScoreAchieveReleaseMapper.java
New file
@@ -0,0 +1,16 @@
package cc.mrbird.febs.mall.mapper;
import cc.mrbird.febs.mall.dto.AdminRoleReleaseDto;
import cc.mrbird.febs.mall.entity.MallMoneyFlow;
import cc.mrbird.febs.mall.entity.MallScoreAchieveRelease;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
public interface MallScoreAchieveReleaseMapper extends BaseMapper<MallScoreAchieveRelease> {
    IPage<MallScoreAchieveRelease> gerAchieveReleaseListInPage(Page<MallScoreAchieveRelease> page, @Param("record")AdminRoleReleaseDto roleReleaseDto);
    IPage<MallMoneyFlow> gerAchieveReleaseChildInPage(Page<MallMoneyFlow> page, @Param("record")MallScoreAchieveRelease mallScoreAchieve);
}
src/main/java/cc/mrbird/febs/mall/mapper/MallScoreRecordMapper.java
New file
@@ -0,0 +1,23 @@
package cc.mrbird.febs.mall.mapper;
import cc.mrbird.febs.mall.dto.AdminRoleReleaseDto;
import cc.mrbird.febs.mall.entity.MallMoneyFlow;
import cc.mrbird.febs.mall.entity.MallScoreRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List;
public interface MallScoreRecordMapper extends BaseMapper<MallScoreRecord> {
    BigDecimal selectSumScoreCnt();
    List<MallScoreRecord> selectList();
    IPage<MallScoreRecord> gerRoleReleaseListInPage(Page<MallScoreRecord> page, @Param("record")AdminRoleReleaseDto roleReleaseDto);
    IPage<MallMoneyFlow> gerRoleReleaseChildInPage(Page<MallMoneyFlow> page, @Param("record")MallScoreRecord mallScoreRecord);
}
src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java
@@ -59,7 +59,7 @@
//    }
    /**
     * 代理商补贴
     * 代理商补贴 TODO 需要去掉注释
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void agentPerkJob() {
@@ -90,6 +90,23 @@
    public void mqPerkRetryJob() {
        memberProfitService.mqPerkRetryJob();
    }
    /**
     * 联创、合伙人的每日绿色凭证释放
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void scoreRecordReleaseJob() {
        memberProfitService.scoreRecordReleaseJob();
    }
    /**
     * 业绩产生凭证
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void achieveReleaseJob() {
        memberProfitService.achieveReleaseJob();
    }
    /**
src/main/java/cc/mrbird/febs/mall/service/IAdminMallMemberService.java
@@ -3,10 +3,7 @@
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.mall.dto.*;
import cc.mrbird.febs.mall.entity.AppVersion;
import cc.mrbird.febs.mall.entity.MallMember;
import cc.mrbird.febs.mall.entity.MallNewsInfo;
import cc.mrbird.febs.mall.entity.MallShopApply;
import cc.mrbird.febs.mall.entity.*;
import cc.mrbird.febs.mall.vo.*;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
@@ -97,4 +94,20 @@
    void updateShopApply(MallShopApply apply);
    AdminMallMemberPaymentVo getMallBankInfoById(long id);
    FebsResponse updateVoucher(MallSystemPayDto mallSystemPayDto);
    /**
     * 后台查询会员购买绿色凭证(绿色积分)
     * @param roleReleaseDto
     * @param request
     * @return
     */
    IPage<MallScoreRecord> gerRoleReleaseList(AdminRoleReleaseDto roleReleaseDto, QueryRequest request);
    IPage<MallMoneyFlow> roleReleaseChild(QueryRequest request, MallScoreRecord mallScoreRecord);
    IPage<MallScoreAchieveRelease> gerAchieveReleaseList(AdminRoleReleaseDto roleReleaseDto, QueryRequest request);
    IPage<MallMoneyFlow> achieveReleaseChild(QueryRequest request, MallScoreAchieveRelease mallScoreAchieveRelease);
}
src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java
@@ -49,4 +49,8 @@
    void teamEqualsPerkJob(Date profitDate);
    void mqPerkRetryJob();
    void scoreRecordReleaseJob();
    void achieveReleaseJob();
}
src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallMemberServiceImpl.java
@@ -4,6 +4,7 @@
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.common.enumerates.AgentLevelEnum;
import cc.mrbird.febs.common.enumerates.FlowTypeEnum;
import cc.mrbird.febs.common.enumerates.GreenScoreEnum;
import cc.mrbird.febs.common.enumerates.MoneyFlowTypeEnum;
import cc.mrbird.febs.common.exception.FebsException;
import cc.mrbird.febs.common.utils.LoginUserUtil;
@@ -69,6 +70,8 @@
    private final IMallMoneyFlowService mallMoneyFlowService;
    private final UnipayService unipayService;
    private final MallMemberBankMapper mallMemberBankMapper;
    private final MallScoreRecordMapper mallScoreRecordMapper;
    private final MallScoreAchieveReleaseMapper mallScoreAchieveReleaseMapper;
    @Override
    public IPage<MallMember> getMallMemberList(MallMember mallMember, QueryRequest request) {
@@ -121,6 +124,10 @@
//                throw new FebsException("团队存在线下服务中心,账号为【"+phoneList.toString()+"】");
//            }
            mallMember.setStoreMaster(value);
        }else if (type == 3){
            mallMember.setCreater(value);
        } else if (type == 4){
            mallMember.setPartner(value);
        } else {
            throw new FebsException("参数错误");
        }
@@ -629,6 +636,88 @@
        return adminMallMemberPaymentVo;
    }
    @Override
    public FebsResponse updateVoucher(MallSystemPayDto mallSystemPayDto) {
        Long memberId = mallSystemPayDto.getId();
        MallMember mallMember = mallMemberMapper.selectById(memberId);
        if(ObjectUtil.isEmpty(mallMember)){
            return new FebsResponse().fail().message("系统繁忙,请刷新页面重试");
        }
        BigDecimal addBalance = mallSystemPayDto.getAddBalance();
        if(addBalance.compareTo(BigDecimal.ZERO) <= 0){
            return new FebsResponse().fail().message("请输入正确的数量");
        }
        DataDictionaryCustom totalCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.TOTAL_CNT.getType(),
                GreenScoreEnum.TOTAL_CNT.getCode()
        );
        BigDecimal totalCnt = new BigDecimal(totalCntDic.getValue());
        //凭证占总数的10%
        BigDecimal roleCnt = totalCnt.multiply(new BigDecimal(0.1));
        //获取已卖出的凭证数量
        BigDecimal roleCntSale = mallScoreRecordMapper.selectSumScoreCnt().setScale(2,BigDecimal.ROUND_DOWN);
        roleCntSale = roleCntSale.add(addBalance);
        if(roleCnt.compareTo(roleCntSale) < 0){
            return new FebsResponse().fail().message("已拨付:"+roleCntSale);
        }
        /**
         * 增加一条会员购买记录
         * mall_score_record
         */
        MallScoreRecord mallScoreRecord = new MallScoreRecord();
        mallScoreRecord.setMemberId(memberId);
        mallScoreRecord.setScoreNo(MallUtils.getOrderNum("MSR"));
        mallScoreRecord.setScoreCnt(addBalance);
        mallScoreRecord.setSurplusCnt(addBalance);
        mallScoreRecordMapper.insert(mallScoreRecord);
        /**
         * 减少剩余绿色凭证数量
         */
        DataDictionaryCustom surplusCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.SURPLUS_CNT.getType(),
                GreenScoreEnum.SURPLUS_CNT.getCode()
        );
        BigDecimal surplusCnt = new BigDecimal(surplusCntDic.getValue());
        surplusCnt = surplusCnt.subtract(addBalance);
        surplusCntDic.setValue(surplusCnt.toString());
        dataDictionaryCustomMapper.updateById(surplusCntDic);
        return new FebsResponse().success();
    }
    @Override
    public IPage<MallScoreRecord> gerRoleReleaseList(AdminRoleReleaseDto roleReleaseDto, QueryRequest request) {
        Page<MallScoreRecord> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<MallScoreRecord> mallScoreRecordIPage = mallScoreRecordMapper.gerRoleReleaseListInPage(page, roleReleaseDto);
        return mallScoreRecordIPage;
    }
    @Override
    public IPage<MallMoneyFlow> roleReleaseChild(QueryRequest request, MallScoreRecord mallScoreRecord) {
        Page<MallMoneyFlow> page = new Page<>(request.getPageNum(), request.getPageSize());
        MallScoreRecord mallScore = mallScoreRecordMapper.selectById(mallScoreRecord.getId());
        IPage<MallMoneyFlow> mallMoneyFlowIPage = mallScoreRecordMapper.gerRoleReleaseChildInPage(page, mallScore);
        return mallMoneyFlowIPage;
    }
    @Override
    public IPage<MallScoreAchieveRelease> gerAchieveReleaseList(AdminRoleReleaseDto roleReleaseDto, QueryRequest request) {
        Page<MallScoreAchieveRelease> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<MallScoreAchieveRelease> MallScoreAchieveReleases = mallScoreAchieveReleaseMapper.gerAchieveReleaseListInPage(page, roleReleaseDto);
        return MallScoreAchieveReleases;
    }
    @Override
    public IPage<MallMoneyFlow> achieveReleaseChild(QueryRequest request, MallScoreAchieveRelease mallScoreAchieveRelease) {
        Page<MallMoneyFlow> page = new Page<>(request.getPageNum(), request.getPageSize());
        MallScoreAchieveRelease mallScoreAchieve = mallScoreAchieveReleaseMapper.selectById(mallScoreAchieveRelease.getId());
        IPage<MallMoneyFlow> mallMoneyFlowIPage = mallScoreAchieveReleaseMapper.gerAchieveReleaseChildInPage(page, mallScoreAchieve);
        return mallMoneyFlowIPage;
    }
    private String refererIds(String parentId) {
        boolean flag = false;
        if (StrUtil.isBlank(parentId)) {
src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java
@@ -448,6 +448,7 @@
         * 所有合伙人补贴至消费礼包的三倍额度需要复购一次。
         */
        BigDecimal scoreSum = BigDecimal.ZERO;
        BigDecimal achieveSum = BigDecimal.ZERO;
        List<MallOrderItem> orderItems = this.baseMapper.getMallOrderItemByOrderId(orderInfo.getId());
        if (CollUtil.isNotEmpty(orderItems)) {
            for (MallOrderItem orderItem : orderItems) {
@@ -488,6 +489,11 @@
                            new BigDecimal(mallGoods.getPresentPrice())
                                    .multiply(new BigDecimal(orderItem.getCnt()))
                                    .multiply(basePercent)
                                    .abs()
                                    .setScale(2,BigDecimal.ROUND_DOWN));
                    achieveSum = achieveSum.add(
                            new BigDecimal(mallGoods.getPresentPrice())
                                    .multiply(new BigDecimal(orderItem.getCnt()))
                                    .abs()
                                    .setScale(2,BigDecimal.ROUND_DOWN));
                }
@@ -608,14 +614,16 @@
        /**
         * 产生一条业绩记录
         */
        if(achieveSum.compareTo(BigDecimal.ZERO) > 0){
        MallAchieveRecord mallAchieveRecord = new MallAchieveRecord();
        mallAchieveRecord.setMemberId(memberId);
        mallAchieveRecord.setAchieveTime(new Date());
        mallAchieveRecord.setAmount(orderInfo.getAmount().subtract(orderInfo.getScoreAmount()));
            mallAchieveRecord.setAmount(achieveSum.subtract(orderInfo.getScoreAmount()));
        mallAchieveRecord.setOrderId(orderId);
        mallAchieveRecord.setPayTime(orderInfo.getPayTime());
        mallAchieveRecordMapper.insert(mallAchieveRecord);
    }
    }
    public static void main(String[] args) {
        String str = "{\"biz_code\":\"JS000000\",\"biz_msg\":\"成功\",\"data\":\"{\\\"order_status\\\":\\\"P2000\\\",\\\"jp_order_no\\\":\\\"100120220826446740396081496064\\\",\\\"err_msg\\\":\\\"短信验证码不符\\\",\\\"err_code\\\":\\\"CP110026\\\",\\\"sign_no\\\":\\\"\\\",\\\"mch_order_no\\\":\\\"NO_2022082618263952399\\\"}\",\"mch_no\":\"888118000001971\",\"rand_str\":\"an2w7ulf5ru6upkk5bdg441kdi3gnpvu\",\"resp_code\":\"SUCCESS\",\"sec_key\":\"\",\"sign\":\"NiJXRTSIZ9xZMUOwEHiEHdZXmgL2cHUU5WUa1NbMRRzui0DIiuZSW4e31LjnBxwVwmy3uuPMP+tqhY8VLyC8uCFOdGdZI7e72VuRvyvaiW7/sqCrsfgPOBEjiGE/CmSMRoEXv9HmqCyNBF6iHSEhQJql5Yge30dQdyB6xFfqjk0=\",\"sign_type\":\"2\"}";
src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java
@@ -1,9 +1,6 @@
package cc.mrbird.febs.mall.service.impl;
import cc.mrbird.febs.common.enumerates.AgentLevelEnum;
import cc.mrbird.febs.common.enumerates.DataDictionaryEnum;
import cc.mrbird.febs.common.enumerates.FlowTypeEnum;
import cc.mrbird.febs.common.enumerates.MoneyFlowTypeEnum;
import cc.mrbird.febs.common.enumerates.*;
import cc.mrbird.febs.common.utils.AppContants;
import cc.mrbird.febs.common.utils.MallUtils;
import cc.mrbird.febs.common.utils.RedisUtils;
@@ -59,6 +56,8 @@
    private final IMallMoneyFlowService mallMoneyFlowService;
    private final MallMqRecordMapper mallMqRecordMapper;
    private final AgentProducer agentProducer;
    private final MallScoreRecordMapper mallScoreRecordMapper;
    private final MallScoreAchieveReleaseMapper mallScoreAchieveReleaseMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
@@ -789,4 +788,298 @@
        }
    }
    @Override
    public void scoreRecordReleaseJob() {
        /**
         * 每日按照比例释放记录的百分比到用户的绿色凭证账户
         */
        //获取全部剩余数量大于零的记录
        List<MallScoreRecord> mallScoreRecords = mallScoreRecordMapper.selectList();
        if(CollUtil.isEmpty(mallScoreRecords)){
            return;
        }
        DataDictionaryCustom roleReleasePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ROLE_RELEASE_PERCENT.getType(),
                GreenScoreEnum.ROLE_RELEASE_PERCENT.getCode()
        );
        if(ObjectUtil.isEmpty(roleReleasePercentDic)){
            return;
        }
        //释放比例
        BigDecimal roleReleasePercent = new BigDecimal(roleReleasePercentDic.getValue()).multiply(new BigDecimal(0.001));
        for(MallScoreRecord mallScoreRecord : mallScoreRecords){
            Long memberId = mallScoreRecord.getMemberId();
            //每日释放的绿色凭证数量 = 总数 * 释放比例
            BigDecimal scoreCnt = mallScoreRecord.getScoreCnt();
            BigDecimal scoreReleaseCnt = scoreCnt.multiply(roleReleasePercent).setScale(2,BigDecimal.ROUND_DOWN);
            BigDecimal surplusCnt = mallScoreRecord.getSurplusCnt();
            if(scoreReleaseCnt.compareTo(surplusCnt) >= 0){
                scoreReleaseCnt = surplusCnt;
            }
            if(scoreReleaseCnt.compareTo(BigDecimal.ZERO) > 0){
                releaseToMemberAndAddFlow(scoreReleaseCnt,memberId,
                        MoneyFlowTypeEnum.ROLE_RELEASE_SCORE.getValue(),mallScoreRecord.getScoreNo());
                //更新凭证记录的剩余数量
                surplusCnt = surplusCnt.subtract(scoreReleaseCnt);
                mallScoreRecord.setSurplusCnt(surplusCnt);
                mallScoreRecordMapper.updateById(mallScoreRecord);
            }
        }
    }
    @Override
    public void achieveReleaseJob() {
        /**
         * 业绩产生凭证
         *      获取每日最大产生的凭证数量
         *      获取每日总业绩
         *      获取业绩产生凭证的最大值和最小值
         *      每条业绩记录占
         */
        //获取每日总业绩
        Date profitDate = DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, -1);
        BigDecimal achieveTotal = mallAchieveRecordMapper.selectAchieveTotal("D", profitDate);
        DataDictionaryCustom achieveMinDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ACHIEVE_MIN.getType(),
                GreenScoreEnum.ACHIEVE_MIN.getCode()
        );
        //业绩的最小值
        BigDecimal achieveMin = new BigDecimal(achieveMinDic.getValue() == null ? "0" : achieveMinDic.getValue());
        if(achieveTotal.compareTo(achieveMin) < 0){
            return;
        }
        DataDictionaryCustom achieveMaxDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ACHIEVE_MAX.getType(),
                GreenScoreEnum.ACHIEVE_MAX.getCode()
        );
        //业绩的最大值
        BigDecimal achieveMax = new BigDecimal(achieveMaxDic.getValue() == null ? "0" : achieveMaxDic.getValue());
        /**
         * 获取每日最大产生的凭证数量
         */
        BigDecimal achieveDailyRelease = getAchieveDailyRelease();
        if(achieveTotal.compareTo(achieveMax) < 0){
            BigDecimal divide = achieveTotal.divide(achieveMax, 2, BigDecimal.ROUND_DOWN);
            achieveDailyRelease = achieveDailyRelease.multiply(divide).setScale(2,BigDecimal.ROUND_DOWN);
        }
        /**
         * 实际每日最大产生的凭证数量
         */
        BigDecimal achieveDailyReleaseReal = BigDecimal.ZERO;
        /**
         * 业务编号
         */
        String scoreNo = MallUtils.getOrderNum("ARSX");
        /**
         * 20%给合伙人、联创
         *  5% 给联创
         *  15% 给合伙人
         */
        DataDictionaryCustom roleAchievePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ROLE_ACHIEVE_PERCENT.getType(),
                GreenScoreEnum.ROLE_ACHIEVE_PERCENT.getCode()
        );
        //业绩产生凭证给创世的比例
        BigDecimal roleAchievePercent = new BigDecimal(roleAchievePercentDic.getValue() == null ? "0" : roleAchievePercentDic.getValue())
                                        .multiply(new BigDecimal(0.01));
        //创世的凭证数量
        BigDecimal roleAchieveRelease = achieveDailyRelease.multiply(roleAchievePercent).setScale(2, BigDecimal.ROUND_DOWN);
        List<MallMember> roleAchieveReleaseMembers = mallMemberMapper.selectByRole(3,1);
        if(CollUtil.isNotEmpty(roleAchieveReleaseMembers)){
            //联创拿走0.25
            BigDecimal multiply = roleAchieveRelease.multiply(new BigDecimal(0.25));
            BigDecimal memberAchieveRelease = multiply.divide(new BigDecimal(roleAchieveReleaseMembers.size()), 2, BigDecimal.ROUND_DOWN);
            if(memberAchieveRelease.compareTo(BigDecimal.ZERO) > 0){
                for(MallMember mallMember : roleAchieveReleaseMembers){
                    releaseToMemberAndAddFlow(memberAchieveRelease,mallMember.getId(),
                            MoneyFlowTypeEnum.ACHIEVE_RELEASE_SCORE_LC.getValue(),scoreNo);
                    achieveDailyReleaseReal = achieveDailyReleaseReal.add(memberAchieveRelease);
                }
            }
        }
        //合伙人拿走0.75
        List<MallMember> roleAchieveReleaseHHR = mallMemberMapper.selectByRole(4,1);
        if(CollUtil.isNotEmpty(roleAchieveReleaseHHR)){
            //合伙人拿走0.75
            BigDecimal multiply = roleAchieveRelease.multiply(new BigDecimal(0.75));
            BigDecimal memberAchieveReleaseHHR = multiply.divide(new BigDecimal(roleAchieveReleaseHHR.size()), 2, BigDecimal.ROUND_DOWN);
            if(memberAchieveReleaseHHR.compareTo(BigDecimal.ZERO) > 0){
                for(MallMember mallMember : roleAchieveReleaseHHR){
                    releaseToMemberAndAddFlow(memberAchieveReleaseHHR,mallMember.getId(),
                            MoneyFlowTypeEnum.ACHIEVE_RELEASE_SCORE_HHR.getValue(),scoreNo);
                    achieveDailyReleaseReal = achieveDailyReleaseReal.add(memberAchieveReleaseHHR);
                }
            }
        }
        /**
         * 30%按贡献点分配给所有人
         */
        DataDictionaryCustom starAchievePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.STAR_ACHIEVE_PERCENT.getType(),
                GreenScoreEnum.STAR_ACHIEVE_PERCENT.getCode()
        );
        //业绩产生凭证给贡献点分配给所有人
        BigDecimal starAchievePercent = new BigDecimal(starAchievePercentDic.getValue() == null ? "0" : starAchievePercentDic.getValue())
                .multiply(new BigDecimal(0.01));
        //贡献点的凭证数量
        BigDecimal starAchieveRelease = achieveDailyRelease.multiply(starAchievePercent).setScale(2, BigDecimal.ROUND_DOWN);
        BigDecimal starSumCnt = mallMemberWalletMapper.selectSumStar();
        if(starSumCnt.compareTo(BigDecimal.ZERO) > 0){
            //每一个贡献点获取的凭证
            BigDecimal starAchieveReleaseOne = starAchieveRelease.divide(starSumCnt, 2, BigDecimal.ROUND_DOWN);
            List<MallMemberWallet> mallMemberWallets = mallMemberWalletMapper.selectStar();
            if(CollUtil.isNotEmpty(mallMemberWallets) && starAchieveReleaseOne.compareTo(BigDecimal.ZERO) > 0){
                for(MallMemberWallet mallMemberWallet : mallMemberWallets){
                    //每个人获取的凭证 = 贡献点 * 每一个贡献点值的凭证
                    BigDecimal bigDecimal = starAchieveReleaseOne.multiply(new BigDecimal(mallMemberWallet.getStar())).setScale(2, BigDecimal.ROUND_DOWN);
                    releaseToMemberAndAddFlow(bigDecimal,mallMemberWallet.getMemberId(),
                            MoneyFlowTypeEnum.ACHIEVE_RELEASE_SCORE_GXD.getValue(),scoreNo);
                    achieveDailyReleaseReal = achieveDailyReleaseReal.add(bigDecimal);
                }
            }
        }
        /**
         * 50%按按星级分配给所有人
         * 二星  30%
         * 三星  25%
         * 四星  20%
         * 五星  15%
         * 六星  10%
         */
        DataDictionaryCustom levelAchievePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.LEVEL_ACHIEVE_PERCENT.getType(),
                GreenScoreEnum.LEVEL_ACHIEVE_PERCENT.getCode()
        );
        //业绩产生凭证给星级分配给所有人
        BigDecimal levelAchievePercent = new BigDecimal(levelAchievePercentDic.getValue() == null ? "0" : levelAchievePercentDic.getValue())
                .multiply(new BigDecimal(0.01));
        //业绩产生凭证给星级分配给所有人总数
        BigDecimal levelAchieveRelease = achieveDailyRelease.multiply(levelAchievePercent).setScale(2, BigDecimal.ROUND_DOWN);
        BigDecimal thirdRelease = releaseByLevel(levelAchieveRelease, AgentLevelEnum.THIRD_LEVEL.getCode(), new BigDecimal(0.3),scoreNo);
        achieveDailyReleaseReal = achieveDailyReleaseReal.add(thirdRelease);
        BigDecimal fourRelease = releaseByLevel(levelAchieveRelease, AgentLevelEnum.FOUR_LEVEL.getCode(), new BigDecimal(0.25),scoreNo);
        achieveDailyReleaseReal = achieveDailyReleaseReal.add(fourRelease);
        BigDecimal fiveRelease = releaseByLevel(levelAchieveRelease, AgentLevelEnum.FIFTH_LEVEL.getCode(), new BigDecimal(0.2),scoreNo);
        achieveDailyReleaseReal = achieveDailyReleaseReal.add(fiveRelease);
        BigDecimal sixRelease = releaseByLevel(levelAchieveRelease, AgentLevelEnum.SIX_LEVEL.getCode(), new BigDecimal(0.15),scoreNo);
        achieveDailyReleaseReal = achieveDailyReleaseReal.add(sixRelease);
        BigDecimal sevenRelease = releaseByLevel(levelAchieveRelease, AgentLevelEnum.SEVEN_LEVEL.getCode(), new BigDecimal(0.1),scoreNo);
        achieveDailyReleaseReal = achieveDailyReleaseReal.add(sevenRelease);
        if(achieveDailyReleaseReal.compareTo(BigDecimal.ZERO) > 0){
            DataDictionaryCustom surplusCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                    GreenScoreEnum.SURPLUS_CNT.getType(),
                    GreenScoreEnum.SURPLUS_CNT.getCode()
            );
            //绿色积分剩余数量
            BigDecimal surplusCnt = new BigDecimal(surplusCntDic.getValue() == null ? "0" : surplusCntDic.getValue());
            BigDecimal subtract = surplusCnt.subtract(achieveDailyReleaseReal).setScale(2,BigDecimal.ROUND_DOWN);
            surplusCntDic.setValue(subtract.toString());
            dataDictionaryCustomMapper.updateById(surplusCntDic);
        }
        log.info("昨日实际业绩:{},昨日凭证总共:{},实际产生凭证:{}",
                achieveTotal,achieveDailyRelease,achieveDailyReleaseReal);
        MallScoreAchieveRelease mallScoreAchieveRelease = new MallScoreAchieveRelease();
        mallScoreAchieveRelease.setAchieve(achieveTotal);
        mallScoreAchieveRelease.setReleaseNo(scoreNo);
        mallScoreAchieveRelease.setVoucherExpect(achieveDailyRelease);
        mallScoreAchieveRelease.setVoucherReal(achieveDailyReleaseReal);
        mallScoreAchieveReleaseMapper.updateById(mallScoreAchieveRelease);
    }
    /**
     * 给用户的增加凭证数据,并且增加流水
     * @param memberAchieveRelease 释放数量
     * @param memberId 用户ID
     * @param Type 流水类型
     * @param flowNo 流水编号
     */
    private void releaseToMemberAndAddFlow(BigDecimal memberAchieveRelease,Long memberId,int Type,String flowNo){
        //释放到用户的账户
        mallMemberWalletMapper.addVorCherCntByMemberId(memberAchieveRelease,memberId);
        //产生一条流水记录 TODO 需要去掉注释
        mallMoneyFlowService.addMoneyFlow(
                memberId,
                memberAchieveRelease,
                Type,
                flowNo,
                FlowTypeEnum.VOUCHER_CNT.getValue());
    }
    /**
     *  根据星级等级和占比,给该星级的用户释放凭证
     * @param levelAchieveRelease
     * @param level
     * @param percent
     * @return
     */
    private BigDecimal releaseByLevel(BigDecimal levelAchieveRelease,String level,BigDecimal percent,String scoreNo){
        //实际支付的凭证数量
        BigDecimal levelReleaseReal = BigDecimal.ZERO;
        //当前星级的人数
        List<MallMember> levelMembers = mallMemberMapper.selectMemberWithLevel(level);
        if(CollUtil.isNotEmpty(levelMembers)){
            //这个星级该获得的凭证数量 = 总数 * 比例
            BigDecimal levelReleaseCnt = levelAchieveRelease.multiply(percent).setScale(2, BigDecimal.ROUND_DOWN);
            if(levelReleaseCnt.compareTo(BigDecimal.ZERO) > 0){
                //每个人获得的数量
                BigDecimal levelRelease = levelReleaseCnt.divide(new BigDecimal(levelMembers.size()), 2, BigDecimal.ROUND_DOWN);
                if(levelRelease.compareTo(BigDecimal.ZERO) > 0){
                    for(MallMember mallMember : levelMembers){
                        releaseToMemberAndAddFlow(levelRelease,mallMember.getId(),MoneyFlowTypeEnum.ACHIEVE_RELEASE_SCORE_XJ.getValue(),scoreNo);
                        levelReleaseReal.add(levelRelease);
                    }
                }
            }
        }
        return levelReleaseReal;
    }
    /**
     * 获取每日最大产生的凭证数量
     * @return
     */
    private BigDecimal getAchieveDailyRelease(){
        DataDictionaryCustom achieveReleasePercentDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.ACHIEVE_RELEASE_PERCENT.getType(),
                GreenScoreEnum.ACHIEVE_RELEASE_PERCENT.getCode()
        );
        BigDecimal achieveReleasePercent = new BigDecimal(achieveReleasePercentDic.getValue() == null ? "0" : achieveReleasePercentDic.getValue())
                .multiply(new BigDecimal(0.0001));
        DataDictionaryCustom totalCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                GreenScoreEnum.TOTAL_CNT.getType(),
                GreenScoreEnum.TOTAL_CNT.getCode()
        );
        //总凭证数量
        BigDecimal totalCnt = new BigDecimal(totalCntDic.getValue() == null ? "0" : totalCntDic.getValue()).multiply(new BigDecimal(0.9));
        //获取每日最大产生的凭证数量
        BigDecimal achieveRelease = totalCnt.multiply(achieveReleasePercent);
        return achieveRelease;
    }
}
src/main/resources/mapper/modules/MallAchieveRecordMapper.xml
@@ -13,7 +13,7 @@
        </if>
    </select>
    <select id="selectSumAchieveByMemberIds" resultType="cc.mrbird.febs.mall.entity.MallAchieveRecord">
    <select id="selectSumAchieveByMemberIds" resultType="java.math.BigDecimal">
        select IFNULL(sum(IFNULL(amount,0)),0)
        from mall_achieve_record
        where  member_id IN
@@ -23,4 +23,9 @@
        and date_format(achieve_time, '%Y-%m-%d') = date_format(#{date}, '%Y-%m-%d');
    </select>
    <select id="selectListByDate" resultType="cc.mrbird.febs.mall.entity.MallAchieveRecord">
        select * from mall_achieve_record
        where date_format(achieve_time, '%Y-%m-%d') = date_format(#{date}, '%Y-%m-%d');
    </select>
</mapper>
src/main/resources/mapper/modules/MallMemberMapper.xml
@@ -12,6 +12,8 @@
               IFNULL(c.commission,0) commission,
               IFNULL(c.star,0) star,
               IFNULL(c.total_score,0) totalScore,
               IFNULL(c.voucher_cnt,0) voucherCnt,
               IFNULL(c.voucher_amount,0) voucherAmount,
               d.description levelName
        FROM mall_member m
        left join mall_member a on m.referrer_id = a.invite_id
@@ -431,4 +433,16 @@
        from mall_member
        where store_master = #{state}
    </select>
    <select id="selectByRole" resultType="cc.mrbird.febs.mall.entity.MallMember">
        select * from mall_member
        <where>
            <if test="type == 3">
                and creater = #{state}
            </if>
            <if test="type == 4">
                and partner = #{state}
            </if>
        </where>
    </select>
</mapper>
src/main/resources/mapper/modules/MallMemberWalletMapper.xml
@@ -127,5 +127,22 @@
            WHERE member_id =  #{memberId}
    </update>
    <update id="addVorCherCntByMemberId">
        update mall_member_wallet
        <set>
            voucher_cnt = voucher_cnt + #{voucherCnt},
        </set>
        WHERE member_id =  #{memberId}
    </update>
    <select id="selectSumStar" resultType="java.math.BigDecimal">
        select ifnull(sum(star),0) total from mall_member_wallet
    </select>
    <select id="selectStar" resultType="cc.mrbird.febs.mall.entity.MallMemberWallet">
        select * from mall_member_wallet
        where  star > 0
    </select>
</mapper>
src/main/resources/mapper/modules/MallScoreAchieveReleaseMapper.xml
New file
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cc.mrbird.febs.mall.mapper.MallScoreAchieveReleaseMapper">
    <select id="gerAchieveReleaseListInPage" resultType="cc.mrbird.febs.mall.entity.MallScoreAchieveRelease">
        select
        a.*
        from mall_score_achieve_release a
        order by a.created_time desc
    </select>
    <select id="gerAchieveReleaseChildInPage" resultType="cc.mrbird.febs.mall.entity.MallMoneyFlow">
        select
            a.*,
               b.name name,
               b.phone phone
        from mall_money_flow a
        left join mall_member b on b.id = a.member_id
        where
            a.order_no = #{record.releaseNo}
        order by a.created_time desc
    </select>
</mapper>
src/main/resources/mapper/modules/MallScoreRecordMapper.xml
New file
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cc.mrbird.febs.mall.mapper.MallScoreRecordMapper">
    <select id="selectSumScoreCnt" resultType="java.math.BigDecimal">
        select IFNULL(sum(IFNULL(score_cnt,0)),0) from mall_score_record
    </select>
    <select id="selectList" resultType="cc.mrbird.febs.mall.entity.MallScoreRecord">
        select * from mall_score_record where surplus_cnt > 0
    </select>
    <select id="gerRoleReleaseListInPage" resultType="cc.mrbird.febs.mall.entity.MallScoreRecord">
        select
               a.*,
               b.name name,
               b.phone phone,
               b.invite_id inviteId
        from mall_score_record a
        left join mall_member b on a.member_id = b.id
        <where>
            <if test="record != null">
                <if test="record.name != null and record.name != ''">
                    and b.name like CONCAT('%', CONCAT(#{record.name}, '%'))
                </if>
                <if test="record.account != null and record.account != ''">
                    and (b.phone like CONCAT('%', CONCAT(#{record.account}, '%'))
                        or b.invite_id like CONCAT('%', CONCAT(#{record.account}, '%')))
                </if>
            </if>
        </where>
        order by a.created_time desc
    </select>
    <select id="gerRoleReleaseChildInPage" resultType="cc.mrbird.febs.mall.entity.MallMoneyFlow">
        select
               a.*
        from mall_money_flow a
        where
            a.order_no = #{record.scoreNo}
        order by a.created_time desc
    </select>
</mapper>
src/main/resources/templates/febs/views/modules/mallMember/mallMemberList.html
@@ -89,6 +89,20 @@
    <input type="checkbox" value={{d.id}} lay-text="是|否" lay-skin="switch" lay-filter="switchDirector">
    {{# } }}
</script>
<script type="text/html" id="switchCreate">
    {{# if(d.creater === 1) { }}
    <input type="checkbox" value={{d.id}} lay-text="是|否" checked lay-skin="switch" lay-filter="switchCreate">
    {{# } else { }}
    <input type="checkbox" value={{d.id}} lay-text="是|否" lay-skin="switch" lay-filter="switchCreate">
    {{# } }}
</script>
<script type="text/html" id="switchPartner">
    {{# if(d.partner === 1) { }}
    <input type="checkbox" value={{d.id}} lay-text="是|否" checked lay-skin="switch" lay-filter="switchPartner">
    {{# } else { }}
    <input type="checkbox" value={{d.id}} lay-text="是|否" lay-skin="switch" lay-filter="switchPartner">
    {{# } }}
</script>
<style>
    .layui-form-onswitch {
        background-color: #5FB878 !important;
@@ -103,6 +117,7 @@
        <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" shiro:hasPermission="resetPwd:update" lay-event="resetPwd">重置登录密码</button>
        <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" shiro:hasPermission="resetPwd:update" lay-event="resetPayPwd">重置支付密码</button>
        <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" shiro:hasPermission="agentLevelSet:update" lay-event="agentLevel">设置代理等级</button>
        <button class="layui-btn layui-btn-normal layui-btn-sm" type="button" shiro:hasPermission="voucherUpdate:update" lay-event="voucherUpdate">拨付绿色凭证</button>
    </div>
</script>
<!-- 表格操作栏 end -->
@@ -241,10 +256,14 @@
                    {field: 'prizeScore', title: '现金积分', minWidth: 100,align:'left',totalRow: '{{= parseInt(d.prizeScore) }}'},
                    {field: 'star', title: '贡献点', minWidth: 100,align:'left',totalRow: '{{= parseInt(d.star) }}'},
                    {field: 'totalScore', title: '补贴额度', minWidth: 100,align:'left',totalRow: '{{= parseInt(d.totalScore) }}'},
                    {field: 'voucherCnt', title: '绿色凭证', minWidth: 100,align:'left',totalRow: '{{= parseInt(d.voucherCnt) }}'},
                    {field: 'voucherAmount', title: '凭证现金', minWidth: 100,align:'left',totalRow: '{{= parseInt(d.voucherAmount) }}'},
                    {field: 'referrerName', title: '推荐人', minWidth: 100,align:'left'},
                    {field: 'levelName', title: '会员类型', minWidth: 100,align:'left'},
                    {field: 'storeMaster', title: '线下服务中心', templet:'#switchStoreMaster', minWidth: 120,align:'left'},
                    {field: 'director', title: '代理商', templet:'#switchDirector', minWidth: 120,align:'left' },
                    {field: 'creater', title: '联创', templet:'#switchCreate', minWidth: 120,align:'left' },
                    {field: 'partner', title: '合伙人', templet:'#switchPartner', minWidth: 120,align:'left' },
                    {field: 'accountType', title: '账号类型',
                        templet: function (d) {
                            if (d.accountType === 2) {
@@ -338,6 +357,19 @@
                systemPay("修改余额", checkData[0].id, 1);
            }
            if (layEvent === 'voucherUpdate') {
                var checkData = table.checkStatus('userTable').data;
                if (checkData.length <= 0) {
                    febs.alert.warn('请选择需要的用户');
                    return;
                }
                if (checkData.length > 1) {
                    febs.alert.warn('请选择一个用户');
                    return;
                }
                voucherUpdate("拨付绿色凭证", checkData[0].id, 1);
            }
            if (layEvent === 'score') {
                var checkData = table.checkStatus('userTable').data;
                if (checkData.length <= 0) {
@@ -386,6 +418,18 @@
            }
        });
        function voucherUpdate(text, id, type) {
            febs.modal.open(text, 'modules/mallMember/voucherUpdate/' + type +'/'+ id, {
                btn: ['提交', '取消'],
                yes: function (index, layero) {
                    $('#voucher-update').find('#submit').trigger('click');
                },
                btn2: function () {
                    layer.closeAll();
                }
            });
        }
        function systemPay(text, id, type) {
            febs.modal.open('text', 'modules/mallMember/mallSystemPay/' + type +'/'+ id, {
                btn: ['提交', '取消'],
@@ -431,5 +475,21 @@
                changeIdentityNo(1, data.value);
            }
        })
        form.on('switch(switchCreate)', function (data) {
            if (data.elem.checked) {
                changeIdentityYes(3, data.value);
            } else {
                changeIdentityNo(3, data.value);
            }
        })
        form.on('switch(switchPartner)', function (data) {
            if (data.elem.checked) {
                changeIdentityYes(4, data.value);
            } else {
                changeIdentityNo(4, data.value);
            }
        })
    })
</script>
src/main/resources/templates/febs/views/modules/mallMember/scoreAchieveRelease.html
New file
@@ -0,0 +1,107 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-achieve-release" lay-title="业绩释放记录">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-card">
                <div class="layui-card-body febs-table-full">
                    <form class="layui-form layui-table-form" lay-filter="user-table-form">
                        <div class="layui-row">
                            <div class="layui-col-md10">
                                <div class="layui-form-item">
                                </div>
                            </div>
                            <div class="layui-col-md2 layui-col-sm12 layui-col-xs12 table-action-area">
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-blue-plain table-action" id="query">
                                    <i class="layui-icon">&#xe848;</i>
                                </div>
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="reset">
                                    <i class="layui-icon">&#xe79b;</i>
                                </div>
                            </div>
                        </div>
                    </form>
                    <table lay-filter="achieveReleaseTable" lay-data="{id: 'achieveReleaseTable'}"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- 表格操作栏 start -->
<script type="text/html" id="user-option">
    <span shiro:lacksPermission="user:view,user:update,user:delete">
        <span class="layui-badge-dot febs-bg-orange"></span> 无权限
    </span>
    <a lay-event="edit" shiro:hasPermission="user:update"><i
            class="layui-icon febs-edit-area febs-blue">&#xe7a5;</i></a>
</script>
<!-- 表格操作栏 end -->
<script data-th-inline="none" type="text/javascript">
    // 引入组件并初始化
    layui.use([ 'jquery', 'form', 'table', 'febs'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            form = layui.form,
            table = layui.table,
            $view = $('#febs-achieve-release'),
            $query = $view.find('#query'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: '', type: null},
            tableIns;
        form.render();
        // 表格初始化
        initTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(scoreAchieveReleaseList)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'scoreAchieveReleaseList') {
                febs.modal.open( '全部记录', 'modules/mallMember/scoreAchieveReleaseList/' + data.id, {
                    maxmin: true,
                });
            }
        });
        // 查询按钮
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: 1}});
        });
        // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
        });
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'achieveReleaseTable',
                url: ctx + 'admin/mallMember/gerAchieveRelease',
                totalRow: true ,// 开启合计行
                cols: [[
                    {field: 'releaseNo', title: '编号', minWidth: 150,align:'center', totalRowText: '合计:'},
                    {field: 'achieve', title: '业绩总数', minWidth: 100,align:'center'},
                    {field: 'voucherExpect', title: '预期凭证数量', minWidth: 100,align:'center',totalRow: '{{= parseInt(d.voucherExpect) }}'},
                    {field: 'voucherReal', title: '实际凭证数量', minWidth: 100,align:'center',totalRow: '{{= parseInt(d.voucherReal) }}'},
                    {field: 'createdTime', title: '释放时间', minWidth: 150,align:'center'},
                    {title: '操作',
                        templet: function (d) {
                            return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="scoreAchieveReleaseList" shiro:hasPermission="user:update">全部记录</button>'
                        },minWidth: 200,align:'center'}
                ]]
            });
        }
        // 获取查询参数
        function getQueryParams() {
            return {
            };
        }
    })
</script>
src/main/resources/templates/febs/views/modules/mallMember/scoreAchieveReleaseList.html
New file
@@ -0,0 +1,55 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-achieve-release-child" lay-title="全部记录">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-card">
                <div class="layui-card-body febs-table-full">
                    <table lay-filter="achieveReleaseChild" lay-data="{id: 'achieveReleaseChild'}"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<script data-th-inline="none" type="text/javascript">
    layui.use([ 'jquery',  'form', 'table', 'febs'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            form = layui.form,
            table = layui.table,
            $view = $('#febs-achieve-release-child'),
            tableIns;
        form.render();
        initTable();
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'achieveReleaseChild',
                url: ctx + 'admin/mallMember/roleReleaseChild?parentId=1',
                totalRow: true ,// 开启合计行
                cols: [[
                    {field: 'name', title: '名称', minWidth: 150,align:'center', totalRowText: '合计:'},
                    {field: 'phone', title: '电话', minWidth: 150,align:'center'},
                    {field: 'createdTime', title: '释放时间', minWidth: 150,align:'center'},
                    {field: 'type', title: '类型',
                        templet: function (d) {
                            if (d.type === 32) {
                                return '<span>联创</span>'
                            } else if (d.type === 33) {
                                return '<span>合伙人</span>'
                            } else if (d.type === 34) {
                                return '<span>贡献点</span>'
                            } else if (d.type === 35) {
                                return '<span>星级</span>'
                            }else{
                                return ''
                            }
                        }, minWidth: 80,align:'center'},
                    {field: 'amount', title: '数量', minWidth: 150,align:'center',totalRow: '{{= parseInt(d.amount) }}'},
                ]]
            });
        }
    })
</script>
src/main/resources/templates/febs/views/modules/mallMember/scoreRoleRelease.html
New file
@@ -0,0 +1,123 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-role-release" lay-title="创世释放记录">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-card">
                <div class="layui-card-body febs-table-full">
                    <form class="layui-form layui-table-form" lay-filter="user-table-form">
                        <div class="layui-row">
                            <div class="layui-col-md10">
                                <div class="layui-form-item">
                                    <div class="layui-inline">
                                        <label class="layui-form-label">名称:</label>
                                        <div class="layui-input-inline">
                                            <input type="text" placeholder="名称" name="name" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                    <div class="layui-inline">
                                        <label class="layui-form-label">账号:</label>
                                        <div class="layui-input-inline">
                                            <input type="text" placeholder="账号/邀请码" name="account" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="layui-col-md2 layui-col-sm12 layui-col-xs12 table-action-area">
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-blue-plain table-action" id="query">
                                    <i class="layui-icon">&#xe848;</i>
                                </div>
                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="reset">
                                    <i class="layui-icon">&#xe79b;</i>
                                </div>
                            </div>
                        </div>
                    </form>
                    <table lay-filter="roleReleaseTable" lay-data="{id: 'roleReleaseTable'}"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- 表格操作栏 start -->
<script type="text/html" id="user-option">
    <span shiro:lacksPermission="user:view,user:update,user:delete">
        <span class="layui-badge-dot febs-bg-orange"></span> 无权限
    </span>
    <a lay-event="edit" shiro:hasPermission="user:update"><i
            class="layui-icon febs-edit-area febs-blue">&#xe7a5;</i></a>
</script>
<!-- 表格操作栏 end -->
<script data-th-inline="none" type="text/javascript">
    // 引入组件并初始化
    layui.use([ 'jquery', 'form', 'table', 'febs'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            form = layui.form,
            table = layui.table,
            $view = $('#febs-role-release'),
            $query = $view.find('#query'),
            $reset = $view.find('#reset'),
            $searchForm = $view.find('form'),
            sortObject = {field: 'phone', type: null},
            tableIns;
        form.render();
        // 表格初始化
        initTable();
        // 初始化表格操作栏各个按钮功能
        table.on('tool(roleReleaseTable)', function (obj) {
            var data = obj.data,
                layEvent = obj.event;
            if (layEvent === 'scoreRoleReleaseList') {
                febs.modal.open( '全部记录', 'modules/mallMember/scoreRoleReleaseList/' + data.id, {
                    maxmin: true,
                });
            }
        });
        // 查询按钮
        $query.on('click', function () {
            var params = $.extend(getQueryParams(), {field: sortObject.field, order: sortObject.type});
            tableIns.reload({where: params, page: {curr: 1}});
        });
        // 刷新按钮
        $reset.on('click', function () {
            $searchForm[0].reset();
            sortObject.type = 'null';
            tableIns.reload({where: getQueryParams(), page: {curr: 1}, initSort: sortObject});
        });
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'roleReleaseTable',
                url: ctx + 'admin/mallMember/gerRoleRelease',
                totalRow: true ,// 开启合计行
                cols: [[
                    {field: 'phone', title: '账号', minWidth: 150,align:'center', totalRowText: '合计:'},
                    {field: 'name', title: '名称', minWidth: 100,align:'center'},
                    {field: 'inviteId', title: '邀请码', minWidth: 100,align:'center'},
                    {field: 'scoreNo', title: '编号', minWidth: 100,align:'center'},
                    {field: 'scoreCnt', title: '总量', minWidth: 100,align:'center',totalRow: '{{= parseInt(d.scoreCnt) }}'},
                    {field: 'surplusCnt', title: '剩余', minWidth: 100,align:'center',totalRow: '{{= parseInt(d.surplusCnt) }}'},
                    {field: 'createdTime', title: '购买时间', minWidth: 150,align:'center'},
                    {title: '操作',
                        templet: function (d) {
                            return '<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="scoreRoleReleaseList" shiro:hasPermission="user:update">全部记录</button>'
                        },minWidth: 200,align:'center'}
                ]]
            });
        }
        // 获取查询参数
        function getQueryParams() {
            return {
                name: $searchForm.find('input[name="name"]').val().trim(),
                account: $searchForm.find('input[name="account"]').val().trim(),
            };
        }
    })
</script>
src/main/resources/templates/febs/views/modules/mallMember/scoreRoleReleaseList.html
New file
@@ -0,0 +1,39 @@
<div class="layui-fluid layui-anim febs-anim" id="febs-role-release-child" lay-title="全部记录">
    <div class="layui-row febs-container">
        <div class="layui-col-md12">
            <div class="layui-card">
                <div class="layui-card-body febs-table-full">
                    <table lay-filter="roleReleaseChild" lay-data="{id: 'roleReleaseChild'}"></table>
                </div>
            </div>
        </div>
    </div>
</div>
<script data-th-inline="none" type="text/javascript">
    layui.use([ 'jquery',  'form', 'table', 'febs'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            form = layui.form,
            table = layui.table,
            $view = $('#febs-role-release-child'),
            tableIns;
        form.render();
        initTable();
        function initTable() {
            tableIns = febs.table.init({
                elem: $view.find('table'),
                id: 'roleReleaseChild',
                url: ctx + 'admin/mallMember/roleReleaseChild?parentId=1',
                totalRow: true ,// 开启合计行
                cols: [[
                    {field: 'createdTime', title: '释放时间', minWidth: 150,align:'center', totalRowText: '合计:'},
                    {field: 'amount', title: '数量', minWidth: 150,align:'center',totalRow: '{{= parseInt(d.amount) }}'},
                ]]
            });
        }
    })
</script>
src/main/resources/templates/febs/views/modules/mallMember/voucherUpdate.html
New file
@@ -0,0 +1,91 @@
<style>
    #voucher-update {
        padding: 20px 25px 25px 0;
    }
    #voucher-update .layui-treeSelect .ztree li a, .ztree li span {
        margin: 0 0 2px 3px !important;
    }
    #voucher-update #data-permission-tree-block {
        border: 1px solid #eee;
        border-radius: 2px;
        padding: 3px 0;
    }
    #voucher-update .layui-treeSelect .ztree li span.button.switch {
        top: 1px;
        left: 3px;
    }
    #voucher-update img{
        max-width:100px
    }
</style>
<div class="layui-fluid" id="voucher-update">
    <form class="layui-form" action="" lay-filter="voucher-update-form">
        <div class="layui-form-item febs-hide">
            <label class="layui-form-label febs-form-item-require">id:</label>
            <div class="layui-input-block">
                <input type="text" name="id">
            </div>
        </div>
<!--        <div class="layui-form-item">-->
<!--            <label class="layui-form-label febs-form-item-require">当前余额:</label>-->
<!--            <div class="layui-input-block">-->
<!--                <input type="number" name="balance" lay-verify="required" autocomplete="off" class="layui-input" readonly>-->
<!--            </div>-->
<!--        </div>-->
        <div class="layui-form-item">
            <label class="layui-form-label febs-form-item-require">拨付数目:</label>
            <div class="layui-input-block">
                <input type="number" name="addBalance" lay-verify="required" autocomplete="off" class="layui-input">
                <div class="layui-word-aux">拨付数目会按照设定的比例,每日拨付到用户账户</div>
            </div>
        </div>
        <div class="layui-form-item febs-hide">
            <button class="layui-btn" lay-submit="" lay-filter="voucher-update-form-submit" id="submit"></button>
        </div>
    </form>
</div>
<script data-th-inline="javascript">
    layui.use(['febs', 'form', 'formSelects', 'validate', 'treeSelect', 'eleTree', 'laydate'], function () {
        var $ = layui.$,
            febs = layui.febs,
            layer = layui.layer,
            formSelects = layui.formSelects,
            treeSelect = layui.treeSelect,
            form = layui.form,
            laydate = layui.laydate,
            eleTree = layui.eleTree,
            systemPay = [[${systemPay}]],
            type = [[${type}]],
            $view = $('#voucher-update'),
            validate = layui.validate;
        form.render();
        laydate.render({
            elem: '#febs-form-group-date'
        });
        formSelects.render();
        initUserValue();
        function initUserValue() {
            form.val("voucher-update-form", {
                "id": systemPay.id,
            });
        }
        form.on('submit(voucher-update-form-submit)', function (data) {
            data.field.type = type;
            febs.post(ctx + 'admin/mallMember/updateVoucher', data.field, function () {
                layer.closeAll();
                febs.alert.success('操作成功');
                $('#febs-member-list').find('#reset').click();
            });
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/system/hlmVoucherButton.html
New file
@@ -0,0 +1,74 @@
<div class="layui-fluid layui-anim febs-anim" id="hlm-voucher-button" lay-title="一键卖出">
    <div class="layui-row layui-col-space8 febs-container">
        <form class="layui-form" action="" lay-filter="hlm-voucher-button-form">
            <div class="layui-card">
                <div class="layui-card-body">
                    <blockquote class="layui-elem-quote blue-border">绿色积分凭证</blockquote>
                    <div class="layui-form-item">
                        <div class="layui-inline">
                            <label class="layui-form-label febs-form-item-require">价格:</label>
                            <div class="layui-form-mid layui-word-aux">当前价格:</div>
                            <div class="layui-input-inline">
                                <input type="text" name="scorePrice" lay-verify="required|integer" placeholder="请输入数字" autocomplete="off" class="layui-input" readonly>
                            </div>
                            <div class="layui-form-mid layui-word-aux">剩余:</div>
                        </div>
                    </div>
                    <div class="layui-card-footer">
                        <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="hlm-voucher-button-submit" id="submit">保存</button>
                    </div>
                    <div class="layui-card-footer">
                        <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="hlm-voucher-button-submit" id="submit">确认一键卖出</button>
                    </div>
                </div>
            </div>
        </form>
    </div>
</div>
<style>
    .layui-form-label {
        width: 120px;
    }
    .layui-form-item .layui-input-block {
        margin-left: 150px;
    }
    .layui-table-form .layui-form-item {
        margin-bottom: 20px !important;
    }
</style>
<script data-th-inline="javascript" type="text/javascript">
    layui.use(['dropdown', 'jquery', 'febs', 'form', 'eleTree'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            form = layui.form,
            hlmVoucherSet = [[${hlmVoucherSetDto}]],
            $view = $('#hlm-voucher-button');
        form.verify({
            integer: [
                /^[1-9]\d*$/
                , '只能输入正整数'
            ]
        });
        initHlmVoucherSetValue();
        form.render();
        function initHlmVoucherSetValue() {
            form.val("hlm-voucher-button-form", {
                "roleReleasePercent": hlmVoucherSet.roleReleasePercent
            });
        }
        form.on('submit(hlm-voucher-button-submit)', function (data) {
            febs.post(ctx + 'admin/system/hlmVoucherSet', data.field, function (res) {
                febs.alert.success('设置成功');
                return ;
            });
            return false;
        });
    });
</script>
src/main/resources/templates/febs/views/modules/system/hlmVoucherSet.html
New file
@@ -0,0 +1,142 @@
<div class="layui-fluid layui-anim febs-anim" id="hlm-voucher-set" lay-title="绿色积分凭证">
    <div class="layui-row layui-col-space8 febs-container">
        <form class="layui-form" action="" lay-filter="hlm-voucher-set-form">
            <div class="layui-card">
                <div class="layui-card-body">
                    <blockquote class="layui-elem-quote blue-border">绿色积分凭证</blockquote>
                    <div class="layui-form-item">
                        <div class="layui-inline">
                            <label class="layui-form-label febs-form-item-require">详情:</label>
                            <div class="layui-form-mid layui-word-aux">总数:</div>
                            <div class="layui-input-inline">
                                <input type="text" name="totalCnt" lay-verify="required|integer" placeholder="请输入数字" autocomplete="off" class="layui-input" readonly>
                            </div>
                            <div class="layui-form-mid layui-word-aux">剩余:</div>
                            <div class="layui-input-inline">
                                <input type="text" name="surplusCnt" lay-verify="required|integer" placeholder="请输入数字" autocomplete="off" class="layui-input" readonly>
                            </div>
                        </div>
                    </div>
                    <blockquote class="layui-elem-quote blue-border">联创、合伙人每日拨付比例</blockquote>
                    <div class="layui-form-item">
                        <label class="layui-form-label febs-form-item-require">比例:</label>
                        <div class="layui-input-block">
                            <input type="text" name="roleReleasePercent" lay-verify="required" placeholder="请输入数字" autocomplete="off" class="layui-input" >
                            <div class="layui-word-aux">设置1,每日拨付千分之1</div>
                        </div>
                    </div>
                    <blockquote class="layui-elem-quote blue-border">业绩产生积分凭证设置一</blockquote>
                    <div class="layui-form-item">
                        <label class="layui-form-label febs-form-item-require">比例:</label>
                        <div class="layui-form-mid layui-word-aux">每日总释放积分凭证比例(万分之几):</div>
                        <div class="layui-input-inline">
                            <input type="text" name="achieveReleasePercent" lay-verify="required" placeholder="请输入数字" autocomplete="off" class="layui-input" >
                        </div>
                        <div class="layui-form-mid layui-word-aux">例如:1,则表示总凭证数3000000*0.9*0.0001</div>
                    </div>
                    <div class="layui-form-item">
                        <label class="layui-form-label febs-form-item-require">规则一:</label>
                        <div class="layui-form-mid layui-word-aux">业绩大于最小值:</div>
                        <div class="layui-input-inline">
                            <input type="text" name="achieveMin" lay-verify="required|integer" placeholder="请输入数字" autocomplete="off" class="layui-input">
                        </div>
                        <div class="layui-form-mid layui-word-aux">才释放积分凭证。</div>
                    </div>
                    <div class="layui-form-item">
                        <label class="layui-form-label febs-form-item-require">规则二:</label>
                        <div class="layui-form-mid layui-word-aux">业绩大于、等于最大值:</div>
                        <div class="layui-input-inline">
                            <input type="text" name="achieveMax" lay-verify="required|integer" placeholder="请输入数字" autocomplete="off" class="layui-input">
                        </div>
                        <div class="layui-form-mid layui-word-aux">释放今日的全额积分凭证。</div>
                    </div>
                    <blockquote class="layui-elem-quote blue-border">业绩产生积分凭证设置二</blockquote>
                    <div class="layui-form-item">
                        <label class="layui-form-label febs-form-item-require">比例一:</label>
                        <div class="layui-form-mid layui-word-aux">业绩积分凭证每日释放联创、合伙人的比例:</div>
                        <div class="layui-input-inline">
                            <input type="text" name="roleAchievePercent" lay-verify="required" placeholder="请输入数字" autocomplete="off" class="layui-input" >
                        </div>
                        <div class="layui-form-mid layui-word-aux">设置20,则表示比例为20%</div>
                    </div>
                    <div class="layui-form-item">
                        <label class="layui-form-label febs-form-item-require">比例二:</label>
                        <div class="layui-form-mid layui-word-aux">业绩积分凭证按贡献点比例:</div>
                        <div class="layui-input-inline">
                            <input type="text" name="starAchievePercent" lay-verify="required" placeholder="请输入数字" autocomplete="off" class="layui-input" >
                        </div>
                        <div class="layui-form-mid layui-word-aux">设置20,则表示比例为20%</div>
                    </div>
                    <div class="layui-form-item">
                        <label class="layui-form-label febs-form-item-require">比例三:</label>
                        <div class="layui-form-mid layui-word-aux">业绩积分凭证按用户星级比例:</div>
                        <div class="layui-input-inline">
                            <input type="text" name="levelAchievePercent" lay-verify="required" placeholder="请输入数字" autocomplete="off" class="layui-input" >
                        </div>
                        <div class="layui-form-mid layui-word-aux">。设置20,则表示比例为20%</div>
                    </div>
                    <div class="layui-card-footer">
                        <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="hlm-voucher-set-submit" id="submit">保存</button>
                    </div>
                </div>
            </div>
        </form>
    </div>
</div>
<style>
    .layui-form-label {
        width: 120px;
    }
    .layui-form-item .layui-input-block {
        margin-left: 150px;
    }
    .layui-table-form .layui-form-item {
        margin-bottom: 20px !important;
    }
</style>
<script data-th-inline="javascript" type="text/javascript">
    layui.use(['dropdown', 'jquery', 'febs', 'form', 'eleTree'], function () {
        var $ = layui.jquery,
            febs = layui.febs,
            form = layui.form,
            hlmVoucherSet = [[${hlmVoucherSetDto}]],
            $view = $('#hlm-voucher-set');
        form.verify({
            integer: [
                /^[1-9]\d*$/
                , '只能输入正整数'
            ]
        });
        initHlmVoucherSetValue();
        form.render();
        function initHlmVoucherSetValue() {
            form.val("hlm-voucher-set-form", {
                "levelAchievePercent": hlmVoucherSet.levelAchievePercent,
                "starAchievePercent": hlmVoucherSet.starAchievePercent,
                "roleAchievePercent": hlmVoucherSet.roleAchievePercent,
                "achieveReleasePercent": hlmVoucherSet.achieveReleasePercent,
                "achieveMin": hlmVoucherSet.achieveMin,
                "achieveMax": hlmVoucherSet.achieveMax,
                "totalCnt": hlmVoucherSet.totalCnt,
                "surplusCnt": hlmVoucherSet.surplusCnt,
                "roleReleasePercent": hlmVoucherSet.roleReleasePercent
            });
        }
        form.on('submit(hlm-voucher-set-submit)', function (data) {
            febs.post(ctx + 'admin/system/hlmVoucherSet', data.field, function (res) {
                febs.alert.success('设置成功');
                return ;
            });
            return false;
        });
    });
</script>
src/test/java/cc/mrbird/febs/AgentTest.java
@@ -623,6 +623,6 @@
    @Test
    public void orderReturnTest() {
        agentConsumer.orderReturnMoney("7");
//        agentConsumer.orderReturnMoney("7");
    }
}
src/test/java/cc/mrbird/febs/ProfitTest.java
@@ -55,7 +55,11 @@
    @Test
    public void dynamicProfit() {
        agentProducer.sendPerkMoneyMsg(679L);
        agentService.perkMoneyConsumer(Long.parseLong("712"));
//        memberProfitService.dynamicProfit(Long.parseLong("709"));
//        memberProfitService.scoreRecordReleaseJob();
//        memberProfitService.achieveReleaseJob();
//        agentProducer.sendPerkMoneyMsg(679L);
//        agentService.perkMoneyConsumer(665L);
//        memberProfitService.teamEqualsPerkJob(null);
//        List<MallMember> mallMemberTeamPerk = new ArrayList<>();