mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-04-22 22:20:07 +08:00
### What problem does this PR solve? feat: Bind data to TenantTable #2846 feat: Add TenantTable ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
791afbba15
commit
cf3106040a
@ -2,8 +2,19 @@ import { LanguageTranslationMap } from '@/constants/common';
|
||||
import { ResponseGetType } from '@/interfaces/database/base';
|
||||
import { IToken } from '@/interfaces/database/chat';
|
||||
import { ITenantInfo } from '@/interfaces/database/knowledge';
|
||||
import { ISystemStatus, IUserInfo } from '@/interfaces/database/user-setting';
|
||||
import userService from '@/services/user-service';
|
||||
import {
|
||||
ISystemStatus,
|
||||
ITenant,
|
||||
ITenantUser,
|
||||
IUserInfo,
|
||||
} from '@/interfaces/database/user-setting';
|
||||
import userService, {
|
||||
addTenantUser,
|
||||
agreeTenant,
|
||||
deleteTenantUser,
|
||||
listTenant,
|
||||
listTenantUser,
|
||||
} from '@/services/user-service';
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { Modal, message } from 'antd';
|
||||
import DOMPurify from 'dompurify';
|
||||
@ -215,3 +226,125 @@ export const useCreateSystemToken = () => {
|
||||
|
||||
return { data, loading, createToken: mutateAsync };
|
||||
};
|
||||
|
||||
export const useListTenantUser = () => {
|
||||
const { data: tenantInfo } = useFetchTenantInfo();
|
||||
const tenantId = tenantInfo.tenant_id;
|
||||
const {
|
||||
data,
|
||||
isFetching: loading,
|
||||
refetch,
|
||||
} = useQuery<ITenantUser[]>({
|
||||
queryKey: ['listTenantUser', tenantId],
|
||||
initialData: [],
|
||||
gcTime: 0,
|
||||
enabled: !!tenantId,
|
||||
queryFn: async () => {
|
||||
const { data } = await listTenantUser(tenantId);
|
||||
|
||||
return data?.data ?? [];
|
||||
},
|
||||
});
|
||||
|
||||
return { data, loading, refetch };
|
||||
};
|
||||
|
||||
export const useAddTenantUser = () => {
|
||||
const { data: tenantInfo } = useFetchTenantInfo();
|
||||
const queryClient = useQueryClient();
|
||||
const {
|
||||
data,
|
||||
isPending: loading,
|
||||
mutateAsync,
|
||||
} = useMutation({
|
||||
mutationKey: ['addTenantUser'],
|
||||
mutationFn: async (email: string) => {
|
||||
const { data } = await addTenantUser(tenantInfo.tenant_id, email);
|
||||
if (data.retcode === 0) {
|
||||
queryClient.invalidateQueries({ queryKey: ['listTenantUser'] });
|
||||
}
|
||||
return data?.retcode;
|
||||
},
|
||||
});
|
||||
|
||||
return { data, loading, addTenantUser: mutateAsync };
|
||||
};
|
||||
|
||||
export const useDeleteTenantUser = () => {
|
||||
const { data: tenantInfo } = useFetchTenantInfo();
|
||||
const queryClient = useQueryClient();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const {
|
||||
data,
|
||||
isPending: loading,
|
||||
mutateAsync,
|
||||
} = useMutation({
|
||||
mutationKey: ['deleteTenantUser'],
|
||||
mutationFn: async ({
|
||||
userId,
|
||||
tenantId,
|
||||
}: {
|
||||
userId: string;
|
||||
tenantId?: string;
|
||||
}) => {
|
||||
const { data } = await deleteTenantUser({
|
||||
tenantId: tenantId ?? tenantInfo.tenant_id,
|
||||
userId,
|
||||
});
|
||||
if (data.retcode === 0) {
|
||||
message.success(t('message.deleted'));
|
||||
queryClient.invalidateQueries({ queryKey: ['listTenantUser'] });
|
||||
queryClient.invalidateQueries({ queryKey: ['listTenant'] });
|
||||
}
|
||||
return data?.data ?? [];
|
||||
},
|
||||
});
|
||||
|
||||
return { data, loading, deleteTenantUser: mutateAsync };
|
||||
};
|
||||
|
||||
export const useListTenant = () => {
|
||||
const { data: tenantInfo } = useFetchTenantInfo();
|
||||
const tenantId = tenantInfo.tenant_id;
|
||||
const {
|
||||
data,
|
||||
isFetching: loading,
|
||||
refetch,
|
||||
} = useQuery<ITenant[]>({
|
||||
queryKey: ['listTenant', tenantId],
|
||||
initialData: [],
|
||||
gcTime: 0,
|
||||
enabled: !!tenantId,
|
||||
queryFn: async () => {
|
||||
const { data } = await listTenant();
|
||||
|
||||
return data?.data ?? [];
|
||||
},
|
||||
});
|
||||
|
||||
return { data, loading, refetch };
|
||||
};
|
||||
|
||||
export const useAgreeTenant = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const {
|
||||
data,
|
||||
isPending: loading,
|
||||
mutateAsync,
|
||||
} = useMutation({
|
||||
mutationKey: ['agreeTenant'],
|
||||
mutationFn: async (tenantId: string) => {
|
||||
const { data } = await agreeTenant(tenantId);
|
||||
if (data.retcode === 0) {
|
||||
message.success(t('message.operated'));
|
||||
queryClient.invalidateQueries({ queryKey: ['listTenant'] });
|
||||
}
|
||||
return data?.data ?? [];
|
||||
},
|
||||
});
|
||||
|
||||
return { data, loading, agreeTenant: mutateAsync };
|
||||
};
|
||||
|
@ -60,3 +60,28 @@ interface Es {
|
||||
number_of_nodes: number;
|
||||
active_shards: number;
|
||||
}
|
||||
|
||||
export interface ITenantUser {
|
||||
avatar: null;
|
||||
delta_seconds: number;
|
||||
email: string;
|
||||
is_active: string;
|
||||
is_anonymous: string;
|
||||
is_authenticated: string;
|
||||
is_superuser: boolean;
|
||||
nickname: string;
|
||||
role: string;
|
||||
status: string;
|
||||
update_date: string;
|
||||
user_id: string;
|
||||
}
|
||||
|
||||
export interface ITenant {
|
||||
avatar: string;
|
||||
delta_seconds: number;
|
||||
email: string;
|
||||
nickname: string;
|
||||
role: string;
|
||||
tenant_id: string;
|
||||
update_date: string;
|
||||
}
|
||||
|
@ -27,7 +27,8 @@ export default {
|
||||
close: 'Close',
|
||||
preview: 'Preview',
|
||||
move: 'Move',
|
||||
warn: '提醒',
|
||||
warn: 'Warn',
|
||||
action: 'Action',
|
||||
},
|
||||
login: {
|
||||
login: 'Sign in',
|
||||
@ -584,6 +585,14 @@ The above is the content you need to summarize.`,
|
||||
'Please add both embedding model and LLM in <b>Settings > Model providers</b> firstly.',
|
||||
apiVersion: 'API-Version',
|
||||
apiVersionMessage: 'Please input API version',
|
||||
add: 'Add',
|
||||
updateDate: 'Update Date',
|
||||
role: 'Role',
|
||||
invite: 'Invite',
|
||||
agree: 'Agree',
|
||||
refuse: 'Refuse',
|
||||
teamMembers: 'Team Members',
|
||||
joinedTeams: 'Joined Teams',
|
||||
},
|
||||
message: {
|
||||
registered: 'Registered!',
|
||||
|
@ -28,6 +28,7 @@ export default {
|
||||
preview: '預覽',
|
||||
move: '移動',
|
||||
warn: '提醒',
|
||||
action: '操作',
|
||||
},
|
||||
login: {
|
||||
login: '登入',
|
||||
@ -540,6 +541,14 @@ export default {
|
||||
GoogleRegionMessage: '請輸入 Google Cloud 區域',
|
||||
modelProvidersWarn:
|
||||
'請先在 <b>「設定」>「模型提供者」</b> 中新增嵌入模型和LLM。',
|
||||
add: '添加',
|
||||
updateDate: '更新日期',
|
||||
role: '角色',
|
||||
invite: '邀請',
|
||||
agree: '同意',
|
||||
refuse: '拒絕',
|
||||
teamMembers: '團隊成員',
|
||||
joinedTeams: '加入的團隊',
|
||||
},
|
||||
message: {
|
||||
registered: '註冊成功',
|
||||
|
@ -28,6 +28,7 @@ export default {
|
||||
preview: '预览',
|
||||
move: '移动',
|
||||
warn: '提醒',
|
||||
action: '操作',
|
||||
},
|
||||
login: {
|
||||
login: '登录',
|
||||
@ -559,6 +560,14 @@ export default {
|
||||
'请首先在 <b>设置 > 模型提供商</b> 中添加嵌入模型和 LLM。',
|
||||
apiVersion: 'API版本',
|
||||
apiVersionMessage: '请输入API版本!',
|
||||
add: '添加',
|
||||
updateDate: '更新日期',
|
||||
role: '角色',
|
||||
invite: '邀请',
|
||||
agree: '同意',
|
||||
refuse: '拒绝',
|
||||
teamMembers: '团队成员',
|
||||
joinedTeams: '加入的团队',
|
||||
},
|
||||
message: {
|
||||
registered: '注册成功',
|
||||
|
@ -30,3 +30,9 @@ export const LocalLlmFactories = [
|
||||
'OpenRouter',
|
||||
'HuggingFace',
|
||||
];
|
||||
|
||||
export enum TenantRole {
|
||||
Owner = 'owner',
|
||||
Invite = 'invite',
|
||||
Normal = 'normal',
|
||||
}
|
||||
|
52
web/src/pages/user-setting/setting-team/add-user-modal.tsx
Normal file
52
web/src/pages/user-setting/setting-team/add-user-modal.tsx
Normal file
@ -0,0 +1,52 @@
|
||||
import { IModalProps } from '@/interfaces/common';
|
||||
import { Form, Input, Modal } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const AddingUserModal = ({
|
||||
visible,
|
||||
hideModal,
|
||||
loading,
|
||||
onOk,
|
||||
}: IModalProps<string>) => {
|
||||
const [form] = Form.useForm();
|
||||
const { t } = useTranslation();
|
||||
|
||||
type FieldType = {
|
||||
email?: string;
|
||||
};
|
||||
|
||||
const handleOk = async () => {
|
||||
const ret = await form.validateFields();
|
||||
|
||||
return onOk?.(ret.email);
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={t('setting.add')}
|
||||
open={visible}
|
||||
onOk={handleOk}
|
||||
onCancel={hideModal}
|
||||
okButtonProps={{ loading }}
|
||||
confirmLoading={loading}
|
||||
>
|
||||
<Form
|
||||
name="basic"
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }}
|
||||
autoComplete="off"
|
||||
form={form}
|
||||
>
|
||||
<Form.Item<FieldType>
|
||||
label={t('setting.email')}
|
||||
name="email"
|
||||
rules={[{ required: true, message: t('namePlaceholder') }]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddingUserModal;
|
68
web/src/pages/user-setting/setting-team/hooks.ts
Normal file
68
web/src/pages/user-setting/setting-team/hooks.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import { useSetModalState, useShowDeleteConfirm } from '@/hooks/common-hooks';
|
||||
import {
|
||||
useAddTenantUser,
|
||||
useAgreeTenant,
|
||||
useDeleteTenantUser,
|
||||
useFetchUserInfo,
|
||||
} from '@/hooks/user-setting-hooks';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const useAddUser = () => {
|
||||
const { addTenantUser } = useAddTenantUser();
|
||||
const {
|
||||
visible: addingTenantModalVisible,
|
||||
hideModal: hideAddingTenantModal,
|
||||
showModal: showAddingTenantModal,
|
||||
} = useSetModalState();
|
||||
|
||||
const handleAddUserOk = useCallback(
|
||||
async (email: string) => {
|
||||
const retcode = await addTenantUser(email);
|
||||
if (retcode === 0) {
|
||||
hideAddingTenantModal();
|
||||
}
|
||||
},
|
||||
[addTenantUser, hideAddingTenantModal],
|
||||
);
|
||||
|
||||
return {
|
||||
addingTenantModalVisible,
|
||||
hideAddingTenantModal,
|
||||
showAddingTenantModal,
|
||||
handleAddUserOk,
|
||||
};
|
||||
};
|
||||
|
||||
export const useHandleDeleteUser = () => {
|
||||
const { deleteTenantUser, loading } = useDeleteTenantUser();
|
||||
const showDeleteConfirm = useShowDeleteConfirm();
|
||||
|
||||
const handleDeleteTenantUser = (userId: string) => () => {
|
||||
showDeleteConfirm({
|
||||
onOk: async () => {
|
||||
const retcode = await deleteTenantUser({ userId });
|
||||
if (retcode === 0) {
|
||||
}
|
||||
return;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return { handleDeleteTenantUser, loading };
|
||||
};
|
||||
|
||||
export const useHandleAgreeTenant = () => {
|
||||
const { agreeTenant } = useAgreeTenant();
|
||||
const { deleteTenantUser } = useDeleteTenantUser();
|
||||
const { data: user } = useFetchUserInfo();
|
||||
|
||||
const handleAgree = (tenantId: string, isAgree: boolean) => () => {
|
||||
if (isAgree) {
|
||||
agreeTenant(tenantId);
|
||||
} else {
|
||||
deleteTenantUser({ tenantId, userId: user.id });
|
||||
}
|
||||
};
|
||||
|
||||
return { handleAgree };
|
||||
};
|
@ -1,5 +1,8 @@
|
||||
.teamWrapper {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
.teamCard {
|
||||
// width: 100%;
|
||||
}
|
||||
|
@ -1,25 +1,70 @@
|
||||
import { Button, Card, Flex } from 'antd';
|
||||
import {
|
||||
useFetchUserInfo,
|
||||
useListTenantUser,
|
||||
} from '@/hooks/user-setting-hooks';
|
||||
import { Button, Card, Flex, Space } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
|
||||
import { TeamOutlined, UserAddOutlined, UserOutlined } from '@ant-design/icons';
|
||||
import AddingUserModal from './add-user-modal';
|
||||
import { useAddUser } from './hooks';
|
||||
import styles from './index.less';
|
||||
import TenantTable from './tenant-table';
|
||||
import UserTable from './user-table';
|
||||
|
||||
const iconStyle = { fontSize: 20, color: '#1677ff' };
|
||||
|
||||
const UserSettingTeam = () => {
|
||||
const { data: userInfo } = useFetchUserInfo();
|
||||
const { t } = useTranslate('setting');
|
||||
const { t } = useTranslation();
|
||||
useListTenantUser();
|
||||
const {
|
||||
addingTenantModalVisible,
|
||||
hideAddingTenantModal,
|
||||
showAddingTenantModal,
|
||||
handleAddUserOk,
|
||||
} = useAddUser();
|
||||
|
||||
return (
|
||||
<div className={styles.teamWrapper}>
|
||||
<Card className={styles.teamCard}>
|
||||
<Flex align="center" justify={'space-between'}>
|
||||
<span>
|
||||
{userInfo.nickname} {t('workspace')}
|
||||
{userInfo.nickname} {t('setting.workspace')}
|
||||
</span>
|
||||
<Button type="primary" disabled>
|
||||
{t('upgrade')}
|
||||
<Button type="primary" onClick={showAddingTenantModal}>
|
||||
<UserAddOutlined />
|
||||
{t('setting.invite')}
|
||||
</Button>
|
||||
</Flex>
|
||||
</Card>
|
||||
<Card
|
||||
title={
|
||||
<Space>
|
||||
<UserOutlined style={iconStyle} /> {t('setting.teamMembers')}
|
||||
</Space>
|
||||
}
|
||||
bordered={false}
|
||||
>
|
||||
<UserTable></UserTable>
|
||||
</Card>
|
||||
<Card
|
||||
title={
|
||||
<Space>
|
||||
<TeamOutlined style={iconStyle} /> {t('setting.joinedTeams')}
|
||||
</Space>
|
||||
}
|
||||
bordered={false}
|
||||
>
|
||||
<TenantTable></TenantTable>
|
||||
</Card>
|
||||
{addingTenantModalVisible && (
|
||||
<AddingUserModal
|
||||
visible
|
||||
hideModal={hideAddingTenantModal}
|
||||
onOk={handleAddUserOk}
|
||||
></AddingUserModal>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
65
web/src/pages/user-setting/setting-team/tenant-table.tsx
Normal file
65
web/src/pages/user-setting/setting-team/tenant-table.tsx
Normal file
@ -0,0 +1,65 @@
|
||||
import { useListTenant } from '@/hooks/user-setting-hooks';
|
||||
import { ITenant } from '@/interfaces/database/user-setting';
|
||||
import { formatDate } from '@/utils/date';
|
||||
import type { TableProps } from 'antd';
|
||||
import { Button, Space, Table } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { TenantRole } from '../constants';
|
||||
import { useHandleAgreeTenant } from './hooks';
|
||||
|
||||
const TenantTable = () => {
|
||||
const { t } = useTranslation();
|
||||
const { data, loading } = useListTenant();
|
||||
const { handleAgree } = useHandleAgreeTenant();
|
||||
|
||||
const columns: TableProps<ITenant>['columns'] = [
|
||||
{
|
||||
title: t('common.name'),
|
||||
dataIndex: 'nickname',
|
||||
key: 'nickname',
|
||||
},
|
||||
{
|
||||
title: t('setting.email'),
|
||||
dataIndex: 'email',
|
||||
key: 'email',
|
||||
},
|
||||
{
|
||||
title: t('setting.updateDate'),
|
||||
dataIndex: 'update_date',
|
||||
key: 'update_date',
|
||||
render(value) {
|
||||
return formatDate(value);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('common.action'),
|
||||
key: 'action',
|
||||
render: (_, { role, tenant_id }) => {
|
||||
if (role === TenantRole.Invite) {
|
||||
return (
|
||||
<Space>
|
||||
<Button type="link" onClick={handleAgree(tenant_id, true)}>
|
||||
{t(`setting.agree`)}
|
||||
</Button>
|
||||
<Button type="link" onClick={handleAgree(tenant_id, false)}>
|
||||
{t(`setting.refuse`)}
|
||||
</Button>
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Table<ITenant>
|
||||
columns={columns}
|
||||
dataSource={data}
|
||||
rowKey={'tenant_id'}
|
||||
loading={loading}
|
||||
pagination={false}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default TenantTable;
|
73
web/src/pages/user-setting/setting-team/user-table.tsx
Normal file
73
web/src/pages/user-setting/setting-team/user-table.tsx
Normal file
@ -0,0 +1,73 @@
|
||||
import { useListTenantUser } from '@/hooks/user-setting-hooks';
|
||||
import { ITenantUser } from '@/interfaces/database/user-setting';
|
||||
import { formatDate } from '@/utils/date';
|
||||
import { DeleteOutlined } from '@ant-design/icons';
|
||||
import type { TableProps } from 'antd';
|
||||
import { Button, Table, Tag } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { TenantRole } from '../constants';
|
||||
import { useHandleDeleteUser } from './hooks';
|
||||
|
||||
const ColorMap = {
|
||||
[TenantRole.Normal]: 'green',
|
||||
[TenantRole.Invite]: 'orange',
|
||||
[TenantRole.Owner]: 'red',
|
||||
};
|
||||
|
||||
const UserTable = () => {
|
||||
const { data, loading } = useListTenantUser();
|
||||
const { handleDeleteTenantUser } = useHandleDeleteUser();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const columns: TableProps<ITenantUser>['columns'] = [
|
||||
{
|
||||
title: t('common.name'),
|
||||
dataIndex: 'nickname',
|
||||
key: 'nickname',
|
||||
},
|
||||
{
|
||||
title: t('setting.email'),
|
||||
dataIndex: 'email',
|
||||
key: 'email',
|
||||
},
|
||||
{
|
||||
title: t('setting.role'),
|
||||
dataIndex: 'role',
|
||||
key: 'role',
|
||||
render(value, { role }) {
|
||||
return (
|
||||
<Tag color={ColorMap[role as keyof typeof ColorMap]}>{role}</Tag>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('setting.updateDate'),
|
||||
dataIndex: 'update_date',
|
||||
key: 'update_date',
|
||||
render(value) {
|
||||
return formatDate(value);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('common.action'),
|
||||
key: 'action',
|
||||
render: (_, record) => (
|
||||
<Button type="text" onClick={handleDeleteTenantUser(record.user_id)}>
|
||||
<DeleteOutlined size={20} />
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Table<ITenantUser>
|
||||
rowKey={'user_id'}
|
||||
columns={columns}
|
||||
dataSource={data}
|
||||
loading={loading}
|
||||
pagination={false}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default UserTable;
|
@ -1,6 +1,6 @@
|
||||
import api from '@/utils/api';
|
||||
import registerServer from '@/utils/register-server';
|
||||
import request from '@/utils/request';
|
||||
import request, { post } from '@/utils/request';
|
||||
|
||||
const {
|
||||
login,
|
||||
@ -105,4 +105,23 @@ const methods = {
|
||||
|
||||
const userService = registerServer<keyof typeof methods>(methods, request);
|
||||
|
||||
export const listTenantUser = (tenantId: string) =>
|
||||
request.get(api.listTenantUser(tenantId));
|
||||
|
||||
export const addTenantUser = (tenantId: string, email: string) =>
|
||||
post(api.addTenantUser(tenantId), { email });
|
||||
|
||||
export const deleteTenantUser = ({
|
||||
tenantId,
|
||||
userId,
|
||||
}: {
|
||||
tenantId: string;
|
||||
userId: string;
|
||||
}) => request.delete(api.deleteTenantUser(tenantId, userId));
|
||||
|
||||
export const listTenant = () => request.get(api.listTenant);
|
||||
|
||||
export const agreeTenant = (tenantId: string) =>
|
||||
request.put(api.agreeTenant(tenantId));
|
||||
|
||||
export default userService;
|
||||
|
@ -12,6 +12,15 @@ export default {
|
||||
tenant_info: `${api_host}/user/tenant_info`,
|
||||
set_tenant_info: `${api_host}/user/set_tenant_info`,
|
||||
|
||||
// team
|
||||
addTenantUser: (tenantId: string) => `${api_host}/tenant/${tenantId}/user`,
|
||||
listTenantUser: (tenantId: string) =>
|
||||
`${api_host}/tenant/${tenantId}/user/list`,
|
||||
deleteTenantUser: (tenantId: string, userId: string) =>
|
||||
`${api_host}/tenant/${tenantId}/user/${userId}`,
|
||||
listTenant: `${api_host}/tenant/list`,
|
||||
agreeTenant: (tenantId: string) => `${api_host}/tenant/agree/${tenantId}`,
|
||||
|
||||
// llm model
|
||||
factories_list: `${api_host}/llm/factories`,
|
||||
llm_list: `${api_host}/llm/list`,
|
||||
|
@ -135,3 +135,15 @@ request.interceptors.response.use(async (response: any, options) => {
|
||||
});
|
||||
|
||||
export default request;
|
||||
|
||||
export const get = (url: string) => {
|
||||
return request.get(url);
|
||||
};
|
||||
|
||||
export const post = (url: string, body: any) => {
|
||||
return request.post(url, { data: body });
|
||||
};
|
||||
|
||||
export const drop = () => {};
|
||||
|
||||
export const put = () => {};
|
||||
|
Loading…
x
Reference in New Issue
Block a user