AppUserCountServiceImpl.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. package com.game.business.service.impl;
  2. import cn.hutool.core.date.DateUtil;
  3. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  6. import com.game.business.domain.*;
  7. import com.game.business.mapper.AppUserCountMapper;
  8. import com.game.business.service.*;
  9. import com.game.common.constant.CacheConstants;
  10. import com.game.common.constant.finance.FinTranType1;
  11. import com.game.common.constant.finance.FinTranType3;
  12. import com.game.common.core.redis.RedisCache;
  13. import com.game.common.entity.KeyValue;
  14. import com.game.common.utils.DateUtils;
  15. import com.game.common.utils.StringUtils;
  16. import lombok.extern.log4j.Log4j2;
  17. import org.redisson.api.RLock;
  18. import org.springframework.beans.factory.annotation.Autowired;
  19. import org.springframework.scheduling.annotation.Async;
  20. import org.springframework.stereotype.Service;
  21. import org.springframework.transaction.annotation.Transactional;
  22. import java.util.*;
  23. import java.util.concurrent.TimeUnit;
  24. import java.util.function.Function;
  25. import java.util.stream.Collectors;
  26. import java.util.Date;
  27. @Service
  28. @Log4j2
  29. public class AppUserCountServiceImpl extends ServiceImpl<AppUserCountMapper, AppUserCount> implements IAppUserCountService {
  30. @Autowired
  31. private AppUserCountMapper appUserCountMapper;
  32. @Autowired
  33. private IAppUserService appUserService;
  34. @Autowired
  35. private IAppUsersChargeService appUsersChargeService;
  36. @Autowired
  37. private IAppUsersCashrecordService appUsersCashrecordService;
  38. @Autowired
  39. private IFinTranRecordService finTranRecordService;
  40. @Autowired
  41. private IAppUserLiveDividedRecordService appUserLiveDividedRecordService;
  42. @Autowired
  43. private IAppUserGameRecordCountService appUserGameRecordCountService;
  44. @Autowired
  45. private IAppGameBettingService appGameBettingService;
  46. @Autowired
  47. private IAppUserCountDividendService appUserCountDividendService;
  48. @Autowired
  49. private IAppUserAgentService appUserAgentService;
  50. @Autowired
  51. private RedisCache redisCache;
  52. @Override
  53. public List<AppUserCount> getAppUserCount(long userId,String beginTime,String endTIme) {
  54. LambdaQueryWrapper<AppUserCount> queryWrapper = new LambdaQueryWrapper<AppUserCount>();
  55. queryWrapper.between(AppUserCount::getStrDate,beginTime,endTIme);
  56. queryWrapper.eq(AppUserCount::getAgentUserId,userId);
  57. return appUserCountMapper.selectList(queryWrapper);
  58. }
  59. @Override
  60. public List<AppUserCount> getAppUserCountNew(long userId, String beginTime, String endTIme) {
  61. return appUserCountMapper.selectTeamUserCount(userId,beginTime,endTIme);
  62. }
  63. @Override
  64. // @Async
  65. @Transactional
  66. public void createAppUserCount(AppUserCount appUserCount) {
  67. synchronized ("app_user_count_".concat(String.valueOf(appUserCount.getUserId()))) {
  68. //查询当前用户当日是否已经生成记录
  69. LambdaQueryWrapper<AppUserCount> queryWrapper = new LambdaQueryWrapper<>();
  70. queryWrapper.eq(AppUserCount::getStrDate, appUserCount.getStrDate());
  71. queryWrapper.eq(AppUserCount::getUserId, appUserCount.getUserId());
  72. AppUserCount userCount = appUserCountMapper.selectOne(queryWrapper);
  73. int res = 0;
  74. if (userCount == null) {
  75. appUserCount.setCreateTime(new Date());
  76. appUserCount.setUpdateTime(new Date());
  77. res = appUserCountMapper.insert(appUserCount);
  78. } else {
  79. appUserCount.setId(userCount.getId());
  80. /*if(null == appUserCount.getUpdateTime()) {
  81. appUserCount.setUpdateTime(new Date());
  82. }*/
  83. if (!appUserCount.isUpdate()) {
  84. //非全量更新
  85. /*if (appUserCount.getRechargeAmount() != null) {
  86. appUserCount.setRechargeAmount(userCount.getRechargeAmount() + appUserCount.getRechargeAmount());
  87. }
  88. if (appUserCount.getRechargeCommission() != null) {
  89. appUserCount.setRechargeCommission(userCount.getRechargeCommission() + appUserCount.getRechargeCommission());
  90. }
  91. if (appUserCount.getRechargeGive() != null) {
  92. appUserCount.setRechargeGive(userCount.getRechargeGive() + appUserCount.getRechargeGive());
  93. }
  94. if (appUserCount.getWithdrawalAmount() != null) {
  95. appUserCount.setWithdrawalAmount(userCount.getWithdrawalAmount() + appUserCount.getWithdrawalAmount());
  96. }
  97. if (appUserCount.getWithdrawalCommission() != null) {
  98. appUserCount.setWithdrawalCommission(userCount.getWithdrawalCommission() + appUserCount.getWithdrawalCommission());
  99. }
  100. if (appUserCount.getLiveUseAmount() != null) {
  101. appUserCount.setLiveUseAmount(userCount.getLiveUseAmount() + appUserCount.getLiveUseAmount());
  102. }
  103. if (appUserCount.getLiveCommission() != null) {
  104. appUserCount.setLiveCommission(userCount.getLiveCommission() + appUserCount.getLiveCommission());
  105. }
  106. if (appUserCount.getGameWinAmount() != null) {
  107. appUserCount.setGameWinAmount(userCount.getGameWinAmount() + appUserCount.getGameWinAmount());
  108. }
  109. if (appUserCount.getGameLoseAmount() != null) {
  110. appUserCount.setGameLoseAmount(userCount.getGameLoseAmount() + appUserCount.getGameLoseAmount());
  111. }
  112. if (appUserCount.getGameCommission() != null) {
  113. appUserCount.setGameCommission(userCount.getGameCommission() + appUserCount.getGameCommission());
  114. }
  115. if (appUserCount.getGameBetting() != null) {
  116. appUserCount.setGameBetting(userCount.getGameBetting() + appUserCount.getGameBetting());
  117. }
  118. if (appUserCount.getLiveBettingCommission() != null) {
  119. appUserCount.setLiveBettingCommission(userCount.getLiveBettingCommission() + appUserCount.getLiveBettingCommission());
  120. }
  121. if (appUserCount.getLiveInvite() != null) {
  122. appUserCount.setLiveInvite(userCount.getLiveInvite() + appUserCount.getLiveInvite());
  123. }
  124. if (appUserCount.getLiveProfit() != null) {
  125. appUserCount.setLiveProfit(userCount.getLiveProfit() + appUserCount.getLiveProfit());
  126. }*/
  127. //增量更新
  128. appUserCountMapper.updateCount(appUserCount);//增量累加
  129. }else{
  130. res = appUserCountMapper.updateById(appUserCount);
  131. }
  132. }
  133. }
  134. }
  135. @Override
  136. public void staticsUserCount(Long gameId,String dateTime,String gameDate) {
  137. log.info("开始更新游戏{},期号:{},开奖统计",gameId,gameDate);
  138. Date curDate = DateUtils.getNowDate();
  139. if (StringUtils.isNotBlank(dateTime)) {
  140. curDate = DateUtil.parse(dateTime, "yyyy-MM-dd");
  141. } else {
  142. dateTime = DateUtils.parseDateToStr("yyyy-MM-dd", curDate);
  143. }
  144. /*Date lastDate = this.selectLastUpdateDate();
  145. String lastDateStr = DateUtil.format(lastDate,"yyyy-MM-dd HH:mm:ss");
  146. if(!dateTime.equals(DateUtil.format(lastDate,"yyyy-MM-dd"))){
  147. lastDateStr = DateUtil.format(curDate, "yyyy-MM-dd").concat(" 00:00:00");
  148. }
  149. String endTimeStr = DateUtil.format(curDate,"yyyy-MM-dd HH:mm:ss");*/
  150. List<AppGameBetting> gameBettingList = appGameBettingService.selectListIsWinByDate(null, null, null,gameId,gameDate);
  151. if (null != gameBettingList && gameBettingList.size() > 0) {
  152. boolean flag = redisCache.redisTemplate.opsForValue().setIfAbsent("app_game_lotty_"+gameId + "_" + gameDate,DateUtil.format(new Date(),"yyyy-MM-dd HH:ss:mm"),1,TimeUnit.DAYS);
  153. if(!flag){
  154. log.info("游戏{},期号{},当日已统计过,跳过统计",gameId,gameDate);
  155. return;
  156. }
  157. String finalDateTime = dateTime;
  158. Date finalCurDate = curDate;
  159. List<Long> userIds = gameBettingList.stream().map(AppGameBetting::getUserId).distinct().collect(Collectors.toList());
  160. userIds.forEach(userId -> {
  161. AppUserAgent appUserAgent = appUserAgentService.selectInfo(userId);
  162. if(null != appUserAgent) {
  163. AppUserCount appUserCount = new AppUserCount();
  164. appUserCount.setUserId(userId);
  165. appUserCount.setStrDate(finalDateTime);
  166. appUserCount.setAgentUserId(appUserAgent.getPid());
  167. appUserCount.setUpdateTime(finalCurDate);
  168. //游戏输
  169. appUserCount.setGameLoseAmount(gameBettingList.stream().filter(
  170. e -> e.getUserId().equals(userId) && e.getIsWinning().intValue() == 2
  171. ).mapToDouble(e ->
  172. e.getBettingAmount()
  173. ).sum());
  174. //游戏赢
  175. appUserCount.setGameWinAmount(gameBettingList.stream().filter(
  176. e -> e.getUserId().equals(userId) && e.getIsWinning().intValue() == 1
  177. ).mapToDouble(e ->
  178. e.getBettingAmount() * e.getBettingMultiple()
  179. ).sum());
  180. this.createAppUserCount(appUserCount);
  181. }
  182. });
  183. //更新周盈亏数据
  184. appUserCountDividendService.reloadCache(null,userIds);
  185. }else{
  186. log.info("游戏{},期号:{},未查到开奖数据",gameId,gameDate);
  187. }
  188. }
  189. @Override
  190. public Date selectLastUpdateDate() {
  191. LambdaQueryWrapper<AppUserCount> queryWrapper = new LambdaQueryWrapper<>();
  192. queryWrapper.orderByDesc(AppUserCount::getUpdateTime);
  193. queryWrapper.last("limit 1");
  194. AppUserCount appUserCount = appUserCountMapper.selectOne(queryWrapper);
  195. if(null == appUserCount || null == appUserCount.getUpdateTime()) {
  196. return DateUtil.beginOfDay(DateUtils.getNowDate());
  197. }
  198. return DateUtil.offsetSecond(appUserCount.getUpdateTime(), 1); //往前加1秒用于增量更新
  199. }
  200. /**
  201. * 查询最后更新时间
  202. * */
  203. @Override
  204. public Date selectLastDate() {
  205. LambdaQueryWrapper<AppUserCount> queryWrapper = new LambdaQueryWrapper<>();
  206. queryWrapper.orderByDesc(AppUserCount::getCountTime);
  207. queryWrapper.last("limit 1");
  208. AppUserCount appUserCount = appUserCountMapper.selectOne(queryWrapper);
  209. if(null == appUserCount || null == appUserCount.getCountTime()) {
  210. return DateUtil.beginOfDay(DateUtils.getNowDate());
  211. }
  212. return DateUtil.offsetSecond(appUserCount.getCountTime(), 1); //往前加1秒用于增量更新
  213. }
  214. /**
  215. * 查询最后更新时间
  216. * */
  217. @Override
  218. public Date selectGameLastDate(Long userId) {
  219. LambdaQueryWrapper<AppUserCount> queryWrapper = new LambdaQueryWrapper<>();
  220. queryWrapper.orderByDesc(AppUserCount::getGameCountTime);
  221. queryWrapper.eq(AppUserCount::getUserId,userId);
  222. queryWrapper.last("limit 1");
  223. AppUserCount appUserCount = appUserCountMapper.selectOne(queryWrapper);
  224. if(null == appUserCount || null == appUserCount.getGameCountTime()) {
  225. return DateUtil.beginOfDay(DateUtils.getNowDate());
  226. }
  227. return appUserCount.getGameCountTime(); //往前加1秒用于增量更新
  228. }
  229. @Override
  230. public void staticsUserBetting(AppGameBetting appGameBetting,List<AppUserGameRecordCount> recordCountList) {
  231. // synchronized (CacheConstants.USER_GAME_RECORD_COUNT.concat(String.valueOf(appGameBetting.getGameId())).concat(appGameBetting.getGameDate())) {
  232. Date curDate = DateUtils.getNowDate();
  233. String dateTime = DateUtils.parseDateToStr("yyyy-MM-dd", curDate);
  234. /*List<Long> userIds = gameRateList.stream().map(AppGameCommission::getUserId).collect(Collectors.toList());
  235. userIds.add(appGameBetting.getUserId());
  236. userIds = userIds.stream().distinct().collect(Collectors.toList());*/
  237. // List<AppUserGameRecordCount> gameRecordCountList = appUserGameRecordCountService.selectByDate(null, null, null,appGameBetting.getGameId(),appGameBetting.getGameDate());
  238. if (null != recordCountList && recordCountList.size() > 0) {
  239. String finalDateTime = dateTime;
  240. Date finalCurDate = curDate;
  241. List<Long> userIds = new ArrayList<>();
  242. recordCountList.forEach(gameRate -> {
  243. Long userId = gameRate.getUserId();
  244. /*//用户最后一次更新时间
  245. Date updateTime = this.selectGameLastDate(userId);
  246. if (!DateUtil.format(updateTime, "yyyy-MM-dd").equals(DateUtil.format(finalCurDate, "yyyy-MM-dd"))) {
  247. //跨天直接从当日零点开始统计
  248. updateTime = DateUtil.beginOfDay(finalCurDate);
  249. }*/
  250. //查询用户返佣
  251. // List<AppUserGameRecordCount> gameRecordCountList = appUserGameRecordCountService.selectByDate(userId, DateUtil.format(updateTime, "yyyy-MM-dd HH:mm:ss"), DateUtil.format(finalCurDate, "yyyy-MM-dd HH:mm:ss"), gameRate.getGameId(), appGameBetting.getGameDate());
  252. userIds.add(userId);
  253. AppUserCount appUserCount = new AppUserCount();
  254. appUserCount.setUserId(userId);
  255. appUserCount.setStrDate(finalDateTime);
  256. appUserCount.setAgentUserId(gameRate.getPid());
  257. appUserCount.setUpdateTime(finalCurDate);
  258. appUserCount.setGameCountTime(finalCurDate);
  259. // if (null != gameRecordCountList && gameRecordCountList.size() > 0) {
  260. //游戏佣金
  261. /*Map<String, Double> map = redisCache.getCacheMap(CacheConstants.USER_GAME_RECORD_COUNT.concat(String.valueOf(userId)));
  262. appUserCount.setGameCommission(gameRecordCountList.stream().filter(e -> {
  263. return null == map || null == map.get(String.valueOf(e.getId())); //过滤已统计过的id
  264. }).mapToDouble(e -> e.getCommission()).sum());
  265. setGameCache(gameRecordCountList);*/
  266. appUserCount.setGameCommission(gameRate.getCommission());
  267. if(gameRate.getType().intValue() == 1){
  268. appUserCount.setLiveBettingCommission(gameRate.getCommission());
  269. }
  270. // }
  271. //游戏下注金额 更新当前下注用户 (非金币)
  272. if (userId.equals(appGameBetting.getUserId()) && appGameBetting.getBettingType().intValue() == 0) {
  273. appUserCount.setGameBetting(appGameBetting.getBettingAmount());
  274. }
  275. this.createAppUserCount(appUserCount);
  276. });
  277. //更新周盈亏数据
  278. appUserCountDividendService.reloadCache(null, userIds);
  279. }
  280. // }
  281. }
  282. @Override
  283. public List<AppUserCount> getListByUserId(long userId, String beginTime, String endTIme) {
  284. LambdaQueryWrapper<AppUserCount> queryWrapper = new LambdaQueryWrapper<>();
  285. queryWrapper.eq(AppUserCount::getUserId, userId);
  286. if(StringUtils.isNotBlank(beginTime)){
  287. queryWrapper.ge(AppUserCount::getStrDate,beginTime);
  288. }
  289. if(StringUtils.isNotBlank(endTIme)){
  290. queryWrapper.le(AppUserCount::getStrDate,endTIme);
  291. }
  292. return appUserCountMapper.selectList(queryWrapper);
  293. }
  294. @Override
  295. public void setGameCache(List<AppUserGameRecordCount> gameRecordCountList) {
  296. if(null != gameRecordCountList && gameRecordCountList.size() > 0) {
  297. gameRecordCountList.forEach(e->{
  298. //凌晨定时任务清除前一天的数据
  299. redisCache.setCacheMapValue(CacheConstants.USER_GAME_RECORD_COUNT.concat(String.valueOf(e.getUserId())),String.valueOf(e.getId()),e.getCommission());
  300. });
  301. }
  302. }
  303. /**
  304. * 金额为负数则转为正数
  305. * */
  306. private double dealMoney(double money){
  307. return money<0?money*-1:money;
  308. }
  309. }