项目上传

This commit is contained in:
2025-03-20 22:05:58 +08:00
commit e7bab0d002
278 changed files with 14221 additions and 0 deletions

146
mainland/pom.xml Normal file
View 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>
<artifactId>mainland</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<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>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</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>mainland</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>

View File

@@ -0,0 +1,19 @@
package com.lightyears.mainland;
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 MainlandApp {
public static void main(String[] args) {
// 设置时区
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
SpringApplication.run(MainlandApp.class, args);
}
}

View File

@@ -0,0 +1,9 @@
package com.lightyears.mainland.annotation;
import java.lang.annotation.*;
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataVerification {
}

View File

@@ -0,0 +1,65 @@
package com.lightyears.mainland.aspect;
import cn.hutool.crypto.digest.MD5;
import com.github.pagehelper.util.StringUtil;
import com.lightyears.common.domain.enums.MessageEnum;
import com.lightyears.mainland.exception.GlobalException;
import com.lightyears.mainland.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.mainland.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);
}
}
}

View File

@@ -0,0 +1,16 @@
package com.lightyears.mainland.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;
}

View File

@@ -0,0 +1,55 @@
package com.lightyears.mainland.controller;
import com.lightyears.common.domain.entity.Player;
import com.lightyears.mainland.util.RedisCache;
import com.lightyears.mainland.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;
}
}

View File

@@ -0,0 +1,14 @@
package com.lightyears.mainland.controller;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@CrossOrigin
@RestController
@RequiredArgsConstructor
@RequestMapping("/mainland")
public class MainlandController {
}

View File

@@ -0,0 +1,18 @@
package com.lightyears.mainland.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);
}
}

View File

@@ -0,0 +1,46 @@
package com.lightyears.mainland.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;
}
}

View File

@@ -0,0 +1,26 @@
package com.lightyears.mainland.exception;
import com.lightyears.common.domain.dto.ResModeBase;
import com.lightyears.common.domain.enums.MessageEnum;
import com.lightyears.mainland.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());
}
}
}

View File

@@ -0,0 +1,119 @@
package com.lightyears.mainland.filter;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.util.StringUtil;
import com.lightyears.common.domain.entity.Player;
import com.lightyears.common.domain.enums.MessageEnum;
import com.lightyears.mainland.config.AppConfig;
import com.lightyears.mainland.util.RedisCache;
import com.lightyears.mainland.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));
}
}

View File

@@ -0,0 +1,33 @@
package com.lightyears.mainland.init;
import com.lightyears.mainland.service.IMainlandLogService;
import com.lightyears.mainland.service.IPlayerIntegralService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
;
/**
* 雷神大陆模式数据初始化
*/
@Component
@RequiredArgsConstructor
public class MainlandDataInit {
private final IPlayerIntegralService playerIntegralService;
private final IMainlandLogService mainlandLogService;
@PostConstruct
public void init() {
// 写入积分排行榜缓存
playerIntegralService.initRankList(mainlandLogService.getRankThreshold());
}
@PreDestroy
public void destroy() {
// 写入持久层
}
}

View File

@@ -0,0 +1,12 @@
package com.lightyears.mainland.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lightyears.common.domain.entity.MainlandLog;
import org.apache.ibatis.annotations.Mapper;
/**
* 雷神大陆数据记录
*/
@Mapper
public interface MainlandLogMapper extends BaseMapper<MainlandLog> {
}

View File

@@ -0,0 +1,12 @@
package com.lightyears.mainland.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lightyears.common.domain.entity.PlayerIntegralDetail;
import org.apache.ibatis.annotations.Mapper;
/**
* 玩家积分明细表mapper
*/
@Mapper
public interface PlayerIntegralDetailMapper extends BaseMapper<PlayerIntegralDetail> {
}

View File

@@ -0,0 +1,22 @@
package com.lightyears.mainland.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lightyears.common.domain.entity.PlayerIntegral;
import com.lightyears.common.domain.dto.RankInitModel;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 玩家积分表mapper
*/
@Mapper
public interface PlayerIntegralMapper extends BaseMapper<PlayerIntegral> {
/**
* 获取排行榜列表
* @param beginNum
* @return
*/
List<RankInitModel> getIntegralRank(@Param("beginNum") Integer beginNum);
}

View File

@@ -0,0 +1,18 @@
package com.lightyears.mainland.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lightyears.common.domain.entity.Player;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 扫雷玩家表 Mapper 接口
* </p>
*
* @author hellor
* @since 2022-03-09
*/
@Mapper
public interface PlayerMapper extends BaseMapper<Player> {
}

View File

@@ -0,0 +1,28 @@
package com.lightyears.mainland.schedule;
import com.lightyears.common.domain.dto.RankModel;
import com.lightyears.mainland.util.RedisCache;
import com.lightyears.mainland.util.StaticUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundZSetOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
public class MainlandTask {
private final RedisCache redisCache;
/**
* 每日 0点执行 清空积分增长日榜
*/
@Scheduled(cron = "0 0 0 * * ?")
public void deleteNotices(){
BoundZSetOperations<String, RankModel> operations = redisCache.redisTemplate.boundZSetOps(StaticUtil.MAINLAND_DAY_RANK);
operations.removeRange(0, -1);
}
}

View File

@@ -0,0 +1,65 @@
package com.lightyears.mainland.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.github.pagehelper.PageInfo;
import com.lightyears.common.domain.dto.MainLandRankInfoDto;
import com.lightyears.common.domain.dto.RankDto;
import com.lightyears.common.domain.dto.RankModel;
import com.lightyears.common.domain.dto.ResModeBase;
import com.lightyears.common.domain.entity.MainlandLog;
import com.lightyears.common.domain.entity.Player;
import java.util.Set;
public interface IMainlandLogService extends IService<MainlandLog> {
/**
* 游戏数据保存
* @param player 玩家信息
* @param level 等级
* @param game_time 游戏时间
* @param bvs3
* @param bv3
* @param video
* @param gameinfo
* @param nf
* @param integralNum 积分操作数量
* @return
*/
ResModeBase saveMainlandLog(Player player, Integer level, int game_time, float bvs3, float bv3, String video, String gameinfo, boolean nf, int integralNum);
/**
* 获取进入排行版的积分数量门槛值
* @return
*/
Integer getRankThreshold();
/**
* 获取玩家积分及排名信息
* @param rankModel
* @return
*/
MainLandRankInfoDto getPlayerRankInfo(RankModel rankModel);
/**
* 获取录像数据
* @param playerId 玩家id
* @return
*/
String getMainlandGameInfo(Integer playerId);
/**
* 获取日积分增长榜
* @param pageIndex 页码
* @param pageSize 页大小
* @return
*/
PageInfo getDayRank(int pageIndex, int pageSize);
/**
* 获取我的排名上下范围内的玩家列表
* @param rankModel 玩家信息
* @param rangeNum 范围值
* @return
*/
Set<RankDto> getRankRangeList(RankModel rankModel, int rangeNum);
}

View File

@@ -0,0 +1,10 @@
package com.lightyears.mainland.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.lightyears.common.domain.entity.PlayerIntegralDetail;
/**
* 玩家积分明细service
*/
public interface IPlayerIntegralDetailService extends IService<PlayerIntegralDetail> {
}

View File

@@ -0,0 +1,24 @@
package com.lightyears.mainland.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.lightyears.common.domain.entity.PlayerIntegral;
/**
* 玩家积分service
*/
public interface IPlayerIntegralService extends IService<PlayerIntegral> {
/**
* 积分加/减操作
* @param num 操作数量
* @param playerId 玩家id
* @param remark 操作备注
* @return
*/
int saveIntegral(Integer num, Integer playerId, String remark);
/**
* 积分排名列表
* @param beginNum 门槛值
*/
void initRankList(Integer beginNum);
}

View File

@@ -0,0 +1,191 @@
package com.lightyears.mainland.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.lightyears.common.domain.dto.MainLandRankInfoDto;
import com.lightyears.common.domain.dto.RankDto;
import com.lightyears.common.domain.dto.RankModel;
import com.lightyears.common.domain.dto.ResModeBase;
import com.lightyears.common.domain.entity.MainlandLog;
import com.lightyears.common.domain.entity.Player;
import com.lightyears.common.domain.entity.PlayerIntegral;
import com.lightyears.common.domain.enums.MessageEnum;
import com.lightyears.mainland.exception.BussinessException;
import com.lightyears.mainland.mapper.MainlandLogMapper;
import com.lightyears.mainland.service.IMainlandLogService;
import com.lightyears.mainland.service.IPlayerIntegralService;
import com.lightyears.mainland.util.RedisCache;
import com.lightyears.mainland.util.ResultUtil;
import com.lightyears.mainland.util.StaticUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.BoundZSetOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
@RequiredArgsConstructor
public class MainlandLogServiceImpl extends ServiceImpl<MainlandLogMapper, MainlandLog> implements IMainlandLogService {
private final RedisCache redisCache;
private final IPlayerIntegralService playerIntegralService;
@Override
@Transactional(rollbackFor = Exception.class)
public ResModeBase saveMainlandLog(Player player, Integer level, int game_time, float bvs3, float bv3, String video, String gameinfo, boolean nf, int integralNum) {
int req = -1;
//1 检验是否存在记录
MainlandLog isTrue = getOne(new QueryWrapper<MainlandLog>().eq("user_id", player.getUser_id()).orderByDesc("creation_time").last("limit 1"));
MainlandLog data = MainlandLog.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 = this.updateById(data)?2:0;
}
} else {
//存储
req = this.save(data)?1:0;
}
int num = playerIntegralService.saveIntegral(integralNum, player.getUser_id(), "游戏对局");
// 排除成绩不计入排行的用户
if (req < 1) {
throw new BussinessException(MessageEnum.GAME_SAVE_LOG_ADD_ERROR);
}
RankModel rankModel = RankModel.builder().userId(player.getUser_id()).userName(player.getUser_name()).build();
// 是否达到段位积分要求 && 玩家成绩计入排行榜
if(num >= getRankThreshold() && player.getUser_gold() == 0){
BoundZSetOperations<String, RankModel> operations = redisCache.redisTemplate.boundZSetOps(StaticUtil.INTEGRAL_RANK_KEY);
operations.add(rankModel, num);
}
// 写入积分增长日榜
BoundZSetOperations<String, RankModel> dayRank = redisCache.redisTemplate.boundZSetOps(StaticUtil.MAINLAND_DAY_RANK);
Double score = Optional.of(dayRank.score(rankModel)).orElse(0D);
dayRank.add(rankModel, score+num);
return ResultUtil.result(MessageEnum.SUCCESS.getCode(), MessageEnum.SUCCESS.getMessage());
}
@Override
public MainLandRankInfoDto getPlayerRankInfo(RankModel rankModel) {
BoundZSetOperations<String, RankModel> operations = redisCache.redisTemplate.boundZSetOps(StaticUtil.INTEGRAL_RANK_KEY);
Long rankNum = operations.reverseRank(rankModel);
Double num = operations.score(rankModel);
MainLandRankInfoDto rankInfoDto = new MainLandRankInfoDto();
if(rankNum != null){
PlayerIntegral playerIntegral = playerIntegralService.getOne(new LambdaQueryWrapper<PlayerIntegral>().eq(PlayerIntegral::getUserId, rankModel.getUserId()).orderByDesc(PlayerIntegral::getNum).last("limit 1"));
if(playerIntegral == null){
return rankInfoDto;
}
rankInfoDto.setIntegralNum(playerIntegral.getNum());
} else {
rankInfoDto.setIntegralNum(num.intValue());
rankInfoDto.setRankNum(rankNum.intValue());
}
return rankInfoDto;
}
@Override
public String getMainlandGameInfo(Integer playerId){
Object value = redisCache.getCacheObject(StaticUtil.MAINLAND_GAME_INFO_KEY.concat(playerId.toString()));
if (value == null) {
MainlandLog mainlandLog = baseMapper.selectOne(new LambdaQueryWrapper<MainlandLog>().eq(MainlandLog::getUser_id, playerId).orderByAsc(MainlandLog::getGame_time).last("limit 1"));
if(mainlandLog == null){
throw new BussinessException(MessageEnum.GAME_RECORD_ERROR);
}
// 缓存10分钟
redisCache.setCacheObject(StaticUtil.MAINLAND_GAME_INFO_KEY.concat(playerId.toString()), mainlandLog.getGame_info(), 10, TimeUnit.MINUTES);
return mainlandLog.getGame_info();
}
return value.toString();
}
@Override
public PageInfo getDayRank(int pageIndex, int pageSize){
BoundZSetOperations<String, RankModel> operations = redisCache.redisTemplate.boundZSetOps(StaticUtil.MAINLAND_DAY_RANK);
List<RankDto> results = new ArrayList<RankDto>();
Page<RankDto> page = new Page(pageIndex, pageSize);
if(operations == null || operations.size() == 0){
} else {
Set<ZSetOperations.TypedTuple<RankModel>> objs = operations.reverseRangeByScoreWithScores(0, -1);
List<ZSetOperations.TypedTuple<RankModel>> cacheObjs = new ArrayList<ZSetOperations.TypedTuple<RankModel>>();
cacheObjs.addAll(objs);
int total = objs.size();
page.setTotal(total);
//计算当前需要显示的数据下标起始值
int startIndex = (pageIndex - 1) * pageSize;
int endIndex = Math.min(startIndex + pageSize, total);
// 截取数据
cacheObjs = cacheObjs.subList(startIndex,endIndex);
// 写入返回体
for (ZSetOperations.TypedTuple<RankModel> obj : cacheObjs){
results.add(new RankDto(obj.getValue(), obj.getScore().intValue()));
}
}
//从链表中截取需要显示的子链表并加入到Page
page.addAll(results);
//以Page创建PageInfo
PageInfo pageInfo = new PageInfo<>(page);
return pageInfo;
}
@Override
public Set<RankDto> getRankRangeList(RankModel rankModel, int rangeNum){
BoundZSetOperations<String, RankModel> operations = redisCache.redisTemplate.boundZSetOps(StaticUtil.INTEGRAL_RANK_KEY);
Set<RankDto> results = new HashSet<RankDto>();
if(operations != null || operations.size() == 0){
Long rankNum = operations.rank(rankModel);
Long startIndex = rankNum - rangeNum;
Long endIndex = rankNum + rangeNum;
Set<ZSetOperations.TypedTuple<RankModel>> objs = operations.reverseRangeWithScores(startIndex >= 0 ? startIndex : startIndex + 1, endIndex);
for (ZSetOperations.TypedTuple<RankModel> obj : objs){
results.add(new RankDto(obj.getValue(), obj.getScore().intValue()));
}
return results;
}
return results;
}
/**
* 获取灵阶的起点: 200,500,2100,4100,19100,40000,100000
* 0-200
* 200-500
* 501-2100 灵阶
* 2101-4100
* 4101-19100
* 19101-40000
* 40001-100000
* > 1000001
*
* @return
*/
@Override
public Integer getRankThreshold(){
String integralInterval = redisCache.getCacheObject(StaticUtil.SYS_INTEGRAL_INTERVAL);
if(!StrUtil.isEmpty(integralInterval)){
String[] integralIntervals = integralInterval.split(",");
if(integralIntervals.length > 2){
return Integer.parseInt(integralIntervals[2].split("-")[0]);
}
}
return -1;
}
}

View File

@@ -0,0 +1,13 @@
package com.lightyears.mainland.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lightyears.common.domain.entity.PlayerIntegralDetail;
import com.lightyears.mainland.mapper.PlayerIntegralDetailMapper;
import com.lightyears.mainland.service.IPlayerIntegralDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class PlayerIntegralDetailServiceImpl extends ServiceImpl<PlayerIntegralDetailMapper, PlayerIntegralDetail> implements IPlayerIntegralDetailService {
}

View File

@@ -0,0 +1,73 @@
package com.lightyears.mainland.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
import com.lightyears.common.domain.entity.PlayerIntegral;
import com.lightyears.common.domain.entity.PlayerIntegralDetail;
import com.lightyears.mainland.mapper.PlayerIntegralMapper;
import com.lightyears.common.domain.dto.RankInitModel;
import com.lightyears.common.domain.dto.RankModel;
import com.lightyears.mainland.service.IPlayerIntegralDetailService;
import com.lightyears.mainland.service.IPlayerIntegralService;
import com.lightyears.mainland.util.RedisCache;
import com.lightyears.mainland.util.StaticUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.BoundZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.Date;
import java.util.List;
@Slf4j
@Service
@RequiredArgsConstructor
public class PlayerIntegralServiceImpl extends ServiceImpl<PlayerIntegralMapper, PlayerIntegral> implements IPlayerIntegralService {
private final IPlayerIntegralDetailService playerIntegralDetailService;
private final RedisCache redisCache;
Interner<String> pool = Interners.newWeakInterner();
@Override
@Transactional(rollbackFor = Exception.class)
public int saveIntegral(Integer num, Integer playerId, String remark){
synchronized (pool.intern("integral-".concat(playerId.toString()))) {
int numR = 0;
Date now = new Date();
PlayerIntegral playerIntegral = baseMapper.selectOne(new LambdaQueryWrapper<PlayerIntegral>().eq(PlayerIntegral::getUserId, playerId).last("limit 1"));
if(playerIntegral == null) {
playerIntegral = PlayerIntegral.builder().createTime(now).userId(playerId).num(num).build();
numR = baseMapper.insert(playerIntegral);
} else {
playerIntegral.setNum(playerIntegral.getNum() + num);
numR = baseMapper.update(null, new LambdaUpdateWrapper<PlayerIntegral>().set(PlayerIntegral::getNum, playerIntegral.getNum()).set(PlayerIntegral::getVersion, playerIntegral.getVersion() + 1).eq(PlayerIntegral::getId, playerIntegral.getId()));
}
if(numR > 0){
PlayerIntegralDetail playerIntegralDetail = PlayerIntegralDetail.builder().createTime(now).num(num).userId(playerId).remark(remark).build();
playerIntegralDetailService.save(playerIntegralDetail);
return playerIntegral.getNum();
} else {
return 0;
}
}
}
@Override
public void initRankList(Integer beginNum){
List<RankInitModel> list = baseMapper.getIntegralRank(beginNum);
if(CollectionUtils.isEmpty(list)){
return;
}
redisCache.deleteByPrefix(StaticUtil.INTEGRAL_RANK_KEY);
BoundZSetOperations<String, RankModel> operations = redisCache.redisTemplate.boundZSetOps(StaticUtil.INTEGRAL_RANK_KEY);
for (RankInitModel item : list){
RankModel rankModel = RankModel.builder().userId(item.getUserId()).userName(item.getUserName()).build();
operations.add(rankModel, item.getNum());
}
}
}

View File

@@ -0,0 +1,37 @@
package com.lightyears.mainland.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());
}
}

View File

@@ -0,0 +1,26 @@
package com.lightyears.mainland.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;
}
}

View File

@@ -0,0 +1,51 @@
package com.lightyears.mainland.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];
}
}

View File

@@ -0,0 +1,231 @@
package com.lightyears.mainland.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);
}
}

View File

@@ -0,0 +1,44 @@
package com.lightyears.mainland.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);
}
}

View File

@@ -0,0 +1,46 @@
package com.lightyears.mainland.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 + '\'' +
'}';
}
}

View File

@@ -0,0 +1,50 @@
package com.lightyears.mainland.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);
}
}

View File

@@ -0,0 +1,28 @@
package com.lightyears.mainland.util;
/**
* 静态工具栏 :目前数据较小 且又想减少服务器压力,特建此类 做静态缓存
*/
public class StaticUtil {
// ------------------------系统类-----------------------
// 数据加解密盐
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:";
// 闯关排行
// 雷神大陆模式 位阶积分区间key
public static final String SYS_INTEGRAL_INTERVAL = "mineClearance:sys:integralInterval";
// 雷神大陆模式 积分排名基础榜
public static final String INTEGRAL_RANK_KEY = "mineClearance:mainland:integral:baseRank";
// 雷神大陆模式 游戏录像信息缓存
public static final String MAINLAND_GAME_INFO_KEY = "mineClearance:mainland:gameInfo:";
// 日积分榜
public static final String MAINLAND_DAY_RANK = "mineClearance:mainland:dayRank";
}

View File

@@ -0,0 +1,67 @@
qbs-switch:
swagger-open: true #swagger开关(true:打开, false:关闭)
spring:
application:
name: mine-clearance-maindland
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

View File

@@ -0,0 +1,73 @@
qbs-switch:
swagger-open: true #swagger开关(true:打开, false:关闭)
spring:
application:
name: mine-clearance-maindland
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

View File

@@ -0,0 +1,11 @@
server:
port: 18631
tomcat:
uri-encoding: UTF-8
logging:
config: classpath:log.xml
spring:
profiles:
active: prod
appconfig:
version: 197.0

View 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/mainland/sys.log</File>
<!-- rollingPolicy:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。 -->
<!-- TimeBasedRollingPolicy 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 活动文件的名字会根据fileNamePattern的值每隔一段时间改变一次 -->
<!-- 文件名log/sys.2022-3-09.0.log -->
<fileNamePattern>logs/mainland/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.mainland" level="DEBUG">
<appender-ref ref="syslog" />
</logger>
</configuration>

View 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.mainland.mapper.MainlandLogMapper">
</mapper>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lightyears.mainland.mapper.PlayerIntegralDetailMapper">
</mapper>

View File

@@ -0,0 +1,18 @@
<?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.mainland.mapper.PlayerIntegralMapper">
<select id="getIntegralRank" resultType="com.lightyears.common.domain.dto.RankInitModel">
SELECT
spi.user_id userId,
sp.user_name userName,
spi.num
FROM
sl_player_integral spi,
sl_player sp
WHERE
spi.user_id = sp.user_id
AND sp.user_gold = 0
AND spi.num &gt; ${beginNum}
limit 30000
</select>
</mapper>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lightyears.mainland.mapper.PlayerMapper">
</mapper>