# 小程序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 安装开发工具
```bash
# 安装HBuilderX或使用VSCode
# 下载微信开发者工具
```
#### 2.2.2 创建项目
```bash
# 使用uni-app CLI创建项目
npx @dcloudio/uvm@latest create jiebanke-miniprogram
cd jiebanke-miniprogram
```
#### 2.2.3 安装依赖
```bash
npm install
```
#### 2.2.4 配置开发环境
```bash
# 复制环境配置文件
cp .env.example .env.development
# 编辑配置文件
```
#### 2.2.5 启动开发服务器
```bash
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和Vite(4人时)
3. 设置ESLint和Prettier(2人时)
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-case,如`user-profile.vue`
- **组件命名**:使用PascalCase,如`UserProfile`
- **方法命名**:使用camelCase,如`getUserInfo`
- **常量命名**:使用UPPER_SNAKE_CASE,如`API_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组件规范
```vue
```
### 4.2 API调用规范
#### 4.2.1 服务层封装
```typescript
// 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 {
return http.post('/auth/wechat/login', params)
}
/**
* 获取用户信息
*/
static async getUserInfo(): Promise {
return http.get('/auth/me')
}
/**
* 更新用户信息
*/
static async updateUserInfo(data: Partial): Promise {
return http.put('/auth/profile', data)
}
}
```
#### 4.2.2 HTTP请求封装
```typescript
// 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(options: RequestOptions): Promise {
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(url: string, params?: any): Promise {
return this.request({ url, method: 'GET', data: params })
}
post(url: string, data?: any): Promise {
return this.request({ url, method: 'POST', data })
}
put(url: string, data?: any): Promise {
return this.request({ url, method: 'PUT', data })
}
delete(url: string): Promise {
return this.request({ url, method: 'DELETE' })
}
}
export const http = new HttpClient()
```
### 4.3 状态管理规范
#### 4.3.1 Store结构
```typescript
// 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变量定义
```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 通用样式类
```scss
// 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配置
```javascript
// .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 单元测试
```typescript
// 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 端到端测试
```typescript
// 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 生产环境构建
```bash
# 构建微信小程序
npm run build:mp-weixin
# 构建其他平台
npm run build:h5
npm run build:app
```
#### 6.1.2 环境配置
```typescript
// .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 版本管理
```json
// 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 性能监控
```typescript
// 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 错误监控
```typescript
// 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 风险控制
- **兼容性测试**:多机型、多版本
- **性能优化**:加载速度、响应时间
- **审核合规**:遵循微信规范
- **用户体验**:持续优化、快速响应
通过严格按照本开发文档执行,可以确保小程序的高质量交付和良好的用户体验。