当前位置: 首页 > news >正文

微信小程序记账类MVP实战:从本地存储到云开发的架构演进

微信小程序记账类MVP实战:从本地存储到云开发的架构演进

本文记录「猪猪记账罐」小程序的架构选型与工程实践,供类似项目参考。


1. 背景与目标

项目背景

「猪猪记账罐」是一款面向个人用户的微信记账小程序。
以下是小程序的一些截图,供大家学习参考。

核心诉求

  • 覆盖记账全流程:记账→统计→预算→目标→导入导出
  • 不做过度复杂度,保持轻量
  • 保留从本地存储到云开发的演进空间

技术挑战

  • 微信小程序包体积限制
  • 离线可用与数据同步的平衡
  • 多人协作场景的权限控制

2. 技术栈概览

层级技术选型
框架微信小程序原生(WXML/WXSS/JS)
UI 组件TDesign 小程序组件(按需引入)
图表ECharts(小程序适配版)
数据层api/封装业务逻辑,utils/负责存储
同步策略本地存储 ↔ 云开发,可通过开关切换

3. 数据模型设计

核心实体

// 账单记录{id:string,// UUIDamount:number,// 金额(分为单位避免精度问题)type:'income'|'expense',category:string,// 分类IDcategoryName:string,// 分类名称(冗余存储便于展示)categoryIcon:string,// 分类图标account:string,// 账户IDaccountName:string,// 账户名称date:string,// YYYY-MM-DDnote:string,// 备注createdAt:number,// 创建时间戳updatedAt:number// 更新时间戳}// 分类{id:string,name:string,icon:string,type:'income'|'expense',order:number,isDefault:boolean}// 账户{id:string,name:string,type:'cash'|'wechat'|'alipay'|'bankcard'|'other',balance:number,order:number}// 预算{id:string,year:number,month:number,type:'total'|'category',categoryId:string|null,amount:number,alertThreshold:number// 提醒阈值(如0.8)}// 储蓄目标{id:string,name:string,targetAmount:number,currentAmount:number,deadline:string|null,createdAt:number}

索引设计

// 本地存储键设计constStorageKeys={RECORDS:'piggy_records',// 账单列表CATEGORIES:'piggy_categories',// 分类列表ACCOUNTS:'piggy_accounts',// 账户列表BUDGETS:'piggy_budgets',// 预算列表GOALS:'piggy_goals',// 储蓄目标SETTINGS:'piggy_settings',// 用户设置LAST_SYNC:'piggy_last_sync'// 最后同步时间};

4. 模块划分

按用户动线拆页面:

├── pages/index # 首页/快捷记账入口 ├── pages/record # 记一笔(完整版) ├── pages/flow # 流水列表 ├── pages/statistics # 统计图表 ├── pages/budget # 预算管理 ├── pages/goal # 储蓄目标 ├── pages/category # 分类管理 ├── pages/account # 账户管理 ├── pages/import # 导入导出 ├── pages/mine # 我的/设置 └── pages/family # 家庭账本(扩展)

分包策略

{"subPackages":[{"root":"pages/category","name":"category"},{"root":"pages/account","name":"account"},{"root":"pages/family","name":"family"}]}

非核心页面放入分包,控制主包体积。


5. 核心功能实现

5.1 记一笔流程

// 简化流程asyncfunctionaddRecord(data){// 1. 验证数据if(!data.amount||data.amount<=0){thrownewError('金额必须大于0');}// 2. 构建记录constrecord={id:generateUUID(),...data,createdAt:Date.now(),updatedAt:Date.now()};// 3. 保存到本地awaitsaveRecord(record);// 4. 更新账户余额awaitupdateAccountBalance(data.account,data.type,data.amount);// 5. 检查预算提醒awaitcheckBudgetAlert(record);returnrecord;}

5.2 预算提醒

asyncfunctioncheckBudgetAlert(record){if(record.type!=='expense')return;// 获取本月该分类支出constmonthTotal=awaitgetMonthCategoryTotal(record.category,record.date);// 获取预算constbudget=awaitgetBudget(record.category,record.date);if(!budget)return;// 检查是否超过阈值constused=monthTotal/budget.amount;if(used>=budget.alertThreshold){constpercent=Math.round(used*100);wx.showToast({title:`预算${percent}%已用完`,icon:'warning'});}}

5.3 统计计算

asyncfunctiongetMonthStatistics(year,month){constrecords=awaitgetRecordsByMonth(year,month);// 按分类聚合constbyCategory={};lettotalExpense=0;lettotalIncome=0;records.forEach(r=>{if(r.type==='expense'){totalExpense+=r.amount;byCategory[r.categoryName]=(byCategory[r.categoryName]||0)+r.amount;}else{totalIncome+=r.amount;}});// 计算百分比constcategoryStats=Object.entries(byCategory).map(([name,amount])=>({name,amount,percent:Math.round((amount/totalExpense)*100)})).sort((a,b)=>b.amount-a.amount);return{totalIncome,totalExpense,balance:totalIncome-totalExpense,byCategory:categoryStats};}

6. CSV 导入导出

6.1 导入流程

asyncfunctionimportFromCSV(filePath){// 1. 选择文件const[{path}]=awaitwx.chooseMessageFile({count:1});// 2. 读取文件constresult=awaitwx.getFileSystemManager().readFile({filePath:path,encoding:'utf-8'});// 3. 解析CSVconstlines=result.data.split('\n');constheaders=parseCSVLine(lines[0]);// 4. 字段映射(支付宝/微信格式对齐)constmapping={'交易时间':'date','交易对方':'note','金额':'amount','收/支':'type'};// 5. 逐行解析并导入constrecords=[];for(leti=1;i<lines.length;i++){constvalues=parseCSVLine(lines[i]);constrecord=mapToRecord(values,headers,mapping);if(record)records.push(record);}// 6. 去重检查constexisting=awaitgetAllRecords();constnewRecords=records.filter(r=>!isDuplicate(r,existing));// 7. 批量保存awaitsaveRecords(newRecords);return{total:records.length,imported:newRecords.length};}

6.2 导出功能

functionexportToCSV(records){constheaders=['日期','类型','分类','账户','金额','备注'];constrows=records.map(r=>[r.date,r.type==='income'?'收入':'支出',r.categoryName,r.accountName,(r.amount/100).toFixed(2),r.note]);constcsv=[headers,...rows].map(row=>row.join(',')).join('\n');wx.getFileSystemManager().writeFile({filePath:`${wx.env.USER_DATA_PATH}/export.csv`,data:csv,success:()=>{wx.showModal({title:'导出成功',content:'文件已保存,是否打开?',success:(res)=>{if(res.confirm){wx.openDocument({filePath:`${wx.env.USER_DATA_PATH}/export.csv`});}}});}});}

7. 性能优化

按需加载图表

// 统计页使用条件加载onLoad(){if(needChart){import('../../lib/echarts'asec).then(ec=>{this.initChart(ec);});}}

TDesign 按需引入

{"usingComponents":{"t-button":"tdesign-miniprogram/button/button","t-icon":"tdesign-miniprogram/icon/icon","t-navbar":"tdesign-miniprogram/navbar/navbar","t-dialog":"tdesign-miniprogram/dialog/dialog","t-toast":"tdesign-miniprogram/toast/toast"}}

安全区处理

<!-- 自定义导航栏 --><viewclass="custom-nav"style="padding-top:{{statusBarHeight}}px"><t-navbartitle="猪猪记账罐"/></view>

8. 云开发演进思路

本地优先

MVP 阶段优先本地存储,保证离线可用。

云函数设计

// 云函数:添加记录asyncfunctionaddRecord(event){const{OPENID}=wx.cloud.getUserInfo();constdb=wx.cloud.database();returnawaitdb.collection('records').add({data:{openid:OPENID,...event.data,createdAt:db.serverDate()}});}

数据同步策略

  • 写入:先本地,再异步同步到云端
  • 读取:优先本地,失败则拉取云端
  • 冲突:按时间戳,以最新为准

9. 后续迭代方向

  • 强化统计可视化(更多图表类型)
  • 家庭账本协作能力
  • PDF 月报导出
  • 合规探索下的 AI 录入辅助
  • 预算智能推荐

10. 总结

「猪猪记账罐」是一个典型的微信小程序 MVP 项目:

  • 技术选型:小程序原生 + TDesign,平衡开发效率与体验
  • 架构设计:本地优先,云开发可演进
  • 性能优化:按需加载,控制包体积
  • 用户体验:路径短,功能实用,不做过度复杂

希望本文能为类似项目提供参考。

Tags:微信小程序云开发TDesignMVP前端开发记账应用JavaScript

http://www.cnnetsun.cn/news/1855309.html

相关文章:

  • AS5600与AS5048A磁编码器实战:从原理到电机控制应用
  • ## 015、AutoSAR CP实战:配置存储栈(NvM,Fee,Ea)
  • 科普大白话:CPU(中央处理器)
  • 云容笔谈·东方红颜影像生成系统数据库设计实战:使用MySQL管理生成任务与用户数据
  • HTU21D温湿度传感器驱动开发与I²C通信详解
  • Arduino I²C四段数码管驱动库:轻量、稳定、即用
  • PyMICAPS:气象工作者的终极Python可视化神器,让你的数据分析效率提升300%
  • 嵌入式开发必备:手把手教你用dtc工具编译dts到dtb(附常见错误排查)
  • 科研小白避坑指南:手把手教你搞定OOMMF微磁模拟软件安装(附TK环境配置)
  • Langchain .. 学习 --- LCEL和Runnable粗
  • 嵌入式按钮事件处理库:多类型去抖与状态机驱动设计
  • STM32驱动ST25R3911B实现多协议NFC开发指南
  • Faiss实战:从零构建Python向量检索系统
  • Kubernetes 故障排查实战手册:从 Pod 异常定位到生产级稳定性治理
  • 低代码平台能承载复杂业务吗?我用接口引擎验证了一下
  • SWDSerial:基于SWD通道的轻量级半主机串口输出方案
  • 5G NR物理层实战:从帧结构到TB块生成的完整链路解析
  • 保姆级教程:用STM32F407ZGT6的HAL库驱动火焰传感器,从CubeMX配置到代码调试(附完整工程)
  • Eigen嵌入式线性代数库:轻量级矩阵计算与实时系统实践
  • 电子电路中的“心脏”:电源都
  • 选型建议:基于职场新人的能力模型,深度分析一级与二级认证的匹配度
  • 深度学习优化利器:Adam自适应学习率算法解析与实践
  • 【仅开放给首批200家AI基建团队】:2024大模型CI/CD成熟度评估矩阵(含17项量化指标+自测工具包)
  • 记录一个使用AI开发企业官网的思路
  • Arduino风扇控制库FanController:4线/3线PC风扇闭环调速与RPM监测
  • 粉紫系超人气月兔铃仙啪
  • Triton + RISC-V居
  • 告别迷茫:手把手教你用Linux内核pci-epf-test快速验证PCIe Endpoint硬件
  • 微信搜一搜SEO实战攻略
  • 从一个地狱笑话看大模型的推理机制峙