mirror of https://gitee.com/topiam/eiam
Merge remote-tracking branch 'origin/master'
# Conflicts: # eiam-portal/src/main/java/cn/topiam/employee/portal/converter/AppGroupConverter.javapull/43/head
commit
7b9e8058f7
|
@ -47,7 +47,7 @@
|
||||||
"@ant-design/charts": "^1.4.2",
|
"@ant-design/charts": "^1.4.2",
|
||||||
"@ant-design/icons": "^5.2.6",
|
"@ant-design/icons": "^5.2.6",
|
||||||
"@ant-design/maps": "^1.0.7",
|
"@ant-design/maps": "^1.0.7",
|
||||||
"@ant-design/pro-components": "^2.6.16",
|
"@ant-design/pro-components": "^2.6.18",
|
||||||
"ahooks": "^3.7.8",
|
"ahooks": "^3.7.8",
|
||||||
"antd": "^5.8.6",
|
"antd": "^5.8.6",
|
||||||
"antd-img-crop": "^4.12.2",
|
"antd-img-crop": "^4.12.2",
|
||||||
|
@ -89,14 +89,14 @@
|
||||||
"@types/google-libphonenumber": "^7.4.26",
|
"@types/google-libphonenumber": "^7.4.26",
|
||||||
"@types/history": "^4.7.11",
|
"@types/history": "^4.7.11",
|
||||||
"@types/js-yaml": "^4.0.5",
|
"@types/js-yaml": "^4.0.5",
|
||||||
"@types/lodash": "^4.14.197",
|
"@types/lodash": "^4.14.198",
|
||||||
"@types/numeral": "^2.0.2",
|
"@types/numeral": "^2.0.2",
|
||||||
"@types/qs": "^6.9.8",
|
"@types/qs": "^6.9.8",
|
||||||
"@types/react": "^18.2.21",
|
"@types/react": "^18.2.21",
|
||||||
"@types/react-dom": "^18.2.7",
|
"@types/react-dom": "^18.2.7",
|
||||||
"@types/react-helmet": "^6.1.6",
|
"@types/react-helmet": "^6.1.6",
|
||||||
"@umijs/lint": "^4.0.79",
|
"@umijs/lint": "^4.0.80",
|
||||||
"@umijs/max": "^4.0.79",
|
"@umijs/max": "^4.0.80",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"cross-port-killer": "^1.4.0",
|
"cross-port-killer": "^1.4.0",
|
||||||
"eslint": "^8.48.0",
|
"eslint": "^8.48.0",
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import { Avatar, Image } from 'antd';
|
import { Avatar, Image } from 'antd';
|
||||||
import { AvatarSize } from 'antd/es/avatar/SizeContext';
|
import { AvatarSize } from 'antd/es/avatar/AvatarContext';
|
||||||
|
|
||||||
export default (props: {
|
export default (props: {
|
||||||
avatar: string;
|
avatar: string;
|
||||||
|
|
|
@ -46,7 +46,7 @@ export default () => {
|
||||||
history.push(`/account/user`);
|
history.push(`/account/user`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!type) {
|
if (!type || !UserDetailTabs[type]) {
|
||||||
setTabActiveKey(UserDetailTabs.user_info);
|
setTabActiveKey(UserDetailTabs.user_info);
|
||||||
history.replace({
|
history.replace({
|
||||||
pathname: location.pathname,
|
pathname: location.pathname,
|
||||||
|
|
|
@ -55,7 +55,7 @@ export default () => {
|
||||||
history.push(`/account/user-group`);
|
history.push(`/account/user-group`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!type) {
|
if (!type || !UserGroupDetailTabs[type]) {
|
||||||
setTabActiveKey(UserGroupDetailTabs.member);
|
setTabActiveKey(UserGroupDetailTabs.member);
|
||||||
history.push({
|
history.push({
|
||||||
pathname: location.pathname,
|
pathname: location.pathname,
|
||||||
|
|
|
@ -48,8 +48,10 @@ export default (props: {
|
||||||
preserve={false}
|
preserve={false}
|
||||||
width="500px"
|
width="500px"
|
||||||
open={visible}
|
open={visible}
|
||||||
onOpenChange={() => {
|
onOpenChange={(visible) => {
|
||||||
|
if (visible) {
|
||||||
form.setFieldsValue({ code: random(9) });
|
form.setFieldsValue({ code: random(9) });
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
modalProps={{
|
modalProps={{
|
||||||
maskClosable: true,
|
maskClosable: true,
|
||||||
|
@ -58,9 +60,9 @@ export default (props: {
|
||||||
}}
|
}}
|
||||||
onFinish={async (values: AccountAPI.BaseUserGroup) => {
|
onFinish={async (values: AccountAPI.BaseUserGroup) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const result = await onFinish(values);
|
await onFinish(values).finally(() => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
return !!result;
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Spin spinning={loading}>
|
<Spin spinning={loading}>
|
||||||
|
|
|
@ -136,7 +136,7 @@ const CreateUser = (props: CreateUserProps) => {
|
||||||
*/
|
*/
|
||||||
const cancel = async () => {
|
const cancel = async () => {
|
||||||
if (onCancel) {
|
if (onCancel) {
|
||||||
await onCancel();
|
onCancel();
|
||||||
}
|
}
|
||||||
setSubmitLoading(false);
|
setSubmitLoading(false);
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
|
|
|
@ -99,7 +99,7 @@ const UpdateUser = (props: UpdateFormProps) => {
|
||||||
*/
|
*/
|
||||||
const cancel = async () => {
|
const cancel = async () => {
|
||||||
if (onCancel) {
|
if (onCancel) {
|
||||||
await onCancel();
|
onCancel();
|
||||||
}
|
}
|
||||||
setSubmitLoading(false);
|
setSubmitLoading(false);
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
|
|
|
@ -38,3 +38,105 @@ export type GetApp = {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
remark: string;
|
remark: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用权限列表
|
||||||
|
*/
|
||||||
|
export type AppAccessPolicyList = {
|
||||||
|
id: string;
|
||||||
|
//主体ID
|
||||||
|
subjectId: string;
|
||||||
|
//主体名称
|
||||||
|
subjectName: string;
|
||||||
|
//主体类型
|
||||||
|
subjectType: string;
|
||||||
|
//应用类型
|
||||||
|
appType: string;
|
||||||
|
appProtocol: string;
|
||||||
|
//Effect
|
||||||
|
effect: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色列表
|
||||||
|
*/
|
||||||
|
type AppPermissionRoleList = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
enabled: boolean;
|
||||||
|
appId: string;
|
||||||
|
remark: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色列表
|
||||||
|
*/
|
||||||
|
type GetAppPermissionRole = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
enabled: boolean;
|
||||||
|
appId: string;
|
||||||
|
remark: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源列表
|
||||||
|
*/
|
||||||
|
type AppPermissionResourceList = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
enabled: boolean;
|
||||||
|
desc: string;
|
||||||
|
appId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限资源点
|
||||||
|
*/
|
||||||
|
type AppPermissionResourceActionList = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
desc: string;
|
||||||
|
appId: string;
|
||||||
|
menus: {
|
||||||
|
access: string;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}[];
|
||||||
|
datas: {
|
||||||
|
access: string;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}[];
|
||||||
|
buttons: {
|
||||||
|
access: string;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}[];
|
||||||
|
apis: {
|
||||||
|
access: string;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}[];
|
||||||
|
others: {
|
||||||
|
access: string;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限授权列表
|
||||||
|
*/
|
||||||
|
type AppPermissionPolicyList = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
enabled: boolean;
|
||||||
|
desc: string;
|
||||||
|
appId: string;
|
||||||
|
};
|
||||||
|
|
|
@ -39,6 +39,7 @@ import CreateAdministrator from './components/CreateAdministrator';
|
||||||
import UpdateAdministrator from './components/UpdateAdministrator';
|
import UpdateAdministrator from './components/UpdateAdministrator';
|
||||||
import ResetPassword from './components/ResetAdministratorPassword';
|
import ResetPassword from './components/ResetAdministratorPassword';
|
||||||
import Avatar from '@/components/UserAvatar';
|
import Avatar from '@/components/UserAvatar';
|
||||||
|
import { AdministratorList } from './data';
|
||||||
|
|
||||||
export const Administrator = () => {
|
export const Administrator = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
@ -49,7 +50,7 @@ export const Administrator = () => {
|
||||||
const [resetPasswordVisible, setResetPasswordVisible] = useState<boolean>(false);
|
const [resetPasswordVisible, setResetPasswordVisible] = useState<boolean>(false);
|
||||||
const [id, setId] = useState<string>();
|
const [id, setId] = useState<string>();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const columns: ProColumns<SettingAPI.AdministratorList>[] = [
|
const columns: ProColumns<AdministratorList>[] = [
|
||||||
{
|
{
|
||||||
title: intl.formatMessage({ id: 'pages.setting.administrator.table.columns.username' }),
|
title: intl.formatMessage({ id: 'pages.setting.administrator.table.columns.username' }),
|
||||||
dataIndex: 'username',
|
dataIndex: 'username',
|
||||||
|
@ -289,7 +290,7 @@ export const Administrator = () => {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<ProTable<SettingAPI.AdministratorList>
|
<ProTable<AdministratorList>
|
||||||
actionRef={actionRef}
|
actionRef={actionRef}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey={'id'}
|
rowKey={'id'}
|
||||||
|
|
|
@ -18,3 +18,14 @@
|
||||||
export type SecurityDefensePolicyConfig = {
|
export type SecurityDefensePolicyConfig = {
|
||||||
contentSecurityPolicy: string;
|
contentSecurityPolicy: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 安全基础配置
|
||||||
|
*/
|
||||||
|
export type BasicSettingConfig = {
|
||||||
|
frequentRegisterCheck: boolean;
|
||||||
|
emailVerifiedDefault: boolean;
|
||||||
|
sendWelcomeEmail: boolean;
|
||||||
|
verifyOldEmail: boolean;
|
||||||
|
verifyOldPhone: boolean;
|
||||||
|
};
|
||||||
|
|
|
@ -35,7 +35,7 @@ export default (): React.ReactNode => {
|
||||||
const { type } = query as {
|
const { type } = query as {
|
||||||
type: TabType;
|
type: TabType;
|
||||||
};
|
};
|
||||||
if (!type) {
|
if (!type || !TabType[type]) {
|
||||||
setActiveKey(TabType.mail_template);
|
setActiveKey(TabType.mail_template);
|
||||||
history.replace({
|
history.replace({
|
||||||
pathname: location.pathname,
|
pathname: location.pathname,
|
||||||
|
|
|
@ -26,6 +26,7 @@ import MailTemplateConfig from './MailTemplateConfig';
|
||||||
import useStyle from './style';
|
import useStyle from './style';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
|
import { EmailTemplateList } from '../../data.d';
|
||||||
|
|
||||||
const prefixCls = 'setting-mail-template';
|
const prefixCls = 'setting-mail-template';
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ export default (props: { visible: boolean }) => {
|
||||||
const [content, setContent] = useState<string>('');
|
const [content, setContent] = useState<string>('');
|
||||||
const [configType, setConfigType] = useState<string>('');
|
const [configType, setConfigType] = useState<string>('');
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [dataSource, setDataSource] = useState<SettingAPI.EmailTemplateList[]>([]);
|
const [dataSource, setDataSource] = useState<EmailTemplateList[]>([]);
|
||||||
const [browseVisible, setBrowseVisible] = useState<boolean>(false);
|
const [browseVisible, setBrowseVisible] = useState<boolean>(false);
|
||||||
const { styles } = useStyle(prefixCls);
|
const { styles } = useStyle(prefixCls);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
@ -85,7 +86,7 @@ export default (props: { visible: boolean }) => {
|
||||||
<div className={styles.main}>
|
<div className={styles.main}>
|
||||||
<ProCard className={`${prefixCls}`}>
|
<ProCard className={`${prefixCls}`}>
|
||||||
<Spin spinning={loading}>
|
<Spin spinning={loading}>
|
||||||
<ProList<SettingAPI.EmailTemplateList>
|
<ProList<EmailTemplateList>
|
||||||
rowKey="type"
|
rowKey="type"
|
||||||
split
|
split
|
||||||
cardProps={{ bodyStyle: { padding: 0 } }}
|
cardProps={{ bodyStyle: { padding: 0 } }}
|
||||||
|
|
|
@ -45,6 +45,7 @@ import QiNiu from './QiNiu';
|
||||||
import Tencent from './Tencent';
|
import Tencent from './Tencent';
|
||||||
import { Container } from '@/components/Container';
|
import { Container } from '@/components/Container';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
|
import { SmsTemplateList } from '@/pages/setting/Message/data';
|
||||||
|
|
||||||
const layout = {
|
const layout = {
|
||||||
labelCol: {
|
labelCol: {
|
||||||
|
@ -130,7 +131,7 @@ const TestModal = (props: {
|
||||||
};
|
};
|
||||||
export default (props: { visible: boolean }) => {
|
export default (props: { visible: boolean }) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const editorFormRef = useRef<EditableFormInstance<SettingAPI.SmsTemplateList>>();
|
const editorFormRef = useRef<EditableFormInstance<SmsTemplateList>>();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { message, modal } = App.useApp();
|
const { message, modal } = App.useApp();
|
||||||
const actionRef = useRef<ActionType>();
|
const actionRef = useRef<ActionType>();
|
||||||
|
@ -144,7 +145,7 @@ export default (props: { visible: boolean }) => {
|
||||||
const [enabled, setEnabled] = useState<boolean>(false);
|
const [enabled, setEnabled] = useState<boolean>(false);
|
||||||
const [language, setLanguage] = useState<string>(Language.ZH);
|
const [language, setLanguage] = useState<string>(Language.ZH);
|
||||||
const [editableKeys, setEditableRowKeys] = useState<React.Key[]>();
|
const [editableKeys, setEditableRowKeys] = useState<React.Key[]>();
|
||||||
const [smsTemplateList, setSmsTemplateList] = useState<SettingAPI.SmsTemplateList[]>();
|
const [smsTemplateList, setSmsTemplateList] = useState<SmsTemplateList[]>();
|
||||||
|
|
||||||
const columns: ProColumns[] = [
|
const columns: ProColumns[] = [
|
||||||
{
|
{
|
||||||
|
@ -380,7 +381,7 @@ export default (props: { visible: boolean }) => {
|
||||||
label={intl.formatMessage({ id: 'pages.setting.message.sms_provider.provider' })}
|
label={intl.formatMessage({ id: 'pages.setting.message.sms_provider.provider' })}
|
||||||
rules={[{ required: true }]}
|
rules={[{ required: true }]}
|
||||||
fieldProps={{
|
fieldProps={{
|
||||||
onChange: async (value) => {
|
onChange: async (value: string) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setProvider(value);
|
setProvider(value);
|
||||||
//清理
|
//清理
|
||||||
|
|
|
@ -99,27 +99,20 @@ export default {
|
||||||
'pages.setting.storage_provider.minio.bucket.rule.0.message': 'MinIO Bucket为必填项',
|
'pages.setting.storage_provider.minio.bucket.rule.0.message': 'MinIO Bucket为必填项',
|
||||||
'pages.setting.storage_provider.provider.s3': 'S3',
|
'pages.setting.storage_provider.provider.s3': 'S3',
|
||||||
'pages.setting.storage_provider.provider.s3.endpoint': 'S3 域名',
|
'pages.setting.storage_provider.provider.s3.endpoint': 'S3 域名',
|
||||||
'pages.setting.storage_provider.provider.s3.endpoint.placeholder':
|
'pages.setting.storage_provider.provider.s3.endpoint.placeholder': '请输入 S3 域名',
|
||||||
'请输入 S3 域名',
|
|
||||||
'pages.setting.storage_provider.provider.qiniu_kodo.endpoint.rule.0.message':
|
'pages.setting.storage_provider.provider.qiniu_kodo.endpoint.rule.0.message':
|
||||||
'七牛云Kodo S3 域名为必填项',
|
'七牛云Kodo S3 域名为必填项',
|
||||||
'pages.setting.storage_provider.provider.s3.domain': '外链域名',
|
'pages.setting.storage_provider.provider.s3.domain': '外链域名',
|
||||||
'pages.setting.storage_provider.provider.s3.domain.placeholder':
|
'pages.setting.storage_provider.provider.s3.domain.placeholder': '请输入S3 外链域名',
|
||||||
'请输入S3 外链域名',
|
'pages.setting.storage_provider.provider.s3.domain.rule.0.message': 'S3 外链域名为必填项',
|
||||||
'pages.setting.storage_provider.provider.s3.domain.rule.0.message':
|
'pages.setting.storage_provider.provider.s3.access_key_id.placeholder': '请输入S3 AccessKeyId',
|
||||||
'S3 外链域名为必填项',
|
|
||||||
'pages.setting.storage_provider.provider.s3.access_key_id.placeholder':
|
|
||||||
'请输入S3 AccessKeyId',
|
|
||||||
'pages.setting.storage_provider.provider.s3.access_key_id.rule.0.message':
|
'pages.setting.storage_provider.provider.s3.access_key_id.rule.0.message':
|
||||||
'S3 AccessKeyId为必填项',
|
'S3 AccessKeyId为必填项',
|
||||||
'pages.setting.storage_provider.provider.s3.secret_access_key.placeholder':
|
'pages.setting.storage_provider.provider.s3.secret_access_key.placeholder':
|
||||||
'请输入S3 SecretAccessKey',
|
'请输入S3 SecretAccessKey',
|
||||||
'pages.setting.storage_provider.provider.s3.secret_access_key.rule.0.message':
|
'pages.setting.storage_provider.provider.s3.secret_access_key.rule.0.message':
|
||||||
'S3 SecretAccessKey为必填项',
|
'S3 SecretAccessKey为必填项',
|
||||||
'pages.setting.storage_provider.provider.s3.region.placeholder':
|
'pages.setting.storage_provider.provider.s3.region.placeholder': '请输入S3 Region',
|
||||||
'请输入S3 Region',
|
'pages.setting.storage_provider.provider.s3.bucket.placeholder': '请输入S3 Bucket',
|
||||||
'pages.setting.storage_provider.provider.s3.bucket.placeholder':
|
'pages.setting.storage_provider.provider.s3.bucket.rule.0.message': 'S3 Bucket为必填项',
|
||||||
'请输入S3 Bucket',
|
|
||||||
'pages.setting.storage_provider.provider.s3.bucket.rule.0.message':
|
|
||||||
'S3 Bucket为必填项',
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,18 +21,6 @@ import type { SortOrder } from 'antd/es/table/interface';
|
||||||
import { request } from '@umijs/max';
|
import { request } from '@umijs/max';
|
||||||
import type { UploadFile } from 'antd/es/upload/interface';
|
import type { UploadFile } from 'antd/es/upload/interface';
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Application Template FormSchema
|
|
||||||
*/
|
|
||||||
export async function getAppTemplateFormSchema(
|
|
||||||
code: string,
|
|
||||||
): Promise<API.ApiResult<Record<string, any>>> {
|
|
||||||
return request<API.ApiResult<AppAPI.GetApp>>(`/api/v1/app/template/form_schema`, {
|
|
||||||
method: 'GET',
|
|
||||||
params: { code: code },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取应用列表
|
* 获取应用列表
|
||||||
*/
|
*/
|
||||||
|
@ -65,15 +53,6 @@ export async function updateApp(params: Record<string, string>): Promise<API.Api
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Application
|
|
||||||
*/
|
|
||||||
export async function getApp(id: string): Promise<API.ApiResult<AppAPI.GetApp>> {
|
|
||||||
return request<API.ApiResult<AppAPI.GetApp>>(`/api/v1/app/get/${id}`, {
|
|
||||||
method: 'GET',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Config
|
* Get Config
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -422,28 +422,4 @@ declare namespace AppAPI {
|
||||||
template: string;
|
template: string;
|
||||||
remark: string;
|
remark: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 应用信息
|
|
||||||
*/
|
|
||||||
export type GetApp = {
|
|
||||||
id: string;
|
|
||||||
type: string;
|
|
||||||
name: string;
|
|
||||||
icon: string;
|
|
||||||
template: string;
|
|
||||||
protocol: string;
|
|
||||||
protocolName: string;
|
|
||||||
clientId: string;
|
|
||||||
clientSecret: string;
|
|
||||||
//sso发起方
|
|
||||||
initLoginType: string;
|
|
||||||
//sso登录链接
|
|
||||||
initLoginUrl: string;
|
|
||||||
nameIdValueType: string;
|
|
||||||
//授权范围
|
|
||||||
authorizationType: string;
|
|
||||||
enabled: boolean;
|
|
||||||
remark: string;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ import static cn.topiam.employee.common.constant.AppConstants.APP_PATH;
|
||||||
@Tag(name = "应用分组管理")
|
@Tag(name = "应用分组管理")
|
||||||
@RestController
|
@RestController
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@RequestMapping(value = APP_PATH + "/app_group", produces = MediaType.APPLICATION_JSON_VALUE)
|
@RequestMapping(value = APP_PATH + "/group", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
public class AppGroupController {
|
public class AppGroupController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -96,21 +96,7 @@ public interface AppGroupConverter {
|
||||||
* @param entity {@link AppGroupEntity}
|
* @param entity {@link AppGroupEntity}
|
||||||
* @return {@link AppGroupListResult}
|
* @return {@link AppGroupListResult}
|
||||||
*/
|
*/
|
||||||
default AppGroupListResult entityConvertToAppGroupListResult(AppGroupEntity entity) {
|
AppGroupListResult entityConvertToAppGroupListResult(AppGroupEntity entity);
|
||||||
if (entity == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
AppGroupListResult appGroupListResult = new AppGroupListResult();
|
|
||||||
if (entity.getId() != null) {
|
|
||||||
appGroupListResult.setId(String.valueOf(entity.getId()));
|
|
||||||
}
|
|
||||||
appGroupListResult.setName(entity.getName());
|
|
||||||
appGroupListResult.setCode(entity.getCode());
|
|
||||||
appGroupListResult.setEnabled(entity.getEnabled());
|
|
||||||
appGroupListResult.setRemark(entity.getRemark());
|
|
||||||
return appGroupListResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实体转分组返回
|
* 实体转分组返回
|
||||||
|
@ -118,20 +104,7 @@ public interface AppGroupConverter {
|
||||||
* @param entity {@link AppGroupEntity}
|
* @param entity {@link AppGroupEntity}
|
||||||
* @return {@link AppGroupGetResult}
|
* @return {@link AppGroupGetResult}
|
||||||
*/
|
*/
|
||||||
default AppGroupGetResult entityConvertToAppGroupResult(AppGroupEntity entity) {
|
AppGroupGetResult entityConvertToAppGroupResult(AppGroupEntity entity);
|
||||||
if (entity == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
AppGroupGetResult appGroupGetResult = new AppGroupGetResult();
|
|
||||||
|
|
||||||
if (entity.getId() != null) {
|
|
||||||
appGroupGetResult.setId(String.valueOf(entity.getId()));
|
|
||||||
}
|
|
||||||
appGroupGetResult.setName(entity.getName());
|
|
||||||
appGroupGetResult.setEnabled(entity.getEnabled());
|
|
||||||
appGroupGetResult.setCreateTime(entity.getCreateTime());
|
|
||||||
return appGroupGetResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将分组修改对象转换为entity
|
* 将分组修改对象转换为entity
|
||||||
|
@ -139,12 +112,12 @@ public interface AppGroupConverter {
|
||||||
* @param param {@link AppGroupUpdateParam}
|
* @param param {@link AppGroupUpdateParam}
|
||||||
* @return {@link AppGroupEntity}
|
* @return {@link AppGroupEntity}
|
||||||
*/
|
*/
|
||||||
|
@Mapping(target = "enabled", ignore = true)
|
||||||
@Mapping(target = "deleted", ignore = true)
|
@Mapping(target = "deleted", ignore = true)
|
||||||
@Mapping(target = "updateTime", ignore = true)
|
@Mapping(target = "updateTime", ignore = true)
|
||||||
@Mapping(target = "updateBy", ignore = true)
|
@Mapping(target = "updateBy", ignore = true)
|
||||||
@Mapping(target = "createTime", ignore = true)
|
@Mapping(target = "createTime", ignore = true)
|
||||||
@Mapping(target = "createBy", ignore = true)
|
@Mapping(target = "createBy", ignore = true)
|
||||||
@Mapping(target = "enabled", ignore = false)
|
|
||||||
AppGroupEntity appGroupUpdateParamConverterToEntity(AppGroupUpdateParam param);
|
AppGroupEntity appGroupUpdateParamConverterToEntity(AppGroupUpdateParam param);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -153,6 +126,7 @@ public interface AppGroupConverter {
|
||||||
* @param param {@link AppAccountCreateParam}
|
* @param param {@link AppAccountCreateParam}
|
||||||
* @return {@link AppAccountEntity}
|
* @return {@link AppAccountEntity}
|
||||||
*/
|
*/
|
||||||
|
@Mapping(target = "enabled", expression = "java(Boolean.TRUE)")
|
||||||
@Mapping(target = "deleted", ignore = true)
|
@Mapping(target = "deleted", ignore = true)
|
||||||
@Mapping(target = "id", ignore = true)
|
@Mapping(target = "id", ignore = true)
|
||||||
@Mapping(target = "updateTime", ignore = true)
|
@Mapping(target = "updateTime", ignore = true)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package cn.topiam.employee.console.pojo.result.app;
|
package cn.topiam.employee.console.pojo.result.app;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
@ -58,6 +59,12 @@ public class AppGroupListResult implements Serializable {
|
||||||
@Parameter(description = "是否启用")
|
@Parameter(description = "是否启用")
|
||||||
private Boolean enabled;
|
private Boolean enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@Parameter(description = "创建时间")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 备注
|
* 备注
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -31,7 +31,7 @@ import jakarta.validation.constraints.NotBlank;
|
||||||
* Created by support@topiam.cn on 2023/8/31 23:26
|
* Created by support@topiam.cn on 2023/8/31 23:26
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Schema(description = "分组保存入参")
|
@Schema(description = "应用分组保存入参")
|
||||||
public class AppGroupCreateParam implements Serializable {
|
public class AppGroupCreateParam implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,16 +41,17 @@ public class AppGroupCreateParam implements Serializable {
|
||||||
@Schema(description = "分组名称")
|
@Schema(description = "分组名称")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分组编码
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "分组编码不能为空")
|
||||||
|
@Schema(description = "分组编码")
|
||||||
|
private String code;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 备注
|
* 备注
|
||||||
*/
|
*/
|
||||||
@Schema(description = "备注")
|
@Schema(description = "备注")
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
/**
|
|
||||||
* 分组编码
|
|
||||||
*/
|
|
||||||
@Schema(description = "分组编码")
|
|
||||||
private String code;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,12 +53,6 @@ public class AppGroupUpdateParam implements Serializable {
|
||||||
@Schema(description = "分组编码")
|
@Schema(description = "分组编码")
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
/**
|
|
||||||
* 分组是否启用
|
|
||||||
*/
|
|
||||||
@Schema(description = "分组是否启用")
|
|
||||||
private Boolean enabled;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 备注
|
* 备注
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -30,6 +30,7 @@ import cn.topiam.employee.common.entity.app.AppGroupEntity;
|
||||||
import cn.topiam.employee.common.entity.app.QAppGroupAssociationEntity;
|
import cn.topiam.employee.common.entity.app.QAppGroupAssociationEntity;
|
||||||
import cn.topiam.employee.common.entity.app.QAppGroupEntity;
|
import cn.topiam.employee.common.entity.app.QAppGroupEntity;
|
||||||
import cn.topiam.employee.portal.pojo.result.AppGroupListResult;
|
import cn.topiam.employee.portal.pojo.result.AppGroupListResult;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分组映射
|
* 分组映射
|
||||||
|
@ -61,9 +62,7 @@ public interface AppGroupConverter {
|
||||||
*/
|
*/
|
||||||
default Predicate queryAppGroupAssociationPredicate() {
|
default Predicate queryAppGroupAssociationPredicate() {
|
||||||
QAppGroupAssociationEntity appGroupAssociation = QAppGroupAssociationEntity.appGroupAssociationEntity;
|
QAppGroupAssociationEntity appGroupAssociation = QAppGroupAssociationEntity.appGroupAssociationEntity;
|
||||||
Predicate predicate = appGroupAssociation.deleted.eq(Boolean.FALSE);
|
return appGroupAssociation.deleted.eq(Boolean.FALSE);
|
||||||
//@formatter:on
|
|
||||||
return predicate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,9 +77,9 @@ public interface AppGroupConverter {
|
||||||
List<AppGroupListResult> results = new ArrayList<>();
|
List<AppGroupListResult> results = new ArrayList<>();
|
||||||
for (AppGroupEntity entity : list) {
|
for (AppGroupEntity entity : list) {
|
||||||
AppGroupListResult result = appGroupEntityConverterToResult(entity);
|
AppGroupListResult result = appGroupEntityConverterToResult(entity);
|
||||||
Long count = appGroupAssociationList.stream()
|
long count = appGroupAssociationList.stream()
|
||||||
.filter(t -> t.getGroupId().equals(entity.getId())).count();
|
.filter(t -> t.getGroupId().equals(entity.getId())).count();
|
||||||
result.setAppCount(Integer.valueOf(count.toString()));
|
result.setAppCount(Integer.valueOf(Long.toString(count)));
|
||||||
results.add(result);
|
results.add(result);
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
|
@ -92,6 +91,7 @@ public interface AppGroupConverter {
|
||||||
* @param entity {@link AppGroupEntity}
|
* @param entity {@link AppGroupEntity}
|
||||||
* @return {@link AppGroupEntity}
|
* @return {@link AppGroupEntity}
|
||||||
*/
|
*/
|
||||||
|
@Mapping(target = "appCount", ignore = true)
|
||||||
AppGroupListResult appGroupEntityConverterToResult(AppGroupEntity entity);
|
AppGroupListResult appGroupEntityConverterToResult(AppGroupEntity entity);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
"@ant-design/charts": "^1.4.2",
|
"@ant-design/charts": "^1.4.2",
|
||||||
"@ant-design/icons": "^5.2.6",
|
"@ant-design/icons": "^5.2.6",
|
||||||
"@ant-design/maps": "^1.0.7",
|
"@ant-design/maps": "^1.0.7",
|
||||||
"@ant-design/pro-components": "^2.6.16",
|
"@ant-design/pro-components": "^2.6.18",
|
||||||
"ahooks": "^3.7.8",
|
"ahooks": "^3.7.8",
|
||||||
"antd": "^5.8.6",
|
"antd": "^5.8.6",
|
||||||
"antd-img-crop": "^4.12.2",
|
"antd-img-crop": "^4.12.2",
|
||||||
|
@ -84,14 +84,14 @@
|
||||||
"@types/google-libphonenumber": "^7.4.26",
|
"@types/google-libphonenumber": "^7.4.26",
|
||||||
"@types/history": "^4.7.11",
|
"@types/history": "^4.7.11",
|
||||||
"@types/js-yaml": "^4.0.5",
|
"@types/js-yaml": "^4.0.5",
|
||||||
"@types/lodash": "^4.14.197",
|
"@types/lodash": "^4.14.198",
|
||||||
"@types/numeral": "^2.0.2",
|
"@types/numeral": "^2.0.2",
|
||||||
"@types/qs": "^6.9.8",
|
"@types/qs": "^6.9.8",
|
||||||
"@types/react": "^18.2.21",
|
"@types/react": "^18.2.21",
|
||||||
"@types/react-dom": "^18.2.7",
|
"@types/react-dom": "^18.2.7",
|
||||||
"@types/react-helmet": "^6.1.6",
|
"@types/react-helmet": "^6.1.6",
|
||||||
"@umijs/lint": "^4.0.79",
|
"@umijs/lint": "^4.0.80",
|
||||||
"@umijs/max": "^4.0.79",
|
"@umijs/max": "^4.0.80",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"cross-port-killer": "^1.4.0",
|
"cross-port-killer": "^1.4.0",
|
||||||
"eslint": "^8.48.0",
|
"eslint": "^8.48.0",
|
||||||
|
|
|
@ -45,15 +45,15 @@ const AccountSettings = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const [initConfig, setInitConfig] = useState<AccountSettingState>({
|
const [initConfig, setInitConfig] = useState<AccountSettingState>({
|
||||||
mode: 'inline',
|
mode: 'inline',
|
||||||
selectKey: AccountSettingsStateKey.BASE,
|
selectKey: AccountSettingsStateKey.base,
|
||||||
});
|
});
|
||||||
|
|
||||||
useAsyncEffect(async () => {
|
useAsyncEffect(async () => {
|
||||||
if (!type || !AccountSettingsStateKey[type.toUpperCase()]) {
|
if (!type || !AccountSettingsStateKey[type]) {
|
||||||
setInitConfig({ ...initConfig, selectKey: AccountSettingsStateKey.BASE });
|
setInitConfig({ ...initConfig, selectKey: AccountSettingsStateKey.base });
|
||||||
history.replace({
|
history.replace({
|
||||||
pathname: location.pathname,
|
pathname: location.pathname,
|
||||||
search: queryString.stringify({ type: AccountSettingsStateKey.BASE }),
|
search: queryString.stringify({ type: AccountSettingsStateKey.base }),
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -62,19 +62,19 @@ const AccountSettings = () => {
|
||||||
|
|
||||||
const menu: ItemType[] = [
|
const menu: ItemType[] = [
|
||||||
{
|
{
|
||||||
key: AccountSettingsStateKey.BASE,
|
key: AccountSettingsStateKey.base,
|
||||||
label: intl.formatMessage({
|
label: intl.formatMessage({
|
||||||
id: 'page.account.menu.base',
|
id: 'page.account.menu.base',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: AccountSettingsStateKey.SECURITY,
|
key: AccountSettingsStateKey.security,
|
||||||
label: intl.formatMessage({
|
label: intl.formatMessage({
|
||||||
id: 'page.account.menu.security',
|
id: 'page.account.menu.security',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: AccountSettingsStateKey.BIND,
|
key: AccountSettingsStateKey.bind,
|
||||||
label: intl.formatMessage({
|
label: intl.formatMessage({
|
||||||
id: 'page.account.menu.bind',
|
id: 'page.account.menu.bind',
|
||||||
}),
|
}),
|
||||||
|
@ -113,11 +113,11 @@ const AccountSettings = () => {
|
||||||
const renderChildren = () => {
|
const renderChildren = () => {
|
||||||
const { selectKey } = initConfig;
|
const { selectKey } = initConfig;
|
||||||
switch (selectKey) {
|
switch (selectKey) {
|
||||||
case AccountSettingsStateKey.BASE:
|
case AccountSettingsStateKey.base:
|
||||||
return <BaseView />;
|
return <BaseView />;
|
||||||
case AccountSettingsStateKey.SECURITY:
|
case AccountSettingsStateKey.security:
|
||||||
return <SecurityView />;
|
return <SecurityView />;
|
||||||
case AccountSettingsStateKey.BIND:
|
case AccountSettingsStateKey.bind:
|
||||||
return <BindingView />;
|
return <BindingView />;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -70,7 +70,7 @@ const ModifyPassword = (props: {
|
||||||
destroyOnClose: true,
|
destroyOnClose: true,
|
||||||
maskClosable: false,
|
maskClosable: false,
|
||||||
onCancel: async () => {
|
onCancel: async () => {
|
||||||
await setVisible(false);
|
setVisible(false);
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
onFinish={async (formData: Record<string, any>) => {
|
onFinish={async (formData: Record<string, any>) => {
|
||||||
|
@ -89,7 +89,7 @@ const ModifyPassword = (props: {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (success && result) {
|
if (success && result) {
|
||||||
await setVisible(false);
|
setVisible(false);
|
||||||
message.success(intl.formatMessage({ id: 'page.account.modify_password.success' }));
|
message.success(intl.formatMessage({ id: 'page.account.modify_password.success' }));
|
||||||
setRefresh(true);
|
setRefresh(true);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
|
|
|
@ -40,7 +40,7 @@ export interface GetBoundIdpList {
|
||||||
* 账户菜单类型
|
* 账户菜单类型
|
||||||
*/
|
*/
|
||||||
export enum AccountSettingsStateKey {
|
export enum AccountSettingsStateKey {
|
||||||
BASE = 'base',
|
base = 'base',
|
||||||
SECURITY = 'security',
|
security = 'security',
|
||||||
BIND = 'bind',
|
bind = 'bind',
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,15 @@ export enum InitLoginType {
|
||||||
/**
|
/**
|
||||||
* 仅允许应用发起 SSO
|
* 仅允许应用发起 SSO
|
||||||
*/
|
*/
|
||||||
ONLY_APP_INIT_SSO = 'only_app_init_sso',
|
only_app_init_sso = 'only_app_init_sso',
|
||||||
/**
|
/**
|
||||||
* 门户或应用发起 SSO
|
* 门户或应用发起 SSO
|
||||||
*/
|
*/
|
||||||
PORTAL_OR_APP_INIT_SSO = 'portal_or_app_init_sso',
|
portal_or_app_init_sso = 'portal_or_app_init_sso',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type AppGroupList = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
appCount: number;
|
||||||
|
};
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import type { IDP_TYPE, MFA_FACTOR } from '@/constants';
|
import type { IDP_TYPE } from '@/constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录参数类型
|
* 登录参数类型
|
||||||
|
@ -44,9 +44,3 @@ export type IdpList = {
|
||||||
export type LoginConfig = {
|
export type LoginConfig = {
|
||||||
idps: IdpList[];
|
idps: IdpList[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MfaFactor = {
|
|
||||||
factor: MFA_FACTOR;
|
|
||||||
target?: string;
|
|
||||||
usable: boolean;
|
|
||||||
};
|
|
||||||
|
|
|
@ -16,16 +16,9 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import { request } from '@umijs/max';
|
import { request } from '@umijs/max';
|
||||||
import type { LoginConfig, LoginParamsType, MfaFactor } from './data.d';
|
import type { LoginConfig, LoginParamsType } from './data.d';
|
||||||
import { stringify } from 'querystring';
|
import { stringify } from 'querystring';
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取 Mfa 因素
|
|
||||||
*/
|
|
||||||
export async function getMfaFactors(): Promise<API.ApiResult<MfaFactor>> {
|
|
||||||
return request('/api/v1/login/mfa/factors');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 账户登录
|
* 账户登录
|
||||||
*
|
*
|
||||||
|
@ -74,32 +67,6 @@ export async function sendLoginCaptchaOpt(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送MFA短信验证码
|
|
||||||
*/
|
|
||||||
export async function sendMfaSmsOtp(): Promise<API.ApiResult<boolean>> {
|
|
||||||
return request(`/api/v1/login/mfa/send`, {
|
|
||||||
method: 'POST',
|
|
||||||
data: stringify({ channel: 'sms' }),
|
|
||||||
skipErrorHandler: true,
|
|
||||||
}).catch((e) => {
|
|
||||||
throw e;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送MFA邮件验证码
|
|
||||||
*/
|
|
||||||
export async function sendMfaEmailOtp(): Promise<API.ApiResult<boolean>> {
|
|
||||||
return request(`/api/v1/login/mfa/send`, {
|
|
||||||
method: 'POST',
|
|
||||||
data: stringify({ channel: 'mail' }),
|
|
||||||
skipErrorHandler: true,
|
|
||||||
}).catch((e) => {
|
|
||||||
throw e;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取钉钉授权URL
|
* 获取钉钉授权URL
|
||||||
*
|
*
|
||||||
|
@ -115,22 +82,6 @@ export async function getDingtalkAuthorizeUrl(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取钉钉授权URL
|
|
||||||
*
|
|
||||||
* @param params
|
|
||||||
*/
|
|
||||||
export async function loginMfaValidate(
|
|
||||||
params: Record<string, any>,
|
|
||||||
): Promise<API.ApiResult<string>> {
|
|
||||||
return request(`/api/v1/login/mfa/validate`, {
|
|
||||||
params: params,
|
|
||||||
skipErrorHandler: true,
|
|
||||||
}).catch(({ response: { data } }) => {
|
|
||||||
return data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Idp绑定用户
|
* Idp绑定用户
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue