结对第二次作业——编程实现

222100207王科竣 2024-03-26 19:20:52
这个作业属于哪个课程福州大学-2302软件工程
这个作业要求在哪里结对第二次作业--原型设计
结对学号222100207、22210226
这个作业的目标采用web技术来实现原型中的功能,编码实现原型设计的内容。
其他参考文献Vue.js教程,CSDN...

目录

  • 一.git仓库链接和代码规范链接
  • 1.1 仓库链接
  • 1.2 代码规范
  • 二.PSP表格
  • 三.项目部署云服务器后的访问链接
  • 四.成品展示
  • 4.1 首页
  • 4.2 选手信息
  • 4.3 每日赛况
  • 4.4 详细赛况
  • 4.5 奖牌榜
  • 4.6 了解更多
  • 五.结对讨论过程描述
  • 5.1 讨论,解决问题和查找资料
  • 5.2 结对讨论的截图
  • 六.设计实现过程
  • 6.1 设计实现过程描述
  • 6.2 功能结构图
  • 七.代码说明
  • 八.心路历程和收获
  • 九.评价结对队友

一.git仓库链接和代码规范链接

1.1 仓库链接


项目地址

1.2 代码规范


规范

二.PSP表格

PSP阶段Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划2020
• Estimate- 估计这个任务需要多少时间2020
Development开发9601360
• Analysis- 需求分析(包括学习新技术)150240
• Design Spec- 生成设计文档3040
• Design Review- 设计复审3030
• Coding Standard- 代码规范 (为目前的开发制定合适的规范)3030
• Design- 具体设计120150
• Coding- 具体编码480740
• Code Review- 代码复审6090
• Test- 测试(自我测试,修改代码,提交修改)6040
Reporting报告140180
• Report- 报告60100
• Size Measurement- 计算工作量4040
• Postmortem & Process Improvement Plan- 事后总结, 并提出过程改进计划4040
合计11201560

三.项目部署云服务器后的访问链接


项目IP地址

http://134.175.236.184/#/

四.成品展示

4.1 首页

赛事介绍,消息图片,与留言栏

img

img

4.2 选手信息

展示Country,Athlete,Gender,DOB

img

4.3 每日赛况

展示每天赛事,显示比赛类型,参与选手和比赛时间,支持点击查看

img

img

4.4 详细赛况

展示比赛的成绩,包含本场比赛参赛选手,选手排名,比赛积分,落后积分

img

img

img

4.5 奖牌榜

直观友好地展示各国的获奖情况

img

4.6 了解更多

介绍世界游泳锦标赛的举办背景,彰显了游泳精神。

img

五.结对讨论过程描述

5.1 讨论,解决问题和查找资料

  • 小问题线上交流,大问题与线下宿舍交流。
  • 在编程开始前,我们进行了vue框架的学习,最后选择了vue2.0,并完成了各配置
  • 任务分配:

    207同学负责了首页,部分赛事详情,奖牌榜,了解更多;226同学负责选手信息,每日赛况,以及对赛事详情的优化修改。
  • 对git分支提交进行了多次讨论与教程查找,对vue相关问题,查找了官方文件与相关组件使用教程。

5.2 结对讨论的截图

如下:

img

img

img

六.设计实现过程

6.1 设计实现过程描述

  • 安装了NPM,NODE.JS,完成了vue项目的创建
  • 创建了各功能页面,对index.js中进行路由路径编写
  • 在views下创建DayView,DetailView,HomeView,MedalView,PlayerView的视图文件,并在component下创建对应的组件以实现具体的功能
  • 进行各页面功能的组件编写,编写基础css:
  • 主页由赛事图片和一个留言表单组成
  • 选手信息页由一个表格组成显示国家、选手名字、性别、生日
  • 每日赛况由一个信息表格和一个日期导航栏组成。表格中显示比赛时间,比赛名称,比赛阶段和跳转详情页的链接。导航栏由四个按钮组成,点击按钮表格信息会变成对应日期的比赛信息
  • 详细赛况由折叠面板和标签页还有表格组成。点击折叠面板选择比赛,点击标签页选择比赛阶段,表格会显示选择的比赛对应阶段的信息,显示排名、国别简称、国旗样式、选手名字、年龄、总分、较第一名落后的分数
  • 奖牌榜一个表格组成显示排名、国家、金银铜牌的个数
  • 数据处理:
  • 使用JavaScript中的Fetch API对json数据进行解析,解析后存储到预先定义的数组中。然后,通过循环生成表格的行,并将解析后的信息填入其中。

6.2 功能结构图

如下:

img

七.代码说明

  • 选手信息页解析json数据

    使用 fetch API 获取 JSON 文件,打开json文件解析,并将其存进数组中

       fetch('datas/athletes.json')
          .then(response => response.json())
          .then(data => {
            // 遍历每个国家的参赛选手
            data.forEach(country => {
              // 遍历每个参赛选手
              country.Participations.forEach(participation => {
                // 提取运动员的PreferredLastName和PreferredFirstName字段并输出
                const lastName = participation.PreferredLastName;
                const firstName = participation.PreferredFirstName;
                this.athletes.fullName.push(lastName + ' ' + firstName);
    
                // 提取运动员的性别
                const genderMap = {
                  0: '男',
                  1: '女'
                };
                const genderText = genderMap[participation.Gender] || '未知';
                this.athletes.gender.push(genderText);
    
                // 提取运动员的出生日期
                const dob = participation.DOB.substr(0, 10);
                this.athletes.dob.push(dob);
    
                // 提取运动员的国家
                const countryText = participation.NAT;
                this.athletes.country.push(countryText);
              });
            });
          })
          .catch(error => {
            console.error('Error fetching or parsing JSON file:', error);
          });
    
  • 选手信息页渲染表格数据

    使用v-for循环读取数组中的数据并依次填入

    <!-- 在这里循环渲染数据 -->
            <tr v-for="(athlete, index) in athletes.fullName" :key="index">
              <td class="coun">{{ athletes.country[index] }}</td>
              <td class="player2">{{ athlete }}</td>
              <td>{{ athletes.gender[index] }}</td>
              <td>{{ athletes.dob[index] }}</td>
            </tr>
    
  • 每日赛况页循环生成日期按钮及其响应事件

    循环生成按钮,实现点击按钮更新选中日期,更新表格数据

    <button v-for="(button, index) in buttons" :key="index" class="button"
            :class="{ active: selectedButton === button.date }" @click="selectButton(button.date)">
            {{ button.label }}
          </button>
    
    selectButton(date) {
         this.selectedButton = date;
         this.selectedData = this.buttons.find(button => button.date === date).data;
       },
    
  • 每日赛事表格信息

    循环生成表格行。为phase属性增加Finals高亮显示,设置为highlight方便css更改样式。实现查看详情页面跳转,传递所需参数以定位信息。

    <tr v-for="(data, index) in selectedData" :key="index">
                <td>{{ data.time }}</td>
                <td>{{ data.event }}</td>
                <td :class="{ 'highlight': data.phase === 'Finals' }">{{ data.phase }}</td>
                <td><router-link
                    :to="{ name: 'detail', params: { code: data.code, phase: data.phase, event: data.$event } }">查看详情</router-link>
                </td>
              </tr>
    
  • 每日赛事初始化

    在mounted中设置默认选择

    <script>
    mounted() {
        // 在组件加载时,默认选择 '18th',手动加载数据
        if (this.selectedButton === '18th') {
          this.showData('18th');
        }
      },
    
  • 详细赛况页面组件

    使用elementUI的el-collapse折叠面板和el-tabs标签页、

    el-collapse嵌套el-tabs,el-tabs嵌套table

    el-collapse从DisciplineNameMap中获取比赛名称,el-tabs从phases中动态获得比赛拥有的阶段,table从results中获得比赛的详细信息并显示。

    <div class="collapse-container">
          <el-collapse v-model="activeNames" accordion @change="handlePanelChange">
            <el-collapse-item v-for="(code, name) in     DisciplineNameMap    " :title="name" :name="code" :key="code">
              <!-- 标签页 -->
              <div class="tabs-container">
                <el-tabs v-model="activePhase" @tab-click="handlePhaseChange">
                  <el-tab-pane v-for="(phase, index) in phases" :key="index" :name="phase" :label="phase"></el-tab-pane>
                </el-tabs>
              </div>
              <!-- 表格内容 -->
              <div class=" results-table-container">
                <table class="results-table">
                  <!-- 表头 -->
                  <thead>
                    <tr>
                      <th>Rank</th>
                      <!-- 奖牌 -->
                      <th></th>
                      <th>NAT</th>
                      <!-- 国家 -->
                      <th></th>
                      <th>Athlete</th>
                      <th>Age</th>
                      <th>TotalPoints</th>
                      <th>PointsBehind</th>
                    </tr>
                  </thead>
                  <!-- 表格内容 -->
                  <tbody>
                    <tr v-for="( result, index ) in      results.Rank     " :key="index">
                      <td>{{ result }}</td>
                      <td>
                        <img v-if="results.Rank[index] < 4" :src="medalUrl[index]" style="width: 20px; height: 20px;">
                        <i v-else class="no-image-icon"></i>
                      </td>
                      <td>{{ results.NAT[index] }}</td>
                      <td>
                        <img style="width: 25px; height: 25px" :src="countryFlagMap[results.NAT[index]]">
                      </td>
                      <td>{{ results.FullName[index] }}</td>
                      <td>{{ results.AthleteResultAge[index] }}</td>
                      <td>{{ results.TotalPoints[index] }}</td>
                      <td>{{ results.PointsBehind[index] }}</td>
                    </tr>
                  </tbody>
                </table>
              </div>
    
            </el-collapse-item>
          </el-collapse>
        </div>
    
  • 详细赛况获取数据

    getData根据选中的比赛对应的文件名或者根据别的页面传入的参数打开json文件,解析json数据,并将数据存入数组

     mounted() {
        // 默认加载数据
        this.getData();
      },
      methods: {
        getData() {
          let jsonFileName;
          let phase = "Finals";
          // 获取 JSON 文件代码
          if (this.selecteCode === null) {
            //theDay传输的参数
            jsonFileName = this.$route.params.code;
            this.activeNames = this.$route.params.code;
            // 获取所需阶段
            phase = this.$route.params.phase;
            this.activePhase = this.$route.params.phase;
          } else {
            //默认或者点击切换面板时
            jsonFileName = this.selecteCode;
            phase = this.activePhase;
          }
          // 发起异步请求获取 JSON 文件内容
          fetch(`/datas/results/${jsonFileName}`)
            .then(response => {
              if (!response.ok) {
                throw new Error('Failed to fetch');
              }
              return response.json();
            })
            .then(jsonData => {
    
              // 清空原有数据
              this.results.TotalPoints = [];
              this.results.PointsBehind = [];
              this.results.Rank = [];
              this.results.NAT = [];
              this.results.FullName = [];
              this.results.AthleteResultAge = [];
              this.phases = [];
    
              if (jsonFileName.substring(5, 7) === 'sy') {
                // 最后两个字符是'sy',代表是双人比赛
                // 处理双人比赛的数据
                jsonData.Heats.forEach(jsonPhase => {
                  this.phases.push(jsonPhase.PhaseName);
    
                  if (jsonPhase.PhaseName === phase) {
                    jsonPhase.Results.forEach(jsonResult => {
                      this.results.TotalPoints.push(jsonResult.TotalPoints);
                      this.results.PointsBehind.push(jsonResult.PointsBehind);
                      this.results.Rank.push(jsonResult.Rank);
                      this.results.NAT.push(jsonResult.NAT);
                      this.results.FullName.push(jsonResult.FullName);
                      this.results.AthleteResultAge.push(jsonResult.Competitors.map(competitor => competitor.AthleteResultAge).join('/'));
                    });
                  }
                });
              } else {
                // 处理单人比赛的数据
                jsonData.Heats.forEach(jsonPhase => {
                  this.phases.push(jsonPhase.PhaseName);
    
                  if (jsonPhase.PhaseName == phase) {
                    jsonPhase.Results.forEach(jsonResult => {
                      this.results.TotalPoints.push(jsonResult.TotalPoints),
                        this.results.PointsBehind.push(jsonResult.PointsBehind),
                        this.results.Rank.push(jsonResult.Rank),
                        this.results.NAT.push(jsonResult.NAT),
                        this.results.FullName.push(jsonResult.FullName),
                        this.results.AthleteResultAge.push(jsonResult.AthleteResultAge)
                    });
                  }
    
                });
              }
    
            })
            .catch(error => {
              // 处理错误
              console.error('Failed to fetch JSON file:', error);
            });
        },
        handlePanelChange(value) {
          // 点击面板时,更新数据
          this.selecteCode = value;
          this.activePhase = "Finals";
          this.getData();
        },
        handlePhaseChange() {
          this.getData();
        }
      },
    
  • 详细赛况的css样式设计

    导入elementUI的样式,并根据需要进行修改

    <!-- 示例 -->
    <script>
    import { Collapse, CollapseItem } from 'element-ui';
    import 'element-ui/lib/theme-chalk/collapse.css';
    import 'element-ui/lib/theme-chalk/collapse-item.css';
    import { Tabs, TabPane } from 'element-ui';
    import 'element-ui/lib/theme-chalk/tabs.css';
    import 'element-ui/lib/theme-chalk/tab-pane.css';
    </script>
    
    <style>
    @import url("//unpkg.com/element-ui@2.15.14/lib/theme-chalk/index.css");
        
    .collapse-container {
      width: 80%;
      margin: 0 auto;
      text-align: center;
    }
    
    .tabs-container {
      display: flex;
      justify-content: center;
      width: 50%;
      margin: 0 auto;
    }
    </style>
    

八.心路历程和收获

  • 222100207王 的心路历程和收获:

    学习流行的前端框架Vue.js,让我更加理解了前端开发。其中的Vue.js组件化开发思想,学习它,使我能够以更加模块化、结构化的方式来组织和构建前端应用。在组件化开发中,我学习了如何创建、注册、使用和管理Vue组件,让我更加熟练了Vue框架。

    在团队合作中,有效的沟通不可或缺,还需要详细的需求分析与设计,才能确保合作编程的顺利进行。在此次编程中,我学习了许多项目开发的技巧和知识,同时也意识到了自身经验的不足。

  • 222100226欧 的心路历程和收获:

    一开始接触作业的时候是很慌的,因为没有学过前端vue,后端springboot,所以早早地就开始作业,但是前期没什么进展,只能看看同学的做法和吸取学长的经验。最后决定使用vue开发,对vue进行现学现用,发现vue和上学期学的web还是有许多相似之处,心里就踏实了踏实了不少。从一开始的慌张,到开始脚踏实地开始编程的镇定,再次认识到万事开头难。

    在结对编程期间,我收获了不少,不仅积累了编程经验,学习了新的技术,掌握了新的开发技巧,还清楚地认识到在团队合作中沟通的重要性

九.评价结对队友

王 to 欧 :同伴十分认真负责,沟通能力实践能力很强。合作中,对我的模块进行了优化修改,对问题主动解决。此次合作将是一段宝贵经验。

欧 to 王 :对待任务时,始终保持高度的责任感和积极的态度,愿意倾听并接受建议,以确保工作的顺利进行。能够有效地合作,共同解决问题并取得成功。

...全文
48 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

122

社区成员

发帖
与我相关
我的任务
社区描述
FZU-SE
软件工程 高校
社区管理员
  • LinQF39
  • 助教-吴可仪
  • 一杯时间
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧