diff --git a/src/components/ImageRecognition.vue b/src/components/ImageRecognition.vue
index 1d2c012..f285360 100644
--- a/src/components/ImageRecognition.vue
+++ b/src/components/ImageRecognition.vue
@@ -57,9 +57,11 @@
驿站:{{ station.name }}
-
- 取件码:
{{ code }}
-
+
+
+ 取件码:{{ code }}
+
+
@@ -115,21 +117,28 @@ export default {
if (!selectedFile.value || isRecognizing.value) return
isRecognizing.value = true
- recognitionStatus.value = 'AI 识别中...'
+ recognitionStatus.value = 'AI 识别中,请稍候...'
statusClass.value = 'status-processing'
try {
const formData = new FormData()
formData.append('file', selectedFile.value)
+ // 添加超时处理
+ const controller = new AbortController()
+ const timeoutId = setTimeout(() => controller.abort(), 60000) // 60秒超时
+
const response = await apiClient.post('/api/ai/extract_pickup_code', formData, {
headers: {
'Content-Type': 'multipart/form-data'
- }
+ },
+ signal: controller.signal
})
+ clearTimeout(timeoutId) // 清除超时
+
if (response.data && response.data.code === 200) {
- recognitionResult.value = response.data.data
+ recognitionResult.value = processRecognitionData(response.data.data)
recognitionStatus.value = '识别成功!'
statusClass.value = 'status-success'
} else {
@@ -138,22 +147,77 @@ export default {
}
} catch (error) {
console.error('识别失败:', error)
- recognitionStatus.value = '识别失败,请重试'
+
+ if (error.name === 'AbortError' || error.code === 'ECONNABORTED') {
+ recognitionStatus.value = '请求超时,请检查网络或稍后重试'
+ } else {
+ recognitionStatus.value = '识别失败,请重试'
+ }
+
statusClass.value = 'status-error'
} finally {
isRecognizing.value = false
}
}
+ // 处理识别数据
+ const processRecognitionData = (data) => {
+ // 检查数据是否为数组格式
+ if (Array.isArray(data)) {
+ // 从数组中获取第一个元素
+ const firstItem = data[0]
+
+ // 构建格式化文本
+ let formattedText = ''
+ if (firstItem && firstItem.stations) {
+ firstItem.stations.forEach(station => {
+ formattedText += `驿站:${station.name}\n`
+ if (station.pickup_codes && station.pickup_codes.length > 0) {
+ station.pickup_codes.forEach(code => {
+ formattedText += `取件码:${code}\n`
+ })
+ }
+ formattedText += '\n'
+ })
+ }
+
+ // 返回处理后的数据结构
+ return {
+ raw: firstItem || { stations: [] },
+ formatted_text: formattedText.trim()
+ }
+ } else {
+ // 如果不是数组格式,直接返回原始数据
+ return data
+ }
+ }
+
// 复制到剪贴板
const copyToClipboard = (text) => {
+ const tempCopyStatus = recognitionStatus.value
+ const tempStatusClass = statusClass.value
+
navigator.clipboard.writeText(text)
.then(() => {
- alert('取件码已复制到剪贴板')
+ recognitionStatus.value = '取件码已复制到剪贴板'
+ statusClass.value = 'status-success'
+
+ // 3秒后恢复原状态
+ setTimeout(() => {
+ recognitionStatus.value = tempCopyStatus
+ statusClass.value = tempStatusClass
+ }, 3000)
})
.catch(err => {
console.error('复制失败:', err)
- alert('复制失败,请手动复制')
+ recognitionStatus.value = '复制失败,请手动复制'
+ statusClass.value = 'status-error'
+
+ // 3秒后恢复原状态
+ setTimeout(() => {
+ recognitionStatus.value = tempCopyStatus
+ statusClass.value = tempStatusClass
+ }, 3000)
})
}
@@ -377,16 +441,24 @@ export default {
}
.station-item {
- padding: 10px;
+ padding: 15px;
background-color: #FFFFFF;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ margin-bottom: 15px;
}
.station-name {
- font-weight: 500;
+ font-weight: 600;
color: #333333;
- margin-bottom: 8px;
+ margin-bottom: 12px;
+ font-size: 16px;
+}
+
+.pickup-codes-container {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
}
.pickup-code {
diff --git a/src/services/api.js b/src/services/api.js
index 915d543..e5fa55a 100644
--- a/src/services/api.js
+++ b/src/services/api.js
@@ -4,7 +4,7 @@ import config from './config'
// 创建 axios 实例
const apiClient = axios.create({
baseURL: config.API_URL,
- timeout: 10000, // 请求超时时间
+ timeout: 30000, // 增加到30秒
headers: {
'Content-Type': 'application/json'
}