package com.panzhihua.service_community.service.impl;
|
|
import static java.util.Objects.isNull;
|
import static java.util.Objects.nonNull;
|
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.Random;
|
|
import javax.annotation.Resource;
|
|
import org.springframework.beans.BeanUtils;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
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 com.panzhihua.common.model.dtos.community.microCommercialStreet.McsGameDTO;
|
import com.panzhihua.common.model.dtos.community.microCommercialStreet.PageMcsGameDTO;
|
import com.panzhihua.common.model.dtos.community.microCommercialStreet.SetPopularForGameDTO;
|
import com.panzhihua.common.model.dtos.community.microCommercialStreet.SetShelfForGameDTO;
|
import com.panzhihua.common.model.vos.R;
|
import com.panzhihua.common.model.vos.community.microCommercialStreet.McsCouponVO;
|
import com.panzhihua.common.model.vos.community.microCommercialStreet.McsGameVO;
|
import com.panzhihua.common.model.vos.community.microCommercialStreet.TopStatisticsVO;
|
import com.panzhihua.common.utlis.DateUtils;
|
import com.panzhihua.common.utlis.Snowflake;
|
import com.panzhihua.service_community.dao.McsCouponDAO;
|
import com.panzhihua.service_community.dao.McsEvaluateDAO;
|
import com.panzhihua.service_community.dao.McsGameDAO;
|
import com.panzhihua.service_community.dao.McsMerchantDAO;
|
import com.panzhihua.service_community.entity.McsCoupon;
|
import com.panzhihua.service_community.entity.McsGame;
|
import com.panzhihua.service_community.entity.McsMerchant;
|
import com.panzhihua.service_community.service.McsGameService;
|
import com.panzhihua.service_community.util.QRCodeUtil;
|
|
/**
|
* (McsGame)表服务实现类
|
*
|
* @author makejava
|
* @since 2021-12-28 14:37:09
|
*/
|
@Service("mcsGameService")
|
public class McsGameServiceImpl extends ServiceImpl<McsGameDAO, McsGame> implements McsGameService {
|
|
@Resource
|
private McsMerchantDAO mcsMerchantDAO;
|
@Resource
|
private McsCouponDAO mcsCouponDAO;
|
@Resource
|
private McsEvaluateDAO mcsEvaluateDAO;
|
|
/**
|
* 分页查询戳戳游戏
|
* @param pageMcsGameDTO
|
* @return
|
*/
|
@Override
|
public R pageMcsGame(PageMcsGameDTO pageMcsGameDTO) {
|
Page page = new Page<>();
|
page.setSize(pageMcsGameDTO.getPageSize());
|
page.setCurrent(pageMcsGameDTO.getPageNum());
|
IPage<McsGameVO> mcsGames = this.baseMapper.pageMcsGame(page, pageMcsGameDTO);
|
return R.ok(mcsGames);
|
}
|
|
/**
|
* 设为/取消游戏热门
|
* @param setPopularForGameDTO
|
* @return
|
*/
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public R setPopularForGame(SetPopularForGameDTO setPopularForGameDTO) {
|
McsGame mcsGame = this.baseMapper.selectById(setPopularForGameDTO.getGameId());
|
if (isNull(mcsGame)) {
|
return R.fail("修改数据不存在");
|
}
|
Integer type = setPopularForGameDTO.getType();
|
if (type.equals(1)) {
|
//设为热门
|
List<McsGame> popularGames = this.baseMapper.selectList(new QueryWrapper<McsGame>().lambda().eq(McsGame::getIsPopular, true));
|
if (nonNull(popularGames) && !popularGames.isEmpty()) {
|
popularGames.forEach(e -> e.setIsPopular(false));
|
this.updateBatchById(popularGames);
|
}
|
mcsGame.setIsPopular(true);
|
} else if (type.equals(2)) {
|
//取消热门
|
mcsGame.setIsPopular(false);
|
} else {
|
return R.fail("未知错误");
|
}
|
int num = this.baseMapper.updateById(mcsGame);
|
if (num > 0) {
|
return R.ok();
|
}
|
return R.fail("修改失败,请重新尝试");
|
}
|
|
/**
|
* 上架/下架戳戳游戏
|
* @param setShelfForGameDTO
|
* @return
|
*/
|
@Override
|
public R setShelfForGame(SetShelfForGameDTO setShelfForGameDTO) {
|
McsGame mcsGame = this.baseMapper.selectById(setShelfForGameDTO.getGameId());
|
if (isNull(mcsGame)) {
|
return R.fail("修改数据不存在");
|
}
|
Integer type = setShelfForGameDTO.getType();
|
if (type.equals(1)) {
|
//上架
|
McsMerchant mcsMerchant = mcsMerchantDAO.selectById(mcsGame.getMerchantId());
|
Integer publishLimit = mcsMerchant.getPublishLimit();
|
Integer publishCount = this.baseMapper.selectPublishCount(mcsGame.getMerchantId());
|
if (publishCount >= publishLimit) {
|
return R.fail("空闲戳戳点不足");
|
}
|
mcsGame.setStatus(2);
|
} else if (type.equals(2)) {
|
//下架
|
mcsGame.setStatus(3);
|
} else {
|
return R.fail("未知错误");
|
}
|
int num = this.baseMapper.updateById(mcsGame);
|
if (num > 0) {
|
return R.ok();
|
}
|
return R.fail("修改失败,请重新尝试");
|
}
|
|
/**
|
* 删除戳戳游戏
|
* @param gameId
|
* @param userId
|
* @return
|
*/
|
@Override
|
public R deleteMcsGame(Long gameId, Long userId) {
|
McsGame mcsGame = this.baseMapper.selectById(gameId);
|
if (isNull(mcsGame)) {
|
return R.fail("修改数据不存在");
|
}
|
mcsGame.setIsDel(true);
|
mcsGame.setStatus(McsGame.Status.yxj);
|
mcsGame.setUpdatedBy(userId);
|
int num = this.baseMapper.updateById(mcsGame);
|
if (num > 0) {
|
return R.ok();
|
}
|
return R.fail("删除失败,请重新尝试");
|
}
|
|
/**
|
* 新增戳戳游戏
|
* @param mcsGameDTO
|
* @return
|
*/
|
@Override
|
public R addMcsGame(McsGameDTO mcsGameDTO) {
|
Long userId = mcsGameDTO.getCreatedBy();
|
McsMerchant mcsMerchant = mcsMerchantDAO.selectOne(new QueryWrapper<McsMerchant>().lambda().eq(McsMerchant::getUserId, userId));
|
if (isNull(mcsMerchant)) {
|
return R.fail("未查询到商家信息");
|
}
|
Integer type = mcsGameDTO.getType();
|
McsGame mcsGame = new McsGame();
|
if (type.equals(1)) {
|
//1.戳戳币游戏
|
Integer allocation = mcsGameDTO.getAllocation();
|
Integer coins = mcsGameDTO.getCoins();
|
if (isNull(allocation)) {
|
return R.fail("缺少分配方式");
|
}
|
if (isNull(coins)) {
|
return R.fail("未设置戳戳币额度");
|
}
|
if (allocation.equals(1)) {
|
mcsGame.setSurplusCoins(mcsGameDTO.getCoins());
|
}
|
} else if (type.equals(2)) {
|
//2.体验游戏
|
Integer awardType = mcsGameDTO.getAwardType();
|
if (isNull(awardType)) {
|
return R.fail("缺少奖励类型");
|
}
|
} else {
|
return R.fail("未知错误");
|
}
|
BeanUtils.copyProperties(mcsGameDTO, mcsGame);
|
mcsGame.setSurplusCoupons(mcsGameDTO.getCoupons());
|
mcsGame.setStatus(McsGame.Status.wfb);
|
mcsGame.setMerchantId(mcsMerchant.getId());
|
int num = this.baseMapper.insert(mcsGame);
|
if (num > 0) {
|
return R.ok();
|
}
|
return R.fail("新增失败,请重新尝试");
|
}
|
|
/**
|
* 编辑戳戳游戏
|
* @param mcsGameDTO
|
* @return
|
*/
|
@Override
|
public R putMcsGame(McsGameDTO mcsGameDTO) {
|
McsGame mcsGame = this.baseMapper.selectById(mcsGameDTO.getId());
|
if (isNull(mcsGame)) {
|
return R.fail("资源不存在");
|
}
|
Integer type = mcsGameDTO.getType();
|
if (type.equals(1)) {
|
//1.戳戳币游戏
|
Integer allocation = mcsGameDTO.getAllocation();
|
Integer coins = mcsGameDTO.getCoins();
|
if (isNull(allocation)) {
|
return R.fail("缺少分配方式");
|
}
|
if (isNull(coins)) {
|
return R.fail("未设置戳戳币额度");
|
}
|
Integer beforeCoins = mcsGame.getCoins();
|
Integer beforeSurplusCoins = mcsGame.getSurplusCoins();
|
if (isNull(beforeSurplusCoins)) {
|
beforeSurplusCoins = beforeCoins;
|
}
|
Integer beforeUsedCoins = beforeCoins - beforeSurplusCoins;
|
Integer surplusCoins = coins - beforeUsedCoins;
|
if (surplusCoins < 0) {
|
return R.fail("戳戳币总额少于已发出的数量");
|
}
|
mcsGame.setSurplusCoins(surplusCoins);
|
} else if (type.equals(2)) {
|
//2.体验游戏
|
Integer awardType = mcsGameDTO.getAwardType();
|
if (isNull(awardType)) {
|
return R.fail("缺少奖励类型");
|
}
|
} else {
|
return R.fail("未知错误");
|
}
|
Integer beforeCoupons = mcsGame.getCoupons();
|
Integer beforeSurplusCoupons = mcsGame.getSurplusCoupons();
|
Integer beforeUsedCoupons = beforeCoupons - beforeSurplusCoupons;
|
BeanUtils.copyProperties(mcsGameDTO, mcsGame);
|
Integer coupons = mcsGame.getCoupons();
|
Integer surplusCoupons = coupons - beforeUsedCoupons;
|
if (surplusCoupons < 0) {
|
return R.fail("卷总数少于已发出的数量");
|
}
|
mcsGame.setSurplusCoupons(surplusCoupons);
|
int num = this.baseMapper.updateById(mcsGame);
|
if (num > 0) {
|
return R.ok();
|
}
|
return R.fail("编辑失败,请重新尝试");
|
}
|
|
/**
|
* 发布戳戳游戏
|
* @param gameId
|
* @param userId
|
* @return
|
*/
|
@Override
|
public R publishMcsGame(Long gameId, Long userId) {
|
McsGame mcsGame = this.baseMapper.selectById(gameId);
|
if (isNull(mcsGame)) {
|
return R.fail("资源不存在");
|
}
|
McsMerchant mcsMerchant = mcsMerchantDAO.selectById(mcsGame.getMerchantId());
|
Integer publishLimit = mcsMerchant.getPublishLimit();
|
Integer publishCount = this.baseMapper.selectPublishCount(mcsGame.getMerchantId());
|
if (publishCount >= publishLimit) {
|
return R.fail("空闲戳戳点不足");
|
}
|
mcsGame.setStatus(McsGame.Status.jxz);
|
mcsGame.setPublishAt(new Date());
|
mcsGame.setUpdatedBy(userId);
|
int num = this.baseMapper.updateById(mcsGame);
|
if (num > 0) {
|
return R.ok();
|
}
|
return R.fail("发布失败,请重新尝试");
|
}
|
|
/**
|
* 结束戳戳游戏
|
* @param gameId
|
* @param userId
|
* @return
|
*/
|
@Override
|
public R finishMcsGame(Long gameId, Long userId) {
|
McsGame mcsGame = this.baseMapper.selectById(gameId);
|
if (isNull(mcsGame)) {
|
return R.fail("资源不存在");
|
}
|
mcsGame.setStatus(McsGame.Status.yjs);
|
mcsGame.setUpdatedBy(userId);
|
int num = this.baseMapper.updateById(mcsGame);
|
if (num > 0) {
|
return R.ok();
|
}
|
return R.fail("结束失败,请重新尝试");
|
}
|
|
/**
|
* 戳戳游戏顶部统计数据
|
* @param userId
|
* @param type
|
* @return
|
*/
|
@Override
|
public R getTopStatistics(Long userId, Integer type) {
|
McsMerchant mcsMerchant = mcsMerchantDAO.selectOne(new QueryWrapper<McsMerchant>().lambda().eq(McsMerchant::getUserId, userId));
|
if (isNull(mcsMerchant)) {
|
return R.fail("未查询到商家信息");
|
}
|
TopStatisticsVO topStatisticsVO = new TopStatisticsVO();
|
topStatisticsVO.setExpireAt(mcsMerchant.getExpireAt());
|
if (nonNull(mcsMerchant.getExpireAt())) {
|
int surplusLitDays = DateUtils.retrieveRemainingDays(mcsMerchant.getExpireAt());
|
topStatisticsVO.setSurplusLitDays(surplusLitDays > 0 ? surplusLitDays : 0);
|
}
|
Integer appliedCount = this.baseMapper.selectAppliedCount(mcsMerchant.getId(), type);
|
topStatisticsVO.setAppliedTotal(appliedCount);
|
Integer verifiedCount = this.baseMapper.selectVerifiedCount(mcsMerchant.getId(), type);
|
topStatisticsVO.setVerifiedTotal(verifiedCount);
|
|
Integer publishLimit = mcsMerchant.getPublishLimit();
|
Integer publishCount = this.baseMapper.selectPublishCount(mcsMerchant.getId());
|
Integer idleTotal = publishLimit - publishCount;
|
topStatisticsVO.setIdleTotal(idleTotal > 0 ? idleTotal : 0);
|
return R.ok(topStatisticsVO);
|
}
|
|
/**
|
* 戳戳卷领取
|
* @param gameId
|
* @param userId
|
* @return
|
*/
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public R applyMcsCoupon(Long gameId, Long userId) {
|
McsGame mcsGame = this.baseMapper.selectById(gameId);
|
if (isNull(mcsGame) || mcsGame.getIsDel()) {
|
return R.fail("游戏已下架");
|
}
|
Integer userAppliedCount = mcsCouponDAO.selectCount(new QueryWrapper<McsCoupon>().lambda().eq(McsCoupon::getGameId, gameId).eq(McsCoupon::getUserId, userId));
|
if (userAppliedCount > 0) {
|
return R.fail("请勿重复领取");
|
}
|
Integer surplusCoupons = mcsGame.getSurplusCoupons();
|
if (surplusCoupons <= 0) {
|
return R.fail("抢光了");
|
}
|
McsCoupon mcsCoupon = new McsCoupon();
|
Long snowflakeId = Snowflake.getId();
|
mcsCoupon.setId(snowflakeId);
|
mcsCoupon.setGameId(gameId);
|
mcsCoupon.setUserId(userId);
|
mcsCoupon.setQrCode(QRCodeUtil.getBase64QRCode(snowflakeId.toString()));
|
Integer type = mcsGame.getType();
|
if (type.equals(1)) {
|
//戳戳币游戏
|
Integer allocation = mcsGame.getAllocation();
|
if (allocation.equals(1)) {
|
//随机分配
|
Integer surplusCoins = mcsGame.getSurplusCoins();
|
Integer coin = getRandomCoins(surplusCoins, mcsGame.getSurplusCoupons());
|
mcsCoupon.setCoin(coin);
|
mcsCoupon.setAward("戳戳币:" + coin);
|
mcsGame.setSurplusCoins(surplusCoins - coin);
|
} else {
|
//固定值
|
mcsCoupon.setCoin(mcsGame.getCoins());
|
mcsCoupon.setAward("戳戳币:" + mcsGame.getCoins());
|
}
|
} else {
|
//体验游戏
|
Integer awardType = mcsGame.getAwardType();
|
if (awardType.equals(1)) {
|
mcsCoupon.setAward("免费领");
|
} else if (awardType.equals(2)) {
|
mcsCoupon.setAward("产品试用");
|
} else if (awardType.equals(3)) {
|
mcsCoupon.setAward("消费赠礼");
|
} else {
|
mcsCoupon.setAward("优惠券");
|
}
|
}
|
int num = mcsCouponDAO.insert(mcsCoupon);
|
if (num > 0) {
|
mcsGame.setSurplusCoupons(surplusCoupons - 1);
|
this.baseMapper.updateById(mcsGame);
|
McsCouponVO mcsCouponVO = new McsCouponVO();
|
mcsCouponVO.setId(snowflakeId);
|
mcsCouponVO.setIsVerified(false);
|
mcsCouponVO.setQrCode(mcsCoupon.getQrCode());
|
mcsCouponVO.setAward(mcsCoupon.getAward());
|
return R.ok(mcsCouponVO);
|
}
|
return R.fail("领取失败,请重试");
|
}
|
|
/**
|
* h5分页查询戳戳游戏
|
* @param pageMcsGameDTO
|
* @return
|
*/
|
@Override
|
public R pageH5McsGame(PageMcsGameDTO pageMcsGameDTO) {
|
Page page = new Page<>();
|
page.setSize(pageMcsGameDTO.getPageSize());
|
page.setCurrent(pageMcsGameDTO.getPageNum());
|
IPage<McsGameVO> mcsGames = this.baseMapper.pageH5McsGame(page, pageMcsGameDTO);
|
return R.ok(mcsGames);
|
}
|
|
/**
|
* 游戏详情
|
* @param gameId
|
* @return
|
*/
|
@Override
|
public R getMcsGame(Long gameId) {
|
McsGameVO mcsGameVO = this.baseMapper.selectDetailById(gameId);
|
Integer gameCount = this.baseMapper.selectCount(new QueryWrapper<McsGame>().lambda()
|
.eq(McsGame::getMerchantId, mcsGameVO.getMerchantId()).eq(McsGame::getStatus, McsGame.Status.jxz)
|
.eq(McsGame::getType, mcsGameVO.getType()).eq(McsGame::getIsDel, false));
|
mcsGameVO.setGameCount(gameCount);
|
return R.ok(mcsGameVO);
|
}
|
|
/**
|
* 定时任务-每隔5分钟执行一次,将已到期的微商业街游戏结束
|
* @return
|
*/
|
@Override
|
public R endStatusForMcsGame() {
|
List<McsGame> games = this.baseMapper.selectNeedDealExpire();
|
if (nonNull(games) && !games.isEmpty()) {
|
games.forEach(e -> e.setStatus(McsGame.Status.yjs));
|
this.updateBatchById(games);
|
}
|
return R.ok();
|
}
|
|
public static void main(String[] args) {
|
int total = 500;
|
int people = 10;
|
for (int i = 1;i <= 10; i++) {
|
Integer decrease = getRandomCoins(total, people);
|
total -= decrease;
|
people --;
|
System.out.println("第:" + i + "个人领取到:" + decrease + "戳戳币,总数还剩下:" + total);
|
}
|
}
|
|
public static Integer getRandomCoins(int totalCoins, int peopleTotal) {
|
List<Integer> list = new ArrayList<>(peopleTotal);
|
if (peopleTotal == 1) {
|
return totalCoins;
|
}
|
Random random = new Random();
|
// 平均分配
|
int average = totalCoins / peopleTotal;
|
int max = (int) Math.floor(totalCoins * 0.6);
|
int min = (int) Math.floor(average * 0.5);
|
float thresh = 0.95F;
|
int rest = totalCoins - average * peopleTotal;
|
for (int i = 0; i < peopleTotal; i++) {
|
if (i < rest) {
|
list.add(average + 1);
|
} else {
|
list.add(average);
|
}
|
}
|
// 根据阀值进行数据随机处理
|
int randOfRange = 0;
|
int randRom = 0;
|
int nextIndex = 0;
|
int nextValue = 0;
|
//多余
|
int surplus = 0;
|
//缺少
|
int lack = 0;
|
for (int i = 0; i < peopleTotal - 1; i++) {
|
nextIndex = i + 1;
|
int itemThis = list.get(i);
|
int itemNext = list.get(nextIndex);
|
boolean isLt = itemThis < itemNext;
|
int rangeThis = isLt ? max - itemThis : itemThis - min;
|
int rangeNext = isLt ? itemNext - min : max - itemNext;
|
int rangeFinal = (int) Math.ceil(thresh * (Math.min(rangeThis, rangeNext) + 1));
|
randOfRange = random.nextInt(rangeFinal);
|
randRom = isLt ? 1 : -1;
|
int iValue = list.get(i) + randRom * randOfRange;
|
nextValue = list.get(nextIndex) + randRom * randOfRange * -1;
|
if (iValue > max) {
|
surplus += (iValue - max);
|
list.set(i, max);
|
} else if (iValue < min) {
|
list.set(i, min);
|
lack += (min - iValue);
|
} else {
|
list.set(i, iValue);
|
}
|
list.set(nextIndex, nextValue);
|
}
|
if (nextValue > max) {
|
surplus += (nextValue - max);
|
list.set(nextIndex, max);
|
}
|
if (nextValue < min) {
|
lack += (min - nextValue);
|
list.set(nextIndex, min);
|
}
|
if (surplus - lack > 0) {
|
//分少了 给低于max的凑到max
|
for (int i = 0; i < list.size(); i++) {
|
int value = list.get(i);
|
if (value < max) {
|
int tmp = max - value;
|
if (surplus >= tmp) {
|
surplus -= tmp;
|
list.set(i, max);
|
} else {
|
list.set(i, value + surplus);
|
return list.get(random.nextInt(list.size() - 1));
|
}
|
}
|
}
|
} else if (lack - surplus > 0) {
|
//分多了 给超过高于min的人凑到min
|
for (int i = 0; i < list.size(); i++) {
|
int value = list.get(i);
|
if (value > min) {
|
int tmp = value - min;
|
if (lack >= tmp) {
|
lack -= tmp;
|
list.set(i, min);
|
} else {
|
list.set(i, min + tmp - lack);
|
return list.get(random.nextInt(list.size() - 1));
|
}
|
}
|
}
|
}
|
return list.get(random.nextInt(list.size() - 1));
|
}
|
}
|