diff --git a/.env.development b/.env.development index f979a78..0b7ff2f 100644 --- a/.env.development +++ b/.env.development @@ -1,3 +1,3 @@ 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 diff --git a/docs/DATE_FORMAT_FIX.md b/docs/DATE_FORMAT_FIX.md new file mode 100644 index 0000000..dd451f1 --- /dev/null +++ b/docs/DATE_FORMAT_FIX.md @@ -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. **代码一致性**:前端各个模块使用相同的日期处理方式 + +这些改进确保了订单管理功能的稳定性和可靠性。 diff --git a/docs/ORDER_DETAIL_BUTTON_ANALYSIS.md b/docs/ORDER_DETAIL_BUTTON_ANALYSIS.md new file mode 100644 index 0000000..21b4bea --- /dev/null +++ b/docs/ORDER_DETAIL_BUTTON_ANALYSIS.md @@ -0,0 +1,278 @@ +# 订单详情页面按钮设计分析 + +## 当前按钮设计 + +### 现有按钮逻辑 + + +````vue + + + 发货 + + + + + 取消订单 + + + + + 删除订单 + +```` + + +## 问题分析 + +### 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 + +``` + +### 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 + + + 主要操作 + + + 次要操作 + + + 危险操作 + + + 关闭 + +``` + +#### 操作确认和提示 +- 所有危险操作都应该有确认对话框 +- 操作成功后显示明确的提示信息 +- 操作失败时显示具体的错误原因 + +#### 权限控制 +```typescript +// 根据用户角色显示不同的操作按钮 +const userRole = getCurrentUserRole(); +const canApproveRefund = userRole.includes('ADMIN') || userRole.includes('FINANCE'); +``` + +## 实施建议 + +### 阶段一:修复现有问题 +1. 完善按钮显示逻辑 +2. 添加缺失的操作按钮 +3. 修复状态判断错误 + +### 阶段二:功能增强 +1. 添加退款处理功能 +2. 实现订单修改功能 +3. 添加批量操作支持 + +### 阶段三:用户体验优化 +1. 优化按钮布局和样式 +2. 添加操作权限控制 +3. 完善错误处理和用户提示 + +## 总结 + +当前的订单详情页面按钮设计存在逻辑不完整、状态判断不准确、缺少关键操作等问题。建议按照上述分析进行系统性的改进,以提供更完整、更准确、更用户友好的订单管理体验。 diff --git a/docs/ORDER_DETAIL_BUTTON_IMPROVEMENTS.md b/docs/ORDER_DETAIL_BUTTON_IMPROVEMENTS.md new file mode 100644 index 0000000..ba062e6 --- /dev/null +++ b/docs/ORDER_DETAIL_BUTTON_IMPROVEMENTS.md @@ -0,0 +1,194 @@ +# 订单详情页面按钮设计改进 + +## 改进概述 + +针对订单详情页面按钮设计的问题,我们进行了系统性的改进,使按钮显示逻辑更加完整、准确,并增加了缺失的关键操作功能。 + +## 主要改进内容 + +### 1. 🔧 **完善按钮显示逻辑** + +#### 改进前 +```vue + +发货 +取消订单 +删除订单 +``` + +#### 改进后 +```vue + + + + + + +``` + +### 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天) + +## 总结 + +通过这次改进,订单详情页面的按钮设计变得更加完整、准确和用户友好。新的设计不仅解决了原有的逻辑问题,还增加了重要的功能,为订单管理提供了更好的支持。 + +这些改进将显著提升管理员的工作效率,减少操作错误,并为用户提供更好的订单处理体验。 diff --git a/docs/ORDER_LIST_ACTION_BUTTONS.md b/docs/ORDER_LIST_ACTION_BUTTONS.md new file mode 100644 index 0000000..6a6ccb1 --- /dev/null +++ b/docs/ORDER_LIST_ACTION_BUTTONS.md @@ -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 + +``` + +### 辅助判断函数 + +```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 + + 同意退款 + +``` + +## 性能优化 + +### 1. 条件渲染优化 +- 使用 `v-if` 而不是 `v-show` 减少DOM节点 +- 合理组织条件判断顺序 +- 避免重复的状态计算 + +### 2. 事件处理优化 +- 使用 `@click.stop` 防止事件冒泡 +- 异步操作添加loading状态 +- 防抖处理频繁点击 + +## 总结 + +新的订单列表操作按钮设计具有以下优势: + +1. **功能完整**:覆盖订单全生命周期的所有操作 +2. **逻辑清晰**:按钮显示严格遵循业务流程 +3. **用户友好**:直观的图标和颜色编码 +4. **安全可靠**:危险操作有确认机制 +5. **易于维护**:模块化的代码结构 + +这个设计将显著提升订单管理的效率和用户体验。 diff --git a/src/views/shop/shopOrder/components/orderInfo.vue b/src/views/shop/shopOrder/components/orderInfo.vue index ba91b0b..ab12d26 100644 --- a/src/views/shop/shopOrder/components/orderInfo.vue +++ b/src/views/shop/shopOrder/components/orderInfo.vue @@ -13,29 +13,95 @@ > @@ -130,14 +206,24 @@ import type { ColumnItem } from 'ele-admin-pro/es/ele-pro-table/types'; import { - ExclamationCircleOutlined + ExclamationCircleOutlined, + EyeOutlined, + EditOutlined, + CloseOutlined, + SendOutlined, + UndoOutlined, + CheckOutlined, + CheckCircleOutlined, + CloseCircleOutlined, + RedoOutlined, + DeleteOutlined } from '@ant-design/icons-vue'; import Search from './components/search.vue'; import {getPageTitle} from "@/utils/common"; import {toDateString} from 'ele-admin-pro'; import OrderInfo from './components/orderInfo.vue'; 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 {getPayType} from '@/utils/shop'; import {message, Modal} from 'ant-design-vue'; @@ -189,7 +275,7 @@ const columns = ref([ title: '商品信息', dataIndex: 'orderGoods', key: 'orderGoods', - width: 400, + width: 360, }, { title: '实付金额', @@ -211,7 +297,7 @@ const columns = ref([ align: 'center' }, { - title: '核销状态', + title: '发货状态', dataIndex: 'deliveryStatus', key: 'deliveryStatus', align: 'center', @@ -229,6 +315,12 @@ const columns = ref([ align: 'center', }, // { + // title: '备注', + // dataIndex: 'comments', + // key: 'comments', + // align: 'center', + // }, + // { // title: '支付时间', // dataIndex: 'payTime', // key: 'payTime', @@ -246,15 +338,15 @@ const columns = ref([ sorter: true, ellipsis: true, 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 filterParams.statusFilter = 5; break; + case 'cancelled': + // 已取消:order_status = 2 + filterParams.statusFilter = 8; + break; case 'refunded': // 已退款:order_status = 6 filterParams.statusFilter = 6; @@ -351,6 +447,183 @@ const query = () => { 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) => { removeShopOrder(row.orderId) diff --git a/src/views/shop/shopOrder/mobile/index.tsx b/src/views/shop/shopOrder/mobile/index.tsx index 84d91c3..0bd91be 100644 --- a/src/views/shop/shopOrder/mobile/index.tsx +++ b/src/views/shop/shopOrder/mobile/index.tsx @@ -165,11 +165,11 @@ function OrderList(props: OrderListProps) { statusParams, searchConditions }); - + try { const res = await pageShopOrder(searchConditions); let newList: OrderWithGoods[] = []; - + if (res?.list && res?.list.length > 0) { // 为每个订单获取商品信息 const ordersWithGoods = await Promise.all( @@ -197,7 +197,7 @@ function OrderList(props: OrderListProps) { newList = []; setHasMore(false); } - + setList(newList || []); setPage(currentPage); setLoading(false); @@ -212,6 +212,11 @@ function OrderList(props: OrderListProps) { reload(); }; + // 格式化日期为后端期望的格式 + const formatDateForBackend = (date: Date) => { + return dayjs(date).format('YYYY-MM-DD HH:mm:ss'); + }; + // 确认收货 const confirmReceive = async (order: ShopOrder) => { try {