软件工程第二次结对作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/SE2024
这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13281
这个作业的目标 小组结对合作进行项目完成
学号 102201335

1. 项目地址

https://github.com/apppp0701/102201335-102201342

2. 具体分工

姓名 分工
潘宇晴 编写前端代码,实现初步项目
董雯莉 编写后端代码,实现数据库连接

3. PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(小时) 实际耗时(小时)
Planning 计划 0.5 1
Estimate 估计这个任务需要多少时间 0.5 0.5
Development 开发 20 35
Analysis 需求分析 (包括学习新技术) 5 7.5
Test 测试(自我测试,修改代码,提交修改) 2 3.5
Test Repor 测试报告 2.5 3
Postmortem&Process Improvement Plan 事后总结, 并提出过程改进计划 1 1
合计 31.5 51.5

4. 代码实现思路

前端代码思路

  1. 登录页面
    功能描述:进入app看到的第一个页面,包含“登录”和“注册”两个按钮,可以进行登录及跳转注册。
    实现思路:在登录页面组件中,使用Vue的数据绑定和事件处理实现用户输入与按钮点击逻辑,通过uni-app的API控制页面跳转。
    代码实现:
methods: {
    // 处理登录的方法
    handleLogin() {
      // 模拟登录成功,无论输入如何
      // 使用uni-app的switchTab方法跳转到首页
      uni.switchTab({
        url: '/pages/index/index' // 指定跳转的页面路径
      });
    },
    // 处理跳转到注册页面的方法
    navigateToRegister() {
      // 使用uni-app的navigateTo方法跳转到注册选择页面
      uni.navigateTo({
        url: '/pages/register/choice' // 指定跳转的页面路径
      })
    }
  }

  1. 身份选择
    功能描述:应用启动后显示的第一个页面,包含两个身份选择按钮:“我是老师”和“我是学生”,用户可以选择身份后跳转到注册页面。
    实现思路:在身份选择页面组件中,使用Vue的事件处理实现按钮点击逻辑,通过uni-app的API存储用户选择并控制页面跳转。

3.注册
功能描述: 本页面是用户注册页面,允许用户填写个人信息来完成注册流程。
实现思路:通过 .wxml 文件定义注册页面的布局,包括头像上传区域、注册表单以及提交按钮。,在 .js 文件中定义数据模型和事件处理方法,包括头像上传逻辑和注册逻辑。uploadAvatar 方法用于处理用户上传头像,register 方法用于处理注册提交,包括验证输入和跳转到登录页面。
代码实现:

methods: {
    // 上传头像图片的方法
    uploadAvatar() {
      // 调用uni-app的chooseImage API让用户选择图片
      uni.chooseImage({
        count: 1, // 限制用户选择一张图片
        sizeType: ['compressed'], // 图片类型,这里只允许压缩图
        sourceType: ['album', 'camera'], // 图片来源,可以是相册或者相机
        success: (res) => {
          // 选择图片成功后,将图片的临时路径赋值给组件的avatar数据属性
          this.avatar = res.tempFilePaths[0];
        }
      });
    },
    // 处理注册的方法
    register() {
      // 在这里进行输入验证和注册逻辑
      // 假设注册成功后执行以下代码
      uni.navigateTo({
        url: '/pages/login/login' // 跳转到登录页面
      });
    }
  }
}

4.首页
功能描述: 主页作为应用的导航中心,提供了“搜索项目”和“发布项目”等核心功能。用户可以通过搜索框查找感兴趣的项目或团队,同时,主页还会根推荐合适的跨专业合作项目。
实现思路:
搜索功能:通过在搜索框中输入关键字,并调用后台接口来获取匹配的项目或团队列表。
发布项目:用户可以自己在表单内填入内容进行发布。
推荐项目:根据用户的专业、兴趣等信息,在主页上展示推荐的项目卡片。

  1. 人才推荐
    功能描述: 该页面是一个人才推荐页面,它展示了不同人才的信息卡片,包括姓名、学校、专业和角色(学生或老师)。用户可以通过搜索框查找特定的人才,并且可以通过点击卡片或聊天图标与人才进行交流。
    实现思路:
    页面布局:使用Flexbox布局创建一个垂直排列的页面结构,包括一个头部区域、搜索框和人才卡片列表。
    数据展示:通过v-for指令循环展示people数组中的每个人才信息,每个人才信息都包含在一个卡片内。
    交互功能:为每个人才卡片添加点击事件,允许用户查看更多人才信息或与人才进行聊天。

  2. 消息界面
    功能描述: 该页面是一个消息列表页面,展示了用户的聊天列表。用户点击列表项可以跳转到与对方的聊天页面。
    实现思路:
    页面布局:使用Flexbox布局创建一个垂直排列的消息列表,每个列表项为一个消息卡片。
    数据展示:通过v-for指令循环展示messages数组中的每条消息,每个消息卡片包含头像、昵称和新消息指示点。
    交互功能:为每个消息卡片添加点击事件,当点击时,标记该消息为已读,并跳转到对应的聊天页面。

  3. 聊天界面
    功能描述: 该页面是一个聊天界面,用户可以输入消息,并点击发送。
    实现思路:
    数据展示:通过v-for指令循环展示chatMessages数组中的每条消息,根据消息类型(接收或发送)决定消息的排列方向和头像显示。
    交互功能:提供一个输入框供用户输入消息,并有一个发送按钮。当用户点击发送按钮时,将输入的消息添加到chatMessages数组中,并清空输入框。

  4. 个人主页
    功能描述: 该页面是一个用户个人主页,根据用户的角色(老师或学生)展示不同的内容,可以通过角色切换按钮在老师和学生的身份之间进行切换,并可以点击进入自己发布的项目和参与的项目。
    数据绑定:通过Vue的数据绑定功能,根据userRole的值动态显示老师或学生的主页内容。
    交互功能:提供按钮点击事件处理方法,用于角色切换和页面跳转。同时,处理头像加载失败的情况,显示提示信息。
    切换角色代码实现:

<!-- 老师主页 -->
    <!-- 使用v-if指令判断用户角色是否为老师,如果是,则显示老师主页的内容 -->
    <view v-if="userRole === 'teacher'" class="profile">
      <!-- 显示欢迎信息 -->
      <text>欢迎你,这里是你的老师主页。</text>
      <!-- 点击按钮跳转到我的项目页面 -->
      <button @click="navigateToMyProject">我的项目</button>
      <!-- 点击按钮跳转到指导项目页面 -->
      <button @click="navigateToProjectPage">指导项目</button>
    </view>
    
    <!-- 学生主页 -->
    <!-- 使用v-else-if指令判断用户角色是否为学生,如果是,则显示学生主页的内容 -->
    <view v-else-if="userRole === 'student'" class="profile">
      <!-- 显示欢迎信息 -->
      <text>欢迎你,这里是你的学生主页。</text>
      <!-- 点击按钮跳转到我的项目页面 -->
      <button @click="navigateToMyProject">我的项目</button>
      <!-- 点击按钮跳转到参与项目页面 -->
      <button @click="navigateToProjectPage">参与项目</button>
    </view>
    
    <!-- 角色切换区域 -->
    <view class="role-switch">
      <!-- 显示切换角色的提示文本 -->
      <text>切换角色:</text>
      <!-- 点击按钮将用户角色设置为老师 -->
      <button @click="setRole('teacher')">老师</button>
      <!-- 点击按钮将用户角色设置为学生 -->
      <button @click="setRole('student')">学生</button>
    </view>

  1. 我的项目
    功能描述:可以点击进入自己发布的不同项目并进行管理,调整项目状态和审核成员。
    实现思路:数据展示:通过v-for指令循环展示people数组中的每个人员信息,并使用数据绑定显示相关信息。
    交互功能:为每个人员卡片提供一个按钮,用于切换其加入状态(“同意申请"或"已加入”),并将状态存储在localStorage中。提供一个全局状态切换按钮,用于在"招募中"、"进行中"和"已完成"之间循环切换。

  2. 参与项目
    功能描述:可以随时退出参与的项目。
    实现思路:使用exitProject方法处理退出按钮的点击事件,将对应项目的状态更改为“已退出”。
    代码实现:

 <!-- 退出按钮,根据项目状态显示不同的文本 -->
          <button 
            class="exit-button" 
            :class="{ 'exited': item.status === '已退出' }" 
            @click.stop="exitProject(index)"
          >
            <!-- 如果项目状态为'已退出',则显示'已退出',否则显示'退出' -->
            {{ item.status === '已退出' ? '已退出' : '退出' }}
          </button>
        </view>
      </view>
    </view>
  </view>
</template>

后端代码思路

注册思路

生成register模块,models文件中写入应有的数据模型,配置url环境和视图函数


项目展示思路

生成project模块,models文件写入数据模型,form文件写入格式,配置url环境和视图函数



5. 附加特点设计与展示

在人才推荐界面设置一键沟通按键,可直接点击跳转专人聊天界面,无需寻找

代码实现

 goToChat(person) {
      // Navigate to the chat page and pass the person data
      uni.navigateTo({
        url: `/pages/chat/chat?name=${person.name}&id=${person.id}&major=${person.major}&role=${person.role}`
      });
    },

在个人界面设置身份切换功能,可以切换老师与学生的身份,并跳转管理项目

代码实现

 methods: {
    setRole(role) {
      this.userRole = role; // 根据按钮设置用户身份
    },
    navigateToMyProject() {
      // 跳转到我的项目页面
      uni.navigateTo({
        url: '/pages/myself/myproject' // 确保路径正确
      });
    },
    navigateToProjectPage() {
      // 跳转到项目页面
      uni.navigateTo({
        url: '/pages/myself/project' // 跳转到 pages/myself/project
      });
    },
    onImageError() {
      uni.showToast({ title: '头像加载失败', icon: 'none' });
    }
  }

6. 项目说明和目录说明

目录说明

- easyjob(front-end)
    -  .hbuilderx # HBuilderX项目配置文件
    - componets/Statusbar # 状态栏
    - pages # 页面
        - chat # 聊天页面
        - creat # 创建项目页面
        - index # 首页
        - login # 登录页面
        - message # 消息页面
        - myself # 个人中心页面
        - people # 推荐人界面
        - post # 发布项目页面
        - register # 注册页面
    - static # 静态资源
    - unpackage
    - App.vue
    - main.js
    - manifest.json
    - index.html
    - pages.json
    - uni.promisify.adaptor.js
- server(back-end)
    - server
        - __init__.py
        - asgi.py
        - settings.py
        - urls.py
        - wsgi.py
        - routing.py
    - register
        - __init__.py
        - admin.py
        - apps.py
        - api_urls.py
        - models.py
        - tests.py
        - views.py
        - people.py
    - project
        - __init__.py
        - admin.py
        - apps.py
        - form.py
        - models.py
        - tests.py
        - views.py
        - api_urls.py
    - manage.py
    - templates

使用说明

点击app打开软件,进行个人信息注册,首页有项目推荐,可点击查看详情;人才页有学生和老师人才推荐,可点击查看人才信息,也可点击右边的聊天标识进入聊天页面;消息页面可以和想认识的人才交流;我的页面可以查看自己所参加的项目或指导的项目。

7. 单元测试

测试工具

我们选用 Jest 作为测试框架,Jest测试的好处是它提供了快速的并行测试执行、内置的代码覆盖率报告以及零配置的易用性,使得编写和运行JavaScript测试变得简单高效。

测试学习教材

学习单元测试的步骤如下:
· 了解单元测试的定义、目的和重要性。选择合适的测试框架(如Jest、Mocha、Jasmine等)和断言库(如Chai、Should.js等)。从最简单的函数开始,学习如何编写测试用例。
· 掌握各种断言方法,用于验证代码的实际行为与预期是否一致。学习使用模拟对象(mocks)、存根(stubs)和间谍(spies)来隔离测试。
· 了解如何使用覆盖率工具来评估测试的全面性。学习如何根据测试结果来修复代码缺陷和重构代码。将单元测试集成到持续集成流程中,确保代码质量。不断学习新的测试技巧和最佳实践,提高测试效率和质量。

具体测试:登录测试

测试代码

const login = require('./login');

describe('Login Function', () => {
  it('should login successfully with correct credentials', async () => {
    const credentials = {
      username: 'testuser',
      password: 'testpassword'
    };
    await expect(login(credentials.username, credentials.password)).resolves.toEqual({
      status: 'success',
      message: '登录成功'
    });
  });

  it('should fail to login with incorrect credentials', async () => {
    const credentials = {
      username: 'wronguser',
      password: 'wrongpassword'
    };
    await expect(login(credentials.username, credentials.password)).rejects.toEqual({
      status: 'error',
      message: '用户名或密码错误'
    });
  });
});

测试思路

· 第一个测试用例确保当提供正确的用户名和密码时,登录功能能够正常工作。
· 第二个测试用例确保当提供错误的用户名和密码时,登录功能能够正确地处理错误并返回相应的错误信息。
· 由于登录操作通常是异步的(例如,涉及到数据库查询或网络请求),测试用例使用了 async/await 语法来处理异步逻辑。
· toEqual 和 rejects 是 Jest 的匹配器,用于验证函数的返回值是否符合预期。

考虑未来测试的挑战

· 全面性:编写测试用例时,尽量覆盖所有可能的执行路径,包括条件分支和循环。
· 编写清晰、有组织的测试代码,以便其他测试人员理解和维护。
· 为测试用例编写文档,说明每个测试的目的和预期结果。
· 确保测试用例本身不会因为外部变化而失败,例如避免使用硬编码的值。
· 设计测试框架和测试数据构造方法时,考虑未来的扩展性,以便容易添加新的测试用例。
· 模拟测试人员可能故意输入的“恶意”数据,测试代码的防御能力。
· 鼓励测试人员提供反馈,并根据反馈调整测试策略。

8. Github项目签到截图

9. 遇见的代码模块异常或结对困难与解决办法

1.问题:myproject页面点击卡片跳转,在浏览器上模拟存在但是打包成app点击无法跳转。

尝试和解决办法:通过筛查是否是按钮使用了事件冒泡,并且有一个父元素的事件处理器捕获了所有的事件,导致其他按钮的事件处理器没有被触发,将卡片的点击功能变为一个,不存在父子元素,在点开的界面里再次加入被删减的功能。同时检查代码发现遗留的localstorage逻辑上的错误,进行修改,多次打包测试解决问题。
收获:积累了宝贵的经验,学会了如何优化组件设计,通过合并点击功能,避免了不必要的父子元素关系,了解了代码审查的重要性。

2.问题:发行软件时软件的图标没有按上传的图片并且打包时屡屡出现问题。

尝试和解决办法:查阅资料发现图标只能是png格式而我上传了jpg格式,转换了图标的格式。打包出现问题经过筛查发现是图片的名称中有中文,修改图片名称,成功打包。
收获:了解到app对图标的格式要求,以及文件命名的规范,意识到在软件开发过程中,即使是看似小的细节(如文件格式和命名)也很重要。

3.问题:更改一个页面的格式其他页面也发生了变化。

尝试和解决办法:经过查阅资料发现是不同的页面中相同的名字的全局格式互相影响,采取了两种方式进行解决,第一种是改变变量的名称,第二种是修改style为style scoped。
收获:加深了对全局样式和局部样式的理解,知道了新的技巧,提高了解决问题的能力。

10. 对队友的评价

值得学习的地方:

队友积极好学,在前端开发上很有效率,做的界面基本符合原型设计;并且能够及时修正错误,迅速找到解决方案

需要改进的地方:

队友在部分模块上还是不能尽善尽美,可以考虑更深入学习测试框架的功能

posted @ 2024-10-10 23:12  apppppppp  阅读(14)  评论(0编辑  收藏  举报