# AGENTS.md - haha-mp 智能体代码生成规则 > 本文件为 AI Agent 代码生成提供强制规则约束,定义生成边界与规范。 > 所有规则均为强制性,Agent 生成代码时必须严格遵守。违反规则的代码不可提交。 --- ## 1. 项目边界 ### 1.1 技术栈版本锁定 | 技术 | 版本 | 禁止事项 | |------|------|----------| | uni-app | 3.0.0-5000720260410001 | 禁止使用 uni-app v2 | | Vue | 3.5.32 | Composition API only,禁止 Options API | | TypeScript | ^4.9.4 | 注意:uni-app 限制,不可升级到 TS 5 | | Vite | 5.2.8 | 禁止升级到 Vite 6+(uni-app 兼容性) | | Pinia | ^3.0.4 | 禁止 Vuex | | Sass | ^1.99.0 | 样式预处理统一使用 SCSS | | 微信小程序 appid | `wxef6ffc2591d04b1b` | 禁止修改 | ### 1.2 目标平台 - **主要平台**:微信小程序(`mp-weixin`) - 构建命令:`pnpm dev:mp-weixin`(开发)、`pnpm build:mp-weixin`(构建) - 代码需兼容小程序运行时限制(无 DOM、无 window、无 axios) ### 1.3 后端 API 对接 | 配置项 | 值 | |--------|-----| | 后端服务地址 | `https://dev-haha.kuaiyuman.cn/api`(开发环境) | | 后端应用 | `haha-miniapp`(端口 7077,context-path: /api) | | 请求方式 | `uni.request`(封装在 `src/utils/request.ts`) | | 认证方式 | 请求头 `accessToken: {token}` | | 请求超时 | 30000ms | ### 1.4 目录职责(严格遵循) ``` src/ ├── api/ # API 请求函数(每个模块一个文件) ├── components/ # 公共组件 ├── pages/ # 小程序页面(每个页面一个目录,含 .vue 文件) ├── static/ # 静态资源(图标、图片、动画样式) │ ├── icons/ # SVG 图标 │ └── images/ # 图片资源 ├── styles/ # 全局样式 ├── utils/ # 工具函数 │ ├── request.ts # HTTP 请求封装 │ ├── auth.ts # 认证工具 │ └── config.ts # API 配置 ├── App.vue # 应用入口(onLaunch/onShow/onHide) ├── main.ts # 创建应用(createSSRApp + Pinia) ├── manifest.json # 小程序配置 ├── pages.json # 页面路由与导航栏配置 └── uni.scss # 全局 SCSS 变量(Design Tokens) ``` --- ## 2. 代码生成规则 ### 2.1 页面 (pages/) **强制结构**:每个页面是一个独立目录,包含同名的 `.vue` 文件 ``` pages/{pageName}/ └── {pageName}.vue # 页面组件 ``` **页面 Vue 文件模板**: ```vue ``` **页面注册**:新增页面必须在 `pages.json` 中注册 ```json { "path": "pages/xxx/xxx", "style": { "navigationBarTitleText": "页面标题", "navigationBarBackgroundColor": "#FFD700", "navigationBarTextStyle": "black" } } ``` **强制规则**: - 导航栏背景色统一 `#FFD700`(品牌黄) - 导航栏文字颜色统一 `black` - 使用 `` 代替 `
`,`` 代替 `` - 使用 `` 代替 ``,必须指定 `mode` 属性 - 使用 `uni.xxx` API 代替浏览器原生 API - 使用 `rpx` 单位代替 `px`(1rpx = 屏幕宽度/750) - 使用 `@dcloudio/uni-app` 生命周期钩子(`onLoad`、`onShow`、`onHide`) - 禁止使用 DOM API(`document`、`window`、`localStorage`) - 使用 `uni.getStorageSync/setStorageSync` 代替 `localStorage` - 路由跳转使用 `uni.navigateTo`/`uni.reLaunch`/`uni.switchTab` ### 2.2 API 层 (api/) **强制规则**: 1. 每个 API 文件对应一个后端模块 2. 统一使用 `src/utils/request.ts` 中的 `request`/`get`/`post`/`put`/`del` 3. 必须定义 TypeScript 接口,导出供页面使用 **API 文件模板**: ```ts /** * xxx相关API */ import { get, post } from '../utils/request'; /** * 数据接口定义 */ export interface XxxInfo { id: string; // 雪花ID,必须为 string 类型 name: string; status: number; createTime: string; } /** * 请求参数接口 */ export interface XxxListRequest { page?: number; pageSize?: number; status?: number; } /** * 获取xxx列表 * @param params 查询参数 */ export const getXxxList = (params?: XxxListRequest): Promise => { return post('/xxx/list', params || {}); }; /** * 获取xxx详情 * @param id xxx ID */ export const getXxxDetail = (id: string): Promise => { return get(`/xxx/${id}`); }; ``` **禁止事项**: - 禁止直接使用 `uni.request`(必须通过 `request.ts` 封装) - 禁止在 API 函数中处理 UI 逻辑(如 `uni.showToast`) - 禁止使用 `axios`(小程序不支持) - 禁止硬编码后端地址(使用 `API_CONFIG.baseUrl`) ### 2.3 请求封装 (utils/request.ts) **已有封装,禁止重写**。关键行为: - 请求拦截:自动添加 `accessToken` 请求头 - 响应拦截:`code === 200 || code === 0` 为成功,返回 `data` 字段 - 401 处理:清除 token + 1.5s 后跳转登录页 - 错误处理:自动 `uni.showToast` 提示 - 支持 `skipAuth` 参数跳过认证(仅用于免登录接口) **免登录接口示例**: ```ts export const getDeviceProducts = (deviceId: string): Promise => { return get(`/device/products/${deviceId}`, undefined, { skipAuth: true }); }; ``` ### 2.4 认证工具 (utils/auth.ts) **已有封装,禁止重写**。关键行为: | 函数 | 用途 | |------|------| | `getToken()` | 获取 accessToken | | `setToken(token)` | 存储 accessToken | | `removeToken()` | 清除 accessToken | | `isLoggedIn()` | 判断是否已登录 | | `checkAuth(redirectUrl?)` | 路由守卫,未登录跳转登录页 | | `clearAuth()` | 清除所有登录信息 + 购物流程数据 | | `logout()` | 清除登录信息 + reLaunch 到登录页 | **Token 存储 key**:`accessToken`(uni.getStorageSync) --- ## 3. 样式规则 ### 3.1 Design Token 变量 **必须使用 `uni.scss` 中定义的 Design Token**,禁止硬编码: ```scss /* 主色系 */ $color-primary: #FFC107; // 品牌黄 $color-primary-light: #FFE082; $color-primary-dark: #FFA000; /* 文字颜色 */ $color-text-primary: #2C2C2C; // 主文字 $color-text-secondary: #8C8C8C; // 辅助文字 $color-text-tertiary: #BDBDBD; // 三级文字 /* 背景色 */ $color-bg-primary: #FFFFFF; $color-bg-secondary: #FAFAFA; $color-bg-tertiary: #F5F5F5; /* 边框/阴影 */ $color-border: #EEEEEE; $shadow-primary: 0 8rpx 24rpx rgba(255, 193, 7, 0.25); /* 间距系统 */ $spacing-xs: 8rpx; $spacing-sm: 16rpx; $spacing-md: 24rpx; $spacing-lg: 32rpx; $spacing-xl: 48rpx; $spacing-xxl: 64rpx; /* 圆角 */ $radius-sm: 8rpx; $radius-md: 16rpx; $radius-lg: 24rpx; $radius-xl: 32rpx; /* 动画 */ $duration-fast: 150ms; $duration-normal: 300ms; $ease-out: cubic-bezier(0.25, 0.1, 0.25, 1); $bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55); ``` ### 3.2 样式编写规范 | 规则 | 说明 | |------|------| | 单位 | 统一使用 `rpx`(设计稿 750rpx 宽度),禁止 `px`/`rem`/`em` | | 颜色 | 使用 Design Token 变量,禁止硬编码颜色值 | | 间距 | 使用 `$spacing-xxx` 变量 | | 圆角 | 使用 `$radius-xxx` 变量 | | 阴影 | 使用 `$shadow-xxx` 变量 | | 动画 | 使用 `$duration-xxx` + `$ease-out` | | 作用域 | 全局样式不加 scoped,页面级样式尽量加 `scoped` | | 性能 | 动画元素添加 `will-change: transform, opacity` + `transform: translateZ(0)` | ### 3.3 禁止事项 - 禁止使用 `px` 作为布局单位(仅 `rpx`) - 禁止硬编码颜色值(必须使用变量) - 禁止使用 CSS `filter` 属性(小程序性能差) - 禁止使用 `backdrop-filter`(兼容性问题) - 禁止使用 `position: fixed` 在列表项中(性能问题) - 禁止复杂 `box-shadow` 动画 --- ## 4. 路由与导航规则 ### 4.1 路由方式 | 场景 | API | 说明 | |------|-----|------| | 普通跳转 | `uni.navigateTo` | 可返回,最多 10 层栈 | | 不可返回跳转 | `uni.reLaunch` | 关闭所有页面,打开目标页 | | Tab 切换 | `uni.switchTab` | 用于 tabBar 页面(当前无 tabBar) | | 返回上一页 | `uni.navigateBack` | -- | | 重定向 | `uni.redirectTo` | 关闭当前页,打开目标页 | ### 4.2 路由传参 ```ts // 传递参数 uni.navigateTo({ url: '/pages/xxx/xxx?id=' + String(id) + '&name=' + name }); // 接收参数 onLoad((options: any) => { const id = options.id; // 字符串 }); ``` **强制规则**: - 雪花 ID 传参必须 `String(id)` 防止精度丢失 - 登录页支持 `redirect` 参数:`/pages/login/login?redirect=/pages/index/index` ### 4.3 页面白名单 以下页面允许未登录用户直接访问(定义在 `App.vue`): ```ts const LOGIN_WHITE_LIST = [ 'pages/login/login', 'pages/products/products', // 柜内商品展示 ]; ``` 新增免登录页面时,必须同步更新此白名单。 --- ## 5. 业务规则约束 ### 5.1 扫码开门流程 ``` 用户扫码 → 检查登录 → 检查支付分 → 调用 scanDoor API → 存储 deviceId/outTradeNo/orderNo → 跳转购物页 ``` **强制规则**: - 扫码前必须检查登录状态 - 扫码前必须检查微信支付分开通状态 - 二维码格式:`https://hh.hahabianli.com/B142977?_wxpmm0=...` - 设备 ID 提取:正则 `/\/([A-Z0-9]+)(\?|$)/` ### 5.2 订单金额显示 - **实付金额字段**:`paidAmount || totalAmount`(优先使用 paidAmount) - 格式化:`(amount || 0).toFixed(2)` - 前缀:`¥` ### 5.3 退款时效 - 仅已完成订单(`status === 1`)可申请退款 - 退款期限:支付时间后 7 天内 - 超过 7 天自动隐藏退款按钮 ### 5.4 登录认证 - **唯一登录方式**:微信手机号快速登录(`open-type="getPhoneNumber"`) - API:`/login/miniapp-phone`,参数 `{ code, phoneCode }` - 登录成功后存储 token + userInfo - 支持登录后跳转回原页面(redirect 参数) --- ## 6. 小程序特有约束 ### 6.1 兼容性规则 | 编号 | 约束 | 说明 | |------|------|------| | C1 | 禁止 DOM API | 无 `document`/`window`/`localStorage` | | C2 | 禁止 axios | 小程序不支持 XHR,必须用 `uni.request` | | C3 | 图片必须指定 mode | `` | | C4 | 禁止 v-html | 小程序不支持 | | C5 | 禁止动态组件 | `` 有限制 | | C6 | 使用 rpx 单位 | 适配不同屏幕宽度 | | C7 | 事件使用 @tap | 优先使用 `@tap` 代替 `@click` | | C8 | 按钮反馈 | 操作按钮添加 `hover-class` | | C9 | 安全区适配 | 底部 `padding-bottom: env(safe-area-inset-bottom)` | | C10 | 包体积 | 单个包不超过 2MB,主包不超过 2MB | ### 6.2 性能优化规则 | 编号 | 规则 | 说明 | |------|------|------| | P1 | 动画使用 `transform` + `opacity` | 避免触发 layout/paint | | P2 | 动画元素添加 `will-change` | `will-change: transform, opacity` | | P3 | 动画元素添加 `transform: translateZ(0)` | 开启 GPU 加速 | | P4 | 禁止 `filter: blur()` | 小程序性能极差 | | P5 | 禁止复杂 `box-shadow` 动画 | 改用静态阴影 | | P6 | 长列表使用虚拟列表 | 超过 100 项必须虚拟滚动 | | P7 | 图片懒加载 | `` | | P8 | 轮询必须有超时和清理 | 避免页面切换后持续请求 | ### 6.3 小程序 API 使用规范 | 需求 | 使用 | 禁止 | |------|------|------| | 存储 | `uni.getStorageSync/setStorageSync` | `localStorage` | | 路由 | `uni.navigateTo/reLaunch` | `router.push` | | 提示 | `uni.showToast/showLoading/showModal` | 自定义 toast | | 扫码 | `uni.scanCode` | 第三方扫码 | | 拨号 | `uni.makePhoneCall` | `tel:` 链接 | | 震动 | `uni.vibrateShort` | -- | | 登录 | `uni.login` | -- | --- ## 7. 常见陷阱 | 编号 | 陷阱 | 规则 | |------|------|------| | T1 | 雪花 ID 使用 number 类型 | 禁止。必须为 `string` 类型,防止 JS 精度丢失 | | T2 | 路由传参直接传 number ID | 禁止。必须 `String(id)` | | T3 | 使用 `localStorage` | 禁止。必须 `uni.getStorageSync/setStorageSync` | | T4 | 使用 `axios` | 禁止。小程序不支持,使用封装的 `request.ts` | | T5 | 使用 `document/window` | 禁止。小程序无 DOM | | T6 | 使用 `px` 单位 | 禁止。统一使用 `rpx` | | T7 | 硬编码颜色值 | 禁止。使用 `uni.scss` 中的 Design Token | | T8 | 新页面不注册 pages.json | 禁止。每个新页面必须在 pages.json 中配置 | | T9 | 免登录页面不更新白名单 | 禁止。同步更新 App.vue 中 LOGIN_WHITE_LIST | | T10 | 轮询不设置超时 | 禁止。所有轮询必须有 timeout + 页面卸载清理 | | T11 | 在 API 层处理 UI 逻辑 | 禁止。API 层只负责请求 | | T12 | 使用 `
//` | 禁止。使用 `//` | | T13 | 导航栏颜色不一致 | 禁止。统一 `#FFD700` 背景 + `black` 文字 | | T14 | 实付金额取 totalAmount | 禁止。优先取 `paidAmount`,fallback `totalAmount` | | T15 | 不处理安全区 | 禁止。底部内容必须适配 `safe-area-inset-bottom` |