记得上下班打卡 | git大法好,push需谨慎

Commit 5a9c1bbc authored by 张国柄's avatar 张国柄

+api:job:平台券移除策略;

parent ce2503cc
...@@ -280,7 +280,7 @@ create table candy_user_coupon ...@@ -280,7 +280,7 @@ create table candy_user_coupon
mcoupon_id varchar(64) comment '~candy_mgt_coupon.mcoupon_id', mcoupon_id varchar(64) comment '~candy_mgt_coupon.mcoupon_id',
uid varchar(64) not null comment '~adam_user.uid', uid varchar(64) not null comment '~adam_user.uid',
coupon_id varchar(64) not null comment '~candy_coupon.coupon_id', coupon_id varchar(64) not null comment '~candy_coupon.coupon_id',
state tinyint comment '用户券状态[1-可用|2-无效|3-已过期|5-已使用]', state tinyint comment '用户券状态[1-可用|2-无效|3-已过期|5-已使用|9-移除不展示(过期或已使用)]',
ccode varchar(64) comment '券码~candy_coupon_code.ccode', ccode varchar(64) comment '券码~candy_coupon_code.ccode',
bind_at datetime(3) comment '激活时间', bind_at datetime(3) comment '激活时间',
...@@ -306,7 +306,7 @@ create table candy_common_coupon ...@@ -306,7 +306,7 @@ create table candy_common_coupon
ccoupon_id varchar(64) not null, ccoupon_id varchar(64) not null,
mcoupon_id varchar(64) not null comment '~candy_mgt_coupon.mcoupon_id', mcoupon_id varchar(64) not null comment '~candy_mgt_coupon.mcoupon_id',
coupon_id varchar(64) not null comment '~candy_coupon.coupon_id', coupon_id varchar(64) not null comment '~candy_coupon.coupon_id',
state tinyint comment '公有券状态[1-可用|2-无效|3-已过期]', state tinyint comment '公有券状态[1-可用|2-无效|3-已过期|9-移除不展示(过期)]',
ranged tinyint comment '公有券范围(~candy_mgt_coupon.event_type)', ranged tinyint comment '公有券范围(~candy_mgt_coupon.event_type)',
operator varchar(64) not null comment '操作人', operator varchar(64) not null comment '操作人',
......
...@@ -72,7 +72,7 @@ public class CandyMgtCouponBuildParam { ...@@ -72,7 +72,7 @@ public class CandyMgtCouponBuildParam {
@Min(value = 1, message = "发放量不能小于1") @Min(value = 1, message = "发放量不能小于1")
@ApiModelProperty(required = true, value = "发放量", example = "1") @ApiModelProperty(required = true, value = "发放量", example = "1")
private Integer eventAmt; private Integer eventAmt;
@ApiModelProperty(required = false, value = "发放类型[0-保留|1-会员|2-手机号|10-全体用户]", allowableValues = "0,1,2,10") @ApiModelProperty(required = false, value = "发放类型[0-保留|1-会员|2-手机号|10-全体用户]", allowableValues = "0,1,2,10")
private Integer eventType; private Integer eventType;
@ApiModelProperty(required = false, value = "`发放类型`为2-手机号时发放手机号以,分隔", example = "18510957291,17701223310") @ApiModelProperty(required = false, value = "`发放类型`为2-手机号时发放手机号以,分隔", example = "18510957291,17701223310")
private String eventLimit; private String eventLimit;
......
...@@ -50,7 +50,7 @@ public class CandyCommonCoupon implements Serializable { ...@@ -50,7 +50,7 @@ public class CandyCommonCoupon implements Serializable {
private Integer exclusive; private Integer exclusive;
/** /**
* 公有券状态[1-可用|2-无效|3-已过期] * 公有券状态[1-可用|2-无效|3-已过期|9-移除不展示(过期)]
*/ */
private Integer state; private Integer state;
......
...@@ -56,7 +56,7 @@ public class CandyUserCoupon implements Serializable,Cloneable { ...@@ -56,7 +56,7 @@ public class CandyUserCoupon implements Serializable,Cloneable {
private Integer exclusive; private Integer exclusive;
/** /**
* 用户券状态[1-可用|2-无效|3-已过期|5-已使用] * 用户券状态[1-可用|2-无效|3-已过期|5-已使用|9-移除不展示(过期或已使用)]
*/ */
private Integer state; private Integer state;
......
...@@ -116,7 +116,7 @@ create table candy_user_coupon ...@@ -116,7 +116,7 @@ create table candy_user_coupon
mcoupon_id varchar(64) comment '~candy_mgt_coupon.mcoupon_id', mcoupon_id varchar(64) comment '~candy_mgt_coupon.mcoupon_id',
uid varchar(64) not null comment '~adam_user.uid', uid varchar(64) not null comment '~adam_user.uid',
coupon_id varchar(64) not null comment '~candy_coupon.coupon_id', coupon_id varchar(64) not null comment '~candy_coupon.coupon_id',
state tinyint comment '用户券状态[1-可用|2-无效|3-已过期|5-已使用]', state tinyint comment '用户券状态[1-可用|2-无效|3-已过期|5-已使用|9-移除不展示(过期或已使用)]',
ccode varchar(64) comment '券码~candy_coupon_code.ccode', ccode varchar(64) comment '券码~candy_coupon_code.ccode',
bind_at datetime(3) comment '激活时间', bind_at datetime(3) comment '激活时间',
...@@ -142,7 +142,7 @@ create table candy_common_coupon ...@@ -142,7 +142,7 @@ create table candy_common_coupon
ccoupon_id varchar(64) not null, ccoupon_id varchar(64) not null,
mcoupon_id varchar(64) not null comment '~candy_mgt_coupon.mcoupon_id', mcoupon_id varchar(64) not null comment '~candy_mgt_coupon.mcoupon_id',
coupon_id varchar(64) not null comment '~candy_coupon.coupon_id', coupon_id varchar(64) not null comment '~candy_coupon.coupon_id',
state tinyint comment '公有券状态[1-可用|2-无效|3-已过期]', state tinyint comment '公有券状态[1-可用|2-无效|3-已过期|9-移除不展示(过期)]',
ranged tinyint comment '公有券范围(~candy_mgt_coupon.event_type)', ranged tinyint comment '公有券范围(~candy_mgt_coupon.event_type)',
operator varchar(64) not null comment '操作人', operator varchar(64) not null comment '操作人',
......
package com.liquidnet.service.executor.main.handler; package com.liquidnet.service.executor.main.handler;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.DESUtils;
import com.liquidnet.commons.lang.util.HttpUtil;
import com.liquidnet.service.feign.kylin.task.FeignPlatformAlipayBackClient; import com.liquidnet.service.feign.kylin.task.FeignPlatformAlipayBackClient;
import com.liquidnet.service.feign.platform.api.FeignPlatformApiClient; import com.liquidnet.service.feign.platform.api.FeignPlatformApiClient;
import com.liquidnet.service.feign.platform.kylin.FeignPlatformFreightClient; import com.liquidnet.service.feign.platform.kylin.FeignPlatformFreightClient;
import com.liquidnet.service.feign.platform.task.FeignPlatformCandyTaskClient; import com.liquidnet.service.feign.platform.task.FeignPlatformCandyTaskClient;
import com.xxl.job.core.context.XxlJobHelper; import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob; import com.xxl.job.core.handler.annotation.XxlJob;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
/** /**
* Platform * Platform
*/ */
@Component @Component
public class PlatformTaskHandler { public class PlatformTaskHandler {
@Value("${liquidnet.service.platform.url}")
private String sevPlatformUrl;
@Autowired @Autowired
private FeignPlatformAlipayBackClient feignPlatformAlipayBackClient; private FeignPlatformAlipayBackClient feignPlatformAlipayBackClient;
@Autowired @Autowired
...@@ -106,6 +116,24 @@ public class PlatformTaskHandler { ...@@ -106,6 +116,24 @@ public class PlatformTaskHandler {
} }
} }
@XxlJob(value = "sev-platform:candyUserCouponRmvProcessing")
public void candyUserCouponRmvProcessing() {// 券中心:券移除处理
try {
String url = sevPlatformUrl.concat("/platform/ccoupon/task/due/rmv");
LinkedMultiValueMap<String, String> paramsMap = CollectionUtil.linkedMultiValueMapStringString();
String jobParam = XxlJobHelper.getJobParam();
paramsMap.add("displayDays", DESUtils.DES().encrypt(StringUtils.isNotBlank(jobParam) ? jobParam : "31"));
LinkedMultiValueMap<String, String> headersMap = CollectionUtil.linkedMultiValueMapStringString();
headersMap.add("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE);
headersMap.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE);
XxlJobHelper.handleSuccess("结果:" + HttpUtil.post(url, paramsMap, headersMap));
} catch (Exception e) {
XxlJobHelper.log(e);
XxlJobHelper.handleFail();
}
}
@XxlJob(value = "sev-platform:getFreightChargeHandler") @XxlJob(value = "sev-platform:getFreightChargeHandler")
public void getFreightChargeHandler() {//运费 public void getFreightChargeHandler() {//运费
try { try {
......
...@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; ...@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.liquidnet.common.cache.redis.util.AbstractRedisUtil; import com.liquidnet.common.cache.redis.util.AbstractRedisUtil;
import com.liquidnet.common.cache.redis.util.RedisDataSourceUtil; import com.liquidnet.common.cache.redis.util.RedisDataSourceUtil;
import com.liquidnet.common.exception.LiquidnetServiceException; import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.common.exception.constant.ErrorCode;
import com.liquidnet.commons.lang.util.DESUtils;
import com.liquidnet.service.base.ResponseDto; import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.candy.constant.CandyRedisConst; import com.liquidnet.service.candy.constant.CandyRedisConst;
import com.liquidnet.service.candy.dto.CandyCommonCouponBasicDto; import com.liquidnet.service.candy.dto.CandyCommonCouponBasicDto;
...@@ -19,12 +21,12 @@ import com.liquidnet.service.platform.service.impl.candy.PlatformCandyCouponCode ...@@ -19,12 +21,12 @@ import com.liquidnet.service.platform.service.impl.candy.PlatformCandyCouponCode
import com.liquidnet.service.platform.service.impl.candy.PlatformCandyCouponService; import com.liquidnet.service.platform.service.impl.candy.PlatformCandyCouponService;
import com.liquidnet.service.platform.service.impl.candy.PlatformCandyUserCouponService; import com.liquidnet.service.platform.service.impl.candy.PlatformCandyUserCouponService;
import com.liquidnet.service.platform.utils.ObjectUtil; import com.liquidnet.service.platform.utils.ObjectUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -80,7 +82,7 @@ public class CandyCouponDueTaskController { ...@@ -80,7 +82,7 @@ public class CandyCouponDueTaskController {
// 查取状态可用的到期兑换码 // 查取状态可用的到期兑换码
LambdaQueryWrapper<CandyCouponCode> couponCodeQueryWrapper = Wrappers.lambdaQuery(CandyCouponCode.class); LambdaQueryWrapper<CandyCouponCode> couponCodeQueryWrapper = Wrappers.lambdaQuery(CandyCouponCode.class);
couponCodeQueryWrapper.eq(CandyCouponCode::getState, 0); couponCodeQueryWrapper.eq(CandyCouponCode::getState, 0);
couponCodeQueryWrapper.le(CandyCouponCode::getRedeemStop, now); couponCodeQueryWrapper.le(CandyCouponCode::getRedeemStop, now.minusSeconds(30));
int totalCount = platformCandyCouponCodeService.count(couponCodeQueryWrapper); int totalCount = platformCandyCouponCodeService.count(couponCodeQueryWrapper);
AtomicInteger pl = new AtomicInteger(); AtomicInteger pl = new AtomicInteger();
int remainCount = totalCount; int remainCount = totalCount;
...@@ -172,7 +174,7 @@ public class CandyCouponDueTaskController { ...@@ -172,7 +174,7 @@ public class CandyCouponDueTaskController {
// 查取状态可用的公有券 - 对应的到期券列表 // 查取状态可用的公有券 - 对应的到期券列表
LambdaQueryWrapper<CandyCoupon> couponQueryWrapper = Wrappers.lambdaQuery(CandyCoupon.class); LambdaQueryWrapper<CandyCoupon> couponQueryWrapper = Wrappers.lambdaQuery(CandyCoupon.class);
couponQueryWrapper.in(CandyCoupon::getCouponId, commonCouponIdArr); couponQueryWrapper.in(CandyCoupon::getCouponId, commonCouponIdArr);
couponQueryWrapper.le(CandyCoupon::getExpireAt, now); couponQueryWrapper.le(CandyCoupon::getExpireAt, now.minusSeconds(30));
int totalCount = platformCandyCouponService.count(couponQueryWrapper), remainCount = totalCount, num = 0, pSize = 1000; int totalCount = platformCandyCouponService.count(couponQueryWrapper), remainCount = totalCount, num = 0, pSize = 1000;
log.info("券到期检查处理:公有券[可用券总数:{},其中到期券ID数:{}]", commonCouponList.size(), totalCount); log.info("券到期检查处理:公有券[可用券总数:{},其中到期券ID数:{}]", commonCouponList.size(), totalCount);
...@@ -245,7 +247,7 @@ public class CandyCouponDueTaskController { ...@@ -245,7 +247,7 @@ public class CandyCouponDueTaskController {
// 查取状态可用的到期券 // 查取状态可用的到期券
LambdaQueryWrapper<CandyUserCoupon> userCouponQueryWrapper = Wrappers.lambdaQuery(CandyUserCoupon.class); LambdaQueryWrapper<CandyUserCoupon> userCouponQueryWrapper = Wrappers.lambdaQuery(CandyUserCoupon.class);
userCouponQueryWrapper.eq(CandyUserCoupon::getState, 1); userCouponQueryWrapper.eq(CandyUserCoupon::getState, 1);
userCouponQueryWrapper.le(CandyUserCoupon::getDuedAt, now); userCouponQueryWrapper.le(CandyUserCoupon::getDuedAt, now.minusSeconds(30));
int totalCount = platformCandyUserCouponService.count(userCouponQueryWrapper); int totalCount = platformCandyUserCouponService.count(userCouponQueryWrapper);
AtomicInteger pl = new AtomicInteger(); AtomicInteger pl = new AtomicInteger();
int remainCount = totalCount; int remainCount = totalCount;
...@@ -311,4 +313,45 @@ public class CandyCouponDueTaskController { ...@@ -311,4 +313,45 @@ public class CandyCouponDueTaskController {
log.info("券到期检查处理:私有券[到期总记录数:{},处理总数:{}] >>> END END END", totalCount, pl.get()); log.info("券到期检查处理:私有券[到期总记录数:{},处理总数:{}] >>> END END END", totalCount, pl.get());
return ResponseDto.success(); return ResponseDto.success();
} }
/**
* 券移除-`过期券/已用券`超过指定时长移除不展示
* - 过期券:更新MySQL用户券状态,删除Redis用户指定过期时段的券
* - 已用券:暂不处理
* 同步REDIS.DTO
*
* @param displayDays 有效展示天数,例如:"31,366",其中31为过期券对应有效展示天数,366为已用券对应有效展示天数,其中366可以不传即不处理已用券,31必传,否则执行无效
* @return ResponseDto<String>
*/
@ApiOperation(value = "@JOB:券移除")
@PostMapping("rmv")
public ResponseDto<String> processForRmv(@RequestParam String displayDays) {
int displayDaysIntVal1 = 31, displayDaysIntVal2 = 0;
ErrorCode paramError = ErrorCode.HTTP_PARAM_ERROR;
if (StringUtils.isNotBlank(displayDays)) {
try {
String decrypt = DESUtils.DES().decrypt(displayDays);
String[] decryptArr = decrypt.split(",");
displayDaysIntVal1 = Integer.parseInt(decryptArr[0]);
displayDaysIntVal2 = decryptArr.length > 1 ? Integer.parseInt(decryptArr[1]) : 0;
} catch (NumberFormatException ignored) {
} catch (Exception e) {
return ResponseDto.failure(paramError.getCode(), paramError.getMessage());
}
if (displayDaysIntVal1 <= 0) {
return ResponseDto.failure(paramError.getCode(), paramError.getMessage());
}
} else {
return ResponseDto.failure(paramError.getCode(), paramError.getMessage());
}
LocalDateTime currentDateTime = LocalDateTime.now();
int plCommonCoupon = platformCandyCommonCouponService.rmvForCommonCouponProcessing(currentDateTime, displayDaysIntVal1);
int plUserCouponDue = platformCandyUserCouponService.rmvForUserCouponProcessing(currentDateTime, displayDaysIntVal1, false);
int plUserCouponUse = 0;
if (displayDaysIntVal2 > 365) {
plUserCouponUse = platformCandyUserCouponService.rmvForUserCouponProcessing(currentDateTime, displayDaysIntVal2, true);
}
return ResponseDto.success(String.format("处理结果[过期公有券:%d,过期私有券:%d,已用券:%d", plCommonCoupon, plUserCouponDue, plUserCouponUse));
}
} }
package com.liquidnet.service.platform.service.impl.candy; package com.liquidnet.service.platform.service.impl.candy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.common.cache.redis.util.AbstractRedisUtil;
import com.liquidnet.common.cache.redis.util.RedisDataSourceUtil;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.service.candy.constant.CandyRedisConst;
import com.liquidnet.service.candy.dto.CandyCommonCouponBasicDto;
import com.liquidnet.service.candy.entity.CandyCommonCoupon; import com.liquidnet.service.candy.entity.CandyCommonCoupon;
import com.liquidnet.service.candy.mapper.CandyCommonCouponMapper; import com.liquidnet.service.candy.mapper.CandyCommonCouponMapper;
import com.liquidnet.service.platform.utils.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@Slf4j
@Service @Service
public class PlatformCandyCommonCouponService extends ServiceImpl<CandyCommonCouponMapper, CandyCommonCoupon> { public class PlatformCandyCommonCouponService extends ServiceImpl<CandyCommonCouponMapper, CandyCommonCoupon> {
@Autowired
private RedisDataSourceUtil redisDataSourceUtil;
/**
* 移除公有券
* - 处理已过期且过期天数超过`displayDays`的券
*
* @param currentDateTime 当前时间
* @param displayDays 展示天数
*/
public int rmvForCommonCouponProcessing(LocalDateTime currentDateTime, int displayDays) {
AtomicInteger pl = new AtomicInteger();
try {
LambdaQueryWrapper<CandyCommonCoupon> commonCouponQueryWrapper = Wrappers.lambdaQuery(CandyCommonCoupon.class);
commonCouponQueryWrapper.eq(CandyCommonCoupon::getState, 3);
commonCouponQueryWrapper.le(CandyCommonCoupon::getUpdatedAt, currentDateTime.minusDays(displayDays));
int totalCount = this.count(commonCouponQueryWrapper);
int remainCount = totalCount, pSize = 1000;
if (totalCount > 0) {
log.info("券移除处理:公有券[总数:{},AT:{} - {} = {}] >>> BEGIN BEGIN BEGIN", totalCount, currentDateTime, displayDays, currentDateTime.minusDays(displayDays));
}
ArrayList<CandyCommonCoupon> updateCommonCouponList = ObjectUtil.getCandyCommonCouponArrayList();
commonCouponQueryWrapper.select(CandyCommonCoupon::getMid, CandyCommonCoupon::getCcouponId);
commonCouponQueryWrapper.orderByAsc(CandyCommonCoupon::getMid);
while (remainCount > 0) {
updateCommonCouponList.clear();
LambdaQueryWrapper<CandyCommonCoupon> commonCouponLambdaQueryWrapper = commonCouponQueryWrapper.clone();
String lastLimitSql = "LIMIT " + 0 + "," + pSize;
commonCouponLambdaQueryWrapper.last(lastLimitSql);
List<CandyCommonCoupon> commonCouponList = this.list(commonCouponLambdaQueryWrapper);
for (int i = 0, listSize = CollectionUtils.isEmpty(commonCouponList) ? -1 : commonCouponList.size(); i < listSize; i++) {
CandyCommonCoupon commonCoupon = commonCouponList.get(i);
commonCoupon.setState(9);
commonCoupon.setOperator("CHECK");
commonCoupon.setUpdatedAt(currentDateTime);
updateCommonCouponList.add(commonCoupon);
}
if (!CollectionUtils.isEmpty(updateCommonCouponList)) {
if (this.updateBatchById(updateCommonCouponList, updateCommonCouponList.size())) {
AbstractRedisUtil redisCandyUtil = redisDataSourceUtil.getRedisCandyUtil();
List<CandyCommonCouponBasicDto> vos = (List<CandyCommonCouponBasicDto>) redisCandyUtil.get(CandyRedisConst.BASIC_COMMON_COUPON);
if (!CollectionUtils.isEmpty(vos)) {
List<String> updateCommonCouponIdList = updateCommonCouponList.stream().map(CandyCommonCoupon::getCcouponId).collect(Collectors.toList());
int beforeSizeVos = vos.size();
vos.removeIf(r -> updateCommonCouponIdList.contains(r.getCcouponId()));
if (beforeSizeVos - vos.size() > 0) {
pl.getAndAdd(beforeSizeVos - vos.size());
redisCandyUtil.set(CandyRedisConst.BASIC_COMMON_COUPON, vos);
}
}
} else {
throw new LiquidnetServiceException("-1", "券移除数据更新失败");
}
}
remainCount = Math.max(remainCount - pSize, 0);
log.info("券移除处理中:公有券[总数:{},单次处理:{}|{},剩余:{}]", totalCount, lastLimitSql, pl.get(), remainCount);
}
if (totalCount > 0) {
log.info("券移除处理:公有券[总数:{},处理总数:{}] >>> END END END", totalCount, pl.get());
}
} catch (Exception e) {
log.error("Ex.券移除处理异常:公有券[currentDateTime={},displayDays={}]", currentDateTime, displayDays, e);
}
return pl.get();
}
} }
package com.liquidnet.service.platform.service.impl.candy; package com.liquidnet.service.platform.service.impl.candy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.common.cache.redis.util.AbstractRedisUtil; import com.liquidnet.common.cache.redis.util.AbstractRedisUtil;
import com.liquidnet.common.cache.redis.util.RedisDataSourceUtil; import com.liquidnet.common.cache.redis.util.RedisDataSourceUtil;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.service.adam.constant.AdamRedisConst; import com.liquidnet.service.adam.constant.AdamRedisConst;
import com.liquidnet.service.base.OrderCloseMapping; import com.liquidnet.service.base.OrderCloseMapping;
import com.liquidnet.service.base.constant.MQConst; import com.liquidnet.service.base.constant.MQConst;
...@@ -15,7 +18,9 @@ import com.liquidnet.service.candy.entity.CandyUserCoupon; ...@@ -15,7 +18,9 @@ import com.liquidnet.service.candy.entity.CandyUserCoupon;
import com.liquidnet.service.candy.mapper.CandyCommonCouponMapper; import com.liquidnet.service.candy.mapper.CandyCommonCouponMapper;
import com.liquidnet.service.candy.mapper.CandyCouponRuleMapper; import com.liquidnet.service.candy.mapper.CandyCouponRuleMapper;
import com.liquidnet.service.candy.mapper.CandyUserCouponMapper; import com.liquidnet.service.candy.mapper.CandyUserCouponMapper;
import com.liquidnet.service.platform.utils.ObjectUtil;
import com.liquidnet.service.platform.utils.QueueUtils; import com.liquidnet.service.platform.utils.QueueUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
...@@ -25,8 +30,10 @@ import java.util.ArrayList; ...@@ -25,8 +30,10 @@ import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j
@Service @Service
public class PlatformCandyUserCouponService extends ServiceImpl<CandyUserCouponMapper, CandyUserCoupon> { public class PlatformCandyUserCouponService extends ServiceImpl<CandyUserCouponMapper, CandyUserCoupon> {
@Autowired @Autowired
...@@ -35,8 +42,7 @@ public class PlatformCandyUserCouponService extends ServiceImpl<CandyUserCouponM ...@@ -35,8 +42,7 @@ public class PlatformCandyUserCouponService extends ServiceImpl<CandyUserCouponM
private CandyCouponRuleMapper candyCouponRuleMapper; private CandyCouponRuleMapper candyCouponRuleMapper;
@Autowired @Autowired
private CandyCommonCouponMapper candyCommonCouponMapper; private CandyCommonCouponMapper candyCommonCouponMapper;
@Autowired
private PlatformCandyUserCouponService platformCandyUserCouponService;
@Autowired @Autowired
private QueueUtils queueUtils; private QueueUtils queueUtils;
@Autowired @Autowired
...@@ -51,7 +57,7 @@ public class PlatformCandyUserCouponService extends ServiceImpl<CandyUserCouponM ...@@ -51,7 +57,7 @@ public class PlatformCandyUserCouponService extends ServiceImpl<CandyUserCouponM
//修改数据库 //修改数据库
CandyUserCoupon userCoupon = CandyUserCoupon.getNew(); CandyUserCoupon userCoupon = CandyUserCoupon.getNew();
userCoupon.setState(1); userCoupon.setState(1);
platformCandyUserCouponService.update(userCoupon, new UpdateWrapper<CandyUserCoupon>().in("ucoupon_id", uCouponIdList)); this.update(userCoupon, new UpdateWrapper<CandyUserCoupon>().in("ucoupon_id", uCouponIdList));
//sendRedis //sendRedis
int forSize = 500; int forSize = 500;
int forCount = uCouponUidList.size() % forSize == 0 ? uCouponUidList.size() / forSize : (uCouponUidList.size() / forSize) + 1; int forCount = uCouponUidList.size() % forSize == 0 ? uCouponUidList.size() / forSize : (uCouponUidList.size() / forSize) + 1;
...@@ -112,4 +118,86 @@ public class PlatformCandyUserCouponService extends ServiceImpl<CandyUserCouponM ...@@ -112,4 +118,86 @@ public class PlatformCandyUserCouponService extends ServiceImpl<CandyUserCouponM
} }
return basicDtoList; return basicDtoList;
} }
/**
* 移除私有券
* - 处理已过期且过期天数超过`displayDays`的券
*
* @param currentDateTime 当前时间
* @param displayDays 展示天数
* @param usedDisplayFlg 已使用券逻辑处理
*/
public int rmvForUserCouponProcessing(LocalDateTime currentDateTime, int displayDays, boolean usedDisplayFlg) {
AtomicInteger pl = new AtomicInteger();
try {
LambdaQueryWrapper<CandyUserCoupon> userCouponQueryWrapper = Wrappers.lambdaQuery(CandyUserCoupon.class);
if (usedDisplayFlg) {
userCouponQueryWrapper.eq(CandyUserCoupon::getState, 5);
userCouponQueryWrapper.le(CandyUserCoupon::getUsedAt, currentDateTime.minusDays(displayDays));
} else {
userCouponQueryWrapper.eq(CandyUserCoupon::getState, 3);
userCouponQueryWrapper.le(CandyUserCoupon::getDuedAt, currentDateTime.minusDays(displayDays));
}
int totalCount = this.count(userCouponQueryWrapper);
int remainCount = totalCount, pSize = 1000;
if (totalCount > 0) {
log.info("券移除处理:私有券[总数:{},AT:{} - {} = {}] >>> BEGIN BEGIN BEGIN", totalCount, currentDateTime, displayDays, currentDateTime.minusDays(displayDays));
}
ArrayList<CandyUserCoupon> updateUserCouponList = ObjectUtil.getCandyUserCouponArrayList();
userCouponQueryWrapper.select(CandyUserCoupon::getMid, CandyUserCoupon::getUcouponId, CandyUserCoupon::getUid);
userCouponQueryWrapper.orderByAsc(CandyUserCoupon::getMid);
while (remainCount > 0) {
updateUserCouponList.clear();
LambdaQueryWrapper<CandyUserCoupon> userCouponLambdaQueryWrapper = userCouponQueryWrapper.clone();
String lastLimitSql = "LIMIT " + 0 + "," + pSize;
userCouponLambdaQueryWrapper.last(lastLimitSql);
List<CandyUserCoupon> userCouponList = this.list(userCouponLambdaQueryWrapper);
for (int i = 0, listSize = CollectionUtils.isEmpty(userCouponList) ? -1 : userCouponList.size(); i < listSize; i++) {
CandyUserCoupon userCoupon = userCouponList.get(i);
userCoupon.setState(9);
userCoupon.setOperator(usedDisplayFlg ? "CHECK-USED" : "CHECK-DUED");
userCoupon.setUpdatedAt(currentDateTime);
updateUserCouponList.add(userCoupon);
}
if (!CollectionUtils.isEmpty(updateUserCouponList)) {
if (this.updateBatchById(updateUserCouponList, updateUserCouponList.size())) {
AbstractRedisUtil redisCandyUtil = redisDataSourceUtil.getRedisCandyUtil();
// 需要更新的用户券记录按UID分组处理
Map<String, List<CandyUserCoupon>> userCouponListByUidMap = updateUserCouponList.stream().collect(Collectors.groupingBy(CandyUserCoupon::getUid));
userCouponListByUidMap.forEach((uid, updateUserCouponListByUid) -> {
String uckey = CandyRedisConst.BASIC_USER_COUPON.concat(uid);
List<CandyUserCouponBasicDto> vos = (List<CandyUserCouponBasicDto>) redisCandyUtil.get(uckey);
if (!CollectionUtils.isEmpty(vos)) {
List<String> updateUserCouponIdListByUid = updateUserCouponListByUid.stream().map(CandyUserCoupon::getUcouponId).collect(Collectors.toList());
int beforeSizeVos = vos.size();
vos.removeIf(r -> updateUserCouponIdListByUid.contains(r.getUcouponId()));
if (beforeSizeVos - vos.size() > 0) {
pl.getAndAdd(beforeSizeVos - vos.size());
redisCandyUtil.set(uckey, vos);
}
}
});
} else {
throw new LiquidnetServiceException("-1", "券移除数据更新失败");
}
}
remainCount = Math.max(remainCount - pSize, 0);
log.info("券移除处理中:私有券[总数:{},单次处理:{}|{},剩余:{}]", totalCount, lastLimitSql, pl.get(), remainCount);
}
if (totalCount > 0) {
log.info("券移除处理:私有券[总数:{},处理总数:{}] >>> END END END", totalCount, pl.get());
}
} catch (Exception e) {
log.error("Ex.券移除处理异常:私有券[currentDateTime={},displayDays={},usedDisplayFlg={}]", currentDateTime, displayDays, usedDisplayFlg, e);
}
return pl.get();
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment