From 1f66d372a04c17502590f45a248abc2135487201 Mon Sep 17 00:00:00 2001 From: smallbun <2689170096@qq.com> Date: Sun, 10 Sep 2023 22:30:59 +0800 Subject: [PATCH] =?UTF-8?q?:zap:=20=E5=BA=94=E7=94=A8=E5=88=86=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/console-fe/config/routes.ts | 50 ++-- .../src/components/RightContent/index.tsx | 2 +- .../main/console-fe/src/locales/zh-CN/menu.ts | 2 + .../IdentitySourceDetail.tsx | 2 +- .../components/AppBasic/AppBasic.tsx | 3 +- .../PermissionResource/UpdateModal.tsx | 152 ++++++++++++ .../src/pages/app/AppCreate/AppCreate.tsx | 49 ++-- .../src/pages/app/AppGroup/AppGroup.tsx | 221 ++++++++++++++++++ .../components/UpdateModal/UpdateModal.tsx | 105 +++++++++ .../src/pages/app/AppGroup/data.d.ts | 17 ++ .../src/pages/app/AppGroup/service.ts | 62 +++++ .../src/pages/app/AppList/AppList.tsx | 27 ++- 12 files changed, 653 insertions(+), 39 deletions(-) create mode 100644 eiam-console/src/main/console-fe/src/pages/app/AppConfig/components/PermissionResource/UpdateModal.tsx create mode 100644 eiam-console/src/main/console-fe/src/pages/app/AppGroup/AppGroup.tsx create mode 100644 eiam-console/src/main/console-fe/src/pages/app/AppGroup/components/UpdateModal/UpdateModal.tsx create mode 100644 eiam-console/src/main/console-fe/src/pages/app/AppGroup/data.d.ts create mode 100644 eiam-console/src/main/console-fe/src/pages/app/AppGroup/service.ts diff --git a/eiam-console/src/main/console-fe/config/routes.ts b/eiam-console/src/main/console-fe/config/routes.ts index a7c038f5..c5094337 100644 --- a/eiam-console/src/main/console-fe/config/routes.ts +++ b/eiam-console/src/main/console-fe/config/routes.ts @@ -134,26 +134,44 @@ export default [ }, ], }, - //应用列表 + //应用管理 { name: 'app', icon: 'AppstoreOutlined', path: '/app', - component: './app/AppList', - }, - //创建应用 - { - name: 'app.create', - path: '/app/create', - hideInMenu: true, - component: './app/AppCreate', - }, - //应用配置 - { - name: 'app.config', - path: '/app/config', - hideInMenu: true, - component: './app/AppConfig', + routes: [ + // 应用列表 + { + path: '/app', + redirect: '/app/list', + }, + // 应用列表 + { + name: 'list', + path: '/app/list', + component: './app/AppList', + }, + //创建应用 + { + name: 'create', + path: '/app/list/create', + hideInMenu: true, + component: './app/AppCreate', + }, + //应用配置 + { + name: 'config', + path: '/app/list/config', + hideInMenu: true, + component: './app/AppConfig', + }, + // 应用分组 + { + name: 'group', + path: '/app/group', + component: './app/AppGroup', + }, + ], }, //行为审计 { diff --git a/eiam-console/src/main/console-fe/src/components/RightContent/index.tsx b/eiam-console/src/main/console-fe/src/components/RightContent/index.tsx index d969ffe3..8a9f6cb7 100644 --- a/eiam-console/src/main/console-fe/src/components/RightContent/index.tsx +++ b/eiam-console/src/main/console-fe/src/components/RightContent/index.tsx @@ -57,7 +57,7 @@ const GlobalHeaderRight: React.FC = () => { return (
- + diff --git a/eiam-console/src/main/console-fe/src/locales/zh-CN/menu.ts b/eiam-console/src/main/console-fe/src/locales/zh-CN/menu.ts index fbb062ec..c5c2b2e4 100644 --- a/eiam-console/src/main/console-fe/src/locales/zh-CN/menu.ts +++ b/eiam-console/src/main/console-fe/src/locales/zh-CN/menu.ts @@ -39,6 +39,8 @@ export default { 'menu.account.logout': '退出登录', 'menu.social-bind': '用户绑定', 'menu.app': '应用管理', + 'menu.app.list': '应用列表', + 'menu.app.group': '应用分组', 'menu.app.create': '创建应用', 'menu.app.config': '应用配置', 'menu.account': '账户管理', diff --git a/eiam-console/src/main/console-fe/src/pages/account/IdentitySourceDetail/IdentitySourceDetail.tsx b/eiam-console/src/main/console-fe/src/pages/account/IdentitySourceDetail/IdentitySourceDetail.tsx index 3f455900..c16294d8 100644 --- a/eiam-console/src/main/console-fe/src/pages/account/IdentitySourceDetail/IdentitySourceDetail.tsx +++ b/eiam-console/src/main/console-fe/src/pages/account/IdentitySourceDetail/IdentitySourceDetail.tsx @@ -81,7 +81,7 @@ export default () => { history.push(`/account/identity-source`); return; } - if (!type) { + if (!type || !IdentitySourceDetailTabs[type]) { setTabActiveKey(IdentitySourceDetailTabs.config); history.push({ pathname: location.pathname, diff --git a/eiam-console/src/main/console-fe/src/pages/app/AppConfig/components/AppBasic/AppBasic.tsx b/eiam-console/src/main/console-fe/src/pages/app/AppConfig/components/AppBasic/AppBasic.tsx index 1b1eb1ac..8ec26ef5 100644 --- a/eiam-console/src/main/console-fe/src/pages/app/AppConfig/components/AppBasic/AppBasic.tsx +++ b/eiam-console/src/main/console-fe/src/pages/app/AppConfig/components/AppBasic/AppBasic.tsx @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import { getApp, updateApp } from '@/services/app'; +import { updateApp } from '@/services/app'; import { ProCard, ProDescriptions } from '@ant-design/pro-components'; import { useAsyncEffect } from 'ahooks'; @@ -30,6 +30,7 @@ import classNames from 'classnames'; import { LoadingOutlined, PlusOutlined } from '@ant-design/icons'; import { uploadFile } from '@/services/upload'; import { GetApp } from '@/pages/app/AppConfig/data'; +import { getApp } from '../../service'; const prefixCls = 'app-basic-info'; const AppBasic = (props: { appId: string }) => { diff --git a/eiam-console/src/main/console-fe/src/pages/app/AppConfig/components/PermissionResource/UpdateModal.tsx b/eiam-console/src/main/console-fe/src/pages/app/AppConfig/components/PermissionResource/UpdateModal.tsx new file mode 100644 index 00000000..6c711332 --- /dev/null +++ b/eiam-console/src/main/console-fe/src/pages/app/AppConfig/components/PermissionResource/UpdateModal.tsx @@ -0,0 +1,152 @@ +/* + * eiam-console - Employee Identity and Access Management + * Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +import { getPermissionResource, permissionResourceParamCheck } from '../../service'; +import { ModalForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components'; +import { Form, Spin } from 'antd'; +import React, { useState } from 'react'; +import { useAsyncEffect } from 'ahooks'; +import Paragraph from 'antd/es/typography/Paragraph'; + +type UpdateFormProps = { + /** + * ID + */ + id?: string; + /** + * SYSTEM + */ + appId: string; + /** + * 是否显示 + */ + open: boolean; + /** + * 取消方法 + */ + onCancel: (e?: React.MouseEvent | React.KeyboardEvent) => void; + /** + * 提交 + */ + onFinish?: (formData: Record) => Promise; +}; +const UpdateResource: React.FC = (props) => { + const { open, onCancel, onFinish, id, appId } = props; + const [loading, setLoading] = useState(false); + const [form] = Form.useForm(); + + useAsyncEffect(async () => { + if (open && id) { + setLoading(true); + const { success, result } = await getPermissionResource(id); + if (success && result) { + setLoading(false); + return; + } + } + }, [id, onCancel, open]); + + return ( + { + setLoading(true); + const result = await onFinish?.(values); + setLoading(false); + return result; + }} + > + + + + ); +}; +export default UpdateResource; diff --git a/eiam-console/src/main/console-fe/src/pages/app/AppCreate/AppCreate.tsx b/eiam-console/src/main/console-fe/src/pages/app/AppCreate/AppCreate.tsx index d04ea3b7..a2e044fc 100644 --- a/eiam-console/src/main/console-fe/src/pages/app/AppCreate/AppCreate.tsx +++ b/eiam-console/src/main/console-fe/src/pages/app/AppCreate/AppCreate.tsx @@ -21,6 +21,7 @@ import { ModalForm, PageContainer, ProCard, + ProFormSelect, ProFormText, ProFormTextArea, ProList, @@ -38,6 +39,7 @@ import classnames from 'classnames'; import { ListTemplate } from './data.d'; import { AppType } from '@/constant'; import { createApp, getAppTemplateList } from './service'; +import { getAllAppGroupList } from '@/services/app'; const { Paragraph } = Typography; const prefixCls = 'topiam-create-app'; @@ -106,7 +108,7 @@ const CreateApp = (props: { onOk: () => { successModal.destroy(); history.push( - `/app/config?id=${result.id}&name=${values.name}&protocol=${protocol}`, + `/app/list/config?id=${result.id}&name=${values.name}&protocol=${protocol}`, ); }, }); @@ -128,6 +130,23 @@ const CreateApp = (props: { }, ]} /> + { + setLoading(true); + const { success, data } = await getAllAppGroupList({}, {}, {}).finally(() => { + setLoading(false); + }); + if (success && data) { + return data.map((i) => { + return { label: i.name, value: i.id }; + }); + } + return []; + }} + /> { ); }} /> - {createAppTemplate && ( - { - setCreateAppOpen(false); - setCreateAppTemplate(undefined); - }} - /> - )} + {createAppTemplate && ( + { + setCreateAppOpen(false); + setCreateAppTemplate(undefined); + }} + /> + )}
); }; -export default () => { - return ; -}; +export default AppCreate; diff --git a/eiam-console/src/main/console-fe/src/pages/app/AppGroup/AppGroup.tsx b/eiam-console/src/main/console-fe/src/pages/app/AppGroup/AppGroup.tsx new file mode 100644 index 00000000..5def7cd0 --- /dev/null +++ b/eiam-console/src/main/console-fe/src/pages/app/AppGroup/AppGroup.tsx @@ -0,0 +1,221 @@ +/* + * eiam-console - Employee Identity and Access Management + * Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +import { PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons'; +import type { ActionType, ProColumns } from '@ant-design/pro-components'; +import { PageContainer, ProTable } from '@ant-design/pro-components'; +import { App, Button, Popconfirm, Tag } from 'antd'; +import { useRef, useState } from 'react'; +import CreateModal from './components/CreateModal'; +import UpdateModal from './components/UpdateModal'; +import { createAppGroup, removeAppGroup, updateAppGroup } from './service'; +import { useIntl } from '@@/exports'; +import { getAppGroupList } from '@/services/app'; + +export default () => { + const intl = useIntl(); + const actionRef = useRef(); + const [createModalOpen, setCreateModalOpen] = useState(false); + const [updateModalOpen, setUpdateModalOpen] = useState(false); + const [id, setId] = useState(); + const { message } = App.useApp(); + const columns: ProColumns[] = [ + { + title: intl.formatMessage({ id: 'pages.app_group.list.column.name' }), + dataIndex: 'name', + fixed: 'left', + }, + { + title: intl.formatMessage({ id: 'pages.app_group.list.column.code' }), + dataIndex: 'code', + }, + { + title: intl.formatMessage({ id: 'pages.app_group.list.column.app_count' }), + dataIndex: 'appCount', + search: false, + }, + { + title: intl.formatMessage({ id: 'pages.app_group.list.column.type' }), + dataIndex: 'type', + valueEnum: { + default: { + text: intl.formatMessage({ + id: 'pages.app_group.list.column.type.default', + }), + }, + custom: { + text: intl.formatMessage({ + id: 'pages.app_group.list.column.type.custom', + }), + }, + }, + render: (_, record) => ( + <> + {record.type === 'custom' && ( + + {intl.formatMessage({ + id: 'pages.app_group.list.column.type.custom', + })} + + )} + {record.type === 'default' && ( + + {intl.formatMessage({ + id: 'pages.app_group.list.column.type.default', + })} + + )} + + ), + }, + { + title: intl.formatMessage({ id: 'pages.app_group.list.column.create_time' }), + dataIndex: 'createTime', + search: false, + align: 'center', + ellipsis: true, + }, + { + title: intl.formatMessage({ id: 'pages.app_group.list.column.remark' }), + dataIndex: 'remark', + search: false, + ellipsis: true, + }, + { + title: intl.formatMessage({ id: 'pages.app_group.list.column.option' }), + valueType: 'option', + key: 'option', + width: 100, + align: 'center', + render: (text, record) => [ + { + setId(record.id); + setUpdateModalOpen(true); + }} + > + {intl.formatMessage({ id: 'app.update' })} + , + + } + onConfirm={async () => { + const { success } = await removeAppGroup(record.id); + if (success) { + message.success(intl.formatMessage({ id: 'app.operation_success' })); + actionRef.current?.reload(); + return; + } + }} + okText={intl.formatMessage({ id: 'app.yes' })} + cancelText={intl.formatMessage({ id: 'app.no' })} + key="delete" + > + + {intl.formatMessage({ id: 'app.delete' })} + + , + ], + }, + ]; + + return ( + + + columns={columns} + actionRef={actionRef} + request={getAppGroupList} + rowKey="id" + search={{ + labelWidth: 'auto', + }} + scroll={{ x: 900 }} + form={{ + syncToUrl: (values, type) => { + if (type === 'get') { + return { + ...values, + }; + } + return values; + }, + }} + pagination={{ + pageSize: 5, + }} + dateFormatter="string" + toolBarRender={() => [ + , + ]} + /> + { + setCreateModalOpen(false); + }} + onFinish={async (values) => { + const { result, success } = await createAppGroup(values); + if (success && result) { + message.success(intl.formatMessage({ id: 'app.create_success' })); + actionRef.current?.reload(); + } + actionRef.current?.reload(); + setCreateModalOpen(false); + return true; + }} + /> + {id && ( + { + setUpdateModalOpen(false); + }} + onFinish={async (values) => { + const { result, success } = await updateAppGroup(values); + if (success && result) { + message.success(intl.formatMessage({ id: 'app.create_success' })); + actionRef.current?.reload(); + } + actionRef.current?.reload(); + setUpdateModalOpen(false); + return true; + }} + /> + )} + + ); +}; diff --git a/eiam-console/src/main/console-fe/src/pages/app/AppGroup/components/UpdateModal/UpdateModal.tsx b/eiam-console/src/main/console-fe/src/pages/app/AppGroup/components/UpdateModal/UpdateModal.tsx new file mode 100644 index 00000000..2b441811 --- /dev/null +++ b/eiam-console/src/main/console-fe/src/pages/app/AppGroup/components/UpdateModal/UpdateModal.tsx @@ -0,0 +1,105 @@ +/* + * eiam-console - Employee Identity and Access Management + * Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +import { ModalForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components'; +import { Form, Spin } from 'antd'; +import React, { useState } from 'react'; +import { useIntl } from '@@/exports'; +import { getAppGroup } from '@/pages/app/AppGroup/service'; + +export default (props: { + id: string; + open: boolean; + onFinish: (formData: Record) => Promise; + onCancel: (e: React.MouseEvent) => void; +}) => { + const { id, open, onCancel, onFinish } = props; + const [form] = Form.useForm(); + const intl = useIntl(); + const [loading, setLoading] = useState(false); + + return ( + { + if (visible) { + setLoading(true); + const { result, success } = await getAppGroup(id).finally(() => { + setLoading(false); + }); + if (success) { + form.setFieldsValue(result); + } + } + }} + onFinish={async (values) => { + setLoading(true); + await onFinish(values).finally(() => { + setLoading(false); + }); + }} + > + + + + ); +}; diff --git a/eiam-console/src/main/console-fe/src/pages/app/AppGroup/data.d.ts b/eiam-console/src/main/console-fe/src/pages/app/AppGroup/data.d.ts new file mode 100644 index 00000000..90b20117 --- /dev/null +++ b/eiam-console/src/main/console-fe/src/pages/app/AppGroup/data.d.ts @@ -0,0 +1,17 @@ +/* + * eiam-console - Employee Identity and Access Management + * Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ diff --git a/eiam-console/src/main/console-fe/src/pages/app/AppGroup/service.ts b/eiam-console/src/main/console-fe/src/pages/app/AppGroup/service.ts new file mode 100644 index 00000000..f17337f9 --- /dev/null +++ b/eiam-console/src/main/console-fe/src/pages/app/AppGroup/service.ts @@ -0,0 +1,62 @@ +/* + * eiam-console - Employee Identity and Access Management + * Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +import { request } from '@umijs/max'; + +/** + * 创建应用分组 + */ +export async function createAppGroup( + params: Record, +): Promise>> { + return request>>(`/api/v1/app/group/create`, { + method: 'POST', + data: params, + requestType: 'json', + }); +} + +/** + * 获取应用分组 + */ +export async function getAppGroup(id: string): Promise>> { + return request>>(`/api/v1/app/group/get/${id}`, { + method: 'GET', + }); +} + +/** + * 修改应用分组 + */ +export async function updateAppGroup( + params: Record, +): Promise>> { + return request>>(`/api/v1/app/group/update`, { + method: 'PUT', + data: params, + requestType: 'json', + }); +} + +/** + * Remove App Group + */ +export async function removeAppGroup(id: string): Promise> { + return request>(`/api/v1/app/group/delete/${id}`, { + method: 'DELETE', + }); +} diff --git a/eiam-console/src/main/console-fe/src/pages/app/AppList/AppList.tsx b/eiam-console/src/main/console-fe/src/pages/app/AppList/AppList.tsx index 7ff32e36..e6f29f57 100644 --- a/eiam-console/src/main/console-fe/src/pages/app/AppList/AppList.tsx +++ b/eiam-console/src/main/console-fe/src/pages/app/AppList/AppList.tsx @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import { getAppList } from '@/services/app'; +import { getAllAppGroupList, getAppList } from '@/services/app'; import { PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons'; import type { ActionType } from '@ant-design/pro-components'; import { PageContainer, ProList } from '@ant-design/pro-components'; @@ -86,7 +86,7 @@ export default () => { key={'create'} type="primary" onClick={() => { - history.push('/app/create'); + history.push('/app/list/create'); }} > @@ -102,7 +102,7 @@ export default () => { { history.push( - `/app/config?id=${row.id}&protocol=${row.protocol}&name=${row.name}`, + `/app/list/config?id=${row.id}&protocol=${row.protocol}&name=${row.name}`, ); }} > @@ -177,7 +177,7 @@ export default () => { key="config" onClick={() => { history.push( - `/app/config?id=${row.id}&protocol=${row.protocol}&name=${row.name}`, + `/app/list/config?id=${row.id}&protocol=${row.protocol}&name=${row.name}`, ); }} > @@ -213,6 +213,25 @@ export default () => { , ], }, + status: { + // 自己扩展的字段,主要用于筛选,不在列表中显示 + title: intl.formatMessage({ + id: 'pages.app.list.metas.group', + }), + valueType: 'select', + fieldProps: { + mode: 'multiple', + }, + request: async () => { + const { success, data } = await getAllAppGroupList({}, {}, {}); + if (success && data) { + return data.map((i) => { + return { label: i.name, value: i.id }; + }); + } + return []; + }, + }, }} />