软工-现场编程
现场编程:个人记账本系统 项目总结
| 项目 | 内容 |
|---|---|
| 作业所属课程 | [https://edu.cnblogs.com/campus/fzu/2026-01SoftwareEngineeringandSoftwareEngineeringPractice] |
| 作业要求 | [https://edu.cnblogs.com/campus/fzu/2026-01SoftwareEngineeringandSoftwareEngineeringPractice/homework/16781] |
| 作业的目标 | 在有限时间内,通过团队协作完成一个具备基础记账、多维度统计及图表展示的个人记账本系统,并熟练掌握 Git 分支协作与接口规范。 |
| 团队名称 | [outfit partner] |
| 团队成员 | [S1阿合加依娜尔-102402108]、[S2谢慧彬-102402114]、[S3王凯凤-052403108]、[S4吴佳仪-102402113]、[S5刘翠华-102402105]、[S6李青容-102402111]、[S7姜思源-102402110]、[S8陈薇薇-102402109]、[S9松格拉-102402112]、[S10王恩嘉-072401214]、[S11张润-102402115]、[S12赖彦然-102402106]、[S13林诗怡-052402111] |
一、 组员职责分工
| 编号 | 岗位/模块 | 交付物 | 具体职责 |
|---|---|---|---|
| S1 | 前端负责人 | index.html |
首页布局、页面框架、提供表单元素挂载点 |
| S2 | 记账表单 | form.js |
表单注入/绑定、必填与合法性校验、新增记录 |
| S3 | 账单列表 | records.js |
监听更新事件、账单渲染、删除记录 |
| S4 | 财务计算 | finance.js |
收入、支出、余额、多维度汇总计算 |
| S5 | 筛选查询 | filter.js |
日期、类别、收支类型、金额范围筛选 |
| S6 | 统计图表 | charts.js |
收支趋势、类别占比图表渲染 |
| S7 | 数据存储 | storage.js |
统一数据读写、增删改查接口、事件派发 |
| S8 | 数据导入导出 | export.js |
严格格式化 JSON/CSV 导出;安全导入及校验 |
| S9 | 测试负责人 | tests/ |
编写测试用例、测试数据保护机制 |
| S10 | UI 体验优化 | style.css |
统一配色、响应式布局与交互反馈 |
| S11 | GitHub 与文档 | README.md |
文档编写、接口规范整理、协作记录整理 |
| S12 | 演示与发布 | demo-data.js |
演示数据生成、版本发布管理 |
| S13 | 项目总负责人 | main 分支 |
架构设计、接口审查、代码合并与集成 |
二、 程序运行环境
- 操作系统:跨平台(Windows / macOS / Linux)。
- 浏览器要求:推荐使用最新版 Chrome、Edge 或 Firefox 浏览器(完美支持 ES6 语法与 HTML5 LocalStorage)。
- 项目依赖:纯前端原生实现,无需安装 Node.js 等构建工具或后端数据库。
- 启动方式:
- 克隆或下载仓库后,直接双击根目录下的
index.html即可运行体验。 - 若需运行自动化测试,请在根目录执行
python -m http.server 8000,并访问http://localhost:8000/tests/storage-test.html。
- 克隆或下载仓库后,直接双击根目录下的
三、 软件运行截图与视频
1. 核心业务界面
[系统运行界面]

功能展示说明:
- 顶部仪表盘:实时展示当月及累计的收支与结余,数据随记录变动动态重算。
- 左侧记账区:支持收/支切换,提供快捷金额标签与分类图标,交互流畅。
- 右侧数据可视化 (S6):利用第三方图表库实现了“收支对比柱状图”、“分类占比环形图”与“每日收支趋势折线图”。
- 底部高级查询与日历 (S5):支持收支类型、分类、日期区间、金额区间等多条件组合筛选;左侧更设计了直观的日历视图,方便用户按天核对账单。
演示视频:
“记一笔”-收入:

“记一笔”-支出:

通过日历查看每日收入/支出:

四、 关键代码与设计说明
1. 财务计算防精度丢失 (S4 - finance.js)
设计说明:金额计算统一转换为“整数分”,避免 JS 浮点数计算误差(如 0.1+0.2=0.30000000004)。
const toCents = (amount) => Math.round(amount * 100);
function totalsCents(records) {
let income = 0, expense = 0;
records.forEach(r => {
const cents = toCents(r.amount);
if (r.type === 'income') income += cents;
else expense += cents;
});
return { income, expense, balance: income - expense };
}
2. 数据存储与事件派发 (S7 - storage.js)
设计说明:底层存储修改后派发全局事件,实现模块解耦,各 UI 模块无需相互调用。
function saveRecords(records) {
try {
localStorage.setItem('ledger_records', JSON.stringify(records));
// 派发全局更新事件,通知 S3/S4/S5/S6 自动刷新视图
document.dispatchEvent(new CustomEvent('ledger:updated'));
return true;
} catch (e) {
return false;
}
}
五、 软件亮点设计
- 事件驱动架构解耦:摒弃传统的模块间直接调用,统一由 S7 监听数据变更并派发
ledger:updated事件。各视图模块独立监听,极大降低了 13 人协同开发时的代码耦合与冲突率。 - 多维度的组合筛选与日历视图:在基础过滤之上,额外实现了金额上下限、关键词模糊查询,并开发了定制化的月历组件,极大地提升了用户核对账目的体验。
- 严谨的边界测试与数据保护:S9 的测试面板覆盖了 20 项极端边界用例(如拒绝非法日期、负数金额),并引入了“前置备份、后置恢复”机制,确保测试安全。
六、 团队协作与事件复盘
事件一:接口数据契约不一致引发的重构
- 过程:开发中期,S2 提交的金额字段为字符串,导致 S4 在计算时发生字符串拼接。
- 解决:S11 紧急在 README 中冻结了《统一数据结构》,强制规定
amount必须为Number。全员重新按规范修改,避免了后续更大的联调灾难。
事件二:测试模块的“数据污染”危机
- 过程:S9 在测试时直接清空了 LocalStorage,导致本地真实账单丢失。
- 解决:组长在 Code Review 时直接驳回。要求 S9 改写测试逻辑,测试前备份原数据,并在
finally中恢复原数据。
事件三:分支合并与代码冲突演练
- 过程:13 人同时开发,多个 PR 同时提交时,出现了
index.html与style.css的代码冲突。 - 解决:团队强制执行“主分支保护”策略,禁止直接向
main提交,所有改动必须在各自的feature分支完成后,发起 PR 由组长审查合并,有效解决了代码覆盖问题。
七、 每位组员的编程体验
S1(前端负责人):负责页面框架与模块挂载,让我深刻体会到了 DOM 结构规范的重要性。预留清晰的容器 ID,是保障 13 人并行开发时互不干扰的基础。
S2(记账表单):在实现表单校验时,处理各种非法输入(如负数、错误日期)锻炼了我的边界思维。这让我明白,严谨的前端校验是保障系统数据质量的第一道防线。
S3(账单列表):通过监听全局事件来渲染列表,让我直观地感受到了“数据驱动视图”的便利。避免了多个模块互相手动调用刷新函数,降低了代码的耦合度。
S4(财务计算):在开发财务汇总功能时,踩到了 JavaScript 浮点数精度丢失的坑。最终采用“整数分”进行底层计算,让我认识到在涉及金融数据的场景中,底层数据结构必须极其严谨。
S5(筛选查询):处理多条件组合筛选(日期、金额、类别等)让我熟练掌握了数组的高阶函数。如何用简洁的逻辑覆盖所有边界条件,是这次开发中最大的收获。
S6(统计图表):负责将原始数据转换成图表库所需的格式,让我体会到了数据可视化中“数据清洗与格式转换”的重要性。看着枯燥的数字变成直观的折线图,很有成就感。
S7(数据存储):作为底层数据枢纽,通过封装统一接口并引入事件派发(ledger:updated),我深入理解了“发布-订阅”模式对系统解耦的巨大作用。
S8(导入导出):在编写数据导入的安全校验逻辑时,我认识到异常处理的重要性。确保导入失败绝不覆盖原数据,是保障用户数据安全的核心底线。
S9(测试负责人):编写自动化测试用例并落实“前置备份、后置恢复”的数据保护机制,让我明白测试不仅要找出 Bug,更要保证测试过程本身的安全性。
S10(UI 体验优化):处理响应式布局和统一样式时,与其他模块的样式覆盖问题让我学到了 CSS 命名规范(如 BEM)的重要性。良好的 UI 体验需要克制和统一。
S11(GitHub 与文档):负责编写 README 与维护协作规范,让我深刻认识到“接口契约”在团队开发中的决定性作用。清晰的数据结构和分支规范,能大幅降低 13 人的沟通成本。
S12(演示与发布):准备演示数据和版本发布的过程,让我从“用户视角”重新审视了软件。一份真实、有逻辑的演示数据,是展示系统价值的关键。
S13(项目总负责人):作为统筹者,我体会到了接口审查与代码合并的挑战。通过强制推行主分支保护和 PR 流程,我们成功实现了多人并行开发且未发生严重的代码丢失
八、 PSP 时间统计
注:本次现场编程预估总时长为 4 小时(240 分钟)。但在实际操作中,由于 13 人并行开发的沟通成本、接口不一致导致的代码重构、合并冲突解决以及最终的文档沉淀,实际总耗时有所延长。
| 阶段 | 具体事项 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| 计划 | 整体规划与团队组建 | 15 | 15 |
| · 估计 | · 拆解需求、确定技术栈(纯前端+LocalStorage)、群内分工与建库 | 15 | 15 |
| 开发 | 核心研发与协同 | 165 | 220 |
| · 需求分析 | · 梳理业务闭环、确定核心数据结构(JSON 契约)与文件目录结构 | 15 | 15 |
| · 生成设计文档 | · 编写 README 基线、制定接口规范、设计事件驱动解耦方案 | 25 | 30 |
| · 设计复审 | · 组长与各模块负责人核对接口命名、确认防精度丢失方案(整数分计算) | 15 | 20 |
| · 代码规范 | · 制定 Git 分支策略(feature/develop)、强制 PR 流程与 Commit 规范 | 15 | 15 |
| · 具体设计 | · 设计 UI 布局(表单、日历、图表)、S9 测试用例设计与数据防污染机制 | 20 | 25 |
| · 具体编码 | · 各模块并行编码、S11 持续更新 README 文档与架构说明 | 45 | 55 |
| · 代码复审 | · 组长审查 PR、驳回违规提交;解决多分支合并冲突与测试污染隐患 | 20 | 40 |
| · 测试 | · 在本地跑通 Storage 自动化测试用例、S11 协同验证主流程闭环 | 10 | 20 |
| 报告 | 总结与交付 | 60 | 75 |
| · 测试报告 | · 汇总 Bug 记录、整理 20 项自动化测试结果与缺陷追踪 | 10 | 15 |
| · 计算工作量 | · 统计 GitHub 各成员 Commit 记录、PR 贡献度及代码量 | 10 | 10 |
| · 事后总结 | · 复盘研发过程中的接口冲突事件、录制 GIF 动图、撰写与排版博客 | 40 | 50 |
| 合计 | 240 | 310 |
九、成员贡献

十、 GitHub 仓库与commit记录
- GitHub 仓库地址:[https://github.com/Annabelle-Lin/personal-ledger]
- commit 截图:[
![f5714ac32c7f8cf96e70ff621d3f1f04_720]()
]

浙公网安备 33010602011771号