mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-06 01:17:46 +08:00
- 添加批量余额查询并发限制,避免数据库连接池耗尽 - 支持余额加载 pending 状态和前端自动重试机制 - 添加用户可用模型 API,统一使用 AccessRestrictions - 修复用户表单编辑时数组引用共享导致的数据覆盖问题 - 添加数据库连接池配置说明到 .env.example
120 lines
3.1 KiB
TypeScript
120 lines
3.1 KiB
TypeScript
import { computed, watch, type Ref, type ComputedRef } from 'vue'
|
||
|
||
/**
|
||
* 表单对话框通用逻辑
|
||
*
|
||
* 统一处理:
|
||
* - 编辑/创建模式切换
|
||
* - 对话框打开/关闭
|
||
* - 表单重置
|
||
* - 数据加载
|
||
* - Loading 状态阻止关闭
|
||
*
|
||
* @example
|
||
* ```typescript
|
||
* const { isEditMode, handleDialogUpdate, handleCancel } = useFormDialog({
|
||
* isOpen: () => props.modelValue,
|
||
* entity: () => props.provider,
|
||
* isLoading: loading,
|
||
* onClose: () => emit('update:modelValue', false),
|
||
* loadData: loadProviderData,
|
||
* resetForm,
|
||
* })
|
||
* ```
|
||
*/
|
||
export interface UseFormDialogOptions<E> {
|
||
/** 对话框是否打开(getter 函数) */
|
||
isOpen: () => boolean
|
||
/** 编辑的实体(getter 函数,返回 null/undefined 表示创建模式) */
|
||
entity: () => E | null | undefined
|
||
/** 是否处于加载状态 */
|
||
isLoading: Ref<boolean> | ComputedRef<boolean>
|
||
/** 关闭对话框的回调 */
|
||
onClose: () => void
|
||
/** 加载实体数据的函数(编辑模式时调用) */
|
||
loadData: () => void
|
||
/** 重置表单的函数 */
|
||
resetForm: () => void
|
||
/** 额外的加载状态(如清理缓存等),可选 */
|
||
extraLoadingStates?: Array<Ref<boolean> | ComputedRef<boolean>>
|
||
}
|
||
|
||
export interface UseFormDialogReturn {
|
||
/** 是否为编辑模式 */
|
||
isEditMode: ComputedRef<boolean>
|
||
/** 处理对话框更新事件(用于 @update:model-value) */
|
||
handleDialogUpdate: (value: boolean) => void
|
||
/** 处理取消按钮点击 */
|
||
handleCancel: () => void
|
||
}
|
||
|
||
export function useFormDialog<E>(
|
||
options: UseFormDialogOptions<E>
|
||
): UseFormDialogReturn {
|
||
const {
|
||
isOpen,
|
||
entity,
|
||
isLoading,
|
||
onClose,
|
||
loadData,
|
||
resetForm,
|
||
extraLoadingStates = [],
|
||
} = options
|
||
|
||
// 是否为编辑模式
|
||
const isEditMode = computed(() => !!entity())
|
||
|
||
// 检查是否有任何加载状态
|
||
const isAnyLoading = computed(() => {
|
||
if (isLoading.value) return true
|
||
return extraLoadingStates.some((state) => state.value)
|
||
})
|
||
|
||
// 处理对话框更新事件
|
||
function handleDialogUpdate(value: boolean) {
|
||
// 加载中不允许关闭
|
||
if (!value && isAnyLoading.value) {
|
||
return
|
||
}
|
||
// 关闭时重置表单
|
||
if (!value) {
|
||
resetForm()
|
||
}
|
||
onClose()
|
||
}
|
||
|
||
// 处理取消按钮
|
||
function handleCancel() {
|
||
if (isAnyLoading.value) return
|
||
onClose()
|
||
}
|
||
|
||
// 监听打开状态变化
|
||
watch(isOpen, (val) => {
|
||
if (val) {
|
||
if (isEditMode.value && entity()) {
|
||
loadData()
|
||
} else {
|
||
resetForm()
|
||
}
|
||
}
|
||
})
|
||
|
||
// 监听实体变化(编辑模式切换)
|
||
// 注意:不使用 deep: true,只在实体引用变化时触发(如从 user A 切换到 user B)
|
||
// 使用 deep: true 会导致实体的深层属性变化时也触发,覆盖用户正在编辑的数据
|
||
watch(entity, (newEntity, oldEntity) => {
|
||
// 只在实体引用真正变化时(如切换用户)才重新加载
|
||
// 避免深层属性变化时意外触发
|
||
if (newEntity && isOpen() && newEntity !== oldEntity) {
|
||
loadData()
|
||
}
|
||
}, { immediate: true })
|
||
|
||
return {
|
||
isEditMode,
|
||
handleDialogUpdate,
|
||
handleCancel,
|
||
}
|
||
}
|