From d4fe921568bc29d72644a55fd194adf7f9277cb5 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期六, 22 十一月 2025 15:28:35 +0800
Subject: [PATCH] feat: 将旧系统数据同步到新系统

---
 sql/legacy_transfer_sync_job.sql                                                                |   88 ++
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java                           |    8 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java                |   12 
 ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TaskCreateVO.java                         |   17 
 ruoyi-system/src/main/resources/mapper/system/SysTaskEmergencyMapper.xml                        |   12 
 ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml                                 |    7 
 ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/LegacySystemSyncTask.java                      |    7 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java     |  770 ++++++++++++++++++++++
 ruoyi-system/src/main/java/com/ruoyi/system/service/ILegacyTransferSyncService.java             |   53 +
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleInfoMapper.java                       |   18 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java                        |    8 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTaskService.java                        |   46 +
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java                |   14 
 prd/旧系统转运单同步功能更新日志.md                                                                           |   57 +
 ruoyi-system/src/main/resources/mapper/system/SysTaskVehicleMapper.xml                          |    5 
 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTask.java                                 |    7 
 ruoyi-system/src/main/resources/mapper/system/LegacyTransferSyncMapper.xml                      |  182 +++++
 ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/LegacyTransferSyncTask.java                    |   51 +
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java                        |    8 
 ruoyi-system/src/test/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImplTest.java |  113 +++
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java                |  271 +++++++
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java                |   12 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskEmergencyMapper.java                  |   16 
 ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml                                 |    8 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java                |   14 
 ruoyi-system/src/test/java/com/ruoyi/system/service/SysDeptServiceTest.java                     |    0 
 ruoyi-system/src/test/java/com/ruoyi/system/mapper/SysDeptMapperTest.java                       |    0 
 ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml                             |   16 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/LegacyTransferSyncMapper.java                |   76 ++
 prd/旧系统转运单同步功能说明.md                                                                             |  171 ++++
 30 files changed, 2,049 insertions(+), 18 deletions(-)

diff --git "a/prd/\346\227\247\347\263\273\347\273\237\350\275\254\350\277\220\345\215\225\345\220\214\346\255\245\345\212\237\350\203\275\346\233\264\346\226\260\346\227\245\345\277\227.md" "b/prd/\346\227\247\347\263\273\347\273\237\350\275\254\350\277\220\345\215\225\345\220\214\346\255\245\345\212\237\350\203\275\346\233\264\346\226\260\346\227\245\345\277\227.md"
new file mode 100644
index 0000000..e080aa2
--- /dev/null
+++ "b/prd/\346\227\247\347\263\273\347\273\237\350\275\254\350\277\220\345\215\225\345\220\214\346\255\245\345\212\237\350\203\275\346\233\264\346\226\260\346\227\245\345\277\227.md"
@@ -0,0 +1,57 @@
+# 鏃х郴缁熻浆杩愬崟鍚屾鍔熻兘鏇存柊鏃ュ織
+
+## v1.1 (2025-11-19)
+
+### 鏂板鍔熻兘
+1. 瀹炵幇浜嗗畬鏁寸殑鏃х郴缁熻浆杩愬崟鍚屾鍔熻兘
+2. 鏀寔瀹氭椂浠诲姟鑷姩鍚屾鍜屾墜鍔ㄥ悓姝ヤ袱绉嶆柟寮�
+3. 鎻愪緵浜嗚缁嗙殑鏁版嵁鏄犲皠鍏崇郴鍜岃浆鎹㈤�昏緫
+4. 娣诲姞浜嗗畬鍠勭殑閿欒澶勭悊鍜屾棩蹇楄褰曟満鍒�
+
+### 浼樺寲鏀硅繘
+1. 浼樺寲浜唖yncSingleTransferOrder鏂规硶锛岀洿鎺ラ�氳繃ID鏌ヨ鎸囧畾杞繍鍗曪紝鎻愰珮鏌ヨ鏁堢巼
+2. 澧炲己浜唅sTransferOrderSynced鏂规硶鐨勫紓甯稿鐞嗭紝鏀寔闈炴暟瀛桰D鐨勫鐞�
+3. 瀹屽杽浜哹uildCreateTaskVo鏂规硶鐨勬暟鎹獙璇佸拰閿欒澶勭悊
+4. 浼樺寲浜唖yncLegacyTransferOrders鏂规硶锛屾坊鍔犱簡杩涘害璺熻釜鍜屼腑鏂鐞�
+5. 澧炲姞浜嗘洿澶氱殑鏁版嵁楠岃瘉鍜岃竟鐣屾潯浠舵鏌�
+
+### 浠g爜璐ㄩ噺
+1. 娣诲姞浜嗗畬鏁寸殑鍗曞厓娴嬭瘯瑕嗙洊鏍稿績鍔熻兘
+2. 鎻愪緵浜嗚缁嗙殑浣跨敤鏂囨。鍜屾暟鎹槧灏勮鏄�
+3. 澧炲姞浜哠QL鑴氭湰鐢ㄤ簬閰嶇疆瀹氭椂浠诲姟
+4. 浼樺寲浜嗘棩蹇楄褰曪紝鎻愪緵鏇磋缁嗙殑璋冭瘯淇℃伅
+
+### 鎬ц兘浼樺寲
+1. 鍑忓皯浜嗕笉蹇呰鐨勬暟鎹煡璇紝鎻愰珮鍚屾鏁堢巼
+2. 娣诲姞浜嗙嚎绋嬩紤鐪犳帶鍒讹紝閬垮厤璇锋眰杩囧揩瀵艰嚧绯荤粺鍘嬪姏
+3. 浼樺寲浜嗗紓甯稿鐞嗘祦绋嬶紝閬垮厤鍥犲崟涓暟鎹紓甯稿奖鍝嶆暣浣撳悓姝�
+
+### 瀹夊叏鎬�
+1. 澧炲姞浜嗗弬鏁版湁鏁堟�ч獙璇侊紝闃叉绌烘寚閽堝紓甯�
+2. 瀹屽杽浜嗘暟瀛楃被鍨嬭浆鎹㈢殑寮傚父澶勭悊
+3. 娣诲姞浜嗘棩鏈熸牸寮忛獙璇侊紝纭繚鏁版嵁姝g‘鎬�
+
+## 浣跨敤璇存槑
+
+### 閮ㄧ讲姝ラ
+1. 鎵цSQL鑴氭湰鍒涘缓瀹氭椂浠诲姟閰嶇疆
+2. 纭繚SQL Server鏁版嵁婧愰厤缃纭�
+3. 鍚姩搴旂敤骞堕獙璇佸姛鑳�
+
+### 楠岃瘉鏂规硶
+1. 杩愯鍗曞厓娴嬭瘯楠岃瘉鏍稿績鍔熻兘
+2. 鎵嬪姩瑙﹀彂鍚屾浠诲姟楠岃瘉鏁版嵁杞崲
+3. 妫�鏌ユ棩蹇楃‘璁ゅ悓姝ヨ繃绋嬫甯�
+
+## 鍚庣画璁″垝
+
+### v1.2 璁″垝鍔熻兘
+1. 娣诲姞杞﹁締淇℃伅鍚屾鍔熻兘
+2. 澧炲姞鏇磋缁嗙殑鍚屾鐘舵�佽窡韪�
+3. 鎻愪緵鍚屾鏁版嵁鐨勭粺璁℃姤琛ㄥ姛鑳�
+4. 澧炲姞鎵嬪姩閲嶈瘯澶辫触浠诲姟鐨勫姛鑳�
+
+### 鎬ц兘浼樺寲鏂瑰悜
+1. 鑰冭檻鎵归噺澶勭悊鎻愰珮鍚屾鏁堢巼
+2. 浼樺寲鏁版嵁搴撴煡璇㈠噺灏戝搷搴旀椂闂�
+3. 澧炲姞缂撳瓨鏈哄埗鍑忓皯閲嶅鏌ヨ
\ No newline at end of file
diff --git "a/prd/\346\227\247\347\263\273\347\273\237\350\275\254\350\277\220\345\215\225\345\220\214\346\255\245\345\212\237\350\203\275\350\257\264\346\230\216.md" "b/prd/\346\227\247\347\263\273\347\273\237\350\275\254\350\277\220\345\215\225\345\220\214\346\255\245\345\212\237\350\203\275\350\257\264\346\230\216.md"
new file mode 100644
index 0000000..7a41359
--- /dev/null
+++ "b/prd/\346\227\247\347\263\273\347\273\237\350\275\254\350\277\220\345\215\225\345\220\214\346\255\245\345\212\237\350\203\275\350\257\264\346\230\216.md"
@@ -0,0 +1,171 @@
+# 鏃х郴缁熻浆杩愬崟鍚屾鍔熻兘璇存槑
+
+## 涓�銆佸姛鑳芥杩�
+
+鏈姛鑳藉疄鐜颁簡浠庢棫绯荤粺锛圫QL Server锛夊悓姝ヨ浆杩愬崟淇℃伅鍒版柊绯荤粺锛圡ySQL锛夌殑鍔熻兘銆傞�氳繃瀹氭椂浠诲姟鎴栨墜鍔ㄨЕ鍙戠殑鏂瑰紡锛屽皢鏃х郴缁熶腑鐨勮浆杩愬崟鏁版嵁杞崲涓烘柊绯荤粺鐨勪换鍔℃暟鎹��
+
+## 浜屻�佹牳蹇冪粍浠�
+
+### 1. ILegacyTransferSyncService 鎺ュ彛
+瀹氫箟浜嗚浆杩愬崟鍚屾鐨勬牳蹇冩柟娉曪細
+- `syncLegacyTransferOrders(int daysAgo)` - 鍚屾鎸囧畾澶╂暟鍓嶇殑杞繍鍗曟暟鎹�
+- `syncSingleTransferOrder(String serviceOrdID, String dispatchOrdID)` - 鍚屾鍗曚釜杞繍鍗�
+- `isTransferOrderSynced(String serviceOrdID, String dispatchOrdID)` - 妫�鏌ヨ浆杩愬崟鏄惁宸插悓姝�
+- `buildCreateTaskVo(String serviceOrdID, String dispatchOrdID, Map<String, Object> order)` - 鏋勯�犱换鍔″垱寤哄璞�
+
+### 2. LegacyTransferSyncServiceImpl 瀹炵幇绫�
+瀹炵幇浜嗚浆杩愬崟鍚屾鐨勫叿浣撻�昏緫锛�
+- 浠嶴QL Server鏌ヨ杞繍鍗曟暟鎹�
+- 杞崲鏁版嵁鏍煎紡涓篢askCreateVO瀵硅薄
+- 璋冪敤sysTaskService鍒涘缓鏂颁换鍔�
+- 璁板綍鍚屾鐘舵�佸拰鏃ュ織
+
+### 3. LegacyTransferSyncMapper 鏁版嵁璁块棶灞�
+鎻愪緵浜嗚闂甋QL Server鏁版嵁搴撶殑Mapper鎺ュ彛锛�
+- `selectTransferOrders(String startDate)` - 鏌ヨ鎸囧畾鏃ユ湡鑼冨洿鐨勮浆杩愬崟
+- `selectTransferOrdersByIDs(String serviceOrdID, String dispatchOrdID)` - 鏍规嵁ID鏌ヨ杞繍鍗�
+- `selectDiseaseIdsByServiceOrdID(String serviceOrdID)` - 鏌ヨ鐥呮儏淇℃伅
+- `selectAssigneesByDispatchOrdID(String dispatchOrdID)` - 鏌ヨ鎵ц浜轰俊鎭�
+- `selectCarLicenseByCarID(String carID)` - 鏌ヨ杞﹁締杞︾墝鍙�
+- `selectHospitalNameByHospID(String hospID)` - 鏌ヨ鍖婚櫌鍚嶇О
+- `selectDepartmentNameByDeptID(String deptID)` - 鏌ヨ绉戝鍚嶇О
+
+### 4. LegacyTransferSyncTask 瀹氭椂浠诲姟
+鎻愪緵浜嗗畾鏃舵墽琛岃浆杩愬崟鍚屾鐨勮皟搴︿换鍔★細
+- `syncTransferOrders7Days()` - 鍚屾7澶╁墠鐨勮浆杩愬崟鏁版嵁
+- `syncTransferOrders(String daysAgo)` - 鍚屾鎸囧畾澶╂暟鍓嶇殑杞繍鍗曟暟鎹�
+
+## 涓夈�佹暟鎹槧灏勫叧绯�
+
+### 1. 鍩烘湰淇℃伅鏄犲皠
+| 鏃х郴缁熷瓧娈� | 鏂扮郴缁熷瓧娈� | 璇存槑 |
+|------------|------------|------|
+| ServiceOrdID | legacy_service_ord_id | 鏈嶅姟鍗旾D |
+| DispatchOrdID | legacy_dispatch_ord_id | 璋冨害鍗旾D |
+| ServiceOrdClass | documentTypeId | 鍗曟嵁绫诲瀷ID |
+| ServiceOrdType | taskTypeId | 浠诲姟绫诲瀷ID |
+
+### 2. 鎮h�呬俊鎭槧灏�
+| 鏃х郴缁熷瓧娈� | 鏂扮郴缁熷瓧娈� | 璇存槑 |
+|------------|------------|------|
+| ServiceOrdPtName | patient.name | 鎮h�呭鍚� |
+| ServiceOrdCoPhone | patient.phone | 鑱旂郴浜虹數璇� |
+| ServiceOrdPtIDCard | patient.idCard | 鎮h�呰韩浠借瘉鍙� |
+| ServiceOrdPtCondition | patient.condition | 鎮h�呯梾鎯呮弿杩� |
+| ServiceOrdCoName | patient.contact | 鑱旂郴浜哄鍚� |
+
+### 3. 鍖婚櫌淇℃伅鏄犲皠
+| 鏃х郴缁熷瓧娈� | 鏂扮郴缁熷瓧娈� | 璇存槑 |
+|------------|------------|------|
+| ServiceOrdPtOutHospID | hospitalOut.id | 杞嚭鍖婚櫌ID |
+| ServiceOrdPtServicesID | hospitalOut.departmentId | 杞嚭鍖婚櫌绉戝ID |
+| ServiceOrdPtInHospID | hospitalIn.id | 杞叆鍖婚櫌ID |
+| ServiceOrdPtInServicesID | hospitalIn.departmentId | 杞叆鍖婚櫌绉戝ID |
+
+### 4. 鍦板潃淇℃伅鏄犲皠
+| 鏃х郴缁熷瓧娈� | 鏂扮郴缁熷瓧娈� | 璇存槑 |
+|------------|------------|------|
+| ServiceOrdTraStreet | departureAddress | 鍑哄彂鍦板潃 |
+| ServiceOrdTraEnd | destinationAddress | 鐩殑鍦板潃 |
+
+### 5. 鏃堕棿淇℃伅鏄犲皠
+| 鏃х郴缁熷瓧娈� | 鏂扮郴缁熷瓧娈� | 璇存槑 |
+|------------|------------|------|
+| DispatchOrdStartDate | plannedStartTime | 璁″垝寮�濮嬫椂闂� |
+| DispatchOrd_NS_Time | createTime | 鍒涘缓鏃堕棿 |
+
+### 6. 鍏朵粬淇℃伅鏄犲皠
+| 鏃х郴缁熷瓧娈� | 鏂扮郴缁熷瓧娈� | 璇存槑 |
+|------------|------------|------|
+| ServiceOrdTraTxnPrice | price | 鎴愪氦浠� |
+| ServiceOrdCoTies | remark | 鑱旂郴浜哄叧绯伙紙澶囨敞涓級 |
+
+## 鍥涖�佹墽琛屼汉淇℃伅鏄犲皠
+
+鎵ц浜鸿鑹叉牴鎹瓻ntourageState瀛楁鏄犲皠锛�
+- 1,2 鈫� driver锛堝徃鏈猴級
+- 3,5 鈫� doctor锛堝尰鐢燂級
+- 4,6 鈫� nurse锛堟姢澹級
+- 鍏朵粬 鈫� other锛堝叾浠栵級
+
+## 浜斻�佷娇鐢ㄨ鏄�
+
+### 1. 鑷姩鍚屾
+閰嶇疆瀹氭椂浠诲姟鑷姩鎵ц杞繍鍗曞悓姝ワ細
+1. 杩涘叆銆岀郴缁熺洃鎺с�嶁啋銆屽畾鏃朵换鍔°��
+2. 娣诲姞鏂颁换鍔★細
+   - 浠诲姟鍚嶇О锛氭棫绯荤粺杞繍鍗曞悓姝�
+   - 浠诲姟缁勫悕锛欴EFAULT
+   - 璋冪敤鐩爣锛歚legacyTransferSyncTask.syncTransferOrders7Days()`
+   - cron琛ㄨ揪寮忥細`0 0 2 * * ?`锛堟瘡澶╁噷鏅�2鐐规墽琛岋級
+   - 骞跺彂鎺у埗锛氱姝㈠苟鍙�
+   - 閿欒繃绛栫暐锛氭斁寮冩墽琛�
+
+### 2. 鎵嬪姩鍚屾
+
+#### 鍚屾鎸囧畾澶╂暟鍓嶇殑鏁版嵁
+```java
+@Autowired
+private ILegacyTransferSyncService legacyTransferSyncService;
+
+// 鍚屾7澶╁墠鐨勮浆杩愬崟鏁版嵁
+int successCount = legacyTransferSyncService.syncLegacyTransferOrders(7);
+```
+
+#### 鍚屾鍗曚釜杞繍鍗�
+```java
+// 鍚屾鎸囧畾鐨勬湇鍔″崟鍜岃皟搴﹀崟
+boolean success = legacyTransferSyncService.syncSingleTransferOrder("12345", "67890");
+```
+
+### 3. 鏌ョ湅鍚屾缁撴灉
+
+```sql
+-- 鏌ヨ杞繍鍗曞悓姝ョ粨鏋�
+SELECT 
+    task_id,
+    task_code,
+    task_description,
+    create_time,
+    e.legacy_service_ord_id,
+    e.legacy_dispatch_ord_id
+FROM sys_task t
+LEFT JOIN sys_task_emergency e ON t.task_id = e.task_id
+WHERE t.task_description LIKE '%浠庢棫绯荤粺鍚屾鐨勮浆杩愬崟%'
+ORDER BY t.create_time DESC;
+
+-- 缁熻鍚屾鎯呭喌
+SELECT 
+    COUNT(*) as total_count,
+    SUM(CASE WHEN e.legacy_service_ord_id IS NOT NULL THEN 1 ELSE 0 END) as sync_success_count
+FROM sys_task t
+LEFT JOIN sys_task_emergency e ON t.task_id = e.task_id
+WHERE t.task_description LIKE '%浠庢棫绯荤粺鍚屾鐨勮浆杩愬崟%';
+```
+
+## 鍏�佺洃鎺у拰缁存姢
+
+### 1. 鐩戞帶鎸囨爣
+- 鍚屾鎴愬姛鐜囷細鎴愬姛鏁� / 鎬绘暟 * 100%
+- 鍚屾澶辫触鐜囷細澶辫触鏁� / 鎬绘暟 * 100%
+- 骞冲潎鍚屾鑰楁椂锛氫粠鍒涘缓鍒板悓姝ユ垚鍔熺殑鏃堕棿
+
+### 2. 鏃ュ織鏌ョ湅
+```bash
+# 鏌ョ湅搴旂敤鏃ュ織
+tail -f logs/sys-info.log | grep "杞繍鍗曞悓姝�"
+```
+
+### 3. 閿欒澶勭悊
+濡傛灉鍚屾澶辫触锛岄渶瑕佹鏌ワ細
+1. SQL Server杩炴帴鏄惁姝e父
+2. 鏁版嵁鏍煎紡鏄惁姝g‘
+3. 鏂扮郴缁熷瓧娈垫槸鍚﹀尮閰�
+4. 瀹氭椂浠诲姟鏃ュ織涓殑璇︾粏閿欒淇℃伅
+
+## 涓冦�佹敞鎰忎簨椤�
+
+1. 寤鸿鍦ㄤ笟鍔′綆宄版湡鎵ц鍚屾浠诲姟锛堝鍑屾櫒2鐐癸級
+2. 鍙牴鎹疄闄呴渶姹傝皟鏁村悓姝ュぉ鏁帮紙濡傛敼涓�3澶╂垨14澶╋級
+3. 瀹氭湡妫�鏌ュ悓姝ュけ璐ョ殑浠诲姟骞跺鐞�
+4. 鍙�氳繃淇敼瀹氭椂浠诲姟鐘舵�佷复鏃剁鐢ㄥ悓姝ヤ换鍔�
\ No newline at end of file
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java
index eef87e6..2b08014 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java
@@ -155,4 +155,18 @@
         deptService.checkDeptDataScope(deptId);
         return toAjax(deptService.deleteDeptById(deptId));
     }
+    
+    /**
+     * 鏍规嵁service_class鏌ヨ閮ㄩ棬淇℃伅
+     */
+    @GetMapping("/service-class/{serviceClass}")
+    public AjaxResult getDeptByServiceClass(@PathVariable String serviceClass)
+    {
+        SysDept dept = deptService.selectDeptByServiceClass(serviceClass);
+        if (dept != null) {
+            return success(dept);
+        } else {
+            return error("鏈壘鍒板搴旂殑閮ㄩ棬淇℃伅");
+        }
+    }
 }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
index a4c6be3..3142bb6 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
@@ -317,4 +317,18 @@
         
         return success(users);
     }
+    
+    /**
+     * 鏍规嵁oaUserId鏌ヨ鐢ㄦ埛淇℃伅
+     */
+    @GetMapping("/oa-user/{oaUserId}")
+    public AjaxResult getUserByOaUserId(@PathVariable Integer oaUserId)
+    {
+        SysUser user = userService.selectUserByOaUserId(oaUserId);
+        if (user != null) {
+            return success(user);
+        } else {
+            return error("鏈壘鍒板搴旂殑鐢ㄦ埛淇℃伅");
+        }
+    }
 }
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/LegacySystemSyncTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/LegacySystemSyncTask.java
index bd8c852..6f28280 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/LegacySystemSyncTask.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/LegacySystemSyncTask.java
@@ -15,6 +15,13 @@
  * 
  * @author ruoyi
  * @date 2024-01-20
+ * 
+ * 鐩稿叧浠诲姟:
+ * 1. LegacySystemSyncTask - 鏃х郴缁熶换鍔″悓姝ワ紙鎬ユ晳杞繍浠诲姟鍜屾湇鍔″崟锛�
+ * 2. LegacyTransferSyncTask - 鏃х郴缁熻浆杩愬崟鍚屾锛堜粠SQL Server鍒版柊绯荤粺锛�
+ * 3. TaskStatusSyncService - 浠诲姟鐘舵�佸悓姝ワ紙浠庢棫绯荤粺鍒版柊绯荤粺锛�
+ * 4. TaskStatusPushService - 浠诲姟鐘舵�佹帹閫侊紙浠庢柊绯荤粺鍒版棫绯荤粺锛�
+ * 5. TaskAttachmentSyncService - 浠诲姟闄勪欢鍚屾锛堜粠鏂扮郴缁熷埌鏃х郴缁燂級
  */
 @Component("legacySystemSyncTask")
 public class LegacySystemSyncTask {
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/LegacyTransferSyncTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/LegacyTransferSyncTask.java
new file mode 100644
index 0000000..21d8fdf
--- /dev/null
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/LegacyTransferSyncTask.java
@@ -0,0 +1,51 @@
+package com.ruoyi.quartz.task;
+
+import com.ruoyi.system.service.ILegacyTransferSyncService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * 鏃х郴缁熻浆杩愬崟鍚屾瀹氭椂浠诲姟
+ * 
+ * @author ruoyi
+ * @date 2025-11-19
+ */
+@Component("legacyTransferSyncTask")
+public class LegacyTransferSyncTask {
+    
+    private static final Logger log = LoggerFactory.getLogger(LegacyTransferSyncTask.class);
+    
+    @Autowired
+    private ILegacyTransferSyncService legacyTransferSyncService;
+    
+    /**
+     * 鍚屾7澶╁墠鐨勬棫绯荤粺杞繍鍗曟暟鎹�
+     */
+    public void syncTransferOrders7Days() {
+        log.info("寮�濮嬫墽琛�7澶╁墠鏃х郴缁熻浆杩愬崟鍚屾浠诲姟");
+        try {
+            int count = legacyTransferSyncService.syncLegacyTransferOrders(7);
+            log.info("7澶╁墠鏃х郴缁熻浆杩愬崟鍚屾浠诲姟鎵ц瀹屾垚锛屽悓姝ユ暟閲�: {}", count);
+        } catch (Exception e) {
+            log.error("7澶╁墠鏃х郴缁熻浆杩愬崟鍚屾浠诲姟鎵ц寮傚父", e);
+        }
+    }
+    
+    /**
+     * 鍚屾鎸囧畾澶╂暟鍓嶇殑鏃х郴缁熻浆杩愬崟鏁版嵁
+     * 
+     * @param daysAgo 澶╂暟
+     */
+    public void syncTransferOrders(String daysAgo) {
+        log.info("寮�濮嬫墽琛寋}澶╁墠鏃х郴缁熻浆杩愬崟鍚屾浠诲姟", daysAgo);
+        try {
+            int days = Integer.parseInt(daysAgo);
+            int count = legacyTransferSyncService.syncLegacyTransferOrders(days);
+            log.info("{}澶╁墠鏃х郴缁熻浆杩愬崟鍚屾浠诲姟鎵ц瀹屾垚锛屽悓姝ユ暟閲�: {}", daysAgo, count);
+        } catch (Exception e) {
+            log.error("{}澶╁墠鏃х郴缁熻浆杩愬崟鍚屾浠诲姟鎵ц寮傚父", daysAgo, e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTask.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTask.java
index 2e5d1a8..bf7fe22 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTask.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTask.java
@@ -396,6 +396,13 @@
         }
     }
 
+    public void setPlanedStartTime(Date plannedStartTime) {
+        this.plannedStartTime = plannedStartTime;
+    }
+    public Date getPlanedStartTime() {
+        return plannedStartTime;
+    }
+
     /**
      * 鍒ゆ柇鏄惁瓒呮椂
      */
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TaskCreateVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TaskCreateVO.java
index 3e4628f..abafe39 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TaskCreateVO.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TaskCreateVO.java
@@ -1,9 +1,11 @@
 package com.ruoyi.system.domain.vo;
 
+import java.io.Serializable;
 import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
 
 /**
  * 浠诲姟鍒涘缓瀵硅薄
@@ -11,8 +13,10 @@
  * @author ruoyi
  * @date 2024-01-15
  */
-public class TaskCreateVO {
-    
+@Data
+public class TaskCreateVO implements Serializable {
+
+    private String taskCode;
     /** 浠诲姟绫诲瀷 */
     private String taskType;
 
@@ -32,6 +36,13 @@
     /** 璁″垝缁撴潫鏃堕棿 */
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date plannedEndTime;
+
+    /** 瀹為檯寮�濮嬫椂闂� */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date actualStartTime;
+    /** 瀹為檯缁撴潫鏃堕棿 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date actualEndTime;
 
     /** 鎵ц浜篒D */
     private Long assigneeId;
@@ -110,6 +121,8 @@
     /** 鐥呮儏ID鍒楄〃锛圛CD-10鐤剧梾ID鍒楄〃锛岀敤浜庡悓姝ヨ皟搴﹀崟鐨凮rdICD_ID鍙傛暟锛� */
     private List<Long> diseaseIds;
 
+    private Date createTime;
+
     // 鎵ц浜哄憳淇℃伅鍐呴儴绫�
     public static class AssigneeInfo {
         /** 鐢ㄦ埛ID */
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/LegacyTransferSyncMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/LegacyTransferSyncMapper.java
new file mode 100644
index 0000000..423fe75
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/LegacyTransferSyncMapper.java
@@ -0,0 +1,76 @@
+package com.ruoyi.system.mapper;
+
+import com.ruoyi.common.annotation.DataSource;
+import com.ruoyi.common.enums.DataSourceType;
+import com.ruoyi.system.domain.OrderClassDTO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 鏃х郴缁熻浆杩愬崟鍚屾Mapper鎺ュ彛
+ * 
+ * @author ruoyi
+ * @date 2025-11-19
+ */
+@DataSource(DataSourceType.SQLSERVER)
+public interface LegacyTransferSyncMapper {
+    
+    /**
+     * 鏌ヨ鎸囧畾鏃ユ湡鑼冨洿鐨勮浆杩愬崟鏁版嵁
+     * 
+     * @param startDate 寮�濮嬫棩鏈�
+     * @return 杞繍鍗曟暟鎹垪琛�
+     */
+    List<Map<String, Object>> selectTransferOrders(@Param("startDate") String startDate);
+    
+    /**
+     * 鏍规嵁鏈嶅姟鍗旾D鍜岃皟搴﹀崟ID鏌ヨ杞繍鍗曟暟鎹�
+     * 
+     * @param serviceOrdID 鏈嶅姟鍗旾D
+     * @param dispatchOrdID 璋冨害鍗旾D
+     * @return 杞繍鍗曟暟鎹垪琛�
+     */
+    List<Map<String, Object>> selectTransferOrdersByIDs(@Param("serviceOrdID") String serviceOrdID, @Param("dispatchOrdID") String dispatchOrdID);
+    
+    /**
+     * 鏍规嵁鏈嶅姟鍗旾D鏌ヨ鐥呮儏淇℃伅
+     * 
+     * @param serviceOrdID 鏈嶅姟鍗旾D
+     * @return 鐥呮儏ID鍒楄〃
+     */
+    List<String> selectDiseaseIdsByServiceOrdID(@Param("serviceOrdID") String serviceOrdID);
+    
+    /**
+     * 鏍规嵁璋冨害鍗旾D鏌ヨ鎵ц浜轰俊鎭�
+     * 
+     * @param dispatchOrdID 璋冨害鍗旾D
+     * @return 鎵ц浜轰俊鎭垪琛�
+     */
+    List<Map<String, Object>> selectAssigneesByDispatchOrdID(@Param("dispatchOrdID") String dispatchOrdID);
+    
+    /**
+     * 鏍规嵁杞﹁締ID鏌ヨ杞︾墝鍙�
+     * 
+     * @param carID 杞﹁締ID
+     * @return 杞︾墝鍙�
+     */
+    String selectCarLicenseByCarID(@Param("carID") String carID);
+    
+    /**
+     * 鏍规嵁鍖婚櫌ID鏌ヨ鍖婚櫌鍚嶇О
+     * 
+     * @param hospID 鍖婚櫌ID
+     * @return 鍖婚櫌鍚嶇О
+     */
+    String selectHospitalNameByHospID(@Param("hospID") String hospID);
+    
+    /**
+     * 鏍规嵁绉戝ID鏌ヨ绉戝鍚嶇О
+     * 
+     * @param deptID 绉戝ID
+     * @return 绉戝鍚嶇О
+     */
+    String selectDepartmentNameByDeptID(@Param("deptID") String deptID);
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
index df69912..7b7365a 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
@@ -150,4 +150,12 @@
      * @return 鍒嗗叕鍙稿垪琛�
      */
     public List<SysDept> selectBranchCompaniesByOrderCodes(@Param("orderCodes") List<String> orderCodes);
+    
+    /**
+     * 鏍规嵁service_class鏌ヨ閮ㄩ棬淇℃伅
+     * 
+     * @param serviceClass 鏈嶅姟绫诲埆缂栫爜
+     * @return 閮ㄩ棬淇℃伅
+     */
+    public SysDept selectDeptByServiceClass(@Param("serviceClass") String serviceClass);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskEmergencyMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskEmergencyMapper.java
index c1ef739..8a852ec 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskEmergencyMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskEmergencyMapper.java
@@ -89,4 +89,20 @@
      * @return 鎬ユ晳杞繍浠诲姟鍒楄〃
      */
     public List<SysTaskEmergency> selectSyncedTasksForStatusUpdate(@Param("offset") Integer offset, @Param("limit") Integer limit);
+    
+    /**
+     * 鏍规嵁鏃х郴缁熸湇鍔″崟ID鏌ヨ鎬ユ晳杞繍浠诲姟鎵╁睍淇℃伅
+     * 
+     * @param legacyServiceOrdId 鏃х郴缁熸湇鍔″崟ID
+     * @return 鎬ユ晳杞繍浠诲姟鎵╁睍淇℃伅
+     */
+    public SysTaskEmergency selectByLegacyServiceOrdId(@Param("legacyServiceOrdId") Long legacyServiceOrdId);
+    
+    /**
+     * 鏍规嵁鏃х郴缁熻皟搴﹀崟ID鏌ヨ鎬ユ晳杞繍浠诲姟鎵╁睍淇℃伅
+     * 
+     * @param legacyDispatchOrdId 鏃х郴缁熻皟搴﹀崟ID
+     * @return 鎬ユ晳杞繍浠诲姟鎵╁睍淇℃伅
+     */
+    public SysTaskEmergency selectByLegacyDispatchOrdId(@Param("legacyDispatchOrdId") Long legacyDispatchOrdId);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleInfoMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleInfoMapper.java
index e1c37ff..ec09157 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleInfoMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleInfoMapper.java
@@ -1,6 +1,8 @@
 package com.ruoyi.system.mapper;
 
 import java.util.List;
+import java.util.Map;
+
 import org.apache.ibatis.annotations.Param;
 import com.ruoyi.system.domain.VehicleInfo;
 import com.ruoyi.system.domain.VehicleDept;
@@ -48,6 +50,22 @@
      * @return 杞﹁締淇℃伅
      */
     public VehicleInfo selectVehicleInfoByVehicleNo(String vehicleNo);
+    
+    /**
+     * 鏍规嵁鏃х郴缁熻溅杈咺D(CarID)鏌ヨ杞﹁締淇℃伅
+     * 
+     * @param carId 鏃х郴缁熻溅杈咺D
+     * @return 杞﹁締淇℃伅
+     */
+    public VehicleInfo selectVehicleInfoByCarId(@Param("carId") Integer carId);
+    
+    /**
+     * 鏍规嵁鏃х郴缁熻溅杈咺D鏌ヨ杞﹁締淇℃伅
+     * 
+     * @param carID 鏃х郴缁熻溅杈咺D
+     * @return 杞﹁締淇℃伅锛坴ehicle_id, car_id, vehicle_no锛�
+     */
+    public Map<String, Object> selectVehicleInfoByCarID(@Param("carID") String carID);
 
     /**
      * 鏌ヨ杞﹁締淇℃伅鍒楄〃
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ILegacyTransferSyncService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ILegacyTransferSyncService.java
new file mode 100644
index 0000000..70e578c
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ILegacyTransferSyncService.java
@@ -0,0 +1,53 @@
+package com.ruoyi.system.service;
+
+import com.ruoyi.system.domain.SysTask;
+import com.ruoyi.system.domain.SysTaskEmergency;
+import com.ruoyi.system.domain.vo.TaskCreateVO;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 鏃х郴缁熻浆杩愬崟鍚屾Service鎺ュ彛
+ * 
+ * @author ruoyi
+ * @date 2025-11-19
+ */
+public interface ILegacyTransferSyncService {
+    
+    /**
+     * 鍚屾鎸囧畾鏃ユ湡鑼冨洿鐨勬棫绯荤粺杞繍鍗曞埌鏂扮郴缁�
+     * 
+     * @param daysAgo 澶氬皯澶╁墠鐨勬暟鎹紙濡�7琛ㄧず7澶╁墠鐨勬暟鎹級
+     * @return 鎴愬姛鍚屾鐨勮浆杩愬崟鏁伴噺
+     */
+    int syncLegacyTransferOrders(int daysAgo);
+    
+    /**
+     * 鍚屾鍗曚釜鏃х郴缁熻浆杩愬崟鍒版柊绯荤粺
+     * 
+     * @param serviceOrdID 鏈嶅姟鍗旾D
+     * @param dispatchOrdID 璋冨害鍗旾D
+     * @return 鏄惁鍚屾鎴愬姛
+     */
+    boolean syncSingleTransferOrder(String serviceOrdID, String dispatchOrdID);
+    
+    /**
+     * 妫�鏌ヨ浆杩愬崟鏄惁宸插悓姝�
+     * 
+     * @param serviceOrdID 鏈嶅姟鍗旾D
+     * @param dispatchOrdID 璋冨害鍗旾D
+     * @return 鏄惁宸插悓姝�
+     */
+    boolean isTransferOrderSynced(String serviceOrdID, String dispatchOrdID);
+    
+    /**
+     * 鏋勯�燭askCreateVO瀵硅薄鐢ㄤ簬鍒涘缓浠诲姟
+     * 
+     * @param serviceOrdID 鏈嶅姟鍗旾D
+     * @param dispatchOrdID 璋冨害鍗旾D
+     * @param order 杞繍鍗曡缁嗕俊鎭�
+     * @return TaskCreateVO瀵硅薄
+     */
+    TaskCreateVO buildCreateTaskVo(String serviceOrdID, String dispatchOrdID, Map<String, Object> order);
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
index a53ab4e..c3d1fcc 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
@@ -134,4 +134,12 @@
      * @return 鍒嗗叕鍙稿垪琛�
      */
     public List<SysDept> computeBranchCompaniesForUser(SysUser user);
+    
+    /**
+     * 鏍规嵁service_class鏌ヨ閮ㄩ棬淇℃伅
+     * 
+     * @param serviceClass 鏈嶅姟绫诲埆缂栫爜
+     * @return 閮ㄩ棬淇℃伅
+     */
+    public SysDept selectDeptByServiceClass(String serviceClass);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTaskService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTaskService.java
index a5cdf19..7b3cab6 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTaskService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTaskService.java
@@ -1,5 +1,6 @@
 package com.ruoyi.system.service;
 
+import java.util.Date;
 import java.util.List;
 import org.springframework.web.multipart.MultipartFile;
 import com.ruoyi.system.domain.SysTask;
@@ -43,6 +44,18 @@
      * @return 缁撴灉
      */
     public int insertSysTask(TaskCreateVO createVO);
+
+    /**
+     * 鏂板浠诲姟绠$悊锛堝厑璁镐粠澶栭儴浼犲叆鐢ㄦ埛淇℃伅銆侀儴闂ㄤ俊鎭拰鏃堕棿淇℃伅锛�
+     * 
+     * @param createVO 浠诲姟鍒涘缓瀵硅薄
+     * @param userId 鐢ㄦ埛ID
+     * @param deptId 閮ㄩ棬ID
+     * @param createTime 鍒涘缓鏃堕棿
+     * @param updateTime 鏇存柊鏃堕棿
+     * @return 缁撴灉
+     */
+    public int insertTask(TaskCreateVO createVO,String serviceOrderId,String dispatchOrderId, Long userId,String userName, Long deptId, Date createTime, Date updateTime);
 
     /**
      * 淇敼浠诲姟绠$悊
@@ -214,4 +227,37 @@
      * @return 姝e湪杩涜涓殑浠诲姟鍒楄〃
      */
     public List<SysTask> checkVehicleActiveTasks(Long vehicleId);
+
+    /**
+     * 妫�鏌ヤ换鍔℃槸鍚﹀凡鍏宠仈鏃х郴缁熸湇鍔″崟ID
+     * 
+     * @param taskId 浠诲姟ID
+     * @return true-宸插叧鑱旓紝false-鏈叧鑱�
+     */
+    public boolean hasLegacyServiceOrdId(Long taskId);
+
+    /**
+     * 妫�鏌ヤ换鍔℃槸鍚﹀凡鍏宠仈鏃х郴缁熻皟搴﹀崟ID
+     * 
+     * @param taskId 浠诲姟ID
+     * @return true-宸插叧鑱旓紝false-鏈叧鑱�
+     */
+    public boolean hasLegacyDispatchOrdId(Long taskId);
+
+    /**
+     * 鏍规嵁鏃х郴缁熸湇鍔″崟ID妫�鏌ユ槸鍚﹀瓨鍦ㄤ换鍔�
+     * 
+     * @param legacyServiceOrdId 鏃х郴缁熸湇鍔″崟ID
+     * @return true-瀛樺湪锛宖alse-涓嶅瓨鍦�
+     */
+    public boolean existsByLegacyServiceOrdId(Long legacyServiceOrdId);
+
+    /**
+     * 鏍规嵁鏃х郴缁熻皟搴﹀崟ID妫�鏌ユ槸鍚﹀瓨鍦ㄤ换鍔�
+     * 
+     * @param legacyDispatchOrdId 鏃х郴缁熻皟搴﹀崟ID
+     * @return true-瀛樺湪锛宖alse-涓嶅瓨鍦�
+     */
+    public boolean existsByLegacyDispatchOrdId(Long legacyDispatchOrdId);
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
index 3b50ba7..0fa21a2 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
@@ -57,6 +57,14 @@
      * @return 鐢ㄦ埛瀵硅薄淇℃伅
      */
     public SysUser selectUserByOpenId(String openId);
+    
+    /**
+     * 鏍规嵁oaUserId鏌ヨ鐢ㄦ埛
+     * 
+     * @param oaUserId SQL Server涓殑OA鐢ㄦ埛ID
+     * @return 鐢ㄦ埛淇℃伅
+     */
+    public SysUser selectUserByOaUserId(Integer oaUserId);
 
     /**
      * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java
new file mode 100644
index 0000000..abc7e5c
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java
@@ -0,0 +1,770 @@
+package com.ruoyi.system.service.impl;
+
+import com.ruoyi.common.annotation.DataSource;
+import com.ruoyi.common.core.domain.entity.SysDept;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.enums.DataSourceType;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.system.domain.SysTask;
+import com.ruoyi.system.domain.SysTaskEmergency;
+import com.ruoyi.system.domain.VehicleInfo;
+import com.ruoyi.system.domain.vo.TaskCreateVO;
+import com.ruoyi.system.mapper.SysTaskEmergencyMapper;
+import com.ruoyi.system.mapper.SysTaskMapper;
+import com.ruoyi.system.service.ILegacyTransferSyncService;
+import com.ruoyi.system.service.ISysDeptService;
+import com.ruoyi.system.service.ISysTaskService;
+import com.ruoyi.system.mapper.LegacyTransferSyncMapper;
+import com.ruoyi.system.mapper.VehicleInfoMapper;
+import com.ruoyi.system.service.ISysUserService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.text.SimpleDateFormat;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 鏃х郴缁熻浆杩愬崟鍚屾Service涓氬姟灞傚鐞�
+ * 
+ * @author ruoyi
+ * @date 2025-11-19
+ */
+@Service
+public class LegacyTransferSyncServiceImpl implements ILegacyTransferSyncService {
+    
+    private static final Logger log = LoggerFactory.getLogger(LegacyTransferSyncServiceImpl.class);
+    
+    @Autowired
+    private SysTaskMapper sysTaskMapper;
+    
+    @Autowired
+    private SysTaskEmergencyMapper sysTaskEmergencyMapper;
+    
+    @Autowired
+    private ISysTaskService sysTaskService;
+    
+    @Autowired
+    private LegacyTransferSyncMapper legacyTransferSyncMapper;
+    
+    @Autowired
+    private VehicleInfoMapper vehicleInfoMapper;
+
+    @Autowired
+    private ISysDeptService sysDeptService;
+
+    @Autowired
+    private ISysUserService sysUserService;
+    
+    /**
+     * 鍚屾鎸囧畾鏃ユ湡鑼冨洿鐨勬棫绯荤粺杞繍鍗曞埌鏂扮郴缁�
+     * 
+     * @param daysAgo 澶氬皯澶╁墠鐨勬暟鎹紙濡�7琛ㄧず7澶╁墠鐨勬暟鎹級
+     * @return 鎴愬姛鍚屾鐨勮浆杩愬崟鏁伴噺
+     */
+    @Override
+    public int syncLegacyTransferOrders(int daysAgo) {
+        log.info("寮�濮嬪悓姝}澶╁墠鐨勬棫绯荤粺杞繍鍗曟暟鎹�", daysAgo);
+        
+        try {
+            // 鍙傛暟楠岃瘉
+            if (daysAgo <= 0) {
+                log.error("澶╂暟鍙傛暟蹇呴』澶т簬0");
+                return 0;
+            }
+            
+            // 璁$畻鏃ユ湡鑼冨洿
+            Date startDate = DateUtils.addDays(new Date(), -daysAgo);
+            String startDateStr = DateUtils.parseDateToStr("yyyy-MM-dd", startDate);
+            
+            // 浠嶴QL Server鏌ヨ杞繍鍗曟暟鎹�
+            List<Map<String, Object>> transferOrders = legacyTransferSyncMapper.selectTransferOrders(startDateStr);
+            
+            if (transferOrders == null || transferOrders.isEmpty()) {
+                log.info("鏈煡璇㈠埌{}澶╁墠鐨勮浆杩愬崟鏁版嵁", daysAgo);
+                return 0;
+            }
+            
+            log.info("鏌ヨ鍒皗}鏉¤浆杩愬崟鏁版嵁锛屽紑濮嬪悓姝�...", transferOrders.size());
+            
+            int successCount = 0;
+            int totalCount = transferOrders.size();
+            int processedCount = 0;
+            
+            for (Map<String, Object> order : transferOrders) {
+                processedCount++;
+                try {
+                    String serviceOrdID = getStringValue(order, "ServiceOrdID");
+                    String dispatchOrdID = getStringValue(order, "DispatchOrdID");
+                    
+                    // 妫�鏌ュ弬鏁版湁鏁堟��
+                    if (StringUtils.isEmpty(serviceOrdID)) {
+                        log.warn("绗瑊}鏉℃暟鎹湇鍔″崟ID涓虹┖锛岃烦杩囧鐞�", processedCount);
+                        continue;
+                    }
+                    
+                    log.debug("姝e湪澶勭悊绗瑊}/{}鏉¤浆杩愬崟: ServiceOrdID={}, DispatchOrdID={}", 
+                             processedCount, totalCount, serviceOrdID, dispatchOrdID);
+                    
+                    // 妫�鏌ユ槸鍚﹀凡鍚屾
+                    if (isTransferOrderSynced(serviceOrdID, dispatchOrdID)) {
+                        log.debug("杞繍鍗曞凡鍚屾锛岃烦杩�: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID);
+                        continue;
+                    }
+                    
+                    // 鍚屾鍗曚釜杞繍鍗�
+                    boolean success = syncSingleTransferOrder(serviceOrdID, dispatchOrdID, order);
+                    if (success) {
+                        successCount++;
+                    }
+                    
+                    // 鎺у埗鍚屾棰戠巼锛岄伩鍏嶈姹傝繃蹇�
+                    Thread.sleep(100);
+                } catch (InterruptedException ie) {
+                    log.warn("鍚屾浠诲姟琚腑鏂�");
+                    Thread.currentThread().interrupt();
+                    break;
+                } catch (Exception e) {
+                    log.error("鍚屾鍗曚釜杞繍鍗曞け璐�: ServiceOrdID={}, DispatchOrdID={}", 
+                             getStringValue(order, "ServiceOrdID"), 
+                             getStringValue(order, "DispatchOrdID"), e);
+                }
+            }
+            
+            log.info("鍚屾瀹屾垚锛屽叡澶勭悊{}鏉¤浆杩愬崟锛屾垚鍔熷悓姝}鏉¤浆杩愬崟鏁版嵁", totalCount, successCount);
+            return successCount;
+            
+        } catch (Exception e) {
+            log.error("鍚屾{}澶╁墠鐨勬棫绯荤粺杞繍鍗曟暟鎹紓甯�", daysAgo, e);
+            return 0;
+        }
+    }
+    
+    /**
+     * 鍚屾鍗曚釜鏃х郴缁熻浆杩愬崟鍒版柊绯荤粺
+     * 
+     * @param serviceOrdID 鏈嶅姟鍗旾D
+     * @param dispatchOrdID 璋冨害鍗旾D
+     * @return 鏄惁鍚屾鎴愬姛
+     */
+    @Override
+    public boolean syncSingleTransferOrder(String serviceOrdID, String dispatchOrdID) {
+        log.info("寮�濮嬪悓姝ュ崟涓浆杩愬崟: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID);
+        
+        try {
+            // 妫�鏌ュ弬鏁版湁鏁堟��
+            if (StringUtils.isEmpty(serviceOrdID)) {
+                log.error("鏈嶅姟鍗旾D涓嶈兘涓虹┖");
+                return false;
+            }
+            
+            // 妫�鏌ユ槸鍚﹀凡鍚屾
+            if (isTransferOrderSynced(serviceOrdID, dispatchOrdID)) {
+                log.info("杞繍鍗曞凡鍚屾锛岃烦杩�: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID);
+                return true;
+            }
+            
+            // 鐩存帴鏌ヨ鎸囧畾鐨勮浆杩愬崟淇℃伅
+            List<Map<String, Object>> transferOrders = legacyTransferSyncMapper.selectTransferOrdersByIDs(serviceOrdID, dispatchOrdID);
+            
+            if (transferOrders == null || transferOrders.isEmpty()) {
+                log.error("鏈煡璇㈠埌瀵瑰簲鐨勮浆杩愬崟淇℃伅: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID);
+                return false;
+            }
+            
+            Map<String, Object> order = transferOrders.get(0);
+            
+            // 鍚屾鍗曚釜杞繍鍗�
+            return syncSingleTransferOrder(serviceOrdID, dispatchOrdID, order);
+            
+        } catch (Exception e) {
+            log.error("鍚屾鍗曚釜杞繍鍗曞紓甯�: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID, e);
+            return false;
+        }
+    }
+    
+    /**
+     * 鍚屾鍗曚釜鏃х郴缁熻浆杩愬崟鍒版柊绯荤粺锛堝甫璇︾粏淇℃伅锛�
+     * 
+     * @param serviceOrdID 鏈嶅姟鍗旾D
+     * @param dispatchOrdID 璋冨害鍗旾D
+     * @param order 杞繍鍗曡缁嗕俊鎭�
+     * @return 鏄惁鍚屾鎴愬姛
+     */
+    private boolean syncSingleTransferOrder(String serviceOrdID, String dispatchOrdID, Map<String, Object> order) {
+        log.info("寮�濮嬪悓姝ュ崟涓浆杩愬崟: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID);
+        
+        try {
+            // 鏋勯�燭askCreateVO瀵硅薄
+            TaskCreateVO createTaskVo = buildCreateTaskVo(serviceOrdID, dispatchOrdID, order);
+            
+            if (createTaskVo == null) {
+                log.error("鏋勯�燭askCreateVO澶辫触: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID);
+                return false;
+            }
+            
+            // 璁板綍鍒涘缓鐨勪换鍔′俊鎭�
+            log.debug("鍑嗗鍒涘缓浠诲姟: ServiceOrdID={}, DispatchOrdID={}, 鎮h�呭鍚�={}, 杞嚭鍖婚櫌={}, 杞叆鍖婚櫌={}", 
+                     serviceOrdID, dispatchOrdID, 
+                     createTaskVo.getPatient() != null ? createTaskVo.getPatient().getName() : "鏈煡",
+                     createTaskVo.getHospitalOut() != null ? createTaskVo.getHospitalOut().getName() : "鏈煡",
+                     createTaskVo.getHospitalIn() != null ? createTaskVo.getHospitalIn().getName() : "鏈煡");
+
+            Date ServiceOrd_CC_Time= getDateValue(order, "ServiceOrd_CC_Time");
+            // 璋冪敤sysTaskService鍒涘缓浠诲姟
+            String serviceOrdClass = getStringValue(order,"ServiceOrdClass");
+
+            Integer oauserId=getIntegerValue(order,"ServiceOrd_NS_ID");
+            SysUser sysUser=sysUserService.selectUserByOaUserId(oauserId);
+            Long taskCreatorId=sysUser==null?null:sysUser.getUserId();
+            String createUserName=sysUser==null?"system":sysUser.getUserName();
+            SysDept dept=sysDeptService.selectDeptByServiceClass(serviceOrdClass);
+            Long deptId=dept==null?null:dept.getDeptId();
+
+            int result = sysTaskService.insertTask(createTaskVo,serviceOrdID,dispatchOrdID, taskCreatorId,createUserName, deptId, ServiceOrd_CC_Time, ServiceOrd_CC_Time);
+
+            if (result > 0) {
+                log.info("杞繍鍗曞悓姝ユ垚鍔�: ServiceOrdID={}, DispatchOrdID={}, 鍒涘缓鐨勪换鍔D={}", serviceOrdID, dispatchOrdID, result);
+                return true;
+            } else {
+                log.error("杞繍鍗曞悓姝ュけ璐�: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID);
+                return false;
+            }
+            
+        } catch (Exception e) {
+            log.error("鍚屾鍗曚釜杞繍鍗曞紓甯�: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID, e);
+            return false;
+        }
+    }
+    
+    /**
+     * 妫�鏌ヨ浆杩愬崟鏄惁宸插悓姝�
+     * 
+     * @param serviceOrdID 鏈嶅姟鍗旾D
+     * @param dispatchOrdID 璋冨害鍗旾D
+     * @return 鏄惁宸插悓姝�
+     */
+    @Override
+    public boolean isTransferOrderSynced(String serviceOrdID, String dispatchOrdID) {
+        try {
+            // 妫�鏌ュ弬鏁版湁鏁堟��
+            if (StringUtils.isEmpty(serviceOrdID)) {
+                log.warn("鏈嶅姟鍗旾D涓嶈兘涓虹┖");
+                return false;
+            }
+            
+            // 妫�鏌ys_task_emergency琛ㄤ腑鏄惁宸插瓨鍦ㄥ搴旂殑璁板綍
+            // 鏉′欢锛歭egacy_service_ord_id = serviceOrdID 鎴� legacy_dispatch_ord_id = dispatchOrdID
+            
+            try {
+                SysTaskEmergency emergency = sysTaskEmergencyMapper.selectByLegacyServiceOrdId(Long.valueOf(serviceOrdID));
+                if (emergency != null) {
+                    return true;
+                }
+            } catch (NumberFormatException e) {
+                log.warn("鏈嶅姟鍗旾D涓嶆槸鏈夋晥鏁板瓧: {}", serviceOrdID);
+            }
+            
+            if (StringUtils.isNotEmpty(dispatchOrdID)) {
+                try {
+                    SysTaskEmergency emergency = sysTaskEmergencyMapper.selectByLegacyDispatchOrdId(Long.valueOf(dispatchOrdID));
+                    if (emergency != null) {
+                        return true;
+                    }
+                } catch (NumberFormatException e) {
+                    log.warn("璋冨害鍗旾D涓嶆槸鏈夋晥鏁板瓧: {}", dispatchOrdID);
+                }
+            }
+            
+            return false;
+        } catch (Exception e) {
+            log.error("妫�鏌ヨ浆杩愬崟鏄惁宸插悓姝ュ紓甯�: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID, e);
+            return false;
+        }
+    }
+    
+    /**
+     * 鏋勯�燭askCreateVO瀵硅薄鐢ㄤ簬鍒涘缓浠诲姟
+     * 
+     * @param serviceOrdID 鏈嶅姟鍗旾D
+     * @param dispatchOrdID 璋冨害鍗旾D
+     * @param order 杞繍鍗曡缁嗕俊鎭�
+     * @return TaskCreateVO瀵硅薄
+     */
+    @Override
+    public TaskCreateVO buildCreateTaskVo(String serviceOrdID, String dispatchOrdID, Map<String, Object> order) {
+        log.info("鏋勯�燭askCreateVO: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID);
+
+        try {
+            // 妫�鏌ュ弬鏁版湁鏁堟��
+            if (order == null || order.isEmpty()) {
+                log.error("杞繍鍗曡缁嗕俊鎭笉鑳戒负绌�");
+                return null;
+            }
+            
+            if (StringUtils.isEmpty(serviceOrdID)) {
+                log.error("鏈嶅姟鍗旾D涓嶈兘涓虹┖");
+                return null;
+            }
+            
+            TaskCreateVO createTaskVo = new TaskCreateVO();
+            String Old_ServiceOrdID_TXT=getStringValue(order,"Old_ServiceOrdID_TXT");
+            if(Old_ServiceOrdID_TXT!=null){
+                createTaskVo.setTaskCode(Old_ServiceOrdID_TXT);
+            }
+            
+            // 璁剧疆鍩烘湰淇℃伅
+            createTaskVo.setTaskType("EMERGENCY_TRANSFER"); // 鎬ユ晳杞繍浠诲姟
+            
+            // 璁剧疆鍗曟嵁绫诲瀷鍜屼换鍔$被鍨婭D锛堜粠鏃х郴缁熷瓧娈垫槧灏勶級
+            String serviceOrdClass = getStringValue(order, "ServiceOrdClass");
+            if (StringUtils.isNotEmpty(serviceOrdClass)) {
+                createTaskVo.setDocumentTypeId(serviceOrdClass);
+            }
+            
+            String serviceOrdType = getStringValue(order, "ServiceOrdType");
+            if (StringUtils.isNotEmpty(serviceOrdType)) {
+                createTaskVo.setTaskTypeId(serviceOrdType);
+            }
+            
+            // 璁剧疆鍖哄煙绫诲瀷
+            String serviceOrdAreaType = getStringValue(order, "ServiceOrdAreaType");
+            if (StringUtils.isNotEmpty(serviceOrdAreaType)) {
+                // 鍙互鏍规嵁闇�瑕佸皢鍖哄煙绫诲瀷鏄犲皠鍒癟askCreateVO鐨勫叾浠栧瓧娈�
+                log.debug("鍖哄煙绫诲瀷: {}", serviceOrdAreaType);
+            }
+            
+            // 璁剧疆鐢ㄦ埛ID
+            Long serviceOrdUserID = getLongValue(order, "ServiceOrdUserID");
+            if (serviceOrdUserID != null) {
+                // 鍙互鏍规嵁闇�瑕佸皢鐢ㄦ埛ID鏄犲皠鍒癟askCreateVO鐨勫叾浠栧瓧娈�
+                log.debug("鐢ㄦ埛ID: {}", serviceOrdUserID);
+            }
+            
+            // 璁剧疆鎮h�呬俊鎭�
+            TaskCreateVO.PatientInfo patientInfo = new TaskCreateVO.PatientInfo();
+            patientInfo.setName(getStringValue(order, "ServiceOrdPtName"));
+            patientInfo.setPhone(getStringValue(order, "ServiceOrdCoPhone"));
+            patientInfo.setIdCard(getStringValue(order, "ServiceOrdPtIDCard"));
+            patientInfo.setCondition(getStringValue(order, "ServiceOrdPtCondition"));
+            patientInfo.setContact(getStringValue(order, "ServiceOrdCoName"));
+
+            String serviceOrdPtSex = getStringValue(order, "ServiceOrdPtSex");
+            if(serviceOrdPtSex!=null){
+                if(serviceOrdPtSex.equals("鐢�")){
+                    patientInfo.setGender("male");
+                }else if(serviceOrdPtSex.equals("濂�")){
+                    patientInfo.setGender("female");
+                }
+            }
+            createTaskVo.setPatient(patientInfo);
+            //1000鍏噷锛屾彁鍙栨暟瀛�
+            String ServiceOrdTraDistance=getStringValue(order, "ServiceOrdTraDistance");
+            if(ServiceOrdTraDistance!=null){
+                ServiceOrdTraDistance=ServiceOrdTraDistance.replaceAll("[^0-9]", "");
+                createTaskVo.setDistance(new BigDecimal(ServiceOrdTraDistance));
+            }
+
+            
+            // 璁剧疆杞嚭鍖婚櫌淇℃伅
+
+            TaskCreateVO.HospitalInfo hospitalOutInfo = new TaskCreateVO.HospitalInfo();
+            Long hospitalOutId = getLongValue(order, "ServiceOrdPtOutHospID");
+            hospitalOutInfo.setId(hospitalOutId);
+            if (hospitalOutId != null) {
+                String hospitalOutName = legacyTransferSyncMapper.selectHospitalNameByHospID(hospitalOutId.toString());
+                if (StringUtils.isNotEmpty(hospitalOutName)) {
+                    hospitalOutInfo.setName(hospitalOutName);
+                }
+            }
+            String ServiceOrdTraVia=getStringValue(order, "ServiceOrdTraVia");
+            if(ServiceOrdTraVia!=null){
+                hospitalOutInfo.setAddress(ServiceOrdTraVia);
+            }
+
+
+            String hospitalOutDeptId = getStringValue(order, "ServiceOrdPtServicesID");
+
+            //杞嚭搴婁綅
+            String serviceOrdPtServices=getStringValue(order, "ServiceOrdPtServices");
+            hospitalOutInfo.setDepartmentId(hospitalOutDeptId);
+            if (StringUtils.isNotEmpty(hospitalOutDeptId)) {
+                String hospitalOutDeptName = legacyTransferSyncMapper.selectDepartmentNameByDeptID(hospitalOutDeptId);
+                if (StringUtils.isNotEmpty(hospitalOutDeptName)) {
+                    hospitalOutInfo.setDepartment(hospitalOutDeptName);
+                }
+            }
+            if(serviceOrdPtServices!= null){
+                hospitalOutInfo.setBedNumber(serviceOrdPtServices);
+            }
+            createTaskVo.setHospitalOut(hospitalOutInfo);
+            
+            // 璁剧疆杞叆鍖婚櫌淇℃伅
+            TaskCreateVO.HospitalInfo hospitalInInfo = new TaskCreateVO.HospitalInfo();
+            Long hospitalInId = getLongValue(order, "ServiceOrdPtInHospID");
+            hospitalInInfo.setId(hospitalInId);
+            if (hospitalInId != null) {
+                String hospitalInName = legacyTransferSyncMapper.selectHospitalNameByHospID(hospitalInId.toString());
+                if (StringUtils.isNotEmpty(hospitalInName)) {
+                    hospitalInInfo.setName(hospitalInName);
+                }
+            }
+            String DispatchOrdTraEnd = getStringValue(order, "DispatchOrdTraEnd");
+            if(DispatchOrdTraEnd!= null){
+                hospitalInInfo.setAddress(DispatchOrdTraEnd);
+            }
+            //杞叆搴婁綅
+            String serviceOrdPtInServices =getStringValue(order, "ServiceOrdPtInServices");
+            if(serviceOrdPtInServices!= null){
+                hospitalInInfo.setBedNumber(serviceOrdPtInServices);
+            }
+
+
+            String hospitalInDeptId = getStringValue(order, "ServiceOrdPtInServicesID");
+            hospitalInInfo.setDepartmentId(hospitalInDeptId);
+            if (StringUtils.isNotEmpty(hospitalInDeptId)) {
+                String hospitalInDeptName = legacyTransferSyncMapper.selectDepartmentNameByDeptID(hospitalInDeptId);
+                if (StringUtils.isNotEmpty(hospitalInDeptName)) {
+                    hospitalInInfo.setDepartment(hospitalInDeptName);
+                }
+            }
+            createTaskVo.setHospitalIn(hospitalInInfo);
+            
+            // 璁剧疆鍦板潃淇℃伅
+            createTaskVo.setDepartureAddress(getStringValue(order, "ServiceOrdTraVia"));
+            createTaskVo.setDestinationAddress(getStringValue(order, "ServiceOrdTraEnd"));
+            
+            // 璁剧疆浠锋牸鍜岃窛绂讳俊鎭�
+            createTaskVo.setPrice(getBigDecimalValue(order, "ServiceOrdTraTxnPrice"));
+            // 璺濈淇℃伅闇�瑕佷粠鍏朵粬瀛楁璁$畻鎴栬幏鍙�
+            
+            // 璁剧疆鎵ц浜轰俊鎭�
+            List<TaskCreateVO.AssigneeInfo> assignees = queryAssignees(dispatchOrdID);
+            createTaskVo.setAssignees(assignees);
+            
+            // 璁剧疆杞﹁締淇℃伅
+            // 杞﹁締ID闇�瑕佹牴鎹瓺ispatchOrdCarID鏌ヨ鑾峰彇
+            String carID = getStringValue(order, "DispatchOrdCarID");
+            if (StringUtils.isNotEmpty(carID)) {
+                String carLicense = legacyTransferSyncMapper.selectCarLicenseByCarID(carID);
+                if (StringUtils.isNotEmpty(carLicense)) {
+                    // 鏍规嵁杞︾墝鍙锋煡璇㈡柊绯荤粺涓殑杞﹁締ID
+                    log.debug("杞﹁締杞︾墝鍙�: {}", carLicense);
+                    
+                    // 棣栧厛灏濊瘯閫氳繃VehicleInfoMapper鏌ヨ杞﹁締淇℃伅
+                    try {
+                        // 鍏堝皾璇曢�氳繃car_id鏌ヨ杞﹁締淇℃伅
+                        Integer carIdInt = Integer.valueOf(carID);
+                        VehicleInfo vehicleInfo = vehicleInfoMapper.selectVehicleInfoByCarId(carIdInt);
+                        if (vehicleInfo != null && vehicleInfo.getVehicleId() != null) {
+                            // 璁剧疆杞﹁締ID鍒楄〃
+                            List<Long> vehicleIds = new ArrayList<>();
+                            vehicleIds.add(vehicleInfo.getVehicleId());
+                            createTaskVo.setVehicleIds(vehicleIds);
+                            log.debug("閫氳繃car_id鎵惧埌杞﹁締淇℃伅: vehicle_id={}, vehicle_no={}", vehicleInfo.getVehicleId(), vehicleInfo.getVehicleNo());
+                        } else {
+                            // 濡傛灉閫氳繃car_id鎵句笉鍒帮紝灏濊瘯閫氳繃杞︾墝鍙锋煡璇�
+                            vehicleInfo = vehicleInfoMapper.selectVehicleInfoByVehicleNo(carLicense);
+                            if (vehicleInfo != null && vehicleInfo.getVehicleId() != null) {
+                                List<Long> vehicleIds = new ArrayList<>();
+                                vehicleIds.add(vehicleInfo.getVehicleId());
+                                createTaskVo.setVehicleIds(vehicleIds);
+                                log.debug("閫氳繃杞︾墝鍙锋壘鍒拌溅杈嗕俊鎭�: vehicle_id={}, vehicle_no={}", vehicleInfo.getVehicleId(), vehicleInfo.getVehicleNo());
+                            } else {
+                                log.warn("鏈壘鍒板搴旂殑杞﹁締淇℃伅: car_id={}, vehicle_no={}", carID, carLicense);
+                            }
+                        }
+                    } catch (NumberFormatException e) {
+                        log.warn("carID涓嶆槸鏈夋晥鏁板瓧: {}", carID);
+                        // 濡傛灉carID涓嶆槸鏁板瓧锛岀洿鎺ラ�氳繃杞︾墝鍙锋煡璇�
+                        VehicleInfo vehicleInfo = vehicleInfoMapper.selectVehicleInfoByVehicleNo(carLicense);
+                        if (vehicleInfo != null && vehicleInfo.getVehicleId() != null) {
+                            List<Long> vehicleIds = new ArrayList<>();
+                            vehicleIds.add(vehicleInfo.getVehicleId());
+                            createTaskVo.setVehicleIds(vehicleIds);
+                            log.debug("閫氳繃杞︾墝鍙锋壘鍒拌溅杈嗕俊鎭�: vehicle_id={}, vehicle_no={}", vehicleInfo.getVehicleId(), vehicleInfo.getVehicleNo());
+                        } else {
+                            log.warn("鏈壘鍒板搴旂殑杞﹁締淇℃伅: vehicle_no={}", carLicense);
+                        }
+                    }
+                }
+            }
+            
+
+            // 璁剧疆鍏朵粬淇℃伅
+            createTaskVo.setTaskDescription("浠庢棫绯荤粺鍚屾鐨勮浆杩愬崟");
+            
+            // 璁剧疆澶囨敞淇℃伅
+            String remark = "鏈嶅姟鍗旾D: " + serviceOrdID + ", 璋冨害鍗旾D: " + dispatchOrdID;
+            String serviceOrdCoTies = getStringValue(order, "ServiceOrdCoTies");
+            if (StringUtils.isNotEmpty(serviceOrdCoTies)) {
+                remark += ", 鑱旂郴浜哄叧绯�: " + serviceOrdCoTies;
+            }
+            createTaskVo.setRemark(remark);
+            
+            // 璁剧疆璁″垝寮�濮嬫椂闂�
+            Date plannedStartTime = getDateValue(order, "ServiceOrdApptDate");
+            if (plannedStartTime != null) {
+                createTaskVo.setPlannedStartTime(plannedStartTime);
+            }
+
+            Date actualStartTime = getDateValue(order, "DispatchOrdActualDate");
+            if (actualStartTime != null) {
+                createTaskVo.setActualStartTime(actualStartTime);
+            }
+
+            Date actualEndTime = getDateValue(order, "DispatchOrdReturnDate");
+            if (actualEndTime != null) {
+                createTaskVo.setActualEndTime(actualEndTime);
+            }
+
+
+            
+            // 璁剧疆鍒涘缓鏃堕棿
+            Date createTime = getDateValue(order, "ServiceOrd_CC_Time");
+            if (createTime != null) {
+                createTaskVo.setCreateTime(createTime);
+            }
+            
+            // 鏌ヨ骞惰缃梾鎯呬俊鎭�
+            String diseaseIdsStr = queryDiseaseIds(serviceOrdID);
+            if (StringUtils.isNotEmpty(diseaseIdsStr)) {
+                String[] diseaseIdArray = diseaseIdsStr.split(",");
+                List<Long> diseaseIds = new ArrayList<>();
+                for (String diseaseId : diseaseIdArray) {
+                    try {
+                        diseaseIds.add(Long.valueOf(diseaseId.trim()));
+                    } catch (NumberFormatException e) {
+                        log.warn("鏃犳晥鐨勭柧鐥匢D: {}", diseaseId);
+                    }
+                }
+                createTaskVo.setDiseaseIds(diseaseIds);
+            }
+            
+            log.info("TaskCreateVO鏋勯�犲畬鎴�: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID);
+            return createTaskVo;
+            
+        } catch (Exception e) {
+            log.error("鏋勯�燭askCreateVO寮傚父: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID, e);
+            return null;
+        }
+    }
+    
+    /**
+     * 鏌ヨ鎵ц浜轰俊鎭�
+     * 
+     * @param dispatchOrdID 璋冨害鍗旾D
+     * @return 鎵ц浜轰俊鎭垪琛�
+     */
+    private List<TaskCreateVO.AssigneeInfo> queryAssignees(String dispatchOrdID) {
+        try {
+            // 妫�鏌ュ弬鏁版湁鏁堟��
+            if (StringUtils.isEmpty(dispatchOrdID)) {
+                log.warn("璋冨害鍗旾D涓嶈兘涓虹┖");
+                return new ArrayList<>();
+            }
+            
+            // 浠嶴QL Server鏌ヨ鎵ц浜轰俊鎭�
+            List<Map<String, Object>> assigneeList = legacyTransferSyncMapper.selectAssigneesByDispatchOrdID(dispatchOrdID);
+            
+            // 杞崲涓篢askCreateVO.AssigneeInfo瀵硅薄
+            List<TaskCreateVO.AssigneeInfo> assignees = new ArrayList<>();
+            if (assigneeList != null && !assigneeList.isEmpty()) {
+                for (Map<String, Object> assigneeMap : assigneeList) {
+                    String entourageOAId = getStringValue(assigneeMap, "EntourageOAId");
+                    String entourageState = getStringValue(assigneeMap, "EntourageState");
+                    
+                    if (StringUtils.isNotEmpty(entourageOAId)) {
+                        try {
+                            // 灏哋A鐢ㄦ埛ID杞崲涓虹郴缁熺敤鎴稩D
+                            Integer oaUserId = Integer.valueOf(entourageOAId);
+                            SysUser sysUser = sysUserService.selectUserByOaUserId(oaUserId);
+                            
+                            if (sysUser != null) {
+                                TaskCreateVO.AssigneeInfo assigneeInfo = new TaskCreateVO.AssigneeInfo();
+                                assigneeInfo.setUserId(sysUser.getUserId()); // 浣跨敤绯荤粺鐢ㄦ埛ID
+                                assigneeInfo.setUserName(sysUser.getUserName());
+                                // 鏍规嵁EntourageState纭畾瑙掕壊绫诲瀷
+                                // 1,2 鍙告満锛�3,5 鍖荤敓锛�4,6 鎶ゅ+
+                                if ("1".equals(entourageState) || "2".equals(entourageState)) {
+                                    assigneeInfo.setUserType("driver");
+                                } else if ("3".equals(entourageState) || "5".equals(entourageState)) {
+                                    assigneeInfo.setUserType("doctor");
+                                } else if ("4".equals(entourageState) || "6".equals(entourageState)) {
+                                    assigneeInfo.setUserType("nurse");
+                                } else {
+                                    assigneeInfo.setUserType("other");
+                                }
+                                
+                                assignees.add(assigneeInfo);
+                            } else {
+                                log.warn("鏈壘鍒板搴旂殑绯荤粺鐢ㄦ埛: OA鐢ㄦ埛ID={}", oaUserId);
+                            }
+                        } catch (NumberFormatException e) {
+                            log.warn("鎵ц浜篛A ID涓嶆槸鏈夋晥鏁板瓧: {}", entourageOAId);
+                        }
+                    }
+                }
+            }
+            
+            log.info("鏌ヨ鍒皗}涓墽琛屼汉锛岃皟搴﹀崟ID: {}", assignees.size(), dispatchOrdID);
+            return assignees;
+        } catch (Exception e) {
+            log.error("鏌ヨ鎵ц浜轰俊鎭紓甯革紝璋冨害鍗旾D: {}", dispatchOrdID, e);
+            return new ArrayList<>(); // 杩斿洖绌哄垪琛ㄨ�屼笉鏄痭ull
+        }
+    }
+    
+    /**
+     * 鏌ヨ鐥呮儏淇℃伅
+     * 
+     * @param serviceOrdID 鏈嶅姟鍗旾D
+     * @return 鐥呮儏ID鍒楄〃
+     */
+    private String queryDiseaseIds(String serviceOrdID) {
+        try {
+            // 妫�鏌ュ弬鏁版湁鏁堟��
+            if (StringUtils.isEmpty(serviceOrdID)) {
+                log.warn("鏈嶅姟鍗旾D涓嶈兘涓虹┖");
+                return null;
+            }
+            
+            // 浠嶴QL Server鏌ヨ鐥呮儏淇℃伅
+            List<String> diseaseIds = legacyTransferSyncMapper.selectDiseaseIdsByServiceOrdID(serviceOrdID);
+            
+            // 杞崲涓洪�楀彿鍒嗛殧鐨勫瓧绗︿覆
+            if (diseaseIds != null && !diseaseIds.isEmpty()) {
+                return String.join(",", diseaseIds);
+            }
+            
+            log.info("鏌ヨ鍒扮梾鎯呬俊鎭紝鏈嶅姟鍗旾D: {}, 鐥呮儏鏁伴噺: {}", serviceOrdID, diseaseIds != null ? diseaseIds.size() : 0);
+            return null;
+        } catch (Exception e) {
+            log.error("鏌ヨ鐥呮儏淇℃伅寮傚父锛屾湇鍔″崟ID: {}", serviceOrdID, e);
+            return null;
+        }
+    }
+    
+    /**
+     * 浠嶮ap涓幏鍙栧瓧绗︿覆鍊�
+     * 
+     * @param map Map瀵硅薄
+     * @param key 閿�
+     * @return 瀛楃涓插��
+     */
+    private String getStringValue(Map<String, Object> map, String key) {
+        Object value = map.get(key);
+        return value != null ? value.toString() : null;
+    }
+    
+    /**
+     * 浠嶮ap涓幏鍙朆igDecimal鍊�
+     * 
+     * @param map Map瀵硅薄
+     * @param key 閿�
+     * @return BigDecimal鍊�
+     */
+    private BigDecimal getBigDecimalValue(Map<String, Object> map, String key) {
+        Object value = map.get(key);
+        if (value == null) {
+            return null;
+        }
+        if (value instanceof BigDecimal) {
+            return (BigDecimal) value;
+        }
+        try {
+            return new BigDecimal(value.toString());
+        } catch (NumberFormatException e) {
+            return null;
+        }
+    }
+    
+    /**
+     * 浠嶮ap涓幏鍙朙ong鍊�
+     * 
+     * @param map Map瀵硅薄
+     * @param key 閿�
+     * @return Long鍊�
+     */
+    private Long getLongValue(Map<String, Object> map, String key) {
+        Object value = map.get(key);
+        if (value == null) {
+            return null;
+        }
+        if (value instanceof Long) {
+            return (Long) value;
+        }
+        try {
+            return Long.valueOf(value.toString());
+        } catch (NumberFormatException e) {
+            return null;
+        }
+    }
+    private Integer getIntegerValue(Map<String, Object> map, String key) {
+        Object value = map.get(key);
+        if (value == null) {
+            return null;
+        }
+        if (value instanceof Integer) {
+            return (Integer) value;
+        }
+        try {
+            return Integer.valueOf(value.toString());
+        } catch (NumberFormatException e) {
+            return null;
+        }
+    }
+    /**
+     * 浠嶮ap涓幏鍙朌ate鍊�
+     * 
+     * @param map Map瀵硅薄
+     * @param key 閿�
+     * @return Date鍊�
+     */
+    private Date getDateValue(Map<String, Object> map, String key) {
+        Object value = map.get(key);
+        if (value == null) {
+            return null;
+        }
+        if (value instanceof Date) {
+            return (Date) value;
+        }
+        // 濡傛灉鏄瓧绗︿覆锛屽皾璇曡В鏋�
+        if (value instanceof String) {
+            try {
+                return DateUtils.parseDate(value.toString());
+            } catch (Exception e) {
+                return null;
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * 楠岃瘉鏃ユ湡瀛楃涓叉牸寮忔槸鍚︽湁鏁�
+     * 
+     * @param dateStr 鏃ユ湡瀛楃涓�
+     * @param format 鏃ユ湡鏍煎紡
+     * @return 鏄惁鏈夋晥
+     */
+    private boolean isValidDateFormat(String dateStr, String format) {
+        if (StringUtils.isEmpty(dateStr)) {
+            return false;
+        }
+        
+        try {
+            SimpleDateFormat sdf = new SimpleDateFormat(format);
+            sdf.setLenient(false);
+            sdf.parse(dateStr);
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
index f990c3c..d4aac64 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
@@ -428,4 +428,16 @@
         
         return result;
     }
+    
+    /**
+     * 鏍规嵁service_class鏌ヨ閮ㄩ棬淇℃伅
+     * 
+     * @param serviceClass 鏈嶅姟绫诲埆缂栫爜
+     * @return 閮ㄩ棬淇℃伅
+     */
+    @Override
+    public SysDept selectDeptByServiceClass(String serviceClass)
+    {
+        return deptMapper.selectDeptByServiceClass(serviceClass);
+    }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java
index 796b509..7e28b71 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java
@@ -142,6 +142,7 @@
     @Override
     @Transactional
     public int insertSysTask(TaskCreateVO createVO) {
+        String username = SecurityUtils.getUsername();
         SysTask task = new SysTask();
         task.setTaskCode(generateTaskCode());
         task.setTaskType(createVO.getTaskType());
@@ -153,9 +154,9 @@
         task.setCreatorId(SecurityUtils.getUserId());
         // 浼樺厛浣跨敤鍓嶇浼犲叆鐨勯儴闂↖D锛屽鏋滄病鏈夊垯浣跨敤褰撳墠鐢ㄦ埛鐨勯儴闂↖D
         task.setDeptId(createVO.getDeptId() != null ? createVO.getDeptId() : SecurityUtils.getDeptId());
-        task.setCreateBy(SecurityUtils.getUsername());
+        task.setCreateBy(username);
         task.setCreateTime(DateUtils.getNowDate());
-        task.setUpdateBy(SecurityUtils.getUsername());
+        task.setUpdateBy(username);
         task.setUpdateTime(DateUtils.getNowDate());
         task.setRemark(createVO.getRemark());
         task.setDelFlag("0");
@@ -228,17 +229,17 @@
         
         // 淇濆瓨鎵ц浜哄憳淇℃伅锛堝寘鍚鑹茬被鍨嬶級
         if (result > 0 && createVO.getAssignees() != null && !createVO.getAssignees().isEmpty()) {
-            saveTaskAssignees(task.getTaskId(), createVO.getAssignees());
+            saveTaskAssignees(task.getTaskId(), createVO.getAssignees(),username);
         }
         
         // 淇濆瓨鎬ユ晳杞繍鎵╁睍淇℃伅
         if (result > 0 && "EMERGENCY_TRANSFER".equals(createVO.getTaskType())) {
-            saveEmergencyInfo(task.getTaskId(), createVO);
+            saveEmergencyInfo(task.getTaskId(),username, createVO,null,null);
         }
         
         // 淇濆瓨绂忕杞︽墿灞曚俊鎭�
         if (result > 0 && "WELFARE".equals(createVO.getTaskType())) {
-            saveWelfareInfo(task.getTaskId(), createVO);
+            saveWelfareInfo(task.getTaskId(),SecurityUtils.getUsername(), createVO);
         }
         
         // 璁板綍鎿嶄綔鏃ュ織
@@ -291,6 +292,170 @@
                 }
             }).start();
         }
+        
+        return result;
+    }
+
+    /**
+     * 鏂板浠诲姟绠$悊锛堝厑璁镐粠澶栭儴浼犲叆鐢ㄦ埛淇℃伅銆侀儴闂ㄤ俊鎭拰鏃堕棿淇℃伅锛�
+     * 
+     * @param createVO 浠诲姟鍒涘缓瀵硅薄
+     * @param userId 鐢ㄦ埛ID
+     * @param deptId 閮ㄩ棬ID
+     * @param createTime 鍒涘缓鏃堕棿
+     * @param updateTime 鏇存柊鏃堕棿
+     * @return 缁撴灉
+     */
+    @Override
+    @Transactional
+    public int insertTask(TaskCreateVO createVO,String serviceOrderId,String dispatchOrderId, Long userId,String userName, Long deptId, Date createTime, Date updateTime) {
+        SysTask task = new SysTask();
+        if(createVO.getTaskCode()!=null){
+            task.setTaskCode(createVO.getTaskCode());
+        }else{
+            task.setTaskCode(generateTaskCode());
+        }
+        task.setTaskType(createVO.getTaskType());
+        task.setTaskStatus(TaskStatus.PENDING.getCode());
+        task.setTaskDescription(createVO.getTaskDescription());
+        task.setPlannedStartTime(createVO.getPlannedStartTime());
+        task.setPlannedEndTime(createVO.getPlannedEndTime());
+        task.setActualStartTime(createVO.getActualStartTime());
+        task.setActualEndTime(createVO.getActualEndTime());
+        task.setAssigneeId(createVO.getAssigneeId());
+        // 浣跨敤澶栭儴浼犲叆鐨勭敤鎴稩D鍜岄儴闂↖D
+        task.setCreatorId(userId);
+        task.setDeptId(deptId);
+        task.setCreateBy(userName);
+        // 浣跨敤澶栭儴浼犲叆鐨勫垱寤烘椂闂村拰鏇存柊鏃堕棿
+        task.setCreateTime(createTime);
+        task.setUpdateTime(updateTime);
+        task.setUpdateBy(userName);
+        task.setRemark(createVO.getRemark());
+        task.setDelFlag("0");
+
+
+        
+        // 璁剧疆閫氱敤鍦板潃鍜屽潗鏍囦俊鎭�
+        if (createVO.getDepartureAddress() != null) {
+            task.setDepartureAddress(createVO.getDepartureAddress());
+        }
+        if (createVO.getDestinationAddress() != null) {
+            task.setDestinationAddress(createVO.getDestinationAddress());
+        }
+        if (createVO.getDepartureLongitude() != null) {
+            task.setDepartureLongitude(createVO.getDepartureLongitude());
+        }
+        if (createVO.getDepartureLatitude() != null) {
+            task.setDepartureLatitude(createVO.getDepartureLatitude());
+        }
+        if (createVO.getDestinationLongitude() != null) {
+            task.setDestinationLongitude(createVO.getDestinationLongitude());
+        }
+        if (createVO.getDestinationLatitude() != null) {
+            task.setDestinationLatitude(createVO.getDestinationLatitude());
+        }
+        if (createVO.getEstimatedDistance() != null) {
+            task.setEstimatedDistance(createVO.getEstimatedDistance());
+        }
+        
+        // 璁剧疆鎬ユ晳杞繍鐗瑰畾淇℃伅
+        if (createVO.getTransferTime() != null) {
+            task.setPlannedStartTime(createVO.getTransferTime());
+        }
+        if (createVO.getTransferDistance() != null) {
+            task.setEstimatedDistance(createVO.getTransferDistance());
+        }
+        
+        // 璁剧疆绂忕杞︾壒瀹氫俊鎭�
+        if (createVO.getPlannedStartTime() != null) {
+            task.setPlannedStartTime(createVO.getPlannedStartTime());
+        }
+        if (createVO.getStartAddress() != null) {
+            task.setDepartureAddress(createVO.getStartAddress());
+        }
+        if (createVO.getEndAddress() != null) {
+            task.setDestinationAddress(createVO.getEndAddress());
+        }
+        // 璁剧疆绂忕杞﹀叕閲屾暟
+        if (createVO.getDistance() != null) {
+            task.setEstimatedDistance(createVO.getDistance());
+        }
+        
+        int result = sysTaskMapper.insertSysTask(task);
+        
+        // 淇濆瓨杞﹁締鍏宠仈淇℃伅
+        if (result > 0 && createVO.getVehicleIds() != null && !createVO.getVehicleIds().isEmpty()) {
+            for (Long vehicleId : createVO.getVehicleIds()) {
+                SysTaskVehicle taskVehicle = new SysTaskVehicle();
+                taskVehicle.setTaskId(task.getTaskId());
+                taskVehicle.setVehicleId(vehicleId);
+                taskVehicle.setAssignTime(updateTime);
+                taskVehicle.setAssignBy(userName);
+                taskVehicle.setStatus("ASSIGNED");
+                taskVehicle.setCreateBy(userName);
+                taskVehicle.setCreateTime(createTime);
+                taskVehicle.setUpdateBy(userName);
+                taskVehicle.setUpdateTime(updateTime);
+                
+                sysTaskVehicleMapper.insertSysTaskVehicle(taskVehicle);
+            }
+        }
+        
+        // 淇濆瓨鎵ц浜哄憳淇℃伅锛堝寘鍚鑹茬被鍨嬶級
+        if (result > 0 && createVO.getAssignees() != null && !createVO.getAssignees().isEmpty()) {
+            saveTaskAssignees(task.getTaskId(), createVO.getAssignees(),userName);
+        }
+        
+        // 淇濆瓨鎬ユ晳杞繍鎵╁睍淇℃伅
+        if (result > 0 && "EMERGENCY_TRANSFER".equals(createVO.getTaskType())) {
+            saveEmergencyInfo(task.getTaskId(),userName, createVO, serviceOrderId, dispatchOrderId);
+        }
+        
+        // 淇濆瓨绂忕杞︽墿灞曚俊鎭�
+        if (result > 0 && "WELFARE".equals(createVO.getTaskType())) {
+            saveWelfareInfo(task.getTaskId(),userName, createVO);
+        }
+        
+        // 璁板綍鎿嶄綔鏃ュ織
+        if (result > 0) {
+            recordTaskLog(task.getTaskId(), "CREATE", "鍒涘缓浠诲姟", null, 
+                         "浠诲姟绫诲瀷锛�" + createVO.getTaskType(), userId, userName);
+        }
+        
+        // 鍙戝竷浠诲姟鍒涘缓浜嬩欢
+        if (result > 0) {
+            eventPublisher.publishEvent(new TaskCreatedEvent(
+                this,
+                task.getTaskId(),
+                task.getTaskCode(),
+                task.getTaskType(),
+                userId,
+                userName
+            ));
+        }
+        
+        // 鍙戝竷浠诲姟鍒嗛厤浜嬩欢
+        if (result > 0 && createVO.getAssignees() != null && !createVO.getAssignees().isEmpty()) {
+            List<Long> assigneeIds = createVO.getAssignees().stream()
+                .map(assignee -> assignee.getUserId())
+                .collect(Collectors.toList());
+            List<String> assigneeNames = createVO.getAssignees().stream()
+                .map(assignee -> assignee.getUserName())
+                .collect(Collectors.toList());
+            
+            eventPublisher.publishEvent(new TaskAssignedEvent(
+                this,
+                task.getTaskId(),
+                task.getTaskCode(),
+                assigneeIds,
+                assigneeNames,
+                userId,
+                userName
+            ));
+        }
+        
+
         
         return result;
     }
@@ -973,6 +1138,70 @@
         return sysTaskMapper.selectActiveTasksByVehicleId(vehicleId);
     }
 
+    /**
+     * 妫�鏌ヤ换鍔℃槸鍚﹀凡鍏宠仈鏃х郴缁熸湇鍔″崟ID
+     * 
+     * @param taskId 浠诲姟ID
+     * @return true-宸插叧鑱旓紝false-鏈叧鑱�
+     */
+    @Override
+    public boolean hasLegacyServiceOrdId(Long taskId) {
+        // 鍙湁鎬ユ晳杞繍浠诲姟鎵嶆湁鏃х郴缁烮D
+        SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId);
+        if (task != null && "EMERGENCY_TRANSFER".equals(task.getTaskType())) {
+            SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId);
+            return emergencyInfo != null && emergencyInfo.getLegacyServiceOrdId() != null;
+        }
+        return false;
+    }
+
+    /**
+     * 妫�鏌ヤ换鍔℃槸鍚﹀凡鍏宠仈鏃х郴缁熻皟搴﹀崟ID
+     * 
+     * @param taskId 浠诲姟ID
+     * @return true-宸插叧鑱旓紝false-鏈叧鑱�
+     */
+    @Override
+    public boolean hasLegacyDispatchOrdId(Long taskId) {
+        // 鍙湁鎬ユ晳杞繍浠诲姟鎵嶆湁鏃х郴缁烮D
+        SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId);
+        if (task != null && "EMERGENCY_TRANSFER".equals(task.getTaskType())) {
+            SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId);
+            return emergencyInfo != null && emergencyInfo.getLegacyDispatchOrdId() != null;
+        }
+        return false;
+    }
+
+    /**
+     * 鏍规嵁鏃х郴缁熸湇鍔″崟ID妫�鏌ユ槸鍚﹀瓨鍦ㄤ换鍔�
+     * 
+     * @param legacyServiceOrdId 鏃х郴缁熸湇鍔″崟ID
+     * @return true-瀛樺湪锛宖alse-涓嶅瓨鍦�
+     */
+    @Override
+    public boolean existsByLegacyServiceOrdId(Long legacyServiceOrdId) {
+        if (legacyServiceOrdId == null) {
+            return false;
+        }
+        SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectByLegacyServiceOrdId(legacyServiceOrdId);
+        return emergencyInfo != null;
+    }
+
+    /**
+     * 鏍规嵁鏃х郴缁熻皟搴﹀崟ID妫�鏌ユ槸鍚﹀瓨鍦ㄤ换鍔�
+     * 
+     * @param legacyDispatchOrdId 鏃х郴缁熻皟搴﹀崟ID
+     * @return true-瀛樺湪锛宖alse-涓嶅瓨鍦�
+     */
+    @Override
+    public boolean existsByLegacyDispatchOrdId(Long legacyDispatchOrdId) {
+        if (legacyDispatchOrdId == null) {
+            return false;
+        }
+        SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectByLegacyDispatchOrdId(legacyDispatchOrdId);
+        return emergencyInfo != null;
+    }
+
     @Autowired
     private TaskCodeGenerator taskCodeGenerator;
     
@@ -1105,14 +1334,14 @@
      * @param taskId 浠诲姟ID
      * @param assignees 鎵ц浜哄憳淇℃伅鍒楄〃
      */
-    private void saveTaskAssignees(Long taskId, java.util.List<TaskCreateVO.AssigneeInfo> assignees) {
+    private void saveTaskAssignees(Long taskId, java.util.List<TaskCreateVO.AssigneeInfo> assignees,String userName) {
         if (assignees == null || assignees.isEmpty()) {
             return;
         }
         
         java.util.List<SysTaskAssignee> taskAssignees = new java.util.ArrayList<>();
         Date now = DateUtils.getNowDate();
-        String currentUser = SecurityUtils.getUsername();
+        String currentUser = userName;
         
         for (int i = 0; i < assignees.size(); i++) {
             TaskCreateVO.AssigneeInfo assigneeInfo = assignees.get(i);
@@ -1145,7 +1374,7 @@
      * @param taskId 浠诲姟ID
      * @param createVO 浠诲姟鍒涘缓瀵硅薄
      */
-    private void saveEmergencyInfo(Long taskId, TaskCreateVO createVO) {
+    private void saveEmergencyInfo(Long taskId,String createUserName, TaskCreateVO createVO,String serviceOrderId,String dispatchOrderId) {
         SysTaskEmergency emergencyInfo = new SysTaskEmergency();
         emergencyInfo.setTaskId(taskId);
         
@@ -1200,12 +1429,26 @@
                 .collect(Collectors.joining(","));
             emergencyInfo.setDiseaseIds(diseaseIdsStr);
         }
-        
+
+        if(serviceOrderId!=null){
+            emergencyInfo.setLegacyServiceOrdId(Long.parseLong(serviceOrderId));
+            emergencyInfo.setSyncStatus(2);
+            emergencyInfo.setSyncTime(new Date());
+            emergencyInfo.setSyncErrorMsg("鏃х郴缁熷悓姝ヨ繃鏉�");
+        }
+        if(dispatchOrderId!=null){
+            emergencyInfo.setLegacyDispatchOrdId(Long.parseLong(dispatchOrderId));
+            emergencyInfo.setDispatchSyncStatus(2);
+            emergencyInfo.setDispatchSyncTime(new Date());
+            emergencyInfo.setDispatchSyncErrorMsg("鏃х郴缁熷悓姝ヨ繃鏉�");
+
+        // 绯荤粺瀛楁
+        }
         // 绯荤粺瀛楁
         emergencyInfo.setCreateTime(DateUtils.getNowDate());
         emergencyInfo.setUpdateTime(DateUtils.getNowDate());
-        emergencyInfo.setCreateBy(SecurityUtils.getUsername());
-        emergencyInfo.setUpdateBy(SecurityUtils.getUsername());
+        emergencyInfo.setCreateBy(createUserName);
+        emergencyInfo.setUpdateBy(createUserName);
         
         sysTaskEmergencyMapper.insertSysTaskEmergency(emergencyInfo);
     }
@@ -1216,7 +1459,7 @@
      * @param taskId 浠诲姟ID
      * @param createVO 浠诲姟鍒涘缓瀵硅薄
      */
-    private void saveWelfareInfo(Long taskId, TaskCreateVO createVO) {
+    private void saveWelfareInfo(Long taskId,String userName, TaskCreateVO createVO) {
         SysTaskWelfare welfareInfo = new SysTaskWelfare();
         welfareInfo.setTaskId(taskId);
         
@@ -1245,8 +1488,8 @@
         // 绯荤粺瀛楁
         welfareInfo.setCreateTime(DateUtils.getNowDate());
         welfareInfo.setUpdateTime(DateUtils.getNowDate());
-        welfareInfo.setCreateBy(SecurityUtils.getUsername());
-        welfareInfo.setUpdateBy(SecurityUtils.getUsername());
+        welfareInfo.setCreateBy(userName);
+        welfareInfo.setUpdateBy(userName);
         
         sysTaskWelfareMapper.insertSysTaskWelfare(welfareInfo);
     }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
index a302044..90b745b 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
@@ -151,6 +151,18 @@
     {
         return userMapper.selectUserByOpenId(openId);
     }
+    
+    /**
+     * 鏍规嵁oaUserId鏌ヨ鐢ㄦ埛
+     * 
+     * @param oaUserId SQL Server涓殑OA鐢ㄦ埛ID
+     * @return 鐢ㄦ埛淇℃伅
+     */
+    @Override
+    public SysUser selectUserByOaUserId(Integer oaUserId)
+    {
+        return userMapper.selectUserByOaUserId(oaUserId);
+    }
 
     /**
      * 鏌ヨ鐢ㄦ埛鎵�灞炶鑹茬粍
diff --git a/ruoyi-system/src/main/resources/mapper/system/LegacyTransferSyncMapper.xml b/ruoyi-system/src/main/resources/mapper/system/LegacyTransferSyncMapper.xml
new file mode 100644
index 0000000..7905aa7
--- /dev/null
+++ b/ruoyi-system/src/main/resources/mapper/system/LegacyTransferSyncMapper.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.system.mapper.LegacyTransferSyncMapper">
+    
+    <!-- 杞繍鍗曠粨鏋滄槧灏� -->
+    <resultMap type="java.util.HashMap" id="TransferOrderResult">
+        <result property="ServiceOrdID" column="ServiceOrdID" />
+        <result property="ServiceOrdUserID" column="ServiceOrdUserID" />
+        <result property="ServiceOrdAreaType" column="ServiceOrdAreaType" />
+        <result property="ServiceOrdType" column="ServiceOrdType" />
+        <result property="ServiceOrdTraTxnPrice" column="ServiceOrdTraTxnPrice" />
+        <result property="ServiceOrdPtOutHospID" column="ServiceOrdPtOutHospID" />
+        <result property="ServiceOrdPtServicesID" column="ServiceOrdPtServicesID" />
+        <result property="ServiceOrdPtInHospID" column="ServiceOrdPtInHospID" />
+        <result property="ServiceOrdPtInServicesID" column="ServiceOrdPtInServicesID" />
+        <result property="ServiceOrdCoTies" column="ServiceOrdCoTies" />
+        <result property="ServiceOrdCoName" column="ServiceOrdCoName" />
+        <result property="ServiceOrdCoPhone" column="ServiceOrdCoPhone" />
+        <result property="ServiceOrdClass" column="ServiceOrdClass" />
+        <result property="ServiceOrdTraStreet" column="ServiceOrdTraStreet" />
+        <result property="ServiceOrdTraEnd" column="ServiceOrdTraEnd" />
+        <result property="ServiceOrdPtCondition" column="ServiceOrdPtCondition" />
+        <result property="DispatchOrd_NS_Time" column="DispatchOrd_NS_Time" />
+        <result property="ServiceOrdState" column="ServiceOrdState" />
+        <result property="ServiceOrdPtIDCard" column="ServiceOrdPtIDCard" />
+        <result property="ServiceOrd_NS_ID" column="ServiceOrd_NS_ID" />
+        <result property="ServiceOrd_CC_ID" column="ServiceOrd_CC_ID" />
+        <result property="DispatchOrdTraStreet" column="DispatchOrdTraStreet" />
+        <result property="DispatchOrdStartDate" column="DispatchOrdStartDate" />
+        <result property="DispatchOrdActualDate" column="DispatchOrdActualDate" />
+        <result property="DispatchOrdReturnDate" column="DispatchOrdReturnDate" />
+        <result property="DispatchOrdTraEnd" column="DispatchOrdTraEnd" />
+        <result property="DispatchOrdID" column="DispatchOrdID" />
+        <result property="DispatchOrdCarID" column="DispatchOrdCarID" />
+        <result property="ServiceOrdPtName" column="ServiceOrdPtName" />
+        <result property="ServiceOrdPtServices" column="ServiceOrdPtServices" />
+        <result property="ServiceOrdPtInServices" column="ServiceOrdPtInServices" />
+        <result property="ServiceOrdPtSex" column="ServiceOrdPtSex" />
+        <result property="ServiceOrdTraVia" column="ServiceOrdTraVia" />
+        <result property="Old_ServiceOrdID_TXT" column="Old_ServiceOrdID_TXT" />
+        <result property="ServiceOrdTraDistance" column="ServiceOrdTraDistance" />
+        <result property="ServiceOrdApptDate" column="ServiceOrdApptDate" />
+    </resultMap>
+    
+    <!-- 鎵ц浜虹粨鏋滄槧灏� -->
+    <resultMap type="java.util.HashMap" id="AssigneeResult">
+        <result property="EntourageOAId" column="EntourageOAId" />
+        <result property="EntourageState" column="EntourageState" />
+    </resultMap>
+    
+    <!-- 鏌ヨ鎸囧畾鏃ユ湡鑼冨洿鐨勮浆杩愬崟鏁版嵁 -->
+    <select id="selectTransferOrders" resultMap="TransferOrderResult">
+        SELECT 
+            a.ServiceOrdID,
+            a.Old_ServiceOrdID_TXT,
+            a.ServiceOrdTraVia,
+            a.ServiceOrdApptDate,
+            a.ServiceOrd_NS_ID,
+            a.ServiceOrd_CC_ID,
+            a.ServiceOrd_CC_Time,
+            a.ServiceOrdPtSex,
+            a.ServiceOrdAreaType,
+            a.ServiceOrdType,
+            a.ServiceOrdTraTxnPrice,
+            a.ServiceOrdPtOutHospID,
+            a.ServiceOrdPtServicesID,
+            a.ServiceOrdPtInHospID,
+            a.ServiceOrdPtInServicesID,
+            a.ServiceOrdCoTies,
+            a.ServiceOrdCoName,
+            a.ServiceOrdTraDistance,
+            a.ServiceOrdCoPhone,
+            a.ServiceOrdClass,
+            a.ServiceOrdTraStreet,
+            a.ServiceOrdTraEnd,
+            a.ServiceOrdPtCondition,
+            b.DispatchOrd_NS_Time,
+            a.ServiceOrdState,
+            a.ServiceOrdPtIDCard,
+            b.DispatchOrdTraStreet,
+            b.DispatchOrdStartDate,
+            b.DispatchOrdActualDate,
+            b.DispatchOrdReturnDate,
+            b.DispatchOrdTraEnd,
+            b.DispatchOrdID,
+            b.DispatchOrdCarID,
+            a.ServiceOrdPtServices,
+            a.ServiceOrdPtInServices,
+            a.ServiceOrdPtName
+        FROM ServiceOrder as a 
+        INNER JOIN DispatchOrd b on a.ServiceOrdID = b.ServiceOrdIDDt
+        WHERE a.ServiceOrdState = 3 
+            AND a.ServiceOrd_CC_Time > #{startDate} 
+            AND b.DispatchOrdState != 0
+    </select>
+    
+    <!-- 鏍规嵁鏈嶅姟鍗旾D鍜岃皟搴﹀崟ID鏌ヨ杞繍鍗曟暟鎹� -->
+    <select id="selectTransferOrdersByIDs" resultMap="TransferOrderResult">
+        SELECT 
+            a.ServiceOrdID,
+            a.Old_ServiceOrdID_TXT,
+            a.ServiceOrdTraVia,
+            a.ServiceOrdApptDate,
+            a.ServiceOrdUserID,
+            a.ServiceOrd_NS_ID,
+            a.ServiceOrd_CC_ID,
+            a.ServiceOrd_CC_Time,
+            a.ServiceOrdAreaType,
+            a.ServiceOrdType,
+            a.ServiceOrdPtSex,
+            a.ServiceOrdTraTxnPrice,
+            a.ServiceOrdPtOutHospID,
+            a.ServiceOrdPtServicesID,
+            a.ServiceOrdPtInHospID,
+            a.ServiceOrdPtInServicesID,
+            a.ServiceOrdCoTies,
+            a.ServiceOrdCoName,
+            a.ServiceOrdTraDistance,
+            a.ServiceOrdCoPhone,
+            a.ServiceOrdClass,
+            a.ServiceOrdTraStreet,
+            a.ServiceOrdTraEnd,
+            a.ServiceOrdPtCondition,
+            b.DispatchOrd_NS_Time,
+            a.ServiceOrdState,
+            a.ServiceOrdPtIDCard,
+            b.DispatchOrdTraStreet,
+            b.DispatchOrdStartDate,
+            b.DispatchOrdTraEnd,
+            b.DispatchOrdID,
+            b.DispatchOrdCarID,
+            a.ServiceOrdPtServices,
+            a.ServiceOrdPtInServices,
+            a.ServiceOrdPtName
+        FROM ServiceOrder as a 
+        INNER JOIN DispatchOrd b on a.ServiceOrdID = b.ServiceOrdIDDt
+        WHERE a.ServiceOrdID = #{serviceOrdID}
+            AND b.DispatchOrdID = #{dispatchOrdID}
+            AND a.ServiceOrdState = 3 
+            AND b.DispatchOrdState != 0
+    </select>
+    
+    <!-- 鏍规嵁鏈嶅姟鍗旾D鏌ヨ鐥呮儏淇℃伅 -->
+    <select id="selectDiseaseIdsByServiceOrdID" resultType="String">
+        SELECT icd_id 
+        FROM ServiceOrder_ICD 
+        WHERE ServiceOrdIDDt = #{serviceOrdID}
+    </select>
+    
+    <!-- 鏍规嵁璋冨害鍗旾D鏌ヨ鎵ц浜轰俊鎭� -->
+    <select id="selectAssigneesByDispatchOrdID" resultMap="AssigneeResult">
+        SELECT 
+            EntourageOAId,
+            EntourageState
+        FROM DispatchOrd_Entourage 
+        WHERE DispatchOrdIDDt = #{dispatchOrdID}
+    </select>
+    
+    <!-- 鏍规嵁杞﹁締ID鏌ヨ杞︾墝鍙� -->
+    <select id="selectCarLicenseByCarID" resultType="String">
+        SELECT CarLicense 
+        FROM CarData 
+        WHERE CarID = #{carID}
+    </select>
+    
+    <!-- 鏍规嵁鍖婚櫌ID鏌ヨ鍖婚櫌鍚嶇О -->
+    <select id="selectHospitalNameByHospID" resultType="String">
+        SELECT HospName 
+        FROM HospData 
+        WHERE HospID = #{hospID}
+    </select>
+    
+    <!-- 鏍规嵁绉戝ID鏌ヨ绉戝鍚嶇О -->
+    <select id="selectDepartmentNameByDeptID" resultType="String">
+        SELECT vtext 
+        FROM dictionary 
+        WHERE vID = #{deptID} AND vtitle = 'HospitalDepartment'
+    </select>
+    
+</mapper>
\ No newline at end of file
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
index f4b16dd..9b9bce3 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
@@ -221,5 +221,12 @@
 			</foreach>
 		)
 	</select>
+	
+	<!-- 鏍规嵁service_class鏌ヨ閮ㄩ棬淇℃伅 -->
+	<select id="selectDeptByServiceClass" parameterType="String" resultMap="SysDeptResult">
+		<include refid="selectDeptVo"/>
+		where d.service_order_class = #{serviceClass} and d.del_flag = '0'
+		limit 1
+	</select>
 
 </mapper> 
\ No newline at end of file
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysTaskEmergencyMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysTaskEmergencyMapper.xml
index 0eaf2d9..3318e20 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysTaskEmergencyMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysTaskEmergencyMapper.xml
@@ -285,5 +285,17 @@
             limit 200
         </if>
     </select>
+    
+    <!-- 鏍规嵁鏃х郴缁熸湇鍔″崟ID鏌ヨ鎬ユ晳杞繍浠诲姟鎵╁睍淇℃伅 -->
+    <select id="selectByLegacyServiceOrdId" parameterType="Long" resultMap="SysTaskEmergencyResult">
+        <include refid="selectSysTaskEmergencyVo"/>
+        where legacy_service_ord_id = #{legacyServiceOrdId}
+    </select>
+    
+    <!-- 鏍规嵁鏃х郴缁熻皟搴﹀崟ID鏌ヨ鎬ユ晳杞繍浠诲姟鎵╁睍淇℃伅 -->
+    <select id="selectByLegacyDispatchOrdId" parameterType="Long" resultMap="SysTaskEmergencyResult">
+        <include refid="selectSysTaskEmergencyVo"/>
+        where legacy_dispatch_ord_id = #{legacyDispatchOrdId}
+    </select>
 
 </mapper>
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml
index 338d8e2..ebc0e2d 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml
@@ -186,6 +186,10 @@
             <if test="creatorId != null">creator_id,</if>
             <if test="assigneeId != null">assignee_id,</if>
             <if test="deptId != null">dept_id,</if>
+            <if test="plannedStartTime!=null">planned_start_time,</if>
+            <if test="plannedEndTime!=null">planned_end_time,</if>
+            <if test="plannedStartTime!=null">planned_start_time,</if>
+            <if test="plannedEndTime!=null">planned_end_time,</if>
             <if test="createTime != null">create_time,</if>
             update_time,
             <if test="createBy != null">create_by,</if>
@@ -212,6 +216,10 @@
             <if test="creatorId != null">#{creatorId},</if>
             <if test="assigneeId != null">#{assigneeId},</if>
             <if test="deptId != null">#{deptId},</if>
+            <if test="plannedStartTime!=null">#{plannedStartTime},</if>
+            <if test="plannedEndTime!=null">#{plannedEndTime},</if>
+            <if test="actualStartTime!=null">#{actualStartTime},</if>
+            <if test="actualEndTime!=null">#{actualEndTime},</if>
             <if test="createTime != null">#{createTime},</if>
             now(),
             <if test="createBy != null">#{createBy},</if>
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysTaskVehicleMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysTaskVehicleMapper.xml
index 89ef050..392434d 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysTaskVehicleMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysTaskVehicleMapper.xml
@@ -27,7 +27,8 @@
                t.task_code, t.task_type
         from sys_task_vehicle tv
         left join tb_vehicle_info v on tv.vehicle_id = v.vehicle_id
-        left join sys_dept d on v.dept_id = d.dept_id
+        left join tb_vehicle_dept vd on v.vehicle_id = vd.vehicle_id
+        left join sys_dept d on vd.dept_id = d.dept_id
         left join sys_task t on tv.task_id = t.task_id
     </sql>
 
@@ -117,4 +118,4 @@
     <delete id="deleteSysTaskVehicleByTaskIdAndVehicleId">
         delete from sys_task_vehicle where task_id = #{taskId} and vehicle_id = #{vehicleId}
     </delete>
-</mapper>
+</mapper>
\ No newline at end of file
diff --git a/ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml b/ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml
index ad36af4..c80eb04 100644
--- a/ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml
@@ -137,6 +137,22 @@
         <include refid="selectVehicleInfoVo"/>
         where v.vehicle_no LIKE concat('%', #{vehicleNo}, '%')
     </select>
+    
+    <!-- 鏍规嵁鏃х郴缁熻溅杈咺D(CarID)鏌ヨ杞﹁締淇℃伅 -->
+    <select id="selectVehicleInfoByCarId" parameterType="Integer" resultMap="VehicleInfoResult">
+        <include refid="selectVehicleInfoVo"/>
+        where v.car_id = #{carId}
+    </select>
+    
+    <!-- 鏍规嵁鏃х郴缁熻溅杈咺D鏌ヨ杞﹁締淇℃伅 -->
+    <select id="selectVehicleInfoByCarID" resultType="java.util.HashMap">
+        SELECT 
+            vehicle_id,
+            car_id,
+            vehicle_no
+        FROM tb_vehicle_info 
+        WHERE car_id = #{carID}
+    </select>
         
     <insert id="insertVehicleInfo" parameterType="VehicleInfo" useGeneratedKeys="true" keyProperty="vehicleId">
         insert into tb_vehicle_info
diff --git a/ruoyi-system/src/test/java/com/ruoyi/system/mapper/SysDeptMapperTest.java b/ruoyi-system/src/test/java/com/ruoyi/system/mapper/SysDeptMapperTest.java
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ruoyi-system/src/test/java/com/ruoyi/system/mapper/SysDeptMapperTest.java
diff --git a/ruoyi-system/src/test/java/com/ruoyi/system/service/SysDeptServiceTest.java b/ruoyi-system/src/test/java/com/ruoyi/system/service/SysDeptServiceTest.java
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ruoyi-system/src/test/java/com/ruoyi/system/service/SysDeptServiceTest.java
diff --git a/ruoyi-system/src/test/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImplTest.java b/ruoyi-system/src/test/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImplTest.java
new file mode 100644
index 0000000..57031af
--- /dev/null
+++ b/ruoyi-system/src/test/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImplTest.java
@@ -0,0 +1,113 @@
+package com.ruoyi.system.service.impl;
+
+import com.ruoyi.system.domain.vo.TaskCreateVO;
+import com.ruoyi.system.service.ILegacyTransferSyncService;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@SpringBootTest
+public class LegacyTransferSyncServiceImplTest {
+
+    @Autowired
+    private ILegacyTransferSyncService legacyTransferSyncService;
+
+    @Test
+    public void testBuildCreateTaskVo() {
+        // 鍑嗗娴嬭瘯鏁版嵁
+        String serviceOrdID = "12345";
+        String dispatchOrdID = "67890";
+        
+        Map<String, Object> order = new HashMap<>();
+        order.put("ServiceOrdID", serviceOrdID);
+        order.put("DispatchOrdID", dispatchOrdID);
+        order.put("ServiceOrdPtName", "寮犱笁");
+        order.put("ServiceOrdCoPhone", "13800138000");
+        order.put("ServiceOrdPtIDCard", "110101199001011234");
+        order.put("ServiceOrdPtCondition", "鐥呮儏绋冲畾");
+        order.put("ServiceOrdCoName", "鏉庡洓");
+        order.put("ServiceOrdPtOutHospID", 1001L);
+        order.put("ServiceOrdPtServicesID", "2001");
+        order.put("ServiceOrdPtInHospID", 1002L);
+        order.put("ServiceOrdPtInServicesID", "2002");
+        order.put("ServiceOrdTraStreet", "鍖椾含甯傛湞闃冲尯鏌愭煇琛楅亾123鍙�");
+        order.put("ServiceOrdTraEnd", "鍖椾含甯傛捣娣�鍖烘煇鏌愬尰闄�");
+        order.put("ServiceOrdTraTxnPrice", "500.00");
+        order.put("ServiceOrdClass", "A001");
+        order.put("ServiceOrdType", "T001");
+        order.put("DispatchOrdStartDate", "2025-11-20 09:00:00");
+        order.put("DispatchOrd_NS_Time", "2025-11-19 14:30:00");
+        
+        // 璋冪敤鏂规硶
+        TaskCreateVO taskCreateVO = legacyTransferSyncService.buildCreateTaskVo(serviceOrdID, dispatchOrdID, order);
+        
+        // 楠岃瘉缁撴灉
+        assertNotNull(taskCreateVO);
+        assertEquals("EMERGENCY_TRANSFER", taskCreateVO.getTaskType());
+        assertEquals("浠庢棫绯荤粺鍚屾鐨勮浆杩愬崟", taskCreateVO.getTaskDescription());
+        
+        // 楠岃瘉鎮h�呬俊鎭�
+        assertNotNull(taskCreateVO.getPatient());
+        assertEquals("寮犱笁", taskCreateVO.getPatient().getName());
+        assertEquals("13800138000", taskCreateVO.getPatient().getPhone());
+        assertEquals("110101199001011234", taskCreateVO.getPatient().getIdCard());
+        assertEquals("鐥呮儏绋冲畾", taskCreateVO.getPatient().getCondition());
+        assertEquals("鏉庡洓", taskCreateVO.getPatient().getContact());
+        
+        // 楠岃瘉杞嚭鍖婚櫌淇℃伅
+        assertNotNull(taskCreateVO.getHospitalOut());
+        assertEquals(Long.valueOf(1001), taskCreateVO.getHospitalOut().getId());
+        assertEquals("2001", taskCreateVO.getHospitalOut().getDepartmentId());
+        
+        // 楠岃瘉杞叆鍖婚櫌淇℃伅
+        assertNotNull(taskCreateVO.getHospitalIn());
+        assertEquals(Long.valueOf(1002), taskCreateVO.getHospitalIn().getId());
+        assertEquals("2002", taskCreateVO.getHospitalIn().getDepartmentId());
+        
+        // 楠岃瘉鍦板潃淇℃伅
+        assertEquals("鍖椾含甯傛湞闃冲尯鏌愭煇琛楅亾123鍙�", taskCreateVO.getDepartureAddress());
+        assertEquals("鍖椾含甯傛捣娣�鍖烘煇鏌愬尰闄�", taskCreateVO.getDestinationAddress());
+        
+        // 楠岃瘉浠锋牸淇℃伅
+        assertEquals("500.00", taskCreateVO.getPrice().toString());
+        
+        // 楠岃瘉鍗曟嵁绫诲瀷鍜屼换鍔$被鍨�
+        assertEquals("A001", taskCreateVO.getDocumentTypeId());
+        assertEquals("T001", taskCreateVO.getTaskTypeId());
+        
+        // 楠岃瘉澶囨敞淇℃伅
+        assertTrue(taskCreateVO.getRemark().contains("鏈嶅姟鍗旾D: " + serviceOrdID));
+        assertTrue(taskCreateVO.getRemark().contains("璋冨害鍗旾D: " + dispatchOrdID));
+    }
+    
+    @Test
+    public void testIsTransferOrderSyncedWithInvalidParams() {
+        // 娴嬭瘯鏈嶅姟鍗旾D涓虹┖鐨勬儏鍐�
+        boolean result1 = legacyTransferSyncService.isTransferOrderSynced(null, "12345");
+        assertFalse(result1);
+        
+        // 娴嬭瘯鏈嶅姟鍗旾D涓虹┖瀛楃涓茬殑鎯呭喌
+        boolean result2 = legacyTransferSyncService.isTransferOrderSynced("", "12345");
+        assertFalse(result2);
+        
+        // 娴嬭瘯鏈嶅姟鍗旾D涓洪潪鏁板瓧瀛楃涓茬殑鎯呭喌
+        boolean result3 = legacyTransferSyncService.isTransferOrderSynced("abc", "12345");
+        assertFalse(result3);
+    }
+    
+    @Test
+    public void testSyncSingleTransferOrderWithInvalidParams() {
+        // 娴嬭瘯鏈嶅姟鍗旾D涓虹┖鐨勬儏鍐�
+        boolean result1 = legacyTransferSyncService.syncSingleTransferOrder(null, "12345");
+        assertFalse(result1);
+        
+        // 娴嬭瘯鏈嶅姟鍗旾D涓虹┖瀛楃涓茬殑鎯呭喌
+        boolean result2 = legacyTransferSyncService.syncSingleTransferOrder("", "12345");
+        assertFalse(result2);
+    }
+}
\ No newline at end of file
diff --git a/sql/legacy_transfer_sync_job.sql b/sql/legacy_transfer_sync_job.sql
new file mode 100644
index 0000000..37d9d69
--- /dev/null
+++ b/sql/legacy_transfer_sync_job.sql
@@ -0,0 +1,88 @@
+-- 鏃х郴缁熻浆杩愬崟鍚屾瀹氭椂浠诲姟閰嶇疆SQL
+-- 鍦╯ys_job琛ㄤ腑娣诲姞瀹氭椂浠诲姟
+
+-- 杞繍鍗曡嚜鍔ㄥ悓姝ワ紙浠庢棫绯荤粺鍒版柊绯荤粺锛�
+INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
+VALUES 
+('鏃х郴缁熻浆杩愬崟鍚屾', 'DEFAULT', 'legacyTransferSyncTask.syncTransferOrders7Days', '0 0 2 * * ?', '3', '1', '0', 'admin', sysdate(), 
+'姣忓ぉ鍑屾櫒2鐐硅嚜鍔ㄥ悓姝�7澶╁墠鐨勬棫绯荤粺杞繍鍗曟暟鎹��');
+
+-- 璇存槑锛�
+-- job_name: 浠诲姟鍚嶇О - 鏃х郴缁熻浆杩愬崟鍚屾
+-- job_group: 浠诲姟缁勫悕锛圖EFAULT涓洪粯璁ょ粍锛�
+-- invoke_target: 璋冪敤鐩爣瀛楃涓诧紙Bean鍚嶇О.鏂规硶鍚嶏級
+--   - legacyTransferSyncTask.syncTransferOrders7Days() 鍚屾7澶╁墠鐨勮浆杩愬崟鏁版嵁
+--   - legacyTransferSyncTask.syncTransferOrders('7') 涔熷彲浠ヤ娇鐢ㄥ甫鍙傛暟鐨勬柟娉�
+-- cron_expression: cron琛ㄨ揪寮�
+--   - '0 0 2 * * ?' = 姣忓ぉ鍑屾櫒2鐐规墽琛�
+--   - '0 0 2 * * ?' = 姣忓ぉ鍑屾櫒2鐐规墽琛�
+--   - '0 0 3 * * ?' = 姣忓ぉ鍑屾櫒3鐐规墽琛�
+--   - '0 0 2 1 * ?' = 姣忔湀1鏃ュ噷鏅�2鐐规墽琛�
+-- misfire_policy: 閿欒繃鎵ц绛栫暐
+--   - 1=绔嬪嵆鎵ц
+--   - 2=鎵ц涓�娆�
+--   - 3=鏀惧純鎵ц锛堟帹鑽愶級
+-- concurrent: 鏄惁骞跺彂
+--   - 0=鍏佽骞跺彂
+--   - 1=绂佹骞跺彂锛堟帹鑽愶紝閬垮厤閲嶅鍚屾锛�
+-- status: 鐘舵��
+--   - 0=姝e父锛堝惎鐢級
+--   - 1=鏆傚仠锛堝仠鐢級
+-- create_by: 鍒涘缓鑰�
+-- create_time: 鍒涘缓鏃堕棿
+-- remark: 澶囨敞璇存槑
+
+-- 鍚屾閫昏緫锛�
+-- 1. 姣忓ぉ鍑屾櫒鑷姩鎵ц鍚屾浠诲姟
+-- 2. 鏌ヨ7澶╁墠鐨勮浆杩愬崟鏁版嵁
+-- 3. 妫�鏌ユ槸鍚﹀凡鍚屾杩�
+-- 4. 鏈悓姝ョ殑杞繍鍗曟暟鎹垱寤烘柊浠诲姟
+-- 5. 璁板綍鍚屾鏃ュ織
+
+-- 鐩戞帶鏌ヨ锛�
+-- 鏌ョ湅浠婃棩杞繍鍗曞悓姝ョ粺璁★細
+SELECT 
+    COUNT(*) AS total_sync_count,
+    SUM(CASE WHEN task_type = 'EMERGENCY_TRANSFER' THEN 1 ELSE 0 END) AS emergency_transfer_count
+FROM sys_task
+WHERE DATE(create_time) = CURDATE()
+  AND task_description LIKE '%浠庢棫绯荤粺鍚屾鐨勮浆杩愬崟%';
+
+-- 鏌ョ湅鍚屾澶辫触鐨勪换鍔★細
+SELECT 
+    task_id,
+    task_code,
+    task_description,
+    create_time
+FROM sys_task
+WHERE task_description LIKE '%浠庢棫绯荤粺鍚屾鐨勮浆杩愬崟%'
+  AND task_status = 'ERROR'
+ORDER BY create_time DESC;
+
+-- 鏌ョ湅鏈�杩戝悓姝ョ殑浠诲姟锛�
+SELECT 
+    t.task_id,
+    t.task_code,
+    t.task_description,
+    t.create_time,
+    e.legacy_service_ord_id,
+    e.legacy_dispatch_ord_id
+FROM sys_task t
+LEFT JOIN sys_task_emergency e ON t.task_id = e.task_id
+WHERE t.task_description LIKE '%浠庢棫绯荤粺鍚屾鐨勮浆杩愬崟%'
+ORDER BY t.create_time DESC
+LIMIT 20;
+
+-- 浣跨敤寤鸿锛�
+-- 1. 寤鸿鍦ㄤ笟鍔′綆宄版湡鎵ц鍚屾浠诲姟锛堝鍑屾櫒2鐐癸級
+-- 2. 鍙牴鎹疄闄呴渶姹傝皟鏁村悓姝ュぉ鏁帮紙濡傛敼涓�3澶╂垨14澶╋級
+-- 3. 瀹氭湡妫�鏌ュ悓姝ュけ璐ョ殑浠诲姟骞跺鐞�
+-- 4. 鍙�氳繃淇敼 status=1 涓存椂绂佺敤鍚屾浠诲姟
+
+-- 閿欒澶勭悊锛�
+-- 1. 濡傛灉鍚屾澶辫触锛屾鏌ワ細
+--    - SQL Server杩炴帴鏄惁姝e父
+--    - 鏁版嵁鏍煎紡鏄惁姝g‘
+--    - 鏂扮郴缁熷瓧娈垫槸鍚﹀尮閰�
+-- 2. 鍙�氳繃瀹氭椂浠诲姟鏃ュ織鏌ョ湅璇︾粏閿欒锛�
+--    绯荤粺鐩戞帶 -> 瀹氭椂浠诲姟 -> 璋冨害鏃ュ織
\ No newline at end of file

--
Gitblit v1.9.1