From 2f09efc660bf2cc94cbc5291ad25ca06fc9bdadf Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期六, 24 一月 2026 22:03:09 +0800
Subject: [PATCH] feat: 增加OCR测试,车辆
---
app/pagesTask/create-emergency.vue | 1385 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 1,343 insertions(+), 42 deletions(-)
diff --git a/app/pagesTask/create-emergency.vue b/app/pagesTask/create-emergency.vue
index 8d590d5..146f8c0 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">
@@ -259,6 +400,41 @@
</view>
</view>
</uni-popup>
+
+ <!-- 鎷嶇収璇嗗埆寮圭獥 -->
+ <uni-popup ref="photoOCRPopup" type="bottom" :safe-area="true">
+ <view class="photo-ocr-popup">
+ <view class="popup-header">
+ <view class="popup-title">鎷嶇収璇嗗埆</view>
+ <view class="popup-close" @click="closePhotoOCRPopup">
+ <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="#007AFF"></uni-icons>
+ <text>鎷嶇収鎴栭�夋嫨鍥剧墖锛岃嚜鍔ㄨ瘑鍒浆杩愬崟淇℃伅</text>
+ </view>
+
+ <view class="image-preview" v-if="ocrImage">
+ <image :src="ocrImage" mode="aspectFit" style="width: 100%; height: 300rpx; border-radius: 10rpx;"></image>
+ </view>
+
+ <view class="ocr-actions">
+ <button class="select-btn" @click="selectImage">閫夋嫨鍥剧墖</button>
+ <button class="capture-btn" @click="captureImage">鎷嶇収</button>
+ </view>
+ </view>
+
+ <view class="popup-footer">
+ <button class="cancel-btn" @click="closePhotoOCRPopup">鍙栨秷</button>
+ <button class="confirm-btn" @click="performOCR" :disabled="ocrLoading">
+ {{ ocrLoading ? '璇嗗埆涓�...' : '寮�濮嬭瘑鍒�' }}
+ </button>
+ </view>
+ </view>
+ </uni-popup>
</scroll-view>
</template>
@@ -268,13 +444,16 @@
import uniPopup from '@/uni_modules/uni-popup/components/uni-popup/uni-popup.vue'
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 } from "@/api/dictionary"
@@ -357,7 +536,21 @@
loading: false,
// 鏅鸿兘璇嗗埆鐩稿叧
rawText: '',
- parseLoading: false
+ parseLoading: false,
+ // 鎷嶇収璇嗗埆鐩稿叧
+ ocrImage: '',
+ ocrLoading: false,
+ // 澶氬浘鐗囨媿鐓ц瘑鍒浉鍏�
+ multiOcrImages: [],
+ multiOcrLoading: false,
+ // 鍒嗛〉OCR璇嗗埆鐩稿叧
+ currentOcrPage: 1, // 褰撳墠涓婁紶鐨勯〉鐮侊細1=绗竴椤碉紝2=绗簩椤�
+ page1Image: '', // 绗竴椤靛浘鐗囷紙鍗曞浘锛�
+ page2Image: '', // 绗簩椤靛浘鐗囷紙鍗曞浘锛�
+ page1Fields: {}, // 绗竴椤佃瘑鍒粨鏋�
+ page2Fields: {}, // 绗簩椤佃瘑鍒粨鏋�
+ // 闄勪欢涓存椂瀛樺偍锛圤CR鍥剧墖锛�
+ pendingAttachments: [] // 寰呬笂浼犵殑闄勪欢鍒楄〃 [{ filePath: '', category: '1' }]
}
},
computed: {
@@ -567,11 +760,7 @@
console.log('杞嚭鍖婚櫌鍙樺寲:', hospitalData)
// 缁勪欢宸茬粡閫氳繃 v-model 鏇存柊浜� taskForm.hospitalOut
- // 濡傛灉閫夋嫨鐨勬槸"瀹朵腑"锛岃嚜鍔ㄨ缃瀹や负"鍏跺畠"
- if (hospitalData.name === '瀹朵腑') {
- this.taskForm.hospitalOut.department = '鍏跺畠'
- this.taskForm.hospitalOut.departmentId = null
- }
+ // 绉戝鐨勮缃敱 DepartmentSelector 缁勪欢鑷姩澶勭悊锛堥�氳繃 isHome 灞炴�э級
// 濡傛灉杞叆鍦板潃宸插~鍐�,鑷姩璁$畻璺濈
if (this.taskForm.hospitalIn.address) {
@@ -597,11 +786,7 @@
console.log('杞叆鍖婚櫌鍙樺寲:', hospitalData)
// 缁勪欢宸茬粡閫氳繃 v-model 鏇存柊浜� taskForm.hospitalIn
- // 濡傛灉閫夋嫨鐨勬槸"瀹朵腑"锛岃嚜鍔ㄨ缃瀹や负"鍏跺畠"
- if (hospitalData.name === '瀹朵腑') {
- this.taskForm.hospitalIn.department = '鍏跺畠'
- this.taskForm.hospitalIn.departmentId = null
- }
+ // 绉戝鐨勮缃敱 DepartmentSelector 缁勪欢鑷姩澶勭悊锛堥�氳繃 isHome 灞炴�э級
// 濡傛灉杞嚭鍦板潃宸插~鍐�,鑷姩璁$畻璺濈
if (this.taskForm.hospitalOut.address) {
@@ -813,6 +998,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
@@ -846,6 +1043,10 @@
conditionText = this.taskForm.patient.condition
}
}
+
+ // 璋冭瘯鏃ュ織锛氭鏌ヨ浆鍏ュ尰闄㈠湴鍧�
+ console.log('鏋勫缓鎻愪氦鏁版嵁 - 杞叆鍖婚櫌:', this.taskForm.hospitalIn.name)
+ console.log('鏋勫缓鎻愪氦鏁版嵁 - 杞叆鍖婚櫌鍦板潃:', this.taskForm.hospitalIn.address)
const submitData = {
taskType: 'EMERGENCY_TRANSFER',
@@ -908,8 +1109,11 @@
if (!this.validateForm()) {
return
}
-
- // 鑾峰彇褰撳墠鏃ユ湡锛堟牸寮廦YYY-MM-DD锛�
+ this.doSubmitTask();
+
+ },
+ checkTaskDp(){
+ // 鑾峰彇褰撳墠鏃ユ湡锛堟牸寮廦YYY-MM-DD锛�
const today = new Date()
const createDate = today.getFullYear() + '-' +
String(today.getMonth() + 1).padStart(2, '0') + '-' +
@@ -938,7 +1142,6 @@
this.$modal.showToast('妫�鏌ュけ璐ワ紝璇烽噸璇�')
})
},
-
// 鎵ц瀹為檯鐨勬彁浜ゆ搷浣�
doSubmitTask() {
this.$modal.confirm('纭畾瑕佷繚瀛樹换鍔″悧锛�').then(() => {
@@ -947,25 +1150,93 @@
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() {
@@ -1270,7 +1541,7 @@
findHospitalByName(name, type, restrictRegion = true) {
if (!name) return Promise.resolve(null)
const normalized = name.trim()
-
+
// 鐗规畩澶勭悊"瀹朵腑"
if (normalized === '瀹朵腑') {
// 鏌ヨ鍖婚櫌搴撲腑鐨�"瀹朵腑"璁板綍
@@ -1278,7 +1549,7 @@
const queryPromise = restrictRegion && deptId
? searchHospitalsByDeptRegion('瀹朵腑', deptId, 50)
: searchHospitals('瀹朵腑', null, 50)
-
+
return queryPromise.then(res => {
const list = res.data || []
// 鏌ユ壘鍚嶇О涓�"瀹朵腑"鐨勫尰闄㈣褰�
@@ -1303,20 +1574,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
})
},
@@ -1414,6 +1688,496 @@
console.error('璺濈璁$畻澶辫触:', error)
this.$modal.showToast('璺濈璁$畻澶辫触锛岃鎵嬪姩杈撳叆')
})
+ },
+
+ // ==================== 鎷嶇収璇嗗埆鐩稿叧鏂规硶 ====================
+
+ // 鏄剧ず鎷嶇収璇嗗埆寮圭獥
+ showPhotoOCRPopup() {
+ this.ocrImage = ''
+ this.$refs.photoOCRPopup.open()
+ },
+
+ // 鏄剧ず澶氬浘鎷嶇収璇嗗埆寮圭獥
+ 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('閫夋嫨鍥剧墖澶辫触')
+ }
+ })
+ },
+
+ // 閫夋嫨鍥剧墖
+ selectImage() {
+ uni.chooseImage({
+ count: 1,
+ sizeType: ['compressed'],
+ sourceType: ['album'],
+ success: (res) => {
+ this.ocrImage = res.tempFilePaths[0]
+ },
+ fail: (err) => {
+ console.error('閫夋嫨鍥剧墖澶辫触:', err)
+ this.$modal.showToast('閫夋嫨鍥剧墖澶辫触')
+ }
+ })
+ },
+
+ // 鎷嶇収
+ captureImage() {
+ uni.chooseImage({
+ count: 1,
+ sizeType: ['compressed'],
+ sourceType: ['camera'],
+ success: (res) => {
+ this.ocrImage = res.tempFilePaths[0]
+ },
+ 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)
+ }
+ }
+
+ // 鎻愬彇璇婃柇锛堢梾鎯咃級
+ if (fields['璇婃柇']) {
+ this.taskForm.patient.condition = fields['璇婃柇'].trim()
+ }
+
+ // 鎻愬彇琛岀▼锛堣浆鍑哄尰闄㈠拰杞叆鍖婚櫌锛�
+ if (fields['琛岀▼']) {
+ const route = fields['琛岀▼'].trim()
+ // 鎸�"-"鎴�"鈥�"鍒嗗壊琛岀▼
+ const hospitals = route.split(/[-鈥擼/).map(h => h.trim())
+ if (hospitals.length >= 2) {
+ // 绗竴涓槸杞嚭鍖婚櫌
+ this.taskForm.hospitalOut.name = hospitals[0]
+ // 绗簩涓槸杞叆鍖婚櫌
+ this.taskForm.hospitalIn.name = hospitals[1]
+
+ // 灏濊瘯浠庡尰闄㈠簱涓尮閰嶅苟琛ュ叏鍦板潃
+ Promise.all([
+ this.findHospitalByName(hospitals[0], 'out', false),
+ this.findHospitalByName(hospitals[1], 'in', false)
+ ]).then(([outHosp, inHosp]) => {
+ if (outHosp) {
+ this.taskForm.hospitalOut.id = outHosp.hospId
+ this.taskForm.hospitalOut.name = outHosp.hospName
+ if (outHosp.hospName !== '瀹朵腑') {
+ this.taskForm.hospitalOut.address = this.buildFullAddress(outHosp)
+ this.taskForm.hospitalOut.city = outHosp.hopsCity || ''
+ }
+ }
+ if (inHosp) {
+ this.taskForm.hospitalIn.id = inHosp.hospId
+ this.taskForm.hospitalIn.name = inHosp.hospName
+ if (inHosp.hospName !== '瀹朵腑') {
+ this.taskForm.hospitalIn.address = this.buildFullAddress(inHosp)
+ this.taskForm.hospitalIn.city = inHosp.hopsCity || ''
+ }
+ }
+
+ // 濡傛灉涓や釜鍖婚櫌鍦板潃閮芥湁锛岃嚜鍔ㄨ绠楄窛绂�
+ if (this.taskForm.hospitalOut.address && this.taskForm.hospitalIn.address &&
+ this.taskForm.hospitalOut.name !== '瀹朵腑' && this.taskForm.hospitalIn.name !== '瀹朵腑') {
+ this.calculateHospitalDistance()
+ }
+ })
+ }
+ }
+
+ console.log('澶氬浘OCR缁撴灉澶勭悊瀹屾垚锛岃〃鍗曟暟鎹洿鏂�')
+ },
+
+ // 鎵цOCR璇嗗埆
+ performOCR() {
+ if (!this.ocrImage) {
+ this.$modal.showToast('璇峰厛閫夋嫨鎴栨媿鎽勫浘鐗�')
+ return
+ }
+
+ this.ocrLoading = true
+
+ // 浣跨敤OCR API杩涜璇嗗埆
+ recognizeImage(this.ocrImage, 'HandWriting', 'tencent', DEFAULT_TRANSFER_ITEM_NAMES)
+ .then(response => {
+ const ocrResult = response.data.ocrResult
+ this.processOCRResult(ocrResult)
+ this.$modal.showToast('OCR璇嗗埆鎴愬姛')
+ })
+ .catch(error => {
+ console.error('OCR璇嗗埆澶辫触:', error)
+ this.$modal.showToast(`OCR璇嗗埆澶辫触: ${error.msg || '鏈煡閿欒'}`)
+ })
+ .finally(() => {
+ this.ocrLoading = false
+ this.closePhotoOCRPopup()
+ })
+ },
+
+ // 澶勭悊OCR璇嗗埆缁撴灉
+ processOCRResult(ocrResult) {
+ if (!ocrResult || !ocrResult.content) {
+ console.log('OCR璇嗗埆缁撴灉涓虹┖')
+ return
+ }
+
+ const content = ocrResult.content
+ console.log('OCR璇嗗埆鍐呭:', content)
+
+ // 鎻愬彇鎮h�呭鍚�
+ const patientNameMatch = content.match(/鎮h�呭鍚峓锛�:]?\s*([^\n锛�,銆傦紱;]+)/)
+ if (patientNameMatch && patientNameMatch[1]) {
+ this.taskForm.patient.name = patientNameMatch[1].trim()
+ }
+
+ // 鎻愬彇鎬у埆
+ const genderMatch = content.match(/鎬у埆[锛�:]?\s*([^\n锛�,銆傦紱;]+)/)
+ if (genderMatch && genderMatch[1]) {
+ const gender = genderMatch[1].trim()
+ if (gender.includes('鐢�')) {
+ this.taskForm.patient.gender = 'male'
+ } else if (gender.includes('濂�')) {
+ this.taskForm.patient.gender = 'female'
+ }
+ }
+
+ // 鎻愬彇韬唤璇佸彿
+ const idCardMatch = content.match(/韬唤璇佸彿[锛�:]?\s*([^\n锛�,銆傦紱;]+)/)
+ const signerIdMatch = content.match(/绛惧瓧浜鸿韩浠借瘉鍙风爜[锛�:]?\s*([^\n锛�,銆傦紱;]+)/)
+ if (idCardMatch && idCardMatch[1]) {
+ this.taskForm.patient.idCard = idCardMatch[1].trim()
+ } else if (signerIdMatch && signerIdMatch[1]) {
+ this.taskForm.patient.idCard = signerIdMatch[1].trim()
+ }
+
+ // 鎻愬彇鑱旂郴鐢佃瘽
+ const phoneMatch = content.match(/鑱旂郴鐢佃瘽[锛�:]?\s*([^\n锛�,銆傦紱;]+)/)
+ if (phoneMatch && phoneMatch[1]) {
+ this.taskForm.patient.phone = phoneMatch[1].trim()
+ }
+
+ // 鎻愬彇璇婃柇淇℃伅
+ const diagnosisMatch = content.match(/璇婃柇[锛�:]?\s*([^\n锛�,銆傦紱;]+)/)
+ if (diagnosisMatch && diagnosisMatch[1]) {
+ this.taskForm.patient.condition = diagnosisMatch[1].trim()
+ }
+
+ // 鎻愬彇闇�鏀粯杞繍璐圭敤锛堟垚浜や环锛�
+ const priceMatch = content.match(/闇�鏀粯杞繍璐圭敤[锛�:]?\s*([^\n锛�,銆傦紱;]+)/)
+ if (priceMatch && priceMatch[1]) {
+ // 鎻愬彇鏁板瓧閲戦
+ const priceNumber = priceMatch[1].match(/\d+(?:\.\d{1,2})?/)
+ if (priceNumber) {
+ this.taskForm.price = parseFloat(priceNumber[0]).toFixed(2)
+ }
+ }
+
+ // 鎻愬彇鏃ユ湡
+ const dateMatch = content.match(/鏃ユ湡[锛�:]?\s*([^\n锛�,銆傦紱;]+)/)
+ if (dateMatch && dateMatch[1]) {
+ const dateString = dateMatch[1].trim()
+ // 灏濊瘯瑙f瀽鏃ユ湡鏍煎紡
+ const dateFormatted = this.formatDateString(dateString)
+ if (dateFormatted) {
+ this.taskForm.transferTime = dateFormatted
+ }
+ }
+
+ // 鎻愬彇琛岀▼锛堣浆鍑哄尰闄㈠拰杞叆鍖婚櫌锛�
+ const routeMatch = content.match(/琛岀▼[锛�:]?\s*([^\n]+)/)
+ if (routeMatch && routeMatch[1]) {
+ const route = routeMatch[1].trim()
+ // 鎸�"-"鍒嗗壊琛岀▼锛岃幏鍙栬浆鍑哄拰杞叆鍖婚櫌
+ const hospitals = route.split(/[-鈥擼/).map(h => h.trim())
+ if (hospitals.length >= 2) {
+ // 绗竴涓槸杞嚭鍖婚櫌
+ this.taskForm.hospitalOut.name = hospitals[0]
+ // 绗簩涓槸杞叆鍖婚櫌
+ this.taskForm.hospitalIn.name = hospitals[1]
+ }
+ }
+
+ // 鎻愬彇瀹跺睘绛惧悕鎴栨湰浜轰綔涓鸿仈绯讳汉
+ const familyContactMatch = content.match(/(?:瀹跺睘绛惧悕|鏈汉)[锛�:]?\s*([^\n锛�,銆傦紱;]+)/)
+ if (familyContactMatch && familyContactMatch[1]) {
+ this.taskForm.patient.contact = familyContactMatch[1].trim()
+ }
+
+ // 鎻愬彇鎮h�呯鍚嶏紙鎵嬪嵃锛変綔涓鸿仈绯讳汉
+ const patientSignatureMatch = content.match(/鎮h�呯鍚嶏紙鎵嬪嵃锛塠锛�:]?\s*([^\n锛�,銆傦紱;]+)/)
+ if (patientSignatureMatch && patientSignatureMatch[1]) {
+ if (!this.taskForm.patient.contact) {
+ this.taskForm.patient.contact = patientSignatureMatch[1].trim()
+ }
+ }
+
+ console.log('OCR缁撴灉澶勭悊瀹屾垚锛岃〃鍗曟暟鎹洿鏂�')
+ },
+
+ // 鏍煎紡鍖栨棩鏈熷瓧绗︿覆锛堣繑鍥� yyyy-MM-dd HH:mm:ss 鏍煎紡锛�
+ formatDateString(dateStr) {
+ // 灏濊瘯涓嶅悓鐨勬棩鏈熸牸寮�
+ let cleaned = dateStr.replace(/[骞存湀]/g, '-').replace(/[鏃ュ彿]/g, '')
+
+ let dateResult = ''
+
+ // 濡傛灉鏄痀YMMDD鏍煎紡
+ if (/^\d{6}$/.test(cleaned)) {
+ const year = '20' + cleaned.substring(0, 2)
+ const month = cleaned.substring(2, 4)
+ const day = cleaned.substring(4, 6)
+ dateResult = `${year}-${month}-${day}`
+ }
+ // 濡傛灉鏄痀YYYMMDD鏍煎紡
+ else if (/^\d{8}$/.test(cleaned)) {
+ const year = cleaned.substring(0, 4)
+ const month = cleaned.substring(4, 6)
+ const day = cleaned.substring(6, 8)
+ dateResult = `${year}-${month}-${day}`
+ }
+ // 濡傛灉宸茬粡鏄悎鐞嗘牸寮忥紝鐩存帴浣跨敤
+ else if (cleaned.match(/^\d{4}[-/]\d{1,2}[-/]\d{1,2}$/)) {
+ dateResult = cleaned.replace(/[//]/g, '-')
+ }
+ // 濡傛灉宸茬粡鍖呭惈鏃跺垎绉掞紝鐩存帴杩斿洖
+ else if (cleaned.match(/^\d{4}[-/]\d{1,2}[-/]\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2}$/)) {
+ return cleaned.replace(/[//]/g, '-')
+ }
+ else {
+ dateResult = dateStr
+ }
+
+ // 濡傛灉鏃ユ湡鏍煎紡姝g‘锛屾坊鍔犻粯璁ゆ椂鍒嗙 00:00:00
+ if (dateResult && dateResult.match(/^\d{4}-\d{1,2}-\d{1,2}$/)) {
+ return dateResult + ' 00:00:00'
+ }
+
+ return dateResult
}
}
}
@@ -1449,7 +2213,9 @@
color: #333;
}
- .smart-parse-btn {
+ .smart-parse-btn,
+ .ocr-page-btn {
+ position: relative;
display: flex;
flex-direction: column;
align-items: center;
@@ -1458,7 +2224,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;
}
}
@@ -1826,4 +2638,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