Update CLAUDE.md
This commit is contained in:
@@ -4,72 +4,111 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
|
||||
## 项目定位
|
||||
|
||||
## 项目定位
|
||||
|
||||
**湖南12301文旅专区**用户端微信小程序(C端),基于 uni-app + Vue 3 + TypeScript + Pinia。仅包含用户端功能,不含管理端。
|
||||
**爱上萍乡**用户端微信小程序(C端),基于 uni-app + Vue 3 + TypeScript + Pinia。仅包含用户端功能,不含管理端。
|
||||
|
||||
## 技术栈
|
||||
|
||||
| 技术 | 版本 | 说明 |
|
||||
|------|------|------|
|
||||
| Vue | 3.5.x | 核心框架 |
|
||||
| uni-app | 3.0.0 | 跨平台框架(当前仅编译微信小程序) |
|
||||
| uni-app | 3.0.0-alpha | 跨平台框架(当前仅编译微信小程序) |
|
||||
| TypeScript | 4.9.x | 类型系统 |
|
||||
| Pinia | 3.x | 状态管理(仅 user store) |
|
||||
| Vite | 5.2.8 | 构建工具 |
|
||||
| @dcloudio/uni-ui | 1.5.12 | UI 组件库(easycom 自动导入) |
|
||||
| @dcloudio/uni-ui | 1.5.x | UI 组件库(easycom 自动导入) |
|
||||
| sass | 1.101.x | 样式预处理 |
|
||||
|
||||
## 微信小程序配置
|
||||
## 运行命令
|
||||
|
||||
- **AppID**: `wx636bc46a6570e9fd`
|
||||
- **后端接口前缀**: `/mp-api`(对应后端 `RouteChannel.MP_API`)
|
||||
- **API 基础地址**: 由 `.env.*` 文件的 `VITE_API_BASE_URL` 控制
|
||||
```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/`,用微信开发者工具导入此目录。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
zhy-test/
|
||||
├── src/
|
||||
│ ├── api/ # API 接口层
|
||||
│ │ ├── request.ts # HTTP 封装(uni.request + Token 注入 + 401 处理)
|
||||
│ │ ├── types.ts # TypeScript 类型定义
|
||||
│ │ ├── user.ts # 微信登录 + 用户信息
|
||||
│ │ ├── card.ts # 年卡列表/详情/激活/绑定/入园码
|
||||
│ │ └── order.ts # 订单创建/支付/查询
|
||||
│ ├── components/ # 公共组件
|
||||
│ │ ├── McGlass.vue # 毛玻璃卡片
|
||||
│ │ ├── card-item.vue # 年卡列表项
|
||||
│ │ └── empty-state.vue # 空状态占位
|
||||
│ ├── config/
|
||||
│ │ └── index.ts # API_BASE / TOKEN_KEY / REFRESH_TOKEN_KEY
|
||||
│ ├── pages/ # 主包页面
|
||||
│ │ ├── index/index.vue # 首页(轮播 + 热门景区 + 精选活动)
|
||||
│ │ ├── login/login.vue # 登录页(微信手机号授权登录)
|
||||
│ │ └── profile/index.vue # 个人中心(tabBar)
|
||||
│ ├── packages/user/pages/card/ # 分包:年卡功能(减小主包体积)
|
||||
│ │ ├── list.vue # 年卡列表(搜索 + 分类筛选)
|
||||
│ │ ├── detail.vue # 年卡详情(权益 + 景区 + 富文本)
|
||||
│ │ ├── buy.vue # 购买确认 + 模拟支付
|
||||
│ │ ├── activate.vue # 实名激活(姓名 + 身份证 + 手机)
|
||||
│ │ ├── qrcode.vue # 入园码(60秒自动刷新)
|
||||
│ │ └── bind.vue # 卡号绑定
|
||||
│ ├── static/ # 静态资源(logo + tabBar 图标)
|
||||
│ ├── store/
|
||||
│ │ └── user.ts # 用户状态(token 持久化 + 登录判断)
|
||||
│ ├── utils/
|
||||
│ │ └── index.ts # 工具函数(showToast / navigateTo 等)
|
||||
│ ├── App.vue # 根组件(隐私协议检查 + 自动获取用户信息)
|
||||
│ ├── main.ts # 入口(createSSRApp + Pinia)
|
||||
│ ├── manifest.json # uni-app 配置(AppID)
|
||||
│ ├── pages.json # 路由 + tabBar + 分包 + easycom
|
||||
│ └── uni.scss # 全局 SCSS 变量
|
||||
├── .env.local # 本地开发环境
|
||||
├── .env.dev # 开发环境
|
||||
├── .env.uat # UAT 环境
|
||||
├── package.json
|
||||
├── project.config.json # 微信开发者工具配置
|
||||
├── vite.config.ts
|
||||
└── tsconfig.json
|
||||
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 变量(自动注入到每个组件)
|
||||
```
|
||||
|
||||
## 架构设计
|
||||
@@ -77,136 +116,92 @@ zhy-test/
|
||||
### 分层
|
||||
|
||||
```
|
||||
页面(.vue) → API 层(api/*.ts) → HTTP 封装(request.ts) → uni.request → 后端
|
||||
页面(.vue) → API 层(api/*.ts) → request.ts → uni.request → 后端
|
||||
↕
|
||||
Store(store/user.ts) ← 仅管理 token + 登录状态
|
||||
```
|
||||
|
||||
- **页面直接调用 API**,不经过 store(年卡、订单等模块)
|
||||
- **只有 user 模块使用 store**,因为需要跨页面共享 token 和登录状态
|
||||
- **request.ts** 统一处理 Token 注入、401 跳转、响应格式解析
|
||||
- **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}`)
|
||||
- 响应格式:`{ errcode, errmsg, data, traceid }`(框架自动包装 `ResDto`)
|
||||
- 响应格式:`{ code, msg, data, errcode, errmsg }`(`code === 200` 或 `errcode === 0` 视为成功)
|
||||
- 用户表:`member` 表,`channel = 99`(Channel_CY,产研小程序)
|
||||
- Token 表:`system_oauth2_access_token`,`clientId = "mp-99"`
|
||||
|
||||
### 微信登录流程
|
||||
### Mock 系统
|
||||
|
||||
```
|
||||
前端 button[open-type=getPhoneNumber]
|
||||
→ phoneCode + wx.login() → loginCode
|
||||
→ POST /mp-api/auth/wx-login { loginCode, phoneCode }
|
||||
→ 后端 jscode2session → openId
|
||||
→ 后端 getuserphonenumber → phoneNumber
|
||||
→ 查找/创建 member → 创建 token
|
||||
→ 返回 LoginResponse { accessToken, refreshToken, userId, openId, mobile }
|
||||
```
|
||||
通过环境变量 `VITE_USE_MOCK=true` 启用。各页面在 `onLoad` 中检查 `USE_MOCK` 标志,为 true 时直接从 mock 文件渲染数据,不发起网络请求。
|
||||
|
||||
## 运行命令
|
||||
## 设计系统
|
||||
|
||||
```bash
|
||||
# 安装依赖
|
||||
pnpm install
|
||||
样式体系基于 **uv-ui 设计系统**(`uv-*` 变量命名),通过 `uni.scss` 全局注入 SCSS 变量,每个组件无需额外 import 即可使用。
|
||||
|
||||
# 微信小程序开发构建
|
||||
pnpm run dev:mp-weixin
|
||||
### 核心变量
|
||||
|
||||
# 微信小程序生产构建
|
||||
pnpm run build:mp-weixin
|
||||
| 类别 | 变量前缀 | 示例 |
|
||||
|------|----------|------|
|
||||
| 品牌色 | `$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` |
|
||||
|
||||
# TypeScript 类型检查
|
||||
pnpm run type-check
|
||||
### 字体
|
||||
|
||||
# 构建产物目录
|
||||
dist/build/mp-weixin/ # 用微信开发者工具导入此目录
|
||||
```
|
||||
- 展示字体:`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` | 本地开发(配合后端 `--spring.profiles.active=local`) |
|
||||
| `.env.local` | `http://localhost:48080` | 本地开发(配合后端 local profile) |
|
||||
| `.env.dev` | `https://dscp-dev.hn12301.net` | 开发环境 |
|
||||
| `.env.uat` | `https://dscp-uat.hn12301.net` | UAT 测试 |
|
||||
|
||||
## 数据库环境
|
||||
## Git 远程
|
||||
|
||||
| 环境 | 地址 | 数据库 |
|
||||
|------|------|--------|
|
||||
| 本地(local profile) | `localhost:3306` | `dscp_business_dev` |
|
||||
| 开发(dev) | `120.26.254.65:3306` | `dscp_business_dev` |
|
||||
| UAT | `47.99.164.129:3306` | `dscp_business` |
|
||||
- `gitee` → `https://gitee.com/jacobxu666/zhy-mp-test.git`(唯一远程,`main` 跟踪此分支)
|
||||
- 当前分支:`xuchao`
|
||||
|
||||
## 开发注意事项
|
||||
|
||||
1. **API 前缀**:所有接口走 `/mp-api`(不是 `/manage-api`,那是管理后台)
|
||||
2. **Token 管理**:`app_token` / `app_refresh_token` 存在 `uni.storage` 中
|
||||
3. **分包策略**:年卡功能放分包(`packages/user`),首页/登录/个人中心在主包
|
||||
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
|
||||
|
||||
<frontend_aesthetics>
|
||||
You tend to converge toward generic, "on distribution" outputs.
|
||||
In frontend design, this creates what users call the "AI slop"
|
||||
aesthetic. Avoid this: make creative, distinctive frontends that
|
||||
surprise and delight. Focus on:
|
||||
|
||||
Typography: Choose fonts that are beautiful, unique, and interesting.
|
||||
Avoid generic fonts like Arial and Inter; opt instead for distinctive
|
||||
choices that elevate the frontend's aesthetics.
|
||||
|
||||
Color & Theme: Commit to a cohesive aesthetic. Use CSS variables for
|
||||
consistency. Dominant colors with sharp accents outperform timid,
|
||||
evenly-distributed palettes.
|
||||
|
||||
Motion: Use animations for effects and micro-interactions.
|
||||
Focus on high-impact moments: one well-orchestrated page load
|
||||
with staggered reveals creates more delight than scattered
|
||||
micro-interactions.
|
||||
|
||||
Backgrounds: Create atmosphere and depth rather than defaulting
|
||||
to solid colors. Layer CSS gradients, use geometric patterns,
|
||||
or add contextual effects.
|
||||
|
||||
Avoid generic AI-generated aesthetics:
|
||||
- Overused font families (Inter, Roboto, Arial, system fonts)
|
||||
- Clichéd color schemes (particularly purple gradients on white)
|
||||
- Predictable layouts and component patterns
|
||||
- Cookie-cutter design that lacks context-specific character
|
||||
|
||||
Interpret creatively and make unexpected choices that feel
|
||||
genuinely designed for the context.
|
||||
</frontend_aesthetics>
|
||||
|
||||
<use_interesting_fonts>
|
||||
Typography instantly signals quality. Avoid boring, generic fonts.
|
||||
|
||||
Never use: Inter, Roboto, Open Sans, Lato, default system fonts
|
||||
|
||||
Impact choices:
|
||||
- Code aesthetic: JetBrains Mono, Fira Code, Space Grotesk
|
||||
- Editorial: Playfair Display, Crimson Pro, Fraunces
|
||||
- Startup: Clash Display, Satoshi, Cabinet Grotesk
|
||||
- Technical: IBM Plex family, Source Sans 3
|
||||
- Distinctive: Bricolage Grotesque, Obviously, Newsreader
|
||||
|
||||
Pairing principle: High contrast = interesting.
|
||||
Display + monospace, serif + geometric sans.
|
||||
|
||||
Use extremes: 100/200 weight vs 800/900, not 400 vs 600.
|
||||
Size jumps of 3x+, not 1.5x.
|
||||
</use_interesting_fonts>
|
||||
|
||||
# Design System
|
||||
|
||||
Always refer to DESIGN.md when generating or modifying any UI component.
|
||||
Use only colors, fonts, and spacing values defined in DESIGN.md.
|
||||
Do not invent new values or use defaults from any framework.
|
||||
Match component states (hover, focus, active, disabled) to patterns
|
||||
in DESIGN.md.
|
||||
7. **Mock 模式**:设置 `VITE_USE_MOCK=true` 可离线开发,不依赖后端
|
||||
8. **样式对齐**:`uni.scss` 是设计令牌的 source of truth,`src/styles/_tokens.scss` 仅供 `main.scss` 兼容使用,新增样式变量优先在 `uni.scss` 中定义
|
||||
Reference in New Issue
Block a user