752 lines
16 KiB
Markdown
752 lines
16 KiB
Markdown
|
|
# 智慧畜牧业小程序矩阵 - 技术文档
|
|||
|
|
|
|||
|
|
## 📋 项目概述
|
|||
|
|
|
|||
|
|
智慧畜牧业小程序矩阵是基于 uni-app 框架开发的跨平台移动应用系统,包含5个专业化小程序应用,覆盖畜牧业全产业链的数字化管理需求。
|
|||
|
|
|
|||
|
|
### 🎯 项目目标
|
|||
|
|
|
|||
|
|
- 提供完整的畜牧业数字化解决方案
|
|||
|
|
- 实现跨平台一体化开发和部署
|
|||
|
|
- 建立标准化的开发规范和流程
|
|||
|
|
- 构建可扩展的技术架构体系
|
|||
|
|
|
|||
|
|
## 🏗️ 技术架构
|
|||
|
|
|
|||
|
|
### 核心技术栈
|
|||
|
|
|
|||
|
|
| 技术 | 版本 | 用途 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| uni-app | 3.x | 跨平台开发框架 |
|
|||
|
|
| Vue.js | 3.x | 前端框架 |
|
|||
|
|
| Pinia | 2.x | 状态管理 |
|
|||
|
|
| TypeScript | 4.x | 类型系统 |
|
|||
|
|
| SCSS | - | 样式预处理器 |
|
|||
|
|
| ESLint | 8.x | 代码检查 |
|
|||
|
|
| Prettier | 2.x | 代码格式化 |
|
|||
|
|
|
|||
|
|
### 架构设计
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
智慧畜牧业小程序矩阵
|
|||
|
|
├── 表现层 (Presentation Layer)
|
|||
|
|
│ ├── 养殖管理小程序
|
|||
|
|
│ ├── 牛只交易小程序
|
|||
|
|
│ ├── 牛肉商城小程序
|
|||
|
|
│ ├── 银行监管小程序
|
|||
|
|
│ └── 保险监管小程序
|
|||
|
|
├── 业务层 (Business Layer)
|
|||
|
|
│ ├── 用户管理
|
|||
|
|
│ ├── 养殖管理
|
|||
|
|
│ ├── 交易管理
|
|||
|
|
│ ├── 商城管理
|
|||
|
|
│ ├── 金融管理
|
|||
|
|
│ └── 保险管理
|
|||
|
|
├── 服务层 (Service Layer)
|
|||
|
|
│ ├── API服务
|
|||
|
|
│ ├── 认证服务
|
|||
|
|
│ ├── 支付服务
|
|||
|
|
│ ├── 消息服务
|
|||
|
|
│ └── 文件服务
|
|||
|
|
└── 数据层 (Data Layer)
|
|||
|
|
├── 用户数据
|
|||
|
|
├── 业务数据
|
|||
|
|
├── 交易数据
|
|||
|
|
└── 系统数据
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 📁 项目结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
mini_program/
|
|||
|
|
├── common/ # 公共资源
|
|||
|
|
│ ├── components/ # 通用组件
|
|||
|
|
│ │ ├── loading/ # 加载组件
|
|||
|
|
│ │ ├── empty/ # 空状态组件
|
|||
|
|
│ │ └── modal/ # 模态框组件
|
|||
|
|
│ ├── utils/ # 工具函数
|
|||
|
|
│ │ ├── request.js # 请求封装
|
|||
|
|
│ │ ├── storage.js # 存储工具
|
|||
|
|
│ │ ├── auth.js # 认证工具
|
|||
|
|
│ │ ├── validation.js # 验证工具
|
|||
|
|
│ │ ├── format.js # 格式化工具
|
|||
|
|
│ │ ├── permission.js # 权限管理
|
|||
|
|
│ │ └── uni-helper.js # uni-app工具
|
|||
|
|
│ ├── styles/ # 公共样式
|
|||
|
|
│ │ ├── variables.scss # 变量定义
|
|||
|
|
│ │ ├── mixins.scss # 混入函数
|
|||
|
|
│ │ └── base.scss # 基础样式
|
|||
|
|
│ ├── mixins/ # Vue混入
|
|||
|
|
│ │ └── page.js # 页面混入
|
|||
|
|
│ └── config/ # 配置文件
|
|||
|
|
│ └── index.js # 全局配置
|
|||
|
|
├── farming-manager/ # 养殖管理小程序
|
|||
|
|
│ ├── manifest.json # 应用配置
|
|||
|
|
│ ├── pages.json # 页面配置
|
|||
|
|
│ ├── App.vue # 应用入口
|
|||
|
|
│ └── pages/ # 页面文件
|
|||
|
|
├── cattle-trading/ # 牛只交易小程序
|
|||
|
|
├── beef-mall/ # 牛肉商城小程序
|
|||
|
|
├── bank-supervision/ # 银行监管小程序
|
|||
|
|
├── insurance-supervision/ # 保险监管小程序
|
|||
|
|
├── package.json # 项目配置
|
|||
|
|
├── vue.config.js # Vue配置
|
|||
|
|
├── .eslintrc.js # ESLint配置
|
|||
|
|
├── .prettierrc.js # Prettier配置
|
|||
|
|
├── .env.development # 开发环境配置
|
|||
|
|
├── .env.production # 生产环境配置
|
|||
|
|
└── README.md # 项目说明
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🔧 开发规范
|
|||
|
|
|
|||
|
|
### 代码规范
|
|||
|
|
|
|||
|
|
#### 1. 命名规范
|
|||
|
|
|
|||
|
|
- **文件命名**: 使用 kebab-case (短横线分隔)
|
|||
|
|
- **组件命名**: 使用 PascalCase (大驼峰)
|
|||
|
|
- **变量命名**: 使用 camelCase (小驼峰)
|
|||
|
|
- **常量命名**: 使用 UPPER_SNAKE_CASE (大写下划线)
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 文件命名
|
|||
|
|
user-profile.vue
|
|||
|
|
api-service.js
|
|||
|
|
|
|||
|
|
// 组件命名
|
|||
|
|
<UserProfile />
|
|||
|
|
<ApiService />
|
|||
|
|
|
|||
|
|
// 变量命名
|
|||
|
|
const userName = 'admin'
|
|||
|
|
const userProfile = {}
|
|||
|
|
|
|||
|
|
// 常量命名
|
|||
|
|
const API_BASE_URL = 'https://api.example.com'
|
|||
|
|
const MAX_RETRY_COUNT = 3
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2. Vue组件规范
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<template>
|
|||
|
|
<view class="component-name">
|
|||
|
|
<!-- 模板内容 -->
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
import { defineComponent, ref, reactive } from 'vue'
|
|||
|
|
|
|||
|
|
export default defineComponent({
|
|||
|
|
name: 'ComponentName',
|
|||
|
|
props: {
|
|||
|
|
// props定义
|
|||
|
|
},
|
|||
|
|
emits: ['event-name'],
|
|||
|
|
setup(props, { emit }) {
|
|||
|
|
// 响应式数据
|
|||
|
|
const state = reactive({
|
|||
|
|
// 状态数据
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// 方法定义
|
|||
|
|
const handleClick = () => {
|
|||
|
|
// 处理逻辑
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
state,
|
|||
|
|
handleClick
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="scss" scoped>
|
|||
|
|
.component-name {
|
|||
|
|
// 样式定义
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 3. API调用规范
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// api/user.js
|
|||
|
|
import request from '@/common/utils/request'
|
|||
|
|
|
|||
|
|
export const userApi = {
|
|||
|
|
// 获取用户信息
|
|||
|
|
getUserInfo: (id) => {
|
|||
|
|
return request.get(`/user/${id}`)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 更新用户信息
|
|||
|
|
updateUserInfo: (data) => {
|
|||
|
|
return request.put('/user/profile', data)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 删除用户
|
|||
|
|
deleteUser: (id) => {
|
|||
|
|
return request.delete(`/user/${id}`)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 样式规范
|
|||
|
|
|
|||
|
|
#### 1. SCSS变量使用
|
|||
|
|
|
|||
|
|
```scss
|
|||
|
|
// 使用全局变量
|
|||
|
|
.page-container {
|
|||
|
|
background-color: $background-color;
|
|||
|
|
padding: $spacing-medium;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 使用混入
|
|||
|
|
.card {
|
|||
|
|
@include card-style;
|
|||
|
|
@include flex-center;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2. 响应式设计
|
|||
|
|
|
|||
|
|
```scss
|
|||
|
|
.responsive-container {
|
|||
|
|
width: 100%;
|
|||
|
|
|
|||
|
|
// 小屏幕
|
|||
|
|
@media (max-width: 768px) {
|
|||
|
|
padding: $spacing-small;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 大屏幕
|
|||
|
|
@media (min-width: 769px) {
|
|||
|
|
padding: $spacing-large;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 状态管理规范
|
|||
|
|
|
|||
|
|
#### 1. Pinia Store结构
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// stores/user.js
|
|||
|
|
import { defineStore } from 'pinia'
|
|||
|
|
|
|||
|
|
export const useUserStore = defineStore('user', {
|
|||
|
|
state: () => ({
|
|||
|
|
userInfo: null,
|
|||
|
|
isLoggedIn: false,
|
|||
|
|
permissions: []
|
|||
|
|
}),
|
|||
|
|
|
|||
|
|
getters: {
|
|||
|
|
hasPermission: (state) => (permission) => {
|
|||
|
|
return state.permissions.includes(permission)
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
actions: {
|
|||
|
|
async login(credentials) {
|
|||
|
|
try {
|
|||
|
|
const response = await userApi.login(credentials)
|
|||
|
|
this.userInfo = response.data
|
|||
|
|
this.isLoggedIn = true
|
|||
|
|
return response
|
|||
|
|
} catch (error) {
|
|||
|
|
throw error
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
logout() {
|
|||
|
|
this.userInfo = null
|
|||
|
|
this.isLoggedIn = false
|
|||
|
|
this.permissions = []
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🚀 开发流程
|
|||
|
|
|
|||
|
|
### 1. 环境搭建
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 克隆项目
|
|||
|
|
git clone <repository-url>
|
|||
|
|
|
|||
|
|
# 进入项目目录
|
|||
|
|
cd xlxumu/mini_program
|
|||
|
|
|
|||
|
|
# 安装依赖
|
|||
|
|
npm install
|
|||
|
|
|
|||
|
|
# 启动开发服务器
|
|||
|
|
npm run dev:mp-weixin
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 开发流程
|
|||
|
|
|
|||
|
|
1. **需求分析**: 明确功能需求和技术要求
|
|||
|
|
2. **设计评审**: 进行UI设计和技术方案评审
|
|||
|
|
3. **功能开发**: 按照规范进行功能开发
|
|||
|
|
4. **代码审查**: 提交代码前进行代码审查
|
|||
|
|
5. **测试验证**: 进行功能测试和兼容性测试
|
|||
|
|
6. **部署发布**: 构建和部署到各个平台
|
|||
|
|
|
|||
|
|
### 3. Git工作流
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 创建功能分支
|
|||
|
|
git checkout -b feature/user-management
|
|||
|
|
|
|||
|
|
# 提交代码
|
|||
|
|
git add .
|
|||
|
|
git commit -m "feat: 添加用户管理功能"
|
|||
|
|
|
|||
|
|
# 推送分支
|
|||
|
|
git push origin feature/user-management
|
|||
|
|
|
|||
|
|
# 创建合并请求
|
|||
|
|
# 代码审查通过后合并到主分支
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 代码提交规范
|
|||
|
|
|
|||
|
|
使用 Conventional Commits 规范:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
<type>[optional scope]: <description>
|
|||
|
|
|
|||
|
|
[optional body]
|
|||
|
|
|
|||
|
|
[optional footer(s)]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
类型说明:
|
|||
|
|
- `feat`: 新功能
|
|||
|
|
- `fix`: 修复bug
|
|||
|
|
- `docs`: 文档更新
|
|||
|
|
- `style`: 代码格式调整
|
|||
|
|
- `refactor`: 代码重构
|
|||
|
|
- `test`: 测试相关
|
|||
|
|
- `chore`: 构建过程或辅助工具的变动
|
|||
|
|
|
|||
|
|
## 🧪 测试策略
|
|||
|
|
|
|||
|
|
### 1. 单元测试
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// tests/utils/format.test.js
|
|||
|
|
import { formatDate, formatCurrency } from '@/common/utils/format'
|
|||
|
|
|
|||
|
|
describe('Format Utils', () => {
|
|||
|
|
test('formatDate should format date correctly', () => {
|
|||
|
|
const date = new Date('2024-01-01')
|
|||
|
|
expect(formatDate(date)).toBe('2024-01-01')
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
test('formatCurrency should format currency correctly', () => {
|
|||
|
|
expect(formatCurrency(1234.56)).toBe('¥1,234.56')
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 组件测试
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// tests/components/UserProfile.test.js
|
|||
|
|
import { mount } from '@vue/test-utils'
|
|||
|
|
import UserProfile from '@/components/UserProfile.vue'
|
|||
|
|
|
|||
|
|
describe('UserProfile', () => {
|
|||
|
|
test('renders user information correctly', () => {
|
|||
|
|
const wrapper = mount(UserProfile, {
|
|||
|
|
props: {
|
|||
|
|
user: {
|
|||
|
|
name: 'Test User',
|
|||
|
|
email: 'test@example.com'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
expect(wrapper.text()).toContain('Test User')
|
|||
|
|
expect(wrapper.text()).toContain('test@example.com')
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. E2E测试
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// tests/e2e/login.spec.js
|
|||
|
|
describe('Login Flow', () => {
|
|||
|
|
it('should login successfully', () => {
|
|||
|
|
cy.visit('/login')
|
|||
|
|
cy.get('[data-cy=username]').type('admin')
|
|||
|
|
cy.get('[data-cy=password]').type('password')
|
|||
|
|
cy.get('[data-cy=login-btn]').click()
|
|||
|
|
cy.url().should('include', '/dashboard')
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 📦 构建部署
|
|||
|
|
|
|||
|
|
### 1. 构建命令
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 构建微信小程序
|
|||
|
|
npm run build:mp-weixin
|
|||
|
|
|
|||
|
|
# 构建支付宝小程序
|
|||
|
|
npm run build:mp-alipay
|
|||
|
|
|
|||
|
|
# 构建H5版本
|
|||
|
|
npm run build:h5
|
|||
|
|
|
|||
|
|
# 构建所有平台
|
|||
|
|
npm run build:all
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 部署脚本
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 部署到测试环境
|
|||
|
|
./scripts/deploy.sh mp-weixin testing
|
|||
|
|
|
|||
|
|
# 部署到生产环境
|
|||
|
|
./scripts/deploy.sh mp-weixin production
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. CI/CD配置
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
# .github/workflows/deploy.yml
|
|||
|
|
name: Deploy
|
|||
|
|
|
|||
|
|
on:
|
|||
|
|
push:
|
|||
|
|
branches: [main]
|
|||
|
|
|
|||
|
|
jobs:
|
|||
|
|
deploy:
|
|||
|
|
runs-on: ubuntu-latest
|
|||
|
|
steps:
|
|||
|
|
- uses: actions/checkout@v2
|
|||
|
|
- name: Setup Node.js
|
|||
|
|
uses: actions/setup-node@v2
|
|||
|
|
with:
|
|||
|
|
node-version: '16'
|
|||
|
|
- name: Install dependencies
|
|||
|
|
run: npm ci
|
|||
|
|
- name: Run tests
|
|||
|
|
run: npm test
|
|||
|
|
- name: Build
|
|||
|
|
run: npm run build:all
|
|||
|
|
- name: Deploy
|
|||
|
|
run: ./scripts/deploy.sh
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🔍 性能优化
|
|||
|
|
|
|||
|
|
### 1. 代码分割
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 路由懒加载
|
|||
|
|
const UserProfile = () => import('@/pages/user/profile')
|
|||
|
|
|
|||
|
|
// 组件懒加载
|
|||
|
|
const LazyComponent = defineAsyncComponent(() => import('@/components/Heavy'))
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 图片优化
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 图片压缩和格式转换
|
|||
|
|
const compressImage = (file, quality = 0.8) => {
|
|||
|
|
return new Promise((resolve) => {
|
|||
|
|
const canvas = document.createElement('canvas')
|
|||
|
|
const ctx = canvas.getContext('2d')
|
|||
|
|
const img = new Image()
|
|||
|
|
|
|||
|
|
img.onload = () => {
|
|||
|
|
canvas.width = img.width
|
|||
|
|
canvas.height = img.height
|
|||
|
|
ctx.drawImage(img, 0, 0)
|
|||
|
|
|
|||
|
|
canvas.toBlob(resolve, 'image/jpeg', quality)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
img.src = URL.createObjectURL(file)
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 缓存策略
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// HTTP缓存
|
|||
|
|
const request = axios.create({
|
|||
|
|
timeout: 10000,
|
|||
|
|
headers: {
|
|||
|
|
'Cache-Control': 'max-age=300'
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// 本地缓存
|
|||
|
|
const cache = {
|
|||
|
|
set(key, value, expire = 30 * 60 * 1000) {
|
|||
|
|
const data = {
|
|||
|
|
value,
|
|||
|
|
expire: Date.now() + expire
|
|||
|
|
}
|
|||
|
|
uni.setStorageSync(key, JSON.stringify(data))
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
get(key) {
|
|||
|
|
const data = uni.getStorageSync(key)
|
|||
|
|
if (!data) return null
|
|||
|
|
|
|||
|
|
const parsed = JSON.parse(data)
|
|||
|
|
if (Date.now() > parsed.expire) {
|
|||
|
|
uni.removeStorageSync(key)
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return parsed.value
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🛡️ 安全规范
|
|||
|
|
|
|||
|
|
### 1. 数据验证
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 输入验证
|
|||
|
|
const validateInput = (data, rules) => {
|
|||
|
|
const errors = {}
|
|||
|
|
|
|||
|
|
Object.keys(rules).forEach(field => {
|
|||
|
|
const rule = rules[field]
|
|||
|
|
const value = data[field]
|
|||
|
|
|
|||
|
|
if (rule.required && !value) {
|
|||
|
|
errors[field] = `${field} is required`
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (rule.pattern && !rule.pattern.test(value)) {
|
|||
|
|
errors[field] = `${field} format is invalid`
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
isValid: Object.keys(errors).length === 0,
|
|||
|
|
errors
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. XSS防护
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// HTML转义
|
|||
|
|
const escapeHtml = (text) => {
|
|||
|
|
const map = {
|
|||
|
|
'&': '&',
|
|||
|
|
'<': '<',
|
|||
|
|
'>': '>',
|
|||
|
|
'"': '"',
|
|||
|
|
"'": '''
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return text.replace(/[&<>"']/g, (m) => map[m])
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 敏感信息保护
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 敏感信息脱敏
|
|||
|
|
const maskSensitiveInfo = (info, type) => {
|
|||
|
|
switch (type) {
|
|||
|
|
case 'phone':
|
|||
|
|
return info.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
|
|||
|
|
case 'email':
|
|||
|
|
return info.replace(/(.{2}).*(@.*)/, '$1***$2')
|
|||
|
|
case 'idCard':
|
|||
|
|
return info.replace(/(\d{6})\d{8}(\d{4})/, '$1********$2')
|
|||
|
|
default:
|
|||
|
|
return info
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 📊 监控告警
|
|||
|
|
|
|||
|
|
### 1. 错误监控
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 全局错误处理
|
|||
|
|
const errorHandler = (error, instance, info) => {
|
|||
|
|
console.error('Global error:', error)
|
|||
|
|
|
|||
|
|
// 发送错误报告
|
|||
|
|
reportError({
|
|||
|
|
error: error.message,
|
|||
|
|
stack: error.stack,
|
|||
|
|
info,
|
|||
|
|
url: window.location.href,
|
|||
|
|
userAgent: navigator.userAgent,
|
|||
|
|
timestamp: new Date().toISOString()
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
app.config.errorHandler = errorHandler
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 性能监控
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 性能数据收集
|
|||
|
|
const performanceMonitor = {
|
|||
|
|
// 页面加载时间
|
|||
|
|
measurePageLoad() {
|
|||
|
|
const navigation = performance.getEntriesByType('navigation')[0]
|
|||
|
|
return {
|
|||
|
|
loadTime: navigation.loadEventEnd - navigation.fetchStart,
|
|||
|
|
domReady: navigation.domContentLoadedEventEnd - navigation.fetchStart,
|
|||
|
|
firstPaint: performance.getEntriesByName('first-paint')[0]?.startTime
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// API响应时间
|
|||
|
|
measureApiResponse(url, startTime) {
|
|||
|
|
const endTime = performance.now()
|
|||
|
|
const duration = endTime - startTime
|
|||
|
|
|
|||
|
|
// 记录API性能数据
|
|||
|
|
this.recordMetric('api_response_time', {
|
|||
|
|
url,
|
|||
|
|
duration,
|
|||
|
|
timestamp: Date.now()
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 📚 文档维护
|
|||
|
|
|
|||
|
|
### 1. API文档
|
|||
|
|
|
|||
|
|
使用 JSDoc 规范编写API文档:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
/**
|
|||
|
|
* 用户登录
|
|||
|
|
* @param {Object} credentials - 登录凭证
|
|||
|
|
* @param {string} credentials.username - 用户名
|
|||
|
|
* @param {string} credentials.password - 密码
|
|||
|
|
* @returns {Promise<Object>} 登录结果
|
|||
|
|
* @throws {Error} 登录失败时抛出错误
|
|||
|
|
*/
|
|||
|
|
const login = async (credentials) => {
|
|||
|
|
// 实现逻辑
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 组件文档
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<!--
|
|||
|
|
组件名称: UserProfile
|
|||
|
|
组件描述: 用户资料展示组件
|
|||
|
|
作者: 开发团队
|
|||
|
|
创建时间: 2024-01-01
|
|||
|
|
最后修改: 2024-01-15
|
|||
|
|
|
|||
|
|
Props:
|
|||
|
|
- user (Object): 用户信息对象
|
|||
|
|
- name (string): 用户姓名
|
|||
|
|
- email (string): 用户邮箱
|
|||
|
|
- avatar (string): 用户头像URL
|
|||
|
|
|
|||
|
|
Events:
|
|||
|
|
- update: 用户信息更新时触发
|
|||
|
|
- delete: 用户删除时触发
|
|||
|
|
|
|||
|
|
Slots:
|
|||
|
|
- default: 默认插槽,用于自定义内容
|
|||
|
|
- actions: 操作按钮插槽
|
|||
|
|
|
|||
|
|
示例:
|
|||
|
|
<UserProfile
|
|||
|
|
:user="userInfo"
|
|||
|
|
@update="handleUpdate"
|
|||
|
|
@delete="handleDelete"
|
|||
|
|
>
|
|||
|
|
<template #actions>
|
|||
|
|
<button>编辑</button>
|
|||
|
|
</template>
|
|||
|
|
</UserProfile>
|
|||
|
|
-->
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🔄 版本管理
|
|||
|
|
|
|||
|
|
### 1. 版本号规范
|
|||
|
|
|
|||
|
|
采用语义化版本控制 (Semantic Versioning):
|
|||
|
|
|
|||
|
|
- **主版本号**: 不兼容的API修改
|
|||
|
|
- **次版本号**: 向下兼容的功能性新增
|
|||
|
|
- **修订号**: 向下兼容的问题修正
|
|||
|
|
|
|||
|
|
### 2. 发布流程
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 更新版本号
|
|||
|
|
npm version patch # 修订版本
|
|||
|
|
npm version minor # 次版本
|
|||
|
|
npm version major # 主版本
|
|||
|
|
|
|||
|
|
# 生成变更日志
|
|||
|
|
npm run changelog
|
|||
|
|
|
|||
|
|
# 创建发布标签
|
|||
|
|
git tag -a v1.0.0 -m "Release version 1.0.0"
|
|||
|
|
|
|||
|
|
# 推送标签
|
|||
|
|
git push origin v1.0.0
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 📞 技术支持
|
|||
|
|
|
|||
|
|
### 联系方式
|
|||
|
|
|
|||
|
|
- **技术负责人**: 开发团队
|
|||
|
|
- **邮箱**: dev@xlxumu.com
|
|||
|
|
- **文档地址**: https://docs.xlxumu.com
|
|||
|
|
- **问题反馈**: https://github.com/xlxumu/issues
|
|||
|
|
|
|||
|
|
### 常见问题
|
|||
|
|
|
|||
|
|
1. **Q: 如何添加新的小程序应用?**
|
|||
|
|
A: 复制现有应用目录结构,修改配置文件,添加到构建脚本中。
|
|||
|
|
|
|||
|
|
2. **Q: 如何处理跨平台兼容性问题?**
|
|||
|
|
A: 使用条件编译和平台特定的API适配。
|
|||
|
|
|
|||
|
|
3. **Q: 如何优化小程序性能?**
|
|||
|
|
A: 采用代码分割、图片优化、缓存策略等方法。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
*本文档持续更新中,如有疑问请联系开发团队。*
|