AGENTS.md 14 KB

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 文件模板

<template>
  <view class="container">
    <!-- 页面内容 -->
  </view>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { onShow, onLoad } from '@dcloudio/uni-app';
import { xxxApi } from '@/api/xxx';

// 响应式数据
const dataList = ref<XxxType[]>([]);
const loading = ref(false);

// 页面加载
onLoad((options: any) => {
  // 处理页面参数
});

// 页面显示(每次从后台切回都触发)
onShow(() => {
  // 刷新数据
});

// 方法
const loadData = async () => {
  if (loading.value) return;
  loading.value = true;
  try {
    uni.showLoading({ title: '加载中...', mask: true });
    const result = await xxxApi();
    dataList.value = result;
  } catch (error: any) {
    console.error('加载失败:', error);
    // 错误已在 request.ts 中统一 toast 提示
  } finally {
    uni.hideLoading();
    loading.value = false;
  }
};
</script>

<style lang="scss">
/* 使用 Design Token 变量,禁止硬编码颜色/间距 */
.container {
  min-height: 100vh;
  background: $color-bg-secondary;
  padding: $spacing-lg;
  box-sizing: border-box;
}
</style>

页面注册:新增页面必须在 pages.json 中注册

{
  "path": "pages/xxx/xxx",
  "style": {
    "navigationBarTitleText": "页面标题",
    "navigationBarBackgroundColor": "#FFD700",
    "navigationBarTextStyle": "black"
  }
}

强制规则

  • 导航栏背景色统一 #FFD700(品牌黄)
  • 导航栏文字颜色统一 black
  • 使用 <view> 代替 <div><text> 代替 <span>
  • 使用 <image> 代替 <img>,必须指定 mode 属性
  • 使用 uni.xxx API 代替浏览器原生 API
  • 使用 rpx 单位代替 px(1rpx = 屏幕宽度/750)
  • 使用 @dcloudio/uni-app 生命周期钩子(onLoadonShowonHide
  • 禁止使用 DOM API(documentwindowlocalStorage
  • 使用 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 文件模板

/**
 * 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<XxxInfo[]> => {
  return post<XxxInfo[]>('/xxx/list', params || {});
};

/**
 * 获取xxx详情
 * @param id xxx ID
 */
export const getXxxDetail = (id: string): Promise<XxxInfo> => {
  return get<XxxInfo>(`/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 参数跳过认证(仅用于免登录接口)

免登录接口示例

export const getDeviceProducts = (deviceId: string): Promise<DeviceProductsResponse> => {
  return get<DeviceProductsResponse>(`/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 存储 keyaccessToken(uni.getStorageSync)


3. 样式规则

3.1 Design Token 变量

必须使用 uni.scss 中定义的 Design Token,禁止硬编码:

/* 主色系 */
$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 路由传参

// 传递参数
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):

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 <image mode="aspectFit/aspectFill">
C4 禁止 v-html 小程序不支持
C5 禁止动态组件 <component :is> 有限制
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 图片懒加载 <image lazy-load>
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 使用 <div>/<span>/<img> 禁止。使用 <view>/<text>/<image>
T13 导航栏颜色不一致 禁止。统一 #FFD700 背景 + black 文字
T14 实付金额取 totalAmount 禁止。优先取 paidAmount,fallback totalAmount
T15 不处理安全区 禁止。底部内容必须适配 safe-area-inset-bottom