CLAUDE.md 8.82 KB

CLAUDE.md

本文件为 Claude Code (claude.ai/code) 在此代码库中工作时提供指导。

项目概述

lls_program 是一个基于 Taro 4 + Vue 3 + NutUI 的微信小程序,名为"老来赛"。这是一个家庭活动和积分奖励管理系统。

技术栈

  • 框架: Taro 4.1.7 - 跨平台小程序框架
  • UI: Vue 3.3 + Composition API (<script setup>)
  • UI 组件库: NutUI Taro 4.3.13 (自动导入,无需手动引入)
  • 样式: TailwindCSS 3.4 + Less (组件特定样式)
  • 状态管理: Pinia 3.0 + taro-plugin-pinia
  • HTTP 请求: axios-miniprogram 2.7.2
  • 构建工具: Webpack 5

开发命令

# 安装依赖
pnpm install

# 开发(微信小程序)
pnpm run dev:weapp

# 生产构建
pnpm run build:weapp

# 其他平台
pnpm run dev:h5      # H5 开发
pnpm run dev:alipay  # 支付宝小程序
pnpm run dev:tt      # 抖音小程序

架构设计

核心目录结构

src/
├── api/              # 按业务领域组织的 API 接口
├── assets/           # 静态资源(图片、样式)
├── components/       # 可复用的 Vue 组件
├── composables/      # Vue 3 组合式函数 (useXxx)
├── pages/            # Taro 页面(每个页面包含 index.vue + index.config.js)
├── stores/           # Pinia 状态管理
├── utils/            # 工具函数
├── app.config.js     # Taro 应用配置(页面列表、窗口、权限)
└── app.less          # 全局样式

路径别名 (config/index.js:30-38)

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

设计宽度配置

  • NutUI 组件: 375px (自动处理)
  • 其他所有内容: 750px (Taro 标准)
  • config/index.js 中的 designWidth 函数根据文件路径自动切换

核心 API 模式

API 响应格式

所有 API 响应遵循以下结构:

{
  code: 1,           // 1 = 成功,其他值 = 失败
  data: {...},       // 响应数据
  msg: "message"     // 错误/成功消息
}

始终检查 res.code === 1(而不是 res.code)来判断成功。

认证机制 (sessionid)

关键: 项目使用 sessionid 进行认证(存储在 wx.storage 中):

  1. 获取: src/utils/request.js:23-30 - getSessionId()wx.getStorageSync("sessionid") 读取
  2. 设置: 在 miniProgramAuthAPIloginAPI 成功后设置
  3. 使用: 请求拦截器 (request.js:75-78) 设置 config.headers.cookie = sessionid
  4. 清除: 收到 401 响应或用户登出时

⚠️ 重要: sessionid 由前端用于判断登录状态(后端通过 401 响应来判断)。它只是传递给服务器的凭证。

请求拦截器 (src/utils/request.js:66-80)

service.interceptors.request.use(config => {
  // 动态获取 sessionid 并设置到请求头
  const sessionid = getSessionId();
  if (sessionid) {
    config.headers.cookie = sessionid;
  }
  return config;
})

API 模块模式 (src/api/)

每个 API 文件导出调用中央 fn() 辅助函数的函数:

// src/api/common.js
export const smsAPI = (params) => fn(fetch.post(Api.SMS, params));

关键 API 模块:

  • common.js - 短信验证码、上传凭证
  • user.js - 用户认证和个人信息
  • family.js - 家庭管理
  • points.js - 积分/奖励系统
  • photo.js - 照片/媒体处理
  • organization.js - 组织管理

Taro 小程序限制

❌ 禁止使用 Web API

// 禁止 - 在小程序中会崩溃
window.document.getElementById()
localStorage
window.location.href
fetch()

✅ 必须使用 Taro API

// 正确 - 使用 Taro 等价 API
Taro.createSelectorQuery()
Taro.getStorage() / Taro.setStorage()
Taro.navigateTo()
Taro.request()

页面生命周期(使用 Taro Hooks)

import { useLoad, useShow, useReady } from '@tarojs/taro'

useLoad((options) => {
  // 页面加载(仅触发一次)- 适合获取路由参数
})

useShow(() => {
  // 页面显示(每次显示都触发)- 适合刷新数据
})

useReady(() => {
  // 页面首次渲染完成
})

❌ 页面中避免使用 Vue 生命周期

// 不要使用 - 可能无法正常工作
onMounted(() => { ... })
onUnmounted(() => { ... })

组件指南

页面结构

每个页面目录包含:

  • index.vue - 页面组件(必须使用 <script setup>
  • index.config.js - 页面特定配置(navigationBarTitleText 等)
  • index.less - 页面特定样式(scoped)

组件命名规范

  • 页面: 目录名(如 pages/Dashboard/
  • 组件: PascalCase 多单词命名(如 PointsCollector.vueFamilyAlbum.vue
  • API 文件: camelCase(如 miniProgramAuthAPI

NutUI 自动导入

NutUI 组件通过 unplugin-vue-components 自动导入。不要手动导入:

<!-- ✅ 正确 - 自动导入 -->
<template>
  <nut-button type="primary">点击</nut-button>
</template>

<!-- ❌ 错误 - 不要导入 -->
<script setup>
import { Button } from '@nutui/nutui-taro'
</script>

样式

TailwindCSS + Less 混合使用

  • TailwindCSS: 用于布局、间距、颜色、排版(80% 的样式)
  • Less: 用于组件特定样式、动画、深度选择器(20%)

Tailwind 配置

  • Content: ./src/**/*.{html,js,ts,jsx,tsx,vue} (tailwind.config.js:13)
  • Preflight: 禁用(小程序不需要)
  • rem → rpx: 由 weapp-tailwindcss 插件处理 (rem2rpx: true)

样式指南

<style lang="less" scoped>
/* ✅ 组件必须使用 scoped */
.page-container {
  padding: 30px;
}

/* ✅ 使用 Less 处理深度选择器 */
.custom-element :deep(.nut-popup) {
  background-color: #fff;
}
</style>

状态管理 (Pinia)

Store 模式

// src/stores/host.js
import { defineStore } from 'pinia'

export const hostStore = defineStore('host', {
  state: () => ({
    id: '',
    join_id: ''
  }),
  actions: {
    add(id) {
      this.id = id
    }
  }
})

在组件中使用

<script setup>
import { hostStore } from '@/stores/host'

const host = hostStore()
host.add('123')
</script>

常用模式

页面导航

import Taro from '@tarojs/taro'

// 跳转到页面
Taro.navigateTo({
  url: '/pages/Detail/index?id=123'
})

// 重定向(无返回)
Taro.redirectTo({
  url: '/pages/Login/index'
})

// 切换 Tab
Taro.switchTab({
  url: '/pages/Dashboard/index'
})

// 获取路由参数
useLoad((options) => {
  const { id } = options
})

本地存储

// 异步(推荐)
await Taro.setStorage({ key: 'user', data: userInfo })
const { data } = await Taro.getStorage({ key: 'user' })

// 同步(谨慎使用)
Taro.setStorageSync('token', 'xxxx')
const token = Taro.getStorageSync('token')

提示/弹窗

// Toast 提示
Taro.showToast({
  title: '操作成功',
  icon: 'success',
  duration: 2000
})

// Modal 弹窗
Taro.showModal({
  title: '提示',
  content: '确定删除吗?',
  success: (res) => {
    if (res.confirm) {
      // 用户点击了确定
    }
  }
})

页面注册

页面在 src/app.config.js 中注册:

export default {
  pages: [
    'pages/Dashboard/index',
    'pages/MyFamily/index',
    'pages/Activities/index',
    // ... 更多页面
  ]
}

创建新页面时: 必须将其添加到此数组中。

构建输出

  • 开发环境: dist/ 目录
  • 微信开发者工具: 打开 dist/ 作为项目根目录

重要文件说明

src/utils/request.js

核心 HTTP 客户端,包含:

  • SessionID 注入
  • 401 响应处理
  • 401 时静默授权重定向
  • 错误处理

src/utils/authRedirect.js

处理小程序登录流程的静默授权。

src/utils/tools.js

通用工具函数:

  • formatDate() - 使用 moment.js 格式化日期
  • wxInfo() - 平台检测(Android/iOS/微信)
  • hasEllipsis() - 文本溢出检测

开发注意事项

  1. 始终使用 Taro API 而非 Web API
  2. 检查 res.code === 1 判断 API 成功(不是 res.code
  3. NutUI 组件已自动导入 - 不要手动导入
  4. 页面中使用 Taro 生命周期钩子useLoaduseShow
  5. SessionID 动态获取 - 每次请求从存储中读取
  6. 已配置路径别名 - 使用 @/components 代替相对路径
  7. 设计宽度双模式: NutUI 使用 375px,其他使用 750px

平台差异

项目通过 Taro 支持多平台:

  • 微信 (weapp): 主要目标平台
  • H5: Web 浏览器版本
  • 支付宝 (alipay): 支付宝小程序
  • 抖音 (tt): 字节跳动小程序

平台特定代码可使用:

if (process.env.TARO_ENV === 'weapp') {
  // 微信特定代码
}