import { useState, useEffect } from 'react'; import { Tabs, Card, Form, Input, Button, message, Radio, Upload, Avatar, List, Tag, Space, Typography } from 'antd'; import { UserOutlined, LockOutlined, SnippetsOutlined, UploadOutlined, LaptopOutlined, EnvironmentOutlined, CheckCircleOutlined, CloseCircleOutlined } from '@ant-design/icons'; import { useTranslation } from "react-i18next"; import useMobile from '@/hooks/useMobile.ts'; import useAuthStore from "@/stores/user"; import { type InfoParams, updateInfo, type PasswordParams, updatePassword, loginRecord } from "@/api/system/sys_user"; import type ISysLoginRecord from "@/domain/iSysLoginRecord.ts"; import type { UploadProps, FormProps } from 'antd'; import dayjs from 'dayjs'; const { Text } = Typography; /** 基本信息 Tab */ const InfoTab = () => { const userInfo = useAuthStore(state => state.userinfo); const getInfo = useAuthStore(state => state.info); const [form] = Form.useForm(); const [loading, setLoading] = useState(false); const { t } = useTranslation(); const uploadChange: UploadProps['onChange'] = async (info) => { if (info.file.status === 'done') { message.success(t("user.profile.baseInfo.avatarSuccess")); await getInfo(); } } const onFinish: FormProps['onFinish'] = async (values: InfoParams) => { try { setLoading(true); await updateInfo(values); await getInfo(); message.success(t("user.profile.baseInfo.success")); } finally { setLoading(false); } } return (

{t("user.profile.baseInfo.updateAvatarDesc")}

form={form} layout="vertical" onFinish={onFinish} initialValues={{ bio: userInfo?.bio, email: userInfo?.email, mobile: userInfo?.mobile, nickname: userInfo?.nickname, sex: userInfo?.sex, username: userInfo?.username, }} >
); }; /** 修改密码 Tab */ const SecurityTab = () => { const [form] = Form.useForm(); const [loading, setLoading] = useState(false); const { t } = useTranslation(); const onFinish: FormProps['onFinish'] = async (values: PasswordParams) => { try { setLoading(true); await updatePassword(values); form.resetFields(); message.success(t("user.profile.changePassword.success")); } finally { setLoading(false); } } return ( form={form} layout="vertical" onFinish={onFinish} className="w-full px-6 py-4"> ({ validator(_, value) { if (!value || getFieldValue('newPassword') === value) { return Promise.resolve(); } return Promise.reject(new Error(t("user.profile.changePassword.rePassword.message"))); }, }), ]} > ); }; /** 登录日志 Tab */ const LoginLogTab = () => { const [logs, setLogs] = useState([]); const { t } = useTranslation(); useEffect(() => { loginRecord().then(res => setLogs(res.data.data || [])); }, []); const BrowserIcon = ({ browser }: { browser?: string }) => { const icons: Record = { Chrome: '🚀', Firefox: '🦊', Safari: '🍎', Edge: '🌊' }; const icon = Object.keys(icons).find(key => browser?.includes(key)); return {icon ? icons[icon] : '💻'}; }; return ( ( } style={{ backgroundColor: log.status === '0' ? '#87d068' : '#f56a00', marginRight: 16 }} />
{log.username} {log.status === '0' ? }>{t("user.profile.loginLog.success")} : }>{t("user.profile.loginLog.error")} } {dayjs(log.login_time).format('YYYY-MM-DD HH:mm:ss')}
{log.ipaddr}
{log.login_location}
{log.browser}
OS: {log.os}
)} /> ); }; /** 用户设置主页面 */ const UserSettingPage = () => { const [activeTab, setActiveTab] = useState('info'); const { t } = useTranslation(); const isMobile = useMobile(); const tabsList = [ { label: ( {isMobile ? null : t("user.profile.baseInfo")} ), key: 'info', children: , }, { label: ( {isMobile ? null : t("user.profile.changePassword")} ), key: 'security', children: , }, { label: ( {isMobile ? null : t("user.profile.loginLog")} ), key: 'loginlog', children: , }, ]; return ( ); }; export default UserSettingPage;