七、C#初学者练习小项目——仓库管理系统

目录

一、创建主窗体,将主窗体设置为MDI窗体

二、工具类

三、保存和读取Json文件的统一类型、所有窗体需要调用的方法类(所有表的父类)

四、自定窗体控件

1、自定义控件的父类:IDbCon

2、DbTextBox

3、DbRadio1

4、DbRichTextBox

5、DbCheckBox

6、DbComboBox

五、基础管理模块

1、创建登陆窗体(登陆成功之后才会进入主窗体)

2、注册窗体

3、所有信息窗体的父类(DgvParentForm)

4、人员信息窗体

5、角色信息窗体

六、仓库管理模块

1、库房信息窗体

2、物品信息窗体

七、出入仓库管理模块

1、入库管理窗体

2、出库管理窗体


一、创建主窗体,将主窗体设置为MDI窗体

七、C#初学者练习小项目——仓库管理系统_第1张图片

七、C#初学者练习小项目——仓库管理系统_第2张图片

主窗体完整代码:

namespace Project
{
    public partial class StartForm : Form
    {
        public StartForm()
        {
            InitializeComponent();
        }
        /// 
        /// 定时器,一秒运行一次
        /// 
        /// 
        /// 
        private void timer1_Tick(object sender, EventArgs e)
        {
            tsslTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }

        private void StartForm_Load(object sender, EventArgs e)
        {
            //在展示主窗口之前,先展示登陆窗口
            LoginForm loginForm = new LoginForm();
            DialogResult dr = loginForm.ShowDialog();
            if (dr != DialogResult.OK)
            {
                this.Close();
                return;
            }
            timer1.Enabled = true;
             //获取在登陆时保存到类中的用户登陆的名字和账号
            tsslName.Text = "欢迎您:" + UserUitl.Name;
        }


        #region 显示菜单按钮和窗体
        /// 
        /// 显示菜单按钮和窗体
        /// 
        /// 
        public void ShowMenuAndForm(string name) where T : Form,new()
        {
           //判断窗体或者菜单按钮存在不存在
           //======获取所有菜单按钮
            var items = ToolStripMain.Items;
            T form =null;
            ToolStripButton button = null;
            //找到按钮
            //======遍历所有菜单按钮,找到与窗体绑定的下拉菜单选项的按钮的Name相同的菜单按钮
            foreach (ToolStripItem item in items)
            {
                if (item.Name == name)
                {
                    button = item as ToolStripButton;
                }
            }
            //找到窗体
            Form[] sonForm = this.MdiChildren;
            //======遍历这个窗体下的所有子窗体,找到与菜单按钮相同Name的窗体
            foreach (Form f in sonForm)
            {
                if (f.Name == name)
                {
                    form = f as T;
                }
            }
            if (form != null && button != null) {
                //窗体最大化
                form.WindowState = FormWindowState.Maximized;
                //菜单按钮点击把底下覆盖的窗体置顶
                form.BringToFront();
                //遍历所有菜单按钮,把按钮的背景颜色去掉
                foreach (ToolStripButton item in items)
                {
                    item.BackColor = SystemColors.Window;
                }
                //点击时给选中的菜单按钮设置背景
                button.BackColor = Color.LightBlue;
                return;
            }
            //添加窗体
            form = new T();
            //设置人员窗体的父窗体是当前主窗体
            form.MdiParent = this;
            form.Name = name;
            form.WindowState = FormWindowState.Maximized;
            //添加菜单按钮
            button = new ToolStripButton();
            button.Text = form.Text;
            button.Name = name;
            //遍历所有菜单按钮,把按钮的背景颜色去掉
            foreach (ToolStripButton item in items)
            {
                item.BackColor = SystemColors.Window;
            }
            button.BackColor = Color.LightBlue;

            //把添加的一个菜单按钮,添加到菜单按钮的集合中去
            ToolStripMain.Items.Add(button);
            
            button.MouseDown += (s, e) =>
            {
                if(e.Button == MouseButtons.Left) //切换
                {
                    //窗体最大化
                    form.WindowState = FormWindowState.Maximized;
                    //菜单按钮点击把底下覆盖的窗体置顶
                    form.BringToFront();
                    //遍历所有菜单按钮,把按钮的背景颜色去掉
                    foreach (ToolStripButton item in items)
                    {
                        item.BackColor = SystemColors.Window;
                    }
                    //点击时给选中的菜单按钮设置背景
                    button.BackColor = Color.LightBlue;
                }
                else if (e.Button == MouseButtons.Right) //删除
                {
                    DialogResult dr = BoxUtil.OKCancel("是否关闭当前窗口");
                    if (dr == DialogResult.OK) {
                        form.Close();
                    } 
                }
            };
            form.FormClosing += (s, e) =>
            {
                    ToolStripMain.Items.Remove(button);
            };
            form.Show();
        }
        #endregion

        #region 基础管理按钮
        /// 
        /// 显示人员信息的数据表格
        /// 
        public void ShowBaseUserForm()
        {
            添加窗体
            //BaseUserForm form = new BaseUserForm();
            设置人员窗体的父窗体是当前主窗体
            //form.MdiParent = this;
            //form.WindowState = FormWindowState.Maximized;
            添加菜单按钮
            //ToolStripButton button = new ToolStripButton();
            //button.Text = form.Text;
            //toolStripMain.Items.Add(button);
            //form.Show();
            ShowMenuAndForm("ShowBaseUserForm");
        }
        /// 
        /// 显示人员信息的数据表格
        /// 
        public void ShowBaseRoleForm()
        {
            添加窗体
            //BaseRoleForm form = new BaseRoleForm();
            设置角色窗体的父窗体是当前主窗体
            //form.MdiParent = this;
            //form.WindowState = FormWindowState.Maximized;
            添加菜单按钮
            //ToolStripButton button = new ToolStripButton();
            //button.Text = form.Text;
            //toolStripMain.Items.Add(button);
            //form.Show();
            ShowMenuAndForm("ShowBaseRoleForm");
        }

        public void ShowBaseStudentForm() {
            ShowMenuAndForm("ShowBaseStudentForm()");
        }
        

        private void 人员信息ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowBaseUserForm();
        }

        private void 角色信息ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowBaseRoleForm();
        }

        private void 学生信息ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowBaseStudentForm();
        }
        #endregion

        #region 仓库管理下的菜单按钮
        /// 
        /// 显示库房信息的数据表格
        /// 
        public void ShowWareHouseInfoForm()
        {
            ShowMenuAndForm("ShowWareHouseInfoForm");
        }
        private void 库房管理ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowWareHouseInfoForm();
        }

        /// 
        /// 显示仓库商品信息
        /// 
        /// 
        /// 
        public void ShowWareHouseGoodsForm()
        {
            ShowMenuAndForm("ShowWareHouseGoodsForm");
        }
        private void 物品信息ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowWareHouseGoodsForm();
        }

        #endregion

        #region 出入库管理
        /// 
        /// 入库管理按钮
        /// 
        public void ShowInWareHouseForm()
        {
            ShowMenuAndForm("ShowInWareHouseForm");
        }
        private void 入库管理ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowInWareHouseForm();
        }
        

        /// 
        /// 出库管理按钮
        /// 
        public void ShowOutWareHouseForm()
        {
            ShowMenuAndForm("ShowOutWareHouseForm");
        }
        private void 出库管理ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowOutWareHouseForm();
        }
        #endregion
    }
}

二、工具类

1.密码MD5加密方法

namespace Project.Util
{
    internal class BaseUtil
    {
        /// 
        /// MD5加密方法
        /// 
        /// 
        public static string CreateMd5(string text) 
        {
            MD5 md5 = MD5.Create();
            byte[] md5Bytes = md5.ComputeHash(Encoding.ASCII.GetBytes(text));
            StringBuilder sb = new StringBuilder();
            foreach (byte b in md5Bytes) {
                sb.Append(b.ToString("x2"));
            }
            return sb.ToString();
        }
    }
}

2.提示框

namespace Project.Util
{
    internal class BoxUtil
    {
        public static DialogResult AsteriskOk(string text) {
            return MessageBox.Show(text, "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
        }
        public static DialogResult OKCancel(string text) {
            return MessageBox.Show(text, "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
        }
    }
}

3.文件读写类(Json数据序列化和反序列化)

namespace Project.Util
{
    /// 
    /// 读写文件数据工具类
    /// 
    internal class DbJsonUtil
    {
        /// 
        /// 数据文件表的路径字段
        /// 
        public static string TablesPath;

        static DbJsonUtil() 
        {
            //获取程序exe文件所在的路径,等同于:TablesPath = Application.StartupPath +"\\tables";
            TablesPath = System.Environment.CurrentDirectory+"\\tables";
        }

        /// 
        /// 读取数据
        /// 
        /// 
        /// 
        /// 读取数据反序列化为数据的T类型
        public static T ReadObject(string tableName) 
        {
            //文件的完整路径
            string fullName = $"{TablesPath}//{tableName}";
            if (File.Exists(fullName))
            {
                string json = File.ReadAllText(fullName,Encoding.UTF8);
                //将Json格式的文件数据反序列化为T类型
                T t = JsonConvert.DeserializeObject(json);
                return t;
            }
            else {
                //default:(例如:int类型;默认值就是0,string类型默认值是null;...)
                return default;
            }
        }

        /// 
        /// 写入数据
        /// 
        /// 
        /// 
        /// 
        /// 读取数据序列化为json类型,写入文件
        public static void  WriteObject(string tableName,object obj)
        {
            string json = JsonConvert.SerializeObject(obj);
            string fullName = $"{TablesPath}//{tableName}";
            //File.WriteAllText(fullName, json,Encoding.UTF8);
            File.WriteAllText(fullName,json);
        }
    }
}

4.存放当前登陆账号的信息类(便于在窗体其它地方展示用户信息)

namespace Project.Util
{
    /// 
    /// 存放登陆人员的账号、名字、id
    /// 
    public class UserUitl
    {
        public static string Name { get; set; }
        public static int Id { get; set; }
    }
}

三、保存和读取Json文件的统一类型、所有窗体需要调用的方法类(所有表的父类)

namespace Project.Entity
{
    public class TableParent
    {
        #region 字段、属性
        //Id的最大值
        public int MaxId { get; set; } = 0;
        //表名
        public  string TableName { get; set; }

        /// 
        /// 表中数据
        /// 
        public DataTable DataTable { get; set; }

        //当前最大值加一
        public int GetMaxIdAdd()
        {
            MaxId++;
            return MaxId;
        }
        #endregion


        //where T : TableParent 表示T这个类型必须继承TableParent才可以使用
        //new()   :表示T类型中必须有一个无参构造器
        public static T Create() where T : TableParent, new()
        {
            //创建一个T类型数据
            T t = new T();
            //读取T类型的数据
            T table = DbJsonUtil.ReadObject(t.TableName);
            if (table != null)
            {
                t.MaxId = table.MaxId;
                //t.TableName = table.TableName;
                t.DataTable = table.DataTable;
            }
            //初始化数据,调用初始化方法
            t.Init();
            return t;
        }


        //初始化数据(当文件不存在,DataTable为null时,需要创建一个)
        public virtual void Init()
        {
            //当文件不存在,DataTable为null时,需要创建一个
            if (DataTable == null)
            {
                DataTable = new DataTable();
            }
            //当列中不包含id字段的时候,添加一个id列
            AddColumn("id", typeof(int));
            //设置id为主键
            DataTable.PrimaryKey = new DataColumn[] { DataTable.Columns["id"] };
            //设置主键的默认值为0
            DataTable.Columns["id"].DefaultValue = 0;
        }
      
        /// 
        /// 添加字段和字段类型的方法
        /// 
        /// 
        /// 
        public void AddColumn(string colum, Type type)
        {
            
            if (!DataTable.Columns.Contains(colum))
            {
                DataTable.Columns.Add(colum, type);
            }
        }

        //保存
        public void Save()
        {
            DbJsonUtil.WriteObject(this.TableName, this);
        }


        /// 
        /// 判断账号是否存在
        /// 
        /// 
        /// 
        public bool CodeIsExists(string code)
        {
            DataTable dt = DataTable;
            //循环遍历每一行数据,判断有没有重复账号
            foreach (DataRow row in dt.Rows)
            {
                string oldCode = Convert.ToString(row["code"]);
                if (oldCode == code)
                {
                    BoxUtil.AsteriskOk("账号已存在");
                    return true;
                }
            }
            return false;
        }

        //编辑数据时(判断新增或者修改ide数据是否存在)
        public bool Exist(int id, string keyName, object keyValue)
        {
            DataTable dt = this.DataTable;
            //判断账号是否存在
            foreach (DataRow row in dt.Rows)
            {
                int oldId = Convert.ToInt32(row["id"]);
                string oldData = Convert.ToString(row[keyName]);
                o1dId != DbId: 把选中的那一行给排除,不做比较
                if (oldData == Convert.ToString(keyValue) && oldId != id)
                {
                    return true;
                }
            }
            return false;
        }


        //删除选中行的数据
        public int Delete(int id) {
            //找出选中的一行
            DataRow row = this.DataTable.Rows.Find(id);
            if (row == null) {
                return 0;
            }
            //删除选中ID的那一行
            this.DataTable.Rows.Remove(row);
            //删除结束之后保存一下数据
            Save();
            return 1;
        }


        /// 
        /// 编辑数据(新增或者修改数据)
        /// 
        /// 
        public int Edit(int id, Dictionary data)
        {
            DataRow row;
            if (id < 1)//新增一行
            {
                row = DataTable.Rows.Add();
                row["id"] = GetMaxIdAdd();
            }
            else //修改
            {
                row = DataTable.Rows.Find(id);
                if (row == null)
                {
                    return 0;
                }
            }
            //把Dictionary集合中的数据赋值给DataRow,并保存
            foreach (var kvs in data)
            {
                row[kvs.Key] = kvs.Value;
            }
            DbJsonUtil.WriteObject(TableName, this);
            return 1;
        }

    }
}

四、自定窗体控件

  • 自定义控件中设置属性的值例子如下,便于Dictionary键值对存储时方便,将KeyName属性的值作为键,文本内容作为值存储到字典中。以便转换成json数据存到文件中,和从文件中读取,反序列化转换成对应格式对象展示。

 七、C#初学者练习小项目——仓库管理系统_第3张图片

  • 窗体中的文本输入框控件需要自定义
  • 自定义窗体统一都继承IDbCon接口,便于遍历窗体控件,获取和设置控件内容

1、自定义控件的父类:IDbCon

  • IDbCon接口内容如下:
namespace Project.ColmunControl
{
    public interface IDbCon
    {
        //键的名字
        string DbKeyName { get; set; }

        //设置值
        void SetDbValue(object value);
        //获取值
        object GetDbValue();

        //判断是否符合条件
        string FilterDb();
    }
    /// 
    /// 数据类型
    /// 
    public enum DataType
    {
        /// 
        /// 字符串类型
        /// 
        StringType,
        /// 
        /// int类型
        /// 
        IntType
    }
}

2、DbTextBox

  • 自定义文本框窗体完整代码如下:
namespace Project.ColmunControl
{
    public partial class DbTextBox : TextBox,IDbCon
    {
        public DbTextBox()
        {
            InitializeComponent();
        }

        /// 
        /// 键的名字
        /// 
        [Description("键的名字"), Category("Db表")]
        public string DbKeyName { get; set; }

        /// 
        /// 输入框是否可以为空
        /// 
        [Description("输入框是否可以为空"), Category("Db表")]
        public bool DbIsEmpty { get; set; }

        /// 
        /// 控件绑定的字段汉字名称,比如:名字,年龄,城市
        /// 
        [Description("控件绑定的字段汉字名称,比如:名字,年龄,城市"), Category("Db表")]
        public string DbHintText { get; set; }

        /// 
        /// 当前输入框的数据类型
        /// 
        [Description("当前输入框的数据类型"), Category("Db表")]
        public DataType DbDataType { get; set; } = DataType.StringType;

        /// 
        /// 当前输入框内容的最小值
        /// ,当DataType是StringType类型则判断长度
        /// ,是IntType类型则大小
        /// 
        [Description("当前输入框内容的最小值,当DataType是StringType类型则判断长度,是IntType类型则大小"), Category("Db表")]
        public int DbMinValue { get; set; } = 0;

        /// 
        /// 当前输入框内容的最大值
        /// ,当DataType是StringType类型则判断长度
        /// ,是IntType类型则大小
        /// 
        [Description("当前输入框内容的最大值,当DataType是StringType类型则判断长度,是IntType类型则大小"), Category("Db表")]
        public int DbMaxValue { get; set; } = 10;

        /// 
        /// 当前输入框不能包含的特殊字符
        /// 
        [Description("当前输入框不能包含的特殊字符"), Category("Db表")]
        public string DbNoChars { get; set; }


        public object GetDbValue()
        {
            return this.Text;
        }

        public void SetDbValue(object value)
        {
            this.Text = Convert.ToString(value);
        }

        /// 
        /// 判断是否符合条件,当返回为空的时候就说明符合条件
        /// 
        /// 
        public string FilterDb()
        {
            //判断是否可以为空
            if (DbIsEmpty)
            {
                if (string.IsNullOrEmpty(Text)) {
                    return string.Empty;
                }
            }
            else {
                if (string.IsNullOrEmpty(Text))
                {
                    return DbHintText + "不能为空";
                }
            }
            

            if (this.DbDataType == DataType.StringType) //长度判断
            {
                if (this.Text.Length < DbMinValue)
                {
                    return $"{DbHintText}长度不能小于{DbMinValue}";
                }
                if (this.Text.Length > DbMaxValue)
                {
                    return $"{DbHintText}长度不能大于{DbMaxValue}";
                }
            }
            else if (this.DbDataType == DataType.IntType) //最小值,最大值
            {
                if (int.TryParse(Text, out int number))
                {
                    if (number < DbMinValue)
                    {
                        return $"{DbHintText}不能小于{DbMinValue}";
                    }
                    if (number > DbMaxValue)
                    {
                        return $"{DbHintText}不能大于{DbMaxValue}";
                    }
                }
                else
                {
                    return $"{DbHintText}请输入一个数字";
                }
            }

            //特殊字符判断
            if (!string.IsNullOrEmpty(DbNoChars))
            {
                char[] chars = DbNoChars.ToArray();
                foreach (char c in chars)
                {
                    if (Text.Contains(c))
                    {
                        return $"{DbHintText}不能包含特殊字符:{c}";
                    }
                }
            }
            return string.Empty;
        }
    }
}

3、DbRadio1

  • 自定义单选框控件代码如下:
namespace Project.ColmunControl
{
    public partial class DbRadio1 : RadioButton,IDbCon
    {
        public DbRadio1()
        {
            InitializeComponent();
        }


        [Description("键的名字"), Category("Db表")]
        public string DbKeyName { get; set; }

        public string FilterDb()
        {
            
            return string.Empty;
        }

        public object GetDbValue()
        {
            return this.Checked;
        }

        public void SetDbValue(object value)
        {
            if (value == null || string.IsNullOrEmpty(value.ToString()))
            {
                return;
            }
            this.Checked = Convert.ToBoolean(value);
        }
    }
}

4、DbRichTextBox

  • 自定义RichTextBox代码如下:

namespace Project.ColmunControl
{
    public partial class DbRichTextBox : RichTextBox,IDbCon
    {
        public DbRichTextBox()
        {
            InitializeComponent();
        }
        /// 
        /// 键的名字
        /// 
        [Description("键的名字"), Category("Db表")]
        public string DbKeyName { get; set; }

        /// 
        /// 输入框是否可以为空
        /// 
        [Description("输入框是否可以为空"), Category("Db表")]
        public bool DbIsEmpty { get; set; }

        /// 
        /// 控件绑定的字段汉字名称,比如:名字,年龄,城市
        /// 
        [Description("控件绑定的字段汉字名称,比如:名字,年龄,城市"), Category("Db表")]
        public string DbHintText { get; set; }

        /// 
        /// 当前输入框的数据类型
        /// 
        [Description("当前输入框的数据类型"), Category("Db表")]
        public DataType DbDataType { get; set; } = DataType.StringType;

        /// 
        /// 当前输入框内容的最小值
        /// ,当DataType是StringType类型则判断长度
        /// ,是IntType类型则大小
        /// 
        [Description("当前输入框内容的最小值,当DataType是StringType类型则判断长度,是IntType类型则大小"), Category("Db表")]
        public int DbMinValue { get; set; } = 0;

        /// 
        /// 当前输入框内容的最大值
        /// ,当DataType是StringType类型则判断长度
        /// ,是IntType类型则大小
        /// 
        [Description("当前输入框内容的最大值,当DataType是StringType类型则判断长度,是IntType类型则大小"), Category("Db表")]
        public int DbMaxValue { get; set; } = 100;


        public object GetDbValue()
        {
            return this.Text;
        }

        public void SetDbValue(object value)
        {
            this.Text = Convert.ToString(value);
        }


        public string FilterDb()
        {
            return string.Empty;
        }

    }
}

5、DbCheckBox

  • 自定义单选框CheckBox代码如下:

namespace Project.ColmunControl
{
    public partial class DbCheckBox : CheckBox,IDbCon
    {
        public DbCheckBox()
        {
            InitializeComponent();
        }
        [Description("键的名字"), Category("Db表")]
        public string DbKeyName { get; set; }

        public string FilterDb()
        {

            return string.Empty;
        }

        public object GetDbValue()
        {
            return this.Checked;
        }

        public void SetDbValue(object value)
        {
            if (value == null || string.IsNullOrEmpty(value.ToString()))
            {
                return;
            }
            this.Checked = Convert.ToBoolean(value);
        }
    }

}

6、DbComboBox

  • 自定义下拉框ComboBox代码如下:

namespace Project.ColmunControl
{
    public partial class DbComboBox : ComboBox,IDbCon
    {
        public DbComboBox()
        {
            InitializeComponent();
        }

        /// 
        /// 键的名字
        /// 
        [Description("键的名字"), Category("Db表")]
        public string DbKeyName { get; set; }


        public object GetDbValue()
        {
            return this.SelectedIndex;
        }

        public void SetDbValue(object value)
        {
            if (value == null && string.IsNullOrEmpty(value.ToString())) {
                return;
            }
            if (int.TryParse(value.ToString(),out int num)) {
                this.SelectedIndex = num;
            }
           
        }



        public string FilterDb()
        {
            return string.Empty;
        }
    }
}

五、基础管理模块

1、创建登陆窗体(登陆成功之后才会进入主窗体)

七、C#初学者练习小项目——仓库管理系统_第4张图片

登陆窗体完整代码如下:

namespace Project.Login
{
    public partial class LoginForm : Form
    {
        public LoginForm()
        {
            InitializeComponent();
        }

        private void LoginForm_Load(object sender, EventArgs e)
        {
            //测试时省去输入账号和密码的环节
            tbCode.Text = "admin";
            tbPwd.Text = "123456";
            //Test();
        }

        private void buttonLogin_Click(object sender, EventArgs e)
        {
            string code = tbCode.Text;
            string pwd = tbPwd.Text;
            if (string.IsNullOrEmpty(code)||string.IsNullOrEmpty(pwd)) 
            {
                BoxUtil.AsteriskOk("账号或者密码不能为空");
                return;
            }
            if (code.Length < 3 || code.Length > 16) 
            {
                BoxUtil.AsteriskOk("账号长度不能小于3、大于16");
                return;
            }
            if (pwd.Length < 3 || code.Length >16) {
                BoxUtil.AsteriskOk("密码长度不能小于3、大于16");
            }
            //密码调用工具类中的MD5加密方法加密
            string md5Pwd = BaseUtil.CreateMd5(pwd);

            //读取数据

            TableParent fileData = DbJsonUtil.ReadObject("base_user");
            DataTable dt = fileData.DataTable;
            foreach (DataRow row in dt.Rows)
            {
                string strCode = row["code"].ToString();
                string strPwd = row["pwd"].ToString();
                if (strPwd == md5Pwd && strCode == code)
                {
                    //获取登陆的账号和id,以便在主页面下面ToolStripSLable控件获取
                    string name = Convert.ToString(row["Name"]);
                    int id = Convert.ToInt32(row["id"]);
                    UserUitl.Id = id;
                    UserUitl.Name = name;

                    //BoxUtil.AsteriskOk("登陆成功");
                    this.DialogResult = DialogResult.OK;
                    return;
                }
            }
            BoxUtil.AsteriskOk("账号或密码不正确");
            return;


        } 

        private void buttonClose_Click(object sender, EventArgs e)
        {
            this.DialogResult=DialogResult.Cancel;
        }


        
        //注册按钮
        private void label4_Click(object sender, EventArgs e)
        {
            RegisterForm registerForm = new RegisterForm();
            registerForm.ShowDialog();
        }
    }
}

2、注册窗体

七、C#初学者练习小项目——仓库管理系统_第5张图片

注册窗体完整代码如下:

namespace Project.Login
{
    public partial class RegisterForm : Form
    {
        public RegisterForm()
        {
            InitializeComponent();
        }

        //注册
        private void button2_Click(object sender, EventArgs e)
        {
            string code = DbTbCode1.Text;
            string pwd = DbTbPwd1.Text;
            string ageOld = DbTbAge1.Text;

            //调用自定义控件的过滤器方法,判断控件的内容是否符合要求
            foreach (Control control in Controls)
            {
                if (control is IDbCon con)
                {
                    string str = con.FilterDb();
                    if (!string.IsNullOrEmpty(str))
                    {
                        BoxUtil.AsteriskOk(str);
                        return;
                    }
                }
            }
            //密码调用工具类中的MD5加密方法加密
            string md5Pwd = BaseUtil.CreateMd5(pwd);
            //读取表数据
            BaseUser user = TableParent.Create();
            //调用判断账号是否存在的方法
            bool v = user.CodeIsExists(code);
            if (!v)
            {
                int age = Convert.ToInt32(ageOld);
                //保存
                Dictionary data = new Dictionary();
                foreach (Control con in Controls)
                {
                    if (con is IDbCon db)
                    {
                        data[db.DbKeyName] = db.GetDbValue();
                    }
                }
                data["pwd"] = md5Pwd;
                //调用注册账号的方法
                //user.Register(code, md5Pwd,name,age,phone,email,city,isAdmin);
                int v1 = user.Edit(0, data);
                if (v1 == 1)
                {
                    BoxUtil.AsteriskOk("注册成功");
                    this.DialogResult = DialogResult.OK;
                }
            }

        }
        //取消
        private void button1_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.No;
        }

        private void RegisterForm_Load(object sender, EventArgs e)
        {
            if (this.Text == "注册账号")
            {
                button2.Text = "注册";
            }
            if(this.Text == "新增账号")
            {
                button2.Text = "添加";
            }
            if (this.Text == "修改数据") 
            {
                button2.Text = "确认修改";             
            }

        }
    }
}

3、所有信息窗体的父类(DgvParentForm)

七、C#初学者练习小项目——仓库管理系统_第6张图片

七、C#初学者练习小项目——仓库管理系统_第7张图片

父窗体中定义数据表格行的样式代码如下:

namespace Project.Login
{
    public partial class DgvParentForm : Form
    {
        public DgvParentForm()
        {
            InitializeComponent();
            //行头显示
            dgv.ColumnHeadersVisible = true;
            //列头隐藏
            dgv.RowHeadersVisible = false;
            //一次选中一行
            dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            //设置奇数行的样式
            var style = dgv.AlternatingRowsDefaultCellStyle;//获取奇数行
            style.BackColor = Color.White;
            style.ForeColor = Color.Black;
            //选中行的背景颜色和字体
            style.SelectionBackColor = Color.LightBlue;
            style.SelectionForeColor = Color.Black;
            //设置单元格样式
            var ce1lStyle = dgv.DefaultCellStyle;
            ce1lStyle.BackColor = Color.White;
            ce1lStyle.ForeColor = Color.Black;
            ce1lStyle.SelectionBackColor = Color.LightBlue;//进入时默认所在的单元格的格的背景颜色
            ce1lStyle.SelectionForeColor = Color.Black;
            
            //单元格只读
            dgv.ReadOnly = true;
            //禁止调整行的大小
            dgv.AllowUserToResizeRows = false;

            //去掉最后一行空白行
            dgv.AllowUserToAddRows = false;
        }
    }
}

4、人员信息窗体

七、C#初学者练习小项目——仓库管理系统_第8张图片

 人员信息的实体类代码如下:

namespace Project.Entity
{
    public class BaseUser : TableParent
    {
        public BaseUser()
        {
            TableName = "base_user";
        }
        public override void Init()
        {
            base.Init();
            AddColumn("code", typeof(string));
            AddColumn("pwd", typeof(string));
            AddColumn("name", typeof(string));
            AddColumn("age", typeof(int));
            AddColumn("phone", typeof(string));
            AddColumn("email", typeof(string));
            AddColumn("jobId", typeof(string));
            AddColumn("city", typeof(string));
            AddColumn("createTime", typeof(DateTime));
            AddColumn("isAdmin", typeof(bool));
            AddColumn("roleId", typeof(int));

        }
        /// 
        /// 编辑数据(新增或者修改数据),TableParent父类中也有这个类,但是用户新增一条时,需要后台加入创建时间和工号列,这里就再写一遍。其它实体类中就不需要了
        /// 
        /// 
        public int Edit(int id, Dictionary data)
        {
            DataRow row;
            if (id < 1)//新增一行
            {
                row = DataTable.Rows.Add();
                row["id"] = GetMaxIdAdd();
                row["jobId"] = row["id"];
                row["createTime"] = DateTime.Now.ToString("yyyy-MM-dd");
            }
            else //修改
            {
                row = DataTable.Rows.Find(id);
                if (row == null)
                {
                    return 0;
                }
            }
            //把Dictionary集合中的数据赋值给DataRow,并保存
            foreach (var kvs in data)
            {
                row[kvs.Key] = kvs.Value;
            }
            DbJsonUtil.WriteObject(TableName, this);
            return 1;
        }
   }
}

人员信息窗体(继承窗体父类:DgvParentForm) 

七、C#初学者练习小项目——仓库管理系统_第9张图片

 人员信息窗体的增删改查代码如下:

namespace Project.Login
{
    public partial class BaseUserForm : DgvParentForm
    {
        public BaseUserForm()
        {
            InitializeComponent();
        }

        private void BaseUserForm_Load(object sender, EventArgs e)
        {
            RefreshDgv();
        }

        //刷新查询数据
        protected void RefreshDgv() {
            //查询人员数据
            BaseUser user = TableParent.Create();
            //展示人员信息数据
            dgv.DataSource = user.DataTable;
            //隐藏id、pwd列
            dgv.Columns["id"].Visible = true;
            dgv.Columns["pwd"].Visible = true;
            //修改一下列的显示名称
            dgv.Columns["name"].HeaderText = "名称";
            dgv.Columns["age"].HeaderText = "年龄";
            dgv.Columns["code"].HeaderText = "账号";
            dgv.Columns["phone"].HeaderText = "电话";
            dgv.Columns["email"].HeaderText = "邮箱";
            dgv.Columns["jobId"].HeaderText = "工号";
            dgv.Columns["city"].HeaderText = "城市";
            dgv.Columns["createTime"].HeaderText = "创建时间";
            dgv.Columns["isAdmin"].HeaderText = "是否是管理员";

        }

        //新增一条数据
        private void btnInsert_Click(object sender, EventArgs e)
        {
            //RegisterForm rf = new RegisterForm();
            //rf.Text = "新增账号";
            //rf.ShowDialog();
            BaseUserAddForm baseUserAddForm = new BaseUserAddForm();
            DialogResult dr = baseUserAddForm.ShowDialog();
            if (dr == DialogResult.OK) {
                RefreshDgv();
            }
        }

        //刷新数据表
        private void btnRefresh_Click(object sender, EventArgs e)
        {
            RefreshDgv();
        }

        //修改数据
        private void btnUpdate_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0) {
                BoxUtil.AsteriskOk("请选中一行数据");
                return;
            }
            var row = rows[0];
            //获取选中行的id
            int id = Convert.ToInt32(row.Cells["id"].Value);
           
            BaseUserAddForm form = new BaseUserAddForm();
            //获取到要修改行的id
            form.DbId = id;
            //把选中的行传给修改页面的属性
            form.dbRow = row;
            //弹出新增人员窗口,展示和修改数据
            DialogResult dr = form.ShowDialog();
            if (dr == DialogResult.OK)
            {
                RefreshDgv();
            }
        

        }

        //删除数据
        private void btnDelete_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0)
            {
                BoxUtil.AsteriskOk("请选中一行数据");
                return;
            }
            DialogResult dr = BoxUtil.OKCancel("确定删除吗?");
            if (dr == DialogResult.OK)
            {
                var row = rows[0];
                int id = Convert.ToInt32(row.Cells["id"].Value);
                BaseUser baseuser = TableParent.Create();
                int num = baseuser.Delete(id);
                if (num == 0)
                {
                    BoxUtil.AsteriskOk("删除失败," +
                        "可能已经被删除了,请刷新数据");
                    return;
                }
                RefreshDgv();
            }
        }
    }
}

人员信息添加和修改窗体

七、C#初学者练习小项目——仓库管理系统_第10张图片

 人员信息添加和修改窗体代如下:

namespace Project.BaseManage
{
    public partial class BaseUserAddForm : Form
    {
        public BaseUserAddForm()
        {
            InitializeComponent();
        }

        //修改时,要修改那条数据的ID
        public int DbId { get; set; }
        public DataGridViewRow dbRow { get; set; }



        //编剧数据(添加、修改)
        private void button2_Click(object sender, EventArgs e)
        {
            foreach (Control con in Controls) {
                if (con is IDbCon idbcon) {
                    string str = idbcon.FilterDb();
                    //BoxUtil.AsteriskOk(str);
                }
            }
            //1.获取人员信息
            BaseUser user = TableParent.Create();
            DataTable dt = user.DataTable;
            string code = DbTbCode1.Text;
            string pwd1 = DbTbPwd1.Text;
            //2判断账号是否重复
            bool exist = user.Exist(DbId,"code",code);
            if (exist) {
                BoxUtil.AsteriskOk("账号不能重复");
                return;
            }
            //3.保存
            Dictionary data = new Dictionary();
            foreach (Control con in Controls) {
                if (con is IDbCon idbcon) {
                    data[idbcon.DbKeyName] = idbcon.GetDbValue();
                }
            }
            string pwdMD5 = BaseUtil.CreateMd5(pwd1);
            data["pwd"] = pwdMD5;
            data["roleId"] = dbCBRole.SelectedValue;
            user.Edit(DbId,data);
            this.DialogResult= DialogResult.OK;
        }

        //取消
        private void button1_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }

        private void BaseUserAddForm_Load(object sender, EventArgs e)
        {
            if (DbId == 0)//新增人员
            {
                this.Text = "新增人员";
                this.button2.Text = "新增";
                label1.Text = "新增人员";
            }
            else //修改
            {
                this.Text = "修改人员";
                this.button2.Text = "修改";
                label1.Text = "修改信息";
            }


            //展示要修改的数据
            BaseRole role = TableParent.Create();
            DataTable dt = role.DataTable;
            //设置下拉框的数据源
            dbCBRole.DataSource = dt;
            //下拉框显示的文本
            dbCBRole.DisplayMember = "code";
            //下拉框隐藏的文本
            dbCBRole.ValueMember = "id";
            if (dbRow != null) {
                foreach (Control con in Controls) {
                    if (con is IDbCon dbcon) {
                        dbcon.SetDbValue(dbRow.Cells[dbcon.DbKeyName].Value);
                    }
                }
                //object value = dbRow.Cells["roleId"].Value;
                //设置下拉框选中的ID
                dbCBRole.SelectedValue = dbRow.Cells["roleId"].Value;
            }
        }
    }
}

5、角色信息窗体

七、C#初学者练习小项目——仓库管理系统_第11张图片

角色信息实体类

namespace Project.Util
{
    public class BaseRole : TableParent
    {
        public BaseRole()
        {
            TableName = "base_role";
        }
        public override void Init()
        {
            base.Init();
            AddColumn("name", typeof(string));
            AddColumn("code", typeof(string));
            AddColumn("details", typeof(string));
            AddColumn("createTime", typeof(DateTime));
        }


        /// 
        /// 编辑数据(新增或者修改数据),TableParent父类中也有这个类,但是新增一条角色时,需要后台加入创建时间,这里就再写一遍。其它实体类中就不需要了
        /// 
        /// 
        public int Edit(int id, Dictionary data)
        {
            DataRow row;
            if (id < 1)//新增一行
            {
                row = DataTable.Rows.Add();
                row["id"] = GetMaxIdAdd();
                row["createTime"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm");
            }
            else //修改
            {
                row = DataTable.Rows.Find(id);
                if (row == null)
                {
                    return 0;
                }
            }
            //把Dictionary集合中的数据赋值给DataRow,并保存
            foreach (var kvs in data)
            {
                row[kvs.Key] = kvs.Value;
            }
            DbJsonUtil.WriteObject(TableName, this);
            return 1;
        }
    }
}

 角色信息展示窗体(继承窗体父类:DgvParentForm)

七、C#初学者练习小项目——仓库管理系统_第12张图片

 角色信息窗体的增删改查代码如下:

namespace Project.BaseManage
{
    public partial class BaseRoleForm : DgvParentForm
    {
        public BaseRoleForm()
        {
            InitializeComponent();
        }

        //刷新查询数据
        protected void RefreshDgv()
        {
            //查询人员数据
            BaseRole role = TableParent.Create();
            //展示人员信息数据
            dgv.DataSource = role.DataTable;
            //隐藏id、pwd列
            dgv.Columns["id"].Visible = true;
            //修改一下列的显示名称
            dgv.Columns["name"].HeaderText = "姓名";
            dgv.Columns["details"].HeaderText = "详情";
            dgv.Columns["code"].HeaderText = "身份";
            dgv.Columns["createTime"].HeaderText = "创建时间";
            dgv.Columns["details"].Width = 400;
            dgv.Columns["createTime"].Width = 200;
            
        }

        //新增一条数据
        private void btnInsert_Click(object sender, EventArgs e)
        {
            BaseRoleEditForm buef = new BaseRoleEditForm();
            DialogResult dr = buef.ShowDialog();
            if (dr == DialogResult.OK)
            {
                RefreshDgv();
            }
        }

        //修改
        private void btnUpdate_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0)
            {
                BoxUtil.AsteriskOk("请选中一行数据");
                return;
            }
            var row = rows[0];
            //获取选中行的id
            int id = Convert.ToInt32(row.Cells["id"].Value);
            BaseRoleEditForm form = new BaseRoleEditForm();
            //获取到要修改行的id
            form.DbId = id;
            //把选中的行传给修改页面的属性
            form.dbRow = row;
            //弹出新增人员窗口,展示和修改数据
            DialogResult dr = form.ShowDialog();
            if (dr == DialogResult.OK)
            {
                RefreshDgv();
            }

        }

        //删除
        private void btnDelete_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0)
            {
                BoxUtil.AsteriskOk("请选中一行数据");
                return;
            }
            DialogResult dr = BoxUtil.OKCancel("确定删除吗?");
            if (dr == DialogResult.OK)
            {
                var row = rows[0];
                int id = Convert.ToInt32(row.Cells["id"].Value);
                BaseRole baseuser = TableParent.Create();
                int num = baseuser.Delete(id);
                if (num == 0)
                {
                    BoxUtil.AsteriskOk("删除失败,可能已经被删除了,请刷新数据");
                    return;
                }
                RefreshDgv();
            }
        }

        //刷新
        private void btnRefresh_Click(object sender, EventArgs e)
        {
            RefreshDgv();
        }

        private void BaseRoleForm_Load(object sender, EventArgs e)
        {
            RefreshDgv();
        }
    }
}

角色信息添加和修改窗体如下: 

七、C#初学者练习小项目——仓库管理系统_第13张图片

角色信息添加和修改窗体代如下:

namespace Project.BaseManage
{
    public partial class BaseRoleEditForm : Form
    {
        public BaseRoleEditForm()
        {
            InitializeComponent();
        }

        public int DbId { get; set; }
        public DataGridViewRow dbRow { get; set; }
        //添加按钮
        private void button1_Click(object sender, EventArgs e)
        {
            foreach (Control con in Controls)
            {
                if (con is IDbCon idbcon)
                {
                    string str = idbcon.FilterDb();
                    //BoxUtil.AsteriskOk(str);
                }
            }
            //1.获取人员信息
            BaseRole role = TableParent.Create();
            DataTable dt = role.DataTable;
            string code = dbCode.Text;
            string name = dbName.Text;
            //2判断角色账号是否重复
            bool exist = role.Exist(DbId, "code", code);
            if (exist)
            {
                BoxUtil.AsteriskOk("账号不能重复");
                return;
            }
            //3.保存
            Dictionary data = new Dictionary();
            foreach (Control con in Controls)
            {
                if (con is IDbCon idbcon)
                {
                    data[idbcon.DbKeyName] = idbcon.GetDbValue();
                }
            }
            role.Edit(DbId, data);
            this.DialogResult = DialogResult.OK;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            this.DialogResult= DialogResult.Cancel;
        }

        private void BaseUserEditForm_Load(object sender, EventArgs e)
        {
            
            if (DbId == 0)//新增人员
            {
                this.Text = "新增角色";
                this.button1.Text = "新增";
                this.label5.Text = "新增角色";
            }
            else //修改
            {
                this.Text = "修改角色";
                this.button1.Text = "修改";
                this.label5.Text = "修改角色";
            }
            //展示要修改的数据
            if (dbRow != null)
            {
                foreach (Control con in Controls)
                {
                    if (con is IDbCon dbcon)
                    {
                        dbcon.SetDbValue(dbRow.Cells[dbcon.DbKeyName].Value);
                    }
                }
            }
        }
    }
}

六、仓库管理模块

1、库房信息窗体

七、C#初学者练习小项目——仓库管理系统_第14张图片

库房信息实体类 

namespace Project.Entity
{
    /// 
    /// 库房信息表
    /// 
    public class WareHouseInfo : TableParent
    {
        public WareHouseInfo()
        {
            TableName = "warehouse_info";
        }
        public override void Init()
        {
            base.Init();
            AddColumn("name",typeof(string));//仓库名称
            AddColumn("location",typeof(string));//仓库地址
        }
    }
}

 库房信息展示窗体(继承窗体父类:DgvParentForm)

七、C#初学者练习小项目——仓库管理系统_第15张图片

 库房信息窗体的增删改查代码如下:

namespace Project.WareHouseManage
{
    //仓库管理菜单窗口
    public partial class WareHouseInfoForm : DgvParentForm
    {
        public WareHouseInfoForm()
        {
            InitializeComponent();
        }

        private void WareHouseInfoForm_Load(object sender, EventArgs e)
        {
            RefreshDgv();
        }
        private void RefreshDgv()
        {
            WareHouseInfo whi = TableParent.Create();
            DataTable dt = whi.DataTable;
            dgv.DataSource = dt;
            //仓库id列显示可见
            dgv.Columns["id"].Visible = true;
            dgv.Columns["name"].HeaderText = "仓库名称";
            dgv.Columns["location"].HeaderText = "仓库地址";
        }

        //新增仓库
        private void btnInsert_Click(object sender, EventArgs e)
        {
            WareHouseInfoEditForm whiE = new WareHouseInfoEditForm();
            DialogResult dr = whiE.ShowDialog();
            if (dr == DialogResult.OK) {
                RefreshDgv();
            }

        }
        //修改仓库
        private void btnUpdate_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0)
            {
                BoxUtil.AsteriskOk("请选中一行数据");
                return;
            }
            var row = rows[0];
            //获取选中行的id
            int id = Convert.ToInt32(row.Cells["id"].Value);
            WareHouseInfoEditForm form = new WareHouseInfoEditForm();
            //获取到要修改行的id
            form.DbId = id;
            //把选中的行传给修改页面的属性
            form.dbRow = row;
            //弹出新新增仓库窗口,展示和修改数据
            DialogResult dr = form.ShowDialog();
            if (dr == DialogResult.OK)
            {
                RefreshDgv();
            }
        }

        //删除仓库
        private void btnDelete_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0)
            {
                BoxUtil.AsteriskOk("请选中一行数据");
                return;
            }
            DialogResult dr = BoxUtil.OKCancel("确定删除吗?");
            if (dr == DialogResult.OK)
            {
                var row = rows[0];
                int id = Convert.ToInt32(row.Cells["id"].Value);
                WareHouseInfo whi = TableParent.Create();
                int num = whi.Delete(id);
                if (num == 0)
                {
                    BoxUtil.AsteriskOk("删除失败,可能已经被删除了,请刷新数据");
                    return;
                }
                RefreshDgv();
            }
        }
        //刷新仓库
        private void btnRefresh_Click(object sender, EventArgs e)
        {
            RefreshDgv();
        }
    }
}

库房信息添加和修改窗体如下: 

七、C#初学者练习小项目——仓库管理系统_第16张图片

 库房信息添加和修改窗体代如下:

namespace Project.WareHouseManage
{
    public partial class WareHouseInfoEditForm : Form
    {
        public WareHouseInfoEditForm()
        {
            InitializeComponent();
        }
        public int DbId;
        public DataGridViewRow dbRow;

        private void WareHouseInfoEditForm_Load(object sender, EventArgs e)
        {

            if (DbId == 0)//新增仓库
            {
                this.Text = "新增仓库";
                this.button1.Text = "添加";
                label5.Text = "新增仓库";
            }
            else //修改
            {
                this.Text = "修改仓库";
                this.button1.Text = "修改";
                label5.Text = "修改仓库";
            }
            //展示要修改的数据
            if (dbRow != null)
            {
                foreach (Control con in Controls)
                {
                    if (con is IDbCon dbcon)
                    {
                        dbcon.SetDbValue(dbRow.Cells[dbcon.DbKeyName].Value);
                    }
                }
                //this.Text = "修改仓库";
                //this.label5.Text = "修改仓库";
            }
        }

        //取消
        private void button2_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }

        //保存
        private void button1_Click(object sender, EventArgs e)
        {
            foreach(Control con in Controls)
            {
                if (con is IDbCon idbcon) {
                    string str = idbcon.FilterDb(); 
                    if (!string.IsNullOrEmpty(str))
                    {
                        BoxUtil.AsteriskOk(str);
                        return;
                    }
                }
            }

            string name = dbTBName.Text;
            WareHouseInfo whi = TableParent.Create();
            DataTable dt = whi.DataTable;
            //判断仓库名称是否存在
            bool exist = whi.Exist(DbId,"name",name);
            if (exist) {
                BoxUtil.AsteriskOk("仓库名称不能重复");
                return;
            }
            //保存
            Dictionary data = new Dictionary();
            foreach (Control con in Controls)
            {
                if (con is IDbCon idbcon)
                {
                    data[idbcon.DbKeyName] = idbcon.GetDbValue();
                }
            }
            whi.Edit(DbId, data);
            this.DialogResult = DialogResult.OK;
        }
    }
}

2、物品信息窗体

七、C#初学者练习小项目——仓库管理系统_第17张图片

 物品信息实体类 

namespace Project.Entity
{
    //仓库物品信息类
    internal class WareHouseGoods : TableParent
    {
        public WareHouseGoods()
        {
            TableName = "warehouse_goods";
        }

        public override void Init()
        {
            base.Init();
            AddColumn("code",typeof(string));//物品编号
            AddColumn("name",typeof(string));//物品名字
            AddColumn("unit",typeof(string));//物品计量单位
            AddColumn("allCount",typeof(int));//总采购数量
            AddColumn("residueCount",typeof(int));//剩余商品数量
            AddColumn("remark",typeof(string));//备注
            DataTable.Columns["allCount"].DefaultValue = 0;
            DataTable.Columns["residueCount"].DefaultValue = 0;
        }
    }
}

物品信息展示窗体(继承窗体父类:DgvParentForm)

七、C#初学者练习小项目——仓库管理系统_第18张图片

 物品信息窗体的增删改查代码如下:

namespace Project.WareHouseManage
{
    public partial class WareHouseGoodsForm : DgvParentForm
    {
        public WareHouseGoodsForm()
        {
            InitializeComponent();
        }

        public void RefreshDgv() {
            WareHouseGoods whg = TableParent.Create();
            DataTable dt = whg.DataTable;
            dgv.DataSource = dt;
            //id列隐藏
            dgv.Columns["id"].Visible = false;
            dgv.Columns["code"].HeaderText = "编号";
            dgv.Columns["name"].HeaderText = "商品名称";
            dgv.Columns["unit"].HeaderText = "单位";
            dgv.Columns["allCount"].HeaderText = "采购数量";
            dgv.Columns["residueCount"].HeaderText = "剩余数量";
            dgv.Columns["remark"].HeaderText = "备注";
        }

        private void WareHouseGoodsForm_Load(object sender, EventArgs e)
        {
            RefreshDgv();
        }

        private void btnInsert_Click(object sender, EventArgs e)
        {
            WareHouseGoodsEditForm form = new WareHouseGoodsEditForm();
            DialogResult dr = form.ShowDialog();
            if (dr == DialogResult.OK)
            {
                RefreshDgv();
            }
        }

        //修改
        private void btnUpdate_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0) {
                BoxUtil.AsteriskOk("请选中要修改的一行");
                return;
            }
            var row = rows[0];
            int id = Convert.ToInt32(row.Cells["id"].Value);
            WareHouseGoodsEditForm whef = new WareHouseGoodsEditForm();
            whef.DbId = id;
            whef.dbRow = row;
            DialogResult dr = whef.ShowDialog();
            if (dr == DialogResult.OK) {
                RefreshDgv();
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0)
            {
                BoxUtil.AsteriskOk("请选中要删除的一行");
                return;
            }
            DialogResult dr = BoxUtil.OKCancel("你确定要删除吗?");
            if (dr == DialogResult.OK) {
                var row = rows[0];
                int id = Convert.ToInt32(row.Cells["id"].Value);
                WareHouseGoods whg = TableParent.Create();
                int result = whg.Delete(id);
                if (result == 1) {
                    RefreshDgv();
                    return;
                }
                BoxUtil.AsteriskOk("删除失败,数据可能已经被删除");
            }
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            RefreshDgv();
        }
    }
}

物品信息添加和修改窗体如下: 

七、C#初学者练习小项目——仓库管理系统_第19张图片

 物品信息添加和修改窗体代如下:

namespace Project.WareHouseManage
{
    public partial class WareHouseGoodsEditForm : Form
    {
        public WareHouseGoodsEditForm()
        {
            InitializeComponent();
        }

        public int DbId { get; set; }

        public DataGridViewRow dbRow { get; set; }


        private void WareHouseGoodsEditForm_Load(object sender, EventArgs e)
        {
            if (DbId == 0)//新增商品
            {
                this.Text = "新增商品";
                this.button1.Text = "添加";
                this.label5.Text = "新增商品";
            }
            else //修改
            {
                this.Text = "修改商品";
                this.button1.Text = "修改";
                this.label5.Text = "修改商品";
            }
            //展示要修改的数据
            if (dbRow != null)
            {
                foreach (Control con in Controls)
                {
                    if (con is IDbCon dbcon)
                    {
                        dbcon.SetDbValue(dbRow.Cells[dbcon.DbKeyName].Value);
                    }
                }
                //this.Text = "修改仓库";
                //this.label5.Text = "修改仓库";
            }
        }

        //取消
        private void button2_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            foreach (Control con in Controls) {
                if (con is IDbCon idbcon) 
                {
                    string str = idbcon.FilterDb();
                    if (!string.IsNullOrEmpty(str))
                    {
                        BoxUtil.AsteriskOk(str);
                        return;
                    }
                }
            }

            //判断商品名称和编号是否存在
            string code = dbTBCode.Text;
            string name = dbTBName.Text;
            WareHouseGoods whg = TableParent.Create();
            DataTable dt = whg.DataTable;
            bool exitCode = whg.Exist(DbId,"code",code);
            if (exitCode) {
                BoxUtil.AsteriskOk("商品编号不能重复");
                return;
            }
            bool exitName = whg.Exist(DbId,"name",name);
            if (exitName) {
                BoxUtil.AsteriskOk("商品名称不能重复");
                return;
            }
            //保存
            Dictionary data = new Dictionary();
            foreach (Control con in Controls) {
                if (con is IDbCon idbcon) {
                    data[idbcon.DbKeyName] = idbcon.GetDbValue();
                }
            }
            whg.Edit(DbId,data);
            this.DialogResult = DialogResult.OK;
        }
    }
}

七、出入仓库管理模块

注意:物品出入库数据的添加修改时,还需要修改对应商品的采购和总数等

1、入库管理窗体

七、C#初学者练习小项目——仓库管理系统_第20张图片

 入库管理实体类 

namespace Project.Entity
{
    //入库信息
    public class InWareHouse : TableParent
    {
        public InWareHouse()
        {
            TableName = "in_warehouse";
        }


        public override void Init()
        {
            base.Init();
            AddColumn("whGoodsId",typeof(int));
            AddColumn("batch",typeof(string));//批次
            AddColumn("money",typeof(int));//单价
            AddColumn("number",typeof(int));//数量
            AddColumn("remaiNumber",typeof(int));//剩余数量
            AddColumn("allMoney",typeof(int));//总价
            AddColumn("createId",typeof(int));//创建人ID
            AddColumn("status",typeof(int));//审核状态
        }
    }
}

 入库管理展示窗体(继承窗体父类:DgvParentForm)

七、C#初学者练习小项目——仓库管理系统_第21张图片

 入库管理窗体的增删改查代码如下:

namespace Project.StorageManage
{
    public partial class InWareHouseForm : DgvParentForm
    {
        public InWareHouseForm()
        {
            InitializeComponent();
        }
        public void RefreshDgv() {
            InWareHouse inWareHouse = TableParent.Create();
            DataTable dataTable = inWareHouse.DataTable;
            dgv.DataSource = dataTable;
            dgv.Columns["whGoodsId"].HeaderText = "物品";
            dgv.Columns["batch"].HeaderText = "批次";
            dgv.Columns["money"].HeaderText = "单价";
            dgv.Columns["number"].HeaderText = "数量";
            dgv.Columns["remaiNumber"].HeaderText = "剩余数量";
            dgv.Columns["allMoney"].HeaderText = "总价";
            dgv.Columns["createId"].HeaderText = "创建人ID";
            dgv.Columns["status"].HeaderText = "审核状态";
            //id隐藏
            dgv.Columns["id"].Visible = false;
        }


        private void InWareHouseForm_Load(object sender, EventArgs e)
        {
            RefreshDgv();
        }

        private void btnInsert_Click(object sender, EventArgs e)
        {
            InWareHouseEditForm inWareHouseEditForm = new InWareHouseEditForm();
            DialogResult dr = inWareHouseEditForm.ShowDialog();
            if (dr == DialogResult.OK)
            {
                RefreshDgv();
            }
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0) {
                BoxUtil.AsteriskOk("请选中一行数据");
                return;
            }
            var row = rows[0];
            //审核通过之后,就不能再修改了(0:待审核,1:审核通过,2:审核未通过)
            int status = Convert.ToInt32(row.Cells["status"].Value);
            if (status == 1) {
                BoxUtil.AsteriskOk("审核已通过,不能再修改");
                return;
            }
            int id  = Convert.ToInt32(row.Cells["id"].Value);
            InWareHouseEditForm inWareHouseEditForm = new InWareHouseEditForm();
            inWareHouseEditForm.DbId = id;
            inWareHouseEditForm.dbRow = row;
            DialogResult dr = inWareHouseEditForm.ShowDialog();
            if (dr == DialogResult.OK)
            {
                RefreshDgv();
            }

        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0)
            {
                BoxUtil.AsteriskOk("请选中一行数据");
                return;
            } 
            DialogResult dr = BoxUtil.OKCancel("你确定要删除吗?");
            if (dr == DialogResult.OK)
            {
                var row = rows[0];
                int id = Convert.ToInt32(row.Cells["id"].Value);
                InWareHouse iwh = TableParent.Create();
                int result = iwh.Delete(id);
                if (result == 1)
                {
                    RefreshDgv();
                    return;
                }
                BoxUtil.AsteriskOk("删除失败,数据可能已经被删除");
            }
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            RefreshDgv();
        }

        /// 
        /// 审核通过按钮
        /// 
        /// 
        /// 
        private void button1_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0)
            {
                BoxUtil.AsteriskOk("请选中一行数据");
                return;
            }
            var row = rows[0];
            int id = Convert.ToInt32(row.Cells["id"].Value);
            //审核通过之后,就不能再修改了(0:待审核,1:审核通过,2:审核未通过)
            int status = Convert.ToInt32(row.Cells["status"].Value);
            if (status != 0) {
                BoxUtil.AsteriskOk("已经审核过,不能重复审核");
                return;
            }
            if (BoxUtil.OKCancel("确定审核通过吗") == DialogResult.OK) {
                Dictionary data = new Dictionary();
                //只修改状态
                data["status"] = 1;
                InWareHouse inWareHouse = TableParent.Create();
                inWareHouse.Edit(id, data);


                //修改商品的采购数量和剩余数量
                WareHouseGoods goods = TableParent.Create();
                DataTable dataTable = goods.DataTable;
                //获取当前选中行的物品id
                int goodId = Convert.ToInt32(row.Cells["whGoodsId"].Value);
                //获取当前选中行的物品id对应的物品的一行数据
                var goodsRow = dataTable.Rows.Find(goodId);
                int allCount = Convert.ToInt32(goodsRow["allCount"]);//查询原来总数量
                int residueCount = Convert.ToInt32(goodsRow["residueCount"]);//查询原来剩余数量
                Dictionary dataGoods = new Dictionary();
                int number = Convert.ToInt32(row.Cells["number"].Value);
                dataGoods["allCount"] = allCount + number;
                dataGoods["residueCount"] = residueCount + number;
                goods.Edit(goodId, dataGoods);
                RefreshDgv();
            }
            
        }

        /// 
        /// 审核未通过按钮
        /// 
        /// 
        /// 
        private void button2_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0)
            {
                BoxUtil.AsteriskOk("请选中一行数据");
                return;
            }
            var row = rows[0];
            int id = Convert.ToInt32(row.Cells["id"].Value);
            //审核通过之后,就不能再修改了(0:待审核,1:审核通过,2:审核未通过)
            int status = Convert.ToInt32(row.Cells["status"].Value);
            if (status != 0 )
            {
                BoxUtil.AsteriskOk("已经审核过,不能重复审核");
                return;
            }
            if (BoxUtil.OKCancel("确定审核不通过吗") == DialogResult.OK)
            {
                Dictionary data = new Dictionary();
                //只修改状态
                data["status"] = 2;
                InWareHouse inWareHouse = TableParent.Create();
                inWareHouse.Edit(id, data);
                RefreshDgv();
            }
        }
    }
}

入库管理添加和修改窗体如下: 

七、C#初学者练习小项目——仓库管理系统_第22张图片

入库管理添加和修改窗体代如下:

namespace Project.StorageManage
{
    public partial class InWareHouseEditForm : Form
    {
        public InWareHouseEditForm()
        {
            InitializeComponent();
        }
        public int DbId;
        public DataGridViewRow dbRow;

        private void InWareHouseEditForm_Load(object sender, EventArgs e)
        {
            if (dbRow != null)
            {
                foreach (Control con in Controls)
                {
                    if (con is IDbCon dbcon)
                    {
                        dbcon.SetDbValue(dbRow.Cells[dbcon.DbKeyName].Value);
                    }
                }
                //设置下拉框选中的ID
                CBGoodsId.SelectedValue = dbRow.Cells["whGoodsId"].Value;

                this.Text = "修改入库记录";
                button1.Text = "修改";
                label9.Text = "修改入库记录";
            }
            else {
                this.Text = "新增入库记录";
                button1.Text = "添加";
                label9.Text = "新增入库记录";
            }

            WareHouseGoods wareHouseGoods = TableParent.Create();
            DataTable dataTable = wareHouseGoods.DataTable;
            CBGoodsId.DataSource = dataTable;
            //下拉框显示的文本
            CBGoodsId.DisplayMember = "name";
            //下拉框隐藏的文本
            CBGoodsId.ValueMember = "id";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //前期判断
            foreach (Control con in Controls)
            {
                if (con is IDbCon idbcon)
                {
                    string str = idbcon.FilterDb();
                    if (!string.IsNullOrEmpty(str)) 
                    {
                        BoxUtil.AsteriskOk(str);
                        return;
                    }
                    
                }
            }
            //判断批次是否重复
            InWareHouse inWareHouse = TableParent.Create();
            if (inWareHouse.Exist(DbId,"batch",dbTbBatch.Text)) {
                BoxUtil.AsteriskOk("批次不能重复");
                return;
            }
            //保存
            Dictionary data = new Dictionary();
            foreach (Control con in Controls)
            {
                if (con is IDbCon idbcon)
                {
                    data[idbcon.DbKeyName] = idbcon.GetDbValue();
                }
            }
            int money = Convert.ToInt32(dbTbMoney.Text);
            int number = Convert.ToInt32(dbTbNumber.Text);
            int allMoney = money * number;
            data["allMoney"] = allMoney;
            data["remaiNumber"] = number;
            data["createId"] = UserUitl.Id;
            data["status"] = 0;
            data["whGoodsId"] = CBGoodsId.SelectedValue;//物品id
            inWareHouse.Edit(DbId,data);
            this.DialogResult = DialogResult.OK;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }
    }
}

2、出库管理窗体

七、C#初学者练习小项目——仓库管理系统_第23张图片

 出库管理实体类 

 出库管理展示窗体(继承窗体父类:DgvParentForm)

七、C#初学者练习小项目——仓库管理系统_第24张图片

 出库管理窗体的增删改查代码如下:

namespace Project.StorageManage
{
    public partial class OutWareHouseForm : DgvParentForm
    {
        public OutWareHouseForm()
        {
            InitializeComponent();
        }

        public void RefreshDgv()
        {
            OutWareHouse outWareHouse = TableParent.Create();
            dgv.DataSource = outWareHouse.DataTable;
            dgv.Columns["inwarehouseId"].HeaderText = "入库id";
            dgv.Columns["money"].HeaderText = "单价";
            dgv.Columns["number"].HeaderText = "数量";
            dgv.Columns["allMoney"].HeaderText = "总金额";
            dgv.Columns["createId"].HeaderText = "创建人id";
            dgv.Columns["status"].HeaderText = "审核状态";
            //id隐藏
            dgv.Columns["id"].Visible = false;
           
        }

        private void OutWareHouseForm_Load(object sender, EventArgs e)
        {
            RefreshDgv();
        }

        private void btnInsert_Click(object sender, EventArgs e)
        {
            OutWareHouseEditForm owhef = new OutWareHouseEditForm();
            DialogResult dr = owhef.ShowDialog();
            if (dr == DialogResult.OK)
            {
                RefreshDgv();
            }
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0)
            {
                BoxUtil.AsteriskOk("请选中一行数据");
                return;
            }
            var row = rows[0];
            //审核通过之后,就不能再修改了(0:待审核,1:审核通过,2:审核未通过)
            int status = Convert.ToInt32(row.Cells["status"].Value);
            if (status == 1)
            {
                BoxUtil.AsteriskOk("审核已通过,不能再修改");
                return;
            }
            int id = Convert.ToInt32(row.Cells["id"].Value);
            OutWareHouseEditForm outWareHouseEditForm = new OutWareHouseEditForm();
            outWareHouseEditForm.DbId = id;
            outWareHouseEditForm.dbRow = row;
            DialogResult dr = outWareHouseEditForm.ShowDialog();
            if (dr == DialogResult.OK)
            {
                RefreshDgv();
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0)
            {
                BoxUtil.AsteriskOk("请选中一行数据");
                return;
            }
            DialogResult dr = BoxUtil.OKCancel("你确定要删除吗?");
            if (dr == DialogResult.OK)
            {
                var row = rows[0];
                int id = Convert.ToInt32(row.Cells["id"].Value);
                OutWareHouse owh = TableParent.Create();
                int result = owh.Delete(id);
                if (result == 1)
                {
                    RefreshDgv();
                    return;
                }
                BoxUtil.AsteriskOk("删除失败,数据可能已经被删除");
            }
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            RefreshDgv();
        }

        //审核通过
        private void button1_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0)
            {
                BoxUtil.AsteriskOk("请选中一行数据");
                return;
            }
            var row = rows[0];
            int id = Convert.ToInt32(row.Cells["id"].Value);
            //审核通过之后,就不能再修改了(0:待审核,1:审核通过,2:审核未通过)
            int status = Convert.ToInt32(row.Cells["status"].Value);
            if (status != 0)
            {
                BoxUtil.AsteriskOk("已经审核过,不能重复审核");
                return;
            }
            if (BoxUtil.OKCancel("确定审核通过吗") == DialogResult.OK)
            {
                Dictionary data = new Dictionary();
                
                OutWareHouse outWareHouse = TableParent.Create();


                //获取当前选中行的入库id
                int inWHId = Convert.ToInt32(row.Cells["inwarehouseId"].Value);

                //查询入库id所在的行
                InWareHouse inWH = TableParent.Create();
                var inRow = inWH.DataTable.Rows.Find(inWHId);

                //查询选中行中的入库数据那一行中查询商品id
                int goodsId = Convert.ToInt32(inRow["whGoodsId"]);

                //修改商品的采购数量和剩余数量
                WareHouseGoods goods = TableParent.Create();
                //获取当前选中行的物品id对应的物品的一行数据
                var goodsRow = goods.DataTable.Rows.Find(goodsId);

                int number = Convert.ToInt32(row.Cells["number"].Value);
                int residueCount = Convert.ToInt32(goodsRow["residueCount"]) - number;//查询原来剩余商品数量
                if (residueCount < 0) {
                    BoxUtil.AsteriskOk($"剩余商品数量不足,还缺少{Math.Abs(residueCount)}个商品");
                    //只修改审核状态,当商品数量不够时,审核不能通过,审核状态就还是0
                    data["status"] = 0;
                    outWareHouse.Edit(id, data);
                    return;
                }
                Dictionary dataGoods = new Dictionary();
                dataGoods["residueCount"] = residueCount;
                goods.Edit(goodsId, dataGoods);

                //只修改审核状态,当商品剩余数量足够出库数量时,审核通过,审核状态修改成1
                //只修改状态
                data["status"] = 1;
                outWareHouse.Edit(id, data);
                RefreshDgv();
            }
        }
        //审核拒绝
        private void button2_Click(object sender, EventArgs e)
        {
            var rows = dgv.SelectedRows;
            if (rows.Count == 0)
            {
                BoxUtil.AsteriskOk("请选中一行数据");
                return;
            }
            var row = rows[0];
            int id = Convert.ToInt32(row.Cells["id"].Value);
            //审核通过之后,就不能再修改了(0:待审核,1:审核通过,2:审核未通过)
            int status = Convert.ToInt32(row.Cells["status"].Value);
            if (status != 0)
            {
                BoxUtil.AsteriskOk("已经审核过,不能重复审核");
                return;
            }
            if (BoxUtil.OKCancel("确定审核不通过吗") == DialogResult.OK)
            {
                Dictionary data = new Dictionary();
                //只修改状态
                data["status"] = 2;
                OutWareHouse outWareHouse = TableParent.Create();
                outWareHouse.Edit(id, data);
                RefreshDgv();
            }
        }
    }
}

出库管理添加和修改窗体如下: 

七、C#初学者练习小项目——仓库管理系统_第25张图片

 出库管理添加和修改窗体代如下:

namespace Project.StorageManage
{
    public partial class OutWareHouseEditForm : Form
    {
        public OutWareHouseEditForm()
        {
            InitializeComponent();
        }

        public int DbId;
        public DataGridViewRow dbRow;

        private void OutWareHouseEditForm_Load(object sender, EventArgs e)
        {
            if (dbRow != null)
            {
                foreach (Control con in Controls)
                {
                    if (con is IDbCon dbcon)
                    {
                        dbcon.SetDbValue(dbRow.Cells[dbcon.DbKeyName].Value);
                    }
                }
                //设置下拉框选中的ID
                dbTbBatch.SelectedValue = dbRow.Cells["inwarehouseId"].Value;
                this.Text = "修改出库记录";
                button1.Text = "修改";
                label9.Text = "修改出库记录";
            }
            else
            {
                this.Text = "新增出库记录";
                button1.Text = "添加";
                label9.Text = "新增出库记录";
            }
            InWareHouse inWareHouse = TableParent.Create();
            DataTable dataTable = inWareHouse.DataTable;
            dbTbBatch.DataSource = dataTable;
            //下拉框显示的文本
            dbTbBatch.DisplayMember = "batch";
            //下拉框隐藏的文本
            dbTbBatch.ValueMember = "id";
        }

        //保存
        private void button1_Click(object sender, EventArgs e)
        {
            //前期判断
            foreach (Control con in Controls)
            {
                if (con is IDbCon idbcon)
                {
                    string str = idbcon.FilterDb();
                    if (!string.IsNullOrEmpty(str))
                    {
                        BoxUtil.AsteriskOk(str);
                        return;
                    }
                }
            }

           
            //保存
            Dictionary data = new Dictionary();
            foreach (Control con in Controls)
            {
                if (con is IDbCon idbcon)
                {
                    data[idbcon.DbKeyName] = idbcon.GetDbValue();
                }
            }
            int money = Convert.ToInt32(dbTbMoney.Text);
            int number = Convert.ToInt32(dbTbNumber.Text);
            int allMoney = money * number;
            data["allMoney"] = allMoney;
            data["createId"] = UserUitl.Id;
            data["status"] = 0;
            data["inwarehouseId"] = dbTbBatch.SelectedValue;//入库id
            OutWareHouse outWareHouse = TableParent.Create();
            outWareHouse.Edit(DbId, data);
            this.DialogResult = DialogResult.OK;
        }
    }
}

你可能感兴趣的:(c#,开发语言)