结对第二次作业--编程实现
| 这个作业属于哪个课程 | <2023年福大-软件工程实践-W班> |
|---|---|
| 这个作业要求在哪里 | <结对第二次作业> |
| 结对学号 | <222000230 222000329> |
| 这个作业的目标 | <Gitcode的合作使用、原型设计的编码实现> |
| 其他参考文献 | 无 |
目录
- 1、Gitcode仓库链接和代码规范链接
- 1.1 Gitcode仓库地址
- 1.2 代码规范地址
- 2、PSP表格
- 3、项目访问链接
- 4、项目成果展示
- 4.1 主页 (附加功能)
- 4.2 选手排名
- 4.3 每日赛程
- 4.4 详细赛况(附加功能)
- 4.5 晋级图
- 4.6 了解更多(附加功能)
- 5、设计实现过程
- 5.1功能结构图
- 5.2 爬取数据【该行为与数据仅用于学习】
- 5.3 前端实现过程
- 5.4后端实现过程
- 6、结对讨论过程描述
- 7、代码说明
- 8、心路历程和收获
- 9、结对队友互评
1、Gitcode仓库链接和代码规范链接
1.1 Gitcode仓库地址
1.2 代码规范地址
2、PSP表格
| PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 20 | 20 |
| • Estimate | • 估计这个任务需要多少时间 | 20 | 20 |
| Development | 开发 | 840 | 1015 |
| • Analysis | • 需求分析 (包括学习新技术) | 180 | 150 |
| • Design Spec | • 生成设计文档 | 60 | 55 |
| • Design Review | • 设计复审 | 10 | 10 |
| • Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 90 | 110 |
| • Design | • 具体设计 | 60 | 45 |
| • Coding | • 具体编码 | 360 | 480 |
| • Code Review | • 代码复审 | 20 | 15 |
| • Test | • 测试(自我测试,修改代码,提交修改) | 60 | 150 |
| Reporting | 报告 | 220 | 225 |
| • Test Repor | • 测试报告 | 180 | 200 |
| • Size Measurement | • 计算工作量 | 20 | 10 |
| • Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 20 | 15 |
| 合计 | 1080 | 1260 |
3、项目访问链接
4、项目成果展示
4.1 主页 (附加功能)
本次的设计以蓝白灰色调为主,追求简洁明了的界面,使用户对本项目功能的操作更加得心应手。主页上方的导航栏可链接到不同的页面,左侧导航可去往首页的不同位置。
- 首页的“关于澳网”介绍了澳大利亚网球公开赛事,说明了2023澳网赛事的举办时间、举办地点、赛事结果。最后,公布了2023赛事奖金池的分配情况。

- 首页的“精彩瞬间”分为“比赛集锦”和“赛后采访”两大块,让用户能更好地了解比赛、了解选手。“比赛集锦”播放的是选手在赛场上的比赛片段,“赛后采访”播放的是赛后选手接受采访的画面。

- 首页的“场馆介绍”通过文字和图片介绍了澳网的比赛场馆——墨尔本公园网球中心,介绍了场馆的可持续发展举措以及公共交通设施,让人们对澳网有更多的了解。

- 首页的“中国风采”栏目,介绍了中国队过往的战绩、2023澳网赛事的两位中国选手及其表现。

4.2 选手排名
开头使用一张图片介绍Singles Aces Leaders第一名选手的比赛情况,使用户能够快速地获取信息,并在下方的列表中得到其它选手的比赛信息。

4.3 每日赛程
- 在导航栏下方有一系列赛程按钮,点击按钮可以显示当天的赛程信息,点击"<"“>”组件还能进行翻页,功能清晰,用户操作起来更加方便。下图所示的为Day13的数据。(PS:我们做了所有比赛日的每日赛况,从Q1到Q4,从Day1到Day14)

4.4 详细赛况(附加功能)
- 当鼠标移到某场比赛上时,会出现蓝色边框,鼠标变为小手。当用户点击某一具体的比赛时,会跳转到“详细赛况”界面,展示比赛的成绩,包含本场比赛参赛选手,每个小场比分和最终比赛的获胜选手。当点击“←返回”时,会返回至“每日赛程”界面。可在下拉菜单中选择轮数,查看不同set的具体数据。比赛信息一目了然,界面简洁,增强可读性。
- 说明:由于时间与精力问题,我们让每场比赛的详细赛况都一样,即:点击不同天的不同比赛,都会跳转到同样的详细赛况。

4.5 晋级图
当用户点击某一具体的比赛阶段时,即可呈现对应阶段的选手晋级路线。晋级图展示了选手的国籍、姓名与比分,获胜选手的姓名加粗显示,并且有“√”图标。当鼠标移到某场比赛时,会出现蓝色边框。

4.6 了解更多(附加功能)
介绍澳大利亚网球公开赛的举办背景,通过丰富的图文使平台更具吸引力,引起引起人们对澳大利亚网球公开赛的兴趣。

5、设计实现过程
5.1功能结构图

5.2 爬取数据【该行为与数据仅用于学习】
从澳大利亚网球公开赛官网上,找到选手排名、每日赛况等相应页面,利用浏览器的开发者工具,在network中爬取到了本次作业所需的数据。
说明:本次爬取行为和爬取数据仅用于学习!
5.3 前端实现过程
- 技术:Vue框架(Element UI)、axios库
- 界面设计:由于纯打css进行UI设计太过冗杂,所以我们使用了Vue中Element UI的相关组件进行界面的美化设计。
- 后端数据的获取:使用axios库向后端发送请求,后端使用servlet将解析好的json数据传递回前端,前端再将得到的数据赋值给table中各个单元格。
5.4后端实现过程
- 技术:Servlet、Tomcat8、fastjson、commons-io
- 读取json:由于原生的java读取文件过于复杂,所以我们使用了commons-io框架来进行文件读取,提高开发效率。
- 处理json数据、封装对象:利用fastjson框架,轻松快速从读取到的json文件内容中解析出前端页面需要展示的字段,构造球员实体类Player、比赛实体类Match,把这些信息封装成相应的实体类对象。最后,把所有的对象装入List集合并返回。
- 向前端响应数据:为每个前端请求编写一个Servlet,在Servlet中调用AOSearch类中的相应方法,获取List结果集合。用fastjson将List集合转成json数据,并写入Response的响应体中,通过服务器Tomcat把后端数据传递给前端。
6、结对讨论过程描述
由于林雯雯同学在之前就接触过Vue框架、Servlet以及Tomcat的使用,所以我们就决定了使用这几个技术完成项目。
- 在前期的工作中,甘佳欣同学先进行相应技术的学习,然后和林雯雯同学一起使用Vue中的Element UI进行界面的美化设计,由于主页、了解更多这部分的数据不是来自于澳网,所以我们在前期就完成了这两个页面的设计,将数据写在了代码中 。



- 在中期的过程中,林雯雯同学由于熟练掌握Servlet框架的使用,所以她通过后端将爬取到的选手排名数据以及每日赛程进行解析并传递到前端进行显示。

而晋级图部分本来我们也是想要通过后端进行解析的,甘佳欣同学也已经写好了后端的解析数据,但是由于前端的排版布局不像之前的表格按顺序排列下来,所以最终我们还是决定将数据写到代码中。
- 到了后期,我们部署云服务器,刚开始其它的服务器根本访问不了网页,后面甘佳欣同学得到了高人的帮助,将端口进行开放由此才解决。但动态的数据还不能显示,于是我们就一直尝试,最后终于部署成功了!

7、代码说明
- 主页点击侧边导航栏实现局部界面的刷新:使用了a标签和iFrame的配合使用,分别展示了“关于澳网”、“精彩瞬间”、“场馆介绍”、“中国风采”4个方面的内容
<el-container style="height:950px;"> <!--侧边栏--> <el-aside width="200px"> <el-row class="tac"> <el-menu default-active="1" class="el-menu-vertical-demo" background-color="#D3DCE6"> <el-menu-item index="1" > <i class="el-icon-location"></i> <span><a href="about.html" target="aboutFrame" style="text-decoration:none;color:black;">关于澳网</a></span> </el-menu-item> <el-menu-item index="2"> <i class="el-icon-menu"></i> <span slot="title"><a href="moment.html" target="aboutFrame" style="text-decoration:none;color:black;">精彩瞬间</a></span> </el-menu-item> <el-menu-item index="3"> <i class="el-icon-document"></i> <span slot="title"><a href="introduce.html" target="aboutFrame" style="text-decoration:none;color:black;">场馆介绍</a></span> </el-menu-item> <el-menu-item index="4"> <i class="el-icon-setting"></i> <span slot="title"><a href="style.html" target="aboutFrame" style="text-decoration:none;color:black;">中国风采</a></span> </el-menu-item> </el-menu> </el-row> </el-aside> <!--Main--> <el-main> <!-- 默认是about.html内容--> <iframe id="aboutFrame" name="aboutFrame" src="about.html" style="overflow: visible;" scrolling="yes" frameborder="no" width="100%" height="100%"> </iframe> </el-main> </el-container> - 选手排名表格,表格数据与模型进行双向绑定。
<el-row :gutter="20"> <!--男子--> <el-col :span="12"><div class="grid-content"> <div class="title">Men’s Singles Aces <br>Leaders</div> <el-table :data="tableData" stripe style="width: 100%;margin-right: 10px;margin-top: 20px"> <el-table-column prop="name" label="Name" width="180px"> </el-table-column> <el-table-column prop="rank" label="Rank"> </el-table-column> <el-table-column prop="matches" label="Match"> </el-table-column> <el-table-column prop="aces" label="Aces"> </el-table-column> </el-table> </div></el-col> <!--女子--> <el-col :span="12"><div class="grid-content"> <div class="title">Womens’s Singles Aces <br>Leaders</div> <el-table :data="tableData2" stripe style="width: 100%;margin-right: 10px;margin-top: 20px"> <el-table-column prop="name" label="Name" width="180px"> </el-table-column> <el-table-column prop="rank" label="Rank"> </el-table-column> <el-table-column prop="matches" label="Match"> </el-table-column> <el-table-column prop="aces" label="Aces"> </el-table-column> </el-table> </div></el-col> </el-row> </el-main> - 前端利用axios库获取从后端传来的选手排名数据,将表格的数据来源绑定为传来的数据
<script>
new Vue ({
el: "#app",
mounted() {
this.selectMen();
this.selectWomen();
},
data() {
return {
activeIndex: '2',
urlFront: "http://localhost:8081/AOWeb/",
// 男子表格
tableData: [],
// 女子表格
tableData2: []
}
},
methods: {
// 获取男子数据
selectMen() {
axios({
method: "get",
url: this.urlFront + "topPlayersServlet"
}).then(resp=> {
this.tableData = resp.data;
})
},
// 获取女子数据
selectWomen() {
axios({
method: "get",
url: this.urlFront + "topWomPlayersServlet"
}).then(resp=> {
this.tableData2 = resp.data;
})
}
}
})
</script>
后端Servlet框架负责调用AOSearch类中的解析方法,并将数据传回给前端
@WebServlet("/topPlayersServlet") public class TopPlayersServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { AOSearch search = new AOSearch(); List<Player> topPlayers = search.getTopPlayers(0); // 将List集合转为json数据 String json = JSON.toJSONString(topPlayers); //System.out.println(json); // 写数据 response.setContentType("text/json;charset=utf-8"); response.getWriter().write(json); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }使用fastjson解析选手排名json文件
public List<Player> getTopPlayers(int sex) {
// 读取json文件
URL path = this.getClass().getResource("/rank.json");
File file = new File(path.getFile());
String content = "";
List<Player> topPlayers = new ArrayList<>(); // 存放球员数据的集合
try {
content = FileUtils.readFileToString(file); // rank.json文件内容
// 解析数据
// 将json字符串转为JSON对象
JSONObject jsonObject = JSONObject.parseObject(content);
// 获取男、女选手合集
JSONArray rankings = jsonObject.getJSONArray("statistics").getJSONObject(0)
.getJSONArray("rankings");
JSONArray players = rankings.getJSONObject(sex).getJSONArray("players"); // 男(女)选手
// 解析选手
for (int i = 0; i < players.size(); i++) {
JSONObject player = players.getJSONObject(i);
// 获取数据
String id = player.getString("player_id");
Integer matches = player.getInteger("matches");
Integer rank = player.getInteger("rank");
Integer aces = player.getInteger("value");
String name = getTopPlayerName(id, content);
// 封装Player对象
Player topPlayer = new Player();
topPlayer.setId(id);
topPlayer.setMatches(matches);
topPlayer.setAces(aces);
topPlayer.setRank(rank);
topPlayer.setName(name);
topPlayers.add(topPlayer);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return topPlayers;
}
//获取排名前二十的选手的名字
public String getTopPlayerName(String id, String content) {
// 将json字符串转为JSON对象
JSONObject jsonObject = JSONObject.parseObject(content);
// 获取players
JSONArray players = jsonObject.getJSONArray("players");
// 要找的名字
String name = "";
// 遍历,找名字
for (int i = 0; i < players.size(); i++) {
JSONObject player = players.getJSONObject(i);
String uuid = player.getString("uuid");
if (id.equals(uuid)) {
// 找到了
name = player.getString("full_name");
break;
}
}
return name;
}
- 晋级图部分本来我们也要使用前后端分离,但由于此界面的排版布局略复杂,最后还是决定将数据写在代码里。将页面划分成2个div,分别对应页面的左右部分,然后利用float属性将第一个div浮动到左边,第二个div浮动到右边。同时使用table:hover实现鼠标移动到某一场比赛时显示边框提示
table:hover {
border: 2px solid #1184F0;
}
<div style="float:left;">
<div>
<table>
<tr>
<td class="left" style="font-size: 15px; font-weight: bold;padding: 15px 10px 15px 10px;width: 60%">
<img src="img/lan.png" style="float: left">
<span>S.Tsitsipas</span>
</td>
<td class="right" style="font-size: 15px;padding: 15px 10px 15px 0px">
<span style="margin-bottom: 10px;float: right">7 6 6 6</span>
<img src="img/gou.png" style="float: right"></td></tr>
<tr>
<td class="left" style="font-size: 15px;padding: 15px 10px 15px 10px">
<img src="img/jp.png" style="float: left">
<span>K.Khachanov</span>
</td>
<td class="right" style="font-size: 15px;padding: 15px 10px 15px 0px">6 4 7 3</td></tr>
</table>
</div>
<div>
<table>
<tr>
<td class="left" style="font-size: 15px; font-weight: bold;padding: 15px 10px 15px 10px;width: 60%">
<img src="img/yang.png" style="float: left">
<span>N.Djokovic</span>
</td>
<td class="right" style="font-size: 15px;padding: 15px 10px 15px 0px">
<span style="margin-bottom: 10px;float: right">7 6 6</span>
<img src="img/gou.png" style="float: right"></td></tr>
<tr>
<td class="left" style="font-size: 15px;padding: 15px 10px 15px 10px">
<img src="img/jin.png" style="float: left">
<span>T.Paul</span>
</td>
<td class="right" style="font-size: 15px;padding: 15px 10px 15px 0px">5 1 2</td></tr>
</table>
</div>
</div>
<div style="float:right; margin-top:70px;">
<div>
<table>
<tr>
<td class="left" style="font-size: 15px; font-weight: bold;padding: 15px 10px 15px 10px;width: 60%">
<img src="img/yang.png" style="float: left">
<span>N.Djokovic</span>
</td>
<td class="right" style="font-size: 15px;padding: 15px 10px 15px 0px">
<span style="margin-bottom: 10px;float: right">6 7 7</span>
<img src="img/gou.png" style="float: right"></td></tr>
<tr>
<td class="left" style="font-size: 15px;padding: 15px 10px 15px 10px">
<img src="img/lan.png" style="float: left">
<span>S.Tsitsipas</span>
</td>
<td class="right" style="font-size: 15px;padding: 15px 10px 15px 0px">3 6 6</td></tr>
</table>
</div>
</div>
每日赛况 根据前端传来的比赛日期date,解析对应比赛日的json文件,提取出有用的信息并封装为Match对象,将所有Match对象装入List集合中并返回。
public List<Match> getMatches(String date) { // 读取json文件 URL path = this.getClass().getResource("/" + date + ".json"); File file = new File(path.getFile()); String content = ""; // json文件内容 List<Match> dayMatches = new ArrayList<>(); try { content = FileUtils.readFileToString(file); // 日期.json文件内容 // 将json字符串转为JSON对象 JSONObject jsonObject = JSONObject.parseObject(content); // 获取courts数组 JSONArray courts = jsonObject.getJSONObject("schedule").getJSONArray("courts"); JSONObject court = null; JSONArray sessions = null; for (int i = 0, size = courts.size(); i < size; i++) { court = courts.getJSONObject(i); sessions = court.getJSONArray("sessions"); String courtId = court.getString("court_id"); // 比赛场地ID String place = getCourt(courtId, jsonObject);// 获取比赛场地 JSONObject session = null; JSONArray activities = null; for (int j = 0, sessionSize = sessions.size(); j < sessionSize; j++) { session = sessions.getJSONObject(j); activities = session.getJSONArray("activities"); JSONObject activity = null; JSONArray teams = null; JSONObject matchStatus = null; String matchAbbr = null; for (int k = 0, actSize = activities.size(); k < actSize; k++) { activity = activities.getJSONObject(k); if (activity.getString("actual_start_time") != null) { String time = activity.getString("duration");// 获取比赛时间 time = handleTime(time); // 转换比赛时间的格式 teams = activity.getJSONArray("teams"); String winner = getWinner(teams, jsonObject); // 获取胜利者 String loser = getLoser(teams, jsonObject); // 获取失败者 String loserScore = getScoreByflag(teams, jsonObject, 0); // 获取失败者分数 String winScore = getScoreByflag(teams, jsonObject, 1); // 获取获胜者分数 String eventUuid = activity.getString("event_uuid"); String type = getMatchType(eventUuid, content); // 获取比赛类型 // 封装Match对象 Match match = new Match(); match.setTime(time); match.setLoser(loser); match.setWinner(winner); match.setLoserScore(loserScore); match.setWinnerScore(winScore); match.setType(type); match.setPlace(place); dayMatches.add(match); } else { matchStatus = activity.getJSONObject("match_status"); if (matchStatus != null) { matchAbbr = matchStatus.getString("abbr"); if ("W/O".equals(matchAbbr)) { // 弃赛 } } } } } } } catch (IOException e) { throw new RuntimeException(e); } return dayMatches; } public String readMatchInfo(JSONArray courts, JSONObject jsonObject) { String matches = ""; JSONObject court = null; JSONArray sessions = null; for (int i = 0, size = courts.size(); i < size; i++) { court = courts.getJSONObject(i); sessions = court.getJSONArray("sessions"); JSONObject session =null; JSONArray activities = null; for (int j = 0, sessionSize = sessions.size(); j < sessionSize; j++) { session = sessions.getJSONObject(j); activities = session.getJSONArray("activities"); JSONObject activity = null; JSONArray teams = null; JSONObject matchStatus = null; String matchAbbr = null; for (int k = 0, actSize = activities.size(); k < actSize; k++) { activity = activities.getJSONObject(k); if (activity.getString("actual_start_time") != null) { String time = activity.getString("actual_start_time");// 获取比赛时间 teams = activity.getJSONArray("teams"); String winner = getWinner(teams, jsonObject); // 获取胜利者 String loser = getLoser(teams, jsonObject); // 获取失败者 //courtStr += "score:" + getScore(teams, jsonObject) + "\n"; } else { matchStatus = activity.getJSONObject("match_status"); if (matchStatus != null) { matchAbbr = matchStatus.getString("abbr"); if ("W/O".equals(matchAbbr)) { // 弃赛 } } } } } } return matches; } /** * 获取胜利者 * @param teams */ public String getWinner(JSONArray teams, JSONObject jsonObject) { String names = ""; JSONObject team = null; String isWin = null; String teamId = null; for (int i = 0, size = teams.size(); i < size; i++) { team = teams.getJSONObject(i); isWin = team.getString("status"); if ("Winner".equals(isWin)) { // 获取胜者名字 teamId = team.getString("team_id"); names += getNamesByteamId(teamId, jsonObject); return names; } } return names; } /** * 获取失败者 * @param teams */ public String getLoser(JSONArray teams, JSONObject jsonObject) { String names = ""; JSONObject team = null; String isWin = null; String teamId = null; for (int i = 0, size = teams.size(); i < size; i++) { team = teams.getJSONObject(i); isWin = team.getString("status"); if (!"Winner".equals(isWin)) { // 获取胜者名字 teamId = team.getString("team_id"); names += getNamesByteamId(teamId, jsonObject); return names; } } return names; } /** * 根据id找出名字 * @param teamId 队伍id * @param jsonObject 指定比赛日的JSON对象 */ public String getNamesByteamId(String teamId, JSONObject jsonObject) { JSONArray teams = jsonObject.getJSONArray("teams"); ArrayList<String> playersCode = new ArrayList<>(); // 装着players的编号 ArrayList<String> playersName = new ArrayList<>(); // 装着players的名字 // 根据teamID查找队伍 JSONObject team = null; for (int i = 0, size = teams.size(); i < size; i++) { team = teams.getJSONObject(i); if (team.getString("uuid").equals(teamId)) { // 找到了队伍 JSONArray players = team.getJSONArray("players"); for (int j = 0, pSize = players.size(); j < pSize; j++) { playersCode.add(players.getString(j)); } break; } } // 根据球员编号获取球员名字 JSONArray players = jsonObject.getJSONArray("players"); JSONObject player = null; String uuid = null; for (int i = 0, size = playersCode.size(); i < size; i++) { for (int j = 0; j < players.size(); j++) { player = players.getJSONObject(j); uuid = player.getString("uuid"); if (uuid.equals(playersCode.get(i))) { // 找到了 playersName.add(player.getString("short_name")); break; } } } String names = "" + playersName.get(0); for (int i = 1, size = playersName.size(); i < size; i++) { names += " & " + playersName.get(i); } return names; } /** * 将时间格式转换 1:50 ==> 1h50m * @param time * @return */ public String handleTime(String time) { String[] s = time.split(":"); // 1:50 用“:”分割字符串 time = s[0] + "h" + s[1] + "m"; return time; } /** * 根据flag来取分数 0:失败 1:获胜 * @param teams * @param jsonObject * @param flag * @return */ public String getScoreByflag(JSONArray teams, JSONObject jsonObject, int flag) { String score = ""; JSONObject team = null; String isWin = null; for (int i = 0, size = teams.size(); i < size; i++) { team = teams.getJSONObject(i); isWin = team.getString("status"); if ("Winner".equals(isWin) && flag == 1) { // 胜者 JSONArray scoreArray = team.getJSONArray("score"); // 分数数组 for (int j = 0; j < scoreArray.size(); j++) { score += scoreArray.getJSONObject(j).getString("game") + " "; } break; } else if (!("Winner".equals(isWin)) && flag == 0){ // 输 JSONArray scoreArray = team.getJSONArray("score"); // 分数数组 for (int j = 0; j < scoreArray.size(); j++) { score += scoreArray.getJSONObject(j).getString("game") + " "; } break; } } return score; } /** * 根据比赛类型的id找比赛类型 * @param eventUuid * @param content * @return */ public String getMatchType(String eventUuid, String content) { String type = ""; JSONObject jsonObject = JSONObject.parseObject(content); JSONArray events = jsonObject.getJSONArray("events"); for (int i = 0; i < events.size(); i++) { // 根据id寻找比赛类型 JSONObject event = events.getJSONObject(i); if (eventUuid.equals(event.getString("uuid"))) { // 找到了 type = event.getString("name"); return type; } } return type; } /** * 根据比赛场地的id查找比赛场地 * @param courtId * @param jsonObject * @return */ public String getCourt(String courtId, JSONObject jsonObject) { String courtName = ""; JSONArray courts = jsonObject.getJSONArray("courts"); for (int i = 0; i < courts.size(); i++) { // 遍历,根据id查找比赛场地 JSONObject court = courts.getJSONObject(i); if (courtId.equals(court.getString("uuid"))) { // 找到了 courtName = court.getString("name"); return courtName; } } return courtName; }后端获取前端传来的数据 前端将要传递的数据写在url后,以参数的形式传递给后端Servlet。Servlet从请求体Request中获取数据。
// 接收是哪一天的数据 url?date=0116
String date = request.getParameter("date");
- 每日赛况前端 选择不同比赛日 每日赛况默认显示比赛日Q1的信息,当用户点击按钮后,会重置Vue对象中的date数据,并重新向后端发起解析请求,在页面上显示新的数据。
<script>
new Vue ({
el: "#app",
mounted() {
this.selectMatchesByDate();
},
data() {
return {
activeIndex: '3',
urlFront: "http://localhost:8888/AOWeb_war/",
// 比赛日期,默认为Q1
matchDate: 'Q1',
matches: []
}
},
methods: {
// 根据比赛日期发送请求
selectMatchesByDate() {
axios ({
method: "get",
url: this.urlFront + "dayMatchServlet?date=" + this.matchDate
}).then(resp=>{
this.matches = resp.data;
})
},
setMatchDate(newDate) {
this.matchDate = newDate; // 重新设置日期
this.selectMatchesByDate(); // 重新查询
},
jumpToDetail() {
location.href = this.urlFront + "detailMatch.html";
}
}
})
</script>
- 每日赛况前端界面 使用了Vue的栅格布局,将页面在宽度上平均分为三份,达到了每行显示三个表格的效果。使用了Vue的v-for指令,把每个表格与每场比赛进行绑定,循环动态生成所有表格。
<el-row :gutter="40">
<el-col :span="8" :key="index" v-for="(item, index) in matches">
<table @click="jumpToDetail">
<tr><td colspan="2" class="left" style="font-size: 5px;;padding: 5px">{{item.type}}</td></tr>
<tr><td class="left" style="font-size: 5px;padding: 5px">{{item.place}}</td><td class="right" style="font-size: 5px;;padding: 5px">{{item.time}}</td></tr>
<tr><td class="left" style="font-size: 15px; font-weight: bold;padding: 15px 10px 15px 10px;width: 60%">{{item.winner}}</td>
<td class="right" style="font-size: 15px;padding: 15px 10px 15px 0px">
<span style="margin-bottom: 10px;float: right">{{item.winnerScore}}</span>
<img src="img/gou.png" style="float: right"></td></tr>
<tr><td class="left" style="font-size: 15px;padding: 15px 10px 15px 10px">{{item.loser}}</td>
<td class="right" style="font-size: 15px;padding: 15px 10px 15px 0px">{{item.loserScore}}</td></tr>
</table>
</el-col>
</el-row>
- 详细赛况 详细赛况的数据直接写在html代码中,以下代码仅展示其中一个表格的一行数据。
<tr style="border-bottom: 0px">
<td rowspan="2" style="width: 50px;border-right: 0px;border-bottom: 0px"><img src="img/be.svg" width="50px" height="30px" style="margin: 15px 10px"></td>
<td style="border-left: 0px;border-bottom: 0px"><span style="font-weight: bold;font-size: 13px">
Point to Z. Bergs • 1:26</span>
<span style="float: right;font-weight: bold;margin-right: 10px">Game</span>
</td>
</tr>
<tr style="border-top: 0px">
<td style="border-left: 0px;border-top: 0px;font-size: 13px">
J. Jin loses the point with a Backhand Unforced Error
</td>
</tr>
8、心路历程和收获
甘佳欣同学的心路历程和收获:此次作业让我有点
质壁分离。前端设计以及后端数据处理这倒不算什么,主要是Tomcat的配置以及云服务器的部署,由于我的IDEA和同学的不一样导致我的Tomcat也和别人不一样,于是我在配置上就走了很多坑,而由于不熟悉云服务器的部署,一直出现页面无法访问也让我接近崩溃,好在最后都解决了!抛开这些配置问题,本次的作业还是让我收获很多新知识的,如Vue的语法、Element UI的使用、Servlet框架的使用、fastjson的使用(之前作业使用的是Gson)、云服务器的部署以及Tomcat的配置。我觉得coding能力固然重要,发现问题来源,环境的配置也十分重要,希望我以后对于这些问题的处理可以更加从容应对吧!林雯雯同学的心路历程和收获:由于之前已经有了一些Java Web基础,也曾经动手开发过几个简单的小案例,所以这次的作业对我来说是一次检验和巩固。当拿到题目时,我就迅速决定了要用哪些技术,脑海中一下就有了整体项目代码的设计思路与框架,引领着我的队友学习,一点点把项目做出来。本次作业检验了我之前自学的成果,进一步加深了我对这些技术的掌握程度。同时我也体会到了提前自主学习的好处,这些编程基础让我不会手忙脚乱、茫然不知所措,给了我很大的信心与底气。今后,我仍会持续自主学习,以应对未来更加复杂的需求。
9、结对队友互评
甘佳欣 To 林雯雯:林雯雯同学真的真的真的好强!她在很早之前就自学了这些技术,令我十分佩服。在本次作业中,我跟着她学习了很多新的知识(Maven的优点、Vue框架中Element的用法、Servlet的使用、Tomcat的部署、fastjson的使用),真的受益良多,希望以后还有机会和她合作。
林雯雯 To 甘佳欣:甘佳欣同学特别特别特别愿意学习新技术,且学习速度非常之快,让我很是佩服。她学习、做事特别积极,丝毫不拖泥带水,和我的做事风格非常一致,给我的两次结对体验都很舒服。她善于解决问题,由于IDEA版本的不一致,很多问题都是她自己摸索着解决的,值得我学习。
相关推荐
PairProject:W班软件工程实践结对第二次作业仓库
结对第二次作业-顶会热词统计的实现 为了不遗漏作业内容,这里有一个清单检查表方便同学们快速检阅。 fork仓库,和伙伴商讨如何通过github协作/代码规范等 编程实现 功能一,操作爬取的论文列表 功能二,爬取结果分析展示 功能三,爬取论文信息(附加功能,实现有附加分) 其他附加功能 部署 发布发布版本,发起拉取请求 撰写博客,在预先之前提交一份博客 包含作业描述和目录 核对评分标准 上一次结对作业中,大家都和小伙伴完成了原型的设计,那么现在再联合小伙伴动手实现原型中的部分功能吧。采用网络技术来实现原型中的功能。 一,作业内容 1.基础功能 功能1:对已爬取的论文列表进行操作 可对论文列表进行删除; 可对论文列表进行查询详细信息(支持模糊查询,查询结果的展示,排序等功能可自行设计); 功能2:分析已爬取到的论文信息,提取top10个热门领域或热门研究方向 形成如关键字图谱之类直观的查看方式
基于Python语言的P4程序结对作业设计源码
该项目是一款基于Python语言的P4程序结对作业设计源码,总文件量为114个,其中Python源文件57个,JSON配置文件24个,P4配置文件11个,Markdown文档8个,PNG图像文件3个,许可证文件1个,以及多个Makefile文件。该项目旨在通过结对作业的形式,提升编程能力和团队合作精神。
软件工程实践结对作业二.md
软件工程实践结对作业二.md
2020级计算机系软件工程第二次结对编程作业.zip
2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip 2020级计算机系软件工程第二次结对编程作业.zip
结对编程技术与策略pdf
介绍结对编程方法、技术和策略。包括结对编程定义、好处。结对策略与组织方法,存在的问题与注意事项等



