feat(ai): 完善知识库接口
This commit is contained in:
105
service-web/client/src/pages/ai/knowledge/DataDetail.tsx
Normal file
105
service-web/client/src/pages/ai/knowledge/DataDetail.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
import React from 'react'
|
||||
import {useParams} from 'react-router'
|
||||
import {amisRender, crudCommonOptions} from '../../../util/amis.tsx'
|
||||
|
||||
const DataDetail: React.FC = () => {
|
||||
const {name} = useParams()
|
||||
return (
|
||||
<div className="import-detail h-full">
|
||||
{amisRender(
|
||||
{
|
||||
className: 'h-full',
|
||||
type: 'page',
|
||||
title: `数据详情 (知识库:${name})`,
|
||||
size: 'lg',
|
||||
actions: [],
|
||||
body: [
|
||||
{
|
||||
type: 'crud',
|
||||
api: {
|
||||
url: 'http://127.0.0.1:8080/knowledge/list_points?name=${name}',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
},
|
||||
...crudCommonOptions(),
|
||||
headerToolbar: [
|
||||
'reload',
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
name: 'text',
|
||||
label: '内容',
|
||||
},
|
||||
{
|
||||
type: 'operation',
|
||||
label: '操作',
|
||||
width: 100,
|
||||
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: 'xs',
|
||||
actionType: 'ajax',
|
||||
api: {
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
},
|
||||
confirmText: '确认删除',
|
||||
confirmTitle: '删除',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: name,
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DataDetail
|
||||
144
service-web/client/src/pages/ai/knowledge/DataImport.tsx
Normal file
144
service-web/client/src/pages/ai/knowledge/DataImport.tsx
Normal file
@@ -0,0 +1,144 @@
|
||||
import React from 'react'
|
||||
import {useParams} from 'react-router'
|
||||
import styled from 'styled-components'
|
||||
import {amisRender} from '../../../util/amis.tsx'
|
||||
|
||||
const ImportDataDiv = styled.div`
|
||||
.antd-EditorControl {
|
||||
min-height: 500px !important;
|
||||
}
|
||||
`
|
||||
|
||||
const DataImport: React.FC = () => {
|
||||
const {name} = useParams()
|
||||
return (
|
||||
<ImportDataDiv className="import-data h-full">
|
||||
{amisRender({
|
||||
type: 'page',
|
||||
title: `数据导入 (知识库:${name})`,
|
||||
body: [
|
||||
[
|
||||
{
|
||||
className: 'h-full',
|
||||
type: 'grid',
|
||||
columns: [
|
||||
{
|
||||
body: [
|
||||
{
|
||||
type: 'form',
|
||||
wrapWithPanel: false,
|
||||
mode: 'horizontal',
|
||||
actions: [],
|
||||
body: [
|
||||
{
|
||||
name: 'mode',
|
||||
type: 'radios',
|
||||
label: '解析模式',
|
||||
value: 'normal',
|
||||
options: [
|
||||
{
|
||||
value: 'normal',
|
||||
label: '常规模式',
|
||||
},
|
||||
{
|
||||
value: 'llm',
|
||||
label: '智能模式',
|
||||
},
|
||||
{
|
||||
value: 'qa',
|
||||
label: 'Q/A模式',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'type',
|
||||
type: 'radios',
|
||||
label: '数据形式',
|
||||
value: 'text',
|
||||
options: [
|
||||
{
|
||||
value: 'text',
|
||||
label: '文本',
|
||||
},
|
||||
{
|
||||
value: 'file',
|
||||
label: '文件',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
visibleOn: 'type === \'text\'',
|
||||
type: 'editor',
|
||||
label: '数据内容',
|
||||
name: 'content',
|
||||
language: 'plaintext',
|
||||
options: {
|
||||
lineNumbers: 'off',
|
||||
wordWrap: 'bounded',
|
||||
},
|
||||
},
|
||||
{
|
||||
visibleOn: 'type === \'file\'',
|
||||
type: 'input-file',
|
||||
name: 'files',
|
||||
label: '数据文件',
|
||||
accept: '.txt,.csv',
|
||||
autoUpload: false,
|
||||
drag: true,
|
||||
multiple: true,
|
||||
},
|
||||
{
|
||||
className: 'text-right',
|
||||
type: 'button-toolbar',
|
||||
buttons: [
|
||||
{
|
||||
type: 'action',
|
||||
label: '预览',
|
||||
},
|
||||
{
|
||||
type: 'submit',
|
||||
label: '提交',
|
||||
level: 'primary',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
body: [
|
||||
{
|
||||
type: 'card',
|
||||
className: 'h-full',
|
||||
header: {
|
||||
title: '解析预览',
|
||||
subTitle: '截取部份文本进行解析预览',
|
||||
},
|
||||
body: [
|
||||
{
|
||||
type: 'list',
|
||||
source: '${rows}',
|
||||
listItem: [
|
||||
{
|
||||
body: {
|
||||
type: 'tpl',
|
||||
tpl: '${content}',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
],
|
||||
})}
|
||||
</ImportDataDiv>
|
||||
)
|
||||
}
|
||||
|
||||
export default DataImport
|
||||
176
service-web/client/src/pages/ai/knowledge/Knowledge.tsx
Normal file
176
service-web/client/src/pages/ai/knowledge/Knowledge.tsx
Normal file
@@ -0,0 +1,176 @@
|
||||
import React from 'react'
|
||||
import {useNavigate} from 'react-router'
|
||||
import {amisRender, crudCommonOptions, mappingField, mappingItem} from '../../../util/amis.tsx'
|
||||
|
||||
const strategyMapping = [
|
||||
mappingItem('文本', 'Cosine'),
|
||||
mappingItem('图片', 'Euclid'),
|
||||
]
|
||||
|
||||
const statusMapping = [
|
||||
mappingItem('正常', 'Green', 'label-success'),
|
||||
mappingItem('优化中', 'Yellow', 'label-warning'),
|
||||
mappingItem('错误', 'Red', 'label-danger'),
|
||||
mappingItem('等待中', 'Grey', 'label-primary'),
|
||||
]
|
||||
|
||||
const Knowledge: React.FC = () => {
|
||||
const navigate = useNavigate()
|
||||
return (
|
||||
<div className="knowledge">
|
||||
{amisRender(
|
||||
{
|
||||
type: 'page',
|
||||
title: '知识库',
|
||||
body: [
|
||||
{
|
||||
type: 'crud',
|
||||
api: {
|
||||
url: 'http://127.0.0.1:8080/knowledge/list',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
},
|
||||
...crudCommonOptions(),
|
||||
headerToolbar: [
|
||||
'reload',
|
||||
{
|
||||
type: 'action',
|
||||
label: '',
|
||||
icon: 'fa fa-plus',
|
||||
actionType: 'dialog',
|
||||
dialog: {
|
||||
title: '新增知识库',
|
||||
size: 'md',
|
||||
body: {
|
||||
type: 'form',
|
||||
api: {
|
||||
url: 'http://127.0.0.1:8080/knowledge/add',
|
||||
dataType: 'form',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
},
|
||||
body: [
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'name',
|
||||
label: '名称',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
name: 'strategy',
|
||||
label: '类型',
|
||||
value: 'Cosine',
|
||||
options: [
|
||||
{
|
||||
label: '文本',
|
||||
value: 'Cosine',
|
||||
},
|
||||
{
|
||||
label: '图片',
|
||||
value: 'Euclid',
|
||||
disabled: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
name: 'name',
|
||||
label: '名称',
|
||||
},
|
||||
{
|
||||
label: '类型',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
...mappingField('strategy', strategyMapping),
|
||||
},
|
||||
{
|
||||
name: 'points',
|
||||
label: '文本数',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
...mappingField('status', statusMapping),
|
||||
},
|
||||
{
|
||||
type: 'operation',
|
||||
label: '操作',
|
||||
width: 150,
|
||||
buttons: [
|
||||
{
|
||||
type: 'action',
|
||||
label: '详情',
|
||||
level: 'link',
|
||||
size: 'xs',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'custom',
|
||||
// @ts-ignore
|
||||
script: (context, action, event) => {
|
||||
navigate(`/ai/knowledge/detail/${context.props.data['name']}`)
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'action',
|
||||
label: '导入',
|
||||
level: 'link',
|
||||
size: 'xs',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'custom',
|
||||
// @ts-ignore
|
||||
script: (context, action, event) => {
|
||||
navigate(`/ai/knowledge/import/${context.props.data['name']}`)
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'action',
|
||||
label: '删除',
|
||||
className: 'text-danger hover:text-red-600',
|
||||
level: 'link',
|
||||
size: 'xs',
|
||||
actionType: 'ajax',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: 'http://127.0.0.1:8080/knowledge/delete?name=${name}',
|
||||
headers: {
|
||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||
},
|
||||
},
|
||||
confirmText: '确认删除',
|
||||
confirmTitle: '删除',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Knowledge
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
serviceLogByAppName,
|
||||
serviceLogByAppNameAndHost,
|
||||
time,
|
||||
} from '../../util/amis.ts'
|
||||
} from '../../util/amis.tsx'
|
||||
|
||||
const cloudCrud = (title: string, path: string) => {
|
||||
return {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import {amisRender, commonInfo, crudCommonOptions, readOnlyDialogOptions} from '../../util/amis.ts'
|
||||
import {amisRender, commonInfo, crudCommonOptions, readOnlyDialogOptions} from '../../util/amis.tsx'
|
||||
|
||||
const color = (number: number) => {
|
||||
let color = 'text-success'
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
paginationCommonOptions,
|
||||
time,
|
||||
yarnQueueCrud,
|
||||
} from '../../util/amis.ts'
|
||||
} from '../../util/amis.tsx'
|
||||
|
||||
const queueCrud = (name: string) => {
|
||||
return {
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
tableMetaDialog,
|
||||
tableRunningStateMapping,
|
||||
timeAndFrom,
|
||||
} from '../../util/amis.ts'
|
||||
} from '../../util/amis.tsx'
|
||||
|
||||
function Table() {
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import {amisRender, commonInfo, paginationCommonOptions, serviceLogByAppName, yarnCrudColumns} from '../../util/amis.ts'
|
||||
import {amisRender, commonInfo, paginationCommonOptions, serviceLogByAppName, yarnCrudColumns} from '../../util/amis.tsx'
|
||||
|
||||
const Task: React.FC = () => {
|
||||
return (
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
paginationCommonOptions,
|
||||
readOnlyDialogOptions,
|
||||
timelineColumns,
|
||||
} from '../../util/amis.ts'
|
||||
} from '../../util/amis.tsx'
|
||||
|
||||
const Tool: React.FC = () => {
|
||||
return (
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
paginationCommonOptions,
|
||||
tableMetaDialog,
|
||||
versionUpdateStateMapping,
|
||||
} from '../../util/amis.ts'
|
||||
} from '../../util/amis.tsx'
|
||||
|
||||
function Version() {
|
||||
return (
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
paginationCommonOptions,
|
||||
yarnCrudColumns,
|
||||
yarnQueueCrud,
|
||||
} from '../../util/amis.ts'
|
||||
} from '../../util/amis.tsx'
|
||||
|
||||
const Yarn: React.FC = () => {
|
||||
const {clusters, queue, search} = useParams()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import {amisRender, commonInfo, yarnQueueCrud} from '../../util/amis.ts'
|
||||
import {amisRender, commonInfo, yarnQueueCrud} from '../../util/amis.tsx'
|
||||
|
||||
const YarnCluster: React.FC = () => {
|
||||
return (
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
CloudOutlined,
|
||||
ClusterOutlined,
|
||||
CompressOutlined,
|
||||
DatabaseOutlined,
|
||||
InfoCircleOutlined,
|
||||
OpenAIOutlined,
|
||||
QuestionOutlined,
|
||||
@@ -14,6 +15,9 @@ import {
|
||||
import {Navigate, type RouteObject} from 'react-router'
|
||||
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 Knowledge from './pages/ai/knowledge/Knowledge.tsx'
|
||||
import App from './pages/App.tsx'
|
||||
import Cloud from './pages/overview/Cloud.tsx'
|
||||
import Overview from './pages/overview/Overview.tsx'
|
||||
@@ -24,7 +28,7 @@ import Tool from './pages/overview/Tool.tsx'
|
||||
import Version from './pages/overview/Version.tsx'
|
||||
import Yarn from './pages/overview/Yarn.tsx'
|
||||
import YarnCluster from './pages/overview/YarnCluster.tsx'
|
||||
import {commonInfo} from './util/amis.ts'
|
||||
import {commonInfo} from './util/amis.tsx'
|
||||
|
||||
export const routes: RouteObject[] = [
|
||||
{
|
||||
@@ -86,6 +90,18 @@ export const routes: RouteObject[] = [
|
||||
path: 'conversation',
|
||||
Component: Conversation,
|
||||
},
|
||||
{
|
||||
path: 'knowledge',
|
||||
Component: Knowledge,
|
||||
},
|
||||
{
|
||||
path: 'knowledge/import/:name',
|
||||
Component: DataImport,
|
||||
},
|
||||
{
|
||||
path: 'knowledge/detail/:name',
|
||||
Component: DataDetail,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -179,6 +195,11 @@ export const menus = {
|
||||
name: '智能巡检',
|
||||
icon: <CheckSquareOutlined/>,
|
||||
},
|
||||
{
|
||||
path: '/ai/knowledge',
|
||||
name: '知识库',
|
||||
icon: <DatabaseOutlined/>,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {attachmentAdpator, makeTranslator, render, type Schema} from 'amis'
|
||||
import {AlertComponent, attachmentAdpator, makeTranslator, render, type Schema, ToastComponent} from 'amis'
|
||||
|
||||
import 'amis/lib/themes/antd.css'
|
||||
import 'amis/lib/helper.css'
|
||||
@@ -58,85 +58,99 @@ const responseAdaptor = () => (response: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
export const amisRender = (schema: Schema) => {
|
||||
return render(
|
||||
schema,
|
||||
{
|
||||
theme: 'antd',
|
||||
},
|
||||
{
|
||||
fetcher: async (api: any) => {
|
||||
let {url, method, data, responseType, config, headers} = api
|
||||
config = config || {}
|
||||
config.url = url
|
||||
config.withCredentials = true
|
||||
responseType && (config.responseType = responseType)
|
||||
export const amisRender = (schema: Schema, data: Record<any, any> = {}) => {
|
||||
const theme = 'antd'
|
||||
const locale = 'zh-CN'
|
||||
return (
|
||||
<>
|
||||
<ToastComponent
|
||||
theme={theme}
|
||||
key="toast"
|
||||
position={'top-right'}
|
||||
locale={locale}
|
||||
/>
|
||||
<AlertComponent theme={theme} key="alert" locale={locale}/>
|
||||
{render(
|
||||
schema,
|
||||
{
|
||||
data: data,
|
||||
theme: theme,
|
||||
},
|
||||
{
|
||||
fetcher: async (api: any) => {
|
||||
let {url, method, data, responseType, config, headers} = api
|
||||
config = config || {}
|
||||
config.url = url
|
||||
config.withCredentials = true
|
||||
responseType && (config.responseType = responseType)
|
||||
|
||||
if (config.cancelExecutor) {
|
||||
config.cancelToken = new (axios as any).CancelToken(
|
||||
config.cancelExecutor,
|
||||
)
|
||||
}
|
||||
|
||||
config.headers = headers || {}
|
||||
config.method = method
|
||||
config.data = data
|
||||
|
||||
if (method === 'get' && data) {
|
||||
config.params = data
|
||||
} else if (data && data instanceof FormData) {
|
||||
// config.headers['Content-Type'] = 'multipart/form-data';
|
||||
} else if (
|
||||
data &&
|
||||
typeof data !== 'string' &&
|
||||
!(data instanceof Blob) &&
|
||||
!(data instanceof ArrayBuffer)
|
||||
) {
|
||||
data = JSON.stringify(data)
|
||||
config.headers['Content-Type'] = 'application/json'
|
||||
}
|
||||
|
||||
// 支持返回各种报错信息
|
||||
config.validateStatus = function () {
|
||||
return true
|
||||
}
|
||||
|
||||
let response = await axios(config)
|
||||
response = await attachmentAdpator(response, __, api)
|
||||
response = responseAdaptor()(response)
|
||||
|
||||
if (response.status >= 400) {
|
||||
if (response.data) {
|
||||
// 主要用于 raw: 模式下,后端自己校验登录,
|
||||
if (
|
||||
response.status === 401 &&
|
||||
response.data.location &&
|
||||
response.data.location.startsWith('http')
|
||||
) {
|
||||
location.href = response.data.location.replace(
|
||||
'{{redirect}}',
|
||||
encodeURIComponent(location.href),
|
||||
)
|
||||
return new Promise(() => {
|
||||
})
|
||||
} else if (response.data.msg) {
|
||||
throw new Error(response.data.msg)
|
||||
} else {
|
||||
throw new Error(
|
||||
'System.requestError' + JSON.stringify(response.data, null, 2),
|
||||
if (config.cancelExecutor) {
|
||||
config.cancelToken = new (axios as any).CancelToken(
|
||||
config.cancelExecutor,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
`${'System.requestErrorStatus'} ${response.status}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return response
|
||||
},
|
||||
isCancel: (value: any) => (axios as any).isCancel(value),
|
||||
},
|
||||
config.headers = headers || {}
|
||||
config.method = method
|
||||
config.data = data
|
||||
|
||||
if (method === 'get' && data) {
|
||||
config.params = data
|
||||
} else if (data && data instanceof FormData) {
|
||||
// config.headers['Content-Type'] = 'multipart/form-data';
|
||||
} else if (
|
||||
data &&
|
||||
typeof data !== 'string' &&
|
||||
!(data instanceof Blob) &&
|
||||
!(data instanceof ArrayBuffer)
|
||||
) {
|
||||
data = JSON.stringify(data)
|
||||
config.headers['Content-Type'] = 'application/json'
|
||||
}
|
||||
|
||||
// 支持返回各种报错信息
|
||||
config.validateStatus = function () {
|
||||
return true
|
||||
}
|
||||
|
||||
let response = await axios(config)
|
||||
response = await attachmentAdpator(response, __, api)
|
||||
response = responseAdaptor()(response)
|
||||
|
||||
if (response.status >= 400) {
|
||||
if (response.data) {
|
||||
// 主要用于 raw: 模式下,后端自己校验登录,
|
||||
if (
|
||||
response.status === 401 &&
|
||||
response.data.location &&
|
||||
response.data.location.startsWith('http')
|
||||
) {
|
||||
location.href = response.data.location.replace(
|
||||
'{{redirect}}',
|
||||
encodeURIComponent(location.href),
|
||||
)
|
||||
return new Promise(() => {
|
||||
})
|
||||
} else if (response.data.msg) {
|
||||
throw new Error(response.data.msg)
|
||||
} else {
|
||||
throw new Error(
|
||||
'System.requestError' + JSON.stringify(response.data, null, 2),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
`${'System.requestErrorStatus'} ${response.status}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return response
|
||||
},
|
||||
isCancel: (value: any) => (axios as any).isCancel(value),
|
||||
},
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user