init
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
package com.tailbet.service.impl;
|
||||
|
||||
import com.tailbet.model.entity.BetOrder;
|
||||
import com.tailbet.model.entity.User;
|
||||
import com.tailbet.model.entity.GameRound;
|
||||
import com.tailbet.mapper.BetOrderMapper;
|
||||
import com.tailbet.mapper.UserMapper;
|
||||
import com.tailbet.mapper.GameRoundMapper;
|
||||
import com.tailbet.service.IBetService;
|
||||
import com.tailbet.service.IGameService;
|
||||
import com.tailbet.service.IPointsService;
|
||||
import com.tailbet.service.IAuditService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 注单Service实现
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class BetServiceImpl implements IBetService {
|
||||
|
||||
private final BetOrderMapper betOrderMapper;
|
||||
private final UserMapper userMapper;
|
||||
private final GameRoundMapper gameRoundMapper;
|
||||
private final IPointsService pointsService;
|
||||
private final IAuditService auditService;
|
||||
|
||||
/**
|
||||
* 下注
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public BetOrder placeBet(Long userId, Long groupId, String clientMsgId,
|
||||
String playType, Integer betAmount) {
|
||||
// 防重检查
|
||||
if (clientMsgId != null) {
|
||||
BetOrder existing = betOrderMapper.selectOne(new LambdaQueryWrapper<BetOrder>()
|
||||
.eq(BetOrder::getClientMsgId, clientMsgId));
|
||||
if (existing != null) {
|
||||
throw new RuntimeException("重复下注");
|
||||
}
|
||||
}
|
||||
|
||||
// 检查用户
|
||||
User user = userMapper.selectById(userId);
|
||||
if (user == null) {
|
||||
throw new RuntimeException("用户不存在");
|
||||
}
|
||||
if (user.getIsFake() != null && user.getIsFake() == 1) {
|
||||
// 假人下注只记录审计日志,不产生订单
|
||||
auditService.log(groupId, null, userId, "FAKE_BET",
|
||||
String.format("{\"playType\":\"%s\",\"amount\":%d}", playType, betAmount));
|
||||
return null;
|
||||
}
|
||||
|
||||
// 检查进行中的局
|
||||
GameRound round = gameRoundMapper.selectOne(new LambdaQueryWrapper<GameRound>()
|
||||
.eq(GameRound::getGroupId, groupId)
|
||||
.eq(GameRound::getStatus, 0));
|
||||
if (round == null) {
|
||||
throw new RuntimeException("当前没有进行中的局");
|
||||
}
|
||||
|
||||
// 检查余额
|
||||
if (user.getPoints() < betAmount) {
|
||||
throw new RuntimeException("余额不足");
|
||||
}
|
||||
|
||||
// 检查限额
|
||||
if (betAmount < 1 || betAmount > 2000) {
|
||||
throw new RuntimeException("单笔下注金额需在1-2000之间");
|
||||
}
|
||||
|
||||
// 检查单局累计
|
||||
Integer roundTotal = betOrderMapper.selectList(new LambdaQueryWrapper<BetOrder>()
|
||||
.eq(BetOrder::getUserId, userId)
|
||||
.eq(BetOrder::getRoundId, round.getId())
|
||||
.eq(BetOrder::getIsFake, 0))
|
||||
.stream()
|
||||
.mapToInt(BetOrder::getBetAmount)
|
||||
.sum();
|
||||
if (roundTotal + betAmount > 20000) {
|
||||
throw new RuntimeException("单局累计下注不能超过20000");
|
||||
}
|
||||
|
||||
// 获取赔率
|
||||
BigDecimal odds = getOdds(playType);
|
||||
|
||||
// 扣减积分
|
||||
boolean success = pointsService.subPoints(userId, betAmount.longValue(),
|
||||
IPointsService.TYPE_BET, null, null, "游戏下注");
|
||||
if (!success) {
|
||||
throw new RuntimeException("余额不足");
|
||||
}
|
||||
|
||||
// 创建注单
|
||||
BetOrder bet = new BetOrder();
|
||||
bet.setUserId(userId);
|
||||
bet.setGroupId(groupId);
|
||||
bet.setRoundId(round.getId());
|
||||
bet.setClientMsgId(clientMsgId);
|
||||
bet.setPlayType(playType);
|
||||
bet.setBetAmount(betAmount);
|
||||
bet.setOdds(odds);
|
||||
bet.setIsFake(0);
|
||||
bet.setStatus(0);
|
||||
bet.setCreateTime(LocalDateTime.now());
|
||||
betOrderMapper.insert(bet);
|
||||
|
||||
// 审计日志
|
||||
auditService.log(groupId, round.getId(), userId, "BET_PLACE",
|
||||
String.format("{\"betId\":%d,\"playType\":\"%s\",\"amount\":%d}",
|
||||
bet.getId(), playType, betAmount));
|
||||
|
||||
return bet;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取赔率
|
||||
*/
|
||||
@Override
|
||||
public BigDecimal getOdds(String playType) {
|
||||
if ("单".equals(playType) || "双".equals(playType)) {
|
||||
return IGameService.ODDS_SINGLE_DOUBLE;
|
||||
} else if ("大".equals(playType) || "小".equals(playType)) {
|
||||
return IGameService.ODDS_SIZE;
|
||||
} else {
|
||||
return IGameService.ODDS_DIGIT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户本局下注总额
|
||||
*/
|
||||
@Override
|
||||
public Integer getUserRoundBetAmount(Long userId, Long roundId) {
|
||||
return betOrderMapper.selectList(new LambdaQueryWrapper<BetOrder>()
|
||||
.eq(BetOrder::getUserId, userId)
|
||||
.eq(BetOrder::getRoundId, roundId)
|
||||
.eq(BetOrder::getIsFake, 0))
|
||||
.stream()
|
||||
.mapToInt(BetOrder::getBetAmount)
|
||||
.sum();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user