feat: i18n

This commit is contained in:
wangdan-fit2cloud 2025-01-15 19:10:29 +08:00
parent ef26e59388
commit 7eb17bab2f
33 changed files with 429 additions and 218 deletions

View File

@ -14,7 +14,7 @@
</template> </template>
</ul> </ul>
<slot name="empty" v-else> <slot name="empty" v-else>
<el-empty description="暂无数据" /> <el-empty :description="$t('common.noData')" />
</slot> </slot>
</div> </div>
</template> </template>

View File

@ -198,5 +198,11 @@ export default {
'-Events and callbacks - event configuration - configure the "request address" of the subscription method' '-Events and callbacks - event configuration - configure the "request address" of the subscription method'
}, },
copyUrl: 'Copy the link and fill it in' copyUrl: 'Copy the link and fill it in'
},
hitTest: {
title: 'Hit testing',
text: 'Ensure effective response by matching paragraphs to user inquiries.',
emptyMessage1: 'The matching paragraph is displayed here',
emptyMessage2: 'No matching sections found'
} }
} }

View File

@ -59,7 +59,5 @@ export default {
placeholder: 'Default is body, can input .classname/#idname/tagname' placeholder: 'Default is body, can input .classname/#idname/tagname'
} }
}, },
buttons: {},
dialog: {}
} }
} }

View File

@ -189,5 +189,11 @@ export default {
}, },
copyUrl: '复制链接填入到' copyUrl: '复制链接填入到'
},
hitTest: {
title: '命中测试',
text: '针对用户提问调试段落匹配情况,保障回答效果。',
emptyMessage1: '命中段落显示在这里',
emptyMessage2: '没有命中的分段'
} }
} }

View File

@ -1,7 +1,6 @@
export default { export default {
title: '知识库', title: '知识库',
createDataset: '创建知识库', createDataset: '创建知识库',
selectDataset: '选择知识库',
general: '通用型', general: '通用型',
web: 'web 站点', web: 'web 站点',
relatedApplications: '关联应用', relatedApplications: '关联应用',
@ -79,5 +78,5 @@ export default {
complete: '整体同步', complete: '整体同步',
completeText: '先删除本地知识库所有文档,重新获取 Web 站点文档', completeText: '先删除本地知识库所有文档,重新获取 Web 站点文档',
tip: '注意:所有同步都会删除已有数据重新获取新数据,请谨慎操作。' tip: '注意:所有同步都会删除已有数据重新获取新数据,请谨慎操作。'
} },
} }

View File

@ -16,11 +16,12 @@ export default {
}, },
tip: { tip: {
saveMessage: '当前的更改尚未保存,确认退出吗?', saveMessage: '当前的更改尚未保存,确认退出吗?',
cancelSuccessMessage: '批量取消成功', cancelSuccess: '批量取消成功',
sendMessage: '发送成功', sendMessage: '发送成功',
vectorizationSuccessMessage: '批量向量化成功', vectorizationSuccess: '批量向量化成功',
nameMessage: '文件名称不能为空!', nameMessage: '文件名称不能为空!',
importMessage: '导入成功' importMessage: '导入成功',
migrationSuccess: '迁移成功'
}, },
upload: { upload: {
selectFile: '选择文件', selectFile: '选择文件',
@ -153,30 +154,5 @@ export default {
error: '向量化未成功的分段', error: '向量化未成功的分段',
all: '全部分段' all: '全部分段'
} }
},
paragraph: {
title: '段落',
editParagraph: '编辑分段',
character_count: '个字符',
delete: {
confirmTitle: '是否删除分段:',
confirmMessage: '删除后将不会存入知识库,对本地文档无影响。'
},
relatedProblem: {
title: '关联问题',
placeholder: '请选择问题'
},
form: {
paragraphTitle: {
label: '分段标题',
placeholder: '请输入分段标题'
},
content: {
label: '分段内容',
placeholder: '请输入分段内容',
requiredMessage1: '请输入分段内容',
requiredMessage2: '内容最多不超过 100000 个字'
}
}
} }
} }

View File

@ -8,6 +8,9 @@ import user from './user';
import team from './team'; import team from './team';
import template from './template'; import template from './template';
import document from './document'; import document from './document';
import paragraph from './paragraph';
import problem from './problem';
import log from './log';
export default { export default {
notFound, notFound,
application, application,
@ -18,5 +21,8 @@ export default {
user, user,
team, team,
template, template,
document document,
paragraph,
problem,
log
}; };

View File

@ -0,0 +1,42 @@
export default {
title: '对话日志',
delete: {
confirmTitle: '是否删除问题:',
confirmMessage1: '删除问题关联的',
confirmMessage2: '个分段会被取消关联,请谨慎操作。'
},
buttons: {
clearStrategy: '清除策略',
prev: '上一条',
next: '下一条'
},
table: {
abstract: '摘要',
chat_record_count: '对话提问数',
feedback: {
label: '用户反馈',
star: '赞同',
trample: '反对'
},
mark: '改进标注',
recenTimes: '最近对话时间'
},
addToDataset: '添加至知识库',
daysText: '天之前的对话记录',
selectDataset: '选择知识库',
selectDatasetPlaceholder: '请选择知识库',
saveToDocument: '保存至文档',
documentPlaceholder: '请选择文档',
editContent: '修改内容',
editMark: '修改标注',
form: {
content: {
label: '内容',
placeholder: '请输入内容'
},
title: {
label: '标题',
placeholder: '请给当前内容设置一个标题,以便管理查看'
},
}
}

View File

@ -0,0 +1,36 @@
export default {
title: '段落',
editParagraph: '编辑分段',
addParagraph: '添加分段',
paragraphDetail: '分段详情',
character_count: '个字符',
setting: {
batchSelected: '批量选择',
cancelSelected: '取消选择'
},
tip: {},
searchBar: {
title: '标题',
content: '内容'
},
delete: {
confirmTitle: '是否删除段落:',
confirmMessage: '删除后无法恢复,请谨慎操作。'
},
relatedProblem: {
title: '关联问题',
placeholder: '请选择问题'
},
form: {
paragraphTitle: {
label: '分段标题',
placeholder: '请输入分段标题'
},
content: {
label: '分段内容',
placeholder: '请输入分段内容',
requiredMessage1: '请输入分段内容',
requiredMessage2: '内容最多不超过 100000 个字'
}
}
}

View File

@ -0,0 +1,37 @@
export default {
title: '问题',
createProblem: '创建问题',
detailProblem: '问题详情',
quickCreateProblem: '快速创建问题',
tip: {
placeholder: '请输入问题,支持输入多个,一行一个。',
errorMessage: '问题不能为空!',
requiredMessage: '请输入问题',
relatedSuccess:'批量关联分段成功'
},
setting: {
batchDelete: '批量删除',
cancelRelated: '取消关联'
},
searchBar: {
placeholder: '按名称搜索'
},
table: {
paragraph_count: '关联分段数',
updateTime: '更新时间'
},
delete: {
confirmTitle: '是否删除问题:',
confirmMessage1: '删除问题关联的',
confirmMessage2: '个分段会被取消关联,请谨慎操作。'
},
relateParagraph: {
title: '关联分段',
selectDocument: '选择文档',
placeholder: '按 文档名称 搜索',
selectParagraph: '选择分段',
selectedParagraph: '已选分段',
count: '个'
},
}

View File

@ -187,5 +187,11 @@ export default {
urlInfo: '-事件與回呼-事件配置-配置訂閱方式的 "請求位址" 中' urlInfo: '-事件與回呼-事件配置-配置訂閱方式的 "請求位址" 中'
}, },
copyUrl: '複製連結填入到' copyUrl: '複製連結填入到'
},
hitTest: {
title: '命中測試',
text: '針對用戶提問調試段落匹配情況,保障回答效果。',
emptyMessage1: '命中的段落顯示在這裡',
emptyMessage2: '沒有命中的分段'
} }
} }

View File

@ -57,7 +57,5 @@ export default {
placeholder: '預設為 body可輸入 .classname/#idname/tagname' placeholder: '預設為 body可輸入 .classname/#idname/tagname'
} }
}, },
buttons: {},
dialog: {}
} }
} }

View File

@ -109,7 +109,7 @@ function editName(val: string, item: any) {
name: val name: val
} }
applicationApi.putWorkFlowVersion(id as string, item.id, obj, loading).then(() => { applicationApi.putWorkFlowVersion(id as string, item.id, obj, loading).then(() => {
MsgSuccess('修改成功') MsgSuccess(t('common.modifySuccess'))
item['writeStatus'] = false item['writeStatus'] = false
getList() getList()
}) })

View File

@ -1,6 +1,6 @@
<template> <template>
<el-dialog <el-dialog
:title="$t('views.document.paragraph.editParagraph')" :title="$t('views.paragraph.editParagraph')"
v-model="dialogVisible" v-model="dialogVisible"
width="80%" width="80%"
destroy-on-close destroy-on-close
@ -15,7 +15,7 @@
<el-col :span="6" class="border-l" style="width: 300px"> <el-col :span="6" class="border-l" style="width: 300px">
<p class="bold title p-24" style="padding-bottom: 0"> <p class="bold title p-24" style="padding-bottom: 0">
<span class="flex align-center"> <span class="flex align-center">
<span>{{ $t('views.document.paragraph.relatedProblem.title') }}</span> <span>{{ $t('views.paragraph.relatedProblem.title') }}</span>
<el-divider direction="vertical" class="mr-4" /> <el-divider direction="vertical" class="mr-4" />
<el-button text @click="addProblem"> <el-button text @click="addProblem">
<el-icon><Plus /></el-icon> <el-icon><Plus /></el-icon>
@ -27,7 +27,7 @@
<el-input <el-input
v-if="isAddProblem" v-if="isAddProblem"
v-model="problemValue" v-model="problemValue"
:placeholder="$t('views.document.paragraph.relatedProblem.placeholder')" :placeholder="$t('views.paragraph.relatedProblem.placeholder')"
@change="addProblemHandle" @change="addProblemHandle"
@blur="isAddProblem = false" @blur="isAddProblem = false"
ref="inputRef" ref="inputRef"

View File

@ -32,7 +32,7 @@
</div> </div>
<div class="lighter mt-12"> <div class="lighter mt-12">
<el-text type="info"> <el-text type="info">
{{ child.content.length }} {{ $t('views.document.paragraph.character_count') }} {{ child.content.length }} {{ $t('views.paragraph.character_count') }}
</el-text> </el-text>
</div> </div>
</el-card> </el-card>
@ -82,8 +82,8 @@ const updateContent = (data: any) => {
const deleteHandle = (item: any, cIndex: number) => { const deleteHandle = (item: any, cIndex: number) => {
MsgConfirm( MsgConfirm(
`${t('views.document.paragraph.delete.confirmTitle')}${item.title || '-'} ?`, `${t('views.paragraph.delete.confirmTitle')}${item.title || '-'} ?`,
t('views.document.paragraph.delete.confirmMessage'), t('views.paragraph.delete.confirmMessage'),
{ {
confirmButtonText: t('common.delete'), confirmButtonText: t('common.delete'),
confirmButtonClass: 'danger' confirmButtonClass: 'danger'

View File

@ -10,7 +10,7 @@
</template> </template>
<div class="mb-16"> <div class="mb-16">
<el-text type="info" <el-text type="info"
>{{ item.content.length }} {{ $t('views.document.paragraph.title') }}</el-text >{{ item.content.length }} {{ $t('views.paragraph.title') }}</el-text
> >
</div> </div>
<div class="paragraph-list" v-if="activeName == index"> <div class="paragraph-list" v-if="activeName == index">

View File

@ -1,6 +1,6 @@
<template> <template>
<el-dialog <el-dialog
:title="$t('views.dataset.selectDataset')" :title="$t('views.log.selectDataset')"
v-model="dialogVisible" v-model="dialogVisible"
width="600" width="600"
class="select-dataset-dialog" class="select-dataset-dialog"
@ -9,7 +9,7 @@
> >
<template #header="{ titleId, titleClass }"> <template #header="{ titleId, titleClass }">
<div class="my-header flex"> <div class="my-header flex">
<h4 :id="titleId" :class="titleClass">{{$t('views.dataset.selectDataset')}}</h4> <h4 :id="titleId" :class="titleClass">{{$t('views.log.selectDataset')}}</h4>
<el-button link class="ml-16" @click="refresh"> <el-button link class="ml-16" @click="refresh">
<el-icon class="mr-4"><Refresh /></el-icon>{{ $t('common.refresh') }} <el-icon class="mr-4"><Refresh /></el-icon>{{ $t('common.refresh') }}
</el-button> </el-button>

View File

@ -553,7 +553,7 @@ function cancelTaskHandle(val: any) {
type: val type: val
} }
documentApi.batchCancelTask(id, obj, loading).then(() => { documentApi.batchCancelTask(id, obj, loading).then(() => {
MsgSuccess(t('views.document.tip.cancelSuccessMessage')) MsgSuccess(t('views.document.tip.cancelSuccess'))
multipleTableRef.value?.clearSelection() multipleTableRef.value?.clearSelection()
}) })
} }
@ -734,7 +734,7 @@ function batchRefresh() {
const arr: string[] = multipleSelection.value.map((v) => v.id) const arr: string[] = multipleSelection.value.map((v) => v.id)
const embeddingBatchDocument = (stateList: Array<string>) => { const embeddingBatchDocument = (stateList: Array<string>) => {
documentApi.batchRefresh(id, arr, stateList, loading).then(() => { documentApi.batchRefresh(id, arr, stateList, loading).then(() => {
MsgSuccess(t('views.document.tip.vectorizationSuccessMessage')) MsgSuccess(t('views.document.tip.vectorizationSuccess'))
multipleTableRef.value?.clearSelection() multipleTableRef.value?.clearSelection()
}) })
} }

View File

@ -3,8 +3,8 @@
<LayoutContainer> <LayoutContainer>
<template #header> <template #header>
<h4> <h4>
命中测试 {{ $t('views.application.hitTest.title') }}
<el-text type="info" class="ml-4">针对用户提问调试段落匹配情况保障回答效果</el-text> <el-text type="info" class="ml-4"> {{ $t('views.application.hitTest.text') }}</el-text>
</h4> </h4>
</template> </template>
<div class="hit-test__main p-16" v-loading="loading"> <div class="hit-test__main p-16" v-loading="loading">
@ -20,8 +20,15 @@
</div> </div>
<el-scrollbar> <el-scrollbar>
<div class="hit-test-height"> <div class="hit-test-height">
<el-empty v-if="first" :image="emptyImg" description="命中段落显示在这里" /> <el-empty
<el-empty v-else-if="paragraphDetail.length == 0" description="没有命中的分段" /> v-if="first"
:image="emptyImg"
:description="$t('views.application.hitTest.emptyMessage1')"
/>
<el-empty
v-else-if="paragraphDetail.length == 0"
:description="$t('views.application.hitTest.emptyMessage2')"
/>
<el-row v-else> <el-row v-else>
<el-col <el-col
:xs="24" :xs="24"
@ -80,10 +87,14 @@
<div class="hit-test__operate p-24 pt-0"> <div class="hit-test__operate p-24 pt-0">
<el-popover :visible="popoverVisible" placement="right-end" :width="500" trigger="click"> <el-popover :visible="popoverVisible" placement="right-end" :width="500" trigger="click">
<template #reference> <template #reference>
<el-button icon="Setting" class="mb-8" @click="settingChange('open')">参数设置</el-button> <el-button icon="Setting" class="mb-8" @click="settingChange('open')">{{
$t('common.paramSetting')
}}</el-button>
</template> </template>
<div class="mb-16"> <div class="mb-16">
<div class="title mb-8">检索模式</div> <div class="title mb-8">
{{ $t('views.application.applicationForm.dialog.selectSearchMode') }}
</div>
<el-radio-group <el-radio-group
v-model="cloneForm.search_mode" v-model="cloneForm.search_mode"
class="card__radio" class="card__radio"
@ -95,8 +106,12 @@
:class="cloneForm.search_mode === 'embedding' ? 'active' : ''" :class="cloneForm.search_mode === 'embedding' ? 'active' : ''"
> >
<el-radio value="embedding" size="large"> <el-radio value="embedding" size="large">
<p class="mb-4">向量检索</p> <p class="mb-4">
<el-text type="info">通过向量距离计算与用户问题最相似的文本分段</el-text> {{ $t('views.application.applicationForm.dialog.vectorSearch') }}
</p>
<el-text type="info">{{
$t('views.application.applicationForm.dialog.vectorSearchTooltip')
}}</el-text>
</el-radio> </el-radio>
</el-card> </el-card>
<el-card <el-card
@ -105,8 +120,12 @@
:class="cloneForm.search_mode === 'keywords' ? 'active' : ''" :class="cloneForm.search_mode === 'keywords' ? 'active' : ''"
> >
<el-radio value="keywords" size="large"> <el-radio value="keywords" size="large">
<p class="mb-4">全文检索</p> <p class="mb-4">
<el-text type="info">通过关键词检索返回包含关键词最多的文本分段</el-text> {{ $t('views.application.applicationForm.dialog.fullTextSearch') }}
</p>
<el-text type="info">{{
$t('views.application.applicationForm.dialog.fullTextSearchTooltip')
}}</el-text>
</el-radio> </el-radio>
</el-card> </el-card>
<el-card <el-card
@ -115,10 +134,12 @@
:class="cloneForm.search_mode === 'blend' ? 'active' : ''" :class="cloneForm.search_mode === 'blend' ? 'active' : ''"
> >
<el-radio value="blend" size="large"> <el-radio value="blend" size="large">
<p class="mb-4">混合检索</p> <p class="mb-4">
<el-text type="info" {{ $t('views.application.applicationForm.dialog.hybridSearch') }}
>同时执行全文检索和向量检索再进行重排序从两类查询结果中选择匹配用户问题的最佳结果</el-text </p>
> <el-text type="info">{{
$t('views.application.applicationForm.dialog.hybridSearchTooltip')
}}</el-text>
</el-radio> </el-radio>
</el-card> </el-card>
</el-radio-group> </el-radio-group>
@ -126,7 +147,9 @@
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<div class="mb-16"> <div class="mb-16">
<div class="title mb-8">相似度高于</div> <div class="title mb-8">
{{ $t('views.application.applicationForm.dialog.similarityThreshold') }}
</div>
<el-input-number <el-input-number
v-model="cloneForm.similarity" v-model="cloneForm.similarity"
:min="0" :min="0"
@ -141,7 +164,9 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<div class="mb-16"> <div class="mb-16">
<div class="title mb-8">返回分段数 TOP</div> <div class="title mb-8">
{{ $t('views.application.applicationForm.dialogues.topReferences') }}
</div>
<el-input-number <el-input-number
v-model="cloneForm.top_number" v-model="cloneForm.top_number"
:min="1" :min="1"
@ -154,8 +179,10 @@
</el-row> </el-row>
<div class="text-right"> <div class="text-right">
<el-button @click="popoverVisible = false">{{$t('common.cancel')}}</el-button> <el-button @click="popoverVisible = false">{{ $t('common.cancel') }}</el-button>
<el-button type="primary" @click="settingChange('close')">{{$t('common.confirm')}}</el-button> <el-button type="primary" @click="settingChange('close')">{{
$t('common.confirm')
}}</el-button>
</div> </div>
</el-popover> </el-popover>
<div class="operate-textarea flex"> <div class="operate-textarea flex">
@ -195,7 +222,7 @@ import applicationApi from '@/api/application'
import ParagraphDialog from '@/views/paragraph/component/ParagraphDialog.vue' import ParagraphDialog from '@/views/paragraph/component/ParagraphDialog.vue'
import { arraySort } from '@/utils/utils' import { arraySort } from '@/utils/utils'
import emptyImg from '@/assets/hit-test-empty.png' import emptyImg from '@/assets/hit-test-empty.png'
import { t } from '@/locales'
const route = useRoute() const route = useRoute()
const { const {
meta: { activeMenu }, meta: { activeMenu },
@ -249,7 +276,7 @@ function settingChange(val: string) {
} }
function editParagraph(row: any) { function editParagraph(row: any) {
title.value = '分段详情' title.value = t('views.paragraph.paragraphDetail')
ParagraphDialogRef.value.open(row) ParagraphDialogRef.value.open(row)
} }

View File

@ -19,8 +19,12 @@
</div> </div>
<template #footer> <template #footer>
<div> <div>
<el-button @click="pre" :disabled="pre_disable || loading">上一条</el-button> <el-button @click="pre" :disabled="pre_disable || loading">{{
<el-button @click="next" :disabled="next_disable || loading">下一条</el-button> $t('views.log.buttons.prev')
}}</el-button>
<el-button @click="next" :disabled="next_disable || loading">{{
$t('views.log.buttons.next')
}}</el-button>
</div> </div>
</template> </template>
</el-drawer> </el-drawer>

View File

@ -1,6 +1,6 @@
<template> <template>
<el-dialog <el-dialog
title="修改内容" :title="$t('views.log.editContent')"
v-model="dialogVisible" v-model="dialogVisible"
width="600" width="600"
:close-on-click-modal="false" :close-on-click-modal="false"
@ -14,19 +14,19 @@
:rules="rules" :rules="rules"
@submit.prevent @submit.prevent
> >
<el-form-item label="关联问题"> <el-form-item :label="$t('views.paragraph.relatedProblem.title')">
<el-input <el-input
v-model="form.problem_text" v-model="form.problem_text"
placeholder="关联问题" :placeholder="$t('views.paragraph.relatedProblem.title')"
maxlength="256" maxlength="256"
show-word-limit show-word-limit
> >
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item label="内容" prop="content"> <el-form-item :label="$t('views.log.form.content.label')" prop="content">
<MdEditor <MdEditor
v-model="form.content" v-model="form.content"
placeholder="请输入内容" :placeholder="$t('views.log.form.content.placeholder')"
:maxLength="100000" :maxLength="100000"
:preview="false" :preview="false"
:toolbars="toolbars" :toolbars="toolbars"
@ -39,20 +39,20 @@
</template> </template>
</MdEditor> </MdEditor>
</el-form-item> </el-form-item>
<el-form-item label="标题"> <el-form-item :label="$t('views.log.form.title.label')">
<el-input <el-input
show-word-limit show-word-limit
v-model="form.title" v-model="form.title"
placeholder="请给当前内容设置一个标题,以便管理查看" :placeholder="$t('views.log.form.title.placeholder')"
maxlength="256" maxlength="256"
> >
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item label="选择知识库" prop="dataset_id"> <el-form-item :label="$t('views.log.selectDataset')" prop="dataset_id">
<el-select <el-select
v-model="form.dataset_id" v-model="form.dataset_id"
filterable filterable
placeholder="请选择知识库" :placeholder="$t('views.log.selectDatasetPlaceholder')"
:loading="optionLoading" :loading="optionLoading"
@change="changeDataset" @change="changeDataset"
> >
@ -79,11 +79,11 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="保存至文档" prop="document_id"> <el-form-item :label="$t('views.log.saveToDocument')" prop="document_id">
<el-select <el-select
v-model="form.document_id" v-model="form.document_id"
filterable filterable
placeholder="请选择文档" :placeholder="$t('views.log.documentPlaceholder')"
:loading="optionLoading" :loading="optionLoading"
@change="changeDocument" @change="changeDocument"
> >
@ -100,8 +100,10 @@
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click.prevent="dialogVisible = false"> {{$t('common.cancel')}} </el-button> <el-button @click.prevent="dialogVisible = false"> {{ $t('common.cancel') }} </el-button>
<el-button type="primary" @click="submitForm(formRef)" :loading="loading"> {{$t('common.save')}} </el-button> <el-button type="primary" @click="submitForm(formRef)" :loading="loading">
{{ $t('common.save') }}
</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
@ -113,7 +115,7 @@ import type { FormInstance, FormRules } from 'element-plus'
import logApi from '@/api/log' import logApi from '@/api/log'
import imageApi from '@/api/image' import imageApi from '@/api/image'
import useStore from '@/stores' import useStore from '@/stores'
import { t } from '@/locales'
const { application, document, user } = useStore() const { application, document, user } = useStore()
const route = useRoute() const route = useRoute()
@ -170,9 +172,11 @@ const form = ref<any>({
}) })
const rules = reactive<FormRules>({ const rules = reactive<FormRules>({
content: [{ required: true, message: '请输入内容', trigger: 'blur' }], content: [{ required: true, message: t('views.log.form.content.placeholder'), trigger: 'blur' }],
dataset_id: [{ required: true, message: '请选择知识库', trigger: 'change' }], dataset_id: [
document_id: [{ required: true, message: '请选择文档', trigger: 'change' }] { required: true, message: t('views.log.selectDatasetPlaceholder'), trigger: 'change' }
],
document_id: [{ required: true, message: t('views.log.documentPlaceholder'), trigger: 'change' }]
}) })
const datasetList = ref<any[]>([]) const datasetList = ref<any[]>([])

View File

@ -1,6 +1,6 @@
<template> <template>
<el-dialog <el-dialog
title="修改标注" :title="$t('views.log.editMark')"
v-model="dialogVisible" v-model="dialogVisible"
width="600" width="600"
class="edit-mark-dialog" class="edit-mark-dialog"
@ -9,7 +9,7 @@
> >
<template #header="{ titleId, titleClass }"> <template #header="{ titleId, titleClass }">
<div class="flex-between"> <div class="flex-between">
<h4 :id="titleId" :class="titleClass">修改标注</h4> <h4 :id="titleId" :class="titleClass">{{ $t('views.log.editMark') }}</h4>
<div class="text-right"> <div class="text-right">
<el-button text @click="isEdit = true" v-if="!isEdit"> <el-button text @click="isEdit = true" v-if="!isEdit">
<el-icon><EditPen /></el-icon> <el-icon><EditPen /></el-icon>
@ -36,8 +36,8 @@
<el-form-item prop="content"> <el-form-item prop="content">
<el-input <el-input
v-model="form.content" v-model="form.content"
placeholder="请输入分段内容" :placeholder="$t('views.log.form.content.placeholder')"
maxlength="100000" :maxlength="100000"
show-word-limit show-word-limit
:rows="15" :rows="15"
type="textarea" type="textarea"
@ -51,8 +51,10 @@
<template #footer> <template #footer>
<span class="dialog-footer" v-if="isEdit"> <span class="dialog-footer" v-if="isEdit">
<el-button @click.prevent="isEdit = false"> {{$t('common.cancel')}} </el-button> <el-button @click.prevent="isEdit = false"> {{ $t('common.cancel') }} </el-button>
<el-button type="primary" @click="submit(formRef)" :loading="loading"> {{$t('common.save')}} </el-button> <el-button type="primary" @click="submit(formRef)" :loading="loading">
{{ $t('common.save') }}
</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
@ -63,6 +65,7 @@ import { useRoute } from 'vue-router'
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
import logApi from '@/api/log' import logApi from '@/api/log'
import useStore from '@/stores' import useStore from '@/stores'
import { t } from '@/locales'
import { MsgSuccess, MsgConfirm } from '@/utils/message' import { MsgSuccess, MsgConfirm } from '@/utils/message'
const route = useRoute() const route = useRoute()
@ -84,7 +87,7 @@ const isEdit = ref(false)
const detail = ref<any>({}) const detail = ref<any>({})
const rules = reactive<FormRules>({ const rules = reactive<FormRules>({
content: [{ required: true, message: '请输入内容', trigger: 'blur' }] content: [{ required: true, message: t('views.log.form.content.placeholder'), trigger: 'blur' }]
}) })
watch(dialogVisible, (bool) => { watch(dialogVisible, (bool) => {

View File

@ -1,5 +1,5 @@
<template> <template>
<LayoutContainer header="对话日志"> <LayoutContainer :header="$t('views.log.title')">
<div class="p-24"> <div class="p-24">
<div class="mb-16"> <div class="mb-16">
<el-select v-model="history_day" class="mr-12 w-120" @change="changeDayHandle"> <el-select v-model="history_day" class="mr-12 w-120" @change="changeDayHandle">
@ -30,10 +30,12 @@
clearable clearable
/> />
<div style="display: flex; align-items: center" class="float-right"> <div style="display: flex; align-items: center" class="float-right">
<el-button @click="dialogVisible = true">清除策略</el-button> <el-button @click="dialogVisible = true">{{
<el-button @click="exportLog">{{$t('common.export')}}</el-button> $t('views.log.buttons.clearStrategy')
}}</el-button>
<el-button @click="exportLog">{{ $t('common.export') }}</el-button>
<el-button @click="openDocumentDialog" :disabled="multipleSelection.length === 0" <el-button @click="openDocumentDialog" :disabled="multipleSelection.length === 0"
>添加至知识库 >{{ $t('views.log.addToDataset') }}
</el-button> </el-button>
</div> </div>
</div> </div>
@ -51,12 +53,20 @@
ref="multipleTableRef" ref="multipleTableRef"
> >
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
<el-table-column prop="abstract" label="摘要" show-overflow-tooltip /> <el-table-column
<el-table-column prop="chat_record_count" label="对话提问数" align="right" /> prop="abstract"
:label="$t('views.log.table.abstract')"
show-overflow-tooltip
/>
<el-table-column
prop="chat_record_count"
:label="$t('views.log.table.chat_record_count')"
align="right"
/>
<el-table-column prop="star_num" align="right"> <el-table-column prop="star_num" align="right">
<template #header> <template #header>
<div> <div>
<span>用户反馈</span> <span>{{ $t('views.log.table.feedback.label') }}</span>
<el-popover :width="190" trigger="click" :visible="popoverVisible"> <el-popover :width="190" trigger="click" :visible="popoverVisible">
<template #reference> <template #reference>
<el-button <el-button
@ -73,7 +83,7 @@
<div class="filter"> <div class="filter">
<div class="form-item mb-16"> <div class="form-item mb-16">
<div @click.stop> <div @click.stop>
赞同 >= {{ $t('views.log.table.feedback.star') }} >=
<el-input-number <el-input-number
v-model="filter.min_star" v-model="filter.min_star"
:min="0" :min="0"
@ -88,7 +98,7 @@
</div> </div>
<div class="form-item mb-16"> <div class="form-item mb-16">
<div @click.stop> <div @click.stop>
反对 >= {{ $t('views.log.table.feedback.trample') }} >=
<el-input-number <el-input-number
v-model="filter.min_trample" v-model="filter.min_trample"
:min="0" :min="0"
@ -103,8 +113,12 @@
</div> </div>
</div> </div>
<div class="text-right"> <div class="text-right">
<el-button size="small" @click="filterChange('clear')">清除</el-button> <el-button size="small" @click="filterChange('clear')">{{
<el-button type="primary" @click="filterChange" size="small">{{ $t('common.confirm') }}</el-button> $t('common.clear')
}}</el-button>
<el-button type="primary" @click="filterChange" size="small">{{
$t('common.confirm')
}}</el-button>
</div> </div>
</el-popover> </el-popover>
</div> </div>
@ -123,8 +137,8 @@
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="mark_sum" label="改进标注" align="right" /> <el-table-column prop="mark_sum" :label="$t('views.log.table.mark')" align="right" />
<el-table-column label="最近对话时间" width="180"> <el-table-column :label="$t('views.log.table.recenTimes')" width="180">
<template #default="{ row }"> <template #default="{ row }">
{{ datetimeFormat(row.update_time) }} {{ datetimeFormat(row.update_time) }}
</template> </template>
@ -153,7 +167,7 @@
@refresh="refresh" @refresh="refresh"
/> />
<el-dialog <el-dialog
title="清除策略" :title="$t('views.log.buttons.clearStrategy')"
v-model="dialogVisible" v-model="dialogVisible"
width="25%" width="25%"
:close-on-click-modal="false" :close-on-click-modal="false"
@ -169,7 +183,7 @@
step-strictly step-strictly
style="width: 110px; margin-left: 8px; margin-right: 8px" style="width: 110px; margin-left: 8px; margin-right: 8px"
></el-input-number> ></el-input-number>
<span>天之前的对话记录</span> <span>{{ $t('views.log.form.daysText') }}</span>
<template #footer> <template #footer>
<div class="dialog-footer" style="margin-top: 16px"> <div class="dialog-footer" style="margin-top: 16px">
<el-button @click="dialogVisible = false" <el-button @click="dialogVisible = false"
@ -183,7 +197,7 @@
</el-dialog> </el-dialog>
<el-dialog <el-dialog
title="添加至知识库" :title="$t('views.log.addToDataset')"
v-model="documentDialogVisible" v-model="documentDialogVisible"
width="50%" width="50%"
:close-on-click-modal="false" :close-on-click-modal="false"
@ -197,11 +211,11 @@
:rules="rules" :rules="rules"
@submit.prevent @submit.prevent
> >
<el-form-item label="选择知识库" prop="dataset_id"> <el-form-item :label="$t('views.log.selectDataset')" prop="dataset_id">
<el-select <el-select
v-model="form.dataset_id" v-model="form.dataset_id"
filterable filterable
placeholder="请选择知识库" :placeholder="$t('views.log.selectDatasetPlaceholder')"
:loading="optionLoading" :loading="optionLoading"
@change="changeDataset" @change="changeDataset"
> >
@ -233,11 +247,11 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="保存至文档" prop="document_id"> <el-form-item :label="$t('views.log.saveToDocument')" prop="document_id">
<el-select <el-select
v-model="form.document_id" v-model="form.document_id"
filterable filterable
placeholder="请选择文档" :placeholder="$t('views.log.documentPlaceholder')"
:loading="optionLoading" :loading="optionLoading"
@change="changeDocument" @change="changeDocument"
> >
@ -254,9 +268,11 @@
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click.prevent="documentDialogVisible = false"> {{$t('common.cancel')}} </el-button> <el-button @click.prevent="documentDialogVisible = false">
{{ $t('common.cancel') }}
</el-button>
<el-button type="primary" @click="submitForm(formRef)" :loading="documentLoading"> <el-button type="primary" @click="submitForm(formRef)" :loading="documentLoading">
{{$t('common.save')}} {{ $t('common.save') }}
</el-button> </el-button>
</span> </span>
</template> </template>
@ -363,8 +379,16 @@ const form = ref<any>({
}) })
const rules = reactive<FormRules>({ const rules = reactive<FormRules>({
dataset_id: [{ required: true, message: '请选择知识库', trigger: 'change' }], dataset_id: [
document_id: [{ required: true, message: '请选择文档', trigger: 'change' }] { required: true, message: t('views.log.selectDatasetPlaceholder'), trigger: 'change' }
],
document_id: [
{
required: true,
message: t('views.log.documentPlaceholder'),
trigger: 'change'
}
]
}) })
const optionLoading = ref(false) const optionLoading = ref(false)
@ -453,20 +477,20 @@ const handleSelectionChange = (val: any[]) => {
multipleSelection.value = val multipleSelection.value = val
} }
function deleteLog(row: any) { // function deleteLog(row: any) {
MsgConfirm(`是否删除对话:${row.abstract} ?`, `删除后无法恢复,请谨慎操作。`, { // MsgConfirm(`${row.abstract} ?`, ``, {
confirmButtonText: t('common.delete'), // confirmButtonText: t('common.delete'),
confirmButtonClass: 'danger' // confirmButtonClass: 'danger'
}) // })
.then(() => { // .then(() => {
loading.value = true // loading.value = true
logApi.delChatLog(id as string, row.id, loading).then(() => { // logApi.delChatLog(id as string, row.id, loading).then(() => {
MsgSuccess(t('common.deleteSuccess')) // MsgSuccess(t('common.deleteSuccess'))
getList() // getList()
}) // })
}) // })
.catch(() => {}) // .catch(() => {})
} // }
function getList() { function getList() {
let obj: any = { let obj: any = {

View File

@ -7,22 +7,22 @@
:rules="rules" :rules="rules"
@submit.prevent @submit.prevent
> >
<el-form-item :label="$t('views.document.paragraph.form.paragraphTitle.label')"> <el-form-item :label="$t('views.paragraph.form.paragraphTitle.label')">
<el-input <el-input
v-if="isEdit" v-if="isEdit"
v-model="form.title" v-model="form.title"
:placeholder="$t('views.document.paragraph.form.paragraphTitle.placeholder')" :placeholder="$t('views.paragraph.form.paragraphTitle.placeholder')"
maxlength="256" maxlength="256"
show-word-limit show-word-limit
> >
</el-input> </el-input>
<span class="lighter" v-else>{{ form.title || '-' }}</span> <span class="lighter" v-else>{{ form.title || '-' }}</span>
</el-form-item> </el-form-item>
<el-form-item :label="$t('views.document.paragraph.form.content.label')" prop="content"> <el-form-item :label="$t('views.paragraph.form.content.label')" prop="content">
<MdEditor <MdEditor
v-if="isEdit" v-if="isEdit"
v-model="form.content" v-model="form.content"
:placeholder="$t('views.document.paragraph.form.content.placeholder')" :placeholder="$t('views.paragraph.form.content.placeholder')"
:maxLength="100000" :maxLength="100000"
:preview="false" :preview="false"
:toolbars="toolbars" :toolbars="toolbars"
@ -98,8 +98,8 @@ const form = ref<any>({
const rules = reactive<FormRules>({ const rules = reactive<FormRules>({
content: [ content: [
{ required: true, message: t('views.document.paragraph.form.content.requiredMessage1'), trigger: 'blur' }, { required: true, message: t('views.paragraph.form.content.requiredMessage1'), trigger: 'blur' },
{ max: 100000, message: t('views.document.paragraph.form.content.requiredMessage2'), trigger: 'blur' } { max: 100000, message: t('views.paragraph.form.content.requiredMessage2'), trigger: 'blur' }
] ]
}) })

View File

@ -1,7 +1,7 @@
<template> <template>
<p class="bold title p-24" style="padding-bottom: 0"> <p class="bold title p-24" style="padding-bottom: 0">
<span class="flex align-center"> <span class="flex align-center">
<span>{{ $t('views.document.paragraph.relatedProblem.title') }}</span> <span>{{ $t('views.paragraph.relatedProblem.title') }}</span>
<el-divider direction="vertical" class="mr-4" /> <el-divider direction="vertical" class="mr-4" />
<el-button text @click="addProblem"> <el-button text @click="addProblem">
<el-icon><Plus /></el-icon> <el-icon><Plus /></el-icon>
@ -18,7 +18,7 @@
allow-create allow-create
default-first-option default-first-option
:reserve-keyword="false" :reserve-keyword="false"
:placeholder="$t('views.document.paragraph.relatedProblem.placeholder')" :placeholder="$t('views.paragraph.relatedProblem.placeholder')"
remote remote
:remote-method="remoteMethod" :remote-method="remoteMethod"
:loading="optionLoading" :loading="optionLoading"

View File

@ -1,6 +1,6 @@
<template> <template>
<el-dialog <el-dialog
title="选择知识库/文档" :title="`${$t('views.log.selectDataset')}/${$t('common.document')}`"
v-model="dialogVisible" v-model="dialogVisible"
width="500" width="500"
:close-on-click-modal="false" :close-on-click-modal="false"
@ -14,11 +14,11 @@
:rules="rules" :rules="rules"
@submit.prevent @submit.prevent
> >
<el-form-item label="选择知识库" prop="dataset_id"> <el-form-item :label="$t('views.log.selectDataset')" prop="dataset_id">
<el-select <el-select
v-model="form.dataset_id" v-model="form.dataset_id"
filterable filterable
placeholder="请选择知识库" :placeholder="$t('views.log.selectDatasetPlaceholder')"
:loading="optionLoading" :loading="optionLoading"
@change="changeDataset" @change="changeDataset"
> >
@ -45,11 +45,11 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="保存至文档" prop="document_id"> <el-form-item :label="$t('views.log.addToDatase.saveToDocument')" prop="document_id">
<el-select <el-select
v-model="form.document_id" v-model="form.document_id"
filterable filterable
placeholder="请选择文档" :placeholder="$t('views.log.addToDatase.documentPlaceholder')"
:loading="optionLoading" :loading="optionLoading"
> >
<el-option <el-option
@ -79,7 +79,7 @@ import { useRoute } from 'vue-router'
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
import paragraphApi from '@/api/paragraph' import paragraphApi from '@/api/paragraph'
import useStore from '@/stores' import useStore from '@/stores'
import { t } from '@/locales'
const { dataset, document } = useStore() const { dataset, document } = useStore()
const route = useRoute() const route = useRoute()
@ -99,8 +99,8 @@ const form = ref<any>({
}) })
const rules = reactive<FormRules>({ const rules = reactive<FormRules>({
dataset_id: [{ required: true, message: '请选择知识库', trigger: 'change' }], dataset_id: [{ required: true, message: t('views.log.selectDatasetPlaceholder'), trigger: 'change' }],
document_id: [{ required: true, message: '请选择文档', trigger: 'change' }] document_id: [{ required: true, message: t('views.log.documentPlaceholder'), trigger: 'change' }]
}) })
const datasetList = ref<any[]>([]) const datasetList = ref<any[]>([])

View File

@ -4,17 +4,20 @@
<div style="width: 78%"> <div style="width: 78%">
<h3 style="display: inline-block">{{ documentDetail?.name }}</h3> <h3 style="display: inline-block">{{ documentDetail?.name }}</h3>
<el-text type="info" v-if="documentDetail?.type === '1'" <el-text type="info" v-if="documentDetail?.type === '1'"
>文档地址<el-link :href="documentDetail?.meta?.source_url" target="_blank"> >{{ $t('views.document.form.source_url.label') }}<el-link
:href="documentDetail?.meta?.source_url"
target="_blank"
>
<span class="break-all">{{ documentDetail?.meta?.source_url }} </span></el-link <span class="break-all">{{ documentDetail?.meta?.source_url }} </span></el-link
> >
</el-text> </el-text>
</div> </div>
<div class="header-button"> <div class="header-button">
<el-button @click="batchSelectedHandle(true)" v-if="isBatch === false"> <el-button @click="batchSelectedHandle(true)" v-if="isBatch === false">
批量选择 {{ $t('views.paragraph.setting.batchSelected') }}
</el-button> </el-button>
<el-button @click="batchSelectedHandle(false)" v-if="isBatch === true"> <el-button @click="batchSelectedHandle(false)" v-if="isBatch === true">
取消选择 {{ $t('views.paragraph.setting.cancelSelected') }}
</el-button> </el-button>
<el-button <el-button
@click="addParagraph" @click="addParagraph"
@ -22,7 +25,7 @@
:disabled="loading" :disabled="loading"
v-if="isBatch === false" v-if="isBatch === false"
> >
添加分段 {{ $t('views.paragraph.addParagraph') }}
</el-button> </el-button>
</div> </div>
</template> </template>
@ -31,7 +34,7 @@
v-loading="(paginationConfig.current_page === 1 && loading) || changeStateloading" v-loading="(paginationConfig.current_page === 1 && loading) || changeStateloading"
> >
<div class="flex-between p-8"> <div class="flex-between p-8">
<span>{{ paginationConfig.total }} 段落</span> <span>{{ paginationConfig.total }} {{ $t('views.paragraph.title') }}</span>
<el-input <el-input
v-model="search" v-model="search"
:placeholder="$t('common.search')" :placeholder="$t('common.search')"
@ -42,15 +45,15 @@
> >
<template #prepend> <template #prepend>
<el-select v-model="searchType" placeholder="Select" style="width: 80px"> <el-select v-model="searchType" placeholder="Select" style="width: 80px">
<el-option label="标题" value="title" /> <el-option :label="$t('views.paragraph.searchBar.title')" value="title" />
<el-option label="内容" value="content" /> <el-option :label="$t('views.paragraph.searchBar.content')" value="content" />
</el-select> </el-select>
</template> </template>
</el-input> </el-input>
</div> </div>
<el-scrollbar> <el-scrollbar>
<div class="document-detail-height"> <div class="document-detail-height">
<el-empty v-if="paragraphDetail.length == 0" description="暂无数据" /> <el-empty v-if="paragraphDetail.length == 0" :description="$t('common.noData')" />
<InfiniteScroll <InfiniteScroll
v-else v-else
@ -87,7 +90,10 @@
<template #footer> <template #footer>
<div class="footer-content flex-between"> <div class="footer-content flex-between">
<span> {{ numberFormat(item?.content.length) || 0 }} 字符 </span> <span>
{{ numberFormat(item?.content.length) || 0 }}
{{ $t('views.paragraph.character_count') }}
</span>
</div> </div>
</template> </template>
</CardBox> </CardBox>
@ -113,7 +119,10 @@
<template #footer> <template #footer>
<div class="footer-content flex-between"> <div class="footer-content flex-between">
<span> {{ numberFormat(item?.content.length) || 0 }} 字符 </span> <span>
{{ numberFormat(item?.content.length) || 0 }}
{{ $t('views.paragraph.character_count') }}
</span>
<span @click.stop> <span @click.stop>
<el-dropdown trigger="click"> <el-dropdown trigger="click">
@ -124,11 +133,13 @@
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item @click="openGenerateDialog(item)"> <el-dropdown-item @click="openGenerateDialog(item)">
<el-icon><Connection /></el-icon> <el-icon><Connection /></el-icon>
{{ $t('views.document.setting.generateQuestion') }}</el-dropdown-item {{
$t('views.document.setting.generateQuestion')
}}</el-dropdown-item
> >
<el-dropdown-item @click="openSelectDocumentDialog(item)"> <el-dropdown-item @click="openSelectDocumentDialog(item)">
<AppIcon iconName="app-migrate"></AppIcon> <AppIcon iconName="app-migrate"></AppIcon>
{{$t('views.document.setting.migration')}}</el-dropdown-item {{ $t('views.document.setting.migration') }}</el-dropdown-item
> >
<el-dropdown-item icon="Delete" @click.stop="deleteParagraph(item)">{{ <el-dropdown-item icon="Delete" @click.stop="deleteParagraph(item)">{{
$t('common.delete') $t('common.delete')
@ -151,13 +162,16 @@
{{ $t('views.document.setting.generateQuestion') }} {{ $t('views.document.setting.generateQuestion') }}
</el-button> </el-button>
<el-button :disabled="multipleSelection.length === 0" @click="openSelectDocumentDialog()"> <el-button :disabled="multipleSelection.length === 0" @click="openSelectDocumentDialog()">
{{$t('views.document.setting.migration')}} {{ $t('views.document.setting.migration') }}
</el-button> </el-button>
<el-button :disabled="multipleSelection.length === 0" @click="deleteMulParagraph"> <el-button :disabled="multipleSelection.length === 0" @click="deleteMulParagraph">
{{ $t('common.delete') }} {{ $t('common.delete') }}
</el-button> </el-button>
<span class="ml-8"> 已选 {{ multipleSelection.length }} </span> <span class="ml-8">
{{ $t('views.document.selected') }} {{ multipleSelection.length }}
{{ $t('views.document.items') }}
</span>
</div> </div>
</div> </div>
<ParagraphDialog ref="ParagraphDialogRef" :title="title" @refresh="refresh" /> <ParagraphDialog ref="ParagraphDialogRef" :title="title" @refresh="refresh" />
@ -176,7 +190,7 @@ import GenerateRelatedDialog from '@/components/generate-related-dialog/index.vu
import { numberFormat } from '@/utils/utils' import { numberFormat } from '@/utils/utils'
import { MsgSuccess, MsgConfirm } from '@/utils/message' import { MsgSuccess, MsgConfirm } from '@/utils/message'
import useStore from '@/stores' import useStore from '@/stores'
import { t } from '@/locales'
const { paragraph } = useStore() const { paragraph } = useStore()
const route = useRoute() const route = useRoute()
const { const {
@ -208,7 +222,7 @@ function refreshMigrateParagraph() {
(v) => !multipleSelection.value.includes(v.id) (v) => !multipleSelection.value.includes(v.id)
) )
multipleSelection.value = [] multipleSelection.value = []
MsgSuccess('迁移删除成功') MsgSuccess(t('views.document.tip.migrationSuccess'))
} }
function openSelectDocumentDialog(row?: any) { function openSelectDocumentDialog(row?: any) {
@ -219,8 +233,8 @@ function openSelectDocumentDialog(row?: any) {
} }
function deleteMulParagraph() { function deleteMulParagraph() {
MsgConfirm( MsgConfirm(
`是否批量删除 ${multipleSelection.value.length} 个分段?`, `${t('views.document.delete.confirmTitle1')} ${multipleSelection.value.length} ${t('views.document.delete.confirmTitle2')}`,
`删除后无法恢复,请谨慎操作。`, t('views.paragraph.delete.confirmMessage'),
{ {
confirmButtonText: t('common.delete'), confirmButtonText: t('common.delete'),
confirmButtonClass: 'danger' confirmButtonClass: 'danger'
@ -234,7 +248,7 @@ function deleteMulParagraph() {
(v) => !multipleSelection.value.includes(v.id) (v) => !multipleSelection.value.includes(v.id)
) )
multipleSelection.value = [] multipleSelection.value = []
MsgSuccess('批量删除成功') MsgSuccess(t('views.document.delete.successMessage'))
}) })
}) })
.catch(() => {}) .catch(() => {})
@ -276,10 +290,14 @@ function changeState(row: any) {
} }
function deleteParagraph(row: any) { function deleteParagraph(row: any) {
MsgConfirm(`是否删除段落:${row.title || '-'} ?`, `删除后无法恢复,请谨慎操作。`, { MsgConfirm(
confirmButtonText: t('common.delete'), `${t('views.paragraph.delete.confirmTitle')} ${row.title || '-'} ?`,
confirmButtonClass: 'danger' t('views.paragraph.delete.confirmMessage'),
}) {
confirmButtonText: t('common.delete'),
confirmButtonClass: 'danger'
}
)
.then(() => { .then(() => {
paragraph.asyncDelParagraph(id, documentId, row.id, loading).then(() => { paragraph.asyncDelParagraph(id, documentId, row.id, loading).then(() => {
const index = paragraphDetail.value.findIndex((v) => v.id === row.id) const index = paragraphDetail.value.findIndex((v) => v.id === row.id)
@ -291,11 +309,11 @@ function deleteParagraph(row: any) {
} }
function addParagraph() { function addParagraph() {
title.value = '添加分段' title.value = t('views.paragraph.addParagraph')
ParagraphDialogRef.value.open() ParagraphDialogRef.value.open()
} }
function editParagraph(row: any) { function editParagraph(row: any) {
title.value = '分段详情' title.value = t('views.paragraph.paragraphDetail')
ParagraphDialogRef.value.open(row) ParagraphDialogRef.value.open(row)
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<el-dialog <el-dialog
title="创建问题" :title="$t('views.problem.createProblem')"
v-model="dialogVisible" v-model="dialogVisible"
:close-on-click-modal="false" :close-on-click-modal="false"
:close-on-press-escape="false" :close-on-press-escape="false"
@ -13,10 +13,10 @@
:model="form" :model="form"
require-asterisk-position="right" require-asterisk-position="right"
> >
<el-form-item label="问题" prop="data"> <el-form-item :label="$t('views.problem.title')" prop="data">
<el-input <el-input
v-model="form.data" v-model="form.data"
placeholder="请输入问题,支持输入多个,一行一个。" :placeholder="$t('views.problem.tip.placeholder')"
:rows="10" :rows="10"
type="textarea" type="textarea"
/> />
@ -38,7 +38,7 @@ import { useRoute } from 'vue-router'
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
import { MsgSuccess } from '@/utils/message' import { MsgSuccess } from '@/utils/message'
import useStore from '@/stores' import useStore from '@/stores'
import { t } from '@/locales'
const route = useRoute() const route = useRoute()
const { const {
params: { id } params: { id }
@ -54,7 +54,7 @@ const form = ref<any>({
}) })
const rules = reactive({ const rules = reactive({
data: [{ required: true, message: '请输入问题', trigger: 'blur' }] data: [{ required: true, message: t('views.problem.tip.requiredMessage'), trigger: 'blur' }]
}) })
const dialogVisible = ref<boolean>(false) const dialogVisible = ref<boolean>(false)

View File

@ -1,13 +1,13 @@
<template> <template>
<el-drawer v-model="visible" size="60%" @close="closeHandle"> <el-drawer v-model="visible" size="60%" @close="closeHandle">
<template #header> <template #header>
<h4>问题详情</h4> <h4>{{ $t('views.problem.detailProblem') }}</h4>
</template> </template>
<div> <div>
<el-scrollbar> <el-scrollbar>
<div class="p-8"> <div class="p-8">
<el-form label-position="top" v-loading="loading" @submit.prevent> <el-form label-position="top" v-loading="loading" @submit.prevent>
<el-form-item label="问题"> <el-form-item :label="$t('views.problem.title')">
<ReadWrite <ReadWrite
@change="editName" @change="editName"
:data="currentContent" :data="currentContent"
@ -15,7 +15,7 @@
:maxlength="256" :maxlength="256"
/> />
</el-form-item> </el-form-item>
<el-form-item label="关联分段"> <el-form-item :label="$t('views.problem.relateParagraph.title')">
<template v-for="(item, index) in paragraphList" :key="index"> <template v-for="(item, index) in paragraphList" :key="index">
<CardBox <CardBox
:title="item.title || '-'" :title="item.title || '-'"
@ -25,7 +25,11 @@
> >
<div class="active-button"> <div class="active-button">
<span class="mr-4"> <span class="mr-4">
<el-tooltip effect="dark" content="取消关联" placement="top"> <el-tooltip
effect="dark"
:content="$t('views.problem.setting.cancelRelated')"
placement="top"
>
<el-button type="primary" text @click.stop="disassociation(item)"> <el-button type="primary" text @click.stop="disassociation(item)">
<AppIcon iconName="app-quxiaoguanlian"></AppIcon> <AppIcon iconName="app-quxiaoguanlian"></AppIcon>
</el-button> </el-button>
@ -53,14 +57,24 @@
</el-form> </el-form>
</div> </div>
</el-scrollbar> </el-scrollbar>
<ParagraphDialog ref="ParagraphDialogRef" title="编辑分段" @refresh="refresh" /> <ParagraphDialog
ref="ParagraphDialogRef"
:title="$t('views.paragraph.editParagraph')"
@refresh="refresh"
/>
<RelateProblemDialog ref="RelateProblemDialogRef" @refresh="refresh" /> <RelateProblemDialog ref="RelateProblemDialogRef" @refresh="refresh" />
</div> </div>
<template #footer> <template #footer>
<div> <div>
<el-button @click="relateProblem">关联分段</el-button> <el-button @click="relateProblem">{{
<el-button @click="pre" :disabled="pre_disable || loading">上一条</el-button> $t('views.problem.relateParagraph.title')
<el-button @click="next" :disabled="next_disable || loading">下一条</el-button> }}</el-button>
<el-button @click="pre" :disabled="pre_disable || loading">{{
$t('views.log.buttons.prev')
}}</el-button>
<el-button @click="next" :disabled="next_disable || loading">{{
$t('views.log.buttons.next')
}}</el-button>
</div> </div>
</template> </template>
</el-drawer> </el-drawer>
@ -74,7 +88,7 @@ import ParagraphDialog from '@/views/paragraph/component/ParagraphDialog.vue'
import RelateProblemDialog from './RelateProblemDialog.vue' import RelateProblemDialog from './RelateProblemDialog.vue'
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message' import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
import useStore from '@/stores' import useStore from '@/stores'
import { t } from '@/locales'
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
/** /**
@ -141,10 +155,10 @@ function editName(val: string) {
} }
problemApi.putProblems(id as string, props.currentId, obj, loading).then(() => { problemApi.putProblems(id as string, props.currentId, obj, loading).then(() => {
emit('update:currentContent', val) emit('update:currentContent', val)
MsgSuccess('修改成功') MsgSuccess(t('common.modifySuccess'))
}) })
} else { } else {
MsgError('问题不能为空!') MsgError(t('views.problem.tip.errorMessage'))
} }
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<el-dialog <el-dialog
title="关联分段" :title="$t('views.problem.relateParagraph.title')"
v-model="dialogVisible" v-model="dialogVisible"
width="80%" width="80%"
class="paragraph-dialog" class="paragraph-dialog"
@ -11,11 +11,13 @@
<el-row v-loading="loading"> <el-row v-loading="loading">
<el-col :span="6"> <el-col :span="6">
<el-scrollbar height="500" wrap-class="paragraph-scrollbar"> <el-scrollbar height="500" wrap-class="paragraph-scrollbar">
<div class="bold title align-center p-24 pb-0">选择文档</div> <div class="bold title align-center p-24 pb-0">
{{ $t('views.problem.relateParagraph.selectDocument') }}
</div>
<div class="p-8" style="padding-bottom: 8px"> <div class="p-8" style="padding-bottom: 8px">
<el-input <el-input
v-model="filterDoc" v-model="filterDoc"
placeholder="按 文档名称 搜索" :placeholder="$t('views.problem.relateParagraph.placeholder')"
prefix-icon="Search" prefix-icon="Search"
clearable clearable
/> />
@ -47,8 +49,13 @@
<div class="p-24" style="padding-bottom: 8px; padding-top: 16px"> <div class="p-24" style="padding-bottom: 8px; padding-top: 16px">
<div class="flex-between mb-16"> <div class="flex-between mb-16">
<div class="bold title align-center"> <div class="bold title align-center">
选择分段 {{ $t('views.problem.relateParagraph.selectParagraph') }}
<el-text> 已选分段{{ associationCount(currentDocument) }} </el-text> <el-text>
{{ $t('views.problem.relateParagraph.selectedParagraph') }}{{
associationCount(currentDocument)
}}
{{ $t('views.problem.relateParagraph.count') }}
</el-text>
</div> </div>
<el-input <el-input
v-model="search" v-model="search"
@ -59,13 +66,13 @@
> >
<template #prepend> <template #prepend>
<el-select v-model="searchType" placeholder="Select" style="width: 80px"> <el-select v-model="searchType" placeholder="Select" style="width: 80px">
<el-option label="标题" value="title" /> <el-option :label="$t('views.paragraph.searchBar.title')" value="title" />
<el-option label="内容" value="content" /> <el-option :label="$t('views.paragraph.searchBar.content')" value="content" />
</el-select> </el-select>
</template> </template>
</el-input> </el-input>
</div> </div>
<el-empty v-if="paragraphList.length == 0" description="暂无数据" /> <el-empty v-if="paragraphList.length == 0" :description="$t('common.noData')" />
<InfiniteScroll <InfiniteScroll
v-else v-else
@ -108,7 +115,7 @@ import problemApi from '@/api/problem'
import paragraphApi from '@/api/paragraph' import paragraphApi from '@/api/paragraph'
import useStore from '@/stores' import useStore from '@/stores'
import { MsgSuccess } from '@/utils/message' import { MsgSuccess } from '@/utils/message'
import { t } from '@/locales'
const { problem, document } = useStore() const { problem, document } = useStore()
const route = useRoute() const route = useRoute()
@ -152,7 +159,7 @@ function mulAssociation() {
})) }))
} }
problemApi.postMulAssociationProblem(id, data, loading).then(() => { problemApi.postMulAssociationProblem(id, data, loading).then(() => {
MsgSuccess('批量关联分段成功') MsgSuccess(t('views.problem.relatedSuccess'))
dialogVisible.value = false dialogVisible.value = false
}) })
} }

View File

@ -1,21 +1,21 @@
<template> <template>
<LayoutContainer header="问题"> <LayoutContainer :header="$t('views.problem.title')">
<div class="main-calc-height"> <div class="main-calc-height">
<div class="p-24"> <div class="p-24">
<div class="flex-between"> <div class="flex-between">
<div> <div>
<el-button type="primary" @click="createProblem">创建问题</el-button> <el-button type="primary" @click="createProblem">{{$t('views.problem.createProblem')}}</el-button>
<el-button @click="relateProblem()" :disabled="multipleSelection.length === 0" <el-button @click="relateProblem()" :disabled="multipleSelection.length === 0"
>关联分段</el-button >{{$t('views.problem.relateParagraph.title')}}</el-button
> >
<el-button @click="deleteMulDocument" :disabled="multipleSelection.length === 0" <el-button @click="deleteMulDocument" :disabled="multipleSelection.length === 0"
>批量删除</el-button >{{$t('views.problem.setting.batchDelete')}}</el-button
> >
</div> </div>
<el-input <el-input
v-model="filterText" v-model="filterText"
placeholder="搜索内容" :placeholder="$t('views.problem.searchBar.placeholder')"
prefix-icon="Search" prefix-icon="Search"
class="w-240" class="w-240"
@change="getList" @change="getList"
@ -28,8 +28,8 @@
:data="problemData" :data="problemData"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
quick-create quick-create
quickCreateName="问题" :quickCreateName="$t('views.problem.title')"
quickCreatePlaceholder="快速创建问题" :quickCreatePlaceholder="$t('views.problem.quickCreateProblem')"
:quickCreateMaxlength="256" :quickCreateMaxlength="256"
@sizeChange="handleSizeChange" @sizeChange="handleSizeChange"
@changePage="getList" @changePage="getList"
@ -43,7 +43,7 @@
:row-key="(row: any) => row.id" :row-key="(row: any) => row.id"
> >
<el-table-column type="selection" width="55" :reserve-selection="true" /> <el-table-column type="selection" width="55" :reserve-selection="true" />
<el-table-column prop="content" label="问题" min-width="280"> <el-table-column prop="content" :label="$t('views.problem.title')" min-width="280">
<template #default="{ row }"> <template #default="{ row }">
<ReadWrite <ReadWrite
@change="editName($event, row.id)" @change="editName($event, row.id)"
@ -53,7 +53,7 @@
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="paragraph_count" label="关联分段数" align="right" min-width="100"> <el-table-column prop="paragraph_count" :label="$t('views.problem.table.paragraph_count')" align="right" min-width="100">
<template #default="{ row }"> <template #default="{ row }">
<el-link type="primary" @click.stop="rowClickHandle(row)" v-if="row.paragraph_count"> <el-link type="primary" @click.stop="rowClickHandle(row)" v-if="row.paragraph_count">
{{ row.paragraph_count }} {{ row.paragraph_count }}
@ -68,7 +68,7 @@
{{ datetimeFormat(row.create_time) }} {{ datetimeFormat(row.create_time) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="update_time" label="更新时间" width="170"> <el-table-column prop="update_time" :label="$t('views.problem.table.updateTime')" width="170">
<template #default="{ row }"> <template #default="{ row }">
{{ datetimeFormat(row.update_time) }} {{ datetimeFormat(row.update_time) }}
</template> </template>
@ -77,7 +77,7 @@
<template #default="{ row }"> <template #default="{ row }">
<div> <div>
<span class="mr-4"> <span class="mr-4">
<el-tooltip effect="dark" content="关联分段" placement="top"> <el-tooltip effect="dark" :content="$t('views.problem.relateParagraph.title')" placement="top">
<el-button type="primary" text @click.stop="relateProblem(row)"> <el-button type="primary" text @click.stop="relateProblem(row)">
<el-icon><Connection /></el-icon> <el-icon><Connection /></el-icon>
</el-button> </el-button>
@ -122,7 +122,7 @@ import { datetimeFormat } from '@/utils/time'
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message' import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
import type { Dict } from '@/api/type/common' import type { Dict } from '@/api/type/common'
import useStore from '@/stores' import useStore from '@/stores'
import { t } from '@/locales'
const route = useRoute() const route = useRoute()
const { const {
params: { id } // id params: { id } // id
@ -208,7 +208,7 @@ function deleteMulDocument() {
} }
}) })
problemApi.delMulProblem(id, arr, loading).then(() => { problemApi.delMulProblem(id, arr, loading).then(() => {
MsgSuccess('批量删除成功') MsgSuccess(t('views.document.delete.successMessage'))
multipleTableRef.value?.clearSelection() multipleTableRef.value?.clearSelection()
getList() getList()
}) })
@ -216,8 +216,8 @@ function deleteMulDocument() {
function deleteProblem(row: any) { function deleteProblem(row: any) {
MsgConfirm( MsgConfirm(
`是否删除问题:${row.content} ?`, `${t('views.problem.delete.confirmTitle')} ${row.content} ?`,
`删除问题关联的 ${row.paragraph_count} 个分段会被取消关联,请谨慎操作。`, `${t('views.problem.delete.confirmMessage1')} ${row.paragraph_count} ${t('views.problem.delete.confirmMessage2')}`,
{ {
confirmButtonText: t('common.delete'), confirmButtonText: t('common.delete'),
confirmButtonClass: 'danger' confirmButtonClass: 'danger'
@ -239,10 +239,10 @@ function editName(val: string, problemId: string) {
} }
problemApi.putProblems(id, problemId, obj, loading).then(() => { problemApi.putProblems(id, problemId, obj, loading).then(() => {
getList() getList()
MsgSuccess('修改成功') MsgSuccess(t('common.modifySuccess'))
}) })
} else { } else {
MsgError('问题不能为空!') MsgError(t('views.problem.tip.errorMessage'))
} }
} }

View File

@ -48,7 +48,7 @@
</template> </template>
</div> </div>
<el-text type="info" v-else> 暂无数据 </el-text> <el-text type="info" v-else> {{ $t('common.noData') }} </el-text>
</el-card> </el-card>
<el-form-item label="返回内容" @click.prevent> <el-form-item label="返回内容" @click.prevent>
<template #label> <template #label>

View File

@ -64,7 +64,7 @@
</template> </template>
</div> </div>
<el-text type="info" v-else> 暂无数据 </el-text> <el-text type="info" v-else> {{ $t('common.noData') }} </el-text>
</el-card> </el-card>
<h5 class="lighter mb-8">Python 代码</h5> <h5 class="lighter mb-8">Python 代码</h5>