Compare commits

..

No commits in common. "dev" and "master" have entirely different histories.
dev ... master

394 changed files with 5348 additions and 20258 deletions

View File

@ -249,7 +249,7 @@ INSERT INTO `common_info` VALUES (420, '2023-08-28 11:23:02', NULL, '一级佣
INSERT INTO `common_info` VALUES (421, '2024-03-05 16:55:37', NULL, '二级佣金比例', 421, '0.04', 'fuwufei');
INSERT INTO `common_info` VALUES (450, '2024-02-02 18:12:27', NULL, '剧导入模板', 450, 'https://duanju.xianmxkj.com/剧导入模板.xlsx', 'xitong');
INSERT INTO `common_info` VALUES (451, '2024-02-02 18:12:49', NULL, '集导入模板', 451, 'https://duanju.xianmxkj.com/集导入模板.xlsx', 'xitong');
INSERT INTO `common_info` VALUES (500, '2020-02-25 20:44:15', NULL, '付费须知说明', 500, '一经购买不予退款未满18岁需在监护人的指导、同意下进行付费操作', 'xieyi');
INSERT INTO `common_info` VALUES (500, '2020-02-25 20:44:15', NULL, '付费须知说明', 500, '一经购买不予退款未满18岁需在监护人的指导、同意下进行付费操作', 'xieyi');
INSERT INTO `common_info` VALUES (800, '2024-05-30 18:08:11', NULL, '腾讯云oss AccessKey', 800, '', 'oss');
INSERT INTO `common_info` VALUES (801, '2024-05-30 18:08:06', NULL, '腾讯云oss SecretKey', 801, '', 'oss');
INSERT INTO `common_info` VALUES (802, '2024-05-30 18:08:17', NULL, '腾讯云oss bucket地域', 802, 'ap-shanghai', 'oss');
@ -274,7 +274,7 @@ INSERT INTO `common_info` VALUES (821, '2024-01-06 11:40:25', NULL, '抖音原
INSERT INTO `common_info` VALUES (822, '2024-06-26 16:07:33', NULL, '小程序AppKey', 822, '', 'xitong');
INSERT INTO `common_info` VALUES (823, '2024-06-26 16:07:18', NULL, '微信虚拟支付OfferID', 823, '', 'xitong');
INSERT INTO `common_info` VALUES (824, '2024-07-08 02:19:39', NULL, '微信虚拟支付环境 0正式环境 1沙盒环境', 824, '0', 'xitong');
INSERT INTO `common_info` VALUES (825, '2024-01-06 11:40:25', NULL, '充值提示', 825, '一经购买不予退款未满18岁需在监护人的指导、同意下进行付费操作', 'xitong');
INSERT INTO `common_info` VALUES (825, '2024-01-06 11:40:25', NULL, '充值提示', 825, '一经购买不予退款未满18岁需在监护人的指导、同意下进行付费操作', 'xitong');
INSERT INTO `common_info` VALUES (826, '2024-06-26 16:07:54', NULL, '小程序Token', 826, '', 'weixin');
INSERT INTO `common_info` VALUES (827, '2024-06-26 16:07:44', NULL, '小程序EncodingAESKey ', 827, '', 'weixin');
INSERT INTO `common_info` VALUES (828, '2020-02-25 20:43:59', NULL, '快手AppId', 828, '', 'xitong');

166
pom.xml
View File

@ -23,7 +23,7 @@
<mssql.version>4.0</mssql.version>
<oracle.version>11.2.0.3</oracle.version>
<druid.version>1.1.13</druid.version>
<!-- <quartz.version>2.3.0</quartz.version>-->
<quartz.version>2.3.0</quartz.version>
<commons.lang.version>2.6</commons.lang.version>
<commons.fileupload.version>1.2.2</commons.fileupload.version>
<commons.io.version>2.5</commons.io.version>
@ -35,14 +35,12 @@
<qiniu.version>7.2.23</qiniu.version>
<aliyun.oss.version>3.4.0</aliyun.oss.version>
<qcloud.cos.version>4.4</qcloud.cos.version>
<!-- <swagger.version>2.7.0</swagger.version>-->
<swagger.version>2.9.2</swagger.version>
<swagger.version>2.7.0</swagger.version>
<joda.time.version>2.9.9</joda.time.version>
<gson.version>2.8.5</gson.version>
<fastjson.version>1.2.83</fastjson.version>
<hutool.version>4.6.10</hutool.version>
<lombok.version>1.18.4</lombok.version>
<shardingsphere.version>4.1.1</shardingsphere.version>
<!--wagon plugin 配置-->
<!--<service-path>/work/sz</service-path>
@ -53,31 +51,6 @@
</properties>
<dependencies>
<dependency>
<groupId>com.github.brainlag</groupId>
<artifactId>nsq-client</artifactId>
<version>1.0.0.RC4</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dytnsapi20200217</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea-openapi</artifactId>
<version>0.3.6</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea-console</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea-util</artifactId>
<version>0.2.23</version>
</dependency>
<dependency>
<groupId>com.volcengine</groupId>
@ -90,27 +63,15 @@
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.amazonaws</groupId>-->
<!-- <artifactId>aws-java-sdk</artifactId>-->
<!-- <version>1.11.274</version>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <artifactId>aws-java-sdk-simpleworkflow</artifactId>-->
<!-- <groupId>com.amazonaws</groupId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.274</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.0.0</version>
<exclusions>
<exclusion>
<artifactId>javassist</artifactId>
<groupId>org.javassist</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.qcloudsms</groupId>
@ -130,6 +91,13 @@
</exclusions>
</dependency>
<!--云购os支付-->
<dependency>
<groupId>com.yungouos.pay</groupId>
<artifactId>yungouos-pay-sdk</artifactId>
<version>2.0.10</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
@ -155,11 +123,11 @@
<version>5.5.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<!-- <dependency>-->
<!-- <groupId>com.alibaba</groupId>-->
<!-- <artifactId>druid</artifactId>-->
<!-- <version>1.1.10</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- 苹果工具类 -->
<dependency>
<groupId>com.auth0</groupId>
@ -209,12 +177,6 @@
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.4.0</version>
<exclusions>
<exclusion>
<artifactId>aliyun-java-sdk-core</artifactId>
<groupId>com.aliyun</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
@ -279,40 +241,16 @@
</exclusion>
</exclusions>
</dependency>
<!--动态数据库切换-->
<!-- <dependency>-->
<!-- <groupId>com.baomidou</groupId>-->
<!-- <artifactId>dynamic-datasource-spring-boot-starter</artifactId>-->
<!-- <version>4.1.3</version>-->
<!-- </dependency>-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--oracle驱动-->
<!-- <dependency>-->
<!-- <groupId>com.oracle</groupId>-->
<!-- <artifactId>ojdbc6</artifactId>-->
<!-- <version>${oracle.version}</version>-->
<!-- </dependency>-->
<!-- 用于定义sharding-jdbc 分片规则 -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-core-api</artifactId>
<version>${shardingsphere.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>${shardingsphere.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${oracle.version}</version>
</dependency>
<!--mssql驱动-->
<dependency>
@ -321,26 +259,26 @@
<version>${mssql.version}</version>
</dependency>
<!--postgresql驱动-->
<!-- <dependency>-->
<!-- <groupId>org.postgresql</groupId>-->
<!-- <artifactId>postgresql</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.quartz-scheduler</groupId>-->
<!-- <artifactId>quartz</artifactId>-->
<!-- <version>${quartz.version}</version>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>com.mchange</groupId>-->
<!-- <artifactId>c3p0</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>${quartz.version}</version>
<exclusions>
<exclusion>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
@ -381,27 +319,16 @@
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.22</version>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.22</version>
</dependency>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
@ -492,22 +419,11 @@
<artifactId>restful-sdk</artifactId>
<version>1.0.0.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!--<dependency>-->
<!--<dependency>-->
<!--<groupId>com.baidu.aip</groupId>-->
<!--            <artifactId>java-sdk</artifactId>-->
<!--            <version>4.11.3</version>-->
<!--</dependency>-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
</dependencies>
<build>

View File

@ -2,16 +2,8 @@ package com.sqx;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import java.util.Map;
/**
* @author GYJ
*/
@EnableCaching
@EnableScheduling
@SpringBootApplication
public class SqxApplication {
@ -19,13 +11,13 @@ public class SqxApplication {
public static void main(String[] args) {
SpringApplication.run(SqxApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 短剧系统启动成功 ლ(´ڡ`ლ)゙ \n"+
" _ \n" +
" | | \n" +
" ___ | | __\n" +
" / _ \\| |/ /\n" +
"| (_) | < \n" +
" \\___/|_|\\_\\");
" _ \n" +
" | | \n" +
" ___ | | __\n" +
" / _ \\| |/ /\n" +
"| (_) | < \n" +
" \\___/|_|\\_\\");
}
}
}

View File

@ -1,24 +0,0 @@
package com.sqx.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;
/**
* @author ww
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Debounce {
// 防抖时间间隔默认2秒
long interval() default 2000;
// 时间单位默认毫秒
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
// 用于指定基于的入参表达式为空时对整个方法防抖
// 格式为 #入参键. 例如 #receive.id
// 多个参数 使用逗号进行拼接 例如: #receive.id,#receive.name
String value() default "";
}

View File

@ -1,17 +0,0 @@
package com.sqx.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 限流注解
* @author GYJoker
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Limiting {
// 默认每秒放入桶中的token
double limitNum() default 10;
}

View File

@ -1,121 +0,0 @@
package com.sqx.common.aspect;
import cn.hutool.core.thread.ThreadUtil;
import com.google.gson.Gson;
import com.sqx.common.exception.CzgException;
import com.sqx.common.exception.LimitException;
import com.sqx.common.exception.UserException;
import com.sqx.common.utils.HttpContextUtils;
import com.sqx.common.utils.IPUtils;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.app.utils.JwtUtils;
import com.sqx.modules.common.service.CommonInfoService;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* 方法调用统一切面处理
*/
@Aspect
@Component
@Slf4j
//@Profile({"dev"})
public class AppApiMethodAspect {
@Autowired
private CommonInfoService commonInfoService;
@Autowired
private UserService userService;
@Autowired
private JwtUtils jwtUtils;
@Pointcut("!execution(public * (com.sqx.modules.sys.controller.SysLoginController).*(..)) " +
"&& execution(public * (com.sqx.modules.*.controller..*).*(..)))")
public void pkg() {
}
@Around("pkg()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
String requestUrl = request.getRequestURL().toString();
if (!requestUrl.contains("common/")) {
String token = request.getHeader("token");
if (StringUtils.isNotBlank(token)) {
Claims claims = jwtUtils.getClaimByToken(token);
if (claims != null && !jwtUtils.isTokenExpired(claims.getExpiration())) {
Long userId = Long.parseLong(claims.getSubject());
UserEntity userInfo = userService.selectUserById(userId);
if (userInfo == null) {
throw new CzgException("用户不存在");
} else if (userInfo.getStatus() == 0) {
throw new UserException("用户被拉黑", 701);
} else if (userInfo.getStatus() == 2) {
throw new UserException("用户被禁用", 702);
}
}
}
}
long start = System.currentTimeMillis();
//避免回填
Object[] args = pjp.getArgs();
// 如果请求参数中包含HttpServletRequest剔除HttpServletRequest
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof HttpServletRequest) {
args[i] = null;
}
}
String requestIp = IPUtils.getIpAddr(request);
// Integer maxAccessCount = Integer.parseInt(commonInfoService.findOne(935).getValue());
// if (!IpAccessCounter.canAccess(requestIp, maxAccessCount)) {
// log.info("IpAccessCounter 一分钟内请求超过限制IP: {}, 最大访问次数: {}", requestIp, maxAccessCount);
// throw new LimitException("访问频率过高,请稍后再试");
// }
String params = new Gson().toJson(args);
// 执行被拦截的方法
Object result = pjp.proceed();
long end = System.currentTimeMillis();
String value = commonInfoService.findOne(933).getValue();
if ("1".equals(value)) {
String method = request.getMethod();
long useTime = end - start;
ThreadUtil.execAsync(() -> {
//请求的参数
// String resultJson = new Gson().toJson(result);
String resultJson = "1";
try {
if (StringUtils.isNotBlank(resultJson) && !"null".equals(resultJson)) {
log.info("\n>>>>>> {} {}" +
"\n>>>>>> IP: {} " +
"\n>>>>>> execute time:{}ms " +
"\n>>>>>> Request: {}" +
"\n>>>>>> Response: {}",
method, requestUrl, requestIp, useTime,
params,
resultJson
);
}
} catch (Exception e) {
log.error("Request 为空" + e.getMessage());
}
});
}
return result;
}
}

View File

@ -1,128 +0,0 @@
package com.sqx.common.aspect;
import com.sqx.common.annotation.Debounce;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.Result;
import com.sqx.common.utils.SpelUtil;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* 防抖切面
* @author ww
*/
@Aspect
@Component
public class DebounceAspect {
@Pointcut("@annotation(com.sqx.common.annotation.Debounce)")
public void logPointCut() {
}
// 用于存储基于方法和入参情况的上次执行时间结构为方法签名 -> (入参值 -> 上次执行时间)
private static final ConcurrentHashMap<String, ConcurrentHashMap<Object, Long>> executionTimeMap = new ConcurrentHashMap<>();
private static final ReentrantLock LOCK = new ReentrantLock();
@Around("logPointCut()")
public Object aroundDebounce(ProceedingJoinPoint joinPoint) throws Throwable {
cleanExpiredRecords();
String methodSignature = joinPoint.getSignature().toLongString();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Debounce annotation = signature.getMethod().getAnnotation(Debounce.class);
long interval = annotation.interval();
TimeUnit timeUnit = annotation.timeUnit();
String value = annotation.value();
if (StringUtils.isBlank(value)) {
// 没有指定入参表达式按照整个方法进行防抖
return debounceForWholeMethod(joinPoint, methodSignature, interval, timeUnit);
}
String[] split = value.split(",");
StringBuilder values = new StringBuilder();
for (String str : split) {
values.append(SpelUtil.generateKeyBySpEL(str, joinPoint));
}
// 解析入参表达式获取对应入参的值
if (StringUtils.isBlank(values.toString())) {
// 如果解析失败或值为null按照整个方法进行防抖
return debounceForWholeMethod(joinPoint, methodSignature, interval, timeUnit);
}
// 根据方法签名和入参值进行防抖判断
return debounceForSpecificValue(joinPoint, methodSignature, interval, timeUnit, values.toString());
}
private Object debounceForWholeMethod(ProceedingJoinPoint joinPoint, String methodSignature, long interval, TimeUnit timeUnit) throws Throwable {
ConcurrentHashMap<Object, Long> methodExecutionTimeMap = executionTimeMap.computeIfAbsent(methodSignature, k -> new ConcurrentHashMap<>());
long currentTime = System.currentTimeMillis();
Long lastTime = methodExecutionTimeMap.get(methodSignature);
if (lastTime == null) {
// 如果不存在对应键值对设置初始值这里设置为一个表示很久之前的时间戳比如0
lastTime = 0L;
}
if (lastTime == null || currentTime - timeUnit.toMillis(interval) >= lastTime) {
// 满足防抖间隔更新上次执行时间并执行目标方法
methodExecutionTimeMap.put(methodSignature, currentTime);
return joinPoint.proceed();
}
// 在防抖间隔内不执行目标方法直接返回
return Result.error("请求频繁,请重试");
}
private Object debounceForSpecificValue(ProceedingJoinPoint joinPoint, String methodSignature, long interval, TimeUnit timeUnit, Object targetValue) throws Throwable {
ConcurrentHashMap<Object, Long> methodExecutionTimeMap = executionTimeMap.computeIfAbsent(methodSignature, k -> new ConcurrentHashMap<>());
long currentTime = System.currentTimeMillis();
Long lastTime = methodExecutionTimeMap.get(targetValue);
if (lastTime == null || currentTime - timeUnit.toMillis(interval) >= lastTime) {
// 满足防抖间隔更新上次执行时间并执行目标方法
methodExecutionTimeMap.put(targetValue, currentTime);
try {
return joinPoint.proceed();
}catch (Exception e) {
if (e instanceof SqxException && ((SqxException) e).getCode() == 407) {
methodExecutionTimeMap.remove(targetValue);
}
throw e;
}
}
// 在防抖间隔内不执行目标方法直接返回
return Result.error("请求频繁,请重试");
}
public void cleanExpiredRecords() {
long expirationTime = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(10);
LOCK.lock();
try {
for (Entry<String, ConcurrentHashMap<Object, Long>> outerEntry : executionTimeMap.entrySet()) {
String methodSignature = outerEntry.getKey();
ConcurrentHashMap<Object, Long> innerMap = outerEntry.getValue();
ConcurrentHashMap<Object, Long> keysToRemove = new ConcurrentHashMap<>();
for (Entry<Object, Long> innerEntry : innerMap.entrySet()) {
if (innerEntry.getValue() < expirationTime) {
keysToRemove.put(innerEntry.getKey(), innerEntry.getValue());
}
}
innerMap.keySet().removeAll(keysToRemove.keySet());
if (innerMap.isEmpty()) {
executionTimeMap.remove(methodSignature);
}
}
} finally {
LOCK.unlock();
}
}
}

View File

@ -1,145 +0,0 @@
//package com.sqx.common.aspect;
//
//import lombok.extern.slf4j.Slf4j;
//
//import java.util.*;
//import java.util.concurrent.ConcurrentHashMap;
//import java.util.concurrent.Executors;
//import java.util.concurrent.ScheduledExecutorService;
//import java.util.concurrent.TimeUnit;
//import java.util.concurrent.atomic.AtomicInteger;
//
///**
// * @author GYJoker
// */
//@Slf4j
//public class IpAccessCounter {
// // 记录 IP 及其每次访问的时间列表
// private static final Map<String, List<Long>> IP_ACCESS_TIMES = new ConcurrentHashMap<>();
// // 黑名单记录 IP 及其加入黑名单的时间
// private static final Map<String, Long> BLACKLIST = new ConcurrentHashMap<>();
// // 一分钟的毫秒数
// private static final long ONE_MINUTE = 60 * 1000;
// // 十分钟的毫秒数
// private static final long TEN_MINUTES = 3 * 10 * ONE_MINUTE;
//
// private static AtomicInteger removeCount = new AtomicInteger(0);
//
//// static {
//// // 定时任务每分钟清理一次访问记录
//// ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
//// executor.scheduleAtFixedRate(() -> {
//// try {
//// long currentTime = System.currentTimeMillis();
//// Set<String> removedIps = new HashSet<>();
//// IP_ACCESS_TIMES.forEach((ip, accessTimes) -> {
//// accessTimes.removeIf(time -> currentTime - time > ONE_MINUTE);
//// if (accessTimes.isEmpty()) {
//// removedIps.add(ip);
//// }
//// });
//// removedIps.forEach(IP_ACCESS_TIMES::remove);
////
//// Set<String> removedBlacklistIps = new HashSet<>();
//// BLACKLIST.entrySet().removeIf(entry -> {
//// boolean shouldRemove = currentTime - entry.getValue() > TEN_MINUTES;
//// if (shouldRemove) {
//// removedBlacklistIps.add(entry.getKey());
//// }
//// return shouldRemove;
//// });
////
//// log.info("IpAccessCounter 清理完成,移除了 {} 个 IP 的黑名单记录,当前 BLACKLIST 大小: {}, IP_ACCESS_TIMES 大小: {}",
//// removedBlacklistIps.size(), BLACKLIST.size(), IP_ACCESS_TIMES.size());
//// } catch (Exception e) {
//// log.error("定时任务异常", e);
//// }
//// }, ONE_MINUTE, 20000, TimeUnit.MINUTES);
//// }
//
// public static void removeOldInfo() {
// synchronized (IpAccessCounter.class) {
// try {
// removeCount.set(0);
// long currentTime = System.currentTimeMillis();
// Set<String> removedIps = new HashSet<>();
//// for (Map.Entry<String, List<Long>> entry : IP_ACCESS_TIMES.entrySet()) {
//// List<Long> accessTimes = entry.getValue();
//// accessTimes.removeIf(time -> currentTime - time > ONE_MINUTE);
//// if (accessTimes.isEmpty()) {
//// removedIps.add(entry.getKey());
//// }
//// }
// IP_ACCESS_TIMES.forEach((ip, accessTimes) -> {
// if (accessTimes != null && !accessTimes.isEmpty()) {
// accessTimes.removeIf(time -> currentTime - time > ONE_MINUTE);
// if (accessTimes.isEmpty()) {
// removedIps.add(ip);
// }
// }
// });
// removedIps.forEach(IP_ACCESS_TIMES::remove);
//
// Set<String> removedBlacklistIps = new HashSet<>();
// BLACKLIST.entrySet().removeIf(entry -> {
// boolean shouldRemove = currentTime - entry.getValue() > TEN_MINUTES;
// if (shouldRemove) {
// removedBlacklistIps.add(entry.getKey());
// }
// return shouldRemove;
// });
//
// log.info("IpAccessCounter 清理完成,移除了 {} 个 IP 的黑名单记录,当前 BLACKLIST 大小: {}, IP_ACCESS_TIMES 大小: {}",
// removedBlacklistIps.size(), BLACKLIST.size(), IP_ACCESS_TIMES.size());
// } catch (Exception e) {
// log.error("定时任务异常", e);
// }
// }
// }
//
// // 检查 IP 是否可以访问
// public static boolean canAccess(String ip, Integer maxAccessCount) {
// removeCount.getAndIncrement();
// if (removeCount.get() > 400) {
// removeOldInfo();
// }
// if (isBlacklisted(ip)) {
// return false;
// }
// long currentTime = System.currentTimeMillis();
// List<Long> accessTimes = IP_ACCESS_TIMES.computeIfAbsent(ip, k -> new ArrayList<>());
// // 移除超过一分钟的访问时间记录
// if (accessTimes.size() + 1 > maxAccessCount) {
// addToBlacklist(ip);
// log.info("IP {} 因一分钟内访问次数超过 {} 次,被加入黑名单, BLACKLIST 大小: {}, IP_ACCESS_TIMES 大小: {}", ip, maxAccessCount, BLACKLIST.size(), IP_ACCESS_TIMES.size());
// return false;
// }
//
// accessTimes.add(currentTime);
// return true;
// }
//
// // 检查 IP 是否在黑名单中
// private static boolean isBlacklisted(String ip) {
// return BLACKLIST.containsKey(ip) && System.currentTimeMillis() - BLACKLIST.get(ip) <= TEN_MINUTES;
// }
//
// // IP 加入黑名单
// private static void addToBlacklist(String ip) {
// BLACKLIST.put(ip, System.currentTimeMillis());
// IP_ACCESS_TIMES.remove(ip);
// }
//
// public static void main(String[] args) throws InterruptedException {
// String testIp = "192.168.1.1";
// for (int i = 0; i < 150; i++) {
// System.out.println("Attempt " + (i + 1) + ": " + (canAccess(testIp, 120) ? "Allowed" : "Blocked"));
// }
//
// Thread.sleep(60 * 1000);
//
// for (int i = 0; i < 150; i++) {
// System.out.println("Attempt " + (i + 1) + ": " + (canAccess(testIp, 120) ? "Allowed" : "Blocked"));
// }
// }
//}

View File

@ -1,70 +0,0 @@
package com.sqx.common.aspect;
import com.google.common.util.concurrent.RateLimiter;
import com.sqx.common.annotation.Limiting;
import com.sqx.common.exception.LimitException;
import com.sqx.common.utils.IPUtils;
import com.sqx.modules.common.service.CommonInfoService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author GYJoker
*/
@Aspect
@Component
@Slf4j
public class RateLimitAspect {
@Autowired
private CommonInfoService commonInfoService;
private ConcurrentHashMap<String, RateLimiter> RATE_LIMITER = new ConcurrentHashMap<>();
private RateLimiter rateLimiter;
@Pointcut("@annotation(com.sqx.common.annotation.Limiting)")
public void serviceLimit() {
}
@Around("serviceLimit()")
public Object around(ProceedingJoinPoint point) throws Throwable {
// 成功获取许可继续执行方法
return point.proceed();
//// 获取当前请求
//ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//HttpServletRequest request = attributes.getRequest();
//// 获取请求的 IP 地址
//String ip = IPUtils.getIpAddr(request);
//
//// 获取方法上的 @AccessLimit 注解
//MethodSignature signature = (MethodSignature) point.getSignature();
//Method method = signature.getMethod();
//Limiting accessLimit = method.getAnnotation(Limiting.class);
//double permitsPerSecond = accessLimit.limitNum();
//
//// 获取或创建该 IP 对应的 RateLimiter
//RateLimiter rateLimiter = RATE_LIMITER.computeIfAbsent(ip, k -> RateLimiter.create(permitsPerSecond));
//
//// 尝试获取许可
//if (rateLimiter.tryAcquire()) {
// // 成功获取许可继续执行方法
// return point.proceed();
//} else {
// // 未获取到许可抛出异常或返回错误信息
// log.info("IP: {} 请求方法: {} 超过访问频率限制", ip, method.getName());
// throw new LimitException("访问频率过高,请稍后再试");
//}
}
}

View File

@ -1,10 +0,0 @@
package com.sqx.common.exception;
/**
* @author GYJoker
*/
public class CzgException extends Exception {
public CzgException(String message) {
super(message);
}
}

View File

@ -1,10 +0,0 @@
package com.sqx.common.exception;
/**
* @author GYJoker
*/
public class LimitException extends RuntimeException {
public LimitException(String message) {
super(message);
}
}

View File

@ -5,8 +5,6 @@ import org.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@ -14,8 +12,6 @@ import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.NoHandlerFoundException;
import java.io.IOException;
/**
* 异常处理器
*
@ -37,15 +33,6 @@ public class SqxExceptionHandler {
return r;
}
@ExceptionHandler(UserException.class)
public Result handleUserException(UserException e) {
Result r = new Result();
r.put("code", e.getCode());
r.put("msg", e.getMessage());
return r;
}
@ExceptionHandler(NoHandlerFoundException.class)
public Result handlerNoFoundException(Exception e, WebRequest webRequest) {
logErrorInfo(webRequest);
@ -78,27 +65,9 @@ public class SqxExceptionHandler {
public Result handleException(Exception e, WebRequest webRequest) {
logErrorInfo(webRequest);
logger.error(e.getMessage(), e);
e.printStackTrace();
return Result.error();
}
@ExceptionHandler(CzgException.class)
public ResponseEntity<Void> handleCzgException() {
// 响应状态码为 444 表示无法处理的异常
return new ResponseEntity<>(HttpStatus.TOO_MANY_REQUESTS);
}
@ExceptionHandler(LimitException.class)
public ResponseEntity<Void> handleLimitException() {
// 响应状态码为 444 表示无法处理的异常
return new ResponseEntity<>(HttpStatus.LOCKED);
}
@ExceptionHandler(IOException.class)
public Result handleIoException() {
return Result.error("请求中断,请重试");
}
private void logErrorInfo(WebRequest webRequest) {
if (webRequest instanceof ServletWebRequest) {
ServletWebRequest servletWebRequest = (ServletWebRequest) webRequest;

View File

@ -1,52 +0,0 @@
package com.sqx.common.exception;
/**
* 自定义异常
*
*/
public class UserException extends RuntimeException {
private static final long serialVersionUID = 1L;
private String msg;
private int code = 701;
public UserException(String msg) {
super(msg);
this.msg = msg;
}
public UserException(String msg, Throwable e) {
super(msg, e);
this.msg = msg;
}
public UserException(String msg, int code) {
super(msg);
this.msg = msg;
this.code = code;
}
public UserException(String msg, int code, Throwable e) {
super(msg, e);
this.msg = msg;
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}

View File

@ -1,233 +0,0 @@
package com.sqx.common.utils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.UUID;
import java.util.function.Supplier;
/**
* 接口访问次数 月为单位
*/
@Component
@Slf4j
public class ApiAccessLimitUtil {
private static final String ACCESS_COUNT_KEY_PREFIX = "sys:limit:";
private static RedisUtils redisUtils;
private static final int DEFAULT_ACCESS_COUNT = 5;
private static final String DATE_TIME_FORMAT = "month";
@Autowired
public void setRedisUtils(RedisUtils redisUtils) {
ApiAccessLimitUtil.redisUtils = redisUtils;
}
/**
* 默认 当月5次
*
* @param id 唯一值
* @param key 接口名称 sys:limit:接口名称
* @return
*/
public static boolean isAccessAllowed(String id, String key) {
String redisKey = generateRedisKey(key, id);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(DATE_TIME_FORMAT);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if ((int) countObj < DEFAULT_ACCESS_COUNT) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
/**
* 默认月 month//自然月
*
* @param id 唯一值
* @param key 接口名称 sys:limit:接口名称
* @param count 次数限制
* @return
*/
public static boolean isAccessAllowed(String id, String key, Integer count) {
String redisKey = generateRedisKey(key, id);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(DATE_TIME_FORMAT);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if ((int) countObj < count) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
/**
* 默认 5次
*
* @param id 唯一值
* @param key 接口名称 sys:limit:接口名称
* @param timeFormat day//自然天 week//本周日 month//自然月 year//自然年
* @return
*/
public static boolean isAccessAllowed(String id, String key, String timeFormat) {
String redisKey = generateRedisKey(key, id);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(timeFormat);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if ((int) countObj < DEFAULT_ACCESS_COUNT) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
/**
* @param id 唯一值
* @param key 接口名称 sys:limit:接口名称
* @param count 次数限制
* @param timeFormat day//自然天 week//本周日 month//自然月 year//自然年
* @return
*/
public static boolean isAccessAllowed(String id, String key, Integer count, String timeFormat) {
String redisKey = generateRedisKey(key, id);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
long expireAt;
if (StrUtil.isBlank(timeFormat)) {
expireAt = count;
} else {
// 根据不同时间周期设置过期时间并初始化访问次数为1
expireAt = calculateExpireAt(timeFormat);
}
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if (Integer.parseInt(countObj.toString()) < count) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
public static boolean getCertAuthIsAccessAllowed(String id, String key, Integer count) {
String redisKey = "app:updateLimit:auth:" + key + ":" + id;
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
return true;
}
return Integer.parseInt(countObj.toString()) < count;
}
public static void setCertAuthIsAccessAllowed(String id, String key, Integer count, String timeFormat) {
String redisKey = "app:updateLimit:auth:" + key + ":" + id;
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
long expireAt;
if (StrUtil.isBlank(timeFormat)) {
expireAt = count;
} else {
// 根据不同时间周期设置过期时间并初始化访问次数为1
expireAt = calculateExpireAt(timeFormat);
}
redisUtils.set(redisKey, 1, expireAt);
} else {
redisUtils.incr(redisKey);
}
}
public static void removeKey(String id, String key) {
String redisKey = generateRedisKey(key, id);
redisUtils.delete(redisKey);
}
public static <T> T runFunAndCheckKey(Supplier<T> supplier, String lockKey, Integer seconds) {
try {
// 创建线程id, 用作判断
String clientId = UUID.randomUUID().toString();
// 设置分布式锁
boolean lock = Boolean.TRUE.equals(redisUtils.setIfAbsent(lockKey, clientId, seconds));
int count = 0;
while (!lock) {
if (count++ > 1000) {
throw new RuntimeException("系统繁忙, 稍后再试");
}
Thread.sleep(20);
lock = Boolean.TRUE.equals(redisUtils.setIfAbsent(lockKey, clientId, seconds));
}
return supplier.get();
} catch (RuntimeException e) {
log.error("执行出错", e);
throw e;
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
redisUtils.delete(lockKey);
}
}
public static boolean isAccessAllowed(String id, String key, Integer count, Integer seconds) {
String redisKey = generateRedisKey(key, id);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
redisUtils.set(redisKey, 1, seconds);
return true;
}
if (Integer.parseInt(countObj.toString()) < count) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
private static String generateRedisKey(String key, String id) {
return ACCESS_COUNT_KEY_PREFIX + key + ":" + id;
}
private static long calculateExpireAt(String timePeriod) {
Date now = DateUtil.beginOfDay(DateUtil.date());
Date expireDate = null;
if ("day".equals(timePeriod)) {
expireDate = DateUtil.endOfDay(now);
} else if ("week".equals(timePeriod)) {
expireDate = DateUtil.endOfWeek(now);
} else if ("month".equals(timePeriod)) {
expireDate = DateUtil.endOfMonth(now);
} else if ("year".equals(timePeriod)) {
expireDate = DateUtil.endOfYear(now);
}
long endTimeStamp = DateUtil.endOfDay(expireDate).getTime() / 1000L;
long currentTimeStamp = DateUtil.currentSeconds();
return endTimeStamp - currentTimeStamp;
}
}

View File

@ -1,154 +0,0 @@
package com.sqx.common.utils;
import cn.hutool.core.date.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 数据出现次数
*/
@Component
public class DataLimitUtil {
private static final String ACCESS_COUNT_KEY_PREFIX = "sys:data:";
private static RedisUtils redisUtils;
private static final int DEFAULT_ACCESS_COUNT = 5;
private static final String DATE_TIME_FORMAT = "month";
@Autowired
public void setRedisUtils(RedisUtils redisUtils) {
DataLimitUtil.redisUtils = redisUtils;
}
/**
* 默认 当月5次
*
* @param key 名称 sys:data:名称
* @return
*/
public static boolean isAccessAllowed(String key) {
String redisKey = generateRedisKey(key);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(DATE_TIME_FORMAT);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if ((int) countObj < DEFAULT_ACCESS_COUNT) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
/**
* 默认月 month//自然月
*
* @param key 名称 sys:data:名称
* @param count 次数限制
* @return
*/
public static boolean isAccessAllowed(String key, Integer count) {
String redisKey = generateRedisKey(key);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(DATE_TIME_FORMAT);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if ((int) countObj < count) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
/**
* 默认 5次
*
* @param key 名称 sys:data:名称
* @param timeFormat day//自然天 week//本周日 month//自然月 year//自然年
* @return
*/
public static boolean isAccessAllowed(String key, String timeFormat) {
String redisKey = generateRedisKey(key);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(timeFormat);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if ((int) countObj < DEFAULT_ACCESS_COUNT) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
public static boolean isAllowed(String key, int seconds) {
String redisKey = generateRedisKey(key);
if (!redisUtils.hasKey(key)) {
redisUtils.set(redisKey, 1, seconds);
return true;
}
return false;
}
/**
* @param key 名称 sys:data:名称
* @param count 次数限制
* @param timeFormat day//自然天 week//本周日 month//自然月 year//自然年
* @return
*/
public static boolean isAccessAllowed(String key, Integer count, String timeFormat) {
String redisKey = generateRedisKey(key);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(timeFormat);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if (Integer.parseInt(countObj.toString()) < count) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
private static String generateRedisKey(String key) {
return ACCESS_COUNT_KEY_PREFIX + key;
}
private static long calculateExpireAt(String timePeriod) {
Date now = DateUtil.beginOfDay(DateUtil.date());
Date expireDate = null;
if ("day".equals(timePeriod)) {
expireDate = DateUtil.endOfDay(now);
} else if ("week".equals(timePeriod)) {
expireDate = DateUtil.endOfWeek(now);
} else if ("month".equals(timePeriod)) {
expireDate = DateUtil.endOfMonth(now);
} else if ("year".equals(timePeriod)) {
expireDate = DateUtil.endOfYear(now);
}
long endTimeStamp = DateUtil.endOfDay(expireDate).getTime() / 1000L;
long currentTimeStamp = DateUtil.currentSeconds();
return endTimeStamp - currentTimeStamp;
}
}

View File

@ -1,6 +1,5 @@
package com.sqx.common.utils;
import cn.hutool.core.date.DateUtil;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
@ -160,17 +159,4 @@ public class DateUtils {
DateTime dateTime = new DateTime(date);
return dateTime.plusYears(years).toDate();
}
//获取当日剩余秒数
public static long todayAfterSecond() {
Date now = new Date();
// 获取当天结束时间即当天23:59:59对应的Date对象
Date endOfDay = DateUtil.endOfDay(now);
// 计算时间差单位为毫秒
long diffMillis = endOfDay.getTime() - now.getTime();
// 将毫秒转换为秒
long diffSeconds = diffMillis / 1000;
return diffSeconds;
}
}

View File

@ -1,364 +0,0 @@
package com.sqx.common.utils;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.StrUtil;
/**
* 脱敏工具类支持以下类型信息的脱敏自动处理
*
* <ul>
* <li>用户ID</li>
* <li>中文名</li>
* <li>身份证</li>
* <li>座机号</li>
* <li>手机号</li>
* <li>地址</li>
* <li>电子邮件</li>
* <li>密码</li>
* <li>车牌</li>
* <li>银行卡号</li>
* </ul>
*
* @author dazer and neusoft and qiaomu
* @since 5.6.2
*/
public class DesensitizedUtil {
/**
* 支持的脱敏类型枚举
*
* @author dazer and neusoft and qiaomu
*/
public enum DesensitizedType {
/**
* 用户id
*/
USER_ID,
/**
* 中文名
*/
CHINESE_NAME,
/**
* 身份证号
*/
ID_CARD,
/**
* 座机号
*/
FIXED_PHONE,
/**
* 手机号
*/
MOBILE_PHONE,
/**
* 地址
*/
ADDRESS,
/**
* 电子邮件
*/
EMAIL,
/**
* 密码
*/
PASSWORD,
/**
* 中国大陆车牌包含普通车辆新能源车辆
*/
CAR_LICENSE,
/**
* 银行卡
*/
BANK_CARD,
/**
* IPv4地址
*/
IPV4,
/**
* IPv6地址
*/
IPV6,
/**
* 定义了一个first_mask的规则只显示第一个字符
*/
FIRST_MASK
}
/**
* 脱敏使用默认的脱敏策略
* <pre>
* DesensitizedUtil.desensitized("100", DesensitizedUtil.DesensitizedType.USER_ID)) = "0"
* DesensitizedUtil.desensitized("段正淳", DesensitizedUtil.DesensitizedType.CHINESE_NAME)) = "段**"
* DesensitizedUtil.desensitized("51343620000320711X", DesensitizedUtil.DesensitizedType.ID_CARD)) = "5***************1X"
* DesensitizedUtil.desensitized("09157518479", DesensitizedUtil.DesensitizedType.FIXED_PHONE)) = "0915*****79"
* DesensitizedUtil.desensitized("18049531999", DesensitizedUtil.DesensitizedType.MOBILE_PHONE)) = "180****1999"
* DesensitizedUtil.desensitized("北京市海淀区马连洼街道289号", DesensitizedUtil.DesensitizedType.ADDRESS)) = "北京市海淀区马********"
* DesensitizedUtil.desensitized("duandazhi-jack@gmail.com.cn", DesensitizedUtil.DesensitizedType.EMAIL)) = "d*************@gmail.com.cn"
* DesensitizedUtil.desensitized("1234567890", DesensitizedUtil.DesensitizedType.PASSWORD)) = "**********"
* DesensitizedUtil.desensitized("苏D40000", DesensitizedUtil.DesensitizedType.CAR_LICENSE)) = "苏D4***0"
* DesensitizedUtil.desensitized("11011111222233333256", DesensitizedUtil.DesensitizedType.BANK_CARD)) = "1101 **** **** **** 3256"
* DesensitizedUtil.desensitized("192.168.1.1", DesensitizedUtil.DesensitizedType.IPV4)) = "192.*.*.*"
* </pre>
*
* @param str 字符串
* @param desensitizedType 脱敏类型;可以脱敏用户id中文名身份证号座机号手机号地址电子邮件密码
* @return 脱敏之后的字符串
* @author dazer and neusoft and qiaomu
* @since 5.6.2
*/
public static String desensitized(CharSequence str, DesensitizedUtil.DesensitizedType desensitizedType) {
if (StrUtil.isBlank(str)) {
return StrUtil.EMPTY;
}
String newStr = String.valueOf(str);
switch (desensitizedType) {
case USER_ID:
newStr = String.valueOf(userId());
break;
case CHINESE_NAME:
newStr = chineseName(String.valueOf(str));
break;
case ID_CARD:
newStr = idCardNum(String.valueOf(str), 1, 2);
break;
case FIXED_PHONE:
newStr = fixedPhone(String.valueOf(str));
break;
case MOBILE_PHONE:
newStr = mobilePhone(String.valueOf(str));
break;
case ADDRESS:
newStr = address(String.valueOf(str), 8);
break;
case EMAIL:
newStr = email(String.valueOf(str));
break;
case PASSWORD:
newStr = password(String.valueOf(str));
break;
case CAR_LICENSE:
newStr = carLicense(String.valueOf(str));
break;
case BANK_CARD:
newStr = bankCard(String.valueOf(str));
break;
case IPV4:
newStr = ipv4(String.valueOf(str));
break;
case IPV6:
newStr = ipv6(String.valueOf(str));
break;
case FIRST_MASK:
newStr = firstMask(String.valueOf(str));
break;
default:
}
return newStr;
}
/**
* 用户id不对外提供userId
*
* @return 脱敏后的主键
*/
public static Long userId() {
return 0L;
}
/**
* 定义了一个first_mask的规则只显示第一个字符<br>
* 脱敏前123456789脱敏后1********
*
* @param str 字符串
* @return 脱敏后的字符串
*/
public static String firstMask(String str) {
if (StrUtil.isBlank(str)) {
return StrUtil.EMPTY;
}
return StrUtil.hide(str, 1, str.length());
}
/**
* 中文姓名只显示第一个汉字其他隐藏为2个星号比如**
*
* @param fullName 姓名
* @return 脱敏后的姓名
*/
public static String chineseName(String fullName) {
return firstMask(fullName);
}
/**
* 身份证号前1位 和后2位
*
* @param idCardNum 身份证
* @param front 保留前面的front位数从1开始
* @param end 保留后面的end位数从1开始
* @return 脱敏后的身份证
*/
public static String idCardNum(String idCardNum, int front, int end) {
//身份证不能为空
if (StrUtil.isBlank(idCardNum)) {
return StrUtil.EMPTY;
}
//需要截取的长度不能大于身份证号长度
if ((front + end) > idCardNum.length()) {
return StrUtil.EMPTY;
}
//需要截取的不能小于0
if (front < 0 || end < 0) {
return StrUtil.EMPTY;
}
return StrUtil.hide(idCardNum, front, idCardNum.length() - end);
}
/**
* 固定电话 前四位后两位
*
* @param num 固定电话
* @return 脱敏后的固定电话
*/
public static String fixedPhone(String num) {
if (StrUtil.isBlank(num)) {
return StrUtil.EMPTY;
}
return StrUtil.hide(num, 4, num.length() - 2);
}
/**
* 手机号码前三位后4位其他隐藏比如135****2210
*
* @param num 移动电话
* @return 脱敏后的移动电话
*/
public static String mobilePhone(String num) {
if (StrUtil.isBlank(num)) {
return StrUtil.EMPTY;
}
return StrUtil.hide(num, 3, num.length() - 4);
}
/**
* 地址只显示到地区不显示详细地址比如北京市海淀区****
*
* @param address 家庭住址
* @param sensitiveSize 敏感信息长度
* @return 脱敏后的家庭地址
*/
public static String address(String address, int sensitiveSize) {
if (StrUtil.isBlank(address)) {
return StrUtil.EMPTY;
}
int length = address.length();
return StrUtil.hide(address, length - sensitiveSize, length);
}
/**
* 电子邮箱邮箱前缀仅显示第一个字母前缀其他隐藏用星号代替@及后面的地址显示比如d**@126.com
*
* @param email 邮箱
* @return 脱敏后的邮箱
*/
public static String email(String email) {
if (StrUtil.isBlank(email)) {
return StrUtil.EMPTY;
}
int index = StrUtil.indexOf(email, '@');
if (index <= 1) {
return email;
}
return StrUtil.hide(email, 1, index);
}
/**
* 密码密码的全部字符都用*代替比如******
*
* @param password 密码
* @return 脱敏后的密码
*/
public static String password(String password) {
if (StrUtil.isBlank(password)) {
return StrUtil.EMPTY;
}
return StrUtil.repeat('*', password.length());
}
/**
* 中国车牌车牌中间用*代替
* eg1null - ""
* eg1"" - ""
* eg3苏D40000 - 苏D4***0
* eg4陕A12345D - 陕A1****D
* eg5京A123 - 京A123 如果是错误的车牌不处理
*
* @param carLicense 完整的车牌号
* @return 脱敏后的车牌
*/
public static String carLicense(String carLicense) {
if (StrUtil.isBlank(carLicense)) {
return StrUtil.EMPTY;
}
// 普通车牌
if (carLicense.length() == 7) {
carLicense = StrUtil.hide(carLicense, 3, 6);
} else if (carLicense.length() == 8) {
// 新能源车牌
carLicense = StrUtil.hide(carLicense, 3, 7);
}
return carLicense;
}
/**
* 银行卡号脱敏
* eg: 1101 **** **** **** 3256
*
* @param bankCardNo 银行卡号
* @return 脱敏之后的银行卡号
* @since 5.6.3
*/
public static String bankCard(String bankCardNo) {
if (StrUtil.isBlank(bankCardNo)) {
return bankCardNo;
}
bankCardNo = StrUtil.trim(bankCardNo);
if (bankCardNo.length() < 9) {
return bankCardNo;
}
final int length = bankCardNo.length();
final int midLength = length - 8;
final StringBuilder buf = new StringBuilder();
buf.append(bankCardNo, 0, 4);
for (int i = 0; i < midLength; ++i) {
if (i % 4 == 0) {
buf.append(CharUtil.SPACE);
}
buf.append('*');
}
buf.append(CharUtil.SPACE).append(bankCardNo, length - 4, length);
return buf.toString();
}
/**
* IPv4脱敏脱敏前192.0.2.1脱敏后192.*.*.*
*
* @param ipv4 IPv4地址
* @return 脱敏后的地址
*/
public static String ipv4(String ipv4) {
return StrUtil.subBefore(ipv4, '.', false) + ".*.*.*";
}
/**
* IPv4脱敏脱敏前2001:0db8:86a3:08d3:1319:8a2e:0370:7344脱敏后2001:*:*:*:*:*:*:*
*
* @param ipv6 IPv4地址
* @return 脱敏后的地址
*/
public static String ipv6(String ipv6) {
return StrUtil.subBefore(ipv6, ':', false) + ":*:*:*:*:*:*:*";
}
}

View File

@ -1,6 +1,6 @@
package com.sqx.common.utils;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.druid.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -1,120 +1,101 @@
package com.sqx.common.utils;
import com.github.pagehelper.PageInfo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.io.Serializable;
import java.util.List;
/**
* 分页工具类
*
*/
public class PageUtils implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 总记录数
*/
private int totalCount;
/**
* 每页记录数
*/
private int pageSize;
/**
* 总页数
*/
private int totalPage;
/**
* 当前页数
*/
private int currPage;
/**
* 列表数据
*/
private List<?> list;
private List<?> records;
private static final long serialVersionUID = 1L;
/**
* 总记录数
*/
private int totalCount;
/**
* 每页记录数
*/
private int pageSize;
/**
* 总页数
*/
private int totalPage;
/**
* 当前页数
*/
private int currPage;
/**
* 列表数据
*/
private List<?> list;
/**
* 分页
* @param list 列表数据
* @param totalCount 总记录数
* @param pageSize 每页记录数
* @param currPage 当前页数
*/
public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {
this.list = list;
this.totalCount = totalCount;
this.pageSize = pageSize;
this.currPage = currPage;
this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
}
/**
* 分页
*/
public PageUtils(IPage<?> page) {
this.list = page.getRecords();
this.totalCount = (int)page.getTotal();
this.pageSize = (int)page.getSize();
this.currPage = (int)page.getCurrent();
this.totalPage = (int)page.getPages();
}
public PageUtils() {
}
public int getTotalCount() {
return totalCount;
}
/**
* 分页
*
* @param list 列表数据
* @param totalCount 总记录数
* @param pageSize 每页记录数
* @param currPage 当前页数
*/
public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {
this.list = list;
this.totalCount = totalCount;
this.pageSize = pageSize;
this.currPage = currPage;
this.totalPage = (int) Math.ceil((double) totalCount / pageSize);
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public static PageUtils page(PageInfo<?> page) {
return page(page,false);
}
public int getPageSize() {
return pageSize;
}
public static PageUtils page(PageInfo<?> page, boolean isRecords) {
PageUtils pageUtils = new PageUtils();
if (isRecords) {
pageUtils.records = page.getList();
} else {
pageUtils.list = page.getList();
}
pageUtils.totalCount = (int) page.getTotal();
pageUtils.pageSize = page.getSize();
pageUtils.currPage = page.getPageNum();
pageUtils.totalPage = page.getPages();
return pageUtils;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalCount() {
return totalCount;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getPageSize() {
return pageSize;
}
public int getCurrPage() {
return currPage;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public void setCurrPage(int currPage) {
this.currPage = currPage;
}
public int getTotalPage() {
return totalPage;
}
public List<?> getList() {
return list;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getCurrPage() {
return currPage;
}
public void setCurrPage(int currPage) {
this.currPage = currPage;
}
public List<?> getList() {
return list;
}
public void setList(List<?> list) {
this.list = list;
}
public List<?> getRecords() {
return records;
}
public void setRecords(List<?> records) {
this.records = records;
}
public void setList(List<?> list) {
this.list = list;
}
}

View File

@ -0,0 +1,68 @@
package com.sqx.common.utils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.common.xss.SQLFilter;
import org.apache.commons.lang.StringUtils;
import java.util.Map;
/**
* 查询参数
*
*/
public class Query<T> {
public IPage<T> getPage(Map<String, Object> params) {
return this.getPage(params, null, false);
}
public IPage<T> getPage(Map<String, Object> params, String defaultOrderField, boolean isAsc) {
//分页参数
long curPage = 1;
long limit = 10;
if(params.get(Constant.PAGE) != null){
curPage = Long.parseLong(String.valueOf(params.get(Constant.PAGE)));
}
if(params.get(Constant.LIMIT) != null){
limit = Long.parseLong(String.valueOf(params.get(Constant.LIMIT)));
}
//分页对象
Page<T> page = new Page<>(curPage, limit);
//分页参数
params.put(Constant.PAGE, page);
//排序字段
//防止SQL注入因为sidxorder是通过拼接SQL实现排序的会有SQL注入风险
String orderField = SQLFilter.sqlInject((String)params.get(Constant.ORDER_FIELD));
String order = (String)params.get(Constant.ORDER);
//前端字段排序
if(StringUtils.isNotEmpty(orderField) && StringUtils.isNotEmpty(order)){
if(Constant.ASC.equalsIgnoreCase(order)) {
return page.addOrder(OrderItem.asc(orderField));
}else {
return page.addOrder(OrderItem.desc(orderField));
}
}
//没有排序字段则不排序
if(StringUtils.isBlank(defaultOrderField)){
return page;
}
//默认排序
if(isAsc) {
page.addOrder(OrderItem.asc(defaultOrderField));
}else {
page.addOrder(OrderItem.desc(defaultOrderField));
}
return page;
}
}

View File

@ -1,54 +1,12 @@
package com.sqx.common.utils;
import cn.hutool.core.date.DateUtil;
/**
* Redis所有Keys
*
*/
public class RedisKeys {
public static final String FREE_WATCH_KEY = "free:watch:";
public static final String LOCK_KEY = "SYS:LOCK:";
public static final String RATE_LIMIT = "RATE:z";
public static String getSysConfigKey(String key){
return "sys:config:" + key;
}
public static String getDateKey(String key){
return "date:" + key;
}
public static String getFreeWatchKey(Long userId, boolean isPermanently) {
if (isPermanently) {
return FREE_WATCH_KEY + userId;
}
return FREE_WATCH_KEY + DateUtil.today() + ":" + userId;
}
public static void main(String[] args) {
System.out.println(DateUtil.today());
}
public static String getLockKey(String sign, Object... args) {
StringBuilder key = new StringBuilder(LOCK_KEY + ":" + sign + ":");
for (Object arg : args) {
if (arg != null) {
key.append(":").append(arg);
}
}
return key.toString();
}
public static String getUserIpRateKey(long userId, String ip) {
return RATE_LIMIT + "user:" + userId + ":ip:" + ip;
}
public static String getUserUrlRateKey(long userId, String url) {
return RATE_LIMIT + "user:" + userId + ":url:" + url;
}
}

View File

@ -1,29 +1,18 @@
package com.sqx.common.utils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.sqx.modules.redisService.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* Redis工具类
*
*/
@Component
public class RedisUtils {
@Autowired
private RedisService redisService;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
@ -36,169 +25,38 @@ public class RedisUtils {
private SetOperations<String, Object> setOperations;
@Autowired
private ZSetOperations<String, Object> zSetOperations;
/**
* 默认过期时长单位
*/
/** 默认过期时长,单位:秒 */
public final static long DEFAULT_EXPIRE = 60 * 60 * 24;
/**
* 不设置过期时长
*/
/** 不设置过期时长 */
public final static long NOT_EXPIRE = -1;
private final static Gson Gson = new Gson();
public <T> Map<String, List<T>> getMapData(String key, String method, Class<T> clazz) {
String jsonStr = getDate(key, method);
ObjectMapper objectMapper = new ObjectMapper();
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) {
String jsonStr = getDate(key, method);
ObjectMapper objectMapper = new ObjectMapper();
try {
// 将JSON字符串转换为List<T>
return objectMapper.readValue(jsonStr, objectMapper.getTypeFactory().constructCollectionType(List.class, clazz));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取缓存里的数据 如果不存在 则插入 并返回
*
* @param key redis Key
* @param clazz 返回类型
* @param method RedisService调用的方法名 如果数据不存在会执行该调用方法
*/
public <T> T getObjectDate(String key, Class<T> clazz, String method) {
String jsonStr = getDate(key, method);
return this.fromJson(jsonStr, clazz);
}
public <T> T getObjectDate(String key, Class<T> clazz) {
String jsonStr = get(key);
return this.fromJson(jsonStr, clazz);
}
public String getDate(String key, String method) {
if (!this.hasKey(key)) {
try {
// 获取Lookup对象
MethodHandles.Lookup lookup = MethodHandles.lookup();
// 构建方法类型这里假设方法无参数返回类型为void
MethodType methodType = MethodType.methodType(void.class, String.class);
// 获取方法句柄
MethodHandle methodHandle = lookup.findVirtual(redisService.getClass(), method, methodType);
// 调用方法句柄
methodHandle.invoke(redisService, key);
} catch (Exception e) {
e.printStackTrace();
return null;
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
return this.get(key);
}
public boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
public void set(String key, Object value, long expire) {
public void set(String key, Object value, long expire){
valueOperations.set(key, toJson(value));
if (expire != NOT_EXPIRE) {
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){
set(key, value, DEFAULT_EXPIRE);
}
public void expire(String key, long seconds){
redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
}
public <T> T get(String key, Class<T> clazz, long expire) {
String value = valueOperations.get(key);
if (expire != NOT_EXPIRE) {
if(expire != NOT_EXPIRE){
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
return value == null ? null : fromJson(value, clazz);
}
// 判断键是否设置了过期时间
public boolean isExpiredSet(String key) {
// 获取过期时间单位是秒
Long expireTime = redisTemplate.getExpire(key);
if (expireTime == null) {
return false; // 如果返回 null表示键不存在
}
return expireTime != -1; // 如果是 -1说明没有设置过期时间
}
public Long getExpire(String key) {
Long currentExpireTime = redisTemplate.getExpire(key);
if (currentExpireTime == null || currentExpireTime == -2 || currentExpireTime == -1) {
return null;
}
return currentExpireTime;
}
// 累加过期时间
public boolean extendExpireTime(String key, long additionalTimeInSeconds) {
// 获取当前键的剩余过期时间单位
Long currentExpireTime = redisTemplate.getExpire(key);
if (currentExpireTime == null || currentExpireTime == -2) {
// 键不存在或已经过期无法进行累加
return false;
}
if (currentExpireTime == -1) {
redisTemplate.expire(key, additionalTimeInSeconds, java.util.concurrent.TimeUnit.SECONDS);
}
// 累加剩余过期时间和新增时间
long newExpireTime = currentExpireTime + additionalTimeInSeconds;
// 设置新的过期时间
return Boolean.TRUE.equals(redisTemplate.expire(key, newExpireTime, TimeUnit.SECONDS));
}
public <T> T get(String key, Class<T> clazz) {
return get(key, clazz, NOT_EXPIRE);
}
public String get(String key, long expire) {
String value = valueOperations.get(key);
if (expire != NOT_EXPIRE) {
if(expire != NOT_EXPIRE){
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
return value;
@ -208,21 +66,6 @@ public class RedisUtils {
return get(key, NOT_EXPIRE);
}
/**
* 对指定的键执行自增操作返回自增后的值
*
* @param key 要自增的键
* @return 自增后的值如果键不存在则初始化为1后返回1如果出现异常返回null
*/
public Long incr(String key) {
try {
return redisTemplate.opsForValue().increment(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public void delete(String key) {
redisTemplate.delete(key);
}
@ -230,9 +73,9 @@ public class RedisUtils {
/**
* Object转成JSON数据
*/
private String toJson(Object object) {
if (object instanceof Integer || object instanceof Long || object instanceof Float ||
object instanceof Double || object instanceof Boolean || object instanceof String) {
private String toJson(Object object){
if(object instanceof Integer || object instanceof Long || object instanceof Float ||
object instanceof Double || object instanceof Boolean || object instanceof String){
return String.valueOf(object);
}
return Gson.toJson(object);
@ -241,25 +84,7 @@ public class RedisUtils {
/**
* JSON数据转成Object
*/
private <T> T fromJson(String json, Class<T> clazz) {
private <T> T fromJson(String json, Class<T> 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

@ -1,55 +0,0 @@
package com.sqx.common.utils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.lang.reflect.Method;
/**
* @author ww
*/
public class SpelUtil {
/**
* 用于SpEL表达式解析.
*/
private static final SpelExpressionParser parser = new SpelExpressionParser();
/**
* 用于获取方法参数定义名字.
*/
private static final DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
/**
* 解析SpEL表达式
*
* @param spELStr
* @param joinPoint
* @return
*/
public static String generateKeyBySpEL(String spELStr, ProceedingJoinPoint joinPoint) {
// 通过joinPoint获取被注解方法
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
// 使用Spring的DefaultParameterNameDiscoverer获取方法形参名数组
String[] paramNames = nameDiscoverer.getParameterNames(method);
// // 解析过后的Spring表达式对象
Expression expression = parser.parseExpression(spELStr);
// Spring的表达式上下文对象
EvaluationContext context = new StandardEvaluationContext();
// 通过joinPoint获取被注解方法的形参
Object[] args = joinPoint.getArgs();
// 给上下文赋值
for (int i = 0; i < args.length; i++) {
context.setVariable(paramNames[i], args[i]);
}
if(expression.getValue(context)==null){
return "";
}
return expression.getValue(context).toString();
}
}

View File

@ -23,11 +23,6 @@ public class SpringContextUtils implements ApplicationContextAware {
return applicationContext.getBean(name);
}
public static Object getSpringBean(Class<?> clazz) {
return applicationContext == null ? null : applicationContext.getBean(clazz);
}
public static <T> T getBean(String name, Class<T> requiredType) {
return applicationContext.getBean(name, requiredType);
}

View File

@ -1,35 +0,0 @@
package com.sqx.common.utils;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMap;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author tankaikai
* @since 2025-03-28 10:16
*/
@Component
public class SqlFetcher {
@Autowired
private SqlSessionFactory sqlSessionFactory;
public String getSqlFromXml(String statementId, Object parameterObject) {
// 获取Configuration对象
Configuration configuration = sqlSessionFactory.getConfiguration();
try {
// 获取指定ID的MappedStatement对象
MappedStatement mappedStatement = configuration.getMappedStatement(statementId);
// 获取SQL语句
if(parameterObject instanceof String){
SqlUtil.escapeOrderBySql((String) parameterObject);
}
return mappedStatement.getBoundSql(parameterObject).getSql();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -1,66 +0,0 @@
package com.sqx.common.utils;
import cn.hutool.core.util.StrUtil;
import java.util.Objects;
import java.util.regex.Pattern;
/**
* sql操作工具类
*
* @author ruoyi
*/
public class SqlUtil {
/**
* SQL语法检查正则符合两个关键字有先后顺序才算匹配
*/
private static final Pattern SQL_SYNTAX_PATTERN = Pattern.compile("(insert|delete|update|select|create|drop|truncate|grant|alter|deny|revoke|call|execute|exec|declare|show|rename|set)" +
"\\s+.*(into|from|set|where|table|database|view|index|on|cursor|procedure|trigger|for|password|union|and|or)|(select\\s*\\*\\s*from\\s+)" +
"|if\\s*\\(.*\\)|select\\s*\\(.*\\)|substr\\s*\\(.*\\)|substring\\s*\\(.*\\)|char\\s*\\(.*\\)|concat\\s*\\(.*\\)|benchmark\\s*\\(.*\\)|sleep\\s*\\(.*\\)|(and|or)\\s+.*", Pattern.CASE_INSENSITIVE);
/**
* 使用';或注释截断SQL检查正则
*/
private static final Pattern SQL_COMMENT_PATTERN = Pattern.compile("'.*(or|union|--|#|/\\*|;)", Pattern.CASE_INSENSITIVE);
/**
* 限制orderBy最大长度
*/
private static final int ORDER_BY_MAX_LENGTH = 500;
/**
* 检查字符防止注入绕过
*/
public static String escapeOrderBySql(String value) {
if (StrUtil.isNotEmpty(value)) {
if (check(value)) {
throw new IllegalArgumentException("参数不符合规范,不能进行查询");
}
if (value.length() > ORDER_BY_MAX_LENGTH) {
throw new IllegalArgumentException("参数已超过最大限制,不能进行查询");
}
}
return value;
}
/**
* 检查参数是否存在 SQL 注入
*
* @param value 检查参数
* @return true 非法 false 合法
*/
public static boolean check(String value) {
Objects.requireNonNull(value);
// 处理是否包含SQL注释字符 || 检查是否包含SQL注入敏感字符
return SQL_COMMENT_PATTERN.matcher(value).find() || SQL_SYNTAX_PATTERN.matcher(value).find();
}
/**
* 刪除字段转义符单引号双引号
*
* @param text 待处理字段
*/
public static String removeEscapeCharacter(String text) {
Objects.nonNull(text);
return text.replaceAll("\"", "").replaceAll("'", "");
}
}

View File

@ -1,20 +1,12 @@
package com.sqx.config;
import com.sqx.common.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
/**
* Redis配置
*
@ -24,18 +16,6 @@ public class RedisConfig {
@Autowired
private RedisConnectionFactory factory;
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(30))
// 设置缓存过期时间为30分钟
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
.disableCachingNullValues();
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(cacheConfiguration)
.build();
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
@ -71,10 +51,4 @@ public class RedisConfig {
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForZSet();
}
@Bean
public RedisUtils redisUtils() {
// 根据实际情况初始化RedisUtils实例可能需要传入相关配置参数如Redis连接信息等
return new RedisUtils();
}
}

View File

@ -1,242 +0,0 @@
package com.sqx.config;
import com.sqx.modules.utils.InvitationCodeUtil;
import com.sqx.sharding.MasterSlaveRules;
import com.sqx.sharding.ShardingDataBase;
import com.sqx.sharding.StandardShardingStrategyConf;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shardingsphere.api.config.masterslave.MasterSlaveRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.KeyGeneratorConfiguration;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
import org.apache.shardingsphere.core.strategy.route.standard.StandardShardingStrategy;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.codehaus.groovy.util.StringUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;
/**
* sharding-jdbc 配置文件
*/
@Slf4j
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.shardingsphere")
public class ShardingConfig {
/**
* 读取数据源信息
*/
private Map<String, ShardingDataBase> datasource;
/**
* 读写分离的配置
*/
private Map<String, MasterSlaveRules> masterSlaveRules;
/**
* 显示sharding-jdbc的sql
*/
private String showSql;
/**
* 广播表
*/
// private Set<String> broadcastTables;
/**
* 中心库的节点
*/
private String centerTablesDataNode;
/**
* 中心表,不进行分库操作
*/
private Set<String> centerTables;
/**
* 区域库的节点
*/
private String regionTablesDataNode;
/**
* 区域表分库策略的字段
*/
private String regionTablesShardingDatabaseColumn;
/**
* 区域表分库的算法
*/
private String regionTablesShardingDatabaseAlgorithm;
/**
* 分库表,通过userId进行分库
*/
private Set<String> regionTables;
/**
* 区域表分库策略的字段
*/
private String courseDetailsShardingDatabaseColumn;
/**
* 区域表分库的算法
*/
private String courseDetailsShardingDatabaseAlgorithm;
/**
* 分库表,通过userId进行分库
*/
private Set<String> courseDetails;
/**
* 配置sharding-jdbc数据源
*/
@Bean
public DataSource dataSource() throws SQLException {
ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
// 配置数据库主从
shardingRuleConfig.setMasterSlaveRuleConfigs(masterSlaveRuleConfigs());
// 配置广播表
// shardingRuleConfig.setBroadcastTables(broadcastTables);
// 配置表的切分策略
shardingRuleConfig.setTableRuleConfigs(addTableRuleConfigs());
// 配置表绑定规则
List<Set<String>> sets = new ArrayList<>();
sets.add(regionTables);
shardingRuleConfig.setBindingTableGroups(bindingTableGroups(sets));
// 配置是否显示sql
Properties props = new Properties();
props.put("sql.show", showSql);
// 配置数据源
Map<String, DataSource> dataSourceMap = getShardingDataBase();
return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, props);
}
/**
* 配置
*/
private Set<TableRuleConfiguration> addTableRuleConfigs() {
Set<TableRuleConfiguration> sets = new HashSet<>();
for (String centerTable : centerTables) {
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(centerTable,
String.format(centerTablesDataNode, centerTable));
sets.add(tableRuleConfig);
}
// 定义区域表的分库规则
StandardShardingStrategyConfiguration databaseShardingStrategyConfig = new StandardShardingStrategyConfiguration(
regionTablesShardingDatabaseColumn, new StandardShardingStrategyConf());
// InlineShardingStrategyConfiguration databaseShardingStrategyConfig = new InlineShardingStrategyConfiguration(
// regionTablesShardingDatabaseColumn, regionTablesShardingDatabaseAlgorithm);
for (String regionTable : regionTables) {
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(regionTable, String.format(regionTablesDataNode, regionTable));
tableRuleConfig.setDatabaseShardingStrategyConfig(databaseShardingStrategyConfig);
sets.add(tableRuleConfig);
}
// 定义区域表的分库规则
StandardShardingStrategyConfiguration courseDetailsShardingStrategyConfig = new StandardShardingStrategyConfiguration(
courseDetailsShardingDatabaseColumn, new StandardShardingStrategyConf());
for (String regionTable : courseDetails) {
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(regionTable, String.format(regionTablesDataNode, regionTable));
tableRuleConfig.setDatabaseShardingStrategyConfig(courseDetailsShardingStrategyConfig);
// 设置区域表使用雪花算法生成主键
KeyGeneratorConfiguration keyGeneratorConfig = new KeyGeneratorConfiguration("SNOWFLAKE", "id");
tableRuleConfig.setKeyGeneratorConfig(keyGeneratorConfig);
sets.add(tableRuleConfig);
}
return sets;
}
/**
* 配置数据源
*/
private Map<String, DataSource> getShardingDataBase() {
String testQuery = "SELECT 1";
Map<String, DataSource> map = new HashMap<>();
datasource.forEach((datasourceName, shardingDataBase) -> {
HikariConfig config = new HikariConfig();
config.setDriverClassName(shardingDataBase.getDriverClassName());
config.setJdbcUrl(shardingDataBase.getJdbcUrl());
config.setUsername(shardingDataBase.getUsername());
config.setPassword(shardingDataBase.getPassword());
config.setPoolName(datasourceName);
config.setMinimumIdle(shardingDataBase.getMinimumIdle());
config.setMaximumPoolSize(shardingDataBase.getMaximumPoolSize());
config.setIdleTimeout(shardingDataBase.getIdleTimeout());
config.setMaxLifetime(shardingDataBase.getMaxLifetime());
config.setConnectionTimeout(shardingDataBase.getConnectionTimeout());
config.setConnectionTestQuery(testQuery);
map.put(datasourceName, new HikariDataSource(config));
});
return map;
}
/**
* 配置读写分离
*/
private Set<MasterSlaveRuleConfiguration> masterSlaveRuleConfigs() {
Set<MasterSlaveRuleConfiguration> sets = new HashSet<>();
masterSlaveRules.forEach((databaseName, masterSlaveRules) -> {
MasterSlaveRuleConfiguration masterSlaveRuleConfig = new MasterSlaveRuleConfiguration(databaseName,
masterSlaveRules.getMasterDataSourceName(), masterSlaveRules.getSlaveDataSourceNames());
sets.add(masterSlaveRuleConfig);
});
return sets;
}
/**
* 绑定表的分片规则
*/
public static Set<String> bindingTableGroups(List<Set<String>> sets) {
if (sets != null && !sets.isEmpty()) {
Set<String> tableGroups = new HashSet<>();
for (Set<String> set : sets) {
String tableNames = bindingTable(set.toArray(new String[0]));
if (StringUtils.isNotBlank(tableNames)) {
tableGroups.add(tableNames);
}
}
return tableGroups;
}
return null;
}
/**
* 批量绑定表规则
*
* @param tables 批量绑定的标规则
* @return tableNames
*/
private static String bindingTable(String... tables) {
StringBuilder tableNames = new StringBuilder();
if (tables != null && tables.length != 0) {
for (String table : tables) {
tableNames.append(table).append(",");
}
tableNames.deleteCharAt(tableNames.length() - 1);
}
return tableNames.toString();
}
}

View File

@ -41,19 +41,22 @@ public class ShiroConfig {
shiroFilter.setFilters(filters);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/uniCallBack/**", "anon");
filterMap.put("/course/synCourse", "anon");
filterMap.put("/webjars/**", "anon");
filterMap.put("/druid/**", "anon");
filterMap.put("/app/**", "anon");
filterMap.put("/activity/**", "anon");
filterMap.put("/banner/**", "anon");
filterMap.put("/courseClassification/selectCourseClassification", "anon");
filterMap.put("/sys/login", "anon");
filterMap.put("/sys/registered", "anon");
filterMap.put("/swagger/**", "anon");
filterMap.put("/alioss/**", "anon");
filterMap.put("/v2/api-docs", "anon");
filterMap.put("/swagger-ui.html", "anon");
filterMap.put("/swagger-resources/**", "anon");
filterMap.put("/captcha.jpg", "anon");
filterMap.put("/aaa.txt", "anon");
filterMap.put("/search/**", "anon");
filterMap.put("/cashOutAudit/batchCashOutOrder", "anon");
filterMap.put("/app/discSpinning/receive1", "anon");
filterMap.put("/**", "oauth2");
shiroFilter.setFilterChainDefinitionMap(filterMap);

View File

@ -1,114 +0,0 @@
package com.sqx.config;
/**
* 描述: Twitter的分布式自增ID雪花算法snowflake (Java版)
**/
public class SnowFlake {
/**
* 起始的时间戳
*/
private final static long START_STMP = 1480166465631L;
/**
* 每一部分占用的位数
*/
private final static long SEQUENCE_BIT = 12; //序列号占用的位数
private final static long MACHINE_BIT = 5; //机器标识占用的位数
private final static long DATACENTER_BIT = 5;//数据中心占用的位数
/**
* 每一部分的最大值
*/
private final static long MAX_DATACENTER_NUM = ~(-1L << DATACENTER_BIT);
private final static long MAX_MACHINE_NUM = ~(-1L << MACHINE_BIT);
private final static long MAX_SEQUENCE = ~(-1L << SEQUENCE_BIT);
/**
* 每一部分向左的位移
*/
private final static long MACHINE_LEFT = SEQUENCE_BIT;
private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
/**
* 数据中心
*/
private long datacenterId;
/**
* 机器标识
*/
private long machineId;
/**
* 代表了一毫秒内生成的多个id的最新序号
*/
private long sequence = 10000L;
/**
* 上一次时间戳
*/
private long lastStmp = -1L;
public SnowFlake() {
}
public SnowFlake(long datacenterId, long machineId) {
if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0");
}
if (machineId > MAX_MACHINE_NUM || machineId < 0) {
throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
}
this.datacenterId = datacenterId;
this.machineId = machineId;
}
/**
* 产生下一个ID
*
* @param ifEvenNum 是否偶数 true 时间不连续全是偶数 时间连续 奇数偶数 false 时间不连续 奇偶都有 所以一般建议用false
*/
public synchronized long nextId(boolean ifEvenNum) {
long currStmp = getNewstmp();
if (currStmp < lastStmp) {
throw new RuntimeException("Clock moved backwards. Refusing to generate id");
}
/**
* 时间不连续出来全是偶数
*/
if (ifEvenNum) {
if (currStmp == lastStmp) {
//相同毫秒内序列号自增
sequence = (sequence + 1) & MAX_SEQUENCE;
//同一毫秒的序列数已经达到最大
if (sequence == 0L) {
currStmp = getNextMill();
}
} else {
//不同毫秒内序列号置为0
sequence = 0L;
}
} else {
//相同毫秒内序列号自增
sequence = (sequence + 1) & MAX_SEQUENCE;
}
lastStmp = currStmp;
return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
| datacenterId << DATACENTER_LEFT //数据中心部分
| machineId << MACHINE_LEFT //机器标识部分
| sequence; //序列号部分
}
private long getNextMill() {
long mill = getNewstmp();
while (mill <= lastStmp) {
mill = getNewstmp();
}
return mill;
}
private long getNewstmp() {
return System.currentTimeMillis();
}
}

View File

@ -1,24 +0,0 @@
package com.sqx.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SnowFlakeConfig {
/**
* 数据中心
*/
@Value("${snowflake.datacenterId}")
private String datacenterId;
/**
* 机器标识
*/
@Value("${snowflake.machineId}")
private String machineId;
@Bean(name = "snowFlake")
public SnowFlake snowFlake() {
return new SnowFlake(Long.parseLong(datacenterId), Long.parseLong(machineId));
}
}

View File

@ -1,85 +1,53 @@
//package com.sqx.config;
//
//import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiOperation;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Profile;
//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//import springfox.documentation.builders.ApiInfoBuilder;
//import springfox.documentation.builders.PathSelectors;
//import springfox.documentation.builders.RequestHandlerSelectors;
//import springfox.documentation.service.ApiInfo;
//import springfox.documentation.service.ApiKey;
//import springfox.documentation.spi.DocumentationType;
//import springfox.documentation.spring.web.plugins.Docket;
//import springfox.documentation.swagger2.annotations.EnableSwagger2;
//
//import java.util.List;
//
//import static com.google.common.collect.Lists.newArrayList;
//
////@Configuration
////@EnableSwagger2
////public class SwaggerConfig implements WebMvcConfigurer {
////
//// @Value("${swagger.enabled}")
//// private boolean enabled;
////
//// @Bean
//// public Docket createRestApi() {
//// return new Docket(DocumentationType.SWAGGER_2)
//// .enable(enabled)
//// .apiInfo(apiInfo())
//// .select()
//// //加了ApiOperation注解的类才生成接口文档
//// .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
//// //包下的类才生成接口文档
//// //.apis(RequestHandlerSelectors.basePackage("com.sqx.controller"))
//// .paths(PathSelectors.any())
//// .build()
//// .securitySchemes(security());
//// }
////
//// private ApiInfo apiInfo() {
//// return new ApiInfoBuilder()
//// .title("")
//// .description("sqx-fast文档")
//// .termsOfServiceUrl("")
//// .version("3.0.0")
//// .build();
//// }
////
//// private List<ApiKey> security() {
//// return newArrayList(
//// new ApiKey("token", "token", "header")
//// );
//// }
////
////}
//
//@Configuration
//@EnableSwagger2
//@Profile({"local", "dev"})
//public class SwaggerConfig {
//
// @Bean
// public Docket api() {
// return new Docket(DocumentationType.SWAGGER_2)
// .apiInfo(apiInfo())
// .select()
// .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
// .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// .paths(PathSelectors.any())
// .build();
// }
//
// private ApiInfo apiInfo() {
// return new ApiInfoBuilder()
// .title("悠车位后台API接口文档")
// .description("悠车位服务端后台API接口文档")
// .version("1.0")
// .build();
// }
//}
package com.sqx.config;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
@Configuration
@EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//加了ApiOperation注解的类才生成接口文档
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
//包下的类才生成接口文档
//.apis(RequestHandlerSelectors.basePackage("com.sqx.controller"))
.paths(PathSelectors.any())
.build()
.securitySchemes(security());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("")
.description("sqx-fast文档")
.termsOfServiceUrl("")
.version("3.0.0")
.build();
}
private List<ApiKey> security() {
return newArrayList(
new ApiKey("token", "token", "header")
);
}
}

View File

@ -0,0 +1,14 @@
package com.sqx.datasource.annotation;
import java.lang.annotation.*;
/**
* 多数据源注解
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface DataSource {
String value() default "";
}

View File

@ -0,0 +1,61 @@
package com.sqx.datasource.aspect;
import com.sqx.datasource.annotation.DataSource;
import com.sqx.datasource.config.DynamicContextHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* 多数据源切面处理类
*/
@Aspect
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class DataSourceAspect {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Pointcut("@annotation(com.sqx.datasource.annotation.DataSource) " +
"|| @within(com.sqx.datasource.annotation.DataSource)")
public void dataSourcePointCut() {
}
@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Class targetClass = point.getTarget().getClass();
Method method = signature.getMethod();
DataSource targetDataSource = (DataSource)targetClass.getAnnotation(DataSource.class);
DataSource methodDataSource = method.getAnnotation(DataSource.class);
if(targetDataSource != null || methodDataSource != null){
String value;
if(methodDataSource != null){
value = methodDataSource.value();
}else {
value = targetDataSource.value();
}
DynamicContextHolder.push(value);
logger.debug("set datasource is {}", value);
}
try {
return point.proceed();
} finally {
DynamicContextHolder.poll();
logger.debug("clean datasource");
}
}
}

View File

@ -0,0 +1,47 @@
package com.sqx.datasource.config;
import java.util.ArrayDeque;
import java.util.Deque;
/**
* 多数据源上下文
*/
public class DynamicContextHolder {
@SuppressWarnings("unchecked")
private static final ThreadLocal<Deque<String>> CONTEXT_HOLDER = new ThreadLocal() {
@Override
protected Object initialValue() {
return new ArrayDeque();
}
};
/**
* 获得当前线程数据源
*
* @return 数据源名称
*/
public static String peek() {
return CONTEXT_HOLDER.get().peek();
}
/**
* 设置当前线程数据源
*
* @param dataSource 数据源名称
*/
public static void push(String dataSource) {
CONTEXT_HOLDER.get().push(dataSource);
}
/**
* 清空当前线程数据源
*/
public static void poll() {
Deque<String> deque = CONTEXT_HOLDER.get();
deque.poll();
if (deque.isEmpty()) {
CONTEXT_HOLDER.remove();
}
}
}

View File

@ -0,0 +1,15 @@
package com.sqx.datasource.config;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 多数据源
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DynamicContextHolder.peek();
}
}

View File

@ -0,0 +1,53 @@
package com.sqx.datasource.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.sqx.datasource.properties.DataSourceProperties;
import com.sqx.datasource.properties.DynamicDataSourceProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* 配置多数据源
*/
@Configuration
@EnableConfigurationProperties(DynamicDataSourceProperties.class)
public class DynamicDataSourceConfig {
@Autowired
private DynamicDataSourceProperties properties;
@Bean
@ConfigurationProperties(prefix = "spring.datasource.druid")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
@Bean
public DynamicDataSource dynamicDataSource(DataSourceProperties dataSourceProperties) {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setTargetDataSources(getDynamicDataSource());
//默认数据源
DruidDataSource defaultDataSource = DynamicDataSourceFactory.buildDruidDataSource(dataSourceProperties);
dynamicDataSource.setDefaultTargetDataSource(defaultDataSource);
return dynamicDataSource;
}
private Map<Object, Object> getDynamicDataSource(){
Map<String, DataSourceProperties> dataSourcePropertiesMap = properties.getDatasource();
Map<Object, Object> targetDataSources = new HashMap<>(dataSourcePropertiesMap.size());
dataSourcePropertiesMap.forEach((k, v) -> {
DruidDataSource druidDataSource = DynamicDataSourceFactory.buildDruidDataSource(v);
targetDataSources.put(k, druidDataSource);
});
return targetDataSources;
}
}

View File

@ -0,0 +1,44 @@
package com.sqx.datasource.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.sqx.datasource.properties.DataSourceProperties;
import java.sql.SQLException;
/**
* DruidDataSource
*
*/
public class DynamicDataSourceFactory {
public static DruidDataSource buildDruidDataSource(DataSourceProperties properties) {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(properties.getDriverClassName());
druidDataSource.setUrl(properties.getUrl());
druidDataSource.setUsername(properties.getUsername());
druidDataSource.setPassword(properties.getPassword());
druidDataSource.setInitialSize(properties.getInitialSize());
druidDataSource.setMaxActive(properties.getMaxActive());
druidDataSource.setMinIdle(properties.getMinIdle());
druidDataSource.setMaxWait(properties.getMaxWait());
druidDataSource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis());
druidDataSource.setMinEvictableIdleTimeMillis(properties.getMinEvictableIdleTimeMillis());
druidDataSource.setMaxEvictableIdleTimeMillis(properties.getMaxEvictableIdleTimeMillis());
druidDataSource.setValidationQuery(properties.getValidationQuery());
druidDataSource.setValidationQueryTimeout(properties.getValidationQueryTimeout());
druidDataSource.setTestOnBorrow(properties.isTestOnBorrow());
druidDataSource.setTestOnReturn(properties.isTestOnReturn());
druidDataSource.setPoolPreparedStatements(properties.isPoolPreparedStatements());
druidDataSource.setMaxOpenPreparedStatements(properties.getMaxOpenPreparedStatements());
druidDataSource.setSharePreparedStatements(properties.isSharePreparedStatements());
try {
druidDataSource.setFilters(properties.getFilters());
druidDataSource.init();
} catch (SQLException e) {
e.printStackTrace();
}
return druidDataSource;
}
}

View File

@ -0,0 +1,192 @@
package com.sqx.datasource.properties;
/**
* 多数据源属性
*
*/
public class DataSourceProperties {
private String driverClassName;
private String url;
private String username;
private String password;
/**
* Druid默认参数
*/
private int initialSize = 2;
private int maxActive = 10;
private int minIdle = -1;
private long maxWait = 60 * 1000L;
private long timeBetweenEvictionRunsMillis = 60 * 1000L;
private long minEvictableIdleTimeMillis = 1000L * 60L * 30L;
private long maxEvictableIdleTimeMillis = 1000L * 60L * 60L * 7;
private String validationQuery = "select 1";
private int validationQueryTimeout = -1;
private boolean testOnBorrow = false;
private boolean testOnReturn = false;
private boolean testWhileIdle = true;
private boolean poolPreparedStatements = false;
private int maxOpenPreparedStatements = -1;
private boolean sharePreparedStatements = false;
private String filters = "stat,wall";
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getInitialSize() {
return initialSize;
}
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public long getMaxWait() {
return maxWait;
}
public void setMaxWait(long maxWait) {
this.maxWait = maxWait;
}
public long getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public long getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public long getMaxEvictableIdleTimeMillis() {
return maxEvictableIdleTimeMillis;
}
public void setMaxEvictableIdleTimeMillis(long maxEvictableIdleTimeMillis) {
this.maxEvictableIdleTimeMillis = maxEvictableIdleTimeMillis;
}
public String getValidationQuery() {
return validationQuery;
}
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
public int getValidationQueryTimeout() {
return validationQueryTimeout;
}
public void setValidationQueryTimeout(int validationQueryTimeout) {
this.validationQueryTimeout = validationQueryTimeout;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public boolean isPoolPreparedStatements() {
return poolPreparedStatements;
}
public void setPoolPreparedStatements(boolean poolPreparedStatements) {
this.poolPreparedStatements = poolPreparedStatements;
}
public int getMaxOpenPreparedStatements() {
return maxOpenPreparedStatements;
}
public void setMaxOpenPreparedStatements(int maxOpenPreparedStatements) {
this.maxOpenPreparedStatements = maxOpenPreparedStatements;
}
public boolean isSharePreparedStatements() {
return sharePreparedStatements;
}
public void setSharePreparedStatements(boolean sharePreparedStatements) {
this.sharePreparedStatements = sharePreparedStatements;
}
public String getFilters() {
return filters;
}
public void setFilters(String filters) {
this.filters = filters;
}
}

View File

@ -0,0 +1,22 @@
package com.sqx.datasource.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 多数据源属性
*/
@ConfigurationProperties(prefix = "dynamic")
public class DynamicDataSourceProperties {
private Map<String, DataSourceProperties> datasource = new LinkedHashMap<>();
public Map<String, DataSourceProperties> getDatasource() {
return datasource;
}
public void setDatasource(Map<String, DataSourceProperties> datasource) {
this.datasource = datasource;
}
}

View File

@ -1,41 +0,0 @@
package com.sqx.modules.announcement.controller;
import com.sqx.common.utils.Result;
import com.sqx.modules.announcement.service.AnnouncementService;
import com.sqx.modules.common.dto.AddAnnouncementDTO;
import com.sqx.modules.common.dto.DeleteAnnouncementDTO;
import com.sqx.modules.common.dto.UpdateAnnouncementDTO;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/announcement")
public class AnnouncementController {
private final AnnouncementService announcementService;
public AnnouncementController(AnnouncementService announcementService) {
this.announcementService = announcementService;
}
@GetMapping("/list")
public Result list(@RequestParam(required = false) String title, @RequestParam(required = false) Integer state, @RequestParam(required = false) Integer id, @RequestParam(required = false) Integer type) {
return Result.success().put("data", announcementService.listInfo(title, state, id, type));
}
@PostMapping
public Result add(@RequestBody @Validated AddAnnouncementDTO announcementDTO) {
return Result.success().put("data", announcementService.add(announcementDTO));
}
@PutMapping
public Result update(@RequestBody @Validated UpdateAnnouncementDTO updateAnnouncementDTO) {
return Result.success().put("data", announcementService.updateInfo(updateAnnouncementDTO));
}
@DeleteMapping
public Result delete(@RequestBody @Validated DeleteAnnouncementDTO deleteAnnouncementDTO) {
return Result.success().put("data", announcementService.removeById(deleteAnnouncementDTO.getId()));
}
}

View File

@ -1,60 +0,0 @@
package com.sqx.modules.announcement.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 公告表
* @TableName announcement
*/
@TableName(value ="announcement")
@Data
@EqualsAndHashCode
public class Announcement implements Serializable {
/**
*
*/
// @TableId
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 标题
*/
private String title;
/**
* 内容
*/
private String content;
/**
* 状态0关闭 1打开
*/
private Integer state;
private Integer type;
/**
* 创建时间
*/
private Date createTime;
/**
* 修改时间
*/
private Date updateTime;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -1,20 +0,0 @@
package com.sqx.modules.announcement.mapper;
import com.sqx.modules.announcement.entity.Announcement;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author Administrator
* @description 针对表announcement(公告表)的数据库操作Mapper
* @createDate 2025-01-02 14:33:44
* @Entity com.sqx.modules.announcement.entity.Announcement
*/
@Mapper
public interface AnnouncementMapper extends BaseMapper<Announcement> {
}

View File

@ -1,22 +0,0 @@
package com.sqx.modules.announcement.service;
import com.sqx.modules.announcement.entity.Announcement;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sqx.modules.common.dto.AddAnnouncementDTO;
import com.sqx.modules.common.dto.DeleteAnnouncementDTO;
import com.sqx.modules.common.dto.UpdateAnnouncementDTO;
/**
* @author Administrator
* @description 针对表announcement(公告表)的数据库操作Service
* @createDate 2025-01-02 14:33:44
*/
public interface AnnouncementService extends IService<Announcement> {
Object add(AddAnnouncementDTO announcementDTO);
Object updateInfo(UpdateAnnouncementDTO updateAnnouncementDTO);
Object listInfo(String title, Integer state, Integer id, Integer type);
}

View File

@ -1,65 +0,0 @@
package com.sqx.modules.announcement.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.common.exception.SqxException;
import com.sqx.modules.announcement.entity.Announcement;
import com.sqx.modules.announcement.service.AnnouncementService;
import com.sqx.modules.announcement.mapper.AnnouncementMapper;
import com.sqx.modules.common.dto.AddAnnouncementDTO;
import com.sqx.modules.common.dto.UpdateAnnouncementDTO;
import org.springframework.stereotype.Service;
/**
* @author Administrator
* @description 针对表announcement(公告表)的数据库操作Service实现
* @createDate 2025-01-02 14:33:44
*/
@Service
public class AnnouncementServiceImpl extends ServiceImpl<AnnouncementMapper, Announcement>
implements AnnouncementService{
@Override
public Object listInfo(String title, Integer state, Integer id, Integer type) {
LambdaQueryWrapper<Announcement> queryWrapper = new LambdaQueryWrapper<>();
if (StrUtil.isNotBlank(title)) {
queryWrapper.like(Announcement::getTitle, title);
}
if (type != null) {
queryWrapper.eq(Announcement::getType, type);
}
if (state != null) {
queryWrapper.eq(Announcement::getState, state);
}
if (id != null) {
queryWrapper.eq(Announcement::getId, id);
}
return queryWrapper.isEmptyOfWhere() ? list() : list(queryWrapper);
}
@Override
public Object add(AddAnnouncementDTO announcementDTO) {
Announcement announcement = new Announcement();
BeanUtil.copyProperties(announcementDTO, announcement);
announcement.setCreateTime(DateUtil.date());
return save(announcement);
}
@Override
public Object updateInfo(UpdateAnnouncementDTO updateAnnouncementDTO) {
Announcement announcement = getById(updateAnnouncementDTO.getId());
if (announcement == null) {
throw new SqxException("公告不存在");
}
BeanUtil.copyProperties(updateAnnouncementDTO, announcement);
announcement.setUpdateTime(DateUtil.date());
return updateById(announcement);
}
}

View File

@ -1,9 +1,8 @@
package com.sqx.modules.app.controller;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sqx.common.utils.PageUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.entity.App;
import com.sqx.modules.app.service.AppService;
@ -14,7 +13,6 @@ import org.springframework.web.bind.annotation.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* APP登录授权
@ -32,10 +30,8 @@ public class AppUpgradeController {
@ApiOperation("管理平台升级详情")
@ResponseBody
public Result list(Integer page,Integer limit) {
PageHelper.startPage(page,limit);
List<App> list = iAppService.list();
PageInfo<App> pageInfo = new PageInfo<>(list);
return Result.success().put("data", PageUtils.page(pageInfo, true));
IPage<App> pages =new Page<>(page,limit);
return Result.success().put("data",iAppService.page(pages));
}

View File

@ -1,58 +0,0 @@
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 com.sqx.modules.app.service.UserService;
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 javax.annotation.Resource;
import java.util.Map;
@RestController
@RequestMapping("/app/userPrizeExchange")
@AllArgsConstructor
@Api(value = "用户奖品兑换", tags = {"用户奖品兑换"})
public class AppUserPrizeExchangeController {
private final UserPrizeExchangeService userPrizeExchangeService;
@Resource
private UserService userService;
@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();
}
@Login
@PostMapping("/receive")
@ApiOperation("领取满签奖励")
public Result receive(@RequestAttribute("userId") Long userId) {
userService.addBlackUser(userId,"领取满签奖励");
return Result.success();
}
}

View File

@ -1,12 +1,10 @@
package com.sqx.modules.app.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.dto.UserInviteDTO;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserMoneyDetails;
import com.sqx.modules.app.entity.UserVip;
@ -23,10 +21,8 @@ import com.sqx.modules.pay.dao.PayDetailsDao;
import com.sqx.modules.pay.entity.PayDetails;
import com.sqx.modules.pay.service.PayDetailsService;
import com.sqx.modules.sys.entity.SysUserEntity;
import com.sqx.modules.sys.service.SysUserMoneyDetailsService;
import com.sqx.modules.sys.service.SysUserService;
import com.sqx.modules.utils.EasyPoi.ExcelUtils;
import com.sqx.modules.utils.TimeCompleteUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
@ -38,7 +34,6 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
@ -61,8 +56,6 @@ public class UserController {
@Autowired
private UserMoneyDetailsService userMoneyDetailsService;
@Autowired
private SysUserMoneyDetailsService sysUserMoneyDetailsService;
@Autowired
private UserMoneyService userMoneyService;
@Autowired
private InviteMoneyService inviteMoneyService;
@ -81,7 +74,7 @@ public class UserController {
public Result selectUserByInvitationCode(String invitationCode) {
Map<String, Object> map = new HashMap<>();
UserEntity userEntity = userService.queryByInvitationCode(invitationCode);
Long userId = userEntity.getUserId();
Long userId=userEntity.getUserId();
//查询用户钱包
// Double money = cashOutDao.selectMayMoney(userId);
InviteMoney inviteMoney = inviteMoneyService.selectInviteMoneyByUserId(userId);
@ -95,7 +88,7 @@ public class UserController {
//查询邀请人数
int count = userService.queryInviterCount(userEntity.getInvitationCode());
UserVip userVip = userVipService.selectUserVipByUserId(userId);
if (userVip != null) {
if(userVip!=null){
userEntity.setMember(userVip.getIsVip());
userEntity.setEndTime(userVip.getEndTime());
userEntity.setVipType(userVip.getVipType());
@ -127,7 +120,7 @@ public class UserController {
//查询邀请人数
int count = userService.queryInviterCount(userEntity.getInvitationCode());
UserVip userVip = userVipService.selectUserVipByUserId(userId);
if (userVip != null) {
if(userVip!=null){
userEntity.setMember(userVip.getIsVip());
userEntity.setEndTime(userVip.getEndTime());
userEntity.setVipType(userVip.getVipType());
@ -143,12 +136,12 @@ public class UserController {
@RequestMapping(value = "/selectUserList", method = RequestMethod.GET)
@ApiOperation("查询所有用户列表")
@ResponseBody
public Result selectUserList(Integer page, Integer limit, String phone, Integer sex, String platform,
String sysPhone, Integer status, Integer member, String inviterCode,
public Result selectUserList(Integer page, Integer limit,String phone,Integer sex,String platform,
String sysPhone,Integer status, Integer member, String inviterCode,
String userName, String invitationCode, String startTime, String endTime,
String qdCode, String sysUserName, Integer vipType, Integer delegate) {
String qdCode,String sysUserName,Integer vipType) {
return Result.success().put("data", userService.selectUserPage(page, limit, phone, sex, platform, sysPhone, status, member,
inviterCode, userName, invitationCode, startTime, endTime, qdCode, sysUserName, vipType, delegate));
inviterCode, userName, invitationCode, startTime, endTime,qdCode,sysUserName,vipType));
}
@GetMapping("/userListExcel")
@ -170,28 +163,17 @@ public class UserController {
@ApiOperation("修改用户")
@ResponseBody
public Result updateUserByUserId(@RequestBody UserEntity userEntity) {
if (StringUtils.isNotEmpty(userEntity.getPhone())) {
if(StringUtils.isNotEmpty(userEntity.getPhone())){
UserEntity phoneUser = userService.queryByPhone(userEntity.getPhone());
if (phoneUser != null && !phoneUser.getUserId().equals(userEntity.getUserId())) {
if(phoneUser!=null && !phoneUser.getUserId().equals(userEntity.getUserId())){
return Result.error("手机号已被其他用户绑定!");
}
}
UserEntity userEntity2 = userService.queryByUserId(userEntity.getUserId());
if (StringUtils.isNotEmpty(userEntity2.getQdCode())) {
SysUserEntity sysUserEntity = sysUserService.getOne(new QueryWrapper<SysUserEntity>().eq("qd_code", userEntity2.getQdCode()));
if (sysUserEntity == null) {
if(StringUtils.isNotEmpty(userEntity.getQdCode())){
SysUserEntity sysUserEntity = sysUserService.getOne(new QueryWrapper<SysUserEntity>().eq("qd_code", userEntity.getQdCode()));
if(sysUserEntity==null){
return Result.error("渠道码不正确!");
}
if (userEntity.getRate() != null) {
if (sysUserEntity.getQdRate().compareTo(userEntity.getRate()) < 0) {
return Result.error("下级佣金不可大于渠道商佣金");
}
}
if (userEntity.getTwoRate() != null) {
if (sysUserEntity.getQdRate().compareTo(userEntity.getTwoRate()) < 0) {
return Result.error("下级佣金不可大于渠道商佣金");
}
}
}
userService.updateById(userEntity);
return Result.success();
@ -200,24 +182,14 @@ public class UserController {
@RequestMapping(value = "/updateUserStatusByUserId", method = RequestMethod.GET)
@ApiOperation("禁用或启用用户")
@ResponseBody
public Result updateUserByUserId(Long userId, Integer status) {
public Result updateUserByUserId(Long userId) {
UserEntity byId = userService.getById(userId);
if (byId == null) {
return Result.error("用户不存在");
}
if (status.equals(1)) {
byId.setStatus(1);
userService.upUserBlack(byId, 1);
} else if (status.equals(2)) {
userService.update(new LambdaUpdateWrapper<UserEntity>()
.eq(UserEntity::getUserId, userId)
.set(UserEntity::getStatus, 2));
} else if (status.equals(0)) {
userService.upUserBlack(byId, 0);
if (byId.getStatus().equals(1)) {
byId.setStatus(2);
} else {
return Result.error("状态不正确");
byId.setStatus(1);
}
userService.updateById(byId);
return Result.success();
}
@ -252,44 +224,29 @@ public class UserController {
@GetMapping("/homeMessage")
@ApiOperation("信息分析")
public Result homeMessage(Long sysUserId) {
String qdCode = null;
if (sysUserId != null) {
qdCode = sysUserService.getById(sysUserId).getQdCode();
String qdCode=null;
if(sysUserId!=null){
qdCode=sysUserService.getById(sysUserId).getQdCode();
}
HomeMessageResponse homeMessageResponse = new HomeMessageResponse();
// 0查总 1查天 2查月 3查年
//设置总用户人数
homeMessageResponse.setTotalUsers(userService.queryUserCount(0, null, null, qdCode));
homeMessageResponse.setTotalUsers(userService.queryUserCount(0, null,null,qdCode));
//设置今日新增
homeMessageResponse.setNewToday(userService.queryUserCount(1, null, null, qdCode));
homeMessageResponse.setNewToday(userService.queryUserCount(1, null,null,qdCode));
//设置本月新增
homeMessageResponse.setNewMonth(userService.queryUserCount(2, null, null, qdCode));
homeMessageResponse.setNewMonth(userService.queryUserCount(2, null,null,qdCode));
//设置本年新增
homeMessageResponse.setNewYear(userService.queryUserCount(3, null, null, qdCode));
// //设置总收入
// homeMessageResponse.setTotalRevenue(userService.queryPayMoney(0, qdCode));
// //设置今日收入
// homeMessageResponse.setTodayRevenue(userService.queryPayMoney(1, qdCode));
// //设置本月收入
// homeMessageResponse.setMonthRevenue(userService.queryPayMoney(2, qdCode));
// //设置本年收入
// homeMessageResponse.setYearRevenue(userService.queryPayMoney(3, qdCode));
homeMessageResponse.setNewYear(userService.queryUserCount(3, null,null,qdCode));
//设置总收入
homeMessageResponse.setTotalRevenue(sysUserMoneyDetailsService.queryPayMoney(0, sysUserId));
homeMessageResponse.setTotalRevenue(userService.queryPayMoney(0,qdCode));
//设置今日收入
homeMessageResponse.setTodayRevenue(sysUserMoneyDetailsService.queryPayMoney(1, sysUserId));
homeMessageResponse.setTodayRevenue(userService.queryPayMoney(1,qdCode));
//设置本月收入
homeMessageResponse.setMonthRevenue(sysUserMoneyDetailsService.queryPayMoney(2, sysUserId));
homeMessageResponse.setMonthRevenue(userService.queryPayMoney(2,qdCode));
//设置本年收入
homeMessageResponse.setYearRevenue(sysUserMoneyDetailsService.queryPayMoney(3, sysUserId));
homeMessageResponse.setYearRevenue(userService.queryPayMoney(3,qdCode));
//查询指定日期下的短剧购买的
Map<String, Object> map = userService.queryPayAndExtractInfo();
homeMessageResponse.setTodayPayAmount(map.get("payAmount") == null ? BigDecimal.ZERO : new BigDecimal(map.get("payAmount").toString()).setScale(2, RoundingMode.HALF_UP));
homeMessageResponse.setTodayPayCount(map.get("payCount") == null ? 0 : Integer.parseInt(map.get("payCount").toString()));
homeMessageResponse.setTodayExtractAmount(map.get("extractAmount") == null ? BigDecimal.ZERO : new BigDecimal(map.get("extractAmount").toString()).setScale(2, RoundingMode.HALF_UP));
homeMessageResponse.setTodayExtractCount(map.get("extractCount") == null ? 0 : Integer.parseInt(map.get("extractCount").toString()));
return Result.success().put("data", homeMessageResponse);
}
@ -300,9 +257,10 @@ public class UserController {
*/
@GetMapping("/courseMessage")
@ApiOperation("短剧分析")
public Result courseMessage(Long page, Long limit, String date, int type, Long sysUserId) {
PageUtils pageUtils = userService.queryCourseOrder(page, limit, type, TimeCompleteUtils.completeStartTime(date), sysUserId);
return Result.success().put("data", pageUtils);
public Result courseMessage(Long page, Long limit, String date, int type,Long sysUserId) {
Page<Map<String, Object>> iPage = new Page<>(page, limit);
IPage<Map<String, Object>> mapIPage = userService.queryCourseOrder(iPage, type, date,sysUserId);
return Result.success().put("data", new PageUtils(mapIPage));
}
/**
@ -310,58 +268,55 @@ public class UserController {
*/
@GetMapping("/userMessage")
@ApiOperation("用户分析")
public Result userMessage(String date, int type, Long sysUserId) {
date = TimeCompleteUtils.completeStartTime(date);
String qdCode = null;
if (sysUserId != null) {
qdCode = sysUserService.getById(sysUserId).getQdCode();
public Result userMessage(String date, int type,Long sysUserId) {
String qdCode=null;
if(sysUserId!=null){
qdCode=sysUserService.getById(sysUserId).getQdCode();
}
int sumUserCount = userService.queryUserCount(type, date, null, qdCode);
int h5Count = userService.queryUserCount(type, date, "h5", qdCode);
int appCount = userService.queryUserCount(type, date, "app", qdCode);
int wxCount = userService.queryUserCount(type, date, "小程序", qdCode);
int dyCount = userService.queryUserCount(type, date, "抖音", qdCode);
int giveMemberCount = userService.userMessage(date, type, qdCode, 1);
int moneyMemberCount = userService.userMessage(date, type, qdCode, 2);
// int memberCount = userVipService.userMessage(date, type, qdCode, null);
int memberCount = userService.userMessage(date, type, qdCode, null);
int userCount = sumUserCount - memberCount;
Map<String, Integer> result = new HashMap<>();
result.put("sumUserCount", sumUserCount);
result.put("h5Count", h5Count);
result.put("appCount", appCount);
result.put("wxCount", wxCount);
result.put("dyCount", dyCount);
result.put("memberCount", memberCount);
result.put("giveMemberCount", giveMemberCount);
result.put("moneyMemberCount", moneyMemberCount);
result.put("userCount", userCount);
int sumUserCount = userService.queryUserCount(type, date,null,qdCode);
int h5Count = userService.queryUserCount(type, date,"h5",qdCode);
int appCount = userService.queryUserCount(type, date,"app",qdCode);
int wxCount = userService.queryUserCount(type, date,"小程序",qdCode);
int dyCount = userService.queryUserCount(type, date,"抖音",qdCode);
int giveMemberCount = userService.userMessage(date, type,qdCode,1);
int moneyMemberCount = userService.userMessage(date, type,qdCode,2);
int memberCount = userService.userMessage(date, type,qdCode,null);
int userCount = sumUserCount-memberCount;
Map<String,Integer> result=new HashMap<>();
result.put("sumUserCount",sumUserCount);
result.put("h5Count",h5Count);
result.put("appCount",appCount);
result.put("wxCount",wxCount);
result.put("dyCount",dyCount);
result.put("memberCount",memberCount);
result.put("giveMemberCount",giveMemberCount);
result.put("moneyMemberCount",moneyMemberCount);
result.put("userCount",userCount);
return Result.success().put("data", result);
}
@PostMapping("addCannotMoney/{userId}/{money}")
@ApiOperation("添加金")
@ApiOperation("添加金")
public Result addCannotMoney(@PathVariable("userId") Long userId, @PathVariable("money") Double money) {
userMoneyService.updateMoney(1, userId, money);
//inviteMoneyDao.updateInviteMoneySum(money,userId);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
userMoneyDetails.setUserId(userId);
userMoneyDetails.setTitle("[增加金币]平台增加金币" + money);
userMoneyDetails.setContent("[增加金币]平台增加金币" + money);
userMoneyDetails.setTitle("[增加金豆]平台增加金豆" + money);
userMoneyDetails.setContent("[增加金豆]平台增加金豆" + money);
userMoneyDetails.setType(1);
//
userMoneyDetails.setClassify(8);
userMoneyDetails.setClassify(1);
userMoneyDetails.setMoney(new BigDecimal(money));
userMoneyDetails.setCreateTime(sdf.format(new Date()));
userMoneyDetails.setMoneyType(2);
userMoneyDetailsService.save(userMoneyDetails);
PayDetails payDetails = new PayDetails();
PayDetails payDetails=new PayDetails();
payDetails.setState(1);
payDetails.setCreateTime(sdf.format(new Date()));
payDetails.setUserId(userId);
payDetails.setMoney(money);
payDetails.setClassify(9);
payDetails.setType(1);
payDetails.setPayTime(sdf.format(new Date()));
payDetailsDao.insert(payDetails);
@ -369,72 +324,68 @@ public class UserController {
}
@PostMapping("subCannotMoney/{userId}/{money}")
@ApiOperation("减少金")
@ApiOperation("减少金")
public Result subCannotMoney(@PathVariable("userId") Long userId, @PathVariable("money") Double money) {
userMoneyService.updateMoney(2, userId, money);
//inviteMoneyDao.updateInviteMoneySumSub(money,userId);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
userMoneyDetails.setUserId(userId);
userMoneyDetails.setTitle("[减少金币]平台减少金币" + money);
userMoneyDetails.setContent("平台减少金" + money);
userMoneyDetails.setTitle("[减少金豆]平台减少金豆" + money);
userMoneyDetails.setContent("平台减少金" + money);
userMoneyDetails.setType(1);
//
userMoneyDetails.setClassify(8);
userMoneyDetails.setClassify(1);
userMoneyDetails.setMoney(new BigDecimal(money));
userMoneyDetails.setCreateTime(sdf.format(new Date()));
userMoneyDetails.setMoneyType(2);
userMoneyDetailsService.save(userMoneyDetails);
return Result.success();
}
@PostMapping("/updateSysUserMoney")
@ApiOperation("修改金币")
public Result updateSysUserMoney(Long userId, Double money, Integer type) {
// userMoneyService.updateSysMoney(type, userId, money);
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
// userMoneyDetails.setSysUserId(userId);
// if (type == 1) {
// userMoneyDetails.setTitle("[增加金币]平台增加金币:" + money);
// userMoneyDetails.setContent("[增加金币]平台增加金币:" + money);
// } else {
// userMoneyDetails.setTitle("[减少金币]平台减少金币:" + money);
// userMoneyDetails.setContent("[减少金币]平台减少金币:" + money);
// }
// userMoneyDetails.setMoneyType(2);
// userMoneyDetails.setType(type);
// //
// userMoneyDetails.setClassify(8);
// userMoneyDetails.setMoney(new BigDecimal(money));
// userMoneyDetails.setCreateTime(sdf.format(new Date()));
// userMoneyDetailsService.save(userMoneyDetails);
@ApiOperation("修改金豆")
public Result updateSysUserMoney(Long userId, Double money,Integer type) {
userMoneyService.updateSysMoney(type, userId, money);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
userMoneyDetails.setSysUserId(userId);
if(type==1){
userMoneyDetails.setTitle("[增加金豆]平台增加金豆:" + money);
userMoneyDetails.setContent("[增加金豆]平台增加金豆:" + money);
}else{
userMoneyDetails.setTitle("[减少金豆]平台减少金豆:" + money);
userMoneyDetails.setContent("[减少金豆]平台减少金豆:" + money);
}
userMoneyDetails.setType(type);
userMoneyDetails.setClassify(1);
userMoneyDetails.setMoney(new BigDecimal(money));
userMoneyDetails.setCreateTime(sdf.format(new Date()));
userMoneyDetailsService.save(userMoneyDetails);
return Result.success();
}
@GetMapping("/selectInviteUserList")
@ApiOperation("邀请用户排行榜")
public Result selectInviteUserList(Integer page, Integer limit, String phone, String userName) {
public Result selectInviteUserList(Integer page,Integer limit,String phone,String userName){
return userService.selectInviteUserList(page, limit, userName, phone);
}
@GetMapping("/selectUserOnLineCount")
@ApiOperation("统计当前在线人数")
public Result selectUserCount(Long sysUserId) {
String qdCode = null;
if (sysUserId != null) {
qdCode = sysUserService.getById(sysUserId).getQdCode();
public Result selectUserCount(Long sysUserId){
String qdCode=null;
if(sysUserId!=null){
qdCode=sysUserService.getById(sysUserId).getQdCode();
}
return userService.selectUserOnLineCount(qdCode);
}
@GetMapping("/selectUserCountStatisticsByTime")
@ApiOperation("用户统计")
public Result selectUserCountStatisticsByTime(String startTime, String endTime) {
List<Integer> userCountList = new ArrayList<>();
List<String> year = new ArrayList<>();
public Result selectUserCountStatisticsByTime(String startTime,String endTime){
List<Integer> userCountList=new ArrayList<>();
List<String> year=new ArrayList<>();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
Calendar calendar=Calendar.getInstance();
Date parse = null;
try {
parse = simpleDateFormat.parse(startTime);
@ -442,29 +393,22 @@ public class UserController {
e.printStackTrace();
}
calendar.setTime(parse);
while (true) {
while (true){
String dateTime = simpleDateFormat.format(calendar.getTime());
int i = userService.queryUserCount(1, dateTime, null, null);
int i = userService.queryUserCount(1, dateTime,null,null);
userCountList.add(i);
year.add(dateTime);
if (dateTime.equals(endTime)) {
if(dateTime.equals(endTime)){
break;
}
calendar.add(Calendar.DATE, 1);
calendar.add(Calendar.DATE,1);
}
Map<String, Object> result = new HashMap<>();
result.put("userCountList", userCountList);
result.put("year", year);
return Result.success().put("data", result);
Map<String,Object> result=new HashMap<>();
result.put("userCountList",userCountList);
result.put("year",year);
return Result.success().put("data",result);
}
@ApiOperation("更新用户邀请奖励金额")
@RequestMapping(value = "/inviteAmount", method = RequestMethod.POST)
@ResponseBody
public Result updateUserInviteAmount(@RequestBody UserInviteDTO userInviteDTO) {
return userService.updateUserInviteAmount(userInviteDTO);
}
}
}

View File

@ -3,7 +3,6 @@ package com.sqx.modules.app.controller;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.service.UserMoneyDetailsService;
import com.sqx.modules.app.service.UserMoneyService;
import com.sqx.modules.sys.service.SysUserMoneyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
@ -14,17 +13,16 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/moneyDetails")
@AllArgsConstructor
@Api(value = "钱包明细", tags = {"钱包明细"})
@Api("钱包明细")
public class UserMoneyDetailsController {
private UserMoneyDetailsService userMoneyDetailsService;
private UserMoneyService userMoneyService;
private SysUserMoneyService sysUserMoneyService;
@ApiOperation("钱包明细")
@GetMapping("/queryUserMoneyDetails")
public Result queryUserMoneyDetails(Integer page, Integer limit,Long sysUserId, Long userId,Integer classify,Integer type, Integer moneyType) {
return userMoneyDetailsService.queryUserMoneyDetails(page, limit, sysUserId, userId,classify,type, moneyType, 0);
public Result queryUserMoneyDetails(Integer page, Integer limit,Long sysUserId, Long userId,Integer classify,Integer type) {
return userMoneyDetailsService.queryUserMoneyDetails(page, limit, sysUserId, userId,classify,type);
}
@GetMapping("/selectUserMoney")
@ -36,7 +34,7 @@ public class UserMoneyDetailsController {
@GetMapping("/selectSysUserMoney")
@ApiOperation("代理钱包")
public Result selectSysUserMoney(Long userId){
return Result.success().put("data",sysUserMoneyService.selectSysUserMoneyByUserId(userId));
return Result.success().put("data",userMoneyService.selectSysUserMoneyByUserId(userId));
}

View File

@ -1,8 +1,6 @@
package com.sqx.modules.app.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
@ -18,7 +16,6 @@ import org.springframework.web.bind.annotation.*;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
@RestController
@Api(value = "会员管理", tags = {"会员管理"})
@ -92,10 +89,7 @@ public class VipDetailsController {
@ApiParam("查询会员列表")
@GetMapping("/selectVipDetailsList")
public Result selectVipDetailsList(Integer page,Integer limit) {
PageHelper.startPage(page,limit);
List<VipDetails> list = vipDetailsService.list();
PageInfo<VipDetails> pageInfo = new PageInfo<>(list);
return Result.success().put("data", PageUtils.page(pageInfo));
return Result.success().put("data",new PageUtils(vipDetailsService.page(new Page<>(page,limit))));
}
}

View File

@ -1,43 +0,0 @@
package com.sqx.modules.app.controller.app;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.app.service.AdService;
import com.sqx.modules.callback.service.UniAdCallbackRecordService;
import com.sqx.modules.redisService.RedisService;
import com.sqx.modules.sys.controller.AbstractController;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
@RestController
@RequestMapping("/app/ad")
public class AdController extends AbstractController {
private final UniAdCallbackRecordService callbackRecordService;
private final AdService adService;
private final RedisService redisService;
public AdController(UniAdCallbackRecordService callbackRecordService, AdService adService, RedisService redisService) {
this.callbackRecordService = callbackRecordService;
this.adService = adService;
this.redisService = redisService;
}
@Login
@GetMapping("/state")
public Result getAdState(@RequestParam String extraKey, @RequestAttribute Long userId) {
HashMap<String, Integer> info = callbackRecordService.getStateByExtraKey(userId, extraKey);
if (info.get("isEnded") == 0 && !redisService.isCanCash(userId) && extraKey.contains("cash")) {
redisService.setCanCashFlag(userId, -1L);
info.put("isEnded", 1);
}
return Result.success();
}
@Login
@GetMapping("/detail")
public Result getAdDetail(@RequestAttribute Long userId) {
return Result.success(adService.getDetail(userId));
}
}

View File

@ -1,34 +0,0 @@
package com.sqx.modules.app.controller.app;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.sqx.common.utils.Result;
import com.sqx.modules.announcement.entity.Announcement;
import com.sqx.modules.announcement.service.AnnouncementService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/app/announcement")
public class AppAnnouncementController {
private final AnnouncementService announcementService;
public AppAnnouncementController(AnnouncementService announcementService) {
this.announcementService = announcementService;
}
@GetMapping
public Result get(@RequestParam(defaultValue = "0") Integer type) {
List<Announcement> list = announcementService.list(new LambdaQueryWrapper<Announcement>()
.eq(Announcement::getType, type)
.eq(Announcement::getState, 1)
.orderByDesc(Announcement::getCreateTime));
return Result.success().put("data", list);
}
}

View File

@ -1,82 +1,45 @@
package com.sqx.modules.app.controller.app;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
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.toolkit.Wrappers;
import com.sqx.common.annotation.Debounce;
import com.sqx.common.annotation.Limiting;
import com.sqx.common.utils.ApiAccessLimitUtil;
import com.sqx.common.utils.DataLimitUtil;
import com.sqx.common.utils.DesensitizedUtil;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.app.annotation.LoginUser;
import com.sqx.modules.app.dto.AuthDTO;
import com.sqx.modules.app.dto.AuthRespDTO;
import com.sqx.modules.app.entity.TbUserBlacklist;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserInfo;
import com.sqx.modules.app.mapper.TbUserBlacklistMapper;
import com.sqx.modules.app.service.AliService;
import com.sqx.modules.app.service.AppService;
import com.sqx.modules.app.service.UserInfoService;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.common.service.CommonInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;
import java.util.regex.Pattern;
/**
* APP登录授权
*
* @author mac
*/
@RestController
@RequestMapping("/app/user")
@Api(value = "APP管理", tags = {"APP管理"})
@Slf4j
public class AppController {
@Autowired
private UserService userService;
@Autowired
private AppService appService;
@Autowired
private CommonInfoService commonRepository;
private final UserInfoService userInfoService;
private final AliService aliService;
@Autowired
private TbUserBlacklistMapper tbUserBlacklistMapper;
public AppController(UserInfoService userInfoService, AliService aliService) {
this.userInfoService = userInfoService;
this.aliService = aliService;
}
@PostMapping("/authenticationRegister")
@ApiOperation("认证创建账号")
public Result authenticationRegister(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
return userService.authenticationRegister(jsonObject, request);
public Result authenticationRegister(@RequestBody JSONObject jsonObject, HttpServletRequest request){
return userService.authenticationRegister(jsonObject,request);
}
@Login
@PostMapping("/getNewUserRed")
@ApiOperation("领取新用户红包")
public Result getNewUserRed(@RequestAttribute Long userId) {
public Result getNewUserRed(@RequestAttribute Long userId){
return userService.getNewUserRed(userId);
}
@ -84,15 +47,15 @@ public class AppController {
@RequestMapping(value = "/updatePwd", method = RequestMethod.POST)
@ResponseBody
@ApiOperation("用户端修改密码")
public Result updatePwd(@LoginUser UserEntity user, String pwd, String oldPwd) {
if (!user.getPassword().equals(DigestUtils.sha256Hex(oldPwd))) {
public Result updatePwd(@LoginUser UserEntity user,String pwd,String oldPwd) {
if(!user.getPassword().equals(DigestUtils.sha256Hex(oldPwd))){
return Result.error("原始密码不正确!");
}
if (pwd.equals(oldPwd)) {
if(pwd.equals(oldPwd)){
return Result.error("新密码不能与旧密码相同!");
}
user.setPassword(DigestUtils.sha256Hex(pwd));
userService.update(user, new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getUserId, user.getUserId()));
userService.updateById(user);
return Result.success();
}
@ -100,182 +63,58 @@ public class AppController {
@RequestMapping(value = "/updatePhone", method = RequestMethod.POST)
@ApiOperation("用户端换绑手机号")
@ResponseBody
public Result updatePhone(@RequestAttribute("userId") Long userId, @RequestParam String phone, @RequestParam String msg) {
return userService.updatePhone(phone, msg, userId);
public Result updatePhone(@RequestAttribute("userId") Long userId,@RequestParam String phone, @RequestParam String msg) {
return userService.updatePhone(phone, msg,userId);
}
@Login
@RequestMapping(value = "/bindAlipay", method = RequestMethod.POST)
@ApiOperation("绑定支付宝")
@RequestMapping(value = "/updateUser", method = RequestMethod.POST)
@ApiOperation("用户修改个人信息")
@ResponseBody
@Debounce(interval = 3000, value = "#userId")
public Result bindAlipay(@RequestAttribute("userId") Long userId,
@RequestParam String zhiFuBao,
@RequestParam String certName
) {
if (StrUtil.isAllBlank(zhiFuBao, certName)) {
return Result.error("支付宝账号或姓名不能为空");
}
if (zhiFuBao.contains("*") || certName.contains("*")) {
return Result.success();
}
UserEntity userEntity = userService.getById(userId);
if (zhiFuBao.equals(userEntity.getZhiFuBao()) && certName.equals(userEntity.getZhiFuBaoName())) {
return Result.success();
}
int count = userService.count(new QueryWrapper<UserEntity>()
.ne("user_id", userId)
.eq("zhi_fu_bao_name", certName)
.eq("zhi_fu_bao", zhiFuBao));
if (count > 0) {
return Result.error("支付宝信息修改失败: 此支付宝账号已被绑定");
}
UserInfo userInfo = userInfoService.getByUserId(userId);
if (userInfo != null) {
if (StrUtil.isNotBlank(userInfo.getCertName()) && !certName.equals(userInfo.getCertName())) {
return Result.error("支付宝信息修改失败: 姓名与实名认证信息不相符");
}
}
if (!DataLimitUtil.isAccessAllowed(zhiFuBao + certName, Integer.parseInt(commonRepository.findOne(924).getValue()), "month")) {
return Result.error("支付宝信息修改失败: 相同支付宝账号每月可绑定次数已用完");
}
if (!ApiAccessLimitUtil.isAccessAllowed(userId.toString(), "updateZFB", Integer.parseInt(commonRepository.findOne(925).getValue()), "month")) {
return Result.error("支付宝信息修改失败: 每月可修改次数已用完,请联系管理员");
}
public Result updateUserImageUrl(@RequestAttribute("userId") Long userId,String zhiFuBao,String zhiFuBaoName) {
UserEntity userEntity=new UserEntity();
userEntity.setZhiFuBao(zhiFuBao);
userEntity.setZhiFuBaoName(certName);
userService.update(userEntity, new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getUserId, userId));
userEntity.setZhiFuBaoName(zhiFuBaoName);
userEntity.setUserId(userId);
userService.updateById(userEntity);
return Result.success();
}
@Login
@PostMapping(value = "/realNameAuth/v2")
@ApiOperation("实名认证")
@ResponseBody
@Debounce(interval = 60000, value = "#auth.certNum")
@Limiting
public Result realNameAuth(@RequestAttribute("userId") Long userId, @RequestBody AuthDTO auth) {
return realNameAuth(userId, auth.getCertName(), auth.getCertNum(), auth.getAccountNo(), auth.getMobile(), auth.getProvince(), auth.getCity(), auth.getBankBranch());
}
@Login
@RequestMapping(value = "/realNameAuth", method = RequestMethod.POST)
@ApiOperation("实名认证")
@ResponseBody
@Debounce(interval = 3000, value = "#userId")
@Limiting
public Result realNameAuth(@RequestAttribute("userId") Long userId,
@RequestParam String certName,
@RequestParam String certNum,
@RequestParam String accountNo,
@RequestParam String mobile,
@RequestParam String province,
@RequestParam String city,
@RequestParam String bankBranch
) {
// 判断身份证号是否有空格
if (certNum.contains(" ")) {
userService.addBlackUser(userId, "恶意实名");
log.warn("恶意实名认证: {}", userId);
return Result.success();
}
// 定义正则表达式匹配只包含数字Xx * 的字符串
String regex = "^[0-9Xx*]+$";
if (!Pattern.matches(regex, certNum)) {
userService.addBlackUser(userId, "恶意实名2");
log.warn("恶意实名认证2: {}", userId);
return Result.success();
}
certNum = certNum.trim();
if (StrUtil.isAllBlank(certName, certNum, accountNo, mobile)) {
return Result.error("真实姓名、身份证号码、银行卡号、银行预留手机号缺一不可");
}
/*if (StrUtil.isAllBlank(province, city, bankBranch)) {
return Result.error("省、市、开户行缺一不可");
}*/
// 已完成实名认证补充开户行等信息
if (certNum.contains("*") || accountNo.contains("*") || mobile.contains("*")) {
/*userInfoService.update(null, Wrappers.<UserInfo>lambdaUpdate()
.set(UserInfo::getProvince, province)
.set(UserInfo::getCity, city)
.set(UserInfo::getBankBranch, bankBranch)
.set(UserInfo::getUpdateTime, new Date())
.eq(UserInfo::getUserId, userId));*/
return Result.success();
}
int count = userInfoService.count(Wrappers.<UserInfo>lambdaQuery()
.eq(UserInfo::getUserId, userId)
);
if (count > 0) {
return Result.error("已完成实名认证,无需重复操作");
}
// 查询现在库里面姓名+身份证号认证过的用户数量
count = userInfoService.count(Wrappers.<UserInfo>lambdaQuery()
.eq(UserInfo::getCertName, certName)
.eq(UserInfo::getCertNo, certNum)
);
if (count >= 3) {
return Result.error("实名认证失败: 1个身份证号码最多绑定3个账号");
}
if (!ApiAccessLimitUtil.getCertAuthIsAccessAllowed(String.valueOf(userId), "updateAuthCertInfo", 5)) {
return Result.error("实名修改失败: 每月可修改次数已用完,请联系管理员");
}
log.info("阿里云四要素认证请求参数userId:{} {} {} {} {}", userId, certName, certNum, accountNo, mobile);
AuthRespDTO resp = aliService.auth(certName, certNum, accountNo, mobile);
UserInfo userInfo = userInfoService.getByUserIdOrSave(userId);
userInfo.setCertName(certName);
userInfo.setCertNo(certNum);
userInfo.setAccountNo(accountNo);
userInfo.setMobile(mobile);
userInfo.setBankName(resp.getBankName());
userInfo.setProvince(province);
userInfo.setCity(city);
userInfo.setBankBranch(bankBranch);
userInfo.setRespJson(resp.getRespJson());
userInfo.setUpdateTime(DateUtil.date());
boolean update = userInfoService.update(userInfo, new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserId, userId).eq(UserInfo::getId, userInfo.getId()));
if (!update) {
return Result.error("实名修改失败: 请稍后重试");
}
ApiAccessLimitUtil.setCertAuthIsAccessAllowed(String.valueOf(userId), "updateAuthCertInfo", 1, "month");
// 校验实名信息是否在黑名单里面
count = tbUserBlacklistMapper.selectCount(new LambdaQueryWrapper<TbUserBlacklist>().eq(TbUserBlacklist::getIdCardNo, certNum));
if (count > 0) {
UserEntity userEntity = userService.getById(userId);
userEntity.setStatus(0);
userEntity.setPlatform("异常行为用户:实名信息异常 在黑名单");
userService.update(userEntity, new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getUserId, userId));
log.warn("异常行为用户:实名信息异常: {}", userId);
return Result.error("异常行为: 您的实名信息存在异常行为");
}
return Result.success();
}
@Login
@RequestMapping(value = "/updateUsers", method = RequestMethod.POST)
@ApiOperation("用户修改个人信息")
@ResponseBody
public Result updateUsers(@RequestAttribute("userId") Long userId, @RequestBody UserEntity userEntity) {
public Result updateUsers(@RequestAttribute("userId") Long userId,@RequestBody UserEntity userEntity) {
userEntity.setUserId(userId);
userService.update(null, Wrappers.<UserEntity>lambdaUpdate().eq(UserEntity::getUserId, userId)
.set(StrUtil.isNotBlank(userEntity.getAvatar()), UserEntity::getAvatar, userEntity.getAvatar())
.set(StrUtil.isNotBlank(userEntity.getUserName()), UserEntity::getUserName, userEntity.getUserName())
);
userService.updateById(userEntity);
return Result.success();
}
/*@Login
@RequestMapping(value = "/updateUsers", method = RequestMethod.POST)
@ApiOperation("用户修改个人信息")
@ResponseBody
public Result updateUsers(@RequestAttribute("userId") Long userId,String userName,String avatar,String phone) {
UserEntity userEntity=new UserEntity();
userEntity.setUserId(userId);
userEntity.setUserName(userName);
userEntity.setAvatar(avatar);
userEntity.setPhone(phone);
userService.updateById(userEntity);
return Result.success();
}*/
@Login
@RequestMapping(value = "/updateUserImageUrl", method = RequestMethod.POST)
@ApiOperation("用户修改头像")
@ResponseBody
public Result updateUserImageUrl(@LoginUser UserEntity user, String avatar) {
public Result updateUserImageUrl(@LoginUser UserEntity user,String avatar) {
user.setAvatar(avatar);
userService.update(user, new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getUserId, user.getUserId()));
userService.updateById(user);
return Result.success();
}
@ -283,9 +122,9 @@ public class AppController {
@RequestMapping(value = "/updateUserName", method = RequestMethod.POST)
@ApiOperation("用户修改昵称")
@ResponseBody
public Result updateUserName(@LoginUser UserEntity user, String userName) {
public Result updateUserName(@LoginUser UserEntity user,String userName) {
user.setUserName(userName);
userService.update(user, new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getUserId, user.getUserId()));
userService.updateById(user);
return Result.success();
}
@ -293,33 +132,8 @@ public class AppController {
@RequestMapping(value = "/selectUserById", method = RequestMethod.GET)
@ApiOperation("获取用户详细信息")
@ResponseBody
@Limiting
public Result selectUserById(@LoginUser UserEntity user) {
UserInfo userInfo = userInfoService.getByUserId(user.getUserId());
userInfo.setRespJson(null);
if (StrUtil.isNotEmpty(userInfo.getAccountNo())) {
userInfo.setAccountNo(DesensitizedUtil.bankCard(userInfo.getAccountNo()));
}
if (StrUtil.isNotEmpty(userInfo.getMobile())) {
userInfo.setMobile(DesensitizedUtil.mobilePhone(userInfo.getMobile()));
}
if (StrUtil.isNotEmpty(userInfo.getCertNo())) {
userInfo.setCertNo(DesensitizedUtil.idCardNum(userInfo.getCertNo(), 3, 2));
}
if (StrUtil.isNotEmpty(user.getZhiFuBao())) {
if (Validator.isEmail(user.getZhiFuBao())) {
user.setZhiFuBao(DesensitizedUtil.email(user.getZhiFuBao()));
} else {
user.setZhiFuBao(DesensitizedUtil.mobilePhone(user.getZhiFuBao()));
}
}
Map<String, Object> map = BeanUtil.beanToMap(user);
map.putAll(BeanUtil.beanToMap(userInfo));
map.put("userId", map.get("userId").toString());
if (StrUtil.isBlank(user.getZhiFuBaoName()) && StrUtil.isNotBlank(userInfo.getCertName())) {
map.put("zhiFuBaoName", userInfo.getCertName());
}
return Result.success().put("data", map);
return Result.success().put("data",user);
}
@ -327,36 +141,26 @@ public class AppController {
@ApiOperation("升级检测")
@ResponseBody
public Result selectNewApp() {
return Result.success().put("data", appService.selectNewApp());
return Result.success().put("data",appService.selectNewApp());
}
@GetMapping("/openId/{code:.+}/{userId}")
@ApiOperation("根据code获取openid")
public Result getOpenid(@PathVariable("code") String code, @PathVariable("userId") Long userId) {
return userService.getOpenId(code, userId);
public Result getOpenid(@PathVariable("code") String code,@PathVariable("userId")Long userId) {
return userService.getOpenId(code,userId);
}
@RequestMapping(value = "/updateClientId", method = RequestMethod.GET)
@ApiOperation("绑定ClientId")
@ResponseBody
public Result updateClientId(String clientId, Long userId, Integer sysPhone) {
public Result updateClientId(String clientId,Long userId,Integer sysPhone ) {
userService.updateUserClientIdIsNull(clientId);
UserEntity userEntity = new UserEntity();
UserEntity userEntity=new UserEntity();
userEntity.setSysPhone(sysPhone);
userEntity.setUserId(userId);
userEntity.setClientid(clientId);
userService.update(userEntity, new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getUserId, userId));
userService.updateById(userEntity);
return Result.success();
}
@Login
@RequestMapping(value = "/deleteUser", method = RequestMethod.POST)
@ApiOperation("删除用户")
@ResponseBody
public Result deleteUserByUserId(@RequestAttribute("userId") Long userId) {
userService.removeById(userId);
return Result.success();
}
}

View File

@ -1,15 +1,9 @@
package com.sqx.modules.app.controller.app;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sqx.common.annotation.Debounce;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.app.dto.BindWxDTO;
import com.sqx.modules.app.dto.LoginDTO;
import com.sqx.modules.app.dto.RegisterDTO;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.service.IAppleService;
import com.sqx.modules.app.service.UserService;
@ -24,13 +18,10 @@ import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import weixin.popular.api.SnsAPI;
import weixin.popular.bean.sns.SnsToken;
import java.util.HashMap;
/**
* APP登录授权
*
@ -150,48 +141,13 @@ public class AppLoginController {
@RequestMapping(value = "/registerCode", method = RequestMethod.POST)
@ApiOperation("app或h5注册或登录")
@ResponseBody
@Debounce(interval = 2500, value = "#phone")
public Result registerCode(@RequestParam String phone,String msg,String platform,Integer sysPhone,
String password,String inviterCode,String wxId,String qdCode) {
return userService.registerCode(phone,msg,platform,sysPhone,password,inviterCode,wxId,qdCode);
}
@PostMapping
@ResponseBody
@Debounce(interval = 2500, value = "#phone")
public Result login(@RequestBody @Validated LoginDTO loginDTO) {
return userService.login(loginDTO);
}
@PostMapping(value = "/register")
@ApiOperation("app或h5注册或登录")
@ResponseBody
@Debounce(interval = 2500, value = "#phone")
public Result register(@RequestBody RegisterDTO registerDTO) {
return userService.register(registerDTO);
}
@Login
@PostMapping("/bindWx")
@ResponseBody
@Debounce(interval = 2500, value = "#code")
public Result bindWx(@RequestBody BindWxDTO bindWxDTO, @RequestAttribute("userId") Long userId) {
return userService.bindWx(bindWxDTO, userId);
}
@Login
@GetMapping("/bindStatus")
@ResponseBody
public Result bindWx(@RequestAttribute("userId") Long userId) {
UserEntity userEntity = userService.queryByUserId(userId);
return Result.success(new HashMap<String, Object>(){{
put("data", new HashMap<String, Object>(){{
put("wxBind", StrUtil.isNotBlank(userEntity.getWxOpenId()));
}});
}});
}
@PostMapping("/bindWxOpenPhone")
@ApiOperation("微信公众号绑定手机号")
public Result bindWxOpenPhone(Long userId,String phone,String msg){
@ -253,4 +209,10 @@ public class AppLoginController {
return userService.loginByOpenId(openId);
}
}

View File

@ -1,7 +1,5 @@
package com.sqx.modules.app.controller.app;
import com.sqx.common.annotation.Debounce;
import com.sqx.common.annotation.Limiting;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.app.service.UserMoneyDetailsService;
@ -17,7 +15,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/app/moneyDetails")
@AllArgsConstructor
@Api(value = "钱包明细app版本", tags = {"钱包明细app版本"})
@Api("钱包明细")
public class AppUserMoneyDetailsController {
private UserMoneyDetailsService userMoneyDetailsService;
@ -27,18 +25,13 @@ public class AppUserMoneyDetailsController {
@Login
@ApiOperation("钱包明细")
@GetMapping("/queryUserMoneyDetails")
@Limiting
@Debounce(interval = 3000, value = "#userId")
public Result queryUserMoneyDetails(Integer page, Integer limit, @RequestAttribute Long userId,Integer classify,
Integer type, Integer moneyType, Integer viewType) {
return userMoneyDetailsService.queryUserMoneyDetails(page, limit,null, userId,classify,type, moneyType ,viewType);
public Result queryUserMoneyDetails(Integer page, Integer limit, @RequestAttribute Long userId,Integer classify,Integer type) {
return userMoneyDetailsService.queryUserMoneyDetails(page, limit,null, userId,1,type);
}
@Login
@GetMapping("/selectUserMoney")
@ApiOperation("我的钱包")
// @Debounce(interval = 3000, value = "#userId")
// @Limiting
public Result selectUserMoney(@RequestAttribute Long userId){
return Result.success().put("data",userMoneyService.selectUserMoneyByUserId(userId));
}

View File

@ -1,51 +0,0 @@
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

@ -1,13 +1,14 @@
package com.sqx.modules.app.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.modules.app.entity.UserEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 用户
@ -16,13 +17,11 @@ import java.util.Set;
public interface UserDao extends BaseMapper<UserEntity> {
List<UserEntity> selectUserPage(@Param("search") String search, @Param("sex") Integer sex, @Param("platform") String platform,
IPage<UserEntity> selectUserPage(@Param("page") Page<UserEntity> page, @Param("search") String search, @Param("sex") Integer sex, @Param("platform") String platform,
@Param("sysPhone") String sysPhone, @Param("status") Integer status, @Param("member") Integer member,
@Param("inviterCode") String inviterCode, @Param("userName") String userName,
@Param("invitationCode") String invitationCode, @Param("startTime") String startTime,
@Param("endTime") String endTime,@Param("qdCode") String qdCode,
@Param("sysUserName") String sysUserName, @Param("vipType") Integer vipType,
@Param("delegate") Integer delegate);
@Param("endTime") String endTime,@Param("qdCode") String qdCode,@Param("sysUserName") String sysUserName,Integer vipType);
List<UserEntity> userListExcel(@Param("startTime") String startTime, @Param("endTime") String endTime, @Param("userEntity") UserEntity userEntity);
@ -32,18 +31,17 @@ public interface UserDao extends BaseMapper<UserEntity> {
Double queryPayMoney(@Param("type") int type, @Param("date") String date,String qdCode);
List<Map<String, Object>> queryCourseOrder(@Param("type") int type, @Param("start") String start, @Param("end") String end,Long sysUserId);
IPage<Map<String, Object>> queryCourseOrder(Page iPage,@Param("type") int type, @Param("date") String date,Long sysUserId);
int userMessage( String date, int type,String qdCode,Integer vipType);
int insertUser(UserEntity userEntity);
List<UserEntity> selectInviteUserList(@Param("queryUserIdList") Set<Long> queryUserIdList);
IPage<UserEntity> selectInviteUserList(Page<UserEntity> page,String userName,String phone);
int selectUserOnLineCount(String qdCode);
int updateUserClientIdIsNull(String clientid);
Map<String, Object> queryPayInfo(@Param("start") String start, @Param("end") String end);
Map<String, Object> queryExtractInfo(@Param("start") String start, @Param("end") String end);
}

View File

@ -3,27 +3,14 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sqx.modules.app.entity.UserMoney;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.math.BigDecimal;
@Mapper
public interface UserMoneyDao extends BaseMapper<UserMoney> {
void updateMayMoney(@Param("type") Integer type, @Param("userId")Long userId, @Param("money") Double money);
void updateMayAmount(@Param("type") Integer type, @Param("userId")Long userId, @Param("amount") Double amount);
void updateMayAmount(@Param("type") Integer type, @Param("userId")Long userId, @Param("money") Double amount);
@Select("select sum(money) from user_money_details where user_id=#{userId} and classify in (6,1) and (content like '%额外奖励金币%' or content like '获取金币')")
BigDecimal sumMoney(Long userId);
void updateSysMoney(@Param("type") Integer type, @Param("sysUserId")Long sysUserId, @Param("money") Double money);
@Select("select sum(money) from user_money_details where user_id=#{userId} and classify=6 and content like '%额外奖励现金红包%'")
BigDecimal sumMoney2(Long userId);
@Update("update user_money set amount=amount+#{money} where user_id=#{userId}")
Boolean incrMoney(@Param("money") String money, @Param("userId") Long userId);
@Update("update user_money set amount=amount-#{money} where user_id=#{userId}")
Boolean decrMoney(@Param("money") String money, @Param("userId") Long userId);
}

View File

@ -4,21 +4,10 @@ import com.sqx.modules.app.entity.UserMoneyDetails;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Map;
@Mapper
public interface UserMoneyDetailsDao extends BaseMapper<UserMoneyDetails> {
Double monthIncome(@Param("date") String date,@Param("userId") Long userId);
/**
* 查询用户邀请收益
*/
Double queryUserInviteMoney(@Param("userId") Long userId);
/**
* 查询用户邀请金币
*/
Double queryUserInviteGoldMoney(@Param("userId") Long userId);
}

View File

@ -1,15 +0,0 @@
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

@ -1,13 +0,0 @@
package com.sqx.modules.app.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class AuthCertNoDTO {
@NotBlank
private String name;
@NotBlank
private String idNum;
}

View File

@ -1,31 +0,0 @@
package com.sqx.modules.app.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class AuthDTO {
@NotBlank
private String name;
@NotBlank
private String idNum;
@NotBlank
private String certName;
@NotBlank
private String certNum;
@NotBlank
private String accountNo;
@NotBlank
private String mobile;
@NotBlank
private String province;
@NotBlank
private String city;
@NotBlank
private String bankBranch;
}

View File

@ -1,13 +0,0 @@
package com.sqx.modules.app.dto;
import lombok.Data;
/**
* @author tankaikai
* @since 2025-01-09 10:37
*/
@Data
public class AuthRespDTO {
private String respJson;
private String bankName;
}

View File

@ -1,14 +0,0 @@
package com.sqx.modules.app.dto;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
/**
* @author Administrator
*/
@Data
public class BindWxDTO {
@NotEmpty(message = "code不能为空")
private String code;
}

View File

@ -1,13 +0,0 @@
package com.sqx.modules.app.dto;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
@Data
public class LoginDTO {
@NotEmpty
private String phone;
@NotEmpty
private String password;
}

View File

@ -1,20 +0,0 @@
package com.sqx.modules.app.dto;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
@Data
public class RegisterDTO {
@NotEmpty
private String phone;
@NotEmpty
private String password;
@NotEmpty
private String msg;
@NotEmpty
private String platform;
private String inviterCode;
private String qdCode;
private Integer sysPhone;
}

View File

@ -1,14 +0,0 @@
package com.sqx.modules.app.dto;
import lombok.Data;
import java.math.BigDecimal;
/**
* @author GYJoker
*/
@Data
public class UserInviteDTO {
private String userId;
private BigDecimal inviteAmount;
}

View File

@ -2,8 +2,6 @@ package com.sqx.modules.app.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.io.Serializable;
@ -15,7 +13,6 @@ import java.io.Serializable;
@TableName("app")
public class App implements Serializable {
@TableId
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private String createAt;

View File

@ -1,73 +0,0 @@
package com.sqx.modules.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.io.Serializable;
import java.util.Date;
/**
*
* @TableName invite_achievement
*/
@TableName(value ="invite_achievement")
@Data
@EqualsAndHashCode
@ToString
public class InviteAchievement implements Serializable {
/**
*
*/
@TableId(type = IdType.ID_WORKER)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 邀请用户用户id -- 上级
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long userId;
/**
* 下级被邀请用户id 当前达标用户id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long targetUserId;
/**
* 达标次数
*/
private Integer count;
/**
* 已领取奖励次数
*/
private Integer giveAwardCount;
/**
* 是否首次达标
*/
private Integer state;
/**
* 一次性任务领取记录 默认为空 存储为 taskId,taskId
*/
private String tasks;
/**
* 创建时间
*/
private Date createTime;
private Date updateTime;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -2,8 +2,6 @@ package com.sqx.modules.app.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.io.Serializable;
@ -19,7 +17,6 @@ public class Msg implements Serializable {
private static final long serialVersionUID = 1L;
@TableId
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private String code;

View File

@ -1,28 +0,0 @@
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;
/**
* 用户黑名单
* @author tankaikai
* @since 2025-01-07 12:56
*/
@Data
@TableName(value ="tb_user_blacklist")
public class TbUserBlacklist implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type=IdType.AUTO)
private Long id;
private String idCardNo;
private String realName;
}

View File

@ -1,25 +0,0 @@
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;
/**
* 提现黑名单表
* @author tankaikai
* @since 2025-01-07 12:56
*/
@Data
@TableName(value ="tb_withdraw_blacklist")
public class TbWithdrawBlacklist implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type=IdType.AUTO)
private Long id;
private String realName;
}

View File

@ -11,7 +11,7 @@ public class UserDetails {
*/
private int monthlyOrderNum;
/**
* 本月充值金
* 本月充值金
*/
private BigDecimal monthlyRechargeMoney;
/**
@ -19,7 +19,7 @@ public class UserDetails {
*/
private int monthWithdrawalNum;
/**
* 本月提现金
* 本月提现金
*/
private BigDecimal monthlyWithdrawalMoney;

View File

@ -5,8 +5,6 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -17,212 +15,188 @@ import java.math.BigDecimal;
/**
* 用户
*
*/
@Data
@ApiModel("用户")
@TableName("tb_user")
public class UserEntity implements Serializable {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
@Excel(name = "用户id", orderNum = "1")
@ApiModelProperty("用户id")
@TableId(type = IdType.ID_WORKER)
@JsonSerialize(using = ToStringSerializer.class)
private Long userId;
/**
* 用户名
*/
@Excel(name = "用户昵称", orderNum = "2")
@ApiModelProperty("用户名")
@TableField("user_name")
private String userName;
/**
* 用户ID
*/
@Excel(name = "用户id", orderNum = "1")
@ApiModelProperty("用户id")
@TableId(type = IdType.AUTO, value = "user_id")
private Long userId;
/**
* 用户名
*/
@Excel(name = "用户昵称", orderNum = "2")
@ApiModelProperty("用户名")
@TableField("user_name")
private String userName;
/**
* 手机号
*/
@Excel(name = "手机号", orderNum = "4")
@ApiModelProperty("手机号")
private String phone;
/**
* 手机号
*/
@Excel(name = "手机号", orderNum = "4")
@ApiModelProperty("手机号")
private String phone;
/**
* 头像
*/
@Excel(name = "头像", orderNum = "3")
@ApiModelProperty("头像")
private String avatar;
/**
* 头像
*/
@Excel(name = "头像", orderNum = "3")
@ApiModelProperty("头像")
private String avatar;
/**
* 性别 1男 2女
*/
@ApiModelProperty("性别 1男 2女")
private Integer sex;
/**
* 性别 1男 2女
*/
@ApiModelProperty("性别 1男 2女")
private Integer sex;
/**
* 微信小程序openid
*/
@ApiModelProperty("微信小程序openid")
@TableField("open_id")
private String openId;
/**
* 微信小程序openid
*/
@ApiModelProperty("微信小程序openid")
@TableField("open_id")
private String openId;
/**
* 微信小程序openid
*/
@ApiModelProperty("微信公众号openid")
@TableField("wx_id")
private String wxId;
/**
* 微信小程序openid
*/
@ApiModelProperty("微信公众号openid")
@TableField("wx_id")
private String wxId;
/**
* 微信app openid
*/
@ApiModelProperty("微信app openid")
@TableField("wx_open_id")
private String wxOpenId;
/**
* 微信app openid
*/
@ApiModelProperty("微信app openid")
@TableField("wx_open_id")
private String wxOpenId;
/**
* 抖音小程序openId
*/
private String dyOpenId;
/**
* 抖音小程序openId
*/
private String dyOpenId;
/**
* 快手小程序openId
*/
private String ksOpenId;
/**
* 快手小程序openId
*/
private String ksOpenId;
/**
* 密码
*/
private String password;
/**
* 密码
*/
private String password;
/**
* 创建时间
*/
@Excel(name = "创建时间", orderNum = "13", width = 18)
@TableField("create_time")
private String createTime;
/**
* 创建时间
*/
@Excel(name = "创建时间", orderNum = "13", width = 18)
@TableField("create_time")
private String createTime;
/**
* 更新时间
*/
@TableField("update_time")
private String updateTime;
/**
* 更新时间
*/
@TableField("update_time")
private String updateTime;
/**
* 苹果id
*/
@TableField("apple_id")
private String appleId;
/**
* 苹果id
*/
@TableField("apple_id")
private String appleId;
/**
* 手机类型 1安卓 2ios
*/
@TableField("sys_phone")
private Integer sysPhone;
/**
* 手机类型 1安卓 2ios
*/
@TableField("sys_phone")
private Integer sysPhone;
/**
* 状态 1正常 2禁用
*/
@Excel(name = "状态", orderNum = "13", replace = {"正常_1", "禁用_1"})
private Integer status;
/**
* 状态 1正常 2禁用
*/
@Excel(name = "状态", orderNum = "13", replace = {"正常_1", "禁用_1"})
private Integer status;
/**
* 来源 app 小程序 公众号
*/
@Excel(name = "渠道来源", orderNum = "9")
@TableField(select = false)
private String platform;
/**
* 来源 app 小程序 公众号
*/
@Excel(name = "渠道来源", orderNum = "9")
private String platform;
/**
* 积分
*/
private Integer jifen;
/**
* 积分
*/
private Integer jifen;
/**
* 邀请码
*/
@Excel(name = "邀请码", orderNum = "5")
@TableField("invitation_code")
private String invitationCode;
/**
* 邀请码
*/
@Excel(name = "邀请码", orderNum = "5")
@TableField("invitation_code")
private String invitationCode;
/**
* 邀请人邀请码
*/
@Excel(name = "邀请人邀请码", orderNum = "6", width = 15)
@TableField("inviter_code")
private String inviterCode;
/**
* 邀请人邀请码
*/
@Excel(name = "邀请人邀请码", orderNum = "6",width = 15)
@TableField("inviter_code")
private String inviterCode;
private String clientid;
private String clientid;
@Excel(name = "支付宝账号", orderNum = "8", width = 18)
private String zhiFuBao;
@Excel(name = "支付宝账号", orderNum = "8", width = 18)
private String zhiFuBao;
@Excel(name = "支付宝名称", orderNum = "8", width = 18)
@TableField("zhi_fu_bao_name")
private String zhiFuBaoName;
@Excel(name = "支付宝名称", orderNum = "8", width = 18)
private String zhiFuBaoName;
@Excel(name = "一级推广收益比例", orderNum = "8", width = 18)
private BigDecimal rate;
@Excel(name = "一级推广收益比例", orderNum = "8", width = 18)
private BigDecimal rate;
@Excel(name = "二级推广收益比例", orderNum = "8", width = 18)
private BigDecimal twoRate;
@Excel(name = "二级推广收益比例", orderNum = "8", width = 18)
private BigDecimal twoRate;
/**
* 最后一次在线时间
*/
private String onLineTime;
/**
* 最后一次在线时间
*/
private String onLineTime;
/**
* 渠道码
*/
private String qdCode;
/**
* 渠道码
*/
private String qdCode;
/**
* 邀请人id
*/
private Long inviterUserId;
/**
* 是否是新用户 1否
*/
private Integer isNewUser;
/**
* 邀请下级打卡奖励金额
*/
private BigDecimal inviteAmount;
/**
* 累计邀请人数
*/
private Integer inviteCount;
/**
* 是否是新用户 1否
*/
private Integer isNewUser;
@TableField(exist = false)
private String sysUserName;
@TableField(exist = false)
private String sysUserName;
@TableField(exist = false)
private Integer member;
@TableField(exist = false)
private Integer member;
@TableField(exist = false)
private Integer counts;
@TableField(exist = false)
private Integer counts;
@TableField(exist = false)
private BigDecimal money;
@TableField(exist = false)
private BigDecimal money;
@TableField(exist = false)
private String endTime;
@TableField(exist = false)
private String endTime;
@TableField(exist = false)
private Integer vipType;
@TableField(exist = false)
private Integer vipType;
@TableField(exist = false)
private Integer cashCount;
@TableField(exist = false)
private BigDecimal cashAmount;
@TableField(exist = false)
private BigDecimal balance;
}

View File

@ -1,93 +0,0 @@
package com.sqx.modules.app.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
/**
*
* @TableName user_info
*/
@TableName(value ="user_info")
@Data
@EqualsAndHashCode
public class UserInfo implements Serializable {
/**
*
*/
@TableId(type = IdType.ID_WORKER)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 用户id
*/
@TableField(updateStrategy = FieldStrategy.NEVER)
@JsonSerialize(using = ToStringSerializer.class)
private Long userId;
/**
* 姓名
*/
private String certName;
/**
* 身份证号码
*/
private String certNo;
/**
* 银行账号
*/
private String accountNo;
/**
* 银行预留手机号
*/
private String mobile;
/**
* 银行预留手机号
*/
private String bankName;
/**
*
*/
private String province;
/**
*
*/
private String city;
/**
* 开户行
*/
private String bankBranch;
/**
* 四要素接口响应报文
*/
private String respJson;
/**
* 修改时间
*/
private Date updateTime;
@TableField(exist = false)
private String name;
@TableField(exist = false)
private String phone;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -4,8 +4,6 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
@ -25,18 +23,17 @@ public class UserMoney implements Serializable {
* 主键id
*/
@ApiModelProperty("主键id")
@TableId(type = IdType.ID_WORKER)
@JsonSerialize(using = ToStringSerializer.class)
@TableId(type = IdType.AUTO)
private Long id;
/**
* 钱包金
* 钱包金
*/
@ApiModelProperty("钱包金")
@ApiModelProperty("钱包金")
private BigDecimal money;
/**
* 钱包金
* 钱包金
*/
@ApiModelProperty("钱包余额 钱")
private BigDecimal amount;
@ -46,7 +43,6 @@ public class UserMoney implements Serializable {
*/
@ApiModelProperty("用户id")
@TableField("user_id")
@JsonSerialize(using = ToStringSerializer.class)
private Long userId;
/**
@ -54,19 +50,6 @@ public class UserMoney implements Serializable {
*/
@ApiModelProperty("渠道用户id")
@TableField("sys_user_id")
@JsonSerialize(using = ToStringSerializer.class)
private Long sysUserId;
private BigDecimal inviteIncomeMoney;;
private BigDecimal inviteIncomeCoin;
/**
* 累计提现金额
*/
private BigDecimal cashAmount;
/**
* 累计提现次数
*/
private Integer cashCount;
}

View File

@ -1,22 +1,21 @@
package com.sqx.modules.app.entity;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user_money_details")
@ApiModel("钱包详情")
public class UserMoneyDetails implements Serializable {
@ -24,15 +23,13 @@ public class UserMoneyDetails implements Serializable {
* 钱包详情id
*/
@ApiModelProperty("钱包详情id")
@TableId(type = IdType.ID_WORKER)
@JsonSerialize(using = ToStringSerializer.class)
@TableId(type = IdType.AUTO)
private Long id;
/**
* 用户id
*/
@TableField("user_id")
@ApiModelProperty("用户id")
@JsonSerialize(using = ToStringSerializer.class)
private Long userId;
/**
@ -40,47 +37,23 @@ public class UserMoneyDetails implements Serializable {
*/
@ApiModelProperty("渠道用户id")
@TableField("sys_user_id")
@JsonSerialize(using = ToStringSerializer.class)
private Long sysUserId;
@ApiModelProperty("源id")
@JsonSerialize(using = ToStringSerializer.class)
private Long sourceId;
/**
* 对应用户id
*/
@TableField("by_user_id")
@ApiModelProperty("对应用户id")
@JsonSerialize(using = ToStringSerializer.class)
private Long byUserId;
/**
* 标题
*/
@ApiModelProperty("标题")
private String title;
/***
* 1 注册 上级
* 2 充值
* 3 购买
* 4 提现
* 5 现金大转盘
* 6 分享达标
* 7 任务领取
* 8 平台操作
* 9 订单退款
* 10 渠道推广
/**
* 1注册 2首次购买 3购买 4提现
*/
@ApiModelProperty(" * 1 注册 (上级)\n" +
" * 2 充值\n" +
" * 3 购买\n" +
" * 4 提现\n" +
" * 5 现金大转盘\n" +
" * 6 分享达标\n" +
" * 7 任务领取\n" +
" * 8 平台操作\n" +
" * 9 订单退款\n" +
" * 10 渠道推广")
@ApiModelProperty("1充值钱包明细 2提现钱包明细")
private Integer classify;
/**
* 类别1充值2支出
@ -93,25 +66,15 @@ public class UserMoneyDetails implements Serializable {
@ApiModelProperty("状态 1待支付 2已到账 3取消")
private Integer state;
/**
*
*
*/
@ApiModelProperty("")
@ApiModelProperty("")
private BigDecimal money;
/**
* 内容
*/
@ApiModelProperty("内容")
private String content;
@ApiModelProperty("金额类型: 1 红包2金币")
private Integer moneyType;
/**
* 循环邀请奖励次数
*/
@ApiModelProperty("循环邀请奖励次数")
private Integer awardCount;
/**
* 创建时间
*/
@ -119,48 +82,5 @@ public class UserMoneyDetails implements Serializable {
@ApiModelProperty("创建时间")
private String createTime;
public UserMoneyDetails() {
}
/**
* @param userId 用户Id tb_user的id
* @param sysUserId 系统用户Id tb_sys_user的id
* @param byUserId 对应用户Id
* @param title 标题
* @param classify 1 注册 上级2 充值 3 购买 4 提现 5 现金大转盘 6 分享达标 7 任务领取 8 平台操作 9 订单退款 10 渠道推广
* @param type 类别1充值2支出
* @param state 状态 1待支付 2已到账 3取消
* @param money 金额
* @param content 内容描述
*/
public UserMoneyDetails(Long userId, Long sysUserId, Long byUserId, String title, Integer classify, Integer type,
Integer state, BigDecimal money, String content, Integer moneyType,Long sourceId) {
this.userId = userId;
this.sysUserId = sysUserId;
this.byUserId = byUserId;
this.title = title;
this.classify = classify;
this.type = type;
this.state = state;
this.money = money;
this.content = content;
this.createTime = DateUtil.now();
this.moneyType = moneyType;
this.sourceId = sourceId;
}
public UserMoneyDetails(Long userId, Long sysUserId, Long byUserId, String title, Integer classify, Integer type,
Integer state, BigDecimal money, String content, Integer moneyType) {
this.userId = userId;
this.sysUserId = sysUserId;
this.byUserId = byUserId;
this.title = title;
this.classify = classify;
this.type = type;
this.state = state;
this.money = money;
this.content = content;
this.createTime = DateUtil.now();
this.moneyType = moneyType;
}
}

View File

@ -1,81 +0,0 @@
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 com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
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)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 奖品引用id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long foreignId;
/**
* 活动类型 task-任务奖励 spinning-大转盘
*/
private String foreignType;
/**
* 奖品名称
*/
private String prizeName;
/**
* 奖品图片地址
*/
private String imgUrl;
/**
* 用户id
*/
@JsonSerialize(using = ToStringSerializer.class)
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

@ -2,8 +2,6 @@ package com.sqx.modules.app.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.io.Serializable;
@ -15,7 +13,6 @@ public class UserVip implements Serializable {
* 用户会员ID
*/
@TableId
@JsonSerialize(using = ToStringSerializer.class)
private Long vipId;
/**
* 会员类型
@ -24,7 +21,6 @@ public class UserVip implements Serializable {
/**
* 用户ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long userId;
/**

View File

@ -4,8 +4,6 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
@ -22,8 +20,7 @@ import java.math.BigDecimal;
@ApiModel("会员详情")
public class VipDetails implements Serializable {
@TableId
@JsonSerialize(using = ToStringSerializer.class)
@TableId(type = IdType.AUTO)
private Long id;
@ApiModelProperty("会员类型")

View File

@ -1,30 +1,14 @@
package com.sqx.modules.app.interceptor;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sqx.common.exception.CzgException;
import com.sqx.common.exception.SqxException;
import com.sqx.common.exception.UserException;
import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.IPUtils;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.app.entity.TbUserBlacklist;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserInfo;
import com.sqx.modules.app.mapper.TbUserBlacklistMapper;
import com.sqx.modules.app.service.UserInfoService;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.app.utils.JwtUtils;
import com.sqx.modules.redisService.RedisService;
import io.jsonwebtoken.Claims;
import com.sqx.modules.app.annotation.Login;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
@ -37,106 +21,54 @@ import java.util.Date;
/**
* 权限(Token)验证
*
*/
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
private static final Logger log = LoggerFactory.getLogger(AuthorizationInterceptor.class);
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserService userService;
@Autowired
private UserInfoService userInfoService;
@Autowired
private TbUserBlacklistMapper tbUserBlacklistMapper;
private final RedisService redisService;
public static final String USER_KEY = "userId";
public AuthorizationInterceptor(RedisService redisService) {
this.redisService = redisService;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Login annotation;
if (handler instanceof HandlerMethod) {
if(handler instanceof HandlerMethod) {
annotation = ((HandlerMethod) handler).getMethodAnnotation(Login.class);
} else {
}else{
return true;
}
if (annotation == null) {
if(annotation == null){
return true;
}
// 获取用户凭证
//获取用户凭证
String token = request.getHeader(jwtUtils.getHeader());
if (StringUtils.isBlank(token)) {
if(StringUtils.isBlank(token)){
token = request.getParameter(jwtUtils.getHeader());
}
// 凭证为空
if (StringUtils.isBlank(token)) {
//凭证为空
if(StringUtils.isBlank(token)){
throw new SqxException(jwtUtils.getHeader() + "不能为空", HttpStatus.UNAUTHORIZED.value());
}
Claims claims = jwtUtils.getClaimByToken(token);
if (claims == null || jwtUtils.isTokenExpired(claims.getExpiration())) {
if(claims == null || jwtUtils.isTokenExpired(claims.getExpiration())){
throw new SqxException(jwtUtils.getHeader() + "失效,请重新登录", HttpStatus.UNAUTHORIZED.value());
}
//设置userId到request里后续根据userId获取用户信息
long userId = Long.parseLong(claims.getSubject());
request.setAttribute(USER_KEY, userId);
// 获取用户的 IP 地址
String ip = IPUtils.getIpAddr(request);
// 检查用户是否超过限流
if (redisService.checkIpJumpLimit(userId, ip) && userId != 14234L && userId != 1074096240846845557L) {
log.warn("用户地址跳动频繁,封禁: {}", userId);
if (!redisService.isSetUserState(userId)) {
ThreadUtil.execAsync(() -> {
userService.addBlackUser(userId,"IP频繁跳动");
});
}
throw new CzgException("ip跳动过于频繁请联系管理员解封");
}
// ThreadUtil.execAsync(() -> {
// redisService.recordUrlVisitCountWithIp(userId, request.getRequestURI(), ip);
// });
// 设置 userId request 后续根据 userId 获取用户信息
UserEntity user = userService.selectUserById(userId);
if(user == null) {
throw new SqxException("会话失效,请重新登录", HttpStatus.UNAUTHORIZED.value());
}
if (user.getStatus() == 0) {
throw new UserException("用户被拉黑", 701);
} else if (user.getStatus() == 2) {
throw new UserException("用户被禁用", 702);
}
// 实名认证信息
UserInfo userInfo = userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserId, user.getUserId()));
if (userInfo != null && StrUtil.isNotBlank(userInfo.getCertNo())) {
TbUserBlacklist blacklist = tbUserBlacklistMapper.selectOne(Wrappers.<TbUserBlacklist>lambdaQuery().eq(TbUserBlacklist::getIdCardNo, userInfo.getCertNo()));
if (blacklist != null) {
// 提出用户
throw new SqxException(jwtUtils.getHeader() + "失效,请重新登录", HttpStatus.UNAUTHORIZED.value());
}
}
// if (redisService.isRecordUserOnLineTime(userId)) {
// ThreadUtil.execAsync(() -> {
// // 记录用户最后一次调用接口的时间
// UserEntity userEntity = new UserEntity();
// userEntity.setUserId(userId);
// userEntity.setOnLineTime(DateUtils.format(new Date()));
// userService.updateById(userEntity);
// });
// }
//记录用户最后一次调用接口的时间
UserEntity userEntity=new UserEntity();
userEntity.setUserId(userId);
userEntity.setOnLineTime(DateUtils.format(new Date()));
userService.updateById(userEntity);
return true;
}
}

View File

@ -1,31 +0,0 @@
package com.sqx.modules.app.mapper;
import com.sqx.modules.app.entity.InviteAchievement;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Update;
/**
* @author Administrator
* @description 针对表invite_achievement的数据库操作Mapper
* @createDate 2024-12-30 13:26:18
* @Entity com.sqx.modules.app.entity.InviteAchievement
*/
@Mapper
public interface InviteAchievementMapper extends BaseMapper<InviteAchievement> {
@Update("update invite_achievement set count = count + #{i}, update_time=now() where id = #{id} and user_id = #{userId}")
int incrCount(Long id, Long userId, int i);
@Insert("INSERT INTO invite_achievement (user_id, source_user_id, count, state, create_time)\n" +
"SELECT #{userId}, #{sourceUserId}, #{count}, #{state}, #{createTime} " +
"WHERE NOT EXISTS ( " +
" SELECT 1 FROM invite_achievement WHERE user_id = #{userId} " +
");")
boolean insertNotExists(InviteAchievement inviteAchievement);
}

View File

@ -1,14 +0,0 @@
package com.sqx.modules.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sqx.modules.app.entity.TbUserBlacklist;
import org.apache.ibatis.annotations.Mapper;
/**
* 实名认证黑名单 Mapper
* @author tankaikai
* @since 2025-01-07 12:56
*/
@Mapper
public interface TbUserBlacklistMapper extends BaseMapper<TbUserBlacklist> {
}

View File

@ -1,14 +0,0 @@
package com.sqx.modules.app.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sqx.modules.app.entity.TbWithdrawBlacklist;
import org.apache.ibatis.annotations.Mapper;
/**
* 提现黑名单 Mapper
* @author tankaikai
* @since 2025-01-07 12:56
*/
@Mapper
public interface TbWithdrawBlacklistMapper extends BaseMapper<TbWithdrawBlacklist> {
}

View File

@ -1,20 +0,0 @@
package com.sqx.modules.app.mapper;
import com.sqx.modules.app.entity.UserInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author Administrator
* @description 针对表user_info的数据库操作Mapper
* @createDate 2025-01-02 14:15:08
* @Entity com.sqx.modules.app.entity.UserInfo
*/
@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
}

View File

@ -19,8 +19,7 @@ public class CourseOrderResponse implements Serializable {
*/
private int coursenum;
/**
* 售卖金
* 售卖金
*/
private Double coursemoney;
private Long courseId;
}

View File

@ -48,21 +48,5 @@ public class HomeMessageResponse implements Serializable {
* 本年收入
*/
private Double yearRevenue;
/**
* 当日总支付金额
*/
private BigDecimal todayPayAmount;
/**
* 当日总支付笔数
*/
private Integer todayPayCount;
/**
* 当日提现金额
*/
private BigDecimal todayExtractAmount;
/**
* 当日提现笔数
*/
private Integer todayExtractCount;
}

View File

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

View File

@ -1,10 +0,0 @@
package com.sqx.modules.app.service;
import com.sqx.modules.app.dto.AuthRespDTO;
public interface AliService {
void authCertNo(String name, String idCard);
AuthRespDTO auth(String name, String idCard, String accountNo, String bankPreMobile);
}

View File

@ -1,31 +0,0 @@
package com.sqx.modules.app.service;
import com.sqx.modules.app.entity.InviteAchievement;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author Administrator
* @description 针对表invite_achievement的数据库操作Service
* @createDate 2024-12-30 13:26:18
*/
public interface InviteAchievementService extends IService<InviteAchievement> {
int countByUserId(Long userId);
InviteAchievement getByUserId(Long userId);
/**
* @param sourceUserId 上级userId 不存在填充自己Id
* @param userId 下级userId
*/
InviteAchievement getByUserIdOrSave(Long sourceUserId, Long userId);
int incrCount(Long id, Long userId, int i);
boolean insertNotExists(InviteAchievement inviteAchievement);
int countBySourceUserId(Long userId);
int countNum(Long userId, Integer signCount);
}

View File

@ -1,35 +0,0 @@
package com.sqx.modules.app.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sqx.modules.app.entity.UserInfo;
import java.util.List;
/**
* @author Administrator
* @description 针对表user_info的数据库操作Service
* @createDate 2025-01-02 14:15:08
*/
public interface UserInfoService extends IService<UserInfo> {
UserInfo getByUserIdOrSave(long userId);
UserInfo getByUserId(long userId);
/**
* 查询用户是否实名
*/
boolean isAuth(long userId);
/**
* 通过查询用户实名信息 绑定的用户ID列表
*/
List<UserInfo> getUsersByNameAndCertNo(String certName,String certNo);
Integer countCertCount(String name, String idNum);
Integer countCertCount(String name, String idNum, String accountNo, String mobile);
int getAuthUserTag(long userId);
Object getList(Integer page, Integer size, String phone, String name);
}

View File

@ -4,13 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.entity.UserMoneyDetails;
import java.util.Map;
public interface UserMoneyDetailsService extends IService<UserMoneyDetails> {
Result queryUserMoneyDetails(Integer page, Integer limit, Long sysUserId, Long userId, Integer classify,
Integer type, Integer moneyType, Integer viewType);
Double monthIncome(String date, Long userId);
Map<String, Double> queryUserTotalEarning(Long userId);
Result queryUserMoneyDetails(Integer page, Integer limit,Long sysUserId,Long userId,Integer classify,Integer type);
Double monthIncome(String date,Long userId);
}

View File

@ -7,7 +7,12 @@ public interface UserMoneyService extends IService<UserMoney> {
UserMoney selectUserMoneyByUserId(Long userId);
UserMoney selectSysUserMoneyByUserId(Long userId);
void updateMoney(int i, Long userId, double money);
void updateAmount(int i, Long userId, double amount);
void updateSysMoney(int i, Long userId, double money);
}

View File

@ -1,38 +0,0 @@
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

@ -2,10 +2,11 @@ package com.sqx.modules.app.service;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.dto.*;
import com.sqx.modules.app.entity.UserEntity;
import javax.servlet.http.HttpServletRequest;
@ -158,6 +159,8 @@ public interface UserService extends IService<UserEntity> {
*
* @param phone 手机号
* @param msg 验证按
* @param pwd 密码
* @param platform 来源 app h5
* @return
*/
Result registerCode(String phone, String msg, String platform, Integer sysPhone,String password,
@ -172,8 +175,11 @@ public interface UserService extends IService<UserEntity> {
/**
* app或h5登录
*
* @param phone 手机号
* @param pwd 密码
* @return
*/
Result login(LoginDTO loginDTO);
Result login(String phone, String pwd);
/**
@ -198,7 +204,7 @@ public interface UserService extends IService<UserEntity> {
PageUtils selectUserPage(Integer page, Integer limit,String phone,Integer sex,String platform,String sysPhone,Integer status,
Integer member, String inviterCode, String userName, String invitationCode, String startTime,
String endTime,String qdCode,String sysUserName,Integer vipType, Integer delegate);
String endTime,String qdCode,String sysUserName,Integer vipType);
List<UserEntity> userListExcel(String startTime, String endTime, UserEntity userEntity);
@ -208,7 +214,7 @@ public interface UserService extends IService<UserEntity> {
Double queryPayMoney(int type,String qdCode);
PageUtils queryCourseOrder(Long page, Long limit, int type, String date,Long sysUserId);
IPage<Map<String, Object>> queryCourseOrder(Page<Map<String, Object>> iPage, int type, String date,Long sysUserId);
int userMessage( String date, int type,String qdCode,Integer vipType);
@ -221,23 +227,4 @@ public interface UserService extends IService<UserEntity> {
int updateUserClientIdIsNull(String clientid);
void firstBindAwardsMoney(UserEntity entity);
/**
* 封禁拉黑用户
* 用户行为
*/
void addBlackUser(Long userId,String behavior);
UserEntity queryByInvitationCodeOrUserId(Long inviterUserId, String invitationCode);
Result register(RegisterDTO registerDTO);
Result updateUserInviteAmount(UserInviteDTO userInviteDTO);
Result upUserBlack(UserEntity userEntity, Integer status);
Map<String, Object> queryPayAndExtractInfo();
Result bindWx(BindWxDTO bindWxDTO, Long userId);
}

View File

@ -1,29 +0,0 @@
package com.sqx.modules.app.service.impl;
import com.sqx.common.utils.RedisUtils;
import com.sqx.modules.app.service.AdService;
import com.sqx.modules.redisService.impl.RedisServiceImpl;
import org.springframework.stereotype.Service;
import java.util.HashMap;
@Service
public class AdServiceImpl implements AdService {
private final RedisServiceImpl redisServiceImpl;
public AdServiceImpl(RedisServiceImpl redisServiceImpl) {
this.redisServiceImpl = redisServiceImpl;
}
@Override
public HashMap<String, Object> getDetail(Long userId) {
Long freeWatchRemainTime = redisServiceImpl.getFreeWatchRemainTime(userId, false);
Long permanentlyFreeWatchRemainTime = redisServiceImpl.getFreeWatchRemainTime(userId, true);
return new HashMap<String, Object>(){{
put("adFreeWatchTime", permanentlyFreeWatchRemainTime);
put("payFreeWatchTime", freeWatchRemainTime);
put("totalFreeWatchTime", freeWatchRemainTime + permanentlyFreeWatchRemainTime);
}};
}
}

View File

@ -1,150 +0,0 @@
package com.sqx.modules.app.service.impl;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.aliyun.dytnsapi20200217.Client;
import com.aliyun.dytnsapi20200217.models.CertNoTwoElementVerificationRequest;
import com.aliyun.dytnsapi20200217.models.CertNoTwoElementVerificationResponse;
import com.aliyun.teautil.models.RuntimeOptions;
import com.sqx.common.exception.SqxException;
import com.sqx.modules.app.dto.AuthRespDTO;
import com.sqx.modules.app.service.AliService;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
@Service
@Slf4j
public class AliServiceImpl implements AliService {
private final CommonInfoService commonInfoService;
private Client client;
public AliServiceImpl(CommonInfoService commonInfoService) {
this.commonInfoService = commonInfoService;
}
@PostConstruct
public void init() throws Exception {
CommonInfo keyIdInfo = commonInfoService.findOne(85);
CommonInfo securityInfo = commonInfoService.findOne(86);
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
// 必填请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID
.setAccessKeyId(keyIdInfo.getValue())
// 必填请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET
.setAccessKeySecret(securityInfo.getValue());
config.endpoint = "dytnsapi.aliyuncs.com";
this.client = new Client(config);
}
@Override
public void authCertNo(String name, String idCard) {
log.info("阿里云二要素认证请求参数: {} {}", name, idCard);
CertNoTwoElementVerificationRequest certNoTwoElementVerificationRequest = new com.aliyun.dytnsapi20200217.models.CertNoTwoElementVerificationRequest()
.setAuthCode("t92K8i9ae6")
.setCertName(name)
.setCertNo(idCard);
RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
CertNoTwoElementVerificationResponse resp = client.certNoTwoElementVerificationWithOptions(certNoTwoElementVerificationRequest, runtime);
log.info("阿里云二要素认证响应参数: {}", resp);
if (resp.getStatusCode() != 200) {
throw new SqxException("请求失败");
}
if (!"OK".equals(resp.getBody().getCode())) {
throw new SqxException(resp.getBody().getMessage());
}
if (!"1".equals(resp.getBody().getData().getIsConsistent())) {
throw new SqxException("身份证信息不匹配,认证失败");
}
} catch (Exception e) {
throw new SqxException(e.getMessage());
}
}
public static final Pattern CHINESE_NAME = Pattern.compile("^[\u2E80-\u9FFF·]{2,60}$");
/**
* 阿里云四要素认证
*
* @param name
* @param idCard
* @param accountNo
* @param bankPreMobile
*/
@Override
public AuthRespDTO auth(String name, String idCard, String accountNo, String bankPreMobile) {
// log.info("阿里云四要素认证请求参数: {} {} {} {}", name, idCard, accountNo, bankPreMobile);
if (StrUtil.isBlank(name)) {
throw new SqxException("持卡人姓名不能为空");
}
if (StrUtil.isBlank(idCard)) {
throw new SqxException("身份证号码不能为空");
}
if (StrUtil.isBlank(accountNo)) {
throw new SqxException("银行卡卡号不能为空");
}
if (StrUtil.isBlank(bankPreMobile)) {
throw new SqxException("银行预留手机号码不能为空");
}
if (!Validator.isMactchRegex(CHINESE_NAME, name)) {
throw new SqxException("持卡人姓名不合法");
}
boolean validCard = IdcardUtil.isValidCard(idCard);
if (!validCard) {
throw new SqxException("身份证号码不合法");
}
validCard = Validator.isMobile(bankPreMobile);
if (!validCard) {
throw new SqxException("银行预留手机号码格式不正确");
}
String appcode = "f98606b602564d209f37fc02b0bd590c";
Map<String, String> headers = new HashMap<>(2);
//最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
headers.put("Authorization", "APPCODE " + appcode);
//根据API的要求定义相对应的Content-Type
headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
Map<String, Object> params = new HashMap<>();
params.put("accountNo", accountNo);
params.put("name", name);
params.put("idCardCode", idCard);
params.put("bankPreMobile", bankPreMobile);
String reqBody = URLUtil.encode(StrUtil.format("accountNo={}&name={}&idCardCode={}&bankPreMobile={}", accountNo, name, idCard, bankPreMobile), Charset.defaultCharset());
String respBody = HttpUtil.createPost("https://bkvip.market.alicloudapi.com/v3/bcheck").headerMap(headers, true).body(reqBody).timeout(15 * 1000).execute().body();
// {"error_code":0,"reason":"成功","result":{"respCode":"0","respMsg":"银行卡鉴权成功","bancardInfor":{"bankName":"招商银行","BankCode":"03080000","BankId":5,"type":"借记卡","cardname":"一卡通(银联卡)","tel":"95555","Icon":"2014121619271052743.gif"}},"sn":"010817431025283426800706871"}
// {"error_code":10028,"reason":"成功","result":{"respCode":"6","respMsg":"身份证格式有误","bancardInfor":{"bankName":"招商银行","BankCode":"03080000","BankId":5,"type":"借记卡","cardname":"一卡通(银联卡)","tel":"95555","Icon":"2014121619271052743.gif"}},"sn":"010817575524183118006799233"}
log.info("阿里云四要素: {},{}, {}, {}, 结果: {}", idCard, name, accountNo, bankPreMobile, respBody);
JSONObject ret = JSONUtil.parseObj(respBody);
JSONObject result = ret.getJSONObject("result");
Integer errorCode = ret.getInt("error_code");
String respCode = result.getStr("respCode");
if (errorCode == 0 && "0".equals(respCode)) {
} else {
throw new SqxException(result.getStr("respMsg"));
}
String bankName = null;
boolean isExist = result.containsKey("bancardInfor");
if (isExist) {
bankName = result.getJSONObject("bancardInfor").getStr("bankName");
}
AuthRespDTO dto = new AuthRespDTO();
dto.setBankName(bankName);
dto.setRespJson(respBody);
return dto;
}
}

View File

@ -1,69 +0,0 @@
package com.sqx.modules.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.modules.app.entity.InviteAchievement;
import com.sqx.modules.app.entity.UserInfo;
import com.sqx.modules.app.service.InviteAchievementService;
import com.sqx.modules.app.mapper.InviteAchievementMapper;
import org.springframework.stereotype.Service;
/**
* @author Administrator
* @description 针对表invite_achievement的数据库操作Service实现
* @createDate 2024-12-30 13:26:18
*/
@Service
public class InviteAchievementServiceImpl extends ServiceImpl<InviteAchievementMapper, InviteAchievement>
implements InviteAchievementService {
@Override
public int countByUserId(Long userId) {
return count(new LambdaQueryWrapper<InviteAchievement>()
.eq(InviteAchievement::getUserId, userId));
}
@Override
public InviteAchievement getByUserId(Long userId) {
return getOne(new LambdaQueryWrapper<InviteAchievement>()
.eq(InviteAchievement::getTargetUserId, userId));
}
@Override
public InviteAchievement getByUserIdOrSave(Long sourceUserId, Long userId) {
InviteAchievement one = getOne(new LambdaQueryWrapper<InviteAchievement>()
.eq(InviteAchievement::getUserId, sourceUserId)
.eq(InviteAchievement::getTargetUserId, userId));
if (one == null) {
one = new InviteAchievement();
one.setUserId(sourceUserId);
one.setTargetUserId(userId);
save(one);
}
return one;
}
@Override
public int incrCount(Long id, Long userId, int i) {
return baseMapper.incrCount(id, userId, i);
}
@Override
public boolean insertNotExists(InviteAchievement inviteAchievement) {
return baseMapper.insertNotExists(inviteAchievement);
}
@Override
public int countBySourceUserId(Long userId) {
return count(new LambdaQueryWrapper<InviteAchievement>()
.eq(InviteAchievement::getState, 1)
.eq(InviteAchievement::getUserId, userId));
}
@Override
public int countNum(Long userId, Integer signCount) {
return count(new LambdaQueryWrapper<InviteAchievement>()
.eq(InviteAchievement::getUserId, userId)
.ge(InviteAchievement::getCount, signCount));
}
}

View File

@ -1,161 +0,0 @@
package com.sqx.modules.app.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sqx.common.utils.PageUtils;
import com.sqx.modules.app.dao.UserDao;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserInfo;
import com.sqx.modules.app.mapper.UserInfoMapper;
import com.sqx.modules.app.service.UserInfoService;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Administrator
* @description 针对表user_info的数据库操作Service实现
* @createDate 2025-01-02 14:15:08
*/
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
implements UserInfoService {
private final UserDao userDao;
public UserInfoServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public UserInfo getByUserIdOrSave(long userId) {
UserInfo userInfo = getOne(new LambdaQueryWrapper<UserInfo>()
.eq(UserInfo::getUserId, userId));
if (userInfo == null) {
userInfo = new UserInfo();
userInfo.setUserId(userId);
save(userInfo);
}
return userInfo;
}
@Override
public UserInfo getByUserId(long userId) {
UserInfo userInfo = getOne(new LambdaQueryWrapper<UserInfo>()
.eq(UserInfo::getUserId, userId));
if (userInfo == null) {
userInfo = new UserInfo();
userInfo.setUserId(userId);
}
return userInfo;
}
@Override
public boolean isAuth(long userId) {
UserInfo userInfo = getOne(new LambdaQueryWrapper<UserInfo>()
.eq(UserInfo::getUserId, userId)
.isNotNull(UserInfo::getCertName)
.isNotNull(UserInfo::getCertNo)
);
if (userInfo != null) {
return true;
}
return false;
}
@Override
public List<UserInfo> getUsersByNameAndCertNo(String certName, String certNo) {
List<UserInfo> userIds = baseMapper.selectList(new LambdaQueryWrapper<UserInfo>()
.eq(UserInfo::getCertName, certName)
.eq(UserInfo::getCertNo, certNo)
.select(UserInfo::getUserId)
);
return userIds;
}
@Override
public Integer countCertCount(String name, String idNum) {
return count(new LambdaQueryWrapper<UserInfo>()
.eq(UserInfo::getCertName, name)
.eq(UserInfo::getCertNo, idNum)
.isNotNull(UserInfo::getAccountNo)
.isNotNull(UserInfo::getMobile)
);
}
@Override
public Integer countCertCount(String name, String idNum, String accountNo, String mobile) {
return count(new LambdaQueryWrapper<UserInfo>()
.eq(UserInfo::getCertName, name)
.eq(UserInfo::getCertNo, idNum)
.eq(UserInfo::getAccountNo, accountNo)
.eq(UserInfo::getMobile, mobile)
);
}
/**
* 获取用户认证标签
* @param userId 用户id
* @return 0-未认证1-新用户2-老用户
*/
@Override
public int getAuthUserTag(long userId) {
UserInfo userInfo = getByUserId(userId);
if (userInfo == null) {
// 未认证
return 0;
}
if(StrUtil.isEmpty(userInfo.getCertNo())){
// 未认证
return 0;
}
String certNo = userInfo.getCertNo();
List<UserInfo> authUserlist = baseMapper.selectList(Wrappers.<UserInfo>lambdaQuery().eq(UserInfo::getCertNo, certNo));
// 同身份证号第一个认证用户
UserInfo firstAuth = authUserlist.stream().sorted(Comparator.comparingLong(UserInfo::getId)).findFirst().get();
if (firstAuth.getUserId() == userId) {
// 新用户
return 1;
}
// 老用户
return 2;
}
@Override
public Object getList(Integer page, Integer size, String phone, String name) {
LambdaQueryWrapper<UserInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
if (StrUtil.isNotBlank(phone)) {
UserEntity userEntity = userDao.selectOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getPhone, phone));
lambdaQueryWrapper.eq(UserInfo::getUserId, userEntity == null ? -99999 : userEntity.getUserId());
}
if (StrUtil.isNotBlank(name)) {
lambdaQueryWrapper.like(UserInfo::getCertName, name);
}
PageHelper.startPage(page, size);
List<UserInfo> userInfoList = list(lambdaQueryWrapper);
PageInfo<UserInfo> userInfoPageInfo = new PageInfo<>(userInfoList);
Set<Long> userIdList = userInfoList.stream().map(UserInfo::getUserId).collect(Collectors.toSet());
Map<Long, UserEntity> userMap = userIdList.isEmpty() ? new HashMap<>() : userDao.selectList(new LambdaQueryWrapper<UserEntity>().in(UserEntity::getUserId, userIdList))
.stream().collect(Collectors.toMap(UserEntity::getUserId, item -> item));
userInfoList.forEach(item -> {
UserEntity userEntity = userMap.get(item.getUserId());
if (userEntity == null) return;
item.setName(userEntity.getUserName());
item.setPhone(userEntity.getPhone());
});
return PageUtils.page(userInfoPageInfo);
}
}

View File

@ -1,79 +1,40 @@
package com.sqx.modules.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.dao.UserMoneyDetailsDao;
import com.sqx.modules.app.entity.UserMoney;
import com.sqx.modules.app.entity.UserMoneyDetails;
import com.sqx.modules.app.service.UserMoneyDetailsService;
import com.sqx.modules.sys.entity.SysUserMoneyDetails;
import com.sqx.modules.sys.service.SysUserMoneyDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class UserMoneyDetailsServiceImpl extends ServiceImpl<UserMoneyDetailsDao, UserMoneyDetails> implements UserMoneyDetailsService {
@Autowired
private SysUserMoneyDetailsService sysUserMoneyDetailsService;
@Override
public Result queryUserMoneyDetails(Integer page, Integer limit, Long sysUserId, Long userId, Integer classify,
Integer type, Integer moneyType, Integer viewType) {
PageHelper.startPage(page, limit);
if (sysUserId != null) {
List<SysUserMoneyDetails> list = sysUserMoneyDetailsService.list(new LambdaQueryWrapper<SysUserMoneyDetails>()
.eq(SysUserMoneyDetails::getUserId, sysUserId).orderByDesc(SysUserMoneyDetails::getCreateTime));
return Result.success().put("data", PageUtils.page(new PageInfo<>(list), true));
}
public Result queryUserMoneyDetails(Integer page, Integer limit,Long sysUserId,Long userId,Integer classify,Integer type) {
IPage<UserMoneyDetails> page1 = new Page(page, limit);
QueryWrapper<UserMoneyDetails> queryWrapper = new QueryWrapper();
if (userId != null) {
if(sysUserId!=null){
queryWrapper.eq("sys_user_id", sysUserId);
}
if(userId!=null){
queryWrapper.eq("user_id", userId);
}
if (classify != null) {
if(classify!=null){
queryWrapper.eq("classify", classify);
}
if (type != null) {
if(type!=null){
queryWrapper.eq("type", type);
}
if (moneyType != null) {
queryWrapper.eq("money_type", moneyType);
}
if (viewType == 1) {
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(6);
queryWrapper.in("classify", arrayList);
}
queryWrapper.orderByDesc("create_time");
return Result.success().put("data", PageUtils.page(new PageInfo<>(baseMapper.selectList(queryWrapper)), true));
return Result.success().put("data", baseMapper.selectPage(page1, queryWrapper));
}
@Override
public Double monthIncome(String date, Long userId) {
return baseMapper.monthIncome(date, userId);
}
@Override
public Map<String, Double> queryUserTotalEarning(Long userId) {
Double inviteMoney = baseMapper.queryUserInviteMoney(userId);
Double inviteGoldMoney = baseMapper.queryUserInviteGoldMoney(userId);
Map<String, Double> map = new HashMap<>(2);
map.put("inviteMoney", inviteMoney == null ? 0 : inviteMoney);
map.put("inviteGoldMoney", inviteGoldMoney == null ? 0 : inviteGoldMoney);
return map;
return baseMapper.monthIncome(date,userId);
}
}

Some files were not shown because too many files have changed in this diff Show More