ASP.NET人事管理系统课程设计

前言

疫情耽搁的这段时间里,一直在家上网课,回校后转眼间又迎来了期末季,唉苦不堪言的大学生活。

这一次我的课程设计是利用ASP.NET做一套人事管理系统,鉴于还得写报告书,所以写代码的过程中顺便记录一篇文章好总结报告。

此次的技术栈选型是:ASP.NET、C#、HTML/CSS、JavaScript。

本项目将开源在GitHub,不推荐作商业用途,安全机制、细节不够完善,仅毕设练手作品。

数据库设计

课堂上老师颁发了每个人的系统数据文本,然后再根据数据进行录入新建数据库中(为什么老师不直接发数据库?呜呜呜),经过我对 Microsoft Visual Studio 2008 的一番风云对决之后,终于完成了数据库的录入。

分别有通讯录表、日常记事、家庭关系表、登录表、奖惩表、培训记录表、个人简历表、人事资料表、省市表、民族表、职务表、部门表。总计12张表。(呜呜好多表啊老师我想kill你的心都有了)

在这里插入图片描述

在这里插入图片描述

需求分析、功能划分

然后简单地划分一下需求,终于才好搭建页面导航功能。

这里的图片仅作参考,实际情况还得改更多细节。

在这里插入图片描述

项目目录结构

这里的目录结构仅作参考,实际情况还得改更多细节。

在这里插入图片描述

这里稍微解释一下我的页面所属功能:

  • Stuffbusic 人事档案
  • WordResume 简历信息
  • TrainNote 培训记录
  • Randp 奖惩信息
  • Family 家庭信息
  • DayWordPad 日常记事
  • AddressBook 通讯信息
  • Branch 部门统计
  • Business 职务统计
  • Folk 民族统计
  • City 省市统计

数据库模型层

我们在日常开发时,通常情况下都会写到重复的代码逻辑,这个时候就需要懂得利用封装技巧去复用代码逻辑了;这里的数据库模型层通常也称作为数据持久层,主要用于处理数据库连接、执行查询,返回结果集,执行增,删,改的基层方法,还有一些分页逻辑等等,都会选择封装在一个文件,给外部去调用此处的方法。

值得一提的是,这里的封装方法都需要调用C#其中的一些类:

using System.Data;
using System.Data.SqlClient;
using System.Configuration;//调用web.config公共配置文件

当我们想要从其他文件中调用这些方法,可以直接输出该文件名称,就可以看到代码提示了,还能看到其中的所有方法。

在这里插入图片描述

登陆验证模块

再做登陆验证逻辑之前,我们先把静态页面搭起来:

在这里插入图片描述

login.aspx页面代码:

<form id="form1" runat="server">
    <div class="loginBody">
        <h2>人事管理系统登录</h2>
        <br />
        <hr />
        <br />
        <asp:Label ID="Label1" runat="server" Text="账号:" ></asp:Label>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <asp:Label ID="Label2" runat="server" Text="密码:"></asp:Label>
        <asp:TextBox ID="TextBox2" runat="server" TextMode="Password"></asp:TextBox><br />
        <asp:Button ID="Button1" runat="server" Text="登录" OnClick="Button1_Click" CssClass="btnHover"/>
        <br />
        <asp:Label ID="Label3" runat="server" Text="默认账号密码:admin,123" Font-Size="X-Small" ForeColor="#990000"></asp:Label>
    </div>
</form>

我们可以看到,其实ASP.NET的控件代码可以和HTML完美融合在一起写,只需要注意数据控件用ASP.NET的控件就可以了。

index.css样式代码,这里的index.css文件我会继续补充,所以不单止登陆页面的样式。(不分样式文件是因为所需要写的样式代码并不多,少而精的样式才是最好的)

/*登录框*/

.loginBody {
    position: fixed;
    left: 50%;
    top: 50%;
    width: 250px;
    padding: 40px;
    background: #fff;
    border-radius: 10px;
    box-shadow: 5px 5px 30px rgba(0,0,0,.1);
    transform: translate(-50%,-50%);
    animation: fadein ease-in-out .5s forwards;
}
.loginBody h2{
    text-align:center;
}

@keyframes fadein {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}
.btnHover {
    cursor: pointer;
}
.btnHover:hover {
    border: 2px solid #aaa;
    box-shadow: 2px 2px 10px rgba(0,0,0,.2)
}

.loginBody input {
    outline: none;
    width: 90%;
    font-size: 18px;
    box-sizing: border-box;
    padding: 5px 10px;
    margin: 10px;
    border-radius: 5px;
    border: 2px solid #eee;
    transition: all .3s;
    background: #eee;
    color: #666;
    font-weight: 400;
}

.loginBody input:focus {
    border: 2px solid #aaa;
}

接下来点击登陆的事件就涉及到后台权限的模块了,所以继续往下看吧。

后台权限模块

登陆成功之后,我们当然要进入到一个后台管理主页啦,先来实现静态页面吧,然后我们再来实现权限登陆的操作,相信小白对权限这块处理还是有点懵的,所以这里是重点内容。

在这里插入图片描述
home.aspx页面代码:

<form id="form1" runat="server">
    
<div class="main">
    <div class="navBody">
        <div class="logo">
            <h3 style="text-align:center">人事管理系统</h3>
            <br />
            <hr />
            <br />
        </div>
    </div>
    <div class="header">
        <asp:Button ID="Button1" runat="server" Text="退出登录" OnClick="Button1_Click" />
    </div>
    <div class="mainBody">
        <iframe src="pages/index.aspx" frameborder="0" width="100%" height="100%" name="iframe"></iframe>
    </div>
</div>
</form>

home样式,我们加在index.css里面(排版不好看莫怪,VS自动缩进怪恶心的):

/*主页*/
.main {
    position: relative;
    width: 100%;
}

.header {
    box-sizing: border-box;
    width: 100%;
    background: #fff;
    border-bottom: 1px solid #ccc;
    text-align: right;
    padding: 20px;
    font-size: 14px;
}

.navBody {
    position: fixed;
    width: 20%;
    left: -20%;
    overflow: hidden;
    min-height: 100vh;
    background-color: #fff;
    padding: 20px;
    box-sizing: border-box;
    border-right: 1px solid #ccc;
    animation: fadeleft .3s ease-in-out forwards;
    opacity: 0;
    z-index: 2;
}

@keyframes fadeleft {
    0% {
        opacity: 0;
        left: -20%;
    }

    100% {
        opacity: 1;
        left: 0%;
    }
}

.navBody ul li a {
    box-sizing: border-box;
    width: 100%;
    text-align: center;
    transition: all .3s;
    display: inline-block;
    padding: 10px;
    margin: 5px;
    text-shadow: 2px 2px 5px rgba(0,0,0,.1);
    border: 2px solid #fff;
}

    .navBody ul li a:hover {
        color: #000;
        text-shadow: 2px 2px 8px rgba(0,0,0,.1);
        border: 2px solid #999;
        box-shadow: 5px 5px 20px rgba(0,0,0,.2)
    }
.navBody ul li{
    transition:all .3s;
}
.navBody ul li:active {
    transform: scale(.8);
}

.activeNav {
    color: #000;
    text-shadow: 2px 2px 8px rgba(0,0,0,.1);
    border: 2px solid #000 !important;
    box-shadow: 5px 5px 20px rgba(0,0,0,.2)
}

.mainBody {
    position: absolute;
    width: 80%;
    min-height: 100vh;
    background-color: #eee;
    padding: 20px;
    margin-left: 20%;
    box-sizing: border-box;
}

    .mainBody iframe {
        animation: fadeup ease-in-out .5s forwards;
    }
@keyframes fadeup {
    0% {
        opacity: 0;
        transform: translate(0,10%)
    }

    100% {
        opacity: 1;
        transform: translate(0,0)
    }
}

.header {
    animation: fadein ease-in-out .5s forwards;
}

    .header input {
        padding: 5px 10px;
        border: 2px solid #999;
        transition: all .2s;
    }

        .header input:hover {
            cursor: pointer;
            box-shadow: 2px 2px 10px rgba(0,0,0,.2)
        }

home.aspx页面,需要注意的有两点:

第一点,我们这里的菜单导航是根据当前用户所拥有的权限进行渲染出来的,我们这里的思路是,用户登陆验证之后,再进行验证是否管理员用户,假如是管理员,则向浏览器填充cookie值,键为isAdmin,值为true,假如是普通用户则值为false,这样我们就能从浏览器取得cookie值进行渲染不同的菜单导航。

第二点,点击选取页面,把相应的页面渲染在iframe标签载体中,实现页面嵌套。

所以我们用JavaScript先来实现这些操作:

//js/index.js

//cookies 封装
function getCookie(cname) {
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i].trim();
        if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
    }
    return "";
}

window.onload = function () {
    

    //渲染菜单
    function innerNav(callback) {
        let isAdmin = `
<ul>
    <li><a href="pages/index.aspx" target="iframe" class="activeNav">个人主页</a></li>
    <li><a href="pages/Stuffbusic.aspx" target="iframe">个人记事</a></li>
    <li><a href="pages/WordResume.aspx" target="iframe">个人简历</a></li>
    <li><a href="pages/Stuffbusic.aspx" target="iframe">个人资料</a></li>
    <li><a href="pages/Randp.aspx" target="iframe">个人奖惩</a></li>
</ul>
`
        let isUser = `
<ul>
    <li><a href="pages/index.aspx" target="iframe" class="activeNav">个人主页</a></li>
</ul>
`
        let isUserTitle = `
<p style="display:inline-block;margin:20px">欢迎!普通用户</p>
`
        let isAdminTitle = `
<p style="display:inline-block;margin:20px">欢迎!管理员</p>
`

        if (getCookie('isAdmin') == 'true') {
            document.querySelector('.navBody').innerHTML += isAdminTitle + isAdmin;
            callback();
        } else if (getCookie('isAdmin') == 'false') {
            document.querySelector('.navBody').innerHTML += isUserTitle + isUser;
            callback();
        }

    }


    //点击切换按钮 需要渲染完菜单才能获取元素进行监听 所以用到异步回调处理
    innerNav(function () {
        let aLink = document.querySelectorAll('.navBody ul li a');
        for (i in aLink) {
            aLink[i].index = i;
            aLink[i].onclick = function () {
                //console.log(aLink[this.index])
                for (i in aLink) {
                    aLink[i].className = ' ';
                }
                aLink[this.index].className = 'activeNav';
            }
        }
    });
}

接下来完善一下login.aspx.cs页面点击登陆之后执行的事情,这里主要实现几点:

第一点,配置web.config公共文件连接数据库,配置sqlHelper数据持久化文件。

web.config文件name 属性 值 必须与 sqlHelper.cs文件的ConnectionStrings值一致,我这里统一PersonnelConnectionString

web.config

//name 属性 值 必须与 
<connectionStrings>
    <add name="PersonnelConnectionString" connectionString="Data Source=.;Initial Catalog=Personnel;Persist Security Info=True;User ID=sa;Password=123456"
providerName="System.Data.SqlClient" />
</connectionStrings>

sqlHelper.cs

public static readonly string ConnectionStringLocalTransaction = ConfigurationManager.ConnectionStrings["PersonnelConnectionString"].ConnectionString;

第二点,连接数据库进行判断用户输入的账号密码是否正确。

第三点,根据用户的权限进行判断填充cookie值。

第四点,当用户已经在登陆状态时,直接跳转至后台主页。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;//调用web.config公共配置文件

public partial class index : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //检测cookies,用户是否已经登陆
        try
        {
            if (Request.Cookies["isAdmin"] != null)
            {
                Response.Redirect("home.aspx");
            }
        }
        catch{
            return;
        }
    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        
        //获取输入的文本值
        string tName = TextBox1.Text.ToString().Trim();
        string tPass = TextBox2.Text.ToString().Trim();

        if(tName == "" || tPass == "")
        {
            //用户提示
            Label3.Text = "请输入账号或密码!";
            return;
        }

        //连接数据库获取信息
        string SqlCmd = "select * from tb_Login where Name = '"+ tName + "'";
        DataTable DT = SqlHelper.ExcuteDataQuery(SqlCmd);

        //当影响行大于1 表示获取成功
        if (DT.Rows.Count > 0)
        {
            //获取sql值
            string sName = DT.Rows[0]["Name"].ToString();
            string sPass = DT.Rows[0]["Pass"].ToString();

            //验证是否管理员登陆
            if (tName == "admin" && tPass == sPass)
            {
                //设置Cookies 一小时过期
                Response.Cookies["isAdmin"].Value = "true";
                Response.Cookies["isAdmin"].Expires = DateTime.Now.AddHours(1);
                Response.Redirect("home.aspx");
                return;
            }
            else
            {
                //验证是否普通用户登陆
                if (tName == sName && tPass == sPass)
                {
                    //设置Cookies 一小时过期
                    Response.Cookies["isAdmin"].Value = "false";
                    Response.Cookies["isAdmin"].Expires = DateTime.Now.AddHours(1);
                    Response.Redirect("home.aspx");
                    return;
                }
                else
                {
                    //用户提示
                    Label3.Text = "账号或密码错误!";
                    return;
                }
            }
        }
        else
        {
            //用户提示
            Label3.Text = "无此账号!";
            return;
        }

        
    }
}

再进行编写home.aspx.cs的代码,这里有几点需要注意:

第一点,此处还加上了退出登录功能,思路就是把cookies值清空就好了。

第二点,页面初始化时就开始检测是否有用户cookies存在,假如没有就会直接跳回登陆页面。

至此,一个简单的登陆权限就完成了。

public partial class home : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //页面初始化时检测cookies是否有用户存在
        try
        {
            if (Request.Cookies["isAdmin"] == null)
            {
                Response.Redirect("login.aspx");
            }
        }
        catch
        {
            return;
        }
    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        //退出登录
        Response.Cookies["isAdmin"].Expires = DateTime.Now.AddHours(0);
        Response.Redirect("login.aspx");
    }
}

看一下我们现在所完成的功能:在这里插入图片描述

日常记事模块

个人简历模块

个人资料模块

个人奖惩模块

人事档案模块

人员奖惩模块

分类查询搜索