feat: 统一三端账号管理页面

- 新增共享账号管理组件 src/components/account/AccountPage.jsx
- 管理台新增账号管理入口(修复 SidebarUser onClick)
- 开发台使用共享组件替换占位符页面
- 扩展 api.user 支持 updateProfile 和 changePassword
- 新增 account-management 规格文件
- 更新 page-navigation 规格文件
This commit is contained in:
2026-03-26 19:33:58 +08:00
parent bc4537b3bc
commit ce9ebe5784
10 changed files with 147 additions and 36 deletions

View File

@@ -1,7 +1,9 @@
import { useState } from 'react';
import Toast from '../../components/common/Toast.jsx';
import { useUserContext } from '../../contexts/UserContext.jsx';
import Toast from '../common/Toast.jsx';
function AccountPage() {
const { user } = useUserContext();
const [profileToast, setProfileToast] = useState(null);
const [passwordErrors, setPasswordErrors] = useState({});
const [passwordForm, setPasswordForm] = useState({
@@ -43,7 +45,6 @@ function AccountPage() {
<div className="card-title">账号信息</div>
</div>
<div className="card-body">
{/* 头像区域 */}
<div style={{ textAlign: 'center', marginBottom: '24px', paddingBottom: '24px', borderBottom: '1px solid var(--color-border-2)' }}>
<div style={{
width: '100px',
@@ -56,10 +57,9 @@ function AccountPage() {
color: '#fff',
fontSize: '36px',
margin: '0 auto 12px'
}}></div>
}}>{user.avatar}</div>
<button className="btn btn-sm">更换头像</button>
</div>
{/* 表单区域 */}
<div className="form-row">
<div className="form-col">
<div className="form-group">
@@ -70,7 +70,7 @@ function AccountPage() {
<div className="form-col">
<div className="form-group">
<label className="form-label">姓名</label>
<input type="text" className="form-control" defaultValue="张三" />
<input type="text" className="form-control" defaultValue={user.name} />
</div>
</div>
</div>
@@ -90,7 +90,7 @@ function AccountPage() {
</div>
<div className="form-group">
<label className="form-label">所属部门</label>
<input type="text" className="form-control" defaultValue="AI 产品部" readOnly style={{ background: '#F8FAFC' }} />
<input type="text" className="form-control" defaultValue={user.role} readOnly style={{ background: '#F8FAFC' }} />
</div>
<button className="btn btn-primary" onClick={handleProfileSave}>保存修改</button>
</div>
@@ -152,4 +152,4 @@ function AccountPage() {
);
}
export default AccountPage;
export default AccountPage;

View File

@@ -0,0 +1,2 @@
export { default as AccountPage } from './AccountPage.jsx';
export { default } from './AccountPage.jsx';

View File

@@ -34,6 +34,7 @@ export const ADMIN_PAGES = {
addUser: { title: '新增用户', icon: null },
addProject: { title: '新增项目', icon: null },
addModelConfig: { title: '新增配置', icon: null },
account: { title: '账号管理', icon: 'FiUser' },
};
/**
@@ -45,7 +46,7 @@ export const DEVELOPER_PAGES = {
uploadSkill: { title: '创建技能', icon: 'FiPlus' },
newVersion: { title: '上传新版本', icon: null },
devDocs: { title: '开发文档', icon: 'FiTerminal' },
devAccount: { title: '开发者设置', icon: 'FiSettings' },
devAccount: { title: '账号管理', icon: 'FiSettings' },
skillEditor: { title: '技能详情', icon: null },
};

View File

@@ -20,6 +20,7 @@ import ConsoleReviewListPage from './console/ConsoleReviewListPage.jsx';
import ConsoleReviewDetailPage from './console/ConsoleReviewDetailPage.jsx';
import ModelConfigsPage from './admin/ModelConfigsPage.jsx';
import AddModelConfigPage from './admin/AddModelConfigPage.jsx';
import AccountPage from '../components/account/AccountPage.jsx';
function AdminPage() {
const location = useLocation();
@@ -106,6 +107,8 @@ function AdminPage() {
onBack={() => navigateTo('modelConfigs')}
editData={editData}
/>;
case 'account':
return <AccountPage />;
default:
return <div>Page not found</div>;
}
@@ -194,7 +197,7 @@ function AdminPage() {
/>
</nav>
<SidebarUser
onClick={() => {}}
onClick={() => navigateTo('account')}
wrapperClassName="admin-sidebar-user"
infoClassName="admin-sidebar-user-info"
nameClassName="admin-sidebar-user-name"

View File

@@ -18,7 +18,7 @@ import SkillConfigPage from './console/SkillConfigPage.jsx';
import LogsPage from './console/LogsPage.jsx';
import TasksPage from './console/TasksPage.jsx';
import TaskDetailPage from './console/TaskDetailPage.jsx';
import AccountPage from './console/AccountPage.jsx';
import AccountPage from '../components/account/AccountPage.jsx';
import ProjectsPage from './console/ProjectsPage.jsx';
import MemberConfigPage from './console/MemberConfigPage.jsx';
import AddMemberPage from './console/AddMemberPage.jsx';

View File

@@ -15,7 +15,7 @@ import MySkillsPage from './developer/MySkillsPage.jsx';
import UploadSkillPage from './developer/UploadSkillPage.jsx';
import NewVersionPage from './developer/NewVersionPage.jsx';
import DevDocsPage from './developer/DevDocsPage.jsx';
import DevAccountPage from './developer/DevAccountPage.jsx';
import AccountPage from '../components/account/AccountPage.jsx';
import SkillEditorPage from './developer/SkillEditorPage.jsx';
import UpdateSkillInfoPage from './developer/UpdateSkillInfoPage.jsx';
import UploadVersionPage from './developer/UploadVersionPage.jsx';
@@ -104,7 +104,7 @@ function DeveloperPage() {
case 'devDocs':
return <DevDocsPage />;
case 'devAccount':
return <DevAccountPage />;
return <AccountPage />;
case 'skillEditor':
return <SkillEditorPage
skillId={currentSkillId}

View File

@@ -1,24 +0,0 @@
function DevAccountPage() {
return (
<div className="card">
<div className="card-header">
<div className="card-title">开发者设置</div>
</div>
<div className="card-body">
<div style={{ display: 'flex', gap: '20px', alignItems: 'flex-start' }}>
<div className="user-avatar" style={{ width: '72px', height: '72px', fontSize: '32px' }}></div>
<div>
<h2 style={{ marginBottom: '8px' }}>张三</h2>
<div style={{ color: '#64748B', marginBottom: '12px' }}>开发者</div>
<div style={{ display: 'flex', gap: '8px' }}>
<button className="btn btn-primary">编辑资料</button>
<button className="btn">API 密钥管理</button>
</div>
</div>
</div>
</div>
</div>
);
}
export default DevAccountPage;

View File

@@ -25,6 +25,27 @@ export const user = {
avatar: '张',
role: 'AI 产品部',
}),
/**
* 更新用户资料
* @param {Object} profile - 用户资料
* @returns {Object} 更新后的用户信息
*/
updateProfile: (profile) => {
console.log('updateProfile:', profile);
return { success: true };
},
/**
* 修改密码
* @param {string} currentPassword - 当前密码
* @param {string} newPassword - 新密码
* @returns {Object} 修改结果
*/
changePassword: (currentPassword, newPassword) => {
console.log('changePassword:', { currentPassword, newPassword });
return { success: true };
},
};
/**