package com.ruoyi.other.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.ruoyi.account.api.feignClient.AppUserClient;
|
import com.ruoyi.account.api.model.AppUser;
|
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.utils.PageUtils;
|
import com.ruoyi.common.core.utils.ServletUtils;
|
import com.ruoyi.common.core.utils.StringUtils;
|
import com.ruoyi.common.core.web.page.TableDataInfo;
|
import com.ruoyi.common.security.service.TokenService;
|
import com.ruoyi.common.security.utils.SecurityUtils;
|
import com.ruoyi.order.feignClient.OrderClient;
|
import com.ruoyi.other.api.domain.*;
|
import com.ruoyi.other.mapper.GoodsShopMapper;
|
import com.ruoyi.other.mapper.SeckillActivityInfoMapper;
|
import com.ruoyi.other.mapper.ShopMapper;
|
import com.ruoyi.other.service.GoodsSeckillService;
|
import com.ruoyi.other.service.GoodsService;
|
import com.ruoyi.other.service.SeckillActivityInfoService;
|
import com.ruoyi.other.util.GeodesyUtil;
|
import com.ruoyi.other.vo.SeckillActivityDetailVO;
|
import com.ruoyi.other.vo.SeckillActivityVO;
|
import com.ruoyi.system.api.domain.SysConfig;
|
import com.ruoyi.system.api.feignClient.SysConfigClient;
|
import com.ruoyi.system.api.model.LoginUser;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import javax.annotation.Resource;
|
import java.math.BigDecimal;
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.util.ArrayList;
|
import java.util.Comparator;
|
import java.util.List;
|
import java.util.stream.Collectors;
|
|
/**
|
* <p>
|
* 服务实现类
|
* </p>
|
*
|
* @author luodangjia
|
* @since 2024-11-20
|
*/
|
@Service
|
public class SeckillActivityInfoServiceImpl extends ServiceImpl<SeckillActivityInfoMapper, SeckillActivityInfo> implements SeckillActivityInfoService {
|
@Resource
|
private SeckillActivityInfoMapper seckillActivityInfoMapper;
|
@Resource
|
private GoodsShopMapper goodsShopMapper;
|
@Resource
|
private ShopMapper shopMapper;
|
@Resource
|
private TokenService tokenService;
|
@Resource
|
private AppUserClient appUserClient;
|
@Resource
|
private GoodsSeckillService goodsSeckillService;
|
@Resource
|
private SysConfigClient sysConfigClient;
|
@Resource
|
private GoodsService goodsService;
|
@Resource
|
private OrderClient orderClient;
|
@Override
|
public TableDataInfo<SeckillActivityVO> listSeckillActivity(Goods goods) {
|
List<SeckillActivityVO> seckillActivityVOS = seckillActivityInfoMapper.listSeckillActivity(goods);
|
for (SeckillActivityVO seckillActivityVO : seckillActivityVOS) {
|
Integer data = orderClient.getGoodsSaleNum(seckillActivityVO.getGoodsId(), 2).getData();
|
seckillActivityVO.setSaleNum(data);
|
LocalDateTime startTime = seckillActivityVO.getStartTime();
|
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime endTime = seckillActivityVO.getEndTime();
|
if (endTime.isBefore(now)){
|
seckillActivityVO.setStatus(3); //已结束
|
}else if (startTime.isBefore(now) && endTime.isAfter(now)){
|
seckillActivityVO.setStatus(2); // 已开始
|
}else {
|
seckillActivityVO.setStatus(1); // 未开始
|
}
|
}
|
|
Integer pageCurr = goods.getPageCurr();
|
Integer pageSize = goods.getPageSize();
|
String orderByColumn = goods.getOrderByColumn();
|
String isAsc = goods.getIsAsc();
|
// 排序
|
Comparator<SeckillActivityVO> comparator = getComparator(orderByColumn, isAsc);
|
List<SeckillActivityVO> sortedList = seckillActivityVOS.stream()
|
.sorted(comparator)
|
.collect(Collectors.toList());
|
|
// 分页
|
int startIndex = (pageCurr - 1) * pageSize;
|
int endIndex = Math.min(startIndex + pageSize, sortedList.size());
|
|
if (startIndex >= sortedList.size()) {
|
return new TableDataInfo();
|
}
|
TableDataInfo tableDataInfo = new TableDataInfo();
|
tableDataInfo.setRows(sortedList.subList(startIndex, endIndex));
|
tableDataInfo.setTotal(sortedList.size());
|
tableDataInfo.setCode(200);
|
return tableDataInfo;
|
}
|
|
private Comparator<SeckillActivityVO> getComparator(String orderByColumn, String isAsc) {
|
if (StringUtils.isEmpty(orderByColumn)){
|
return Comparator.comparing(SeckillActivityVO::getId);
|
}
|
Comparator<SeckillActivityVO> comparator;
|
|
switch (orderByColumn) {
|
case "tgs.selling_price":
|
comparator = Comparator.comparing(SeckillActivityVO::getSellingPrice);
|
break;
|
case "integral":
|
comparator = Comparator.comparing(SeckillActivityVO::getIntegral);
|
break;
|
case "sale_num":
|
comparator = Comparator.comparing(SeckillActivityVO::getSaleNum);
|
break;
|
// 添加其他排序字段
|
default:
|
comparator = Comparator.comparing(SeckillActivityVO::getId); // 默认按ID排序
|
break;
|
}
|
|
if ("desc".equalsIgnoreCase(isAsc)) {
|
comparator = comparator.reversed();
|
}
|
return comparator;
|
}
|
|
@Override
|
public SeckillActivityDetailVO detail(Integer seckillActivityId, String latitude, String longitude) {
|
/* Integer vipId = 0;
|
String token = SecurityUtils.getToken(ServletUtils.getRequest());
|
if(StringUtils.isNotEmpty(token)){
|
Long userid = tokenService.getLoginUserApplet().getUserid();
|
AppUser appUser = appUserClient.getAppUserById(userid);
|
vipId = appUser.getVipId();
|
}
|
SeckillActivityInfo activityInfo = this.getById(seckillActivityId);
|
if(null == activityInfo || activityInfo.getDelFlag() == 1){
|
throw new RuntimeException("活动不存在");
|
}
|
if(activityInfo.getIsShelves() == 0){
|
throw new RuntimeException("活动已下架");
|
}
|
if(!activityInfo.getVipIds().contains(vipId.toString())){
|
throw new RuntimeException("权限不足");
|
}
|
SeckillActivityDetailVO seckillActivityDetailVO = seckillActivityInfoMapper.selectDetail(seckillActivityId, vipId);
|
Integer goodsId = seckillActivityDetailVO.getGoodsId();
|
|
Goods goods = goodsService.getById(goodsId);
|
seckillActivityDetailVO.setGoodsName(goods.getName());
|
seckillActivityDetailVO.setGoodsType(goods.getType());
|
List<Shop> shops;
|
if(goods.getAppointStore() == 1){
|
List<Integer> shopIdList = goodsShopMapper.selectList(new LambdaQueryWrapper<GoodsShop>()
|
.eq(GoodsShop::getGoodsId, goodsId)).stream().map(GoodsShop::getShopId).collect(Collectors.toList());
|
shops = shopMapper.selectList(new LambdaQueryWrapper<Shop>()
|
.in(shopIdList.size() > 0, Shop::getId, shopIdList).eq(Shop::getDelFlag, 0));
|
}else{
|
shops = shopMapper.selectList(new LambdaUpdateWrapper<Shop>().eq(Shop::getDelFlag, 0));
|
}
|
|
if(StringUtils.isNotEmpty(longitude) && StringUtils.isNotEmpty(latitude)){
|
for (Shop shop : shops) {
|
Double wgs84 = GeodesyUtil.getDistance(longitude + "," + latitude, shop.getLongitude() + "," + shop.getLatitude()).get("WGS84");
|
shop.setDistance(wgs84);
|
}
|
shops.sort(new Comparator<Shop>() {
|
@Override
|
public int compare(Shop o1, Shop o2) {
|
return o1.getDistance().compareTo(o2.getDistance());
|
}
|
});
|
}
|
seckillActivityDetailVO.setShopList(shops);
|
Integer integer = orderClient.getGoodsSaleNum(goods.getId(), 2).getData();
|
seckillActivityDetailVO.setSaleNum(integer);
|
return seckillActivityDetailVO;*/
|
return null;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void saveSeckillActivityInfo(SeckillActivityInfo seckillActivityInfo) {
|
Integer goodId = seckillActivityInfo.getGoodId();
|
|
//检查该商品是否有秒杀活动
|
SeckillActivityInfo one = this.getOne(new LambdaQueryWrapper<SeckillActivityInfo>().eq(SeckillActivityInfo::getGoodId, goodId).eq(SeckillActivityInfo::getDelFlag, 0));
|
if(null!=one){
|
throw new RuntimeException("该秒杀商品已在其他秒杀活动中存在");
|
}
|
seckillActivityInfo.setId(null);
|
seckillActivityInfo.setDelFlag(0);
|
seckillActivityInfo.setIsShelves(0);//下架状态
|
seckillActivityInfo.setSellingPrice(seckillActivityInfo.getActivityPrice());
|
this.baseMapper.insert(seckillActivityInfo);
|
//添加价格积分
|
GoodsSeckill goodsSeckill = new GoodsSeckill();
|
goodsSeckill.setSeckillActivityInfoId(seckillActivityInfo.getId());
|
goodsSeckill.setSellingPrice(seckillActivityInfo.getSellingPrice());
|
Integer point =getPoint(seckillActivityInfo.getSellingPrice());
|
goodsSeckill.setIntegral(point);
|
goodsSeckillService.save(goodsSeckill);
|
}
|
/**
|
* 获取现金对应积分
|
*/
|
public Integer getPoint(BigDecimal cash){
|
if (cash == null || cash.compareTo(BigDecimal.ZERO) < 0) {
|
throw new IllegalArgumentException("金额不能为null或负数");
|
}
|
// 获取积分兑换比例配置
|
R<SysConfig> info = sysConfigClient.getInfo(6L);
|
if (info == null || info.getData() == null) {
|
throw new RuntimeException("获取积分兑换比例配置失败");
|
}
|
String configValue = info.getData().getConfigValue();
|
if (StringUtils.isBlank(configValue)) {
|
throw new RuntimeException("积分兑换比例配置值为空");
|
}
|
try {
|
// 使用BigDecimal处理比例,避免精度问题
|
BigDecimal ratio = new BigDecimal(configValue.trim());
|
if (ratio.compareTo(BigDecimal.ZERO) <= 0) {
|
throw new RuntimeException("积分兑换比例必须大于0");
|
}
|
|
// 计算积分并四舍五入取整
|
return cash.multiply(ratio).intValue();
|
|
} catch (NumberFormatException e) {
|
throw new RuntimeException("积分兑换比例配置值格式错误", e);
|
} catch (ArithmeticException e) {
|
throw new RuntimeException("积分计算结果溢出", e);
|
}
|
|
}
|
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void updateSeckillActivityInfo(SeckillActivityInfo seckillActivityInfo) {
|
SeckillActivityInfo one = this.getOne(new LambdaQueryWrapper<SeckillActivityInfo>()
|
.eq(SeckillActivityInfo::getId, seckillActivityInfo.getId()).eq(SeckillActivityInfo::getDelFlag, 0));
|
if(null==one){
|
throw new RuntimeException("该秒杀活动不存在");
|
}
|
seckillActivityInfo.setSellingPrice(seckillActivityInfo.getActivityPrice());
|
this.baseMapper.updateById(seckillActivityInfo);//修改限购数量、开始时间、结束时间
|
|
//修改价格积分
|
Integer point =getPoint(seckillActivityInfo.getSellingPrice());
|
UpdateWrapper<GoodsSeckill> wrapper = new UpdateWrapper<>();
|
wrapper.eq("seckill_activity_info_id", seckillActivityInfo.getId())
|
.set("selling_price", seckillActivityInfo.getSellingPrice())
|
.set("integral", point);
|
goodsSeckillService.update(wrapper);
|
}
|
}
|