You've already forked mine_clearance
项目上传
This commit is contained in:
146
basics/pom.xml
Normal file
146
basics/pom.xml
Normal file
@@ -0,0 +1,146 @@
|
||||
<?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>
|
||||
<name>basics</name>
|
||||
<artifactId>basics</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>
|
||||
<!-- 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>com.lightyears.mine_clearance</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>basics</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.basics.BasicsApp</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>
|
||||
19
basics/src/main/java/com/lightyears/basics/BasicsApp.java
Normal file
19
basics/src/main/java/com/lightyears/basics/BasicsApp.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package com.lightyears.basics;
|
||||
|
||||
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 BasicsApp {
|
||||
public static void main(String[] args) {
|
||||
// 设置时区
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
|
||||
SpringApplication.run(BasicsApp.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.lightyears.basics.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Documented
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DataVerification {
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.lightyears.basics.aspect;
|
||||
|
||||
import cn.hutool.crypto.digest.MD5;
|
||||
import com.github.pagehelper.util.StringUtil;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import com.lightyears.basics.exception.GlobalException;
|
||||
import com.lightyears.basics.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.basics.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.basics.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.basics.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.basics.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.basics.controller;
|
||||
|
||||
import com.lightyears.common.domain.entity.Player;
|
||||
import com.lightyears.basics.util.RedisCache;
|
||||
import com.lightyears.basics.util.StaticUtil;
|
||||
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,39 @@
|
||||
package com.lightyears.basics.controller;
|
||||
|
||||
import com.lightyears.basics.annotation.DataVerification;
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
import com.lightyears.common.domain.dto.SimplePlayerAssert;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import com.lightyears.basics.service.IPlayerAssetsService;
|
||||
import com.lightyears.basics.util.ResultUtil;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@CrossOrigin
|
||||
@RestController
|
||||
@RequestMapping("/challenge")
|
||||
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
|
||||
public class ChallengeController extends BaseController{
|
||||
private final IPlayerAssetsService playerAssetsService;
|
||||
|
||||
// @DataVerification
|
||||
@GetMapping("/list")
|
||||
public ResModeBase list() {
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), new ArrayList<>());
|
||||
}
|
||||
// @DataVerification
|
||||
@GetMapping("/playerAssert")
|
||||
@ApiOperation(value = "获取玩家资产信息", notes = "挑战榜")
|
||||
public ResModeBase playerAssert(){
|
||||
List<SimplePlayerAssert> assets = playerAssetsService.getPlayerAssets(this.getUserInfo().getUser_id());
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), assets);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
package com.lightyears.basics.controller;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.lightyears.basics.annotation.DataVerification;
|
||||
import com.lightyears.basics.service.IClearanceLogService;
|
||||
import com.lightyears.basics.service.IGameSystemService;
|
||||
import com.lightyears.basics.service.ILogService;
|
||||
import com.lightyears.basics.service.INoticeService;
|
||||
import com.lightyears.basics.util.ResultUtil;
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
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.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Date;
|
||||
|
||||
@CrossOrigin
|
||||
@RestController
|
||||
@RequestMapping("/saolei")
|
||||
@Api("扫雷 客户端调用接口:")
|
||||
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
|
||||
public class ClientController extends BaseController{
|
||||
private final IGameSystemService gameSystemServiceImpl;
|
||||
private final INoticeService noticeServiceImpl;
|
||||
private final ILogService logService;
|
||||
private final IClearanceLogService clearanceLogService;
|
||||
|
||||
@RequestMapping(value = "/touristLogin/{id}", method = RequestMethod.GET)
|
||||
@ApiImplicitParam(paramType="path", name = "id", value = "用户openId", example = "123", required = true, dataType = "Integer")
|
||||
@ApiOperation(value = "三方登陆", notes = "参数 QQ/微信open_id(tokenId) 新建用户 isNewUser = true")
|
||||
public ResModeBase touristLogin(@PathVariable String id) {
|
||||
return this.gameSystemServiceImpl.touristlogin(id);
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/checkName", method = RequestMethod.POST)
|
||||
@ApiOperation(value = "昵称验证", notes = "昵称是否重复,true 代表昵称可用")
|
||||
public ResModeBase checkName(@RequestParam("userName") String userName) {
|
||||
return this.gameSystemServiceImpl.checkName(userName);
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/updateName", method = RequestMethod.POST)
|
||||
@ApiOperation(value = "修改昵称", notes = "更新指定ID玩家的名称(玩家第一次登录时,系统分配默认名称,并提供玩家一次改名的机会)")
|
||||
public ResModeBase updateName(@RequestParam("userName") String userName) {
|
||||
return this.gameSystemServiceImpl.updateName(this.getUserInfo().getUser_id(), userName);
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/add_Gold", method = RequestMethod.POST)
|
||||
@ApiOperation(value = "金币存储", notes = "每次 用户主动向数据库 存储金币")
|
||||
public ResModeBase add_Gold(@ApiParam(value = "货币数", example = "1") @RequestParam("gold") int gold,
|
||||
@ApiParam(value = "货币类型(0.金币)", example = "0")@RequestParam("type") int type,
|
||||
@ApiParam(value = "货币变化说明", example = "游戏增加货币") @RequestParam("remark")String remark) {
|
||||
return this.gameSystemServiceImpl.pushGoldImpl(this.getUserInfo().getUser_id(), gold, type, remark);
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/sub_Gold", method = RequestMethod.POST)
|
||||
@ApiOperation(value = "金币取出", notes = "与“金币存储”相反,从用户账号扣除指定金币,如果余额不够扣费")
|
||||
public ResModeBase sub_Gold(@ApiParam(value = "货币数", example = "1") @RequestParam("gold") int gold,
|
||||
@ApiParam(value = "货币类型(0.金币)", example = "0")@RequestParam("type") int type,
|
||||
@ApiParam(value = "货币变化说明", example = "扣手续费") @RequestParam("remark")String remark) {
|
||||
return this.gameSystemServiceImpl.pullGoldImpl(this.getUserInfo().getUser_id(), gold, type, remark);
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/saveFile", method = RequestMethod.POST)
|
||||
@ApiOperation(value = "数据存档", notes = "本都游戏数据上传服务器保存")
|
||||
public ResModeBase saveFile(@ApiParam(value = "存档数据") @RequestParam(value = "record", required = false) String record,
|
||||
@ApiParam(value = "存档类型0 皮肤 1 记录 2游戏设置", example = "1") @RequestParam(value = "record_type") Integer record_type) {
|
||||
return this.gameSystemServiceImpl.saveFileImpl(this.getUserInfo().getUser_id(), record, record_type);
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/readFile", method = RequestMethod.POST)
|
||||
@ApiOperation(value = "读取存档", notes = "读取服务器存档")
|
||||
public ResModeBase readFile(@ApiParam(value = "存档类型0 皮肤 1 记录 2游戏设置", example = "1") @RequestParam(value = "record_type") Integer record_type) {
|
||||
return this.gameSystemServiceImpl.readFile(this.getUserInfo().getUser_id(), record_type);
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/saveLog", method = RequestMethod.POST)
|
||||
@ApiOperation(value = "提交游戏记录", notes = "每次游戏完成 进行记录提交")
|
||||
public ResModeBase saveLog(@ApiParam(value = " 游戏难度:1 - 普通 2 困难 3 大师 4 超凡", example = "1") @RequestParam(value = "level", required = false) Integer level,
|
||||
@ApiParam(value = "本剧游戏所用时间", example = "1") @RequestParam(value = "game_time") int game_time,
|
||||
@RequestParam(value = "bvs3") float bvs3,
|
||||
@RequestParam(value = "bv3") float bv3,
|
||||
@RequestParam(value = "video") String video,
|
||||
@RequestParam(value = "gameinfo") String gameinfo,
|
||||
@RequestParam(value = "nf") boolean nf) {
|
||||
return this.gameSystemServiceImpl.saveLogImpl(this.getUserInfo(), level, game_time, bvs3, bv3, video, gameinfo,nf);
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/rankingLog", method = RequestMethod.POST)
|
||||
@ApiOperation(value = "综合排行榜", notes = "所有玩家的排行榜信息")
|
||||
public ResModeBase ranking(
|
||||
@ApiParam(value = "当前页", example = "1") @RequestParam(value = "pageIndex") int pageIndex,
|
||||
@ApiParam(value = "每页数量", example = "1") @RequestParam(value = "pageSize") int pageSize,
|
||||
@ApiParam(value = "游戏难度:-1综合 1 - 普通 2 困难 3 大师 4 超凡", example = "1") @RequestParam(value = "level") int level) {
|
||||
return this.gameSystemServiceImpl.ranking(pageIndex, pageSize, level);
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/userLog", method = RequestMethod.POST)
|
||||
@ApiOperation(value = "玩家个人 排行名次以及信息", notes = "")
|
||||
public ResModeBase log(@ApiParam(value = "游戏难度:-1综合 1 - 普通 2 困难 3 大师 4 超凡", example = "1") @RequestParam(value = "level") int level) {
|
||||
return this.gameSystemServiceImpl.log(this.getUserInfo().getUser_id(), level);
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/getList", method = RequestMethod.GET)
|
||||
@ApiOperation(value = "公告查询", notes = "1")
|
||||
public ResModeBase getList() {
|
||||
return this.noticeServiceImpl.getList(this.getUserInfo().getUser_id());
|
||||
}
|
||||
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/getContent", method = RequestMethod.GET)
|
||||
@ApiOperation(value = "公告内容查询", notes = "1")
|
||||
public ResModeBase getContent(@ApiParam(value = "公告id", example = "1") @RequestParam(value = "id") int id) {
|
||||
return this.noticeServiceImpl.getContent(id);
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/getGameData", method = RequestMethod.POST)
|
||||
@ApiOperation(value = "回放数据查询", notes = "1")
|
||||
public ResModeBase getGameData(@ApiParam(value = "排行榜id", example = "1") @RequestParam(value = "id") Integer id,@ApiParam(value = "榜单类型:1.普通榜,2挑战榜", example = "1") Integer type) {
|
||||
return this.gameSystemServiceImpl.getGameData(id, type);
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/getSystemTime", method = RequestMethod.GET)
|
||||
@ApiOperation(value = "获取系统时间", notes = "1")
|
||||
public ResModeBase getSystemTime() {
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), DateUtil.format(new Date(),"yyyy-MM-dd"));
|
||||
}
|
||||
|
||||
@DataVerification
|
||||
@RequestMapping(value = "/cancellationAccount", method = RequestMethod.GET)
|
||||
@ApiOperation(value = "注销账号", notes = "1")
|
||||
public ResModeBase cancellationAccount(@ApiParam(value = "身份token", example = "1") @RequestParam(value = "checkToken")String checkToken, HttpServletRequest request) {
|
||||
if(checkToken.equals(request.getHeader("Tracecode"))){
|
||||
gameSystemServiceImpl.cancellationAccount(this.getUserInfo().getUser_id());
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage());
|
||||
} else {
|
||||
return ResultUtil.result(MessageEnum.CHECK_LOGGING_ERROR.getCode(), MessageEnum.CHECK_LOGGING_ERROR.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/refreshRankCache", method = RequestMethod.GET)
|
||||
@ApiOperation(value = "刷新排行榜缓存", notes = "1")
|
||||
public ResModeBase refreshRankCache(@RequestParam(value = "key")Integer key) {
|
||||
if(key == 43626546){
|
||||
// 排行榜缓存
|
||||
logService.cacheRankList(null);
|
||||
// 雷神之塔缓存
|
||||
clearanceLogService.cachePlayerClearanceRank();
|
||||
}
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage());
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/saveClearanceLog", method = RequestMethod.POST)
|
||||
@ApiOperation(value = "写入雷神之塔闯关记录", notes = "1")
|
||||
public ResModeBase saveClearanceLog(@ApiParam(value = "游戏数据", example = "1") @RequestParam(value = "data")String data) {
|
||||
clearanceLogService.saveClearanceLog(this.getUserInfo().getUser_id(), data);
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage());
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/getPlayerClearanceLog", method = RequestMethod.GET)
|
||||
@ApiOperation(value = "获取雷神之塔个人信息", notes = "1")
|
||||
public ResModeBase getPlayerClearanceLog(@RequestParam(value = "type", required = false, defaultValue = "0")Integer type) {
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), clearanceLogService.getPlayer(this.getUserInfo().getUser_id(), this.getUserInfo().getUser_name(), type));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.lightyears.basics.controller;
|
||||
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
import com.lightyears.common.domain.entity.Notice;
|
||||
import com.lightyears.basics.service.ISystemService;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@CrossOrigin
|
||||
@RestController
|
||||
@RequestMapping("/sys")
|
||||
@Api("扫雷 管理端调用接口:")
|
||||
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
|
||||
public class SystemController extends BaseController{
|
||||
private final ISystemService systemService;
|
||||
|
||||
@RequestMapping(value = "/publishNotice", method = RequestMethod.POST)
|
||||
public ResModeBase publishNotice(@RequestBody Notice notice) {
|
||||
return systemService.publishNotice(notice);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.lightyears.basics.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,46 @@
|
||||
package com.lightyears.basics.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.basics.exception;
|
||||
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import com.lightyears.basics.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,119 @@
|
||||
package com.lightyears.basics.filter;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.github.pagehelper.util.StringUtil;
|
||||
import com.lightyears.basics.config.AppConfig;
|
||||
import com.lightyears.common.domain.entity.Player;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import com.lightyears.basics.util.RedisCache;
|
||||
import com.lightyears.basics.util.StaticUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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;
|
||||
|
||||
@Slf4j
|
||||
@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);
|
||||
// log.info("version :" + appConfig.getVersion());
|
||||
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,38 @@
|
||||
package com.lightyears.basics.init;
|
||||
|
||||
import com.lightyears.basics.service.IClearanceLogService;
|
||||
import com.lightyears.basics.service.ILogService;
|
||||
import com.lightyears.basics.util.RedisCache;
|
||||
import com.lightyears.basics.util.StaticUtil;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.annotation.Resource;
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* 挑战数据初始化
|
||||
*/
|
||||
@Component
|
||||
public class ChallengeDataInit {
|
||||
@Resource
|
||||
private ILogService logService;
|
||||
@Resource
|
||||
private IClearanceLogService clearanceLogService;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
// 缓存排行榜数据
|
||||
logService.cacheRankList(null);
|
||||
// 缓存雷神之塔玩家关卡数据
|
||||
clearanceLogService.cachePlayerClearanceRank();
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void destroy() {
|
||||
// 写入持久层
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.lightyears.basics.mapper;
|
||||
|
||||
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,26 @@
|
||||
package com.lightyears.basics.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.lightyears.common.domain.dto.ClearanceRankDto;
|
||||
import com.lightyears.common.domain.entity.ClearanceLog;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-06-02
|
||||
*/
|
||||
@Mapper
|
||||
public interface ClearanceLogMapper extends BaseMapper<ClearanceLog> {
|
||||
/**
|
||||
* 获取玩家最高闯关 关卡数据
|
||||
* @return
|
||||
*/
|
||||
List<ClearanceRankDto> getPlayerClearanceLogs(@Param("userId")Integer userId);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.lightyears.basics.mapper;
|
||||
|
||||
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,29 @@
|
||||
package com.lightyears.basics.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.lightyears.common.domain.dto.OrdinaryRankDto;
|
||||
import com.lightyears.common.domain.entity.Log;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 游戏 完成记录 表 游戏难度:1 - 普通 2 困难 3 大师 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-09
|
||||
*/
|
||||
@Mapper
|
||||
public interface LogMapper extends BaseMapper<Log> {
|
||||
List<OrdinaryRankDto> paging(@Param("level") Integer level, @Param("userId")Integer userId);
|
||||
//综合查询 三种难度加起来 获取排名
|
||||
List<OrdinaryRankDto> syntheticalPaging();
|
||||
// 查询用户综合排名
|
||||
Map getComprehensiveRankByUserId(@Param("userId") Integer userId);
|
||||
//根据User_id和 level 查询排名
|
||||
Map getRankByLevelUserId(@Param("level")int level, @Param("userId") Integer userId);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.lightyears.basics.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.lightyears.common.domain.dto.NoticeDto;
|
||||
import com.lightyears.common.domain.entity.Notice;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-18
|
||||
*/
|
||||
@Mapper
|
||||
public interface NoticeMapper extends BaseMapper<Notice> {
|
||||
List<NoticeDto> getList(@Param("type") Integer type, @Param("playerId") Integer playerId);
|
||||
String getContent(@Param("id")Integer id);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.lightyears.basics.mapper;
|
||||
|
||||
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,31 @@
|
||||
package com.lightyears.basics.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.lightyears.common.domain.entity.Player;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 扫雷玩家表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-09
|
||||
*/
|
||||
@Mapper
|
||||
public interface PlayerMapper extends BaseMapper<Player> {
|
||||
/**
|
||||
* 设置不活跃玩家标记
|
||||
* @param dateNum 秒数时间戳
|
||||
* @return
|
||||
*/
|
||||
int setInactivePlayer(@Param("dateNum") Long dateNum);
|
||||
|
||||
/**
|
||||
* 设置活跃玩家标记
|
||||
* @param dateNum 秒数时间戳
|
||||
* @return
|
||||
*/
|
||||
int setActivePlayer(@Param("dateNum") Long dateNum);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.lightyears.basics.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.lightyears.common.domain.entity.Record;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 游戏存档 Mapper 接口
|
||||
* </p>x
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-09
|
||||
*/
|
||||
@Mapper
|
||||
public interface RecordMapper extends BaseMapper<Record> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.lightyears.basics.schedule;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.lightyears.basics.mapper.AssertLogMapper;
|
||||
import com.lightyears.basics.mapper.PlayerMapper;
|
||||
import com.lightyears.basics.service.ILogService;
|
||||
import com.lightyears.basics.service.INoticeService;
|
||||
import com.lightyears.common.domain.entity.AssertLog;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
|
||||
public class BasicsTask {
|
||||
private final ILogService logService;
|
||||
private final AssertLogMapper assertLogMapper;
|
||||
private final INoticeService noticeService;
|
||||
private final PlayerMapper playerMapper;
|
||||
|
||||
|
||||
/**
|
||||
* 刷新综合榜数据 5分钟
|
||||
*/
|
||||
@Scheduled(cron = "0 */1 * * * ?")
|
||||
public void refreshComprehensiveRank() {
|
||||
log.info("-----------刷新排行数据----------");
|
||||
// 重新计算、缓存综合榜数据
|
||||
logService.cacheRankList(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 每日 3点执行 删除用户资产log(保留最近7日记录)
|
||||
*/
|
||||
@Scheduled(cron = "0 0 3 * * ?")
|
||||
public void deleteRecords(){
|
||||
Date date = DateUtil.offsetDay(new Date(), -7);
|
||||
assertLogMapper.delete(new LambdaQueryWrapper<AssertLog>().lt(AssertLog::getCreateDate, date));
|
||||
}
|
||||
|
||||
/**
|
||||
* 每日 0点执行 删除用户过期公告
|
||||
*/
|
||||
@Scheduled(cron = "0 0 0 * * ?")
|
||||
public void deleteNotices(){
|
||||
noticeService.deleteNoticeForTask();
|
||||
}
|
||||
|
||||
/**
|
||||
* 每月 1号 1点7分执行 标记上月不活跃用户
|
||||
*/
|
||||
@Scheduled(cron = "0 7 1 1 * ?")
|
||||
public void markPlayerActive(){
|
||||
// 30天前的时间戳
|
||||
Long time = System.currentTimeMillis() / 1000 - 2592000L;
|
||||
// 标记上月活跃用户
|
||||
playerMapper.setActivePlayer(time);
|
||||
// 标记上月不活跃用户
|
||||
playerMapper.setInactivePlayer(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* 每月 1号 1点13分执行 刷新基础排行榜(排除上月不活跃玩家)
|
||||
*/
|
||||
@Scheduled(cron = "0 13 1 1 * ?")
|
||||
public void refreshRankList(){
|
||||
logService.cacheRankList(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.lightyears.basics.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.lightyears.common.domain.dto.PlayerClearanceLogInfoDto;
|
||||
import com.lightyears.common.domain.entity.ClearanceLog;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-06-02
|
||||
*/
|
||||
public interface IClearanceLogService extends IService<ClearanceLog> {
|
||||
|
||||
/**
|
||||
* 保存闯关记录
|
||||
* @param playerId
|
||||
* @param layersNum
|
||||
* @param gameData
|
||||
*/
|
||||
void saveClearanceLog(Integer playerId, String gameData);
|
||||
|
||||
/**
|
||||
* 获取用户闯关记录
|
||||
* @param playerId 用户id
|
||||
* @param playerName 用户名
|
||||
* @return
|
||||
*/
|
||||
PlayerClearanceLogInfoDto getPlayer(Integer playerId, String playerName, Integer type);
|
||||
|
||||
/**
|
||||
* 缓存用户闯关记录
|
||||
*/
|
||||
void cachePlayerClearanceRank();
|
||||
|
||||
/**
|
||||
* 删除用户闯关记录缓存
|
||||
*/
|
||||
void deletCacheByPlayerId(Integer playerId);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.lightyears.basics.service;
|
||||
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
import com.lightyears.common.domain.entity.Player;
|
||||
|
||||
public interface IGameSystemService {
|
||||
|
||||
|
||||
ResModeBase touristlogin(String open_id);
|
||||
|
||||
ResModeBase checkName(String userName);
|
||||
|
||||
ResModeBase updateName(int userId, String userName);
|
||||
|
||||
ResModeBase pushGoldImpl(Integer userId, int gold, int type, String remark);
|
||||
|
||||
ResModeBase pushGold(Integer userId, int gold, int type, String remark);
|
||||
|
||||
ResModeBase pullGoldImpl(Integer userId, int gold, int type, String remark);
|
||||
|
||||
ResModeBase pullGold(Integer userId, int gold, int type, String remark);
|
||||
|
||||
ResModeBase saveFileImpl(int userId, String record, Integer record_type);
|
||||
|
||||
ResModeBase saveFile(int userId, String record, Integer record_type);
|
||||
|
||||
ResModeBase readFile(int userId, int record_type);
|
||||
|
||||
ResModeBase saveLogImpl(Player player, Integer level, int game_time, float bvs3, float bv3, String video, String gameinfo, boolean nf);
|
||||
|
||||
ResModeBase saveLog(Player player, Integer level, int game_time, float bvs3, float bv3, String video, String gameinfo, boolean nf);
|
||||
|
||||
ResModeBase ranking(int pageIndex, int pageSize, int level);
|
||||
|
||||
ResModeBase log(int userId, int level);
|
||||
|
||||
ResModeBase getGameData(Integer id, Integer type);
|
||||
|
||||
void cancellationAccount(Integer userId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.lightyears.basics.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.lightyears.common.domain.dto.OrdinaryRankDto;
|
||||
import com.lightyears.common.domain.entity.Log;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 游戏 完成记录 表 游戏难度:1 - 普通 2 困难 3 大师 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-09
|
||||
*/
|
||||
public interface ILogService extends IService<Log> {
|
||||
/**
|
||||
* 查询排行榜
|
||||
* @param level 游戏难度:1 - 普通 2 困难 3 大师
|
||||
* @return
|
||||
*/
|
||||
List<OrdinaryRankDto> getRankList(Integer level);
|
||||
|
||||
/**
|
||||
* 排行榜数据写入缓存
|
||||
*/
|
||||
void cacheRankList(Integer level);
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
* @param userId
|
||||
*/
|
||||
void deleteCacheByUserId(Integer userId);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.lightyears.basics.service;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
import com.lightyears.common.domain.entity.Notice;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-18
|
||||
*/
|
||||
public interface INoticeService extends IService<Notice> {
|
||||
ResModeBase getList(Integer playerId);
|
||||
ResModeBase getContent(Integer id);
|
||||
void deleteNoticeForTask();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.lightyears.basics.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);
|
||||
|
||||
/**
|
||||
* 获取指定用户的资产
|
||||
* @param playerId 用户id
|
||||
* @return
|
||||
*/
|
||||
List<SimplePlayerAssert> getPlayerAssets(int playerId);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.lightyears.basics.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.basics.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,8 @@
|
||||
package com.lightyears.basics.service;
|
||||
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
import com.lightyears.common.domain.entity.Notice;
|
||||
|
||||
public interface ISystemService {
|
||||
ResModeBase publishNotice(Notice notice);
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.lightyears.basics.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.lightyears.basics.mapper.ClearanceLogMapper;
|
||||
import com.lightyears.common.domain.dto.ClearanceRankDto;
|
||||
import com.lightyears.common.domain.dto.PlayerClearanceLogInfoDto;
|
||||
import com.lightyears.common.domain.entity.ClearanceLog;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import com.lightyears.basics.exception.BussinessException;
|
||||
import com.lightyears.basics.service.IClearanceLogService;
|
||||
import com.lightyears.basics.util.RedisCache;
|
||||
import com.lightyears.basics.util.StaticUtil;
|
||||
import org.springframework.data.redis.core.BoundZSetOperations;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-06-02
|
||||
*/
|
||||
@Service
|
||||
public class ClearanceLogServiceImpl extends ServiceImpl<ClearanceLogMapper, ClearanceLog> implements IClearanceLogService {
|
||||
|
||||
@Resource
|
||||
private RedisCache redisCache;
|
||||
|
||||
@Override
|
||||
public void saveClearanceLog(Integer playerId, String gameData){
|
||||
BoundZSetOperations<String, Integer> operations = redisCache.redisTemplate.boundZSetOps(StaticUtil.CLEARANCE_RANK_LIST);
|
||||
Integer layersNum = operations.score(playerId).intValue() + 1;
|
||||
ClearanceLog clearanceLog = baseMapper.selectOne(new LambdaQueryWrapper<ClearanceLog>().eq(ClearanceLog::getPlayerId, playerId).eq(ClearanceLog::getLayersNum, layersNum).last("limit 1"));
|
||||
Date now = new Date();
|
||||
if(ObjectUtils.isEmpty(clearanceLog)){
|
||||
clearanceLog = new ClearanceLog();
|
||||
clearanceLog.setData(gameData);
|
||||
clearanceLog.setLayersNum(layersNum);
|
||||
clearanceLog.setPlayerId(playerId);
|
||||
clearanceLog.setCreateTime(now);
|
||||
clearanceLog.setLastUpdateTime(now);
|
||||
baseMapper.insert(clearanceLog);
|
||||
} else {
|
||||
clearanceLog.setData(gameData);
|
||||
clearanceLog.setLastUpdateTime(now);
|
||||
baseMapper.updateById(clearanceLog);
|
||||
}
|
||||
operations.add(clearanceLog.getPlayerId(), clearanceLog.getLayersNum());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerClearanceLogInfoDto getPlayer(Integer playerId, String playerName, Integer type){
|
||||
PlayerClearanceLogInfoDto dto = new PlayerClearanceLogInfoDto();
|
||||
dto.setPlayerName(playerName);
|
||||
BoundZSetOperations<String, Integer> bzo = redisCache.redisTemplate.boundZSetOps(StaticUtil.CLEARANCE_RANK_LIST);
|
||||
Set<Integer> set = bzo.rangeByScore(1D, 99999999999999D);
|
||||
// 从0开始
|
||||
Long rank = bzo.reverseRank(playerId);
|
||||
Double score = bzo.score(playerId);
|
||||
Set<Integer> overSet = bzo.rangeByScore(score, 99999999999999D);
|
||||
if (rank == null || score == null) {
|
||||
throw new BussinessException(MessageEnum.ERROR.getCode(), "暂无玩家的排名信息");
|
||||
}
|
||||
dto.setClearanceNum(score.intValue());
|
||||
dto.setPlayerId(playerId);
|
||||
Float rage = 0f;
|
||||
String text = StaticUtil.CLEARANCE_LOG_TEXT_HAVE;
|
||||
if(score.equals(0D)){
|
||||
rage = 0.00F;
|
||||
} else{
|
||||
if (type == 1) {
|
||||
rage = (set.size() - overSet.size())*1f/set.size()*100F;
|
||||
text = StaticUtil.CLEARANCE_LOG_TEXT_OVER;
|
||||
} else {
|
||||
rage = overSet.size()*1f/set.size()*100F;
|
||||
}
|
||||
}
|
||||
dto.setRankRate(String.format("%.3f",rage).concat("%"));
|
||||
dto.setRemark(String.format(text, dto.getRankRate()));
|
||||
return dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cachePlayerClearanceRank(){
|
||||
List<ClearanceRankDto> logs = this.getClearanceLogs();
|
||||
String key = StaticUtil.CLEARANCE_RANK_LIST;
|
||||
BoundZSetOperations<String, Integer> operations = redisCache.redisTemplate.boundZSetOps(key);
|
||||
redisCache.deleteByPrefix(key);
|
||||
for (ClearanceRankDto log: logs){
|
||||
operations.add(log.getPlayerId(), log.getLayersNum());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deletCacheByPlayerId(Integer playerId){
|
||||
String key = StaticUtil.CLEARANCE_RANK_LIST;
|
||||
BoundZSetOperations<String, Integer> operations = redisCache.redisTemplate.boundZSetOps(key);
|
||||
operations.remove(playerId);
|
||||
}
|
||||
|
||||
public List<ClearanceRankDto> getClearanceLogs(){
|
||||
List<ClearanceRankDto> logs = baseMapper.getPlayerClearanceLogs(null);
|
||||
return logs;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,462 @@
|
||||
package com.lightyears.basics.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.github.pagehelper.util.StringUtil;
|
||||
import com.google.common.collect.Interner;
|
||||
import com.google.common.collect.Interners;
|
||||
import com.lightyears.basics.exception.BussinessException;
|
||||
import com.lightyears.basics.mapper.*;
|
||||
import com.lightyears.basics.service.IClearanceLogService;
|
||||
import com.lightyears.basics.service.IGameSystemService;
|
||||
import com.lightyears.basics.service.ILogService;
|
||||
import com.lightyears.basics.service.IPlayerAssetsService;
|
||||
import com.lightyears.basics.util.RedisCache;
|
||||
import com.lightyears.basics.util.ResultUtil;
|
||||
import com.lightyears.basics.util.StaticUtil;
|
||||
import com.lightyears.common.domain.dto.OrdinaryRankDto;
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
import com.lightyears.common.domain.dto.SimplePlayerAssert;
|
||||
import com.lightyears.common.domain.entity.*;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.data.redis.core.BoundZSetOperations;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@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 IClearanceLogService clearanceLogService;
|
||||
@Resource
|
||||
private IGameSystemService gameSystemService;
|
||||
Interner<String> pool = Interners.newWeakInterner();
|
||||
private static final int AssetLimit = 999999;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ResModeBase touristlogin(String open_id) {
|
||||
//通过三方open_id 查询用户是否存在
|
||||
Player player = this.playerMapper.selectOne(new QueryWrapper<Player>().eq("open_id", open_id).last("limit 1"));
|
||||
Long time = System.currentTimeMillis() / 1000;
|
||||
//生成 该字段暂时启用
|
||||
String user_token = UUID.randomUUID().toString();
|
||||
if (null == player) {
|
||||
//极限操作 检验
|
||||
if (StaticUtil.goldSyn.containsKey(open_id)) {
|
||||
return ResultUtil.result(MessageEnum.MOTION_SAFEGUARD.getCode(), MessageEnum.MOTION_SAFEGUARD.getMessage());
|
||||
} else {
|
||||
StaticUtil.goldSyn.put(open_id, true);
|
||||
}
|
||||
player = Player.builder()
|
||||
//每次登陆刷新token
|
||||
.token(user_token)
|
||||
//账号密码暂不考虑,使用
|
||||
.user_name("saolei")
|
||||
.sex("男")
|
||||
.age(18)
|
||||
.open_id(open_id)
|
||||
.distric("")
|
||||
.status(1)
|
||||
.creation_time(time.intValue())
|
||||
.update_name_count(0)
|
||||
.user_gold(0)
|
||||
.user_rank(0)
|
||||
.local_id(-1)
|
||||
.build();
|
||||
int req = playerMapper.insert(player);
|
||||
if (req < 1) {
|
||||
return ResultUtil.result(MessageEnum.ADD_ERROR.getCode(), MessageEnum.ADD_ERROR.getMessage());
|
||||
}
|
||||
// 写入雷神之塔排名缓存
|
||||
String key = StaticUtil.CLEARANCE_RANK_LIST;
|
||||
BoundZSetOperations<String, Integer> operations = redisCache.redisTemplate.boundZSetOps(key);
|
||||
operations.add(player.getUser_id(), 0);
|
||||
|
||||
// 初始化资产
|
||||
PlayerAssets playerAsset = PlayerAssets.builder().playerId(player.getUser_id()).type(0).number(0).version(0L).build();
|
||||
playerAssetsService.save(playerAsset);
|
||||
|
||||
player.setNewUser(true);
|
||||
} else {
|
||||
if (player.getStatus() == 0){
|
||||
return ResultUtil.result(MessageEnum.LOGIN_USERNAME_ERROR.getCode(), MessageEnum.LOGIN_USERNAME_ERROR.getMessage());
|
||||
}
|
||||
//存在 更新最后登录时间
|
||||
Player upObject = Player.builder()
|
||||
//每次登陆刷新token
|
||||
.token(user_token)
|
||||
.user_id(player.getUser_id())
|
||||
.update_time(time.intValue()).build();
|
||||
int req = playerMapper.update(upObject, new QueryWrapper<Player>().eq("user_id", player.getUser_id()));
|
||||
if (req < 1) {
|
||||
return ResultUtil.result(MessageEnum.UPDATE_ERROR.getCode(), MessageEnum.UPDATE_ERROR.getMessage());
|
||||
}
|
||||
player.setNewUser(player.getUpdate_name_count() == 0);
|
||||
}
|
||||
StaticUtil.goldSyn.remove(open_id);
|
||||
player.setToken(user_token);
|
||||
// 获取用户资产
|
||||
List<SimplePlayerAssert> playerAsserts = playerAssetsService.getPlayerAssets(player.getUser_id());
|
||||
player.setPlayerAssets(playerAsserts);
|
||||
/**
|
||||
* 写入用户信息缓存,token缓存
|
||||
*/
|
||||
redisCache.setCacheObject(StaticUtil.ONLINE_USER_PUBLIC_KEY.concat(user_token), player, 1, TimeUnit.HOURS);
|
||||
redisCache.setCacheObject(StaticUtil.ONLINE_USER_TOKEN.concat(player.getUser_id().toString()),user_token,1, TimeUnit.HOURS);
|
||||
player.setOpen_id("");
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResModeBase checkName(String userName) {
|
||||
Long num = playerMapper.selectCount(new QueryWrapper<Player>().eq("user_name", userName));
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), num.compareTo(0L) == 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ResModeBase updateName(int userId, String userName) {
|
||||
//1 检查昵称修改次数
|
||||
int updaNameCount = playerMapper.selectById(userId).getUpdate_name_count();
|
||||
if (updaNameCount != 0) {
|
||||
throw new BussinessException(MessageEnum.GAME_UPDATE_ERROR_COUNT);
|
||||
}
|
||||
//1 修改
|
||||
Player upObject = Player.builder()
|
||||
.user_id(userId)
|
||||
.update_name_count(updaNameCount + 1
|
||||
).user_name(userName).build();
|
||||
int req = playerMapper.updateById(upObject);
|
||||
if (req < 1) {
|
||||
return ResultUtil.result(MessageEnum.UPDATE_ERROR.getCode(), MessageEnum.UPDATE_ERROR.getMessage());
|
||||
}
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResModeBase pushGoldImpl(Integer userId, int gold, int type, String remark){
|
||||
synchronized (pool.intern("gold-".concat(userId.toString()))) {
|
||||
return gameSystemService.pushGold(userId, gold, type, remark);
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResModeBase pullGoldImpl(Integer userId, int gold, int type, String remark){
|
||||
synchronized (pool.intern("gold-".concat(userId.toString()))) {
|
||||
return gameSystemService.pullGold(userId, gold, type, remark);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ResModeBase pullGold(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 num = 0;
|
||||
// 不存在用户的钱包数据则新增初始化钱包数据
|
||||
if(ObjectUtils.isEmpty(playerAssets)){
|
||||
playerAssets = PlayerAssets.builder().playerId(userId).type(0).number(0).version(0L).build();
|
||||
playerAssetsService.save(playerAssets);
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), 0);
|
||||
}
|
||||
if (playerAssets.getNumber() < gold) {
|
||||
return ResultUtil.result(MessageEnum.GAME_GOLD_PULL_MAX_ERROR.getCode(), String.format(MessageEnum.GAME_GOLD_PULL_MAX_ERROR.getMessage(), playerAssets.getNumber()));
|
||||
}
|
||||
//2 取出金币
|
||||
num = playerAssetsService.reduceGold(playerAssets.getId(), gold);
|
||||
if(num == -999){
|
||||
return ResultUtil.result(MessageEnum.GAME_GOLD_PULL_MAX_ERROR.getCode(), String.format(MessageEnum.GAME_GOLD_PULL_MAX_ERROR.getMessage(), playerAssets.getNumber()));
|
||||
}
|
||||
//3 写入变化记录
|
||||
assertLogMapper.insert(AssertLog.builder().playerId(userId).createDate(new Date()).assertChangeNum(-gold).assertType(type).remark(remark).build());
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), num);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResModeBase saveFileImpl(int userId, String record, Integer record_type) {
|
||||
if(StringUtil.isEmpty(record)){
|
||||
throw new BussinessException(MessageEnum.ERROR.getCode(), "数据存档异常:record is null! userId:".concat(String.valueOf(userId)).concat(",record_type: " + record_type));
|
||||
}
|
||||
synchronized (pool.intern(String.valueOf(userId))){
|
||||
return gameSystemService.saveFile(userId, record, record_type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ResModeBase saveFile(int userId, String record, Integer record_type) {
|
||||
Record recordData = null;
|
||||
Long time = System.currentTimeMillis() / 1000;
|
||||
//1 检查 用户存档信息
|
||||
List<Record> records = recordMapper.selectList(new QueryWrapper<Record>().eq("user_id", userId).eq("record_type", record_type));
|
||||
if (CollectionUtils.isEmpty(records)) { //没有存档信息
|
||||
recordData = Record.builder()
|
||||
.user_id(userId)
|
||||
.record_name("第一次存档信息")
|
||||
.record(record)
|
||||
.creation_time(time.intValue())
|
||||
.updata_time(time.intValue())
|
||||
.record_type(record_type)
|
||||
.build();
|
||||
int req = recordMapper.insert(recordData);
|
||||
if (req < 1) {
|
||||
throw new BussinessException(MessageEnum.ADD_ERROR);
|
||||
}
|
||||
} else {
|
||||
recordData = records.get(0);
|
||||
if (null != recordData) {
|
||||
recordData.setUpdata_time(time.intValue());
|
||||
recordData.setRecord(record);
|
||||
recordData.setRecord_name(recordData.getRecord_name());
|
||||
int req = recordMapper.updateById(recordData);
|
||||
if (req < 1) {
|
||||
throw new BussinessException(MessageEnum.UPDATE_ERROR);
|
||||
}
|
||||
} else {
|
||||
throw new BussinessException(MessageEnum.GAME_RECORD_ID_IS_NULL);
|
||||
}
|
||||
}
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResModeBase readFile(int userId, int record_type) {
|
||||
QueryWrapper thisQueryWrapper = new QueryWrapper<Record>().eq("user_id", userId);
|
||||
if (record_type != -1) {
|
||||
thisQueryWrapper.eq("record_type", record_type);
|
||||
}
|
||||
|
||||
List<Record> records = recordMapper.selectList(thisQueryWrapper);
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), records);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResModeBase saveLogImpl(Player player, Integer level, int game_time, float bvs3, float bv3, String video, String gameinfo, boolean nf) {
|
||||
if(level == null){
|
||||
throw new BussinessException(MessageEnum.ERROR.getCode(), "提交游戏记录异常:level is null! userId:".concat(String.valueOf(player.getUser_id())).concat(",record_type: "));
|
||||
}
|
||||
synchronized (pool.intern(String.valueOf(player.getUser_id()).concat("saveLog"))){
|
||||
return gameSystemService.saveLog(player, level, game_time, bvs3, bv3, video, gameinfo, nf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ResModeBase saveLog(Player player, Integer level, int game_time, float bvs3, float bv3, String video, String gameinfo, boolean nf) {
|
||||
if(level == null){
|
||||
throw new BussinessException(MessageEnum.ERROR.getCode(), "提交游戏记录异常:level is null! userId:".concat(String.valueOf(player.getUser_id())).concat(",record_type: "));
|
||||
}
|
||||
int req = -1;
|
||||
//1 检验是否存在记录
|
||||
Log isTrue = logService.getOne(new QueryWrapper<Log>().eq("user_id", player.getUser_id()).eq("level", level).orderByDesc("creation_time").last("limit 1"));
|
||||
String key = StaticUtil.RANK_LIST.concat(level.toString());
|
||||
BoundZSetOperations<String, OrdinaryRankDto> operations = redisCache.redisTemplate.boundZSetOps(key);
|
||||
Log data = Log.builder()
|
||||
.user_id(player.getUser_id())
|
||||
.creation_time(Integer.parseInt(System.currentTimeMillis() / 1000 + ""))
|
||||
.game_time(game_time)
|
||||
.bvs3(bvs3)
|
||||
.bv3(bv3)
|
||||
.video(video)
|
||||
.game_info(gameinfo)
|
||||
.level(level)
|
||||
.nf(nf)
|
||||
.build();
|
||||
|
||||
if (null != isTrue) {
|
||||
if (game_time < isTrue.getGame_time()) {
|
||||
data.setId(isTrue.getId());
|
||||
req = logService.updateById(data)?1:0;
|
||||
} else {
|
||||
req = 99;
|
||||
}
|
||||
} else {
|
||||
//存储
|
||||
req = logService.save(data)?1:0;
|
||||
}
|
||||
// 排除成绩不计入排行的用户
|
||||
if(req != 99 && player.getUser_gold() == 0){
|
||||
OrdinaryRankDto rankDto;
|
||||
// 正序
|
||||
Set<OrdinaryRankDto> sets = operations.range(0, -1);
|
||||
// 更新缓存
|
||||
try{
|
||||
rankDto = sets.stream().filter(obj -> obj.getUser_id().equals(player.getUser_id())).findFirst().get();
|
||||
} catch (NoSuchElementException ex){ // 捕获缓存未找到玩家信息异常
|
||||
rankDto = new OrdinaryRankDto();
|
||||
rankDto.setUser_id(player.getUser_id());
|
||||
rankDto.setUser_name(player.getUser_name());
|
||||
rankDto.setId(data.getId());
|
||||
}
|
||||
|
||||
BeanUtils.copyProperties(data, rankDto);
|
||||
// 直接添加进缓存,userId相同自动覆盖
|
||||
operations.add(rankDto, rankDto.getGame_time());
|
||||
}
|
||||
if (req < 1) {
|
||||
throw new BussinessException(MessageEnum.GAME_SAVE_LOG_ADD_ERROR);
|
||||
}
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResModeBase ranking(int pageIndex, int pageSize, int level) {
|
||||
Integer max = 999;
|
||||
if(level == -1){
|
||||
level = 0;
|
||||
max = 499;
|
||||
}
|
||||
BoundZSetOperations<String, OrdinaryRankDto> bzo = redisCache.redisTemplate.boundZSetOps(StaticUtil.RANK_LIST.concat(String.valueOf(level)));
|
||||
//创建Page类
|
||||
Page<OrdinaryRankDto> page = new Page(pageIndex, pageSize);
|
||||
List<OrdinaryRankDto> reuslts;
|
||||
if(bzo == null || bzo.size() == 0){
|
||||
reuslts = new ArrayList<OrdinaryRankDto>();
|
||||
} else {
|
||||
// 只取前1000名
|
||||
Set<OrdinaryRankDto> set = bzo.range(0, max);
|
||||
List<OrdinaryRankDto> reqData = new ArrayList<>();
|
||||
reqData.addAll(set);
|
||||
|
||||
//为Page类中的total属性赋值
|
||||
int total = reqData.size();
|
||||
page.setTotal(total);
|
||||
//计算当前需要显示的数据下标起始值
|
||||
int startIndex = (pageIndex - 1) * pageSize;
|
||||
int endIndex = Math.min(startIndex + pageSize,total);
|
||||
reuslts = reqData.subList(startIndex,endIndex);
|
||||
// 写排名
|
||||
for(OrdinaryRankDto map: reuslts){
|
||||
map.setRanking(startIndex);
|
||||
startIndex ++;
|
||||
}
|
||||
}
|
||||
|
||||
//从链表中截取需要显示的子链表,并加入到Page
|
||||
page.addAll(reuslts);
|
||||
|
||||
//以Page创建PageInfo
|
||||
PageInfo pageInfo = new PageInfo<>(page);
|
||||
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), pageInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResModeBase log(int userId, int level) {
|
||||
if(level == -1){
|
||||
level = 0;
|
||||
}
|
||||
String key = StaticUtil.RANK_LIST.concat(String.valueOf(level));
|
||||
BoundZSetOperations<String, OrdinaryRankDto> bzo = redisCache.redisTemplate.boundZSetOps(key);
|
||||
OrdinaryRankDto dto = null;
|
||||
if (bzo != null || bzo.size() > 0){
|
||||
// 正序 只取前1000
|
||||
Set<OrdinaryRankDto> sets = bzo.range(0, -1);
|
||||
if(sets == null || sets.size() == 0){
|
||||
dto = null;
|
||||
}else {
|
||||
List<OrdinaryRankDto> reqData = new ArrayList<>();
|
||||
reqData.addAll(sets);
|
||||
for(int i = 0; i < reqData.size(); i ++){
|
||||
OrdinaryRankDto obj = reqData.get(i);
|
||||
if(obj.getUser_id().equals(userId)){
|
||||
dto = obj;
|
||||
dto.setRanking(i +1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResModeBase getGameData(Integer id, Integer type){
|
||||
String gameData = "";
|
||||
if(type == 1){
|
||||
Log log = logService.getById(id);
|
||||
if(!ObjectUtils.isEmpty(log)){
|
||||
gameData = log.getVideo();
|
||||
}
|
||||
} else if (type == 2){
|
||||
ListRank listRank =listRankMapper.selectById(id);
|
||||
if(!ObjectUtils.isEmpty(listRank)){
|
||||
gameData = listRank.getGameData();
|
||||
}
|
||||
}
|
||||
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), gameData);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void cancellationAccount(Integer userId) {
|
||||
// 删除排行榜缓存数据.
|
||||
logService.deleteCacheByUserId(userId);
|
||||
// 删除雷神之塔缓存数据
|
||||
clearanceLogService.deletCacheByPlayerId(userId);
|
||||
|
||||
// sl_assert_log 资产日志
|
||||
assertLogMapper.delete(new UpdateWrapper<AssertLog>().eq("player_id", userId));
|
||||
// sl_log 游戏日志
|
||||
logService.remove(new UpdateWrapper<Log>().eq("user_id", userId));
|
||||
// sl_notic 公告
|
||||
noticeMapper.delete(new UpdateWrapper<Notice>().eq("player_id", userId));
|
||||
// sl_player_assets 用户资产
|
||||
playerAssetsService.remove(new UpdateWrapper<PlayerAssets>().eq("player_id", userId));
|
||||
// sl_record 用户游戏数据记录
|
||||
recordMapper.delete(new UpdateWrapper<Record>().eq("user_id", userId));
|
||||
// sl_player 用户
|
||||
playerMapper.deleteById(userId);
|
||||
// sl_clearance_log 通关日志
|
||||
clearanceLogService.remove(new LambdaQueryWrapper<ClearanceLog>().eq(ClearanceLog::getPlayerId, userId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.lightyears.basics.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.lightyears.basics.mapper.LogMapper;
|
||||
import com.lightyears.common.domain.dto.OrdinaryRankDto;
|
||||
import com.lightyears.common.domain.entity.Log;
|
||||
import com.lightyears.basics.service.ILogService;
|
||||
import com.lightyears.basics.util.RedisCache;
|
||||
import com.lightyears.basics.util.StaticUtil;
|
||||
import org.springframework.data.redis.core.BoundZSetOperations;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 游戏 完成记录 表 游戏难度:1 - 普通 2 困难 3 大师 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-09
|
||||
*/
|
||||
@Service
|
||||
public class LogServiceImpl extends ServiceImpl<LogMapper, Log> implements ILogService {
|
||||
@Resource
|
||||
private RedisCache redisCache;
|
||||
|
||||
@Override
|
||||
public List<OrdinaryRankDto> getRankList(Integer level){
|
||||
List<OrdinaryRankDto> reqData = new ArrayList<>();
|
||||
if (level == -1) {//查询综合
|
||||
reqData = baseMapper.syntheticalPaging();
|
||||
} else {
|
||||
reqData = baseMapper.paging(level, -1);
|
||||
}
|
||||
return reqData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCacheByUserId(Integer userId){
|
||||
deleteCacheByRankUserId(0, userId);
|
||||
deleteCacheByRankUserId(1, userId);
|
||||
deleteCacheByRankUserId(2, userId);
|
||||
deleteCacheByRankUserId(3, userId);
|
||||
deleteCacheByRankUserId(4, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cacheRankList(Integer level){
|
||||
if(level == null){
|
||||
// -1 - 综合
|
||||
List<OrdinaryRankDto> zh = getRankList(-1);
|
||||
cacheRankListItem(zh, 0);
|
||||
// 1 - 普通
|
||||
List<OrdinaryRankDto> zh1 = getRankList(1);
|
||||
cacheRankListItem(zh1, 1);
|
||||
// 2 困难
|
||||
List<OrdinaryRankDto> zh2 = getRankList(2);
|
||||
cacheRankListItem(zh2, 2);
|
||||
// 3 大师
|
||||
List<OrdinaryRankDto> zh3 = getRankList(3);
|
||||
cacheRankListItem(zh3, 3);
|
||||
// 4 超凡
|
||||
List<OrdinaryRankDto> zh4 = getRankList(4);
|
||||
cacheRankListItem(zh4, 4);
|
||||
} else if(level == -1) { // 刷新综合榜数据
|
||||
// -1 - 综合
|
||||
List<OrdinaryRankDto> zh = getRankList(-1);
|
||||
cacheRankListItem(zh, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void cacheRankListItem(List<OrdinaryRankDto> list, Integer level){
|
||||
String key = StaticUtil.RANK_LIST.concat(level.toString());
|
||||
redisCache.deleteByPrefix(key);
|
||||
BoundZSetOperations<String, OrdinaryRankDto> operations = redisCache.redisTemplate.boundZSetOps(key);
|
||||
for (OrdinaryRankDto item : list){
|
||||
operations.add(item, item.getGame_time());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void deleteCacheByRankUserId(Integer level, Integer userId){
|
||||
String key = StaticUtil.RANK_LIST.concat(level.toString());
|
||||
BoundZSetOperations<String, OrdinaryRankDto> operations = redisCache.redisTemplate.boundZSetOps(key);
|
||||
if (operations != null && operations.size() > 0){
|
||||
Set<OrdinaryRankDto> sets = operations.range(0, -1);
|
||||
if(sets != null && sets.size() > 0){
|
||||
Optional<OrdinaryRankDto> dto = sets.stream().filter(obj -> obj.getUser_id().equals(userId)).findFirst();
|
||||
if(dto != null && dto.isPresent()){
|
||||
operations.remove(dto.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.lightyears.basics.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.lightyears.common.domain.dto.NoticeDto;
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
import com.lightyears.common.domain.entity.Notice;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import com.lightyears.basics.mapper.NoticeMapper;
|
||||
import com.lightyears.basics.service.INoticeService;
|
||||
import com.lightyears.basics.util.ResultUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hellor
|
||||
* @since 2022-03-18
|
||||
*/
|
||||
@Service(value = "noticeServiceImpl")
|
||||
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
|
||||
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements INoticeService {
|
||||
|
||||
|
||||
@Override
|
||||
public ResModeBase getList(Integer playerId){
|
||||
// List<NoticeDto> results = new ArrayList<>();
|
||||
List<NoticeDto> systemNotice = this.baseMapper.getList(null, playerId);
|
||||
// List<NoticeDto> myNotice = this.baseMapper.getList(1, playerId);
|
||||
// if (!CollectionUtils.isEmpty(systemNotice)){
|
||||
// results.add(systemNotice.get(0));
|
||||
// }
|
||||
// if (!CollectionUtils.isEmpty(myNotice)){
|
||||
// results.addAll(myNotice);
|
||||
// }
|
||||
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), systemNotice);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResModeBase getContent(Integer id){
|
||||
String content = this.baseMapper.getContent(id);
|
||||
// 设置已读
|
||||
this.baseMapper.updateById(Notice.builder().id(id).status(1).build());
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage(), content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteNoticeForTask(){
|
||||
List<Notice> notices = this.baseMapper.selectList(new LambdaQueryWrapper<Notice>().select(Notice::getId, Notice::getExpirationDay, Notice::getCreateDate).isNotNull(Notice::getExpirationDay));
|
||||
if (CollectionUtils.isEmpty(notices))
|
||||
return;
|
||||
Date now = new Date();
|
||||
List<Integer> ids = new ArrayList<>();
|
||||
notices.forEach(notice -> {
|
||||
Date date = DateUtil.offsetDay(notice.getCreateDate(), notice.getExpirationDay());
|
||||
if(DateUtil.compare(now, date) > -1){
|
||||
ids.add(notice.getId());
|
||||
}
|
||||
});
|
||||
|
||||
if(ids.size() < 1)
|
||||
return;
|
||||
baseMapper.deleteBatchIds(ids);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.lightyears.basics.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.lightyears.basics.mapper.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.basics.exception.BussinessException;
|
||||
import com.lightyears.basics.service.IPlayerAssetsService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
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.basics.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.lightyears.basics.mapper.PlayerMapper;
|
||||
import com.lightyears.common.domain.entity.Player;
|
||||
import com.lightyears.basics.service.IPlayerService;
|
||||
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.basics.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.lightyears.basics.mapper.RecordMapper;
|
||||
import com.lightyears.common.domain.entity.Record;
|
||||
import com.lightyears.basics.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,101 @@
|
||||
package com.lightyears.basics.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.lightyears.common.domain.dto.ResModeBase;
|
||||
import com.lightyears.common.domain.entity.Notice;
|
||||
import com.lightyears.common.domain.entity.PlayerAssets;
|
||||
import com.lightyears.common.domain.enums.MessageEnum;
|
||||
import com.lightyears.basics.service.INoticeService;
|
||||
import com.lightyears.basics.service.IPlayerAssetsService;
|
||||
import com.lightyears.basics.service.ISystemService;
|
||||
import com.lightyears.basics.util.BatchInsertThread;
|
||||
import com.lightyears.basics.util.ResultUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
|
||||
public class SystemServiceImpl implements ISystemService {
|
||||
private final INoticeService noticeService;
|
||||
private final IPlayerAssetsService playerAssetsService;
|
||||
|
||||
@Override
|
||||
public ResModeBase publishNotice(Notice notice){
|
||||
List<PlayerAssets> players = playerAssetsService.list(new LambdaQueryWrapper<PlayerAssets>().select(PlayerAssets::getPlayerId).eq(PlayerAssets::getType, 0));
|
||||
if(CollectionUtils.isEmpty(players))
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage());
|
||||
Date now = new Date();
|
||||
|
||||
List<Notice> notices = new ArrayList<>();
|
||||
players.stream().forEach(player -> {
|
||||
Notice obj = new Notice();
|
||||
obj.setContent(notice.getContent());
|
||||
obj.setTitle(notice.getTitle());
|
||||
obj.setType(0);
|
||||
obj.setPlayerId(player.getPlayerId());
|
||||
obj.setStatus(0);
|
||||
obj.setCreateDate(now);
|
||||
notices.add(obj);
|
||||
});
|
||||
//一个线程处理200条数据
|
||||
int count = 2000;
|
||||
//数据集合大小
|
||||
int listSize = notices.size();
|
||||
//开启的线程数
|
||||
int runSize = (listSize / count) + 1;
|
||||
//存放每个线程的执行数据
|
||||
List<Notice> newlist = null;
|
||||
|
||||
//创建一个线程池,数量和开启线程的数量一样
|
||||
//Executors 的写法
|
||||
// ExecutorService executor = Executors.newFixedThreadPool(runSize);
|
||||
|
||||
//ThreadPoolExecutor的写法
|
||||
ThreadPoolExecutor executor = new ThreadPoolExecutor(runSize, runSize, 1,
|
||||
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),
|
||||
new ThreadPoolExecutor.DiscardOldestPolicy());
|
||||
|
||||
//创建两个个计数器
|
||||
CountDownLatch begin = new CountDownLatch(1);
|
||||
CountDownLatch end = new CountDownLatch(runSize);
|
||||
try {
|
||||
//循环创建线程
|
||||
for (int i = 0; i < runSize; i++) {
|
||||
//计算每个线程执行的数据
|
||||
if ((i + 1) == runSize) {
|
||||
int startIndex = (i * count);
|
||||
int endIndex = notices.size();
|
||||
newlist = notices.subList(startIndex, endIndex);
|
||||
} else {
|
||||
int startIndex = (i * count);
|
||||
int endIndex = (i + 1) * count;
|
||||
newlist = notices.subList(startIndex, endIndex);
|
||||
}
|
||||
//线程类
|
||||
BatchInsertThread mythead = new BatchInsertThread(newlist, begin, end, noticeService);
|
||||
//这里执行线程的方式是调用线程池里的executor.execute(mythead)方法。
|
||||
executor.execute(mythead);
|
||||
}
|
||||
begin.countDown();
|
||||
end.await();
|
||||
}catch (Exception e){
|
||||
log.error("发布公告异常:", e);
|
||||
} finally {
|
||||
//执行完关闭线程池
|
||||
executor.shutdown();
|
||||
}
|
||||
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.lightyears.basics.util;
|
||||
|
||||
import com.lightyears.common.domain.entity.Notice;
|
||||
import com.lightyears.basics.service.INoticeService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class BatchInsertThread implements Runnable {
|
||||
|
||||
public BatchInsertThread() {
|
||||
}
|
||||
|
||||
INoticeService noticeService;
|
||||
private List<Notice> list;
|
||||
private CountDownLatch begin;
|
||||
private CountDownLatch end;
|
||||
|
||||
/**
|
||||
* 方法名: ImportThread
|
||||
* 方法描述: 创建个构造函数初始化 list,和其他用到的参数
|
||||
* @throws
|
||||
*/
|
||||
public BatchInsertThread(List<Notice> list, CountDownLatch begin, CountDownLatch end,INoticeService noticeService) {
|
||||
this.list = list;
|
||||
this.begin = begin;
|
||||
this.end = end;
|
||||
this.noticeService=noticeService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
//执行完让线程直接进入等待
|
||||
noticeService.saveBatch(list);
|
||||
begin.await();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
//这里要主要了,当一个线程执行完 了计数要减一不然这个线程会被一直挂起
|
||||
//这个方法就是直接把计数器减一的
|
||||
end.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.lightyears.basics.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.basics.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.basics.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];
|
||||
}
|
||||
|
||||
}
|
||||
231
basics/src/main/java/com/lightyears/basics/util/RedisCache.java
Normal file
231
basics/src/main/java/com/lightyears/basics/util/RedisCache.java
Normal file
@@ -0,0 +1,231 @@
|
||||
package com.lightyears.basics.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.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
|
||||
public RedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* 判断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数据
|
||||
*
|
||||
* @param key 缓存的键值
|
||||
* @return 缓存的对象
|
||||
*/
|
||||
public <T> long setCacheList(final String key, final List<T> dataList) {
|
||||
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
|
||||
return count == null ? 0 : count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得缓存的list对象
|
||||
*
|
||||
* @param key 缓存的键值
|
||||
* @return 缓存键值对应的数据
|
||||
*/
|
||||
public <T> List<T> getCacheList(final String key) {
|
||||
return redisTemplate.opsForList().range(key, 0, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.lightyears.basics.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.basics.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.basics.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.basics.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
basics/src/main/resources/application-dev.yml
Normal file
67
basics/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-basic
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
allow-circular-references: true
|
||||
# 全局配置响应日期格式和时区为东八区,解决日期类型返回前端少八个小时的问题
|
||||
jackson:
|
||||
time-zone: GMT+8
|
||||
datasource:
|
||||
username: root
|
||||
password: 43626546
|
||||
url: jdbc:mysql://localhost: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
basics/src/main/resources/application-prod.yml
Normal file
73
basics/src/main/resources/application-prod.yml
Normal file
@@ -0,0 +1,73 @@
|
||||
qbs-switch:
|
||||
swagger-open: true #swagger开关(true:打开, false:关闭)
|
||||
spring:
|
||||
application:
|
||||
name: mine-clearance-basic
|
||||
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://127.0.0.1:3306/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
|
||||
# Redis数据库索引(默认为0)
|
||||
database: 0
|
||||
# Redis服务器连接端口
|
||||
port: 6379
|
||||
# Redis服务器连接密码(默认为空)
|
||||
# password: 1476346288@redis
|
||||
password: 123456
|
||||
# 连接超时时间
|
||||
timeout: 1000ms
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池最大连接数
|
||||
max-active: 8
|
||||
# 连接池最大空闲连接数
|
||||
max-idle: 8
|
||||
# 连接池最小空闲连接数
|
||||
min-idle: 0
|
||||
# 连接池最大阻塞等待时间,负值表示没有限制
|
||||
# max-wait: -1ms
|
||||
max-wait: 3
|
||||
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
|
||||
11
basics/src/main/resources/application.yml
Normal file
11
basics/src/main/resources/application.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
server:
|
||||
port: 18633
|
||||
tomcat:
|
||||
uri-encoding: UTF-8
|
||||
logging:
|
||||
config: classpath:log.xml
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
appconfig:
|
||||
version: 197.0
|
||||
51
basics/src/main/resources/log.xml
Normal file
51
basics/src/main/resources/log.xml
Normal file
@@ -0,0 +1,51 @@
|
||||
<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/basics/sys.log</File>
|
||||
<!-- rollingPolicy:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。 -->
|
||||
<!-- TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 活动文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
|
||||
<!-- 文件名:log/sys.2022-3-09.0.log -->
|
||||
<fileNamePattern>logs/basics/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>
|
||||
|
||||
<!-- 控制台输出日志级别 -->
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
<!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
|
||||
<!-- com.lightyears为根包,也就是只要是发生在这个根包下面的所有日志操作行为的权限都是DEBUG -->
|
||||
<!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE -->
|
||||
<logger name="com.lightyears.basics" level="DEBUG">
|
||||
<appender-ref ref="syslog" />
|
||||
</logger>
|
||||
</configuration>
|
||||
5
basics/src/main/resources/mapper/AssertLogMapper.xml
Normal file
5
basics/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.basics.mapper.AssertLogMapper">
|
||||
|
||||
</mapper>
|
||||
19
basics/src/main/resources/mapper/ClearanceLogMapper.xml
Normal file
19
basics/src/main/resources/mapper/ClearanceLogMapper.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?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.basics.mapper.ClearanceLogMapper">
|
||||
<select id="getPlayerClearanceLogs" resultType="com.lightyears.common.domain.dto.ClearanceRankDto">
|
||||
SELECT
|
||||
p.user_id as playerId,
|
||||
ifnull( max( l.layers_num ), 0 ) AS layersNum
|
||||
FROM
|
||||
sl_player p
|
||||
left join sl_clearance_log l on l.player_id = p.user_id
|
||||
<where>
|
||||
<if test="userId != null and userId > 0">
|
||||
and p.user_id = ${userId}
|
||||
</if>
|
||||
</where>
|
||||
group by p.user_id
|
||||
ORDER BY layersNum desc
|
||||
</select>
|
||||
</mapper>
|
||||
79
basics/src/main/resources/mapper/ListRankMapper.xml
Normal file
79
basics/src/main/resources/mapper/ListRankMapper.xml
Normal file
@@ -0,0 +1,79 @@
|
||||
<?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.basics.mapper.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
|
||||
LEFT JOIN sl_list_instance n on n.id = r.instance_id
|
||||
<where>
|
||||
<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>
|
||||
</where>
|
||||
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>
|
||||
126
basics/src/main/resources/mapper/LogMapper.xml
Normal file
126
basics/src/main/resources/mapper/LogMapper.xml
Normal file
@@ -0,0 +1,126 @@
|
||||
<?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.basics.mapper.LogMapper">
|
||||
<select id="paging" resultType="com.lightyears.common.domain.dto.OrdinaryRankDto">
|
||||
SELECT
|
||||
a.id,
|
||||
a.user_id,
|
||||
a.game_time,
|
||||
a.bv3,
|
||||
a.bvs3,
|
||||
a.nf,
|
||||
s.user_name
|
||||
FROM
|
||||
sl_log a
|
||||
LEFT JOIN sl_player s ON s.user_id = a.user_id
|
||||
where a.level = #{level}
|
||||
<if test="userId != null and userId > 0">
|
||||
and a.user_id = ${userId}
|
||||
</if>
|
||||
and s.user_gold = 0
|
||||
ORDER BY a.game_time
|
||||
limit 1000
|
||||
</select>
|
||||
|
||||
<select id="syntheticalPaging" resultType="com.lightyears.common.domain.dto.OrdinaryRankDto">
|
||||
SELECT
|
||||
a.user_id user_id,
|
||||
SUM( a.game_time ) game_time,
|
||||
SUM( bv3 ) bv3,
|
||||
SUM( bvs3 ) bvs3,
|
||||
s.user_name,
|
||||
0 nf
|
||||
FROM
|
||||
sl_log a
|
||||
LEFT JOIN sl_player s ON s.user_id = a.user_id
|
||||
WHERE
|
||||
a.user_id IN (
|
||||
SELECT
|
||||
t.user_id
|
||||
FROM
|
||||
( SELECT user_id, count( LEVEL ) count_level FROM sl_log WHERE LEVEL in (1, 2 ,3) GROUP BY user_id ) t
|
||||
WHERE
|
||||
t.count_level >= 3
|
||||
)
|
||||
AND a.LEVEL in (1, 2 ,3)
|
||||
and s.user_gold = 0
|
||||
GROUP BY
|
||||
a.user_id
|
||||
ORDER BY
|
||||
game_time
|
||||
limit 500
|
||||
</select>
|
||||
|
||||
<select id="getComprehensiveRankByUserId" parameterType="Integer" resultType="java.util.Map">
|
||||
SELECT
|
||||
m.*
|
||||
from ( SELECT q.*,( @i := @i + 1 ) ranking
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
a.user_id user_id,
|
||||
SUM( a.game_time ) game_time,
|
||||
SUM( bv3 ) bv3,
|
||||
SUM( bvs3 ) bvs3,
|
||||
s.user_name,
|
||||
0 nf
|
||||
FROM
|
||||
sl_log a
|
||||
LEFT JOIN sl_player s ON s.user_id = a.user_id
|
||||
WHERE
|
||||
a.user_id IN (
|
||||
SELECT
|
||||
t.user_id
|
||||
FROM
|
||||
( SELECT user_id, count( LEVEL ) count_level FROM sl_log WHERE LEVEL in (1, 2 ,3) GROUP BY user_id ) t
|
||||
WHERE
|
||||
t.count_level >= 3
|
||||
)
|
||||
AND a.LEVEL in (1, 2 ,3)
|
||||
and s.user_gold = 0
|
||||
GROUP BY
|
||||
a.user_id
|
||||
) q,
|
||||
( SELECT @i := 0 ) t2
|
||||
ORDER BY
|
||||
q.game_time
|
||||
) m where user_id = #{userId}
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<select id="getRankByLevelUserId" resultType="java.util.Map">
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
( @i := @i + 1 ) ranking,
|
||||
x.*
|
||||
FROM
|
||||
( SELECT @i := 0 ) t2,
|
||||
(
|
||||
SELECT
|
||||
a.id,
|
||||
a.user_id,
|
||||
a.game_time,
|
||||
a.bv3,
|
||||
a.bvs3,
|
||||
a.nf,
|
||||
s.user_name,
|
||||
a.creation_time
|
||||
FROM
|
||||
sl_log a
|
||||
LEFT JOIN sl_player s ON s.user_id = a.user_id
|
||||
WHERE
|
||||
a.LEVEL = #{level}
|
||||
and s.user_gold = 0
|
||||
) x
|
||||
ORDER BY
|
||||
x.game_time ASC,
|
||||
x.creation_time ASC
|
||||
) m
|
||||
WHERE
|
||||
m.user_id = #{userId}
|
||||
limit 1
|
||||
</select>
|
||||
</mapper>
|
||||
31
basics/src/main/resources/mapper/NoticeMapper.xml
Normal file
31
basics/src/main/resources/mapper/NoticeMapper.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?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.basics.mapper.NoticeMapper">
|
||||
<select id="getList" resultType="com.lightyears.common.domain.dto.NoticeDto">
|
||||
SELECT
|
||||
id,
|
||||
title,
|
||||
type,
|
||||
`status`,
|
||||
create_date as createDate
|
||||
FROM
|
||||
sl_notice
|
||||
WHERE
|
||||
`status` IN (0, 1)
|
||||
<if test="type != null and type > -1">
|
||||
and type = #{type}
|
||||
</if>
|
||||
<if test="playerId != null and playerId > 0">
|
||||
and player_id = #{playerId}
|
||||
</if>
|
||||
order by create_date desc
|
||||
</select>
|
||||
<select id="getContent" resultType="String">
|
||||
SELECT
|
||||
content
|
||||
FROM
|
||||
sl_notice
|
||||
WHERE
|
||||
id = #{id}
|
||||
</select>
|
||||
</mapper>
|
||||
14
basics/src/main/resources/mapper/PlayerAssetsMapper.xml
Normal file
14
basics/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.basics.mapper.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>
|
||||
11
basics/src/main/resources/mapper/PlayerMapper.xml
Normal file
11
basics/src/main/resources/mapper/PlayerMapper.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?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.basics.mapper.PlayerMapper">
|
||||
<update id="setInactivePlayer">
|
||||
update sl_player set user_gold = 1 where update_time <= ${dateNum};
|
||||
|
||||
</update>
|
||||
<update id="setActivePlayer">
|
||||
update sl_player set user_gold = 0 where update_time > ${dateNum};
|
||||
</update>
|
||||
</mapper>
|
||||
5
basics/src/main/resources/mapper/RecordMapper.xml
Normal file
5
basics/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.basics.mapper.RecordMapper">
|
||||
|
||||
</mapper>
|
||||
25
basics/src/test/java/com/lightyears/basics/BasicsTests.java
Normal file
25
basics/src/test/java/com/lightyears/basics/BasicsTests.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package com.lightyears.basics;
|
||||
|
||||
import com.lightyears.basics.service.INoticeService;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = BasicsApp.class)
|
||||
public class BasicsTests {
|
||||
|
||||
@Resource
|
||||
private INoticeService noticeService;
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
// ResModeBase dto = systemService.publishNotice(Notice.builder().title("服务器停机维护通知").content("为了保障更好的在线游戏服务,扫雷F服务器将在2022年10月2日 03:00~05:00进行停机维护,届时将停止所有在线服务!").build());
|
||||
|
||||
noticeService.deleteNoticeForTask();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user