package cc.mrbird.febs.mall.service.impl;
|
|
import cc.mrbird.febs.common.entity.FebsResponse;
|
import cc.mrbird.febs.common.enumerates.DataDictionaryEnum;
|
import cc.mrbird.febs.common.enumerates.FlowTypeEnum;
|
import cc.mrbird.febs.common.enumerates.MoneyFlowTypeNewEnum;
|
import cc.mrbird.febs.common.exception.FebsException;
|
import cc.mrbird.febs.common.utils.*;
|
import cc.mrbird.febs.mall.conversion.CjInfoConversion;
|
import cc.mrbird.febs.mall.conversion.TzInfoConversion;
|
import cc.mrbird.febs.mall.dto.ApiCreateDto;
|
import cc.mrbird.febs.mall.dto.ApiCreateItemDto;
|
import cc.mrbird.febs.mall.dto.KjRecordDto;
|
import cc.mrbird.febs.mall.dto.OpenPrice;
|
import cc.mrbird.febs.mall.entity.*;
|
import cc.mrbird.febs.mall.mapper.*;
|
import cc.mrbird.febs.mall.service.AsyncCjService;
|
import cc.mrbird.febs.mall.service.CJService;
|
import cc.mrbird.febs.mall.service.IApiMallMemberService;
|
import cc.mrbird.febs.mall.vo.ApiKjInfoVo;
|
import cc.mrbird.febs.mall.vo.ApiKjRecordVo;
|
import cc.mrbird.febs.mall.vo.ApiTzInfoVo;
|
import cc.mrbird.febs.mall.vo.ApiTzListVo;
|
import cc.mrbird.febs.rabbit.producter.AgentProducer;
|
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.RandomUtil;
|
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.core.metadata.IPage;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
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.text.ParseException;
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.util.ArrayList;
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
@Slf4j
|
@Service
|
@RequiredArgsConstructor
|
public class CJServiceImpl extends ServiceImpl<CjInfoMapper, CjInfo> implements CJService {
|
|
private final KjRecordMapper kjRecordMapper;
|
private final RedisUtils redisUtils;
|
private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
|
private final AgentProducer agentProducer;
|
private final TzInfoMapper tzInfoMapper;
|
private final MallMemberWalletMapper mallMemberWalletMapper;
|
private final CjInfoMapper cjInfoMapper;
|
private final CjItemMapper cjItemMapper;
|
private final IApiMallMemberService mallMemberService;
|
private final AsyncCjService asyncCjService;
|
|
@Override
|
public FebsResponse kjRecord(KjRecordDto kjRecordDto) {
|
IPage<ApiKjRecordVo> page = new Page<>(kjRecordDto.getPageNum(), kjRecordDto.getPageSize());
|
IPage<ApiKjRecordVo> pages = kjRecordMapper.selectListInPage(page, kjRecordDto);
|
return new FebsResponse().success().data(pages);
|
}
|
|
@Override
|
public void createKjRecord() {
|
KjRecord kjRecord = new KjRecord();
|
String kjNo = MallUtils.getOrderNum();
|
kjRecord.setKjNo(kjNo);
|
kjRecordMapper.insert(kjRecord);
|
/**
|
* redis中设置下一期的开奖编号和开奖时间
|
*/
|
//开奖编号
|
String recordNoExit = redisUtils.getString(AppContants.KJ_RECORD_NO);
|
if (StrUtil.isNotBlank(recordNoExit)) {
|
redisUtils.del(AppContants.KJ_RECORD_NO);
|
}
|
redisUtils.set(AppContants.KJ_RECORD_NO, kjNo, AppContants.KJ_RECORD_TIME_INTERVAL*60);
|
//开奖时间
|
if (StrUtil.isNotBlank(redisUtils.getString(AppContants.KJ_RECORD_TIME))) {
|
redisUtils.del(AppContants.KJ_RECORD_TIME);
|
}
|
redisUtils.set(AppContants.KJ_RECORD_TIME, kjRecord.getCreatedTime(), AppContants.KJ_RECORD_TIME_INTERVAL*60);
|
|
agentProducer.sendChouJiangDelayMsg(kjNo, AppContants.KJ_RECORD_TIME_INTERVAL * 60 * 1000L);
|
agentProducer.sendNoTimeDelayMsg(kjNo, (AppContants.KJ_RECORD_TIME_INTERVAL-1) * 60 * 1000L);//提一分钟停止下注
|
|
//todo 测试下注
|
// ApiCreateDto apiCreateDto = new ApiCreateDto();
|
// List<ApiCreateItemDto> items = new ArrayList<>();
|
// ApiCreateItemDto apiCreateItemDto = new ApiCreateItemDto();
|
// apiCreateItemDto.setId(1L);
|
// apiCreateItemDto.setTzAmount(new BigDecimal("10"));
|
// items.add(apiCreateItemDto);
|
//
|
// ApiCreateItemDto apiCreateItemDto2 = new ApiCreateItemDto();
|
// apiCreateItemDto2.setId(2L);
|
// apiCreateItemDto2.setTzAmount(new BigDecimal("10"));
|
// items.add(apiCreateItemDto2);
|
//
|
// ApiCreateItemDto apiCreateItemDto3 = new ApiCreateItemDto();
|
// apiCreateItemDto3.setId(3L);
|
// apiCreateItemDto3.setTzAmount(new BigDecimal("10"));
|
// items.add(apiCreateItemDto3);
|
//
|
// ApiCreateItemDto apiCreateItemDto4 = new ApiCreateItemDto();
|
// apiCreateItemDto4.setId(4L);
|
// apiCreateItemDto4.setTzAmount(new BigDecimal("10"));
|
// items.add(apiCreateItemDto4);
|
//
|
// ApiCreateItemDto apiCreateItemDto5 = new ApiCreateItemDto();
|
// int randomInt = RandomUtil.randomInt(1, 25);
|
// apiCreateItemDto5.setId(Long.parseLong(String.valueOf(randomInt)));
|
// apiCreateItemDto5.setTzAmount(new BigDecimal("10"));
|
// items.add(apiCreateItemDto5);
|
// apiCreateDto.setItems(items);
|
//
|
// for(int i = 0;i<=100;i++){
|
// asyncCjService.create(apiCreateDto);
|
// }
|
|
}
|
|
@Override
|
public FebsResponse kjInfo() {
|
ApiKjInfoVo apiKjInfoVo = new ApiKjInfoVo();
|
String kjNoOld = redisUtils.getString(AppContants.KJ_RECORD_NO_OLD);
|
String kjNumOld = redisUtils.getString(AppContants.KJ_RECORD_NUM_OLD);
|
if(StrUtil.isBlank(kjNoOld)){
|
KjRecord kjRecordOld = kjRecordMapper.selectOneByLimitZero(1,1);
|
if(ObjectUtil.isNotEmpty(kjRecordOld)){
|
apiKjInfoVo.setKjNoOld(kjRecordOld.getKjNo());
|
apiKjInfoVo.setKjNumOld(kjRecordOld.getKjNum());
|
}
|
}else{
|
apiKjInfoVo.setKjNoOld(kjNoOld);
|
apiKjInfoVo.setKjNumOld(kjNumOld);
|
}
|
|
String kjNo = redisUtils.getString(AppContants.KJ_RECORD_NO);
|
String createdTime = redisUtils.getString(AppContants.KJ_RECORD_TIME);
|
if(StrUtil.isBlank(kjNo)){
|
KjRecord kjRecord = kjRecordMapper.selectOneByLimitZero(0,1);
|
if(ObjectUtil.isNotEmpty(kjRecord)){
|
apiKjInfoVo.setKjNo(kjRecord.getKjNo());
|
apiKjInfoVo.setCreatedTime(kjRecord.getCreatedTime().toString());
|
}
|
}else{
|
apiKjInfoVo.setKjNo(kjNo);
|
try {
|
apiKjInfoVo.setCreatedTime(DateUtil.formatCstTime(createdTime, DateUtil.FULL_TIME_SPLIT_PATTERN));
|
} catch (ParseException e) {
|
e.printStackTrace();
|
}
|
}
|
|
DataDictionaryCustom timeIntervalDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
|
DataDictionaryEnum.TIME_INTERVAL.getType(),
|
DataDictionaryEnum.TIME_INTERVAL.getCode()
|
);
|
apiKjInfoVo.setDjs(Integer.parseInt(timeIntervalDic.getValue()));
|
|
// 获取当前时间
|
LocalDateTime currentTime = LocalDateTime.now();
|
// 定义时间格式
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
apiKjInfoVo.setSystemTime(currentTime.format(formatter));
|
return new FebsResponse().success().data(apiKjInfoVo);
|
}
|
|
@Override
|
public void getChouJiangDelayMsg(String kjNo) {
|
//开启下注
|
DataDictionaryCustom noTimeDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
|
DataDictionaryEnum.NO_TIME.getType(),
|
DataDictionaryEnum.NO_TIME.getCode()
|
);
|
noTimeDic.setValue("1");
|
dataDictionaryCustomMapper.updateById(noTimeDic);
|
//开奖
|
KjRecord kjRecord = kjRecordMapper.selectKjNo(kjNo);
|
if(ObjectUtil.isEmpty(kjRecord)){
|
return;
|
}
|
DataDictionaryCustom openPriceDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
|
DataDictionaryEnum.OPEN_PRICE.getType(),
|
DataDictionaryEnum.OPEN_PRICE.getCode()
|
);
|
int randomInt = RandomUtil.randomInt(1, 25);
|
if(StrUtil.isNotEmpty(openPriceDic.getValue())){
|
randomInt = Integer.parseInt(openPriceDic.getValue());
|
openPriceDic.setValue("");
|
dataDictionaryCustomMapper.updateById(openPriceDic);
|
}
|
kjRecord.setKjNum( String.valueOf(randomInt));
|
kjRecordMapper.updateById(kjRecord);
|
|
//开奖编号
|
String recordNoExit = redisUtils.getString(AppContants.KJ_RECORD_NO_OLD);
|
if (StrUtil.isNotBlank(recordNoExit)) {
|
redisUtils.del(AppContants.KJ_RECORD_NO_OLD);
|
}
|
redisUtils.set(AppContants.KJ_RECORD_NO_OLD, kjNo, AppContants.KJ_RECORD_TIME_INTERVAL * 60);
|
|
//开奖号码
|
if (StrUtil.isNotBlank(redisUtils.getString(AppContants.KJ_RECORD_NUM_OLD))) {
|
redisUtils.del(AppContants.KJ_RECORD_NUM_OLD);
|
}
|
redisUtils.set(AppContants.KJ_RECORD_NUM_OLD, randomInt, AppContants.KJ_RECORD_TIME_INTERVAL * 60);
|
OpenPrice openPrice = new OpenPrice();
|
openPrice.setKjNo(kjNo);
|
openPrice.setKjNum(String.valueOf(randomInt));
|
agentProducer.sendOpenPriceMsg(openPrice);
|
|
}
|
|
@Override
|
public FebsResponse tzInfo() {
|
LinkedHashMap<String, JSON> tzInfo1 = new LinkedHashMap<>();
|
Object tzInfoMap = redisUtils.get(AppContants.TZ_INFO);
|
if(ObjectUtil.isEmpty(tzInfoMap)){
|
tzInfo1 = this.getTzInfo();
|
}else{
|
tzInfo1 = JSONUtil.toBean(JSONUtil.parseObj(tzInfoMap), LinkedHashMap.class);
|
}
|
return new FebsResponse().success().data(tzInfo1);
|
}
|
|
@Override
|
@Transactional
|
public FebsResponse create(ApiCreateDto apiCreateDto) {
|
Long memberId = LoginUserUtil.getLoginUser().getId();
|
//开启下注
|
DataDictionaryCustom noTimeDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
|
DataDictionaryEnum.NO_TIME.getType(),
|
DataDictionaryEnum.NO_TIME.getCode()
|
);
|
if("2".equals(noTimeDic.getValue())){
|
throw new FebsException("已停止投注");
|
}
|
|
List<ApiCreateItemDto> items = apiCreateDto.getItems();
|
if(CollUtil.isEmpty(items)){
|
throw new FebsException("参数有误,请刷新页面");
|
}
|
MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId);
|
BigDecimal totalAmount = BigDecimal.ZERO;
|
for(ApiCreateItemDto apiCreateItemDto : items){
|
BigDecimal tzAmount = apiCreateItemDto.getTzAmount().setScale(2,BigDecimal.ROUND_DOWN);//投注金额
|
if(BigDecimal.ZERO.compareTo(tzAmount) >= 0){
|
throw new FebsException("金额必须大于0");
|
}
|
totalAmount = totalAmount.add(tzAmount);
|
}
|
if(mallMemberWallet.getBalance().compareTo(totalAmount) < 0){
|
throw new FebsException("余额不足");
|
}
|
//更新用户余额
|
mallMemberWallet.setBalance(mallMemberWallet.getBalance().subtract(totalAmount));
|
mallMemberWalletMapper.updateBalanceWithVersion(mallMemberWallet);
|
|
//新增一条投注主表记录
|
CjInfo cjInfo = new CjInfo();
|
cjInfo.setMemberId(memberId);
|
String kjNo = redisUtils.getString(AppContants.KJ_RECORD_NO);
|
cjInfo.setKjNo(kjNo);
|
cjInfo.setKjState(0);
|
cjInfo.setPerkAmount(BigDecimal.ZERO);
|
cjInfo.setTotalAmount(totalAmount);
|
cjInfoMapper.insert(cjInfo);
|
|
for(ApiCreateItemDto apiCreateItemDto : items){
|
Long id = apiCreateItemDto.getId();//投注ID
|
TzInfo tzInfo = tzInfoMapper.selectById(id);
|
if(ObjectUtil.isEmpty(tzInfo)){
|
throw new FebsException("参数有误,请刷新页面");
|
}
|
BigDecimal tzAmount = apiCreateItemDto.getTzAmount().setScale(2,BigDecimal.ROUND_DOWN);//投注金额
|
CjItem cjItem = new CjItem();
|
cjItem.setInfoId(cjInfo.getId());
|
cjItem.setMemberId(memberId);
|
cjItem.setTzId(id);
|
cjItem.setTzCode(tzInfo.getTzCode());
|
cjItem.setTzPercent(tzInfo.getTzPercent());
|
cjItem.setType(tzInfo.getType());
|
cjItem.setAmount(tzAmount);
|
cjItem.setItemNum(tzInfo.getTzCode());
|
cjItem.setPerkAmount(BigDecimal.ZERO);
|
cjItemMapper.insert(cjItem);
|
}
|
|
String orderNo = MallUtils.getOrderNum("T");
|
mallMemberService.addMoneyFlow(
|
memberId,
|
totalAmount.negate(),
|
MoneyFlowTypeNewEnum.STATIC_BONUS.getValue(),
|
orderNo,
|
MoneyFlowTypeNewEnum.STATIC_BONUS.getDescription(),
|
null,
|
cjInfo.getId(),
|
2,
|
FlowTypeEnum.BALANCE.getValue());
|
|
return new FebsResponse().success().message("操作成功");
|
}
|
|
@Override
|
public FebsResponse tzInfoList(KjRecordDto kjRecordDto) {
|
Long memberId = LoginUserUtil.getLoginUser().getId();
|
kjRecordDto.setMemberId(memberId);
|
IPage<CjInfo> page = new Page<>(kjRecordDto.getPageNum(), kjRecordDto.getPageSize());
|
IPage<CjInfo> pages = cjInfoMapper.selectTzListByMemberId(page, kjRecordDto);
|
List<CjInfo> records = pages.getRecords();
|
if(CollUtil.isNotEmpty(records)){
|
for(CjInfo item : records){
|
Long id = item.getId();
|
List<CjItem> cjItems = cjItemMapper.selectListByInfoId(id);
|
item.setItems(cjItems);
|
}
|
}
|
List<ApiTzListVo> apiTzListVos = CjInfoConversion.INSTANCE.entitysToVos(records);
|
return new FebsResponse().success().data(apiTzListVos);
|
}
|
|
@Override
|
public void getNoTimeDelayMsg(String kjNo) {
|
DataDictionaryCustom noTimeDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
|
DataDictionaryEnum.NO_TIME.getType(),
|
DataDictionaryEnum.NO_TIME.getCode()
|
);
|
noTimeDic.setValue("2");
|
dataDictionaryCustomMapper.updateById(noTimeDic);
|
}
|
|
@Override
|
public void getOpenPriceMsg(String kjNo, String kjNum) {
|
QueryWrapper<CjInfo> objectQueryWrapper = new QueryWrapper<>();
|
objectQueryWrapper.eq("kj_no",kjNo);
|
List<CjInfo> cjInfos = cjInfoMapper.selectList(objectQueryWrapper);
|
if(ObjectUtil.isEmpty(cjInfos)){
|
return;
|
}
|
String danshuang = judgeNumberOne(Integer.parseInt(kjNum));
|
String daXiao = judgeNumberTwo(Integer.parseInt(kjNum));
|
for(CjInfo cjInfo : cjInfos){
|
asyncCjService.openPriceAsync(cjInfo,kjNum,danshuang,daXiao);
|
}
|
}
|
|
@Override
|
public LinkedHashMap<String, JSON> getTzInfo() {
|
LinkedHashMap<String, JSON> linkedHashMap = new LinkedHashMap<>();
|
|
ArrayList<ApiTzInfoVo> objectDaxiao = new ArrayList<>();
|
QueryWrapper<TzInfo> daxiaoQueryWrapper = new QueryWrapper<>();
|
daxiaoQueryWrapper.eq("type",1);
|
List<TzInfo> daXiaos = tzInfoMapper.selectList(daxiaoQueryWrapper);
|
if(CollUtil.isNotEmpty(daXiaos)){
|
for(TzInfo tzInfoRedis : daXiaos){
|
ApiTzInfoVo apiTzInfoVo = TzInfoConversion.INSTANCE.entityToVo(tzInfoRedis);
|
objectDaxiao.add(apiTzInfoVo);
|
}
|
}
|
linkedHashMap.put("daXiao", JSONUtil.parse(objectDaxiao));
|
|
ArrayList<ApiTzInfoVo> objectDanshuang = new ArrayList<>();
|
QueryWrapper<TzInfo> danshuangQueryWrapper = new QueryWrapper<>();
|
danshuangQueryWrapper.eq("type",2);
|
List<TzInfo> danShuangs = tzInfoMapper.selectList(danshuangQueryWrapper);
|
if(CollUtil.isNotEmpty(danShuangs)){
|
for(TzInfo tzInfoRedis : danShuangs){
|
ApiTzInfoVo apiTzInfoVo = TzInfoConversion.INSTANCE.entityToVo(tzInfoRedis);
|
objectDanshuang.add(apiTzInfoVo);
|
}
|
}
|
linkedHashMap.put("danShuang",JSONUtil.parse(objectDanshuang));
|
|
ArrayList<ApiTzInfoVo> objectShuZi = new ArrayList<>();
|
QueryWrapper<TzInfo> shuZiQueryWrapper = new QueryWrapper<>();
|
shuZiQueryWrapper.eq("type",3);
|
List<TzInfo> shuZis = tzInfoMapper.selectList(shuZiQueryWrapper);
|
if(CollUtil.isNotEmpty(shuZis)){
|
for(TzInfo tzInfoRedis : shuZis){
|
ApiTzInfoVo apiTzInfoVo = TzInfoConversion.INSTANCE.entityToVo(tzInfoRedis);
|
objectShuZi.add(apiTzInfoVo);
|
}
|
}
|
linkedHashMap.put("shuZi",JSONUtil.parse(objectShuZi));
|
|
//投注信息
|
String tzInfoNoExit = redisUtils.getString(AppContants.TZ_INFO);
|
if (StrUtil.isNotBlank(tzInfoNoExit)) {
|
redisUtils.del(AppContants.TZ_INFO);
|
}
|
JSON jsonStr = JSONUtil.parse(linkedHashMap);
|
redisUtils.set(AppContants.TZ_INFO, jsonStr);
|
return linkedHashMap;
|
}
|
|
/**
|
* 取模运算符%来判断该数字是否为偶数。如果余数为0,则该数字为偶数,返回"双数";否则,该数字为奇数,返回"单数"
|
* @param num
|
* @return 1-单数 2-双数
|
*/
|
public static String judgeNumberOne(int num) {
|
if (num % 2 == 0) {
|
return "双";
|
} else {
|
return "单";
|
}
|
}
|
|
/**
|
* 小于等于12为小 大于12为大
|
* @param num
|
* @return 1-小数 2-大数
|
*/
|
public static String judgeNumberTwo(int num) {
|
if (num <= 12) {
|
return "小";
|
} else {
|
return "大";
|
}
|
}
|
|
}
|