diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AlipayController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AlipayController.java new file mode 100644 index 000000000..dfa64eeb0 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AlipayController.java @@ -0,0 +1,180 @@ +package com.ruoyi.web.controller.xkt; + +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.StrUtil; +import com.alipay.api.AlipayApiException; +import com.alipay.api.internal.util.AlipaySignature; +import com.ruoyi.common.core.controller.XktBaseController; +import com.ruoyi.xkt.domain.AlipayCallback; +import com.ruoyi.xkt.domain.StoreOrder; +import com.ruoyi.xkt.enums.EProcessStatus; +import com.ruoyi.xkt.manager.impl.AliPaymentMangerImpl; +import com.ruoyi.xkt.service.IStoreOrderService; +import io.swagger.annotations.Api; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * @author liangyq + * @date 2025-04-07 18:31 + */ +@Api(tags = "支付宝回调接口") +@RestController +@RequestMapping("/rest/v1/alipay") +public class AlipayController extends XktBaseController { + + private static final String SUCCESS = "success"; + private static final String FAILURE = "failure"; + + @Autowired + private IStoreOrderService storeOrderService; + @Autowired + private AliPaymentMangerImpl paymentManger; + + /** + * 支付宝服务器异步通知 + *

+ * 1. 在进行异步通知交互时,如果支付宝收到的应答不是 success ,支付宝会认为通知失败,会通过一定的策略定期重新发起通知。 + * 通知的间隔频率为:4m、10m、10m、1h、2h、6h、15h。 + * 2. 商家设置的异步地址(notify_url)需保证无任何字符,如空格、HTML 标签,且不能重定向。 + * (如果重定向,支付宝会收不到 success 字符,会被支付宝服务器判定为该页面程序运行出现异常,而重发处理结果通知) + * 3. 支付宝是用 POST 方式发送通知信息,商户获取参数的方式如下:request.Form("out_trade_no")、$_POST['out_trade_no']。 + * 4. 支付宝针对同一条异步通知重试时,异步通知参数中的 notify_id 是不变的。 + * + * @param request + * @return + */ + @PostMapping("/notify") + public String notify(HttpServletRequest request) { + Map params = getParamsMap(request); + boolean signVerified = false; + try { + //验证签名 + signVerified = AlipaySignature.rsaCheckV1(params, paymentManger.getAlipayPublicKey(), + paymentManger.getCharset(), paymentManger.getSignType()); + } catch (AlipayApiException e) { + logger.error("支付宝验签异常", e); + } + if (signVerified) { + AlipayCallback alipayCallback = trans2DO(params); + //需要严格按照如下描述校验通知数据的正确性: + //1. 商家需要验证该通知数据中的 out_trade_no 是否为商家系统中创建的订单号。 + StoreOrder order = storeOrderService.getByOrderNo(alipayCallback.getOutTradeNo()); + if (order == null) { + logger.info("支付宝回调订单匹配失败:{}", params); + return FAILURE; + } + //2. 判断 total_amount 是否确实为该订单的实际金额(即商家订单创建时的金额)。 + if (!NumberUtil.equals(order.getTotalAmount(), alipayCallback.getTotalAmount())) { + logger.info("支付宝回调订单金额匹配失败:{}", params); + return FAILURE; + } + //3. 校验通知中的 seller_id(或者 seller_email)是否为 out_trade_no 这笔单据的对应的操作方 + // (有的时候,一个商家可能有多个 seller_id/seller_email)。 + //4. 验证 app_id 是否为该商家本身。 + if (!StrUtil.equals(paymentManger.getAppId(), alipayCallback.getAppId())) { + logger.info("支付宝回调应用ID异常:{}", params); + return FAILURE; + } + //5. 处理支付宝回调信息 + paymentManger.processAlipayCallback(alipayCallback); + return SUCCESS; + } else { + logger.info("支付宝验签未通过:{}", params); + return FAILURE; + } + } + + + /** + * 获取参数 + * + * @param request + * @return + */ + private Map getParamsMap(HttpServletRequest request) { + Map params = new HashMap<>(); + Map requestParams = request.getParameterMap(); + for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) { + String name = (String) iter.next(); + String[] values = (String[]) requestParams.get(name); + String valueStr = ""; + for (int i = 0; i < values.length; i++) { + valueStr = (i == values.length - 1) ? valueStr + values[i] + : valueStr + values[i] + ","; + } + params.put(name, valueStr); + } + return params; + } + + /** + * 转换为do + * + * @param params + * @return + */ + private AlipayCallback trans2DO(Map params) { + AlipayCallback alipayCallback = new AlipayCallback(); + alipayCallback.setNotifyType(params.get("notify_type")); + alipayCallback.setNotifyId(params.get("notify_id")); + alipayCallback.setAppId(params.get("app_id")); + alipayCallback.setCharset(params.get("charset")); + alipayCallback.setVersion(params.get("version")); + alipayCallback.setSignType(params.get("sign_type")); + alipayCallback.setSign(params.get("sign")); + alipayCallback.setTradeNo(params.get("trade_no")); + alipayCallback.setOutTradeNo(params.get("out_trade_no")); + alipayCallback.setOutBizNo(params.get("out_biz_no")); + alipayCallback.setBuyerId(params.get("buyer_id")); + alipayCallback.setBuyerLogonId(params.get("buyer_logon_id")); + alipayCallback.setSellerId(params.get("seller_id")); + alipayCallback.setSellerEmail(params.get("seller_email")); + alipayCallback.setTradeStatus(params.get("trade_status")); + String totalAmountStr = params.get("total_amount"); + alipayCallback.setTotalAmount(trans2BigDecimal(totalAmountStr)); + String receiptAmountStr = params.get("receipt_amount"); + alipayCallback.setReceiptAmount(trans2BigDecimal(receiptAmountStr)); + String invoiceAmountStr = params.get("invoice_amount"); + alipayCallback.setInvoiceAmount(trans2BigDecimal(invoiceAmountStr)); + String buyerPayAmountStr = params.get("buyer_pay_amount"); + alipayCallback.setBuyerPayAmount(trans2BigDecimal(buyerPayAmountStr)); + String pointAmountStr = params.get("point_amount"); + alipayCallback.setPointAmount(trans2BigDecimal(pointAmountStr)); + String refundFeeStr = params.get("refund_fee"); + alipayCallback.setRefundFee(trans2BigDecimal(refundFeeStr)); + alipayCallback.setSubject(params.get("subject")); + alipayCallback.setBody(params.get("body")); + alipayCallback.setGmtCreate(params.get("gmt_create")); + alipayCallback.setGmtPayment(params.get("gmt_payment")); + alipayCallback.setGmtRefund(params.get("gmt_refund")); + alipayCallback.setGmtClose(params.get("gmt_close")); + alipayCallback.setFundBillList(params.get("fund_bill_list")); + alipayCallback.setPassbackParams(params.get("passback_params")); + alipayCallback.setVoucherDetailList(params.get("voucher_detail_list")); + alipayCallback.setProcessStatus(EProcessStatus.INIT.getValue()); + return alipayCallback; + } + + /** + * 转换为BigDecimal + * + * @param value + * @return + */ + private BigDecimal trans2BigDecimal(String value) { + if (StrUtil.isBlank(value)) { + return BigDecimal.ZERO; + } + return new BigDecimal(value); + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index be51d9036..6058fdb10 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -188,6 +188,10 @@ public class Constants public static final Integer SIZE_41 = 41; public static final Integer SIZE_42 = 42; public static final Integer SIZE_43 = 43; + /** + * 平台内部账户ID + */ + public static final Long PLATFORM_INTERNAL_ACCOUNT_ID = 1L; diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java index 15ec7edd7..fca5d57b1 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java @@ -111,10 +111,12 @@ public class SecurityConfig .authorizeHttpRequests((requests) -> { permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll()); // 对于登录login 注册register 验证码captchaImage 允许匿名访问 - requests.antMatchers("/login", "/register", "/captchaImage", "/xkt/test/execute").permitAll() + requests.antMatchers("/login", "/register", "/captchaImage").permitAll() // 静态资源,可匿名访问 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() + //支付宝回调 + .antMatchers("/rest/v1/alipay-notify").permitAll() // 除上面外的所有请求全部需要鉴权认证 .anyRequest().authenticated(); }) diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/payment/PaymentBillInfo.java b/xkt/src/main/java/com/ruoyi/xkt/dto/payment/PaymentBillInfo.java new file mode 100644 index 000000000..e2febb621 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/payment/PaymentBillInfo.java @@ -0,0 +1,23 @@ +package com.ruoyi.xkt.dto.payment; + +import com.ruoyi.xkt.domain.PaymentBill; +import com.ruoyi.xkt.domain.PaymentBillDetail; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author liangyq + * @date 2025-04-08 21:18 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PaymentBillInfo { + + private PaymentBill paymentBill; + + private List paymentBillDetails; +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EProcessStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EProcessStatus.java new file mode 100644 index 000000000..d421a81c5 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EProcessStatus.java @@ -0,0 +1,30 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author liangyq + * @date 2025-04-07 23:42 + */ +@Getter +@AllArgsConstructor +public enum EProcessStatus { + + INIT(1, "初始"), + PROCESSING(2, "处理中"), + SUCCESS(3, "处理成功"), + FAILURE(4, "处理失败"); + + private final Integer value; + private final String label; + + public static EProcessStatus of(Integer value) { + for (EProcessStatus e : EProcessStatus.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java b/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java index 2de6b57c9..fd6a42b21 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java @@ -1,5 +1,6 @@ package com.ruoyi.xkt.manager.impl; +import cn.hutool.core.util.NumberUtil; import com.alibaba.fastjson2.JSON; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; @@ -7,23 +8,29 @@ import com.alipay.api.DefaultAlipayClient; import com.alipay.api.request.AlipayTradePagePayRequest; import com.alipay.api.request.AlipayTradeWapPayRequest; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.xkt.domain.AlipayCallback; import com.ruoyi.xkt.dto.order.StoreOrderInfo; import com.ruoyi.xkt.dto.payment.AlipayReqDTO; import com.ruoyi.xkt.enums.EPayChannel; import com.ruoyi.xkt.enums.EPayFrom; import com.ruoyi.xkt.manager.PaymentManager; +import com.ruoyi.xkt.service.IAlipayCallbackService; import com.ruoyi.xkt.service.IStoreOrderService; import io.jsonwebtoken.lang.Assert; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import java.math.BigDecimal; + /** * @author liangyq * @date 2025-04-06 19:36 */ @Slf4j +@Getter @Component public class AliPaymentMangerImpl implements PaymentManager { /** @@ -39,7 +46,7 @@ public class AliPaymentMangerImpl implements PaymentManager { /** * 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 */ - @Value("${alipay.publicKey:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkiTTeQLIkyVHnYiNmRKEtsdlwKftUySN1SLkrhn6CgmHl5ovjPeYteweZEZmsf2kt6wRnaLkODVP7xUQiRVC2cu6StdJyvDzyiYI00u72PvSOvaWHcpzgKqTFpGiQseJQlHnI8U3ob4PxfJylBy8RDQHG9fZwNY1WOCsnSb3m2ufV1EQIjndzTq13yQE6jCz639rO8atlAG3PtJW/QRiGUzyGaOuKsS4HRzPbbpmVtsXoN76+x+WLWkeqlTBEu35X4Hdbkf1C36wp3b68sI5fVyLksF6elRv/It4aUzjXSXbO/Dx+zvMIN01FgwaFV6nLh++k3qlmo87p4I+hvsGiQIDAQAB}") + @Value("${alipay.alipayPublicKey:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkiTTeQLIkyVHnYiNmRKEtsdlwKftUySN1SLkrhn6CgmHl5ovjPeYteweZEZmsf2kt6wRnaLkODVP7xUQiRVC2cu6StdJyvDzyiYI00u72PvSOvaWHcpzgKqTFpGiQseJQlHnI8U3ob4PxfJylBy8RDQHG9fZwNY1WOCsnSb3m2ufV1EQIjndzTq13yQE6jCz639rO8atlAG3PtJW/QRiGUzyGaOuKsS4HRzPbbpmVtsXoN76+x+WLWkeqlTBEu35X4Hdbkf1C36wp3b68sI5fVyLksF6elRv/It4aUzjXSXbO/Dx+zvMIN01FgwaFV6nLh++k3qlmo87p4I+hvsGiQIDAQAB}") private String alipayPublicKey; /** * 服务器异步通知页面路径 @@ -69,6 +76,8 @@ public class AliPaymentMangerImpl implements PaymentManager { @Autowired private IStoreOrderService storeOrderService; + @Autowired + private IAlipayCallbackService alipayCallbackService; @Override public EPayChannel channel() { @@ -117,4 +126,19 @@ public class AliPaymentMangerImpl implements PaymentManager { } } + public void processAlipayCallback(AlipayCallback alipayCallback) { + AlipayCallback info = alipayCallbackService.getByNotifyId(alipayCallback.getNotifyId()); + if (info == null) { + //保存到数据库 + info = alipayCallback; + alipayCallbackService.insertAlipayCallback(info); + } + if (info.getRefundFee() != null && + !NumberUtil.equals(info.getRefundFee(), BigDecimal.ZERO)) { + //如果有退款金额,可能是部分退款的回调,这里不做处理 + return; + } + //TODO + } + } diff --git a/xkt/src/main/java/com/ruoyi/xkt/mapper/InternalAccountMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/InternalAccountMapper.java index 50320300c..be4ed4909 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/mapper/InternalAccountMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/InternalAccountMapper.java @@ -2,12 +2,31 @@ package com.ruoyi.xkt.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.xkt.domain.InternalAccount; +import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; +import java.util.Collection; +import java.util.List; + /** * @author liangyq * @date 2025-04-02 12:48 */ @Repository public interface InternalAccountMapper extends BaseMapper { + /** + * 获取内部账户(带锁) + * + * @param id + * @return + */ + InternalAccount getForUpdate(@Param("id") Long id); + + /** + * 获取内部账户列表(带锁) + * + * @param ids + * @return + */ + List listForUpdate(@Param("ids") Collection ids); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IAlipayCallbackService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IAlipayCallbackService.java new file mode 100644 index 000000000..c28aaaaf1 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IAlipayCallbackService.java @@ -0,0 +1,27 @@ +package com.ruoyi.xkt.service; + +import com.ruoyi.xkt.domain.AlipayCallback; + +/** + * @author liangyq + * @date 2025-04-08 17:39 + */ +public interface IAlipayCallbackService { + + /** + * 通过通知ID获取回调信息 + * + * @param notifyId + * @return + */ + AlipayCallback getByNotifyId(String notifyId); + + /** + * 保存回调信息 + * + * @param alipayCallback + * @return + */ + int insertAlipayCallback(AlipayCallback alipayCallback); + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IInternalAccountService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IInternalAccountService.java new file mode 100644 index 000000000..d13d02f5e --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IInternalAccountService.java @@ -0,0 +1,30 @@ +package com.ruoyi.xkt.service; + +import com.ruoyi.xkt.domain.InternalAccount; + +import java.util.Collection; +import java.util.List; + +/** + * @author liangyq + * @date 2025-04-08 21:14 + */ +public interface IInternalAccountService { + + /** + * 获取内部账户(加锁) + * + * @param id + * @return + */ + InternalAccount getWithLock(Long id); + + /** + * 获取内部账户列表(加锁) + * + * @param ids + * @return + */ + List listWithLock(Collection ids); + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IPaymentBillService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IPaymentBillService.java new file mode 100644 index 000000000..63f4f2cb7 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IPaymentBillService.java @@ -0,0 +1,18 @@ +package com.ruoyi.xkt.service; + +import com.ruoyi.xkt.dto.order.StoreOrderInfo; +import com.ruoyi.xkt.dto.payment.PaymentBillInfo; + +/** + * @author liangyq + * @date 2025-04-08 21:14 + */ +public interface IPaymentBillService { + /** + * 根据订单创建收款单 + * + * @param orderInfo + * @return + */ + PaymentBillInfo createCollectionBillByOrder(StoreOrderInfo orderInfo); +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java index 18bc851e6..eda5fe1c9 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java @@ -1,5 +1,6 @@ package com.ruoyi.xkt.service; +import com.ruoyi.xkt.domain.StoreOrder; import com.ruoyi.xkt.dto.order.StoreOrderAddDTO; import com.ruoyi.xkt.dto.order.StoreOrderInfo; @@ -16,6 +17,14 @@ public interface IStoreOrderService { */ StoreOrderInfo createOrder(StoreOrderAddDTO storeOrderAddDTO); + /** + * 通过订单号获取订单 + * + * @param orderNo + * @return + */ + StoreOrder getByOrderNo(String orderNo); + /** * 准备支付订单 * diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/AlipayCallbackServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AlipayCallbackServiceImpl.java new file mode 100644 index 000000000..50c7d0f1a --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AlipayCallbackServiceImpl.java @@ -0,0 +1,36 @@ +package com.ruoyi.xkt.service.impl; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ruoyi.xkt.domain.AlipayCallback; +import com.ruoyi.xkt.mapper.AlipayCallbackMapper; +import com.ruoyi.xkt.service.IAlipayCallbackService; +import io.jsonwebtoken.lang.Assert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * @author liangyq + * @date 2025-04-08 17:40 + */ +@Service +public class AlipayCallbackServiceImpl implements IAlipayCallbackService { + + @Autowired + private AlipayCallbackMapper alipayCallbackMapper; + + + @Override + public AlipayCallback getByNotifyId(String notifyId) { + Assert.notNull(notifyId); + return alipayCallbackMapper.selectOne(Wrappers.lambdaQuery(AlipayCallback.class) + .eq(AlipayCallback::getNotifyId, notifyId)); + } + + @Transactional + @Override + public int insertAlipayCallback(AlipayCallback alipayCallback) { + Assert.notNull(alipayCallback); + return alipayCallbackMapper.insert(alipayCallback); + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/InternalAccountServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/InternalAccountServiceImpl.java new file mode 100644 index 000000000..aed4268ec --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/InternalAccountServiceImpl.java @@ -0,0 +1,37 @@ +package com.ruoyi.xkt.service.impl; + +import com.ruoyi.xkt.domain.InternalAccount; +import com.ruoyi.xkt.mapper.InternalAccountMapper; +import com.ruoyi.xkt.mapper.InternalAccountTransDetailMapper; +import com.ruoyi.xkt.service.IInternalAccountService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; +import java.util.List; + +/** + * @author liangyq + * @date 2025-04-08 21:14 + */ +@Service +public class InternalAccountServiceImpl implements IInternalAccountService { + + @Autowired + private InternalAccountMapper internalAccountMapper; + @Autowired + private InternalAccountTransDetailMapper internalAccountTransDetailMapper; + + @Transactional + @Override + public InternalAccount getWithLock(Long id) { + return internalAccountMapper.getForUpdate(id); + } + + @Transactional + @Override + public List listWithLock(Collection ids) { + return internalAccountMapper.listForUpdate(ids); + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/PaymentBillServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/PaymentBillServiceImpl.java new file mode 100644 index 000000000..551233b93 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/PaymentBillServiceImpl.java @@ -0,0 +1,35 @@ +package com.ruoyi.xkt.service.impl; + +import com.ruoyi.common.constant.Constants; +import com.ruoyi.xkt.domain.InternalAccount; +import com.ruoyi.xkt.dto.order.StoreOrderInfo; +import com.ruoyi.xkt.dto.payment.PaymentBillInfo; +import com.ruoyi.xkt.mapper.PaymentBillDetailMapper; +import com.ruoyi.xkt.mapper.PaymentBillMapper; +import com.ruoyi.xkt.service.IInternalAccountService; +import com.ruoyi.xkt.service.IPaymentBillService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * @author liangyq + * @date 2025-04-08 21:14 + */ +@Service +public class PaymentBillServiceImpl implements IPaymentBillService { + + @Autowired + private PaymentBillMapper paymentBillMapper; + @Autowired + private PaymentBillDetailMapper paymentBillDetailMapper; + @Autowired + private IInternalAccountService internalAccountService; + + @Transactional + @Override + public PaymentBillInfo createCollectionBillByOrder(StoreOrderInfo orderInfo) { + InternalAccount ca = internalAccountService.getWithLock(Constants.PLATFORM_INTERNAL_ACCOUNT_ID); + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java index dd8d88ce8..63ef3c0bd 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java @@ -163,6 +163,13 @@ public class StoreOrderServiceImpl implements IStoreOrderService { return new StoreOrderInfo(order, orderDetailList); } + @Override + public StoreOrder getByOrderNo(String orderNo) { + Assert.notNull(orderNo); + return storeOrderMapper.selectOne(Wrappers.lambdaQuery(StoreOrder.class) + .eq(StoreOrder::getOrderNo, orderNo)); + } + @Transactional @Override public StoreOrderInfo preparePayOrder(Long storeOrderId) { diff --git a/xkt/src/main/resources/mapper/InternalAccountMapper.xml b/xkt/src/main/resources/mapper/InternalAccountMapper.xml index af5cc8f60..247bb217c 100644 --- a/xkt/src/main/resources/mapper/InternalAccountMapper.xml +++ b/xkt/src/main/resources/mapper/InternalAccountMapper.xml @@ -2,4 +2,15 @@ + + \ No newline at end of file