From 0ffdf00009b0bede0859fa33deddefb55c075a7b Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期日, 01 二月 2026 16:42:36 +0800
Subject: [PATCH] feat:优化增加任务同步接口,允许前端手动控制同步
---
app/pagesTask/create-emergency.vue | 1477 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 1,358 insertions(+), 119 deletions(-)
diff --git a/app/pagesTask/create-emergency.vue b/app/pagesTask/create-emergency.vue
index a752eda..d1adac9 100644
--- a/app/pagesTask/create-emergency.vue
+++ b/app/pagesTask/create-emergency.vue
@@ -8,8 +8,149 @@
<view class="smart-parse-btn" @click="showSmartParsePopup">
<uni-icons type="compose" size="20" color="#007AFF"></uni-icons>
<text>鏅鸿兘璇嗗埆</text>
+ </view>
+ <view class="multi-photo-ocr-btn" @click="showMultiPhotoOCRPopup">
+ <uni-icons type="images" size="20" color="#FF6B00"></uni-icons>
+ <text>鎷嶇収璇嗗埆</text>
</view>
</view>
+
+ <!-- 澶氬浘鐗囨媿鐓ц瘑鍒脊绐� -->
+ <uni-popup ref="multiPhotoOCRPopup" type="bottom" :safe-area="true">
+ <view class="photo-ocr-popup">
+ <view class="popup-header">
+ <view class="popup-title">
+ <uni-icons type="images" size="22" color="#FF6B00"></uni-icons>
+ <text>鎷嶇収璇嗗埆 - 鐭ユ儏鍚屾剰涔�</text>
+ </view>
+ <view class="popup-close" @click="closeMultiPhotoOCRPopup">
+ <uni-icons type="closeempty" size="24" color="#333"></uni-icons>
+ </view>
+ </view>
+
+ <view class="ocr-content">
+ <view class="ocr-tip">
+ <uni-icons type="info" size="18" color="#FF6B00"></uni-icons>
+ <text>璇峰垎鍒笂浼犵煡鎯呭悓鎰忎功鐨勭涓�椤靛拰绗簩椤碉紝绯荤粺灏嗚嚜鍔ㄨ瘑鍒苟濉厖鍒拌〃鍗曚腑</text>
+ </view>
+
+ <!-- 鐭ユ儏鍚屾剰涔︾涓�椤� -->
+ <view class="page-upload-section first-page">
+ <view class="page-header">
+ <view class="page-title">
+ <view class="page-badge">
+ <uni-icons type="compose" size="18" color="#52c41a"></uni-icons>
+ <text class="page-number">1</text>
+ </view>
+ <view class="page-info">
+ <text class="page-main-title">鐭ユ儏鍚屾剰涔︾涓�椤�</text>
+ <text class="page-sub-title">鎮h�呭熀鏈俊鎭〉</text>
+ </view>
+ </view>
+ <!-- 鍙湁鏈笂浼犳椂鏄剧ず+鍙� -->
+ <view class="upload-btn green" @click="selectPage1Images" v-if="!page1Image">
+ <uni-icons type="plusempty" size="30" color="#52c41a"></uni-icons>
+ </view>
+ </view>
+
+ <!-- 璇嗗埆瀛楁鎻愮ず -->
+ <view class="field-hint" v-if="!page1Image">
+ <text>璇嗗埆瀛楁锛氭偅鑰呭鍚嶃�佹�у埆銆佸勾榫勩�佽韩浠借瘉鍙枫�佽瘖鏂�佽浆杩愯垂鐢ㄣ�佽绋嬨�佸紑濮嬫椂闂淬�佺粨鏉熸椂闂淬�佸灞炵鍚�</text>
+ </view>
+
+ <!-- 鍗曞浘棰勮 -->
+ <view class="single-image-container" v-if="page1Image">
+ <image :src="page1Image" mode="aspectFit" class="preview-image"></image>
+ <view class="delete-btn" @click="deletePage1Image">
+ <uni-icons type="closeempty" size="20" color="#fff"></uni-icons>
+ </view>
+ <view class="image-status">
+ <uni-icons type="checkmarkempty" size="16" color="#fff"></uni-icons>
+ <text>宸蹭笂浼�</text>
+ </view>
+ </view>
+
+ <!-- 绗竴椤佃瘑鍒粨鏋� -->
+ <view class="recognition-result" v-if="Object.keys(page1Fields).length > 0">
+ <view class="result-title">
+ <uni-icons type="checkmarkempty" size="18" color="#52c41a"></uni-icons>
+ <text>璇嗗埆缁撴灉</text>
+ <text class="result-count">(鍏眥{ Object.keys(page1Fields).length }}涓瓧娈�)</text>
+ </view>
+ <view class="field-list">
+ <view class="field-item" v-for="(value, key) in page1Fields" :key="key">
+ <text class="field-name">{{ key }}</text>
+ <text class="field-value">{{ value || '鏈瘑鍒�' }}</text>
+ </view>
+ </view>
+ </view>
+ </view>
+
+ <!-- 鐭ユ儏鍚屾剰涔︾浜岄〉 -->
+ <view class="page-upload-section second-page">
+ <view class="page-header">
+ <view class="page-title">
+ <view class="page-badge">
+ <uni-icons type="compose" size="18" color="#FF6B00"></uni-icons>
+ <text class="page-number">2</text>
+ </view>
+ <view class="page-info">
+ <text class="page-main-title">鐭ユ儏鍚屾剰涔︾浜岄〉</text>
+ <text class="page-sub-title">绛惧悕涓庤仈绯讳俊鎭〉</text>
+ </view>
+ </view>
+ <!-- 鍙湁鏈笂浼犳椂鏄剧ず+鍙� -->
+ <view class="upload-btn orange" @click="selectPage2Images" v-if="!page2Image">
+ <uni-icons type="plusempty" size="30" color="#FF6B00"></uni-icons>
+ </view>
+ </view>
+
+ <!-- 璇嗗埆瀛楁鎻愮ず -->
+ <view class="field-hint" v-if="!page2Image">
+ <text>璇嗗埆瀛楁锛氭偅鑰呯鍚嶃�佺瀛椾汉韬唤璇佸彿銆佺瀛楁棩鏈熴�佽仈绯荤數璇濄�佺瀛椾汉鍏崇郴</text>
+ </view>
+
+ <!-- 鍗曞浘棰勮 -->
+ <view class="single-image-container" v-if="page2Image">
+ <image :src="page2Image" mode="aspectFit" class="preview-image"></image>
+ <view class="delete-btn" @click="deletePage2Image">
+ <uni-icons type="closeempty" size="20" color="#fff"></uni-icons>
+ </view>
+ <view class="image-status">
+ <uni-icons type="checkmarkempty" size="16" color="#fff"></uni-icons>
+ <text>宸蹭笂浼�</text>
+ </view>
+ </view>
+
+ <!-- 绗簩椤佃瘑鍒粨鏋� -->
+ <view class="recognition-result" v-if="Object.keys(page2Fields).length > 0">
+ <view class="result-title">
+ <uni-icons type="checkmarkempty" size="18" color="#FF6B00"></uni-icons>
+ <text>璇嗗埆缁撴灉</text>
+ <text class="result-count">(鍏眥{ Object.keys(page2Fields).length }}涓瓧娈�)</text>
+ </view>
+ <view class="field-list">
+ <view class="field-item" v-for="(value, key) in page2Fields" :key="key">
+ <text class="field-name">{{ key }}</text>
+ <text class="field-value">{{ value || '鏈瘑鍒�' }}</text>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+
+ <view class="popup-footer">
+ <button class="cancel-btn" @click="closeMultiPhotoOCRPopup">鍙栨秷</button>
+ <button
+ class="confirm-btn"
+ @click="applyOcrResult"
+ :disabled="Object.keys(page1Fields).length === 0 && Object.keys(page2Fields).length === 0"
+ >
+ 搴旂敤鍒拌〃鍗�
+ </button>
+ </view>
+ </view>
+ </uni-popup>
<view class="form-section">
<view class="form-item">
@@ -65,7 +206,7 @@
label="鎵ц浠诲姟浜哄憳"
:required="false"
:auto-add-current-user="true"
- :current-user-removable="false"
+ :current-user-removable="true"
:branch-dept-ids="allOrganizationIds"
@change="onStaffChange"
/>
@@ -144,28 +285,60 @@
label="鍖婚櫌鍚嶇О"
address-label="杞嚭鍦板潃"
:required="true"
- :department-required="true"
+ :show-department="false"
v-model="taskForm.hospitalOut"
:dept-id="selectedOrganizationId"
:region="selectedRegion"
- :department-options="departmentOptions"
@change="onHospitalOutChange"
@address-selected="onHospitalOutAddressSelected"
/>
+ <DepartmentSelector
+ label="杞嚭绉戝"
+ :required="true"
+ v-model="taskForm.hospitalOut.department"
+ :department-id="taskForm.hospitalOut.departmentId"
+ :is-home="taskForm.hospitalOut.name === '瀹朵腑'"
+ @change="onHospitalOutDepartmentChange"
+ />
+
+ <view class="form-item">
+ <view class="form-label">搴婂彿</view>
+ <input
+ class="form-input"
+ placeholder="璇疯緭鍏ュ簥鍙�"
+ v-model="taskForm.hospitalOut.bedNumber"
+ />
+ </view>
<view class="form-section-title">杞叆鍖婚櫌淇℃伅</view>
<HospitalSelector
label="鍖婚櫌鍚嶇О"
address-label="杞叆鍦板潃"
:required="true"
- :department-required="true"
+ :show-department="false"
v-model="taskForm.hospitalIn"
:dept-id="selectedOrganizationId"
:region="selectedRegion"
- :department-options="departmentOptions"
@change="onHospitalInChange"
@address-selected="onHospitalInAddressSelected"
/>
+ <DepartmentSelector
+ label="杞叆绉戝"
+ :required="true"
+ v-model="taskForm.hospitalIn.department"
+ :department-id="taskForm.hospitalIn.departmentId"
+ :is-home="taskForm.hospitalIn.name === '瀹朵腑'"
+ @change="onHospitalInDepartmentChange"
+ />
+
+ <view class="form-item">
+ <view class="form-label">搴婂彿</view>
+ <input
+ class="form-input"
+ placeholder="璇疯緭鍏ュ簥鍙�"
+ v-model="taskForm.hospitalIn.bedNumber"
+ />
+ </view>
<view class="form-item">
<view class="form-label required">杞繍鍏噷鏁�</view>
@@ -234,24 +407,28 @@
import { mapState } from 'vuex'
import uniDatetimePicker from '@/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue'
import uniPopup from '@/uni_modules/uni-popup/components/uni-popup/uni-popup.vue'
-import { addTask } from "@/api/task"
+import { addTask, checkTaskDuplicate } from "@/api/task"
import { listAvailableVehicles, getUserBoundVehicle } from "@/api/vehicle"
-import { searchHospitals, searchHospitalsByDeptRegion } from "@/api/hospital"
+import { searchHospitals, searchHospitalsByDeptRegion, searchHospitalsByKeywords } from "@/api/hospital"
import DepartureSelector from './components/DepartureSelector.vue'
import { calculateTianDiTuDistance } from "@/api/map"
import { listBranchUsers } from "@/api/system/user"
import { searchIcd10 } from "@/api/icd10"
import { calculateTransferPrice } from "@/api/price"
import { checkVehicleActiveTasks } from "@/api/task"
+import { recognizeImage, batchRecognizeImages, DEFAULT_TRANSFER_ITEM_NAMES } from "@/api/ocr"
+import config from '@/config'
+import { getToken } from '@/utils/auth'
import { getDicts } from "@/api/dict"
-import { getServiceOrdAreaTypes, getServiceOrderTypes, getHospitalDepartments } from "@/api/dictionary"
+import { getServiceOrdAreaTypes, getServiceOrderTypes } from "@/api/dictionary"
import { listBranchCompany, getDept } from "@/api/system/dept"
import MapSelector from './components/map-selector.vue'
import OrganizationSelector from './components/OrganizationSelector.vue'
import HospitalSelector from './components/HospitalSelector.vue'
import DiseaseSelector from './components/DiseaseSelector.vue'
import StaffSelector from './components/StaffSelector.vue'
+import DepartmentSelector from './components/DepartmentSelector.vue'
export default {
components: {
@@ -262,7 +439,8 @@
HospitalSelector,
DiseaseSelector,
DepartureSelector,
- StaffSelector
+ StaffSelector,
+ DepartmentSelector
},
data() {
return {
@@ -320,11 +498,21 @@
emergencyTaskTypeOptions: [], // 浠诲姟绫诲瀷閫夐」锛堢敤浜巔icker鏄剧ず锛�
documentTypes: [], // 鍗曟嵁绫诲瀷鍒楄〃
documentTypeOptions: [], // 鍗曟嵁绫诲瀷閫夐」锛堢敤浜巔icker鏄剧ず锛�
- departmentOptions: [], // 绉戝瀛楀吀鏁版嵁
loading: false,
// 鏅鸿兘璇嗗埆鐩稿叧
rawText: '',
- parseLoading: false
+ parseLoading: false,
+ // 澶氬浘鐗囨媿鐓ц瘑鍒浉鍏�
+ multiOcrImages: [],
+ multiOcrLoading: false,
+ // 鍒嗛〉OCR璇嗗埆鐩稿叧
+ currentOcrPage: 1, // 褰撳墠涓婁紶鐨勯〉鐮侊細1=绗竴椤碉紝2=绗簩椤�
+ page1Image: '', // 绗竴椤靛浘鐗囷紙鍗曞浘锛�
+ page2Image: '', // 绗簩椤靛浘鐗囷紙鍗曞浘锛�
+ page1Fields: {}, // 绗竴椤佃瘑鍒粨鏋�
+ page2Fields: {}, // 绗簩椤佃瘑鍒粨鏋�
+ // 闄勪欢涓存椂瀛樺偍锛圤CR鍥剧墖锛�
+ pendingAttachments: [] // 寰呬笂浼犵殑闄勪欢鍒楄〃 [{ filePath: '', category: '1' }]
}
},
computed: {
@@ -357,8 +545,6 @@
this.getAvailableVehicles().then(() => {
this.getUserBoundVehicleInfo()
})
- // 鍔犺浇绉戝瀛楀吀鏁版嵁
- this.loadDepartments()
// 鍔犺浇浠诲姟绫诲瀷鏁版嵁
this.loadEmergencyTaskTypes()
// 鍔犺浇鍗曟嵁绫诲瀷鏁版嵁
@@ -468,22 +654,6 @@
}
},
- // 鍔犺浇绉戝鏁版嵁锛堜粠 SQL Server 鍔ㄦ�佸姞杞斤級
- loadDepartments() {
- getHospitalDepartments().then(response => {
- const list = response.data || [];
- this.departmentOptions = list.map(item => ({
- id: item.vID,
- text: item.vtext,
- dictValue: item.vtext // 涓轰簡淇濇寔鍏煎鎬э紝淇濈暀dictValue瀛楁
- }));
- // console.log('绉戝鏁版嵁鍔犺浇鎴愬姛:', this.departmentOptions);
- }).catch(error => {
- console.error('鍔犺浇绉戝鏁版嵁澶辫触:', error)
- this.departmentOptions = []
- })
- },
-
// 鍔犺浇浠诲姟绫诲瀷鏁版嵁锛堜粠 SQL Server锛�
loadEmergencyTaskTypes() {
getServiceOrderTypes().then(response => {
@@ -552,6 +722,8 @@
console.log('杞嚭鍖婚櫌鍙樺寲:', hospitalData)
// 缁勪欢宸茬粡閫氳繃 v-model 鏇存柊浜� taskForm.hospitalOut
+ // 绉戝鐨勮缃敱 DepartmentSelector 缁勪欢鑷姩澶勭悊锛堥�氳繃 isHome 灞炴�э級
+
// 濡傛灉杞叆鍦板潃宸插~鍐�,鑷姩璁$畻璺濈
if (this.taskForm.hospitalIn.address) {
// 濡傛灉涓や釜閮戒笉鏄�"瀹朵腑",浣跨敤鍖婚櫌璺濈璁$畻
@@ -576,6 +748,8 @@
console.log('杞叆鍖婚櫌鍙樺寲:', hospitalData)
// 缁勪欢宸茬粡閫氳繃 v-model 鏇存柊浜� taskForm.hospitalIn
+ // 绉戝鐨勮缃敱 DepartmentSelector 缁勪欢鑷姩澶勭悊锛堥�氳繃 isHome 灞炴�э級
+
// 濡傛灉杞嚭鍦板潃宸插~鍐�,鑷姩璁$畻璺濈
if (this.taskForm.hospitalOut.address) {
// 濡傛灉涓や釜閮戒笉鏄�"瀹朵腑",浣跨敤鍖婚櫌璺濈璁$畻
@@ -592,6 +766,28 @@
onHospitalInAddressSelected(data) {
if (this.taskForm.hospitalOut.address) {
this.calculateDistanceByManualAddress()
+ }
+ },
+
+ // 杞嚭绉戝鍙樺寲
+ onHospitalOutDepartmentChange(data) {
+ if (data && typeof data === 'object') {
+ this.taskForm.hospitalOut.department = data.department
+ this.taskForm.hospitalOut.departmentId = data.departmentId
+ } else {
+ this.taskForm.hospitalOut.department = data
+ this.taskForm.hospitalOut.departmentId = null
+ }
+ },
+
+ // 杞叆绉戝鍙樺寲
+ onHospitalInDepartmentChange(data) {
+ if (data && typeof data === 'object') {
+ this.taskForm.hospitalIn.department = data.department
+ this.taskForm.hospitalIn.departmentId = data.departmentId
+ } else {
+ this.taskForm.hospitalIn.department = data
+ this.taskForm.hospitalIn.departmentId = null
}
},
@@ -764,6 +960,18 @@
return false
}
+ // 濡傛灉杞叆鍖婚櫌鏄�滃涓�濓紝蹇呴』濉啓鍦板潃
+ if (this.taskForm.hospitalIn.name === '瀹朵腑' && !this.taskForm.hospitalIn.address) {
+ this.$modal.showToast('璇疯緭鍏ヨ浆鍏ュ湴鍧�锛堝涓級')
+ return false
+ }
+
+ // 濡傛灉杞嚭鍖婚櫌鏄�滃涓�濓紝蹇呴』濉啓鍦板潃
+ if (this.taskForm.hospitalOut.name === '瀹朵腑' && !this.taskForm.hospitalOut.address) {
+ this.$modal.showToast('璇疯緭鍏ヨ浆鍑哄湴鍧�锛堝涓級')
+ return false
+ }
+
if (!this.taskForm.transferDistance) {
this.$modal.showToast('璇疯緭鍏ヨ浆杩愬叕閲屾暟')
return false
@@ -797,6 +1005,10 @@
conditionText = this.taskForm.patient.condition
}
}
+
+ // 璋冭瘯鏃ュ織锛氭鏌ヨ浆鍏ュ尰闄㈠湴鍧�
+ console.log('鏋勫缓鎻愪氦鏁版嵁 - 杞叆鍖婚櫌:', this.taskForm.hospitalIn.name)
+ console.log('鏋勫缓鎻愪氦鏁版嵁 - 杞叆鍖婚櫌鍦板潃:', this.taskForm.hospitalIn.address)
const submitData = {
taskType: 'EMERGENCY_TRANSFER',
@@ -859,32 +1071,134 @@
if (!this.validateForm()) {
return
}
+ this.doSubmitTask();
+
+ },
+ checkTaskDp(){
+ // 鑾峰彇褰撳墠鏃ユ湡锛堟牸寮廦YYY-MM-DD锛�
+ const today = new Date()
+ const createDate = today.getFullYear() + '-' +
+ String(today.getMonth() + 1).padStart(2, '0') + '-' +
+ String(today.getDate()).padStart(2, '0')
+ const phone = this.taskForm.patient.phone
+ // 鍏堟鏌ユ槸鍚﹂噸澶�
+ uni.showLoading({
+ title: '妫�鏌ヤ腑...'
+ })
+
+ checkTaskDuplicate(phone, createDate).then(response => {
+ uni.hideLoading()
+
+ // 濡傛灉鎺ュ彛杩斿洖閿欒锛岃鏄庡瓨鍦ㄩ噸澶�
+ if (response.code !== 200) {
+ this.$modal.showToast(response.msg || '璇ヨ仈绯荤數璇濆湪褰撳ぉ宸叉湁浠诲姟锛屼笉鑳介噸澶嶆彁浜�')
+ return
+ }
+
+ // 妫�鏌ラ�氳繃锛岀户缁彁浜�
+ this.doSubmitTask()
+ }).catch(error => {
+ uni.hideLoading()
+ console.error('閲嶅鎬ф鏌ュけ璐�:', error)
+ this.$modal.showToast('妫�鏌ュけ璐ワ紝璇烽噸璇�')
+ })
+ },
+ // 鎵ц瀹為檯鐨勬彁浜ゆ搷浣�
+ doSubmitTask() {
this.$modal.confirm('纭畾瑕佷繚瀛樹换鍔″悧锛�').then(() => {
this.loading = true
const submitData = this.buildSubmitData()
addTask(submitData).then(response => {
this.loading = false
- this.$modal.showToast('浠诲姟鍒涘缓鎴愬姛')
- // 寤惰繜璺宠浆锛岃鐢ㄦ埛鐪嬪埌鎴愬姛鎻愮ず
- setTimeout(() => {
- // 璺宠浆鍒颁换鍔″垪琛ㄥ苟瑙﹀彂鍒锋柊
- uni.switchTab({
- url: '/pages/task/index',
- success: () => {
- // 浣跨敤浜嬩欢鎬荤嚎閫氱煡浠诲姟鍒楄〃椤甸潰鍒锋柊
- uni.$emit('refreshTaskList')
- }
+ // 鑾峰彇鍒涘缓鐨勪换鍔D
+ const taskId = response.taskId || (response.data && response.data.taskId) || null
+ console.log('浠诲姟鍒涘缓鎴愬姛锛宼askId:', taskId)
+
+ // 濡傛灉鏈夊緟涓婁紶鐨勯檮浠讹紙OCR鍥剧墖锛夛紝鍏堜笂浼犻檮浠�
+ if (taskId && this.pendingAttachments.length > 0) {
+ this.uploadPendingAttachments(taskId).then(() => {
+ this.$modal.showToast('浠诲姟鍒涘缓鎴愬姛锛岄檮浠跺凡涓婁紶')
+ this.navigateToTaskList()
+ }).catch(error => {
+ console.error('闄勪欢涓婁紶澶辫触:', error)
+ this.$modal.showToast('浠诲姟鍒涘缓鎴愬姛锛屼絾闄勪欢涓婁紶澶辫触')
+ this.navigateToTaskList()
})
- }, 1000)
+ } else {
+ this.$modal.showToast('浠诲姟鍒涘缓鎴愬姛')
+ this.navigateToTaskList()
+ }
}).catch(error => {
this.loading = false
console.error('浠诲姟鍒涘缓澶辫触:', error)
this.$modal.showToast('浠诲姟鍒涘缓澶辫触锛岃閲嶈瘯')
})
}).catch(() => {})
+ },
+
+ // 涓婁紶寰呬笂浼犵殑闄勪欢锛圤CR鍥剧墖锛�
+ uploadPendingAttachments(taskId) {
+ console.log('寮�濮嬩笂浼犻檮浠讹紝taskId:', taskId, '闄勪欢鏁伴噺:', this.pendingAttachments.length)
+
+ // 浣跨敤 Promise.all 骞跺彂涓婁紶鎵�鏈夐檮浠�
+ const uploadPromises = this.pendingAttachments.map(attachment => {
+ return this.uploadSingleAttachment(taskId, attachment)
+ })
+
+ return Promise.all(uploadPromises)
+ },
+
+ // 涓婁紶鍗曚釜闄勪欢
+ uploadSingleAttachment(taskId, attachment) {
+ return new Promise((resolve, reject) => {
+ uni.uploadFile({
+ url: config.baseUrl + '/task/attachment/upload/' + taskId,
+ filePath: attachment.filePath,
+ name: 'file',
+ formData: {
+ 'category': attachment.category
+ },
+ header: {
+ 'Authorization': 'Bearer ' + getToken()
+ },
+ success: function(uploadRes) {
+ if (uploadRes.statusCode === 200) {
+ const result = JSON.parse(uploadRes.data)
+ if (result.code === 200) {
+ console.log('闄勪欢涓婁紶鎴愬姛:', attachment.description)
+ resolve(result)
+ } else {
+ console.error('闄勪欢涓婁紶澶辫触:', attachment.description, result.msg)
+ reject(result)
+ }
+ } else {
+ console.error('闄勪欢涓婁紶澶辫触:', attachment.description, uploadRes)
+ reject(uploadRes)
+ }
+ },
+ fail: function(err) {
+ console.error('闄勪欢涓婁紶澶辫触:', attachment.description, err)
+ reject(err)
+ }
+ })
+ })
+ },
+
+ // 璺宠浆鍒颁换鍔″垪琛�
+ navigateToTaskList() {
+ setTimeout(() => {
+ // 璺宠浆鍒颁换鍔″垪琛ㄥ苟瑙﹀彂鍒锋柊
+ uni.switchTab({
+ url: '/pages/task/index',
+ success: () => {
+ // 浣跨敤浜嬩欢鎬荤嚎閫氱煡浠诲姟鍒楄〃椤甸潰鍒锋柊
+ uni.$emit('refreshTaskList')
+ }
+ })
+ }, 1000)
},
goBack() {
@@ -1002,20 +1316,14 @@
if (result.phone) this.taskForm.patient.phone = result.phone
if (result.price) this.taskForm.price = result.price
- // 搴旂敤绉戝淇℃伅锛堝尮閰� departmentOptions 涓殑鏁版嵁锛�
+ // 搴旂敤绉戝淇℃伅锛堥�氳繃 DepartmentSelector 缁勪欢澶勭悊锛�
if (result.departmentOut) {
- const deptOut = this.matchDepartment(result.departmentOut)
- if (deptOut) {
- this.taskForm.hospitalOut.department = deptOut.text
- this.taskForm.hospitalOut.departmentId = deptOut.id
- }
+ this.taskForm.hospitalOut.department = result.departmentOut
+ // 绉戝ID浼氬湪 DepartmentSelector 缁勪欢涓嚜鍔ㄥ尮閰�
}
if (result.departmentIn) {
- const deptIn = this.matchDepartment(result.departmentIn)
- if (deptIn) {
- this.taskForm.hospitalIn.department = deptIn.text
- this.taskForm.hospitalIn.departmentId = deptIn.id
- }
+ this.taskForm.hospitalIn.department = result.departmentIn
+ // 绉戝ID浼氬湪 DepartmentSelector 缁勪欢涓嚜鍔ㄥ尮閰�
}
// 澶勭悊鍖婚櫌鍚嶇О 鈫� 绮剧‘鍖归厤鍖婚櫌骞惰ˉ鍏ㄥ湴鍧�涓嶪D锛堜笉闄愬埗鍒嗗叕鍙稿尯鍩燂級
@@ -1161,40 +1469,6 @@
return ''
},
- // 鍖归厤绉戝锛堜紭鍏堜娇鐢� departmentOptions 涓殑鏁版嵁锛�
- matchDepartment(deptName) {
- if (!deptName || !this.departmentOptions || this.departmentOptions.length === 0) {
- return null
- }
-
- const normalized = deptName.trim().toUpperCase()
-
- // 1. 绮剧‘鍖归厤锛堜笉鍖哄垎澶у皬鍐欙級
- let matched = this.departmentOptions.find(d =>
- d.text.toUpperCase() === normalized
- )
- if (matched) return matched
-
- // 2. 鍖呭惈鍖归厤锛堢瀹ゅ悕鍖呭惈璇嗗埆鍒扮殑鍏抽敭璇嶏級
- matched = this.departmentOptions.find(d =>
- d.text.toUpperCase().includes(normalized) ||
- normalized.includes(d.text.toUpperCase())
- )
- if (matched) return matched
-
- // 3. 妯$硦鍖归厤锛堝幓闄�"绉�"銆�"瀹�"绛夊悗缂�鍐嶅尮閰嶏級
- const cleanedInput = normalized.replace(/[绉戝閮╙/g, '')
- matched = this.departmentOptions.find(d => {
- const cleanedDept = d.text.toUpperCase().replace(/[绉戝閮╙/g, '')
- return cleanedDept === cleanedInput ||
- cleanedDept.includes(cleanedInput) ||
- cleanedInput.includes(cleanedDept)
- })
- if (matched) return matched
-
- return null
- },
-
// 鎻愬彇绉戝淇℃伅
extractDepartment(text, type) {
// 甯歌绉戝鍏抽敭璇嶏紙浣滀负鍏滃簳鏂规锛�
@@ -1210,24 +1484,7 @@
'妫�楠岀', '鐥呯悊绉�', '鑽墏绉�', '钀ュ吇绉�'
]
- // 浼樺厛灏濊瘯浠� departmentOptions 涓尮閰�
- if (this.departmentOptions && this.departmentOptions.length > 0) {
- // 鏋勫缓 departmentOptions 鐨勫尮閰嶆ā寮忥紙鎸夐暱搴﹀�掑簭锛�
- const optionTexts = this.departmentOptions.map(d => d.text).sort((a, b) => b.length - a.length)
- const optionPattern = optionTexts.map(t => t.replace(/[()锛堬級]/g, '\\$&')).join('|')
-
- if (optionPattern) {
- const regex = new RegExp(`(${optionPattern})`, 'gi')
- const matches = text.match(regex)
-
- if (matches && matches.length > 0) {
- // 濡傛灉鏄浆鍑猴紝鍙栫涓�涓瀹わ紱濡傛灉鏄浆鍏ワ紝鍙栨渶鍚庝竴涓瀹�
- return type === 'out' ? matches[0] : matches[matches.length - 1]
- }
- }
- }
-
- // 鍏滃簳锛氫娇鐢ㄩ粯璁ょ瀹ゅ垪琛ㄥ尮閰�
+ // 浣跨敤榛樿绉戝鍒楄〃鍖归厤
const sortedDepts = departments.sort((a, b) => b.length - a.length)
const deptPattern = sortedDepts.join('|')
@@ -1246,7 +1503,7 @@
findHospitalByName(name, type, restrictRegion = true) {
if (!name) return Promise.resolve(null)
const normalized = name.trim()
-
+
// 鐗规畩澶勭悊"瀹朵腑"
if (normalized === '瀹朵腑') {
// 鏌ヨ鍖婚櫌搴撲腑鐨�"瀹朵腑"璁板綍
@@ -1254,7 +1511,7 @@
const queryPromise = restrictRegion && deptId
? searchHospitalsByDeptRegion('瀹朵腑', deptId, 50)
: searchHospitals('瀹朵腑', null, 50)
-
+
return queryPromise.then(res => {
const list = res.data || []
// 鏌ユ壘鍚嶇О涓�"瀹朵腑"鐨勫尰闄㈣褰�
@@ -1279,20 +1536,23 @@
}
})
}
-
- // restrictRegion=false 鏃惰蛋鍏ㄩ噺鏌ヨ锛泃rue 涓旀湁 deptId 鏃惰蛋鍖哄煙鎺ュ彛
+
+ // OCR璇嗗埆鍚庣殑鍖婚櫌鍚嶇О锛屼娇鐢ㄦ柊鐨勫垎璇嶅尮閰嶆帴鍙�
const deptId = this.selectedOrganizationId || null
- const queryPromise = (restrictRegion && deptId)
- ? searchHospitalsByDeptRegion(normalized, deptId, 50)
- : searchHospitals(normalized, null, 50)
-
- return queryPromise.then(res => {
- const list = res.data || []
- if (!list.length) return null
-
- // 鑷姩閫夋嫨绗竴涓潪"瀹朵腑"鐨勫尯闄紝濡傛灉鍏ㄦ槸"瀹朵腑"鍒欓�夌涓�涓�
- const best = this.pickBestHospitalMatch(list, normalized)
- return best || null
+
+ return searchHospitalsByKeywords(normalized, deptId, 50).then(res => {
+ const rawData = res.data || []
+ if (!rawData.length) return null
+
+ // 鎻愬彇 hospital 瀵硅薄锛堟帴鍙h繑鍥炴牸寮忥細{hospital: {...}, matchScore: ...}锛�
+ const firstItem = rawData[0]
+ const firstHospital = firstItem.hospital || firstItem
+
+ console.log(`OCR璇嗗埆鍖婚櫌"${normalized}"锛岃嚜鍔ㄩ�変腑锛�${firstHospital.hospName}锛堝尮閰嶅垎鏁帮細${firstItem.matchScore || 'N/A'}锛塦)
+ return firstHospital
+ }).catch(error => {
+ console.error(`鎼滅储鍖婚櫌"${normalized}"澶辫触:`, error)
+ return null
})
},
@@ -1390,6 +1650,448 @@
console.error('璺濈璁$畻澶辫触:', error)
this.$modal.showToast('璺濈璁$畻澶辫触锛岃鎵嬪姩杈撳叆')
})
+ },
+
+ // ==================== 鎷嶇収璇嗗埆鐩稿叧鏂规硶 ====================
+
+ // 鏄剧ず澶氬浘鎷嶇収璇嗗埆寮圭獥
+ showMultiPhotoOCRPopup() {
+ this.page1Image = ''
+ this.page2Image = ''
+ this.page1Fields = {}
+ this.page2Fields = {}
+ this.$refs.multiPhotoOCRPopup.open()
+ },
+
+ // 鍏抽棴澶氬浘鎷嶇収璇嗗埆寮圭獥
+ closeMultiPhotoOCRPopup() {
+ this.$refs.multiPhotoOCRPopup.close()
+ },
+
+ // 閫夋嫨绗竴椤靛浘鐗�
+ selectPage1Images() {
+ uni.showActionSheet({
+ itemList: ['浠庣浉鍐岄�夋嫨', '鎷嶇収'],
+ success: (res) => {
+ if (res.tapIndex === 0) {
+ this.chooseImageForPage(1, 'album')
+ } else if (res.tapIndex === 1) {
+ this.chooseImageForPage(1, 'camera')
+ }
+ }
+ })
+ },
+
+ // 閫夋嫨绗簩椤靛浘鐗�
+ selectPage2Images() {
+ uni.showActionSheet({
+ itemList: ['浠庣浉鍐岄�夋嫨', '鎷嶇収'],
+ success: (res) => {
+ if (res.tapIndex === 0) {
+ this.chooseImageForPage(2, 'album')
+ } else if (res.tapIndex === 1) {
+ this.chooseImageForPage(2, 'camera')
+ }
+ }
+ })
+ },
+
+ // 鍒犻櫎绗竴椤靛浘鐗�
+ deletePage1Image() {
+ this.page1Image = ''
+ this.page1Fields = {}
+ },
+
+ // 鍒犻櫎绗簩椤靛浘鐗�
+ deletePage2Image() {
+ this.page2Image = ''
+ this.page2Fields = {}
+ },
+
+ // 涓烘寚瀹氶〉鐮侀�夋嫨鍥剧墖锛堝崟鍥撅級
+ chooseImageForPage(page, sourceType) {
+ uni.chooseImage({
+ count: 1, // 鍙�夋嫨涓�寮犲浘鐗�
+ sizeType: ['compressed'],
+ sourceType: [sourceType],
+ success: (res) => {
+ const imagePath = res.tempFilePaths[0]
+
+ if (page === 1) {
+ this.page1Image = imagePath
+ } else {
+ this.page2Image = imagePath
+ }
+
+ // 閫夋嫨瀹屽浘鐗囧悗锛岀珛鍗宠繘琛孫CR璇嗗埆
+ this.$modal.showToast(`宸查�夋嫨鍥剧墖锛屽紑濮嬭瘑鍒�...`)
+ this.recognizeSinglePage(page)
+ },
+ fail: (err) => {
+ console.error('閫夋嫨鍥剧墖澶辫触:', err)
+ this.$modal.showToast('閫夋嫨鍥剧墖澶辫触')
+ }
+ })
+ },
+
+ // 搴旂敤OCR璇嗗埆缁撴灉鍒拌〃鍗�
+ applyOcrResult() {
+ // 鍚堝苟涓ら〉鐨勮瘑鍒粨鏋�
+ const mergedFields = { ...this.page1Fields, ...this.page2Fields }
+
+ // 澶勭悊鍚堝苟鍚庣殑璇嗗埆缁撴灉
+ this.processMultiOCRResult(mergedFields)
+
+ // 淇濆瓨OCR鍥剧墖鍒板緟涓婁紶闄勪欢鍒楄〃锛堢煡鎯呭悓鎰忎功锛屽垎绫讳负'1'锛�
+ this.pendingAttachments = []
+ if (this.page1Image) {
+ this.pendingAttachments.push({
+ filePath: this.page1Image,
+ category: '1', // 鐭ユ儏鍚屾剰涔�
+ description: '鐭ユ儏鍚屾剰涔︾涓�椤�'
+ })
+ }
+ if (this.page2Image) {
+ this.pendingAttachments.push({
+ filePath: this.page2Image,
+ category: '1', // 鐭ユ儏鍚屾剰涔�
+ description: '鐭ユ儏鍚屾剰涔︾浜岄〉'
+ })
+ }
+
+ console.log('淇濆瓨寰呬笂浼犻檮浠�:', this.pendingAttachments)
+
+ // 鍏抽棴寮圭獥
+ this.closeMultiPhotoOCRPopup()
+
+ // 娓呯┖鍥剧墖鍜岀粨鏋滐紙浣嗕繚鐣� pendingAttachments锛�
+ this.page1Image = ''
+ this.page2Image = ''
+ this.page1Fields = {}
+ this.page2Fields = {}
+
+ this.$modal.showToast('宸插簲鐢ㄥ埌琛ㄥ崟锛岀煡鎯呭悓鎰忎功灏嗗湪浠诲姟鍒涘缓鍚庝笂浼�')
+ },
+
+ // 璇嗗埆鍗曚釜椤电爜鐨勫浘鐗囷紙閫夋嫨鍚庣珛鍗宠瘑鍒級
+ recognizeSinglePage(page) {
+ const image = page === 1 ? this.page1Image : this.page2Image
+
+ if (!image) {
+ return
+ }
+
+ // 鏄剧ず鍔犺浇鎻愮ず
+ uni.showLoading({
+ title: `璇嗗埆绗�${page}椤�...`
+ })
+
+ // 绗竴椤电殑itemNames
+ const page1ItemNames = [
+ "鎮h�呭鍚�", "鎬у埆", "骞撮緞", "韬唤璇佸彿", "璇婃柇",
+ "闇�鏀粯杞繍璐圭敤", "琛岀▼", "寮�濮嬫椂闂�", "缁撴潫鏃堕棿", "瀹跺睘绛惧悕"
+ ]
+
+ // 绗簩椤电殑itemNames
+ const page2ItemNames = [
+ "鎮h�呯鍚嶏紙鎵嬪嵃锛�", "绛惧瓧浜鸿韩浠借瘉鍙风爜", "绛惧瓧浜鸿韩浠借瘉鍙�", "鏃ユ湡",
+ "鑱旂郴鐢佃瘽", "鏈汉", "绛惧瓧浜轰笌鎮h�呭叧绯�"
+ ]
+
+ const itemNames = page === 1 ? page1ItemNames : page2ItemNames
+
+ // 璋冪敤鎵归噺OCR API锛堜紶鍏ュ崟涓浘鐗囷級
+ batchRecognizeImages([image], itemNames)
+ .then(result => {
+ uni.hideLoading()
+
+ if (result.success && result.successCount > 0) {
+ // 淇濆瓨璇嗗埆缁撴灉
+ if (page === 1) {
+ this.page1Fields = result.fields
+ } else {
+ this.page2Fields = result.fields
+ }
+
+ console.log(`绗�${page}椤佃瘑鍒粨鏋�:`, result.fields)
+ this.$modal.showToast(`绗�${page}椤佃瘑鍒垚鍔焋)
+ } else {
+ this.$modal.showToast(`绗�${page}椤佃瘑鍒け璐)
+ }
+ })
+ .catch(error => {
+ uni.hideLoading()
+ console.error(`绗�${page}椤礝CR璇嗗埆澶辫触:`, error)
+ this.$modal.showToast(error.msg || `绗�${page}椤佃瘑鍒け璐)
+ })
+ },
+
+ // 澶勭悊澶氬浘OCR璇嗗埆缁撴灉
+ processMultiOCRResult(fields) {
+ console.log('澶氬浘OCR璇嗗埆缁撴灉:', fields)
+
+ // 鎻愬彇鎮h�呭鍚�
+ if (fields['鎮h�呭鍚�']) {
+ this.taskForm.patient.name = fields['鎮h�呭鍚�'].trim()
+ }
+
+ // 鎻愬彇鑱旂郴浜猴紙浼樺厛鎮h�呯鍚嶏紝鍏舵瀹跺睘绛惧悕锛屾渶鍚庢湰浜猴級
+ if (fields['鎮h�呯鍚嶏紙鎵嬪嵃锛�']) {
+ this.taskForm.patient.contact = fields['鎮h�呯鍚嶏紙鎵嬪嵃锛�'].trim()
+ } else if (fields['瀹跺睘绛惧悕']) {
+ this.taskForm.patient.contact = fields['瀹跺睘绛惧悕'].trim()
+ } else if (fields['鏈汉']) {
+ this.taskForm.patient.contact = fields['鏈汉'].trim()
+ }
+
+ // 鎻愬彇鎬у埆
+ if (fields['鎬у埆']) {
+ const gender = fields['鎬у埆'].trim()
+ if (gender.includes('鐢�')) {
+ this.taskForm.patient.gender = 'male'
+ } else if (gender.includes('濂�')) {
+ this.taskForm.patient.gender = 'female'
+ }
+ }
+
+ // 鎻愬彇韬唤璇佸彿锛堜紭鍏堣韩浠借瘉鍙凤紝鍏舵绛惧瓧浜鸿韩浠借瘉鍙风爜锛�
+ const patientIdCard = fields['韬唤璇佸彿'] || fields['鎮h�呰韩浠借瘉鍙�']
+ const signerIdCard = fields['绛惧瓧浜鸿韩浠借瘉鍙风爜'] || fields['绛惧瓧浜鸿韩浠借瘉鍙�']
+
+ if (patientIdCard) {
+ this.taskForm.patient.idCard = patientIdCard.trim()
+ } else if (signerIdCard) {
+ this.taskForm.patient.idCard = signerIdCard.trim()
+ }
+
+ // 鎻愬彇鏃ユ湡锛堣浆杩愭椂闂达級
+ if (fields['鏃ユ湡']) {
+ const dateString = fields['鏃ユ湡'].trim()
+ const dateFormatted = this.formatDateString(dateString)
+ if (dateFormatted) {
+ this.taskForm.transferTime = dateFormatted
+ }
+ }
+
+ // 鎻愬彇鑱旂郴鐢佃瘽
+ if (fields['鑱旂郴鐢佃瘽']) {
+ this.taskForm.patient.phone = fields['鑱旂郴鐢佃瘽'].trim()
+ }
+
+ // 鎻愬彇闇�鏀粯杞繍璐圭敤锛堟垚浜や环锛�
+ if (fields['闇�鏀粯杞繍璐圭敤']) {
+ const priceText = fields['闇�鏀粯杞繍璐圭敤'].trim()
+ const priceNumber = priceText.match(/\d+(?:\.\d{1,2})?/)
+ if (priceNumber) {
+ this.taskForm.price = parseFloat(priceNumber[0]).toFixed(2)
+ }
+ }
+
+ // 鎻愬彇璇婃柇锛堢梾鎯咃級锛堥檺鍒�10涓瓧绗︿互鍐咃紝閬垮厤璇瘑鍒級
+ if (fields['璇婃柇']) {
+ const diagnosis = fields['璇婃柇'].trim()
+ // 鍙湁褰�10涓瓧绗︿互鍐呯殑璇婃柇淇℃伅鎵嶅~鍏ヨ〃鍗�
+ if (diagnosis.length <= 10) {
+ this.taskForm.patient.condition = diagnosis
+ } else {
+ console.log('璇婃柇淇℃伅杩囬暱锛屽彲鑳戒负璇瘑鍒紝宸插拷鐣�:', diagnosis)
+ }
+ }
+
+ // 鎻愬彇琛岀▼锛堣浆鍑哄尰闄㈠拰杞叆鍖婚櫌锛�
+ if (fields['琛岀▼']) {
+ const route = fields['琛岀▼'].trim()
+ console.log('銆愯绋嬨�慜CR璇嗗埆鐨勮绋嬩俊鎭�:', route)
+
+ // 鎸夊绉嶅垎闅旂鍒嗗壊琛岀▼锛�-銆佲�斻��---銆�-->銆佲啋銆佺┖鏍肩瓑
+ const hospitals = route.split(/[-鈥擼{1,3}|-->|鈫抾\s{2,}/).map(h => h.trim()).filter(h => h.length > 0)
+ console.log('銆愯绋嬨�戝垎鍓插悗鐨勫尰闄㈠垪琛�:', hospitals)
+
+ if (hospitals.length >= 2) {
+ // 绗竴涓槸杞嚭鍖婚櫌
+ const outHospital = hospitals[0]
+ this.taskForm.hospitalOut.name = outHospital
+
+ // 濡傛灍杞嚭鍖婚櫌鏄�滃涓�濓紝鎻愬彇鍚庨潰鐨勮缁嗗湴鍧�
+ if (outHospital === '瀹朵腑' && hospitals.length >= 3) {
+ // 灏嗗墿浣欓儴鍒嗕綔涓鸿缁嗗湴鍧�
+ const detailAddress = hospitals.slice(1, hospitals.length - 1).join(' ')
+ if (detailAddress) {
+ this.taskForm.hospitalOut.address = detailAddress
+ console.log('銆愯绋嬨�戣浆鍑哄涓湴鍧�:', detailAddress)
+ }
+ // 鏈�鍚庝竴涓槸杞叆鍖婚櫌
+ this.taskForm.hospitalIn.name = hospitals[hospitals.length - 1]
+ console.log('銆愯绋嬨�戣浆鍏ュ尰闄�:', hospitals[hospitals.length - 1])
+ } else {
+ // 绗簩涓槸杞叆鍖婚櫌
+ const inHospital = hospitals[1]
+ this.taskForm.hospitalIn.name = inHospital
+
+ // 濡傛灉杞叆鍖婚櫌鏄�滃涓�濓紝鎻愬彇鍚庨潰鐨勮缁嗗湴鍧�
+ if (inHospital === '瀹朵腑' && hospitals.length >= 3) {
+ // 灏嗗墿浣欓儴鍒嗕綔涓鸿缁嗗湴鍧�
+ const detailAddress = hospitals.slice(2).join(' ')
+ if (detailAddress) {
+ this.taskForm.hospitalIn.address = detailAddress
+ console.log('銆愯绋嬨�戣浆鍏ュ涓湴鍧�:', detailAddress)
+ }
+ }
+ }
+
+ // 灏濊瘯浠庡尰闄㈠簱涓尮閰嶅苟琛ュ叏鍦板潃锛堝彧鍦ㄩ潪鈥滃涓�濇椂锛�
+ const outHospitalName = this.taskForm.hospitalOut.name
+ const inHospitalName = this.taskForm.hospitalIn.name
+
+ Promise.all([
+ outHospitalName !== '瀹朵腑' ? this.findHospitalByName(outHospitalName, 'out', false) : Promise.resolve(null),
+ inHospitalName !== '瀹朵腑' ? this.findHospitalByName(inHospitalName, 'in', false) : Promise.resolve(null)
+ ]).then(([outHosp, inHosp]) => {
+ // 澶勭悊杞嚭鍖婚櫌
+ if (outHospitalName !== '瀹朵腑') {
+ if (outHosp) {
+ // 鎵惧埌鍖婚櫌锛屼娇鐢ㄥ尰闄㈠簱涓殑淇℃伅
+ this.taskForm.hospitalOut.id = outHosp.hospId
+ this.taskForm.hospitalOut.name = outHosp.hospName
+ this.taskForm.hospitalOut.address = this.buildFullAddress(outHosp)
+ this.taskForm.hospitalOut.city = outHosp.hopsCity || ''
+ console.log('銆愯绋嬨�戣浆鍑哄尰闄㈠尮閰嶆垚鍔�:', outHosp.hospName)
+ } else {
+ // 鎵句笉鍒板尰闄紝榛樿璁剧疆涓�"瀹朵腑"锛屽師鍖婚櫌鍚嶇О浣滀负鍦板潃
+ console.log('銆愯绋嬨�戣浆鍑哄尰闄㈡湭鎵惧埌锛岄粯璁よ缃负瀹朵腑锛屽湴鍧�涓�:', outHospitalName)
+ this.taskForm.hospitalOut.name = '瀹朵腑'
+ this.taskForm.hospitalOut.address = outHospitalName
+ this.taskForm.hospitalOut.id = null
+ this.taskForm.hospitalOut.city = ''
+ }
+ }
+
+ // 澶勭悊杞叆鍖婚櫌
+ if (inHospitalName !== '瀹朵腑') {
+ if (inHosp) {
+ // 鎵惧埌鍖婚櫌锛屼娇鐢ㄥ尰闄㈠簱涓殑淇℃伅
+ this.taskForm.hospitalIn.id = inHosp.hospId
+ this.taskForm.hospitalIn.name = inHosp.hospName
+ this.taskForm.hospitalIn.address = this.buildFullAddress(inHosp)
+ this.taskForm.hospitalIn.city = inHosp.hopsCity || ''
+ console.log('銆愯绋嬨�戣浆鍏ュ尰闄㈠尮閰嶆垚鍔�:', inHosp.hospName)
+ } else {
+ // 鎵句笉鍒板尰闄紝榛樿璁剧疆涓�"瀹朵腑"锛屽師鍖婚櫌鍚嶇О浣滀负鍦板潃
+ console.log('銆愯绋嬨�戣浆鍏ュ尰闄㈡湭鎵惧埌锛岄粯璁よ缃负瀹朵腑锛屽湴鍧�涓�:', inHospitalName)
+ this.taskForm.hospitalIn.name = '瀹朵腑'
+ this.taskForm.hospitalIn.address = inHospitalName
+ this.taskForm.hospitalIn.id = null
+ this.taskForm.hospitalIn.city = ''
+ }
+ }
+
+ // 濡傛灉涓や釜鍖婚櫌鍦板潃閮芥湁锛岃嚜鍔ㄨ绠楄窛绂�
+ if (this.taskForm.hospitalOut.address && this.taskForm.hospitalIn.address &&
+ this.taskForm.hospitalOut.name !== '瀹朵腑' && this.taskForm.hospitalIn.name !== '瀹朵腑') {
+ this.calculateHospitalDistance()
+ }
+ })
+ }
+ }
+
+ console.log('澶氬浘OCR缁撴灉澶勭悊瀹屾垚锛岃〃鍗曟暟鎹洿鏂�')
+ },
+
+ // 鏍煎紡鍖栨棩鏈熷瓧绗︿覆锛堣繑鍥� yyyy-MM-dd HH:mm:ss 鏍煎紡锛�
+ formatDateString(dateStr) {
+ // 灏濊瘯涓嶅悓鐨勬棩鏈熸牸寮�
+ // 鏀寔鏍煎紡锛�
+ // - yyyy骞碝M鏈坉d鏃H鏃秏m鍒�
+ // - yyyy骞碝M鏈坉d鏃�
+ // - YYYYMMDD
+ // - yyyy-MM-dd HH:mm:ss
+ console.log('灏濊瘯鏍煎紡鍖栨棩鏈熷瓧绗︿覆:', dateStr)
+
+ // 濡傛灉杈撳叆涓虹┖鎴栨棤鏁堬紝杩斿洖绌哄瓧绗︿覆
+ if (!dateStr || typeof dateStr !== 'string') {
+ console.warn('鏃ユ湡瀛楃涓叉棤鏁�:', dateStr)
+ return ''
+ }
+
+ // 娓呮礂鏃ユ湡瀛楃涓�
+ let cleaned = dateStr
+ .replace(/[骞存湀]/g, '-')
+ .replace(/[鏃ュ彿]/g, ' ') // 鏃�/鍙� 鈫� 绌烘牸锛屼繚鐣欐棩鏈熷拰鏃堕棿鐨勫垎闅�
+ .replace(/鏃�/g, ':')
+ .replace(/鍒�/g, ':')
+ .replace(/绉�/g, '')
+ .replace(/\s+/g, ' ') // 澶氫釜绌烘牸鍚堝苟涓轰竴涓�
+ .trim()
+
+ console.log('娓呯悊鍚庣殑鏃ユ湡瀛楃涓�:', cleaned)
+
+ // 鍒嗙鏃ユ湡鍜屾椂闂撮儴鍒�
+ const parts = cleaned.split(' ')
+ let datePart = parts[0] || ''
+ let timePart = parts[1] || ''
+
+ let dateResult = ''
+
+ // 澶勭悊鏃ユ湡閮ㄥ垎
+ // 濡傛灉鏄痀YMMDD鏍煎紡
+ if (/^\d{6}$/.test(datePart)) {
+ const year = '20' + datePart.substring(0, 2)
+ const month = datePart.substring(2, 4)
+ const day = datePart.substring(4, 6)
+ dateResult = `${year}-${month}-${day}`
+ }
+ // 濡傛灉鏄痀YYYMMDD鏍煎紡
+ else if (/^\d{8}$/.test(datePart)) {
+ const year = datePart.substring(0, 4)
+ const month = datePart.substring(4, 6)
+ const day = datePart.substring(6, 8)
+ dateResult = `${year}-${month}-${day}`
+ }
+ // 濡傛灉鏄痽yyy-MM-dd鎴杫yyy/MM/dd鏍煎紡
+ else if (datePart.match(/^\d{4}[-\/]\d{1,2}[-\/]\d{1,2}$/)) {
+ dateResult = datePart.replace(/\//g, '-')
+ }
+ else {
+ dateResult = datePart
+ }
+
+ // 楠岃瘉鏃ユ湡閮ㄥ垎鏄惁鏈夋晥
+ if (!dateResult.match(/^\d{4}-\d{1,2}-\d{1,2}$/)) {
+ console.warn('鏃ユ湡鏍煎紡涓嶆纭�:', dateResult)
+ return ''
+ }
+
+ // 澶勭悊鏃堕棿閮ㄥ垎
+ let timeResult = '00:00:00' // 榛樿鏃堕棿
+
+ if (timePart) {
+ // 绉婚櫎鏈熬澶氫綑鐨勫啋鍙�
+ timePart = timePart.replace(/:+$/, '')
+
+ // 鍒嗗壊鏃躲�佸垎銆佺
+ const timeParts = timePart.split(':')
+ const hour = timeParts[0] || '00'
+ const minute = timeParts[1] || '00'
+ const second = timeParts[2] || '00'
+
+ // 楠岃瘉鏃堕棿鏁板瓧鏄惁鏈夋晥
+ const hourNum = parseInt(hour, 10)
+ const minuteNum = parseInt(minute, 10)
+ const secondNum = parseInt(second, 10)
+
+ if (!isNaN(hourNum) && !isNaN(minuteNum) && !isNaN(secondNum) &&
+ hourNum >= 0 && hourNum < 24 && minuteNum >= 0 && minuteNum < 60 && secondNum >= 0 && secondNum < 60) {
+ // 琛ラ綈涓や綅鏁�
+ timeResult = `${String(hourNum).padStart(2, '0')}:${String(minuteNum).padStart(2, '0')}:${String(secondNum).padStart(2, '0')}`
+ } else {
+ console.warn('鏃堕棿鏁板�艰秴鍑鸿寖鍥达紝浣跨敤榛樿鍊�00:00:00')
+ }
+ }
+
+ const finalResult = `${dateResult} ${timeResult}`
+ console.log('鏈�缁堟牸寮忓寲缁撴灉:', finalResult)
+
+ return finalResult
}
}
}
@@ -1425,7 +2127,9 @@
color: #333;
}
- .smart-parse-btn {
+ .smart-parse-btn,
+ .ocr-page-btn {
+ position: relative;
display: flex;
flex-direction: column;
align-items: center;
@@ -1434,7 +2138,53 @@
text {
font-size: 22rpx;
+ margin-top: 4rpx;
+ }
+
+ .badge {
+ position: absolute;
+ top: 0;
+ right: 10rpx;
+ min-width: 32rpx;
+ height: 32rpx;
+ line-height: 32rpx;
+ text-align: center;
+ background-color: #ff4d4f;
+ color: white;
+ font-size: 20rpx;
+ border-radius: 16rpx;
+ padding: 0 8rpx;
+ }
+ }
+
+ .smart-parse-btn {
+ text {
color: #007AFF;
+ }
+ }
+
+ .ocr-page-btn:first-of-type {
+ text {
+ color: #52c41a;
+ }
+ }
+
+ .ocr-page-btn:last-of-type {
+ text {
+ color: #FF6B00;
+ }
+ }
+
+ .multi-photo-ocr-btn {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 10rpx 20rpx;
+
+ text {
+ font-size: 22rpx;
+ color: #FF6B00;
margin-top: 4rpx;
}
}
@@ -1802,4 +2552,493 @@
}
}
}
+
+// 鎷嶇収璇嗗埆寮圭獥鏍峰紡
+.photo-ocr-popup {
+ background-color: white;
+ border-radius: 20rpx 20rpx 0 0;
+ max-height: 80vh;
+ display: flex;
+ flex-direction: column;
+
+ .popup-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 30rpx;
+ border-bottom: 1rpx solid #f0f0f0;
+ flex-shrink: 0;
+
+ .popup-title {
+ display: flex;
+ align-items: center;
+ gap: 10rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ color: #333;
+
+ text {
+ margin-left: 8rpx;
+ }
+ }
+
+ .popup-close {
+ padding: 10rpx;
+ }
+ }
+
+ .ocr-content {
+ flex: 1;
+ padding: 30rpx;
+ overflow-y: auto;
+
+ .ocr-tip {
+ display: flex;
+ align-items: flex-start;
+ padding: 20rpx;
+ background-color: #f0f7ff;
+ border-radius: 10rpx;
+ margin-bottom: 20rpx;
+
+ text {
+ flex: 1;
+ margin-left: 10rpx;
+ font-size: 24rpx;
+ color: #666;
+ line-height: 1.6;
+ }
+ }
+
+ .image-preview {
+ margin-bottom: 20rpx;
+ border: 1rpx solid #eee;
+ border-radius: 10rpx;
+ overflow: hidden;
+ }
+
+ .multi-image-preview {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 15rpx;
+ margin-bottom: 20rpx;
+
+ .image-item {
+ position: relative;
+ width: 200rpx;
+ height: 200rpx;
+ border: 1rpx solid #eee;
+ border-radius: 10rpx;
+ overflow: hidden;
+
+ image {
+ width: 100%;
+ height: 100%;
+ }
+
+ .delete-btn {
+ position: absolute;
+ top: 5rpx;
+ right: 5rpx;
+ width: 40rpx;
+ height: 40rpx;
+ background-color: rgba(0, 0, 0, 0.6);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ }
+ }
+
+ .ocr-actions {
+ display: flex;
+ gap: 20rpx;
+
+ button {
+ flex: 1;
+ height: 80rpx;
+ border-radius: 10rpx;
+ font-size: 28rpx;
+ }
+
+ .select-btn {
+ background-color: #f5f5f5;
+ color: #333;
+ }
+
+ .capture-btn {
+ background-color: #007AFF;
+ color: white;
+ }
+ }
+
+ .image-count {
+ text-align: center;
+ margin-top: 20rpx;
+ font-size: 26rpx;
+ color: #FF6B00;
+ font-weight: bold;
+ }
+
+ // 椤甸潰涓婁紶鍖哄煙
+ .page-upload-section {
+ background: linear-gradient(135deg, #f9f9f9 0%, #ffffff 100%);
+ border-radius: 15rpx;
+ padding: 25rpx;
+ margin-bottom: 25rpx;
+ border: 2rpx solid #f0f0f0;
+ transition: all 0.3s;
+
+ &.first-page {
+ border-left: 4rpx solid #52c41a;
+
+ .page-badge {
+ background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
+
+ .page-number {
+ color: #52c41a;
+ }
+ }
+ }
+
+ &.second-page {
+ border-left: 4rpx solid #FF6B00;
+
+ .page-badge {
+ background: linear-gradient(135deg, #FF6B00 0%, #ff8c3a 100%);
+
+ .page-number {
+ color: #FF6B00;
+ }
+ }
+ }
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .page-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20rpx;
+
+ .page-title {
+ display: flex;
+ align-items: center;
+ gap: 15rpx;
+ flex: 1;
+
+ .page-badge {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 60rpx;
+ height: 60rpx;
+ background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
+ border-radius: 50%;
+ position: relative;
+
+ .page-number {
+ position: absolute;
+ bottom: -2rpx;
+ right: -2rpx;
+ width: 24rpx;
+ height: 24rpx;
+ background-color: #fff;
+ border-radius: 50%;
+ font-size: 16rpx;
+ font-weight: bold;
+ color: #52c41a;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
+ }
+ }
+
+ .page-info {
+ display: flex;
+ flex-direction: column;
+ gap: 4rpx;
+
+ .page-main-title {
+ font-size: 28rpx;
+ font-weight: bold;
+ color: #333;
+ }
+
+ .page-sub-title {
+ font-size: 22rpx;
+ color: #999;
+ }
+ }
+ }
+
+ .upload-btn {
+ width: 60rpx;
+ height: 60rpx;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.3s;
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
+
+ &.green {
+ border: 2rpx dashed #52c41a;
+ background-color: rgba(82, 196, 26, 0.05);
+ }
+
+ &.orange {
+ border: 2rpx dashed #FF6B00;
+ background-color: rgba(255, 107, 0, 0.05);
+ }
+
+ &:active {
+ transform: scale(0.95);
+ opacity: 0.8;
+ }
+ }
+ }
+
+ // 璇嗗埆瀛楁鎻愮ず
+ .field-hint {
+ background-color: #fffbe6;
+ border: 1rpx solid #ffe58f;
+ border-radius: 8rpx;
+ padding: 15rpx;
+ margin-bottom: 15rpx;
+
+ text {
+ font-size: 22rpx;
+ color: #d48806;
+ line-height: 1.6;
+ }
+ }
+
+ .images-container {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10rpx;
+ margin-bottom: 15rpx;
+
+ .image-item {
+ position: relative;
+ width: 150rpx;
+ height: 150rpx;
+ border: 1rpx solid #eee;
+ border-radius: 10rpx;
+ overflow: hidden;
+
+ image {
+ width: 100%;
+ height: 100%;
+ }
+
+ .delete-btn {
+ position: absolute;
+ top: 5rpx;
+ right: 5rpx;
+ width: 35rpx;
+ height: 35rpx;
+ background-color: rgba(0, 0, 0, 0.6);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ }
+ }
+
+ // 鍗曞浘棰勮鍖哄煙
+ .single-image-container {
+ position: relative;
+ width: 100%;
+ height: 400rpx;
+ border: 1rpx solid #eee;
+ border-radius: 10rpx;
+ overflow: hidden;
+ margin-bottom: 15rpx;
+ background-color: #f5f5f5;
+
+ .preview-image {
+ width: 100%;
+ height: 100%;
+ }
+
+ .delete-btn {
+ position: absolute;
+ top: 10rpx;
+ right: 10rpx;
+ width: 50rpx;
+ height: 50rpx;
+ background-color: rgba(0, 0, 0, 0.6);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 2;
+
+ &:active {
+ transform: scale(0.95);
+ opacity: 0.9;
+ }
+ }
+
+ // 鍥剧墖鐘舵�佹爣绛�
+ .image-status {
+ position: absolute;
+ bottom: 10rpx;
+ left: 10rpx;
+ display: flex;
+ align-items: center;
+ gap: 5rpx;
+ padding: 8rpx 15rpx;
+ background-color: rgba(82, 196, 26, 0.9);
+ border-radius: 20rpx;
+ z-index: 2;
+
+ text {
+ font-size: 22rpx;
+ color: #fff;
+ font-weight: 500;
+ }
+ }
+ }
+
+ .recognition-result {
+ background-color: white;
+ border-radius: 10rpx;
+ padding: 15rpx;
+ border: 1rpx solid #e0e0e0;
+
+ .result-title {
+ display: flex;
+ align-items: center;
+ margin-bottom: 15rpx;
+ padding-bottom: 10rpx;
+ border-bottom: 1rpx solid #f0f0f0;
+
+ text {
+ margin-left: 8rpx;
+ font-size: 26rpx;
+ font-weight: bold;
+ color: #333;
+ }
+
+ .result-count {
+ margin-left: 8rpx;
+ font-size: 22rpx;
+ color: #999;
+ font-weight: normal;
+ }
+ }
+
+ .field-list {
+ .field-item {
+ display: flex;
+ padding: 10rpx 0;
+ border-bottom: 1rpx solid #f9f9f9;
+
+ &:last-child {
+ border-bottom: none;
+ }
+
+ .field-name {
+ min-width: 150rpx;
+ font-size: 24rpx;
+ color: #666;
+ font-weight: 500;
+
+ &::after {
+ content: ':';
+ margin-left: 4rpx;
+ }
+ }
+
+ .field-value {
+ flex: 1;
+ font-size: 24rpx;
+ color: #333;
+ word-break: break-all;
+ }
+ }
+ }
+ }
+ }
+
+ .page-indicator {
+ display: flex;
+ justify-content: center;
+ gap: 30rpx;
+ margin-top: 30rpx;
+
+ .page-dot {
+ padding: 15rpx 30rpx;
+ border: 2rpx solid #ddd;
+ border-radius: 30rpx;
+ font-size: 26rpx;
+ color: #999;
+ background-color: #f5f5f5;
+ transition: all 0.3s;
+
+ &.active {
+ border-color: #007AFF;
+ background-color: #007AFF;
+ color: white;
+ }
+
+ &.completed {
+ border-color: #52c41a;
+ color: #52c41a;
+
+ &.active {
+ background-color: #007AFF;
+ border-color: #007AFF;
+ color: white;
+ }
+ }
+ }
+ }
+ }
+
+ .popup-footer {
+ display: flex;
+ padding: 20rpx 30rpx;
+ border-top: 1rpx solid #f0f0f0;
+ gap: 20rpx;
+ flex-shrink: 0;
+ flex-wrap: wrap;
+
+ button {
+ flex: 1;
+ min-width: 160rpx;
+ height: 80rpx;
+ border-radius: 10rpx;
+ font-size: 30rpx;
+ }
+
+ .cancel-btn {
+ background-color: #f5f5f5;
+ color: #666;
+ }
+
+ .next-btn,
+ .prev-btn {
+ background-color: #52c41a;
+ color: white;
+ }
+
+ .confirm-btn {
+ background-color: #007AFF;
+ color: white;
+
+ &[disabled] {
+ background-color: #ccc;
+ color: #999;
+ }
+ }
+ }
+}
</style>
--
Gitblit v1.9.1