Files
ckb-SuperAdmin/nkebao/src/pages/mine/index.tsx
笔记本里的永平 6479bea3ce feat: 本次提交更新内容如下
用户信息修改完成
2025-07-23 19:10:43 +08:00

296 lines
7.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { Card, NavBar, List, Button, Dialog, Toast } from "antd-mobile";
import {
LogoutOutlined,
PhoneOutlined,
MessageOutlined,
DatabaseOutlined,
FolderOpenOutlined,
BellOutlined,
SettingOutlined,
} from "@ant-design/icons";
import MeauMobile from "@/components/MeauMobile/MeauMoible";
import Layout from "@/components/Layout/Layout";
import style from "./index.module.scss";
import { useUserStore } from "@/store/module/user";
import { getDashboard } from "./api";
const Mine: React.FC = () => {
const navigate = useNavigate();
const { user } = useUserStore();
const [stats, setStats] = useState({
devices: 12,
wechat: 25,
traffic: 8,
content: 156,
balance: 0,
});
const [showLogoutDialog, setShowLogoutDialog] = useState(false);
// 用户信息
const currentUserInfo = {
name: user?.username || "-",
email: user?.account || "-",
role: user?.isAdmin === 1 ? "管理员" : "普通用户",
lastLogin: user?.lastLoginTime
? new Date(user.lastLoginTime * 1000).toLocaleString()
: "-",
avatar: user?.avatar || "",
};
// 功能模块数据
const functionModules = [
{
id: "devices",
title: "设备管理",
description: "管理您的设备和微信账号",
icon: <PhoneOutlined />,
count: stats.devices,
path: "/devices",
bgColor: "#e6f7ff",
iconColor: "#1890ff",
},
{
id: "wechat",
title: "微信号管理",
description: "管理微信账号和好友",
icon: <MessageOutlined />,
count: stats.wechat,
path: "/wechat-accounts",
bgColor: "#f6ffed",
iconColor: "#52c41a",
},
{
id: "traffic",
title: "流量池",
description: "管理用户流量池和分组",
icon: <DatabaseOutlined />,
count: stats.traffic,
path: "/traffic-pool",
bgColor: "#f9f0ff",
iconColor: "#722ed1",
},
{
id: "content",
title: "内容库",
description: "管理营销内容和素材",
icon: <FolderOpenOutlined />,
count: stats.content,
path: "/content",
bgColor: "#fff7e6",
iconColor: "#fa8c16",
},
];
// 加载统计数据
const loadStats = async () => {
try {
const res = await getDashboard();
setStats({
devices: res.deviceNum,
wechat: res.wechatNum,
traffic: 999,
content: 999,
balance: res.balance || 0,
});
} catch (error) {
console.error("加载统计数据失败:", error);
}
};
useEffect(() => {
loadStats();
}, []);
const handleLogout = () => {
// 清除本地存储的用户信息
localStorage.removeItem("token");
localStorage.removeItem("token_expired");
localStorage.removeItem("s2_accountId");
localStorage.removeItem("userInfo");
setShowLogoutDialog(false);
navigate("/login");
Toast.show({
content: "退出成功",
position: "top",
});
};
const handleFunctionClick = (path: string) => {
navigate(path);
};
// 渲染用户头像
const renderUserAvatar = () => {
if (currentUserInfo.avatar) {
return <img src={currentUserInfo.avatar} alt="头像" />;
}
return (
<div
style={{
width: "100%",
height: "100%",
backgroundColor: "#1890ff",
display: "flex",
alignItems: "center",
justifyContent: "center",
color: "white",
fontSize: "24px",
fontWeight: "bold",
}}
>
</div>
);
};
// 渲染功能模块图标
const renderModuleIcon = (module: any) => (
<div
style={{
width: "40px",
height: "40px",
backgroundColor: module.bgColor,
borderRadius: "8px",
display: "flex",
alignItems: "center",
justifyContent: "center",
color: module.iconColor,
fontSize: "20px",
}}
>
{module.icon}
</div>
);
return (
<Layout
header={
<NavBar back={null} style={{ background: "#fff" }}>
<div style={{ color: "var(--primary-color)", fontWeight: 600 }}>
</div>
</NavBar>
}
footer={<MeauMobile activeKey="mine" />}
>
<div className={style["mine-page"]}>
{/* 用户信息卡片(严格按图片风格) */}
<Card className={style["user-card"]}>
<div className={style["user-info-row"]}>
{/* 头像 */}
<div className={style["user-avatar"]}>
{currentUserInfo.avatar ? (
<img src={currentUserInfo.avatar} />
) : (
<div className={style["avatar-placeholder"]}></div>
)}
</div>
{/* 右侧内容 */}
<div className={style["user-main-info"]}>
<div className={style["user-main-row"]}>
<span className={style["user-name"]}>
{currentUserInfo.name}
</span>
<span className={style["role-badge"]}>
{currentUserInfo.role}
</span>
<span className={style["icon-btn"]}>
<i className="iconfont icon-bell" />
</span>
</div>
<div>
<span className={style["balance-label"]}></span>
<span className={style["balance-value"]}>
{Number(stats.balance || 0).toFixed(2)}
</span>
<Button
size="small"
color="primary"
onClick={() => navigate("/recharge")}
>
</Button>
</div>
<div className={style["last-login"]}>
{currentUserInfo.lastLogin}
</div>
<SettingOutlined
className={style["icon-setting"]}
onClick={() => navigate("/settings")}
/>
</div>
</div>
</Card>
{/* 我的功能 */}
<Card className={style["menu-card"]}>
<List>
{functionModules.map((module) => (
<List.Item
key={module.id}
prefix={renderModuleIcon(module)}
title={module.title}
description={module.description}
extra={
<span
style={{
padding: "2px 8px",
backgroundColor: "#f0f0f0",
borderRadius: "12px",
fontSize: "12px",
color: "#666",
}}
>
{module.count}
</span>
}
arrow
onClick={() => handleFunctionClick(module.path)}
/>
))}
</List>
</Card>
{/* 退出登录按钮 */}
<Button
block
color="danger"
fill="outline"
className={style["logout-btn"]}
onClick={() => setShowLogoutDialog(true)}
>
<LogoutOutlined style={{ marginRight: "8px" }} />
退
</Button>
</div>
{/* 退出登录确认对话框 */}
<Dialog
content="您确定要退出登录吗?退出后需要重新登录才能使用完整功能。"
visible={showLogoutDialog}
closeOnAction
actions={[
[
{
key: "cancel",
text: "取消",
},
{
key: "confirm",
text: "确认退出",
bold: true,
danger: true,
onClick: handleLogout,
},
],
]}
onClose={() => setShowLogoutDialog(false)}
/>
</Layout>
);
};
export default Mine;