From 5a7486e9893a706ed464e3197c9711286b077896 Mon Sep 17 00:00:00 2001 From: huliguo <2023611923@qq.com> Date: 星期四, 26 六月 2025 11:12:28 +0800 Subject: [PATCH] 文件导入 --- ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/ShopServiceImpl.java | 469 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 425 insertions(+), 44 deletions(-) diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/ShopServiceImpl.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/ShopServiceImpl.java index 8a43b04..968a5ea 100644 --- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/ShopServiceImpl.java +++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/ShopServiceImpl.java @@ -1,5 +1,6 @@ package com.ruoyi.other.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -8,24 +9,30 @@ import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.utils.GeodesyUtil; -import com.ruoyi.common.core.utils.ServletUtils; import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.bean.BeanUtils; +import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.common.security.service.TokenService; -import com.ruoyi.common.security.utils.SecurityUtils; -import com.ruoyi.other.api.domain.Shop; -import com.ruoyi.other.mapper.ShopMapper; -import com.ruoyi.other.service.ShopService; -import com.ruoyi.other.vo.NearbyShopVO; -import com.ruoyi.other.vo.SaveWithdrawalAccount; -import com.ruoyi.other.vo.ShopDetailVO; +import com.ruoyi.order.feignClient.OrderClient; +import com.ruoyi.order.vo.Price; +import com.ruoyi.other.api.domain.*; +import com.ruoyi.other.dto.AddGoodsDTO; +import com.ruoyi.other.enums.GoodsStatus; +import com.ruoyi.other.mapper.*; +import com.ruoyi.other.service.*; +import com.ruoyi.other.vo.*; +import com.ruoyi.system.api.domain.SysConfig; import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.api.feignClient.SysConfigClient; import com.ruoyi.system.api.feignClient.SysUserClient; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; +import java.time.LocalDateTime; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -41,13 +48,44 @@ @Resource private ShopMapper shopMapper; @Resource + private GoodsService goodsService; + @Resource + private PhoneMapper phoneMapper; + @Resource + private ShopScoreService shopScoreService; + @Resource private AppUserClient appUserClient; @Resource private TokenService tokenService; @Resource private SysUserClient sysUserClient; + @Resource + private ShopScoreMapper scoreMapper; + @Resource + private ShopBalanceStatementMapper shopBalanceStatementMapper; + @Resource + private OrderClient orderClient; + @Resource + private SeckillActivityInfoService seckillActivityInfoService; + @Resource + private GoodsSeckillService goodsSeckillService; + @Resource + private SysConfigClient sysConfigClient; + @Resource + private GoodsShopMapper goodsShopMapper; + @Resource + private GoodsShopService goodsShopService; + @Resource + private GoodsEvaluateMapper goodsEvaluateMapper; + /** + * 获取门店列表 + * @param PageNum + * @param pageSize + * @param shop + * @return + */ @Override public IPage<Shop> getShopList(Integer PageNum, Integer pageSize, Shop shop) { Page<Shop> page = new Page<>(); @@ -56,52 +94,33 @@ return shopMapper.selectShopList(page, shop); } - @Override - public List<NearbyShopVO> nearbyShopList(BigDecimal longitude, BigDecimal latitude) { - String token = SecurityUtils.getToken(ServletUtils.getRequest()); - AppUser appUser = null; - if(StringUtils.isNotEmpty(token)){ - Long userid = tokenService.getLoginUserApplet().getUserid(); - appUser = appUserClient.getAppUserById(userid); - } - List<NearbyShopVO> nearbyShopVOS = shopMapper.selectNearbyShopList(); + /** + * 获取最近的门店 + * @param longitude + * @param latitude + * @return + */ + @Override + public List<NearbyShopVO> nearbyShopList(BigDecimal longitude, BigDecimal latitude,Shop shop) { + //获取所有店 + List<NearbyShopVO> nearbyShopVOS = shopMapper.selectNearbyShopList(shop); + if (nearbyShopVOS == null || nearbyShopVOS.isEmpty()) { + return Collections.emptyList(); + } + //计算距离 for (NearbyShopVO nearbyShopVO : nearbyShopVOS) { Double wgs84 = GeodesyUtil.getDistance(nearbyShopVO.getLongitude() + "," + nearbyShopVO.getLatitude(), longitude + "," + latitude).get("WGS84"); nearbyShopVO.setDistance(new BigDecimal(wgs84).setScale(2, RoundingMode.HALF_EVEN).doubleValue()); } + /*//排序 nearbyShopVOS.sort(new Comparator<NearbyShopVO>() { @Override public int compare(NearbyShopVO o1, NearbyShopVO o2) { return o1.getDistance().compareTo(o2.getDistance()); } - }); + });*/ - if(null != appUser && null != appUser.getShopId()){ - AppUser finalAppUser = appUser; - Optional<NearbyShopVO> first = nearbyShopVOS.stream().filter(s -> s.getId().equals(finalAppUser.getShopId().longValue())).findFirst(); - if(first.isPresent()){ - NearbyShopVO nearbyShopVO = first.get(); - if(null != nearbyShopVO){ - nearbyShopVOS.remove(nearbyShopVO); - } - } - - Shop shop = shopMapper.selectById(appUser.getShopId()); - if(null != shop && shop.getDelFlag() == 0 && shop.getStatus() == 1){ - NearbyShopVO vo = new NearbyShopVO(); - vo.setId(appUser.getShopId().longValue()); - vo.setName(shop.getName()); - vo.setAddress(shop.getAddress()); - vo.setHomePicture(shop.getHomePicture()); - Double wgs84 = GeodesyUtil.getDistance(longitude.toString() + "," + latitude.toString(), shop.getLongitude() + "," + shop.getLatitude()).get("WGS84"); - vo.setDistance(new BigDecimal(wgs84).setScale(2, RoundingMode.HALF_EVEN).doubleValue()); - nearbyShopVOS.add(0, vo); - } - } - if (nearbyShopVOS == null || nearbyShopVOS.isEmpty()) { - return Collections.emptyList(); - } return sortByDistance(nearbyShopVOS); } @@ -122,9 +141,28 @@ if (shopDetailVO == null) { throw new ServiceException("查询店铺不存在"); } + //查询客服电话 + Phone phone = phoneMapper.selectOne(new LambdaQueryWrapper<Phone>().eq(Phone::getShopId, shopDetailVO.getId())); + ArrayList<String> phones = new ArrayList<>(); + if (phone != null) { + if (phone.getPhoneOne() != null) { + phones.add(phone.getPhoneOne()); + } + if (phone.getPhoneTwo() != null) { + phones.add(phone.getPhoneTwo()); + } + } + shopDetailVO.setPhones(phones); + + //我的评分 + if (userid != null){ + ShopScore one = shopScoreService.getOne(new LambdaQueryWrapper<ShopScore>().eq(ShopScore::getAppUserId, userid).eq(ShopScore::getShopId, shopId).last(" order by create_time desc limit 0, 1")); + shopDetailVO.setMyScore(null == one ? BigDecimal.ZERO : one.getScore()); + } // 计算距离 - if (shopDetailVO.getLongitude() != null && shopDetailVO.getLatitude() != null){ + if (shopDetailVO.getLongitude() != null && shopDetailVO.getLatitude() != null + && longitude != null && latitude != null) { String shopLocation = String.format("%s,%s", shopDetailVO.getLongitude(), shopDetailVO.getLatitude()); String userLocation = String.format("%s,%s", longitude.toString(), latitude.toString()); Map<String, Double> distanceMap = GeodesyUtil.getDistance(userLocation, shopLocation); @@ -133,6 +171,8 @@ } return shopDetailVO; } + + @Override public Boolean cheUserByPhone(String phone) { @@ -161,4 +201,345 @@ this.updateById(shop); } } + + /** + * 门店余额统计 + * @param shopId + * @return + */ + @Override + public ShopBalanceVO getShopBalance(Integer shopId) { + Shop shop = shopMapper.selectById(shopId); + ShopBalanceVO shopBalanceVO = new ShopBalanceVO(); + shopBalanceVO.setBalance(shop.getBalance()); + shopBalanceVO.setCanWithdrawMoney(shop.getCanWithdrawMoney()); + shopBalanceVO.setWithdrawMoney(shop.getWithdrawMoney()); + shopBalanceVO.setWithdrawAuditMoney(shop.getWithdrawAuditMoney()); + //冻结金额 = 余额 - 可提现金额 + shopBalanceVO.setFreezeMoney(shop.getBalance().subtract(shop.getCanWithdrawMoney())); + return shopBalanceVO; + } + + /** + * 门店余额变更明细 + */ + @Override + public PageInfo<ShopBalanceStatementVO> getShopBalanceStatementList(Integer shopId, LocalDateTime startTime, LocalDateTime endTime, Integer type, Integer pageCurr, Integer pageSize) { + PageInfo<ShopBalanceStatementVO> pageInfo = new PageInfo<>(pageCurr, pageSize); + List<ShopBalanceStatementVO> ShopBalanceStatementList = shopBalanceStatementMapper.getShopBalanceStatementList(pageInfo, shopId, startTime, endTime, type); + + for (ShopBalanceStatementVO shopBalanceStatementVO : ShopBalanceStatementList) { + log.error(shopBalanceStatementVO.toString()); + BigDecimal historicalBalance = shopBalanceStatementVO.getHistoricalBalance(); + BigDecimal balance = shopBalanceStatementVO.getBalance(); + if (historicalBalance != null && balance != null) { + shopBalanceStatementVO.setFlag( + historicalBalance.compareTo(balance) > 0 ? 2 : 1 + ); + } + } + pageInfo.setRecords(ShopBalanceStatementList); + return pageInfo; + } + + /** + * 店铺内商品列表 门店后台 + */ + @Override + public List<GoodsVO> getGoodsListByShopId(PageInfo<GoodsVO> pageInfo, Integer shopId) { + //查询该门店商品 + List<GoodsVO> goods = shopMapper.selectListByShopId(pageInfo, shopId); + if(null == goods){ + return null; + } + // 根据id去重 + List<GoodsVO> distinctGoods = goods.stream() + .collect(Collectors.collectingAndThen( + Collectors.toMap(GoodsVO::getGoodsId, Function.identity(), (existing, replacement) -> existing), + map -> new ArrayList<>(map.values()) + )); + for (GoodsVO good : distinctGoods) { + //价格 + Price price = getPrice( good.getGoodsId()); + if(null != price){ + //秒杀活动 + good.setSellingPrice(price.getCash()); + good.setIntegral(price.getPoint()); + good.setStartTime(price.getStartTime()); + good.setEndTime(price.getEndTime()); + good.setPurchaseLimit(price.getPurchaseLimit()); + } + Integer data = orderClient.getGoodsSaleNum(good.getGoodsId(), 1).getData(); + good.setSaleNum(data); + } + return distinctGoods; + } + + @Override + public GoodsVO goodsDetail(Long goodsId) { + if (goodsId == null || goodsId <= 0) { + throw new NullPointerException("商品ID不能为空"); + } + + Goods goods = goodsService.getById(goodsId); + if(null == goods || goods.getDelFlag() == 1){ + throw new RuntimeException("商品不存在"); + } + + GoodsVO goodsVO = new GoodsVO(); + BeanUtils.copyBeanProp(goodsVO, goods); + goodsVO.setGoodsId(goods.getId()); + goodsVO.setGoodsName(goods.getName()); + + //商品活动前售价(编辑商品回显) + goodsVO.setEditPrice(goods.getSellingPrice()); + //限购数量(编辑商品回显) + goodsVO.setEditNum(goods.getPurchaseLimit()); + + //计算所需价格和积分 + Price price = getPrice( goods.getId()); + if(null != price){ + //在秒杀活动时间段内 + goodsVO.setSellingPrice(price.getCash()); + goodsVO.setIntegral(price.getPoint()); + goodsVO.setStartTime(price.getStartTime()); + goodsVO.setEndTime(price.getEndTime()); + } + //已售数量 + Integer data = orderClient.getGoodsSaleNum(goods.getId(), 1).getData(); + goodsVO.setSaleNum(data); + //一个商品对应一个门店 + //查找门店 + GoodsShop goodsShop = goodsShopMapper.selectOne(new LambdaQueryWrapper<GoodsShop>() + .eq(GoodsShop::getGoodsId, goodsId)); + Shop shop1 = shopMapper.selectById(goodsShop.getShopId()); + goodsVO.setShop(shop1); + //已售数量 + Integer integer = orderClient.getGoodsSaleNum(goods.getId(), 1).getData(); + goodsVO.setSaleNum(integer); + //分类id + goodsVO.setGoodsCategoryId(goods.getGoodsCategoryId()); + + //一个商品只有一个秒杀活动 + SeckillActivityInfo seckillActivityInfo = seckillActivityInfoService.getOne(new LambdaQueryWrapper<SeckillActivityInfo>() + .eq(SeckillActivityInfo::getGoodId, goodsId) + .eq(SeckillActivityInfo::getIsShelves,1) + .eq(SeckillActivityInfo::getDelFlag, 0)); + //商品是否开启秒杀活动 + goodsVO.setIsSkillActivity(0); + if (seckillActivityInfo != null) { + goodsVO.setIsSkillActivity(1); + //活动限购数量 + goodsVO.setEditActivityNum(seckillActivityInfo.getMaxNum()); + GoodsSeckill one = goodsSeckillService.getOne(new LambdaQueryWrapper<GoodsSeckill>().eq(GoodsSeckill::getSeckillActivityInfoId, seckillActivityInfo.getId())); + //有秒杀活动,查看秒杀价格 + goodsVO.setEditActivityPrice(one.getSellingPrice()); + } + + //商品评价 + GoodsEvaluate goodsEvaluateOne = goodsEvaluateMapper.getGoodsEvaluateOne(goods.getId()); + if(goodsEvaluateOne != null){ + AppUser appUserById = appUserClient.getAppUserById(goodsEvaluateOne.getAppUserId()); + goodsEvaluateOne.setUserName(appUserById.getName()); + goodsEvaluateOne.setAvatar(appUserById.getAvatar()); + goodsVO.setGoodsEvaluate(goodsEvaluateOne); + } + return goodsVO; + + } + + + /** + * 发布商品 门店后台-商品管理 + */ + @Override + public Integer addGoodsByShop(AddGoodsDTO addGoodsDTO) { + if(addGoodsDTO.getPurchaseLimit()==null){ + addGoodsDTO.setPurchaseLimit(-1); + } + Goods goods = new Goods(); + BeanUtils.copyProperties(addGoodsDTO, goods); + goods.setSaleNum(0);//销量 + goods.setStatus(GoodsStatus.DOWN.getCode());//下架状态 + goods.setIntegral(getPoint(addGoodsDTO.getSellingPrice()));//积分 + goods.setDelFlag(0); + goods.setCreateTime(LocalDateTime.now()); + goodsService.save(goods);//添加商品 + //保存商品门店关系 + GoodsShop goodsShop = new GoodsShop(); + goodsShop.setGoodsId(goods.getId()); + goodsShop.setShopId(addGoodsDTO.getShopId()); + Shop shop = shopMapper.selectById(addGoodsDTO.getShopId()); + if(shop==null){ + throw new ServiceException("门店不存在"); + } + goodsShop.setShopName(shop.getName()); + goodsShop.setOwnerName(shop.getShopManager()); + goodsShop.setPhone(shop.getPhone()); + goodsShop.setAddress(shop.getAddress()); + goodsShopService.save(goodsShop); + //判断是否参加秒杀活动 + if (addGoodsDTO.getIsActivity()==1){ + //秒杀活动 + SeckillActivityInfo seckillActivityInfo = new SeckillActivityInfo(); + seckillActivityInfo.setDelFlag(0); + seckillActivityInfo.setCreateTime(LocalDateTime.now()); + seckillActivityInfo.setGoodId(goods.getId()); + seckillActivityInfo.setMaxNum(addGoodsDTO.getMaxNum()); + seckillActivityInfo.setStartTime(addGoodsDTO.getStartTime()); + seckillActivityInfo.setEndTime(addGoodsDTO.getEndTime()); + seckillActivityInfo.setIsShelves(1);//默认上架 + seckillActivityInfoService.save(seckillActivityInfo); + //秒杀活动价格 + GoodsSeckill goodsSeckill = new GoodsSeckill(); + goodsSeckill.setSellingPrice(addGoodsDTO.getActivityPrice()); + goodsSeckill.setIntegral(getPoint(addGoodsDTO.getActivityPrice())); + goodsSeckill.setSeckillActivityInfoId(seckillActivityInfo.getId()); + goodsSeckillService.save(goodsSeckill); + } + return goods.getId(); + } + + + /** + * 编辑商品 + * @param addGoodsDTO + * @return + */ + + @Override + public Integer editGoodsByShop(AddGoodsDTO addGoodsDTO) { + if(addGoodsDTO.getPurchaseLimit()==null){ + addGoodsDTO.setPurchaseLimit(-1); + } + //先修改商品 + Goods goods = new Goods(); + BeanUtils.copyProperties(addGoodsDTO, goods); + goods.setStatus(GoodsStatus.DOWN.getCode());//下架状态 + goods.setId(addGoodsDTO.getGoodId()); + goods.setIntegral(getPoint(addGoodsDTO.getSellingPrice()));//积分 + goods.setDelFlag(0); + goods.setCreateTime(LocalDateTime.now()); + goodsService.updateById(goods);//添加商品 + + + //门店关系不变 + + //判断是否参加秒杀活动 + if (addGoodsDTO.getIsActivity()==1){//参加 + //一个商品只有一个秒杀活动 + SeckillActivityInfo seckillActivityInfo = seckillActivityInfoService.getOne(new LambdaQueryWrapper<SeckillActivityInfo>() + .eq(SeckillActivityInfo::getGoodId, addGoodsDTO.getGoodId()) + .eq(SeckillActivityInfo::getDelFlag, 0)); + if (seckillActivityInfo != null) { + //删除原本活动 + goodsSeckillService.remove(new LambdaQueryWrapper<GoodsSeckill>().eq(GoodsSeckill::getSeckillActivityInfoId, seckillActivityInfo.getId())); + //删除主表 + seckillActivityInfoService.removeById(seckillActivityInfo.getId()); + } + //新增 + //秒杀活动 + SeckillActivityInfo seckillActivityInfo1 = new SeckillActivityInfo(); + seckillActivityInfo1.setDelFlag(0); + seckillActivityInfo1.setCreateTime(LocalDateTime.now()); + seckillActivityInfo1.setGoodId(goods.getId()); + seckillActivityInfo1.setMaxNum(addGoodsDTO.getMaxNum()); + seckillActivityInfo1.setStartTime(addGoodsDTO.getStartTime()); + seckillActivityInfo1.setEndTime(addGoodsDTO.getEndTime()); + seckillActivityInfo1.setIsShelves(1);//默认上架 + seckillActivityInfoService.save(seckillActivityInfo1); + //秒杀活动价格 + GoodsSeckill goodsSeckill = new GoodsSeckill(); + goodsSeckill.setSellingPrice(addGoodsDTO.getActivityPrice()); + goodsSeckill.setIntegral(getPoint(addGoodsDTO.getActivityPrice())); + goodsSeckill.setSeckillActivityInfoId(seckillActivityInfo1.getId()); + goodsSeckillService.save(goodsSeckill); + }else{ + //不参加秒杀活动,删除之前的活动 + //一个商品只有一个秒杀活动 + SeckillActivityInfo seckillActivityInfo = seckillActivityInfoService.getOne(new LambdaQueryWrapper<SeckillActivityInfo>() + .eq(SeckillActivityInfo::getGoodId, addGoodsDTO.getGoodId()) + .eq(SeckillActivityInfo::getDelFlag, 0)); + if (seckillActivityInfo != null) { + //删除原本活动 + goodsSeckillService.remove(new LambdaQueryWrapper<GoodsSeckill>().eq(GoodsSeckill::getSeckillActivityInfoId, seckillActivityInfo.getId())); + //删除主表 + seckillActivityInfoService.removeById(seckillActivityInfo.getId()); + } + } + return goods.getId(); + } + + @Override + public PageInfo<ShopBalanceListVO> getBalanceList(String name, Integer pageCurr, Integer pageSize) { + PageInfo<ShopBalanceListVO> pageInfo = new PageInfo<>(pageCurr, pageSize); + + List<ShopBalanceListVO> list = shopMapper.getBalanceList(pageInfo,name); + + + pageInfo.setRecords(list); + return pageInfo; + } + + /** + * 获取商品当前的价格,就是看当前商品是否在秒杀活动中 + */ + public Price getPrice( Integer goodsId){ + //判断是否有在秒杀活动时间中 + Price price = new Price(); + SeckillActivityInfo one = seckillActivityInfoService.getOne(new LambdaQueryWrapper<SeckillActivityInfo>().eq(SeckillActivityInfo::getGoodId, goodsId) + .eq(SeckillActivityInfo::getIsShelves, 1).eq(SeckillActivityInfo::getDelFlag, 0) + .last(" and now() between start_time and end_time order by create_time desc limit 0, 1")); + GoodsSeckill goodsSeckill = null;//秒杀配置 + if(null != one){ + //有秒杀活动,查看秒杀价格 + goodsSeckill = goodsSeckillService.getOne(new LambdaQueryWrapper<GoodsSeckill>().eq(GoodsSeckill::getSeckillActivityInfoId, one.getId())); + } + //没有秒杀活动或者添加的普通商品则使用秒杀活动价格 + if(null == goodsSeckill ){ + return null; + } + //秒杀活动价格 + price.setCash(goodsSeckill.getSellingPrice()); + //计算对应积分 + price.setPoint(getPoint(price.getCash())); + price.setStartTime(one.getStartTime()); + price.setEndTime(one.getEndTime()); + price.setPurchaseLimit(one.getMaxNum()); + return price; + } + + /** + * 获取现金对应积分 + */ + 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); + } + + } } -- Gitblit v1.7.1