685
社区成员
这个作业属于哪个课程 | 2023软工W班 |
---|---|
这个作业要求在哪里 | 软工实践——团队编程实战 |
团队名称 | Machine Guard |
这个作业的目标 | 开发一个澳网竞猜平台,为广大体育迷和澳网爱好者提供一个充满趣味和挑战的在线体育竞猜体验。 |
其他参考文献 | 无 |
在终端键入命令git shortlog
,得到项目的按提交者分类的提交日志:
得到:
学号 | 提交次数 |
---|---|
222000321 | 4 |
222000234 | 3 |
222000231 | 13 |
222000320 | 3 |
222000322 | 18 |
222000317 | 8 |
222000318 | 5 |
222000310 | 5 |
为了连接数据库,必须提前使用仓库中的SQL文件恢复到MySQL数据库aoqw
,然后在后端Application.yml
中修改数据库相关字段。Redis端口为默认端口,无密码。
前端修改src\config.ts
中的后端地址构建使用yarn
安装依赖,然后yarn build
构建dist目录,将目录内部置于nginx的html文件夹下。
后端打包成jar
包,然后使用java -jar xxxx.jar
运行。
为了连接数据库,必须提前使用仓库中的SQL文件恢复到MySQL数据库aoqw
,然后在后端Application.yml
中修改数据库相关字段。Redis端口为默认端口,无密码。
前端修改src\config.ts
中的后端地址构建使用yarn
安装依赖,然后yarn dev
运行。
在用户每天第一次登录时,系统将赠送用户100积分。对于没有登录的情况,以及在一天内重复登录的情况,则不赠送积分。
在用户参与竞猜时,立即扣除掉用户的投注的积分。
在用户赢得竞猜时,按下列算法获得积分:
若用户仅赌赢胜队:
若用户也赌赢比分:
/a
进入管理端,不设显式的按钮使用MockPlus实现原型如下:
基于mybatis-plus来实现所有接口对于数据库的增删改查,在配置了相应依赖,连接好数据库之后,进行实体类的创建以及相应mapper接口的定义,再在实现各个接口的service并调用在mapper中定义的方法,来实现数据库的增删改查,然后返回给controller层处理,在controller层中定义对外暴露的接口,通过调用service层中的方法来完成具体的业务逻辑,并将结果返回给前端。
实现了用户的注册登录功能,实现了注册登录接口、短信验证码获取接口。
其中注册实现了短信验证码验证:
首先调用发送短信的接口,生成6位随机数作为验证码,使用腾讯云的sms服务发送短信,并将验证码存入Redis中,之后调用注册接口,先对账号唯一性进行校验,之后通过redis校验手机验证码正确性,最后校验绑定手机号的唯一性(在一定程度上实现一人一号),有一环节出错则返回对应的报错信息,无报错则成功注册。
注册需要提供账户名以及密码。账户名将作为登录名使用。同时还生成了默认的昵称和地址,用户登录之后可以在用户中自行修改。用户登录之后,后端返回token,前端将token保存在localStorage中持久化。
对于需要登录才能查看的界面,前端使用路由拦截,跳转到登录界面。
实现了竞猜投注功能,实现了获取竞猜赛事列表接口以及投注接口。
当用户进入竞猜界面时,根据筛选器的筛选条件调用获取竞猜赛事列表接口,显示对应的赛事,并给出实时赔率。其中获取竞猜赛事列表接口:
在controller层中接收前端传入的格式为
/quiz
的请求,解析Get参数{date}{state}{eventid}
后调用service
层和mapper
层对数据库进行查询,将得到的quiz
实体类转为QuizVO
便于与前端进行交互。其中date为yyyy-MM-dd
格式的字符串,返回指定日期下的竞猜信息;state
为0表示竞猜结果已公开即比赛结束,为1则表示竞猜仍在进行中。
当用户填入比分或选择胜方,并进行提交时,调用投注接口。其中投注接口:
根据用户的投注分数以及用户的选择(猜测比分还是仅猜测获胜队伍),并及时更新数据库表中用户所投注的比赛竞猜的剩余名额,并根据用户投注分数来更新当前用户的剩余分数,具体实现过程为接受前端返回的数据集,使用mybatisplus识别并区分出用户投注内容,在这个过程中,对用户投注的合理性加以辨别和进行异常处理,处理通过后,将数据及时更新并插入的数据库中。
用户登录之后将直接跳转到竞猜模块,每个竞猜模块都包含一个倒计时,提示用户当前竞猜还有多久结束,以此鼓励用户参与竞猜。
当某场比赛竞猜结果公布,且用户有在这场比赛中投注,则短信通知用户结果。
通知模板为:
使用手机验证码验证的形式确保账号与手机号的一一对应关系,一定程度上防止了账户滥用。
实现了积分策略,在用户每天第一次登录时,系统将赠送用户100积分。对于没有登录的情况,以及在一天内重复登录的情况,则不赠送积分。
通过在数据库用户表中添加last_login_time字段实现。当接收到登录请求时,在filter中拦截,并通过账号密码获取用户对象,将用户最后登录时间与当前登录时间进行比较(若最后登录时间为空说明此为用户第一次登录,则直接进行奖励操作并更新时间),若不同则说明此为用户今日第一次登录,修改用户最后登录时间并进行奖励操作,若相同则不进行操作。
用户必须要投注一定的积分才能进行竞猜,参与竞猜即扣除积分。竞猜结果公布之后,根据最后的赔率以及所投积分决定用户获得的奖励积分,并添加到用户积分中。
用户可以查看到自己的积分增添状况,通过获取积分记录表接口得到积分记录表。
积分可以在兑奖中心进行兑奖。
用户在兑奖中心选择心仪的礼品,兑奖发起请求,后端验证积分足够,扣除用户积分并为兑奖表增加一条记录,否则兑换失败。
积分记录表将体现兑奖的奖品以及所花的积分。
有如下公式来确保赔率合理性:
若用户仅赌赢胜队:
若用户也赌赢比分:
实现了管理端。
在前端,只能通过在路径中输入/a
来进入管理端,且进入管理端需要额外登录,登录时请求的接口与用户登录相同,但参数不同,以此来区分管理端或用户端。将token区别于用户端token保存在localStorage中。
管理端实现了两张表:用户兑奖汇总表以及用户积分改变汇总表,分别调用这两张表的接口来以表格形式显示内容,同时还支持筛选用户名关键字。
使用Apifox进行压测。先写好接口描述,然后新增一个测试样例,将接口绑定到测试样例中去。
其中,测试样例分配为16个线程并发,每线程测试100次,1轮,无间隔。运行查看效果。
下面是其中一个接口:获取总表 的压测情况:
具体的功能请参考需求分析及功能实现部分,本节着重讲解界面操作。
在用户初次使用系统时(或者登录状态失效时)跳转到登录界面。在登录界面输入账号密码来登录。新用户可以点击signup跳转到注册页面。
新用户可以进行注册,必须提供账号,密码,重复密码,以及手机号。手机号用于验证账户主唯一性。点击get code按钮可以获取验证码,必须填写正确的验证码才能登录,同时需要手机号唯一且合法,否则不予发送验证码。
登录后进入竞猜主页面,可以通过左侧days选择器选择竞猜比赛的天数,可以点击上方选择器来筛选比赛来自哪个类型的赛事,以及是否正在进行中。
在单个模块,可以填写投入的积分,选择对应的赢家,然后点击submit进行投注。同时,比赛的结果也会在这里显示。
在兑奖页面,用户可以查看自己所持的积分总额,以及查看变化情况。点击礼品的exchange按钮可以选择对应礼品进行兑奖。兑奖之后积分即扣除。
在用户页面,可以查看个人基本信息,登出,以及修改自己的信息。
进入管理端(登录之后),首先跳转到兑奖记录页面,可以查看兑奖记录表,记载了日期,用户名,奖品名,积分。
点击Point Record 跳转到积分变化页面,可以查看积分变化记录表,记载了日期,用户名,变化原因,积分。
学号 | 分工 | 贡献度 |
---|---|---|
222000321 | PM、主要前端开发 | 18% |
222000234 | UI设计、前端菜单栏和首页等功能、博客撰写 | 12% |
222000231 | 数据库和接口设计(竞猜部分)、博客撰写 | 12% |
222000320 | 数据库数据填充、DBA | 5% |
222000322 | 数据库和接口设计(用户、管理员、兑奖),类图 | 20% |
222000317 | 接口文档、数据库和接口(赔率、竞猜) | 12% |
222000318 | 接口文档、数据库和接口(赔率、竞猜) | 11% |
222000310 | 主页、注册、登录前端页面开发 | 10% |
学号 | 困难 | 解决方法 |
---|---|---|
222000321 | 在实现前端的时候,由于过度追求精细化,在具体的实现上常常不能来得及完成,如:对于单个竞猜模块的格式雕琢,以及力图还原原型在主界面、用户界面的美术设计,导致后面的开发进度极具延缓。没有充分地规划好对后端建模的需求,导致数据库设计返工。 | 跳过一些前端精细化的步骤,加快总体开发进度。暂停开发,理清接口的思路和需求,重新确定表的字段的意义。 |
222000234 | 极限编程对我的知识储备来说时间太紧了,挑战很大,为给编码留出足够的时间只能压缩对功能和逻辑设计的时间,导致在开发的时候会因为过于着急和思路混沌导致逻辑设计混乱。 | 这种时候需要让自己停下来,保持冷静,认真分析如何安排功能模块来合理和高效地实现功能、满足需求。 |
222000231 | 1. 竞猜赔率如何计算? 2. 总积分为0时系统会报错? 3. 如何使用mybatis-plus,根据外键同时从多个表中查询数据? | 在队友的帮助下得到的了积分奖赔机制的计算公式;判断系统总积分为0时代表无人投注,故不计算赔率,返回-1作为flag;在Mapper类中手动编写查询方法和@sql注解,建立表的关联视图同时嵌套querywrapper进行查询。 |
222000320 | 对于需求的不明确导致数据库设计的时候很多字段不明确。 | 重新讨论,制定修改计划。 |
222000322 | 如何实现每日上线时赠送积分、 如何实现竞猜结束时分配积分 | 一开始打算通过mysql的定时任务来实现每日积分增加,但发现与需求要求的“签到”模式并不符合,于是决定在用户表中增加一个字段 用于记录用户最后登录时间,在每次调用登录接口时,检查该用户的最后登录时间,若与当前时间不同,则说明用户今日未登录,进行积分奖励并更新最后登录时间,反之不变。 通过@EnableScheduling开启springboot定时任务,用@Scheduled设置定时任务经过固定时间扫描一次竞猜记录表,当发现对应的竞猜结束时,通过用户的竞猜情况对用户的积分进行调整并通过腾讯云sms服务发送短信通知。 |
222000317 | 在导入依赖包时遇到问题,在起初实现自己所负责的接口时,对核心流程不是很熟悉,以及在后面对数据库进行查询时,遇到了语法错误。 | 在网上查资料,解决了依赖的导入问题,在数据查询时,请教队内大佬,通过对敏感字添加``符号,解决了查询过程的语法错误。 |
222000318 | 对如何操作数据库不熟练,许多接口的逻辑都没有弄懂。 | 在队友的耐心指导下以及自己到处查资料,勉强弄懂了业务的逻辑,以及接口的大致逻辑。 |
222000310 | 开发时间紧张, 对于前端部分样式书写存在不熟练的情况, 书写思路不够清晰。 | 通过及时与组员讨论与交流,分析开发流程,理清思路,及时对页面进行修改解决了问题。 |
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 30 |
• Estimate | • 估计这个任务需要多少时间 | 20 | 30 |
Development | 开发 | 460 | 760 |
• Analysis | • 需求分析 (包括学习新技术) | 30 | 20 |
• Design Spec | • 生成设计文档 | 20 | 10 |
• Design Review | • 设计复审 | 10 | 0 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 10 | 5 |
• Design | • 具体设计 | 60 | 140 |
• Coding | • 具体编码 | 240 | 355 |
• Code Review | • 代码复审 | 30 | 70 |
• Test | • 测试(自我测试,修改代码,提交修改) | 60 | 160 |
Reporting | 报告 | 110 | 200 |
• Project Repor | • 项目报告 | 80 | 150 |
• Size Measurement | • 计算工作量 | 20 | 20 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 10 | 30 |
SUM | 总计 | 590 | 990 |
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 53 |
• Estimate | • 估计这个任务需要多少时间 | 30 | 53 |
Development | 开发 | 580 | 742 |
• Analysis | • 需求分析 (包括学习新技术) | 60 | 70 |
• Design Spec | • 生成设计文档 | 20 | 25 |
• Design Review | • 设计复审 | 10 | 15 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 10 | 7 |
• Design | • 具体设计 | 30 | 50 |
• Coding | • 具体编码 | 400 | 510 |
• Code Review | • 代码复审 | 20 | 30 |
• Test | • 测试(自我测试,修改代码,提交修改) | 30 | 35 |
Reporting | 报告 | 50 | 45 |
• Project Repor | • 项目报告 | 20 | 30 |
• Size Measurement | • 计算工作量 | 10 | 5 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 20 | 10 |
SUM | 总计 | 660 | 822 |
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 60 |
• Estimate | • 估计这个任务需要多少时间 | 30 | 60 |
Development | 开发 | 500 | 1080 |
• Analysis | • 需求分析 (包括学习新技术) | 40 | 120 |
• Design Spec | • 生成设计文档 | 20 | 40 |
• Design Review | • 设计复审 | 20 | 40 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 10 | 20 |
• Design | • 具体设计 | 120 | 180 |
• Coding | • 具体编码 | 240 | 440 |
• Code Review | • 代码复审 | 30 | 200 |
• Test | • 测试(自我测试,修改代码,提交修改) | 20 | 40 |
Reporting | 报告 | 40 | 90 |
• Project Repor | • 项目报告 | 20 | 40 |
• Size Measurement | • 计算工作量 | 10 | 20 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 10 | 30 |
SUM | 总计 | 550 | 1230 |
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 20 |
• Estimate | • 估计这个任务需要多少时间 | 20 | 20 |
Development | 开发 | 505 | 1015 |
• Analysis | • 需求分析 (包括学习新技术) | 40 | 50 |
• Design Spec | • 生成设计文档 | 15 | 10 |
• Design Review | • 设计复审 | 20 | 10 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 10 | 5 |
• Design | • 具体设计 | 40 | 220 |
• Coding | • 具体编码 | 300 | 420 |
• Code Review | • 代码复审 | 60 | 200 |
• Test | • 测试(自我测试,修改代码,提交修改) | 20 | 100 |
Reporting | 报告 | 40 | 70 |
• Project Repor | • 项目报告 | 15 | 30 |
• Size Measurement | • 计算工作量 | 10 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 15 | 30 |
SUM | 总计 | 565 | 1105 |
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 30 |
• Estimate | • 估计这个任务需要多少时间 | 20 | 30 |
Development | 开发 | 460 | 855 |
• Analysis | • 需求分析 (包括学习新技术) | 30 | 20 |
• Design Spec | • 生成设计文档 | 20 | 10 |
• Design Review | • 设计复审 | 10 | 0 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 10 | 5 |
• Design | • 具体设计 | 60 | 210 |
• Coding | • 具体编码 | 240 | 410 |
• Code Review | • 代码复审 | 30 | 60 |
• Test | • 测试(自我测试,修改代码,提交修改) | 60 | 140 |
Reporting | 报告 | 110 | 200 |
• Project Repor | • 项目报告 | 80 | 150 |
• Size Measurement | • 计算工作量 | 20 | 20 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 10 | 30 |
SUM | 总计 | 590 | 1085 |
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 25 |
• Estimate | • 估计这个任务需要多少时间 | 20 | 25 |
Development | 开发 | 445 | 645 |
• Analysis | • 需求分析 (包括学习新技术) | 25 | 50 |
• Design Spec | • 生成设计文档 | 20 | 25 |
• Design Review | • 设计复审 | 20 | 15 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 20 | 15 |
• Design | • 具体设计 | 30 | 50 |
• Coding | • 具体编码 | 280 | 440 |
• Code Review | • 代码复审 | 30 | 30 |
• Test | • 测试(自我测试,修改代码,提交修改) | 20 | 20 |
Reporting | 报告 | 38 | 50 |
• Project Repor | • 项目报告 | 8 | 10 |
• Size Measurement | • 计算工作量 | 10 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 20 | 30 |
SUM | 总计 | 503 | 720 |
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 25 |
• Estimate | • 估计这个任务需要多少时间 | 20 | 25 |
Development | 开发 | 435 | 690 |
• Analysis | • 需求分析 (包括学习新技术) | 25 | 40 |
• Design Spec | • 生成设计文档 | 20 | 25 |
• Design Review | • 设计复审 | 20 | 15 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 20 | 15 |
• Design | • 具体设计 | 30 | 50 |
• Coding | • 具体编码 | 260 | 480 |
• Code Review | • 代码复审 | 30 | 45 |
• Test | • 测试(自我测试,修改代码,提交修改) | 30 | 35 |
Reporting | 报告 | 38 | 50 |
• Project Repor | • 项目报告 | 8 | 10 |
• Size Measurement | • 计算工作量 | 10 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 30 | 30 |
SUM | 总计 | 503 | 765 |
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 30 |
• Estimate | • 估计这个任务需要多少时间 | 20 | 30 |
Development | 开发 | 500 | 755 |
• Analysis | • 需求分析 (包括学习新技术) | 30 | 40 |
• Design Spec | • 生成设计文档 | 20 | 30 |
• Design Review | • 设计复审 | 20 | 25 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 10 | 20 |
• Design | • 具体设计 | 60 | 70 |
• Coding | • 具体编码 | 300 | 500 |
• Code Review | • 代码复审 | 30 | 30 |
• Test | • 测试(自我测试,修改代码,提交修改) | 30 | 40 |
Reporting | 报告 | 55 | 80 |
• Project Repor | • 项目报告 | 30 | 45 |
• Size Measurement | • 计算工作量 | 15 | 15 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 10 | 20 |
SUM | 总计 | 575 | 865 |
在本次作业中,本组声明使用超时提交的版本,以及超时提交的博客。
看看严重超出预计时间的PSP,就知道本组在实际的项目编码中出现了极其严重的失误,导致我们不能在规定的时间交出一版满意的项目。就像在23日0点下的一场暴雨,浇灭了我们的心。
当然,希望项目尽善尽美,做出超出基本需求的功能是每个组的心愿。但是时间是严肃的,不会因为梦想的美好而退却半步。因此,在本组沉浸在动手编程,以及遐想到在截止时间前能做出的那个美好的、功能完善的、界面美观的项目时,我们显然对于该项目的需求过于乐观了。
固然,本项目的基础功能是足够平凡的,但是显然,与附加功能以及其他非功能性需求一起考虑时,事情就变得棘手了。在下午的机房中,我们已经意识到了这点,直到最后接受时间截止的事实。再回过头看,核心问题有二。
一是动工前讨论会的缺失。在之前的团队项目中(选题到系统分析),我们总是拿出约半个下午的时间讨论,然后会生成一份《团队工作大纲》,放在腾讯文档的协作空间中。但本次组队却因为对项目的乐观而缺失了,也没有很详细地对需求进行分析,只是简单的进行了一下分工分配。
二是没有足够准确地分清需求的主次。在数据库设计上,我们遇到了比较大的幅度的返工和调整,这是因为我们的一些结构沿袭了之前项目的内容,因为对于项目的基本要求,那是足够的;但是我们把附加功能放在了一个比较中心的位置,也就是积分制度,大部分的接口都要考虑这个内容,因此在设计到积分时,一切都要推翻。
当然,在延后了一天后,大部分的接口都已经实现,前端也能够对接、部署上页面。主要更新在于对积分这个概念的相关控制,包括积分奖励机制,积分签到机制,积分兑换机制,以及一些赛程与赔率相关的计算。博客也几乎重写,尽力完善到上文的程度。
天苍苍,野茫茫,英雄折腰博客处,我奈AO无可为!
这是一次相当深刻的教训。我想AO系列终会过去,也许我们工作之后很少有人能在5、10年之后再想到这个普普通通的AO项目(及其之前的AO项目),但是我想,我们组内的同学应该会永远记得,在开工前的那份不存在的《工作大纲》。
尽管是平凡的需求,涉及到多人协作,开工前的计划依然是必不可少的。希望未来作为leader的你们能够回忆起这一次协作,加油!加油!