Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
poc-fe
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
poc
poc-fe
Commits
ed3948ed
Commit
ed3948ed
authored
Mar 11, 2025
by
nick zheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 知识库支持问答知识库
parent
f9bb6cc4
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
2224 additions
and
351 deletions
+2224
-351
knowledge.ts
src/apis/knowledge.ts
+84
-0
knowledge.ts
src/enums/knowledge.ts
+4
-0
en.yaml
src/locales/langs/en.yaml
+21
-4
zh-cn.yaml
src/locales/langs/zh-cn.yaml
+18
-2
zh-hk.yaml
src/locales/langs/zh-hk.yaml
+18
-1
personal-space.ts
src/router/modules/personal-space.ts
+1
-1
utils.ts
src/utils/utils.ts
+7
-0
associated-knowledge-modal.vue
...g/agent-setting/components/associated-knowledge-modal.vue
+4
-2
create-knowledge-modal.vue
.../personal-knowledge/components/create-knowledge-modal.vue
+33
-12
edit-knowledge-modal.vue
...ce/personal-knowledge/components/edit-knowledge-modal.vue
+2
-0
base-knowledge-chunk-detail.vue
...dge-detail/base-knowledge/base-knowledge-chunk-detail.vue
+36
-59
add-knowledge-chunk-modal.vue
...l/base-knowledge/components/add-knowledge-chunk-modal.vue
+1
-1
edit-knowledge-chunk-modal.vue
.../base-knowledge/components/edit-knowledge-chunk-modal.vue
+1
-1
knowledge-chuck-item.vue
...detail/base-knowledge/components/knowledge-chuck-item.vue
+3
-3
columns.tsx
...nal-space/personal-knowledge/knowledge-detail/columns.tsx
+143
-0
knowledge-detail.vue
.../personal-knowledge/knowledge-detail/knowledge-detail.vue
+82
-0
add-qa-knowledge-chunk-modal.vue
.../qa-knowledge/components/add-qa-knowledge-chunk-modal.vue
+148
-0
edit-qa-knowledge-chunk-modal.vue
...qa-knowledge/components/edit-qa-knowledge-chunk-modal.vue
+154
-0
setting-knowledge-chunk-index-modal.vue
...wledge/components/setting-knowledge-chunk-index-modal.vue
+81
-0
qa-knowledge-chunk-detail.vue
...owledge-detail/qa-knowledge/qa-knowledge-chunk-detail.vue
+449
-0
personal-document.vue
...s/personal-space/personal-knowledge/personal-document.vue
+4
-1
types.d.ts
src/views/personal-space/personal-knowledge/types.d.ts
+20
-0
data-setting.vue
...ledge/upload-knowledge/qa-local-document/data-setting.vue
+148
-0
index.vue
...al-knowledge/upload-knowledge/qa-local-document/index.vue
+122
-0
upload-file.vue
...wledge/upload-knowledge/qa-local-document/upload-file.vue
+355
-0
upload-knowledge.vue
.../personal-knowledge/upload-knowledge/upload-knowledge.vue
+6
-2
index.vue
...nowledge/upload-knowledge/upload-local-document/index.vue
+1
-1
upload-file.vue
...ge/upload-knowledge/upload-local-document/upload-file.vue
+1
-0
personal-space.vue
src/views/personal-space/personal-space.vue
+1
-0
stylelint.config.js
stylelint.config.js
+1
-1
locales.d.ts
types/locales.d.ts
+275
-260
No files found.
src/apis/knowledge.ts
View file @
ed3948ed
import
{
request
}
from
'@/utils/request'
import
qs
from
'qs'
/* 知识库部分开始 */
...
...
@@ -164,3 +165,86 @@ export function fetchOpenKnowledgeChunk<T>(payload: { kdId: number; chunkRelatio
return
request
.
post
<
T
>
(
'/knowledgeRest/openKnowledgeChunk.json'
,
payload
)
}
/* 知识库文档部分结束 */
/* 问答知识库文档片段开始 */
/**
* @query kdId 知识库文档Id
* @returns 获取问答知识库分片结构
*/
export
function
fetchQAKnowledgeChunkStruct
<
T
>
(
kdId
:
number
)
{
return
request
.
post
<
T
>
(
`/qAKnowledgeRest/getKnowledgeStruct.json?kdId=
${
kdId
}
`
)
}
/**
* @query query 模糊搜索
* @query kdId 知识库文档Id
* @params payload { page: number, pageSize: number }
* @returns 获取问答知识库分片列表
*/
export
function
fetchQAKnowledgeChunkList
<
T
>
(
query
:
string
,
kdId
:
number
,
payload
:
object
)
{
return
request
.
post
<
T
>
(
`/qAKnowledgeRest/getQAKnowledgeChunks.json?query=
${
query
}
&kdId=
${
kdId
+
''
}
`
,
payload
)
}
/**
* @query kdId 知识库文档Id structId 结构Id structName 结构名称 isIndex 是否开启索引
* @returns 修改问答知识库表结构
*/
export
function
fetchUpdateQAKnowledgeStruct
<
T
>
(
payload
:
object
)
{
return
request
.
post
<
T
>
(
'/qAKnowledgeRest/updateKnowledgeChunk.json'
,
{},
{
params
:
payload
,
paramsSerializer
:
function
(
params
)
{
return
qs
.
stringify
(
params
,
{
arrayFormat
:
'repeat'
})
},
},
)
}
/**
* @params { kdId 知识库文档Id chunkInfos 分片内容 chunkSort 文档顺序 }
* @returns 添加问答知识库分片
*/
export
function
fetchAddQAKnowledgeChunk
<
T
>
(
payload
:
object
)
{
return
request
.
post
<
T
>
(
'/qAKnowledgeRest/addKnowledgeChunk.json'
,
payload
)
}
/**
* @params { kdId 知识库文档Id chunkRelationId 分片Id chunkInfos 分片内容 chunkSort 文档顺序 }
* @returns 编辑问答知识库分片
*/
export
function
fetchEditQAKnowledgeChunk
<
T
>
(
payload
:
object
)
{
return
request
.
post
<
T
>
(
'/qAKnowledgeRest/batchUpdateKnowledgeChunkDoc.json'
,
payload
,
{
timeout
:
15000
,
})
}
/**
* @payload kdId 知识库文档Id chunkRelationId 分片Id
* @returns 删除问答知识库分片
*/
export
function
fetchDeleteQAKnowledgeChunk
<
T
>
(
payload
:
{
kdId
:
number
;
chunkRelationId
:
string
})
{
return
request
.
post
<
T
>
(
'/qAKnowledgeRest/deleteKnowledgeChunk.json'
,
payload
)
}
/**
* @payload kdId 知识库文档Id chunkRelationId 分片Id isOpen 开启状态
* @returns 问答知识库分片开启
*/
export
function
fetchOpenQAKnowledgeChunk
<
T
>
(
payload
:
{
kdId
:
number
;
chunkRelationId
:
string
;
isOpen
:
'Y'
|
'N'
})
{
return
request
.
post
<
T
>
(
'/qAKnowledgeRest/openKnowledgeChunk.json'
,
payload
)
}
/**
* @query kdId 知识库文档Id chunkRelationIds 分片Id数组
* @returns 批量删除问答知识库分片
*/
export
function
fetchBatchDeleteQAKnowledgeChunks
<
T
>
(
kdId
:
number
,
chunkRelationIds
:
string
[])
{
return
request
.
post
<
T
>
(
`/qAKnowledgeRest/batchDeleteKnowledgeChunks.json?kdId=
${
kdId
}
&chunkRelationIds=
${
chunkRelationIds
}
`
,
)
}
/* 知识库文档部分结束 */
src/enums/knowledge.ts
0 → 100644
View file @
ed3948ed
export
enum
KnowledgeTypeIcon
{
Base
=
'https://gsst-poe-sit.gz.bcebos.com/icon/knowledge-Base.svg'
,
QA
=
'https://gsst-poe-sit.gz.bcebos.com/icon/knowledge-QA.svg'
,
}
src/locales/langs/en.yaml
View file @
ed3948ed
...
...
@@ -25,7 +25,7 @@ common_module:
available
:
'
Usable'
studying
:
'
Studying'
config
:
'
Configure'
agent
:
'
A
pply
'
agent
:
'
A
gent
'
knowledge
:
'
Knowledge
base'
custom
:
'
Custom'
char
:
'
Character'
...
...
@@ -34,7 +34,7 @@ common_module:
upload_success_message
:
'
Upload
successfully'
empty_data
:
'
No
data
available'
search_empty_data
:
'
No
related
content
found'
create_agent_btn_text
:
'
Create
a
n
application
'
create_agent_btn_text
:
'
Create
a
gent
'
copy_success_message
:
'
Successful
replication'
delete_success_message
:
'
Successfully
deleted'
save_success_message
:
'
Save
successfully'
...
...
@@ -238,7 +238,7 @@ home_module:
personal_space_module
:
title
:
'
Personal
space'
create_btn_text
:
'
Newly
build
'
create_btn_text
:
'
Create
'
agent_module
:
agent_list_module
:
...
...
@@ -465,9 +465,11 @@ personal_space_module:
knowledge_type_rule
:
'
Please
select
the
data
set
type'
knowledge_name_rule
:
'
Please
enter
a
data
set
name'
knowledge_import_type_rule
:
'
Select
a
data
set
import
method'
knowledge_document_text
_type
:
'
Text
format'
base_knowledge
_type
:
'
Text
format'
import_local_document_knowledge
:
'
Local
document'
import_local_document_knowledge_desc
:
'
Supports
uploading
local
files
in
TXT,
MD,
PDF,
DOC,
DOCX
formats'
QA_knowledge_type
:
'
Q&A
knowledge'
import_QA_local_document_knowledge_desc
:
'
Upload
local
documents
in
xls
and
xlsx
formats,
suitable
for
Q&A
scenarios'
segment
:
'
Segment'
auto_segment
:
'
Automatic
segmentation'
...
...
@@ -489,6 +491,17 @@ personal_space_module:
English_exclamation_mark
:
'
English
exclamation
mark'
ellipsis
:
'
Ellipsis'
index
:
'
Index'
no
:
'
No'
add_QA
:
'
Add
Q&A'
add_QA_data
:
'
Add
Q&A
data'
edit_QA_data
:
'
Edit
Q&A
data'
setting_index_desc
:
'
The
index
is
an
important
key
field
of
the
knowledge
base
search
slice.
Select
at
least
one
field
as
the
index.'
select_at_least_one_field_as_the_index
:
'
Select
at
least
one
field
as
the
index'
setting_index
:
'
Setting
Index'
field_name
:
'
Field
name'
please_enter_the_content
:
'
Please
enter
the
content'
upload_document_module
:
segment_setting
:
'
Segmented
processing'
data_process
:
'
Data
processing'
...
...
@@ -514,6 +527,10 @@ personal_space_module:
segment_overlap_word_proportion_tip
:
'
The
ratio
of
the
"number
of
overlapping
characters"
between
the
current
slice
and
the
previous
slice
to
the
set
"Maximum
length
of
slice".
If
there
are
incomplete
sentences
in
the
overlapping
part,
this
slice
deletes
the
sentence,
the
larger
the
proportion,
the
more
overlapping
characters
in
the
adjacent
slice,
the
smaller
the
proportion,
the
fewer
overlapping
characters,
and
the
maximum
bit
25'
please_input_segment_overlap_word_proportion
:
'
Please
input
segment
overlap
word
proportion'
data_process_tip_message
:
'
Click
confirm
does
not
affect
the
data
processing,
after
processing
can
be
referenced'
upload_QA_limit_tip_message
:
'
Support
XLSX\XLS,
up
to
5
files
can
be
uploaded,
each
file
does
not
exceed
10MB'
upload_QA_suggest_tip_message
:
'
It
is
recommended
to
use
the
"Q&A
Template"
to
upload,
otherwise
the
parsing
will
fail.
Click
below
to
download
the
template'
upload_QA_format_error_message
:
'
Only
xls
and
xlsx
files
can
be
uploaded.
Please
upload
them
again'
download_QA_template
:
'
Download
Q&A
Template'
share_agent_module
:
please
:
'
Please
first'
...
...
src/locales/langs/zh-cn.yaml
View file @
ed3948ed
...
...
@@ -463,9 +463,11 @@ personal_space_module:
knowledge_type_rule
:
'
请选择数据集类型'
knowledge_name_rule
:
'
请输入数据集名称'
knowledge_import_type_rule
:
'
请选择数据集导入方式'
knowledge_document_text
_type
:
'
文本格式'
base_knowledge
_type
:
'
文本格式'
import_local_document_knowledge
:
'
本地文档'
import_local_document_knowledge_desc
:
'
支持上传TXT、MD、PDF、DOC、DOCX格式的本地文件'
QA_knowledge_type
:
'
问答知识库'
import_QA_local_document_knowledge_desc
:
'
支持上传xls,xlsx格式的本地文档,适合问答场景使用'
segment
:
'
分段'
auto_segment
:
'
自动分段'
...
...
@@ -487,6 +489,17 @@ personal_space_module:
English_exclamation_mark
:
'
英文感叹号'
ellipsis
:
'
省略号'
index
:
'
索引'
no
:
'
序列号'
add_QA
:
'
新建问答'
add_QA_data
:
'
添加问答数据'
edit_QA_data
:
'
编辑问答数据'
setting_index_desc
:
'
索引是知识库检索切片的重要关键字段,至少选择1个字段作为索引'
select_at_least_one_field_as_the_index
:
'
至少选择1个字段作为索引'
setting_index
:
'
设置索引'
field_name
:
'
字段名称'
please_enter_the_content
:
'
请输入内容'
upload_document_module
:
segment_setting
:
'
分段处理'
data_process
:
'
数据处理'
...
...
@@ -512,6 +525,10 @@ personal_space_module:
segment_overlap_word_proportion_tip
:
'
当前切片与前后切片的“重叠部分字符数”相较于设置的“切片最大长度”的比例,如果重叠部分存在不完整的句子,则此切片舍去该句,占比越大,相邻切片重叠字符越多,占比越少,重叠字符越少,最大值位25'
please_input_segment_overlap_word_proportion
:
'
请输入分段重叠字数占比'
data_process_tip_message
:
'
点击确认不影响数据处理,处理完毕后可进行引用'
upload_QA_limit_tip_message
:
'
支持XLSX\XLS,最多可上传5个文件,每个文件不超过10MB'
upload_QA_suggest_tip_message
:
'
建议使用【问答模版】上传,否则会解析失败,点击下方下载模版'
upload_QA_format_error_message
:
'
只能上传xls,xlsx格式文件,请重新上传'
download_QA_template
:
'
下载问答模版'
share_agent_module
:
please
:
'
请先'
...
...
@@ -697,4 +714,3 @@ editor_module:
center_align
:
'
居中对齐'
justify_right
:
'
右对齐'
align_both_ends
:
'
两端对齐'
src/locales/langs/zh-hk.yaml
View file @
ed3948ed
...
...
@@ -463,9 +463,11 @@ personal_space_module:
knowledge_type_rule
:
'
請選擇數據集類型'
knowledge_name_rule
:
'
請輸入數據集名稱'
knowledge_import_type_rule
:
'
請選擇數據集導入方式'
knowledge_document_text
_type
:
'
文本格式'
base_knowledge
_type
:
'
文本格式'
import_local_document_knowledge
:
'
本地文檔'
import_local_document_knowledge_desc
:
'
支持上傳TXT、MD、PDF、DOC、DOCX格式的本地文件'
QA_knowledge_type
:
'
問答知識庫'
import_QA_local_document_knowledge_desc
:
'
支持上傳xls,xlsx格式的本地文檔,適合問答場景使用'
segment
:
'
分段'
auto_segment
:
'
自動分段'
...
...
@@ -487,6 +489,17 @@ personal_space_module:
English_exclamation_mark
:
'
英文感嘆號'
ellipsis
:
'
省略號'
index
:
'
索引'
no
:
'
序列號'
add_QA
:
'
新建問答'
add_QA_data
:
'
添加問答數據'
edit_QA_data
:
'
編輯問答數據'
setting_index_desc
:
'
索引是知識庫檢索切片的重要關鍵字段,至少選擇1個字段作為索引'
select_at_least_one_field_as_the_index
:
'
至少選擇1個字段作為索引'
setting_index
:
'
設置索引'
field_name
:
'
字段名稱'
please_enter_the_content
:
'
請輸入內容'
upload_document_module
:
segment_setting
:
'
分段處理'
data_process
:
'
數據處理'
...
...
@@ -512,6 +525,10 @@ personal_space_module:
segment_overlap_word_proportion_tip
:
'
當前切片與前後切片的“重疊部分字符數”相較於設置的“切片最大長度”的比例,如果重疊部分存在不完整的句子,則此切片捨去該句,佔比越大,相鄰切片重疊字符越多,佔比越少,重疊字符越少,最大值位25'
please_input_segment_overlap_word_proportion
:
'
請輸入分段重疊字數佔比'
data_process_tip_message
:
'
點擊確認不影響數據處理,處理完畢後可進行引用'
upload_QA_limit_tip_message
:
'
支持XLSX\XLS,最多可上傳5個文件,每個文件不超過10MB'
upload_QA_suggest_tip_message
:
'
建議使用【問答模版】上傳,否則會解析失敗,點擊下方下載模版'
upload_QA_format_error_message
:
'
只能上傳xls,xlsx格式文件,請重新上傳'
download_QA_template
:
'
下載問答模版'
share_agent_module
:
please
:
'
請先'
...
...
src/router/modules/personal-space.ts
View file @
ed3948ed
...
...
@@ -67,7 +67,7 @@ export default [
title
:
'router_title_module.knowledge_document_detail'
,
belong
:
'PersonalSpace'
,
},
component
:
()
=>
import
(
'@/views/personal-space/personal-knowledge/
document
-detail.vue'
),
component
:
()
=>
import
(
'@/views/personal-space/personal-knowledge/
knowledge-detail/knowledge
-detail.vue'
),
},
{
...
...
src/utils/utils.ts
0 → 100644
View file @
ed3948ed
export
function
downloadFile
(
fileUrl
:
string
,
name
:
string
)
{
const
a
=
document
.
createElement
(
'a'
)
a
.
download
=
name
||
'file'
a
.
href
=
fileUrl
a
.
click
()
a
.
remove
()
}
src/views/personal-space/personal-app-setting/components/agent-config/agent-setting/components/associated-knowledge-modal.vue
View file @
ed3948ed
...
...
@@ -12,6 +12,7 @@ import { formatDateTime } from '@/utils/date-formatter'
import
CreateKnowledgeModal
,
{
KnowledgeFormDataInterface
,
}
from
'@/views/personal-space/personal-knowledge/components/create-knowledge-modal.vue'
import
{
KnowledgeTypeIcon
}
from
'@/enums/knowledge'
interface
Props
{
isShowModal
:
boolean
...
...
@@ -202,7 +203,7 @@ async function handleCreateKnowledgeNextStep(createKnowledgeData: KnowledgeFormD
key-field=
"id"
items-style=
"padding-right: 12px;"
>
<
template
#
default=
"{ item }"
>
<
template
#
default=
"{ item }
: { item: KnowledgeItem }
"
>
<div
:key=
"item.id"
class=
"border-inactive-border-color hover:border-theme-color mb-4.5 flex h-[118px] w-full cursor-pointer items-center gap-4 rounded-[10px] border px-4 py-3.5"
...
...
@@ -211,7 +212,8 @@ async function handleCreateKnowledgeNextStep(createKnowledgeData: KnowledgeFormD
<div
class=
"flex flex-1 flex-col overflow-hidden"
>
<div
class=
"flex flex-1"
>
<div
class=
"mt-[3px] h-9 w-9 flex-shrink-0 bg-[url(https://gsst-poe-sit.gz.bcebos.com/data/20241106/1730873304749.png)] bg-contain"
class=
"mt-[3px] h-9 w-9 flex-shrink-0 bg-contain"
:style=
"
{ backgroundImage: `url(${KnowledgeTypeIcon[item.knowledgeType]})` }"
/>
<div
class=
"ml-3.5 flex flex-col items-start overflow-hidden"
>
...
...
src/views/personal-space/personal-knowledge/components/create-knowledge-modal.vue
View file @
ed3948ed
...
...
@@ -4,6 +4,7 @@ import { FormInst } from 'naive-ui'
import
{
useI18n
}
from
'vue-i18n'
import
{
FileAddition
}
from
'@icon-park/vue-next'
import
CustomModal
from
'@/components/custom-modal/custom-modal.vue'
import
{
KnowledgeTypeIcon
}
from
'@/enums/knowledge'
const
{
t
}
=
useI18n
()
...
...
@@ -30,7 +31,7 @@ const emit = defineEmits<Emits>()
const
createKnowledgeFormRef
=
ref
<
FormInst
|
null
>
(
null
)
const
defaultKnowledgeFormData
=
{
knowledgeType
:
'
text
'
,
knowledgeType
:
'
Base
'
,
knowledgeName
:
''
,
knowledgeDesc
:
''
,
knowledgeImportType
:
'local-document'
,
...
...
@@ -61,9 +62,15 @@ const createKnowledgeFormDataRules = {
const
knowledgeTypeList
=
readonly
([
{
id
:
'KJ7rCkq3HNOk'
,
icon
:
'https://gsst-poe-sit.gz.bcebos.com/data/20241012/1728700558225.png'
,
type
:
'text'
,
name
:
'personal_space_module.knowledge_module.knowledge_document_text_type'
,
icon
:
KnowledgeTypeIcon
.
Base
,
type
:
'Base'
,
name
:
t
(
'personal_space_module.knowledge_module.base_knowledge_type'
),
},
{
id
:
'O7Y9BsSm5J5j'
,
icon
:
KnowledgeTypeIcon
.
QA
,
type
:
'QA'
,
name
:
t
(
'personal_space_module.knowledge_module.QA_knowledge_type'
),
},
])
...
...
@@ -71,12 +78,25 @@ const importKnowledgeFileList = readonly([
{
id
:
'ewwBbe9di5Ym'
,
icon
:
()
=>
h
(
FileAddition
,
{
theme
:
'outline'
,
size
:
'16'
,
fill
:
'#333'
}),
knowledgeType
:
'Base'
,
type
:
'local-document'
,
title
:
t
(
'personal_space_module.knowledge_module.import_local_document_knowledge'
),
desc
:
t
(
'personal_space_module.knowledge_module.import_local_document_knowledge_desc'
),
},
{
id
:
'M8BMXe2tOIlB'
,
icon
:
()
=>
h
(
FileAddition
,
{
theme
:
'outline'
,
size
:
'16'
,
fill
:
'#333'
}),
knowledgeType
:
'QA'
,
type
:
'local-document'
,
title
:
'personal_space_module.knowledge_module.import_local_document_knowledge'
,
desc
:
'personal_space_module.knowledge_module.import_local_document_knowledge_desc'
,
title
:
t
(
'personal_space_module.knowledge_module.import_local_document_knowledge'
)
,
desc
:
t
(
'personal_space_module.knowledge_module.import_QA_local_document_knowledge_desc'
)
,
},
])
const
currentKnowledgeTypeList
=
computed
(()
=>
{
return
importKnowledgeFileList
.
filter
((
item
)
=>
item
.
knowledgeType
===
createKnowledgeFormData
.
value
.
knowledgeType
)
})
const
showModal
=
computed
({
get
()
{
return
props
.
isShowModal
...
...
@@ -133,13 +153,14 @@ function handleNext() {
:key=
"knowledgeTypeItem.id"
:class=
"
createKnowledgeFormData.knowledgeType === knowledgeTypeItem.type
? 'border-theme-color text-theme-color
bg-[#ecedfa]
'
? 'border-theme-color text-theme-color'
: 'text-font-color bg-white'
"
class=
"hover:border-theme-color hover:text-theme-color flex h-[66px] cursor-pointer flex-col items-center justify-center rounded-lg border"
@
click=
"createKnowledgeFormData.knowledgeType = knowledgeTypeItem.type"
>
<img
:src=
"knowledgeTypeItem.icon"
class=
"h-6 w-6"
/>
<span
class=
"mt-2 text-sm leading-[14px]"
>
{{
t
(
knowledgeTypeItem
.
name
)
}}
</span>
<span
class=
"mt-2 text-sm leading-[14px]"
>
{{
knowledgeTypeItem
.
name
}}
</span>
</div>
</div>
</div>
...
...
@@ -169,22 +190,22 @@ function handleNext() {
>
<div
class=
"grid w-full grid-cols-2 gap-2"
>
<div
v-for=
"importKnowledgeFileItem in
importKnowledgeFil
eList"
v-for=
"importKnowledgeFileItem in
currentKnowledgeTyp
eList"
:key=
"importKnowledgeFileItem.id"
class=
"border-inactive-border-color flex h-[64px] flex-col items-start justify-center rounded-lg border bg-[#FAFAFA] px-[14px]"
>
<div
class=
"flex items-center"
>
<component
:is=
"importKnowledgeFileItem.icon()"
/>
<span
class=
"text-font-color ml-1 line-clamp-1"
>
{{
t
(
importKnowledgeFileItem
.
title
)
}}
</span>
<span
class=
"text-font-color ml-1 line-clamp-1"
>
{{
importKnowledgeFileItem
.
title
}}
</span>
</div>
<NPopover
trigger=
"hover"
>
<template
#
trigger
>
<span
class=
"text-gray-font-color mt-1.5 line-clamp-1 text-xs"
>
{{
t
(
importKnowledgeFileItem
.
desc
)
}}
{{
importKnowledgeFileItem
.
desc
}}
</span>
</
template
>
<span>
{{
t(importKnowledgeFileItem.desc)
}}
</span>
<span>
{{
importKnowledgeFileItem.desc
}}
</span>
</NPopover>
</div>
</div>
...
...
src/views/personal-space/personal-knowledge/components/edit-knowledge-modal.vue
View file @
ed3948ed
...
...
@@ -9,6 +9,7 @@ const { t } = useI18n()
export
interface
KnowledgeFormDataInterface
{
knowledgeName
:
string
desc
:
string
knowledgeType
:
'Base'
|
'QA'
}
interface
Props
{
...
...
@@ -28,6 +29,7 @@ const emit = defineEmits<Emits>()
const
defaultKnowledgeFormData
=
{
knowledgeName
:
''
,
desc
:
''
,
knowledgeType
:
'Base'
as
const
,
}
const
knowledgeFormRef
=
ref
<
FormInst
|
null
>
(
null
)
...
...
src/views/personal-space/personal-knowledge/
document
-detail.vue
→
src/views/personal-space/personal-knowledge/
knowledge-detail/base-knowledge/base-knowledge-chunk
-detail.vue
View file @
ed3948ed
<
script
setup
lang=
"ts"
>
import
{
computed
,
onMounted
,
ref
}
from
'vue'
import
{
useRouter
}
from
'vue-router'
import
{
useI18n
}
from
'vue-i18n'
import
{
ScrollbarInst
}
from
'naive-ui'
import
{
Left
,
Search
}
from
'@icon-park/vue-next'
import
{
KnowledgeChunkItem
,
KnowledgeDocumentItem
}
from
'.
/types.d
'
import
{
KnowledgeChunkItem
,
KnowledgeDocumentItem
}
from
'.
./../types
'
import
KnowledgeChuckItem
from
'./components/knowledge-chuck-item.vue'
import
{
fetchAddKnowledgeChunk
,
fetchDeleteKnowledgeChunk
,
fetchGetKnowledgeChunkList
,
fetchGetKnowledgeDocumentListByKdIds
,
fetchOpenKnowledgeChunk
,
fetchUpdateKnowledgeChunk
,
}
from
'@/apis/knowledge'
...
...
@@ -19,16 +17,20 @@ import { usePagination } from '@/composables/usePagination.ts'
import
EditKnowledgeChunkModal
from
'./components/edit-knowledge-chunk-modal.vue'
import
AddKnowledgeChunkModal
from
'./components/add-knowledge-chunk-modal.vue'
const
{
t
}
=
useI18n
()
interface
Props
{
kdId
:
number
knowledgeDocument
:
Pick
<
KnowledgeDocumentItem
,
'documentUrl'
|
'documentName'
|
'segmentationConfig'
>
}
const
router
=
useRouter
()
const
props
=
defineProps
<
Props
>
()
const
{
paginationData
}
=
usePagination
()
const
emit
=
defineEmits
<
{
backList
:
[]
}
>
()
const
{
t
}
=
useI18n
()
const
currentKdId
=
ref
(
0
)
const
currentKnowledgeDocumentName
=
ref
(
''
)
const
currentKnowledgeDocumentUrl
=
ref
(
''
)
const
currentKnowledgeSegmentationType
=
ref
(
''
)
const
{
paginationData
}
=
usePagination
()
const
scrollBarRef
=
ref
<
ScrollbarInst
|
null
>
(
null
)
...
...
@@ -63,38 +65,15 @@ const emptyKnowledgeChunkListText = computed(() => {
})
onMounted
(
async
()
=>
{
if
(
!
router
.
currentRoute
.
value
.
params
.
kdId
)
{
window
.
$message
.
warning
(
t
(
'personal_space_module.knowledge_module.not_find_knowledge_document_message'
))
router
.
replace
({
name
:
'PersonalSpaceKnowledge'
})
return
}
currentKdId
.
value
=
Number
(
router
.
currentRoute
.
value
.
params
.
kdId
)
await
handleGetKnowledgeDocumentDetail
()
await
handleGetKnowledgeChunkList
()
props
.
kdId
&&
(
await
handleGetKnowledgeChunkList
())
})
function
handleGetKnowledgeDocumentDetail
()
{
fetchGetKnowledgeDocumentListByKdIds
<
KnowledgeDocumentItem
[]
>
([
currentKdId
.
value
])
.
then
((
res
)
=>
{
if
(
res
.
code
===
0
)
{
currentKnowledgeDocumentName
.
value
=
res
.
data
[
0
].
documentName
currentKnowledgeDocumentUrl
.
value
=
res
.
data
[
0
].
documentUrl
currentKnowledgeSegmentationType
.
value
=
res
.
data
[
0
]?.
segmentationConfig
?.
segmentationType
}
})
.
catch
(()
=>
{
window
.
$message
.
warning
(
t
(
'personal_space_module.knowledge_module.not_find_knowledge_document_message'
))
router
.
replace
({
name
:
'PersonalSpaceKnowledge'
})
})
}
async
function
handleGetKnowledgeChunkList
()
{
knowledgeChunkListLoading
.
value
=
true
const
res
=
await
fetchGetKnowledgeChunkList
<
{
totalChunk
:
number
;
chunkInfos
:
KnowledgeChunkItem
[]
}
>
(
searchKnowledgeChunkValue
.
value
,
currentKdId
.
value
,
props
.
kdId
,
{
pagingInfo
:
paginationData
,
},
...
...
@@ -111,7 +90,7 @@ async function handleGetKnowledgeChunkList() {
}
function
handleBackKnowledgeDocumentList
()
{
router
.
replace
({
name
:
'KnowledgeDocument'
,
params
:
{
id
:
router
.
currentRoute
.
value
.
params
.
id
}
}
)
emit
(
'backList'
)
}
async
function
handleSearchKnowledgeChunkList
()
{
...
...
@@ -129,7 +108,7 @@ async function handleUpdateKnowledgeChunk(chunkRelationId: string, chunkContent:
updateKnowledgeChunkBtnLoading
.
value
=
true
const
res
=
await
fetchUpdateKnowledgeChunk
({
kdId
:
currentKdId
.
value
,
kdId
:
props
.
kdId
,
chunkRelationId
,
chunkContent
,
}).
finally
(()
=>
(
updateKnowledgeChunkBtnLoading
.
value
=
false
))
...
...
@@ -155,7 +134,7 @@ async function handleAddKnowledgeChunk(chunkContent: string, chunkSort: number)
addKnowledgeChunkBtnLoading
.
value
=
true
const
res
=
await
fetchAddKnowledgeChunk
({
kdId
:
currentKdId
.
value
,
kdId
:
props
.
kdId
,
chunkContent
,
chunkSort
,
}).
finally
(()
=>
{
...
...
@@ -174,7 +153,7 @@ async function handleDeleteKnowledgeChunk(chunkRelationId: string) {
.
ctWarning
(
''
,
t
(
'personal_space_module.knowledge_module.delete_knowledge_chunk_content_message'
))
.
then
(
async
()
=>
{
const
res
=
await
fetchDeleteKnowledgeChunk
({
kdId
:
currentKdId
.
value
,
kdId
:
props
.
kdId
,
chunkRelationId
,
})
...
...
@@ -191,7 +170,7 @@ async function handleUpdateOpenKnowledgeChunk(chunkItem: KnowledgeChunkItem) {
const
res
=
await
fetchOpenKnowledgeChunk
({
chunkRelationId
,
isOpen
:
isOpen
===
'Y'
?
'N'
:
'Y'
,
kdId
:
currentKdId
.
value
,
kdId
:
props
.
kdId
,
})
if
(
res
.
code
===
0
)
{
...
...
@@ -214,31 +193,29 @@ async function handleGetKnowledgeChunkListUpdatePageSize(pageSize: number) {
</
script
>
<
template
>
<div
class=
"flex h-full flex-col overflow-hidden"
>
<div
class=
"m
y-6
"
>
<div
class=
"flex h-full
w-full
flex-col overflow-hidden"
>
<div
class=
"m
b-4.5 gap-4.5 mt-6 flex items-center
"
>
<div
class=
"flex h-9 items-center"
>
<Left
theme=
"outline"
size=
"20"
fill=
"#333"
class=
"cursor-pointer"
@
click=
"handleBackKnowledgeDocumentList"
/>
<img
:src=
"documentIcon(
currentKnowledgeD
ocumentUrl)"
class=
"ml-[2px] h-9 w-9"
/>
<img
:src=
"documentIcon(
knowledgeDocument.d
ocumentUrl)"
class=
"ml-[2px] h-9 w-9"
/>
<span
class=
"text-font-color ml-[5px] line-clamp-1 select-none break-all text-lg"
>
{{
currentKnowledgeD
ocumentName
}}
{{
knowledgeDocument
.
d
ocumentName
}}
</span>
</div>
<div
class=
"ml-[66px] mt-1"
>
<ul
class=
"flex gap-2"
>
<li
class=
"border-inactive-border-color select-none rounded-full border px-4 py-1 leading-[18px]"
>
{{
totalChunk
}}
{{
t
(
'personal_space_module.knowledge_module.segment'
)
}}
</li>
<li
class=
"border-inactive-border-color select-none rounded-full border px-4 py-1 leading-[18px]"
>
{{
currentKnowledgeSegmentationType
===
'DEFAULT'
?
t
(
'personal_space_module.knowledge_module.auto_segment'
)
:
t
(
'personal_space_module.knowledge_module.custom_segment'
)
}}
</li>
</ul>
</div>
<ul
class=
"flex flex-shrink-0 gap-2"
>
<li
class=
"border-inactive-border-color select-none rounded-full border px-4 py-1 leading-[18px]"
>
{{
totalChunk
}}
{{
t
(
'personal_space_module.knowledge_module.segment'
)
}}
</li>
<li
class=
"border-inactive-border-color select-none rounded-full border px-4 py-1 leading-[18px]"
>
{{
knowledgeDocument
.
segmentationConfig
.
segmentationType
===
'DEFAULT'
?
t
(
'personal_space_module.knowledge_module.auto_segment'
)
:
t
(
'personal_space_module.knowledge_module.custom_segment'
)
}}
</li>
</ul>
</div>
<div
class=
"mb-[18px] flex justify-end"
>
...
...
src/views/personal-space/personal-knowledge/components/add-knowledge-chunk-modal.vue
→
src/views/personal-space/personal-knowledge/
knowledge-detail/base-knowledge/
components/add-knowledge-chunk-modal.vue
View file @
ed3948ed
...
...
@@ -3,7 +3,7 @@ import { computed, ref, watch } from 'vue'
import
{
useI18n
}
from
'vue-i18n'
import
{
FormInst
}
from
'naive-ui'
import
CustomModal
from
'@/components/custom-modal/custom-modal.vue'
import
{
KnowledgeChunkItem
}
from
'../
knowledge-type
'
import
{
KnowledgeChunkItem
}
from
'../
../../types
'
interface
Props
{
isShowModal
:
boolean
...
...
src/views/personal-space/personal-knowledge/components/edit-knowledge-chunk-modal.vue
→
src/views/personal-space/personal-knowledge/
knowledge-detail/base-knowledge/
components/edit-knowledge-chunk-modal.vue
View file @
ed3948ed
...
...
@@ -3,7 +3,7 @@ import { computed, ref, watch } from 'vue'
import
{
FormInst
}
from
'naive-ui'
import
{
useI18n
}
from
'vue-i18n'
import
CustomModal
from
'@/components/custom-modal/custom-modal.vue'
import
{
KnowledgeChunkItem
}
from
'../
knowledge-type
'
import
{
KnowledgeChunkItem
}
from
'../
../../types
'
interface
Props
{
isShowModal
:
boolean
...
...
src/views/personal-space/personal-knowledge/components/knowledge-chuck-item.vue
→
src/views/personal-space/personal-knowledge/
knowledge-detail/base-knowledge/
components/knowledge-chuck-item.vue
View file @
ed3948ed
<
script
setup
lang=
"ts"
>
import
{
ref
}
from
'vue'
import
{
useI18n
}
from
'vue-i18n'
import
{
KnowledgeChunkItem
}
from
'../types.d'
import
{
KnowledgeChunkItem
}
from
'../
../../
types.d'
interface
Props
{
chunkItem
:
KnowledgeChunkItem
...
...
@@ -74,11 +74,11 @@ const isShowKnowledgeChunkAction = ref(false)
<span>
{{ t('common_module.data_table_module.delete') }}
</span>
</n-popover>
<n-switch
:value=
"chunkItem.isOpen === 'Y'"
@
update:value=
"emit('updateOpen', chunkItem)"
/>
<n-switch
:value=
"chunkItem.isOpen === 'Y'"
size=
"small"
@
update:value=
"emit('updateOpen', chunkItem)"
/>
</div>
</div>
<div
class=
"text-font-color mt-[14px] whitespace-pre-wrap"
>
<div
class=
"text-font-color mt-[14px] whitespace-pre-wrap
break-all
"
>
{{ chunkItem.chunkContent }}
</div>
</div>
...
...
src/views/personal-space/personal-knowledge/knowledge-detail/columns.tsx
0 → 100644
View file @
ed3948ed
import
{
NEllipsis
,
NPopover
,
NSwitch
}
from
'naive-ui'
import
i18n
from
'@/locales'
import
{
QAKnowledgeChunkContentItem
,
QAKnowledgeChunkKeyItem
}
from
'../types'
const
t
=
i18n
.
global
.
t
export
function
createQAKnowledgeChunkColumn
(
chunkColumnKey
:
QAKnowledgeChunkKeyItem
[],
handleKnowledgeChunkTableAction
:
(
actionType
:
string
,
chunkRelationId
:
string
,
KnowledgeItem
?:
QAKnowledgeChunkContentItem
,
)
=>
void
,
)
{
return
[
{
type
:
'selection'
,
fixed
:
'left'
,
className
:
'qa-knowledge-chunk-selection'
,
},
{
title
:
()
=>
<
span
class=
'font-family-medium'
>
{
t
(
'personal_space_module.knowledge_module.no'
)
}
</
span
>,
key
:
'key'
,
minWidth
:
92
,
className
:
'qa-knowledge-chunk-index'
,
render
:
(
_
:
any
,
index
:
number
)
=>
{
return
`
${
index
+
1
}
`
},
},
...
chunkColumnKey
.
map
((
item
)
=>
{
return
{
title
:
()
=>
{
return
(
<
div
class=
'flex items-center gap-[10px]'
>
<
NEllipsis
class=
'font-family-medium max-w-full'
tooltip=
{
{
width
:
200
}
}
>
{
item
.
structName
}
</
NEllipsis
>
{
item
.
isIndex
===
'Y'
&&
(
<
span
class=
'border-theme-color text-theme-color rounded-theme flex-shrink-0 border px-[11px] py-[2px] text-xs'
>
{
t
(
'personal_space_module.knowledge_module.index'
)
}
</
span
>
)
}
</
div
>
)
},
key
:
item
.
structId
,
align
:
'left'
,
width
:
246
,
className
:
'qa-knowledge-chunk-item'
,
render
(
row
:
QAKnowledgeChunkContentItem
&
{
expanded
:
boolean
})
{
return
(
<
div
class=
{
[
row
.
expanded
?
''
:
'line-clamp-1'
,
'cursor-pointer'
]
}
onClick=
{
()
=>
{
row
.
expanded
=
!
row
.
expanded
}
}
>
{
row
.
chunkInfo
.
find
((
chunkInfo
)
=>
chunkInfo
.
structId
===
item
.
structId
)?.
content
||
'--'
}
</
div
>
)
},
}
}),
{
title
:
''
,
key
:
'action'
,
align
:
''
,
fixed
:
'right'
,
width
:
0
,
render
(
row
:
QAKnowledgeChunkContentItem
)
{
return
(
<
div
class=
'top-4.5 flex-center absolute right-[24px] z-10 gap-[10px]'
>
<
NPopover
v
-
slots=
{
{
trigger
:
()
=>
(
<
i
class=
'iconfont icon-edit-document hover:text-font-color hover:bg-background-color flex h-6 w-6 cursor-pointer items-center justify-center rounded-full text-sm'
onClick=
{
()
=>
{
handleKnowledgeChunkTableAction
(
'edit'
,
row
.
chunkRelationId
,
row
)
}
}
/>
),
}
}
>
<
span
>
{
t
(
'common_module.data_table_module.edit'
)
}
</
span
>
</
NPopover
>
<
NPopover
v
-
slots=
{
{
trigger
:
()
=>
(
<
i
class=
'iconfont icon-add-chunk-up hover:text-font-color hover:bg-background-color flex h-6 w-6 cursor-pointer items-center justify-center rounded-full text-sm'
onClick=
{
()
=>
{
handleKnowledgeChunkTableAction
(
'addUp'
,
row
.
chunkRelationId
,
row
)
}
}
/>
),
}
}
>
<
span
>
{
t
(
'personal_space_module.knowledge_module.add_chunk_up_message'
)
}
</
span
>
</
NPopover
>
<
NPopover
v
-
slots=
{
{
trigger
:
()
=>
(
<
i
class=
'iconfont icon-add-chunk-up hover:text-font-color hover:bg-background-color flex h-6 w-6 rotate-180 cursor-pointer items-center justify-center rounded-full text-sm'
onClick=
{
()
=>
{
handleKnowledgeChunkTableAction
(
'addDown'
,
row
.
chunkRelationId
,
row
)
}
}
/>
),
}
}
>
<
span
>
{
t
(
'personal_space_module.knowledge_module.add_chunk_down_message'
)
}
</
span
>
</
NPopover
>
<
NPopover
v
-
slots=
{
{
trigger
:
()
=>
(
<
i
class=
'iconfont icon-delete hover:text-font-color hover:bg-background-color flex h-6 w-6 cursor-pointer items-center justify-center rounded-full text-sm'
onClick=
{
()
=>
{
handleKnowledgeChunkTableAction
(
'delete'
,
row
.
chunkRelationId
)
}
}
/>
),
}
}
>
<
span
>
{
t
(
'common_module.delete'
)
}
</
span
>
</
NPopover
>
<
NSwitch
value=
{
row
.
isOpen
===
'Y'
}
size=
'small'
onUpdateValue=
{
()
=>
handleKnowledgeChunkTableAction
(
'updateOpen'
,
row
.
chunkRelationId
,
row
)
}
/>
</
div
>
)
},
},
]
}
src/views/personal-space/personal-knowledge/knowledge-detail/knowledge-detail.vue
0 → 100644
View file @
ed3948ed
<
script
setup
lang=
"ts"
>
import
{
onMounted
,
ref
}
from
'vue'
import
{
useRouter
}
from
'vue-router'
import
{
useI18n
}
from
'vue-i18n'
import
{
fetchGetKnowledgeDocumentListByKdIds
}
from
'@/apis/knowledge'
import
{
KnowledgeDocumentItem
}
from
'../types'
import
BaseKnowledgeChunkDetail
from
'./base-knowledge/base-knowledge-chunk-detail.vue'
import
QAKnowledgeChunkDetail
from
'./qa-knowledge/qa-knowledge-chunk-detail.vue'
const
{
t
}
=
useI18n
()
const
router
=
useRouter
()
const
currentKdId
=
ref
(
0
)
const
currentKnowledgeDocument
=
ref
<
Pick
<
KnowledgeDocumentItem
,
'documentUrl'
|
'documentName'
|
'segmentationConfig'
>
>
({
documentName
:
''
,
documentUrl
:
''
,
segmentationConfig
:
{
segmentationType
:
'DEFAULT'
,
chunkSize
:
0
,
scrapSize
:
0
,
repetitionRate
:
0
,
relationInfo
:
[],
regex
:
''
,
punctuations
:
[],
},
})
const
currentKnowledgeType
=
ref
()
onMounted
(
async
()
=>
{
if
(
!
router
.
currentRoute
.
value
.
params
.
kdId
)
{
window
.
$message
.
warning
(
t
(
'personal_space_module.knowledge_module.not_find_knowledge_document_message'
))
router
.
replace
({
name
:
'PersonalSpaceKnowledge'
})
return
}
currentKdId
.
value
=
Number
(
router
.
currentRoute
.
value
.
params
.
kdId
)
await
handleGetKnowledgeDocumentDetail
()
})
function
handleGetKnowledgeDocumentDetail
()
{
fetchGetKnowledgeDocumentListByKdIds
<
KnowledgeDocumentItem
[]
>
([
currentKdId
.
value
])
.
then
((
res
)
=>
{
if
(
res
.
code
===
0
)
{
currentKnowledgeDocument
.
value
=
res
.
data
?.[
0
]
currentKnowledgeType
.
value
=
res
.
data
?.[
0
]?.
knowledgeType
||
'Base'
}
})
.
catch
(()
=>
{
window
.
$message
.
warning
(
t
(
'personal_space_module.knowledge_module.not_find_knowledge_document_message'
))
router
.
replace
({
name
:
'PersonalSpaceKnowledge'
})
})
}
function
handleBackKnowledgeDocumentList
()
{
router
.
replace
({
name
:
'KnowledgeDocument'
,
params
:
{
id
:
router
.
currentRoute
.
value
.
params
.
id
}
})
}
</
script
>
<
template
>
<div
class=
"flex h-full flex-col overflow-hidden"
>
<div
v-if=
"currentKnowledgeType === 'BASE'"
class=
"flex h-full w-full"
>
<BaseKnowledgeChunkDetail
:kd-id=
"currentKdId"
:knowledge-document=
"currentKnowledgeDocument"
@
back-list=
"handleBackKnowledgeDocumentList"
/>
</div>
<div
v-if=
"currentKnowledgeType === 'QA'"
class=
"flex h-full w-full"
>
<QAKnowledgeChunkDetail
:kd-id=
"currentKdId"
:knowledge-document=
"currentKnowledgeDocument"
@
back-list=
"handleBackKnowledgeDocumentList"
/>
</div>
</div>
</
template
>
src/views/personal-space/personal-knowledge/knowledge-detail/qa-knowledge/components/add-qa-knowledge-chunk-modal.vue
0 → 100644
View file @
ed3948ed
<
script
setup
lang=
"ts"
>
import
{
computed
,
ref
,
watch
}
from
'vue'
import
{
FormInst
}
from
'naive-ui'
import
{
useI18n
}
from
'vue-i18n'
import
CustomModal
from
'@/components/custom-modal/custom-modal.vue'
import
{
QAKnowledgeChunkKeyItem
,
QAKnowledgeChunkInfoItem
}
from
'../../../types'
type
QAKnowledgeChunkStructItem
=
QAKnowledgeChunkKeyItem
&
{
content
:
string
}
interface
Props
{
btnLoading
:
boolean
knowledgeChunkKeyList
:
QAKnowledgeChunkKeyItem
[]
}
const
emit
=
defineEmits
<
{
confirm
:
[
chunkStructInfo
:
QAKnowledgeChunkInfoItem
[]]
}
>
()
const
props
=
defineProps
<
Props
>
()
const
{
t
}
=
useI18n
()
const
isShow
=
defineModel
<
boolean
>
(
'isShow'
,
{
required
:
true
})
const
knowledgeChunkFormRef
=
ref
<
FormInst
|
null
>
(
null
)
const
chunkStructList
=
ref
<
QAKnowledgeChunkStructItem
[]
>
([])
const
chunkStructRules
=
{
content
:
{
required
:
true
,
trigger
:
'blur'
,
message
:
t
(
'personal_space_module.knowledge_module.please_enter_the_content'
),
},
}
const
dataTableScrollX
=
computed
(()
=>
{
return
props
.
knowledgeChunkKeyList
.
length
*
215
})
watch
(
()
=>
isShow
.
value
,
(
newVal
)
=>
{
if
(
newVal
)
{
chunkStructList
.
value
=
props
.
knowledgeChunkKeyList
.
map
((
chunkKeyItem
)
=>
{
return
{
...
chunkKeyItem
,
content
:
''
}
})
}
},
)
function
handleAddKnowledgeChunk
()
{
knowledgeChunkFormRef
.
value
?.
validate
((
valid
)
=>
{
if
(
!
valid
)
{
const
newChunkStructInfo
=
chunkStructList
.
value
.
map
((
chunkItem
)
=>
{
const
{
structId
,
content
}
=
chunkItem
return
{
structId
,
content
,
}
})
emit
(
'confirm'
,
newChunkStructInfo
)
}
})
}
</
script
>
<
template
>
<CustomModal
v-model:is-show=
"isShow"
:title=
"t('personal_space_module.knowledge_module.add_QA_data')"
:btn-loading=
"btnLoading"
:width=
"1000"
@
confirm=
"handleAddKnowledgeChunk"
>
<template
#
content
>
<n-scrollbar
x-scrollable
>
<n-form
ref=
"knowledgeChunkFormRef"
:inline=
"true"
:model=
"
{ chunkStructList }"
:rules="chunkStructRules"
:style="{ width: dataTableScrollX + 'px' }"
class="rounded-theme"
>
<n-form-item
v-for=
"(chunkItem, index) in chunkStructList"
:key=
"chunkItem.structId"
class=
"qa-knowledge-chunk-key w-[215px]! box-border border-collapse overflow-hidden border border-r-0 border-[#e5e7eb] first:rounded-l-[10px] last:rounded-r-[10px] last:border-r"
:path=
"`chunkStructList[$
{index}].content`"
:show-require-mark="false"
feedback-class="px-3!"
:rule="chunkItem.isIndex === 'Y' ? chunkStructRules.content : []"
>
<template
#
label
>
<div
class=
"flex h-12 w-full flex-shrink-0 items-center border-b border-[#e5e7eb] bg-[#f7f7fa] px-3"
>
<span
v-show=
"chunkItem.isIndex === 'Y'"
class=
"mr-1 text-base text-[#d03050]"
>
*
</span>
<n-ellipsis
:tooltip=
"
{ width: '200px' }">
{{
chunkItem
.
structName
}}
</n-ellipsis>
<span
v-show=
"chunkItem.isIndex === 'Y'"
class=
"border-theme-color text-theme-color rounded-theme ml-[10px] flex-shrink-0 border px-[11px] py-[2px] text-xs"
>
{{
t
(
'personal_space_module.knowledge_module.index'
)
}}
</span>
</div>
</
template
>
<div
class=
"flex w-full flex-shrink-0 p-0"
>
<n-input
v-model:value=
"chunkItem.content"
type=
"textarea"
:placeholder=
"t('personal_space_module.knowledge_module.please_enter_the_content')"
class=
"chunk-content-input"
:autosize=
"{
minRows: 3,
maxRows: 3,
}"
/>
</div>
</n-form-item>
</n-form>
</n-scrollbar>
</template>
</CustomModal>
</template>
<
style
lang=
"scss"
scoped
>
:deep
(
.qa-knowledge-chunk-key.n-form-item
)
{
flex-shrink
:
0
;
width
:
215px
;
margin-right
:
0
!
important
;
.n-form-item-label__text
{
width
:
100%
;
}
.n-form-item-label
{
padding
:
0
;
}
}
:deep
(
.chunk-content-input.n-input--textarea
)
{
--n-border
:
none
!
important
;
--n-border-focus
:
none
!
important
;
--n-border-hover
:
none
!
important
;
--n-box-shadow-focus
:
none
!
important
;
}
</
style
>
src/views/personal-space/personal-knowledge/knowledge-detail/qa-knowledge/components/edit-qa-knowledge-chunk-modal.vue
0 → 100644
View file @
ed3948ed
<
script
setup
lang=
"ts"
>
import
{
computed
,
ref
,
watch
}
from
'vue'
import
{
FormInst
}
from
'naive-ui'
import
{
useI18n
}
from
'vue-i18n'
import
CustomModal
from
'@/components/custom-modal/custom-modal.vue'
import
{
QAKnowledgeChunkKeyItem
,
QAKnowledgeChunkInfoItem
,
QAKnowledgeChunkContentItem
}
from
'../../../types'
type
QAKnowledgeChunkStructItem
=
QAKnowledgeChunkKeyItem
&
{
content
:
string
}
interface
Props
{
btnLoading
:
boolean
knowledgeChunkKeyList
:
QAKnowledgeChunkKeyItem
[]
currentChunkItem
:
QAKnowledgeChunkContentItem
}
const
emit
=
defineEmits
<
{
confirm
:
[
chunkRelationId
:
string
,
chunkStructInfo
:
QAKnowledgeChunkInfoItem
[]]
}
>
()
const
props
=
defineProps
<
Props
>
()
const
{
t
}
=
useI18n
()
const
isShow
=
defineModel
<
boolean
>
(
'isShow'
,
{
required
:
true
})
const
knowledgeChunkFormRef
=
ref
<
FormInst
|
null
>
(
null
)
const
chunkStructList
=
ref
<
QAKnowledgeChunkStructItem
[]
>
([])
const
chunkStructRules
=
{
content
:
{
required
:
true
,
trigger
:
'blur'
,
message
:
t
(
'personal_space_module.knowledge_module.please_enter_the_content'
),
},
}
const
dataTableScrollX
=
computed
(()
=>
{
return
props
.
knowledgeChunkKeyList
.
length
*
215
})
watch
(
()
=>
isShow
.
value
,
(
newVal
)
=>
{
if
(
newVal
)
{
const
map
=
new
Map
(
props
.
currentChunkItem
.
chunkInfo
.
map
((
chunkInfoItem
)
=>
[
chunkInfoItem
.
structId
,
chunkInfoItem
]),
)
chunkStructList
.
value
=
props
.
knowledgeChunkKeyList
.
map
((
chunkKeyItem
)
=>
({
...
chunkKeyItem
,
content
:
map
.
get
(
chunkKeyItem
.
structId
)?.
content
||
''
,
}))
}
},
)
function
handleAddKnowledgeChunk
()
{
knowledgeChunkFormRef
.
value
?.
validate
((
valid
)
=>
{
if
(
!
valid
)
{
const
newChunkStructInfo
=
chunkStructList
.
value
.
map
((
chunkItem
)
=>
{
const
{
structId
,
content
}
=
chunkItem
return
{
structId
,
content
,
}
})
emit
(
'confirm'
,
props
.
currentChunkItem
.
chunkRelationId
,
newChunkStructInfo
)
}
})
}
</
script
>
<
template
>
<CustomModal
v-model:is-show=
"isShow"
:title=
"t('personal_space_module.knowledge_module.edit_QA_data')"
:btn-loading=
"btnLoading"
:width=
"1000"
@
confirm=
"handleAddKnowledgeChunk"
>
<template
#
content
>
<n-scrollbar
x-scrollable
>
<n-form
ref=
"knowledgeChunkFormRef"
:inline=
"true"
:model=
"
{ chunkStructList }"
:rules="chunkStructRules"
:style="{ width: dataTableScrollX + 'px' }"
class="rounded-theme"
>
<n-form-item
v-for=
"(chunkItem, index) in chunkStructList"
:key=
"chunkItem.structId"
class=
"qa-knowledge-chunk-key w-[215px]! box-border border-collapse overflow-hidden border border-r-0 border-[#e5e7eb] first:rounded-l-[10px] last:rounded-r-[10px] last:border-r"
:path=
"`chunkStructList[$
{index}].content`"
:show-require-mark="false"
feedback-class="px-3!"
:rule="chunkItem.isIndex === 'Y' ? chunkStructRules.content : []"
>
<template
#
label
>
<div
class=
"flex h-12 w-full flex-shrink-0 items-center border-b border-[#e5e7eb] bg-[#f7f7fa] px-3"
>
<span
v-show=
"chunkItem.isIndex === 'Y'"
class=
"mr-1 text-base text-[#d03050]"
>
*
</span>
<n-ellipsis
:tooltip=
"
{ width: '200px' }">
{{
chunkItem
.
structName
}}
</n-ellipsis>
<span
v-show=
"chunkItem.isIndex === 'Y'"
class=
"border-theme-color text-theme-color rounded-theme ml-[10px] flex-shrink-0 border px-[11px] py-[2px] text-xs"
>
{{
t
(
'personal_space_module.knowledge_module.index'
)
}}
</span>
</div>
</
template
>
<div
class=
"flex w-full flex-shrink-0 p-0"
>
<n-input
v-model:value=
"chunkItem.content"
type=
"textarea"
:placeholder=
"t('personal_space_module.knowledge_module.please_enter_the_content')"
class=
"chunk-content-input"
:autosize=
"{
minRows: 3,
maxRows: 3,
}"
/>
</div>
</n-form-item>
</n-form>
</n-scrollbar>
</template>
</CustomModal>
</template>
<
style
lang=
"scss"
scoped
>
:deep
(
.qa-knowledge-chunk-key.n-form-item
)
{
flex-shrink
:
0
;
width
:
215px
;
margin-right
:
0
!
important
;
.n-form-item-label__text
{
width
:
100%
;
}
.n-form-item-label
{
padding
:
0
;
}
}
:deep
(
.chunk-content-input.n-input--textarea
)
{
--n-border
:
none
!
important
;
--n-border-focus
:
none
!
important
;
--n-border-hover
:
none
!
important
;
--n-box-shadow-focus
:
none
!
important
;
}
</
style
>
src/views/personal-space/personal-knowledge/knowledge-detail/qa-knowledge/components/setting-knowledge-chunk-index-modal.vue
0 → 100644
View file @
ed3948ed
<
script
setup
lang=
"ts"
>
import
{
computed
,
h
}
from
'vue'
import
{
NSwitch
}
from
'naive-ui'
import
{
useI18n
}
from
'vue-i18n'
import
CustomModal
from
'@/components/custom-modal/custom-modal.vue'
import
{
QAKnowledgeChunkKeyItem
}
from
'../../../types'
interface
Props
{
kdId
:
number
knowledgeChunkKeyList
:
QAKnowledgeChunkKeyItem
[]
}
const
props
=
defineProps
<
Props
>
()
const
emit
=
defineEmits
<
{
updateKnowledgeChunkIndex
:
[
chunkKeyItem
:
QAKnowledgeChunkKeyItem
]
confirm
:
[]
}
>
()
const
{
t
}
=
useI18n
()
const
isShow
=
defineModel
<
boolean
>
(
'isShow'
,
{
required
:
true
})
const
isHasChunkIndex
=
computed
(()
=>
{
return
props
.
knowledgeChunkKeyList
.
some
((
item
)
=>
item
.
isIndex
===
'Y'
)
})
const
chunkIndexColumns
=
createChunkIndexColumns
()
function
createChunkIndexColumns
()
{
return
[
{
title
:
()
=>
t
(
'personal_space_module.knowledge_module.field_name'
),
key
:
'structName'
,
render
:
(
row
:
QAKnowledgeChunkKeyItem
)
=>
{
return
row
.
structName
||
'-'
},
},
{
title
:
()
=>
t
(
'personal_space_module.knowledge_module.setting_index'
),
key
:
'isIndex'
,
render
:
(
row
:
QAKnowledgeChunkKeyItem
)
=>
{
return
h
(
NSwitch
,
{
value
:
row
.
isIndex
===
'Y'
,
size
:
'small'
,
onUpdateValue
:
()
=>
handleKnowledgeTableAction
(
row
)
},
{},
)
},
},
]
}
function
handleKnowledgeTableAction
(
chunkKeyItem
:
QAKnowledgeChunkKeyItem
)
{
chunkKeyItem
.
isIndex
=
chunkKeyItem
.
isIndex
===
'Y'
?
'N'
:
'Y'
if
(
!
isHasChunkIndex
.
value
)
{
chunkKeyItem
.
isIndex
=
chunkKeyItem
.
isIndex
===
'Y'
?
'N'
:
'Y'
window
.
$message
.
warning
(
t
(
'personal_space_module.knowledge_module.select_at_least_one_field_as_the_index'
))
return
}
emit
(
'updateKnowledgeChunkIndex'
,
chunkKeyItem
)
}
</
script
>
<
template
>
<CustomModal
v-model:is-show=
"isShow"
:title=
"t('personal_space_module.knowledge_module.setting_index')"
:width=
"644"
@
confirm=
"emit('confirm')"
>
<template
#
content
>
<p
class=
"text-gray-font-color mb-2.5"
>
{{
t
(
'personal_space_module.knowledge_module.setting_index_desc'
)
}}
</p>
<n-data-table
:single-line=
"false"
:columns=
"chunkIndexColumns"
:data=
"knowledgeChunkKeyList"
:max-height=
"300"
/>
</
template
>
</CustomModal>
</template>
src/views/personal-space/personal-knowledge/knowledge-detail/qa-knowledge/qa-knowledge-chunk-detail.vue
0 → 100644
View file @
ed3948ed
<
script
lang=
"ts"
setup
>
import
{
computed
,
onMounted
,
ref
}
from
'vue'
import
{
useI18n
}
from
'vue-i18n'
import
{
Left
,
Search
}
from
'@icon-park/vue-next'
import
{
useElementSize
}
from
'@vueuse/core'
import
{
fetchAddQAKnowledgeChunk
,
fetchBatchDeleteQAKnowledgeChunks
,
fetchDeleteQAKnowledgeChunk
,
fetchEditQAKnowledgeChunk
,
fetchOpenQAKnowledgeChunk
,
fetchQAKnowledgeChunkList
,
fetchQAKnowledgeChunkStruct
,
fetchUpdateQAKnowledgeStruct
,
}
from
'@/apis/knowledge'
import
CustomPagination
from
'@/components/custom-pagination/custom-pagination.vue'
import
{
usePagination
}
from
'@/composables/usePagination'
import
{
useUserStore
}
from
'@/store/modules/user'
import
SettingKnowledgeChunkIndexModal
from
'./components/setting-knowledge-chunk-index-modal.vue'
import
AddQAKnowledgeChunkModal
from
'./components/add-qa-knowledge-chunk-modal.vue'
import
EditQAKnowledgeChunkModal
from
'./components/edit-qa-knowledge-chunk-modal.vue'
import
{
createQAKnowledgeChunkColumn
}
from
'../columns'
import
{
KnowledgeDocumentItem
,
QAKnowledgeChunkContentItem
,
QAKnowledgeChunkKeyItem
,
QAKnowledgeChunkInfoItem
,
}
from
'../../types'
interface
Props
{
kdId
:
number
knowledgeDocument
:
Pick
<
KnowledgeDocumentItem
,
'documentUrl'
|
'documentName'
|
'segmentationConfig'
>
}
const
props
=
defineProps
<
Props
>
()
const
emit
=
defineEmits
<
{
backList
:
[]
}
>
()
const
{
t
}
=
useI18n
()
const
userStore
=
useUserStore
()
const
{
paginationData
}
=
usePagination
()
const
knowledgeChunkListContainer
=
ref
<
HTMLDivElement
|
null
>
(
null
)
const
{
height
}
=
useElementSize
(
knowledgeChunkListContainer
)
const
totalChunk
=
ref
(
0
)
// 总分片数
const
currentChunkSort
=
ref
(
0
)
// 当前分片排序
const
showAddKnowledgeChunkModal
=
ref
(
false
)
const
showEditKnowledgeChunkModal
=
ref
(
false
)
const
knowledgeChunkBtnLoading
=
ref
(
false
)
const
showSettingChunkIndexModal
=
ref
(
false
)
const
isSearchEmptyList
=
ref
(
false
)
const
searchKnowledgeChunkValue
=
ref
(
''
)
const
chunkKeyList
=
ref
<
QAKnowledgeChunkKeyItem
[]
>
([])
// QA知识库分片表头列表
const
knowledgeChunkList
=
ref
<
QAKnowledgeChunkContentItem
[]
>
([])
// QA知识库分片内容列表
const
knowledgeChunkColumnTableLoading
=
ref
(
false
)
const
checkedChunkIdList
=
ref
<
string
[]
>
([])
const
currentChunkItem
=
ref
<
QAKnowledgeChunkContentItem
>
({
chunkRelationId
:
''
,
chunkSort
:
0
,
chunkInfo
:
[],
isOpen
:
'Y'
,
})
const
knowledgeChunkColumn
=
computed
(()
=>
{
return
createQAKnowledgeChunkColumn
(
chunkKeyList
.
value
,
handleKnowledgeChunkTableAction
)
})
const
dataTableScrollX
=
computed
(()
=>
{
return
chunkKeyList
.
value
.
length
*
246
+
40
+
92
})
const
tableContentY
=
computed
(()
=>
{
return
height
.
value
-
48
})
const
emptyTableDataText
=
computed
(()
=>
{
return
isSearchEmptyList
.
value
?
t
(
'common_module.search_empty_data'
)
:
t
(
'personal_space_module.knowledge_module.empty_knowledge_document_list'
)
})
const
documentIcon
=
computed
(()
=>
(
documentUrl
:
string
)
=>
{
const
type
=
documentUrl
.
substring
(
documentUrl
.
lastIndexOf
(
'.'
)
+
1
)
return
`https://gsst-poe-sit.gz.bcebos.com/icon/
${
type
}
.svg`
})
const
isDisabledOperateBtn
=
computed
(()
=>
{
return
chunkKeyList
.
value
.
length
<=
0
})
const
isDisabledBatchDelBtn
=
computed
(()
=>
{
return
checkedChunkIdList
.
value
.
length
<=
0
})
onMounted
(
async
()
=>
{
if
(
props
.
kdId
)
{
await
handleGetQAKnowledgeChunkStruct
()
await
handleQAKnowledgeChunkList
()
}
})
function
handleBackKnowledgeDocumentList
()
{
emit
(
'backList'
)
}
// 获取QA知识库分片结构
async
function
handleGetQAKnowledgeChunkStruct
()
{
const
res
=
await
fetchQAKnowledgeChunkStruct
<
{
key
:
QAKnowledgeChunkKeyItem
[]
}
>
(
props
.
kdId
)
if
(
res
.
code
===
0
)
{
chunkKeyList
.
value
=
res
.
data
.
key
||
[]
}
}
// 获取QA知识库分片列表
async
function
handleQAKnowledgeChunkList
()
{
knowledgeChunkColumnTableLoading
.
value
=
true
const
res
=
await
fetchQAKnowledgeChunkList
<
{
chunk
:
QAKnowledgeChunkContentItem
[]
totalChunk
:
number
}
>
(
searchKnowledgeChunkValue
.
value
,
props
.
kdId
,
{
pagingInfo
:
paginationData
,
})
if
(
res
.
code
===
0
)
{
knowledgeChunkColumnTableLoading
.
value
=
false
knowledgeChunkList
.
value
=
res
.
data
.
chunk
||
[]
totalChunk
.
value
=
res
.
data
.
totalChunk
||
0
paginationData
.
totalRows
=
res
.
pagingInfo
?.
totalRows
||
0
paginationData
.
totalPages
=
res
.
pagingInfo
?.
totalPages
||
0
isSearchEmptyList
.
value
=
!!
searchKnowledgeChunkValue
.
value
&&
!
res
.
data
.
chunk
?.
length
}
}
// 搜索QA知识库分片列表
async
function
handleSearchKnowledgeChunkList
()
{
paginationData
.
pageNo
=
1
await
handleQAKnowledgeChunkList
()
}
// 更新分页数获取分片列表
async
function
handleGetKnowledgeChunkListUpdatePageNo
(
pageNo
:
number
)
{
paginationData
.
pageNo
=
pageNo
await
handleQAKnowledgeChunkList
()
}
// 更新分页大小获取分片列表
async
function
handleGetKnowledgeChunkListUpdatePageSize
(
pageSize
:
number
)
{
paginationData
.
pageNo
=
1
paginationData
.
pageSize
=
pageSize
await
handleQAKnowledgeChunkList
()
}
// 更新知识库索引
async
function
handleUpdateKnowledgeChunkIndex
(
chunkKeyItem
:
QAKnowledgeChunkKeyItem
)
{
const
{
structId
,
isIndex
}
=
chunkKeyItem
const
payload
=
{
kdId
:
props
.
kdId
,
structId
,
isIndex
,
}
fetchUpdateQAKnowledgeStruct
(
payload
).
catch
(()
=>
{
chunkKeyItem
.
isIndex
=
chunkKeyItem
.
isIndex
===
'Y'
?
'N'
:
'Y'
})
}
// 关闭设置索引对话框
function
handleCloseSettingChunkIndexModal
()
{
showSettingChunkIndexModal
.
value
=
false
handleGetQAKnowledgeChunkStruct
()
}
// QA知识库分片列表操作
function
handleKnowledgeChunkTableAction
(
actionType
:
string
,
chunkRelationId
:
string
,
chunkContentItem
?:
QAKnowledgeChunkContentItem
,
)
{
switch
(
actionType
)
{
case
'addUp'
:
{
const
chunkSort
=
chunkContentItem
?.
chunkSort
||
0
handleShowAddQAKnowledgeChunk
(
chunkSort
)
break
}
case
'addDown'
:
{
const
chunkSort
=
chunkContentItem
?.
chunkSort
||
0
handleShowAddQAKnowledgeChunk
(
chunkSort
+
1
)
break
}
case
'edit'
:
handleUpdateQAKnowledgeChunk
(
chunkContentItem
!
)
break
case
'delete'
:
handleDeleteQAKnowledgeChunk
(
chunkRelationId
)
break
case
'updateOpen'
:
handleUpdateQAKnowledgeChunkOpen
(
chunkRelationId
,
chunkContentItem
!
)
break
}
}
// 更新选中的分片Id
function
handleUpdateCheckedChunkId
(
chunkIdList
:
string
[])
{
checkedChunkIdList
.
value
=
chunkIdList
}
// 显示新增知识库分片对话框
function
handleShowAddQAKnowledgeChunk
(
chunkSort
:
number
)
{
showAddKnowledgeChunkModal
.
value
=
true
currentChunkSort
.
value
=
chunkSort
}
// 执行添加QA知识库分片
async
function
handleAddQAKnowledgeChunk
(
chunkInfos
:
QAKnowledgeChunkInfoItem
[])
{
knowledgeChunkBtnLoading
.
value
=
true
const
payload
=
{
kdId
:
props
.
kdId
,
chunkInfos
,
chunkSort
:
currentChunkSort
.
value
,
}
const
res
=
await
fetchAddQAKnowledgeChunk
(
payload
).
finally
(()
=>
{
knowledgeChunkBtnLoading
.
value
=
false
})
if
(
res
.
code
===
0
)
{
showAddKnowledgeChunkModal
.
value
=
false
window
.
$message
.
success
(
t
(
'common_module.add_success_message'
))
currentChunkSort
.
value
===
0
&&
(
paginationData
.
pageNo
=
1
)
handleQAKnowledgeChunkList
()
}
}
// 显示编辑知识库分片对话框
function
handleUpdateQAKnowledgeChunk
(
chunkContentItem
:
QAKnowledgeChunkContentItem
)
{
showEditKnowledgeChunkModal
.
value
=
true
currentChunkItem
.
value
=
JSON
.
parse
(
JSON
.
stringify
(
chunkContentItem
||
[]))
}
// 执行编辑知识库分片
async
function
handleEditQAKnowledgeChunk
(
chunkRelationId
:
string
,
chunkInfos
:
QAKnowledgeChunkInfoItem
[])
{
knowledgeChunkBtnLoading
.
value
=
true
const
payload
=
{
kdId
:
props
.
kdId
,
chunkRelationId
,
chunkInfos
,
}
const
res
=
await
fetchEditQAKnowledgeChunk
(
payload
).
finally
(()
=>
{
knowledgeChunkBtnLoading
.
value
=
false
})
if
(
res
.
code
===
0
)
{
showEditKnowledgeChunkModal
.
value
=
false
window
.
$message
.
success
(
t
(
'common_module.edit_success_message'
))
handleQAKnowledgeChunkList
()
}
}
// 删除知识库分片
async
function
handleDeleteQAKnowledgeChunk
(
chunkRelationId
:
string
)
{
window
.
$message
.
ctWarning
(
''
,
t
(
'personal_space_module.knowledge_module.delete_knowledge_chunk_content_message'
))
.
then
(
async
()
=>
{
knowledgeChunkColumnTableLoading
.
value
=
true
const
res
=
await
fetchDeleteQAKnowledgeChunk
({
kdId
:
props
.
kdId
,
chunkRelationId
,
})
if
(
res
.
code
===
0
)
{
window
.
$message
.
success
(
t
(
'common_module.delete_success_message'
))
await
handleQAKnowledgeChunkList
()
}
})
}
// 更新知识库是否开启
function
handleUpdateQAKnowledgeChunkOpen
(
chunkRelationId
:
string
,
chunkContentItem
:
QAKnowledgeChunkContentItem
)
{
chunkContentItem
.
isOpen
=
chunkContentItem
.
isOpen
===
'Y'
?
'N'
:
'Y'
const
payload
=
{
kdId
:
props
.
kdId
,
chunkRelationId
,
isOpen
:
chunkContentItem
.
isOpen
,
}
fetchOpenQAKnowledgeChunk
(
payload
).
catch
(()
=>
{
chunkContentItem
.
isOpen
=
chunkContentItem
.
isOpen
===
'Y'
?
'N'
:
'Y'
})
}
// 批量删除知识库分片
function
handleBatchDeleteKnowledgeChunk
()
{
window
.
$message
.
ctWarning
(
''
,
t
(
'personal_space_module.knowledge_module.delete_knowledge_dialog_content'
))
.
then
(
async
()
=>
{
knowledgeChunkColumnTableLoading
.
value
=
true
const
res
=
await
fetchBatchDeleteQAKnowledgeChunks
(
props
.
kdId
,
checkedChunkIdList
.
value
)
if
(
res
.
code
===
0
)
{
window
.
$message
.
success
(
t
(
'common_module.delete_success_message'
))
await
userStore
.
fetchUpdateEquityInfo
()
await
handleQAKnowledgeChunkList
()
}
})
}
</
script
>
<
template
>
<div
class=
"flex h-full w-full flex-col overflow-hidden"
>
<div
class=
"mb-4.5 gap-4.5 mt-6 flex items-center"
>
<div
class=
"flex h-9 items-center"
>
<Left
theme=
"outline"
size=
"20"
fill=
"#333"
class=
"cursor-pointer"
@
click=
"handleBackKnowledgeDocumentList"
/>
<img
:src=
"documentIcon(knowledgeDocument.documentUrl)"
class=
"ml-[2px] h-9 w-9"
/>
<span
class=
"text-font-color ml-[5px] line-clamp-1 select-none break-all text-lg"
>
{{
knowledgeDocument
.
documentName
}}
</span>
</div>
<ul
class=
"flex flex-shrink-0 gap-2"
>
<li
class=
"border-inactive-border-color select-none rounded-full border px-4 py-1 leading-[18px]"
>
{{
totalChunk
}}
{{
t
(
'personal_space_module.knowledge_module.segment'
)
}}
</li>
</ul>
</div>
<div
class=
"flex-center mb-4.5 justify-between"
>
<div
class=
"flex-center gap-2.5"
>
<n-button
type=
"primary"
:disabled=
"isDisabledOperateBtn"
@
click=
"handleShowAddQAKnowledgeChunk(0)"
>
{{
t
(
'personal_space_module.knowledge_module.add_QA'
)
}}
</n-button>
<n-button
type=
"primary"
:disabled=
"isDisabledOperateBtn"
@
click=
"showSettingChunkIndexModal = true"
>
{{
t
(
'personal_space_module.knowledge_module.setting_index'
)
}}
</n-button>
</div>
<div
class=
"flex-center gap-2.5"
>
<n-input
v-model:value=
"searchKnowledgeChunkValue"
:placeholder=
"t('common_module.search')"
class=
"w-[214px]!"
@
keyup
.
enter=
"handleSearchKnowledgeChunkList"
>
<template
#
suffix
>
<Search
theme=
"outline"
size=
"16"
fill=
"#999"
class=
"cursor-pointer"
@
click=
"handleSearchKnowledgeChunkList"
/>
</
template
>
</n-input>
<n-button
type=
"info"
:disabled=
"isDisabledBatchDelBtn"
@
click=
"handleBatchDeleteKnowledgeChunk"
>
{{ t('personal_space_module.knowledge_module.batch_delete_knowledge_document_btn_text') }}
</n-button>
</div>
</div>
<div
ref=
"knowledgeChunkListContainer"
class=
"w-full flex-1 overflow-hidden rounded-[10px] bg-white p-6"
>
<n-data-table
:loading=
"knowledgeChunkColumnTableLoading"
:columns=
"knowledgeChunkColumn"
:data=
"knowledgeChunkList"
:scroll-x=
"dataTableScrollX"
:max-height=
"tableContentY"
:row-key=
"(row: QAKnowledgeChunkContentItem) => row.chunkRelationId"
:checked-row-keys=
"checkedChunkIdList"
@
update:checked-row-keys=
"handleUpdateCheckedChunkId"
>
<
template
#
empty
>
<div
:style=
"
{ height: tableContentY + 'px' }" class="flex items-center justify-center">
<div
class=
"flex flex-col items-center justify-center"
>
<div
class=
"mb-5 h-[68px] w-[68px]"
:class=
"isSearchEmptyList ? 'bg-px-search_empty_list-png' : 'bg-px-empty_document_list-png'"
/>
<p
class=
"select-none text-[#84868c]"
>
{{
emptyTableDataText
}}
</p>
</div>
</div>
</
template
>
</n-data-table>
</div>
<div
class=
"mt-4 flex justify-end"
>
<CustomPagination
:paging-info=
"paginationData"
@
update-page-no=
"handleGetKnowledgeChunkListUpdatePageNo"
@
update-page-size=
"handleGetKnowledgeChunkListUpdatePageSize"
/>
</div>
<SettingKnowledgeChunkIndexModal
v-model:is-show=
"showSettingChunkIndexModal"
:kd-id=
"kdId"
:knowledge-chunk-key-list=
"chunkKeyList"
@
update-knowledge-chunk-index=
"handleUpdateKnowledgeChunkIndex"
@
confirm=
"handleCloseSettingChunkIndexModal"
/>
<AddQAKnowledgeChunkModal
v-model:is-show=
"showAddKnowledgeChunkModal"
:btn-loading=
"knowledgeChunkBtnLoading"
:knowledge-chunk-key-list=
"chunkKeyList"
@
confirm=
"handleAddQAKnowledgeChunk"
/>
<EditQAKnowledgeChunkModal
v-model:is-show=
"showEditKnowledgeChunkModal"
:btn-loading=
"knowledgeChunkBtnLoading"
:knowledge-chunk-key-list=
"chunkKeyList"
:current-chunk-item=
"currentChunkItem"
@
confirm=
"handleEditQAKnowledgeChunk"
/>
</div>
</template>
<
style
lang=
"scss"
scoped
>
:deep
(
.qa-knowledge-chunk-selection.n-data-table-td
.n-checkbox
)
{
margin-top
:
46px
;
}
:deep
(
.qa-knowledge-chunk-index.n-data-table-td
)
{
padding-top
:
56px
;
}
:deep
(
.qa-knowledge-chunk-item.n-data-table-td
)
{
padding-top
:
56px
;
vertical-align
:
top
;
}
:deep
(
.n-data-table-tr
)
{
position
:
relative
;
}
</
style
>
src/views/personal-space/personal-knowledge/personal-document.vue
View file @
ed3948ed
...
...
@@ -40,6 +40,7 @@ const updateKnowledgeInfoBtnLoading = ref(false)
const
currentKnowledgeData
=
ref
<
KnowledgeFormDataInterface
>
({
knowledgeName
:
''
,
desc
:
''
,
knowledgeType
:
'Base'
,
})
const
isDisabledBatchDelBtn
=
computed
(()
=>
{
...
...
@@ -203,9 +204,11 @@ async function handleBatchDelDocument() {
}
function
handleToUploadDocument
()
{
const
knowledgeType
=
currentKnowledgeData
.
value
.
knowledgeType
||
'Base'
router
.
push
({
name
:
'UploadKnowledge'
,
params
:
{
id
:
router
.
currentRoute
.
value
.
params
.
id
,
type
:
'text-local-document'
},
params
:
{
id
:
router
.
currentRoute
.
value
.
params
.
id
,
type
:
`
${
knowledgeType
}
-local-document`
},
})
}
...
...
src/views/personal-space/personal-knowledge/types.d.ts
View file @
ed3948ed
...
...
@@ -11,6 +11,7 @@ export interface KnowledgeItem {
knowledgeName
:
string
desc
:
string
trainStatus
:
TrainStatus
knowledgeType
:
'Base'
|
'QA'
isOpen
:
'Y'
|
'N'
createdTime
:
Date
documentInfos
:
KnowledgeDocumentItem
[]
...
...
@@ -46,3 +47,22 @@ export interface KnowledgeChunkItem {
chunkSort
:
number
isOpen
:
'Y'
|
'N'
}
export
interface
QAKnowledgeChunkKeyItem
{
structId
:
number
isIndex
:
'Y'
|
'N'
sort
:
number
structName
:
string
}
export
interface
QAKnowledgeChunkContentItem
{
chunkRelationId
:
string
chunkSort
:
number
chunkInfo
:
QAKnowledgeChunkInfoItem
[]
isOpen
:
'Y'
|
'N'
}
export
interface
QAKnowledgeChunkInfoItem
{
structId
:
number
content
:
string
}
src/views/personal-space/personal-knowledge/upload-knowledge/qa-local-document/data-setting.vue
0 → 100644
View file @
ed3948ed
<
script
setup
lang=
"ts"
>
import
{
computed
,
onMounted
,
ref
,
watch
}
from
'vue'
import
{
useI18n
}
from
'vue-i18n'
import
{
useIntervalFn
}
from
'@vueuse/core'
import
{
fetchGetKnowledgeDocumentListByKdIds
}
from
'@/apis/knowledge'
interface
Props
{
kdIds
:
number
[]
}
interface
Emit
{
(
e
:
'confirm'
):
void
}
enum
TrainStatus
{
UNOPENED
=
'Unopened'
,
LINE
=
'Line'
,
TRAINING
=
'Training'
,
COMPLETE
=
'Complete'
,
FAIL
=
'Fail'
,
}
interface
TrainFileItem
{
kdId
:
number
documentName
:
string
documentUrl
:
string
trainStatus
:
TrainStatus
knowledgeId
:
string
documentSize
:
string
}
const
{
t
}
=
useI18n
()
const
props
=
defineProps
<
Props
>
()
const
emit
=
defineEmits
<
Emit
>
()
const
trainFileList
=
ref
<
TrainFileItem
[]
>
([])
onMounted
(()
=>
{
!!
props
.
kdIds
.
length
&&
handleGetKnowledgeDocumentList
()
})
const
trainFileText
=
computed
(()
=>
(
status
:
TrainStatus
)
=>
{
switch
(
status
)
{
case
TrainStatus
.
COMPLETE
:
return
'personal_space_module.knowledge_module.upload_document_module.process_success'
case
TrainStatus
.
FAIL
:
return
'personal_space_module.knowledge_module.upload_document_module.process_fail'
default
:
return
'personal_space_module.knowledge_module.upload_document_module.processed'
}
})
const
trainFileFontColor
=
computed
(()
=>
(
status
:
TrainStatus
)
=>
{
switch
(
status
)
{
case
TrainStatus
.
COMPLETE
:
return
'#0B7DFF'
case
TrainStatus
.
FAIL
:
return
'#F25744'
default
:
return
'#333333'
}
})
const
trainFileIcon
=
computed
(()
=>
(
documentUrl
:
string
)
=>
{
const
type
=
documentUrl
.
substring
(
documentUrl
.
lastIndexOf
(
'.'
)
+
1
)
return
`https://gsst-poe-sit.gz.bcebos.com/icon/
${
type
}
.svg`
})
const
isTrainFileListFinish
=
computed
(()
=>
{
return
trainFileList
.
value
.
every
((
trainFileItem
)
=>
{
return
[
TrainStatus
.
FAIL
,
TrainStatus
.
COMPLETE
].
includes
(
trainFileItem
.
trainStatus
)
})
})
watch
(
()
=>
isTrainFileListFinish
.
value
,
(
newVal
)
=>
{
newVal
?
pauseIntervalFn
()
:
resumeIntervalFn
()
},
{
deep
:
true
},
)
const
{
pause
:
pauseIntervalFn
,
resume
:
resumeIntervalFn
}
=
useIntervalFn
(
async
()
=>
{
handleGetKnowledgeDocumentList
()
},
2000
,
{
immediateCallback
:
false
,
immediate
:
false
},
)
async
function
handleGetKnowledgeDocumentList
()
{
const
res
=
await
fetchGetKnowledgeDocumentListByKdIds
<
TrainFileItem
[]
>
(
props
.
kdIds
)
if
(
res
.
code
===
0
)
{
trainFileList
.
value
=
res
.
data
}
}
function
handleConfirm
()
{
emit
(
'confirm'
)
}
</
script
>
<
template
>
<ul
class=
"grid gap-[18px]"
>
<li
v-for=
"trainFileItem in trainFileList"
:key=
"trainFileItem.kdId"
class=
"border-inactive-border-color relative h-[90px] select-none overflow-hidden rounded-[10px] border bg-white p-6"
>
<div
class=
"flex h-full items-center justify-between"
>
<div
class=
"flex items-center"
>
<img
:src=
"trainFileIcon(trainFileItem.documentUrl)"
class=
"mr-[15px] h-9 w-9"
/>
<div
class=
"flex h-9 flex-col justify-between"
>
<span
class=
"text-font-color line-clamp-1 break-all text-sm leading-[14px]"
>
{{
trainFileItem
.
documentName
}}
</span>
<span
class=
"text-gray-font-color line-clamp-1 break-all text-[13px] leading-[13px]"
>
{{
trainFileItem
.
documentSize
}}
</span>
</div>
</div>
<span
:style=
"
{ color: trainFileFontColor(trainFileItem.trainStatus) }">
{{
t
(
trainFileText
(
trainFileItem
.
trainStatus
))
}}
</span>
</div>
<div
v-show=
"![TrainStatus.COMPLETE, TrainStatus.FAIL].includes(trainFileItem.trainStatus)"
class=
"animate-training absolute left-0 top-[-1px] h-[90px] w-full rounded-[10px] bg-gradient-to-r from-transparent via-[#9EA0FF] to-transparent"
/>
</li>
</ul>
<div
class=
"mt-14 flex items-center justify-end"
>
<span
class=
"text-gray-font-color mr-2.5 select-none text-xs"
>
{{
t
(
'personal_space_module.knowledge_module.upload_document_module.data_process_tip_message'
)
}}
</span>
<NButton
type=
"primary"
:bordered=
"false"
@
click=
"handleConfirm"
>
{{
t
(
'common_module.confirm_btn_text'
)
}}
</NButton>
</div>
</
template
>
src/views/personal-space/personal-knowledge/upload-knowledge/qa-local-document/index.vue
0 → 100644
View file @
ed3948ed
<
script
lang=
"ts"
setup
>
import
{
onMounted
,
ref
}
from
'vue'
import
{
useI18n
}
from
'vue-i18n'
import
{
useRouter
}
from
'vue-router'
import
UploadFile
from
'./upload-file.vue'
import
DataSetting
from
'./data-setting.vue'
import
{
fetchTrainKnowledge
}
from
'@/apis/knowledge'
interface
StepItem
{
stepId
:
number
title
:
string
}
const
{
t
}
=
useI18n
()
const
router
=
useRouter
()
const
stepList
=
ref
<
StepItem
[]
>
([
{
stepId
:
1
,
title
:
t
(
'common_module.upload'
),
},
{
stepId
:
2
,
title
:
t
(
'personal_space_module.knowledge_module.upload_document_module.data_process'
),
},
])
const
currentStepId
=
ref
(
1
)
const
currentKdIdList
=
ref
<
number
[]
>
([])
const
currentKnowledgeId
=
ref
(
0
)
onMounted
(()
=>
{
if
(
!
router
.
currentRoute
.
value
.
params
.
id
)
{
window
.
$message
.
warning
(
t
(
'personal_space_module.knowledge_module.not_find_knowledge_message'
))
router
.
replace
({
name
:
'PersonalSpaceKnowledge'
})
return
}
currentKnowledgeId
.
value
=
Number
(
router
.
currentRoute
.
value
.
params
.
id
)
})
async
function
handleToDataProcess
(
kdId
:
number
[])
{
currentKdIdList
.
value
=
kdId
const
res
=
await
fetchTrainKnowledge
({
knowledgeInfoId
:
currentKnowledgeId
.
value
,
kdIds
:
currentKdIdList
.
value
,
segmentationConfig
:
{},
})
if
(
res
.
code
===
0
)
{
currentStepId
.
value
=
2
}
}
function
handleToKnowledgeList
()
{
router
.
replace
({
name
:
'KnowledgeDocument'
,
params
:
{
id
:
currentKnowledgeId
.
value
}
})
}
</
script
>
<
template
>
<div
class=
"flex flex-1 flex-col overflow-hidden"
>
<ul
class=
"mx-auto my-10 flex w-[870px] shrink-0 duration-500 ease-in"
>
<li
v-for=
"(stepItem, index) in stepList"
:key=
"stepItem.stepId"
class=
"relative flex flex-1 shrink-0 flex-col items-center justify-center"
>
<div
v-show=
"stepItem.stepId !== 1"
class=
"absolute left-0 top-[24px] w-[calc((100%-48px)/2)] border-t"
:class=
"[currentStepId >= stepItem.stepId ? 'border-[#9EA3FF]' : 'border-inactive-border-color']"
/>
<div
class=
"flex flex-col items-center justify-center"
>
<div
class=
"relative mb-3 flex h-12 w-12 items-center justify-center rounded-full border text-lg"
:class=
"
{
'border-[#6F77FF] bg-[#6F77FF]': stepItem.stepId === currentStepId,
'border-inactive-border-color text-gray-font-color': stepItem.stepId > currentStepId,
'bg-[#9ea3ff]': stepItem.stepId
<
currentStepId
,
}"
>
<span
v-show=
"currentStepId
<
=
stepItem
.
stepId
"
class=
"select-none text-xl"
:class=
"stepItem.stepId === currentStepId ? 'text-white' : 'text-gray-font-color'"
>
{{
index
+
1
}}
</span>
<Check
v-show=
"currentStepId > stepItem.stepId"
theme=
"outline"
size=
"24"
fill=
"#fff"
:stroke-width=
"3"
/>
</div>
<span
class=
"text-base"
:class=
"[currentStepId === stepItem.stepId ? 'text-theme-color' : 'text-gray-font-color']"
>
{{
stepItem
.
title
}}
</span>
</div>
<div
v-show=
"index
<
stepList
.
length
-
1
"
class=
"absolute right-0 top-[24px] w-[calc((100%-48px)/2)] border-t"
:class=
"[currentStepId > stepItem.stepId ? 'border-[#9EA3FF]' : 'border-inactive-border-color']"
/>
</li>
</ul>
<div
class=
"mx-10 flex-1 overflow-hidden"
>
<NScrollbar
class=
"max-h-full! px-10"
>
<div
v-show=
"currentStepId === 1"
>
<UploadFile
@
next=
"handleToDataProcess"
/>
</div>
<div
v-if=
"currentStepId === 2"
>
<DataSetting
:kd-ids=
"currentKdIdList"
@
confirm=
"handleToKnowledgeList"
/>
</div>
</NScrollbar>
</div>
</div>
</
template
>
src/views/personal-space/personal-knowledge/upload-knowledge/qa-local-document/upload-file.vue
0 → 100644
View file @
ed3948ed
<
script
setup
lang=
"ts"
>
import
{
computed
,
onMounted
,
ref
}
from
'vue'
import
{
UploadFileInfo
}
from
'naive-ui'
import
{
useI18n
}
from
'vue-i18n'
import
{
useRouter
}
from
'vue-router'
import
{
UploadOne
}
from
'@icon-park/vue-next'
import
{
fetchUploadKnowledgeDocument
}
from
'@/apis/knowledge'
import
{
useUserStore
}
from
'@/store/modules/user'
import
{
downloadFile
}
from
'@/utils/utils'
interface
Emit
{
(
e
:
'next'
,
value
:
number
[]):
void
}
enum
FileItemStatus
{
PENDING
=
'pending'
,
UPLOADING
=
'uploading'
,
FINISHED
=
'finished'
,
REMOVED
=
'removed'
,
ERROR
=
'error'
,
}
interface
FileItem
{
id
:
string
name
:
string
size
:
number
status
:
FileItemStatus
kdId
:
number
type
?:
string
}
const
{
t
}
=
useI18n
()
const
router
=
useRouter
()
const
userStore
=
useUserStore
()
const
emit
=
defineEmits
<
Emit
>
()
const
uploadFileList
=
ref
<
FileItem
[]
>
([])
const
isExceedKnowledgeCount
=
ref
(
false
)
const
uploadFileIcon
=
(
type
:
string
)
=>
{
return
`https://gsst-poe-sit.gz.bcebos.com/icon/
${
type
}
.svg`
}
const
isDisabledNextBtn
=
computed
(()
=>
{
return
(
uploadFileList
.
value
.
length
>
0
&&
uploadFileList
.
value
.
every
((
item
)
=>
item
.
status
===
FileItemStatus
.
FINISHED
)
)
})
const
uploadFileSize
=
computed
(()
=>
(
fileSize
:
number
)
=>
{
if
(
fileSize
==
0
)
return
'0B'
const
binarySize
=
1024
const
sizes
=
[
'B'
,
'KB'
,
'MB'
,
'GB'
,
'TB'
]
const
unit
=
Math
.
floor
(
Math
.
log
(
fileSize
)
/
Math
.
log
(
binarySize
))
return
(
fileSize
/
Math
.
pow
(
binarySize
,
unit
)).
toPrecision
(
3
)
+
' '
+
sizes
[
unit
]
})
onMounted
(
async
()
=>
{
await
handleGetEquityInfo
()
})
async
function
handleGetEquityInfo
()
{
await
userStore
.
fetchUpdateEquityInfo
()
}
// 上传文件前限制
function
handleLimitUpload
(
data
:
{
file
:
UploadFileInfo
;
fileList
:
UploadFileInfo
[]
})
{
// 上传数量达到上限
if
(
isExceedKnowledgeCount
.
value
)
{
return
false
}
// 获取文件上传时多选的个数
let
uploadKnowledgeCount
=
0
const
knowledgeFileList
=
document
.
getElementsByClassName
(
'upload-knowledge-file'
)
if
(
knowledgeFileList
&&
knowledgeFileList
.
length
>
0
)
{
const
knowledgeFile
=
knowledgeFileList
[
0
].
getElementsByTagName
(
'input'
)
if
(
knowledgeFile
&&
knowledgeFile
.
length
>
0
&&
knowledgeFile
[
0
].
files
&&
knowledgeFile
[
0
].
files
.
length
>
0
)
{
uploadKnowledgeCount
=
knowledgeFile
[
0
].
files
.
length
}
}
const
enableKnowledgeCount
=
Math
.
max
(
0
,
userStore
.
equityInfo
.
maxKnowledgeCount
-
userStore
.
equityInfo
.
usedKnowledgeCount
-
uploadFileList
.
value
.
length
,
)
if
(
userStore
.
equityInfo
.
maxKnowledgeCount
!==
0
&&
enableKnowledgeCount
<
uploadKnowledgeCount
)
{
isExceedKnowledgeCount
.
value
=
true
window
.
$message
.
ctWarning
(
t
(
'equity_module.documents_uploaded_exceeds_tip'
,
{
count
:
enableKnowledgeCount
}),
''
)
.
then
(()
=>
{
router
.
push
({
name
:
'Equity'
})
})
.
catch
(()
=>
{})
return
false
}
const
allowTypeList
=
[
'xls'
,
'xlsx'
]
const
fileType
=
(
data
.
file
.
file
&&
data
.
file
.
file
?.
name
.
split
(
'.'
)?.
pop
()?.
toLowerCase
())
||
''
if
(
data
.
file
.
file
&&
!
allowTypeList
.
includes
(
fileType
))
{
window
.
$message
.
error
(
t
(
'personal_space_module.knowledge_module.upload_document_module.upload_QA_format_error_message'
),
)
return
false
}
if
(
data
.
file
.
file
&&
data
.
file
.
file
?.
size
===
0
)
{
window
.
$message
.
error
(
t
(
'personal_space_module.knowledge_module.upload_document_module.empty_document_content_message'
),
)
const
fileData
=
{
id
:
data
.
file
.
id
,
name
:
data
.
file
.
name
,
status
:
FileItemStatus
.
ERROR
,
size
:
data
.
file
.
file
?.
size
||
0
,
type
:
fileType
,
kdId
:
0
,
}
uploadFileList
.
value
.
push
(
fileData
)
return
false
}
if
(
data
.
file
.
file
&&
data
.
file
.
file
?.
size
>
10
*
1024
*
1024
)
{
window
.
$message
.
error
(
t
(
'personal_space_module.knowledge_module.upload_document_module.upload_size_error_message'
))
const
fileData
=
{
id
:
data
.
file
.
id
,
name
:
data
.
file
.
name
,
status
:
FileItemStatus
.
ERROR
,
size
:
data
.
file
.
file
?.
size
||
0
,
type
:
fileType
,
kdId
:
0
,
}
uploadFileList
.
value
.
push
(
fileData
)
return
false
}
return
true
}
// 上传文件
async
function
handleUpload
(
file
:
any
)
{
const
formData
=
new
FormData
()
formData
.
append
(
'documentFiles'
,
file
.
file
.
file
)
formData
.
append
(
'knowledgeType'
,
'QA'
)
const
fileData
=
{
id
:
file
.
file
.
id
,
name
:
file
.
file
.
name
,
status
:
FileItemStatus
.
UPLOADING
,
size
:
file
.
file
?.
file
?.
size
||
0
,
type
:
file
.
file
?.
name
.
split
(
'.'
)?.
pop
()?.
toLowerCase
(),
kdId
:
0
,
}
if
(
uploadFileList
.
value
.
length
<
5
)
{
await
uploadFileList
.
value
.
push
(
fileData
)
fetchUploadKnowledgeDocument
<
{
kdId
:
number
}[]
>
(
formData
)
.
then
((
res
)
=>
{
if
(
res
.
code
===
0
)
{
uploadFileList
.
value
.
forEach
((
fileItem
)
=>
{
if
(
fileItem
.
id
===
file
.
file
.
id
)
{
fileItem
.
status
=
FileItemStatus
.
FINISHED
fileItem
.
kdId
=
res
.
data
?.[
0
]?.
kdId
}
})
}
})
.
catch
(()
=>
{
uploadFileList
.
value
.
forEach
((
fileItem
)
=>
{
if
(
fileItem
.
id
===
file
.
file
.
id
)
{
fileItem
.
status
=
FileItemStatus
.
ERROR
}
})
})
}
}
// 拖拽文件
function
handleDropFile
(
e
:
DragEvent
)
{
const
files
=
e
.
dataTransfer
?.
files
as
FileList
const
file
=
files
[
0
]
isExceedKnowledgeCount
.
value
=
false
const
dropKnowledgeCount
=
files
.
length
const
enableKnowledgeCount
=
Math
.
max
(
0
,
userStore
.
equityInfo
.
maxKnowledgeCount
-
userStore
.
equityInfo
.
usedKnowledgeCount
-
uploadFileList
.
value
.
length
,
)
if
(
userStore
.
equityInfo
.
maxKnowledgeCount
!==
0
&&
enableKnowledgeCount
<
dropKnowledgeCount
)
{
isExceedKnowledgeCount
.
value
=
true
window
.
$message
.
ctWarning
(
t
(
'equity_module.documents_uploaded_exceeds_tip'
,
{
count
:
enableKnowledgeCount
}),
''
)
.
then
(()
=>
{
router
.
push
({
name
:
'Equity'
})
})
.
catch
(()
=>
{})
return
}
const
allowTypeList
=
[
'xls'
,
'xlsx'
]
if
(
file
&&
file
.
name
)
{
const
fileType
=
file
.
name
.
split
(
'.'
)?.
pop
()?.
toLowerCase
()
||
''
if
(
!
allowTypeList
.
includes
(
fileType
))
{
window
.
$message
.
error
(
t
(
'personal_space_module.knowledge_module.upload_document_module.upload_QA_format_error_message'
),
)
return
false
}
}
}
function
handleRemoveFile
(
id
:
string
)
{
uploadFileList
.
value
=
uploadFileList
.
value
.
filter
((
item
)
=>
item
.
id
!==
id
)
}
function
handleDownloadQATemplate
()
{
downloadFile
(
'https://gsst-poe-sit.gz.bcebos.com/v1/%E9%97%AE%E7%AD%94%E6%95%B0%E6%8D%AE%E5%BA%93%E6%A8%A1%E6%9D%BF.xlsx'
,
'问答模版.xlsx'
,
)
}
function
handleNextStep
()
{
const
kdIds
=
uploadFileList
.
value
.
map
((
item
)
=>
item
.
kdId
)
emit
(
'next'
,
kdIds
)
}
</
script
>
<
template
>
<div
class=
"w-full"
>
<NUpload
multiple
directory-dnd
:show-file-list=
"false"
:disabled=
"uploadFileList.length >= 5"
class=
"upload-knowledge-file"
accept=
".xlsx, .xls"
@
before-upload=
"handleLimitUpload"
@
change=
"handleUpload"
@
drop=
"handleDropFile"
>
<NUploadDragger
@
click=
"isExceedKnowledgeCount = false"
>
<div
class=
"mb-3 flex justify-center"
>
<UploadOne
theme=
"outline"
size=
"36"
fill=
"#333"
/>
</div>
<NText
class=
"text-base"
>
{{
t
(
'personal_space_module.knowledge_module.upload_document_module.upload_action_tip_message'
)
}}
</NText>
<p
class=
"text-gray-font-color mt-3 text-sm"
>
{{
t
(
'personal_space_module.knowledge_module.upload_document_module.upload_QA_limit_tip_message'
)
}}
</p>
<p
class=
"text-gray-font-color mt-3 text-sm"
>
{{
t
(
'personal_space_module.knowledge_module.upload_document_module.upload_QA_suggest_tip_message'
)
}}
</p>
<p
class=
"text-theme-color mt-3 text-sm hover:opacity-80"
@
click
.
stop=
"handleDownloadQATemplate"
>
{{
t
(
'personal_space_module.knowledge_module.upload_document_module.download_QA_template'
)
}}
</p>
</NUploadDragger>
</NUpload>
<div
class=
"mt-[18px]"
>
<ul
class=
"grid grid-cols-2 gap-4"
>
<li
v-for=
"uploadFileItem in uploadFileList"
:key=
"uploadFileItem.id"
class=
"group relative h-[92px] w-full overflow-hidden rounded-[10px] border bg-white p-6"
:class=
"uploadFileItem.status === 'error' ? 'border-error-font-color' : 'border-transparent'"
>
<div
class=
"flex items-center justify-between"
>
<div
class=
"flex items-center"
>
<img
:src=
"uploadFileIcon(uploadFileItem.type!)"
class=
"h-9 w-9"
/>
<div
class=
"mx-4 flex flex-col"
>
<NPopover
trigger=
"hover"
>
<template
#
trigger
>
<span
class=
"text-font-color mb-2 line-clamp-1 select-none break-all text-base leading-4"
>
{{
uploadFileItem
.
name
}}
</span>
</
template
>
<span>
{{ uploadFileItem.name }}
</span>
</NPopover>
<div
v-if=
"uploadFileItem.status === FileItemStatus.FINISHED"
class=
"text-gray-font-color line-clamp-1 select-none break-all"
>
<span
class=
"inline-block group-hover:hidden"
>
{{ uploadFileSize(uploadFileItem.size) }}
</span>
<span
class=
"hidden group-hover:inline-block"
>
{{ t('common_module.upload_success_message') }}
</span>
</div>
<div
v-else-if=
"uploadFileItem.status === FileItemStatus.UPLOADING"
class=
"text-gray-font-color line-clamp-1 select-none break-all"
>
<span>
{{ t('common_module.uploading') }}
</span>
</div>
<span
v-else
class=
"text-error-font-color line-clamp-1 select-none break-all"
>
{{ t('personal_space_module.knowledge_module.upload_document_module.upload_error_message') }}
</span>
</div>
</div>
<div
v-show=
"[FileItemStatus.FINISHED, FileItemStatus.ERROR].includes(uploadFileItem.status)"
class=
"hidden group-hover:block"
>
<NPopover
trigger=
"hover"
>
<
template
#
trigger
>
<i
class=
"iconfont icon-close cursor-pointer text-base outline-none hover:opacity-80"
:class=
"
uploadFileItem.status === FileItemStatus.ERROR ? 'text-error-font-color' : 'text-font-color'
"
@
click=
"handleRemoveFile(uploadFileItem.id)"
/>
</
template
>
<span>
{{ t('common_module.delete') }}
</span>
</NPopover>
</div>
</div>
<div
v-show=
"[FileItemStatus.UPLOADING].includes(uploadFileItem.status)"
class=
"animate-training absolute left-0 top-[-1px] h-[92px] w-full rounded-[10px] bg-gradient-to-r from-transparent via-[#9EA0FF] to-transparent"
/>
</li>
</ul>
</div>
<div
class=
"mt-14 flex justify-end"
>
<NButton
type=
"primary"
:disabled=
"!isDisabledNextBtn"
:bordered=
"false"
@
click=
"handleNextStep"
>
{{ t('common_module.next_btn_text') }}
</NButton>
</div>
</div>
</template>
src/views/personal-space/personal-knowledge/upload-knowledge/upload-knowledge.vue
View file @
ed3948ed
...
...
@@ -3,7 +3,8 @@ import { onMounted, ref } from 'vue'
import
{
useRouter
}
from
'vue-router'
import
{
useI18n
}
from
'vue-i18n'
import
{
Left
}
from
'@icon-park/vue-next'
import
UploadLocalDocument
from
'./upload-local-document/index.vue'
import
BaseLocalDocument
from
'./upload-local-document/index.vue'
import
QALocalDocument
from
'./qa-local-document/index.vue'
import
{
fetchGetKnowledgeDetail
,
fetchUpdateKnowledgeInfo
}
from
'@/apis/knowledge'
import
EditKnowledgeModal
,
{
KnowledgeFormDataInterface
}
from
'../components/edit-knowledge-modal.vue'
...
...
@@ -19,6 +20,7 @@ const updateKnowledgeInfoBtnLoading = ref(false)
const
currentKnowledgeData
=
ref
<
KnowledgeFormDataInterface
>
({
knowledgeName
:
''
,
desc
:
''
,
knowledgeType
:
'Base'
,
})
onMounted
(
async
()
=>
{
...
...
@@ -81,7 +83,9 @@ async function handleUpdateKnowledgeInfo(knowledgeData: KnowledgeFormDataInterfa
</div>
</div>
<UploadLocalDocument
v-if=
"uploadKnowledgeType === 'text-local-document'"
/>
<BaseLocalDocument
v-if=
"uploadKnowledgeType === 'Base-local-document'"
/>
<QALocalDocument
v-if=
"uploadKnowledgeType === 'QA-local-document'"
/>
<EditKnowledgeModal
v-model:is-show-modal=
"isShowEditKnowledgeModal"
...
...
src/views/personal-space/personal-knowledge/upload-knowledge/upload-local-document/index.vue
View file @
ed3948ed
...
...
@@ -39,7 +39,7 @@ const stepList = ref<StepItem[]>([
onMounted
(()
=>
{
if
(
!
router
.
currentRoute
.
value
.
params
.
id
)
{
window
.
$message
.
warning
(
'知识库不存在'
)
window
.
$message
.
warning
(
t
(
'personal_space_module.knowledge_module.not_find_knowledge_message'
)
)
router
.
replace
({
name
:
'PersonalSpaceKnowledge'
})
return
}
...
...
src/views/personal-space/personal-knowledge/upload-knowledge/upload-local-document/upload-file.vue
View file @
ed3948ed
...
...
@@ -152,6 +152,7 @@ function handleLimitUpload(data: { file: UploadFileInfo; fileList: UploadFileInf
async
function
handleUpload
(
file
:
any
)
{
const
formData
=
new
FormData
()
formData
.
append
(
'documentFiles'
,
file
.
file
.
file
)
formData
.
append
(
'knowledgeType'
,
'Base'
)
const
fileData
=
{
id
:
file
.
file
.
id
,
...
...
src/views/personal-space/personal-space.vue
View file @
ed3948ed
...
...
@@ -71,6 +71,7 @@ async function handleCreateKnowledgeNextStep(createKnowledgeData: KnowledgeFormD
const
res
=
await
fetchCreateKnowledge
<
{
id
:
number
}
>
({
knowledgeName
:
createKnowledgeData
.
knowledgeName
,
desc
:
createKnowledgeData
.
knowledgeDesc
,
knowledgeType
:
createKnowledgeData
.
knowledgeType
,
}).
finally
(()
=>
{
createKnowledgeBtnLoading
.
value
=
false
})
...
...
stylelint.config.js
View file @
ed3948ed
...
...
@@ -28,7 +28,7 @@ export default {
],
'font-family-name-quotes'
:
null
,
'font-family-no-missing-generic-family-keyword'
:
null
,
'scss/
at-import
-partial-extension'
:
'always'
,
'scss/
load
-partial-extension'
:
'always'
,
'alpha-value-notation'
:
'number'
,
'selector-class-pattern'
:
null
,
},
...
...
types/locales.d.ts
View file @
ed3948ed
...
...
@@ -248,279 +248,294 @@ declare namespace I18n {
title
:
string
create_btn_text
:
string
tab_module
:
{
agent_module
:
{
agent_list_module
:
{
agent_title
:
string
large_model
:
string
agent_id
:
string
agent_publish_status
:
string
publish_status
:
string
modified_time
:
string
channel
:
string
channel_popover_text
:
string
agent_copy
:
string
empty_agent_list
:
string
delete_agent_dialog_title
:
string
delete_agent_dialog_content
:
string
}
agent_module
:
{
agent_list_module
:
{
agent_title
:
string
large_model
:
string
agent_id
:
string
agent_publish_status
:
string
publish_status
:
string
modified_time
:
string
channel
:
string
channel_popover_text
:
string
agent_copy
:
string
empty_agent_list
:
string
delete_agent_dialog_title
:
string
delete_agent_dialog_content
:
string
}
}
agent_setting_module
:
{
my_agent
:
string
modified
:
string
auto_save_in
:
string
update_publish_btn_text
:
string
publish_btn_text
:
string
please_finish_publish
:
string
missing_agent_title_message
:
string
missing_agent_desc_message
:
string
agent_config_module
:
{
stop_generate
:
string
generating_config_message
:
string
title
:
string
ai_auto_config
:
string
question_answer_model
:
string
question_answer_model_desc
:
string
generate_diversity
:
string
topP
:
string
topP_popover_message
:
string
temperature
:
string
temperature_popover_message
:
string
communication_turn
:
string
communication_turn_popover_message
:
string
agent_setting
:
string
base_info
:
string
ai_generate_picture
:
string
agent_title_input_placeholder
:
string
agent_title_input_rule_message
:
string
agent_desc_input_placeholder
:
string
update_avatar
:
string
agent_system_prompt
:
string
agent_system_popover_message
:
string
optimize_agent_system_prompt
:
string
optimize_agent_system_popover_message
:
string
agent_system_template
:
string
agent_system_template_message
:
string
agent_system_input_placeholder
:
string
ability_expand
:
string
plugin
:
string
plugin_desc
:
string
add_plugin
:
string
add_plugin_successfully
:
string
remove_plugin_successfully
:
string
knowledge
:
string
knowledge_base
:
string
knowledge_base_desc
:
string
upload_file
:
string
upload_file_desc
:
string
dialogue
:
string
preamble
:
string
preamble_input_placeholder
:
string
featured_questions
:
string
featured_questions_input_placeholder
:
string
continuous_question
:
string
continuous_question_popover_message
:
string
continuous_question_default
:
string
continuous_question_default_desc
:
string
continuous_question_close
:
string
continuous_question_close_desc
:
string
memory
:
string
add_memory_variable
:
string
memory_variable
:
string
memory_message
:
string
memory_variable_message
:
string
memory_variable_action_edit
:
string
memory_variable_action_copy
:
string
variable_name
:
string
variable_value
:
string
memory_fragment
:
string
memory_fragment_message
:
string
memory_fragment_content
:
string
memory_variable_delete_tip_content
:
string
memory_fragment_delete_all_tip_content
:
string
memory_fragment_delete_row_tip_content
:
string
add_knowledge_successfully
:
string
remove_knowledge_successfully
:
string
setting_voice
:
string
setting_voice_message
:
string
setting_voice_desc
:
string
currently_only_one_voice_can_be_set
:
string
memory_variable_modal
:
{
edit_memory_variable
:
string
memory_variable_message_tip
:
string
memory_variable_table_name
:
string
memory_variable_table_name_tip
:
string
memory_variable_table_name_content
:
string
memory_variable_table_name_length
:
string
memory_variable_table_default_value
:
string
default_value_tip
:
string
default_value_tip_example
:
string
memory_variable_table_action
:
string
default_value_placeholder
:
string
name_placeholder
:
string
add_variable
:
string
memory_variable_add_now
:
string
none_memory_variable
:
string
add_variable_message
:
string
memory_variable_rules
:
{
name_not_null
:
string
name_length
:
string
name_supports
:
string
name_not_duplicated
:
string
}
agent_setting_module
:
{
my_agent
:
string
modified
:
string
auto_save_in
:
string
update_publish_btn_text
:
string
publish_btn_text
:
string
please_finish_publish
:
string
missing_agent_title_message
:
string
missing_agent_desc_message
:
string
agent_config_module
:
{
stop_generate
:
string
generating_config_message
:
string
title
:
string
ai_auto_config
:
string
question_answer_model
:
string
question_answer_model_desc
:
string
generate_diversity
:
string
topP
:
string
topP_popover_message
:
string
temperature
:
string
temperature_popover_message
:
string
communication_turn
:
string
communication_turn_popover_message
:
string
agent_setting
:
string
base_info
:
string
ai_generate_picture
:
string
agent_title_input_placeholder
:
string
agent_title_input_rule_message
:
string
agent_desc_input_placeholder
:
string
update_avatar
:
string
agent_system_prompt
:
string
agent_system_popover_message
:
string
optimize_agent_system_prompt
:
string
optimize_agent_system_popover_message
:
string
agent_system_template
:
string
agent_system_template_message
:
string
agent_system_input_placeholder
:
string
ability_expand
:
string
plugin
:
string
plugin_desc
:
string
add_plugin
:
string
add_plugin_successfully
:
string
remove_plugin_successfully
:
string
knowledge
:
string
knowledge_base
:
string
knowledge_base_desc
:
string
upload_file
:
string
upload_file_desc
:
string
dialogue
:
string
preamble
:
string
preamble_input_placeholder
:
string
featured_questions
:
string
featured_questions_input_placeholder
:
string
continuous_question
:
string
continuous_question_popover_message
:
string
continuous_question_default
:
string
continuous_question_default_desc
:
string
continuous_question_close
:
string
continuous_question_close_desc
:
string
memory
:
string
add_memory_variable
:
string
memory_variable
:
string
memory_message
:
string
memory_variable_message
:
string
memory_variable_action_edit
:
string
memory_variable_action_copy
:
string
variable_name
:
string
variable_value
:
string
memory_fragment
:
string
memory_fragment_message
:
string
memory_fragment_content
:
string
memory_variable_delete_tip_content
:
string
memory_fragment_delete_all_tip_content
:
string
memory_fragment_delete_row_tip_content
:
string
add_knowledge_successfully
:
string
remove_knowledge_successfully
:
string
setting_voice
:
string
setting_voice_message
:
string
setting_voice_desc
:
string
currently_only_one_voice_can_be_set
:
string
memory_variable_modal
:
{
edit_memory_variable
:
string
memory_variable_message_tip
:
string
memory_variable_table_name
:
string
memory_variable_table_name_tip
:
string
memory_variable_table_name_content
:
string
memory_variable_table_name_length
:
string
memory_variable_table_default_value
:
string
default_value_tip
:
string
default_value_tip_example
:
string
memory_variable_table_action
:
string
default_value_placeholder
:
string
name_placeholder
:
string
add_variable
:
string
memory_variable_add_now
:
string
none_memory_variable
:
string
add_variable_message
:
string
memory_variable_rules
:
{
name_not_null
:
string
name_length
:
string
name_supports
:
string
name_not_duplicated
:
string
}
}
preview
:
string
avatar_oversize_message
:
string
generate_format_error_message
:
string
preview
:
string
auto_config_modal_module
:
{
modal_title
:
string
generate_tip_message
:
string
auto_config_input_placeholder
:
string
cancel_btn_text
:
string
random_generate_btn_text
:
string
}
avatar_oversize_message
:
string
generate_format_error_message
:
string
optimize_system_modal_module
:
{
modal_title
:
string
confirm_btn_text
:
string
}
auto_config_modal_module
:
{
modal_title
:
string
generate_tip_message
:
string
auto_config_input_placeholder
:
string
cancel_btn_text
:
string
random_generate_btn_text
:
string
}
agent_publish_module
:
{
channel
:
string
web_channel_name
:
string
web_channel_desc
:
string
access_page
:
string
share_link
:
string
copy_share_url_success_message
:
string
application_square_desc
:
string
modify_setting_btn
:
string
not_configured_btn
:
string
removal_prompt_title
:
string
removal_prompt_content
:
string
successfully_configured_published
:
string
api_call
:
string
api_call_desc
:
string
interface_document
:
string
click_to_generate
:
string
agentId
:
string
copy_id
:
string
api_call_details
:
string
api_call_datetime
:
string
optimize_system_modal_module
:
{
modal_title
:
string
confirm_btn_text
:
string
}
}
agent_sale_module
:
{
application_square_release_setting
:
string
application_classification
:
string
application_classification_null
:
string
application_classify
:
{
media_entertainment
:
string
education_training
:
string
business_services
:
string
medical_health
:
string
efficiency_tools
:
string
office_personnel
:
string
marketing_commerce
:
string
finance
:
string
law
:
string
culture_tourism
:
string
}
is_copy
:
string
yes
:
string
no
:
string
confirm_release
:
string
copy_tip
:
string
agent_publish_module
:
{
channel
:
string
web_channel_name
:
string
web_channel_desc
:
string
access_page
:
string
share_link
:
string
copy_share_url_success_message
:
string
application_square_desc
:
string
modify_setting_btn
:
string
not_configured_btn
:
string
removal_prompt_title
:
string
removal_prompt_content
:
string
successfully_configured_published
:
string
api_call
:
string
api_call_desc
:
string
interface_document
:
string
click_to_generate
:
string
agentId
:
string
copy_id
:
string
api_call_details
:
string
api_call_datetime
:
string
}
}
knowledge_module
:
{
search_knowledge_placeholder
:
string
knowledge_name
:
string
knowledge_desc
:
string
delete_knowledge_dialog_content
:
string
not_find_knowledge_message
:
string
search_knowledge_document_placeholder
:
string
knowledge_document_name
:
string
knowledge_document_char_count
:
string
knowledge_document_format
:
string
view_knowledge_document_fragment
:
string
training_knowledge_document
:
string
empty_knowledge_document_list
:
string
upload_knowledge_document_btn_text
:
string
batch_delete_knowledge_document_btn_text
:
string
not_find_knowledge_document_message
:
string
not_all_files_train_complete_tip
:
string
cannot_add_tip_when_file_is_training
:
string
create_knowledge_modal_title
:
string
edit_knowledge_modal_title
:
string
knowledge_name_input_placeholder
:
string
knowledge_desc_input_placeholder
:
string
knowledge_import_type_label
:
string
knowledge_type_rule
:
string
knowledge_name_rule
:
string
knowledge_import_type_rule
:
string
knowledge_document_text_type
:
string
import_local_document_knowledge
:
string
import_local_document_knowledge_desc
:
string
segment
:
string
auto_segment
:
string
custom_segment
:
string
add_chunk_up_message
:
string
add_chunk_down_message
:
string
search_knowledge_chunk_placeholder
:
string
add_knowledge_chunk_modal_title
:
string
knowledge_chunk_content_input_placeholder
:
string
knowledge_chunk_content_input_rule
:
string
delete_knowledge_chunk_content_message
:
string
divide_by_word_count
:
string
Chinese_comma
:
string
Chinese_period
:
string
Chinese_question_mark
:
string
Chinese_exclamation_mark
:
string
English_period
:
string
English_exclamation_mark
:
string
ellipsis
:
string
upload_document_module
:
{
segment_setting
:
string
data_process
:
string
process_success
:
string
process_fail
:
string
processed
:
string
upload_action_tip_message
:
string
upload_limit_tip_message
:
string
empty_document_content_message
:
string
upload_format_error_message
:
string
upload_size_error_message
:
string
upload_error_message
:
string
default_segment_setting_title
:
string
default_segment_setting_desc
:
string
custom_segment_setting_desc
:
string
segment_identifier
:
string
segment_identifier_tip
:
string
please_select_segment_identifier
:
string
segment_maximum_number_of_words
:
string
segment_maximum_number_of_words_tip
:
string
please_input_segment_word_number
:
string
segment_overlap_word_proportion
:
string
segment_overlap_word_proportion_tip
:
string
please_input_segment_overlap_word_proportion
:
string
data_process_tip_message
:
string
}
agent_sale_module
:
{
application_square_release_setting
:
string
application_classification
:
string
application_classification_null
:
string
application_classify
:
{
media_entertainment
:
string
education_training
:
string
business_services
:
string
medical_health
:
string
efficiency_tools
:
string
office_personnel
:
string
marketing_commerce
:
string
finance
:
string
law
:
string
culture_tourism
:
string
}
is_copy
:
string
yes
:
string
no
:
string
confirm_release
:
string
copy_tip
:
string
}
knowledge_module
:
{
search_knowledge_placeholder
:
string
knowledge_name
:
string
knowledge_desc
:
string
delete_knowledge_dialog_content
:
string
not_find_knowledge_message
:
string
search_knowledge_document_placeholder
:
string
knowledge_document_name
:
string
knowledge_document_char_count
:
string
knowledge_document_format
:
string
view_knowledge_document_fragment
:
string
training_knowledge_document
:
string
empty_knowledge_document_list
:
string
upload_knowledge_document_btn_text
:
string
batch_delete_knowledge_document_btn_text
:
string
not_find_knowledge_document_message
:
string
not_all_files_train_complete_tip
:
string
cannot_add_tip_when_file_is_training
:
string
create_knowledge_modal_title
:
string
edit_knowledge_modal_title
:
string
knowledge_name_input_placeholder
:
string
knowledge_desc_input_placeholder
:
string
knowledge_import_type_label
:
string
knowledge_type_rule
:
string
knowledge_name_rule
:
string
knowledge_import_type_rule
:
string
knowledge_document_text_type
:
string
import_local_document_knowledge
:
string
import_local_document_knowledge_desc
:
string
QA_knowledge_type
:
string
import_QA_local_document_knowledge_desc
:
string
segment
:
string
auto_segment
:
string
custom_segment
:
string
add_chunk_up_message
:
string
add_chunk_down_message
:
string
search_knowledge_chunk_placeholder
:
string
add_knowledge_chunk_modal_title
:
string
knowledge_chunk_content_input_placeholder
:
string
knowledge_chunk_content_input_rule
:
string
delete_knowledge_chunk_content_message
:
string
divide_by_word_count
:
string
Chinese_comma
:
string
Chinese_period
:
string
Chinese_question_mark
:
string
Chinese_exclamation_mark
:
string
English_period
:
string
English_exclamation_mark
:
string
ellipsis
:
string
index
:
string
no
:
string
add_QA
:
string
add_QA_data
:
string
edit_QA_data
:
string
setting_index_desc
:
string
select_at_least_one_field_as_the_index
:
string
setting_index
:
string
field_name
:
string
please_enter_the_content
:
string
upload_document_module
:
{
segment_setting
:
string
data_process
:
string
process_success
:
string
process_fail
:
string
processed
:
string
upload_action_tip_message
:
string
upload_limit_tip_message
:
string
empty_document_content_message
:
string
upload_format_error_message
:
string
upload_size_error_message
:
string
upload_error_message
:
string
default_segment_setting_title
:
string
default_segment_setting_desc
:
string
custom_segment_setting_desc
:
string
segment_identifier
:
string
segment_identifier_tip
:
string
please_select_segment_identifier
:
string
segment_maximum_number_of_words
:
string
segment_maximum_number_of_words_tip
:
string
please_input_segment_word_number
:
string
segment_overlap_word_proportion
:
string
segment_overlap_word_proportion_tip
:
string
please_input_segment_overlap_word_proportion
:
string
data_process_tip_message
:
string
upload_QA_limit_tip_message
:
string
upload_QA_suggest_tip_message
:
string
upload_QA_format_error_message
:
string
download_QA_template
:
string
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment