Kaynağa Gözat

feat: 移除status=4状态,导入物流后订单状态直接更新为3(已发货)

变更内容:
- 后端: STATUS_MAP移除status=4,SQL CASE移除已发运分支
- 导入逻辑: UPDATE status=4 改为 status=3,移除status=4重复校验
- 统计接口: 移除imported字段,只保留pending/completed/cancelled/shipped
- 前端: 移除status=4筛选项、已发运统计卡、状态标签映射
- 登录页: 已发运统计改为已发货(stats.shipped)
- 文档: README同步更新
C 2 ay önce
ebeveyn
işleme
1d80569244

+ 4 - 4
README.md

@@ -10,7 +10,7 @@
 
 - **订单分散难管理**:大量订单散落在不同批次,缺乏统一的查询和筛选手段
 - **物流导入效率低**:传统手工逐条录入物流信息耗时易错,需要批量导入能力
-- **状态追踪不透明**:订单从"待处理"到"已发货/已发运"的状态流转缺乏可视化
+- **状态追踪不透明**:订单从"待处理"到"已发货"的状态流转缺乏可视化
 - **操作无审计**:多人协作时无法追溯谁在什么时候做了什么操作
 - **界面体验差**:传统后台系统界面老旧,操作效率低
 
@@ -26,10 +26,10 @@
 - 登录日志自动记录
 
 ### 2. 订单管理
-- **统计看板**:总订单数、待处理、已发运、已取消 四大 KPI 卡片
+- **统计看板**:总订单数、待处理、已发货、已取消 四大 KPI 卡片
 - **多维筛选**:按订单状态、下单日期、批次号、卡号、订单号组合查询
 - **数据表格**:批次号、订单号、物流公司、物流单号、订单状态等 17 个字段
-- **自定义状态标签**:待处理(橙)、已完成(绿)、已取消(红)、已发货(蓝)、已发运(青)
+- **自定义状态标签**:待处理(橙)、已完成(绿)、已取消(红)、已发货(蓝)
 - **Excel 导出**:按筛选条件导出订单列表,物流公司列带下拉验证
 - **分页浏览**:支持 20/50/100 条每页
 
@@ -40,7 +40,7 @@
   - 物流公司必须从下拉列表选择(中文名或代码)
   - 物流单号不能为空或占位符(`-`、`—`、`--`)
   - 订单必须存在于数据库
-  - 已发货(status=3)、已完成(status=1)、已发运(status=4)的订单禁止重复导入
+  - 已发货(status=3)、已完成(status=1)的订单禁止重复导入
 - **结果展示**:成功/失败/总计统计 + 失败详情列表
 - **模板下载**:提供标准导入模板(含物流公司下拉验证)
 

+ 4 - 15
server/routes/orders.js

@@ -95,7 +95,6 @@ const STATUS_MAP = {
   1: '已完成',
   2: '已取消',
   3: '已发货',
-  4: '已发运',
 };
 
 // 动态查询订单
@@ -127,7 +126,6 @@ router.post('/query', authMiddleware, async (req, res) => {
           WHEN 1 THEN '已完成'
           WHEN 2 THEN '已取消'
           WHEN 3 THEN '已发货'
-          WHEN 4 THEN '已发运'
         END AS "订单状态"
       FROM gift_order o
       JOIN gift_card c ON c.id = o.card_id AND c.del_flag = '0'
@@ -216,7 +214,6 @@ router.post('/export/excel', authMiddleware, async (req, res) => {
           WHEN 1 THEN '已完成'
           WHEN 2 THEN '已取消'
           WHEN 3 THEN '已发货'
-          WHEN 4 THEN '已发运'
         END AS "订单状态"
       FROM gift_order o
       JOIN gift_card c ON c.id = o.card_id AND c.del_flag = '0'
@@ -420,7 +417,7 @@ router.post('/import/logistics', authMiddleware, upload.single('file'), async (r
         const orderId = orderResult.rows[0].id;
         const orderStatus = orderResult.rows[0].status;
 
-        // 不允许重复发货/已完成/已发运
+        // 不允许重复发货/已完成
         if (orderStatus === 3) {
           await pool.query('ROLLBACK');
           results.failed++;
@@ -433,16 +430,10 @@ router.post('/import/logistics', authMiddleware, upload.single('file'), async (r
           results.errors.push(`第${i + 2}行: 订单 ${orderNo} 已完成,不能导入`);
           continue;
         }
-        if (orderStatus === 4) {
-          await pool.query('ROLLBACK');
-          results.failed++;
-          results.errors.push(`第${i + 2}行: 订单 ${orderNo} 已发运,不能重复导入`);
-          continue;
-        }
 
-        // 更新订单状态为已发运
+        // 更新订单状态为已发货
         await pool.query(
-          `UPDATE gift_order SET status = 4, update_time = now(), update_by = $1
+          `UPDATE gift_order SET status = 3, update_time = now(), update_by = $1
            WHERE id = $2 AND del_flag = '0'`,
           ['import', orderId]
         );
@@ -530,8 +521,7 @@ router.get('/stats', async (req, res) => {
         COUNT(*) FILTER (WHERE o.status = 0) AS pending,
         COUNT(*) FILTER (WHERE o.status = 1) AS completed,
         COUNT(*) FILTER (WHERE o.status = 2) AS cancelled,
-        COUNT(*) FILTER (WHERE o.status = 3) AS shipped,
-        COUNT(*) FILTER (WHERE o.status = 4) AS imported
+        COUNT(*) FILTER (WHERE o.status = 3) AS shipped
       FROM gift_order o
       WHERE o.del_flag = '0'
     `);
@@ -544,7 +534,6 @@ router.get('/stats', async (req, res) => {
         completed: parseInt(row.completed),
         cancelled: parseInt(row.cancelled),
         shipped: parseInt(row.shipped),
-        imported: parseInt(row.imported),
       }
     });
   } catch (err) {

+ 2 - 2
web/src/views/LoginPage.vue

@@ -30,8 +30,8 @@
           <div class="login-stat-label">待处理</div>
         </div>
         <div class="login-stat">
-          <div class="login-stat-value">{{ stats.imported || '—' }}</div>
-          <div class="login-stat-label">已发运</div>
+          <div class="login-stat-value">{{ stats.shipped || '—' }}</div>
+          <div class="login-stat-label">已发货</div>
         </div>
       </div>
     </div>

+ 2 - 2
web/src/views/LogisticsImport.vue

@@ -84,8 +84,8 @@
           <li>请先下载导入模板,按模板格式填写物流运单信息</li>
           <li>必填字段:订单号、物流公司、物流单号</li>
           <li>物流公司请从下拉列表中选择,物流单号不能为 "-" 等占位符</li>
-          <li>已发货、已完成、已发运的订单不能重复导入</li>
-          <li>导入后系统自动更新订单状态为「已发运」,可在订单管理中查看</li>
+          <li>已发货、已完成的订单不能重复导入</li>
+          <li>导入后系统自动更新订单状态为「已发货」,可在订单管理中查看</li>
         </ol>
       </div>
     </div>

+ 2 - 3
web/src/views/OrderManagement.vue

@@ -38,7 +38,6 @@
             <el-option label="已完成" :value="1" />
             <el-option label="已取消" :value="2" />
             <el-option label="已发货" :value="3" />
-            <el-option label="已发运" :value="4" />
           </el-select>
         </div>
         <div class="filter-field">
@@ -136,7 +135,7 @@ const pageSize = ref(20)
 const statCards = computed(() => [
   { label: '总订单数', value: props.stats?.total ?? '—', color: 'primary', icon: 'Box' },
   { label: '待处理', value: props.stats?.pending ?? '—', color: 'warning', icon: 'Clock' },
-  { label: '已发运', value: props.stats?.imported ?? '—', color: 'success', icon: 'CircleCheck' },
+  { label: '已发货', value: props.stats?.shipped ?? '—', color: 'success', icon: 'CircleCheck' },
   { label: '已取消', value: props.stats?.cancelled ?? '—', color: 'info', icon: 'CircleClose' },
 ])
 
@@ -156,7 +155,7 @@ function handleReset() {
 }
 
 function getStatusClass(status) {
-  const map = { '待处理': 'warning', '已完成': 'success', '已取消': 'danger', '已发货': 'info', '已发运': 'primary' }
+  const map = { '待处理': 'warning', '已完成': 'success', '已取消': 'danger', '已发货': 'info' }
   return map[status] || 'neutral'
 }