无标题

Posted 高校俱乐部

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无标题相关的知识,希望对你有一定的参考价值。

人力资源管理系统

长文预警

记录一下自己的C#实训课的成果
需要github gitee链接的在最底下.

实训项目目标

目标1:理解复杂软件系统的分层架构思想,能运用两层/三层架构设计软件。
目标2:在明确软件功能需求下,能按两层架/三层架构设计特定的软件模块。
目标3:了解复杂软件系统,通过设计实现不同的组件、模块及其关系完成整个软件的开发,并体现创新意识。
目标4:熟练掌握一种集成开发环境,并能运用各类技术、资源解决软件开发中的问题。
目标5:能够撰写报告,清晰表达软件开发中的问题和方案。


软件版本

ide 我使用的Visual Studio 2015
sql 就是使用vs自带的sql server 2014


功能介绍

  1. 能实现用户和管理员的登录,同时密码不能明文存储在数据库中
  2. 能针对不同的登录情况做出不同的提示
  3. 能在主界面中状态栏显示登录信息
  4. 能在每次登录操作之后记录在日志表中
  5. 包括用户对自己密码的修改功能
  6. 包括管理员对用户管理:添加用户,删除用户,锁定用户,查询用户功能
  7. 包括管理员对部门管理:添加部门,删除部门,部门列表展示功能
  8. 包括管理员对日志列表查询功能,实行分页浏览,可进行上下页以及首尾页跳转功能
  9. 包括管理员对员工列表查询功能:按照姓名模糊查询,部门查询,入职时间查询三个不定项查询条件
  10. 包括管理员对员工管理功能:添加员工,编辑员工信息,以及删除员工功能
  11. 包括管理员对日志迁移的功能,把指定日期间的日志从旧表中移除,存入新表.
  12. 能实现把员工列表导出为Excel文件
  13. 能实现员工不同年月部门的工资单显示以及写入修改以及导出功能
  14. 能实现工资单的打印功能,打印样式中有总计,和年月部门的显示.

运行成果部分展示

登录

添加用户界面

日志查询

日志迁移

员工列表

编辑员工信息

生成工资单

打印工资单

如果你有打印机的话就可以直接打印了.

修改密码


解决方案部分展示




数据库准备

利用脚本生成数据库

首先在自己的D盘新建一个文件夹,我这叫做SqlData~~(当然你也可以叫别的,甚至不在d盘,但是需要你在sql文件里重写修改储存地址)~~ 文件夹地址就是D:SqlData
创建完后具体使用方式就是把sql文件拖到Visual Studio中再点击左上角的运行按键就可以了

脚本和项目文件我会一起放在github上和gitee上,有需要的自取.

创建登录名,用户以及赋予登陆权限

1. 创建登录名

首先用windows身份登录数据库,点击安全性,再右键登录名选择添加新登录名

输入,后运行就创建成功了.(可以自己修改用户名和密码,我这里用户名为hrmtest,密码为test)

CREATE LOGIN [hrmtest] WITH PASSWORD = 'test'

2. 创建用户

进入刚刚创建好的数据库HRMDB数据库中,选择安全性,之后右键用户,添加用户

我们把第二行的WITHOUT LOGIN给删掉,将两处[]内改成我们的用户名hrmtest后,运行

CREATE USER [hrmtest]
	WITH DEFAULT_SCHEMA = dbo
GO
GRANT CONNECT TO [hrmtest]

3. 赋予权限

我们右键HRMDB数据库后新建查询

输入后运行,其中把最后一个引号内改成自己的用户名

exec sp_addrolemember 'db_owner', 'hrmtest'

4. 使用新用户连接服务器

首先右键原有是由windows连接的服务器,断开连接.
点击添加Sql server

填写身份验证

连接完成之后进去HRMDB中看看,如果可以看到表就说明之前的操作都成功了.


Model模型层

右键解决方案,点击添加,点击新建项目,选择类库,创建我们的模型层HRMSystem.Model

Operator类

在这个类库中,我们添加一个Operator类,作为登录的操作员的信息模型
其中Id的数据类型设置为Guid,这样可以使用Guid来生成一个独一无二的辨识编号

    public class Operator
    
        public Guid Id  get; set;  //Guid为全局统一标识符,可以生成一个独一无二的id
        public string UserName  get; set; 
        public string Password  get; set; 
        public bool IsDeleted  get; set; //有无被删除
        public string RealName  get; set; 
        public bool IsLocked  get; set; //有无被锁定
    

OperationLog类

用来存放操作日志

public class OperationLog
    
        public Guid Id  get; set; 
        public string ActionDesc  get; set; 
        public Guid OperatorId  get; set; 
        public DateTime ActionDate  get; set; 
    

Employee类

用来存放员工的信息
其中Photo的数据类型需要设置为Byte[],要不然不能存储图片,必须用数据流来存储

public class Employee
    
        public Guid Id  get; set; 
        public string Number  get; set; 
        public string Name  get; set; 
        public DateTime BirthDay  get; set; 
        public DateTime InDay  get; set; 
        public Guid MarriageId  get; set; 
        public Guid PartyId  get; set; 
        public Guid EducationId  get; set; 
        public Guid GenderId  get; set; 
        public Guid DepartmentId  get; set; 
        public string Telephone  get; set; 
        public string Address  get; set; 
        public string Email  get; set; 
        public string Remarks  get; set; 
        public string Resume  get; set; 
        public Byte[] Photo  get; set; 
        public string Nation  get; set; 
        public string NativePlace  get; set; 

    

EmployeeSelect类

用来存放员工查询时的查询条件信息

    public class EmployeeSelect
    
        public string Name  get; set; 
        public DateTime InDay1  get; set; 
        public DateTime InDay2  get; set; 
        public Guid DepartmentId  get; set; 
        public bool TimeCheck  get; set; 
    

Department类

用来存放部门的编号和名字信息

    public class Department
    
        public Guid Id  get; set; 
        public string Name  get; set; 
    

SalarySheet类

存储工资表的信息

    public class SalarySheet
    
        public Guid Id  get; set; 
        public int Year  get; set; 
        public int Month  get; set; 
        public Guid DepartmentId  get; set; 
    

SalarySheetItem类

存储工资单细节信息

    public class SalarySheetItem
    
        public Guid Id  get; set; 
        public Guid SheetId  get; set; 
        public Guid EmployeeId  get; set; 
        public decimal BaseSalary  get; set; 
        public decimal Bonus  get; set; 
        public decimal Fine  get; set; 
        public decimal Other  get; set; 
    

DAL数据层

创建一个类库叫做HRMSystem.DAL,当作数据层,用来对于数据库进行操作.

为了简化connstr,所以我们使用引用来添加.
在数据层中右键引用,添加引用Configuration
然后在HRMSystem2022类库中加上

  <connectionStrings>
    <add name="connStr" connectionString="Data Source=(localdb)MSSQLLocalDB;Initial Catalog = HRMDB;Uid =hrmtest;Pwd=test"/>
  </connectionStrings>

其中用户名和密码要对应


SqlHelper类

这个类被设置成抽象类用来存放对sql server的操作.这样可以在代码中重复多次的sql语句等进行化简.需要用到对sql访问的时候调用这个类中的静态方法就可以了.
其中包括存放connstr信息的字段,以及返回SqlDataReader的方法,返回Object对象的ExecuteScalar方法,返回受影响记录数的ExecuteNonQuery方法,返回DataTable数据类型的GetDataTable方法,事务处理的Execute方法.
注意,参数里的SqlParameter[]前面要加一个params,表示可以有多个也可以没有,这样可以符合所有查询的条件或者是没有条件.

public class SqlHelper
    
        public static string connstr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
        public static SqlDataReader ExecuteReader(string sql, params SqlParameter[] parameters)
        
            SqlConnection conn = new SqlConnection(connstr);
            SqlCommand comm = new SqlCommand(sql, conn);
            comm.Parameters.AddRange(parameters);
            conn.Open();
            return comm.ExecuteReader(CommandBehavior.CloseConnection);
        
        public static Object ExecuteScalar(string sql, params SqlParameter[] parameters)
        
            using (SqlConnection conn = new SqlConnection(connstr))
            
                SqlCommand comm = new SqlCommand(sql, conn);
                comm.Parameters.AddRange(parameters);
                conn.Open();
                return comm.ExecuteScalar();
            
        
        public static int ExecuteNonQuery(string sql, params SqlParameter[] parameters)
        
            using (SqlConnection conn = new SqlConnection(connstr))
            
                SqlCommand comm = new SqlCommand(sql, conn);
                comm.Parameters.AddRange(parameters);
                conn.Open();
                return comm.ExecuteNonQuery();
            
        
        public static DataTable GetDataTable(string sql, params SqlParameter[] parameters)
        
            using (SqlConnection conn = new SqlConnection(connstr))
            
                DataTable dt = new DataTable();
                SqlDataAdapter sda = new SqlDataAdapter(sql, conn);
                sda.SelectCommand.Parameters.AddRange(parameters);
                sda.Fill(dt);
                return dt;
            
        
        public static bool Execute(string sql1, string sql2, params SqlParameter[] parameters)
        
            using (SqlConnection conn = new SqlConnection(connstr))
            
                conn.Open();
                SqlTransaction st = null;
                SqlCommand comm = null;
                try
                
                    st = conn.BeginTransaction();
                    comm = new SqlCommand(sql1, conn, st);
                    comm.CommandText += sql2;
                    comm.Parameters.AddRange(parameters);
                    comm.ExecuteNonQuery();
                    st.Commit();
                
                catch (Exception ex)
                
                    st.Rollback();
                    return false;
                    throw ex;
                
                return true;
            
        
    

OperatorService类

这个类用来写对于操作员的一些对数据库的操作的一些方法.例如添加用户,删除用户

1. DeleteOperator方法

删除用户的方法,将传入的信息放入SqlParameter中来调用SqlHelper类中的ExecuteNonQuery方法实现删除用户.(此处的删除不是真的在数据库中删除,而是给该用户一个标记,表面这个用户已经被注销了)

        public bool DeleteOperator(string UserName)
        
            string sql = "UPDATE Operator SET IsDeleted = 1 WHERE @UserName = UserName";
            SqlParameter paramUserName = new SqlParameter("@UserName", UserName);
            int n = SqlHelper.ExecuteNonQuery(sql, paramUserName);
            return n > 0;
        

2. InsertOperator方法

添加新用户的方法,将传入的信息放入SqlParameter[]中来调用SqlHelper类中的ExecuteNonQuery方法实现插入用户.

        public bool InsertOperator(string RealName, string Password, string UserName)
        
            string sql = "INSERT INTO Operator(Id, UserName, Password, IsDeleted, RealName, IsLocked) VALUES(NEWID(), @UserName, @Password, 0, @RealName, 0)";
            SqlParameter[] parames = 
                new SqlParameter("@UserName", UserName),
                new SqlParameter("@Password", Password),
                new SqlParameter("@RealName", RealName)
            ;
            int n = SqlHelper.ExecuteNonQuery(sql, parames);
            return n > 0;
        

3. LockOperator方法

锁定用户的方法,将传入的信息放入SqlParameter中来调用SqlHelper类中的ExecuteNonQuery方法实现锁定用户.

        public bool LockOperator(string UserName)
        
            string sql = "UPDATE Operator SET IsLocked = 1 WHERE @UserName = UserName";
            SqlParameter paramUserName = new SqlParameter("@UserName", UserName);
            int n = SqlHelper.ExecuteNonQuery(sql, paramUserName);
            return n > 0;
        

4. PwdModify方法

修改用户的密码的方法,将传入的信息放入SqlParameter中来调用SqlHelper类中的ExecuteNonQuery方法实现修改用户密码.

        public void PwdModify(string un, string pwdAfter)
        
            string sql = "update Operator set Password = @PasswordAfter where UserName = @UserName";
            SqlParameter[] parames = 
                new SqlParameter("@PasswordAfter", pwdAfter),
                new SqlParameter("@UserName", un)
            ;
            int n = SqlHelper.ExecuteNonQuery(sql, parames);
        

5. GetOperator方法

用来通过用户名来调用SqlHelper中的ExecuteReader方法返回当前登录着的用户的信息,存储在op对象中

public Operator GetOperator(string un)
        
            Operator op = null;
            string sql = "select * from Operator where UserName = @UserName";
            SqlParameter paramUserName = new SqlParameter("@UserName", un);
            SqlDataReader sdr = SqlHelper.ExecuteReader(sql, paramUserName);
            if (sdr.Read())
                
                    op = new Operator();
                    op.Id = (Guid)sdr["Id"];
                    op.UserName = sdr["UserName"].ToString();
                    op.Password = sdr["Password"].ToString();
                    op.IsDeleted = (bool)sdr["IsDeleted"];
                    op.RealName = sdr["RealName"].ToString();
                    op.IsLocked = (bool)sdr["IsLocked"];
                
            sdr.Close();
            return op;
        

OperationLogService类

创建该类用来存放一些对于操作日志进行操作的方法,比如添加日志,获取日志数以及获取日志列表

1. LogAdd方法

将操作员的信息通过SqlHelper中的ExecuteNonQuery方法插入到OperationLog数据表中

public bool LogAdd(OperationLog ol)
        
            string sql = "insert into OperationLog values(@Id, @OperatorId, @ActionDate, @ActionDesc)";
            SqlParameter[] Parameters = 
                new SqlParameter("@Id", ol.Id),
                new SqlParameter("@OperatorId", ol.OperatorId),
                new SqlParameter("@ActionDate", ol.ActionDate),
                new SqlParameter("@ActionDesc", ol.ActionDesc)
            ;
            int n = SqlHelper.ExecuteNonQuery(sql, Parameters);
            return n > 0;
        

2. GetLogCount方法

获取日志的数目

        public int GetLogCount()
        
            string sql = "select count(*) from OperationLog";
            int n = SqlHelper.ExecuteNonQuery(sql);
            return n;
        

3. GetLogList方法

获取日志所有列表的DataTable,然后分页显示,所以这里面的sql语句有点长,大家仔细看看.

public DataTable GetLogList(int pageNo, int numPerPage)
        
            string sql = "SELECT Temp.Id AS 编号,Operator.RealName AS 操作员, Temp.ActionDate AS 操作时间, Temp.ActionDesc AS 描述 FROM (SELECT TOP(@LogNum) * FROM OperationLog WHERE Id NOT IN(SELECT TOP(@BeforeNum) Id FROM OperationLog)) AS Temp, Operator WHERE Temp.OperatorId = Operator.Id";
            SqlParameter[] parameters = 
                    new SqlParameter("@LogNum", numPerPage),
                    new SqlParameter("@BeforeNum", numPerPage * (pageNo - 1))
                ;
            return SqlHelper.GetDataTable(sql, parameters);
        

EmployeeService类

用来存放对于员工的一些操作,包括获取员工列表,删除员工,插入员工,编辑员工,通过Id查找员工等功能

1. GetEmployeeList方法

这个方法有两个重载,一个是无参数的,直接查询所有的员工信息然后输出DataTable
另一个是有一个EmployeeSelect类型的参数,将员工查询的信息输入,然后仅仅查询出符合条件的员工返回DataTable
无参的:

        public DataTable GetEmployeeList()
        
            string sql = "select Id as 编号, Number as 工号, Name as 姓名, InDay as 入职时间, Nation as 民族, NativePlace as 籍贯 from Employee";
            return SqlHelper.GetDataTable(sql);
        

有参的:
这里面需要使用List<string ,要不然就要手动多敲很多行代码,看起来很繁琐,通过这种方式可以将代码化简.
将查询条件通过Add加到whereList里面,这样可以避免每次进行判断之后都写重复的一长串sql语句.
最后将条件使用and连接起来.
但要注意!!使用sql语句中参数的时候如果进行模糊查询,那么就不能直接将%加在@Name中,因为这样就识别不出来了,所以需要使用+进行字符串的拼接.例如"Name like ‘%’ + @Name + ‘%’"
这也是我好久都提示错误的原因,哎!

public DataTable GetEmployeeList(EmployeeSelect es)
        
            string sql = "select Id as 编号, Number as 工号, Name as 姓名, InDay as 入职时间, Nation as 民族, NativePlace as 籍贯 from Employee";
            List<SqlParameter> whereParameters = new List<SqlParameter>();
            if(es != null)
            
                List<string> whereList = new List<string>();
                if (!string.IsNullOrEmpty(es.Name))
                
                    whereList.Add(string.Format("Name like '%' + @Name + '%'"));
                    whereParameters.Add(new SqlParameter("@Name", es.Name));
                
                if (es.TimeCheck)
                
                    whereList.Add(string.Format("InDay between @Time1 and @Time2"));
                    whereParameters.Add(new SqlParameter("@Time1", es.InDay1));
                    whereParameters.Add(new SqlParameter("@Time2", es.InDay2));
                
                if(es.DepartmentId != Guid.Empty)
                
                    whereList.Add(string.Format("DepartmentId = @Dept"));
                    whereParameters.Add(new SqlParameter("@Dept", es.DepartmentId));
                

                string whereStr = string.Join(" and ", whereList);
                if(whereStr != null && whereStr.Length > 0)
                
                    sql += " where " + whereStr;
                

            
            return SqlHelper.GetDataTable(sql, whereParameters.ToArray());

        

2. InsertEmployee方法

添加新员工的方法,将传入的emp对象中的信息都作为参数传入SqlHelper中调用ExecuteNonQuery方法来实现往数据库中添加新记录.

public bool InsertEmployee(Employee emp)
        
            string sql = "insert into Employee values(@Id, @Number, @Name, @BirthDay, @InDay, @MarriageId, @PartyId, @EducationId, @GenderId, @DepartmentId, @Telephone, @Address, @Email, @Remarks, @Resume, @Photo, @Nation, @NativaPalce)";
            SqlParameter[] Parameter = 
                new SqlParameter("@Id", emp.Id),
                new SqlParameter("@Number", emp.Number),
                new SqlParameter("@Name", emp.Name),
                new SqlParameter("@BirthDay", emp.BirthDay),
                new SqlParameter("@InDay", emp.InDay),
                new SqlParameter("@MarriageId", emp.MarriageId),
                new SqlParameter("@PartyId", emp.PartyId),
                new SqlParameter("@EducationId", emp.EducationId),
                new SqlParameter("@GenderId", emp.GenderId),
                new SqlParameter("@DepartmentId", emp.DepartmentId),
                new SqlParameter("@Telephone", emp.Telephone),
                new SqlParameter("@Address", emp.Address),
                new SqlParameter("@Email", emp.Email),
                new SqlParameter("@Remarks", emp.Remarks),
                new SqlParameter("@Resume", emp.Resume),
                new SqlParameter("@Photo", emp.Photo),
                new SqlParameter("@Nation", emp.Nation),
                new SqlParameter("@NativaPalce", emp.NativePlace),
            ;
            return SqlHelper.ExecuteNonQuery(sql, Parameter) > 0;
        

3. GetEmpById方法

通过传入的Id来查找到对应的员工信息,存到emp对象中然后返回该对象.

public Employee GetEmpById(Guid id)
        
            string sql = "select * from Employee where Id = @id";
            SqlParameter para = new SqlParameter("@id", id);
            Employee emp = new Employee();
            SqlDataReader sdr = SqlHelper.ExecuteReader(sql, para);
            while (sdr.Read())
            
                emp.Name = sdr["Name"].ToString();
                emp.Address = sdr["Address"].ToString();
                emp.Telephone = sdr["Telephone"].ToString();
                emp.Resume = sdr["Resume"].ToString();
                emp.Remarks = sdr["Remarks"].ToString();
                emp.Photo = (byte[])sdr["Photo"];
                emp.PartyId = (Guid)sdr["PartyId"];
                emp.Number = sdr["Number"].ToString();
                emp.NativePlace = sdr["NativePlace"].ToString();
                emp.Nation = sdr["Nation"].ToString();
                emp.MarriageId = (Guid)sdr["MarriageId"];
                emp.InDay = (DateTime)sdr["InDay"];
                emp.Email = sdr["Email"].ToString();
                emp.EducationId = (Guid)sdr["EducationId"];
                emp.DepartmentId = (Guid)sdr["DepartmentId"];
                emp.BirthDay = (DateTime)sdr["BirthDay"];
                emp.GenderId = (Guid)sdr["GenderId"];
            
            return emp;
        

4. deleteEmployeeById方法

通过传入的员工Id来把该对应的员工给从数据库中删除.

        public bool deleteEmployeeById(Guid id)
        
            string sql = "delete from Employee where Id = @id";
            SqlParameter param = new SqlParameter("@id", id);
            if(SqlHelper.ExecuteNonQuery(sql, param) > 0)
            
                return true;
            
            else
            
                return false;
            
        

5. updateEmployee方法

该方法需要传入两个值,一个存有编辑以后员工的全部信息Employee对象,另一个员工的Id

        public bool updateEmployee(Employee emp, Guid id)
        
            string sql = "update Employee set Number = @Number, Name = @Name, BirthDay = @BirthDay, InDay = @InDay, MarriageId = @MarriageId, PartyId = @PartyId, EducationId = @EducationId, GenderId = @GenderId, DepartmentId = @DepartmentId, Telephone = @Telephone, Address = @Address, Email = @Email, Remarks = @Remarks, Resume = @Resume, Photo = @Photo, Nation = @Nation, NativePlace = @NativaPalce where Id = @Id";
            SqlParameter[] Parameter = 
                new SqlParameter("@Id", id),
                new SqlParameter("@Number", emp.Number),
                new SqlParameter("@Name", emp.Name),
                new SqlParameter("@BirthDay", emp.BirthDay),
                new SqlParameter("@InDay", emp.InDay),
                new SqlParameter("@MarriageId", emp.MarriageId),
                new SqlParameter("@PartyId", emp.PartyId),
                new SqlParameter("@EducationId", emp.EducationId),
                new SqlParameter("@GenderId", emp.GenderId),
                new SqlParameter("@DepartmentId", emp.DepartmentId),
                new SqlParameter("@Telephone", emp.Telephone),
                new SqlParameter("@Address", emp.Address),
                new SqlParameter("@Email", emp.Email),
                new SqlParameter("@Remarks", emp.Remarks),
                new SqlParameter("@Resume", emp.Resume),
                new SqlParameter("@Photo", emp.Photo),
                new SqlParameter("@Nation", emp.Nation),
                new SqlParameter("@NativaPalce", emp.NativePlace),
            ;
            return SqlHelper.ExecuteNonQuery(sql, Parameter) > 0;
        

DictionaryService类

这个类用来存放获取Dictionary表中的数据方法,应用于赋值给comboBox的功能.

1. GetComboList方法

获取Dictionary表中的信息,返回DataTable数据类型

        public DataTable GetComboList(string para)
        
            string sql = "select * from Dictionary where Category = @para";
            SqlParameter param = new SqlParameter("@para", para);
            return SqlHelper.GetDataTable(sql, param);
        

DepartmentService类

用于存放对部门进行操作的一些方法,包括添加部门,删除部门以及获取部门列表功能

1. InsertDepartment方法

添加新部门到数据库中

        public bool InsertDepartment(string name)
        
            string sql = "INSERT INTO Department(Id, Name) VALUES(NEWID(), @Name)";
            SqlParameter paramName = new SqlParameter("@Name", name);
            int n = SqlHelper.ExecuteNonQuery(sql, paramName);
            return n > 0;
        

2. deleteDepartment方法

从数据库中删除对应的部门信息

        public bool deleteDepartment(string name)
        
            string sql = "delete from Department where Name = @Name";
            SqlParameter paramName = new SqlParameter("@Name", name);
            int n = SqlHelper.ExecuteNonQuery(sql, paramName);
            return n > 0;
        

3. GetDeptList方法

获取所有的部门信息

public DataTable GetDeptList()
        
            string sql = "select Id as 编号, Name as 部门名 from Department";
            return SqlHelper.GetDataTable(sql);
        

ExcelService类

1. CreateExcel方法

用来导出excel文件
首先进行判断,如果文件存储的地址为空时返回
使用SqlHelper.GetDataTable方法来把需要导出的信息查询出来存入DateTable
然后我们需要用到NPOI相关的东西,所以需要先进行引用以下这五个,大家可以自行下载或者我文件也会发在gitbubgitee上可以自取


导入方式和其他的一样,在数据层的引用右键添加引用然后浏览对应目录再勾选上五个就可以了
创建IWorkbook对象和我们的表对象ISheet,可以自己命名,然后再统计信息的行列分别有多少再创建对应的行列就可以了
格式问题可以将日期形式和编号的列宽设置长一点,修改sheetSetColumnWidth属性
为了美观再把表头的文字给居中
为了显示日期更准确,还可以重新设置一下日期的格式
最后再通过FileStream写入磁盘中完成导出Excel

public bool CreateExcel(string filePath)
        
            if (string.IsNullOrEmpty(filePath))
            
                return false;
            
            string sql = "select Id as 编号, Number as 工号, Name as 姓名, InDay as 入职时间, Nation as 民族, NativePlace as 籍贯 from Employee";
            DataTable dt =  SqlHelper.GetDataTable(sql);
            IWorkbook workbook = new HSSFWorkbook();
            ISheet sheet = workbook.CreateSheet("员工列表");
            sheet.SetColumnWidth(0, 38 * 256);
            sheet.SetColumnWidth(3, 30 * 256);
            int rowCount = dt.Rows.Count;
            int columnCount = dt.Columns.Count;
            IRow headerRow = sheet.CreateRow(0);
            IFont headerFont = workbook.CreateFont();
            ICellStyle headerStyle = workbook.CreateCellStyle();
            headerFont.FontName = "宋体";
            headerStyle.SetFont(headerFont);
            headerStyle.Alignment = HorizontalAlignment.CENTER;
            for (int j = 0; j < columnCount; j++)
            
                ICell cell = headerRow.CreateCell(j);
                cell.CellStyle = headerStyle;
                cell.SetCellValue(dt.Columns[j].ColumnName);
            
            for (int i = 1; i <= rowCount; i++)
            
                IRow row = sheet.CreateRow(i);
                for (int j = 0; j < columnCount; j++)
                
                    ICell cell = row.CreateCell(j);
                    if (j == 3)
                    
                        cell.SetCellValue((DateTime)dt.Rows[i - 1][j]);
                        ICellStyle cellStyle = workbook.CreateCellStyle();
                        
                        cellStyle.DataFormat = workbook.CreateDataFormat().GetFormat("yyyy年m月d日 hh时mm分ss秒");
                        cell.CellStyle = cellStyle;
                    
                    else
                    
                        cell.SetCellValue(dt.Rows[i - 1][j].ToString());
                    
                
            
            using (FileStream fs = new FileStream(filePath, FileMode.Create))
            
                workbook.Write(fs);
            
            return true;
        

SalarySheetService类

存放一些对工资单的操作方法

1. GetSalarySheetId方法

根据年月和部门来通过SqlHelper.ExecuteScalar获取对应的工资单ID,如果没有找到就返回Guid.Empty.

public Guid GetSalarySheetId(int month, int year, Guid departmentId)
        
            string sql = "select Id from SalarySheet where Year = @year and Month = @month and DepartmentId = @deptId";
            SqlParameter[] para = 
                new SqlParameter("@year", year),
                new SqlParameter("@month", month),
                new SqlParameter("@deptId", departmentId),
            ;
            Object Id = SqlHelper.ExecuteScalar(sql, para);
            if (Id != null)
            
                return (Guid)Id;
            
            else
            
                return Guid.Empty;
            
        

2. BuildNewSalarySheet方法

新建新的工资表,并返回对应的工资单的编号

public Guid BuildNewSalarySheet(SalarySheet sheet)
        
            string sql = "insert into SalarySheet(Id, Year, Month, DepartmentId) values(@Id, @Year, @Month, @DeptId)";
            SqlParameter[] para =
            
                new SqlParameter("@Id", sheet.Id),
                new SqlParameter("@Year", sheet.Year),
                new SqlParameter("@Month", sheet.Month),
                new SqlParameter("@DeptId", sheet.DepartmentId),
            ;
            SqlHelper.ExecuteNonQuery(sql, para);
            return sheet.Id;
        

SalarySheetItemService类

存放一些工资表的详细信息的操作方法

1. BuildSalarySheetItems方法

新建新的工资单详细信息

使用sql1来找到对应的员工id,再使用sql2来把员工信息和初始化的工资信息存入数据库中.

public void BuildSalarySheetItems(Guid sheetId, Guid deptId)
        
            string sql1 = "select Id from Employee where DepartmentId = @deptId";
            string sql2 = "insert into SalarySheetItem(Id, SheetId, EmployeeId, BaseSalary, Bonus, Fine, Other) values(@Id, @SheetId, @EmployeeId, 0, 0, 0, 0)";
            SqlParameter parameter = new SqlParameter("@deptId", deptId);
            SqlDataReader sdr = SqlHelper.ExecuteReader(sql1, parameter);
            while (sdr.Read())
            
                SqlParameter[] para = new SqlParameter[]
                
                    new SqlParameter("@Id", Guid.NewGuid()),
                    new SqlParameter("@SheetId", sheetId),
                    new SqlParameter("@EmployeeId", sdr["Id"]),
                ;
                SqlHelper.ExecuteNonQuery(sql2, para);  
            
        

2. GetSalarySheetItems方法

通过sql查询语句将数据库中的工资单详细信息找出来并且将EmployeeId变成对应的员工姓名,返回一个DataTable用来传给界面中显示.

        public DataTable GetSalarySheetItems(Guid sheetId)
        
            string sql = "select SalarySheetItem.Id as 编号, Employee.Name as 姓名, SalarySheetItem.BaseSalary as 基本工资, SalarySheetItem.Bonus as 奖金, SalarySheetItem.Fine as 罚款, SalarySheetItem.Other as 其他 from SalarySheetItem, Employee where SheetId = @sheetId and SalarySheetItem.EmployeeId = Employee.Id";
            SqlParameter para = new SqlParameter("@sheetId", sheetId);
            return SqlHelper.GetDataTable(sql, para);
        

3. ReBuildSalarySheetItem方法

重新生成新的工资单信息,将工资信息都初始化为0

        public void ReBuildSalarySheetItem(Guid sheetId)
        
            string sql = "update SalarySheetItem set BaseSalary = 0, Bonus = 0, Fine = 0, Other = 0 where SheetId = @sheetId";
            SqlParameter para = new SqlParameter("@sheetId", sheetId);
            SqlHelper.ExecuteNonQuery(sql, para);
        

4. SaveSheetItem方法

将被修改的工资信息在数据库中更新

        public void SaveSheetItem(SalarySheetItem sheetitem)
        
            string sql = "update SalarySheetItem set BaseSalary = @base, Bonus = @bonus, Fine = @fine, Other = @other where Id = @id";
            SqlParameter[] para = new SqlParameter[]
            
                new SqlParameter("@base", sheetitem.BaseSalary),
                new SqlParameter("@bonus", sheetitem.Bonus),
                new SqlParameter("@fine", sheetitem.Fine),
                new SqlParameter("@other", sheetitem.Other),
                new SqlParameter("@id", sheetitem.Id),
            ;
            SqlHelper.ExecuteNonQuery(sql, para);
        

5. GetReportSheet方法

返回一个报表的DataTable

        public DataTable GetReportSheet(Guid sheetId)
        
            string sql = "select SalarySheet.Year as year,SalarySheet.Month as month,Department.Name as dept,SalarySheetItem.Id ,Employee.Name as name ,BaseSalary as baseSalary ,Bonus as bonus,Fine as fine ,Other as other from SalarySheetItem ,Employee,SalarySheet ,Department where SheetId=@SheetId and SalarySheetItem.EmployeeId=Employee.Id and SalarySheetItem.SheetId=SalarySheet.Id and SalarySheet.DepartmentId=Department.Id";
            SqlParameter para = new SqlParameter("@SheetId", sheetId);
            return SqlHelper.GetDataTable(sql, para);
        

BLL业务逻辑层

SystemGuard类

创建HRMSystem.BLL类库当作业务逻辑层
新建一个类叫SystemGuard,用来进行登录用户的身份判断
包含一个check方法和一个枚举类型用来存放不同的身份
check方法中调用OperatorService中的GetOperator方法获取操作员的信息,然后进行判断,从而返回不同的枚举类型,从而实现对于不同的登录信息做出不同的响应.

    public class SystemGuard
    
        public UserType check(string un, string pwd)
        
            OperatorService opSev = new OperatorService();
            Operator op = opSev.GetOperator(un);
            if (op == null) return UserType.noUser;
            else if (op.Password != pwd) return UserType.pwdError;
            else if (op.UserName == "admin") return UserType.admin;
            else if (op.IsLocked) return UserType.locked;
            else if (op.IsDeleted) return UserType.deleted;
            else return UserType.validUser;
        
        public enum UserType  validUser, pwdError, noUser, locked, deleted, admin;
    

LoginUser类

这个类是使用单例模式用来对于已经登录的用户进行信息的存放和读取,便于其他功能调用.
其中InitMember方法是将登录的用户信息存入op对象中
GetInstance方法用来在其他地方获取到当前用户的信息.

public class LoginUser
    
        public Guid Id  get; set; 
        public string UserName  get; set; 
        public string Password  get; set; 
        public bool IsDeleted  get; set; 
        public string RealName  get; set; 
        public bool IsLocked  get; set; 
        private static LoginUser lu = null;
        private LoginUser()
        
        
        public static LoginUser GetInstance()
        
            if(lu == null)
            
                lu = new LoginUser();
            
            return lu;
        
        public void InitMember(string un)
        
            OperatorService opSev = new OperatorService();
            Operator op = opSev.GetOperator(un);
            if(op != null)
            
                lu.Id = op.Id;
                lu.RealName = op.RealName;
                lu.Password = op.Password;
                lu.UserName = op.UserName;
                lu.IsDeleted = op.IsDeleted;
                lu.IsLocked = op.IsLocked;
            
        
    

EmptyJudge类

用来进行一些是否为空的判定

isSheetExist方法用来判断是否存在该Sheet工资单

isEmployeeExist方法用来判断在对应部门里是否存在员工

注意:当使用ExecuteScalar来查询count(*)的时候如果没有查询到记录返回的将是-1,而不是0

public bool isSheetExist(int month, int year, Guid deptId)
        
            string sql = "select count(*) from SalarySheet where Year = @year and Month = @month and DepartmentId = @deptId";
            SqlParameter[] para = 
                new SqlParameter("@year", year),
                new SqlParameter("@month", month),
                new SqlParameter("@deptId", deptId),
            ;
            if ((int)SqlHelper.ExecuteScalar(sql, para) > 0)
            
                return true;
            
            else
            
                return false;
            

        
        public bool isEmployeeExist(Guid depId)
        
            string sql = "

以上是关于无标题的主要内容,如果未能解决你的问题,请参考以下文章

PTA第三次作业

这工资不要也罢,女朋友不要也罢,三十年河东,三十年河西,莫欺少年穷!

我想问一下,软件测试都做什么入行居然能拿12K以上的工资?

工资管理系统的接口设计

工资系统--练习文件的操作(增改查)

蘑菇街裁员回复覆巢之下无完卵