Merge branch 'test' into dev

This commit is contained in:
2024-12-23 09:40:20 +08:00
47 changed files with 1679 additions and 612 deletions

View File

@@ -72,6 +72,12 @@
<groupId>cn.afterturn</groupId> <groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId> <artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.0.0</version> <version>4.0.0</version>
<exclusions>
<exclusion>
<artifactId>javassist</artifactId>
<groupId>org.javassist</groupId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.qcloudsms</groupId> <groupId>com.github.qcloudsms</groupId>

View File

@@ -1,11 +1,15 @@
package com.sqx.common.utils; package com.sqx.common.utils;
import cn.hutool.core.date.DateUtil;
/** /**
* Redis所有Keys * Redis所有Keys
* *
*/ */
public class RedisKeys { public class RedisKeys {
public static final String PAY_FREE_WATCH_KEY = "pay:free:watch:";
public static String getSysConfigKey(String key){ public static String getSysConfigKey(String key){
return "sys:config:" + key; return "sys:config:" + key;
} }
@@ -13,4 +17,12 @@ public class RedisKeys {
public static String getDateKey(String key){ public static String getDateKey(String key){
return "date:" + key; return "date:" + key;
} }
public static String getPayFreeWatchKey(Long userId) {
return PAY_FREE_WATCH_KEY + DateUtil.today() + ":" + userId;
}
public static void main(String[] args) {
System.out.println(DateUtil.today());
}
} }

View File

@@ -1,5 +1,6 @@
package com.sqx.common.utils; package com.sqx.common.utils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.sqx.modules.redisService.RedisService; import com.sqx.modules.redisService.RedisService;
@@ -10,12 +11,14 @@ import org.springframework.stereotype.Component;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType; import java.lang.invoke.MethodType;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* Redis工具类 * Redis工具类
*
*/ */
@Component @Component
public class RedisUtils { public class RedisUtils {
@@ -33,18 +36,30 @@ public class RedisUtils {
private SetOperations<String, Object> setOperations; private SetOperations<String, Object> setOperations;
@Autowired @Autowired
private ZSetOperations<String, Object> zSetOperations; private ZSetOperations<String, Object> zSetOperations;
/** 默认过期时长,单位:秒 */ /**
* 默认过期时长,单位:秒
*/
public final static long DEFAULT_EXPIRE = 60 * 60 * 24; public final static long DEFAULT_EXPIRE = 60 * 60 * 24;
/** 不设置过期时长 */ /**
* 不设置过期时长
*/
public final static long NOT_EXPIRE = -1; public final static long NOT_EXPIRE = -1;
private final static Gson Gson = new Gson(); private final static Gson Gson = new Gson();
/**
* 获取缓存里的数据 如果不存在 则插入 并返回 public <T> Map<String, List<T>> getMapData(String key, String method, Class<T> clazz) {
* @param key redis Key String jsonStr = getDate(key, method);
* @param clazz 返回类型 ObjectMapper objectMapper = new ObjectMapper();
* @param method RedisService调用的方法名 如果数据不存在会执行该调用方法 try {
*/ JsonNode jsonNode = objectMapper.readTree(jsonStr);
return jsonNodeToMap(jsonNode, clazz);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public <T> List<T> getListData(String key, Class<T> clazz, String method) { public <T> List<T> getListData(String key, Class<T> clazz, String method) {
String jsonStr = getDate(key, method); String jsonStr = getDate(key, method);
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
@@ -59,6 +74,7 @@ public class RedisUtils {
/** /**
* 获取缓存里的数据 如果不存在 则插入 并返回 * 获取缓存里的数据 如果不存在 则插入 并返回
*
* @param key redis Key * @param key redis Key
* @param clazz 返回类型 * @param clazz 返回类型
* @param method RedisService调用的方法名 如果数据不存在会执行该调用方法 * @param method RedisService调用的方法名 如果数据不存在会执行该调用方法
@@ -98,6 +114,20 @@ public class RedisUtils {
if (expire != NOT_EXPIRE) { if (expire != NOT_EXPIRE) {
redisTemplate.expire(key, expire, TimeUnit.SECONDS); redisTemplate.expire(key, expire, TimeUnit.SECONDS);
} }
}
public boolean setIfAbsent(String key, Object value, long expire){
Boolean absent = valueOperations.setIfAbsent(key, toJson(value));
if (Boolean.FALSE.equals(absent)) {
return false;
}
if(expire != NOT_EXPIRE){
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
return true;
} }
public void set(String key, Object value) { public void set(String key, Object value) {
@@ -164,4 +194,22 @@ public class RedisUtils {
private <T> T fromJson(String json, Class<T> clazz) { private <T> T fromJson(String json, Class<T> clazz) {
return Gson.fromJson(json, clazz); return Gson.fromJson(json, clazz);
} }
public <T> Map<String, List<T>> jsonNodeToMap(JsonNode jsonNode, Class<T> clazz) {
Map<String, List<T>> resultMap = new HashMap<>();
ObjectMapper objectMapper = new ObjectMapper();
if (jsonNode.isObject()) {
// 获取字段名(也就是键)的迭代器
Iterator<String> fieldNames = jsonNode.fieldNames();
while (fieldNames.hasNext()) {
String key = fieldNames.next();
JsonNode elementNode = jsonNode.get(key);
resultMap.put(key, objectMapper.convertValue(elementNode,
objectMapper.getTypeFactory().constructCollectionType(List.class, clazz)));
}
}
return resultMap;
}
} }

View File

@@ -49,6 +49,7 @@ public class ShiroConfig {
filterMap.put("/banner/**", "anon"); filterMap.put("/banner/**", "anon");
filterMap.put("/courseClassification/selectCourseClassification", "anon"); filterMap.put("/courseClassification/selectCourseClassification", "anon");
filterMap.put("/sys/login", "anon"); filterMap.put("/sys/login", "anon");
filterMap.put("/sys/registered", "anon");
filterMap.put("/swagger/**", "anon"); filterMap.put("/swagger/**", "anon");
filterMap.put("/alioss/**", "anon"); filterMap.put("/alioss/**", "anon");
filterMap.put("/v2/api-docs", "anon"); filterMap.put("/v2/api-docs", "anon");

View File

@@ -0,0 +1,46 @@
package com.sqx.modules.app.controller;
import com.sqx.common.utils.Constant;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.app.entity.UserPrizeExchange;
import com.sqx.modules.app.service.UserPrizeExchangeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import java.util.Map;
@RestController
@RequestMapping("/app/userPrizeExchange")
@AllArgsConstructor
@Api(value = "用户奖品兑换", tags = {"用户奖品兑换"})
public class AppUserPrizeExchangeController {
private final UserPrizeExchangeService userPrizeExchangeService;
@Login
@GetMapping("/page")
@ApiOperation("分页")
@ApiImplicitParams({
@ApiImplicitParam(name = Constant.PAGE, value = "当前页码从1开始", paramType = "query", required = true, dataType = "int"),
@ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query", required = true, dataType = "int"),
})
public Result page(@RequestAttribute("userId") Long userId, @ApiIgnore @RequestParam Map<String, Object> params) {
params.put("userId", userId);
PageUtils page = userPrizeExchangeService.page(params);
return Result.success().put("page", page);
}
@Login
@PostMapping("/exchange")
@ApiOperation("兑换")
public Result exchange(@RequestAttribute("userId") Long userId, @RequestBody UserPrizeExchange entity) {
userPrizeExchangeService.exchange(userId, entity);
return Result.success();
}
}

View File

@@ -1,9 +1,9 @@
package com.sqx.modules.app.controller.app; package com.sqx.modules.app.controller.app;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sqx.common.annotation.Debounce;
import com.sqx.common.utils.ApiAccessLimitUtil; import com.sqx.common.utils.ApiAccessLimitUtil;
import com.sqx.common.utils.Result; import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login; import com.sqx.modules.app.annotation.Login;
@@ -11,7 +11,6 @@ import com.sqx.modules.app.annotation.LoginUser;
import com.sqx.modules.app.entity.UserEntity; import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.service.AppService; import com.sqx.modules.app.service.AppService;
import com.sqx.modules.app.service.UserService; import com.sqx.modules.app.service.UserService;
import com.sqx.modules.message.entity.MessageInfo;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
@@ -75,22 +74,37 @@ public class AppController {
@ApiOperation("用户修改个人信息") @ApiOperation("用户修改个人信息")
@ResponseBody @ResponseBody
public Result updateUserImageUrl(@RequestAttribute("userId") Long userId, String zhiFuBao, String zhiFuBaoName) { public Result updateUserImageUrl(@RequestAttribute("userId") Long userId, String zhiFuBao, String zhiFuBaoName) {
if(StrUtil.isEmpty(zhiFuBao) || StrUtil.isEmpty(zhiFuBaoName)){
return Result.error("支付宝账户及姓名不能为空!");
}
int count = userService.count(new QueryWrapper<UserEntity>() int count = userService.count(new QueryWrapper<UserEntity>()
.ne("user_id", userId) .ne("user_id", userId)
.eq("zhi_fu_bao_name", zhiFuBaoName) .eq("zhi_fu_bao_name", zhiFuBaoName)
.eq("zhi_fu_bao", zhiFuBao)); .eq("zhi_fu_bao", zhiFuBao));
if (count > 0) { if (count > 0) {
return Result.error("一个支付宝账号仅可绑定一个支付宝用户"); return Result.error("一个支付宝账号仅可绑定一个用户");
} }
if (!ApiAccessLimitUtil.isAccessAllowed(userId.toString(), "updateZFB", 3, "month")) { if (!ApiAccessLimitUtil.isAccessAllowed(userId.toString(), "updateZFB", 3, "month")) {
return Result.error("每月仅支持修改三次,请联系管理员"); return Result.error("每月仅支持修改三次,请联系管理员");
} }
UserEntity old = userService.getById(userId);
String accountNo = old.getZhiFuBao();
String accountName = old.getZhiFuBaoName();
boolean isFirstBind = false;
if (StrUtil.isEmpty(accountNo) && StrUtil.isEmpty(accountName)) {
isFirstBind = true;
}
UserEntity userEntity = new UserEntity(); UserEntity userEntity = new UserEntity();
userEntity.setZhiFuBao(zhiFuBao); userEntity.setZhiFuBao(zhiFuBao);
userEntity.setZhiFuBaoName(zhiFuBaoName); userEntity.setZhiFuBaoName(zhiFuBaoName);
userEntity.setUserId(userId); userEntity.setUserId(userId);
userService.updateById(userEntity); old.setZhiFuBao(userEntity.getZhiFuBao());
old.setZhiFuBaoName(userEntity.getZhiFuBaoName());
boolean bool = userService.updateById(userEntity);
if (bool && isFirstBind) {
userService.firstBindAwardsMoney(old);
}
return Result.success(); return Result.success();
} }

View File

@@ -0,0 +1,51 @@
package com.sqx.modules.app.controller.app;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.userSign.dto.UserSignDTO;
import com.sqx.modules.userSign.service.UserSignRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author tankaikai
* @since 2024-12-19 15:23
*/
@Slf4j
@RestController
@Api(value = "用户签到", tags = {"用户签到"})
@RequestMapping(value = "/app/userSignRecord")
public class AppUserSignController {
@Autowired
private UserSignRecordService userSignRecordService;
/**
* 获取用户连续签到数据
*/
@Login
@GetMapping("/getUserSignData")
@ApiOperation("获取用户连续签到数据")
public Result getUserSignData(@RequestAttribute("userId") Long userId) {
UserSignDTO data = userSignRecordService.getUserSignData(userId);
return Result.success().put("data", data);
}
/**
* 获取连续签到奖励配置
*/
@Login
@GetMapping("/getUserSignAwardConfig")
@ApiOperation(value = "获取连续签到奖励配置", notes = "如:[7,7] = 连续签到7天奖励7元")
public Result getUserSignAwardConfig() {
String[] data = userSignRecordService.getUserSignAwardConfig();
return Result.success().put("data", data);
}
}

View File

@@ -0,0 +1,15 @@
package com.sqx.modules.app.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sqx.modules.app.entity.UserPrizeExchange;
import org.apache.ibatis.annotations.Mapper;
/**
* 用户奖品兑换
*
* @author tankaikai
* @since 2024-12-20 18:11
*/
@Mapper
public interface UserPrizeExchangeDao extends BaseMapper<UserPrizeExchange> {
}

View File

@@ -0,0 +1,68 @@
package com.sqx.modules.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 用户奖品兑换
* @author tankaikai
* @since 2024-12-20 17:52
*/
@Data
@TableName("user_prize_exchange")
public class UserPrizeExchange implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 奖品记录
*/
@TableId(type = IdType.ID_WORKER)
private Long id;
/**
* 奖品记录id
*/
private Long discSpinningRecordId;
/**
* 奖品名称
*/
private String prizeName;
/**
* 用户id
*/
private Long userId;
/**
* 用户名
*/
private String userName;
/**
* 手机号
*/
private String phone;
/**
* 收货地址
*/
private String address;
/**
* 备注
*/
private String remark;
/**
* 状态 0-待发放 1-已发放
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}

View File

@@ -0,0 +1,38 @@
package com.sqx.modules.app.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sqx.common.utils.PageUtils;
import com.sqx.modules.app.entity.UserPrizeExchange;
import java.util.Map;
/**
* 用户奖品兑换Service
*
* @author tankaikai
* @since 2024-12-20 18:04
*/
public interface UserPrizeExchangeService extends IService<UserPrizeExchange> {
/**
* 分页查询
*
* @param params
* @return
*/
PageUtils page(Map<String, Object> params);
/**
* 兑换奖品
*
* @param entity
*/
void exchange(Long currentUserId, UserPrizeExchange entity);
/**
* 发放奖品
*
* @param dto
*/
void deliver(UserPrizeExchange dto);
}

View File

@@ -227,4 +227,6 @@ public interface UserService extends IService<UserEntity> {
int updateUserClientIdIsNull(String clientid); int updateUserClientIdIsNull(String clientid);
void firstBindAwardsMoney(UserEntity entity);
} }

View File

@@ -0,0 +1,145 @@
package com.sqx.modules.app.service.impl;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.map.MapProxy;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyun.tea.ValidateException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.Constant;
import com.sqx.common.utils.PageUtils;
import com.sqx.modules.app.dao.UserDao;
import com.sqx.modules.app.dao.UserPrizeExchangeDao;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserPrizeExchange;
import com.sqx.modules.app.service.UserPrizeExchangeService;
import com.sqx.modules.discSpinning.dao.DiscSpinningRecordDao;
import com.sqx.modules.discSpinning.entity.DiscSpinningRecord;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;
/**
* @author tankaikai
* @since 2024-12-20 18:10
*/
@Slf4j
@Service
public class UserPrizeExchangeServiceImpl extends ServiceImpl<UserPrizeExchangeDao, UserPrizeExchange> implements UserPrizeExchangeService {
@Resource
private DiscSpinningRecordDao discSpinningRecordDao;
@Resource
private UserDao userDao;
@Override
public PageUtils page(Map<String, Object> params) {
MapProxy proxy = MapProxy.create(params);
Long discSpinningRecordId = proxy.getLong("discSpinningRecordId");
Long userId = proxy.getLong("userId");
String userName = proxy.getStr("userName");
String prizeName = proxy.getStr("prizeName");
Integer status = proxy.getInt("status");
String phone = proxy.getStr("phone");
String remark = proxy.getStr("remark");
String beginDate = proxy.getStr("beginDate");
String endDate = proxy.getStr("endDate");
LambdaQueryWrapper<UserPrizeExchange> wrapper = Wrappers.lambdaQuery();
wrapper.eq(discSpinningRecordId != null, UserPrizeExchange::getDiscSpinningRecordId, discSpinningRecordId);
wrapper.eq(userId != null, UserPrizeExchange::getUserId, userId);
wrapper.like(StrUtil.isNotEmpty(userName), UserPrizeExchange::getUserName, userName);
wrapper.like(StrUtil.isNotEmpty(prizeName), UserPrizeExchange::getPrizeName, prizeName);
wrapper.eq(status != null, UserPrizeExchange::getStatus, status);
wrapper.like(StrUtil.isNotEmpty(phone), UserPrizeExchange::getPhone, phone);
wrapper.like(StrUtil.isNotEmpty(remark), UserPrizeExchange::getRemark, remark);
if (StrUtil.isNotEmpty(beginDate)) {
wrapper.apply("create_time >= str_to_date({0}, '%Y-%m-%d %H:%i:%s')", beginDate + " 00:00:00");
}
if (StrUtil.isNotEmpty(endDate)) {
wrapper.apply("create_time <= str_to_date({0}, '%Y-%m-%d %H:%i:%s')", endDate + " 23:59:59");
}
wrapper.orderByDesc(UserPrizeExchange::getId);
long pageNum = proxy.getLong(Constant.PAGE, 1L);
long pageSize = proxy.getLong(Constant.LIMIT, 10L);
IPage<UserPrizeExchange> page = this.page(new Page<>(pageNum, pageSize), wrapper);
return new PageUtils(page);
}
@Override
public void exchange(Long currentUserId, UserPrizeExchange dto) {
if (dto.getDiscSpinningRecordId() == null) {
throw new SqxException("中奖记录ID不能为空");
}
if (StrUtil.isBlank(dto.getPhone())) {
throw new SqxException("用户手机号码不能为空");
}
try {
Validator.isMobile(dto.getPhone());
} catch (ValidateException e) {
throw new SqxException("用户手机号码不合法");
}
DiscSpinningRecord record = discSpinningRecordDao.selectById(dto.getDiscSpinningRecordId());
if (record == null) {
throw new SqxException("中奖记录不存在");
}
if (record.getUserId() == null) {
throw new SqxException("中奖用户数据不完整");
}
if (currentUserId == null) {
throw new SqxException("未获取当前登录用户id");
}
Long userId = record.getUserId();
if (!currentUserId.equals(userId)) {
throw new SqxException("兑奖用户和获奖用户不一致");
}
UserEntity user = userDao.selectById(record.getUserId());
if (user == null) {
throw new SqxException("兑奖用户不存在");
}
if (ArrayUtil.contains(new int[]{1, 2}, record.getType())) {
throw new SqxException("仅限兑换实物、会员卡等奖项");
}
Integer count = baseMapper.selectCount(Wrappers.<UserPrizeExchange>lambdaQuery()
.eq(UserPrizeExchange::getDiscSpinningRecordId, record.getId())
);
if (count != null && count > 0) {
throw new SqxException("奖品已兑换,请勿重复操作");
}
dto.setPrizeName(record.getName());
dto.setUserId(record.getUserId());
dto.setUserName(user.getUserName());
dto.setStatus(0);
dto.setCreateTime(new Date());
baseMapper.insert(dto);
}
@Override
public void deliver(UserPrizeExchange dto) {
Long id = dto.getId();
if (id == null) {
throw new SqxException("兑奖id不能为空");
}
UserPrizeExchange entity = baseMapper.selectById(id);
if (entity == null) {
throw new SqxException("兑奖订单不存在");
}
entity.setStatus(1);
if (StrUtil.isNotEmpty(dto.getAddress())) {
entity.setAddress(dto.getAddress());
}
if (StrUtil.isNotEmpty(dto.getRemark())) {
entity.setRemark(dto.getRemark());
}
entity.setUpdateTime(new Date());
baseMapper.updateById(entity);
}
}

View File

@@ -1,6 +1,9 @@
package com.sqx.modules.app.service.impl; package com.sqx.modules.app.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
@@ -42,6 +45,7 @@ import com.sqx.modules.app.utils.JwtUtils;
import com.sqx.modules.app.utils.UserConstantInterface; import com.sqx.modules.app.utils.UserConstantInterface;
import com.sqx.modules.common.entity.CommonInfo; import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService; import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.discSpinning.service.DiscSpinningService;
import com.sqx.modules.file.utils.Md5Utils; import com.sqx.modules.file.utils.Md5Utils;
import com.sqx.modules.invite.service.InviteService; import com.sqx.modules.invite.service.InviteService;
import com.sqx.modules.message.entity.MessageInfo; import com.sqx.modules.message.entity.MessageInfo;
@@ -61,13 +65,17 @@ import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import weixin.popular.api.SnsAPI; import weixin.popular.api.SnsAPI;
import weixin.popular.util.JsonUtil; import weixin.popular.util.JsonUtil;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
/** /**
@@ -98,6 +106,10 @@ public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements
private UserVipService userVipService; private UserVipService userVipService;
@Autowired @Autowired
private MessageService messageService; private MessageService messageService;
@Autowired
private CommonInfoService commonRepository;
@Autowired
private DiscSpinningService discSpinningService;
private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(true); private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(true);
@Override @Override
@@ -213,7 +225,6 @@ public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements
} }
@Override @Override
public Result getNewUserRed(Long userId) { public Result getNewUserRed(Long userId) {
reentrantReadWriteLock.writeLock().lock(); reentrantReadWriteLock.writeLock().lock();
@@ -622,8 +633,6 @@ public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements
} }
@Override @Override
public Result wxAppLogin(String wxOpenId, String token) { public Result wxAppLogin(String wxOpenId, String token) {
UserEntity userEntity = queryByWxOpenId(wxOpenId); UserEntity userEntity = queryByWxOpenId(wxOpenId);
@@ -980,8 +989,6 @@ public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements
} }
@Override @Override
public Result login(String phone, String pwd) { public Result login(String phone, String pwd) {
UserEntity userEntity = queryByPhone(phone); UserEntity userEntity = queryByPhone(phone);
@@ -1462,4 +1469,38 @@ public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements
return baseMapper.updateUserClientIdIsNull(clientid); return baseMapper.updateUserClientIdIsNull(clientid);
} }
@Override
@Transactional(rollbackFor = Exception.class)
public void firstBindAwardsMoney(UserEntity entity) {
reentrantReadWriteLock.writeLock().lock();
try {
CommonInfo one = commonRepository.findOne(920);
BigDecimal money = new BigDecimal(one.getValue());
userMoneyService.updateAmount(1, entity.getUserId(), money.doubleValue());
UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
userMoneyDetails.setUserId(entity.getUserId());
userMoneyDetails.setTitle("[首绑支付宝]");
userMoneyDetails.setContent("现金红包奖励:" + money + "");
// 充值
userMoneyDetails.setType(1);
// 任务领取
userMoneyDetails.setClassify(7);
userMoneyDetails.setMoney(money);
userMoneyDetails.setCreateTime(DateUtil.format(new Date(System.currentTimeMillis() - 1000), "yyyy-MM-dd HH:mm:ss"));
userMoneyDetails.setMoneyType(1);
boolean ret = userMoneyDetailsService.save(userMoneyDetails);
if (ret) {
ThreadUtil.execAsync(()->{
discSpinningService.withdrawAsync(entity, money.doubleValue(), "[首绑支付宝]");
},true);
}
} catch (Exception e) {
log.error("首绑支付宝发放奖励异常,用户信息:{}", JSONUtil.toJsonStr(entity));
log.error("首绑支付宝发放奖励异常:", e);
throw new RuntimeException("首绑奖励失败");
} finally {
reentrantReadWriteLock.writeLock().unlock();
}
}
} }

View File

@@ -1,6 +1,8 @@
package com.sqx.modules.course.service.impl; package com.sqx.modules.course.service.impl;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -12,6 +14,8 @@ import com.sqx.common.utils.Result;
import com.sqx.modules.app.entity.UserEntity; import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.service.UserService; import com.sqx.modules.app.service.UserService;
import com.sqx.modules.app.utils.JwtUtils; import com.sqx.modules.app.utils.JwtUtils;
import com.sqx.modules.common.dao.CommonInfoDao;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.course.dao.CourseCollectDao; import com.sqx.modules.course.dao.CourseCollectDao;
import com.sqx.modules.course.dao.CourseDao; import com.sqx.modules.course.dao.CourseDao;
import com.sqx.modules.course.dao.CourseDetailsDao; import com.sqx.modules.course.dao.CourseDetailsDao;
@@ -22,11 +26,15 @@ import com.sqx.modules.course.entity.CourseDetails;
import com.sqx.modules.course.entity.CourseUser; import com.sqx.modules.course.entity.CourseUser;
import com.sqx.modules.course.service.CourseDetailsService; import com.sqx.modules.course.service.CourseDetailsService;
import com.sqx.modules.course.vo.CourseDetailsIn; import com.sqx.modules.course.vo.CourseDetailsIn;
import com.sqx.modules.orders.dao.OrdersDao;
import com.sqx.modules.orders.entity.Orders;
import com.sqx.modules.orders.service.OrdersService; import com.sqx.modules.orders.service.OrdersService;
import com.sqx.modules.redisService.impl.RedisServiceImpl;
import com.sqx.modules.utils.EasyPoi.ExcelUtils; import com.sqx.modules.utils.EasyPoi.ExcelUtils;
import com.sqx.modules.utils.HttpClientUtil; import com.sqx.modules.utils.HttpClientUtil;
import com.sqx.modules.utils.SenInfoCheckUtil; import com.sqx.modules.utils.SenInfoCheckUtil;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -39,6 +47,7 @@ import java.util.Date;
import java.util.List; import java.util.List;
@Service @Service
@Slf4j
public class CourseDetailsServiceImpl extends ServiceImpl<CourseDetailsDao, CourseDetails> implements CourseDetailsService { public class CourseDetailsServiceImpl extends ServiceImpl<CourseDetailsDao, CourseDetails> implements CourseDetailsService {
@Autowired @Autowired
@@ -53,6 +62,12 @@ public class CourseDetailsServiceImpl extends ServiceImpl<CourseDetailsDao, Cour
private OrdersService ordersService; private OrdersService ordersService;
@Autowired @Autowired
private UserService userService; private UserService userService;
@Autowired
private OrdersDao ordersDao;
@Autowired
private CommonInfoDao commonInfoDao;
@Autowired
private RedisServiceImpl redisServiceImpl;
@Override @Override
@@ -77,6 +92,37 @@ public class CourseDetailsServiceImpl extends ServiceImpl<CourseDetailsDao, Cour
return Result.success(); return Result.success();
} }
/**
* 校验用户是否达到免费播放购买次数
* @param userId 用户id
* @return true 可观看
*/
private boolean checkFreeWatchPayCount(Long userId) {
Boolean isExpire = redisServiceImpl.getPayFreeWatchTimeIsExpire(userId);
if (isExpire == null) {
Integer count = ordersDao.countPayOrderByDay(userId);
CommonInfo needCountCommonInfo = commonInfoDao.selectOne(new LambdaQueryWrapper<CommonInfo>()
.eq(CommonInfo::getType, 916));
CommonInfo freeTimeCommonInfo = commonInfoDao.selectOne(new LambdaQueryWrapper<CommonInfo>()
.eq(CommonInfo::getType, 917));
if (needCountCommonInfo == null || freeTimeCommonInfo == null
|| StrUtil.isBlank(needCountCommonInfo.getValue()) || StrUtil.isBlank(freeTimeCommonInfo.getValue())) {
log.warn("系统未配置全免次数或时间");
return false;
}
// 购买次数超过设置redis标识
if (count >= Integer.parseInt(needCountCommonInfo.getValue())) {
redisServiceImpl.setPayFreeWatchTime(userId, Integer.parseInt(freeTimeCommonInfo.getValue()));
isExpire = false;
}else {
isExpire = true;
}
}
return !isExpire;
}
@Override @Override
public Result selectCourseDetailsById(Long id, String token, String courseDetailsId) { public Result selectCourseDetailsById(Long id, String token, String courseDetailsId) {
Course bean = courseDao.selectById(id); Course bean = courseDao.selectById(id);
@@ -99,7 +145,9 @@ public class CourseDetailsServiceImpl extends ServiceImpl<CourseDetailsDao, Cour
UserEntity userEntity = userService.selectUserById(userId); UserEntity userEntity = userService.selectUserById(userId);
//查询用户是否购买了整集 //查询用户是否购买了整集
CourseUser courseUser = courseUserDao.selectCourseUser(id, userId); CourseUser courseUser = courseUserDao.selectCourseUser(id, userId);
if (courseUser != null || (userEntity != null && userEntity.getMember() != null && userEntity.getMember() == 2)) { // 每天购买超过上限,获得免费时间段资格
boolean freeWatch = checkFreeWatchPayCount(userId);
if (freeWatch || courseUser != null || (userEntity != null && userEntity.getMember() != null && userEntity.getMember() == 2)) {
bean.setListsDetail(baseMapper.findByCourseId(id, userId)); bean.setListsDetail(baseMapper.findByCourseId(id, userId));
} else { } else {
bean.setListsDetail(baseMapper.findByCourseIdNotUrl(id, userId)); bean.setListsDetail(baseMapper.findByCourseIdNotUrl(id, userId));

View File

@@ -59,7 +59,7 @@ public class DiscSpinningAmountController {
@GetMapping("/selectDiscSpinningAmount") @GetMapping("/selectDiscSpinningAmount")
@ApiOperation("查询现金红包 抽奖配置") @ApiOperation("查询现金红包 抽奖配置")
public Result selectDiscSpinningAmount(Integer page, Integer limit) { public Result selectDiscSpinningAmount(Integer page, Integer limit) {
return Result.success().put("data", discSpinningAmountService.page(new Page<>(page, limit), new QueryWrapper<DiscSpinningAmount>().orderByDesc("status").orderByAsc("random","max_amount"))); return Result.success().put("data", discSpinningAmountService.page(new Page<>(page, limit), new QueryWrapper<DiscSpinningAmount>().orderByDesc("status").orderByAsc("num","random","max_amount")));
} }
} }

View File

@@ -1,5 +1,6 @@
package com.sqx.modules.discSpinning.controller; package com.sqx.modules.discSpinning.controller;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.common.annotation.Debounce; import com.sqx.common.annotation.Debounce;
@@ -20,6 +21,7 @@ import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import reactor.util.annotation.Nullable; import reactor.util.annotation.Nullable;
import springfox.documentation.annotations.ApiIgnore; import springfox.documentation.annotations.ApiIgnore;
@@ -55,9 +57,26 @@ public class DiscSpinningController {
@PostMapping("/discSpinning/insertDiscSpinning") @PostMapping("/discSpinning/insertDiscSpinning")
@ApiOperation("添加大转盘") @ApiOperation("添加大转盘")
@Transactional
public Result insertDiscSpinning(@RequestBody DiscSpinning discSpinning) { public Result insertDiscSpinning(@RequestBody DiscSpinning discSpinning) {
discSpinning.setCreateTime(DateUtils.format(new Date())); discSpinning.setCreateTime(DateUtils.format(new Date()));
discSpinning.setNumber(discSpinning.getOdds());
discSpinningService.save(discSpinning); discSpinningService.save(discSpinning);
List<DiscSpinning> prizes = discSpinningService.list(new QueryWrapper<DiscSpinning>().eq("disc_type", discSpinning.getDiscType()).orderByAsc("type", "id"));
BigDecimal number = BigDecimal.ZERO;
for (DiscSpinning prize : prizes) {
number = number.add(prize.getOdds());
prize.setNumber(number);
}
BigDecimal totalOdds = prizes.stream()
.map(DiscSpinning::getOdds)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
if (totalOdds.compareTo(new BigDecimal(100)) > 0) {
return Result.error("中奖概率总和 不可超过100");
}
discSpinningService.updateBatchById(prizes);
return Result.success(); return Result.success();
} }
@@ -70,20 +89,13 @@ public class DiscSpinningController {
@PostMapping("/discSpinning/updateDiscSpinning") @PostMapping("/discSpinning/updateDiscSpinning")
@ApiOperation("修改大转盘") @ApiOperation("修改大转盘")
public Result updateDiscSpinning(@RequestBody DiscSpinning discSpinning) { public Result updateDiscSpinning(@RequestBody DiscSpinning discSpinning) {
List<DiscSpinning> prizes = discSpinningService.list(new QueryWrapper<DiscSpinning>().orderByAsc("type", "id")); discSpinningService.updateById(discSpinning);
List<DiscSpinning> prizes = discSpinningService.list(new QueryWrapper<DiscSpinning>().eq("disc_type", discSpinning.getDiscType()).orderByAsc("type", "id"));
BigDecimal number = BigDecimal.ZERO; BigDecimal number = BigDecimal.ZERO;
List<DiscSpinning> prizesResult = new ArrayList<>();
for (DiscSpinning prize : prizes) { for (DiscSpinning prize : prizes) {
if (discSpinning.getId().equals(prize.getId())) {
number = prize.getNumber().add(discSpinning.getOdds().subtract(prize.getOdds()));
discSpinning.setNumber(number);
prize.setOdds(discSpinning.getOdds());
prizesResult.add(discSpinning);
} else if (number.compareTo(BigDecimal.ZERO) > 0) {
number = number.add(prize.getOdds()); number = number.add(prize.getOdds());
prize.setNumber(number); prize.setNumber(number);
prizesResult.add(prize);
}
} }
BigDecimal totalOdds = prizes.stream() BigDecimal totalOdds = prizes.stream()
.map(DiscSpinning::getOdds) .map(DiscSpinning::getOdds)
@@ -92,7 +104,7 @@ public class DiscSpinningController {
if (totalOdds.compareTo(new BigDecimal(100)) > 0) { if (totalOdds.compareTo(new BigDecimal(100)) > 0) {
return Result.error("中奖概率总和 不可超过100"); return Result.error("中奖概率总和 不可超过100");
} }
discSpinningService.updateBatchById(prizesResult); discSpinningService.updateBatchById(prizes);
return Result.success(); return Result.success();
} }
@@ -105,32 +117,31 @@ public class DiscSpinningController {
@GetMapping("/app/discSpinning/selectDiscSpinning") @GetMapping("/app/discSpinning/selectDiscSpinning")
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(name = "type", value = "`1`普通转盘 `2`任务转盘", dataTypeClass = String.class, paramType = "body"), @ApiImplicitParam(name = "source", value = "1 普通转盘 2 周任务转盘 3 月任务转盘", dataTypeClass = Integer.class),
}) })
@ApiOperation("查询大转盘") @ApiOperation("查询大转盘")
public Result selectDiscSpinning(@RequestParam(required = false, defaultValue = "1") Integer type) { public Result selectDiscSpinning(@RequestParam(required = false, defaultValue = "1") Integer source) {
return Result.success().put("data", discSpinningService.page(new Page<>(1, 20), return Result.success().put("data", discSpinningService.page(new Page<>(1, 20),
new QueryWrapper<DiscSpinning>().eq("disc_type", type).orderByAsc("disc_type", "odds"))); new QueryWrapper<DiscSpinning>().eq("disc_type", source).orderByAsc("disc_type", "odds")));
} }
//14232
@Login @Login
@GetMapping("/app/discSpinning/drawCount") @GetMapping("/app/discSpinning/drawCount")
@ApiOperation("获取大转盘抽奖次数") @ApiOperation("获取大转盘抽奖次数")
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(name = "source", value = "`task`任务拉起抽奖 或者 `order` 订单拉起抽奖", dataTypeClass = String.class, paramType = "body"), @ApiImplicitParam(name = "source", value = "`1` 订单拉起抽奖 `2` 周任务拉起抽奖 `3` 月任务拉起抽奖", dataTypeClass = Integer.class),
}) })
@ApiResponses({ @ApiResponses({
@ApiResponse(code = 200, message = "{\"sum\":\"总抽奖次数\",\"count\":\"剩余抽奖次数\"}"), @ApiResponse(code = 200, message = "{\"sum\":\"总抽奖次数\",\"count\":\"剩余抽奖次数\"}"),
}) })
public Result drawCount(@ApiIgnore @RequestAttribute("userId") Long userId, @Nullable @ApiIgnore @RequestBody Map maps) { public Result drawCount(@ApiIgnore @RequestAttribute("userId") Long userId, @RequestParam(required = false, defaultValue = "1") Integer source) {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
int drawCount = Integer.parseInt(commonRepository.findOne(901).getValue()); int drawCount = Integer.parseInt(commonRepository.findOne(901).getValue());
map.put("sum", drawCount); map.put("sum", drawCount);
if (maps != null && maps.containsKey("source") && "task".equals(maps.get("source"))) { if (source != null && !source.equals(1)) {
//任务可抽奖次数 //任务可抽奖次数
map.put("count", taskCenterService.countTaskDisc(userId)); map.put("count", taskCenterService.countTaskDisc(userId, source.toString()));
} else { } else {
int i = recordService.countDraw(userId); int i = recordService.countDraw(userId);
if (drawCount - i > 0) { if (drawCount - i > 0) {
@@ -145,28 +156,30 @@ public class DiscSpinningController {
@Login @Login
@GetMapping("/app/discSpinning/draw") @GetMapping("/app/discSpinning/draw")
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(name = "source", value = "`task`任务拉起抽奖 或者 `order` 订单拉起抽奖", dataTypeClass = String.class, paramType = "body"), @ApiImplicitParam(name = "source", value = "1 普通转盘 2 周任务转盘 3 月任务转盘", dataTypeClass = Integer.class),
}) })
@ApiOperation("抽取大转盘") @ApiOperation("抽取大转盘")
public Result draw(@ApiIgnore @RequestAttribute("userId") Long userId, @Nullable @ApiIgnore @RequestBody Map maps) { public Result draw(@ApiIgnore @RequestAttribute("userId") Long userId, @RequestParam(required = false, defaultValue = "1") Integer source) {
double amount = 0; double amount = 0;
Long orderId = null; Long orderId = null;
if (maps == null || !maps.containsKey("source") || !"task".equals(maps.get("source"))) { Integer i = recordService.countDraw(userId);
if (source != null && source.equals(1)) {
//任务抽奖 //任务抽奖
int drawCount = Integer.parseInt(commonRepository.findOne(901).getValue()); int drawCount = Integer.parseInt(commonRepository.findOne(901).getValue());
Integer i = recordService.countDraw(userId);
if (i != null && i >= drawCount) { if (i != null && i >= drawCount) {
return Result.error("当日可抽奖次数已超限"); return Result.error("当日可抽奖次数已超限");
} }
Orders orders = ordersService.selectOrdersByDay(userId); Orders orders = ordersService.selectOrdersByDay(userId);
amount = orders.getPayMoney().doubleValue();
orderId = orders.getOrdersId();
if (orders == null) { if (orders == null) {
return Result.error("无可抽奖机会"); return Result.error("无可抽奖机会");
} }
amount = orders.getPayMoney().doubleValue();
orderId = orders.getOrdersId();
} else if (source == null) {
source = 1;
} }
return new Result().put("data", return new Result().put("data",
discSpinningService.draws(amount, orderId, userId, maps == null || maps.get("source") == null ? "order" : maps.get("source").toString())); discSpinningService.draws(i == null ? 1 : i + 1, amount, orderId, userId, source));
} }
@ApiOperation("大转盘奖项领取") @ApiOperation("大转盘奖项领取")

View File

@@ -0,0 +1,42 @@
package com.sqx.modules.discSpinning.controller;
import com.sqx.common.utils.Constant;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.entity.UserPrizeExchange;
import com.sqx.modules.app.service.UserPrizeExchangeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import java.util.Map;
@RestController
@RequestMapping("/userPrizeExchange")
@AllArgsConstructor
@Api(value = "用户奖品兑换", tags = {"用户奖品兑换"})
public class UserPrizeExchangeController {
private final UserPrizeExchangeService userPrizeExchangeService;
@GetMapping("/page")
@ApiOperation("分页")
@ApiImplicitParams({
@ApiImplicitParam(name = Constant.PAGE, value = "当前页码从1开始", paramType = "query", required = true, dataType = "int"),
@ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query", required = true, dataType = "int"),
})
public Result page(@ApiIgnore @RequestParam Map<String, Object> params) {
PageUtils page = userPrizeExchangeService.page(params);
return Result.success().put("page", page);
}
@PostMapping("/deliver")
@ApiOperation("发放")
public Result exchange(@RequestBody UserPrizeExchange entity) {
userPrizeExchangeService.deliver(entity);
return Result.success();
}
}

View File

@@ -21,12 +21,12 @@ public class DiscSpinning extends Model<DiscSpinning> {
private String url; private String url;
//描述 //描述
private String name; private String name;
//1 普通转盘 2 周任务转盘 3 月任务转盘
private Integer discType;
//类型 1谢谢惠顾 2 红包 9 其它 //类型 1谢谢惠顾 2 红包 9 其它
private Integer type; private Integer type;
//数值 //数值
private BigDecimal number; private BigDecimal number;
//红包金额比例
private BigDecimal ratio;
//中奖概率 //中奖概率
private BigDecimal odds; private BigDecimal odds;
//创建时间 //创建时间

View File

@@ -1,5 +1,7 @@
package com.sqx.modules.discSpinning.entity; package com.sqx.modules.discSpinning.entity;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
@@ -18,6 +20,9 @@ import lombok.Data;
public class DiscSpinningAmount extends Model<DiscSpinningAmount> { public class DiscSpinningAmount extends Model<DiscSpinningAmount> {
@ApiModelProperty("主键id") @ApiModelProperty("主键id")
private Long id; private Long id;
@ApiModelProperty("从第几次开始变化")
@TableField(updateStrategy = FieldStrategy.IGNORED)
private Integer num;
@ApiModelProperty("描述") @ApiModelProperty("描述")
private String name; private String name;
@ApiModelProperty("0-1 小于 多少为该奖励") @ApiModelProperty("0-1 小于 多少为该奖励")
@@ -27,6 +32,12 @@ public class DiscSpinningAmount extends Model<DiscSpinningAmount> {
@ApiModelProperty("是否启动 0否1是") @ApiModelProperty("是否启动 0否1是")
private Integer status; private Integer status;
public void setNum(Integer num) {
if (num != null && num.equals(0)) {
this.num = null;
} else {
this.num = num;
}
}
} }

View File

@@ -47,7 +47,7 @@ public class DiscSpinningRecord extends Model<DiscSpinningRecord> {
} }
public DiscSpinningRecord(String name, Long orderId, Long userId, Integer type, BigDecimal number, public DiscSpinningRecord(String name, Long orderId, Long userId, Integer type, BigDecimal number,
String drawDay, String createTime, String source) { String drawDay, String createTime, Integer source) {
this.name = name; this.name = name;
this.userId = userId; this.userId = userId;
this.orderId = orderId; this.orderId = orderId;
@@ -55,8 +55,20 @@ public class DiscSpinningRecord extends Model<DiscSpinningRecord> {
this.number = number; this.number = number;
this.drawDay = drawDay; this.drawDay = drawDay;
this.createTime = createTime; this.createTime = createTime;
if (StringUtils.isNotBlank(source)) { if (source != null) {
this.source = source; switch (source) {
case 1:
this.source = "order";
break;
case 2:
this.source = "taskW";
break;
case 3:
this.source = "taskM";
break;
default:
this.source = source.toString();
}
} }
} }
} }

View File

@@ -8,7 +8,7 @@ import com.sqx.modules.discSpinning.entity.DiscSpinningRecord;
public interface DiscSpinningService extends IService<DiscSpinning> { public interface DiscSpinningService extends IService<DiscSpinning> {
//抽奖 //抽奖
DiscSpinningRecord draws(double orderAmount, Long orderId, Long userId, String source); DiscSpinningRecord draws(int drawCount, double orderAmount, Long orderId, Long userId, Integer source);
//领奖 //领奖
void receiveAsync(DiscSpinningRecord receive); void receiveAsync(DiscSpinningRecord receive);
@@ -16,6 +16,11 @@ public interface DiscSpinningService extends IService<DiscSpinning> {
//提现 //提现
void withdraw(UserEntity userInfo, Double money); void withdraw(UserEntity userInfo, Double money);
//提现
void withdraw(UserEntity userInfo, Double money, String title);
//提现
void withdrawAsync(UserEntity userInfo, Double money, String title);
} }

View File

@@ -17,27 +17,27 @@ import com.sqx.modules.discSpinning.dao.DiscSpinningDao;
import com.sqx.modules.discSpinning.entity.DiscSpinning; import com.sqx.modules.discSpinning.entity.DiscSpinning;
import com.sqx.modules.discSpinning.entity.DiscSpinningAmount; import com.sqx.modules.discSpinning.entity.DiscSpinningAmount;
import com.sqx.modules.discSpinning.entity.DiscSpinningRecord; import com.sqx.modules.discSpinning.entity.DiscSpinningRecord;
import com.sqx.modules.discSpinning.service.DiscSpinningAmountService;
import com.sqx.modules.discSpinning.service.DiscSpinningRecordService; import com.sqx.modules.discSpinning.service.DiscSpinningRecordService;
import com.sqx.modules.discSpinning.service.DiscSpinningService; import com.sqx.modules.discSpinning.service.DiscSpinningService;
import com.sqx.modules.orders.service.OrdersService;
import com.sqx.modules.pay.entity.CashOut; import com.sqx.modules.pay.entity.CashOut;
import com.sqx.modules.pay.service.CashOutService; import com.sqx.modules.pay.service.CashOutService;
import com.sqx.modules.pay.wuyou.BaseResp; import com.sqx.modules.pay.wuyou.BaseResp;
import com.sqx.modules.pay.wuyou.WuyouPay; import com.sqx.modules.pay.wuyou.WuyouPay;
import com.sqx.modules.utils.AliPayOrderUtil; import com.sqx.modules.utils.AliPayOrderUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.ArrayList; import java.util.*;
import java.util.Date;
import java.util.List;
import java.util.Random;
@Slf4j
@Service @Service
public class DiscSpinningServiceImpl extends ServiceImpl<DiscSpinningDao, DiscSpinning> implements DiscSpinningService { public class DiscSpinningServiceImpl extends ServiceImpl<DiscSpinningDao, DiscSpinning> implements DiscSpinningService {
@@ -49,6 +49,9 @@ public class DiscSpinningServiceImpl extends ServiceImpl<DiscSpinningDao, DiscSp
private final CashOutService cashOutService; private final CashOutService cashOutService;
private final RedisUtils redisUtils; private final RedisUtils redisUtils;
@Autowired
private PlatformTransactionManager transactionManager;
@Autowired @Autowired
public DiscSpinningServiceImpl(CommonInfoService commonRepository, public DiscSpinningServiceImpl(CommonInfoService commonRepository,
@@ -95,6 +98,12 @@ public class DiscSpinningServiceImpl extends ServiceImpl<DiscSpinningDao, DiscSp
@Override @Override
@Transactional @Transactional
public void withdraw(UserEntity userInfo, Double money) { public void withdraw(UserEntity userInfo, Double money) {
withdraw(userInfo, money, "[现金大转盘]");
}
@Override
@Transactional
public void withdraw(UserEntity userInfo, Double money, String title) {
CashOut cashOut = new CashOut(); CashOut cashOut = new CashOut();
cashOut.setIsOut(false); cashOut.setIsOut(false);
cashOut.setMoney(money.toString()); cashOut.setMoney(money.toString());
@@ -114,7 +123,7 @@ public class DiscSpinningServiceImpl extends ServiceImpl<DiscSpinningDao, DiscSp
BaseResp baseResp = WuyouPay.extractOrder(outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName()); BaseResp baseResp = WuyouPay.extractOrder(outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName());
if (baseResp.getStatus() != null && (baseResp.getStatus().equals(2) || baseResp.getStatus().equals(10000))) { if (baseResp.getStatus() != null && (baseResp.getStatus().equals(2) || baseResp.getStatus().equals(10000))) {
UserMoneyDetails userMoneyDetails = new UserMoneyDetails( UserMoneyDetails userMoneyDetails = new UserMoneyDetails(
userInfo.getUserId(), null, null, "[现金大转盘]", 4, 2, 1, userInfo.getUserId(), null, null, title, 4, 2, 1,
new BigDecimal(money), "现金红包自动提现" + money + "", 1); new BigDecimal(money), "现金红包自动提现" + money + "", 1);
userMoneyDetailsService.save(userMoneyDetails); userMoneyDetailsService.save(userMoneyDetails);
//减去余额 钱 //减去余额 钱
@@ -128,23 +137,40 @@ public class DiscSpinningServiceImpl extends ServiceImpl<DiscSpinningDao, DiscSp
} else { } else {
cashOut.setRefund(baseResp.getErrorMsg()); cashOut.setRefund(baseResp.getErrorMsg());
} }
} else if (StringUtils.isNotBlank(baseResp.getMsg())) {
cashOut.setState(2);
cashOut.setRefund("提现失败,请检查支付宝账号与收款人姓名后,重试。");
} }
} else { } else {
UserMoneyDetails userMoneyDetails = new UserMoneyDetails( UserMoneyDetails userMoneyDetails = new UserMoneyDetails(
userInfo.getUserId(), null, null, "[现金大转盘]", 4, 2, 1, userInfo.getUserId(), null, null, title, 4, 2, 1,
new BigDecimal(money), "现金红包自动提现" + money + "", 1); new BigDecimal(money), "现金红包自动提现" + money + "", 1);
userMoneyDetailsService.save(userMoneyDetails); userMoneyDetailsService.save(userMoneyDetails);
//减去余额 钱 //减去余额 钱
userMoneyService.updateAmount(2, userInfo.getUserId(), money); userMoneyService.updateAmount(2, userInfo.getUserId(), money);
} }
cashOutService.saveBody(cashOut); cashOutService.saveBody(cashOut);
log.info("领取奖励执行完毕");
} }
@Override @Override
@Transactional @Transactional
public DiscSpinningRecord draws(double orderAmount, Long orderId, Long userId, String source) { public void withdrawAsync(UserEntity userInfo, Double money, String title) {
TransactionStatus transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
withdraw(userInfo, money, title);
transactionManager.commit(transactionStatus);
}catch (Exception e){
transactionManager.rollback(transactionStatus);
throw e;
}
}
@Override
@Transactional
public DiscSpinningRecord draws(int drawCount, double orderAmount, Long orderId, Long userId, Integer source) {
DiscSpinning result = new DiscSpinning("谢谢惠顾", 1, null); DiscSpinning result = new DiscSpinning("谢谢惠顾", 1, null);
List<DiscSpinning> prizes = baseMapper.selectList(new QueryWrapper<DiscSpinning>().eq("disc_type", "order".equals(source) ? 1 : 2).orderByAsc("odds")); List<DiscSpinning> prizes = baseMapper.selectList(new QueryWrapper<DiscSpinning>().eq("disc_type", source).orderByAsc("odds"));
Random random = new Random(); Random random = new Random();
double randomDouble; double randomDouble;
@@ -153,7 +179,14 @@ public class DiscSpinningServiceImpl extends ServiceImpl<DiscSpinningDao, DiscSp
} while (randomDouble == 0); } while (randomDouble == 0);
BigDecimal randomNum = new BigDecimal(randomDouble).multiply(new BigDecimal(10000)).divide(new BigDecimal(100)); BigDecimal randomNum = new BigDecimal(randomDouble).multiply(new BigDecimal(10000)).divide(new BigDecimal(100));
List<DiscSpinningAmount> amounts = redisUtils.getListData(RedisKeys.getDateKey("spinning:amount"), DiscSpinningAmount.class, "setDiscSpinningAmounts"); List<DiscSpinningAmount> amounts = new ArrayList<>();
Map<String, List<DiscSpinningAmount>> amountMaps = redisUtils.getMapData(RedisKeys.getDateKey("spinning:amount"), "setDiscSpinningAmounts", DiscSpinningAmount.class);
for (int i = drawCount; i >= 0; i--) {
if (amountMaps.containsKey(i + "")) {
amounts = amountMaps.get(i + "");
break;
}
}
for (DiscSpinning prize : prizes) { for (DiscSpinning prize : prizes) {
if (randomNum.compareTo(prize.getNumber()) < 0) { if (randomNum.compareTo(prize.getNumber()) < 0) {
if (prize.getType() == 2) { if (prize.getType() == 2) {
@@ -180,12 +213,14 @@ public class DiscSpinningServiceImpl extends ServiceImpl<DiscSpinningDao, DiscSp
} }
result = new DiscSpinning(prize.getName(), 2, new BigDecimal(resultAmount).setScale(2, RoundingMode.HALF_UP)); result = new DiscSpinning(prize.getName(), 2, new BigDecimal(resultAmount).setScale(2, RoundingMode.HALF_UP));
break; break;
} } else {
// else { if (source != 1) {
// result = prize; result = prize;
// }
} }
} }
}
}
DiscSpinningRecord record = new DiscSpinningRecord(result.getName(), orderId, userId, result.getType(), DiscSpinningRecord record = new DiscSpinningRecord(result.getName(), orderId, userId, result.getType(),
result.getNumber(), DateUtils.formatYMD(new Date()), DateUtils.format(new Date()), source); result.getNumber(), DateUtils.formatYMD(new Date()), DateUtils.format(new Date()), source);
recordService.save(record); recordService.save(record);

View File

@@ -1,8 +1,15 @@
package com.sqx.modules.orders.controller; package com.sqx.modules.orders.controller;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sqx.common.utils.DateUtils; import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.Result; import com.sqx.common.utils.Result;
import com.sqx.modules.course.entity.CourseCollect;
import com.sqx.modules.orders.service.OrdersService; import com.sqx.modules.orders.service.OrdersService;
import com.sqx.modules.pay.dao.CashOutDao;
import com.sqx.modules.pay.entity.CashOut;
import com.sqx.modules.pay.service.CashOutService;
import com.sqx.modules.sys.controller.AbstractController; import com.sqx.modules.sys.controller.AbstractController;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@@ -14,6 +21,8 @@ import org.springframework.web.bind.annotation.RestController;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
@RestController @RestController
@@ -22,6 +31,8 @@ import java.util.*;
public class OrdersController extends AbstractController { public class OrdersController extends AbstractController {
@Autowired @Autowired
private OrdersService ordersService; private OrdersService ordersService;
@Autowired
private CashOutDao cashOutDao;
@GetMapping("/selectOrders") @GetMapping("/selectOrders")
@ApiOperation("订单信息列表") @ApiOperation("订单信息列表")
@@ -80,15 +91,33 @@ public class OrdersController extends AbstractController {
Double daiMemberOrdersMoney = ordersService.selectOrdersMoney(0, 2, flag, time, null, sysUserId); Double daiMemberOrdersMoney = ordersService.selectOrdersMoney(0, 2, flag, time, null, sysUserId);
Double wanMemberOrdersMoney = ordersService.selectOrdersMoney(1, 2, flag, time, null, sysUserId); Double wanMemberOrdersMoney = ordersService.selectOrdersMoney(1, 2, flag, time, null, sysUserId);
Double tuiMemberOrdersMoney = ordersService.selectOrdersMoney(2, 2, flag, time, null, sysUserId); Double tuiMemberOrdersMoney = ordersService.selectOrdersMoney(2, 2, flag, time, null, sysUserId);
//提现
Integer cashCount = cashOutDao.selectCount(new QueryWrapper<CashOut>()
.eq("sys_user_id", sysUserId)
.eq("state", 1)
.gt("create_at", DateUtil.format(DateUtil.parse(time, "yyyy-MM-dd"), "yyyy-MM-dd HH:mm:ss")));
Double cashSum = cashOutDao.selectSysUserCashOutSum(sysUserId, DateUtil.format(DateUtil.parse(time, "yyyy-MM-dd"), "yyyy-MM-dd HH:mm:ss"));
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
result.put("sumCourseOrdersCount",sumCourseOrdersCount);result.put("daiCourseKeOrdersCount",daiCourseKeOrdersCount);
result.put("wanCourseKeOrdersCount",wanCourseKeOrdersCount);result.put("tuiCourseOrdersCount",tuiCourseOrdersCount); result.put("sumCourseOrdersCount", sumCourseOrdersCount);
result.put("sumCourseOrdersMoney",sumCourseOrdersMoney);result.put("daiCourseOrdersMoney",daiCourseOrdersMoney); result.put("daiCourseKeOrdersCount", daiCourseKeOrdersCount);
result.put("wanCourseOrdersMoney",wanCourseOrdersMoney);result.put("tuiCourseOrdersMoney",tuiCourseOrdersMoney); result.put("wanCourseKeOrdersCount", wanCourseKeOrdersCount);
result.put("sumMemberOrdersCount",sumMemberOrdersCount);result.put("daiMemberKeOrdersCount",daiMemberKeOrdersCount); result.put("tuiCourseOrdersCount", tuiCourseOrdersCount);
result.put("wanMemberKeOrdersCount",wanMemberKeOrdersCount);result.put("tuiMemberOrdersCount",tuiMemberOrdersCount); result.put("sumCourseOrdersMoney", sumCourseOrdersMoney);
result.put("sumMemberOrdersMoney",sumMemberOrdersMoney);result.put("daiMemberOrdersMoney",daiMemberOrdersMoney); result.put("daiCourseOrdersMoney", daiCourseOrdersMoney);
result.put("wanMemberOrdersMoney",wanMemberOrdersMoney);result.put("tuiMemberOrdersMoney",tuiMemberOrdersMoney); result.put("wanCourseOrdersMoney", wanCourseOrdersMoney);
result.put("tuiCourseOrdersMoney", tuiCourseOrdersMoney);
result.put("sumMemberOrdersCount", sumMemberOrdersCount);
result.put("daiMemberKeOrdersCount", daiMemberKeOrdersCount);
result.put("wanMemberKeOrdersCount", wanMemberKeOrdersCount);
result.put("tuiMemberOrdersCount", tuiMemberOrdersCount);
result.put("sumMemberOrdersMoney", sumMemberOrdersMoney);
result.put("daiMemberOrdersMoney", daiMemberOrdersMoney);
result.put("wanMemberOrdersMoney", wanMemberOrdersMoney);
result.put("tuiMemberOrdersMoney", tuiMemberOrdersMoney);
result.put("cashCount", cashCount == null ? 0 : cashCount);
result.put("cashSum", cashSum);
return Result.success().put("data", result); return Result.success().put("data", result);
} }
@@ -178,9 +207,4 @@ public class OrdersController extends AbstractController {
result.put("year", year); result.put("year", year);
return Result.success().put("data", result); return Result.success().put("data", result);
} }
} }

View File

@@ -39,6 +39,8 @@ public interface OrdersDao extends BaseMapper<Orders> {
Integer selectOrdersCountStatisticsByDay(Long userId); Integer selectOrdersCountStatisticsByDay(Long userId);
Orders selectOrdersByDay(Long userId); Orders selectOrdersByDay(Long userId);
Integer countPayOrderByDay(Long userId);
Integer countOrderNum(Long userId, String time); Integer countOrderNum(Long userId, String time);

View File

@@ -32,6 +32,8 @@ import com.sqx.modules.utils.AmountCalUtils;
import com.sqx.modules.utils.excel.ExcelData; import com.sqx.modules.utils.excel.ExcelData;
import com.sqx.modules.utils.excel.ExportExcelUtils; import com.sqx.modules.utils.excel.ExportExcelUtils;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import lombok.val; import lombok.val;
@@ -484,8 +486,16 @@ public class CashController {
@Login @Login
@GetMapping(value = "/withdraw") @GetMapping(value = "/withdraw")
@ApiOperation("发起提现 余额 金钱") @ApiOperation("发起提现 余额 金钱")
public Result withdraw(Long userId, Double money) { @ApiImplicitParams({
return cashOutService.withdraw(userId, money, true); @ApiImplicitParam(name = "userId", value = "提现人员Id", dataTypeClass = String.class, paramType = "param"),
@ApiImplicitParam(name = "money", value = "提现金额", dataTypeClass = Double.class, paramType = "param"),
@ApiImplicitParam(name = "msg", value = "验证码", dataTypeClass = String.class, paramType = "param"),
})
public Result withdraw(Long userId, Double money, String msg) {
if (StringUtils.isBlank(msg)) {
return Result.error("请输入验证码");
}
return cashOutService.withdraw(userId, money, msg, true);
} }

View File

@@ -48,7 +48,7 @@ public class AppCashController {
@Debounce(interval = 3000, value = "#userId") @Debounce(interval = 3000, value = "#userId")
@ApiOperation("发起提现 余额 金钱") @ApiOperation("发起提现 余额 金钱")
public Result withdraw(@RequestAttribute("userId") Long userId, Double amount) { public Result withdraw(@RequestAttribute("userId") Long userId, Double amount) {
return cashOutService.withdraw(userId, amount, false); return cashOutService.withdraw(userId, amount, null, false);
} }
@Login @Login

View File

@@ -2,9 +2,7 @@ package com.sqx.modules.pay.controller.app;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.amazonaws.services.dynamodbv2.xspec.S;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.common.annotation.Debounce; import com.sqx.common.annotation.Debounce;
import com.sqx.common.utils.DateUtils; import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.Result; import com.sqx.common.utils.Result;
@@ -36,7 +34,6 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -46,6 +43,9 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/** /**
* @author GYJ * @author GYJ
@@ -67,7 +67,7 @@ public class WuyouController {
private final CashOutDao cashOutDao; private final CashOutDao cashOutDao;
private final CompletAwardService completAwardService; private final CompletAwardService completAwardService;
private final SysUserService sysUserService; private final SysUserService sysUserService;
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
WuyouController(OrdersService ordersService, PayDetailsDao payDetailsDao, UserService userService, InviteService inviteService, CashOutDao cashOutDao, WuyouController(OrdersService ordersService, PayDetailsDao payDetailsDao, UserService userService, InviteService inviteService, CashOutDao cashOutDao,
@@ -169,45 +169,18 @@ public class WuyouController {
@PostMapping("/extractNotify") @PostMapping("/extractNotify")
public String extractNotify(HttpServletRequest request, NotifyDto notifyDto) { public String extractNotify(HttpServletRequest request, NotifyDto notifyDto) {
log.info("无忧支付提现回调, {}", notifyDto); CompletableFuture.runAsync(() -> {
Map<String, Object> params = new HashMap<>(); updateCashAsync(notifyDto);
params.put("callbacks", notifyDto.getCallbacks()); // try {
params.put("total", notifyDto.getTotal()); // scheduledExecutorService.schedule(() -> updateCashAsync(notifyDto), 3, TimeUnit.SECONDS);
params.put("out_trade_no", notifyDto.getOut_trade_no()); // } catch (Exception e) {
params.put("status", notifyDto.getStatus()); // e.printStackTrace();
params.put("msg", notifyDto.getMsg()); // }
});
String sign = Encrypt.getParamsSign(params);
if (!sign.equals(notifyDto.getSign())) {
log.error("无忧支付提现回调签名错误, 参数: {},签名结果:{}", JSONObject.toJSONString(notifyDto), sign);
// return "签名错误";
}
CashOut cashOut = cashOutDao.selectOne(new QueryWrapper<CashOut>().eq("order_number", notifyDto.getOut_trade_no()));
if (cashOut != null) {
if ("2".equals(notifyDto.getStatus())) {
cashOut.setState(1);
cashOut.setOutAt(DateUtil.now());
} else if(!cashOut.getState().equals(2)){
cashOut.setState(2);
cashOut.setRefund(notifyDto.getMsg());
if(StringUtils.isNotBlank(notifyDto.getMsg()) && notifyDto.getMsg().contains("已驳回")){
cashOut.setRefund("提现失败,请检查支付宝账号与收款人姓名后,重试。");
}
UserMoneyDetails userMoneyDetails = new UserMoneyDetails(
cashOut.getUserId(), null, null, "提现失败", 4, 1, 1,
new BigDecimal(cashOut.getMoney()), "提现失败存入余额" + cashOut.getMoney() + "", 1);
//存入余额 钱
userMoneyService.updateAmount(1, cashOut.getUserId(), Double.parseDouble(cashOut.getMoney()));
userMoneyDetailsService.save(userMoneyDetails);
}else{
return "success";
}
cashOutDao.updateById(cashOut);
}
return "success"; return "success";
} }
@PostMapping("/notify") @PostMapping("/notify")
public String notify(HttpServletRequest request, NotifyDto notifyDto) { public String notify(HttpServletRequest request, NotifyDto notifyDto) {
log.info("无忧支付回调, {}", notifyDto); log.info("无忧支付回调, {}", notifyDto);
@@ -363,4 +336,42 @@ public class WuyouController {
activities(user, byUser); activities(user, byUser);
}); });
} }
private void updateCashAsync(NotifyDto notifyDto){
log.info("无忧支付提现回调, {}", notifyDto);
Map<String, Object> params = new HashMap<>();
params.put("callbacks", notifyDto.getCallbacks());
params.put("total", notifyDto.getTotal());
params.put("out_trade_no", notifyDto.getOut_trade_no());
params.put("status", notifyDto.getStatus());
params.put("msg", notifyDto.getMsg());
String sign = Encrypt.getParamsSign(params);
if (!sign.equals(notifyDto.getSign())) {
log.error("无忧支付提现回调签名错误, 参数: {},签名结果:{}", JSONObject.toJSONString(notifyDto), sign);
// return "签名错误";
}
CashOut cashOut = cashOutDao.selectOne(new QueryWrapper<CashOut>().eq("order_number", notifyDto.getOut_trade_no()));
if (cashOut != null) {
if ("2".equals(notifyDto.getStatus())) {
cashOut.setState(1);
cashOut.setOutAt(DateUtil.now());
} else if(!cashOut.getState().equals(2)){
cashOut.setState(2);
cashOut.setRefund(notifyDto.getMsg());
if(StringUtils.isNotBlank(notifyDto.getMsg()) && notifyDto.getMsg().contains("已驳回")){
cashOut.setRefund("提现失败,请检查支付宝账号与收款人姓名后重试。");
}
UserMoneyDetails userMoneyDetails = new UserMoneyDetails(
cashOut.getUserId(), null, null, "提现失败", 4, 1, 1,
new BigDecimal(cashOut.getMoney()), "提现失败存入余额" + cashOut.getMoney() + "", 1);
//存入余额 钱
userMoneyService.updateAmount(1, cashOut.getUserId(), Double.parseDouble(cashOut.getMoney()));
userMoneyDetailsService.save(userMoneyDetails);
}
cashOutDao.updateById(cashOut);
}
}
} }

View File

@@ -22,6 +22,7 @@ public interface CashOutDao extends BaseMapper<CashOut> {
List<CashOut> selectYesterday(); List<CashOut> selectYesterday();
Double selectCashOutSum(@Param("userId") Long userId, @Param("startTime") Date startTime, @Param("endTime") Date endTime); Double selectCashOutSum(@Param("userId") Long userId, @Param("startTime") Date startTime, @Param("endTime") Date endTime);
Double selectSysUserCashOutSum(@Param("sysUserId") Long sysUserId, @Param("time") String time);
Double sumMoney(@Param("time") String time, @Param("flag") Integer flag); Double sumMoney(@Param("time") String time, @Param("flag") Integer flag);

View File

@@ -43,11 +43,10 @@ public interface CashOutService {
Result sysCashMoney(Long userId, Double money); Result sysCashMoney(Long userId, Double money);
/** /**
*
* @param userId 用户Id tb_user的id * @param userId 用户Id tb_user的id
* @param money 提现金额 * @param money 提现金额
* @param isSys 是否是系统用户提现 * @param isSys 是否是系统用户提现
*/ */
Result withdraw(Long userId, Double money, boolean isSys); Result withdraw(Long userId, Double money, String msg, boolean isSys);
} }

View File

@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.common.utils.PageUtils; import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result; import com.sqx.common.utils.Result;
import com.sqx.modules.app.dao.MsgDao;
import com.sqx.modules.app.entity.Msg;
import com.sqx.modules.app.entity.UserEntity; import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserMoney; import com.sqx.modules.app.entity.UserMoney;
import com.sqx.modules.app.entity.UserMoneyDetails; import com.sqx.modules.app.entity.UserMoneyDetails;
@@ -76,6 +78,8 @@ public class CashOutServiceImpl extends ServiceImpl<CashOutDao, CashOut> impleme
private InviteMoneyService inviteMoneyService; private InviteMoneyService inviteMoneyService;
@Autowired @Autowired
private SysUserService sysUserService; private SysUserService sysUserService;
@Autowired
private MsgDao msgDao;
@Override @Override
public PageUtils selectCashOutList(Integer page, Integer limit, CashOut cashOut) { public PageUtils selectCashOutList(Integer page, Integer limit, CashOut cashOut) {
@@ -402,7 +406,7 @@ public class CashOutServiceImpl extends ServiceImpl<CashOutDao, CashOut> impleme
@Override @Override
@Transactional @Transactional
public Result withdraw(Long userId, Double money, boolean isSys) { public Result withdraw(Long userId, Double money, String msg, boolean isSys) {
if (money == null || money <= 0.00) { if (money == null || money <= 0.00) {
return Result.error("请不要输入小于0的数字,请输入正确的提现金额!"); return Result.error("请不要输入小于0的数字,请输入正确的提现金额!");
} }
@@ -412,6 +416,10 @@ public class CashOutServiceImpl extends ServiceImpl<CashOutDao, CashOut> impleme
if (isSys) { if (isSys) {
SysUserEntity sysUserEntity = sysUserService.getById(userId); SysUserEntity sysUserEntity = sysUserService.getById(userId);
Msg msg1 = msgDao.findByPhoneAndCode(sysUserEntity.getMobile(), msg);
if (msg1 == null) {
return Result.error("验证码不正确!");
}
if (StringUtils.isBlank(sysUserEntity.getZhiFuBao()) || StringUtils.isBlank(sysUserEntity.getZhiFuBaoName())) { if (StringUtils.isBlank(sysUserEntity.getZhiFuBao()) || StringUtils.isBlank(sysUserEntity.getZhiFuBaoName())) {
return Result.error(9999, "请先绑定支付宝账号!"); return Result.error(9999, "请先绑定支付宝账号!");
} }

View File

@@ -8,4 +8,8 @@ public interface RedisService {
void setDiscSpinningAmounts(String key); void setDiscSpinningAmounts(String key);
void setPayFreeWatchTime(Long userId, Integer time);
Boolean getPayFreeWatchTimeIsExpire(Long userId);
} }

View File

@@ -1,6 +1,9 @@
package com.sqx.modules.redisService.impl; package com.sqx.modules.redisService.impl;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sqx.common.utils.RedisKeys;
import com.sqx.common.utils.RedisUtils; import com.sqx.common.utils.RedisUtils;
import com.sqx.modules.discSpinning.entity.DiscSpinningAmount; import com.sqx.modules.discSpinning.entity.DiscSpinningAmount;
import com.sqx.modules.discSpinning.service.DiscSpinningAmountService; import com.sqx.modules.discSpinning.service.DiscSpinningAmountService;
@@ -9,7 +12,11 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service @Service
public class RedisServiceImpl implements RedisService { public class RedisServiceImpl implements RedisService {
@Lazy @Lazy
@@ -21,6 +28,29 @@ public class RedisServiceImpl implements RedisService {
@Override @Override
public void setDiscSpinningAmounts(String key) { public void setDiscSpinningAmounts(String key) {
List<DiscSpinningAmount> amounts = amountService.list(new QueryWrapper<DiscSpinningAmount>().eq("status", 1).orderByAsc("max_amount")); List<DiscSpinningAmount> amounts = amountService.list(new QueryWrapper<DiscSpinningAmount>().eq("status", 1).orderByAsc("max_amount"));
redisUtils.set(key, amounts); Map<Integer, List<DiscSpinningAmount>> map =
amounts.stream().collect(Collectors.groupingBy(
disc -> disc.getNum() == null ? 0 : disc.getNum()
));
redisUtils.set(key, map);
}
@Override
public void setPayFreeWatchTime(Long userId, Integer minute) {
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);
}
@Override
public Boolean getPayFreeWatchTimeIsExpire(Long userId) {
String data = redisUtils.get(RedisKeys.getPayFreeWatchKey(userId));
if (data == null) {
return null;
}
long expireTime = Long.parseLong(data);
return DateUtil.current() > expireTime;
} }
} }

View File

@@ -1,12 +1,21 @@
package com.sqx.modules.sys.controller; package com.sqx.modules.sys.controller;
import com.sqx.common.utils.Result; import com.sqx.common.utils.Result;
import com.sqx.common.validator.ValidatorUtils;
import com.sqx.common.validator.group.AddGroup;
import com.sqx.modules.app.dao.MsgDao;
import com.sqx.modules.app.entity.Msg;
import com.sqx.modules.sys.entity.SysUserEntity; import com.sqx.modules.sys.entity.SysUserEntity;
import com.sqx.modules.sys.form.SysLoginForm; import com.sqx.modules.sys.form.SysLoginForm;
import com.sqx.modules.sys.service.SysCaptchaService; import com.sqx.modules.sys.service.SysCaptchaService;
import com.sqx.modules.sys.service.SysUserService; import com.sqx.modules.sys.service.SysUserService;
import com.sqx.modules.sys.service.SysUserTokenService; import com.sqx.modules.sys.service.SysUserTokenService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash; import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -19,13 +28,17 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map; import java.util.Map;
/** /**
* 登录相关 * 登录相关
*
*/ */
@RestController @RestController
@Api(value = "登录相关", tags = {"登录相关"})
public class SysLoginController extends AbstractController { public class SysLoginController extends AbstractController {
@Autowired @Autowired
private SysUserService sysUserService; private SysUserService sysUserService;
@@ -33,6 +46,8 @@ public class SysLoginController extends AbstractController {
private SysUserTokenService sysUserTokenService; private SysUserTokenService sysUserTokenService;
@Autowired @Autowired
private SysCaptchaService sysCaptchaService; private SysCaptchaService sysCaptchaService;
@Autowired
private MsgDao msgDao;
/** /**
* 验证码 * 验证码
@@ -50,6 +65,33 @@ public class SysLoginController extends AbstractController {
IOUtils.closeQuietly(out); IOUtils.closeQuietly(out);
} }
@PostMapping("/sys/registered")
@ApiOperation("代理注册")
@ApiImplicitParams({
@ApiImplicitParam(name = "msg", value = "验证码", dataTypeClass = String.class, paramType = "param"),
})
public Result registered(@RequestBody SysUserEntity user, String msg) {
if(StringUtils.isBlank(user.getMobile())){
return Result.error("注册失败,请输入手机号");
}
if(StringUtils.isBlank(msg)){
return Result.error("注册失败,请输入验证码");
}
Msg msg1 = msgDao.findByPhoneAndCode(user.getMobile(), msg);
if (msg1 == null) {
return Result.error("验证码不正确!");
}
user.setIsChannel(1);
user.setQdRate(new BigDecimal("0.01"));
user.setStatus(1);
user.setRoleIdList(Collections.singletonList(4L));
ValidatorUtils.validateEntity(user, AddGroup.class);
sysUserService.saveUser(user);
return Result.success();
}
/** /**
* 登录 * 登录
*/ */

View File

@@ -10,6 +10,7 @@ import com.sqx.modules.sys.entity.SysUserEntity;
import com.sqx.modules.sys.service.SysRoleService; import com.sqx.modules.sys.service.SysRoleService;
import com.sqx.modules.sys.service.SysUserRoleService; import com.sqx.modules.sys.service.SysUserRoleService;
import com.sqx.modules.sys.service.SysUserService; import com.sqx.modules.sys.service.SysUserService;
import com.sqx.modules.utils.InvitationCodeUtil;
import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash; import org.apache.shiro.crypto.hash.Sha256Hash;
@@ -25,7 +26,6 @@ import java.util.Map;
/** /**
* 系统用户 * 系统用户
*
*/ */
@SuppressWarnings("ALL") @SuppressWarnings("ALL")
@Service("sysUserService") @Service("sysUserService")
@@ -80,7 +80,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> i
user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex()); user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex());
user.setSalt(salt); user.setSalt(salt);
this.save(user); this.save(user);
if (user.getIsChannel() != null && user.getIsChannel().equals(1) && StringUtils.isBlank(user.getQdCode())) {
user.setQdCode(InvitationCodeUtil.toRegisteredCode(user.getUserId()));
this.updateById(user);
}
//检查角色是否越权 //检查角色是否越权
checkRole(user); checkRole(user);

View File

@@ -10,6 +10,6 @@ import java.util.List;
public interface TaskCenterDao extends BaseMapper<TaskCenter> { public interface TaskCenterDao extends BaseMapper<TaskCenter> {
//大转盘任务 //大转盘任务
List<TaskCenter> queryTaskDiscCenter(Long userId); List<TaskCenter> queryTaskDiscCenter();
} }

View File

@@ -1,15 +1,10 @@
package com.sqx.modules.taskCenter.entity; package com.sqx.modules.taskCenter.entity;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.Data; import lombok.Data;
/** /**
@@ -46,6 +41,10 @@ public class TaskCenter extends Model<TaskCenter> {
private Integer jumpType; private Integer jumpType;
@ApiModelProperty("按钮跳转地址") @ApiModelProperty("按钮跳转地址")
private String buttonUrl; private String buttonUrl;
@ApiModelProperty("按钮下方内容")
private String buttonUnderContent;
@ApiModelProperty("按钮下方内容 跳转路径")
private String buttonUnderUrl;
private String createTime; private String createTime;
private String updateTime; private String updateTime;
@ApiModelProperty("排序") @ApiModelProperty("排序")

View File

@@ -12,6 +12,6 @@ public interface TaskCenterService extends IService<TaskCenter> {
Result taskReceive(Long userId, Long id); Result taskReceive(Long userId, Long id);
int countTaskDisc(Long userId); int countTaskDisc(Long userId,String type);
} }

View File

@@ -19,6 +19,7 @@ import com.sqx.modules.taskCenter.service.TaskCenterRewardService;
import com.sqx.modules.taskCenter.service.TaskCenterService; import com.sqx.modules.taskCenter.service.TaskCenterService;
import com.sqx.modules.userSign.entity.UserSignRecord; import com.sqx.modules.userSign.entity.UserSignRecord;
import com.sqx.modules.userSign.service.UserSignRecordService; import com.sqx.modules.userSign.service.UserSignRecordService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -70,7 +71,7 @@ public class TaskCenterServiceImpl extends ServiceImpl<TaskCenterDao, TaskCenter
} else if (recordService.countTaskNum(userId, s.getId(), DateUtil.today() + " 00:00:00") > 0) { } else if (recordService.countTaskNum(userId, s.getId(), DateUtil.today() + " 00:00:00") > 0) {
s.setButtonTitle("已领取"); s.setButtonTitle("已领取");
s.setNumber(null); s.setNumber(null);
s.setDisabled(false); // s.setDisabled(false);
} else { } else {
s.setDiscNumber(0); s.setDiscNumber(0);
s.setNumber(null); s.setNumber(null);
@@ -79,7 +80,7 @@ public class TaskCenterServiceImpl extends ServiceImpl<TaskCenterDao, TaskCenter
} else { } else {
if (todaySign) { if (todaySign) {
if ((signCount < (s.getNumber().intValue() - 1))) { if ((signCount < (s.getNumber().intValue() - 1))) {
s.setDiscNumber(s.getNumber() - signCount); s.setDiscNumber(signCount);
s.setNumber(null); s.setNumber(null);
s.setDisabled(false); s.setDisabled(false);
} else if (recordService.countTaskNum(userId, s.getId(), DateUtil.beginOfMonth(new Date()).toString()) > 0) { } else if (recordService.countTaskNum(userId, s.getId(), DateUtil.beginOfMonth(new Date()).toString()) > 0) {
@@ -89,7 +90,7 @@ public class TaskCenterServiceImpl extends ServiceImpl<TaskCenterDao, TaskCenter
} }
} else { } else {
if ((signCount < s.getNumber().intValue())) { if ((signCount < s.getNumber().intValue())) {
s.setDiscNumber(s.getNumber() - signCount); s.setDiscNumber(signCount);
s.setDisabled(false); s.setDisabled(false);
s.setNumber(null); s.setNumber(null);
} else if (recordService.countTaskNum(userId, s.getId(), DateUtil.beginOfMonth(new Date()).toString()) > 0) { } else if (recordService.countTaskNum(userId, s.getId(), DateUtil.beginOfMonth(new Date()).toString()) > 0) {
@@ -226,7 +227,10 @@ public class TaskCenterServiceImpl extends ServiceImpl<TaskCenterDao, TaskCenter
} }
@Override @Override
public int countTaskDisc(Long userId) { public int countTaskDisc(Long userId, String type) {
if (StringUtils.isBlank(type) || "1".equals(type)) {
return 0;
}
//月 签到记录 //月 签到记录
QueryWrapper<UserSignRecord> signWrapper = new QueryWrapper<>(); QueryWrapper<UserSignRecord> signWrapper = new QueryWrapper<>();
signWrapper.eq("user_id", userId); signWrapper.eq("user_id", userId);
@@ -235,7 +239,7 @@ public class TaskCenterServiceImpl extends ServiceImpl<TaskCenterDao, TaskCenter
int signCount = signRecordService.count(signWrapper); int signCount = signRecordService.count(signWrapper);
//TaskCenter的number为大转盘次数 //TaskCenter的number为大转盘次数
List<TaskCenter> taskCenters = baseMapper.queryTaskDiscCenter(userId); List<TaskCenter> taskCenters = baseMapper.queryTaskDiscCenter();
int countTaskDisc = 0; int countTaskDisc = 0;
Integer dayOrderNum = ordersService.countOrderNum(userId, DateUtil.today() + " 00:00:00"); Integer dayOrderNum = ordersService.countOrderNum(userId, DateUtil.today() + " 00:00:00");
for (TaskCenter taskCenter : taskCenters) { for (TaskCenter taskCenter : taskCenters) {
@@ -245,6 +249,7 @@ public class TaskCenterServiceImpl extends ServiceImpl<TaskCenterDao, TaskCenter
countTaskDisc = countTaskDisc + taskCenter.getDiscNumber(); countTaskDisc = countTaskDisc + taskCenter.getDiscNumber();
} }
} else { } else {
if ("2".equals(type) && taskCenter.getNumber().intValue() > 1 && taskCenter.getNumber().intValue() < 8) {
if (dayOrderNum > 2) { if (dayOrderNum > 2) {
if (signCount - taskCenter.getNumber().intValue() >= -1 && recordService.countTaskNum(userId, taskCenter.getId(), DateUtil.beginOfMonth(new Date()).toString()) < 1) { if (signCount - taskCenter.getNumber().intValue() >= -1 && recordService.countTaskNum(userId, taskCenter.getId(), DateUtil.beginOfMonth(new Date()).toString()) < 1) {
countTaskDisc = countTaskDisc + taskCenter.getDiscNumber(); countTaskDisc = countTaskDisc + taskCenter.getDiscNumber();
@@ -254,7 +259,17 @@ public class TaskCenterServiceImpl extends ServiceImpl<TaskCenterDao, TaskCenter
countTaskDisc = countTaskDisc + taskCenter.getDiscNumber(); countTaskDisc = countTaskDisc + taskCenter.getDiscNumber();
} }
} }
} else if ("3".equals(type) && taskCenter.getNumber().intValue() > 7 && taskCenter.getNumber().intValue() < 32) {
if (dayOrderNum > 2) {
if (signCount - taskCenter.getNumber().intValue() >= -1 && recordService.countTaskNum(userId, taskCenter.getId(), DateUtil.beginOfMonth(new Date()).toString()) < 1) {
countTaskDisc = countTaskDisc + taskCenter.getDiscNumber();
}
} else {
if (signCount - taskCenter.getNumber().intValue() >= 0 && recordService.countTaskNum(userId, taskCenter.getId(), DateUtil.beginOfMonth(new Date()).toString()) < 1) {
countTaskDisc = countTaskDisc + taskCenter.getDiscNumber();
}
}
}
} }
} }
} }

View File

@@ -1,35 +1,46 @@
package com.sqx.modules.userSign.controller; package com.sqx.modules.userSign.controller;
import com.sqx.modules.userSign.entity.UserSignRecord;
import com.sqx.modules.userSign.service.UserSignRecordService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.Result; import com.sqx.common.utils.Result;
import com.sqx.modules.sys.controller.AbstractController;
import com.sqx.modules.userSign.service.UserSignRecordService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Date; import org.springframework.web.bind.annotation.RestController;
@Slf4j @Slf4j
@RestController @RestController
@Api(value = "用户签到", tags = {"用户签到"}) @Api(value = "用户签到", tags = {"用户签到"})
@RequestMapping(value = "/userSignRecord") @RequestMapping(value = "/userSignRecord")
public class UserSignRecordController { public class UserSignRecordController extends AbstractController {
/** /**
* 服务对象 * 服务对象
*/ */
@Autowired @Autowired
private UserSignRecordService userSignRecordService; private UserSignRecordService userSignRecordService;
// @GetMapping("/selectUserSignRecord") /**
// @ApiOperation("查询用户签到表") * 获取用户连续签到数据
// public Result selectUserSignRecord(Integer page, Integer limit,@RequestAttribute("userId") Long userId) { */
// return Result.success().put("data", userSignRecordService.page(new Page<>(page, limit), new QueryWrapper<UserSignRecord>().orderByAsc("create_time"))); @GetMapping("/getUserSignData")
// } @ApiOperation("获取用户连续签到数据")
public Result getUserSignData() {
//UserSignDTO data = userSignRecordService.getUserSignData();
return Result.success().put("data", null);
}
/**
* 获取连续签到奖励配置
*/
@GetMapping("/getUserSignAwardConfig")
@ApiOperation(value = "获取连续签到奖励配置", notes = "如:[7,7] = 连续签到7天奖励7元")
public Result getUserSignAwardConfig() {
String[] data = userSignRecordService.getUserSignAwardConfig();
return Result.success().put("data", data);
}
} }

View File

@@ -0,0 +1,38 @@
package com.sqx.modules.userSign.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 用户签到数据
*
* @author tankaikai
* @since 2024-12-18 17:34
*/
@Data
@ApiModel(value = "用户签到数据")
public class UserSignDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用户id")
private Long userId;
@ApiModelProperty(value = "用户名")
private String username;
@ApiModelProperty(value = "手机号")
private String mobile;
@ApiModelProperty(value = "连续签到天数")
private Integer signDays;
@ApiModelProperty(value = "该用户能否参加签到活动", example = "1-允许,0-不允许")
private Integer enable;
@ApiModelProperty(value = "连续签到记录")
private List<UserSignRecordDTO> recordList;
}

View File

@@ -0,0 +1,32 @@
package com.sqx.modules.userSign.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 用户连续签到记录
*
* @author tankaikai
* @since 2024-12-18 17:34
*/
@Data
@ApiModel(value = "用户连续签到记录")
public class UserSignRecordDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "签到日期", required = true, example = "2024-12-18")
private String signDay;
@ApiModelProperty(value = "签到状态", required = true, example = "0-未签到, 1-已签到")
private String status;
@ApiModelProperty(value = "展示文本", required = true, example = "未签到, 待签到, 已签到, 第x天")
private String showText;
@ApiModelProperty(value = "签到时间", example = "2024-12-18 17:34:00")
private String signDate;
}

View File

@@ -1,11 +1,14 @@
package com.sqx.modules.userSign.service; package com.sqx.modules.userSign.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.sqx.modules.userSign.dto.UserSignDTO;
import com.sqx.modules.userSign.entity.UserSignRecord; import com.sqx.modules.userSign.entity.UserSignRecord;
import java.util.Map;
public interface UserSignRecordService extends IService<UserSignRecord> { public interface UserSignRecordService extends IService<UserSignRecord> {
UserSignDTO getUserSignData(long userId);
String[] getUserSignAwardConfig();
} }

View File

@@ -1,14 +1,145 @@
package com.sqx.modules.userSign.service.impl; package com.sqx.modules.userSign.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.common.exception.SqxException;
import com.sqx.modules.app.dao.UserDao;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.common.dao.CommonInfoDao;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.userSign.dao.UserSignRecordDao; import com.sqx.modules.userSign.dao.UserSignRecordDao;
import com.sqx.modules.userSign.dto.UserSignDTO;
import com.sqx.modules.userSign.dto.UserSignRecordDTO;
import com.sqx.modules.userSign.entity.UserSignRecord; import com.sqx.modules.userSign.entity.UserSignRecord;
import com.sqx.modules.userSign.service.UserSignRecordService; import com.sqx.modules.userSign.service.UserSignRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service @Service
public class UserSignRecordServiceImpl extends ServiceImpl<UserSignRecordDao, UserSignRecord> implements UserSignRecordService { public class UserSignRecordServiceImpl extends ServiceImpl<UserSignRecordDao, UserSignRecord> implements UserSignRecordService {
@Autowired
private CommonInfoDao commonInfoDao;
@Autowired
private UserDao userDao;
@Override
public UserSignDTO getUserSignData(long userId) {
UserEntity currentUser = userDao.selectById(userId);
UserSignDTO dto = new UserSignDTO();
dto.setUserId(currentUser.getUserId());
dto.setUsername(currentUser.getUserName());
dto.setMobile(currentUser.getPhone());
dto.setSignDays(0);
dto.setEnable(1);
CommonInfo config = commonInfoDao.findOne(918);
if (config == null) {
throw new SqxException("签到活动配置不存在");
}
// 活动天数
int activeDays = Convert.toInt(config.getValue().split(",")[0]);
// 当前日期
LocalDate beginDay = LocalDate.now();
// 签到记录
List<UserSignRecordDTO> recordList = new ArrayList<>();
// 连续签到日期
List<String> flowDays = buildFlowDays(beginDay, activeDays);
// 实际签到记录
List<UserSignRecord> list = baseMapper.selectList(Wrappers.<UserSignRecord>lambdaQuery().eq(UserSignRecord::getUserId, currentUser.getUserId()).orderByAsc(UserSignRecord::getCreateTime));
// 第x天
int index = 1;
// 连续签到天数
int signDays = 0;
if (CollUtil.isEmpty(list)) {
for (String day : flowDays) {
UserSignRecordDTO record = new UserSignRecordDTO();
record.setSignDay(day);
record.setStatus("0");
record.setShowText(StrUtil.format("第{}天", index));
record.setSignDate("");
recordList.add(record);
index++;
}
dto.setRecordList(recordList);
dto.setSignDays(signDays);
return dto;
}
String beginSignDay = list.stream().findFirst().get().getSignDay();
flowDays = buildFlowDays(LocalDate.parse(beginSignDay, DateTimeFormatter.ofPattern("yyyy-MM-dd")), activeDays);
index = 1;
Map<String, Date> signMap = list.stream().collect(Collectors.toMap(UserSignRecord::getSignDay, UserSignRecord::getCreateTime));
for (String day : flowDays) {
Date date = signMap.get(day);
UserSignRecordDTO record = new UserSignRecordDTO();
if (date != null) {
String signDay = DateUtil.formatDateTime(signMap.get(day));
record.setSignDay(day);
record.setStatus("1");
record.setSignDate(signDay);
record.setShowText("已签到");
signDays++;
} else {
record.setSignDay(day);
record.setStatus("0");
record.setSignDate("");
LocalDate thisDay = LocalDate.parse(day);
LocalDate currentDay = LocalDate.now();
long daysBetween = ChronoUnit.DAYS.between(thisDay, currentDay);
if (daysBetween > 0) {
signDays = 0;
record.setShowText("未签到");
} else if (daysBetween == 0) {
record.setShowText("待签到");
} else {
record.setShowText(StrUtil.format("第{}天", index));
}
}
recordList.add(record);
index++;
}
dto.setRecordList(recordList);
dto.setSignDays(signDays);
// 该用户是否可以继续签到
UserSignRecordDTO last = recordList.get(recordList.size() - 1);
LocalDate lastDay = LocalDate.parse(last.getSignDay());
LocalDate currentDay = LocalDate.now();
long daysBetween = ChronoUnit.DAYS.between(currentDay, lastDay);
if (daysBetween < 0 || "1".equals(last.getStatus())) {
dto.setEnable(0);
}
return dto;
}
@Override
public String[] getUserSignAwardConfig() {
CommonInfo config = commonInfoDao.findOne(918);
if (config == null) {
throw new SqxException("签到活动配置不存在");
}
return config.getValue().split(",");
}
private List<String> buildFlowDays(LocalDate beginDay, int activeDays) {
List<String> flowDays = new ArrayList<>();
for (int i = 0; i < activeDays; i++) {
flowDays.add(beginDay.plusDays(i).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
}
return flowDays;
}
} }

View File

@@ -2,30 +2,73 @@ package com.sqx.modules.utils;
/** /**
* 邀请码生成解密工具类 * 邀请码生成解密工具类
*
* @author fang * @author fang
* @date 2020/7/8 * @date 2020/7/8
*/ */
public class InvitationCodeUtil { public class InvitationCodeUtil {
/** 自定义进制选择你想要的进制数不能重复且最好不要0、1这些容易混淆的字符 */ /**
* 自定义进制选择你想要的进制数不能重复且最好不要0、1这些容易混淆的字符
*/
private static final char[] r = new char[]{'M', 'J', 'U', 'D', 'Z', 'X', '9', 'C', '7', 'P', 'E', '8', '6', 'B', 'G', 'H', 'S', '2', '5', 'F', 'R', '4', 'Q', 'W', 'K', '3', 'V', 'Y', 'T', 'N'}; private static final char[] r = new char[]{'M', 'J', 'U', 'D', 'Z', 'X', '9', 'C', '7', 'P', 'E', '8', '6', 'B', 'G', 'H', 'S', '2', '5', 'F', 'R', '4', 'Q', 'W', 'K', '3', 'V', 'Y', 'T', 'N'};
/** 定义一个字符用来补全邀请码长度(该字符前面是计算出来的邀请码,后面是用来补全用的) */ /**
* 定义一个字符用来补全邀请码长度(该字符前面是计算出来的邀请码,后面是用来补全用的)
*/
private static final char b = 'A'; private static final char b = 'A';
/** 进制长度 */ /**
* 进制长度
*/
private static final int binLen = r.length; private static final int binLen = r.length;
/** 邀请码长度 */ /**
* 邀请码长度
*/
private static final int s = 6; private static final int s = 6;
/** 补位字符串 */ /**
* 补位字符串
*/
private static final String e = "KSLFXFR"; private static final String e = "KSLFXFR";
/**
* 代理注册 补位字符串
*/
private static final String re = "REGISTER";
/** /**
* 根据ID生成六位随机码 * 根据ID生成六位随机码
*
* @param id ID
* @return 随机码
*/
public static String toRegisteredCode(long id) {
char[] buf = new char[32];
int charPos = 32;
while ((id / binLen) > 0) {
int ind = (int) (id % binLen);
buf[--charPos] = r[ind];
id /= binLen;
}
buf[--charPos] = r[(int) (id % binLen)];
String str = new String(buf, charPos, (32 - charPos));
// 不够长度的自动补全
if (str.length() < s) {
StringBuilder sb = new StringBuilder();
sb.append(re.subSequence(0, s - str.length()));
str += sb.toString();
}
return str;
}
/**
* 根据ID生成六位随机码
*
* @param id ID * @param id ID
* @return 随机码 * @return 随机码
*/ */
@@ -51,6 +94,7 @@ public class InvitationCodeUtil {
/** /**
* 根据随机码生成ID * 根据随机码生成ID
*
* @param code 随机码 * @param code 随机码
* @return ID * @return ID
*/ */
@@ -79,8 +123,4 @@ public class InvitationCodeUtil {
} }
} }

View File

@@ -319,4 +319,12 @@
and create_time > #{time} and create_time > #{time}
</if> </if>
</select> </select>
<select id="countPayOrderByDay" resultType="java.lang.Integer">
SELECT count(*)
FROM orders
WHERE orders.user_id = #{userId}
AND orders.`status` = 1
AND orders.`pay_way` = 9
AND orders.create_time > DATE_FORMAT(CURDATE(), '%Y-%m-%d 00:00:00')
</select>
</mapper> </mapper>

View File

@@ -19,6 +19,10 @@
select sum(money) from cash_out where state in (0,1) and user_id=#{userId} and date_format(create_at,'%Y-%m-%d') between #{startTime} and #{endTime} select sum(money) from cash_out where state in (0,1) and user_id=#{userId} and date_format(create_at,'%Y-%m-%d') between #{startTime} and #{endTime}
</select> </select>
<select id="selectSysUserCashOutSum" resultType="Double">
select sum(money) from cash_out where state = 1 and sys_user_id=#{sysUserId} and create_at &gt; #{time}
</select>
<select id="sumMoney" resultType="Double"> <select id="sumMoney" resultType="Double">
select sum(money) from cash_out where state =1 select sum(money) from cash_out where state =1
<if test="flag!=null and flag==1"> <if test="flag!=null and flag==1">

View File

@@ -9,7 +9,6 @@
FROM task_center_reward reward FROM task_center_reward reward
INNER JOIN task_center task ON reward.task_id = task.id and task.shows = 1 INNER JOIN task_center task ON reward.task_id = task.id and task.shows = 1
where reward.type = 9 where reward.type = 9
and user_id = #{userId}
</select> </select>
</mapper> </mapper>