| @@ -46,11 +46,12 @@ public class WxCreditHistoryController extends BaseController { | |||||
| @GetMapping("findByMerchantIdAndSpend") | @GetMapping("findByMerchantIdAndSpend") | ||||
| @ApiImplicitParams({ | @ApiImplicitParams({ | ||||
| @ApiImplicitParam(name = "merchantId", value = "商户ID", dataType = "long", paramType = "query", required = true), | @ApiImplicitParam(name = "merchantId", value = "商户ID", dataType = "long", paramType = "query", required = true), | ||||
| @ApiImplicitParam(name = "spend", value = "消费金额", dataType = "int", paramType = "query", required = true)}) | |||||
| @ApiImplicitParam(name = "spend", value = "消费金额", dataType = "int", paramType = "query", required = true), | |||||
| @ApiImplicitParam(name = "userId", value = "会员Id", dataType = "long", paramType = "query", required = true)}) | |||||
| @SystemControllerLog(description = "积分历史-根据商户ID和消费金额获取所增加积分") | @SystemControllerLog(description = "积分历史-根据商户ID和消费金额获取所增加积分") | ||||
| public ResultData findByMerchantIdAndSpend(@RequestParam Long merchantId, @RequestParam String spendStr) { | |||||
| public ResultData findByMerchantIdAndSpend(@RequestParam Long merchantId, @RequestParam String spendStr,@RequestParam Long userId) { | |||||
| logger.debug("[" + getIpAddr() + "] WxCreditHistoryController::findByMerchantIdAndSpend"); | logger.debug("[" + getIpAddr() + "] WxCreditHistoryController::findByMerchantIdAndSpend"); | ||||
| return new ResultData(wxCreditHistoryService.findByMerchantIdAndSpend(merchantId, spendStr, getTenantId())); | |||||
| return new ResultData(wxCreditHistoryService.findByMerchantIdAndSpend(merchantId, spendStr, userId,getTenantId())); | |||||
| } | } | ||||
| @ApiOperation("新增接口") | @ApiOperation("新增接口") | ||||
| @@ -5,7 +5,7 @@ package com.iformall.enums; | |||||
| */ | */ | ||||
| public enum EnumCouponSendSendType { | public enum EnumCouponSendSendType { | ||||
| // -1: 未知 0:精准发券 1:主动(保留) 2:停车发券 3:核销发券 4: B端刷卡发券 | |||||
| // -1: 未知 0:精准发券 1:主动(保留) 2:停车发券 3:核销发券 4: B端刷卡发券 5:商户发卷 | |||||
| UNKNOWN(-1, "未知"), | UNKNOWN(-1, "未知"), | ||||
| INJECT(0, "精准发券"), | INJECT(0, "精准发券"), | ||||
| ACTIVE(1, "主动(保留)"), | ACTIVE(1, "主动(保留)"), | ||||
| @@ -14,6 +14,8 @@ public enum EnumCouponSendSendType { | |||||
| B_MICROPAY(4, "B端刷卡发券"), | B_MICROPAY(4, "B端刷卡发券"), | ||||
| C_ORDER(5, "购买发券"), | C_ORDER(5, "购买发券"), | ||||
| TIMED(6, "定时发券"), | TIMED(6, "定时发券"), | ||||
| MERCHANT(7, "商户发券"), | |||||
| BIRTHDAY(8, "会员生日券"), | |||||
| ; | ; | ||||
| public static EnumCouponSendSendType getEnum(Integer code) { | public static EnumCouponSendSendType getEnum(Integer code) { | ||||
| @@ -28,6 +28,8 @@ public interface WxCUserBasicInfoMapper extends CommonMapper<WxCUserBasicInfo, S | |||||
| List<WxCUserBasicInfo> findListByScore(WxCUserBasicInfoDto dto); | List<WxCUserBasicInfo> findListByScore(WxCUserBasicInfoDto dto); | ||||
| List<WxCUserBasicInfo> findBirthdayList(); | |||||
| long findCount(WxCUserBasicInfoDto dto); | long findCount(WxCUserBasicInfoDto dto); | ||||
| List<WxCUserBasicInfoVo> findVoList(WxCUserBasicInfo wxCUserBasicInfo); | List<WxCUserBasicInfoVo> findVoList(WxCUserBasicInfo wxCUserBasicInfo); | ||||
| @@ -60,7 +60,7 @@ public interface WxCreditHistoryService { | |||||
| */ | */ | ||||
| void deleteById(Long id); | void deleteById(Long id); | ||||
| Map<String, Integer> findByMerchantIdAndSpend(Long merchantId, String spendStr, String tenantId); | |||||
| Map<String, Integer> findByMerchantIdAndSpend(Long merchantId, String spendStr, Long userId,String tenantId); | |||||
| void clearCreditByYear(); | void clearCreditByYear(); | ||||
| @@ -1,5 +1,6 @@ | |||||
| package com.iformall.service.impl; | package com.iformall.service.impl; | ||||
| import com.alibaba.fastjson.JSONArray; | |||||
| import com.alibaba.fastjson.JSONObject; | import com.alibaba.fastjson.JSONObject; | ||||
| import com.github.pagehelper.PageHelper; | import com.github.pagehelper.PageHelper; | ||||
| import com.github.pagehelper.PageInfo; | import com.github.pagehelper.PageInfo; | ||||
| @@ -23,12 +24,10 @@ import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Propagation; | import org.springframework.transaction.annotation.Propagation; | ||||
| import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||
| import springfox.documentation.spring.web.json.Json; | |||||
| import java.text.SimpleDateFormat; | import java.text.SimpleDateFormat; | ||||
| import java.util.Date; | |||||
| import java.util.HashMap; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import java.util.*; | |||||
| @Service | @Service | ||||
| public class WxCouponSendServiceImpl implements WxCouponSendService { | public class WxCouponSendServiceImpl implements WxCouponSendService { | ||||
| @@ -79,12 +78,53 @@ public class WxCouponSendServiceImpl implements WxCouponSendService { | |||||
| //record.setId(UUID.randomUUID().toString().replaceAll("-", "")); | //record.setId(UUID.randomUUID().toString().replaceAll("-", "")); | ||||
| final IdWorker idWorker = IdWorker.get(); | final IdWorker idWorker = IdWorker.get(); | ||||
| record.setId(idWorker.nextId()); | record.setId(idWorker.nextId()); | ||||
| record = buildConditions(record); | |||||
| wxCouponSendMapper.insertSelective(record); | wxCouponSendMapper.insertSelective(record); | ||||
| } else { | } else { | ||||
| record = buildConditions(record); | |||||
| wxCouponSendMapper.updateByPrimaryKeySelective(record); | wxCouponSendMapper.updateByPrimaryKeySelective(record); | ||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * 会员生日券处理 | |||||
| * @param record | |||||
| * @return | |||||
| */ | |||||
| private WxCouponSend buildConditions(WxCouponSend record) { | |||||
| if (!Objects.equals(record.getSendType(), EnumCouponSendSendType.BIRTHDAY.getCode())) { | |||||
| return record ; | |||||
| } | |||||
| //会员生日券 | |||||
| JSONObject conditions = JSONObject.parseObject(record.getConditions()); | |||||
| Long couponId = record.getCouponId(); | |||||
| if (Objects.nonNull(couponId)) { | |||||
| JSONArray couponIds; | |||||
| if (Objects.isNull(record.getId())) { | |||||
| //添加新卡券 | |||||
| couponIds = new JSONArray(); | |||||
| couponIds.add(couponId); | |||||
| } else { | |||||
| //更新卡券列表 | |||||
| WxCouponSend couponSend = wxCouponSendMapper.selectByPrimaryKey(record.getId()); | |||||
| JSONObject couponSendJo = JSONObject.parseObject(couponSend.getConditions()); | |||||
| couponIds = couponSendJo.getJSONArray("couponIds"); | |||||
| if (Objects.isNull(couponIds)) { | |||||
| couponIds = new JSONArray(); | |||||
| couponIds.add(couponId); | |||||
| } else { | |||||
| //添加新卡券 | |||||
| if (!couponIds.contains(couponId)) { | |||||
| couponIds.add(couponId); | |||||
| } | |||||
| } | |||||
| } | |||||
| conditions.put("couponIds", couponIds); | |||||
| } | |||||
| record.setConditions(conditions.toJSONString()); | |||||
| return record; | |||||
| } | |||||
| @Override | @Override | ||||
| public void deleteById(Long id) { | public void deleteById(Long id) { | ||||
| wxCouponSendMapper.deleteByPrimaryKey(id); | wxCouponSendMapper.deleteByPrimaryKey(id); | ||||
| @@ -17,6 +17,7 @@ import com.iformall.mapper.*; | |||||
| import com.iformall.service.ExcelService; | import com.iformall.service.ExcelService; | ||||
| import com.iformall.service.WxCreditHistoryService; | import com.iformall.service.WxCreditHistoryService; | ||||
| import com.iformall.service.WxScoreRulesService; | import com.iformall.service.WxScoreRulesService; | ||||
| import com.iformall.utils.CreditUtil; | |||||
| import com.iformall.utils.RedisLock; | import com.iformall.utils.RedisLock; | ||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| @@ -213,40 +214,21 @@ public class WxCreditHistoryServiceImpl implements WxCreditHistoryService { | |||||
| currentCreditAmount = wxCUserBasicInfo.getCredit(); | currentCreditAmount = wxCUserBasicInfo.getCredit(); | ||||
| } | } | ||||
| // 获取等级积分倍率:默认为1.0, | |||||
| int levelScale = WxLevelConfig.DEFAULT_SCALE; | |||||
| Integer score = wxCUser.getScore(); | |||||
| if (Objects.nonNull(score)) { | |||||
| Integer scaleFromDb = wxLevelConfigMapper.getScale(wxCUser.getTenantId(), wxCUser.getScore()); | |||||
| if (Objects.nonNull(scaleFromDb)) { | |||||
| levelScale = scaleFromDb; | |||||
| } | |||||
| } | |||||
| // 获取等级积分倍率: | |||||
| int scoreScale = WxScoreRules.DEFAULT_SCALE; | |||||
| if(Objects.nonNull(wxCUserBasicInfo.getBirthdate())) { | |||||
| WxScoreRules rules = wxScoreRulesService.getScoreRules(wxCUser.getTenantId()) ; | |||||
| if(Objects.nonNull(rules)&&Objects.nonNull(rules.getScale())) { | |||||
| scoreScale = rules.getScale() ; | |||||
| } | |||||
| } | |||||
| //计算出需要新增或减少的积分 | |||||
| int creditChangeNumOrigin = creditIncrement(record); | int creditChangeNumOrigin = creditIncrement(record); | ||||
| int creditChangeNum = new BigDecimal(creditChangeNumOrigin).multiply(new BigDecimal(levelScale)).multiply(new BigDecimal(scoreScale)).divide(new BigDecimal(WxScoreRules.DEFAULT_SCALE)).divide(new BigDecimal(WxLevelConfig.DEFAULT_SCALE),BigDecimal.ROUND_HALF_UP).intValue(); | |||||
| int creditChangeNum = CreditUtil.calUserCredit(creditChangeNumOrigin,wxCUser,wxLevelConfigMapper,wxCUserBasicInfo,wxScoreRulesService) ; | |||||
| if (creditChangeNum != 0) { | if (creditChangeNum != 0) { | ||||
| Long total = Long.valueOf(currentCreditAmount) + Long.valueOf(creditChangeNum); | |||||
| if (total > Integer.MAX_VALUE) { | |||||
| throw new MallinkException(ErrorCode.OUT_OF_CREDIT); | |||||
| } | |||||
| Integer total = currentCreditAmount + creditChangeNum; | |||||
| // if (total > Integer.MAX_VALUE) { | |||||
| // throw new MallinkException(ErrorCode.OUT_OF_CREDIT); | |||||
| // } | |||||
| if (total < 0) { | if (total < 0) { | ||||
| throw new MallinkException(ErrorCode.CREDIT_NOT_ENOUGH); | throw new MallinkException(ErrorCode.CREDIT_NOT_ENOUGH); | ||||
| } | } | ||||
| //如果为导入的会员 则直接覆盖总积分和操作积分明细 | //如果为导入的会员 则直接覆盖总积分和操作积分明细 | ||||
| if (record.getCreditType() != EnumScoreType.MEM_IMPORT.getCode()) { | |||||
| if (!Objects.equals(record.getCreditType(),EnumScoreType.MEM_IMPORT.getCode())) { | |||||
| record.setCreditNum(creditChangeNum); | record.setCreditNum(creditChangeNum); | ||||
| record.setCreditAmount(currentCreditAmount + creditChangeNum); | |||||
| record.setCreditAmount(total); | |||||
| } | } | ||||
| if (record.getId() == null) { | if (record.getId() == null) { | ||||
| final IdWorker idWorker = IdWorker.get(); | final IdWorker idWorker = IdWorker.get(); | ||||
| @@ -320,7 +302,7 @@ public class WxCreditHistoryServiceImpl implements WxCreditHistoryService { | |||||
| } | } | ||||
| @Override | @Override | ||||
| public Map<String, Integer> findByMerchantIdAndSpend(Long merchantId, String spendStr, String tenantId) { | |||||
| public Map<String, Integer> findByMerchantIdAndSpend(Long merchantId, String spendStr, Long userId,String tenantId) { | |||||
| WxMerchant wxMerchant = wxMerchantMapper.selectByPrimaryKey(merchantId); | WxMerchant wxMerchant = wxMerchantMapper.selectByPrimaryKey(merchantId); | ||||
| Map<String, Integer> creditMap = Maps.newHashMap(); | Map<String, Integer> creditMap = Maps.newHashMap(); | ||||
| if (wxMerchant != null && wxMerchant.getBusinessId() != null) { | if (wxMerchant != null && wxMerchant.getBusinessId() != null) { | ||||
| @@ -328,11 +310,19 @@ public class WxCreditHistoryServiceImpl implements WxCreditHistoryService { | |||||
| wxCreditHistory.setBusinessId(Long.valueOf(wxMerchant.getBusinessId())); | wxCreditHistory.setBusinessId(Long.valueOf(wxMerchant.getBusinessId())); | ||||
| wxCreditHistory.setTenantId(tenantId); | wxCreditHistory.setTenantId(tenantId); | ||||
| int credit = 0; | int credit = 0; | ||||
| int creditNew = 0 ; | |||||
| if (StringUtils.isNotBlank(spendStr)) { | if (StringUtils.isNotBlank(spendStr)) { | ||||
| wxCreditHistory.setSpend(new BigDecimal(spendStr).multiply(new BigDecimal(100)).intValue()); | wxCreditHistory.setSpend(new BigDecimal(spendStr).multiply(new BigDecimal(100)).intValue()); | ||||
| credit = payAddCredit(wxCreditHistory); | credit = payAddCredit(wxCreditHistory); | ||||
| if(Objects.nonNull(userId)) { | |||||
| WxCUser wxCUser = wxCUserMapper.selectByPrimaryKey(userId); | |||||
| WxCUserBasicInfo wxCUserBasicInfo = wxCUserBasicInfoMapper.selectByPrimaryKey(userId); | |||||
| creditNew = CreditUtil.calUserCredit(credit,wxCUser,wxLevelConfigMapper,wxCUserBasicInfo,wxScoreRulesService) ; | |||||
| } else { | |||||
| creditNew = credit ; | |||||
| } | |||||
| } | } | ||||
| creditMap.put("credit", credit); | |||||
| creditMap.put("credit", creditNew); | |||||
| } | } | ||||
| return creditMap; | return creditMap; | ||||
| } | } | ||||
| @@ -442,7 +432,7 @@ public class WxCreditHistoryServiceImpl implements WxCreditHistoryService { | |||||
| throw new MallinkException(ErrorCode.MERCHANT_INFO_NOT_FOUND); | throw new MallinkException(ErrorCode.MERCHANT_INFO_NOT_FOUND); | ||||
| } | } | ||||
| //根据商户id和花费金额计算需要新增的积分 | //根据商户id和花费金额计算需要新增的积分 | ||||
| Map<String, Integer> map = findByMerchantIdAndSpend(record.getMerchantId(), record.getSpendStr(), record.getTenantId()); | |||||
| Map<String, Integer> map = findByMerchantIdAndSpend(record.getMerchantId(), record.getSpendStr(), null,record.getTenantId()); | |||||
| return map.get("credit"); | return map.get("credit"); | ||||
| } | } | ||||
| @@ -495,7 +485,6 @@ public class WxCreditHistoryServiceImpl implements WxCreditHistoryService { | |||||
| log.info("CREDIT:" + busRule.toJSONString() + "\nAddCredit: 0, not touch credit limit"); | log.info("CREDIT:" + busRule.toJSONString() + "\nAddCredit: 0, not touch credit limit"); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| return addCreditNumber; | return addCreditNumber; | ||||
| } | } | ||||
| @@ -0,0 +1,55 @@ | |||||
| package com.iformall.utils; | |||||
| import com.iformall.domain.po.WxCUser; | |||||
| import com.iformall.domain.po.WxCUserBasicInfo; | |||||
| import com.iformall.domain.po.WxLevelConfig; | |||||
| import com.iformall.domain.po.WxScoreRules; | |||||
| import com.iformall.mapper.WxLevelConfigMapper; | |||||
| import com.iformall.service.WxScoreRulesService; | |||||
| import lombok.extern.slf4j.Slf4j; | |||||
| import java.math.BigDecimal; | |||||
| import java.util.Objects; | |||||
| @Slf4j | |||||
| public class CreditUtil { | |||||
| /** | |||||
| * 计算用户积分 | |||||
| * | |||||
| * @return | |||||
| */ | |||||
| public static int calUserCredit(int creditOrigin, WxCUser wxCUser, WxLevelConfigMapper wxLevelConfigMapper, WxCUserBasicInfo wxCUserBasicInfo, WxScoreRulesService wxScoreRulesService) { | |||||
| if (Objects.isNull(wxCUser) || Objects.isNull(wxCUserBasicInfo)) { | |||||
| return 0; | |||||
| } | |||||
| // 获取等级积分倍率:默认为1.0, | |||||
| int levelScale = WxLevelConfig.DEFAULT_SCALE; | |||||
| Integer score = wxCUser.getScore(); | |||||
| if (Objects.nonNull(score)) { | |||||
| Integer scaleFromDb = wxLevelConfigMapper.getScale(wxCUser.getTenantId(), wxCUser.getScore()); | |||||
| if (Objects.nonNull(scaleFromDb)) { | |||||
| levelScale = scaleFromDb; | |||||
| } | |||||
| } | |||||
| // 获取生日积分倍率: | |||||
| int birthdayScale = WxScoreRules.DEFAULT_SCALE; | |||||
| if (Objects.nonNull(wxCUserBasicInfo.getBirthdate())) { | |||||
| WxScoreRules rules = wxScoreRulesService.getScoreRules(wxCUser.getTenantId()); | |||||
| if (Objects.nonNull(rules) && Objects.nonNull(rules.getScale())) { | |||||
| birthdayScale = rules.getScale(); | |||||
| } else { | |||||
| //没有配置积分规则 | |||||
| } | |||||
| } | |||||
| int creditNew = new BigDecimal(creditOrigin) | |||||
| .multiply(new BigDecimal(levelScale)) | |||||
| .multiply(new BigDecimal(birthdayScale)) | |||||
| .divide(new BigDecimal(WxScoreRules.DEFAULT_SCALE)) | |||||
| .divide(new BigDecimal(WxLevelConfig.DEFAULT_SCALE) | |||||
| , BigDecimal.ROUND_HALF_UP).intValue(); | |||||
| log.info("积分倍率, 用户:{},成长值:{},等级积分倍率:{},生日积分倍率:{},原积分:{},新积分:{}", wxCUser.getId(), wxCUser.getScore(), levelScale, birthdayScale, creditOrigin, creditNew); | |||||
| return creditNew; | |||||
| } | |||||
| } | |||||
| @@ -229,6 +229,11 @@ | |||||
| </select> | </select> | ||||
| <select id="findBirthdayList" resultMap="BaseResultMap"> | |||||
| select <include refid="allColumnsOfScoreList"/> | |||||
| from wx_c_user_basic_info where birthdate is not null and phone is not null | |||||
| </select> | |||||
| <select id="findCount" parameterType="com.iformall.domain.dto.WxCUserBasicInfoDto" resultType="java.lang.Long"> | <select id="findCount" parameterType="com.iformall.domain.dto.WxCUserBasicInfoDto" resultType="java.lang.Long"> | ||||
| select count(id) from wx_c_user_basic_info where 1=1 | select count(id) from wx_c_user_basic_info where 1=1 | ||||
| <if test=" null != startTime "> | <if test=" null != startTime "> | ||||