You've already forked mine_clearance
项目上传
This commit is contained in:
149
challenge/pom.xml
Normal file
149
challenge/pom.xml
Normal file
@@ -0,0 +1,149 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>mine_clearance</artifactId>
|
||||
<groupId>com.lightyears.mine_clearance</groupId>
|
||||
<version>1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>challenge</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
<!-- druid数据源驱动 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!--json-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-generator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!-- 由于SpringBoot 2.x中默认并没有使用Redis连接池,所以需要添加commons-pool2的依赖-->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
<!--redis依赖配置-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<!-- 模板引擎 -->
|
||||
<dependency>
|
||||
<groupId>org.freemarker</groupId>
|
||||
<artifactId>freemarker</artifactId>
|
||||
</dependency>
|
||||
<!--swagger2整合-->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>2.9.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>2.9.2</version>
|
||||
</dependency>
|
||||
<!-- rocketmq 整合 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.rocketmq</groupId>
|
||||
<artifactId>rocketmq-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!-- hutool 一个常用工具集 -->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.rocketmq</groupId>
|
||||
<artifactId>rocketmq-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.lightyears.mine_clearance</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<finalName>challenge</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<encoding>utf-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!--打包一个JAR-->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<mainClass>com.lightyears.challenge.ChallengeApp</mainClass>
|
||||
<includeSystemScope>true</includeSystemScope>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<testFailureIgnore>true</testFailureIgnore>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.lightyears.challenge;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
import java.util.TimeZone;
|
||||
|
||||
@EnableScheduling
|
||||
@SpringBootApplication
|
||||
@EnableTransactionManagement
|
||||
public class ChallengeApp {
|
||||
public static void main(String[] args) {
|
||||
// 设置时区
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
|
||||
SpringApplication.run(ChallengeApp.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.lightyears.challenge.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Documented
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DataVerification {
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.lightyears.challenge.aspect;
|
||||
|
||||
import cn.hutool.crypto.digest.MD5;
|
||||
import com.github.pagehelper.util.StringUtil;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import com.lightyears.challenge.exception.GlobalException;
|
||||
import com.lightyears.challenge.util.StaticUtil;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class DataVerificationAspect {
|
||||
/**
|
||||
* 过滤类
|
||||
* 指定自定义注解为切入点
|
||||
**/
|
||||
@Pointcut("@annotation(com.lightyears.challenge.annotation.DataVerification)")
|
||||
public void checkPoint() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 前置
|
||||
*/
|
||||
@Before("checkPoint()")
|
||||
public void doAround(JoinPoint joinPoint) throws GlobalException {
|
||||
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
|
||||
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
|
||||
assert sra != null;
|
||||
HttpServletRequest request = sra.getRequest();
|
||||
String checkKey = request.getHeader("checkKey");
|
||||
Map<String, String[]> paramMap = request.getParameterMap();
|
||||
StringBuffer paramsStr = new StringBuffer();
|
||||
|
||||
if (StringUtil.isEmpty(checkKey)) {
|
||||
throw new GlobalException(MessageEnum.CHECK_KEY_ERROR);
|
||||
}
|
||||
Object[] params = joinPoint.getArgs();
|
||||
if(paramMap.size() > 0) {
|
||||
Collection<String[]> values = paramMap.values();
|
||||
for (String[] value : values) {
|
||||
paramsStr.append(value[0]);
|
||||
}
|
||||
} else {
|
||||
if(params.length == 1) {
|
||||
paramsStr.append(params[0].toString());
|
||||
}
|
||||
}
|
||||
String testKey = MD5.create().digestHex(MD5.create().digestHex(paramsStr.append(StaticUtil.PRIVATE_KEY).toString()));
|
||||
if (!checkKey.equals(testKey)) {
|
||||
throw new GlobalException(MessageEnum.CHECK_KEY_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lightyears.challenge.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Data
|
||||
@Component
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ConfigurationProperties(prefix = "appconfig")
|
||||
public class AppConfig {
|
||||
private Float version;
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.lightyears.challenge.configuration;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||
import org.springframework.data.redis.cache.RedisCacheWriter;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
// 开启redis缓存功能
|
||||
@EnableCaching
|
||||
// 备注这是一个配置类
|
||||
@Configuration
|
||||
public class RedisConfig extends CachingConfigurerSupport {
|
||||
|
||||
/**
|
||||
* 配置redis模板文件
|
||||
* @param redisConnectionFactory
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisSerializer<Object> serializer = redisSerializer();
|
||||
// 创建RedisTemplate<String, Object>对象
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||
// 配置连接工厂
|
||||
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||
// redis key 序列化方式使用stringSerial
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
// redis value 序列化方式使用jackson
|
||||
redisTemplate.setValueSerializer(serializer);
|
||||
// redis hash key 序列化方式使用stringSerial
|
||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||
// redis hash value 序列化方式使用jackson
|
||||
redisTemplate.setHashValueSerializer(serializer);
|
||||
redisTemplate.afterPropertiesSet();
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置序列化
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public RedisSerializer<Object> redisSerializer() {
|
||||
// 定义Jackson2JsonRedisSerializer序列化对象
|
||||
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
|
||||
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会报异常
|
||||
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
serializer.setObjectMapper(objectMapper);
|
||||
return serializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义缓存管理器
|
||||
* @param redisConnectionFactory
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
|
||||
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration
|
||||
.defaultCacheConfig()
|
||||
// 设置value 为自动转json的Object
|
||||
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer()))
|
||||
// 缓存有效期为一天
|
||||
.entryTtl(Duration.ofDays(1));
|
||||
return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.lightyears.challenge.configuration;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
|
||||
import java.util.TimeZone;
|
||||
|
||||
@Configuration
|
||||
public class ScheduledConfig {
|
||||
@Bean
|
||||
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
|
||||
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
|
||||
threadPoolTaskScheduler.setPoolSize(3);
|
||||
threadPoolTaskScheduler.setRemoveOnCancelPolicy(true);
|
||||
return threadPoolTaskScheduler;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
|
||||
return jacksonObjectMapperBuilder ->
|
||||
jacksonObjectMapperBuilder.timeZone(TimeZone.getTimeZone("GMT+8"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.lightyears.challenge.controller;
|
||||
|
||||
import com.lightyears.challenge.util.RedisCache;
|
||||
import com.lightyears.challenge.util.StaticUtil;
|
||||
import com.lightyears.common.domain.entity.Player;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class BaseController {
|
||||
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
/**
|
||||
* 得到request对象
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public HttpServletRequest getRequest() {
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
|
||||
.getRequest();
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到respones对象
|
||||
* @return
|
||||
*/
|
||||
public HttpServletResponse getResponse() {
|
||||
HttpServletResponse request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
|
||||
.getResponse();
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到当前登录用户信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Player getUserInfo() {
|
||||
// 获取请求头中的token数据
|
||||
String token = getRequest().getHeader("Tracecode");
|
||||
if(token == null) {
|
||||
token = this.getRequest().getParameter("Tracecode");
|
||||
}
|
||||
String key = StaticUtil.ONLINE_USER_PUBLIC_KEY.concat(token);
|
||||
// 获取登录用户信息
|
||||
Player user = redisCache.getCacheObject(key);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.lightyears.challenge.controller;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.lightyears.challenge.annotation.DataVerification;
|
||||
import com.lightyears.challenge.schedule.DynamicCornTask;
|
||||
import com.lightyears.challenge.service.IChallengeService;
|
||||
import com.lightyears.challenge.util.ResultUtil;
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
import com.lightyears.common.domain.entity.Player;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@CrossOrigin
|
||||
@RestController
|
||||
@RequestMapping("/challenge")
|
||||
@Api("扫雷 挑战榜调用接口:")
|
||||
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
|
||||
public class ChallengeController extends BaseController{
|
||||
|
||||
private final IChallengeService challengeServiceImpl;
|
||||
private final DynamicCornTask dynamicCornTask;
|
||||
|
||||
@DataVerification
|
||||
@GetMapping("/list")
|
||||
@ApiOperation(value = "榜单列表", notes = "挑战榜")
|
||||
public ResModeBase list() {
|
||||
return challengeServiceImpl.getList();
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/rankList", method = RequestMethod.POST)
|
||||
@ApiOperation(value = "挑战榜列表", notes = "挑战榜")
|
||||
@DataVerification
|
||||
public ResModeBase rankList(
|
||||
@ApiParam(value = "当前页", example = "1") @RequestParam(value = "pageIndex") Integer pageIndex,
|
||||
@ApiParam(value = "每页数量", example = "1") @RequestParam(value = "pageSize") Integer pageSize,
|
||||
@ApiParam(value = "榜单id", example = "1") @RequestParam(value = "id") Integer id) {
|
||||
return challengeServiceImpl.rankList(pageIndex, pageSize, id);
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/admissionTicket", method = RequestMethod.POST)
|
||||
@ApiOperation(value = "挑战门票费-开始挑战", notes = "挑战榜")
|
||||
public ResModeBase admissionTicket( @ApiParam(value = "榜单id", example = "1") @RequestParam(value = "instanceId") Integer instanceId,
|
||||
@ApiParam(value = "将要挑战的名次", example = "1") @RequestParam(value = "rank")Integer rank,
|
||||
@ApiParam(value = "货币数量", example = "1") @RequestParam(value = "gold") Integer gold,
|
||||
@ApiParam(value = "货币类型", example = "1") @RequestParam(value = "type") Integer type,
|
||||
@ApiParam(value = "操作备注", example = "1") @RequestParam(value = "remark") String remark) {
|
||||
return challengeServiceImpl.admissionTicket(instanceId, rank, gold, type,remark, this.getUserInfo().getUser_id());
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/challengeDataSubmit", method = RequestMethod.POST)
|
||||
@ApiOperation(value = "挑战结算", notes = "挑战榜")
|
||||
public ResModeBase challengeDataSubmit( @ApiParam(value = "榜单id", example = "1") @RequestParam(value = "instanceId") Integer instanceId,
|
||||
@ApiParam(value = "挑战名次", example = "1") @RequestParam(value = "rank") Integer rank,
|
||||
@ApiParam(value = "游戏数据", example = "1") @RequestParam(value = "gameData") String gameData,
|
||||
@ApiParam(value = "挑战用时", example = "1") @RequestParam(value = "challengeTime") Integer challengeTime,
|
||||
@ApiParam(value = "挑战时原榜主id", example = "1") @RequestParam(value = "ownerId") Integer ownerId) {
|
||||
Player player = this.getUserInfo();
|
||||
return challengeServiceImpl.challengeDataSubmit(instanceId,rank,gameData,challengeTime,ownerId, player.getUser_id(), player.getUser_name());
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@GetMapping("/playerAssert")
|
||||
@ApiOperation(value = "获取玩家资产信息", notes = "挑战榜")
|
||||
public ResModeBase playerAssert(){
|
||||
return challengeServiceImpl.playerAssert(this.getUserInfo().getUser_id());
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@GetMapping("/getMyRankInfo")
|
||||
@ApiOperation(value = "获取玩家在榜单中的名次信息", notes = "挑战榜")
|
||||
public ResModeBase getPlayerRankInfo(@ApiParam(value = "榜单id", example = "1") @RequestParam(value = "instanceId") Integer instanceId){
|
||||
return challengeServiceImpl.getPlayerRankInfo(instanceId, this.getUserInfo().getUser_id());
|
||||
}
|
||||
|
||||
@PostMapping("/resetTaskTime")
|
||||
public ResModeBase resetChallengeTaskTime(@RequestParam(value = "lockDate") String lockDateStr,
|
||||
@RequestParam(value = "settlementDate") String settlementDateStr,
|
||||
@RequestParam(value = "initDate") String initDateStr,
|
||||
@RequestParam(value = "refreshDateStr") String refreshDateStr){
|
||||
// 锁榜
|
||||
DateTime lockDate = DateUtil.parse(lockDateStr);
|
||||
// 结算
|
||||
DateTime settlementDate = DateUtil.parse(settlementDateStr);
|
||||
// 初始化
|
||||
DateTime initDate = DateUtil.parse(initDateStr);
|
||||
// 刷新
|
||||
DateTime refreshDate = DateUtil.parse(refreshDateStr);
|
||||
|
||||
// 发起重置时间
|
||||
dynamicCornTask.initChallengeTask(lockDate, settlementDate, initDate, refreshDate);
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), "请求成功!");
|
||||
}
|
||||
|
||||
@PostMapping("/refreshRankCache")
|
||||
public ResModeBase refreshRankCache(@RequestParam(value = "key")Integer key, @RequestParam(value = "instanceId") Integer instanceId, @RequestParam(value = "playerId") Integer playerId, @RequestParam(value = "rankNum") Integer rankNum){
|
||||
if(key == 43626546) {
|
||||
challengeServiceImpl.clearRankByInstancePlayerId(instanceId, playerId, rankNum);
|
||||
}
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.lightyears.challenge.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.lightyears.common.domain.entity.AssertLog;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-16
|
||||
*/
|
||||
@Mapper
|
||||
public interface AssertLogMapper extends BaseMapper<AssertLog> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.lightyears.challenge.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.lightyears.common.domain.entity.ListBase;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-16
|
||||
*/
|
||||
@Mapper
|
||||
public interface ListBaseMapper extends BaseMapper<ListBase> {
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.lightyears.challenge.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.lightyears.common.domain.dto.ListInstanceDto;
|
||||
import com.lightyears.common.domain.entity.ListInstance;
|
||||
import com.lightyears.common.domain.dto.ListInstanceDto;
|
||||
import com.lightyears.common.domain.entity.ListInstance;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-16
|
||||
*/
|
||||
@Mapper
|
||||
public interface ListInstanceMapper extends BaseMapper<ListInstance> {
|
||||
|
||||
/**
|
||||
* 奖池增加
|
||||
* @param instanceId 榜实例id
|
||||
* @param awardSize 奖池要增加的数
|
||||
* @param assetsType 货币类型
|
||||
* @return
|
||||
*/
|
||||
int updateInstanceAwardSize(@Param("instanceId") Integer instanceId,@Param("awardSize") Integer awardSize,@Param("assetsType") Integer assetsType);
|
||||
|
||||
/**
|
||||
* 获取榜单列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<ListInstanceDto> getListInstances();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.lightyears.challenge.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.lightyears.common.domain.dto.ListRankDto;
|
||||
import com.lightyears.common.domain.entity.ListRank;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-16
|
||||
*/
|
||||
@Mapper
|
||||
public interface ListRankMapper extends BaseMapper<ListRank> {
|
||||
int initRank(@Param("instanceId") Integer instanceId, @Param("playerId") Integer playerId);
|
||||
List<ListRankDto> getRankList(@Param("instanceId") Integer instanceId, @Param("playerId") Integer playerId, @Param("state") Integer state);
|
||||
List<ListRankDto> getNewRankList (@Param("instanceId") Integer instanceId, @Param("playerId") Integer playerId);
|
||||
ListRankDto getRankByInsRank(@Param("instanceId") Integer instanceId,@Param("rank") Integer rank);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.lightyears.challenge.dao;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.lightyears.common.domain.entity.Log;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 游戏 完成记录 表 游戏难度:1 - 普通 2 困难 3 大师 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-09
|
||||
*/
|
||||
@Mapper
|
||||
public interface LogMapper extends BaseMapper<Log> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.lightyears.challenge.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.lightyears.common.domain.entity.Notice;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-18
|
||||
*/
|
||||
@Mapper
|
||||
public interface NoticeMapper extends BaseMapper<Notice> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.lightyears.challenge.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.lightyears.common.domain.dto.SimplePlayerAssert;
|
||||
import com.lightyears.common.domain.entity.PlayerAssets;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-16
|
||||
*/
|
||||
@Mapper
|
||||
public interface PlayerAssetsMapper extends BaseMapper<PlayerAssets> {
|
||||
// 货币存放服务器
|
||||
int addGold(@Param("id") int id, @Param("gold") int gold, @Param("version") Long version);
|
||||
|
||||
// 从服务器取出货币
|
||||
int reduceGold(@Param("id") int id,@Param("gold") int gold, @Param("version") Long version);
|
||||
/**
|
||||
* 获取用户资产
|
||||
* @param playerId
|
||||
* @return
|
||||
*/
|
||||
List<SimplePlayerAssert> getPlayerAssets(@Param("playerId") int playerId);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.lightyears.challenge.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.lightyears.common.domain.entity.Player;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 扫雷玩家表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-09
|
||||
*/
|
||||
@Mapper
|
||||
public interface PlayerMapper extends BaseMapper<Player> {
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.lightyears.challenge.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.lightyears.common.domain.entity.Record;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 游戏存档 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-09
|
||||
*/
|
||||
@Mapper
|
||||
public interface RecordMapper extends BaseMapper<Record> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.lightyears.challenge.exception;
|
||||
|
||||
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
|
||||
/**
|
||||
* @author fengshuonan
|
||||
* @Description 业务异常的封装
|
||||
*/
|
||||
public class BussinessException extends GlobalException {
|
||||
public BussinessException(MessageEnum messageEnum) {
|
||||
super(messageEnum.getCode(), messageEnum.getMessage());
|
||||
}
|
||||
|
||||
public BussinessException(Integer code, String message) {
|
||||
super(code, message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.lightyears.challenge.exception;
|
||||
|
||||
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
|
||||
/***
|
||||
* 全局异常捕捉 统一返回 model
|
||||
* */
|
||||
public class GlobalException extends RuntimeException {
|
||||
|
||||
//友好提示的code码
|
||||
protected int friendlyCode;
|
||||
|
||||
//友好提示
|
||||
protected String friendlyMsg;
|
||||
|
||||
|
||||
protected GlobalException(int friendlyCode, String friendlyMsg) {
|
||||
this.setValues(friendlyCode, friendlyMsg);
|
||||
}
|
||||
|
||||
public GlobalException(MessageEnum messageEnum) {
|
||||
this.setValues(messageEnum.getCode(), messageEnum.getMessage());
|
||||
}
|
||||
|
||||
private void setValues(int friendlyCode, String friendlyMsg) {
|
||||
this.friendlyCode = friendlyCode;
|
||||
this.friendlyMsg = friendlyMsg;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return friendlyCode;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.friendlyCode = code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return friendlyMsg;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.friendlyMsg = message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.lightyears.challenge.exception;
|
||||
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import com.lightyears.challenge.util.ResultUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
@Slf4j
|
||||
@ControllerAdvice
|
||||
public class MyExceptionHandle {
|
||||
|
||||
@ExceptionHandler(value = Exception.class)
|
||||
@ResponseBody
|
||||
public ResModeBase handle(Exception e) {
|
||||
if (e instanceof GlobalException) {
|
||||
GlobalException myException = (GlobalException) e;
|
||||
return ResultUtil.result(myException.getCode(), myException.getMessage());
|
||||
} else {
|
||||
log.error("系统异常", e);
|
||||
return ResultUtil.result(MessageEnum.UNKNOWN_ERROR.getCode(), MessageEnum.UNKNOWN_ERROR.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.lightyears.challenge.filter;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.github.pagehelper.util.StringUtil;
|
||||
import com.lightyears.challenge.config.AppConfig;
|
||||
import com.lightyears.common.domain.entity.Player;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import com.lightyears.challenge.util.RedisCache;
|
||||
import com.lightyears.challenge.util.StaticUtil;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
public class TokenFilter implements Filter{
|
||||
@Resource
|
||||
private RedisCache redisCache;
|
||||
@Resource
|
||||
private AppConfig appConfig;
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) {
|
||||
ServletContext servletContext = filterConfig.getServletContext();
|
||||
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
|
||||
redisCache = (RedisCache) ctx.getBean("redisCache");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
||||
// 刷新缓存不验证
|
||||
if(request.getRequestURI().indexOf("refreshRankCache")<0){
|
||||
// 版本号验证
|
||||
String version = request.getHeader("version");
|
||||
if (StrUtil.isEmpty(version)) {
|
||||
this.authcReq(response, MessageEnum.VERSION_ERROR.getCode(), MessageEnum.VERSION_ERROR.getMessage());
|
||||
return;
|
||||
}
|
||||
try{
|
||||
Float versionCode = Float.valueOf(version);
|
||||
if(versionCode < appConfig.getVersion()){
|
||||
this.authcReq(response, MessageEnum.VERSION_ERROR.getCode(), MessageEnum.VERSION_ERROR.getMessage());
|
||||
return;
|
||||
}
|
||||
}catch (Exception e) {
|
||||
this.authcReq(response, MessageEnum.VERSION_ERROR.getCode(), MessageEnum.VERSION_ERROR.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String tracecode = request.getHeader("Tracecode");
|
||||
Boolean flag = request.getRequestURI().indexOf("touristLogin")<0 && request.getRequestURI().indexOf("getSystemTime") < 0 && request.getRequestURI().indexOf("swagger-ui")<0 && request.getRequestURI().indexOf("swagger-resources")<0 && request.getRequestURI().indexOf("v2") < 0 && request.getRequestURI().indexOf("refreshRankCache")<0;
|
||||
|
||||
// 登录放行
|
||||
if(flag){
|
||||
// 判断身份码, 是否已登录
|
||||
if((StringUtil.isEmpty(tracecode) || !redisCache.hasKey(StaticUtil.ONLINE_USER_PUBLIC_KEY.concat(tracecode)))){
|
||||
/**
|
||||
* 不是登录 || 身份码不存在 || 未在登录列表 就拒绝访问
|
||||
*/
|
||||
this.authcReq(response, MessageEnum.SYSTEM_ERROR.getCode(), MessageEnum.SYSTEM_ERROR.getMessage());
|
||||
return;
|
||||
}
|
||||
Player player = redisCache.getCacheObject(StaticUtil.ONLINE_USER_PUBLIC_KEY.concat(tracecode));
|
||||
String token = redisCache.getCacheObject(StaticUtil.ONLINE_USER_TOKEN.concat(player.getUser_id().toString())).toString();
|
||||
if(!tracecode.equals(token)) {
|
||||
/**
|
||||
* 登录失效,已被异地登录
|
||||
*/
|
||||
this.authcReq(response, MessageEnum.LOCATION_ERROR.getCode(), MessageEnum.LOCATION_ERROR.getMessage());
|
||||
return;
|
||||
}
|
||||
// 重置身份缓存过期时间
|
||||
redisCache.expire(StaticUtil.ONLINE_USER_TOKEN.concat(player.getUser_id().toString()), 1, TimeUnit.HOURS);
|
||||
// 重置身份认证过期时间
|
||||
redisCache.expire(StaticUtil.ONLINE_USER_PUBLIC_KEY.concat(tracecode), 1, TimeUnit.HOURS);
|
||||
}
|
||||
|
||||
//执行
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应访问
|
||||
* @param response
|
||||
* @throws IOException
|
||||
*/
|
||||
private void authcReq(HttpServletResponse response, Integer code, String msg) throws IOException {
|
||||
response.setHeader("Access-Control-Allow-Origin", "*");
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.setContentType("application/json; charset=utf-8");
|
||||
PrintWriter writer = response.getWriter();
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("code", code);
|
||||
map.put("msg", msg);
|
||||
writer.print(JSONObject.toJSON(map));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.lightyears.challenge.init;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.lightyears.challenge.dao.ListBaseMapper;
|
||||
import com.lightyears.challenge.dao.ListInstanceMapper;
|
||||
import com.lightyears.challenge.dao.ListRankMapper;
|
||||
import com.lightyears.common.domain.dto.ListInstanceDto;
|
||||
import com.lightyears.common.domain.dto.ListRankDto;
|
||||
import com.lightyears.common.domain.dto.OrdinaryRankDto;
|
||||
import com.lightyears.common.domain.entity.ListBase;
|
||||
import com.lightyears.challenge.schedule.DynamicCornTask;
|
||||
import com.lightyears.challenge.util.RedisCache;
|
||||
import com.lightyears.challenge.util.StaticUtil;
|
||||
import org.springframework.data.redis.core.BoundZSetOperations;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 挑战数据初始化
|
||||
*/
|
||||
@Component
|
||||
public class ChallengeDataInit {
|
||||
@Resource
|
||||
private RedisCache redisCache;
|
||||
@Resource
|
||||
private ListRankMapper listRankMapper;
|
||||
@Resource
|
||||
private ListInstanceMapper listInstanceMapper;
|
||||
@Resource
|
||||
private ListBaseMapper listBaseMapper;
|
||||
@Resource
|
||||
private DynamicCornTask dynamicCornTask;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
redisCache.deleteByPrefix(StaticUtil.CHALLENGE_INSTANCE);
|
||||
redisCache.deleteByPrefix(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL);
|
||||
this.initData(true);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void destroy() {
|
||||
// 系统运行结束
|
||||
redisCache.deleteByPrefix(StaticUtil.CHALLENGE_INSTANCE);
|
||||
redisCache.deleteByPrefix(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL);
|
||||
// 写入持久层
|
||||
}
|
||||
|
||||
// 刷新挑战榜的缓存数据
|
||||
public void refreshData() {
|
||||
// 删除上一周期的挑战榜缓存数据
|
||||
redisCache.deleteByPrefix(StaticUtil.CHALLENGE_INSTANCE);
|
||||
redisCache.deleteByPrefix(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL);
|
||||
redisCache.deleteByPrefix(StaticUtil.CHALLENGE_ONLINE_USER);
|
||||
// 写入新一周期的挑战榜缓存数据
|
||||
this.initData(false);
|
||||
}
|
||||
|
||||
private void initData(Boolean isStart){
|
||||
redisCache.deleteByPrefix(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL);
|
||||
// 写入开启中挑战榜实例信息
|
||||
List<ListInstanceDto> instances = this.initInstance();
|
||||
if(isStart){
|
||||
// 启动挑战榜定时任务
|
||||
initChallengeTask();
|
||||
}
|
||||
|
||||
instances.stream().forEach(instance -> {
|
||||
List<ListRankDto> ranks = this.initranks(instance.getId());
|
||||
// 存入
|
||||
redisCache.lSetAll(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL.concat(instance.getId().toString()), ranks);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 存入榜实例信息
|
||||
* @return
|
||||
*/
|
||||
public List<ListInstanceDto> initInstance (){
|
||||
redisCache.deleteByPrefix(StaticUtil.CHALLENGE_INSTANCE);
|
||||
List<ListInstanceDto> instances = this.listInstanceMapper.getListInstances();
|
||||
if (!CollectionUtils.isEmpty(instances)){
|
||||
redisCache.setCacheObject(StaticUtil.CHALLENGE_INSTANCE, instances);
|
||||
}
|
||||
return instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入开启中挑战榜的排名信息
|
||||
* @param instanceId 榜实例id
|
||||
* @return
|
||||
*/
|
||||
public List<ListRankDto> initranks (Integer instanceId){
|
||||
// redisCache.deleteByPrefix(StaticUtil.CHALLENGE_INSTANCE_RANK.concat(instanceId.toString()));
|
||||
List<ListRankDto> ranks = listRankMapper.getRankList(instanceId, null, null);
|
||||
// if (!CollectionUtils.isEmpty(ranks)){
|
||||
// redisCache.setCacheList(StaticUtil.CHALLENGE_INSTANCE_RANK.concat(instanceId.toString()), ranks);
|
||||
// }
|
||||
return ranks;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动挑战榜定时任务
|
||||
*/
|
||||
public void initChallengeTask(){
|
||||
List<ListBase> list = listBaseMapper.selectList(new QueryWrapper<ListBase>().orderByDesc("init_date"));
|
||||
if (!CollectionUtils.isEmpty(list)){
|
||||
ListBase bases = list.get(0);
|
||||
// 锁榜 周日 晚上11:00
|
||||
DateTime lockDate = DateUtil.offsetDay(DateUtil.parse(bases.getInitDate().concat(StaticUtil.LOCKE_TIME)), bases.getSettlementDay() - 1);
|
||||
// 结算 周一 晚上11:45
|
||||
DateTime settlementDate = DateUtil.offsetDay(DateUtil.parse(bases.getInitDate().concat(StaticUtil.SETTLEMENT_TIME)), bases.getSettlementDay());
|
||||
// 初始化 周二 早上1:00
|
||||
DateTime initDate = DateUtil.offsetDay(DateUtil.parse(bases.getInitDate().concat(StaticUtil.CHALLENGE_INIT_TIME)), bases.getSettlementDay() + 1);
|
||||
// 缓存刷新 周二 早上1:05
|
||||
DateTime refreshData = DateUtil.offsetDay(DateUtil.parse(bases.getInitDate().concat(StaticUtil.CHALLENGE_REFRESH_TIME)), bases.getSettlementDay() + 1);
|
||||
// 启动定时任务
|
||||
dynamicCornTask.initChallengeTask(lockDate, settlementDate, initDate, refreshData);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.lightyears.challenge.listener;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.lightyears.challenge.dao.ListInstanceMapper;
|
||||
import com.lightyears.common.domain.dto.ListPoolChangeDto;
|
||||
import com.lightyears.common.domain.dto.ListRankDto;
|
||||
import com.lightyears.common.domain.entity.ListInstance;
|
||||
import com.lightyears.challenge.util.RedisCache;
|
||||
import com.lightyears.challenge.util.StaticUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
|
||||
@RocketMQMessageListener(topic = "admissionTicket", selectorExpression = "submit",consumerGroup = "challengeRankTicket")
|
||||
public class AdmissionTicketListener implements RocketMQListener<ListPoolChangeDto> {
|
||||
|
||||
private final ListInstanceMapper listInstanceMapper;
|
||||
private final RedisCache redisCache;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onMessage(ListPoolChangeDto dto) {
|
||||
log.info("报名消息已成功接收!");
|
||||
ListInstance instance = listInstanceMapper.selectById(dto.getInstanceId());
|
||||
String key = StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL.concat(dto.getInstanceId().toString());
|
||||
if(instance != null && instance.getStatus() == 1){
|
||||
Object obj = redisCache.lGetIndex(key, dto.getRank()-1);
|
||||
if(obj == null)
|
||||
return;
|
||||
String json = JSONObject.toJSONString(obj) ;
|
||||
ListRankDto rankDto = JSON.parseObject(json, ListRankDto.class);
|
||||
|
||||
Integer num = rankDto.getChallenges() == null ? 0 : rankDto.getChallenges();
|
||||
rankDto.setChallenges(num + 1);
|
||||
// 挑战人数+1
|
||||
redisCache.lUpdateIndex(key, dto.getRank()-1, rankDto);
|
||||
// 更新奖池大小
|
||||
listInstanceMapper.updateInstanceAwardSize(dto.getInstanceId(), (int) (dto.getGold()*instance.getInPondFee()), dto.getType());
|
||||
}
|
||||
log.info("报名消息已消费完成");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.lightyears.challenge.listener;
|
||||
|
||||
import com.lightyears.common.domain.dto.ListRankDto;
|
||||
import com.lightyears.common.domain.dto.RankDataDto;
|
||||
import com.lightyears.challenge.service.IListRankService;
|
||||
import com.lightyears.challenge.util.RedisCache;
|
||||
import com.lightyears.challenge.util.StaticUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
|
||||
@RocketMQMessageListener(topic = "rankUpdate", selectorExpression = "submit", consumerGroup = "challengeRank")
|
||||
public class RankDataUpdateListener implements RocketMQListener<RankDataDto> {
|
||||
|
||||
private final IListRankService listRankService;
|
||||
private final RedisCache redisCache;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onMessage(RankDataDto dto) {
|
||||
log.info("结算消息已成功接收!");
|
||||
ListRankDto rankDto = dto.getRankDto();
|
||||
// 查询未结算的原排名信息
|
||||
List<ListRankDto> ranks = listRankService.getPlayerRankInfo(null, dto.getMyId());
|
||||
for (ListRankDto rank : ranks){
|
||||
// 重置该挑战榜单下的其他名次信息
|
||||
int num = listRankService.initRank(rank.getInstanceId(), dto.getMyId());
|
||||
// 更新原排名缓存
|
||||
if(num > 0) {
|
||||
rank.setChallengeTime(null);
|
||||
rank.setPlayerId(null);
|
||||
rank.setPlayerName(null);
|
||||
rank.setGameData(null);
|
||||
redisCache.lUpdateIndex(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL.concat(rank.getInstanceId().toString()), rank.getRankNum() - 1, rank);
|
||||
}
|
||||
}
|
||||
|
||||
rankDto.setPlayerId(dto.getMyId());
|
||||
rankDto.setPlayerName(dto.getMyName());
|
||||
rankDto.setChallengeTime(dto.getChallengeTime());
|
||||
// 更新缓存
|
||||
redisCache.lUpdateIndex(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL.concat(dto.getInstanceId().toString()), rankDto.getRankNum() - 1, rankDto);
|
||||
// 写入数据库
|
||||
listRankService.updateRankInfo(dto.getInstanceId(), dto.getRankNum(), dto.getGameData(), dto.getChallengeTime(), dto.getMyId(), dto.getMyName());
|
||||
log.info("结算消息已成功消费!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.lightyears.challenge.schedule;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.lightyears.common.domain.entity.ListBase;
|
||||
import com.lightyears.challenge.init.ChallengeDataInit;
|
||||
import com.lightyears.challenge.service.IListBaseService;
|
||||
import com.lightyears.challenge.util.GetBeanUtil;
|
||||
import com.lightyears.challenge.util.StaticUtil;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ChallengeCacheRefreshTask implements Runnable{
|
||||
@Override
|
||||
public void run() {
|
||||
ChallengeDataInit challengeDataInit = (ChallengeDataInit) GetBeanUtil.getBean(ChallengeDataInit.class);
|
||||
IListBaseService listBaseService = (IListBaseService)GetBeanUtil.getBean("listBaseServiceImpl");
|
||||
DynamicCornTask dynamicCornTask = (DynamicCornTask) GetBeanUtil.getBean(DynamicCornTask.class);
|
||||
// 刷新挑战榜数据
|
||||
challengeDataInit.refreshData();
|
||||
// 开启下一周期的任务
|
||||
List<ListBase> listBases = listBaseService.list();
|
||||
if(!CollectionUtils.isEmpty(listBases)){
|
||||
ListBase listBase = listBases.get(0);
|
||||
// 锁榜 结束日 晚上11:00
|
||||
DateTime lockDate = DateUtil.offsetDay(DateUtil.parse(listBase.getInitDate().concat(StaticUtil.LOCKE_TIME)), listBase.getSettlementDay() - 1);
|
||||
// 结算 结束日 晚上11:45
|
||||
DateTime settlementDate = DateUtil.offsetDay(DateUtil.parse(listBase.getInitDate().concat(StaticUtil.SETTLEMENT_TIME)), listBase.getSettlementDay());
|
||||
// 初始化 结束日第二天 早上1:00
|
||||
DateTime initDate = DateUtil.offsetDay(DateUtil.parse(listBase.getInitDate().concat(StaticUtil.CHALLENGE_INIT_TIME)), listBase.getSettlementDay() + 1);
|
||||
// 缓存刷新 结束日第二天 早上1:00
|
||||
DateTime refreshDate = DateUtil.offsetDay(DateUtil.parse(listBase.getInitDate().concat(StaticUtil.CHALLENGE_REFRESH_TIME)), listBase.getSettlementDay() + 1);
|
||||
for (ListBase base : listBases) {
|
||||
// 修改初始化日期
|
||||
base.setInitDate(initDate.toDateStr());
|
||||
}
|
||||
// 重置定时任务
|
||||
dynamicCornTask.resetChallengeTask(lockDate, settlementDate, initDate, refreshDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.lightyears.challenge.schedule;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.lightyears.common.domain.entity.ListInstance;
|
||||
import com.lightyears.challenge.service.IListInstanceService;
|
||||
import com.lightyears.challenge.util.GetBeanUtil;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class ChallengeLockTask implements Runnable{
|
||||
@Override
|
||||
@Transactional
|
||||
public void run() {
|
||||
IListInstanceService listInstanceService = (IListInstanceService) GetBeanUtil.getBean("listInstanceServiceImpl");
|
||||
// 查询开启中的挑战榜实例
|
||||
List<ListInstance> listInstances = listInstanceService.list(new QueryWrapper<ListInstance>().eq("status", 1));
|
||||
// 结算每个实例榜单
|
||||
listInstances.stream().forEach(listInstance ->{
|
||||
// 结算日期
|
||||
listInstance.setSettlementDate(new Date());
|
||||
// 已截止,待结算
|
||||
listInstance.setStatus(3);
|
||||
// 修改实例榜信息
|
||||
listInstanceService.updateById(listInstance);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.lightyears.challenge.schedule;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.lightyears.challenge.service.*;
|
||||
import com.lightyears.common.domain.dto.ListRankDto;
|
||||
import com.lightyears.common.domain.entity.ListBase;
|
||||
import com.lightyears.common.domain.entity.ListInstance;
|
||||
import com.lightyears.common.domain.entity.Notice;
|
||||
import com.lightyears.common.domain.enums.AssetsTypeEnum;
|
||||
import com.lightyears.challenge.util.GetBeanUtil;
|
||||
import com.lightyears.challenge.util.RedisCache;
|
||||
import com.lightyears.challenge.util.StaticUtil;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class ChallengeSettlementTask implements Runnable{
|
||||
@Override
|
||||
@Transactional
|
||||
public void run() {
|
||||
IListBaseService listBaseService = (IListBaseService)GetBeanUtil.getBean("listBaseServiceImpl");
|
||||
IListInstanceService listInstanceService = (IListInstanceService) GetBeanUtil.getBean("listInstanceServiceImpl");
|
||||
IListRankService listRankService = (IListRankService) GetBeanUtil.getBean("listRankServiceImpl");
|
||||
IGameSystemService gameSystemService = (IGameSystemService)GetBeanUtil.getBean("gameSystemServiceImpl");
|
||||
INoticeService noticeService = (INoticeService) GetBeanUtil.getBean("noticeServiceImpl");
|
||||
RedisCache redisCache = (RedisCache)GetBeanUtil.getBean("redisCache");
|
||||
// 查询待结算的挑战榜实例
|
||||
List<ListInstance> listInstances = listInstanceService.list(new QueryWrapper<ListInstance>().eq("status", 3));
|
||||
// 结算每个实例榜单
|
||||
listInstances.stream().forEach(listInstance -> {
|
||||
BigDecimal awardSize = new BigDecimal(listInstance.getAwardSize());
|
||||
String[] distribution = ObjectUtils.isEmpty(listInstance.getDistribution()) || listInstance.getDistribution().length() < listInstance.getMaxPlayerNum() ? defaultDistribution(listInstance.getMaxPlayerNum()) : listInstance.getDistribution().split(",");
|
||||
List<ListRankDto> ranks = listRankService.getRankList(listInstance.getId());
|
||||
BigDecimal hundred = new BigDecimal(100);
|
||||
for (int i = 0; i < ranks.size(); i++) {
|
||||
ListRankDto rank = ranks.get(i);
|
||||
if (!ObjectUtils.isEmpty(rank.getPlayerId())){
|
||||
BigDecimal distributionNum = new BigDecimal(distribution[i]).divide(hundred);
|
||||
Integer bonus = awardSize.multiply(distributionNum).setScale(0, BigDecimal.ROUND_HALF_DOWN).intValue();
|
||||
if (bonus > 0){
|
||||
// 排名玩家奖励发放
|
||||
gameSystemService.pushGold(rank.getPlayerId(), bonus, listInstance.getAssetsType(), String.format(StaticUtil.CHALLENGE_REMARK, listInstance.getName(), rank.getRankNum(), bonus, AssetsTypeEnum.getNameById(listInstance.getAssetsType())));
|
||||
// 奖励通知写入
|
||||
Notice notice = new Notice().builder()
|
||||
.playerId(rank.getPlayerId())
|
||||
.status(0)
|
||||
.type(1)
|
||||
.createDate(new Date())
|
||||
.title(StaticUtil.CHALLENGE_NOTICE_TITLE)
|
||||
.content(String.format(StaticUtil.CHALLENGE_REMARK, listInstance.getName(), rank.getRankNum(), bonus, AssetsTypeEnum.getNameById(listInstance.getAssetsType()))).build();
|
||||
noticeService.save(notice);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 结算日期
|
||||
listInstance.setSettlementDate(new Date());
|
||||
// 已截止
|
||||
listInstance.setStatus(2);
|
||||
// 修改实例榜信息
|
||||
listInstanceService.updateById(listInstance);
|
||||
// 删除这次挑战榜所有缓存
|
||||
redisCache.deleteByPrefix(StaticUtil.CHALLENGE);
|
||||
// 修改初始化时间
|
||||
listBaseService.update(new LambdaUpdateWrapper<ListBase>().set(ListBase::getInitDate, DateUtil.today()).eq(ListBase::getId, listInstance.getListId()));
|
||||
});
|
||||
}
|
||||
private String[] defaultDistribution(Integer maxNum) {
|
||||
List<String> arr = new ArrayList<>();
|
||||
for (int i = 0; i < maxNum; i++) {
|
||||
arr.add(calc(i, 0, 100, maxNum).intValue() + "");
|
||||
}
|
||||
return arr.toArray(new String[]{});
|
||||
}
|
||||
/**
|
||||
* @param curtime
|
||||
* @param begin
|
||||
* @param end
|
||||
* @param duration
|
||||
* @return
|
||||
*/
|
||||
private Float controlWeightRote(Integer curtime, Integer begin, Integer end, Integer duration) {
|
||||
return (curtime == 0) ? begin * 1.0F : end * (curtime / duration - 1) + begin;
|
||||
}
|
||||
|
||||
private Float calc(Integer curtime, Integer begin, Integer end, Integer duration) {
|
||||
return controlWeightRote(curtime, begin, end, duration) - controlWeightRote(curtime - 1, begin, end, duration);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package com.lightyears.challenge.schedule;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import com.lightyears.challenge.util.CronUtils;
|
||||
import com.lightyears.challenge.util.ScheduledFutureHolder;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
import org.springframework.scheduling.support.CronTrigger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
|
||||
public class DynamicCornTask {
|
||||
private final ThreadPoolTaskScheduler threadPoolTaskScheduler;
|
||||
//存储任务执行的包装类
|
||||
private HashMap<String, ScheduledFutureHolder> scheduleMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
*启动任务
|
||||
* 如果不想手动触发任务可以使用 @PostConstruct注解来启动
|
||||
*/
|
||||
public void startTask(Runnable task, String corn) {
|
||||
try {
|
||||
//将任务交给任务调度器执行
|
||||
ScheduledFuture<?> schedule = threadPoolTaskScheduler.schedule(task, new CronTrigger(corn));
|
||||
|
||||
//将任务包装成ScheduledFutureHolder
|
||||
ScheduledFutureHolder scheduledFutureHolder = new ScheduledFutureHolder();
|
||||
scheduledFutureHolder.setScheduledFuture(schedule);
|
||||
scheduledFutureHolder.setRunnableClass(task.getClass());
|
||||
scheduledFutureHolder.setCorn(corn);
|
||||
|
||||
scheduleMap.put(task.getClass().getName(),scheduledFutureHolder);
|
||||
log.info("定时任务启动成功:".concat(task.getClass().getName()));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有的任务
|
||||
*/
|
||||
public void queryTask(){
|
||||
scheduleMap.forEach((k,v)->{
|
||||
System.out.println(k+" "+v);
|
||||
System.out.println(v.getCorn());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止任务
|
||||
* @param className
|
||||
*/
|
||||
public void stopTask(String className){
|
||||
if(scheduleMap.containsKey(className)){//如果包含这个任务
|
||||
ScheduledFuture<?> scheduledFuture = scheduleMap.get(className).getScheduledFuture();
|
||||
if(scheduledFuture!=null){
|
||||
scheduledFuture.cancel(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 重启任务,修改任务的触发时间
|
||||
* @param className
|
||||
* @throws InstantiationException
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
public void restartTask(String className, String corn){
|
||||
if(scheduleMap.containsKey(className)){//如果包含这个任务
|
||||
|
||||
ScheduledFutureHolder scheduledFutureHolder = scheduleMap.get(className);
|
||||
ScheduledFuture<?> scheduledFuture = scheduledFutureHolder.getScheduledFuture();
|
||||
if(scheduledFuture!=null) {
|
||||
try {
|
||||
//先停掉任务
|
||||
scheduledFuture.cancel(true);
|
||||
|
||||
//修改触发时间重新启动任务
|
||||
Runnable runnable = null;
|
||||
|
||||
runnable = scheduledFutureHolder.getRunnableClass().newInstance();
|
||||
|
||||
ScheduledFuture<?> schedule = threadPoolTaskScheduler.schedule(runnable, new CronTrigger(corn));
|
||||
|
||||
scheduledFutureHolder.setScheduledFuture(schedule);
|
||||
scheduledFutureHolder.setCorn(corn);
|
||||
|
||||
scheduleMap.put(scheduledFutureHolder.getRunnableClass().getName(), scheduledFutureHolder);
|
||||
}catch(Exception e){
|
||||
log.error("定时任务重置失败:".concat(className));
|
||||
log.error("详细错误信息:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 挑战榜定时任务重启
|
||||
* @param lockDate 锁榜日期时间
|
||||
* @param settlementDate 结算日期时间
|
||||
* @param initDate 初始化新榜日期时间
|
||||
* @param refreshDate 缓存刷新时间
|
||||
*/
|
||||
public void resetChallengeTask(DateTime lockDate, DateTime settlementDate, DateTime initDate, DateTime refreshDate){
|
||||
restartTask(ChallengeLockTask.class.getName(), CronUtils.getCron(lockDate));
|
||||
restartTask(ChallengeSettlementTask.class.getName(), CronUtils.getCron(settlementDate));
|
||||
restartTask(InitChallengeTask.class.getName(), CronUtils.getCron(initDate));
|
||||
restartTask(ChallengeCacheRefreshTask.class.getName(), CronUtils.getCron(refreshDate));
|
||||
log.info("下次锁榜时间:".concat(lockDate.toString()));
|
||||
log.info("下次结算时间:".concat(settlementDate.toString()));
|
||||
log.info("下次初始化时间:".concat(initDate.toString()));
|
||||
log.info("下次刷新时间:".concat(refreshDate.toString()));
|
||||
log.info("挑战榜定时任务启动成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 挑战榜定时任务启动
|
||||
* @param lockDate 锁榜日期时间
|
||||
* @param settlementDate 结算日期时间
|
||||
* @param initDate 初始化新榜日期时间
|
||||
* @param refreshDate 缓存刷新时间
|
||||
*/
|
||||
public void initChallengeTask(DateTime lockDate, DateTime settlementDate, DateTime initDate, DateTime refreshDate){
|
||||
// 每5分钟刷新挑战实例的奖池
|
||||
startTask(new RefreshInstanceListTask(), "0 */1 * * * ?");
|
||||
startTask(new ChallengeLockTask(), CronUtils.getCron(lockDate));
|
||||
startTask(new ChallengeSettlementTask(), CronUtils.getCron(settlementDate));
|
||||
startTask(new InitChallengeTask(), CronUtils.getCron(initDate));
|
||||
startTask(new ChallengeCacheRefreshTask(), CronUtils.getCron(refreshDate));
|
||||
log.info("下次锁榜时间:".concat(lockDate.toString()));
|
||||
log.info("下次结算时间:".concat(settlementDate.toString()));
|
||||
log.info("下次初始化时间:".concat(initDate.toString()));
|
||||
log.info("下次刷新时间:".concat(refreshDate.toString()));
|
||||
log.info("挑战榜定时任务启动成功");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.lightyears.challenge.schedule;
|
||||
|
||||
import com.lightyears.challenge.service.IListBaseService;
|
||||
import com.lightyears.challenge.service.IListInstanceService;
|
||||
import com.lightyears.challenge.service.IListRankService;
|
||||
import com.lightyears.challenge.util.GetBeanUtil;
|
||||
import com.lightyears.common.domain.entity.ListBase;
|
||||
import com.lightyears.common.domain.entity.ListInstance;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class InitChallengeTask implements Runnable {
|
||||
@Override
|
||||
@Transactional
|
||||
public void run() {
|
||||
IListInstanceService listInstanceService = (IListInstanceService) GetBeanUtil.getBean("listInstanceServiceImpl");
|
||||
IListBaseService listBaseService = (IListBaseService)GetBeanUtil.getBean("listBaseServiceImpl");
|
||||
IListRankService listRankService = (IListRankService) GetBeanUtil.getBean("listRankServiceImpl");
|
||||
|
||||
List<ListBase> listBases = listBaseService.list();
|
||||
List<ListInstance> instances = new ArrayList<>();
|
||||
if(!CollectionUtils.isEmpty(listBases)){
|
||||
for (ListBase base : listBases) {
|
||||
ListInstance instance = listInstanceService.saveInstanceByBase(base);
|
||||
instances.add(instance);
|
||||
for (int i = 0; i < instance.getMaxPlayerNum(); i++) {
|
||||
listRankService.saveRankByInstance(instance.getId(), i+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.lightyears.challenge.schedule;
|
||||
|
||||
import com.lightyears.challenge.init.ChallengeDataInit;
|
||||
import com.lightyears.challenge.util.GetBeanUtil;
|
||||
|
||||
public class RefreshInstanceListTask implements Runnable{
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ChallengeDataInit challengeDataInit = (ChallengeDataInit) GetBeanUtil.getBean("challengeDataInit");
|
||||
challengeDataInit.initInstance();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.lightyears.challenge.service;
|
||||
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
|
||||
public interface IChallengeService {
|
||||
ResModeBase getList();
|
||||
ResModeBase rankList(Integer pageIndex, Integer pageSize, Integer id);
|
||||
ResModeBase challengeDataSubmit(Integer instanceId, Integer rank, String gameData, Integer challengeTime, Integer ownerId, Integer myId, String myName);
|
||||
ResModeBase playerAssert(Integer playerId);
|
||||
ResModeBase admissionTicket(Integer instanceId, Integer rank, Integer gold, Integer type, String remark, Integer playerId);
|
||||
ResModeBase getPlayerRankInfo(Integer instanceId, Integer playerId);
|
||||
void clearRankByInstancePlayerId(Integer instanceId, Integer playerId, Integer rankNum);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.lightyears.challenge.service;
|
||||
|
||||
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
|
||||
public interface IGameSystemService {
|
||||
|
||||
ResModeBase pushGold(Integer userId, int gold, int type, String remark);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lightyears.challenge.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.lightyears.common.domain.entity.ListBase;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-16
|
||||
*/
|
||||
public interface IListBaseService extends IService<ListBase> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.lightyears.challenge.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.lightyears.common.domain.entity.ListBase;
|
||||
import com.lightyears.common.domain.entity.ListInstance;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-16
|
||||
*/
|
||||
public interface IListInstanceService extends IService<ListInstance> {
|
||||
|
||||
ListInstance saveInstanceByBase(ListBase base);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.lightyears.challenge.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.lightyears.common.domain.dto.ListRankDto;
|
||||
import com.lightyears.common.domain.entity.ListRank;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-16
|
||||
*/
|
||||
public interface IListRankService extends IService<ListRank> {
|
||||
ListRank saveRankByInstance(Integer instanceId, Integer rank);
|
||||
int initRank(Integer instanceId,Integer playerId);
|
||||
int updateRankInfo(Integer instanceId, Integer rank, String gameData, Integer challengeTime, Integer playerId, String playerName);
|
||||
ListRankDto getRankByInsRank(Integer instanceId, Integer rank);
|
||||
List<ListRankDto> getRankList(Integer instanceId);
|
||||
List<ListRankDto> getPlayerRankInfo(Integer instanceId, Integer playerId);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.lightyears.challenge.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.lightyears.common.domain.entity.Log;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 游戏 完成记录 表 游戏难度:1 - 普通 2 困难 3 大师 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-09
|
||||
*/
|
||||
public interface ILogService extends IService<Log> {
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lightyears.challenge.service;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.lightyears.common.domain.entity.Notice;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-18
|
||||
*/
|
||||
public interface INoticeService extends IService<Notice> {
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.lightyears.challenge.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.lightyears.common.domain.dto.SimplePlayerAssert;
|
||||
import com.lightyears.common.domain.entity.PlayerAssets;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-16
|
||||
*/
|
||||
public interface IPlayerAssetsService extends IService<PlayerAssets> {
|
||||
/**
|
||||
* 添加金币
|
||||
* @param id id
|
||||
* @param gold 增加后的金币
|
||||
*/
|
||||
Integer addGold(int id, int gold);
|
||||
|
||||
/**
|
||||
* 扣除金币
|
||||
* @param id id
|
||||
* @param gold 需要扣减的金币
|
||||
*/
|
||||
Integer reduceGold(int id, int gold);
|
||||
|
||||
List<SimplePlayerAssert> getPlayerAssets(int playerId);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lightyears.challenge.service;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.lightyears.common.domain.entity.Player;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 扫雷玩家表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-09
|
||||
*/
|
||||
public interface IPlayerService extends IService<Player> {
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.lightyears.challenge.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.lightyears.common.domain.entity.Record;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 游戏存档 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-09
|
||||
*/
|
||||
public interface IRecordService extends IService<Record> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
package com.lightyears.challenge.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.lightyears.challenge.dao.AssertLogMapper;
|
||||
import com.lightyears.challenge.dao.ListInstanceMapper;
|
||||
import com.lightyears.common.domain.dto.*;
|
||||
import com.lightyears.common.domain.entity.AssertLog;
|
||||
import com.lightyears.common.domain.entity.ListInstance;
|
||||
import com.lightyears.common.domain.entity.PlayerAssets;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import com.lightyears.challenge.init.ChallengeDataInit;
|
||||
import com.lightyears.challenge.service.IChallengeService;
|
||||
import com.lightyears.challenge.service.IListRankService;
|
||||
import com.lightyears.challenge.service.IPlayerAssetsService;
|
||||
import com.lightyears.challenge.util.RedisCache;
|
||||
import com.lightyears.challenge.util.ResultUtil;
|
||||
import com.lightyears.challenge.util.StaticUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.client.producer.SendCallback;
|
||||
import org.apache.rocketmq.client.producer.SendResult;
|
||||
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@Validated
|
||||
@Service("challengeServiceImpl")
|
||||
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
|
||||
public class ChallengeServiceImpl implements IChallengeService {
|
||||
|
||||
private final RedisCache redisCache;
|
||||
private final ListInstanceMapper listInstanceMapper;
|
||||
private final IListRankService listRankServiceImpl;
|
||||
private final ChallengeDataInit challengeDataInit;
|
||||
private final RocketMQTemplate rocketMQTemplate;
|
||||
private final AssertLogMapper assertLogMapper;
|
||||
private final IPlayerAssetsService playerAssetsService;
|
||||
|
||||
@Override
|
||||
public ResModeBase getList() {
|
||||
List<ListInstanceDto> dtos = this.redisCache.getCacheObject(StaticUtil.CHALLENGE_INSTANCE);
|
||||
if(CollectionUtils.isEmpty(dtos)) {
|
||||
// 如果缓存无,查询数据库
|
||||
dtos = challengeDataInit.initInstance();
|
||||
}
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), dtos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResModeBase rankList(Integer pageIndex, Integer pageSize, Integer id) {
|
||||
Long total = redisCache.lGetListSize(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL.concat(id.toString()));
|
||||
// 计算当前需要显示的数据下标起始值
|
||||
int startIndex = (pageIndex - 1) * pageSize;
|
||||
int endIndex = Math.min(startIndex + pageSize,total.intValue()) - 1;
|
||||
// 缓存中读取对应实例榜的排名数据
|
||||
List<Object> objectList = redisCache.lGet(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL.concat(id.toString()), startIndex, endIndex);
|
||||
List<ListRankDto> listRankDtos = new ArrayList<>();
|
||||
objectList.stream().forEach(item -> {
|
||||
String json = JSONObject.toJSONString(item) ;
|
||||
listRankDtos.add(JSON.parseObject(json, ListRankDto.class));
|
||||
});
|
||||
if (CollectionUtils.isEmpty(listRankDtos)) {
|
||||
return ResultUtil.result(MessageEnum.ADD_ERROR.getCode(), "暂无该排行排名数据");
|
||||
}
|
||||
// 创建Page类
|
||||
Page page = new Page(pageIndex, pageSize);
|
||||
// 为Page类中的total属性赋值
|
||||
page.setTotal(total);
|
||||
// 从链表中截取需要显示的子链表,并加入到Page
|
||||
page.addAll(listRankDtos);
|
||||
// 以Page创建PageInfo
|
||||
PageInfo<ListRankDto> pageInfo = new PageInfo<ListRankDto>(page);
|
||||
pageInfo.getList().stream().forEach(rankDto -> {
|
||||
rankDto.setGameData(null);
|
||||
});
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), pageInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ResModeBase challengeDataSubmit(Integer instanceId, Integer rank, String gameData, Integer challengeTime, Integer ownerId, Integer myId, String myName){
|
||||
Integer code = 2;
|
||||
ListRankDto rankDto;
|
||||
ListInstance listInstance = listInstanceMapper.selectById(instanceId);
|
||||
// 挑战榜不存在或者挑战榜不为开启状态
|
||||
if (ObjectUtils.isEmpty(listInstance) || listInstance.getStatus() != 1){
|
||||
return ResultUtil.result(MessageEnum.ERROR.getCode(), "提交失败,挑战榜已关闭");
|
||||
}
|
||||
/**
|
||||
* TODO:
|
||||
* 1.获取指定榜单与名次的listRank
|
||||
* 2.比较对局时间判断是否挑战成功
|
||||
* (挑战成功则写入信息到挑战榜,返回1.挑战成功;
|
||||
* 挑战失败则判断挑战榜主id是否是原挑战榜主id,是则返回2.挑战失败;
|
||||
* 否则返回 3.已被其他人抢先挑战成功)
|
||||
*/
|
||||
// 获取指定榜单与名次的listRank
|
||||
Object obj = redisCache.lGetIndex(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL.concat(instanceId.toString()), rank-1);
|
||||
if(obj == null){
|
||||
rankDto= listRankServiceImpl.getRankByInsRank(instanceId, rank);
|
||||
if(ObjectUtils.isEmpty(rankDto)){
|
||||
log.error("未查询到挑战的排名信息");
|
||||
return ResultUtil.result(MessageEnum.ERROR.getCode(), "未查询到挑战的排名信息");
|
||||
}
|
||||
} else {
|
||||
String json = JSONObject.toJSONString(obj) ;
|
||||
rankDto = JSON.parseObject(json, ListRankDto.class);
|
||||
}
|
||||
if(rankDto.getChallengeTime() == null || challengeTime < rankDto.getChallengeTime()){
|
||||
RankDataDto rankDataDto = RankDataDto.builder().rankDto(rankDto).instanceId(instanceId).rankNum(rank).gameData(gameData).challengeTime(challengeTime).myId(myId).myName(myName).build();
|
||||
code = 1;
|
||||
SendCallback callback = new SendCallback() {
|
||||
@Override
|
||||
public void onSuccess(SendResult sendResult) {
|
||||
log.info("消息已成功发送");
|
||||
}
|
||||
@Override
|
||||
public void onException(Throwable throwable) {
|
||||
log.info("消息发送异常,发送失败");
|
||||
}
|
||||
};
|
||||
rocketMQTemplate.asyncSend("rankUpdate:submit",rankDataDto,callback);
|
||||
} else {
|
||||
// 挑战的榜主与现在的榜主是否是同一用户
|
||||
if (!rankDto.getPlayerId().equals(ownerId) && ownerId != -1) {
|
||||
code = 3;
|
||||
}
|
||||
}
|
||||
// 移除正在挑战的信息
|
||||
redisCache.deleteObject(StaticUtil.CHALLENGE_ONLINE_USER.concat(instanceId.toString()).concat(":".concat(rank.toString()).concat(":".concat(myId.toString()))));
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResModeBase admissionTicket(Integer instanceId, Integer rank, Integer gold, Integer type, String remark, Integer playerId) {
|
||||
ListInstance instance = listInstanceMapper.selectOne(new QueryWrapper<ListInstance>().eq("id", instanceId).eq("status", 1));
|
||||
if(ObjectUtils.isEmpty(instance)){
|
||||
log.error("未查询到挑战榜信息,挑战榜实例id:".concat(instanceId.toString()));
|
||||
return ResultUtil.result(MessageEnum.ERROR.getCode(), "挑战榜已关闭!");
|
||||
}
|
||||
Object obj = redisCache.lGetIndex(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL.concat(instanceId.toString()), rank-1);
|
||||
if(obj == null){
|
||||
log.error("未查询到挑战的排名信息");
|
||||
return ResultUtil.result(MessageEnum.ERROR.getCode(), "未查询到挑战的排名信息");
|
||||
}
|
||||
Long time = System.currentTimeMillis() / 1000;
|
||||
try{
|
||||
|
||||
PlayerAssets playerAssets = playerAssetsService.getOne(new LambdaQueryWrapper<PlayerAssets>().eq(PlayerAssets::getPlayerId, playerId).eq(PlayerAssets::getType, type).orderByDesc(PlayerAssets::getId).last("limit 1"));
|
||||
if(playerAssets == null){
|
||||
log.error("未查询到玩家资产信息,玩家id:".concat(playerId.toString()));
|
||||
return ResultUtil.result(MessageEnum.ERROR.getCode(), "玩家资产信息不存在!");
|
||||
}
|
||||
// 扣除玩家指定货币
|
||||
playerAssetsService.reduceGold(playerAssets.getId(), gold);
|
||||
//3 写入变化记录
|
||||
assertLogMapper.insert(AssertLog.builder().playerId(playerId).createDate(new Date()).assertChangeNum(-gold).assertType(type).remark(remark).build());
|
||||
|
||||
ListPoolChangeDto dto = ListPoolChangeDto.builder().rank(rank).userId(playerId).instanceId(instanceId).gold(gold).type(type).remark(remark).build();
|
||||
SendCallback callback = new SendCallback() {
|
||||
@Override
|
||||
public void onSuccess(SendResult sendResult) {
|
||||
log.info("消息已成功发送");
|
||||
}
|
||||
@Override
|
||||
public void onException(Throwable throwable) {
|
||||
log.error("发送异常", throwable);
|
||||
log.info("消息发送异常,发送失败");
|
||||
}
|
||||
};
|
||||
rocketMQTemplate.asyncSend("admissionTicket:submit",dto,callback);
|
||||
// 写入正在挑战的人 设置最长40分钟
|
||||
redisCache.setCacheObject(StaticUtil.CHALLENGE_ONLINE_USER.concat(instanceId.toString()).concat(":".concat(rank.toString()).concat(":".concat(playerId.toString()))), time.toString(), 40, TimeUnit.MINUTES);
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), "操作成功");
|
||||
}catch (Exception ex){
|
||||
log.error("报名失败,挑战扣费失败!", ex);
|
||||
return ResultUtil.result(MessageEnum.ERROR.getCode(), MessageEnum.SUCCESS.getMessage(), "报名失败,挑战扣费失败!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResModeBase playerAssert(Integer playerId) {
|
||||
List<SimplePlayerAssert> assets = playerAssetsService.getPlayerAssets(playerId);
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), assets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResModeBase getPlayerRankInfo(Integer instanceId, Integer playerId) {
|
||||
List<ListRankDto> dtos = listRankServiceImpl.getPlayerRankInfo(instanceId, playerId);
|
||||
ListRankDto dto = null;
|
||||
if (!CollectionUtils.isEmpty(dtos)){
|
||||
dto = dtos.get(0);
|
||||
dto.setGameData(null);
|
||||
}
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearRankByInstancePlayerId(Integer instanceId, Integer playerId, Integer rankNum){
|
||||
int i = listRankServiceImpl.initRank(instanceId, playerId);
|
||||
ListRankDto dto = redisCache.getCacheObject(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL.concat(instanceId.toString()).concat(":".concat(rankNum.toString())));
|
||||
if(dto != null && playerId == dto.getPlayerId()){
|
||||
dto.setChallengeTime(null);
|
||||
dto.setPlayerId(null);
|
||||
dto.setPlayerName(null);
|
||||
dto.setGameData(null);
|
||||
redisCache.setCacheObject(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL.concat(dto.getInstanceId().toString()).concat(":".concat(dto.getRankNum().toString())), dto);
|
||||
|
||||
}
|
||||
if(i > 0){
|
||||
// 刷新榜单
|
||||
challengeDataInit.initranks(instanceId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.lightyears.challenge.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.google.common.collect.Interner;
|
||||
import com.google.common.collect.Interners;
|
||||
import com.lightyears.challenge.dao.*;
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
import com.lightyears.common.domain.entity.AssertLog;
|
||||
import com.lightyears.common.domain.entity.PlayerAssets;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import com.lightyears.challenge.service.IGameSystemService;
|
||||
import com.lightyears.challenge.service.ILogService;
|
||||
import com.lightyears.challenge.service.IPlayerAssetsService;
|
||||
import com.lightyears.challenge.util.RedisCache;
|
||||
import com.lightyears.challenge.util.ResultUtil;
|
||||
import com.lightyears.challenge.util.StaticUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
@Slf4j
|
||||
@Service("gameSystemServiceImpl")
|
||||
public class GameSystemServiceImpl implements IGameSystemService {
|
||||
|
||||
@Resource
|
||||
private PlayerMapper playerMapper;
|
||||
@Resource
|
||||
private RecordMapper recordMapper;
|
||||
@Resource
|
||||
private ILogService logService;
|
||||
@Resource
|
||||
private RedisCache redisCache;
|
||||
@Resource
|
||||
private IPlayerAssetsService playerAssetsService;
|
||||
@Resource
|
||||
private AssertLogMapper assertLogMapper;
|
||||
@Resource
|
||||
private ListRankMapper listRankMapper;
|
||||
@Resource
|
||||
private NoticeMapper noticeMapper;
|
||||
@Resource
|
||||
private IGameSystemService gameSystemService;
|
||||
Interner<String> pool = Interners.newWeakInterner();
|
||||
private static final int AssetLimit = 999999;
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ResModeBase pushGold(Integer userId, int gold, int type, String remark) {
|
||||
//1. 查询金额, 设置资产上限
|
||||
PlayerAssets playerAssets = playerAssetsService.getOne(new QueryWrapper<PlayerAssets>().eq("player_id", userId).eq("type", type).last("limit 1"));
|
||||
Integer playerAssetsNumber = playerAssets == null? 0 : playerAssets.getNumber();
|
||||
int nowGold = Math.min(playerAssetsNumber +gold , AssetLimit);
|
||||
// 2.写入改变数量
|
||||
if (ObjectUtils.isEmpty(playerAssets)) {
|
||||
playerAssetsService.save(PlayerAssets.builder().playerId(userId).type(type).number(nowGold).version(0L).build());
|
||||
} else {
|
||||
playerAssetsService.addGold(playerAssets.getId(), nowGold - playerAssetsNumber);
|
||||
}
|
||||
//3 写入变化记录
|
||||
assertLogMapper.insert(AssertLog.builder().playerId(userId).createDate(new Date()).assertChangeNum(nowGold - playerAssetsNumber).assertType(type).remark(remark).build());
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), nowGold);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.lightyears.challenge.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.lightyears.challenge.dao.ListBaseMapper;
|
||||
import com.lightyears.common.domain.entity.ListBase;
|
||||
import com.lightyears.challenge.service.IListBaseService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-16
|
||||
*/
|
||||
@Service(value = "listBaseServiceImpl")
|
||||
public class ListBaseServiceImpl extends ServiceImpl<ListBaseMapper, ListBase> implements IListBaseService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.lightyears.challenge.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.lightyears.challenge.dao.ListInstanceMapper;
|
||||
import com.lightyears.common.domain.entity.ListBase;
|
||||
import com.lightyears.common.domain.entity.ListInstance;
|
||||
import com.lightyears.challenge.service.IListInstanceService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-16
|
||||
*/
|
||||
@Service(value = "listInstanceServiceImpl")
|
||||
public class ListInstanceServiceImpl extends ServiceImpl<ListInstanceMapper, ListInstance> implements IListInstanceService {
|
||||
|
||||
@Override
|
||||
public ListInstance saveInstanceByBase(ListBase base){
|
||||
String startDate = DateUtil.now();
|
||||
Date date = DateUtil.parse(startDate);
|
||||
// 7 周日锁榜 周一晚上结算
|
||||
DateTime endDate = DateUtil.offsetDay(date, base.getSettlementDay() - 1);
|
||||
String startDateStr = DateUtil.format(date, "yyyy-MM-dd");
|
||||
String endDateStr = DateUtil.format(endDate, "yyyy-MM-dd");
|
||||
ListInstance instance = ListInstance.builder().listId(base.getId())
|
||||
.listDate(startDateStr.concat("~".concat(endDateStr)))
|
||||
.ticketsNum(base.getTicketsNum())
|
||||
.assetsType(base.getAssetsType())
|
||||
.createDate(new Date())
|
||||
.mapSize(base.getMapSize())
|
||||
.status(1)
|
||||
.entryThreshold(base.getEntryThreshold())
|
||||
.awardSize(base.getInitAwardSize())
|
||||
.inPondFee(base.getInPondFee())
|
||||
.maxPlayerNum(base.getMaxPlayerNum())
|
||||
.mineNumSection(base.getMineNumSection())
|
||||
.name(base.getName())
|
||||
.distribution(base.getDistribution())
|
||||
.remark("系统自动生成").build();
|
||||
this.baseMapper.insert(instance);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.lightyears.challenge.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.lightyears.challenge.dao.ListRankMapper;
|
||||
import com.lightyears.common.domain.dto.ListRankDto;
|
||||
import com.lightyears.common.domain.entity.ListRank;
|
||||
import com.lightyears.challenge.service.IListRankService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-16
|
||||
*/
|
||||
@Service(value = "listRankServiceImpl")
|
||||
public class ListRankServiceImpl extends ServiceImpl<ListRankMapper, ListRank> implements IListRankService {
|
||||
|
||||
@Resource
|
||||
private ListRankMapper listRankMapper;
|
||||
|
||||
@Override
|
||||
public ListRank saveRankByInstance(Integer instanceId, Integer rank){
|
||||
ListRank data = ListRank.builder().rankNum(rank).instanceId(instanceId).createDate(new Date()).build();
|
||||
listRankMapper.insert(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int initRank(Integer instanceId,Integer playerId){
|
||||
int num = listRankMapper.initRank(instanceId, playerId);
|
||||
return num;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public int updateRankInfo(Integer instanceId, Integer rank, String gameData, Integer challengeTime, Integer playerId, String playerName) {
|
||||
ListRank rankInfo = ListRank.builder().instanceId(instanceId).rankNum(rank).gameData(gameData).challengeTime(challengeTime).playerId(playerId).playerName(playerName).updateDate(new Date()).build();
|
||||
return listRankMapper.update(rankInfo, new UpdateWrapper<ListRank>().eq("instance_id", instanceId).eq("rank_num", rank));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListRankDto getRankByInsRank(Integer instanceId, Integer rank){
|
||||
return listRankMapper.getRankByInsRank(instanceId, rank);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ListRankDto> getRankList(Integer instanceId) {
|
||||
return listRankMapper.getRankList(instanceId, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ListRankDto> getPlayerRankInfo(Integer instanceId, Integer playerId){
|
||||
// 只查开启中挑战榜的数据
|
||||
List<ListRankDto> dtos = listRankMapper.getNewRankList(instanceId, playerId);
|
||||
return dtos;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.lightyears.challenge.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.lightyears.challenge.dao.LogMapper;
|
||||
import com.lightyears.common.domain.entity.Log;
|
||||
import com.lightyears.challenge.service.ILogService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 游戏 完成记录 表 游戏难度:1 - 普通 2 困难 3 大师 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-09
|
||||
*/
|
||||
@Service
|
||||
public class LogServiceImpl extends ServiceImpl<LogMapper, Log> implements ILogService {
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.lightyears.challenge.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.lightyears.challenge.dao.NoticeMapper;
|
||||
import com.lightyears.common.domain.entity.Notice;
|
||||
import com.lightyears.challenge.service.INoticeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-18
|
||||
*/
|
||||
@Service(value = "noticeServiceImpl")
|
||||
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements INoticeService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.lightyears.challenge.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.lightyears.challenge.dao.PlayerAssetsMapper;
|
||||
import com.lightyears.common.domain.dto.SimplePlayerAssert;
|
||||
import com.lightyears.common.domain.entity.PlayerAssets;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import com.lightyears.challenge.exception.BussinessException;
|
||||
import com.lightyears.challenge.service.IPlayerAssetsService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-16
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class PlayerAssetsServiceImpl extends ServiceImpl<PlayerAssetsMapper, PlayerAssets> implements IPlayerAssetsService {
|
||||
|
||||
@Override
|
||||
public Integer addGold(int id, int gold){
|
||||
PlayerAssets playerAssets = baseMapper.selectById(id);
|
||||
if(ObjectUtils.isEmpty(playerAssets)){
|
||||
log.error("减少金币异常------------没有查到资产信息");
|
||||
throw new BussinessException(MessageEnum.ERROR.getCode(), "减少金币异常------------没有查到资产信息!");
|
||||
}
|
||||
int result = 0;
|
||||
try{
|
||||
result = baseMapper.addGold(playerAssets.getId(), gold, playerAssets.getVersion());
|
||||
}catch (Exception ex){
|
||||
log.error("写入金币异常", ex);
|
||||
throw new BussinessException(MessageEnum.ERROR.getCode(), "写入金币异常!");
|
||||
}
|
||||
|
||||
if(result < 1){
|
||||
this.addGold(id, gold);
|
||||
}
|
||||
return gold;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer reduceGold(int id, int gold){
|
||||
PlayerAssets playerAssets = baseMapper.selectById(id);
|
||||
if(ObjectUtils.isEmpty(playerAssets)){
|
||||
log.error("减少金币异常------------没有查到资产信息");
|
||||
throw new BussinessException(MessageEnum.ERROR.getCode(), "减少金币异常------------没有查到资产信息!");
|
||||
}
|
||||
int result = 0;
|
||||
if(playerAssets.getNumber() < gold){
|
||||
return -999;
|
||||
}
|
||||
try {
|
||||
result = baseMapper.reduceGold(playerAssets.getId(), gold, playerAssets.getVersion());
|
||||
} catch (Exception ex){
|
||||
log.error("写入金币异常", ex);
|
||||
throw new BussinessException(MessageEnum.ERROR.getCode(), "写入金币异常!");
|
||||
}
|
||||
if(result < 1){
|
||||
this.reduceGold(id, gold);
|
||||
}
|
||||
return playerAssets.getNumber() - gold;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SimplePlayerAssert> getPlayerAssets(int playerId){
|
||||
return baseMapper.getPlayerAssets(playerId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.lightyears.challenge.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.lightyears.challenge.dao.PlayerMapper;
|
||||
import com.lightyears.challenge.service.IPlayerService;
|
||||
import com.lightyears.common.domain.entity.Player;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 扫雷玩家表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-09
|
||||
*/
|
||||
@Service
|
||||
public class PlayerServiceImpl extends ServiceImpl<PlayerMapper, Player> implements IPlayerService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.lightyears.challenge.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.lightyears.challenge.dao.RecordMapper;
|
||||
import com.lightyears.common.domain.entity.Record;
|
||||
import com.lightyears.challenge.service.IRecordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 游戏存档 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-09
|
||||
*/
|
||||
@Service
|
||||
public class RecordServiceImpl extends ServiceImpl<RecordMapper, Record> implements IRecordService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.lightyears.challenge.util;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 日期转换cron表达式
|
||||
*/
|
||||
public class CronUtils {
|
||||
|
||||
/***
|
||||
* 功能描述:日期转换cron表达式
|
||||
* @param dateStr
|
||||
* @return
|
||||
*/
|
||||
public static String formatDateByPattern(String dateStr) {
|
||||
String formatTimeStr = null;
|
||||
if (Objects.nonNull(dateStr)) {
|
||||
LocalDateTime time = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
formatTimeStr = time.format(DateTimeFormatter.ofPattern("ss mm HH dd MM ?"));
|
||||
}
|
||||
return formatTimeStr;
|
||||
}
|
||||
|
||||
/***
|
||||
* @param dateTime : 时间点
|
||||
* @return
|
||||
*/
|
||||
public static String getCron(DateTime dateTime) {
|
||||
return formatDateByPattern(dateTime.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.lightyears.challenge.util;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class GetBeanUtil implements ApplicationContextAware {
|
||||
private static ApplicationContext applicationContext;
|
||||
|
||||
public void setApplicationContext(ApplicationContext context) {
|
||||
GetBeanUtil.applicationContext = context;
|
||||
}
|
||||
|
||||
public static Object getBean(String name) {
|
||||
return applicationContext.getBean(name);
|
||||
}
|
||||
|
||||
public static Object getBean(Class classObj) {
|
||||
return applicationContext.getBean(classObj);
|
||||
}
|
||||
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return applicationContext;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.lightyears.challenge.util;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
/**
|
||||
* Created by tanhao on 2019/3/18.
|
||||
*/
|
||||
public class MD5Utils {
|
||||
private static final String hexDigIts[] = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
|
||||
|
||||
/**
|
||||
* MD5加密
|
||||
* @param origin 字符
|
||||
* @param charsetname 编码 UTF-8
|
||||
* @return
|
||||
*/
|
||||
public static String MD5Encode(String origin, String charsetname){
|
||||
String resultString = null;
|
||||
try{
|
||||
resultString = new String(origin);
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
if(null == charsetname || "".equals(charsetname)){
|
||||
resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
|
||||
}else{
|
||||
resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
|
||||
}
|
||||
}catch (Exception e){
|
||||
}
|
||||
return resultString;
|
||||
}
|
||||
|
||||
|
||||
public static String byteArrayToHexString(byte b[]){
|
||||
StringBuffer resultSb = new StringBuffer();
|
||||
for(int i = 0; i < b.length; i++){
|
||||
resultSb.append(byteToHexString(b[i]));
|
||||
}
|
||||
return resultSb.toString();
|
||||
}
|
||||
|
||||
public static String byteToHexString(byte b){
|
||||
int n = b;
|
||||
if(n < 0){
|
||||
n += 256;
|
||||
}
|
||||
int d1 = n / 16;
|
||||
int d2 = n % 16;
|
||||
return hexDigIts[d1] + hexDigIts[d2];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,383 @@
|
||||
package com.lightyears.challenge.util;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.HashOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.core.ValueOperations;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* spring redis 工具类
|
||||
**/
|
||||
@Component
|
||||
public class RedisCache {
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate redisTemplate;
|
||||
@Autowired
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
/**
|
||||
* 判断key是否存在
|
||||
* @param key 键
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean hasKey(String key) {
|
||||
try {
|
||||
return redisTemplate.hasKey(key);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存基本的对象,Integer、String、实体类等
|
||||
*
|
||||
* @param key 缓存的键值
|
||||
* @param value 缓存的值
|
||||
*/
|
||||
public <T> void setCacheObject(final String key, final T value) {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存基本的对象,Integer、String、实体类等
|
||||
*
|
||||
* @param key 缓存的键值
|
||||
* @param value 缓存的值
|
||||
* @param timeout 时间
|
||||
* @param timeUnit 时间颗粒度
|
||||
*/
|
||||
public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
|
||||
redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置有效时间
|
||||
*
|
||||
* @param key Redis键
|
||||
* @param timeout 超时时间
|
||||
* @return true=设置成功;false=设置失败
|
||||
*/
|
||||
public boolean expire(final String key, final long timeout) {
|
||||
return expire(key, timeout, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置有效时间
|
||||
*
|
||||
* @param key Redis键
|
||||
* @param timeout 超时时间
|
||||
* @param unit 时间单位
|
||||
* @return true=设置成功;false=设置失败
|
||||
*/
|
||||
public boolean expire(final String key, final long timeout, final TimeUnit unit) {
|
||||
return redisTemplate.expire(key, timeout, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得缓存的基本对象。
|
||||
*
|
||||
* @param key 缓存键值
|
||||
* @return 缓存键值对应的数据
|
||||
*/
|
||||
public <T> T getCacheObject(final String key) {
|
||||
ValueOperations<String, T> operation = redisTemplate.opsForValue();
|
||||
return operation.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单个对象
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
public boolean deleteObject(final String key) {
|
||||
return redisTemplate.delete(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定前缀的缓存
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public Long deleteByPrefix(final String key) {
|
||||
Set<String> keys = redisTemplate.keys(key.concat("*"));
|
||||
return redisTemplate.delete(keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除集合对象
|
||||
*
|
||||
* @param collection 多个对象
|
||||
* @return
|
||||
*/
|
||||
public long deleteObject(final Collection collection) {
|
||||
return redisTemplate.delete(collection);
|
||||
}
|
||||
|
||||
// ===============================list=================================
|
||||
|
||||
/**
|
||||
* 获取list缓存的内容
|
||||
*
|
||||
* @param key 键
|
||||
* @param start 开始
|
||||
* @param end 结束 0 到 -1代表所有值
|
||||
* @return
|
||||
*/
|
||||
public List<Object> lGet(String key, long start, long end) {
|
||||
try {
|
||||
return redisTemplate.opsForList().range(key, start, end);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取list缓存的长度
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public long lGetListSize(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForList().size(key);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过索引 获取list中的值
|
||||
*
|
||||
* @param key 键
|
||||
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
|
||||
* @return
|
||||
*/
|
||||
public Object lGetIndex(String key, long index) {
|
||||
try {
|
||||
return redisTemplate.opsForList().index(key, index);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPush(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, Object value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPush(key, value);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lSetAll(String key, List<? extends Object> value) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPushAll(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, List<Object> value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPushAll(key, value);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据索引修改list中的某条数据
|
||||
*
|
||||
* @param key 键
|
||||
* @param index 索引
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lUpdateIndex(String key, long index, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForList().set(key, index, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除N个值为value
|
||||
*
|
||||
* @param key 键
|
||||
* @param count 移除多少个
|
||||
* @param value 值
|
||||
* @return 移除的个数
|
||||
*/
|
||||
public long lRemove(String key, long count, Object value) {
|
||||
try {
|
||||
Long remove = redisTemplate.opsForList().remove(key, count, value);
|
||||
return remove;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存Set
|
||||
*
|
||||
* @param key 缓存键值
|
||||
* @param dataSet 缓存的数据
|
||||
* @return 缓存数据的对象
|
||||
*/
|
||||
public <T> long setCacheSet(final String key, final Set<T> dataSet) {
|
||||
Long count = redisTemplate.opsForSet().add(key, dataSet);
|
||||
return count == null ? 0 : count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得缓存的set
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public <T> Set<T> getCacheSet(final String key) {
|
||||
return redisTemplate.opsForSet().members(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存Map
|
||||
*
|
||||
* @param key
|
||||
* @param dataMap
|
||||
*/
|
||||
public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
|
||||
if (dataMap != null) {
|
||||
redisTemplate.opsForHash().putAll(key, dataMap);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得缓存的Map
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public <T> Map<String, T> getCacheMap(final String key) {
|
||||
return redisTemplate.opsForHash().entries(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 往Hash中存入数据
|
||||
*
|
||||
* @param key Redis键
|
||||
* @param hKey Hash键
|
||||
* @param value 值
|
||||
*/
|
||||
public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
|
||||
redisTemplate.opsForHash().put(key, hKey, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Hash中的数据
|
||||
*
|
||||
* @param key Redis键
|
||||
* @param hKey Hash键
|
||||
* @return Hash中的对象
|
||||
*/
|
||||
public <T> T getCacheMapValue(final String key, final String hKey) {
|
||||
HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
|
||||
return opsForHash.get(key, hKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取多个Hash中的数据
|
||||
*
|
||||
* @param key Redis键
|
||||
* @param hKeys Hash键集合
|
||||
* @return Hash对象集合
|
||||
*/
|
||||
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
|
||||
return redisTemplate.opsForHash().multiGet(key, hKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得缓存的基本对象列表
|
||||
*
|
||||
* @param pattern 字符串前缀
|
||||
* @return 对象列表
|
||||
*/
|
||||
public Collection<String> keys(final String pattern) {
|
||||
return redisTemplate.keys(pattern);
|
||||
}
|
||||
|
||||
public StringRedisTemplate getStringRedisTemplate() {
|
||||
return stringRedisTemplate;
|
||||
}
|
||||
|
||||
public RedisTemplate getRedisTemplate() {
|
||||
return redisTemplate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.lightyears.challenge.util;
|
||||
|
||||
import cn.hutool.crypto.digest.MD5;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 返回 数据 指定数据结构
|
||||
*
|
||||
* @author Melody
|
||||
*/
|
||||
@Slf4j
|
||||
public class ResultUtil {
|
||||
public static final ObjectMapper mapper = new ObjectMapper();
|
||||
public static ResModeBase result(int code, String mes) {
|
||||
return result(code, mes, null);
|
||||
}
|
||||
|
||||
public static ResModeBase result(int code, String mes, Object data) {
|
||||
String key = "";
|
||||
String dataStr = "";
|
||||
if(data == null){
|
||||
key = MD5.create().digestHex(MD5.create().digestHex(StaticUtil.PRIVATE_KEY));
|
||||
} else {
|
||||
try {
|
||||
if (data instanceof String){
|
||||
dataStr = data.toString();
|
||||
} else {
|
||||
dataStr = mapper.writeValueAsString(data);
|
||||
}
|
||||
key = MD5.create().digestHex(MD5.create().digestHex(dataStr.concat(StaticUtil.PRIVATE_KEY)));
|
||||
}catch (JsonProcessingException ex){
|
||||
log.error("json解析错误", ex);
|
||||
return new ResModeBase(MessageEnum.SERVER_ERROR.getCode(), MessageEnum.SERVER_ERROR.getMessage(), key, null);
|
||||
}
|
||||
|
||||
}
|
||||
return new ResModeBase(code, mes, key, data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.lightyears.challenge.util;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
/**
|
||||
* 任务执行的包装类
|
||||
*/
|
||||
public class ScheduledFutureHolder {
|
||||
private ScheduledFuture<?> scheduledFuture;
|
||||
|
||||
private Class<? extends Runnable> runnableClass;
|
||||
|
||||
private String corn;
|
||||
|
||||
public ScheduledFuture<?> getScheduledFuture() {
|
||||
return scheduledFuture;
|
||||
}
|
||||
|
||||
public void setScheduledFuture(ScheduledFuture<?> scheduledFuture) {
|
||||
this.scheduledFuture = scheduledFuture;
|
||||
}
|
||||
|
||||
public Class<? extends Runnable> getRunnableClass() {
|
||||
return runnableClass;
|
||||
}
|
||||
|
||||
public void setRunnableClass(Class<? extends Runnable> runnableClass) {
|
||||
this.runnableClass = runnableClass;
|
||||
}
|
||||
|
||||
public String getCorn() {
|
||||
return corn;
|
||||
}
|
||||
|
||||
public void setCorn(String corn) {
|
||||
this.corn = corn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ScheduledFutureHolder{" +
|
||||
"scheduledFuture=" + scheduledFuture +
|
||||
", runnableClass=" + runnableClass +
|
||||
", corn='" + corn + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.lightyears.challenge.util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 文 件 名 : 特殊处理工具
|
||||
* 创 建 人:HL
|
||||
* 日 期:2019-8-12
|
||||
* 修 改 人:HL
|
||||
* 日 期:2019-8-12
|
||||
* 描 述: 分页、
|
||||
* 版 本 号:2.0
|
||||
*/
|
||||
public class SpecialTool<T> {
|
||||
public static SpecialTool specialTool = new SpecialTool();
|
||||
|
||||
//时间格式
|
||||
public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
//集合判断是否为空
|
||||
|
||||
public boolean ifGather(Object o) {
|
||||
if ((o instanceof List && null == o) || (o instanceof Map && null == o)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//字符串判断是否为空
|
||||
public boolean isEmpty(String s) {
|
||||
if (null == s || s.equals("")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将字符串的首字母转大写
|
||||
* @param str 需要转换的字符串
|
||||
* @return
|
||||
*/
|
||||
private static String captureName(String str) {
|
||||
// 进行字母的ascii编码前移,效率要高于截取字符串进行转换的操作
|
||||
char[] cs=str.toCharArray();
|
||||
cs[0]-=32;
|
||||
return String.valueOf(cs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.lightyears.challenge.util;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 静态工具栏 :目前数据较小 且又想减少服务器压力,特建此类 做静态缓存
|
||||
*/
|
||||
public class StaticUtil {
|
||||
// ------------------------系统类-----------------------
|
||||
//金币极限操作 防范静态变量
|
||||
public static Map<String,Boolean> goldSyn = new HashMap<String,Boolean>();
|
||||
// 数据加解密盐
|
||||
public static final String PRIVATE_KEY = "123144123";
|
||||
|
||||
// ---------------------------------redis -----------------------------------------
|
||||
// 在线用户信息
|
||||
public static final String ONLINE_USER_PUBLIC_KEY="mineClearance:onlineUser:";
|
||||
// 在线用户TOKEN
|
||||
public static final String ONLINE_USER_TOKEN="mineClearance:onlineToken:";
|
||||
// 排行榜
|
||||
public static final String RANK_LIST = "mineClearance:rankList:";
|
||||
// 闯关排行
|
||||
public static final String CLEARANCE_RANK_LIST = "mineClearance:clearanceList";
|
||||
|
||||
// 挑战榜所有缓存前缀
|
||||
public static final String CHALLENGE="mineClearance:challenge:*";
|
||||
// 开启中的挑战榜信息
|
||||
public static final String CHALLENGE_INSTANCE="mineClearance:challenge:instance:";
|
||||
// 开启中的挑战榜排名信息 mineClearance:challenge:rank:instance
|
||||
public static final String CHALLENGE_INSTANCE_RANK="mineClearance:challenge:rank:";
|
||||
// 开启中的挑战榜每个排名的信息 mineClearance:challenge:rankDetail:instance:rank
|
||||
public static final String CHALLENGE_INSTANCE_RANK_DETAIL="mineClearance:challenge:rankDetail:";
|
||||
// 正在挑战的用户,mineClearance:challenge:onlineUser: instanceId : rank: playerId
|
||||
public static final String CHALLENGE_ONLINE_USER="mineClearance:challenge:onlineUser:";
|
||||
// -------------------------------------公告类------------------------------------------
|
||||
// 挑战榜结算 奖励发放备注
|
||||
public static final String CHALLENGE_REMARK = "你在挑战榜:<b>%s</b> 的名次为:<b>%s</b>, 获得<color=orange>%s</color> %s";
|
||||
// 挑战榜奖励发放公告 标题
|
||||
public static final String CHALLENGE_NOTICE_TITLE = "挑战榜奖励发放";
|
||||
// 闯关信息提示 已有多少人到达
|
||||
public static final String CLEARANCE_LOG_TEXT_HAVE = "当前已有<b> %s </b>的玩家到达这一层!";
|
||||
// 闯关信息提示 已超过多少人
|
||||
public static final String CLEARANCE_LOG_TEXT_OVER = "你已超过<b> %s </b>的玩家!";
|
||||
|
||||
//----------------------------挑战榜task--------------------------
|
||||
// 锁榜时间
|
||||
public static final String LOCKE_TIME = " 23:00:00";
|
||||
// 结算时间
|
||||
public static final String SETTLEMENT_TIME = " 23:45:00";
|
||||
// 挑战榜初始化时间
|
||||
public static final String CHALLENGE_INIT_TIME = " 1:00:00";
|
||||
// 挑战榜redis刷新时间
|
||||
public static final String CHALLENGE_REFRESH_TIME = " 1:05:00";
|
||||
}
|
||||
67
challenge/src/main/resources/application-dev.yml
Normal file
67
challenge/src/main/resources/application-dev.yml
Normal file
@@ -0,0 +1,67 @@
|
||||
qbs-switch:
|
||||
swagger-open: true #swagger开关(true:打开, false:关闭)
|
||||
spring:
|
||||
application:
|
||||
name: mine-clearance-challenge
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
allow-circular-references: true
|
||||
# 全局配置响应日期格式和时区为东八区,解决日期类型返回前端少八个小时的问题
|
||||
jackson:
|
||||
time-zone: GMT+8
|
||||
datasource:
|
||||
username: root
|
||||
password: 43626546
|
||||
url: jdbc:mysql://42.192.76.87:3306/saolei_v2_db?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
druid:
|
||||
initial-size: 20
|
||||
max-active: 80
|
||||
min-idle: 20
|
||||
max-wait: 60000
|
||||
timeBetweenEvictionRunsMillis: 60000
|
||||
minEvictabkeIdleTimeMillis: 1800000
|
||||
validationQuery: SELECT 1
|
||||
testWhileIdle: true
|
||||
testOnBorrow: false
|
||||
testOnReturn: false
|
||||
poolPreparedStatements: true
|
||||
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计。‘wall’用于防火墙
|
||||
filters: stat,wall
|
||||
# cloud:
|
||||
# nacos:
|
||||
# discovery:
|
||||
# server-addr: localhost:8848
|
||||
redis:
|
||||
# Redis服务器地址
|
||||
host: localhost
|
||||
# Redis数据库索引(默认为0)
|
||||
database: 0
|
||||
# Redis服务器连接端口
|
||||
port: 6379
|
||||
# Redis服务器连接密码(默认为空)
|
||||
password: 123456
|
||||
# 连接超时时间
|
||||
timeout: 1000ms
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池最大连接数
|
||||
max-active: 8
|
||||
# 连接池最大空闲连接数
|
||||
max-idle: 8
|
||||
# 连接池最小空闲连接数
|
||||
min-idle: 0
|
||||
# 连接池最大阻塞等待时间,负值表示没有限制
|
||||
max-wait: -1ms
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath*:mapper/**/*Mapper.xml
|
||||
type-aliases-package: com.lightyears.common.domain
|
||||
global-config:
|
||||
banner: false
|
||||
db-config:
|
||||
id-type: input
|
||||
configuration:
|
||||
# 控制台SQL日志
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
map-underscore-to-camel-case: false
|
||||
73
challenge/src/main/resources/application-prod.yml
Normal file
73
challenge/src/main/resources/application-prod.yml
Normal file
@@ -0,0 +1,73 @@
|
||||
qbs-switch:
|
||||
swagger-open: false #swagger开关(true:打开, false:关闭)
|
||||
spring:
|
||||
application:
|
||||
name: mine-clearance-challenge
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
allow-circular-references: true
|
||||
# 全局配置响应日期格式和时区为东八区,解决日期类型返回前端少八个小时的问题
|
||||
jackson:
|
||||
time-zone: GMT+8
|
||||
datasource:
|
||||
username: root
|
||||
password: 1476346288@mysql
|
||||
#password: 1813547935mysql
|
||||
# 挑战
|
||||
url: jdbc:mysql://172.26.101.6:3986/saolei_v2_db?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull
|
||||
# 本地
|
||||
# url: jdbc:mysql://39.106.21.14:3986/saolei_v2_db?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
druid:
|
||||
initial-size: 20
|
||||
max-active: 80
|
||||
min-idle: 20
|
||||
max-wait: 60000
|
||||
timeBetweenEvictionRunsMillis: 60000
|
||||
minEvictabkeIdleTimeMillis: 1800000
|
||||
validationQuery: SELECT 1
|
||||
testWhileIdle: true
|
||||
testOnBorrow: false
|
||||
testOnReturn: false
|
||||
poolPreparedStatements: true
|
||||
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计。‘wall’用于防火墙
|
||||
filters: stat,wall
|
||||
# cloud:
|
||||
# nacos:
|
||||
# discovery:
|
||||
# server-addr: localhost:8848
|
||||
redis:
|
||||
# Redis服务器地址
|
||||
# host: localhost
|
||||
host: 172.26.101.6
|
||||
# Redis数据库索引(默认为0)
|
||||
database: 0
|
||||
# Redis服务器连接端口
|
||||
port: 7963
|
||||
# Redis服务器连接密码(默认为空)
|
||||
password: 1476346288@redis
|
||||
#password: 123456
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池最大连接数
|
||||
max-active: 8
|
||||
# 连接池最大空闲连接数
|
||||
max-idle: 8
|
||||
# 连接池最小空闲连接数
|
||||
min-idle: 0
|
||||
# 连接池最大阻塞等待时间,负值表示没有限制
|
||||
# max-wait: -1ms
|
||||
max-wait: -1ms
|
||||
shutdown-timeout: 100ms
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath*:mapper/**/*Mapper.xml
|
||||
type-aliases-package: com.lightyears.common.domain
|
||||
global-config:
|
||||
banner: false
|
||||
db-config:
|
||||
id-type: input
|
||||
configuration:
|
||||
# 控制台SQL日志
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
map-underscore-to-camel-case: false
|
||||
21
challenge/src/main/resources/application.yml
Normal file
21
challenge/src/main/resources/application.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
server:
|
||||
port: 18632
|
||||
tomcat:
|
||||
uri-encoding: UTF-8
|
||||
#最大等待连接数
|
||||
accept-count: 1000
|
||||
#最大线程数
|
||||
server.tomcat.max-threads: 800
|
||||
#最小工作线程数
|
||||
server.tomcat.min-spare-threads: 100
|
||||
logging:
|
||||
config: classpath:log.xml
|
||||
rocketmq:
|
||||
name-server: localhost:9876
|
||||
producer:
|
||||
group: mineClearance
|
||||
spring:
|
||||
profiles:
|
||||
active: prod
|
||||
appconfig:
|
||||
version: 197.0
|
||||
72
challenge/src/main/resources/log.xml
Normal file
72
challenge/src/main/resources/log.xml
Normal file
@@ -0,0 +1,72 @@
|
||||
<configuration>
|
||||
<!-- %m输出的信息,%p日志级别,%t线程名,%d日期,%c类的全名,%i索引【从数字0开始递增】,,, -->
|
||||
<!-- appender是configuration的子节点,是负责写日志的组件。 -->
|
||||
<!-- ConsoleAppender:把日志输出到控制台 -->
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d %p (%file:%line\)- %m%n</pattern>
|
||||
<!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
<!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
|
||||
<!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是sys.log -->
|
||||
<!-- 2.如果日期没有发生变化,但是当前日志的文件大小超过1KB时,对当前日志进行分割 重命名-->
|
||||
<appender name="syslog"
|
||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<File>logs/challenge/sys.log</File>
|
||||
<!-- rollingPolicy:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。 -->
|
||||
<!-- TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 活动文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
|
||||
<!-- 文件名:log/sys.2022-3-09.0.log -->
|
||||
<fileNamePattern>logs/challenge/sys.%d.%i.log</fileNamePattern>
|
||||
<!-- 每产生一个日志文件,该日志文件的保存期限为30天 -->
|
||||
<maxHistory>30</maxHistory>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<!-- maxFileSize:这是活动文件的大小,默认值是10MB -->
|
||||
<maxFileSize>10MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<!-- pattern节点,用来设置日志的输入格式 -->
|
||||
<pattern>
|
||||
%d %p (%file:%line\)- %m%n
|
||||
</pattern>
|
||||
<!-- 记录日志的编码 -->
|
||||
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
|
||||
</encoder>
|
||||
</appender>
|
||||
<!-- rocketmq日志 -->
|
||||
<appender name="RocketmqClientAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>logs/rocketmq_client.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>logs/rocketmq_client.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<!--保留时间,单位:天-->
|
||||
<maxHistory>30</maxHistory>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<!-- maxFileSize:这是活动文件的大小,默认值是10MB -->
|
||||
<maxFileSize>10MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
</rollingPolicy>
|
||||
<encoder charset="UTF-8">
|
||||
<pattern>%d{yy-MM-dd.HH:mm:ss.SSS} [%-16t] %-5p %-22c{0} %X{ServiceId} - %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 控制台输出日志级别 -->
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
<!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
|
||||
<!-- com.lightyears为根包,也就是只要是发生在这个根包下面的所有日志操作行为的权限都是DEBUG -->
|
||||
<!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE -->
|
||||
<logger name="com.lightyears.challenge" level="DEBUG">
|
||||
<appender-ref ref="syslog" />
|
||||
</logger>
|
||||
<!-- Rocketmq日志配置 -->
|
||||
<logger name="RocketmqClient" additivity="false">
|
||||
<level value="ERROR" />
|
||||
<appender-ref ref="RocketmqClientAppender"/>
|
||||
</logger>
|
||||
</configuration>
|
||||
5
challenge/src/main/resources/mapper/AssertLogMapper.xml
Normal file
5
challenge/src/main/resources/mapper/AssertLogMapper.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.lightyears.challenge.dao.AssertLogMapper">
|
||||
|
||||
</mapper>
|
||||
5
challenge/src/main/resources/mapper/ListBaseMapper.xml
Normal file
5
challenge/src/main/resources/mapper/ListBaseMapper.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.lightyears.challenge.dao.ListBaseMapper">
|
||||
|
||||
</mapper>
|
||||
32
challenge/src/main/resources/mapper/ListInstanceMapper.xml
Normal file
32
challenge/src/main/resources/mapper/ListInstanceMapper.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.lightyears.challenge.dao.ListInstanceMapper">
|
||||
|
||||
<update id="updateInstanceAwardSize">
|
||||
UPDATE sl_list_instance
|
||||
SET award_size = award_size + #{awardSize}
|
||||
where id = #{instanceId}
|
||||
and assets_type = #{assetsType}
|
||||
</update>
|
||||
|
||||
<select id="getListInstances" resultType="com.lightyears.common.domain.dto.ListInstanceDto">
|
||||
SELECT
|
||||
id,
|
||||
list_id as listId,
|
||||
`name`,
|
||||
list_date AS listDate,
|
||||
mine_num_section AS mineNumSection,
|
||||
map_size AS mapSize,
|
||||
in_pond_fee AS inPondFee,
|
||||
award_size AS awardSize,
|
||||
entry_threshold AS entryThreshold,
|
||||
`status`,
|
||||
assets_type as assetsType,
|
||||
tickets_num as ticketsNum,
|
||||
distribution as distribution
|
||||
FROM
|
||||
sl_list_instance
|
||||
WHERE
|
||||
`status` = 1
|
||||
</select>
|
||||
</mapper>
|
||||
81
challenge/src/main/resources/mapper/ListRankMapper.xml
Normal file
81
challenge/src/main/resources/mapper/ListRankMapper.xml
Normal file
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.lightyears.challenge.dao.ListRankMapper">
|
||||
<update id="initRank">
|
||||
UPDATE `sl_list_rank`
|
||||
SET
|
||||
`player_name` = NULL,
|
||||
`player_id` = NULL,
|
||||
`challenge_time` = NULL,
|
||||
`game_data` = NULL
|
||||
WHERE
|
||||
`instance_id` = ${instanceId}
|
||||
and `player_id` = ${playerId}
|
||||
</update>
|
||||
<select id="getRankList" resultType="com.lightyears.common.domain.dto.ListRankDto">
|
||||
SELECT
|
||||
r.id as id,
|
||||
r.instance_id AS instanceId,
|
||||
r.rank_num AS rankNum,
|
||||
r.player_id AS playerId,
|
||||
r.player_name AS playerName,
|
||||
r.challenge_time AS challengeTime,
|
||||
r.game_data AS gameData
|
||||
FROM
|
||||
sl_list_rank r,
|
||||
sl_list_instance n,
|
||||
sl_player sp
|
||||
WHERE
|
||||
n.id = r.instance_id
|
||||
AND r.player_id = sp.user_id
|
||||
<if test="instanceId != null and instanceId != 0">
|
||||
and r.instance_id = #{instanceId}
|
||||
</if>
|
||||
<if test="playerId != null and playerId != 0">
|
||||
and r.player_id = ${playerId}
|
||||
</if>
|
||||
<if test="state != null and state > -1">
|
||||
and n.status = ${state}
|
||||
</if>
|
||||
ORDER BY
|
||||
rank_num ASC
|
||||
</select>
|
||||
<select id="getNewRankList" resultType="com.lightyears.common.domain.dto.ListRankDto">
|
||||
SELECT
|
||||
r.id as id,
|
||||
r.instance_id AS instanceId,
|
||||
r.rank_num AS rankNum,
|
||||
r.player_id AS playerId,
|
||||
r.player_name AS playerName,
|
||||
r.challenge_time AS challengeTime,
|
||||
r.game_data AS gameData
|
||||
FROM
|
||||
sl_list_rank r
|
||||
LEFT JOIN sl_list_instance n on n.id = r.instance_id
|
||||
where
|
||||
n.status in (1, 3)
|
||||
<if test="instanceId != null and instanceId != 0">
|
||||
and r.instance_id = #{instanceId}
|
||||
</if>
|
||||
<if test="playerId != null and playerId != 0">
|
||||
and r.player_id = ${playerId}
|
||||
</if>
|
||||
ORDER BY
|
||||
rank_num ASC
|
||||
</select>
|
||||
<select id="getRankByInsRank" resultType="com.lightyears.common.domain.dto.ListRankDto">
|
||||
SELECT
|
||||
id,
|
||||
instance_id as instanceId,
|
||||
rank_num as rankNum,
|
||||
player_id AS playerId,
|
||||
player_name AS playerName,
|
||||
challenge_time AS challengeTime,
|
||||
game_data as gameData
|
||||
FROM
|
||||
sl_list_rank
|
||||
WHERE
|
||||
instance_id = #{instanceId}
|
||||
AND rank_num = #{rank}
|
||||
</select>
|
||||
</mapper>
|
||||
4
challenge/src/main/resources/mapper/LogMapper.xml
Normal file
4
challenge/src/main/resources/mapper/LogMapper.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.lightyears.challenge.dao.LogMapper">
|
||||
</mapper>
|
||||
4
challenge/src/main/resources/mapper/NoticeMapper.xml
Normal file
4
challenge/src/main/resources/mapper/NoticeMapper.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.lightyears.challenge.dao.NoticeMapper">
|
||||
</mapper>
|
||||
14
challenge/src/main/resources/mapper/PlayerAssetsMapper.xml
Normal file
14
challenge/src/main/resources/mapper/PlayerAssetsMapper.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.lightyears.challenge.dao.PlayerAssetsMapper">
|
||||
<update id="addGold">
|
||||
update sl_player_assets set number = number + #{gold}, version = version +1 where id = #{id} and version = ${version}
|
||||
</update>
|
||||
<update id="reduceGold">
|
||||
update sl_player_assets set number = number - #{gold}, version = version +1 where id = #{id} and version = ${version}
|
||||
</update>
|
||||
<!-- 获取用户的资产信息 -->
|
||||
<select id="getPlayerAssets" resultType="com.lightyears.common.domain.dto.SimplePlayerAssert">
|
||||
select type, number from sl_player_assets where player_id = #{playerId}
|
||||
</select>
|
||||
</mapper>
|
||||
5
challenge/src/main/resources/mapper/PlayerMapper.xml
Normal file
5
challenge/src/main/resources/mapper/PlayerMapper.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.lightyears.challenge.dao.PlayerMapper">
|
||||
|
||||
</mapper>
|
||||
5
challenge/src/main/resources/mapper/RecordMapper.xml
Normal file
5
challenge/src/main/resources/mapper/RecordMapper.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.lightyears.challenge.dao.RecordMapper">
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user