feat: 管理后台完整可用 + 注册登录记日志 + 提取信息结构化展示 + 微信配置就绪
- 管理后台用户/统计/日志/配置四页签全部对接真实后端API - auth注册/登录/游客/微信登录事件写入usage_logs表 - 提取信息结果从原始JSON改为卡片式字段列表(中文标签) - 管理后台搜索按钮增加加载态和结果数提示 - 配置WECHAT_APP_ID/WECHAT_APP_SECRET - 客户/产品/报价单CRUD页面完整(导出导入批量操作)
This commit is contained in:
@@ -71,12 +71,15 @@
|
||||
<text class="result-text">{{ tryResult }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="try-extracted" v-if="tryExtracted">
|
||||
<view class="try-extracted" v-if="tryExtracted && Object.keys(tryExtracted).length">
|
||||
<view class="result-header">
|
||||
<text class="result-label">提取结果</text>
|
||||
</view>
|
||||
<view class="extracted-content">
|
||||
<text class="extracted-text">{{ tryExtracted }}</text>
|
||||
<view class="extract-field" v-for="(val, key) in tryExtracted" :key="key">
|
||||
<text class="extract-field-label">{{ extractFieldLabels[key] || key }}</text>
|
||||
<text class="extract-field-value">{{ val || '-' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -144,7 +147,7 @@
|
||||
<text class="more-icon">👨👩👧👦</text>
|
||||
<text class="more-text">团队</text>
|
||||
</view>
|
||||
<view class="more-item" @click="hasLogin ? goToPage('/pages/admin/admin') : goToLogin()">
|
||||
<view class="more-item" v-if="isAdmin" @click="goToPage('/pages/admin/admin')">
|
||||
<text class="more-icon">⚙️</text>
|
||||
<text class="more-text">管理</text>
|
||||
</view>
|
||||
@@ -272,6 +275,10 @@ const hasLogin = computed(() => {
|
||||
const isGuest = uni.getStorageSync('isGuest')
|
||||
return !!token && !isGuest
|
||||
})
|
||||
const isAdmin = computed(() => {
|
||||
return hasLogin.value && userInfo.value?.role === 'admin'
|
||||
})
|
||||
const userInfo = ref(null)
|
||||
const stats = ref({
|
||||
customers: 0,
|
||||
silentCustomers: 0,
|
||||
@@ -291,7 +298,13 @@ const generatedContent = ref([])
|
||||
|
||||
const tryText = ref('')
|
||||
const tryResult = ref('')
|
||||
const tryExtracted = ref('')
|
||||
const tryExtracted = ref(null)
|
||||
const extractFieldLabels = {
|
||||
product_name: '产品名称', quantity: '数量', price: '价格',
|
||||
currency: '货币', delivery_terms: '交货条款', target_country: '目标国家',
|
||||
intent: '意图', product_interest: '感兴趣产品', budget: '预算',
|
||||
urgency: '紧迫程度', contact_info: '联系方式',
|
||||
}
|
||||
const tryLoading = ref(false)
|
||||
|
||||
onShow(() => {
|
||||
@@ -309,7 +322,7 @@ onShow(() => {
|
||||
loadFollowupStats()
|
||||
} else {
|
||||
tryResult.value = ''
|
||||
tryExtracted.value = ''
|
||||
tryExtracted.value = null
|
||||
tryText.value = ''
|
||||
}
|
||||
})
|
||||
@@ -429,7 +442,7 @@ const handleTryTranslate = async () => {
|
||||
}
|
||||
tryLoading.value = true
|
||||
tryResult.value = ''
|
||||
tryExtracted.value = ''
|
||||
tryExtracted.value = null
|
||||
|
||||
try {
|
||||
const chinesePattern = /[\u4e00-\u9fa5]/
|
||||
@@ -455,7 +468,7 @@ const handleTryExtract = async () => {
|
||||
}
|
||||
tryLoading.value = true
|
||||
tryResult.value = ''
|
||||
tryExtracted.value = ''
|
||||
tryExtracted.value = null
|
||||
|
||||
try {
|
||||
const isGuest = uni.getStorageSync('isGuest')
|
||||
@@ -463,7 +476,7 @@ const handleTryExtract = async () => {
|
||||
? await translateApi.publicExtract(tryText.value, 'auto')
|
||||
: await translateApi.extract(tryText.value, 'auto')
|
||||
const extracted = res.extracted || {}
|
||||
tryExtracted.value = JSON.stringify(extracted, null, 2)
|
||||
tryExtracted.value = typeof extracted === 'string' ? { raw: extracted } : extracted
|
||||
uni.showToast({ title: '提取成功', icon: 'success' })
|
||||
} catch (err) {
|
||||
uni.showToast({ title: err.message || '提取失败', icon: 'none' })
|
||||
@@ -761,13 +774,20 @@ const playTryResult = () => {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.try-result, .try-extracted {
|
||||
.try-result {
|
||||
background: #f6ffed;
|
||||
border-radius: 12rpx;
|
||||
padding: 24rpx;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.try-extracted {
|
||||
background: #f9f0ff;
|
||||
border-radius: 12rpx;
|
||||
padding: 24rpx;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.result-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -802,13 +822,36 @@ const playTryResult = () => {
|
||||
padding: 16rpx;
|
||||
}
|
||||
|
||||
.result-text, .extracted-text {
|
||||
.result-text {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.extract-field {
|
||||
display: flex;
|
||||
padding: 8rpx 0;
|
||||
border-bottom: 1rpx solid rgba(114, 46, 209, 0.1);
|
||||
}
|
||||
|
||||
.extract-field:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.extract-field-label {
|
||||
width: 160rpx;
|
||||
font-size: 24rpx;
|
||||
color: #722ed1;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.extract-field-value {
|
||||
flex: 1;
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.section {
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
|
||||
Reference in New Issue
Block a user