Files
trade-assistant/user-frontend/src/views/Translate.vue
T
TradeMate Dev bc48c220a0 Add user-friendly loading feedback for all AI/long-running operations
- Discovery: show '搜索中约需30-60秒' message, auto-save to history, timeout hint
- Discovery extract/outreach: show '正在分析网站/生成文案' loading message
- Translate: inline '翻译中...' placeholder while waiting
- Marketing: inline 'AI 生成中...' placeholder, success feedback
- Quotations AI: inline progress text + ElMessage.info during generation
- Analytics: add v-loading skeleton with '加载数据分析中...'
- Notifications: add v-loading skeleton with '加载通知中...'
- Followup: wire up '扫描跟进提醒' button with AI progress indicator
2026-05-27 16:22:07 +08:00

117 lines
4.6 KiB
Vue

<template>
<div>
<el-card shadow="never">
<template #header><span>文本翻译</span></template>
<el-input v-model="form.text" type="textarea" :rows="5" placeholder="输入需要翻译的外贸文本..." />
<div style="margin:16px 0;display:flex;gap:12px;align-items:center;flex-wrap:wrap">
<el-select v-model="form.target_lang" style="width:160px">
<el-option label="英语" value="en" />
<el-option label="中文" value="zh" />
<el-option label="西班牙语" value="es" />
<el-option label="日语" value="ja" />
</el-select>
<el-button type="primary" :loading="loading" @click="doTranslate">翻译</el-button>
<el-button @click="showReply = !showReply">回复建议</el-button>
<el-button @click="showExtract = !showExtract">信息提取</el-button>
</div>
<div v-if="result" style="padding:16px;background:#f5f5f5;border-radius:6px">
<p style="white-space:pre-wrap">{{ result }}</p>
<div style="margin-top:8px;display:flex;gap:8px">
<el-button text type="primary" size="small" @click="copyText(result)">复制</el-button>
</div>
</div>
</el-card>
<el-card v-if="showReply" shadow="never" style="margin-top:16px">
<template #header><span>回复建议</span></template>
<el-input v-model="replyInquiry" type="textarea" :rows="3" placeholder="输入客户询盘内容..." />
<div style="margin-top:12px;display:flex;gap:8px">
<el-button type="primary" :loading="replyLoading" @click="getReply">生成建议</el-button>
</div>
<div v-if="suggestions.length" style="margin-top:12px">
<el-card v-for="(s, i) in suggestions" :key="i" shadow="hover" style="margin-bottom:8px">
<template #header>
<span style="font-weight:500">{{ s.tone || s.style || '建议 ' + (i+1) }}</span>
</template>
<p style="white-space:pre-wrap">{{ s.content || s.text }}</p>
<el-button text type="primary" size="small" style="margin-top:8px" @click="copyText(s.content || s.text)">复制</el-button>
</el-card>
</div>
</el-card>
<el-card v-if="showExtract" shadow="never" style="margin-top:16px">
<template #header><span>信息提取</span></template>
<el-input v-model="extractText" type="textarea" :rows="3" placeholder="输入要提取信息的文本..." />
<div style="margin-top:12px">
<el-button type="primary" :loading="extractLoading" @click="doExtract">提取</el-button>
</div>
<pre v-if="extractResult" style="margin-top:12px;padding:12px;background:#f5f5f5;border-radius:6px;white-space:pre-wrap">{{ extractResult }}</pre>
</el-card>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { translate, translateReply, extractInfo } from '@/api'
import { ElMessage } from 'element-plus'
const form = ref({ text: '', target_lang: 'en' })
const loading = ref(false)
const result = ref('')
const showReply = ref(false)
const showExtract = ref(false)
const replyInquiry = ref('')
const replyLoading = ref(false)
const suggestions = ref([])
const extractText = ref('')
const extractLoading = ref(false)
const extractResult = ref('')
async function doTranslate() {
if (!form.value.text.trim()) return
loading.value = true
result.value = '翻译中...'
try {
const res = await translate(form.value)
result.value = res.data?.translated_text || res.translated_text || ''
} catch {
result.value = ''
ElMessage.error('翻译失败')
}
finally { loading.value = false }
}
async function getReply() {
if (!replyInquiry.value.trim()) return
replyLoading.value = true
suggestions.value = [{ content: '生成中...', tone: '处理中' }]
try {
const res = await translateReply({ text: replyInquiry.value })
suggestions.value = res.data?.suggestions || res.suggestions || []
if (!suggestions.length) ElMessage.info('未生成建议,请尝试修改询盘内容')
} catch {
suggestions.value = []
ElMessage.error('生成建议失败')
}
finally { replyLoading.value = false }
}
async function doExtract() {
if (!extractText.value.trim()) return
extractLoading.value = true
extractResult.value = '提取中...'
try {
const res = await extractInfo({ text: extractText.value })
extractResult.value = JSON.stringify(res.data || res, null, 2)
} catch {
extractResult.value = ''
ElMessage.error('提取失败')
}
finally { extractLoading.value = false }
}
function copyText(text) {
navigator.clipboard.writeText(text).then(() => ElMessage.success('已复制'))
}
</script>