import { useCallback, useMemo, useState } from "react"; import { createPopup, deletePopup, listPopups, updatePopup } from "@/features/app-config/api"; import { useAppConfigAbilities } from "@/features/app-config/permissions.js"; import { appPopupSchema } from "@/features/app-config/schema"; import { parseForm } from "@/shared/forms/validation"; import { useAdminQuery } from "@/shared/hooks/useAdminQuery.js"; import { useConfirm } from "@/shared/ui/ConfirmProvider.jsx"; import { useToast } from "@/shared/ui/ToastProvider.jsx"; const emptyData = { items: [], total: 0 }; const emptyForm = () => ({ code: "", displayPeriodDays: "0", endsAtMs: "", imageUrl: "", jumpType: "h5", jumpUrl: "", name: "", sortOrder: "0", startsAtMs: "", status: "active", }); export function usePopupConfigPage() { const abilities = useAppConfigAbilities(); const confirm = useConfirm(); const { showToast } = useToast(); const [keyword, setKeyword] = useState(""); const [status, setStatus] = useState(""); const [activeAction, setActiveAction] = useState(""); const [editingItem, setEditingItem] = useState(null); const [form, setFormState] = useState(emptyForm); const [loadingAction, setLoadingAction] = useState(""); const filters = useMemo( () => ({ keyword, status, }), [keyword, status], ); const queryFn = useCallback(() => listPopups(filters), [filters]); const { data = emptyData, error, loading, reload, } = useAdminQuery(queryFn, { errorMessage: "加载弹窗配置失败", initialData: emptyData, queryKey: ["app-config", "popups", filters], }); const setForm = (patch) => { setFormState((current) => ({ ...current, ...patch })); }; const openCreate = () => { setEditingItem(null); setFormState(emptyForm()); setActiveAction("create"); }; const openEdit = (item) => { setEditingItem(item); setFormState(formFromPopup(item)); setActiveAction("edit"); }; const closeDialog = () => { setActiveAction(""); setEditingItem(null); setFormState(emptyForm()); }; const resetFilters = () => { setKeyword(""); setStatus(""); }; const submitPopup = async (event) => { event.preventDefault(); const payload = parseForm(appPopupSchema, normalizeForm(form)); const action = editingItem ? "edit" : "create"; setLoadingAction(action); try { if (editingItem) { await updatePopup(editingItem.id, payload); showToast("弹窗配置已更新", "success"); } else { await createPopup(payload); showToast("弹窗配置已新增", "success"); } closeDialog(); await reload(); } catch (err) { showToast(err.message || "操作失败", "error"); } finally { setLoadingAction(""); } }; const removePopup = async (item) => { const ok = await confirm({ confirmText: "删除", message: item.name || item.jumpUrl || `弹窗配置 ${item.id}`, title: "删除弹窗配置", tone: "danger", }); if (!ok) { return; } setLoadingAction(`delete:${item.id}`); try { await deletePopup(item.id); await reload(); showToast("弹窗配置已删除", "success"); } catch (err) { showToast(err.message || "删除失败", "error"); } finally { setLoadingAction(""); } }; return { abilities, activeAction, closeDialog, data, editingItem, error, form, keyword, loading, loadingAction, openCreate, openEdit, reload, removePopup, resetFilters, setForm, setKeyword, setStatus, status, submitPopup, }; } function normalizeForm(form) { return { ...form, displayPeriodDays: form.displayPeriodDays || 0, endsAtMs: form.endsAtMs || 0, imageUrl: form.imageUrl || "", sortOrder: form.sortOrder || 0, startsAtMs: form.startsAtMs || 0, }; } function formFromPopup(item) { return { code: item.code || "", displayPeriodDays: String(item.displayPeriodDays ?? 0), endsAtMs: item.endsAtMs || "", imageUrl: item.imageUrl || "", jumpType: item.jumpType || "h5", jumpUrl: item.jumpUrl || "", name: item.name || "", sortOrder: String(item.sortOrder || 0), startsAtMs: item.startsAtMs || "", status: item.status || "active", }; }