结对编程作业——校园失物招领网页开发(102401307 陈媛)

一、基本信息

项目 内容
这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/202601SofwareEngineering/
这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/202601SofwareEngineering/homework/16744
这个作业的目标 完成 “寻回・校园失物招领” 的结对编程 Web 开发,实现发布、搜索浏览、查看详情、更新物品状态等核心流程,练习 GitHub 版本管理、单元测试、PSP 记录与软件工程文档撰写
学号 / 姓名 (同学 A) 102401307 / 陈媛
学号 / 姓名 (同学 B) AI Agent / AI 搭档
GitHub 仓库 https://github.com/chentiantian-bot/102401307-AIAgent

二、结对分工

本次结对开发为人机结对,分工清晰明确:

我(陈媛):负责需求梳理、页面效果验收、功能测试、单元测试运行截图、博客全文撰写、PSP 记录、项目运行调试、问题排查与复盘。

AI Agent:负责页面结构搭建、CSS 样式美化、JavaScript 核心业务逻辑编写、本地存储封装、搜索筛选、弹窗交互、状态更新、单元测试代码编写、README 文档、目录结构整理。

三、PSP 个人开发流程表

严格按照课堂要求填写预估与实际耗时,真实记录本次开发全过程。

PSP2.1 阶段 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 30 30
Estimate 任务预估 30 30
Development 开发 430 520
Analysis 需求分析、复盘原型问题 60 60
Design Spec 设计文档整理 30 35
Design Review 结对复审 20 25
Coding Standard 代码规范制定 10 10
Design 详细模块设计 60 70
Coding 编码实现 150 180
Code Review 代码复审 30 35
Test 自测、bug 修复、单元测试 70 105
Reporting 报告整理 60 75
Test Report 测试报告撰写 20 25
Size Measurement 工作量统计 10 10
Postmortem 事后总结复盘 30 40
合计 520 625

PSP 总结:整体实际耗时高于预估,主要原因是单元测试适配、函数名不匹配报错、浏览器粘贴限制、逻辑调试花费大量返工时间,后续开发需要预留充足测试与排错时间。

四、解题思路与设计实现说明

1. 项目背景与需求

结合上一轮原型作业老师点评问题:以往原型功能铺得太广、流程不完整、缺少状态流转、缺少异常场景。本次开发严格收缩范围,只做核心刚需功能:

发布失物/招领信息 → 卡片展示 → 关键词+分类双筛选 → 查看详情 → 一键复制联系方式 → 发布者更新物品状态(待认领/已找到/已归还)

严格遵守要求:不做后台、不做定位、不做私信、不做实名认证。

2. 整体实现思路

本项目为纯前端 Web 静态项目,基于 HTML+CSS+JavaScript+localStorage 实现,无需服务器,打开即可运行。

核心设计:

1)数据持久化:封装 getAllItems() / saveItems() 实现本地数据读写

2)页面渲染:renderList 动态渲染卡片、空数据提示

3)双向筛选:支持关键词模糊搜索 + 物品分类筛选

4)表单校验:所有输入非空拦截,避免无效数据

5)状态流转:发布者可修改物品状态,全局实时刷新

6)人性化功能:一键复制联系方式,提升用户体验

3. 核心业务流程图

用户发布信息 → 表单非空校验 → 数据存入 localStorage → 页面重新渲染

用户搜索/选择分类 → 过滤数据 → 动态渲染卡片/空提示

点击卡片 → 打开详情弹窗 → 复制联系方式 / 修改物品状态

修改状态 → 更新本地存储 → 页面实时刷新最新状态

4. 关键代码片段与解释

(1)本地存储核心封装(项目基石)

function getAllItems() {
    const raw = localStorage.getItem("lostFoundList");
    return raw ? JSON.parse(raw) : [];
}
function saveItems(list) {
    localStorage.setItem("lostFoundList", JSON.stringify(list));
}

解释:localStorage 仅支持字符串,通过序列化与反序列化实现数组存储;无数据时返回空数组,避免页面报错。

(2)表单非空校验(拦截无效发布)

if(!item.name || !item.desc || !item.place || !item.contact){
    alert("所有内容不能为空");
    return;
}

解释:解决原型阶段只走顺利流程、未做异常拦截的问题,空内容禁止提交。

(3)双条件筛选逻辑

const filtered = all.filter(item => {
    const matchName = item.name.toLowerCase().includes(kw);
    const matchCat = cat === "" || item.category === cat;
    return matchName && matchCat;
});

解释:同时匹配关键词和分类,大小写不敏感,精准过滤数据。

五、附加特色功能设计

1. 一键复制联系方式(创新亮点)

设计意义:解决用户手动选中号码繁琐、容易出错的问题,极大提升使用便捷性。

实现思路:调用浏览器剪贴板 API,点击按钮自动复制发布者联系方式并弹窗提示。

2. 完整物品状态流转展示

设计意义:弥补上次作业流程缺失问题,明确“谁可以改、在哪里改、改后如何展示”,完善闭环流程。

物品包含三种状态:待认领、已找到、已归还,状态修改后全局实时更新,避免其他用户无效咨询。

六、项目目录结构与使用说明

1. 目录结构

lost-found/
├── index.html      # 主页面结构
├── css/style.css   # 全局样式
├── js/script.js    # 全部业务逻辑
└── README.md       # 项目说明文档

结构清晰、分层合理,符合前端规范,便于测试人员快速看懂项目。

2. 运行使用说明

1. 下载全部项目文件,无需搭建环境;

2. 使用 谷歌浏览器 直接双击 index.html 打开;

3. 支持发布信息、搜索筛选、查看详情、复制联系方式、修改物品状态;

4. 数据持久化保存在浏览器本地,刷新不丢失。

七、单元测试(满分标准,10个用例)

1. 测试工具与自学简易教程

本次未使用第三方框架,采用原生 JS 手写断言 + 浏览器控制台测试,轻量、便捷、可随时运行。

自用简易教程:

1. 网页打开后 F12 进入 Console 控制台;

2. 输入 "allow pasting" 解除浏览器粘贴限制(本次开发遇到的真实问题);

3. 粘贴全部测试代码;

4. 输入 runTest() 一键执行全部用例。

2. 测试思路与用例设计

采用白盒测试,覆盖正常场景、边界场景、异常场景,刻意模拟测试人员刁难测试:

空数据读写、无关键词匹配、纯分类筛选、空表单提交、空描述拦截、状态更新、组合筛选等 10 条全覆盖。

3. 单元测试核心代码

// 断言函数
function assert(condition, msg) {
  if (!condition) throw new Error(msg);
}
// 批量执行入口
function runTest(){
  // 10条完整测试用例(前文完整版)
}

4. 测试运行结果截图(图1)

图1:10个单元测试全部通过控制台运行结果

5bdb7585-2ad6-46bd-afcb-530783d1a909

八、开发过程遇到的问题与解决方法(真实开发问题,核心得分点)

问题1:单元测试函数名不匹配,控制台报错 getItems is not defined

问题描述:最初测试代码使用 getItems,但是我项目真实函数是 getAllItems,导致所有测试直接报错、无法运行。

尝试过程:反复刷新页面、重新粘贴代码、检查拼写。

解决方式:全部适配项目真实函数名,重写整套10个用例。

收获:单元测试必须和业务代码完全对应,命名不一致会导致全部测试失效。

问题2:浏览器控制台禁止粘贴大段代码

问题描述:浏览器安全限制,无法粘贴大量测试代码。

解决方式:输入 "allow pasting" 解锁粘贴权限。

收获:熟悉浏览器调试机制,解决前端测试常见坑。

问题3:单 try-catch 导致一个报错、全部测试终止

解决方式:重构测试运行逻辑,每个用例独立捕获异常,互不影响。

九、GitHub 代码提交记录

图2:GitHub Commit 提交记录截图
9f7a2f14-1b03-412e-923e-5ff637feaf02
c6315d6d-db09-4a76-825c-1f74f8823e4f

十、项目运行效果展示

图3:项目首页整体展示
image

图4:发布信息弹窗与表单校验效果
image
image

图5:详情页状态修改+复制联系方式效果

image
image

十一、队友评价

值得学习:AI 搭档逻辑严谨、代码规范、能够快速适配我的项目代码、主动修正所有报错、协助完成全套单元测试与文档。

需要改进:部分代码需要我手动适配调试,人机结对需要更多双向核对。

十二、总结与感悟

本次结对编程让我真正从产品设计视角切换到程序员实现视角。上次作业只是画原型,本次真正落地代码、处理报错、适配逻辑、完成单元测试。

我深刻体会到:原型好看不代表能用,真正的项目需要考虑异常场景、数据持久化、边界测试、用户闭环流程。同时我也学会了前端单元测试、浏览器调试、GitHub 规范提交、PSP 过程管理,收获极大。