2026-07-23 17:47:38 +08:00

90 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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<MenuItem[]>([])
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<DialogConfig>({ title: '', msg: '' })
let dialogResolve: ((v: string | boolean) => void) | null = null
function showDialog(config: DialogConfig): Promise<string | boolean> {
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<boolean> {
return showDialog({ icon, title, msg, buttons: ['好'] }).then(() => true)
}
async function confirm(
title: string, msg: string,
opts: { ok?: string; danger?: boolean; icon?: string } = {}
): Promise<boolean> {
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<string | null> {
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,
}
})