155 lines
9.4 KiB
Markdown
155 lines
9.4 KiB
Markdown
---
|
||
name: soul-admin-dev
|
||
description: 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()`。
|
||
|
||
```typescript
|
||
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 接口。
|