Просмотр исходного кода

feat(lakala): 优化订单搜索和快递信息管理功能

- 合并多个搜索输入框为统一搜索框,支持选择不同搜索类型
- 在订单列表中整合显示所有相关编号信息
- 增加快递公司编号显示及纠正功能
- 新增快递公司选择弹窗用于信息修正
- 添加获取快递公司列表的接口调用
- 实现更新快递公司信息的后端接口
- 支持通过微信交易号进行订单搜索
- 优化金额显示格式,增加人民币符号
- 更新路由配置以支持新的快递信息更新接口
- 引入LakalaWechatPaymentEntity实体类处理数据更新
- 创建DeliveryController提供快递公司列表接口
- 新建wechat模块的管理员路由文件
- 调整前端样式以适应新的订单编号展示方式
- 增加express_company字段到订单查询结果中
runphp 4 месяцев назад
Родитель
Сommit
5d4326a1d3

+ 161 - 36
resource/admin/TradeOrder.vue

@@ -3,29 +3,23 @@
     <!-- 搜索条件 -->
     <el-card class="search-card">
       <el-form :model="searchForm" label-width="140px" inline>
-        <el-form-item label="订单编号">
-          <el-input
-              v-model="searchForm.order_sn"
-              placeholder="请输入订单编号"
-              clearable
-              @keyup.enter="handleSearch"
-          />
-        </el-form-item>
-        <el-form-item label="商户支付订单号">
-          <el-input 
-            v-model="searchForm.out_trade_no" 
-            placeholder="请输入商户支付订单号" 
-            clearable
-            @keyup.enter="handleSearch"
-          />
-        </el-form-item>
-        <el-form-item label="拉卡拉交易号">
+        <el-form-item>
           <el-input 
-            v-model="searchForm.transaction_id" 
-            placeholder="请输入拉卡拉交易号" 
+            v-model="searchForm.keyword" 
+            placeholder="请输入订单编号/交易号等" 
             clearable
             @keyup.enter="handleSearch"
-          />
+            style="width: 400px;"
+          >
+            <template #prepend>
+              <el-select v-model="searchForm.searchType" placeholder="请选择" style="width: 130px;">
+                <el-option label="订单编号" value="order_sn"></el-option>
+                <el-option label="商户支付订单号" value="out_trade_no"></el-option>
+                <el-option label="拉卡拉交易号" value="transaction_id"></el-option>
+                <el-option label="微信交易号" value="wechat_transaction_id"></el-option>
+              </el-select>
+            </template>
+          </el-input>
         </el-form-item>
         <el-form-item>
           <el-button type="primary" @click="handleSearch">查询</el-button>
@@ -49,13 +43,31 @@
         stripe
       >
         <el-table-column prop="id" label="ID" width="80" />
-        <el-table-column prop="order_sn" label="订单编号" width="180" />
-        <el-table-column prop="out_trade_no" label="商户支付订单号" min-width="200" />
-        <el-table-column prop="transaction_id" label="拉卡拉交易号" min-width="250" />
-        <el-table-column prop="wechat_transaction_id" label="微信交易号" min-width="250" />
+        <el-table-column label="订单与交易编号" min-width="300">
+          <template #default="{ row }">
+            <div class="order-numbers">
+              <div class="number-item">
+                <span class="label">订单编号:</span>
+                <span class="value">{{ row.order_sn || '-' }}</span>
+              </div>
+              <div class="number-item">
+                <span class="label">商户支付订单号:</span>
+                <span class="value">{{ row.out_trade_no || '-' }}</span>
+              </div>
+              <div class="number-item">
+                <span class="label">拉卡拉交易号:</span>
+                <span class="value">{{ row.transaction_id || '-' }}</span>
+              </div>
+              <div class="number-item">
+                <span class="label">微信交易号:</span>
+                <span class="value">{{ row.wechat_transaction_id || '-' }}</span>
+              </div>
+            </div>
+          </template>
+        </el-table-column>
         <el-table-column prop="amount" label="支付金额(元)" width="120" align="right">
           <template #default="{ row }">
-            <span class="amount-highlight">{{ formatAmount(row.amount) }}</span>
+            <span class="amount-highlight">¥{{ formatAmount(row.amount) }}</span>
           </template>
         </el-table-column>
         <el-table-column prop="order_state_text" label="状态" width="100" />
@@ -64,6 +76,10 @@
             <div class="express-info">
               <div>快递公司:{{ row.express_name || '-' }}</div>
               <div>快递单号:{{ row.express_number || '-' }}</div>
+              <div>快递公司编号: {{ row.express_company || '-' }}</div>
+              <div v-if="!row.express_company && row.express_name" class="correct-button">
+                <el-button type="primary" size="small" @click="handleCorrectExpress(row)">纠正</el-button>
+              </div>
             </div>
           </template>
         </el-table-column>
@@ -90,6 +106,34 @@
         class="pagination"
       />
     </el-card>
+    
+    <!-- 快递公司选择弹窗 -->
+    <el-dialog
+      title="选择快递公司"
+      v-model="dialogVisible"
+      width="500px"
+    >
+      <el-select 
+        v-model="selectedExpress" 
+        placeholder="请选择快递公司" 
+        style="width: 100%"
+        filterable
+      >
+        <el-option
+          v-for="item in expressList"
+          :key="item.delivery_id"
+          :label="item.delivery_name"
+          :value="item.delivery_id"
+        />
+      </el-select>
+      
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="confirmCorrect">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -106,9 +150,8 @@ export default {
     return {
       loading: false,
       searchForm: {
-        out_trade_no: '',
-        order_sn: '',
-        transaction_id: ''
+        searchType: 'order_sn',
+        keyword: ''
       },
       statusOptions: [
         { label: '待支付', value: 0 },
@@ -126,7 +169,11 @@ export default {
         page: 1,
         limit: 10,
         total: 0
-      }
+      },
+      dialogVisible: false,
+      expressList: [], // 快递公司列表
+      currentRow: null, // 当前操作行
+      selectedExpress: '' // 选中的快递公司
     }
   },
   async created() {
@@ -157,10 +204,12 @@ export default {
       try {
         const params = {
           page: this.pagination.page,
-          limit: this.pagination.limit,
-          out_trade_no: this.searchForm.out_trade_no,
-          order_sn: this.searchForm.order_sn,
-          transaction_id: this.searchForm.transaction_id
+          limit: this.pagination.limit
+        }
+        
+        // 添加搜索参数
+        if (this.searchForm.keyword) {
+          params[this.searchForm.searchType] = this.searchForm.keyword
         }
         
         const res = await this.axiosInstance.get('/lakala/trade_order', { params })
@@ -188,9 +237,8 @@ export default {
     // 重置
     handleReset() {
       this.searchForm = {
-        out_trade_no: '',
-        order_sn: '',
-        transaction_id: ''
+        searchType: 'order_sn',
+        keyword: ''
       }
       this.pagination.page = 1
       this.fetchData()
@@ -206,6 +254,52 @@ export default {
     handleCurrentChange(val) {
       this.pagination.page = val
       this.fetchData()
+    },
+
+    // 纠正快递公司信息
+    async handleCorrectExpress(row) {
+      this.currentRow = row;
+      // 获取快递公司列表
+      try {
+        const res = await this.axiosInstance.get('/wechat/delivery');
+        if (res.code === 200) {
+          this.expressList = res.page.data;
+          this.dialogVisible = true;
+        } else {
+          this.$message.error(res.msg || '获取快递公司列表失败');
+        }
+      } catch (error) {
+        console.error('获取快递公司列表失败:', error);
+        this.$message.error('获取快递公司列表失败: ' + (error.message || '未知错误'));
+      }
+    },
+    
+    // 确认纠正快递公司
+    async confirmCorrect() {
+      if (!this.selectedExpress) {
+        this.$message.warning('请选择快递公司');
+        return;
+      }
+      
+      try {
+        const params = {
+          express_company: this.selectedExpress
+        };
+        
+        const res = await this.axiosInstance.put(`/lakala/trade_order/${this.currentRow.wechat_payment_id}/express_company`, params);
+        if (res.code === 200) {
+          this.$message.success('纠正成功');
+          this.dialogVisible = false;
+          this.selectedExpress = '';
+          // 重新获取数据
+          this.fetchData();
+        } else {
+          this.$message.error(res.msg || '纠正失败');
+        }
+      } catch (error) {
+        console.error('纠正快递公司失败:', error);
+        this.$message.error('纠正失败: ' + (error.message || '未知错误'));
+      }
     }
   }
 }
@@ -272,4 +366,35 @@ export default {
   overflow: hidden;
   text-overflow: ellipsis;
 }
+
+.correct-button {
+  margin-top: 8px;
+}
+
+.order-numbers {
+  font-size: 12px;
+}
+
+.number-item {
+  margin-bottom: 4px;
+  display: flex;
+}
+
+.number-item:last-child {
+  margin-bottom: 0;
+}
+
+.label {
+  font-weight: 500;
+  color: #606266;
+  min-width: 90px;
+  flex-shrink: 0;
+  text-align: right;
+}
+
+.value {
+  color: #303133;
+  word-break: break-all;
+  margin-left: 8px;
+}
 </style>

+ 3 - 1
route/admin.php

@@ -24,5 +24,7 @@ Route::resource('profit_share_receiver', ProfitShareReceiverController::class, f
 Route::resource('profit_share_order', ProfitShareOrderController::class)
     ->middleware(['auth', MacroPageMiddleware::class]);
 
-Route::resource('trade_order', TradeOrderController::class)
+Route::resource('trade_order', TradeOrderController::class, function (){
+    Route::put('express_company', [TradeOrderController::class, 'updateExpressCompany']);
+})
     ->middleware(['auth', MacroPageMiddleware::class]);

+ 13 - 1
src/Controller/Admin/TradeOrderController.php

@@ -3,19 +3,31 @@ declare(strict_types=1);
 namespace SixShop\Lakala\Controller\Admin;
 
 use SixShop\Core\Request;
+use SixShop\Lakala\Entity\LakalaWechatPaymentEntity;
 use SixShop\Lakala\Service\PaymentRecordService;
 use think\Response;
 use function SixShop\Core\page_response;
+use function SixShop\Core\success_response;
 
 class TradeOrderController
 {
     public function index(Request $request, PaymentRecordService $service): Response
     {
         $params = $request->get([
-            'out_trade_no/s' => '',
             'order_sn/s' => '',
+            'out_trade_no/s' => '',
             'transaction_id/s' => '',
+            'wechat_transaction_id/s' => '',
         ]);
         return page_response(page: $service->getTradeOrderList($params, $request->pageAndLimit()));
     }
+
+    public function updateExpressCompany(int $id, Request $request, LakalaWechatPaymentEntity $lakalaWechatPaymentEntity): Response
+    {
+        $expressCompany = $request->put('express_company/s');
+        return success_response($lakalaWechatPaymentEntity->update(
+            ['express_company' => $expressCompany],
+            ['id' => $id]
+        ));
+    }
 }

+ 13 - 0
src/Entity/LakalaWechatPaymentEntity.php

@@ -0,0 +1,13 @@
+<?php
+declare(strict_types=1);
+namespace SixShop\Lakala\Entity;
+
+use SixShop\Core\Entity\BaseEntity;
+
+/**
+ * @mixin \SixShop\Lakala\Model\LakalaWechatPaymentModel
+ */
+class LakalaWechatPaymentEntity extends BaseEntity
+{
+
+}

+ 6 - 0
src/Service/PaymentRecordService.php

@@ -39,6 +39,9 @@ class PaymentRecordService
             ->when($params['transaction_id'], function (Query $query) use ($params) {
                 $query->whereLike('p.transaction_id', '%' . $params['transaction_id'] . '%');
             })
+            ->when($params['wechat_transaction_id'], function (Query $query) use ($params) {
+                $query->whereLike('w.wechat_transaction_id', '%' . $params['wechat_transaction_id'] . '%');
+            })
             ->field([
                 'p.id',
                 'p.order_sn',
@@ -53,9 +56,12 @@ class PaymentRecordService
                 'o.city',
                 'o.district',
                 'o.address',
+                'w.id as wechat_payment_id',
                 'w.wechat_transaction_id',
                 'w.order_state',
                 'w.goods_desc',
+                'w.express_company',
+                'w.express_company_name'
             ])
             ->order('p.id', 'DESC')
             ->paginate($pageAndLimit);