2026秋软件工程第二次结对作业——校园失物招领

项目 内容
这个作业属于哪个课程 软件工程
这个作业要求在哪里 软工第四次作业
这个这作业的目标 程序实现“校园失物招领小程序”
GitHub项目地址 https://github.com/lickchime/102402147-102402146
成员一 102402147郑宇嘉
成员二 102402146郑仕廷

一、具体分工

  • 102402147郑宇嘉:负责GitHub仓库的创建。负责首页信息列表、搜索页面、详情页的 UI 设计与前端逻辑;编写单元测试;README 文档撰写。
  • 102402146郑仕廷:负责fork郑宇嘉的仓库。负责发布信息页面(寻物/招领)、状态修改逻辑;数据持久化(localStorage)封装;APK 打包与真机测试。

二、PSP 表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20 30
Estimate 估计这个任务需要多少时间 10 15
Development 开发 210 300
Analysis 需求分析 (包括学习新技术) 30 45
Design Spec 生成设计文档 20 30
Design Review 设计复审 15 20
Coding Standard 代码规范 (为目前的开发制定合适的规范) 10 15
Design 具体设计 30 45
Coding 具体编码 120 180
Code Review 代码复审 20 30
Test 测试 (自我测试, 修改代码, 提交修改) 40 65
Reporting 报告 50 75
Test Report 测试报告 20 25
Size Measurement 计算工作量 10 10
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 30 45
合计 400 540

三、解题思路描述与设计实现说明

1. 代码实现思路

本次作业采用 移动端 Web APP(H5) 方案,使用 HTML5 + CSS3 + 原生 JavaScript 开发,通过 localStorage 实现数据持久化,最终使用 HBuilderX 打包成 APK 提交。功能严格控制在“发布—浏览/搜索—详情—联系—更新状态”这一闭环内,坚决不添加地图定位、即时聊天、实名认证等复杂模块。

关键设计:

  • 数据模型:{ id, type, name, place, contact, desc, status },其中 type 为寻物/招领,status 为进行中/已完成。
  • 数据流:所有页面共享一套数据层,通过 localStorage 读写。页面切换通过 JS 控制显示隐藏,详情页通过传入 id 获取指定数据。
  • 异常与空状态处理:发布时校验必填项;搜索无结果时展示“没有找到相关物品”提示,而不是白屏。

2. 关键实现的流程图

flowchart TD A[进入首页] --> B{选择操作} B -->|浏览| C[查看信息列表] C --> D[查看物品详情] D --> E[复制联系方式] D --> F[发布者标记已归还/已找到] B -->|发布| G[进入发布页面] G --> H[填写物品信息] H --> I{校验是否完整} I -->|不完整| J[提示补全] I -->|完整| K[保存并发布成功] B -->|搜索| L[输入关键词] L --> M[查看搜索结果] M --> D

3.关键代码片段

  • 搜索功能的实现(支持物品名称模糊搜索):
function goSearch() {
    const kw = document.getElementById('search-input').value.trim().toLowerCase();
    const results = items.filter(i => i.name.toLowerCase().includes(kw));
    document.getElementById('search-results').innerHTML = results.length ?
        results.map(item => `<div class="card" onclick="openDetail(${item.id})"><h4>${item.name}</h4><p> ${item.place}</p ></div>`).join('') :
        '<p style="text-align:center;color:#999;">没有找到相关物品</p >';
    showPage('page-search');
}
  • 状态更新逻辑(只有发布者可以修改,并同步到列表):
function updateStatus() {
    const item = items.find(i => i.id === currentDetailId);
    item.status = 'done';
    saveData();
    alert('状态已更新为已完成!');
    openDetail(currentDetailId); // 刷新详情页
}

四、附加特点设计与展示

1. 设计的创意独到之处及意义

特点一:一键复制联系方式
在详情页,如果用户想要联系发布者,通常需要手动记录微信号或手机号。我们设计了一个“复制联系方式”按钮,点击后直接将信息放入剪贴板,用户无需长按选中,可以直接去微信或QQ粘贴,极大地提升了便捷性。

特点二:空状态与搜索无结果友好提示
针对老师上次反馈的“不能只按一条顺利成功的路线设计产品”的问题,我们在搜索无结果、发布信息不完整的情况下均设置了友好的提示,避免用户面对白屏不知所措。这一改动虽然不大,但体现了对真实使用场景的思考。

2. 实现思路与关键代码

一键复制功能:利用现代浏览器的 Clipboard API。

function copyContact() {
    const item = items.find(i => i.id === currentDetailId);
    navigator.clipboard.writeText(item.contact).then(() => alert('联系方式已复制!'));
}

空状态处理:在渲染搜索结果时先判断数组长度。

const results = items.filter(i => i.name.toLowerCase().includes(kw));
document.getElementById('search-results').innerHTML = results.length ?
    results.map(...).join('') :
    '<p style="text-align:center;color:#999;">没有找到相关物品</p >';

3.实现成果展示

  • 首页
    8a020116e700c2a26df6f5283d86f16b
  • 发布页
    04bf237f486fb95fb8d08bd7436305c6
  • 详情页
    5b64b05d26a544bb4ba44f5ab8ce2ed7
    *搜索无结果
    140bcd057206657368ae457c8442e9b8

五、目录说明和使用说明

1. 目录结构说明

本项目采用 H5 目录结构,方便后续使用 HBuilderX 打包为 Android APP。项目目录组织如下:

  • index.html:主页面(包含首页、发布、搜索、详情四个视图)
  • test.html:单元测试页面
  • manifest.json:HBuilderX 打包配置文件
  • css/style.css:全局样式表
  • js/script.js:核心逻辑(数据层、页面切换、搜索、发布、状态更新)
  • README.md:项目说明文档

HTML 采用单页面多视图方式,切换时通过 JavaScript 控制显示隐藏;CSS 统一管理样式,实现移动端界面的清爽布局;JS 封装了 localStorage 数据层、搜索逻辑、发布逻辑和状态更新逻辑,职责分明。

2. 如何使用

(1)网页测试

  • 下载整个项目文件夹到本地
  • 双击打开 index.html
  • 使用谷歌浏览器(Chrome)打开,按 F12 切换到手机模式即可预览效果

(2)APP 测试

  • 直接下载安装我们提供的 .apk 文件
  • 在安卓手机上打开,即可看到“校园失物招领”应用
  • 推荐安卓 8.0 及以上系统

(3)操作流程

  1. 首页浏览信息,点击卡片查看详情
  2. 在详情页点击“复制联系方式”一键获取发布者联系方式
  3. 点击右下角“+ 发布”,选择寻物或招领并填写信息
  4. 在详情页点击“标记为已找到/已归还”,更新状态

六、单元测试

1. 选用的测试工具与学习教程

测试工具:我们选用了原生 JavaScript 断言,配合简易的 HTML 页面进行测试。因为项目没有复杂的第三方依赖,直接写一个 test.html 就能运行,学习成本极低,非常适合两人快速协作。

简易教程:

  1. 新建一个 test.html 文件,在 <script> 中引入核心逻辑
  2. 用条件判断或 console.assert 编写测试断言
  3. 在浏览器打开 test.html,查看页面上的 ✅ 和 ❌ 结果

2. 部分单元测试代码

results.push(["测试1: 搜索存在的物品 '校园卡'", searchItems('校园卡').length === 1 ? "✅ 通过" : "❌ 失败"]);
results.push(["测试2: 搜索不存在的物品 '钥匙'", searchItems('钥匙').length === 0 ? "✅ 通过" : "❌ 失败"]);
results.push(["测试3: 按类型筛选 '寻物'", items.filter(i => i.type === 'lost').length === 1 ? "✅ 通过" : "❌ 失败"]);
results.push(["测试4: 发布信息缺少必填项", addItem('雨伞', '') === false ? "✅ 通过" : "❌ 失败"]);
results.push(["测试5: 修改物品状态为已归还", updateStatus(1) && items[0].status === 'done' ? "✅ 通过" : "❌ 失败"]);

七、GitHub 签入记录截图

  • 队友提交
    image

  • 我修改提交
    image

八、遇到的代码模块异常或结对困难及解决方法

问题描述 1:页面样式失效与按钮无反应

做过哪些尝试:检查了 HTML 中的引入路径,发现 CSS 和 JS 文件被放在了子文件夹中(css/ 和 js/),但代码中直接写的是 style.css 和 script.js,导致文件 404 加载失败。

是否解决:已解决。将路径改为 css/style.css 和 js/script.js 后恢复正常,页面样式和按钮交互都能跑通。

有何收获:界面画出来和用户能够用起来是两回事。结对编程中,同学B在真机上测试时发现了这个问题,而我在电脑模拟器上一直没发现。这提醒我们要重视真机走查。

问题描述 2:云打包被通讯录权限拦截

做过哪些尝试:使用 HBuilderX 云打包时,提示“本次打包选择了通讯录权限,请登录开发者中心完成实名认证”。检查了 manifest.json 的权限配置,发现默认勾选了通讯录权限。因为是校园失物招领 APP,完全不需要读取通讯录。

是否解决:已解决。在 manifest.json 中取消了通讯录权限,并清空额外添加的权限,重新打包成功。

有何收获:打包不仅是技术操作,更需要对项目所需的权限有清晰的认知,遵循最小权限原则。同时,遇到报错要学会查官方文档,而不是盲目试错。

九、评价你的队友

郑宇嘉负责 GitHub 仓库搭建、首页 / 搜索 / 详情页面 UI 与前端逻辑、单元测试和项目文档撰写。他设计的移动端页面布局清爽,并且考虑了空状态等异常场景,同时编写单元测试验证核心功能,文档整理完整。开发过程中沟通积极,能够及时同步进度,配合我完成前后页面的数据联调,认真完成分配的全部任务,是很好的结对队友。

posted @ 2026-10-10 15:22  郑仕廷  阅读(5)  评论(0)    收藏  举报