ソースを参照

feat: 订单状态「已导入」更名为「已发运」

变更范围:
- 后端 STATUS_MAP、SQL CASE 语句、导入校验提示语
- 前端筛选项、统计卡片、状态标签、登录页统计
- 物流导入说明文字
- README 文档描述
C 2 ヶ月 前
親
コミット
2b0317fec5

+ 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)、已发运(status=4)的订单禁止重复导入
 - **结果展示**:成功/失败/总计统计 + 失败详情列表
 - **模板下载**:提供标准导入模板(含物流公司下拉验证)
 

+ 6 - 6
server/routes/orders.js

@@ -95,7 +95,7 @@ const STATUS_MAP = {
   1: '已完成',
   2: '已取消',
   3: '已发货',
-  4: '已导入',
+  4: '已发运',
 };
 
 // 动态查询订单
@@ -127,7 +127,7 @@ router.post('/query', authMiddleware, async (req, res) => {
           WHEN 1 THEN '已完成'
           WHEN 2 THEN '已取消'
           WHEN 3 THEN '已发货'
-          WHEN 4 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 +216,7 @@ router.post('/export/excel', authMiddleware, async (req, res) => {
           WHEN 1 THEN '已完成'
           WHEN 2 THEN '已取消'
           WHEN 3 THEN '已发货'
-          WHEN 4 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 +420,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++;
@@ -436,11 +436,11 @@ router.post('/import/logistics', authMiddleware, upload.single('file'), async (r
         if (orderStatus === 4) {
           await pool.query('ROLLBACK');
           results.failed++;
-          results.errors.push(`第${i + 2}行: 订单 ${orderNo} 已导入,不能重复导入`);
+          results.errors.push(`第${i + 2}行: 订单 ${orderNo} 已发运,不能重复导入`);
           continue;
         }
 
-        // 更新订单状态为已导入
+        // 更新订单状态为已发运
         await pool.query(
           `UPDATE gift_order SET status = 4, update_time = now(), update_by = $1
            WHERE id = $2 AND del_flag = '0'`,

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

@@ -31,7 +31,7 @@
         </div>
         <div class="login-stat">
           <div class="login-stat-value">{{ stats.imported || '—' }}</div>
-          <div class="login-stat-label">已导入</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>

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

@@ -38,7 +38,7 @@
             <el-option label="已完成" :value="1" />
             <el-option label="已取消" :value="2" />
             <el-option label="已发货" :value="3" />
-            <el-option label="已导入" :value="4" />
+            <el-option label="已发运" :value="4" />
           </el-select>
         </div>
         <div class="filter-field">
@@ -136,7 +136,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?.imported ?? '—', color: 'success', icon: 'CircleCheck' },
   { label: '已取消', value: props.stats?.cancelled ?? '—', color: 'info', icon: 'CircleClose' },
 ])
 
@@ -156,7 +156,7 @@ function handleReset() {
 }
 
 function getStatusClass(status) {
-  const map = { '待处理': 'warning', '已完成': 'success', '已取消': 'danger', '已发货': 'info', '已导入': 'primary' }
+  const map = { '待处理': 'warning', '已完成': 'success', '已取消': 'danger', '已发货': 'info', '已发运': 'primary' }
   return map[status] || 'neutral'
 }