Files
ebiz-ai-knowledge-manage/src/views/knowledge/detail/index.vue
陈昱达 599280bf84 style(button): 优化按钮样式和尺寸
- 添加中等尺寸按钮的样式
- 移除自定义 render-button 类样式
-统一使用 Element UI 的 size="medium" 属性
-调整按钮的其他样式属性,如字体和对齐方式
2025-04-23 20:40:48 +08:00

684 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class=" render-container">
<div class="clearfix flex align-items-c justify-content-b ">
<img :src="knowledgePng_1" class="header-icon" />
<div class="ml20" style="flex:1">
<div class="flex align-items-c">
<div class="mr20 header" v-if="!editKnowledge">{{ knowledgeName }}</div>
<el-input class="mr20 w400" size="small" v-else v-model="copyKnowledgeName">{{ knowledgeName }}</el-input>
<el-icon class="fs16 el-icon-edit-outline cursor-pointer" @click.native="editKnowledgeName" v-if="!editKnowledge" />
<div v-else>
<el-button type="primary" size="medium" class="render-button" @click="saveKnowledgeName">保存</el-button>
<el-button size="medium" class="render-button" @click="cancelKnowledgeName">取消</el-button>
</div>
<span class="segment-content">{{ segmentedMode | filterSegmentedMode }}</span>
</div>
<p class="mt10 fs14" style="line-height: 20px">描述{{ knowledgeDesc }}</p>
<!-- <p class="mt10 fs14" style="line-height: 20px">分段模式{{ segmentedMode | filterSegmentedMode }}</p>-->
</div>
<div>
<!-- <el-button type="primary" size="medium" class="normal-button" @click="jumpEditKnowledge">修改知识库</el-button>-->
<el-button type="primary" size="medium" icon="el-icon-edit-outline" class="primary-button" @click="jumpEditKnowledge">修改知识库</el-button>
<el-button type="primary" size="medium" icon="el-icon-plus" class="primary-button" @click="jumpAddKnowledge">上传知识</el-button>
</div>
</div>
<div class="mt20 card-body">
<el-empty v-if="!hasList">
<div class="mt20">
<el-button type="primary" size="medium" class="fs14" @click="jumpAddKnowledge">立即添加</el-button>
</div>
</el-empty>
<div class="table-container" v-else>
<div class="flex align-items-c justify-content-b">
<el-form :model="form" label-width="100px" label-position="top" inline>
<el-form-item label="知识文件名称" prop="fileName">
<el-input v-model="form.knowledgeNameLike" size="medium" placeholder="请输入知识文件名称" @keydown.enter.native="search"></el-input>
</el-form-item>
<el-form-item label="知识文件来源" prop="documentSource">
<el-select v-model="form.documentSource" placeholder="请输入知识文件名称" size="medium">
<el-option label="全部" value=""></el-option>
<el-option v-for="item in documentSourceOptions" :label="item.label" :value="item.value" :key="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="上传用户" prop="createdUserLike">
<el-select v-model="form.createdUserLike" placeholder="请输入知识文件名称" disabled size="medium">
<el-option label="暂无用户" value=""></el-option>
</el-select>
</el-form-item>
<el-form-item label="关键字">
<el-input v-model="form.name" placeholder="请输入关键字/敏感词" disabled size="medium"></el-input>
</el-form-item>
<el-form-item label="上传时间" prop="times">
<el-date-picker
size="medium"
style="width:100%"
v-model="form.times"
value-format="yyyy-MM-dd"
start-placeholder="开始时间"
end-placeholder="结束时间"
type="daterange"
></el-date-picker>
</el-form-item>
</el-form>
<div class="mt15">
<el-button size="medium" type="primary" @click="search">查询</el-button>
<el-button size="medium" @click="reset">重置</el-button>
</div>
</div>
<r-table
:columns="columns"
:data="list"
:deletion="false"
:total="total"
@page-change="pageChange"
@current-change="currentChange"
:current-page="page"
:page-size="pageSize"
></r-table>
</div>
</div>
<document-drawer
:visible.sync="drawer"
:descriptions="descriptions"
:document-detail="documentDetail"
:active-segment="activeSegment"
@update:visible="val => (drawer = val)"
/>
<knowledgeForm :visible.sync="drawerForm" :datasetId="$route.query.datasetId" @update:visible="getKnowledgeDetail"></knowledgeForm>
</div>
</template>
<script>
import { datasetDocumentEx, datasetQueryDelete, datasetQuerySegments, datasetsExPages, datasetUpdate, getDatasetById } from '@/api/generatedApi/index'
import { documentSourceOptions, segmentedModeOptionsMap } from '@/assets/js/utils/utilOptions'
import DocumentDrawer from './components/documentDetail/DocumentDrawer.vue'
import knowledgeForm from '@/views/knowledge/detail/components/knowledgeForm.vue'
import knowledgePng_1 from '@/assets/images/konwledge/konwledge-1.png'
export default {
name: 'index',
data() {
return {
knowledgePng_1,
datasetId: this.$route.query.datasetId,
activeName: -1,
drawer: false,
drawerForm: false,
editKnowledge: false,
form: {
knowledgeNameLike: '',
documentSource: '',
createdUserLike: '',
times: ''
},
//知识库名称
knowledgeName: '监管',
copyKnowledgeName: '监管',
knowledgeDesc: '监管',
segmentedMode: '分段模式',
list: [],
page: 1,
pageSize: 10,
total: 0,
hasList: false,
documentSourceOptions,
descriptions: { data: [{ content: '' }] },
activeSegmentTab: 'content',
activeSegments: [0],
activeSegment: 0,
documentDetail: {
splitRules: '',
extractRules: ''
}
}
},
props: {},
watch: {},
components: {
knowledgeForm,
DocumentDrawer
},
methods: {
// 开启编辑 知识库标题
editKnowledgeName() {
this.editKnowledge = true
this.copyKnowledgeName = this.knowledgeName
},
// 保存知识库标题
saveKnowledgeName() {
let { datasetId } = this.$route.query
this.knowledgeName = this.copyKnowledgeName
// 调用update接口
datasetUpdate({
name: this.knowledgeName,
description: this.knowledgeDesc,
segmentedMode: this.segmentedMode,
id: datasetId
}).then(res => {
this.editKnowledge = false
})
},
// 取消保存
cancelKnowledgeName() {
this.editKnowledge = false
},
// 跳转去上传文件
jumpAddKnowledge() {
sessionStorage.removeItem('documentId')
let { datasetId } = this.$route.query
this.$router.push({
path: '/knowledge/detail/create',
query: {
datasetId: datasetId
}
})
},
// 跳转到知识库编辑
jumpEditKnowledge() {
this.drawerForm = true
// let { datasetId } = this.$route.query
// this.$router.push({
// path: '/knowledge/knowledge-create',
// query: {
// datasetId: datasetId
// }
// })
},
/**
* @name 根据id 获取知识内容详情
* @author Chen Yuda
* @created_date 2025/4/9
* @description
**/
getKnowledgeDetail() {
let { datasetId } = this.$route.query
getDatasetById({ id: datasetId }).then(res => {
this.knowledgeName = res.content.content.name
this.knowledgeDesc = res.content.content.description
this.segmentedMode = res.content.content.segmentedMode
})
},
// 查询
search() {
this.page = 1
this.getKnowledgeFiledList()
},
reset() {
this.form = {
fileName: '',
documentSource: '',
createdUserLike: '',
times: []
}
this.getKnowledgeFiledList()
},
//获取知识库文件
getKnowledgeFiledList() {
let { datasetId } = this.$route.query
datasetsExPages({
...this.form,
datasetId,
page: this.page,
pageSize: this.pageSize,
startCreatedDate: this.form.times[0] ? this.form.times[0] + ' 00:00:00' : '',
endCreatedDate: this.form.times[1] ? this.form.times[1] + ' 23:59:59' : ''
}).then(res => {
this.list = res.content.content.list
this.total = res.content.content.total
if (!this.hasList && this.list.length > 0) {
this.hasList = true
}
})
},
pageChange(pageSize) {
this.pageSize = pageSize
this.page = 1
this.getKnowledgeFiledList()
},
currentChange(page) {
this.page = page
this.getKnowledgeFiledList()
},
// 查看文档详情
viewDocumentDetail(row) {
// 调用查询分段信息接口
datasetQuerySegments({ documentId: row.id }).then(res => {
if (res) {
console.log(res.content.content)
this.descriptions = {
...row,
...res.content.content
}
this.drawer = true
// 调用datasetDocumentEx接口获取分词规则和词频规则
this.getDocumentExInfo(row.id)
}
})
},
// 获取文档详细信息(包含分词规则和词频规则)
getDocumentExInfo(documentId) {
datasetDocumentEx({ documentId })
.then(res => {
if (res && res.content && res.content.content) {
const docData = res.content.content
// 提取分词规则和词频规则
this.documentDetail.splitRules = docData.splitRules
this.documentDetail.extractRules = docData.extractRules
}
})
.catch(err => {
console.error('获取文档详情失败', err)
})
},
// 提取规则文本处理可能是JSON字符串的情况
extractRuleText(rule) {
if (!rule) return '暂无规则'
try {
// 尝试解析JSON字符串
if (typeof rule === 'string' && (rule.startsWith('{') || rule.startsWith('['))) {
const parsedRule = JSON.parse(rule)
return JSON.stringify(parsedRule, null, 2)
}
return rule
} catch (e) {
// 如果解析失败,直接返回原始文本
return rule
}
},
// 删除文件
deleteKnowledge(row) {
this.$messageBox(
() => {
datasetQueryDelete({ id: row.id }).then(res => {
if (res) {
this.$message({
type: 'success',
message: '删除成功!'
})
this.page = 1
this.getKnowledgeFiledList()
}
})
},
'是否确认删除当前知识文件?',
'warning'
)
}
},
filters: {
filterSegmentedMode(val) {
switch (val) {
case 0:
return '传统分段模式'
case 1:
return ' Q&A分段模式'
default:
return ''
}
},
filterUseMineru(val) {
let item = segmentedModeOptionsMap.find(item => item.value === String(val))
return item ? item.label : '否'
}
},
created() {},
async mounted() {
this.getKnowledgeDetail()
// 获取知识库文件列表
this.getKnowledgeFiledList()
let documentId = sessionStorage.getItem('documentId')
if (documentId) {
setTimeout(() => {
let row = this.list.filter(item => item.id === documentId)
this.viewDocumentDetail(row[0])
sessionStorage.removeItem('documentId')
}, 1000)
}
},
computed: {
columns(vm) {
return [
{
key: '知识文件名称',
prop: 'knowledgeName',
width: '200px'
},
{
key: '知识文件来源',
prop: 'documentSource',
width: '200px',
render: (h, params) => {
let text = documentSourceOptions.find(item => item.value === String(params.row.documentSource)).label
return h('div', [h('span', text)])
}
},
{
key: '召回次数',
prop: 'hitCount',
render: (h, params) => {
return h('div', !params.row.hitCount ? '0' : params.row.hitCount)
}
},
{
key: '上传用户',
prop: 'createdUser',
render: (h, params) => {
return h('div', !params.row.createdUser ? '-' : params.row.createdUser)
}
},
{
key: '上传时间',
prop: 'createdDate'
},
{
key: '操作',
prop: 'knowledgeDesc',
width: '200px',
isRedraw: true,
render: (h, params) => {
return h('div', [
h('el-button', {
class: 'normal-button',
props: {
type: 'primary',
size: 'mini',
disabled: true,
icon: 'el-icon-edit-outline',
title: '编辑'
},
on: {}
}),
h(
'el-button',
{
class: 'floatSpan',
props: {
type: 'danger',
size: 'mini',
icon: 'el-icon-delete'
},
on: {
click: () => this.deleteKnowledge(params.row)
}
},
'删除'
),
h(
'el-button',
{
class: 'floatSpan',
props: {
type: 'primary',
size: 'mini',
icon: 'el-icon-tickets'
},
on: {
click: () => this.viewDocumentDetail(params.row)
}
},
'查看详情'
)
])
}
}
]
}
}
}
</script>
<style scoped lang="scss">
.ellipsis-title {
// 最多展示一行 省略号展示
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
word-break: break-all;
white-space: nowrap;
//width: 50%;
&:hover {
color: #409eff;
}
}
.drawer-content {
padding: 20px;
display: flex;
flex-direction: column;
}
.file-header {
display: flex;
align-items: center;
margin-bottom: 20px;
.file-icon {
font-size: 36px;
margin-right: 15px;
color: #409eff;
}
.file-info {
h3 {
margin: 0 0 10px 0;
font-size: 18px;
font-weight: bold;
}
}
}
.segment-info {
margin-top: 20px;
padding: 15px;
background: #f5f7fa;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
.segment-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
h4 {
margin: 0;
font-size: 18px;
color: #333;
}
}
.rule-card {
//background: #fff;
//border-radius: 4px;
//padding: 15px;
//box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
.rule-item {
margin-bottom: 12px;
h5 {
display: inline-block;
margin: 0 8px 0 0;
font-weight: bold;
color: #666;
}
&:last-child {
margin-bottom: 0;
}
}
.rule-detail-item {
margin-top: 8px;
padding: 10px;
background: #f9f9f9;
border-radius: 8px;
border: 1px solid #e0e0e0;
margin-right: 10px;
p {
margin: 5px 0;
}
.rule-label {
font-size: 14px;
color: #606266;
margin-bottom: 10px;
}
.rule-value {
font-size: 14px;
color: #606266;
font-weight: 500;
margin-left: 15px;
}
}
}
}
.el-collapse-item__header {
font-weight: bold;
//color: #409eff;
}
.mr10 {
margin-right: 10px;
}
.el-descriptions {
margin-bottom: 20px;
}
.collapse-title {
font-weight: bold;
color: #333;
font-size: 16px;
}
.collapse-content {
margin-top: 10px;
color: #666;
}
.tags {
margin-top: 10px;
}
.el-tag {
margin-right: 5px;
}
.segment-content-container {
margin-top: 20px;
}
.segment-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
h4 {
margin: 0;
font-size: 16px;
}
.segment-summary {
color: #606266;
}
}
.segment-split-view {
display: flex;
}
.segment-list {
//flex: 1;
width: 45%;
margin-right: 10px;
}
.segment-list-item {
cursor: pointer;
margin-bottom: 10px;
padding: 15px 0 10px 15px;
border-radius: 15px;
transition: background-color 0.3s;
font-size: 14px;
&:hover {
background: #f3f5f7;
}
&.active {
background: #f3f5f7;
}
p {
margin: 10px 0;
}
.segment-number {
color: #0a84ff;
}
.segment-keywords {
color: #606266;
}
}
.segment-detail {
width: 55%;
}
.segment-content {
background: #f6f8fa;
border-radius: 4px;
font-family: PingFangSC;
font-size: 12px;
color: #4e5969;
line-height: 17px;
text-align: left;
font-style: normal;
margin-left: 20px;
padding: 2px 5px;
}
.segment-empty {
padding: 10px;
text-align: center;
}
.clearfix {
padding-bottom: 20px;
position: relative;
&:after {
position: absolute;
bottom: 0;
left: 0;
content: '';
width: 100%;
border-bottom: 1px solid #979797;
// 宽度缩小
transform: scaleY(0.2);
}
& .header {
font-family: PingFangSC, PingFang SC;
font-weight: 600;
font-size: 16px;
color: #000000;
text-align: left;
font-style: normal;
}
}
</style>