首页 图书管理系统图书管理系统文档

图书管理系统图书管理系统文档

举报
开通vip

图书管理系统图书管理系统文档 C# WinForm项目实战 实训目标: · 综合前面的知识,练习C#编写程序的能力 · 提高.net控件的使用能力 · 了解实际开发中的项目流程 · 提高自己实际操作能力 课前准备 在开始这个项目之前,我们要求同学们能熟练使用SQL语句,C#基础编程语法与基础控件的使用。 项目介绍 本系统开发的目的是为了减轻图书管理工作的负担,将那些原来需要用手工完成的事情让计算机来完成。不但使得图书管理工作的效率大大提高,同时也大大地降低了出错概率。 本系统使用传统的编程方法,实现了真...

图书管理系统图书管理系统文档
C# WinForm项目实战 实训目标: · 综合前面的知识,练习C#编写程序的能力 · 提高.net控件的使用能力 · 了解实际开发中的项目流程 · 提高自己实际操作能力 课前准备 在开始这个项目之前,我们要求同学们能熟练使用SQL语句,C#基础编程语法与基础控件的使用。 项目介绍 本系统开发的目的是为了减轻图书管理工作的负担,将那些原来需要用手工完成的事情让计算机来完成。不但使得图书管理工作的效率大大提高,同时也大大地降低了出错概率。 本系统使用传统的编程方法,实现了真实项目的部分内容,同时有助于同学们的综合编写能力的提高。 图 21 所示图21是图书管理系统整体功能结构图,每个部分也就是一个模块。系统由图上所示的各种模块组合而成,每个模块都完成相应得功能,它们协调一致进行工作,下面将简要介绍各个模块的功能。 · 登陆模块 登陆模块是用户进入系统的一个必须途径,它保证了用户或管理员能以不同的权限进入系统,从而实现不同的功能操作。对不同类别的人员的登陆判断,保证了系统操作的安全性。 · 帐户管理模块 本模块实现了对用户的基本信息的管理。管理员对自己登陆口令及密码的修改,提高了重要账户的安全性。 退出系统功能,让用户能或管理员正常地退出操作系统。 · 系统管理模块 本模块主要针对系统的关键功能操作,实现了对用户的管理,可以新增用户。一般来说,在很多系统里,都不提供删除记录的操作。所以这里也不提供删除用户的操作。实现了书籍录入的功能,能让图书管可以及时添加新书。 · 书籍管理模块 本模块实现了图书馆里的日常工作操作,并使其简单化,精确化。实现了借书功能以及还书功能。 对借书者信息的查询功能,管理员可以查询借书者借书情况。 书籍的管理功能,管理员可以对书籍的借阅情况进行查询。 · 读者管理模块 本模块主要提供给用户,让借阅者可以查询自己所借书籍的相关信息,并查询图书馆里的所有可借阅书籍。 环境要求 运行系统要求:Win9x/Me/NT/2000/XP/2003 256M及以上内存,1.6Hz及以上CPU。 开发平台:Visual Studio 2008,SQL 2005,visio 2003。 用到的 知识点 高中化学知识点免费下载体育概论知识点下载名人传知识点免费下载线性代数知识点汇总下载高中化学知识点免费下载 我们在这个项目里面,将会用到C#为主要编程语言,运用到Winfrom的基础知识。 我们将会用到的控件如下表2-1: 表 21 TextBox TextChanged Button Click MenuStrip NumericUpDown ComboBox SelectedIndexChanged TabControl DataGridView GroupBox Lable 推荐实现步骤 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 数据库并画出ER图 首先我要从需求上 分析 定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析 ,我们需要做哪些事情:读者可以借书,还书,查询哪些书可以借出去;然后会想到这些事情的参与者:读者借书,还书,书籍管理员来借出书与收回书,查询读者的借书情况;再深入地想到:为什么读者可以查询哪些书可以借出去,或自己借了哪些书,为什么不同级别的读者能够借书的时间也不同;管理员为什么可以去管理书籍情况与读者借书情况;这样就出现了一个权限关系。 我们在SQL 2005里新建一个数据库LibrarySystem,设计出以下2-2所示的几张表: 表 22 读者表(User) 读者等级表(ReaderGrade) 书籍表(books) 书籍类别表(BookType) 管理员表(Manager) 角色表(Role) 借书表(BorrowBook) 表之间的关系如下图2-2: 图 22 这是一个非常简单的关系图,我们可以看到: · 读者和书籍产生了多对多的关系 · 读者与读者等级是多对一的关系 · 管理员和借书操作是一对多的关系 · 角色分别与读者,管理员产生一对多的关系 · 类别与书籍产生一对多的关系 最后我们完成数据字典,请看表2-3: 表 23 角色表 Role 字段中文名 字段名 字段类型 约束 角色ID roleID Begint 主键,自增 角色名称 roleName Varchar(50) 读者等级ReaderGrade 读者等级 grandID Begint 主键,自增 等级描述 grandName Varchar(50) 可借数量 quantity Int 还书期限 dateAmount Int 类别 BookType 类别ID typeID Begint 主键,自增 类别名称 typeName Varchar(50) 书籍表 Books 书籍ID bookID Begint 主键,自增 书籍名称 bookName Varchar(50) 书籍数量 bookQuantity Int 单价 price Int 作者 author Varchar(50) 出版社 bookConcern Varchar(50) 书号 bookCode Varchar(50) 书籍类别ID typeID Begint 外键,引用类别表 读者表 Reader 读者ID readerID Begint 主键,自增 用户名 readerName Varvhar(50) 用户密码 readerPass Varchar(50) 用户姓名 realityName Varchar(50) 地址 address Varchar(50) 电话 phone Varchar(50) 角色ID roleID Begint 外键,引用角色表 等级ID grandID Begint 外键,引用等级表 管理员表 Manager 管理员ID managerID Begint 主键,自增 登录名 manageName Varchar(50) 登录密码 managePass Varchar(50) 姓名 realityName Varchar(50) 地址 address Varchar(50) 电话 phone Varchar(50) 角色ID roleID Begint 外键,引用角色表 上班时间 dutyDate smallDateTime 下班时间 leaveDate smallDateTime 借书表 BorrowBook 借书ID borrowID Begint 主键,自增 读者ID readerID Begint 外键,引用读者表 管理员ID managerID Begint 外键,引用管理员表 借书时间 borrowDate smallDateTime 还书时间 restoreDate smallDateTime 书籍状况 bookStart Varchar(50) 书籍ID bookID Begint 外键,引用书籍表 功能实现 我们打VS 2008新建一个C#语言的Windows窗体应用程序项目LibrarySystem。 全局文件部分 创建公共系统数据类(SystemData) 我们会在整个系统中,用到一些公共的参数,比如用户登陆后的名称(UserName),用户ID(readerID),角色ID(roleID)等。所以我们在项目中添加一个文件夹ClassLibrary,在其中添加一个类:SystemData。 我们在其中定义一些公共变量: 代码: public static long managreID = -1; public static long readerID = -1; public static string userName = ""; public static long roleID = -1; public static string roleName =""; 创建公共数据操作类(ControlDB) 我们将会针对数据库进行一系列操作,所以我们在ClassLibrary文件夹下添加一个数据操作类(ControlDB),我们会提供以下几个方法及变量: · private string strConn 声明 无利益冲突声明中华医学会杂志社职业健康检查不够规范教育部留学服务中心亲友住房声明 一个string变量,保存连接字符串。 · private SqlConnection conn 声明一个连接对象,并初始化为NULL。 · public ControlDB(){}构造方法封装一个连接对象。 · public int UpdataDB(string strSql){} 用来执行SQL语句,并返回受影响的行数。主要用来更新数据库 · ExecuteNonQuery();用来返回结果。 · public object Query (string strSql){} 这个方法用来验证对象是否存在,并返回结果。 · ExecuteScalar();用来返回结果。 · public DataSet GetDataSet(DataSet ds,string strSelect,string tableName){} · 创建一个SqlComman,在打开数据连接后,创建一个SqlDataAdapter。 · 用SqlDataAdapter把表填充到ds,并给ds里的表取一个别名tableName,最后将填充表后的ds返回出去。 我们还会动态地将数据绑定到ComboBox里,这里我们写一个public void BindComBox(string sqltxt, ComboBox comboxName){}方法,这里用GetDataSet方法从数据库里取得要梆定到ComboBox里的字段,再用循环写入到ComboBox里。 创建登陆窗体(frmLoad) 此窗体将会用到TextBox,ComboBox,Button这些控件,效果如下图2-3所示: 图 23 窗体命名如表2-4所示: 表 24 控件 控件名 UI名 TextBox txtUserName 用户名 TextBox txtPassWord 密码 ComboBox cbType 类型 Button btnOK 确定 Button btnCencal 取消 首先在这个窗体加载的时候,要给cbType绑定数据,我们先把需要的数据从数据库拿出来,并存入一个DataSet。 代码: DataSet ds = new DataSet(); ds = db.GetDataSet(ds, "select * from Role", "Role"); 绑定到cbType。 然后声明一个数组,长度由查出的结果定,并且把它赋给全局的ClassLibrary.SystemData.roleNames,这样我们在后面一些窗体里就不用再去数据库拿信息,直接在全局变量里拿就行了。 代码: cbType.DataSource = ds.Tables[0]; cbType.DisplayMember = "roleName"; cbType.ValueMember = "roleID"; 我们在点击确定的时候进行判断用户是否能登陆,并记录其相应信息到全局变量。 首先判断用户登陆是哪种角色,如果为读者(cbType.SelectedIndex == 2),则查询Users表,如果不是,则查询管理员表(Manager),并用ClassLibrary.ControlDB里的Query方法返回查询结果。如果不为空,记录下用户名,角色ID,到全局变量,并把登陆状态改成true。 代码: ClassLibrary.SystemData.userName = txtUserName.Text; ClassLibrary.SystemData.roleName = cbType.Text; validateLoad = true; 这里边如果登录的是用户,则记录下用户ID,否则记录是管理员ID;完成以上操作后关闭此界面。 代码: ClassLibrary.SystemData.roleID = Convert.ToInt64(cbType.SelectedValue); object obj = null; if (cbType.SelectedIndex == 2) { obj = db.Query("select readerID from Reader where readerName='" + txtUserName.Text + "' and readerPass='" + txtPassWord.Text + "'"); if (obj != null) { ClassLibrary.SystemData.readerID = int.Parse(obj.ToString()); this.Close(); } else { MessageBox.Show("帐号密码错误,请重新输入", "警告信息!"); txtPassWord.Text = ""; txtUserName.Text = ""; } } else { obj = db.Query("select managerID from Manager where manageName='" + txtUserName.Text + "' and managePass='" + txtPassWord.Text + "' and roleID=" + ClassLibrary.SystemData.roleID); if (obj != null) { ClassLibrary.SystemData.managreID = int.Parse(obj.ToString()); this.Close(); } else { MessageBox.Show("帐号密码错误,请重新输入", "警告信息!"); txtPassWord.Text = ""; txtUserName.Text = ""; } } ClassLibrary.ControlDB里的Query方法返回查询结果为空,那么登陆错误,然后清空txtPassWord与txtUserName。 代码: MessageBox.Show("帐号密码错误,请重新输入!", "警告信息"); txtPassWord.Text = ""; txtUserName.Text = ""; 最后当我们点击取消按钮时,关闭窗体: 代码: this.Close(); 到这里我们就完成了用户的登陆与判断功能。 创建主窗体(frmMain) 在工具栏里拖入一个MenuStrip控件,分别设置其菜单如下图2-4所示: 图 24 菜单命名如表2-5所示: 表 25 系统管理 sysToolStripMenuItem 用户管理 userManageToolStripMenuItem 书籍管理 bookManageToolStripMenuItem 统计 statisticToolStripMenuItem 书籍管理菜单如图2-5所示: 图 25 菜单命名如表2-6所示: 表 26 书籍管理 bookToolStripMenuItem 借书 borrowBookToolStripMenuItem 还书 returnBookToolStripMenuItem 查询 selectBorrowToolStripMenuItem1 借书者信息 borrowerInfoToolStripMenuItem 书籍管理 borrowBooksManageToolStripMenuItem 读者管理菜单如图2-6所示: 图 26 菜单命名如表2-7所示: 表 27 读者管理 readerToolStripMenuItem 查询 selectToolStripMenuItem 查询可借书籍 selectBooksToolStripMenuItem 查询所借书籍 selectBorrowToolStripMenuItem 账户菜单如图2-7所示: 图 27 菜单命名如表2-8所示: 表 28 帐户管理 accountToolStripMenuItem 用户信息 userInfoToolStripMenuItem 密码修改 passToolStripMenuItem 退出系统: exitToolStripMenuItem 功能实现: 我们在加载这个窗体时,首先要加载登陆页面,这样才能保证系统的安全性,并且跟据frmLoad页是否已经验证通过,来控制此窗体的状态,同时跟据用户登陆的角色来控制用户能进行的相关操作。 代码: frmLoad load = new frmLoad(); load.ShowDialog(); if (!load.ValidateLoad) { this.Close(); } sysToolStripMenuItem.Enabled = ClassLibrary.SystemData.roleID == 0; bookToolStripMenuItem.Enabled = ClassLibrary.SystemData.roleID == 1; readerToolStripMenuItem.Enabled = ClassLibrary.SystemData.roleID == 2 当我们在点击相应的菜单选项时,会弹出应的窗体: 首先我们先把窗体实例化出来,再指定它的MdiParent为this,最后Show()出来, 示例: AccountManage.frmChangePass frm = new LibrarySystem.AccountManage.frmChangePass(); frm.MdiParent = this; frm.Show(); 注意: 这此把窗体Show()出来的方法可以等我们在完成了其它窗体后再来编写。我们在打开添加书籍(BookEnter)时,应该传一个参数1过去 系统管理部分 首先我们在项目下添加一个文件夹,命名为:SystemManage, 在SystemManage下添加一个窗体,命名为:frmUserManage。 frmUserManager窗体 界面设计: 这个窗体用到了TabControl控件,设计页面如下图2-8、2-9所示: 图 28 图 29 控件命名如下表2-9所示: 表 29 控件类型 控件名 UI名 TabControl tcSelect TextBox txtUserName 用户名 TextBox txtPass 密码 TextBox txtTrueName 真实姓名 TextBox txtTell 电话 TextBox txtAddress 地址 ComboBox cmbRole 角色分配 DataGridView dgvInfo 放在管理员视图里 DataGridView dgvReader 放在读者视图里 Button btnSubmit 确定 Button btnReset 重置 Label 读者级别 Label lbQuantity 可借数量 Label lbDateAmount 还书期 ComboBox cbGrand GroupBox gbGrand 功能实现: 我们在加载的时候会给读者级别cbGrand绑定相应的数据,会给两个DataGradView都绑定对应的数据。 我们可以定义一个全局的DataSet来存储这些信息,我们需要角色表的信息,用户表的信息,用户级别表的信息,用户表信息,管理员表信息。 再定义一个全局的ClassLibrary.ControlDB db = new ClassLibrary.ControlDB();来执行数据库操作 可以将这些信息都封装在一个方法private void GetData()里,用DataSet来存储。 代码: ds.Tables.Clear(); ds = db.GetDataSet(ds, "select * from Role", "Role"); ds = db.GetDataSet(ds, "select manageName 用户姓名,realityName 真实姓名,address 地址,phone 电话,roleName 角色描述 from Manager m,Role ro where m.roleID=ro.roleID", "Manager"); ds = db.GetDataSet(ds, "select readerName 用户姓名,realityName 真实姓名,address 地址,phone 电话,roleName 角色描述,grandName 级别描述,quantity 可借数量,dateAmount 还书期 from Reader r,Role ro,ReaderGrade g where r.roleID=ro.roleID and r.grandID=g.grandID", "Reader"); ds = db.GetDataSet(ds, "select * from ReaderGrade", "ReaderGrade"); 然后将数据绑定到对应的DataGridView里,并初始化cmbRole。 代码: dgvInfo.DataSource = null; dgvInfo.DataSource = ds.Tables[1]; dgvReader.DataSource = null; dgvReader.DataSource = ds.Tables[2]; 最后在窗体加载时,载入这些信息到UI上,并将gbGrand初始化为不可见。 代码: GetData(); cbGrand.DataSource = ds.Tables[3]; cbGrand.DisplayMember = "grandName"; cbGrand.ValueMember = "grandID"; cbGrand.SelectedIndex = 0; gbGrand.Visible = false; foreach (DataRow dr in ds.Tables[0].Rows) { if (!dr["roleName"].Equals("读者")) { cmbRole.Items.Add(dr["roleName"]); } } cmbRole.SelectedIndex = 0; 因为在不同的视图里,角色分配cmbRole里面的信息不同所以我们在TableControl页面切换事件里将不同的信息载入: 代码: cmbRole.Items.Clear(); switch (tcSelect.SelectedIndex) { case 0: foreach (DataRow dr in ds.Tables[0].Rows) { if (!dr["roleName"].Equals("读者")) { cmbRole.Items.Add(dr["roleName"]); } } gbGrand.Visible = false; break; case 1: cmbRole.Items.Add("读者"); gbGrand.Visible = true; break; } cmbRole.SelectedIndex = 0; 在页面切换时,为了不让重复的信息加载,所以cmbRole.Items.Clear(),在选择管理员视图时gbGrand.Visible = false;在选择读者视图时 gbGrand.Visible = true,默认让CmbRole选择第一个,接下来,在读者视图里,当我们选择不同的读者级别时,在UI上显示不同级别相应的一些权限。 代码 : lbQuantity.Text = "可借数量是: " +ds.Tables[3].Rows[cbGrand.SelectedIndex]["quantity"].ToString()+" 本"; lbDateAmount.Text = "还 书 期是: " + ds.Tables[3].Rows[cbGrand.SelectedIndex]["dateAmount"].ToString()+" 天"; 这些相应的数据,都是我们在加载窗体时从数据库里拿出来的存在DataSet里的,当我们在需要的时候可以在窗体里取用,就不必多次联接数据库了,这样可以减轻对数据库服务器的开销。 当我们在点击重置按钮时,会将输入框里的信息清空TextBox.Text=""。 最后让我们来完成修改功能,双击btnSubmit注册Click事件,在事件中定义一个全局的int roleID=-1。 我们先取得要角色的ID,将从cmbRole里用选择的SelectedItem与ds.Tables[0]表里的roleName相匹配,如果相同,则获得roleID,并赋给全局的int roleID。 代码: foreach (DataRow dr in ds.Tables[0].Rows) { if (dr["roleName"].Equals(cmbRole.SelectedItem)) { roleID = int.Parse(dr["roleID"].ToString()); break; } } 我们要根据视图来选择对应的SQL语句switch (tcSelect.SelectedIndex){}, 如果为管理员视图case 0: 代码: strInsert = "insert into Manager values('" + txtUserName.Text + "','" + txtPass.Text + "','" + txtTrueName.Text + "','" + txtAddress.Text + "','" + txtTell.Text + "'," + roleID + ")"; 如果为读者视图 case 1: 我们从ds.Tables[3]取得grandID并存储下来,实现方法同取得角色ID,写出SQL语句。 代码: strInsert = "insert into Reader values('" + txtUserName.Text + "','" + txtPass.Text + "','" + txtTrueName.Text + "','" + txtAddress.Text + "','" + txtTell.Text + "'," + roleID + "," + cbGrand.SelectedValue + ")"; 最后用db.UpdataDB(strInsert);执行SQL语句,并将视图刷新一次:GetData()。 frmBookEnter窗体 界面设计如图2-10所示: 图 210 控件命名如下表2-10所示: 表 210 控件类型 控件名 UI名 TextBox txtName 书名 TextBox txtAuthor 作者 TextBox txtCode 书号 TextBox txtConcern 出版社 NumericUpDown nudQuantity 数量 NumericUpDown nudPrice 单价 ComboBox cbType 类型j 功能实现: 如下图2-11所示: 图 211 我们在类下定义一个全局的long bookID=0,DataSet ds用来保存一些全局的信息。 声明出有参构造 用来给BookID赋值。 代码: public frmBookEnter(long bookID) { InitializeComponent(); this.bookID = bookID; } 如是编辑书籍,则窗体里的控件都不可用,在窗体加载时判断: 代码: txtName.ReadOnly = bookID == 0; txtAuthor.ReadOnly = bookID == 0; txtCode.ReadOnly = bookID == 0; txtConcern.ReadOnly = bookID == 0; cbType.Enabled = bookID > 0; 在这个项目里面,我们不会在其它页面进入打开这个窗体,但是当我们扩展功能后,比如: 管理员在对书籍查询后,发现某些书籍需要补充了,这时直接从查询页面进扩添加书籍页面,就可以跟据查询到的书籍ID来添加相关信息,这样减少了去数据库查询数据的操作次数,系统重用性更高。 在加载窗体的时候我们通过BookID来确定载入的信息。 代码: ClassLibrary.ControlDB db = new LibrarySystem.ClassLibrary.ControlDB(); ds = db.GetDataSet(ds, "select * from BookType", "Type"); if (bookID > 0) { try { ds = db.GetDataSet(ds, "select * from Books where bookID = " + bookID, "Books"); nudQuantity.Value= int.Parse(ds.Tables[1].Rows[0]["bookQuantity"].ToString()); nudPrice.Value = int.Parse(ds.Tables[1].Rows[0]["price"].ToString()); } catch { } } foreach (DataRow dr in ds.Tables[0].Rows) { cbType.Items.Add(dr["typeName"].ToString()); } if (cbType.Items.Count > 0) { if (bookID > 0) { cbType.SelectedValue = db.Query("select typeID from Books where bookID = " + bookID); } else { cbType.SelectedIndex = 0; } } 当点击重置按钮时: 代码: if (bookID > 0) { txtName.Text = ""; txtConcern.Text = ""; txtCode.Text = ""; txtAuthor.Text = ""; nudPrice.Value = 0; nudQuantity.Value = 0; } else { try { nudQuantity.Value = int.Parse(ds.Tables[1].Rows[0]["bookQuantity"].ToString()); nudPrice.Value = int.Parse(ds.Tables[1].Rows[0]["price"].ToString()); } catch { } 当点击取消时: This.Close(); 当点击保存时: 代码: string strSql = ""; if (bookID == 0) { strSql = "insert into Books values('" + txtName.Text + "'," + nudQuantity.Value + "," + nudPrice.Value + ",'" + txtAuthor.Text + "','" + txtConcern.Text + "','" + txtCode.Text + "'," + cbType.SelectedValue + ")"; } else { strSql = "update Books set bookQuantity = " + nudQuantity.Value + ", price = " + nudPrice.Value + " where bookID = " + bookID; } db.UpdataDB(strSql); frmStat窗体 界面设计如下图2-12所示 图 212 控件命名如下表211所示: 表 211 控件类型 控件名 UI名 tabControl tcl1 热门书籍 ComboBox cbType DataGridView dgvInfo 功能实现:当这个窗体加载时: 代码: cbType.Items.Add("全部"); ds = db.GetDataSet(ds, "select * from BookType", "BookType"); foreach (DataRow row in ds.Tables[0].Rows) { cbType.Items.Add(row["typeName"]); } cbType.SelectedIndex = 0; ds = db.GetDataSet(ds, "select * from BookType", "BookType"); 当我们选择不同的类型筛选时: 代码: string strSelect = "select top 10 bookName 书名,price 价格,author 作者,bookConcern 出版社,bookCode 书号,typeName 类别,degree 借出次数 from Books b,BookType t,(select bookID,count(bookID) degree from BorrowBook group by bookID) a where b.bookID=a.bookID and b.typeID=t.typeID"; if (cbType.SelectedIndex > 0) { strSelect += " and typeName = '" + cbType.SelectedItem.ToString() + "'"; } strSelect += " order by degree desc"; dgvInfo.DataSource = null; dgvInfo.DataSource = db.GetDataSet(new DataSet(), strSelect, "热门统计").Tables[0]; 书籍管理部分 在项目下新添加一个BookManage文件夹。 frmBackManage窗体 在BookManage文件夹里添加frmBackManage窗体。 界面设计如下图2-13所示: 图 213 控件命名如下表2-12所示: 表 212 控件类型 控件名 UI名 TextBox txtUserName 用户名 ComboBox cbBook 书籍 TextBox txtBookStat 书籍状况 Button btnOK 确定 Button btnBackBook 确定归还 Button btnClear 清空 功能实现: 当我们去图书馆去还书时,会跟据用户名,查询出读者借了哪些书,然后会在这些书里去选择要还的是哪本书。 所以在输入用户名并点击确定后,会在书籍的cbBook里绑定用户借了哪些书,我们定义一个方法private void GetBookInfo()来实现这些功能。 当在每次调用时,就把原来cbBook里的信息清空。 代码: ds.Tables.Clear(); cbBook.Items.Clear(); txtBookStat.Text = ""; 再从数据库里取得相关信息,bookName,bookid,readerid并存入一个DataSet。 代码: ClassLibrary.ControlDB db = new LibrarySystem.ClassLibrary.ControlDB(); ds = db.GetDataSet(ds, "select bookName,b.bookID,c.readerID from BorrowBook c,Books b,Reader r where c.bookID=b.bookID and c.readerID = r.readerID and readerName = '" + txtreaderName.Text + "' and restoreDate is null", " BorrowBook"); 并将其写入cbBook: 代码: cbBook.DataSource = ds.Tables[0]; cbBook.DisplayMember = "bookName"; cbBook.ValueMember = "bookID"; 如果此用户借过书,那么取得用户ID,便可以还书。 代码: if (cbBook.Items.Count > 0) { cbBook.SelectedIndex = 0; readerID = int.Parse(ds.Tables[0].Rows[0]["readerID"].ToString()); btnBackBook.Enabled = true; } 否则便不能还书。 代码: btnBackBook.Enabled = false; 在点击确定btnOk时,调用GetBookInfo.实现查询功能。 当用户在修改了用户名后,将btnBackBook设置为false;在点击清空时,将文本清空。 代码: txtUserName.Text = ""; txtBookStat.Text = ""; cbBook.DataSource = null; btnBackBook.Enabled = false; 最后,在点击还书时,实现还书功能。 这时将会在BorrowBook里修改还书时间及还书状态: 代码: string strUpdate = "update BorrowBook set restoreDate = '" + DateTime.Now.ToShortDateString() + "',bookStart = '" + txtBookStat.Text + "' where readerID = " + readerID + " and bookID = " + cbBook.SelectedValue; 当行成功后,显示用户新的信息并提示用户: 代码: if (db.UpdataDB(strUpdate) > 0) { MessageBox.Show(cbBook.SelectedItem.ToString() + " 归还成功", "提示信息"); GetBookInfo(); } frmBookManage窗体 在BookManage文件夹里添加frmBookManage窗体 界面设计如下图2-14所示: 图 214 控件命名如下表表 213所示: 表 213 控件类型 控件名 UI名 Button btnSearch 查找 ComboBox cbPar 查询类型 ComboBox cbType 这两个控件重合放在一起 TextBox txtMess DataGridView dgvInfo 功能实现: 这是一个给书籍管理员使用的功能。我们确定可以分类来查询:按书籍类型,按书籍名称,按书籍编号;并且查询出的结果如图。 所以在窗体加载时,应该载入书籍的相关信息,以及分类信息。 载入分类信息: 代码: txtMess.Visible = false; cbPar.Items.Add("按书籍类型"); cbPar.Items.Add("按书籍名称"); cbPar.Items.Add("按书籍书号");// 载入书籍信息,及将书籍类型信息绑定到cbType。 代码: ds = db.GetDataSet(ds, "select * from BookType", "BookType"); ds = db.GetDataSet(ds, "select bookName 书名,price 价格,author 作者,bookConcern 出版社,bookCode 书号,typeName 类别 from Books b, BookType t where b.typeID=t.typeID", "Books"); cbType.DataSource = ds.Tables[0]; cbType.DisplayMember = "typeName"; cbType.ValueMember = "typeID"; 注意: ds是类文件下的全局对象。 当我们点击cbPar时,会将对应的查询控件显示出来,因为我们会在窗体加载时设置cbPar.SelectedIndex=0。 代码: cbType.Visible = cbPar.SelectedIndex == 0; txtMess.Visible = cbPar.SelectedIndex > 0; 最后,当我们点击查询时,会实现查询功能。 因为在前面的DataSet ds里存入了书籍的相关信息.所以这里便不需要再去读数据库,直接在ds上查询便可。 定义一个string strSelect=""来存放查询条件。 代码: string strSelect = ""; switch (cbPar.SelectedIndex) { case 0: strSelect = "类别= '" + cbType.Text + "'"; break; case 1: strSelect = "书名 like '%" + txtMess.Text + "%'"; break; case 2: strSelect = "书号 like '%" + txtMess.Text + "%'"; break; } 经过查询,将结果存入一个DataTable,并绑定到dgvInfo。 代码: DataTable dt = ds.Tables[1].Clone(); foreach (DataRow row in ds.Tables[1].Select(strSelect)) { dt.Rows.Add(row.ItemArray); } dgvInfo.DataSource = null; dgvInfo.DataSource = dt; 到这里,我们使完成了书籍管理功能。 frmBorrowerInfoManage窗体 在BookManage文件夹里添加frmBorrowerInfoManage窗体。 界面设计如下图2-15所示: 图 215 控件命名如下表表 214所示: 表 214 控件类型 控件名 UI名 TextBox txtName 用户名 Button btnOK 确定 DataGridView dgvInfo Lable lbAll 可以借多少本书 Lable lbOld 已经借了多少书 Lable lbNow 还可以借多少书 在窗体加载时和文本框txtNme改变时,加载。 代码: lbAll.Text = "您总共可以借 0 本书";; lbOld.Text = "您已经借了 0 本书";; lbNow.Text = "您还可以借 0 本书"; 当在点击确定时,显示搜索出的内容。 从ReaderGrade和Reader表里根据用户名获得要使用的数据。 代码: ds = db.GetDataSet(ds, "select quantity,dateAmount from ReaderGrade g,Reader r where r.grandID = g.grandID and readerName = '" + txtName.Text + "'", "ReaderGrade"); 如用户有借书ds.Tables[0].Rows.Count > 0,便取得用户借了多少本,可以借多少本, 代码: object obj = db.Query("select count(r.readerID) from BorrowBook c,Reader r where c.readerID=r.readerID and restoreDate is null and readerName = '" + txtName.Text + "'"); int all = int.Parse(ds.Tables[0].Rows[0]["quantity"].ToString()); int old = 0; if (obj != null) { old = int.Parse(obj.ToString()); } int date = int.Parse(ds.Tables[0].Rows[0]["dateAmount"].ToString()); ds = db.GetDataSet(ds, "select bookName 书名,bookCode 书号,typeName 类别,borrowDate + " + date + " 最晚还书时间 from Books b,BookType t, BorrowBook c,Reader r where b.bookID=c.bookID and b.typeID=t.typeID and c.readerID = r.readerID and restoreDate is null and readerName = '" + txtName.Text + "'", "BorrowBook "); 显示出借出的书相关信息与用户借书权限的相关信息。 代码: dgvInfo.DataSource = null; dgvInfo.DataSource = ds.Tables[1]; lbAll.Text = "您总共可以借 " + all + " 本书"; ; lbNow.Text = "您还可以借 " + (all - old) + " 本书"; frmBorrowManage窗体 在BookManage文件夹里添加frmBorrowManage窗体 界面设计如下图2-16所示: 图 216 控件命名如下表表 215所示: 表 215 控件类型 控件名 UI名 TextBox txtBook 请输入书名 TextBox txtUserName 请输入借阅者 Button btnBookView 预览 Button btnOK 确定 Button btnBorrow 确定借阅 DataGridView dgvBookInfo Label lbAll 显示可以借多少本书 Label lbOld 显示已经借了多少本书 Label lbNow 显示还可以借多少本书 功能实现: 我们在这个窗体里,只有存在的书才可以借阅,只有用户还存在可以借书的权限,才可以借阅。所以在整个文档中定义一些锁,来控制相关操作。 代码: private bool lockUser = false; private bool lockBook = false; 并且,定义出要在UI里显示的内容与要使用的相关参数。 代码: private long bookID = 0; private int residual = 0; private int old = 0; 在窗体加载时,载入UI信息,并让其不可借阅。 代码: lbAll.Text = "您总共可以借 0 本书"; lbOld.Text = "您已经借了 0 本书"; lbNow.Text = "您还可以借 0 本书"; btnBorrow.Enabled = false; 在txtBook,与txtreaderName内容改变时: 代码: btnBorrow.Enabled = false; 当在点击预览时,我们会把读者要借的书的信息显示给读者,首先验证: 代码: if (txtBook.Text == "") { MessageBox.Show("请输入书名!", "提示信息"); return; } 这时我们便可以拿到书籍相关的信息了。 代码: string strSelect = "select b.bookID, bookName 书名,author 作者,bookConcern 出版社,bookCode 书号,typeName 类别,bookQuantity-degree 剩余数量,b.bookID from Books b,BookType t,(select bookID,count(bookID) degree from BorrowBook group by bookID) a where b.bookID=a.bookID and b.typeID=t.typeID and bookName ='" + txtBook.Text + "' union all select distinct b.bookID,bookName 书名,author 作者,bookConcern 出版社,bookCode 书号,typeName 类别,bookQuantity 剩余数量,b.bookID from Books b,BookType t where b.typeID=t.typeID and bookName ='" + txtBook.Text + "' and bookID not in (select bookID from BorrowBook where restoreDate is null)"; ds = db.GetDataSet(ds, strSelect, "Books"); dgvBookInfo.DataSource = null; dgvBookInfo.DataSource = ds.Tables[0]; dgvBookInfo.Columns["bookID"].Visible = false; 在存在些书的情况下,解开lockBook,并取得bookID: 代码: if (ds.Tables[0].Rows.Count > 0) { bookID = int.Parse(ds.Tables[0].Rows[0]["bookID"].ToString()); } lockBook = ds.Tables[0].Rows.Count > 0; btnBorrow.Enabled = lockUser && lockBook; //如果lockUser为true,则可以借阅btnBorrow.Enabled = true。 在读者输入用户名后,我们查询出此用户借书的相关权限,并显示在界面上。 代码: if (txtUserName.Text == "") { MessageBox.Show("请输入读者名!", "提示信息"); return; } object obj = db.Query("select count(r.readerID) from BorrowBook c,Reader r where c.readerID=r.readerID and restoreDate is null and readerName = '" + txtUserName.Text + "'"); if (obj != null) { old = int.Parse(obj.ToString()); } obj = db.Query("select quantity from ReaderGrade g,Reader reader where g.grandID=reader.grandID and readerName = '" + txtUserName.Text + "'"); int all = 0; if (obj != null) { all = int.Parse(obj.ToString()); } residual = all - old; lbAll.Text = "您总共可以借 " + all + " 本书"; //同时解开用户锁 SetLableMessage(old, residual); SetLableMessage定义如下: 代码: private void SetLableMessage(int iOld, int iresidual) { lbOld.Text = "您已经借了 " + iOld + " 本书"; lbNow.Text = "您还可以借 " + iresidual + " 本书"; lockUser = iresidual > 0; btnBorrow.Enabled = lockUser && lockBook; } 在点击借书时,通过readerID实现对BorrowBook表的修改。 代码: object obj = db.Query("select readerID from Reader where readerName = '" + txtUserName.Text + "'"); if (obj != null) { long readerID = long.Parse(obj.ToString()); string strUpdate = "insert into BorrowBook values(" + readerID + "," + ClassLibrary.SystemData. managreID + ",'" + DateTime.Now.ToString() + "',NULL,NULL," + bookID + ")"; if (db.UpdataDB(strUpdate) > 0) { MessageBox.Show("借书成功!", "提示信息"); txtBook.Text = ""; lockBook = false; SetLableMessage(++old, --residual); } } 读者管理部分 在项目下新添加一个ReaderManage文件夹。 frmSelectAllowBorrowBooks窗体 在ReaderManage文件夹里添加frmSelectAllowBorowBooks窗体。 界面设计如下图2-17所示: 图 217 控件命名如下表表 216所示: 表 216 控件类型 控件名 UI名 GroupBox grpSearchType 书籍查询分类 GroupBox grpResultType 查询结果 ComboBox cbPar 查询 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 TextBox txtBookName 用于查询的数据, 这两个重合在一起 ComboBox cbBookTypes Lable lblBookName 请输入书名 Button btnSearch Search DataGridView dgvShowResult 功能实现: 此窗体在功能上和frmBookManage是一样的,请同学们自行完成此页面 注意:在SQL语句上的应用。 FrmSelectedBorrowBooks窗体 在ReaderManage文件夹里添加FrmSelectedBorrowBooks窗体。 界面设计如下图2-18所示: 图 218 控件命名如下表表 217所示: 表 217 控件类型 控件名 UI名 DataGridView dgvResult 功能实现: 在这个窗体,里要显示还书时间,所以我们要取得用户的借书时间,借书的期限, 代码: int all = 0; object obj = db.Query("select quantity from Reader r,ReaderGrade g where r.grandID = g.grandID and readerID = " + ClassLibrary.SystemData.readerID); if (obj != null) { all = int.Parse(obj.ToString()); } 我们将借书时间与借书期限想加,便得到还书日期,最后绑定到dgvResult。 代码: string sql = "select c.borrowDate 借书时间,b.bookName 书名,t.typeName 类型,borrowDate+" + all + " 还书时间 from books b, BorrowBookc,BookType t where b.bookID=c.bookID and b.typeID=t.typeID and c.readerID=" + ClassLibrary.SystemData.readerID; ds = codb.GetDataSet(ds, sql, "ShowBorrow"); dgvResult.DataSource = ds.Tables["ShowBorrow"]; 帐户管理部分 首先我们在项目下添加一个文件夹,命名为:AccountManage。 frmUserInfo窗体 在AccountManage下添加一个窗体,命名为:frmUserInfo,这是系统的用户信息窗体,界面设计如下图2-19所示: 图 219 控件命名如下表表 218所示: 表 218 控件类型 控件名 UI名 textBox txtName 姓名 textBox txtAdds 地址 textbox txtTel 电话 Button btnUpdata 修改 Button btnCancel 取消 label lbInfo 显示文字 功能实现: 这个窗体主要是用来显示用户信息及实现一部分信息修改,在加载此窗体时,应将用户的一些基本信息显示出来。我们将会显示: 用户登陆名,地址,电话,用户角色,用户真实姓名,用户级别,能借多少书,此级别的还书期是多久。 此窗体分三个功能模块,信息显示,修改信息。 因为在用户登陆的时候,已经记录了用户的角色,用户名还有用户ID,所以在窗体名上显示的内容可以直接从全局文件里拿到: 代码: this.Text = "欢迎您!" + ClassLibrary.SystemData.roleName+ " " + ClassLibrary.SystemData.userName; 注意:记得导入命令空间using LibrarySystem.ClassLibrary; 然后我们根据用户是读者还是管理员,来判断应该去哪些表取相关数据。 New一个DataSet来存放读取的信息, 一个DataSet可以存多张表。 代码: DataSet ds = new DataSet(); if (SystemData.roleID == 3)则去ReaderGrade和Reader表取数据,并将其存入同一个DataSet里: 代码: ds = db.GetDataSet(ds, "select * from Reader where readerID=" + ClassLibrary.SystemData.readerID, "Reader"); ds = db.GetDataSet(ds, "select grandName,quantity,dateAmount from Reader read,ReaderGrade r where read.grandID=r.grandID and readerID=" + ClassLibrary.SystemData.readerID, "ReaderGrade"); 然后我们从Ds里拿出需要的数据,写入到UI控件里。 代码: txtName.Text = ds.Tables[0].Rows[0]["realityName"].ToString(); txtAdds.Text = ds.Tables[0].Rows[0]["address"].ToString(); txtTel.Text = ds.Tables[0].Rows[0]["phone"].ToString(); lbInfo.Text += "您的级别是:" + ds.Tables[1].Rows[0]["grandName"] + "\r\n"; lbInfo.Text += "您最多可以借:" + ds.Tables[1].Rows[0]["quantity"] + "本书\r\n"; lbInfo.Text += "您的还书期是:" + ds.Tables[1].Rows[0]["dateAmount"] + "天"; 同理,如果用户不是读者,那便去Manager取相应的数据,再放入UI控件: 代码: ds = db.GetDataSet(ds, "select * from Manager where managerID=" + ClassLibrary.SystemData.managreID, "Manager"); this.Width -= lbInfo.Width; txtName.Text = ds.Tables[0].Rows[0]["realityName"].ToString(); txtAdds.Text = ds.Tables[0].Rows[0]["address"].ToString(); txtTel.Text = ds.Tables[0].Rows[0]["phone"].ToString(); 我们要提一下,因为是管理员那么他就没有借书期限或用读者等级等这些信息,所以lbInfo里便没有信息,为了美观,我们将窗体多于的宽减去: 代码: this.Width -= lbInfo.Width; 当我们点击修改时,会从数据库里修改用户的地址或电话。当然我们同样要判断她是读者还是管理员,然后用ControlDB里的UpdataDB(string sql)方法来执行并判断是否执行成功。 当执行成功后,用MessageBox.show(“修改成功”)来提示用户。 代码: ControlDB db = new ControlDB(); string strUpdate=""; if (ClassLibrary .SystemData.roleID == 3) { strUpdate = "update Reader set address='" + txtAdds.Text + "',phone='" + txtTel.Text + "' where readerID=" + ClassLibrary .SystemData.readerID; if (db.UpdataDB(strUpdate) > 0) { MessageBox.Show("修改成功"); } } else { // 请同学们自己完成后边代码编写…… } frmChangePass窗体 界面设计如下图 220所示: 图 220 控件命名如下表 219所示: 表 219 控件类型 控件名 UI名 textBox txtReader 用户名 textBox txtOldPass 原始密码 textBox txtNewPass 新密码 textbox txtAgainPass 确认密码 Button btnChange 修改 Button btnCancel 取消 功能实现: 这个页面实现的时候,我们会从全局变量里拿到用户名和用户ID,当我们加载此窗体时,会在txtreaderName文本框里显示用户名。 代码: txtReader.Text = ClassLibrary.SystemData.userName; 当点击取消按钮时,会取消当前页面的操作: 代码: This.Close(); 一般来说,我们在修改用户密码时,都关系到一个很高的安全问题,这需要我们验证用户是否是正常的操作。 如果用户输入为空,则提示用户: 代码: if (txtNewPass.Text == "") { MessageBox.Show("请输入新密码!", "提示信息"); return; } if (txtAgainPass.Text == "") { MessageBox.Show("请输入确认密码!", "提示信息"); return; } if (txtNewPass.Text != txtAgainPass.Text) { MessageBox.Show("2次密码输入不匹配!请重新输入!", "提示信息"); return; } 从全局变量ClassLibrary.SystemData.roleID拿到用户相应的角色后,我们判断, 如果是用户则去查询Reader表; 代码: strSelect = "select * from Reader where readerName='" + txtReader.Text + "' and readerPass = '" + txtOldPass.Text + "'"; 如果是管理员表则查询Manager表: 代码: strSelect = "select * from Manager where manageName='" + txtReader.Text + "' and managePass = '" + txtOldPass.Text + "'"; 用ControlDB类的Query(string sql)方法执行后,如果执行结果不正确,则提示用户,并return: 代码: if (db.Query(strSelect) == null) { MessageBox.Show("密码输入错误!请重新输入!", "提示信息"); return; } 从以上,我们都是对用户的安全进行验证,当所以都通过后,则进行更改密码的操作。 同理,先断是读者还是管理员,再用ControlDB类的Updata方法来实现。 代码: string strUpdate = ""; if (ClassLibrary.SystemData.roleID == 2) { strUpdate = "update Reader set readerPass = '" + txtNewPass.Text + "' where readerID= " + ClassLibrary.SystemData.readerID; } else { strUpdate = "update Manager set managePass = '" + txtNewPass.Text + "' where managerID= " + ClassLibrary.SystemData.managreID; } db.UpdataDB(strUpdate); 到此,我们便完成了用户密码修改的操作。 退出系统 功能实现: 双击exitToolStripMenuItem注册Click事件,用Close()方法,实现关闭功能。 � � 用户 书籍系统 登录� 成功 失败 读者 判断 书籍管理员 管理员 读者 查询所借书籍 查询可借书籍 个人信息查询 借书操作 还书操作 查询读者信息 查询书籍信息 书籍录入 密码修改 个人信息查询 密码修改 系统管理员 系统管理员 密码修改 用户管理 统计 热门书籍 书籍补充 书籍损坏
本文档为【图书管理系统图书管理系统文档】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_974814
暂无简介~
格式:doc
大小:397KB
软件:Word
页数:43
分类:互联网
上传时间:2018-09-10
浏览量:40