Merge pull request 'feat: 添加删除全部modal的方法' (#50) from dev-zw into dev

This commit is contained in:
cp3hnu 2024-05-24 11:40:57 +08:00
commit 1385310b27
32 changed files with 133 additions and 108 deletions

View File

@ -17,6 +17,7 @@ export enum ModelDeploymentStatus {
Running = 'Running', // 运行中
Stopped = 'Stopped', // 已停止
Failed = 'Failed', // 失败
Pending = 'Pending', // 挂起中
}
export const modelDeploymentStatusOptions = [
@ -25,4 +26,5 @@ export const modelDeploymentStatusOptions = [
{ label: '运行中', value: ModelDeploymentStatus.Running },
{ label: '已停止', value: ModelDeploymentStatus.Stopped },
{ label: '失败', value: ModelDeploymentStatus.Failed },
{ label: '挂起中', value: ModelDeploymentStatus.Pending },
];

View File

@ -126,13 +126,3 @@ export const useResetFormOnCloseModal = (form: FormInstance, open: boolean) => {
}
}, [form, prevOpen, open]);
};
export const useInputModel = <T>(initialValue: T) => {
const [value, setValue] = useState<T>(initialValue);
const updateValue = useCallback((e: any) => {
setValue(e.target?.value);
}, []);
return [value, updateValue];
};

View File

@ -4,6 +4,7 @@ import { to } from '@/utils/promise';
import { type SelectProps } from 'antd';
import { useCallback, useEffect, useState } from 'react';
// 获取资源规格
export function useComputingResource() {
const [resourceStandardList, setResourceStandardList] = useState<ComputingResource[]>([]);

View File

@ -1,6 +1,7 @@
import { getSessionStorageItem, removeSessionStorageItem } from '@/utils/sessionStorage';
import { useEffect, useState } from 'react';
// 获取缓存数据
export function useSessionStorage<T>(key: string, isObject: boolean, initialValue: T) {
const [storage, setStorage] = useState<T>(initialValue);

View File

@ -7,6 +7,7 @@ import { getDictSelectOption } from '@/services/system/dict';
import { to } from '@/utils/promise';
import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui';
import {
App,
Button,
Form,
Input,
@ -14,7 +15,6 @@ import {
Select,
Upload,
UploadFile,
message,
type ModalProps,
type UploadProps,
} from 'antd';
@ -32,6 +32,7 @@ interface AddDatasetModalProps extends Omit<ModalProps, 'onOk'> {
function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalProps) {
const [uuid] = useState(Date.now());
const [clusterOptions, setClusterOptions] = useState<DictValueEnumObj[]>([]);
const { message } = App.useApp();
useEffect(() => {
getClusterOptions();

View File

@ -6,13 +6,13 @@ import { addModel } from '@/services/dataset/index.js';
import { to } from '@/utils/promise';
import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui';
import {
App,
Button,
Form,
Input,
Select,
Upload,
UploadFile,
message,
type ModalProps,
type UploadProps,
} from 'antd';
@ -28,6 +28,8 @@ interface AddModelModalProps extends Omit<ModalProps, 'onOk'> {
function AddModelModal({ typeList, tagList, onOk, ...rest }: AddModelModalProps) {
const [uuid] = useState(Date.now());
const { message } = App.useApp();
// 上传组件参数
const uploadProps: UploadProps = {
action: '/api/mmp/models/upload',

View File

@ -5,12 +5,12 @@ import { ResourceType, resourceConfig } from '@/pages/Dataset/types';
import { to } from '@/utils/promise';
import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui';
import {
App,
Button,
Form,
Input,
Upload,
UploadFile,
message,
type ModalProps,
type UploadProps,
} from 'antd';
@ -33,6 +33,7 @@ function AddVersionModal({
...rest
}: AddVersionModalProps) {
const [uuid] = useState(Date.now());
const { message } = App.useApp();
// 上传组件参数
const uploadProps: UploadProps = {

View File

@ -5,7 +5,7 @@ import { openAntdModal } from '@/utils/modal';
import { to } from '@/utils/promise';
import { modalConfirm } from '@/utils/ui';
import { useNavigate } from '@umijs/max';
import { Button, Input, Pagination, PaginationProps, message } from 'antd';
import { App, Button, Input, Pagination, PaginationProps } from 'antd';
import { Ref, forwardRef, useEffect, useImperativeHandle, useState } from 'react';
import { CategoryData, ResourceData, ResourceType, resourceConfig } from '../../types';
import AddDatasetModal from '../AddDatasetModal';
@ -53,6 +53,7 @@ function ResourceList(
);
const [searchText, setSearchText] = useState(initialSearchText);
const [inputText, setInputText] = useState(initialSearchText);
const { message } = App.useApp();
useEffect(() => {
getDataList();

View File

@ -11,7 +11,7 @@ import { downLoadZip } from '@/utils/downloadfile';
import { openAntdModal } from '@/utils/modal';
import { modalConfirm } from '@/utils/ui';
import { useParams, useSearchParams } from '@umijs/max';
import { Button, Input, Select, Table, Tabs, message } from 'antd';
import { App, Button, Input, Select, Table, Tabs } from 'antd';
import { useEffect, useRef, useState } from 'react';
import AddVersionModal from './components/AddVersionModal';
import Styles from './intro.less';
@ -19,6 +19,7 @@ const { Search } = Input;
const { TabPane } = Tabs;
const Dataset = () => {
const { message } = App.useApp();
const [formList, setFormList] = useState([]);
const [datasetDetailObj, setDatasetDetailObj] = useState({});
const [version, setVersion] = useState(null);

View File

@ -97,6 +97,11 @@ function AddExperimentModal({
wrapperCol: { span: 20 },
};
const paramLayout = {
labelCol: { span: 8 },
wrapperCol: { span: 16 },
};
// 除了流水线选择发生变化
const handleWorkflowChange = (id: string | number) => {
const pipeline: Workflow | undefined = workflowList.find((v) => v.id === id);
@ -187,7 +192,7 @@ function AddExperimentModal({
fields.map(({ key, name, ...restField }) => (
<Form.Item
{...restField}
{...layout}
{...paramLayout}
key={key}
label={getParamType(globalParam[name])}
name={[name, 'param_value']}

View File

@ -1,9 +1,7 @@
import SubAreaTitle from '@/components/SubAreaTitle';
import { getComputingResourceReq } from '@/services/pipeline';
import { useComputingResource } from '@/hooks/resource';
import { PipelineNodeModelSerialize } from '@/types';
import { to } from '@/utils/promise';
import { Form, Input, Select, type FormProps } from 'antd';
import { useEffect, useState } from 'react';
import styles from './index.less';
const { TextArea } = Input;
@ -13,24 +11,7 @@ type ExperimentParameterProps = {
};
function ExperimentParameter({ form, nodeData }: ExperimentParameterProps) {
const [resourceStandardList, setResourceStandardList] = useState([]); // 资源规模列表
useEffect(() => {
getComputingResource();
}, []);
// 获取资源规格列表数据
const getComputingResource = async () => {
const params = {
page: 0,
size: 1000,
resource_type: '',
};
const [res] = await to(getComputingResourceReq(params));
if (res && res.data && res.data.content) {
setResourceStandardList(res.data.content);
}
};
const [resourceStandardList] = useComputingResource(); // 资源规模
// 控制策略
const controlStrategyList = Object.entries(nodeData.control_strategy ?? {}).map(

View File

@ -18,7 +18,7 @@ import themes from '@/styles/theme.less';
import { elapsedTime, formatDate } from '@/utils/date';
import { to } from '@/utils/promise';
import { modalConfirm } from '@/utils/ui';
import { Button, ConfigProvider, Space, Table, message } from 'antd';
import { App, Button, ConfigProvider, Space, Table } from 'antd';
import classNames from 'classnames';
import { useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
@ -47,6 +47,7 @@ function Experiment() {
const [isAdd, setIsAdd] = useState(true);
const [isModalOpen, setIsModalOpen] = useState(false);
const [addFormData, setAddFormData] = useState({});
const { message } = App.useApp();
useEffect(() => {
getList();

View File

@ -18,7 +18,7 @@ export enum ExperimentStatus {
export const experimentStatusInfo: Record<ExperimentStatus, StatusInfo | undefined> = {
Running: {
label: '运行中',
color: '#165bff',
color: '#1664ff',
icon: '/assets/images/running-icon.png',
},
Succeeded: {
@ -53,7 +53,7 @@ export const experimentStatusInfo: Record<ExperimentStatus, StatusInfo | undefin
},
Omitted: {
label: '未执行',
color: '#8a8a8ae',
color: '#8a8a8a',
icon: '/assets/images/omitted-icon.png',
},
};

View File

@ -18,7 +18,7 @@ import {
} from '@/utils/sessionStorage';
import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui';
import { useNavigate } from '@umijs/max';
import { Button, Col, Form, Input, Row, Upload, UploadFile, message, type UploadProps } from 'antd';
import { App, Button, Col, Form, Input, Row, Upload, UploadFile, type UploadProps } from 'antd';
import { omit } from 'lodash';
import { useEffect, useState } from 'react';
import styles from './index.less';
@ -49,6 +49,7 @@ function MirrorCreate() {
const navgite = useNavigate();
const [form] = Form.useForm();
const [nameDisabled, setNameDisabled] = useState(false);
const { message } = App.useApp();
const uploadProps: UploadProps = {
action: '/api/mmp/image/upload',

View File

@ -68,11 +68,13 @@ function MirrorInfo() {
pageSize: 10,
},
);
const isPublic = searchParams.get('isPublic') === 'true';
const { message } = App.useApp();
const isPublic = searchParams.get('isPublic') === 'true';
useEffect(() => {
getMirrorInfo();
}, []);
useEffect(() => {
getMirrorVersionList();
}, [pagination]);

View File

@ -15,12 +15,12 @@ import { mirrorNameKey, setSessionStorageItem } from '@/utils/sessionStorage';
import { modalConfirm } from '@/utils/ui';
import { useNavigate } from '@umijs/max';
import {
App,
Button,
ConfigProvider,
Input,
Table,
Tabs,
message,
type TablePaginationConfig,
type TableProps,
type TabsProps,
@ -64,6 +64,7 @@ function MirrorList() {
pageSize: 10,
},
);
const { message } = App.useApp();
useEffect(() => {
getMirrorList();
@ -174,13 +175,14 @@ function MirrorList() {
title: '版本数据',
dataIndex: 'version_count',
key: 'version_count',
width: 100,
width: '15%',
render: CommonTableCell(),
},
{
title: '镜像描述',
dataIndex: 'description',
key: 'description',
width: '35%',
render: CommonTableCell(true),
ellipsis: { showTitle: false },
},
@ -188,7 +190,7 @@ function MirrorList() {
title: '创建时间',
dataIndex: 'create_time',
key: 'create_time',
width: 200,
width: '20%',
render: DateTableCell,
},
{

View File

@ -1,7 +1,7 @@
/*
* @Author:
* @Date: 2024-04-18 18:35:41
* @Description:
* @Description:
*/
import { MirrorVersionStatus } from '@/enums';
import styles from './index.less';
@ -26,7 +26,7 @@ const statusInfo: Record<MirrorVersionStatus, MirrorVersionStatusInfo> = {
},
};
function MirrorStatusCell(status: MirrorVersionStatus) {
function MirrorStatusCell(status?: MirrorVersionStatus | null) {
if (status === null || status === undefined || !statusInfo[status]) {
return <span>--</span>;
}

View File

@ -12,7 +12,7 @@ import { downLoadZip } from '@/utils/downloadfile';
import { openAntdModal } from '@/utils/modal';
import { modalConfirm } from '@/utils/ui';
import { useParams, useSearchParams } from '@umijs/max';
import { Button, Input, Select, Table, Tabs, message } from 'antd';
import { App, Button, Input, Select, Table, Tabs } from 'antd';
import { useEffect, useRef, useState } from 'react';
import Styles from './intro.less';
const { Search } = Input;
@ -26,6 +26,7 @@ const Dataset = () => {
const locationParams = useParams(); //
const [searchParams] = useSearchParams();
const [wordList, setWordList] = useState([]);
const { message } = App.useApp();
const isPublic = searchParams.get('isPublic') === 'true';
const getModelByDetail = () => {

View File

@ -164,7 +164,7 @@ function ModelDeploymentInfo() {
</Col>
<Col span={10}>
<div className={styles['model-deployment-info__basic__item']}>
<div className={styles['label']}></div>
<div className={styles['label']}></div>
<div className={styles['value']}>
{modelDeployementInfo?.resource
? getResourceDescription(modelDeployementInfo.resource)
@ -174,7 +174,7 @@ function ModelDeploymentInfo() {
</Col>
</Row>
<Row gutter={40}>
<Col span={24}>
<Col span={18}>
<div className={styles['model-deployment-info__basic__item']}>
<div className={styles['label']}>  </div>
<div className={styles['value']}>{modelDeployementInfo?.description ?? '--'}</div>

View File

@ -249,7 +249,8 @@ function ModelDeployment() {
</Button>
)}
{(record.status === ModelDeploymentStatus.Running ||
record.status === ModelDeploymentStatus.Init) && (
record.status === ModelDeploymentStatus.Init ||
record.status === ModelDeploymentStatus.Pending) && (
<Button
type="link"
size="small"

View File

@ -6,10 +6,14 @@
}
&--stopped {
color: @warning-color;
color: @abort-color;
}
&--error {
color: @error-color;
}
&--pending {
color: @warning-color;
}
}

View File

@ -28,9 +28,13 @@ export const statusInfo: Record<ModelDeploymentStatus, ModelDeploymentStatusInfo
classname: styles['model-deployment-status-cell--error'],
text: '失败',
},
[ModelDeploymentStatus.Pending]: {
classname: styles['model-deployment-status-cell--pending'],
text: '挂起中',
},
};
function ModelDeploymentStatusCell(status: ModelDeploymentStatus | undefined) {
function ModelDeploymentStatusCell(status?: ModelDeploymentStatus | null) {
if (status === null || status === undefined || !statusInfo[status]) {
return <span>--</span>;
}

View File

@ -26,13 +26,7 @@ export type ModelDeploymentData = {
// 操作类型
export enum ModelDeploymentOperationType {
Create = 'create',
Update = 'update',
Restart = 'restart',
Create = 'Create',
Update = 'Update',
Restart = 'Restart',
}
// 状态
export type ModelDeploymentStatusInfo = {
text: string;
classname: string;
};

View File

@ -1,4 +1,5 @@
import { DictOptionType, DictValueEnumObj } from '@/components/DictTag';
import KFModal from '@/components/KFModal';
import {
ProForm,
ProFormCaptcha,
@ -9,9 +10,8 @@ import {
ProFormTextArea,
} from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Form, Modal } from 'antd';
import { Form } from 'antd';
import React, { useEffect } from 'react';
import KFModal from '@/components/KFModal';
/**
* Edit Form
*

View File

@ -3,7 +3,7 @@ import { useStateRef, useVisible } from '@/hooks';
import { getWorkflowById, saveWorkflow } from '@/services/pipeline/index.js';
import { to } from '@/utils/promise';
import G6 from '@antv/g6';
import { Button, message } from 'antd';
import { App, Button } from 'antd';
import { useEffect, useRef } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { s8 } from '../../../utils';
@ -24,7 +24,7 @@ const EditPipeline = () => {
const propsRef = useRef();
const [paramsDrawerOpen, openParamsDrawer, closeParamsDrawer] = useVisible(false);
const [globalParam, setGlobalParam, globalParamRef] = useStateRef([]);
const { message } = App.useApp();
let sourceAnchorIdx, targetAnchorIdx;
const onDragEnd = (val) => {

View File

@ -1,14 +1,17 @@
import KFIcon from '@/components/KFIcon';
import ParameterInput from '@/components/ParameterInput';
import SubAreaTitle from '@/components/SubAreaTitle';
import { getComputingResourceReq } from '@/services/pipeline';
import { useComputingResource } from '@/hooks/resource';
import { openAntdModal } from '@/utils/modal';
import { to } from '@/utils/promise';
import { Button, Drawer, Form, Input, Select } from 'antd';
import { pick } from 'lodash';
import { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
import { forwardRef, useImperativeHandle, useState } from 'react';
import PropsLabel from '../components/PropsLabel';
import ResourceSelectorModal, { ResourceSelectorType } from '../components/ResourceSelectorModal';
import ResourceSelectorModal, {
ResourceSelectorType,
selectorTypeConfig,
} from '../components/ResourceSelectorModal';
import styles from './props.less';
import { canInput, createMenuItems } from './utils';
const { TextArea } = Input;
@ -19,26 +22,9 @@ const Props = forwardRef(({ onParentChange }, ref) => {
const [open, setOpen] = useState(false);
const [selectedModel, setSelectedModel] = useState(undefined); //
const [selectedDataset, setSelectedDataset] = useState(undefined); //
const [resourceStandardList, setResourceStandardList] = useState([]); //
const [resourceStandardList, filterResourceStandard] = useComputingResource(); //
const [menuItems, setMenuItems] = useState([]);
useEffect(() => {
getComputingResource();
}, []);
//
const getComputingResource = async () => {
const params = {
page: 0,
size: 1000,
resource_type: '',
};
const [res] = await to(getComputingResourceReq(params));
if (res && res.data && res.data.content) {
setResourceStandardList(res.data.content);
}
};
const afterOpenChange = () => {
if (!open) {
console.log('zzzzz', form.getFieldsValue());
@ -57,6 +43,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
const onClose = () => {
setOpen(false);
};
useImperativeHandle(ref, () => ({
getFieldsValue: async () => {
const [propsRes, propsError] = await to(form.validateFields());
@ -155,18 +142,16 @@ const Props = forwardRef(({ onParentChange }, ref) => {
// icon
const getSelectBtnIcon = (item) => {
const type = item.item_type;
let selectorType;
if (type === 'dataset') {
return <KFIcon type="icon-xuanzeshujuji" />;
selectorType = ResourceSelectorType.Dataset;
} else if (type === 'model') {
return <KFIcon type="icon-xuanzemoxing" />;
selectorType = ResourceSelectorType.Model;
} else {
return <KFIcon type="icon-xuanzejingxiang" />;
selectorType = ResourceSelectorType.Mirror;
}
};
//
const filterResourceStandard = (input, { computing_resource = '' }) => {
return computing_resource.toLocaleLowerCase().includes(input.toLocaleLowerCase());
return <KFIcon type={selectorTypeConfig[selectorType].buttonIcon} />;
};
//

View File

@ -12,7 +12,7 @@ import {
} from '@/services/pipeline/index.js';
import themes from '@/styles/theme.less';
import { modalConfirm } from '@/utils/ui';
import { Button, ConfigProvider, Form, Input, Space, Table, message } from 'antd';
import { App, Button, ConfigProvider, Form, Input, Space, Table } from 'antd';
import classNames from 'classnames';
import { useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
@ -28,6 +28,7 @@ const Pipeline = () => {
const [pipeList, setPipeList] = useState([]);
const [total, setTotal] = useState(0);
const [isModalOpen, setIsModalOpen] = useState(false);
const { message } = App.useApp();
const editTable = (e, record) => {
e.stopPropagation();
getWorkflowById(record.id).then((ret) => {
@ -66,7 +67,7 @@ const Pipeline = () => {
} else {
addWorkflow(values).then((ret) => {
console.log(ret);
if (ret.code == 200) {
if (ret.code === 200) {
navgite({ pathname: `/pipeline/template/${ret.data.id}/${ret.data.name}` });
}
});

View File

@ -3,7 +3,7 @@
* @Date: 2024-03-25 13:52:54
* @Description: https://umijs.org/docs/max/request
*/
import type { RequestConfig } from '@umijs/max';
import type { AxiosRequestConfig, AxiosResponse, RequestConfig } from '@umijs/max';
import { message } from 'antd';
import { clearSessionToken, getAccessToken } from './access';
import { setRemoteMenu } from './services/session';
@ -16,8 +16,8 @@ import { gotoLoginPage } from './utils/ui';
export const requestConfig: RequestConfig = {
errorConfig: {},
requestInterceptors: [
(url: any, options: { headers: any }) => {
const headers = options.headers ? options.headers : [];
(url: string, options: AxiosRequestConfig) => {
const headers = options.headers ?? {};
const authHeader = headers['Authorization'];
const isToken = headers['isToken'];
if (!authHeader && isToken !== false) {
@ -30,7 +30,7 @@ export const requestConfig: RequestConfig = {
},
],
responseInterceptors: [
(response: any) => {
(response: AxiosResponse) => {
const { status, data } = response || {};
if (status >= 200 && status < 300) {
if (data && (data instanceof Blob || data.code === 200)) {

View File

@ -14,6 +14,7 @@
@success-color: #1ace62;
@error-color: #c73131;
@warning-color: #f98e1b;
@abort-color: #8a8a8a;
@border-color: rgba(22, 100, 255, 0.3);
@border-color-secondary: rgba(22, 100, 255, 0.1);

View File

@ -29,7 +29,7 @@ export function parseJsonText(text?: string | null): any | null {
}
}
// Underscore-to-camelCase
// underscore-to-camelCase
export function underscoreToCamelCase(obj: Record<string, any>) {
const newObj: Record<string, any> = {};
for (const key in obj) {
@ -47,6 +47,7 @@ export function underscoreToCamelCase(obj: Record<string, any>) {
return newObj;
}
// camelCase-to-underscore
export function camelCaseToUnderscore(obj: Record<string, any>) {
const newObj: Record<string, any> = {};
for (const key in obj) {
@ -61,3 +62,21 @@ export function camelCaseToUnderscore(obj: Record<string, any>) {
}
return newObj;
}
// null 转 undefined
export function nullToUndefined(obj: Record<string, any>) {
const newObj: Record<string, any> = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];
if (value === null) {
newObj[key] = undefined;
} else if (typeof value === 'object' && value !== null) {
newObj[key] = nullToUndefined(value);
} else {
newObj[key] = value;
}
}
}
return newObj;
}

View File

@ -9,6 +9,8 @@ import zhCN from 'antd/locale/zh_CN';
import React, { useState } from 'react';
import { createRoot } from 'react-dom/client';
const destroyFns: (() => void)[] = [];
/**
* Function to open an Ant Design modal.
*
@ -16,7 +18,6 @@ import { createRoot } from 'react-dom/client';
* @param modalProps - The modal properties.
* @return An object with a destroy method to close the modal.
*/
export const openAntdModal = <T extends Omit<ModalProps, 'onOk'>>(
modal: (props: T) => React.ReactNode,
modalProps: T,
@ -29,6 +30,11 @@ export const openAntdModal = <T extends Omit<ModalProps, 'onOk'>>(
let timeoutId: ReturnType<typeof setTimeout>;
function destroy() {
const index = destroyFns.indexOf(close);
if (index !== -1) {
destroyFns.splice(index, 1);
}
root.unmount();
}
@ -79,6 +85,8 @@ export const openAntdModal = <T extends Omit<ModalProps, 'onOk'>>(
render({ ...modalProps, open: true });
destroyFns.push(close);
return {
close,
};
@ -88,19 +96,23 @@ export const openAntdModal = <T extends Omit<ModalProps, 'onOk'>>(
* Generates a custom hook for managing an Ant Design modal.
*
* @param modal - The function that renders the modal content.
* @param key - The key for the modal.
* @param defaultProps - The default modal properties.
* @return The modal component, open function, and close function.
*/
export const useAntdModal = <T extends ModalProps>(
export const useModal = <T extends ModalProps>(
modal: (props: T) => React.ReactNode,
key: React.Key,
defaultProps?: T,
) => {
const [visible, setVisible] = useState(false);
const [props, setProps] = useState<T>({} as T);
const [props, setProps] = useState<T>(defaultProps || ({} as T));
const CustomModel = modal;
const open = (props: T) => {
setProps(props);
setProps((prev) => ({
...prev,
...props,
}));
setVisible(true);
};
@ -108,5 +120,14 @@ export const useAntdModal = <T extends ModalProps>(
setVisible(false);
};
return [<CustomModel key={key} open={visible} {...props} />, open, close] as const;
return [<CustomModel key="modal" open={visible} {...props} />, open, close] as const;
};
// 关闭没有手动关闭的 Modal
export const closeAllModals = () => {
let close = destroyFns.pop();
while (close) {
close();
close = destroyFns.pop();
}
};

View File

@ -7,6 +7,7 @@ import { PageEnum } from '@/enums/pagesEnums';
import themes from '@/styles/theme.less';
import { history } from '@umijs/max';
import { Modal, message, type ModalFuncProps, type UploadFile } from 'antd';
import { closeAllModals } from './modal';
// 自定义 Confirm 弹框
export function modalConfirm({ title, content, onOk, ...rest }: ModalFuncProps) {
@ -58,6 +59,7 @@ export const gotoLoginPage = (toHome: boolean = true) => {
console.log('pathname', pathname);
console.log('search', search);
if (window.location.pathname !== PageEnum.LOGIN) {
closeAllModals();
history.replace({
pathname: PageEnum.LOGIN,
search: newSearch,