/* ===================================================================== * dialog.ts — 全局对话框服务(替代原生 alert/confirm/prompt) * * Promise 风格:await appConfirm('删除?') → boolean * 渲染走 AppDialogHost(主 app 内 Teleport 到 body), * App.vue 模板放置 即接线,无需手动 mount * ===================================================================== */ import { ref } from 'vue' export interface DialogOptions { type: 'alert' | 'confirm' | 'prompt' title: string message?: string /** prompt 默认值 */ defaultValue?: string /** input placeholder */ placeholder?: string /** 确认按钮文案(默认「确定」) */ okText?: string /** 危险操作样式(确认按钮红色) */ danger?: boolean } interface DialogResult { ok: boolean; value: string } type Resolver = (r: DialogResult) => void /* ---------- 模块级响应式状态(AppDialogHost 渲染消费) ---------- */ export const dialogState = { open: ref(false), options: ref(null) } let resolver: Resolver | null = null /** 由 AppDialogHost 的 close 事件回调 */ export function resolveDialog(r: DialogResult) { dialogState.open.value = false dialogState.options.value = null if (resolver) { resolver(r); resolver = null } } function show(opts: DialogOptions): Promise { return new Promise(resolve => { resolver = resolve dialogState.options.value = opts dialogState.open.value = true }) } /* ---------- 对外 API ---------- */ /** 信息提示(替代 alert) */ export function appAlert(title: string, message?: string) { return show({ type: 'alert', title, message }) } /** 确认(替代 confirm)→ Promise */ export function appConfirm(title: string, message?: string, opts?: { okText?: string; danger?: boolean }) { return show({ type: 'confirm', title, message, okText: opts?.okText, danger: opts?.danger }).then(r => r.ok) } /** 输入(替代 prompt)→ Promise(取消为 null) */ export function appPrompt(title: string, opts?: { message?: string; defaultValue?: string; placeholder?: string }) { return show({ type: 'prompt', title, message: opts?.message, defaultValue: opts?.defaultValue, placeholder: opts?.placeholder }) .then(r => (r.ok ? r.value : null)) }