赞
踩
这个作业属于哪个课程 | 软件工程-23年春季学期 |
---|---|
这个作业要求在哪里 | 结对第二次作业–编程实现 |
结对学号 | 222000202陈仕燊、222000212黄志腾 |
这个作业的目标 | 1、fork仓库,和伙伴商讨协作细节等。 2、编程实现。 3、撰写博客 |
其他参考文献 | CSDN、博客园 |
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
• Estimate | • 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 2160 | 2270 |
• Analysis | • 需求分析(包括学习新技术) | 360 | 400 |
• Design Spec | • 生成设计文档 | 60 | 60 |
• Design Review | • 设计复审 | 45 | 40 |
• Coding Standard | • 代码规范(为目前的开发制定合适的规范) | 45 | 30 |
• Design | • 具体设计 | 90 | 60 |
• Coding | • 具体编码 | 1320 | 1500 |
• Code Review | • 代码复审 | 60 | 60 |
• Test | • 测试(接口测试、修改代码、提交修改) | 180 | 240 |
Reporting | 报告 | 140 | 70 |
• Test and use Repor | • 接口、使用报告 | 60 | 10 |
• Size Measurement | • 计算工作量 | 20 | 10 |
• Postmortem & Process Improved Plan | • 事后总结,并提出过程改进计划 | 60 | 60 |
合计 | 650 | 900 |
首页:其中是含有四种图片的轮播图,循环播放赛程期间的热点图片
选手排名:其中两种表格,分别存放选手的Rank、Matches、Aces信息。
每日赛程:里面放在不同日期、不同场地、不同比赛的信息
详细赛况:放在特定比赛的详细信息,并且可以下拉选择不同比赛场次
晋级图:里面存放晋级路线图,并高亮显示获胜者
种子选手:展示未来最具潜力的选手排名。
了解更多:放在有关澳大利亚历史的时间线并配上两张图片,有李娜夺冠照片哦
前期任务分工
css同学有过一定的后端开发经验,并且对项目部署和数据库比较熟悉,所以由css同学负责后端接口设计和编写、数据库设计。因为css同学主动选择了后端,因此hzt同学只能选择前端了,虽然开发经验较少,但是审美比css同学好,所以完全能够胜任前端的任务。
博客和学习资源的分享:
问题交流和解决
//html的部分代码 <div id="app"> <div class="page" v-show="this.$route.meta.index != 5"> <nav class="button"> <a class="el-menu-item" @click="show(1)" :class="index===1? 'active':''">首页</a> <a class="el-menu-item" @click="show(2)" :class="index===2? 'active':''">选手排名</a> <a class="el-menu-item" @click="show(3)" :class="index===3? 'active':''">每日赛程</a> <a class="el-menu-item" @click="show(4)" :class="index===4? 'active':''">晋级图</a> <a class="el-menu-item" @click="show(6)" :class="index===6? 'active':''">了解更多</a> </nav> <div class="tab_content"> <keep-alive> <component :is="comp" v-show="isShow"></component> </keep-alive> </div> </div> </div>
//script的部分代码 methods: { show (value) { if (this.index === value) { this.index = 0 this.isShow = !this.isShow } else { this.index = value this.isShow = true } if (value === 1) this.comp = 'one' if (value === 2) this.comp = 'two' if (value === 3) this.comp = 'three' if (value === 4) this.comp = 'four' if (value === 5) this.comp = 'five' if (value === 6) this.comp = 'six' this.$route.meta.index = 0 } },
<template>
<el-carousel :interval="4000" type="card" class="all_img">
<el-carousel-item v-for="item in imgList" :key="item">
<img :src="item.imgsrc" class="single_img"/>
</el-carousel-item>
</el-carousel>
</template>
// 左滑动 scrollLeft() { const allLength = this.monitorList.length * 120 const boxLength = document.getElementById('list-box').clientWidth if (allLength < boxLength) return const listEl = document.getElementById('list') const leftMove = Math.abs(parseInt(window.getComputedStyle(listEl, null)?.left)) if (leftMove + boxLength - 360 < boxLength) { // 到最开始的时候 listEl.style.left = '0px' } else { listEl.style.left = '-' + (leftMove - 360) + 'px' } }, // 右滑动 scrollRight() { const allLength = this.monitorList.length * 120 const boxLength = document.getElementById('list-box').clientWidth if (allLength < boxLength) return const listEl = document.getElementById('list') const leftMove = Math.abs(parseInt(window.getComputedStyle(listEl, null)?.left)) if (leftMove + boxLength + 360 > allLength) { listEl.style.left = '-' + (allLength - boxLength) + 'px' } else { listEl.style.left = '-' + (leftMove + 360) + 'px' } },
//按钮的监听事件 show (value) { this.num === value ? this.isShow = this.isShow : this.isShow = true this.num = value var _this = this let s = '' if (value >= 4) { console.log(value) let data = value - 4 + 116 let str_data = data.toString() s = '/PairProject/matches?matchType=0' + str_data } else { let data = value + 1 let str_data = data.toString() s = '/PairProject/matches?matchType=Q' + str_data } Axios({ method: 'get', url: s }).then(function (resp) { _this.race_mes = resp.data console.log(resp.data) }) },
//跳转页面
goNavbar (value) {
this.$router.push({ path: '/navbar' })
console.log(value)
}
//router配置
{
path: '/navbar',
name: 'navbar',
component: () => import('@/components/navbar.vue'),
meta: {
index: 5,
showFooter: false
}
}
//数据获取
created () {
if (this.$route.meta.index === 5) {
this.num++
this.comp = 'five'
}
}
//界面显示
<div class="page" v-show="this.$route.meta.index == 5 && num == 0">
<div class="tab_content">
<keep-alive>
<component :is="later" v-show="isShow"></component>
</keep-alive>
</div>
</div>
/** * 根据已有的json文件获取选手数据并写入到数据库中 * @param filePath 选手json数据文件路径 * @throws IOException */ public static void getPlayersResult(String filePath) throws IOException { SqlSessionFactory factory = SqlSessionFactoryUtil.getSqlSessionFactory(); SqlSession sqlSession = factory.openSession(); Mapper mapper = sqlSession.getMapper(Mapper.class); String json = fileToJson(filePath); int id = 1; Map playerMap = JSON.parseObject(json, Map.class); List<HashMap> playerMapList = (List<HashMap>) playerMap.get("players"); for (HashMap map : playerMapList) { String uuid = (String) map.get("uuid");//获取选手信息 String fullName = (String) map.get("full_name"); String shortName = (String) map.get("short_name"); String gender = (String) map.get("gender"); Random random = new Random(); Integer ranking = getPlayerRanking(gender, (List<HashMap>) map.get("rankings")); int randomInt = 90 - ranking * (1 + random.nextInt(1)); int ace = ranking != 0 && randomInt > 0 ? randomInt : 0; int matches = 2 + random.nextInt(6); String nationality = (String) ((HashMap) map.get("nationality")).get("name"); String url = (String) ((HashMap) ((HashMap) map.get("nationality")).get("flag")).get("url");//处理国籍的url int index = url.lastIndexOf("/")+1; String nationalityUrl = url.substring(index, index+2); String profileUrl = map.get("image") != null ? (String) ((HashMap) map.get("image")).get("url") : " "; Player player = new Player(id++, uuid, fullName, shortName, gender, ranking, ace, matches, 0, nationality, nationalityUrl, profileUrl); System.out.println(player); mapper.addPlayer(player); } sqlSession.commit(); sqlSession.close(); getTeamResult(filePath); }
/** * 根据已有的json文件获取比赛数据并写入到数据库中 * @param matchType 比赛类型,Q1-Q4,Day1-Day14,draw等 * @throws IOException */ static public void getMatchesResult(String matchType) throws IOException { SqlSessionFactory factory = SqlSessionFactoryUtil.getSqlSessionFactory(); SqlSession sqlSession = factory.openSession(); Mapper mapper = sqlSession.getMapper(Mapper.class); String filePath = "src/main/data/schedule/" + matchType + ".json"; Map matchMap = JSON.parseObject(fileToJson(filePath), Map.class); List<HashMap> matchMapList = (List<HashMap>) matchMap.get("matches"); List<HashMap> roundMapList = (List<HashMap>) matchMap.get("rounds"); List<HashMap> courtMapList = (List<HashMap>) matchMap.get("courts"); List<HashMap> eventMapList = matchMap.get("events") == null ? Arrays.asList((HashMap) matchMap.get("event")) : (List<HashMap>) matchMap.get("events"); int id = 1; for (HashMap map : matchMapList) { String matchName = getValueByMap((String) map.get("event_uuid"), eventMapList);//获取比赛名字、比赛场地、轮次信息、比赛状态 String matchCourt = getValueByMap((String) map.get("court_id"), courtMapList); String roundName = getValueByMap((String) map.get("round_id"), roundMapList); String matchStatus = (String) ((HashMap) map.get("match_status")).get("name"); List<HashMap> teamList = (List<HashMap>) map.get("teams"); HashMap teamAMap = teamList.get(0), teamBMap = teamList.get(1); String teamAUuid = (String) teamAMap.get("team_id");//获取A、B、胜利队伍的id,比赛开始时间、持续时间 String teamBUuid = (String) teamBMap.get("team_id"); String winnerTeamUuid = teamList.get(0).get("status") != null ? teamAUuid : teamBUuid; String actualStartTime = (String) map.get("actual_start_time"); String duration = (String) map.get("duration"); List<HashMap> scoresAMap = (List<HashMap>) teamAMap.get("score");//获取A、B队分数 List<HashMap> scoresBMap = (List<HashMap>) teamBMap.get("score"); String scoresA = "", scoresB = ""; for (int j = 0; j < scoresAMap.size(); j++) { HashMap gameA = scoresAMap.get(j); HashMap gameB = scoresBMap.get(j); scoresA = scoresA + gameA.get("game") + "|"; scoresB = scoresB + gameB.get("game") + "|"; } mapper.addMatch(new Match(id++, matchName, matchStatus, matchCourt, matchType, actualStartTime, duration, teamAUuid, teamBUuid, winnerTeamUuid, scoresA, scoresB, roundName)); } sqlSession.commit(); sqlSession.close(); }
/** * 根据已有的json文件获取组队数据并写入到数据库中 * @param filePath * @throws IOException */ public static void getTeamResult(String filePath) throws IOException { SqlSessionFactory factory = SqlSessionFactoryUtil.getSqlSessionFactory(); SqlSession sqlSession = factory.openSession(); Mapper mapper = sqlSession.getMapper(Mapper.class); String json = fileToJson(filePath); int id = 1; Map teamMap = JSON.parseObject(json, Map.class); List<HashMap> teamMapList = (List<HashMap>) teamMap.get("teams"); for (HashMap map : teamMapList) { String teamUuid = (String) map.get("uuid"); String seedString = map.get("seed") != null && !map.get("seed").equals("")? (String) map.get("seed") : "0"; Integer seed = map.get("seed") != null ? Integer.parseInt(seedString) : 0; ArrayList<String> teamPlayerList = (ArrayList<String>) (map.get("players")); for (String playerUuid : teamPlayerList) { mapper.addTeamRecord(new TeamRecord(id++, teamUuid, playerUuid, seed)); if(teamPlayerList.size() == 1)mapper.updatePlayerSeed(playerUuid, seed); } } sqlSession.commit(); sqlSession.close(); }
/** * match是用于数据库数据写入用的,传给前端的数据需要转换为AOMatch来实现数据的封装 * @param match */ public AOMatch(Match match) { this.matchName = match.getMatchName(); this.matchType = match.getMatchType(); this.matchStage = match.getRoundName(); this.matchLocation = match.getMatchCourt(); this.duration = match.getDuration(); this.winner = match.getWinnerTeamUuid().equals(match.getTeamAUuid()) ? 1 : 0; this.scoresA = new ArrayList<>(); this.scoresB = new ArrayList<>(); this.teamA = new ArrayList<>(); this.teamB = new ArrayList<>(); String[] resA = match.getScoresA().split("\\|"); for (String str : resA) { if(str.matches("-?[0-9]+(\\\\.[0-9]+)?")) { this.scoresA.add(Integer.parseInt(str)); } } String[] resB = match.getScoresB().split("\\|"); for (String str : resB) { if(str.matches("-?[0-9]+(\\\\.[0-9]+)?")) { this.scoresB.add(Integer.parseInt(str)); } } SqlSessionFactory factory = SqlSessionFactoryUtil.getSqlSessionFactory(); SqlSession sqlSession = factory.openSession(); Mapper mapper = sqlSession.getMapper(Mapper.class); teamA = mapper.selectPlayersByTeam(match.getTeamAUuid()); teamB = mapper.selectPlayersByTeam(match.getTeamBUuid()); sqlSession.close(); }
/** * 根据参数值返回选手数据 * @param gender,值为M表示返回男性,值F表示返回女性,默认按ranking排序 * @param seed,true表示按seed排序 * @throws ServletException * @throws IOException */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setHeader("Access-Control-Allow-Origin", "*"); resp.setHeader("Access-Control-Allow-Methods", "*"); String gender = req.getParameter("gender"); String seed = req.getParameter("seed"); SqlSessionFactory factory = SqlSessionFactoryUtil.getSqlSessionFactory(); SqlSession sqlSession = factory.openSession(); Mapper mapper = sqlSession.getMapper(Mapper.class); List<Player> players = new ArrayList<>(); List<Player> res = new ArrayList<>(); if (gender == null || gender.length() == 0) players = mapper.selectPlayerAll(); else if (gender.equals("M")) { if(seed != null && seed.equals("true")) players = mapper.selectMalePlayersOrderedBySeeds(); else players = mapper.selectMalePlayersOrderedByRanking(); } else if (gender.equals("F")) { if(seed != null && seed.equals("true")) players = mapper.selectFemalePlayersOrderedBySeeds(); else players = mapper.selectFemalePlayersOrderedByRanking(); } sqlSession.close(); if(seed != null && seed.equals("true")) { for(int i=0; res.size() < 20 && i <players.size() ; i++) { if(res.size() == 0) { res.add(players.get(i)); continue; } if(res.get(res.size()-1).getSeeds() != players.get(i).getSeeds()) res.add(players.get(i)); } } else { for(int i=0 ; i<50; i++) res.add(players.get(i)); } String jsonString = JSON.toJSONString(res); resp.getWriter().write(jsonString); }
/** * 根据参数值返回比赛数据 * @param matchType 可能取值为Q1-Q4,0116-0129,draws * @param roundName 表示轮次 * @throws IOException */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setHeader("Access-Control-Allow-Origin", "*"); resp.setHeader("Access-Control-Allow-Methods", "*"); SqlSessionFactory factory = SqlSessionFactoryUtil.getSqlSessionFactory(); SqlSession sqlSession = factory.openSession(); Mapper mapper = sqlSession.getMapper(Mapper.class); String matchType = req.getParameter("matchType"); String roundName = req.getParameter("roundName"); ArrayList<Match> matchArrayList = mapper.selectMatchesByCondition(matchType, roundName); HashMap<String, ArrayList<AOMatch>> hashMap = new HashMap<>(); for(Match match : matchArrayList) { if(hashMap.containsKey(match.getMatchCourt())) { hashMap.get(match.getMatchCourt()).add(new AOMatch(match)); } else { hashMap.put(match.getMatchCourt(), new ArrayList<>()); } } ArrayList<HashMap> hashMapArrayList = new ArrayList<>();//根据前端的需求改写返回的数据组织结构 for(String key: hashMap.keySet()) { HashMap<String, Object> stringHashMap = new HashMap<>(); stringHashMap.put("matchLocation", key); stringHashMap.put("matches",hashMap.get(key)); hashMapArrayList.add(stringHashMap); } String jsonString = JSON.toJSONString(hashMapArrayList); resp.getWriter().write(jsonString); }
/** * 根据晋级关系和轮次顺序获取晋级图数据,并返回给前端 * @throws IOException */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setHeader("Access-Control-Allow-Origin", "*"); resp.setHeader("Access-Control-Allow-Methods", "*"); SqlSessionFactory factory = SqlSessionFactoryUtil.getSqlSessionFactory(); SqlSession sqlSession = factory.openSession(); Mapper mapper = sqlSession.getMapper(Mapper.class); Match finalMatch = mapper.selectDrawsMatchByCondition("", MyUtil.rounds.get(0)); ArrayList<ArrayList<Match>> matchArrayLists = new ArrayList<>(); ArrayList<ArrayList<AOMatch>> aoMatchArrayLists = new ArrayList<>(); matchArrayLists.add(new ArrayList<>()); aoMatchArrayLists.add(new ArrayList<>()); matchArrayLists.get(0).add(finalMatch); aoMatchArrayLists.get(0).add(new AOMatch(finalMatch)); //根据晋级关系和轮次顺序获取晋级赛图数据 int roundCnt= 0; while(roundCnt < MyUtil.rounds.size() - 1) { matchArrayLists.add(new ArrayList<>()); aoMatchArrayLists.add(new ArrayList<>()); for(Match match : matchArrayLists.get(roundCnt)) { String teamAuuid = match.getTeamAUuid(); String teamBuuid = match.getTeamBUuid(); Match match1 = mapper.selectDrawsMatchByCondition(teamAuuid, MyUtil.rounds.get(roundCnt+1)); Match match2 = mapper.selectDrawsMatchByCondition(teamBuuid, MyUtil.rounds.get(roundCnt+1)); matchArrayLists.get(roundCnt+1).add(match1); matchArrayLists.get(roundCnt+1).add(match2); aoMatchArrayLists.get(roundCnt+1).add(new AOMatch(match1)); aoMatchArrayLists.get(roundCnt+1).add(new AOMatch(match2)); } roundCnt++; } Collections.reverse(aoMatchArrayLists); String jsonString = JSON.toJSONString(aoMatchArrayLists); resp.getWriter().write(jsonString); }
222000202同学对222000212队友的评价: hzt同学开发项目时时积极负责,能够及时完成任务,基本实现了所有项目需求。遇到问题时都会及时解决,如果遇到了解决不了的问题也会和我交流讨论,如果有需求变化也会及时和我说。我指出他的一些问题他也会及时改正,提出的建议也会虚心接受,进步速度很快。虽然这次作业的工作量很大,但是他也没有抱怨。希望他能够通过这次作业能力有所提升,继续打磨自己的编码水平。期待与他的下次合作。
222000212同学对222000202队友的评价: 此次解决过程中,css同学发挥了相对关键的作用。在过程中,他会经常性对我的前端设计提出正确性的建议,在不懂或不会的地方也会提供我思路,我们也经常进行交流,发现他对待作业的态度十分认真,对于一些细节上的实现也会严格对待,争取把结对作业做到最好,我十分庆幸此次作业与他合作,他真的帮助我许多。最后还是那句话,这个结对,没有他就不行了呀。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。