import { Check } from "lucide-react" import { type ReactNode, useEffect, useState } from "react" import { fetchAgreementStatus, fetchRealNameStatus } from "@/api/agreement" import { getUserInfo } from "@/api/token" import AgreementDialog from "@/components/composites/dialogs/agreementDialog" import { EditInfoDialog, type EditInfoValues, } from "@/components/composites/dialogs/editInfoDialog" import RealNameDialog from "@/components/composites/dialogs/realNameDialog" import Page from "@/components/page" import { QrCodeImage } from "@/components/qrCodeImage" import { Button } from "@/components/ui/button" import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { cn } from "@/lib/utils" import b3 from "../assets/b3.webp" import b5 from "../assets/b5.webp" import b6 from "../assets/b6.webp" import b7 from "../assets/b7.webp" import b8 from "../assets/b8.webp" import b9 from "../assets/b9.webp" import b10 from "../assets/b10.webp" import b11 from "../assets/b11.webp" import b12 from "../assets/b12.webp" import banner from "../assets/banner.webp" import banner2 from "../assets/banner2.webp" import { MOCK_ACCOUNT_INFO, MOCK_BALANCE, MOCK_CONSUMPTION, MOCK_IP_STATS, } from "./mock" const fmt = (n: number) => n.toFixed(2) const MANAGER_QR_URLS: Record = { 1029: "https://work.weixin.qq.com/u/vc887a78c8a042ee8e?v=4.1.8.133653", 1030: "https://work.weixin.qq.com/u/vc83c509032e079ac3?v=4.1.8.23932", 1017: "https://work.weixin.qq.com/u/vc7e4f48bc9e52e3d0?v=4.1.8.133653", } function readUserInfo() { const raw = getUserInfo>() const info = (raw ?? {}) as Record const phone = String( info.Phone ?? info.LoginCode ?? info.phone ?? info.logincode ?? info.Mobile ?? info.mobile ?? "", ) const managerId = Number(info.ManagerId ?? info.managerId ?? 0) return { phone, managerQrUrl: Number.isFinite(managerId) && MANAGER_QR_URLS[managerId] ? MANAGER_QR_URLS[managerId] : "", } } export default function DashboardPage() { // ========== 数据定义(待接口就绪后改为 useEffect 拉取) ========== const balanceData = MOCK_BALANCE const accountInfo = MOCK_ACCOUNT_INFO const consumptionData = MOCK_CONSUMPTION const ipAccountData = MOCK_IP_STATS const { phone, managerQrUrl } = readUserInfo() // 实名认证状态(php-api /agent/index/isverify)、网络安全协议签署状态 // (php-api /tencent/index/get_is_upload) const [verified, setVerified] = useState(null) const [agreementSigned, setAgreementSigned] = useState(null) const refreshVerifyState = () => { if (!phone) return void fetchRealNameStatus(phone).then(res => { if (res.success) setVerified(res.data) }) } const refreshAgreementState = () => { void fetchAgreementStatus().then(res => { if (res.success) setAgreementSigned(res.data) }) } useEffect(() => { if (phone) { void fetchRealNameStatus(phone).then(res => { if (res.success) setVerified(res.data) }) } void fetchAgreementStatus().then(res => { if (res.success) setAgreementSigned(res.data) }) }, [phone]) const [editDialogOpen, setEditDialogOpen] = useState(false) const [realNameOpen, setRealNameOpen] = useState(false) const [agreementOpen, setAgreementOpen] = useState(false) const [managerQrOpen, setManagerQrOpen] = useState(false) const handleSaveInfo = (data: EditInfoValues) => { // TODO: 接入 src/api/user.ts updateUserProfile void data } // 未返回状态(请求中/失败/无手机号)时默认按「未实名/未签署」展示, // 接口成功后自动更新为真实状态 const verifyBadge = (() => { if (verified === true) { return ( 已认证 ) } return ( ) })() const agreementAction = (mobile = false) => { const className = mobile ? "mt-3 inline-flex items-center gap-1 self-start text-xs sm:hidden" : "hidden items-center gap-1 text-xs sm:inline-flex" if (agreementSigned === true) { return ( 签署网络安全协议 ) } return ( ) } return (

账户信息

{verifyBadge}
{agreementAction()}

扫二维码联系
我的客户经理

{managerQrUrl && (
)}

手机号/用户名

{phone || accountInfo.phone}

密码

********
{agreementAction(true)}

消费信息

本年消费

{fmt(consumptionData.year)}

本年消费

IP账号

我的客户经理

请扫码添加

) } function InfoRow({ label, value }: { label: string; value: string }) { return (
{label}
{value || "--"}
) } function BalanceCard(props: { label: string amount: string image: string imageAlt: string gradientClassName?: string children?: ReactNode }) { return (

{props.label}

{props.imageAlt}

{props.amount}

{props.children}
) } function StatTile(props: { icon: string alt: string label: string value: string }) { return (
{props.alt}

{props.label}

{props.value}

) } function IpStat(props: { icon: string alt: string value: number label: string chipClassName?: string }) { return (
{props.alt}

{props.value}

{props.label}

) }