You need to sign in or sign up before continuing.
CLAUDE.md 5.38 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

常用命令

pnpm dev:weapp          # 开发模式(微信小程序,watch)
pnpm build:weapp        # 生产构建(微信小程序)
pnpm dev:h5             # 开发模式(H5)
pnpm lint               # ESLint 检查

包管理器:pnpm。构建产物输出到 dist/,微信开发者工具指向此目录。

技术栈

Taro 4.1.9 + Vue 3 (Composition API <script setup>) + NutUI 4.x + Pinia + axios-miniprogram + Less + TailwindCSS + Webpack 5

架构要点

双设计宽度体系

config/index.jsdesignWidth 函数根据文件路径判断基准:

  • NutUI 组件文件(含 @nutui)→ 375px
  • 其他所有页面/组件 → 750px

编写样式时注意:NutUI 组件按 375 设计稿,自定义组件按 750 设计稿。

认证流程

启动链路(src/app.js onLaunch):

  1. saveCurrentPagePath() 保存当前路径到 routerStore
  2. 跳过 auth 页本身
  3. 若无 sessionid → silentAuth() 静默授权(Taro.login 获取 code → 后端 openid_wxapp 换 cookie)

请求链路(src/utils/request.js 拦截器):

  1. 请求拦截:注入 cookie header、合并默认参数、GET 加时间戳
  2. 响应拦截:code === 401refreshSession() 静默续期 → 成功则重放原请求(__is_retry 防循环)→ 失败则 navigateToAuth() 跳授权页
  3. 授权页完成后 returnToOriginalPage() 回跳来源页

auth_promise 单例锁防止并发重复授权。navigating_to_auth + 时间戳防重复跳转。

HTTP 客户端

src/utils/request.js:axios-miniprogram 实例,baseURL 来自 src/utils/config.js(按 NODE_ENV 切换),超时 5s。

src/api/fn.js:统一请求封装。

  • fn(api) — 标准化后端返回 { code, data, msg }code === 1 成功,失败自动 toast
  • fetch.get / fetch.post / fetch.stringifyPost / fetch.basePost — 封装不同请求方式

API 定义模式

// src/api/index.js — 用 buildApiUrl(action, params) 生成 URL
// buildApiUrl 拼接:${BASE_URL}/srv/?a=${action}&f=...&client_name=...&params...
export const xxxAPI = (params) => buildApiUrl('action_name', params)

// 调用方式
import { fn, fetch } from '@/api/fn'
import { xxxAPI } from '@/api'
const res = await fn(fetch.get(xxxAPI({ key: value })))

导航

src/hooks/useGo.js

  • useGo() → 返回 go(path, query) 函数,支持短路径('notice' 自动补全为 pages/notice/index),自动处理 tabbar 降级
  • useReplace() → 返回 replace(path, query) 函数,使用 redirectTo

路径别名

@/utils → src/utils      @/components → src/components
@/api → src/api           @/stores → src/stores
@/hooks → src/hooks       @/composables → src/composables
@/images → src/assets/images   @/assets → src/assets

项目结构

src/
├── api/          # 接口定义(index.js 用 buildApiUrl,fn.js 封装请求)
├── assets/       # 静态资源(images/、styles/、css/)
├── components/   # 通用组件
├── composables/  # Composition API hooks
├── hooks/        # useGo 等导航/工具 hooks
├── pages/        # 页面(pages/auth/index 为授权页,必须保留)
├── stores/       # Pinia stores(router.js 管理回跳路径)
└── utils/        # 核心工具(authRedirect.js、request.js、config.js)

关键约定

  • 后端返回格式:{ code: 1, data, msg }code === 1 为成功
  • sessionid 存储在 Taro Storage,key 为 sessionid
  • 公共请求参数(fclient_name)在 src/utils/config.jsREQUEST_DEFAULT_PARAMS 中配置
  • NutUI 组件已配置自动导入(unplugin-vue-components),无需手动 import
  • TailwindCSS 已禁用 preflight(corePlugins.preflight: false),避免与小程序冲突
  • 新增页面必须同时在 src/app.config.js 的 pages 数组中注册
  • 微信小程序 appid:wx602d6843b145058b

授权流程

完整链路(src/utils/authRedirect.js):

  1. 启动app.js onLaunch → silentAuth()Taro.login 获取 code → 后端 /srv/?a=openid 换 cookie → 写入 sessionid
  2. 请求 401request.js 响应拦截器 → refreshSession() 续期 → 成功重放原请求(__is_retry 防循环)→ 失败 navigateToAuth() 跳授权页
  3. 授权页pages/auth/indexsilentAuth()returnToOriginalPage() 回跳
  4. 防重入auth_promise 单例锁防并发,navigating_to_auth + 时间戳防重复跳转
  5. sessionid 存储在 Taro Storage,key 为 sessionidhasAuth() 判断是否已授权

支付流程

src/composables/useWechatMiniPay.js 统一封装:

  1. 手动测试pages/pay-test → 输入 order_id → pay_by_order_id() → 获取支付参数 → Taro.requestPayment
  2. WebView 桥接pages/webview-preview 内嵌 H5 → H5 跳 pages/pay-bridge?order_id=xxx → 自动授权 + 拉起支付 → 支付结束自动返回
  3. APIgetWechatPayParamsAPI({ order_id }) → POST /srv/?a=pay 获取微信支付参数(timeStamp/nonceStr/package/signType/paySign)
  4. 自动授权pay_by_order_idauto_auth 选项(默认 true),未授权时先 refresh_auth() 再支付
  5. 返回格式{ code, status: 'success'|'cancel'|'fail'|'auth_required'|..., msg, data }