diff --git a/doc/订单支付API文档.md b/doc/订单支付API文档.md new file mode 100644 index 0000000..8796aad --- /dev/null +++ b/doc/订单支付API文档.md @@ -0,0 +1,198 @@ +# 订单支付API文档 + +## 概述 +本文档描述了客户端订单支付相关的API接口,包括创建订单、支付、退款等完整流程。 + +## 基础信息 +- 基础URL: `/client/order` +- 请求方式: REST API +- 数据格式: JSON +- 认证方式: Token认证 + +## 订单状态说明 +- 1: 已创建 - 订单创建成功,等待支付 +- 2: 已支付 - 支付成功,等待服务开始 +- 3: 已完成 - 服务完成 +- 4: 已退款 - 订单已退款 +- 5: 已取消 - 订单已取消 + +## 支付方式 +- aliPay: 支付宝支付 +- wechatPay: 微信支付 +- applePay: Apple Pay支付 + +## API接口 + +### 1. 创建订单 +**接口地址**: `POST /client/order/create` + +**请求参数**: +```json +{ + "orderName": "VIP会员包月", + "amount": 9900, + "payType": "aliPay", + "packageType": "1", + "deviceType": "android" +} +``` + +**响应示例**: +```json +{ + "code": 200, + "msg": "订单创建成功", + "data": { + "id": "uuid", + "orderId": 1706342400000, + "orderName": "VIP会员包月", + "userId": 1, + "amount": 9900, + "payType": "aliPay", + "payStatus": 1, + "packageType": "1", + "deviceType": "android", + "createTime": "2025-01-27 10:00:00" + } +} +``` + +### 2. 支付订单 +**接口地址**: `POST /client/order/pay` + +**请求参数**: +```json +{ + "orderId": "1706342400000", + "payType": "aliPay", + "deviceType": "android", + "paymentParams": "{}" +} +``` + +**响应示例**: +```json +{ + "code": 200, + "msg": "支付请求成功", + "data": { + "paymentUrl": "https://openapi.alipay.com/gateway.do?", + "orderId": "1706342400000", + "amount": 9900, + "payType": "aliPay" + } +} +``` + +### 3. 支付回调 +**接口地址**: `POST /client/order/callback` + +**请求参数**: +- orderId: 订单ID +- tradeNo: 第三方交易号 +- payType: 支付方式 + +**响应示例**: +```json +{ + "code": 200, + "msg": "支付完成" +} +``` + +### 4. 申请退款 +**接口地址**: `POST /client/order/refund` + +**请求参数**: +```json +{ + "orderId": "1706342400000", + "refundAmount": 9900, + "refundReason": "用户申请退款", + "refundType": 1 +} +``` + +**响应示例**: +```json +{ + "code": 200, + "msg": "退款申请成功" +} +``` + +### 5. 查询用户订单列表 +**接口地址**: `GET /client/order/list` + +**响应示例**: +```json +{ + "code": 200, + "msg": "查询成功", + "data": [ + { + "id": "uuid", + "orderId": "1706342400000", + "orderName": "VIP会员包月", + "amount": 9900, + "payType": "aliPay", + "payStatus": 2, + "payTime": "2025-01-27 10:05:00", + "startTime": "2025-01-27 10:05:00", + "endTime": "2025-02-27 10:05:00", + "createTime": "2025-01-27 10:00:00" + } + ] +} +``` + +### 6. 查询订单详情 +**接口地址**: `GET /client/order/detail/{orderId}` + +**响应示例**: +```json +{ + "code": 200, + "msg": "查询成功", + "data": { + "id": "uuid", + "orderId": "1706342400000", + "orderName": "VIP会员包月", + "userId": 1, + "amount": 9900, + "payType": "aliPay", + "payStatus": 2, + "payTime": "2025-01-27 10:05:00", + "startTime": "2025-01-27 10:05:00", + "endTime": "2025-02-27 10:05:00", + "tradeNo": "2025012722001234567890", + "createTime": "2025-01-27 10:00:00", + "updateTime": "2025-01-27 10:05:00" + } +} +``` + +## 错误码说明 +- 200: 成功 +- 400: 请求参数错误 +- 401: 用户未登录 +- 403: 权限不足 +- 404: 资源不存在 +- 500: 服务器内部错误 + +## 套餐类型说明 +- 1: 包月 +- 3: 包季度 +- 6: 半年 +- 12: 一年 + +## 设备类型说明 +- android: Android设备 +- ios: iOS设备 + +## 注意事项 +1. 所有金额单位为分 +2. 支付回调需要验证签名 +3. 退款只能对已支付的订单进行 +4. 订单创建后需要在指定时间内完成支付 +5. 支付成功后会自动计算服务时间 \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/back/ActivityInfoController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/back/ActivityInfoController.java index 8d47c44..44681d8 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/back/ActivityInfoController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/back/ActivityInfoController.java @@ -75,13 +75,6 @@ public class ActivityInfoController extends BaseController // @Log(title = "【请填写功能名称】", businessType = BusinessType.INSERT) @PostMapping("/addActivity") public AjaxResult add(@RequestBody ActivityInfo activityInfo) throws IOException { -// ActivityInfo activityInfo = new ActivityInfo(); -// String imgAddr = AliConfig.ossUp("config/" , Objects.requireNonNull(file.getOriginalFilename()), file.getInputStream()); -// activityInfo.setImg(""); -// activityInfo.setName(name); -// activityInfo.setContent(content); -// activityInfo.setStartTime(DateUtil.parseDateTime(startTime)); -// activityInfo.setEndTime(DateUtil.parseDateTime(endTime)); return toAjax(activityInfoService.insertActivityInfo(activityInfo)); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/back/OrderInfoController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/back/OrderInfoController.java index 861a3de..9c28bd2 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/back/OrderInfoController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/back/OrderInfoController.java @@ -4,6 +4,7 @@ import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.OrderInfo; +import com.ruoyi.common.core.domain.vo.OrderInfoVO; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.poi.ExcelUtil; @@ -22,7 +23,7 @@ import java.util.List; * @date 2025-08-03 */ @RestController -@RequestMapping("/back/info") +@RequestMapping("/back/order") public class OrderInfoController extends BaseController { @Autowired @@ -40,6 +41,18 @@ public class OrderInfoController extends BaseController return getDataTable(list); } + /** + * 查询订单详细信息列表 + */ + // @PreAuthorize("@ss.hasPermi('system:info:list')") + @GetMapping("/detailList") + public TableDataInfo detailList(OrderInfo orderInfo) + { + startPage(); + List list = orderInfoService.selectOrderInfoVOList(orderInfo); + return getDataTable(list); + } + /** * 导出【请填写功能名称】列表 */ @@ -53,6 +66,19 @@ public class OrderInfoController extends BaseController util.exportExcel(response, list, "【请填写功能名称】数据"); } + /** + * 导出订单详细信息列表 + */ + @PreAuthorize("@ss.hasPermi('system:info:export')") + @Log(title = "订单详细信息", businessType = BusinessType.EXPORT) + @PostMapping("/exportDetail") + public void exportDetail(HttpServletResponse response, OrderInfo orderInfo) + { + List list = orderInfoService.selectOrderInfoVOList(orderInfo); + ExcelUtil util = new ExcelUtil(OrderInfoVO.class); + util.exportExcel(response, list, "订单详细信息数据"); + } + /** * 获取【请填写功能名称】详细信息 */ @@ -95,4 +121,15 @@ public class OrderInfoController extends BaseController { return toAjax(orderInfoService.deleteOrderInfoByIds(ids)); } + + /** + * 确认出货 + */ + @PreAuthorize("@ss.hasPermi('system:info:edit')") + @Log(title = "确认出货", businessType = BusinessType.UPDATE) + @PostMapping("/confirmShipment/{orderId}") + public AjaxResult confirmShipment(@PathVariable String orderId) + { + return orderInfoService.confirmShipment(orderId); + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/ClientOrderInfoController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/ClientOrderInfoController.java index 030b7d8..0f2b3ae 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/ClientOrderInfoController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/ClientOrderInfoController.java @@ -1,19 +1,27 @@ package com.ruoyi.web.controller.client; +import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.OrderInfo; +import com.ruoyi.common.core.domain.dto.OrderCreateRequest; +import com.ruoyi.common.core.domain.dto.PaymentRequest; +import com.ruoyi.common.core.domain.dto.RefundRequest; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.system.service.IOrderInfoService; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; /** - * 【请填写功能名称】Controller + * 客户端订单Controller * * @author ruoyi - * @date 2025-08-03 + * @date 2025-01-27 */ @RestController @RequestMapping("/client/order") @@ -22,13 +30,137 @@ public class ClientOrderInfoController extends BaseController @Autowired private IOrderInfoService orderInfoService; - // 创建订单 + /** + * 创建订单 + */ + @Log(title = "创建订单", businessType = BusinessType.INSERT) @PostMapping("/create") - public void crateOrder(@RequestBody OrderInfo orderInfo){ - - orderInfoService.createOrder(orderInfo); - + public AjaxResult createOrder(@RequestBody OrderCreateRequest request, HttpServletRequest httpRequest) { + try { + // 获取客户端IP + String clientIp = getClientIp(httpRequest); + request.setClientIp(clientIp); + + return orderInfoService.createOrder(request); + } catch (Exception e) { + return AjaxResult.error("创建订单失败: " + e.getMessage()); + } } + /** + * 支付订单 + */ + @Log(title = "支付订单", businessType = BusinessType.UPDATE) + @PostMapping("/pay") + public AjaxResult payOrder(@RequestBody PaymentRequest request) { + try { + return orderInfoService.payOrder(request); + } catch (Exception e) { + return AjaxResult.error("支付失败: " + e.getMessage()); + } + } + /** + * 支付回调 + */ + @PostMapping("/callback") + public AjaxResult paymentCallback(@RequestParam("orderId") String orderId, + @RequestParam("tradeNo") String tradeNo, + @RequestParam("payType") String payType) { + try { + return orderInfoService.completePayment(orderId, tradeNo, payType); + } catch (Exception e) { + return AjaxResult.error("支付回调处理失败: " + e.getMessage()); + } + } + + /** + * 确认出货 + */ + @Log(title = "确认出货", businessType = BusinessType.UPDATE) + @PostMapping("/confirmShipment") + public AjaxResult confirmShipment(@RequestParam("orderId") String orderId) { + try { + return orderInfoService.confirmShipment(orderId); + } catch (Exception e) { + return AjaxResult.error("确认出货失败: " + e.getMessage()); + } + } + + /** + * 申请退款 + */ + @Log(title = "申请退款", businessType = BusinessType.UPDATE) + @PostMapping("/refund") + public AjaxResult refundOrder(@RequestBody RefundRequest request) { + try { + return orderInfoService.refundOrder(request); + } catch (Exception e) { + return AjaxResult.error("退款申请失败: " + e.getMessage()); + } + } + + /** + * 查询用户订单列表 + */ + @GetMapping("/list") + public AjaxResult getUserOrders() { + try { + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser == null) { + return AjaxResult.error("用户未登录"); + } + + List orders = orderInfoService.selectUserOrders(loginUser.getUserId()); + return AjaxResult.success("查询成功", orders); + } catch (Exception e) { + return AjaxResult.error("查询订单失败: " + e.getMessage()); + } + } + + /** + * 查询订单详情 + */ + @GetMapping("/detail/{orderId}") + public AjaxResult getOrderDetail(@PathVariable String orderId) { + try { + OrderInfo orderInfo = orderInfoService.selectOrderByOrderId(orderId); + if (orderInfo == null) { + return AjaxResult.error("订单不存在"); + } + + // 检查用户权限 + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser == null || !loginUser.getUserId().equals(orderInfo.getUserId())) { + return AjaxResult.error("无权限查看此订单"); + } + + return AjaxResult.success("查询成功", orderInfo); + } catch (Exception e) { + return AjaxResult.error("查询订单详情失败: " + e.getMessage()); + } + } + + /** + * 获取客户端IP地址 + */ + private String getClientIp(HttpServletRequest request) { + String ip = request.getHeader("X-Forwarded-For"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + return ip; + } } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/config/AliPayConfig.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/AliPayConfig.java index 641bd8d..dd5cd84 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/config/AliPayConfig.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/AliPayConfig.java @@ -1,62 +1,62 @@ -package com.ruoyi.common.config; - -import com.alipay.easysdk.factory.Factory; -import com.alipay.easysdk.kernel.Config; -import lombok.Getter; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.stereotype.Component; - -/** - * 描述: - * - * @author menxipeng by 2023/12/15 - */ -@Getter -@Component -public class AliPayConfig { - - @Value("${alipay.gateway}") - private String aliPayGateway; - @Value("${alipay.appid}") - private String aliPayAppid; - @Value("${alipay.privateKey}") - private String aliPayPrivateKey; - @Value("${alipay.publicKey}") - private String aliPayPublicKey; - @Value("${alipay.merchantCertPath}") - private String merchantCertPath; - @Value("${alipay.alipayCertPath}") - private String alipayCertPath; - @Value("${alipay.alipayRootCertPath}") - private String alipayRootCertPath; - @Value("${alipay.notifyUrl}") - private String aliPayNotifyUrl; - @Value("${alipay.authUrl}") - private String aliPayAuthUrl; - @Value("${alipay.timeout}") - private Integer aliTimeOut; - - - @Bean - public void init() { - Config config = new Config(); - config.protocol = "https"; - config.gatewayHost = "openapi.alipay.com"; - config.signType = "RSA2"; - - config.appId = aliPayAppid; - // 为避免私钥随源码泄露,推荐从文件中读取私钥字符串而不是写入源码中 - config.merchantPrivateKey = aliPayPrivateKey; - //注:证书文件路径支持设置为文件系统中的路径或CLASS_PATH中的路径,优先从文件系统中加载,加载失败后会继续尝试从CLASS_PATH中加载 - config.merchantCertPath = merchantCertPath; - config.alipayCertPath = alipayCertPath; - config.alipayRootCertPath = alipayRootCertPath; - //注:如果采用非证书模式,则无需赋值上面的三个证书路径,改为赋值如下的支付宝公钥字符串即可 - //可设置异步通知接收服务地址(可选) - config.notifyUrl = aliPayNotifyUrl; - - Factory.setOptions(config); - } - -} +//package com.ruoyi.common.config; +// +//import com.alipay.easysdk.factory.Factory; +//import com.alipay.easysdk.kernel.Config; +//import lombok.Getter; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.context.annotation.Bean; +//import org.springframework.stereotype.Component; +// +///** +// * 描述: +// * +// * @author menxipeng by 2023/12/15 +// */ +//@Getter +//@Component +//public class AliPayConfig { +// +// @Value("${alipay.gateway}") +// private String aliPayGateway; +// @Value("${alipay.appid}") +// private String aliPayAppid; +// @Value("${alipay.privateKey}") +// private String aliPayPrivateKey; +// @Value("${alipay.publicKey}") +// private String aliPayPublicKey; +// @Value("${alipay.merchantCertPath}") +// private String merchantCertPath; +// @Value("${alipay.alipayCertPath}") +// private String alipayCertPath; +// @Value("${alipay.alipayRootCertPath}") +// private String alipayRootCertPath; +// @Value("${alipay.notifyUrl}") +// private String aliPayNotifyUrl; +// @Value("${alipay.authUrl}") +// private String aliPayAuthUrl; +// @Value("${alipay.timeout}") +// private Integer aliTimeOut; +// +// +// @Bean +// public void init() { +// Config config = new Config(); +// config.protocol = "https"; +// config.gatewayHost = "openapi.alipay.com"; +// config.signType = "RSA2"; +// +// config.appId = aliPayAppid; +// // 为避免私钥随源码泄露,推荐从文件中读取私钥字符串而不是写入源码中 +// config.merchantPrivateKey = aliPayPrivateKey; +// //注:证书文件路径支持设置为文件系统中的路径或CLASS_PATH中的路径,优先从文件系统中加载,加载失败后会继续尝试从CLASS_PATH中加载 +// config.merchantCertPath = merchantCertPath; +// config.alipayCertPath = alipayCertPath; +// config.alipayRootCertPath = alipayRootCertPath; +// //注:如果采用非证书模式,则无需赋值上面的三个证书路径,改为赋值如下的支付宝公钥字符串即可 +// //可设置异步通知接收服务地址(可选) +// config.notifyUrl = aliPayNotifyUrl; +// +// Factory.setOptions(config); +// } +// +//} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/OrderCreateRequest.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/OrderCreateRequest.java new file mode 100644 index 0000000..7f9cb30 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/OrderCreateRequest.java @@ -0,0 +1,80 @@ +package com.ruoyi.common.core.domain.dto; + +import java.io.Serializable; + +/** + * 订单创建请求DTO + * + * @author ruoyi + * @date 2025-01-27 + */ +public class OrderCreateRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 订单名称 */ + private String orderName; + + /** 金额(分) */ + private Long amount; + + /** 支付方式 aliPay/wechatPay/applePay */ + private String payType; + + /** 套餐类型 1包月 3包季度 6半年 12一年 */ + private String packageType; + + /** 设备类型 android/ios */ + private String deviceType; + + /** 客户端IP */ + private String clientIp; + + public String getOrderName() { + return orderName; + } + + public void setOrderName(String orderName) { + this.orderName = orderName; + } + + public Long getAmount() { + return amount; + } + + public void setAmount(Long amount) { + this.amount = amount; + } + + public String getPayType() { + return payType; + } + + public void setPayType(String payType) { + this.payType = payType; + } + + public String getPackageType() { + return packageType; + } + + public void setPackageType(String packageType) { + this.packageType = packageType; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getClientIp() { + return clientIp; + } + + public void setClientIp(String clientIp) { + this.clientIp = clientIp; + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/PaymentRequest.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/PaymentRequest.java new file mode 100644 index 0000000..fcf65d7 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/PaymentRequest.java @@ -0,0 +1,124 @@ +package com.ruoyi.common.core.domain.dto; + +import java.io.Serializable; + +/** + * 支付请求DTO + * + * @author ruoyi + * @date 2025-01-27 + */ +public class PaymentRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 订单ID */ + private String orderId; + + /** 支付方式 aliPay/wechatPay/applePay */ + private String payType; + + /** 设备类型 android/ios */ + private String deviceType; + + /** 商品标题 */ + private String subject; + + /** 商品描述 */ + private String body; + + /** 附加数据 */ + private String attach; + + /** 用户openid(微信支付专用) */ + private String openid; + + /** 商户标识符(Apple Pay专用) */ + private String merchantIdentifier; + + /** 支付令牌(Apple Pay专用) */ + private String paymentToken; + + /** 订单超时时间(分钟) */ + private Integer timeoutMinutes; + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getPayType() { + return payType; + } + + public void setPayType(String payType) { + this.payType = payType; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } + + public String getAttach() { + return attach; + } + + public void setAttach(String attach) { + this.attach = attach; + } + + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + public String getMerchantIdentifier() { + return merchantIdentifier; + } + + public void setMerchantIdentifier(String merchantIdentifier) { + this.merchantIdentifier = merchantIdentifier; + } + + public String getPaymentToken() { + return paymentToken; + } + + public void setPaymentToken(String paymentToken) { + this.paymentToken = paymentToken; + } + + public Integer getTimeoutMinutes() { + return timeoutMinutes; + } + + public void setTimeoutMinutes(Integer timeoutMinutes) { + this.timeoutMinutes = timeoutMinutes; + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/RefundRequest.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/RefundRequest.java new file mode 100644 index 0000000..369d777 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/dto/RefundRequest.java @@ -0,0 +1,58 @@ +package com.ruoyi.common.core.domain.dto; + +import java.io.Serializable; + +/** + * 退款请求DTO + * + * @author ruoyi + * @date 2025-01-27 + */ +public class RefundRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 订单ID */ + private String orderId; + + /** 退款金额(分) */ + private Long refundAmount; + + /** 退款原因 */ + private String refundReason; + + /** 退款方式 1全额退款 2部分退款 */ + private Integer refundType; + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public Long getRefundAmount() { + return refundAmount; + } + + public void setRefundAmount(Long refundAmount) { + this.refundAmount = refundAmount; + } + + public String getRefundReason() { + return refundReason; + } + + public void setRefundReason(String refundReason) { + this.refundReason = refundReason; + } + + public Integer getRefundType() { + return refundType; + } + + public void setRefundType(Integer refundType) { + this.refundType = refundType; + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/OrderInfoVO.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/OrderInfoVO.java new file mode 100644 index 0000000..21b0a79 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/OrderInfoVO.java @@ -0,0 +1,127 @@ +package com.ruoyi.common.core.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 订单信息VO + * + * @author ruoyi + * @date 2025-01-27 + */ +public class OrderInfoVO { + + /** 订单号 */ + @Excel(name = "订单号") + private Long orderId; + + /** 用户昵称 */ + @Excel(name = "用户昵称") + private String userNickname; + + /** 套餐名称 */ + @Excel(name = "套餐名称") + private String packageName; + + /** 支付金额(元) */ + @Excel(name = "支付金额(元)") + private BigDecimal amountYuan; + + /** 支付方式 */ + @Excel(name = "支付方式") + private String payTypeName; + + /** 开通时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "开通时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date startTime; + + /** 到期时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "到期时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date endTime; + + /** 订单状态 */ + @Excel(name = "订单状态") + private String statusName; + + /** 创建时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + public Long getOrderId() { + return orderId; + } + + public void setOrderId(Long orderId) { + this.orderId = orderId; + } + + public String getUserNickname() { + return userNickname; + } + + public void setUserNickname(String userNickname) { + this.userNickname = userNickname; + } + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public BigDecimal getAmountYuan() { + return amountYuan; + } + + public void setAmountYuan(BigDecimal amountYuan) { + this.amountYuan = amountYuan; + } + + public String getPayTypeName() { + return payTypeName; + } + + public void setPayTypeName(String payTypeName) { + this.payTypeName = payTypeName; + } + + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + public Date getEndTime() { + return endTime; + } + + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/OrderStatus.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/OrderStatus.java new file mode 100644 index 0000000..22bd5ea --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/OrderStatus.java @@ -0,0 +1,41 @@ +package com.ruoyi.common.enums; + +/** + * 订单状态枚举 + * + * @author ruoyi + * @date 2025-01-27 + */ +public enum OrderStatus { + + CREATED(1L, "已创建"), + PAID(2L, "已支付"), + COMPLETED(3L, "已完成"), + REFUNDED(4L, "已退款"), + CANCELLED(5L, "已取消"); + + private final Long code; + private final String description; + + OrderStatus(Long code, String description) { + this.code = code; + this.description = description; + } + + public Long getCode() { + return code; + } + + public String getDescription() { + return description; + } + + public static OrderStatus getByCode(Long code) { + for (OrderStatus status : values()) { + if (status.getCode().equals(code)) { + return status; + } + } + return null; + } +} \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderInfoMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderInfoMapper.java index db974a8..d0b9d0e 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderInfoMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderInfoMapper.java @@ -1,6 +1,7 @@ package com.ruoyi.system.mapper; import com.ruoyi.common.core.domain.entity.OrderInfo; +import com.ruoyi.common.core.domain.vo.OrderInfoVO; import java.util.List; @@ -59,4 +60,20 @@ public interface OrderInfoMapper * @return 结果 */ public int deleteOrderInfoByIds(String[] ids); + + /** + * 根据订单号查询订单 + * + * @param orderId 订单号 + * @return 订单信息 + */ + public OrderInfo selectOrderByOrderId(String orderId); + + /** + * 查询订单列表(包含用户信息和套餐信息) + * + * @param orderInfo 查询条件 + * @return 订单列表 + */ + public List selectOrderInfoVOList(OrderInfo orderInfo); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderInfoService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderInfoService.java index 06845de..342c1cb 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderInfoService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderInfoService.java @@ -2,6 +2,10 @@ package com.ruoyi.system.service; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.OrderInfo; +import com.ruoyi.common.core.domain.dto.OrderCreateRequest; +import com.ruoyi.common.core.domain.dto.PaymentRequest; +import com.ruoyi.common.core.domain.dto.RefundRequest; +import com.ruoyi.common.core.domain.vo.OrderInfoVO; import java.util.List; @@ -61,5 +65,69 @@ public interface IOrderInfoService */ public int deleteOrderInfoById(String id); - AjaxResult createOrder(OrderInfo orderInfo); + /** + * 创建订单 + * + * @param request 订单创建请求 + * @return 结果 + */ + AjaxResult createOrder(OrderCreateRequest request); + + /** + * 支付订单 + * + * @param request 支付请求 + * @return 结果 + */ + AjaxResult payOrder(PaymentRequest request); + + /** + * 完成支付(支付回调) + * + * @param orderId 订单ID + * @param tradeNo 第三方交易号 + * @param payType 支付方式 + * @return 结果 + */ + AjaxResult completePayment(String orderId, String tradeNo, String payType); + + /** + * 确认出货 + * + * @param orderId 订单ID + * @return 结果 + */ + AjaxResult confirmShipment(String orderId); + + /** + * 申请退款 + * + * @param request 退款请求 + * @return 结果 + */ + AjaxResult refundOrder(RefundRequest request); + + /** + * 查询用户订单列表 + * + * @param userId 用户ID + * @return 订单列表 + */ + List selectUserOrders(Long userId); + + /** + * 查询订单详情 + * + * @param orderId 订单ID + * @return 订单详情 + */ + OrderInfo selectOrderByOrderId(String orderId); + + /** + * 查询订单列表(包含用户信息和套餐信息) + * + * @param orderInfo 查询条件 + * @return 订单列表 + */ + List selectOrderInfoVOList(OrderInfo orderInfo); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderInfoServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderInfoServiceImpl.java index 2cdafc4..74d6ffa 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderInfoServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderInfoServiceImpl.java @@ -1,16 +1,24 @@ package com.ruoyi.system.service.impl; import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.dto.OrderCreateRequest; +import com.ruoyi.common.core.domain.dto.PaymentRequest; +import com.ruoyi.common.core.domain.dto.RefundRequest; import com.ruoyi.common.core.domain.entity.OrderInfo; +import com.ruoyi.common.core.domain.entity.PayStatusEnum; +import com.ruoyi.common.core.domain.vo.OrderInfoVO; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.mapper.OrderInfoMapper; import com.ruoyi.system.service.IOrderInfoService; +import com.ruoyi.system.util.PaymentUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; -import java.util.List; +import java.util.*; /** * 【请填写功能名称】Service业务层处理 @@ -23,6 +31,9 @@ public class OrderInfoServiceImpl implements IOrderInfoService { @Autowired private OrderInfoMapper orderInfoMapper; + + @Autowired + private PaymentUtil paymentUtil; /** * 查询【请填写功能名称】 @@ -99,13 +110,272 @@ public class OrderInfoServiceImpl implements IOrderInfoService } @Override - public AjaxResult createOrder(OrderInfo orderInfo) { - LoginUser userInfo = SecurityUtils.getLoginUser(); - - if (userInfo != null){ - //orderInfo.setPayStatus(); + @Transactional + public AjaxResult createOrder(OrderCreateRequest request) { + try { + // 参数校验 + if (StringUtils.isEmpty(request.getOrderName()) || request.getAmount() == null || request.getAmount() <= 0) { + return AjaxResult.error("订单信息不完整"); + } + + // 获取当前用户 + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser == null) { + return AjaxResult.error("用户未登录"); + } + + // 创建订单 + OrderInfo orderInfo = new OrderInfo(); + orderInfo.setId(UUID.randomUUID().toString().replace("-", "")); + orderInfo.setOrderId(System.currentTimeMillis()); // 使用时间戳作为订单号 + orderInfo.setOrderName(request.getOrderName()); + orderInfo.setUserId(loginUser.getUserId()); + orderInfo.setAmount(request.getAmount()); + orderInfo.setPayType(request.getPayType()); + orderInfo.setPackageType(request.getPackageType()); + orderInfo.setDeviceType(request.getDeviceType()); + orderInfo.setClientIp(request.getClientIp()); + orderInfo.setPayStatus(PayStatusEnum.CREATE.status); // 1-创建订单 + orderInfo.setIdDel(0L); + orderInfo.setVersion(1L); + orderInfo.setCreateTime(DateUtils.getNowDate()); + + // 保存订单 + int result = insertOrderInfo(orderInfo); + if (result > 0) { + return AjaxResult.success("订单创建成功", orderInfo); + } else { + return AjaxResult.error("订单创建失败"); + } + } catch (Exception e) { + return AjaxResult.error("订单创建异常: " + e.getMessage()); } + } - return null; + @Override + @Transactional + public AjaxResult payOrder(PaymentRequest request) { + try { + // 参数校验 + if (StringUtils.isEmpty(request.getOrderId())) { + return AjaxResult.error("订单ID不能为空"); + } + + // 查询订单 + OrderInfo orderInfo = selectOrderByOrderId(request.getOrderId()); + if (orderInfo == null) { + return AjaxResult.error("订单不存在"); + } + + // 检查订单状态 + if (orderInfo.getPayStatus() != PayStatusEnum.CREATE.getStatus()) { + return AjaxResult.error("订单状态不正确"); + } + + // 检查用户权限 + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser == null || !loginUser.getUserId().equals(orderInfo.getUserId())) { + return AjaxResult.error("无权限操作此订单"); + } + + // 调用第三方支付接口 + Map paymentResult = processPayment(orderInfo, request); + + return AjaxResult.success("支付请求成功", paymentResult); + + } catch (Exception e) { + return AjaxResult.error("支付异常: " + e.getMessage()); + } + } + + @Override + @Transactional + public AjaxResult completePayment(String orderId, String tradeNo, String payType) { + try { + // 查询订单 + OrderInfo orderInfo = selectOrderByOrderId(orderId); + if (orderInfo == null) { + return AjaxResult.error("订单不存在"); + } + + // 检查订单状态 + if (orderInfo.getPayStatus() != PayStatusEnum.CREATE.getStatus()) { + return AjaxResult.error("订单状态不正确"); + } + + // 更新订单状态 + orderInfo.setPayStatus(PayStatusEnum.PENDING.getStatus()); // 2-待出货 + orderInfo.setPayTime(DateUtils.getNowDate()); + orderInfo.setTradeNo(tradeNo); + orderInfo.setCallTime(DateUtils.getNowDate()); + orderInfo.setCallbackContent("支付成功回调"); + orderInfo.setUpdateTime(DateUtils.getNowDate()); + + // 计算服务时间 + calculateServiceTime(orderInfo); + + // 保存订单 + int result = updateOrderInfo(orderInfo); + if (result > 0) { + return AjaxResult.success("支付完成"); + } else { + return AjaxResult.error("支付完成处理失败"); + } + + } catch (Exception e) { + return AjaxResult.error("支付完成处理异常: " + e.getMessage()); + } + } + + @Override + @Transactional + public AjaxResult refundOrder(RefundRequest request) { + try { + // 参数校验 + if (StringUtils.isEmpty(request.getOrderId()) || request.getRefundAmount() == null || request.getRefundAmount() <= 0) { + return AjaxResult.error("退款信息不完整"); + } + + // 查询订单 + OrderInfo orderInfo = selectOrderByOrderId(request.getOrderId()); + if (orderInfo == null) { + return AjaxResult.error("订单不存在"); + } + + // 检查订单状态 + if (orderInfo.getPayStatus() != PayStatusEnum.PENDING.getStatus() && orderInfo.getPayStatus() != PayStatusEnum.WAIT_REFUND.getStatus()) { + return AjaxResult.error("订单状态不允许退款"); + } + + // 检查退款金额 + if (request.getRefundAmount() > orderInfo.getAmount()) { + return AjaxResult.error("退款金额不能大于订单金额"); + } + + // 检查是否已退款 + if (orderInfo.getRefundAmount() != null && orderInfo.getRefundAmount() > 0) { + return AjaxResult.error("订单已退款"); + } + + // 调用第三方退款接口 + boolean refundResult = paymentUtil.processRefund(orderInfo.getOrderId().toString(), request.getRefundAmount(), orderInfo.getPayType()); + if (!refundResult) { + return AjaxResult.error("第三方退款失败"); + } + + // 更新订单退款信息 + orderInfo.setRefundAmount(request.getRefundAmount()); + orderInfo.setRefundTime(DateUtils.getNowDate()); + orderInfo.setUpdateTime(DateUtils.getNowDate()); + + // 如果是全额退款,更新订单状态 + if (request.getRefundAmount().equals(orderInfo.getAmount())) { + orderInfo.setPayStatus(PayStatusEnum.REFUND.getStatus()); // 4-已退款 + } + + // 保存订单 + int result = updateOrderInfo(orderInfo); + if (result > 0) { + return AjaxResult.success("退款申请成功"); + } else { + return AjaxResult.error("退款申请失败"); + } + + } catch (Exception e) { + return AjaxResult.error("退款异常: " + e.getMessage()); + } + } + + @Override + public List selectUserOrders(Long userId) { + OrderInfo orderInfo = new OrderInfo(); + orderInfo.setUserId(userId); + orderInfo.setIdDel(0L); + return orderInfoMapper.selectOrderInfoList(orderInfo); + } + + @Override + public OrderInfo selectOrderByOrderId(String orderId) { + return orderInfoMapper.selectOrderByOrderId(orderId); + } + + @Override + public List selectOrderInfoVOList(OrderInfo orderInfo) { + return orderInfoMapper.selectOrderInfoVOList(orderInfo); + } + + @Override + @Transactional + public AjaxResult confirmShipment(String orderId) { + try { + // 查询订单 + OrderInfo orderInfo = selectOrderByOrderId(orderId); + if (orderInfo == null) { + return AjaxResult.error("订单不存在"); + } + + // 检查订单状态 + if (orderInfo.getPayStatus() != PayStatusEnum.PENDING.getStatus()) { + return AjaxResult.error("订单状态不正确,只有已支付的订单才能确认出货"); + } + + // 更新订单状态为已完成 + orderInfo.setPayStatus(PayStatusEnum.COMPLETE.getStatus()); // 3-已完成 + orderInfo.setUpdateTime(DateUtils.getNowDate()); + + // 保存订单 + int result = updateOrderInfo(orderInfo); + if (result > 0) { + return AjaxResult.success("确认出货成功"); + } else { + return AjaxResult.error("确认出货失败"); + } + + } catch (Exception e) { + return AjaxResult.error("确认出货异常: " + e.getMessage()); + } + } + + /** + * 处理支付过程 + */ + private Map processPayment(OrderInfo orderInfo, PaymentRequest request) { + // 根据支付方式调用相应的支付接口 + switch (request.getPayType()) { + case "aliPay": + return paymentUtil.processAliPay(orderInfo, request); + case "wechatPay": + return paymentUtil.processWechatPay(orderInfo, request); + case "applePay": + return paymentUtil.processApplePay(orderInfo, request); + default: + Map errorResult = new HashMap<>(); + errorResult.put("error", "不支持的支付方式"); + return errorResult; + } + } + + /** + * 计算服务时间 + */ + private void calculateServiceTime(OrderInfo orderInfo) { + Date now = DateUtils.getNowDate(); + orderInfo.setStartTime(now); + + // 根据套餐类型计算结束时间 + String packageType = orderInfo.getPackageType(); + if ("1".equals(packageType)) { + // 包月 + orderInfo.setEndTime(DateUtils.addMonths(now, 1)); + } else if ("3".equals(packageType)) { + // 包季度 + orderInfo.setEndTime(DateUtils.addMonths(now, 3)); + } else if ("6".equals(packageType)) { + // 半年 + orderInfo.setEndTime(DateUtils.addMonths(now, 6)); + } else if ("12".equals(packageType)) { + // 一年 + orderInfo.setEndTime(DateUtils.addMonths(now, 12)); + } } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/util/PaymentUtil.java b/ruoyi-system/src/main/java/com/ruoyi/system/util/PaymentUtil.java new file mode 100644 index 0000000..f6cc389 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/util/PaymentUtil.java @@ -0,0 +1,195 @@ +package com.ruoyi.system.util; + +import com.ruoyi.common.core.domain.entity.OrderInfo; +import com.ruoyi.common.core.domain.dto.PaymentRequest; +import com.ruoyi.common.utils.StringUtils; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +/** + * 支付工具类 + * + * @author ruoyi + * @date 2025-01-27 + */ +@Component +public class PaymentUtil { + + /** + * 处理支付宝支付 + */ + public Map processAliPay(OrderInfo orderInfo, PaymentRequest request) { + Map result = new HashMap<>(); + + // TODO: 调用支付宝SDK进行支付 + // 这里只是模拟返回支付参数 + + // 构建支付宝支付参数 + Map aliPayParams = new HashMap<>(); + aliPayParams.put("out_trade_no", orderInfo.getOrderId().toString()); + aliPayParams.put("total_amount", orderInfo.getAmount() / 100.0); + aliPayParams.put("subject", StringUtils.isNotEmpty(request.getSubject()) ? request.getSubject() : orderInfo.getOrderName()); + aliPayParams.put("body", StringUtils.isNotEmpty(request.getBody()) ? request.getBody() : "购买VIP会员服务"); + aliPayParams.put("timeout_express", (request.getTimeoutMinutes() != null ? request.getTimeoutMinutes() : 30) + "m"); + aliPayParams.put("product_code", "QUICK_WAP_WAY"); + + result.put("paymentUrl", "https://openapi.alipay.com/gateway.do?"); + result.put("orderId", orderInfo.getOrderId()); + result.put("amount", orderInfo.getAmount()); + result.put("payType", "aliPay"); + result.put("params", aliPayParams); + + return result; + } + + /** + * 处理微信支付 + */ + public Map processWechatPay(OrderInfo orderInfo, PaymentRequest request) { + Map result = new HashMap<>(); + + // TODO: 调用微信支付SDK进行支付 + // 这里只是模拟返回支付参数 + + // 构建微信支付参数 + Map wechatPayParams = new HashMap<>(); + wechatPayParams.put("out_trade_no", orderInfo.getOrderId().toString()); + wechatPayParams.put("total_fee", orderInfo.getAmount()); + wechatPayParams.put("body", StringUtils.isNotEmpty(request.getBody()) ? request.getBody() : orderInfo.getOrderName()); + wechatPayParams.put("attach", StringUtils.isNotEmpty(request.getAttach()) ? request.getAttach() : "VIP会员服务"); + + if (StringUtils.isNotEmpty(request.getOpenid())) { + wechatPayParams.put("openid", request.getOpenid()); + } + + result.put("prepayId", "wx_prepay_id_" + System.currentTimeMillis()); + result.put("orderId", orderInfo.getOrderId()); + result.put("amount", orderInfo.getAmount()); + result.put("payType", "wechatPay"); + result.put("params", wechatPayParams); + + return result; + } + + /** + * 处理Apple Pay支付 + */ + public Map processApplePay(OrderInfo orderInfo, PaymentRequest request) { + Map result = new HashMap<>(); + + // TODO: 调用Apple Pay SDK进行支付 + // 这里只是模拟返回支付参数 + + // 构建Apple Pay支付参数 + Map applePayParams = new HashMap<>(); + applePayParams.put("orderId", orderInfo.getOrderId().toString()); + applePayParams.put("amount", orderInfo.getAmount() / 100.0); + applePayParams.put("currency", "CNY"); + applePayParams.put("merchantIdentifier", StringUtils.isNotEmpty(request.getMerchantIdentifier()) ? + request.getMerchantIdentifier() : "merchant.com.example"); + + if (StringUtils.isNotEmpty(request.getPaymentToken())) { + applePayParams.put("paymentToken", request.getPaymentToken()); + } + + result.put("paymentToken", "apple_payment_token_" + System.currentTimeMillis()); + result.put("orderId", orderInfo.getOrderId()); + result.put("amount", orderInfo.getAmount()); + result.put("payType", "applePay"); + result.put("params", applePayParams); + + return result; + } + + /** + * 验证支付回调 + */ + public boolean verifyPaymentCallback(String orderId, String tradeNo, String payType, String signature) { + // TODO: 根据不同的支付方式验证回调签名 + // 这里只是模拟验证 + + if (StringUtils.isEmpty(orderId) || StringUtils.isEmpty(tradeNo) || StringUtils.isEmpty(payType)) { + return false; + } + + // 验证签名逻辑 + switch (payType) { + case "aliPay": + return verifyAliPayCallback(signature); + case "wechatPay": + return verifyWechatPayCallback(signature); + case "applePay": + return verifyApplePayCallback(signature); + default: + return false; + } + } + + /** + * 验证支付宝回调 + */ + private boolean verifyAliPayCallback(String signature) { + // TODO: 实现支付宝回调验证 + return true; + } + + /** + * 验证微信支付回调 + */ + private boolean verifyWechatPayCallback(String signature) { + // TODO: 实现微信支付回调验证 + return true; + } + + /** + * 验证Apple Pay回调 + */ + private boolean verifyApplePayCallback(String signature) { + // TODO: 实现Apple Pay回调验证 + return true; + } + + /** + * 处理退款 + */ + public boolean processRefund(String orderId, Long refundAmount, String payType) { + // TODO: 根据不同的支付方式调用相应的退款接口 + + switch (payType) { + case "aliPay": + return processAliPayRefund(orderId, refundAmount); + case "wechatPay": + return processWechatPayRefund(orderId, refundAmount); + case "applePay": + return processApplePayRefund(orderId, refundAmount); + default: + return false; + } + } + + /** + * 处理支付宝退款 + */ + private boolean processAliPayRefund(String orderId, Long refundAmount) { + // TODO: 调用支付宝退款接口 + return true; + } + + /** + * 处理微信支付退款 + */ + private boolean processWechatPayRefund(String orderId, Long refundAmount) { + // TODO: 调用微信支付退款接口 + return true; + } + + /** + * 处理Apple Pay退款 + */ + private boolean processApplePayRefund(String orderId, Long refundAmount) { + // TODO: 调用Apple Pay退款接口 + return true; + } +} \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/system/OrderInfoMapper.xml b/ruoyi-system/src/main/resources/mapper/system/OrderInfoMapper.xml index f33f3c0..f56d0b5 100644 --- a/ruoyi-system/src/main/resources/mapper/system/OrderInfoMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/OrderInfoMapper.xml @@ -151,4 +151,70 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-ui/src/api/system/orderInfo.js b/ruoyi-ui/src/api/system/orderInfo.js new file mode 100644 index 0000000..38e14b0 --- /dev/null +++ b/ruoyi-ui/src/api/system/orderInfo.js @@ -0,0 +1,61 @@ +import request from '@/utils/request' + +// 查询订单列表 +export function listOrderInfo(query) { + return request({ + url: '/back/order/detailList', + method: 'get', + params: query + }) +} + +// 查询订单详细 +export function getOrderInfo(id) { + return request({ + url: '/back/order/' + id, + method: 'get' + }) +} + +// 新增订单 +export function addOrderInfo(data) { + return request({ + url: '/back/order', + method: 'post', + data: data + }) +} + +// 修改订单 +export function updateOrderInfo(data) { + return request({ + url: '/back/order', + method: 'put', + data: data + }) +} + +// 删除订单 +export function delOrderInfo(id) { + return request({ + url: '/back/order/' + id, + method: 'delete' + }) +} + +// 确认出货 +export function confirmShipment(orderId) { + return request({ + url: '/back/order/confirmShipment/' + orderId, + method: 'post' + }) +} + +// 导出订单 +export function exportOrderInfo(query) { + return request({ + url: '/back/order/exportDetail', + method: 'post', + data: query + }) +} diff --git a/ruoyi-ui/src/views/member/index.vue b/ruoyi-ui/src/views/member/index.vue index d2ee2c3..0d12488 100644 --- a/ruoyi-ui/src/views/member/index.vue +++ b/ruoyi-ui/src/views/member/index.vue @@ -1,9 +1,9 @@