|
|
@@ -0,0 +1,642 @@
|
|
|
+package com.fs.course.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.fs.common.core.domain.R;
|
|
|
+import com.fs.common.core.redis.RedisCache;
|
|
|
+import com.fs.common.utils.DateUtils;
|
|
|
+import com.fs.common.utils.StringUtils;
|
|
|
+import com.fs.company.vo.RedPacketMoneyVO;
|
|
|
+import com.fs.course.domain.*;
|
|
|
+import com.fs.course.mapper.*;
|
|
|
+import com.fs.course.param.FsCourseSendRewardUParam;
|
|
|
+import com.fs.course.service.IFsCourseRewardRoundService;
|
|
|
+import com.fs.course.service.IFsUserCourseVideoService;
|
|
|
+import com.fs.course.utils.Range;
|
|
|
+import com.fs.his.domain.FsUser;
|
|
|
+import com.fs.his.domain.FsUserIntegralLogs;
|
|
|
+import com.fs.his.domain.FsUserWx;
|
|
|
+import com.fs.his.mapper.FsUserMapper;
|
|
|
+import com.fs.his.param.WxSendRedPacketParam;
|
|
|
+import com.fs.his.service.IFsStorePaymentService;
|
|
|
+import com.fs.his.service.IFsUserIntegralLogsService;
|
|
|
+import com.fs.his.service.IFsUserWxService;
|
|
|
+import com.fs.qw.mapper.LuckyBagCollectRecordMapper;
|
|
|
+import com.fs.system.service.ISysConfigService;
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 奖励领取记录Service业务层处理
|
|
|
+ *
|
|
|
+ * @author 杨衍生
|
|
|
+ * @date 2025-09-02
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class FsCourseRewardRoundServiceImpl extends ServiceImpl<FsCourseRewardRoundMapper, FsCourseRewardRound> implements IFsCourseRewardRoundService {
|
|
|
+ @Autowired
|
|
|
+ private IFsUserCourseVideoService courseVideoService;
|
|
|
+ private static final Logger logger = LoggerFactory.getLogger(FsUserCourseVideoServiceImpl.class);
|
|
|
+ @Autowired
|
|
|
+ private RedisCache redisCache;
|
|
|
+ @Autowired
|
|
|
+ private IFsUserWxService fsUserWxService;
|
|
|
+ @Autowired
|
|
|
+ private FsUserCourseVideoMapper fsUserCourseVideoMapper;
|
|
|
+ @Autowired
|
|
|
+ private FsCourseWatchLogMapper courseWatchLogMapper;
|
|
|
+ @Autowired
|
|
|
+ private ISysConfigService configService;
|
|
|
+ @Autowired
|
|
|
+ private FsUserCourseVideoRedPackageMapper fsUserCourseVideoRedPackageMapper;
|
|
|
+ @Autowired
|
|
|
+ private IFsUserIntegralLogsService iFsUserIntegralLogsService;
|
|
|
+ @Autowired
|
|
|
+ private FsUserMapper fsUserMapper;
|
|
|
+ @Autowired
|
|
|
+ private IFsStorePaymentService paymentService;
|
|
|
+ @Autowired
|
|
|
+ private FsCourseRedPacketLogMapper redPacketLogMapper;
|
|
|
+ @Autowired
|
|
|
+ private FsCourseRewardMapper fsCourseRewardMapper;
|
|
|
+ @Autowired
|
|
|
+ private FsCourseRewardVideoRelationMapper fsCourseRewardVideoRelationMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private LuckyBagCollectRecordMapper luckyBagCollectRecordMapper;
|
|
|
+ /**
|
|
|
+ * 查询奖励领取记录
|
|
|
+ *
|
|
|
+ * @param id 奖励领取记录主键
|
|
|
+ * @return 奖励领取记录
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public FsCourseRewardRound selectFsCourseRewardRoundById(Long id)
|
|
|
+ {
|
|
|
+ return baseMapper.selectFsCourseRewardRoundById(id);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询奖励领取记录列表
|
|
|
+ *
|
|
|
+ * @param rewardRound 奖励领取记录
|
|
|
+ * @return 奖励领取记录
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<FsCourseRewardRound> selectFsCourseRewardRoundList(FsCourseRewardRound rewardRound)
|
|
|
+ {
|
|
|
+ return baseMapper.selectFsCourseRewardRoundList(rewardRound);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 新增奖励领取记录
|
|
|
+ *
|
|
|
+ * @param rewardRound 奖励领取记录
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public int insertFsCourseRewardRound(FsCourseRewardRound rewardRound)
|
|
|
+ {
|
|
|
+ FsCourseWatchLog fsCourseWatchLog = courseWatchLogMapper.getWatchCourseVideo(
|
|
|
+ rewardRound.getUserId(), rewardRound.getVideoId(),rewardRound.getQwUserId(),rewardRound.getQwExternalId());
|
|
|
+ if (ObjectUtil.isNotEmpty(fsCourseWatchLog)){
|
|
|
+ rewardRound.setWatchId(fsCourseWatchLog.getLogId());
|
|
|
+ rewardRound.setCompanyId(fsCourseWatchLog.getCompanyId());
|
|
|
+ }
|
|
|
+ rewardRound.setCreateTime(DateUtils.getNowDate());
|
|
|
+ return baseMapper.insertFsCourseRewardRound(rewardRound);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 修改奖励领取记录
|
|
|
+ *
|
|
|
+ * @param rewardRound 奖励领取记录
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public int updateFsCourseRewardRound(FsCourseRewardRound rewardRound)
|
|
|
+ {
|
|
|
+ rewardRound.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ return baseMapper.updateFsCourseRewardRound(rewardRound);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量删除奖励领取记录
|
|
|
+ *
|
|
|
+ * @param ids 需要删除的奖励领取记录主键
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public int deleteFsCourseRewardRoundByIds(Long[] ids)
|
|
|
+ {
|
|
|
+ return baseMapper.deleteFsCourseRewardRoundByIds(ids);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除奖励领取记录信息
|
|
|
+ *
|
|
|
+ * @param id 奖励领取记录主键
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public int deleteFsCourseRewardRoundById(Long id)
|
|
|
+ {
|
|
|
+ return baseMapper.deleteFsCourseRewardRoundById(id);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R claim(FsCourseRewardRound rewardRound) {
|
|
|
+ Double inputSecond = Double.parseDouble(rewardRound.getSecond());
|
|
|
+ if (inputSecond == null) {
|
|
|
+ return R.error(400, "请输入有效时长");
|
|
|
+ }
|
|
|
+ FsCourseWatchLog fsCourseWatchLog = courseWatchLogMapper.getWatchCourseVideo(
|
|
|
+ rewardRound.getUserId(), rewardRound.getVideoId(),rewardRound.getQwUserId(),rewardRound.getQwExternalId());
|
|
|
+ if (fsCourseWatchLog == null) {
|
|
|
+ return R.error(502, "未找到观看记录");
|
|
|
+ }
|
|
|
+ String redisKey = "h5user:watch:duration:" + fsCourseWatchLog.getQwUserId()+ ":" + fsCourseWatchLog.getQwExternalContactId() + ":" + fsCourseWatchLog.getVideoId();
|
|
|
+ String videoRedisKey = "h5user:video:duration:" + fsCourseWatchLog.getVideoId();
|
|
|
+ String redisSecondStr = redisCache.getCacheObject(redisKey);
|
|
|
+ Long videoRedisKeyStr = redisCache.getCacheObject(videoRedisKey);
|
|
|
+// String redisSecondStr = "304";
|
|
|
+// String videoRedisKeyStr = "1000";
|
|
|
+ if (ObjectUtil.isEmpty(redisSecondStr) || ObjectUtil.isEmpty(videoRedisKeyStr)) {
|
|
|
+
|
|
|
+ return R.error(500, "系统配置错误,请稍后再试");
|
|
|
+ }
|
|
|
+ double range = 60.0;
|
|
|
+ double lowerBound = Long.parseLong(redisSecondStr) - range;
|
|
|
+ double upperBound = Long.parseLong(redisSecondStr) + range;
|
|
|
+ if (inputSecond < lowerBound || inputSecond > upperBound) {
|
|
|
+ return R.error(501, "您的观看时长不符合领取条件");
|
|
|
+ }
|
|
|
+ FsCourseRewardRound fsCourseRewardRound = new FsCourseRewardRound();
|
|
|
+ fsCourseRewardRound.setWatchId(fsCourseWatchLog.getLogId());
|
|
|
+ fsCourseRewardRound.setUserId(rewardRound.getUserId());
|
|
|
+ List<FsCourseRewardRound> fsCourseRewardRounds = baseMapper.selectFsCourseRewardRoundList(fsCourseRewardRound);
|
|
|
+
|
|
|
+ FsCourseRewardVideoRelation fsCourseRewardVideoRelation = new FsCourseRewardVideoRelation();
|
|
|
+ fsCourseRewardVideoRelation.setVideoSectionId(rewardRound.getVideoId());
|
|
|
+ fsCourseRewardVideoRelation.setCompanyId(rewardRound.getCompanyId());
|
|
|
+// fsCourseRewardVideoRelation.setRewardId(rewardRound.getRewardId());
|
|
|
+ List<FsCourseRewardVideoRelation> fsCourseRewardVideoRelationList = fsCourseRewardVideoRelationMapper.selectFsCourseRewardVideoRelationList(fsCourseRewardVideoRelation);
|
|
|
+
|
|
|
+ if (CollectionUtils.isEmpty(fsCourseRewardVideoRelationList)){
|
|
|
+ return R.error(504, "没有配置领取规则,请联系客服!");
|
|
|
+ }
|
|
|
+ if (fsCourseRewardVideoRelationList.size()>1){
|
|
|
+ if (CollectionUtils.isNotEmpty(fsCourseRewardRounds) && fsCourseRewardRounds.size() >= 2) {
|
|
|
+ return R.error(504, "已经领取过两次了,不能领取了");
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ if (CollectionUtils.isNotEmpty(fsCourseRewardRounds) && fsCourseRewardRounds.size() >= 1) {
|
|
|
+ return R.error(504, "已经领取过了,不能领取了");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ double actualPercentage = (inputSecond / videoRedisKeyStr) * 100;
|
|
|
+
|
|
|
+ String targetPercentage = findClosestPercentage(actualPercentage);
|
|
|
+ if (targetPercentage == null) {
|
|
|
+ return R.error(503, "您的观看时长不在任何奖励区间内");
|
|
|
+ }
|
|
|
+ FsCourseRewardVideoRelation fsCourseRewardVideoRelation1 = new FsCourseRewardVideoRelation();
|
|
|
+ fsCourseRewardVideoRelation1.setVideoSectionId(rewardRound.getVideoId());
|
|
|
+ fsCourseRewardVideoRelation1.setCompanyId(rewardRound.getCompanyId());
|
|
|
+ fsCourseRewardVideoRelation1.setRewardId(rewardRound.getRewardId());
|
|
|
+ fsCourseRewardVideoRelation1.setMark(targetPercentage+"%");
|
|
|
+ System.out.println("参数:"+fsCourseRewardVideoRelation1);
|
|
|
+ List<FsCourseRewardVideoRelation> fsCourseRewardVideoRelationList1 = fsCourseRewardVideoRelationMapper
|
|
|
+ .selectFsCourseRewardVideoRelationList(fsCourseRewardVideoRelation1);
|
|
|
+ FsCourseRewardVideoRelation fsCourseRewardVideoRelation2 = new FsCourseRewardVideoRelation();
|
|
|
+ if (CollectionUtils.isNotEmpty(fsCourseRewardVideoRelationList1)){
|
|
|
+ fsCourseRewardVideoRelation2 = fsCourseRewardVideoRelationList1.get(0);
|
|
|
+ }else {
|
|
|
+ return R.error(503, "当前时间段不能领取!");
|
|
|
+ }
|
|
|
+ FsCourseReward fsCourseReward = fsCourseRewardMapper.selectFsCourseRewardById(rewardRound.getRewardId());
|
|
|
+
|
|
|
+ rewardRound.setRewardType(fsCourseReward.getRewardType());
|
|
|
+ rewardRound.setRewardVideoRelationId(fsCourseRewardVideoRelation2.getId());
|
|
|
+ List<FsCourseRewardRound> rewardRounds = selectFsCourseRewardRoundList(rewardRound);
|
|
|
+ if (CollectionUtils.isNotEmpty(rewardRounds)){
|
|
|
+ return R.error(503, "已经领取过奖励了,不能在领取了");
|
|
|
+ }
|
|
|
+ if (ObjectUtil.isNotEmpty(rewardRound.getStatus())&&(!rewardRound.getStatus().equals(1L))){
|
|
|
+ rewardRound.setActualRewards("0");
|
|
|
+ insertFsCourseRewardRound(rewardRound);
|
|
|
+ return R.ok();
|
|
|
+ }
|
|
|
+ FsCourseSendRewardUParam param = new FsCourseSendRewardUParam();
|
|
|
+// param.setCourseId(rewardRound.getCourseId());
|
|
|
+ param.setUserId(rewardRound.getUserId());
|
|
|
+ param.setVideoId(rewardRound.getVideoId());
|
|
|
+ param.setLinkType(rewardRound.getLinkType());
|
|
|
+ param.setRewardType(2);
|
|
|
+ param.setQwUserId(rewardRound.getQwUserId());
|
|
|
+ param.setQwExternalId(rewardRound.getQwExternalId());
|
|
|
+ Integer auctual = findIntegral(fsCourseReward.getActualRewards());
|
|
|
+ R result = sendReward(param,auctual);
|
|
|
+ rewardRound.setActualRewards(String.valueOf(auctual));
|
|
|
+ if (result.get("code").equals(200)){
|
|
|
+ insertFsCourseRewardRound(rewardRound);
|
|
|
+ return R.ok("芳华币+"+auctual);
|
|
|
+ }else {
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 随机宝箱奖励数
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Integer findIntegral(String listString) {
|
|
|
+ List<Map> items = JSONObject.parseArray(listString, Map.class);
|
|
|
+
|
|
|
+ // 根据probability概率随机选择一个项
|
|
|
+ Map<String, Object> selectedItem = new HashMap<>();
|
|
|
+
|
|
|
+ // 1. 提取并转换概率值
|
|
|
+ List<Double> probabilities = new ArrayList<>();
|
|
|
+ double totalProbability = 0.0;
|
|
|
+
|
|
|
+ for (Map item : items) {
|
|
|
+ String probStr = (String) item.get("probability");
|
|
|
+ // 移除百分号并转换为小数
|
|
|
+ double prob = Double.parseDouble(probStr.replace("%", "")) / 100.0;
|
|
|
+ probabilities.add(prob);
|
|
|
+ totalProbability += prob;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 验证概率总和(应该是1.0,即100%)
|
|
|
+ if (Math.abs(totalProbability - 1.0) > 0.0001) {
|
|
|
+ for (int i = 0; i < probabilities.size(); i++) {
|
|
|
+ probabilities.set(i, probabilities.get(i) / totalProbability);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 生成随机数并选择
|
|
|
+ double random = Math.random();
|
|
|
+ double cumulativeProbability = 0.0;
|
|
|
+
|
|
|
+ for (int i = 0; i < probabilities.size(); i++) {
|
|
|
+ cumulativeProbability += probabilities.get(i);
|
|
|
+ if (random <= cumulativeProbability) {
|
|
|
+ selectedItem = items.get(i);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Integer amount = (Integer) selectedItem.get("amount");
|
|
|
+ return amount;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发放奖励
|
|
|
+ * @param param
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private R sendReward(FsCourseSendRewardUParam param,Integer integral) {
|
|
|
+ FsUser user = fsUserMapper.selectFsUserByUserId(param.getUserId());
|
|
|
+ if (user.getStatus()==0){
|
|
|
+ return R.error("会员被停用,无权限,请联系客服!");
|
|
|
+ }
|
|
|
+ FsCourseWatchLog log = new FsCourseWatchLog();
|
|
|
+
|
|
|
+ //判断链接类型
|
|
|
+ if (param.getLinkType()!=null&¶m.getLinkType()==1){
|
|
|
+ FsCourseRedPacketLog packetLog = redPacketLogMapper.selectFsCourseRedPacketLogByTemporary(param.getVideoId(),param.getUserId());
|
|
|
+ if (packetLog!=null){
|
|
|
+ return R.error("奖励已发放");
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ log = courseWatchLogMapper.getWatchCourseVideo(param.getUserId(),param.getVideoId(),param.getQwUserId(),param.getQwExternalId());
|
|
|
+ if (log==null){
|
|
|
+ return R.error("无记录");
|
|
|
+ }
|
|
|
+ if (log.getRewardType()!=null){
|
|
|
+ return R.error("奖励已发放");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
|
|
|
+ //发放奖励
|
|
|
+ switch (param.getRewardType()){
|
|
|
+ case 2:
|
|
|
+ //增加积分
|
|
|
+ FsUser userMap=new FsUser();
|
|
|
+ userMap.setUserId(user.getUserId());
|
|
|
+ userMap.setIntegral(user.getIntegral()+integral);
|
|
|
+
|
|
|
+ fsUserMapper.updateFsUser(userMap);
|
|
|
+ FsUserIntegralLogs integralLogs = new FsUserIntegralLogs();
|
|
|
+ integralLogs.setIntegral(integral.longValue());
|
|
|
+ integralLogs.setUserId(user.getUserId());
|
|
|
+ integralLogs.setBalance(userMap.getIntegral());
|
|
|
+ integralLogs.setLogType(22);
|
|
|
+ integralLogs.setBusinessId(StringUtils.isNotEmpty(log.getLogId().toString()) ? log.getLogId().toString() : null);
|
|
|
+ integralLogs.setCreateTime(new Date());
|
|
|
+ integralLogs.setNickName(user.getNickName());
|
|
|
+ integralLogs.setPhone(user.getPhone());
|
|
|
+ //integralLogs.setId(integralLogsService.getFsUserIntegralLogsInsertId());
|
|
|
+// fsUserIntegralLogsMapper.insertFsUserIntegralLogs(integralLogs);
|
|
|
+ iFsUserIntegralLogsService.insertFsUserIntegralLogs(integralLogs);
|
|
|
+
|
|
|
+ return R.ok("奖励发放成功");
|
|
|
+ default:
|
|
|
+ return R.error("参数错误!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理用户与小程序的绑定
|
|
|
+ */
|
|
|
+ private void handleFsUserWx(FsUser user,String appId) {
|
|
|
+ FsUserWx fsUserWx = new FsUserWx();
|
|
|
+ fsUserWx.setType(1);
|
|
|
+ fsUserWx.setFsUserId(user.getUserId());
|
|
|
+ fsUserWx.setAppId(appId);
|
|
|
+ fsUserWx.setOpenId(user.getCourseMaOpenId());
|
|
|
+ fsUserWx.setUnionId(user.getUnionId());
|
|
|
+ fsUserWx.setCreateTime(new Date());
|
|
|
+ fsUserWx.setUpdateTime(new Date());
|
|
|
+ fsUserWxService.saveOrUpdateByUniqueKey(fsUserWx);
|
|
|
+
|
|
|
+ logger.info("zyp \n 【更新或插入用户与小程序{}的绑定关系】:{}", appId, user.getUserId());
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R isClaim(FsCourseRewardRound rewardRound) {
|
|
|
+ Double inputSecond = Double.parseDouble(rewardRound.getSecond());
|
|
|
+ if (inputSecond == null) {
|
|
|
+ return R.error(400, "请输入有效时长");
|
|
|
+ }
|
|
|
+ FsCourseWatchLog fsCourseWatchLog = courseWatchLogMapper.getWatchCourseVideo(
|
|
|
+ rewardRound.getUserId(), rewardRound.getVideoId(),rewardRound.getQwUserId(),rewardRound.getQwExternalId());
|
|
|
+ if (fsCourseWatchLog == null) {
|
|
|
+ return R.error(502, "未找到观看记录");
|
|
|
+ }
|
|
|
+ String redisKey = "h5user:watch:duration:" + fsCourseWatchLog.getQwUserId()+ ":" + fsCourseWatchLog.getQwExternalContactId() + ":" + fsCourseWatchLog.getVideoId();
|
|
|
+ String videoRedisKey = "h5user:video:duration:" + fsCourseWatchLog.getVideoId();
|
|
|
+ String redisSecondStr = redisCache.getCacheObject(redisKey);
|
|
|
+ Long videoRedisKeyStr = redisCache.getCacheObject(videoRedisKey);
|
|
|
+// String redisSecondStr = "304";
|
|
|
+// String videoRedisKeyStr = "1000";
|
|
|
+ if (ObjectUtil.isEmpty(redisSecondStr) || ObjectUtil.isEmpty(videoRedisKeyStr)) {
|
|
|
+
|
|
|
+ return R.error(500, "系统配置错误,请稍后再试");
|
|
|
+ }
|
|
|
+ double range = 60.0;
|
|
|
+ double lowerBound = Long.parseLong(redisSecondStr) - range;
|
|
|
+ double upperBound = Long.parseLong(redisSecondStr) + range;
|
|
|
+ if (inputSecond < lowerBound || inputSecond > upperBound) {
|
|
|
+ return R.error(501, "您的观看时长不符合领取条件");
|
|
|
+ }
|
|
|
+ FsCourseRewardRound fsCourseRewardRound = new FsCourseRewardRound();
|
|
|
+ fsCourseRewardRound.setWatchId(fsCourseWatchLog.getLogId());
|
|
|
+ fsCourseRewardRound.setUserId(rewardRound.getUserId());
|
|
|
+ List<FsCourseRewardRound> fsCourseRewardRounds = baseMapper.selectFsCourseRewardRoundList(fsCourseRewardRound);
|
|
|
+
|
|
|
+ FsCourseRewardVideoRelation fsCourseRewardVideoRelation = new FsCourseRewardVideoRelation();
|
|
|
+ fsCourseRewardVideoRelation.setVideoSectionId(rewardRound.getVideoId());
|
|
|
+ fsCourseRewardVideoRelation.setCompanyId(rewardRound.getCompanyId());
|
|
|
+// fsCourseRewardVideoRelation.setRewardId(rewardRound.getRewardId());
|
|
|
+ List<FsCourseRewardVideoRelation> fsCourseRewardVideoRelationList = fsCourseRewardVideoRelationMapper.selectFsCourseRewardVideoRelationList(fsCourseRewardVideoRelation);
|
|
|
+
|
|
|
+ if (CollectionUtils.isEmpty(fsCourseRewardVideoRelationList)){
|
|
|
+ return R.error(504, "没有配置领取规则,请联系客服!");
|
|
|
+ }
|
|
|
+ if (fsCourseRewardVideoRelationList.size()>1){
|
|
|
+ if (CollectionUtils.isNotEmpty(fsCourseRewardRounds) && fsCourseRewardRounds.size() >= 2) {
|
|
|
+ return R.error(504, "已经领取过两次了,不能领取了");
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ if (CollectionUtils.isNotEmpty(fsCourseRewardRounds) && fsCourseRewardRounds.size() >= 1) {
|
|
|
+ return R.error(504, "已经领取过了,不能领取了");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ double actualPercentage = (inputSecond / videoRedisKeyStr) * 100;
|
|
|
+
|
|
|
+ String targetPercentage = findClosestPercentage(actualPercentage);
|
|
|
+ if (targetPercentage == null) {
|
|
|
+ return R.error(503, "您的观看时长不在任何奖励区间内");
|
|
|
+ }
|
|
|
+ FsCourseRewardVideoRelation fsCourseRewardVideoRelation1 = new FsCourseRewardVideoRelation();
|
|
|
+ fsCourseRewardVideoRelation1.setVideoSectionId(rewardRound.getVideoId());
|
|
|
+ fsCourseRewardVideoRelation1.setCompanyId(rewardRound.getCompanyId());
|
|
|
+ fsCourseRewardVideoRelation1.setRewardId(rewardRound.getRewardId());
|
|
|
+ fsCourseRewardVideoRelation1.setMark(targetPercentage+"%");
|
|
|
+ System.out.println("参数:"+fsCourseRewardVideoRelation1);
|
|
|
+ List<FsCourseRewardVideoRelation> fsCourseRewardVideoRelationList1 = fsCourseRewardVideoRelationMapper
|
|
|
+ .selectFsCourseRewardVideoRelationList(fsCourseRewardVideoRelation1);
|
|
|
+ FsCourseRewardVideoRelation fsCourseRewardVideoRelation2 = new FsCourseRewardVideoRelation();
|
|
|
+ if (CollectionUtils.isNotEmpty(fsCourseRewardVideoRelationList1)){
|
|
|
+ fsCourseRewardVideoRelation2 = fsCourseRewardVideoRelationList1.get(0);
|
|
|
+ }else {
|
|
|
+ return R.error(503, "当前时间段不能领取!");
|
|
|
+ }
|
|
|
+ FsCourseReward fsCourseReward = fsCourseRewardMapper.selectFsCourseRewardById(rewardRound.getRewardId());
|
|
|
+
|
|
|
+ rewardRound.setRewardType(fsCourseReward.getRewardType());
|
|
|
+ rewardRound.setRewardVideoRelationId(fsCourseRewardVideoRelation2.getId());
|
|
|
+ List<FsCourseRewardRound> rewardRounds = selectFsCourseRewardRoundList(rewardRound);
|
|
|
+ if (CollectionUtils.isNotEmpty(rewardRounds)){
|
|
|
+ return R.error(503, "已经领取过奖励了,不能在领取了");
|
|
|
+ }
|
|
|
+ return R.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 辅助方法:查找最接近的配置百分比
|
|
|
+ private String findClosestPercentage(double actualPercentage) {
|
|
|
+ Map<String, Range<Double>> percentageRanges = new LinkedHashMap<>();
|
|
|
+ percentageRanges.put("10", Range.between(5.0, 15.0));
|
|
|
+ percentageRanges.put("20", Range.between(15.0, 25.0));
|
|
|
+ percentageRanges.put("30", Range.between(25.0, 35.0));
|
|
|
+ percentageRanges.put("40", Range.between(35.0, 45.0));
|
|
|
+ percentageRanges.put("50", Range.between(45.0, 55.0));
|
|
|
+ percentageRanges.put("70", Range.between(65.0, 75.0));
|
|
|
+ percentageRanges.put("80", Range.between(75.0, 85.0));
|
|
|
+
|
|
|
+ for (Map.Entry<String, Range<Double>> entry : percentageRanges.entrySet()) {
|
|
|
+ if (entry.getValue().contains(actualPercentage)) {
|
|
|
+ return entry.getKey();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 同步公司奖励金额(按状态区分初始化与每日更新)
|
|
|
+ *
|
|
|
+ * @param status 0=初始化统计(统计截止昨日23:59:59之前所有数据)
|
|
|
+ * 1=每日统计(统计昨日00:00:00 - 昨日23:59:59的数据)
|
|
|
+ * @return 按公司统计的红包金额列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<RedPacketMoneyVO> syncUpdatedCompanyAmount(Integer status) {
|
|
|
+ // 定义时间变量
|
|
|
+ LocalDateTime startTime = null;
|
|
|
+ LocalDateTime endTime;
|
|
|
+ String start = null;
|
|
|
+ String end = null;
|
|
|
+
|
|
|
+ // 获取Redis缓存标识
|
|
|
+ Long kcdate = redisCache.getCacheObject("syncUpdatedCompanyAmount");
|
|
|
+
|
|
|
+ // 定义日期格式化器
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
+
|
|
|
+ // 校验入参
|
|
|
+ if (status == null) {
|
|
|
+ logger.warn("【syncUpdatedCompanyAmount】status参数为空,默认执行每日统计逻辑。");
|
|
|
+ status = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ if (status.equals(0)
|
|
|
+ && ObjectUtil.isEmpty(kcdate)
|
|
|
+ ) {
|
|
|
+ // 初始化逻辑:统计截止到昨天23:59:59前的所有数据
|
|
|
+ LocalDate yesterdayEnd = LocalDate.now().minusDays(1);
|
|
|
+ endTime = yesterdayEnd.atTime(23, 59, 59);
|
|
|
+ end = endTime.format(formatter);
|
|
|
+
|
|
|
+ logger.info("【初始化公司奖励金额统计】截止时间:{}", end);
|
|
|
+
|
|
|
+ List<RedPacketMoneyVO> resultList = baseMapper.selectFsCourseRewardRoundByAmount(null, end);
|
|
|
+ logger.info("【初始化公司奖励金额统计】共统计公司数:{}",
|
|
|
+ resultList != null ? resultList.size() : 0);
|
|
|
+ return Optional.ofNullable(resultList).orElse(Collections.emptyList());
|
|
|
+
|
|
|
+ } else {
|
|
|
+ // 每日统计逻辑:统计昨天整天的数据
|
|
|
+ LocalDate yesterday = LocalDate.now().minusDays(1);
|
|
|
+ startTime = yesterday.atStartOfDay();
|
|
|
+ endTime = yesterday.atTime(23, 59, 59);
|
|
|
+
|
|
|
+ start = startTime.format(formatter);
|
|
|
+ end = endTime.format(formatter);
|
|
|
+
|
|
|
+ logger.info("【每日公司奖励金额统计】统计时间范围:{} - {}", start, end);
|
|
|
+
|
|
|
+ List<RedPacketMoneyVO> resultList = baseMapper.selectFsCourseRewardRoundByAmount(start, end);
|
|
|
+ logger.info("【每日公司奖励金额统计】共统计公司数:{}",
|
|
|
+ resultList != null ? resultList.size() : 0);
|
|
|
+ return Optional.ofNullable(resultList).orElse(Collections.emptyList());
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("【公司奖励金额统计异常】status={}, start={}, end={}, error={}",
|
|
|
+ status, start, end, e.getMessage(), e);
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 同步公司奖励金额(按状态区分初始化与每日更新) 福袋
|
|
|
+ *
|
|
|
+ * @param status 0=初始化统计(统计截止昨日23:59:59之前所有数据)
|
|
|
+ * 1=每日统计(统计昨日00:00:00 - 昨日23:59:59的数据)
|
|
|
+ * @return 按公司统计的红包金额列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<RedPacketMoneyVO> syncUpdatedCompanyAmountForLuckyBag(Integer status) {
|
|
|
+ // 定义时间变量
|
|
|
+ LocalDateTime startTime = null;
|
|
|
+ LocalDateTime endTime;
|
|
|
+ String start = null;
|
|
|
+ String end = null;
|
|
|
+
|
|
|
+ // 获取Redis缓存标识
|
|
|
+ Long kcdate = redisCache.getCacheObject("syncUpdatedCompanyAmountForLuckyBag");
|
|
|
+
|
|
|
+ // 定义日期格式化器
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
+
|
|
|
+ // 校验入参
|
|
|
+ if (status == null) {
|
|
|
+ logger.warn("【syncUpdatedCompanyAmountForLuckyBag】status参数为空,默认执行每日统计逻辑。");
|
|
|
+ status = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ if (status.equals(0)
|
|
|
+ && ObjectUtil.isEmpty(kcdate)
|
|
|
+ ) {
|
|
|
+ // 初始化逻辑:统计截止到昨天23:59:59前的所有数据
|
|
|
+ LocalDate yesterdayEnd = LocalDate.now().minusDays(1);
|
|
|
+ endTime = yesterdayEnd.atTime(23, 59, 59);
|
|
|
+ end = endTime.format(formatter);
|
|
|
+
|
|
|
+ logger.info("【初始化公司福袋奖励金额统计】截止时间:{}", end);
|
|
|
+
|
|
|
+ List<RedPacketMoneyVO> resultList = baseMapper.selectFsCourseRewardRoundByAmountForLuckyBag(null, end);
|
|
|
+ logger.info("【初始化公司福袋奖励金额统计】共统计公司数:{}",
|
|
|
+ resultList != null ? resultList.size() : 0);
|
|
|
+ return Optional.ofNullable(resultList).orElse(Collections.emptyList());
|
|
|
+
|
|
|
+ } else {
|
|
|
+ // 每日统计逻辑:统计昨天整天的数据
|
|
|
+ LocalDate yesterday = LocalDate.now().minusDays(1);
|
|
|
+ startTime = yesterday.atStartOfDay();
|
|
|
+ endTime = yesterday.atTime(23, 59, 59);
|
|
|
+
|
|
|
+ start = startTime.format(formatter);
|
|
|
+ end = endTime.format(formatter);
|
|
|
+
|
|
|
+ logger.info("【每日公司福袋奖励金额统计】统计时间范围:{} - {}", start, end);
|
|
|
+
|
|
|
+ List<RedPacketMoneyVO> resultList = baseMapper.selectFsCourseRewardRoundByAmountForLuckyBag(start, end);
|
|
|
+ logger.info("【每日公司福袋奖励金额统计】共统计公司数:{}",
|
|
|
+ resultList != null ? resultList.size() : 0);
|
|
|
+ return Optional.ofNullable(resultList).orElse(Collections.emptyList());
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("【公司奖励福袋金额统计异常】status={}, start={}, end={}, error={}",
|
|
|
+ status, start, end, e.getMessage(), e);
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void syncLuckyBagExpiry() {
|
|
|
+ int updatedRows = luckyBagCollectRecordMapper.updateLuckyBagExpiryStatus();
|
|
|
+ if (updatedRows >= 0) {
|
|
|
+ logger.info("【更新福袋领取状态】更新成功,共更新 {} 条记录", updatedRows);
|
|
|
+ } else {
|
|
|
+ logger.error("【更新福袋领取状态】更新失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询1w条指定状态且小于指定时间的数据
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<FsCourseRewardRound> get1kByStatusAndLtDate(int status, LocalDate endTime) {
|
|
|
+ return baseMapper.get1kByStatusAndLtDate(status, endTime);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|