当前位置: 首页 > news >正文

做网站每天任务及实训过程铜仁做网站

做网站每天任务及实训过程,铜仁做网站,什么信息发布型网站,aspcms开源企业网站建设系统本项目是要开发一个图书馆管理系统#xff0c;通过这个系统处理常见的图书馆业务。这个系统主要功能是#xff1a;#xff08;1#xff09;有客户端#xff08;借阅者使用#xff09;和管理端#xff08;图书馆管理员和系统管理员使用#xff09;。#xff08;2#…本项目是要开发一个图书馆管理系统通过这个系统处理常见的图书馆业务。这个系统主要功能是1有客户端借阅者使用和管理端图书馆管理员和系统管理员使用。2借阅者可以对于图书馆里面存在的图书进行借阅图书、归还图书等基本操作。3借阅者可以对于图书馆里面的图书的书号、种类、书名关键字等信息进行查询。4图书管理员能够查看借阅者的借阅图书、归还图书等的记录。5图书管理员能够对图书信息进行查看、增加、修改、删除功能。6图书管理员能够对读者信息进行查看、增加、修改、删除功能。7借阅者还可以在系统提供的电子资源进行浏览网络书籍。8客户端和管理端用户都可以进行公告的发布或留言的发布以及查看动态等操作。 资源附在文章末尾。 第1章 概 述 1.1 项目的目的和意义 1.1.1本课题研究背景 一直以来人们使用传统的人工方式管理图书馆的日常工作对于图书馆的借书和还书过程想必大家都已很熟悉。在计算机尚未在图书管理系统广泛使用之前借书和还书过程主要依靠手工。一个最典型的手工处理还书过程就是读者将要借的书和借阅证交给工作人员工作人员将每本书上附带的描述书的信息的卡片和读者的借阅证放在一个小格栏里并在借阅证和每本书贴的借阅条上填写借阅信息。这样借书过程就完成了。还书时读者将要还的书交给工作人员工作人员根据图书信息找到相应的书卡和借阅证并填好相应的还书信息这样还书过程就完成了。随着近年来信息技术及计算机网络技术的不断发展, 图书馆也先从传统的图书馆发展到自动化图书馆再发展到今天的数字图书馆这些变化使得图书馆的形象越来越现代化人们查找资料也更加方便。对于一些小图书馆和一些图书室来说由于工作人员比较少长期以来作为图书馆的主要工作—图书借阅一直未能很好地开展。在平常的图书借阅工作中, 由于大部分读者不熟悉图书馆藏书且对图书排架分类的不了解往往花费很长时间才能找到其所需的书。为提高管理效率更好地为读者服务利用已有的条件使图书查询和借阅变得更加方便快捷从而使图书室的工作效率得到明显提高。 基于这此问题有必要建立一个图书管理系统使图书管理工作规范化系统化程序化避免图书管理的随意性提高信息处理的速度和准确性能够及时、准确、有效的进行查询和修改图书情况等图书管理操作。 1.1.2本课题目的和意义 随着社会的进步信息技术的广泛应用数字化管理的优势日趋显著。针对中小型图书馆或图书室管理落后的情况设计实现一个图书信息管理系统通过与计算机的结合使用对中小型图书馆或图书室的各种图书信息进行管理可以给管理员和用户带来以下不同的方便检索迅速、查找方便、可靠性高、存储量大、保密性好、寿命长、成本低等。这些优点能够极大地提高工作效率也是图书馆等部门管理科学化、正规化的重要标志之一。而且计算机管理的成本不断降低。因此开发一套这样的中小型图书管理软件已经很有必要并且实现研究服务于实践的原则。 图书馆规模的不断扩大导致图书数量也相应的增加有关图书的各种信息量也成倍增加面对着庞大的信息量传统的人工方式管理会导致图书馆管理上的混乱人力与物力过多浪费图书馆管理费用的增加从而使图书馆的负担过重影响整个图书馆的运作和控制管理因此必须制定一套合理、有效规范和实用的图书管理系统对图书资料进行集中统一的管理。图书管理系统对于现代图书馆而言是能否发挥其教学研究的作用的自关重要的技术平台对于在校学生和管理员来说是能否方便快速获取信息的关键。所以图书管理系统应该能够为用户提供充足的信息和快捷方便的操作手段。 本系统的宗旨是提高图书管理工作的效率减少相关人员的工作量使图书管理工作真正做到科学、合理的规划系统、高效的实施。目标如下 1减少人力成本和管理费用 2提高信息的准确性和信息的安全 3改进管理和服务 4良好的人机交互界面操作简单 1.2 技术开发基础 1.2.1 面向对象技术 面向对象技术可以用于软件的设计、开发、维护方面。面向对象技术的原理就是仿照人类解决问题的思维以及方式,将出现的问题划分解决。问题的复杂程度无论大小均被面向对象的思维中作为对象。软件无论任何规格都可以转化为对象的处理,这是是因为对象是数据以及由此产生的操作所构成的独立单元的统称。以对象为中心也是面向对象的中心思想。面向对象技术具有以下特点 (1)在处理问题的时候把客观事物看作一个个对象无疑接近于人的思维,对象作为实际系统的基本单位,基于面向对象的开发着重的就是问题域与软件程序之间的直接映射关系。在整个研发系统中,组构模型系统以及最终软件中始终采用同一方法,将实际系统抽象表示为对象,并且构成了系统的基本组成单位。 (2)软件可以方便地修改、扩展、维护依赖于信息的封装。所谓封装就是指在面向对象的技术中对象的基本属性以及服务功能结合为一个独立的信息体,其内部信息无法被外部得知。正是由于封装使其自身的修改独立于整体,所以应用其开发的软件才会便于更改维护。除此之外,面向对象的开发也推崇软件开发中信息与数据的独立化和抽象化。 (3)类是具有继承关系的,它可以减少系统的构成过程以及文档。类就是具有相同属性与服务对象的集合,面向对象技术将其归为一类。类是对象的抽象化是每个实例对象的集合。类按照程度的不同分为一般和特殊,特殊类会承接一般类所具有的服务。这种类的处理方式的实现也是面向对象被人们接受的原因之一。 (4)支持再利用,扩充了可再利用的范围。面向对象的应用很广,它可以应用于软件开发的整个周期,包含了分析以及编码。而目,该方法不仅支持软件的再利用,即便是其设计模型也可以这样处理,而且它还可以实现网络中不同节点之间资源的交换利用。 (5)支持难度较高的软件的开发。现在的软件系统中常见的并发、层次等现象也是面向对象所支持的。复杂的系统的层次结构多由很多子系统构成. 分布式对象技术已经成为了构建服务框架以及软件的核心技术,在大型应用系统(分布式)开发中更具有强效的作用。这也发展成为了三种最具代表性的技术:微软的COM/DCOM技术、Sun公司的Java技术和OMG的COBRA技术。 (6)支持开放式系统的开发。在开发复杂系统之时,面向对象的开发,由于通过不同的应用来进行软件的构成,使其具有更大的抗力,再加上软件生命周期之内都有系统集成的穿插,大幅度降低了开发复杂系统的风险。 1.2.2 C#.NET开发语言/框架 .NET是一个微软的技术平台致力于敏捷、快速开发和跨平台可以用于软件开发和网站开发。.NET Framework 4.0组件包含了.NET平台的基础委库以运行认境开发人员在细写程序时可以自接调用微软到装好的类。C#是.NET平台中使用最为广泛的一种开发语言基于CIL规范、用C#8写的程序或是类库在VB、F#或是任何一种基于.NET及CIL规范的编程语言中都可以调用、继承。开发环境、开发平台和开发语言三者之间相辅相成完成应用程序的编写。 .Net Framework是Microsoft为开发应用程序而创建的一个具有革命意义的平台。这个定义是非常广义的首先这句话没有说是在Windows操作系统上开发的应用程序言外之意.Net Framework平台不仅仅在Windows操作系统和Windows Moblie操作系统上运行而且可以在Linux、macOS上运行。 所以.Net Framework就是一个开发应用程序的平台。还有这个定义并未指定开发程序的类型比如桌面应用程序、Windows StoreUWP应用程序、云/Web应用程序、Web API和其他各种类型的应用程序。 .Net Framework还可以用于各种语言进行开发编程不仅仅包含C#还有F#、C、JavaScript、VB以及COBOL。所以.Net Framework就是可以在多种操作平台上运行可以开发多种类型应用程序、可以使用多种开发语言开发应用程序的一个平台。简而言之就是开头的那句话。 1.2.3 SQL Server数据库管理系统 SQL是英文名称Structured Query Language的缩写,翻译过来就是结构化查询语言。通常对实践操作中与其相关的具体作用分析可以得出,人们可以理解成在各种不同的数据库之间建立具体联系。美国国家标准协会介于数据库管理系统,也明确地规定SQL是最标准的语言。通过使用SQL语句实现数据的更新、提取,对海量数据进行整理。在当今时代,SQL使用广泛,大部分的关系型数据库管理系统中使用的语言中都少不了它的身影,不少数据库甚至通过对SQL语句的深入开发研究,拓展出新功能,可以借助于SQL命令,有利于实现对数据库操作的专业性。在对告警数据分析处理中,不少管理信息系统都引进了Microsoft公司的SQL Server数据库系统,通过对数据库的分布存储和访问,成功实现高级别的数据管理工作,有利于降低系统的负担,系统的稳定性会有一定程度的增强。 优点:第一,它具有易用性、适合分布式组织的可伸缩性等特性较强;同时SQL Server数据库用于决策支持的数据库功能具有明显优势;具有与其他服务器软件紧密关联的特性,它的性价比也比较高。第二,在数据挂目录与分析中,它的便捷性、灵活性都很强,可以实现各种单位在快速变化的环境中对数据应用分析的便捷,在激烈的外部竞争中取得优势。这一优势在数据管理和分析中,对于原始数据转化为商业智能信息具有非常重要的意义。第三,它可以快速开发新一代企业级商业应用程序,因此为企业增强核心竞争力,在激烈的市场竞争中处于不败地位。第四,它可以保持一些重要的基准测试,对其可伸缩性和速度奖进行记录,为Internet上和防火墙外进行查询提供了极大的便利。 缺点:(1)SQL Server数据库的开放性不够强,只能在windows上运行,而windows这一平台的可靠性和安全性都是很有限的,难以实现在运行中久经考验或者在处理大数据库时有所不便。(2)SQL Server在处理日益增多用户数和数据时具有局限性,面对繁杂庞大的数据留,SOL Server在安全性方面并没有获得任何安全证书,缺少保障:加之用户较多,SQL Server数据库在处理时会面临性能上当面临多用户时性能不佳。(3)客户端支持及应用模式不够多,一般只支持C/S模式,它的涵盖面不够广,用途不够广。在以上SQL Server数据库的三个缺点中,笔者认为最重要的就是其安全性难以保障,这阻碍了其对各项功能的利用。 1.2.4 Client/Server开发模式 随着计算机网络技术的成熟和应用普及特别是局域网的发展、PC机的出现越来越多的用户和企业开始使用计算机管理一些事务。PC机的资源没有大型、中型甚至小型主机丰富但将多台PC机联成网必然会增加资源含量各个用户都在网络上来共享所有资源。根据客户/服务器Client/Server简记为C/S体系结构的概念至少用两台计算机来分别充当客户机和服务器角色。客户端可以是X86体系的风机或RISC体系的工作站等而服务器端硬件一般比较高档比如高档PC服务器或SUN专用服务器操作系统也比较高档比如 Windows NT和 Unix。 服务器-客户机即Client-Server(C/S)结构。C/S结构通常采取两层结构。服务器负责数据的管理客户机负责完成与用户的交互任务。 客户机通过局域网与服务器相连接受用户的请求并通过网络向服务器提出请求对数据库进行操作。服务器接受客户机的请求将数据提交给客户机客户机将数据进行计算并将结果呈现给用户。服务器还要提供完善安全保护及对数据完整性的处理等操作并允许多个客户机同时访问服务器这就对服务器的硬件处理数据能力提出了很高的要求。 在C/S结构中应用程序分为两部分:服务器部分和客户机部分。服务器部分是多个用户共享的信息与功能执行后台服务如控制共享数据库的操作等;客户机部分为用户所专有负责执行前台功能在出错提示、在线帮助等方面都有强大的功能并且可以在子程序间自由切换。 C/S结构在技术上已经很成熟它的主要特点是交互性强、具有安全的存取模式、响应速度快、利于处理大量数据。但是C/S结构缺少通用性系统维护、升级需要重新设计和开发增加了维护和管理的难度进一步的数据拓展困难较多所以C/S结构只限于小型的局域网 。 1.2.5开发平台及第三方插件 本项目使用的开发平台是Visual Studio第三方界面库Cskin和DevExpress。 本项目基于Microsoft Visual Studio 2022开发环境该软件集成了.NET程序的便捷功能可编程性强。它可以利用使用者所用的语言(如C、C、C#等)进行编程也可以和.NET平台协同开发程序具有强大的功能和优势:该软件内部提供了诸多实用的功能如代码片段、代码复用等能帮助程序员快速开发应用程序;通过图形化模型的设计集成多种组建和控件便于普通开发者简单快速完成项目开发;集成了多种调试工具方便程序员快速完成代码调试:具有丰富的扩展机制用户可以根据自己的需要在此开发软件上拓展更多功能。 .NET平台c# 语言开发很方便支持拖拉拽生成界面程序员只需要专注自己的业务逻辑即可大大节省了开发时间。但是呢原生系统的界面比较丑陋不太友好需要再美化一下。.net平台因为是封闭的缺乏生态系统所以其上的UI库很少CSkin是我在CSDN社区寻到的一个广泛被推荐的第三方控件。CSkin界面库是完全免费的可以任意使用并且代码中无任何限制。 但DevExpress界面库更加强大支持Edit编辑且自提供编辑器进行一定程度上的控件外观设计。 1.2.6三层架构技术 三层架构来源于后端开发的一种分层思想。三层架构3-tier architecture通常意义上的三层架构就是将整个业务应用划分为界面层User Interface layer、业务逻辑层Business Logic Layer、数据访问层Data access layer。 区分层次的目的即为了“高内聚低耦合”的思想。在软件体系架构设计中分层式结构是最常见也是最重要的一种结构。微软推荐的分层式结构一般分为三层从下至上分别为数据访问层、业务逻辑层又或称为领域层、表示层。 1.表示层主要对用户的请求接受以及数据的返回为客户端提供应用程序的访问。 2.业务逻辑层主要负责对数据层的操作。也就是说把一些数据层的操作进行组合。 3.数据访问层主要看数据层里面有没有包含逻辑处理实际上它的各个函数主要完成各个对数据文件的操作。而不必管其他操作。 1.3 系统基本功能 本项目是要开发一个图书馆管理系统通过这个系统处理常见的图书馆业务。这个系统主要功能是1有客户端借阅者使用和管理端图书馆管理员和系统管理员使用。2借阅者可以对于图书馆里面存在的图书进行借阅图书、归还图书等基本操作。3借阅者可以对于图书馆里面的图书的书号、种类、书名关键字等信息进行查询。4图书管理员能够查看借阅者的借阅图书、归还图书等的记录。5图书管理员能够对图书信息进行查看、增加、修改、删除功能。6图书管理员能够对读者信息进行查看、增加、修改、删除功能。7借阅者还可以在系统提供的电子资源进行浏览网络书籍。8客户端和管理端用户都可以进行公告的发布或留言的发布以及查看动态等操作。 第2章 系统设计 2.1系统功能模块设计 图书馆管理系统可以进行用户的注册登录数据的统计管理员可以发布系统公告以及对图书、书类、普通用户的信息进行添加、修改、删除、查询等工作读者可以进行借阅与归还、留言建议等操作。 图书馆信息管理系统是图书馆系统中不可或缺的一个子系统它涉及到图书、书类、人员、时间、罚金等信息的结合。图书馆信息系统包括七个小模块 1.登录注册注册模块主要是为用户提供注册登录的机会并存储个人数据保护个人信息用户提供相应信息即可注册账户。登录模块需要用户提供用户名和密码进行登录的操作并匹配权限与账户密码。 2.找回密码找回密码模块需要用户提供账号、注册时使用的手机号并使用支持扫描QRCode二维码的应用进行扫描获取本次验证码方可从数据库中找回密码。 3.借阅图书。借阅者登录以后选择借阅图书进入在这借阅者可以输入想要借的图书的名字图书馆管理系统会去进入查询书籍信息检测是否有该图书存在和进入预借图书功能检测用户是否预借了图书并且查询借阅者的借书数量是否超过了限制。如果图书馆有该书用户借书数量没有超过限制并且准备借这本图书系统会记录用户的借书时间和借阅图书的信息并且显示借书的最长时间给用户。 4.归还图书。借阅者登录以后选择归还图书进入在这借阅者可以归还之前在图书馆里面借阅的图书通过图书馆管理系统检测图书没有过期的书可以归还过期的图书借阅会计算罚款信息然后归还 5.用户管理。该模块使管理员可以对已注册的读者用户进行信息的查询、注销、修改并为读者注册账户。读者用户可以查询自身非密码的所有用户注册信息并可以修改自身非管理员锁定数据信息外的信息即修改密码。 6.图书管理。该模块为管理员提供了对图书的录入、删除、查询、修改以及图书种类信息的增、删、查、改的权限。 7.留言动态。本模块是系统管理员发布系统公告的渠道提交留言和建议使管理员了解用户反馈查看系统公告、了解其他用户体验等。 8.拓展设计。除留言功能以外拓展设计还包括了网络数字资源、报表与数据统计等 图书馆信息管理系统功能模块如图2-1系统功能模块图所示。 图2-1 系统功能模块图 2.2 数据库设计 通过使用数据库可以对我们所需要的信息进行存储。从而进行添加和修改删除查询等操作的实现。 根据上文要求分析图书馆信息管理系统数据库(Stark图书馆管理系统)中包括读者信息”tblReader”、管理员信息”tblAdmin”、图书信息”tblBooks”、图书类型”tblType”、借阅信息”tblBorrow”、留言信息”tblMsg”六个数据表。表的结构、表字段的数据类型及相关说明如下 1.读者信息表 该表主要存放读者用户的相关信息包括读者用户名密码读者编号读者姓名读者性别注册日期电话号码所属单位家庭住址可借阅书籍最大数量等其结构如表2-1读者信息表所示 表2-1 读者信息表 列名 说明 数据类型 约束 Uid 用户名 nchar(20) 主键 Pwd 密码 nchar(20) 非空 Rno 读者编号 nchar(20) 主键 Name 读者姓名 ncahr(50) 非空 Sex 读者性别 ncahr(10) 非空 Date 注册日期 ncahr(20) 非空 Tel 电话号码 nchar(11) 非空 Dept 所属单位 nvarchar(MAX) 非空 Address 家庭住址 nvarchar(MAX) 非空 Number 可借阅书籍 int 非空 2.管理员信息表 该表用于存放图书管理员的信息包括用户名及密码管理员姓名管理员联系方式用户权限等其结构如表2-2管理员信息表所示。 表2-2 管理员信息表 列名 说明 数据类型 约束 Uid 用户名 nchar(20) 主键 Pwd 密码 nchar(20) 非空 Name 姓名 ncahr(50) 非空 Tel 电话 ncahr(11) 非空 Limit 权限 nchar(10) 非空 3.图书信息表表 该表用于存放图书信息包括书号书名类别出版社作者价格登记时间借阅状态等其结构如表2-3图书信息表所示。 表2-3 图书信息表 列名 说明 数据类型 约束 Bno 书号 nchar(20) 主键 Title 书名 nchar(50) 非空 Tno 类别编号 ncahr(5) 主键 Publisher 出版社 nchar(50) 非空 Author 作者 nchar(50) 非空 Price 价格 int 非空 Date 登记日期 nchar(20) 非空 State 借阅状态 nchar(10) 非空 4.图书类型表 该表用于存放图书类型的基本信息包括类别编号类别该类别图书最大借阅天数逾期每日罚金等其结构如表2-4图书类型表所示。 表2-4 图书类型表 列名 说明 数据类型 约束 Tno 类别编号 nchar(5) 主键 Type 类名 nchar(50) 非空 Day 最大借阅天数 int 非空 Fine 逾期每日罚金 int 非空 5.借阅信息表 该表用于存放借阅的相关信息包括所借阅书籍的编号借阅人编号借阅日期和归还日期逾期天数总罚金归还状态等其结构如表2-5借阅信息表所示。 表2-5 借阅信息表 列名 说明 数据类型 约束 Bno 借阅书号 nchar(20) 主键 Rno 借阅人编号 nchar(20) 主键 Bdate 借阅日期 nchar(20) 非空 Rdate 归还日期 nchar(20) 可空 Exday 逾期天数 int 非空 Fine 罚款 int 非空 State 归还状态 nchar(10) 非空 6.留言信息表 该表用于存放留言人、留言内容和留言日期结构如表2-6留言信息表所示。 表2-6 留言信息表 列名 说明 数据类型 约束 Uid 留言人标识 nchar(20) 主键 Msg 留言内容 nvarchar(MAX) 非空 Date 留言时间 nchar(50) 非空 第3章 系统的详细设计及实现 3.1 公共类 本系统大多模块都需要访问数据库因此在开发时编写了一些访问数据库的方法如返回数据集的公共查询方法执行数据操作的公共方法并把它们放在了一个公共的类(SQLHelper)中然后在各模块中调用这些方法来实现对数据库的访问。 同样在实现访问时需要记录一些基本信息因此也需要使用到一些公共的静态变量本系统在开发时把这些变量放在了Model类库中根据各数据表建立了各个类来存储静态变量如类AdminInfo、类ReaderInfo、类BooksInfo、类BooksType、类BorrowInfo、类MsgInfo等。 编写SQLHelper公共类及公共方法 为系统添加一个”SQLHelper”的公共类用于存放访问数据库的公共方法为SQLHelper类声明数据库连接字符串。代码如下: Static string constr  serverLAPTOP-B3JDLUIF\\SQLEXPRESS; uidsa;pwd2396573637;databaseStark图书馆管理系统;; 1.链接数据库方法Link() 数据操作的前提是链接并打开数据库Link()可以将这个操作封装以便使用避免了程序不断的链接打开时造成的代码冗余。代码如下: static SqlConnection conn null; private static void Link() { conn new SqlConnetion(constr); conn.open(); } 2.查询方法Query(string sql) 公共数据操作方法Query执行SQL查询(SELECT)语句返回DataTable。需要通过Link()方法链接打开设置的数据库然后通过适配器SqlDataAdpter将查询的数据填充到数据集DataSet关闭数据库最后以数据表DataTable的形式返回。具体代码如下: public static DataTable Query(string sql) { Link(); SqlDataAdapter da new SqlDataAdapter(sql, conn); DataSet ds new DataSet(); da.Fill(ds); conn.Close(); return ds.Tables[0]; } 3.增、删、改数据操作方法NoQuery(string sql) 公共数据操作方法NoQuery执行SQL非查询(INSERT、UPDATE、DELECT)语句返回受影响的行数。首先链接并打开数据库然后创建SqlCommand变量使用ExcuteNonQuery()方法执行SQL命令返回操作影响到的行数。代码如下: public static int NoQuery(string sql) { Link(); SqlCommand cmd new SqlCommand(sql, conn); int rows cmd.ExecuteNonQuery(); conn.Close(); return rows; } 3.2系统登录、注册 登录是每一个成功的项目中不可或缺的模块好的登录模块可以保证系统的可靠性和安全性。首先为”图书馆信息管理系统”制作了一个简单的登录模块该模块可进入用户注册界面注册成功后进行登录如果忘记密码可以进行找回密码登录成功后会根据权限进入各自的系统主窗体(主页面)。 3.2.1登录界面设计 新建一个Windows应用程序命名为”frmLogin”更改继承关系(父类由System.Windows.Forms.Form改为CCWin.Skin_Color)使用SkinLabel、TextBox、SkinButton控件等设计登录界面。 根据设计要求的一致性原则本套登录界面字体一致选择微软雅黑颜色为黑白二色、具体取决于字体的背景对比色。可点击的模块选择使用按钮、下划线标签控件。根据准确性原则使用一致的标记、明确信息的含义使用户不需要参考其它信息源。 点击【管理申请】和【读者注册】分别进入两类用户注册界面。点击【忘记密码】会进入找回密码的界面。点击【登录】则根据TextBox的文本属性text以及访问数据库进行数据匹配然后进入主界面。具体设计如图3-1登录界面所示。 图3-1登录界面 3.2.2登录模块代码实现 在如图3-1所示的登录界面中【登录】按钮用于验证输入的用户名和用户密码以及用户权限是否匹配若正确则进入系统主页面否则弹出相应错误信息并返回重新输入信息。 1.UI代码 首先系统会根据TextBox.Text的值判断输入的用户信息是否为空有任何一项为空的话就给予提示例如不输入用户名会触发以下提示 if (txtUid.Text string.Empty) { MessageBox.Show(用户名不可为空); return; } 否则调用BLL层AdminManger或ReaderManger类的State()方法检测是否存在该用户不存在则有以下提示 if (AdminManger.State(admin)) { MessageBox.Show(用户不存在,请尝试注册用户或更换权限); return; } 没有进入上面的if入口代表存在用户。存在的话会调用BLL.Manger.Get()方法获取用户全部信息然后根据用户类的Pwd属性匹配密码做出进一步判断 if(txtPwd.Text.Trim()! AdminManger.Get(admin).Pwd.Trim()) { MessageBox.Show(密码错误,请尝试找回密码或更换权限); return; } 层层异常排除之后进入主界面如果选择关闭界面的话会导致进程结束后续代码执行不了所以选择通过this.Hide()隐藏登陆界面然后打开用户窗体这里执行ShowDialog()方法不可对该进程之前隐藏的界面进行交互。 this.Hide(); frmAdmin frmAdmin new frmAdmin(admin); frmAdmin.ShowDialog(); 如果选择的权限不是管理员而是读者用户的话上述操作同理。 if (skinComboBox1.SelectedIndex 1) { ReaderInfo reader new ReaderInfo(); reader.Uid txtUid.Text.Trim(); } 2.BLL层代码 通过调用DAL层代码State()方法执行查询操作如果查询到的数据表的行数为0代表没有用户返回true无法登录。否则返回false在数据库中找到了该用户可以进行下一步的密码判断。密码判断是根据用户的账号信息这一唯一标识来查询所有信息并返回一个用户类然后将获取到的用户信息的密码这一信息与输入的密码进行比较。其中注意到查询结果多用字符串表示但实体类的个别字段属性为其它类型需要进行强制类型转换以确保数据类型准确查询结果转化完整。 由于查询结果是DataTable类型的数据该类型有属性Rows.Count。查询结果的行数就是由该属性确定的。具体实现方法如下 public static bool State(AdminInfo admin) { return (AdminService.Query(admin).Rows.Count 0); } public static bool State(ReaderInfo reader) { return (ReaderService.Query(reader).Rows.Count 0); } 而将数据转化为Model 层的实体信息会更容易判断由于读者信息过多且二者方法一致避免代码冗余下面只陈述管理员的Get()方法该方法首先会生成一个虚拟用户 AdminInfo adm new AdminInfo(); 通过使用Query()查询用户所有信息。 adm.Uid AdminService.Query(admin).Rows[0][Uid].ToString().Trim(); 由于索引条件是主键主键设计时保证了唯一性。所以第零行的数据Rows[0]就是该用户所有信息。再根据列名一一获取用户的所有信息使用ToString()方法将信息转化为字符串经过去空处理Trim(),将信息存储到新建的用户信息中 adm.Pwd AdminService.Query(admin).Rows[0][Pwd].ToString().Trim(); adm.Name AdminService.Query(admin).Rows[0][Name].ToString().Trim(); adm.Tel AdminService.Query(admin).Rows[0][Tel].ToString().Trim(); adm.Limit AdminService.Query(admin).Rows[0][Limit].ToString().Trim(); 最后将用户类型的数据作为返回值返回给引用处从而时调用该方法的用户得到具体的信息。例如 realUserManger.Get(realUser)。realUser必须具有非null的Uid属性。 3.DAL层代码 调用SQLHelper工具类的查询方法将用户信息传入只要用户有账号信息即可查询其它所有信息。两类用户查询的SQL语句分别为 string sql string.Format(select * from tblAdmin where Uid{0},a.Uid); string sql string.Format(select * from tblReader where Uid{0},r.Uid); 执行操作的语句是(返回数据表) return SQLHelper.Query(sql); 4.Model层代码 管理员类包括账户、密码、姓名、电话、权限信息。 public class AdminInfo { private string uid; private string pwd; private string name; private string tel; private string limit; public string Uid { get uid; set uid value; } public string Pwd { get pwd; set pwd value; } public string Name { get name; set name value; } public string Tel { get tel; set tel value; } public string Limit { get limit; set limit value; } } 读者类包括信息如注释所示。 public class ReaderInfo { private string uid;//账号 private string pwd;//密码 private string rno;//读者编号 private string name;//姓名 private string sex;//性别 private DateTime date;//办证日期 private string tel;//电话 private string dept;//所属单位 private string address;//家庭住址 private int number;//可借阅书籍 public string Uid { get uid; set uid value; } public string Pwd { get pwd; set pwd value; } public string Rno { get rno; set rno value; } public string Name { get name; set name value; } public string Sex { get sex; set sex value; } public DateTime Date { get date; set date value; } public string Tel { get tel; set tel value; } public string Dept { get dept; set dept value; } public string Address { get address; set address value; } public int Number { get number; set number value; } } 如果用户填写信息无误后则进入系统主界面、系统登录界面隐藏。如果单击登录界面的【取消】按钮则关闭登录界面退出系统其单击事件主要代码是 Application.Exit();//this.Close();同样有效 3.2.3注册界面设计 在系统登录界面单击【读者注册】/【管理申请】进入两类用户的注册界面。所以需要提前添加两个注册的窗体”frmRegister1””frmRegister2”给读者和管理员使用。两个窗体均包括TextBox、SkinLable、SkinButton、Panel、RadioButton等控件。 坚持以用户体验为中心设计原则界面直观、简洁操作方便快捷用户对界面上的功能一目了然不需要经过任何培训就可以使用本应用系统。两个界面最终设计为如图3-2注册界面所示。 图3-2 注册界面 3.2.3注册模块代码实现 点击确认按钮时首先判断输入信息是否完整非空然后通过BLL层逻辑功能进行注册在注册时会对用户输入信息进行判断看是否存在用户存在的话不予注册。不存在的话调用再DAL层增加一条用户记录。 1.UI层代码 首先根据TextBox.Text属性值对信息的完整性进行判断 if (txtName.Text||txtPwd.Text||txtTel.Text||txtUid.Text) MessageBox.Show(信息不完整请填写完整后重试); 如果信息完整使用TextBox的Text属性继续下一步的信息填充注意填充时用字符串的内置方法Trim()方法将两端空字符去除。默认注册管理时的权限等级为“管理员”。 AdminInfo admin new AdminInfo(); admin.Limit 管理员; admin.UidtxtUid.Text.Trim(); admin.NametxtName.Text.Trim(); admin.TeltxtTel.Text.Trim(); admin.Pwd txtPwd.Text.Trim(); 这时候如果填充的信息中账号信息经AdminManger.Register(AdminInfo)方法的检测该账号已被使用则提示用户账户存在无法注册 if(AdminManger.Register(admin)0) { MessageBox.Show(用户存在无法注册); return; } 否则的话提示注册成功。关闭注册窗体关闭该线程。 MessageBox.Show(注册成功); this.Close(); 普通读者用户注册时性别信息用到了RidioButton控件与管理员注册有细微差别。其中需要使用Checked属性判断哪个选项被选中并获取其上Text文本信息。进而判断用户注册时是否选则了性别的有效信息。 string sex string.Empty; if (rbMale.Checked) sex 男; if (rbFemale.Checked) sex 女; if (sex string.Empty) { MessageBox.Show(请选择性别); return; } 读者的注册日期信息需要使用System.DateTime这一结构体类型的Now成员属性获取当前计算机时间。 reader.Date DateTime.Now; 2.BLL层代码 通过调用BLL层的Register()方法进行注册在此方法内需要使用State()方法进行状态判断看是否已经存在过该用户。其中又使用到了登录时的存在状态方法bool State(User)。 public static int Register(ReaderInfo reader) { if (!State(reader))  return 0; //代表存在用户不能注册 return ReaderService.Insert(reader); } 3.DAL层代码 该层代码调用SQLHelper工具类的非查询方法noQuery()进行添加操作将用户的全部信息添加到数据库即注册功能。 两类用户注册时的SQL语句分别为 string sql string.Format(insert into tblAdmin values({0},{1},{2},{3}), a.Uid, a.Pwd, a.Name, a.Tel); string sql string.Format(insert into tblReader values({0},{1},{2},{3},{4},{5},{6},{7},{8},{9}),r.Rno, r.Name, r.Sex, r.Date.ToString(), r.Tel, r.Dept, r.Address, r.Number, r.Uid, r.Pwd); 执行SQL语句时调用SQLHelper工具类的非查询方法NoQuery()。 return SQLHelper.NoQuery(sql); 4.Model层代码 Model层代码同登录界面的Model层是两大用户类AdminInfo和ReaderInfo。 3.2.5找回密码功能设计 在登录界面点击“找回密码”进入提前建好的frmForgetpwd窗体进行找回密码的操作。窗体包括pictureBox、TextBox、Label、Button等控件其中按照习惯将取消按钮的背景色设置为红色。 考虑到密码信息安全等级比较高找回密码的操作需要验证更多的信息。因此加入了BarCodeControl控件使用二维码获取验证码功能。找回密码功能一共有两个按钮事件。 取消按钮关闭本窗体返回登录界面。确认按钮在界面加载时进行信息提示如何操作并生成六位数字字符串作为本次找回密码的验证码并生成一个可扫描二维码例如通过微信、支付宝、浏览器等扫描工具可以获取六位数字字符串。首先判断输入信息是否完整然后判断账户手机号信息是否匹配最后判断验证码是否与本次页面加载时生成的二维码一致若一致则会弹出账户的密码用户应当记下密码用于登录。界面如图3-3找回密码界面。 图3-3 找回密码界面 取消按钮代码如下: this.Close();//关闭该线程返回主线程。 确认功能分析: 在界面加载时进行信息提示具体操作流程。 MessageBox.Show(请用微信、支付宝、浏览器扫码获取本次验证码验证码可用于找回账户密码); 生成六位数字字符串作为本次找回密码的验证码并生成一个可扫描二维码例如通过微信、支付宝、浏览器等扫描工具可以获取六位数字字符串。通过循环生成六位数字转化为字符串存储在变量ans中。 Random r new Random();//随机种子 string ansstring.Empty;//验证码答案 for (int i 0; i txtStrCode.MaxLength; i) { int randr.Next(9); string item rand.ToString().Trim(); ans item; } qrCode.Text 请记住你的验证码: ans;//将随机答案放入二维码中 执行代码时需要先对文本信息的完整性进行判断。在这里可以使用TextBox.Text与String.Empty进行比较当然也可以使用TextBox.Text.Length与0进行比较。此处使用第一种实现方法。 if (txtUser.Text || txtTel.Text ) { MessageBox.Show(请输入账户信息); return; } if (txtStrCode.Text ) { MessageBox.Show(请扫描二维码后获取验证码信息填入文本框内); return; } 还需要对输入的用户信息进行存在性判断。使用的方法依旧是用户的State()方法 if (ReaderManger.State(reader) AdminManger.State(admin)) { MessageBox.Show(用户不存在,请检测用户名是否正确); return; } 最后通过输入验证码与ans的存储信息进行匹配判断正误。使用上文提到过的Get()方法根据账户信息获取电话信息与密码信息。 //判断验证码后的信息与输入文本框的字符串是否一致 if (txtStrCode.Text ! ans) { MessageBox.Show(验证码错误); TxtStrCode.Focus(); return; } string msg string.Empty; if (!ReaderManger.State(reader)txtTel.TextReaderManger.Get(reader).Tel) { msg ReaderManger.Get(reader).Pwd; } 最后通过信息弹窗给出密码 MessageBox.Show(msg); 3.3图书信息管理 图书信息管理系统最核心的功能就是对图书的各种信息进行管理。在此通过使用数据库和C#开发语言将图书的增删查改基本功能和一些异常情况处理进行设计实现。 3.3.1图书管理页面设计 新建一个窗体命名为frmAdmin。添加一个TabControl控件新增tabPage,并命名tabPage_Book。页面包括Button、ComboBox、TextBox、Label、DataGridView等控件 界面左边两个按钮的功能是导出图书信息(包括种类的详细信息)到Excel中查询按钮可以根据关键信息索引相关图书其它按钮是图书的增改删操作页面下方的DataGridView显示具体数据。页面如图3-4图书管理页面所示。 图3-4 图书管理页面 3.3.2图书管理代码实现 在如图3-4所示的图书管理页面中查询按钮用于根据comboBox1选项的方式以及txtMsg文本框内容查询指定的图书。删除图书时根据点击dgvBooks的单元格获取当前行的书号显示到txtInfo中删除该书号的书籍。录入图书和修改信息都将打开子窗体录入或修改信息注意修改时需要先点击单元格获取当前行书的信息传入子窗体。附导出Excel功能在3.7拓展功能设计给出。 1.查询功能 创建一个临时实例作为虚拟书籍无任何信息根据选择的方式赋予其对应的信息根据该信息进行查询返回数据结果。 (1)UI层 使用实体类BooksInfo创建一个不具有任何信息的虚拟书籍实例book BooksInfo book new BooksInfo(); 通过复合框的选项对虚拟书籍进行部分真实化使可以根据该部分真实信息访问数据库并查询到全部信息。不同方式使用不同的方法的功能使用switch...case语法实现。主要代码如下 switch (skinComboBox1.SelectedIndex) { case 0:  book.Bno txtMsg.Text.Trim();//当选择该项时赋予虚拟书籍书号 dgvBooks.DataSource BooksManger.QueryBybno(book);break; case 1:  book.Title txtMsg.Text.Trim();//当选择该项时赋予虚拟书籍书名 dgvBooks.DataSource BooksManger.QueryBytitle(book);break; case 2:  book.Tno txtMsg.Text.Trim();//当选择该项时赋予虚拟书籍种类号 dgvBooks.DataSource BooksManger.QueryBytno(book);break; } (2)BLL层 条件查询时以按书号、书名、书类分别调用了三个方法QueryBybno(BookInfo book)、QueryBytitle(BookInfo book)、 QueryBytno(BookInfo book)来返回查询结果。具体代码如下: BooksService.Query(book, WayIndex); 其中对应的WayIndex的012分别对应上述三种条件查询方式。 (3)DAL层 通过switch...case语句调用SQLHelper工具类的Query(sqlStr)方法在一段代码域内实现三种查询。具体代码如下; 方法声明为: public static DataTable Query(BooksInfo book,int method) 初始化sql语句为string sql select * from tblBooks 如果需要根据条件查询那么就可以根据条件判断进行不同的查询操作 三条sql语句分别是 sql string.Format(select * from tblBooks where Bno{0}, book.Bno); sql string.Format(select * from tblBooks where Tno{0}, book.Tno); sql string.Format(select * from tblBooks where Title like %{0}%, book.Title); 执行数据访问的具体操作为 return SQLHelper.Query(sql); 2.删除功能 选择数据表中需要删除的行对应书号信息会展示到文本框中在删除前会进行询问检查以免误删。删除成功后会重新查询数据库所有信息来刷新数据表、避免了数据不同步的情况。 DialogResult re MessageBox.Show(是否确认删除该书, 提示, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning); if (re DialogResult.Cancel) return; (1)UI层 获取当前点击单元格的行索引将改行索引的“书号”列的值Value转化为字符串在经过Trim()处理传给新建的book的Bno属性 int index dgvBooks.CurrentCell.RowIndex; book.Bno dgvBooks.Rows[index].Cells[Bno].Value.ToString().Trim(); 调用BooksManger.Delete方法删除数据表中的该图书。如果数据表中受影响行数大于0即是操作成功提示删除成功。将代码简写为: if (BooksManger.Delete(book) 0) MessageBox.Show(删除成功); 最后重新查询图书信息表来刷新数据 dgvBooks.DataSource BooksManger.Query(); (2)BLL层 删除操作核心方法是BLL层BookManger类库的Delete(BookInfo book)具体代码如下 public static int Delete(BooksInfo book) { return BooksService.Delete(book); } (3)DAL层 在此删除功能只许知晓书号这一唯一标识信息即可准确删除一条数据记录。直接执行SQL语句即可代码如下 public static int Delete(BooksInfo book) { string sql  string.Format(delete from tblBooks where Bno{0}, book.Bno); return SQLHelper.NoQuery(sql); } 3.录入与修改 录入与修改图书功能是在子窗体frmBook中实现的。窗体主要由TextBox、Label、Button、GroupBox控件构成。界面如图3-5图书操作界面。 图书录入信息时登记时间由确认录入时刻确认即DateTime.Now将其转化为字符串ToString()后存入数据库。新登记图书必定属于未借出状态该子控件为只读属性。其余信息需要管理员录入。 图书修改时会将获取到的信息传入子窗体管理员只需修改需要更改的内容即可。通过方法重载和条件判断来将同一窗体实现类似操作的两种功能。 图3-5 图书操作界面 打开新窗体时需要预先进行的代码操作 录入图书时直接打开窗体 frmBook bfrm new frmBook(); bfrm.ShowDialog(); 修改图书信息时会将修改前获取的图书信息传入到本界面然后选择有需要的信息进行修改点击确认按钮调用数据库修改数据信息记录。首先创建一个临时的书籍作为参数(桥梁作用)。 BooksInfo books new BooksInfo(); 将本次图书信息全部填充到一个虚拟图书books中。传入新窗体内这样的话会直接显示需要更改的书籍的全部信息选择性的更改书籍信息就可以了避免了更改图书的工作量。 try{ books.Bno txtInfo.Text.ToString().Trim(); books.Tno BooksManger.QueryBybno(books).Rows[0][Tno].ToString().ToUpper().Trim(); books.Title BooksManger.QueryBybno(books).Rows[0][Title].ToString().Trim(); books.Publisher BooksManger.QueryBybno(books).Rows[0][Publisher].ToString().Trim(); books.Author BooksManger.QueryBybno(books).Rows[0][Author].ToString().Trim(); books.State BooksManger.QueryBybno(books).Rows[0][State].ToString().Trim(); 由于部分信息不是字符串String类型的数据需要使用Convert类进行强制类型转换。(部分类型可以使用数据类型内置方法Parse()转化) books.Price Convert.ToInt32(BooksManger.QueryBybno(books).Rows[0][Price] .ToString().Trim()); }catch { MessageBox.Show(未选中图书);throw; } 获取完信息后打开新窗体的主要代码为 修改时图书书号作为主键传入时需要避免被修改。所以本次选择frmBook的重载方法传入books参数。 frmBook bfrm new frmBook(books); bfrm.ShowDialog(); (1)UI层 界面生成时需要对构造函数进行方法重载。 新增图书界面方法重载 public frmBook(){ InitializeComponent(); txtState.Text 未借出;//新增图书一定是未借出 txtState.ReadOnly true;//录入时不可更改借阅状态 } 修改图书界面方法重载 BooksInfo books new BooksInfo(); public frmBook(BooksInfo booksInfo){ InitializeComponent(); books.Bno booksInfo.Bno;//进行图书信息修改的依据数据 设置所有文本框的text属性值例如 txtBno.Text booksInfo.Bno.Trim(); 设置存储特殊信息的TextBox的ReadOnly属性为True值。 txtBno.ReadOnly true;//书号不可更改 txtState.ReadOnlytrue;}//状态不可更改 具体功能是实现 当功能为增添图书时需要判断输入的书别类型编号是否存在不存在的话询问管理员用户是否需要添加新类别编号。具体操作在书类信息管理时交代此处不做赘述。修改图书时只需将传入的信息进行修改重新上传数据库使用Update语句操作即可更改图书信息书号作为主键无法被更改。 输入信息判断检测文本内容是否为空。如果为空给出读者提示信息不可为空然后返回让用户重新操作。 if (txtBno.Text || txtTitle.Text || txtPrice.Text ) { MessageBox.Show(信息不可空); return; } if(txtAuthor.Text||txtPublisher.Text||txtType.Text) { MessageBox.Show(信息不可空); return; } 在录入图书前需要检测图书馆收录种类是否存在不存在的话需要询问是否先录入新图书种类然后录入完毕再进行新类型图书的录入工作。主要是根据图书种类查询判断是否有该种类的查询结果。 BooksType type new BooksType(); type.Tno txtType.Text.Trim(); if (TypeManger.Query(type).Rows.Count 0) { DialogResult re MessageBox.Show(未查询到该类别是否需要录入新种类, 温馨提示, MessageBoxButtons.YesNo); if (re DialogResult.No) return; 下面是打开新增种类的一个新窗体窗体设计在后文中如图3-7所示。 frmType ft new frmType(); ft.ShowDialog(); ft.Dispose(); } 将文本信息传入预操作的虚拟书籍避免修改时书本信息改为null值。 books.Bno txtBno.Text.Trim(); books.Title txtTitle.Text.Trim(); books.Tno txtType.Text.Trim(); books.Publisher txtPublisher.Text.Trim(); books.Author txtAuthor.Text.Trim(); books.PriceConvert.ToInt32(txtPrice.Text.Trim()); books.State txtState.Text.Trim(); books.Date DateTime.Now; 如果进入的是录入图书界面先判断书号是否被占用如果书号空闲执行添加操作否则提示用户“该图书的书号被使用无需录入或者尝试录入其它的书号”。 if (BooksManger.QueryBybno(books).Rows.Count 0) { MessageBox.Show(该书号被使用无需录入或尝试其他书号); return; } BooksManger.Add(books); 如果进入的是修改图书信息界面由于书号不可被修改直接执行修改操作。 BooksManger.Change(books); 二者操作结束后都会关闭本窗体。 this.Close(); (2)BLL层 图书增删改查方法在BLL层的Book Manger类库中。 增添图书Add(BookInfo book) 修改图书Change(BookInfo book) public static int Add(BooksInfo book) { return BooksService.Insert(book); } public static int Change(BooksInfo book) { return BooksService.Update(book); } (3)DAL层 增改图书的DAL层代码主要靠sql语句实现。 增加的sql语句代码实现 string sql string.Format(insert into tblBooks values({0},{1},{2},{3},{4},{5},{6},{7}),book.Bno.Trim(), book.Title.Trim(), book.Tno.Trim(), book.Publisher.Trim(), book.Author.Trim(), book.Price, book.Date.ToString().Trim(), book.State.Trim()); return SQLHelper.NoQuery(sql); 修改的sql语句代码实现 string sql string.Format(update tblBooks set Title{0},Tno{1},Publisher{2},Author{3},Price{4},Date{5},State{6} where Bno{7}, book.Title.Trim(), book.Tno.Trim(), book.Publisher.Trim(), book.Author.Trim(), book.Price, book.Date.ToString().Trim(), book.State.Trim(), book.Bno.Trim()); return SQLHelper.NoQuery(sql); 5.Model层 由于四项功能均是操作书籍信息所以Model层代码一样。在录入图书时涉及到图书类别信息在下面书种信息管理代码实现时给出。 public class BooksInfo { private string bno; private string title; private string tno; private string publisher; private string author; private int price; private DateTime date; private string state; public string Bno { get bno; set bno value; } public string Title { get title; set title value; } public string Tno { get tno; set tno value; } public string Publisher { get publisher; set publisher value; } public string Author { get author; set author value; } public int Price { get price; set price value; } public DateTime Date { get date; set date value; } public string State { get state; set state value; } } 3.4书类信息管理 图书的管理必然伴随着分门别类如此方能方便在不同类的图书中快速找到需要的图书或者为读者想要了解某方面图书时提供了范围压缩。是图书信息管理模块不可或缺的辅助信息。图书类别的信息包括类别编号、类别名称、该类图书可借阅最大天数、逾期每日罚款金额等信息设计时完成了对这些信息进行增删查改。 3.4.1书类管理页面设计 在上述的tabControl控件中新增页面tabPage_Type.页面主要控件有Button、dataGridView、treeView等。在此页面中分别有五个按钮主要是对书类增删查改以及通过treeView展示。 具体布局左面是树状图TreeView将类型编号和类型名称匹配到一起方便观察右面是图书种类的具体信息包括不同管理功能的不同配色的Button按钮。 具备功能【刷新查询】按钮会将页面的所有数据重新查询生成。【新增种类】按钮会打开一个添加种类的子窗体进行填充信息操作【修改种类】按钮会打开子窗体进行修改信息。【删除种类】按钮会删除选中行种类信息。的如图3-6书类管理页面。 图3-6书类管理页面 3.4.2书类管理代码实现 1.Model层 图书种类的Model层代码也只有四个字段属性操作起来相对图书的操作是非常简单的。先让我们见识一下书类的Model实体 public class BooksType { private string tno; private string type; private  int day;//可借阅天数 private int fine;//每天罚金 public string Tno { get tno; set tno value; } public string Type { get type; set type value; } public int Day { get day; set day value; } public int Fine { get fine; set fine value; } } 2.刷新查询 (1)UI层 展示树图。在刷新树图前将树节点TreeView.Nodes全部清除Clear()然后将数据表中的类别数据利用for循环其中dgvType的Rows.Count属性作为循环次数标准使用Nodes.Add()一一添加类别树节点。此处节点值TreeNode类型为String字符串类型所以会事先准备好类型编号和类型名称值。 myTree.Nodes.Clear(); for (int i 0; i dgvType.Rows.Count - 1; i) { TreeNode item new TreeNode(); item.Text dgvType.Rows[i].Cells[Tno].Value.ToString().Trim(); Item.Text dgvType.Rows[i].Cells[Type].Value.ToString().Trim(); myTree.Nodes.Add(item); } 获取数据表将种类信息查询到dgvType数据表视图中。 dgvType.DataSource TypeManger.Show();//图书种类信息查询 string[] str { 类号, 类名, 天数, 罚金 }; for (int i 0; i str.Length; i) { dgvType.Columns[i].HeaderCell.Value str[i]; } 设置视图信息并刷新树节点避免了两处数据展示不同步的问题。 btnRefresh_Click(this, e); (2)BLL层 上述功能只调用了TypeManger的查询方法Show().其代码为 public static DataTable Show() { return TypeService.Query(); } (3)DAL层 public static DataTable Query() { string sql select * from tblType; return SQLHelper.Query(sql); } 3.删除种类 (1)UI层 点击dataGridView控件进行获取改行信息通过主键Tno类别编号进行删除。在此之前询问用户是否确认删除。删除完毕执行查询刷新数据与数据库数据进行同步操作。 执行删除操作时需要向用户进行提示以免用户误删 DialogResult re MessageBox.Show(是否确认删除该图书种类, 提示, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning); if (re DialogResult.Cancel) return; 如果用户确认需要删除那么就获取选中行的种类信息从数据表中移除一条种类信息记录。 BooksType type new BooksType(); type.TnodgvType.Rows[dgvType.CurrentCell.RowIndex].Cells[Tno].Value.ToString().Trim(); if (TypeManger.Del(type) 0) MessageBox.Show(删除成功); (2)BLL层 删除的BLL层调用的方法是Del(BooksType type) public static int Del(BooksType type) { return TypeService.Delete(type); } (3)DAL层 public static int Delete(BooksType type) { string sql string.Format(delete from tblType where Tno{0}, type.Tno.Trim()); return SQLHelper.NoQuery(sql); } 4.增加和修改 同图书管理的增改一样书类的增改也在子窗体执行。创建窗体并命名为frmType窗体控件有TextBox、Button、Label等。用户只需要向窗体内的TextBox中填充信息然后点击提交即可如果操作有问题系统会向用户进行信息提示。如图3-7 书类操作界面。 图3-7 书类操作界面 (1)UI层 增加的UI层就是将输入的文本信息赋与临时书类类型变量然后传入业务逻辑层再进行数据访问插入一条添加记录新增书类数据。点击按钮的前提是判断信息是否全部完整、种类编号是否空闲未被使用。修改的操作就是通过构造函数重载、同界面条件语句进行改变实现。 private void btnSubmit_Click(object sender, EventArgs e) { 如果信息有空信息向用户进行信息提示引导用户填写相关信息然后再进行下一步操作。 if (txtDaylimit.Text || txtTno.Text || txtFine.Text || txtType.Text ) { MessageBox.Show(信息不可空); return; } 当填写的信息完整后填充种类信息 type.Tno txtTno.Text.Trim(); type.Type txtType.Text.Trim(); type.Day Convert.ToInt32(txtDaylimit.Text.Trim()); type.Fine Convert.ToInt32(txtFine.Text.Trim()); int rows 0; 如果调用前点击的按钮是【增加】按钮那么就执行添加功能的具体操作 if (this.Text 新增种类) { 事先判断数据表中是否已经存在过该信息如果存在的话不能新增种类否则主键冲突影响其它操作。向用户进行提示后返回主线程。 if (TypeManger.Query(type).Rows.Count 0) { MessageBox.Show(该书号对应图书已分类请尝试修改操作); return; } rows TypeManger.Add(type); } 如果调用窗体前点击的是【修改种类】那么就执行修改功能的具体操作修改时的种类号是存在的种类传进来的所以不需要判断是否种类号存在。 if (this.Text 修改种类) { rows TypeManger.Update(type); } if (rows 0) MessageBox.Show(this.Text 成功); this.Close(); } (2)BLL层 public static int Add(BooksType type) { return TypeService.Insert(type); } public static int Update(BooksType type) { return TypeService.Update(type); } (3)DAL层 public static int Insert(BooksType type) { string sql string.Format(insert into tblType values({0},{1},{2},{3}), type.Tno.Trim(), type.Type.Trim(), type.Day,type.Fine);     return SQLHelper.NoQuery(sql); } public static int Update(BooksType type) { string sqlstring.Format(update tblType set Type{0},Day{1},Fine{2} where Tno{3}, type.Type, type.Day, type.Fine, type.Tno); return SQLHelper.NoQuery(sql); } 3.5用户信息管理 图书信息管理系统归根结底是方便管理员的管理和读者的使用。所以系统的设计是为了用户的需求。那么用户信息的管理也必将占据系统的一席之地。用户信息分为两类管理员和读者。前者信息包括账户密码、姓名电话后者信息包括读者编号、姓名性别、单位、住址、电话、注册日期、最大可借阅数量。由于前者的信息比较单一且管理员的信息管理归于所在图书馆单位进行档案管理所以只需实现管理的修改密码和用户信息的管理即可。考虑到信息安全问题读者信息一旦注册只许联系管理员进行修改、不可擅自更改避免伪造虚假信息等。 3.5.1用户管理界面设计 简洁美观的界面能够大大提升用户的体验。管理端新建一个tabPage_Home作为用户管理中心可以进行自身的密码修改以及读者信息的增删查改。读者端除具体设计外同管理端一样操作页面包括groupBox、label、button、textBox、dataGridView、pictureBox等控件。 页面内部的左上方是管理员用户的基本信息以及修改密码操作功能处右面是对读者用户的管理功能的Button按钮和TextBox文本框。页面下方是用户的所有信息左右滚轮的隐藏两项信息是账号密码。 管理端在本界面可以进行【修改密码】的操作【浏览用户】、【注销用户】、【注册用户】、【修改信息】等操作。并且可以单击数据表获取本行用户信息展示到界面的文本框内便于上述的修改、删除操作。 读者端可以修改密码和查询信息。 图3-8 用户信息页面(管理端) 图3-9 用户信息界面(读者端) 3.5.2用户管理代码实现 读者端在如图3-9 用户信息界面中刷新数据用于查询用户的基本信息。修改密码用于更改用户的密码。 1.UI代码 刷新数据将登录时传入的用户信息填充到文本框中。 txtUid.Text reader.Uid; txtRno.Text reader.Rno; txtSex.Text reader.Sex; txtTel.Text reader.Tel; txtAddress.Text reader.Address; txtDate.Text reader.Date.ToString().Trim(); txtName.Text reader.Name; txtNum.Text reader.Number.ToString().Trim(); txtDept.Text reader.Dept; 修改密码通过验证文本框信息是否为空、原密码是否正确、两次新密码是否一致等异常情况。 if (txtOldPwd.Text string.Empty) {MessageBox.Show(请输入有效信息);} if (txtNewPwd.Text.Trim() ! txtRePwd.Text.Trim()) {MessageBox.Show(两次密码不一致);} if (txtOldPwd.Text.Trim() ! ReaderManger.Get(reader).Pwd.Trim()) {MessageBox.Show(原密码不正确);} 层层验证后才能修改密码成功后给予提示。并清空输入的文本信息。 reader.Pwd txtNewPwd.Text.Trim(); ReaderManger.newPwd(reader); MessageBox.Show(密码修改成功); txtNewPwd.Text string.Empty; txtOldPwd.Text string.Empty; txtRePwd.Text string.Empty; 2.BLL层代码 创建一个虚拟读者接收传入的读者的编号通过调用同层的Get()方法获取读者的全部信息改变读者的登录密码调用DAL层的Update()方法更新数据库中的数据。 public static int newPwd(ReaderInfo readerInfo) { ReaderInfo reader new ReaderInfo(); reader Get(readerInfo); reader.Pwd readerInfo.Pwd.Trim(); return ReaderService.Update(reader); } 3.DAL层代码 编辑sql语句string.Format(update tblReader set Rno{0},Name{1},Sex{2},Date{3},Tel{4},Dept{5},Address{6},Number{7},Pwd{8} where Uid{9} , r.Rno.Trim(), r.Name.Trim(), r.Sex.Trim(), r.Date.ToString().Trim(), r.Tel.Trim(), r.Dept.Trim(), r.Address.Trim(), r.Number, r.Pwd.Trim(), r.Uid.Trim())调用SQLHelper工具类执行SQL语句SQLHelper.NoQuery(sql);完成修改密码的操作。 管理端在如图3-8 用户信息管理(管理端)中包括读者用户的增删查改、自身用户的密码修改。 1.密码修改 同读者端的密码修改 if (txtOldPwd.Text string.Empty || txtNewPwd.Text || txtRePwd.Text ){ MessageBox.Show(请输入有效信息); return;} if (txtNewPwd.Text.Trim() ! txtRePwd.Text.Trim()) MessageBox.Show(两次密码不一致); if (txtOldPwd.Text.Trim() ! AdminManger.Get(admin).Pwd.Trim()){ MessageBox.Show(原密码不正确); return;} 验证过所有不合理操作后才能执行真正的修改密码NewPwd(user)操作。 admin.Pwd txtNewPwd.Text.Trim(); if (AdminManger.newPwd(admin) 0) { MessageBox.Show(error); ; return; } MessageBox.Show(密码修改成功); 2.注册用户 打开注册界面相当于登录界面的读者注册功能此处不做赘述。 3.注销用户 选择DataGridView控件dgvReaders的单元格将基础信息展示到文本框内点击删除系统提示是否确认注销用户xxx选择取消则不继续执行后续代码本次删除无效。如果确认将删除所选行的用户账号。删除后重新查询数据库刷新数据。 (1)UI代码 删除操作需要提示以免误删 DialogResult re MessageBox.Show(是否确认注销该用户在删除之前请确认需要删除的用户, 提示,MessageBoxButtons.OKCancel,MessageBoxIcon.Warning); if (re DialogResult.Cancel) return; ReaderInfo reader new ReaderInfo(); int indexdgvReaders.CurrentCell.RowIndex; reader.Uid dgvReaders.Rows[index].Cells[Uid].Value.ToString(); ReaderManger.Del(reader); (2)BLL代码 UI层调用BLL层的Del(ReaderInfo reader)方法该方法通过访问数据库ReaderService.Delete(reader)请求删除用户数据。 (3)DAL代码 编辑SQL语句串并执行SQL语句访问数据库。 string.Format(delete from tblReader where uid{0},r.Uid.Trim()); SQLHelper.NoQuery(sql); 4.查询用户 提供一键查询所有用户信息的功能能够浏览所有系统使用者的信息。点击【浏览信息】按钮通过BLL间接访问数据库查询查询语句为: string.Format(select * from tblReader) 5.修改信息 修改用户信息是通过修改展示到文本框中的信息后点击【修改信息】按钮即可修改。具体实现方法为ReaderInfo reader new ReaderInfo(); int index dgvReaders.CurrentCell.RowIndex; 不可更改内容读者的编号、账号、密码、注册日期等内容在注册时就已经被确定由于信息安全不应该被修改所以此处的信息经由Get方法将查询结果重新赋予该读者。 reader.Uid dgvReaders.Rows[index].Cells[Uid].Value.ToString().Trim(); reader.Rno dgvReaders.Rows[index].Cells[Rno].Value.ToString().Trim(); reader.Number Int32.Parse(dgvReaders.Rows[index].Cells[Number].Value.ToString()); reader.Pwd dgvReaders.Rows[index].Cells[Pwd].Value.ToString().Trim() ; reader.Date Convert.ToDateTime(dgvReaders.Rows[index].Cells[Date].Value.ToString()); 可更改内容包括用户的非用户基本信息如家庭住址、所属单位、联系电话、读者姓名和读者性别。 reader.AddresstxtAddress.Text.Trim(); reader.Dept txtDept.Text.Trim(); reader.Tel txtTel.Text.Trim(); reader.Name txtName.Text.Trim(); reader.SexcmbSex.Text.Trim(); 最后一句代码通过调用BLL间接调用DAL层访问数据库执行修改操作。 if (ReaderManger.Update(reader) 0) MessageBox.Show(修改成功);修改的sql语句为 string.Format(update tblReader set Rno{0},Name{1},Sex{2},Date{3},Tel{4},Dept{5},Address{6},Number{7},Pwd{8} where Uid{9} , r.Rno.Trim(), r.Name.Trim(), r.Sex.Trim(), r.Date.ToString().Trim(), r.Tel.Trim(), r.Dept.Trim(), r.Address.Trim(), r.Number, r.Pwd.Trim(), r.Uid.Trim()); 3.6图书借阅管理 图书借阅是用户端的核心功能即借阅图书归还图书两项基本核心操作。借阅记录的留存统计也是图书馆信息管理系统的重要内容之一有了借阅的记录才能分析图书借阅情况、用户喜好情况、书籍流向等信息。在此用读者可以借还图书、管理员可以查看借阅记录。借阅信息包括借阅书籍编号、读者编号、借阅时间、归还时间、逾期天数、罚款金额(默认为0)归还状态等。 3.6.1 图书借阅界面设计 用户端(图3-10借阅归还操作界面)在frmReaders的选项卡中添加一页xpBook添加控件dataGridView、groupBox、label、textBox、Button等。 最上方是索引导航、根据选择的索引方式快速查询自己想要借阅的书籍读者端的上方表格是图书馆的资源下面的表格是自己借阅的未归还的书籍右下角是具体的借阅归还功能Button。管理端(图3-11借阅记录查询页面)在frmAdmin的选项卡中添加一页pageBorrow,添加控件dataGridView控件仅供查询浏览。 图3-10 借阅归还操作界面(读者端) 图3-11 借阅记录查询界面(管理端) 3.6.2 图书借阅代码实现 1.管理端查询。代码 查询数据库中的借阅信息表dgvBorrow.DataSource BorrowManger.Query(); 通过DataGridView.Columns.Width设置列宽使信息在一页内展示完整 dgvBorrow.Columns[0].Width 105; dgvBorrow.Columns[1].Width 105; dgvBorrow.Columns[2].Width 140; dgvBorrow.Columns[3].Width 140; 将表的列名更改为中文信息使用户一目了然。我认为最佳设置方法是创建一个字符串数组str[],然后按照数据库中的列的顺序赋予中文列名存储到字符串数组中。然后用循环依次赋予第i列的列名为str[i]储存的字符串。 string[] str { 借出书号, 借阅人, 借阅时间, 归还时间, 逾期天数, 结算罚款, 借阅状态 }; for (int i 0; i str.Length; i) { dgvBorrow.Columns[i].HeaderCell.Value str[i]; } DAL层的SQL查询语句为select * from tblBorrow; 2.读者端借书 通过点击预操作行的图书获取书号点击【我要借书】按钮加入到我的书架中将图书的状态改为已借出插入一条借阅记录并默认状态为未归还。 (1)UI代码 查询获取图书状态检测是否可以借阅 string BookState BooksManger.QueryBybno(book).Rows[0][State].ToString().Trim(); if (BookState 已借出) { MessageBox.Show(书籍已被借阅尚未归还请静待几日); return; } Get()读者借阅书籍数量上限 int number ReaderManger.Get(reader).Number; 如果上限数量小于等于0即已经借阅了太多书图书馆自动认为用户看不过来不可再借书了给予用户提示。 if (number 0) MessageBox.Show(可借阅书籍数量已达上线); 如果没有达到上限将可借阅书籍-1达到书籍借阅成功的一个标志 reader.Number number - 1; ReaderManger.Update(reader);//可借阅书籍数量减一 然后调用BLL层的BooksManger()方法根据书号查询该图书的类别编号引用书类信息表使用TypeManger()方法获取相关信息提示读者用户本书的借阅时长限制和罚款情况。 第一步获取类型编号 string tno BooksManger.QueryBybno(book).Rows[0][Tno].ToString().Trim(); BooksType type new BooksType(); 第二步获取最大借阅天数和逾期每日罚金 type.Tno tno; string maxDayTypeManger.Query(type).Rows[0][Day].ToString().Trim(); string fine TypeManger.Query(type).Rows[0][Fine].ToString().Trim(); 第三步进行提示 string msg string.Format(本次可借阅时长:{0}天\r\n逾期将每日罚款{1}元\r\n是否继续借阅, maxDay, fine); DialogResult re MessageBox.Show(msg,提示,MessageBoxButtons.OKCancel); if (re DialogResult.Cancel) return; 如果读者同意继续借书将调用BLL层的BorrowManger.BorrowBook()方法插入一条借阅书籍的记录。 BorrowManger.BorrowBook(book, reader); (2)BLL代码 BorrowManger.BorrowBook(book, reader); 1.将tblBooks中图书的借阅状态改为已借出 book.State 已借出; BooksService.Update(book); 2.插入一条借阅信息包括 book.Bno;reader.Rno,其他有默认值 BorrowInfo borrowInfo new BorrowInfo(); borrowInfo.Bno book.Bno; borrowInfo.Rno reader.Rno; borrowInfo.State 未归还; borrowInfo.Bdate DateTime.Now.Date; borrowInfo.Rdate DateTime.MinValue; borrowInfo.Exday 0; borrowInfo.Fine 0; 调用DAL层Insert()方法访问数据库BorrowService.Insert(borrowInfo); (3)DAL代码 BooksService.Update(book);return SQLHelper.NoQuery(sql); 具体SQL语句如下 string sql string.Format(update tblBooks set Title{0},Tno{1},Publisher{2},Author{3},Price{4},Date{5},State{6} where Bno{7}, book.Title.Trim(), book.Tno.Trim(), book.Publisher.Trim(), book.Author.Trim(), book.Price, book.Date.ToString().Trim(), book.State.Trim(), book.Bno.Trim()); BorrowService.Insert(borrowInfo);return SQLHelper.NoQuery(sql); 具体SQL语句如下 string sql string.Format(insert into tblBorrow values({0},{1},{2},{3},{4},{5},{6}),b.Bno, b.Rno, b.Bdate.ToString().Trim(), b.Rdate.ToString().Trim(), b.Exday,b.Fine,b.State); 3.读者端还书 通过点击预操作行的图书获取书号点击【我要还书】按钮从我的书架中移除将图书的状态改为未借出更改该条借阅记录并默认状态为已归还。本条借阅记录就此完整。 (1)UI代码 还书时更新用户的最大借阅书籍限制1。 reader.Number ReaderManger.Get(reader).Number 1; ReaderManger.Update(reader);//可借阅书籍数量加一 某用户借阅某书需要用户编号和书籍编号 BooksInfo book new BooksInfo(); book.Bno txtBno.Text; BorrowManger.ReturnBook(book, reader); (2)BLL代码 BorrowManger.ReturnBook(book, reader); 具体代码如下 BorrowInfo borrowInfo new BorrowInfo(); borrowInfo.Bno book.Bno; borrowInfo.Rno reader.Rno; borrowInfo.Bdate Convert.ToDateTime(BorrowService.Query(borrowInfo, -1).Rows[0][Bdate].ToString().Trim()).Date; 1.将tblBooks中图书的借阅状态改为未借出 book.State 未借出; BooksService.Update(book); 2.获取tblType图书所属类别规定的最大可借阅时长逾期每天需罚款多少钱 BooksType type new BooksType(); type.Tno book.Tno; int maxDay Int32.Parse(TypeService.Query(type).Rows[0][Day].ToString().Trim()); int price Convert.ToInt32(TypeService.Query(type).Rows[0][Fine].ToString().Trim()); 3.获取tblBorrow借书时间与还书时间差并截取Days属性作为天数差然后分别计算逾期天数罚款金额 int day (DateTime.Now - borrowInfo.Bdate).Days; int exday 0; int fine 0; 如果没有逾期就不用计算直接就是00。如果天数差day比最大借阅天数maxDay大那么就计算罚金。 if (day maxDay) { exday day - maxDay; fine exday * price; } 4.更改tblBorrow的超出天数罚款金额 borrowInfo.Exday exday; borrowInfo.Fine fine; borrowInfo.Rdate DateTime.Now.Date; borrowInfo.State 已归还; 调用DAL.BorrowService.Update()方法更改本次借阅记录 BorrowService.Update(borrowInfo); (3)DAL代码 BooksService.Update(book);SQLHelper.NoQuery(sql); 具体SQL代码如下 string sql string.Format(update tblBooks set Title{0},Tno{1},Publisher{2},Author{3},Price{4},Date{5},State{6} where Bno{7}, book.Title.Trim(), book.Tno.Trim(), book.Publisher.Trim(), book.Author.Trim(), book.Price, book.Date.ToString().Trim(), book.State.Trim(), book.Bno.Trim()); BorrowService.Update(borrowInfo);SQLHelper.NoQuery(sql); 具体SQL代码如下 string sql string.Format(update tblBorrow set State{0},Rdate{1},Exday{2},Fine{3} where Bno{4} and Rno{5},b.State , b.Rdate.ToString().Trim(), b.Exday,b.Fine,b.Bno, b.Rno); 4.Model层 该层的图书类在上面已经提到此处只写出借阅类的代码: public class BorrowInfo { private string bno;//书号 private string rno;//读者编号 private DateTime bdate;//借书时间 private DateTime rdate;//还书时间 private int exday;//超出天数 private int fine;//罚款金额 private string state;//是否还书 public string Bno { get bno; set bno value; } public string Rno { get rno; set rno value; } public DateTime Bdate { get bdate; set bdate value; } public DateTime Rdate { get rdate; set rdate value; } public int Exday { get exday; set exday value; } public int Fine { get fine; set fine value; } public string State { get state; set state value; } } 3.7拓展功能设计 为了更好地用户体验和便捷高效地管理只有基础的功能是不够地。对此系统做了一定功能地拓展。例如报表统计、留言建议、系统公告数据统计、最优推荐联网资源拓宽书籍资源库界面合理性和美化等。 *读者功能导航 打开DevExpress提供的第三方Edit编辑器选择主题Office 2019 Colorful添加导航栏。增加导航栏按钮并向按钮注册事件。 this.barBtnLibrary.ItemClick new DevExpress.XtraBars.ItemClickEventHandler(this.barBtnLibrary_ItemClick); this.barBtnUser.ItemClick new DevExpress.XtraBars.ItemClickEventHandler(this.barBtnUser_ItemClick); this.barBtnBorrow.ItemClick new DevExpress.XtraBars.ItemClickEventHandler(this.barBtnBorrow_ItemClick); this.barBtnElectric.ItemClick new DevExpress.XtraBars.ItemClickEventHandler(this.barBtnElectric_ItemClick); this.barBtnNotice.ItemClick new DevExpress.XtraBars.ItemClickEventHandler(this.barBtnNotice_ItemClick); this.barBtnMore.ItemClick new DevExpress.XtraBars.ItemClickEventHandler(this.barBtnMore_ItemClick); this.barButtonItem2.ItemClick new DevExpress.XtraBars.ItemClickEventHandler(this.barButtonItem2_ItemClick); this.barButtonItem1.ItemClick new DevExpress.XtraBars.ItemClickEventHandler(this.barButtonItem1_ItemClick); 其中离开系统的功能实现是关闭所有进程Application.Exit();返回登陆是关闭进程并重启Applica.ReStart();这是本系统返回登陆的一个特色实现方法。其它方法是打开不同的tabPage或form并配置。 *导出Excel表 public static void ExportToExcel(System.Data.DataTable dt, string path) 导出数据公共类。首先定义一个流写入变量sw。 StreamWriter sw null; 为变量创建实例path是保存路径false即选择覆盖不追加。导出字符为Unicode字符集。 sw new StreamWriter(path, false, Encoding.Unicode); 创建一个临时存储变量。并通过StringBuilder.Append()方法依次导入数据表的列头附加制表符。并换行。 StringBuilder sb new StringBuilder(); for (int i 0; i dt.Columns.Count; i) {sb.Append(dt.Columns[i].ColumnName \t);} sb.Append(Environment.NewLine); 通过StringBuilder.Append()方法通过循环将具体数据以行为基础单位读入sb。并换行。 for (int i 0; i dt.Rows.Count; i) { for (int j 0; j dt.Columns.Count; j) {sb.Append(dt.Rows[i][j].ToString() \t);} sb.Append(Environment.NewLine); } 数据读取完毕后使用StreamWrite.Write()方法将sb转化为字符串写入Excel表。写入后使用内置方法Flush()清空缓存。 sw.Write(sb.ToString()); sw.Flush(); } 导出Excel表的BLL层代码 第一步生成一个保存文件的系统窗体SaveFileDialog saveFileDialog1 new SaveFileDialog(); 第二步将调用的窗体的标题更改一下作为提示:saveFileDialog1.Title 保存文件; 第三步设置保存格式/路径saveFileDialog1.Filter Excel 文件(*.xls)|*.xls|Excel 文件(*.xlsx)|*.xlsx|所有文件(*.*)|*.*; 第四步导出数据表 1.导出图书信息 设置文件名为Book拓展名为excel的文件格式.xls saveFileDialog1.FileName Book.xls; 查询图书信息表并存到DataTable变量中。 DataTable dt BooksManger.Query(); if (saveFileDialog1.ShowDialog() DialogResult.OK) { string path saveFileDialog1.FileName;//保存路径 ExcelHelper.ExportToExcel(dt, path);//将dt表通过path的路径格式保存为Excel文件 } 2.导出书类信息 设置文件名为Type拓展名为excel的文件格式.xls saveFileDialog1.FileName Type.xls; 查询图书种类信息表并存到DataTable变量中。 DataTable dt TypeManger.Show(); if (saveFileDialog1.ShowDialog() DialogResult.OK) { string path saveFileDialog1.FileName;//保存路径 ExcelHelper.ExportToExcel(dt, path);//将dt表通过path的路径格式保存为Excel文件 } 3.7.1 留言动态 留言和公告包括了发布者、发布内容和发布时间等必要信息。因此留言模块的Model层代码如下 public class MsgInfo { private string uid;//发布者 private string msg;//发布内容 private string date;//发布日期 public string Uid { get uid; set uid value; } public string Msg { get msg; set msg value; } public string Date { get date; set date value; } } 界面设计:如图3-12 系统公告(管理端)和图3-13留言动态(读者端)所示。界面包括了TextBox、Button、dataGridView等控件。 管理端设计TextBox文本框设置为MutiLine可多行编辑显示放在页面内的最上方【发布系统公告】按钮与【查看留言建议】按钮依次分布其右。下方是具体的留言动态表。 读者端设计页面上方是留言动态表、留言内容编辑文本框以及功能按钮下方是一个ReadOnly的内容显示文本框作用是显示表格中被隐藏的留言内容。 图3-12 系统公告(管理端) 图3-13 留言动态(读者端) 代码实现 两端发布公告/留言(对应DML类sql语句的的增加) 如果发布的内容为空被系统认定为不发布也就是内容完整性判断 if (txtMessage.Text string.Empty) { MessageBox.Show(无法发布内容为空的公告); return; } 尝试使用MsgManger.WriteMsg()方法将写入文本框的内容上传到数据表中传入的三个参数分别是发布用户User.Id.ToString().Trim()发布内容TextBox.Text.Trim()发布时间DateTime.Now.ToString().Trim()。例如管理员发布内容时的代码为 try { MsgManger.WriteMsg(admin.Uid.ToString().Trim(), 系统公告: txtMessage. Text.Trim() , DateTime.Now.ToString().Trim()); MessageBox.Show(发布成功); } 如果中间补货到了异常提示用户发布失败是系统问题不是用户操作问题。 catch (Exception) {MessageBox.Show(发布失败请联系技术员检查后台);throw;} 紧接着清空本次发布内容并刷新留言表同步数据 txtMessage.Text string.Empty; btnViewHistory_Click(this, e); Sql语句为 string.Format(insert into tblMsg values({0},{1},{2}),uid.Trim(), msg.Trim(), date.Trim()); 两端查询动态的操作(对应DQL类sql语句-查询数据表语句) dgvNotice.DataSource MsgManger.GetMsg(); 根据列头和列宽设置查询结果的表的外观 dgvNotice.Columns[0].HeaderText 用户; dgvNotice.Columns[1].HeaderText 内容; dgvNotice.Columns[2].HeaderText 时间; dgvNotice.Columns[1].Width 550; dgvNotice.Columns[2].Width 180; Sql语句为string.Format(select * from tblMsg) 3.7.2 数据统计 数据统计分析是为了发现图书馆服务中可能存在的问题。对于后续系统的维护和改进有很大的帮助。 统计分析一本馆概况如图3-14 数据统计(管理端)。图表展示内容是本系统使用者借阅的所有图书种类的占比情况。 图3-14 数据统计(管理端) 设置图书馆情况信息。通过查阅数据表中一共存在多少行来判断一共有多少条数据也就是通过图书表、借阅记录表、读者用户表依次可以获取馆内图书总数、累计借阅次数、使用本系统的读者数目。 labelBooks.Text 馆内在册图书:BooksManger.Query().Rows.Count.ToString()册; labelCnt.Text 累计借阅次数: BorrowManger.Query().Rows.Count.ToString().次; labelReader.Text 注册读者数目:ReaderManger.Query().Rows.Count.ToString()人; chart1.Titles.Clear();//将上次的统计结果清除以便后续重新统计。 chart1.Titles.Add(图书分类借阅数据分析); Liststring XList new Liststring();//x轴存储字符串 Listint YList new Listint();//y周存放数据 for(int i0; i TypeManger.Show().Rows.Count;i) { string str TypeManger.Show().Rows[i][Tno].ToString().Trim() . TypeManger.Show().Rows[i][Type].ToString().Trim(); XList.Add(str);//横坐标就是种类 BooksType t new BooksType(); t.Tno str[0].ToString(); int cnt 0;//假设本次横坐标种类一共被借阅的次数为0 for (int j 0; j BorrowManger.Query().Rows.Count; j) { BooksInfo books new BooksInfo(); books.Bno BorrowManger.Query().Rows[j][Bno].ToString().Trim(); if (BooksManger.QueryBybno(books).Rows.Count 0 t.Tno BooksManger.QueryBybno(books).Rows[0][Tno].ToString().Trim()) { cnt;//每次在借阅记录表中查询到之后都可以让这类的y轴数据1. } } YList.Add(cnt);//循环结束后将数据添加到y轴 } chart1.Series[0].IsVisibleInLegend true;//标注可见 chart1.Series[TypeCnt].Points.DataBindXY(XList, YList);//Points()方法绘图 统计分析二最多借阅书籍图表展示了本馆所有图书的借阅次数并将借阅次数最多的书籍的信息推荐给读者如图3-16数据分析(读者端)。 图3-16 数据分析(读者端) int maxIndex 0; int max 0; 设置X、Y轴等待填充具体内容。 Liststring Xlist new Liststring(); Listint Ylist new Listint(); for (int j 0; j BooksManger.Query().Rows.Count; j){ string str BooksManger.Query().Rows[j][Title].ToString().Trim(); Xlist.Add(str);//横坐标就是书名 int cnt 0; string bookId BooksManger.Query().Rows[j][Bno].ToString().Trim(); for (int i 0; i BorrowManger.Query().Rows.Count; i) { if (BorrowManger.Query().Rows[i][Bno].ToString().Trim() bookId){cnt;} } if (cnt max){ maxIndex j; max cnt; } Ylist.Add(cnt); } 将x轴信息和y轴信息添加到图表的Series[0]中并将图表的示例Legend设为可见。 chartBestBooks.Series[0].IsVisibleInLegend true; chartBestBooks.Series[0].Points.DataBindXY(Xlist, Ylist); 将表格结果进行分析。通过TextBox的文本属性展示分析出的最佳借阅书籍结果。并调用BLL层方法查询该书籍信息并写入TextBox中。 txtAnalysis.Text string.Format(本馆最多借阅书籍:\r\n\r\n书名: 《{0}》\r\n借阅次数: {1}\r\n, Xlist[maxIndex].Trim(),max); txtAnalysis.Text string.Format(作者: {0}\r\n, BooksManger.Query().Rows[maxIndex][Author].ToString().Trim()); txtAnalysis.Text string.Format(书号: {0}\r\n, BooksManger.Query().Rows[maxIndex][Bno].ToString().Trim()); string type BooksManger.Query().Rows[maxIndex][Tno].ToString(); BooksType tnew BooksType(); t.Tno type; string tname TypeManger.Query(t).Rows[0][Type].ToString().Trim(); txtAnalysis.Text string.Format(类型: {0}.{1}\r\n, type.Trim(), tname.Trim()); txtAnalysis.Text string.Format(出版社: {0}\r\n, BooksManger.Query().Rows[maxIndex][Publisher].ToString().Trim()); txtAnalysis.Text string.Format(售价: {0}\r\n, BooksManger.Query().Rows[maxIndex][Price].ToString().Trim()); 图3-15 数据展示(读者端) 3.7.3 电子资源 图3-17 链接跳转(管理端) 管理端设计如图3-17所示页面集成了一部分网页和图书馆信息点击网页时会获取本机默认浏览器并跳转到超链接内容。 读者端界面包括左侧的菜单网页、搜索引擎以及右侧隐藏的WebBrowser浏览器窗体。 图3-17 访问网页(用户端) 界面初始化时加载浏览器内核自动配置浏览器内核。 var settings new CefSettings(); try {CefSharp.Cef.Initialize(settings);} catch (Exception) {;//空语句目的是捕获错误置之不理避免影响系统运行} 浏览网页初始化(实质就是添加一个浏览器选项卡) void webInit(string str) { webChannel.Controls.Clear();//清理上次的浏览页面 webChannel.Controls.Add(new ChromiumWebBrowser(str));//增加新的浏览页面 } str就是网址字符串。如图3-18所示系统给提供了一部分网址串。可以直接打开。 3.7.4 界面加载 添加一个progressBar进度条控件一个timer组件。通过timer的Tick事来增加进度条并改变进度显示字体。如图3-19界面主体是一个动漫图片目的是使读者等待时有所看设想未来可以发展为广告位获取系统维护资金等。加载的目的是让后台准备进程、匹配用户信息等。等到加载完成后进度条消失、显示进入系统的按钮如末尾附图3-20。 图3-19 加载中 for (int i 0; i 3; i) { barProgress.Increment(new Random().Next(1500) 1);//随机增加数字 labelLoding.Text加载中...   Math.Round(barProgress.Value/100.0,2).ToString(#00.00)%;//规定字符数据格式。 System.Threading.Thread.Sleep(300);//模拟令timer休眠300毫秒防止字体不断闪烁造成不显示字符的情况。 } 当进度条的当前位置比设置好的最大值10000相等或一样的话就停止模拟时间流失。通过Visible属性将进度条设为不可见进入系统的按钮设为可见设置timer控件的Enabled属性设为false防止后续系统运行时timer继续执行占用系统资源。 if (barProgress.Value barProgress.Maximum) { this.barProgress.Visible false;//进度条不可见 this.labelLoding.Visible false;//进度数据不可见 this.timer1.Enabled false;//防止占用资源导致卡顿 this.btnEnter.Visible true;//显示加载后的按钮 } 图3-20 加载完成(附) 第4章 系统测试 软件生命周期的每个阶段都不可回避地会产生差错力求在每个阶段加速之前通过严格的技术审查尽可能的早发现并纠正错误。测试的目的就是在软件投入实际使用前尽可能地多发现软件中的错误实现对软件规格说明设计和编码的最后复查。测试是不可穷尽的测试人员不可能发现系统中所有的缺陷每个版本发布前也不可能保证所有已知的缺陷都会得到修复所以反复测试是为了发现更多的缺陷预防风险。测试人员跟踪需求、验证质量、提交缺陷的同时也促进了开发人员技术的提升在这个过程中牵扯到项目流程管理的问题一个优秀的测试在这个过程中会建立一套完成的体系来提高整个团队的工作效率从而来降低开发成本进而把控产品质量但需明确的是软件的质量不只是测试人员来把关最终质量好坏是整个团队的结果。软件测试整体是验证功能的实现、可用性检查程序的错误最终目的是为了提高用户体验在测试过程中有一些缺陷级别低解决与否都不影响用户使用且缺陷存在本身用户也不会有感知这时就需要从用户体验的角度去考量是否要定义该类问题为缺陷。 4.1 系统测试的原则 通过阅读《软件评测师教程》我对本次系统设计的测试工作有了以下的十一点认识 1.尽早地和不断地进行软件测试 越早进行测试缺陷的修复成本就会越低。应当把软件测试贯穿到整个软件开发的过程中而不应该把软件测试看作是其过程中的一个独立阶段。因为在软件开发的每一环节都有可能产生意想不到的问题其影响因素有很多比如软件本身的抽象性和复杂性、软件所涉及问题的复杂性、软件开发各个阶段工作的多样性以及各层次工作人员的配合关系等。所以要坚持软件开发各阶段的技术评审把错误克服在早期从而减少成本提高软件质量。在本系统的开发编码阶段我就在不停的测试每实现一个模块我就测试一下看看与其他模块是否能连接上提高系统的可靠性。 2.严格执行测试计划排除测试的随意性以避免发生疏漏或者重复无效工作。 3.程序员应避免检查自己的程序由第三方进行测试更客观有效 4.穷举测试是不可能的 5.充分注意测试中的群集现象一段程序中一发现的错误数越多其中存在的错误概率越大因此对发现错误较多的程序段应进行更深入的测试 6.设计测试用例时应包括合理输入和不合理输入以及各种边界条件、特殊情况下要制造极端状态和意外状态 7.注意回归测试的关联性往往修改一个错误会引起更多错误 8.测试应从“小规模”开始逐步转向“大规模” 9.测试用例式设计出来不是写出来的应根据测试的目的采用相应的方法设计测试用例从而提高测试的效率更多的发现错误提高程序的可靠性 10.重视并妥善保存一切测试过程文档测试计划测试用例测试报告等对测试错误结果一定要有一个确认的过程 11.所有测试的标准都是建立在用户需求之上的测试的目的在于发现系统是否满足规定的需求。 在遵守以上原则的基础上进行软件测试可以以最少的时间和人力找出软件中的各种缺陷从而达到保证软件质量的目的。  4.2 测试结果 本次测试针对开发的图书馆管理系统进行包括功能测试界面测试负载测试文档测试。按照规格需求说明书中的功能进行测试在测试过程中发现软件的漏洞不足并予以改正。检验软件本身的功能是否达到了预期的想法在众多的测试当中性能和功能都在不断的进行完善设计的合理达到了人们的一些生活需求在以后的测试极其维护该改进中都有非常良好空间。 主要对系统功能模块进行测试得到的测试结果如下表4-1所示。 表4-1测试结果 测试项目 验证过程 预期结果 实际结果 结论说明 管理员登录 系统管理员登录输入种植户名Stark密码123456 进入系统管理员管理界面 进入系统管理员管理界面 测试成功通过 读者用户登录 注册会员登录输入种植户名Stark密码123456 进入系统读者用户浏览界面 进入系统读者用户浏览界面 测试成功通过 读者用户注册 点击注册按键进入新读者用户注册页面填写注册信息并提交 显示注册成功 显示注册成功 测试成功通过 找回密码 点击找回密码选项进入找回密码界面输入用户信息扫描二维码获取验证码并提交 显示用户密码 显示用户密码 测试成功通过 密码修改 提交用户新旧密码点击密码修改按键 显示密码修改成功 显示密码修改成功 测试成功通过 添加读者用户信息 进入图书馆信息管理系统点击进入用户管理页面添加读者信息添加相关信息并提交 提交后增加新数据信息 提交后增加新数据信息 测试成功通过 修改读者用户信息 进入图书馆信息管理系统点击进入用户管理页面修改读者信息修改相关信息并提交 提交后数据信息发生改变 提交后数据信息发生改变 测试成功通过 删除读者用户信息 进入图书馆信息管理系统点击进入用户管理页面删除读者信息点击删除 删除后列表记录数减少 删除后列表记录数减少 测试成功通过 查询读者用户信息 进入图书馆信息管理系统用户管理页面点击浏览用户 页面显示所有读者用户相关数据 页面显示所有读者用户相关数据 测试成功通过 浏览图书信息 进入图书管理页面点击进入图书信息管理页面 列表显示所有图书信息 列表显示所有图书信息 测试成功通过 查询图书信息 进入图书管理页面点击查询方式按要求填入关键信息点击查询 页面显示查询相关数据 页面显示查询相关数据 测试成功通过 添加图书信息 进入图书管理页面点击进入图书管理界面添加图书信息添加相关信息并提交 提交后增加新数据信息 提交后增加新数据信息 测试成功通过 修改图书信息 进入图书管理页面点击进入图书管理界面修改图书信息修改相关信息并提交 提交后数据信息发生改变 提交后数据信息发生改变 测试成功通过 删除图书信息 进入图书管理页面选中预操作行点击删除 删除后列表记录数减少 删除后列表记录数减少 测试成功通过 增加图书种类 进入图书种类管理页面点击进入图书种类管理界面添加相关信息并提交 提交后增加新数据信息 提交后增加新数据信息 测试成功通过 修改图书种类 进入图书种类管理页面点击进入图书种类管理界面修改图书图书种类修改相关信息并提交 提交后数据信息发生改变 提交后数据信息发生改变 测试成功通过 删除图书种类 进入图书种类管理页面选中预操作行点击删除 删除后列表记录数减少 删除后列表记录数减少 测试成功通过 浏览图书种类 进入图书种类管理页面点击进入图书种类信息列表页面 列表显示所有图书种类信息 列表显示所有图书种类信息 测试成功通过 图书借阅 进入图书借阅页面选中预操作行点击借阅按钮 图书列表信息更改、插入一条借阅记录 图书列表信息更改、插入一条借阅记录 测试成功通过 图书归还 进入图书借阅页面选中预操作行点击归还按钮 图书列表信息更改、修改一条借阅记录 图书列表信息更改、修改一条借阅记录 测试成功通过 浏览留言记录 进入留言界面点击浏览记录按钮 列表显示所有留言信息 列表显示所有留言信息 测试成功通过 发布留言 进入留言界面点击发布按钮 提交后增加新数据信息 提交后增加新数据信息 测试成功通过 导出图书信息 进入图书管理页面点击导出按钮 弹出保存Excel文件系统窗口 弹出保存Excel文件系统窗口 测试成功通过 导出图书种类 进入图书管理页面点击导出按钮 弹出保存Excel文件系统窗口 弹出保存Excel文件系统窗口 测试成功通过 浏览网页 点击进入电子资源界面选择列表网址或自行输入有效网址 页面内打开网址内容网页信息 页面内打开网址内容网页信息 测试成功通过 界面加载 选择进入读者系统进入中间加载界面 随加载显示进度加载完成显示进入按钮。 随加载显示进度加载完成显示进入按钮。 测试成功通过 结论 图书馆信息管理系统是基于C/S结构、C#开发语言、Visual Studio开发环境以及SQL Server数据库管理系统进行构建开发的。具体实现的功能如下 每个用户都可以注册、找回密码以及使用自己的账号密码登录系统或更改密码管理员可以任意修改读者的部分账户信息管理员可以对图书馆的图书进行增删查改用户可以对图书进行借阅归还(更改图书的借阅状态信息)管理员可以对图书的种类进行增删查改管理端可以查看所有的借阅记录读者端可以查看自己的未归还状态的借阅记录读者端借书时插入一条借阅记录、还书时更改借阅记录的归还状态管理端可以发布系统公告、读者端发可以布使用方面的留言反馈两端都可以互相查看内容数据统计系统会根据读者的借阅情况为管理端提供种类借阅情况饼状图以便引进更多该种类的书籍、同时给读者端提供每本书的借阅次数、给新手一个阅读方向。Excel报表管理员可以在图书管理页面将图书信息和图书种类两种图书馆核心信息导出Excel表。 在系统开发过程中使用和扩展的关键技术如下 1页面布局设计方面使用了DevExpress皮肤插件和Cskin皮肤插件优化界面布局、提供配套设计高度的自定义属性和大量的方法给了本人更灵活的设计思路和方向以适应客户需求提高用户体验 2逻辑层面上通过学习表的约束和表的相互之间的配合使用、绘制系统功能逻辑图等在逻辑层面上使得系统功能更加完善功能不单一。 3三层架构方面程序通过建立Model实体类减少了传参时代码的冗余分层调用方法避免了UI层直接访问数据库导致数据信息不安全的问题为测试、维护、升级、开发等各方面都提供了极大的便利。 4编程技巧方面学习运用了面向对象设计的思想例如继承实现Cskin的换肤操作、封装功能减少代码冗余、每个不同窗体的建立就是多态的实现。OOP的三大特点让系统的维护和开发更加有利。 5.拓展控件方面例如chart控件绘制图表并设计分析使系统功能全面化、具体化codeControl控件(QRcode)字符串生成二维码找回密码使得系统更加现代化timer控件与progressBar控件进行搭配进行进度条加载、使得系统界面更加美观timer控件与pictureBox控件搭配进行图片轮播使得系统实现了简易版的主流主页模式。 系统具有一定的局限性具体体现在 由于系统是由C#.NET写出来的在Linux操作系统上使用会非常复杂需要准备工具AnyExec(工具在Linux.NET有且目前只支持64位)。 【免费】实践项目-图书馆管理系统(C#.NET)_图书馆数据库管理系统资源-CSDN文库
http://www.hkea.cn/news/14479633/

相关文章:

  • 制作自己的网站需要什么软件好大型的网站建设
  • 如何设计企业网站简述几种网络营销的方法
  • 网页设计网站制作收获推广文章
  • 网站转app工具高级版网址怎么申请
  • 北京做网站比较有名的公司有哪些网站是做流程
  • 国内ui网站有哪些网页制作教程答案
  • 网站建设工单系统房子装修风格大全2021新款
  • 做一回最好的网站龙岗爱联有学网站建设
  • 深圳的设计企业网站提供专业网站建设平台
  • 有没有可以做翻译的网站wordpress 微站
  • 一个店铺的运营方案seo加盟代理
  • 八爪鱼网站建设中国民政网站医院标准化建设
  • 开发一个网站 要多久百度地图网页版
  • 做旅游网约车的网站中国战略咨询公司排名
  • 电子商务网站建设与管理论文网页素材提取
  • dedecms 模版网站wordpress 发货
  • 成都捕鱼网站建设陕西省建设监理协会查询官方网站
  • h5 建站网站 移动端做卖挖掘机的网站
  • 保定市做网站制作网站结构设计
  • 做网站价格中核工建设集团有限公司网站
  • python 做的网站有哪些链接怎么做
  • 查询网网站毕业答辩ppt模板免费下载 素材
  • 游戏网站做关键字做3d图的网站有哪些软件
  • 网站优化是做什么的wordpress默认相册图片连接到媒体
  • 可以自己做网站吗企业oa系统下载
  • 济南建网站品牌自适应网站建设
  • 建筑网站建设赏析免费网站下载大全
  • 企业做网站公司排名口碑详情页设计策划
  • 更新网站的步骤wordpress建站如何微信
  • 花生壳动态域名做网站做两个阿里网站吗