refactor: 重构项目接口与API调用体系,统一类型管理
1. 合并拆分的API类型定义到统一的api/interface.ts文件 2. 删除旧的api/client.ts与api/types.ts文件 3. 重构所有页面与组件的API调用方式,统一使用api/index.ts导出的接口 4. 调整组件文件结构,将分散的组件按模块整理 5. 统一类型导入路径,移除冗余的类型重复定义
This commit is contained in:
21
src/Profile/components/ProfileInfoList.tsx
Normal file
21
src/Profile/components/ProfileInfoList.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { ProfileInfoItemProps, ProfileInfoListProps } from "../interface";
|
||||
|
||||
export function ProfileInfoList({ profile }: ProfileInfoListProps) {
|
||||
return (
|
||||
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
||||
<ProfileInfoItem label="用户名" value={profile?.username || "-"} />
|
||||
<ProfileInfoItem label="状态" value={profile?.status === "active" ? "启用" : "禁用"} />
|
||||
<ProfileInfoItem label="角色" value={profile?.isSuperAdmin ? "超级管理员" : profile?.roles.map((role) => role.name).join("、") || "-"} />
|
||||
<ProfileInfoItem label="创建时间" value={profile?.createdAt || "-"} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ProfileInfoItem({ label, value }: ProfileInfoItemProps) {
|
||||
return (
|
||||
<div className="rounded-lg border border-line bg-panel p-3.5">
|
||||
<span className="mb-2 block text-[13px] text-muted">{label}</span>
|
||||
<strong className="break-words font-medium text-ink">{value}</strong>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
14
src/Profile/components/ProfileSummary.tsx
Normal file
14
src/Profile/components/ProfileSummary.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Avatar } from "@arco-design/web-react";
|
||||
import type { ProfileSummaryProps } from "../interface";
|
||||
|
||||
export function ProfileSummary({ profile }: ProfileSummaryProps) {
|
||||
return (
|
||||
<div className="mb-6 flex items-center gap-4">
|
||||
<Avatar size={56}>{profile?.username?.slice(0, 1).toUpperCase() || "A"}</Avatar>
|
||||
<div>
|
||||
<h2 className="mb-1.5 mt-0 text-[22px]">{profile?.nickname || profile?.username || "管理员"}</h2>
|
||||
<p className="m-0 text-muted">{profile?.email || "未设置邮箱"}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Avatar, Button, Card, Form, Input, Message } from '@arco-design/web-react';
|
||||
import { Button, Card, Form, Input, Message } from '@arco-design/web-react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import type { AdminProfile } from '../api/types';
|
||||
import { changePassword as changePasswordApi, getProfile, updateProfile as updateProfileApi } from '../api/auth';
|
||||
import { TOKEN_KEY } from '../api/client';
|
||||
import { authApi } from '../api';
|
||||
import { ProfileInfoList } from './components/ProfileInfoList';
|
||||
import { ProfileSummary } from './components/ProfileSummary';
|
||||
import type { AdminProfile, ChangePasswordFormValues, ProfileFormValues } from './interface';
|
||||
|
||||
function ProfilePage() {
|
||||
const navigate = useNavigate();
|
||||
@@ -17,7 +18,7 @@ function ProfilePage() {
|
||||
const loadProfile = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const data = await getProfile();
|
||||
const data = await authApi.getProfile();
|
||||
setProfile(data);
|
||||
form.setFieldsValue({
|
||||
nickname: data.nickname,
|
||||
@@ -32,10 +33,10 @@ function ProfilePage() {
|
||||
void loadProfile();
|
||||
}, []);
|
||||
|
||||
const updateProfile = async (values: { nickname?: string; email?: string }) => {
|
||||
const updateProfile = async (values: ProfileFormValues) => {
|
||||
setSaving(true);
|
||||
try {
|
||||
const data = await updateProfileApi(values);
|
||||
const data = await authApi.updateProfile(values);
|
||||
setProfile(data);
|
||||
Message.success('个人信息已更新');
|
||||
} finally {
|
||||
@@ -43,20 +44,20 @@ function ProfilePage() {
|
||||
}
|
||||
};
|
||||
|
||||
const changePassword = async (values: { oldPassword: string; newPassword: string; confirmPassword: string }) => {
|
||||
const changePassword = async (values: ChangePasswordFormValues) => {
|
||||
if (values.newPassword !== values.confirmPassword) {
|
||||
Message.error('两次输入的新密码不一致');
|
||||
return;
|
||||
}
|
||||
setChangingPassword(true);
|
||||
try {
|
||||
await changePasswordApi({
|
||||
await authApi.changePassword({
|
||||
oldPassword: values.oldPassword,
|
||||
newPassword: values.newPassword,
|
||||
});
|
||||
Message.success('密码修改成功,请重新登录');
|
||||
passwordForm.resetFields();
|
||||
localStorage.removeItem(TOKEN_KEY);
|
||||
authApi.clearAuthToken();
|
||||
navigate('/login', { replace: true });
|
||||
} finally {
|
||||
setChangingPassword(false);
|
||||
@@ -66,19 +67,8 @@ function ProfilePage() {
|
||||
return (
|
||||
<div className="grid items-start gap-4 min-[901px]:grid-cols-[minmax(0,1fr)_420px]">
|
||||
<Card className="section-card min-[901px]:row-span-2" title="个人中心" loading={loading}>
|
||||
<div className="mb-6 flex items-center gap-4">
|
||||
<Avatar size={56}>{profile?.username?.slice(0, 1).toUpperCase() || 'A'}</Avatar>
|
||||
<div>
|
||||
<h2 className="mb-1.5 mt-0 text-[22px]">{profile?.nickname || profile?.username || '管理员'}</h2>
|
||||
<p className="m-0 text-muted">{profile?.email || '未设置邮箱'}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
||||
<div className="rounded-lg border border-line bg-panel p-3.5"><span className="mb-2 block text-[13px] text-muted">用户名</span><strong className="break-words font-medium text-ink">{profile?.username || '-'}</strong></div>
|
||||
<div className="rounded-lg border border-line bg-panel p-3.5"><span className="mb-2 block text-[13px] text-muted">状态</span><strong className="break-words font-medium text-ink">{profile?.status === 'active' ? '启用' : '禁用'}</strong></div>
|
||||
<div className="rounded-lg border border-line bg-panel p-3.5"><span className="mb-2 block text-[13px] text-muted">角色</span><strong className="break-words font-medium text-ink">{profile?.isSuperAdmin ? '超级管理员' : profile?.roles.map((role) => role.name).join('、') || '-'}</strong></div>
|
||||
<div className="rounded-lg border border-line bg-panel p-3.5"><span className="mb-2 block text-[13px] text-muted">创建时间</span><strong className="break-words font-medium text-ink">{profile?.createdAt || '-'}</strong></div>
|
||||
</div>
|
||||
<ProfileSummary profile={profile} />
|
||||
<ProfileInfoList profile={profile} />
|
||||
</Card>
|
||||
<Card className="section-card" title="修改个人信息">
|
||||
<Form form={form} layout="vertical" onSubmit={updateProfile}>
|
||||
|
||||
22
src/Profile/interface.ts
Normal file
22
src/Profile/interface.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import type { AdminProfile, ChangePasswordPayload, UpdateProfilePayload } from "../api";
|
||||
|
||||
export type { AdminProfile };
|
||||
|
||||
export type ProfileFormValues = UpdateProfilePayload;
|
||||
|
||||
export type ChangePasswordFormValues = ChangePasswordPayload & {
|
||||
confirmPassword: string;
|
||||
};
|
||||
|
||||
export type ProfileSummaryProps = {
|
||||
profile: AdminProfile | null;
|
||||
};
|
||||
|
||||
export type ProfileInfoListProps = {
|
||||
profile: AdminProfile | null;
|
||||
};
|
||||
|
||||
export type ProfileInfoItemProps = {
|
||||
label: string;
|
||||
value: string;
|
||||
};
|
||||
Reference in New Issue
Block a user