【功能优化】支付:支付应用,增加 appKey 标识,用于不同接入方的标识

【更多】同步 boot 最新代码到 cloud
This commit is contained in:
YunaiV
2024-08-18 17:18:03 +08:00
parent 720b426f5e
commit 4ca68ff56a
52 changed files with 484 additions and 591 deletions

View File

@@ -148,5 +148,4 @@ public class AppProductSpuController {
return price - newPrice;
}
// TODO 芋艿:商品的浏览记录;
}

View File

@@ -48,6 +48,4 @@ public class ProductBrandDO extends BaseDO {
*/
private Integer status;
// TODO 芋艿firstLetter 首字母
}

View File

@@ -130,11 +130,5 @@ public class ProductSkuDO extends BaseDO {
}
// TODO 芋艿integral from y
// TODO 芋艿pinkPrice from y
// TODO 芋艿seckillPrice from y
// TODO 芋艿pinkStock from y
// TODO 芋艿seckillStock from y
}

View File

@@ -10,9 +10,7 @@ import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.Ap
import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordSummaryRespVO;
import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
@@ -20,7 +18,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Max;
import org.springframework.context.annotation.Lazy;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -43,9 +40,6 @@ public class AppCombinationRecordController {
@Resource
private CombinationRecordService combinationRecordService;
@Resource
@Lazy
private TradeOrderApi tradeOrderApi;
@GetMapping("/get-summary")
@Operation(summary = "获得拼团记录的概要信息", description = "用于小程序首页")
@@ -117,26 +111,4 @@ public class AppCombinationRecordController {
return success(CombinationActivityConvert.INSTANCE.convert(getLoginUserId(), headRecord, memberRecords));
}
@GetMapping("/cancel")
@Operation(summary = "取消拼团")
@Parameter(name = "id", description = "拼团记录编号", required = true, example = "1024")
public CommonResult<Boolean> cancelCombinationRecord(@RequestParam("id") Long id) {
Long userId = getLoginUserId();
// 1、查找这条拼团记录
CombinationRecordDO record = combinationRecordService.getCombinationRecordByIdAndUser(userId, id);
if (record == null) {
return success(Boolean.FALSE);
}
// 1.1、需要先校验拼团记录未完成;
if (!CombinationRecordStatusEnum.isInProgress(record.getStatus())) {
return success(Boolean.FALSE);
}
// 2. 取消已支付的订单
tradeOrderApi.cancelPaidOrder(userId, record.getOrderId());
// 3. 取消拼团记录
combinationRecordService.cancelCombinationRecord(userId, record.getId(), record.getHeadId());
return success(Boolean.TRUE);
}
}

View File

@@ -72,7 +72,6 @@ public interface SeckillActivityMapper extends BaseMapperX<SeckillActivityDO> {
default PageResult<SeckillActivityDO> selectPage(AppSeckillActivityPageReqVO pageReqVO, Integer status) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<SeckillActivityDO>()
.eqIfPresent(SeckillActivityDO::getStatus, status)
// TODO 芋艿:对 find in set 的想法;
.apply(ObjectUtil.isNotNull(pageReqVO.getConfigId()), "FIND_IN_SET(" + pageReqVO.getConfigId() + ",config_ids) > 0"));
}

View File

@@ -139,24 +139,6 @@ public interface CombinationRecordService {
@Nullable Integer status,
@Nullable Long headId);
/**
* 获取拼团记录
*
* @param userId 用户编号
* @param id 拼团记录编号
* @return 拼团记录
*/
CombinationRecordDO getCombinationRecordByIdAndUser(Long userId, Long id);
/**
* 取消拼团
*
* @param userId 用户编号
* @param id 拼团记录编号
* @param headId 团长编号
*/
void cancelCombinationRecord(Long userId, Long id, Long headId);
/**
* 处理过期拼团
*

View File

@@ -37,7 +37,10 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.time.LocalDateTime;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
@@ -69,7 +72,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
private ProductSpuApi productSpuApi;
@Resource
private ProductSkuApi productSkuApi;
@Resource
@Lazy // 延迟加载,避免循环依赖
private TradeOrderApi tradeOrderApi;
@@ -289,61 +291,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
return combinationRecordMapper.selectCombinationRecordCountMapByActivityIdAndStatusAndHeadId(activityIds, status, headId);
}
@Override
public CombinationRecordDO getCombinationRecordByIdAndUser(Long userId, Long id) {
return combinationRecordMapper.selectOne(CombinationRecordDO::getUserId, userId, CombinationRecordDO::getId, id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void cancelCombinationRecord(Long userId, Long id, Long headId) {
// 删除记录
combinationRecordMapper.deleteById(id);
// 需要更新的记录
List<CombinationRecordDO> updateRecords = new ArrayList<>();
// 如果它是团长,则顺序(下单时间)继承
if (Objects.equals(headId, CombinationRecordDO.HEAD_ID_GROUP)) { // 情况一:团长
// 团员
List<CombinationRecordDO> list = getCombinationRecordListByHeadId(id);
if (CollUtil.isEmpty(list)) {
return;
}
// 按照创建时间升序排序
list.sort(Comparator.comparing(CombinationRecordDO::getCreateTime)); // 影响原 list
CombinationRecordDO newHead = list.get(0); // 新团长继位
list.forEach(item -> {
CombinationRecordDO recordDO = new CombinationRecordDO();
recordDO.setId(item.getId());
if (ObjUtil.equal(item.getId(), newHead.getId())) { // 新团长
recordDO.setHeadId(CombinationRecordDO.HEAD_ID_GROUP);
} else {
recordDO.setHeadId(newHead.getId());
}
recordDO.setUserCount(list.size());
updateRecords.add(recordDO);
});
} else { // 情况二:团员
// 团长
CombinationRecordDO recordHead = combinationRecordMapper.selectById(headId);
// 团员
List<CombinationRecordDO> records = getCombinationRecordListByHeadId(headId);
if (CollUtil.isEmpty(records)) {
return;
}
records.add(recordHead); // 加入团长,团长数据也需要更新
records.forEach(item -> {
CombinationRecordDO recordDO = new CombinationRecordDO();
recordDO.setId(item.getId());
recordDO.setUserCount(records.size());
updateRecords.add(recordDO);
});
}
// 更新拼团记录
combinationRecordMapper.updateBatch(updateRecords);
}
@Override
public KeyValue<Integer, Integer> expireCombinationRecord() {
// 1. 获取所有正在进行中的过期的父拼团

View File

@@ -10,8 +10,6 @@ import com.xxl.job.core.handler.annotation.XxlJob;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
// TODO 芋艿:缺个 Job 的配置;等和 Product 一起配置
/**
* 商品统计 Job
*

View File

@@ -11,7 +11,6 @@ import org.springframework.stereotype.Component;
import jakarta.annotation.Resource;
// TODO 芋艿:缺个 Job 的配置;等和 Product 一起配置
/**
* 交易统计 Job
*

View File

@@ -21,6 +21,9 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true)
public class AfterSalePageReqVO extends PageParam {
@Schema(description = "用户编号", example = "1024")
private Long userId;
@Schema(description = "售后流水号", example = "202211190847450020500077")
private String no;

View File

@@ -101,7 +101,7 @@ public interface TradeOrderConvert {
default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
TradeOrderProperties orderProperties) {
PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO()
.setAppId(orderProperties.getAppId()).setUserIp(order.getUserIp());
.setAppKey(orderProperties.getPayAppKey()).setUserIp(order.getUserIp());
// 商户相关字段
createReqDTO.setMerchantOrderId(String.valueOf(order.getId()));
String subject = orderItems.get(0).getSpuName();

View File

@@ -16,6 +16,7 @@ public interface AfterSaleMapper extends BaseMapperX<AfterSaleDO> {
default PageResult<AfterSaleDO> selectPage(AfterSalePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<AfterSaleDO>()
.eqIfPresent(AfterSaleDO::getUserId, reqVO.getUserId())
.likeIfPresent(AfterSaleDO::getNo, reqVO.getNo())
.eqIfPresent(AfterSaleDO::getStatus, reqVO.getStatus())
.eqIfPresent(AfterSaleDO::getType, reqVO.getType())

View File

@@ -1,4 +0,0 @@
/**
* TODO 占位
*/
package cn.iocoder.yudao.module.trade.dal.mysql;

View File

@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.framework.order.config;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
// TODO @LeeYan9: 可以直接给 TradeOrderProperties 一个 @Component生效哈
/**
* @author LeeYan9
* @since 2022-09-15

View File

@@ -1,10 +1,12 @@
package cn.iocoder.yudao.module.trade.framework.order.config;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
import jakarta.validation.constraints.NotNull;
import java.time.Duration;
/**
@@ -18,11 +20,15 @@ import java.time.Duration;
@Validated
public class TradeOrderProperties {
private static final String PAY_APP_KEY_DEFAULT = "mall";
/**
* 应用编号
* 支付应用标识
*
* 在 pay 模块的 [支付管理 -> 应用信息] 里添加
*/
@NotNull(message = "应用编号不能为空")
private Long appId;
@NotEmpty(message = "Pay 应用标识不能为空")
private String payAppKey = PAY_APP_KEY_DEFAULT;
/**
* 支付超时时间

View File

@@ -125,7 +125,6 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
@Override
public BrokerageUserDO getOrCreateBrokerageUser(Long id) {
// TODO @芋艿:这块优化下;统一到注册时处理;
BrokerageUserDO brokerageUser = brokerageUserMapper.selectById(id);
// 特殊:人人分销的情况下,如果分销人为空则创建分销人
if (brokerageUser == null && ObjUtil.equal(BrokerageEnabledConditionEnum.ALL.getCondition(),

View File

@@ -855,12 +855,14 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
@Override
@Transactional(rollbackFor = Exception.class)
public void cancelPaidOrder(Long userId, Long orderId) {
// TODO 芋艿:这里实现要优化下;
// TODO @puhui999需要校验状态已支付的情况下才可以。
TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(orderId, userId);
if (order == null) {
throw exception(ORDER_NOT_FOUND);
}
cancelOrder0(order, TradeOrderCancelTypeEnum.MEMBER_CANCEL);
// TODO @puhui999需要退款
}
/**

View File

@@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.trade.service.price.calculator;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
@@ -61,7 +62,7 @@ public class TradePriceCalculatorHelper {
orderItem.setSpuName(spu.getName()).setCategoryId(spu.getCategoryId())
.setDeliveryTemplateId(spu.getDeliveryTemplateId())
.setGivePoint(spu.getGiveIntegral()).setUsePoint(0);
if (orderItem.getPicUrl() == null) {
if (StrUtil.isBlank(orderItem.getPicUrl())) {
orderItem.setPicUrl(spu.getPicUrl());
}
});
@@ -240,7 +241,7 @@ public class TradePriceCalculatorHelper {
*
* 和 {@link #dividePrice(List, Integer)} 逻辑一致,只是传入的是 TradeOrderItemDO 对象
*
* @param items 订单项
* @param items 订单项
* @param price 订单支付金额
* @return 分摊金额数组,和传入的 orderItems 一一对应
*/

View File

@@ -125,7 +125,6 @@ yudao:
ignore-tables:
trade:
order:
app-id: 1 # 商户编号
pay-expire-time: 2h # 支付的过期时间
receive-expire-time: 14d # 收货的过期时间
comment-expire-time: 7d # 评论的过期时间