feat: 1.uni-ad广告回调接入 2.广告奖励免费观看时长

This commit is contained in:
张松 2024-12-23 16:16:36 +08:00
parent f4e93e748e
commit f11ae848b0
18 changed files with 607 additions and 18 deletions

View File

@ -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) {

View File

@ -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> T get(String key, Class<T> 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> T get(String key, Class<T> clazz) {
return get(key, clazz, NOT_EXPIRE);
}

View File

@ -41,6 +41,7 @@ public class ShiroConfig {
shiroFilter.setFilters(filters);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/uniCallBack/**", "anon");
filterMap.put("/course/synCourse", "anon");
filterMap.put("/webjars/**", "anon");
filterMap.put("/druid/**", "anon");

View File

@ -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));
}
}

View File

@ -0,0 +1,7 @@
package com.sqx.modules.app.service;
import java.util.HashMap;
public interface AdService {
HashMap<String, Object> getDetail(Long userId);
}

View File

@ -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<String, Object> getDetail(Long userId) {
Long freeWatchRemainTime = redisServiceImpl.getFreeWatchRemainTime(userId, false);
Long permanentlyFreeWatchRemainTime = redisServiceImpl.getFreeWatchRemainTime(userId, true);
return new HashMap<String, Object>(){{
put("adFreeWatchTime", permanentlyFreeWatchRemainTime);
put("payFreeWatchTime", freeWatchRemainTime);
put("totalFreeWatchTime", freeWatchRemainTime + permanentlyFreeWatchRemainTime);
}};
}
}

View File

@ -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));
}
}

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -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<UniAdCallbackRecord> {
}

View File

@ -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<UniAdCallbackRecord> {
Map<String, Object> adCallBack(UniAdCallBackDTO callBackDTO);
HashMap<String, Object> getStateByExtraKey(Long userId, String extraKey);
}

View File

@ -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<UniAdCallbackRecordMapper, UniAdCallbackRecord>
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<String, Object> adCallBack(UniAdCallBackDTO callBackDTO) {
HashMap<String, Object> respData = new HashMap<>();
UniAdCallbackRecord one = getOne(new LambdaQueryWrapper<UniAdCallbackRecord>()
.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<String, Object> getStateByExtraKey(Long userId, String extraKey) {
UniAdCallbackRecord one = getOne(new LambdaQueryWrapper<UniAdCallbackRecord>().eq(UniAdCallbackRecord::getUserId, userId)
.eq(UniAdCallbackRecord::getExtra, extraKey));
return new HashMap<String, Object>(){{
put("isEnded", one == null ? 0 : 1);
}};
}
}

View File

@ -20,5 +20,4 @@ public interface CommonInfoDao extends BaseMapper<CommonInfo> {
CommonInfo findOne(@Param("type") int type);
}
}

View File

@ -98,7 +98,7 @@ public class CourseDetailsServiceImpl extends ServiceImpl<CourseDetailsDao, Cour
* @return true 可观看
*/
private boolean checkFreeWatchPayCount(Long userId) {
Boolean isExpire = redisServiceImpl.getPayFreeWatchTimeIsExpire(userId);
Boolean isExpire = redisServiceImpl.getFreeWatchTimeIsExpire(userId);
if (isExpire == null) {
Integer count = ordersDao.countPayOrderByDay(userId);
CommonInfo needCountCommonInfo = commonInfoDao.selectOne(new LambdaQueryWrapper<CommonInfo>()
@ -113,7 +113,9 @@ public class CourseDetailsServiceImpl extends ServiceImpl<CourseDetailsDao, Cour
// 购买次数超过设置redis标识
if (count >= 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;

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -81,3 +81,5 @@ sqx:
# token有效时长7天单位秒
expire: 604800
header: token
uni:
adSecret: 122e4ff1edc66dcf8761f7f7ffc81e0f8773cbfafb58aed29c72fbd092c77315

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sqx.modules.callback.mapper.UniAdCallbackRecordMapper">
<resultMap id="BaseResultMap" type="com.sqx.modules.callback.entity.UniAdCallbackRecord">
<id property="id" column="id" jdbcType="INTEGER"/>
<result property="userId" column="user_id" jdbcType="INTEGER"/>
<result property="platform" column="platform" jdbcType="VARCHAR"/>
<result property="transId" column="trans_id" jdbcType="VARCHAR"/>
<result property="adpid" column="adpid" jdbcType="VARCHAR"/>
<result property="provider" column="provider" jdbcType="VARCHAR"/>
<result property="sign" column="sign" jdbcType="VARCHAR"/>
<result property="extra" column="extra" jdbcType="VARCHAR"/>
<result property="isEnded" column="is_ended" jdbcType="TINYINT"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
</resultMap>
<sql id="Base_Column_List">
id,user_id,platform,
trans_id,adpid,provider,
sign,extra,is_ended,
create_time
</sql>
</mapper>