Преглед на файлове

add: tanent,tanent-package

dev
powersir преди 1 година
родител
ревизия
c61626599e
променени са 13 файла, в които са добавени 895 реда и са изтрити 1 реда
  1. +1
    -0
      src/models/index.ts
  2. +49
    -0
      src/models/tenant.data.ts
  3. +1
    -0
      src/pages/system/dept/create-department.tsx
  4. +1
    -0
      src/pages/system/menu/menu-editor.tsx
  5. +1
    -0
      src/pages/system/post/create-position.tsx
  6. +1
    -0
      src/pages/system/role/role-editor.tsx
  7. +235
    -0
      src/pages/system/tenant/list/index.tsx
  8. +194
    -0
      src/pages/system/tenant/list/tenant-editor.tsx
  9. +184
    -0
      src/pages/system/tenant/package/index.tsx
  10. +143
    -0
      src/pages/system/tenant/package/tenant-pkg-editor.tsx
  11. +8
    -1
      src/request/service/menu.ts
  12. +38
    -0
      src/request/service/tenant-package.ts
  13. +39
    -0
      src/request/service/tenant.ts

+ 1
- 0
src/models/index.ts Целия файл

@@ -3,6 +3,7 @@ export * from './product.data.ts'
export * from './role.data.ts'
export * from './position.data.ts'
export * from './department.data.ts'
export * from './tenant.data.ts'

export interface ResponseDTO<T>{
code: number;


+ 49
- 0
src/models/tenant.data.ts Целия файл

@@ -0,0 +1,49 @@
export interface TenantVO {
id: number
name: string
contactName: string
contactMobile: string
status: number
domain: string
packageId: number
username: string
password: string
expireTime: Date
accountCount: number
createTime: Date
}

export interface TenantPageReqVO extends PageParam {
name?: string
contactName?: string
contactMobile?: string
status?: number
createTime?: Date[]
}

export interface TenantExportReqVO {
name?: string
contactName?: string
contactMobile?: string
status?: number
createTime?: Date[]
}

export interface TenantPackageVO {
id: number
name: string
status: number
remark: string
creator: string
updater: string
updateTime: string
menuIds: number[]
createTime: Date
}

export interface TenantPackagePageReqVO extends PageParam {
name?: string
status?: number
remark?: string
createTime?: Date[]
}

+ 1
- 0
src/pages/system/dept/create-department.tsx Целия файл

@@ -66,6 +66,7 @@ const DepartmentEditor: React.FC<EditorProps> = (props) => {
width={640}
onOk={save}
onCancel={() => onCancel()}
confirmLoading= {saveLoading}
destroyOnClose
>
<Form


+ 1
- 0
src/pages/system/menu/menu-editor.tsx Целия файл

@@ -162,6 +162,7 @@ const MenuEditor: React.FC<MenuEditorProps> = (props) => {
width={640}
onOk={save}
onCancel={() => onCancel()}
confirmLoading= {saveLoading}
destroyOnClose
>
<Form


+ 1
- 0
src/pages/system/post/create-position.tsx Целия файл

@@ -66,6 +66,7 @@ const PositionEditor: React.FC<EditorProps> = (props) => {
width={640}
onOk={save}
onCancel={() => onCancel()}
confirmLoading= {saveLoading}
destroyOnClose
>
<Form


+ 1
- 0
src/pages/system/role/role-editor.tsx Целия файл

@@ -67,6 +67,7 @@ const RoleEditor: React.FC<RoleEditorProps> = (props) => {
width={640}
onOk={save}
onCancel={() => onCancel()}
confirmLoading= {saveLoading}
destroyOnClose
>
<Form


+ 235
- 0
src/pages/system/tenant/list/index.tsx Целия файл

@@ -0,0 +1,235 @@
import { Space, Table, Button, Input, Select, Divider, Tag, Card, Badge, Form } from 'antd';
import type { TableColumnsType } from 'antd';
import { t } from '@/utils/i18n';
import React, { useState, useEffect } from 'react';
import { PlusOutlined, ExclamationCircleFilled, SearchOutlined, UndoOutlined } from '@ant-design/icons';
import type { TenantVO } from '@/models'
import { antdUtils } from '@/utils/antd';
import { useRequest } from '@/hooks/use-request';
import tenantService from '@/request/service/tenant';
import { formatDate } from '@/utils/formatTime'
import TenantEditor from './tenant-editor';

export default () => {

const [editorVisable, seEditorVisable] = useState<boolean>(false);
const [editData, seEditData] = useState<TenantVO>();
const [dataSource, setDataSource] = useState<TenantVO[]>([]);
const [searchFrom] = Form.useForm();


const { runAsync: getPageApi } = useRequest(tenantService.getTenantPageApi, { manual: true });
const { runAsync: deleteApi } = useRequest(tenantService.deleteTenantApi, { manual: true });

const load = async () => {
const [error, { data }] = await getPageApi(searchFrom.getFieldsValue());
if (!error) {
setDataSource(data.list);
}
};


const showDeleteConfirm = (data: TenantVO) => {
antdUtils.modal?.confirm({
title: '确认要将该菜单删除吗?',
icon: <ExclamationCircleFilled />,
content: '请注意删除以后不可恢复!',
okText: '删除',
okType: 'danger',
cancelText: '取消',
onOk() {
return new Promise(async (resolve) => {
const [error, { code, msg }] = await deleteApi(data.id);
if (error || code !== 0) {
antdUtils.message?.open({ type: 'error', content: msg ?? '操作失败' })
} else {
antdUtils.message?.open({ type: 'success', content: '删除成功' })
}
await load();
resolve('')
}).catch(() => antdUtils.message?.open({
type: 'error',
content: '操作失败',
}));
},
onCancel() {
},
});
};










const columns: TableColumnsType<TenantVO> = [
{
title: '租户编号',
dataIndex: 'id',
key: 'id',
align: 'right',
width: 100,
},
{
title: '租户名称',
dataIndex: 'name',
key: 'name',
align: 'center',
width: 150,
},
{
title: '租户套餐',
dataIndex: 'packageId',
key: 'packageId',
align: 'center',
width: 100,
},
{
title: '联系人',
dataIndex: 'contactName',
key: 'contactName',
align: 'center',
width: 150
},
{
title: '联系手机',
dataIndex: 'contactMobile',
key: 'contactMobile',
align: 'center',
width: 150
},
{
title: '账号额度',
dataIndex: 'accountCount',
key: 'accountCount',
align: 'center',
width: 150
},
{
title: '过期时间',
key: 'expireTime',
dataIndex: 'expireTime',
width: 200,
align: 'center',
render: (value: number) => {
return formatDate(new Date(value), "YYYY-mm-dd HH:MM:SS")
}
},
{
title: '绑定域名',
dataIndex: 'domain',
key: 'domain',
align: 'center',
width: 200
},
{
title: '租户状态',
key: 'status',
dataIndex: 'status',
width: 100,
align: 'center',
render: (value: number) => {
return (value === 0 ? <Badge status="success" text="已开启" /> : <Badge status="error" text="已关闭" />)
}
},
{
title: '创建时间',
key: 'createTime',
dataIndex: 'createTime',
width: 200,
render: (value: number) => {
return formatDate(new Date(value), "YYYY-mm-dd HH:MM:SS")
}
},
{
title: t("QkOmYwne" /* 操作 */),
key: 'action',
render: (value: TenantVO, record) => (
<Space size="small" split={(<Divider type='vertical' />)}>
<a onClick={() => {
seEditData(value);
seEditorVisable(true);
}}>
编辑
</a>
<a onClick={() => {
showDeleteConfirm(value)
}}>
删除
</a>
</Space>
),
},
];

useEffect(() => {
load();
}, []);

const onReset = () => {
searchFrom.resetFields()
load()
}

return (
<>
<div>
<Card className='mt-[4px] dark:bg-[rgb(33,41,70)] bg-white roundle-lg px[12px]' bodyStyle={{ paddingTop: 4, paddingBottom: 4 }}>
<div className='flex justify-between content-center'>
<div className='flex justify-normal items-center'>
<Form layout='inline' form={searchFrom}>
<Form.Item name="name" label="租户名称">
<Input className='w-[150px]' placeholder='请输入名称' allowClear />
</Form.Item>
<Form.Item name="contactName" label="租户名称">
<Input className='w-[150px]' placeholder='请输入联系人' allowClear />
</Form.Item>
<Form.Item name="contactMobile" label="联系人手机">
<Input className='w-[160px]' placeholder='请输入联系人手机' allowClear />
</Form.Item>
<Form.Item className='ml-2 w-[130px]' name="status" label="状态">
<Select placeholder="请选择" allowClear >
<Select.Option value="">全部</Select.Option>
<Select.Option value="0">开启</Select.Option>
<Select.Option value="1">关闭</Select.Option>
</Select>
</Form.Item>
</Form>
<Space.Compact className="ml-5">
<Button type='primary' size='large' icon={<SearchOutlined />} onClick={load}> 搜索 </Button>
<Button type='primary' size='large' icon={<UndoOutlined />} onClick={onReset}> 重置 </Button>
</Space.Compact>
</div>
<div className="py-[4px]">
<Button className="ml-5" type='primary' size='large' icon={<PlusOutlined />} onClick={() => {
seEditData(undefined);
seEditorVisable(true);
}}> 新增租户 </Button>
</div>
</div>
</Card>
<Card className='mt-[4px] dark:bg-[rgb(33,41,70)] bg-white roundle-lg px[12px]'>
<Table rowKey="id"
scroll={{ x: true }}
columns={columns}
dataSource={dataSource}
className='bg-transparent'
pagination={false} />
</Card>
</div>
<TenantEditor
onSave={() => {
load();
seEditorVisable(false);
}}
onCancel={() => { seEditorVisable(false) }}
visible={editorVisable}
data={editData} />
</>
);
};


+ 194
- 0
src/pages/system/tenant/list/tenant-editor.tsx Целия файл

@@ -0,0 +1,194 @@
import React, { useEffect, useState } from 'react'
import { Form, Input, InputNumber, Radio, Modal, Select, DatePicker } from 'antd';
import tenantService from '@/request/service/tenant';
import tenantPkgService from '@/request/service/tenant-package';
import { useRequest } from '@/hooks/use-request';
import type { TenantVO } from '@/models'
import { antdUtils } from '@/utils/antd';
import customParseFormat from 'dayjs/plugin/customParseFormat';

import dayjs from 'dayjs';
dayjs.extend(customParseFormat);


const layout = {
labelCol: { span: 4, },
wrapperCol: { span: 16 }
};

interface EditorProps {
visible: boolean;
onCancel: (flag?: boolean) => void;
onSave: (role: TenantVO) => void;
data?: TenantVO | null;
}


const TenantEditor: React.FC<EditorProps> = (props) => {

const { visible, onCancel, onSave, data } = props;

const { runAsync: updateApi } = useRequest(tenantService.updateTenantApi, { manual: true });
const { runAsync: createApi } = useRequest(tenantService.createTenantApi, { manual: true });
const { data: tenanPackages, run: getTenantPackageList } = useRequest(tenantPkgService.getTenantPackageList, { manual: true });

const isEdit = !!data;


const [saveLoading, setSaveLoading] = useState(false);
const [form] = Form.useForm();

useEffect(() => {
if (visible) {
if (data) {
form.setFieldsValue(data);
form.setFieldValue('expireTime', dayjs(data.expireTime))
}
} else {
form.resetFields();
}
}, [visible]);

useEffect(() => {
getTenantPackageList()
}, [getTenantPackageList])

const save = async () => {
setSaveLoading(true);
const fieldValues = form.getFieldsValue();
const expireTime = dayjs(form.getFieldValue('expireTime')).toDate().getTime()
const newValue = isEdit ? { ...data, ...fieldValues, expireTime } : {...fieldValues, expireTime};
const [error, { msg, code }] = isEdit ? await updateApi(newValue) : await createApi(newValue);
if (!error && code === 0) {
onSave(newValue);
} else {
antdUtils.message?.open({
type: 'error',
content: msg ?? '操作失败',
});
}
setSaveLoading(false);
}

return (
<>
<Modal
open={visible}
title="新建"
width={640}
onOk={save}
onCancel={() => onCancel()}
confirmLoading= {saveLoading}
destroyOnClose
>
<Form
form={form}
{...layout}
onFinish={save}
labelCol={{ flex: '0 0 100px' }}
wrapperCol={{ span: 16 }}
>
<Form.Item name="name" label="租户名称"
rules={[
{
required: true,
message: '请输入租户名称',
},
]}
>
<Input />
</Form.Item>

<Form.Item name="packageId" label="租户套餐"
rules={[
{
required: true,
message: '请选择租户套餐',
},
]}
>
<Select placeholder="请选择租户套餐" options={tenanPackages?.data.map(item => {
return {
label: item.name,
value: item.id,
}
})}>
</Select>
</Form.Item>


<Form.Item name="contactName" label="联系人"
rules={[
{
required: true,
message: '请输入联系人',
},
]}
>
<Input />
</Form.Item>


<Form.Item name="contactMobile" label="联系电话"
rules={[
{
required: true,
message: '请输入电话号码',
},
]}
>
<Input />
</Form.Item>

<Form.Item name="username" label="用户名称">
<Input />
</Form.Item>

<Form.Item name="password" label="用户密码">
<Input />
</Form.Item>

<Form.Item name="accountCount" label="账号额度" >
<InputNumber min={0} />
</Form.Item>

<Form.Item name="expireTime" label="过期时间"
rules={[
{
required: true,
message: '请设置过期时间',
},
]}>
<DatePicker showTime format="YYYY-MM-DD HH:mm:ss" />
</Form.Item>

<Form.Item name="domain" label="绑定域名"
rules={[
{
required: true,
message: '请输入绑定域名',
},
]}
>
<Input />
</Form.Item>

<Form.Item name="status" label="租户状态" rules={[
{
required: true,
message: '请选择租户状态',
},
]}>
<Radio.Group options={[
{ value: 0, label: "开启" },
{ value: 1, label: "关闭" }
]} optionType="default">
</Radio.Group>
</Form.Item>
</Form>
</Modal>
</>
)
}

export default TenantEditor;

+ 184
- 0
src/pages/system/tenant/package/index.tsx Целия файл

@@ -0,0 +1,184 @@
import { Space, Table, Button, Input, Select, Divider, Tag, Card, Badge, Form } from 'antd';
import type { TableColumnsType } from 'antd';
import { t } from '@/utils/i18n';
import React, { useState, useEffect } from 'react';
import { PlusOutlined, ExclamationCircleFilled, SearchOutlined, UndoOutlined } from '@ant-design/icons';
import type { TenantPackageVO } from '@/models'
import { antdUtils } from '@/utils/antd';
import { useRequest } from '@/hooks/use-request';
import tenantPkgService from '@/request/service/tenant-package';
import { formatDate } from '@/utils/formatTime'
import TenantPackageEditor from './tenant-pkg-editor';

export default () => {

const [editorVisable, seEditorVisable] = useState<boolean>(false);
const [editData, seEditData] = useState<TenantPackageVO>();
const [dataSource, setDataSource] = useState<TenantPackageVO[]>([]);
const [searchFrom] = Form.useForm();


const { runAsync: getPageApi } = useRequest(tenantPkgService.getTenantPackageTypePageApi, { manual: true });
const { runAsync: deleteApi } = useRequest(tenantPkgService.deleteTenantPackageTypeApi, { manual: true });

const load = async () => {
const [error, { data }] = await getPageApi(searchFrom.getFieldsValue());
if (!error) {
setDataSource(data.list);
}
};


const showDeleteConfirm = (data: TenantPackageVO) => {
antdUtils.modal?.confirm({
title: '确认要将该菜单删除吗?',
icon: <ExclamationCircleFilled />,
content: '请注意删除以后不可恢复!',
okText: '删除',
okType: 'danger',
cancelText: '取消',
onOk() {
return new Promise(async (resolve) => {
const [error, { code, msg} ] = await deleteApi(data.id);
if(error || code !== 0) {
antdUtils.message?.open({ type: 'error', content: msg??'操作失败'})
} else {
antdUtils.message?.open({ type: 'success', content: '删除成功'})
}
await load();
resolve('')
}).catch(() => antdUtils.message?.open({
type: 'error',
content: '操作失败',
}));
},
onCancel() {
},
});
};

const columns: TableColumnsType<TenantPackageVO> = [
{
title: '套餐编号',
dataIndex: 'id',
key: 'id',
align: 'right',
width: 200,
},
{
title: '套餐名称',
dataIndex: 'name',
key: 'name',
align: 'center',
width: 150
},
{
title: '备注',
key: 'remark',
dataIndex: 'remark',
align: 'center',
},
{
title: '状态',
key: 'status',
dataIndex: 'status',
width: 100,
align: 'center',
render: (value: number) => {
return (value === 0 ? <Badge status="success" text="已开启" /> : <Badge status="error" text="已关闭" />)
}
},
{
title: '创建时间',
key: 'createTime',
dataIndex: 'createTime',
width: 200,
render: (value: number) => {
return formatDate(new Date(value), "YYYY-mm-dd HH:MM:SS")
}
},
{
title: t("QkOmYwne" /* 操作 */),
key: 'action',
render: (value: TenantPackageVO, record) => (
<Space size="small" split={( <Divider type='vertical' />)}>
<a onClick={() => {
seEditData(value);
seEditorVisable(true);
}}>
编辑
</a>
<a onClick={() => {
showDeleteConfirm(value)
}}>
删除
</a>
</Space>
),
},
];

useEffect(() => {
load();
}, []);

const onReset = () => {
searchFrom.resetFields()
load()
}

return (
<>
<div>
<Card className='mt-[4px] dark:bg-[rgb(33,41,70)] bg-white roundle-lg px[12px]' bodyStyle={{ paddingTop: 4, paddingBottom: 4 }}>
<div className='flex justify-between content-center'>
<div className='flex justify-normal items-center'>
<Form layout='inline' form={searchFrom}>
<Form.Item name="name" label="套餐名称">
<Input className='w-[150px]' placeholder='请输入名称' allowClear />
</Form.Item>
<Form.Item name="remark" label="备注">
<Input className='w-[150px]' placeholder='请输入备注信息' allowClear />
</Form.Item>
<Form.Item className='ml-2 w-[130px]' name="status" label="状态">
<Select placeholder="请选择" allowClear >
<Select.Option value="">全部</Select.Option>
<Select.Option value="0">开启</Select.Option>
<Select.Option value="1">关闭</Select.Option>
</Select>
</Form.Item>
</Form>
<Space.Compact className="ml-5">
<Button type='primary' size='large' icon={<SearchOutlined />} onClick={load}> 搜索 </Button>
<Button type='primary' size='large' icon={<UndoOutlined />} onClick={onReset}> 重置 </Button>
</Space.Compact>
</div>
<div className="py-[4px]">
<Button className="ml-5" type='primary' size='large' icon={<PlusOutlined />} onClick={() => {
seEditData(undefined);
seEditorVisable(true);
}}> 新增套餐 </Button>
</div>
</div>
</Card>
<Card className='mt-[4px] dark:bg-[rgb(33,41,70)] bg-white roundle-lg px[12px]'>
<Table rowKey="id"
scroll={{ x: true }}
columns={columns}
dataSource={dataSource}
className='bg-transparent'
pagination={false}/>
</Card>
</div>
<TenantPackageEditor
onSave={() => {
load();
seEditorVisable(false);
}}
onCancel={() => { seEditorVisable(false) }}
visible={editorVisable}
data={editData} />
</>
);
};


+ 143
- 0
src/pages/system/tenant/package/tenant-pkg-editor.tsx Целия файл

@@ -0,0 +1,143 @@
import React, { useEffect, useState } from 'react'
import { Form, Input, InputNumber, Radio, Modal, TreeSelect } from 'antd';
import tenantPkgService from '@/request/service/tenant-package';
import menuService from '@/request/service/menu';
import { useRequest } from '@/hooks/use-request';
import type { DefaultOptionType } from 'antd/es/select';
import type { Menu, TenantPackageVO } from '@/models';
import { antdUtils } from '@/utils/antd';

const layout = {
labelCol: { span: 4, },
wrapperCol: { span: 16 },
bordered: false,
};

interface EditorProps {
visible: boolean;
onCancel: (flag?: boolean) => void;
onSave: (role: TenantPackageVO) => void;
data?: TenantPackageVO | null;
}
const toMenuTree = (data: Menu[]) => {
const root: Menu[] = data.filter(item => {
return !data.some(it => it.id === item.parentId)
});
const toMenuTreeItem = (item: Menu): DefaultOptionType => {
return {
label: item.name,
value: item.id,
children: data.filter(it => it.parentId === item.id).map(it => {
return toMenuTreeItem(it)
})
}
}
return root.map(item => {
return toMenuTreeItem(item)
})
}

const TenantPackageEditor: React.FC<EditorProps> = (props) => {

const { visible, onCancel, onSave, data } = props;

const { runAsync: updateApi } = useRequest(tenantPkgService.updateTenantPackageTypeApi, { manual: true });
const { runAsync: createApi } = useRequest(tenantPkgService.createTenantPackageTypeApi, { manual: true });
const { data: menus, run: getMenuList } = useRequest(menuService.listSimpleMenusApi, { manual: true });
// const [value, setValue] = useState(['0-0-0']);

// const onChange = (newValue: string[]) => {
// console.log('onChange ', value);
// setValue(newValue);
// };

const isEdit = !!data;

const [saveLoading, setSaveLoading] = useState(false);
const [form] = Form.useForm();

useEffect(() => {
if (visible) {
if (data) {
form.setFieldsValue(data);
}
} else {
form.resetFields();
}
}, [visible]);

useEffect(() => {
getMenuList();
}, [getMenuList]);

const save = async () => {
setSaveLoading(true);
const fieldValues = form.getFieldsValue();
const newValue = isEdit ? { ...data, ...fieldValues } : fieldValues;
const [error, { msg, code }] = isEdit ? await updateApi(newValue) : await createApi(newValue);
if (!error && code === 0) {
onSave(newValue);
} else {
antdUtils.message?.open({
type: 'error',
content: msg ?? '操作失败',
});
}
setSaveLoading(false);
}

return (
<>
<Modal
open={visible}
title="新建"
width={640}
onOk={save}
confirmLoading={saveLoading}
onCancel={() => onCancel()}
destroyOnClose
>
<Form
form={form}
{...layout}
onFinish={save}
labelCol={{ flex: '0 0 100px' }}
wrapperCol={{ span: 16 }}
>
<Form.Item name="name" label="套餐名称"
rules={[
{
required: true,
message: '请输入套餐名称',
},
]}
>
<Input />
</Form.Item>

<Form.Item name="menuIds" label="菜单权限" >
<TreeSelect
multiple
treeCheckable
showCheckedStrategy= {TreeSelect.SHOW_PARENT}
treeData={toMenuTree(menus?.data ?? [])} />
</Form.Item>

<Form.Item name="remark" label="备注" >
<Input.TextArea showCount maxLength={100} />
</Form.Item>

<Form.Item name="status" label="状态">
<Radio.Group options={[
{ value: 0, label: "开启" },
{ value: 1, label: "关闭" }
]} optionType="default">
</Radio.Group>
</Form.Item>
</Form>
</Modal>
</>
)
}

export default TenantPackageEditor;

+ 8
- 1
src/request/service/menu.ts Целия файл

@@ -7,9 +7,10 @@ export default {
getMenuList: (params?: { name?: string, status?: number }) => {
return request.get<Menu[]>(`${BASE_URL}/list`, { params });
},
// 获取菜单详情
getMenu: (id: number) => {
return request.get(`${BASE_URL}/get`, { params: { id }})
return request.get(`${BASE_URL}/get`, { params: { id } })
},

// 新增菜单
@@ -24,5 +25,11 @@ export default {

deleteMenu: (params: { id: number }) => {
return request.delete(`${BASE_URL}/delete`, { params })
},

// 查询菜单(精简)列表
listSimpleMenusApi: () => {
return request.get<Menu[]>(`${BASE_URL}/list-all-simple`);
}

};

+ 38
- 0
src/request/service/tenant-package.ts Целия файл

@@ -0,0 +1,38 @@
import request from '@/request';
import { PageData, TenantPackagePageReqVO, TenantPackageVO } from '@/models';

const BASE_URL = '/admin-api/system/tenant-package';

export default {
// 查询租户套餐列表
getTenantPackageTypePageApi: (params: TenantPackagePageReqVO) => {
return request.get<PageData<TenantPackageVO>>(`${BASE_URL}/page`, { params });
},

// 获得租户
getTenantPackageApi: (id: number) => {
return request.get(`${BASE_URL}/get?id=${id}`);
},

// 新增租户套餐
createTenantPackageTypeApi: (data: TenantPackageVO) => {
return request.post(`${BASE_URL}/create`, data );
},

// 修改租户套餐
updateTenantPackageTypeApi: (data: TenantPackageVO) => {
return request.put(`${BASE_URL}/update`, data );
},

// 删除租户套餐
deleteTenantPackageTypeApi: (id: number) => {
return request.delete(`${BASE_URL}/delete?id=${id}`);
},

// 获取租户套餐精简信息列表
getTenantPackageList: () => {
return request.get<TenantPackageVO[]>(`${BASE_URL}/get-simple-list`);
}
}



+ 39
- 0
src/request/service/tenant.ts Целия файл

@@ -0,0 +1,39 @@
import request from '@/request';
import { TenantPageReqVO, TenantVO, TenantExportReqVO, PageData } from '@/models';

const BASE_URL = '/admin-api/system/tenant';

export default {
// 查询租户列表
getTenantPageApi: (params: TenantPageReqVO) => {
return request.get<PageData<TenantVO>>(`${BASE_URL}/page`, { params })
},

// 查询租户详情
getTenantApi: (id: number) => {
return request.get(`${BASE_URL}/get?id=${id}`)
},

// 新增租户
createTenantApi: (data: TenantVO) => {
return request.post(`${BASE_URL}/create`, data)
},

// 修改租户
updateTenantApi: (data: TenantVO) => {
return request.put(`${BASE_URL}/update`, data)
},

// 删除租户
deleteTenantApi: (id: number) => {
return request.delete(`${BASE_URL}/delete?id=${id}`)
},

// 导出租户
exportTenantApi: (params: TenantExportReqVO) => {
return request.download(`${BASE_URL}/export-excel`, params)
},

}



Loading…
Отказ
Запис