会员
This commit is contained in:
198
doc/订单支付API文档.md
Normal file
198
doc/订单支付API文档.md
Normal file
@@ -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. 支付成功后会自动计算服务时间
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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<OrderInfoVO> 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<OrderInfoVO> list = orderInfoService.selectOrderInfoVOList(orderInfo);
|
||||
ExcelUtil<OrderInfoVO> util = new ExcelUtil<OrderInfoVO>(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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<OrderInfo> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<OrderInfoVO> selectOrderInfoVOList(OrderInfo orderInfo);
|
||||
}
|
||||
|
||||
@@ -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<OrderInfo> selectUserOrders(Long userId);
|
||||
|
||||
/**
|
||||
* 查询订单详情
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return 订单详情
|
||||
*/
|
||||
OrderInfo selectOrderByOrderId(String orderId);
|
||||
|
||||
/**
|
||||
* 查询订单列表(包含用户信息和套餐信息)
|
||||
*
|
||||
* @param orderInfo 查询条件
|
||||
* @return 订单列表
|
||||
*/
|
||||
List<OrderInfoVO> selectOrderInfoVOList(OrderInfo orderInfo);
|
||||
}
|
||||
|
||||
@@ -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<String, Object> 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<OrderInfo> 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<OrderInfoVO> 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<String, Object> 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<String, Object> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String, Object> processAliPay(OrderInfo orderInfo, PaymentRequest request) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
// TODO: 调用支付宝SDK进行支付
|
||||
// 这里只是模拟返回支付参数
|
||||
|
||||
// 构建支付宝支付参数
|
||||
Map<String, Object> 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<String, Object> processWechatPay(OrderInfo orderInfo, PaymentRequest request) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
// TODO: 调用微信支付SDK进行支付
|
||||
// 这里只是模拟返回支付参数
|
||||
|
||||
// 构建微信支付参数
|
||||
Map<String, Object> 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<String, Object> processApplePay(OrderInfo orderInfo, PaymentRequest request) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
// TODO: 调用Apple Pay SDK进行支付
|
||||
// 这里只是模拟返回支付参数
|
||||
|
||||
// 构建Apple Pay支付参数
|
||||
Map<String, Object> 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;
|
||||
}
|
||||
}
|
||||
@@ -151,4 +151,70 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<select id="selectOrderByOrderId" parameterType="String" resultMap="OrderInfoResult">
|
||||
<include refid="selectOrderInfoVo"/>
|
||||
where order_id = #{orderId} and id_del = 0
|
||||
</select>
|
||||
|
||||
<resultMap type="OrderInfoVO" id="OrderInfoVOResult">
|
||||
<result property="orderId" column="order_id" />
|
||||
<result property="userNickname" column="user_nickname" />
|
||||
<result property="packageName" column="package_name" />
|
||||
<result property="amountYuan" column="amount_yuan" />
|
||||
<result property="payTypeName" column="pay_type_name" />
|
||||
<result property="startTime" column="start_time" />
|
||||
<result property="endTime" column="end_time" />
|
||||
<result property="statusName" column="status_name" />
|
||||
<result property="createTime" column="create_time" />
|
||||
</resultMap>
|
||||
|
||||
<select id="selectOrderInfoVOList" parameterType="OrderInfo" resultMap="OrderInfoVOResult">
|
||||
SELECT
|
||||
o.order_id,
|
||||
su.nickname as user_nickname,
|
||||
CASE
|
||||
WHEN o.package_type = '1' THEN '包月'
|
||||
WHEN o.package_type = '3' THEN '包季度'
|
||||
WHEN o.package_type = '6' THEN '半年'
|
||||
WHEN o.package_type = '12' THEN '一年'
|
||||
ELSE '未知套餐'
|
||||
END as package_name,
|
||||
ROUND(o.amount / 100.0, 2) as amount_yuan,
|
||||
CASE
|
||||
WHEN o.pay_type = 'aliPay' THEN '支付宝'
|
||||
WHEN o.pay_type = 'wechatPay' THEN '微信支付'
|
||||
WHEN o.pay_type = 'applePay' THEN 'Apple Pay'
|
||||
ELSE '未知支付方式'
|
||||
END as pay_type_name,
|
||||
o.start_time,
|
||||
o.end_time,
|
||||
CASE
|
||||
WHEN o.pay_status = 1 THEN '待支付'
|
||||
WHEN o.pay_status = 2 THEN '待出货'
|
||||
WHEN o.pay_status = 3 THEN '待退款'
|
||||
WHEN o.pay_status = 4 THEN '已退款'
|
||||
WHEN o.pay_status = 5 THEN '已完成'
|
||||
ELSE '未知状态'
|
||||
END as status_name,
|
||||
o.create_time
|
||||
FROM order_info o
|
||||
LEFT JOIN shop_user su ON o.user_id = su.user_id
|
||||
<where>
|
||||
o.id_del = 0
|
||||
<if test="orderId != null "> and o.order_id = #{orderId}</if>
|
||||
<if test="orderName != null and orderName != ''"> and o.order_name like concat('%', #{orderName}, '%')</if>
|
||||
<if test="userId != null "> and o.user_id = #{userId}</if>
|
||||
<if test="amount != null "> and o.amount = #{amount}</if>
|
||||
<if test="payType != null and payType != ''"> and o.pay_type = #{payType}</if>
|
||||
<if test="payTime != null "> and o.pay_time = #{payTime}</if>
|
||||
<if test="payStatus != null "> and o.pay_status = #{payStatus}</if>
|
||||
<if test="startTime != null "> and o.start_time = #{startTime}</if>
|
||||
<if test="endTime != null "> and o.end_time = #{endTime}</if>
|
||||
<if test="packageType != null and packageType != ''"> and o.package_type = #{packageType}</if>
|
||||
<if test="clientIp != null and clientIp != ''"> and o.client_ip = #{clientIp}</if>
|
||||
<if test="deviceType != null and deviceType != ''"> and o.device_type = #{deviceType}</if>
|
||||
</where>
|
||||
ORDER BY o.create_time DESC
|
||||
</select>
|
||||
</mapper>
|
||||
61
ruoyi-ui/src/api/system/orderInfo.js
Normal file
61
ruoyi-ui/src/api/system/orderInfo.js
Normal file
@@ -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
|
||||
})
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
||||
<el-form-item label="订单号" prop="orderNumber">
|
||||
<el-form-item label="订单号" prop="orderId">
|
||||
<el-input
|
||||
v-model="queryParams.orderNumber"
|
||||
v-model="queryParams.orderId"
|
||||
placeholder="请输入订单号查找"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
@@ -20,8 +20,8 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="选择状态" clearable style="width: 150px">
|
||||
<el-form-item label="选择状态" prop="payStatus">
|
||||
<el-select v-model="queryParams.payStatus" placeholder="选择状态" clearable style="width: 150px">
|
||||
<el-option
|
||||
v-for="item in statusOptions"
|
||||
:key="item.value"
|
||||
@@ -36,55 +36,42 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="memberList">
|
||||
<el-table-column label="订单号" align="center" prop="orderNumber" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="套餐名称" align="center" prop="packageName" :show-overflow-tooltip="true" />
|
||||
<el-table v-loading="loading" :data="orderList">
|
||||
<el-table-column label="订单号" align="center" prop="orderId" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="用户昵称" align="center" prop="userNickname" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="金额" align="center" prop="amount" width="100">
|
||||
<el-table-column label="套餐名称" align="center" prop="packageName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="金额" align="center" prop="amountYuan" width="100">
|
||||
<template slot-scope="scope">
|
||||
<span>¥{{ scope.row.amount }}</span>
|
||||
<span>¥{{ scope.row.amountYuan }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="支付方式" align="center" prop="paymentMethod" width="120" />
|
||||
<el-table-column label="开通时间" align="center" prop="activationTime" width="160">
|
||||
<el-table-column label="支付方式" align="center" prop="payTypeName" width="120" />
|
||||
<el-table-column label="开通时间" align="center" prop="startTime" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.activationTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="到期时间" align="center" prop="expirationTime" width="160">
|
||||
<el-table-column label="到期时间" align="center" prop="endTime" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.expirationTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center" prop="status" width="100">
|
||||
<el-table-column label="状态" align="center" prop="statusName" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'" size="mini">
|
||||
{{ scope.row.status === 1 ? '正常' : '已过期' }}
|
||||
<el-tag :type="getStatusType(scope.row.statusName)" size="mini">
|
||||
{{ scope.row.statusName }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['member:member:edit']"
|
||||
>编辑</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['member:member:remove']"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
@@ -95,110 +82,41 @@
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改会员记录对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
||||
<el-form-item label="订单号" prop="orderNumber" required>
|
||||
<el-input v-model="form.orderNumber" placeholder="请输入订单号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="套餐名称" prop="packageName" required>
|
||||
<el-select v-model="form.packageName" placeholder="请选择套餐" style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in packageOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户昵称" prop="userNickname" required>
|
||||
<el-input v-model="form.userNickname" placeholder="请输入用户昵称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="金额" prop="amount" required>
|
||||
<el-input-number v-model="form.amount" :precision="2" :step="0.01" :min="0" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="支付方式" prop="paymentMethod" required>
|
||||
<el-select v-model="form.paymentMethod" placeholder="请选择支付方式" style="width: 100%">
|
||||
<el-option label="微信支付" value="微信支付" />
|
||||
<el-option label="支付宝支付" value="支付宝支付" />
|
||||
<el-option label="app store" value="app store" />
|
||||
<el-option label="其他" value="其他" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开通时间" prop="activationTime" required>
|
||||
<el-date-picker
|
||||
v-model="form.activationTime"
|
||||
type="datetime"
|
||||
placeholder="选择开通时间"
|
||||
style="width: 100%"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="到期时间" prop="expirationTime" required>
|
||||
<el-date-picker
|
||||
v-model="form.expirationTime"
|
||||
type="datetime"
|
||||
placeholder="选择到期时间"
|
||||
style="width: 100%"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status" required>
|
||||
<el-select v-model="form.status" placeholder="请选择状态" style="width: 100%">
|
||||
<el-option label="正常" :value="1" />
|
||||
<el-option label="已过期" :value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listMember, getMember, delMember, addMember, updateMember } from "@/api/member/member";
|
||||
import { listOrderInfo } from "@/api/system/orderInfo";
|
||||
|
||||
export default {
|
||||
name: "Member",
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
showSearch: true,
|
||||
total: 0,
|
||||
memberList: [],
|
||||
title: "",
|
||||
open: false,
|
||||
loading: true,
|
||||
showSearch: true,
|
||||
total: 0,
|
||||
orderList: [],
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
orderNumber: null,
|
||||
orderId: null,
|
||||
packageType: null,
|
||||
status: null
|
||||
},
|
||||
form: {},
|
||||
rules: {
|
||||
orderNumber: [{ required: true, message: "订单号不能为空", trigger: "blur" }],
|
||||
packageName: [{ required: true, message: "套餐名称不能为空", trigger: "change" }],
|
||||
userNickname: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
|
||||
amount: [{ required: true, message: "金额不能为空", trigger: "blur" }],
|
||||
paymentMethod: [{ required: true, message: "支付方式不能为空", trigger: "change" }],
|
||||
activationTime: [{ required: true, message: "开通时间不能为空", trigger: "change" }],
|
||||
expirationTime: [{ required: true, message: "到期时间不能为空", trigger: "change" }],
|
||||
status: [{ required: true, message: "状态不能为空", trigger: "change" }]
|
||||
payStatus: null
|
||||
},
|
||||
|
||||
packageOptions: [
|
||||
{ label: '连续包月', value: '连续包月' },
|
||||
{ label: '年卡会员', value: '年卡会员' },
|
||||
{ label: '季卡会员', value: '季卡会员' },
|
||||
{ label: '月卡会员', value: '月卡会员' },
|
||||
{ label: '周卡会员', value: '周卡会员' }
|
||||
{ label: '包月', value: '1' },
|
||||
{ label: '包季度', value: '3' },
|
||||
{ label: '半年', value: '6' },
|
||||
{ label: '一年', value: '12' }
|
||||
],
|
||||
statusOptions: [
|
||||
{ label: '已过期', value: 0 },
|
||||
{ label: '正常', value: 1 }
|
||||
{ label: '待支付', value: 1 },
|
||||
{ label: '待出货', value: 2 },
|
||||
{ label: '待退款', value: 3 },
|
||||
{ label: '已退款', value: 4 },
|
||||
{ label: '已完成', value: 5 }
|
||||
]
|
||||
};
|
||||
},
|
||||
@@ -206,81 +124,41 @@ export default {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询订单列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listMember(this.queryParams).then(response => {
|
||||
this.memberList = response.rows;
|
||||
listOrderInfo(this.queryParams).then(response => {
|
||||
this.orderList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
reset() {
|
||||
this.form = {
|
||||
id: null,
|
||||
orderNumber: null,
|
||||
packageName: null,
|
||||
userNickname: null,
|
||||
amount: null,
|
||||
paymentMethod: null,
|
||||
activationTime: null,
|
||||
expirationTime: null,
|
||||
status: 1
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = "新增会员记录";
|
||||
},
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const id = row.id || this.ids
|
||||
getMember(id).then(response => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = "编辑会员记录";
|
||||
});
|
||||
},
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.id != null) {
|
||||
updateMember(this.form).then(response => {
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
addMember(this.form).then(response => {
|
||||
this.$modal.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
handleDelete(row) {
|
||||
const ids = row.id || this.ids;
|
||||
this.$modal.confirm('是否确认删除会员记录编号为"' + ids + '"的数据项?').then(function() {
|
||||
return delMember(ids);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
/** 获取状态标签类型 */
|
||||
getStatusType(statusName) {
|
||||
switch (statusName) {
|
||||
case '待支付':
|
||||
return 'warning';
|
||||
case '待出货':
|
||||
return 'primary';
|
||||
case '待退款':
|
||||
return 'info';
|
||||
case '已退款':
|
||||
return 'danger';
|
||||
case '已完成':
|
||||
return 'success';
|
||||
default:
|
||||
return 'info';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,8 +10,8 @@ const CompressionPlugin = require('compression-webpack-plugin')
|
||||
const name = process.env.VUE_APP_TITLE || '若依管理系统' // 网页标题
|
||||
|
||||
// const baseUrl = 'http://localhost:8080' // 后端接口
|
||||
const baseUrl = 'http://60.205.107.210:8080' // 后端接口
|
||||
// const baseUrl = 'http://192.168.31.239:8081' // 后端接口
|
||||
// const baseUrl = 'http://60.205.107.210:8080' // 后端接口
|
||||
const baseUrl = 'http://192.168.31.239:8080' // 后端接口
|
||||
|
||||
const port = process.env.port || process.env.npm_config_port || 80 // 端口
|
||||
|
||||
|
||||
Reference in New Issue
Block a user