feat:国际化页面views/application-overview (#539)

This commit is contained in:
JinTao Chen 2024-05-27 13:33:11 +08:00 committed by GitHub
parent 2c82f12571
commit 270ba18980
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 308 additions and 88 deletions

View File

@ -0,0 +1,103 @@
export default {
title: 'Overview',
appInfo: {
header: 'Application Info',
publicAccessLink: 'Public Access Link',
openText: 'On',
closeText: 'Off',
copyLinkText: 'Copy Link',
refreshLinkText: 'Refresh Link',
demo: 'Demo',
embedThirdParty: 'Embed Third Party',
accessRestrictions: 'Access Restrictions',
apiAccessCredentials: 'API Access Credentials',
apiKey: 'API Key',
refreshToken: {
msgConfirm1: 'Do you want to regenerate the public access link?',
msgConfirm2: 'Regenerating the public access link will affect third-party embedded scripts changes and will require re-embedding the new script into third-party sites. Please proceed with caution!',
confirm: 'Confirm',
cancel: 'Cancel',
refreshSuccess: 'Refresh Successful',
},
changeState: {
enableSuccess: 'Enable Successful',
disableSuccess: 'Disable Successful',
},
APIKeyDialog: {
creatApiKey: 'Create',
status: 'Status',
creationDate: 'Creation Date',
operations: 'Operations',
settings: 'Settings',
delete: 'Delete',
saveSettings: 'Save Settings',
msgConfirm1: 'Are you sure you want to delete the API Key?',
msgConfirm2: 'Deleting the API Key cannot be undone. Please confirm if you want to delete it!',
confirmDelete: 'Delete',
deleteSuccess: 'Delete Successful',
cancel: 'Cancel',
enabledSuccess: 'Enabled',
disabledSuccess: 'Disabled',
},
EditAvatarDialog: {
title: 'Edit Logo',
customizeUpload: 'Custom Upload',
upload: 'Upload',
default: 'Default Logo',
custom: 'Custom',
sizeTip: 'Suggested size 32*32, supports ico, png, size no more than 200KB',
cancel: 'Cancel',
save: 'Save',
fileSizeExceeded: 'File size exceeds 200KB',
setSuccess: 'Setting Successful',
uploadImagePrompt: 'Please upload an image'
},
EmbedDialog: {
embedDialogTitle: 'Embed Third Party',
fullscreenModeTitle: 'Fullscreen Mode',
copyInstructions: 'Copy the following code to embed',
floatingModeTitle: 'Floating Mode'
},
LimitDialog: {
dialogTitle: 'Access Restrictions',
showSourceLabel: 'Show Source',
clientQueryLimitLabel: 'Client Query Limit',
timesDays: 'Times/Day',
whitelistLabel: 'Whitelist',
whitelistPlaceholder: 'Please enter allowed third-party source addresses, one per line, such as:\nhttp://127.0.0.1:5678\nhttps://dataease.io',
cancelButtonText: 'Cancel',
saveButtonText: 'Save',
settingSuccessMessage: 'Setting Successful'
},
SettingAPIKeyDialog: {
dialogTitle: 'Settings',
allowCrossDomainLabel: 'Allow Cross-Domain Address',
crossDomainPlaceholder: 'Please enter allowed cross-domain addresses, if open without inputting addresses, there are no restrictions.\nCross-domain addresses one per line, such as:\nhttp://127.0.0.1:5678\nhttps://dataease.io',
cancelButtonText: 'Cancel',
saveButtonText: 'Save',
successMessage: 'Setting Successful'
}
},
monitor: {
monitoringStatistics: 'Monitoring Statistics',
customRange: 'Custom Range',
startDatePlaceholder: 'Start Date',
endDatePlaceholder: 'End Date',
pastDayOptions: {
past7Days: 'Past 7 Days',
past30Days: 'Past 30 Days',
past90Days: 'Past 90 Days',
past183Days: 'Past Half Year',
other: 'Custom'
},
charts: {
customerTotal: 'Total Customers',
customerNew: 'New Customers',
queryCount: 'Query Count',
tokensTotal: 'Total Tokens',
userSatisfaction: 'User Satisfaction',
approval: 'Approval',
disapproval: 'Disapproval'
}
},
};

View File

@ -1,6 +1,8 @@
import notFound from './404';
import application from './application';
import applicationOverview from './application-overview';
export default {
notFound,
application,
applicationOverview
};

View File

@ -1,5 +1,5 @@
export default {
title: "404",
Message: "无法访问应用",
message: "无法访问应用",
operate: "返回首页",
};

View File

@ -0,0 +1,103 @@
export default {
title: '概览',
appInfo:{
header: '应用信息',
publicAccessLink: '公开访问链接',
openText: '开',
closeText: '关',
copyLinkText: '复制链接',
refreshLinkText: '刷新链接',
demo: '演示',
embedThirdParty: '嵌入第三方',
accessRestrictions: '访问限制',
apiAccessCredentials: 'API访问凭据',
apiKey: 'API Key',
refreshToken:{
msgConfirm1:'是否重新生成公开访问链接?',
msgConfirm2:'重新生成公开访问链接会影响嵌入第三方脚本变更,需要将新脚本重新嵌入第三方,请谨慎操作!',
confirm: '确认',
cancel: '取消',
refreshSuccess: '刷新成功',
},
changeState:{
enableSuccess: '启用成功',
disableSuccess: '禁用成功',
},
APIKeyDialog:{
creatApiKey: '创建',
status: '状态',
creationDate: '创建日期',
operations: '操作',
settings: '设置',
delete: '删除',
saveSettings: '保存设置',
msgConfirm1: '是否删除API Key?',
msgConfirm2: '删除API Key后将无法恢复请确认是否删除',
confirmDelete: '删除',
deleteSuccess: '删除成功',
cancel: '取消',
enabledSuccess: '已启用',
disabledSuccess: '已禁用',
},
EditAvatarDialog:{
title: '编辑logo',
customizeUpload: '自定义上传',
upload: '上传',
default: '默认logo',
custom: '自定义',
sizeTip: '建议尺寸 32*32支持 ico、png大小不超过200KB',
cancel: '取消',
save: '保存',
fileSizeExceeded: '文件大小超过 200KB',
setSuccess: '设置成功',
uploadImagePrompt: '请上传一张图片'
},
EmbedDialog:{
embedDialogTitle: '嵌入第三方',
fullscreenModeTitle: '全屏模式',
copyInstructions: '复制以下代码进行嵌入',
floatingModeTitle: '浮窗模式'
},
LimitDialog:{
dialogTitle: '访问限制',
showSourceLabel: '显示知识来源',
clientQueryLimitLabel: '客户端提问限制',
timesDays: '次/天',
whitelistLabel: '白名单',
whitelistPlaceholder: '请输入允许嵌入第三方的源地址,一行一个,如:\nhttp://127.0.0.1:5678\nhttps://dataease.io',
cancelButtonText: '取消',
saveButtonText: '保存',
settingSuccessMessage: '设置成功'
},
SettingAPIKeyDialog:{
dialogTitle: '设置',
allowCrossDomainLabel: '允许跨域地址',
crossDomainPlaceholder: '请输入允许的跨域地址,开启后不输入跨域地址则不限制。\n跨域地址一行一个\nhttp://127.0.0.1:5678 \nhttps://dataease.io',
cancelButtonText: '取消',
saveButtonText: '保存',
successMessage: '设置成功'
}
},
monitor:{
monitoringStatistics: '监控统计',
customRange: '自定义范围',
startDatePlaceholder: '开始时间',
endDatePlaceholder: '结束时间',
pastDayOptions:{
past7Days:'过去7天',
past30Days:'过去30天',
past90Days:'过去90天',
past183Days:'过去半年',
other:'自定义'
},
charts:{
'customerTotal': '用户总数',
'customerNew': '用户新增数',
'queryCount': '提问次数',
'tokensTotal': 'Tokens 总数',
'userSatisfaction': '用户满意度',
'approval': '赞同',
'disapproval': '反对'
}
},
};

View File

@ -1,6 +1,8 @@
import notFound from './404';
import application from './application';
import applicationOverview from './application-overview';
export default {
notFound,
application,
applicationOverview
};

View File

@ -1,6 +1,6 @@
<template>
<el-dialog title="API Key" v-model="dialogVisible" width="800">
<el-button type="primary" class="mb-16" @click="createApiKey"> 创建 </el-button>
<el-button type="primary" class="mb-16" @click="createApiKey"> {{$t('views.applicationOverview.appInfo.APIKeyDialog.creatApiKey')}} </el-button>
<el-table :data="apiKey" class="mb-16" :loading="loading">
<el-table-column prop="secret_key" label="API Key">
<template #default="{ row }">
@ -12,28 +12,28 @@
</el-button>
</template>
</el-table-column>
<el-table-column label="状态" width="60">
<el-table-column :label="$t('views.applicationOverview.appInfo.APIKeyDialog.status')" width="60">
<template #default="{ row }">
<div @click.stop>
<el-switch size="small" v-model="row.is_active" @change="changeState($event, row)" />
</div>
</template>
</el-table-column>
<el-table-column prop="name" label="创建日期" width="170">
<el-table-column prop="name" :label="$t('views.applicationOverview.appInfo.APIKeyDialog.creationDate')" width="170">
<template #default="{ row }">
{{ datetimeFormat(row.create_time) }}
</template>
</el-table-column>
<el-table-column label="操作" align="left" width="80">
<el-table-column :label="$t('views.applicationOverview.appInfo.APIKeyDialog.operations')" align="left" width="80">
<template #default="{ row }">
<span class="mr-4">
<el-tooltip effect="dark" content="设置" placement="top">
<el-tooltip effect="dark" :content="$t('views.applicationOverview.appInfo.APIKeyDialog.settings')" placement="top">
<el-button type="primary" text @click.stop="settingApiKey(row)">
<el-icon><Setting /></el-icon>
</el-button>
</el-tooltip>
</span>
<el-tooltip effect="dark" content="删除" placement="top">
<el-tooltip effect="dark" :content="$t('views.applicationOverview.appInfo.APIKeyDialog.delete')" placement="top">
<el-button type="primary" text @click="deleteApiKey(row)">
<el-icon><Delete /></el-icon>
</el-button>
@ -52,6 +52,7 @@ import overviewApi from '@/api/application-overview'
import SettingAPIKeyDialog from './SettingAPIKeyDialog.vue'
import { datetimeFormat } from '@/utils/time'
import { MsgSuccess, MsgConfirm } from '@/utils/message'
import { t } from '@/locales'
const route = useRoute()
const {
params: { id }
@ -76,16 +77,18 @@ function settingApiKey(row: any) {
function deleteApiKey(row: any) {
MsgConfirm(
`是否删除API Key${row.secret_key} ?`,
`删除后无法使用该 API Key 调用接口,请谨慎操作`,
// @ts-ignore
`${t('views.applicationOverview.appInfo.APIKeyDialog.msgConfirm1')}: ${row.secret_key}?`,
t('views.applicationOverview.appInfo.APIKeyDialog.msgConfirm2'),
{
confirmButtonText: '删除',
confirmButtonText: t('views.applicationOverview.appInfo.APIKeyDialog.confirmDelete'),
cancelButtonText:t('views.applicationOverview.appInfo.APIKeyDialog.cancel'),
confirmButtonClass: 'danger'
}
)
.then(() => {
overviewApi.delAPIKey(id as string, row.id, loading).then(() => {
MsgSuccess('删除成功')
MsgSuccess(t('views.applicationOverview.appInfo.APIKeyDialog.deleteSuccess'))
getApiKeyList()
})
})
@ -96,7 +99,7 @@ function changeState(bool: Boolean, row: any) {
const obj = {
is_active: bool
}
const str = bool ? '启用成功' : '禁用成功'
const str = bool ? t('views.applicationOverview.appInfo.APIKeyDialog.enabledSuccess') : t('views.applicationOverview.appInfo.APIKeyDialog.disabledSuccess')
overviewApi.putAPIKey(id as string, row.id, obj, loading).then((res) => {
MsgSuccess(str)
getApiKeyList()

View File

@ -1,9 +1,9 @@
<template>
<el-dialog title="设置 Logo" v-model="dialogVisible">
<el-dialog :title="$t('views.applicationOverview.appInfo.EditAvatarDialog.title')" v-model="dialogVisible">
<el-radio-group v-model="radioType" class="radio-block mb-16">
<div>
<el-radio value="default">
<p>默认 Logo</p>
<p>{{$t('views.applicationOverview.appInfo.EditAvatarDialog.default')}}</p>
<AppAvatar
v-if="detail?.name"
:name="detail?.name"
@ -16,7 +16,7 @@
</div>
<div class="mt-8">
<el-radio value="custom">
<p>自定义上传</p>
<p>{{$t('views.applicationOverview.appInfo.EditAvatarDialog.customizeUpload')}}</p>
<div class="flex mt-8">
<AppAvatar
v-if="fileURL"
@ -35,19 +35,19 @@
accept="image/*"
:on-change="onChange"
>
<el-button icon="Upload" :disabled="radioType !== 'custom'">上传</el-button>
<el-button icon="Upload" :disabled="radioType !== 'custom'">{{$t('views.applicationOverview.appInfo.EditAvatarDialog.upload')}}</el-button>
</el-upload>
</div>
<div class="el-upload__tip info mt-16">
建议尺寸 32*32支持 icopng , 大小不超过200KB
{{$t('views.applicationOverview.appInfo.EditAvatarDialog.sizeTip')}}
</div>
</el-radio>
</div>
</el-radio-group>
<template #footer>
<span class="dialog-footer">
<el-button @click.prevent="dialogVisible = false"> 取消 </el-button>
<el-button type="primary" @click="submit" :loading="loading"> 保存 </el-button>
<el-button @click.prevent="dialogVisible = false"> {{$t('views.applicationOverview.appInfo.EditAvatarDialog.cancel')}}</el-button>
<el-button type="primary" @click="submit" :loading="loading"> {{$t('views.applicationOverview.appInfo.EditAvatarDialog.save')}}</el-button>
</span>
</template>
</el-dialog>
@ -60,6 +60,7 @@ import { cloneDeep } from 'lodash'
import { MsgSuccess, MsgError } from '@/utils/message'
import { defaultIcon, isAppIcon } from '@/utils/application'
import useStore from '@/stores'
import { t } from '@/locales'
const { application } = useStore()
@ -96,7 +97,8 @@ const onChange = (file: any) => {
//1 200KB
const isLimit = file?.size / 1024 < 200
if (!isLimit) {
MsgError('文件大小超过 200KB')
// @ts-ignore
MsgError(t('views.applicationOverview.appInfo.EditAvatarDialog.fileSizeExceeded'))
return false
}
iconFile.value = file
@ -107,7 +109,7 @@ function submit() {
if (radioType.value === 'default') {
application.asyncPutApplication(id as string, { icon: defaultIcon }, loading).then((res) => {
emit('refresh')
MsgSuccess('设置成功')
MsgSuccess(t('views.applicationOverview.appInfo.EditAvatarDialog.setSuccess'))
dialogVisible.value = false
})
} else if (radioType.value === 'custom' && iconFile.value) {
@ -115,11 +117,11 @@ function submit() {
fd.append('file', iconFile.value.raw)
overviewApi.putAppIcon(id as string, fd, loading).then((res: any) => {
emit('refresh')
MsgSuccess('设置成功')
MsgSuccess(t('views.applicationOverview.appInfo.EditAvatarDialog.setSuccess'))
dialogVisible.value = false
})
} else {
MsgError('请上传一张图片')
MsgError(t('views.applicationOverview.appInfo.EditAvatarDialog.uploadImagePrompt'))
}
}

View File

@ -1,13 +1,13 @@
<template>
<el-dialog title="嵌入第三方" v-model="dialogVisible" width="900" class="embed-dialog">
<el-dialog :title="$t('views.applicationOverview.appInfo.EmbedDialog.embedDialogTitle')" v-model="dialogVisible" width="900" class="embed-dialog">
<el-row :gutter="12">
<el-col :span="12">
<div class="border">
<p class="title p-16 bold">全屏模式</p>
<p class="title p-16 bold">{{$t('views.applicationOverview.appInfo.EmbedDialog.embedDialogTitle')}}</p>
<img src="@/assets/window1.png" alt="" class="ml-8" />
<div class="code border-t p-16">
<div class="flex-between">
<span class="bold">复制以下代码进行嵌入</span>
<span class="bold">{{$t('views.applicationOverview.appInfo.EmbedDialog.fullscreenModeTitle')}}</span>
<el-button text @click="copyClick(source1)">
<AppIcon iconName="app-copy"></AppIcon>
</el-button>
@ -20,11 +20,11 @@
</el-col>
<el-col :span="12">
<div class="border">
<p class="title p-16 bold">浮窗模式</p>
<p class="title p-16 bold">{{$t('views.applicationOverview.appInfo.EmbedDialog.floatingModeTitle')}}</p>
<img src="@/assets/window2.png" alt="" class="ml-8" />
<div class="code border-t p-16">
<div class="flex-between">
<span class="bold">复制以下代码进行嵌入</span>
<span class="bold">{{$t('views.applicationOverview.appInfo.EmbedDialog.copyInstructions')}}</span>
<el-button text @click="copyClick(source2)">
<AppIcon iconName="app-copy"></AppIcon>
</el-button>
@ -61,15 +61,15 @@ watch(dialogVisible, (bool) => {
})
const open = (val: string) => {
source1.value = `<iframe
source1.value = `<iframe
src="${application.location + val}"
style="width: 100%; height: 100%;"
frameborder="0"
style="width: 100%; height: 100%;"
frameborder="0"
allow="microphone">
</iframe>
`
source2.value = `<script
source2.value = `<script
async
defer
src="${window.location.origin}/api/application/embed?protocol=${window.location.protocol.replace(

View File

@ -1,10 +1,10 @@
<template>
<el-dialog title="访问限制" v-model="dialogVisible">
<el-dialog :title="$t('views.applicationOverview.appInfo.LimitDialog.dialogTitle')" v-model="dialogVisible">
<el-form label-position="top" ref="limitFormRef" :model="form">
<el-form-item label="显示知识来源" @click.prevent>
<el-form-item :label="$t('views.applicationOverview.appInfo.LimitDialog.showSourceLabel')" @click.prevent>
<el-switch size="small" v-model="form.show_source"></el-switch>
</el-form-item>
<el-form-item label="客户端提问限制">
<el-form-item :label="$t('views.applicationOverview.appInfo.LimitDialog.clientQueryLimitLabel')">
<el-input-number
v-model="form.access_num"
:min="0"
@ -12,17 +12,15 @@
controls-position="right"
step-strictly
/>
<span class="ml-4"> / </span>
<span class="ml-4">{{$t('views.applicationOverview.appInfo.LimitDialog.timesDays')}}</span>
</el-form-item>
<el-form-item label="白名单" @click.prevent>
<el-form-item :label="$t('views.applicationOverview.appInfo.LimitDialog.whitelistLabel')" @click.prevent>
<el-switch size="small" v-model="form.white_active"></el-switch>
</el-form-item>
<el-form-item>
<el-input
v-model="form.white_list"
placeholder="请输入允许嵌入第三方的源地址一行一个
http://127.0.0.1:5678
https://dataease.io"
:placeholder="$t('views.applicationOverview.appInfo.LimitDialog.whitelistPlaceholder')"
:rows="10"
type="textarea"
/>
@ -30,9 +28,9 @@ https://dataease.io"
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click.prevent="dialogVisible = false"> 取消 </el-button>
<el-button @click.prevent="dialogVisible = false">{{$t('views.applicationOverview.appInfo.LimitDialog.cancelButtonText')}} </el-button>
<el-button type="primary" @click="submit(limitFormRef)" :loading="loading">
保存
{{$t('views.applicationOverview.appInfo.LimitDialog.saveButtonText')}}
</el-button>
</span>
</template>
@ -44,6 +42,7 @@ import { useRoute } from 'vue-router'
import type { FormInstance, FormRules } from 'element-plus'
import applicationApi from '@/api/application'
import { MsgSuccess, MsgConfirm } from '@/utils/message'
import { t } from '@/locales'
const route = useRoute()
const {
@ -94,7 +93,8 @@ const submit = async (formEl: FormInstance | undefined) => {
}
applicationApi.putAccessToken(id as string, obj, loading).then((res) => {
emit('refresh')
MsgSuccess('设置成功')
// @ts-ignore
MsgSuccess(t('views.applicationOverview.appInfo.LimitDialog.settingSuccessMessage'))
dialogVisible.value = false
})
}

View File

@ -1,16 +1,13 @@
<template>
<el-dialog title="设置" v-model="dialogVisible">
<el-dialog :title="$t('views.applicationOverview.appInfo.SettingAPIKeyDialog.dialogTitle')" v-model="dialogVisible">
<el-form label-position="top" ref="settingFormRef" :model="form">
<el-form-item label="允许跨域地址" @click.prevent>
<el-form-item :label="$t('views.applicationOverview.appInfo.SettingAPIKeyDialog.allowCrossDomainLabel')" @click.prevent>
<el-switch size="small" v-model="form.allow_cross_domain"></el-switch>
</el-form-item>
<el-form-item>
<el-input
v-model="form.cross_domain_list"
placeholder="请输入允许的跨域地址开启后不输入跨域地址则不限制
跨域地址一行一个
http://127.0.0.1:5678
https://dataease.io"
:placeholder="$t('views.applicationOverview.appInfo.SettingAPIKeyDialog.crossDomainPlaceholder')"
:rows="10"
type="textarea"
/>
@ -18,9 +15,9 @@ https://dataease.io"
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click.prevent="dialogVisible = false"> 取消 </el-button>
<el-button @click.prevent="dialogVisible = false">{{$t('views.applicationOverview.appInfo.SettingAPIKeyDialog.cancelButtonText')}}</el-button>
<el-button type="primary" @click="submit(settingFormRef)" :loading="loading">
保存
{{$t('views.applicationOverview.appInfo.SettingAPIKeyDialog.saveButtonText')}}
</el-button>
</span>
</template>
@ -32,6 +29,7 @@ import { useRoute } from 'vue-router'
import type { FormInstance, FormRules } from 'element-plus'
import overviewApi from '@/api/application-overview'
import { MsgSuccess, MsgConfirm } from '@/utils/message'
import { t } from '@/locales'
const route = useRoute()
const {
params: { id }
@ -82,7 +80,8 @@ const submit = async (formEl: FormInstance | undefined) => {
}
overviewApi.putAPIKey(id as string, APIKeyId.value, obj, loading).then((res) => {
emit('refresh')
MsgSuccess('设置成功')
//@ts-ignore
MsgSuccess(t('views.applicationOverview.appInfo.SettingAPIKeyDialog.successMessage'))
dialogVisible.value = false
})
}

View File

@ -57,6 +57,7 @@
import { ref, computed, onMounted } from 'vue'
import AppCharts from '@/components/app-charts/index.vue'
import { getAttrsArray, getSum, numberFormat } from '@/utils/utils'
import { t } from '@/locales'
const props = defineProps({
data: {
type: Array,
@ -66,7 +67,8 @@ const props = defineProps({
const statisticsType = computed(() => [
{
id: 'customerCharts',
name: '用户总数',
// @ts-ignore
name: t('views.applicationOverview.monitor.charts.customerTotal'),
icon: 'app-user',
background: '#EBF1FF',
color: '#3370FF',
@ -75,17 +77,17 @@ const statisticsType = computed(() => [
getSum(getAttrsArray(props.data, 'customer_added_count') || 0)
],
option: {
title: '用户总数',
title: t('views.applicationOverview.monitor.charts.customerTotal'),
xData: getAttrsArray(props.data, 'day'),
yData: [
{
name: '用户总数',
name: t('views.applicationOverview.monitor.charts.customerTotal'),
type: 'line',
area: true,
data: getAttrsArray(props.data, 'customer_num')
},
{
name: '用户新增数',
name: t('views.applicationOverview.monitor.charts.customerNew'),
type: 'line',
area: true,
data: getAttrsArray(props.data, 'customer_added_count')
@ -95,13 +97,13 @@ const statisticsType = computed(() => [
},
{
id: 'chatRecordCharts',
name: '提问次数',
name: t('views.applicationOverview.monitor.charts.queryCount'),
icon: 'app-question',
background: '#FFF3E5',
color: '#FF8800',
sum: [getSum(getAttrsArray(props.data, 'chat_record_count') || 0)],
option: {
title: '提问次数',
title: t('views.applicationOverview.monitor.charts.queryCount'),
xData: getAttrsArray(props.data, 'day'),
yData: [
{
@ -113,13 +115,13 @@ const statisticsType = computed(() => [
},
{
id: 'tokensCharts',
name: 'Tokens 总数',
name: t('views.applicationOverview.monitor.charts.tokensTotal'),
icon: 'app-tokens',
background: '#E5FBF8',
color: '#00D6B9',
sum: [getSum(getAttrsArray(props.data, 'tokens_num') || 0)],
option: {
title: 'Tokens 总数',
title: t('views.applicationOverview.monitor.charts.tokensTotal'),
xData: getAttrsArray(props.data, 'day'),
yData: [
{
@ -131,7 +133,7 @@ const statisticsType = computed(() => [
},
{
id: 'starCharts',
name: '用户满意度',
name: t('views.applicationOverview.monitor.charts.userSatisfaction'),
icon: 'app-user-stars',
background: '#FEEDEC',
color: '#F54A45',
@ -140,16 +142,16 @@ const statisticsType = computed(() => [
getSum(getAttrsArray(props.data, 'trample_num') || 0)
],
option: {
title: '用户满意度',
title: t('views.applicationOverview.monitor.charts.userSatisfaction'),
xData: getAttrsArray(props.data, 'day'),
yData: [
{
name: '赞同',
name: t('views.applicationOverview.monitor.charts.approval'),
type: 'line',
data: getAttrsArray(props.data, 'star_num')
},
{
name: '反对',
name: t('views.applicationOverview.monitor.charts.disapproval'),
type: 'line',
data: getAttrsArray(props.data, 'trample_num')
}

View File

@ -1,8 +1,8 @@
<template>
<LayoutContainer header="概览">
<LayoutContainer :header="$t('views.applicationOverview.title')">
<el-scrollbar>
<div class="main-calc-height p-24">
<h4 class="title-decoration-1 mb-16">应用信息</h4>
<h4 class="title-decoration-1 mb-16">{{$t('views.applicationOverview.appInfo.header')}}</h4>
<el-card shadow="never" class="overview-card" v-loading="loading">
<div class="title flex align-center">
<div
@ -42,14 +42,14 @@
<el-row :gutter="12">
<el-col :span="12" class="mt-16">
<div class="flex">
<el-text type="info">公开访问链接</el-text>
<el-text type="info">{{$t('views.applicationOverview.appInfo.publicAccessLink')}}</el-text>
<el-switch
v-model="accessToken.is_active"
class="ml-8"
size="small"
inline-prompt
active-text=""
inactive-text=""
:active-text="$t('views.applicationOverview.appInfo.openText')"
:inactive-text="$t('views.applicationOverview.appInfo.closeText')"
@change="changeState($event)"
/>
</div>
@ -68,18 +68,18 @@
</div>
<div>
<el-button :disabled="!accessToken?.is_active" type="primary">
<a v-if="accessToken?.is_active" :href="shareUrl" target="_blank"> 演示 </a>
<span v-else>演示</span>
<a v-if="accessToken?.is_active" :href="shareUrl" target="_blank"> {{$t('views.applicationOverview.appInfo.demo')}} </a>
<span v-else> {{$t('views.applicationOverview.appInfo.demo')}}</span>
</el-button>
<el-button :disabled="!accessToken?.is_active" @click="openDialog">
嵌入第三方
{{$t('views.applicationOverview.appInfo.embedThirdParty')}}
</el-button>
<el-button @click="openLimitDialog"> 访问限制 </el-button>
<el-button @click="openLimitDialog"> {{$t('views.applicationOverview.appInfo.accessRestrictions')}} </el-button>
</div>
</el-col>
<el-col :span="12" class="mt-16">
<div class="flex">
<el-text type="info">API访问凭据</el-text>
<el-text type="info">{{$t('views.applicationOverview.appInfo.apiAccessCredentials')}} </el-text>
</div>
<div class="mt-4 mb-16 url-height">
<a target="_blank" :href="apiUrl" class="vertical-middle lighter break-all">
@ -91,12 +91,12 @@
</el-button>
</div>
<div>
<el-button @click="openAPIKeyDialog"> API Key </el-button>
<el-button @click="openAPIKeyDialog">{{$t('views.applicationOverview.appInfo.apiKey')}}</el-button>
</div>
</el-col>
</el-row>
</el-card>
<h4 class="title-decoration-1 mt-16 mb-16">监控统计</h4>
<h4 class="title-decoration-1 mt-16 mb-16">{{$t('views.applicationOverview.monitor.monitoringStatistics')}}</h4>
<div class="mb-16">
<el-select v-model="history_day" class="mr-12 w-120" @change="changeDayHandle">
<el-option
@ -110,8 +110,8 @@
v-if="history_day === 'other'"
v-model="daterangeValue"
type="daterange"
start-placeholder="开始时间"
end-placeholder="结束时间"
:start-placeholder="$t('views.applicationOverview.monitor.startDatePlaceholder')"
:end-placeholder="$t('views.applicationOverview.monitor.endDatePlaceholder')"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
@change="changeDayRangeHandle"
@ -143,6 +143,7 @@ import { MsgSuccess, MsgConfirm } from '@/utils/message'
import { copyClick } from '@/utils/clipboard'
import { isAppIcon } from '@/utils/application'
import useStore from '@/stores'
import { t } from '@/locales'
const { application } = useStore()
const route = useRoute()
const {
@ -166,23 +167,24 @@ const shareUrl = computed(() => application.location + accessToken.value.access_
const dayOptions = [
{
value: 7,
label: '过去7天'
// @ts-ignore
label: t('views.applicationOverview.monitor.pastDayOptions.past7Days') // 使 t
},
{
value: 30,
label: '过去30天'
label: t('views.applicationOverview.monitor.pastDayOptions.past30Days')
},
{
value: 90,
label: '过去90天'
label: t('views.applicationOverview.monitor.pastDayOptions.past90Days')
},
{
value: 183,
label: '过去半年'
label: t('views.applicationOverview.monitor.pastDayOptions.past183Days')
},
{
value: 'other',
label: '自定义'
label: t('views.applicationOverview.monitor.pastDayOptions.other')
}
]
@ -228,17 +230,19 @@ function getAppStatistics() {
function refreshAccessToken() {
MsgConfirm(
`是否重新生成公开访问链接?`,
`重新生成公开访问链接会影响嵌入第三方脚本变更,需要将新脚本重新嵌入第三方,请谨慎操作!`,
t('views.applicationOverview.appInfo.refreshToken.msgConfirm1'),
t('views.applicationOverview.appInfo.refreshToken.msgConfirm2'),
{
confirmButtonText: '确认'
confirmButtonText: t('views.applicationOverview.appInfo.refreshToken.confirm'),
cancelButtonText:t('views.applicationOverview.appInfo.refreshToken.cancel')
}
)
.then(() => {
const obj = {
access_token_reset: true
}
const str = '刷新成功'
// @ts-ignore
const str = t('views.applicationOverview.appInfo.refreshToken.refreshSuccess')
updateAccessToken(obj, str)
})
.catch(() => {})
@ -247,7 +251,7 @@ function changeState(bool: Boolean) {
const obj = {
is_active: bool
}
const str = bool ? '启用成功' : '禁用成功'
const str = bool ? t('views.applicationOverview.appInfo.changeState.enableSuccess') : t('views.applicationOverview.appInfo.changeState.disableSuccess')
updateAccessToken(obj, str)
}