作业所属课程 | https://edu.cnblogs.com/campus/fzu/SE2024 |
---|---|
作业要求 | https://edu.cnblogs.com/campus/fzu/SE2024/homework/13302 |
作业的目标 | 在三个小时内编写出一个个人记账本,用户可以对自己平时的收入和支出情况进行简单的记录,查看和统计 |
团队名称 | “研途无忧” |
团队成员学号-名字 | 102202101-马鑫、102202141-黄昕怡、102202123-张铭心、102202112-刘莹、102202145-谢含、102202115-孙佳会、102202106-王强、102201317-陈磊、102201439-谢芳菲 |
一、队员的职责分工
马鑫、王强:负责博客的撰写与协助程序优化
黄昕怡:程序框架的搭建,细分队员的各个工作板块
张铭心:界面设计
孙佳会:bug检查与修复
刘莹、谢含:部分功能开发、界面美化
陈磊、谢芳菲:程序测试与界面美化
二、程序运行环境使用
用JavaScript进行编程,WXML(微信标记语言)和WXSS(微信样式表)来构建界面
使用云函数、云数据库等服务,用于后端开发和数据管理
三、软件运行截图和视频
1.登陆我们的小程序,引入眼帘的就是非常可爱的个人页面
2.如果你有更喜欢的背景图片也可以选择更换
3.接下来的是我们的添加支出界面,这个界面有多种类型供你选择,可以清楚为自己的花销分类
4.选择我们的类别添加具体的消费(想去北京)
5.同时我们不止有记录支出的功能,还有记录收入的功能,这也是一个记账app必不可少的(相中彩票)
6.这是我们的记账详情界面,它可以查看不同年月的具体支出,同时会统计年月的总支出与总收入,非常实用
7.同时为了满足j人需求,我们还推出了计划功能,可以说是相当人性化
8.添加计划后马上在我的计划界面显示,完成每一个功能的实现,绝不画饼(想换手机了)
9.可以在添加账单时选择计划,同时在添加账单的时候也可实时增添计划
10.将每次选择计划的账单金额同步到对应计划里
11.同时我们也提供人性化服务更改账单
四.关键代码
1.基础记账:实现基础的记账功能,记录每笔支出或收入,包括:日期、金额、类别(如饮食、交通、工资等)、备注。
点击查看代码
saveBook(){//保存记账功能
let _this = this;
let data = this.data;
if(data.activeType == -1 || data.amt == 0){
return; // 如果未选择类型或金额为0,则不保存
}
let date = app.getDateInfo(this.data.selectDay); // 获取选择的日期信息
let bookType = data.bookTypeList[data.activeType]; // 获取选中的账单类型
let params = {
amtType: data.activeTab, // 支出或收入类型
bookAmt:data.amt-0, // 账单金额
bookDate:date.date, // 账单日期
bookMonth:date.month, // 账单月份
bookYear:date.year, // 账单年份
week:date.week, // 账单星期
remark:data.remark, // 备注
bookTypeName: bookType.name, // 账单类型名称
bookTypeIcon: bookType.icon, // 账单类型图标
bookTypeId: bookType._id, // 账单类型ID
planId:data.planList[data.planIdx]._id // 计划ID
}
if (data.remark) {
let remarkArr = this.data.remarkArr;
if (remarkArr[bookType._id]){
if (remarkArr[bookType._id].indexOf(data.remark) == -1) {
remarkArr[bookType._id].push(data.remark); // 添加新的备注
this.setData({
remarkArr:remarkArr
});
_this.setStorage('remarks', remarkArr); // 更新缓存中的备注
}
}else{
remarkArr[bookType._id] = [data.remark];
this.setData({
remarkArr: remarkArr
});
_this.setStorage('remarks', remarkArr); // 更新缓存中的备注
}
}
if(this.data.bookId){
params.id = this.data.bookId;
app.getAjax({
url:'editBook', // 编辑账单
params:params,
success(res){
console.log("editBook:",res);
wx.navigateBack(); // 返回上一页
}
});
}else{
app.getAjax({
url:'addBook', // 添加账单
params:params,
success(res){
console.log("addBook:",res);
wx.navigateBack(); // 返回上一页
},
fail(res){
console.log("addBookFail:",res);
common.showModal('添加失败,请稍后重试!'); // 显示添加失败提示
}
});
}
}
2.查看数据:用户可以通过小程序查看最近的几笔记录。
点击查看代码
onShow: function () {
app.getAjax({
url:'login',
params:{},
success:res=>{
console.log('[云函数] [login] user openid: ', res.result.openid)
app.globalData.openid = res.result.openid // 获取用户的openid并存储到全局变量
}
})
let dateObj = app.getDateInfo(); // 获取当前日期信息
this.initData(dateObj.year, dateObj.month); // 初始化数据
},
initData(year, month) {//初始化数据
let _this = this;
app.getAjax({
url:'getUserBookList', // 获取用户账单列表
params:{
bookYear: year - 0, // 账单年份
bookMonth: month - 0 // 账单月份
},
success(res){
console.log("getUserBookList:", res);
let sortedBookList = _this.sortBookList(res.result.data); // 对账单列表进行排序和格式化
_this.setData({
bookList: sortedBookList.sortData, // 设置账单列表数据
incomeAmt: sortedBookList.incomeAmt, // 设置收入金额
payAmt: sortedBookList.payAmt, // 设置支出金额
selectYear: year, // 设置选中的年份
selectMonth: month // 设置选中的月份
});
console.log("bookList:", sortedBookList.sortData)
}
});
},
sortBookList(data) {//格式化账单列表
let dateArr = [],
sortData = [],
incomeAmt = 0,
payAmt = 0;
for(var key in data){
let index = dateArr.indexOf(data[key].bookDate);
let amtType = data[key].amtType;
if (index == -1){
dateArr.push(data[key].bookDate);
sortData.push({
date: data[key].bookDate,
week: ['日', '一', '二', '三', '四', '五', '六'][data[key].week], // 将星期数转换为中文
incomeAmt: amtType == '0' ? 0 : data[key].bookAmt, // 如果是收入,设置收入金额
payAmt: amtType == '0' ? data[key].bookAmt : 0, // 如果是支出,设置支出金额
list: [data[key]] // 初始化账单列表
});
} else {
if(amtType == 0){
sortData[index].payAmt = (sortData[index].payAmt * 100 + data[key].bookAmt * 100) / 100; // 累加支出金额
} else {
sortData[index].incomeAmt = (sortData[index].incomeAmt * 100 + data[key].bookAmt * 100) / 100; // 累加收入金额
}
sortData[index].list.push(data[key]); // 添加账单记录到列表
}
if(amtType == 0){
payAmt += data[key].bookAmt; // 累加总支出金额
} else {
incomeAmt += data[key].bookAmt; // 累加总收入金额
}
}
return {
sortData: sortData, // 返回格式化后的账单列表
incomeAmt: parseInt(incomeAmt * 100) / 100, // 返回总收入金额
payAmt: parseInt(payAmt * 100) / 100 // 返回总支出金额
}
}
3.收支统计: 用户可以根据日期,类别,金额等查看总支出和收入情况。
点击查看代码
onLoad: function (options) {
if(options.id){
this.setData({
amtType:options.type, // 设置收支类型
id:options.id, // 设置类型ID
year:options.year, // 设置年份
beginMonth:options.mon1, // 设置开始月份
endMonth:options.mon2 // 设置结束月份
});
this.getChartDetail(); // 获取统计详情
}else{
let month = new Date().getMonth() + 1;
let year = new Date().getFullYear();
this.setData({
year:year, // 设置当前年份
beginMonth:month, // 设置当前月份
endMonth:month, // 设置当前月份
monthArr:this.data.monthArr.slice(12-month), // 设置月份数组
dateTypeIdx:0 // 设置日期类型索引
});
this.initData(); // 初始化数据
}
},
initData(){
let _this = this;
let data = this.data;
this.setData({
chartList:[] // 清空统计列表
});
app.getAjax({
url:'getChartData', // 获取统计数据
params:{
amtType:data.amtType, // 收支类型
year: data.year-0, // 年份
beginMonth: data.beginMonth, // 开始月份
endMonth:data.endMonth // 结束月份
},
success(res){
console.log("getChartData:",res);
let data = res.result.list;
let count = 0;
for(var key in data){
data[key].count = parseInt(data[key].count*100)/100; // 格式化金额
count += data[key].count; // 计算总金额
}
_this.setData({
chartList:data, // 设置统计列表
chartListCount:count // 设置总金额
});
}
});
},
getChartDetail(){
let _this = this;
let data = this.data;
app.getAjax({
url:'getChartDetailData', // 获取统计详情数据
params:{
id:data.id, // 类型ID
year:data.year, // 年份
beginMonth:data.beginMonth, // 开始月份
endMonth:data.endMonth // 结束月份
},
success(res){
console.log("getChartDetailData:",res);
let data = res.result.data;
let count = 0;
for(var key in data){
count += data[key].bookAmt; // 计算总金额
}
_this.setData({
chartList: data, // 设置统计详情列表
chartListCount: count // 设置总金额
});
}
});
}
4.花销管理计划:用户可以根据消费意愿设置计划,查看计划。
设置计划:
点击查看代码
onLoad: function (options) {
if(options.pid){
this.setData({
planId:options.pid, // 设置计划ID
plan:app.globalData.plan // 设置全局计划数据
});
this.initData(); // 初始化数据
}
},
initData(){
let _this = this;
app.getAjax({
url:'getPlanBookList', // 获取计划账单列表
params:{
planId:_this.data.planId // 传递计划ID参数
},
success(res){
console.log("getPlanBookList:",res);
_this.setData({
bookList:res.result.data // 设置账单列表数据
});
}
});
}
点击查看代码
onShow: function () {
this.getPlanList(); // 页面显示时获取计划列表
},
getPlanList(){//获取计划列表
let _this = this;
app.getAjax({
url: 'getPlanList', // 请求获取计划列表
params: {
type: _this.data.amtType // 传递收支类型参数
},
success(res) {
console.log("getPlanList:", res);
let planList = res.result;
for(var key in planList){
planList[key].diffAmt = planList[key].planAmt - planList[key].total; // 计算计划剩余金额
planList[key].showInfo = false; // 初始化计划详情显示状态
}
_this.setData({
planList: planList // 设置计划列表数据
});
}
});
},
setAmtType(e) {//选择收入支出类型
this.setData({
amtType: e.currentTarget.dataset.type // 设置收支类型
});
this.getPlanList(); // 重新获取计划列表
},
showPlanInfo(e){//显示计划进度
let idx = e.currentTarget.dataset.idx;
this.setData({
[`planList[${idx}].showInfo`]:!this.data.planList[idx].showInfo // 切换计划详情显示状态
});
},
toPlanDetail(e){//到计划详情页
let idx = e.currentTarget.dataset.idx;
let plan = this.data.planList[idx];
if(plan.total == 0){
return; // 如果计划总金额为0,则不跳转
}
app.globalData.plan = plan; // 设置全局计划数据
app.navigate(`/pages/planBookList/planBookList?pid=${plan._id}`); // 跳转到计划详情页
}
五.设计亮点
1. 计划管理功能
- 计划创建与管理:用户可以创建不同的消费计划,并根据计划进行消费管理。每个计划都有详细的金额记录和剩余金额显示,帮助用户更好地控制支出。
- 动态显示计划详情:通过 showPlanInfo 方法,用户可以动态展开或收起计划的详细信息,查看每个计划的进度和具体消费记录。
- 收支类型切换:用户可以通过 setAmtType 方法切换查看支出或收入的计划列表,方便用户分类管理不同类型的计划。
- 计划删除功能:通过 showDeleteBtn 和 deletePlanList 方法,用户可以方便地删除不需要的计划,保持计划列表的整洁。
- 计划详情跳转:通过 toPlanDetail 方法,用户可以跳转到具体计划的详情页面,查看该计划下的所有消费记录,帮助用户更详细地了解每个计划的执行情况。
2. 账单管理功能
- 账单记录与编辑:用户可以记录每一笔支出或收入,并可以随时编辑已记录的账单。
账单类型与备注管理:用户有多种图标进行选择账单类型,并添加备注。用户可以根据账单类型获取相应的备注提示,方便用户快速输入常用备注。 - 日期选择与金额输入:用户可以选择账单日期,并通过数字键盘输入金额。通过 bindDateChange 和 setAmt 方法,用户可以方便地选择日期和输入金额。
这些设计亮点使得计划管理功能更加实用和人性化,帮助用户更好地进行财务规划和管理。
六.过程与收获
1. 计划管理功能的设计与实现
- 事件描述: 在设计和实现计划管理功能时,团队花费了大量时间讨论如何让用户能够方便地创建、查看和管理消费计划。特别是在计划的创建和编辑界面设计上,如何让用户直观地输入和查看计划的详细信息,以及如何动态显示计划的进度和剩余金额。
- 收获:
学会了如何通过用户体验设计提升功能的易用性。
了解了如何在前端代码中动态更新和显示数据。
掌握了如何通过接口与后端进行数据交互,确保数据的实时性和准确性。
2. 收支统计功能的优化
- 事件描述: 在实现收支统计功能时,团队遇到了如何高效地统计和展示大量账单数据的问题。特别是在按日期范围和类型进行统计时,如何确保数据的准确性和展示的流畅性。
- 收获:
学会了如何通过算法优化数据的统计和排序,提高性能。
了解了如何通过图表和数据可视化技术,直观地展示统计结果。
掌握了如何通过用户交互设计,让用户能够方便地切换和查看不同的统计数据。
3. 数据同步与缓存机制的实现
- 事件描述: 在实现数据同步与缓存机制时,团队花费了大量时间讨论如何确保数据的实时性和一致性,特别是在网络不稳定或离线状态下,如何通过本地缓存机制保证用户数据的完整性和可用性。
- 收获:
学会了如何通过本地缓存技术(如微信小程序的 wx.setStorage 和 wx.getStorageSync)提升应用的性能和用户体验。
了解了如何通过数据同步机制,确保本地数据与服务器数据的一致性。
掌握了如何处理网络异常和数据同步失败的情况,确保用户数据的安全和完整。
4. 账单详情页面的设计与实现
- 事件描述: 在设计和实现账单详情页面时,团队花费了大量时间讨论如何让用户能够方便地查看和编辑账单的详细信息。特别是在账单类型、金额、备注等信息的展示和编辑上,如何确保界面的简洁和易用。
- 收获:
学会了如何通过组件化设计提升页面的可维护性和复用性。
了解了如何通过数据绑定和事件处理,实现账单详情的动态展示和编辑功能。
掌握了如何通过接口与后端进行数据交互,确保账单数据的实时更新和同步。
5.数据统计与图表展示
- 事件描述: 在实现数据统计与图表展示功能时,团队花费了大量时间讨论如何让用户能够直观地查看收支统计数据,并通过图表展示数据的变化趋势。特别是在处理大量数据的统计和图表绘制时,如何确保数据的准确性和展示的流畅性。
- 收获:
学会了如何通过数据统计算法优化数据的计算和处理,提高性能。
了解了如何通过图表库(如 ECharts)实现数据的可视化展示,提升用户体验。
掌握了如何通过用户交互设计,让用户能够方便地切换和查看不同的统计数据和图表。
七、每个组员的团队编程体验
姓名 | 贡献分 |
---|---|
马鑫 | 8% |
黄昕怡 | 24% |
王强 | 8% |
陈磊 | 8% |
谢芳菲 | 8% |
张铭心 | 11% |
孙佳会 | 11% |
谢含 | 11% |
刘莹 | 11% |
- 马鑫:在此次随堂编程中,我体会到了速度与激情,在短短的三个小时内制作成了一个功能完整的记账小程序,从设计到编码的过程中再到最后的优化阶段,感受到团队前所未有的凝聚力。在初期,我并不熟悉微信开发小程序的使用,在编码中期我也遇到了许多困难,期间在队友的帮助下,我解决了一个又一个困难,最后我要感谢我们的团队,谢谢大家。
- 孙佳会:这次团队编程作业时间很紧急,只有三个小时,但是大家分工很明确很完善。每个人负责自己的部分,在写的过程中都非常迅速,最后整合给演示的同学,也在GitHub上上传了代码,我们团队最后的完成程度很不错,基础的功能都实现了。在这次团队作业中,我深刻体会到了团队合作的重要性,自己的代码速度以及与队友配合的能力都得到了很好的锻炼。
- 谢含:在这次现场编程中,通过快速开发记账小程序,我了解道每个成员之间熟悉的领域,大家集思广益快速分工,在有限的时间push出一个简单的成品,心酸苦楚只有自己知道,但也是这种有压力的感觉,激发出最大的潜力,我主要负责的是前端开发(美工),看见页面成果就会很开心呀呀呀,我爱软件工程(不要现场编程)。
- 刘莹:在本次记账小程序的团队编程过程中,大家刚开始共同商量小程序的风格并快速领取了自己要完成的代码部分,最后在fu姐的领导和明星姐的整合下完成了最后的展示,最终的效果还是非常令人满意的,很高兴和大家一起完成这次编程任务!
- 张铭心:和优秀的组员们一起,能在这么短的时间内开发出功能完备的记账小程序使我收获颇丰,关键是每个类型消费收入的统计我们也考虑在内,并且实现了可视化,这点更是让人欣喜。
非常有趣的小组编程,使我的大脑高速运转。ps:一起扣头也是有趣 标签:账单,res,软工,实践,2024,计划,let,key,data From: https://www.cnblogs.com/fufubufff/p/18522658