fix: 退款修改

This commit is contained in:
张松
2024-11-28 13:57:21 +08:00
parent c1dbd68616
commit 04473738b7
27 changed files with 1044 additions and 29 deletions

View File

@@ -16,6 +16,7 @@ import com.chaozhanggui.system.cashierservice.entity.TbOrderDetail;
import com.chaozhanggui.system.cashierservice.entity.TbOrderInfo;
import com.chaozhanggui.system.cashierservice.entity.TbShopInfo;
import com.chaozhanggui.system.cashierservice.entity.dto.ReturnGroupOrderDto;
import com.chaozhanggui.system.cashierservice.entity.dto.ReturnOrderDTO;
import com.chaozhanggui.system.cashierservice.entity.dto.VipPayDTO;
import com.chaozhanggui.system.cashierservice.model.PaymentReq;
import com.chaozhanggui.system.cashierservice.service.PayService;
@@ -34,10 +35,7 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
@CrossOrigin(origins = "*")
@RestController
@@ -247,7 +245,20 @@ public class PayController {
@RequestBody List<TbOrderDetail> list,
@RequestParam("pwd") String pwd,
@RequestParam(defaultValue = "true") boolean isOnline) {
return payService.returnOrder(list, token, pwd, isOnline);
ReturnOrderDTO returnOrderDTO = new ReturnOrderDTO();
returnOrderDTO.setOrderId(list.get(0).getOrderId());
returnOrderDTO.setNote(list.get(0).getRemark());
returnOrderDTO.setPwd(pwd);
ArrayList<ReturnOrderDTO.OrderDetail> orderDetails = new ArrayList<>();
list.forEach(item -> {
ReturnOrderDTO.OrderDetail orderDetail = new ReturnOrderDTO.OrderDetail();
orderDetail.setId(item.getId());
orderDetail.setNum(item.getNum());
orderDetails.add(orderDetail);
});
returnOrderDTO.setOrderDetails(orderDetails);
returnOrderDTO.setIsOnline(isOnline);
return Result.success(CodeEnum.SUCCESS, payService.returnOrder(returnOrderDTO));
}

View File

@@ -2,6 +2,7 @@ package com.chaozhanggui.system.cashierservice.dao;
import com.chaozhanggui.system.cashierservice.entity.TbActivateInRecord;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import org.springframework.data.domain.Pageable;
import java.util.List;
@@ -64,5 +65,10 @@ public interface TbActivateInRecordMapper {
*/
int deleteById(Integer id);
@Update("update tb_activate_in_record" +
" set over_num = #{overNum}" +
" where id = #{id}")
int updateOverNum(@Param("id") Integer id, @Param("overNum") Integer overNum);
}

View File

@@ -2,6 +2,7 @@ package com.chaozhanggui.system.cashierservice.dao;
import com.chaozhanggui.system.cashierservice.entity.TbActivateOutRecord;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import org.springframework.data.domain.Pageable;
import java.util.List;
@@ -64,5 +65,10 @@ public interface TbActivateOutRecordMapper {
*/
int deleteById(Integer id);
@Update("update tb_activate_out_record" +
" set ref_num = ref_num + #{refNum}" +
" where id = #{id}")
int updateRefNum(@Param("id") Integer id, @Param("refNum") Integer refNum);
}

View File

@@ -0,0 +1,72 @@
package com.chaozhanggui.system.cashierservice.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
/**
* 会员积分
*
* @author Tankaikai tankaikai@aliyun.com
* @since 2.0 2024-10-25
*/
@Data
@EqualsAndHashCode(callSuper=false)
@TableName("tb_shop_user")
public class TbMemberPoints {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 店铺id
*/
private Long shopId;
/**
* 会员id
*/
@TableField(value = "id", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
private Long memberId;
/**
* 会员名称
*/
@TableField("name")
private String memberName;
/**
* 会员头像
*/
@TableField("head_img")
private String avatarUrl;
/**
* 手机号码
*/
@TableField("telephone")
private String mobile;
/**
* 账户积分
*/
@TableField("account_points")
private Integer accountPoints;
/**
* 最近一次积分变动时间
*/
@TableField("last_points_change_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date lastPointsChangeTime;
/**
* 最近一次浮动积分
*/
@TableField("last_float_points")
private Integer lastFloatPoints;
/**
* 是否会员 1-是 0-否
*/
@TableField("is_vip")
private Integer vip;
}

View File

@@ -0,0 +1,70 @@
package com.chaozhanggui.system.cashierservice.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
/**
* 会员积分变动记录
*
* @author Tankaikai tankaikai@aliyun.com
* @since 2.0 2024-10-25
*/
@Data
@EqualsAndHashCode(callSuper=false)
@TableName("tb_member_points_log")
public class TbMemberPointsLog {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 店铺id
*/
private Long shopId;
/**
* 会员id
*/
private Long memberId;
/**
* 会员名称
*/
private String memberName;
/**
* 会员头像
*/
private String avatarUrl;
/**
* 摘要信息(如:兑换某个商品/消费多少钱/充值多少钱/新会员赠送积分等)
*/
private String content;
/**
* 订单编号
*/
private String orderNo;
/**
* 手机号码
*/
private String mobile;
/**
* 浮动类型 add-累加 subtract-扣减
*/
private String floatType;
/**
* 浮动积分(非0正负数)
*/
private Integer floatPoints;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
}

View File

@@ -53,5 +53,10 @@ public class TbOrderDetail implements Serializable {
private Integer isMember;
private Integer isTemporary;
private Integer isThirdCoupon;
private Integer userCouponId;
private String useCouponInfo;
private BigDecimal canReturnAmount;
private BigDecimal returnAmount;
}

View File

@@ -117,6 +117,11 @@ public class TbOrderInfo implements Serializable {
private static final long serialVersionUID = 1L;
private int isPostpaid;
private String couponInfoList;
private BigDecimal fullCouponDiscountAmount;
private BigDecimal pointsDiscountAmount;
private String refundRemark;
private Integer pointsNum;
public TbOrderInfo(){
super();
@@ -181,4 +186,6 @@ public class TbOrderInfo implements Serializable {
this.payType=payType;
this.tableName=tableName;
}
}

View File

@@ -0,0 +1,14 @@
package com.chaozhanggui.system.cashierservice.entity.dto;
import com.chaozhanggui.system.cashierservice.entity.TbActivateOutRecord;
import lombok.Data;
import java.util.Collection;
import java.util.List;
@Data
public class OrderInfoCouponInfoDTO {
private List<TbActivateOutRecord> outRecordList;
private Collection<OrderInfoUserCouponVo> fullReductionCoupon;
private Collection<OrderInfoUserCouponVo> productCoupon;
}

View File

@@ -0,0 +1,11 @@
package com.chaozhanggui.system.cashierservice.entity.dto;
import com.chaozhanggui.system.cashierservice.entity.vo.TbUserCouponVo;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class OrderInfoUserCouponVo extends TbUserCouponVo {
private int returnNum = 0;
}

View File

@@ -0,0 +1,32 @@
package com.chaozhanggui.system.cashierservice.entity.dto;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
@Data
public class ReturnOrderDTO {
@Data
public static class OrderDetail{
@NotNull
private Integer id;
@NotNull
@Min(1)
private BigDecimal num;
}
@NotNull
private Integer orderId;
@NotEmpty
private String note;
// @NotEmpty
private String pwd;
@Valid
private List<OrderDetail> orderDetails;
private Boolean isOnline;
}

View File

@@ -0,0 +1,43 @@
package com.chaozhanggui.system.cashierservice.entity.vo;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class TbUserCouponVo {
private Integer id;
private BigDecimal fullAmount;
private BigDecimal discountAmount;
private Integer couponId;
private Integer proId;
// 商品名称
private String productName;
private String productCover;
//优惠券名称
private String name;
//优惠券类型 1 满减 2 商品券
private Integer type;
//数量
private Integer num;
//到期时间
private Date endTime;
private Long expireTime;
private String useRestrictions;
private boolean isUse = false;
//当前使用数量
private BigDecimal currentUseNum;
private Integer finalUseNum;
private BigDecimal finalDiscountAmount = new BigDecimal(0);
public void setEndTime(Date endTime) {
this.endTime = endTime;
if(endTime!=null){
expireTime=endTime.getTime();
}
}
}

View File

@@ -0,0 +1,7 @@
package com.chaozhanggui.system.cashierservice.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chaozhanggui.system.cashierservice.entity.TbProductStockDetail;
public interface MpProductStockDetailMapper extends BaseMapper<TbProductStockDetail> {
}

View File

@@ -0,0 +1,16 @@
package com.chaozhanggui.system.cashierservice.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chaozhanggui.system.cashierservice.entity.TbMemberPointsLog;
import org.apache.ibatis.annotations.Mapper;
/**
* 会员积分变动记录
*
* @author Tankaikai tankaikai@aliyun.com
* @since 2.0 2024-10-25
*/
@Mapper
public interface TbMemberPointsLogMapper extends BaseMapper<TbMemberPointsLog> {
}

View File

@@ -0,0 +1,16 @@
package com.chaozhanggui.system.cashierservice.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chaozhanggui.system.cashierservice.entity.TbMemberPoints;
import org.apache.ibatis.annotations.Mapper;
/**
* 会员积分
*
* @author Tankaikai tankaikai@aliyun.com
* @since 2.0 2024-10-25
*/
@Mapper
public interface TbMemberPointsMapper extends BaseMapper<TbMemberPoints> {
}

View File

@@ -10,4 +10,7 @@ import java.math.BigDecimal;
public interface MpShopUserMapper extends BaseMapper<TbShopUser> {
@Update("update tb_shop_user set amount=amount-#{orderAmount}, consume_amount=consume_amount+#{orderAmount} where id=#{vipUserId} and amount-#{orderAmount} >= 0")
long decrBalance(@Param("vipUserId") Integer vipUserId, @Param("orderAmount") BigDecimal orderAmount);
@Update("update tb_shop_user set amount=amount+#{returnAmount}, consume_amount=consume_amount-#{returnAmount}, updated_at=#{current} where id=#{userId}")
void incrBalance(@Param("userId") Integer userId, @Param("shopId") Integer shopId, @Param("returnAmount") BigDecimal returnAmount, @Param("current") long current);
}

View File

@@ -70,4 +70,12 @@ public interface RabbitConstants {
// 排号打印
String QUEUE_PRINT_CALL_TABLE = "queue.print.call.table";
String ROUTING_KEY_CALL_TABLE = "routing.call.table";
// 会员余额记录
String EXCHANGE_BALANCE = "balance_put";
String ROUTING_KEY_BALANCE = "balance_routingkey_put";
// 耗材
String EXCHANGE_CONS = "cons_collect_put";
String ROUTING_KEY_CONS = "cons_collect_routingkey_put";
}

View File

@@ -49,5 +49,15 @@ public interface MpOrderDetailService extends IService<TbOrderDetail> {
boolean updateFieldByCartId(SFunction<TbOrderDetail, ?> field, Object val, List<Integer> cartIds);
/**
* 根据orderId和id修改detail状态
* @param oldOrderStatusEnums 原始订单状态
* @param orderStatusEnums 状态
* @param orderId 订单id
* @param orderDetails detailIds
* @return 影响数量
*/
boolean updateStatusByOrderIdAndIds(TableConstant.OrderInfo.Status oldOrderStatusEnums, TableConstant.OrderInfo.Status orderStatusEnums, Integer orderId, List<Integer> orderDetails);
}

View File

@@ -27,5 +27,9 @@ public interface MpOrderInfoService extends IService<TbOrderInfo> {
boolean incrAmount(Integer orderId, BigDecimal subtract);
/**
* 储值卡退款
*/
void depositReturn(Integer userId, Integer shopId, BigDecimal returnAmount);
}

View File

@@ -44,6 +44,7 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
@@ -1051,6 +1052,7 @@ public class OrderService {
orderDetail.setPackAmount(BigDecimal.ZERO);
}
}
updateOrderDetailCanReturn(orderDetails, orderInfo);
mpOrderDetailService.saveOrUpdateBatch(orderDetails);
// 删除已经移除购物车的商品
@@ -1111,6 +1113,27 @@ public class OrderService {
return Result.success(CodeEnum.SUCCESS, orderInfo);
}
private void updateOrderDetailCanReturn(List<TbOrderDetail> orderDetailList, TbOrderInfo orderInfo) {
orderDetailList = orderDetailList.stream().filter(item -> TableConstant.OrderInfo.Status.UNPAID.equalsVals(item.getStatus())).collect(Collectors.toList());
BigDecimal totalAmount = BigDecimal.ZERO;
BigDecimal lastAmount = BigDecimal.ZERO;
BigDecimal lastReturnAmount = BigDecimal.ZERO;
BigDecimal orderAmount = orderInfo.getOrderAmount();
for (TbOrderDetail orderDetail : orderDetailList) {
totalAmount = totalAmount.add(orderDetail.getPriceAmount());
}
for (TbOrderDetail item : orderDetailList) {
if (StrUtil.isNotBlank(orderInfo.getCouponInfoList()) || orderInfo.getPointsNum() != null) {
BigDecimal canReturnAmount = item.getPriceAmount().divide(totalAmount.subtract(lastAmount), 10, RoundingMode.HALF_DOWN)
.multiply(orderAmount.subtract(lastReturnAmount)).setScale(2, RoundingMode.HALF_DOWN);
lastReturnAmount = canReturnAmount;
lastAmount = item.getPriceAmount();
item.setCanReturnAmount(canReturnAmount);
} else {
item.setCanReturnAmount(item.getPriceAmount());
}
}
}
/**
* 获取当前台桌当前下单次数

View File

@@ -1,5 +1,6 @@
package com.chaozhanggui.system.cashierservice.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
@@ -14,17 +15,18 @@ import com.chaozhanggui.system.cashierservice.bean.TableStateEnum;
import com.chaozhanggui.system.cashierservice.bean.constant.TableConstant;
import com.chaozhanggui.system.cashierservice.dao.*;
import com.chaozhanggui.system.cashierservice.entity.*;
import com.chaozhanggui.system.cashierservice.entity.dto.OrderInfoCouponInfoDTO;
import com.chaozhanggui.system.cashierservice.entity.dto.ReturnGroupOrderDto;
import com.chaozhanggui.system.cashierservice.entity.dto.ReturnOrderDTO;
import com.chaozhanggui.system.cashierservice.entity.po.OrderDetailPo;
import com.chaozhanggui.system.cashierservice.exception.MsgException;
import com.chaozhanggui.system.cashierservice.exception.NotPrintException;
import com.chaozhanggui.system.cashierservice.mapper.MpProductStockDetailMapper;
import com.chaozhanggui.system.cashierservice.mapper.MpShopUnitMapper;
import com.chaozhanggui.system.cashierservice.model.ReturnOrderReq;
import com.chaozhanggui.system.cashierservice.model.ScanPayReq;
import com.chaozhanggui.system.cashierservice.model.TradeQueryReq;
import com.chaozhanggui.system.cashierservice.mybatis.MPOrderDetailMapper;
import com.chaozhanggui.system.cashierservice.mybatis.MpShopTableMapper;
import com.chaozhanggui.system.cashierservice.mybatis.MpShopUserFlowMapper;
import com.chaozhanggui.system.cashierservice.mybatis.MpShopUserMapper;
import com.chaozhanggui.system.cashierservice.mybatis.*;
import com.chaozhanggui.system.cashierservice.rabbit.RabbitProducer;
import com.chaozhanggui.system.cashierservice.sign.CodeEnum;
import com.chaozhanggui.system.cashierservice.sign.Result;
@@ -55,6 +57,7 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static com.chaozhanggui.system.cashierservice.sign.CodeEnum.ACCOUNTEIXST;
import static com.chaozhanggui.system.cashierservice.sign.CodeEnum.SUCCESS;
@@ -137,13 +140,29 @@ public class PayService {
private PlatformTransactionManager transactionManager;
private final MpCashierCartService mpCashierCartService;
private final TbShopCouponService shopCouponService;
private final MpOrderDetailService mpOrderDetailService;
private final MpShopUnitMapper mpShopUnitMapper;
private final MpProductStockDetailMapper mpProductStockDetailMapper;
private final MpOrderInfoService mpOrderInfoService;
private final TbMemberPointsService memberPointsService;
private final Utils utils;
@Autowired
private MPOrderInfoMapper mPOrderInfoMapper;
public PayService(RedisTemplate<String, Object> redisTemplate, MpCashierCartService mpCashierCartService, Utils utils) {
public PayService(RedisTemplate<String, Object> redisTemplate, MpCashierCartService mpCashierCartService, TbShopCouponService shopCouponService, MpOrderDetailService mpOrderDetailService, MpShopUnitMapper mpShopUnitMapper, MpProductStockDetailMapper mpProductStockDetailMapper, MpOrderInfoService mpOrderInfoService, Utils utils) {
this.redisTemplate = redisTemplate;
this.mpCashierCartService = mpCashierCartService;
this.shopCouponService = shopCouponService;
this.mpOrderDetailService = mpOrderDetailService;
this.mpShopUnitMapper = mpShopUnitMapper;
this.mpProductStockDetailMapper = mpProductStockDetailMapper;
this.mpOrderInfoService = mpOrderInfoService;
this.utils = utils;
memberPointsService = null;
}
public static void main(String[] args) {
@@ -151,7 +170,7 @@ public class PayService {
}
public Result queryPayType(String shopId) {
return Result.success(CodeEnum.SUCCESS, tbShopPayTypeMapper.selectByShopId(shopId));
return Result.success(SUCCESS, tbShopPayTypeMapper.selectByShopId(shopId));
}
private void clearTableInfoCache(TbOrderInfo orderInfo) {
@@ -355,7 +374,7 @@ public class PayService {
redisUtil.del(tableCartKey);
clearTableInfoCache(orderInfo);
return Result.success(CodeEnum.SUCCESS, object.getJSONObject("data"));
return Result.success(SUCCESS, object.getJSONObject("data"));
} else {
String status = ObjectUtil.isNotEmpty(object.getJSONObject("data")) ? object.getJSONObject("data").getString("status") : null;
if (ObjectUtil.isNotNull(status) && "7".equals(status)) {
@@ -558,7 +577,7 @@ public class PayService {
}
}
return Result.success(CodeEnum.SUCCESS, orderInfo);
return Result.success(SUCCESS, orderInfo);
}
@@ -719,7 +738,7 @@ public class PayService {
redisUtil.del(tableCartKey);
clearTableInfoCache(orderInfo);
return Result.success(CodeEnum.SUCCESS);
return Result.success(SUCCESS);
}
@Transactional(rollbackFor = Exception.class)
@@ -853,7 +872,7 @@ public class PayService {
producer.balance(baObj.toString());
clearTableInfoCache(orderInfo);
return Result.success(CodeEnum.SUCCESS);
return Result.success(SUCCESS);
}
public Result vipPay(Integer orderId, String token, Integer vipUserId, BigDecimal payAmount, BigDecimal discountAmount) {
@@ -963,7 +982,7 @@ public class PayService {
redisUtil.del(tableCartKey);
clearTableInfoCache(orderInfo);
return Result.success(CodeEnum.SUCCESS);
return Result.success(SUCCESS);
}
@@ -1058,7 +1077,7 @@ public class PayService {
redisUtil.del(tableCartKey);
clearTableInfoCache(orderInfo);
return Result.success(CodeEnum.SUCCESS);
return Result.success(SUCCESS);
}
@Transactional(rollbackFor = Exception.class)
@@ -1146,7 +1165,368 @@ public class PayService {
clearTableInfoCache(orderInfo);
return Result.success(CodeEnum.SUCCESS);
return Result.success(SUCCESS);
}
private HashMap<String, Object> updateReturnOrderInfo(ReturnOrderDTO returnOrderDTO, TbOrderInfo oldOrderInfo, boolean isOnline) {
String couponInfoList = oldOrderInfo.getCouponInfoList();
OrderInfoCouponInfoDTO couponInfoDTO = null;
if (StrUtil.isNotBlank(couponInfoList)) {
couponInfoDTO = JSONObject.parseObject(couponInfoList, OrderInfoCouponInfoDTO.class);
}
ArrayList<Integer> detailIds = new ArrayList<>();
HashMap<String, BigDecimal> returnNumMap = new HashMap<>();
returnOrderDTO.getOrderDetails().forEach(item -> {
detailIds.add(item.getId());
returnNumMap.put(item.getId().toString(), item.getNum());
});
List<TbOrderDetail> detailList = mPOrderDetailMapper.selectList(new LambdaQueryWrapper<TbOrderDetail>()
// .eq(TbOrderDetail::getShopId, returnOrderDTO.getShopId())
.eq(TbOrderDetail::getStatus, "closed")
.eq(TbOrderDetail::getOrderId, returnOrderDTO.getOrderId())
.in(TbOrderDetail::getId, detailIds)
.orderByDesc(TbOrderDetail::getUserCouponId));
if (detailList.size() != returnOrderDTO.getOrderDetails().size()) {
throw new MsgException("订单明细数量不一致");
}
HashMap<String, Object> data = new HashMap<>();
BigDecimal returnAmount = BigDecimal.ZERO;
BigDecimal packAMount = BigDecimal.ZERO;
BigDecimal saleAmount = BigDecimal.ZERO;
ArrayList<TbOrderDetail> remainOrderDetailList = new ArrayList<>();
boolean hasNormalReturn = false;
for (TbOrderDetail orderDetail : detailList) {
// 原始金额
BigDecimal originalAmount = orderDetail.getPriceAmount();
BigDecimal originalPackAmount = orderDetail.getPackAmount();
// 退款数量
BigDecimal returnNum = returnNumMap.get(orderDetail.getId().toString());
// 剩余数量
BigDecimal remainNum = orderDetail.getNum().subtract(returnNum);
if (remainNum.compareTo(BigDecimal.ZERO) < 0) {
throw new MsgException(StrUtil.format("{}最多可退数量为: {}", orderDetail.getProductName(), orderDetail.getNum()));
}
// 将未退款的剩余订单详情重新生成记录
BigDecimal packFee = orderDetail.getPackAmount().divide(orderDetail.getNum(), RoundingMode.HALF_UP);
BigDecimal returnPackFee = packFee.multiply(returnNum);
BigDecimal currentDetailAMount = BigDecimal.ZERO;
// 优惠券抵扣商品直接退券
if (StrUtil.isNotBlank(orderDetail.getUseCouponInfo())) {
data.put("isCouponDiscount", true);
TbActivateOutRecord outRecord = JSONObject.parseObject(orderDetail.getUseCouponInfo(), TbActivateOutRecord.class);
outRecord.setRefNum(returnNum.intValue());
shopCouponService.refund(CollUtil.newArrayList(outRecord));
currentDetailAMount = returnNum.multiply(orderDetail.getPrice())
.add(returnPackFee);
// 移除使用的券
couponInfoDTO.getProductCoupon().forEach(item -> {
if (Objects.equals(item.getId(), outRecord.getGiveId())) {
item.setReturnNum(item.getReturnNum() + outRecord.getRefNum());
}
});
// 使用了满减或积分,获取普通付款商品计算退款比例,退部分现金
} else if (oldOrderInfo.getFullCouponDiscountAmount().compareTo(BigDecimal.ZERO) > 0 || oldOrderInfo.getPointsDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
hasNormalReturn = true;
// 计算当前商品占比
returnAmount = calcDetailReturnAmount(orderDetail, returnNum);
currentDetailAMount = orderDetail.getPriceAmount().divide(orderDetail.getNum(), 8, RoundingMode.HALF_UP)
.multiply(returnNum).setScale(2, RoundingMode.HALF_DOWN);
if (oldOrderInfo.getRefundAmount() == null) {
oldOrderInfo.setRefundAmount(BigDecimal.ZERO);
}
// if (ratio.compareTo(BigDecimal.ONE) == 0) {
// returnAmount = oldOrderInfo.getPayAmount().subtract(oldOrderInfo.getRefundAmount());
// }else {
// returnAmount = returnAmount.add(oldOrderInfo.getPayAmount().subtract(oldOrderInfo.getRefundAmount()).multiply(ratio));
// }
saleAmount = saleAmount.add(orderDetail.getPrice());
packAMount = packAMount.add(orderDetail.getPackAmount()
.divide(orderDetail.getNum(), 8, RoundingMode.HALF_UP)
.multiply(returnNum)).setScale(2, RoundingMode.HALF_UP);
} else {
hasNormalReturn = true;
saleAmount = saleAmount.add(orderDetail.getPrice());
if (remainNum.compareTo(BigDecimal.ZERO) <= 0) {
returnAmount = orderDetail.getPriceAmount();
packAMount = orderDetail.getPackAmount();
} else {
currentDetailAMount = orderDetail.getPriceAmount()
.divide(orderDetail.getNum(), 8, RoundingMode.HALF_UP)
.multiply(returnNum).setScale(2, RoundingMode.HALF_UP);
returnAmount = returnAmount.add(currentDetailAMount);
packAMount = packAMount.add(orderDetail.getPackAmount()
.divide(orderDetail.getNum(), 8, RoundingMode.HALF_UP)
.multiply(returnNum)).setScale(2, RoundingMode.HALF_UP);
}
}
returnAmount = returnAmount.setScale(2, RoundingMode.HALF_DOWN);
if (remainNum.compareTo(BigDecimal.ZERO) > 0) {
// 单个打包费
TbOrderDetail remainOrderDetail = new TbOrderDetail();
BeanUtil.copyProperties(remainOrderDetail, orderDetail);
remainOrderDetail.setNum(remainNum);
remainOrderDetail.setPriceAmount(originalAmount.subtract(returnAmount));
remainOrderDetail.setPackAmount(originalPackAmount.subtract(returnPackFee));
remainOrderDetail.setReturnNum(BigDecimal.ZERO);
remainOrderDetail.setId(null);
remainOrderDetail.setCanReturnAmount(remainOrderDetail.getCanReturnAmount().subtract(returnAmount));
remainOrderDetailList.add(remainOrderDetail);
orderDetail.setCanReturnAmount(returnAmount);
}
orderDetail.setNum(returnNum);
orderDetail.setPriceAmount(currentDetailAMount);
orderDetail.setPackAmount(returnPackFee);
orderDetail.setReturnNum(returnNum);
orderDetail.setReturnAmount(returnAmount);
// orderDetail.setStatus(isOnline ? "refunding" : "refund");
orderDetail.setStatus("refund");
}
if (returnAmount.compareTo(BigDecimal.ZERO) < 0) {
throw new MsgException("退款金额为负数有误");
}
if (hasNormalReturn && returnAmount.compareTo(new BigDecimal("0")) <= 0 && oldOrderInfo.getPayAmount().compareTo(BigDecimal.ZERO) != 0) {
throw new MsgException("退款金额必须大于0");
}
oldOrderInfo.setCouponInfoList(JSONObject.toJSONString(couponInfoDTO));
// 保存剩余未退款的订单详情
if (!remainOrderDetailList.isEmpty()) {
mpOrderDetailService.saveBatch(remainOrderDetailList);
}
// TbOrderInfo returnOrder = mpOrderInfoService.selectReturnOrderByOrderId(returnOrderDTO.getOrderId());
TbOrderInfo returnOrder = new TbOrderInfo();
String orderNo = generateOrderNumber();
cn.hutool.core.bean.BeanUtil.copyProperties(oldOrderInfo, returnOrder);
returnOrder.setId(null);
returnOrder.setOrderNo(orderNo);
returnOrder.setRefundAmount(returnAmount);
returnOrder.setOrderType("return");
returnOrder.setStatus(isOnline ? "refunding" : "refund");
returnOrder.setUpdatedAt(null);
returnOrder.setSystemTime(DateUtil.date().getTime());
returnOrder.setCreatedAt(DateUtil.date().getTime());
returnOrder.setPayOrderNo(null);
returnOrder.setSource(oldOrderInfo.getId());
returnOrder.setRefundRemark(returnOrderDTO.getNote());
returnOrder.setOrderAmount(returnAmount);
returnOrder.setAmount(returnAmount);
returnOrder.setSettlementAmount(returnAmount);
returnOrder.setPayAmount(returnAmount);
mPOrderInfoMapper.insert(returnOrder);
updateStockAndRecord(detailList);
mpOrderDetailService.updateBatchById(detailList);
data.put("returnOrder", returnOrder);
data.put("returnAmount", returnAmount);
data.put("hasNormalReturn", hasNormalReturn);
return data;
}
private void updateStockAndRecord(List<TbOrderDetail> orderDetailList) {
// 更新商品库存
for (TbOrderDetail detail : orderDetailList) {
TbProductSku productSku = productSkuMapper.selectByPrimaryKey(detail.getProductSkuId());
TbProduct product = productMapper.selectByPrimaryKey(detail.getProductId());
TbProductStockDetail tbProductStockDetail = new TbProductStockDetail();
tbProductStockDetail.setCreatedAt(System.currentTimeMillis());
tbProductStockDetail.setUpdatedAt(System.currentTimeMillis());
tbProductStockDetail.setShopId(detail.getShopId().toString());
tbProductStockDetail.setSourcePath("NORMAL");
tbProductStockDetail.setType("退单");
tbProductStockDetail.setSubType((byte) 1);
tbProductStockDetail.setRemark("退单: " + detail.getOrderId());
tbProductStockDetail.setOrderId(String.valueOf(detail.getOrderId()));
if (ObjectUtil.isNotEmpty(product)) {
TbShopUnit shopUnit = mpShopUnitMapper.selectById(product.getUnitId());
tbProductStockDetail.setProductName(product.getName());
tbProductStockDetail.setIsStock(Integer.valueOf(product.getIsStock()));
tbProductStockDetail.setStockSnap(product.getSelectSpec());
tbProductStockDetail.setUnitName(shopUnit.getName());
tbProductStockDetail.setProductId(product.getId().toString());
productMapper.incrStock(String.valueOf(product.getId()), detail.getNum());
tbProductStockDetail.setLeftNumber(product.getStockNumber());
tbProductStockDetail.setStockNumber(detail.getNum().doubleValue());
productSkuMapper.decrRealSalesNumber(productSku.getId(), detail.getNum().intValue());
}
mpProductStockDetailMapper.insert(tbProductStockDetail);
}
}
private void returnCoupon(TbOrderInfo orderInfo, boolean resetInfo) {
// 返还优惠券
if (StrUtil.isNotBlank(orderInfo.getCouponInfoList())) {
OrderInfoCouponInfoDTO couponInfoDTO = JSONObject.parseObject(orderInfo.getCouponInfoList(), OrderInfoCouponInfoDTO.class);
ArrayList<Integer> couponIds = new ArrayList<>();
couponInfoDTO.getProductCoupon().forEach(item -> {
if (item.getReturnNum() >= item.getFinalUseNum()) {
couponIds.add(item.getId());
}
});
// 券返还
if (!couponInfoDTO.getOutRecordList().isEmpty()) {
ArrayList<TbActivateOutRecord> finalReturnList = new ArrayList<>();
couponInfoDTO.getOutRecordList().forEach(item -> {
if (!couponIds.contains(item.getGiveId())) {
item.setRefNum(item.getUseNum());
finalReturnList.add(item);
}
});
shopCouponService.refund(finalReturnList);
if (resetInfo) {
couponInfoDTO.setOutRecordList(new ArrayList<>());
orderInfo.setCouponInfoList(JSONObject.toJSONString(couponInfoDTO));
}
}
}
}
@Transactional
public Object returnOrder(ReturnOrderDTO returnOrderDTO) {
TbOrderInfo orderInfo = mPOrderInfoMapper.selectOne(new LambdaQueryWrapper<TbOrderInfo>()
.eq(TbOrderInfo::getId, returnOrderDTO.getOrderId())
.in(TbOrderInfo::getStatus, TableConstant.OrderInfo.Status.REFUND.getValue(),
TableConstant.OrderInfo.Status.CLOSED.getValue())
// .eq(TbOrderInfo::getStatus, "closed")
);
if (orderInfo == null) {
throw new MsgException("订单不处于可退款状态");
}
TbShopInfo shopInfo = tbShopInfoMapper.selectByPrimaryKey(Integer.valueOf(orderInfo.getShopId()));
if (shopInfo == null) {
throw new MsgException("店铺信息不存在");
}
if ("1".equals(shopInfo.getIsReturn())) {
// TODO 密码校验
}
String payType = orderInfo.getPayType();
HashMap<String, Object> returnInfoData = updateReturnOrderInfo(returnOrderDTO, orderInfo, "scanCode".equals(payType) || "wx_lite".equals(payType));
TbOrderInfo returnOrderInfo = (TbOrderInfo) returnInfoData.get("returnOrder");
BigDecimal returnAmount = (BigDecimal) returnInfoData.get("returnAmount");
boolean hasNormalReturn = (boolean) returnInfoData.get("hasNormalReturn");
String shopId = orderInfo.getShopId();
// // 线上退款
orderInfo.setRefundAmount(orderInfo.getRefundAmount().add(returnOrderInfo.getRefundAmount()));
orderInfo.setRefundRemark(returnOrderDTO.getNote());
if (hasNormalReturn && ("scanCode".equals(payType) || "wx_lite".equals(payType))) {
if (returnOrderDTO.getIsOnline() != null && !returnOrderDTO.getIsOnline()) {
mpOrderDetailService.updateStatusByOrderIdAndIds(TableConstant.OrderInfo.Status.REFUNDING, TableConstant.OrderInfo.Status.REFUND,
returnOrderDTO.getOrderId(), returnOrderDTO.getOrderDetails().stream().map(ReturnOrderDTO.OrderDetail::getId).collect(Collectors.toList()));
}else {
TbMerchantThirdApply thirdApply = tbMerchantThirdApplyMapper.selectByPrimaryKey(Integer.valueOf(orderInfo.getMerchantId()));
MsgException.checkNull(thirdApply, "支付参数配置错误");
if ("ysk".equals(thirdPayType)) {
ReturnOrderReq req = new ReturnOrderReq();
req.setAppId(thirdApply.getAppId());
req.setTimestamp(System.currentTimeMillis());
req.setOrderNumber(orderInfo.getPayOrderNo());
req.setAmount(String.format("%.2f", returnOrderInfo.getPayAmount().setScale(2, RoundingMode.DOWN)));
req.setMercRefundNo(orderInfo.getOrderNo());
req.setRefundReason("退货");
req.setPayPassword(thirdApply.getPayPassword());
Map<String, Object> map = BeanUtil.transBean2Map(req);
req.setSign(MD5Util.encrypt(map, thirdApply.getAppToken(), true));
log.info("merchantOrderReturn req:{}", JSONUtil.toJsonStr(req));
ResponseEntity<String> response = restTemplate.postForEntity(gateWayUrl.concat("merchantOrder/returnOrder"), req, String.class);
log.info("merchantOrderReturn:{}", response.getBody());
if (response.getStatusCodeValue() == 200 && ObjectUtil.isNotEmpty(response.getBody())) {
JSONObject object = JSONObject.parseObject(response.getBody());
if (!object.get("code").equals("0")) {
MsgException.check(true, "退款渠道调用失败");
}
// newOrderInfo.setPayOrderNo(object.getJSONObject("data").getString("refundOrderNumber"));
}
} else {
TbOrderPayment payment = tbOrderPaymentMapper.selectByOrderId(String.valueOf(orderInfo.getId()));
PublicResp<OrderReturnResp> publicResp = thirdPayService.returnOrder(url, thirdApply.getAppId(),
returnOrderInfo.getOrderNo(), payment.getTradeNumber(), null, "订单退款",
returnOrderInfo.getPayAmount().setScale(2, RoundingMode.DOWN).multiply(new BigDecimal(100)).longValue(), callBack, null, thirdApply.getAppToken());
if (ObjectUtil.isNotNull(publicResp) && ObjectUtil.isNotEmpty(publicResp)) {
if ("000000".equals(publicResp.getCode())) {
if (!"SUCCESS".equals(publicResp.getObjData().getState()) && !publicResp.getObjData().getState().equals("ING")) {
MsgException.check(true, "退款渠道调用失败");
}
} else {
MsgException.check(true, "退款渠道调用失败");
}
}
}
returnOrderInfo.setStatus("refund");
mPOrderInfoMapper.updateById(returnOrderInfo);
}
// 储值卡支付退款
} else if ("deposit".equals(payType)) {
mpOrderInfoService.depositReturn(Integer.valueOf(orderInfo.getUserId()), Integer.valueOf(orderInfo.getShopId()), returnAmount);
mpOrderDetailService.updateStatusByOrderIdAndIds(TableConstant.OrderInfo.Status.REFUNDING, TableConstant.OrderInfo.Status.REFUND,
returnOrderDTO.getOrderId(), returnOrderDTO.getOrderDetails().stream().map(ReturnOrderDTO.OrderDetail::getId).collect(Collectors.toList()));
} else if ("cash".equals(payType)) {
mpOrderDetailService.updateStatusByOrderIdAndIds(TableConstant.OrderInfo.Status.REFUNDING, TableConstant.OrderInfo.Status.REFUND,
returnOrderDTO.getOrderId(), returnOrderDTO.getOrderDetails().stream().map(ReturnOrderDTO.OrderDetail::getId).collect(Collectors.toList()));
}
orderInfo.setStatus(TableConstant.OrderInfo.Status.CLOSED.getValue());
// 订单金额全退,退优惠券以及积分
if (orderInfo.getPayAmount().compareTo(orderInfo.getRefundAmount()) <= 0) {
long count = mpOrderDetailService.count(new LambdaQueryWrapper<TbOrderDetail>()
.eq(TbOrderDetail::getOrderId, orderInfo.getId())
.eq(TbOrderDetail::getStatus, TableConstant.OrderInfo.Status.CLOSED));
if (count == 0) {
returnCoupon(orderInfo, true);
// 返还积分
memberPointsService.addPoints(Long.valueOf(orderInfo.getMemberId()), orderInfo.getPointsNum(),
"用户退款订单积分返还: " + orderInfo.getPointsNum() + "积分", Long.valueOf(orderInfo.getId()));
}
}
mPOrderInfoMapper.updateById(orderInfo);
// 打印退款小票
// producer.printMechine(newOrderInfo.getId().toString());
producer.printMechine(returnOrderInfo.getId().toString());
//修改耗材数据
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("orderId", returnOrderInfo.getId());
jsonObject1.put("type", "delete");
rabbitMsgUtils.updateCons(jsonObject1);
return true;
}
private BigDecimal calcDetailReturnAmount(TbOrderDetail orderDetail, BigDecimal returnNum) {
if (orderDetail.getNum().compareTo(returnNum) == 0) {
return orderDetail.getCanReturnAmount();
}
if (returnNum.compareTo(BigDecimal.ONE) == 0 &&
orderDetail.getNum().compareTo(BigDecimal.ONE) > 0 &&
orderDetail.getCanReturnAmount().compareTo(new BigDecimal("0.01")) <= 0) {
throw new MsgException(orderDetail.getProductName() + "总金额为0.01,请选择全部商品数量退回");
}
return orderDetail.getCanReturnAmount().divide(orderDetail.getNum(), 10, RoundingMode.HALF_DOWN).multiply(returnNum).setScale(2, RoundingMode.HALF_DOWN);
}
@Transactional(rollbackFor = Exception.class)
@@ -1177,7 +1557,7 @@ public class PayService {
//
// TbmerchantAccount account = tbmerchantAccountMapper.selectByPrimaryKey(Integer.valueOf(accountId));
// if (Objects.isNull(account)) {
// return Result.fail(CodeEnum.ACCOUNTEIXST);
// return Result.fail(ACCOUNTEIXST);
// }
// if (Objects.isNull(account.getPwd()) || ObjectUtil.isEmpty(account.getPwd())) {
// return Result.fail(CodeEnum.PWDNOSET);
@@ -1457,7 +1837,7 @@ public class PayService {
// redisUtil.del("SHOP:CODE:USER:" + "pc" + ":" + orderInfo.getShopId() + ":" + DateUtils.getDay() + TokenUtil.parseParamFromToken(token).getString("accountId"));
//
//
// return Result.success(CodeEnum.SUCCESS);
// return Result.success(SUCCESS);
return null;
}
@@ -1488,7 +1868,7 @@ public class PayService {
jsonObject.put("amount", tbQuickPay.getAmount());
producer.putOrderCollect(jsonObject.toJSONString());
return Result.success(CodeEnum.SUCCESS, tbQuickPay);
return Result.success(SUCCESS, tbQuickPay);
} else {
TbShopInfo tbShopInfo = tbShopInfoMapper.selectByPrimaryKey(Integer.valueOf(shopId));
@@ -1515,7 +1895,7 @@ public class PayService {
tbQuickPay.setTradeNo(object.getJSONObject("data").get("orderNumber").toString());
tbQuickPayMapper.insert(tbQuickPay);
return Result.success(CodeEnum.SUCCESS, tbQuickPay);
return Result.success(SUCCESS, tbQuickPay);
}
String status = ObjectUtil.isNotEmpty(object.getJSONObject("data")) ? object.getJSONObject("data").getString("status") : null;
@@ -1540,7 +1920,7 @@ public class PayService {
jsonObject.put("type", "quick");
jsonObject.put("amount", tbQuickPay.getAmount());
producer.putOrderCollect(jsonObject.toJSONString());
return Result.success(CodeEnum.SUCCESS, tbQuickPay);
return Result.success(SUCCESS, tbQuickPay);
}
if ("TRADE_AWAIT".equals(mainScanResp.getState())) {
@@ -1610,7 +1990,7 @@ public class PayService {
}
}
return Result.success(CodeEnum.SUCCESS, tbQuickPay);
return Result.success(SUCCESS, tbQuickPay);
}
public Result queryQuickPay(String token, int pageNo, int pageSize) {
@@ -1624,7 +2004,7 @@ public class PayService {
List<TbQuickPay> list = tbQuickPayMapper.selectByShopIdAndStaffId(Integer.valueOf(shopId), Integer.valueOf(staffId));
PageInfo pageInfo = new PageInfo(list);
return Result.success(CodeEnum.SUCCESS, pageInfo);
return Result.success(SUCCESS, pageInfo);
}
@@ -1710,7 +2090,7 @@ public class PayService {
groupOrderInfo.setStatus("refund");
}
tbGroupOrderInfoMapper.update(groupOrderInfo);
return Result.success(CodeEnum.SUCCESS);
return Result.success(SUCCESS);
}
public Result getOrderDiscount(String staffId, String orderId, String token) {
@@ -1869,7 +2249,7 @@ public class PayService {
ObjectMapper mapper = new ObjectMapper();
return Result.success(CodeEnum.SUCCESS, mapper.readTree(scanpayResp.getPayInfo()));
return Result.success(SUCCESS, mapper.readTree(scanpayResp.getPayInfo()));
} else if ("TRADE_AWAIT".equals(scanpayResp.getState())) {
payment.setTradeNumber(scanpayResp.getPayOrderId());
@@ -2028,7 +2408,7 @@ public class PayService {
ObjectMapper mapper = new ObjectMapper();
return Result.success(CodeEnum.SUCCESS, mapper.readTree(scanpayResp.getPayInfo()));
return Result.success(SUCCESS, mapper.readTree(scanpayResp.getPayInfo()));
} else if ("TRADE_AWAIT".equals(scanpayResp.getState())) {
payment.setTradeNumber(scanpayResp.getPayOrderId());
@@ -2099,7 +2479,7 @@ public class PayService {
}
}
return Result.success(CodeEnum.SUCCESS, orderInfo);
return Result.success(SUCCESS, orderInfo);
}

View File

@@ -0,0 +1,30 @@
package com.chaozhanggui.system.cashierservice.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.chaozhanggui.system.cashierservice.entity.TbMemberPoints;
import java.math.BigDecimal;
import java.util.Map;
/**
* 会员积分
*
* @author Tankaikai tankaikai@aliyun.com
* @since 2.0 2024-10-25
*/
public interface TbMemberPointsService extends IService<TbMemberPoints> {
/**
* 追加积分
*
* @param memberId 会员id
* @param points 积分
* @param content 摘要信息(如:兑换积分商品/积分抵扣账单/消费赠送积分/新会员送积分/储值赠送积分)
* @param orderId 订单id可以为空
* @throws Exception
*/
boolean addPoints(Long memberId, int points, String content, Long orderId);
}

View File

@@ -0,0 +1,24 @@
package com.chaozhanggui.system.cashierservice.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.chaozhanggui.system.cashierservice.entity.TbActivateOutRecord;
import com.chaozhanggui.system.cashierservice.entity.TbShopCoupon;
import org.springframework.http.ResponseEntity;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 优惠券(TbShopCoupon)表服务接口
*
* @author ww
* @since 2024-10-22 15:43:25
*/
public interface TbShopCouponService {
boolean refund(List<TbActivateOutRecord> param);
}

View File

@@ -70,5 +70,17 @@ public class MpOrderDetailServiceImpl extends ServiceImpl<MPOrderDetailMapper, T
}
return update(query);
}
@Override
public boolean updateStatusByOrderIdAndIds(TableConstant.OrderInfo.Status oldOrderStatusEnums, TableConstant.OrderInfo.Status orderStatusEnums, Integer orderId, List<Integer> orderDetails) {
LambdaUpdateWrapper<TbOrderDetail> wrapper = new LambdaUpdateWrapper<TbOrderDetail>()
.eq(TbOrderDetail::getOrderId, orderId)
.in(TbOrderDetail::getId, orderDetails)
.set(TbOrderDetail::getStatus, orderStatusEnums.getValue());
if (oldOrderStatusEnums != null) {
wrapper.eq(TbOrderDetail::getStatus, oldOrderStatusEnums.getValue());
}
return update(wrapper);
}
}

View File

@@ -1,16 +1,25 @@
package com.chaozhanggui.system.cashierservice.service.impl;
import cn.hutool.Hutool;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chaozhanggui.system.cashierservice.bean.constant.TableConstant;
import com.chaozhanggui.system.cashierservice.entity.TbOrderDetail;
import com.chaozhanggui.system.cashierservice.entity.TbOrderInfo;
import com.chaozhanggui.system.cashierservice.entity.TbShopUser;
import com.chaozhanggui.system.cashierservice.entity.TbShopUserFlow;
import com.chaozhanggui.system.cashierservice.exception.MsgException;
import com.chaozhanggui.system.cashierservice.mybatis.MPOrderDetailMapper;
import com.chaozhanggui.system.cashierservice.mybatis.MPOrderInfoMapper;
import com.chaozhanggui.system.cashierservice.mybatis.MpShopUserFlowMapper;
import com.chaozhanggui.system.cashierservice.mybatis.MpShopUserMapper;
import com.chaozhanggui.system.cashierservice.service.MpOrderDetailService;
import com.chaozhanggui.system.cashierservice.service.MpOrderInfoService;
import com.chaozhanggui.system.cashierservice.util.RabbitMsgUtils;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
@@ -25,6 +34,16 @@ import java.util.List;
@Service
public class MpOrderInfoServiceImpl extends ServiceImpl<MPOrderInfoMapper, TbOrderInfo> implements MpOrderInfoService {
private final MpShopUserMapper mpShopUserMapper;
private final MpShopUserFlowMapper mpShopUserFlowMapper;
private final RabbitMsgUtils rabbitMsgUtils;
public MpOrderInfoServiceImpl(MpShopUserMapper mpShopUserMapper, MpShopUserFlowMapper mpShopUserFlowMapper, RabbitMsgUtils rabbitMsgUtils) {
this.mpShopUserMapper = mpShopUserMapper;
this.mpShopUserFlowMapper = mpShopUserFlowMapper;
this.rabbitMsgUtils = rabbitMsgUtils;
}
@Override
public boolean updateStateById(Integer shopId, Integer orderId, TableConstant.Status status) {
return update(new LambdaUpdateWrapper<TbOrderInfo>()
@@ -45,5 +64,37 @@ public class MpOrderInfoServiceImpl extends ServiceImpl<MPOrderInfoMapper, TbOrd
.setSql(StrUtil.format("origin_amount=origin_amount+{}", subtract))
);
}
@Override
public void depositReturn(Integer userId, Integer shopId, BigDecimal returnAmount) {
TbShopUser user = mpShopUserMapper.selectOne(new LambdaQueryWrapper<TbShopUser>()
.eq(TbShopUser::getShopId, shopId)
.eq(TbShopUser::getUserId, userId));
if (user == null) {
throw new MsgException("用户信息不存在");
}
mpShopUserMapper.incrBalance(user.getId(), shopId, returnAmount, DateUtil.date().getTime());
TbShopUserFlow flow = new TbShopUserFlow();
flow.setShopUserId(user.getId());
flow.setBizCode("accountReturnPay");
flow.setBizName("会员储值卡退款");
flow.setType("+");
flow.setAmount(returnAmount);
flow.setBalance(user.getAmount().add(returnAmount));
flow.setCreateTime(cn.hutool.core.date.DateUtil.date().toTimestamp());
flow.setIsReturn("0");
mpShopUserFlowMapper.insert(flow);
JSONObject baObj = new JSONObject();
baObj.put("userId", user.getUserId());
baObj.put("shopId", user.getShopId());
baObj.put("amount", returnAmount);
baObj.put("balance", user.getAmount());
baObj.put("type", "退款");
baObj.put("time", flow.getCreateTime());
rabbitMsgUtils.addBalanceRecord(baObj);
// producer.balance(baObj.toString());
}
}

View File

@@ -0,0 +1,94 @@
package com.chaozhanggui.system.cashierservice.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapProxy;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chaozhanggui.system.cashierservice.dao.TbOrderInfoMapper;
import com.chaozhanggui.system.cashierservice.entity.TbMemberPoints;
import com.chaozhanggui.system.cashierservice.entity.TbMemberPointsLog;
import com.chaozhanggui.system.cashierservice.entity.TbOrderInfo;
import com.chaozhanggui.system.cashierservice.exception.MsgException;
import com.chaozhanggui.system.cashierservice.mapper.TbMemberPointsLogMapper;
import com.chaozhanggui.system.cashierservice.mapper.TbMemberPointsMapper;
import com.chaozhanggui.system.cashierservice.service.TbMemberPointsService;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.Map;
/**
* 会员积分
*
* @author Tankaikai tankaikai@aliyun.com
* @since 2.0 2024-10-25
*/
@Service
@Primary
public class TbMemberPointsServiceImpl extends ServiceImpl<TbMemberPointsMapper, TbMemberPoints> implements TbMemberPointsService {
@Resource
private TbMemberPointsLogMapper tbMemberPointsLogMapper;
@Resource
private TbOrderInfoMapper tbOrderInfoMapper;
public TbMemberPoints initMemberPoints(Long memberId) {
TbMemberPoints entity = super.getOne(Wrappers.<TbMemberPoints>lambdaQuery().eq(TbMemberPoints::getMemberId, memberId));
if (entity == null) {
throw new MsgException("会员信息不存在");
}
if (entity.getAccountPoints() == null) {
entity.setAccountPoints(0);
}
super.updateById(entity);
return entity;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean addPoints(Long memberId, int points, String content, Long orderId) {
TbMemberPoints entity = initMemberPoints(memberId);
// 增加账户积分
entity.setAccountPoints(entity.getAccountPoints() + points);
entity.setLastPointsChangeTime(new Date());
entity.setLastFloatPoints(points);
// 记录积分变动记录
TbMemberPointsLog log = new TbMemberPointsLog();
log.setShopId(entity.getShopId());
log.setMemberId(entity.getMemberId());
log.setMemberName(entity.getMemberName());
log.setAvatarUrl(entity.getAvatarUrl());
log.setMobile(entity.getMobile());
log.setContent(content);
log.setFloatType("add");
log.setFloatPoints(points);
log.setCreateTime(new Date());
// 有关联订单的需要回置订单表的相关积分使用字段
if (orderId != null) {
TbOrderInfo orderInfo = tbOrderInfoMapper.selectById(Math.toIntExact(orderId));
if (orderInfo != null) {
log.setOrderNo(orderInfo.getOrderNo());
}
}
super.updateById(entity);
tbMemberPointsLogMapper.insert(log);
return true;
}
}

View File

@@ -0,0 +1,53 @@
package com.chaozhanggui.system.cashierservice.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chaozhanggui.system.cashierservice.dao.TbActivateInRecordMapper;
import com.chaozhanggui.system.cashierservice.dao.TbActivateOutRecordMapper;
import com.chaozhanggui.system.cashierservice.dao.TbShopCouponMapper;
import com.chaozhanggui.system.cashierservice.entity.TbActivateInRecord;
import com.chaozhanggui.system.cashierservice.entity.TbActivateOutRecord;
import com.chaozhanggui.system.cashierservice.entity.TbShopCoupon;
import com.chaozhanggui.system.cashierservice.service.TbShopCouponService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* 优惠券(TbShopCoupon)表服务实现类
*
* @author ww
* @since 2024-10-22 15:43:25
*/
@Service("tbShopCouponService")
@Primary
public class TbShopCouponServiceImpl implements TbShopCouponService {
@Autowired
private TbActivateInRecordMapper inRecordMapper;
@Autowired
private TbActivateOutRecordMapper outRecordMapper;
/**
* 退还券
*
* @param param giveId和 refNum 必传
* @return
*/
@Override
public boolean refund(List<TbActivateOutRecord> param) {
for (TbActivateOutRecord outRecord : param) {
outRecord.setUpdateTime(new Date());
outRecordMapper.updateRefNum(outRecord.getId(), outRecord.getRefNum());
TbActivateInRecord inRecord = inRecordMapper.queryById(outRecord.getGiveId());
inRecord.setOverNum(inRecord.getOverNum() + outRecord.getRefNum());
inRecordMapper.updateOverNum(inRecord.getId(), inRecord.getOverNum());
}
return true;
}
}

View File

@@ -73,4 +73,11 @@ public class RabbitMsgUtils implements RabbitTemplate.ConfirmCallback {
}
public void addBalanceRecord(JSONObject baObj) {
sendMsg(RabbitConstants.EXCHANGE_BALANCE, RabbitConstants.ROUTING_KEY_BALANCE, baObj, "储值卡记录", true);
}
public void updateCons(JSONObject jsonObject1) {
sendMsg(RabbitConstants.EXCHANGE_CONS, RabbitConstants.ROUTING_KEY_CONS, jsonObject1, "储值卡记录", true);
}
}