feat: add overview (#391)

### What problem does this PR solve?

feat: render stats charts
feat: create api token
feat: delete api token
feat: add ChatApiKeyModal
feat: add RagLineChart


Issue link: #345

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2024-04-16 19:06:47 +08:00
committed by GitHub
parent b3843138f4
commit ad6f0a1ce5
25 changed files with 1177 additions and 40 deletions

View File

@ -3,7 +3,7 @@ let api_host = `/v1`;
export { api_host };
export default {
// 用户
// user
login: `${api_host}/user/login`,
logout: `${api_host}/user/logout`,
register: `${api_host}/user/register`,
@ -12,21 +12,21 @@ export default {
tenant_info: `${api_host}/user/tenant_info`,
set_tenant_info: `${api_host}/user/set_tenant_info`,
// 模型管理
// llm model
factories_list: `${api_host}/llm/factories`,
llm_list: `${api_host}/llm/list`,
my_llm: `${api_host}/llm/my_llms`,
set_api_key: `${api_host}/llm/set_api_key`,
add_llm: `${api_host}/llm/add_llm`,
//知识库管理
// knowledge base
kb_list: `${api_host}/kb/list`,
create_kb: `${api_host}/kb/create`,
update_kb: `${api_host}/kb/update`,
rm_kb: `${api_host}/kb/rm`,
get_kb_detail: `${api_host}/kb/detail`,
// chunk管理
// chunk
chunk_list: `${api_host}/chunk/list`,
create_chunk: `${api_host}/chunk/create`,
set_chunk: `${api_host}/chunk/set`,
@ -35,7 +35,7 @@ export default {
rm_chunk: `${api_host}/chunk/rm`,
retrieval_test: `${api_host}/chunk/retrieval_test`,
// 文件管理
// document
upload: `${api_host}/document/upload`,
get_document_list: `${api_host}/document/list`,
document_change_status: `${api_host}/document/change_status`,
@ -48,14 +48,22 @@ export default {
get_document_file: `${api_host}/document/get`,
document_upload: `${api_host}/document/upload`,
// chat
setDialog: `${api_host}/dialog/set`,
getDialog: `${api_host}/dialog/get`,
removeDialog: `${api_host}/dialog/rm`,
listDialog: `${api_host}/dialog/list`,
setConversation: `${api_host}/conversation/set`,
getConversation: `${api_host}/conversation/get`,
listConversation: `${api_host}/conversation/list`,
removeConversation: `${api_host}/conversation/rm`,
completeConversation: `${api_host}/conversation/completion`,
// chat for external
createToken: `${api_host}/api/new_token`,
listToken: `${api_host}/api/token_list`,
removeToken: `${api_host}/api/rm`,
getStats: `${api_host}/api/stats`,
createExternalConversation: `${api_host}/api/new_conversation`,
getExternalConversation: `${api_host}/api/conversation`,
completeExternalConversation: `${api_host}/api/completion`,
};

View File

@ -0,0 +1,17 @@
import isObject from 'lodash/isObject';
import snakeCase from 'lodash/snakeCase';
export const isFormData = (data: unknown): data is FormData => {
return data instanceof FormData;
};
export const convertTheKeysOfTheObjectToSnake = (data: unknown) => {
if (isObject(data) && !isFormData(data)) {
return Object.keys(data).reduce<Record<string, any>>((pre, cur) => {
const value = (data as Record<string, any>)[cur];
pre[isFormData(value) ? cur : snakeCase(cur)] = value;
return pre;
}, {});
}
return data;
};

View File

@ -1,20 +1,20 @@
import moment from 'moment';
import dayjs from 'dayjs';
export function today() {
return formatDate(moment());
return formatDate(dayjs());
}
export function lastDay() {
return formatDate(moment().subtract(1, 'days'));
return formatDate(dayjs().subtract(1, 'days'));
}
export function lastWeek() {
return formatDate(moment().subtract(1, 'weeks'));
return formatDate(dayjs().subtract(1, 'weeks'));
}
export function formatDate(date: any) {
if (!date) {
return '';
}
return moment(date).format('DD/MM/YYYY');
return dayjs(date).format('DD/MM/YYYY');
}

View File

@ -8,16 +8,20 @@ const registerServer = <T extends string>(
) => {
const server: Service<T> = {} as Service<T>;
for (let key in opt) {
server[key] = (params) => {
server[key] = (params: any, urlAppendix?: string) => {
let url = opt[key].url;
if (urlAppendix) {
url = url + '/' + urlAppendix;
}
if (opt[key].method === 'post' || opt[key].method === 'POST') {
return request(opt[key].url, {
return request(url, {
method: opt[key].method,
data: params,
});
}
if (opt[key].method === 'get' || opt[key].method === 'GET') {
return request.get(opt[key].url, {
return request.get(url, {
params,
});
}

View File

@ -4,6 +4,7 @@ import authorizationUtil from '@/utils/authorizationUtil';
import { message, notification } from 'antd';
import { history } from 'umi';
import { RequestMethod, extend } from 'umi-request';
import { convertTheKeysOfTheObjectToSnake } from './commonUtil';
const ABORT_REQUEST_ERR_MESSAGE = 'The user aborted a request.'; // 手动中断请求。errorHandler 抛出的error message
@ -87,10 +88,15 @@ const request: RequestMethod = extend({
request.interceptors.request.use((url: string, options: any) => {
const authorization = authorizationUtil.getAuthorization();
const data = convertTheKeysOfTheObjectToSnake(options.data);
const params = convertTheKeysOfTheObjectToSnake(options.params);
return {
url,
options: {
...options,
// data,
// params,
headers: {
...(options.skipToken ? undefined : { [Authorization]: authorization }),
...options.headers,