mirror of https://github.com/longtai-cn/hippo4j
Merge branch 'develop' of https://github.com/opengoofy/hippo4j into develop
commit
ce69c6667a
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"systemParams": "darwin-arm64-93",
|
||||||
|
"modulesFolders": [
|
||||||
|
"node_modules"
|
||||||
|
],
|
||||||
|
"flags": [],
|
||||||
|
"linkedModules": [],
|
||||||
|
"topLevelPatterns": [],
|
||||||
|
"lockfileEntries": {},
|
||||||
|
"files": [],
|
||||||
|
"artifacts": {}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
/.git
|
/.git
|
||||||
node_modules
|
node_modules
|
||||||
build
|
build
|
||||||
|
src/lib/*
|
@ -1,3 +1,2 @@
|
|||||||
export * from './useThemeMode';
|
|
||||||
export * from './useTransLate';
|
export * from './useTransLate';
|
||||||
export * from './useFormToUrl';
|
export * from './useFormToUrl';
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
import { useContext, useEffect } from 'react';
|
|
||||||
import { useLocalStorageState } from 'ahooks';
|
|
||||||
import { MyContext, THEME_NAME } from '@/context';
|
|
||||||
|
|
||||||
export const useThemeMode = (): { isDark: boolean | undefined; setIsDark: (isDark: boolean) => void } => {
|
|
||||||
const [isDark, setIsDark] = useLocalStorageState<boolean>('current-mode', { defaultValue: false });
|
|
||||||
const { setThemeName } = useContext<any>(MyContext);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
isDark ? setThemeName(THEME_NAME.DARK) : setThemeName(THEME_NAME.DEFAULT);
|
|
||||||
}, [isDark, setThemeName]);
|
|
||||||
|
|
||||||
return { isDark, setIsDark };
|
|
||||||
};
|
|
@ -0,0 +1,18 @@
|
|||||||
|
import useUrlState from '@ahooksjs/use-url-state';
|
||||||
|
|
||||||
|
export const useUrlSet = (options: { form: any }) => {
|
||||||
|
const { form } = options;
|
||||||
|
const [state, setState] = useUrlState({});
|
||||||
|
|
||||||
|
const setUrl = () => {
|
||||||
|
const params = form.getFieldsValue();
|
||||||
|
Object.keys(params).forEach(key => {
|
||||||
|
if (!params[key]) {
|
||||||
|
params[key] = undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setState({ ...params });
|
||||||
|
};
|
||||||
|
|
||||||
|
return { setUrl };
|
||||||
|
};
|
@ -0,0 +1,5 @@
|
|||||||
|
.tenant_wrapper {
|
||||||
|
.opreate_btn {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
import { useAntdTable } from 'ahooks';
|
||||||
|
import { Button, Form, Input, Row, Space, Table, Col } from 'antd';
|
||||||
|
import { SearchOutlined, EditOutlined } from '@ant-design/icons';
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { fetchItemList } from './service';
|
||||||
|
import { useUrlSet } from '@/hooks/useUrlSet';
|
||||||
|
import style from './index.module.less';
|
||||||
|
|
||||||
|
const baseColumns = [
|
||||||
|
{
|
||||||
|
title: '序号',
|
||||||
|
dataIndex: 'index',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '租户',
|
||||||
|
dataIndex: 'tenantId',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '项目名称',
|
||||||
|
dataIndex: 'itemName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '负责人',
|
||||||
|
dataIndex: 'owner',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '修改时间',
|
||||||
|
dataIndex: 'gmtModified',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const Tenant: React.FC = () => {
|
||||||
|
const [editVisible, setEditVisible] = useState(false);
|
||||||
|
const [type, setType] = useState('add');
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const { setUrl } = useUrlSet({ form });
|
||||||
|
const { tableProps, search } = useAntdTable(fetchItemList, { form });
|
||||||
|
// const {run: delete} = useRequest(fetchDeleteTenant, { manual: true });
|
||||||
|
const actions = (type: string, item?: any) => {
|
||||||
|
switch (type) {
|
||||||
|
case 'add':
|
||||||
|
setEditVisible(true);
|
||||||
|
break;
|
||||||
|
case 'edit':
|
||||||
|
setEditVisible(true);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
// handleDelete();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleSearch = () => {
|
||||||
|
setUrl();
|
||||||
|
search.submit();
|
||||||
|
};
|
||||||
|
// const handleDelete = (item: any) => {
|
||||||
|
// Modal.confirm({
|
||||||
|
// title: `此操作将删除${item.tenantName}, 是否继续?`,
|
||||||
|
// onOk: () => {
|
||||||
|
// search.submit();
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={style.tenant_wrapper}>
|
||||||
|
<Form form={form} wrapperCol={{ span: 23 }}>
|
||||||
|
<Row>
|
||||||
|
<Col span={6}>
|
||||||
|
<Form.Item name="note">
|
||||||
|
<Input placeholder="项目" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={18}>
|
||||||
|
<Space>
|
||||||
|
<Button onClick={() => handleSearch()} type="primary" icon={<SearchOutlined />}>
|
||||||
|
搜索
|
||||||
|
</Button>
|
||||||
|
<Button onClick={() => setEditVisible(true)} type="primary" icon={<EditOutlined />}>
|
||||||
|
添加
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col span={6}></Col>
|
||||||
|
<Col span={18}></Col>
|
||||||
|
</Row>
|
||||||
|
</Form>
|
||||||
|
<Table
|
||||||
|
{...tableProps}
|
||||||
|
bordered
|
||||||
|
rowKey="index"
|
||||||
|
columns={[
|
||||||
|
...baseColumns,
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
render: (text: string, record: any) => {
|
||||||
|
return (
|
||||||
|
<Space>
|
||||||
|
<Button onClick={() => actions('edit', record)} type="link" className={style.opreate_btn}>
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
<Button onClick={() => actions('edit', record)} type="link" className={style.opreate_btn}>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Tenant;
|
@ -0,0 +1,8 @@
|
|||||||
|
import { lazy } from 'react';
|
||||||
|
import { IRouterList } from '@/typings';
|
||||||
|
|
||||||
|
const ItemManage = lazy(() => import('./index'));
|
||||||
|
|
||||||
|
const routerList: IRouterList[] = [{ path: '/item', component: () => <ItemManage /> }];
|
||||||
|
|
||||||
|
export default routerList;
|
@ -0,0 +1,75 @@
|
|||||||
|
import request from '@/utils';
|
||||||
|
|
||||||
|
const fetchItemList = async (
|
||||||
|
pageProps: { current: number; pageSize: number },
|
||||||
|
formData: { tencent: string | number }
|
||||||
|
): Promise<{ total: number; list: Array<any> }> => {
|
||||||
|
const res: any = await request('/hippo4j/v1/cs/item/query/page', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Authorization:
|
||||||
|
'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI3LGJhb3hpbnlpX2FkbWluIiwiaXNzIjoiYWRtaW4iLCJleHAiOjE2OTUzOTg4NDksImlhdCI6MTY5NDc5NDA0OSwicm9sIjoiUk9MRV9BRE1JTiJ9.syRDshKpd-xETsSdeMPRtk956f4BJkPt4utVsUl4smgH71Woj8SUq4w2RX1YtGTC4aTZRJYdKOfkTqwK0g_dHQ',
|
||||||
|
cookie:
|
||||||
|
'Admin-Token=Bearer%20eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI3LGJhb3hpbnlpX2FkbWluIiwiaXNzIjoiYWRtaW4iLCJleHAiOjE2OTUzOTg4NDksImlhdCI6MTY5NDc5NDA0OSwicm9sIjoiUk9MRV9BRE1JTiJ9.syRDshKpd-xETsSdeMPRtk956f4BJkPt4utVsUl4smgH71Woj8SUq4w2RX1YtGTC4aTZRJYdKOfkTqwK0g_dHQ; userName=baoxinyi_admin',
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
...formData,
|
||||||
|
current: pageProps.current,
|
||||||
|
size: pageProps.pageSize,
|
||||||
|
desc: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (res && res.success) {
|
||||||
|
return {
|
||||||
|
total: res.data.total,
|
||||||
|
list: res.data.records.map((item: any, index: number) => ({ index: index + 1, ...item })),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw new Error(res.msg || '服务器开小差啦~');
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchAddTenant = async (params: {
|
||||||
|
itemDesc: string; // 项目简介
|
||||||
|
itemId: string; // 项目
|
||||||
|
itemName: string; // 项目名称
|
||||||
|
owner: string; // 负责人
|
||||||
|
tenantId: string; // 租户
|
||||||
|
tenantDesc?: string;
|
||||||
|
tenantName?: string;
|
||||||
|
}) => {
|
||||||
|
const res = await request('/hippo4j/v1/cs/tenant/save', {
|
||||||
|
method: 'POST',
|
||||||
|
body: { ...params },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res && res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
throw new Error(res.msg || '服务器开小差啦~');
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchDeleteItem = async (id: string) => {
|
||||||
|
const url = 'hippo4j/v1/cs/item/delete/prescription/' + id;
|
||||||
|
const res = await request(url, {
|
||||||
|
method: 'DELETE',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res && res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
throw new Error(res.msg || '服务器开小差啦~');
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchUpdateItem = async (id: string) => {
|
||||||
|
const res = await request('/hippo4j/v1/cs/item/update', {
|
||||||
|
method: 'POST',
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res && res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
throw new Error(res.msg || '服务器开小差啦~');
|
||||||
|
};
|
||||||
|
|
||||||
|
export { fetchItemList, fetchAddTenant, fetchDeleteItem, fetchUpdateItem };
|
@ -0,0 +1,5 @@
|
|||||||
|
.tenant_wrapper {
|
||||||
|
.opreate_btn {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
import { useAntdTable } from 'ahooks';
|
||||||
|
import { Button, Form, Input, Row, Space, Table, Col, Modal } from 'antd';
|
||||||
|
import { SearchOutlined, EditOutlined } from '@ant-design/icons';
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { fetchTenantList } from './service';
|
||||||
|
import { useUrlSet } from '@/hooks/useUrlSet';
|
||||||
|
import style from './index.module.less';
|
||||||
|
|
||||||
|
const baseColumns = [
|
||||||
|
{
|
||||||
|
title: '序号',
|
||||||
|
dataIndex: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '租户',
|
||||||
|
dataIndex: 'tenantId',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '租户名称',
|
||||||
|
dataIndex: 'tenantName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '负责人',
|
||||||
|
dataIndex: 'owner',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '修改时间',
|
||||||
|
dataIndex: 'gmtModified',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const Tenant: React.FC = () => {
|
||||||
|
const [editVisible, setEditVisible] = useState(false);
|
||||||
|
const [type, setType] = useState('add');
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const { setUrl } = useUrlSet({ form });
|
||||||
|
const { tableProps, search } = useAntdTable(fetchTenantList, { form });
|
||||||
|
// const {run: delete} = useRequest(fetchDeleteTenant, { manual: true });
|
||||||
|
const actions = (type: string, item?: any) => {
|
||||||
|
switch (type) {
|
||||||
|
case 'add':
|
||||||
|
setEditVisible(true);
|
||||||
|
break;
|
||||||
|
case 'edit':
|
||||||
|
setEditVisible(true);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
// handleDelete();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleSearch = () => {
|
||||||
|
setUrl();
|
||||||
|
search.submit();
|
||||||
|
};
|
||||||
|
// const handleDelete = (item: any) => {
|
||||||
|
// Modal.confirm({
|
||||||
|
// title: `此操作将删除${item.tenantName}, 是否继续?`,
|
||||||
|
// onOk: () => {
|
||||||
|
// search.submit();
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={style.tenant_wrapper}>
|
||||||
|
<Form form={form} wrapperCol={{ span: 23 }}>
|
||||||
|
<Row>
|
||||||
|
<Col span={6}>
|
||||||
|
<Form.Item name="note">
|
||||||
|
<Input placeholder="租户" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={18}>
|
||||||
|
<Space>
|
||||||
|
<Button onClick={() => handleSearch()} type="primary" icon={<SearchOutlined />}>
|
||||||
|
搜索
|
||||||
|
</Button>
|
||||||
|
<Button onClick={() => setEditVisible(true)} type="primary" icon={<EditOutlined />}>
|
||||||
|
添加
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col span={6}></Col>
|
||||||
|
<Col span={18}></Col>
|
||||||
|
</Row>
|
||||||
|
</Form>
|
||||||
|
<Table
|
||||||
|
{...tableProps}
|
||||||
|
bordered
|
||||||
|
rowKey="id"
|
||||||
|
columns={[
|
||||||
|
...baseColumns,
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
render: (text: string, record: any) => {
|
||||||
|
return (
|
||||||
|
<Space>
|
||||||
|
<Button onClick={() => actions('edit', record)} type="link" className={style.opreate_btn}>
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
<Button onClick={() => actions('edit', record)} type="link" className={style.opreate_btn}>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Tenant;
|
@ -0,0 +1,8 @@
|
|||||||
|
import { lazy } from 'react';
|
||||||
|
import { IRouterList } from '@/typings';
|
||||||
|
|
||||||
|
const LogManage = lazy(() => import('./index'));
|
||||||
|
|
||||||
|
const routerList: IRouterList[] = [{ path: '/log', component: () => <LogManage /> }];
|
||||||
|
|
||||||
|
export default routerList;
|
@ -0,0 +1,79 @@
|
|||||||
|
import request from '@/utils';
|
||||||
|
|
||||||
|
const fetchTenantList = async (
|
||||||
|
pageProps: { current: number; pageSize: number },
|
||||||
|
formData: { tencent: string | number }
|
||||||
|
): Promise<{ total: number; list: Array<any> }> => {
|
||||||
|
const res: any = await request('/hippo4j/v1/cs/tenant/query/page', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Authorization:
|
||||||
|
'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI3LGJhb3hpbnlpX2FkbWluIiwiaXNzIjoiYWRtaW4iLCJleHAiOjE2OTUzOTg4NDksImlhdCI6MTY5NDc5NDA0OSwicm9sIjoiUk9MRV9BRE1JTiJ9.syRDshKpd-xETsSdeMPRtk956f4BJkPt4utVsUl4smgH71Woj8SUq4w2RX1YtGTC4aTZRJYdKOfkTqwK0g_dHQ',
|
||||||
|
cookie:
|
||||||
|
'Admin-Token=Bearer%20eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI3LGJhb3hpbnlpX2FkbWluIiwiaXNzIjoiYWRtaW4iLCJleHAiOjE2OTUzOTg4NDksImlhdCI6MTY5NDc5NDA0OSwicm9sIjoiUk9MRV9BRE1JTiJ9.syRDshKpd-xETsSdeMPRtk956f4BJkPt4utVsUl4smgH71Woj8SUq4w2RX1YtGTC4aTZRJYdKOfkTqwK0g_dHQ; userName=baoxinyi_admin',
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
...formData,
|
||||||
|
current: pageProps.current,
|
||||||
|
size: pageProps.pageSize,
|
||||||
|
desc: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (res && res.success) {
|
||||||
|
return {
|
||||||
|
total: res.data.total,
|
||||||
|
list: res.data.records,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw new Error(res.msg || '服务器开小差啦~');
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchAddTenant = async (id: string) => {
|
||||||
|
const res = await request('/hippo4j/v1/cs/tenant/save', {
|
||||||
|
method: 'POST',
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res && res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
throw new Error(res.msg || '服务器开小差啦~');
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchDeleteTenant = async (id: string) => {
|
||||||
|
const res = await request('/tenants', {
|
||||||
|
method: 'POST',
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res && res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
throw new Error(res.msg || '服务器开小差啦~');
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchUpdateTenant = async (id: string) => {
|
||||||
|
const res = await request('hippo4j/v1/cs/tenant/update', {
|
||||||
|
method: 'POST',
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res && res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
throw new Error(res.msg || '服务器开小差啦~');
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchTenantDetail = async (id: string) => {
|
||||||
|
const res = await request('/tenants', {
|
||||||
|
method: 'POST',
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res && res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
throw new Error(res.msg || '服务器开小差啦~');
|
||||||
|
};
|
||||||
|
|
||||||
|
export { fetchTenantList, fetchAddTenant, fetchDeleteTenant, fetchUpdateTenant, fetchTenantDetail };
|
@ -0,0 +1,37 @@
|
|||||||
|
.login-wrapper {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 550px;
|
||||||
|
grid-template-rows: 1fr;
|
||||||
|
height: 100%;
|
||||||
|
.login-bgi {
|
||||||
|
background: url('https://gw.alipayobjects.com/zos/rmsportal/FfdJeJRQWjEeGTpqgBKj.png') no-repeat fixed center center;
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
.login-form-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
.img-wrapper {
|
||||||
|
width: 50px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
img {
|
||||||
|
flex: 1;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tip {
|
||||||
|
margin-block-start: 12px;
|
||||||
|
margin-block-end: 36px;
|
||||||
|
}
|
||||||
|
.form-content {
|
||||||
|
width: 330px;
|
||||||
|
.login-edit {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,143 @@
|
|||||||
import React from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
|
import { Typography, Tabs, TabsProps, Form, Input, Checkbox, Button, message } from 'antd';
|
||||||
|
import service from './service';
|
||||||
|
import { LockOutlined, UserOutlined } from '@ant-design/icons';
|
||||||
|
import style from './index.module.less';
|
||||||
|
import { useRequest } from 'ahooks';
|
||||||
|
import { setToken } from '@/utils';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
const { Paragraph } = Typography;
|
||||||
|
|
||||||
|
enum TABS_KEY {
|
||||||
|
LOGIN = 'login',
|
||||||
|
PHONE = 'phoneLogin',
|
||||||
|
}
|
||||||
|
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
return <></>;
|
const [form] = Form.useForm();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { validateFields } = form;
|
||||||
|
const [remenberMe, setRemenberMe] = useState(0);
|
||||||
|
|
||||||
|
const { run, loading } = useRequest(service.fetchLogin, {
|
||||||
|
manual: true,
|
||||||
|
onSuccess: res => {
|
||||||
|
if (res) {
|
||||||
|
message.success('登陆成功');
|
||||||
|
navigate('/thread-poll/index');
|
||||||
|
setToken(res?.data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleLogin = useCallback(() => {
|
||||||
|
validateFields()
|
||||||
|
.then(values => {
|
||||||
|
console.log('value:::', values, remenberMe);
|
||||||
|
run({
|
||||||
|
password: '1BsL68bUgS52alKirqFprU1QfWJyPFlb3dA2AzEMc6kMTpTHN1doEN4=',
|
||||||
|
rememberMe: 1,
|
||||||
|
tag: 'lw4xNmj6QuamOFsy',
|
||||||
|
username: 'baoxinyi_user',
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(err => console.log('err:::', err));
|
||||||
|
}, [remenberMe, validateFields, run]);
|
||||||
|
|
||||||
|
const formNode = useMemo(
|
||||||
|
() => (
|
||||||
|
<Form form={form}>
|
||||||
|
<Form.Item
|
||||||
|
name="username"
|
||||||
|
initialValue={'baoxinyi_user'}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入用户名!',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
placeholder="用户名"
|
||||||
|
prefix={<UserOutlined className={'prefixIcon'} />}
|
||||||
|
size="large"
|
||||||
|
allowClear
|
||||||
|
></Input>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name="password"
|
||||||
|
initialValue={'baoxinyi_user'}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入密码!',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input.Password
|
||||||
|
placeholder="密码"
|
||||||
|
prefix={<LockOutlined className={'prefixIcon'} />}
|
||||||
|
size="large"
|
||||||
|
allowClear
|
||||||
|
></Input.Password>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item name="rememberMe">
|
||||||
|
<div className={style['login-edit']}>
|
||||||
|
<Checkbox
|
||||||
|
value={1}
|
||||||
|
checked
|
||||||
|
onChange={e => {
|
||||||
|
setRemenberMe(e.target.checked ? 1 : 0);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
记住密码
|
||||||
|
</Checkbox>
|
||||||
|
<Button type="link">忘记密码</Button>
|
||||||
|
</div>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item>
|
||||||
|
<Button
|
||||||
|
htmlType="submit"
|
||||||
|
type="primary"
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
size="large"
|
||||||
|
onClick={handleLogin}
|
||||||
|
loading={loading}
|
||||||
|
>
|
||||||
|
登陆
|
||||||
|
</Button>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
),
|
||||||
|
[form, loading, handleLogin]
|
||||||
|
);
|
||||||
|
|
||||||
|
const items: TabsProps['items'] = [
|
||||||
|
{
|
||||||
|
key: TABS_KEY.LOGIN,
|
||||||
|
label: '账号密码登陆',
|
||||||
|
children: formNode,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: TABS_KEY.PHONE,
|
||||||
|
label: '手机号登陆',
|
||||||
|
children: formNode,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<div className={style['login-wrapper']}>
|
||||||
|
<div className={style['login-bgi']}></div>
|
||||||
|
<div className={style['login-form-wrapper']}>
|
||||||
|
<div className={style['img-wrapper']}>
|
||||||
|
<img src="https://nageoffer.com/img/logo3.png" alt="" />
|
||||||
|
</div>
|
||||||
|
<Paragraph className={style['tip']}>全球最好用的线程池管理工具</Paragraph>
|
||||||
|
<div className={style['form-content']}>
|
||||||
|
<Tabs centered defaultActiveKey={TABS_KEY.LOGIN} items={items} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
export default Login;
|
export default Login;
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
import { IRouterList } from '@/typings';
|
||||||
|
import Login from '.';
|
||||||
|
|
||||||
|
const routerList: IRouterList[] = [{ path: '/login', component: Login }];
|
||||||
|
|
||||||
|
export default routerList;
|
@ -0,0 +1,13 @@
|
|||||||
|
import request from '@/utils';
|
||||||
|
|
||||||
|
const fetchLogin = async (body: any) => {
|
||||||
|
const { data } = await request<{ data: string; roles: string[] }>('/hippo4j/v1/cs/auth/login', {
|
||||||
|
method: 'POST',
|
||||||
|
body,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
fetchLogin,
|
||||||
|
};
|
@ -0,0 +1,5 @@
|
|||||||
|
.tenant_wrapper {
|
||||||
|
.opreate_btn {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
.tenant_wrapper {
|
||||||
|
.opreate_btn {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
import { useAntdTable } from 'ahooks';
|
||||||
|
import { Button, Form, Input, Row, Space, Table, Col } from 'antd';
|
||||||
|
import { SearchOutlined, EditOutlined } from '@ant-design/icons';
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { fetchUserList } from './service';
|
||||||
|
import { useUrlSet } from '@/hooks/useUrlSet';
|
||||||
|
import style from './index.module.less';
|
||||||
|
|
||||||
|
const baseColumns = [
|
||||||
|
{
|
||||||
|
title: '序号',
|
||||||
|
dataIndex: 'index',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '用户名',
|
||||||
|
dataIndex: 'userName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '角色',
|
||||||
|
dataIndex: 'role',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'gmtCreate',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '修改时间',
|
||||||
|
dataIndex: 'gmtModified',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const Tenant: React.FC = () => {
|
||||||
|
const [editVisible, setEditVisible] = useState(false);
|
||||||
|
const [type, setType] = useState('add');
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const { setUrl } = useUrlSet({ form });
|
||||||
|
const { tableProps, search } = useAntdTable(fetchUserList, { form });
|
||||||
|
// const {run: delete} = useRequest(fetchDeleteTenant, { manual: true });
|
||||||
|
const actions = (type: string, item?: any) => {
|
||||||
|
switch (type) {
|
||||||
|
case 'add':
|
||||||
|
setEditVisible(true);
|
||||||
|
break;
|
||||||
|
case 'edit':
|
||||||
|
setEditVisible(true);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
// handleDelete();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleSearch = () => {
|
||||||
|
setUrl();
|
||||||
|
search.submit();
|
||||||
|
};
|
||||||
|
// const handleDelete = (item: any) => {
|
||||||
|
// Modal.confirm({
|
||||||
|
// title: `此操作将删除${item.tenantName}, 是否继续?`,
|
||||||
|
// onOk: () => {
|
||||||
|
// search.submit();
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={style.tenant_wrapper}>
|
||||||
|
<Form form={form} wrapperCol={{ span: 23 }}>
|
||||||
|
<Row>
|
||||||
|
<Col span={6}>
|
||||||
|
<Form.Item name="note">
|
||||||
|
<Input placeholder="用户名" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={18}>
|
||||||
|
<Space>
|
||||||
|
<Button onClick={() => handleSearch()} type="primary" icon={<SearchOutlined />}>
|
||||||
|
搜索
|
||||||
|
</Button>
|
||||||
|
<Button onClick={() => setEditVisible(true)} type="primary" icon={<EditOutlined />}>
|
||||||
|
添加
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col span={6}></Col>
|
||||||
|
<Col span={18}></Col>
|
||||||
|
</Row>
|
||||||
|
</Form>
|
||||||
|
<Table
|
||||||
|
{...tableProps}
|
||||||
|
bordered
|
||||||
|
rowKey="index"
|
||||||
|
columns={[
|
||||||
|
...baseColumns,
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
render: (text: string, record: any) => {
|
||||||
|
return (
|
||||||
|
<Space>
|
||||||
|
<Button onClick={() => actions('edit', record)} type="link" className={style.opreate_btn}>
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
<Button onClick={() => actions('edit', record)} type="link" className={style.opreate_btn}>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Tenant;
|
@ -0,0 +1,8 @@
|
|||||||
|
import { lazy } from 'react';
|
||||||
|
import { IRouterList } from '@/typings';
|
||||||
|
|
||||||
|
const UserManage = lazy(() => import('./index'));
|
||||||
|
|
||||||
|
const routerList: IRouterList[] = [{ path: '/user', component: () => <UserManage /> }];
|
||||||
|
|
||||||
|
export default routerList;
|
@ -0,0 +1,78 @@
|
|||||||
|
import request from '@/utils';
|
||||||
|
|
||||||
|
const fetchUserList = async (
|
||||||
|
pageProps: { current: number; pageSize: number },
|
||||||
|
formData: { tencent: string | number }
|
||||||
|
): Promise<{ total: number; list: Array<any> }> => {
|
||||||
|
const res: any = await request('/hippo4j/v1/cs/auth/users/page', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Authorization:
|
||||||
|
'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI3LGJhb3hpbnlpX2FkbWluIiwiaXNzIjoiYWRtaW4iLCJleHAiOjE2OTUzOTg4NDksImlhdCI6MTY5NDc5NDA0OSwicm9sIjoiUk9MRV9BRE1JTiJ9.syRDshKpd-xETsSdeMPRtk956f4BJkPt4utVsUl4smgH71Woj8SUq4w2RX1YtGTC4aTZRJYdKOfkTqwK0g_dHQ',
|
||||||
|
cookie:
|
||||||
|
'Admin-Token=Bearer%20eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI3LGJhb3hpbnlpX2FkbWluIiwiaXNzIjoiYWRtaW4iLCJleHAiOjE2OTUzOTg4NDksImlhdCI6MTY5NDc5NDA0OSwicm9sIjoiUk9MRV9BRE1JTiJ9.syRDshKpd-xETsSdeMPRtk956f4BJkPt4utVsUl4smgH71Woj8SUq4w2RX1YtGTC4aTZRJYdKOfkTqwK0g_dHQ; userName=baoxinyi_admin',
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
...formData,
|
||||||
|
current: pageProps.current,
|
||||||
|
size: pageProps.pageSize,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (res && res.success) {
|
||||||
|
return {
|
||||||
|
total: res.data.total,
|
||||||
|
list: res.data.records.map((item: any, index: number) => ({ index: index + 1, ...item })),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw new Error(res.msg || '服务器开小差啦~');
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchAddTenant = async (id: string) => {
|
||||||
|
const res = await request('/hippo4j/v1/cs/tenant/save', {
|
||||||
|
method: 'POST',
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res && res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
throw new Error(res.msg || '服务器开小差啦~');
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchDeleteTenant = async (id: string) => {
|
||||||
|
const res = await request('/tenants', {
|
||||||
|
method: 'POST',
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res && res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
throw new Error(res.msg || '服务器开小差啦~');
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchUpdateTenant = async (id: string) => {
|
||||||
|
const res = await request('hippo4j/v1/cs/tenant/update', {
|
||||||
|
method: 'POST',
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res && res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
throw new Error(res.msg || '服务器开小差啦~');
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchTenantDetail = async (id: string) => {
|
||||||
|
const res = await request('/tenants', {
|
||||||
|
method: 'POST',
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res && res.success) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
throw new Error(res.msg || '服务器开小差啦~');
|
||||||
|
};
|
||||||
|
|
||||||
|
export { fetchUserList, fetchAddTenant, fetchDeleteTenant, fetchUpdateTenant, fetchTenantDetail };
|
@ -1,2 +1,3 @@
|
|||||||
/// <reference types="react-scripts" />
|
/// <reference types="react-scripts" />
|
||||||
declare module '*.less';
|
declare module '*.less';
|
||||||
|
declare module 'crypto-browserify' {}
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
||||||
# yarn lockfile v1
|
|
||||||
|
|
||||||
|
|
||||||
"@babel/runtime@^7.21.0":
|
|
||||||
version "7.22.15"
|
|
||||||
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.22.15.tgz#38f46494ccf6cf020bd4eed7124b425e83e523b8"
|
|
||||||
integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==
|
|
||||||
dependencies:
|
|
||||||
regenerator-runtime "^0.14.0"
|
|
||||||
|
|
||||||
"@types/js-cookie@^2.x.x":
|
|
||||||
version "2.2.7"
|
|
||||||
resolved "https://registry.npmmirror.com/@types/js-cookie/-/js-cookie-2.2.7.tgz#226a9e31680835a6188e887f3988e60c04d3f6a3"
|
|
||||||
integrity sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==
|
|
||||||
|
|
||||||
ahooks-v3-count@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.npmmirror.com/ahooks-v3-count/-/ahooks-v3-count-1.0.0.tgz#ddeb392e009ad6e748905b3cbf63a9fd8262ca80"
|
|
||||||
integrity sha512-V7uUvAwnimu6eh/PED4mCDjE7tokeZQLKlxg9lCTMPhN+NjsSbtdacByVlR1oluXQzD3MOw55wylDmQo4+S9ZQ==
|
|
||||||
|
|
||||||
ahooks@^3.7.8:
|
|
||||||
version "3.7.8"
|
|
||||||
resolved "https://registry.npmmirror.com/ahooks/-/ahooks-3.7.8.tgz#3fa3c491cd153e884a32b0c4192fc72cf84c4332"
|
|
||||||
integrity sha512-e/NMlQWoCjaUtncNFIZk3FG1ImSkV/JhScQSkTqnftakRwdfZWSw6zzoWSG9OMYqPNs2MguDYBUFFC6THelWXA==
|
|
||||||
dependencies:
|
|
||||||
"@babel/runtime" "^7.21.0"
|
|
||||||
"@types/js-cookie" "^2.x.x"
|
|
||||||
ahooks-v3-count "^1.0.0"
|
|
||||||
dayjs "^1.9.1"
|
|
||||||
intersection-observer "^0.12.0"
|
|
||||||
js-cookie "^2.x.x"
|
|
||||||
lodash "^4.17.21"
|
|
||||||
resize-observer-polyfill "^1.5.1"
|
|
||||||
screenfull "^5.0.0"
|
|
||||||
tslib "^2.4.1"
|
|
||||||
|
|
||||||
dayjs@^1.9.1:
|
|
||||||
version "1.11.9"
|
|
||||||
resolved "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.9.tgz#9ca491933fadd0a60a2c19f6c237c03517d71d1a"
|
|
||||||
integrity sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==
|
|
||||||
|
|
||||||
intersection-observer@^0.12.0:
|
|
||||||
version "0.12.2"
|
|
||||||
resolved "https://registry.npmmirror.com/intersection-observer/-/intersection-observer-0.12.2.tgz#4a45349cc0cd91916682b1f44c28d7ec737dc375"
|
|
||||||
integrity sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==
|
|
||||||
|
|
||||||
js-cookie@^2.x.x:
|
|
||||||
version "2.2.1"
|
|
||||||
resolved "https://registry.npmmirror.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8"
|
|
||||||
integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==
|
|
||||||
|
|
||||||
lodash@^4.17.21:
|
|
||||||
version "4.17.21"
|
|
||||||
resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
|
||||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
|
||||||
|
|
||||||
regenerator-runtime@^0.14.0:
|
|
||||||
version "0.14.0"
|
|
||||||
resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
|
|
||||||
integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
|
|
||||||
|
|
||||||
resize-observer-polyfill@^1.5.1:
|
|
||||||
version "1.5.1"
|
|
||||||
resolved "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
|
|
||||||
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
|
|
||||||
|
|
||||||
screenfull@^5.0.0:
|
|
||||||
version "5.2.0"
|
|
||||||
resolved "https://registry.npmmirror.com/screenfull/-/screenfull-5.2.0.tgz#6533d524d30621fc1283b9692146f3f13a93d1ba"
|
|
||||||
integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==
|
|
||||||
|
|
||||||
tslib@^2.4.1:
|
|
||||||
version "2.6.2"
|
|
||||||
resolved "https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
|
||||||
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
|
Loading…
Reference in new issue