chore: 添加 .gitignore 规则,包含前端、pnpm、Node.js 和 AI 工具

This commit is contained in:
2026-03-20 09:14:58 +08:00
parent bf294f9f50
commit 176a727f6e
50 changed files with 6436 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
import { useState } from 'react';
import ListSelector from '../../components/ListSelector.jsx';
const availableLeaders = [
{ id: 1, name: '张三', department: 'AI 产品部', phone: '138****8888', email: 'zhangsan@example.com' },
{ id: 2, name: '李四', department: '技术研发部', phone: '139****1234', email: 'lisi@example.com' },
{ id: 3, name: '王五', department: '数据分析部', phone: '136****5678', email: 'wangwu@example.com' },
{ id: 4, name: '赵六', department: 'AI 产品部', phone: '135****9012', email: 'zhaoliu@example.com' },
{ id: 5, name: '钱七', department: '运营部', phone: '137****3456', email: 'qianqi@example.com' }
];
function AddDepartmentPage({ onBack }) {
const [selectedLeader, setSelectedLeader] = useState(null);
const leaderColumns = [
{ key: 'name', label: '姓名' },
{ key: 'phone', label: '联系电话' },
{ key: 'email', label: '邮箱' }
];
const selectedLabel = selectedLeader
? `${availableLeaders.find(l => l.id === selectedLeader)?.name} - ${availableLeaders.find(l => l.id === selectedLeader)?.department}`
: null;
return (
<div className="card">
<div className="card-header">
<div className="card-title">新增部门</div>
</div>
<div className="card-body">
<div className="form-group">
<label className="form-label required">部门名称</label>
<input type="text" className="form-control" placeholder="请输入部门名称" />
</div>
<div className="form-group">
<label className="form-label">部门描述</label>
<textarea className="form-control" rows="3" placeholder="请输入部门描述"></textarea>
</div>
<div className="form-group">
<label className="form-label required">负责人</label>
<ListSelector
data={availableLeaders}
selectedIds={selectedLeader}
onChange={setSelectedLeader}
searchPlaceholder="搜索负责人..."
columns={leaderColumns}
multiSelect={false}
selectedLabel={selectedLabel}
onClearSelected={() => setSelectedLeader(null)}
/>
</div>
<div style={{ display: 'flex', gap: '12px', justifyContent: 'flex-end', marginTop: '24px' }}>
<button className="btn" onClick={onBack}>取消</button>
<button className="btn btn-primary">确定</button>
</div>
</div>
</div>
);
}
export default AddDepartmentPage;

View File

@@ -0,0 +1,61 @@
import { useState } from 'react';
import ListSelector from '../../components/ListSelector.jsx';
const availableLeaders = [
{ id: 1, name: '张三', department: 'AI 产品部', phone: '138****8888', email: 'zhangsan@example.com' },
{ id: 2, name: '李四', department: '技术研发部', phone: '139****1234', email: 'lisi@example.com' },
{ id: 3, name: '王五', department: '数据分析部', phone: '136****5678', email: 'wangwu@example.com' },
{ id: 4, name: '赵六', department: 'AI 产品部', phone: '135****9012', email: 'zhaoliu@example.com' },
{ id: 5, name: '钱七', department: '运营部', phone: '137****3456', email: 'qianqi@example.com' }
];
function AddProjectPage({ onBack }) {
const [selectedLeader, setSelectedLeader] = useState(null);
const leaderColumns = [
{ key: 'name', label: '姓名' },
{ key: 'department', label: '部门' },
{ key: 'phone', label: '联系电话' }
];
const selectedLabel = selectedLeader
? `${availableLeaders.find(l => l.id === selectedLeader)?.name} - ${availableLeaders.find(l => l.id === selectedLeader)?.department}`
: null;
return (
<div className="card">
<div className="card-header">
<div className="card-title">新增项目</div>
</div>
<div className="card-body">
<div className="form-group">
<label className="form-label required">项目名称</label>
<input type="text" className="form-control" placeholder="请输入项目名称" />
</div>
<div className="form-group">
<label className="form-label">项目描述</label>
<textarea className="form-control" rows="3" placeholder="请输入项目描述"></textarea>
</div>
<div className="form-group">
<label className="form-label required">负责人</label>
<ListSelector
data={availableLeaders}
selectedIds={selectedLeader}
onChange={setSelectedLeader}
searchPlaceholder="搜索负责人..."
columns={leaderColumns}
multiSelect={false}
selectedLabel={selectedLabel}
onClearSelected={() => setSelectedLeader(null)}
/>
</div>
<div style={{ display: 'flex', gap: '12px', justifyContent: 'flex-end', marginTop: '24px' }}>
<button className="btn" onClick={onBack}>取消</button>
<button className="btn btn-primary">确定</button>
</div>
</div>
</div>
);
}
export default AddProjectPage;

View File

@@ -0,0 +1,74 @@
import { useState } from 'react';
import ListSelector from '../../components/ListSelector.jsx';
const availableDepartments = [
{ id: 1, name: 'AI 产品部', description: '负责AI产品规划与设计', head: '张三', memberCount: 8 },
{ id: 2, name: '技术研发部', description: '负责核心技术研发与实现', head: '李四', memberCount: 15 },
{ id: 3, name: '数据分析部', description: '负责数据分析与挖掘', head: '王五', memberCount: 10 },
{ id: 4, name: '运营部', description: '负责产品运营与推广', head: '钱七', memberCount: 6 },
{ id: 5, name: '测试部', description: '负责产品质量保障', head: '周九', memberCount: 5 },
{ id: 6, name: '客户服务部', description: '负责客户支持与服务', head: '吴十', memberCount: 12 }
];
function AddUserPage({ onBack }) {
const [selectedDepartment, setSelectedDepartment] = useState(null);
const departmentColumns = [
{ key: 'name', label: '部门名称' },
{ key: 'description', label: '部门描述' },
{ key: 'head', label: '负责人' }
];
const selectedLabel = selectedDepartment
? availableDepartments.find(d => d.id === selectedDepartment)?.name
: null;
return (
<div className="card">
<div className="card-header">
<div className="card-title">新增用户</div>
</div>
<div className="card-body">
<div className="form-group">
<label className="form-label required">姓名</label>
<input type="text" className="form-control" placeholder="请输入用户姓名" />
</div>
<div className="form-group">
<label className="form-label required">部门</label>
<ListSelector
data={availableDepartments}
selectedIds={selectedDepartment}
onChange={setSelectedDepartment}
searchPlaceholder="搜索部门..."
columns={departmentColumns}
multiSelect={false}
selectedLabel={selectedLabel}
onClearSelected={() => setSelectedDepartment(null)}
/>
</div>
<div className="form-group">
<label className="form-label required">角色</label>
<select className="form-control">
<option>成员</option>
<option>管理员</option>
<option>开发者</option>
</select>
</div>
<div className="form-group">
<label className="form-label required">邮箱</label>
<input type="email" className="form-control" placeholder="请输入邮箱" />
</div>
<div className="form-group">
<label className="form-label">手机号</label>
<input type="tel" className="form-control" placeholder="请输入手机号" />
</div>
<div style={{ display: 'flex', gap: '12px', justifyContent: 'flex-end', marginTop: '24px' }}>
<button className="btn" onClick={onBack}>取消</button>
<button className="btn btn-primary">确定</button>
</div>
</div>
</div>
);
}
export default AddUserPage;

View File

@@ -0,0 +1,93 @@
const adminProjects = [
{ id: 1, name: '企业 AI 智算平台', description: '企业级AI智能助手平台', owner: '张三', members: 8, status: '正常', createTime: '2026-01-15', lastActive: '2026-03-19 10:30' },
{ id: 2, name: '知识库管理系统', description: '智能知识库检索与管理', owner: '李四', members: 5, status: '正常', createTime: '2026-02-10', lastActive: '2026-03-18 16:20' },
{ id: 3, name: '数据分析平台', description: '大数据分析与可视化平台', owner: '王五', members: 12, status: '正常', createTime: '2026-01-20', lastActive: '2026-03-19 09:45' },
{ id: 4, name: '智能客服系统', description: 'AI驱动的客户服务系统', owner: '赵六', members: 6, status: '禁用', createTime: '2026-02-28', lastActive: '2026-03-10 14:15' },
{ id: 5, name: '文档自动化平台', description: '智能文档生成与处理', owner: '钱七', members: 4, status: '正常', createTime: '2026-03-01', lastActive: '2026-03-19 11:20' },
{ id: 6, name: '代码审查助手', description: '自动化代码审查与优化建议', owner: '孙八', members: 7, status: '正常', createTime: '2026-02-15', lastActive: '2026-03-17 15:30' }
];
function StatusTag({ status }) {
const statusClass = status === '正常' ? 'status-running' : status === '禁用' ? 'status-error' : '';
return <span className={`status ${statusClass}`}>{status}</span>;
}
function AdminProjectsPage({ onAdd }) {
return (
<>
<div className="card">
<div className="card-body">
<div className="search-bar">
<div className="search-item" style={{ flex: 1, minWidth: '200px' }}>
<label>关键词</label>
<input type="text" className="form-control" placeholder="搜索项目名称、描述..." />
</div>
<div className="search-item">
<label>状态</label>
<select className="form-control">
<option>全部</option>
<option>正常</option>
<option>禁用</option>
</select>
</div>
</div>
<div className="search-actions">
<button className="btn btn-primary">查询</button>
<button className="btn">重置</button>
</div>
</div>
</div>
<div className="card">
<div className="card-header" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<div className="card-title">项目列表</div>
<button className="btn btn-primary btn-sm" onClick={onAdd}>新增项目</button>
</div>
<div className="card-body">
<div className="table-wrapper">
<table className="table">
<thead>
<tr>
<th>项目名称</th>
<th>项目描述</th>
<th>负责人</th>
<th>成员数</th>
<th>状态</th>
<th>创建时间</th>
<th style={{ width: '200px' }}>操作</th>
</tr>
</thead>
<tbody>
{adminProjects.map(project => (
<tr key={project.id}>
<td><strong>{project.name}</strong></td>
<td>{project.description}</td>
<td>{project.owner}</td>
<td>{project.members} </td>
<td><StatusTag status={project.status} /></td>
<td>{project.createTime}</td>
<td style={{ width: '200px' }}>
<div style={{ display: 'flex', gap: '8px' }}>
<button className={`text-btn ${project.status === '正常' ? 'text-btn-danger' : 'text-btn-primary'}`}>{project.status === '正常' ? '禁用' : '启用'}</button>
<button className="text-btn text-btn-primary">编辑</button>
<button className="text-btn text-btn-danger">删除</button>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="pagination">
<div className="pagination-item"></div>
<div className="pagination-item active">1</div>
<div className="pagination-item">2</div>
<div className="pagination-item">3</div>
<div className="pagination-item"></div>
</div>
</div>
</div>
</>
);
}
export default AdminProjectsPage;

View File

@@ -0,0 +1,93 @@
const departments = [
{ id: 1, name: 'AI 产品部', description: '负责AI产品规划与设计', head: '张三', members: 8, status: '正常', createTime: '2025-06-01' },
{ id: 2, name: '技术研发部', description: '负责核心技术研发与实现', head: '李四', members: 15, status: '正常', createTime: '2025-06-01' },
{ id: 3, name: '数据分析部', description: '负责数据分析与挖掘', head: '王五', members: 10, status: '正常', createTime: '2025-06-01' },
{ id: 4, name: '运营部', description: '负责产品运营与推广', head: '钱七', members: 6, status: '正常', createTime: '2025-08-15' },
{ id: 5, name: '测试部', description: '负责产品质量保障', head: '周九', members: 5, status: '正常', createTime: '2025-07-01' },
{ id: 6, name: '客户服务部', description: '负责客户支持与服务', head: '吴十', members: 12, status: '禁用', createTime: '2025-09-10' }
];
function StatusTag({ status }) {
const statusClass = status === '正常' ? 'status-running' : status === '禁用' ? 'status-error' : '';
return <span className={`status ${statusClass}`}>{status}</span>;
}
function DepartmentsPage({ onAdd }) {
return (
<>
<div className="card">
<div className="card-body">
<div className="search-bar">
<div className="search-item" style={{ flex: 1, minWidth: '200px' }}>
<label>关键词</label>
<input type="text" className="form-control" placeholder="搜索部门名称、描述..." />
</div>
<div className="search-item">
<label>状态</label>
<select className="form-control">
<option>全部</option>
<option>正常</option>
<option>禁用</option>
</select>
</div>
</div>
<div className="search-actions">
<button className="btn btn-primary">查询</button>
<button className="btn">重置</button>
</div>
</div>
</div>
<div className="card">
<div className="card-header" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<div className="card-title">部门列表</div>
<button className="btn btn-primary btn-sm" onClick={onAdd}>新增部门</button>
</div>
<div className="card-body">
<div className="table-wrapper">
<table className="table">
<thead>
<tr>
<th>部门名称</th>
<th>部门描述</th>
<th>负责人</th>
<th>成员数</th>
<th>状态</th>
<th>创建时间</th>
<th style={{ width: '200px' }}>操作</th>
</tr>
</thead>
<tbody>
{departments.map(dept => (
<tr key={dept.id}>
<td><strong>{dept.name}</strong></td>
<td>{dept.description}</td>
<td>{dept.head}</td>
<td>{dept.members} </td>
<td><StatusTag status={dept.status} /></td>
<td>{dept.createTime}</td>
<td style={{ width: '200px' }}>
<div style={{ display: 'flex', gap: '8px' }}>
<button className={`text-btn ${dept.status === '正常' ? 'text-btn-danger' : 'text-btn-primary'}`}>{dept.status === '正常' ? '禁用' : '启用'}</button>
<button className="text-btn text-btn-primary">编辑</button>
<button className="text-btn text-btn-danger">删除</button>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="pagination">
<div className="pagination-item"></div>
<div className="pagination-item active">1</div>
<div className="pagination-item">2</div>
<div className="pagination-item">3</div>
<div className="pagination-item"></div>
</div>
</div>
</div>
</>
);
}
export default DepartmentsPage;

View File

@@ -0,0 +1,18 @@
function OverviewPage() {
return (
<div className="card">
<div className="card-header">
<div className="card-title">运营总览</div>
</div>
<div className="card-body">
<div style={{ textAlign: 'center', padding: '60px 20px', color: 'var(--color-text-3)' }}>
<div style={{ fontSize: '48px', marginBottom: '16px' }}></div>
<div style={{ fontSize: '18px', fontWeight: 600, marginBottom: '8px' }}>运营总览页面</div>
<div>此处展示平台运营数据概览</div>
</div>
</div>
</div>
);
}
export default OverviewPage;

View File

@@ -0,0 +1,113 @@
const adminUsers = [
{ id: 1, name: '张三', department: 'AI 产品部', role: '管理员', email: 'zhangsan@example.com', phone: '138****8888', status: '正常', lastLogin: '2026-03-19 10:30' },
{ id: 2, name: '李四', department: '技术研发部', role: '开发者', email: 'lisi@example.com', phone: '139****1234', status: '正常', lastLogin: '2026-03-19 09:15' },
{ id: 3, name: '王五', department: '数据分析部', role: '成员', email: 'wangwu@example.com', phone: '136****5678', status: '禁用', lastLogin: '2026-03-15 18:20' },
{ id: 4, name: '赵六', department: 'AI 产品部', role: '管理员', email: 'zhaoliu@example.com', phone: '135****9012', status: '正常', lastLogin: '2026-03-19 11:45' },
{ id: 5, name: '钱七', department: '技术研发部', role: '开发者', email: 'qianqi@example.com', phone: '137****3456', status: '正常', lastLogin: '2026-03-18 16:30' },
{ id: 6, name: '孙八', department: '技术研发部', role: '成员', email: 'sunba@example.com', phone: '133****7890', status: '正常', lastLogin: '2026-03-19 08:00' },
{ id: 7, name: '周九', department: '测试部', role: '成员', email: 'zhoujiu@example.com', phone: '158****2345', status: '正常', lastLogin: '2026-03-17 14:20' },
{ id: 8, name: '吴十', department: '技术研发部', role: '开发者', email: 'wushi@example.com', phone: '159****6789', status: '正常', lastLogin: '2026-03-19 12:10' }
];
function StatusTag({ status }) {
const statusClass = status === '正常' ? 'status-running' : status === '禁用' ? 'status-error' : '';
return <span className={`status ${statusClass}`}>{status}</span>;
}
function RoleTag({ role }) {
const roleClass = role === '管理员' ? 'role-admin' : role === '开发者' ? 'role-developer' : 'role-member';
return <span className={`status ${roleClass}`}>{role}</span>;
}
function UsersPage({ onAdd }) {
return (
<>
<div className="card">
<div className="card-body">
<div className="search-bar">
<div className="search-item" style={{ flex: 1, minWidth: '200px' }}>
<label>关键词</label>
<input type="text" className="form-control" placeholder="搜索用户姓名、邮箱..." />
</div>
<div className="search-item">
<label>部门</label>
<select className="form-control">
<option>全部部门</option>
<option>AI 产品部</option>
<option>技术研发部</option>
<option>数据分析部</option>
<option>运营部</option>
<option>测试部</option>
</select>
</div>
<div className="search-item">
<label>状态</label>
<select className="form-control">
<option>全部</option>
<option>正常</option>
<option>禁用</option>
</select>
</div>
</div>
<div className="search-actions">
<button className="btn btn-primary">查询</button>
<button className="btn">重置</button>
</div>
</div>
</div>
<div className="card">
<div className="card-header" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<div className="card-title">用户列表</div>
<button className="btn btn-primary btn-sm" onClick={onAdd}>新增用户</button>
</div>
<div className="card-body">
<div className="table-wrapper">
<table className="table">
<thead>
<tr>
<th>姓名</th>
<th>部门</th>
<th>角色</th>
<th>邮箱</th>
<th>手机号</th>
<th>状态</th>
<th>最后登录</th>
<th style={{ width: '200px' }}>操作</th>
</tr>
</thead>
<tbody>
{adminUsers.map(user => (
<tr key={user.id}>
<td><strong>{user.name}</strong></td>
<td>{user.department}</td>
<td><RoleTag role={user.role} /></td>
<td>{user.email}</td>
<td>{user.phone}</td>
<td><StatusTag status={user.status} /></td>
<td>{user.lastLogin}</td>
<td style={{ width: '200px' }}>
<div style={{ display: 'flex', gap: '8px' }}>
<button className={`text-btn ${user.status === '正常' ? 'text-btn-danger' : 'text-btn-primary'}`}>{user.status === '正常' ? '禁用' : '启用'}</button>
<button className="text-btn text-btn-primary">编辑</button>
<button className="text-btn text-btn-danger">删除</button>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="pagination">
<div className="pagination-item"></div>
<div className="pagination-item active">1</div>
<div className="pagination-item">2</div>
<div className="pagination-item">3</div>
<div className="pagination-item"></div>
</div>
</div>
</div>
</>
);
}
export default UsersPage;