feat(knowledge): 完成知识库基本功能开发
This commit is contained in:
@@ -1,30 +1,85 @@
|
||||
import React from 'react'
|
||||
import {useParams} from 'react-router'
|
||||
import {amisRender, crudCommonOptions} from '../../../util/amis.tsx'
|
||||
import {useNavigate, useParams} from 'react-router'
|
||||
import {amisRender, crudCommonOptions, mappingField, mappingItem} from '../../../util/amis.tsx'
|
||||
|
||||
const statusMapping = [
|
||||
mappingItem('解析中', 'RUNNING', 'bg-warning'),
|
||||
mappingItem('使用中', 'FINISHED', 'bg-success'),
|
||||
]
|
||||
|
||||
const DataDetail: React.FC = () => {
|
||||
const {name} = useParams()
|
||||
const {knowledge_id} = useParams()
|
||||
const navigate = useNavigate()
|
||||
return (
|
||||
<div className="import-detail h-full">
|
||||
{amisRender(
|
||||
{
|
||||
className: 'h-full',
|
||||
type: 'page',
|
||||
title: `数据详情 (知识库:${name})`,
|
||||
title: {
|
||||
type: 'wrapper',
|
||||
size: 'none',
|
||||
body: [
|
||||
'数据详情 (知识库:',
|
||||
{
|
||||
type: 'service',
|
||||
className: 'inline',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: 'http://127.0.0.1:8080/knowledge/name',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
data: {
|
||||
id: knowledge_id,
|
||||
},
|
||||
},
|
||||
body: {
|
||||
type: 'tpl',
|
||||
tpl: '${name}',
|
||||
},
|
||||
},
|
||||
')',
|
||||
],
|
||||
},
|
||||
size: 'lg',
|
||||
actions: [],
|
||||
body: [
|
||||
{
|
||||
type: 'crud',
|
||||
api: {
|
||||
url: 'http://127.0.0.1:8080/knowledge/list_points?name=${name}',
|
||||
method: 'get',
|
||||
url: 'http://127.0.0.1:8080/group/list',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
data: {
|
||||
knowledge_id,
|
||||
},
|
||||
},
|
||||
...crudCommonOptions(),
|
||||
headerToolbar: [
|
||||
'reload',
|
||||
{
|
||||
type: 'action',
|
||||
icon: 'fa fa-plus',
|
||||
label: '',
|
||||
tooltip: '新增',
|
||||
tooltipPlacement: 'top',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'custom',
|
||||
// @ts-ignore
|
||||
script: (context, action, event) => {
|
||||
navigate(`/ai/knowledge/import/${knowledge_id}`)
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
@@ -32,8 +87,15 @@ const DataDetail: React.FC = () => {
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
name: 'text',
|
||||
label: '内容',
|
||||
name: 'name',
|
||||
label: '文件名',
|
||||
},
|
||||
{
|
||||
name: 'status',
|
||||
label: '状态',
|
||||
width: 50,
|
||||
align: 'center',
|
||||
...mappingField('status', statusMapping),
|
||||
},
|
||||
{
|
||||
type: 'operation',
|
||||
@@ -42,30 +104,17 @@ const DataDetail: React.FC = () => {
|
||||
buttons: [
|
||||
{
|
||||
type: 'action',
|
||||
label: '编辑',
|
||||
label: '查看',
|
||||
level: 'link',
|
||||
size: 'lg',
|
||||
actionType: 'dialog',
|
||||
dialog: {
|
||||
title: '编辑文段',
|
||||
size: 'md',
|
||||
body: {
|
||||
type: 'form',
|
||||
body: [
|
||||
size: 'sm',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'id',
|
||||
disabled: true,
|
||||
label: '文段ID',
|
||||
},
|
||||
{
|
||||
type: 'editor',
|
||||
label: '内容',
|
||||
name: 'text',
|
||||
language: 'plaintext',
|
||||
options: {
|
||||
lineNumbers: 'off',
|
||||
wordWrap: 'bounded',
|
||||
actionType: 'custom',
|
||||
// @ts-ignore
|
||||
script: (context, action, event) => {
|
||||
navigate(`/ai/knowledge/detail/${knowledge_id}/segment/${context.props.data['id']}`)
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -77,13 +126,17 @@ const DataDetail: React.FC = () => {
|
||||
label: '删除',
|
||||
className: 'text-danger hover:text-red-600',
|
||||
level: 'link',
|
||||
size: 'xs',
|
||||
size: 'sm',
|
||||
actionType: 'ajax',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: 'http://127.0.0.1:8080/group/delete',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
data: {
|
||||
id: '${id}',
|
||||
},
|
||||
},
|
||||
confirmText: '确认删除',
|
||||
confirmTitle: '删除',
|
||||
|
||||
@@ -10,12 +10,37 @@ const ImportDataDiv = styled.div`
|
||||
`
|
||||
|
||||
const DataImport: React.FC = () => {
|
||||
const {name} = useParams()
|
||||
const {knowledge_id} = useParams()
|
||||
return (
|
||||
<ImportDataDiv className="import-data h-full">
|
||||
{amisRender({
|
||||
type: 'page',
|
||||
title: `数据导入 (知识库:${name})`,
|
||||
title: {
|
||||
type: 'wrapper',
|
||||
size: 'none',
|
||||
body: [
|
||||
'数据导入 (知识库:',
|
||||
{
|
||||
type: 'service',
|
||||
className: 'inline',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: 'http://127.0.0.1:8080/knowledge/name',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
data: {
|
||||
id: knowledge_id,
|
||||
},
|
||||
},
|
||||
body: {
|
||||
type: 'tpl',
|
||||
tpl: '${name}',
|
||||
},
|
||||
},
|
||||
')',
|
||||
],
|
||||
},
|
||||
body: [
|
||||
[
|
||||
{
|
||||
@@ -53,7 +78,7 @@ const DataImport: React.FC = () => {
|
||||
name: 'type',
|
||||
type: 'radios',
|
||||
label: '数据形式',
|
||||
value: 'text',
|
||||
value: 'file',
|
||||
options: [
|
||||
{
|
||||
value: 'text',
|
||||
@@ -62,7 +87,6 @@ const DataImport: React.FC = () => {
|
||||
{
|
||||
value: 'file',
|
||||
label: '文件',
|
||||
disabled: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -82,10 +106,38 @@ const DataImport: React.FC = () => {
|
||||
type: 'input-file',
|
||||
name: 'files',
|
||||
label: '数据文件',
|
||||
accept: '.txt,.csv',
|
||||
autoUpload: false,
|
||||
drag: true,
|
||||
multiple: true,
|
||||
useChunk: true,
|
||||
accept: '*',
|
||||
// 5MB 5242880
|
||||
// 100MB 104857600
|
||||
// 500MB 524288000
|
||||
// 1GB 1073741824
|
||||
maxSize: '',
|
||||
maxLength: 0,
|
||||
startChunkApi: {
|
||||
method: 'post',
|
||||
url: 'http://127.0.0.1:8080/upload/start',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
},
|
||||
chunkApi: {
|
||||
method: 'post',
|
||||
url: 'http://127.0.0.1:8080/upload/slice',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
},
|
||||
finishChunkApi: {
|
||||
method: 'post',
|
||||
url: 'http://127.0.0.1:8080/upload/finish',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
className: 'text-right',
|
||||
@@ -103,16 +155,10 @@ const DataImport: React.FC = () => {
|
||||
},
|
||||
dataType: 'form',
|
||||
data: {
|
||||
mode: '${mode}',
|
||||
type: '${type}',
|
||||
content: '${content}',
|
||||
},
|
||||
// @ts-ignore
|
||||
adaptor: (payload, response, api, context) => {
|
||||
console.log(payload)
|
||||
return {
|
||||
items: payload,
|
||||
}
|
||||
mode: '${mode|default:undefined}',
|
||||
type: '${type|default:undefined}',
|
||||
content: '${content|default:undefined}',
|
||||
files: '${files|default:undefined}',
|
||||
},
|
||||
},
|
||||
reload: 'preview_list?rows=${items}',
|
||||
@@ -121,6 +167,22 @@ const DataImport: React.FC = () => {
|
||||
type: 'submit',
|
||||
label: '提交',
|
||||
level: 'primary',
|
||||
actionType: 'ajax',
|
||||
api: {
|
||||
method: 'post',
|
||||
url: 'http://127.0.0.1:8080/knowledge/submit_text',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
dataType: 'form',
|
||||
data: {
|
||||
id: knowledge_id,
|
||||
mode: '${mode|default:undefined}',
|
||||
type: '${type|default:undefined}',
|
||||
content: '${content|default:undefined}',
|
||||
files: '${files|default:undefined}',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -155,6 +217,7 @@ const DataImport: React.FC = () => {
|
||||
],
|
||||
listItem: {
|
||||
body: {
|
||||
className: 'white-space-pre-line',
|
||||
type: 'tpl',
|
||||
tpl: '${text}',
|
||||
},
|
||||
|
||||
133
service-web/client/src/pages/ai/knowledge/DataSegment.tsx
Normal file
133
service-web/client/src/pages/ai/knowledge/DataSegment.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
import React from 'react'
|
||||
import {useParams} from 'react-router'
|
||||
import {amisRender, crudCommonOptions} from '../../../util/amis.tsx'
|
||||
|
||||
const DataDetail: React.FC = () => {
|
||||
const {knowledge_id, group_id} = useParams()
|
||||
return (
|
||||
<div className="import-detail h-full">
|
||||
{amisRender(
|
||||
{
|
||||
className: 'h-full',
|
||||
type: 'page',
|
||||
title: {
|
||||
type: 'wrapper',
|
||||
size: 'none',
|
||||
body: [
|
||||
'数据详情 (知识库:',
|
||||
{
|
||||
type: 'service',
|
||||
className: 'inline',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: 'http://127.0.0.1:8080/knowledge/name',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
data: {
|
||||
id: knowledge_id,
|
||||
},
|
||||
},
|
||||
body: {
|
||||
type: 'tpl',
|
||||
tpl: '${name}',
|
||||
},
|
||||
},
|
||||
')',
|
||||
],
|
||||
},
|
||||
size: 'lg',
|
||||
actions: [],
|
||||
body: [
|
||||
{
|
||||
type: 'crud',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: 'http://127.0.0.1:8080/segment/list',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
data: {
|
||||
knowledge_id,
|
||||
group_id,
|
||||
},
|
||||
},
|
||||
...crudCommonOptions(),
|
||||
headerToolbar: [
|
||||
'reload',
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
name: 'text',
|
||||
label: '内容',
|
||||
className: 'white-space-pre-line',
|
||||
},
|
||||
{
|
||||
type: 'operation',
|
||||
label: '操作',
|
||||
width: 50,
|
||||
buttons: [
|
||||
/*{
|
||||
type: 'action',
|
||||
label: '编辑',
|
||||
level: 'link',
|
||||
size: 'lg',
|
||||
actionType: 'dialog',
|
||||
dialog: {
|
||||
title: '编辑文段',
|
||||
size: 'md',
|
||||
body: {
|
||||
type: 'form',
|
||||
body: [
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'id',
|
||||
disabled: true,
|
||||
label: '文段ID',
|
||||
},
|
||||
{
|
||||
type: 'editor',
|
||||
label: '内容',
|
||||
name: 'text',
|
||||
language: 'plaintext',
|
||||
options: {
|
||||
lineNumbers: 'off',
|
||||
wordWrap: 'bounded',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},*/
|
||||
{
|
||||
type: 'action',
|
||||
label: '删除',
|
||||
className: 'text-danger hover:text-red-600',
|
||||
level: 'link',
|
||||
size: 'sm',
|
||||
actionType: 'ajax',
|
||||
api: {
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
},
|
||||
confirmText: '删除后无法恢复,确认删除该记录?',
|
||||
confirmTitle: '删除',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DataDetail
|
||||
@@ -38,6 +38,8 @@ const Knowledge: React.FC = () => {
|
||||
type: 'action',
|
||||
label: '',
|
||||
icon: 'fa fa-plus',
|
||||
tooltip: '新增',
|
||||
tooltipPlacement: 'top',
|
||||
actionType: 'dialog',
|
||||
dialog: {
|
||||
title: '新增知识库',
|
||||
@@ -111,7 +113,7 @@ const Knowledge: React.FC = () => {
|
||||
type: 'action',
|
||||
label: '详情',
|
||||
level: 'link',
|
||||
size: 'xs',
|
||||
size: 'sm',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
@@ -119,7 +121,7 @@ const Knowledge: React.FC = () => {
|
||||
actionType: 'custom',
|
||||
// @ts-ignore
|
||||
script: (context, action, event) => {
|
||||
navigate(`/ai/knowledge/detail/${context.props.data['name']}`)
|
||||
navigate(`/ai/knowledge/detail/${context.props.data['id']}`)
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -130,7 +132,7 @@ const Knowledge: React.FC = () => {
|
||||
type: 'action',
|
||||
label: '导入',
|
||||
level: 'link',
|
||||
size: 'xs',
|
||||
size: 'sm',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
@@ -138,7 +140,7 @@ const Knowledge: React.FC = () => {
|
||||
actionType: 'custom',
|
||||
// @ts-ignore
|
||||
script: (context, action, event) => {
|
||||
navigate(`/ai/knowledge/import/${context.props.data['name']}`)
|
||||
navigate(`/ai/knowledge/import/${context.props.data['id']}`)
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -150,14 +152,17 @@ const Knowledge: React.FC = () => {
|
||||
label: '删除',
|
||||
className: 'text-danger hover:text-red-600',
|
||||
level: 'link',
|
||||
size: 'xs',
|
||||
size: 'sm',
|
||||
actionType: 'ajax',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: 'http://127.0.0.1:8080/knowledge/delete?name=${name}',
|
||||
url: 'http://127.0.0.1:8080/knowledge/delete',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
data: {
|
||||
id: '${id}',
|
||||
},
|
||||
},
|
||||
confirmText: '确认删除',
|
||||
confirmTitle: '删除',
|
||||
|
||||
@@ -17,6 +17,7 @@ import Conversation from './pages/ai/Conversation.tsx'
|
||||
import Inspection from './pages/ai/Inspection.tsx'
|
||||
import DataDetail from './pages/ai/knowledge/DataDetail.tsx'
|
||||
import DataImport from './pages/ai/knowledge/DataImport.tsx'
|
||||
import DataSegment from './pages/ai/knowledge/DataSegment.tsx'
|
||||
import Knowledge from './pages/ai/knowledge/Knowledge.tsx'
|
||||
import App from './pages/App.tsx'
|
||||
import Cloud from './pages/overview/Cloud.tsx'
|
||||
@@ -95,13 +96,17 @@ export const routes: RouteObject[] = [
|
||||
Component: Knowledge,
|
||||
},
|
||||
{
|
||||
path: 'knowledge/import/:name',
|
||||
path: 'knowledge/import/:knowledge_id',
|
||||
Component: DataImport,
|
||||
},
|
||||
{
|
||||
path: 'knowledge/detail/:name',
|
||||
path: 'knowledge/detail/:knowledge_id',
|
||||
Component: DataDetail,
|
||||
},
|
||||
{
|
||||
path: 'knowledge/detail/:knowledge_id/segment/:group_id',
|
||||
Component: DataSegment,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -77,6 +77,7 @@ export const amisRender = (schema: Schema, data: Record<any, any> = {}) => {
|
||||
theme: theme,
|
||||
},
|
||||
{
|
||||
enableAMISDebug: true,
|
||||
fetcher: async (api: any) => {
|
||||
let {url, method, data, responseType, config, headers} = api
|
||||
config = config || {}
|
||||
|
||||
Reference in New Issue
Block a user