import { useCallback, useEffect, useMemo, useState } from "react"; import { listResourceGroups } from "@/features/resources/api"; import { getCumulativeRechargeRewardConfig, listCumulativeRechargeRewardGrants, updateCumulativeRechargeRewardConfig, } from "@/features/cumulative-recharge-reward/api"; import { useCumulativeRechargeRewardAbilities } from "@/features/cumulative-recharge-reward/permissions.js"; import { usePaginatedQuery } from "@/shared/hooks/usePaginatedQuery.js"; import { useToast } from "@/shared/ui/ToastProvider.jsx"; const pageSize = 50; const emptyGrants = { items: [], page: 1, pageSize, total: 0 }; const emptyForm = { enabled: false, tiers: [], }; export function useCumulativeRechargeRewardPage() { const abilities = useCumulativeRechargeRewardAbilities(); const { showToast } = useToast(); const [config, setConfig] = useState(null); const [configDrawerOpen, setConfigDrawerOpen] = useState(false); const [form, setForm] = useState(emptyForm); const [configLoading, setConfigLoading] = useState(false); const [configSaving, setConfigSaving] = useState(false); const [resourceGroups, setResourceGroups] = useState([]); const [query, setQuery] = useState(""); const [cycleKey, setCycleKey] = useState(""); const [status, setStatus] = useState(""); const [page, setPage] = useState(1); const filters = useMemo(() => ({ keyword: query, cycle_key: cycleKey, status }), [cycleKey, query, status]); const { data: grants = emptyGrants, error: grantsError, loading: grantsLoading, reload: reloadGrants, } = usePaginatedQuery({ errorMessage: "加载累充奖励记录失败", fetcher: listCumulativeRechargeRewardGrants, filters, page, pageSize, queryKey: ["cumulative-recharge-reward-grants", filters, page], }); const reloadConfig = useCallback(async () => { setConfigLoading(true); try { const [config, groups] = await Promise.all([ getCumulativeRechargeRewardConfig(), listResourceGroups({ page: 1, page_size: 100, status: "active" }), ]); setConfig(config); setForm(formFromConfig(config)); setResourceGroups(groups.items || []); } catch (err) { showToast(err.message || "加载累充奖励配置失败", "error"); } finally { setConfigLoading(false); } }, [showToast]); useEffect(() => { void reloadConfig(); }, [reloadConfig]); const openConfigDrawer = useCallback(() => { setForm(config ? formFromConfig(config) : emptyForm); setConfigDrawerOpen(true); }, [config]); const closeConfigDrawer = useCallback(() => { setConfigDrawerOpen(false); setForm(config ? formFromConfig(config) : emptyForm); }, [config]); const changeQuery = (value) => { setQuery(value); setPage(1); }; const changeCycleKey = (value) => { setCycleKey(value); setPage(1); }; const changeStatus = (value) => { setStatus(value); setPage(1); }; const submitConfig = async (event) => { event.preventDefault(); if (!abilities.canUpdate) { return; } setConfigSaving(true); try { const saved = await updateCumulativeRechargeRewardConfig(payloadFromForm(form)); setConfig(saved); setForm(formFromConfig(saved)); setConfigDrawerOpen(false); showToast("累充奖励配置已保存", "success"); await reloadGrants(); } catch (err) { showToast(err.message || "保存累充奖励配置失败", "error"); } finally { setConfigSaving(false); } }; return { abilities, changeCycleKey, changeQuery, changeStatus, closeConfigDrawer, config, configDrawerOpen, configLoading, configSaving, cycleKey, form, grants, grantsError, grantsLoading, openConfigDrawer, page, query, reloadConfig, reloadGrants, resourceGroups, setForm, setPage, status, submitConfig, }; } function formFromConfig(config) { return { enabled: Boolean(config.enabled), tiers: (config.tiers || []).map((tier) => ({ tierId: tier.tierId || 0, tierCode: tier.tierCode || "", tierName: tier.tierName || "", thresholdUsd: tier.thresholdUsdMinor ? String((tier.thresholdUsdMinor / 100).toFixed(2)) : "", resourceGroupId: tier.resourceGroupId ? String(tier.resourceGroupId) : "", status: tier.status || "active", sortOrder: String(tier.sortOrder || 0), })), }; } function payloadFromForm(form) { const tiers = (form.tiers || []).map((tier, index) => { const thresholdUsdMinor = Math.round(Number(tier.thresholdUsd || 0) * 100); const resourceGroupId = Number(tier.resourceGroupId || 0); if (thresholdUsdMinor <= 0) { throw new Error("充值 USD 金额必须大于 0"); } if (resourceGroupId <= 0) { throw new Error("请选择资源组"); } const existingTier = Number(tier.tierId || 0) > 0; const tierCode = String(tier.tierCode || "").trim() || `cumulative_recharge_${Date.now()}_${index + 1}`; const tierName = existingTier && String(tier.tierName || "").trim() ? String(tier.tierName).trim() : `累充 ${(thresholdUsdMinor / 100).toFixed(2)} USD`; return { tier_id: Number(tier.tierId || 0), tier_code: tierCode, tier_name: tierName, threshold_usd_minor: thresholdUsdMinor, resource_group_id: resourceGroupId, status: tier.status === "inactive" ? "inactive" : "active", sort_order: index, }; }); if (form.enabled && tiers.filter((tier) => tier.status === "active").length === 0) { throw new Error("开启后至少需要一个启用档位"); } return { enabled: Boolean(form.enabled), tiers, }; }