diff --git a/src/main/java/com/sqx/common/utils/RedisKeys.java b/src/main/java/com/sqx/common/utils/RedisKeys.java index e336f71e..54ae6475 100644 --- a/src/main/java/com/sqx/common/utils/RedisKeys.java +++ b/src/main/java/com/sqx/common/utils/RedisKeys.java @@ -8,7 +8,7 @@ import cn.hutool.core.date.DateUtil; */ public class RedisKeys { - public static final String PAY_FREE_WATCH_KEY = "pay:free:watch:"; + public static final String FREE_WATCH_KEY = "free:watch:"; public static String getSysConfigKey(String key){ return "sys:config:" + key; @@ -18,8 +18,11 @@ public class RedisKeys { return "date:" + key; } - public static String getPayFreeWatchKey(Long userId) { - return PAY_FREE_WATCH_KEY + DateUtil.today() + ":" + userId; + public static String getFreeWatchKey(Long userId, boolean isPermanently) { + if (isPermanently) { + return FREE_WATCH_KEY + userId; + } + return FREE_WATCH_KEY + DateUtil.today() + ":" + userId; } public static void main(String[] args) { diff --git a/src/main/java/com/sqx/common/utils/RedisUtils.java b/src/main/java/com/sqx/common/utils/RedisUtils.java index 6761c2e6..b838cad3 100644 --- a/src/main/java/com/sqx/common/utils/RedisUtils.java +++ b/src/main/java/com/sqx/common/utils/RedisUtils.java @@ -134,6 +134,10 @@ public class RedisUtils { set(key, value, DEFAULT_EXPIRE); } + public void expire(String key, long seconds){ + redisTemplate.expire(key, seconds, TimeUnit.SECONDS); + } + public T get(String key, Class clazz, long expire) { String value = valueOperations.get(key); if (expire != NOT_EXPIRE) { @@ -142,6 +146,47 @@ public class RedisUtils { return value == null ? null : fromJson(value, clazz); } + // 判断键是否设置了过期时间 + public boolean isExpiredSet(String key) { + // 获取过期时间,单位是秒 + Long expireTime = redisTemplate.getExpire(key); + + if (expireTime == null) { + return false; // 如果返回 null,表示键不存在 + } + + return expireTime != -1; // 如果是 -1,说明没有设置过期时间 + } + + public Long getExpire(String key) { + Long currentExpireTime = redisTemplate.getExpire(key); + if (currentExpireTime == null || currentExpireTime == -2 || currentExpireTime == -1) { + return null; + } + return currentExpireTime; + } + + // 累加过期时间 + public boolean extendExpireTime(String key, long additionalTimeInSeconds) { + // 获取当前键的剩余过期时间(单位:秒) + Long currentExpireTime = redisTemplate.getExpire(key); + + if (currentExpireTime == null || currentExpireTime == -2) { + // 键不存在或已经过期,无法进行累加 + return false; + } + + if (currentExpireTime == -1) { + redisTemplate.expire(key, additionalTimeInSeconds, java.util.concurrent.TimeUnit.SECONDS); + } + + // 累加剩余过期时间和新增时间 + long newExpireTime = currentExpireTime + additionalTimeInSeconds; + + // 设置新的过期时间 + return Boolean.TRUE.equals(redisTemplate.expire(key, newExpireTime, TimeUnit.SECONDS)); + } + public T get(String key, Class clazz) { return get(key, clazz, NOT_EXPIRE); } diff --git a/src/main/java/com/sqx/config/ShiroConfig.java b/src/main/java/com/sqx/config/ShiroConfig.java index 98adf705..92ce0b02 100644 --- a/src/main/java/com/sqx/config/ShiroConfig.java +++ b/src/main/java/com/sqx/config/ShiroConfig.java @@ -41,6 +41,7 @@ public class ShiroConfig { shiroFilter.setFilters(filters); Map filterMap = new LinkedHashMap<>(); + filterMap.put("/uniCallBack/**", "anon"); filterMap.put("/course/synCourse", "anon"); filterMap.put("/webjars/**", "anon"); filterMap.put("/druid/**", "anon"); diff --git a/src/main/java/com/sqx/modules/app/controller/app/AdController.java b/src/main/java/com/sqx/modules/app/controller/app/AdController.java new file mode 100644 index 00000000..877d755e --- /dev/null +++ b/src/main/java/com/sqx/modules/app/controller/app/AdController.java @@ -0,0 +1,33 @@ +package com.sqx.modules.app.controller.app; + +import com.sqx.common.utils.Result; +import com.sqx.modules.app.annotation.Login; +import com.sqx.modules.app.service.AdService; +import com.sqx.modules.callback.service.UniAdCallbackRecordService; +import com.sqx.modules.sys.controller.AbstractController; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/app/ad") +public class AdController extends AbstractController { + + private final UniAdCallbackRecordService callbackRecordService; + private final AdService adService; + + public AdController(UniAdCallbackRecordService callbackRecordService, AdService adService) { + this.callbackRecordService = callbackRecordService; + this.adService = adService; + } + + @Login + @GetMapping("/state") + public Result getAdState(@RequestParam String extraKey, @RequestAttribute Long userId) { + return Result.success(callbackRecordService.getStateByExtraKey(userId, extraKey)); + } + + @Login + @GetMapping("/detail") + public Result getAdDetail(@RequestAttribute Long userId) { + return Result.success(adService.getDetail(userId)); + } +} diff --git a/src/main/java/com/sqx/modules/app/service/AdService.java b/src/main/java/com/sqx/modules/app/service/AdService.java new file mode 100644 index 00000000..11a61077 --- /dev/null +++ b/src/main/java/com/sqx/modules/app/service/AdService.java @@ -0,0 +1,7 @@ +package com.sqx.modules.app.service; + +import java.util.HashMap; + +public interface AdService { + HashMap getDetail(Long userId); +} diff --git a/src/main/java/com/sqx/modules/app/service/impl/AdServiceImpl.java b/src/main/java/com/sqx/modules/app/service/impl/AdServiceImpl.java new file mode 100644 index 00000000..52bff4d1 --- /dev/null +++ b/src/main/java/com/sqx/modules/app/service/impl/AdServiceImpl.java @@ -0,0 +1,29 @@ +package com.sqx.modules.app.service.impl; + +import com.sqx.common.utils.RedisUtils; +import com.sqx.modules.app.service.AdService; +import com.sqx.modules.redisService.impl.RedisServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.HashMap; + +@Service +public class AdServiceImpl implements AdService { + + private final RedisServiceImpl redisServiceImpl; + + public AdServiceImpl(RedisServiceImpl redisServiceImpl) { + this.redisServiceImpl = redisServiceImpl; + } + + @Override + public HashMap getDetail(Long userId) { + Long freeWatchRemainTime = redisServiceImpl.getFreeWatchRemainTime(userId, false); + Long permanentlyFreeWatchRemainTime = redisServiceImpl.getFreeWatchRemainTime(userId, true); + return new HashMap(){{ + put("adFreeWatchTime", permanentlyFreeWatchRemainTime); + put("payFreeWatchTime", freeWatchRemainTime); + put("totalFreeWatchTime", freeWatchRemainTime + permanentlyFreeWatchRemainTime); + }}; + } +} diff --git a/src/main/java/com/sqx/modules/callback/UniCallBackController.java b/src/main/java/com/sqx/modules/callback/UniCallBackController.java new file mode 100644 index 00000000..061ea0a9 --- /dev/null +++ b/src/main/java/com/sqx/modules/callback/UniCallBackController.java @@ -0,0 +1,28 @@ +package com.sqx.modules.callback; + +import com.sqx.common.utils.Result; +import com.sqx.modules.callback.dao.UniAdCallBackDTO; +import com.sqx.modules.callback.service.UniAdCallbackRecordService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/uniCallBack") +@Slf4j +public class UniCallBackController { + private final UniAdCallbackRecordService uniCallBackService; + + public UniCallBackController(UniAdCallbackRecordService uniCallBackService) { + this.uniCallBackService = uniCallBackService; + } + + @GetMapping("/adCallBack") + public ResponseEntity adCallBack(@RequestBody UniAdCallBackDTO callBackDTO) { + log.info("接收到uni-ad广告完播回调,回调信息: {}", callBackDTO); + return ResponseEntity.ok(uniCallBackService.adCallBack(callBackDTO)); + } +} diff --git a/src/main/java/com/sqx/modules/callback/dao/UniAdCallBackDTO.java b/src/main/java/com/sqx/modules/callback/dao/UniAdCallBackDTO.java new file mode 100644 index 00000000..7d5350c3 --- /dev/null +++ b/src/main/java/com/sqx/modules/callback/dao/UniAdCallBackDTO.java @@ -0,0 +1,16 @@ +package com.sqx.modules.callback.dao; + +import lombok.Data; +import lombok.ToString; + +@Data +@ToString +public class UniAdCallBackDTO { + private String adpid; + private String provider; + private String platform; + private String sign; + private String trans_id; + private String user_id; + private String extra; +} diff --git a/src/main/java/com/sqx/modules/callback/entity/UniAdCallbackRecord.java b/src/main/java/com/sqx/modules/callback/entity/UniAdCallbackRecord.java new file mode 100644 index 00000000..43ff1af6 --- /dev/null +++ b/src/main/java/com/sqx/modules/callback/entity/UniAdCallbackRecord.java @@ -0,0 +1,141 @@ +package com.sqx.modules.callback.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * + * @TableName uni_ad_callback_record + */ +@TableName(value ="uni_ad_callback_record") +@Data +public class UniAdCallbackRecord implements Serializable { + /** + * + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 用户id + */ + private Long userId; + + /** + * 平台 + */ + private String platform; + + /** + * 交易id + */ + private String transId; + + /** + * DCloud广告位id + */ + private String adpid; + + /** + * 广告服务商 + */ + private String provider; + + /** + * + */ + private String sign; + + /** + * 调用SDK传入并透传,自定义数据 + */ + private String extra; + + /** + * 是否播放完毕 + */ + private Integer isEnded; + + /** + * 回调时间 + */ + private Date createTime; + + /** + * 错误信息 + */ + private String errMsg; + + @TableField(exist = false) + private static final long serialVersionUID = 1L; + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that == null) { + return false; + } + if (getClass() != that.getClass()) { + return false; + } + UniAdCallbackRecord other = (UniAdCallbackRecord) that; + return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId())) + && (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId())) + && (this.getPlatform() == null ? other.getPlatform() == null : this.getPlatform().equals(other.getPlatform())) + && (this.getTransId() == null ? other.getTransId() == null : this.getTransId().equals(other.getTransId())) + && (this.getAdpid() == null ? other.getAdpid() == null : this.getAdpid().equals(other.getAdpid())) + && (this.getProvider() == null ? other.getProvider() == null : this.getProvider().equals(other.getProvider())) + && (this.getSign() == null ? other.getSign() == null : this.getSign().equals(other.getSign())) + && (this.getExtra() == null ? other.getExtra() == null : this.getExtra().equals(other.getExtra())) + && (this.getIsEnded() == null ? other.getIsEnded() == null : this.getIsEnded().equals(other.getIsEnded())) + && (this.getCreateTime() == null ? other.getCreateTime() == null : this.getCreateTime().equals(other.getCreateTime())) + && (this.getErrMsg() == null ? other.getErrMsg() == null : this.getErrMsg().equals(other.getErrMsg())); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((getId() == null) ? 0 : getId().hashCode()); + result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode()); + result = prime * result + ((getPlatform() == null) ? 0 : getPlatform().hashCode()); + result = prime * result + ((getTransId() == null) ? 0 : getTransId().hashCode()); + result = prime * result + ((getAdpid() == null) ? 0 : getAdpid().hashCode()); + result = prime * result + ((getProvider() == null) ? 0 : getProvider().hashCode()); + result = prime * result + ((getSign() == null) ? 0 : getSign().hashCode()); + result = prime * result + ((getExtra() == null) ? 0 : getExtra().hashCode()); + result = prime * result + ((getIsEnded() == null) ? 0 : getIsEnded().hashCode()); + result = prime * result + ((getCreateTime() == null) ? 0 : getCreateTime().hashCode()); + result = prime * result + ((getErrMsg() == null) ? 0 : getErrMsg().hashCode()); + return result; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()); + sb.append(" ["); + sb.append("Hash = ").append(hashCode()); + sb.append(", id=").append(id); + sb.append(", userId=").append(userId); + sb.append(", platform=").append(platform); + sb.append(", transId=").append(transId); + sb.append(", adpid=").append(adpid); + sb.append(", provider=").append(provider); + sb.append(", sign=").append(sign); + sb.append(", extra=").append(extra); + sb.append(", isEnded=").append(isEnded); + sb.append(", createTime=").append(createTime); + sb.append(", errMsg=").append(errMsg); + sb.append(", serialVersionUID=").append(serialVersionUID); + sb.append("]"); + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/sqx/modules/callback/mapper/UniAdCallbackRecordMapper.java b/src/main/java/com/sqx/modules/callback/mapper/UniAdCallbackRecordMapper.java new file mode 100644 index 00000000..fd0d4405 --- /dev/null +++ b/src/main/java/com/sqx/modules/callback/mapper/UniAdCallbackRecordMapper.java @@ -0,0 +1,20 @@ +package com.sqx.modules.callback.mapper; + +import com.sqx.modules.callback.entity.UniAdCallbackRecord; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** +* @author Administrator +* @description 针对表【uni_ad_callback_record】的数据库操作Mapper +* @createDate 2024-12-23 10:37:52 +* @Entity com.sqx.modules.callback.entity.UniAdCallbackRecord +*/ +@Mapper +public interface UniAdCallbackRecordMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/sqx/modules/callback/service/UniAdCallbackRecordService.java b/src/main/java/com/sqx/modules/callback/service/UniAdCallbackRecordService.java new file mode 100644 index 00000000..301aabbb --- /dev/null +++ b/src/main/java/com/sqx/modules/callback/service/UniAdCallbackRecordService.java @@ -0,0 +1,20 @@ +package com.sqx.modules.callback.service; + +import com.sqx.modules.callback.dao.UniAdCallBackDTO; +import com.sqx.modules.callback.entity.UniAdCallbackRecord; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.HashMap; +import java.util.Map; + +/** +* @author Administrator +* @description 针对表【uni_ad_callback_record】的数据库操作Service +* @createDate 2024-12-23 10:37:52 +*/ +public interface UniAdCallbackRecordService extends IService { + + Map adCallBack(UniAdCallBackDTO callBackDTO); + + HashMap getStateByExtraKey(Long userId, String extraKey); +} diff --git a/src/main/java/com/sqx/modules/callback/service/impl/UniAdCallbackRecordServiceImpl.java b/src/main/java/com/sqx/modules/callback/service/impl/UniAdCallbackRecordServiceImpl.java new file mode 100644 index 00000000..959f3c72 --- /dev/null +++ b/src/main/java/com/sqx/modules/callback/service/impl/UniAdCallbackRecordServiceImpl.java @@ -0,0 +1,136 @@ +package com.sqx.modules.callback.service.impl; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.digest.DigestUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.sqx.modules.app.dao.UserDao; +import com.sqx.modules.app.entity.UserEntity; +import com.sqx.modules.callback.dao.UniAdCallBackDTO; +import com.sqx.modules.callback.entity.UniAdCallbackRecord; +import com.sqx.modules.callback.service.UniAdCallbackRecordService; +import com.sqx.modules.callback.mapper.UniAdCallbackRecordMapper; +import com.sqx.modules.common.dao.CommonInfoDao; +import com.sqx.modules.common.entity.CommonInfo; +import com.sqx.modules.redisService.RedisService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; + +/** +* @author Administrator +* @description 针对表【uni_ad_callback_record】的数据库操作Service实现 +* @createDate 2024-12-23 10:37:52 +*/ +@Service +@Slf4j +public class UniAdCallbackRecordServiceImpl extends ServiceImpl + implements UniAdCallbackRecordService{ + @Value("${sqx.uni.adSecret}") + private String adSecurity; + + private final UserDao userDao; + private final CommonInfoDao commonInfoDao; + + private final RedisService redisService; + + public UniAdCallbackRecordServiceImpl(UserDao userDao, CommonInfoDao commonInfoDao, RedisService redisService) { + this.userDao = userDao; + this.commonInfoDao = commonInfoDao; + this.redisService = redisService; + } + + private String getBaseErrInfo(UniAdCallbackRecord callbackRecord) { + return StrUtil.format("广告获取免费观看时长回调异常: {}, 用户id: {}, 广告播放回调trans_id: {}", + callbackRecord.getErrMsg(), callbackRecord.getUserId(), callbackRecord.getTransId()); + } + + // 生成签名 + public static String generateSign(String secret, String transId) { + // 生成待加密的字符串 + String data = secret + ":" + transId; + + // 使用SHA-256生成签名 + return DigestUtil.sha256Hex(data); + } + + // 验证签名 + public static boolean validateSign(String secret, String transId, String providedSign) { + // 生成系统计算出来的签名 + String generatedSign = generateSign(secret, transId); + + // 比较计算出来的签名和提供的签名 + return StrUtil.equalsIgnoreCase(generatedSign, providedSign); + } + + @Override + public Map adCallBack(UniAdCallBackDTO callBackDTO) { + HashMap respData = new HashMap<>(); + UniAdCallbackRecord one = getOne(new LambdaQueryWrapper() + .eq(UniAdCallbackRecord::getTransId, callBackDTO.getTrans_id())); + if (one != null) { + log.warn("回调重复, {}", one.getTransId()); + respData.put("isValid", false); + return respData; + } + UniAdCallbackRecord callbackRecord = new UniAdCallbackRecord(); + callbackRecord.setUserId(Long.valueOf(callBackDTO.getUser_id())); + callbackRecord.setPlatform(callBackDTO.getPlatform()); + callbackRecord.setTransId(callBackDTO.getTrans_id()); + callbackRecord.setAdpid(callBackDTO.getAdpid()); + callbackRecord.setProvider(callBackDTO.getProvider()); + callbackRecord.setSign(callBackDTO.getSign()); + callbackRecord.setExtra(callBackDTO.getExtra()); + callbackRecord.setCreateTime(DateUtil.date()); + callbackRecord.setIsEnded(1); + + boolean flag = validateSign(adSecurity, callBackDTO.getTrans_id(), callBackDTO.getSign()); + if (!flag) { + callbackRecord.setErrMsg("签名验证失败"); + log.warn(getBaseErrInfo(callbackRecord)); + save(callbackRecord); + respData.put("isValid", false); + return respData; + } + + UserEntity userEntity = userDao.selectById(callBackDTO.getUser_id()); + if (userEntity == null) { + callbackRecord.setErrMsg("用户不存在"); + log.warn(getBaseErrInfo(callbackRecord)); + save(callbackRecord); + respData.put("isValid", false); + return respData; + } + + CommonInfo info = commonInfoDao.findOne(921); + if (info == null || StrUtil.isBlank(info.getValue())){ + callbackRecord.setErrMsg("CommonInfo时长时间未配置"); + log.warn(getBaseErrInfo(callbackRecord)); + save(callbackRecord); + respData.put("isValid", false); + return respData; + } + + redisService.setFreeWatchTime(callbackRecord.getUserId(), Integer.valueOf(info.getValue()), true); + save(callbackRecord); + respData.put("isValid", true); + return respData; + } + + @Override + public HashMap getStateByExtraKey(Long userId, String extraKey) { + UniAdCallbackRecord one = getOne(new LambdaQueryWrapper().eq(UniAdCallbackRecord::getUserId, userId) + .eq(UniAdCallbackRecord::getExtra, extraKey)); + return new HashMap(){{ + put("isEnded", one == null ? 0 : 1); + }}; + } +} + + + + diff --git a/src/main/java/com/sqx/modules/common/dao/CommonInfoDao.java b/src/main/java/com/sqx/modules/common/dao/CommonInfoDao.java index 558bf5e8..1712de10 100644 --- a/src/main/java/com/sqx/modules/common/dao/CommonInfoDao.java +++ b/src/main/java/com/sqx/modules/common/dao/CommonInfoDao.java @@ -20,5 +20,4 @@ public interface CommonInfoDao extends BaseMapper { CommonInfo findOne(@Param("type") int type); - -} \ No newline at end of file +} diff --git a/src/main/java/com/sqx/modules/course/service/impl/CourseDetailsServiceImpl.java b/src/main/java/com/sqx/modules/course/service/impl/CourseDetailsServiceImpl.java index 3ae16729..409e06f2 100644 --- a/src/main/java/com/sqx/modules/course/service/impl/CourseDetailsServiceImpl.java +++ b/src/main/java/com/sqx/modules/course/service/impl/CourseDetailsServiceImpl.java @@ -98,7 +98,7 @@ public class CourseDetailsServiceImpl extends ServiceImpl() @@ -113,7 +113,9 @@ public class CourseDetailsServiceImpl extends ServiceImpl= Integer.parseInt(needCountCommonInfo.getValue())) { - redisServiceImpl.setPayFreeWatchTime(userId, Integer.parseInt(freeTimeCommonInfo.getValue())); + redisServiceImpl.setFreeWatchTime(userId, Integer.parseInt(freeTimeCommonInfo.getValue()), false); + // 触发计时 + redisServiceImpl.getFreeWatchTimeIsExpire(userId); isExpire = false; }else { isExpire = true; diff --git a/src/main/java/com/sqx/modules/redisService/RedisService.java b/src/main/java/com/sqx/modules/redisService/RedisService.java index 9652816b..09eff649 100644 --- a/src/main/java/com/sqx/modules/redisService/RedisService.java +++ b/src/main/java/com/sqx/modules/redisService/RedisService.java @@ -9,7 +9,9 @@ public interface RedisService { void setDiscSpinningAmounts(String key); - void setPayFreeWatchTime(Long userId, Integer time); + void setFreeWatchTime(Long userId, Integer time, boolean isPermanently); - Boolean getPayFreeWatchTimeIsExpire(Long userId); + Boolean getFreeWatchTimeIsExpire(Long userId); + + Long getFreeWatchRemainTime(Long userId, boolean isPermanently); } diff --git a/src/main/java/com/sqx/modules/redisService/impl/RedisServiceImpl.java b/src/main/java/com/sqx/modules/redisService/impl/RedisServiceImpl.java index c25b7b8f..351ac5fe 100644 --- a/src/main/java/com/sqx/modules/redisService/impl/RedisServiceImpl.java +++ b/src/main/java/com/sqx/modules/redisService/impl/RedisServiceImpl.java @@ -2,6 +2,8 @@ package com.sqx.modules.redisService.impl; import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.sqx.common.utils.RedisKeys; import com.sqx.common.utils.RedisUtils; @@ -17,6 +19,8 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import java.util.Map; + @Service public class RedisServiceImpl implements RedisService { @Lazy @@ -36,21 +40,96 @@ public class RedisServiceImpl implements RedisService { } @Override - public void setPayFreeWatchTime(Long userId, Integer minute) { + public void setFreeWatchTime(Long userId, Integer second, boolean isPermanently) { Date now = DateUtil.date(); Date tomorrow = DateUtil.beginOfDay(DateUtil.offsetDay(now, 1)); - long seconds = DateUtil.between(now, tomorrow, DateUnit.SECOND); - redisUtils.setIfAbsent(RedisKeys.getPayFreeWatchKey(userId), DateUtil.offsetMinute(now, minute).getTime(), seconds); + String freeWatchKey = RedisKeys.getFreeWatchKey(userId, isPermanently); + if (isPermanently) { + String data = redisUtils.get(freeWatchKey); + if (StrUtil.isBlank(data)) { + redisUtils.set(freeWatchKey, second, -1); + }else { + Long expire = redisUtils.getExpire(freeWatchKey); + if (expire == null) { + expire = Long.valueOf(second); + }else { + expire += Long.valueOf(second); + } + redisUtils.set(freeWatchKey, second + Long.parseLong(data), expire); + + } + }else { + long expire = DateUtil.between(now, tomorrow, DateUnit.SECOND); +// redisUtils.setIfAbsent(freeWatchKey, DateUtil.offsetSecond(now, second).getTime(), seconds); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("expireTime", -1); + jsonObject.put("second", second); + redisUtils.setIfAbsent(freeWatchKey, jsonObject.toJSONString(), expire); + } } @Override - public Boolean getPayFreeWatchTimeIsExpire(Long userId) { - String data = redisUtils.get(RedisKeys.getPayFreeWatchKey(userId)); - if (data == null) { - return null; + public Boolean getFreeWatchTimeIsExpire(Long userId) { + String freeWatchKey = RedisKeys.getFreeWatchKey(userId, true); + String permanentlyFreeWatch = redisUtils.get(freeWatchKey); + + String watchKey = RedisKeys.getFreeWatchKey(userId, false); + String payFreeWatchInfo = redisUtils.get(watchKey); + Integer expireTime = -1; + JSONObject jsonObject = null; + if (StrUtil.isNotBlank(payFreeWatchInfo)) { + jsonObject = JSONObject.parseObject(payFreeWatchInfo); + expireTime = jsonObject.getInteger("expireTime"); } - long expireTime = Long.parseLong(data); - return DateUtil.current() > expireTime; + if ((StrUtil.isNotBlank(permanentlyFreeWatch) && redisUtils.isExpiredSet(freeWatchKey)) || (StrUtil.isNotBlank(permanentlyFreeWatch) && DateUtil.current() >= expireTime)) { + if (StrUtil.isBlank(permanentlyFreeWatch)) { + return null; + } + + if (!redisUtils.isExpiredSet(freeWatchKey)) { + redisUtils.expire(freeWatchKey, Long.parseLong(permanentlyFreeWatch)); + } + return false; + }else { + if (StrUtil.isBlank(payFreeWatchInfo)) { + return null; + } + + Integer second = jsonObject.getInteger("second"); + if (expireTime == -1) { + jsonObject.put("expireTime", DateUtil.offsetSecond(DateUtil.date(), second).getTime()); + redisUtils.set(watchKey, jsonObject.toJSONString()); + return false; + }else { + return DateUtil.current() > expireTime; + } + } + } + + @Override + public Long getFreeWatchRemainTime(Long userId, boolean isPermanently) { + String key = RedisKeys.getFreeWatchKey(userId, isPermanently); + if (isPermanently) { + String permanentlyFreeInfo = redisUtils.get(key); + if (StrUtil.isBlank(permanentlyFreeInfo)) { + return 0L; + } + + Long expire = redisUtils.getExpire(key); + return expire == null ? Long.valueOf(permanentlyFreeInfo) : expire; + } + + + String payFreeInfo = redisUtils.get(RedisKeys.getFreeWatchKey(userId, false)); + if (StrUtil.isBlank(payFreeInfo)) { + return 0L; + } + + JSONObject jsonObject = JSONObject.parseObject(payFreeInfo); + Integer expireTime = jsonObject.getInteger("expireTime"); + Long second = jsonObject.getLong("second"); + + return expireTime == -1 ? second : expireTime > DateUtil.current() ? expireTime - DateUtil.current() : 0L; } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 1248147b..83db9176 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -81,3 +81,5 @@ sqx: # token有效时长,7天,单位秒 expire: 604800 header: token + uni: + adSecret: 122e4ff1edc66dcf8761f7f7ffc81e0f8773cbfafb58aed29c72fbd092c77315 diff --git a/src/main/resources/mapper/callback/UniAdCallbackRecordMapper.xml b/src/main/resources/mapper/callback/UniAdCallbackRecordMapper.xml new file mode 100644 index 00000000..a0ad2181 --- /dev/null +++ b/src/main/resources/mapper/callback/UniAdCallbackRecordMapper.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + id,user_id,platform, + trans_id,adpid,provider, + sign,extra,is_ended, + create_time + +