AppUserCountTask.java 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. package com.game.business.task;
  2. import cn.hutool.core.date.DateUtil;
  3. import com.alibaba.fastjson2.JSONObject;
  4. import com.baomidou.dynamic.datasource.annotation.DSTransactional;
  5. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  6. import com.game.business.domain.*;
  7. import com.game.business.service.*;
  8. import com.game.business.util.im.HttpClientUtils;
  9. import com.game.business.vo.OffLineUserVo;
  10. import com.game.common.constant.CacheConstants;
  11. import com.game.common.constant.finance.FinTranType1;
  12. import com.game.common.constant.finance.FinTranType2;
  13. import com.game.common.constant.finance.FinTranType3;
  14. import com.game.common.core.domain.HttpRet;
  15. import com.game.common.core.domain.R;
  16. import com.game.common.core.redis.RedisCache;
  17. import com.game.common.entity.KeyValue;
  18. import com.game.common.utils.DateUtils;
  19. import com.game.common.utils.StringUtils;
  20. import com.game.system.service.ISysConfigService;
  21. import lombok.extern.log4j.Log4j2;
  22. import org.springframework.beans.factory.annotation.Autowired;
  23. import org.springframework.beans.factory.annotation.Value;
  24. import org.springframework.stereotype.Component;
  25. import java.math.BigDecimal;
  26. import java.util.*;
  27. import java.util.concurrent.TimeUnit;
  28. import java.util.function.Function;
  29. import java.util.stream.Collectors;
  30. @Component("appUserCountTask")
  31. @Log4j2
  32. public class AppUserCountTask {
  33. @Autowired
  34. private IAppUsersChargeService appUsersChargeService;
  35. @Autowired
  36. private IAppUserService appUserService;
  37. @Autowired
  38. private IAppUsersCashrecordService appUsersCashrecordService;
  39. @Autowired
  40. private IFinTranRecordService finTranRecordService;
  41. @Autowired
  42. private IAppUserLiveDividedRecordService appUserLiveDividedRecordService;
  43. @Autowired
  44. private IAppUserGameRecordCountService appUserGameRecordCountService;
  45. @Autowired
  46. private IAppGameBettingService appGameBettingService;
  47. @Autowired
  48. private IAppUserCountService appUserCountService;
  49. @Autowired
  50. private IAppUserGameCountService appUserGameCountService;
  51. @Autowired
  52. private IAppUserAgentService appUserAgentService;
  53. @Autowired
  54. private IAppUserCountDividendService appUserCountDividendService;
  55. @Autowired
  56. private ISysConfigService sysConfigService;
  57. @Autowired
  58. private RedisCache redisCache;
  59. @Value("${task.switch}")
  60. private Boolean taskSwitch;
  61. /**
  62. * 统计用户前一天
  63. * */
  64. public void statistics(String dateTime){
  65. if(!taskSwitch){
  66. return;
  67. }
  68. String redisKey = CacheConstants.USER_STATICS_COUNT.concat("statistics");
  69. /*if(!redisCache.redisTemplate.opsForValue().setIfAbsent(redisKey,1)){
  70. log.info("停止统计用户每日直播、游戏、佣金,已在其他机器执行");
  71. return;
  72. }*/
  73. log.info("开始统计用户每日直播、游戏、佣金");
  74. try {
  75. Date curDate = DateUtil.offsetDay(DateUtils.getNowDate(), -1);
  76. if (StringUtils.isNotBlank(dateTime)) {
  77. curDate = DateUtil.parse(dateTime, "yyyy-MM-dd");
  78. } else {
  79. //清除前一天游戏返佣缓存
  80. dateTime = DateUtils.parseDateToStr("yyyy-MM-dd", curDate);
  81. }
  82. AppUser queryUser = new AppUser();
  83. queryUser.setAgentFlag(1);
  84. List<AppUser> list = appUserService.selectAppUserList(queryUser);//查询所有代理用户
  85. List<AppUsersCharge> appUsersChargeList = appUsersChargeService.getChargeList(null, dateTime.concat(" 00:00:00"), dateTime.concat(" 23:59:59"));
  86. List<AppUsersCashrecord> appUsersCashrecords = appUsersCashrecordService.getUserCashList(null, dateTime.concat(" 00:00:00"), dateTime.concat(" 23:59:59"));
  87. List<FinTranRecord> finTranRecordList = finTranRecordService.getUserRecordList(null, dateTime.concat(" 00:00:00"), dateTime.concat(" 23:59:59"));
  88. List<AppUserLiveDividedRecord> liveDividedRecordList = appUserLiveDividedRecordService.selectByDate(null, dateTime.concat(" 00:00:00"), dateTime.concat(" 23:59:59"));
  89. List<AppUserGameRecordCount> gameRecordCountList = appUserGameRecordCountService.selectByDate(null, dateTime.concat(" 00:00:00"), dateTime.concat(" 23:59:59"),null,null);
  90. List<AppGameBetting> gameBettingList = appGameBettingService.selectListByDate(null, dateTime.concat(" 00:00:00"), dateTime.concat(" 23:59:59"),null,null,null,0);
  91. Date nowDate = new Date();
  92. if (null != list && list.size() > 0) {
  93. List<AppUserCount> appUserCountList = new ArrayList<>();
  94. String finalDateTime = dateTime;
  95. list.forEach(appUser -> {
  96. AppUserCount appUserCount = new AppUserCount();
  97. appUserCount.setUserId(appUser.getUserid());
  98. appUserCount.setStrDate(finalDateTime);
  99. appUserCount.setAgentUserId(appUser.getPid());
  100. appUserCount.setUpdate(true);//全量更新
  101. appUserCount.setCountTime(nowDate);
  102. appUserCount.setGameCountTime(nowDate);
  103. appUserCount.setUpdateTime(nowDate);
  104. //充值总额
  105. appUserCount.setRechargeAmount(appUsersChargeList.stream().filter(e -> e.getUid().equals(appUser.getUserid())).mapToDouble(e -> e.getCoin().doubleValue()).sum());
  106. //提现金额
  107. appUserCount.setWithdrawalAmount(appUsersCashrecords.stream().filter(e -> e.getUid().equals(appUser.getUserid())).mapToDouble(e -> e.getMoney().doubleValue()).sum());
  108. //充值服务费/手续费
  109. appUserCount.setRechargeCommission(appUsersChargeList.stream().filter(e -> e.getUid().equals(appUser.getUserid())).mapToDouble(e -> e.getPlatformService()).sum());
  110. //充值赠送余额
  111. /*appUserCount.setRechargeGive(finTranRecordList.stream().filter(e -> {
  112. return e.getUid().equals(appUser.getUserid()) &&
  113. e.getTranType1().intValue() == FinTranType1.U_Income_Coin_Balance.getType() &&
  114. e.getTranType3().intValue() == FinTranType3.CHARGE_IN_REWARD.getType();
  115. }).mapToDouble(e->e.getCoinChange()).sum()); */
  116. appUserCount.setRechargeGive(appUsersChargeList.stream().filter(e -> {
  117. return e.getUid().equals(appUser.getUserid());
  118. }).mapToDouble(e->null==e.getCoinGive()?0:e.getCoinGive().doubleValue()).sum());
  119. //提现服务费/手续费
  120. appUserCount.setWithdrawalCommission(appUsersCashrecords.stream().filter(e -> e.getUid().equals(appUser.getUserid())).mapToDouble(e -> e.getService().doubleValue()).sum());
  121. //直播消费金额
  122. Map<String, KeyValue> type1Keys = Arrays.stream(FinTranType1.getKeyValues(1)).collect(Collectors.toMap(e -> e.a, Function.identity(), (k1, k2) -> k2)); //支出交易类型
  123. Map<String, KeyValue> type3Keys = Arrays.stream(FinTranType3.getKeyValues(1)).collect(Collectors.toMap(e -> e.a, Function.identity(), (k1, k2) -> k2)); //支出交易类型
  124. appUserCount.setLiveUseAmount(finTranRecordList.stream().filter(e -> {
  125. return e.getUid().equals(appUser.getUserid()) &&
  126. null != type1Keys.get(String.valueOf(e.getTranType1().intValue())) &&
  127. null != type3Keys.get(String.valueOf(e.getTranType3().intValue()));
  128. }).mapToDouble(e -> dealMoney(e.getCoinChange())).sum());
  129. //直播佣金
  130. appUserCount.setLiveCommission(liveDividedRecordList.stream().filter(e -> e.getUserId().equals(appUser.getUserid())).mapToDouble(e -> e.getMoney().doubleValue()).sum());
  131. //游戏下注金额
  132. appUserCount.setGameBetting(gameBettingList.stream().filter(e->e.getUserId().equals(appUser.getUserid())).mapToDouble(AppGameBetting::getBettingAmount).sum());
  133. //游戏佣金
  134. appUserCount.setGameCommission(gameRecordCountList.stream().filter(e -> e.getUserId().equals(appUser.getUserid())).mapToDouble(e -> e.getCommission()).sum());
  135. //直播间下注佣金
  136. appUserCount.setLiveBettingCommission(gameRecordCountList.stream().filter(e -> e.getUserId().equals(appUser.getUserid()) && 1 == e.getType().intValue()).mapToDouble(e -> e.getCommission()).sum());
  137. //游戏输
  138. appUserCount.setGameLoseAmount(gameBettingList.stream().filter(
  139. e -> e.getUserId().equals(appUser.getUserid()) && e.getIsWinning().intValue() == 2
  140. ).mapToDouble(e ->
  141. e.getBettingAmount()
  142. ).sum());
  143. //游戏赢
  144. appUserCount.setGameWinAmount(gameBettingList.stream().filter(
  145. e -> e.getUserId().equals(appUser.getUserid()) && e.getIsWinning().intValue() == 1
  146. ).mapToDouble(e ->
  147. e.getBettingAmount() * e.getBettingMultiple()
  148. ).sum());
  149. //邀请奖励
  150. appUserCount.setLiveInvite(finTranRecordList.stream().filter(e->
  151. e.getUid().equals(appUser.getUserid()) &&
  152. FinTranType3.CHARGE_IN_INVITE.getType() == e.getTranType3().intValue()
  153. ).mapToDouble(FinTranRecord::getCoinChange).sum());
  154. //直播收益
  155. List<Integer> profitTypeList = Arrays.asList(
  156. FinTranType3.RECOMMEND_ADD_AMOUNT.getType()
  157. );
  158. appUserCount.setLiveProfit(finTranRecordList.stream().filter(e->
  159. e.getUid().equals(appUser.getUserid()) &&
  160. profitTypeList.contains(e.getTranType3()) &&
  161. FinTranType1.U_Income_Coin.getType() == e.getTranType1().intValue()&&
  162. FinTranType2.REWARD_Income.getType() == e.getTranType2().intValue()
  163. ).mapToDouble(FinTranRecord::getCoinChange).sum());
  164. appUserCountService.createAppUserCount(appUserCount);
  165. });
  166. }
  167. //统计游戏返佣缓存
  168. appUserCountService.setGameCache(gameRecordCountList);
  169. //统计当日用户游戏输赢
  170. if (null != gameBettingList && gameBettingList.size() > 0) {
  171. Map<String, List<AppGameBetting>> map = gameBettingList.stream().
  172. collect(Collectors.groupingBy(
  173. e -> String.valueOf(e.getUserId()).concat("_").
  174. concat(String.valueOf(e.getGameId())).
  175. concat("_").concat(String.valueOf(e.getIsWinning()))
  176. ));
  177. for (String key : map.keySet()) {
  178. List<AppGameBetting> appGameBettingList = map.get(key);
  179. Long userId = Long.valueOf(key.split("_")[0]);
  180. Long gameId = Long.valueOf(key.split("_")[1]);
  181. AppUserGameCount appUserGameCount = new AppUserGameCount();
  182. appUserGameCount.setUserId(userId);
  183. appUserGameCount.setGameId(gameId);
  184. appUserGameCount.setStrDate(dateTime);
  185. appUserGameCount.setGameLoseAmount(appGameBettingList.stream().filter(e -> 2 == e.getIsWinning()).mapToDouble(
  186. e -> e.getBettingAmount()
  187. ).sum());
  188. appUserGameCount.setGameWinAmount(appGameBettingList.stream().filter(e -> 2 == e.getIsWinning()).mapToDouble(
  189. e -> e.getBettingAmount() * e.getBettingMultiple()
  190. ).sum());
  191. appUserGameCount.setGameCommission(gameRecordCountList.stream().filter(
  192. e -> e.getUserId().equals(userId) && e.getGameId().equals(gameId)
  193. ).mapToDouble(e -> e.getCommission()).sum());//自己得到的佣金
  194. appUserGameCountService.save(appUserGameCount);
  195. }
  196. }
  197. }catch (Exception e){
  198. log.info("用户每日直播、游戏、佣金统计异常:{}",e.getMessage());
  199. } finally {
  200. redisCache.redisTemplate.delete(redisKey);
  201. }
  202. log.info("用户每日直播、游戏、佣金统计完成");
  203. }
  204. /**
  205. * 统计用户直播/充值 (增量更新 1分钟)
  206. * */
  207. public void statisticsLive(){
  208. if(!taskSwitch){
  209. return;
  210. }
  211. String redisKey = CacheConstants.USER_STATICS_COUNT.concat("statisticsLive");
  212. /*if(!redisCache.redisTemplate.opsForValue().setIfAbsent(redisKey,1)){
  213. log.info("停止增量更新用户每日直播、佣金,已在其他机器执行");
  214. return;
  215. }*/
  216. log.info("开始增量更新用户每日直播、佣金");
  217. try {
  218. Long userId = null;
  219. Date curDate = new Date();
  220. String dateTime = DateUtil.format(curDate, "yyyy-MM-dd");
  221. Date lastDate = appUserCountService.selectLastDate();
  222. /*String lastDateStr = DateUtil.format(lastDate,"yyyy-MM-dd HH:mm:ss");
  223. if(!dateTime.equals(DateUtil.format(lastDate,"yyyy-MM-dd"))){
  224. lastDateStr = DateUtil.format(curDate, "yyyy-MM-dd").concat(" 00:00:00");
  225. }*/
  226. String lastDateStr = DateUtil.format(curDate, "yyyy-MM-dd" + " 00:00:00");
  227. String endTimeStr = DateUtil.format(curDate,"yyyy-MM-dd HH:mm:ss");
  228. AppUser queryUser = new AppUser();
  229. queryUser.setAgentFlag(1);
  230. List<AppUser> list = appUserService.selectAppUserList(queryUser);//查询所有代理用户
  231. List<AppUsersCharge> appUsersChargeList = appUsersChargeService.getChargeList(userId, lastDateStr, endTimeStr);
  232. List<AppUsersCashrecord> appUsersCashrecords = appUsersCashrecordService.getUserCashList(userId, lastDateStr, endTimeStr);
  233. List<FinTranRecord> finTranRecordList = finTranRecordService.getUserRecordList(null!=userId?String.valueOf(userId):null, lastDateStr, endTimeStr);
  234. List<AppUserLiveDividedRecord> liveDividedRecordList = appUserLiveDividedRecordService.selectByDate(userId, lastDateStr, endTimeStr);
  235. if (null != list && list.size() > 0) {
  236. // List<AppUserCount> appUserCountList = new ArrayList<>();
  237. String finalDateTime = dateTime;
  238. list.forEach(appUser -> {
  239. AppUserCount appUserCount = new AppUserCount();
  240. appUserCount.setUserId(appUser.getUserid());
  241. appUserCount.setStrDate(finalDateTime);
  242. appUserCount.setAgentUserId(appUser.getPid());
  243. appUserCount.setCountTime(curDate);
  244. //充值总额
  245. appUserCount.setRechargeAmount(appUsersChargeList.stream().filter(e -> e.getUid().equals(appUser.getUserid())).mapToDouble(e -> e.getCoin().doubleValue()).sum());
  246. //提现金额
  247. appUserCount.setWithdrawalAmount(appUsersCashrecords.stream().filter(e -> e.getUid().equals(appUser.getUserid())).mapToDouble(e -> e.getMoney().doubleValue()).sum());
  248. //充值服务费/手续费
  249. appUserCount.setRechargeCommission(appUsersChargeList.stream().filter(e -> e.getUid().equals(appUser.getUserid())).mapToDouble(e -> e.getPlatformService()).sum());
  250. //充值赠送余额
  251. /*appUserCount.setRechargeGive(finTranRecordList.stream().filter(e -> {
  252. return e.getUid().equals(appUser.getUserid()) &&
  253. e.getTranType1().intValue() == FinTranType1.U_Income_Coin_Balance.getType() &&
  254. e.getTranType3().intValue() == FinTranType3.CHARGE_IN_REWARD.getType();
  255. }).mapToDouble(e->e.getCoinChange()).sum());*/
  256. appUserCount.setRechargeGive(appUsersChargeList.stream().filter(e -> {
  257. return e.getUid().equals(appUser.getUserid());
  258. }).mapToDouble(e->null==e.getCoinGive()?0:e.getCoinGive().doubleValue()).sum());
  259. //提现服务费/手续费
  260. appUserCount.setWithdrawalCommission(appUsersCashrecords.stream().filter(e -> e.getUid().equals(appUser.getUserid())).mapToDouble(e -> e.getService().doubleValue()).sum());
  261. //直播消费金额
  262. Map<String, KeyValue> type1Keys = Arrays.stream(FinTranType1.getKeyValues(1)).collect(Collectors.toMap(e -> e.a, Function.identity(), (k1, k2) -> k2)); //支出交易类型
  263. Map<String, KeyValue> type3Keys = Arrays.stream(FinTranType3.getKeyValues(1)).collect(Collectors.toMap(e -> e.a, Function.identity(), (k1, k2) -> k2)); //支出交易类型
  264. appUserCount.setLiveUseAmount(finTranRecordList.stream().filter(e -> {
  265. return e.getUid().equals(appUser.getUserid()) &&
  266. null != type1Keys.get(String.valueOf(e.getTranType1().intValue())) &&
  267. null != type3Keys.get(String.valueOf(e.getTranType3().intValue()));
  268. }).mapToDouble(e -> dealMoney(e.getCoinChange())).sum());
  269. //直播佣金
  270. appUserCount.setLiveCommission(liveDividedRecordList.stream().filter(e -> e.getUserId().equals(appUser.getUserid())).mapToDouble(e -> e.getMoney().doubleValue()).sum());
  271. //邀请奖励
  272. appUserCount.setLiveInvite(finTranRecordList.stream().filter(e->
  273. e.getUid().equals(appUser.getUserid()) &&
  274. FinTranType3.CHARGE_IN_INVITE.getType() == e.getTranType3().intValue()
  275. ).mapToDouble(FinTranRecord::getCoinChange).sum());
  276. //直播收益
  277. List<Integer> profitTypeList = Arrays.asList(
  278. FinTranType3.RECOMMEND_ADD_AMOUNT.getType()
  279. );
  280. appUserCount.setLiveProfit(finTranRecordList.stream().filter(e->
  281. e.getUid().equals(appUser.getUserid()) &&
  282. profitTypeList.contains(e.getTranType3()) &&
  283. FinTranType1.U_Income_Coin.getType() == e.getTranType1().intValue()&&
  284. FinTranType2.REWARD_Income.getType() == e.getTranType2().intValue()
  285. ).mapToDouble(FinTranRecord::getCoinChange).sum());
  286. appUserCount.setUpdate(true);
  287. appUserCountService.createAppUserCount(appUserCount);
  288. });
  289. }
  290. }catch (Exception e){
  291. log.info("增量更新用户每日直播、佣金统计异常:{}",e.getMessage());
  292. } finally {
  293. redisCache.redisTemplate.delete(redisKey);
  294. }
  295. log.info("增量更新用户每日直播、佣金统计完成");
  296. }
  297. /**
  298. * 计算分红
  299. * @param dateTime 格式yyyy-MM-dd
  300. * */
  301. @DSTransactional
  302. public void calculateDividends(String dateTime){
  303. if(!taskSwitch){
  304. return;
  305. }
  306. String redisKey = CacheConstants.USER_STATICS_COUNT.concat("calculateDividends");
  307. /*if(!redisCache.redisTemplate.opsForValue().setIfAbsent(redisKey,1)){
  308. log.info("停止每周代理分红,已在其他机器执行");
  309. return;
  310. }*/
  311. try {
  312. log.info("开始每周代理分红");
  313. String dateNo = dealDividendsNew(dateTime);
  314. log.info("每周代理分红完成");
  315. log.info("开始给系统用户的直属下级自动发放分红");
  316. AppUser queryUser = new AppUser();
  317. queryUser.setPid(0L);
  318. List<AppUser> list = appUserService.selectAppUserList(queryUser);
  319. if(null != list && list.size() > 0){
  320. for(AppUser appUser : list){
  321. HttpRet<Boolean> httpRet = appUserCountDividendService.send(null,dateNo,appUser.getUserid());
  322. if(HttpRet.FAIL == httpRet.getCode()){
  323. log.info("{}用户,{}",appUser.getUserid(),httpRet.getMsg());
  324. }
  325. }
  326. }
  327. log.info("系统用户的直属下级自动发放分红完成");
  328. }catch (Exception e){
  329. log.info("每周分红失败:{}",e.getMessage());
  330. }finally {
  331. redisCache.redisTemplate.delete(redisKey);
  332. }
  333. }
  334. /**
  335. * 分红(已废弃)
  336. * */
  337. private void dealDividends(String dateTime){
  338. Date curDate = DateUtil.offsetDay(DateUtils.getNowDate(), -1);
  339. if (StringUtils.isNotBlank(dateTime)) {
  340. curDate = DateUtil.parse(dateTime, "yyyy-MM-dd");
  341. } else {
  342. dateTime = DateUtils.parseDateToStr("yyyy-MM-dd", curDate);
  343. }
  344. Date beginTime = DateUtil.beginOfWeek(curDate);
  345. Date endTime = DateUtil.endOfWeek(curDate);
  346. //查询所有总代理用户
  347. AppUser queryUser = new AppUser();
  348. queryUser.setAgentFlag(1);
  349. List<AppUser> list = appUserService.selectAppUserList(queryUser);
  350. // List<AppUser> list = appUserService.selectTeamUserList();
  351. if (null != list && list.size() > 0) {
  352. list.forEach(appUser -> {
  353. String beginTimeStr = DateUtil.format(beginTime,"yyyy-MM-dd");
  354. String endTimeStr = DateUtil.format(endTime,"yyyy-MM-dd");
  355. //查询用户所有下级本周盈亏
  356. /*LambdaQueryWrapper<AppUserCount> queryWrapper = new LambdaQueryWrapper<>();
  357. queryWrapper.ge(AppUserCount::getStrDate, beginTimeStr);
  358. queryWrapper.le(AppUserCount::getStrDate, endTimeStr);
  359. queryWrapper.eq(AppUserCount::getAgentUserId, appUser.getUserid());
  360. List<AppUserCount> appUserCountList = appUserCountService.list(queryWrapper);*/
  361. List<AppUserCount> appUserCountList = appUserCountService.getAppUserCountNew(appUser.getUserid(),beginTimeStr,endTimeStr);
  362. if (null != appUserCountList && appUserCountList.size() > 0) {
  363. //游戏输钱
  364. double loseAmount = appUserCountList.stream().mapToDouble(e -> e.getGameLoseAmount()).sum();
  365. //游戏赢钱
  366. double winAmount = appUserCountList.stream().mapToDouble(e -> e.getGameWinAmount()).sum();
  367. //提现手续费
  368. double withdrawalCommission = appUserCountList.stream().mapToDouble(e -> e.getWithdrawalCommission()).sum();
  369. //游戏佣金
  370. double gameCommission = appUserCountList.stream().mapToDouble(e -> e.getGameCommission()).sum();
  371. //直播佣金
  372. double liveCommission = appUserCountList.stream().mapToDouble(e -> e.getLiveCommission()).sum();
  373. //充值赠送
  374. double rechargeGive = appUserCountList.stream().mapToDouble(e -> e.getRechargeGive()).sum();
  375. //计算分红金额 (输-赢)
  376. // double money = (loseAmount - winAmount) - withdrawalCommission - gameCommission - liveCommission;
  377. double money = (loseAmount - winAmount) - gameCommission - rechargeGive;
  378. if (money > 0) {
  379. //金额大于0 满足分红
  380. //查询当前用户所有下级
  381. AppUserAgent queryAppUserAgent = new AppUserAgent();
  382. queryAppUserAgent.setPid(appUser.getUserid());
  383. List<AppUserAgent> appUserAgentList = appUserAgentService.selectAppUserAgentList(queryAppUserAgent);
  384. if (null != appUserAgentList && appUserAgentList.size() > 0) {
  385. appUserAgentList.forEach(userAgent -> {
  386. if (userAgent.getDividendGuaranteeRate() <= 0.00) {
  387. log.info("用户{},团队亏损{},或未设置分红比例,停止分红", userAgent.getUserId(), money);
  388. return;
  389. }
  390. double rate = userAgent.getDividendGuaranteeRate();
  391. double dividends = BigDecimal.valueOf(money * rate/100).setScale(4,BigDecimal.ROUND_HALF_UP).doubleValue();
  392. AppUserCountDividend appUserCountDividend = new AppUserCountDividend();
  393. appUserCountDividend.setUserId(userAgent.getUserId());
  394. appUserCountDividend.setDateNo(DateUtil.format(endTime, "yyyy-MM-dd"));
  395. appUserCountDividend.setBeginTime(beginTime);
  396. appUserCountDividend.setEndTime(endTime);
  397. appUserCountDividend.setProfitLoss(money);
  398. appUserCountDividend.setRate(rate);
  399. appUserCountDividend.setCoin(0.00);
  400. appUserCountDividend.setDiamondCoin(dividends);
  401. appUserCountDividend.setStatus(0);
  402. appUserCountDividendService.insertAppUserCountDividend(appUserCountDividend);
  403. });
  404. } else {
  405. log.info("用户{},所有下级亏损{},查询下级为空,停止分红", appUser.getUserid(), money);
  406. }
  407. } else {
  408. log.info("用户{},所有下级亏损{},不满足分红条件", appUser.getUserid(), money);
  409. }
  410. }
  411. });
  412. }
  413. }
  414. /**
  415. * 分红
  416. * */
  417. private String dealDividendsNew(String dateTime){
  418. String resDate = "";
  419. Date curDate = DateUtil.offsetDay(DateUtils.getNowDate(), -1);
  420. if (StringUtils.isNotBlank(dateTime)) {
  421. curDate = DateUtil.parse(dateTime, "yyyy-MM-dd");
  422. } else {
  423. dateTime = DateUtils.parseDateToStr("yyyy-MM-dd", curDate);
  424. }
  425. Date beginTime = DateUtil.beginOfWeek(curDate);
  426. Date endTime = DateUtil.endOfWeek(curDate);
  427. /*Date weekBegin = null;
  428. Date weekend = null;*/
  429. int curDay = Integer.parseInt(DateUtil.format(curDate,"dd"));
  430. if(curDay <= 15){
  431. beginTime = DateUtil.beginOfMonth(curDate);
  432. endTime = DateUtil.parse(DateUtil.format(curDate,"yyyy-MM-".concat("15").concat(" 23:59:59")),"yyyy-MM-dd HH:mm:ss");
  433. }else{
  434. beginTime = DateUtil.parse(DateUtil.format(curDate,"yyyy-MM-".concat("15").concat(" 00:00:00")),"yyyy-MM-dd HH:mm:ss");
  435. endTime = DateUtil.endOfMonth(curDate);
  436. }
  437. resDate = DateUtil.format(endTime, "yyyy-MM-dd");
  438. //查询所有总代理用户
  439. AppUser queryUser = new AppUser();
  440. queryUser.setAgentFlag(1);
  441. List<AppUser> list = appUserService.selectAppUserList(queryUser);
  442. // List<AppUser> list = appUserService.selectTeamUserList();
  443. if (null != list && list.size() > 0) {
  444. Date finalBeginTime = beginTime;
  445. Date finalEndTime = endTime;
  446. list.forEach(appUser -> {
  447. AppUserAgent userAgent = appUserAgentService.selectInfo(appUser.getUserid());
  448. if (userAgent.getDividendGuaranteeRate() <= 0.00) {
  449. log.info("用户{},未设置分红比例,停止分红", userAgent.getUserId());
  450. return;
  451. }
  452. String beginTimeStr = DateUtil.format(finalBeginTime,"yyyy-MM-dd");
  453. String endTimeStr = DateUtil.format(finalEndTime,"yyyy-MM-dd");
  454. //查询用户所有下级本周盈亏
  455. /*LambdaQueryWrapper<AppUserCount> queryWrapper = new LambdaQueryWrapper<>();
  456. queryWrapper.ge(AppUserCount::getStrDate, beginTimeStr);
  457. queryWrapper.le(AppUserCount::getStrDate, endTimeStr);
  458. queryWrapper.eq(AppUserCount::getAgentUserId, appUser.getUserid());
  459. List<AppUserCount> appUserCountList = appUserCountService.list(queryWrapper);*/
  460. List<AppUserCount> appUserCountList = appUserCountService.getAppUserCountNew(appUser.getUserid(),beginTimeStr,endTimeStr);
  461. if (null != appUserCountList && appUserCountList.size() > 0) {
  462. //游戏输钱
  463. double loseAmount = appUserCountList.stream().mapToDouble(e -> e.getGameLoseAmount()).sum();
  464. //游戏赢钱
  465. double winAmount = appUserCountList.stream().mapToDouble(e -> {
  466. return e.getGameWinAmount() - (e.getGameBetting() - e.getGameLoseAmount()); //实际赢钱 = 赢 - 中奖本金
  467. }).sum();
  468. //提现手续费
  469. List<AppUsersCashrecord> usersCashrecords = appUsersCashrecordService.getUserCashListByIds(appUserCountList.stream().map(AppUserCount::getUserId).collect(Collectors.toList()), beginTimeStr.concat(" 00:00:00"),endTimeStr.concat(" 23:59:59"));
  470. // double withdrawalCommission = appUserCountList.stream().mapToDouble(e -> e.getWithdrawalCommission()).sum();
  471. double withdrawalCommission = null==usersCashrecords?0.00:usersCashrecords.stream().mapToDouble(e->{return null==e.getPlatformService()?0.00:e.getPlatformService().doubleValue();}).sum();
  472. //充值手续费
  473. double rechargeCommission = appUserCountList.stream().mapToDouble(e -> e.getRechargeCommission()).sum();
  474. //游戏佣金
  475. double gameCommission = appUserCountList.stream().mapToDouble(e -> e.getGameCommission()).sum();
  476. //直播佣金
  477. double liveCommission = appUserCountList.stream().mapToDouble(e -> e.getLiveCommission()).sum();
  478. //充值赠送
  479. double rechargeGive = appUserCountList.stream().mapToDouble(e -> e.getRechargeGive()).sum();
  480. //计算分红金额 (输-赢)
  481. // double money = (loseAmount - winAmount) - withdrawalCommission - gameCommission - liveCommission;
  482. double money = (loseAmount - winAmount) - gameCommission - rechargeGive - rechargeCommission - withdrawalCommission;
  483. if (money > 0) {
  484. //金额大于0 满足分红
  485. double rate = userAgent.getDividendGuaranteeRate();
  486. double dividends = BigDecimal.valueOf(money * rate/100).setScale(4,BigDecimal.ROUND_HALF_UP).doubleValue();
  487. AppUserCountDividend appUserCountDividend = new AppUserCountDividend();
  488. appUserCountDividend.setUserId(userAgent.getUserId());
  489. appUserCountDividend.setDateNo(DateUtil.format(finalEndTime, "yyyy-MM-dd"));
  490. appUserCountDividend.setBeginTime(finalBeginTime);
  491. appUserCountDividend.setEndTime(finalEndTime);
  492. appUserCountDividend.setProfitLoss(money);
  493. appUserCountDividend.setRate(rate);
  494. appUserCountDividend.setCoin(0.00);
  495. appUserCountDividend.setDiamondCoin(dividends);
  496. appUserCountDividend.setStatus(0);
  497. appUserCountDividendService.insertAppUserCountDividend(appUserCountDividend);
  498. } else {
  499. log.info("用户{},所有下级亏损{},没有亏损停止分红", appUser.getUserid(), money);
  500. }
  501. } else {
  502. log.info("用户{},团队没有流水停止分红", appUser.getUserid());
  503. }
  504. });
  505. }
  506. return resDate;
  507. }
  508. /**
  509. * 更新用户下级列表
  510. * */
  511. public void statisticsTeam(){
  512. if(!taskSwitch){
  513. return;
  514. }
  515. AppUserAgent query = new AppUserAgent();
  516. List<AppUserAgent> userAgents = appUserAgentService.selectAppUserAgentList(query);
  517. userAgents.forEach(appUserAgent -> {
  518. AppUserAgent updateAgent = new AppUserAgent();
  519. updateAgent.setId(appUserAgent.getId());
  520. List<String> userIds = userAgents.stream().filter(e->e.getPid().equals(appUserAgent.getUserId())).map(e->{return String.valueOf(e.getUserId());}).collect(Collectors.toList());
  521. updateAgent.setSubset(String.join(",",userIds));
  522. appUserAgentService.updateAppUserAgent(updateAgent);
  523. });
  524. }
  525. public void reloadDividendCache(String dateTime,String topUserId){
  526. if(!taskSwitch){
  527. return;
  528. }
  529. appUserCountDividendService.reloadCache(dateTime,StringUtils.isBlank(topUserId)?null:Arrays.asList(Long.valueOf(topUserId)));
  530. }
  531. //凌晨清除缓存
  532. public void cleanCache(){
  533. redisCache.deleteObject(CacheConstants.USER_GAME_RECORD_COUNT.concat("*"));
  534. }
  535. /**
  536. * 金额为负数则转为正数
  537. * */
  538. private double dealMoney(double money){
  539. return money<0?money*-1:money;
  540. }
  541. /**
  542. * 更新用户充值后是否满足流水
  543. *
  544. * */
  545. @DSTransactional
  546. public void calculationWithdraw(Long userId){
  547. if(null != userId && userId.longValue() == -1){
  548. userId = null;
  549. if(!taskSwitch){
  550. return;
  551. }
  552. }
  553. //查询所有未满足提现的充值、转账
  554. String chargeType3 = FinTranType3.ON_LINE_CHARGE.getType() + "," + FinTranType3.CHARGE_IN.getType()+ "," + FinTranType3.CHARGE_IN_Back.getType()
  555. + "," + FinTranType3.TRANSFER_TO_TEAM_DiamondCoin.getType();
  556. List<FinTranRecord> chargeList = finTranRecordService.selectUserTran(FinTranType1.U_Income_Coin_Balance.getType(),chargeType3,userId,null,null,0);
  557. if(null != chargeList && chargeList.size() > 0) {
  558. Map<Long, List<FinTranRecord>> chargeMap = chargeList.stream().collect(Collectors.groupingBy(FinTranRecord::getUid));
  559. for(Long uid:chargeMap.keySet()){
  560. List<FinTranRecord> userChargeList = chargeMap.get(uid);
  561. //按时间排序
  562. userChargeList = userChargeList.stream().sorted(Comparator.comparing(FinTranRecord::getCreateTime)).collect(Collectors.toList());
  563. Date beginDate= null;
  564. Double money = 0.00;//需要满足的投注流水
  565. Date endDate = new Date();
  566. int i = 1;
  567. List<FinTranRecord> dealTranList = new ArrayList<>();
  568. for (FinTranRecord tranRecord : userChargeList) {
  569. dealTranList.add(tranRecord);
  570. if (null == beginDate){
  571. beginDate = tranRecord.getCreateTime();
  572. }
  573. if(userChargeList.size() > i){
  574. endDate = new Date(userChargeList.get(i).getCreateTime().getTime() - 1);
  575. }else{
  576. endDate = new Date();
  577. }
  578. money += tranRecord.getDiamondCoinChange();
  579. //查询赠送金额
  580. AppUsersCharge appUsersCharge = appUsersChargeService.selectByOrderNo(String.valueOf(tranRecord.getTranGroupId()));
  581. if(null != appUsersCharge && null != appUsersCharge.getCoinGive()){
  582. money += appUsersCharge.getCoinGive().doubleValue();
  583. }
  584. dealTran(dealTranList,beginDate,endDate,uid,money);
  585. i++;
  586. }
  587. }
  588. }
  589. }
  590. private void dealTran(List<FinTranRecord> userChargeList,Date beginDate,Date endDate,Long userId,Double money){
  591. //查询用户这段时间流水记录
  592. String type3s = FinTranType3.CONSUM_GAME_ANCHOR_ZHUANPAN.getType() + "," + FinTranType3.CONSUM_GAME_ANCHOR_WITHDRAW.getType();
  593. List<FinTranRecord> curTranList = finTranRecordService.selectUserTran(null,type3s,userId,beginDate,endDate,0);
  594. if(null != curTranList && curTranList.size() > 0){
  595. //筛选投注流水
  596. double bettingAmount = curTranList.stream().filter(e->
  597. e.getCurrencyType().intValue() == 4
  598. ).mapToDouble(FinTranRecord::getDiamondCoinChange).sum() * -1;
  599. log.info("用户{},充值:{} 以满足流水:{}",userId,money,bettingAmount);
  600. if(bettingAmount >= money * 2){
  601. //更新为已满足提现
  602. userChargeList.forEach(e->{
  603. FinTranRecord updateTran = new FinTranRecord();
  604. updateTran.setId(e.getId());
  605. updateTran.setWithdrawFlag(1);
  606. finTranRecordService.updateFinTranRecord(updateTran);
  607. });
  608. //更新可提现余额
  609. updateWithdrawAble(userId);
  610. }
  611. }
  612. }
  613. /**
  614. * 更新用户可提现余额
  615. * */
  616. @DSTransactional()
  617. public void updateWithdrawAble(Long userId){
  618. if(null != userId && userId.longValue() == -1){
  619. userId = null;
  620. }
  621. //查询所有已满足提现的充值、转账
  622. String chargeType3 = FinTranType3.ON_LINE_CHARGE.getType() + "," + FinTranType3.CHARGE_IN.getType()+ "," + FinTranType3.CHARGE_IN_Back.getType()
  623. + "," + FinTranType3.TRANSFER_TO_TEAM_DiamondCoin.getType();
  624. List<FinTranRecord> chargeList = finTranRecordService.selectUserTran(FinTranType1.U_Income_Coin_Balance.getType(),chargeType3,userId,null,null,1);
  625. log.info("用户{},:满足提现充值订单数{} :{}",userId,null!=chargeList?chargeList.size():0);
  626. if(null != chargeList && chargeList.size() > 0){
  627. Map<Long, List<FinTranRecord>> chargeMap = chargeList.stream().collect(Collectors.groupingBy(FinTranRecord::getUid));
  628. for(Long uid : chargeMap.keySet()) {
  629. int i = 1;
  630. double withdrawAble = 0;
  631. List<FinTranRecord> tranRecordList = chargeMap.get(uid);
  632. tranRecordList = tranRecordList.stream().sorted(Comparator.comparing(FinTranRecord::getCreateTime)).collect(Collectors.toList());
  633. Date beginDate = null;
  634. Date endDate = null;
  635. for (FinTranRecord finTranRecord : tranRecordList) {
  636. if(null == beginDate) {
  637. beginDate = finTranRecord.getCreateTime();
  638. }
  639. if (tranRecordList.size() > i) {
  640. endDate = new Date(chargeList.get(i).getCreateTime().getTime() - 1);
  641. }else{
  642. //查询用户是否还有未满足提现的充值
  643. List<FinTranRecord> curChargeList = finTranRecordService.selectUserTran(FinTranType1.U_Income_Coin_Balance.getType(),chargeType3,finTranRecord.getUid(),finTranRecord.getCreateTime(),null,0);
  644. if(null != curChargeList && curChargeList.size() > 0){
  645. endDate = curChargeList.get(0).getCreateTime();
  646. }else{
  647. endDate = new Date();
  648. }
  649. }
  650. i++;
  651. }
  652. //查询用户这段时间流水记录
  653. List<FinTranRecord> curTranList = finTranRecordService.selectUserTran(null, null, uid, null, endDate, null);
  654. withdrawAble += curTranList.stream().filter(e->FinTranType3.CONSUM_GAME_ANCHOR_WITHDRAW.getType()!=e.getTranType3().intValue()).mapToDouble(FinTranRecord::getDiamondCoinChange).sum();
  655. AppUser updateUser = new AppUser();
  656. updateUser.setUserid(uid);
  657. updateUser.setWithdrawAble(withdrawAble);
  658. appUserService.updateAppUser(updateUser);
  659. log.info("用户{},可提现额度{}",uid,withdrawAble);
  660. //清除用户缓存
  661. redisCache.deleteObject("U:UserInfo:".concat(String.valueOf(uid)));
  662. }
  663. }
  664. }
  665. public void dealOffLive(){
  666. if(!taskSwitch){
  667. return;
  668. }
  669. List<OffLineUserVo> list = appUserService.selectOffLineUser();
  670. if(null != list && list.size() > 0){
  671. Date now = DateUtil.date();
  672. list.forEach(e->{
  673. if(now.getTime() - e.getOffTime().getTime() >= 1*60*1000){
  674. log.info("{}离线已超过1分钟,自动关播",e.getUserId());
  675. //离线超过一分钟 自动关播
  676. String url = sysConfigService.selectConfigByKey("sys_live_apiurl").concat("/api/live/httpClose");
  677. Map<String, String> map = new HashMap<>();
  678. map.put("roomId", String.valueOf(e.getRoomId()));
  679. map.put("liveType", "1");
  680. map.put("isLive", String.valueOf(e.getIsLive()));
  681. map.put("description", "主播已离线,自动关播");
  682. String res = HttpClientUtils.ajaxPost(url,map);
  683. if(org.apache.commons.lang3.StringUtils.isBlank(res) || !JSONObject.parseObject(res).getString("code").equals("1")){
  684. log.info("{}自动关播失败===============》》".concat(res),e.getUserId());
  685. }
  686. }else{
  687. log.info("{}离线未超过1分钟,停止自动关播",e.getUserId());
  688. }
  689. });
  690. }
  691. }
  692. }