Files
jiebanke/docs/小程序app开发文档.md

24 KiB
Raw Permalink Blame History

小程序app开发文档

1. 项目概述

1.1 项目简介

解班客小程序是一个专注于旅行结伴和动物认领的微信小程序应用,为用户提供便捷的移动端服务体验。

1.2 技术栈

  • 开发框架uni-app 3.x
  • 开发语言Vue 3 + TypeScript
  • UI组件库uni-ui + 自定义组件
  • 状态管理Pinia
  • 网络请求uni.request + 封装
  • 地图服务腾讯地图API
  • 支付功能:微信支付
  • 图片处理uni.chooseImage + 压缩
  • 构建工具Vite
  • 代码规范ESLint + Prettier

1.3 项目结构

mini-program/
├── src/
│   ├── pages/           # 页面文件
│   │   ├── index/       # 首页
│   │   ├── travel/      # 旅行相关页面
│   │   ├── animal/      # 动物认领页面
│   │   ├── user/        # 用户相关页面
│   │   └── common/      # 通用页面
│   ├── components/      # 组件
│   │   ├── common/      # 通用组件
│   │   ├── travel/      # 旅行组件
│   │   └── animal/      # 动物组件
│   ├── store/           # 状态管理
│   ├── utils/           # 工具函数
│   ├── services/        # API服务
│   ├── types/           # 类型定义
│   ├── styles/          # 样式文件
│   ├── static/          # 静态资源
│   ├── App.vue          # 应用入口
│   ├── main.ts          # 主文件
│   └── manifest.json    # 应用配置
├── tests/               # 测试文件
├── docs/                # 文档
├── package.json
├── tsconfig.json
├── vite.config.ts
└── README.md

2. 开发环境搭建

2.1 环境要求

  • Node.js >= 16.0.0
  • npm >= 8.0.0
  • 微信开发者工具
  • HBuilderX可选

2.2 环境搭建步骤

2.2.1 安装开发工具

# 安装HBuilderX或使用VSCode
# 下载微信开发者工具

2.2.2 创建项目

# 使用uni-app CLI创建项目
npx @dcloudio/uvm@latest create jiebanke-miniprogram
cd jiebanke-miniprogram

2.2.3 安装依赖

npm install

2.2.4 配置开发环境

# 复制环境配置文件
cp .env.example .env.development
# 编辑配置文件

2.2.5 启动开发服务器

npm run dev:mp-weixin

2.3 开发工具配置

2.3.1 VSCode配置

推荐安装以下插件:

  • Vetur
  • TypeScript Importer
  • ESLint
  • Prettier
  • uni-app-schemas
  • uni-app-snippets

2.3.2 微信开发者工具配置

  • 导入项目选择dist/dev/mp-weixin目录
  • 配置AppID在manifest.json中配置
  • 开启ES6转ES5
  • 开启增强编译

3. 开发计划与任务分解

3.1 开发阶段划分

阶段一基础框架搭建预计8个工作日

  • 项目初始化和环境配置
  • 基础组件开发
  • 路由和状态管理配置
  • 通用工具类开发

阶段二核心页面开发预计20个工作日

  • 首页和导航
  • 用户系统页面
  • 旅行结伴页面
  • 动物认领页面

阶段三功能完善预计12个工作日

  • 支付功能集成
  • 消息通知功能
  • 搜索和筛选功能
  • 个人中心功能

阶段四优化和测试预计8个工作日

  • 性能优化
  • 兼容性测试
  • 用户体验优化
  • 发布准备

3.2 详细任务分解

3.2.1 阶段一:基础框架搭建

任务1.1项目初始化2个工作日

负责人:前端架构师 + 小程序开发工程师
工时估算16人时
任务描述

  • 创建uni-app项目结构
  • 配置TypeScript和构建工具
  • 设置代码规范和Git hooks
  • 配置开发环境

具体子任务

  1. 创建uni-app项目和目录结构4人时
  2. 配置TypeScript和Vite4人时
  3. 设置ESLint和Prettier2人时
  4. 配置环境变量和构建脚本3人时
  5. 设置Git hooks和提交规范3人时

验收标准

  • 项目可以正常编译和运行
  • 代码规范检查通过
  • 开发环境配置完整
任务1.2基础组件开发3个工作日

负责人:小程序开发工程师
工时估算24人时
任务描述

  • 开发通用UI组件
  • 创建布局组件
  • 开发表单组件
  • 创建反馈组件

具体子任务

  1. 按钮、输入框等基础组件6人时
  2. 导航栏、标签栏组件4人时
  3. 列表、卡片组件6人时
  4. 弹窗、提示组件4人时
  5. 加载、空状态组件4人时

验收标准

  • 组件功能完整
  • 样式符合设计规范
  • 支持自定义配置
任务1.3路由和状态管理2个工作日

负责人:小程序开发工程师
工时估算16人时
任务描述

  • 配置页面路由
  • 设置Pinia状态管理
  • 创建全局状态模块
  • 实现数据持久化

具体子任务

  1. 配置pages.json路由4人时
  2. 设置Pinia store结构4人时
  3. 创建用户状态模块4人时
  4. 实现本地存储封装4人时

验收标准

  • 路由跳转正常
  • 状态管理功能完整
  • 数据持久化正常
任务1.4通用工具类开发1个工作日

负责人:小程序开发工程师
工时估算8人时
任务描述

  • 网络请求封装
  • 工具函数开发
  • 常量定义
  • 类型定义

具体子任务

  1. HTTP请求封装3人时
  2. 日期、字符串工具函数2人时
  3. 常量和枚举定义2人时
  4. TypeScript类型定义1人时

验收标准

  • 网络请求功能完整
  • 工具函数覆盖常用场景
  • 类型定义准确

3.2.2 阶段二:核心页面开发

任务2.1首页和导航3个工作日

负责人:小程序开发工程师
工时估算24人时
任务描述

  • 首页布局和功能
  • 底部导航栏
  • 搜索功能
  • 轮播图和推荐

具体子任务

  1. 首页整体布局6人时
  2. 轮播图组件4人时
  3. 推荐内容展示6人时
  4. 搜索功能实现4人时
  5. 底部导航栏4人时

验收标准

  • 首页布局美观
  • 导航功能正常
  • 搜索结果准确
任务2.2用户系统页面4个工作日

负责人:小程序开发工程师
工时估算32人时
任务描述

  • 登录授权页面
  • 个人信息页面
  • 设置页面
  • 实名认证页面

具体子任务

  1. 微信登录授权页面6人时
  2. 个人信息展示和编辑8人时
  3. 用户设置页面6人时
  4. 实名认证流程页面6人时
  5. 头像上传功能6人时

验收标准

  • 登录流程顺畅
  • 个人信息管理完整
  • 实名认证功能正常
任务2.3旅行结伴页面7个工作日

负责人:小程序开发工程师
工时估算56人时
任务描述

  • 旅行列表页面
  • 旅行详情页面
  • 发布旅行页面
  • 申请参与页面

具体子任务

  1. 旅行活动列表页面10人时
  2. 旅行详情页面12人时
  3. 发布旅行活动页面12人时
  4. 申请参与页面8人时
  5. 我的旅行页面8人时
  6. 旅行搜索和筛选6人时

验收标准

  • 列表展示美观
  • 详情信息完整
  • 发布流程顺畅
  • 申请功能正常
任务2.4动物认领页面6个工作日

负责人:小程序开发工程师
工时估算48人时
任务描述

  • 动物列表页面
  • 动物详情页面
  • 认领申请页面
  • 认领记录页面

具体子任务

  1. 动物列表页面10人时
  2. 动物详情页面12人时
  3. 认领申请页面10人时
  4. 我的认领页面8人时
  5. 认领动态页面8人时

验收标准

  • 动物信息展示完整
  • 认领流程清晰
  • 动态更新及时

3.2.3 阶段三:功能完善

任务3.1支付功能集成3个工作日

负责人:小程序开发工程师
工时估算24人时
任务描述

  • 订单确认页面
  • 微信支付集成
  • 支付结果页面
  • 订单管理页面

具体子任务

  1. 订单确认页面6人时
  2. 微信支付功能集成8人时
  3. 支付结果处理4人时
  4. 订单列表和详情6人时

验收标准

  • 支付流程完整
  • 支付结果准确
  • 订单管理功能正常
任务3.2消息通知功能2个工作日

负责人:小程序开发工程师
工时估算16人时
任务描述

  • 消息列表页面
  • 消息详情页面
  • 消息推送处理
  • 消息状态管理

具体子任务

  1. 消息列表页面6人时
  2. 消息详情页面4人时
  3. 消息推送处理4人时
  4. 消息状态管理2人时

验收标准

  • 消息展示正常
  • 推送功能正常
  • 状态更新及时
任务3.3搜索和筛选功能3个工作日

负责人:小程序开发工程师
工时估算24人时
任务描述

  • 搜索页面优化
  • 高级筛选功能
  • 搜索历史管理
  • 搜索建议功能

具体子任务

  1. 搜索页面优化6人时
  2. 筛选条件组件8人时
  3. 搜索历史功能4人时
  4. 搜索建议实现6人时

验收标准

  • 搜索功能完善
  • 筛选条件准确
  • 用户体验良好
任务3.4个人中心功能4个工作日

负责人:小程序开发工程师
工时估算32人时
任务描述

  • 个人中心首页
  • 收藏和点赞管理
  • 关注和粉丝功能
  • 设置和帮助页面

具体子任务

  1. 个人中心首页8人时
  2. 收藏和点赞页面8人时
  3. 关注和粉丝页面8人时
  4. 设置和帮助页面8人时

验收标准

  • 个人中心功能完整
  • 社交功能正常
  • 设置项目齐全

3.2.4 阶段四:优化和测试

任务4.1性能优化3个工作日

负责人:小程序开发工程师
工时估算24人时
任务描述

  • 页面加载优化
  • 图片懒加载
  • 代码分包优化
  • 缓存策略优化

具体子任务

  1. 页面加载性能优化8人时
  2. 图片懒加载实现6人时
  3. 代码分包配置4人时
  4. 缓存策略优化6人时

验收标准

  • 页面加载速度提升30%
  • 图片加载流畅
  • 包体积控制在合理范围
任务4.2兼容性测试2个工作日

负责人:小程序开发工程师 + 测试工程师
工时估算16人时
任务描述

  • 不同机型测试
  • 不同版本测试
  • 网络环境测试
  • 边界情况测试

具体子任务

  1. iOS和Android兼容性测试6人时
  2. 不同微信版本测试4人时
  3. 弱网络环境测试3人时
  4. 边界情况和异常测试3人时

验收标准

  • 主流机型兼容性良好
  • 弱网络环境可用
  • 异常情况处理正确
任务4.3用户体验优化2个工作日

负责人:小程序开发工程师 + UI设计师
工时估算16人时
任务描述

  • 交互体验优化
  • 视觉效果优化
  • 无障碍功能
  • 用户反馈收集

具体子任务

  1. 交互动画和反馈优化6人时
  2. 视觉效果和样式调整6人时
  3. 无障碍功能支持2人时
  4. 用户反馈机制2人时

验收标准

  • 交互体验流畅
  • 视觉效果美观
  • 支持无障碍访问
任务4.4发布准备1个工作日

负责人:小程序开发工程师
工时估算8人时
任务描述

  • 代码审查和清理
  • 版本号管理
  • 发布配置
  • 文档整理

具体子任务

  1. 代码审查和优化3人时
  2. 版本号和更新日志2人时
  3. 发布配置检查2人时
  4. 用户手册整理1人时

验收标准

  • 代码质量达标
  • 发布配置正确
  • 文档完整

4. 开发规范

4.1 代码规范

4.1.1 命名规范

  • 文件命名使用kebab-caseuser-profile.vue
  • 组件命名使用PascalCaseUserProfile
  • 方法命名使用camelCasegetUserInfo
  • 常量命名使用UPPER_SNAKE_CASEAPI_BASE_URL

4.1.2 目录结构规范

src/
├── pages/
│   ├── index/
│   │   ├── index.vue
│   │   └── index.scss
│   └── user/
│       ├── profile/
│       │   ├── profile.vue
│       │   └── profile.scss
│       └── settings/
│           ├── settings.vue
│           └── settings.scss
├── components/
│   ├── common/
│   │   ├── Button/
│   │   │   ├── Button.vue
│   │   │   └── Button.scss
│   │   └── Input/
│   │       ├── Input.vue
│   │       └── Input.scss
│   └── business/
│       ├── TravelCard/
│       └── AnimalCard/

4.1.3 Vue组件规范

<template>
  <view class="user-profile">
    <view class="user-profile__header">
      <image :src="userInfo.avatar" class="user-profile__avatar" />
      <text class="user-profile__name">{{ userInfo.nickname }}</text>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import type { UserInfo } from '@/types/user'

interface Props {
  userId?: number
}

const props = withDefaults(defineProps<Props>(), {
  userId: 0
})

const userInfo = ref<UserInfo>({} as UserInfo)

const getUserInfo = async () => {
  // 获取用户信息逻辑
}

onMounted(() => {
  getUserInfo()
})
</script>

<style lang="scss" scoped>
.user-profile {
  padding: 20rpx;
  
  &__header {
    display: flex;
    align-items: center;
  }
  
  &__avatar {
    width: 100rpx;
    height: 100rpx;
    border-radius: 50%;
  }
  
  &__name {
    margin-left: 20rpx;
    font-size: 32rpx;
    font-weight: bold;
  }
}
</style>

4.2 API调用规范

4.2.1 服务层封装

// services/user.service.ts
import { http } from '@/utils/http'
import type { UserInfo, LoginParams } from '@/types/user'

export class UserService {
  /**
   * 用户登录
   */
  static async login(params: LoginParams): Promise<UserInfo> {
    return http.post('/auth/wechat/login', params)
  }

  /**
   * 获取用户信息
   */
  static async getUserInfo(): Promise<UserInfo> {
    return http.get('/auth/me')
  }

  /**
   * 更新用户信息
   */
  static async updateUserInfo(data: Partial<UserInfo>): Promise<UserInfo> {
    return http.put('/auth/profile', data)
  }
}

4.2.2 HTTP请求封装

// utils/http.ts
import type { RequestOptions } from '@/types/http'

class HttpClient {
  private baseURL = process.env.VUE_APP_API_BASE_URL
  private timeout = 10000

  async request<T>(options: RequestOptions): Promise<T> {
    return new Promise((resolve, reject) => {
      uni.request({
        url: this.baseURL + options.url,
        method: options.method || 'GET',
        data: options.data,
        header: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${uni.getStorageSync('token')}`,
          ...options.header
        },
        timeout: this.timeout,
        success: (res) => {
          if (res.statusCode === 200) {
            const data = res.data as any
            if (data.code === 200) {
              resolve(data.data)
            } else {
              reject(new Error(data.message))
            }
          } else {
            reject(new Error('网络请求失败'))
          }
        },
        fail: (err) => {
          reject(err)
        }
      })
    })
  }

  get<T>(url: string, params?: any): Promise<T> {
    return this.request({ url, method: 'GET', data: params })
  }

  post<T>(url: string, data?: any): Promise<T> {
    return this.request({ url, method: 'POST', data })
  }

  put<T>(url: string, data?: any): Promise<T> {
    return this.request({ url, method: 'PUT', data })
  }

  delete<T>(url: string): Promise<T> {
    return this.request({ url, method: 'DELETE' })
  }
}

export const http = new HttpClient()

4.3 状态管理规范

4.3.1 Store结构

// store/user.ts
import { defineStore } from 'pinia'
import { UserService } from '@/services/user.service'
import type { UserInfo } from '@/types/user'

export const useUserStore = defineStore('user', {
  state: () => ({
    userInfo: {} as UserInfo,
    token: '',
    isLoggedIn: false
  }),

  getters: {
    isProfileCompleted: (state) => {
      return !!(state.userInfo.nickname && state.userInfo.avatar_url)
    }
  },

  actions: {
    async login(code: string) {
      try {
        const result = await UserService.login({ code })
        this.token = result.access_token
        this.userInfo = result.user_info
        this.isLoggedIn = true
        
        // 保存到本地存储
        uni.setStorageSync('token', this.token)
        uni.setStorageSync('userInfo', this.userInfo)
      } catch (error) {
        throw error
      }
    },

    async getUserInfo() {
      try {
        this.userInfo = await UserService.getUserInfo()
        uni.setStorageSync('userInfo', this.userInfo)
      } catch (error) {
        throw error
      }
    },

    logout() {
      this.token = ''
      this.userInfo = {} as UserInfo
      this.isLoggedIn = false
      
      uni.removeStorageSync('token')
      uni.removeStorageSync('userInfo')
    }
  }
})

4.4 样式规范

4.4.1 SCSS变量定义

// styles/variables.scss
// 颜色变量
$primary-color: #007aff;
$success-color: #4cd964;
$warning-color: #f0ad4e;
$error-color: #dd524d;

// 字体大小
$font-size-xs: 20rpx;
$font-size-sm: 24rpx;
$font-size-base: 28rpx;
$font-size-lg: 32rpx;
$font-size-xl: 36rpx;

// 间距
$spacing-xs: 10rpx;
$spacing-sm: 20rpx;
$spacing-base: 30rpx;
$spacing-lg: 40rpx;
$spacing-xl: 50rpx;

// 圆角
$border-radius-sm: 8rpx;
$border-radius-base: 12rpx;
$border-radius-lg: 16rpx;

4.4.2 通用样式类

// styles/common.scss
// 布局类
.flex {
  display: flex;
}

.flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

.flex-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

// 文本类
.text-center {
  text-align: center;
}

.text-primary {
  color: $primary-color;
}

.text-success {
  color: $success-color;
}

// 间距类
.m-0 { margin: 0; }
.m-1 { margin: $spacing-xs; }
.m-2 { margin: $spacing-sm; }
.m-3 { margin: $spacing-base; }

.p-0 { padding: 0; }
.p-1 { padding: $spacing-xs; }
.p-2 { padding: $spacing-sm; }
.p-3 { padding: $spacing-base; }

5. 质量保证

5.1 代码质量检查

5.1.1 ESLint配置

// .eslintrc.js
module.exports = {
  extends: [
    '@vue/typescript/recommended',
    '@vue/prettier',
    '@vue/prettier/@typescript-eslint'
  ],
  rules: {
    '@typescript-eslint/no-unused-vars': 'error',
    '@typescript-eslint/explicit-function-return-type': 'warn',
    'vue/component-name-in-template-casing': ['error', 'kebab-case'],
    'vue/no-unused-components': 'error'
  }
}

5.1.2 代码审查流程

  1. 开发者提交Pull Request
  2. 自动化检查ESLint、TypeScript、构建
  3. 同行代码审查
  4. 技术负责人审查
  5. 合并到主分支

5.2 测试策略

5.2.1 单元测试

// tests/components/Button.spec.ts
import { mount } from '@vue/test-utils'
import Button from '@/components/common/Button/Button.vue'

describe('Button Component', () => {
  it('renders correctly', () => {
    const wrapper = mount(Button, {
      props: {
        text: 'Click me',
        type: 'primary'
      }
    })
    
    expect(wrapper.text()).toBe('Click me')
    expect(wrapper.classes()).toContain('button--primary')
  })

  it('emits click event', async () => {
    const wrapper = mount(Button)
    await wrapper.trigger('click')
    
    expect(wrapper.emitted('click')).toBeTruthy()
  })
})

5.2.2 端到端测试

// tests/e2e/login.spec.ts
describe('Login Flow', () => {
  it('should login successfully', () => {
    // 模拟微信登录流程
    cy.visit('/pages/login/login')
    cy.get('[data-testid="login-button"]').click()
    cy.url().should('include', '/pages/index/index')
  })
})

5.3 性能要求

5.3.1 页面性能指标

  • 首屏加载时间<2s
  • 页面切换时间<500ms
  • 图片加载时间<1s
  • 接口响应时间<1s

5.3.2 包体积要求

  • 主包大小<2MB
  • 分包大小<2MB
  • 总包大小<20MB
  • 图片资源<5MB

6. 部署和发布

6.1 构建配置

6.1.1 生产环境构建

# 构建微信小程序
npm run build:mp-weixin

# 构建其他平台
npm run build:h5
npm run build:app

6.1.2 环境配置

// .env.production
VUE_APP_API_BASE_URL=https://api.jiebanke.com
VUE_APP_CDN_BASE_URL=https://cdn.jiebanke.com
VUE_APP_WECHAT_APP_ID=wx1234567890abcdef

6.2 发布流程

6.2.1 版本管理

// package.json
{
  "version": "1.0.0",
  "scripts": {
    "version:patch": "npm version patch",
    "version:minor": "npm version minor",
    "version:major": "npm version major"
  }
}

6.2.2 发布步骤

  1. 代码审查通过
  2. 构建生产版本
  3. 上传到微信开发者工具
  4. 提交审核
  5. 发布上线

6.3 监控和分析

6.3.1 性能监控

// utils/monitor.ts
export class PerformanceMonitor {
  static trackPageLoad(pageName: string) {
    const startTime = Date.now()
    
    return () => {
      const loadTime = Date.now() - startTime
      console.log(`Page ${pageName} loaded in ${loadTime}ms`)
      
      // 上报性能数据
      this.reportPerformance({
        page: pageName,
        loadTime,
        timestamp: Date.now()
      })
    }
  }

  static reportPerformance(data: any) {
    // 上报到监控平台
    uni.request({
      url: 'https://monitor.jiebanke.com/performance',
      method: 'POST',
      data
    })
  }
}

6.3.2 错误监控

// utils/error-handler.ts
export class ErrorHandler {
  static init() {
    // 全局错误处理
    uni.onError((error) => {
      console.error('Global error:', error)
      this.reportError({
        type: 'javascript',
        message: error.message,
        stack: error.stack,
        timestamp: Date.now()
      })
    })

    // 未处理的Promise错误
    uni.onUnhandledRejection((event) => {
      console.error('Unhandled promise rejection:', event.reason)
      this.reportError({
        type: 'promise',
        message: event.reason,
        timestamp: Date.now()
      })
    })
  }

  static reportError(error: any) {
    // 上报错误信息
    uni.request({
      url: 'https://monitor.jiebanke.com/error',
      method: 'POST',
      data: error
    })
  }
}

7. 风险管理

7.1 技术风险

7.1.1 兼容性风险

  • 风险:不同机型和微信版本兼容性问题
  • 应对充分测试、降级方案、polyfill
  • 监控:用户反馈、错误日志

7.1.2 性能风险

  • 风险:页面加载慢、卡顿
  • 应对:代码分包、图片优化、缓存策略
  • 监控:性能指标、用户体验数据

7.2 业务风险

7.2.1 审核风险

  • 风险:小程序审核不通过
  • 应对:遵循微信规范、提前沟通
  • 监控:审核状态、反馈信息

7.2.2 用户体验风险

  • 风险:用户流失、满意度下降
  • 应对:用户测试、快速迭代
  • 监控:用户行为、反馈数据

8. 总结

本开发文档详细规划了解班客小程序的开发计划,包括:

8.1 开发计划

  • 总工期48个工作日
  • 团队规模2-3名小程序开发工程师
  • 关键里程碑:基础框架、核心页面、功能完善、优化测试

8.2 技术架构

  • 开发框架uni-app + Vue 3 + TypeScript
  • 状态管理Pinia
  • UI组件uni-ui + 自定义组件
  • 构建工具Vite

8.3 质量保证

  • 代码规范ESLint + Prettier
  • 测试策略:单元测试 + 端到端测试
  • 性能优化:分包、懒加载、缓存
  • 监控体系:性能监控 + 错误监控

8.4 风险控制

  • 兼容性测试:多机型、多版本
  • 性能优化:加载速度、响应时间
  • 审核合规:遵循微信规范
  • 用户体验:持续优化、快速响应

通过严格按照本开发文档执行,可以确保小程序的高质量交付和良好的用户体验。