feat:购物车商品级退款

This commit is contained in:
dzc committed 2025-08-27 20:15:08 +08:00
1 parent 5647b14b9d
commit d153ce27c1
8 files changed
+176 -9

No files matched your search

@@ -20,7 +20,6 @@ import java.time.LocalDateTime;
@Schema(description = "购物车退款表")
public class HardAfterSaleCarEntity extends Model<HardAfterSaleCarEntity> {
/**
* 编号
*/
@@ -23,6 +23,7 @@ import org.springframework.http.HttpHeaders;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@@ -14,9 +14,11 @@ import com.bsd.pjcloud.hard.api.constant.HardTypeEnum;
import com.bsd.pjcloud.hard.api.constant.order.HardOrderTypeEnum;
import com.bsd.pjcloud.hard.api.dto.app.HardCarSaveOrUpdateDto;
import com.bsd.pjcloud.hard.api.dto.order.HardCarDto;
import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleCarEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardCarEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity;
import com.bsd.pjcloud.hard.api.vo.order.HardCarVo;
import com.bsd.pjcloud.hard.service.HardAfterSaleCarService;
import com.bsd.pjcloud.hard.service.HardCarService;
import com.bsd.pjcloud.hard.service.HardOrderService;
import org.springframework.security.access.prepost.PreAuthorize;
@@ -46,6 +48,7 @@ public class HardCarController {
private final HardCarService hardCarService;
private final HardOrderService hardOrderService;
private final HardAfterSaleCarService hardAfterSaleCarService;
/* ************************************* start app start ************************************* */
@GetMapping("/app/mch-detail")
@@ -88,9 +91,16 @@ public class HardCarController {
return R.ok(hardCarService.pageJoin(page, dto));
}
@GetMapping("/refund-car")
@Operation(summary = "查询退款购物车根据订单id")
public R<List<HardAfterSaleCarEntity>> refundCar(@RequestParam Long orderId) {
return R.ok(hardAfterSaleCarService.getByOrderId(orderId));
}
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('hard_hardCar_view')")
public R getHardCarPage(@ParameterObject Page page, @ParameterObject HardCarEntity hardCar) {
LambdaQueryWrapper<HardCarEntity> wrapper = Wrappers.lambdaQuery();
return R.ok(hardCarService.page(page, wrapper));
@@ -3,9 +3,13 @@ package com.bsd.pjcloud.hard.mapper.order;
import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleCarEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface HardAfterSaleCarMapper extends PjcloudBaseMapper<HardAfterSaleCarEntity> {
List<HardAfterSaleCarEntity> getByCarPrentId(@Param("carParentId") Long carParentId);
}
@@ -2,7 +2,16 @@ package com.bsd.pjcloud.hard.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleCarEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity;
import java.util.List;
public interface HardAfterSaleCarService extends IService<HardAfterSaleCarEntity> {
List<HardAfterSaleCarEntity> getByOrderId(Long orderId);
List<HardAfterSaleCarEntity> getByCarPrentId(Long carParentId);
void create(List<HardAfterSaleCarEntity> carList, HardOrderEntity order, HardAfterSaleEntity afterSale);
}
@@ -1,15 +1,53 @@
package com.bsd.pjcloud.hard.service.impl.order;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleCarEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity;
import com.bsd.pjcloud.hard.mapper.order.HardAfterSaleCarMapper;
import com.bsd.pjcloud.hard.mapper.order.HardOrderMapper;
import com.bsd.pjcloud.hard.service.HardAfterSaleCarService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.util.List;
/**
* 购物车退款表
*/
@Validated
@Slf4j
@RequiredArgsConstructor
@Service
public class HardAfterSaleCarServiceImpl extends ServiceImpl<HardAfterSaleCarMapper, HardAfterSaleCarEntity> implements HardAfterSaleCarService {
private final HardOrderMapper hardOrderMapper;
@Override
public List<HardAfterSaleCarEntity> getByOrderId(Long orderId) {
HardOrderEntity order = hardOrderMapper.selectById(orderId);
if (ObjectUtil.isEmpty(order)) return null;
return getByCarPrentId(order.getParentCarId());
}
@Override
public List<HardAfterSaleCarEntity> getByCarPrentId(Long carParentId) {
return baseMapper.getByCarPrentId(carParentId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(List<HardAfterSaleCarEntity> carList, HardOrderEntity order, HardAfterSaleEntity afterSale) {
if (ObjectUtil.isEmpty(carList)) return;
carList = carList.stream().map(item -> {
item.setParentCarId(order.getParentCarId());
item.setRefundId(afterSale.getId());
return item;
}).toList();
saveBatch(carList);
}
}
@@ -36,21 +36,21 @@ import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleLogEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity;
import com.bsd.pjcloud.hard.api.utils.HardUtil;
import com.bsd.pjcloud.hard.api.vo.order.HardAfterSaleVo;
import com.bsd.pjcloud.hard.api.vo.order.HardCarVo;
import com.bsd.pjcloud.hard.api.vo.order.HardOrderVo;
import com.bsd.pjcloud.hard.api.vo.wechat.WechantRefunCallbackVo;
import com.bsd.pjcloud.hard.api.vo.wechat.WechatRefundVo;
import com.bsd.pjcloud.hard.mapper.order.HardAfterSaleLogMapper;
import com.bsd.pjcloud.hard.mapper.order.HardAfterSaleMapper;
import com.bsd.pjcloud.hard.mapper.order.HardCarMapper;
import com.bsd.pjcloud.hard.mapper.order.HardOrderMapper;
import com.bsd.pjcloud.hard.service.AlipayService;
import com.bsd.pjcloud.hard.service.HardAfterSaleService;
import com.bsd.pjcloud.hard.service.HardOrderService;
import com.bsd.pjcloud.hard.service.WechatPayService;
import com.bsd.pjcloud.hard.service.*;
import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeRefundDto;
import com.bsd.pjcloud.wallet.api.feign.RemoteWalletRechargeService;
import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -81,6 +81,8 @@ public class HardAfterSaleServiceImpl extends ServiceImpl<HardAfterSaleMapper, H
private final RemoteUserService userService;
private final RemoteDeptService deptService;
private final RemoteWalletRechargeService walletRechargeService;
private final HardCarService hardCarService;
private final HardAfterSaleCarService hardAfterSaleCarService;
@Override
@@ -413,10 +415,31 @@ public class HardAfterSaleServiceImpl extends ServiceImpl<HardAfterSaleMapper, H
return orderVo;
}
public boolean validateOrderCarCanRefund(HardOrderEntity order, List<HardAfterSaleCarEntity> carList) {
if (ObjectUtil.isEmpty(carList)) throw new RuntimeException("售后商品列表不能为空");
public void validateOrderCarCanRefund(HardOrderEntity order, List<HardAfterSaleCarEntity> refundCarList) {
if (ObjectUtil.isEmpty(refundCarList)) throw new RuntimeException("售后商品列表不能为空");
// 查询订单购物车
return false;
List<HardCarVo> orderCarList = hardCarService.getByOrderId(order.getId());
if (ObjectUtil.isEmpty(orderCarList)) throw new RuntimeException("订单购物车不存在");
// 查询已退款商品
List<HardAfterSaleCarEntity> refundSuccessCarList = hardAfterSaleCarService.getByCarPrentId(order.getParentCarId());
for (HardAfterSaleCarEntity refundCar : refundCarList) {
HardCarVo orderCar = orderCarList.stream().filter(v -> ObjectUtil.equal(v.getId(), refundCar.getId())).findFirst().orElse(null);
if (orderCar == null) throw new RuntimeException("退款商品<" + refundCar.getProductName() + ">不存在");
int refundCount = 0;
if (ObjectUtil.isNotEmpty(refundCar.getProductCount())) {
refundCount = refundCar.getProductCount();
}
// 已经退货成功的商品列表
if (ObjectUtil.isNotEmpty(refundSuccessCarList)) {
HardAfterSaleCarEntity refundSuccessCar = refundSuccessCarList.stream().filter(v -> ObjectUtil.equal(v.getId(), refundCar.getId())).findFirst().orElse(null);
if (ObjectUtil.isNotEmpty(refundSuccessCar)) {
refundCount += refundSuccessCar.getProductCount();
}
}
if (orderCar.getProductCount() < refundCount) {
throw new RuntimeException("退款商品<" + refundCar.getProductName() + ">数量超出");
}
}
}
private HardAfterSaleEntity validateAfterSaleAuditable(Long id) {
@@ -504,7 +527,9 @@ public class HardAfterSaleServiceImpl extends ServiceImpl<HardAfterSaleMapper, H
* 后台强化退款
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean adminReinforceRefund(HardAdminRefundReinforceDto dto, PjcloudUser user) {
if (ObjectUtil.isEmpty(dto.getCarList())) throw new RuntimeException("退款商品列表不能为空");
// 校验订单是否可以退款
HardOrderVo order = validateOrderCanRefund(dto.getOrderId());
// 校验订单购物车是否支持退款
@@ -512,7 +537,33 @@ public class HardAfterSaleServiceImpl extends ServiceImpl<HardAfterSaleMapper, H
// 添加售后订单
HardAfterSaleEntity saveObj = BeanUtils.toBean(dto, HardAfterSaleEntity.class);
String refundCode = "hard_" + order.getId();
return null;
saveObj.setType(HardSaleTypeEnum.AFTER_SALE.getType());
saveObj.setStatus(HardSaleStatusEnum.COMPLETE.getStatus());
saveObj.setNo(refundCode);
saveObj.setOrderId(order.getId());
saveObj.setRefundPrice(order.getPayPrice());
saveObj.setUserId(order.getUserId());
saveObj.setAuditUserId(user.getId());
saveObj.setAuditTime(LocalDateTime.now());
saveObj.setAuditReason("后台退款");
baseMapper.insert(saveObj);
// 添加退款购物车
hardAfterSaleCarService.create(dto.getCarList(), order, saveObj);
// 添加售后进度
HardAfterSaleLogEntity saveLogObj = HardAfterSaleLogEntity.builder()
.afterSaleId(saveObj.getId())
.userId(order.getUserId())
.operateType(HardAfterSaleOperateTypeEnum.ADMIN_REFUND.getType())
.beforeStatus(order.getOrderStatus())
.afterStatus(HardSaleStatusEnum.COMPLETE.getStatus())
.content(HardSaleStatusEnum.COMPLETE.getContent())
.build();
hardAfterSaleLogMapper.insert(saveLogObj);
// 执行退款
getSelf().refund(saveObj.getId());
// 退库存
// hardOrderService.fastenerInventory(order, YesNoEnum.NO);
return true;
}
/**
@@ -2,5 +2,60 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bsd.pjcloud.hard.mapper.order.HardAfterSaleCarMapper">
<sql id="selectA">
select a.id,
a.refund_id,
a.parent_car_id,
a.product_id,
a.product_name,
a.product_pic,
a.product_price,
a.product_count,
a.product_weight,
a.total_price,
a.create_by,
a.create_time,
a.update_by,
a.update_time,
a.del_flag,
a.tenant_id
</sql>
<sql id="whereA">
a.del_flag = '0'
<if test="id != null">
and a.id = #{id}
</if>
<if test="refundId != null">
and a.refund_id = #{refundId}
</if>
<if test="parentCarId != null">
and a.parent_car_id = #{parentCarId}
</if>
</sql>
<select id="getByCarPrentId" resultType="com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleCarEntity">
select a.id,
a.refund_id,
a.parent_car_id,
a.product_id,
a.product_name,
a.product_pic,
sum(a.product_price) as productPrice,
sum(a.product_count) as productCount,
sum(a.product_weight) as productWeight,
sum(a.total_price) as totalPrice,
a.create_by,
a.create_time,
a.update_by,
a.update_time,
a.del_flag,
a.tenant_id
from hard_after_sale_car a
<where>
a.del_flag = '0'
and a.parent_car_id = #{carParentId}
</where>
group by a.product_id
</select>
</mapper>