refactor: 重构数据库配置为SQLite开发环境并移除冗余文档
This commit is contained in:
752
docs/development/小程序开发技术文档.md
Normal file
752
docs/development/小程序开发技术文档.md
Normal file
@@ -0,0 +1,752 @@
|
||||
# 智慧畜牧业小程序矩阵 - 技术文档
|
||||
|
||||
## 📋 项目概述
|
||||
|
||||
智慧畜牧业小程序矩阵是基于 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: 采用代码分割、图片优化、缓存策略等方法。
|
||||
|
||||
---
|
||||
|
||||
*本文档持续更新中,如有疑问请联系开发团队。*
|
||||
Reference in New Issue
Block a user