You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

832 lines
38 KiB

package com.cyl.h5.service;
import cn.hutool.core.collection.CollectionUtil;
2 years ago
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyl.h5.config.SecurityUtil;
import com.cyl.h5.pojo.dto.ApplyRefundDTO;
import com.cyl.h5.pojo.dto.OrderCreateDTO;
import com.cyl.h5.pojo.dto.OrderProductListDTO;
import com.cyl.h5.pojo.dto.PayNotifyMessageDTO;
2 years ago
import com.cyl.h5.pojo.request.CancelOrderRequest;
2 years ago
import com.cyl.h5.pojo.request.OrderPayRequest;
import com.cyl.h5.pojo.response.OrderPayResponse;
import com.cyl.h5.pojo.vo.*;
import com.cyl.h5.pojo.vo.form.OrderSubmitForm;
2 years ago
import com.cyl.manager.act.service.IntegralHistoryService;
import com.cyl.manager.oms.convert.AftersaleItemConvert;
import com.cyl.manager.oms.convert.OrderItemConvert;
2 years ago
import com.cyl.manager.oms.domain.*;
import com.cyl.manager.oms.mapper.*;
import com.cyl.manager.oms.service.OrderItemService;
2 years ago
import com.cyl.manager.oms.service.OrderOperateHistoryService;
import com.cyl.manager.pms.domain.Product;
import com.cyl.manager.pms.domain.Sku;
import com.cyl.manager.pms.mapper.ProductMapper;
import com.cyl.manager.pms.mapper.SkuMapper;
import com.cyl.manager.ums.domain.Member;
import com.cyl.manager.ums.domain.MemberAddress;
import com.cyl.manager.ums.domain.MemberCart;
2 years ago
import com.cyl.manager.ums.domain.MemberWechat;
import com.cyl.manager.ums.mapper.MemberAddressMapper;
import com.cyl.manager.ums.mapper.MemberCartMapper;
2 years ago
import com.cyl.manager.ums.mapper.MemberWechatMapper;
import com.cyl.wechat.WechatPayData;
import com.cyl.wechat.WechatPayService;
import com.cyl.wechat.WechatPayUtil;
import com.github.pagehelper.PageHelper;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisService;
2 years ago
import com.ruoyi.common.enums.AftersaleStatus;
2 years ago
import com.ruoyi.common.enums.OrderRefundStatus;
import com.ruoyi.common.enums.OrderStatus;
2 years ago
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.IDGenerator;
import com.ruoyi.framework.config.LocalDataUtil;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
2 years ago
import java.util.stream.Stream;
@Service
@Slf4j
public class H5OrderService {
@Autowired
private MemberAddressMapper memberAddressMapper;
@Autowired
private SkuMapper skuMapper;
@Autowired
private ProductMapper productMapper;
@Autowired
private MemberCartMapper memberCartMapper;
@Autowired
private OrderMapper orderMapper;
@Autowired
private OrderItemMapper orderItemMapper;
@Autowired
private OrderOperateHistoryMapper orderOperateHistoryMapper;
@Autowired
private OrderItemService orderItemService;
2 years ago
@Autowired
private OrderOperateHistoryService orderOperateHistoryService;
@Autowired(required = false)
2 years ago
private WechatPayService wechatPayService;
@Autowired
private MemberWechatMapper memberWechatMapper;
@Autowired
private WechatPaymentHistoryMapper wechatPaymentHistoryMapper;
@Autowired
private RedisService redisService;
2 years ago
@Autowired
private AftersaleMapper aftersaleMapper;
@Autowired
private AftersaleItemMapper aftersaleItemMapper;
@Autowired
private AftersaleItemConvert aftersaleItemConvert;
@Autowired
private OrderItemConvert orderItemConvert;
2 years ago
@Autowired
private IntegralHistoryService integralHistoryService;
@Transactional
public Long submit(OrderSubmitForm form) {
Member member = (Member) LocalDataUtil.getVar(Constants.MEMBER_INFO);
//只支持快递
Long addressId = form.getAddressId();
if (addressId == null){
throw new RuntimeException("收获地址不能为空");
}
MemberAddress memberAddress = memberAddressMapper.selectById(addressId);
if (memberAddress == null){
throw new RuntimeException("收货地址不能为空");
}
//sku不能为空
List<OrderProductListDTO> skuList = form.getSkuList();
if (CollectionUtil.isEmpty(skuList)){
throw new RuntimeException("商品SKU信息不能为空");
}
//将sku信息转换为 keyskuId value购买数量
Map<Long, Integer> skuQuantityMap = skuList.stream().collect(Collectors.toMap(OrderProductListDTO::getSkuId, OrderProductListDTO::getQuantity));
//查询所有sku信息
Map<Long, Sku> querySkuMap = skuMapper
.selectBatchIds(skuList.stream().map(OrderProductListDTO::getSkuId).collect(Collectors.toList()))
.stream().collect(Collectors.toMap(Sku::getId, it -> it));
//计算商品总额、订单总额(订单总金额=商品总金额,因为暂时没有运费等概念)
BigDecimal productTotalAmount = BigDecimal.ZERO;
BigDecimal orderTotalAmount = BigDecimal.ZERO;
for (OrderProductListDTO dto : skuList){
if (!querySkuMap.containsKey(dto.getSkuId())){
throw new RuntimeException("商品SKU不存在");
}
Sku sku = querySkuMap.get(dto.getSkuId());
Product product = productMapper.selectById(sku.getProductId());
if (product == null){
throw new RuntimeException("商品不存在");
}
if (Constants.PublishStatus.UNDERCARRIAGE.equals(product.getPublishStatus())){
throw new RuntimeException("商品" + product.getName() + "已下架");
}
if (sku.getStock() < skuQuantityMap.get(sku.getId())) {
throw new RuntimeException("库存不足");
}
productTotalAmount = productTotalAmount.add(sku.getPrice().multiply(BigDecimal.valueOf(skuQuantityMap.get(sku.getId()))));
orderTotalAmount = orderTotalAmount.add(sku.getPrice().multiply(BigDecimal.valueOf(skuQuantityMap.get(sku.getId()))));
dto.setSku(sku);
dto.setProduct(product);
}
LocalDateTime optTime = LocalDateTime.now();
//生成一个统一的订单号
Long orderId = IDGenerator.generateId();
2 years ago
//生产一个payId
Long payId = IDGenerator.generateId();
//创建订单
Order order = new Order();
2 years ago
order.setPayId(payId);
order.setId(orderId);
order.setOrderSn(this.getOrderIdPrefix() + orderId);
order.setMemberId(member.getId());
order.setMemberUsername(member.getNickname());
order.setPayType(Constants.PayType.WECHAT);
order.setTotalAmount(orderTotalAmount);
order.setPurchasePrice(BigDecimal.ZERO);
order.setFreightAmount(BigDecimal.ZERO);
order.setPayAmount(orderTotalAmount);
2 years ago
order.setStatus(Constants.OrderStatus.NOTPAID);
order.setAftersaleStatus(1);
order.setReceiverName(memberAddress.getName());
order.setReceiverPhone(memberAddress.getPhoneHidden());
order.setReceiverPhoneEncrypted(memberAddress.getPhoneEncrypted());
order.setReceiverPostCode(memberAddress.getPostCode());
order.setReceiverProvince(memberAddress.getProvince());
order.setReceiverCity(memberAddress.getCity());
order.setReceiverDistrict(memberAddress.getDistrict());
order.setReceiverProvinceId(memberAddress.getProvinceId());
order.setReceiverCityId(memberAddress.getCityId());
order.setReceiverDistrictId(memberAddress.getDistrictId());
order.setReceiverDetailAddress(memberAddress.getDetailAddress());
order.setNote(form.getNote());
order.setConfirmStatus(0);
order.setDeleteStatus(0);
2 years ago
// order.setPaymentTime(optTime);
order.setCreateTime(optTime);
order.setCreateBy(member.getId());
int rows = orderMapper.insert(order);
if (rows < 1){
throw new RuntimeException("订单新增失败");
}
// 保存orderItem
orderItemService.saveOrderItem(member, optTime, orderId, skuList);
skuList.forEach(item -> {
//减少sku的库存
skuMapper.updateStockById(item.getSkuId(),LocalDateTime.now(),item.getQuantity());
});
// 保存订单操作记录
OrderOperateHistory orderOperateHistory = new OrderOperateHistory();
orderOperateHistory.setOrderId(orderId);
orderOperateHistory.setOrderSn(order.getOrderSn());
orderOperateHistory.setOperateMan(member.getNickname());
2 years ago
orderOperateHistory.setOrderStatus(Constants.OrderStatus.NOTPAID);
orderOperateHistory.setCreateTime(optTime);
orderOperateHistory.setCreateBy(member.getId());
rows = orderOperateHistoryMapper.insert(orderOperateHistory);
if (rows < 1){
throw new RuntimeException("保存订单操作记录失败");
}
//若来源为购物车,删除购物车
if (Constants.OrderFrom.CART.equals(form.getFrom())){
List<Long> skuIdList = skuList.stream().map(OrderProductListDTO::getSkuId).collect(Collectors.toList());
LambdaUpdateWrapper<MemberCart> wrapper = Wrappers.lambdaUpdate();
wrapper.eq(MemberCart::getMemberId, member.getId());
wrapper.in(MemberCart::getSkuId, skuIdList);
rows = memberCartMapper.delete(wrapper);
if (rows < 1){
throw new RuntimeException("删除购物车失败");
}
}
//当前订单id接入支付后可返回payId
2 years ago
return payId;
}
public OrderCalcVO addOrderCheck(OrderCreateDTO orderCreateDTO) {
OrderCalcVO res = new OrderCalcVO();
List<SkuViewDTO> skuList = new ArrayList<>();
List<OrderProductListDTO> list = orderCreateDTO.getSkuList();
if (CollectionUtil.isEmpty(list)){
throw new RuntimeException("商品SKU信息不能为空");
}
//将购买的sku信息转化为keyskuId value数量
Map<Long, Integer> quantityMap = list.stream().
collect(Collectors.toMap(OrderProductListDTO::getSkuId, OrderProductListDTO::getQuantity, (v1, v2) -> v2));
//查询所有sku信息
Set<Long> collect = list.stream().map(OrderProductListDTO::getSkuId).collect(Collectors.toSet());
Map<Long, Sku> querySkuMap = skuMapper.selectBatchIds(collect).stream().collect(Collectors.toMap(Sku::getId, it -> it));
//计算商品总金额、订单总金额
BigDecimal productTotalAmount = BigDecimal.ZERO;
BigDecimal orderTotalAmount = BigDecimal.ZERO;
for (OrderProductListDTO dto : list){
if (!querySkuMap.containsKey(dto.getSkuId())){
throw new RuntimeException("商品SKU不存在");
}
Sku sku = querySkuMap.get(dto.getSkuId());
//查product
Product product = productMapper.selectById(sku.getProductId());
if (product == null){
throw new RuntimeException("商品不存在");
}
if (Constants.PublishStatus.UNDERCARRIAGE.equals(product.getPublishStatus())){
throw new RuntimeException("商品" + product.getName() + "已下架");
}
if (sku.getStock() < quantityMap.get(sku.getId())) {
throw new RuntimeException("库存不足");
}
BigDecimal addAmount = sku.getPrice().multiply(BigDecimal.valueOf(dto.getQuantity()));
//由于目前没有运费等数据,暂时订单总金额=商品总金额了
productTotalAmount = productTotalAmount.add(addAmount);
orderTotalAmount = orderTotalAmount.add(addAmount);
//封装sku信息
SkuViewDTO skuViewDTO = new SkuViewDTO();
skuViewDTO.setPic(product.getPic());
skuViewDTO.setPrice(sku.getPrice());
skuViewDTO.setProductId(product.getId());
skuViewDTO.setProductName(product.getName());
skuViewDTO.setQuantity(quantityMap.get(sku.getId()));
skuViewDTO.setSkuId(sku.getId());
skuViewDTO.setSpData(sku.getSpData());
skuList.add(skuViewDTO);
}
res.setSkuList(skuList);
res.setOrderTotalAmount(orderTotalAmount);
res.setProductTotalAmount(productTotalAmount);
return res;
}
private String getOrderIdPrefix(){
LocalDateTime time = LocalDateTime.now();
return time.format(DateTimeFormatter.ofPattern("yyMMdd")) + "-";
}
/**
* h5
* @param status -1->0->1->2->-2->
* @param memberId id
* @param pageable
* @return
*/
public PageImpl<H5OrderVO> orderPage(Integer status, Long memberId, Pageable pageable) {
// 如果全部且页数为1看看有无待付款单
List<H5OrderVO> unpaidOrderList = new ArrayList<>();
if (Constants.H5OrderStatus.ALL.equals(status) && pageable.getPageNumber() == 0){
unpaidOrderList = orderMapper.orderPage(Constants.H5OrderStatus.UN_PAY, memberId);
}
if (pageable != null){
PageHelper.startPage(pageable.getPageNumber() + 1, pageable.getPageSize());
}
List<H5OrderVO> orderList = orderMapper.orderPage(status, memberId);
long total = ((com.github.pagehelper.Page) orderList).getTotal();
// 两个list都没数据那肯定返回空了
if (CollectionUtil.isEmpty(unpaidOrderList) && CollectionUtil.isEmpty(orderList)){
return new PageImpl<>(Collections.EMPTY_LIST, pageable, total);
}
// 开始组装item了
// 拿出所有orderId查item然后分组 by orderId
List<Long> idList = new ArrayList<>();
if (CollectionUtil.isNotEmpty(unpaidOrderList)){
idList.addAll(unpaidOrderList.stream().map(H5OrderVO::getOrderId).collect(Collectors.toList()));
}
if (CollectionUtil.isNotEmpty(orderList)){
idList.addAll(orderList.stream().map(H5OrderVO::getOrderId).collect(Collectors.toList()));
}
QueryWrapper<OrderItem> orderItemQw = new QueryWrapper<>();
orderItemQw.in("order_id", idList);
Map<Long, List<OrderItem>> orderItemMap =
orderItemMapper.selectList(orderItemQw).stream().collect(Collectors.groupingBy(OrderItem::getOrderId));
orderList.addAll(0, unpaidOrderList);
orderList.forEach(item -> {
item.setOrderItemList(orderItemMap.get(item.getOrderId()));
});
return new PageImpl<>(orderList, pageable, total);
}
public H5OrderVO orderDetail(Long orderId) {
H5OrderVO order = orderMapper.selectOrderDetail(orderId);
if (order == null){
throw new RuntimeException("未查询到该订单");
}
// 组装item
QueryWrapper<OrderItem> orderItemQw = new QueryWrapper<>();
orderItemQw.eq("order_id", orderId);
List<OrderItem> orderItemList = orderItemMapper.selectList(orderItemQw);
order.setOrderItemList(orderItemList);
// 如果未付款,计算倒计时
if (Constants.OrderStatus.NOTPAID.equals(order.getStatus())){
// 订单超时时间900s后面可以配置到字典等
Integer time = 900;
Date addDate = Date.from(order.getCreateTime().plusSeconds(time).atZone(ZoneId.systemDefault()).toInstant());
if (addDate.after(new Date())) {
order.setTimeToPay(addDate.getTime());
}
}
return order;
}
@Transactional
public void orderCompleteByJob(List<Order> idList) {
idList.forEach(order-> {
LocalDateTime optDate = LocalDateTime.now();
OrderItem queryOrderItem = new OrderItem();
queryOrderItem.setOrderId(order.getId());
//更新订单
order.setStatus(Constants.H5OrderStatus.COMPLETED);
order.setReceiveTime(optDate);
order.setConfirmStatus(1);
order.setUpdateTime(optDate);
order.setUpdateBy(null);
orderMapper.updateById(order);
//创建订单操作记录
OrderOperateHistory optHistory = new OrderOperateHistory();
optHistory.setOrderId(order.getId());
optHistory.setOrderSn(order.getOrderSn());
optHistory.setOperateMan("后台管理员" );
optHistory.setOrderStatus(Constants.H5OrderStatus.COMPLETED);
optHistory.setCreateTime(optDate);
optHistory.setUpdateTime(optDate);
orderOperateHistoryMapper.insert(optHistory);
});
}
@Transactional
public String orderComplete(Long orderId) {
LocalDateTime optDate = LocalDateTime.now();
Order order = orderMapper.selectById(orderId);
OrderItem queryOrderItem = new OrderItem();
queryOrderItem.setOrderId(orderId);
List<OrderItem> orderItemList = orderItemMapper.selectByEntity(queryOrderItem);
if(order == null || CollectionUtil.isEmpty(orderItemList)){
throw new RuntimeException("未查询到订单信息");
}
// 只有【待收货】状态才能确认
if(!order.getStatus().equals(Constants.H5OrderStatus.DELIVERED)){
throw new RuntimeException("订单状态已改变,请刷新");
}
order.setStatus(Constants.H5OrderStatus.COMPLETED);
order.setReceiveTime(optDate);
order.setConfirmStatus(1);
order.setUpdateTime(optDate);
order.setUpdateBy(SecurityUtil.getLocalMember().getId());
orderMapper.updateById(order);
//创建订单操作记录
OrderOperateHistory optHistory = new OrderOperateHistory();
optHistory.setOrderId(order.getId());
optHistory.setOrderSn(order.getOrderSn());
optHistory.setOperateMan("" + order.getMemberId());
optHistory.setOrderStatus(Constants.H5OrderStatus.COMPLETED);
optHistory.setCreateTime(optDate);
optHistory.setCreateBy(order.getMemberId());
optHistory.setUpdateBy(order.getMemberId());
optHistory.setUpdateTime(optDate);
orderOperateHistoryMapper.insert(optHistory);
return order.getOrderSn();
}
/**
*
* @param memberId
* @return
*/
public CountOrderVO orderNumCount(Long memberId) {
return orderMapper.countByStatusAndMemberId(memberId);
}
2 years ago
@Transactional
public String orderBatchCancel(CancelOrderRequest request, Long userId) {
LocalDateTime optDate = LocalDateTime.now();
if (CollectionUtil.isEmpty(request.getIdList())){
throw new RuntimeException("未指定需要取消的订单号");
}
QueryWrapper<Order> orderQw = new QueryWrapper<>();
orderQw.in("id", request.getIdList());
List<Order> orderList = orderMapper.selectList(orderQw);
if (orderList.size() < request.getIdList().size()){
throw new RuntimeException("未查询到订单信息");
}
//查orderItem
QueryWrapper<OrderItem> qw = new QueryWrapper<>();
qw.in("order_id", request.getIdList());
List<OrderItem> orderItem = orderItemMapper.selectList(qw);
if (CollectionUtil.isEmpty(orderItem)) {
throw new RuntimeException("未查询到订单信息");
}
2 years ago
long count = orderList.stream().filter(it -> !Constants.H5OrderStatus.UN_PAY.equals(it.getStatus())).count();
if (count > 0){
throw new RuntimeException("订单状态已更新,请刷新页面");
}
List<OrderOperateHistory> addHistoryList = new ArrayList<>();
orderList.forEach(item -> {
item.setStatus(Constants.H5OrderStatus.CLOSED);
item.setUpdateTime(optDate);
item.setUpdateBy(userId);
OrderOperateHistory history = new OrderOperateHistory();
history.setOrderId(item.getId());
history.setOrderSn(item.getOrderSn());
2 years ago
history.setOperateMan(userId == null ? "后台管理员" : "" + item.getMemberId());
2 years ago
history.setOrderStatus(Constants.H5OrderStatus.CLOSED);
history.setCreateTime(optDate);
history.setCreateBy(userId);
history.setUpdateBy(userId);
history.setUpdateTime(optDate);
addHistoryList.add(history);
2 years ago
});
//取消订单
int rows = orderMapper.cancelBatch(orderList);
if (rows < 1){
throw new RuntimeException("更改订单状态失败");
}
orderItem.stream().collect(Collectors.groupingBy(it->it.getSkuId())).forEach((k,v)->{
AtomicReference<Integer> totalCount = new AtomicReference<>(0);
v.forEach(it-> totalCount.updateAndGet(v1 -> v1 + it.getQuantity()));
skuMapper.updateStockById(k, optDate, -1 * totalCount.get());
});
2 years ago
//创建订单操作记录
boolean flag = orderOperateHistoryService.saveBatch(addHistoryList);
if (!flag){
throw new RuntimeException("创建订单操作记录失败");
}
return "取消订单成功";
}
2 years ago
/**
*
* @param req
* @return
*/
public OrderPayResponse orderPay(OrderPayRequest req) {
QueryWrapper<Order> qw = new QueryWrapper<>();
qw.eq("pay_id", req.getPayId());
qw.eq("status", 0);
List<Order> orderList = orderMapper.selectList(qw);
if (CollectionUtil.isEmpty(orderList)){
throw new RuntimeException("没有待支付的订单");
}
QueryWrapper<MemberWechat> memberWechatQw = new QueryWrapper<>();
memberWechatQw.eq("member_id", req.getMemberId());
MemberWechat memberWechat = memberWechatMapper.selectOne(memberWechatQw);
if (memberWechat == null || StrUtil.isBlank(memberWechat.getOpenid())){
throw new RuntimeException("获取用户openId失败");
}
QueryWrapper<OrderItem> orderItemQw = new QueryWrapper<>();
orderItemQw.eq("order_id", orderList.get(0).getId());
List<OrderItem> orderItemList = orderItemMapper.selectList(orderItemQw);
String orderDesc = orderItemList.get(0).getProductName().substring(0, Math.min(40, orderItemList.get(0).getProductName().length()));
//保存微信支付历史
LocalDateTime optDate = LocalDateTime.now();
QueryWrapper<WechatPaymentHistory> wxPaymentQw = new QueryWrapper<>();
2 years ago
wxPaymentQw.eq("order_id", orderList.get(0).getPayId());
wxPaymentQw.eq("op_type", Constants.PaymentOpType.PAY);
WechatPaymentHistory wechatPaymentHistory = wechatPaymentHistoryMapper.selectOne(wxPaymentQw);
if (wechatPaymentHistory == null){
wechatPaymentHistory = new WechatPaymentHistory();
wechatPaymentHistory.setOrderId(orderList.get(0).getPayId());
wechatPaymentHistory.setMemberId(req.getMemberId());
wechatPaymentHistory.setOpenid(memberWechat.getOpenid());
wechatPaymentHistory.setTitle(orderItemList.get(0).getProductName());
wechatPaymentHistory.setMoney(orderList.get(0).getPayAmount());
wechatPaymentHistory.setOpType(Constants.PaymentOpType.PAY);
wechatPaymentHistory.setPaymentStatus(0);
wechatPaymentHistory.setCreateBy(req.getMemberId());
wechatPaymentHistory.setCreateTime(optDate);
wechatPaymentHistory.setUpdateBy(req.getMemberId());
wechatPaymentHistory.setUpdateTime(optDate);
wechatPaymentHistoryMapper.insert(wechatPaymentHistory);
}else {
wechatPaymentHistory.setMoney(orderList.get(0).getPayAmount());
wechatPaymentHistoryMapper.updateById(wechatPaymentHistory);
}
//请开启微信支付 wechat.enabled=true
//调用wx的jsapi拿prepayId返回签名等信息
2 years ago
String openId = memberWechat.getOpenid();
String appId = WechatPayData.appId;
if (2 == req.getWechatType()) {
openId = memberWechat.getRoutineOpenid();
appId = WechatPayData.miniProgramAppId;
}
2 years ago
String prepayId = wechatPayService.jsapiPay(
String.valueOf(req.getPayId()),
orderDesc,
Integer.valueOf(orderList.stream().map(Order::getPayAmount).
reduce(BigDecimal.ZERO, BigDecimal::add).multiply(new BigDecimal(100)).stripTrailingZeros().toPlainString()),
2 years ago
openId,
req.getMemberId(),
appId
2 years ago
);
OrderPayResponse response = new OrderPayResponse();
response.setPayType(2);
String nonceStr = WechatPayUtil.generateNonceStr();
long timeStamp = WechatPayUtil.getCurrentTimestamp();
prepayId = "prepay_id=" + prepayId;
String signType = "RSA";
String paySign = null;
String signatureStr = Stream.of(appId, String.valueOf(timeStamp), nonceStr, prepayId)
.collect(Collectors.joining("\n", "", "\n"));
try {
paySign = WechatPayUtil.getSign(signatureStr, WechatPayData.privateKeyPath);
} catch (Exception e) {
throw new RuntimeException("支付失败");
}
response.setAppId(appId);
response.setTimeStamp(String.valueOf(timeStamp));
response.setNonceStr(nonceStr);
response.setSignType(signType);
response.setPackage_(prepayId);
response.setPaySign(paySign);
return response;
}
/**
*
* @param messageDTO
* @return
*/
@Transactional
public ResponseEntity<String> payCallBack(PayNotifyMessageDTO messageDTO){
log.info("【订单支付回调】" + JSONObject.toJSON(messageDTO));
String redisKey = "h5_oms_order_pay_notify_" + messageDTO.getOutTradeNo();
String redisValue = messageDTO.getOutTradeNo() + "_" + System.currentTimeMillis();
LocalDateTime optDate = LocalDateTime.now();
try{
redisService.lock(redisKey, redisValue, 60);
//先判断回信回调的是否未success
if (!Transaction.TradeStateEnum.SUCCESS.equals(messageDTO.getTradeStatus())){
log.error("【订单支付回调】订单状态不是支付成功状态" + messageDTO.getTradeStatus());
throw new RuntimeException();
}
QueryWrapper<WechatPaymentHistory> paymentWrapper = new QueryWrapper<>();
paymentWrapper.eq("order_id", messageDTO.getOutTradeNo());
paymentWrapper.eq("op_type", Constants.PaymentOpType.PAY);
WechatPaymentHistory paymentHistory = wechatPaymentHistoryMapper.selectOne(paymentWrapper);
if (paymentHistory.getPaymentStatus() != Constants.PaymentStatus.INCOMPLETE) {
log.info("【订单支付回调】支付订单不是未支付状态,不再处理" + "orderId" + paymentHistory.getOrderId() + "status" + paymentHistory.getPaymentStatus());
throw new RuntimeException();
}
QueryWrapper<Order> orderQw = new QueryWrapper<>();
orderQw.eq("pay_id", messageDTO.getOutTradeNo());
orderQw.eq("status", OrderStatus.UN_PAY.getType());
List<Order> orderList = orderMapper.selectList(orderQw);
orderList.forEach(order -> {
order.setPaymentTime(messageDTO.getPayTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
order.setStatus(OrderStatus.NOT_DELIVERED.getType());
orderMapper.updateById(order);
OrderOperateHistory optHistory = new OrderOperateHistory();
optHistory.setOrderId(order.getId());
optHistory.setOrderSn(order.getOrderSn());
optHistory.setOperateMan("" + order.getMemberId());
optHistory.setOrderStatus(OrderStatus.NOT_DELIVERED.getType());
optHistory.setCreateTime(optDate);
optHistory.setCreateBy(order.getMemberId());
optHistory.setUpdateBy(order.getMemberId());
optHistory.setUpdateTime(optDate);
orderOperateHistoryMapper.insert(optHistory);
2 years ago
//处理积分
integralHistoryService.handleIntegral(order.getId(),order.getPayAmount(),order.getMemberId());
});
UpdateWrapper<WechatPaymentHistory> paymentHistoryUpdateWrapper = new UpdateWrapper<>();
paymentHistoryUpdateWrapper.eq("order_id", messageDTO.getOutTradeNo()).set("payment_id", messageDTO.getTradeNo())
.set("payment_status", Constants.PaymentStatus.COMPLETE).set("update_time", optDate);
wechatPaymentHistoryMapper.update(null, paymentHistoryUpdateWrapper);
}catch (Exception e){
2 years ago
log.error("订单支付回调异常",e);
throw new RuntimeException("订单支付回调异常");
}finally {
try{
redisService.unLock(redisKey, redisValue);
}catch (Exception e){
log.error("", e);
}
}
return ResponseEntity.ok("订单支付回调成功");
}
2 years ago
/**
*
* @param applyRefundDTO
* @return
*/
2 years ago
@Transactional
2 years ago
public String applyRefund(ApplyRefundDTO applyRefundDTO) {
2 years ago
Order order = orderMapper.selectById(applyRefundDTO.getOrderId());
//是否符合售后条件
this.checkIfCanApplyRefund(order);
LocalDateTime optDate = LocalDateTime.now();
Long memberId = order.getMemberId();
//创建售后单aftersale
Aftersale addAftersale = new Aftersale();
addAftersale.setId(IDGenerator.generateId());
addAftersale.setMemberId(order.getMemberId());
addAftersale.setOrderId(order.getId());
addAftersale.setReturnAmount(order.getPayAmount());
addAftersale.setType(applyRefundDTO.getApplyRefundType());
2 years ago
addAftersale.setStatus(AftersaleStatus.APPLY.getType());
2 years ago
addAftersale.setReason(applyRefundDTO.getReason());
addAftersale.setQuantity(applyRefundDTO.getQuantity());
addAftersale.setReason(applyRefundDTO.getReason());
addAftersale.setDescription(applyRefundDTO.getDescription());
addAftersale.setProofPics(applyRefundDTO.getProofPics());
addAftersale.setCreateTime(optDate);
addAftersale.setCreateBy(memberId);
addAftersale.setUpdateTime(optDate);
addAftersale.setUpdateBy(memberId);
int rows = aftersaleMapper.insert(addAftersale);
if (rows != 1) {
throw new RuntimeException("插入订单售后失败");
}
//创建aftersale item
QueryWrapper<OrderItem> orderItemQw = new QueryWrapper<>();
orderItemQw.eq("order_id", order.getId());
List<OrderItem> orderItemList = orderItemMapper.selectList(orderItemQw);
List<AftersaleItem> addAftersaleItemList = new ArrayList<>();
orderItemList.forEach(orderItem -> {
AftersaleItem aftersaleItem = new AftersaleItem();
aftersaleItem.setMemberId(memberId);
aftersaleItem.setAftersaleId(addAftersale.getId());
2 years ago
aftersaleItem.setOrderId(orderItem.getOrderId());
aftersaleItem.setOrderItemId(orderItem.getId());
aftersaleItem.setReturnAmount(orderItem.getSalePrice().multiply(BigDecimal.valueOf(orderItem.getQuantity())));
aftersaleItem.setQuantity(orderItem.getQuantity());
aftersaleItem.setCreateTime(optDate);
aftersaleItem.setCreateBy(memberId);
aftersaleItem.setUpdateTime(optDate);
aftersaleItem.setUpdateBy(memberId);
addAftersaleItemList.add(aftersaleItem);
});
rows = aftersaleItemMapper.insertBatch(addAftersaleItemList);
2 years ago
if (rows < 1){
throw new RuntimeException("创建售后订单item失败");
}
//更新订单
UpdateWrapper<Order> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", order.getId()).set("aftersale_status", OrderRefundStatus.APPLY.getType())
.set("update_time", optDate)
.set("update_by", memberId);
rows = orderMapper.update(null, updateWrapper);
if (rows < 1){
throw new RuntimeException("修改订单状态失败");
}
//创建订单操作记录
OrderOperateHistory optHistory = new OrderOperateHistory();
optHistory.setOrderId(order.getId());
optHistory.setOrderSn(order.getOrderSn());
optHistory.setOperateMan("" + memberId);
2 years ago
optHistory.setOrderStatus(11);
optHistory.setCreateTime(optDate);
optHistory.setCreateBy(memberId);
optHistory.setUpdateBy(memberId);
optHistory.setUpdateTime(optDate);
rows = orderOperateHistoryMapper.insert(optHistory);
if (rows < 1){
throw new RuntimeException("创建订单操作记录失败");
}
return "售后申请成功";
}
2 years ago
2 years ago
/**
* check
* @param order
*/
private void checkIfCanApplyRefund(Order order){
if (order == null){
throw new RuntimeException("为查询到订单信息");
}
Integer status = order.getStatus();
boolean flag = OrderStatus.NOT_DELIVERED.getType().equals(status) || OrderStatus.DELIVERED.getType().equals(status)
|| OrderStatus.COMPLETE.getType().equals(status);
if (!flag){
throw new RuntimeException("该订单无法申请售后");
}
if (OrderStatus.COMPLETE.getType().equals(order.getStatus()) &&
DateUtils.betweenDay(LocalDateTime.now(), order.getReceiveTime()) > 7){
throw new RuntimeException("订单确认收货时间已超过7天无法申请售后");
}
if(OrderRefundStatus.APPLY.getType().equals(order.getAftersaleStatus())
|| OrderRefundStatus.WAIT.getType().equals(order.getAftersaleStatus())){
throw new RuntimeException("售后正在处理中");
}
2 years ago
}
2 years ago
/**
*
* @param orderId id
* @return
*/
@Transactional
2 years ago
public String cancelRefund(Long orderId) {
Order order = orderMapper.selectById(orderId);
if (order == null){
throw new RuntimeException("未查询到该订单");
}
//查询是否有(待处理和退货中)售后单
QueryWrapper<Aftersale> aftersaleQw = new QueryWrapper<>();
aftersaleQw.eq("order_id", orderId);
aftersaleQw.in("status", Arrays.asList(AftersaleStatus.APPLY.getType(), AftersaleStatus.WAIT.getType()));
Aftersale aftersale = aftersaleMapper.selectOne(aftersaleQw);
if (aftersale == null){
throw new RuntimeException("无售后单");
}
if (OrderRefundStatus.SUCCESS.getType().equals(order.getAftersaleStatus())){
throw new RuntimeException("已退款成功");
}
Member member = (Member) LocalDataUtil.getVar(Constants.MEMBER_INFO);
LocalDateTime optDate = LocalDateTime.now();
//更新售后单状态
UpdateWrapper<Aftersale> aftersaleUpdateWrapper = new UpdateWrapper<>();
aftersaleUpdateWrapper.eq("id", aftersale.getId());
aftersaleUpdateWrapper.set("status", AftersaleStatus.CANCEL.getType());
aftersaleUpdateWrapper.set("update_time", optDate);
aftersaleUpdateWrapper.set("update_by", member.getId());
int rows = aftersaleMapper.update(null, aftersaleUpdateWrapper);
if (rows < 1){
throw new RuntimeException("更新售后单失败");
}
//更新订单售后状态
// 更新订单
UpdateWrapper<Order> updateOrderWrapper = new UpdateWrapper<>();
updateOrderWrapper.eq("id", orderId)
.set("aftersale_status", OrderRefundStatus.NO_REFUND.getType()).set("update_time", optDate)
.set("update_by", member.getId());
rows = orderMapper.update(null, updateOrderWrapper);
if (rows != 1) {
throw new RuntimeException("更新订单状态失败");
}
return "售后取消成功";
}
/**
*
* @param orderId id
* @return
*/
public AftersaleRefundInfoVO refundOrderDetail(Long orderId) {
QueryWrapper<Aftersale> aftersaleQw = new QueryWrapper<>();
aftersaleQw.eq("order_id", orderId);
aftersaleQw.orderByDesc("create_time");
aftersaleQw.last("limit 1");
Aftersale aftersale = aftersaleMapper.selectOne(aftersaleQw);
if (aftersale == null){
throw new RuntimeException("未查询到售后订单");
}
//查一下售后订单item
QueryWrapper<AftersaleItem> aftersaleItemQw = new QueryWrapper<>();
aftersaleItemQw.eq("aftersale_id", aftersale.getId());
List<AftersaleItem> aftersaleItemList = aftersaleItemMapper.selectList(aftersaleItemQw);
List<Long> orderItemIdList = aftersaleItemList.stream().map(AftersaleItem::getOrderItemId).collect(Collectors.toList());
//再去查orderItem
QueryWrapper<OrderItem> orderItemQw = new QueryWrapper<>();
orderItemQw.in("id", orderItemIdList);
List<OrderItem> orderItemList = orderItemMapper.selectList(orderItemQw);
AftersaleRefundInfoVO vo = new AftersaleRefundInfoVO();
BeanUtils.copyProperties(aftersale, vo);
vo.setAftersaleItemList(aftersaleItemConvert.dos2vos(aftersaleItemList));
vo.setOrderItemList(orderItemConvert.dos2vos(orderItemList));
return vo;
}
}