Files
soul-yongping/.cursor/skills/admin-dev/SKILL.md
2026-03-14 14:37:17 +08:00

155 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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/`:通用 UIbutton、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 包裹 inputpadding 写在容器上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 token401 时跳转登录页并清除 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/5xxclient 在 `!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 接口。