项目需求
项目功能结构图:
项目功能
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流直接存在文件,可也直接在文件里读的数据)
实现代码
实体类
用户实体:用户编号(学号/教师编号)、密码、姓名、年龄、性别、电话、所在院系、注册日期等
兼职信息实体:营业执照编号、公司名字、岗位名称、兼职类型、兼职等级、工作内容、需求人数、工作时间等
兼职类型:兼职类型编号、兼职类型名称、薪水、逾期费用扣除比例
普通用户账户:账户编号、信用等级、余额
User.java:UID, password, username, age, sex, phone, department, regdat, credit_rating, balance
UserAccount: ACID, credit_rating, balance
Job.java: JID, company_name, job_name, jobtype_name, job_level, salary, deduct_salary, job_content, job_demand, job_time
JobType.java: JTID, salary, deduct_salary, jobtype_name
ApplyJob.java: UID, JID, work_start, work_end
首先观察需求,发现需要大量应用文件IO流,由此为基础对后面的代码需要进行一定的规划。
创建实体类,对类的各项属性设置完成,以便后面应用。注意继承Serializable接口,并且用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
会出问题,会抛出InvalidClassException异常
如果出问题了,如何解决呢?
重新序列化
给对象所属的类加一个serialVersionUID
private static final long serialVersionUID = 42L;
TSUtility为工具类
public class TSUtility {
private static Scanner sc=new Scanner(System.in);
//序列化
public static void mySerializable(Object obj,String fileName) throws IOException {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(fileName));
oos.writeObject(obj);
oos.close();
}
//反序列化
public static Object myDeserializable(String filename) throws IOException, ClassNotFoundException {
File file=new File(filename);
Object o;
if (file.createNewFile()||file.length()==0){
return null;
}
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(filename));
o = ois.readObject();
ois.close();
return o;
}
}
这里主要介绍将序列化和反序列化写为两个方法,可增加代码利用率,使得后面应用时,只用输入路径和对象即可。
LoginView类实现登录注册功能
package view;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import domain.User;
import domain.UserAccount;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Properties;
import java.util.logging.SimpleFormatter;
public class LoginView {
private User user = null;
private static ArrayList<User> users;
private Properties prop = new Properties();
private static HashMap<String, UserAccount> accounts;
static {
String filename1 = "D:\\桌面\\src\\files\\registerusers.txt";
String filename3 = "D:\\桌面\\src\\files\\accounts.txt";
try {
Object o = TSUtility.myDeserializable(filename1);
if (o == null) {
users = new ArrayList<>();
} else {
users = (ArrayList<User>) TSUtility.myDeserializable(filename1);
}
o = TSUtility.myDeserializable(filename3);
if (o == null) {
accounts = new HashMap<>();
} else {
accounts = (HashMap<String, UserAccount>) TSUtility.myDeserializable(filename3);
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public static ArrayList<User> getUsers() {
return users;
}
public static void setUsers(ArrayList<User> users) {
LoginView.users = users;
}
public Properties getProp() {
return prop;
}
public void setProp(Properties prop) {
this.prop = prop;
}
public static HashMap<String, UserAccount> getAccounts() {
return accounts;
}
public static void setAccounts(HashMap<String, UserAccount> accounts) {
LoginView.accounts = accounts;
}
public void entrySystem() throws IOException {
FileWriter fw=new FileWriter("D:\\Project\\src\\files\\schoolsystem.txt",true);
String id="";
String name="";
while (true){
System.out.println("请输入需要录入的学号/教师编号");
id=TSUtility.readUserID();
if (prop.containsKey(id)){
System.out.println("该用户已被录入系统!");
}else {
System.out.println("请输入需要录入的姓名:");
name =TSUtility.readKeyBoard(4, false);
prop.setProperty(id, name);
prop.store(fw, null);
System.out.println("录入系统成功!");
break;
}
}
fw.close();
}
public void register() throws IOException {
while (true) {
System.out.println("开始注册");
System.out.println("请输入新用户ID(5位数字学生,3位数字老师)");
String id = TSUtility.readUserID();
if (prop.size() == 0) {
FileReader fr = new FileReader("D:\\src\\files\\schoolsystem.txt");
prop.load(fr);
fr.close();
}
for (int i = 0; i < users.size(); i++) {
if (users.get(i).getUserId().equals(id)) {
System.out.println("该用户已注册,请重新输入");
return;
}
}
if (prop.containsKey(id)) {
String name = prop.getProperty(id);
System.out.println("请设置密码");
String passWorld = TSUtility.readPasWord();
System.out.println("请输入年龄");
int age = TSUtility.readInt(2);
System.out.print("请输入您的性别:");
char gender = TSUtility.setGender();
System.out.print("请输入您的手机号码:");
int telephone = TSUtility.readInt(11);
System.out.print("请输入您的院系:");
String department = TSUtility.readKeyBoard(10, false);
User user = new User(id, passWorld, name, age, gender, telephone, department);
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String regdat = sdf.format(date);
user.setRegdat(regdat);
int ACID = TSUtility.readAccount(accounts);
System.out.println("系统将为您创建一个账户,编号:" + ACID);
UserAccount userAccount = new UserAccount(ACID, user.getCredit_rating(), user.getBalance());
users.add(user);
accounts.put(user.getUserId(), userAccount);
System.out.println("注册成功,请登录");
String filename = "D:\\src\\files\\journal.txt";
String s = "用户" + id + "已注册";
TSUtility.writeJournal(filename, s);
String filename2 = "D:\\src\\files\\registerusers.txt";
TSUtility.mySerializable(users, filename2);
String filename3 = "D:\\src\\files\\accounts.txt";
TSUtility.mySerializable(accounts, filename3);
break;
} else {
System.out.println("用户系统没有录入");
}
}
}
public void logIn() throws IOException {
boolean flag = false;
int count = 5;
while (!flag) {
System.out.println("请输入用户名");
String id = TSUtility.readUserID();
System.out.println("请输入密码");
String passWord = TSUtility.readPasWord();
if (users.isEmpty()) {
System.out.println("您输入账号不存在,请先注册");
register();
continue;
}
for (int i = 0; i < users.size(); i++) {
User user = users.get(i);
if (id.equals(user.getUserId())) {
if (passWord.equals(user.getPassWord())) {
this.user = user;
if (id.length() == 3) {
System.out.println("登录成功!欢迎您"+user.getName()+"老师");
}else {
System.out.println("登录成功!欢迎您"+user.getName()+"同学");
}
}
String filename="\\src\\files\\journal.txt";
String s ="用户"+id+"登录";
TSUtility.writeJournal(filename,s);
return;
}
}
count--;
if (count>0){
System.out.println("用户名或密码输入错误,您还有" + count + "次机会,\n请重新输入:");
}else {
flag=true;
}
}
}
}
后面,判断登录人员是学生还是管理员时,采用判断编号长度,若为3位进入管理员系统,若为5位进入学生系统。
BaseMessageService类是管理员对兼职基本信息维护内容。
/*
基本信息服务
*/
public class BaseMessageService implements Serializable {
//兼职等级设置
public void setJobLevel(ArrayList<Job> jobs) throws IOException {
if (jobs.isEmpty()){
System.out.println("没有可供选择的兼职");
return;
}
System.out.println("工作编号\t兼职名\t兼职等级\t薪水\t\t工作内容");
for (Job job:jobs){
job.showJob();
}
System.out.println("请输入需要调整等级的工作编号;");
while (true){
int jobId= TSUtility.readInt(3);
for (int i =0;i<jobs.size();i++){
if (jobs.get(i).getJID()==jobId){
System.out.println("请输入需要设置的等级");
int jobLevel=TSUtility.readLevel();
jobs.get(i).setJob_level(jobLevel);
System.out.println("工作等级设置成功!");
String filename="D:\\Project\\src\\files\\registerusers.txt";
TSUtility.mySerializable(jobs,filename);
String filename2="D:\\Project\\src\\files\\journal.txt";
String s="兼职"+jobId+"已调整工作等级为"+jobLevel;
TSUtility.writeJournal(filename2,s);
return;
}
}
System.out.println("未找到您输入的工作!");
System.out.println("请重新输入工作编号(三位数字):");
}
}
//兼职类型设置/增加工作类型
public void addJobType(ArrayList<JobType>jobTypes) throws IOException {
System.out.println("请输入新的工作类型编号:");
int JTID=TSUtility.readInt(3);
if (jobTypes.size()!=0){
for (int i =0;i<jobTypes.size();i++){
if (jobTypes.get(i).getJTID() == JTID) {
System.out.println("工作类型编号已存在!");
return;
}
}}
System.out.println("请输入工作类型名称:");
String jobtype_name = TSUtility.readKeyBoard(6, false);
if (jobTypes.size()!=0){
for (int i = 0; i < jobTypes.size(); i++) {
if (jobTypes.get(i).getJobtype_name().equals(jobtype_name)) {
System.out.println("工作类型名称已存在!");
return;
}
}}
System.out.println("请设置该工作类型的逾期扣除比例:");
int deduct_salary = TSUtility.readInt(4);
JobType jt = new JobType(JTID, deduct_salary, jobtype_name);
jobTypes.add(jt);
System.out.println("工作类型增加成功!");
String filename="D:\\Project\\src\\files\\jobtypes.txt";
TSUtility.mySerializable(jobTypes,filename);
String filename2="\Project\\src\\files\\journal.txt";
String s="兼职类型"+JTID+"已添加";
TSUtility.writeJournal(filename2,s);
}
//兼职类型设置//删除工作类型
public void delJobType(ArrayList<JobType>jobTypes) throws IOException {
System.out.println("请输入需要删除的工作类型编号");
int JTID=TSUtility.readInt(3);
for (int i =0;i<jobTypes.size();i++){
if (JTID==jobTypes.get(i).getJTID()){
jobTypes.remove(i);
System.out.println("删除成功");
String filename="D:\\Project\\src\\files\\jobtypes.txt";
TSUtility.mySerializable(jobTypes,filename);
String filename2="D:\\Project\\src\\files\\journal.txt";
String s="兼职类型"+JTID+"已删除";
TSUtility.writeJournal(filename2,s);
return;
}else {
System.out.println("未找到");
}
}
}
//兼职类型设置//查看所有工作类型
public void showJobType(ArrayList<JobType>jobTypes){
System.out.println("工作类型编号\t工作类型\t逾期扣除比例");
for (int i=0;i<jobTypes.size();i++){
System.out.println(jobTypes.get(i));
}
}
//用户信用调整
public void setUserCreditRating(ArrayList<User>users, HashMap<String, UserAccount>accounts) throws IOException {
User user;
int creditRating=0;
System.out.println("请输入需要修改的用户学号/教师编号");
while (true){
String userId=TSUtility.readUserID();
for (int i =0;i<users.size();i++){
if (users.get(i).getUserId().equals(userId)){
user=users.get(i);
if (user.getCredit_rating()==0){
System.out.println("该用户信用等级为0,不可修改");
}
System.out.println("请输入需要设置的信用等级");
users.get(i).setCredit_rating(TSUtility.readLevel());
String filename="D:\\Project\\src\\files\\registerusers.txt";
TSUtility.mySerializable(users,filename);
String filename2="D:\\Project\\src\\files\\journal.txt";
String s="用户"+userId+"已修改信用等级为"+creditRating;
TSUtility.writeJournal(filename2,s);
}
}
Set<String>keys=accounts.keySet();
for (String key:keys){
if (key.equals(userId)){
accounts.get(key).setCredit_rating(creditRating);
System.out.println("用户信用等级设置成功!");
String filename="D:\\Project\\src\\files\\accounts.txt";
TSUtility.mySerializable(accounts,filename);
return;
}
}
System.out.println("该用户不存在!");
System.out.println("请重新输入学号(5位)/教师编号(3位):");
}
}
//逾期费用扣除比例调整
public void modifyDeductSalary(ArrayList<JobType>jobTypes) throws IOException {
System.out.println("请输入需要修改逾期扣除比例的工作类型编号:");
int JTID=TSUtility.readInt(3);
for (int i=0;i<jobTypes.size();i++){
if (jobTypes.get(i).getJTID()==JTID){
System.out.println("请输入逾期扣除比例:");
int deductSalary=TSUtility.readInt(4);
jobTypes.get(i).setDeduct_salary(deductSalary);
System.out.println("修改成功");
String filename="D:\\Project\\src\\files\\jobtypes.txt";
TSUtility.mySerializable(jobTypes,filename);
String filename2="D:\\Project\\src\\files\\journal.txt";
String s= "兼职类型"+JTID+"的逾期比例已调整";
TSUtility.writeJournal(filename2,s);
return;
}
}
System.out.println("未找到该工作类型!");
}
}