2024秋软件工程结对作业(第二次之程序实现)

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/SE2024
这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13281
这个作业的目标 根据需求分析和原型设计,通过代码实现项目互通小程序
学号 102202131
合作伙伴 102202132 林鑫
博客链接 https://www.cnblogs.com/PZn000/p/18457483
合作伙伴博客链接 https://www.cnblogs.com/zhengbingzhi/p/18457479
github项目仓库地址 https://github.com/PZn000/102202131-102202132

一、具体分工

102202132 郑冰智

  1. 模块开发

    • 聊天论坛模块:负责开发小程序的聊天论坛功能。实现聊天信息的存储、发布和查询,通过云数据库和云函数进行数据处理。在前端提供实时更新的聊天界面,方便用户交流和讨论项目。
    • 我的收藏模块:开发“我的收藏”功能,实现项目的收藏和管理。与后端交互,将收藏信息存储在云数据库中,并在前端提供收藏列表展示和删除功能。
    • 主页模块:设计并实现主页界面,包括搜索栏、项目发布按钮和项目列表展示。与后端接口配合,实现搜索栏的高效检索功能,项目发布按钮触发后端数据录入操作,项目列表从云数据库获取数据并在前端展示。
    • 我的项目模块:开发“我的项目”功能,自动查询用户参与的项目。通过前后端通信,从云数据库获取用户参与项目信息并在前端呈现。
  2. 后端开发

    • 云数据库配置:合理规划云数据库结构,为用户信息、项目信息等数据创建相应的数据表和字段。设置索引以提高数据查询效率,确保数据存储的安全性和稳定性。
    • 云函数开发:编写云函数实现用户认证、项目发布、项目查询等业务逻辑。利用云函数的触发机制,实时处理数据变化并通知前端更新界面。
  3. 特色功能

    • 我的项目自动查询功能:通过优化数据库查询语句和前后端通信机制,实现快速准确地自动查询用户参与的项目。在前端提供清晰的项目列表展示,方便用户管理和查看自己参与的项目。
    • 数据安全特色:加强用户密码加密存储,采用多因素认证等安全措施,保障用户数据的安全性。对敏感数据进行加密传输,防止数据泄露。
  4. 博客撰写

    • 记录小程序开发过程中的技术挑战和解决方案,分享开发经验和心得。撰写关于小程序功能介绍、使用教程等内容的博客文章,为用户提供使用指导和帮助。
    • 定期更新博客,回应用户反馈和问题,与用户进行互动交流,不断改进小程序的功能和用户体验。

102202131 林鑫

  1. 模块开发

    • 用户认证模块:负责开发小程序的登入、注册和找回密码界面。通过前后端交互,将用户输入信息发送至后端,后端利用云数据库存储用户信息并进行验证。采用加密算法保障用户密码安全,实现身份验证机制以判断用户是否存在。
    • 聊天论坛模块:负责开发小程序的聊天论坛功能。实现聊天信息的存储、发布和查询,通过云数据库和云函数进行数据处理。在前端提供实时更新的聊天界面,方便用户交流和讨论项目。
    • 项目发布模块:负责项目发布功能的实现。在前端提供简洁易用的项目发布界面,用户可以输入项目名称、描述、所需专业等信息。通过与后端接口交互,将项目信息存储到云数据库中,并触发相关的云函数进行数据处理和通知。确保项目发布的流程顺畅,数据准确存储。
    • 项目申请加入模块:开发项目申请加入功能。在前端展示项目详情页面时,提供申请加入按钮。用户点击后,弹出申请信息输入框,用户填写相关信息后提交申请。后端接收申请信息,进行数据校验和处理,将申请信息存储到项目对应的数据库表中,
  2. 页面优化

    • 界面美化:运用专业的设计工具和技术,对小程序的界面进行美化设计。选择合适的色彩搭配、字体样式和图标,提升小程序的视觉效果和用户体验。
    • 弹窗和滑动优化:优化小程序中的弹窗效果,使其更加简洁美观、易于操作。对页面滑动效果进行优化,提高页面切换的流畅性和响应速度。
  3. 小程序测试

    • 功能测试:对小程序的各个功能模块进行全面的功能测试,确保功能的正确性和稳定性。编写测试用例,覆盖各种场景和用户操作,及时发现并修复功能缺陷。
    • 性能测试:进行小程序的性能测试,包括页面加载速度、响应时间等方面的测试。优化小程序的性能,提高用户使用的流畅性和满意度。
  4. 博客优化

    • 对成员一撰写的博客文章进行优化,提高文章的可读性和专业性。检查文章中的语法错误和排版问题,确保文章质量。
    • 根据大家对小程序的反馈和建议,及时转达给开发团队,促进小程序的不断改进和完善。

二、PSP 表格

PSP2.1 Personal Software Process Stages 预估耗时(小时) 实际耗时(小时)
Planning (计划) 2 2.5
Estimate (估计这个任务需要多少时间) 48 48
Development (开发) 15 15
Analysis (需求分析,包括学习新技术) 3 3.5
Design Review (设计复审) 1.5 1.5
Coding Standard (代码规范,为开发制定规范) 1 1.5
Design (具体设计) 2.5 3
Coding (具体编码) 12 14
Code Review (代码复审) 2 3
Test (测试,自我测试,修改代码,提交修改) 4 4
Reporting(报告) 2 1.5
Test Report (测试报告) 1.5 1.5
Size Measurement (计算工作量) 0.5 0.5
Postmortem & Process Improvement Plan (总结) 0.5 0.75
合计 48 52.25

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

一、需求分析

(一)功能需求(附带伪代码)

  1. 登入注册功能
    • 用户可以通过输入用户名、密码进行注册,注册成功后可以使用用户名和密码进行登录。
    • 代码实现思路:前端通过表单收集用户输入的注册信息,使用表单验证技术确保信息格式正确。然后通过 axios 等工具向后端接口发送 POST 请求,携带用户信息。后端接收到请求后,将用户信息存储到数据库中,同时对密码进行加密处理。登录时,前端同样发送请求,后端验证用户名和密码是否匹配,如果匹配则返回登录成功的响应。
# 后端
def get_projects_from_database():
    """
    从数据库获取项目列表。
    """
    pass
# 前端
def display_projects(projects):
    """
    展示项目列表。
    """
    pass
  1. 主页项目分布功能
    • 在主页上展示项目列表,包括项目名称、描述等信息。用户可以浏览项目列表,了解不同的项目。
    • 代码实现思路:后端从数据库中读取项目信息,通过接口将项目列表数据返回给前端。前端使用列表渲染的方式展示项目列表,每个项目可以点击进入项目详情页面。
# 前端
def get_search_keyword():
    """
    获取用户输入的搜索关键词。
    """
    pass
def send_search_request(keyword):
    """
    发送搜索请求。
    """
    pass
# 后端
def search_projects(keyword):
    """
    根据关键词在数据库中搜索项目。
    """
    pass
  1. 主页搜索功能
    • 用户可以在主页的搜索栏中输入关键词,搜索相关的项目。
    • 代码实现思路:前端获取用户输入的搜索关键词,发送请求到后端。后端使用数据库的搜索功能,如倒排索引等,根据关键词在项目信息中进行检索,然后将搜索结果返回给前端进行展示。
# 前端
def get_search_keyword():
    """
    获取用户输入的搜索关键词。
    """
    pass
def send_search_request(keyword):
    """
    发送搜索请求。
    """
    pass
# 后端
def search_projects(keyword):
    """
    根据关键词在数据库中搜索项目。
    """
    pass
  1. 论坛讨论功能
    • 用户可以在论坛中发布消息、回复消息,进行项目相关的讨论。
    • 代码实现思路:前端提供论坛页面,用户输入消息后发送请求到后端。后端将消息存储到数据库中,并通过实时更新的技术,如 WebSocket 等,将新消息推送给所有在线的用户。
# 前端
def get_message_input():
    """
    获取用户输入的消息。
    """
    pass
def send_message_request(message):
    """
    发送消息请求。
    """
    pass
# 后端
def save_message_to_database(message):
    """
    将消息保存到数据库。
    """
    pass
def push_new_message_to_users(new_message):
    """
    将新消息推送给用户。
    """
    pass
  1. 我的界面收藏模块和参与项目模块
    • 收藏模块:用户可以收藏感兴趣的项目,在我的收藏页面中查看和管理收藏的项目。
    • 参与项目模块:展示用户参与的项目列表,方便用户快速访问自己参与的项目。
    • 代码实现思路:收藏模块,前端通过接口将收藏操作发送到后端,后端将收藏信息存储到数据库中。在我的收藏页面,从数据库中读取收藏信息并展示给用户。参与项目模块,后端通过数据库查询和关联技术,获取用户参与的项目信息,返回给前端展示。
# 前端
def send_favorite_request(project_id):
    """
    发送收藏请求。
    """
    pass
# 后端
def save_favorite_to_database(user_id, project_id):
    """
    将项目收藏信息保存到数据库。
    """
    pass
def get_favorites_from_database(user_id):
    """
    从数据库获取用户收藏的项目。
    """
    pass
#后端
def get_user_participated_projects(user_id):
    """
    获取用户参与的项目。
    """
    pass

(二)个人信息分析(伪代码)

  1. 全局变量:可以设置一些全局变量来存储用户的登录状态、用户信息等。例如,在用户登录成功后,将用户信息存储在全局变量中,方便在不同页面中使用。
    • 代码实现思路:在 Vue.js 项目中,可以使用 Vuex 等状态管理工具来管理全局变量。在用户登录成功后,将用户信息存储到 Vuex 的 state 中,在需要使用用户信息的组件中,可以通过mapState等方式获取全局变量中的用户信息。
// 定义全局状态存储
const globalState = {
  isLoggedIn: false,
  userInfo: null
};
// 设置登录状态和用户信息
function setLoginStatus(status, info) {
  globalState.isLoggedIn = status;
  globalState.userInfo = info;
}
// 获取登录状态和用户信息
function getLoginStatus() {
  return globalState.isLoggedIn;
}
function getUserInfo() {
  return globalState.userInfo;
}
  1. 数据库:存储用户信息、项目信息、聊天信息、收藏信息等。合理设计数据库结构,确保数据的存储和查询效率。
    • 代码实现思路:根据不同的功能需求,设计相应的数据表结构。例如,用户信息表可以包括用户名、密码、邮箱等字段;项目信息表可以包括项目名称、描述、发布者等字段。使用云数据库等工具,通过设置索引、优化查询语句等方式提高数据存储和查询的性能。
// 添加用户信息到数据库
function addUserToDatabase(username, password, email) {
  // 使用云数据库 API 添加用户信息
}

// 查询用户信息
function queryUserFromDatabase(username) {
  // 使用云数据库 API 根据用户名查询用户信息
}

// 添加项目信息到数据库
function addProjectToDatabase(name, description, publisher) {
  // 使用云数据库 API 添加项目信息
}

// 查询项目信息
function queryProjectsFromDatabase() {
  // 使用云数据库 API 查询项目信息
}

(三)性能优化分析

  1. 优化代码,更换部分函数以及调用云数据库的方法等,提高小程序性能。例如,优化数据库查询语句,避免不必要的查询和数据加载。
    • 代码实现思路:对代码进行性能分析,找出性能瓶颈。如果数据库查询耗时较长,可以通过优化查询语句、添加索引等方式提高查询效率。同时,检查代码中是否存在不必要的循环、重复计算等问题,进行优化。
  2. 对于数据不同步的问题,增加刷新功能,确保用户能够及时看到最新的数据。
    • 代码实现思路:在前端页面中添加刷新按钮,用户点击刷新按钮时,发送请求到后端获取最新的数据。后端可以通过缓存技术等方式,提高数据的获取速度,确保数据的实时性。

4. 关键实现流程图

  • 流程图:
graph TD; A[登入界面] --> B{有账户?}; B -- 否 --> C[注册界面]; C --> D[登入界面]; B -- 是 --> E[输入密码]; E --> F{密码正确?}; F -- 是 --> G[主菜单]; F -- 否 --> E; G --> H[主页]; G --> I[聊天论坛]; G --> J[我的]; H --> K[搜索框]; K --> L[项目栏]; H --> M[项目发布按钮]; M --> N[项目发布界面]; N --> O[项目栏]; H --> P[项目栏]; P --> Q[项目详情界面]; Q --> R[收藏功能]; R --> S[我的收藏]; Q --> T[讨论区按钮]; T --> U[讨论区]; I --> V[输入框]; V --> W[聊天记录]; J --> X[个人信息]; X --> Y[个人信息界面]; J --> Z[我的收藏]; Z --> Q; J --> AA[我的项目]; AA --> AB[我参与的项目]; AB --> Q; AA --> AC[设置按钮]; AC --> AD[设置界面]; AA --> AE[退出账户按钮]; AE --> A;
  • 项目信息数据流图:
graph TD; subgraph 用户层 A[用户] --> B[用户操作界面]; B --> C[输入账号密码]; B --> D[项目发布]; B --> E[项目收藏]; B --> F[论坛互动]; end subgraph 数据层 G[用户账号数据库] --> H[账号密码验证]; I[项目发布数据库] --> J[项目展示]; K[项目详情数据库] --> L[项目详细信息]; M[我的收藏数据库] --> N[收藏管理]; O[论坛数据库] --> P[论坛交流]; end subgraph 管理层 Q[管理系统] --> R[数据监控]; R --> S[故障处理]; S --> T[性能优化]; end C --> H; D --> I; E --> M; F --> O; H --> B; J --> B; L --> B; N --> B; P --> B;

5. 代码片段:

  • 代码片段1:通过数据库申请项目并输出项目:
const app = getApp();
const db = wx.cloud.database(); // 获取数据库引用

Page({
  data: {
    projectName: '',
    projectType: '',
    majorsRequired: '',
    timeSchedule: '',
    contactInfo: '',
    memberRequirements: '',
    projectIntroduction: ''
  },

  inputProjectName: function(e) { this.setData({ projectName: e.detail.value }); },
  inputProjectType: function(e) { this.setData({ projectType: e.detail.value }); },
  inputMajorsRequired: function(e) { this.setData({ majorsRequired: e.detail.value }); },
  inputTimeSchedule: function(e) { this.setData({ timeSchedule: e.detail.value }); },
  inputContactInfo: function(e) { this.setData({ contactInfo: e.detail.value }); },
  inputMemberRequirements: function(e) { this.setData({ memberRequirements: e.detail.value }); },
  inputProjectIntroduction: function(e) { this.setData({ projectIntroduction: e.detail.value }); },

  // 提交项目到数据库
  submitProject: function() {
    if (this.validateInput()) {
      let projectData = {
        user: app.globalData.user,
        projectName: this.data.projectName,
        projectType: this.data.projectType,
        majorsRequired: this.data.majorsRequired,
        timeSchedule: this.data.timeSchedule,
        contactInfo: this.data.contactInfo,
        memberRequirements: this.data.memberRequirements,
        projectIntroduction: this.data.projectIntroduction,
        participator: []
      };

      db.collection('project').add({
        data: projectData,
        success: function(res) {
          wx.showToast({ title: '提交成功', icon: 'success', duration: 2000 });
          wx.navigateBack(); // 返回上一页
        },
        fail: function(error) {
          wx.showToast({ title: '提交失败,请重试', icon: 'none', duration: 2000 });
        }
      });
    }
  },

  // 输入验证函数
  validateInput: function() {
    let { projectName, projectType, majorsRequired, timeSchedule, contactInfo, memberRequirements, projectIntroduction } = this.data;
    let isValid = true;

    if (!projectName.trim()) { wx.showToast({ title: '请输入项目名称', icon: 'none' }); isValid = false; }
    if (!projectType.trim()) { wx.showToast({ title: '请输入项目类型', icon: 'none' }); isValid = false; }
    if (!majorsRequired.trim()) { wx.showToast({ title: '请输入所需专业', icon: 'none' }); isValid = false; }
    if (!timeSchedule.trim()) { wx.showToast({ title: '请输入时间安排', icon: 'none' }); isValid = false; }
    if (!contactInfo.trim()) { wx.showToast({ title: '请输入联系方式', icon: 'none' }); isValid = false; }
    if (!memberRequirements.trim()) { wx.showToast({ title: '请输入成员要求', icon: 'none' }); isValid = false; }
    if (!projectIntroduction.trim()) { wx.showToast({ title: '请输入项目简介', icon: 'none' }); isValid = false; }

    return isValid;
  }
});

--------------------------------------------------------------------------------------------------------------------------------------------

// 从数据库加载项目
  loadProjectsFromDB: function(callback) {
    const db = wx.cloud.database();
    const that = this;
    db.collection('project').get({
      success: function(res) {
        that.setData({ allCategory: res.data });
        if (callback) callback();
      },
      fail: function(error) {
        wx.showToast({ title: '加载项目失败', icon: 'none' });
        if (callback) callback();
      }
    });
  },

项目数据提交:
用户输入项目信息后,调用 submitProject 函数,先通过 validateInput 验证必填项。验证成功后,将项目数据作为 JSON 对象存入云数据库的 project 集合。数据库操作使用 wx.cloud.database().collection('project').add(),成功提交后提示并返回上一页。

项目数据展示:
主页加载时,onLoad 函数调用 loadProjectsFromDB,从数据库提取项目并存储到 allCategory,项目数据展示在页面上。

  • 代码片段2:搜索功能:
// 处理搜索框输入
handleInput: function(e) {
  const value = e.detail.value;
  this.setData({
    searchKeyword: value
  });

  // 如果搜索框为空,重新加载所有项目
  if (value.trim() === '') {
    this.loadProjectsFromDB(); // 重新加载所有项目
  }
},

// 处理搜索图标点击
handleSearch: function() {
  this.setData({
    isCategory: true
  });
  const keyword = this.data.searchKeyword.trim().toLowerCase();
  if (keyword === '') {
    // 如果关键词为空,恢复显示所有项目
    this.loadProjectsFromDB(); // 重新加载所有项目
    return;
  }

  // 通过关键词筛选项目
  let results = this.data.allCategory.filter(project => {
    return Object.values(project).some(prop => 
      prop.toString().toLowerCase().includes(keyword)
    );
  });

  if (results.length === 0) {
    wx.showToast({
      title: '未找到匹配内容',
      icon: 'none'
    });
  }

  this.setData({
    searchResults: results
  });
},


搜索框输入处理 (handleInput):
用户输入时,内容会存入 searchKeyword。若搜索框为空(清空输入),系统调用 loadProjectsFromDB 重新加载并显示所有项目。

点击搜索按钮处理 (handleSearch):
点击搜索按钮后,isCategory 设置为 true,获取并小写化用户输入的关键词。如果为空,恢复显示所有项目;否则,根据关键词在 allCategory 中进行模糊匹配。若无结果,显示“未找到匹配内容”,否则更新 searchResults 以展示匹配的项目。

关键点:
模糊匹配:项目字段与关键词进行模糊匹配,使用 includes 查找。
实时反馈:根据用户输入动态过滤显示项目。
空输入恢复:若输入为空,恢复项目列表。

  • 代码片段3:刷新功能:
// 点击刷新图片时触发,从数据库重新加载项目
handleRefreshTap: function() {
  this.setData({
    isCategory: false // 将 isCategory 设置为 false,表明当前处于非分类或搜索状态
  });
  console.log(this.data.isCategory);
  
  // 显示顶部加载动画
  wx.showNavigationBarLoading();
  
  // 重新加载项目数据
  this.loadProjectsFromDB(() => {
    // 隐藏顶部加载动画
    wx.hideNavigationBarLoading();
    
    // 显示刷新成功的提示
    wx.showToast({
      title: '刷新成功',
      icon: 'success'
    });
  });
}

代码解释:
状态更新:将 isCategory 设置为 false,表明当前状态不是分类或搜索状态。
显示加载动画:调用 wx.showNavigationBarLoading() 在页面顶部显示加载动画,提示用户正在刷新。
重新加载项目:调用 loadProjectsFromDB() 函数从数据库重新获取项目数据。
加载完成处理:
隐藏加载动画:调用 wx.hideNavigationBarLoading() 停止顶部加载动画。
显示提示信息:刷新完成后,通过 wx.showToast() 显示 "刷新成功" 的提示消息,告知用户刷新已完成。
关键点:
用户反馈:通过顶部加载动画和提示信息,提供了实时的用户反馈,改善用户体验。
数据重新加载:每次点击刷新按钮时,项目数据会从数据库中重新提取并更新显示。

四、附加特点设计与展示

-特色部分:搜索功能具有历史记录和猜你想搜的功能,可以根据不同用户的搜索记录等等来判断个人喜好:

代码:

updateSuggestedTags: function () {
  const { recentSearches, tagLibrary } = this.data;
  let suggestedTags = [];

  if (recentSearches.length > 0) {
    // 遍历最近搜索记录,查找相关标签
    recentSearches.forEach(search => {
      Object.keys(tagLibrary).forEach(category => {
        if (search.includes(category)) {
          // 如果搜索关键词匹配某个类别,获取相关标签
          suggestedTags = [...new Set([...suggestedTags,...tagLibrary[category]])];
        }
      });
    });
  }

  // 如果没有匹配到标签,则从分类中随机挑选一些标签
  if (suggestedTags.length === 0) {
    const shuffledCategories = this.data.categories.sort(() => 0.5 - Math.random());
    suggestedTags = shuffledCategories.slice(0, 6); // 随机选取6个标签
  }

  this.setData({
    suggestedTags: suggestedTags
  });
},


handleInput: function (e) {
  const value = e.detail.value;
  this.setData({
    searchKeyword: value
  });

  // 如果搜索框为空,重新加载所有项目并隐藏搜索记录
  if (value.trim() === '') {
    this.setData({
      showRecentSearches: false // 隐藏最近搜索
    });
    this.loadProjectsFromDB(); // 重新加载所有项目
  }
},


handleTagTap: function (e) {
  const tag = e.currentTarget.dataset.tag;
  this.setData({
    searchKeyword: tag
  });

  this.handleSearch(); // 直接进行搜索
},


handleDeleteSearch: function (e) {
  const keywordToDelete = e.currentTarget.dataset.keyword;
  let recentSearches = this.data.recentSearches.filter(item => item!== keywordToDelete);
  this.setData({
    recentSearches: recentSearches
  });

  // 更新猜你想搜标签
  this.updateSuggestedTags();
},

更新猜你想搜标签的函数:这个函数用于更新猜你想搜的标签列表。如果最近搜索记录不为空,遍历最近搜索记录,检查是否包含在tagLibrary中的学科名称,如果包含,则将对应的相关标签添加到suggestedTags中。如果没有匹配到任何标签,则从分类列表中随机选取 6 个作为猜你想搜的标签。最后,通过setData更新suggestedTags数据。
处理猜你想搜标签点击的函数:当猜你想搜的标签被点击时,将标签设置为搜索关键词,并调用搜索函数进行搜索。
删除单个搜索记录的函数:这个函数在删除单个搜索记录时被调用。根据点击的关键词从最近搜索记录中删除该关键词,然后更新最近搜索记录数据,并更新猜你想搜的标签。

成果展示:

五、目录说明和使用说明

1. 目录结构

项目名称/专业项目交流小程序
E:.
│  .eslintrc.js
│  .gitignore
│  app.js
│  app.json
│  app.wxss
│  mine.rar
│  package-lock.json
│  package.json
│  project.config.json
│  project.private.config.json
│  ReadMe.txt
│  sitemap.json
│  
├─102202131-102202132
├─miniprogram_npm
│  ├─@cloudbase
│  │  └─wx-cloud-client-sdk
│  │          index.js
│  │          index.js.map
│  │          
│  └─regenerator-runtime
│          index.js
│          index.js.map
│          
├─node_modules
│  │  .package-lock.json
│  │  
│  ├─@cloudbase
│  │  └─wx-cloud-client-sdk
│  │      │  package.json
│  │      │  README.md
│  │      │  
│  │      └─lib
│  │          │  error.d.ts
│  │          │  index.d.ts
│  │          │  utils.d.ts
│  │          │  wxCloudClientSDK.cjs.js
│  │          │  wxCloudClientSDK.esm.js
│  │          │  wxCloudClientSDK.umd.js
│  │          │  
│  │          ├─api
│  │          │      datasouce-caller.d.ts
│  │          │      
│  │          ├─orm
│  │          │      orm-client.d.ts
│  │          │      
│  │          └─types
│  │                  index.d.ts
│  │                  
│  └─regenerator-runtime
│          LICENSE
│          package.json
│          path.js
│          README.md
│          runtime.js
│          
├─pages
│  ├─addProject
│  │      addProject.js
│  │      addProject.json
│  │      addProject.wxml
│  │      addProject.wxss
│  │      
│  ├─chatPage
│  │      chatPage.js
│  │      chatPage.json
│  │      chatPage.wxml
│  │      chatPage.wxss
│  │      
│  ├─collectionPage
│  │  │  collectionPage.js
│  │  │  collectionPage.json
│  │  │  collectionPage.wxml
│  │  │  collectionPage.wxss
│  │  │  
│  │  └─image
│  │          OIP.jpg
│  │          
│  ├─discussionArea
│  │      discussionArea.js
│  │      discussionArea.json
│  │      discussionArea.wxml
│  │      discussionArea.wxss
│  │      
│  ├─forgotPassword
│  │      forgotPassword.js
│  │      forgotPassword.json
│  │      forgotPassword.wxml
│  │      forgotPassword.wxss
│  │      
│  ├─forum
│  │  │  forum.js
│  │  │  forum.json
│  │  │  forum.wxml
│  │  │  forum.wxss
│  │  │  
│  │  └─image
│  │          OIP.jpg
│  │          
│  ├─homePage
│  │  │  homePage.js
│  │  │  homePage.json
│  │  │  homePage.wxml
│  │  │  homePage.wxss
│  │  │  
│  │  └─image
│  │          OIP.jpg
│  │          search.jpg
│  │          search.png
│  │          
│  ├─index
│  │      index.js
│  │      index.json
│  │      index.wxml
│  │      index.wxss
│  │      
│  ├─joinedProject
│  │      joinedProject.js
│  │      joinedProject.json
│  │      joinedProject.wxml
│  │      joinedProject.wxss
│  │      
│  ├─loginRegisterPage
│  │      loginRegisterPage.js
│  │      loginRegisterPage.json
│  │      loginRegisterPage.wxml
│  │      loginRegisterPage.wxss
│  │      
│  ├─logs
│  │      logs.js
│  │      logs.json
│  │      logs.wxml
│  │      logs.wxss
│  │      
│  ├─mainPage
│  │      mainPage.js
│  │      mainPage.json
│  │      mainPage.wxml
│  │      mainPage.wxss
│  │      
│  ├─messagePage
│  │      messagePage.js
│  │      messagePage.json
│  │      messagePage.wxml
│  │      messagePage.wxss
│  │      
│  ├─myPage
│  │  │  myPage.js
│  │  │  myPage.json
│  │  │  myPage.wxml
│  │  │  myPage.wxss
│  │  │  
│  │  └─images
│  │          setting.jpg
│  │          settings.png
│  │          write.jpg
│  │          
│  ├─projectDetail
│  │  │  projectDetail.js
│  │  │  projectDetail.json
│  │  │  projectDetail.wxml
│  │  │  projectDetail.wxss
│  │  │  
│  │  └─images
│  │          collection.jpg
│  │          
│  ├─projectResults
│  │      projectResults.js
│  │      projectResults.json
│  │      projectResults.wxml
│  │      projectResults.wxss
│  │      
│  ├─test
│  │      test.js
│  │      test.wxml
│  │      
│  └─text
│          text.js
│          text.json
│          text.wxml
│          text.wxss
│          
└─utils
        util.js
        websocket.js


  
### 2. 使用步骤:

- 获取小程序二维码
1. 向开发团队索取小程序的测试版二维码。通常会在小程序开发过程中生成二维码并赋给测试人员,供测试人员进行测试。

- 扫码进入小程序
1. 打开手机微信,使用“扫一扫”功能扫描测试版二维码。
2. 微信会自动识别二维码并打开小程序。

- 功能测试
1. 登录注册功能:
   - 尝试使用不同的用户名、密码组合进行登录和注册操作,检查输入验证和错误提示是否正确。
   - 测试忘记密码功能,验证找回密码的流程是否顺畅。
2. 项目发布功能:
   - 检查是否能够顺利发布项目。
   - 确认发布后的项目是否能在项目列表中正确显示,并且信息完整准确。
3. 项目申请加入功能:
   - 申请加入不同的项目,检查申请信息的填写和提交过程是否简便流畅。
   - 观察申请提交后,系统是否有相应的提示和反馈。
4. 聊天论坛功能:
   - 能否收到不同测试人员在论坛发布的消息。
5. 我的收藏功能:
   - 收藏项目,检查收藏列表的更新是否及时。

- 性能测试
1. 在使用小程序的过程中,注意观察页面加载速度、操作响应时间等性能指标。
   - 打开不同的页面,记录加载时间,判断是否在可接受范围内。
   - 进行频繁的操作,如快速切换页面、发送多条消息等,观察小程序是否出现卡顿或崩溃现象。

- 问题反馈
1. 如果在测试过程中发现问题,及时记录问题的详细情况。
   - 包括操作步骤、出现问题的页面、错误现象、手机型号和微信版本等信息。
2. 将问题反馈给开发团队,可以通过邮件、项目管理工具或直接沟通的方式,以便开发团队及时修复问题。


## 六、单元测试
为了测试上述代码,我选择使用 **Jest** 作为单元测试工具。Jest 是一个流行的 JavaScript 测试框架,支持模块化测试、异步测试和快照测试,适合与小程序进行集成。以下是对单元测试的解释、部分代码示例和测试数据构造思路。

## 1. 测试工具与学习方式【4分】

### 选用的测试工具
**Jest** 是我选择的测试工具,主要原因包括:
- **简单易用**:Jest 的 API 简单且直观,适合初学者。
- **良好的社区支持**:有丰富的文档和示例,便于学习和解决问题。
- **支持异步测试**:可以处理 Promises 和异步函数,适合用于测试小程序中的异步 API。

### 学习单元测试的方法
我主要通过以下方式学习单元测试:
1. **官方文档**:阅读 [Jest 官方文档](https://jestjs.io/docs/getting-started) 了解基本用法和高级功能。
2. **示例项目**:查找和分析开源项目中的测试示例,理解最佳实践。
3. **在线教程**:观看 YouTube 和 Coursera 上的相关教程,结合视频和实践加深理解。

### 简易教程
以下是一个简易的 Jest 测试教程:

#### 安装 Jest
```bash
npm install --save-dev jest

创建测试文件

在项目目录中,创建一个 __tests__ 文件夹,并在其中创建测试文件,例如 app.test.js

编写测试代码

const app = require('../app.js'); // 导入要测试的模块

test('用户名和密码不能为空', () => {
  expect(app.validateCredentials('', '')).toBe(false);
});

运行测试

在命令行中,运行以下命令以执行测试:

npx jest

2. 项目部分单元测试代码【3分】

测试代码示例

以下是针对注册和登录功能的部分单元测试代码:

const app = require('../app.js'); // 假设 app.js 是要测试的模块

describe('User Registration and Login', () => {
  
  test('should not allow empty username and password', () => {
    const result = app.submit('', '');
    expect(result).toBe('账号密码不能为空');
  });

  test('should show error if username already exists', async () => {
    // 构造测试数据
    const existingUser = { user: 'testuser', password: 'testpass' };
    await app.models.userInfo.create({ data: existingUser }); // 创建一个用户

    const result = await app.submit('testuser', 'newpass');
    expect(result).toBe('账号已存在');
  });

  test('should successfully register a new user', async () => {
    const result = await app.submit('newuser', 'newpass');
    expect(result).toBe('注册成功');
  });

  test('should show error for incorrect login', async () => {
    const result = await app.submit('wronguser', 'wrongpass');
    expect(result).toBe('账号密码不存在');
  });

  test('should successfully login with correct credentials', async () => {
    await app.models.userInfo.create({ data: { user: 'loginuser', password: 'loginpass' } });

    const result = await app.submit('loginuser', 'loginpass');
    expect(result).toBe('登录成功');
  });
});

测试的函数

  • submit(): 此函数用于处理用户的注册和登录逻辑,并根据不同的情况返回相应的提示信息。

3. 构造测试数据的思路【3分】

测试数据构造思路

在构造测试数据时,我考虑以下几点:

  1. 边界情况:确保测试包括空输入、过长的用户名或密码等情况。例如:

    • 空用户名和密码。
    • 已存在的用户名。
    • 不匹配的登录凭据。
  2. 有效数据:创建有效的用户数据用于测试注册和登录,例如:

    • 一个有效的用户名和密码组合。
    • 一个只包含字母和数字的用户名。
  3. 异常情况:模拟可能发生的异常,例如数据库错误、网络问题等,通过 mock 处理这些情况。

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

为了考虑将来的测试人员的***难,我会:

  • 保持代码的可扩展性:确保测试代码易于修改和扩展,以适应新需求。
  • 编写详细的文档:提供清晰的测试说明和测试数据的背景,让其他人可以快速理解和修改。
  • 添加更多的测试用例:针对可能的边界情况和潜在的失败场景添加更多测试用例。

通过这种方式,可以确保我们的单元测试能够应对各种场景,并且为将来的维护和扩展打下良好的基础。

七、Github 的代码签入记录截图

八、问题及解决方法

一、数据内存太多,小程序无法在手机上呈现

  • 问题描述:由于数据内存占用过多,导致小程序在手机上运行时出现卡顿甚至无法呈现的情况。其中部分图片数据占用了大量内存空间。
  • 解决方法:将部分图片载入数据库,通过优化图片存储方式,减少内存占用。在需要展示图片时,从数据库中动态加载图片,而不是一次性将所有图片加载到内存中。

二、数据库连接异常,无法建立数据库

  • 问题描述:在开发过程中,出现数据库连接异常的情况,导致无法成功建立数据库连接。
  • 解决方法:确保环境 ID 配置正确,成员协作配置数据库环境。检查数据库配置参数,如数据库地址、端口号、用户名和密码等是否正确。同时,检查网络连接是否正常,确保小程序能够与数据库服务器进行通信。

三、数据不同步(比如发布项目后在项目栏里无法出现新发布的项目)

  • 问题描述:数据不同步问题表现为发布项目后,项目栏中无法及时出现新发布的项目,影响用户体验。
  • 解决方法:增加刷新功能,用户点击即可刷新项目列表。在发布项目后,通过触发刷新事件,从数据库中重新获取项目数据并更新项目栏的显示。同时,优化数据同步机制,确保新发布的项目能够及时同步到各个客户端。

四、反应速度慢

  • 问题描述:小程序反应速度慢,影响用户操作的流畅性和体验。
  • 解决方法:优化代码,更换部分函数以及调用云数据库的方法等,提高小程序性能。对代码进行性能分析,找出性能瓶颈并进行优化。例如,优化数据库查询语句,减少不必要的数据库访问;采用缓存技术,提高数据访问速度;优化界面渲染,减少不必要的界面更新等。

九、评价

一、值得学习的地方

(一)专业能力

在技术方面表现出较高的专业水准,对小程序开发涉及的前端和后端技术都有深入的理解。例如,在处理用户认证模块时,能够熟练运用加密算法确保用户密码的安全性,同时通过前后端的紧密配合实现高效的身份验证机制。

(二)团队协作

  1. 具有良好的团队协作精神,能够积极与其他成员沟通和协作,共同解决项目中遇到的问题。在分工明确的基础上,能够主动承担一些额外的任务,为团队的整体目标贡献自己的力量。

二、需要改进的地方

(一)时间管理

在项目开发过程中,有时会出现时间预估不准确的情况,导致部分任务未能按时完成。在处理一些紧急问题时,可能会因为过于专注于问题的解决而忽略了其他任务的进度。

(二)沟通方式

在与其他成员沟通时,有时会因为表达不够清晰而导致误解。需要进一步提高沟通能力,更加清晰地表达自己的观点和想法,确保信息的准确传递。

posted @ 2024-10-10 23:50  PZn  阅读(4)  评论(0编辑  收藏  举报