Add admin-frontend and user-frontend standalone projects, certification/invoice/discovery features, fix auth header and theme consistency

This commit is contained in:
TradeMate Dev
2026-05-22 18:35:30 +08:00
parent 18c6cf5406
commit 52dba37f22
79 changed files with 10333 additions and 248 deletions
+103
View File
@@ -0,0 +1,103 @@
<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">
<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
try {
const res = await translate(form.value)
result.value = res.data?.translated_text || res.translated_text || ''
} catch { ElMessage.error('翻译失败') }
finally { loading.value = false }
}
async function getReply() {
if (!replyInquiry.value.trim()) return
replyLoading.value = true
try {
const res = await translateReply({ text: replyInquiry.value })
suggestions.value = res.data?.suggestions || res.suggestions || []
} catch { ElMessage.error('生成建议失败') }
finally { replyLoading.value = false }
}
async function doExtract() {
if (!extractText.value.trim()) return
extractLoading.value = true
try {
const res = await extractInfo({ text: extractText.value })
extractResult.value = JSON.stringify(res.data || res, null, 2)
} catch { ElMessage.error('提取失败') }
finally { extractLoading.value = false }
}
function copyText(text) {
navigator.clipboard.writeText(text).then(() => ElMessage.success('已复制'))
}
</script>