配置文件代码:
<!--版本 -->
<properties>
<spring.version>4.3.17.RELEASE</spring.version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 使AspectJ注解起作用:自动为匹配的类生成代理对象 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
程序代码:
/**
* @author handong
* @description: 切面:会员等级修改后,记录入record表,
* 后置处理:发放完商户自动投放规则下的按照会员等级发券
* @date 2021/8/3 18:09
*/
//这个类声明为一个切面:需要把该类放入到IOC容器中;再声明为一个切面
@Aspect
@Component
public class MemberLevelAspect {
@Autowired
private CouponSendService couponSendService;
@Autowired
private TCloudcrmCouponTaskMapper couponTaskMapper;
@Autowired
private TimeAutoCouponService timeAutoCouponService;
@Autowired
private TCloudcrmCouponSendRuleMapper couponSendRuleMapper;
@Autowired
private TCloudcrmCouponTaskUserRecordMapper tCloudcrmCouponTaskUserRecordMapper;
/*
Spring AOP
AspectJ:Java社区里最完整最流行的AOP框架
在Spring2.0以上的版本中,可以使用基于AspectJ注解或基于XML配置的AOP
*/
//后置通知:在目标方法执行后(无论是否发生异常),执行的通知
//在后置通知中,还不能访问目标方法执行的结果 ;insert , insertBatch
@After("execution(* com.fuiou.crm.mapper.TCloudcrmMemberLevelChangeRecordMapper+.insert*(..))")
public void afterMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
List<Object> args = Arrays.asList(joinPoint.getArgs());
LogWriter.info("The method " + methodName + " end with " + args + "args.size() is " + args.size());
//拦截的方法,只有一个函数形参 参数 args.get(0)
switch (methodName) {
case "insert":
TCloudcrmMemberLevelChangeRecord record = (TCloudcrmMemberLevelChangeRecord) args.get(0);
checkTimeAutoSendRule(record);
break;
case "insertBatch":
List<TCloudcrmMemberLevelChangeRecord> records = (List<TCloudcrmMemberLevelChangeRecord>) args.get(0);
for (TCloudcrmMemberLevelChangeRecord record2 : records) {
checkTimeAutoSendRule(record2);
}
break;
}
}
/*由每一个会员的等级变更行为触发,发券一次性补充发光
根据参数,等级的上下间隔,商户号,去查询自动投放规则,是否按照会员等级发放券
1、对于一个等级,商户下可能配置了多条投放规则:查找是否存在规则与变更前的会员等级相同,是,则一次性发光
2、且检查是否未发放完,是, 则一次性发光 ,所以必须是限领取张数目有限制的券
等级变更是跳级的,不发中间等级的券;连续等级变更,要发完中间的券,升级、降级都一次性补充发光
*/
public void checkTimeAutoSendRule(TCloudcrmMemberLevelChangeRecord record) {
//找出自动投放规则
List<TCloudcrmCouponSendRule> couponSendRuleList = timeAutoCouponService.getSendRuleList(record.getMchntCd());
List<TCloudcrmCouponTask> taskList = new ArrayList<>(10);
for (TCloudcrmCouponSendRule sendRule : couponSendRuleList) {
// 找出 符合 更改前的会员等级,且限制领取的券张数目 任务
TCloudcrmCouponTask param = new TCloudcrmCouponTask();
param.setObjectType(RemarkingConst.ObjectType.LEVEL.getValue());
param.setToObject(String.valueOf(record.getBeforeLevelValue()));
param.setTaskRelatesNum(1);
param.setTaskId(sendRule.getTaskId());
TCloudcrmCouponTask task = couponTaskMapper.selectByTaskId(param);
if (task != null) {
taskList.add(task);
}
}
for (TCloudcrmCouponTask sendTask : taskList) {
handleAutoUserCouponByTask(sendTask, record);
}
}
/*
对每一个会员,每一个关联自动投放规则的发券任务:做发券一次性补充发光
* 规则关连了task表 task_type = '03:自定义规则'
* 1、查询表中所有rule_state规则状态=01:启用; del_state作废状态=00:正常; rule_type规则类型=04:定时自动发券 的规则
* 2、查找规则中的task 进行发券
*/
public void handleAutoUserCouponByTask(TCloudcrmCouponTask task, TCloudcrmMemberLevelChangeRecord record) {
// 5、根据task查询状态为正常的:t_cloudcrm_coupon_task_relate 商户优惠券发放任务表
LogWriter.info(" MemberLevelAspect step-5--> merchantCode:" + record.getMchntCd() + ",taskId:" + task.getTaskId() + "查询出couponTaskRelates!");
List<TCloudcrmCouponTaskRelate> couponTaskRelates = couponSendService.getAutoCouponTaskRelate(task);
// 6、查询出任务关联的优惠券信息
LogWriter.info(" MemberLevelAspect step-6--> merchantCode:" + record.getMchntCd() + ",taskId:" + task.getTaskId() + "查询出任务关联的优惠券信息!");
Map<Integer, TCloudcrmCouponInfo> couponInfoMap = couponSendService.getCouponInfo(couponTaskRelates, task.getMerchantCode());
// 8、发券处理 ,这里只处理,定时自动发券后 ,记录定时投放 定时自动发券,每个用户每种券的发放记录
// .定时发券支持设置‘每人限领张数’(如会员降级或升级规则不适用,若恢复当前等级,累计之前发的张数继续累加发放)
LogWriter.info(" MemberLevelAspect step-8--> merchantCode:" + record.getMchntCd() + ",taskId:" + task.getTaskId() + "发券处理!");
// couponSendService.handleAutoUserCouponRelate(task, task.getCouponTaskRelates(), couponInfoMap, openIds);
this.handleAutoUserCouponRelateLeft(task, task.getCouponTaskRelates(), couponInfoMap, Arrays.asList(record.getOpenId()));
}
/*
对于剩余的券,一次发光;
跳级的中间等级不发
*/
public void handleAutoUserCouponRelateLeft(TCloudcrmCouponTask task, List<TCloudcrmCouponTaskRelate> newCTRelates, Map<Integer, TCloudcrmCouponInfo> couponInfoMap, List<String> openIds) {
LogWriter.info(" MemberLevelAspect 发券处理taskId【" + task.getTaskId() + "】t_cloudcrm_user_coupon_relate 用户优惠券关联表 开始。。。");
List<TCloudcrmUserCouponRelate> userCouponRelates = new ArrayList<TCloudcrmUserCouponRelate>();
Date nowDate = new Date();
TCloudcrmCouponSendRule sendRule = null;
if (RemarkingConst.TASK_TYPE.DEFINED.getValue().equals(task.getTaskType())) {
TCloudcrmCouponSendRule po = new TCloudcrmCouponSendRule();
po.setMerchantCode(task.getMerchantCode());
po.setTaskId(task.getTaskId());
sendRule = couponSendRuleMapper.query(po);
}
//每一个任务下的关联被发放的券
for (int i = 0; i < newCTRelates.size(); i++) {
TCloudcrmCouponTaskRelate ctRelate = newCTRelates.get(i);
TCloudcrmCouponInfo couponInfo = couponInfoMap.get(ctRelate.getCouponId());
String curDateString = DateUtils.getCurrentDate();
Date effTimeDate = DateUtils.getCurDate000();
Date expTimeDate = DateUtils.getNeedTime(23, 59, 59, Integer.valueOf(couponInfo.getExpDay()) - 1, nowDate, 0);
if (RemarkingConst.ValidType.REGULAR.getValue().equals(couponInfo.getValidType())) {
effTimeDate = couponInfo.getEffTime();
expTimeDate = couponInfo.getExpTime();
}
if (RemarkingConst.ValidType.NEXT_DAY.getValue().equals(couponInfo.getValidType())) {
effTimeDate = DateUtils.getNeedTime(0, 0, 0, 1, nowDate, 0);
expTimeDate = DateUtils.getNeedTime(23, 59, 59, Integer.valueOf(couponInfo.getExpDay()), nowDate, 0);
}
if (RemarkingConst.ValidType.XDAY_YDAT.getValue().equals(couponInfo.getValidType())) {
effTimeDate = DateUtils.getNeedTime(0, 0, 0, Integer.valueOf(couponInfo.getReceiveExpDay()), nowDate, 0);
expTimeDate = DateUtils.getNeedTime(23, 59, 59, Integer.valueOf(couponInfo.getExpDay()) - 1, nowDate, 0);
}
if (RemarkingConst.TASK_TYPE.MANUAL.getValue().equals(task.getTaskType()) && openIds != null && !openIds.isEmpty()) {
TCloudcrmCouponTask memberCountTask = new TCloudcrmCouponTask();
memberCountTask.setTaskId(task.getTaskId());
memberCountTask.setCount(openIds.size());
couponTaskMapper.update(memberCountTask);
}
for (int j = 0; j < openIds.size(); j++) {
TCloudcrmUserCouponRelate ucRelate = new TCloudcrmUserCouponRelate();
ucRelate.setOpenId(openIds.get(j));
ucRelate.setMerchantCode(task.getMerchantCode());
ucRelate.setCouponId(ctRelate.getCouponId());
ucRelate.setTaskId(task.getTaskId());
ucRelate.setCouponState(couponSendService.setCouponStateByDate(effTimeDate, expTimeDate));
ucRelate.setCouponFee(couponInfo.getCouponFee());
ucRelate.setEffTime(effTimeDate);
ucRelate.setExpTime(expTimeDate);
ucRelate.setCrtTime(nowDate);
ucRelate.setCurDate(curDateString);//yyyy-MM-dd
// 10:手动发放,18:每天定时自动发券,19:每周定时自动发券,20:每月定时自动发券
if (StringUtils.isBlank(task.getTaskName()) && RemarkingConst.TASK_TYPE.MANUAL.getValue().equals(task.getTaskType())) {
ucRelate.setGetType("10"); //手动发放
} else if (sendRule != null && RemarkingConst.SendFrequency.DAILY.getValue().equals(sendRule.getSendFrequency())) {
ucRelate.setGetType("18"); //每天定时自动发券
} else if (sendRule != null && RemarkingConst.SendFrequency.WEEKLY.getValue().equals(sendRule.getSendFrequency())) {
ucRelate.setGetType("19"); //每周定时自动发券
} else if (sendRule != null && RemarkingConst.SendFrequency.MONTHLY.getValue().equals(sendRule.getSendFrequency())) {
ucRelate.setGetType("20"); //每月定时自动发券
}
ucRelate.setTermUserCd(task.getTermUserCd());
int maxSend = task.getTaskRelatesNum();
TCloudcrmCouponTaskUserRecord param = new TCloudcrmCouponTaskUserRecord();
// 发券前,要限制“每人限领张数” ,仅对于“object_type=01” 处理,
// 会员等级 ,=0代表不限制
// if (RemarkingConst.ObjectType.LEVEL.getValue().equals(task.getObjectType()) && maxSend != 0) {
param.setCouponId(ctRelate.getCouponId());
param.setMerchantCode(task.getMerchantCode());
param.setOpenId(openIds.get(j));
param.setTaskId(task.getTaskId());
// 每个人,每种券的限制发放数量
int alreadySend = tCloudcrmCouponTaskUserRecordMapper.selectUseLimitNum(param);
// if (alreadySend + ctRelate.getCouponNum() > maxSend) {
if (alreadySend >= maxSend) {
LogWriter.info("对于券ID为" + ctRelate.getCouponId() + ",按照会员等级自动投放,每人限领张数为" + maxSend + "张,用户为" + openIds.get(j) + "您的优惠券投放领取次数已用完");
continue;
//提前结束,这个用户的这种券id不发了
}
// }
// 兼容老版本:CouponNum参数没有,至少发一张
userCouponRelates.add(ucRelate);
//
// //每一种券:多张券的发放,这里不去一张张比较大小,以投放次数为依据,剩余的值 TaskRelatesNum -UseLimitNum >=CouponNum足够就继续投放一次,
// if (ctRelate.getCouponNum() != null && ctRelate.getCouponNum() > 1) {
// for (int k = 1; k < ctRelate.getCouponNum(); k++) {
// TCloudcrmUserCouponRelate loopUcRelate = null;
// try {
// loopUcRelate = (TCloudcrmUserCouponRelate) BeanUtils.cloneBean(ucRelate);
// } catch (Exception e) {
// loopUcRelate = ucRelate;
// LogWriter.error("TCloudcrmUserCouponRelate clone 克隆出错", e);
// }
// userCouponRelates.add(loopUcRelate);
// }
// }
// 发光剩余的券张数目 maxSend - alreadySend
for (int k = 1; k < maxSend - alreadySend; k++) {
TCloudcrmUserCouponRelate loopUcRelate = null;
try {
loopUcRelate = (TCloudcrmUserCouponRelate) BeanUtils.cloneBean(ucRelate);
} catch (Exception e) {
loopUcRelate = ucRelate;
LogWriter.error("TCloudcrmUserCouponRelate clone 克隆出错", e);
}
userCouponRelates.add(loopUcRelate);
}
// 按道理,应该在handleBatchUserCouponRelates表插入后,才插入record表,代表已经发放,
//每种券:每个会员,一次投放一种券的张数CouponNum,全部insert到record表
// if (RemarkingConst.ObjectType.LEVEL.getValue().equals(task.getObjectType()) && maxSend != 0) {
List<TCloudcrmCouponTaskUserRecord> listValue = new ArrayList<TCloudcrmCouponTaskUserRecord>();
// for (int index = 0; index < ctRelate.getCouponNum(); index++) {
for (int index = 0; index < maxSend - alreadySend; index++) {
listValue.add(param);
}
tCloudcrmCouponTaskUserRecordMapper.insertBatchSelective(listValue);
// }
}
}
//所有的openId,该task下所有的券种类,统一插入
// 批量处理userCouponRelates
couponSendService.handleBatchUserCouponRelates(userCouponRelates);
LogWriter.info(" MemberLevelAspect 发券处理taskId【" + task.getTaskId() + "】t_cloudcrm_user_coupon_relate 用户优惠券关联表 结束。。。");
}
}