售后退款问题修复

This commit is contained in:
徐唯轩
2023-11-22 19:01:45 +08:00
parent e49f2a5d24
commit 3495a23492
351 changed files with 437 additions and 17511 deletions

View File

@ -1,5 +1,6 @@
package co.yixiang.yshop.module.order.controller.admin.storeaftersales.vo;
import co.yixiang.yshop.framework.desensitize.core.slider.annotation.MobileDesensitize;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.math.BigDecimal;
@ -50,6 +51,7 @@ public class StoreAfterSalesBaseVO {
@Schema(description = "商家收货人")
private String consignee;
@MobileDesensitize
@Schema(description = "商家手机号")
private String phoneNumber;

View File

@ -29,4 +29,8 @@ public class StoreAfterSalesRespVO extends StoreAfterSalesBaseVO {
@Schema(description = "退货凭证", required = true)
private String returnVoucher;
@Schema(description = "退货说明", required = true, example = "0")
private String returnPolicy;
}

View File

@ -47,8 +47,8 @@ public class AppOrderAfterSalesController {
@GetMapping("/applyForAfterSales/{key}")
@Operation(summary = "查询订单详情")
@Parameter(name = "key", description = "唯一的uni值或者订单号", required = true, example = "10")
public CommonResult<List<AppStoreOrderCartInfoVo>> checkOrderDetails(@PathVariable String key) {
return success(appStoreAfterSalesService.checkOrderDetails(key));
public CommonResult<List<AppStoreOrderCartInfoVo>> checkOrderDetails(@PathVariable String key, @RequestParam(value = "goods", defaultValue = "") String goods) {
return success(appStoreAfterSalesService.checkOrderDetails(key, goods));
}
@PreAuthenticated

View File

@ -100,4 +100,7 @@ public class AppStoreOrderAfterSalesDetailVo implements Serializable {
@Schema(description = "收货状态0、未收到1、已收到", required = true, example = "0")
private Integer receivingStatus;
/** 剩余自动确认时间 */
private String remainTime;
}

View File

@ -50,4 +50,12 @@ public class AppStoreOrderCartInfoVo {
/** 售后状态-0正常1用户取消2商家拒绝 */
private Integer salesState;
/** 优惠金额 */
private BigDecimal couponPrice;
/** 邮费价格 */
private BigDecimal postagePrice;
/** 订单状态 */
private Integer status;
}

View File

@ -174,6 +174,11 @@ public class AppStoreOrderQueryVo implements Serializable {
@Schema(description = "发货时间" )
private LocalDateTime deliveryTime;
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@Schema(description = "更新时间")
private LocalDateTime updateTime;
/**
* 支付信息
*/

View File

@ -238,4 +238,9 @@ public class StoreOrderDO extends BaseDO {
*/
private String payInfo;
/**
* 订单地址在城市id
*/
private Integer cityId;
}

View File

@ -1,6 +1,8 @@
package co.yixiang.yshop.module.order.dal.dataobject.storeordercartinfo;
import lombok.*;
import java.math.BigDecimal;
import java.util.*;
import com.baomidou.mybatisplus.annotation.*;
import co.yixiang.yshop.framework.mybatis.core.dataobject.BaseDO;
@ -54,4 +56,13 @@ public class StoreOrderCartInfoDO {
*/
private Integer isAfterSales;
/**
* 优惠金额
*/
private BigDecimal couponPrice;
/**
* 邮费金额
*/
private BigDecimal postagePrice;
}

View File

@ -29,5 +29,9 @@ public interface RedisKeyConstants {
"yshop_admin_order_count_cache:", // 参数为访问uid
STRING, CacheDto.class, RedisKeyDefine.TimeoutTypeEnum.FOREVER);
RedisKeyDefine YSHOP_ORDER_STATUS_KEY = new RedisKeyDefine("订单售后前装态",
"yshop_order_status:%s", // 参数为访问uid+key
STRING, Integer.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC);
}

View File

@ -1,17 +1,12 @@
package co.yixiang.yshop.module.order.dal.redis.order;
import cn.hutool.core.util.IdUtil;
import co.yixiang.yshop.framework.common.constant.ShopConstants;
import co.yixiang.yshop.framework.common.util.json.JsonUtils;
import co.yixiang.yshop.module.member.controller.app.user.vo.AppUserOrderCountVo;
import co.yixiang.yshop.module.order.service.storeorder.dto.CacheDto;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
import static co.yixiang.yshop.module.order.dal.redis.RedisKeyConstants.YSHOP_ORDER_CACHE_KEY;
import static co.yixiang.yshop.module.order.dal.redis.RedisKeyConstants.YSHOP_ORDER_COUNT_CACHE_KEY;
/**

View File

@ -4,6 +4,7 @@ import cn.hutool.core.thread.ExecutorBuilder;
import cn.hutool.core.thread.ThreadFactoryBuilder;
import cn.hutool.core.util.StrUtil;
import co.yixiang.yshop.framework.common.constant.ShopConstants;
import co.yixiang.yshop.module.order.service.storeaftersales.StoreAfterSalesService;
import co.yixiang.yshop.module.order.service.storeorder.AppStoreOrderService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@ -30,13 +31,16 @@ public class RedisDelayHandle {
@Resource
private AppStoreOrderService appStoreOrderService;
@Resource
private StoreAfterSalesService storeAfterSalesService;
@PostConstruct
public void startJobTimer() {
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNamePrefix("delay-job-service").build();
log.info("========延时队列开始=========");
ExecutorService executorService = ExecutorBuilder.create()
.setCorePoolSize(2)
.setCorePoolSize(4)
.setMaxPoolSize(10)
.setKeepAliveTime(0)
.setThreadFactory(threadFactory)
@ -44,6 +48,7 @@ public class RedisDelayHandle {
executorService.execute(new ExecutorTaskUnPay());
executorService.execute(new ExecutorTaskUnConfirm());
executorService.execute(new ExecutorTaskAfterSalesConfirm());
}
class ExecutorTaskUnPay implements Runnable {
@ -63,7 +68,6 @@ public class RedisDelayHandle {
} catch (Exception e) {
log.error("延时取消订单消费失败,"+e.getMessage());
}
}
}
}
@ -80,13 +84,32 @@ public class RedisDelayHandle {
try {
unConfirmOrderId = blockingUnConfirmDeque.take();
log.info("获取到待确认收货订单id{}", unConfirmOrderId);
if (StrUtil.isNotEmpty(unConfirmOrderId)) {
appStoreOrderService.takeOrder(unConfirmOrderId, null);
}
} catch (Exception e) {
log.error("延时确认收货失败,"+e.getMessage());
}
if (StrUtil.isNotEmpty(unConfirmOrderId)) {
appStoreOrderService.takeOrder(unConfirmOrderId, null);
}
}
}
}
class ExecutorTaskAfterSalesConfirm implements Runnable {
@SneakyThrows
@Override
public void run() {
RBlockingDeque<Long> blockingUnConfirmDeque = redissonClient
.getBlockingDeque(ShopConstants.REDIS_AFTERSALESORDER_UNCONFIRM);
while (true) {
log.info("======延时售后用户确认收货循环任务=====");
Long unConfirmOrderId;
try {
unConfirmOrderId = blockingUnConfirmDeque.take();
log.info("获取到待确认售后用户收货订单id{}", unConfirmOrderId);
storeAfterSalesService.taskAfterSalesConfirm(unConfirmOrderId);
} catch (Exception e) {
log.error("延时确认售后用户收货失败,"+e.getMessage());
}
}
}
}

View File

@ -29,9 +29,10 @@ public interface AppStoreAfterSalesService extends IService<StoreAfterSalesDO> {
/**
* 查询订单详情
* @param key 订单号
* @param goods 商品规格
* @return
*/
List<AppStoreOrderCartInfoVo> checkOrderDetails(String key);
List<AppStoreOrderCartInfoVo> checkOrderDetails(String key, String goods);
/**
* 查询订单详情

View File

@ -1,9 +1,9 @@
package co.yixiang.yshop.module.order.service.storeaftersales;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.yshop.framework.common.constant.ShopConstants;
import co.yixiang.yshop.framework.common.enums.OrderInfoEnum;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.module.order.controller.app.afterorder.param.AppProsuctParam;
@ -26,20 +26,25 @@ import co.yixiang.yshop.module.order.dal.mysql.storeorder.StoreOrderMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeordercartinfo.StoreOrderCartInfoMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeorderstatus.StoreOrderStatusMapper;
import co.yixiang.yshop.module.order.dal.redis.ofterorder.AfterOrderRedisDAO;
import co.yixiang.yshop.module.order.enums.AfterChangeTypeEnum;
import co.yixiang.yshop.module.order.enums.AfterSalesStatusEnum;
import co.yixiang.yshop.module.order.enums.AfterStatusEnum;
import co.yixiang.yshop.module.order.enums.OrderLogEnum;
import co.yixiang.yshop.module.order.enums.*;
import co.yixiang.yshop.module.order.service.storeaftersalesstatus.StoreAfterSalesStatusService;
import co.yixiang.yshop.module.order.service.storeorder.AppStoreOrderServiceImpl;
import co.yixiang.yshop.module.order.service.storeorderstatus.StoreOrderStatusService;
import co.yixiang.yshop.module.product.controller.app.cart.vo.AppStoreCartQueryVo;
import co.yixiang.yshop.module.product.service.productcouponrelation.AppCouponRelationService;
import com.alibaba.fastjson.JSON;
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.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@ -48,9 +53,15 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static co.yixiang.yshop.framework.common.enums.OrderInfoEnum.STATUS_DEFAULT;
import static co.yixiang.yshop.framework.common.enums.OrderInfoEnum.UNABLE_AFTER_SALES;
import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.module.order.enums.AfterSalesStatusEnum.USER_CANCELLED;
import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.*;
@ -62,6 +73,7 @@ import static co.yixiang.yshop.module.order.enums.OrderLogEnum.APPLY_AFTER_SALES
* @author yshop
*/
@Service
@Slf4j
@Validated
public class AppStoreAfterSalesServiceImpl extends ServiceImpl<StoreAfterSalesMapper, StoreAfterSalesDO> implements AppStoreAfterSalesService {
@Resource
@ -78,6 +90,11 @@ public class AppStoreAfterSalesServiceImpl extends ServiceImpl<StoreAfterSalesMa
private StoreAfterSalesStatusService storeAfterSalesStatusService;
@Resource
private StoreOrderStatusMapper storeOrderStatusMapper;
@Resource
private StoreOrderStatusService storeOrderStatusService;
@Resource
private RedissonClient redissonClient;
/**
* 创建售后订单
@ -93,58 +110,36 @@ public class AppStoreAfterSalesServiceImpl extends ServiceImpl<StoreAfterSalesMa
System.out.println("storeAfterSalesParam:" + storeAfterSalesParam);
afterOrderRedisDAO.set(userId, storeAfterSalesParam.getOrderId(), yxStoreOrder.getStatus().toString());
checkOrder(yxStoreOrder);
//商品除去优惠后的总价格
BigDecimal totalPrice = BigDecimal.ZERO;
// 退款金额
BigDecimal refundAmount = BigDecimal.ZERO;
//拿到所有的商品
List<StoreOrderCartInfoDO> yxStoreOrderCartInfos = storeOrderCartInfoMapper.selectList(Wrappers.<StoreOrderCartInfoDO>lambdaQuery().eq(StoreOrderCartInfoDO::getOid, yxStoreOrder.getId()));
List<StoreAfterSalesItemDO> insertAfterSalesItems = new ArrayList<>();
// 所有商品规格合集
Set<String> allProductAttrUniqueSet = new HashSet<>();
// 发货标识
boolean sendFlag = STATUS_DEFAULT.getValue().equals(yxStoreOrder.getStatus());
for (StoreOrderCartInfoDO yxStoreOrderCartInfo : yxStoreOrderCartInfos) {
AppStoreCartQueryVo cartInfo = JSONObject.parseObject(yxStoreOrderCartInfo.getCartInfo(), AppStoreCartQueryVo.class);
allProductAttrUniqueSet.add(cartInfo.getProductAttrUnique());
// 过滤出对应规格的商品
AppProsuctParam productParam = storeAfterSalesParam.getProductParamList().stream()
.filter(item -> cartInfo.getProductAttrUnique().equals(item.getProductAttrUnique()))
.findFirst().orElse(new AppProsuctParam());
if (productParam.getProductId() != null) {
//商品优惠前总金额
// 商品优惠前总金额
BigDecimal totalAmountOfGoods = NumberUtil.mul(cartInfo.getTruePrice(), cartInfo.getCartNum());
//该项商品优惠金额
BigDecimal commodityDiscountAmount = null;
if (yxStoreOrder.getTotalPrice().compareTo(yxStoreOrder.getPayPostage()) == 0) {
commodityDiscountAmount = totalAmountOfGoods;
} else {
commodityDiscountAmount = NumberUtil.mul(NumberUtil.div(totalAmountOfGoods, NumberUtil
.sub(yxStoreOrder.getTotalPrice().add(yxStoreOrder.getCouponPrice()),
yxStoreOrder.getPayPostage())), yxStoreOrder.getCouponPrice());
refundAmount = refundAmount.add(totalAmountOfGoods).subtract(yxStoreOrderCartInfo.getCouponPrice());
// 未发货退运费
if (sendFlag) {
refundAmount = refundAmount.add(yxStoreOrderCartInfo.getPostagePrice());
}
//商品优惠后总金额
totalPrice = NumberUtil.add(totalPrice, NumberUtil.sub(totalAmountOfGoods, commodityDiscountAmount));
yxStoreOrderCartInfo.setIsAfterSales(0);
yxStoreOrderCartInfo.setIsAfterSales(UNABLE_AFTER_SALES.getValue());
storeOrderCartInfoMapper.updateById(yxStoreOrderCartInfo);
// 售后明细
StoreAfterSalesItemDO storeAfterSalesItem = new StoreAfterSalesItemDO();
storeAfterSalesItem.setProductId(yxStoreOrderCartInfo.getProductId());
storeAfterSalesItem.setCartInfo(yxStoreOrderCartInfo.getCartInfo());
insertAfterSalesItems.add(storeAfterSalesItem);
}
}
// 退货商品规格合集
Set<String> returnProductAttrUniqueSet =
storeAfterSalesParam.getProductParamList().stream()
.map(AppProsuctParam::getProductAttrUnique).collect(Collectors.toSet());
// 全部退货且未发货退运费
if (allProductAttrUniqueSet.equals(returnProductAttrUniqueSet) &&
OrderInfoEnum.STATUS_DEFAULT.getValue().equals(yxStoreOrder.getStatus())) {
totalPrice = NumberUtil.add(totalPrice, yxStoreOrder.getPayPostage());
}
//更新订单状态
yxStoreOrder.setStatus(OrderInfoEnum.STATUS_APPLY_REFUND.getValue());
yxStoreOrder.setRefundStatus(OrderInfoEnum.REFUND_STATUS_BEING_REFUNDED.getValue());
@ -155,42 +150,33 @@ public class AppStoreAfterSalesServiceImpl extends ServiceImpl<StoreAfterSalesMa
//生成售后订单
StoreAfterSalesDO storeAfterSales = new StoreAfterSalesDO();
storeAfterSales.setOrderCode(storeAfterSalesParam.getOrderId());
storeAfterSales.setRefundAmount(totalPrice);
storeAfterSales.setRefundAmount(refundAmount);
storeAfterSales.setServiceType(storeAfterSalesParam.getServiceType());
storeAfterSales.setReasons(storeAfterSalesParam.getReasonForApplication());
storeAfterSales.setExplains(storeAfterSalesParam.getApplicationInstructions());
storeAfterSales.setExplainImg(storeAfterSalesParam.getApplicationDescriptionPicture());
storeAfterSales.setState(AfterSalesStatusEnum.PENDING_REVIEW.getValue());
// storeAfterSales.setSalesState(AfterStatusEnum.STATE_0.getValue());
storeAfterSales.setReceivingStatus(storeAfterSalesParam.getReceivingStatus());
storeAfterSales.setCreateTime(LocalDateTime.now());
storeAfterSales.setUserId(userId);
this.baseMapper.insert(storeAfterSales);
insertAfterSalesItems.forEach(res -> {
res.setStoreAfterSalesId(storeAfterSales.getId());
});
insertAfterSalesItems.forEach(res -> res.setStoreAfterSalesId(storeAfterSales.getId()));
// 售后明细批量保存
storeAfterSalesItemMapper.insertBatch(insertAfterSalesItems);
/*for (AppProsuctParam productParam : storeAfterSalesParam.getProductParamList()) {
StoreOrderCartInfoDO yxStoreOrderCartInfo =
yxStoreOrderCartInfos.stream().filter(item -> productParam.getProductId().equals(item.getProductId()))
.findFirst().orElse(new StoreOrderCartInfoDO());
StoreAfterSalesItemDO storeAfterSalesItem = new StoreAfterSalesItemDO();
storeAfterSalesItem.setStoreAfterSalesId(storeAfterSales.getId());
storeAfterSalesItem.setProductId(yxStoreOrderCartInfo.getProductId());
storeAfterSalesItem.setCartInfo(yxStoreOrderCartInfo.getCartInfo());
storeAfterSalesItemMapper.insert(storeAfterSalesItem);
}*/
StoreOrderStatusDO orderStatusDO = StoreOrderStatusDO.builder()
.oid(yxStoreOrder.getId()).changeType(APPLY_AFTER_SALES.getValue())
.changeMessage(APPLY_AFTER_SALES.getDesc()).changeTime(LocalDateTime.now()).build();
// 记录订单操作
storeOrderStatusMapper.insert(orderStatusDO);
//操作记录
storeOrderStatusService.create(yxStoreOrder.getUid(), yxStoreOrder.getId(),
APPLY_AFTER_SALES.getValue(), APPLY_AFTER_SALES.getDesc());
// 售后操作记录
storeAfterSalesStatusService.create(storeAfterSales.getUserId(), storeAfterSales.getId(),
AfterChangeTypeEnum.CREATE_AFTER_SALES.getValue(), AfterChangeTypeEnum.CREATE_AFTER_SALES.getDesc());
//加入自动收货延迟队列
RBlockingDeque<Object> blockingDeque = redissonClient.getBlockingDeque(ShopConstants.REDIS_AFTERSALESORDER_UNCONFIRM);
RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
delayedQueue.offer(storeAfterSales.getId(), ShopConstants.AFTER_SALES_ORDER_OUTTIME_UNCONFIRM, TimeUnit.DAYS);
String s = ShopConstants.AFTER_SALES_ORDER_OUTTIME_UNCONFIRM + "";
log.info("添加延时队列成功 ,延迟时间:" + s);
return storeAfterSales.getId();
}
@ -227,34 +213,38 @@ public class AppStoreAfterSalesServiceImpl extends ServiceImpl<StoreAfterSalesMa
storeOrderStatusMapper.selectOne(new LambdaQueryWrapper<StoreOrderStatusDO>()
.eq(StoreOrderStatusDO::getOid, storeOrderDO.getId())
.eq(StoreOrderStatusDO::getChangeType, OrderLogEnum.DELIVERY_GOODS.getValue()));
//计算创建售后到自动确认时间
int offset = Integer.parseInt(String.valueOf(ShopConstants.ORDER_OUTTIME_UNCONFIRM));
log.info("time" + afterSales.getCreateTime());
LocalDateTime time = afterSales.getCreateTime().plusDays(offset);
long remainTime = afterSales.getState().equals(AfterStatusEnum.STATE_0.getValue()) ?
time.toEpochSecond(ZoneOffset.ofHours(8)) * 1000 - System.currentTimeMillis() : 0;
// 数据整合
AppStoreOrderAfterSalesDetailVo result =
AppStoreOrderAfterSalesDetailVo.builder()
// 售后信息
.id(afterSales.getId())
.refundAmount(afterSales.getRefundAmount()).reasons(afterSales.getReasons())
.explains(afterSales.getExplains()).explainImg(afterSales.getExplainImg())
.state(afterSales.getState()).salesState(afterSales.getSalesState())
.realName(afterSales.getConsignee())
.userPhone(afterSales.getPhoneNumber())
.userAddress(afterSales.getAddress())
.receivingStatus(afterSales.getReceivingStatus())
.serviceType(afterSales.getServiceType())
// 订单信息
.orderId(storeOrderDO.getOrderId()).uid(storeOrderDO.getUid())
.createTime(storeOrderDO.getCreateTime())
.payPrice(storeOrderDO.getPayPrice()).totalPrice(totalPrice)
.totalPostage(storeOrderDO.getTotalPostage()).deductionPrice(storeOrderDO.getDeductionPrice())
.deliveryTime(orderStatusDO == null ? null : orderStatusDO.getChangeTime())
.payTime(storeOrderDO.getPayTime())
.couponPrice(storeOrderDO.getCouponPrice())
// 商品数据
.cartInfo(cartInfo)
// 物流数据
.deliverySn(afterSales.getDeliverySn()).deliveryName(afterSales.getDeliveryName())
.build();
return result;
return AppStoreOrderAfterSalesDetailVo.builder()
// 售后信息
.id(afterSales.getId())
.refundAmount(afterSales.getRefundAmount()).reasons(afterSales.getReasons())
.explains(afterSales.getExplains()).explainImg(afterSales.getExplainImg())
.state(afterSales.getState()).salesState(afterSales.getSalesState())
.realName(afterSales.getConsignee())
.userPhone(afterSales.getPhoneNumber())
.userAddress(afterSales.getAddress())
.receivingStatus(afterSales.getReceivingStatus())
.serviceType(afterSales.getServiceType())
// 订单信息
.orderId(storeOrderDO.getOrderId()).uid(storeOrderDO.getUid())
.createTime(storeOrderDO.getCreateTime())
.payPrice(storeOrderDO.getPayPrice()).totalPrice(totalPrice)
.totalPostage(storeOrderDO.getTotalPostage()).deductionPrice(storeOrderDO.getDeductionPrice())
.deliveryTime(orderStatusDO == null ? null : orderStatusDO.getChangeTime())
.payTime(storeOrderDO.getPayTime())
.couponPrice(storeOrderDO.getCouponPrice())
// 商品数据
.cartInfo(cartInfo)
// 物流数据
.deliverySn(afterSales.getDeliverySn()).deliveryName(afterSales.getDeliveryName())
.remainTime(String.valueOf(remainTime))
.build();
}
/**
@ -264,7 +254,7 @@ public class AppStoreAfterSalesServiceImpl extends ServiceImpl<StoreAfterSalesMa
* @return 订单详情列表
*/
@Override
public List<AppStoreOrderCartInfoVo> checkOrderDetails(String key) {
public List<AppStoreOrderCartInfoVo> checkOrderDetails(String key, String goods) {
LambdaQueryWrapper<StoreOrderCartInfoDO> wrapper = new LambdaQueryWrapper<>();
wrapper.and(i -> i.eq(StoreOrderCartInfoDO::getOrderId, key)
.or().eq(StoreOrderCartInfoDO::getUnique, key).or()
@ -273,41 +263,40 @@ public class AppStoreAfterSalesServiceImpl extends ServiceImpl<StoreAfterSalesMa
if (yxStoreOrderCartInfos == null || yxStoreOrderCartInfos.isEmpty()) {
throw exception(STORE_ORDER_NOT_EXISTS);
}
// 查询订单信息
StoreOrderDO yxStoreOrder = storeOrderMapper.selectOne(Wrappers.<StoreOrderDO>lambdaQuery().eq(StoreOrderDO::getOrderId, yxStoreOrderCartInfos.get(0).getOrderId()));
//查询 售后信息
// StoreAfterSalesDO storeAfterSales = this.baseMapper.selectOne(Wrappers.<StoreAfterSalesDO>lambdaQuery()
// .eq(StoreAfterSalesDO::getOrderCode, yxStoreOrder.getOrderId()));
List<AppStoreOrderCartInfoVo> yxStoreOrderCartInfoVos = new ArrayList<>();
List<String> productAttrUniques = null;
if (StringUtils.isNotBlank(goods)) {
productAttrUniques = Arrays.asList(goods.split(","));
}
for (StoreOrderCartInfoDO yxStoreOrderCartInfo : yxStoreOrderCartInfos) {
AppStoreCartQueryVo cartInfo = JSONObject.parseObject(yxStoreOrderCartInfo.getCartInfo(), AppStoreCartQueryVo.class);
if (CollectionUtils.isNotEmpty(productAttrUniques) && !productAttrUniques.contains(cartInfo.getProductAttrUnique())) {
continue;
}
AppStoreOrderCartInfoVo yxStoreOrderCartInfoVo = new AppStoreOrderCartInfoVo();
yxStoreOrderCartInfoVo.setId(yxStoreOrderCartInfo.getId());
yxStoreOrderCartInfoVo.setOid(yxStoreOrderCartInfo.getOid());
yxStoreOrderCartInfoVo.setOrderId(yxStoreOrderCartInfo.getOrderId());
yxStoreOrderCartInfoVo.setCartId(yxStoreOrderCartInfo.getCartId());
yxStoreOrderCartInfoVo.setProductId(yxStoreOrderCartInfo.getProductId());
AppStoreCartQueryVo cartInfo = JSONObject.parseObject(yxStoreOrderCartInfo.getCartInfo(), AppStoreCartQueryVo.class);
yxStoreOrderCartInfoVo.setCouponPrice(yxStoreOrderCartInfo.getCouponPrice());
yxStoreOrderCartInfoVo.setPostagePrice(yxStoreOrderCartInfo.getPostagePrice());
yxStoreOrderCartInfoVo.setCartInfo(cartInfo);
yxStoreOrderCartInfoVo.setUnique(yxStoreOrderCartInfo.getUnique());
yxStoreOrderCartInfoVo.setIsAfterSales(yxStoreOrderCartInfo.getIsAfterSales() == null ? 0 : yxStoreOrderCartInfo.getIsAfterSales());
//商品优惠前总金额
// 商品优惠前总金额
BigDecimal totalAmountOfGoods = NumberUtil.mul(cartInfo.getTruePrice(), cartInfo.getCartNum());
//商品优惠金额
// BigDecimal commodityDiscountAmount = BigDecimal.ZERO;
// if()
BigDecimal commodityDiscountAmount = null;
// 运费金额等于商品总价
if (yxStoreOrder.getTotalPrice().compareTo(yxStoreOrder.getPayPostage()) == 0) {
commodityDiscountAmount = totalAmountOfGoods;
} else {
commodityDiscountAmount = NumberUtil.mul(NumberUtil.div(totalAmountOfGoods, NumberUtil
.sub(yxStoreOrder.getTotalPrice().add(yxStoreOrder.getCouponPrice()),
yxStoreOrder.getPayPostage())), yxStoreOrder.getCouponPrice());
// 优惠金额
BigDecimal couponAfterAmount = NumberUtil.sub(totalAmountOfGoods, yxStoreOrderCartInfo.getCouponPrice());
BigDecimal postagePrice = BigDecimal.ZERO;
// 未发货退运费
if (STATUS_DEFAULT.getValue().equals(yxStoreOrder.getStatus())) {
postagePrice = yxStoreOrderCartInfo.getPostagePrice();
}
yxStoreOrderCartInfoVo.setRefundablePrice(NumberUtil.sub(totalAmountOfGoods, commodityDiscountAmount));
//yxStoreOrderCartInfoVo.setReasons(storeAfterSales.getReasons());
yxStoreOrderCartInfoVo.setStatus(yxStoreOrder.getStatus());
yxStoreOrderCartInfoVo.setRefundablePrice(NumberUtil.add(couponAfterAmount, postagePrice));
yxStoreOrderCartInfoVos.add(yxStoreOrderCartInfoVo);
}
@ -320,7 +309,7 @@ public class AppStoreAfterSalesServiceImpl extends ServiceImpl<StoreAfterSalesMa
* 查询列表
*
* @param uid 用户id
* @param status 状态 //状态 0已提交等待平台审核 1平台已审核 等待用户发货/退款 2 用户已发货 3退款成功
* // * @param status 状态 //状态 0已提交等待平台审核 1平台已审核 等待用户发货/退款 2 用户已发货 3退款成功
* @param page 页
* @param orderCode 订单编码
* @param limit 数量
@ -434,7 +423,7 @@ public class AppStoreAfterSalesServiceImpl extends ServiceImpl<StoreAfterSalesMa
StoreOrderDO yxStoreOrder = storeOrderMapper.selectOne(Wrappers.<StoreOrderDO>lambdaQuery().eq(StoreOrderDO::getOrderId, key));
String o = afterOrderRedisDAO.get(key, uid);
yxStoreOrder.setStatus(o == null ? 0 : Integer.parseInt(o));
yxStoreOrder.setRefundStatus(OrderInfoEnum.STATUS_DEFAULT.getValue());
yxStoreOrder.setRefundStatus(STATUS_DEFAULT.getValue());
storeOrderMapper.updateById(yxStoreOrder);
List<StoreOrderCartInfoDO> yxStoreOrderCartInfos = storeOrderCartInfoMapper.selectList(Wrappers.<StoreOrderCartInfoDO>lambdaQuery()
@ -461,7 +450,7 @@ public class AppStoreAfterSalesServiceImpl extends ServiceImpl<StoreAfterSalesMa
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public Boolean addLogisticsInformation(AppReturnLogisticsParam param) {
StoreAfterSalesDO storeAfterSales = getById(param.getId());
// .eq(StoreAfterSalesDO::getOrderCode, param.getOrderCode()));
// .eq(StoreAfterSalesDO::getOrderCode, param.getOrderCode()));
if (!storeAfterSales.getState().equals(AfterSalesStatusEnum.AUDITED.getValue())) {
throw exception(ORDER_STATUS_NOT_EXPRESS_);
}
@ -533,7 +522,7 @@ public class AppStoreAfterSalesServiceImpl extends ServiceImpl<StoreAfterSalesMa
throw exception(STORE_ORDER_NOT_EXISTS);
}
if (!yxStoreOrder.getPaid().equals(OrderInfoEnum.PAY_STATUS_HAVE_PAID.getValue()) || !yxStoreOrder.getRefundStatus().equals(OrderInfoEnum.REFUND_STATUS_NORMAL.getValue()) || yxStoreOrder.getStatus() < OrderInfoEnum.STATUS_DEFAULT.getValue()) {
if (!yxStoreOrder.getPaid().equals(OrderInfoEnum.PAY_STATUS_HAVE_PAID.getValue()) || !yxStoreOrder.getRefundStatus().equals(OrderInfoEnum.REFUND_STATUS_NORMAL.getValue()) || yxStoreOrder.getStatus() < STATUS_DEFAULT.getValue()) {
throw exception(ORDER_REFUND_NOT);
}
}

View File

@ -24,6 +24,7 @@ public interface StoreAfterSalesService {
void updateStoreAfterSales(@Valid StoreAfterSalesUpdateReqVO updateReqVO) throws Exception;
void taskAfterSalesConfirm(Long id) throws Exception;
/**
* 立即退款
*

View File

@ -1,6 +1,7 @@
package co.yixiang.yshop.module.order.service.storeaftersales;
import co.yixiang.yshop.framework.common.enums.OrderInfoEnum;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.framework.common.pojo.PageResult;
import co.yixiang.yshop.module.member.controller.admin.user.vo.UserRespVO;
import co.yixiang.yshop.module.member.convert.user.UserConvert;
@ -13,10 +14,13 @@ import co.yixiang.yshop.module.order.convert.storeaftersales.StoreAfterSalesConv
import co.yixiang.yshop.module.order.dal.dataobject.storeaftersales.StoreAfterSalesDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeaftersalesitem.StoreAfterSalesItemDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeorder.StoreOrderDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeordercartinfo.StoreOrderCartInfoDO;
import co.yixiang.yshop.module.order.dal.mysql.storeaftersales.StoreAfterSalesMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeaftersalesitem.StoreAfterSalesItemMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeorder.StoreOrderMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeordercartinfo.StoreOrderCartInfoMapper;
import co.yixiang.yshop.module.order.dal.redis.ofterorder.AfterOrderRedisDAO;
import co.yixiang.yshop.module.order.dal.redis.order.OrderStatusRedisDAO;
import co.yixiang.yshop.module.order.enums.AfterChangeTypeEnum;
import co.yixiang.yshop.module.order.enums.AfterSalesStatusEnum;
import co.yixiang.yshop.module.order.enums.AfterTypeEnum;
@ -29,7 +33,6 @@ import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
@ -61,6 +64,8 @@ public class StoreAfterSalesServiceImpl implements StoreAfterSalesService {
@Resource
private StoreAfterSalesStatusService storeAfterSalesStatusService;
@Resource
private StoreOrderCartInfoMapper storeOrderCartInfoMapper;
@Override
@ -73,6 +78,12 @@ public class StoreAfterSalesServiceImpl implements StoreAfterSalesService {
}
@Override
public void taskAfterSalesConfirm(Long id) throws Exception {
StoreAfterSalesDO storeAfterSales = storeAfterSalesMapper.selectById(id);
salesCheck(id,storeAfterSales.getOrderCode(),AfterTypeEnum.AGREE.getValue(),storeAfterSales.getConsignee(),storeAfterSales.getPhoneNumber(),storeAfterSales.getAddress());
}
/**
* 售后处理
* @param salesId 售后id
@ -108,14 +119,14 @@ public class StoreAfterSalesServiceImpl implements StoreAfterSalesService {
}else {
//仅仅退款直接退款
appStoreOrderService.orderRefund(storeAfterSales.getOrderCode(),storeAfterSales.getRefundAmount());
storeAfterSales.setState(AfterSalesStatusEnum.REFUND_SUCCESS.getValue());
storeAfterSalesStatusService.create(storeAfterSales.getUserId(),storeAfterSales.getId()
,AfterChangeTypeEnum.PAYMENT.getValue(),AfterChangeTypeEnum.PAYMENT.getDesc());
}
} else {//拒绝
} else {
//拒绝
storeAfterSales.setState(AfterSalesStatusEnum.MERCHANT_REJECTION.getValue());
// storeAfterSales.setSalesState(AfterTypeEnum.REFUSE.getValue());
//操作记录
@ -123,12 +134,19 @@ public class StoreAfterSalesServiceImpl implements StoreAfterSalesService {
,AfterChangeTypeEnum.AUDIT_FAILED.getValue(),AfterChangeTypeEnum.AUDIT_FAILED.getDesc());
StoreOrderDO yxStoreOrder = storeOrderMapper.selectOne(Wrappers.<StoreOrderDO>lambdaQuery().eq(StoreOrderDO::getOrderId, storeAfterSales.getOrderCode()));
String o = afterOrderRedisDAO.get(storeAfterSales.getOrderCode(),storeAfterSales.getUserId());
String o = afterOrderRedisDAO.get(yxStoreOrder.getOrderId(), yxStoreOrder.getUid());
yxStoreOrder.setStatus(o == null ? 0 : Integer.parseInt(o));
yxStoreOrder.setRefundStatus(OrderInfoEnum.STATUS_DEFAULT.getValue());
// 退款状态重置
yxStoreOrder.setRefundStatus(OrderInfoEnum.REFUND_STATUS_NORMAL.getValue());
storeOrderMapper.updateById(yxStoreOrder);
afterOrderRedisDAO.delete(storeAfterSales.getOrderCode(),storeAfterSales.getUserId());
// 订单详情重置是否售后字段
List<StoreOrderCartInfoDO> yxStoreOrderCartInfos = storeOrderCartInfoMapper.selectList(Wrappers.<StoreOrderCartInfoDO>lambdaQuery()
.eq(StoreOrderCartInfoDO::getOid, yxStoreOrder.getId()));
for (StoreOrderCartInfoDO yxStoreOrderCartInfo : yxStoreOrderCartInfos) {
yxStoreOrderCartInfo.setIsAfterSales(ShopCommonEnum.YES.getValue());
storeOrderCartInfoMapper.updateById(yxStoreOrderCartInfo);
}
}
storeAfterSalesMapper.updateById(storeAfterSales);
}

View File

@ -3,6 +3,7 @@ package co.yixiang.yshop.module.order.service.storeaftersalesstatus;
import co.yixiang.yshop.module.order.dal.dataobject.storeaftersalesstatus.StoreAfterSalesStatusDO;
import co.yixiang.yshop.module.order.dal.mysql.storeaftersalesstatus.StoreAfterSalesStatusMapper;
import co.yixiang.yshop.module.order.service.storeorder.AsyncStoreOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@ -24,8 +25,8 @@ import static co.yixiang.yshop.framework.security.core.util.SecurityFrameworkUti
public class StoreAfterSalesStatusServiceImpl implements StoreAfterSalesStatusService {
// @Resource
// private AsyncStoreOrderService asyncStoreOrderService;
@Autowired
private AsyncStoreOrderService asyncStoreOrderService;
@Resource
private StoreAfterSalesStatusMapper storeAfterSalesStatusMapper;
@ -49,7 +50,7 @@ public class StoreAfterSalesStatusServiceImpl implements StoreAfterSalesStatusSe
storeAfterSalesStatusMapper.insert(storeAfterSalesStatus);
//异步统计
// asyncStoreOrderService.orderData(uid);
asyncStoreOrderService.orderData(uid);
}
}

View File

@ -6,7 +6,6 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.yshop.framework.common.constant.ShopConstants;
import co.yixiang.yshop.framework.common.enums.OrderInfoEnum;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.framework.common.exception.ErrorCode;
import co.yixiang.yshop.framework.common.util.json.JsonUtils;
import co.yixiang.yshop.framework.common.util.servlet.ServletUtils;
@ -43,20 +42,19 @@ import co.yixiang.yshop.module.pay.PayContext;
import co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo.PayParam;
import co.yixiang.yshop.module.pay.dal.dataobject.merchantdetails.MerchantDetailsDO;
import co.yixiang.yshop.module.pay.service.merchantdetails.MerchantDetailsService;
import co.yixiang.yshop.module.pay.strategy.weixin.service.WxPayService;
import co.yixiang.yshop.module.pay.strategy.weixin.service.WxPayServiceUtils;
import co.yixiang.yshop.module.pay.strategy.weixin.skd.HttpKit;
import co.yixiang.yshop.module.pay.strategy.weixin.skd.PaymentApi;
import co.yixiang.yshop.module.pay.strategy.weixin.skd.PaymentKit;
import co.yixiang.yshop.module.pay.strategy.weixin.skd.RandomStringUtil;
import co.yixiang.yshop.module.product.controller.app.cart.vo.AppStoreCartQueryVo;
import co.yixiang.yshop.module.product.controller.app.couponrelation.vo.CartCouponDetailVO;
import co.yixiang.yshop.module.product.controller.app.couponrelation.vo.CartCouponVO;
import co.yixiang.yshop.module.product.controller.app.product.vo.AppStoreProductRespVo;
import co.yixiang.yshop.module.product.dal.dataobject.shippingtemplates.ShippingTemplatesDO;
import co.yixiang.yshop.module.product.dal.dataobject.shippingtemplatesfree.ShippingTemplatesFreeDO;
import co.yixiang.yshop.module.product.dal.dataobject.shippingtemplatesregion.ShippingTemplatesRegionDO;
import co.yixiang.yshop.module.product.dal.dataobject.storeproductreply.StoreProductReplyDO;
import co.yixiang.yshop.module.product.service.productcoupon.ProductCouponService;
import co.yixiang.yshop.module.product.service.productcouponrelation.AppCouponRelationService;
import co.yixiang.yshop.module.product.service.productcouponrelation.dto.CartCouponDto;
import co.yixiang.yshop.module.product.service.shippingtemplates.ShippingTemplatesService;
@ -67,6 +65,7 @@ import co.yixiang.yshop.module.product.service.storeproductreply.AppStoreProduct
import com.alibaba.fastjson.JSON;
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.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@ -96,6 +95,7 @@ import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -158,6 +158,9 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
@Resource
private PayServiceManager manager;
@Resource
private WxPayServiceUtils wxPayServiceUtils;
private static final String LOCK_KEY = "cart:check:stock:lock";
private static final String STOCK_LOCK_KEY = "cart:do:stock:lock";
@ -185,8 +188,8 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
//获取默认地址
UserAddressDO userAddress = appUserAddressService.getOne(Wrappers.<UserAddressDO>lambdaQuery()
.eq(UserAddressDO::getUid, uid)
.eq(param.getAddressId() != null, UserAddressDO::getId, param.getAddressId())
.eq(param.getAddressId() == null, UserAddressDO::getIsDefault, ShopCommonEnum.IS_DEFAULT.getValue()));
.eq(Objects.nonNull(param.getAddressId()) && param.getAddressId() != 0, UserAddressDO::getId, param.getAddressId())
.orderByDesc(UserAddressDO::getIsDefault).last("limit 1"));
List<AppStoreCartQueryVo> cartInfo = (List<AppStoreCartQueryVo>) cartGroup.get("valid");
PriceGroupDto priceGroup = this.getOrderPriceGroup(cartInfo, userAddress, param.getCouponId());
@ -247,7 +250,7 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
@Override
public Map<String, Object> computedOrder(Long uid, String key, AppComputeOrderParam param) {
//检查订单
Map<String, Object> map = this.check(uid, key, param);
Map<String, Object> map = this.check(uid, key);
if (OrderLogEnum.EXTEND_ORDER.getValue().equals(map.get("status"))) {
return map;
}
@ -281,7 +284,7 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
}
AppComputeVo appComputeVo = AppComputeVo.builder()
.totalPrice(cacheDTO.getPriceGroup().getTotalPrice())
.totalPrice(payPrice)
.payPrice(payPrice)
.payPostage(payPostage)
.couponPrice(couponPrice)
@ -365,12 +368,13 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
storeOrder.setUserPhone(userAddress.getPhone());
storeOrder.setUserAddress(userAddress.getProvince() + " " + userAddress.getCity() +
" " + userAddress.getDistrict() + " " + userAddress.getDetail());
storeOrder.setCityId(userAddress.getCityId());
storeOrder.setCartId(StrUtil.join(",", cartIds));
storeOrder.setTotalNum(totalNum);
storeOrder.setTotalPrice(computeVo.getTotalPrice());
storeOrder.setTotalPostage(computeVo.getPayPostage());
storeOrder.setCouponId(param.getCouponId() != null && param.getCouponId().compareTo(0l) > 0 ? param.getCouponId() : null);
storeOrder.setCouponId(param.getCouponId() != null && param.getCouponId().compareTo(0L) > 0 ? param.getCouponId() : null);
storeOrder.setCouponPrice(computeVo.getCouponPrice());
storeOrder.setPayPrice(computeVo.getPayPrice());
storeOrder.setPayPostage(computeVo.getPayPostage());
@ -499,21 +503,21 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
Map<String, String> packageParams = new HashMap<>();
if (param.getPaytype().contains(PayTypeEnum.ALI.getValue())) {
aliPay(orderInfo, param, packageParams);
updatePayInfo(orderInfo,packageParams);
}else if(param.getPaytype().contains(PayTypeEnum.WEIXIN.getValue())){
packageParams = payContext.selectPayWay(PayTypeEnum.WEIXIN.getValue(),
updatePayInfo(orderInfo, packageParams);
} else if (param.getPaytype().contains(PayTypeEnum.WEIXIN.getValue())) {
packageParams = payContext.selectPayWay(PayTypeEnum.WEIXIN.getValue(),
new PayParam(orderInfo.getOrderId(), orderInfo.getPayPrice(), userDO.getRoutineOpenid(), ServletUtils.getClientIP(),
param.getPaytype(), "Yshop商城", merchantDetailsDO));
updatePayInfo(orderInfo,packageParams);
}else if(param.getPaytype().contains(PayTypeEnum.YUE.getValue())){
yuePay(param.getUni(),uid);
updatePayInfo(orderInfo, packageParams);
} else if (param.getPaytype().contains(PayTypeEnum.YUE.getValue())) {
yuePay(param.getUni(), uid);
}
// 异步统计
asyncStoreOrderService.orderData(uid);
return packageParams;
}
private void updatePayInfo(AppStoreOrderQueryVo orderInfo, Map<String, String> packageParams){
private void updatePayInfo(AppStoreOrderQueryVo orderInfo, Map<String, String> packageParams) {
PayInfo payInfo = new PayInfo();
payInfo.setOrderId(orderInfo.getOrderId());
payInfo.setOut_trade_no(packageParams.get("out_trade_no"));
@ -526,17 +530,17 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
this.update(storeOrder, wrapper);
}
private void aliPay(AppStoreOrderQueryVo orderInfo, AppPayParam param, Map<String, String> packageParams ){
if(PayTypeEnum.ALI_H5.getValue().equals(param.getPaytype())){
private void aliPay(AppStoreOrderQueryVo orderInfo, AppPayParam param, Map<String, String> packageParams) {
if (PayTypeEnum.ALI_H5.getValue().equals(param.getPaytype())) {
MerchantPayOrder payOrder = new MerchantPayOrder("1", "WAP", "支付宝H5商品购买",
"h5商品购买", orderInfo.getPayPrice(), param.getUni()+"-"+ RandomStringUtil.getRandomCode(3,0)+"H5");
String str = manager.toPay(payOrder);
"h5商品购买", orderInfo.getPayPrice(), param.getUni() + "-" + RandomStringUtil.getRandomCode(3, 0) + "H5");
String str = manager.toPay(payOrder);
log.info(str);
// packageParams.put("data",manager.toPay(payOrder));
}else if(PayTypeEnum.ALI_APP.getValue().equals(param.getFrom())){
// packageParams.put("data",manager.toPay(payOrder));
} else if (PayTypeEnum.ALI_APP.getValue().equals(param.getFrom())) {
MerchantPayOrder payOrder = new MerchantPayOrder("1", "APP", "支付宝APP商品购买",
"支付宝APP5商品购买", orderInfo.getPayPrice(), param.getUni()+"-"+ RandomStringUtil.getRandomCode(3,0)+"APP");
// packageParams.put("data",manager.app(payOrder));
"支付宝APP5商品购买", orderInfo.getPayPrice(), param.getUni() + "-" + RandomStringUtil.getRandomCode(3, 0) + "APP");
// packageParams.put("data",manager.app(payOrder));
}
}
@ -591,7 +595,14 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
// throw exception(STORE_ORDER_PAY_FEE_ERROR);
//最简单做法 不一致退还支付金额,订单装态不变
assert payInfo != null;
Map map = new WxPayServiceUtils().refund(resultMap.get("transaction_id"), payInfo.getOut_refund_no(), orderInfo.getTotalPrice(), totalFee, merchantDetailsDO);
// 微信 根据不同付款方式进行退款 小程序 app
if (payInfo.getOut_trade_no().contains("APPLET")) {
merchantDetailsDO = merchantDetailsService.getMerchantDetails(PayTypeEnum.WEIXIN_APPLET.getCode());
} else {
//app 和h5 appId目前一样
merchantDetailsDO = merchantDetailsService.getMerchantDetails(PayTypeEnum.WEIXIN_H5.getCode());
}
Map map = wxPayServiceUtils.refund(resultMap.get("transaction_id"), payInfo.getOut_refund_no(), orderInfo.getTotalPrice(), totalFee, merchantDetailsDO);
log.info("退款详情:" + map);
String result = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
response.getWriter().write(result);
@ -816,7 +827,14 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
LambdaQueryWrapper<StoreOrderCartInfoDO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(StoreOrderCartInfoDO::getOid, order.getId());
List<StoreOrderCartInfoDO> cartInfos = storeOrderCartInfoService.list(wrapper);
// 查询是否发货 为后面待发货提前计算时间
StoreOrderStatusDO orderStatusDO =
storeOrderStatusMapper.selectOne(new LambdaQueryWrapper<StoreOrderStatusDO>()
.eq(StoreOrderStatusDO::getOid, order.getId())
.eq(StoreOrderStatusDO::getChangeType, OrderLogEnum.DELIVERY_GOODS.getValue()));
if (orderStatusDO != null) {
order.setDeliveryTime(orderStatusDO.getChangeTime());
}
List<AppStoreCartQueryVo> cartInfo = cartInfos.stream()
.map(cart -> {
AppStoreCartQueryVo cartQueryVo = JSON.parseObject(cart.getCartInfo(), AppStoreCartQueryVo.class);
@ -828,7 +846,7 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
order.setCartInfo(cartInfo);
StatusDto statusDTO = new StatusDto();
if (OrderStatusEnum.STATUS_WAIT_PAY.getValue().equals(order.getPaid())) {
if (OrderStatusEnum.STATUS_WAIT_PAY.getValue().equals(order.getPaid()) && !OrderInfoEnum.STATUS_CANCEL.getValue().equals(order.getStatus())) {
//计算未支付到自动取消订 时间
int offset = Integer.parseInt(String.valueOf(ShopConstants.ORDER_OUTTIME_UNPAY));
log.info("time" + order.getCreateTime());
@ -859,10 +877,16 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
}
} else if (OrderInfoEnum.STATUS_WAIT_RECEIVED.getValue().equals(order.getStatus())) {
//计算发货到自动收货 时间
int offset = Integer.parseInt(String.valueOf(ShopConstants.ORDER_OUTTIME_UNCONFIRM));
log.info("time" + order.getDeliveryTime());
LocalDateTime time = order.getDeliveryTime().plusDays(offset);
statusDTO.set_class("state-ysh");
statusDTO.set_msg("服务商已发货");
statusDTO.set_type("2");
statusDTO.set_title("待收货");
statusDTO.set_title(OrderInfoEnum.STATUS_WAIT_RECEIVED.getDesc());
statusDTO.set_msg("待收货," + StrUtil.format("{}自动确认", time.format(DateTimeFormatter.ofPattern(FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND))));
long remainTime = time.toEpochSecond(ZoneOffset.ofHours(8)) * 1000 - System.currentTimeMillis();
statusDTO.set_payRemainTime(String.valueOf(remainTime));
} else if (OrderInfoEnum.STATUS_RECEIVED.getValue().equals(order.getStatus())) {
statusDTO.set_class("state-ypj");
statusDTO.set_msg("已收货,快去评价一下吧");
@ -873,6 +897,11 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
statusDTO.set_msg("交易完成,感谢您的支持");
statusDTO.set_type("4");
statusDTO.set_title("交易完成");
} else if (OrderInfoEnum.STATUS_CANCEL.getValue().equals(order.getStatus())) {
statusDTO.set_class("state-yqx");
statusDTO.set_msg("交易取消,感谢您的支持");
statusDTO.set_type("5");
statusDTO.set_title("已取消");
}
if (PayTypeEnum.WEIXIN.getValue().equals(order.getPayType())) {
@ -884,17 +913,6 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
}
order.set_status(statusDTO);
// 查询是否发货
StoreOrderStatusDO orderStatusDO =
storeOrderStatusMapper.selectOne(new LambdaQueryWrapper<StoreOrderStatusDO>()
.eq(StoreOrderStatusDO::getOid, order.getId())
.eq(StoreOrderStatusDO::getChangeType, OrderLogEnum.DELIVERY_GOODS.getValue()));
if (orderStatusDO != null) {
order.setDeliveryTime(orderStatusDO.getChangeTime());
}
return order;
}
@ -1055,10 +1073,15 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
this.regressionStock(order, 0);
// 取消订单退回优惠券
appCouponRelationService.returnCoupon(order.getCouponId());
if (order.getCouponId() != null && order.getCouponId() != 0) {
appCouponRelationService.returnCoupon(order.getCouponId());
}
this.regressionCoupon(order, 0);
storeOrderMapper.deleteById(order.getId());
// 订单状态改为取消
update(new LambdaUpdateWrapper<StoreOrderDO>()
.eq(StoreOrderDO::getId, order.getId())
.set(StoreOrderDO::getStatus, OrderInfoEnum.STATUS_CANCEL.getValue()));
// 异步统计
asyncStoreOrderService.orderData(order.getUid());
@ -1107,9 +1130,14 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
storeOrderStatusService.create(orderQueryVo.getUid(), orderQueryVo.getId(),
OrderLogEnum.REFUND_ORDER_SUCCESS.getValue(), "退款给用户:" + price + "");
} else if (PayTypeEnum.WEIXIN.getValue().equals(orderQueryVo.getPayType())) {
// 微信
MerchantDetailsDO merchantDetailsDO = merchantDetailsService.getMerchantDetails("4");
packageParams = new WxPayServiceUtils().refund(payInfo.getTransaction_id(), payInfo.getOut_refund_no(), orderQueryVo.getTotalPrice(), price, merchantDetailsDO);
// 微信 根据不同付款方式进行退款 小程序 app
MerchantDetailsDO merchantDetailsDO;
if (payInfo.getOut_trade_no().contains("APPLET")) {
merchantDetailsDO = merchantDetailsService.getMerchantDetails(PayTypeEnum.WEIXIN_APPLET.getCode());
} else {
merchantDetailsDO = merchantDetailsService.getMerchantDetails(PayTypeEnum.WEIXIN_H5.getCode());
}
packageParams = wxPayServiceUtils.refund(payInfo.getTransaction_id(), payInfo.getOut_refund_no(), orderQueryVo.getTotalPrice(), price, merchantDetailsDO);
log.info("退款信息:{}", packageParams);
//退款成功操作 应该在回调url中
@ -1271,12 +1299,11 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
/**
* 订单检测
*
* @param uid uid
* @param key 缓存值
* @param param ComputeOrderParam
* @param uid uid
* @param key 缓存值
* @return map
*/
private Map<String, Object> check(Long uid, String key, AppComputeOrderParam param) {
private Map<String, Object> check(Long uid, String key) {
Map<String, Object> map = Maps.newHashMap();
if (StrUtil.isBlank(key)) {
throw exception(PARAM_ERROR);
@ -1306,38 +1333,42 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
*/
private PriceGroupDto getOrderPriceGroup(List<AppStoreCartQueryVo> cartInfo, UserAddressDO userAddress, Long couponId) {
BigDecimal storePostage;
BigDecimal storePostage = BigDecimal.ZERO;
BigDecimal storeFreePostage = BigDecimal.ZERO;
BigDecimal costPrice = this.getOrderSumPrice(cartInfo, "truePrice");//获取订单成本价
BigDecimal payIntegral = BigDecimal.ZERO;
BigDecimal couponPrice = BigDecimal.ZERO;
if (couponId == null || couponId != -1l) {
Map<Long, List<AppStoreCartQueryVo>> cartInfoMap =
cartInfo.stream().collect(Collectors.groupingBy(AppStoreCartQueryVo::getProductId));
if (couponId == null || couponId != -1L) {
List<CartCouponDto> cartCouponDtoList = new ArrayList<>();
for (List<AppStoreCartQueryVo> queryVos : cartInfoMap.values()) {
BigDecimal amount = BigDecimal.ZERO;
for (AppStoreCartQueryVo appStoreCartQueryVo : queryVos) {
amount = amount.add(appStoreCartQueryVo.getTruePrice()
.multiply(BigDecimal.valueOf(appStoreCartQueryVo.getCartNum())));
}
cartCouponDtoList.add(CartCouponDto.builder().productId(queryVos.get(0).getProductId()).price(amount).build());
for (AppStoreCartQueryVo vo : cartInfo) {
cartCouponDtoList.add(new CartCouponDto(vo.getProductId(), vo.getProductAttrUnique(), NumberUtil.mul(vo.getTruePrice(), vo.getCartNum())));
}
List<CartCouponVO> cartCouponVOList = appCouponRelationService.searchCartCoupon(cartCouponDtoList, couponId);
// 默认优惠券
if (CollectionUtils.isNotEmpty(cartCouponVOList)) {
CartCouponVO defaultCoupon = cartCouponVOList.get(0);
couponPrice = defaultCoupon.getDiscountAmount();
couponId = defaultCoupon.getDetailId();
CartCouponVO cartCouponVO = cartCouponVOList.get(0);
couponPrice = cartCouponVO.getDiscountAmount();
couponId = cartCouponVO.getDetailId();
List<CartCouponDetailVO> cartCouponDetailVOList = cartCouponVO.getDetailVOList();
if (CollectionUtils.isNotEmpty(cartCouponDetailVOList)) {
Map<String, CartCouponDetailVO> cartCouponDetailVOMap =
cartCouponDetailVOList.stream().collect(Collectors.toMap(CartCouponDetailVO::getProductAttrUnique, Function.identity()));
cartInfo.forEach(res -> {
if (ObjectUtil.isNotNull(cartCouponDetailVOMap.get(res.getProductAttrUnique()))) {
res.setCouponPrice(cartCouponDetailVOMap.get(res.getProductAttrUnique()).getProductCoupon());
}
});
}
}
}
// this.getOrderSumPrice(cartInfo, "payIntegral");//获取订单需要的积分
//运费模板
storePostage = this.handlePostage(cartInfo, userAddress);
// 计算运费
for (AppStoreCartQueryVo vo : cartInfo) {
BigDecimal postagePrice = this.handlePostage(Arrays.asList(vo), userAddress);
vo.setPostagePrice(postagePrice);
storePostage = storePostage.add(postagePrice);
}
BigDecimal totalPrice = costPrice.add(storePostage).subtract(couponPrice);//获取订单总金额
@ -1391,7 +1422,7 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
* @param userAddress 地址
* @return double
*/
private BigDecimal handlePostage(List<AppStoreCartQueryVo> cartInfo, UserAddressDO userAddress) {
public BigDecimal handlePostage(List<AppStoreCartQueryVo> cartInfo, UserAddressDO userAddress) {
BigDecimal storePostage = BigDecimal.ZERO;
if (userAddress != null) {
if (userAddress.getCityId() == null) {
@ -1442,11 +1473,11 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
//是否是固定邮费,没设置运费模板走固定
if (tempId == 0) {
storePostage =
/*storePostage =
storePostage.add(storeCartVO.getProductInfo().getPostage()
.multiply(BigDecimal.valueOf(storeCartVO.getCartNum())));
continue;
// return storeCartVO.getProductInfo().getPostage();
continue;*/
return storeCartVO.getProductInfo().getPostage();
}
//根据模板类型获取相应的数量
@ -1503,7 +1534,7 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, Stor
}
//处理区域邮费
boolean isFirst = false; //用来是否多个产品的标识 false表示数量大于1
boolean isFirst = true; //用来是否多个产品的标识 false表示数量大于1
for (TemplateDto templateDTO : templateDTOMap.values()) {
if (isFirst) {//首件
//只满足首件

View File

@ -1,9 +1,5 @@
package co.yixiang.yshop.module.order.service.storeorder;
import co.yixiang.yshop.module.member.controller.app.user.vo.AppUserOrderCountVo;
import co.yixiang.yshop.module.order.controller.admin.storeorder.vo.ShoperOrderTimeDataVo;
import co.yixiang.yshop.module.order.service.storeorder.dto.OrderTimeDataDto;
/**
* 异步订单 Service 接口
*

View File

@ -8,6 +8,7 @@ import co.yixiang.yshop.module.member.service.user.MemberUserService;
import co.yixiang.yshop.module.order.controller.admin.storeorder.vo.ShoperOrderTimeDataVo;
import co.yixiang.yshop.module.order.dal.dataobject.storeaftersales.StoreAfterSalesDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeorder.StoreOrderDO;
import co.yixiang.yshop.module.order.dal.mysql.storeaftersales.StoreAfterSalesMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeorder.StoreOrderMapper;
import co.yixiang.yshop.module.order.dal.redis.order.AsyncCountRedisDAO;
import co.yixiang.yshop.module.order.dal.redis.order.AsyncOrderRedisDAO;
@ -16,6 +17,8 @@ import co.yixiang.yshop.module.order.service.storeorder.dto.OrderTimeDataDto;
import co.yixiang.yshop.module.product.service.storeproduct.StoreProductService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@ -32,12 +35,13 @@ import java.util.Objects;
@Service
@Validated
@Slf4j
@Lazy
public class AsyncStoreOrderServiceImpl implements AsyncStoreOrderService {
@Resource
private StoreOrderMapper storeOrderMapper;
@Resource
private AppStoreAfterSalesService appStoreAfterSalesService;
private StoreAfterSalesMapper storeAfterSalesMapper;
@Resource
private AsyncOrderRedisDAO asyncOrderRedisDAO;
@Resource
@ -69,7 +73,6 @@ public class AsyncStoreOrderServiceImpl implements AsyncStoreOrderService {
double sumPrice = storeOrderMapper.sumPrice(uid);
//订单待发货 数量
LambdaQueryWrapper<StoreOrderDO> wrapperThree = new LambdaQueryWrapper<>();
if (uid != null) {
@ -112,9 +115,8 @@ public class AsyncStoreOrderServiceImpl implements AsyncStoreOrderService {
Long completeCount = storeOrderMapper.selectCount(wrapperSix);
//售后退款
Long salesCount = appStoreAfterSalesService.lambdaQuery()
.eq(Objects.nonNull(uid), StoreAfterSalesDO::getUserId, uid)
.count();
Long salesCount = storeAfterSalesMapper.selectCount(new LambdaQueryWrapper<StoreAfterSalesDO>()
.eq(StoreAfterSalesDO::getUserId, uid));
//订单待支付 数量
LambdaQueryWrapper<StoreOrderDO> wrapperTwo = new LambdaQueryWrapper<>();
@ -125,7 +127,7 @@ public class AsyncStoreOrderServiceImpl implements AsyncStoreOrderService {
.eq(StoreOrderDO::getRefundStatus, OrderInfoEnum.REFUND_STATUS_NORMAL.getValue())
.eq(StoreOrderDO::getStatus, OrderInfoEnum.STATUS_DEFAULT.getValue());
Long unpaidCount = storeOrderMapper.selectCount(wrapperTwo);
AppUserOrderCountVo appUserOrderCountVo = AppUserOrderCountVo.builder()
AppUserOrderCountVo appUserOrderCountVo = AppUserOrderCountVo.builder()
.orderCount(orderCount)
.sumPrice(sumPrice)
.unpaidCount(unpaidCount)
@ -136,9 +138,10 @@ public class AsyncStoreOrderServiceImpl implements AsyncStoreOrderService {
.refundCount(salesCount)
.build();
//先删除再存redis
//先删除再存redis
asyncOrderRedisDAO.delete(uid);
asyncOrderRedisDAO.set(appUserOrderCountVo,uid);
log.info("订单统计数据:{}", appUserOrderCountVo);
asyncOrderRedisDAO.set(appUserOrderCountVo, uid);
this.getOrderTimeData();
}
@ -146,7 +149,6 @@ public class AsyncStoreOrderServiceImpl implements AsyncStoreOrderService {
/**
* 首页订单/用户等统计
*
*/
@Async
@Override

View File

@ -205,7 +205,7 @@ public class StoreOrderServiceImpl implements StoreOrderService {
/**
* 订单查询
* @param pageReqVO 分页查询
* @return
* @return 订单vo
*/
@Override
public PageResult<StoreOrderRespVO> getStoreOrderPage(StoreOrderPageReqVO pageReqVO) {
@ -336,11 +336,11 @@ public class StoreOrderServiceImpl implements StoreOrderService {
/**
* 处理订单状态
* @param payStatus
* @param status
* @param refundStatus
* @param del
* @return
* @param payStatus 支付状态
* @param status 订单状态
* @param refundStatus 退款状态
* @param del 删除标准
* @return 订单状态
*/
private String handleOrderStatus(Integer payStatus,Integer status,Integer refundStatus,Integer del) {
String statusName = "";
@ -348,6 +348,8 @@ public class StoreOrderServiceImpl implements StoreOrderService {
statusName = "已删除";
}else if (payStatus == 0 && status == 0) {
statusName = "未支付";
} else if (payStatus == 0 && status == 4) {
statusName = "已取消";
} else if (payStatus == 1 && status == 0 && refundStatus == 0) {
statusName = "未发货";
} else if (payStatus == 1 && status == 1 && refundStatus == 0) {
@ -358,8 +360,7 @@ public class StoreOrderServiceImpl implements StoreOrderService {
statusName = "已完成";
} else if (payStatus == 1 && refundStatus == 2) {
statusName = "已退款";
}
else if (payStatus == 1 && refundStatus == 1) {
} else if (payStatus == 1 && refundStatus == 1) {
statusName = "退款中";
}
return statusName;

View File

@ -46,6 +46,8 @@ public class StoreOrderCartInfoServiceImpl extends ServiceImpl<StoreOrderCartInf
info.setCartInfo(JSONObject.toJSON(cart).toString());
info.setUnique(IdUtil.simpleUUID());
info.setIsAfterSales(OrderInfoEnum.YES.getValue());
info.setCouponPrice(cart.getCouponPrice());
info.setPostagePrice(cart.getPostagePrice());
list.add(info);
}
saveBatch(list);