登录模块
编写一个程序之前,首先需要构思他所需要的参数是什么。
这里我们使用sqlite数据库来进行存储数据
首先确定肯定需要一个ID来记录数据库的唯一属性,其次登录肯定需要用户名,密码,权限。
在Model层中创建LoginInfo
public class LoginInfo
{
public int MId { get; set; }
public string MName { get; set; }
public string MPwd { get; set; }
public LoginType MType { get; set; }
}
public enum LoginType
{
操作员 = 0,
技术员,
管理员,
程序员,
}
通过以上参数可以知道数据库需要这样设计
这里可以通过数据库工具来进行设计或者使用sql语句来进行创建
接下来我们需要构造一个通用的方法,这样可以提到重用性
在Dal层中创建SqliteHelper
private static string connStr =
ConfigurationManager.ConnectionStrings["MySQLlite"].ConnectionString;
/// <summary>
/// 得到数据库里所有的值,或者某一列的值
/// </summary>
/// <param name="sql"></param>
/// <param name="ps"></param>
/// <returns></returns>
public static DataTable GetList(string sql, params SQLiteParameter[] ps)
{
//构造连接对象
using (SQLiteConnection conn = new SQLiteConnection(connStr))
{
//构造桥接器对象
SQLiteDataAdapter adapter = new SQLiteDataAdapter(sql, conn);
//加参数查找
if (ps[0] != null)
{
adapter.SelectCommand.Parameters.AddRange(ps);
}
//数据表对象
DataTable table = new DataTable();
//将数据存到table中
adapter.Fill(table);
//返回数据表
return table;
}
}
/// <summary>
/// 对数据库进行 增,删,改
/// </summary>
/// <param name="sql"></param>
/// <param name="ps"></param>
/// <returns></returns>
public static int ExecuteNonQuery(string sql, params SQLiteParameter[] ps)
{
using (SQLiteConnection conn = new SQLiteConnection(connStr))
{
SQLiteCommand cmd = new SQLiteCommand(sql, conn);
cmd.Parameters.AddRange(ps);
conn.Open();
return cmd.ExecuteNonQuery();
}
}
其中connStr 是通过UI层的App.config中获得的,当然也可以直接在源码里写死
<configuration>
<connectionStrings>
<add name="MySQLlite" connectionString="data source=data\data.db;version=3"/>
</connectionStrings>
</configuration>
接下来的步骤就是我们要对数据库进行增,删,改,查
所以在Dal层中接着创建LoginDal
public class LoginDal
{
public List<LoginInfo> GetList(LoginInfo li)
{
//构造集合对象
List<LoginInfo> list = new List<LoginInfo>();
SQLiteParameter[] ps = new SQLiteParameter[2];
string sql = "select * from logininfo";
if (li != null)
{
sql += " where mname=@name and mpwd=@pwd";
ps[0] = new SQLiteParameter("@name", li.MName);
ps[1] = new SQLiteParameter("@pwd", Md5Helper.GetMd5(li.MPwd));
}
//执行查询,获取数据
DataTable table = SqliteHelper.GetList(sql, ps);
//遍历数据表,将数据转存到集合中 遍历行
foreach (DataRow row in table.Rows)
{
list.Add(new LoginInfo()
{
MId = Convert.ToInt32(row["mid"]),
MName = row["mname"].ToString(),
MPwd = row["mpwd"].ToString(),
MType = (LoginType)Enum.ToObject(typeof(LoginType), Convert.ToInt32(row["mtype"]))
});
}
//返回数据
return list;
}
public int Insert(LoginInfo li)
{
//构造sql语句
string sql =
"insert into logininfo(mname,mpwd,mtype) values(@name,@pwd,@type)";
//数组的初始化器
SQLiteParameter[] ps =
{
new SQLiteParameter("@name", li.MName),
new SQLiteParameter("@pwd",Md5Helper.GetMd5(li.MPwd)),
new SQLiteParameter("@type",li.MType)
};
//执行
return SqliteHelper.ExecuteNonQuery(sql, ps);
}
public int Delete(int id)
{
string sql = "delete from logininfo where mid=@id";
SQLiteParameter p = new SQLiteParameter("@id", id);
return SqliteHelper.ExecuteNonQuery(sql, p);
}
public int Update(LoginInfo li)
{
List<SQLiteParameter> list = new List<SQLiteParameter>();
string sql =
"update logininfo set mname=@name,";
list.Add(new SQLiteParameter("@name", li.MName));
if (!li.MPwd.Equals("******"))
{
sql += "mpwd=@pwd,";
list.Add(new SQLiteParameter("@pwd", Md5Helper.GetMd5(li.MPwd)));
}
sql += "mtype=@type where mid=@id";
list.Add(new SQLiteParameter("@type", li.MType));
list.Add(new SQLiteParameter("@id", li.MId));
string k = sql;
return SqliteHelper.ExecuteNonQuery(sql, list.ToArray());
}
public LoginInfo GetUser(int id)
{
//构造集合对象
LoginInfo li = new LoginInfo();
SQLiteParameter ps = new SQLiteParameter();
string sql = "select * from logininfo where MId=@id";
ps = new SQLiteParameter("@id", id);
//执行查询,获取数据
DataTable table = SqliteHelper.GetList(sql, ps);
//遍历数据表,将数据转存到集合中 遍历行
foreach (DataRow row in table.Rows)
{
li.MId = Convert.ToInt32(row["mid"]);
li.MName = row["mname"].ToString();
li.MPwd = row["mpwd"].ToString();
li.MType = (LoginType)Enum.ToObject(typeof(LoginType), Convert.ToInt32(row["mtype"]));
}
//返回数据
return li;
}
}
这里使用到了MD5加密,所以在COMMON层中新建一个类Md5Helper
创建静态方法
public class Md5Helper
{
public static string GetMd5(string txt)
{
//创建md5对象 工厂
MD5 md5 = MD5.Create();
//将字符串转成字节数组
byte[] bs = Encoding.UTF8.GetBytes(txt);
//加密
byte[] bs2 = md5.ComputeHash(bs);
//将字节数据转换成字符串
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bs2.Length; i++)
{
//x2代表16进制 2位 如果不写2 不补0 不会都是2位
//0-255 => 00-ff
sb.Append(bs2[i].ToString("x2").ToLower());
}
//返回
return sb.ToString();
}
}
接着需要在Bll层中进行使用,所以创建
这里使用了单例模式,避免全局函数过多的现象
#region << 版 本 注 释 >>
/*----------------------------------------------------------------
// Copyright (C) 2022 XXX单位
// 版权所有。
//
// 文件名:StandardSoftware
// 文件功能描述:登录业务逻辑层
//
//
// 创建者:liangjinhao
// 时间:2022/4/25 15:59:00
// 功能:标准化软件
//
// 修改人:
// 时间:
// 修改说明:
//
// 版本:V1.0.0
//----------------------------------------------------------------*/
#endregion
public class LoginBll
{
LoginDal liDal = new LoginDal();
/// <summary>
/// 私有化构造函数
/// </summary>
private LoginBll()
{
}
/// <summary>
/// 当前登录的人员
/// </summary>
public LoginInfo users;
/// <summary>
/// 声名一个静态变量
/// </summary>
private static LoginBll LoList;
/// <summary>
/// 单例模式
/// </summary>
/// <returns></returns>
public static LoginBll CreateLogin()
{
if (LoList == null)
{
LoList = new LoginBll();
}
return LoList;
}
/// <summary>
/// 得到当前表格所有值
/// </summary>
/// <returns></returns>
public List<LoginInfo> GetList()
{
return liDal.GetList(null);
}
/// <summary>
/// 添加
/// </summary>
/// <param name="li"></param>
/// <returns></returns>
public bool Add(LoginInfo li)
{
return liDal.Insert(li) > 0;
}
/// <summary>
/// 移除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public bool Remove(int id)
{
return liDal.Delete(id) > 0;
}
/// <summary>
/// 修改
/// </summary>
/// <param name="li"></param>
/// <returns></returns>
public bool Edit(LoginInfo li)
{
return liDal.Update(li) > 0;
}
/// <summary>
/// 登录
/// </summary>
/// <param name="li"></param>
/// <returns></returns>
public bool Login(LoginInfo li)
{
var list = liDal.GetList(li);
if (list.Count > 0)
{
users = list[0];
return true;
}
else
{
return false;
}
}
/// <summary>
/// 返回TYPE类型
/// </summary>
/// <returns></returns>
public List<LoginType> BindList()
{
List<LoginType> list = new List<LoginType>();
foreach (LoginType e in Enum.GetValues(typeof(LoginType)))
{
list.Add(e);
}
return list;
}
/// <summary>
/// 通过ID查询对象
/// </summary>
/// <returns></returns>
public LoginInfo GetUser(int id)
{
return liDal.GetUser(id);
}
/// <summary>
/// 获得用户名
/// </summary>
/// <returns></returns>
public List<string> GetName()
{
List<string> list = new List<string>();
List<LoginInfo> listLog = new List<LoginInfo>();
listLog = liDal.GetList(null);
if (listLog != null)
{
for (int i = 0; i < listLog.Count; i++)
{
list.Add(listLog[i].MName);
}
}
return list;
}
/// <summary>
/// 锁定权限
/// </summary>
public void PermissionLock()
{
users = new LoginInfo()
{
MName = "未登录",
MType = LoginType.操作员
};
}
接着,可以对UI层进行编写了
登录模块可以分为:登录,修改,新增,人员显示(显示所有的用户,包括删除功能)
登录模块
大概这样一个界面
接着需要在界面进行用户绑定,登录查询功能
public partial class SignForm : Form
{
public SignForm()
{
InitializeComponent();
this.StartPosition = FormStartPosition.CenterScreen;
Init();
}
LoginBll lb= LoginBll.CreateLogin();
public void Init()
{
cbx_用户.DataSource = lb.GetName();
cbx_用户.Text = cbx_用户.Items[0].ToString();//默认选中第一个
}
private void btn_登录_Click(object sender, EventArgs e)
{
LoginInfo li = new LoginInfo()
{
MName = cbx_用户.Text,
MPwd = tbx_密码.Text
};
if (lb.Login(li))
{
MessageBox.Show("登录成功");
this.Close();
}
else
{
MessageBox.Show("用户名或密码错误");
}
}
}
接着是更新模块
用户名使用的是一个label 通过id来获得当前需要修改的用户名
public partial class UpdatePassWordFrom : Form
{
private int _id;
public UpdatePassWordFrom(int id)
{
InitializeComponent();
_id = id;
li = lb.GetUser(_id);
lblName.Text=li.MName;
}
LoginInfo li;
LoginBll lb = LoginBll.CreateLogin();
private void btn_Edit_Click(object sender, EventArgs e)
{
if (txt_旧密码.Text.Trim() == "")
{
MessageBox.Show("密码不能为空");
return;
}
if (tbx_txt_Password.Text.Trim() != txt_PasswordAgain.Text.Trim())
{
MessageBox.Show("密码不一致,请确认");
return;
}
if (Md5Helper.GetMd5(txt_旧密码.Text.Trim()) == li.MPwd)
{
li.MPwd = tbx_txt_Password.Text.Trim();
if(lb.Edit(li))
{
MessageBox.Show("修改成功");
this.Close();
}
else
{
MessageBox.Show("修改失败");
}
}
else
{
MessageBox.Show("密码错误");
}
}
}
接着是增加模块
public partial class AddRoleFrom : Form
{
public AddRoleFrom()
{
InitializeComponent();
Init();
}
LoginBll lb = LoginBll.CreateLogin();
/// <summary>
/// 加载类型
/// </summary>
private void Init()
{
cbx_Type.DataSource = lb.BindList();
}
private void btn_Add_Click(object sender, EventArgs e)
{
try
{
#region 判断是否可以添加
if (lb.users.MType == LoginType.管理员 || lb.users.MType == LoginType.程序员)
{
if (txt_Name.Text.Trim() == "")
{
MessageBox.Show("用户名不能为空");
return;
}
if (txt_Password.Text.Trim() == "")
{
MessageBox.Show("密码不能为空");
return;
}
if (txt_Password.Text.Trim() != txt_PasswordAgain.Text.Trim())
{
MessageBox.Show("密码不一致,请检查");
return;
}
List<string> userAll = lb.GetName();
if (userAll.Contains(txt_Name.Text.Trim()))
{
MessageBox.Show("该用户名已经被存在,请换一个用户名");
return;
}
if (cbx_Type.Text.Trim() == "程序员")
{
if (lb.users.MType != LoginType.程序员)
{
MessageBox.Show("您无权创建程序员");
return;
}
}
#endregion
LoginInfo li = new LoginInfo()
{
MName = txt_Name.Text,
MPwd = txt_Password.Text,
MType = (LoginType)Enum.Parse(typeof(LoginType), cbx_Type.Text)
};
if (lb.Add(li))
{
MessageBox.Show("添加成功");
this.Close();
}
else
{
MessageBox.Show("添加失败,请稍后重试");
}
}
else
{
MessageBox.Show("权限不足");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
最后则是用户管理界面
打开界面通过datagridview绑定来获取数据所有的数据,并显示在界面上
该界面,可以进行数据库的增,删,改,查
public partial class UserManageFrom : Form
{
public UserManageFrom()
{
InitializeComponent();
dgvName.ReadOnly = true;
dgvName.AutoGenerateColumns = false;
ReturnNewUser();
}
LoginBll lb = LoginBll.CreateLogin();
private void btn_添加_Click(object sender, EventArgs e)
{
new AddRoleFrom().ShowDialog();
ReturnNewUser();
}
/// <summary>
/// 显示用户名
/// </summary>
/// <param name="strName">返回的用户名</param>
private void ReturnNewUser()
{
lbx_操作.Items.Clear();
lbx_技术.Items.Clear();
lbx_管理.Items.Clear();
lbx_程序.Items.Clear();
List<LoginInfo> list = lb.GetList();
dgvName.DataSource = list;
foreach (var item in list)
{
if (item.MType == LoginType.操作员)
{
lbx_操作.Items.Add(item.MName);
}
else if (item.MType == LoginType.技术员)
{
lbx_技术.Items.Add(item.MName);
}
else if (item.MType == LoginType.管理员)
{
lbx_管理.Items.Add(item.MName);
}
else
{
lbx_程序.Items.Add(item.MName);
}
}
}
private void btn_修改_Click(object sender, EventArgs e)
{
//获取选中的行
var rows = dgvName.SelectedRows;
if (rows.Count > 0)
{
UpdatePassWordFrom upw = new UpdatePassWordFrom(Convert.ToInt32(rows[0].Cells[0].Value));
upw.ShowDialog();
ReturnNewUser();
}
}
private void btn_删除_Click(object sender, EventArgs e)
{
if (lb.users.MType == LoginType.管理员 || lb.users.MType == LoginType.程序员)
{
//获取选中的行
var rows = dgvName.SelectedRows;
//集合用的是.count 数组用的是.lenth
if (rows.Count > 0)
{
DialogResult result = MessageBox.Show("确定要删除?", "提示", MessageBoxButtons.OKCancel);
if (result == DialogResult.OK)
{
int id = Convert.ToInt32(rows[0].Cells[0].Value);
if (lb.Remove(id))
{
ReturnNewUser();
}
else
{
MessageBox.Show("删除失败,请稍后重试");
}
}
}
else
{
MessageBox.Show("未选中要删除的行");
}
}
else
{
MessageBox.Show("权限不足");
}
}
}
打开的界面
这样登录模块就算写完了,里面还有一些东西需要完善,可根据项目的不同需求进行更改。