package cc.mrbird.febs.dapp.service.impl; import cc.mrbird.febs.common.configure.i18n.MessageSourceUtils; import cc.mrbird.febs.common.contants.AppContants; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.common.utils.LoginUserUtil; import cc.mrbird.febs.common.utils.RedisUtils; import cc.mrbird.febs.dapp.dto.ApiStartDto; import cc.mrbird.febs.dapp.entity.*; import cc.mrbird.febs.dapp.enumerate.DataDictionaryEnum; import cc.mrbird.febs.dapp.enumerate.MemberOnHookPlanEnum; import cc.mrbird.febs.dapp.mapper.*; import cc.mrbird.febs.dapp.service.ApiIgtOnHookPlanService; import cc.mrbird.febs.dapp.service.DappWalletService; import cc.mrbird.febs.dapp.vo.ApiAwardInfoVo; import cc.mrbird.febs.dapp.vo.ApiPlanInfoVo; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSON; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.aspectj.bridge.MessageUtil; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.*; @Slf4j @Service @RequiredArgsConstructor public class ApiIgtOnHookPlanServiceImpl extends ServiceImpl implements ApiIgtOnHookPlanService { private final IgtOnHookPlanOrderDao igtOnHookPlanOrderDao; private final IgtOnHookPlanOrderItemDao igtOnHookPlanOrderItemDao; private final DappWalletCoinDao dappWalletCoinDao; private final DataDictionaryCustomMapper dataDictionaryCustomMapper; private final DappMemberDao dappMemberDao; private final DappAccountMoneyChangeDao dappAccountMoneyChangeDao; private final RedisUtils redisUtils; private final DappOnHookAwardDao dappOnHookAwardDao; private final DappWalletService dappWalletService; @Override @Transactional(rollbackFor = Exception.class) public FebsResponse start(ApiStartDto apiStartDto) { /** * 开始挂机 * 增加一条挂机记录 * 匹配收益方案(预先生成) * 发送一条mq消息,根据受益方案生成挂机字表未生效详细记录 * 余额减少 * 更新用户表是否正在挂机状态字段 * 定时器五分钟去更新一下详细记录的状态 * */ //todo 发送一条mq消息,根据受益方案生成挂机字表未生效详细记录(目前定时器) DappMemberEntity dappMemberEntity = LoginUserUtil.getAppUser(); Long memberId = dappMemberEntity.getId(); DappMemberEntity member = dappMemberDao.selectById(memberId); int isOnHook = member.getIsOnHook() == null ? 2 : member.getIsOnHook(); if(2 != isOnHook){ return new FebsResponse().fail().message(MessageSourceUtils.getString("Operation_002")); } //挂机金额的倍数 Integer planCode = apiStartDto.getPlanCode() == null ? 1 : apiStartDto.getPlanCode(); if(0 >= planCode){ return new FebsResponse().fail().message(MessageSourceUtils.getString("balance_err_001")); } //挂机金额 BigDecimal balance = apiStartDto.getBalance() == null ? BigDecimal.ZERO : apiStartDto.getBalance(); if(AppContants.ONHOOK_BASIC_AMOUNT.compareTo(balance) > 0){ return new FebsResponse().fail().message(MessageSourceUtils.getString("balance_err_001")); } DappWalletCoinEntity dappWalletCoinEntity = dappWalletCoinDao.selectByMemberId(memberId); if(ObjectUtil.isEmpty(dappWalletCoinEntity)){ return new FebsResponse().fail().message(MessageSourceUtils.getString("login_err_003")); } BigDecimal availableAmount = dappWalletCoinEntity.getAvailableAmount(); if(balance.compareTo(availableAmount) > 0){ return new FebsResponse().fail().message(MessageSourceUtils.getString("balance_err_002")); } //挂机开始时间和结束时间 DataDictionaryCustom startTimeDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.START_TIME.getType(), DataDictionaryEnum.START_TIME.getCode()); DataDictionaryCustom endTimeDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.END_TIME.getType(), DataDictionaryEnum.END_TIME.getCode()); DateTime startTime = DateUtil.parseTimeToday(startTimeDic.getValue()); DateTime endTime = DateUtil.parseTimeToday(endTimeDic.getValue()); DateTime nowTime = DateUtil.parseTimeToday(DateUtil.format(DateUtil.date(),"HH:mm:ss")); if(DateUtil.compare(nowTime,startTime) < 0){ return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_0015")); } if(DateUtil.compare(nowTime,endTime) > 0){ return new FebsResponse().fail().message(MessageSourceUtils.getString("member_err_0015")); } //增加一条挂机记录 IgtOnHookPlanOrder igtOnHookPlanOrder = new IgtOnHookPlanOrder(); igtOnHookPlanOrder.setMemberId(memberId); igtOnHookPlanOrder.setStartTime(DateUtil.date()); igtOnHookPlanOrder.setState(IgtOnHookPlanOrder.STATE_START); igtOnHookPlanOrder.setPlanAmount(apiStartDto.getBalance()); igtOnHookPlanOrder.setAvaAmount(apiStartDto.getBalance()); igtOnHookPlanOrder.setPlanCode(apiStartDto.getPlanCode()); igtOnHookPlanOrder.setProfit(AppContants.INIT_MONEY); igtOnHookPlanOrderDao.insert(igtOnHookPlanOrder); //余额减少 Integer updateCount = dappWalletCoinDao.delAvailableDelTotalById(dappWalletCoinEntity.getId(), balance); if(1 != updateCount){ throw new FebsException(MessageSourceUtils.getString("balance_err_002")); } DappMemberEntity dappMember= dappMemberDao.selectById(memberId); //更新用户表是否正在挂机状态字段 dappMember.setIsOnHook(1); dappMemberDao.updateById(dappMember); List dataDictionaryCustoms = dataDictionaryCustomMapper.selectDicByType(DataDictionaryEnum.PLAN_A.getType()); LinkedList> strings = new LinkedList<>(); for(DataDictionaryCustom dataDictionaryCustom : dataDictionaryCustoms){ Map stringStringHashMap = new HashMap<>(); stringStringHashMap.put(dataDictionaryCustom.getDescription(),dataDictionaryCustom.getValue()); strings.add(stringStringHashMap); } //收益率 BigDecimal hangingRevenue = BigDecimal.ZERO; //挂机时长 DataDictionaryCustom maxHours = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.MAX_HOURS.getType(), DataDictionaryEnum.MAX_HOURS.getCode()); if(ObjectUtil.isEmpty(maxHours)){ throw new FebsException(MessageSourceUtils.getString("login_err_003")); } Double maxHoursValue = Double.parseDouble(maxHours.getValue()); //获取用户信息的是否盈利字段 Integer isProfit = dappMember.getIsProfit() == null ? 1 : dappMember.getIsProfit(); String identity = null; if(isProfit == 2){ identity = "IS_PROFIT_NO"; }else{ identity = "LEVEL_MB"; DataDictionaryCustom levelMember = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(DataDictionaryEnum.LEVEL_MB.getType(), dappMemberEntity.getIdentity()); if(ObjectUtil.isEmpty(levelMember)){ throw new FebsException(MessageSourceUtils.getString("login_err_003")); } String levelMemberValue = levelMember.getValue(); JSONObject levelMemberValueParse = JSONUtil.parseObj(levelMemberValue); //挂机收益只有总收益的60% hangingRevenue = new BigDecimal(levelMemberValueParse.get("hangingRevenue").toString()) .multiply(new BigDecimal(0.01)).setScale(4,BigDecimal.ROUND_DOWN); } //获取挂机字表的顺序 LinkedList isProfitPlan = new LinkedList<>(); Map> identity_level = MemberOnHookPlanEnum.valueOf(identity) .getMemberOnHook(maxHoursValue,hangingRevenue,strings); isProfitPlan = identity_level.get(identity); if(CollUtil.isEmpty(isProfitPlan)){ throw new FebsException(MessageSourceUtils.getString("login_err_003")); } //获取下一个开奖 String redisKey = "on_hook_award_id"; String onHookAwardRedisId = redisUtils.getString(redisKey); DappOnHookAward dappOnHookAward = dappOnHookAwardDao.selectById(Long.parseLong(onHookAwardRedisId)); if(ObjectUtil.isEmpty(dappOnHookAward)){ throw new FebsException(MessageSourceUtils.getString("login_err_003")); } Date awardTime = dappOnHookAward.getAwardTime(); DateTime dateTime = DateUtil.offsetMinute(awardTime, 5); int orderNum = 1; for(String profitPlan : isProfitPlan){ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); String yyyyMMddHHMM = sdf.format(dateTime); DappOnHookAward dappOnHookAwardNext = dappOnHookAwardDao.selectByByAwardTime(yyyyMMddHHMM); JSONObject jsonObject = JSONUtil.parseObj(profitPlan); IgtOnHookPlanOrderItem igtOnHookPlanOrderItem = new IgtOnHookPlanOrderItem(); igtOnHookPlanOrderItem.setMemberId(memberId); igtOnHookPlanOrderItem.setOrderId(igtOnHookPlanOrder.getId()); BigDecimal amount = new BigDecimal(jsonObject.get("amount").toString()); igtOnHookPlanOrderItem.setAmount(amount.multiply(new BigDecimal(planCode))); BigDecimal profit = new BigDecimal(jsonObject.get("profit").toString()); igtOnHookPlanOrderItem.setProfit(profit.multiply(new BigDecimal(planCode))); igtOnHookPlanOrderItem.setState(2); igtOnHookPlanOrderItem.setPlanCode(planCode); String isGoal = jsonObject.get("isGoal").toString(); igtOnHookPlanOrderItem.setIsGoal(Integer.parseInt(isGoal)); igtOnHookPlanOrderItem.setBelongNum(dappOnHookAwardNext.getRecordNum()); igtOnHookPlanOrderItem.setOrderNum(orderNum); igtOnHookPlanOrderItemDao.insert(igtOnHookPlanOrderItem); orderNum++; dateTime = DateUtil.offsetMinute(dateTime, 5); } DappAccountMoneyChangeEntity dappAccountMoneyChangeEntity = new DappAccountMoneyChangeEntity(memberId, availableAmount, balance , availableAmount.subtract(balance).setScale(2,BigDecimal.ROUND_DOWN), "挂机", 6); dappAccountMoneyChangeDao.insert(dappAccountMoneyChangeEntity); return new FebsResponse().success().message(MessageSourceUtils.getString("Operation_001")); } @Override public FebsResponse endPlan(Long orderId) { DappMemberEntity dappMemberEntity = LoginUserUtil.getAppUser(); Long memberId = dappMemberEntity.getId(); /* 1、更新主表为结束状态 2、删除子表中未生效的记录 3、计算总收益和总挂机剩余金额,操作用户资金账户信息 4、生成流水记录 5、更新用户表是否正在挂机状态字段为否 */ //删除子表中未生效的记录 QueryWrapper objectQueryWrapper = new QueryWrapper<>(); objectQueryWrapper.eq("order_id",orderId); objectQueryWrapper.eq("member_id",memberId); objectQueryWrapper.eq("state",2); igtOnHookPlanOrderItemDao.delete(objectQueryWrapper); //计算总收益和总挂机剩余金额,操作用户资金账户信息 //所有中奖的收益 BigDecimal totalProfit = igtOnHookPlanOrderItemDao.selectTotalProfitByByOrderIdAndMemberIdAndState(orderId,memberId,1,2); String refererIds = dappMemberDao.selectById(memberId).getRefererIds(); List refererIdList = StrUtil.split(refererIds, ",", -1, true, true); //生成流水佣金和盈利分成和流水记录,返回剩余盈利 BigDecimal profitSharingTotal = dappWalletService.updateLSYJYLFC(refererIdList, totalProfit); //平台分成,返回剩余盈利 BigDecimal systemTotal = dappWalletService.updatePTFC(memberId,totalProfit); totalProfit = totalProfit.subtract(profitSharingTotal).subtract(systemTotal); //获取用户信息的是否盈利字段 DappMemberEntity dappMember = dappMemberDao.selectById(memberId); Integer isProfit = dappMember.getIsProfit() == null ? 1 : dappMember.getIsProfit(); //所有未中奖的本金 BigDecimal totalAmount = igtOnHookPlanOrderItemDao.selectTotalAmountByByOrderIdAndMemberIdAndState(orderId,memberId,1,1); //更新主表为结束状态 IgtOnHookPlanOrder igtOnHookPlanOrder = igtOnHookPlanOrderDao.selectById(orderId); BigDecimal avaAmount = igtOnHookPlanOrder.getAvaAmount(); BigDecimal planAmount = igtOnHookPlanOrder.getPlanAmount(); igtOnHookPlanOrder.setState(2); //一次挂机剩余的全部金额 BigDecimal totalMoney = totalProfit.add(avaAmount); if(totalMoney.compareTo(planAmount)<=0){ igtOnHookPlanOrder.setProfitState(2); }else{ igtOnHookPlanOrder.setProfitState(1); } igtOnHookPlanOrder.setProfit(totalProfit); igtOnHookPlanOrderDao.updateById(igtOnHookPlanOrder); DappWalletCoinEntity dappWalletCoinEntity = dappWalletCoinDao.selectByMemberId(memberId); BigDecimal availableAmount = dappWalletCoinEntity.getAvailableAmount(); BigDecimal total = BigDecimal.ZERO; if(isProfit == 2){ //设置成不盈利,只返回收益加剩余挂机总金额 total = totalProfit.add(igtOnHookPlanOrder.getAvaAmount()).setScale(4, BigDecimal.ROUND_DOWN); }else{ //设置成盈利,如果中奖,返回收益,如果没中奖,则返回本金,最后加上剩余总挂机金额 // total = totalProfit.add(totalAmount).add(igtOnHookPlanOrder.getAvaAmount()).setScale(4, BigDecimal.ROUND_DOWN); total = totalProfit.add(igtOnHookPlanOrder.getAvaAmount()).setScale(4, BigDecimal.ROUND_DOWN); } dappWalletCoinDao.addTotalAndaddAvailableById(dappWalletCoinEntity.getId(),total); //生成流水记录 BigDecimal add = availableAmount.add(total); BigDecimal subtract = add.subtract(totalProfit); DappAccountMoneyChangeEntity dappAccountMoneyChangeEntity = new DappAccountMoneyChangeEntity(memberId, subtract, totalProfit, add, "投注盈利", 5); dappAccountMoneyChangeDao.insert(dappAccountMoneyChangeEntity); //更新用户表是否正在挂机状态字段为否 dappMember.setIsOnHook(3); dappMemberDao.updateById(dappMember); return new FebsResponse().success().message(MessageSourceUtils.getString("Operation_001")); } @Override public FebsResponse planInfo() { DappMemberEntity dappMemberEntity = LoginUserUtil.getAppUser(); Long memberId = dappMemberEntity.getId(); DappMemberEntity member = dappMemberDao.selectById(memberId); Integer isOnHook = member.getIsOnHook() == null ? 2 : member.getIsOnHook(); ApiPlanInfoVo apiPlanInfoVo = new ApiPlanInfoVo(); if(1 == isOnHook){ //获取当前最新的一条 IgtOnHookPlanOrder igtOnHookPlanOrder = igtOnHookPlanOrderDao.selectByMemberId(memberId); if(ObjectUtil.isNotEmpty(igtOnHookPlanOrder)){ apiPlanInfoVo.setPlanAmount(igtOnHookPlanOrder.getPlanAmount()); apiPlanInfoVo.setCreateTime(igtOnHookPlanOrder.getCreateTime()); apiPlanInfoVo.setId(igtOnHookPlanOrder.getId()); apiPlanInfoVo.setAvaAmount(igtOnHookPlanOrder.getAvaAmount()); BigDecimal totalProfit = igtOnHookPlanOrderItemDao.selectTotalProfitByByOrderIdAndMemberIdAndState(igtOnHookPlanOrder.getId(),memberId,1,2); apiPlanInfoVo.setProfit(totalProfit.setScale(4,BigDecimal.ROUND_DOWN)); } } return new FebsResponse().success().data(apiPlanInfoVo); } @Override public BigDecimal getTotalFrofit(Long memberId) { BigDecimal totalProfit = igtOnHookPlanOrderDao.selectSumProfitByMemberId(memberId); return totalProfit; } @Override public FebsResponse awardInfo() { DappMemberEntity dappMemberEntity = LoginUserUtil.getAppUser(); Long memberId = dappMemberEntity.getId(); ArrayList apiAwardInfoVos = new ArrayList<>(); DateTime date = DateUtil.date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); String yyyyMMddHHMM = sdf.format(date); List dappOnHookAwards = dappOnHookAwardDao.selectInfoByByAwardTime(yyyyMMddHHMM); if(CollUtil.isNotEmpty(dappOnHookAwards)){ for(DappOnHookAward dappOnHookAward : dappOnHookAwards){ ApiAwardInfoVo apiAwardInfoVo = new ApiAwardInfoVo(); apiAwardInfoVo.setAwardNum(dappOnHookAward.getAwardNum()); apiAwardInfoVo.setRecordNum(dappOnHookAward.getRecordNum()); IgtOnHookPlanOrderItem igtOnHookPlanOrderItem = igtOnHookPlanOrderItemDao.selectByMemberIdAndBelongNum(memberId,dappOnHookAward.getRecordNum()); if(ObjectUtil.isNotEmpty(igtOnHookPlanOrderItem)){ BigDecimal bigDecimal = igtOnHookPlanOrderItem.getAmount().setScale(1, BigDecimal.ROUND_DOWN); apiAwardInfoVo.setAmount(bigDecimal.toString()); }else{ apiAwardInfoVo.setAmount("-"); } apiAwardInfoVos.add(apiAwardInfoVo); } } return new FebsResponse().success().data(apiAwardInfoVos); } private String getProfitCase(String identity,BigDecimal balance){ //匹配会员等级获取对应的收益率 List dataDictionaryCustoms = dataDictionaryCustomMapper.selectDicByType(DataDictionaryEnum.LEVEL_MB.getType()); if(CollUtil.isNotEmpty(dataDictionaryCustoms)){ for(DataDictionaryCustom memberLevel : dataDictionaryCustoms){ String code = memberLevel.getCode(); String memberLevelValue = memberLevel.getValue(); JSONObject profitValue = JSONUtil.parseObj(memberLevelValue); //挂机收益 BigDecimal hangingRevenue = new BigDecimal(profitValue.get("hangingRevenue").toString()).divide(new BigDecimal(100)); //预计收益 BigDecimal expectProfit = balance.multiply(balance).setScale(4, BigDecimal.ROUND_DOWN); } } return null; } public static void main(String[] args) { DateTime nowTime = DateUtil.parseTimeToday(DateUtil.format(DateUtil.date(),"HH:mm:ss")); System.out.println(nowTime); int maxTimes = 10; for(int i =1;i