This commit is contained in:
aaron 2025-03-07 15:37:11 +08:00
parent b94f2935a3
commit 9e003918ea
2 changed files with 85 additions and 13 deletions

View File

@ -57,9 +57,11 @@
<div class="result-details">
<div v-for="(station, index) in recognitionResult.raw.stations" :key="index" class="station-item">
<div class="station-name">驿站{{ station.name }}</div>
<div v-for="(code, codeIndex) in station.pickup_codes" :key="codeIndex" class="pickup-code">
取件码<span class="code-value">{{ code }}</span>
<button class="btn-copy" @click="copyToClipboard(code)">复制</button>
<div class="pickup-codes-container">
<div v-for="(code, codeIndex) in station.pickup_codes" :key="codeIndex" class="pickup-code">
取件码<span class="code-value">{{ code }}</span>
<button class="btn-copy" @click="copyToClipboard(code)">复制</button>
</div>
</div>
</div>
</div>
@ -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 {

View File

@ -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'
}