getNewRankList (@Param("instanceId") Integer instanceId, @Param("playerId") Integer playerId);
+ ListRankDto getRankByInsRank(@Param("instanceId") Integer instanceId,@Param("rank") Integer rank);
+}
diff --git a/admin/src/main/java/com/lightyears/admin/mapper/LogMapper.java b/admin/src/main/java/com/lightyears/admin/mapper/LogMapper.java
new file mode 100644
index 0000000..e33d46b
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/mapper/LogMapper.java
@@ -0,0 +1,29 @@
+package com.lightyears.admin.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;
+
+/**
+ *
+ * 游戏 完成记录 表 游戏难度:1 - 普通 2 困难 3 大师 Mapper 接口
+ *
+ *
+ * @author hellor
+ * @since 2022-03-09
+ */
+@Mapper
+public interface LogMapper extends BaseMapper {
+ List paging(@Param("level") Integer level, @Param("userId")Integer userId);
+ //综合查询 三种难度加起来 获取排名
+ List syntheticalPaging();
+ // 查询用户综合排名
+ Map getComprehensiveRankByUserId(@Param("userId") Integer userId);
+ //根据User_id和 level 查询排名
+ Map getRankByLevelUserId(@Param("level")int level, @Param("userId") Integer userId);
+}
diff --git a/admin/src/main/java/com/lightyears/admin/mapper/NoticeMapper.java b/admin/src/main/java/com/lightyears/admin/mapper/NoticeMapper.java
new file mode 100644
index 0000000..b956e62
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/mapper/NoticeMapper.java
@@ -0,0 +1,23 @@
+package com.lightyears.admin.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;
+
+/**
+ *
+ * Mapper 接口
+ *
+ *
+ * @author hellor
+ * @since 2022-03-18
+ */
+@Mapper
+public interface NoticeMapper extends BaseMapper {
+ List getList(@Param("type") Integer type, @Param("playerId") Integer playerId);
+ String getContent(@Param("id")Integer id);
+}
diff --git a/admin/src/main/java/com/lightyears/admin/mapper/PlayerAssetsMapper.java b/admin/src/main/java/com/lightyears/admin/mapper/PlayerAssetsMapper.java
new file mode 100644
index 0000000..5d83fb9
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/mapper/PlayerAssetsMapper.java
@@ -0,0 +1,33 @@
+package com.lightyears.admin.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;
+
+/**
+ *
+ * Mapper 接口
+ *
+ *
+ * @author hellor
+ * @since 2022-03-16
+ */
+@Mapper
+public interface PlayerAssetsMapper extends BaseMapper {
+ // 货币存放服务器
+ 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 getPlayerAssets(@Param("playerId") int playerId);
+}
diff --git a/admin/src/main/java/com/lightyears/admin/mapper/PlayerMapper.java b/admin/src/main/java/com/lightyears/admin/mapper/PlayerMapper.java
new file mode 100644
index 0000000..f00bd00
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/mapper/PlayerMapper.java
@@ -0,0 +1,26 @@
+package com.lightyears.admin.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.lightyears.admin.dto.UserListParams;
+import com.lightyears.common.domain.entity.Player;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ *
+ * 扫雷玩家表 Mapper 接口
+ *
+ *
+ * @author hellor
+ * @since 2022-03-09
+ */
+@Mapper
+public interface PlayerMapper extends BaseMapper {
+ /**
+ * 玩家列表
+ * @param params
+ * @return
+ */
+ List getPlayerList(UserListParams params);
+}
diff --git a/admin/src/main/java/com/lightyears/admin/mapper/RecordMapper.java b/admin/src/main/java/com/lightyears/admin/mapper/RecordMapper.java
new file mode 100644
index 0000000..783db8c
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/mapper/RecordMapper.java
@@ -0,0 +1,18 @@
+package com.lightyears.admin.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.lightyears.common.domain.entity.Record;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ *
+ * 游戏存档 Mapper 接口
+ *
x
+ *
+ * @author hellor
+ * @since 2022-03-09
+ */
+@Mapper
+public interface RecordMapper extends BaseMapper {
+
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/IClearanceLogService.java b/admin/src/main/java/com/lightyears/admin/service/IClearanceLogService.java
new file mode 100644
index 0000000..96c8e1f
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/IClearanceLogService.java
@@ -0,0 +1,26 @@
+package com.lightyears.admin.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.lightyears.common.domain.dto.PlayerClearanceLogInfoDto;
+import com.lightyears.common.domain.entity.ClearanceLog;
+
+/**
+ *
+ * 服务类
+ *
+ *
+ * @author hellor
+ * @since 2022-06-02
+ */
+public interface IClearanceLogService extends IService {
+
+ /**
+ * 缓存用户闯关记录
+ */
+ void cachePlayerClearanceRank();
+
+ /**
+ * 删除用户闯关记录缓存
+ */
+ void deletCacheByPlayerId(Integer playerId);
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/IGameSystemService.java b/admin/src/main/java/com/lightyears/admin/service/IGameSystemService.java
new file mode 100644
index 0000000..5120080
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/IGameSystemService.java
@@ -0,0 +1,16 @@
+package com.lightyears.admin.service;
+
+import com.lightyears.common.domain.dto.ResModeBase;
+import com.lightyears.common.domain.entity.Player;
+
+public interface IGameSystemService {
+
+ 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);
+
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/ILogService.java b/admin/src/main/java/com/lightyears/admin/service/ILogService.java
new file mode 100644
index 0000000..567e293
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/ILogService.java
@@ -0,0 +1,42 @@
+package com.lightyears.admin.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;
+
+/**
+ *
+ * 游戏 完成记录 表 游戏难度:1 - 普通 2 困难 3 大师 服务类
+ *
+ *
+ * @author hellor
+ * @since 2022-03-09
+ */
+public interface ILogService extends IService {
+ /**
+ * 查询排行榜
+ * @param level 游戏难度:1 - 普通 2 困难 3 大师
+ * @return
+ */
+ List getRankList(Integer level);
+
+ /**
+ * 排行榜数据写入缓存
+ */
+ void cacheRankList(Integer level);
+
+ /**
+ * 删除缓存
+ * @param userId
+ */
+ void deleteCacheByUserId(Integer userId);
+
+ /**
+ * 删除用户指定排行榜数据
+ * @param level
+ * @param userId
+ */
+ void deleteCacheByRankUserId(Integer level, Integer userId);
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/INoticeService.java b/admin/src/main/java/com/lightyears/admin/service/INoticeService.java
new file mode 100644
index 0000000..cdc9f1b
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/INoticeService.java
@@ -0,0 +1,20 @@
+package com.lightyears.admin.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.lightyears.common.domain.dto.ResModeBase;
+import com.lightyears.common.domain.entity.Notice;
+
+/**
+ *
+ * 服务类
+ *
+ *
+ * @author hellor
+ * @since 2022-03-18
+ */
+public interface INoticeService extends IService {
+ ResModeBase getList(Integer playerId);
+ ResModeBase getContent(Integer id);
+ void deleteNoticeForTask();
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/IPlayerAssetsService.java b/admin/src/main/java/com/lightyears/admin/service/IPlayerAssetsService.java
new file mode 100644
index 0000000..1346a34
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/IPlayerAssetsService.java
@@ -0,0 +1,38 @@
+package com.lightyears.admin.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;
+
+/**
+ *
+ * 服务类
+ *
+ *
+ * @author hellor
+ * @since 2022-03-16
+ */
+public interface IPlayerAssetsService extends IService {
+ /**
+ * 添加金币
+ * @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 getPlayerAssets(int playerId);
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/IPlayerService.java b/admin/src/main/java/com/lightyears/admin/service/IPlayerService.java
new file mode 100644
index 0000000..710af06
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/IPlayerService.java
@@ -0,0 +1,15 @@
+package com.lightyears.admin.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.lightyears.common.domain.entity.Player;
+
+/**
+ *
+ * 扫雷玩家表 服务类
+ *
+ *
+ * @author hellor
+ * @since 2022-03-09
+ */
+public interface IPlayerService extends IService {
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/IRecordService.java b/admin/src/main/java/com/lightyears/admin/service/IRecordService.java
new file mode 100644
index 0000000..2840b07
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/IRecordService.java
@@ -0,0 +1,16 @@
+package com.lightyears.admin.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.lightyears.common.domain.entity.Record;
+
+/**
+ *
+ * 游戏存档 服务类
+ *
+ *
+ * @author hellor
+ * @since 2022-03-09
+ */
+public interface IRecordService extends IService {
+
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/ISystemService.java b/admin/src/main/java/com/lightyears/admin/service/ISystemService.java
new file mode 100644
index 0000000..3caf031
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/ISystemService.java
@@ -0,0 +1,98 @@
+package com.lightyears.admin.service;
+
+import com.lightyears.admin.dto.ListBaseListParams;
+import com.lightyears.admin.dto.PlayerAssetsParams;
+import com.lightyears.admin.dto.UserListParams;
+import com.lightyears.admin.dto.UserStatusParams;
+import com.lightyears.common.domain.dto.Params;
+import com.lightyears.common.domain.dto.ResModeBase;
+import com.lightyears.common.domain.entity.ListBase;
+import com.lightyears.common.domain.entity.Notice;
+
+public interface ISystemService {
+ /**
+ * 管理端登录
+ * @param userName
+ * @param password
+ * @return
+ */
+ ResModeBase login(String userName, String password);
+
+ /**
+ * 注销登录
+ * @return
+ */
+ ResModeBase logout();
+
+ /**
+ * 用户列表
+ * @param params
+ * @return
+ */
+ ResModeBase userList(Params params);
+ /**
+ * 发布公告
+ * @param notice
+ * @return
+ */
+ void publishNotice(Notice notice);
+
+ /**
+ * 删除玩家
+ * @param userId 玩家id
+ */
+ void cancellationAccount(Integer userId);
+
+ /**
+ * 删除玩家排行数据
+ * @param level
+ * @param userId
+ */
+ void deleteCacheByRankUserId(Integer level, Integer userId);
+
+ /**
+ * 修改用户状态
+ * @param params
+ */
+ void updateUserStatus(UserStatusParams params);
+
+ /**
+ * 加/减用户资产
+ * @param params
+ */
+ void setPlayerAssets(PlayerAssetsParams params);
+
+ /**
+ * 查询挑战榜模板列表
+ * @param params
+ * @return
+ */
+ ResModeBase challengeBaseList(Params params);
+
+ /**
+ * 添加挑战模板
+ * @param base
+ * @return
+ */
+ ResModeBase addBase(ListBase base);
+
+ /**
+ * 删除未实例化的模板
+ * @param id 模板id
+ * @return
+ */
+ ResModeBase deleteBase(Integer id);
+
+ /**
+ * 获取实例list
+ * @return
+ */
+ ResModeBase challengeInstanceList();
+
+ /**
+ * 清空指定挑战榜排名的玩家数据
+ * @param instanceId 实例榜单id
+ * @param rankNum 排名
+ */
+ void removeChallengeRankInfo(Integer instanceId, Integer rankNum);
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/impl/ClearanceLogServiceImpl.java b/admin/src/main/java/com/lightyears/admin/service/impl/ClearanceLogServiceImpl.java
new file mode 100644
index 0000000..666aa5c
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/impl/ClearanceLogServiceImpl.java
@@ -0,0 +1,60 @@
+package com.lightyears.admin.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.lightyears.admin.exception.BussinessException;
+import com.lightyears.admin.mapper.ClearanceLogMapper;
+import com.lightyears.admin.service.IClearanceLogService;
+import com.lightyears.admin.util.RedisCache;
+import com.lightyears.admin.util.StaticUtil;
+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 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;
+
+/**
+ *
+ * 服务实现类
+ *
+ *
+ * @author hellor
+ * @since 2022-06-02
+ */
+@Service
+public class ClearanceLogServiceImpl extends ServiceImpl implements IClearanceLogService {
+
+ @Resource
+ private RedisCache redisCache;
+
+ @Override
+ public void cachePlayerClearanceRank(){
+ List logs = this.getClearanceLogs();
+ String key = StaticUtil.CLEARANCE_RANK_LIST;
+ BoundZSetOperations operations = redisCache.getRedisTemplate().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 operations = redisCache.getRedisTemplate().boundZSetOps(key);
+ operations.remove(playerId);
+ }
+
+ public List getClearanceLogs(){
+ List logs = baseMapper.getPlayerClearanceLogs(null);
+ return logs;
+ }
+
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/impl/GameSystemServiceImpl.java b/admin/src/main/java/com/lightyears/admin/service/impl/GameSystemServiceImpl.java
new file mode 100644
index 0000000..ea3a44b
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/impl/GameSystemServiceImpl.java
@@ -0,0 +1,107 @@
+package com.lightyears.admin.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.admin.mapper.*;
+import com.lightyears.admin.exception.BussinessException;
+import com.lightyears.admin.service.IClearanceLogService;
+import com.lightyears.admin.service.IGameSystemService;
+import com.lightyears.admin.service.ILogService;
+import com.lightyears.admin.service.IPlayerAssetsService;
+import com.lightyears.admin.util.RedisCache;
+import com.lightyears.admin.util.ResultUtil;
+import com.lightyears.admin.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 IPlayerAssetsService playerAssetsService;
+ @Resource
+ private AssertLogMapper assertLogMapper;
+ @Resource
+ private IGameSystemService gameSystemService;
+ Interner pool = Interners.newWeakInterner();
+ private static final int AssetLimit = 999999;
+
+ @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().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().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);
+ }
+
+
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/impl/LogServiceImpl.java b/admin/src/main/java/com/lightyears/admin/service/impl/LogServiceImpl.java
new file mode 100644
index 0000000..6b6f783
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/impl/LogServiceImpl.java
@@ -0,0 +1,101 @@
+package com.lightyears.admin.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.lightyears.admin.mapper.LogMapper;
+import com.lightyears.admin.service.ILogService;
+import com.lightyears.admin.util.RedisCache;
+import com.lightyears.admin.util.StaticUtil;
+import com.lightyears.common.domain.dto.OrdinaryRankDto;
+import com.lightyears.common.domain.entity.Log;
+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;
+
+/**
+ *
+ * 游戏 完成记录 表 游戏难度:1 - 普通 2 困难 3 大师 服务实现类
+ *
+ *
+ * @author hellor
+ * @since 2022-03-09
+ */
+@Service
+public class LogServiceImpl extends ServiceImpl implements ILogService {
+ @Resource
+ private RedisCache redisCache;
+
+ @Override
+ public List getRankList(Integer level){
+ List 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 zh = getRankList(-1);
+ cacheRankListItem(zh, 0);
+ // 1 - 普通
+ List zh1 = getRankList(1);
+ cacheRankListItem(zh1, 1);
+ // 2 困难
+ List zh2 = getRankList(2);
+ cacheRankListItem(zh2, 2);
+ // 3 大师
+ List zh3 = getRankList(3);
+ cacheRankListItem(zh3, 3);
+ // 4 超凡
+ List zh4 = getRankList(4);
+ cacheRankListItem(zh4, 4);
+ } else if(level == -1) { // 刷新综合榜数据
+ // -1 - 综合
+ List zh = getRankList(-1);
+ cacheRankListItem(zh, 0);
+ }
+ }
+
+ public void cacheRankListItem(List list, Integer level){
+ String key = StaticUtil.RANK_LIST.concat(level.toString());
+ redisCache.deleteByPrefix(key);
+ BoundZSetOperations operations = redisCache.getRedisTemplate().boundZSetOps(key);
+ for (OrdinaryRankDto item : list){
+ operations.add(item, item.getGame_time());
+ }
+ }
+
+
+ @Override
+ public void deleteCacheByRankUserId(Integer level, Integer userId){
+ String key = StaticUtil.RANK_LIST.concat(level.toString());
+ BoundZSetOperations operations = redisCache.getRedisTemplate().boundZSetOps(key);
+ if (operations != null && operations.size() > 0){
+ Set sets = operations.range(0, -1);
+ if(sets != null && sets.size() > 0){
+ Optional dto = sets.stream().filter(obj -> obj.getUser_id().equals(userId)).findFirst();
+ if(dto != null && dto.isPresent()){
+ operations.remove(dto.get());
+ }
+ }
+ }
+ }
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/impl/NoticeServiceImpl.java b/admin/src/main/java/com/lightyears/admin/service/impl/NoticeServiceImpl.java
new file mode 100644
index 0000000..8a34f9d
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/impl/NoticeServiceImpl.java
@@ -0,0 +1,77 @@
+package com.lightyears.admin.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.admin.mapper.NoticeMapper;
+import com.lightyears.admin.service.INoticeService;
+import com.lightyears.admin.util.ResultUtil;
+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 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;
+
+/**
+ *
+ * 服务实现类
+ *
+ *
+ * @author hellor
+ * @since 2022-03-18
+ */
+@Service(value = "noticeServiceImpl")
+@RequiredArgsConstructor(onConstructor = @_(@Autowired))
+public class NoticeServiceImpl extends ServiceImpl implements INoticeService {
+
+
+ @Override
+ public ResModeBase getList(Integer playerId){
+// List results = new ArrayList<>();
+ List systemNotice = this.baseMapper.getList(null, playerId);
+// List 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 notices = this.baseMapper.selectList(new LambdaQueryWrapper().select(Notice::getId, Notice::getExpirationDay, Notice::getCreateDate).isNotNull(Notice::getExpirationDay));
+ if (CollectionUtils.isEmpty(notices))
+ return;
+ Date now = new Date();
+ List 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);
+ }
+
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/impl/PlayerAssetsServiceImpl.java b/admin/src/main/java/com/lightyears/admin/service/impl/PlayerAssetsServiceImpl.java
new file mode 100644
index 0000000..0f3529d
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/impl/PlayerAssetsServiceImpl.java
@@ -0,0 +1,76 @@
+package com.lightyears.admin.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.lightyears.admin.exception.BussinessException;
+import com.lightyears.admin.mapper.PlayerAssetsMapper;
+import com.lightyears.admin.service.IPlayerAssetsService;
+import com.lightyears.common.domain.dto.SimplePlayerAssert;
+import com.lightyears.common.domain.entity.PlayerAssets;
+import com.lightyears.common.domain.enums.MessageEnum;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+
+import java.util.List;
+
+/**
+ *
+ * 服务实现类
+ *
+ *
+ * @author hellor
+ * @since 2022-03-16
+ */
+@Slf4j
+@Service
+public class PlayerAssetsServiceImpl extends ServiceImpl 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 getPlayerAssets(int playerId){
+ return baseMapper.getPlayerAssets(playerId);
+ }
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/impl/PlayerServiceImpl.java b/admin/src/main/java/com/lightyears/admin/service/impl/PlayerServiceImpl.java
new file mode 100644
index 0000000..44913f0
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/impl/PlayerServiceImpl.java
@@ -0,0 +1,20 @@
+package com.lightyears.admin.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.lightyears.admin.mapper.PlayerMapper;
+import com.lightyears.admin.service.IPlayerService;
+import com.lightyears.common.domain.entity.Player;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 扫雷玩家表 服务实现类
+ *
+ *
+ * @author hellor
+ * @since 2022-03-09
+ */
+@Service
+public class PlayerServiceImpl extends ServiceImpl implements IPlayerService {
+
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/impl/RecordServiceImpl.java b/admin/src/main/java/com/lightyears/admin/service/impl/RecordServiceImpl.java
new file mode 100644
index 0000000..9954a3d
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/impl/RecordServiceImpl.java
@@ -0,0 +1,20 @@
+package com.lightyears.admin.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.lightyears.admin.mapper.RecordMapper;
+import com.lightyears.admin.service.IRecordService;
+import com.lightyears.common.domain.entity.Record;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 游戏存档 服务实现类
+ *
+ *
+ * @author hellor
+ * @since 2022-03-09
+ */
+@Service
+public class RecordServiceImpl extends ServiceImpl implements IRecordService {
+
+}
diff --git a/admin/src/main/java/com/lightyears/admin/service/impl/SystemServiceImpl.java b/admin/src/main/java/com/lightyears/admin/service/impl/SystemServiceImpl.java
new file mode 100644
index 0000000..603c3da
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/service/impl/SystemServiceImpl.java
@@ -0,0 +1,280 @@
+package com.lightyears.admin.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.lightyears.admin.dto.ListBaseListParams;
+import com.lightyears.admin.dto.PlayerAssetsParams;
+import com.lightyears.admin.dto.UserListParams;
+import com.lightyears.admin.dto.UserStatusParams;
+import com.lightyears.admin.exception.BussinessException;
+import com.lightyears.admin.mapper.*;
+import com.lightyears.admin.service.*;
+import com.lightyears.admin.util.*;
+import com.lightyears.common.domain.dto.ListInstanceDto;
+import com.lightyears.common.domain.dto.ListRankDto;
+import com.lightyears.common.domain.dto.Params;
+import com.lightyears.common.domain.dto.ResModeBase;
+import com.lightyears.common.domain.entity.*;
+import com.lightyears.common.domain.enums.MessageEnum;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+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;
+ private final PlayerMapper playerMapper;
+ private final RecordMapper recordMapper;
+ private final ILogService logService;
+ private final AssertLogMapper assertLogMapper;
+ private final NoticeMapper noticeMapper;
+ private final IClearanceLogService clearanceLogService;
+ private final RedisCache redisCache;
+ private final RedisLock redisLock;
+ private final IGameSystemService gameSystemService;
+ private final ListBaseMapper listBaseMapper;
+ private final ListRankMapper listRankMapper;
+ private final ListInstanceMapper listInstanceMapper;
+
+ @Override
+ public ResModeBase login(String userName, String password){
+ String checkStr = redisCache.getCacheObject(StaticUtil.ADMIN_PASSWORD).toString();
+ log.info("登录来了:" + checkStr);
+ if(checkStr.equals(userName.trim().concat(password.trim()))){
+ String token = StrUtil.uuid().replace("-", "");
+ // 写入管理端用户在线缓存
+ redisCache.setCacheObject(StaticUtil.ONLINE_ADMIN_USER_PUBLIC_KEY.concat(token), "admin", 86400, TimeUnit.SECONDS);
+ // 返回token
+ return ResultUtil.success(token);
+ } else {
+ return ResultUtil.error("登录失败,账号或密码错误!");
+ }
+ }
+
+ @Override
+ public ResModeBase logout(){
+ redisCache.deleteByPrefix(StaticUtil.ONLINE_ADMIN_USER_PUBLIC_KEY);
+ return ResultUtil.success();
+ }
+
+ @Override
+ public ResModeBase userList(Params params){
+ PageHelperUtil.setPage(params.getPageNum(), params.getPageSize());
+ return ResultUtil.success(PageHelperUtil.slicedQueryResult(playerMapper.getPlayerList(params.getRecord())));
+ }
+
+ @Override
+ @Transactional
+ public void updateUserStatus(UserStatusParams params){
+ playerMapper.update(null, new LambdaUpdateWrapper().set(Player::getStatus, params.getStatus()).eq(Player::getUser_id, params.getPlayerId()));
+ // 如果是禁用
+ if(params.getStatus() == 0){
+ Object token = redisCache.getCacheObject(StaticUtil.ONLINE_USER_TOKEN.concat(params.getPlayerId().toString()));
+ if(token == null)
+ return;
+ redisCache.deleteByPrefix(StaticUtil.ONLINE_USER_TOKEN.concat(params.getPlayerId().toString()));
+ // 删除缓存
+ redisCache.deleteByPrefix(StaticUtil.ONLINE_USER_PUBLIC_KEY.concat(token.toString()));
+ }
+ }
+
+ @Override
+ public void publishNotice(Notice notice){
+ //redis锁
+ String lockKey=StaticUtil.NOTICE_LOCK;
+ try {
+ if(redisLock.tryLock(lockKey)){
+ List players = playerAssetsService.list(new LambdaQueryWrapper().select(PlayerAssets::getPlayerId).eq(PlayerAssets::getType, 0));
+ if(CollectionUtils.isEmpty(players))
+ return;
+ Date now = new Date();
+
+ List 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);
+ });
+ //一个线程处理10000条数据
+ int count = 10000;
+ //数据集合大小
+ int listSize = notices.size();
+ //开启的线程数
+ int runSize = (listSize / count) + 1;
+ //存放每个线程的执行数据
+ List newlist = null;
+
+ //创建一个线程池,数量和开启线程的数量一样
+ //Executors 的写法
+ // ExecutorService executor = Executors.newFixedThreadPool(runSize);
+
+ //ThreadPoolExecutor的写法
+ ThreadPoolExecutor executor = new ThreadPoolExecutor(runSize, runSize, 1,
+ TimeUnit.SECONDS, new ArrayBlockingQueue(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();
+ } finally {
+ //执行完关闭线程池
+ executor.shutdown();
+ }
+
+ }else{
+ throw new BussinessException(MessageEnum.ERROR.getCode(), "公告正在发布中,请稍后!");
+ }
+ }catch (BussinessException e){
+ throw new BussinessException(MessageEnum.ERROR.getCode(), "公告正在发布中,请稍后!");
+ }catch (Exception e){
+ log.error("发布公告异常:", e);
+ throw new BussinessException(MessageEnum.ERROR.getCode(), "发布公告异常!");
+ } finally {
+ redisLock.releaseLock(lockKey);
+ }
+ }
+
+
+ @Override
+ public void deleteCacheByRankUserId(Integer level, Integer userId){
+ // 删除游戏日志
+ logService.remove(new LambdaQueryWrapper().eq(Log::getUser_id, userId).eq(Log::getLevel, level));
+ // 删除缓存
+ logService.deleteCacheByRankUserId(level, userId);
+ }
+
+ @Override
+ @Transactional
+ public void cancellationAccount(Integer userId) {
+ // 删除排行榜缓存数据.
+ logService.deleteCacheByUserId(userId);
+ // 删除雷神之塔缓存数据
+ clearanceLogService.deletCacheByPlayerId(userId);
+
+ // sl_assert_log 资产日志
+ assertLogMapper.delete(new UpdateWrapper().eq("player_id", userId));
+ // sl_log 游戏日志
+ logService.remove(new UpdateWrapper().eq("user_id", userId));
+ // sl_notic 公告
+ noticeMapper.delete(new UpdateWrapper().eq("player_id", userId));
+ // sl_player_assets 用户资产
+ playerAssetsService.remove(new UpdateWrapper().eq("player_id", userId));
+ // sl_record 用户游戏数据记录
+ recordMapper.delete(new UpdateWrapper().eq("user_id", userId));
+ // sl_player 用户
+ playerMapper.deleteById(userId);
+ // sl_clearance_log 通关日志
+ clearanceLogService.remove(new LambdaQueryWrapper().eq(ClearanceLog::getPlayerId, userId));
+ }
+
+ @Override
+ public void setPlayerAssets(PlayerAssetsParams params){
+ if(params.getGold() == 0)
+ return;
+ if(params.getGold() > 0){
+ gameSystemService.pushGold(params.getUserId(),params.getGold(),params.getType(), params.getRemark());
+ } else {
+ gameSystemService.pullGold(params.getUserId(),0 - params.getGold(),params.getType(), params.getRemark());
+ }
+ }
+
+ @Override
+ public ResModeBase challengeBaseList(Params params){
+ PageHelperUtil.setPage(params.getPageNum(), params.getPageSize());
+ CustomLambdaQueryWrapper queryWrapper = new CustomLambdaQueryWrapper();
+ if(params.getRecord() != null && !StrUtil.isBlankIfStr(params.getRecord().getKeyword())){
+ queryWrapper.like(ListBase::getName, params.getRecord().getKeyword());
+ }
+ return ResultUtil.success(PageHelperUtil.slicedQueryResult(listBaseMapper.selectList(queryWrapper)));
+ }
+
+ @Override
+ public ResModeBase addBase(ListBase base){
+ if(base.getId() == null){
+ listBaseMapper.insert(base);
+ } else {
+ listBaseMapper.updateById(base);
+ }
+ return ResultUtil.success();
+ }
+
+ @Override
+ public ResModeBase deleteBase(Integer id){
+ Long num = listInstanceMapper.selectCount(new LambdaQueryWrapper().eq(ListInstance:: getId, id).eq(ListInstance::getStatus, 0));
+ if(num == 0L){
+ listBaseMapper.deleteById(id);
+ }
+ return ResultUtil.success();
+ }
+
+ @Override
+ public ResModeBase challengeInstanceList(){
+ List list = listInstanceMapper.getListInstances();
+ return ResultUtil.success(list);
+ }
+
+ @Override
+ public void removeChallengeRankInfo(Integer instanceId, Integer rankNum){
+ int i = listRankMapper.initRank(instanceId, rankNum);
+ // 清空成功 更新缓存
+ if(i > 0){
+ ListRankDto rank;
+ // 获取指定榜单与名次的listRank
+ Object obj = redisCache.lGetIndex(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL.concat(instanceId.toString()), rankNum-1);
+ if(obj == null){
+ return;
+ } else {
+ String json = JSONObject.toJSONString(obj) ;
+ rank = JSON.parseObject(json, ListRankDto.class);
+ }
+ rank.setChallengeTime(null);
+ rank.setPlayerId(null);
+ rank.setPlayerName(null);
+ rank.setGameData(null);
+ redisCache.lUpdateIndex(StaticUtil.CHALLENGE_INSTANCE_RANK_DETAIL.concat(rank.getInstanceId().toString()), rank.getRankNum() - 1, rank);
+ }
+ }
+}
diff --git a/admin/src/main/java/com/lightyears/admin/util/BatchInsertThread.java b/admin/src/main/java/com/lightyears/admin/util/BatchInsertThread.java
new file mode 100644
index 0000000..fe0100b
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/util/BatchInsertThread.java
@@ -0,0 +1,46 @@
+package com.lightyears.admin.util;
+
+import com.lightyears.admin.service.INoticeService;
+import com.lightyears.common.domain.entity.Notice;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+public class BatchInsertThread implements Runnable {
+
+ public BatchInsertThread() {
+ }
+
+ INoticeService noticeService;
+ private List list;
+ private CountDownLatch begin;
+ private CountDownLatch end;
+
+ /**
+ * 方法名: ImportThread
+ * 方法描述: 创建个构造函数初始化 list,和其他用到的参数
+ * @throws
+ */
+ public BatchInsertThread(List 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();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/admin/src/main/java/com/lightyears/admin/util/CronUtils.java b/admin/src/main/java/com/lightyears/admin/util/CronUtils.java
new file mode 100644
index 0000000..f2352f1
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/util/CronUtils.java
@@ -0,0 +1,37 @@
+package com.lightyears.admin.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());
+ }
+
+}
+
diff --git a/admin/src/main/java/com/lightyears/admin/util/CustomLambdaQueryWrapper.java b/admin/src/main/java/com/lightyears/admin/util/CustomLambdaQueryWrapper.java
new file mode 100644
index 0000000..6484b41
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/util/CustomLambdaQueryWrapper.java
@@ -0,0 +1,149 @@
+package com.lightyears.admin.util;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+
+import java.util.Collection;
+
+/**
+ * .自定义的查询wrapper.
+ *
+ * @author yangps
+ */
+public class CustomLambdaQueryWrapper extends LambdaQueryWrapper {
+
+ public CustomLambdaQueryWrapper() {
+ }
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7733721688976788787L;
+
+ /**
+ * .软条件查询, 如果条件无值, 就不加入查询.
+ *
+ * @param R
+ * @param val
+ * @return
+ */
+ public CustomLambdaQueryWrapper softEq(SFunction R, Object val) {
+ if (val != null && StringUtils.isNotBlank(val + "")) {
+ super.eq(R, val);
+ }
+ return this;
+ }
+
+ /**
+ * .软条件查询, 如果条件无值, 就不加入查询.
+ *
+ * @param R
+ * @param val
+ * @return
+ */
+ public CustomLambdaQueryWrapper softEqForInteger(SFunction R, Object val) {
+ if (val != null && StringUtils.isNotBlank(val + "") && Integer.valueOf(String.valueOf(val)).intValue() != -1) {
+ super.eq(R, val);
+ }
+ return this;
+ }
+
+ /**
+ * .软条件查询, 如果条件无值, 就不加入查询.
+ *
+ * @param R
+ * @param val
+ * @return
+ */
+ public CustomLambdaQueryWrapper softNe(SFunction R, Object val) {
+ if (val != null && StringUtils.isNotBlank(val + "")) {
+ super.ne(R, val);
+ }
+ return this;
+ }
+
+ /**
+ * .软条件查询, 如果条件无值, 就不加入查询.
+ *
+ * @param R
+ * @param val
+ * @return
+ */
+ public CustomLambdaQueryWrapper softLike(SFunction R, Object val) {
+ if (val != null && StringUtils.isNotBlank(val + "")) {
+ super.like(R, val);
+ }
+ return this;
+ }
+
+ /**
+ * .软条件查询, 如果条件无值, 就不加入查询.
+ *
+ * @param R
+ * @param coll
+ * @return
+ */
+ public CustomLambdaQueryWrapper softIn(SFunction R, Collection> coll) {
+ if (coll.size() > 0) {
+ super.in(R, coll);
+ }
+ return this;
+ }
+
+ /**
+ * .软条件查询, 如果条件无值, 就不加入查询.
+ *
+ * @param R
+ * @param coll
+ * @return
+ */
+ public CustomLambdaQueryWrapper softNotIn(SFunction R, Collection> coll) {
+ if (coll.size() > 0) {
+ super.notIn(R, coll);
+ }
+ return this;
+ }
+
+ /**
+ * .软条件查询, 如果条件无值, 就不加入查询.
+ *
+ * @param R
+ * @param val1
+ * @param val2
+ * @return
+ */
+ public CustomLambdaQueryWrapper softTimeBetween(SFunction R, Object val1, Object val2) {
+
+ if (val1 != null && StringUtils.isNotBlank(val1 + "") && val2 != null && StringUtils.isNotBlank(val2 + "")) {
+ super.between(R, val1, val2);
+ return this;
+ }
+
+ if (val1 != null && StringUtils.isNotBlank(val1 + "") && val2 == null) {
+ super.ge(R, val1);
+ return this;
+ }
+
+ if (val1 == null && val2 != null && StringUtils.isNotBlank(val2 + "")) {
+ super.le(R, val2);
+ }
+ return this;
+ }
+
+ /**
+ * .软条件查询, 如果条件为null, 查询就改为is null.
+ *
+ * @param R
+ * @param val
+ * @return
+ */
+ public CustomLambdaQueryWrapper softEqOrIsNull(SFunction R, Object val) {
+ if (val != null && StringUtils.isNotBlank(val + "")) {
+ super.eq(R, val);
+ } else if (val == null) {
+ super.isNull(R);
+ }
+ return this;
+ }
+}
diff --git a/admin/src/main/java/com/lightyears/admin/util/GetBeanUtil.java b/admin/src/main/java/com/lightyears/admin/util/GetBeanUtil.java
new file mode 100644
index 0000000..04cac51
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/util/GetBeanUtil.java
@@ -0,0 +1,26 @@
+package com.lightyears.admin.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;
+ }
+}
\ No newline at end of file
diff --git a/admin/src/main/java/com/lightyears/admin/util/MD5Utils.java b/admin/src/main/java/com/lightyears/admin/util/MD5Utils.java
new file mode 100644
index 0000000..cc3ef6e
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/util/MD5Utils.java
@@ -0,0 +1,51 @@
+package com.lightyears.admin.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];
+ }
+
+}
diff --git a/admin/src/main/java/com/lightyears/admin/util/PageHelperUtil.java b/admin/src/main/java/com/lightyears/admin/util/PageHelperUtil.java
new file mode 100644
index 0000000..01bcd17
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/util/PageHelperUtil.java
@@ -0,0 +1,28 @@
+package com.lightyears.admin.util;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.lightyears.common.domain.dto.SlicedQueryResult;
+
+import java.util.List;
+
+public class PageHelperUtil {
+
+ public static void setPage(Integer pageNo, Integer pageSize) {
+ PageHelper.startPage(pageNo, pageSize);
+ }
+
+ /**
+ * 分页查询数据
+ *
+ * @param data
+ * 数据集合
+ * @return 分页对象
+ */
+ public static SlicedQueryResult slicedQueryResult(List data) {
+ PageInfo pageInfo = new PageInfo(data);
+ SlicedQueryResult slicedQueryResult = new SlicedQueryResult(pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), data);
+ PageHelper.clearPage();
+ return slicedQueryResult;
+ }
+}
diff --git a/admin/src/main/java/com/lightyears/admin/util/RedisCache.java b/admin/src/main/java/com/lightyears/admin/util/RedisCache.java
new file mode 100644
index 0000000..c958751
--- /dev/null
+++ b/admin/src/main/java/com/lightyears/admin/util/RedisCache.java
@@ -0,0 +1,383 @@
+package com.lightyears.admin.util;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.HashOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.stereotype.Component;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * spring redis 工具类
+ **/
+@Component
+public class RedisCache {
+
+ @Autowired
+ private RedisTemplate redisTemplate;
+ @Autowired
+ private StringRedisTemplate stringRedisTemplate;
+
+ /**
+ * 判断key是否存在
+ * @param key 键
+ * @return true 存在 false不存在
+ */
+ public boolean hasKey(String key) {
+ try {
+ return redisTemplate.hasKey(key);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * 缓存基本的对象,Integer、String、实体类等
+ *
+ * @param key 缓存的键值
+ * @param value 缓存的值
+ */
+ public void setCacheObject(final String key, final T value) {
+ redisTemplate.opsForValue().set(key, value);
+ }
+
+ /**
+ * 缓存基本的对象,Integer、String、实体类等
+ *
+ * @param key 缓存的键值
+ * @param value 缓存的值
+ * @param timeout 时间
+ * @param timeUnit 时间颗粒度
+ */
+ public 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 getCacheObject(final String key) {
+ ValueOperations 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 keys = redisTemplate.keys(key.concat("*"));
+ return redisTemplate.delete(keys);
+ }
+
+ /**
+ * 删除集合对象
+ *
+ * @param collection 多个对象
+ * @return
+ */
+ public long deleteObject(final Collection collection) {
+ return redisTemplate.delete(collection);
+ }
+
+ // ===============================list=================================
+
+ /**
+ * 获取list缓存的内容
+ *
+ * @param key 键
+ * @param start 开始
+ * @param end 结束 0 到 -1代表所有值
+ * @return
+ */
+ public List