/*
* @Author: 赵伟
* @Date: 2024-04-19 14:42:51
* @Description: UI 公共方法
*/
import { PageEnum } from '@/enums/pagesEnums';
import { removeAllPageCacheState } from '@/hooks/useCacheState';
import { deleteUploadFileReq } from '@/services/dataset/index.js';
import themes from '@/styles/theme.less';
import { type AppResponse, type ClientInfo, type UploadFileRes } from '@/types';
import { to } from '@/utils/promise';
import { history } from '@umijs/max';
import {
Modal,
Upload,
message,
type FormInstance,
type ModalFuncProps,
type UploadFile,
} from 'antd';
import { NamePath } from 'antd/es/form/interface';
import { isEmpty } from './index';
import { closeAllModals } from './modal';
import SessionStorage from './sessionStorage';
type ModalConfirmProps = ModalFuncProps & {
isDelete?: boolean;
};
/**
* 自定义 Confirm 弹框
*/
export function modalConfirm({
title,
content,
okText = '确认',
cancelText = '取消',
isDelete = true,
onOk,
...rest
}: ModalConfirmProps) {
Modal.confirm({
...rest,
width: 600,
centered: true,
title: (
{title}
),
content: content && {content}
,
okText: okText,
cancelText: cancelText,
onOk: onOk,
});
}
/**
* 跳转到登录页
* @param toHome - 是否跳转到首页
*/
export const gotoLoginPage = (toHome: boolean = true) => {
const { pathname, search } = location;
const urlParams = new URLSearchParams();
urlParams.append('redirect', pathname + search);
const newSearch = toHome || pathname === '/' ? '' : urlParams.toString();
if (pathname !== PageEnum.LOGIN) {
closeAllModals();
removeAllPageCacheState();
history.replace({
pathname: PageEnum.LOGIN,
search: newSearch,
});
}
};
/**
* 跳转到 OAuth2 登录页
*/
export const gotoOAuth2 = () => {
const clientInfo = SessionStorage.getItem(SessionStorage.clientInfoKey, true) as ClientInfo;
if (clientInfo) {
const { clientId, userAuthorizationUri } = clientInfo;
const url = `${userAuthorizationUri}?client_id=${clientId}&response_type=code&grant_type=authorization_code`;
location.replace(url);
}
};
/**
* 从事件中获取上传文件列表,用于 Upload + Form 中
* @param e - 事件,包含文件列表 fileList
*/
export const getFileListFromEvent = (e: any) => {
const fileList: UploadFile[] = (Array.isArray(e) ? e : e?.fileList) || [];
return fileList.map((item) => {
if (item.status === 'done') {
const { response } = item;
if (response?.code !== 200) {
return {
...item,
status: 'error',
};
}
}
return item;
});
};
/**
* 验证文件上传
*
* @param {UploadFile[]} files - The array of uploaded files.
* @param {boolean} [required=true] - Flag indicating if files are required.
* @return {boolean} Returns true if all files are valid, false otherwise.
*/
export const validateUploadFiles = (files: UploadFile[], required: boolean = true): boolean => {
if (required && files.length === 0) {
message.error('请上传文件');
return false;
}
const hasError = files.some((file) => {
if (file.status === 'uploading') {
message.error('请等待文件上传完成');
return true;
}
if (file.status === 'error') {
message.error('存在上传失败的文件,请删除后重新上传');
return true;
}
if (!file.response || file.response.code !== 200 || !file.response.data) {
message.error('存在上传失败的文件,请删除后重新上传');
return true;
}
return false;
});
return !hasError;
};
/**
* 限制上传文件类型
* @param type - 只允许上次的的文件类型
*/
export const limitUploadFileType = (type: string) => {
return (file: UploadFile): boolean | string => {
const acceptTypes = type.split(',').map((item) => item.trim());
const fileType = file.name.split('.').pop()?.trim();
if (!(fileType && acceptTypes.includes(fileType))) {
message.error(`文件类型不正确,只支持 "${acceptTypes.join('、')}" 类型的文件`);
file.status = 'error';
return Upload.LIST_IGNORE;
}
return true;
};
};
/**
* 删除已上传的文件
* @param file - 已上传的文件
*/
export const removeUploadedFile = async (file: UploadFile>) => {
const { status, response } = file;
const { code, data } = response ?? {};
if (status === 'done' && code === 200 && Array.isArray(data) && data.length > 0) {
const uploadRes = data[0];
const { fileName, url } = uploadRes;
const [res] = await to(
deleteUploadFileReq({
fileName,
url,
}),
);
if (res) {
return true;
} else {
return false;
}
}
return true;
};
/**
* 删除 FormList 表单项,如果表单项没有值,则直接删除,否则弹出确认框
* @param form - From实例
* @param listName - FormList 的 name
* @param name - FormList 的其中一项
* @param remove - FormList 的删除方法
* @param fieldNames - FormList 的子项名称数组
* @param confirmTitle - 弹出确认框的标题
*/
export const removeFormListItem = (
form: FormInstance,
listName: NamePath,
name: number,
remove: (name: number) => void,
fieldNames: NamePath[],
confirmTitle: string,
) => {
const fields = fieldNames.map((item) => [listName, name, item].flat());
const isEmptyField = fields.every((item) => {
const value = form.getFieldValue(item);
return isEmpty(value);
});
if (isEmptyField) {
remove(name);
return;
}
modalConfirm({
title: confirmTitle,
content: '是否确认删除?',
onOk: () => {
remove(name);
},
});
};
/**
* 退出子系统
* @param url - 退出登录的地址
*/
export const oauthLogout = (url: string) => {
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = url;
document.body.appendChild(iframe);
};