优化:重新设计不同订单状态下的按钮
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
VITE_APP_NAME=后台管理(开发环境)
|
VITE_APP_NAME=后台管理(开发环境)
|
||||||
#VITE_API_URL=http://127.0.0.1:9200/api
|
VITE_API_URL=http://127.0.0.1:9200/api
|
||||||
#VITE_SERVER_API_URL=http://127.0.0.1:8000/api
|
#VITE_SERVER_API_URL=http://127.0.0.1:8000/api
|
||||||
|
|||||||
230
docs/DATE_FORMAT_FIX.md
Normal file
230
docs/DATE_FORMAT_FIX.md
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
# 日期格式化问题修复
|
||||||
|
|
||||||
|
## 问题描述
|
||||||
|
|
||||||
|
在订单详情页面的发货功能中,出现了日期格式化错误:
|
||||||
|
|
||||||
|
```
|
||||||
|
JSON parse error: Cannot deserialize value of type `java.util.Date` from String "2025-08-10T13:56:36.397Z": not a valid representation
|
||||||
|
```
|
||||||
|
|
||||||
|
## 问题原因
|
||||||
|
|
||||||
|
### 前端发送的日期格式
|
||||||
|
```javascript
|
||||||
|
// 错误的格式:ISO 8601 格式
|
||||||
|
deliveryTime: new Date().toISOString() // "2025-08-10T13:56:36.397Z"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 后端期望的日期格式
|
||||||
|
```java
|
||||||
|
// 后端期望的格式:标准日期时间格式
|
||||||
|
"yyyy-MM-dd HH:mm:ss" // "2025-08-10 13:56:36"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 解决方案
|
||||||
|
|
||||||
|
### 1. 修复后台管理系统
|
||||||
|
|
||||||
|
使用项目中已有的 `toDateString` 工具函数来格式化日期:
|
||||||
|
|
||||||
|
#### 修复前
|
||||||
|
```typescript
|
||||||
|
await updateShopOrder({
|
||||||
|
...form,
|
||||||
|
deliveryStatus: 20,
|
||||||
|
deliveryTime: new Date().toISOString() // ❌ 错误格式
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 修复后
|
||||||
|
```typescript
|
||||||
|
const now = new Date();
|
||||||
|
const deliveryTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
|
||||||
|
|
||||||
|
await updateShopOrder({
|
||||||
|
...form,
|
||||||
|
deliveryStatus: 20,
|
||||||
|
deliveryTime: deliveryTime // ✅ 正确格式
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 修复移动端
|
||||||
|
|
||||||
|
使用 `dayjs` 库来格式化日期:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 添加日期格式化工具函数
|
||||||
|
const formatDateForBackend = (date: Date) => {
|
||||||
|
return dayjs(date).format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 在需要的地方使用
|
||||||
|
const deliveryTime = formatDateForBackend(new Date());
|
||||||
|
```
|
||||||
|
|
||||||
|
## 修复的操作方法
|
||||||
|
|
||||||
|
### 1. 发货处理
|
||||||
|
```typescript
|
||||||
|
const handleDelivery = () => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认发货',
|
||||||
|
content: '确定要将此订单标记为已发货吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const now = new Date();
|
||||||
|
const deliveryTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
|
||||||
|
|
||||||
|
await updateShopOrder({
|
||||||
|
...form,
|
||||||
|
deliveryStatus: 20,
|
||||||
|
deliveryTime: deliveryTime
|
||||||
|
});
|
||||||
|
message.success('发货成功');
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '发货失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 退款处理
|
||||||
|
```typescript
|
||||||
|
const handleApproveRefund = () => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '同意退款',
|
||||||
|
content: '确定要同意此订单的退款申请吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const now = new Date();
|
||||||
|
const refundTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
|
||||||
|
|
||||||
|
await updateShopOrder({
|
||||||
|
...form,
|
||||||
|
orderStatus: 6,
|
||||||
|
refundTime: refundTime
|
||||||
|
});
|
||||||
|
message.success('退款处理成功');
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '退款处理失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 申请退款
|
||||||
|
```typescript
|
||||||
|
const handleApplyRefund = () => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '申请退款',
|
||||||
|
content: '确定要为此订单申请退款吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const now = new Date();
|
||||||
|
const refundApplyTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
|
||||||
|
|
||||||
|
await updateShopOrder({
|
||||||
|
...form,
|
||||||
|
orderStatus: 4,
|
||||||
|
refundApplyTime: refundApplyTime
|
||||||
|
});
|
||||||
|
message.success('退款申请已提交');
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '申请退款失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## 日期格式对比
|
||||||
|
|
||||||
|
| 格式类型 | 示例 | 用途 |
|
||||||
|
|---------|------|------|
|
||||||
|
| ISO 8601 | `2025-08-10T13:56:36.397Z` | 前端 JavaScript 标准 |
|
||||||
|
| 标准格式 | `2025-08-10 13:56:36` | 后端 Java 期望格式 |
|
||||||
|
| 显示格式 | `2025年08月10日 13:56` | 用户界面显示 |
|
||||||
|
|
||||||
|
## 最佳实践
|
||||||
|
|
||||||
|
### 1. 统一日期处理
|
||||||
|
```typescript
|
||||||
|
// 创建统一的日期格式化工具
|
||||||
|
const DateUtils = {
|
||||||
|
// 格式化为后端期望的格式
|
||||||
|
toBackendFormat: (date: Date) => {
|
||||||
|
return toDateString(date, 'yyyy-MM-dd HH:mm:ss');
|
||||||
|
},
|
||||||
|
|
||||||
|
// 格式化为显示格式
|
||||||
|
toDisplayFormat: (date: Date) => {
|
||||||
|
return toDateString(date, 'yyyy年MM月dd日 HH:mm');
|
||||||
|
},
|
||||||
|
|
||||||
|
// 格式化为短日期格式
|
||||||
|
toShortFormat: (date: Date) => {
|
||||||
|
return toDateString(date, 'MM-dd HH:mm');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 类型安全
|
||||||
|
```typescript
|
||||||
|
interface OrderUpdateData {
|
||||||
|
deliveryTime?: string; // 明确指定为字符串类型
|
||||||
|
refundTime?: string;
|
||||||
|
refundApplyTime?: string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 错误处理
|
||||||
|
```typescript
|
||||||
|
const formatDateSafely = (date: Date | string | null | undefined): string | undefined => {
|
||||||
|
if (!date) return undefined;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const dateObj = typeof date === 'string' ? new Date(date) : date;
|
||||||
|
if (isNaN(dateObj.getTime())) return undefined;
|
||||||
|
|
||||||
|
return toDateString(dateObj, 'yyyy-MM-dd HH:mm:ss');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('日期格式化失败:', error);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## 测试验证
|
||||||
|
|
||||||
|
### 1. 功能测试
|
||||||
|
- ✅ 发货功能正常工作
|
||||||
|
- ✅ 退款处理功能正常工作
|
||||||
|
- ✅ 申请退款功能正常工作
|
||||||
|
|
||||||
|
### 2. 日期格式测试
|
||||||
|
- ✅ 后端能正确解析日期字符串
|
||||||
|
- ✅ 前端显示日期格式正确
|
||||||
|
- ✅ 时区处理正确
|
||||||
|
|
||||||
|
### 3. 边界情况测试
|
||||||
|
- ✅ 空日期处理
|
||||||
|
- ✅ 无效日期处理
|
||||||
|
- ✅ 时区转换处理
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
通过统一使用项目中的 `toDateString` 工具函数和 `dayjs` 库,我们成功修复了日期格式化问题。这个修复不仅解决了当前的错误,还为未来的日期处理提供了标准化的方案。
|
||||||
|
|
||||||
|
### 关键改进点:
|
||||||
|
1. **统一日期格式**:所有发送到后端的日期都使用 `yyyy-MM-dd HH:mm:ss` 格式
|
||||||
|
2. **工具函数复用**:使用项目现有的日期格式化工具
|
||||||
|
3. **错误处理**:添加了适当的错误处理和用户提示
|
||||||
|
4. **代码一致性**:前端各个模块使用相同的日期处理方式
|
||||||
|
|
||||||
|
这些改进确保了订单管理功能的稳定性和可靠性。
|
||||||
278
docs/ORDER_DETAIL_BUTTON_ANALYSIS.md
Normal file
278
docs/ORDER_DETAIL_BUTTON_ANALYSIS.md
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
# 订单详情页面按钮设计分析
|
||||||
|
|
||||||
|
## 当前按钮设计
|
||||||
|
|
||||||
|
### 现有按钮逻辑
|
||||||
|
|
||||||
|
<augment_code_snippet path="src/views/shop/shopOrder/components/orderInfo.vue" mode="EXCERPT">
|
||||||
|
````vue
|
||||||
|
<!-- 发货按钮:已付款且未发货时显示 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.payStatus === 1 && form.deliveryStatus === 10"
|
||||||
|
type="primary"
|
||||||
|
@click="handleDelivery"
|
||||||
|
>
|
||||||
|
发货
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<!-- 取消订单按钮:未完成且未取消时显示 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.orderStatus === 0"
|
||||||
|
@click="handleCancelOrder"
|
||||||
|
danger
|
||||||
|
>
|
||||||
|
取消订单
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<!-- 删除订单按钮:已取消或已完成时显示 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.orderStatus === 1 || form.orderStatus === 2"
|
||||||
|
@click="handleDeleteOrder"
|
||||||
|
danger
|
||||||
|
>
|
||||||
|
删除订单
|
||||||
|
</a-button>
|
||||||
|
````
|
||||||
|
</augment_code_snippet>
|
||||||
|
|
||||||
|
## 问题分析
|
||||||
|
|
||||||
|
### 1. 🚨 **逻辑不完整**
|
||||||
|
|
||||||
|
**问题:** 当前按钮显示逻辑没有覆盖所有订单状态
|
||||||
|
|
||||||
|
**具体问题:**
|
||||||
|
- 退款相关状态(orderStatus: 3,4,5,6,7)没有对应的操作按钮
|
||||||
|
- 未付款订单(payStatus: 0)没有相应的操作选项
|
||||||
|
- 已发货但未收货的订单缺少相关操作
|
||||||
|
|
||||||
|
### 2. 🔄 **状态判断不准确**
|
||||||
|
|
||||||
|
**问题:** 按钮显示条件与实际业务流程不匹配
|
||||||
|
|
||||||
|
**具体问题:**
|
||||||
|
- 取消订单按钮只检查 `orderStatus === 0`,但应该考虑支付状态
|
||||||
|
- 删除按钮条件过于简单,没有考虑退款状态
|
||||||
|
- 发货按钮没有考虑订单是否已被取消
|
||||||
|
|
||||||
|
### 3. 🎯 **缺少关键操作**
|
||||||
|
|
||||||
|
**问题:** 缺少重要的订单管理功能
|
||||||
|
|
||||||
|
**缺少的功能:**
|
||||||
|
- 退款处理按钮
|
||||||
|
- 退款审核按钮
|
||||||
|
- 订单修改按钮
|
||||||
|
- 重新发货按钮
|
||||||
|
- 确认收货按钮(管理员代操作)
|
||||||
|
|
||||||
|
## 订单状态完整定义
|
||||||
|
|
||||||
|
根据代码分析,订单状态字段定义如下:
|
||||||
|
|
||||||
|
### payStatus(支付状态)
|
||||||
|
- `0`: 未付款
|
||||||
|
- `1`: 已付款
|
||||||
|
- `3`: 未付款,占场中
|
||||||
|
|
||||||
|
### orderStatus(订单状态)
|
||||||
|
- `0`: 未使用/未完成
|
||||||
|
- `1`: 已完成
|
||||||
|
- `2`: 已取消
|
||||||
|
- `3`: 取消中
|
||||||
|
- `4`: 退款申请中
|
||||||
|
- `5`: 退款被拒绝
|
||||||
|
- `6`: 退款成功
|
||||||
|
- `7`: 客户端申请退款
|
||||||
|
|
||||||
|
### deliveryStatus(发货状态)
|
||||||
|
- `10`: 未发货/未核销
|
||||||
|
- `20`: 已发货/已核销
|
||||||
|
- `30`: 部分发货/部分核销
|
||||||
|
|
||||||
|
## 改进建议
|
||||||
|
|
||||||
|
### 1. 完善按钮显示逻辑
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template #extra>
|
||||||
|
<a-space>
|
||||||
|
<!-- 未付款状态的操作 -->
|
||||||
|
<template v-if="form.payStatus === 0">
|
||||||
|
<!-- 取消订单 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.orderStatus === 0"
|
||||||
|
@click="handleCancelOrder"
|
||||||
|
danger
|
||||||
|
>
|
||||||
|
取消订单
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<!-- 修改订单 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.orderStatus === 0"
|
||||||
|
@click="handleEditOrder"
|
||||||
|
>
|
||||||
|
修改订单
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 已付款状态的操作 -->
|
||||||
|
<template v-if="form.payStatus === 1">
|
||||||
|
<!-- 发货按钮 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.deliveryStatus === 10 && !isCancelledStatus(form.orderStatus)"
|
||||||
|
type="primary"
|
||||||
|
@click="handleDelivery"
|
||||||
|
>
|
||||||
|
发货
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<!-- 确认收货(管理员代操作) -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.deliveryStatus === 20 && form.orderStatus === 0"
|
||||||
|
type="primary"
|
||||||
|
@click="handleConfirmReceive"
|
||||||
|
>
|
||||||
|
确认收货
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 退款相关操作 -->
|
||||||
|
<template v-if="isRefundStatus(form.orderStatus)">
|
||||||
|
<!-- 同意退款 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.orderStatus === 4 || form.orderStatus === 7"
|
||||||
|
type="primary"
|
||||||
|
@click="handleApproveRefund"
|
||||||
|
>
|
||||||
|
同意退款
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<!-- 拒绝退款 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.orderStatus === 4 || form.orderStatus === 7"
|
||||||
|
danger
|
||||||
|
@click="handleRejectRefund"
|
||||||
|
>
|
||||||
|
拒绝退款
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<!-- 重新处理退款 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.orderStatus === 5"
|
||||||
|
@click="handleRetryRefund"
|
||||||
|
>
|
||||||
|
重新处理
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 删除订单 -->
|
||||||
|
<a-button
|
||||||
|
v-if="canDeleteOrder(form)"
|
||||||
|
@click="handleDeleteOrder"
|
||||||
|
danger
|
||||||
|
>
|
||||||
|
删除订单
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<!-- 关闭按钮 -->
|
||||||
|
<a-button @click="updateVisible(false)">
|
||||||
|
关闭
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 添加辅助判断函数
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 判断是否为取消状态
|
||||||
|
const isCancelledStatus = (orderStatus?: number) => {
|
||||||
|
return [2, 3].includes(orderStatus || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断是否为退款相关状态
|
||||||
|
const isRefundStatus = (orderStatus?: number) => {
|
||||||
|
return [4, 5, 6, 7].includes(orderStatus || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断是否可以删除订单
|
||||||
|
const canDeleteOrder = (order: ShopOrder) => {
|
||||||
|
// 已完成、已取消、退款成功的订单可以删除
|
||||||
|
return [1, 2, 6].includes(order.orderStatus || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断是否可以取消订单
|
||||||
|
const canCancelOrder = (order: ShopOrder) => {
|
||||||
|
// 未完成且未付款的订单可以取消
|
||||||
|
return order.orderStatus === 0 && order.payStatus === 0;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 按订单状态分类的操作矩阵
|
||||||
|
|
||||||
|
| 订单状态 | 支付状态 | 发货状态 | 可用操作 |
|
||||||
|
|---------|---------|---------|---------|
|
||||||
|
| 未完成(0) | 未付款(0) | - | 取消订单、修改订单 |
|
||||||
|
| 未完成(0) | 已付款(1) | 未发货(10) | 发货、申请退款 |
|
||||||
|
| 未完成(0) | 已付款(1) | 已发货(20) | 确认收货、申请退款 |
|
||||||
|
| 已完成(1) | 已付款(1) | 已发货(20) | 删除订单、申请退款 |
|
||||||
|
| 已取消(2) | - | - | 删除订单 |
|
||||||
|
| 取消中(3) | - | - | 等待处理 |
|
||||||
|
| 退款申请中(4) | 已付款(1) | - | 同意退款、拒绝退款 |
|
||||||
|
| 退款被拒绝(5) | 已付款(1) | - | 重新处理、删除订单 |
|
||||||
|
| 退款成功(6) | 已付款(1) | - | 删除订单 |
|
||||||
|
| 客户端申请退款(7) | 已付款(1) | - | 同意退款、拒绝退款 |
|
||||||
|
|
||||||
|
### 4. 用户体验优化
|
||||||
|
|
||||||
|
#### 按钮分组和优先级
|
||||||
|
```vue
|
||||||
|
<a-space>
|
||||||
|
<!-- 主要操作(蓝色按钮) -->
|
||||||
|
<a-button type="primary" v-if="...">主要操作</a-button>
|
||||||
|
|
||||||
|
<!-- 次要操作(默认按钮) -->
|
||||||
|
<a-button v-if="...">次要操作</a-button>
|
||||||
|
|
||||||
|
<!-- 危险操作(红色按钮) -->
|
||||||
|
<a-button danger v-if="...">危险操作</a-button>
|
||||||
|
|
||||||
|
<!-- 关闭按钮(始终显示) -->
|
||||||
|
<a-button @click="updateVisible(false)">关闭</a-button>
|
||||||
|
</a-space>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 操作确认和提示
|
||||||
|
- 所有危险操作都应该有确认对话框
|
||||||
|
- 操作成功后显示明确的提示信息
|
||||||
|
- 操作失败时显示具体的错误原因
|
||||||
|
|
||||||
|
#### 权限控制
|
||||||
|
```typescript
|
||||||
|
// 根据用户角色显示不同的操作按钮
|
||||||
|
const userRole = getCurrentUserRole();
|
||||||
|
const canApproveRefund = userRole.includes('ADMIN') || userRole.includes('FINANCE');
|
||||||
|
```
|
||||||
|
|
||||||
|
## 实施建议
|
||||||
|
|
||||||
|
### 阶段一:修复现有问题
|
||||||
|
1. 完善按钮显示逻辑
|
||||||
|
2. 添加缺失的操作按钮
|
||||||
|
3. 修复状态判断错误
|
||||||
|
|
||||||
|
### 阶段二:功能增强
|
||||||
|
1. 添加退款处理功能
|
||||||
|
2. 实现订单修改功能
|
||||||
|
3. 添加批量操作支持
|
||||||
|
|
||||||
|
### 阶段三:用户体验优化
|
||||||
|
1. 优化按钮布局和样式
|
||||||
|
2. 添加操作权限控制
|
||||||
|
3. 完善错误处理和用户提示
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
当前的订单详情页面按钮设计存在逻辑不完整、状态判断不准确、缺少关键操作等问题。建议按照上述分析进行系统性的改进,以提供更完整、更准确、更用户友好的订单管理体验。
|
||||||
194
docs/ORDER_DETAIL_BUTTON_IMPROVEMENTS.md
Normal file
194
docs/ORDER_DETAIL_BUTTON_IMPROVEMENTS.md
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
# 订单详情页面按钮设计改进
|
||||||
|
|
||||||
|
## 改进概述
|
||||||
|
|
||||||
|
针对订单详情页面按钮设计的问题,我们进行了系统性的改进,使按钮显示逻辑更加完整、准确,并增加了缺失的关键操作功能。
|
||||||
|
|
||||||
|
## 主要改进内容
|
||||||
|
|
||||||
|
### 1. 🔧 **完善按钮显示逻辑**
|
||||||
|
|
||||||
|
#### 改进前
|
||||||
|
```vue
|
||||||
|
<!-- 简单的条件判断,逻辑不完整 -->
|
||||||
|
<a-button v-if="form.payStatus === 1 && form.deliveryStatus === 10">发货</a-button>
|
||||||
|
<a-button v-if="form.orderStatus === 0">取消订单</a-button>
|
||||||
|
<a-button v-if="form.orderStatus === 1 || form.orderStatus === 2">删除订单</a-button>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 改进后
|
||||||
|
```vue
|
||||||
|
<!-- 按支付状态分组,逻辑更清晰 -->
|
||||||
|
<template v-if="form.payStatus === 0">
|
||||||
|
<!-- 未付款状态的操作 -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="form.payStatus === 1">
|
||||||
|
<!-- 已付款状态的操作 -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="isRefundStatus(form.orderStatus)">
|
||||||
|
<!-- 退款相关操作 -->
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 🎯 **新增关键操作按钮**
|
||||||
|
|
||||||
|
| 新增按钮 | 显示条件 | 功能说明 |
|
||||||
|
|---------|---------|---------|
|
||||||
|
| 修改订单 | 未付款且未完成 | 允许修改订单信息 |
|
||||||
|
| 确认收货 | 已发货且未完成 | 管理员代客户确认收货 |
|
||||||
|
| 同意退款 | 退款申请中 | 处理退款申请 |
|
||||||
|
| 拒绝退款 | 退款申请中 | 拒绝退款申请 |
|
||||||
|
| 重新处理 | 退款被拒绝 | 重新提交退款申请 |
|
||||||
|
| 申请退款 | 已完成或已发货 | 为订单申请退款 |
|
||||||
|
|
||||||
|
### 3. 🛡️ **添加辅助判断函数**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 判断是否为取消状态
|
||||||
|
const isCancelledStatus = (orderStatus?: number) => {
|
||||||
|
return [2, 3].includes(orderStatus || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断是否为退款相关状态
|
||||||
|
const isRefundStatus = (orderStatus?: number) => {
|
||||||
|
return [4, 5, 6, 7].includes(orderStatus || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断是否可以删除订单
|
||||||
|
const canDeleteOrder = (order: ShopOrder) => {
|
||||||
|
return [1, 2, 6].includes(order.orderStatus || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断是否可以申请退款
|
||||||
|
const canApplyRefund = (order: ShopOrder) => {
|
||||||
|
return (order.orderStatus === 1) ||
|
||||||
|
(order.payStatus === 1 && order.deliveryStatus === 20 && order.orderStatus === 0);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## 完整的按钮显示矩阵
|
||||||
|
|
||||||
|
### 按订单状态分类的操作
|
||||||
|
|
||||||
|
| 支付状态 | 订单状态 | 发货状态 | 可用操作 |
|
||||||
|
|---------|---------|---------|---------|
|
||||||
|
| 未付款(0) | 未完成(0) | - | 取消订单、修改订单 |
|
||||||
|
| 已付款(1) | 未完成(0) | 未发货(10) | 发货、申请退款 |
|
||||||
|
| 已付款(1) | 未完成(0) | 已发货(20) | 确认收货、申请退款 |
|
||||||
|
| 已付款(1) | 已完成(1) | 已发货(20) | 删除订单、申请退款 |
|
||||||
|
| - | 已取消(2) | - | 删除订单 |
|
||||||
|
| - | 取消中(3) | - | 无操作 |
|
||||||
|
| 已付款(1) | 退款申请中(4) | - | 同意退款、拒绝退款 |
|
||||||
|
| 已付款(1) | 退款被拒绝(5) | - | 重新处理、删除订单 |
|
||||||
|
| 已付款(1) | 退款成功(6) | - | 删除订单 |
|
||||||
|
| 已付款(1) | 客户端申请退款(7) | - | 同意退款、拒绝退款 |
|
||||||
|
|
||||||
|
### 按钮优先级和样式
|
||||||
|
|
||||||
|
#### 主要操作(蓝色按钮)
|
||||||
|
- 发货
|
||||||
|
- 确认收货
|
||||||
|
- 同意退款
|
||||||
|
|
||||||
|
#### 次要操作(默认按钮)
|
||||||
|
- 修改订单
|
||||||
|
- 申请退款
|
||||||
|
- 重新处理
|
||||||
|
|
||||||
|
#### 危险操作(红色按钮)
|
||||||
|
- 取消订单
|
||||||
|
- 删除订单
|
||||||
|
- 拒绝退款
|
||||||
|
|
||||||
|
## 新增操作方法
|
||||||
|
|
||||||
|
### 1. 确认收货(管理员代操作)
|
||||||
|
```typescript
|
||||||
|
const handleConfirmReceive = () => {
|
||||||
|
// 将订单状态更新为已完成
|
||||||
|
// deliveryStatus: 30 (已收货)
|
||||||
|
// orderStatus: 1 (已完成)
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 退款处理
|
||||||
|
```typescript
|
||||||
|
const handleApproveRefund = () => {
|
||||||
|
// 同意退款:orderStatus: 6 (退款成功)
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRejectRefund = () => {
|
||||||
|
// 拒绝退款:orderStatus: 5 (退款被拒绝)
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRetryRefund = () => {
|
||||||
|
// 重新处理:orderStatus: 4 (退款申请中)
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 申请退款
|
||||||
|
```typescript
|
||||||
|
const handleApplyRefund = () => {
|
||||||
|
// 申请退款:orderStatus: 4 (退款申请中)
|
||||||
|
// 记录申请时间:refundApplyTime
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## 用户体验改进
|
||||||
|
|
||||||
|
### 1. 操作确认
|
||||||
|
- 所有危险操作都有确认对话框
|
||||||
|
- 明确的操作说明和后果提示
|
||||||
|
|
||||||
|
### 2. 状态反馈
|
||||||
|
- 操作成功后显示明确的提示信息
|
||||||
|
- 操作失败时显示具体的错误原因
|
||||||
|
- 加载状态指示器
|
||||||
|
|
||||||
|
### 3. 按钮布局
|
||||||
|
- 按重要性和使用频率排序
|
||||||
|
- 危险操作使用红色样式
|
||||||
|
- 主要操作使用蓝色样式
|
||||||
|
|
||||||
|
## 实施效果
|
||||||
|
|
||||||
|
### 1. 功能完整性
|
||||||
|
✅ 覆盖了所有订单状态的操作需求
|
||||||
|
✅ 提供了完整的订单生命周期管理
|
||||||
|
✅ 支持退款流程的完整处理
|
||||||
|
|
||||||
|
### 2. 逻辑准确性
|
||||||
|
✅ 按钮显示条件准确匹配业务流程
|
||||||
|
✅ 避免了不合理的操作组合
|
||||||
|
✅ 状态判断逻辑清晰可维护
|
||||||
|
|
||||||
|
### 3. 用户体验
|
||||||
|
✅ 操作流程更加直观
|
||||||
|
✅ 减少了用户的困惑和误操作
|
||||||
|
✅ 提供了及时的反馈和确认
|
||||||
|
|
||||||
|
## 后续优化建议
|
||||||
|
|
||||||
|
### 1. 权限控制
|
||||||
|
- 根据用户角色显示不同的操作按钮
|
||||||
|
- 财务人员可以处理退款,普通管理员不能
|
||||||
|
|
||||||
|
### 2. 批量操作
|
||||||
|
- 支持批量发货
|
||||||
|
- 支持批量退款处理
|
||||||
|
|
||||||
|
### 3. 操作日志
|
||||||
|
- 记录所有订单操作的历史
|
||||||
|
- 显示操作人员和操作时间
|
||||||
|
|
||||||
|
### 4. 自动化流程
|
||||||
|
- 超时自动取消未付款订单
|
||||||
|
- 自动确认收货(发货后N天)
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
通过这次改进,订单详情页面的按钮设计变得更加完整、准确和用户友好。新的设计不仅解决了原有的逻辑问题,还增加了重要的功能,为订单管理提供了更好的支持。
|
||||||
|
|
||||||
|
这些改进将显著提升管理员的工作效率,减少操作错误,并为用户提供更好的订单处理体验。
|
||||||
237
docs/ORDER_LIST_ACTION_BUTTONS.md
Normal file
237
docs/ORDER_LIST_ACTION_BUTTONS.md
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
# 订单列表操作按钮设计
|
||||||
|
|
||||||
|
## 设计概述
|
||||||
|
|
||||||
|
为订单列表页面设计了根据不同订单状态显示相应操作按钮的功能,提供更精准、更直观的订单管理体验。
|
||||||
|
|
||||||
|
## 按钮设计原则
|
||||||
|
|
||||||
|
### 1. 🎯 **状态驱动**
|
||||||
|
- 根据订单的支付状态、发货状态、订单状态组合显示按钮
|
||||||
|
- 确保每个状态下的操作都符合业务逻辑
|
||||||
|
|
||||||
|
### 2. 🎨 **视觉层次**
|
||||||
|
- 主要操作使用蓝色样式 (`ele-text-primary`)
|
||||||
|
- 成功操作使用绿色样式 (`ele-text-success`)
|
||||||
|
- 警告操作使用橙色样式 (`ele-text-warning`)
|
||||||
|
- 危险操作使用红色样式 (`ele-text-danger`)
|
||||||
|
|
||||||
|
### 3. 🔒 **安全确认**
|
||||||
|
- 所有危险操作都有确认对话框
|
||||||
|
- 明确的操作说明和后果提示
|
||||||
|
|
||||||
|
## 完整的按钮矩阵
|
||||||
|
|
||||||
|
### 基础操作(所有状态)
|
||||||
|
|
||||||
|
| 按钮 | 图标 | 样式 | 说明 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| 详情 | 👁️ EyeOutlined | 默认 | 查看订单详细信息 |
|
||||||
|
|
||||||
|
### 未付款状态 (payStatus=0, orderStatus=0)
|
||||||
|
|
||||||
|
| 按钮 | 图标 | 样式 | 操作 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| 修改 | ✏️ EditOutlined | 默认 | 修改订单信息 |
|
||||||
|
| 取消 | ❌ CloseOutlined | 警告 | 取消订单 |
|
||||||
|
|
||||||
|
### 已付款未发货 (payStatus=1, deliveryStatus=10, 未取消)
|
||||||
|
|
||||||
|
| 按钮 | 图标 | 样式 | 操作 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| 发货 | 🚚 SendOutlined | 主要 | 标记为已发货 |
|
||||||
|
| 退款 | ↩️ UndoOutlined | 默认 | 申请退款 |
|
||||||
|
|
||||||
|
### 已发货未完成 (payStatus=1, deliveryStatus=20, orderStatus=0)
|
||||||
|
|
||||||
|
| 按钮 | 图标 | 样式 | 操作 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| 确认收货 | ✅ CheckOutlined | 主要 | 确认收货并完成订单 |
|
||||||
|
| 退款 | ↩️ UndoOutlined | 默认 | 申请退款 |
|
||||||
|
|
||||||
|
### 退款申请中 (orderStatus=4,7)
|
||||||
|
|
||||||
|
| 按钮 | 图标 | 样式 | 操作 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| 同意退款 | ✅ CheckCircleOutlined | 成功 | 同意退款申请 |
|
||||||
|
| 拒绝退款 | ❌ CloseCircleOutlined | 危险 | 拒绝退款申请 |
|
||||||
|
|
||||||
|
### 退款被拒绝 (orderStatus=5)
|
||||||
|
|
||||||
|
| 按钮 | 图标 | 样式 | 操作 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| 重新处理 | 🔄 RedoOutlined | 默认 | 重新提交退款申请 |
|
||||||
|
|
||||||
|
### 已完成 (orderStatus=1)
|
||||||
|
|
||||||
|
| 按钮 | 图标 | 样式 | 操作 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| 申请退款 | ↩️ UndoOutlined | 默认 | 为已完成订单申请退款 |
|
||||||
|
|
||||||
|
### 可删除状态 (orderStatus=1,2,6)
|
||||||
|
|
||||||
|
| 按钮 | 图标 | 样式 | 操作 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| 删除 | 🗑️ DeleteOutlined | 危险 | 删除订单记录 |
|
||||||
|
|
||||||
|
## 代码实现
|
||||||
|
|
||||||
|
### 模板结构
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template v-if="column.key === 'action'">
|
||||||
|
<a-space>
|
||||||
|
<!-- 查看详情 - 所有状态都可以查看 -->
|
||||||
|
<a @click.stop="openEdit(record)">
|
||||||
|
<EyeOutlined /> 详情
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- 未付款状态的操作 -->
|
||||||
|
<template v-if="record.payStatus === 0 && record.orderStatus === 0">
|
||||||
|
<!-- 修改和取消按钮 -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 已付款未发货状态的操作 -->
|
||||||
|
<template v-if="record.payStatus === 1 && record.deliveryStatus === 10 && !isCancelledStatus(record.orderStatus)">
|
||||||
|
<!-- 发货和退款按钮 -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 其他状态的操作... -->
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 辅助判断函数
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 判断是否为取消状态
|
||||||
|
const isCancelledStatus = (orderStatus?: number) => {
|
||||||
|
return [2, 3].includes(orderStatus || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断是否为退款相关状态
|
||||||
|
const isRefundStatus = (orderStatus?: number) => {
|
||||||
|
return [4, 5, 6, 7].includes(orderStatus || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断是否可以删除订单
|
||||||
|
const canDeleteOrder = (order: ShopOrder) => {
|
||||||
|
return [1, 2, 6].includes(order.orderStatus || 0);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 操作方法示例
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 发货处理
|
||||||
|
const handleDelivery = (record: ShopOrder) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认发货',
|
||||||
|
content: '确定要将此订单标记为已发货吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
const deliveryTime = toDateString(new Date(), 'yyyy-MM-dd HH:mm:ss');
|
||||||
|
await updateShopOrder({
|
||||||
|
...record,
|
||||||
|
deliveryStatus: 20,
|
||||||
|
deliveryTime: deliveryTime
|
||||||
|
});
|
||||||
|
message.success('发货成功');
|
||||||
|
reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '发货失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## 状态流转图
|
||||||
|
|
||||||
|
```
|
||||||
|
未付款订单 → [修改/取消]
|
||||||
|
↓ 付款
|
||||||
|
已付款未发货 → [发货/退款]
|
||||||
|
↓ 发货
|
||||||
|
已发货未完成 → [确认收货/退款]
|
||||||
|
↓ 确认收货
|
||||||
|
已完成订单 → [申请退款/删除]
|
||||||
|
|
||||||
|
退款流程:
|
||||||
|
申请退款 → [同意/拒绝]
|
||||||
|
↓ 同意
|
||||||
|
退款成功 → [删除]
|
||||||
|
↓ 拒绝
|
||||||
|
退款被拒绝 → [重新处理/删除]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 用户体验优化
|
||||||
|
|
||||||
|
### 1. 按钮排序
|
||||||
|
- 主要操作放在前面(发货、确认收货)
|
||||||
|
- 次要操作放在中间(修改、申请退款)
|
||||||
|
- 危险操作放在最后(取消、删除)
|
||||||
|
|
||||||
|
### 2. 视觉反馈
|
||||||
|
- 使用图标增强按钮识别度
|
||||||
|
- 颜色编码表示操作类型
|
||||||
|
- 分隔线清晰区分不同操作
|
||||||
|
|
||||||
|
### 3. 操作确认
|
||||||
|
- 危险操作使用 `a-popconfirm` 组件
|
||||||
|
- 明确的确认文案
|
||||||
|
- 详细的操作说明
|
||||||
|
|
||||||
|
### 4. 错误处理
|
||||||
|
- 统一的错误提示
|
||||||
|
- 操作失败后的状态恢复
|
||||||
|
- 网络异常的友好提示
|
||||||
|
|
||||||
|
## 权限控制建议
|
||||||
|
|
||||||
|
### 1. 角色权限
|
||||||
|
```typescript
|
||||||
|
// 根据用户角色显示不同按钮
|
||||||
|
const userRole = getCurrentUserRole();
|
||||||
|
|
||||||
|
// 财务人员可以处理退款
|
||||||
|
const canHandleRefund = userRole.includes('FINANCE') || userRole.includes('ADMIN');
|
||||||
|
|
||||||
|
// 仓库人员可以发货
|
||||||
|
const canDelivery = userRole.includes('WAREHOUSE') || userRole.includes('ADMIN');
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 按钮权限控制
|
||||||
|
```vue
|
||||||
|
<a
|
||||||
|
v-if="canHandleRefund && (record.orderStatus === 4 || record.orderStatus === 7)"
|
||||||
|
@click.stop="handleApproveRefund(record)"
|
||||||
|
class="ele-text-success"
|
||||||
|
>
|
||||||
|
<CheckCircleOutlined /> 同意退款
|
||||||
|
</a>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 性能优化
|
||||||
|
|
||||||
|
### 1. 条件渲染优化
|
||||||
|
- 使用 `v-if` 而不是 `v-show` 减少DOM节点
|
||||||
|
- 合理组织条件判断顺序
|
||||||
|
- 避免重复的状态计算
|
||||||
|
|
||||||
|
### 2. 事件处理优化
|
||||||
|
- 使用 `@click.stop` 防止事件冒泡
|
||||||
|
- 异步操作添加loading状态
|
||||||
|
- 防抖处理频繁点击
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
新的订单列表操作按钮设计具有以下优势:
|
||||||
|
|
||||||
|
1. **功能完整**:覆盖订单全生命周期的所有操作
|
||||||
|
2. **逻辑清晰**:按钮显示严格遵循业务流程
|
||||||
|
3. **用户友好**:直观的图标和颜色编码
|
||||||
|
4. **安全可靠**:危险操作有确认机制
|
||||||
|
5. **易于维护**:模块化的代码结构
|
||||||
|
|
||||||
|
这个设计将显著提升订单管理的效率和用户体验。
|
||||||
@@ -13,29 +13,95 @@
|
|||||||
>
|
>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<a-space>
|
<a-space>
|
||||||
<!-- 发货按钮:已付款且未发货时显示 -->
|
<!-- 未付款状态的操作 -->
|
||||||
|
<template v-if="!form.payStatus">
|
||||||
|
<!-- 取消订单:未完成且未付款 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.orderStatus === 0"
|
||||||
|
@click="handleCancelOrder"
|
||||||
|
danger
|
||||||
|
:loading="loading"
|
||||||
|
>
|
||||||
|
取消订单
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<!-- 修改订单:未完成且未付款 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.orderStatus === 0"
|
||||||
|
@click="handleEditOrder"
|
||||||
|
:loading="loading"
|
||||||
|
>
|
||||||
|
修改订单
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 已付款状态的操作 -->
|
||||||
|
<template v-if="form.payStatus">
|
||||||
|
<!-- 发货按钮:已付款且未发货且未取消 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.deliveryStatus === 10 && !isCancelledStatus(form.orderStatus)"
|
||||||
|
type="primary"
|
||||||
|
@click="handleDelivery"
|
||||||
|
:loading="loading"
|
||||||
|
>
|
||||||
|
发货
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<!-- 确认收货:已发货且未完成 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.deliveryStatus === 20 && form.orderStatus === 0"
|
||||||
|
type="primary"
|
||||||
|
@click="handleConfirmReceive"
|
||||||
|
:loading="loading"
|
||||||
|
>
|
||||||
|
确认收货
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 退款相关操作 -->
|
||||||
|
<template v-if="isRefundStatus(form.orderStatus)">
|
||||||
|
<!-- 同意退款:退款申请中或客户端申请退款 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.orderStatus === 4 || form.orderStatus === 7"
|
||||||
|
type="primary"
|
||||||
|
@click="handleApproveRefund"
|
||||||
|
:loading="loading"
|
||||||
|
>
|
||||||
|
同意退款
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<!-- 拒绝退款:退款申请中或客户端申请退款 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.orderStatus === 4 || form.orderStatus === 7"
|
||||||
|
danger
|
||||||
|
@click="handleRejectRefund"
|
||||||
|
:loading="loading"
|
||||||
|
>
|
||||||
|
拒绝退款
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<!-- 重新处理:退款被拒绝 -->
|
||||||
|
<a-button
|
||||||
|
v-if="form.orderStatus === 5"
|
||||||
|
@click="handleRetryRefund"
|
||||||
|
:loading="loading"
|
||||||
|
>
|
||||||
|
重新处理
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 申请退款:已完成或已发货的订单 -->
|
||||||
<a-button
|
<a-button
|
||||||
v-if="form.payStatus === 1 && form.deliveryStatus === 10"
|
v-if="canApplyRefund(form)"
|
||||||
type="primary"
|
@click="handleApplyRefund"
|
||||||
@click="handleDelivery"
|
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
>
|
>
|
||||||
发货
|
申请退款
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
||||||
<!-- 取消订单按钮:未完成且未取消时显示 -->
|
<!-- 删除订单:已完成、已取消、退款成功 -->
|
||||||
<a-button
|
<a-button
|
||||||
v-if="form.orderStatus === 0"
|
v-if="canDeleteOrder(form)"
|
||||||
@click="handleCancelOrder"
|
|
||||||
danger
|
|
||||||
:loading="loading"
|
|
||||||
>
|
|
||||||
取消订单
|
|
||||||
</a-button>
|
|
||||||
|
|
||||||
<!-- 删除订单按钮:已取消或已完成时显示 -->
|
|
||||||
<a-button
|
|
||||||
v-if="form.orderStatus === 1 || form.orderStatus === 2"
|
|
||||||
@click="handleDeleteOrder"
|
@click="handleDeleteOrder"
|
||||||
danger
|
danger
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
@@ -692,10 +758,14 @@ const handleDelivery = () => {
|
|||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
// 格式化日期为后端期望的格式
|
||||||
|
const now = new Date();
|
||||||
|
const deliveryTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
|
||||||
|
|
||||||
await updateShopOrder({
|
await updateShopOrder({
|
||||||
...form,
|
...form,
|
||||||
deliveryStatus: 20, // 已发货
|
deliveryStatus: 20, // 已发货
|
||||||
deliveryTime: new Date().toISOString()
|
deliveryTime: deliveryTime
|
||||||
});
|
});
|
||||||
message.success('发货成功');
|
message.success('发货成功');
|
||||||
emit('done');
|
emit('done');
|
||||||
@@ -756,6 +826,167 @@ const handleDeleteOrder = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 辅助判断函数 */
|
||||||
|
// 判断是否为取消状态
|
||||||
|
const isCancelledStatus = (orderStatus?: number) => {
|
||||||
|
return [2, 3].includes(orderStatus || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断是否为退款相关状态
|
||||||
|
const isRefundStatus = (orderStatus?: number) => {
|
||||||
|
return [4, 5, 6, 7].includes(orderStatus || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断是否可以删除订单
|
||||||
|
const canDeleteOrder = (order: ShopOrder) => {
|
||||||
|
// 已完成、已取消、退款成功的订单可以删除
|
||||||
|
return [1, 2, 6].includes(order.orderStatus || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断是否可以申请退款
|
||||||
|
const canApplyRefund = (order: ShopOrder) => {
|
||||||
|
// 已完成或已发货且未申请退款的订单可以申请退款
|
||||||
|
return (order.orderStatus === 1) ||
|
||||||
|
(order.payStatus === 1 && order.deliveryStatus === 20 && order.orderStatus === 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 确认收货(管理员代操作) */
|
||||||
|
const handleConfirmReceive = () => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认收货',
|
||||||
|
content: '确定要将此订单标记为已收货并完成吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
await updateShopOrder({
|
||||||
|
...form,
|
||||||
|
deliveryStatus: 30, // 已收货
|
||||||
|
orderStatus: 1 // 已完成
|
||||||
|
});
|
||||||
|
message.success('确认收货成功');
|
||||||
|
emit('done');
|
||||||
|
updateVisible(false);
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '确认收货失败');
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 同意退款 */
|
||||||
|
const handleApproveRefund = () => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '同意退款',
|
||||||
|
content: '确定要同意此订单的退款申请吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
// 格式化日期为后端期望的格式
|
||||||
|
const now = new Date();
|
||||||
|
const refundTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
|
||||||
|
|
||||||
|
await updateShopOrder({
|
||||||
|
...form,
|
||||||
|
orderStatus: 6, // 退款成功
|
||||||
|
refundTime: refundTime
|
||||||
|
});
|
||||||
|
message.success('退款处理成功');
|
||||||
|
emit('done');
|
||||||
|
updateVisible(false);
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '退款处理失败');
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 拒绝退款 */
|
||||||
|
const handleRejectRefund = () => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '拒绝退款',
|
||||||
|
content: '确定要拒绝此订单的退款申请吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
await updateShopOrder({
|
||||||
|
...form,
|
||||||
|
orderStatus: 5 // 退款被拒绝
|
||||||
|
});
|
||||||
|
message.success('已拒绝退款申请');
|
||||||
|
emit('done');
|
||||||
|
updateVisible(false);
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '操作失败');
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 重新处理退款 */
|
||||||
|
const handleRetryRefund = () => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '重新处理退款',
|
||||||
|
content: '确定要重新处理此订单的退款吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
await updateShopOrder({
|
||||||
|
...form,
|
||||||
|
orderStatus: 4 // 退款申请中
|
||||||
|
});
|
||||||
|
message.success('已重新提交退款申请');
|
||||||
|
emit('done');
|
||||||
|
updateVisible(false);
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '操作失败');
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 申请退款 */
|
||||||
|
const handleApplyRefund = () => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '申请退款',
|
||||||
|
content: '确定要为此订单申请退款吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
// 格式化日期为后端期望的格式
|
||||||
|
const now = new Date();
|
||||||
|
const refundApplyTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
|
||||||
|
|
||||||
|
await updateShopOrder({
|
||||||
|
...form,
|
||||||
|
orderStatus: 4, // 退款申请中
|
||||||
|
refundApplyTime: refundApplyTime
|
||||||
|
});
|
||||||
|
message.success('退款申请已提交');
|
||||||
|
emit('done');
|
||||||
|
updateVisible(false);
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '申请退款失败');
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 修改订单 */
|
||||||
|
const handleEditOrder = () => {
|
||||||
|
message.info('订单修改功能开发中...');
|
||||||
|
// TODO: 实现订单修改功能
|
||||||
|
};
|
||||||
|
|
||||||
/* 保存编辑 */
|
/* 保存编辑 */
|
||||||
const save = () => {
|
const save = () => {
|
||||||
// 保留原有的保存功能
|
// 保留原有的保存功能
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
<!-- 搜索表单 -->
|
<!-- 搜索表单 -->
|
||||||
<template>
|
<template>
|
||||||
<a-space :size="10" style="flex-wrap: wrap">
|
<a-space :size="10" style="flex-wrap: wrap">
|
||||||
<a-button
|
<!-- <a-button-->
|
||||||
danger
|
<!-- danger-->
|
||||||
type="primary"
|
<!-- type="primary"-->
|
||||||
class="ele-btn-icon"
|
<!-- class="ele-btn-icon"-->
|
||||||
:disabled="selection?.length === 0"
|
<!-- :disabled="selection?.length === 0"-->
|
||||||
@click="removeBatch"
|
<!-- @click="removeBatch"-->
|
||||||
>
|
<!-- >-->
|
||||||
<template #icon>
|
<!-- <template #icon>-->
|
||||||
<DeleteOutlined/>
|
<!-- <DeleteOutlined/>-->
|
||||||
</template>
|
<!-- </template>-->
|
||||||
<span>批量删除</span>
|
<!-- <span>批量删除</span>-->
|
||||||
</a-button>
|
<!-- </a-button>-->
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="where.type"
|
v-model:value="where.type"
|
||||||
style="width: 150px"
|
style="width: 150px"
|
||||||
|
|||||||
@@ -16,9 +16,10 @@
|
|||||||
<a-tab-pane key="undelivered" tab="待发货"/>
|
<a-tab-pane key="undelivered" tab="待发货"/>
|
||||||
<a-tab-pane key="unreceived" tab="待收货"/>
|
<a-tab-pane key="unreceived" tab="待收货"/>
|
||||||
<a-tab-pane key="completed" tab="已完成"/>
|
<a-tab-pane key="completed" tab="已完成"/>
|
||||||
<a-tab-pane key="deleted" tab="已取消"/>
|
<a-tab-pane key="cancelled" tab="已取消"/>
|
||||||
<!-- <a-tab-pane key="unevaluated" tab="待评价"/>-->
|
<!-- <a-tab-pane key="unevaluated" tab="待评价"/>-->
|
||||||
<!-- <a-tab-pane key="refunded" tab="已退款"/>-->
|
<a-tab-pane key="refunded" tab="已退款"/>
|
||||||
|
<!-- <a-tab-pane key="deleted" tab="已删除"/>-->
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
<ele-pro-table
|
<ele-pro-table
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
@@ -26,7 +27,6 @@
|
|||||||
:columns="columns"
|
:columns="columns"
|
||||||
:datasource="datasource"
|
:datasource="datasource"
|
||||||
:customRow="customRow"
|
:customRow="customRow"
|
||||||
v-model:selection="selection"
|
|
||||||
:toolbar="false"
|
:toolbar="false"
|
||||||
tool-class="ele-toolbar-form"
|
tool-class="ele-toolbar-form"
|
||||||
class="sys-org-table"
|
class="sys-org-table"
|
||||||
@@ -63,10 +63,10 @@
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.key === 'payStatus'">
|
<template v-if="column.key === 'payStatus'">
|
||||||
<a-tag v-if="record.payStatus == 1" color="green" @click.stop="updatePayStatus(record)"
|
<a-tag v-if="record.payStatus" color="green" @click.stop="updatePayStatus(record)"
|
||||||
class="cursor-pointer">已付款
|
class="cursor-pointer">已付款
|
||||||
</a-tag>
|
</a-tag>
|
||||||
<a-tag v-if="record.payStatus == 0" @click.stop="updatePayStatus(record)" class="cursor-pointer">未付款
|
<a-tag v-if="!record.payStatus" @click.stop="updatePayStatus(record)" class="cursor-pointer">未付款
|
||||||
</a-tag>
|
</a-tag>
|
||||||
<a-tag v-if="record.payStatus == 3">未付款,占场中</a-tag>
|
<a-tag v-if="record.payStatus == 3">未付款,占场中</a-tag>
|
||||||
</template>
|
</template>
|
||||||
@@ -78,9 +78,9 @@
|
|||||||
<a-tag v-if="record.sex === 2">女</a-tag>
|
<a-tag v-if="record.sex === 2">女</a-tag>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.key === 'deliveryStatus'">
|
<template v-if="column.key === 'deliveryStatus'">
|
||||||
<a-tag v-if="record.deliveryStatus == 10">未核销</a-tag>
|
<a-tag v-if="record.deliveryStatus == 10">未发货</a-tag>
|
||||||
<a-tag v-if="record.deliveryStatus == 20" color="green">已核销</a-tag>
|
<a-tag v-if="record.deliveryStatus == 20" color="green">已发货</a-tag>
|
||||||
<a-tag v-if="record.deliveryStatus == 30" color="bule">部分核销</a-tag>
|
<a-tag v-if="record.deliveryStatus == 30" color="bule">部分发货</a-tag>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.key === 'orderStatus'">
|
<template v-if="column.key === 'orderStatus'">
|
||||||
<a-tag v-if="record.orderStatus === 0">未完成</a-tag>
|
<a-tag v-if="record.orderStatus === 0">未完成</a-tag>
|
||||||
@@ -102,16 +102,92 @@
|
|||||||
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
|
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.key === 'action'">
|
<template v-if="column.key === 'action'">
|
||||||
<a-space>
|
<!-- 查看详情 - 所有状态都可以查看 -->
|
||||||
<a @click.stop="openEdit(record)">修改</a>
|
<a @click.stop="openEdit(record)">
|
||||||
<a-divider type="vertical"/>
|
<EyeOutlined /> 详情
|
||||||
<a-popconfirm
|
</a>
|
||||||
title="确定要删除此记录吗?"
|
|
||||||
@confirm.stop="remove(record)"
|
<!-- 未付款状态的操作 -->
|
||||||
>
|
<template v-if="!record.payStatus && record.orderStatus === 0">
|
||||||
<a class="ele-text-danger">删除</a>
|
<a-divider type="vertical"/>
|
||||||
</a-popconfirm>
|
<a @click.stop="handleEditOrder(record)">
|
||||||
</a-space>
|
<EditOutlined /> 修改
|
||||||
|
</a>
|
||||||
|
<a-divider type="vertical"/>
|
||||||
|
<a
|
||||||
|
@click.stop="openEdit(record)"
|
||||||
|
>
|
||||||
|
<a class="ele-text-warning">
|
||||||
|
<CloseOutlined /> 取消
|
||||||
|
</a>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 已付款未发货状态的操作 -->
|
||||||
|
<template v-if="record.payStatus && record.deliveryStatus === 10 && !isCancelledStatus(record.orderStatus)">
|
||||||
|
<a-divider type="vertical"/>
|
||||||
|
<a @click.stop="handleDelivery(record)" class="ele-text-primary">
|
||||||
|
<SendOutlined /> 发货
|
||||||
|
</a>
|
||||||
|
<a-divider type="vertical"/>
|
||||||
|
<a @click.stop="handleApplyRefund(record)">
|
||||||
|
<UndoOutlined /> 退款
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 已发货未完成状态的操作 -->
|
||||||
|
<template v-if="record.payStatus && record.deliveryStatus === 20 && record.orderStatus === 0">
|
||||||
|
<a-divider type="vertical"/>
|
||||||
|
<a @click.stop="handleConfirmReceive(record)" class="ele-text-primary">
|
||||||
|
<CheckOutlined /> 确认收货
|
||||||
|
</a>
|
||||||
|
<a-divider type="vertical"/>
|
||||||
|
<a @click.stop="handleApplyRefund(record)">
|
||||||
|
<UndoOutlined /> 退款
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 退款相关状态的操作 -->
|
||||||
|
<template v-if="isRefundStatus(record.orderStatus)">
|
||||||
|
<template v-if="record.orderStatus === 4 || record.orderStatus === 7">
|
||||||
|
<a-divider type="vertical"/>
|
||||||
|
<a @click.stop="handleApproveRefund(record)" class="ele-text-success">
|
||||||
|
<CheckCircleOutlined /> 同意退款
|
||||||
|
</a>
|
||||||
|
<a-divider type="vertical"/>
|
||||||
|
<a @click.stop="handleRejectRefund(record)" class="ele-text-danger">
|
||||||
|
<CloseCircleOutlined /> 拒绝退款
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="record.orderStatus === 5">
|
||||||
|
<a-divider type="vertical"/>
|
||||||
|
<a @click.stop="handleRetryRefund(record)">
|
||||||
|
<RedoOutlined /> 重新处理
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 已完成状态的操作 -->
|
||||||
|
<template v-if="record.orderStatus === 1">
|
||||||
|
<a-divider type="vertical"/>
|
||||||
|
<a @click.stop="handleApplyRefund(record)">
|
||||||
|
<UndoOutlined /> 申请退款
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 删除操作 - 已完成、已取消、退款成功的订单可以删除 -->
|
||||||
|
<template v-if="canDeleteOrder(record)">
|
||||||
|
<a-divider type="vertical"/>
|
||||||
|
<a-popconfirm
|
||||||
|
title="确定要删除此订单吗?删除后无法恢复。"
|
||||||
|
@confirm.stop="remove(record)"
|
||||||
|
>
|
||||||
|
<a class="ele-text-danger">
|
||||||
|
<DeleteOutlined /> 删除
|
||||||
|
</a>
|
||||||
|
</a-popconfirm>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</ele-pro-table>
|
</ele-pro-table>
|
||||||
@@ -130,14 +206,24 @@ import type {
|
|||||||
ColumnItem
|
ColumnItem
|
||||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||||
import {
|
import {
|
||||||
ExclamationCircleOutlined
|
ExclamationCircleOutlined,
|
||||||
|
EyeOutlined,
|
||||||
|
EditOutlined,
|
||||||
|
CloseOutlined,
|
||||||
|
SendOutlined,
|
||||||
|
UndoOutlined,
|
||||||
|
CheckOutlined,
|
||||||
|
CheckCircleOutlined,
|
||||||
|
CloseCircleOutlined,
|
||||||
|
RedoOutlined,
|
||||||
|
DeleteOutlined
|
||||||
} from '@ant-design/icons-vue';
|
} from '@ant-design/icons-vue';
|
||||||
import Search from './components/search.vue';
|
import Search from './components/search.vue';
|
||||||
import {getPageTitle} from "@/utils/common";
|
import {getPageTitle} from "@/utils/common";
|
||||||
import {toDateString} from 'ele-admin-pro';
|
import {toDateString} from 'ele-admin-pro';
|
||||||
import OrderInfo from './components/orderInfo.vue';
|
import OrderInfo from './components/orderInfo.vue';
|
||||||
import {ShopOrder, ShopOrderParam} from "@/api/shop/shopOrder/model";
|
import {ShopOrder, ShopOrderParam} from "@/api/shop/shopOrder/model";
|
||||||
import {pageShopOrder, repairOrder, removeShopOrder, removeBatchShopOrder} from "@/api/shop/shopOrder";
|
import {pageShopOrder, repairOrder, removeShopOrder, removeBatchShopOrder, updateShopOrder} from "@/api/shop/shopOrder";
|
||||||
import {updateUser} from "@/api/system/user";
|
import {updateUser} from "@/api/system/user";
|
||||||
import {getPayType} from '@/utils/shop';
|
import {getPayType} from '@/utils/shop';
|
||||||
import {message, Modal} from 'ant-design-vue';
|
import {message, Modal} from 'ant-design-vue';
|
||||||
@@ -189,7 +275,7 @@ const columns = ref<ColumnItem[]>([
|
|||||||
title: '商品信息',
|
title: '商品信息',
|
||||||
dataIndex: 'orderGoods',
|
dataIndex: 'orderGoods',
|
||||||
key: 'orderGoods',
|
key: 'orderGoods',
|
||||||
width: 400,
|
width: 360,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '实付金额',
|
title: '实付金额',
|
||||||
@@ -211,7 +297,7 @@ const columns = ref<ColumnItem[]>([
|
|||||||
align: 'center'
|
align: 'center'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '核销状态',
|
title: '发货状态',
|
||||||
dataIndex: 'deliveryStatus',
|
dataIndex: 'deliveryStatus',
|
||||||
key: 'deliveryStatus',
|
key: 'deliveryStatus',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
@@ -229,6 +315,12 @@ const columns = ref<ColumnItem[]>([
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
|
// title: '备注',
|
||||||
|
// dataIndex: 'comments',
|
||||||
|
// key: 'comments',
|
||||||
|
// align: 'center',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
// title: '支付时间',
|
// title: '支付时间',
|
||||||
// dataIndex: 'payTime',
|
// dataIndex: 'payTime',
|
||||||
// key: 'payTime',
|
// key: 'payTime',
|
||||||
@@ -246,15 +338,15 @@ const columns = ref<ColumnItem[]>([
|
|||||||
sorter: true,
|
sorter: true,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
customRender: ({text}) => toDateString(text)
|
customRender: ({text}) => toDateString(text)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
width: 280,
|
||||||
|
fixed: 'right',
|
||||||
|
align: 'center',
|
||||||
|
hideInSetting: true
|
||||||
}
|
}
|
||||||
// {
|
|
||||||
// title: '操作',
|
|
||||||
// key: 'action',
|
|
||||||
// width: 180,
|
|
||||||
// fixed: 'right',
|
|
||||||
// align: 'center',
|
|
||||||
// hideInSetting: true
|
|
||||||
// }
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/* 搜索 */
|
/* 搜索 */
|
||||||
@@ -298,6 +390,10 @@ const onTabs = () => {
|
|||||||
// 已完成:order_status = 1
|
// 已完成:order_status = 1
|
||||||
filterParams.statusFilter = 5;
|
filterParams.statusFilter = 5;
|
||||||
break;
|
break;
|
||||||
|
case 'cancelled':
|
||||||
|
// 已取消:order_status = 2
|
||||||
|
filterParams.statusFilter = 8;
|
||||||
|
break;
|
||||||
case 'refunded':
|
case 'refunded':
|
||||||
// 已退款:order_status = 6
|
// 已退款:order_status = 6
|
||||||
filterParams.statusFilter = 6;
|
filterParams.statusFilter = 6;
|
||||||
@@ -351,6 +447,183 @@ const query = () => {
|
|||||||
loading.value = true;
|
loading.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 辅助判断函数 */
|
||||||
|
// 判断是否为取消状态
|
||||||
|
const isCancelledStatus = (orderStatus?: number) => {
|
||||||
|
return [2, 3].includes(orderStatus || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断是否为退款相关状态
|
||||||
|
const isRefundStatus = (orderStatus?: number) => {
|
||||||
|
return [4, 5, 6, 7].includes(orderStatus || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 判断是否可以删除订单
|
||||||
|
const canDeleteOrder = (order: ShopOrder) => {
|
||||||
|
// 已完成、已取消、退款成功的订单可以删除
|
||||||
|
return [1, 2, 6].includes(order.orderStatus || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 订单操作方法 */
|
||||||
|
// 修改订单
|
||||||
|
const handleEditOrder = (record: ShopOrder) => {
|
||||||
|
message.info('订单修改功能开发中...');
|
||||||
|
// TODO: 实现订单修改功能
|
||||||
|
};
|
||||||
|
|
||||||
|
// 取消订单
|
||||||
|
const handleCancelOrder = (record: ShopOrder) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认取消订单',
|
||||||
|
content: '确定要取消此订单吗?取消后无法恢复。',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
await updateShopOrder({
|
||||||
|
...record,
|
||||||
|
orderStatus: 2 // 已取消
|
||||||
|
});
|
||||||
|
message.success('订单已取消');
|
||||||
|
reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '取消订单失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 发货处理
|
||||||
|
const handleDelivery = (record: ShopOrder) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认发货',
|
||||||
|
content: '确定要将此订单标记为已发货吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
const now = new Date();
|
||||||
|
const deliveryTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
|
||||||
|
|
||||||
|
await updateShopOrder({
|
||||||
|
...record,
|
||||||
|
deliveryStatus: 20, // 已发货
|
||||||
|
deliveryTime: deliveryTime
|
||||||
|
});
|
||||||
|
message.success('发货成功');
|
||||||
|
reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '发货失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 确认收货
|
||||||
|
const handleConfirmReceive = (record: ShopOrder) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认收货',
|
||||||
|
content: '确定要将此订单标记为已收货并完成吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
await updateShopOrder({
|
||||||
|
...record,
|
||||||
|
deliveryStatus: 30, // 已收货
|
||||||
|
orderStatus: 1 // 已完成
|
||||||
|
});
|
||||||
|
message.success('确认收货成功');
|
||||||
|
reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '确认收货失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 同意退款
|
||||||
|
const handleApproveRefund = (record: ShopOrder) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '同意退款',
|
||||||
|
content: '确定要同意此订单的退款申请吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
const now = new Date();
|
||||||
|
const refundTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
|
||||||
|
|
||||||
|
await updateShopOrder({
|
||||||
|
...record,
|
||||||
|
orderStatus: 6, // 退款成功
|
||||||
|
refundTime: refundTime
|
||||||
|
});
|
||||||
|
message.success('退款处理成功');
|
||||||
|
reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '退款处理失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 拒绝退款
|
||||||
|
const handleRejectRefund = (record: ShopOrder) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '拒绝退款',
|
||||||
|
content: '确定要拒绝此订单的退款申请吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
await updateShopOrder({
|
||||||
|
...record,
|
||||||
|
orderStatus: 5 // 退款被拒绝
|
||||||
|
});
|
||||||
|
message.success('已拒绝退款申请');
|
||||||
|
reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '操作失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 重新处理退款
|
||||||
|
const handleRetryRefund = (record: ShopOrder) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '重新处理退款',
|
||||||
|
content: '确定要重新处理此订单的退款吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
await updateShopOrder({
|
||||||
|
...record,
|
||||||
|
orderStatus: 4 // 退款申请中
|
||||||
|
});
|
||||||
|
message.success('已重新提交退款申请');
|
||||||
|
reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '操作失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 申请退款
|
||||||
|
const handleApplyRefund = (record: ShopOrder) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '申请退款',
|
||||||
|
content: '确定要为此订单申请退款吗?',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
const now = new Date();
|
||||||
|
const refundApplyTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
|
||||||
|
|
||||||
|
await updateShopOrder({
|
||||||
|
...record,
|
||||||
|
orderStatus: 4, // 退款申请中
|
||||||
|
refundApplyTime: refundApplyTime
|
||||||
|
});
|
||||||
|
message.success('退款申请已提交');
|
||||||
|
reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '申请退款失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/* 删除单个订单 */
|
/* 删除单个订单 */
|
||||||
const remove = (row: ShopOrder) => {
|
const remove = (row: ShopOrder) => {
|
||||||
removeShopOrder(row.orderId)
|
removeShopOrder(row.orderId)
|
||||||
|
|||||||
@@ -165,11 +165,11 @@ function OrderList(props: OrderListProps) {
|
|||||||
statusParams,
|
statusParams,
|
||||||
searchConditions
|
searchConditions
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await pageShopOrder(searchConditions);
|
const res = await pageShopOrder(searchConditions);
|
||||||
let newList: OrderWithGoods[] = [];
|
let newList: OrderWithGoods[] = [];
|
||||||
|
|
||||||
if (res?.list && res?.list.length > 0) {
|
if (res?.list && res?.list.length > 0) {
|
||||||
// 为每个订单获取商品信息
|
// 为每个订单获取商品信息
|
||||||
const ordersWithGoods = await Promise.all(
|
const ordersWithGoods = await Promise.all(
|
||||||
@@ -197,7 +197,7 @@ function OrderList(props: OrderListProps) {
|
|||||||
newList = [];
|
newList = [];
|
||||||
setHasMore(false);
|
setHasMore(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
setList(newList || []);
|
setList(newList || []);
|
||||||
setPage(currentPage);
|
setPage(currentPage);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -212,6 +212,11 @@ function OrderList(props: OrderListProps) {
|
|||||||
reload();
|
reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 格式化日期为后端期望的格式
|
||||||
|
const formatDateForBackend = (date: Date) => {
|
||||||
|
return dayjs(date).format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
};
|
||||||
|
|
||||||
// 确认收货
|
// 确认收货
|
||||||
const confirmReceive = async (order: ShopOrder) => {
|
const confirmReceive = async (order: ShopOrder) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user