项目场景:
项目名称:校园兼职平台
需求说明:
1)本平台根据角色定位不同有不同的模块,首先系统有一个登录注册模块,属于兼职人员的模块有个人信息管理和兼职申请;属于管理员的模块有基本信息维护、兼职信息投放和系统管理。
2)平台登录注册:
用户可以通过账号密码登录平台,如果用户是第一次使用该平台,则可以通过注册方式完成信息录入。==平台根据用户输入的账号密码,判断该用户的角色是兼职人员还是管理员,展示不同的操作界面。==如果用户忘记密码,可以通过自己的账号和注册时录入的真实姓名找回密码。
3)兼职人员–>个人信息管理:
能够对用户的基本信息进行管理,包括个人信息的修改,如学生转到别的专业,此时要修改学生的基本信息;
修改密码,为了账户的安全性,可以修改用户的密码。
查询信用等级,比如有一个用户一开始可以完成兼职等级最高的工作,但是在这次工作中,未能按时完成工作,于是管理员降低了该用户的信用等级,该用户就不能接高级的兼职工作了。
查询余额,用户每次按时完成兼职能得到一笔费用,有逾期会扣除一部分佣金,最后得到总的余额。
4)兼职人员–>兼职申请模块:
用户能够查询所有的职位信息,因为信用等级的限制,用户也可以只查询自己能够申请的职位信息。
查询到合适的职位用户可以直接申请,申请后到达工作截至时间前完成工作可以提前结束工作得到佣金,如果逾期后完成,管理员会调整用户的信用等级。
用户可以查询自己已经完成过的兼职信息和自己正在完成的兼职信息。
5)管理员–>基本信息维护模块:
管理员能够根据用户完成兼职的情况动态的调整用户的兼职等级状态。
管理员可以调整兼职的等级,供用户选择。
管理员能够根据兼职的等级不同设置逾期费用扣除比例,比如最高级的兼职逾期一天扣10元,扣除兼职费用后继续扣除用户余额,直到用户余额为0,自动结束工作,结算费用。
6)管理员–>兼职信息投放:
管理员可以把所有公司的兼职招聘信息发布到网上,根据公司的需求设置岗位所需人员,工资以及兼职的时间段,比如发传单,这份兼职需要周一到周五的上午9点至11点工作,那么在这个时间段已经有了其他工作的用户就不能申请该工作。
7)管理员–>系统管理模块:
管理员能够删除管理员账户,也能删除平台用户以及一些完成过的兼职信息。
管理员能够添加平台用户信息到系统,本平台是针对学生的软件,所以能够注册的只能是学生,所以平台需要提前将学生信息录入系统,用户才能注册账号,如果未能及时录入信息照成无法注册,那么就需要联系管理员进行信息录入。
管理员可以添加其他的管理员账户,为了安全起见,管理员和普通用户一样能够修改密码。管理员还能够查询所有的用户信息、管理员账户信息、已经投放的职位信息、已经完成的兼职信息和已经逾期的兼职信息。
功能结构图
功能说明:
1)登录注册功能:
用户通过注册进入平台,注册信息包括用户编号(用户编号决定角色类型,学号注册为兼职人员,教师编号注册为管理员),注册后到登录界面输入账号和密码登录平台,注册信息包括:用户编号(学号/教师编号)、密码、姓名、出生日期、性别、电话、所在院系、注册日期等。后期如果忘记了密码,用户通过自己的账号和注册时的姓名找回密码。注意,为了安全起见,只有已经录入系统的用户可以注册账户,本平台提前录入了部分管理员和学生的信息到系统中供大家注册。(相关存储数据可通过I/O流直接存在文件,可也直接在文件里读的数据)
2)兼职人员–>个人信息管理:
包括个人信息修改、密码修改、查询信用等级和查询余额功能。普通用户登录成功之后,可以修改个人注册时录入的信息,学号和注册时间不可更改,密码单独修改;也可以查询个人的信用等级,若信用等级不是最高,则查询个人信用等级时附加显示“按时完成X次后信用等级恢复至X级”(默认未逾期完成兼职工作3次恢复1级信用等级,等级梯度为1-5级,5级最高)。(相关存储数据可通过I/O流直接存在文件,可也直接在文件里读的数据)
3)兼职人员–>兼职申请功能:
包括兼职信息查询、申请工作和结束工作。用户登录成功之后,可以查询所有的兼职信息,包括自己能申请的职位和不能申请的职位,也可以只查看自己能申请的职位(是否可申请与信用等级、岗位所需人员、兼职时间相关)。用户还可查看自己已完成的兼职信息和自己正在完成的兼职信息。满足条件的兼职,用户可以申请,开始工作时间为系统当前时间,相对的该兼职岗位对应的所需人员需要减少;完成工作后(逾期完成信用自动降低1级,0级为最低,0级后不可再申请兼职工作),需要计算所得薪酬(所得薪酬和是否逾期、逾期天数相关),若未逾期且信用等级未满,则需要计算恢复信用等级所需的次数,完成时间手动输入,不可小于兼职开始时间。(相关存储数据可通过I/O流直接存在文件,可也直接在文件里读的数据)
4)管理员–>基本信息维护功能:
包括兼职等级设置、用户信用调整和逾期费用扣除比例调整。管理员端登录成功之后,可以调整兼职的等级(兼职等级梯度为一-五级,五级最高,一级最低),普通用户的信用等级>=兼职等级可申请职位,还可以增删兼职的类型,比如开发外包/销售/设计师等。管理员可以根据用户的表现动态地调整用户的信用等级,可越级增减,0级信用的普通用户管理员不可调整其信用等级。管理员还可以调整兼职的逾期费用,每天逾期扣除的费用相同,比如:原定一份兼职总薪资1000元,工作要求10天完成,逾期1天扣除100元,调整后一天扣除200元(扣除兼职费用为0后继续扣除用户余额,直到用户余额为<=0,自动结束工作,结算费用)。(相关存储数据可通过I/O流直接存在文件,可也直接在文件里读的数据)
5)管理员–>兼职信息投放:
包括兼职人员设置、兼职的金额设置、兼职的时间录入以及兼职的其他信息录入。系统管理员登录成功之后可以把所有公司发布的兼职信息录入到平台,录入信息包括:营业执照编号、公司名字、岗位名称、兼职类型、兼职等级、工作内容、需求人数、工作时间等。系统管理员可以根据市场和公司要求,动态调整这些兼职工作的部分内容,比如需求人数、薪水等,工作时间不允许更改。(相关存储数据可通过I/O流直接存在文件,可也直接在文件里读的数据)
6)管理员–>系统管理功能:
包括对普通用户、管理员和兼职信息的增删查改等。系统提前录入了一些管理员或者学生的信息在系统中,但是未全部录入,所以后续需要注册的用户需要已经录入的管理员登录平台进行信息录入,系统录入仅需要学号/教师编号和姓名即可,此信息供用户注册使用。管理员可以删除普通用户和别的管理员,以及没有用的兼职信息。(相关存储数据可通过I/O流直接存在文件,可也直接在文件里读的数据)
项目思路:
1)登录注册功能
首先利用序列化流录入部分管理员和学生的信息到系统中,之后逐步实现注册功能。
注册需要将输入的编号与反序列化读取出来的内容进行比较,若不存在,就提示失败退出系统;若存在该用户,接着输入注册的密码,定义一个工具类获取当前年月日更改注册日期,将该用户注册后更新的信息再序列化到文件中。
登录功能同样是将输入的账号和密码与反序列化的用户信息比对,一致则登录成功,不一致提示重新输入或者退出系统。每次输入密码,限定次数,超过三次回到主界面。根据输入的账号判断用户类型,进入对应的兼职人员和管理员界面。
2)兼职人员–>个人信息管理
确保修改的值符合常理。
3)兼职人员–>兼职申请功能
private String UID;//兼职人员编号
private String JID;//营业执照编号
private Date work_start;//开始工作时间
private Date work_end;//结束工作时间
private String state = “正在进行中”;//兼职状态
private String name;//申请兼职人员的姓名
private String jobName;//申请兼职岗位名称
private String JTID;//兼职类型标号
添加一些字段,兼职人员申请后job后,applyjob集合存入,并且可以根据检索字段的值,从而得到不同状态的兼职。
4)管理员–>基本信息维护功能
注意修改用户信用时,按时完成的次数重新置零。
5)管理员–>兼职信息投放
投放兼职时,要注意营业执照编号和简直类型编号唯一确定一个兼职,不能重复,以及设置的工作时间要规范。
6)管理员–>系统管理功能
删除用户就是直接将用户文件删除,删除账户就是对用户信息的账户进行重置。
问题描述、分析以及解决
- 1.反序列化时,出错(遗忘)
分析:
1)没有在Mydate注释掉toString方法
解决:
1)注释后,没有报错。
最后注册日期换为Date类型。用户所有信息放到User类中,用户注册成功时,用日期类相关方法,new一个对象,获取当前年月日,存到文件中。
- 2.出现如下异常
分析:
1)注册的用户全都在一个文件当中,判断用户是否已经注册是读取该文件中的对象,因为用户是第一个注册的人,文件为空,出现EOFException。
解决:
1)
转换思路,创建一个文件夹存放所有账户的信息文本文件,传入id参数,若该文件夹下没有以该id命名的文件,返回null,说明该用户没有注册过。若在该目录下找到了该文件,返回对象信息。
//判断是否已经注册 存在账户文件返回信息 不存在账户文件返回null
public static User readUser(String id) throws IOException, ClassNotFoundException {
File[] files = reRoot.listFiles();
User u;
for(File f : files){
String fname = f.getName();
if(fname.equals(id + ".txt")){
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
Object obj = ois.readObject();
u = (User) obj;
ois.close();
return u;
}
}
return null;
}
- 3.如何确保输入的日期是符合常规的?
分析:
1)
// 如果日期不合法,则抛异常
try {
String date_str = “5555-22-33”;
SimpleDateFormat format=new SimpleDateFormat(“yyyy-MM-dd”);
format.setLenient(false);
Date date = format.parse(date_str);
} catch (Exception ex){
ex.printStackTrace();
System.out.println(“日期不合法”);
}
解决:
1)使用SimpleDateFormat 的setLenient方法
System.out.println("请先输入年(yyyy):");
String year = readKeyBoard(4, false);
System.out.println("请先输入月(MM):");
int month = readInt();
System.out.println("请先输入日(dd):");
int day = readInt();
System.out.println("请先输入小时(HH):");
int hour = readInt();
System.out.println("请先输入分钟(mm):");
int minute = readInt();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
try{
time = year + "-" +month + "-" +day + " " + hour + ":"+ minute;
sdf.setLenient(false);
}catch (Exception e){
System.out.println("日期不合法!");
continue;
}
-
4.管理员删除用户和账户时,没有把该用户申请的兼职删除。applyjob和job中仍然存在该用户申请的兼职。
-
第一次尝试
思路:用增强for循环找到applyjob,比较申请人的id和被删除用户的id,找到就删除,然后在里层同样增强for循环遍历job找到相同JID和JTID的兼职,若这个兼职此时需求人数已经为零,就将这个兼职从job中删除。
结果:因为删除集合中的元素,容易出现并发修改异常和索引越界问题。
分析:缺少判断集合是否为空的条件
- 第二次尝试
思路:在两个循环遍历,删除集合元素时,增加判断集合为空,避免出现并发修改异常。
结果:
if(!applyjobs.isEmpty()){
String s1 = null;
String s2 = null;
for(Applyjob a : applyjobs){
if(a.getUID().equals(uid)){
s1 = a.getJID();
s2 = a.getJTID();
applyjobs.remove(a);
}
if(jobs.isEmpty()){
break;
}
for(Job j : jobs){
if(j.getJID().equals(s1) && j.getJobtype().getJTID().equals(s2) && j.getJob_demand().equals("0")){
jobs.remove(j);
}
}
if(applyjobs.isEmpty()){
break;
}
}
}
运行成功,job和applyjob中都删除了这个用户申请的兼职。
总结
在整个项目运行过程中,先把大体框架确定,根据用户分为两个大模块,就是兼职人员模块和管理员模块,之后就是各自细分的功能模块。依次按照模块编写代码,输入多个测试用例进行测试,不断完善代码。过程中注意一些变量需要随着操作而更新,这样兼职人员和管理员收到的信息一致。
为了保证系统的安全性,用户在注册系统时,提前录入的信息只用包含编号和姓名,用户登录注册时就通过这两个进行判定。判定信息单独作为一个文件,用properties进行操作,注册之后所有用户的详细信息再单独存入一个文件。
如果每个用户的详细信息单独录入一个文件,这样比较浪费资源,不推荐这样。下次构建项目时修改这个问题。