2024秋软件工程结对作业(第二次)

软件工程 班级链接:https://edu.cnblogs.com/campus/fzu/SE2024
作业要求链接 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13281
作业目标 开发一套跨专业合作平台,为大学生提供发起和参与跨学科项目的渠道。
学号 102201313
Github项目地址 https://github.com/KeepUpIce/102201313-102201315
本作业博客地址 https://www.cnblogs.com/qiushuo/p/18436079
队友博客地址 https://www.cnblogs.com/Kkclt

项目背景+项目需求

在大学内,部分学生希望通过发起或参与跨专业的项目(如创业或学术研究)来提升个人综合能力、拓宽知识面并积累人脉。

然而,大学生在实现这些跨学科合作时面临诸多困扰,主要体现为:

1、跨学科合作的机会主要依赖于个人积累的有限人脉资源或通过导师的引荐,方式过于局限,导致许多潜在的合作机会未能实现。

2、不同专业的学生在课程安排、项目目标和沟通方式上存在显著差异,这增加了合作过程中的沟通与磨合成本,给跨学科合作带来了挑战。

3、目前,学校缺乏专门用于促进学生跨学科合作的工具或平台。现有的合作方式多依赖于群聊、校园公告墙等渠道,其效果有限,难以满足学生之间有效交流与合作的需求。

基于此,需开发一套跨专业合作平台,为大学生提供发起和参与跨学科项目的渠道。

该平台具备但不限于以下功能和特点:

1、系统支持不同角色用户的注册和认证。学生可以自主发起或加入项目,教师也可发起项目,并上传和分享相关资源。

2、用户可以在平台上发布需要多学科支持的项目并为其添加标签,用户可通过点击标签查看对应项目。

3、系统提供预定格式,用户需按格式填写表单内容,包括个人专业、课程安排、项目目标、个人能力、联系方式和招募需求等。申请者需提交相同的表单以申请参与项目。

4、平台需具备高频率使用场景,并确保操作简便。从使用频率、便捷性和合作有效性三方面出发,设计易用的界面和简化的操作流程,以提升用户体验。

5、平台内的项目合作应保持相对封闭,仅限已认证用户查看和参与,以防止项目核心内容外泄。

项目原型设计及设计理念具体参考:2024秋软件工程结对作业(第一次)

开发语言及环境

开发语言:PHP+MySQL+HTML+JS+CSS

开发环境:Apache2.4.39 / Nginx1.15.11、MySQL5.7.26

数据库构建

数据库:project_management,配置如下:

数据库中包含5张表:

1、users表,存储学号/工号、姓名、密码、专业、邮箱。

2、projects表,存储项目编号、发起者ID、项目名称、项目目标、课程安排、个人能力、招募需求、创建时间、项目标签。

3、applications表,存储项目编号、学号/工号、课程安排、个人能力、外键。

4、pending_users表,存储待审核用户ID、学号/工号、姓名、密码、专业、邮箱、身份证明照片、审核状态、创建时间。

5、admin表,存储管理员的用户名和密码。

项目结构

uploads文件夹包含用户上传的资源文件,user_images文件夹包含用户注册时上传的身份证件照片,其它为功能文件,实现前后端功能:

在这里插入图片描述

代码实现思路及设计实现说明

该应用程序分为用户窗口和管理员窗口。设计流程图如下:

以下为项目设计文字描述,界面 demo 于后文给出。

用户窗口包括:

1.用户注册界面 (register.php):实现用户注册功能,并提供跳转至登录界面的链接。

2.用户登录界面 (login.php):支持用户登录,并提供跳转至注册界面的功能。

3.项目大厅界面 (project_hall.php):显示所有项目,用户可以通过点击标签进行项目过滤。左侧提供标签栏,可导航至个人中心、资源中心等界面。

4.标签详情界面 (tag_detail.php):展示所有包含特定标签的项目。

5.项目详情界面 (project_detail.php):显示项目发起人信息、招募需求、项目目标等信息。申请人可以在此页面点击“点击此处申请此项目”来提交申请。

6.发起招募界面 (recruit.php):实现发起新项目的功能,供用户填写相关信息。

7.申请项目界面 (apply.php):提供申请项目的界面,用户可以在此提交申请

8.个人中心界面 (personal_center.php):展示用户的个人信息以及发起或申请的项目列表。

9.资源中心界面 (resource_center.php):显示已上传的资源,并支持资源的搜索功能。

管理员窗口包括:

1.管理员登录界面 (admin_login.php)**:仅供管理员登录的界面。

2.管理员审核界面 (admin.php)**:用于审核用户注册信息,确保用户的合规性。

项目介绍+项目展示

1、用户注册界面

demo如下所示:

用户需要填写学号/工号、姓名、密码、专业和邮箱,并上传身份证明照片(工作证/学生证)。提交后,系统会验证输入数据,确保所有字段均已填写且照片格式正确。

注册信息将被插入到pending_users数据库表中,用户在提交后会收到成功消息,提示其申请正在等待管理员审核。

身份证明照片将被存储至plateform\user_images,用于之后管理员审核时呈现到前端:

此外,界面提供了链接以便已注册用户登录,确保了注册和登录的顺畅体验。

2、用户登录界面

demo如下所示:

该界面实现用户登录功能。用户需输入学号/工号和密码进行身份验证。系统通过查询users数据库表确认输入的凭据是否有效。如果验证成功,用户将被重定向至project_hall.php页面;若失败,将显示错误消息,提示用户检查输入的学号/工号或密码。

界面还提供了链接,方便用户进行注册和联系管理员以解决密码问题(admin@plateform.com),确保了用户体验的完整性和流畅性。整体设计聚焦于简化登录流程,提高用户便捷性。

3、项目大厅界面

界面如下所示:

该页面实现项目大厅的功能。用户必须登录后才能访问,若未登录,将被重定向至注册页面。

功能包括:

1、分页显示项目:每页显示10个项目,支持前后翻页。

2、标签过滤:从数据库中获取并显示所有独特的项目标签,用户可通过标签查看相关项目。

3、项目列表展示:显示项目名称和链接,用户点击可查看项目详情。

4、用户导航:侧边栏提供快速访问链接到其他页面,如发起招募和个人中心。

项目细节:

为避免用户在项目存量较大时寻找项目浪费时间,将项目按时间顺序排列,最新的项目置于最上方。对应的SQL语句如下:

// 项目列表
$sql = "SELECT * FROM projects ORDER BY created_at DESC LIMIT $items_per_page OFFSET $offset";
$result = $conn->query($sql);

if ($result && $result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        echo "<p><a href='project_detail.php?id=" . $row['id'] . "'>" . $row['id'] . " - " . htmlspecialchars($row['name']) . "</a></p>";
    }
} else {
    echo "<p>没有项目可显示</p>";
}

ORDER BY created_at DESC确保了项目按照创建时间的降序排列,从而优先显示最新的项目。

4、标签详情界面

demo如下所示:

该页面实现了标签页面的功能,用户在选择标签后,可以查看与该标签相关的项目。用户必须登录后才能访问,若未登录,将被重定向至注册页面。

功能包括:

1、标签展示:页面标题显示当前选择的标签。

2、项目列表:根据用户选择的标签,从数据库中检索并显示相关项目,用户可以点击项目链接查看详情。

3、侧边栏导航:提供快捷链接到其他主要功能页面,如项目大厅和个人中心。

项目细节:

动态获取与特定标签相关的项目(使用%进行模糊查询),并按时间顺序呈现,便于用户查看最新的相关项目。对应的SQL语句如下:

// 根据标签获取相关项目
$sql = "SELECT * FROM projects WHERE tags LIKE '%" . $conn->real_escape_string($tag) . "%' ORDER BY created_at DESC";
$result = $conn->query($sql);

5、项目详情界面

界面如下所示:

该页面展示了特定项目的详细信息,包括发起人及申请人信息。用户必须登录后才能访问,若未登录,将被重定向至注册页面。

主要功能包括:

1、项目信息展示:显示项目名称、发起人姓名、专业、邮箱及项目目标等。

2、申请人信息:列出所有申请该项目的学生信息,如学号、姓名和专业等。

3、申请链接:提供申请该项目的链接,方便用户直接跳转。

项目细节:

若目前没有申请人,表示项目尚未吸引任何申请,同时界面输出提示。

代码如下:

if ($applications_result->num_rows > 0) {
    while ($application = $applications_result->fetch_assoc()) {
        // 显示申请人信息
    }
} else {
    echo "<p>目前没有申请人。</p>";
}

示例界面:

6、发起招募界面

demo如下所示:

该页面允许用户创建新的项目并发起招募。用户必须登录后才能访问,若未登录,将被重定向至注册页面。

主要功能包括:

1、项目基本信息输入:用户可以填写项目名称、课程安排、项目目标、个人能力、招募需求和标签等信息。

2、表单验证:所有字段均为必填项,确保用户提供必要的信息。

3、提交功能:通过提交按钮,将输入的信息保存到数据库中,并在成功后重定向到个人中心。

7、申请项目界面

demo如下所示:

该页面允许用户申请特定项目,并展示所申请项目的基本信息。用户必须登录后才能访问,若未登录,将被重定向至注册页面。

主要功能包括:

1、项目标识展示:清晰显示用户申请的项目ID,帮助用户确认所申请的项目。

2、课程安排与个人能力输入:用户可以填写课程安排和个人能力的详细信息。

3、表单提交:提供提交申请的功能,用户填写完信息后,可以通过提交按钮将申请发送到服务器。

8、个人中心界面

界面如下所示:

该页面允许用户查看个人信息及相关项目。用户必须登录后才能访问,若未登录,将被重定向至注册页面。

主要功能包括:

1、用户信息展示:用户的学号、姓名、专业和邮箱等基本信息会在页面上显示,方便用户查看。

2、项目列表展示:用户参与或发起的项目以列表形式呈现,项目名称为链接,用户可以点击查看项目详情。

项目细节:

将项目按时间顺序排列,最新的项目显示在最上方,以便与用户当前的活动保持一致,因为时间较早的项目可能已经结束。对应的SQL语句如下:

$sql_projects = "SELECT * FROM projects WHERE creator_id='$student_id' OR id IN (SELECT project_id FROM applications WHERE student_id='$student_id') ORDER BY id DESC";
$projects = $conn->query($sql_projects);

9、资源中心界面

demo如下所示:

该页面提供文件上传和搜索功能,方便用户管理和访问上传的资源。

主要功能包括:

1、文件上传:用户可以选择文件进行上传,支持多种文件类型(如图片、文档、视频等)。上传成功后,文件将存储在指定目录中。

文件上传接口:POST /plateform/resource_center.php

2、文件类型验证:在上传过程中,系统会检查文件类型,确保只允许特定格式的文件上传,避免不必要的安全风险。

3、文件搜索:用户可以输入关键字搜索已上传的文件,支持不区分大小写的搜索功能。

$files = array_filter($files, function($file) use ($search_query) {
    return stripos($file, $search_query) !== false && $file !== '.' && $file !== '..';
});

文件搜索接口:POST /plateform/resource_center.php
参数:search

4、已上传文件列表:页面展示所有已上传文件的列表,用户可以点击文件名以在新标签页中查看或下载文件。

文件下载接口:GET /plateform/uploads/filename

10、管理员登录界面

demo如下所示:

该页面允许管理员进行登录以访问管理功能。

主要功能包括:

1、登录信息输入:用户可以填写用户名和密码,进行身份验证。

2、身份验证:系统会检查输入的用户名和密码是否与数据库中的记录匹配,确保用户身份的合法性。

3、错误提示:如果用户名或密码不正确,页面会显示相应的错误信息,指导用户重新输入。

4、会话管理:成功登录后,系统会设置会话变量,保持用户的登录状态,以便访问后续管理页面。

项目细节:

在本系统中,只有在 admin 表中的用户才能访问管理员审核功能。若当前用户不属于管理员,则系统将重定向至登录页面。经过审核的用户信息将被插入至 users 表中,成为普通用户。这样可以确保不同用户角色的权限明确区分。

例如,普通用户输入正确的用户名及密码,也不可进入管理员审核界面:

11、管理员审核界面

界面如下所示:

该页面允许管理员审核待处理的用户注册申请,并进行管理操作。必须登录且身份为管理员才能访问,否则将被重定向至admin_login.php页面。

主要功能包括:

1、用户登录验证:检查用户是否已登录,并确保用户具有管理员权限,未登录或权限不足时重定向到登录页面。

2、待审核用户列表:显示所有待审核用户的信息,包括学号/工号、姓名、专业、邮箱及身份证明照片。

3、审核操作:管理员可以对每个待审核用户进行审核,审核通过,则将其添加到正式用户表中,再从待审核表中删除其信息。

通过GET传参实现审核操作:

项目细节:

插入用户数据到 users 表并在 pending_users 表删除待审核用户(存在先后关系)。SQL语句如下:

项目细节

部分项目细节已在上文及 2024秋软件工程结对作业(第一次) 阐述,此处作统一总结。

1、权限划分防止未授权访问

项目内的接口保持相对封闭,除登录界面、注册界面外的所有接口、界面均作权限划分处理,仅限已认证用户查看和参与,以防止项目核心内容外泄。

相关代码:

session_start();
if (!isset($_SESSION['student_id'])) {
    header("Location: register.php"); // 重定向到注册页面
    exit();
}

如图,未登录状态下,访问项目详情界面、申请项目接口时均被重定向至注册界面:

同时,管理员审核界面仅允许管理员身份访问,已登录用户不得访问管理员审核界面。

2、DESC实现时间逆序排列

在项目大厅、个人中心和标签详情界面的项目列表中,使用SQL中的DESC命令实现时间逆序排列。这是因为较久远的项目通常已完成,因此优先展示最新项目能够更好地满足用户需求。

3、多处调用htmlspecialchars函数

在项目代码中,使用htmlspecialchars() 函数将一些预定义的字符转换为 HTML 实体,防止潜在的XSS攻击。

4. 功能优化与用户友好性

在用户发起招募或申请项目时,无需重复输入姓名、学号、专业、邮箱等信息。提交表单后,系统会自动从数据库中查询用户的相关信息,并将其与提交的数据结合后,直接回显到浏览器页面。这一优化提高了用户体验,减少了不必要的输入步骤。

5、互动性与响应式效果

对于点击此处申请此项目按钮处,加入了颜色和缩放过渡效果,按钮在用户悬停时轻微放大,明确告知用户该元素是可点击的,让用户在点击或悬停时获得流畅的视觉反馈,增强了交互体验。

单元测试

选用的测试工具:

在测试中使用PHP的内置函数(如 ob_start()include)来模拟页面访问,这种方法适用于测试PHP应用中的页面逻辑。此外,还使用 curl 、Burp工具测试API端点,从而有效地验证后端逻辑的正确性和稳定性。

测试过程:

1、编写测试用例,以用户会话模拟访问 apply.php 页面,并检查页面是否按照预期显示了项目名称和表单字段:

<?php
//试apply.php页面
function testApplyPage() {
   // 模拟登录状态
   session_start();
   $_SESSION['student_id'] = 1;
   $_GET['id'] = 1;
   ob_start();
   include 'apply.php';
   $output = ob_get_clean();

   //检查输出内容是否包含项目名称
   if (strpos($output, '你申请的项目为') !== false) {
       echo "测试通过: 项目名称显示成功\n";
   } else {
       echo "测试失败: 项目名称未显示\n";
   }

   //检查表单字段是否存在
   if (strpos($output, '<textarea name="schedule"') !== false && strpos($output, '<textarea name="abilities"') !== false) {
       echo "测试通过: 表单字段正确渲染\n";
   } else {
       echo "测试失败: 表单字段渲染不正确\n";
   }
}
//运行测试
testApplyPage();

如图,回显如下,说明测试通过:

2、使用curl工具测试管理员登录逻辑

添加测试回显,登录成功时输出success

终端运行如下命令,其中用户名密码均正确:

curl -X POST http://127.0.0.1/plateform/admin_login.php -d "username=admin" -d "password=passwd"

回显如下,成功回显测试字符串:

3、使用Burp测试文件上传功能点,查看文件是否被上传至预期目录:

如图所示,文件被上传至uploads/下,说明代码预期功能实现成功。

4、由于文件功能点中用户可以输入关键字搜索已上传的文件,支持不区分大小写的搜索功能,故使用Burp测试如下。

首先确保仅存在以下两份文件:

搜索APPLICATION,若功能点逻辑正确,则将回显electirc application.png,测试结果如图:

回显搜索的文件名及列出的文件名,说明成功实现不区分大小写的搜索功能。

5、使用curl工具测试用户登录逻辑

添加测试回显,登录成功时输出success,失败时输出false

终端运行如下命令,其中密码为错误密码:

curl -X POST http://127.0.0.1/plateform/login.php -d "username=01001" -d "password=01002"

回显如下,成功回显测试字符串:

学习单元测试的方法:

1.阅读在线资源了解单元测试的基本概念和最佳实践,学习如何编写高效的测试用例。

2.分析优秀的测试用例,学习其测试结构和用例设计。

3.在实际项目中编写和运行测试用例,逐步积累经验,并不断优化测试代码。

4.合理运用 AIGC 工具,提高测试质量。

以PHP为例,简易教程如下:

1、配置PHP环境,创建一个用于测试的目录,包含要测试的PHP文件。

2、编写测试用例时,使用条件语句检查输出内容是否符合预期,使用内置的 ob_start()ob_get_clean() 函数来捕获输出。

3、代码示例:

function IceTest() {
    ob_start();
    include 'example.php';
    $output = ob_get_clean();

    if (strpos($output, '预期内容字符串') !== false) {
        echo "测试通过\n";
    } else {
        echo "测试失败\n";
    }
}

4、浏览器打开测试文件或命令行运行测试文件,查看测试结果,验证功能是否如预期工作,并进行调整。

构造测试数据的思路:

1.基本功能测试

创建有效的测试数据以测试核心功能,例如用户登录、文件上传等。确保至少有一个有效的用户和文件供测试使用。

2.边界测试

考虑各种边界条件,例如空输入、超长输入和无效格式等。确保系统能够处理这些异常情况。

3.错误处理测试

模拟错误场景,例如错误的用户名和密码,确保系统能给出正确的错误提示。

考虑将来测试人员的***难:

在设计测试时,考虑到测试人员可能尝试进行不常规的操作,例如输入意外的格式或进行大量请求。因此,可以将各种测试方法写入备忘录,在项目开发时进行测试。同时可以设计自动化测试脚本,进行压力测试和负载测试,以确认系统在高并发下的稳定性。

PSP表格

以下为 PSP 表格,包含任务阶段、预估耗时及实际耗时(估算):

任务阶段(PSP) 预估耗时(min) 实际耗时(min)
环境、数据库配置 10 15
用户注册界面开发 15 10
用户登录界面开发 20 15
项目大厅界面开发 40 60
标签详情界面开发 40 50
项目详情界面开发 40 55
发起招募界面开发 40 40
申请项目界面开发 30 35
个人中心界面开发 30 25
管理员登录界面开发 15 15
管理员审核界面开发 30 25
资源中心界面开发 35 30
项目整体优化 20 25
细节完善 25 35
需求点测试+代码调试 30 40
事后总结、提出优化方案 15 15
总计 435 490

分工情况

由于项目未采用前后端分离的架构,故决定根据页面功能进行任务划分。本人主要负责项目大厅界面、标签详情界面、项目详情界面、发起招募界面、申请项目界面以及个人中心界面的开发。队友承担用户注册界面、用户登录界面、管理员登录界面、管理员审核界面和资源中心界面的开发工作。

在开发的过程中,我们保持了密切的沟通与协作,确保项目各部分的功能完整。同时,通过反复讨论与调整,对界面进行细节优化,实现样式设计的风格统一及使用体验的升级。

队友评价

队友不仅严格遵守时间节点,按时完成任务,而且在项目各个阶段及时进行汇报,同时针对开发中的各种情况分享自己的想法和进展。在项目开发中,我们倾听彼此的意见并提出建设性的反馈,确保了项目的顺利推进。

不足之处在于,有时队友的代码缺乏详细的注释,这增加了调试及项目整合的难度。建议在完成开发时增加更多注释,并编写简要的开发文档,以提高项目的可维护性。

Github代码签入记录

代码模块异常及解决方法

在实现简单的文件上传和搜索功能时,遇到搜索功能偶尔无法准确匹配文件名的问题,导致查询不到文件。

为了排查问题,使用 var_dump($files) 检查了文件列表,同时对搜索功能进行了多种文件名的调试。

经排查,当用户输入的搜索关键字包含大小写敏感的字符时,可能会导致搜索不到匹配项。于是我使用不区分大小写的匹配方法(stripos())进行搜索,成功解决了该问题。

posted @ 2024-10-10 18:53  秋说  阅读(89)  评论(0编辑  收藏  举报