import { resolveErrorMessage as resolveUserErrorMessage } from "../lib/resolveErrorMessage"; import { useEffect, useState } from "react"; import { Link } from "react-router-dom"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { toast } from "sonner"; import { createPaymentAccount, disablePaymentAccount, fetchBankInstitutions, fetchPaymentAccounts, replacePaymentAccount, revealPaymentAccount, type PaymentAccount, } from "../api/paymentAccounts"; import { fetchLegalEntities } from "../api/masterData"; import { useAuth } from "../auth/AuthContext"; import { hasAnyPermission, hasPermission } from "../auth/permissions"; import { PageHeader } from "../components/common/PageHeader"; import { resolveSingleCompanyState } from "../features/company/singleCompany"; import { PageScaffold } from "../components/patterns/PageScaffold"; import { SectionPanel } from "../components/patterns/SectionPanel"; import { Button } from "../components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "../components/ui/dialog"; import { Input } from "../components/ui/input"; import { Label } from "../components/ui/label"; import { Textarea } from "../components/ui/textarea"; function errorText(error: unknown) { return resolveUserErrorMessage(error, "操作失败"); } export function PaymentAccountsPage() { const queryClient = useQueryClient(); const { permissions } = useAuth(); const canManage = hasPermission(permissions, "payment.account.manage"); const canReveal = hasPermission(permissions, "payment.account.read_full"); const canManageCompanyInformation = hasAnyPermission(permissions, ["masterdata.view", "masterdata.manage"]); const [editing, setEditing] = useState(null); const [legalEntityId, setLegalEntityId] = useState(""); const [bankInstitutionId, setBankInstitutionId] = useState(""); const [accountName, setAccountName] = useState(""); const [accountNumber, setAccountNumber] = useState(""); const [revealTarget, setRevealTarget] = useState(null); const [revealReason, setRevealReason] = useState(""); const [revealedAccount, setRevealedAccount] = useState(""); const [disableTarget, setDisableTarget] = useState(null); const accountsQuery = useQuery({ queryKey: ["payment-accounts"], queryFn: fetchPaymentAccounts }); const banksQuery = useQuery({ queryKey: ["bank-institutions"], queryFn: fetchBankInstitutions }); const legalEntitiesQuery = useQuery({ queryKey: ["master-data", "legal-entities", "payment-accounts"], queryFn: () => fetchLegalEntities({ enabled: true }), enabled: canManage, }); const activeCompanies = legalEntitiesQuery.data?.items ?? []; const companyState = resolveSingleCompanyState(activeCompanies); const singleCompany = companyState.kind === "single" ? companyState.company : null; useEffect(() => { if (!editing && singleCompany) { setLegalEntityId(singleCompany.id); } }, [editing, singleCompany]); const resetForm = () => { setEditing(null); setLegalEntityId(singleCompany?.id ?? ""); setBankInstitutionId(""); setAccountName(""); setAccountNumber(""); }; const refresh = () => queryClient.invalidateQueries({ queryKey: ["payment-accounts"] }); const saveMutation = useMutation({ mutationFn: () => { const payload = { legalEntityId, bankInstitutionId, accountName, accountNumber }; return editing ? replacePaymentAccount(editing.id, payload) : createPaymentAccount(payload); }, onSuccess: async () => { toast.success(editing ? "企业银行账户已替换,历史账户已保留" : "企业银行账户已新增"); resetForm(); await refresh(); }, onError: (error) => toast.error(errorText(error)), }); const disableMutation = useMutation({ mutationFn: disablePaymentAccount, onSuccess: async () => { setDisableTarget(null); toast.success("企业银行账户已停用"); await refresh(); }, onError: (error) => toast.error(errorText(error)), }); const revealMutation = useMutation({ mutationFn: () => revealPaymentAccount(revealTarget!.id, revealReason.trim()), onSuccess: ({ accountNumber: value }) => { setRevealedAccount(value); window.setTimeout(() => revealMutation.reset(), 0); }, onError: (error) => toast.error(errorText(error)), }); const accounts = accountsQuery.data?.items ?? []; return (
{canManage && legalEntitiesQuery.isLoading ? (
正在读取公司信息...
) : null} {canManage && legalEntitiesQuery.isError ? (
公司信息读取失败,请刷新后重试。
) : null} {canManage && !legalEntitiesQuery.isLoading && !legalEntitiesQuery.isError && companyState.kind === "empty" ? (

企业银行账户必须关联当前公司。请先完善公司信息,再回来录入付款账户。

{canManageCompanyInformation ? ( ) : (

请联系管理员先完善公司信息。

)}
) : null} {canManage && companyState.kind === "multiple" ? (

检测到多条启用的公司信息,系统不会猜测付款账户应关联哪一条。请先处理公司信息。

{canManageCompanyInformation ? ( ) : null}
) : null} {canManage && singleCompany ? (
{editing?.legalEntity.name ?? singleCompany.name}
setAccountName(event.target.value)} autoComplete="off" />
setAccountNumber(event.target.value)} autoComplete="new-password" />
{editing ? : null}
) : null}
{accounts.map((account) => (
{account.legalEntity.name} · {account.accountName}
{account.bankInstitution.name} · {account.accountNumberMasked ?? "-"}
{account.enabled ? "当前启用" : "历史/已停用"}
{canReveal ? : null} {canManage && account.enabled ? : null} {canManage && account.enabled ? : null}
))} {!accountsQuery.isLoading && !accounts.length ?
尚未配置企业银行账户。
: null}
{ if (!open) { setRevealTarget(null); setRevealReason(""); setRevealedAccount(""); } }}> 查看完整企业银行账号本次查看会记录查看人、目标账户、时间和原因。 {revealedAccount ?
{revealedAccount}
: