From f5c900c58513bad824381e69750ac7667ef35de0 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期四, 26 二月 2026 22:29:46 +0800
Subject: [PATCH] feat: 修改增另任务单查询,使用单号查询

---
 ruoyi-ui/src/views/task/general/detail.vue |  697 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 663 insertions(+), 34 deletions(-)

diff --git a/ruoyi-ui/src/views/task/general/detail.vue b/ruoyi-ui/src/views/task/general/detail.vue
index 0450def..2c0ab51 100644
--- a/ruoyi-ui/src/views/task/general/detail.vue
+++ b/ruoyi-ui/src/views/task/general/detail.vue
@@ -8,7 +8,7 @@
       
       <!-- 鍩烘湰淇℃伅 -->
       <el-descriptions title="鍩烘湰淇℃伅" :column="2" border>
-        <el-descriptions-item label="浠诲姟缂栧彿">{{ taskDetail.taskCode }}</el-descriptions-item>
+        <el-descriptions-item label="浠诲姟缂栧彿">{{ taskDetail.showTaskCode }}</el-descriptions-item>
         <el-descriptions-item label="浠诲姟绫诲瀷">
           <dict-tag :options="dict.type.sys_task_type" :value="taskDetail.taskType"/>
         </el-descriptions-item>
@@ -33,11 +33,11 @@
       <!-- 鎬ユ晳杞繍浠诲姟鎵╁睍淇℃伅 -->
       <el-descriptions v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo" title="鎬ユ晳杞繍淇℃伅" :column="2" border style="margin-top: 20px;">
         <el-descriptions-item label="鑱旂郴浜�">
-          <span v-if="taskDetail.emergencyInfo.contactPerson">{{ taskDetail.emergencyInfo.contactPerson }}</span>
+          <span v-if="taskDetail.emergencyInfo.patientContact">{{ taskDetail.emergencyInfo.patientContact }}</span>
           <span v-else style="color: #C0C4CC;">--</span>
         </el-descriptions-item>
         <el-descriptions-item label="鑱旂郴鐢佃瘽">
-          <span v-if="taskDetail.emergencyInfo.contactPhone">{{ taskDetail.emergencyInfo.contactPhone }}</span>
+          <span v-if="taskDetail.emergencyInfo.patientPhone">{{ taskDetail.emergencyInfo.patientPhone }}</span>
           <span v-else style="color: #C0C4CC;">--</span>
         </el-descriptions-item>
         <el-descriptions-item label="鎮h�呭鍚�">
@@ -53,7 +53,7 @@
           <span v-else style="color: #C0C4CC;">--</span>
         </el-descriptions-item>
         <el-descriptions-item label="鐥呮儏鎻忚堪" :span="2">
-          <span v-if="taskDetail.emergencyInfo.illnessDescription">{{ taskDetail.emergencyInfo.illnessDescription }}</span>
+          <span v-if="taskDetail.emergencyInfo.patientCondition">{{ taskDetail.emergencyInfo.patientCondition }}</span>
           <span v-else style="color: #C0C4CC;">--</span>
         </el-descriptions-item>
       </el-descriptions>
@@ -74,10 +74,26 @@
             <i class="el-icon-error"></i> 鍚屾澶辫触
           </el-tag>
           <span v-else style="color: #C0C4CC;">--</span>
+          <!-- 鏈悓姝ユ垨鍚屾澶辫触鏃舵樉绀哄悓姝ユ寜閽� -->
+          <el-button
+            v-if="taskDetail.emergencyInfo.syncStatus === 0 || taskDetail.emergencyInfo.syncStatus === 3"
+            type="primary"
+            size="mini"
+            icon="el-icon-refresh"
+            :loading="syncingServiceOrder"
+            @click="syncServiceOrder"
+            style="margin-left: 10px;"
+          >鍚屾鏈嶅姟鍗�</el-button>
         </el-descriptions-item>
         <el-descriptions-item label="鏈嶅姟鍗曞彿">
           <span v-if="taskDetail.emergencyInfo.legacyServiceOrdId">
             <el-tag type="primary" size="small">{{ taskDetail.emergencyInfo.legacyServiceOrdId }}</el-tag>
+          </span>
+          <span v-else style="color: #C0C4CC;">--</span>
+        </el-descriptions-item>
+        <el-descriptions-item label="鏈嶅姟鍗曠紪鐮�">
+          <span v-if="taskDetail.emergencyInfo.serviceCode">
+            <el-tag type="success" size="small">{{ taskDetail.emergencyInfo.serviceCode }}</el-tag>
           </span>
           <span v-else style="color: #C0C4CC;">--</span>
         </el-descriptions-item>
@@ -103,10 +119,36 @@
             <i class="el-icon-error"></i> 鍚屾澶辫触
           </el-tag>
           <span v-else style="color: #C0C4CC;">--</span>
+          <!-- 鏈悓姝ユ垨鍚屾澶辫触鏃舵樉绀哄悓姝ユ寜閽� -->
+          <el-button
+            v-if="taskDetail.emergencyInfo.dispatchSyncStatus === 0 || taskDetail.emergencyInfo.dispatchSyncStatus === 3"
+            type="primary"
+            size="mini"
+            icon="el-icon-refresh"
+            :loading="syncingDispatchOrder"
+            @click="syncDispatchOrder"
+            style="margin-left: 10px;"
+          >鍚屾璋冨害鍗�</el-button>
+          <!-- 浠庢棫绯荤粺鍚屾鏁版嵁鍒版柊绯荤粺鎸夐挳 -->
+          <el-button
+            v-if="taskDetail.emergencyInfo.legacyServiceOrdId && taskDetail.emergencyInfo.legacyDispatchOrdId"
+            type="success"
+            size="mini"
+            icon="el-icon-download"
+            :loading="syncingFromLegacy"
+            @click="syncFromLegacySystem"
+            style="margin-left: 10px;"
+          >浠庢棫绯荤粺鍚屾</el-button>
         </el-descriptions-item>
         <el-descriptions-item label="璋冨害鍗曞彿">
           <span v-if="taskDetail.emergencyInfo.legacyDispatchOrdId">
             <el-tag type="primary" size="small">{{ taskDetail.emergencyInfo.legacyDispatchOrdId }}</el-tag>
+          </span>
+          <span v-else style="color: #C0C4CC;">--</span>
+        </el-descriptions-item>
+        <el-descriptions-item label="璋冨害鍗曠紪鐮�">
+          <span v-if="taskDetail.emergencyInfo.dispatchCode">
+            <el-tag type="success" size="small">{{ taskDetail.emergencyInfo.dispatchCode }}</el-tag>
           </span>
           <span v-else style="color: #C0C4CC;">--</span>
         </el-descriptions-item>
@@ -118,7 +160,197 @@
           <span v-if="taskDetail.emergencyInfo.dispatchSyncErrorMsg" style="color: #F56C6C;">{{ taskDetail.emergencyInfo.dispatchSyncErrorMsg }}</span>
           <span v-else style="color: #C0C4CC;">--</span>
         </el-descriptions-item>
+        <el-descriptions-item label="浠诲姟鐘舵�佸悓姝�" :span="2">
+          <el-alert
+            title="鎻愮ず锛氫换鍔$姸鎬佷細鑷姩鍚屾鍒版棫绯荤粺鐨勮皟搴﹀崟涓紝濡傛灉鍥犵綉缁滅瓑鍘熷洜鏈悓姝ワ紝鍙偣鍑讳笅鏂规寜閽墜鍔ㄥ悓姝ャ��"
+            type="info"
+            :closable="false"
+            show-icon
+            style="margin-bottom: 10px;">
+          </el-alert>
+          <el-button
+            v-if="taskDetail.emergencyInfo.legacyDispatchOrdId && taskDetail.emergencyInfo.legacyDispatchOrdId > 0"
+            type="warning"
+            size="small"
+            icon="el-icon-refresh"
+            :loading="syncingTaskStatus"
+            @click="syncTaskStatus"
+          >鍚屾浠诲姟鐘舵�佸埌鏃х郴缁�</el-button>
+          <el-tag v-else type="info" size="small">
+            <i class="el-icon-warning"></i> 璇峰厛鍚屾璋冨害鍗�
+          </el-tag>
+        </el-descriptions-item>
       </el-descriptions>
+
+      <!-- 鏀粯淇℃伅锛堜粎鎬ユ晳杞繍浠诲姟鏄剧ず锛� -->
+      <el-card v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && paymentInfo" class="box-card" style="margin-top: 20px;">
+        <div slot="header" class="clearfix">
+          <span>鏀粯淇℃伅</span>
+          <!-- 宸插畬鎴愪笖鏈敵璇峰彂绁ㄦ椂鏄剧ず鐢宠鍙戠エ鎸夐挳 -->
+          <el-button 
+            v-if="canApplyInvoice" 
+            style="float: right; padding: 3px 0" 
+            type="text" 
+            @click="handleApplyInvoice"
+            v-hasPermi="['system:invoice:add']"
+          >
+            <i class="el-icon-document-add"></i> 鐢宠鍙戠エ
+          </el-button>
+        </div>
+        
+        <!-- 鏀粯姒傝 -->
+        <el-descriptions :column="3" border>
+          <el-descriptions-item label="鍩烘湰浠锋牸">
+            <span style="color: #409EFF; font-weight: bold;">楼{{ paymentInfo.transferPrice || '0.00' }}</span>
+          </el-descriptions-item>
+          <el-descriptions-item label="闄勫姞璐圭敤鎬婚">
+            <span style="color: #E6A23C; font-weight: bold;">楼{{ paymentInfo.additionalAmount || '0.00' }}</span>
+          </el-descriptions-item>
+          <el-descriptions-item label="鎬婚噾棰�">
+            <span style="color: #67C23A; font-weight: bold;">楼{{ paymentInfo.totalAmount || '0.00' }}</span>
+          </el-descriptions-item>
+          <el-descriptions-item label="宸叉敮浠橀噾棰�">
+            <span style="color: #67C23A; font-weight: bold;">楼{{ paymentInfo.paidAmount || '0.00' }}</span>
+          </el-descriptions-item>
+          <el-descriptions-item label="鍓╀綑鏈粯閲戦">
+            <span style="color: #F56C6C; font-weight: bold;">楼{{ getRemainingAmount() }}</span>
+          </el-descriptions-item>
+          <el-descriptions-item label="鏀粯鐘舵��">
+            <el-tag v-if="getRemainingAmount() <= 0" type="success" size="small">
+              <i class="el-icon-success"></i> 宸茬粨娓�
+            </el-tag>
+            <el-tag v-else-if="paymentInfo.paidAmount > 0" type="warning" size="small">
+              <i class="el-icon-warning"></i> 閮ㄥ垎鏀粯
+            </el-tag>
+            <el-tag v-else type="info" size="small">
+              <i class="el-icon-warning"></i> 鏈敮浠�
+            </el-tag>
+          </el-descriptions-item>
+        </el-descriptions>
+
+        <!-- 闄勫姞璐圭敤鏄庣粏 -->
+        <div style="margin-top: 20px;">
+          <h4 style="margin-bottom: 10px;">闄勫姞璐圭敤鏄庣粏</h4>
+          <el-table :data="paymentInfo.additionalFees" border>
+            <el-table-column label="璐圭敤绫诲瀷" align="center" prop="feeType" width="120">
+              <template slot-scope="scope">
+                <dict-tag :options="dict.type.task_additional_fee_type" :value="scope.row.feeType"/>
+              </template>
+            </el-table-column>
+            <el-table-column label="璐圭敤鍚嶇О" align="center" prop="feeName" />
+            <el-table-column label="鍗曚环" align="center" prop="unitAmount" width="120">
+              <template slot-scope="scope">
+                <span>楼{{ scope.row.unitAmount }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="鏁伴噺" align="center" prop="quantity" width="80" />
+            <el-table-column label="灏忚" align="center" prop="totalAmount" width="120">
+              <template slot-scope="scope">
+                <span style="color: #E6A23C; font-weight: bold;">楼{{ scope.row.totalAmount }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="鍚屾鐘舵��" align="center" width="120">
+              <template slot-scope="scope">
+                <el-tag v-if="scope.row.syncStatus === 0" type="info" size="small">
+                  <i class="el-icon-warning"></i> 鏈悓姝�
+                </el-tag>
+                <el-tag v-else-if="scope.row.syncStatus === 1" type="warning" size="small">
+                  <i class="el-icon-loading"></i> 鍚屾涓�
+                </el-tag>
+                <el-tag v-else-if="scope.row.syncStatus === 2" type="success" size="small">
+                  <i class="el-icon-success"></i> 鍚屾鎴愬姛
+                </el-tag>
+                <el-tag v-else-if="scope.row.syncStatus === 3" type="danger" size="small">
+                  <i class="el-icon-error"></i> 鍚屾澶辫触
+                </el-tag>
+                <span v-else style="color: #C0C4CC;">--</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="澶囨敞" align="center" prop="remark" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span v-if="scope.row.remark">{{ scope.row.remark }}</span>
+                <span v-else style="color: #C0C4CC;">--</span>
+              </template>
+            </el-table-column>
+          </el-table>
+          
+          <!-- 绌虹姸鎬佹彁绀� -->
+          <div v-if="!paymentInfo.additionalFees || paymentInfo.additionalFees.length === 0" style="text-align: center; padding: 40px 0; color: #909399;">
+            <i class="el-icon-document" style="font-size: 48px; display: block; margin-bottom: 12px;"></i>
+            <span>鏆傛棤闄勫姞璐圭敤</span>
+          </div>
+        </div>
+
+        <!-- 宸叉敮浠樿褰� -->
+        <div style="margin-top: 20px;">
+          <h4 style="margin-bottom: 10px;">宸叉敮浠樿褰�</h4>
+          <el-table :data="paymentInfo.paidPayments" border>
+            <el-table-column label="鍟嗘埛璁㈠崟鍙�" align="center" prop="outTradeNo" width="200" show-overflow-tooltip />
+            <el-table-column label="鏀粯閲戦" align="center" prop="settlementAmount" width="120">
+              <template slot-scope="scope">
+                <span style="color: #67C23A; font-weight: bold;">楼{{ scope.row.settlementAmount }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="鏀粯鏂瑰紡" align="center" prop="paymentMethod" width="120">
+              <template slot-scope="scope">
+                <dict-tag :options="dict.type.task_payment_method" :value="scope.row.paymentMethod"/>
+              </template>
+            </el-table-column>
+            <el-table-column label="鏀粯鐘舵��" align="center" prop="payStatus" width="120">
+              <template slot-scope="scope">
+                <el-tag v-if="scope.row.payStatus === 'PAID'" type="success" size="small">
+                  <i class="el-icon-success"></i> 宸叉敮浠�
+                </el-tag>
+                <el-tag v-else-if="scope.row.payStatus === 'PENDING'" type="warning" size="small">
+                  <i class="el-icon-time"></i> 寰呮敮浠�
+                </el-tag>
+                <el-tag v-else-if="scope.row.payStatus === 'FAILED'" type="danger" size="small">
+                  <i class="el-icon-error"></i> 澶辫触
+                </el-tag>
+                <el-tag v-else type="info" size="small">
+                  {{ scope.row.payStatus }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column label="浜ゆ槗鍙�" align="center" prop="tradeNo" width="150" show-overflow-tooltip />
+            <el-table-column label="鏀粯鏃堕棿" align="center" prop="payTime" width="180">
+              <template slot-scope="scope">
+                <span v-if="scope.row.payTime">{{ parseTime(scope.row.payTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+                <span v-else style="color: #C0C4CC;">--</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="鍚屾鐘舵��" align="center" width="120">
+              <template slot-scope="scope">
+                <el-tag v-if="scope.row.syncStatus === 0" type="info" size="small">
+                  <i class="el-icon-warning"></i> 鏈悓姝�
+                </el-tag>
+                <el-tag v-else-if="scope.row.syncStatus === 1" type="warning" size="small">
+                  <i class="el-icon-loading"></i> 鍚屾涓�
+                </el-tag>
+                <el-tag v-else-if="scope.row.syncStatus === 2" type="success" size="small">
+                  <i class="el-icon-success"></i> 鍚屾鎴愬姛
+                </el-tag>
+                <el-tag v-else-if="scope.row.syncStatus === 3" type="danger" size="small">
+                  <i class="el-icon-error"></i> 鍚屾澶辫触
+                </el-tag>
+                <span v-else style="color: #C0C4CC;">--</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="澶囨敞" align="center" prop="remark" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span v-if="scope.row.remark">{{ scope.row.remark }}</span>
+                <span v-else style="color: #C0C4CC;">--</span>
+              </template>
+            </el-table-column>
+          </el-table>
+          
+          <!-- 绌虹姸鎬佹彁绀� -->
+          <div v-if="!paymentInfo.paidPayments || paymentInfo.paidPayments.length === 0" style="text-align: center; padding: 40px 0; color: #909399;">
+            <i class="el-icon-document" style="font-size: 48px; display: block; margin-bottom: 12px;"></i>
+            <span>鏆傛棤鏀粯璁板綍</span>
+          </div>
+        </div>
+      </el-card>
 
       <!-- 绂忕杞︿换鍔℃墿灞曚俊鎭� -->
       <el-descriptions v-if="taskDetail.taskType === 'WELFARE' && taskDetail.welfareInfo" title="绂忕杞︽湇鍔′俊鎭�" :column="2" border style="margin-top: 20px;">
@@ -146,11 +378,53 @@
       </el-descriptions>
 
       <!-- 鎿嶄綔鎸夐挳 -->
-      <div style="margin-top: 20px; text-align: center;">
+      <!-- <div style="margin-top: 20px; text-align: center;">
         <el-button type="primary" @click="handleEdit" v-hasPermi="['task:general:edit']">缂栬緫浠诲姟</el-button>
         <el-button type="success" @click="handleAssign" v-hasPermi="['task:general:assign']">鍒嗛厤浠诲姟</el-button>
         <el-button type="warning" @click="handleStatusChange" v-hasPermi="['task:general:status']">鐘舵�佸彉鏇�</el-button>
         <el-button type="info" @click="handleVehicleAssign" v-hasPermi="['task:general:assign']">鍒嗛厤杞﹁締</el-button>
+      </div> -->
+    </el-card>
+    
+    <!-- 鎵ц浜哄憳鍒楄〃 -->
+    <el-card class="box-card" style="margin-top: 20px;">
+      <div slot="header" class="clearfix">
+        <span>鎵ц浜哄憳</span>
+      </div>
+        
+      <el-table :data="taskDetail.assignees" v-loading="assigneeLoading">
+        <el-table-column label="搴忓彿" align="center" width="60">
+          <template slot-scope="scope">
+            <span>{{ scope.$index + 1 }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="濮撳悕" align="center" prop="userName">
+          <template slot-scope="scope">
+            <span>{{ scope.row.userName }}</span>
+            <el-tag v-if="scope.row.isPrimary === '1'" type="warning" size="mini" style="margin-left: 8px;">
+              <i class="el-icon-star-on"></i> 璐熻矗浜�
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="瑙掕壊绫诲瀷" align="center" prop="userType" width="120">
+          <template slot-scope="scope">
+            <el-tag v-if="scope.row.userType === 'driver'" type="primary" size="small">鍙告満</el-tag>
+            <el-tag v-else-if="scope.row.userType === 'doctor'" type="success" size="small">鍖荤敓</el-tag>
+            <el-tag v-else-if="scope.row.userType === 'nurse'" type="info" size="small">鎶ゅ+</el-tag>
+            <el-tag v-else type="" size="small">{{ scope.row.userType }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
+        
+      <!-- 绌虹姸鎬佹彁绀� -->
+      <div v-if="!taskDetail.assignees || taskDetail.assignees.length === 0" style="text-align: center; padding: 40px 0; color: #909399;">
+        <i class="el-icon-user" style="font-size: 48px; display: block; margin-bottom: 12px;"></i>
+        <span>鏆傛棤鎵ц浜哄憳</span>
       </div>
     </el-card>
 
@@ -203,11 +477,38 @@
       </div>
       
       <el-table :data="taskDetail.attachments" v-loading="attachmentLoading">
-        <el-table-column label="鏂囦欢鍚�" align="center" prop="fileName" />
-        <el-table-column label="鏂囦欢绫诲瀷" align="center" prop="fileType" />
-        <el-table-column label="鏂囦欢澶у皬" align="center" prop="fileSize">
+        <el-table-column label="缂╃暐鍥�" align="center" width="120">
           <template slot-scope="scope">
-            <span>{{ formatFileSize(scope.row.fileSize) }}</span>
+            <el-image
+              v-if="isImage(scope.row.fileType)"
+              :src="scope.row.fileUrl"
+              :preview-src-list="[scope.row.fileUrl]"
+              fit="cover"
+              style="width: 80px; height: 80px; border-radius: 4px; cursor: pointer;"
+            >
+              <div slot="error" class="image-slot">
+                <i class="el-icon-picture-outline" style="font-size: 40px; color: #C0C4CC;"></i>
+              </div>
+            </el-image>
+            <div v-else style="text-align: center;">
+              <i class="el-icon-document" style="font-size: 40px; color: #909399;"></i>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="涓氬姟鍒嗙被" align="center" prop="attachmentCategory" width="150">
+          <template slot-scope="scope">
+            <dict-tag :options="dict.type.sys_attachment_category" :value="scope.row.attachmentCategory"/>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍚屾鐘舵��" align="center" width="120">
+          <template slot-scope="scope">
+            <el-tag v-if="scope.row.syncedToImageData === 0" type="info" size="small">
+              <i class="el-icon-warning"></i> 鏈悓姝�
+            </el-tag>
+            <el-tag v-else-if="scope.row.syncedToImageData === 1" type="success" size="small">
+              <i class="el-icon-success"></i> 宸插悓姝�
+            </el-tag>
+            <span v-else style="color: #C0C4CC;">--</span>
           </template>
         </el-table-column>
         <el-table-column label="涓婁紶鏃堕棿" align="center" prop="uploadTime" width="180">
@@ -234,6 +535,74 @@
           </template>
         </el-table-column>
       </el-table>
+    </el-card>
+
+    <!-- 闄勫姞璐圭敤鍒楄〃 -->
+    <el-card class="box-card" style="margin-top: 20px;">
+      <div slot="header" class="clearfix">
+        <span>闄勫姞璐圭敤鍒楄〃</span>
+      </div>
+      
+      <el-table :data="additionalFeeList" v-loading="feeLoading">
+        <el-table-column label="璐圭敤绫诲瀷" align="center" prop="feeType" width="120">
+          <template slot-scope="scope">
+            <dict-tag :options="dict.type.task_additional_fee_type" :value="scope.row.feeType"/>
+          </template>
+        </el-table-column>
+        <el-table-column label="璐圭敤鍚嶇О" align="center" prop="feeName" />
+        <el-table-column label="鍗曚环" align="center" prop="unitAmount" width="120">
+          <template slot-scope="scope">
+            <span>楼{{ scope.row.unitAmount }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鏁伴噺" align="center" prop="quantity" width="80" />
+        <el-table-column label="鎬婚噾棰�" align="center" prop="totalAmount" width="120">
+          <template slot-scope="scope">
+            <span style="color: #E6A23C; font-weight: bold;">楼{{ scope.row.totalAmount }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍚屾鐘舵��" align="center" width="120">
+          <template slot-scope="scope">
+            <el-tag v-if="scope.row.syncStatus === 0" type="info" size="small">
+              <i class="el-icon-warning"></i> 鏈悓姝�
+            </el-tag>
+            <el-tag v-else-if="scope.row.syncStatus === 1" type="warning" size="small">
+              <i class="el-icon-loading"></i> 鍚屾涓�
+            </el-tag>
+            <el-tag v-else-if="scope.row.syncStatus === 2" type="success" size="small">
+              <i class="el-icon-success"></i> 鍚屾鎴愬姛
+            </el-tag>
+            <el-tag v-else-if="scope.row.syncStatus === 3" type="danger" size="small">
+              <i class="el-icon-error"></i> 鍚屾澶辫触
+            </el-tag>
+            <span v-else style="color: #C0C4CC;">--</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍚屾鏃堕棿" align="center" prop="syncTime" width="180">
+          <template slot-scope="scope">
+            <span v-if="scope.row.syncTime">{{ parseTime(scope.row.syncTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+            <span v-else style="color: #C0C4CC;">--</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createdTime" width="180">
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.createdTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍒涘缓鑰�" align="center" prop="createdBy" width="100" />
+        <el-table-column label="澶囨敞" align="center" prop="remark" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span v-if="scope.row.remark">{{ scope.row.remark }}</span>
+            <span v-else style="color: #C0C4CC;">--</span>
+          </template>
+        </el-table-column>
+      </el-table>
+      
+      <!-- 绌虹姸鎬佹彁绀� -->
+      <div v-if="!additionalFeeList || additionalFeeList.length === 0" style="text-align: center; padding: 40px 0; color: #909399;">
+        <i class="el-icon-document" style="font-size: 48px; display: block; margin-bottom: 12px;"></i>
+        <span>鏆傛棤闄勫姞璐圭敤</span>
+      </div>
     </el-card>
 
     <!-- 鎿嶄綔鏃ュ織 -->
@@ -388,33 +757,54 @@
     </el-dialog>
 
     <!-- 涓婁紶闄勪欢瀵硅瘽妗� -->
-    <el-dialog title="涓婁紶闄勪欢" :visible.sync="uploadOpen" width="500px" append-to-body>
-      <el-upload
-        class="upload-demo"
-        drag
-        :action="uploadUrl"
-        :headers="uploadHeaders"
-        :data="uploadData"
-        :on-success="handleUploadSuccess"
-        :on-error="handleUploadError"
-        :before-upload="beforeUpload"
-        multiple>
-        <i class="el-icon-upload"></i>
-        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
-        <div class="el-upload__tip" slot="tip">鍙兘涓婁紶jpg/png/pdf/doc/docx鏂囦欢锛屼笖涓嶈秴杩�10MB</div>
-      </el-upload>
+    <el-dialog title="涓婁紶闄勪欢" :visible.sync="uploadOpen" width="500px" append-to-body @close="cancelUpload">
+      <el-form ref="uploadForm" :model="uploadForm" :rules="uploadRules" label-width="100px">
+        <el-form-item label="涓氬姟鍒嗙被" prop="category">
+          <el-select v-model="uploadForm.category" placeholder="璇烽�夋嫨涓氬姟鍒嗙被" clearable style="width: 100%;">
+            <el-option
+              v-for="dict in dict.type.sys_attachment_category"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="闄勪欢" prop="files">
+          <el-upload
+            ref="upload"
+            class="upload-demo"
+            :action="uploadUrl"
+            :headers="uploadHeaders"
+            :data="uploadData"
+            :on-success="handleUploadSuccess"
+            :on-error="handleUploadError"
+            :before-upload="beforeUpload"
+            :file-list="fileList"
+            :auto-upload="false"
+            multiple
+            drag>
+            <i class="el-icon-upload"></i>
+            <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+            <div class="el-upload__tip" slot="tip">鍙兘涓婁紶jpg/png/pdf/doc/docx鏂囦欢锛屼笖涓嶈秴杩�100MB</div>
+          </el-upload>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitUpload">纭� 瀹�</el-button>
+        <el-button @click="cancelUpload">鍙� 娑�</el-button>
+      </div>
     </el-dialog>
   </div>
 </template>
 
 <script>
-import { getTask, updateTask, assignTask, changeTaskStatus, uploadAttachment, deleteAttachment, getTaskVehicles, getAvailableVehicles, assignVehiclesToTask, unassignVehicleFromTask } from "@/api/task";
+import { getTask, updateTask, assignTask, changeTaskStatus, uploadAttachment, deleteAttachment, getTaskVehicles, getAvailableVehicles, assignVehiclesToTask, unassignVehicleFromTask, getPaymentInfo, syncServiceOrder, syncDispatchOrder, syncTaskStatus, syncFromLegacySystem, checkTaskInvoice } from "@/api/task";
 import { listUser } from "@/api/system/user";
 import { getToken } from "@/utils/auth";
 
 export default {
   name: "TaskDetail",
-  dicts: ['sys_task_type', 'sys_task_status', 'sys_vehicle_type', 'sys_task_vehicle_status', 'sys_user_sex', 'hospital_department'],
+  dicts: ['sys_task_type', 'sys_task_status', 'sys_vehicle_type', 'sys_task_vehicle_status', 'sys_user_sex', 'hospital_department', 'sys_attachment_category', 'task_additional_fee_type', 'task_payment_method'],
   data() {
     return {
       // 浠诲姟璇︽儏
@@ -433,6 +823,12 @@
       vehicleAssignOpen: false,
       // 鏄惁鏄剧ず涓婁紶瀵硅瘽妗�
       uploadOpen: false,
+      // 涓婁紶琛ㄥ崟
+      uploadForm: {
+        category: null
+      },
+      // 鏂囦欢鍒楄〃
+      fileList: [],
       // 缂栬緫琛ㄥ崟
       editForm: {},
       // 鍒嗛厤琛ㄥ崟
@@ -448,8 +844,14 @@
       // 鍔犺浇鐘舵��
       vehicleLoading: false,
       attachmentLoading: false,
+      feeLoading: false,
+      assigneeLoading: false,
+      // 闄勫姞璐圭敤鍒楄〃
+      additionalFeeList: [],
+      // 鏀粯淇℃伅
+      paymentInfo: null,
       // 涓婁紶鐩稿叧
-      uploadUrl: process.env.VUE_APP_BASE_API + "/task/attachment/upload/" + this.$route.params.taskId,
+      uploadUrl: process.env.VUE_APP_BASE_API + "/task/attachment/upload/" + (new URLSearchParams(window.location.search).get('taskId') || ''),
       uploadHeaders: {
         Authorization: "Bearer " + getToken()
       },
@@ -480,19 +882,81 @@
         vehicleIds: [
           { required: true, message: "杞﹁締涓嶈兘涓虹┖", trigger: "change" }
         ]
-      }
+      },
+      uploadRules: {
+        category: [
+          { required: true, message: "涓氬姟鍒嗙被涓嶈兘涓虹┖", trigger: "change" }
+        ]
+      },
+      // 鍚屾鍔犺浇鐘舵��
+      syncingServiceOrder: false,
+      syncingDispatchOrder: false,
+      syncingFromLegacy: false,
+      syncingTaskStatus: false,
+      // 鍙戠エ鐢宠鐘舵��
+      hasInvoiceApplied: false,
+      invoiceStatus: null // 0-寰呭鏍�, 1-宸查�氳繃, 2-宸查┏鍥�
     };
   },
   created() {
     this.getTaskDetail();
     this.getUserList();
+    this.getAdditionalFeeList();
+    // 鍒濆鍖栦笂浼燯RL
+    this.uploadUrl = process.env.VUE_APP_BASE_API + "/task/attachment/upload/" + this.$route.params.taskId;
+    // 妫�鏌ュ彂绁ㄧ敵璇风姸鎬�
+    this.checkInvoiceStatus();
+  },
+  computed: {
+    /** 鏄惁鍙互鐢宠鍙戠エ */
+    canApplyInvoice() {
+      // 鍙湁鎬ユ晳杞繍浠诲姟
+      if (this.taskDetail.taskType !== 'EMERGENCY_TRANSFER') return false;
+      // 浠诲姟蹇呴』宸插畬鎴�
+      if (this.taskDetail.taskStatus !== 'COMPLETED') return false;
+      // 鏈敵璇疯繃鍙戠エ锛屾垨鑰呮浘琚┏鍥�
+      return !this.hasInvoiceApplied || this.invoiceStatus === 2;
+    }
   },
   methods: {
     /** 鑾峰彇浠诲姟璇︽儏 */
     getTaskDetail() {
       getTask(this.$route.params.taskId).then(response => {
         this.taskDetail = response.data;
+        // 浠诲姟璇︽儏鍔犺浇瀹屾垚鍚庯紝鍔犺浇鏀粯淇℃伅
+        // console.log("TaskDetail", this.taskDetail);
+        this.loadPaymentInfo();
       });
+    },
+    /** 鑾峰彇闄勫姞璐圭敤鍒楄〃 */
+    getAdditionalFeeList() {
+      this.feeLoading = true;
+      getPaymentInfo(this.$route.params.taskId).then(response => {
+        this.additionalFeeList = response.data.additionalFees || [];
+        this.feeLoading = false;
+      }).catch(() => {
+        this.feeLoading = false;
+      });
+    },
+    /** 鍔犺浇鏀粯淇℃伅 */
+    loadPaymentInfo() {
+      //EMERGENCY_TRANSFER
+      if (this.taskDetail.taskType === 'EMERGENCY_TRANSFER') {
+        getPaymentInfo(this.$route.params.taskId).then(response => {
+          // console.log("PaymentInfo", response.data);
+          this.paymentInfo = response.data;
+        }).catch(() => {
+          this.paymentInfo = null;
+        });
+      }
+    },
+    /** 璁$畻鍓╀綑鏈粯閲戦 */
+    getRemainingAmount() {
+      if (!this.paymentInfo) return '0.00';
+      const total = parseFloat(this.paymentInfo.totalAmount || 0);
+      const paid = parseFloat(this.paymentInfo.paidAmount || 0);
+      const remaining = total - paid;
+      return remaining > 0 ? remaining.toFixed(2) : '0.00';
     },
     /** 鑾峰彇鐢ㄦ埛鍒楄〃 */
     getUserList() {
@@ -554,6 +1018,10 @@
     },
     /** 涓婁紶闄勪欢 */
     handleUpload() {
+      this.uploadForm = {
+        category: null
+      };
+      this.fileList = [];
       this.uploadOpen = true;
     },
     /** 鍙栨秷杞﹁締鍒嗛厤 */
@@ -648,22 +1116,67 @@
     },
     /** 涓婁紶鍓嶆鏌� */
     beforeUpload(file) {
+      // 妫�鏌ユ槸鍚﹂�夋嫨浜嗕笟鍔″垎绫�
+      if (!this.uploadForm.category) {
+        this.$message.error('璇峰厛閫夋嫨涓氬姟鍒嗙被!');
+        return false;
+      }
+      
+      // 鏇存柊uploadData锛岀‘淇濇瘡娆′笂浼犻兘甯︽湁category鍙傛暟
+      this.uploadData = {
+        category: this.uploadForm.category
+      };
+      
       const isValidType = ['image/jpeg', 'image/png', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'].includes(file.type);
-      const isLt10M = file.size / 1024 / 1024 < 10;
+      const isLt10M = file.size / 1024 / 1024 < 100;
 
       if (!isValidType) {
         this.$message.error('鍙兘涓婁紶 JPG/PNG/PDF/DOC/DOCX 鏍煎紡鐨勬枃浠�!');
+        return false;
       }
       if (!isLt10M) {
-        this.$message.error('涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB!');
+        this.$message.error('涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 100MB!');
+        return false;
       }
-      return isValidType && isLt10M;
+      return true;
+    },
+    /** 鎻愪氦涓婁紶 */
+    submitUpload() {
+      this.$refs["uploadForm"].validate(valid => {
+        if (valid) {
+          // 妫�鏌ユ槸鍚﹂�夋嫨浜嗘枃浠�
+          const fileList = this.$refs.upload.uploadFiles;
+          if (!fileList || fileList.length === 0) {
+            this.$message.warning('璇烽�夋嫨瑕佷笂浼犵殑鏂囦欢');
+            return;
+          }
+          
+          // 瑙﹀彂涓婁紶
+          this.$refs.upload.submit();
+        }
+      });
+    },
+    /** 鍙栨秷涓婁紶 */
+    cancelUpload() {
+      this.uploadOpen = false;
+      this.uploadForm = {
+        category: null
+      };
+      this.fileList = [];
+      if (this.$refs.upload) {
+        this.$refs.upload.clearFiles();
+      }
     },
     /** 涓婁紶鎴愬姛 */
     handleUploadSuccess(response, file, fileList) {
-      this.$modal.msgSuccess("涓婁紶鎴愬姛");
-      this.uploadOpen = false;
-      this.getTaskDetail();
+      // 妫�鏌ユ槸鍚︽墍鏈夋枃浠堕兘涓婁紶瀹屾垚
+      const allDone = fileList.every(f => f.status === 'success' || f.status === 'fail');
+      
+      if (allDone) {
+        this.$modal.msgSuccess("涓婁紶鎴愬姛");
+        this.cancelUpload();
+        this.getTaskDetail();
+      }
     },
     /** 涓婁紶澶辫触 */
     handleUploadError(err, file, fileList) {
@@ -687,6 +1200,122 @@
         return typeItem ? typeItem.label : vehicleType;
       }
       return vehicleType;
+    },
+    /** 鍒ゆ柇鏄惁涓哄浘鐗囩被鍨� */
+    isImage(fileType) {
+      if (!fileType) return false;
+      const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
+      return imageTypes.includes(fileType.toLowerCase());
+    },
+    /** 鎵嬪姩鍚屾鏈嶅姟鍗� */
+    syncServiceOrder() {
+      this.$modal.confirm('鏄惁纭鍚屾鏈嶅姟鍗曞埌鏃х郴缁燂紵').then(() => {
+        this.syncingServiceOrder = true;
+        return syncServiceOrder(this.taskDetail.taskId);
+      }).then(() => {
+        this.$modal.msgSuccess("鏈嶅姟鍗曞悓姝ユ垚鍔�");
+        // 閲嶆柊鍔犺浇浠诲姟璇︽儏
+        this.getTaskDetail();
+      }).catch(() => {
+        // 澶勭悊鍙栨秷鍜岄敊璇�
+      }).finally(() => {
+        this.syncingServiceOrder = false;
+      });
+    },
+    /** 鎵嬪姩鍚屾璋冨害鍗� */
+    syncDispatchOrder() {
+      this.$modal.confirm('鏄惁纭鍚屾璋冨害鍗曞埌鏃х郴缁燂紵').then(() => {
+        this.syncingDispatchOrder = true;
+        return syncDispatchOrder(this.taskDetail.taskId);
+      }).then(() => {
+        this.$modal.msgSuccess("璋冨害鍗曞悓姝ユ垚鍔�");
+        // 閲嶆柊鍔犺浇浠诲姟璇︽儏
+        this.getTaskDetail();
+      }).catch(() => {
+        // 澶勭悊鍙栨秷鍜岄敊璇�
+      }).finally(() => {
+        this.syncingDispatchOrder = false;
+      });
+    },
+    /** 浠庢棫绯荤粺鍚屾鏁版嵁鍒版柊绯荤粺 */
+    syncFromLegacySystem() {
+      // 妫�鏌ユ槸鍚﹀悓鏃舵湁serviceOrdID鍜宒ispatchOrdID
+      if (!this.taskDetail.emergencyInfo.legacyServiceOrdId || !this.taskDetail.emergencyInfo.legacyDispatchOrdId) {
+        this.$modal.msgError("缂哄皯蹇呰鐨勬棫绯荤粺ID淇℃伅");
+        return;
+      }
+      
+      this.$modal.confirm('鏄惁纭浠庢棫绯荤粺鍚屾鏁版嵁鍒版柊绯荤粺锛�').then(() => {
+        this.syncingFromLegacy = true;
+        return syncFromLegacySystem(
+          this.taskDetail.emergencyInfo.legacyServiceOrdId,
+          this.taskDetail.emergencyInfo.legacyDispatchOrdId
+        );
+      }).then(() => {
+        this.$modal.msgSuccess("浠庢棫绯荤粺鍚屾鎴愬姛");
+        // 閲嶆柊鍔犺浇浠诲姟璇︽儏
+        this.getTaskDetail();
+      }).catch((error) => {
+        if (error !== 'cancel') {
+          this.$modal.msgError("鍚屾澶辫触: " + (error.message || "鏈煡閿欒"));
+        }
+      }).finally(() => {
+        this.syncingFromLegacy = false;
+      });
+    },
+    /** 鎵嬪姩鍚屾浠诲姟鐘舵�� */
+    syncTaskStatus() {
+      this.$modal.confirm('鏄惁纭鍚屾浠诲姟鐘舵�佸埌鏃х郴缁燂紵').then(() => {
+        this.syncingTaskStatus = true;
+        return syncTaskStatus(this.taskDetail.taskId);
+      }).then(() => {
+        this.$modal.msgSuccess("浠诲姟鐘舵�佸悓姝ユ垚鍔�");
+        // 閲嶆柊鍔犺浇浠诲姟璇︽儏
+        this.getTaskDetail();
+      }).catch(() => {
+        // 澶勭悊鍙栨秷鍜岄敊璇�
+      }).finally(() => {
+        this.syncingTaskStatus = false;
+      });
+    },
+    
+    /** 妫�鏌ュ彂绁ㄧ敵璇风姸鎬� */
+    checkInvoiceStatus() {
+      // 璋冪敤鍚庣鎺ュ彛妫�鏌ヨ浠诲姟鏄惁宸茬敵璇峰彂绁�
+      checkTaskInvoice(this.$route.params.taskId)
+        .then(response => {
+          if (response.code === 200 && response.data) {
+            this.hasInvoiceApplied = true;
+            this.invoiceStatus = response.data.status;
+          }
+        })
+        .catch(() => {
+          // 蹇界暐閿欒锛岄粯璁ゆ湭鐢宠
+        });
+    },
+    
+    /** 鐢宠鍙戠エ */
+    handleApplyInvoice() {
+      // 璺宠浆鍒板彂绁ㄧ敵璇烽〉闈紝甯︿笂浠诲姟淇℃伅
+      const taskInfo = {
+        taskId: this.taskDetail.taskId,
+        taskCode: this.taskDetail.taskCode || this.taskDetail.showTaskCode,
+        legacyServiceOrderId: this.taskDetail.emergencyInfo?.legacyServiceOrdId,
+        serviceCode: this.taskDetail.emergencyInfo?.serviceCode,
+        departure: this.taskDetail.departureAddress,
+        destination: this.taskDetail.destinationAddress,
+        completionTime: this.parseTime(this.taskDetail.actualEndTime),
+        transferPrice: this.paymentInfo?.transferPrice || this.paymentInfo?.totalAmount
+      };
+      
+      // 灏嗕换鍔′俊鎭瓨鍌ㄥ埌 sessionStorage
+      sessionStorage.setItem('invoiceTaskInfo', JSON.stringify(taskInfo));
+      
+      // 璺宠浆鍒板彂绁ㄧ敵璇烽〉闈�
+      this.$router.push({
+        path: '/system/invoice/apply',
+        query: { taskId: this.taskDetail.taskId }
+      });
     }
   }
 };

--
Gitblit v1.9.1