Files
pingxiangcard/CLAUDE.md
T
2026-07-29 13:54:13 +08:00

207 lines
10 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.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## 项目定位
**爱上萍乡**用户端微信小程序(C端),基于 uni-app + Vue 3 + TypeScript + Pinia。仅包含用户端功能,不含管理端。
## 技术栈
| 技术 | 版本 | 说明 |
|------|------|------|
| Vue | 3.5.x | 核心框架 |
| uni-app | 3.0.0-alpha | 跨平台框架(当前仅编译微信小程序) |
| TypeScript | 4.9.x | 类型系统 |
| Pinia | 3.x | 状态管理(仅 user store) |
| Vite | 5.2.8 | 构建工具 |
| @dcloudio/uni-ui | 1.5.x | UI 组件库(easycom 自动导入) |
| sass | 1.101.x | 样式预处理 |
## 运行命令
```bash
pnpm install # 安装依赖
pnpm run dev:mp-weixin # 微信小程序开发构建
pnpm run build:mp-weixin # 微信小程序生产构建
pnpm run type-check # TypeScript 类型检查(vue-tsc --noEmit)
```
构建产物在 `dist/build/mp-weixin/`,用微信开发者工具导入此目录。
## 目录结构
```
src/
├── api/ # API 接口层
│ ├── request.ts # HTTP 封装(uni.request + Token 注入 + 401 处理)
│ ├── types.ts # 公共类型定义
│ ├── user.ts # 微信登录(两种方式)
│ ├── card.ts # 年卡接口
│ └── order.ts # 订单接口
├── components/ # 公共组件
│ ├── mc-glass.vue # 毛玻璃卡片
│ ├── card-item.vue # 年卡列表项
│ ├── empty-state.vue # 空状态占位
│ ├── announcement-modal.vue # 公告弹窗
│ ├── confirm-modal.vue # 确认弹窗
│ ├── design-button.vue # 设计系统按钮
│ ├── design-card.vue # 设计系统卡片
│ ├── design-input.vue # 设计系统输入框
│ └── section-label.vue # 区块标题
├── config/
│ └── index.ts # API_BASE / TOKEN_KEY / 环境变量
├── mock/ # Mock 数据(VITE_USE_MOCK=true 时启用)
│ ├── index.ts # USE_MOCK 开关
│ ├── images.ts # 图片 URL
│ ├── notice.ts # 公告数据
│ ├── scenic.ts # 景区列表数据
│ └── scenic-detail.ts # 景区详情数据
├── pages/ # 主包页面
│ ├── index/index.vue # 首页(轮播 + 热门景区 + 精选活动)
│ ├── qrcode/index.vue # 入园码(tabBar 旅游卡)
│ ├── login/login.vue # 登录页(微信手机号授权)
│ ├── login/agreement.vue # 服务条款
│ ├── login/privacy.vue # 隐私条款
│ └── profile/index.vue # 个人中心(tabBar)
├── packages/user/ # 分包:用户相关(年卡、订单、预约)
│ ├── api/
│ │ ├── card.ts # 年卡 API
│ │ └── order.ts # 订单 API
│ ├── pages/
│ │ ├── card/list.vue # 年卡列表
│ │ ├── card/detail.vue # 年卡详情
│ │ ├── card/buy.vue # 年卡购买
│ │ ├── card/activate.vue # 年卡激活
│ │ ├── card/qrcode.vue # 入园码
│ │ ├── card/bind.vue # 年卡绑定
│ │ ├── bind.vue # 绑卡激活
│ │ ├── buy.vue # 超级玩家卡购买
│ │ ├── union-buy.vue # 工会购买
│ │ ├── card-notice.vue # 用卡须知
│ │ ├── order/list.vue # 订单列表
│ │ ├── order/detail.vue # 订单详情
│ │ ├── reserve/index.vue # 景区预约
│ │ ├── reserve/success.vue # 预约成功/详情
│ │ └── reserve/list.vue # 预约/使用记录
│ └── mock/
│ └── order.ts # 订单 mock 数据
├── packages/content/ # 分包:内容展示(景区、公告、帮助)
│ └── pages/
│ ├── scenic-list.vue # 景区列表(custom navbar)
│ ├── scenic-detail.vue # 景区详情
│ ├── notice-list.vue # 通知公告
│ ├── usage-guide.vue # 使用说明
│ └── faq.vue # 常见问题
├── store/
│ └── user.ts # 用户状态(token 持久化 + 登录判断)
├── styles/ # 设计系统样式
│ ├── main.scss # 入口(全局样式)
│ ├── _tokens.scss # 设计令牌(对齐 uni.scss)
│ ├── _mixins.scss # 混入(text-display / text-body / text-mono 等)
│ ├── _animations.scss # 动画
│ └── _utilities.scss # 工具类
├── static/ # 静态资源(tabBar 图标、logo 等)
├── utils/
│ └── index.ts # 工具函数(showToast / navigateTo 等)
├── App.vue # 根组件(隐私协议检查)
├── main.ts # 入口(createSSRApp + Pinia)
├── manifest.json # uni-app 配置(AppID)
├── pages.json # 路由 + tabBar + 分包 + easycom
└── uni.scss # 全局 SCSS 变量(自动注入到每个组件)
```
## 架构设计
### 分层
```
页面(.vue) → API 层(api/*.ts) → request.ts → uni.request → 后端
↕
Store(store/user.ts) ← 仅管理 token + 登录状态
```
- **页面直接调用 API**,不经过 store(年卡、订单等模块)
- **只有 user 模块使用 store**,因为需要跨页面共享 token 和登录状态
- **request.ts** 统一处理 Token 注入、401 跳转、响应格式解析(兼容 `code`/`errcode` 两种业务状态码)
### 路由
- 3 个 tabBar 页面:首页、旅游卡(入园码)、我的
- 主包:首页、登录、隐私/服务条款、个人中心
- 分包 `packages/user`:年卡、订单、预约功能
- 分包 `packages/content`:景区列表/详情、公告、使用说明、FAQ
### 微信登录
两种登录方式并存:
1. **OAuth2 登录**(当前使用):`wx.login()` → `encryptedData` + `iv` → `POST /open-api/auth/oauth2` → 返回 `openId` 作为 token
2. **手机号登录**(旧方式):`button[open-type=getPhoneNumber]` → `phoneCode` + `loginCode` → `POST /mp-api/auth/wx-login`
### 后端对接
- 后端项目:`jxxx-dscp`(Spring Boot 2.7 + MyBatis-Plus)
- 路由渠道:`RouteChannel.MP_API`(`/mp-api`)
- 认证方式:Bearer Token(`Authorization: Bearer {accessToken}`)
- 响应格式:`{ code, msg, data, errcode, errmsg }`(`code === 200` 或 `errcode === 0` 视为成功)
- 用户表:`member` 表,`channel = 99`(Channel_CY,产研小程序)
- Token 表:`system_oauth2_access_token`,`clientId = "mp-99"`
### Mock 系统
通过环境变量 `VITE_USE_MOCK=true` 启用。各页面在 `onLoad` 中检查 `USE_MOCK` 标志,为 true 时直接从 mock 文件渲染数据,不发起网络请求。
## 设计系统
样式体系基于 **uv-ui 设计系统**(`uv-*` 变量命名),通过 `uni.scss` 全局注入 SCSS 变量,每个组件无需额外 import 即可使用。
### 核心变量
| 类别 | 变量前缀 | 示例 |
|------|----------|------|
| 品牌色 | `$uv-primary` / `$color-accent` | `#3c9cff` |
| 语义色 | `$uv-error` / `$uv-success` / `$uv-warning` | 红/绿/橙 |
| 中性色 | `$uv-main-color` / `$uv-bg-color` / `$uv-border-color` | 黑/灰/白 |
| 字体 | `$font-family-display` / `$font-family-body` | 思源宋体 / PingFang |
| 字号 | `$font-size-*` | `xxs: 18rpx` ~ `display: 72rpx` |
| 间距 | `$spacing-*` | `0` ~ `160rpx` |
| 圆角 | `$radius-*` | `sm: 8rpx` ~ `full: 9999rpx` |
| 阴影 | `$shadow-*` | `sm` ~ `xl` + `accent` |
### 字体
- 展示字体:`SourceHanSerifCN`(思源宋体),用于标题
- 正文字体:系统字体栈(`-apple-system, PingFang SC, Helvetica Neue`)
- 等宽字体:`Menlo, Monaco, Courier New`
### 样式文件
- `uni.scss` — **source of truth**,自动注入到每个组件
- `src/styles/_tokens.scss` — 兼容层,对齐 `uni.scss` 的值,供 `main.scss` 使用
- `src/styles/main.scss` — 全局样式入口,在 `App.vue` 中通过 `@use` 导入
- 另外还有 `_mixins.scss`、`_animations.scss`、`_utilities.scss`
## 环境配置
| 文件 | API 地址 | 用途 |
|------|---------|------|
| `.env.local` | `http://localhost:48080` | 本地开发(配合后端 local profile) |
| `.env.dev` | `https://dscp-dev.hn12301.net` | 开发环境 |
| `.env.uat` | `https://dscp-uat.hn12301.net` | UAT 测试 |
## Git 远程
- `gitee` → `https://gitee.com/jacobxu666/zhy-mp-test.git`(唯一远程,`main` 跟踪此分支)
- 当前分支:`xuchao`
## 开发注意事项
1. **API 前缀**:所有接口走 `/mp-api`(不是 `/manage-api`,那是管理后台)
2. **Token 管理**:`app_token` 存在 `uni.storage` 中,通过 `request.ts` 的 `getToken/setToken/removeToken` 管理
3. **分包策略**:年卡/订单/预约放 `packages/user`,景区内容放 `packages/content`,主包仅放首页/登录/个人中心/入园码
4. **条件编译**:`#ifdef MP-WEIXIN` 包裹微信特有逻辑
5. **隐私协议**:`App.vue` 中 `wx.getPrivacySetting` 检查,未同意前不能调授权 API
6. **微信开发者工具调试**:需勾选「不校验合法域名」才能请求 localhost
7. **Mock 模式**:设置 `VITE_USE_MOCK=true` 可离线开发,不依赖后端
8. **样式对齐**:`uni.scss` 是设计令牌的 source of truth,`src/styles/_tokens.scss` 仅供 `main.scss` 兼容使用,新增样式变量优先在 `uni.scss` 中定义