src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java
@@ -143,4 +143,25 @@ } //补贴金额 end /** * 强制卖出 * @return */ //强制卖出 start @Bean public DirectExchange forceVoucherSaleExchange() { return new DirectExchange(RabbitQueueEnum.FORCE_VOUCHER_SALE.getExchange()); } @Bean public Queue forceVoucherSaleQueue() { return new Queue(QueueConstants.FORCE_VOUCHER_SALE); } @Bean public Binding forceVoucherSaleBind() { return BindingBuilder.bind(forceVoucherSaleQueue()).to(forceVoucherSaleExchange()).with(RabbitQueueEnum.FORCE_VOUCHER_SALE.getRoute()); } //强制卖出 end } src/main/java/cc/mrbird/febs/common/enumerates/FlowTypeEnum.java
@@ -37,7 +37,11 @@ /** * 凭证数量 */ VOUCHER_CNT(7); VOUCHER_CNT(7), /** * 凭证数量 */ VOUCHER_AMOUNT(8); private final int value; src/main/java/cc/mrbird/febs/common/enumerates/GreenScoreEnum.java
@@ -8,6 +8,14 @@ @Getter public enum GreenScoreEnum { /** * 绿色凭证提现开关 1:开启 2:关闭 */ VOUCHER_ON_OFF("GREEN_SCORE", "VOUCHER_ON_OFF"), /** * 绿色凭证买卖池 */ SCORE_POOL_CNT("GREEN_SCORE", "SCORE_POOL_CNT"), /** * 绿色凭证价格 */ SCORE_PRICE("GREEN_SCORE", "SCORE_PRICE"), src/main/java/cc/mrbird/febs/common/enumerates/MoneyFlowTypeEnum.java
@@ -178,7 +178,17 @@ /** * 业绩释放星级凭证 */ ACHIEVE_RELEASE_SCORE_XJ(35); ACHIEVE_RELEASE_SCORE_XJ(35), /** * 凭证买入 */ VOUCHER_BUY(36), /** * 凭证卖出 */ VOUCHER_SALE(37); private final int value; src/main/java/cc/mrbird/febs/mall/controller/AdminSystemController.java
@@ -4,8 +4,12 @@ import cc.mrbird.febs.common.enumerates.DataDictionaryEnum; import cc.mrbird.febs.common.enumerates.GreenScoreEnum; import cc.mrbird.febs.mall.dto.*; import cc.mrbird.febs.mall.entity.DataDictionaryCustom; import cc.mrbird.febs.mall.mapper.DataDictionaryCustomMapper; import cc.mrbird.febs.mall.service.ICommonService; import cc.mrbird.febs.mall.service.IMemberProfitService; import cc.mrbird.febs.mall.service.ISystemService; import cc.mrbird.febs.rabbit.producter.AgentProducer; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -29,6 +33,13 @@ private ISystemService systemService; private final ICommonService commonService; @Autowired private IMemberProfitService memberProfitService; private final AgentProducer agentProducer; private final DataDictionaryCustomMapper dataDictionaryCustomMapper; @PostMapping(value = "/bonusSystemSetting") public FebsResponse bonusSystemSetting(@RequestBody Map<String, Object> map) { @@ -146,4 +157,33 @@ hlmVoucherSetDto.getLevelAchievePercent()); return new FebsResponse().success(); } @PostMapping(value = "/hlmVoucherButton") public FebsResponse hlmVoucherButton(HlmVoucherButtonDto hlmVoucherButtonDto) { BigDecimal scorePrice = new BigDecimal(hlmVoucherButtonDto.getScorePrice()); if(scorePrice.compareTo(BigDecimal.ZERO) <= 0){ return new FebsResponse().fail().message("请输入合理的价格"); } commonService.updateDataDic( GreenScoreEnum.SCORE_PRICE.getType(), GreenScoreEnum.SCORE_PRICE.getCode(), hlmVoucherButtonDto.getScorePrice()); commonService.updateDataDic( GreenScoreEnum.VOUCHER_ON_OFF.getType(), GreenScoreEnum.VOUCHER_ON_OFF.getCode(), hlmVoucherButtonDto.getVoucherOnOff()); return new FebsResponse().success(); } @PostMapping(value = "/selaHalfVoucher") public FebsResponse selaHalfVoucher() { DataDictionaryCustom scorePriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( GreenScoreEnum.SCORE_PRICE.getType(), GreenScoreEnum.SCORE_PRICE.getCode() ); agentProducer.sendForceVoucherSaleMsg(scorePriceDic.getValue()); return new FebsResponse().success(); } } src/main/java/cc/mrbird/febs/mall/controller/ApiMallMemberController.java
@@ -215,4 +215,6 @@ return memberService.delMemberBank(id); } } src/main/java/cc/mrbird/febs/mall/controller/ApiScoreController.java
@@ -2,12 +2,12 @@ import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.mall.dto.ApiMallScoreSignRecordDto; import cc.mrbird.febs.mall.dto.ApiScoreVoucherRecordDto; import cc.mrbird.febs.mall.dto.ApiVoucherBusinessDto; import cc.mrbird.febs.mall.dto.OrderListDto; import cc.mrbird.febs.mall.service.ICommonService; import cc.mrbird.febs.mall.service.IScoreService; import cc.mrbird.febs.mall.vo.ApiMallScoreSignRecordVo; import cc.mrbird.febs.mall.vo.OrderListVo; import cc.mrbird.febs.mall.vo.ScoreSignVo; import cc.mrbird.febs.mall.vo.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; @@ -17,6 +17,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; /** * @author wzy @@ -57,4 +59,35 @@ public FebsResponse signRecordList(@RequestBody ApiMallScoreSignRecordDto apiMallScoreSignRecordDto) { return new FebsResponse().success().data(scoreService.findMallScoreSignRecordList(apiMallScoreSignRecordDto)); } @ApiOperation(value = "绿色积分个人信息", notes = "绿色积分个人信息") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = ApiScoreVoucherInfoVo.class) }) @GetMapping(value = "/memberScoreVoucher") public FebsResponse memberScoreVoucher() { return new FebsResponse().success().data(scoreService.memberScoreVoucher()); } @ApiOperation(value = "绿色积分个人信息-买卖信息", notes = "绿色积分个人信息-买卖信息") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = ApiScoreVoucherRecordVo.class) }) @PostMapping(value = "/memberScoreVoucher") public FebsResponse memberScoreVoucher(@RequestBody ApiScoreVoucherRecordDto apiScoreVoucherRecordDto) { return new FebsResponse().success().data(scoreService.findMallScoreVoucherList(apiScoreVoucherRecordDto)); } @ApiOperation(value = "绿色积分个人信息-买入", notes = "绿色积分个人信息-买入") @PostMapping(value = "/voucherBusinessBuy") public FebsResponse voucherBusinessBuy(@Valid @RequestBody ApiVoucherBusinessDto apiVoucherBusinessDto) { return scoreService.voucherBusinessBuy(apiVoucherBusinessDto); } @ApiOperation(value = "绿色积分个人信息-卖出", notes = "绿色积分个人信息-卖出") @PostMapping(value = "/voucherBusinessSale") public FebsResponse voucherBusinessSale(@Valid @RequestBody ApiVoucherBusinessDto apiVoucherBusinessDto) { return scoreService.voucherBusinessSale(apiVoucherBusinessDto); } } src/main/java/cc/mrbird/febs/mall/controller/ViewSystemController.java
@@ -291,7 +291,41 @@ String levelAchievePercent = ObjectUtil.isEmpty(levelAchievePercentDic.getValue()) ? "0" : levelAchievePercentDic.getValue(); hlmVoucherSetDto.setLevelAchievePercent(levelAchievePercent); } DataDictionaryCustom scorePoolCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( GreenScoreEnum.SCORE_POOL_CNT.getType(), GreenScoreEnum.SCORE_POOL_CNT.getCode()); if (scorePoolCntDic != null) { String scorePoolCnt = ObjectUtil.isEmpty(scorePoolCntDic.getValue()) ? "0" : scorePoolCntDic.getValue(); hlmVoucherSetDto.setScorePoolCnt(scorePoolCnt); } model.addAttribute("hlmVoucherSetDto", hlmVoucherSetDto); return FebsUtil.view("modules/system/hlmVoucherSet"); } /** * 一键卖出 * @param model * @return */ @GetMapping("hlmVoucherButton") @RequiresPermissions("hlmVoucherButton:view") public String hlmVoucherButton(Model model) { HlmVoucherButtonDto hlmVoucherButtonDto = new HlmVoucherButtonDto(); DataDictionaryCustom scorePriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( GreenScoreEnum.SCORE_PRICE.getType(), GreenScoreEnum.SCORE_PRICE.getCode()); if (scorePriceDic != null) { String scorePrice = ObjectUtil.isEmpty(scorePriceDic.getValue()) ? "0" : scorePriceDic.getValue(); hlmVoucherButtonDto.setScorePrice(scorePrice); } DataDictionaryCustom voucherOnOffDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( GreenScoreEnum.VOUCHER_ON_OFF.getType(), GreenScoreEnum.VOUCHER_ON_OFF.getCode()); if (voucherOnOffDic != null) { String voucherOnOff = ObjectUtil.isEmpty(voucherOnOffDic.getValue()) ? "0" : voucherOnOffDic.getValue(); hlmVoucherButtonDto.setVoucherOnOff(voucherOnOff); } model.addAttribute("hlmVoucherButtonDto", hlmVoucherButtonDto); return FebsUtil.view("modules/system/hlmVoucherButton"); } } src/main/java/cc/mrbird/febs/mall/dto/AddMemberBankDto.java
@@ -20,6 +20,9 @@ // 银行卡号 @ApiModelProperty(value = "银行卡号") private String bankNo; // 银行卡号 @ApiModelProperty(value = "数字账号") private String digitalNo; // 手机号 @ApiModelProperty(value = "手机号") private String phone; src/main/java/cc/mrbird/febs/mall/dto/ApiScoreVoucherRecordDto.java
New file @@ -0,0 +1,17 @@ package cc.mrbird.febs.mall.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @ApiModel(value = "ApiScoreVoucherRecordDto", description = "请求类") public class ApiScoreVoucherRecordDto { @ApiModelProperty(value = "一页数量", example = "10") private Integer pageSize; @ApiModelProperty(value = "第几页", example = "1") private Integer pageNum; } src/main/java/cc/mrbird/febs/mall/dto/ApiVoucherBusinessDto.java
New file @@ -0,0 +1,30 @@ package cc.mrbird.febs.mall.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.math.BigDecimal; @Data @ApiModel(value = "ApiVoucherBusinessDto", description = "请求类") public class ApiVoucherBusinessDto { /** * B:买入S:卖出 */ @ApiModelProperty(value = "B:买入S:卖出") @NotBlank(message = "请选择买入") private String type; @ApiModelProperty(value = "数量") @NotNull(message = "请输入合理的数量") private BigDecimal voucherCnt; @ApiModelProperty(value = "交易密码") @NotBlank(message = "请输入支付密码") private String tradePassword; } src/main/java/cc/mrbird/febs/mall/dto/HlmVoucherButtonDto.java
New file @@ -0,0 +1,17 @@ package cc.mrbird.febs.mall.dto; import lombok.Data; @Data public class HlmVoucherButtonDto { /** * 绿色凭证价格 */ private String scorePrice; /** * 绿色凭证提现开关 1:开启 2:关闭 */ private String voucherOnOff; } src/main/java/cc/mrbird/febs/mall/dto/HlmVoucherSetDto.java
@@ -42,5 +42,9 @@ * 业绩积分凭证按用户星级比例 */ private String levelAchievePercent; /** * 绿色凭证买卖池 */ private String scorePoolCnt; } src/main/java/cc/mrbird/febs/mall/dto/UpdateMemberBankDto.java
@@ -25,4 +25,7 @@ // 手机号 @ApiModelProperty(value = "手机号") private String phone; // 银行卡号 @ApiModelProperty(value = "数字账号") private String digitalNo; } src/main/java/cc/mrbird/febs/mall/entity/MallMemberBank.java
@@ -18,4 +18,5 @@ private String bankNo; // 手机号 private String phone; private String digitalNo; } src/main/java/cc/mrbird/febs/mall/entity/MallScoreVoucher.java
New file @@ -0,0 +1,34 @@ 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_voucher") public class MallScoreVoucher extends BaseEntity { private String voucherNo; private Long memberId; /** * B:买入S:卖出 */ private String type; /** * 数量 */ private BigDecimal voucherCnt; /** * 单价 */ private BigDecimal price; /** * 总价 */ private BigDecimal voucherAmount; } src/main/java/cc/mrbird/febs/mall/mapper/DataDictionaryCustomMapper.java
@@ -31,4 +31,6 @@ AdminRankAwardUpdateInfoVo getRankAwardUpdateInfoById(@Param("id")long id); int updateDicValueByTypeAndCode(@Param("type") String type, @Param("code") String code, @Param("value") String value); DataDictionaryCustom selectScorePoolCntForUpdate(@Param("type") String type, @Param("code") String code); } src/main/java/cc/mrbird/febs/mall/mapper/MallMemberWalletMapper.java
@@ -47,4 +47,6 @@ BigDecimal selectSumStar(); List<MallMemberWallet> selectStar(); void addVorCherAmountAndCntById(@Param("voucherAmount")BigDecimal voucherAmountAdd,@Param("voucherCnt")BigDecimal voucherCnt, @Param("id")Long id); } src/main/java/cc/mrbird/febs/mall/mapper/MallScoreVoucherMapper.java
New file @@ -0,0 +1,14 @@ package cc.mrbird.febs.mall.mapper; import cc.mrbird.febs.mall.dto.ApiScoreVoucherRecordDto; import cc.mrbird.febs.mall.entity.MallScoreVoucher; import cc.mrbird.febs.mall.vo.ApiScoreVoucherRecordVo; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import org.apache.ibatis.annotations.Param; public interface MallScoreVoucherMapper extends BaseMapper<MallScoreVoucher> { IPage<ApiScoreVoucherRecordVo> findMallScoreVoucherListInPage(IPage<ApiScoreVoucherRecordVo> page, @Param("record")ApiScoreVoucherRecordDto apiScoreVoucherRecordDto); } src/main/java/cc/mrbird/febs/mall/service/IMemberProfitService.java
@@ -53,4 +53,6 @@ void scoreRecordReleaseJob(); void achieveReleaseJob(); void selaHalfVoucher(String price); } src/main/java/cc/mrbird/febs/mall/service/IScoreService.java
@@ -1,8 +1,13 @@ package cc.mrbird.febs.mall.service; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.mall.dto.ApiMallScoreSignRecordDto; import cc.mrbird.febs.mall.dto.ApiScoreVoucherRecordDto; import cc.mrbird.febs.mall.dto.ApiVoucherBusinessDto; import cc.mrbird.febs.mall.entity.MallScoreSignRecord; import cc.mrbird.febs.mall.vo.ApiMallScoreSignRecordVo; import cc.mrbird.febs.mall.vo.ApiScoreVoucherInfoVo; import cc.mrbird.febs.mall.vo.ApiScoreVoucherRecordVo; import cc.mrbird.febs.mall.vo.ScoreSignVo; import java.util.List; @@ -16,4 +21,12 @@ MallScoreSignRecord judgeScoreIsContinuity(MallScoreSignRecord mallScoreSignRecord); List<ApiMallScoreSignRecordVo> findMallScoreSignRecordList(ApiMallScoreSignRecordDto apiMallScoreSignRecordDto); ApiScoreVoucherInfoVo memberScoreVoucher(); List<ApiScoreVoucherRecordVo> findMallScoreVoucherList(ApiScoreVoucherRecordDto apiScoreVoucherRecordDto); FebsResponse voucherBusinessBuy(ApiVoucherBusinessDto apiVoucherBusinessDto); FebsResponse voucherBusinessSale(ApiVoucherBusinessDto apiVoucherBusinessDto); } src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java
@@ -613,6 +613,7 @@ mallMemberBank.setIdCardNum(updateMemberBankDto.getIdCardNum()); mallMemberBank.setBankNo(updateMemberBankDto.getBankNo()); mallMemberBank.setPhone(updateMemberBankDto.getPhone()); mallMemberBank.setDigitalNo(updateMemberBankDto.getDigitalNo()); mallMemberBankMapper.updateById(mallMemberBank); return new FebsResponse().success(); } src/main/java/cc/mrbird/febs/mall/service/impl/MemberProfitServiceImpl.java
@@ -58,6 +58,7 @@ private final AgentProducer agentProducer; private final MallScoreRecordMapper mallScoreRecordMapper; private final MallScoreAchieveReleaseMapper mallScoreAchieveReleaseMapper; private final MallScoreVoucherMapper mallScoreVoucherMapper; @Override @Transactional(rollbackFor = Exception.class) @@ -789,6 +790,7 @@ } @Override @Transactional(rollbackFor = Exception.class) public void scoreRecordReleaseJob() { /** * 每日按照比例释放记录的百分比到用户的绿色凭证账户 @@ -831,6 +833,7 @@ } @Override @Transactional(rollbackFor = Exception.class) public void achieveReleaseJob() { /** * 业绩产生凭证 @@ -1009,6 +1012,82 @@ } @Override @Transactional(rollbackFor = Exception.class) public void selaHalfVoucher(String price) { /** * 获取所有凭证大于0的用户 * 当前价格卖出账户的一半凭证 */ BigDecimal scorePrice = new BigDecimal(price == null ? "0" : price); if(scorePrice.compareTo(BigDecimal.ZERO) <= 0){ return; } List<MallMemberWallet> mallMemberWallets = mallMemberWalletMapper.selectList(null); if(CollUtil.isNotEmpty(mallMemberWallets)){ List<MallMemberWallet> wallets = mallMemberWallets .stream() .filter(mallMemberWallet -> mallMemberWallet.getVoucherCnt().compareTo(BigDecimal.ZERO) > 0) .collect(Collectors.toList()); if(CollUtil.isNotEmpty(wallets)){ BigDecimal scorePoolCntAdd = BigDecimal.ZERO; //绿色积分剩余数量 for(MallMemberWallet mallMemberWallet : wallets){ //增加账户的凭证金额,减少当前的一半的凭证数量 BigDecimal voucherCnt = mallMemberWallet.getVoucherCnt().divide(new BigDecimal(2), 2, BigDecimal.ROUND_DOWN) .setScale(2,BigDecimal.ROUND_DOWN); BigDecimal voucherAmountAdd = scorePrice.multiply(voucherCnt) .setScale(2,BigDecimal.ROUND_DOWN); mallMemberWalletMapper.addVorCherAmountAndCntById(voucherAmountAdd,voucherCnt,mallMemberWallet.getId()); scorePoolCntAdd = scorePoolCntAdd.add(voucherCnt); DataDictionaryCustom surplusCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( GreenScoreEnum.SURPLUS_CNT.getType(), GreenScoreEnum.SURPLUS_CNT.getCode() ); //增加绿色积分剩余数量 BigDecimal surplusCnt = new BigDecimal(surplusCntDic.getValue() == null ? "0" : surplusCntDic.getValue()); BigDecimal voucherCntAdd = surplusCnt.add(voucherCnt).setScale(2,BigDecimal.ROUND_DOWN); surplusCntDic.setValue(voucherCntAdd.toString()); dataDictionaryCustomMapper.updateById(surplusCntDic); /** * 生成一条卖出记录 */ String voucherNo = MallUtils.getOrderNum("VS"); MallScoreVoucher mallScoreVoucher = new MallScoreVoucher(); mallScoreVoucher.setVoucherNo(voucherNo); mallScoreVoucher.setMemberId(mallMemberWallet.getMemberId()); mallScoreVoucher.setVoucherCnt(voucherCnt); mallScoreVoucher.setPrice(scorePrice); mallScoreVoucher.setVoucherAmount(voucherAmountAdd); mallScoreVoucher.setType("S"); mallScoreVoucherMapper.insert(mallScoreVoucher); //产生一条流水记录 mallMoneyFlowService.addMoneyFlow( mallMemberWallet.getMemberId(), voucherAmountAdd, MoneyFlowTypeEnum.VOUCHER_SALE.getValue(), voucherNo, FlowTypeEnum.VOUCHER_AMOUNT.getValue()); } //增加积分凭证池的凭证数量 DataDictionaryCustom scorePoolCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( GreenScoreEnum.SCORE_POOL_CNT.getType(), GreenScoreEnum.SCORE_POOL_CNT.getCode() ); //增加绿色积分剩余数量 BigDecimal scorePoolCnt = new BigDecimal(scorePoolCntDic.getValue() == null ? "0" : scorePoolCntDic.getValue()); scorePoolCnt = scorePoolCnt.add(scorePoolCntAdd); scorePoolCntDic.setValue(scorePoolCnt.toString()); dataDictionaryCustomMapper.updateById(scorePoolCntDic); } } } /** * 给用户的增加凭证数据,并且增加流水 * @param memberAchieveRelease 释放数量 src/main/java/cc/mrbird/febs/mall/service/impl/ScoreServiceImpl.java
@@ -1,28 +1,34 @@ package cc.mrbird.febs.mall.service.impl; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.enumerates.DataDictionaryEnum; 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; import cc.mrbird.febs.common.utils.MallUtils; import cc.mrbird.febs.mall.conversion.MallOrderInfoConversion; import cc.mrbird.febs.mall.dto.ApiMallScoreSignRecordDto; import cc.mrbird.febs.mall.dto.ApiScoreVoucherRecordDto; import cc.mrbird.febs.mall.dto.ApiVoucherBusinessDto; import cc.mrbird.febs.mall.dto.ScoreSettingDto; import cc.mrbird.febs.mall.entity.*; import cc.mrbird.febs.mall.mapper.DataDictionaryCustomMapper; import cc.mrbird.febs.mall.mapper.MallMemberMapper; import cc.mrbird.febs.mall.mapper.MallMemberWalletMapper; import cc.mrbird.febs.mall.mapper.MallScoreSignRecordMapper; import cc.mrbird.febs.mall.mapper.*; import cc.mrbird.febs.mall.service.IApiMallMemberService; import cc.mrbird.febs.mall.service.IApiMallMemberWalletService; import cc.mrbird.febs.mall.service.IMallMoneyFlowService; import cc.mrbird.febs.mall.service.IScoreService; import cc.mrbird.febs.mall.vo.ApiMallScoreSignRecordVo; import cc.mrbird.febs.mall.vo.ApiScoreVoucherInfoVo; import cc.mrbird.febs.mall.vo.ApiScoreVoucherRecordVo; import cc.mrbird.febs.mall.vo.ScoreSignVo; import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -51,6 +57,8 @@ private final IMallMoneyFlowService mallMoneyFlowService; private final IApiMallMemberWalletService walletService; private final MallMemberMapper mallMemberMapper; private final MallScoreVoucherMapper mallScoreVoucherMapper; private final IApiMallMemberWalletService memberWalletService; @Override public ScoreSignVo scoreSign() { @@ -94,6 +102,167 @@ } @Override public ApiScoreVoucherInfoVo memberScoreVoucher() { MallMember member = LoginUserUtil.getLoginUser(); ApiScoreVoucherInfoVo apiScoreVoucherInfoVo = new ApiScoreVoucherInfoVo(); MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(member.getId()); apiScoreVoucherInfoVo.setVoucherCnt(mallMemberWallet.getVoucherCnt().compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : mallMemberWallet.getVoucherCnt()); apiScoreVoucherInfoVo.setVoucherAmount(mallMemberWallet.getVoucherAmount().compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : mallMemberWallet.getVoucherAmount()); DataDictionaryCustom scorePriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( GreenScoreEnum.SCORE_PRICE.getType(), GreenScoreEnum.SCORE_PRICE.getCode()); apiScoreVoucherInfoVo.setScorePrice(new BigDecimal(scorePriceDic.getValue()).setScale(2,BigDecimal.ROUND_DOWN)); DataDictionaryCustom scorePoolCntDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( GreenScoreEnum.SCORE_POOL_CNT.getType(), GreenScoreEnum.SCORE_POOL_CNT.getCode()); apiScoreVoucherInfoVo.setScorePoolCnt(new BigDecimal(scorePoolCntDic.getValue()).setScale(2,BigDecimal.ROUND_DOWN)); return apiScoreVoucherInfoVo; } @Override public List<ApiScoreVoucherRecordVo> findMallScoreVoucherList(ApiScoreVoucherRecordDto apiScoreVoucherRecordDto) { IPage<ApiScoreVoucherRecordVo> page = new Page<>(apiScoreVoucherRecordDto.getPageNum(), apiScoreVoucherRecordDto.getPageSize()); IPage<ApiScoreVoucherRecordVo> apiScoreVoucherRecordVoIPage = mallScoreVoucherMapper.findMallScoreVoucherListInPage(page, apiScoreVoucherRecordDto); return apiScoreVoucherRecordVoIPage.getRecords(); } @Override @Transactional(rollbackFor = Exception.class) public FebsResponse voucherBusinessBuy(ApiVoucherBusinessDto apiVoucherBusinessDto) { Long memberId = LoginUserUtil.getLoginUser().getId(); BigDecimal voucherCnt = apiVoucherBusinessDto.getVoucherCnt(); if(voucherCnt.compareTo(BigDecimal.ZERO) <= 0){ throw new FebsException("请输入合理的数量"); } DataDictionaryCustom scorePoolCntDic = dataDictionaryCustomMapper.selectScorePoolCntForUpdate( GreenScoreEnum.SCORE_POOL_CNT.getType(), GreenScoreEnum.SCORE_POOL_CNT.getCode()); BigDecimal scorePoolCnt = new BigDecimal(scorePoolCntDic.getValue() == null ? "0" : scorePoolCntDic.getValue()); if(scorePoolCnt.compareTo(voucherCnt) < 0){ throw new FebsException("可购买总量不足"); } String tradePassword = apiVoucherBusinessDto.getTradePassword(); if (StrUtil.isBlank(tradePassword)) { throw new FebsException("支付密码错误"); } MallMember mallMember = mallMemberMapper.selectById(memberId); if (StrUtil.isBlank(mallMember.getTradePassword())) { throw new FebsException("未设置支付密码"); } if (!SecureUtil.md5(tradePassword).equals(mallMember.getTradePassword())) { throw new FebsException("支付密码错误"); } DataDictionaryCustom scorePriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( GreenScoreEnum.SCORE_PRICE.getType(), GreenScoreEnum.SCORE_PRICE.getCode()); BigDecimal scorePrice = new BigDecimal(scorePriceDic.getValue()).setScale(2, BigDecimal.ROUND_DOWN); BigDecimal voucherAmount = voucherCnt.multiply(scorePrice); MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId); BigDecimal balance = mallMemberWallet.getBalance(); if(voucherAmount.compareTo(balance) > 0){ throw new FebsException("余额不足"); } //减少余额 memberWalletService.reduceBalance(voucherAmount,memberId); //减少绿色积分池 scorePoolCnt = scorePoolCnt.subtract(voucherCnt); scorePoolCntDic.setValue(scorePoolCnt.toString()); dataDictionaryCustomMapper.updateById(scorePoolCntDic); //增加凭证数量 mallMemberWalletMapper.addVorCherCntByMemberId(voucherCnt,memberId); //增加购买记录 String voucherNo = MallUtils.getOrderNum("VB"); MallScoreVoucher mallScoreVoucher = new MallScoreVoucher(); mallScoreVoucher.setVoucherNo(voucherNo); mallScoreVoucher.setMemberId(memberId); mallScoreVoucher.setVoucherCnt(voucherCnt); mallScoreVoucher.setPrice(scorePrice); mallScoreVoucher.setVoucherAmount(voucherAmount); mallScoreVoucher.setType("B"); mallScoreVoucherMapper.insert(mallScoreVoucher); //产生一条流水记录 mallMoneyFlowService.addMoneyFlow( mallMemberWallet.getMemberId(), voucherCnt, MoneyFlowTypeEnum.VOUCHER_BUY.getValue(), voucherNo, FlowTypeEnum.VOUCHER_CNT.getValue()); return new FebsResponse().success().message("操作成功"); } @Override @Transactional(rollbackFor = Exception.class) public FebsResponse voucherBusinessSale(ApiVoucherBusinessDto apiVoucherBusinessDto) { Long memberId = LoginUserUtil.getLoginUser().getId(); BigDecimal voucherCnt = apiVoucherBusinessDto.getVoucherCnt(); if(voucherCnt.compareTo(BigDecimal.ZERO) <= 0){ throw new FebsException("请输入合理的数量"); } String tradePassword = apiVoucherBusinessDto.getTradePassword(); if (StrUtil.isBlank(tradePassword)) { throw new FebsException("支付密码错误"); } MallMember mallMember = mallMemberMapper.selectById(memberId); if (StrUtil.isBlank(mallMember.getTradePassword())) { throw new FebsException("未设置支付密码"); } if (!SecureUtil.md5(tradePassword).equals(mallMember.getTradePassword())) { throw new FebsException("支付密码错误"); } MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId); BigDecimal voucherCntMember = mallMemberWallet.getVoucherCnt(); if(voucherCntMember.compareTo(voucherCnt) < 0){ throw new FebsException("绿色积分不足"); } DataDictionaryCustom scorePriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode( GreenScoreEnum.SCORE_PRICE.getType(), GreenScoreEnum.SCORE_PRICE.getCode()); BigDecimal scorePrice = new BigDecimal(scorePriceDic.getValue()).setScale(2, BigDecimal.ROUND_DOWN); BigDecimal voucherAmount = voucherCnt.multiply(scorePrice); //减少凭证积分 //增加凭证现金 mallMemberWalletMapper.addVorCherAmountAndCntById(voucherAmount,voucherCnt,mallMemberWallet.getId()); //增加积分池 DataDictionaryCustom scorePoolCntDic = dataDictionaryCustomMapper.selectScorePoolCntForUpdate( GreenScoreEnum.SCORE_POOL_CNT.getType(), GreenScoreEnum.SCORE_POOL_CNT.getCode()); BigDecimal scorePoolCnt = new BigDecimal(scorePoolCntDic.getValue() == null ? "0" : scorePoolCntDic.getValue()); scorePoolCnt = scorePoolCnt.add(voucherCnt).setScale(2,BigDecimal.ROUND_DOWN); scorePoolCntDic.setValue(scorePoolCnt.toString()); dataDictionaryCustomMapper.updateById(scorePoolCntDic); //增加购买记录 String voucherNo = MallUtils.getOrderNum("VS"); MallScoreVoucher mallScoreVoucher = new MallScoreVoucher(); mallScoreVoucher.setVoucherNo(voucherNo); mallScoreVoucher.setMemberId(memberId); mallScoreVoucher.setVoucherCnt(voucherCnt); mallScoreVoucher.setPrice(scorePrice); mallScoreVoucher.setVoucherAmount(voucherAmount); mallScoreVoucher.setType("S"); mallScoreVoucherMapper.insert(mallScoreVoucher); //产生一条流水记录 mallMoneyFlowService.addMoneyFlow( mallMemberWallet.getMemberId(), voucherAmount, MoneyFlowTypeEnum.VOUCHER_SALE.getValue(), voucherNo, FlowTypeEnum.VOUCHER_AMOUNT.getValue()); return new FebsResponse().success().message("操作成功"); } @Override @Transactional(rollbackFor = Exception.class) public void sign() { MallMember member = LoginUserUtil.getLoginUser(); src/main/java/cc/mrbird/febs/mall/vo/ApiScoreVoucherInfoVo.java
New file @@ -0,0 +1,25 @@ package cc.mrbird.febs.mall.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; @Data @ApiModel(value = "ApiScoreVoucherInfoVo", description = "绿色积分个人信息") public class ApiScoreVoucherInfoVo { @ApiModelProperty(value = "绿色积分") private BigDecimal voucherCnt; @ApiModelProperty(value = "现金元") private BigDecimal voucherAmount; @ApiModelProperty(value = "当前积分价格") private BigDecimal scorePrice; @ApiModelProperty(value = "可购买总量") private BigDecimal scorePoolCnt; } src/main/java/cc/mrbird/febs/mall/vo/ApiScoreVoucherRecordVo.java
New file @@ -0,0 +1,39 @@ package cc.mrbird.febs.mall.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; @Data @ApiModel(value = "ApiScoreVoucherRecordVo", description = "绿色积分买卖信息") public class ApiScoreVoucherRecordVo { @ApiModelProperty(value = "编号") private String voucherNo; @ApiModelProperty(value = "会员") private String memberName; /** * B:买入S:卖出 */ @ApiModelProperty(value = "B:买入S:卖出") private String type; /** * 数量 */ @ApiModelProperty(value = "数量") private BigDecimal voucherCnt; /** * 单价 */ @ApiModelProperty(value = "单价") private BigDecimal price; /** * 总价 */ @ApiModelProperty(value = "总价") private BigDecimal voucherAmount; } src/main/java/cc/mrbird/febs/mall/vo/MemberBankListVo.java
@@ -23,4 +23,7 @@ // 手机号 @ApiModelProperty(value = "手机号") private String phone; // 银行卡号 @ApiModelProperty(value = "数字账号") private String digitalNo; } src/main/java/cc/mrbird/febs/rabbit/constants/QueueConstants.java
@@ -15,4 +15,6 @@ * 分享补贴,星级补贴 */ public static final String PERK_MONEY = "hlm_queue_perk_money"; public static final String FORCE_VOUCHER_SALE = "hlm_queue_force_voucher_sale"; } src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java
@@ -84,4 +84,16 @@ } } @RabbitListener(queues = QueueConstants.FORCE_VOUCHER_SALE) public void forceVoucherSaleConsumer(String price) { log.info("收到强制卖出消息,价格:{}",price); try { memberProfitService.selaHalfVoucher(price); } catch (Exception e) { log.error("强制卖出异常", e); // todo 更新表 } } } src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java
@@ -26,7 +26,11 @@ PERK_MONEY("hlm_exchange_perk_money", "hlm_route_key_perk_money", "hlm_queue_perk_money"); "hlm_queue_perk_money"), FORCE_VOUCHER_SALE("hlm_exchange_force_voucher_sale", "hlm_route_key_force_voucher_sale", "hlm_queue_force_voucher_sale"); private String exchange; src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java
@@ -81,4 +81,9 @@ log.info("发送补贴消息:{}", orderId); rabbitTemplate.convertAndSend(RabbitQueueEnum.PERK_MONEY.getExchange(), RabbitQueueEnum.PERK_MONEY.getRoute(), orderId); } public void sendForceVoucherSaleMsg(String value) { log.info("发送强制卖出消息,价格:{}",value); rabbitTemplate.convertAndSend(RabbitQueueEnum.FORCE_VOUCHER_SALE.getExchange(), RabbitQueueEnum.FORCE_VOUCHER_SALE.getRoute(),value); } } src/main/resources/mapper/modules/DataDictionaryCustomMapper.xml
@@ -53,4 +53,9 @@ </if> </where> </update> <select id="selectScorePoolCntForUpdate" resultType="cc.mrbird.febs.mall.entity.DataDictionaryCustom"> select a.* from data_dictionary_custom a where a.type = #{type} and a.code = #{code} for update </select> </mapper> src/main/resources/mapper/modules/MallMemberWalletMapper.xml
@@ -144,5 +144,14 @@ where star > 0 </select> <update id="addVorCherAmountAndCntById"> update mall_member_wallet <set> voucher_amount = voucher_amount + #{voucherAmount}, voucher_cnt = voucher_cnt - #{voucherCnt}, </set> WHERE id = #{id} </update> </mapper> src/main/resources/mapper/modules/MallScoreVoucherMapper.xml
New file @@ -0,0 +1,20 @@ <?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.MallScoreVoucherMapper"> <select id="findMallScoreVoucherListInPage" resultType="cc.mrbird.febs.mall.vo.ApiScoreVoucherRecordVo"> SELECT a.voucher_no voucherNo, a.type type, a.voucher_cnt voucherCnt, a.price price, a.voucher_amount voucherAmount, RPAD(SUBSTRING(b.NAME,1,1),CHAR_LENGTH(b.NAME),'*') memberName FROM mall_score_voucher a LEFT JOIN mall_member b ON a.member_id = b.id ORDER BY a.CREATED_TIME DESC </select> </mapper> src/main/resources/templates/febs/views/modules/system/hlmVoucherButton.html
@@ -9,16 +9,25 @@ <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> <input type="text" name="scorePrice" lay-verify="required" placeholder="请输入数字" autocomplete="off" class="layui-input"> </div> <div class="layui-form-mid layui-word-aux">剩余:</div> </div> </div> <blockquote class="layui-elem-quote blue-border">提现设置,提现时,是否需要凭证</blockquote> <div class="layui-col-lg6"> <label class="layui-form-label febs-form-item-require">需要凭证:</label> <div class="layui-input-block"> <input type="radio" name="voucherOnOff" value="1" title="是" /> <input type="radio" name="voucherOnOff" value="2" title="否" checked /> </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 class="layui-btn layui-btn-warm table-action" id="voucherButton"> 确认一键卖出 </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> </div> @@ -38,12 +47,15 @@ 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'), hlmVoucherButton = [[${hlmVoucherButtonDto}]], $voucherButton = $view.find('#voucherButton'), $view = $('#hlm-voucher-button'); form.verify({ @@ -53,18 +65,33 @@ ] }); initHlmVoucherSetValue(); initHlmVoucherButtonValue(); $voucherButton.on('click', function () { febs.modal.confirm('确认一键卖出', '点击【确定】,即强制卖出所有账户的一半积分凭证?', function () { selaHalfVoucher(); }); }); function selaHalfVoucher() { febs.post(ctx + 'admin/system/selaHalfVoucher', null, function (res) { febs.alert.success('设置成功'); return ; }); } form.render(); function initHlmVoucherSetValue() { function initHlmVoucherButtonValue() { form.val("hlm-voucher-button-form", { "roleReleasePercent": hlmVoucherSet.roleReleasePercent "scorePrice": hlmVoucherButton.scorePrice, "voucherOnOff": hlmVoucherButton.voucherOnOff, }); } form.on('submit(hlm-voucher-button-submit)', function (data) { febs.post(ctx + 'admin/system/hlmVoucherSet', data.field, function (res) { febs.post(ctx + 'admin/system/hlmVoucherButton', data.field, function (res) { febs.alert.success('设置成功'); return ; }); src/main/resources/templates/febs/views/modules/system/hlmVoucherSet.html
@@ -11,10 +11,15 @@ <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-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 class="layui-form-mid layui-word-aux">,可购买总量:</div> <div class="layui-input-inline"> <input type="text" name="scorePoolCnt" lay-verify="required|integer" placeholder="请输入数字" autocomplete="off" class="layui-input" readonly> </div> <div class="layui-form-mid layui-word-aux">。</div> </div> </div> @@ -23,7 +28,7 @@ <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 class="layui-word-aux">设置1,每日拨付千分之1。</div> </div> </div> @@ -34,7 +39,7 @@ <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 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> @@ -42,7 +47,7 @@ <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 class="layui-form-mid layui-word-aux">,才释放积分凭证。</div> </div> <div class="layui-form-item"> <label class="layui-form-label febs-form-item-require">规则二:</label> @@ -50,7 +55,7 @@ <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 class="layui-form-mid layui-word-aux">,释放今日的全额积分凭证。</div> </div> <blockquote class="layui-elem-quote blue-border">业绩产生积分凭证设置二</blockquote> <div class="layui-form-item"> @@ -59,7 +64,7 @@ <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 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> @@ -67,7 +72,7 @@ <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 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> @@ -75,7 +80,7 @@ <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 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> @@ -127,6 +132,7 @@ "achieveMax": hlmVoucherSet.achieveMax, "totalCnt": hlmVoucherSet.totalCnt, "surplusCnt": hlmVoucherSet.surplusCnt, "scorePoolCnt": hlmVoucherSet.scorePoolCnt, "roleReleasePercent": hlmVoucherSet.roleReleasePercent }); }