feat(gift): 修复赠礼事务并补充租户隔离
Some checks failed
Build and Push Backend / docker (push) Failing after 6s

This commit is contained in:
irving
2025-10-26 01:30:02 -04:00
parent 15aea7d779
commit 0356834b88
14 changed files with 490 additions and 123 deletions

View File

@@ -0,0 +1,44 @@
package com.starry.admin.modules.common.controller;
import cn.hutool.core.util.StrUtil;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.common.oss.service.IOssFileService;
import com.starry.admin.utils.SecurityUtils;
import com.starry.common.result.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.io.IOException;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
/**
* 后台通用能力接口
*/
@Api(tags = "后台通用接口", description = "提供后台常用的公共能力,例如文件上传")
@RestController
@RequestMapping("/common")
public class CommonController {
@Resource
private IOssFileService ossFileService;
@ApiOperation(value = "上传文件", notes = "上传文件到 OSS 并返回访问地址")
@PostMapping("/upload")
public R upload(@ApiParam(value = "上传文件", required = true) @RequestParam("file") MultipartFile file)
throws IOException {
if (file == null || file.isEmpty()) {
throw new CustomException("上传文件不能为空");
}
String tenantId = SecurityUtils.getTenantId();
if (StrUtil.isBlank(tenantId)) {
throw new CustomException("租户信息缺失,请重新登录");
}
String fileUrl = ossFileService.upload(file.getInputStream(), tenantId, file.getOriginalFilename());
return R.ok(fileUrl);
}
}

View File

@@ -2,6 +2,8 @@ package com.starry.admin.modules.custom.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import com.starry.admin.modules.custom.module.entity.PlayCustomGiftInfoEntity;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
/**
* 顾客和礼物关系Mapper接口
@@ -11,4 +13,20 @@ import com.starry.admin.modules.custom.module.entity.PlayCustomGiftInfoEntity;
*/
public interface PlayCustomGiftInfoMapper extends MPJBaseMapper<PlayCustomGiftInfoEntity> {
/**
* 原子递增顾客礼物数量
*
* @param customId 顾客ID
* @param giftId 礼物ID
* @param tenantId 租户ID
* @param delta 增量
* @return 受影响行数
*/
@Update("UPDATE play_custom_gift_info "
+ "SET giff_number = giff_number + #{delta} "
+ "WHERE custom_id = #{customId} AND giff_id = #{giftId} "
+ "AND (tenant_id = #{tenantId} OR tenant_id IS NULL)")
int incrementGiftCount(@Param("customId") String customId, @Param("giftId") String giftId,
@Param("tenantId") String tenantId, @Param("delta") long delta);
}

View File

@@ -31,7 +31,7 @@ public interface IPlayCustomGiftInfoService extends IService<PlayCustomGiftInfoE
* 顾客IF
* @return 顾客已点亮礼物列表
*/
List<PlayCustomGiftInfoEntity> selectBtyCustomId(String customId);
List<PlayCustomGiftInfoEntity> selectByCustomId(String customId, String tenantId);
/**
* 查询顾客和礼物关系
@@ -69,6 +69,16 @@ public interface IPlayCustomGiftInfoService extends IService<PlayCustomGiftInfoE
*/
boolean update(PlayCustomGiftInfoEntity playCustomGiftInfo);
/**
* 原子递增顾客礼物数量,无记录时按增量初始化
*
* @param customId 顾客ID
* @param giftId 礼物ID
* @param tenantId 租户ID
* @param delta 增量
*/
void incrementGiftCount(String customId, String giftId, String tenantId, long delta);
/**
* 批量删除顾客和礼物关系
*

View File

@@ -12,6 +12,7 @@ import com.starry.common.utils.IdUtils;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
/**
@@ -43,9 +44,12 @@ public class PlayCustomGiftInfoServiceImpl extends ServiceImpl<PlayCustomGiftInf
* @return 店员活动礼物列表
*/
@Override
public List<PlayCustomGiftInfoEntity> selectBtyCustomId(String customId) {
public List<PlayCustomGiftInfoEntity> selectByCustomId(String customId, String tenantId) {
LambdaQueryWrapper<PlayCustomGiftInfoEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(PlayCustomGiftInfoEntity::getCustomId, customId);
if (StrUtil.isNotBlank(tenantId)) {
lambdaQueryWrapper.eq(PlayCustomGiftInfoEntity::getTenantId, tenantId);
}
return this.baseMapper.selectList(lambdaQueryWrapper);
}
@@ -101,6 +105,39 @@ public class PlayCustomGiftInfoServiceImpl extends ServiceImpl<PlayCustomGiftInf
return updateById(playCustomGiftInfo);
}
/**
* 原子递增顾客礼物数量,无记录时按增量初始化
*
* @param customId 顾客ID
* @param giftId 礼物ID
* @param tenantId 租户ID
* @param delta 增量
*/
@Override
public void incrementGiftCount(String customId, String giftId, String tenantId, long delta) {
if (delta <= 0) {
throw new IllegalArgumentException("delta must be positive");
}
int updated = playCustomGiftInfoMapper.incrementGiftCount(customId, giftId, tenantId, delta);
if (updated == 0) {
PlayCustomGiftInfoEntity entity = new PlayCustomGiftInfoEntity();
entity.setId(IdUtils.getUuid());
entity.setCustomId(customId);
entity.setTenantId(tenantId);
entity.setGiffId(giftId);
entity.setGiffNumber(delta);
boolean inserted = false;
try {
inserted = this.save(entity);
} catch (DuplicateKeyException ex) {
// ignore and retry update below
}
if (!inserted) {
playCustomGiftInfoMapper.incrementGiftCount(customId, giftId, tenantId, delta);
}
}
}
/**
* 批量删除顾客和礼物关系
*

View File

@@ -2,6 +2,8 @@ package com.starry.admin.modules.shop.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.starry.admin.modules.shop.module.entity.PlayClerkGiftInfoEntity;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
/**
* 店员和礼物关系Mapper接口
@@ -11,4 +13,20 @@ import com.starry.admin.modules.shop.module.entity.PlayClerkGiftInfoEntity;
*/
public interface PlayClerkGiftInfoMapper extends BaseMapper<PlayClerkGiftInfoEntity> {
/**
* 原子递增店员礼物数量
*
* @param clerkId 店员ID
* @param giftId 礼物ID
* @param tenantId 租户ID
* @param delta 增量
* @return 受影响行数
*/
@Update("UPDATE play_clerk_gift_info "
+ "SET giff_number = giff_number + #{delta} "
+ "WHERE clerk_id = #{clerkId} AND giff_id = #{giftId} "
+ "AND (tenant_id = #{tenantId} OR tenant_id IS NULL)")
int incrementGiftCount(@Param("clerkId") String clerkId, @Param("giftId") String giftId,
@Param("tenantId") String tenantId, @Param("delta") long delta);
}

View File

@@ -32,7 +32,7 @@ public interface IPlayClerkGiftInfoService extends IService<PlayClerkGiftInfoEnt
* @return 店员活动礼物列表
*/
List<PlayClerkGiftInfoEntity> selectBtyClerkId(String clerkId);
List<PlayClerkGiftInfoEntity> selectBtyClerkId(String clerkId, String tenantId);
/**
* 查询店员和礼物关系
@@ -70,6 +70,16 @@ public interface IPlayClerkGiftInfoService extends IService<PlayClerkGiftInfoEnt
*/
boolean update(PlayClerkGiftInfoEntity playClerkGiftInfo);
/**
* 原子递增店员礼物数量,无记录时按增量初始化
*
* @param clerkId 店员ID
* @param giftId 礼物ID
* @param tenantId 租户ID
* @param delta 增量
*/
void incrementGiftCount(String clerkId, String giftId, String tenantId, long delta);
/**
* 批量删除店员和礼物关系
*

View File

@@ -42,7 +42,7 @@ public interface IPlayGiftInfoService extends IService<PlayGiftInfoEntity> {
* @author admin
* @since 2024/4/25 15:56
**/
List<PlayClerkGiftReturnVo> clerkListByAll(String clerkId, String obtained);
List<PlayClerkGiftReturnVo> clerkListByAll(String tenantId, String clerkId, String obtained);
/**
* 店员查询所有礼物
@@ -57,7 +57,7 @@ public interface IPlayGiftInfoService extends IService<PlayGiftInfoEntity> {
* @author admin
* @since 2024/4/25 15:56
**/
List<PlayClerkGiftReturnVo> customListByAll(String customId, String obtained);
List<PlayClerkGiftReturnVo> customListByAll(String tenantId, String customId, String obtained);
/**
* 查询礼物列表

View File

@@ -12,6 +12,7 @@ import com.starry.common.utils.IdUtils;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
/**
@@ -43,9 +44,12 @@ public class PlayClerkGiftInfoServiceImpl extends ServiceImpl<PlayClerkGiftInfoM
* @return 店员活动礼物列表
*/
@Override
public List<PlayClerkGiftInfoEntity> selectBtyClerkId(String clerkId) {
public List<PlayClerkGiftInfoEntity> selectBtyClerkId(String clerkId, String tenantId) {
LambdaQueryWrapper<PlayClerkGiftInfoEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(PlayClerkGiftInfoEntity::getClerkId, clerkId);
if (StrUtil.isNotBlank(tenantId)) {
lambdaQueryWrapper.eq(PlayClerkGiftInfoEntity::getTenantId, tenantId);
}
return this.baseMapper.selectList(lambdaQueryWrapper);
}
@@ -101,6 +105,39 @@ public class PlayClerkGiftInfoServiceImpl extends ServiceImpl<PlayClerkGiftInfoM
return updateById(playClerkGiftInfo);
}
/**
* 原子递增店员礼物数量,无记录时按增量初始化
*
* @param clerkId 店员ID
* @param giftId 礼物ID
* @param tenantId 租户ID
* @param delta 增量
*/
@Override
public void incrementGiftCount(String clerkId, String giftId, String tenantId, long delta) {
if (delta <= 0) {
throw new IllegalArgumentException("delta must be positive");
}
int updated = playClerkGiftInfoMapper.incrementGiftCount(clerkId, giftId, tenantId, delta);
if (updated == 0) {
PlayClerkGiftInfoEntity entity = new PlayClerkGiftInfoEntity();
entity.setId(IdUtils.getUuid());
entity.setClerkId(clerkId);
entity.setTenantId(tenantId);
entity.setGiffId(giftId);
entity.setGiffNumber(delta);
boolean inserted = false;
try {
inserted = this.save(entity);
} catch (DuplicateKeyException ex) {
// ignore and retry update below
}
if (!inserted) {
playClerkGiftInfoMapper.incrementGiftCount(clerkId, giftId, tenantId, delta);
}
}
}
/**
* 批量删除店员和礼物关系
*

View File

@@ -8,17 +8,19 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.modules.custom.module.entity.PlayCustomGiftInfoEntity;
import com.starry.admin.modules.custom.service.impl.PlayCustomGiftInfoServiceImpl;
import com.starry.admin.modules.custom.service.IPlayCustomGiftInfoService;
import com.starry.admin.modules.shop.mapper.PlayGiftInfoMapper;
import com.starry.admin.modules.shop.module.entity.PlayClerkGiftInfoEntity;
import com.starry.admin.modules.shop.module.entity.PlayGiftInfoEntity;
import com.starry.admin.modules.shop.service.IPlayClerkGiftInfoService;
import com.starry.admin.modules.shop.service.IPlayGiftInfoService;
import com.starry.admin.modules.weichat.entity.gift.PlayClerkGiftReturnVo;
import com.starry.common.utils.IdUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
@@ -36,10 +38,10 @@ public class PlayGiftInfoServiceImpl extends ServiceImpl<PlayGiftInfoMapper, Pla
private PlayGiftInfoMapper playGiftInfoMapper;
@Resource
private PlayClerkGiftInfoServiceImpl clerkGiftInfoService;
private IPlayClerkGiftInfoService clerkGiftInfoService;
@Resource
private PlayCustomGiftInfoServiceImpl customGiftInfoService;
private IPlayCustomGiftInfoService customGiftInfoService;
/**
* 查询礼物
@@ -58,27 +60,24 @@ public class PlayGiftInfoServiceImpl extends ServiceImpl<PlayGiftInfoMapper, Pla
}
@Override
public List<PlayClerkGiftReturnVo> customListByAll(String customId, String obtained) {
public List<PlayClerkGiftReturnVo> customListByAll(String tenantId, String customId, String obtained) {
if ("0".equals(obtained)) {
// 查询所有礼物,然后减去已获得礼物
MPJLambdaWrapper<PlayGiftInfoEntity> lambdaWrapper = new MPJLambdaWrapper<>();
lambdaWrapper.selectAll(PlayGiftInfoEntity.class);
List<PlayClerkGiftReturnVo> list = this.baseMapper.selectJoinList(PlayClerkGiftReturnVo.class,
lambdaWrapper);
List<PlayCustomGiftInfoEntity> giftInfoEntities = customGiftInfoService.selectBtyCustomId(customId);
// 使用迭代器安全地移除元素
Iterator<PlayClerkGiftReturnVo> iterator = list.iterator();
while (iterator.hasNext()) {
PlayClerkGiftReturnVo item = iterator.next();
for (PlayCustomGiftInfoEntity giftInfoEntity : giftInfoEntities) {
if (giftInfoEntity.getGiffId().equals(item.getId())) {
iterator.remove();
break;
}
}
LambdaQueryWrapper<PlayGiftInfoEntity> giftWrapper = new LambdaQueryWrapper<>();
giftWrapper.eq(PlayGiftInfoEntity::getState, "0");
giftWrapper.eq(PlayGiftInfoEntity::getHistory, "0");
giftWrapper.eq(StrUtil.isNotBlank(tenantId), PlayGiftInfoEntity::getTenantId, tenantId);
List<PlayGiftInfoEntity> activeGifts = this.baseMapper.selectList(giftWrapper);
}
return list;
List<PlayCustomGiftInfoEntity> obtainedRecords =
customGiftInfoService.selectByCustomId(customId, tenantId);
Set<String> obtainedGiftIds = obtainedRecords.stream()
.map(PlayCustomGiftInfoEntity::getGiffId)
.collect(Collectors.toSet());
return activeGifts.stream()
.filter(gift -> !obtainedGiftIds.contains(gift.getId()))
.map(this::toGiftReturnVoWithZeroCount)
.collect(Collectors.toList());
}
if ("1".equals(obtained)) {
MPJLambdaWrapper<PlayGiftInfoEntity> lambdaWrapper = new MPJLambdaWrapper<>();
@@ -88,6 +87,10 @@ public class PlayGiftInfoServiceImpl extends ServiceImpl<PlayGiftInfoMapper, Pla
lambdaWrapper.innerJoin(PlayCustomGiftInfoEntity.class, PlayCustomGiftInfoEntity::getGiffId,
PlayGiftInfoEntity::getId);
lambdaWrapper.eq(PlayCustomGiftInfoEntity::getCustomId, customId);
lambdaWrapper.eq(PlayGiftInfoEntity::getState, "0");
lambdaWrapper.eq(PlayGiftInfoEntity::getHistory, "0");
lambdaWrapper.eq(StrUtil.isNotBlank(tenantId), PlayGiftInfoEntity::getTenantId, tenantId);
lambdaWrapper.eq(StrUtil.isNotBlank(tenantId), PlayCustomGiftInfoEntity::getTenantId, tenantId);
return this.baseMapper.selectJoinList(PlayClerkGiftReturnVo.class, lambdaWrapper);
}
return new ArrayList<>();
@@ -95,27 +98,24 @@ public class PlayGiftInfoServiceImpl extends ServiceImpl<PlayGiftInfoMapper, Pla
}
@Override
public List<PlayClerkGiftReturnVo> clerkListByAll(String clerkId, String obtained) {
public List<PlayClerkGiftReturnVo> clerkListByAll(String tenantId, String clerkId, String obtained) {
if ("0".equals(obtained)) {
// 查询所有礼物,然后减去已获得礼物
MPJLambdaWrapper<PlayGiftInfoEntity> lambdaWrapper = new MPJLambdaWrapper<>();
lambdaWrapper.selectAll(PlayGiftInfoEntity.class);
List<PlayClerkGiftReturnVo> list = this.baseMapper.selectJoinList(PlayClerkGiftReturnVo.class,
lambdaWrapper);
List<PlayClerkGiftInfoEntity> clerkGiftInfoEntities = clerkGiftInfoService.selectBtyClerkId(clerkId);
// 使用迭代器安全地移除元素
Iterator<PlayClerkGiftReturnVo> iterator = list.iterator();
while (iterator.hasNext()) {
PlayClerkGiftReturnVo item = iterator.next();
for (PlayClerkGiftInfoEntity clerkGiftInfoEntity : clerkGiftInfoEntities) {
if (clerkGiftInfoEntity.getGiffId().equals(item.getId())) {
iterator.remove();
break;
}
}
LambdaQueryWrapper<PlayGiftInfoEntity> giftWrapper = new LambdaQueryWrapper<>();
giftWrapper.eq(PlayGiftInfoEntity::getState, "0");
giftWrapper.eq(PlayGiftInfoEntity::getHistory, "0");
giftWrapper.eq(StrUtil.isNotBlank(tenantId), PlayGiftInfoEntity::getTenantId, tenantId);
List<PlayGiftInfoEntity> activeGifts = this.baseMapper.selectList(giftWrapper);
}
return list;
List<PlayClerkGiftInfoEntity> obtainedRecords =
clerkGiftInfoService.selectBtyClerkId(clerkId, tenantId);
Set<String> obtainedGiftIds = obtainedRecords.stream()
.map(PlayClerkGiftInfoEntity::getGiffId)
.collect(Collectors.toSet());
return activeGifts.stream()
.filter(gift -> !obtainedGiftIds.contains(gift.getId()))
.map(this::toGiftReturnVoWithZeroCount)
.collect(Collectors.toList());
}
if ("1".equals(obtained)) {
MPJLambdaWrapper<PlayGiftInfoEntity> lambdaWrapper = new MPJLambdaWrapper<>();
@@ -125,6 +125,10 @@ public class PlayGiftInfoServiceImpl extends ServiceImpl<PlayGiftInfoMapper, Pla
lambdaWrapper.innerJoin(PlayClerkGiftInfoEntity.class, PlayClerkGiftInfoEntity::getGiffId,
PlayGiftInfoEntity::getId);
lambdaWrapper.eq(PlayClerkGiftInfoEntity::getClerkId, clerkId);
lambdaWrapper.eq(PlayGiftInfoEntity::getState, "0");
lambdaWrapper.eq(PlayGiftInfoEntity::getHistory, "0");
lambdaWrapper.eq(StrUtil.isNotBlank(tenantId), PlayGiftInfoEntity::getTenantId, tenantId);
lambdaWrapper.eq(StrUtil.isNotBlank(tenantId), PlayClerkGiftInfoEntity::getTenantId, tenantId);
return this.baseMapper.selectJoinList(PlayClerkGiftReturnVo.class, lambdaWrapper);
}
return new ArrayList<>();
@@ -132,7 +136,24 @@ public class PlayGiftInfoServiceImpl extends ServiceImpl<PlayGiftInfoMapper, Pla
@Override
public List<PlayGiftInfoEntity> listByAll() {
return this.baseMapper.selectList(new LambdaQueryWrapper<>());
LambdaQueryWrapper<PlayGiftInfoEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(PlayGiftInfoEntity::getState, "0");
wrapper.eq(PlayGiftInfoEntity::getHistory, "0");
wrapper.orderByAsc(PlayGiftInfoEntity::getListingTime);
return this.baseMapper.selectList(wrapper);
}
private PlayClerkGiftReturnVo toGiftReturnVoWithZeroCount(PlayGiftInfoEntity gift) {
PlayClerkGiftReturnVo vo = new PlayClerkGiftReturnVo();
vo.setId(gift.getId());
vo.setName(gift.getName());
vo.setType(gift.getType());
vo.setUrl(gift.getUrl());
vo.setPrice(gift.getPrice());
vo.setUnit(gift.getUnit());
vo.setState(gift.getState());
vo.setGiffNumber(0L);
return vo;
}
/**

View File

@@ -1,5 +1,6 @@
package com.starry.admin.modules.weichat.controller;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.starry.admin.common.aspect.ClerkUserLogin;
@@ -51,6 +52,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
@@ -416,9 +418,13 @@ public class WxClerkController {
throw new CustomException("用户不存在");
}
// 获取所有礼物列表
List<PlayGiftInfoEntity> giftInfoEntities = giftInfoService.listByAll();
List<PlayGiftInfoEntity> giftInfoEntities = giftInfoService.listByAll().stream()
.filter(gift -> StrUtil.isBlank(entity.getTenantId())
|| entity.getTenantId().equals(gift.getTenantId()))
.collect(Collectors.toList());
// 获取已点亮礼物
List<PlayClerkGiftReturnVo> clerkListByAll = giftInfoService.clerkListByAll(id, "1");
List<PlayClerkGiftReturnVo> clerkListByAll =
giftInfoService.clerkListByAll(entity.getTenantId(), id, "1");
// 组装数据
List<PlayClerkGiftReturnVo> result = new ArrayList<>();
for (PlayGiftInfoEntity giftInfoEntity : giftInfoEntities) {

View File

@@ -12,7 +12,6 @@ import com.starry.admin.common.task.OverdueOrderHandlerTask;
import com.starry.admin.modules.clerk.module.entity.PlayClerkUserInfoEntity;
import com.starry.admin.modules.clerk.service.IPlayClerkCommodityService;
import com.starry.admin.modules.clerk.service.IPlayClerkUserInfoService;
import com.starry.admin.modules.custom.module.entity.PlayCustomGiftInfoEntity;
import com.starry.admin.modules.custom.module.entity.PlayCustomLeaveMsgEntity;
import com.starry.admin.modules.custom.module.entity.PlayCustomUserInfoEntity;
import com.starry.admin.modules.custom.service.IPlayCustomFollowInfoService;
@@ -31,10 +30,8 @@ import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity;
import com.starry.admin.modules.order.service.IPlayOrderComplaintInfoService;
import com.starry.admin.modules.order.service.IPlayOrderEvaluateInfoService;
import com.starry.admin.modules.order.service.IPlayOrderInfoService;
import com.starry.admin.modules.shop.module.entity.PlayClerkGiftInfoEntity;
import com.starry.admin.modules.shop.module.entity.PlayCouponDetailsEntity;
import com.starry.admin.modules.shop.module.entity.PlayCouponInfoEntity;
import com.starry.admin.modules.shop.module.entity.PlayGiftInfoEntity;
import com.starry.admin.modules.shop.module.vo.PlayCommodityInfoVo;
import com.starry.admin.modules.shop.service.*;
import com.starry.admin.modules.weichat.entity.*;
@@ -49,6 +46,7 @@ import com.starry.admin.modules.weichat.entity.order.PlayOrderInfoCommodityAdd;
import com.starry.admin.modules.weichat.entity.user.PlayCustomUserReturnDetailVo;
import com.starry.admin.modules.weichat.service.WxCustomMpService;
import com.starry.admin.modules.weichat.service.WxCustomUserService;
import com.starry.admin.modules.weichat.service.WxGiftOrderService;
import com.starry.admin.utils.MoneyUtils;
import com.starry.admin.utils.SecurityUtils;
import com.starry.common.result.R;
@@ -128,6 +126,9 @@ public class WxCustomController {
@Resource
private WxCustomMpService wxCustomMpService;
@Resource
private WxGiftOrderService wxGiftOrderService;
@Resource
OverdueOrderHandlerTask overdueOrderHandlerTask;
@@ -271,73 +272,8 @@ public class WxCustomController {
@CustomUserLogin
@PostMapping("/order/gift")
public R giftToOdder(@ApiParam(value = "礼物信息", required = true) @Validated @RequestBody PlayOrderInfoGiftAdd vo) {
String userId = ThreadLocalRequestDetail.getCustomUserInfo().getId();
PlayGiftInfoEntity giftInfo = giftInfoService.selectPlayGiftInfoById(vo.getGiftId());
PlayCustomUserInfoEntity customUserInfo = customUserInfoService.selectById(userId);
BigDecimal money = giftInfo.getPrice().multiply(new BigDecimal(vo.getGiftQuantity()));
if (money.compareTo(customUserInfo.getAccountBalance()) > 0) {
throw new ServiceException("余额不足", 998);
}
String orderId = IdUtils.getUuid();
// 记录订单信息
OrderCreationRequest orderRequest = OrderCreationRequest.builder()
.orderId(orderId)
.orderNo(playOrderInfoService.getOrderNo())
.orderStatus(OrderConstant.OrderStatus.COMPLETED)
.orderType(OrderConstant.OrderType.NORMAL)
.placeType(OrderConstant.PlaceType.REWARD)
.rewardType(RewardType.GIFT)
.isFirstOrder(true)
.commodityInfo(CommodityInfo.builder()
.commodityId(giftInfo.getId())
.commodityType(OrderConstant.CommodityType.GIFT)
.commodityPrice(giftInfo.getPrice())
.serviceDuration("")
.commodityName(giftInfo.getName())
.commodityNumber(String.valueOf(vo.getGiftQuantity()))
.build())
.paymentInfo(PaymentInfo.builder()
.orderMoney(money)
.finalAmount(money)
.discountAmount(BigDecimal.ZERO)
.couponIds(new ArrayList<>())
.build())
.purchaserBy(userId)
.acceptBy(vo.getClerkId())
.weiChatCode(vo.getWeiChatCode())
.remark(vo.getRemark())
.build();
playOrderInfoService.createOrderInfo(orderRequest);
// 顾客减少余额
customUserInfoService.updateAccountBalanceById(customUserInfo.getId(), customUserInfo.getAccountBalance(), customUserInfo.getAccountBalance().subtract(money), "1", "赠送礼物", money, BigDecimal.ZERO, orderId);
// 陪聊增加余额
// 修改顾客和礼物消息
PlayCustomGiftInfoEntity customGiftInfoEntity = playCustomGiftInfoService.selectByGiftIdAndCustomId(vo.getGiftId(), userId);
if (customGiftInfoEntity == null) {
customGiftInfoEntity = new PlayCustomGiftInfoEntity();
customGiftInfoEntity.setGiffId(vo.getGiftId());
customGiftInfoEntity.setCustomId(userId);
customGiftInfoEntity.setGiffNumber(1L);
playCustomGiftInfoService.save(customGiftInfoEntity);
} else {
customGiftInfoEntity.setGiffNumber(customGiftInfoEntity.getGiffNumber() + vo.getGiftQuantity());
playCustomGiftInfoService.update(customGiftInfoEntity);
}
// 修改陪玩和礼物数据
PlayClerkGiftInfoEntity clerkGiftInfoEntity = playClerkGiftInfoService.selectByGiftIdAndClerkId(vo.getGiftId(), vo.getClerkId());
if (clerkGiftInfoEntity == null) {
clerkGiftInfoEntity = new PlayClerkGiftInfoEntity();
clerkGiftInfoEntity.setGiffId(vo.getGiftId());
clerkGiftInfoEntity.setClerkId(vo.getClerkId());
clerkGiftInfoEntity.setGiffNumber(0L);
playClerkGiftInfoService.create(clerkGiftInfoEntity);
} else {
customGiftInfoEntity.setGiffNumber(customGiftInfoEntity.getGiffNumber() + vo.getGiftQuantity());
playClerkGiftInfoService.update(clerkGiftInfoEntity);
}
return R.ok("成功");
String orderId = wxGiftOrderService.createGiftOrder(vo);
return R.ok().message("成功").data(orderId);
}
/**

View File

@@ -5,6 +5,8 @@ import com.starry.admin.common.aspect.ClerkUserLogin;
import com.starry.admin.common.aspect.CustomUserLogin;
import com.starry.admin.common.conf.ThreadLocalRequestDetail;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.modules.clerk.module.entity.PlayClerkUserInfoEntity;
import com.starry.admin.modules.custom.module.entity.PlayCustomUserInfoEntity;
import com.starry.admin.modules.shop.service.IPlayGiftInfoService;
import com.starry.admin.modules.weichat.entity.PlayGiftInfoDto;
import com.starry.admin.modules.weichat.entity.gift.PlayClerkGiftReturnVo;
@@ -68,8 +70,9 @@ public class WxGiftController {
if (!"0".equals(obtained) && !"1".equals(obtained)) {
throw new CustomException("obtained参数异常");
}
PlayClerkUserInfoEntity clerk = ThreadLocalRequestDetail.getClerkUserInfo();
List<PlayClerkGiftReturnVo> list = giftInfoService
.clerkListByAll(ThreadLocalRequestDetail.getClerkUserInfo().getId(), obtained);
.clerkListByAll(clerk.getTenantId(), clerk.getId(), obtained);
return R.ok(list);
}
@@ -94,8 +97,9 @@ public class WxGiftController {
if (!"0".equals(obtained) && !"1".equals(obtained)) {
throw new CustomException("obtained参数异常");
}
PlayCustomUserInfoEntity custom = ThreadLocalRequestDetail.getCustomUserInfo();
List<PlayClerkGiftReturnVo> list = giftInfoService
.customListByAll(ThreadLocalRequestDetail.getCustomUserInfo().getId(), obtained);
.customListByAll(custom.getTenantId(), custom.getId(), obtained);
return R.ok(list);
}

View File

@@ -0,0 +1,131 @@
package com.starry.admin.modules.weichat.service;
import com.starry.admin.common.conf.ThreadLocalRequestDetail;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.common.exception.ServiceException;
import com.starry.admin.modules.custom.module.entity.PlayCustomUserInfoEntity;
import com.starry.admin.modules.custom.service.IPlayCustomGiftInfoService;
import com.starry.admin.modules.custom.service.IPlayCustomUserInfoService;
import com.starry.admin.modules.order.module.constant.OrderConstant;
import com.starry.admin.modules.order.module.constant.OrderConstant.RewardType;
import com.starry.admin.modules.order.module.dto.CommodityInfo;
import com.starry.admin.modules.order.module.dto.OrderCreationRequest;
import com.starry.admin.modules.order.module.dto.PaymentInfo;
import com.starry.admin.modules.order.service.IPlayOrderInfoService;
import com.starry.admin.modules.shop.module.entity.PlayGiftInfoEntity;
import com.starry.admin.modules.shop.service.IPlayClerkGiftInfoService;
import com.starry.admin.modules.shop.service.IPlayGiftInfoService;
import com.starry.admin.modules.weichat.entity.PlayOrderInfoGiftAdd;
import com.starry.common.utils.IdUtils;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Objects;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 微信礼物订单服务,负责处理顾客赠送礼物的事务逻辑。
*/
@Service
public class WxGiftOrderService {
@Resource
private IPlayGiftInfoService giftInfoService;
@Resource
private IPlayOrderInfoService playOrderInfoService;
@Resource
private IPlayCustomUserInfoService customUserInfoService;
@Resource
private IPlayCustomGiftInfoService playCustomGiftInfoService;
@Resource
private IPlayClerkGiftInfoService playClerkGiftInfoService;
/**
* 创建礼物订单并处理余额与礼物计数。
*
* @param request 礼物下单请求
* @return 生成的订单ID
*/
@Transactional(rollbackFor = Exception.class)
public String createGiftOrder(PlayOrderInfoGiftAdd request) {
PlayCustomUserInfoEntity sessionUser = ThreadLocalRequestDetail.getCustomUserInfo();
if (sessionUser == null || sessionUser.getId() == null) {
throw new CustomException("用户未登录");
}
PlayCustomUserInfoEntity customUserInfo = customUserInfoService.selectById(sessionUser.getId());
if (customUserInfo == null) {
throw new CustomException("用户不存在");
}
PlayGiftInfoEntity giftInfo = giftInfoService.selectPlayGiftInfoById(request.getGiftId());
BigDecimal unitPrice = Objects.requireNonNull(giftInfo.getPrice(), "礼物价格未配置");
int giftQuantity = request.getGiftQuantity();
if (giftQuantity <= 0) {
throw new CustomException("礼物数量必须大于0");
}
BigDecimal totalAmount = unitPrice.multiply(BigDecimal.valueOf(giftQuantity));
if (totalAmount.compareTo(BigDecimal.ZERO) <= 0) {
throw new CustomException("礼物金额必须大于0");
}
BigDecimal currentBalance = customUserInfo.getAccountBalance() == null
? BigDecimal.ZERO : customUserInfo.getAccountBalance();
if (totalAmount.compareTo(currentBalance) > 0) {
throw new ServiceException("余额不足", 998);
}
String orderId = IdUtils.getUuid();
OrderCreationRequest orderRequest = buildOrderCreationRequest(orderId, request, sessionUser.getId(),
giftInfo, totalAmount);
playOrderInfoService.createOrderInfo(orderRequest);
BigDecimal newBalance = currentBalance.subtract(totalAmount);
customUserInfoService.updateAccountBalanceById(customUserInfo.getId(), currentBalance, newBalance, "1",
"赠送礼物", totalAmount, BigDecimal.ZERO, orderId);
String tenantId = customUserInfo.getTenantId();
long delta = giftQuantity;
playCustomGiftInfoService.incrementGiftCount(customUserInfo.getId(), request.getGiftId(), tenantId, delta);
playClerkGiftInfoService.incrementGiftCount(request.getClerkId(), request.getGiftId(), tenantId, delta);
return orderId;
}
private OrderCreationRequest buildOrderCreationRequest(String orderId, PlayOrderInfoGiftAdd request,
String purchaserId, PlayGiftInfoEntity giftInfo,
BigDecimal totalAmount) {
return OrderCreationRequest.builder()
.orderId(orderId)
.orderNo(playOrderInfoService.getOrderNo())
.orderStatus(OrderConstant.OrderStatus.COMPLETED)
.orderType(OrderConstant.OrderType.NORMAL)
.placeType(OrderConstant.PlaceType.REWARD)
.rewardType(RewardType.GIFT)
.isFirstOrder(true)
.commodityInfo(CommodityInfo.builder()
.commodityId(giftInfo.getId())
.commodityType(OrderConstant.CommodityType.GIFT)
.commodityPrice(giftInfo.getPrice())
.serviceDuration("")
.commodityName(giftInfo.getName())
.commodityNumber(String.valueOf(request.getGiftQuantity()))
.build())
.paymentInfo(PaymentInfo.builder()
.orderMoney(totalAmount)
.finalAmount(totalAmount)
.discountAmount(BigDecimal.ZERO)
.couponIds(Collections.emptyList())
.build())
.purchaserBy(purchaserId)
.acceptBy(request.getClerkId())
.weiChatCode(request.getWeiChatCode())
.remark(request.getRemark())
.build();
}
}