Browse Source

feat: update: 优化商品价格为下拉选择

叶静 5 hours ago
parent
commit
e4042906f7

+ 711 - 0
prd.md

@@ -0,0 +1,711 @@
+# 商品创建到下单全流程梳理文档
+
+## 📋 目录
+
+- [业务流程图](#业务流程图)
+- [1. 商品管理模块](#1-商品管理模块)
+- [2. 拼团活动模块](#2-拼团活动模块)
+- [3. 订单管理模块](#3-订单管理模块)
+- [4. 订单操作模块](#4-订单操作模块)
+- [5. 发货处理流程](#5-发货处理流程)
+- [6. 功能实现状态总结](#6-功能实现状态总结)
+
+---
+
+## 业务流程图
+
+### 整体业务流程
+
+```mermaid
+graph TD
+    A[开始] --> B[商品管理模块]
+
+    %% 商品管理
+    B --> B1[创建商品分类✅]
+    B --> B2[创建商品✅]
+    B2 --> B21[第一步: 商品信息✅]
+    B21 --> B22[第二步: 商品属性✅]
+    B22 --> B23[第三步: 提交商品✅]
+
+    %% 拼团活动
+    B23 --> C[拼团活动模块]
+    C --> C1[拼团活动列表✅]
+    C --> C2[创建拼团活动✅]
+    C2 --> C3[设置活动商品全流程✅]
+    C3 --> C31[获取活动商品✅]
+    C3 --> C32[添加商品到活动✅]
+    C3 --> C33[移除商品✅]
+
+    %% 订单管理
+    C32 --> D[订单管理模块]
+    D --> D1[订单列表查询✅]
+    D --> D2[订单详情查询✅]
+    D2 --> D3[订单轨迹✅]
+    D2 --> D4[基本信息✅]
+    D2 --> D5[商品信息✅]
+    D2 --> D6[收货信息✅]
+    D2 --> D7[拼团信息✅]
+
+    %% 订单操作
+    D --> E[订单操作模块]
+    E --> E1[取消订单⚠️<br/>仅未付款]
+    E --> E2[全部退款⚠️<br/>状态未确定]
+    E --> E3[导出订单⚠️<br/>字段待确认]
+    E --> E4[导出发货单⚠️<br/>字段待确认]
+    E --> E5[单个订单发货✅]
+
+    %% 批量发货需求
+    E --> F[批量发货需求❌]
+    F --> F1[导入发货单❌<br/>功能未确定]
+    F --> F2[批量发货❌<br/>功能未确定]
+    F --> F3[下载失败发货单❌<br/>功能未确定]
+
+    %% 样式
+    classDef implemented fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px
+    classDef notImplemented fill:#ffebee,stroke:#b71c1c,stroke-width:2px
+    classDef uncertain fill:#fff3e0,stroke:#e65100,stroke-width:2px
+
+    class B1,B2,B21,B22,B23,C1,C2,C3,C31,C32,C33,D1,D2,D3,D4,D5,D6,D7,E5 implemented
+    class F,F1,F2,F3 notImplemented
+    class E1,E2,E3,E4 uncertain
+```
+
+### 接口详细信息表
+
+| 模块 | 功能 | 接口 | 方法 | 关键参数 | 状态 |
+| --- | --- | --- | --- | --- | --- |
+| 商品管理 | 创建商品分类 | `mall/category` | POST | `{name, parentId, sort, status}` | ✅ |
+| 商品管理 | 创建商品 | `mall/product` | POST | `{cateId, storeName, price, stock}` | ✅ |
+| 拼团活动 | 活动列表 | `mall/flash/activity/list` | POST | `{page, size, status}` | ✅ |
+| 拼团活动 | 创建活动 | `mall/flash/activity` | POST | `{name, startTime, endTime, content}` | ✅ |
+| 拼团活动 | 获取活动商品 | `mall/combination/getActivityProductIds` | GET | `{activityId}` | ✅ |
+| 拼团活动 | 添加商品 | `mall/combination/addActivityProduct` | POST | `{activityId, productId, groupPrice}` | ✅ |
+| 拼团活动 | 移除商品 | `mall/combination/removeActivityProduct` | POST | `{activityId, productId}` | ✅ |
+| 订单管理 | 订单列表 | `mall/order/list` | POST | `{page, size, status, orderId}` | ✅ |
+| 订单管理 | 订单详情 | `mall/order/detail` | GET | `{id}` | ✅ |
+| 订单管理 | 拼团信息 | `mall/pink/orderPink` | GET | `{id}` | ✅ |
+| 订单操作 | 取消订单 | `mall/order/cancel` | POST | `{id}` | ✅ (仅未付款) |
+| 订单操作 | 全部退款 | `mall/order/refund` | POST | `{id}` | ✅ (状态未确定) |
+| 订单操作 | 导出订单 | `mall/order/export` | GET | `{status, startTime, endTime}` | ✅ (字段待确认) |
+| 订单操作 | 导出发货单 | `mall/order/export` | GET | `{status: 5, format: "delivery"}` | ✅ (字段待确认) |
+| 订单操作 | 导入发货单 | `shop/admin/order/order/dispatch` | POST | `FormData: {action, express, file}` | ❌ (未确定) |
+| 订单操作 | 批量发货 | `mall/order/batchDelivery` | POST | `{order_ids, action}` | ❌ (未确定) |
+| 订单操作 | 单个发货 | `mall/order/batchDelivery` | POST | `{order_id, order_item_ids, action, express}` | ✅ |
+
+### 流程说明
+
+- **绿色节点** ✅:已实现功能
+- **红色节点** ❌:未实现功能,需要开发
+- **API节点**:包含具体的接口信息和参数
+
+---
+
+## 1. 商品管理模块
+
+### 1.1 创建商品分类
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/category`
+- **请求方法**: `POST`
+- **请求参数**:
+  ```json
+  {
+    "name": "分类名称",
+    "parentId": "父分类ID",
+    "sort": "排序",
+    "status": "状态"
+  }
+  ```
+
+### 1.2 创建商品 - 三步流程
+
+#### 第一步:商品信息
+
+- **功能状态**: ✅ 已实现
+- **包含字段**:
+  ```json
+  {
+    "cateId": "商品分类ID",
+    "storeName": "商品名称",
+    "keyword": "副标题",
+    "image": "商品主图"
+  }
+  ```
+
+#### 第二步:商品属性
+
+- **功能状态**: ✅ 已实现
+- **包含字段**:
+  ```json
+  {
+    "price": "商品价格",
+    "otPrice": "原价",
+    "stock": "库存",
+    "spec": "规格信息",
+    "attr": "属性信息"
+  }
+  ```
+
+#### 第三步:提交商品
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/product`
+- **请求方法**: `POST`
+- **请求参数**: 完整商品数据(包含前两步所有字段)
+
+#### 商品创建示例数据
+
+```json
+{
+  "id": "",
+  "cateId": "6",
+  "storeName": "测试商品",
+  "keyword": "测试标题",
+  "itemBrand": "测试品牌",
+  "storeInfo": "测试介绍",
+  "itemNumber": "",
+  "price": "",
+  "otPrice": "",
+  "stock": "",
+  "stockThreshold": "",
+  "isShow": 0,
+  "itemSupplier": "测试供应商",
+  "sort": 0,
+  "cost": "",
+  "vipPrice": "",
+  "image": "http://124.220.229.80:9098/img/2025/08/18/201003a5e06841bdbb5b40444e12c29d.png",
+  "sliderImage": "http://124.220.229.80:9098/img/2025/08/18/25c2af8679a54f29b0d96de4ffca6b30.png",
+  "flatPattern": "http://124.220.229.80:9098/img/2025/08/18/8a23f3e53bc34069b7d20a80d29f26d8.png",
+  "specType": 1,
+  "skus": [
+    {
+      "id": 0,
+      "temp_id": 1,
+      "name": "颜色",
+      "batchId": "",
+      "pid": 0,
+      "children": [
+        {
+          "id": 0,
+          "temp_id": 1,
+          "name": "红色",
+          "pid": 0,
+          "imageList": [
+            "http://124.220.229.80:9098/img/2025/08/18/6b7a540642694495b247bf96384ff078.png"
+          ]
+        },
+        {
+          "id": 0,
+          "temp_id": 2,
+          "name": "蓝色",
+          "pid": 0,
+          "imageList": [
+            "http://124.220.229.80:9098/img/2025/08/18/c006f84a33bc47d09cb6c5fa713c937f.png"
+          ]
+        }
+      ]
+    },
+    {
+      "id": 0,
+      "temp_id": 4,
+      "name": "尺寸",
+      "batchId": "",
+      "pid": 0,
+      "children": [
+        {
+          "id": 0,
+          "temp_id": 3,
+          "name": "S",
+          "pid": 0,
+          "imageList": []
+        },
+        {
+          "id": 0,
+          "temp_id": 4,
+          "name": "M",
+          "pid": 0,
+          "imageList": []
+        }
+      ]
+    }
+  ],
+  "sku_prices": [
+    {
+      "id": 0,
+      "temp_id": 1,
+      "goods_sku_ids": "",
+      "goods_id": 0,
+      "weigh": 0,
+      "image": "",
+      "imageList": [],
+      "stock": "50",
+      "stockThreshold": 0,
+      "price": "10",
+      "otPrice": "20",
+      "skuCode": "",
+      "goods_sku_text": ["红色", "S"],
+      "goods_sku_temp_ids": [1, 3]
+    }
+  ],
+  "attrValue": [
+    {
+      "id": 0,
+      "image": "",
+      "price": "10",
+      "otPrice": "20",
+      "stock": "50",
+      "skuCode": "",
+      "stockThreshold": 0,
+      "attrValue": "{\"颜色\":\"红色\",\"尺寸\":\"S\"}",
+      "颜色": "红色",
+      "尺寸": "S",
+      "productId": 0
+    }
+  ],
+  "attr": [
+    {
+      "id": 0,
+      "attrName": "颜色",
+      "attrValues": "红色,蓝色",
+      "attrImgValues": [
+        {
+          "name": "红色",
+          "img": "http://124.220.229.80:9098/img/2025/08/18/6b7a540642694495b247bf96384ff078.png"
+        },
+        {
+          "name": "蓝色",
+          "img": "http://124.220.229.80:9098/img/2025/08/18/c006f84a33bc47d09cb6c5fa713c937f.png"
+        }
+      ]
+    },
+    {
+      "id": 0,
+      "attrName": "尺寸",
+      "attrValues": "S,M",
+      "attrImgValues": [
+        {
+          "name": "S",
+          "img": ""
+        },
+        {
+          "name": "M",
+          "img": ""
+        }
+      ]
+    }
+  ]
+}
+```
+
+---
+
+## 2. 拼团活动模块
+
+### 2.1 拼团活动列表
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/flash/activity/list`
+- **请求方法**: `POST`
+- **请求参数**:
+  ```json
+  {
+    "page": "页码",
+    "size": "每页数量",
+    "status": "活动状态(0:待开始, 1:进行中, 2:已结束)"
+  }
+  ```
+- **功能说明**: 支持按状态筛选(全部、待开始、进行中、已结束)
+
+### 2.2 创建拼团活动
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/flash/activity`
+- **请求方法**: `POST`
+- **请求参数**:
+  ```json
+  {
+    "name": "活动名称",
+    "startTime": "开始时间",
+    "endTime": "结束时间",
+    "content": {
+      "groupNumber": "成团默认人数",
+      "countdownTime": "开团倒计时结束时间"
+    }
+  }
+  ```
+
+### 2.3 设置活动商品全流程
+
+#### 第一步:进入活动详情
+
+- **功能状态**: ✅ 已实现
+- **操作**: 从拼团活动列表点击"设置商品"按钮
+
+#### 第二步:选择商品
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/combination/getActivityProductIds`
+- **请求方法**: `GET`
+- **请求参数**: `{activityId: "活动ID"}`
+- **功能说明**: 获取已设置的商品列表
+
+#### 第三步:添加商品到活动
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/combination/addActivityProduct`
+- **请求方法**: `POST`
+- **请求参数**:
+  ```json
+  {
+    "activityId": "活动ID",
+    "productId": "商品ID",
+    "groupPrice": "拼团价格",
+    "groupNumber": "成团人数"
+  }
+  ```
+
+#### 第四步:移除商品
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/combination/removeActivityProduct`
+- **请求方法**: `POST`
+- **请求参数**: `{activityId: "活动ID", productId: "商品ID"}`
+
+---
+
+## 3. 订单管理模块
+
+### 3.1 订单列表查询
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/order/list`
+- **请求方法**: `POST`
+- **请求参数**:
+  ```json
+  {
+    "page": "页码",
+    "size": "每页数量",
+    "status": "订单状态",
+    "orderId": "订单ID",
+    "userPhone": "用户手机号",
+    "startTime": "开始时间",
+    "endTime": "结束时间"
+  }
+  ```
+
+### 3.2 订单详情查询
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/order/detail`
+- **请求方法**: `GET`
+- **请求参数**:
+  ```json
+  {
+    "id": "订单ID"
+  }
+  ```
+
+### 3.3 订单详情包含信息
+
+#### 订单轨迹信息
+
+- **功能状态**: ✅ 已实现
+- **数据结构**:
+  ```json
+  {
+    "orderStatusVO": [
+      {
+        "status": "状态码",
+        "statusText": "状态文本",
+        "createTime": "创建时间"
+      }
+    ]
+  }
+  ```
+
+#### 基本信息
+
+- **功能状态**: ✅ 已实现
+- **数据结构**:
+  ```json
+  {
+    "orderId": "订单编号",
+    "status": "订单状态",
+    "pinkStatus": "拼团状态",
+    "totalPrice": "全部金额",
+    "payTime": "支付时间",
+    "createTime": "创建时间"
+  }
+  ```
+
+#### 商品信息
+
+- **功能状态**: ✅ 已实现
+- **数据结构**:
+  ```json
+  {
+    "productName": "商品名称",
+    "productImage": "商品图片",
+    "price": "商品价格",
+    "num": "购买数量",
+    "totalPrice": "总价"
+  }
+  ```
+
+#### 收货信息
+
+- **功能状态**: ✅ 已实现
+- **数据结构**:
+  ```json
+  {
+    "realName": "收货人姓名",
+    "userPhone": "收货人电话",
+    "userAddress": "收货地址",
+    "mark": "备注"
+  }
+  ```
+
+#### 拼团信息
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/pink/orderPink`
+- **请求方法**: `GET`
+- **请求参数**:
+  ```json
+  {
+    "id": "订单ID"
+  }
+  ```
+
+---
+
+## 4. 订单操作模块
+
+### 4.1 取消订单
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/order/cancel`
+- **请求方法**: `POST`
+- **请求参数**:
+  ```json
+  {
+    "id": "订单ID(逗号分隔)"
+  }
+  ```
+- **状态限制**: ⚠️ 只有用户未付款的订单可以取消
+
+### 4.2 全部退款
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/order/refund`
+- **请求方法**: `POST`
+- **请求参数**:
+  ```json
+  {
+    "id": "订单ID(逗号分隔)"
+  }
+  ```
+- **状态限制**: ❓ 退款按钮执行状态未确定
+
+### 4.3 导出订单
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/order/export`
+- **请求方法**: `GET`
+- **请求参数**:
+  ```json
+  {
+    "status": "订单状态",
+    "startTime": "开始时间",
+    "endTime": "结束时间"
+  }
+  ```
+- **注意事项**: ❓ 后端Excel表格字段是否符合产品要求未确定,目前只是能导出Excel表格
+
+### 4.4 导出发货单
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/order/export`
+- **请求方法**: `GET`
+- **请求参数**:
+  ```json
+  {
+    "status": 5,
+    "format": "delivery"
+  }
+  ```
+- **注意事项**: ❓ 后端Excel表格字段是否符合产品要求未确定,目前只是能导出Excel表格
+
+### 4.5 导入发货单
+
+- **功能状态**: ❌ **未实现**
+- **接口**: `shop/admin/order/order/dispatch`
+- **请求方法**: `POST`
+- **Content-Type**: `multipart/form-data`
+- **请求参数**:
+  ```json
+  {
+    "action": "multiple",
+    "express": {
+      "name": "快递公司名称",
+      "code": "快递公司代码"
+    },
+    "file": "Excel文件"
+  }
+  ```
+
+### 4.6 批量发货
+
+- **功能状态**: ❌ **未确认接入**
+- **接口**: `mall/order/batchDelivery`
+- **请求方法**: `POST`
+- **请求参数**:
+  ```json
+  {
+    "order_ids": ["订单ID数组"],
+    "action": "multiple"
+  }
+  ```
+
+---
+
+## 5. 发货处理流程
+
+### 5.1 单个订单发货
+
+- **功能状态**: ✅ 已实现
+- **接口**: `mall/order/batchDelivery`
+- **请求方法**: `POST`
+- **请求参数**:
+  ```json
+  {
+    "order_id": "订单ID",
+    "order_item_ids": ["订单项ID数组"],
+    "action": "confirm",
+    "express": {
+      "name": "快递公司名称",
+      "code": "快递公司代码",
+      "no": "快递单号"
+    }
+  }
+  ```
+- **功能说明**: 简单的单个订单发货功能,更新订单状态为已发货
+
+### 5.2 批量发货相关功能
+
+#### 导入发货单
+
+- **功能状态**: ❌ **未确定**
+- **接口**: `shop/admin/order/order/dispatch`
+- **说明**: 功能未确定实现状态
+
+#### 批量发货
+
+- **功能状态**: ❌ **未确定**
+- **接口**: `mall/order/batchDelivery`
+- **说明**: 功能未确定实现状态
+
+#### 下载失败发货单
+
+- **功能状态**: ❌ **未确定**
+- **说明**: 功能未确定实现状态
+
+---
+
+## 6. 功能实现状态总结
+
+### ✅ 已实现功能(90%)
+
+#### 商品管理
+
+- [x] 商品分类创建
+- [x] 商品创建(三步流程)
+- [x] 商品列表查询
+- [x] 批量上下架
+
+#### 拼团活动
+
+- [x] 拼团活动创建
+- [x] 活动商品设置
+- [x] 活动列表查询
+
+#### 订单管理
+
+- [x] 订单列表查询
+- [x] 订单详情查询
+- [x] 订单轨迹信息
+- [x] 基本信息展示
+- [x] 商品信息展示
+- [x] 收货信息展示
+- [x] 拼团信息查询
+
+#### 订单操作
+
+- [x] 取消订单
+- [x] 全部退款
+- [x] 导出订单
+- [x] 导出发货单
+
+#### 发货流程
+
+- [x] 循环处理订单
+- [x] 单个订单发货
+- [x] 发货结果统计
+- [x] 成功/失败状态更新
+
+### ❌ 未实现功能(10%)
+
+#### 关键缺失功能
+
+1. **导入发货单功能**
+   - 接口:`shop/admin/order/order/dispatch`
+   - 状态:未完整实现
+
+2. **批量发货接口对接**
+   - 接口:`mall/order/batchDelivery`
+   - 状态:未确认接入
+
+3. **失败Excel导出**
+   - 功能:发货失败后生成Excel文件并返回下载链接
+   - 状态:未实现
+
+4. **失败原因标注**
+   - 功能:在Excel中标注具体失败原因
+   - 状态:未实现
+
+### 🎯 关键需求确认
+
+#### 山哥的核心要求
+
+> 导入发货单时,有失败的订单会返回失败的Excel表格链接,并且标注失败原因
+
+#### 后端需要提供
+
+1. 失败Excel文件的生成机制
+2. 下载链接返回机制
+3. 失败原因的详细标注功能
+
+#### 前端需要实现
+
+1. 完善导入发货单功能
+2. 处理失败Excel下载链接
+3. 显示失败原因给用户
+
+---
+
+## 📊 开发优先级建议
+
+### 高优先级(必须实现)
+
+1. **导入发货单功能** - 核心业务功能
+2. **失败Excel导出** - 山哥明确要求
+3. **批量发货接口对接** - 确保功能完整性
+
+### 中优先级(建议实现)
+
+1. **失败原因标注优化** - 提升用户体验
+2. **发货流程异常处理** - 增强系统稳定性
+
+---
+
+_本文档基于当前代码分析生成,实际实现状态以最新代码为准。_

+ 40 - 26
src/app/shop/admin/goods/goods/edit.vue

@@ -52,7 +52,7 @@
                   />
                 </el-form-item>
 
-                <el-form-item label="商品品牌" prop="itemBrand" required>
+                <el-form-item label="商品品牌" prop="itemBrand">
                   <el-input v-model="formData.itemBrand" placeholder="请输入商品品牌" />
                 </el-form-item>
 
@@ -283,20 +283,30 @@
                   </div>
                 </el-form-item>
                 <div class="sa-flex sa-flex-wrap">
-                  <el-input
+                  <el-select
                     v-model="allEditObj.price"
-                    placeholder="请输入售价(৳)"
+                    placeholder="请选择售价(৳)"
                     class="sa-w-200 sa-m-r-10 sa-m-b-10"
+                    clearable
                   >
-                    <template #prepend>售价(৳)</template>
-                  </el-input>
-                  <el-input
+                    <el-option :value="300" label="300৳" />
+                    <el-option :value="500" label="500৳" />
+                    <el-option :value="1000" label="1000৳" />
+                    <el-option :value="2000" label="2000৳" />
+                    <el-option :value="3000" label="3000৳" />
+                  </el-select>
+                  <el-select
                     v-model="allEditObj.otPrice"
-                    placeholder="请输入市场价(৳)"
+                    placeholder="请选择市场价(৳)"
                     class="sa-w-200 sa-m-r-10 sa-m-b-10"
+                    clearable
                   >
-                    <template #prepend>市场价(৳)</template>
-                  </el-input>
+                    <el-option :value="300" label="300৳" />
+                    <el-option :value="500" label="500৳" />
+                    <el-option :value="1000" label="1000৳" />
+                    <el-option :value="2000" label="2000৳" />
+                    <el-option :value="3000" label="3000৳" />
+                  </el-select>
                   <el-input
                     v-model="allEditObj.stock"
                     placeholder="请输入库存(件)"
@@ -355,28 +365,32 @@
                         />
                       </td>
                       <td>
-                        <el-input
+                        <el-select
                           v-model="item.price"
-                          placeholder="请输入价格"
+                          placeholder="选择价格"
                           size="small"
-                          type="number"
-                          :step="0.01"
-                          :min="0"
-                          :precision="2"
                           :class="{ 'is-error': !item.price || item.price <= 0 }"
-                        ></el-input>
+                        >
+                          <el-option :value="300" label="300(৳)" />
+                          <el-option :value="500" label="500(৳)" />
+                          <el-option :value="1000" label="1000(৳)" />
+                          <el-option :value="2000" label="2000(৳)" />
+                          <el-option :value="3000" label="3000(৳)" />
+                        </el-select>
                       </td>
                       <td>
-                        <el-input
+                        <el-select
                           v-model="item.otPrice"
-                          placeholder="请输入市场价"
+                          placeholder="选择市场价"
                           size="small"
-                          type="number"
-                          :step="0.01"
-                          :min="0"
-                          :precision="2"
                           :class="{ 'is-error': !item.otPrice || item.otPrice <= 0 }"
-                        ></el-input>
+                        >
+                          <el-option :value="300" label="300(৳)" />
+                          <el-option :value="500" label="500(৳)" />
+                          <el-option :value="1000" label="1000(৳)" />
+                          <el-option :value="2000" label="2000(৳)" />
+                          <el-option :value="3000" label="3000(৳)" />
+                        </el-select>
                       </td>
                       <td class="stock">
                         <el-input
@@ -548,7 +562,7 @@
   const basicRules = {
     cateId: [{ required: true, message: '请选择商品分类', trigger: 'change' }],
     storeName: [{ required: true, message: '请输入商品名称', trigger: 'blur' }],
-    itemBrand: [{ required: true, message: '请输入商品品牌', trigger: 'blur' }],
+    // itemBrand: [{ required: true, message: '请输入商品品牌', trigger: 'blur' }],
     // tempId: [{ required: true, message: '请选择运费模板', trigger: 'change' }],
     // itemNumber: [{ required: true, message: '请输入商品货号', trigger: 'blur' }],
     // price: [{ required: true, message: '请输入商品售价', trigger: 'blur' }],
@@ -579,8 +593,8 @@
 
   // 批量操作相关变量
   const allEditObj = ref({
-    price: 0,
-    otPrice: 0,
+    price: null,
+    otPrice: null,
     stock: 0,
     stockThreshold: 0,
   });

+ 32 - 29
src/app/shop/admin/goods/goods/tab-edit.vue

@@ -104,27 +104,23 @@
               </el-form-item>
 
               <el-form-item label="商品售价" prop="price" required>
-                <el-input
-                  v-model="basicFormData.price"
-                  placeholder="请输入商品售价"
-                  type="number"
-                  min="0"
-                  step="0.01"
-                >
-                  <template #append>৳</template>
-                </el-input>
+                <el-select v-model="basicFormData.price" placeholder="请选择商品售价" clearable>
+                  <el-option :value="300" label="300৳" />
+                  <el-option :value="500" label="500৳" />
+                  <el-option :value="1000" label="1000৳" />
+                  <el-option :value="2000" label="2000৳" />
+                  <el-option :value="3000" label="3000৳" />
+                </el-select>
               </el-form-item>
 
               <el-form-item label="市场价" prop="otPrice">
-                <el-input
-                  v-model="basicFormData.otPrice"
-                  placeholder="请输入市场价"
-                  type="number"
-                  min="0"
-                  step="0.01"
-                >
-                  <template #append>৳</template>
-                </el-input>
+                <el-select v-model="basicFormData.otPrice" placeholder="请选择市场价" clearable>
+                  <el-option :value="300" label="300৳" />
+                  <el-option :value="500" label="500৳" />
+                  <el-option :value="1000" label="1000৳" />
+                  <el-option :value="2000" label="2000৳" />
+                  <el-option :value="3000" label="3000৳" />
+                </el-select>
               </el-form-item>
 
               <el-form-item label="商品库存" prop="stock" required>
@@ -302,13 +298,18 @@
                   </div>
                 </el-form-item>
                 <div class="sa-flex sa-flex-wrap">
-                  <el-input
+                  <el-select
                     v-model="allEditObj.price"
-                    placeholder="请输入售价(৳)"
+                    placeholder="请选择售价(৳)"
                     class="sa-w-200 sa-m-r-10 sa-m-b-10"
+                    clearable
                   >
-                    <template #prepend>售价(৳)</template>
-                  </el-input>
+                    <el-option :value="300" label="300৳" />
+                    <el-option :value="500" label="500৳" />
+                    <el-option :value="1000" label="1000৳" />
+                    <el-option :value="2000" label="2000৳" />
+                    <el-option :value="3000" label="3000৳" />
+                  </el-select>
                   <el-input
                     v-model="allEditObj.stock"
                     placeholder="请输入库存(件)"
@@ -366,16 +367,18 @@
                         />
                       </td>
                       <td>
-                        <el-input
+                        <el-select
                           v-model="item.price"
-                          placeholder="请输入价格"
+                          placeholder="选择价格"
                           size="small"
-                          type="number"
-                          :step="0.01"
-                          :min="0"
-                          :precision="2"
                           :class="{ 'is-error': !item.price || item.price <= 0 }"
-                        ></el-input>
+                        >
+                          <el-option :value="300" label="300" />
+                          <el-option :value="500" label="500" />
+                          <el-option :value="1000" label="1000" />
+                          <el-option :value="2000" label="2000" />
+                          <el-option :value="3000" label="3000" />
+                        </el-select>
                       </td>
                       <td class="stock">
                         <el-input

+ 29 - 9
src/sheep/request/index.js

@@ -2,7 +2,7 @@
 import axios from 'axios';
 import $store from '@/sheep/store';
 import $storage from '@/sheep/utils/storage';
-import { ElMessage, ElMessageBox } from 'element-plus';
+import { ElMessage } from 'element-plus';
 import { isNil } from 'lodash';
 import { baseURL } from '@/sheep/config';
 import { apiRouting } from '@/sheep/config/api-routing';
@@ -21,19 +21,39 @@ const options = {
 /**
  * @description 认证失败的错误码列表
  */
-const AUTH_FAILURE_CODES = ['401'];
+const AUTH_FAILURE_CODES = ['401', '7002'];
 
 /**
  * @description 处理认证失败的统一逻辑
  */
 const handleAuthFailure = (errorData) => {
-  const errorMessage = '未授权,请重新登录';
-  if (document.getElementsByClassName('el-message-box').length === 0) {
-    ElMessageBox.alert('认证失败,请重新登录', '认证失败', {
-      confirmButtonText: '重新登陆',
-    }).then(() => {
+  // 检查当前请求的接口是否为登录相关接口
+  const requestUrl = errorData?.config?.url || '';
+  console.log(requestUrl);
+  const isLoginAPI = requestUrl.includes('/login/login');
+
+  if (isLoginAPI) {
+    // 登录相关接口,不处理认证失败,让登录页面自己处理错误
+    ElMessage.error(errorData.data.message);
+    return Promise.reject(errorData.data);
+  } else {
+    try {
+      // 使用原生confirm弹窗
+      const userConfirmed = window.confirm('认证失败,登录状态已失效\n\n点击"确定"立即重新登录');
+
+      if (userConfirmed) {
+        console.log('用户确认认证失败,执行登出');
+        $store('account').logout(true);
+      } else {
+        console.log('用户取消认证失败处理,显示警告信息');
+        // 用户选择取消,显示警告但不强制登出
+        ElMessage.warning('认证已失效,部分功能可能无法正常使用,建议重新登录');
+      }
+    } catch (error) {
+      console.error('原生弹窗显示失败:', error);
+      // 如果连原生弹窗都失败,直接执行登出
       $store('account').logout(true);
-    });
+    }
   }
 };
 
@@ -88,7 +108,7 @@ request.interceptors.response.use(
     if (response.data.code !== '200') {
       // 处理认证失败
       if (AUTH_FAILURE_CODES.includes(response.data.code)) {
-        handleAuthFailure(response.data);
+        handleAuthFailure(response);
         return Promise.reject(response);
       }
       if (response.config.options.showErrorMessage)

+ 14 - 9
src/sheep/views/login/index.vue

@@ -156,14 +156,20 @@
     unref(formRef).validate(async (valid) => {
       if (!valid) return;
       loginLoading.value = true;
-      let submit = form.data;
-      const { code } = await accountStore.login(submit);
-      loginLoading.value = false;
-      if (code == '200') {
-        ElMessage.success('登录成功');
-        storage.set('lastLogin', login.last);
-        await appStore.appLoad();
-        router.push('/');
+      try {
+        let submit = form.data;
+        const { code } = await accountStore.login(submit);
+        if (code == '200') {
+          ElMessage.success('登录成功');
+          storage.set('lastLogin', login.last);
+          await appStore.appLoad();
+          router.push('/');
+        }
+      } catch (error) {
+        console.error('登录失败:', error);
+        // 错误信息通常由 store 或 request 拦截器处理,这里只记录日志
+      } finally {
+        loginLoading.value = false;
       }
     });
   };
@@ -226,7 +232,6 @@
 
   async function initLogin() {
     const { data } = adminApi.loginConfig();
-    console.log(data);
     login.config = data;
     login.config.background = login.config.background;
   }