2026-06-11 01:01:53 +08:00

123 lines
7.7 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.

# AGENTS.md
## 项目约束
1. 写代码不要猜。遇到不确定的依赖版本、导出名称、组件 API、项目结构、样式约定先查本地文件、`node_modules` 或实际命令输出。
2. 写前端或客户端项目时,不要添加无意义的描述文案。
3. 包管理器固定使用 `pnpm`,不要生成 npm/yarn 锁文件。
4. 基础 UI 使用 MUI但视觉风格必须保持当前白色 HYApp 管理平台风格。
5. 修改 MUI 组件颜色、尺寸、hover、focus、active 状态时,优先通过 `src/theme.js` 或项目封装组件处理,避免在页面里硬写零散覆盖。
6. 图表必须使用图表库。本项目使用 ECharts不手写业务图表。
7. 组件必须模块化。不要把页面、基础组件、图表、业务表格、抽屉混在单个文件里。
8. 页面加载必须有动画占位图,并且占位图要铺满内容区域。
9. 动画要覆盖页面切换、按钮、菜单、输入框、选择框、表格、图表、弹窗/抽屉等交互,同时保留 `prefers-reduced-motion` 降级。
10. Header 右侧放操作组件,左侧只放菜单展开/收起按钮和当前页 tab。
11. 时间筛选属于总览页面内容,不属于 Header。
12. 顶部搜索框点击后打开大搜索弹窗,输入后展示列表,列表项必须可点击。
13. 左侧菜单 active 样式优先级必须高于 hover 样式。
14. 侧边栏展开/收起按钮必须跟随状态切换图标。
15. 展开态 Logo 区域和侧边栏宽度保持 248px。
16. 所有逻辑功能配置默认打开;只有密钥、地址、三方账号等必须由环境提供的敏感值使用占位符或环境配置,不在默认配置里伪造可用凭证。
17. 所有业务逻辑、状态流转、权限判断、支付链路、异步流程都保持高密度逻辑注释,注释解释为什么这样处理和失败分支,不复述语法。
## 当前实现方式
- 框架React + Vite。
- UI 组件库MUI。
- 图表库ECharts。
- 包管理器pnpm。
- 页面:按业务放在 `src/features/*/pages/`
- 应用壳:`src/app/App.jsx``src/app/layout/AdminLayout.jsx``src/app/router/routeConfig.ts`
- 页面加载占位:`src/shared/ui/PageSkeleton.jsx`
- 公共时间选择器:`src/shared/ui/TimeRangeFilter.jsx`,使用 `{ startMs, endMs }` 毫秒值作为输入输出。
- 全局资源组选择抽屉:`src/shared/ui/ResourceGroupSelectDrawer.jsx`,业务表单资源组字段统一使用其导出的 `ResourceGroupSelectField`,不在业务页面里重复手写普通下拉或资源组 ID 输入框。
- 顶部搜索弹窗:`src/features/search/components/SearchDialog.jsx`
- MUI 主题:`src/theme.js`
- CSS token`src/styles/tokens.css`
- 样式入口:`src/styles/app.css`,实际样式按 `src/styles/*.css``src/features/*/*.css``*.module.css` 拆分。
- 服务端状态:使用 `@tanstack/react-query`,共享入口在 `src/shared/query/``src/shared/hooks/useAdminQuery.js`
- 接口契约:`contracts/admin-openapi.json` 是本仓库的前端 API 契约源;`pnpm gen:api` 只基于该契约生成 `src/shared/api/generated/schema.d.ts``src/shared/api/generated/endpoints.ts`
## 目录规范
- `src/app/`应用壳、Provider、鉴权上下文、路由守卫、统一路由配置和布局。
- `src/shared/`:跨业务共享的 API 基础层、UI 组件、hooks、工具和图表封装。
- `src/features/<module>/`:业务模块,内部放 `api.ts``routes.js``permissions.js``schema.ts``hooks/``components/``pages/`
- 新增后台业务模块必须优先落在 `src/features/`,不要重新创建横向 `pages/``api/``components/` 目录。
- 新增模块优先复制 `admin-module.example.json`,改成业务配置后运行 `pnpm gen:module <config.json>`;它会生成 feature、权限常量、路由接入和 OpenAPI 契约。
- 只需要预览生成内容时运行 `pnpm gen:module <config.json> --dry-run`
- `pnpm scaffold:feature <feature-name>` 是低层级骨架命令,只有在不需要权限/菜单/契约自动接入时使用。
- API 契约或权限变更后运行 `pnpm gen:api`
- 前端 API 路径必须从 `src/shared/api/generated/endpoints.ts` 取,不要在 feature API 中重新手写路径。
- 表单提交前必须走模块内 `schema.ts` 或共享 schema 校验。
## 按需导入规则
- MUI 组件必须路径导入,例如:
```js
import Button from "@mui/material/Button";
```
- MUI 图标必须路径导入,例如:
```js
import Refresh from "@mui/icons-material/Refresh";
```
- 不要使用总入口:
```js
import { Button } from "@mui/material";
import { Refresh } from "@mui/icons-material";
```
- ECharts 只在 `src/shared/charts/` 内封装和加载,不要在页面里直接散落图表初始化逻辑。
- 页面和抽屉继续使用 `React.lazy` 做拆分加载。
- 顶部搜索弹窗继续使用 lazy 加载,不要静态塞进主入口。
## 样式规则
- 状态色不要随意改:
- `--success`:运行中
- `--warning`:警告
- `--danger`:异常/危险操作
- `--stopped`:已停止
- 新增颜色优先写入 token 或 theme不要在多个组件里重复硬编码。
- 基础组件的视觉兼容优先改封装组件,不要让页面直接依赖 MUI 细节。
- 不添加卡片套卡片。
- 不添加无业务意义的说明区、营销区、空泛介绍区。
## 后台表格交互规则
- 表格空态只显示 `当前无数据`,创建入口放在页面工具栏,不放在空态里。
- 表格里的启用/禁用状态优先使用行内 Switch 快捷操作,不使用单独的启用/禁用图标按钮。
- 表格状态筛选使用 Select 下拉框,默认值为 `全部状态`,不使用状态 chip 组。
- 后台列表页的时间区间筛选必须使用统一的单入口时间区间筛选框(`src/shared/ui/TimeRangeFilter.jsx`);不要在工具栏里并排放两个开始/结束时间输入框,也不要使用浏览器原生日期/时间输入样式。时间区间弹层内使用快捷项、日历和时分下拉点选,不使用手写时间文本框。
- 后台表单里的生效时间、有效期、投放时间等时间区间必须使用统一公共时间选择器(`src/shared/ui/TimeRangeFilter.jsx`);不要并排放两个开始/结束时间输入框,也不要使用浏览器原生日期/时间输入样式。
- 资源组选择必须优先使用统一的 `src/shared/ui/ResourceGroupSelectDrawer.jsx` / `ResourceGroupSelectField`,点击输入框打开右侧资源组图标抽屉,点击资源组后自动回填并关闭,不要在业务页面里重复实现资源组 Select 下拉,也不要用普通文本框填写资源组 ID。
- 区域编辑弹窗必须同时包含区域基础字段和国家码字段;国家码使用可搜索多选下拉框,不再拆成独立“区域国家”弹窗。
- 头像、图片、封面等图片资源字段必须使用 `src/shared/ui/UploadField.jsx` 上传表单组件,不使用普通文本输入框承载 URL。
- 图片上传表单必须提供统一预览;`webp` 使用浏览器原生动效预览,`svga` 使用 SVGA 播放器预览,`pag` 使用 libpag + wasm 预览。
- BD Leader 创建弹窗不选择区域、不提交 `regionId`;创建结果按目标用户当前区域生成,若区域不对,先修复用户国家/区域映射,再创建 BD Leader。
- 区域创建和区域启用/禁用调用后台管理后端接口,不要求 user-service 新增对应 RPC。
- 国家创建和国家启用/禁用调用后台管理后端接口,不要求 user-service 新增对应 RPC。
## 验证要求
每次完成前端改动后至少运行:
```bash
pnpm check:contracts
pnpm typecheck
pnpm lint
pnpm test
pnpm build
```
如果需要本地预览:
```bash
pnpm dev
```