Files
xlxumu/docs/architecture/小程序架构文档.md

19 KiB
Raw Blame History

小程序架构文档

版本历史

版本 日期 作者 变更说明
1.0 2024-01-20 前端团队 初始版本

1. 小程序架构概述

1.1 项目背景

本小程序是养殖管理平台的移动端应用,主要面向养殖户和经销商,提供养殖管理、交易管理、数据查看等核心功能。

1.2 架构目标

  • 用户体验:流畅的交互体验和快速的页面响应
  • 性能优化:小程序包体积控制和运行性能优化
  • 可维护性:清晰的代码结构和组件化开发
  • 扩展性:支持功能模块的快速扩展
  • 稳定性:异常处理和容错机制完善

1.3 技术栈

  • 开发框架:微信小程序原生开发
  • 开发语言TypeScript + JavaScript
  • UI框架WeUI + 自定义组件
  • 状态管理MobX + 本地存储
  • 网络请求wx.request + 请求封装
  • 图表组件ECharts for 微信小程序
  • 地图服务:腾讯地图 + 微信地图

2. 系统架构设计

2.1 整体架构

┌─────────────────────────────────────────────────────────────┐
│                      视图层 (View)                          │
│                   Pages + Components                        │
├─────────────────────────────────────────────────────────────┤
│                    逻辑层 (Logic)                           │
│                 Service + Store + Utils                     │
├─────────────────────────────────────────────────────────────┤
│                    数据层 (Data)                            │
│              API + Storage + Cache                          │
├─────────────────────────────────────────────────────────────┤
│                   微信小程序框架                             │
│                 WeChat Mini Program                         │
└─────────────────────────────────────────────────────────────┘

2.2 目录结构

mini-program/
├── pages/                    # 页面目录
│   ├── index/               # 首页
│   ├── farm/                # 养殖管理
│   ├── trade/               # 交易管理
│   ├── profile/             # 个人中心
│   └── ...
├── components/              # 组件目录
│   ├── common/              # 通用组件
│   ├── business/            # 业务组件
│   └── charts/              # 图表组件
├── services/                # 服务层
│   ├── api/                 # API接口
│   ├── auth/                # 认证服务
│   └── storage/             # 存储服务
├── stores/                  # 状态管理
│   ├── user.ts              # 用户状态
│   ├── farm.ts              # 养殖状态
│   └── trade.ts             # 交易状态
├── utils/                   # 工具函数
│   ├── request.ts           # 网络请求
│   ├── validator.ts         # 数据验证
│   └── formatter.ts         # 数据格式化
├── styles/                  # 样式文件
│   ├── common.wxss          # 通用样式
│   └── variables.wxss       # 样式变量
├── static/                  # 静态资源
│   ├── images/              # 图片资源
│   └── icons/               # 图标资源
├── app.ts                   # 应用入口
├── app.json                 # 应用配置
├── app.wxss                 # 全局样式
└── project.config.json      # 项目配置

3. 核心模块设计

3.1 用户认证模块

功能: 微信授权登录、用户信息管理、权限控制

核心组件:

  • 登录页面: 微信授权登录界面
  • 用户信息: 用户资料展示和编辑
  • 权限管理: 基于角色的功能权限控制

实现方案:

// 用户认证服务
class AuthService {
  // 微信登录
  async wxLogin(): Promise<LoginResult> {
    const { code } = await wx.login();
    const { userInfo } = await wx.getUserProfile({
      desc: '用于完善用户资料'
    });
    
    return this.apiLogin(code, userInfo);
  }
  
  // API登录
  async apiLogin(code: string, userInfo: any): Promise<LoginResult> {
    const response = await request.post('/auth/wx-login', {
      code,
      userInfo
    });
    
    if (response.success) {
      await this.setToken(response.data.token);
      await this.setUserInfo(response.data.user);
    }
    
    return response;
  }
}

3.2 养殖管理模块

功能: 养殖场管理、动物管理、数据统计

核心页面:

  • 养殖场列表: 展示用户的养殖场信息
  • 养殖场详情: 养殖场详细信息和管理功能
  • 动物管理: 动物档案、健康记录、生长数据
  • 数据统计: 养殖数据图表和分析报告

状态管理:

// 养殖状态管理
class FarmStore {
  @observable farms: Farm[] = [];
  @observable currentFarm: Farm | null = null;
  @observable animals: Animal[] = [];
  
  @action
  async loadFarms() {
    const response = await farmService.getFarms();
    if (response.success) {
      this.farms = response.data;
    }
  }
  
  @action
  async selectFarm(farmId: string) {
    const farm = this.farms.find(f => f.id === farmId);
    this.currentFarm = farm || null;
    
    if (farm) {
      await this.loadAnimals(farmId);
    }
  }
}

3.3 交易管理模块

功能: 订单管理、支付管理、物流跟踪

核心页面:

  • 商品列表: 展示可交易的商品信息
  • 订单管理: 订单创建、查看、状态跟踪
  • 支付页面: 微信支付集成
  • 物流跟踪: 订单物流信息查看

支付集成:

// 支付服务
class PaymentService {
  async wxPay(orderId: string): Promise<PaymentResult> {
    // 1. 获取支付参数
    const payParams = await this.getPayParams(orderId);
    
    // 2. 调起微信支付
    return new Promise((resolve, reject) => {
      wx.requestPayment({
        ...payParams,
        success: (res) => {
          resolve({ success: true, data: res });
        },
        fail: (err) => {
          reject({ success: false, error: err });
        }
      });
    });
  }
}

3.4 数据可视化模块

功能: 图表展示、数据分析、报表生成

图表组件:

  • 折线图: 展示趋势数据
  • 柱状图: 展示对比数据
  • 饼图: 展示占比数据
  • 仪表盘: 展示关键指标

ECharts集成:

// 图表组件
Component({
  properties: {
    chartData: Object,
    chartType: String
  },
  
  data: {
    ec: null
  },
  
  ready() {
    this.initChart();
  },
  
  methods: {
    initChart() {
      this.createSelectorQuery()
        .select('#chart')
        .fields({ node: true, size: true })
        .exec((res) => {
          const canvas = res[0].node;
          const ctx = canvas.getContext('2d');
          
          canvas.width = res[0].width * dpr;
          canvas.height = res[0].height * dpr;
          ctx.scale(dpr, dpr);
          
          echarts.setCanvasCreator(() => canvas);
          
          const chart = echarts.init(canvas, null, {
            width: res[0].width,
            height: res[0].height,
            devicePixelRatio: dpr
          });
          
          chart.setOption(this.getChartOption());
          this.setData({ ec: { chart } });
        });
    }
  }
});

4. 网络层设计

4.1 请求封装

// 网络请求封装
class RequestService {
  private baseURL = 'https://api.example.com';
  private timeout = 10000;
  
  async request(options: RequestOptions): Promise<ApiResponse> {
    const token = await storage.getToken();
    
    return new Promise((resolve, reject) => {
      wx.request({
        url: `${this.baseURL}${options.url}`,
        method: options.method || 'GET',
        data: options.data,
        header: {
          'Content-Type': 'application/json',
          'Authorization': token ? `Bearer ${token}` : '',
          ...options.header
        },
        timeout: this.timeout,
        success: (res) => {
          if (res.statusCode === 200) {
            resolve(res.data);
          } else {
            this.handleError(res);
            reject(res);
          }
        },
        fail: (err) => {
          this.handleError(err);
          reject(err);
        }
      });
    });
  }
  
  private handleError(error: any) {
    console.error('Request error:', error);
    
    // 统一错误处理
    if (error.statusCode === 401) {
      // Token过期跳转登录
      this.redirectToLogin();
    } else if (error.statusCode >= 500) {
      // 服务器错误
      wx.showToast({
        title: '服务器错误,请稍后重试',
        icon: 'none'
      });
    }
  }
}

4.2 API接口管理

// API接口定义
class ApiService {
  // 用户相关接口
  user = {
    login: (data: LoginData) => request.post('/auth/login', data),
    profile: () => request.get('/user/profile'),
    updateProfile: (data: UserProfile) => request.put('/user/profile', data)
  };
  
  // 养殖相关接口
  farm = {
    list: (params: FarmListParams) => request.get('/farms', params),
    detail: (id: string) => request.get(`/farms/${id}`),
    create: (data: FarmData) => request.post('/farms', data),
    update: (id: string, data: FarmData) => request.put(`/farms/${id}`, data)
  };
  
  // 交易相关接口
  trade = {
    orders: (params: OrderListParams) => request.get('/orders', params),
    createOrder: (data: OrderData) => request.post('/orders', data),
    payOrder: (orderId: string) => request.post(`/orders/${orderId}/pay`)
  };
}

5. 数据存储设计

5.1 本地存储策略

// 存储服务
class StorageService {
  // 同步存储
  setSync(key: string, value: any): void {
    try {
      wx.setStorageSync(key, JSON.stringify(value));
    } catch (error) {
      console.error('Storage set error:', error);
    }
  }
  
  getSync(key: string): any {
    try {
      const value = wx.getStorageSync(key);
      return value ? JSON.parse(value) : null;
    } catch (error) {
      console.error('Storage get error:', error);
      return null;
    }
  }
  
  // 异步存储
  async set(key: string, value: any): Promise<void> {
    return new Promise((resolve, reject) => {
      wx.setStorage({
        key,
        data: JSON.stringify(value),
        success: resolve,
        fail: reject
      });
    });
  }
  
  async get(key: string): Promise<any> {
    return new Promise((resolve, reject) => {
      wx.getStorage({
        key,
        success: (res) => {
          try {
            resolve(JSON.parse(res.data));
          } catch (error) {
            resolve(res.data);
          }
        },
        fail: () => resolve(null)
      });
    });
  }
}

5.2 缓存管理

// 缓存管理
class CacheService {
  private cache = new Map<string, CacheItem>();
  private defaultTTL = 5 * 60 * 1000; // 5分钟
  
  set(key: string, value: any, ttl?: number): void {
    const expireTime = Date.now() + (ttl || this.defaultTTL);
    this.cache.set(key, {
      value,
      expireTime
    });
  }
  
  get(key: string): any {
    const item = this.cache.get(key);
    if (!item) return null;
    
    if (Date.now() > item.expireTime) {
      this.cache.delete(key);
      return null;
    }
    
    return item.value;
  }
  
  clear(): void {
    this.cache.clear();
  }
}

6. 组件化设计

6.1 通用组件

// 列表组件
Component({
  properties: {
    items: Array,
    loading: Boolean,
    hasMore: Boolean
  },
  
  data: {
    refreshing: false
  },
  
  methods: {
    onRefresh() {
      this.setData({ refreshing: true });
      this.triggerEvent('refresh');
    },
    
    onLoadMore() {
      if (!this.data.loading && this.data.hasMore) {
        this.triggerEvent('loadmore');
      }
    },
    
    onItemTap(e: any) {
      const { item, index } = e.currentTarget.dataset;
      this.triggerEvent('itemtap', { item, index });
    }
  }
});

6.2 业务组件

// 养殖场卡片组件
Component({
  properties: {
    farm: Object
  },
  
  methods: {
    onTap() {
      const { farm } = this.properties;
      wx.navigateTo({
        url: `/pages/farm/detail?id=${farm.id}`
      });
    },
    
    onEdit() {
      const { farm } = this.properties;
      this.triggerEvent('edit', { farm });
    }
  }
});

7. 性能优化

7.1 包体积优化

  • 代码分包: 使用小程序分包加载
  • 图片优化: 使用WebP格式压缩图片大小
  • 代码压缩: 启用代码压缩和混淆
  • 按需加载: 组件和页面按需加载

7.2 运行时优化

  • 数据预加载: 关键数据提前加载
  • 图片懒加载: 长列表图片懒加载
  • 防抖节流: 频繁操作防抖节流处理
  • 内存管理: 及时清理不用的数据和监听器

7.3 渲染优化

// 长列表优化
Component({
  data: {
    visibleItems: [],
    scrollTop: 0
  },
  
  methods: {
    onScroll(e: any) {
      const { scrollTop } = e.detail;
      this.updateVisibleItems(scrollTop);
    },
    
    updateVisibleItems(scrollTop: number) {
      const itemHeight = 100;
      const containerHeight = 600;
      const startIndex = Math.floor(scrollTop / itemHeight);
      const endIndex = startIndex + Math.ceil(containerHeight / itemHeight) + 1;
      
      const visibleItems = this.data.allItems.slice(startIndex, endIndex);
      this.setData({ visibleItems });
    }
  }
});

8. 错误处理

8.1 全局错误处理

// 应用级错误处理
App({
  onError(error: string) {
    console.error('App Error:', error);
    
    // 错误上报
    this.reportError(error);
    
    // 用户提示
    wx.showToast({
      title: '程序出现异常',
      icon: 'none'
    });
  },
  
  onUnhandledRejection(res: any) {
    console.error('Unhandled Promise Rejection:', res);
    this.reportError(res.reason);
  },
  
  reportError(error: any) {
    // 上报错误到服务器
    wx.request({
      url: 'https://api.example.com/errors',
      method: 'POST',
      data: {
        error: error.toString(),
        stack: error.stack,
        timestamp: Date.now(),
        userAgent: wx.getSystemInfoSync()
      }
    });
  }
});

8.2 页面级错误处理

// 页面错误处理
Page({
  data: {
    error: null,
    loading: false
  },
  
  async onLoad() {
    try {
      this.setData({ loading: true });
      await this.loadData();
    } catch (error) {
      this.handleError(error);
    } finally {
      this.setData({ loading: false });
    }
  },
  
  handleError(error: any) {
    console.error('Page Error:', error);
    
    this.setData({
      error: {
        message: error.message || '加载失败',
        code: error.code
      }
    });
  },
  
  onRetry() {
    this.setData({ error: null });
    this.onLoad();
  }
});

9. 安全设计

9.1 数据安全

  • 敏感数据加密: 本地存储敏感数据加密
  • 传输安全: HTTPS传输防止中间人攻击
  • 输入验证: 严格验证用户输入数据

9.2 权限控制

// 权限检查
class PermissionService {
  async checkPermission(permission: string): Promise<boolean> {
    const userInfo = await storage.get('userInfo');
    if (!userInfo || !userInfo.permissions) {
      return false;
    }
    
    return userInfo.permissions.includes(permission);
  }
  
  async requirePermission(permission: string): Promise<void> {
    const hasPermission = await this.checkPermission(permission);
    if (!hasPermission) {
      throw new Error('权限不足');
    }
  }
}

10. 测试策略

10.1 单元测试

// 工具函数测试
describe('Validator', () => {
  test('should validate phone number', () => {
    expect(validator.isPhone('13800138000')).toBe(true);
    expect(validator.isPhone('1380013800')).toBe(false);
  });
  
  test('should validate email', () => {
    expect(validator.isEmail('test@example.com')).toBe(true);
    expect(validator.isEmail('invalid-email')).toBe(false);
  });
});

10.2 集成测试

  • API测试: 测试与后端API的集成
  • 支付测试: 测试微信支付流程
  • 授权测试: 测试微信授权登录

10.3 用户体验测试

  • 真机测试: 在不同设备上测试
  • 网络测试: 测试不同网络环境下的表现
  • 性能测试: 测试页面加载和响应性能

11. 发布与运维

11.1 版本管理

  • 版本号规范: 遵循语义化版本号
  • 发布流程: 开发 → 测试 → 预发布 → 正式发布
  • 回滚机制: 支持快速回滚到上一版本

11.2 监控告警

  • 性能监控: 监控页面加载时间和API响应时间
  • 错误监控: 监控JavaScript错误和API错误
  • 用户行为: 统计用户使用行为和路径

11.3 数据统计

// 埋点统计
class AnalyticsService {
  track(event: string, properties?: any) {
    const data = {
      event,
      properties: {
        ...properties,
        timestamp: Date.now(),
        page: getCurrentPages().pop()?.route
      }
    };
    
    // 发送统计数据
    wx.request({
      url: 'https://analytics.example.com/track',
      method: 'POST',
      data
    });
  }
  
  trackPageView(page: string) {
    this.track('page_view', { page });
  }
  
  trackUserAction(action: string, target?: string) {
    this.track('user_action', { action, target });
  }
}

12. 扩展性设计

12.1 插件化架构

  • 功能模块: 支持功能模块的插拔
  • 主题系统: 支持多主题切换
  • 配置化: 支持功能开关配置

12.2 多端适配

  • 响应式设计: 适配不同屏幕尺寸
  • 平台兼容: 兼容不同版本的微信客户端
  • 设备适配: 适配不同性能的设备

13. 未来规划

13.1 技术升级

  • 框架升级: 考虑使用Taro等跨端框架
  • TypeScript: 全面使用TypeScript开发
  • 组件库: 构建统一的组件库

13.2 功能扩展

  • 离线功能: 支持离线数据查看
  • 实时通信: 集成WebSocket实时通信
  • AI功能: 集成AI智能分析功能