微信小程序记账类MVP实战:从本地存储到云开发的架构演进
微信小程序记账类MVP实战从本地存储到云开发的架构演进本文记录「猪猪记账罐」小程序的架构选型与工程实践供类似项目参考。1. 背景与目标项目背景「猪猪记账罐」是一款面向个人用户的微信记账小程序。以下是小程序的一些截图供大家学习参考。核心诉求覆盖记账全流程记账→统计→预算→目标→导入导出不做过度复杂度保持轻量保留从本地存储到云开发的演进空间技术挑战微信小程序包体积限制离线可用与数据同步的平衡多人协作场景的权限控制2. 技术栈概览层级技术选型框架微信小程序原生WXML/WXSS/JSUI 组件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.amount0){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;// 获取本月该分类支出constmonthTotalawaitgetMonthCategoryTotal(record.category,record.date);// 获取预算constbudgetawaitgetBudget(record.category,record.date);if(!budget)return;// 检查是否超过阈值constusedmonthTotal/budget.amount;if(usedbudget.alertThreshold){constpercentMath.round(used*100);wx.showToast({title:预算${percent}%已用完,icon:warning});}}5.3 统计计算asyncfunctiongetMonthStatistics(year,month){constrecordsawaitgetRecordsByMonth(year,month);// 按分类聚合constbyCategory{};lettotalExpense0;lettotalIncome0;records.forEach(r{if(r.typeexpense){totalExpenser.amount;byCategory[r.categoryName](byCategory[r.categoryName]||0)r.amount;}else{totalIncomer.amount;}});// 计算百分比constcategoryStatsObject.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. 读取文件constresultawaitwx.getFileSystemManager().readFile({filePath:path,encoding:utf-8});// 3. 解析CSVconstlinesresult.data.split(\n);constheadersparseCSVLine(lines[0]);// 4. 字段映射支付宝/微信格式对齐constmapping{交易时间:date,交易对方:note,金额:amount,收/支:type};// 5. 逐行解析并导入constrecords[];for(leti1;ilines.length;i){constvaluesparseCSVLine(lines[i]);constrecordmapToRecord(values,headers,mapping);if(record)records.push(record);}// 6. 去重检查constexistingawaitgetAllRecords();constnewRecordsrecords.filter(r!isDuplicate(r,existing));// 7. 批量保存awaitsaveRecords(newRecords);return{total:records.length,imported:newRecords.length};}6.2 导出功能functionexportToCSV(records){constheaders[日期,类型,分类,账户,金额,备注];constrowsrecords.map(r[r.date,r.typeincome?收入:支出,r.categoryName,r.accountName,(r.amount/100).toFixed(2),r.note]);constcsv[headers,...rows].map(rowrow.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/echartsasec).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}}安全区处理!-- 自定义导航栏 --viewclasscustom-navstylepadding-top:{{statusBarHeight}}pxt-navbartitle猪猪记账罐//view8. 云开发演进思路本地优先MVP 阶段优先本地存储保证离线可用。云函数设计// 云函数添加记录asyncfunctionaddRecord(event){const{OPENID}wx.cloud.getUserInfo();constdbwx.cloud.database();returnawaitdb.collection(records).add({data:{openid:OPENID,...event.data,createdAt:db.serverDate()}});}数据同步策略写入先本地再异步同步到云端读取优先本地失败则拉取云端冲突按时间戳以最新为准9. 后续迭代方向强化统计可视化更多图表类型家庭账本协作能力PDF 月报导出合规探索下的 AI 录入辅助预算智能推荐10. 总结「猪猪记账罐」是一个典型的微信小程序 MVP 项目技术选型小程序原生 TDesign平衡开发效率与体验架构设计本地优先云开发可演进性能优化按需加载控制包体积用户体验路径短功能实用不做过度复杂希望本文能为类似项目提供参考。Tags:微信小程序云开发TDesignMVP前端开发记账应用JavaScript