diff --git a/pom.xml b/pom.xml index b22e84e9..7c4217ec 100644 --- a/pom.xml +++ b/pom.xml @@ -35,12 +35,14 @@ 7.2.23 3.4.0 4.4 - 2.7.0 + + 2.9.2 2.9.9 2.8.5 1.2.83 4.6.10 1.18.4 + 4.1.1 - - com.yungouos.pay - yungouos-pay-sdk - 2.0.10 - - org.hibernate.validator hibernate-validator @@ -129,11 +130,11 @@ 5.5.0 - - com.alibaba - druid - 1.1.10 - + + + + + com.auth0 @@ -183,6 +184,12 @@ com.aliyun.oss aliyun-sdk-oss 3.4.0 + + + aliyun-java-sdk-core + com.aliyun + + com.aliyun @@ -247,16 +254,40 @@ + + + + + + + mysql mysql-connector-java ${mysql.version} + + + + + + - com.oracle - ojdbc6 - ${oracle.version} + org.apache.shardingsphere + sharding-core-api + ${shardingsphere.version} + compile + + + org.apache.shardingsphere + sharding-jdbc-core + ${shardingsphere.version} + compile + + + org.springframework.boot + spring-boot-starter-actuator @@ -265,10 +296,10 @@ ${mssql.version} - - org.postgresql - postgresql - + + + + com.alibaba druid-spring-boot-starter @@ -327,14 +358,25 @@ io.springfox - springfox-swagger2 + springfox-swagger-ui ${swagger.version} io.springfox - springfox-swagger-ui + springfox-swagger2 ${swagger.version} + + io.swagger + swagger-annotations + 1.5.22 + + + io.swagger + swagger-models + 1.5.22 + + com.qiniu qiniu-java-sdk diff --git a/src/main/java/com/sqx/SqxApplication.java b/src/main/java/com/sqx/SqxApplication.java index a3c22cfd..adc28108 100644 --- a/src/main/java/com/sqx/SqxApplication.java +++ b/src/main/java/com/sqx/SqxApplication.java @@ -1,6 +1,5 @@ package com.sqx; -import com.sqx.modules.pay.wuyou.WuyouPay; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @@ -18,25 +17,7 @@ import java.util.Map; public class SqxApplication { public static void main(String[] args) { - ConfigurableApplicationContext context = SpringApplication.run(SqxApplication.class, args); - context.getEnvironment().getPropertySources().forEach(source -> { - if (source.getName().contains("application-dev.yml") || source.getName().contains("application-prod.yml")) { - if (source.getSource() instanceof Map) { - ((Map) source.getSource()).forEach((key, value) -> { - System.out.println(key + ": " + value); - if ("pay.orderNotifyUrl".equals(key)) { - WuyouPay.setNotifyUrl(value.toString()); - } - if ("pay.extractNotifyUrl".equals(key)) { - WuyouPay.setExtractNotifyUrl(value.toString()); - } - if ("pay.h5BaseUrl".equals(key)) { - WuyouPay.setH5BaseUrl(value.toString()); - } - }); - } - } - }); + SpringApplication.run(SqxApplication.class, args); System.out.println("(♥◠‿◠)ノ゙ 短剧系统启动成功 ლ(´ڡ`ლ)゙ \n"+ " _ \n" + " | | \n" + diff --git a/src/main/java/com/sqx/common/aspect/AppApiMethodAspect.java b/src/main/java/com/sqx/common/aspect/AppApiMethodAspect.java index b7315939..22cf198d 100644 --- a/src/main/java/com/sqx/common/aspect/AppApiMethodAspect.java +++ b/src/main/java/com/sqx/common/aspect/AppApiMethodAspect.java @@ -1,5 +1,6 @@ package com.sqx.common.aspect; +import cn.hutool.core.thread.ThreadUtil; import com.google.gson.Gson; import com.sqx.common.utils.HttpContextUtils; import com.sqx.common.utils.IPUtils; @@ -21,9 +22,9 @@ import javax.servlet.http.HttpServletRequest; @Slf4j public class AppApiMethodAspect { - @Pointcut("execution(public * (com.sqx.modules.*.controller.*).*(..)) " + - "&& " + - "!execution(public * (com.sqx.modules.sys.controller.SysLoginController).*(..))") + @Pointcut("!execution(public * (com.sqx.modules.sys.controller.SysLoginController).*(..)) " + + "&& (execution(public * (com.sqx.modules.*.controller.*).*(..)) " + + "|| execution(public * (com.sqx.modules.app.*.controller.*).*(..)))") public void pkg() { } @@ -44,22 +45,31 @@ public class AppApiMethodAspect { // 执行被拦截的方法 Object result = pjp.proceed(); - - //请求的参数 - String resultJson = new Gson().toJson(result); - try{ - HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); - long end = System.currentTimeMillis(); - if(StringUtils.isNotBlank(resultJson) && !"null".equals(resultJson)){ - log.info("\n>>>>>> {} {}\n>>>>>> IP: {} \n>>>>>> execute time:{}ms \n>>>>>> Request: {}\n>>>>>> Response: {}", - request.getMethod(), request.getRequestURL(), IPUtils.getIpAddr(request),end-start, - params, - resultJson - ); + long end = System.currentTimeMillis(); + HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); + String method = request.getMethod(); + String requestUrl = request.getRequestURL().toString(); + String requestIp = IPUtils.getIpAddr(request); + long useTime = end - start; + ThreadUtil.execAsync(() -> { + //请求的参数 + String resultJson = new Gson().toJson(result); + 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()); } - }catch (Exception e){ - log.error("Request 为空"+e.getMessage()); - } + }); return result; } } diff --git a/src/main/java/com/sqx/common/utils/IPUtils.java b/src/main/java/com/sqx/common/utils/IPUtils.java index 0fbd6c9f..24248d3f 100644 --- a/src/main/java/com/sqx/common/utils/IPUtils.java +++ b/src/main/java/com/sqx/common/utils/IPUtils.java @@ -1,6 +1,6 @@ package com.sqx.common.utils; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/com/sqx/common/utils/RedisKeys.java b/src/main/java/com/sqx/common/utils/RedisKeys.java index 0f736498..373db19e 100644 --- a/src/main/java/com/sqx/common/utils/RedisKeys.java +++ b/src/main/java/com/sqx/common/utils/RedisKeys.java @@ -10,6 +10,8 @@ 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){ @@ -41,4 +43,12 @@ public class RedisKeys { } 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; + } } diff --git a/src/main/java/com/sqx/config/RedisConfig.java b/src/main/java/com/sqx/config/RedisConfig.java index 6fddb78c..3188988c 100644 --- a/src/main/java/com/sqx/config/RedisConfig.java +++ b/src/main/java/com/sqx/config/RedisConfig.java @@ -1,5 +1,6 @@ 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; @@ -70,4 +71,10 @@ public class RedisConfig { public ZSetOperations zSetOperations(RedisTemplate redisTemplate) { return redisTemplate.opsForZSet(); } + + @Bean + public RedisUtils redisUtils() { + // 根据实际情况初始化RedisUtils实例,可能需要传入相关配置参数,如Redis连接信息等 + return new RedisUtils(); + } } diff --git a/src/main/java/com/sqx/config/ShardingConfig.java b/src/main/java/com/sqx/config/ShardingConfig.java new file mode 100644 index 00000000..f8efb899 --- /dev/null +++ b/src/main/java/com/sqx/config/ShardingConfig.java @@ -0,0 +1,150 @@ +package com.sqx.config; + +import com.sqx.sharding.MasterSlaveRules; +import com.sqx.sharding.ShardingDataBase; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.apache.shardingsphere.api.config.masterslave.MasterSlaveRuleConfiguration; +import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration; +import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration; +import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory; +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.annotation.PostConstruct; +import javax.sql.DataSource; +import java.sql.SQLException; +import java.util.*; +import java.util.stream.Collectors; + + +/** + * sharding-jdbc 配置文件 + */ +@Slf4j +@Data +@Configuration +@ConfigurationProperties(prefix = "spring.shardingsphere") +public class ShardingConfig { + + /** + * 读取数据源信息 + */ + private Map datasource; + /** + * 读写分离的配置 + */ + private Map masterSlaveRules; + /** + * 显示sharding-jdbc的sql + */ + private String showSql; + + /** + * 中心库的节点 + */ + private String centerTablesDataNode; + + @Value("${center-tables}") + private String tableNamesAsString; + + /** + * 中心表,不进行分库操作 + */ +// @Value("${center-tables}") + private Set centerTables; + + @PostConstruct + public void init() { + // 使用换行符进行分割,然后去除空白字符,收集到Set集合中 + centerTables = Arrays.stream(tableNamesAsString.split(",")) + .map(String::trim) + .collect(Collectors.toSet()); + } + + + /** + * 配置sharding-jdbc数据源 + */ + @Bean + public DataSource dataSource() throws SQLException { + ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration(); + + // 配置数据库主从 + shardingRuleConfig.setMasterSlaveRuleConfigs(masterSlaveRuleConfigs()); + + // 配置表的切分策略 + shardingRuleConfig.setTableRuleConfigs(addTableRuleConfigs()); + + // 配置是否显示sql + Properties props = new Properties(); + props.put("sql.show", showSql); + + // 配置数据源 + Map dataSourceMap = getShardingDataBase(); + return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, props); + } + + /** + * 配置 + */ + private Set addTableRuleConfigs() { + Set sets = new HashSet<>(); + for (String centerTable : centerTables) { + TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(centerTable, + String.format(centerTablesDataNode, centerTable)); + sets.add(tableRuleConfig); + } + +// // 定义区域表的分库规则 +// 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); +// } + return sets; + } + + /** + * 配置数据源 + */ + private Map getShardingDataBase() { + String testQuery = "SELECT 1"; + Map 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 masterSlaveRuleConfigs() { + Set sets = new HashSet<>(); + masterSlaveRules.forEach((databaseName, masterSlaveRules) -> { + MasterSlaveRuleConfiguration masterSlaveRuleConfig = new MasterSlaveRuleConfiguration(databaseName, + masterSlaveRules.getMasterDataSourceName(), masterSlaveRules.getSlaveDataSourceNames()); + sets.add(masterSlaveRuleConfig); + }); + return sets; + } +} \ No newline at end of file diff --git a/src/main/java/com/sqx/config/SwaggerConfig.java b/src/main/java/com/sqx/config/SwaggerConfig.java index 8cf4bfee..8f991bfa 100644 --- a/src/main/java/com/sqx/config/SwaggerConfig.java +++ b/src/main/java/com/sqx/config/SwaggerConfig.java @@ -1,58 +1,85 @@ -package com.sqx.config; - -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.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 security() { - return newArrayList( - new ApiKey("token", "token", "header") - ); - } - -} \ No newline at end of file +//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 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(); +// } +//} \ No newline at end of file diff --git a/src/main/java/com/sqx/datasource/annotation/DataSource.java b/src/main/java/com/sqx/datasource/annotation/DataSource.java deleted file mode 100644 index 082da71b..00000000 --- a/src/main/java/com/sqx/datasource/annotation/DataSource.java +++ /dev/null @@ -1,14 +0,0 @@ -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 ""; -} diff --git a/src/main/java/com/sqx/datasource/aspect/DataSourceAspect.java b/src/main/java/com/sqx/datasource/aspect/DataSourceAspect.java deleted file mode 100644 index b3c5d0ac..00000000 --- a/src/main/java/com/sqx/datasource/aspect/DataSourceAspect.java +++ /dev/null @@ -1,61 +0,0 @@ -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"); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/sqx/datasource/config/DynamicContextHolder.java b/src/main/java/com/sqx/datasource/config/DynamicContextHolder.java deleted file mode 100644 index f059bf76..00000000 --- a/src/main/java/com/sqx/datasource/config/DynamicContextHolder.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.sqx.datasource.config; - -import java.util.ArrayDeque; -import java.util.Deque; - -/** - * 多数据源上下文 - */ -public class DynamicContextHolder { - @SuppressWarnings("unchecked") - private static final ThreadLocal> 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 deque = CONTEXT_HOLDER.get(); - deque.poll(); - if (deque.isEmpty()) { - CONTEXT_HOLDER.remove(); - } - } - -} \ No newline at end of file diff --git a/src/main/java/com/sqx/datasource/config/DynamicDataSource.java b/src/main/java/com/sqx/datasource/config/DynamicDataSource.java deleted file mode 100644 index 4374032b..00000000 --- a/src/main/java/com/sqx/datasource/config/DynamicDataSource.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.sqx.datasource.config; - -import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; - -/** - * 多数据源 - */ -public class DynamicDataSource extends AbstractRoutingDataSource { - - @Override - protected Object determineCurrentLookupKey() { - return DynamicContextHolder.peek(); - } - -} diff --git a/src/main/java/com/sqx/datasource/config/DynamicDataSourceConfig.java b/src/main/java/com/sqx/datasource/config/DynamicDataSourceConfig.java deleted file mode 100644 index 9c1033fd..00000000 --- a/src/main/java/com/sqx/datasource/config/DynamicDataSourceConfig.java +++ /dev/null @@ -1,53 +0,0 @@ -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 getDynamicDataSource(){ - Map dataSourcePropertiesMap = properties.getDatasource(); - Map targetDataSources = new HashMap<>(dataSourcePropertiesMap.size()); - dataSourcePropertiesMap.forEach((k, v) -> { - DruidDataSource druidDataSource = DynamicDataSourceFactory.buildDruidDataSource(v); - targetDataSources.put(k, druidDataSource); - }); - - return targetDataSources; - } - -} \ No newline at end of file diff --git a/src/main/java/com/sqx/datasource/config/DynamicDataSourceFactory.java b/src/main/java/com/sqx/datasource/config/DynamicDataSourceFactory.java deleted file mode 100644 index b506b40c..00000000 --- a/src/main/java/com/sqx/datasource/config/DynamicDataSourceFactory.java +++ /dev/null @@ -1,44 +0,0 @@ -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; - } -} \ No newline at end of file diff --git a/src/main/java/com/sqx/datasource/properties/DataSourceProperties.java b/src/main/java/com/sqx/datasource/properties/DataSourceProperties.java deleted file mode 100644 index 0cc4fc44..00000000 --- a/src/main/java/com/sqx/datasource/properties/DataSourceProperties.java +++ /dev/null @@ -1,192 +0,0 @@ -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; - } -} \ No newline at end of file diff --git a/src/main/java/com/sqx/datasource/properties/DynamicDataSourceProperties.java b/src/main/java/com/sqx/datasource/properties/DynamicDataSourceProperties.java deleted file mode 100644 index ebd2a269..00000000 --- a/src/main/java/com/sqx/datasource/properties/DynamicDataSourceProperties.java +++ /dev/null @@ -1,22 +0,0 @@ -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 datasource = new LinkedHashMap<>(); - - public Map getDatasource() { - return datasource; - } - - public void setDatasource(Map datasource) { - this.datasource = datasource; - } -} diff --git a/src/main/java/com/sqx/modules/app/controller/UserController.java b/src/main/java/com/sqx/modules/app/controller/UserController.java index 0186e91b..7ff0b9bf 100644 --- a/src/main/java/com/sqx/modules/app/controller/UserController.java +++ b/src/main/java/com/sqx/modules/app/controller/UserController.java @@ -23,6 +23,7 @@ import com.sqx.modules.pay.service.PayDetailsService; import com.sqx.modules.sys.entity.SysUserEntity; 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; @@ -270,7 +271,7 @@ public class UserController { @ApiOperation("短剧分析") public Result courseMessage(Long page, Long limit, String date, int type, Long sysUserId) { Page> iPage = new Page<>(page, limit); - IPage> mapIPage = userService.queryCourseOrder(iPage, type, date, sysUserId); + IPage> mapIPage = userService.queryCourseOrder(iPage, type, TimeCompleteUtils.completeStartTime(date), sysUserId); return Result.success().put("data", new PageUtils(mapIPage)); } @@ -280,6 +281,7 @@ 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(); diff --git a/src/main/java/com/sqx/modules/app/controller/app/AppController.java b/src/main/java/com/sqx/modules/app/controller/app/AppController.java index 56121135..c55a5cb6 100644 --- a/src/main/java/com/sqx/modules/app/controller/app/AppController.java +++ b/src/main/java/com/sqx/modules/app/controller/app/AppController.java @@ -107,8 +107,8 @@ public class AppController { userEntity.setUserId(userId); old.setZhiFuBao(userEntity.getZhiFuBao()); old.setZhiFuBaoName(userEntity.getZhiFuBaoName()); + boolean bool = userService.updateById(userEntity); // 去除首绑支付宝奖励 -// boolean bool = userService.updateById(userEntity); // if (bool && isFirstBind) { // userService.firstBindAwardsMoney(old); // } diff --git a/src/main/java/com/sqx/modules/app/dao/UserDao.java b/src/main/java/com/sqx/modules/app/dao/UserDao.java index f7b0dc5c..97df46fd 100644 --- a/src/main/java/com/sqx/modules/app/dao/UserDao.java +++ b/src/main/java/com/sqx/modules/app/dao/UserDao.java @@ -31,7 +31,7 @@ public interface UserDao extends BaseMapper { Double queryPayMoney(@Param("type") int type, @Param("date") String date,String qdCode); - IPage> queryCourseOrder(Page iPage,@Param("type") int type, @Param("date") String date,Long sysUserId); + IPage> queryCourseOrder(Page iPage,@Param("type") int type, @Param("start") String start, @Param("end") String end,Long sysUserId); int userMessage( String date, int type,String qdCode,Integer vipType); diff --git a/src/main/java/com/sqx/modules/app/entity/InviteAchievement.java b/src/main/java/com/sqx/modules/app/entity/InviteAchievement.java new file mode 100644 index 00000000..f034862b --- /dev/null +++ b/src/main/java/com/sqx/modules/app/entity/InviteAchievement.java @@ -0,0 +1,59 @@ +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 java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +/** + * + * @TableName invite_achievement + */ +@TableName(value ="invite_achievement") +@Data +@EqualsAndHashCode +@ToString +public class InviteAchievement implements Serializable { + /** + * + */ + @TableId(type = IdType.AUTO) + private Integer id; + + /** + * 用户id + */ + private Long userId; + + /** + * 上级邀请用户id + */ + private Long sourceUserId; + + /** + * 达标次数 + */ + private Integer count; + + /** + * 是否首次达标 + */ + private Integer state; + + /** + * 创建时间 + */ + private Date createTime; + private Date updateTime; + + @TableField(exist = false) + private static final long serialVersionUID = 1L; + + +} diff --git a/src/main/java/com/sqx/modules/app/interceptor/AuthorizationInterceptor.java b/src/main/java/com/sqx/modules/app/interceptor/AuthorizationInterceptor.java index ac03c2a9..7e778a39 100644 --- a/src/main/java/com/sqx/modules/app/interceptor/AuthorizationInterceptor.java +++ b/src/main/java/com/sqx/modules/app/interceptor/AuthorizationInterceptor.java @@ -1,14 +1,21 @@ package com.sqx.modules.app.interceptor; +import cn.hutool.core.thread.ThreadUtil; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.sqx.common.exception.CzgException; import com.sqx.common.exception.SqxException; 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.UserEntity; 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; @@ -24,13 +31,20 @@ import java.util.Date; */ @Component public class AuthorizationInterceptor extends HandlerInterceptorAdapter { + private static final Logger log = LoggerFactory.getLogger(AuthorizationInterceptor.class); @Autowired private JwtUtils jwtUtils; @Autowired private UserService userService; + 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; @@ -44,13 +58,13 @@ public class AuthorizationInterceptor extends HandlerInterceptorAdapter { return true; } - //获取用户凭证 + // 获取用户凭证 String token = request.getHeader(jwtUtils.getHeader()); if (StringUtils.isBlank(token)) { token = request.getParameter(jwtUtils.getHeader()); } - //凭证为空 + // 凭证为空 if (StringUtils.isBlank(token)) { throw new SqxException(jwtUtils.getHeader() + "不能为空", HttpStatus.UNAUTHORIZED.value()); } @@ -60,18 +74,43 @@ public class AuthorizationInterceptor extends HandlerInterceptorAdapter { throw new SqxException(jwtUtils.getHeader() + "失效,请重新登录", HttpStatus.UNAUTHORIZED.value()); } - //设置userId到request里,后续根据userId,获取用户信息 long userId = Long.parseLong(claims.getSubject()); - UserEntity user = userService.selectUserById(userId); - if (user.getStatus().equals(0)) { - return false; - } request.setAttribute(USER_KEY, userId); - //记录用户最后一次调用接口的时间 - UserEntity userEntity = new UserEntity(); - userEntity.setUserId(userId); - userEntity.setOnLineTime(DateUtils.format(new Date())); - userService.updateById(userEntity); + + String ip = IPUtils.getIpAddr(request); // 获取用户的 IP 地址 + // 检查用户是否超过限流 + if (redisService.checkIpJumpLimit(userId, ip)) { + log.warn("用户地址跳动频繁,封禁: {}", userId); + if (!redisService.isSetUserState(userId)) { + ThreadUtil.execAsync(() -> { + userService.update(null, new LambdaUpdateWrapper() + .eq(UserEntity::getUserId, userId) + .set(UserEntity::getStatus, 0)); + }); + } + throw new CzgException("ip跳动过于频繁,请联系管理员解封"); + } + + ThreadUtil.execAsync(() -> { + redisService.recordUrlVisitCountWithIp(userId, request.getRequestURI(), ip); + }); + + // 设置 userId 到 request 里,后续根据 userId 获取用户信息 + UserEntity user = userService.selectUserById(userId); + if (user != null && user.getStatus().equals(0)) { + throw new CzgException("异常行为用户: {}" + user.getUserId()); + } + + if (redisService.isRecordUserOnLineTime(userId)) { + ThreadUtil.execAsync(() -> { + // 记录用户最后一次调用接口的时间 + UserEntity userEntity = new UserEntity(); + userEntity.setUserId(userId); + userEntity.setOnLineTime(DateUtils.format(new Date())); + userService.updateById(userEntity); + }); + } + return true; } } diff --git a/src/main/java/com/sqx/modules/app/mapper/InviteAchievementMapper.java b/src/main/java/com/sqx/modules/app/mapper/InviteAchievementMapper.java new file mode 100644 index 00000000..144dd004 --- /dev/null +++ b/src/main/java/com/sqx/modules/app/mapper/InviteAchievementMapper.java @@ -0,0 +1,31 @@ +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 { + + @Update("update invite_achievement set count = count + #{i}, update_time=now() where id = #{id}") + int incrCount(Integer id, 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); +} + + + + diff --git a/src/main/java/com/sqx/modules/app/service/InviteAchievementService.java b/src/main/java/com/sqx/modules/app/service/InviteAchievementService.java new file mode 100644 index 00000000..1203354b --- /dev/null +++ b/src/main/java/com/sqx/modules/app/service/InviteAchievementService.java @@ -0,0 +1,25 @@ +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 { + + int countByUserId(Long userId); + + InviteAchievement getByUserId(Long userId); + + int incrCount(Integer id, int i); + + boolean insertNotExists(InviteAchievement inviteAchievement); + + int countBySourceUserId(Long userId); + + int countNum(Long userId, Integer signCount); + +} diff --git a/src/main/java/com/sqx/modules/app/service/impl/InviteAchievementServiceImpl.java b/src/main/java/com/sqx/modules/app/service/impl/InviteAchievementServiceImpl.java new file mode 100644 index 00000000..1e13404d --- /dev/null +++ b/src/main/java/com/sqx/modules/app/service/impl/InviteAchievementServiceImpl.java @@ -0,0 +1,57 @@ +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.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 + implements InviteAchievementService{ + + @Override + public int countByUserId(Long userId) { + return count(new LambdaQueryWrapper() + .eq(InviteAchievement::getUserId, userId)); + } + + @Override + public InviteAchievement getByUserId(Long userId) { + return getOne(new LambdaQueryWrapper() + .eq(InviteAchievement::getUserId, userId)); + } + + @Override + public int incrCount(Integer id, int i) { + return baseMapper.incrCount(id,i); + } + + @Override + public boolean insertNotExists(InviteAchievement inviteAchievement) { + return baseMapper.insertNotExists(inviteAchievement); + } + + @Override + public int countBySourceUserId(Long userId) { + return count(new LambdaQueryWrapper() + .eq(InviteAchievement::getSourceUserId, userId)); + } + + @Override + public int countNum(Long userId, Integer signCount) { + return count(new LambdaQueryWrapper() + .eq(InviteAchievement::getSourceUserId, userId) + .ge(InviteAchievement::getCount, signCount)); + } +} + + + + diff --git a/src/main/java/com/sqx/modules/app/service/impl/UserServiceImpl.java b/src/main/java/com/sqx/modules/app/service/impl/UserServiceImpl.java index 2de000d5..306d5d47 100644 --- a/src/main/java/com/sqx/modules/app/service/impl/UserServiceImpl.java +++ b/src/main/java/com/sqx/modules/app/service/impl/UserServiceImpl.java @@ -1,6 +1,7 @@ package com.sqx.modules.app.service.impl; +import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.thread.ThreadUtil; import cn.hutool.json.JSONUtil; @@ -55,6 +56,7 @@ import com.sqx.modules.sys.service.SysUserService; import com.sqx.modules.utils.HttpClientUtil; import com.sqx.modules.utils.InvitationCodeUtil; import com.sqx.modules.utils.MD5Util; +import com.sqx.modules.utils.TimeCompleteUtils; import com.tencentcloudapi.common.Credential; import com.tencentcloudapi.common.exception.TencentCloudSDKException; import com.tencentcloudapi.common.profile.ClientProfile; @@ -1335,7 +1337,7 @@ public class UserServiceImpl extends ServiceImpl implements String invitationCode, String startTime, String endTime, String qdCode, String sysUserName, Integer vipType) { Page pages = new Page<>(page, limit); return new PageUtils(baseMapper.selectUserPage(pages, search, sex, platform, sysPhone, status, member, - inviterCode, userName, invitationCode, startTime, endTime, qdCode, sysUserName, vipType)); + inviterCode, userName, invitationCode, TimeCompleteUtils.completeStartTime(startTime), TimeCompleteUtils.completeEndTime(endTime), qdCode, sysUserName, vipType)); } @Override @@ -1367,7 +1369,18 @@ public class UserServiceImpl extends ServiceImpl implements @Override public IPage> queryCourseOrder(Page> iPage, int type, String date, Long sysUserId) { - return baseMapper.queryCourseOrder(iPage, type, date, sysUserId); + DateTime parse = DateUtil.parse(date, "yyyy-MM-dd"); + + String startTime = DateUtil.format(parse, "yyyy-MM-dd 00:00:00"); + String endTime = DateUtil.format(parse, "yyyy-MM-dd 23:59:59"); + if (type == 2) { + startTime = DateUtil.format(DateUtil.beginOfMonth(parse), "yyyy-MM-dd 00:00:00"); + endTime = DateUtil.format(DateUtil.endOfMonth(parse), "yyyy-MM-dd 23:59:59"); + } else if (type == 3) { + startTime = DateUtil.format(DateUtil.beginOfYear(parse), "yyyy-MM-dd 00:00:00"); + endTime = DateUtil.format(DateUtil.endOfYear(parse), "yyyy-MM-dd 23:59:59"); + } + return baseMapper.queryCourseOrder(iPage, type, startTime, endTime, sysUserId); } @Override @@ -1498,7 +1511,7 @@ public class UserServiceImpl extends ServiceImpl implements if (ret) { ThreadUtil.execAsync(()->{ discSpinningService.withdrawAsync(entity, money.doubleValue(), "[提现]"); - },true); + }); } } catch (Exception e) { log.error("首绑支付宝发放奖励异常,用户信息:{}", JSONUtil.toJsonStr(entity)); diff --git a/src/main/java/com/sqx/modules/common/controller/app/AppCommonController.java b/src/main/java/com/sqx/modules/common/controller/app/AppCommonController.java index 55c3a3dd..2a66d5ce 100644 --- a/src/main/java/com/sqx/modules/common/controller/app/AppCommonController.java +++ b/src/main/java/com/sqx/modules/common/controller/app/AppCommonController.java @@ -47,7 +47,6 @@ public class AppCommonController { " 20后台管理平台域名配置\n" + " 22拼多多优惠券地址") @ResponseBody - @Login public Result getCommonList(@PathVariable Integer type) { return commonService.findByType(type); } diff --git a/src/main/java/com/sqx/modules/course/controller/CourseController.java b/src/main/java/com/sqx/modules/course/controller/CourseController.java index 71d1b22a..6a3ef5a8 100644 --- a/src/main/java/com/sqx/modules/course/controller/CourseController.java +++ b/src/main/java/com/sqx/modules/course/controller/CourseController.java @@ -61,11 +61,11 @@ public class CourseController extends AbstractController { } - @GetMapping("/selectCourseUserbyid") - @ApiOperation("我的短剧") - public Result selectCourseUser(Integer page, Integer limit, Long userId) { - return courseUserService.selectCourseUser(page, limit, userId); - } +// @GetMapping("/selectCourseUserbyid") +// @ApiOperation("我的短剧") +// public Result selectCourseUser(Integer page, Integer limit, Long userId) { +// return courseUserService.selectCourseUser(page, limit, userId); +// } @GetMapping("/updateCourse") @ApiOperation("修改状态") diff --git a/src/main/java/com/sqx/modules/course/controller/app/AppCourseController.java b/src/main/java/com/sqx/modules/course/controller/app/AppCourseController.java index 7cb4cb20..537433fc 100644 --- a/src/main/java/com/sqx/modules/course/controller/app/AppCourseController.java +++ b/src/main/java/com/sqx/modules/course/controller/app/AppCourseController.java @@ -59,7 +59,7 @@ public class AppCourseController extends AbstractController { if (result.get("code").equals(0)) { redisUtils.set(redisKey, result.get("data"), 3); } - return courseDetailsService.selectCourseDetailsById(id, token, courseDetailsId); + return result; } @Login diff --git a/src/main/java/com/sqx/modules/course/controller/app/AppCourseUserController.java b/src/main/java/com/sqx/modules/course/controller/app/AppCourseUserController.java index 03e3d16d..9a5b9108 100644 --- a/src/main/java/com/sqx/modules/course/controller/app/AppCourseUserController.java +++ b/src/main/java/com/sqx/modules/course/controller/app/AppCourseUserController.java @@ -19,12 +19,12 @@ public class AppCourseUserController extends AbstractController { @Autowired private CourseUserService courseUserService; - @Login - @GetMapping("/selectCourseUser") - @ApiOperation("App我的短剧") - public Result selectCourseUser(Integer page, Integer limit, Long userId) { - return courseUserService.selectCourseUser(page, limit, userId); - } +// @Login +// @GetMapping("/selectCourseUser") +// @ApiOperation("App我的短剧") +// public Result selectCourseUser(Integer page, Integer limit, Long userId) { +// return courseUserService.selectCourseUser(page, limit, userId); +// } @Login @GetMapping("/updateTime") @@ -33,12 +33,12 @@ public class AppCourseUserController extends AbstractController { courseUserService.updateTime(courseId); } - @Login - @GetMapping("/selectLatelyCourse") - @ApiOperation("最近学习") - public Result selectLatelyCourse(Integer page, Integer limit, Long userId) { - return courseUserService.selectLatelyCourse(page, limit, userId); - } +// @Login +// @GetMapping("/selectLatelyCourse") +// @ApiOperation("最近学习") +// public Result selectLatelyCourse(Integer page, Integer limit, Long userId) { +// return courseUserService.selectLatelyCourse(page, limit, userId); +// } diff --git a/src/main/java/com/sqx/modules/course/dao/CourseUserDao.java b/src/main/java/com/sqx/modules/course/dao/CourseUserDao.java index 459fa740..de0a5902 100644 --- a/src/main/java/com/sqx/modules/course/dao/CourseUserDao.java +++ b/src/main/java/com/sqx/modules/course/dao/CourseUserDao.java @@ -13,9 +13,10 @@ import java.util.List; @Mapper public interface CourseUserDao extends BaseMapper { - IPage selectLatelyCourse(Page pages, @Param("userId") Long userId); +// IPage selectLatelyCourse(Page pages, @Param("userId") Long userId); - IPage selectCourseByCourseUser(Page pages, @Param("userId") Long userId); + //子查询不能用 +// IPage selectCourseByCourseUser(Page pages, @Param("userId") Long userId); /** * 查询用户是否订购 diff --git a/src/main/java/com/sqx/modules/course/entity/CourseCollect.java b/src/main/java/com/sqx/modules/course/entity/CourseCollect.java index 56f0060a..17b6e034 100644 --- a/src/main/java/com/sqx/modules/course/entity/CourseCollect.java +++ b/src/main/java/com/sqx/modules/course/entity/CourseCollect.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +import lombok.experimental.Accessors; import java.io.Serializable; @@ -14,6 +15,7 @@ import java.io.Serializable; * @date 2021-03-27 */ @Data +@Accessors(chain = true) @TableName("course_collect") public class CourseCollect implements Serializable { diff --git a/src/main/java/com/sqx/modules/course/entity/CourseDetails.java b/src/main/java/com/sqx/modules/course/entity/CourseDetails.java index f763df94..7099c515 100644 --- a/src/main/java/com/sqx/modules/course/entity/CourseDetails.java +++ b/src/main/java/com/sqx/modules/course/entity/CourseDetails.java @@ -155,6 +155,4 @@ public class CourseDetails implements Serializable { @TableField(exist = false) private String wxUrl; - public CourseDetails() { - } } diff --git a/src/main/java/com/sqx/modules/course/service/CourseUserService.java b/src/main/java/com/sqx/modules/course/service/CourseUserService.java index 18af6dea..4a972394 100644 --- a/src/main/java/com/sqx/modules/course/service/CourseUserService.java +++ b/src/main/java/com/sqx/modules/course/service/CourseUserService.java @@ -9,9 +9,9 @@ public interface CourseUserService extends IService { void updateTime(Long courseId); - Result selectCourseUser(Integer page, Integer limit, Long userId); +// Result selectCourseUser(Integer page, Integer limit, Long userId); - Result selectLatelyCourse(Integer page, Integer limit, Long userId); +// Result selectLatelyCourse(Integer page, Integer limit, Long userId); Result insertCourseUser(CourseUser courseUser); } diff --git a/src/main/java/com/sqx/modules/course/service/impl/CourseCollectServiceImpl.java b/src/main/java/com/sqx/modules/course/service/impl/CourseCollectServiceImpl.java index 619affac..6905aeac 100644 --- a/src/main/java/com/sqx/modules/course/service/impl/CourseCollectServiceImpl.java +++ b/src/main/java/com/sqx/modules/course/service/impl/CourseCollectServiceImpl.java @@ -35,6 +35,29 @@ public class CourseCollectServiceImpl extends ServiceImpl queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("user_id", courseCollect.getUserId()).eq("classify", 3).eq("course_id", courseCollect.getCourseId()); + queryWrapper.orderByDesc("create_time"); + queryWrapper.last("limit 1"); + CourseCollect collect = baseMapper.selectOne(queryWrapper); + if (collect != null) { + collect.setUpdateTime(DateUtils.format(new Date())); + collect.setCourseCollectId(courseCollect.getCourseCollectId()); + baseMapper.updateById(collect); + return Result.success("操作成功!"); + } + + collect = new CourseCollect() + .setUserId(courseCollect.getUserId()) + .setCourseId(courseCollect.getCourseId()) + .setCourseDetailsId(courseCollect.getCourseDetailsId()) + .setClassify(3) + .setCreateTime(DateUtils.format(new Date())) + .setUpdateTime(DateUtils.format(new Date())); + baseMapper.insert(collect); + return Result.success("操作成功!"); + } CourseCollect courseCollect1 = selectCourseCollectUserIdAnd(courseCollect.getUserId(), courseCollect.getCourseId(),courseCollect.getClassify(),courseCollect.getCourseDetailsId()); if (courseCollect.getType() == 1) { if(courseCollect1==null){ diff --git a/src/main/java/com/sqx/modules/course/service/impl/CourseDetailsServiceImpl.java b/src/main/java/com/sqx/modules/course/service/impl/CourseDetailsServiceImpl.java index 3c5de6ae..abde3ffc 100644 --- a/src/main/java/com/sqx/modules/course/service/impl/CourseDetailsServiceImpl.java +++ b/src/main/java/com/sqx/modules/course/service/impl/CourseDetailsServiceImpl.java @@ -1,13 +1,16 @@ package com.sqx.modules.course.service.impl; +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.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.sqx.common.exception.SqxException; import com.sqx.common.utils.DateUtils; import com.sqx.common.utils.PageUtils; import com.sqx.common.utils.Result; @@ -27,7 +30,6 @@ import com.sqx.modules.course.entity.CourseUser; import com.sqx.modules.course.service.CourseDetailsService; import com.sqx.modules.course.vo.CourseDetailsIn; import com.sqx.modules.orders.dao.OrdersDao; -import com.sqx.modules.orders.entity.Orders; import com.sqx.modules.orders.service.OrdersService; import com.sqx.modules.redisService.impl.RedisServiceImpl; import com.sqx.modules.utils.EasyPoi.ExcelUtils; @@ -68,6 +70,8 @@ public class CourseDetailsServiceImpl extends ServiceImpl list = baseMapper.findByCourseIdNotUrl(id, userId); + bean.setListsDetail(list); //查询用户是否单独购买了集 List courseUsers = courseUserDao.selectCourseUserList(id, userId); if (courseUsers.size() > 0) { @@ -199,6 +205,30 @@ public class CourseDetailsServiceImpl extends ServiceImpllambdaQuery() + .select(CourseCollect::getCourseDetailsId) + .eq(CourseCollect::getCourseId, id) + .eq(CourseCollect::getClassify, 3) + .eq(CourseCollect::getUserId, userId) + .orderByDesc(CourseCollect::getUpdateTime).last("limit 1") + ); + if (courseCollect != null && courseCollect.getCourseDetailsId() != null) { + CourseDetails courseDetails = courseDetailsDao.selectById(courseCollect.getCourseDetailsId()); + if (courseDetails != null) { + bean.setCourseDetailsId(courseDetails.getCourseDetailsId()); + bean.setCourseDetailsName(courseDetails.getCourseDetailsName()); + bean.setCourseDetailsCount(courseDetails.getCourseDetailsCount()); + } + }else{ + //默认取第一集 + CourseDetails courseDetails = courseDetailsDao.selectOne(Wrappers.lambdaQuery().eq(CourseDetails::getCourseId, id) + .orderByAsc(CourseDetails::getSort).last(" limit 1")); + if (courseDetails != null) { + bean.setCourseDetailsId(courseDetails.getCourseDetailsId()); + bean.setCourseDetailsName(courseDetails.getCourseDetailsName()); + bean.setCourseDetailsCount(courseDetails.getCourseDetailsCount()); + } + } return Result.success().put("data", bean); } @@ -211,6 +241,9 @@ public class CourseDetailsServiceImpl extends ServiceImpl courseDetailsIPage = baseMapper.selectCourseDetailsList(new Page<>(page, limit), randomNum, wxShow, dyShow); if (userId != null) { diff --git a/src/main/java/com/sqx/modules/course/service/impl/CourseServiceImpl.java b/src/main/java/com/sqx/modules/course/service/impl/CourseServiceImpl.java index c36a4def..0f1db86d 100644 --- a/src/main/java/com/sqx/modules/course/service/impl/CourseServiceImpl.java +++ b/src/main/java/com/sqx/modules/course/service/impl/CourseServiceImpl.java @@ -88,7 +88,7 @@ public class CourseServiceImpl extends ServiceImpl implements private void setCache(String key, String value) { key = getIndexKey(key); - redisUtils.set(key, value, 600); + redisUtils.set(key, value, 60 * 30); } private String getCache(String key) { @@ -174,26 +174,10 @@ public class CourseServiceImpl extends ServiceImpl implements sort, startTime, endTime, userId, isPrice, over, wxCourse, dyCourse, wxShow, dyShow); List> records = mapIPage.getRecords(); for (Map map : records) { - Object courseDetailsId = map.get("courseDetailsId"); - Object courseId = map.get("courseId"); - if (courseDetailsId != null) { - CourseDetails courseDetails = courseDetailsDao.selectById(Long.parseLong(String.valueOf(courseDetailsId))); - if (courseDetails != null) { - map.put("courseDetailsName", courseDetails.getCourseDetailsName()); - map.put("dyEpisodeId", courseDetails.getDyEpisodeId()); - map.put("wxCourseDetailsId", courseDetails.getWxCourseDetailsId()); - } - } else { - //默认取第一集 - CourseDetails courseDetails = courseDetailsDao.selectOne(new QueryWrapper().eq("course_id", courseId) - .orderByAsc("sort").last(" limit 1")); - if (courseDetails != null) { - map.put("courseDetailsId", courseDetails.getCourseDetailsId()); - map.put("courseDetailsName", courseDetails.getCourseDetailsName()); - map.put("dyEpisodeId", courseDetails.getDyEpisodeId()); - map.put("wxCourseDetailsId", courseDetails.getWxCourseDetailsId()); - } - } + map.put("courseDetailsId", null); + map.put("courseDetailsName", ""); + map.put("dyEpisodeId", ""); + map.put("wxCourseDetailsId", ""); } setCache(cacheKey, JSONUtil.toJsonStr(new PageUtils(mapIPage))); return Result.success().put("data", new PageUtils(mapIPage)); @@ -202,16 +186,10 @@ public class CourseServiceImpl extends ServiceImpl implements sort, startTime, endTime, userId, isPrice, over, wxCourse, dyCourse, wxShow, dyShow); List> records = mapIPage.getRecords(); for (Map map : records) { - Object courseId = map.get("courseId"); - //默认取第一集 - CourseDetails courseDetails = courseDetailsDao.selectOne(new QueryWrapper().eq("course_id", courseId) - .orderByAsc("sort").last(" limit 1")); - if (courseDetails != null) { - map.put("courseDetailsId", courseDetails.getCourseDetailsId()); - map.put("courseDetailsName", courseDetails.getCourseDetailsName()); - map.put("dyEpisodeId", courseDetails.getDyEpisodeId()); - map.put("wxCourseDetailsId", courseDetails.getWxCourseDetailsId()); - } + map.put("courseDetailsId", null); + map.put("courseDetailsName", ""); + map.put("dyEpisodeId", ""); + map.put("wxCourseDetailsId", ""); } setCache(cacheKey, JSONUtil.toJsonStr(new PageUtils(mapIPage))); return Result.success().put("data", new PageUtils(mapIPage)); diff --git a/src/main/java/com/sqx/modules/course/service/impl/CourseUserServiceImpl.java b/src/main/java/com/sqx/modules/course/service/impl/CourseUserServiceImpl.java index e79d013f..37055fcf 100644 --- a/src/main/java/com/sqx/modules/course/service/impl/CourseUserServiceImpl.java +++ b/src/main/java/com/sqx/modules/course/service/impl/CourseUserServiceImpl.java @@ -42,40 +42,40 @@ public class CourseUserServiceImpl extends ServiceImpl courseUserPage = new Page<>(page, limit); - IPage iPage = baseMapper.selectCourseByCourseUser(courseUserPage, userId); +// @Override +// public Result selectCourseUser(Integer page, Integer limit, Long userId) { +// Page courseUserPage = new Page<>(page, limit); +// IPage iPage = baseMapper.selectCourseByCourseUser(courseUserPage, userId); +// +// List courses = iPage.getRecords(); +// if (courses != null && courses.size() > 0) { +// for (Course course : courses) { +// Orders orders = ordersService.selectOrdersByCourseIdAndUserId(userId, course.getCourseId()); +// if(orders!=null){ +// course.setOrders(orders); +// } +// course.setCourseClassification(courseClassificationDao.selectById(course.getClassifyId())); +// } +// } +// return Result.success().put("data", new PageUtils(iPage)); +// } - List courses = iPage.getRecords(); - if (courses != null && courses.size() > 0) { - for (Course course : courses) { - Orders orders = ordersService.selectOrdersByCourseIdAndUserId(userId, course.getCourseId()); - if(orders!=null){ - course.setOrders(orders); - } - course.setCourseClassification(courseClassificationDao.selectById(course.getClassifyId())); - } - } - return Result.success().put("data", new PageUtils(iPage)); - } - - @Override - public Result selectLatelyCourse(Integer page, Integer limit, Long userId) { - Page pages = new Page<>(page, limit); - IPage iPage = baseMapper.selectLatelyCourse(pages, userId); - List courses = iPage.getRecords(); - if (courses != null && courses.size() > 0) { - for (Course course : courses) { - Orders orders = ordersService.selectOrdersByCourseIdAndUserId(userId, course.getCourseId()); - if(orders!=null){ - course.setOrders(orders); - } - course.setCourseClassification(courseClassificationDao.selectById(course.getClassifyId())); - } - } - return Result.success().put("data", new PageUtils(iPage)); - } +// @Override +// public Result selectLatelyCourse(Integer page, Integer limit, Long userId) { +// Page pages = new Page<>(page, limit); +// IPage iPage = baseMapper.selectLatelyCourse(pages, userId); +// List courses = iPage.getRecords(); +// if (courses != null && courses.size() > 0) { +// for (Course course : courses) { +// Orders orders = ordersService.selectOrdersByCourseIdAndUserId(userId, course.getCourseId()); +// if(orders!=null){ +// course.setOrders(orders); +// } +// course.setCourseClassification(courseClassificationDao.selectById(course.getClassifyId())); +// } +// } +// return Result.success().put("data", new PageUtils(iPage)); +// } @Override diff --git a/src/main/java/com/sqx/modules/discSpinning/service/impl/DiscSpinningServiceImpl.java b/src/main/java/com/sqx/modules/discSpinning/service/impl/DiscSpinningServiceImpl.java index 2d88ad58..f5bdc478 100644 --- a/src/main/java/com/sqx/modules/discSpinning/service/impl/DiscSpinningServiceImpl.java +++ b/src/main/java/com/sqx/modules/discSpinning/service/impl/DiscSpinningServiceImpl.java @@ -53,9 +53,8 @@ public class DiscSpinningServiceImpl extends ServiceImpl 10) { return; diff --git a/src/main/java/com/sqx/modules/invite/service/impl/InviteServiceImpl.java b/src/main/java/com/sqx/modules/invite/service/impl/InviteServiceImpl.java index aab59ab9..f4926807 100644 --- a/src/main/java/com/sqx/modules/invite/service/impl/InviteServiceImpl.java +++ b/src/main/java/com/sqx/modules/invite/service/impl/InviteServiceImpl.java @@ -165,7 +165,7 @@ public class InviteServiceImpl extends ServiceImpl implements // 金币 int money = Integer.parseInt(commonInfoService.findOne(911).getValue()); - if (money > 0) { + if (money > 0 && userEntity.getUserId() != 1) { userMoneyService.updateMoney(1, userEntity.getUserId(), money); UserMoneyDetails userMoneyDetails = new UserMoneyDetails(); userMoneyDetails.setUserId(userEntity.getUserId()); diff --git a/src/main/java/com/sqx/modules/job/config/ScheduleConfig.java b/src/main/java/com/sqx/modules/job/config/ScheduleConfig.java deleted file mode 100644 index 8b7653b7..00000000 --- a/src/main/java/com/sqx/modules/job/config/ScheduleConfig.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.sqx.modules.job.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; - -import javax.sql.DataSource; -import java.util.Properties; - -/** - * 定时任务配置 - * - */ -@Configuration -public class ScheduleConfig { - - @Bean - public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) { - SchedulerFactoryBean factory = new SchedulerFactoryBean(); - factory.setDataSource(dataSource); - - //quartz参数 - Properties prop = new Properties(); - prop.put("org.quartz.scheduler.instanceName", "sqxScheduler"); - prop.put("org.quartz.scheduler.instanceId", "AUTO"); - //线程池配置 - prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); - prop.put("org.quartz.threadPool.threadCount", "20"); - prop.put("org.quartz.threadPool.threadPriority", "5"); - //JobStore配置 - prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); - //集群配置 - prop.put("org.quartz.jobStore.isClustered", "true"); - prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); - prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); - - prop.put("org.quartz.jobStore.misfireThreshold", "12000"); - prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); - prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); - - //PostgreSQL数据库,需要打开此注释 - //prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate"); - - factory.setQuartzProperties(prop); - - factory.setSchedulerName("sqxScheduler"); - //延时启动 - factory.setStartupDelay(30); - factory.setApplicationContextSchedulerContextKey("applicationContextKey"); - //可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 - factory.setOverwriteExistingJobs(true); - //设置自动启动,默认为true - factory.setAutoStartup(true); - - return factory; - } -} diff --git a/src/main/java/com/sqx/modules/job/controller/ScheduleJobController.java b/src/main/java/com/sqx/modules/job/controller/ScheduleJobController.java index 3ab91d53..95b211a6 100644 --- a/src/main/java/com/sqx/modules/job/controller/ScheduleJobController.java +++ b/src/main/java/com/sqx/modules/job/controller/ScheduleJobController.java @@ -4,11 +4,16 @@ import com.sqx.common.annotation.SysLog; import com.sqx.common.utils.PageUtils; import com.sqx.common.utils.Result; import com.sqx.common.validator.ValidatorUtils; +import com.sqx.modules.job.dto.RunJobDTO; import com.sqx.modules.job.entity.ScheduleJobEntity; import com.sqx.modules.job.service.ScheduleJobService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.lang.reflect.Method; +import java.util.List; import java.util.Map; /** @@ -20,8 +25,15 @@ import java.util.Map; public class ScheduleJobController { @Autowired private ScheduleJobService scheduleJobService; - - /** + + private final ApplicationContext applicationContext; + + public ScheduleJobController(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + + /** * 定时任务列表 */ @RequestMapping("/list") @@ -30,17 +42,17 @@ public class ScheduleJobController { return Result.success().put("page", page); } - + /** * 定时任务信息 */ @RequestMapping("/info/{jobId}") public Result info(@PathVariable("jobId") Long jobId){ ScheduleJobEntity schedule = scheduleJobService.getById(jobId); - + return Result.success().put("schedule", schedule); } - + /** * 保存定时任务 */ @@ -48,12 +60,12 @@ public class ScheduleJobController { @RequestMapping("/save") public Result save(@RequestBody ScheduleJobEntity scheduleJob){ ValidatorUtils.validateEntity(scheduleJob); - + scheduleJobService.saveJob(scheduleJob); - + return Result.success(); } - + /** * 修改定时任务 */ @@ -61,12 +73,12 @@ public class ScheduleJobController { @RequestMapping("/update") public Result update(@RequestBody ScheduleJobEntity scheduleJob){ ValidatorUtils.validateEntity(scheduleJob); - + scheduleJobService.update(scheduleJob); - + return Result.success(); } - + /** * 删除定时任务 */ @@ -74,41 +86,49 @@ public class ScheduleJobController { @RequestMapping("/delete") public Result delete(@RequestBody Long[] jobIds){ scheduleJobService.deleteBatch(jobIds); - - return Result.success(); - } - - /** - * 立即执行任务 - */ - @SysLog("立即执行任务") - @RequestMapping("/run") - public Result run(@RequestBody Long[] jobIds){ - scheduleJobService.run(jobIds); - - return Result.success(); - } - - /** - * 暂停定时任务 - */ - @SysLog("暂停定时任务") - @RequestMapping("/pause") - public Result pause(@RequestBody Long[] jobIds){ - scheduleJobService.pause(jobIds); - - return Result.success(); - } - - /** - * 恢复定时任务 - */ - @SysLog("恢复定时任务") - @RequestMapping("/resume") - public Result resume(@RequestBody Long[] jobIds){ - scheduleJobService.resume(jobIds); - + return Result.success(); } + /** + * 立即执行任务 + */ + + @SysLog("立即执行任务") + @RequestMapping("/run") + public Result run(@RequestBody Long[] jobIds) throws Exception { + + return Result.success().put("data", scheduleJobService.run(jobIds)); + } + +// @SysLog("立即执行任务") +// @RequestMapping("/run") +// public Result run(@RequestBody Long[] jobIds){ +// scheduleJobService.run(jobIds); +// +// return Result.success(); +// } + +// /** +// * 暂停定时任务 +// */ +// @SysLog("暂停定时任务") +// @RequestMapping("/pause") +// public Result pause(@RequestBody Long[] jobIds){ +// scheduleJobService.pause(jobIds); +// +// return Result.success(); +// } +// +// /** +// * 恢复定时任务 +// */ +// @SysLog("恢复定时任务") +// @RequestMapping("/resume") +// public Result resume(@RequestBody Long[] jobIds){ +// scheduleJobService.resume(jobIds); +// +// return Result.success(); +// } + } diff --git a/src/main/java/com/sqx/modules/job/dto/RunJobDTO.java b/src/main/java/com/sqx/modules/job/dto/RunJobDTO.java new file mode 100644 index 00000000..f0c7c2ee --- /dev/null +++ b/src/main/java/com/sqx/modules/job/dto/RunJobDTO.java @@ -0,0 +1,14 @@ +package com.sqx.modules.job.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Data +public class RunJobDTO { + @NotNull + private Integer jobId; + private List args; +} diff --git a/src/main/java/com/sqx/modules/job/service/ScheduleJobService.java b/src/main/java/com/sqx/modules/job/service/ScheduleJobService.java index 407a197d..7f867189 100644 --- a/src/main/java/com/sqx/modules/job/service/ScheduleJobService.java +++ b/src/main/java/com/sqx/modules/job/service/ScheduleJobService.java @@ -2,6 +2,7 @@ package com.sqx.modules.job.service; import com.baomidou.mybatisplus.extension.service.IService; import com.sqx.common.utils.PageUtils; +import com.sqx.modules.job.dto.RunJobDTO; import com.sqx.modules.job.entity.ScheduleJobEntity; import java.util.Map; @@ -18,34 +19,36 @@ public interface ScheduleJobService extends IService { * 保存定时任务 */ void saveJob(ScheduleJobEntity scheduleJob); - + /** * 更新定时任务 */ void update(ScheduleJobEntity scheduleJob); - + /** * 批量删除定时任务 */ void deleteBatch(Long[] jobIds); - + /** * 批量更新定时任务状态 */ int updateBatch(Long[] jobIds, int status); - - /** - * 立即执行 - */ - void run(Long[] jobIds); - - /** - * 暂停运行 - */ - void pause(Long[] jobIds); - - /** - * 恢复运行 - */ - void resume(Long[] jobIds); + + Object run(Long[] jobIds) throws Exception; + +// /** +// * 立即执行 +// */ +// void run(Long[] jobIds); +// +// /** +// * 暂停运行 +// */ +// void pause(Long[] jobIds); +// +// /** +// * 恢复运行 +// */ +// void resume(Long[] jobIds); } diff --git a/src/main/java/com/sqx/modules/job/service/impl/ScheduleJobServiceImpl.java b/src/main/java/com/sqx/modules/job/service/impl/ScheduleJobServiceImpl.java index 33db3560..1a4f6fe6 100644 --- a/src/main/java/com/sqx/modules/job/service/impl/ScheduleJobServiceImpl.java +++ b/src/main/java/com/sqx/modules/job/service/impl/ScheduleJobServiceImpl.java @@ -1,5 +1,6 @@ package com.sqx.modules.job.service.impl; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -7,40 +8,30 @@ import com.sqx.common.utils.Constant; import com.sqx.common.utils.PageUtils; import com.sqx.common.utils.Query; import com.sqx.modules.job.dao.ScheduleJobDao; +import com.sqx.modules.job.dto.RunJobDTO; import com.sqx.modules.job.entity.ScheduleJobEntity; import com.sqx.modules.job.service.ScheduleJobService; -import com.sqx.modules.job.utils.ScheduleUtils; import org.apache.commons.lang.StringUtils; -import org.quartz.CronTrigger; -import org.quartz.Scheduler; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import javax.annotation.PostConstruct; +import java.lang.reflect.Method; import java.util.*; @Service("scheduleJobService") public class ScheduleJobServiceImpl extends ServiceImpl implements ScheduleJobService { - @Autowired - private Scheduler scheduler; - - /** + + private final ApplicationContext applicationContext; + + public ScheduleJobServiceImpl(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + /** * 项目启动时,初始化定时器 */ - @PostConstruct - public void init(){ - List scheduleJobList = this.list(); - for(ScheduleJobEntity scheduleJob : scheduleJobList){ - CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, scheduleJob.getJobId()); - //如果不存在,则创建 - if(cronTrigger == null) { - ScheduleUtils.createScheduleJob(scheduler, scheduleJob); - }else { - ScheduleUtils.updateScheduleJob(scheduler, scheduleJob); - } - } - } + @Override public PageUtils queryPage(Map params) { @@ -61,25 +52,18 @@ public class ScheduleJobServiceImpl extends ServiceImpl result = new ArrayList<>(); + for(Long jobId : jobIds){ + ScheduleJobEntity jobEntity = baseMapper.selectById(jobId); + if (jobEntity == null) { + throw new RuntimeException("任务不存在"); + } - @Override - @Transactional(rollbackFor = Exception.class) - public void resume(Long[] jobIds) { - for(Long jobId : jobIds){ - ScheduleUtils.resumeJob(scheduler, jobId); - } + // 从Spring容器获取类的实例 + Object classInstance = applicationContext.getBean(StrUtil.lowerFirst(jobEntity.getBeanName())); + if (!"com.sqx.modules.job.task".equals(classInstance.getClass().getPackage().getName())) { + throw new RuntimeException("非法调用"); + } + +// if (jobDTO.getArgs() != null && !jobDTO.getArgs().isEmpty()) { +// Class[] argTypes = new Class[jobDTO.getArgs().size()]; +// for (int i = 0; i < jobDTO.getArgs().size(); i++) { +// argTypes[i] = jobDTO.getArgs().get(i).getClass(); +// } +// // 获取指定的Method对象 +// Method method = classInstance.getClass().getDeclaredMethod(jobDTO.getMethodName(), argTypes); +// +// // 调用方法并返回结果 +// return method.invoke(classInstance, jobDTO.getArgs().toArray()); +// } + // 获取指定的Method对象 + Method method = classInstance.getClass().getDeclaredMethod("run", String.class); + + // 调用方法并返回结果 + Object invoke = method.invoke(classInstance, jobEntity.getParams()); + if (invoke != null) { + result.add(invoke); + } + } + + return result; + } + + // @Override +// @Transactional(rollbackFor = Exception.class) +// public void run(Long[] jobIds) { +// for(Long jobId : jobIds){ +// ScheduleUtils.run(scheduler, this.getById(jobId)); +// } +// } +// +// @Override +// @Transactional(rollbackFor = Exception.class) +// public void pause(Long[] jobIds) { +// for(Long jobId : jobIds){ +// ScheduleUtils.pauseJob(scheduler, jobId); +// } +// +// updateBatch(jobIds, Constant.ScheduleStatus.PAUSE.getValue()); +// } +// +// @Override +// @Transactional(rollbackFor = Exception.class) +// public void resume(Long[] jobIds) { +// for(Long jobId : jobIds){ +// ScheduleUtils.resumeJob(scheduler, jobId); +// } +// +// updateBatch(jobIds, Constant.ScheduleStatus.NORMAL.getValue()); +// } - updateBatch(jobIds, Constant.ScheduleStatus.NORMAL.getValue()); - } - } diff --git a/src/main/java/com/sqx/modules/job/task/CashOutTask.java b/src/main/java/com/sqx/modules/job/task/CashOutTask.java index 75829799..b77aee96 100644 --- a/src/main/java/com/sqx/modules/job/task/CashOutTask.java +++ b/src/main/java/com/sqx/modules/job/task/CashOutTask.java @@ -18,8 +18,8 @@ import javax.annotation.Resource; import java.math.BigDecimal; import java.util.List; -@Component("CashOutTask") -public class CashOutTask implements ITask { +@Component +public class CashOutTask{ @Resource private CashOutDao cashOutDao; @@ -27,20 +27,21 @@ public class CashOutTask implements ITask { private UserMoneyService userMoneyService; @Resource private UserMoneyDetailsService userMoneyDetailsService; + @Resource + private WuyouPay wuyouPay; private Logger logger = LoggerFactory.getLogger(getClass()); - @Override public void run(String params) { logger.info("提现开始"); List cashOuts = cashOutDao.selectYesterday(); for (CashOut cashOut : cashOuts) { - if (WuyouPay.checkCanCash(cashOut.getUserId(), WithdrawTypeEnum.RED_ENVELOPE, new BigDecimal(cashOut.getMoney()))) { + if (wuyouPay.checkCanCash(cashOut.getUserId(), WithdrawTypeEnum.RED_ENVELOPE, new BigDecimal(cashOut.getMoney()))) { cashOut.setState(4); String outOrderNo = AliPayOrderUtil.createOrderId(); cashOut.setOrderNumber(outOrderNo); - BaseResp baseResp = WuyouPay.extractOrder(outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName()); + BaseResp baseResp = wuyouPay.extractOrder(outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName()); if (baseResp.getStatus() != null && baseResp.getStatus().equals(2)) { cashOut.setState(1); } else { @@ -66,4 +67,9 @@ public class CashOutTask implements ITask { } logger.info("提现结束"); } + + + public void test(String name, String age) { + logger.info("name: {}, age: {}", name, age); + } } diff --git a/src/main/java/com/sqx/modules/job/task/CashOutTask2.java b/src/main/java/com/sqx/modules/job/task/CashOutTask2.java index 8cc74dae..f2de353e 100644 --- a/src/main/java/com/sqx/modules/job/task/CashOutTask2.java +++ b/src/main/java/com/sqx/modules/job/task/CashOutTask2.java @@ -15,6 +15,7 @@ import com.sqx.modules.utils.AliPayOrderUtil; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.Resource; @@ -23,8 +24,8 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; -@Component("CashOutTask2") -public class CashOutTask2 implements ITask { +@Component +public class CashOutTask2{ @Resource private CashOutDao cashOutDao; @@ -32,10 +33,11 @@ public class CashOutTask2 implements ITask { private UserMoneyService userMoneyService; @Resource private UserMoneyDetailsService userMoneyDetailsService; + @Resource + private WuyouPay wuyouPay; private Logger logger = LoggerFactory.getLogger(getClass()); - @Override public void run(String params) { logger.info("提现开始"); if (StringUtils.isBlank(params) || isValidDate(params)) { @@ -47,11 +49,11 @@ public class CashOutTask2 implements ITask { .lt("create_at", params + " 23:59:59")); System.out.println(cashOuts.size()); for (CashOut cashOut : cashOuts) { - if (WuyouPay.checkCanCash(cashOut.getUserId(), WithdrawTypeEnum.RED_ENVELOPE, new BigDecimal(cashOut.getMoney()))) { + if (wuyouPay.checkCanCash(cashOut.getUserId(), WithdrawTypeEnum.RED_ENVELOPE, new BigDecimal(cashOut.getMoney()))) { cashOut.setState(4); String outOrderNo = AliPayOrderUtil.createOrderId(); cashOut.setOrderNumber(outOrderNo); - BaseResp baseResp = WuyouPay.extractOrder(outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName()); + BaseResp baseResp = wuyouPay.extractOrder(outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName()); if (baseResp.getStatus() != null && baseResp.getStatus().equals(2)) { cashOut.setState(1); } else { diff --git a/src/main/java/com/sqx/modules/job/task/ITask.java b/src/main/java/com/sqx/modules/job/task/ITask.java deleted file mode 100644 index 2e98de28..00000000 --- a/src/main/java/com/sqx/modules/job/task/ITask.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.sqx.modules.job.task; - -/** - * 定时任务接口,所有定时任务都要实现该接口 - * - */ -public interface ITask { - - /** - * 执行定时任务接口 - * - * @param params 参数,多参数使用JSON数据 - */ - void run(String params); -} \ No newline at end of file diff --git a/src/main/java/com/sqx/modules/job/task/SpinningTask3.java b/src/main/java/com/sqx/modules/job/task/SpinningTask3.java index 2f083680..fc3d89c8 100644 --- a/src/main/java/com/sqx/modules/job/task/SpinningTask3.java +++ b/src/main/java/com/sqx/modules/job/task/SpinningTask3.java @@ -9,14 +9,17 @@ import com.sqx.modules.discSpinning.service.DiscSpinningService; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Date; import java.util.List; -@Component("SpinningTask3") -public class SpinningTask3 implements ITask { +@Component +@EnableScheduling +public class SpinningTask3 { @Resource private DiscSpinningService spinningController; @@ -25,8 +28,12 @@ public class SpinningTask3 implements ITask { private Logger logger = LoggerFactory.getLogger(getClass()); - @Override - public void run(String params) { + @Scheduled(cron = "0 0/2 * * * ? ") + public void record() { + record("1"); + } + + public void record(String params) { logger.info("大转盘到账补偿机制"); // 获取当前时间 Date now = DateUtil.date(); @@ -48,6 +55,7 @@ public class SpinningTask3 implements ITask { recordQueryWrapper.lt("create_time", fiveMinutesAgoStr); //小于 recordQueryWrapper.gt("create_time", tenMinutesAgoStr); + logger.info("大转盘到账补偿时间范围:{}-----{}", tenMinutesAgoStr, fiveMinutesAgoStr); List list = recordService.list(recordQueryWrapper); ThreadUtil.execAsync(() -> { for (DiscSpinningRecord record : list) { diff --git a/src/main/java/com/sqx/modules/job/task/SupplyAgainSignRewardTask.java b/src/main/java/com/sqx/modules/job/task/SupplyAgainSignRewardTask.java index 57527923..6c5dd15e 100644 --- a/src/main/java/com/sqx/modules/job/task/SupplyAgainSignRewardTask.java +++ b/src/main/java/com/sqx/modules/job/task/SupplyAgainSignRewardTask.java @@ -21,8 +21,8 @@ import java.util.List; * @author GYJoker */ @Slf4j -@Component("SupplyAgainSignRewardTask") -public class SupplyAgainSignRewardTask implements ITask { +@Component +public class SupplyAgainSignRewardTask{ @Autowired private UserService userService; @@ -35,7 +35,6 @@ public class SupplyAgainSignRewardTask implements ITask { @Autowired private UserMoneyService userMoneyService; - @Override public void run(String params) { if (StringUtils.isBlank(params)) { log.error("参数为空"); diff --git a/src/main/java/com/sqx/modules/job/task/TempCashOutTask.java b/src/main/java/com/sqx/modules/job/task/TempCashOutTask.java index a7a9adc2..73e6f2d8 100644 --- a/src/main/java/com/sqx/modules/job/task/TempCashOutTask.java +++ b/src/main/java/com/sqx/modules/job/task/TempCashOutTask.java @@ -2,8 +2,6 @@ package com.sqx.modules.job.task; import cn.hutool.core.date.DateUtil; import cn.hutool.json.JSONUtil; -import com.sqx.modules.app.service.UserMoneyDetailsService; -import com.sqx.modules.app.service.UserMoneyService; import com.sqx.modules.pay.dao.CashOutDao; import com.sqx.modules.pay.entity.CashOut; import com.sqx.modules.pay.wuyou.BaseResp; @@ -15,24 +13,21 @@ import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.List; -@Component("TempCashOutTask") -public class TempCashOutTask implements ITask { +@Component +public class TempCashOutTask{ @Resource private CashOutDao cashOutDao; @Resource - private UserMoneyService userMoneyService; - @Resource - private UserMoneyDetailsService userMoneyDetailsService; + private WuyouPay wuyouPay; private Logger logger = LoggerFactory.getLogger(getClass()); - @Override public void run(String params) { logger.info("提现开始"); List cashOuts = cashOutDao.selectTemp(); for (CashOut cashOut : cashOuts) { - BaseResp baseResp = WuyouPay.queryExtractOrder(cashOut.getOrderNumber(), cashOut.getMoney()); + BaseResp baseResp = wuyouPay.queryExtractOrder(cashOut.getOrderNumber(), cashOut.getMoney()); logger.info("baseResp:{} ", JSONUtil.toJsonStr(baseResp)); if (baseResp.getStatus() != null && (baseResp.getStatus().equals(2) || baseResp.getStatus().equals(10000))){ logger.info("success:{} ", cashOut.getOrderNumber()); diff --git a/src/main/java/com/sqx/modules/job/task/TempOrdersTask.java b/src/main/java/com/sqx/modules/job/task/TempOrdersTask.java index f9d5d4d1..a09738d2 100644 --- a/src/main/java/com/sqx/modules/job/task/TempOrdersTask.java +++ b/src/main/java/com/sqx/modules/job/task/TempOrdersTask.java @@ -40,8 +40,8 @@ import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; -@Component("TempOrdersTask") -public class TempOrdersTask implements ITask { +@Component +public class TempOrdersTask { @Resource private OrdersDao ordersDao; @@ -65,11 +65,12 @@ public class TempOrdersTask implements ITask { private InviteDao inviteDao; @Resource private CompletAwardService completAwardService; + @Resource + private WuyouPay wuyouPay; private Logger logger = LoggerFactory.getLogger(getClass()); - @Override public void run(String params) { logger.info("订单表数据处理开始"); List orders = ordersDao.selectList(Wrappers.lambdaQuery() @@ -92,7 +93,7 @@ public class TempOrdersTask implements ITask { continue; } try { - BaseResp baseResp = WuyouPay.queryOrder(payDetails.getTradeNo(), order.getPayMoney().toString(), "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1 Edg/131.0.0.0"); + BaseResp baseResp = wuyouPay.queryOrder(payDetails.getTradeNo(), order.getPayMoney().toString(), "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1 Edg/131.0.0.0"); logger.info("baseResp:{} ", JSONUtil.toJsonStr(baseResp)); if (baseResp.getCode() == null || baseResp.getCode() != 200) { continue; @@ -104,13 +105,13 @@ public class TempOrdersTask implements ITask { logger.info("payDetails:{} ", JSONUtil.toJsonStr(payDetails)); logger.info("order:{} ", JSONUtil.toJsonStr(order)); updateOrderStatus(payDetails, order); - }else { + } else { order.setStatus(3); payDetails.setState(2); ordersDao.updateById(order); payDetailsDao.updateById(payDetails); } - }catch (Exception e){ + } catch (Exception e) { e.printStackTrace(); logger.error("订单数据处理异常:", e); } @@ -119,17 +120,13 @@ public class TempOrdersTask implements ITask { logger.info("订单表数据处理完毕"); } - public static void main(String[] args) { - WuyouPay.queryOrder("1000001323859732", "0.5", "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1 Edg/131.0.0.0"); - } - private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private void updateOrderStatus(PayDetails payDetails, Orders order) { String format = sdf.format(new Date()); - payDetailsDao.updateState(payDetails.getId(), 1, format, payDetails.getTradeNo()); + payDetailsDao.updateState(payDetails.getId(), 1, format, payDetails.getTradeNo(), payDetails.getThirdOrderNo()); order.setPayWay(9); order.setStatus(1); diff --git a/src/main/java/com/sqx/modules/job/task/TestTask.java b/src/main/java/com/sqx/modules/job/task/TestTask.java deleted file mode 100644 index 8f566e10..00000000 --- a/src/main/java/com/sqx/modules/job/task/TestTask.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.sqx.modules.job.task; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -/** - * 测试定时任务(演示Demo,可删除) - * - * testTask为spring bean的名称 - * - */ -@Component("testTask") -public class TestTask implements ITask { - private Logger logger = LoggerFactory.getLogger(getClass()); - - @Override - public void run(String params){ - - logger.debug("TestTask定时任务正在执行,参数为:{}", params); - } - - - -} diff --git a/src/main/java/com/sqx/modules/job/utils/ScheduleJob.java b/src/main/java/com/sqx/modules/job/utils/ScheduleJob.java deleted file mode 100644 index deb910fb..00000000 --- a/src/main/java/com/sqx/modules/job/utils/ScheduleJob.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.sqx.modules.job.utils; - -import com.sqx.common.utils.SpringContextUtils; -import com.sqx.modules.job.entity.ScheduleJobEntity; -import com.sqx.modules.job.entity.ScheduleJobLogEntity; -import com.sqx.modules.job.service.ScheduleJobLogService; -import org.apache.commons.lang.StringUtils; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.scheduling.quartz.QuartzJobBean; - -import java.lang.reflect.Method; -import java.util.Date; - - -/** - * 定时任务 - * - */ -public class ScheduleJob extends QuartzJobBean { - private Logger logger = LoggerFactory.getLogger(getClass()); - - @Override - protected void executeInternal(JobExecutionContext context) throws JobExecutionException { - ScheduleJobEntity scheduleJob = (ScheduleJobEntity) context.getMergedJobDataMap() - .get(ScheduleJobEntity.JOB_PARAM_KEY); - - //获取spring bean - ScheduleJobLogService scheduleJobLogService = (ScheduleJobLogService) SpringContextUtils.getBean("scheduleJobLogService"); - - //数据库保存执行记录 - ScheduleJobLogEntity log = new ScheduleJobLogEntity(); - log.setJobId(scheduleJob.getJobId()); - log.setBeanName(scheduleJob.getBeanName()); - log.setParams(scheduleJob.getParams()); - log.setCreateTime(new Date()); - - //任务开始时间 - long startTime = System.currentTimeMillis(); - - try { - //执行任务 - logger.debug("任务准备执行,任务ID:" + scheduleJob.getJobId()); - - Object target = SpringContextUtils.getBean(scheduleJob.getBeanName()); - Method method = target.getClass().getDeclaredMethod("run", String.class); - method.invoke(target, scheduleJob.getParams()); - - //任务执行总时长 - long times = System.currentTimeMillis() - startTime; - log.setTimes((int)times); - //任务状态 0:成功 1:失败 - log.setStatus(0); - - logger.debug("任务执行完毕,任务ID:" + scheduleJob.getJobId() + " 总共耗时:" + times + "毫秒"); - } catch (Exception e) { - logger.error("任务执行失败,任务ID:" + scheduleJob.getJobId(), e); - - //任务执行总时长 - long times = System.currentTimeMillis() - startTime; - log.setTimes((int)times); - - //任务状态 0:成功 1:失败 - log.setStatus(1); - log.setError(StringUtils.substring(e.toString(), 0, 2000)); - }finally { - scheduleJobLogService.save(log); - } - } -} diff --git a/src/main/java/com/sqx/modules/job/utils/ScheduleUtils.java b/src/main/java/com/sqx/modules/job/utils/ScheduleUtils.java deleted file mode 100644 index f2895570..00000000 --- a/src/main/java/com/sqx/modules/job/utils/ScheduleUtils.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.sqx.modules.job.utils; - -import com.sqx.common.exception.SqxException; -import com.sqx.common.utils.Constant; -import com.sqx.modules.job.entity.ScheduleJobEntity; -import org.quartz.*; - -/** - * 定时任务工具类 - * - */ -public class ScheduleUtils { - private final static String JOB_NAME = "TASK_"; - - /** - * 获取触发器key - */ - public static TriggerKey getTriggerKey(Long jobId) { - return TriggerKey.triggerKey(JOB_NAME + jobId); - } - - /** - * 获取jobKey - */ - public static JobKey getJobKey(Long jobId) { - return JobKey.jobKey(JOB_NAME + jobId); - } - - /** - * 获取表达式触发器 - */ - public static CronTrigger getCronTrigger(Scheduler scheduler, Long jobId) { - try { - return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId)); - } catch (SchedulerException e) { - throw new SqxException("获取定时任务CronTrigger出现异常", e); - } - } - - /** - * 创建定时任务 - */ - public static void createScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) { - try { - //构建job信息 - JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(scheduleJob.getJobId())).build(); - - //表达式调度构建器 - CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()) - .withMisfireHandlingInstructionDoNothing(); - - //按新的cronExpression表达式构建一个新的trigger - CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(scheduleJob.getJobId())).withSchedule(scheduleBuilder).build(); - - //放入参数,运行时的方法可以获取 - jobDetail.getJobDataMap().put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob); - - scheduler.scheduleJob(jobDetail, trigger); - - //暂停任务 - if(scheduleJob.getStatus() == Constant.ScheduleStatus.PAUSE.getValue()){ - pauseJob(scheduler, scheduleJob.getJobId()); - } - } catch (SchedulerException e) { - throw new SqxException("创建定时任务失败", e); - } - } - - /** - * 更新定时任务 - */ - public static void updateScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) { - try { - TriggerKey triggerKey = getTriggerKey(scheduleJob.getJobId()); - - //表达式调度构建器 - CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()) - .withMisfireHandlingInstructionDoNothing(); - - CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getJobId()); - - //按新的cronExpression表达式重新构建trigger - trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); - - //参数 - trigger.getJobDataMap().put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob); - - scheduler.rescheduleJob(triggerKey, trigger); - - //暂停任务 - if(scheduleJob.getStatus() == Constant.ScheduleStatus.PAUSE.getValue()){ - pauseJob(scheduler, scheduleJob.getJobId()); - } - - } catch (SchedulerException e) { - throw new SqxException("更新定时任务失败", e); - } - } - - /** - * 立即执行任务 - */ - public static void run(Scheduler scheduler, ScheduleJobEntity scheduleJob) { - try { - //参数 - JobDataMap dataMap = new JobDataMap(); - dataMap.put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob); - - scheduler.triggerJob(getJobKey(scheduleJob.getJobId()), dataMap); - } catch (SchedulerException e) { - throw new SqxException("立即执行定时任务失败", e); - } - } - - /** - * 暂停任务 - */ - public static void pauseJob(Scheduler scheduler, Long jobId) { - try { - scheduler.pauseJob(getJobKey(jobId)); - } catch (SchedulerException e) { - throw new SqxException("暂停定时任务失败", e); - } - } - - /** - * 恢复任务 - */ - public static void resumeJob(Scheduler scheduler, Long jobId) { - try { - scheduler.resumeJob(getJobKey(jobId)); - } catch (SchedulerException e) { - throw new SqxException("暂停定时任务失败", e); - } - } - - /** - * 删除定时任务 - */ - public static void deleteScheduleJob(Scheduler scheduler, Long jobId) { - try { - scheduler.deleteJob(getJobKey(jobId)); - } catch (SchedulerException e) { - throw new SqxException("删除定时任务失败", e); - } - } -} diff --git a/src/main/java/com/sqx/modules/message/controller/app/AppMessageController.java b/src/main/java/com/sqx/modules/message/controller/app/AppMessageController.java index 5c88fe00..fea87a1e 100644 --- a/src/main/java/com/sqx/modules/message/controller/app/AppMessageController.java +++ b/src/main/java/com/sqx/modules/message/controller/app/AppMessageController.java @@ -70,6 +70,14 @@ public class AppMessageController { return Result.success(); } + @Login + @PostMapping("/sendMessage") + @ApiOperation("添加投诉") + public Result sendMessage(@RequestBody MessageInfo messageInfo){ + messageService.saveBody(messageInfo); + return Result.success(); + } + diff --git a/src/main/java/com/sqx/modules/orders/controller/OrdersController.java b/src/main/java/com/sqx/modules/orders/controller/OrdersController.java index 3c6d5511..0eb417f9 100644 --- a/src/main/java/com/sqx/modules/orders/controller/OrdersController.java +++ b/src/main/java/com/sqx/modules/orders/controller/OrdersController.java @@ -93,7 +93,7 @@ public class OrdersController extends AbstractController { Double tuiMemberOrdersMoney = ordersService.selectOrdersMoney(2, 2, flag, time, null, sysUserId); //提现 Integer cashCount = cashOutDao.selectCount(new QueryWrapper() - .eq("sys_user_id", sysUserId) +// .eq("sys_user_id", sysUserId) .eq("state", 1) .gt("create_at", DateUtil.format(DateUtil.parse(time, "yyyy-MM-dd"), "yyyy-MM-dd HH:mm:ss"))); Double cashSum = cashOutDao.selectSysUserCashOutSum(sysUserId, DateUtil.format(DateUtil.parse(time, "yyyy-MM-dd"), "yyyy-MM-dd HH:mm:ss")); diff --git a/src/main/java/com/sqx/modules/orders/service/impl/OrdersServiceImpl.java b/src/main/java/com/sqx/modules/orders/service/impl/OrdersServiceImpl.java index b1956c4e..bfafba8d 100644 --- a/src/main/java/com/sqx/modules/orders/service/impl/OrdersServiceImpl.java +++ b/src/main/java/com/sqx/modules/orders/service/impl/OrdersServiceImpl.java @@ -38,6 +38,7 @@ import com.sqx.modules.pay.controller.app.AliPayController; import com.sqx.modules.pay.service.DyService; import com.sqx.modules.pay.service.WxService; import com.sqx.modules.utils.AliPayOrderUtil; +import com.sqx.modules.utils.TimeCompleteUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -657,8 +658,9 @@ public class OrdersServiceImpl extends ServiceImpl implements Integer flag, String time, String userName, Integer ordersType, String startTime, String endTime, Long sysUserId, String qdCode, String sysUserName) { Page pages = new Page<>(page, limit); + return Result.success().put("data", new PageUtils(baseMapper.selectOrdersByOrdersNo(pages, ordersNo, status, userId, courseId, - flag, time, userName, ordersType, startTime, endTime, sysUserId, qdCode, sysUserName))); + flag, time, userName, ordersType, TimeCompleteUtils.completeStartTime(startTime), TimeCompleteUtils.completeEndTime(endTime), sysUserId, qdCode, sysUserName))); } @Override diff --git a/src/main/java/com/sqx/modules/pay/controller/CashController.java b/src/main/java/com/sqx/modules/pay/controller/CashController.java index ea98a0b8..63167c20 100644 --- a/src/main/java/com/sqx/modules/pay/controller/CashController.java +++ b/src/main/java/com/sqx/modules/pay/controller/CashController.java @@ -1,6 +1,8 @@ package com.sqx.modules.pay.controller; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSON; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; @@ -211,9 +213,21 @@ public class CashController { @ApiOperation("财务提现统计") @GetMapping("/statisticsCashMoney") public Result statisticsMoney(String time, Integer flag) { - Double sumMoney = cashOutService.sumMoney(time, flag); - Integer countMoney = cashOutService.countMoney(time, flag); - Integer stayMoney = cashOutService.stayMoney(time, flag); + DateTime parse = DateUtil.parse(time, "yyyy-MM-dd"); + + String startTime = DateUtil.format(parse, "yyyy-MM-dd 00:00:00"); + String endTime = DateUtil.format(parse, "yyyy-MM-dd 23:59:59"); + if (flag == 2) { + startTime = DateUtil.format(DateUtil.beginOfMonth(parse), "yyyy-MM-dd 00:00:00"); + endTime = DateUtil.format(DateUtil.endOfMonth(parse), "yyyy-MM-dd 23:59:59"); + } else if (flag == 3) { + startTime = DateUtil.format(DateUtil.beginOfYear(parse), "yyyy-MM-dd 00:00:00"); + endTime = DateUtil.format(DateUtil.endOfYear(parse), "yyyy-MM-dd 23:59:59"); + } + + Double sumMoney = cashOutService.sumMoney(startTime, endTime, flag); + Integer countMoney = cashOutService.countMoney(startTime, endTime, flag); + Integer stayMoney = cashOutService.stayMoney(startTime, endTime, flag); Map map = new HashMap<>(); map.put("sumMoney", sumMoney == null ? 0.00 : sumMoney); map.put("countMoney", countMoney == null ? 0 : countMoney); diff --git a/src/main/java/com/sqx/modules/pay/controller/app/AliPayController.java b/src/main/java/com/sqx/modules/pay/controller/app/AliPayController.java index ec5f508d..b0c40bce 100644 --- a/src/main/java/com/sqx/modules/pay/controller/app/AliPayController.java +++ b/src/main/java/com/sqx/modules/pay/controller/app/AliPayController.java @@ -32,9 +32,6 @@ import com.sqx.modules.pay.dao.PayDetailsDao; import com.sqx.modules.pay.entity.PayClassify; import com.sqx.modules.pay.entity.PayDetails; import com.sqx.modules.pay.service.PayClassifyService; -import com.yungouos.pay.alipay.AliPay; -import com.yungouos.pay.entity.AliPayH5Biz; -import com.yungouos.pay.util.PaySignUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -109,16 +106,16 @@ public class AliPayController { log.info(flag + "回调验证信息"); if (flag) { String tradeStatus = params.get("trade_status"); - if("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)){ + if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) { //支付宝返回的订单编号 String outTradeNo = params.get("out_trade_no"); //支付宝支付单号 String tradeNo = params.get("trade_no"); PayDetails payDetails = payDetailsDao.selectByOrderId(outTradeNo); - if(payDetails.getState()==0){ + if (payDetails.getState() == 0) { String format = sdf.format(new Date()); - payDetailsDao.updateState(payDetails.getId(),1,format,tradeNo); - if(payDetails.getType()==1){ + payDetailsDao.updateState(payDetails.getId(), 1, format, tradeNo,""); + if (payDetails.getType() == 1) { Orders orders = ordersService.selectOrderByOrdersNo(payDetails.getOrderId()); orders.setPayWay(4); orders.setStatus(1); @@ -128,34 +125,34 @@ public class AliPayController { UserEntity byUser = userService.queryByInvitationCode(user.getInviterCode()); Map map = inviteService.updateInvite(byUser, format, user.getUserId(), orders.getPayMoney()); Object oneUserId = map.get("oneUserId"); - if(oneUserId!=null){ + if (oneUserId != null) { orders.setOneUserId(Long.parseLong(String.valueOf(oneUserId))); orders.setOneMoney(new BigDecimal(String.valueOf(map.get("oneMoney")))); } Object twoUserId = map.get("twoUserId"); - if(twoUserId!=null){ + if (twoUserId != null) { orders.setTwoUserId(Long.parseLong(String.valueOf(twoUserId))); orders.setTwoMoney(new BigDecimal(String.valueOf(map.get("twoMoney")))); } Object sysUserId = map.get("sysUserId"); - if(sysUserId!=null){ + if (sysUserId != null) { orders.setSysUserId(Long.parseLong(String.valueOf(sysUserId))); orders.setQdMoney(new BigDecimal(String.valueOf(map.get("qdMoney")))); } ordersService.updateById(orders); ordersService.insertOrders(orders); - }else{ + } else { String remark = payDetails.getRemark(); PayClassify payClassify = payClassifyService.getById(Long.parseLong(remark)); BigDecimal add = payClassify.getMoney().add(payClassify.getGiveMoney()); - userMoneyService.updateMoney(1,payDetails.getUserId(),add.doubleValue()); - UserMoneyDetails userMoneyDetails=new UserMoneyDetails(); + userMoneyService.updateMoney(1, payDetails.getUserId(), add.doubleValue()); + UserMoneyDetails userMoneyDetails = new UserMoneyDetails(); // ✅ userMoneyDetails.setClassify(2); userMoneyDetails.setMoney(add); userMoneyDetails.setUserId(payDetails.getUserId()); userMoneyDetails.setContent("支付宝充值金币"); - userMoneyDetails.setTitle("支付宝充值金币:"+payClassify.getMoney()+",赠送:"+payClassify.getGiveMoney()); + userMoneyDetails.setTitle("支付宝充值金币:" + payClassify.getMoney() + ",赠送:" + payClassify.getGiveMoney()); userMoneyDetails.setType(1); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); userMoneyDetails.setCreateTime(simpleDateFormat.format(new Date())); @@ -179,92 +176,15 @@ public class AliPayController { @ApiOperation("支付宝回调") @RequestMapping("/notifyAppYunOS") @Transactional(rollbackFor = Exception.class) - public String notifyAppYunOS(HttpServletRequest request, HttpServletResponse response){ - //获取支付宝POST过来反馈信息 - Map params = new HashMap(); - Map requestParams = request.getParameterMap(); - for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) { - String name = (String) iter.next(); - String[] values = (String[]) requestParams.get(name); - String valueStr = ""; - for (int i = 0; i < values.length; i++) { - valueStr = (i == values.length - 1) ? valueStr + values[i] - : valueStr + values[i] + ","; - } - //乱码解决,这段代码在出现乱码时使用。 - //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); - params.put(name, valueStr); - } - String outTradeNo = params.get("outTradeNo"); - String code = params.get("code"); - String key = commonInfoService.findOne(169).getValue(); - try { - boolean flag = PaySignUtil.checkNotifySign(request, key); - if(flag){ - if("1".equals(code)){ - PayDetails payDetails=payDetailsDao.selectByOrderId(outTradeNo); - if(payDetails.getState()==0) { - String format = sdf.format(new Date()); - payDetailsDao.updateState(payDetails.getId(),1,format,null); - if(payDetails.getType()==1){ - Orders orders = ordersService.selectOrderByOrdersNo(payDetails.getOrderId()); - orders.setPayWay(4); - orders.setStatus(1); - orders.setPayTime(DateUtils.format(new Date())); - ordersService.updateById(orders); - UserEntity user = userService.selectUserById(orders.getUserId()); - UserEntity byUser = userService.queryByInvitationCode(user.getInviterCode()); - Map map = inviteService.updateInvite(byUser, format, user.getUserId(), orders.getPayMoney()); - Object oneUserId = map.get("oneUserId"); - if(oneUserId!=null){ - orders.setOneUserId(Long.parseLong(String.valueOf(oneUserId))); - orders.setOneMoney(new BigDecimal(String.valueOf(map.get("oneMoney")))); - } - Object twoUserId = map.get("twoUserId"); - if(twoUserId!=null){ - orders.setTwoUserId(Long.parseLong(String.valueOf(twoUserId))); - orders.setTwoMoney(new BigDecimal(String.valueOf(map.get("twoMoney")))); - } - Object sysUserId = map.get("sysUserId"); - if(sysUserId!=null){ - orders.setSysUserId(Long.parseLong(String.valueOf(sysUserId))); - orders.setQdMoney(new BigDecimal(String.valueOf(map.get("qdMoney")))); - } - ordersService.insertOrders(orders); - }else{ - String remark = payDetails.getRemark(); - PayClassify payClassify = payClassifyService.getById(Long.parseLong(remark)); - BigDecimal add = payClassify.getMoney().add(payClassify.getGiveMoney()); - userMoneyService.updateMoney(1,payDetails.getUserId(),add.doubleValue()); - UserMoneyDetails userMoneyDetails=new UserMoneyDetails(); - // ✅ - userMoneyDetails.setClassify(2); - userMoneyDetails.setMoney(add); - userMoneyDetails.setUserId(payDetails.getUserId()); - userMoneyDetails.setContent("支付宝充值金币"); - userMoneyDetails.setTitle("支付宝充值金币:"+payClassify.getMoney()+",赠送:"+payClassify.getGiveMoney()); - userMoneyDetails.setType(1); - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - userMoneyDetails.setCreateTime(simpleDateFormat.format(new Date())); - userMoneyDetails.setMoneyType(2); - userMoneyDetailsService.save(userMoneyDetails); - } - } - } - return "SUCCESS"; - } - } catch (Exception e) { - e.printStackTrace(); - log.error("云购os支付报错!"+e.getMessage()); - } - return null; + public String notifyAppYunOS(HttpServletRequest request, HttpServletResponse response) { + return "SUCCESS"; } @Login @ApiOperation("支付宝支付订单") @RequestMapping(value = "/payOrder", method = RequestMethod.POST) @Transactional(rollbackFor = Exception.class) - public Result payOrder(Long orderId,Integer classify) { + public Result payOrder(Long orderId, Integer classify) { //通知页面地址 CommonInfo one = commonInfoService.findOne(19); String returnUrl = one.getValue() + "/#/pages/task/recharge"; @@ -274,17 +194,17 @@ public class AliPayController { log.info("回调地址:" + url); Orders orders = ordersDao.selectById(orderId); PayDetails payDetails = payDetailsDao.selectByOrderId(orders.getOrdersNo()); - if(payDetails==null){ - payDetails=new PayDetails(); + if (payDetails == null) { + payDetails = new PayDetails(); payDetails.setState(0); payDetails.setCreateTime(sdf.format(new Date())); payDetails.setOrderId(orders.getOrdersNo()); payDetails.setUserId(orders.getUserId()); payDetails.setMoney(orders.getPayMoney().doubleValue()); payDetails.setType(1); - if(classify==1){ + if (classify == 1) { payDetails.setClassify(4); - }else{ + } else { payDetails.setClassify(5); } payDetailsDao.insert(payDetails); @@ -300,7 +220,7 @@ public class AliPayController { @ApiOperation("支付宝支付订单") @RequestMapping(value = "/payMoney", method = RequestMethod.POST) @Transactional(rollbackFor = Exception.class) - public Result payMoney(Long payClassifyId, Integer classify,@RequestAttribute Long userId) { + public Result payMoney(Long payClassifyId, Integer classify, @RequestAttribute Long userId) { //通知页面地址 CommonInfo one = commonInfoService.findOne(19); String returnUrl = one.getValue() + "/#/pages/task/recharge"; @@ -310,15 +230,15 @@ public class AliPayController { log.info("回调地址:" + url); String generalOrder = getGeneralOrder(); PayClassify payClassify = payClassifyService.getById(payClassifyId); - PayDetails payDetails=new PayDetails(); + PayDetails payDetails = new PayDetails(); payDetails.setState(0); payDetails.setCreateTime(sdf.format(new Date())); payDetails.setOrderId(generalOrder); payDetails.setUserId(userId); payDetails.setMoney(payClassify.getPrice().doubleValue()); - if(classify==1){ + if (classify == 1) { payDetails.setClassify(4); - }else{ + } else { payDetails.setClassify(5); } payDetails.setType(2); @@ -368,7 +288,6 @@ public class AliPayController { } - public Result payApp(String name, String generalOrder, Double money) { CommonInfo one = commonInfoService.findOne(19); String url = one.getValue() + "/sqx_fast/app/aliPay/notifyApp"; @@ -405,7 +324,7 @@ public class AliPayController { model.setSubject(name); model.setOutTradeNo(generalOrder); model.setTimeoutExpress("30m"); - model.setTotalAmount(money +""); + model.setTotalAmount(money + ""); model.setProductCode("QUICK_MSECURITY_PAY"); request.setBizModel(model); request.setNotifyUrl(url); @@ -417,7 +336,7 @@ public class AliPayController { return Result.error("获取订单失败!"); } return Result.success().put("data", result); - } else if("2".equals(payWay.getValue())){ + } else if ("2".equals(payWay.getValue())) { //实例化客户端 AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", commonInfoService.findOne(63).getValue(), commonInfoService.findOne(65).getValue(), "json", AliPayConstants.CHARSET, commonInfoService.findOne(64).getValue(), "RSA2"); //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay @@ -439,13 +358,6 @@ public class AliPayController { return Result.error("获取订单失败!"); } return Result.success().put("data", result); - }else{ - url=one.getValue()+"/sqx_fast/app/aliPay/notifyAppYunOS"; - log.info("回调地址:"+url); - String mchId = commonInfoService.findOne(168).getValue(); - String key = commonInfoService.findOne(169).getValue(); - result = AliPay.appPay(generalOrder, String.valueOf(money), mchId, name ,null, url, null, null, null, null,key); - return Result.success().put("data", result); } } catch (AlipayApiException e) { e.printStackTrace(); @@ -491,7 +403,7 @@ public class AliPayController { alipayRequest.setReturnUrl(returnUrl); //线上通知页面地址 String result = alipayClient.pageExecute(alipayRequest).getBody(); return Result.success().put("data", result); - } else if ("2".equals(payWay.getValue())){ + } else if ("2".equals(payWay.getValue())) { AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", commonInfoService.findOne(63).getValue(), commonInfoService.findOne(65).getValue(), "json", AliPayConstants.CHARSET, commonInfoService.findOne(64).getValue(), "RSA2"); AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest(); JSONObject order = new JSONObject(); @@ -507,13 +419,6 @@ public class AliPayController { alipayRequest.setReturnUrl(returnUrl); String form = alipayClient.pageExecute(alipayRequest).getBody(); return Result.success().put("data", form); - }else{ - url=one.getValue()+"/sqx_fast/app/aliPay/notifyAppYunOS"; - log.info("回调地址:"+url); - String mchId = commonInfoService.findOne(168).getValue(); - String key = commonInfoService.findOne(169).getValue(); - AliPayH5Biz aliPayH5Biz = AliPay.h5Pay(generalOrder, String.valueOf(money), mchId, name, null, url, returnUrl, null, null, null,null,key); - return Result.success().put("data", aliPayH5Biz.getForm()); } } catch (AlipayApiException e) { log.error("CreatPayOrderForH5", e); @@ -522,5 +427,4 @@ public class AliPayController { } - } diff --git a/src/main/java/com/sqx/modules/pay/controller/app/WuyouController.java b/src/main/java/com/sqx/modules/pay/controller/app/WuyouController.java index baad5c22..c3811033 100644 --- a/src/main/java/com/sqx/modules/pay/controller/app/WuyouController.java +++ b/src/main/java/com/sqx/modules/pay/controller/app/WuyouController.java @@ -9,8 +9,10 @@ import com.sqx.common.utils.ApiAccessLimitUtil; import com.sqx.common.utils.DateUtils; import com.sqx.common.utils.RedisKeys; import com.sqx.common.utils.Result; +import com.sqx.modules.app.entity.InviteAchievement; import com.sqx.modules.app.entity.UserEntity; import com.sqx.modules.app.entity.UserMoneyDetails; +import com.sqx.modules.app.service.InviteAchievementService; import com.sqx.modules.app.service.UserMoneyDetailsService; import com.sqx.modules.app.service.UserMoneyService; import com.sqx.modules.app.service.UserService; @@ -71,13 +73,13 @@ public class WuyouController { private final CashOutDao cashOutDao; private final CompletAwardService completAwardService; private final SysUserService sysUserService; - private final ApplicationContext applicationContext; - ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5); + private final WuyouPay wuyouPay; + private final InviteAchievementService inviteAchievementService; private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); WuyouController(OrdersService ordersService, PayDetailsDao payDetailsDao, UserService userService, InviteService inviteService, CashOutDao cashOutDao, UserMoneyService userMoneyService, UserMoneyDetailsService userMoneyDetailsService, CommonInfoService commonRepository, - InviteDao inviteDao, CompletAwardService completAwardService, SysUserService sysUserService, ApplicationContext applicationContext) { + InviteDao inviteDao, CompletAwardService completAwardService, SysUserService sysUserService, WuyouPay wuyouPay, InviteAchievementService inviteAchievementService) { this.ordersService = ordersService; this.payDetailsDao = payDetailsDao; this.userService = userService; @@ -89,59 +91,59 @@ public class WuyouController { this.inviteDao = inviteDao; this.completAwardService = completAwardService; this.sysUserService = sysUserService; - this.applicationContext = applicationContext; + this.wuyouPay = wuyouPay; + this.inviteAchievementService = inviteAchievementService; } @Debounce(interval = 1000, value = "#orderId") @ApiOperation("支付订单") @GetMapping("/payOrder/{orderId}") public Result payOrder(HttpServletRequest request, @PathVariable("orderId") Long orderId, @RequestParam(value = "payType", required = false) String payType) { - return Result.error("暂无可支付渠道"); -// Orders order = ordersService.getById(orderId); -// if (order == null) { -// return Result.error("订单不存在"); -// } -// -// if (order.getStatus() != 0) { -// return Result.error("订单已支付"); -// } -// -// PayDetails payDetails = payDetailsDao.selectByOrderId(order.getOrdersNo()); -// if (payDetails == null) { -// payDetails = new PayDetails(); -// payDetails.setState(0); -// payDetails.setCreateTime(sdf.format(new Date())); -// payDetails.setOrderId(order.getOrdersNo()); -// payDetails.setUserId(order.getUserId()); -// payDetails.setMoney(order.getPayMoney().doubleValue()); -// payDetails.setType(1); -// payDetails.setClassify(9); -// payDetails.setTradeNo(AliPayOrderUtil.createOrderId()); -// payDetailsDao.insert(payDetails); -// } else { -// payDetails.setTradeNo(AliPayOrderUtil.createOrderId()); -// payDetailsDao.updateById(payDetails); -// } -// -// if (order.getPayMoney().compareTo(BigDecimal.ZERO) == 0) { -// updateOrderStatus(payDetails, order); -// Map data = new HashMap<>(); -// data.put("tradeNo", payDetails.getTradeNo()); -// data.put("payStatus", 1); -// return Result.success().put("data", data); -// } -// -// BaseResp baseResp = WuyouPay.payOrder(payDetails.getTradeNo(), order.getPayMoney().toString(), -// request.getHeader("User-Agent"), String.format("%d-%d", order.getCourseId(), order.getCourseDetailsId()), -// payType); -// if (baseResp.getCode() == null) { -// return Result.error(baseResp.getErrorMsg()); -// } -// if (baseResp.getCode() != 200) { -// return Result.error(baseResp.getMsg()); -// } -// -// return Result.success().put("data", baseResp.getData()); + Orders order = ordersService.getById(orderId); + if (order == null) { + return Result.error("订单不存在"); + } + + if (order.getStatus() != 0) { + return Result.error("订单已支付"); + } + + PayDetails payDetails = payDetailsDao.selectByOrderId(order.getOrdersNo()); + if (payDetails == null) { + payDetails = new PayDetails(); + payDetails.setState(0); + payDetails.setCreateTime(sdf.format(new Date())); + payDetails.setOrderId(order.getOrdersNo()); + payDetails.setUserId(order.getUserId()); + payDetails.setMoney(order.getPayMoney().doubleValue()); + payDetails.setType(1); + payDetails.setClassify(9); + payDetails.setTradeNo(AliPayOrderUtil.createOrderId()); + payDetailsDao.insert(payDetails); + } else { + payDetails.setTradeNo(AliPayOrderUtil.createOrderId()); + payDetailsDao.updateById(payDetails); + } + + if (order.getPayMoney().compareTo(BigDecimal.ZERO) == 0) { + updateOrderStatus(payDetails, order); + Map data = new HashMap<>(); + data.put("tradeNo", payDetails.getTradeNo()); + data.put("payStatus", 1); + return Result.success().put("data", data); + } + + BaseResp baseResp = wuyouPay.payOrder(payDetails.getTradeNo(), order.getPayMoney().toString(), + request.getHeader("User-Agent"), String.format("%d-%d", order.getCourseId(), order.getCourseDetailsId()), + payType); + if (baseResp.getCode() == null) { + return Result.error(baseResp.getErrorMsg()); + } + if (baseResp.getCode() != 200) { + return Result.error(baseResp.getMsg()); + } + + return Result.success().put("data", baseResp.getData()); } @ApiOperation("查询订单支付结果") @@ -161,7 +163,7 @@ public class WuyouController { return Result.success().put("data", 1); } - BaseResp baseResp = WuyouPay.queryOrder(payDetails.getTradeNo(), order.getPayMoney().toString(), request.getHeader("User-Agent")); + BaseResp baseResp = wuyouPay.queryOrder(payDetails.getTradeNo(), order.getPayMoney().toString(), request.getHeader("User-Agent")); if (baseResp.getCode() == null || baseResp.getCode() != 200) { return Result.success().put("data", 0); } @@ -245,54 +247,65 @@ public class WuyouController { if (sourceUser == null || sourceUser.getUserId() == 1) { return; } - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("classify", 6); - queryWrapper.eq("user_id", sourceUser.getUserId()); - queryWrapper.eq("by_user_id", user.getUserId()); - int count = userMoneyDetailsService.count(queryWrapper); - if (count == 0) { +// QueryWrapper queryWrapper = new QueryWrapper<>(); +// queryWrapper.eq("classify", 6); +// queryWrapper.eq("user_id", sourceUser.getUserId()); +// queryWrapper.eq("by_user_id", user.getUserId()); +// int count = userMoneyDetailsService.count(queryWrapper); + InviteAchievement inviteAchievement = inviteAchievementService.getByUserId(user.getUserId()); + // 首次达标 + int signCount = Integer.parseInt(commonRepository.findOne(913).getValue()); + if (inviteAchievement.getState() == 0 && inviteAchievement.getCount() >= signCount) { //满3笔 - Integer sumOrderNum = ordersService.countOrderNum(user.getUserId(), null); - if (sumOrderNum >= Integer.parseInt(commonRepository.findOne(913).getValue())) { - String amount = commonRepository.findOne(912).getValue(); - UserMoneyDetails userMoneyDetails = new UserMoneyDetails(); - userMoneyDetails.setClassify(6); - userMoneyDetails.setMoney(new BigDecimal(amount)); - userMoneyDetails.setUserId(sourceUser.getUserId()); - userMoneyDetails.setByUserId(user.getUserId()); - userMoneyDetails.setCreateTime(DateUtil.now()); - userMoneyDetails.setContent("分享达标奖励" + amount + "元"); - userMoneyDetails.setTitle("分享达标奖励"); - userMoneyDetails.setState(2); - userMoneyDetails.setType(1); - userMoneyDetails.setMoneyType(1); - userMoneyDetailsService.save(userMoneyDetails); - //存入余额 钱 - userMoneyService.updateAmount(1, sourceUser.getUserId(), Double.parseDouble(amount)); +// Integer sumOrderNum = ordersService.countOrderNum(user.getUserId(), null); +// if (sumOrderNum >= Integer.parseInt(commonRepository.findOne(913).getValue())) { + String amount = commonRepository.findOne(912).getValue(); + UserMoneyDetails userMoneyDetails = new UserMoneyDetails(); + userMoneyDetails.setClassify(6); + userMoneyDetails.setMoney(new BigDecimal(amount)); + userMoneyDetails.setUserId(sourceUser.getUserId()); + userMoneyDetails.setByUserId(user.getUserId()); + userMoneyDetails.setCreateTime(DateUtil.now()); + userMoneyDetails.setContent("分享达标奖励" + amount + "元"); + userMoneyDetails.setTitle("分享达标奖励"); + userMoneyDetails.setState(2); + userMoneyDetails.setType(1); + userMoneyDetails.setMoneyType(1); + userMoneyDetailsService.save(userMoneyDetails); + //存入余额 钱 + userMoneyService.updateAmount(1, sourceUser.getUserId(), Double.parseDouble(amount)); + + inviteAchievement.setState(1); + inviteAchievementService.updateById(inviteAchievement); + + int count = inviteAchievementService.countBySourceUserId(sourceUser.getUserId()); + // 首次达标奖励 + if (count == 1) { SysUserEntity sysUser = sysUserService.selectSysUserByQdCode(user.getQdCode()); String qdAward = commonRepository.findOne(915).getValue(); - UserMoneyDetails userMoneyDetails4 = new UserMoneyDetails( null, sysUser == null ? null : sysUser.getUserId(), null, "[分享达标额外奖励]", 6, 1, 2, new BigDecimal(qdAward), "推广人员首次达标,额外奖励现金红包" + qdAward, 2); userMoneyService.updateSysAmount(1, sysUser == null ? null : sysUser.getUserId(), Double.parseDouble(qdAward)); userMoneyDetailsService.save(userMoneyDetails4); - - Invite invite = inviteService.selectInviteByUser(sourceUser.getUserId(), user.getUserId(), 1); - if (invite != null) { - invite.setMoney(Double.valueOf(amount)); - invite.setState(1); - inviteDao.updateById(invite); - } } + + Invite invite = inviteService.selectInviteByUser(sourceUser.getUserId(), user.getUserId(), 1); + if (invite != null) { + invite.setMoney(Double.valueOf(amount)); + invite.setState(1); + inviteDao.updateById(invite); + } +// } } QueryWrapper moneyDetailsQuery = new QueryWrapper<>(); moneyDetailsQuery.eq("classify", 6); moneyDetailsQuery.eq("user_id", sourceUser.getUserId()); //达标人数 - int completeCount = userMoneyDetailsService.count(moneyDetailsQuery); +// int completeCount = userMoneyDetailsService.count(moneyDetailsQuery); + int completeCount = inviteAchievementService.countNum(sourceUser.getUserId(), signCount); completAwardService.list(new QueryWrapper().eq("invite_count", completeCount)).forEach(completAward -> { switch (completAward.getType()) { case 1: @@ -322,7 +335,7 @@ public class WuyouController { } String format = sdf.format(new Date()); - payDetailsDao.updateState(payDetails.getId(), 1, format, payDetails.getTradeNo()); + payDetailsDao.updateState(payDetails.getId(), 1, format, payDetails.getTradeNo(),payDetails.getThirdOrderNo()); order.setPayWay(9); order.setStatus(1); @@ -348,6 +361,22 @@ public class WuyouController { } ordersService.updateById(order); ordersService.insertOrders(order); + + if (byUser != null) { + InviteAchievement inviteAchievement = inviteAchievementService.getByUserId(user.getUserId()); + if (inviteAchievement == null) { + inviteAchievement = new InviteAchievement(); + inviteAchievement.setState(0); + inviteAchievement.setCount(1); + inviteAchievement.setCreateTime(DateUtil.date()); + inviteAchievement.setUserId(user.getUserId()); + inviteAchievement.setSourceUserId(byUser.getUserId()); + inviteAchievementService.save(inviteAchievement); + } else { + inviteAchievementService.incrCount(inviteAchievement.getId(), 1); + } + } + ThreadUtil.execAsync(() -> { activities(user, byUser); }); diff --git a/src/main/java/com/sqx/modules/pay/dao/CashOutDao.java b/src/main/java/com/sqx/modules/pay/dao/CashOutDao.java index d06d8a83..655a3000 100644 --- a/src/main/java/com/sqx/modules/pay/dao/CashOutDao.java +++ b/src/main/java/com/sqx/modules/pay/dao/CashOutDao.java @@ -32,11 +32,11 @@ public interface CashOutDao extends BaseMapper { Double selectSysUserCashOutSum(@Param("sysUserId") Long sysUserId, @Param("time") String time); - Double sumMoney(@Param("time") String time, @Param("flag") Integer flag); + Double sumMoney(@Param("start") String start, @Param("end") String end, @Param("flag") Integer flag); - Integer countMoney(@Param("time") String time, @Param("flag") Integer flag); + Integer countMoney(@Param("start") String start, @Param("end") String end, @Param("flag") Integer flag); - Integer stayMoney(@Param("time") String time, @Param("flag") Integer flag); + Integer stayMoney(@Param("start") String start, @Param("end") String end, @Param("flag") Integer flag); void updateMayMoney(@Param("type") Integer type, @Param("userId") Long userId, @Param("money") Double money); diff --git a/src/main/java/com/sqx/modules/pay/dao/PayDetailsDao.java b/src/main/java/com/sqx/modules/pay/dao/PayDetailsDao.java index ae517188..7cdd1e9e 100644 --- a/src/main/java/com/sqx/modules/pay/dao/PayDetailsDao.java +++ b/src/main/java/com/sqx/modules/pay/dao/PayDetailsDao.java @@ -24,7 +24,7 @@ public interface PayDetailsDao extends BaseMapper { PayDetails selectByTradeNo(@Param("tradeNo") String tradeNo); - int updateState(@Param("id") Long id, @Param("state") Integer state, @Param("time") String time, @Param("tradeNo") String tradeNo); + int updateState(@Param("id") Long id, @Param("state") Integer state, @Param("time") String time, @Param("tradeNo") String tradeNo,@Param("thirdOrderNo") String thirdOrderNo); IPage> selectPayDetails(@Param("page") Page> page, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("userId") Long userId, @Param("state") Integer state, @Param("userName") String userName, String orderId); diff --git a/src/main/java/com/sqx/modules/pay/service/CashOutService.java b/src/main/java/com/sqx/modules/pay/service/CashOutService.java index 5e733f61..56736921 100644 --- a/src/main/java/com/sqx/modules/pay/service/CashOutService.java +++ b/src/main/java/com/sqx/modules/pay/service/CashOutService.java @@ -31,11 +31,11 @@ public interface CashOutService { Double selectCashOutSum(Long userId, Date startTime, Date endTime); - Double sumMoney(String time, Integer flag); + Double sumMoney(String time, String end, Integer flag); - Integer countMoney(String time, Integer flag); + Integer countMoney(String time, String end, Integer flag); - Integer stayMoney(String time, Integer flag); + Integer stayMoney(String time, String end, Integer flag); void updateMayMoney(int i, Long userId, Double money); diff --git a/src/main/java/com/sqx/modules/pay/service/impl/CashOutServiceImpl.java b/src/main/java/com/sqx/modules/pay/service/impl/CashOutServiceImpl.java index c88d4419..06a23e7a 100644 --- a/src/main/java/com/sqx/modules/pay/service/impl/CashOutServiceImpl.java +++ b/src/main/java/com/sqx/modules/pay/service/impl/CashOutServiceImpl.java @@ -100,6 +100,9 @@ public class CashOutServiceImpl extends ServiceImpl impleme @Autowired private UserDao userDao; + @Autowired + private WuyouPay wuyouPay; + @Override public PageUtils selectCashOutList(Integer page, Integer limit, CashOut cashOut) { return new PageUtils(baseMapper.selectCashOutPage(new Page<>(page, limit), cashOut)); @@ -247,18 +250,18 @@ public class CashOutServiceImpl extends ServiceImpl impleme } @Override - public Double sumMoney(String time, Integer flag) { - return cashOutDao.sumMoney(time, flag); + public Double sumMoney(String start, String end, Integer flag) { + return cashOutDao.sumMoney(start, end, flag); } @Override - public Integer countMoney(String time, Integer flag) { - return cashOutDao.countMoney(time, flag); + public Integer countMoney(String start, String end, Integer flag) { + return cashOutDao.countMoney(start, end, flag); } @Override - public Integer stayMoney(String time, Integer flag) { - return cashOutDao.stayMoney(time, flag); + public Integer stayMoney(String start, String end, Integer flag) { + return cashOutDao.stayMoney(start, end, flag); } @Override @@ -503,9 +506,9 @@ public class CashOutServiceImpl extends ServiceImpl impleme return Result.success("可提现余额不足!"); } - if (WuyouPay.checkCanCash(userId, WithdrawTypeEnum.MANUAL, new BigDecimal(money.toString()))) { + if (wuyouPay.checkCanCash(userId, WithdrawTypeEnum.MANUAL, new BigDecimal(money.toString()))) { cashOut.setStatus(4); - BaseResp baseResp = WuyouPay.extractOrder(outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName()); + BaseResp baseResp = wuyouPay.extractOrder(outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName()); if (baseResp.getStatus() != null && (baseResp.getStatus().equals(2) || baseResp.getStatus().equals(10000))) { userMoneyDetails.setContent("成功提现:" + money); cashOut.setState(1); @@ -590,7 +593,7 @@ public class CashOutServiceImpl extends ServiceImpl impleme entity.setOrderNumber(outOrderNo); } // 执行提现操作 - BaseResp baseResp = WuyouPay.extractOrder(entity.getOrderNumber(), entity.getMoney(), entity.getZhifubao(), entity.getZhifubaoName()); + BaseResp baseResp = wuyouPay.extractOrder(entity.getOrderNumber(), entity.getMoney(), entity.getZhifubao(), entity.getZhifubaoName()); if (baseResp.getStatus() != null && (baseResp.getStatus().equals(2) || baseResp.getStatus().equals(10000))) { entity.setState(1); } else if (StringUtils.isNotBlank(baseResp.getErrorMsg())) { diff --git a/src/main/java/com/sqx/modules/pay/service/impl/DyServiceImpl.java b/src/main/java/com/sqx/modules/pay/service/impl/DyServiceImpl.java index ad2576af..c7f28aca 100644 --- a/src/main/java/com/sqx/modules/pay/service/impl/DyServiceImpl.java +++ b/src/main/java/com/sqx/modules/pay/service/impl/DyServiceImpl.java @@ -406,7 +406,7 @@ public class DyServiceImpl implements DyService { PayDetails payDetails = payDetailsDao.selectByOrderId(orderNo); if(payDetails.getState()==0){ String format = sdf.format(new Date()); - payDetailsDao.updateState(payDetails.getId(),1,format,""); + payDetailsDao.updateState(payDetails.getId(),1,format,"",""); if(payDetails.getType()==1){ Orders orders = ordersService.selectOrderByOrdersNo(payDetails.getOrderId()); orders.setPayWay(7); @@ -493,7 +493,7 @@ public class DyServiceImpl implements DyService { PayDetails payDetails = payDetailsDao.selectByOrderId(orderNo); if(payDetails.getState()==0){ String format = sdf.format(new Date()); - payDetailsDao.updateState(payDetails.getId(),1,format,""); + payDetailsDao.updateState(payDetails.getId(),1,format,"",""); if(payDetails.getType()==1){ Orders orders = ordersService.selectOrderByOrdersNo(payDetails.getOrderId()); orders.setPayWay(7); diff --git a/src/main/java/com/sqx/modules/pay/service/impl/KsServiceImpl.java b/src/main/java/com/sqx/modules/pay/service/impl/KsServiceImpl.java index 6e7437e2..2853e907 100644 --- a/src/main/java/com/sqx/modules/pay/service/impl/KsServiceImpl.java +++ b/src/main/java/com/sqx/modules/pay/service/impl/KsServiceImpl.java @@ -182,7 +182,7 @@ public class KsServiceImpl implements KsService { PayDetails payDetails = payDetailsDao.selectByOrderId(orderNo); if(payDetails.getState()==0){ String format = sdf.format(new Date()); - payDetailsDao.updateState(payDetails.getId(),1,format,""); + payDetailsDao.updateState(payDetails.getId(),1,format,"",""); if(payDetails.getType()==1){ Orders orders = ordersService.selectOrderByOrdersNo(payDetails.getOrderId()); orders.setPayWay(8); diff --git a/src/main/java/com/sqx/modules/pay/service/impl/PayDetailsServiceImpl.java b/src/main/java/com/sqx/modules/pay/service/impl/PayDetailsServiceImpl.java index bd760e7c..47d120f9 100644 --- a/src/main/java/com/sqx/modules/pay/service/impl/PayDetailsServiceImpl.java +++ b/src/main/java/com/sqx/modules/pay/service/impl/PayDetailsServiceImpl.java @@ -6,6 +6,7 @@ import com.sqx.common.utils.PageUtils; 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.utils.TimeCompleteUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -30,15 +31,15 @@ public class PayDetailsServiceImpl extends ServiceImpl params = getBaseParams(); params.put("type", "6001"); params.put("is_code", "1"); params.put("out_trade_no", orderNo); params.put("total", amount); - params.put("notify_url", NOTIFY_URL); + params.put("notify_url", notifyUrl); String sign = Encrypt.getParamsSign(params); params.put("sign", sign); if ("h5".equals(payType)) { - params.put("return_url", H5_BASE_URL + allId); + params.put("return_url", h5BaseUrl + allId); } // https://dj-h5.hnsiyao.cn/me/detail/detail?allId=1230-98688 @@ -70,7 +62,7 @@ public class WuyouPay { return JSONObject.parseObject(body, BaseResp.class); } - public static BaseResp queryOrder(String orderNo, String amount, String userAgent) { + public BaseResp queryOrder(String orderNo, String amount, String userAgent) { Map params = getBaseParams(); params.put("out_trade_no", orderNo); params.put("total", amount); @@ -82,10 +74,10 @@ public class WuyouPay { return JSONObject.parseObject(body, BaseResp.class); } - public static boolean checkCanCash(long userId, WithdrawTypeEnum type, BigDecimal money) { + public boolean checkCanCash(long userId, WithdrawTypeEnum type, BigDecimal money) { if (WithdrawTypeEnum.MANUAL.equals(type)) { // 查询当日体现次数 - Integer successCashCount = cashOutDao.selectTodayCashCount(userId, 1, DateUtil.today()+ " 00:00:00"); + Integer successCashCount = cashOutDao.selectTodayCashCount(userId, 1, DateUtil.today() + " 00:00:00"); CommonInfo cashLimit = commonInfoService.findOne(922); if (cashLimit == null || StrUtil.isBlank(cashLimit.getValue())) { logger.warn("提现必要参数未配置,请联系管理员"); @@ -102,7 +94,7 @@ public class WuyouPay { return true; } - public static boolean checkCanCashByLimit(BigDecimal money) { + public boolean checkCanCashByLimit(BigDecimal money) { CommonInfo info = commonInfoService.findOne(923); if (info == null || StrUtil.isBlank(info.getValue())) { logger.warn("未配置提现限制,请联系管理员配置"); @@ -114,11 +106,11 @@ public class WuyouPay { /** * 提现 - * @param account 支付宝账号 - * @param userName 支付宝名称 - * @return + * + * @param account 支付宝账号 + * @param userName 支付宝名称 */ - public static BaseResp extractOrder(String outOrderNo, String amount, String account, String userName) { + public BaseResp extractOrder(String outOrderNo, String amount, String account, String userName) { Map params = getBaseParams(); params.put("out_trade_no", outOrderNo); @@ -129,7 +121,7 @@ public class WuyouPay { params.put("bank_branch", "1"); params.put("province", "1"); params.put("city", "1"); - params.put("notify_url", EXTRACT_NOTIFY_URL); + params.put("notify_url", extractNotifyUrl); String sign = Encrypt.getParamsSign(params); params.put("sign", sign); @@ -141,7 +133,7 @@ public class WuyouPay { return JSONObject.parseObject(body, BaseResp.class); } - public static BaseResp queryExtractOrder(String outOrderNo, String amount) { + public BaseResp queryExtractOrder(String outOrderNo, String amount) { Map params = getBaseParams(); params.put("out_trade_no", outOrderNo); params.put("total", amount); @@ -153,7 +145,7 @@ public class WuyouPay { return JSONObject.parseObject(body, BaseResp.class); } - private static Map getBaseParams() { + private Map getBaseParams() { Map params = new HashMap<>(); params.put("mch_id", Constants.MERCHANT_ID); params.put("timestamp", System.currentTimeMillis() / 1000); @@ -161,7 +153,7 @@ public class WuyouPay { return params; } - private static String request(String url, Map params, String userAgent) { + private String request(String url, Map params, String userAgent) { String body = HttpRequest.post(url) .header("Content-Type", "application/x-www-form-urlencoded") .header("User-Agent", userAgent) @@ -181,6 +173,6 @@ public class WuyouPay { // extractOrder("20221118123456793", "1", "1157756119@qq.com", "巩奕杰"); // queryExtractOrder("20221118123456793", "1"); - System.out.println(DateUtil.today()+ " 00:00:00"); + System.out.println(DateUtil.today() + " 00:00:00"); } } diff --git a/src/main/java/com/sqx/modules/redisService/RedisService.java b/src/main/java/com/sqx/modules/redisService/RedisService.java index 09eff649..c20bda12 100644 --- a/src/main/java/com/sqx/modules/redisService/RedisService.java +++ b/src/main/java/com/sqx/modules/redisService/RedisService.java @@ -14,4 +14,11 @@ public interface RedisService { Boolean getFreeWatchTimeIsExpire(Long userId); Long getFreeWatchRemainTime(Long userId, boolean isPermanently); + + boolean checkIpJumpLimit(long userId, String ip); + void recordUrlVisitCountWithIp(long userId, String url, String ip); + + boolean isRecordUserOnLineTime(long userId); + + boolean isSetUserState(long userId); } diff --git a/src/main/java/com/sqx/modules/redisService/impl/RedisServiceImpl.java b/src/main/java/com/sqx/modules/redisService/impl/RedisServiceImpl.java index 7c45e604..596982c8 100644 --- a/src/main/java/com/sqx/modules/redisService/impl/RedisServiceImpl.java +++ b/src/main/java/com/sqx/modules/redisService/impl/RedisServiceImpl.java @@ -12,23 +12,36 @@ import com.sqx.modules.discSpinning.entity.DiscSpinningAmount; import com.sqx.modules.discSpinning.service.DiscSpinningAmountService; import com.sqx.modules.redisService.RedisService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.Map; @Service public class RedisServiceImpl implements RedisService { + @Value("${limit.urlRate}") + private Integer urlLimitRate; + @Value("${limit.ipJumpLimit}") + private Integer ipJumpLimit; + @Lazy @Autowired private RedisUtils redisUtils; @Autowired private DiscSpinningAmountService amountService; + private final StringRedisTemplate redisTemplate; + + public RedisServiceImpl(StringRedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } @Override public void setDiscSpinningAmounts(String key) { @@ -84,7 +97,7 @@ public class RedisServiceImpl implements RedisService { expireTime = jsonObject.getLong("expireTime"); } - if ((StrUtil.isNotBlank(permanentlyFreeWatch) && redisUtils.isExpiredSet(freeWatchKey)) || (StrUtil.isNotBlank(permanentlyFreeWatch) && DateUtil.current() >= expireTime)) { + if ((StrUtil.isNotBlank(permanentlyFreeWatch) && redisUtils.isExpiredSet(freeWatchKey)) || (StrUtil.isNotBlank(permanentlyFreeWatch) && DateUtil.current(false) >= expireTime)) { if (StrUtil.isBlank(permanentlyFreeWatch)) { return null; } @@ -108,7 +121,7 @@ public class RedisServiceImpl implements RedisService { redisUtils.set(watchKey, jsonObject.toJSONString(), expire); return false; }else { - return DateUtil.current() > expireTime; + return DateUtil.current(false) > expireTime; } } } @@ -136,6 +149,146 @@ public class RedisServiceImpl implements RedisService { Integer expireTime = jsonObject.getInteger("expireTime"); Long second = jsonObject.getLong("second"); - return expireTime == -1 ? second : expireTime > DateUtil.current() ? expireTime - DateUtil.current() : 0L; + return expireTime == -1 ? second : expireTime > DateUtil.current(false) ? expireTime - DateUtil.current(false) : 0L; + } + + + public boolean checkIpJumpLimit(long userId, String ip) { + String userKey = "user:" + userId + ":last_ip"; // 存储用户上次的 IP 地址 + String lastIp = redisTemplate.opsForValue().get(userKey); + + // 获取用户跳动的历史 IP 地址集合 + String jumpHistoryKey = "user:" + userId + ":ip_history"; // 记录用户跳动过的 IP 地址 + Set jumpHistory = redisTemplate.opsForSet().members(jumpHistoryKey); + + // 记录 IP 跳动次数 + String ipTimestampKey = "user:" + userId + ":ip_timestamp"; // 记录每个 IP 跳动的过期时间 + String userJumpCountKey = "user:" + userId + ":jump_count"; // 用户跳动的总次数 + + // 新增用于记录所有 IP 请求时间和次数的 Hash + String ipRequestsKey = "user:" + userId + ":ip_requests"; // 用来记录 IP 的请求次数和时间 + + + // 如果用户之前没有记录过 IP,说明是第一次请求,直接保存 + if (lastIp == null) { + redisTemplate.opsForValue().set(userKey, ip); + + // 将当前 IP 添加到跳动历史中,设置 60 秒过期时间 + redisTemplate.opsForSet().add(jumpHistoryKey, ip); + redisTemplate.expire(jumpHistoryKey, 1, TimeUnit.MINUTES); + + // 设置该 IP 的过期时间为 60 秒,表示跳动记录会在 60 秒后过期 + redisTemplate.opsForValue().set(ipTimestampKey + ":" + ip, "1", 1, TimeUnit.MINUTES); + + // 记录用户 IP 请求的次数和时间 + String ipData = DateUtil.date() + "|1"; // 时间和请求次数 + redisTemplate.opsForHash().put(ipRequestsKey, ip, ipData); + + return false; + } + + // 如果当前 IP 和上次 IP 不一致,说明发生了 IP 跳动 + if (!lastIp.equals(ip)) { + // 判断当前 IP 是否在历史跳动的 IP 中 + if (jumpHistory != null && jumpHistory.contains(ip)) { + // 如果当前 IP 存在于历史跳动记录中,认为是多节点登录,增加跳动次数 + String s = redisTemplate.opsForValue().get(userJumpCountKey); + Integer currentJumpCount = s == null ? null : Integer.parseInt(s); + if (currentJumpCount == null) { + currentJumpCount = 0; + } + currentJumpCount++; + + // 更新跳动次数 + redisTemplate.opsForValue().set(userJumpCountKey, String.valueOf(currentJumpCount)); + + // 如果跳动次数超过限制,触发封禁 + if (currentJumpCount >= ipJumpLimit) { + return true; + } + } + + // 检查用户是否跳动过多次 + if (jumpHistory != null && jumpHistory.size() >= ipJumpLimit) { + // 如果历史 IP 地址数超过最大跳动次数,触发封禁 + return true; + } + + // 将当前 IP 添加到跳动历史中,设置 60 秒过期时间 + redisTemplate.opsForSet().add(jumpHistoryKey, ip); + redisTemplate.expire(jumpHistoryKey, 1, TimeUnit.MINUTES); + + // 更新用户的上次 IP 地址 + redisTemplate.opsForValue().set(userKey, ip); + + // 增加该 IP 的跳动计数,并设置过期时间为 60 秒 + redisTemplate.opsForValue().increment(ipTimestampKey + ":" + ip, 1); + redisTemplate.expire(ipTimestampKey + ":" + ip, 1, TimeUnit.MINUTES); + + // 记录该 IP 请求的次数和时间 + String ipData = DateUtil.date() + "|1"; // 时间和请求次数 + redisTemplate.opsForHash().put(ipRequestsKey, ip, ipData); + } else { + // 如果 IP 没有变化,更新该 IP 的请求次数和时间 + String currentCount = (String) redisTemplate.opsForHash().get(ipRequestsKey, ip); + String[] ipData = currentCount != null ? currentCount.split("\\|") : new String[]{"", "0"}; + int newCount = Integer.parseInt(ipData[1]) + 1; // 增加请求次数 + + // 更新新的时间和请求次数 + String updatedIpData = DateUtil.date() + "|" + newCount; + redisTemplate.opsForHash().put(ipRequestsKey, ip, updatedIpData); + } + + return false; + } + + @Override + public boolean isSetUserState(long userId) { + String userKey = "user:" + userId + ":state"; // 存储用户上次的 IP 地址 + String key = redisUtils.get(userKey); + if (StrUtil.isBlank(key)) { + DateTime date = DateUtil.date(); + Date tomorrow = DateUtil.beginOfDay(DateUtil.offsetDay(date, 1)); + long expire = DateUtil.between(date, tomorrow, DateUnit.SECOND); + redisUtils.set(key, userId, expire); + return false; + } + return true; + } + + // 记录用户访问 URL 的次数和 IP 地址 + public void recordUrlVisitCountWithIp(long userId, String url, String ip) { + String userUrlKey = "user:" + userId + ":url:" + url; // 存储用户访问特定 URL 的数据 + + // 获取用户访问该 URL 的访问记录 + Map urlAccessInfo = redisTemplate.opsForHash().entries(userUrlKey); + + // 记录访问次数的键名和每个 IP 地址的计数 + String ipKey = "ip:" + ip; + int currentIpVisitCount = urlAccessInfo.containsKey(ipKey) ? Integer.parseInt(urlAccessInfo.get(ipKey).toString()) : 0; + + // 更新该 IP 的访问计数 + redisTemplate.opsForHash().put(userUrlKey, ipKey, String.valueOf(currentIpVisitCount + 1)); + + // 更新总的访问次数(不区分 IP) + int totalVisitCount = urlAccessInfo.containsKey("total") ? Integer.parseInt(urlAccessInfo.get("total").toString()) : 0; + redisTemplate.opsForHash().put(userUrlKey, "total", String.valueOf(totalVisitCount + 1)); + } + + @Override + public boolean isRecordUserOnLineTime(long userId) { + // Redis 键值为 "user:{userId}:last_call_time",存储的是用户最后一次调用接口的时间戳 + String lastCallTimeKey = "user:" + userId + ":last_call_time"; + + // 获取 Redis 中存储的上次更新时间 + String lastCallTimeStr = redisTemplate.opsForValue().get(lastCallTimeKey); + // 如果 Redis 中没有记录过,表示这是用户第一次调用接口 + if (lastCallTimeStr == null) { + // 更新 Redis 中记录的最后调用时间 + redisTemplate.opsForValue().set(lastCallTimeKey, String.valueOf(DateUtil.date().getTime()), 10, TimeUnit.MINUTES); + return true; + } else { + return false; + } } } diff --git a/src/main/java/com/sqx/modules/sys/oauth2/OAuth2Filter.java b/src/main/java/com/sqx/modules/sys/oauth2/OAuth2Filter.java index c13b6713..1a546607 100644 --- a/src/main/java/com/sqx/modules/sys/oauth2/OAuth2Filter.java +++ b/src/main/java/com/sqx/modules/sys/oauth2/OAuth2Filter.java @@ -21,7 +21,6 @@ import java.io.IOException; /** * oauth2过滤器 - * */ public class OAuth2Filter extends AuthenticatingFilter { @@ -32,7 +31,7 @@ public class OAuth2Filter extends AuthenticatingFilter { //获取请求token String token = getRequestToken((HttpServletRequest) request); - if(StringUtils.isBlank(token)){ + if (StringUtils.isBlank(token)) { return null; } @@ -41,7 +40,7 @@ public class OAuth2Filter extends AuthenticatingFilter { @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { - if(((HttpServletRequest) request).getMethod().equals(RequestMethod.OPTIONS.name())){ + if (((HttpServletRequest) request).getMethod().equals(RequestMethod.OPTIONS.name())) { return true; } @@ -52,7 +51,7 @@ public class OAuth2Filter extends AuthenticatingFilter { protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { //获取请求token,如果token不存在,直接返回401 String token = getRequestToken((HttpServletRequest) request); - if(StringUtils.isBlank(token)){ + if (StringUtils.isBlank(token)) { HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setHeader("Access-Control-Allow-Credentials", "true"); httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin()); @@ -63,17 +62,8 @@ public class OAuth2Filter extends AuthenticatingFilter { return false; } - try{ - return executeLogin(request, response); - }catch (AbstractMethodError e){ - if (e.getMessage().contains("sessionCreated")) { - logger.error(e.getMessage()); - return false; - }else { - logger.error(e.getMessage()); - return false; - } - } + return executeLogin(request, response); + } @Override @@ -99,12 +89,12 @@ public class OAuth2Filter extends AuthenticatingFilter { /** * 获取请求的token */ - private String getRequestToken(HttpServletRequest httpRequest){ + private String getRequestToken(HttpServletRequest httpRequest) { //从header中获取token String token = httpRequest.getHeader("token"); //如果header中不存在token,则从参数中获取token - if(StringUtils.isBlank(token)){ + if (StringUtils.isBlank(token)) { token = httpRequest.getParameter("token"); } diff --git a/src/main/java/com/sqx/modules/utils/TimeCompleteUtils.java b/src/main/java/com/sqx/modules/utils/TimeCompleteUtils.java new file mode 100644 index 00000000..7cdaa069 --- /dev/null +++ b/src/main/java/com/sqx/modules/utils/TimeCompleteUtils.java @@ -0,0 +1,27 @@ +package com.sqx.modules.utils; + +/** + * @author GYJoker + */ +public class TimeCompleteUtils { + + public static String completeStartTime(String startTime) { + if (startTime == null || startTime.isEmpty()) { + return null; + } + if (startTime.contains(" ")) { + return startTime; + } + return startTime + " 00:00:00"; + } + + public static String completeEndTime(String endTime) { + if (endTime == null || endTime.isEmpty()) { + return null; + } + if (endTime.contains(" ")) { + return endTime; + } + return endTime + " 23:59:59"; + } +} diff --git a/src/main/java/com/sqx/sharding/MasterSlaveRules.java b/src/main/java/com/sqx/sharding/MasterSlaveRules.java new file mode 100644 index 00000000..064773e0 --- /dev/null +++ b/src/main/java/com/sqx/sharding/MasterSlaveRules.java @@ -0,0 +1,22 @@ +package com.sqx.sharding; + +import lombok.Data; + +import java.util.List; + +/** + * 读写分离配置 + */ +@Data +public class MasterSlaveRules { + + /** + * 写库 + */ + private String masterDataSourceName; + + /** + * 读库 + */ + private List slaveDataSourceNames; +} \ No newline at end of file diff --git a/src/main/java/com/sqx/sharding/ShardingDataBase.java b/src/main/java/com/sqx/sharding/ShardingDataBase.java new file mode 100644 index 00000000..ccf6f58c --- /dev/null +++ b/src/main/java/com/sqx/sharding/ShardingDataBase.java @@ -0,0 +1,61 @@ +package com.sqx.sharding; + +import lombok.Data; + +/** + * 用于注入sharding-jdbc的值 + */ +@Data +public class ShardingDataBase { + + /** + * 连接池 + */ + private String type; + + /** + * 驱动名称 + */ + private String driverClassName; + + /** + * 数据库地址 + */ + private String jdbcUrl; + + /** + * 数据库用户名 + */ + private String username; + + /** + * 数据库密码 + */ + private String password; + + /** + * 最小空闲连接,默认值10,小于0或大于maximum-pool-size,都会重置为maximum-pool-size + */ + private int minimumIdle; + + /** + * 最大连接数,小于等于0会被重置为默认值10;大于零小于1会被重置为minimum-idle的值 + */ + private int maximumPoolSize; + + /** + * 空闲连接超时时间,默认值600000(10分钟),大于等于max-lifetime且max-lifetime>0,会被重置为0;不等于0且小于10秒,会被重置为10秒。 + */ + private int idleTimeout; + + /** + * 连接最大存活时间.不等于0且小于30秒,会被重置为默认值30分钟.设置应该比mysql设置的超时时间短 + */ + private int maxLifetime; + + /** + * 连接超时时间:毫秒,小于250毫秒,否则被重置为默认值30秒 + */ + private int connectionTimeout; + +} \ No newline at end of file diff --git a/src/main/java/com/sqx/sharding/ShardingDataSourcePoolMetricsAutoConfiguration.java b/src/main/java/com/sqx/sharding/ShardingDataSourcePoolMetricsAutoConfiguration.java new file mode 100644 index 00000000..3c7252ac --- /dev/null +++ b/src/main/java/com/sqx/sharding/ShardingDataSourcePoolMetricsAutoConfiguration.java @@ -0,0 +1,67 @@ +package com.sqx.sharding; + +import com.zaxxer.hikari.HikariDataSource; +import com.zaxxer.hikari.metrics.micrometer.MicrometerMetricsTrackerFactory; +import io.micrometer.core.instrument.MeterRegistry; +import lombok.extern.slf4j.Slf4j; +import org.apache.shardingsphere.shardingjdbc.jdbc.core.datasource.ShardingDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.DataSourceUnwrapper; +import org.springframework.context.annotation.Configuration; + +import javax.sql.DataSource; +import java.util.Collection; + +/** + * @author wxkj0012 + */ +@Configuration(proxyBeanMethods = false) +@AutoConfigureAfter({MetricsAutoConfiguration.class, DataSourceAutoConfiguration.class, + SimpleMetricsExportAutoConfiguration.class}) +@ConditionalOnClass({DataSource.class, MeterRegistry.class}) +@ConditionalOnBean({DataSource.class, MeterRegistry.class}) +@Slf4j +public class ShardingDataSourcePoolMetricsAutoConfiguration { + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass({ShardingDataSource.class, HikariDataSource.class}) + static class ShardingDataSourceMetricsConfiguration { + + private final MeterRegistry registry; + + ShardingDataSourceMetricsConfiguration(MeterRegistry registry) { + this.registry = registry; + } + + @Autowired + void bindMetricsRegistryToHikariDataSources(Collection dataSources) { + for (DataSource dataSource : dataSources) { + ShardingDataSource shardingDataSource = DataSourceUnwrapper.unwrap(dataSource, ShardingDataSource.class); + Collection shardDataSources = shardingDataSource.getDataSourceMap().values(); + for (DataSource ds : shardDataSources) { + HikariDataSource hikariDataSource = DataSourceUnwrapper.unwrap(ds, HikariDataSource.class); + if (hikariDataSource != null) { + bindMetricsRegistryToHikariDataSource(hikariDataSource); + } + } + } + } + + private void bindMetricsRegistryToHikariDataSource(HikariDataSource hikari) { + if (hikari.getMetricRegistry() == null && hikari.getMetricsTrackerFactory() == null) { + try { + hikari.setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory(this.registry)); + } catch (Exception ex) { + log.warn("Failed to bind Hikari metrics: {}}", ex.getMessage()); + } + } + } + + } +} \ No newline at end of file diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 870d10a3..54eea696 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -1,37 +1,55 @@ +# 数据源的一些配置 +driver-class-name: com.mysql.cj.jdbc.Driver +# 最小空闲连接,默认值10,小于0或大于maximum-pool-size,都会重置为maximum-pool-size +minimum-idle: 5 +# 最大连接数,小于等于0会被重置为默认值10;大于零小于1会被重置为minimum-idle的值 +maximum-pool-size: 15 +# 空闲连接超时时间,默认值600000(10分钟),大于等于max-lifetime且max-lifetime>0,会被重置为0;不等于0且小于10秒,会被重置为10秒。 +idle-timeout: 30000 +# 连接最大存活时间.不等于0且小于30秒,会被重置为默认值30分钟.设置应该比mysql设置的超时时间短 +max-lifetime: 30000 +# 连接超时时间:毫秒,小于250毫秒,否则被重置为默认值30秒 +connection-timeout: 30000 + spring: - datasource: - type: com.alibaba.druid.pool.DruidDataSource - druid: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://rm-gc712o11yndj78x6a6o.mysql.cn-chengdu.rds.aliyuncs.com/duanju?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT - username: video_user - password: VideoUser@1 - initial-size: 10 - max-active: 50 - min-idle: 10 - max-wait: 60000 - pool-prepared-statements: true - max-pool-prepared-statement-per-connection-size: 20 - time-between-eviction-runs-millis: 60000 - min-evictable-idle-time-millis: 300000 - #Oracle需要打开注释 - #validation-query: SELECT 1 FROM DUAL - test-while-idle: true - test-on-borrow: false - test-on-return: false - stat-view-servlet: - enabled: true - url-pattern: /druid/* - #login-username: admin - #login-password: admin - filter: - stat: - log-slow-sql: true - slow-sql-millis: 1000 - merge-sql: false - wall: - config: - multi-statement-allow: true + # sharding-jdbc 配置 + shardingsphere: + center-tables-data-node: duanju.%s + # 显示sharding-jdbc改写的sql语句 + show-sql: false + # 数据源名称 + datasource: + # 数据源配置begin + master-0: + driver-class-name: ${driver-class-name} + jdbc-url: jdbc:mysql://rm-gc712o11yndj78x6a6o.mysql.cn-chengdu.rds.aliyuncs.com/duanju?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT + username: video_user + password: VideoUser@1 + minimum-idle: ${minimum-idle} + maximum-pool-size: ${maximum-pool-size} + idle-timeout: ${idle-timeout} + max-lifetime: ${max-lifetime} + connection-timeout: ${connection-timeout} + slave-0: + driver-class-name: ${driver-class-name} + jdbc-url: jdbc:mysql://47.122.26.160:3306/duanju?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT + username: root + password: 0fd6497c308ccfa8 + minimum-idle: ${minimum-idle} + maximum-pool-size: ${maximum-pool-size} + idle-timeout: ${idle-timeout} + max-lifetime: ${max-lifetime} + connection-timeout: ${connection-timeout} + # 数据源配置end + + # 读写分离配置begin + master-slave-rules: + #数据源 + duanju: + master-data-source-name: master-0 + slave-data-source-names: slave-0 +# - master-0 +# - slave-0 swagger: enabled: true diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml new file mode 100644 index 00000000..54eea696 --- /dev/null +++ b/src/main/resources/application-local.yml @@ -0,0 +1,59 @@ +# 数据源的一些配置 +driver-class-name: com.mysql.cj.jdbc.Driver +# 最小空闲连接,默认值10,小于0或大于maximum-pool-size,都会重置为maximum-pool-size +minimum-idle: 5 +# 最大连接数,小于等于0会被重置为默认值10;大于零小于1会被重置为minimum-idle的值 +maximum-pool-size: 15 +# 空闲连接超时时间,默认值600000(10分钟),大于等于max-lifetime且max-lifetime>0,会被重置为0;不等于0且小于10秒,会被重置为10秒。 +idle-timeout: 30000 +# 连接最大存活时间.不等于0且小于30秒,会被重置为默认值30分钟.设置应该比mysql设置的超时时间短 +max-lifetime: 30000 +# 连接超时时间:毫秒,小于250毫秒,否则被重置为默认值30秒 +connection-timeout: 30000 + +spring: + # sharding-jdbc 配置 + shardingsphere: + center-tables-data-node: duanju.%s + # 显示sharding-jdbc改写的sql语句 + show-sql: false + # 数据源名称 + datasource: + # 数据源配置begin + master-0: + driver-class-name: ${driver-class-name} + jdbc-url: jdbc:mysql://rm-gc712o11yndj78x6a6o.mysql.cn-chengdu.rds.aliyuncs.com/duanju?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT + username: video_user + password: VideoUser@1 + minimum-idle: ${minimum-idle} + maximum-pool-size: ${maximum-pool-size} + idle-timeout: ${idle-timeout} + max-lifetime: ${max-lifetime} + connection-timeout: ${connection-timeout} + slave-0: + driver-class-name: ${driver-class-name} + jdbc-url: jdbc:mysql://47.122.26.160:3306/duanju?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT + username: root + password: 0fd6497c308ccfa8 + minimum-idle: ${minimum-idle} + maximum-pool-size: ${maximum-pool-size} + idle-timeout: ${idle-timeout} + max-lifetime: ${max-lifetime} + connection-timeout: ${connection-timeout} + # 数据源配置end + + # 读写分离配置begin + master-slave-rules: + #数据源 + duanju: + master-data-source-name: master-0 + slave-data-source-names: slave-0 +# - master-0 +# - slave-0 + +swagger: + enabled: true +pay: + h5BaseUrl: https://video-h5.hnsiyao.cn/me/detail/detail?allId= + orderNotifyUrl: https://video.hnsiyao.cn/czg/app/wuyou/notify + extractNotifyUrl: https://video.hnsiyao.cn/czg/app/wuyou/extractNotify diff --git a/src/main/resources/application-pay.yml b/src/main/resources/application-pay.yml new file mode 100644 index 00000000..0d94a784 --- /dev/null +++ b/src/main/resources/application-pay.yml @@ -0,0 +1,65 @@ +# 数据源的一些配置 +driver-class-name: com.mysql.cj.jdbc.Driver +# 最小空闲连接,默认值10,小于0或大于maximum-pool-size,都会重置为maximum-pool-size +minimum-idle: 5 +# 最大连接数,小于等于0会被重置为默认值10;大于零小于1会被重置为minimum-idle的值 +maximum-pool-size: 15 +# 空闲连接超时时间,默认值600000(10分钟),大于等于max-lifetime且max-lifetime>0,会被重置为0;不等于0且小于10秒,会被重置为10秒。 +idle-timeout: 30000 +# 连接最大存活时间.不等于0且小于30秒,会被重置为默认值30分钟.设置应该比mysql设置的超时时间短 +max-lifetime: 30000 +# 连接超时时间:毫秒,小于250毫秒,否则被重置为默认值30秒 +connection-timeout: 30000 + +spring: + # sharding-jdbc 配置 + shardingsphere: + center-tables-data-node: duanju.%s + # 显示sharding-jdbc改写的sql语句 + show-sql: false + # 数据源名称 + datasource: + # 数据源配置begin + master-0: + driver-class-name: ${driver-class-name} + jdbc-url: jdbc:mysql://rm-gc7xx913734hv5w5qxo.mysql.cn-chengdu.rds.aliyuncs.com/duanju?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT + username: video_user + password: VideoUser@1 +# jdbc-url: jdbc:mysql://rm-gc712o11yndj78x6a6o.mysql.cn-chengdu.rds.aliyuncs.com/duanju?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT +# username: video_user +# password: VideoUser@1 + minimum-idle: ${minimum-idle} + maximum-pool-size: ${maximum-pool-size} + idle-timeout: ${idle-timeout} + max-lifetime: ${max-lifetime} + connection-timeout: ${connection-timeout} + slave-0: + driver-class-name: ${driver-class-name} + jdbc-url: jdbc:mysql://rm-gc7xx913734hv5w5qxo.mysql.cn-chengdu.rds.aliyuncs.com/duanju?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT + username: video_user + password: VideoUser@1 +# jdbc-url: jdbc:mysql://47.122.26.160:3306/duanju?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT +# username: root +# password: 0fd6497c308ccfa8 + minimum-idle: ${minimum-idle} + maximum-pool-size: ${maximum-pool-size} + idle-timeout: ${idle-timeout} + max-lifetime: ${max-lifetime} + connection-timeout: ${connection-timeout} + # 数据源配置end + + # 读写分离配置begin + master-slave-rules: + #数据源 + duanju: + master-data-source-name: master-0 + slave-data-source-names: slave-0 +# - master-0 +# - slave-0 + +swagger: + enabled: true +pay: + h5BaseUrl: https://video-h5.hnsiyao.cn/me/detail/detail?allId= + orderNotifyUrl: https://video.hnsiyao.cn/czg/app/wuyou/notify + extractNotifyUrl: https://video.hnsiyao.cn/czg/app/wuyou/extractNotify diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 00000000..80305245 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1 @@ +center-tables=activity,app,banner,cash_out,comment_good,common_info,complet_award,coupon,coupon_user,course,course_classification,course_collect,course_comment,course_details,course_user,disc_spinning,disc_spinning_amount,disc_spinning_record,help_classify,help_word,invite,invite_award,invite_money,message_info,msg,orders,pay_classify,pay_details,qrtz_blob_triggers,qrtz_calendars,qrtz_cron_triggers,qrtz_fired_triggers,qrtz_job_details,qrtz_locks,qrtz_paused_trigger_grps,qrtz_scheduler_state,qrtz_simple_triggers,qrtz_simprop_triggers,qrtz_triggers,schedule_job,schedule_job_log,sdk_info,sdk_type,search,sys_captcha,sys_config,sys_dict,sys_log,sys_menu,sys_oss,sys_role,sys_role_menu,sys_user,sys_user_role,sys_user_token,task_center,task_center_record,task_center_reward,tb_user,uni_ad_callback_record,url_address,user_integral,user_integral_details,user_money,user_money_details,user_prize_exchange,user_sign_record,user_vip,vip_details,invite_achievement \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3c9ca3c1..508a1738 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -45,10 +45,14 @@ spring: min-idle: 5 # 连接池中的最小空闲连接 mvc: throw-exception-if-no-handler-found: true - pathmatch: - matching-strategy: ant_path_matcher +# pathmatch: +# matching-strategy: ant_path_matcher +management: + health: + db: + enabled: false #关闭数据库健康检查isV #mybatis mybatis-plus: mapper-locations: classpath*:/mapper/**/*.xml @@ -84,3 +88,8 @@ sqx: header: token uni: adSecret: 122e4ff1edc66dcf8761f7f7ffc81e0f8773cbfafb58aed29c72fbd092c77315 + + +limit: + urlRate: 10 # 同一用户单url每秒限制次数 + ipJumpLimit: 4 # 同一ip每分钟跳动次数 diff --git a/src/main/resources/mapper/InviteAchievementMapper.xml b/src/main/resources/mapper/InviteAchievementMapper.xml new file mode 100644 index 00000000..bfa2a236 --- /dev/null +++ b/src/main/resources/mapper/InviteAchievementMapper.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + id,user_id,by_user_id, + amount,create_time + + diff --git a/src/main/resources/mapper/app/UserDao.xml b/src/main/resources/mapper/app/UserDao.xml index ef279061..6a2e79b7 100644 --- a/src/main/resources/mapper/app/UserDao.xml +++ b/src/main/resources/mapper/app/UserDao.xml @@ -52,13 +52,13 @@ - and date_format(u.create_time,'%Y-%m-%d') BETWEEN #{startTime} and #{endTime} + and u.create_time BETWEEN #{startTime} and #{endTime} - and date_format(u.create_time,'%Y-%m-%d') >= #{startTime} + and u.create_time >= #{startTime} - and date_format(u.create_time,'%Y-%m-%d') <= #{endTime} + and u.create_time <= #{endTime} order by create_time desc @@ -136,7 +136,6 @@ SELECT - MAX( u.update_time ) AS produceEndTime, - c.*, - ( - SELECT - d.course_details_name - FROM - course_collect cc - LEFT JOIN course_details d ON cc.course_details_id = d.course_details_id - WHERE - d.course_id = u.course_id - AND cc.classify = 3 and cc.user_id=#{userId} - ORDER BY - cc.update_time DESC - LIMIT 1 - ) AS courseDetailsName, - ( - SELECT - d.course_details_id - FROM - course_collect cc - LEFT JOIN course_details d ON cc.course_details_id = d.course_details_id - WHERE - d.course_id = u.course_id - AND cc.classify = 3 and cc.user_id=#{userId} - ORDER BY - cc.update_time DESC - LIMIT 1 - ) AS courseDetailsId, - ( SELECT count(*) FROM course_details d WHERE d.course_id = c.course_id ) AS courseDetailsCount + MAX(u.update_time) AS produceEndTime, + c.*, + d.course_details_name AS courseDetailsName, + d.course_details_id AS courseDetailsId, + cd.course_details_count AS courseDetailsCount FROM - course_collect u - LEFT JOIN course c ON u.course_id = c.course_id + course_collect u + LEFT JOIN course c ON u.course_id = c.course_id + LEFT JOIN ( + SELECT + cc.course_id, + cc.user_id, + d.course_details_name, + d.course_details_id + FROM + course_collect cc + LEFT JOIN course_details d ON cc.course_details_id = d.course_details_id WHERE - u.user_id = #{userId} - AND c.course_id IS NOT NULL - AND u.classify = #{classify} - GROUP BY - u.course_id + cc.classify = 3 + AND cc.user_id = #{userId} ORDER BY - produceEndTime DESC + cc.update_time DESC + ) AS d ON u.course_id = d.course_id + LEFT JOIN ( + SELECT + d.course_id, + COUNT(*) AS course_details_count + FROM + course_details d + GROUP BY + d.course_id + ) AS cd ON c.course_id = cd.course_id + WHERE + u.user_id = #{userId} + AND c.course_id IS NOT NULL + AND u.classify = #{classify} + GROUP BY + u.course_id + ORDER BY + produceEndTime DESC + + + + - \ No newline at end of file + diff --git a/src/main/resources/mapper/course/CourseDao.xml b/src/main/resources/mapper/course/CourseDao.xml index a8118457..39b6fbae 100644 --- a/src/main/resources/mapper/course/CourseDao.xml +++ b/src/main/resources/mapper/course/CourseDao.xml @@ -31,43 +31,32 @@ c.course_type as courseType, c.banner_id as bannerId, b.name as bannerName, - (select sum(cd.view_count) from course_details cd where cd.course_id = c.course_id ) as viewCounts, + 0 as viewCounts, c.dy_img_id as dyImgId, c.dy_course_id as dyCourseId, c.wx_course_id as wxCourseId, c.wx_show as wxShow, c.dy_show as dyShow, c.sort, - (select sum(good_num) from course_details d where d.course_id=c.course_id ) as goodNum, - (select count(*) from course_details d where d.course_id=c.course_id ) as courseDetailsCount, - - ( - SELECT - cc.course_details_id - FROM - course_collect cc - WHERE - cc.course_id = c.course_id - AND cc.classify = 3 - and cc.user_id = #{userId} - ORDER BY - cc.update_time desc - LIMIT 1 - ) AS courseDetailsId, - - - null AS courseDetailsName, - null AS courseDetailsId, - - - (select count(*) from course_collect d where d.course_id=c.course_id - and date_format(create_time,'%Y-%m-%d')>=date_format(#{startTime},'%Y-%m-%d') and - date_format(create_time,'%Y-%m-%d')<=date_format(#{endTime},'%Y-%m-%d') ) as weekGoodNum, - (select count(*) from course_details cd where c.course_id=cd.course_id and cd.good=1 ) as isRecommend + round(10000*rand(),0) as goodNum, + ifnull(d.courseDetailsCount,0) as courseDetailsCount, + null AS courseDetailsName, + null AS courseDetailsId, + round(10000*rand(),0) as weekGoodNum, + 0 as isRecommend FROM course AS c LEFT JOIN course_classification AS cc ON c.classify_id = cc.classification_id - left join banner as b on b.id=c.banner_id + LEFT JOIN banner AS b ON b.id = c.banner_id + LEFT JOIN ( + SELECT + course_id, + COUNT(*) AS courseDetailsCount + FROM + course_details + GROUP BY + course_id + ) AS d ON d.course_id = c.course_id WHERE 1 = 1 AND c.is_delete = 0 @@ -114,7 +103,7 @@ and c.dy_status=4 - order by c.sort asc + order by c.sort asc,c.create_time desc order by goodNum desc @@ -150,7 +139,7 @@ c.course_type as courseType, c.banner_id as bannerId, b.name as bannerName, - (select sum(cd.view_count) from course_details cd where cd.course_id = c.course_id ) as viewCounts, + ifnull(d.viewCounts,0) as viewCounts, c.dy_img_id as dyImgId, c.dy_course_id as dyCourseId, c.dy_status as dyStatus, @@ -173,26 +162,26 @@ c.`cost_distribution_uri` as costDistributionUri, c.`assurance_uri` as assuranceUri, c.`playlet_production_cost` as playletProductionCost, - c.`qualification_type` as qualificationType, c.`registration_number` as registrationNumber, c.`qualification_certificate_material_id` as qualificationCertificateMaterialId, c.`cost_of_production` as costOfProduction, c.`cost_commitment_letter_material_id` as costCommitmentLetterMaterialId, c.`wx_course_status` as wxCourseStatus, - - (select count(*) from course_details where dy_url_status in (1,3) or dy_url_status=null) as dyUrlStatus, - (select sum(o.pay_money) from orders o where o.course_id=c.course_id and o.status=1) as payMoney, - (select sum(good_num) from course_details d where d.course_id=c.course_id ) as goodNum, - (select count(*) from course_details d where d.course_id=c.course_id ) as courseDetailsCount, - (select count(*) from course_collect d where d.course_id=c.course_id - and date_format(create_time,'%Y-%m-%d')>=date_format(#{startTime},'%Y-%m-%d') and - date_format(create_time,'%Y-%m-%d')<=date_format(#{endTime},'%Y-%m-%d') ) as weekGoodNum, - (select count(*) from course_details cd where c.course_id=cd.course_id and cd.good=1 ) as isRecommend + t.dyUrlStatus, + o.payMoney, + ifnull(d.goodNum,0) as goodNum, + ifnull(d.courseDetailsCount) as courseDetailsCount, + 0 as weekGoodNum, + ifnull(tt.isRecommend,0) as isRecommend FROM course AS c LEFT JOIN course_classification AS cc ON c.classify_id = cc.classification_id left join banner as b on b.id=c.banner_id + left join (select 1 as id,count(*) as dyUrlStatus from course_details where dy_url_status in (1,3) or dy_url_status=null group by course_id) t on t.id = 1 + left join (select course_id,sum(pay_money) as payMoney from orders where status=1 group by course_id) o on o.course_id = c.course_id + left join (select course_id,sum(view_count) as viewCounts,sum(good_num) as goodNum,count(*) as courseDetailsCount from course_details group by course_id) d on d.course_id = c.course_id + left join (select course_id,count(*) as isRecommend from course_details where good=1 group by course_id) tt on tt.course_id = c.course_id WHERE 1 = 1 AND c.is_delete = 0 @@ -217,7 +206,7 @@ and c.banner_id = #{bannerId} - + and c.is_recommend=1 diff --git a/src/main/resources/mapper/course/CourseDetailsDao.xml b/src/main/resources/mapper/course/CourseDetailsDao.xml index 558bdb5e..6d3512fb 100644 --- a/src/main/resources/mapper/course/CourseDetailsDao.xml +++ b/src/main/resources/mapper/course/CourseDetailsDao.xml @@ -4,9 +4,12 @@ @@ -57,7 +71,7 @@ and (c.dy_show = #{dyShow} or c.dy_show is null) - order by SUBSTR(uid, #{randomNum}, 6) + order by SUBSTR(uid, ${randomNum}, 6) diff --git a/src/main/resources/mapper/course/CourseUserDao.xml b/src/main/resources/mapper/course/CourseUserDao.xml index 4123e5ac..70c86e24 100644 --- a/src/main/resources/mapper/course/CourseUserDao.xml +++ b/src/main/resources/mapper/course/CourseUserDao.xml @@ -2,31 +2,31 @@ - + + + + + + + + + + + - + + + + + + + + + + + + + diff --git a/src/main/resources/mapper/pay/CashDao.xml b/src/main/resources/mapper/pay/CashDao.xml index 1533132c..0e3cf72b 100644 --- a/src/main/resources/mapper/pay/CashDao.xml +++ b/src/main/resources/mapper/pay/CashDao.xml @@ -30,43 +30,15 @@ - update pay_details set `state`=#{state},pay_time=#{time},trade_no=#{tradeNo} where id=#{id} - - - + update pay_details + set `state`=#{state}, + pay_time=#{time}, + trade_no=#{tradeNo}, + third_order_no=#{thirdOrderNo} + where id = #{id} + select sum(money) from pay_details - where str_to_date(create_time, '%Y-%m-%d') BETWEEN str_to_date(#{createTime}, '%Y-%m-%d') AND str_to_date(#{endTime}, '%Y-%m-%d') + where create_time BETWEEN #{createTime} AND #{endTime} and user_id=#{userId}