团队作业(二)
1.概述
1.1开发背景
每到统计活动分的时候,都会给各各班级的学生干部带来麻烦,每次问道你获得了哪些奖项,什么时候获得的,获奖的等级等等诸如此类的问题,给统计活动分的学生干部带来麻烦,以至于导致再上活动分时出现错报,重报,漏报等问题出现。还有有的学生时刻关系自己的活动分是多少却不知到去哪查询。从而造成很多不必要的麻烦。
1.2开发目标
将统计活动分的实现交给计算机来完成,缩短班干部活动分的统计时间,将上报活动分的责任由学生个人承担,从而减少由班干部上报活动分时产生意外。
1.3参考资料
1.4设计原则
2.需求分析
2.1需求陈述
本系统为活动分管理系统,用户群体是普通大学生,学生干部,和学籍管理人员。从功能上看,该系统应当实现用户管理,普通学生活动分申报,学生干部审批、批量导入活动分等功能,学期末自动统计汇总等功能。
1)信息管理
录入,修改,查询
2)普通用户
简介,申报,密码管理
3)管理员用户
简介,审批,密码管理
4)统计汇总
系统自动计算每位用户的活动分,并保存,期末管理员可以将全面所有同学的活动分批量导出成xls格式,方便统计。
2.2操作用例
2.3功能分析划分
2.3.1系统登录
本系统的登陆界面如下图,本系统在登录时通过用户获得的权限不同在登录后,所获得的服务不同。
当用户点击登录按键(GO)时,此时用户编号的文本框和密码输入框为空就会在下方产生相应的提示。
因为登陆的学生编号为我们学校用的编号,所以不能出现英文单词等非数字的字符出现,当输入的用户编号出现非数字字符时,则会提示出相应的提示。
当用户的编号和密码符合输入的规则但是从数据中没有该用户,所以调到错误提示页面。
2.3.2用户管理
当登录的用户权限时普通用户时登录到的页面上显示的服务有个人信息查询,活动分查询,奖项类加分申报,活动分争议。此页面为个人信息查询页面,登录用户登录时首先显示的页面如下如,此页面仅仅显示当前用户的基本信息和活动分的获得。
当点击活动分查询时,显示页面如图2.3.2.2,,在查询的文本框中输入相应的班级号(或相应的学生编号)则显示相应的查询结果。当输入的班级编号(或学生编号)不存在时则显示没有该用户。
奖项类加分申报则是用户申报活动分的页面,用户输入自己的获奖名称,获奖时间等一系列的信息点击提交则将信息添加到数据库中。
当申请用户列表的时候,当一个或多个文本框为空的时候则提出相应的提示则表当不进行提交。如下图
用户的最后一个功能是活动分争议的功能,该功能是当学生在进行活动分的查询的时候,浏览到自己或其他人的活动分发生上报错误,上报遗漏等问题时,通过该功能与管理员进行及时的沟通,防止最后上报活动分产生歧义
2.3.3管理员界面
本程序的管理员界面的功能和普通用户的界面相似,但是管理员的功能比普通用户的功能多一个上活动分的功能,当管理员登录到界面时,点击管理员界面会出现没有上分的学生姓名,活动分的名称等信息,当管理员给每一个活动分上完分后,自动将该活动分从管理员的界面中删除。如图
2.4运行环境
3.总体设计
3.1系统建模
3.1.1 层次方框图
3.1.2 ER图
3.2接口设计
3.2.1内部接口设计
public class StudentServiceImpl implements StudentService {
@Override
//学生注册
public void addStudent(Student student) {
Reader reader = null;
try{
reader = Resources.getResourceAsReader("sqlMapConfig.xml");
SqlSessionFactory sessionfactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sessionfactory.openSession();
StudentDao sdao = session.getMapper(StudentDao.class);
sdao.addStudent(student);
session.commit();
}
catch(IOException e){
e.printStackTrace();
}
}
@Override
//学生登陆
public Student loginStudent(String name, String password) {
Reader reader = null;
Student stu =null;
try{
reader = Resources.getResourceAsReader("sqlMapConfig.xml");
SqlSessionFactory sessionfactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session= sessionfactory.openSession();
StudentDao sdao = session.getMapper(StudentDao.class);
stu= new Student();
Map<String,Object> map = new HashMap<String,Object>();
map.put("username", name);
map.put("password", password);
stu = sdao.loginStudent(map);
session.commit();
}catch(IOException e)
{
e.printStackTrace();
}
return stu;
}
@Override
//查询学生信息
public PageInfo<StudentVo> pageStudent(Student student, Integer pageNum) {
Reader reader = null;
PageInfo<StudentVo> page = null;
List<StudentVo>stulist =null;
try{
reader = Resources.getResourceAsReader("sqlMapConfig.xml");
SqlSessionFactory sessionfactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session= sessionfactory.openSession();
StudentDao sdao = session.getMapper(StudentDao.class);
PageHelper.startPage(pageNum,ConstantUtil.PAGE_SIZE);
if(!("管理员".equals(student.getPermission()))||student.getPermission()==null)
{
stulist = sdao.stuList(student) ;
}
else
{
stulist = sdao.stuListc(student);
}
page = new PageInfo<StudentVo>(stulist);
System.out.println(page);
session.commit();
}catch(IOException e)
{
e.printStackTrace();
}
System.out.println();
return page;
}
//添加申请信息
public void insertStudent(StudentVo student) {
Reader reader = null;
try{
reader = Resources.getResourceAsReader("sqlMapConfig.xml");
SqlSessionFactory sessionfactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session= sessionfactory.openSession();
StudentDao sdao = session.getMapper(StudentDao.class);
sdao.insertStudent(student);
sdao.insertStudentc(student);
session.commit();
}catch(IOException e)
{
e.printStackTrace();
}
}
//判断该学生是否存在
public Student isStudent(String name, String password) {
Reader reader = null;
Student stu =null;
try{
reader = Resources.getResourceAsReader("sqlMapConfig.xml");
SqlSessionFactory sessionfactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session= sessionfactory.openSession();
StudentDao sdao = session.getMapper(StudentDao.class);
stu= new Student();
Map<String,Object> map = new HashMap<String,Object>();
map.put("username", name);
map.put("password", password);
stu = sdao.isStudent(map);
session.commit();
}catch(IOException e)
{
e.printStackTrace();
}
return stu;
}
//将学生信息插入到数据库
public void insertScore(StudentVo student) {
Reader reader = null;
Student stu =null;
try{
reader = Resources.getResourceAsReader("sqlMapConfig.xml");
SqlSessionFactory sessionfactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session= sessionfactory.openSession();
StudentDao sdao = session.getMapper(StudentDao.class);
sdao.insertSocre(student);
sdao.delectInsertSocre(student);
session.commit();
}catch(IOException e)
{
e.printStackTrace();
}
}
//批量更新所有活动分数
public void insertAllScore(List<StudentVo> list) {
Reader reader = null;
try{
reader = Resources.getResourceAsReader("sqlMapConfig.xml");
SqlSessionFactory sessionfactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session= sessionfactory.openSession();
StudentDao sdao = session.getMapper(StudentDao.class);
sdao.insertConnect(list);
sdao.insertAllScore();
sdao.delectAllScore();
sdao.delectAllStudentapplyc(list);
session.commit();
}catch(IOException e)
{
e.printStackTrace();
}
}
//显示该学生的总活动分
public int showAllScore(StudentVo student) {
Reader reader = null;
Integer allScore=0;
try{
reader = Resources.getResourceAsReader("sqlMapConfig.xml");
SqlSessionFactory sessionfactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session= sessionfactory.openSession();
StudentDao sdao = session.getMapper(StudentDao.class);
allScore=sdao.showAllScore(student);
if(allScore==null)
{
allScore = 0;
}
session.commit();
}catch(IOException e)
{
e.printStackTrace();
}
return allScore;
}
//添加争议材料
public void showArgue(ArgueData data) {
Reader reader = null;
try{
reader = Resources.getResourceAsReader("sqlMapConfig.xml");
SqlSessionFactory sessionfactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session= sessionfactory.openSession();
StudentDao sdao = session.getMapper(StudentDao.class);
sdao.showArgueData(data);
session.commit();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
3.2.2登录界面设计
<!DOCTYPE html>
<html>
<head>
<base href="<%=basePath%>"/>
<meta charset="utf-8">
<title>登陆页面</title>
<meta name="keywords" content="">
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link href="public/css/base.css" rel="stylesheet" type="text/css">
<link href="public/css/login.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="login">
<form action="/DradeP/Login.do" method="post" id="form" onsubmit="return checkSubmit()">
<div class="logo"></div>
<div class="login_form">
<div class="user">
<input class="text_value" name="username" type="text" id="username" AutoComplete="off" placeholder="请输入学生编号"/>
<input class="text_value" value="" name="password" type="password" id="password" AutoComplete="off" placeholder="请输入密码"/>
</div>
<button class="button" id="showsubmit" type="submit">登录</button>
<a href="register.jsp"><font color="#FFFFFF" size="+1">注册</font></a>
</div>
<div id="tip">
<br/>
<h2></h2>
</div>
<div class="foot">
</div>
</form>
</div>
<script src="js/jquery-1.9.1.js"></script>
<script src="js/jquery.validate.min.js"></script>
<script src="js/additional-methods.js"></script>
<script>
$(document).ready(function(){
$("#useradvise").hide();
$("#passwd").hide();
});
</script>
<script>
$("#username").mouseover(function(){
$("#username").attr("placeholder","");
});
$("#username").mouseout(function(){
$("#username").attr("placeholder","请输入学生编号");
});
</script>
<script>
$("#password").mouseover(function(){
$("#password").attr("placeholder","");
});
$("#password").mouseout(function(){
$("#password").attr("placeholder","请输入密码");
});
</script>
<script>
$(document).ready(function(){
$("#form").validate({
rules:{
username:{required:true},
password:{required:true},
},
messages:{
username:{required:"学生的编号不能为空<br/>"},
password:{required:"学生的密码不能为空<br/>"},
},
errorPlacement: function(error, element) {
error.appendTo("h2");
},
});
});
</script>
<script>
function checkSubmit()
{
var reg =new RegExp("^[0-9]*$");
var username = $("#username").val();
if(!reg.test(username))
{
$("h2").html("学生编号的位置上输入数字<br/>");
return false;
}
return true;
}
</script>
</body>
</html>
3.3数据库设计
名称 | 类型 | 长度 | 小数点 | 不是null | 主键 |
---|---|---|---|---|---|
id | int | 100 | 0 | 不是 | 是 |
studentName | varchar | 100 | 0 | 不是 | 不是 |
password | varchar | 100 | 0 | 不是 | 不是 |
studentID | varchar | 100 | 0 | 不是 | 不是 |
classID | varchar | 100 | 0 | 不是 | 不是 |
activityDate | varchar | 100 | 0 | 不是 | 不是 |
activityEvent | varchar | 100 | 0 | 不是 | 不是 |
arrangement | varchar | 100 | 0 | 不是 | 不是 |
level | varchar | 100 | 0 | 不是 | 不是 |
permission | varchar | 100 | 0 | 不是 | 不是 |
3.4出错处理
用户登录时输入的内容有错误时则会产生相应的提示,或者提跳转到错误提示界面进行提示。
3.5安全保密设计
虽然本次没有对数据进行安全保密的处理,但打算在登录界面添加验证码的添加,在将数据传入数据库时对数据进行加密处理。
4.详细设计
4.1程序活动图
4.2伪代码编写
5.实现
5.1编码
5.1.1 代码编写原则
1)在定义POJO类时,成员变量定义为私有,通过成员函数进行操作。
2)在编写代码时,缩进通过使用tab键进行缩进。
3)在代码的某些节点处表明相应的注释,方便以后回忆。
4)在定义service层时,写service的实现类时,顺便写一个相应类的抽象的接口。
5.3测试结果和总结
<!DOCTYPE html>
<html>
<head>
<base href="<%=basePath%>"/>
<meta charset="utf-8">
<title>登陆页面</title>
<meta name="keywords" content="">
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link href="public/css/base.css" rel="stylesheet" type="text/css">
<link href="public/css/login.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="login">
<form action="/DradeP/Login.do" method="post" id="form" onsubmit="return checkSubmit()">
<div class="logo"></div>
<div class="login_form">
<div class="user">
<input class="text_value" name="username" type="text" id="username" AutoComplete="off" placeholder="请输入学生编号"/>
<input class="text_value" value="" name="password" type="password" id="password" AutoComplete="off" placeholder="请输入密码"/>
</div>
<button class="button" id="showsubmit" type="submit">登录</button>
<a href="register.jsp"><font color="#FFFFFF" size="+1">注册</font></a>
</div>
<div id="tip">
<br/>
<h2></h2>
</div>
<div class="foot">
</div>
</form>
</div>
<script src="js/jquery-1.9.1.js"></script>
<script src="js/jquery.validate.min.js"></script>
<script src="js/additional-methods.js"></script>
<script>
$(document).ready(function(){
$("#useradvise").hide();
$("#passwd").hide();
});
</script>
<script>
$("#username").mouseover(function(){
$("#username").attr("placeholder","");
});
$("#username").mouseout(function(){
$("#username").attr("placeholder","请输入学生编号");
});
</script>
<script>
$("#password").mouseover(function(){
$("#password").attr("placeholder","");
});
$("#password").mouseout(function(){
$("#password").attr("placeholder","请输入密码");
});
</script>
<script>
$(document).ready(function(){
$("#form").validate({
rules:{
username:{required:true},
password:{required:true},
},
messages:{
username:{required:"学生的编号不能为空<br/>"},
password:{required:"学生的密码不能为空<br/>"},
},
errorPlacement: function(error, element) {
error.appendTo("h2");
},
});
});
</script>
<script>
function checkSubmit()
{
var reg =new RegExp("^[0-9]*$");
var username = $("#username").val();
if(!reg.test(username))
{
$("h2").html("学生编号的位置上输入数字<br/>");
return false;
}
return true;
}
</script>
</body>
</html>
本测试以登陆界面为例:
测试方法为白盒测试
1)当登录的页面中账号或密码中有一项货两项没有填时则在下方进行相应的提示。(测试用例:学生编号:(空) 密码:(空))
2)当用户的账号输入了非法的字符时则,进行相应的提示。。(测试用例:学生编号:asdfgh 密码:123456)
3)当用户输入的学生不存在时,则跳转到错误提示界面给出相应的提示,并返回到登录界面。(测试用例:学生编号:111111 密码:123456)
4)当用户没有登陆,直接输入index.jsp页面,则网页跳转到错误提示页面,给出相应的提示,并返回到登录页面。
6维护
6.1维护方法
1)在开发过程中要生成100%可靠无误的软件通常是不太现实的,但通过使用一些新技术,可以大大减少进行改正性维护的需要
2)进行配置管理。把硬件、操作系统和其他相关环境因素的可能变化进行配置管理。修改局部化。把因环境变化而必须修改的程序局部于某些程序模块中。使用例行程序包等。例如使用内部程序列表等,可为维护性修改程序提供方便。
3)使用功能强且易于使用的工具和通过用户使用系统原型模型完整地确定系统需求等可以减少完善性维护的工作量。
4)可通过采用提前实现或软件重用等手段或技术来减少此类维护活动的工作量。
5)可通过提供最新用户文档或联机用户文档,进行适当的用户培训或设立专门的维护人员等方式来减少此类维护活动。
6.2维护文档
6.3功能拓展
1)在登陆的页面下方在多添加一个文本框用于增加网站的安全性。
功能的接口 boolean IdentifyingCodeServer(String code);
2)给予普通用户申请管理员的功能。
功能的接口 boolean ApplicationManager(Student student);
3) 管理员增加将上完活动分的表当从数据库中导出(以Excel的格式输出)
功能的接口 void DisplayAllScore();