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.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.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 io.grpc.internal.JsonUtil; 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; @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")); } //增加一条挂机记录 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); 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、更新用户表是否正在挂机状态字段为否 */ //更新主表为结束状态 IgtOnHookPlanOrder igtOnHookPlanOrder = igtOnHookPlanOrderDao.selectById(orderId); igtOnHookPlanOrder.setState(2); igtOnHookPlanOrderDao.updateById(igtOnHookPlanOrder); //删除子表中未生效的记录 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); BigDecimal totalAmount = igtOnHookPlanOrderItemDao.selectTotalAmountByByOrderIdAndMemberIdAndState(orderId,memberId,1,2); DappWalletCoinEntity dappWalletCoinEntity = dappWalletCoinDao.selectByMemberId(memberId); BigDecimal availableAmount = dappWalletCoinEntity.getAvailableAmount(); //如果中奖,返回本金加收益加剩余总挂机金额 BigDecimal total = totalProfit.add(totalAmount).add(igtOnHookPlanOrder.getAvaAmount()).setScale(4, BigDecimal.ROUND_DOWN); dappWalletCoinDao.addTotalAndaddAvailableById(memberId,total); //生成流水记录 BigDecimal add = availableAmount.add(total); DappAccountMoneyChangeEntity dappAccountMoneyChangeEntity = new DappAccountMoneyChangeEntity(memberId, availableAmount, total, add, "投注盈利", 5); dappAccountMoneyChangeDao.insert(dappAccountMoneyChangeEntity); //更新用户表是否正在挂机状态字段为否 DappMemberEntity dappMember= dappMemberDao.selectById(memberId); 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) { int maxTimes = 10; for(int i =1;i