import { Component, ref, shallowRef } from "vue"; import XEUtils from "xe-utils"; interface DialogProps { title: string; fullscreen?: boolean; width?: number | string; top?: string | number; showClose?: boolean; alignCenter?: boolean; closeOnClickModal?: boolean; closeOnPressEscape?: boolean; } export type CloseValue = "close" | "confirm" | "cancel"; export interface DialogExpose { // 如果报错了会阻止关闭弹窗 confirm: () => any | Promise; // 如果报错了会阻止关闭弹窗 cancel: () => any | Promise; } export namespace UseDialogType { export interface Expose extends DialogExpose {} export interface Emits { (e: "cyDialogConfirm" | "cyDialogCancel", value?: any): void; } } type FirstParam = T extends Component ? P extends Record ? P : {} : never; export interface DialogOptions

{ dialogProps: DialogProps; params?: any; showCancel?: boolean; hideHeader?: boolean; showConfirm?: boolean; showFooter?: boolean; cancelText?: string; confirmText?: string; visible?: boolean; component?: any; componentRef?: DialogExpose; manuallyClose?: ( cb: (value: CloseValue, data: any) => void, currentItem: DialogState ) => void; } export interface DialogState extends DialogOptions { resolve: (val: { value: CloseValue; data: any }) => void; reject: (val: { value: CloseValue; data: any }) => void; dialogKey?: number; closeValue?: CloseValue; } export const dialogStore = ref([]); export const dialogKey = ref(1); export function useDialog( component: C, props: DialogOptions ) { return new Promise((resolve, reject) => { props = { visible: true, component: shallowRef(component), showCancel: true, showConfirm: true, showFooter: true, hideHeader: false, ...props, }; dialogKey.value++; const pushIndex = dialogStore.value.push({ ...props, resolve: XEUtils.once(value => { resolve(value); }), reject: XEUtils.once(value => { reject(value); }), dialogKey: dialogKey.value, closeValue: "close", }); if (props.manuallyClose) { const currentItem = dialogStore.value[pushIndex - 1]; currentItem.dialogProps.showClose = false; currentItem.dialogProps.alignCenter = currentItem.dialogProps.alignCenter ?? true; currentItem.dialogProps.closeOnClickModal = false; currentItem.dialogProps.closeOnPressEscape = false; currentItem.showFooter = false; props.manuallyClose( (value: CloseValue, data: any) => { const item = dialogStore.value[pushIndex - 1]; if (value === "confirm") { item.resolve(data); } else { item.reject({ value: item.closeValue, data }); } item.visible = false; }, dialogStore.value[pushIndex - 1] ); } }); } export const dialogKeyType: InjectionKey = Symbol("cyDialog");