feat(payment): 优化支付请求参数处理与商品列表接口
- 移除CheckoutRequestDTO中accId和sign字段的必填校验 - 支持从配置文件自动填充accId和signType字段 - 签名sign字段改为后端自动生成 - 新增商品列表查询接口GET /products/list - 实现listProducts服务方法,支持分页和状态过滤 - 添加详细的日志记录和异常处理 - 修复启动时devtools导致的静默退出问题 - 优化数字类型参数转换异常处理
This commit is contained in:
@@ -83,7 +83,12 @@ public enum ResultCode {
|
||||
/**
|
||||
* 服务不可用
|
||||
*/
|
||||
SERVICE_UNAVAILABLE("5001", "服务不可用");
|
||||
SERVICE_UNAVAILABLE("5001", "服务不可用"),
|
||||
|
||||
/**
|
||||
* 业务错误
|
||||
*/
|
||||
BUSINESS_ERROR("6000", "业务错误");
|
||||
|
||||
/**
|
||||
* 响应码
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.mtkj.mtpay.controller;
|
||||
|
||||
import com.mtkj.mtpay.common.Result;
|
||||
import com.mtkj.mtpay.dto.request.CreateCustomerOrderRequestDTO;
|
||||
import com.mtkj.mtpay.dto.response.CustomerOrderResponseDTO;
|
||||
import com.mtkj.mtpay.service.CustomerOrderService;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 客户订单控制器
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/order")
|
||||
@RequiredArgsConstructor
|
||||
public class CustomerOrderController {
|
||||
|
||||
private final CustomerOrderService customerOrderService;
|
||||
|
||||
/**
|
||||
* 创建客户订单
|
||||
*/
|
||||
@PostMapping
|
||||
public Result<CustomerOrderResponseDTO> createOrder(@Valid @RequestBody CreateCustomerOrderRequestDTO request) {
|
||||
log.info("创建客户订单请求:{}", request);
|
||||
CustomerOrderResponseDTO order = customerOrderService.createOrder(request);
|
||||
return Result.success("订单创建成功", order);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单号获取订单详情
|
||||
*/
|
||||
@GetMapping("/{orderNo}")
|
||||
public Result<CustomerOrderResponseDTO> getOrderByOrderNo(@PathVariable String orderNo) {
|
||||
log.info("获取订单详情,订单号:{}", orderNo);
|
||||
CustomerOrderResponseDTO order = customerOrderService.getOrderByOrderNo(orderNo);
|
||||
return Result.success(order);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID获取订单详情
|
||||
*/
|
||||
@GetMapping("/id/{id}")
|
||||
public Result<CustomerOrderResponseDTO> getOrderById(@PathVariable Long id) {
|
||||
log.info("获取订单详情,订单ID:{}", id);
|
||||
CustomerOrderResponseDTO order = customerOrderService.getOrderById(id);
|
||||
return Result.success(order);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,16 @@ public class ProductController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public Result<List<ProductResponseDTO>> listProducts() {
|
||||
log.info("获取商品列表");
|
||||
List<ProductResponseDTO> products = productService.listProducts();
|
||||
return Result.success(products);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品详情页URL
|
||||
*/
|
||||
|
||||
@@ -13,9 +13,8 @@ import java.io.Serializable;
|
||||
@Data
|
||||
public class CheckoutRequestDTO implements Serializable {
|
||||
|
||||
@NotBlank(message = "商户店铺编号不能为空")
|
||||
@Size(max = 64, message = "商户店铺编号长度不能超过64")
|
||||
private String accId;
|
||||
private String accId; // 可选,后端会自动从配置中获取
|
||||
|
||||
@NotBlank(message = "交易金额不能为空")
|
||||
@Pattern(regexp = "^\\d+(\\.\\d{2})?$", message = "交易金额格式不正确,需保留两位小数")
|
||||
@@ -49,9 +48,8 @@ public class CheckoutRequestDTO implements Serializable {
|
||||
@Pattern(regexp = "^(MD5|SHA256)$", message = "签名类型必须为MD5或SHA256")
|
||||
private String signType;
|
||||
|
||||
@NotBlank(message = "签名不能为空")
|
||||
@Size(max = 255, message = "签名长度不能超过255")
|
||||
private String sign;
|
||||
private String sign; // 可选,后端会自动生成
|
||||
|
||||
@Size(max = 64, message = "商户用户ID长度不能超过64")
|
||||
private String merchantUserId;
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.mtkj.mtpay.dto.request;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 创建客户订单请求DTO
|
||||
*/
|
||||
@Data
|
||||
public class CreateCustomerOrderRequestDTO implements Serializable {
|
||||
|
||||
@NotNull(message = "商品ID不能为空")
|
||||
private Long productId;
|
||||
|
||||
@NotNull(message = "SKU ID不能为空")
|
||||
private Long skuId;
|
||||
|
||||
@NotNull(message = "购买数量不能为空")
|
||||
@Min(value = 1, message = "购买数量至少为1")
|
||||
private Integer quantity;
|
||||
|
||||
// 客户信息
|
||||
@NotBlank(message = "客户姓名不能为空")
|
||||
@Size(max = 100, message = "客户姓名长度不能超过100")
|
||||
private String customerName;
|
||||
|
||||
@NotBlank(message = "客户电话不能为空")
|
||||
@Size(max = 20, message = "客户电话长度不能超过20")
|
||||
private String customerPhone;
|
||||
|
||||
@Email(message = "邮箱格式不正确")
|
||||
@Size(max = 100, message = "邮箱长度不能超过100")
|
||||
private String customerEmail;
|
||||
|
||||
// 收货地址
|
||||
@NotBlank(message = "收货人姓名不能为空")
|
||||
@Size(max = 100, message = "收货人姓名长度不能超过100")
|
||||
private String shippingName;
|
||||
|
||||
@NotBlank(message = "收货人电话不能为空")
|
||||
@Size(max = 20, message = "收货人电话长度不能超过20")
|
||||
private String shippingPhone;
|
||||
|
||||
@NotBlank(message = "收货国家不能为空")
|
||||
@Size(max = 50, message = "收货国家长度不能超过50")
|
||||
private String shippingCountry;
|
||||
|
||||
@Size(max = 50, message = "收货州/省长度不能超过50")
|
||||
private String shippingState;
|
||||
|
||||
@NotBlank(message = "收货城市不能为空")
|
||||
@Size(max = 50, message = "收货城市长度不能超过50")
|
||||
private String shippingCity;
|
||||
|
||||
@NotBlank(message = "收货街道地址不能为空")
|
||||
@Size(max = 200, message = "收货街道地址长度不能超过200")
|
||||
private String shippingStreet;
|
||||
|
||||
@Size(max = 20, message = "收货邮编长度不能超过20")
|
||||
private String shippingPostcode;
|
||||
|
||||
@Size(max = 500, message = "订单备注长度不能超过500")
|
||||
private String remark;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.mtkj.mtpay.dto.response;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 客户订单响应DTO
|
||||
*/
|
||||
@Data
|
||||
public class CustomerOrderResponseDTO implements Serializable {
|
||||
|
||||
private Long id;
|
||||
private String orderNo;
|
||||
private Long productId;
|
||||
private String productName;
|
||||
private Long skuId;
|
||||
private String skuName;
|
||||
private Integer quantity;
|
||||
private BigDecimal unitPrice;
|
||||
private BigDecimal totalAmount;
|
||||
private String currency;
|
||||
private String status;
|
||||
private String customerName;
|
||||
private String customerPhone;
|
||||
private String customerEmail;
|
||||
private String shippingName;
|
||||
private String shippingPhone;
|
||||
private String shippingCountry;
|
||||
private String shippingState;
|
||||
private String shippingCity;
|
||||
private String shippingStreet;
|
||||
private String shippingPostcode;
|
||||
private Long paymentOrderId;
|
||||
private String paymentStatus;
|
||||
private String remark;
|
||||
private LocalDateTime createTime;
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
|
||||
172
mt-pay/src/main/java/com/mtkj/mtpay/entity/CustomerOrder.java
Normal file
172
mt-pay/src/main/java/com/mtkj/mtpay/entity/CustomerOrder.java
Normal file
@@ -0,0 +1,172 @@
|
||||
package com.mtkj.mtpay.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 客户订单实体类
|
||||
*/
|
||||
@TableName(value = "customer_order")
|
||||
@Data
|
||||
public class CustomerOrder {
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 订单号(全局唯一)
|
||||
*/
|
||||
@TableField(value = "order_no", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String orderNo;
|
||||
|
||||
/**
|
||||
* 商品ID
|
||||
*/
|
||||
@TableField(value = "product_id", jdbcType = org.apache.ibatis.type.JdbcType.BIGINT)
|
||||
private Long productId;
|
||||
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
@TableField(value = "product_name", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String productName;
|
||||
|
||||
/**
|
||||
* SKU ID
|
||||
*/
|
||||
@TableField(value = "sku_id", jdbcType = org.apache.ibatis.type.JdbcType.BIGINT)
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* SKU名称/描述
|
||||
*/
|
||||
@TableField(value = "sku_name", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String skuName;
|
||||
|
||||
/**
|
||||
* 购买数量
|
||||
*/
|
||||
@TableField(value = "quantity", jdbcType = org.apache.ibatis.type.JdbcType.INTEGER)
|
||||
private Integer quantity;
|
||||
|
||||
/**
|
||||
* 单价
|
||||
*/
|
||||
@TableField(value = "unit_price", jdbcType = org.apache.ibatis.type.JdbcType.DECIMAL)
|
||||
private BigDecimal unitPrice;
|
||||
|
||||
/**
|
||||
* 订单总金额
|
||||
*/
|
||||
@TableField(value = "total_amount", jdbcType = org.apache.ibatis.type.JdbcType.DECIMAL)
|
||||
private BigDecimal totalAmount;
|
||||
|
||||
/**
|
||||
* 货币代码
|
||||
*/
|
||||
@TableField(value = "currency", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String currency;
|
||||
|
||||
/**
|
||||
* 订单状态:PENDING-待支付,PAID-已支付,SHIPPED-已发货,COMPLETED-已完成,CANCELLED-已取消
|
||||
*/
|
||||
@TableField(value = "status", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 客户姓名
|
||||
*/
|
||||
@TableField(value = "customer_name", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String customerName;
|
||||
|
||||
/**
|
||||
* 客户电话
|
||||
*/
|
||||
@TableField(value = "customer_phone", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String customerPhone;
|
||||
|
||||
/**
|
||||
* 客户邮箱
|
||||
*/
|
||||
@TableField(value = "customer_email", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String customerEmail;
|
||||
|
||||
/**
|
||||
* 收货人姓名
|
||||
*/
|
||||
@TableField(value = "shipping_name", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String shippingName;
|
||||
|
||||
/**
|
||||
* 收货人电话
|
||||
*/
|
||||
@TableField(value = "shipping_phone", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String shippingPhone;
|
||||
|
||||
/**
|
||||
* 收货国家
|
||||
*/
|
||||
@TableField(value = "shipping_country", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String shippingCountry;
|
||||
|
||||
/**
|
||||
* 收货州/省
|
||||
*/
|
||||
@TableField(value = "shipping_state", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String shippingState;
|
||||
|
||||
/**
|
||||
* 收货城市
|
||||
*/
|
||||
@TableField(value = "shipping_city", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String shippingCity;
|
||||
|
||||
/**
|
||||
* 收货街道地址
|
||||
*/
|
||||
@TableField(value = "shipping_street", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String shippingStreet;
|
||||
|
||||
/**
|
||||
* 收货邮编
|
||||
*/
|
||||
@TableField(value = "shipping_postcode", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String shippingPostcode;
|
||||
|
||||
/**
|
||||
* 关联的支付订单ID
|
||||
*/
|
||||
@TableField(value = "payment_order_id", jdbcType = org.apache.ibatis.type.JdbcType.BIGINT)
|
||||
private Long paymentOrderId;
|
||||
|
||||
/**
|
||||
* 支付状态:UNPAID-未支付,PAID-已支付,FAILED-支付失败
|
||||
*/
|
||||
@TableField(value = "payment_status", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String paymentStatus;
|
||||
|
||||
/**
|
||||
* 订单备注
|
||||
*/
|
||||
@TableField(value = "remark", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(value = "create_time", fill = FieldFill.INSERT)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.mtkj.mtpay.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.mtkj.mtpay.entity.CustomerOrder;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 客户订单Mapper接口
|
||||
*/
|
||||
@Mapper
|
||||
public interface CustomerOrderMapper extends BaseMapper<CustomerOrder> {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.mtkj.mtpay.service;
|
||||
|
||||
import com.mtkj.mtpay.dto.request.CreateCustomerOrderRequestDTO;
|
||||
import com.mtkj.mtpay.dto.response.CustomerOrderResponseDTO;
|
||||
|
||||
/**
|
||||
* 客户订单服务接口
|
||||
*/
|
||||
public interface CustomerOrderService {
|
||||
|
||||
/**
|
||||
* 创建客户订单
|
||||
* @param request 创建订单请求
|
||||
* @return 订单响应
|
||||
*/
|
||||
CustomerOrderResponseDTO createOrder(CreateCustomerOrderRequestDTO request);
|
||||
|
||||
/**
|
||||
* 根据订单号获取订单详情
|
||||
* @param orderNo 订单号
|
||||
* @return 订单响应
|
||||
*/
|
||||
CustomerOrderResponseDTO getOrderByOrderNo(String orderNo);
|
||||
|
||||
/**
|
||||
* 根据ID获取订单详情
|
||||
* @param id 订单ID
|
||||
* @return 订单响应
|
||||
*/
|
||||
CustomerOrderResponseDTO getOrderById(Long id);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.mtkj.mtpay.service;
|
||||
import com.mtkj.mtpay.dto.request.CreateProductRequestDTO;
|
||||
import com.mtkj.mtpay.dto.response.ProductResponseDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品服务接口
|
||||
*/
|
||||
@@ -35,5 +37,11 @@ public interface ProductService {
|
||||
* @return 商品ID
|
||||
*/
|
||||
Long getProductIdByLinkCode(String linkCode);
|
||||
|
||||
/**
|
||||
* 获取商品列表
|
||||
* @return 商品列表
|
||||
*/
|
||||
List<ProductResponseDTO> listProducts();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
package com.mtkj.mtpay.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.mtkj.mtpay.common.ResultCode;
|
||||
import com.mtkj.mtpay.dto.request.CreateCustomerOrderRequestDTO;
|
||||
import com.mtkj.mtpay.dto.response.CustomerOrderResponseDTO;
|
||||
import com.mtkj.mtpay.entity.CustomerOrder;
|
||||
import com.mtkj.mtpay.entity.MtProduct;
|
||||
import com.mtkj.mtpay.entity.MtProductSku;
|
||||
import com.mtkj.mtpay.exception.BusinessException;
|
||||
import com.mtkj.mtpay.mapper.CustomerOrderMapper;
|
||||
import com.mtkj.mtpay.mapper.MtProductMapper;
|
||||
import com.mtkj.mtpay.mapper.MtProductSkuMapper;
|
||||
import com.mtkj.mtpay.service.CustomerOrderService;
|
||||
import com.mtkj.mtpay.util.OrderIdGenerator;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 客户订单服务实现类
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class CustomerOrderServiceImpl implements CustomerOrderService {
|
||||
|
||||
private final CustomerOrderMapper customerOrderMapper;
|
||||
private final MtProductMapper productMapper;
|
||||
private final MtProductSkuMapper productSkuMapper;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public CustomerOrderResponseDTO createOrder(CreateCustomerOrderRequestDTO request) {
|
||||
log.info("创建客户订单,商品ID: {}, SKU ID: {}, 数量: {}",
|
||||
request.getProductId(), request.getSkuId(), request.getQuantity());
|
||||
|
||||
// 验证商品是否存在
|
||||
MtProduct product = productMapper.selectById(request.getProductId());
|
||||
if (product == null) {
|
||||
log.warn("商品不存在,商品ID: {}", request.getProductId());
|
||||
throw new BusinessException(ResultCode.DATA_NOT_FOUND, "商品不存在");
|
||||
}
|
||||
|
||||
// 验证SKU是否存在
|
||||
MtProductSku sku = productSkuMapper.selectById(request.getSkuId());
|
||||
if (sku == null || !sku.getProductId().equals(request.getProductId())) {
|
||||
log.warn("SKU不存在或不属于该商品,SKU ID: {}, 商品ID: {}",
|
||||
request.getSkuId(), request.getProductId());
|
||||
throw new BusinessException(ResultCode.DATA_NOT_FOUND, "SKU不存在");
|
||||
}
|
||||
|
||||
// 验证库存
|
||||
if (sku.getStock() == null || sku.getStock() < request.getQuantity()) {
|
||||
log.warn("库存不足,SKU ID: {}, 库存: {}, 需要: {}",
|
||||
request.getSkuId(), sku.getStock(), request.getQuantity());
|
||||
throw new BusinessException(ResultCode.BUSINESS_ERROR, "库存不足");
|
||||
}
|
||||
|
||||
// 创建订单
|
||||
CustomerOrder order = new CustomerOrder();
|
||||
order.setOrderNo(OrderIdGenerator.generateMerchantTransactionId());
|
||||
order.setProductId(request.getProductId());
|
||||
order.setProductName(product.getName());
|
||||
order.setSkuId(request.getSkuId());
|
||||
order.setSkuName(sku.getSku());
|
||||
order.setQuantity(request.getQuantity());
|
||||
order.setUnitPrice(sku.getPrice());
|
||||
order.setTotalAmount(sku.getPrice().multiply(new BigDecimal(request.getQuantity())));
|
||||
order.setCurrency(sku.getCurrency());
|
||||
order.setStatus("PENDING");
|
||||
order.setPaymentStatus("UNPAID");
|
||||
|
||||
// 客户信息
|
||||
order.setCustomerName(request.getCustomerName());
|
||||
order.setCustomerPhone(request.getCustomerPhone());
|
||||
order.setCustomerEmail(request.getCustomerEmail());
|
||||
|
||||
// 收货地址
|
||||
order.setShippingName(request.getShippingName());
|
||||
order.setShippingPhone(request.getShippingPhone());
|
||||
order.setShippingCountry(request.getShippingCountry());
|
||||
order.setShippingState(request.getShippingState());
|
||||
order.setShippingCity(request.getShippingCity());
|
||||
order.setShippingStreet(request.getShippingStreet());
|
||||
order.setShippingPostcode(request.getShippingPostcode());
|
||||
order.setRemark(request.getRemark());
|
||||
|
||||
// 保存订单
|
||||
int result = customerOrderMapper.insert(order);
|
||||
if (result <= 0) {
|
||||
log.error("创建订单失败,商品ID: {}", request.getProductId());
|
||||
throw new BusinessException(ResultCode.SYSTEM_ERROR, "创建订单失败");
|
||||
}
|
||||
|
||||
log.info("客户订单创建成功,订单ID: {}, 订单号: {}", order.getId(), order.getOrderNo());
|
||||
|
||||
// 转换为响应DTO
|
||||
CustomerOrderResponseDTO response = new CustomerOrderResponseDTO();
|
||||
BeanUtils.copyProperties(order, response);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomerOrderResponseDTO getOrderByOrderNo(String orderNo) {
|
||||
log.debug("查询订单,订单号: {}", orderNo);
|
||||
LambdaQueryWrapper<CustomerOrder> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustomerOrder::getOrderNo, orderNo);
|
||||
CustomerOrder order = customerOrderMapper.selectOne(queryWrapper);
|
||||
|
||||
if (order == null) {
|
||||
log.warn("订单不存在,订单号: {}", orderNo);
|
||||
throw new BusinessException(ResultCode.DATA_NOT_FOUND, "订单不存在");
|
||||
}
|
||||
|
||||
CustomerOrderResponseDTO response = new CustomerOrderResponseDTO();
|
||||
BeanUtils.copyProperties(order, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomerOrderResponseDTO getOrderById(Long id) {
|
||||
log.debug("查询订单,订单ID: {}", id);
|
||||
CustomerOrder order = customerOrderMapper.selectById(id);
|
||||
|
||||
if (order == null) {
|
||||
log.warn("订单不存在,订单ID: {}", id);
|
||||
throw new BusinessException(ResultCode.DATA_NOT_FOUND, "订单不存在");
|
||||
}
|
||||
|
||||
CustomerOrderResponseDTO response = new CustomerOrderResponseDTO();
|
||||
BeanUtils.copyProperties(order, response);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.mtkj.mtpay.service.impl;
|
||||
|
||||
import com.mtkj.mtpay.common.ResultCode;
|
||||
import com.mtkj.mtpay.common.constants.PaymentConstants;
|
||||
import com.mtkj.mtpay.config.PingPongProperties;
|
||||
import com.mtkj.mtpay.dto.request.CheckoutRequestDTO;
|
||||
import com.mtkj.mtpay.dto.response.CheckoutResponseDTO;
|
||||
import com.mtkj.mtpay.entity.PaymentOrder;
|
||||
@@ -15,6 +16,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Optional;
|
||||
@@ -30,6 +32,7 @@ public class PaymentOrderServiceImpl implements PaymentOrderService {
|
||||
private final PaymentOrderMapper paymentOrderMapper;
|
||||
private final PaymentRecordMapper paymentRecordMapper;
|
||||
private final PingPongPayService pingPongPayService;
|
||||
private final PingPongProperties pingPongProperties;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@@ -45,6 +48,17 @@ public class PaymentOrderServiceImpl implements PaymentOrderService {
|
||||
throw new BusinessException(ResultCode.ORDER_EXISTS);
|
||||
}
|
||||
|
||||
// 填充accId和signType(如果前端未提供,从配置中获取)
|
||||
if (!StringUtils.hasText(request.getAccId())) {
|
||||
request.setAccId(pingPongProperties.getAccId());
|
||||
log.debug("使用配置中的accId: {}", request.getAccId());
|
||||
}
|
||||
if (!StringUtils.hasText(request.getSignType())) {
|
||||
request.setSignType(pingPongProperties.getSignType());
|
||||
log.debug("使用配置中的signType: {}", request.getSignType());
|
||||
}
|
||||
// sign字段由PingPongPayService自动生成,不需要前端提供
|
||||
|
||||
// 创建订单实体
|
||||
PaymentOrder order = new PaymentOrder();
|
||||
order.setMerchantTransactionId(request.getMerchantTransactionId());
|
||||
@@ -58,6 +72,7 @@ public class PaymentOrderServiceImpl implements PaymentOrderService {
|
||||
order.setNotificationUrl(request.getNotificationUrl());
|
||||
order.setRemark(request.getRemark());
|
||||
order.setStatus(PaymentConstants.DEFAULT_ORDER_STATUS);
|
||||
order.setAccId(request.getAccId());
|
||||
|
||||
// 调用PingPong API创建支付
|
||||
CheckoutResponseDTO response = pingPongPayService.checkout(request);
|
||||
|
||||
@@ -245,5 +245,73 @@ public class ProductServiceImpl implements ProductService {
|
||||
log.debug("根据链接码获取商品ID成功,链接码: {}, 商品ID: {}", linkCode, productId);
|
||||
return productId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductResponseDTO> listProducts() {
|
||||
log.debug("查询商品列表");
|
||||
|
||||
// 查询所有商品(排除已删除的)
|
||||
LambdaQueryWrapper<MtProduct> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.ne(MtProduct::getStatus, "DELETED");
|
||||
queryWrapper.orderByDesc(MtProduct::getCreateTime);
|
||||
List<MtProduct> products = productMapper.selectList(queryWrapper);
|
||||
|
||||
log.debug("查询到商品数量: {}", products.size());
|
||||
|
||||
// 转换为响应DTO列表
|
||||
List<ProductResponseDTO> result = new ArrayList<>();
|
||||
for (MtProduct product : products) {
|
||||
ProductResponseDTO dto = new ProductResponseDTO();
|
||||
BeanUtils.copyProperties(product, dto);
|
||||
|
||||
// 处理主图:解析JSON数组或使用单个URL
|
||||
if (StringUtils.hasText(product.getMainImage())) {
|
||||
try {
|
||||
// 尝试解析为JSON数组
|
||||
if (product.getMainImage().trim().startsWith("[")) {
|
||||
List<String> mainImages = objectMapper.readValue(
|
||||
product.getMainImage(),
|
||||
new TypeReference<List<String>>() {}
|
||||
);
|
||||
dto.setMainImages(mainImages);
|
||||
// 兼容:第一个作为mainImage
|
||||
if (!mainImages.isEmpty()) {
|
||||
dto.setMainImage(mainImages.get(0));
|
||||
}
|
||||
} else {
|
||||
// 单个URL
|
||||
dto.setMainImage(product.getMainImage());
|
||||
List<String> singleImageList = new ArrayList<>();
|
||||
singleImageList.add(product.getMainImage());
|
||||
dto.setMainImages(singleImageList);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("解析商品主图失败,使用原始值,商品ID: {}", product.getId(), e);
|
||||
dto.setMainImage(product.getMainImage());
|
||||
List<String> singleImageList = new ArrayList<>();
|
||||
singleImageList.add(product.getMainImage());
|
||||
dto.setMainImages(singleImageList);
|
||||
}
|
||||
}
|
||||
|
||||
// 查询SKU列表(用于获取销售地区信息)
|
||||
LambdaQueryWrapper<MtProductSku> skuWrapper = new LambdaQueryWrapper<>();
|
||||
skuWrapper.eq(MtProductSku::getProductId, product.getId());
|
||||
List<MtProductSku> skus = productSkuMapper.selectList(skuWrapper);
|
||||
|
||||
// 转换SKU为DTO(列表页需要SKU的currency信息来显示销售地区)
|
||||
List<ProductResponseDTO.ProductSkuResponseDTO> skuDTOs = skus.stream().map(sku -> {
|
||||
ProductResponseDTO.ProductSkuResponseDTO skuDTO = new ProductResponseDTO.ProductSkuResponseDTO();
|
||||
BeanUtils.copyProperties(sku, skuDTO);
|
||||
return skuDTO;
|
||||
}).collect(Collectors.toList());
|
||||
dto.setSkus(skuDTOs);
|
||||
|
||||
result.add(dto);
|
||||
}
|
||||
|
||||
log.info("获取商品列表成功,商品数量: {}", result.size());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user