一、需求说明书
软件需求说明书
1引言
1.1编写目的
开发本系统的目的,就是要解决目前我校关于学生请假和管理请假事务所面临的一系列问题。
1.2背景
说明:
- 计算机学院请假管理系统;
- 目前我校基本上是采用线下请假,学生先是向班主任说明情况,班主任再向辅导员进行报告,然后学生去辅导员那里申请请假并盖章,再到书记那边盖章,最后到学工处盖章,这才算是完成了一个完整的请假流程,离校时还需向宿管报备。这些流程不仅办事效率不高,而且需要老师和学生同时有时间才能完成请假,为了提高请假效率,请假管理系统能够解决线下请假所带来的麻烦。
1.3定义
无
1.4参考资料
无
2任务概述
2.1目标
该管理系统的用户可分为两大类,即学生用户和校方用户,实现管理的登录,学生用户可以填写请假信息并打印请假条,等待校方领导审核,还可以查看请假记录;校方用户可以对学生的请假情况进行审核、批准,完成学生的请假,还可以对学生请假信息进行增删改查的操作。
2.2用户的特点
学生用户:学生填写请假原因进行请假、打印请假条、查看请假记录。
校方用户:学生信息管理(增/删/改/查)、老师(含辅导员和院系领导)信息管理、对学生的请假申请进行审核、打印、和查看请假记录。
该管理系统面对我校全体师生,故使用频度很高,需要经常修改和维护。
2.3假定和约束
该管理管理系统仅限于我校学生请假和校方管理请假事务,不能用于其他方面。
3需求规定
3.1对功能的规定
基于我院采用的是线下请假,请假手续繁琐,还有诸多不确定因素,导致学生请假存在较多的问题。为了提高请假效率,请假管理系统能够解决线下请假所带来的麻烦。
顶层DFD如图3-1-1所示
图3-1-1
0层DFD如图3-1-2所示
图3-1-2
1层DFD如3-1-3所示
图3-1-3
|
数据字典:
| |||
|
3.2输人输出要求
无
3.3数据管理能力要求
无
3.4故障处理要求
输入信息不符合要求的处理,会弹出警告信息。
3.5其他专门要求
- 系统健壮性:具有一定的容错能力,并且以友好的方式告知用户。
- 安全性:系统应自动备份数据库,防止意外操作或者恶意破坏造成数据的丢失和损坏。
4运行环境规定
4.1设备
1)内存:不小于512MHZ
2)硬盘:20G以上
4.2支持软件
1)操作系统:Windows 7/ Windows 8或Windows 10
2)数据库:MySQL
3)开发环境:Visual Studio 2019、Navicat Premium 15
4.3接口
IE浏览器、Ghrome浏览器等主流浏览器。
4.4控制
浏览器
5.数据需求
对系统中的实体及属性进行ER建模
ER图如图5-1-1所示
图5-1-1
以上内容均是自己所编写的,有缺陷有错误的地方还请指正。。。
二、项目(部分源码+运行截图)
1.实体
(1)学生
package com.leave.entity;import java.io.Serializable;public class Apply implements Serializable {private static final long serialVersionUID = 1L;private int aid;// IDprivate String l_s_card;// 学号private String s_username;// 姓名private String g_name;// 年级private String c_name;// 班级private String s_phone;// 联系电话private String l_begintime;// 请假开始时间private String l_endtime;// 请假结束时间private String l_address;// 请假去向private String l_cause;// 请假理由private int status;// 申请请假条状态 0:待审核 1:请假失败 3:未销假 4:已销假 2:表示由班主任审核通过到辅导员审批的标记符public int getAid() {return aid;}public void setAid(int aid) {this.aid = aid;}public String getL_s_card() {return l_s_card;}public void setL_s_card(String l_s_card) {this.l_s_card = l_s_card;}public String getS_username() {return s_username;}public void setS_username(String s_username) {this.s_username = s_username;}public String getG_name() {return g_name;}public void setG_name(String g_name) {this.g_name = g_name;}public String getC_name() {return c_name;}public void setC_name(String c_name) {this.c_name = c_name;}public String getS_phone() {return s_phone;}public void setS_phone(String s_phone) {this.s_phone = s_phone;}public String getL_begintime() {return l_begintime;}public void setL_begintime(String l_begintime) {this.l_begintime = l_begintime;}public String getL_endtime() {return l_endtime;}public void setL_endtime(String l_endtime) {this.l_endtime = l_endtime;}public String getL_address() {return l_address;}public void setL_address(String l_address) {this.l_address = l_address;}public String getL_cause() {return l_cause;}public void setL_cause(String l_cause) {this.l_cause = l_cause;}public int getStatus() {return status;}public void setStatus(int status) {this.status = status;}}
(2)老师
package com.leave.entity;/** * 系统用户类 * */public class User {/** * 学生类型用户 */public static final int USER_STUDENT = 1;/** * 班主任类型用户 */public static final int USER_TEACHER = 2;/** * 辅导员类型用户 */public static final int USER_ADMIN = 3;private int id; // IDprivate String account; // 账户private String password = "######"; // 密码:默认'111111'private String username; // 用户姓名private int type = USER_STUDENT; // 账户类型:默认1为学生;1为学生,2为班主任,3为辅导员public int getId() {return id;}public void setId(int id) {this.id = id;}public String getAccount() {return account;}public void setAccount(String account) {this.account = account;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public int getType() {return type;}public void setType(int type) {this.type = type;}public User(){//无参构造函数}}
2.数据库(MySQL)
(1)配置连接池
package com.leave.util;import java.io.InputStream;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Properties;import javax.naming.Context;import javax.naming.InitialContext;import javax.naming.NamingException;import javax.sql.DataSource;import org.apache.commons.beanutils.BeanUtils;public class JdbcUtils {private static DataSource dataSource;static {init();}// 每个线程都会自己的一份private static ThreadLocal connectionHolder = new ThreadLocal();/* * 如果有事务,说明connectionHolder中存在Connection对象 * 这个事务都用这个connection来完成 */public static void beginTransaction() throws SQLException {/* * 如果已经开始了事务,就不能再次开启事务! */Connection con = connectionHolder.get();if(con != null) {throw new SQLException("已经存在了事务,不能再次开启!");}// 获取连接con = dataSource.getConnection();// 设置为手动提交con.setAutoCommit(false);// 放到Holder中connectionHolder.set(con);}/* * 提交事务了 * 当前事务的连接在holder中 * 从holder中获取连接,然后提交 */public static void commitTransaction() throws SQLException {Connection con = connectionHolder.get();// 如果holder中没有con,说明根本没有开启事务if(con == null) {throw new SQLException("没有事务可以提交!");}con.commit();//提交事务con.close();//关闭连接connectionHolder.remove();//从holder中移除连接对象}public static void rollbackTransaction() throws SQLException {Connection con = connectionHolder.get();// 如果holder中没有con,说明根本没有开启事务if(con == null) {throw new SQLException("没有事务可以回滚!");}con.rollback();//回滚事务con.close();//关闭连接connectionHolder.remove();//从holder中移除连接对象}// 在连接池没有初始化时,去初始化它// 然后再返回。public static DataSource getDataSource() {return dataSource;}// 给dataSource赋值private static void jndi(String jndiName) {try {Context cxt = new InitialContext();dataSource = (DataSource) cxt.lookup("java:/comp/env/" + jndiName);} catch (NamingException e) {throw new RuntimeException(e);}}// 给dataSource赋值private static void initDataSource(Properties prop) {/* * 1获取连接池类名称 2通过反射他都连接池对象 3通过BeanUtils把属性注入 */String dataSourceClassName = prop.getProperty("dataSourceClassName");try {// 加载连接池的类型@SuppressWarnings("rawtypes")Class clazz = Class.forName(dataSourceClassName);// 通过反射创建连接池对象dataSource = (DataSource) clazz.newInstance();BeanUtils.populate(dataSource, prop);} catch (Exception e) {throw new RuntimeException("dataSourceClassName找不到:"+ dataSourceClassName, e);}}// 在dataSource没有被初始化时调用它private static void init() {// 初始化/* * 1如果在Tomcat环境下,已经配置JNDI,那么就不用管其他的配置信息了,因为会在Tonmcat中配置好了 2如果用户使用的是DBCP * 3如果用户使用的c3p0 *//* * 当用户配置了jndiName属性时,那么使用这个值直接调用jndi()方法 indi()方法 */try {// 加载配置文件,配置文件名为dbconfig.propertiesProperties prop = new Properties();InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("dbconfig.properties");prop.load(in);// 获取jndiNameString jndiName = prop.getProperty("jndiName");// 如果存在jndiName,那么就直接使用jndi的初始化方式// jndi初始化if(jndiName != null) {jndi(jndiName);return;}// 配置初始化initDataSource(prop);} catch (Exception e) {throw new RuntimeException("dbconfig.properties找不到:", e);}}/* * 修改了getConnection() * 当holder中存在Connection,说明用户已经开启了事务 * 那么用来在获取连接时,一定要让他使用事务的连接对象 */public static Connection getConnection() throws SQLException {Connection con = connectionHolder.get();if(con != null) {return con;}return dataSource.getConnection();}public static void close(Connection con, Statement stmt) {close(con, stmt, null);}public static void close(Connection con) {close(con, null, null);}public static void close(Connection con, Statement stmt, ResultSet rs) {try {if (rs != null)rs.close();if (stmt != null)stmt.close();if (con != null)con.close();} catch (SQLException e) {throw new RuntimeException(e);}}}
(2)数据库连接
jdbc:mysql://localhost:3306/leave?serverTimezone=UTC;characterEncoding=utf-8com.mysql.jdbc.Driverroot123456310210>
dataSourceClassName=com.mchange.v2.c3p0.ComboPooledDataSourceuser=rootpassword=######jdbcUrl=jdbc:mysql://localhost:3306/leave?serverTimezone=UTC&characterEncoding=utf-8driverClass=com.mysql.jdbc.DriveracquireIncrement=1maxPoolSize=20minPoolSize=3initialPoolSize=5
三、Tomcat配置
我配置的是Tomcat7.0 ,详细安装配置过程参考下面连接:
tomcat下载安装及配置教程_NiUoW的博客-CSDN博客_tomcat下载安装及配置教程
四、运行截图
登录页面
学生界面
请假申请界面
请假记录页面
班主任审核界面
辅导员审核界面
简单的一个项目,虽然很粗糙,但完成大作业还是很不错的,哈哈哈哈。小白一名,上述内容如有错误的地方,还请指正。
个人原创,如有侵权请联系!