C#桌面办公应用-工资管理系统系列五

接前文系列四,本文将讲解实现工资管理系统的代码的层次结构。主要采用的是MVCS模式的代码层次结构,视图层(V):是各种winform窗体;控制层(C):主要是winform窗体中各种控件的各个逻辑处理事件;而模型层(M)则是各个model实体以及数据库访问层的代码;最后是服务层(S):是从模型层(M)中获取数据库访问操作的结果并为逻辑控制处理层(C)提供服务的层次。除此之外,还有另外的几个层次:工具类层util:主要是本系统共用的一些工具类的操作;报表打印层report:主要是在处理报表方面的共有操作;公共信息层commonMessage:主要是存放本系统在进行相关逻辑处理时候需要存放的一些通用的信息;最后是存放“图片或者文件”的文件层imageAndFile。如下图所示

在此说明一下,本系统其实并非传统的桌面C/S的单机版办公系统,经过测试,本系统是可以在局域网内实现服务器共享的C/S的桌面办公系统,只需要对服务器进行相应的配置,从而实现只需在每台主机安装一个本系统的客户端,就可以访问局域网内的服务器的数据了!

下面介绍一下本管理系统登录模块的实现。在前期,本管理系统的登录比较简单,只是采用userName和password明文进行登录验证而已!今天心血来潮,觉得“一个好的管理系统应该有登录功能,而登录则会涉及密码的验证,而密码的使用必然涉及到安全性问题,而安全则会不自觉跟加密解密挂上钩!”,所以,今天花了一个多小时,实现了采用MD5+自定义的字符串 实现用户登录与注册时候的密码解密与密码加密的功能,在下面会进行介绍!

下图是本系统用户登录的流程图。在贴上用户登录代码之前,需要先将获取数据库连接、数据库访问层的代码和系统共用的类的代码贴上!在系统后续的讲解中会时常使用到,但由于篇幅原因,并没有贴上全部,所以如果需要的话,可以QQ联系我QQ:1948831260(记得备注:桌面办公应用),我愿意低出售你并与你进行相关交流!

后续系统中出现SqlConnection conn = DBConnection.MyConnection(); 是从dbConnection包中获取的,主要的代码为:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;//引用SQL命名空间
using System.Windows.Forms;
namespace SMS.dbConnection
{class DBConnection//定义类型{/// <summary>/// 返回数据库连接的静态方法/// </summary>/// <returns>方法返回数据库连接对象</returns>public static SqlConnection MyConnection(){return new SqlConnection(//创建数据库连接对象
@"server=.;database=db_SMS;uid=sa;pwd=123456");//数据库连接字符串}}
}

而operate和cmmUtils是在类的开始之处定义的:

        public frmLogin(){InitializeComponent();}//创建数据库操作对象DBOperate operate = new DBOperate();//工具类CommonUtils cmmUtils = new CommonUtils();

而DBOperate类和CommonUtils类的代码的作用分别为:数据库访问和共用的工具类,下面贴出各自的部分代码,下面是DBOperate类的代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Drawing;
using SMS.dbConnection;namespace SMS.dbOperation
{class DBOperate{//获取数据库链接SqlConnection conn = DBConnection.MyConnection();/// <summary>/// 操作数据库,执行各种SQL语句/// </summary>/// <param name="strSql">SQL语句</param>/// <returns>方法返回受影响的行数</returns>public int OperateData(String strSql){try{conn.Open();//打开数据库连接SqlCommand cmd = new SqlCommand(strSql, conn);//创建命令对象int i = (int)cmd.ExecuteNonQuery();//执行SQL命令conn.Close();//关闭数据库连接return i;//返回数值}catch (System.Exception ex){return -1;}}/// <summary>/// 根据SQL语句查询返回n行数据/// </summary>/// <param name="sql"></param>/// <param name="conn"></param>/// <returns></returns>public SqlDataReader getSQLData(String sql,SqlConnection conn){conn.Open();SqlCommand cmd = new SqlCommand(sql, conn);SqlDataReader sdr = cmd.ExecuteReader();return sdr;}/// <summary>/// 方法用于绑定DataGridView控件/// </summary>/// <param name="dgv">DataGridView控件</param>/// <param name="sql">SQL语句</param>public void BindDataGridView(DataGridView dgv, String sql){SqlDataAdapter sda = new SqlDataAdapter(sql, conn);//创建数据适配器对象DataSet ds = new DataSet();//创建数据集对象sda.Fill(ds);//填充数据集dgv.DataSource = ds.Tables[0];//绑定到数据表ds.Dispose();//释放资源}/// <summary>/// 查找某个字段数量/// </summary>/// <param name="strsql">SQL语句</param>/// <returns>方法返回指定记录的数量</returns>public int HumanNum(String strsql){conn.Open();//打开数据库连接SqlCommand cmd = new SqlCommand(strsql, conn);//创建命令对象int i = (int)cmd.ExecuteScalar();//执行SQL命令conn.Close();//关闭数据库连接return i;//返回数值}/// <summary>/// 根据数据库字段组成的sql语句,查询返回的结果集也是对应需要查询的数据库字段的值/// </summary>/// <param name="sql">sql中指定了要查询的字段</param>/// <param name="fieldNames">数据库字段数组</param>/// <returns></returns>public String[] GetDatasFromSelectedTable(String sql,String[] fieldNames){SqlDataAdapter sda = new SqlDataAdapter(sql, conn);//创建数据适配器对象DataSet ds = new DataSet();//创建数据集sda.Fill(ds);//填充数据集ds.Dispose();//释放资源//MessageBox.Show(ds.Tables[0].Rows.Count+"");String[] dataResults=new String[fieldNames.Length];if (ds.Tables[0].Rows.Count==0){return null;}for (int i = 0; i < fieldNames.Length;i++ ){dataResults[i] = ds.Tables[0].Rows[0][fieldNames[i]].ToString().Trim();}return dataResults;}/// <summary>/// 使用此方法可以得到数据集/// </summary>/// <param name="sql">SQL语句</param>/// <returns>方法返回数据集</returns>public DataSet GetTable(String sql){SqlDataAdapter sda = new SqlDataAdapter(sql, conn);//创建数据适配器对象DataSet ds = new DataSet();//创建数据集sda.Fill(ds);//填充数据集ds.Dispose();//释放资源return ds;//返回数据集}/// <summary>/// //绑定下拉列表/// </summary>/// <param name="strTable">数据库表名</param>/// <param name="cb">ComboBox对象</param>/// <param name="i">指定数据列索引</param>public void BindDropdownlist(String strSQL, ComboBox cb, int i){conn.Open();//打开数据库连接SqlCommand cmd = new SqlCommand(strSQL, conn);SqlDataReader sdr = cmd.ExecuteReader();//得到数据读取器while (sdr.Read()){cb.Items.Add(sdr[i].ToString().Trim());//添加信息}conn.Close();//关闭数据库连接}}
}

下面是CmmUtils类的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;namespace SMS.utils
{class CommonUtils{/// <summary>/// 为GetDatasFromSelectedTable方法提供sql参数/// </summary>/// <param name="fieldNames">要查询数据库表的字段名</param>/// <param name="tempSQL">是拼接后的数据库语句的from后面的部分</param>/// <returns></returns>public String organizeSqlStatementWithFields(String[] fieldNames, String tempSQL){StringBuilder strSql = new StringBuilder("select ");for (int i = 0; i < fieldNames.Length; i++){if (i != fieldNames.Length - 1){strSql.Append(fieldNames[i] + ",");}else{strSql.Append(fieldNames[i]);}}strSql.Append(tempSQL);return strSql.ToString();}/// <summary>/// 获取系统当前的日期和时间/// </summary>/// <returns></returns>public String getSystemCurrentTime(){StringBuilder sb = new StringBuilder("");sb.Append(DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.DayOfWeek.ToString() + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString());return sb.ToString();}//只能输入数字public void onlyInputDigitNumber(object sender, KeyPressEventArgs e){if (((int)e.KeyChar < 48 || (int)e.KeyChar > 57) && (int)e.KeyChar != 8){e.Handled = true;}}//只能输入数字和小数点,小数点只能一位且不能在第一位public void onlyInputDigitAndDotNumber(object sender, KeyPressEventArgs e,TextBox textBox){if (e.KeyChar != 8 && e.KeyChar != 13 && e.KeyChar != 46 && !char.IsNumber(e.KeyChar)){e.Handled = true;}if (e.KeyChar == 46 && textBox.Text.Length == 0){e.Handled = true;return;}int a = 0;try{a = textBox.Text.ToString().Trim().Split('.').Length;}catch { }if (e.KeyChar == 46 && a > 1){e.Handled = true;}}//只能下拉选择public void onlyDropDownToSelect(object sender, KeyPressEventArgs e){MessageBox.Show("请进行下拉选择而无需手动填写!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);e.Handled = true;}}
}

(1)首先贴上没有解密的用户登录代码:

        //登录事件private void buttonLogin_Click(object sender, EventArgs e){try{string userName = textBoxUserName.Text.Trim();string userPwd = textBoxPwd.Text.Trim();if (userName == "" || userPwd == ""){MessageBox.Show("用户名或密码不能为空!", "友情提示", MessageBoxButtons.OK, MessageBoxIcon.Information);return;}else{SqlConnection conn = DBConnection.MyConnection();String sql = "select * from tb_employee where loginName='"+userName+"' and loginPassword='"+userPwd+"'";SqlDataReader sdr=operate.getSQLData(sql, conn);sdr.Read();//存在该用户名与密码if (sdr.HasRows){conn.Close();this.Hide();CommonMessage.userName = userName;CommonMessage.userPassword = userPwd;String[] selFieldNames = new String[]{"powerName"};String tempSQL=" from tb_employee,tb_powerType where tb_employee.powerId=tb_powerType.powerId and tb_employee.loginName='"+userName+"'";String strSql=cmmUtils.organizeSqlStatementWithFields(selFieldNames, tempSQL);String[] dataResults = operate.GetDatasFromSelectedTable(strSql.ToString(), selFieldNames);CommonMessage.userPower = dataResults[0];Console.Write(userName + "--" + userPwd + "--" + CommonMessage.userPower);frmMain fMain = new frmMain();fMain.ShowDialog();}else{//清空文本内容textBoxUserName.Text = "";textBoxPwd.Text = "";MessageBox.Show("用户名或密码错误!", "友情提示", MessageBoxButtons.OK, MessageBoxIcon.Information);frmLogin_Activated(sender, e);}}}catch (System.Exception ex){MessageBox.Show(ex.Message + "\n请与管理员联系!", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Information);}}

(2)接着贴上有MD5加解密的用户登录的代码:

        //加密解密工具MD5EncryptAndDecrypt md5 = new MD5EncryptAndDecrypt();//登录事件private void buttonLogin_Click(object sender, EventArgs e){try{string userName = textBoxUserName.Text.Trim();string userPwd = textBoxPwd.Text.Trim();if (userName == "" || userPwd == ""){MessageBox.Show("用户名或密码不能为空!", "友情提示", MessageBoxButtons.OK, MessageBoxIcon.Information);return;}else{String[] loginFieldNames = new String[]{"loginPassword","loginKey"};String tempSQL = " from tb_employee where loginName='" + userName + "'";String strSql = cmmUtils.organizeSqlStatementWithFields(loginFieldNames, tempSQL);Console.WriteLine(strSql);String[] dataResults = operate.GetDatasFromSelectedTable(strSql.ToString(), loginFieldNames);if (dataResults==null){MessageBox.Show("该用户名不存在!", "友情提示", MessageBoxButtons.OK, MessageBoxIcon.Information);}else{//Console.WriteLine("密码密文: " + dataResults[0] + "\n密码密钥: " + dataResults[1]);String loginPasswordEncrypt = dataResults[0];String loginKeyTemp = dataResults[1];String loginKeyReal = loginKeyTemp.Substring(0, loginKeyTemp.IndexOf(CommonMessage.lastKeyStr));//MessageBox.Show(loginKeyReal);String loginPasswordDecrypt = md5.MD5Decrypt(loginPasswordEncrypt, loginKeyReal);if (!userPwd.Equals(loginPasswordDecrypt)){MessageBox.Show("用户密码错误!", "友情提示", MessageBoxButtons.OK, MessageBoxIcon.Information);}else{//MessageBox.Show("登陆成功!", "友情提示", MessageBoxButtons.OK, MessageBoxIcon.Information);this.Hide();CommonMessage.userName = userName;CommonMessage.userPassword = userPwd;String[] selFieldNames = new String[]{"powerName"};String tempPowerSQL = " from tb_employee,tb_powerType where tb_employee.powerId=tb_powerType.powerId and tb_employee.loginName='" + userName + "'";String strPowerSql = cmmUtils.organizeSqlStatementWithFields(selFieldNames, tempPowerSQL);String[] dataPowerResults = operate.GetDatasFromSelectedTable(strPowerSql.ToString(), selFieldNames);CommonMessage.userPower = dataPowerResults[0];Console.Write(userName + "--" + userPwd + "--" + CommonMessage.userPower);frmMain fMain = new frmMain();fMain.ShowDialog();}}}}catch (System.Exception ex){MessageBox.Show(ex.Message + "\n请与管理员联系!", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Information);}}

其中,MD5EncryptAndDecrypt 功能包括:产生密钥,加密密码明文为密码密文,解密密码密文为密码明文。其源代码可以参考我的下一篇博客!

在这里需要说明的,本系统虽然是MD5,但还在密钥Key中还拼接上了一段自定义的字符串,在本系统中为“520lancy”,所以在解密的时候需要去掉这段自定义的字符串,截断的代码为上述代码的String loginKeyReal = loginKeyTemp.Substring(0, loginKeyTemp.IndexOf(CommonMessage.lastKeyStr)); 其中CommonMessage.lastKeyStr即为自定义的那段字符串。

下面是效果!登录界面和登录过程的处理以及成功后的主界面!

下文将介绍MD5加密的简要原理以及我采用C#实现并将其应用在本系统的源代码!

C#桌面办公应用-工资管理系统系列五相关推荐

  1. C#桌面办公应用-工资管理系统系列六

    C#桌面办公应用-工资管理系统系列六 接前文系列五,本文将讲解自主开发的工资管理系统中的员工管理模块:主要包括"员工初始化信息加载","员工信息综合查询与分页查询&quo ...

  2. C#桌面办公应用-工资管理系统系列七

    C#桌面办公应用-工资管理系统系列七 接前文工资管理系统系列六,本文将介绍C# winform应用程序中的查询模块功能.其中,就包括了综合.模糊查询以及分页查询:值得说明的是,综合查询,其实就是多个条 ...

  3. C#桌面办公应用-工资管理系统系列四

    C#桌面办公应用-工资管理系统系列四 已经好久没写博客了!!!今天就重拾旧业,继续我的博客之旅. 紧接着上面关于C#桌面办公应用-工资管理系统系列一到三的内容,博客接下来可能会有比较多的系列,用于介绍 ...

  4. 人事办公考勤工资管理系统(ssm,mysql)

    人事办公考勤工资管理系统(ssm,mysql)(毕业论文10000字以上,程序代码,MySQL数据库) [运行环境]  IDEA  JDK1.8 Mysql 代码下载网址:  链接:https://p ...

  5. 计算机会计学ufo报表,计算机会计实践部分工资管理系统.ppt

    <计算机会计实践部分工资管理系统.ppt>由会员分享,可在线阅读,更多相关<计算机会计实践部分工资管理系统.ppt(22页珍藏版)>请在人人文库网上搜索. 1.计算机会计学,主 ...

  6. 《vue3+ts+element-plus 后台管理系统系列》之微前端版本

    系列文章目录 <vue3+ts+element-plus 后台管理系统系列一>之简介 <vue3+ts+element-plus 后台管理系统系列二>之布局 <vue3+ ...

  7. vb和php一起开发,基于VB和PHP开发在线人事工资管理系统

    计 算机 科 学 消费 电子 年 月 下 基于 和 开发在线人事工资管理系统 孙 丽 娜 (哈 尔滨铁 道 职 业技 术 学 院 ,哈 尔滨 ) 摘 要 :人事 工资管理 系统越 来越 多的应 用于企 ...

  8. [附源码]JAVA+ssm计算机毕业设计高校工资管理系统(程序+Lw)

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

  9. [附源码]Java计算机毕业设计SSM高校工资管理系统

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

最新文章

  1. [Ruby01]Class, Module, Object,Kernel的关系
  2. linux根分区扩容(LVM动态卷)
  3. Servlet+MySQL使用DBCP数据库连接池实现用户登录
  4. Delphi中JSon SuperObject 使用:数据集与JSON对象互转
  5. 从NoSQL到Lakehouse,Apache Doris的13年技术演进之路
  6. 微信小程序项目实战知识点总结(swiper组件自适应高度,自定义弹出层,悬浮按钮,虚拟键盘)...
  7. Opportunity retrieval in SalesPipeline
  8. 他高考数学仅得15分,清华校长复查后激动拍板:这名学生,我要了
  9. 一本书看懂数字化转型|全新《2021年度案例观察》限时免费送
  10. dj鲜生-09-商品应用-首页的显示
  11. js进阶 11-15 jquery过滤方法有哪些
  12. android ichartjs 曲线图,C#中利用LightningChart绘制曲线图表
  13. 《Java设计模式》刘伟 超清晰版本 下载链接
  14. 条形码的码制分类详解
  15. iOS逆向 和班尼特福迪一起攻克难关(unity)
  16. Java集合这样子学习
  17. 如何在计算机里查找最新文件,在电脑上怎么查找目标文件
  18. C++ 0xc0000417 错误
  19. Vue中使用tailwindcss
  20. java制作音乐播放器教程_教你轻松制作java音乐播放器

热门文章

  1. Redis监控和预警
  2. 分子对接结果分析和作图
  3. UE5/C++ 基于GAS的角色升级 7.2 准备好经验奖励效果GE
  4. Unity WebGL开发问题
  5. Java程序员11面阿里,错失offer,期间还面了EMC+网易+美团......
  6. 大疆无人机安卓Mobile Sdk开发(四)读取飞机的图片和视频并下载
  7. 史上公认的最好学习方法, 学英语者的福利
  8. 如何垂直居中对齐CSS[转载]
  9. 银行家算法——C++实现 [ 开源代码 + 详细解析 ]
  10. 打印银行类,创建银行,实现存钱,取钱,转账