9.4 KiB
name, description
| name | description |
|---|---|
| soul-admin-dev | Soul 创业派对管理端开发规范。在 soul-admin/ 下编辑时必遵循。React、Vite、client.ts、/api/admin/*、/api/db/*、Radix UI、鉴权。Use when editing soul-admin, 管理端, React 管理后台. |
Soul 创业派对 - 管理端开发 Skill
当你在 soul-admin/ 目录下新增、优化或编辑代码时,必须遵循本 Skill。管理端仅对接 soul-api 的管理端与 DB 接口,禁止调用小程序专属路径,防止与 miniprogram、soul-api 路由互窜。
1. 项目定位与边界
- soul-admin:React + TypeScript + Vite 管理后台,使用 React Router、Tailwind CSS、Radix UI 系组件(见
src/components/ui/)。 - 唯一后端:所有接口请求 soul-api(Go),通过
VITE_API_BASE_URL或默认 baseUrl 配置。 - 禁止:不得调用
/api/miniprogram/*(小程序专属);管理端只使用/api/admin/*、/api/db/*、/api/orders等 soul-api 中挂载在 admin/db 下的路由。
2. API 调用规范(防互窜)
- 路径:仅使用管理端与数据类路径,例如:
- 登录/登出:
POST /api/admin、POST /api/admin/logout、GET /api/admin(校验) - 业务数据:
GET /api/admin/withdrawals、GET /api/orders、GET /api/db/users、GET/POST/PUT/DELETE /api/admin/chapters、/api/admin/content、/api/db/config/full等
- 登录/登出:
- 禁止:不得使用
/api/miniprogram/login、/api/miniprogram/book/...、/api/miniprogram/withdraw/...等小程序端路径。 - 发起方式:统一通过
src/api/client.ts的get、post、put、del、request;自动带Authorization: Bearer <admin_token>(见src/api/auth.ts)。 - 示例:
- 正确:
get('/api/admin/withdrawals')、put('/api/admin/withdrawals', { id, action: 'approve' })、get('/api/db/users') - 错误:
get('/api/miniprogram/xxx')、在管理端实现「用小程序登录接口拿 token」
- 正确:
3. 代码风格与结构
- 技术栈:React 18、TypeScript、Vite、React Router v6、Tailwind CSS、Radix UI、lucide-react、zustand(若用状态)。
- 目录:
src/api/:请求封装(client.ts)、鉴权(auth.ts);可在此扩展管理端专用 API 方法。src/pages/:按功能分页(如 DashboardPage、WithdrawalsPage、UsersPage、ChaptersPage);页面内用 useState/useEffect 或 zustand 拉数。src/components/ui/:通用 UI(button、card、input、dialog、table、badge 等);业务模块可放在src/components/modules/。src/layouts/:AdminLayout 等布局与侧栏路由。
- 命名:组件 PascalCase;文件与组件名一致(如
WithdrawalsPage.tsx);接口/类型用 PascalCase 或小驼峰按习惯。 - 类型:请求响应用 TypeScript 接口定义(如
interface Withdrawal { ... }),可用get<WithdrawalsRes>(...)泛型。
3.1 TypeScript 严格类型(可选→必填、API 映射)
- 可选字段赋给必填:从
T | undefined赋给T时,用?? defaultValue兜底,如t.appId ?? ''、t.pagePath ?? '' - 接口与 API 对齐:若 API 返回某字段而接口未声明,在接口中补
field?: Type(如isPinned?: boolean) - API 映射兜底:
data.map(p => ({ id: p.token ?? p.personId ?? '', label: p.label ?? '', ... })),避免undefined流入 state - setState 传参:
useState<string | null>的 setter 不接受undefined,传value ?? null而非裸value
4. 列表页标准(必守)
新增或修改列表页时,必须包含:
必做:
- 分页:后端支持时接入
page、pageSize、total,使用src/components/ui/Pagination.tsx - 搜索:使用
useDebounce对输入做 300ms 防抖(见src/hooks/useDebounce.ts) - 筛选:按业务提供下拉/按钮筛选
- 刷新:提供刷新按钮,加载时禁用并显示 loading
- 加载状态:请求中显示 loading
- 空状态:无数据时显示友好提示
- 错误提示:catch 后设置 error 状态,页面顶部展示可关闭的红底错误条
可选:导出 CSV、列头排序、批量操作。
禁止:不得用原生 alert 做任何提示(包括成功、失败、验证);不得调用 /api/miniprogram/*。
检查清单:分页、搜索防抖、刷新、loading、空状态、错误条、仅 admin/db 路径。详见 开发文档/列表标准与角色分工.md。
4.1 输入框 padding(前端通用)
口诀:外边包 div/view,内部 input width 100%。设置 input 的 padding、背景、边框时,用 div 包裹 input;padding 写在容器上,input 仅做文字样式(width: 100%)。禁止在 input 自身上设 padding,可避免光标截断、布局异常。React:<div className="form-input"><input className="form-input-inner" ... /></div>。
4.2 用户操作反馈:统一使用 Toast(禁止 alert)
规则:管理端所有操作反馈(保存成功、操作失败、表单验证提示等)必须使用 @/utils/toast,严禁使用原生 window.alert()。
import toast from '@/utils/toast'
// ✅ 正确
toast.success('已保存')
toast.success(`章节「${title}」创建成功`)
toast.error('保存失败: ' + (res?.error || '未知错误'))
toast.error('请填写章节ID和标题') // 表单验证也用 error
toast.info('暂无数据可导出') // 中性说明用 info
// ❌ 错误
alert('已保存')
alert('保存失败')
类型语义:
| 方法 | 使用场景 | 颜色 |
|---|---|---|
toast.success() |
操作成功、保存成功、创建/删除成功 | 绿色 |
toast.error() |
接口报错、表单验证不通过、操作失败 | 红色 |
toast.info() |
中性提示(无数据、当前状态说明) | 蓝色 |
注意:
confirm()仍可用于删除等破坏性操作的二次确认- toast 自动 3 秒消失,不阻断流程;若需用户强制确认才能继续,使用
confirm() - 新增页面/组件时,不得引入新的
alert()
来源:2026-03-10 全系统 alert → toast 改造(18 文件约 90 处)
4.4 表单弹窗与「可选择+可手动填写」(吸收 SetVipModal 经验)
当表单需支持「从预设选项选择」或「手动填写自定义值」时:
- 下拉:
<select>从GET /api/db/xxx拉取预设列表,选项包含「其他(手动填写)」; - 自定义输入:当选中「其他」时展示
<Input>,最终提交时取「选中项」或「自定义输入」; - 独立弹窗:功能入口在列表行操作按钮(如「设置 VIP」),点击打开独立
XxxModal,不塞进详情页,保持详情页纯粹; - 路由与菜单:新增管理页(如 VIP 角色)时,在
App.tsx加 Route,在AdminLayout的menuItems加菜单项。
5. 业务逻辑约定(与 soul-api 对齐)
- 鉴权:登录后 token 存 localStorage(
admin_token);请求头由 client 自动带 Bearer token;401 时跳转登录页并清除 token。 - 提现:列表/统计用
GET /api/admin/withdrawals;审核/拒绝用PUT /api/admin/withdrawals(如 action: approve/reject);状态与 soul-api 一致(如 pending、processing、success、failed),前端展示可映射为「已完成/已拒绝」等文案。 - 用户/订单:用户列表
GET /api/db/users;订单GET /api/admin/orders;字段名与 soul-api 返回一致(如 userNickname、userAvatar、status、amount)。 - 内容/章节:
/api/admin/chapters、/api/admin/content等 CRUD;配置类用/api/admin/settings、/api/admin/referral-settings、/api/db/config/full。 - 列表与表格:管理端列表需有 user_name/userNickname、userAvatar、status、amount 等字段以便通用展示;若 soul-api 返回字段不同,仅在管理端做字段映射,不修改 soul-api 的 miniprogram 接口。
6. 与 soul-api 的对接要点
- 响应格式:成功多为
{ success: true, data?: ..., withdrawals?: ..., ... };失败{ success: false, error?: string }或 HTTP 4xx/5xx;client 在!res.ok时 throw,页面 catch 后展示错误。 - 新增需求:新功能应在 soul-api 的 admin 或 db 组下新增接口,管理端只调
/api/admin/...或/api/db/...,不得新增对/api/miniprogram/...的依赖。
7. 小程序变更驱动的管理端补充(必守)
小程序有功能变更时,管理端须根据 C 端能力主动补充管理功能。
- 触发:小程序新增/优化任何可配置、可运营的功能(如价格、推荐位、文案、审核流等)
- 动作:管理端开发工程师分析该功能在后台需要哪些配置、审核、统计,并输出管理端需求
- 后端配合:需为每个可配置项设计对应的 admin/db 接口(如每个导师独立价格配置)
- 示例:导师价格 → 后端 mentors 表支持按导师配置价格;管理端导师编辑页增加价格字段
8. 何时使用本 Skill
- 在 soul-admin/ 下新增或修改页面、组件、API 调用时。
- 在管理端新增任何网络请求时(必须仅使用 admin/db 等管理端路径)。
- 做提现、用户、订单、内容、配置等后台功能时。
遵循本 Skill 可保证管理端只与 soul-api 的管理端路由对接,避免与小程序接口混用或误用 next-project 接口。