/** * uiStore — 菜单/对话框状态管理 * 替代 useUI.ts 中的状态管理部分 */ import { defineStore } from 'pinia' import { ref } from 'vue' import type { MenuItem } from '@/types/app' import type { DialogConfig } from '@/types/ui' export const useUIStore = defineStore('ui', () => { // ---- 弹出菜单 ---- const menuVisible = ref(false) const menuItems = ref([]) const menuPosition = ref({ x: 0, y: 0 }) const menuSub = ref(false) let menuOnClose: (() => void) | null = null function showMenu(items: MenuItem[], x: number, y: number, opts: { sub?: boolean; onClose?: () => void } = {}) { hideMenu() menuItems.value = items menuPosition.value = { x, y } menuSub.value = !!opts.sub menuVisible.value = true menuOnClose = opts.onClose ?? null } function hideMenu() { menuOnClose?.() menuOnClose = null menuVisible.value = false } function showContextMenu(items: MenuItem[], e: MouseEvent) { e.preventDefault(); e.stopPropagation() showMenu(items, e.clientX, e.clientY) } // ---- 对话框 ---- const dialogVisible = ref(false) const dialogConfig = ref({ title: '', msg: '' }) let dialogResolve: ((v: string | boolean) => void) | null = null function showDialog(config: DialogConfig): Promise { return new Promise(resolve => { dialogConfig.value = config dialogVisible.value = true dialogResolve = resolve }) } function resolveDialog(value: string | boolean) { dialogVisible.value = false dialogResolve?.(value) dialogResolve = null } async function alert(title: string, msg: string, icon?: string): Promise { return showDialog({ icon, title, msg, buttons: ['好'] }).then(() => true) } async function confirm( title: string, msg: string, opts: { ok?: string; danger?: boolean; icon?: string } = {} ): Promise { const result = await showDialog({ icon: opts.icon, title, msg, ok: opts.ok || '确定', danger: opts.danger, }) return result === 'ok' || result === true } async function prompt(title: string, msg: string, defaultValue?: string): Promise { const result = await showDialog({ title, msg: msg + (defaultValue ? `\n\n默认值:${defaultValue}` : ''), ok: '确定', }) return typeof result === 'string' ? result : null } return { // menu menuVisible, menuItems, menuPosition, menuSub, showMenu, hideMenu, showContextMenu, // dialog dialogVisible, dialogConfig, showDialog, resolveDialog, alert, confirm, prompt, } })