package com.kym.service.impl;
import com.github.pagehelper.PageHelper;
import com.kym.common.utils.CommUtil;
import com.kym.common.utils.IDGenerator;
import com.kym.entity.*;
import com.kym.entity.queryParams.ActivityQueryParam;
import com.kym.entity.vo.ActivityVo;
import com.kym.entity.common.PageBean;
import com.kym.entity.common.RedisKeys;
import com.kym.entity.UserRechargeRights;
import com.kym.mapper.ActivityMapper;
import com.kym.service.*;
import com.kym.service.UserRechargeRightsService;
import com.kym.service.mybatisplus.MyBaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Collectors;
import static com.kym.entity.Activity.*;
/**
*
* 服务实现类
*
*
* @author skyline
* @since 2023-10-18
*/
@Service
@Slf4j
public class ActivityServiceImpl extends MyBaseServiceImpl implements ActivityService {
private final ActivityStationService activityStationService;
private final RechargeRightsService rechargeRightsService;
private final UserRechargeRightsService userRechargeRightsService;
private final BannerService bannerService;
private final CouponService couponService;
private final RedisTemplate redisTemplate;
public ActivityServiceImpl(ActivityStationService activityStationService, RechargeRightsService rechargeRightsService,
UserRechargeRightsService userRechargeRightsService,
BannerService bannerService, CouponService couponService, RedisTemplate redisTemplate) {
this.activityStationService = activityStationService;
this.rechargeRightsService = rechargeRightsService;
this.userRechargeRightsService = userRechargeRightsService;
this.bannerService = bannerService;
this.couponService = couponService;
this.redisTemplate = redisTemplate;
}
/**
* 新增活动
*
* @param activityVo
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void createActivity(ActivityVo activityVo) {
// 新增activity
var activity = new Activity();
BeanUtils.copyProperties(activityVo, activity);
activity.setId(IDGenerator.INS().nextId());
save(activity);
// 新增activityStation 活动-站点关联
if (activityVo.getApplyStation() == APPLY_STATION_部分站点 && !CommUtil.isEmptyOrNull(activityVo.getStationIds())) {
var activityStationList = activityVo.getStationIds().stream().map(stationId -> new ActivityStation().setActivityId(activity.getId()).setStationId(stationId)).toList();
activityStationService.saveBatch(activityStationList);
}
// 新增充值优惠活动
if (activityVo.getDiscountType().equals(Activity.DISCOUNT_TYPE_服务费折扣权益) && !CommUtil.isEmptyOrNull(activityVo.getRechargeRightsList())) {
var rechargeRightsList = activityVo.getRechargeRightsList().stream().peek(rechargeRights -> {
BeanUtils.copyProperties(activity, rechargeRights, "id");
rechargeRights.setActivityId(activity.getId());
}).toList();
rechargeRightsService.saveBatch(rechargeRightsList);
}
// 新增优惠券活动
if (activityVo.getDiscountType().equals(Activity.DISCOUNT_TYPE_优惠券) && !CommUtil.isEmptyOrNull(activityVo.getCouponList())) {
List couponList = activityVo.getCouponList().stream().peek(coupon -> {
BeanUtils.copyProperties(activity, coupon, "id", "name");
coupon.setActivityId(activity.getId());
// coupon.setStatus(Coupon.STATUS_有效);
}).collect(Collectors.toList());
couponService.saveBatch(couponList);
}
// TODO 加入活动延迟启停队列
}
/**
* 主活动列表
*
* @param params
* @return
*/
@Override
public PageBean listActivity(ActivityQueryParam params) {
PageHelper.startPage(params.getPageNum(), params.getPageSize());
var list = lambdaQuery()
.like(!CommUtil.isEmptyOrNull(params.getName()), Activity::getName, params.getName())
.eq(params.getStatus() != null, Activity::getStatus, params.getStatus())
.eq(params.getDiscountType() != null, Activity::getDiscountType, params.getDiscountType())
.gt(params.getStartTime() != null, Activity::getStartTime, params.getStartTime())
.lt(params.getEndTime() != null, Activity::getEndTime, params.getEndTime())
.orderByDesc(Activity::getId)
.list();
return new PageBean<>(list);
}
/**
* 活动详情
*
* @param activityId
* @return
*/
@Override
public ActivityVo activityDetail(String activityId) {
var activity = lambdaQuery().eq(Activity::getId, activityId).one();
var activityVo = new ActivityVo();
BeanUtils.copyProperties(activity, activityVo);
if (activity.getDiscountType().equals(DISCOUNT_TYPE_服务费折扣权益)) {
var rechargeRightsList = rechargeRightsService.lambdaQuery().eq(RechargeRights::getActivityId, activityId).list();
activityVo.setRechargeRightsList(rechargeRightsList);
var activityStationIds = activityStationService.lambdaQuery().eq(ActivityStation::getActivityId, activityId).list().stream().map(ActivityStation::getStationId).toList();
if (CommUtil.isNotEmptyAndNull(activityStationIds)) {
activityVo.setStationIds(activityStationIds);
//var stationList = stationService.lambdaQuery().in(Station::getStationId, activityStationIds).list();
//activityVo.setStationList(stationList);
}
} else if (activity.getDiscountType().equals(DISCOUNT_TYPE_优惠券)) {
List couponList = couponService.lambdaQuery().eq(Coupon::getActivityId, activityId).list();
activityVo.setCouponList(couponList);
var activityStationIds = activityStationService.lambdaQuery().eq(ActivityStation::getActivityId, activityId).list().stream().map(ActivityStation::getStationId).toList();
if (CommUtil.isNotEmptyAndNull(activityStationIds)) {
activityVo.setStationIds(activityStationIds);
// var stationList = stationService.lambdaQuery().in(Station::getStationId, activityStationIds).list();
// activityVo.setStationList(stationList);
}
}
return activityVo;
}
/**
* 终止活动
*
* @param activityId
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void terminateActivity(String activityId) {
var activity = lambdaQuery().eq(Activity::getId, activityId).one();
if (activity != null) {
// 根据活动类型分别处理
if (activity.getDiscountType().equals(Activity.DISCOUNT_TYPE_服务费折扣权益)) {
lambdaUpdate().set(Activity::getStatus, Activity.STATUS_已结束).eq(Activity::getId, activityId).update();
rechargeRightsService.lambdaUpdate().set(RechargeRights::getStatus, Activity.STATUS_已结束).eq(RechargeRights::getActivityId, activityId).update();
// 修改banner状态为失效
bannerService.lambdaUpdate().set(Banner::getStatus, Banner.STATUS_有效).eq(Banner::getActivityId, activityId).update();
}
if (activity.getDiscountType().equals(Activity.DISCOUNT_TYPE_优惠券)) {
var couponList = couponService.lambdaQuery().eq(Coupon::getActivityId, activityId).list();
// 优惠券状态修改为已结束
if (CommUtil.isNotEmptyAndNull(couponList)) {
couponService.updateBatchById(couponList.stream().peek(coupon -> coupon.setStatus(Activity.STATUS_已结束)).toList());
// redis 优惠券失效,删除数据
var userCoupons = redisTemplate.opsForSet().members(RedisKeys.COUPON_ID_TO_USERS);
if (userCoupons != null) {
couponList.forEach(coupon -> {
// 筛选出活动相关的数据
var coupon2user = userCoupons.stream().filter(userCoupon -> userCoupon.startsWith(String.valueOf(coupon.getId()))).toArray();
if (coupon2user.length > 0) {
redisTemplate.opsForSet().remove(RedisKeys.COUPON_ID_TO_USERS, coupon2user);
}
});
}
}
}
// 修改活动状态
lambdaUpdate().set(Activity::getStatus, Activity.STATUS_已结束).eq(Activity::getId, activityId).update();
// 修改站点活动关联表状态
activityStationService.lambdaUpdate().set(ActivityStation::getStatus, Activity.STATUS_已结束).eq(ActivityStation::getActivityId, activityId).update();
}
}
/**
* 异步处理充值活动
*
* @param userId
* @param rechargeAmount
*/
@Override
@Async
public void handleRechargeActivity(long userId, int rechargeAmount) {
asyncHandleRechargeActivity(userId, rechargeAmount);
}
/**
* 处理充值活动
*/
@Transactional(rollbackFor = Exception.class)
public void asyncHandleRechargeActivity(long userId, int rechargeAmount) {
log.info("RechargeActivityTask run....");
// 进行中的充值权益活动
var activity = lambdaQuery().eq(Activity::getDiscountType, DISCOUNT_TYPE_服务费折扣权益).eq(Activity::getStatus, Activity.STATUS_进行中).one();
// 充值金额,匹配到到具体的充值权益,生成用户权益
if (activity != null) {
var rechargeRights = rechargeRightsService.lambdaQuery().eq(RechargeRights::getActivityId, activity.getId())
.le(RechargeRights::getAmountMin, rechargeAmount)
.gt(RechargeRights::getAmountMax, rechargeAmount)
.one();
if (rechargeRights != null) {
var userRechargeRights = new UserRechargeRights().setRightsId(rechargeRights.getId()).setUserId(userId).setRightsBalance(rechargeAmount);
BeanUtils.copyProperties(rechargeRights, userRechargeRights, "id", "createTime", "updateTime");
// 计算有效期
var endTime = LocalDateTime.now().with(LocalTime.MAX).plusDays(rechargeRights.getValidity() - 1);
userRechargeRightsService.save(userRechargeRights.setStartTime(LocalDateTime.now()).setEndTime(endTime));
}
} else {
}
log.info("RechargeActivityTask run end....");
}
}