From d9281d43e27ab6c510d390ddb26eaffc8ccc1add Mon Sep 17 00:00:00 2001
From: 陈昶聿 <chychen@nbjetron.com>
Date: 星期三, 11 十一月 2026 14:04:52 +0800
Subject: [PATCH] 妇幼-补充住院随访档案生成日志、完成事件及自检文件
---
smartor/src/main/java/com/smartor/listener/InhospFollowupArchiveListener.java | 42 +
sql/pat_specific_archive_generate_log_and_source_20261111.sql | 105 ++++
smartor/src/main/resources/mapper/smartor/PatSpecificArchiveGenerateLogMapper.xml | 94 ++++
doc/api/妇保接口文档.md | 646 ++++++++++++++++++++++++++++
smartor/src/main/java/com/smartor/domain/PatSpecificArchiveGenerateLog.java | 90 +++
smartor/src/test/java/com/smartor/service/InhospFollowupArchiveLogicCheck.java | 130 +++++
ruoyi-common/src/main/java/com/ruoyi/common/core/event/FollowupCompletedEvent.java | 46 ++
ruoyi-task/src/main/java/com/ruoyi/task/event/FollowupCompletedEventPublisher.java | 37 +
smartor/src/main/java/com/smartor/mapper/PatSpecificArchiveGenerateLogMapper.java | 41 +
smartor/src/main/java/com/smartor/service/impl/PatSpecificArchiveGenerateLogServiceImpl.java | 74 +++
smartor/src/main/java/com/smartor/service/IPatSpecificArchiveGenerateLogService.java | 18
11 files changed, 1,323 insertions(+), 0 deletions(-)
diff --git "a/doc/api/\345\246\207\344\277\235\346\216\245\345\217\243\346\226\207\346\241\243.md" "b/doc/api/\345\246\207\344\277\235\346\216\245\345\217\243\346\226\207\346\241\243.md"
new file mode 100644
index 0000000..5724f39
--- /dev/null
+++ "b/doc/api/\345\246\207\344\277\235\346\216\245\345\217\243\346\226\207\346\241\243.md"
@@ -0,0 +1,646 @@
+# 濡囦繚鎺ュ彛鏂囨。锛堝绉� / 鍎跨妗f锛�
+
+> 鏈枃妗d粎鍖呭惈浠ヤ笅 8 涓帴鍙o細
+
+| 搴忓彿 | 妯″潡 | 鎺ュ彛 | 鏂规硶 | 璇存槑 |
+| --- | --- | --- | --- | --- |
+| 1 | 濡囩妗f | `/smartor/maternityArchive/selectPatMaternityArchiveList` | POST | 鏌ヨ濡囩妗f鍒楄〃 |
+| 2 | 濡囩妗f | `/smartor/maternityArchive/insertOrUpdateMaternityArchive` | POST | 鏂板鎴栦慨鏀瑰绉戞。妗� |
+| 3 | 濡囩妗f | `/smartor/maternityArchive/batchDelete` | POST | 鎵归噺鍒犻櫎濡囩妗f锛堝惈璇︽儏锛� |
+| 4 | 濡囩妗f璇︽儏 | `/smartor/maternityArchiveDetail/getInfo/{archiveid}` | GET | 鑾峰彇濡囩妗f璇︽儏 |
+| 5 | 鍎跨妗f | `/smartor/childArchive/selectPatChildArchiveList` | POST | 鏌ヨ鍎跨妗f鍒楄〃 |
+| 6 | 鍎跨妗f | `/smartor/childArchive/insertOrUpdateChildArchive` | POST | 鏂板鎴栦慨鏀瑰効绉戞。妗� |
+| 7 | 鍎跨妗f | `/smartor/childArchive/batchDelete` | POST | 鎵归噺鍒犻櫎鍎跨妗f锛堝惈璇︽儏锛� |
+| 8 | 鍎跨妗f璇︽儏 | `/smartor/childArchiveDetail/getInfo/{archiveid}` | GET | 鑾峰彇鍎跨妗f璇︽儏 |
+
+---
+
+## 涓�銆侀�氱敤璇存槑
+
+### 1.1 鏈嶅姟鍦板潃
+
+- 鍓嶇紑锛歚http://鏈嶅姟IP:绔彛`锛堥粯璁ゅ紑鍙戠幆澧冧负 `http://localhost:8080`锛�
+
+### 1.2 璁よ瘉鏂瑰紡
+
+- 鎵�鏈夋帴鍙e潎闇�鐧诲綍鍚庤皟鐢ㄣ��
+- 璇锋眰澶存惡甯︼細`Authorization: Bearer {token}`
+
+### 1.3 璇锋眰涓庡搷搴旀牸寮�
+
+- 璇锋眰浣擄細`Content-Type: application/json`
+- 鍒楄〃鎺ュ彛鍝嶅簲缁撴瀯锛圱ableDataInfo锛夛細
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+| --- | --- | --- |
+| total | long | 鎬昏褰曟暟 |
+| rows | array | 鏁版嵁鍒楄〃 |
+| code | int | 鐘舵�佺爜锛�200 涓烘垚鍔� |
+| msg | string | 鎻愮ず淇℃伅锛屽鈥滄煡璇㈡垚鍔熲�� |
+
+- 闈炲垪琛ㄦ帴鍙e搷搴旂粨鏋勶紙AjaxResult锛夛細
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+| --- | --- | --- |
+| code | int | 鐘舵�佺爜锛�200 涓烘垚鍔燂紝500 涓哄け璐� |
+| msg | string | 鎻愮ず淇℃伅锛屽鈥滄搷浣滄垚鍔熲�濄�佲�滄搷浣滃け璐モ�� |
+| data | object | 涓氬姟鏁版嵁锛堝彲鑳戒负绌猴級 |
+
+---
+
+## 浜屻�佸绉戞。妗堟帴鍙�
+
+### 2.1 鏌ヨ濡囩妗f鍒楄〃
+
+- **URL**锛歚POST /smartor/maternityArchive/selectPatMaternityArchiveList`
+- **璇存槑**锛氬垎椤垫煡璇㈠绉戞。妗堜富琛ㄥ垪琛紙鏈垹闄ゆ暟鎹� `del_flag = '0'`锛夈��
+
+**璇锋眰浣擄紙JSON锛屽叏閮ㄥ彲閫夛級**
+
+| 鍙傛暟鍚� | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+| --- | --- | --- | --- |
+| pageNum | Integer | 鍚� | 椤电爜锛堝垎椤垫椂蹇呭~锛� |
+| pageSize | Integer | 鍚� | 姣忛〉鏉℃暟锛堝垎椤垫椂蹇呭~锛� |
+| archiveType | String | 鍚� | 妗f绫诲瀷锛�1 鏃╁瓡鍏崇埍锛�2 鍥寸粷缁忔湡MHI |
+| outhospno | String | 鍚� | 闂ㄨ瘖缂栧彿锛堢簿纭尮閰嶏級 |
+| inhospno | String | 鍚� | 浣忛櫌缂栧彿锛堢簿纭尮閰嶏級 |
+| serialnum | String | 鍚� | 娴佹按鍙凤紙绮剧‘鍖归厤锛� |
+| patid | Long | 鍚� | 鎮h�匢D |
+| patname | String | 鍚� | 鎮h�呭鍚嶏紙妯$硦鍖归厤锛� |
+| parentname | String | 鍚� | 瀹堕暱濮撳悕锛堟ā绯婂尮閰嶏級 |
+| birthdate | Date | 鍚� | 鍑虹敓鏃ユ湡 |
+| idcardno | String | 鍚� | 璇佷欢鍙风爜锛堢簿纭尮閰嶏級 |
+| phone | String | 鍚� | 鑱旂郴鐢佃瘽锛堢簿纭尮閰嶏級 |
+| diagTime | Date | 鍚� | 璇婃柇鏃堕棿 |
+| plannedFollowTime | Date | 鍚� | 鎷熼殢璁挎椂闂� |
+| followupCycleTimes | String | 鍚� | 闅忚鍛ㄦ湡(娆℃暟) |
+| sex | Long | 鍚� | 鎬у埆锛�1 鐢凤紝2 濂� |
+| doctorCode | String | 鍚� | 涓绘不鍖荤敓锛堢簿纭尮閰嶏級 |
+| doctorName | String | 鍚� | 涓绘不鍖荤敓濮撳悕锛堟ā绯婂尮閰嶏級 |
+| managementDoctorCode | String | 鍚� | 缁忕鍖荤敓锛堢簿纭尮閰嶏級 |
+| managementDoctorName | String | 鍚� | 缁忕鍖荤敓濮撳悕锛堟ā绯婂尮閰嶏級 |
+| deptcode | String | 鍚� | 绉戝缂栧彿锛堢簿纭尮閰嶏級 |
+| deptname | String | 鍚� | 绉戝鍚嶇О锛堟ā绯婂尮閰嶏級 |
+| wardcode | String | 鍚� | 鐥呭尯缂栧彿锛堢簿纭尮閰嶏級 |
+| wardname | String | 鍚� | 鐥呭尯鍚嶇О锛堟ā绯婂尮閰嶏級 |
+| icd10code | String | 鍚� | 璇婃柇ID锛堢簿纭尮閰嶏級 |
+| diagname | String | 鍚� | 璇婃柇鍚嶇О锛堟ā绯婂尮閰嶏級 |
+| pregnancySituation | String | 鍚� | 濡婂鎯呭喌 |
+| closeStatus | String | 鍚� | 缁撴鐘舵�� |
+| registerUser | String | 鍚� | 鐧昏浜哄憳 |
+| orgid | String | 鍚� | 鍖婚櫌鏈烘瀯ID锛堝悗绔寜鐧诲綍鐢ㄦ埛鑷姩娉ㄥ叆锛� |
+| campusid | String | 鍚� | 闄㈠尯ID锛堝悗绔寜鐧诲綍鐢ㄦ埛鑷姩娉ㄥ叆锛� |
+| params.beginTime | String | 鍚� | 寤烘。鏃堕棿鑼冨洿寮�濮嬶紝鏍煎紡 yyyy-MM-dd |
+| params.endTime | String | 鍚� | 寤烘。鏃堕棿鑼冨洿缁撴潫锛屾牸寮� yyyy-MM-dd |
+
+**璇锋眰绀轰緥**
+
+```json
+{
+ "pageNum": 1,
+ "pageSize": 10,
+ "patname": "寮�",
+ "archiveType": "1"
+}
+```
+
+**鍝嶅簲绀轰緥**
+
+```json
+{
+ "code": 200,
+ "msg": "鏌ヨ鎴愬姛",
+ "total": 1,
+ "rows": [
+ {
+ "id": 1001,
+ "archiveType": "1",
+ "outhospno": "MZ20261001001",
+ "inhospno": null,
+ "serialnum": "LS20261001001",
+ "patid": 9001,
+ "patname": "寮犱笁",
+ "parentname": null,
+ "birthdate": "1995-06-01 00:00:00",
+ "idcardno": "330102199506010022",
+ "phone": "13800000000",
+ "diagTime": "2026-10-01 09:30:00",
+ "archiveTime": "2026-10-01 10:00:00",
+ "plannedFollowTime": "2026-11-01 00:00:00",
+ "followupCycleTimes": "4",
+ "sex": 2,
+ "doctorCode": "D001",
+ "doctorName": "鏉庡尰鐢�",
+ "managementDoctorCode": "D002",
+ "managementDoctorName": "鐜嬪尰鐢�",
+ "deptcode": "FK",
+ "deptname": "濡囩",
+ "wardcode": null,
+ "wardname": null,
+ "icd10code": "O20.0",
+ "diagname": "鍏堝厗娴佷骇",
+ "pregnancySituation": "瀛�12鍛�",
+ "closeStatus": "0",
+ "registerUser": "鏉庡尰鐢�",
+ "orgid": "1",
+ "campusid": "1",
+ "delFlag": "0"
+ }
+ ]
+}
+```
+
+---
+
+### 2.2 鏂板鎴栦慨鏀瑰绉戞。妗�
+
+- **URL**锛歚POST /smartor/maternityArchive/insertOrUpdateMaternityArchive`
+- **璇存槑**锛氬悓鏃剁淮鎶ゅ绉戞。妗堜富琛ㄤ笌璇︽儏琛ㄣ��
+ - 涓昏〃鏈� `archiveid`锛堟垨璇︽儏鏈� `id` 涓旇兘鍙嶆煡锛変笖瀛樺湪鏃舵洿鏂帮紝鍚﹀垯鏂板銆�
+ - 杩斿洖 `data` 涓哄绉戞。妗堜富琛↖D銆�
+
+**璇锋眰浣擄紙JSON锛�**
+
+| 鍙傛暟鍚� | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+| --- | --- | --- | --- |
+| id | Long | 鍚� | 濡囩妗f璇︽儏涓婚敭ID锛堟洿鏂拌鎯呮椂浼犲叆锛� |
+| archiveid | Long | 鍚� | 濡囩妗f涓昏〃ID锛堟洿鏂颁富琛ㄦ椂浼犲叆锛� |
+| archiveType | String | 鍚� | 妗f绫诲瀷锛�1 鏃╁瓡鍏崇埍锛�2 鍥寸粷缁忔湡MHI |
+| sourceType | String | 鍚� | 鏉ユ簮绫诲瀷锛�1 闂ㄨ瘖鎺ヨ瘖锛�2 浣忛櫌闅忚锛�3 鎵嬪伐鏂板 |
+| sourceBizId | Long | 鍚� | 鏉ユ簮涓氬姟ID锛氶棬璇婅褰旾D/浣忛櫌璁板綍ID |
+| sourceBizNo | String | 鍚� | 鏉ユ簮涓氬姟缂栧彿锛氶棬璇婂彿/浣忛櫌鍙� |
+| sourceSubId | Long | 鍚� | 鏉ユ簮闅忚瀛愪换鍔D锛氫綇闄㈤殢璁跨敓鎴愭椂涓� service_subtask.id |
+| outhospno | String | 鍚� | 闂ㄨ瘖缂栧彿 |
+| inhospno | String | 鍚� | 浣忛櫌缂栧彿 |
+| serialnum | String | 鍚� | 娴佹按鍙� |
+| patid | Long | 鍚� | 鎮h�匢D |
+| patname | String | 鍚� | 鎮h�呭鍚� |
+| birthdate | Date | 鍚� | 鍑虹敓鏃ユ湡锛屾牸寮� yyyy-MM-dd HH:mm:ss |
+| idcardno | String | 鍚� | 璇佷欢鍙风爜 |
+| phone | String | 鍚� | 鑱旂郴鐢佃瘽 |
+| diagTime | Date | 鍚� | 璇婃柇鏃堕棿 |
+| archiveTime | Date | 鍚� | 寤烘。鏃堕棿 |
+| plannedFollowTime | Date | 鍚� | 鎷熼殢璁挎椂闂� |
+| sex | Long | 鍚� | 鎬у埆锛�1 鐢凤紝2 濂� |
+| doctorCode | String | 鍚� | 涓绘不鍖荤敓 |
+| doctorName | String | 鍚� | 涓绘不鍖荤敓濮撳悕 |
+| managementDoctorCode | String | 鍚� | 缁忕鍖荤敓 |
+| managementDoctorName | String | 鍚� | 缁忕鍖荤敓濮撳悕 |
+| deptcode | String | 鍚� | 绉戝缂栧彿 |
+| deptname | String | 鍚� | 绉戝鍚嶇О |
+| wardcode | String | 鍚� | 鐥呭尯缂栧彿 |
+| wardname | String | 鍚� | 鐥呭尯鍚嶇О |
+| icd10code | String | 鍚� | 璇婃柇ID |
+| diagname | String | 鍚� | 璇婃柇鍚嶇О |
+| pregnancySituation | String | 鍚� | 濡婂鎯呭喌 |
+| specificSituation | String | 鍚� | 鍏蜂綋鎯呭喌 |
+| handleSuggestion | String | 鍚� | 澶勭悊寤鸿 |
+| closeStatus | String | 鍚� | 缁撴鐘舵�� |
+| isRecordEstablished | String | 鍚� | 鏄惁寤哄唽锛�0 鍚︼紝1 鏄� |
+| dueDate | Date | 鍚� | 棰勪骇鏈� |
+| registerUser | String | 鍚� | 鐧昏浜哄憳 |
+| followupPeriod | String | 鍚� | 闅忚鍛ㄦ湡 |
+| followupCycleTimes | String | 鍚� | 闅忚鍛ㄦ湡(娆℃暟) |
+| lastMenstrualTime | Date | 鍚� | 鏈鏈堢粡 |
+| firstDoctorCode | String | 鍚� | 棣栬瘖鍖荤敓 |
+| firstDoctorName | String | 鍚� | 棣栬瘖鍖荤敓濮撳悕 |
+| contactPhone | String | 鍚� | 鑱旂郴浜鸿仈绯荤數璇� |
+| address | String | 鍚� | 灞呬綇鍦板潃 |
+| epEarlyPregnancyFollowupForm | String | 鍚� | 鏃╁瓡鍏崇埍-鏃╁瓡闅忚琛� |
+| mhiMenopauseFollowupSystemIssuesForm | String | 鍚� | 鍥寸粷缁忔湡MHI-鏇村勾鏈熼殢璁跨郴缁熼棶棰樿〃 |
+| mhiMhtInitialVisitMedicalRecordForm | String | 鍚� | 鍥寸粷缁忔湡MHI-MHT棣栬瘖鐥呭巻琛� |
+| mhiMhtFollowUpMedicalRecordForm | String | 鍚� | 鍥寸粷缁忔湡MHI-MHT澶嶈瘖鐥呭巻琛� |
+| mhiModifiedKuppermanScoringScaleForm | String | 鍚� | 鍥寸粷缁忔湡MHI-鏀硅壇Kupperman璇勫垎鏍囧噯琛� |
+| mhiMenopauseRatingScaleForm | String | 鍚� | 鍥寸粷缁忔湡MHI-鏇村勾鏈熻瘎瀹氶噺琛紙MRS锛� |
+| mhiPittsburghSleepQualityIndexForm | String | 鍚� | 鍥寸粷缁忔湡MHI-鍖瑰吂鍫$潯鐪犺川閲忔寚鏁伴噺琛紙PSQI锛� |
+| remark | String | 鍚� | 澶囨敞 |
+| orgid | String | 鍚� | 鍖婚櫌鏈烘瀯ID锛堝悗绔寜鐧诲綍鐢ㄦ埛鑷姩瑕嗙洊锛� |
+| campusid | String | 鍚� | 闄㈠尯ID锛堝悗绔寜鐧诲綍鐢ㄦ埛鑷姩瑕嗙洊锛� |
+| delFlag | String | 鍚� | 鍒犻櫎鏍囧織锛�0 鏈垹闄わ紝1 宸插垹闄わ紙榛樿 0锛� |
+
+**璇锋眰绀轰緥锛堟柊澧烇級**
+
+```json
+{
+ "archiveType": "1",
+ "patid": 9001,
+ "patname": "寮犱笁",
+ "birthdate": "1995-06-01 00:00:00",
+ "idcardno": "330102199506010022",
+ "phone": "13800000000",
+ "diagTime": "2026-10-01 09:30:00",
+ "archiveTime": "2026-10-01 10:00:00",
+ "sex": 2,
+ "deptcode": "FK",
+ "deptname": "濡囩",
+ "pregnancySituation": "瀛�12鍛�",
+ "closeStatus": "0"
+}
+```
+
+**鍝嶅簲绀轰緥**
+
+```json
+{
+ "code": 200,
+ "msg": "鎿嶄綔鎴愬姛",
+ "data": 1001
+}
+```
+
+---
+
+### 2.3 鎵归噺鍒犻櫎濡囩妗f
+
+- **URL**锛歚POST /smartor/maternityArchive/batchDelete`
+- **璇存槑**锛氭寜涓昏〃ID鎵归噺鍒犻櫎濡囩妗f锛屽悓鏃堕�昏緫鍒犻櫎瀵瑰簲鐨勫绉戞。妗堣鎯呰〃鏁版嵁锛坄del_flag` 缃负 1锛夛紝涓ゆ鍦ㄥ悓涓�浜嬪姟涓��
+
+**璇锋眰浣擄紙JSON锛�**
+
+| 鍙傛暟鍚� | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+| --- | --- | --- | --- |
+| ids | Long[] | 鏄� | 濡囩妗f涓昏〃ID鏁扮粍 |
+
+**璇锋眰绀轰緥**
+
+```json
+[1001, 1002, 1003]
+```
+
+**鍝嶅簲绀轰緥**
+
+```json
+{
+ "code": 200,
+ "msg": "鎿嶄綔鎴愬姛"
+}
+```
+
+---
+
+### 2.4 鑾峰彇濡囩妗f璇︽儏
+
+- **URL**锛歚GET /smartor/maternityArchiveDetail/getInfo/{archiveid}`
+- **璇存槑**锛氭寜妗f涓昏〃ID鏌ヨ濡囩妗f璇︽儏锛堟湭鍒犻櫎鏁版嵁 `del_flag = '0'`锛夛紝杩斿洖绗竴鏉¤鎯呰褰曪紱鏃犳暟鎹椂 `data` 涓� `null`銆�
+
+**璺緞鍙傛暟**
+
+| 鍙傛暟鍚� | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+| --- | --- | --- | --- |
+| archiveid | Long | 鏄� | 濡囩妗f涓昏〃ID锛坄pat_maternity_archive.id`锛� |
+
+**鍝嶅簲绀轰緥**
+
+```json
+{
+ "code": 200,
+ "msg": "鎿嶄綔鎴愬姛",
+ "data": {
+ "id": 5001,
+ "archiveid": 1001,
+ "archiveType": "1",
+ "sourceType": "1",
+ "outhospno": "MZ20261001001",
+ "inhospno": null,
+ "serialnum": "LS20261001001",
+ "patid": 9001,
+ "patname": "寮犱笁",
+ "birthdate": "1995-06-01 00:00:00",
+ "idcardno": "330102199506010022",
+ "phone": "13800000000",
+ "diagTime": "2026-10-01 09:30:00",
+ "archiveTime": "2026-10-01 10:00:00",
+ "plannedFollowTime": "2026-11-01 00:00:00",
+ "sex": 2,
+ "doctorCode": "D001",
+ "doctorName": "鏉庡尰鐢�",
+ "managementDoctorCode": "D002",
+ "managementDoctorName": "鐜嬪尰鐢�",
+ "deptcode": "FK",
+ "deptname": "濡囩",
+ "wardcode": null,
+ "wardname": null,
+ "icd10code": "O20.0",
+ "diagname": "鍏堝厗娴佷骇",
+ "pregnancySituation": "瀛�12鍛�",
+ "specificSituation": "鍏蜂綋鎯呭喌",
+ "handleSuggestion": "娉ㄦ剰浼戞伅",
+ "closeStatus": "0",
+ "isRecordEstablished": "1",
+ "dueDate": "2027-03-20 00:00:00",
+ "registerUser": "鏉庡尰鐢�",
+ "followupPeriod": "姣忔湀",
+ "followupCycleTimes": "4",
+ "lastMenstrualTime": "2026-06-10 00:00:00",
+ "firstDoctorCode": "D001",
+ "firstDoctorName": "鏉庡尰鐢�",
+ "contactPhone": "13900000000",
+ "address": "鏉窞甯傝タ婀栧尯",
+ "orgid": "1",
+ "campusid": "1",
+ "delFlag": "0"
+ }
+}
+```
+
+> 杩斿洖瀵硅薄 `data` 涓哄绉戞。妗堣鎯呭璞★紝瀛楁璇存槑鍚� 2.2 璇锋眰浣撳瓧娈点��
+
+---
+
+## 涓夈�佸効绉戞。妗堟帴鍙�
+
+### 3.1 鏌ヨ鍎跨妗f鍒楄〃
+
+- **URL**锛歚POST /smartor/childArchive/selectPatChildArchiveList`
+- **璇存槑**锛氬垎椤垫煡璇㈠効绉戞。妗堜富琛ㄥ垪琛紙鏈垹闄ゆ暟鎹� `del_flag = '0'`锛夈��
+
+**璇锋眰浣擄紙JSON锛屽叏閮ㄥ彲閫夛級**
+
+| 鍙傛暟鍚� | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+| --- | --- | --- | --- |
+| pageNum | Integer | 鍚� | 椤电爜锛堝垎椤垫椂蹇呭~锛� |
+| pageSize | Integer | 鍚� | 姣忛〉鏉℃暟锛堝垎椤垫椂蹇呭~锛� |
+| archiveType | String | 鍚� | 妗f绫诲瀷锛�1 钀ュ吇鎬х柧鐥咃紝2 瀛︿範鍥伴毦锛�3 楂樺嵄鍎夸笓妗� |
+| outhospno | String | 鍚� | 闂ㄨ瘖缂栧彿锛堢簿纭尮閰嶏級 |
+| inhospno | String | 鍚� | 浣忛櫌缂栧彿锛堢簿纭尮閰嶏級 |
+| serialnum | String | 鍚� | 娴佹按鍙凤紙绮剧‘鍖归厤锛� |
+| patid | Long | 鍚� | 鎮h�匢D |
+| patname | String | 鍚� | 鎮h�呭鍚嶏紙妯$硦鍖归厤锛� |
+| parentname | String | 鍚� | 瀹堕暱濮撳悕锛堟ā绯婂尮閰嶏級 |
+| birthdate | Date | 鍚� | 鍑虹敓鏃ユ湡 |
+| idcardno | String | 鍚� | 璇佷欢鍙风爜锛堢簿纭尮閰嶏級 |
+| phone | String | 鍚� | 鑱旂郴鐢佃瘽锛堢簿纭尮閰嶏級 |
+| diagTime | Date | 鍚� | 璇婃柇鏃堕棿 |
+| plannedFollowTime | Date | 鍚� | 鎷熼殢璁挎椂闂� |
+| followupCycleTimes | String | 鍚� | 闅忚鍛ㄦ湡(娆℃暟) |
+| sex | Long | 鍚� | 鎬у埆锛�1 鐢凤紝2 濂� |
+| doctorCode | String | 鍚� | 涓绘不鍖荤敓锛堢簿纭尮閰嶏級 |
+| doctorName | String | 鍚� | 涓绘不鍖荤敓濮撳悕锛堟ā绯婂尮閰嶏級 |
+| managementDoctorCode | String | 鍚� | 缁忕鍖荤敓锛堢簿纭尮閰嶏級 |
+| managementDoctorName | String | 鍚� | 缁忕鍖荤敓濮撳悕锛堟ā绯婂尮閰嶏級 |
+| deptcode | String | 鍚� | 绉戝缂栧彿锛堢簿纭尮閰嶏級 |
+| deptname | String | 鍚� | 绉戝鍚嶇О锛堟ā绯婂尮閰嶏級 |
+| wardcode | String | 鍚� | 鐥呭尯缂栧彿锛堢簿纭尮閰嶏級 |
+| wardname | String | 鍚� | 鐥呭尯鍚嶇О锛堟ā绯婂尮閰嶏級 |
+| icd10code | String | 鍚� | 璇婃柇ID锛堢簿纭尮閰嶏級 |
+| diagname | String | 鍚� | 璇婃柇鍚嶇О锛堟ā绯婂尮閰嶏級 |
+| closeStatus | String | 鍚� | 缁撴鐘舵�� |
+| registerUser | String | 鍚� | 鐧昏浜哄憳 |
+| orgid | String | 鍚� | 鍖婚櫌鏈烘瀯ID锛堝悗绔寜鐧诲綍鐢ㄦ埛鑷姩娉ㄥ叆锛� |
+| campusid | String | 鍚� | 闄㈠尯ID锛堝悗绔寜鐧诲綍鐢ㄦ埛鑷姩娉ㄥ叆锛� |
+| params.beginTime | String | 鍚� | 寤烘。鏃堕棿鑼冨洿寮�濮嬶紝鏍煎紡 yyyy-MM-dd |
+| params.endTime | String | 鍚� | 寤烘。鏃堕棿鑼冨洿缁撴潫锛屾牸寮� yyyy-MM-dd |
+
+**璇锋眰绀轰緥**
+
+```json
+{
+ "pageNum": 1,
+ "pageSize": 10,
+ "patname": "鐜�",
+ "archiveType": "1"
+}
+```
+
+**鍝嶅簲绀轰緥**
+
+```json
+{
+ "code": 200,
+ "msg": "鏌ヨ鎴愬姛",
+ "total": 1,
+ "rows": [
+ {
+ "id": 2001,
+ "archiveType": "1",
+ "outhospno": "MZ20261001002",
+ "inhospno": null,
+ "serialnum": "LS20261001002",
+ "patid": 9002,
+ "patname": "鐜嬪皬瀹�",
+ "parentname": "鐜嬪己",
+ "birthdate": "2023-01-15 00:00:00",
+ "idcardno": null,
+ "phone": "13800000001",
+ "diagTime": "2026-10-01 09:00:00",
+ "archiveTime": "2026-10-01 09:30:00",
+ "plannedFollowTime": "2026-11-01 00:00:00",
+ "followupCycleTimes": "3",
+ "sex": 1,
+ "doctorCode": "D003",
+ "doctorName": "璧靛尰鐢�",
+ "managementDoctorCode": "D004",
+ "managementDoctorName": "瀛欏尰鐢�",
+ "deptcode": "EK",
+ "deptname": "鍎跨",
+ "wardcode": null,
+ "wardname": null,
+ "icd10code": "E44.0",
+ "diagname": "涓害钀ュ吇涓嶈壇",
+ "closeStatus": "0",
+ "registerUser": "璧靛尰鐢�",
+ "orgid": "1",
+ "campusid": "1",
+ "delFlag": "0"
+ }
+ ]
+}
+```
+
+---
+
+### 3.2 鏂板鎴栦慨鏀瑰効绉戞。妗�
+
+- **URL**锛歚POST /smartor/childArchive/insertOrUpdateChildArchive`
+- **璇存槑**锛氬悓鏃剁淮鎶ゅ効绉戞。妗堜富琛ㄤ笌璇︽儏琛ㄣ��
+ - 涓昏〃鏈� `archiveid`锛堟垨璇︽儏鏈� `id` 涓旇兘鍙嶆煡锛変笖瀛樺湪鏃舵洿鏂帮紝鍚﹀垯鏂板銆�
+ - 杩斿洖 `data` 涓哄効绉戞。妗堜富琛↖D銆�
+
+**璇锋眰浣擄紙JSON锛�**
+
+| 鍙傛暟鍚� | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+| --- | --- | --- | --- |
+| id | Long | 鍚� | 鍎跨妗f璇︽儏涓婚敭ID锛堟洿鏂拌鎯呮椂浼犲叆锛� |
+| archiveid | Long | 鍚� | 鍎跨妗f涓昏〃ID锛堟洿鏂颁富琛ㄦ椂浼犲叆锛� |
+| archiveType | String | 鍚� | 妗f绫诲瀷锛�1 钀ュ吇鎬х柧鐥咃紝2 瀛︿範鍥伴毦锛�3 楂樺嵄鍎夸笓妗� |
+| sourceType | String | 鍚� | 鏉ユ簮绫诲瀷锛�1 闂ㄨ瘖鎺ヨ瘖锛�2 浣忛櫌闅忚锛�3 鎵嬪伐鏂板 |
+| sourceBizId | Long | 鍚� | 鏉ユ簮涓氬姟ID锛氶棬璇婅褰旾D/浣忛櫌璁板綍ID |
+| sourceBizNo | String | 鍚� | 鏉ユ簮涓氬姟缂栧彿锛氶棬璇婂彿/浣忛櫌鍙� |
+| sourceSubId | Long | 鍚� | 鏉ユ簮闅忚瀛愪换鍔D锛氫綇闄㈤殢璁跨敓鎴愭椂涓� service_subtask.id |
+| outhospno | String | 鍚� | 闂ㄨ瘖缂栧彿 |
+| inhospno | String | 鍚� | 浣忛櫌缂栧彿 |
+| serialnum | String | 鍚� | 娴佹按鍙� |
+| patid | Long | 鍚� | 鎮h�匢D |
+| patname | String | 鍚� | 鎮h�呭鍚� |
+| parentname | String | 鍚� | 瀹堕暱濮撳悕 |
+| parentRelation | String | 鍚� | 瀹堕暱涓庡効绔ュ叧绯� |
+| parentPhone | String | 鍚� | 瀹堕暱鑱旂郴鐢佃瘽 |
+| parentIdcardno | String | 鍚� | 瀹堕暱璇佷欢鍙风爜 |
+| parentAddress | String | 鍚� | 瀹堕暱鑱旂郴鍦板潃 |
+| birthdate | Date | 鍚� | 鍑虹敓鏃ユ湡锛屾牸寮� yyyy-MM-dd HH:mm:ss |
+| idcardno | String | 鍚� | 璇佷欢鍙风爜 |
+| phone | String | 鍚� | 鑱旂郴鐢佃瘽 |
+| diagTime | Date | 鍚� | 璇婃柇鏃堕棿 |
+| archiveTime | Date | 鍚� | 寤烘。鏃堕棿 |
+| sex | Long | 鍚� | 鎬у埆锛�1 鐢凤紝2 濂� |
+| doctorCode | String | 鍚� | 涓绘不鍖荤敓 |
+| doctorName | String | 鍚� | 涓绘不鍖荤敓濮撳悕 |
+| managementDoctorCode | String | 鍚� | 缁忕鍖荤敓 |
+| managementDoctorName | String | 鍚� | 缁忕鍖荤敓濮撳悕 |
+| deptcode | String | 鍚� | 绉戝缂栧彿 |
+| deptname | String | 鍚� | 绉戝鍚嶇О |
+| wardcode | String | 鍚� | 鐥呭尯缂栧彿 |
+| wardname | String | 鍚� | 鐥呭尯鍚嶇О |
+| icd10code | String | 鍚� | 璇婃柇ID |
+| diagname | String | 鍚� | 璇婃柇鍚嶇О |
+| nutritionIcd10Code | String | 鍚� | 钀ュ吇鎬х柧鐥匢D |
+| nutritionDiagName | String | 鍚� | 钀ュ吇鎬х柧鐥呭悕绉� |
+| ndPhysicalMeasurements | String | 鍚� | 钀ュ吇鎬х柧鐥�-浣撴牸娴嬮噺 |
+| ndDietaryAssessment | String | 鍚� | 钀ュ吇鎬х柧鐥�-鑶抽璇勪及 |
+| ndInterventionProgram | String | 鍚� | 钀ュ吇鎬х柧鐥�-骞查鏂规 |
+| appointmentSituation | String | 鍚� | 瀛︿範鍥伴毦-棰勭害鎯呭喌 |
+| ldLearningAbilityAssessment | String | 鍚� | 瀛︿範鍥伴毦-瀛︿範鑳藉姏璇勪及 |
+| ldBehavioralAssessment | String | 鍚� | 瀛︿範鍥伴毦-琛屼负璇勪及 |
+| ldInterventionTrainingRecord | String | 鍚� | 瀛︿範鍥伴毦-骞查璁粌璁板綍 |
+| highRiskChildType | String | 鍚� | 楂樺嵄鍎夸笓妗�-楂樺嵄鍎垮垎绫� |
+| highRiskChildName | String | 鍚� | 楂樺嵄鍎夸笓妗�-楂樺嵄鍎垮悕绉� |
+| plannedFollowTime | Date | 鍚� | 楂樺嵄鍎夸笓妗�-鎷熼殢璁挎椂闂� |
+| hrcGrowthDevelopmentMonitoring | String | 鍚� | 楂樺嵄鍎夸笓妗�-鐢熼暱鍙戣偛妫�娴� |
+| hrcNeurologicalEvaluation | String | 鍚� | 楂樺嵄鍎夸笓妗�-绁炵粡绯荤粺璇勪及 |
+| hrcInterventionRecords | String | 鍚� | 楂樺嵄鍎夸笓妗�-骞查璁板綍 |
+| closeStatus | String | 鍚� | 缁撴鐘舵�� |
+| gestationalWeek | BigDecimal | 鍚� | 鍑虹敓瀛曞懆 |
+| birthWeight | BigDecimal | 鍚� | 鍑虹敓浣撻噸(kg) |
+| registerUser | String | 鍚� | 鐧昏浜哄憳 |
+| remark | String | 鍚� | 澶囨敞 |
+| orgid | String | 鍚� | 鍖婚櫌鏈烘瀯ID锛堝悗绔寜鐧诲綍鐢ㄦ埛鑷姩瑕嗙洊锛� |
+| campusid | String | 鍚� | 闄㈠尯ID锛堝悗绔寜鐧诲綍鐢ㄦ埛鑷姩瑕嗙洊锛� |
+| delFlag | String | 鍚� | 鍒犻櫎鏍囧織锛�0 鏈垹闄わ紝1 宸插垹闄わ紙榛樿 0锛� |
+
+**璇锋眰绀轰緥锛堟柊澧烇級**
+
+```json
+{
+ "archiveType": "1",
+ "patid": 9002,
+ "patname": "鐜嬪皬瀹�",
+ "parentname": "鐜嬪己",
+ "parentRelation": "鐖跺瓙",
+ "parentPhone": "13900000001",
+ "birthdate": "2023-01-15 00:00:00",
+ "phone": "13800000001",
+ "diagTime": "2026-10-01 09:00:00",
+ "archiveTime": "2026-10-01 09:30:00",
+ "sex": 1,
+ "deptcode": "EK",
+ "deptname": "鍎跨",
+ "icd10code": "E44.0",
+ "diagname": "涓害钀ュ吇涓嶈壇",
+ "nutritionIcd10Code": "E44.0",
+ "nutritionDiagName": "涓害钀ュ吇涓嶈壇",
+ "closeStatus": "0"
+}
+```
+
+**鍝嶅簲绀轰緥**
+
+```json
+{
+ "code": 200,
+ "msg": "鎿嶄綔鎴愬姛",
+ "data": 2001
+}
+```
+
+---
+
+### 3.3 鎵归噺鍒犻櫎鍎跨妗f
+
+- **URL**锛歚POST /smartor/childArchive/batchDelete`
+- **璇存槑**锛氭寜涓昏〃ID鎵归噺鍒犻櫎鍎跨妗f锛屽悓鏃堕�昏緫鍒犻櫎瀵瑰簲鐨勫効绉戞。妗堣鎯呰〃鏁版嵁锛坄del_flag` 缃负 1锛夛紝涓ゆ鍦ㄥ悓涓�浜嬪姟涓��
+
+**璇锋眰浣擄紙JSON锛�**
+
+| 鍙傛暟鍚� | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+| --- | --- | --- | --- |
+| ids | Long[] | 鏄� | 鍎跨妗f涓昏〃ID鏁扮粍 |
+
+**璇锋眰绀轰緥**
+
+```json
+[2001, 2002, 2003]
+```
+
+**鍝嶅簲绀轰緥**
+
+```json
+{
+ "code": 200,
+ "msg": "鎿嶄綔鎴愬姛"
+}
+```
+
+---
+
+### 3.4 鑾峰彇鍎跨妗f璇︽儏
+
+- **URL**锛歚GET /smartor/childArchiveDetail/getInfo/{archiveid}`
+- **璇存槑**锛氭寜妗f涓昏〃ID鏌ヨ鍎跨妗f璇︽儏锛堟湭鍒犻櫎鏁版嵁 `del_flag = '0'`锛夛紝杩斿洖绗竴鏉¤鎯呰褰曪紱鏃犳暟鎹椂 `data` 涓� `null`銆�
+
+**璺緞鍙傛暟**
+
+| 鍙傛暟鍚� | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+| --- | --- | --- | --- |
+| archiveid | Long | 鏄� | 鍎跨妗f涓昏〃ID锛坄pat_child_archive.id`锛� |
+
+**鍝嶅簲绀轰緥**
+
+```json
+{
+ "code": 200,
+ "msg": "鎿嶄綔鎴愬姛",
+ "data": {
+ "id": 6001,
+ "archiveid": 2001,
+ "archiveType": "1",
+ "sourceType": "1",
+ "outhospno": "MZ20261001002",
+ "inhospno": null,
+ "serialnum": "LS20261001002",
+ "patid": 9002,
+ "patname": "鐜嬪皬瀹�",
+ "parentname": "鐜嬪己",
+ "parentRelation": "鐖跺瓙",
+ "parentPhone": "13900000001",
+ "parentIdcardno": null,
+ "parentAddress": "鏉窞甯傛嫳澧呭尯",
+ "birthdate": "2023-01-15 00:00:00",
+ "idcardno": null,
+ "phone": "13800000001",
+ "diagTime": "2026-10-01 09:00:00",
+ "archiveTime": "2026-10-01 09:30:00",
+ "sex": 1,
+ "doctorCode": "D003",
+ "doctorName": "璧靛尰鐢�",
+ "managementDoctorCode": "D004",
+ "managementDoctorName": "瀛欏尰鐢�",
+ "deptcode": "EK",
+ "deptname": "鍎跨",
+ "wardcode": null,
+ "wardname": null,
+ "icd10code": "E44.0",
+ "diagname": "涓害钀ュ吇涓嶈壇",
+ "nutritionIcd10Code": "E44.0",
+ "nutritionDiagName": "涓害钀ュ吇涓嶈壇",
+ "closeStatus": "0",
+ "gestationalWeek": 39.5,
+ "birthWeight": 3.2,
+ "registerUser": "璧靛尰鐢�",
+ "orgid": "1",
+ "campusid": "1",
+ "delFlag": "0"
+ }
+}
+```
+
+> 杩斿洖瀵硅薄 `data` 涓哄効绉戞。妗堣鎯呭璞★紝瀛楁璇存槑鍚� 3.2 璇锋眰浣撳瓧娈点��
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/event/FollowupCompletedEvent.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/event/FollowupCompletedEvent.java
new file mode 100644
index 0000000..43ad2c9
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/event/FollowupCompletedEvent.java
@@ -0,0 +1,46 @@
+package com.ruoyi.common.core.event;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 闅忚瀹屾垚浜嬩欢銆�
+ *
+ * <p>浠呮惡甯﹀瓙浠诲姟ID锛屾秷璐规柟鎸塈D閲嶆柊鍔犺浇鏈�鏂版暟鎹紝閬垮厤浜嬩欢鍐呭涓庡簱鍐呯姸鎬佷笉涓�鑷淬��</p>
+ *
+ * @author ruoyi
+ * @date 2026-11-11
+ */
+public class FollowupCompletedEvent implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /** 闅忚瀛愪换鍔D */
+ private Long subId;
+
+ /** 瀹屾垚鏃堕棿 */
+ private Date finishTime;
+
+ public FollowupCompletedEvent() {
+ }
+
+ public FollowupCompletedEvent(Long subId, Date finishTime) {
+ this.subId = subId;
+ this.finishTime = finishTime;
+ }
+
+ public Long getSubId() {
+ return subId;
+ }
+
+ public void setSubId(Long subId) {
+ this.subId = subId;
+ }
+
+ public Date getFinishTime() {
+ return finishTime;
+ }
+
+ public void setFinishTime(Date finishTime) {
+ this.finishTime = finishTime;
+ }
+}
diff --git a/ruoyi-task/src/main/java/com/ruoyi/task/event/FollowupCompletedEventPublisher.java b/ruoyi-task/src/main/java/com/ruoyi/task/event/FollowupCompletedEventPublisher.java
new file mode 100644
index 0000000..aefaebe
--- /dev/null
+++ b/ruoyi-task/src/main/java/com/ruoyi/task/event/FollowupCompletedEventPublisher.java
@@ -0,0 +1,37 @@
+package com.ruoyi.task.event;
+
+import com.ruoyi.common.core.event.FollowupCompletedEvent;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+/**
+ * 闅忚瀹屾垚浜嬩欢鍙戝竷鍣ㄣ��
+ *
+ * <p>浠诲姟妯″潡鍦ㄥ瓙浠诲姟鐘舵�佹洿鏂颁负宸插畬鎴愶紙sendstate=6锛夊悗鍙戝竷浜嬩欢锛�
+ * 妗f绛変笅娓告ā鍧楅�氳繃 {@code @TransactionalEventListener} 寮傛娑堣垂銆�</p>
+ *
+ * @author ruoyi
+ * @date 2026-11-11
+ */
+@Slf4j
+@Component
+public class FollowupCompletedEventPublisher {
+
+ @Autowired
+ private ApplicationEventPublisher applicationEventPublisher;
+
+ public void publish(Long subId) {
+ if (subId == null) {
+ return;
+ }
+ try {
+ applicationEventPublisher.publishEvent(new FollowupCompletedEvent(subId, new Date()));
+ } catch (Exception e) {
+ log.error("鍙戝竷闅忚瀹屾垚浜嬩欢澶辫触锛宻ubId={}", subId, e);
+ }
+ }
+}
diff --git a/smartor/src/main/java/com/smartor/domain/PatSpecificArchiveGenerateLog.java b/smartor/src/main/java/com/smartor/domain/PatSpecificArchiveGenerateLog.java
new file mode 100644
index 0000000..fcdf5c5
--- /dev/null
+++ b/smartor/src/main/java/com/smartor/domain/PatSpecificArchiveGenerateLog.java
@@ -0,0 +1,90 @@
+package com.smartor.domain;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 涓撶妗f鐢熸垚鏃ュ織瀵硅薄 pat_specific_archive_generate_log銆�
+ *
+ * <p>鐢ㄤ簬浣忛櫌闅忚瀹屾垚鍚庣殑骞傜瓑鎺у埗銆佹潵婧愯拷婧拰琛ュ伩浠诲姟绛涢�夈��</p>
+ *
+ * @author ruoyi
+ * @date 2026-11-11
+ */
+@Data
+@ApiModel(value = "涓撶妗f鐢熸垚鏃ュ織瀵硅薄")
+public class PatSpecificArchiveGenerateLog implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /** 涓婚敭ID */
+ @ApiModelProperty(value = "涓婚敭ID")
+ private Long id;
+
+ /** 鏉ユ簮绫诲瀷锛�1闂ㄨ瘖鎺ヨ瘖 2浣忛櫌闅忚 */
+ @ApiModelProperty(value = "鏉ユ簮绫诲瀷锛�1闂ㄨ瘖鎺ヨ瘖 2浣忛櫌闅忚")
+ private String sourceType;
+
+ /** 鏉ユ簮涓氬姟ID锛氶棬璇婅褰旾D/浣忛櫌璁板綍ID */
+ @ApiModelProperty(value = "鏉ユ簮涓氬姟ID锛氶棬璇婅褰旾D/浣忛櫌璁板綍ID")
+ private Long sourceBizId;
+
+ /** 鏉ユ簮涓氬姟缂栧彿锛氶棬璇婂彿/浣忛櫌鍙� */
+ @ApiModelProperty(value = "鏉ユ簮涓氬姟缂栧彿锛氶棬璇婂彿/浣忛櫌鍙�")
+ private String sourceBizNo;
+
+ /** 鏉ユ簮闅忚瀛愪换鍔D锛氳Е鍙戞。妗堢敓鎴愮殑 service_subtask.id */
+ @ApiModelProperty(value = "鏉ユ簮闅忚瀛愪换鍔D锛氳Е鍙戞。妗堢敓鎴愮殑 service_subtask.id")
+ private Long sourceSubId;
+
+ /** 鎮h�匢D */
+ @ApiModelProperty(value = "鎮h�匢D")
+ private Long patid;
+
+ /** 鏈烘瀯ID */
+ @ApiModelProperty(value = "鏈烘瀯ID")
+ private String orgid;
+
+ /** 闄㈠尯ID */
+ @ApiModelProperty(value = "闄㈠尯ID")
+ private String campusid;
+
+ /** 閮ㄩ棬鍒嗙被锛�1濡囩 2鍎跨 */
+ @ApiModelProperty(value = "閮ㄩ棬鍒嗙被锛�1濡囩 2鍎跨")
+ private String deptCategory;
+
+ /** 妗f绫诲瀷 */
+ @ApiModelProperty(value = "妗f绫诲瀷")
+ private String archiveType;
+
+ /** 鍛戒腑鐨勯厤缃甀D锛涙湭鍛戒腑閰嶇疆鏃朵负0 */
+ @ApiModelProperty(value = "鍛戒腑鐨勯厤缃甀D锛涙湭鍛戒腑閰嶇疆鏃朵负0")
+ private Integer configId;
+
+ /** 鐢熸垚鎴栧懡涓殑妗f涓昏〃ID */
+ @ApiModelProperty(value = "鐢熸垚鎴栧懡涓殑妗f涓昏〃ID")
+ private Long archiveId;
+
+ /** 澶勭悊缁撴灉锛�1鐢熸垚 2宸插瓨鍦ㄨ烦杩� 3鏈尮閰� 4澶辫触 */
+ @ApiModelProperty(value = "澶勭悊缁撴灉锛�1鐢熸垚 2宸插瓨鍦ㄨ烦杩� 3鏈尮閰� 4澶辫触")
+ private String processResult;
+
+ /** 澶勭悊璇存槑 */
+ @ApiModelProperty(value = "澶勭悊璇存槑")
+ private String processMsg;
+
+ /** 閲嶈瘯娆℃暟 */
+ @ApiModelProperty(value = "閲嶈瘯娆℃暟")
+ private Integer retryCount;
+
+ /** 鍒涘缓鏃堕棿 */
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ private Date createTime;
+
+ /** 鏇存柊鏃堕棿 */
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ private Date updateTime;
+}
diff --git a/smartor/src/main/java/com/smartor/listener/InhospFollowupArchiveListener.java b/smartor/src/main/java/com/smartor/listener/InhospFollowupArchiveListener.java
new file mode 100644
index 0000000..b9f2bbd
--- /dev/null
+++ b/smartor/src/main/java/com/smartor/listener/InhospFollowupArchiveListener.java
@@ -0,0 +1,42 @@
+package com.smartor.listener;
+
+import com.ruoyi.common.core.event.FollowupCompletedEvent;
+import com.smartor.service.IPatSpecificArchiveGenerateService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.event.TransactionPhase;
+import org.springframework.transaction.event.TransactionalEventListener;
+
+/**
+ * 闅忚瀹屾垚鐢熸垚涓撶妗f鐩戝惉鍣ㄣ��
+ *
+ * <p>浣跨敤 AFTER_COMMIT 淇濊瘉闅忚瀹屾垚鐘舵�佸凡钀藉簱锛涘紓甯稿彧璁板綍鏃ュ織锛屼笉褰卞搷闅忚涓绘祦绋嬨��</p>
+ *
+ * @author ruoyi
+ * @date 2026-11-11
+ */
+@Slf4j
+@Component
+public class InhospFollowupArchiveListener {
+
+ @Autowired
+ private IPatSpecificArchiveGenerateService patSpecificArchiveGenerateService;
+
+ @Async("threadPoolTaskExecutor")
+ @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT, fallbackExecution = true)
+ public void onFollowupCompleted(FollowupCompletedEvent event) {
+ if (event == null || event.getSubId() == null) {
+ return;
+ }
+ try {
+ int generated = patSpecificArchiveGenerateService.generateByInhospFollowup(event.getSubId());
+ if (generated > 0) {
+ log.info("浣忛櫌闅忚瀹屾垚鐢熸垚涓撶妗f鎴愬姛锛宻ubId={}锛岀敓鎴愭暟閲�={}", event.getSubId(), generated);
+ }
+ } catch (Throwable e) {
+ log.error("浣忛櫌闅忚瀹屾垚鐢熸垚涓撶妗f澶辫触锛宻ubId={}", event.getSubId(), e);
+ }
+ }
+}
diff --git a/smartor/src/main/java/com/smartor/mapper/PatSpecificArchiveGenerateLogMapper.java b/smartor/src/main/java/com/smartor/mapper/PatSpecificArchiveGenerateLogMapper.java
new file mode 100644
index 0000000..e5971c8
--- /dev/null
+++ b/smartor/src/main/java/com/smartor/mapper/PatSpecificArchiveGenerateLogMapper.java
@@ -0,0 +1,41 @@
+package com.smartor.mapper;
+
+import com.smartor.domain.PatSpecificArchiveGenerateLog;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 涓撶妗f鐢熸垚鏃ュ織Mapper鎺ュ彛銆�
+ *
+ * @author ruoyi
+ * @date 2026-11-11
+ */
+@Mapper
+public interface PatSpecificArchiveGenerateLogMapper {
+
+ /**
+ * 鎸夋潵婧� + 闅忚瀛愪换鍔� + 閰嶇疆鏌ヨ鏃ュ織銆�
+ *
+ * @param sourceType 鏉ユ簮绫诲瀷
+ * @param sourceSubId 鏉ユ簮闅忚瀛愪换鍔D
+ * @param configId 閰嶇疆ID锛屾湭鍛戒腑閰嶇疆浼�0
+ * @return 鏃ュ織璁板綍锛屼笉瀛樺湪杩斿洖 null
+ */
+ PatSpecificArchiveGenerateLog selectBySourceSubAndConfig(@Param("sourceType") String sourceType,
+ @Param("sourceSubId") Long sourceSubId,
+ @Param("configId") Integer configId);
+
+ /**
+ * 鏌ヨ鏉ユ簮闅忚瀛愪换鍔′笅鏄惁宸叉湁鎴愬姛/璺宠繃/鏈尮閰嶇殑缁撴灉銆�
+ *
+ * @param sourceType 鏉ユ簮绫诲瀷
+ * @param sourceSubId 鏉ユ簮闅忚瀛愪换鍔D
+ * @return 宸插鐞嗘潯鏁�
+ */
+ int countProcessedBySourceSub(@Param("sourceType") String sourceType,
+ @Param("sourceSubId") Long sourceSubId);
+
+ int insertPatSpecificArchiveGenerateLog(PatSpecificArchiveGenerateLog log);
+
+ int updatePatSpecificArchiveGenerateLog(PatSpecificArchiveGenerateLog log);
+}
diff --git a/smartor/src/main/java/com/smartor/service/IPatSpecificArchiveGenerateLogService.java b/smartor/src/main/java/com/smartor/service/IPatSpecificArchiveGenerateLogService.java
new file mode 100644
index 0000000..47f812a
--- /dev/null
+++ b/smartor/src/main/java/com/smartor/service/IPatSpecificArchiveGenerateLogService.java
@@ -0,0 +1,18 @@
+package com.smartor.service;
+
+import com.smartor.domain.PatSpecificArchiveGenerateLog;
+
+/**
+ * 涓撶妗f鐢熸垚鏃ュ織Service鎺ュ彛銆�
+ *
+ * @author ruoyi
+ * @date 2026-11-11
+ */
+public interface IPatSpecificArchiveGenerateLogService {
+
+ PatSpecificArchiveGenerateLog selectBySourceSubAndConfig(String sourceType, Long sourceSubId, Integer configId);
+
+ boolean existsProcessedBySourceSub(String sourceType, Long sourceSubId);
+
+ int saveOrUpdate(PatSpecificArchiveGenerateLog log);
+}
diff --git a/smartor/src/main/java/com/smartor/service/impl/PatSpecificArchiveGenerateLogServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/PatSpecificArchiveGenerateLogServiceImpl.java
new file mode 100644
index 0000000..7071a9e
--- /dev/null
+++ b/smartor/src/main/java/com/smartor/service/impl/PatSpecificArchiveGenerateLogServiceImpl.java
@@ -0,0 +1,74 @@
+package com.smartor.service.impl;
+
+import com.smartor.domain.PatSpecificArchiveGenerateLog;
+import com.smartor.mapper.PatSpecificArchiveGenerateLogMapper;
+import com.smartor.service.IPatSpecificArchiveGenerateLogService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+
+/**
+ * 涓撶妗f鐢熸垚鏃ュ織Service涓氬姟灞傚鐞嗐��
+ *
+ * @author ruoyi
+ * @date 2026-11-11
+ */
+@Service
+public class PatSpecificArchiveGenerateLogServiceImpl implements IPatSpecificArchiveGenerateLogService {
+
+ @Autowired
+ private PatSpecificArchiveGenerateLogMapper logMapper;
+
+ @Override
+ public PatSpecificArchiveGenerateLog selectBySourceSubAndConfig(String sourceType, Long sourceSubId, Integer configId) {
+ return logMapper.selectBySourceSubAndConfig(sourceType, sourceSubId,
+ configId == null ? 0 : configId);
+ }
+
+ @Override
+ public boolean existsProcessedBySourceSub(String sourceType, Long sourceSubId) {
+ return logMapper.countProcessedBySourceSub(sourceType, sourceSubId) > 0;
+ }
+
+ @Override
+ public int saveOrUpdate(PatSpecificArchiveGenerateLog log) {
+ if (log == null) {
+ return 0;
+ }
+ if (log.getSourceType() == null) {
+ log.setSourceType("2");
+ }
+ if (log.getConfigId() == null) {
+ log.setConfigId(0);
+ }
+ if (log.getRetryCount() == null) {
+ log.setRetryCount(0);
+ }
+ Date now = new Date();
+ log.setUpdateTime(now);
+ PatSpecificArchiveGenerateLog old = logMapper.selectBySourceSubAndConfig(
+ log.getSourceType(), log.getSourceSubId(), log.getConfigId());
+ if (old == null) {
+ log.setCreateTime(now);
+ try {
+ return logMapper.insertPatSpecificArchiveGenerateLog(log);
+ } catch (DuplicateKeyException e) {
+ // 骞跺彂涓嬪彟涓�涓嚎绋嬪凡鍐欏叆锛岃浆涓烘洿鏂帮紝淇濊瘉骞傜瓑
+ old = logMapper.selectBySourceSubAndConfig(
+ log.getSourceType(), log.getSourceSubId(), log.getConfigId());
+ if (old == null) {
+ throw e;
+ }
+ log.setId(old.getId());
+ return logMapper.updatePatSpecificArchiveGenerateLog(log);
+ }
+ }
+ log.setId(old.getId());
+ if (log.getCreateTime() == null) {
+ log.setCreateTime(old.getCreateTime());
+ }
+ return logMapper.updatePatSpecificArchiveGenerateLog(log);
+ }
+}
diff --git a/smartor/src/main/resources/mapper/smartor/PatSpecificArchiveGenerateLogMapper.xml b/smartor/src/main/resources/mapper/smartor/PatSpecificArchiveGenerateLogMapper.xml
new file mode 100644
index 0000000..ddcfef9
--- /dev/null
+++ b/smartor/src/main/resources/mapper/smartor/PatSpecificArchiveGenerateLogMapper.xml
@@ -0,0 +1,94 @@
+<?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.smartor.mapper.PatSpecificArchiveGenerateLogMapper">
+
+ <resultMap type="com.smartor.domain.PatSpecificArchiveGenerateLog" id="PatSpecificArchiveGenerateLogResult">
+ <result property="id" column="id"/>
+ <result property="sourceType" column="source_type"/>
+ <result property="sourceBizId" column="source_biz_id"/>
+ <result property="sourceBizNo" column="source_biz_no"/>
+ <result property="sourceSubId" column="source_sub_id"/>
+ <result property="patid" column="patid"/>
+ <result property="orgid" column="orgid"/>
+ <result property="campusid" column="campusid"/>
+ <result property="deptCategory" column="dept_category"/>
+ <result property="archiveType" column="archive_type"/>
+ <result property="configId" column="config_id"/>
+ <result property="archiveId" column="archive_id"/>
+ <result property="processResult" column="process_result"/>
+ <result property="processMsg" column="process_msg"/>
+ <result property="retryCount" column="retry_count"/>
+ <result property="createTime" column="create_time"/>
+ <result property="updateTime" column="update_time"/>
+ </resultMap>
+
+ <sql id="selectPatSpecificArchiveGenerateLogVo">
+ select id,
+ source_type,
+ source_biz_id,
+ source_biz_no,
+ source_sub_id,
+ patid,
+ orgid,
+ campusid,
+ dept_category,
+ archive_type,
+ config_id,
+ archive_id,
+ process_result,
+ process_msg,
+ retry_count,
+ create_time,
+ update_time
+ from pat_specific_archive_generate_log
+ </sql>
+
+ <select id="selectBySourceSubAndConfig" resultMap="PatSpecificArchiveGenerateLogResult">
+ <include refid="selectPatSpecificArchiveGenerateLogVo"/>
+ where source_type = #{sourceType}
+ and source_sub_id = #{sourceSubId}
+ and config_id = #{configId}
+ limit 1
+ </select>
+
+ <select id="countProcessedBySourceSub" resultType="int">
+ select count(1)
+ from pat_specific_archive_generate_log
+ where source_type = #{sourceType}
+ and source_sub_id = #{sourceSubId}
+ and process_result in ('1', '2', '3')
+ </select>
+
+ <insert id="insertPatSpecificArchiveGenerateLog" parameterType="com.smartor.domain.PatSpecificArchiveGenerateLog"
+ useGeneratedKeys="true" keyProperty="id">
+ insert into pat_specific_archive_generate_log
+ (source_type, source_biz_id, source_biz_no, source_sub_id, patid, orgid, campusid,
+ dept_category, archive_type, config_id, archive_id, process_result,
+ process_msg, retry_count, create_time, update_time)
+ values
+ (#{sourceType}, #{sourceBizId}, #{sourceBizNo}, #{sourceSubId}, #{patid}, #{orgid}, #{campusid},
+ #{deptCategory}, #{archiveType}, #{configId}, #{archiveId}, #{processResult},
+ #{processMsg}, #{retryCount}, #{createTime}, #{updateTime})
+ </insert>
+
+ <update id="updatePatSpecificArchiveGenerateLog" parameterType="com.smartor.domain.PatSpecificArchiveGenerateLog">
+ update pat_specific_archive_generate_log
+ <trim prefix="SET" suffixOverrides=",">
+ <if test="sourceBizNo != null">source_biz_no = #{sourceBizNo},</if>
+ <if test="sourceSubId != null">source_sub_id = #{sourceSubId},</if>
+ <if test="patid != null">patid = #{patid},</if>
+ <if test="orgid != null">orgid = #{orgid},</if>
+ <if test="campusid != null">campusid = #{campusid},</if>
+ <if test="deptCategory != null">dept_category = #{deptCategory},</if>
+ <if test="archiveType != null">archive_type = #{archiveType},</if>
+ <if test="archiveId != null">archive_id = #{archiveId},</if>
+ <if test="processResult != null">process_result = #{processResult},</if>
+ <if test="processMsg != null">process_msg = #{processMsg},</if>
+ <if test="retryCount != null">retry_count = #{retryCount},</if>
+ <if test="updateTime != null">update_time = #{updateTime},</if>
+ </trim>
+ where id = #{id}
+ </update>
+</mapper>
diff --git a/smartor/src/test/java/com/smartor/service/InhospFollowupArchiveLogicCheck.java b/smartor/src/test/java/com/smartor/service/InhospFollowupArchiveLogicCheck.java
new file mode 100644
index 0000000..a14ad68
--- /dev/null
+++ b/smartor/src/test/java/com/smartor/service/InhospFollowupArchiveLogicCheck.java
@@ -0,0 +1,130 @@
+package com.smartor.service;
+
+import com.ruoyi.patarchive.domain.PatSpecificArchiveGenerateConfig;
+import com.ruoyi.task.domain.ServiceSubtask;
+import com.smartor.service.impl.PatSpecificArchiveGenerateServiceImpl;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * 浣忛櫌闅忚鐢熸垚涓撶妗f閫昏緫鑷锛堢函 main锛屼笉渚濊禆 JUnit / Spring / 鏁版嵁搴擄級銆�
+ *
+ * <p>瑕嗙洊锛氫綇闄㈤殢璁胯寖鍥村垽鏂�佺瀹�/鐥呭尯/璇婃柇閰嶇疆鍖归厤銆丣SON/閫楀彿閰嶇疆瑙f瀽銆丮apper XML 鍙В鏋愭�с��</p>
+ */
+public final class InhospFollowupArchiveLogicCheck {
+
+ private static int passed = 0;
+ private static int failed = 0;
+
+ private static void check(String key, Object expected, Object actual) {
+ boolean ok = expected == null ? actual == null : expected.equals(actual);
+ if (ok) {
+ passed++;
+ System.out.println(" [OK] " + key + " = " + actual);
+ } else {
+ failed++;
+ System.out.println(" [FAIL] " + key + " 鏈熸湜=" + expected + " 瀹為檯=" + actual);
+ }
+ }
+
+ private static void setField(Object target, String name, Object value) throws Exception {
+ Field field = target.getClass().getDeclaredField(name);
+ field.setAccessible(true);
+ field.set(target, value);
+ }
+
+ private static ServiceSubtask subtask(String hospType, String serviceType) {
+ ServiceSubtask subtask = new ServiceSubtask();
+ subtask.setId(1001L);
+ subtask.setHospType(hospType);
+ subtask.setServiceType(serviceType);
+ return subtask;
+ }
+
+ private static PatSpecificArchiveGenerateConfig config(String deptType, String archiveType,
+ String deptCodes, String icd10Codes) {
+ PatSpecificArchiveGenerateConfig config = new PatSpecificArchiveGenerateConfig();
+ config.setId(1L);
+ config.setDeptType(deptType);
+ config.setDeptCategory("2");
+ config.setArchiveType(archiveType);
+ config.setDeptCodes(deptCodes);
+ config.setIcd10Codes(icd10Codes);
+ return config;
+ }
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("========== 浣忛櫌闅忚鐢熸垚涓撶妗f閫昏緫鑷 ==========");
+
+ PatSpecificArchiveGenerateServiceImpl service = new PatSpecificArchiveGenerateServiceImpl();
+ setField(service, "inhospFollowupServiceTypes", "2,13,18,19");
+
+ Method isInhosp = PatSpecificArchiveGenerateServiceImpl.class
+ .getDeclaredMethod("isInhospFollowup", ServiceSubtask.class);
+ isInhosp.setAccessible(true);
+
+ System.out.println("-- 1) 浣忛櫌闅忚鑼冨洿 --");
+ check("鍑洪櫌闅忚 serviceType=2", true, isInhosp.invoke(service, subtask("2", "2")));
+ check("鍏ラ櫌闅忚 serviceType=18", true, isInhosp.invoke(service, subtask("6", "18")));
+ check("闂ㄨ瘖浠诲姟 hospType=1", false, isInhosp.invoke(service, subtask("1", "3")));
+ check("瀹f暀浠诲姟 serviceType=4", false, isInhosp.invoke(service, subtask("2", "4")));
+ check("serviceType 涓虹┖", false, isInhosp.invoke(service, subtask("2", null)));
+
+ Method match = PatSpecificArchiveGenerateServiceImpl.class.getDeclaredMethod(
+ "matchConfig", PatSpecificArchiveGenerateConfig.class,
+ String.class, String.class, String.class, String.class);
+ match.setAccessible(true);
+
+ System.out.println("-- 2) 绉戝鍖归厤 --");
+ PatSpecificArchiveGenerateConfig deptConfig = config("1", "1", "[\"D001\"]", null);
+ check("绉戝 D001 鍛戒腑", true, match.invoke(service, deptConfig, "D001", null, null, null));
+ check("绉戝 D002 涓嶅懡涓�", false, match.invoke(service, deptConfig, "D002", null, null, null));
+
+ System.out.println("-- 3) 鐥呭尯鍖归厤 --");
+ PatSpecificArchiveGenerateConfig wardConfig = config("2", "3", "[\"W001\"]", null);
+ check("鐥呭尯 W001 鍛戒腑", true, match.invoke(service, wardConfig, "D001", "W001", null, null));
+ check("绉戝 D001 瀵圭梾鍖洪厤缃笉鍛戒腑", false,
+ match.invoke(service, wardConfig, "D001", "D001", null, null));
+
+ System.out.println("-- 4) 璇婃柇鍖归厤 --");
+ PatSpecificArchiveGenerateConfig diagConfig = config("1", "1", null, "[\"E46.x00x003\"]");
+ check("璇婃柇鐮佸懡涓�", true, match.invoke(service, diagConfig, "D001", null, "E46.x00x003", "钀ュ吇涓嶈壇"));
+ check("鏃犺瘖鏂爜鏃舵寜璇婃柇鍚嶇О鍏滃簳", true,
+ match.invoke(service, diagConfig, "D001", null, null, "E46.x00x003"));
+ check("璇婃柇涓嶅懡涓�", false, match.invoke(service, diagConfig, "D001", null, "R00", "鍏朵粬"));
+
+ System.out.println("-- 5) 閰嶇疆涓虹┖ / 闈炴硶 JSON --");
+ PatSpecificArchiveGenerateConfig emptyConfig = config("1", "1", null, null);
+ check("绉戝鍜岃瘖鏂兘涓虹┖", false, match.invoke(service, emptyConfig, "D001", null, null, null));
+ PatSpecificArchiveGenerateConfig commaConfig = config("1", "1", "D001,D002", null);
+ check("閫楀彿鍒嗛殧閰嶇疆鍏滃簳", true, match.invoke(service, commaConfig, "D002", null, null, null));
+
+ System.out.println("-- 6) Mapper XML 鍙В鏋愭�� --");
+ String[] xmlFiles = new String[]{
+ "smartor/src/main/resources/mapper/smartor/PatMaternityArchiveMapper.xml",
+ "smartor/src/main/resources/mapper/smartor/PatChildArchiveMapper.xml",
+ "smartor/src/main/resources/mapper/smartor/PatMaternityArchiveDetailMapper.xml",
+ "smartor/src/main/resources/mapper/smartor/PatChildArchiveDetailMapper.xml",
+ "smartor/src/main/resources/mapper/smartor/PatSpecificArchiveGenerateLogMapper.xml",
+ "ruoyi-task/src/main/resources/mapper/task/ServiceSubtaskMapper.xml"
+ };
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+ for (String xmlFile : xmlFiles) {
+ try {
+ factory.newDocumentBuilder().parse(new File(xmlFile));
+ check(xmlFile, "OK", "OK");
+ } catch (Exception e) {
+ check(xmlFile, "OK", e.getClass().getSimpleName() + ":" + e.getMessage());
+ }
+ }
+
+ System.out.println("========== 缁撴灉锛歅ASS=" + passed + "锛孎AIL=" + failed + " ==========");
+ if (failed > 0) {
+ System.exit(1);
+ }
+ }
+}
diff --git a/sql/pat_specific_archive_generate_log_and_source_20261111.sql b/sql/pat_specific_archive_generate_log_and_source_20261111.sql
new file mode 100644
index 0000000..c94af5c
--- /dev/null
+++ b/sql/pat_specific_archive_generate_log_and_source_20261111.sql
@@ -0,0 +1,105 @@
+-- =============================================================================
+-- 浣忛櫌闅忚瀹屾垚鐢熸垚濡囩/鍎跨涓撶妗f
+-- 1. 妗f涓昏〃/璇︽儏琛ㄥ鍔犳潵婧愬瓧娈�
+-- 2. 鏂板涓撶妗f鐢熸垚鏃ュ織琛紙骞傜瓑 + 琛ュ伩 + 杩芥函锛�
+-- 3. 澧炲姞鎮h�呮。妗堟煡璇㈢储寮�
+-- 鏃ユ湡锛�2026-11-11
+-- =============================================================================
+
+-- -----------------------------------------------------------------------------
+-- 1. 妗f涓昏〃鏉ユ簮瀛楁
+-- -----------------------------------------------------------------------------
+ALTER TABLE pat_maternity_archive
+ ADD COLUMN source_type CHAR(1) DEFAULT NULL COMMENT '鏉ユ簮绫诲瀷锛�1闂ㄨ瘖鎺ヨ瘖 2浣忛櫌闅忚 3鎵嬪伐鏂板',
+ ADD COLUMN source_biz_id BIGINT DEFAULT NULL COMMENT '鏉ユ簮涓氬姟ID锛氶棬璇婅褰旾D/浣忛櫌璁板綍ID',
+ ADD COLUMN source_biz_no VARCHAR(64) DEFAULT NULL COMMENT '鏉ユ簮涓氬姟缂栧彿锛氶棬璇婂彿/浣忛櫌鍙�',
+ ADD COLUMN source_sub_id BIGINT DEFAULT NULL COMMENT '鏉ユ簮闅忚瀛愪换鍔D锛歴ervice_subtask.id';
+
+ALTER TABLE pat_child_archive
+ ADD COLUMN source_type CHAR(1) DEFAULT NULL COMMENT '鏉ユ簮绫诲瀷锛�1闂ㄨ瘖鎺ヨ瘖 2浣忛櫌闅忚 3鎵嬪伐鏂板',
+ ADD COLUMN source_biz_id BIGINT DEFAULT NULL COMMENT '鏉ユ簮涓氬姟ID锛氶棬璇婅褰旾D/浣忛櫌璁板綍ID',
+ ADD COLUMN source_biz_no VARCHAR(64) DEFAULT NULL COMMENT '鏉ユ簮涓氬姟缂栧彿锛氶棬璇婂彿/浣忛櫌鍙�',
+ ADD COLUMN source_sub_id BIGINT DEFAULT NULL COMMENT '鏉ユ簮闅忚瀛愪换鍔D锛歴ervice_subtask.id';
+
+-- -----------------------------------------------------------------------------
+-- 2. 妗f璇︽儏琛ㄨˉ鍏呮潵婧愪笟鍔D/缂栧彿锛坰ource_type 鍘熻〃宸叉湁锛�
+-- -----------------------------------------------------------------------------
+ALTER TABLE pat_maternity_archive_detail
+ ADD COLUMN source_biz_id BIGINT DEFAULT NULL COMMENT '鏉ユ簮涓氬姟ID锛氶棬璇婅褰旾D/浣忛櫌璁板綍ID',
+ ADD COLUMN source_biz_no VARCHAR(64) DEFAULT NULL COMMENT '鏉ユ簮涓氬姟缂栧彿锛氶棬璇婂彿/浣忛櫌鍙�',
+ ADD COLUMN source_sub_id BIGINT DEFAULT NULL COMMENT '鏉ユ簮闅忚瀛愪换鍔D锛歴ervice_subtask.id';
+
+ALTER TABLE pat_child_archive_detail
+ ADD COLUMN source_biz_id BIGINT DEFAULT NULL COMMENT '鏉ユ簮涓氬姟ID锛氶棬璇婅褰旾D/浣忛櫌璁板綍ID',
+ ADD COLUMN source_biz_no VARCHAR(64) DEFAULT NULL COMMENT '鏉ユ簮涓氬姟缂栧彿锛氶棬璇婂彿/浣忛櫌鍙�',
+ ADD COLUMN source_sub_id BIGINT DEFAULT NULL COMMENT '鏉ユ簮闅忚瀛愪换鍔D锛歴ervice_subtask.id';
+
+-- -----------------------------------------------------------------------------
+-- 3. 鐢熸垚鏃ュ織琛�
+-- -----------------------------------------------------------------------------
+CREATE TABLE IF NOT EXISTS pat_specific_archive_generate_log
+(
+ id BIGINT NOT NULL AUTO_INCREMENT COMMENT '涓婚敭ID',
+ source_type CHAR(1) NOT NULL DEFAULT '2' COMMENT '鏉ユ簮绫诲瀷锛�1闂ㄨ瘖鎺ヨ瘖 2浣忛櫌闅忚',
+ source_biz_id BIGINT DEFAULT NULL COMMENT '鏉ユ簮涓氬姟ID锛氶棬璇婅褰旾D/浣忛櫌璁板綍ID',
+ source_biz_no VARCHAR(64) DEFAULT NULL COMMENT '鏉ユ簮涓氬姟缂栧彿锛氶棬璇婂彿/浣忛櫌鍙�',
+ source_sub_id BIGINT DEFAULT NULL COMMENT '鏉ユ簮闅忚瀛愪换鍔D锛歴ervice_subtask.id',
+ patid BIGINT DEFAULT NULL COMMENT '鎮h�匢D',
+ orgid VARCHAR(64) DEFAULT NULL COMMENT '鏈烘瀯ID',
+ campusid VARCHAR(64) DEFAULT NULL COMMENT '闄㈠尯ID',
+ dept_category CHAR(1) DEFAULT NULL COMMENT '閮ㄩ棬鍒嗙被锛�1濡囩 2鍎跨',
+ archive_type VARCHAR(32) DEFAULT NULL COMMENT '妗f绫诲瀷',
+ config_id INT NOT NULL DEFAULT 0 COMMENT '鍛戒腑鐨勯厤缃甀D锛涙湭鍛戒腑閰嶇疆鏃朵负0',
+ archive_id BIGINT DEFAULT NULL COMMENT '鐢熸垚鎴栧懡涓殑妗f涓昏〃ID',
+ process_result CHAR(1) NOT NULL COMMENT '澶勭悊缁撴灉锛�1鐢熸垚 2宸插瓨鍦ㄨ烦杩� 3鏈尮閰� 4澶辫触',
+ process_msg VARCHAR(1000) DEFAULT NULL COMMENT '澶勭悊璇存槑',
+ retry_count INT NOT NULL DEFAULT 0 COMMENT '閲嶈瘯娆℃暟',
+ create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+ update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+ PRIMARY KEY (id),
+ UNIQUE KEY uk_pasgl_source_sub_config (source_type, source_sub_id, config_id),
+ KEY idx_pasgl_biz_id (source_biz_id),
+ KEY idx_pasgl_patid (patid, dept_category, archive_type),
+ KEY idx_pasgl_archive (archive_id)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4 COMMENT ='涓撶妗f鐢熸垚鏃ュ織琛�';
+
+-- -----------------------------------------------------------------------------
+-- 4. 鎮h�呭凡鏈夋。妗堟煡璇㈢储寮�
+-- -----------------------------------------------------------------------------
+ALTER TABLE pat_maternity_archive
+ ADD INDEX idx_pma_patid_type (orgid, patid, archive_type, del_flag);
+
+ALTER TABLE pat_child_archive
+ ADD INDEX idx_pca_patid_type (orgid, patid, archive_type, del_flag);
+
+-- -----------------------------------------------------------------------------
+-- 5. 鏉ユ簮绫诲瀷瀛楀吀锛堝瀛楀吀琛ㄥ凡鏈夊悓绫诲瀷鏁版嵁锛屽彲璺宠繃锛�
+-- -----------------------------------------------------------------------------
+INSERT INTO sys_dict_type (dict_name, dict_type, status, create_by, create_time, remark)
+SELECT '涓撶妗f鏉ユ簮', 'pat_archive_source_type', '0', 'system', NOW(), '涓撶妗f鐢熸垚鏉ユ簮'
+FROM DUAL
+WHERE NOT EXISTS (
+ SELECT 1 FROM sys_dict_type WHERE dict_type = 'pat_archive_source_type'
+);
+
+INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, is_default, status, create_by, create_time, remark)
+SELECT 1, '闂ㄨ瘖鎺ヨ瘖', '1', 'pat_archive_source_type', 'N', '0', 'system', NOW(), '闂ㄨ瘖鎺ヨ瘖瀹屾垚鐢熸垚'
+FROM DUAL
+WHERE NOT EXISTS (
+ SELECT 1 FROM sys_dict_data WHERE dict_type = 'pat_archive_source_type' AND dict_value = '1'
+);
+
+INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, is_default, status, create_by, create_time, remark)
+SELECT 2, '浣忛櫌闅忚', '2', 'pat_archive_source_type', 'N', '0', 'system', NOW(), '浣忛櫌闅忚瀹屾垚鐢熸垚'
+FROM DUAL
+WHERE NOT EXISTS (
+ SELECT 1 FROM sys_dict_data WHERE dict_type = 'pat_archive_source_type' AND dict_value = '2'
+);
+
+INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, is_default, status, create_by, create_time, remark)
+SELECT 3, '鎵嬪伐鏂板', '3', 'pat_archive_source_type', 'N', '0', 'system', NOW(), '鎵嬪伐鏂板/瀵煎叆'
+FROM DUAL
+WHERE NOT EXISTS (
+ SELECT 1 FROM sys_dict_data WHERE dict_type = 'pat_archive_source_type' AND dict_value = '3'
+);
--
Gitblit v1.9.3