《2022年进销存管理系统权限管理模块的设计方案》由会员分享,可在线阅读,更多相关《2022年进销存管理系统权限管理模块的设计方案(45页珍藏版)》请在金锄头文库上搜索。
1、本科毕业论文进销存管理系统权限管理模块的设计精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 1 页,共 45 页2 / 45 Design and Simulation of IIR Digital Filter LUO Xiao Supervisor: LIU Peng-jun March 2008 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 2 页,共 45 页I / 45 摘要本篇论文主要是对进销存管理系统,库存管理和权限管理模块的设计。使用SQL Server ,C+Builder等程序对公
2、司的系统管理的变革,让系统模块的使用者更方便,更效率的管理进销存系统。关键词 :进销存管理系统;库存管理;权限管理模块精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 3 页,共 45 页II / 45 Abstract Keywords:MIS ; C+ Builder6.0 ;information system 目录1 前言 12 系统的需求分析12.1 系统总体分析 1 2.2 系统的基本功能模块2 2.3 系统流程图 53 系统设计 53.1 系统配置 5 3.2 数据库设计 6 3.2.1 系统数据表及其用途6 3.2.2 创建数据库及数
3、据表6 3.3 系统模块的具体设计7 3.3.1 系统主窗体的设计7 3.3.2 访问数据模块的创建8 3.3.3 登录功能的完成 9 3.4 库存查询与权限管理模块设计15 4 数据库的安全性及管理224.1 数据库的安全性 22 4.2 备份和恢复数据库31 4.2.1 数据库的备份 31 4.2.2 数据库的恢复 33 5 源代码 34参考文献 40致谢 41精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 4 页,共 45 页1 / 45 1 前言随着我国社会主义市场经济体制的确立和发展,商业流通领域进入了一个空前的发展阶段,面临商界的激烈竞
4、争,只有在多变的商品和顾客中挖掘并掌握市场需求,即淘汰“卖不出去的商品”,购进“卖得快、利润高的商品”的经营者才会获利,企业也才能在竞争中生存和发展,如果能够选择一个好的管理系统,把大量繁杂的、看似毫无关系的数据,有机的结合起来,形象的反映出市场的供求关系,就能够为得出正确的决策做出事半功倍的效果。在过去,销售业的操作一般都靠人工操作,如靠人工登记卡片、填写表格资料,然后根据不同的分类入帐,销售额的日结算和每月的盘点都需花费大量的人力和物力来完成。即使前几年,有些商家开始使用电脑管理,但也只是进行一些简单的数据计算的操作。这是一项极其繁琐的工作。通过人手工计算不仅容易出错,而且不能够及时把数据
5、之间的关系形象化表现出来,也就不能够进一步掌握市场的最新动态。而通过本系统基本可解决以上问题,并且能够方便、灵活地对数据库的资料进行查询、统计、打印等操作,所有这些对数据库进行的操作都受到管理级别的限制,确保数据的安全性。另外,本系统从实用性方面考虑,在联机交换数据时,尽量使数据在必要时才进行传递,提高运行速度。数据库技术是一门历史弥坚的学科,不像其它的计算机技术会随着时间的推移而变得越来越没有声息。考虑其原因,则是因为信息的爆炸对数据库技术的要求只增不减。在互联网日益发展、壮大的背景下,在因特网热潮不减的情况下,如何让原来在单机中使用的数据库可供多机使用,也成了必然的趋势。企业要在竞争中求得
6、生存,就应使自己的产品资料销售、管理等方面科学化,让更多的人知道自己的产品,这样才能争取到更多的销售渠道。在实际应用中,对于商品编码的输入可采用扫描仪的方式,比较准确、方便、快捷,但在本系统中,前台销售操作部分由于缺乏硬件条件,须人手工输入商品编号,但这对系统的模拟并无太大的影响。在实际的仓库进销存管理中,普遍使用多机操作共享同一个数据库的管理系统。本论文将详细介绍仓库进销存的模拟管理系统的开发环境、需求分析、设计思想及其强大的功能,使用户对本系统有一个清晰、完整的了解,详细介绍了个别模块的实现步骤,并附有参考文献。2 系统的需求分析2.1 系统总体分析精选学习资料 - - - - - - -
7、 - - 名师归纳总结 - - - - - - -第 5 页,共 45 页2 / 45 我们现已确定系统开发的目标,系统需求规格。确定软件系统的总体结构,给出系统中各个组成模块见的联系。划分功能模块,将软件功能需求分配给所有单元模块。下一步工作就是在上述结果基础上,考虑怎样实现这个软件系统。仓库各种信息的输入,包括入库,出库,还原,需求信息的输入等(b仓库管理的各种信息查询,修改和维护(c设备采购报表的生成在库存管理中加入最高储备和最低储备字段(d对仓库的物质设备实现监控和报警(e企业各个部门的物质需求管理, 操作日志的管理(f 仓库管理系统的使用帮助本系统的以上功能会更适合仓库管理的发展情况
8、,将会给仓库管理带来一种更为科学的服务系统,是仓库管理自动化的一面新窗口。也将会是仓库管理员的好帮手。设备信息情况描述包括设备的编号、名称、入库时间、供应商、采购员、价格等。(b工作用户权利描述密码、权限级别 一般用户权利描述权限级别 数值)经过对以上数据的分析与描述,现在可以知道设备的各种信息关系。然后更好的实现系统 . 。3)实现本系统功能的方法首先要制作一个仓库设备信息的存储库,以用来存储设备信息。作为主题工作后台。接下来将要再建立一个主表,也就是设备信息表,作为前台功能展开,以完成各方面操作。最后新系统要在友好的界面中,达到用预期,并要在良好的可靠性、高速的效率、易使用的目的在安全性和
9、稳定性前提下,给用户们提供各种方便的操作。2.2 系统的基本功能模块一个进销存管理系统应包含以下几大功能模块。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 6 页,共 45 页3 / 45 图1 进销存管理系统结构图1)资料管理模块企业经营的基础资料是一个企业最基本和最重要的信息。其中包括商品资料,供货商资料和客户资料,脱离了基础资料,进销存系统将无法运行。资料管理用于维护这些基础资料,它包含的功能字模快为:图2 资料管理模块结构图其中商品资料维护用于维护企业经营商品的基本信息,内容包括货号,条形码,品名,拼音编码,规格,单位,产地,类别,销售价
10、1,销售价 2,最底售价等。其中拼音编码是商品名称的拼音简称,目的是在程序中可以通过拼音码方便的查到所需要的产品。供货商资料维护用于维护企业供货商的基本信息,内容包括供货商号,拼音编码,简称,名称,地址,邮编,电话,传真,类型,库房地址,库房电话,业务员,业务部门等。客户资料维护用于维护企业客户的基本信息,内容包括客户编号,拼音编码,简称,名称,联系人,地址,电话,传真,开户行,开户行邮编,银行帐号,业务员,业务部门,授信额度等。进销存管理系统资料管理采购管理销售管理库存管理系统管理资料管理商品资料维护供货商资料维护客户资料维护精选学习资料 - - - - - - - - - 名师归纳总结 -
11、 - - - - - -第 7 页,共 45 页4 / 45 2)采购管理模块采购管理用于管理企业的采购业务,我们所做的系统中它主要有进货单功能子模块。进货单用于录入企业的进货单,它分为主从两张表,主表进货单内容包括编号,供货商号,进货日期,业务员,制单人,验收员,保管员,税额,订单号等,从表进货单明细内容包括编号,进货单号,货号,进货数量,进价,税价合计,不含税价,税额,仓库,货物质量等。根据企业的规模和管理方法,可以直接做进货单而不用做采购订单,但对于较大规模的企业,一般采购部门和库房部门是分开的,由采购部门填写采购订单,货物运输到库房后由库房验收人员填写进货单。填写进货单后商品的库存才会
12、增加并产生应付款。3)销售管理模块销售管理用于管理企业的销售业务,我们做的系统它主要包含销售单功能子模块。销售单用于录入企业的销售单,主表销售单内容包括编号,客户编号,销售日期,业务员,制单人,保管员,税价合计,不含税价,税额,订单号等,从表销售单明细内容包括编号,销售单号,货号,销售数量,销售价,税价合计,不含税价,税额,仓库等。采购入库指将从供应商处采购的产品入库;(b生产入库指将企业自己生产的产品入库;(c退货入库指售出的产品退货后,将退货产品入库;(d退料入库指用于本企业生产的原材料出库后没有完全使用,退回仓库。入库操作需要记录相关的产品信息、仓库信息、客户信息、经办人、涉及金额和入库
13、时间等信息;5)出库操作可以分为销售出库、退货出库、用料出库等情况。出库操作需要记录相关的产品信息、仓库信息、客户信息、经办人、涉及金额和出库时间等信息。库存盘点是指对库存产品进行整理,纠正不准确的库存数据。由于人为操作等原因,系统中的库存数据与实际数据之间可能会存在误差。所以没隔一段时间就需要对库存进行盘点,从而保证库存数据的准确, 库存查询用于查询企业商品的库存,可以查询总库存和分仓库库存。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 8 页,共 45 页5 / 45 6)系统管理模块系统管理是每个系统都必须具备的功能,包括的功能子模块如下:
14、图3 系统管理结构图权限设置用于设置各操作员使用系统操作的权限,为了方便设置,一般的应用系统都可以将操作人员分组的,将通用的权限赋予整个组,个别的权限单独赋予个人,这样可以大大减少权限管理的工作量。数据备份用于备份系统数据库。数据恢复用于恢复系统数据库。2.3 系统流程图图4 进销存管理系统流程图3 系统设计3.1 系统配置系统的使用环境:硬件环境: PentiumIV 或同档次以上微机; 32MB 以上内存或更高; 4.2G以上硬盘;打印系统管理权限设置数据备份数据恢复供货商库存库客户应付款应收款进货单销售单增加库存减少库存产生应收款产生应付款精选学习资料 - - - - - - - - -
15、 名师归纳总结 - - - - - - -第 9 页,共 45 页6 / 45 机一台。软件环境:中文 WINDOWS/2000操作系统。3.2 数据库设计3.2.1 系统数据表及其用途表 1 系统数据表数据表名称数据表用途用户清单保存系统使用者的信息权限清单保存系统使用者的权限信息商品清单保存企业经营商品的资料信息供货商清单保存企业供货商的信息客户清单保存企业客户的资料信息仓库清单保存企业库房的分类信息业务员清单保存企业的业务员信息进货单进货单主表进货单明细进货单从表进货单历史保存进货单历史进货单明细历史保存进货单明细历史销售单销售单主表销售单明细销售单从表销售单历史保存销售单历史销售单明细
16、历史保存销售单明细历史库存单保存企业商品库存的数量、金额等应付款、应收款保存企业应付款明细、应收款明细3.2.2 创建数据库及数据表数据库的创建比较简单。打开SQL Server 2000 企业管理器,新建一个数据库,名称为 jxc 。表的创建有两种方式:第一个是利用SQL Server 2000的查询分析器打开建库的脚本,直接运行它,系统的相关元素就可以自动建立起来。第二个是进入新建的数据库 jxc, 利用设计表这一功能来创建表。数据表的创建如下: CREAT TABLE dbo. 商品清单 NOT NULL Primary Key, 条码 char (14 NULL, 品名 varchar
17、 (80 NULL, 规格 varchar (40 NULL, 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 10 页,共 45 页7 / 45 单位 char (6 NOT NULL, 产地 varchar (50 NULL, 类别 char (20 NULL, 进货价 decimal (9 NULL default(0, 销售价 1 decimal (9 NULL default(0, 销售价 2 decimal (9 NULL default(0, CREAT TABLE dbo. 库存库 NOT NULL , 仓库 varchar (20
18、 NOT NULL , 库存数量 decial (28,6 NOT NULL , 库存金额 decial (28,6 NOT NULL , 库存单价 decial (28,6 NOT NULL , 最新进价 decial (28,6 NOT NULL , CREAT TABLE dbo. 权限清单 NOT NULL , 用户编号 char (6 NULL, 部门 char (20 NULL, 权限名称 char (6 NOT NULL 3.3 系统模块的具体设计3.3.1 系统主窗体的设计利用系统默认生成的窗体作为主窗体,并为其添加一个主菜单MainMenu )控件,布局如图:精选学习资料 -
19、 - - - - - - - - 名师归纳总结 - - - - - - -第 11 页,共 45 页8 / 45 图 5 进销存管理系统主界面3.3.2 访问数据模块的创建因为各个窗体均需要对数据库进行访问,我们可以把与数据库进行连接的控件放置到一个数据访问模块中,这样所有的窗体都可以共享来访问数据库。1)在 ODBC 中添加一个驱动程序为SQL Server的系统 DNS 数据源指向前面创的jxc 数据库,名称为“ jxclink ” 。2)在C+ Bilder 的 BDE Administrator 工具中新建一个BDE 数据源,名称为“jxclink ” ,Type属性为“ SQL Se
20、rver” ,ODBC DNS 属性为” jxclink ” 。3)在 C+ Builder 中选择 File/New/Data Module 菜单命令,生成一个数据模块并保存为“ db.cpp” 文件。4)为数据模块添加一个Database控件,控件的属性设置如下所示,这样在其他窗体中就可以直接使用Query和 Table控件来访问数据了。表 2 数据库表控件名属性取值Database1 Name Database1 Database1 AliasName jxclink Database1 DatabaseName db 精选学习资料 - - - - - - - - - 名师归纳总结 -
21、- - - - - -第 12 页,共 45 页9 / 45 Database1 LoginPrompt false 3.3.3 登录功能的完成用户在输入“用户号”和“密码”之后,系统对用户的输入进行确认,并记录登录用户的姓名和用户号,供系统使用权限管理、制单人指定等)。设计步骤如下:登录界面如图 6:图 6 管理员登录模块界面1)选择 NewForm 菜单命令,新建一个窗体,将其Name 属性改为“ fmLogin ”,并为其添加下列控件:为 fmMain 和 fmLogin 两个窗体 TfmLogin *pForm=new TfmLogin(Application 。PForm-ShowM
22、odal(。If(pForm-m_szUserCode.IsEmpty( /取消了,退出程序Application-terminate( 。 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 13 页,共 45 页10 / 45 else m_szUserCode=pForm-m_szUserCode 。m_szUserName=pForm-m_szUserName 。 delete pForm。 CreateForm(_classid(TfmMain,&fmMain 。Application-CreateForm(_classid(TdataMod
23、ule1,&DataModule1。(3为 fmLogin 窗体添加如下事件响应函数代码,完成密码认证功能。void _fastcall TfmLogin:edUserCodeExit(TObject *Sender if(edUserCode-Text.IsEmpty( return。TQuery* pQuery = new TQuery(NULL 。pQuery-DatabaseName = db 。AnsiString sql。sql = select 姓名,密码 from 用户清单 where 用户编号 = + edUserCode-Text + 。pQuery-SQL-Add(sql
24、。pQuery-Open(。TField* pField = pQuery-FieldByName( 姓名 。if(pField-IsNull / 不存在该用户 edUserCode-Text = 。edUserName-Text = 。edPassword-Text = 。edUserCode-SetFocus( 。 else/ 显示用户名 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 14 页,共 45 页11 / 45 edUserName-Text = pField-AsString。m_szUserCode = edUserCode-T
25、ext 。m_szUserName = pField-AsString 。m_szPassword = pQuery-FieldByName( 密码-AsString。 / 释放空间delete pQuery。 /- void _fastcall TfmLogin:edUserCodeKeyPress(TObject *Sender, char &Key if(Key = 13 edPassword-SetFocus( 。 /- void _fastcall TfmLogin:btLoginClick(TObject *Sender if(!m_szUserName.IsEmpty( & m_
26、szPassword = edPassword-Text / 密码正确 this-Close(。 else / 密码错误 edPassword-Text = 。edPassword-SetFocus( 。 /- void _fastcall TfmLogin:btExitClick(TObject *Sender m_szUserCode = 。m_szUserName = 。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 15 页,共 45 页12 / 45 m_szPassword = 。this-Close(。 /- void _fastca
27、ll TfmLogin:edPasswordKeyPress(TObject *Sender, char &Key if(Key = 13 btLoginClick(NULL 。 至此,我已经完成了用户登录的功能。系统首先要求用户输入用户号和密码,并与用户清单中的信息进行对比,认证通过后在可以进入系统。Login.h 文件原代码如下:#ifndef loginH #define loginH /- #include #include #include #include #include #include /- class TfmLogin : public TForm _published:
28、/ IDE-managed Components TLabel *Label1 。TLabel *Label2 。TLabel *Label3 。TEdit *edUserCode。TEdit *edUserName。TEdit *edPassword。TButton *btLogin 。TButton *btExit 。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 16 页,共 45 页13 / 45 TLabel *Label4 。void _fastcall edUserCodeExit(TObject *Sender 。void _fas
29、tcall edUserCodeKeyPress(TObject *Sender, char &Key 。void _fastcall btLoginClick(TObject *Sender 。void _fastcall btExitClick(TObject *Sender 。void _fastcall edPasswordKeyPress(TObject *Sender, char &Key 。private: / User declarations public: / User declarations _fastcall TfmLogin(TComponent* Owner 。A
30、nsiString m_szUserCode 。AnsiString m_szUserName。AnsiString m_szPassword 。 。/- extern PACKAGE TfmLogin *fmLogin 。/- #endif Login.cpp 文件原代码如下:#include #pragma hdrstop #include login.h /- #pragma package(smart_init #pragma resource *.dfm TfmLogin *fmLogin 。/- _fastcall TfmLogin:TfmLogin(TComponent* Own
31、er : TForm(Owner /- 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 17 页,共 45 页14 / 45 void _fastcall TfmLogin:edUserCodeExit(TObject *Sender if(edUserCode-Text.IsEmpty( return。TQuery* pQuery = new TQuery(NULL 。pQuery-DatabaseName = db 。AnsiString sql。sql = select 姓名,密码 from 用户清单 where 用户编号 = + edUse
32、rCode-Text + 。pQuery-SQL-Add(sql。pQuery-Open(。TField* pField = pQuery-FieldByName( 姓名 。if(pField-IsNull / 不存在该用户 edUserCode-Text = 。edUserName-Text = 。edPassword-Text = 。edUserCode-SetFocus( 。 else/ 显示用户名 edUserName-Text = pField-AsString。m_szUserCode = edUserCode-Text 。m_szUserName = pField-AsStrin
33、g 。m_szPassword = pQuery-FieldByName( 密码-AsString。 / 释放空间delete pQuery。/- void _fastcall TfmLogin:edUserCodeKeyPress(TObject *Sender, char &Key if(Key = 13 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 18 页,共 45 页15 / 45 edPassword-SetFocus( 。 /- void _fastcall TfmLogin:btLoginClick(TObject *Sender
34、 if(!m_szUserName.IsEmpty( & m_szPassword = edPassword-Text /密码正确 this-Close(。 else / 密码错误 edPassword-Text = 。edPassword-SetFocus( 。 /- void _fastcall TfmLogin:btExitClick(TObject *Sender m_szUserCode = 。m_szUserName = 。m_szPassword = 。this-Close(。 /- void_fastcall TfmLogin:edPasswordKeyPress(TObjec
35、t *Sender, char &Key if(Key = 13 btLoginClick(NULL 。 3.4 库存查询与权限管理模块设计库存查询功能用于查询商品的库存信息,只能查询,不可以修改。1 ) 选 择New/Form 菜 单 命 令 , 新 建 一 个 窗 体 , 将 其Name 属 性 改 为精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 19 页,共 45 页16 / 45 “fmStoreQuery” ,并为其添加如图所示的控件。选择Project/Options菜单命令,将fmStoreQuery窗体从自动创建的窗体列表中删除。
36、2)窗体中的 DBGrid 控件, Query 控件和 DateSource控件的属性设置和选择仓库窗体一致 .Query 控件的 SQL 属性设置为“ select a.货号, b.品名,拼音编码,单位,仓库,库存数量,库存单价,库存金额from 库存库 as a,商品清单 as b where a.货号=b.货号”。图 7 库存查询及权限管理模块图 /初始化仓库下拉选项 TQuery* pQuery=new Tquery(NULL 。 PQuery-DatebaseName= ”db”。 PQuery-SQL-Clear(。 PQuery-SQL-Add(“select仓库名 from 仓
37、库清单“ ; PQuery-Open(。 While(!pQuery-Eof cbostore-Items-Add(pQuery-FieldByName(“仓库名“ -AsString。pQuery-Next(。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 20 页,共 45 页17 / 45 pQuery-Close(。delete pQuery。cboStore-Text = “”。edGoodcode-Text edGoodPY-Text = 。 /- void _fastcall TfmStoreQuery:btQueryClick(TO
38、bject *Sender Query1-Filtered = false。 / 设置 Query控件的 filter 属性可以起到查询条件的作用 AnsiString szCon。 if(edGoodCode-Text.Length(0 szCon = 货号= +edGoodCode-Text + 。 if(edGoodPY-Text.Length(0 if(szCon.Length(0 szCon += and 拼音编码 like % + edGoodPY-Text + %。 else szCon = 拼音编码 like % + edGoodPY-Text + %。 if(cboStore
39、-Text.Length(0 if(szCon.Length(0 szCon += and 仓库 = + cboStore-Text + 。 else szCon = 仓库 = + cboStore-Text + 。 Query1-Filter = szCon。 Query1-Filtered = true。 权限管理是每一个应用系统必须具备的功能,以下为完成权限管理功能的过程。1 ) 选 择New/Form 菜 单 命 令 , 新 建 一 个 窗 体 , 将 其Name 属 性 该 为“fmRightManage”,并为其添加如图所示的控件。选择Project/Options菜单命令,将fm
40、RightManage 窗体从自动创建的窗体列表中删除。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 21 页,共 45 页18 / 45 图 8 权限管理模块界面图2)各控件属性设置如表所示:表 3 权限管理数据信息表控件类型对象名属性取值说明)Query Query1 DatabaseName db Table Table1 DatabaseName db Table Table1 TableName 用户清单Table Table1 Active true DataSource DataSource1 DataSet Table1 Data
41、Source DataSource1 AutoEdit false DBGrid DBGrid1 DataSource DataSource1 DBGrid DBGrid1 OptionsdgEditing false DBGrid DBGrid1 OptionsdgRowSelect true CheckListBox CheckListBox1 Items 权限管理窗体 / 删除窗体并回收空间精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 22 页,共 45 页19 / 45 Action = caFree。 /- void _fastcall
42、 TfmRightManage:Table1AfterScroll(TDataSet *DataSet / 先去除所有的权限标志 for(int i=0 。 iItems-Count。 i+ CheckListBox1-Checkedi = false。 / 根据选择的用户设置权限标志 Query1-Close(。 Query1-SQL-Clear(。 Query1-SQL-Add(select 权限名称 from 权限清单 where 用户编号 = + Table1-FieldByName(用户编号 -AsString + 。 Query1-Open(。 while(!Query1-Eof
43、AnsiString szFunName = Query1-FieldByName(权限名称 -AsString。 CheckListBox1-CheckedCheckListBox1-Items-IndexOf(szFunName = true。 Query1-Next(。 /- / 选择或去除功能权限 ,修改数据库权限清单表void _fastcall TfmRightManage:CheckListBox1ClickCheck(TObject *Sender / 没有选择用户 ,退出函数 if(!Table1-FieldByName( 用户编号 return。 / 循环判断 Query1
44、-Close(。 Query1-SQL-Clear(。 AnsiString sql。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 23 页,共 45 页20 / 45 / 不管没有选中 ,先全部删除 ,再根据选择的情况插入 sql = delete from 权限清单 where 用户编号 = 。 sql += Table1-FieldByName(用户编号 -AsString + 。 Query1-SQL-Add(sql。 for(int i=0 。 iItems-Count。 i+ if(CheckListBox1-Checkedi / 选
45、中权限 ,权限清单中插入一条 sql = insert into 权限清单 (用户编号 ,权限名称 values( 。 sql += Table1-FieldByName(用户编号 -AsString + , 。 sql += CheckListBox1-Items-Stringsi + 。 Query1-SQL-Add(sql。 Query1-ExecSQL(。 Query1-Close(。 到此我们完成了权限管理的功能,在主窗体中添加权限管理菜单的响应函数即可运行程序查看结果,如图所示。选择一个用户可以对其进行权限设置,赋予的权限在功能模块左边打勾即可。上面我们只是完成了权限设置的功能,程
46、序中还要控制用户登录系统后将该用户不具备的功能菜单变成灰色的不可操作菜单,从而控制用户的操作权限。 TfmLogin *pForm = new TfmLogin(Application 。 pForm-ShowModal(。 if(pForm-m_szUserCode.IsEmpty( / 取消了 ,退出程序 Application-Terminate(。 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 24 页,共 45 页21 / 45 else m_szUserCode = pForm-m_szUserCode 。 m_szUserName
47、= pForm-m_szUserName 。 StatusBar1-Panels-Items1-Text = m_szUserName 。 delete pForm。 / 设置功能菜单的状态 ,屏蔽用户不可操作的功能 / 如果是系统管理员登录 ,则不设置 if(m_szUserCode = 1 return。 TQuery* pQuery = new TQuery(NULL 。 pQuery-DatabaseName = db 。 pQuery-SQL-Add(select 权 限 名 称from 权 限 清 单 where 用 户 编 号 = + m_szUserCode + 。 pQuer
48、y-Open(。 TStringList* plst = new TStringList( 。 while(!pQuery-Eof plst-Add(pQuery-FieldByName(权限名称 -AsString。 pQuery-Next(。 for(int j=0 。 jItems-Count。 j+ TMenuItem* pItem = MainMenu1-Items-Itemsj 。 for(int i=0 。 iCount。 i+ TMenuItem* pSubItem = pItem-Itemsi 。 if(pSubItem-Count = 0 & plst-IndexOf(pS
49、ubItem-Caption pSubItem-Enabled = false 。 delete pQuery 。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 25 页,共 45 页22 / 45 delete plst。 自此我们基本完成了这个制作,我们可以运行程序进行各种操作,检查程序的稳定性,也可以尝试增加其他功能。我们可以使用其他用户来登录,比如使用一同学来登录,按照前面赋予该同学的权限,登录后系统如图所示,该同学没有操作权限的功能被屏蔽了。4 数据库的安全性及管理4.1 数据库的安全性安全性管理是数据库管理系统的一个重要组成部分。安全性
50、就是确保只有授权的用户才能使用数据库中的数据和执行相应的操作,它包括两方面的内容,一是用户能否登录系统和如何登录的管理,二是用户能否使用数据库中的对象和执行相应的操作管理。 Microsoft SQL Server 2000系统提供了一套完整的安全机制,这些机制包括选择认证模式和认证进程.登录账户管理 .数据库用户账户管理.角色管理 .许可管理等内容。用户在使用 Microsoft SQL Server系统前,必须通过系统的认证进程。认证模式就是设置系统的认证进程的方式。认证进程就是指当用户访问数据库时,系统对用户的账户和口令的确认过程。认证内容包括确认用户的账户是否有效,是否能访问系统,能访
51、问系统中的哪些数据等。认证模式就是指系统选择何种认证进程确认用户是否为合法的方式。用户必须使用一个 Login账户,才能连接到 SOL Sever 系统中。 SOL Sever 系统通过Windows认证进程来确认用户的身份。使用Windows认证进程时,由 Windows系统确认用户的 Login账户,这些 Windows系统的 Login账户可以直接访问 SOL Sever 系统的数据,不必提供 SOL Sever 的Login账户和口令。在 SOL Sever系统中,把网络协议 Named pipes和TCP/IP称为信任协议。如果在一个网络环境中,连接客户机和服务器的所有通讯协议都是信
52、任连接协议,那么应该采用Windows认证模式。在 Windows认证模式下,系统只是采用 Windows认证进程来确认用户的身份,那些通过非信任连接协议连接服务器的客户机不能访问 SOL Sever 系统。 Windows认证进程具有下列优点:提供了更多的功能,例如安全确认和口令加密,审计,口令失效,最小口令长度和账户锁定。允许用户迅速访问 SOL Sever 系统,而不必使用另外一个登录账户和口令。SOL Sever 系统通过下列方式处理 Windows认证模式中的 Login账户: 1)当用户连接 SOL Sever 系统时,客户机打开一个到 SOL Sever系统的信任连接。该信任连接
53、传送Windows组或用户的Login账户到 SOL Sever系统中。因为客户机打开了一个信任连接,所以SOL Sever系统精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 26 页,共 45 页23 / 45 已经确认该用户的 Login账户有效。 2)如果 SOL Sever 系统在 syslogins系统表中的 SOL Sever用户列表中找到该用户的Login账户,那么就接受这次认证连接。这时,SOL Sever系统不需要重新验证口令是否有效,因为Windows系统已经 验证该用户的口令是否有效的。 3)在这种情况下,该用户的Login账
54、户即可以是 Windows的用户账户,也可以是 Windows的组账户。当然,这些账户都是作为SOL Sever 系统的 Login账户已经定义了。 4)如果多个 SOL Sever 系统在一个域中或在一组信任域中,那么只要登录到其中一个域就可以访问全部的SOL Sever 系统。为了访问 SOL Sever 系统,用户必须提供正确的Login账户。这些 Login账户既可以是Windows系统的 Login账户,也可以是 SOL Sever 系统的 Login账户。 Login账户是基于服务器使用的户名。在 SOL Sever系统中,既可以基于 Windows组或用户账户创建 Login账户
55、,也可以创建 SOL Sever自己的账户。 Login账户的信息是系统级信息,存储在master 数据库的 syslogins系统表中。 SOL Sever有一个默认的 Login账户sa。Sa是系统管理员的简称,是一个特殊的Login账户。 Sa账户在 SOL Sever系统中拥有全部的权限,即可以执行所有操作。另外,Sa账户是不能被删除的。所有的Windows管理员Administrator拥有SOL Sever系统的全部的权限,其对应的SOL Sever 系统中的 Login账户分别是 BUILTINAdministrator 和域名 Administrator。图8 库存查询模块图我
56、们可以通过两种方式增加Login 账户:基于 Windows 组成用户账户创建 Login 账户和创建新的 SOL Sever系统的 Login 账户。我们可以使用系统存储过程sp_grantlogin或SOL Sever Enterprise Manager工具允许 Windows 用户账户或组账户连接到 SOL Sever系统上。只有系统管理员或安全管理员才可以执行系统存储过程sp_grantlogin。系统存储过程 sp_grantlogin的语法形式如下: sp_grantlogin domainNamelogin 精选学习资料 - - - - - - - - - 名师归纳总结 - -
57、 - - - - -第 27 页,共 45 页24 / 45 在上面的语法中, Login 参数是将要增加的 Windows 用户账户或组账户。 Windows 用户账户或组账户必须使用 Windows 域名限定。域名和用户名或组名合起来的长度不能超过128个字符。在下列的程序清单中,把sales 域中的 tom用户添加到了 SOL Sever系统中。添加之后,只要 tom用户登录到 Windows 系统之后,就可以直接访问SOL Sever系统中的数据。除了 sp_grantlogin系统存储过程之外,还有两个系统存储过程用来管理Login 账户: sp_revokelogin 和sp_de
58、nylogin. 其中系统存储过程 sp_revokelogin 从SOL Sever中删除 Windows 组或用户账户,系统存储过程sp_denylogin 禁止Windows 组或用户连接到 SOL Sever中。我们可以使用 SOL Sever Enterprise Manager工具把 Windows 的组或用户账户添加到SOL Sever系统中。1)创建 Windows 用户账户。在 Windows xp中增加一个用户 JXC. 2)授权 Windows 用户访问 SQL Server。在SQL Server企业管理器的主窗口中,打开制定的服务器节点。打开安全性节点,右击登录节点,
59、从弹出的快捷式菜单中选择新建登录命令。这时,打开SQL Server登录属性 - 新建登录对话框,如图所示,该对话框有三个选项卡,即常规选项卡,服务器角色选项卡,数据库访问选项卡。图9 SQL Server 登录属性界面图 I 3)在常规选项卡中,选择 Windows 身份验证,然后从域下拉框中选择相应的域名。接下来,单击名称文本框右边的无线电按钮,则出现选择Windows 账户对话框,如精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 28 页,共 45 页25 / 45 图所示:图10 SQL Server 登录属性界面图 II 4)在所示的对话
60、框中,从名称列表中选中WinSQL 账户。单击添加按钮,则可以把 WinSQL 账户添加到添加名称文本框中。然后,单击确定按钮,则可以把该账户添加到 General选项卡中的 Name文本框中。图11SQL Server 登录属性界面图 III 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 29 页,共 45 页26 / 45 5)选择 Grant Access 单选按钮,表示授权该 Windows的用户账户访问 SQL Server。还应该为该账户指定一个默认的数据库和使用的语言,这些操作可以通过Database 下拉框和 Language 下
61、拉框完成。 Sever Roles 选项卡如下所示。在该选项卡中,列出了系统中所有的固定的服务器角色。在每一个固定服务器角色的左侧,有一个复选框。选中某个复选框,就表示新创建的Login账户是该服务器角色的成员。这里,将新建的 Login账户添加到了 System Administrators固定的服务器角色中。使用Properties按钮可显示指定角色的详细描述信息。图12 SQL Server 登录属性界面图Database Access 选项卡如下图所示。在该选项卡中,上面的列表框列出了当前系统的数据库。单击数据库左侧的复选框,表示该账户可以访问该数据库,并且指定一个该账户在该数据库中对
62、应的用户名。默认情况下,login 帐户与数据库用户的名称是一样的。下面的列表框列出了数据库中的数据库角色。可以指定该账户所属的数据库角色。这里,指定新建的login 账户可以访问Northwind 数据库,在该数据库中的user账户是 WinSQL,且添加到了 db_owner固定的数据库角色中。6)单击 New Login 对话框中的确定按钮,则完成login 账户的创建操作。在创建基于 Windows 账户的 SQL Server的 login 账户时,应该注意下面一些问题:首先对于精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 30 页,共
63、 45 页27 / 45 一个Windows 组账户来说,SQL Server 只有一个login 账户与其对应。因此删除Windows 组账户的某个成员账户并不影响SQL Server 中的 login 账户。其次,删除Windows 的某个组账户或用户账户,并不把它们从SQL Server 系统中删除。如果希望删除 Windows 的某个组账户或用户账胡,应该首先把它从Windows 删除,然后再把它从 SQL Server中删除。还有作为Windows 某个组账户成员的用户账户,既可以作为成员访问 SQL Server系统,也可以通过单独授权访问SQL Server系统。我们还可以使用s
64、p_addlogin系统存储过程或SQL Server Enterprise Manager或向导创建一个 SQL Server的 login 账户。只有系统管理员或安全管理员才可以执行sp_addlogin 系统存储的过程。我们前面说过, login 账户信息存储在系统表syslogins中。sp_addlogin系统存储过程就是在master 数据库的系统表syslogins 中添加一条记录。当执行了系统存储过程sp_addlogin 之后,用户就可以使用该账户登录到SQL Server 系统中。 SQL Server 的login 账户最长是128 个字符。通过使用sp_password
65、 系统存储过程,用户可以在任意时刻改变自己的账户口令。另外,系统管理员通过使用sp_password 系统存储过程,用NULL 作为老口令,也可以改变任意用户账户的口令。图13SQL Server 登录属性界面图每个数据库都有一个用来记录数据库user账户信息的 sysusers 系统表。在 sysusers 系精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 31 页,共 45 页28 / 45 统表中,每一行数据要么是一个Windows用户账户, Windows组账户, SQL Server的login账户或 SQL Server角色。 user
66、账户是基于数据库使用的名称,与login账户是相对应的。为了访问数据库,一个 login账户可以使用一个特定的用户账户或一个默认的用户账户。为了在数据库中增加用户账户,可以使用SQL Server Enterprise Manager 或sp_grantdbacess 系统存储过程。只有数据库所有者或数据库访问管理员可以执行添加user账户的操作。 sp_grantdbacess 系统存储过程的语法形式如下:sp_grantdbacessloginName,userName 在上面的语法形式中,参数loginName是将要成为数据库user账户的 login账户名称。该 login账户可以是
67、Windows用户账户, Windows组账户或SQL Server的login账户。参数 userName 是一个可选的数据库中 user账户名。如果没有使用参数 userName ,那么 user账户名称与 login账户名称相同。除此之外,sp_revokedbacess 系统存储过程可以从当前的数据库中删除指定的user账户。sp_revokedbacess 系统存储过程的语法形式为:sp_revokedbacess userName 。就像创建login账户一样,也可以使用 SQL Server Enterprise Manager 创建数据库 user账户。1)在 SQL Serv
68、er Enterprise Manager主窗口中打开指定的服务器组再打开指定的服务器再选择一个将增加用户的数据库,例如Northwind. 2)右击 Northwind 数据库,从弹出的菜单中选择New Database User 命令,则出现 Database User Properties-New User 对话框。检查点机制检查数据库,记录最早的事务日志记录和日志序列号。(b通过直接阅读磁盘,把全部的数据页写进备份介质中。(c从捕捉到的序列号到日志末尾,写全部的事务日志记录。在 SQL Server 企业管理器的主窗口中,打开指定的服务器组、指定的服务器,打开 Management节点
69、,右击 Backup 选项,从弹出的菜单中选择Backup a Database ,则出现SQL Server Backup 对话框,如图所示:该对话框有两个选项卡:General 和Options选项卡。图14SQL Server数据库备份图 I1)在常规选项卡中,从上到下有五个区域:精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 35 页,共 45 页32 / 45 第一区域用于选择要备份的数据库。可以在数据库下拉列表框中选择将要备份的数据库名称,名称文本框用于输入备份的名称,描述文本框用于输入这次备份的描述性信息。这里选择的数据库是jxc。在
70、第二区域中,可以选择备份的类型。数据库-完全单选按钮表示执行数据库完全备份,这时备份数据库的所有文件和日志文件。我选择完全备份。在目的区域,可以指定将要使用的备份介质。在重写区域,可以指定备份的行为。追加到媒体表示这次备份附加在备份介质上原有内容之后,即仍然保留原有的备份内容。重写现有媒体表示这次备份操作将覆盖备份介质上原有的内容,即不保留原有的内容。指定的数据库是否存在(b数据库文件是否变化(c数据库文件是否兼容(d重建数据库及其相关的文件针对不同的数据库备份类型,可以采用不同的数据库恢复方法。当使用完全数据库备份恢复数据库时,系统将自动重建原来的数据库文件,并且把这些文件放在备份数据库时的
71、这些文件所在的位置,这种进程是系统自动提供的,因此,用户在执行数据库恢复工作时,不需要重新建立数据库模式结构。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 37 页,共 45 页34 / 45 5 源代码源代码:StoryQuery.cpp 文件代码:#include #pragma hdrstop #includeStoreQuery.h #pragma package(smart_init #pragma resource *.dfm TfmStoreQuery *fmStoreQuery 。/- void_fastcall TfmStore
72、Query:TfmStoreQuery(TComponent* Owner : TForm(Owner /- void _fastcall TfmStoreQuery:FormCreate(TObject *Sender / 初始化仓库下拉选项TQuery* pQuery = new TQuery(NULL 。pQuery-DatabaseName = db 。pQuery-SQL-Clear( 。pQuery-SQL-Add(select 仓库名 from 仓库清单 。pQuery-Open(。while(!pQuery-Eof cboStore-Items-Add(pQuery-Field
73、ByName(仓库名 -AsString 。pQuery-Next( 。 pQuery-Close( 。delete pQuery 。cboStore-Text = 。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 38 页,共 45 页35 / 45 edGoodCode-Text = 。edGoodPY-Text = 。 /- void _fastcall TfmStoreQuery:btQueryClick(TObject *Sender Query1-Filtered=false。/ 设置Query控件的 filter属性可以起到查询条件的
74、作用AnsiString szCon。if(edGoodCode-Text.Length(0 szCon = 货号= + edGoodCode-Text + 。if(edGoodPY-Text.Length(0 if(szCon.Length(0 szCon += and 拼音编码 like % + edGoodPY-Text + % 。else szCon = 拼音编码 like % + edGoodPY-Text + %。 if(cboStore-Text.Length(0 if(szCon.Length(0 szCon += and 仓库 = + cboStore-Text + 。els
75、e szCon = 仓库 = + cboStore-Text + 。 Query1-Filter = szCon。Query1-Filtered = true。 /- void _fastcall TfmStoreQuery:FormClose(TObject *Sender, TCloseAction &Action / 删除窗体并回收空间Action = caFree。 /- 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 39 页,共 45 页36 / 45 Right.cpp 文件代码:#include #pragma hdrstop #i
76、nclude Right.h /- #pragma package(smart_init #pragma resource *.dfm TfmRightManage *fmRightManage。/- _fastcall TfmRightManage:TfmRightManage(TComponent* Owner : TForm(Owner /- void _fastcall TfmRightManage:FormClose(TObject *Sender, TCloseAction &Action / 删除窗体并回收空间Action = caFree。 /- void _fastcall
77、TfmRightManage:Table1AfterScroll(TDataSet *DataSet / 先去除所有的权限标志for(int i=0。 iItems-Count。 i+ CheckListBox1-Checkedi = false。/ 根据选择的用户设置权限标志Query1-Close( 。Query1-SQL-Clear( 。Query1-SQL-Add(select 权限名称 from 权限清单 where 用户编号 = +Table1-FieldByName( 用户编号 -AsString+。Query1-Open(。精选学习资料 - - - - - - - - - 名师
78、归纳总结 - - - - - - -第 40 页,共 45 页37 / 45 while(!Query1-Eof AnsiString szFunName = Query1-FieldByName(权限名称 -AsString。CheckListBox1-CheckedCheckListBox1-Items-IndexOf(szFunName = true 。Query1-Next( 。 /- / 选择或去除功能权限 , 修改数据库权限清单表void _fastcall TfmRightManage:CheckListBox1ClickCheck(TObject *Sender / 没有选择用
79、户 , 退出函数if(!Table1-FieldByName(用户编号 return。/ 循环判断Query1-Close( 。Query1-SQL-Clear( 。AnsiString sql。/ 不管没有选中 , 先全部删除 , 再根据选择的情况插入sql = delete from 权限清单 where 用户编号 = 。sql += Table1-FieldByName(用户编号 -AsString + 。Query1-SQL-Add(sql。for(int i=0。 iItems-Count。 i+ if(CheckListBox1-Checkedi/选中权限 , 权限清单中插入一条
80、sql=insert into 权限清单 (用户编号 , 权限名称 values( 。sql += Table1-FieldByName(用户编号 -AsString + ,。sql += CheckListBox1-Items-Stringsi + 。Query1-SQL-Add(sql。 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 41 页,共 45 页38 / 45 Query1-ExecSQL(。Query1-Close( 。 /- StoreQuery.h 文件代码:#ifndef StoreQueryH #define StoreQ
81、ueryH /- #include #include #include #include #include #include #include #include #include /- class TfmStoreQuery : public TForm _published: / IDE-managed Components TPanel *Panel1 。TQuery *Query1 。TDataSource *DataSource1 。TLabel *Label1。TEdit *edGoodCode 。TLabel *Label2。TEdit *edGoodPY。TLabel *Labe
82、l3。TComboBox *cboStore。TDBGrid *DBGrid1 。TButton *btQuery。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 42 页,共 45 页39 / 45 void _fastcall FormCreate(TObject *Sender。void _fastcall btQueryClick(TObject *Sender。void _fastcall FormClose(TObject *Sender, TCloseAction &Action。private: / User declaration
83、s public: / User declarations _fastcall TfmStoreQuery(TComponent* Owner。 。/- extern PACKAGE TfmStoreQuery *fmStoreQuery 。/- #endif Right.h 文件代码:#ifndef RightH #define RightH /- #include #include #include #include #include #include #include #include #include #include /- class TfmRightManage : public
84、TForm _published: / IDE-managed Components TCheckListBox *CheckListBox1。TLabel *Label1。TLabel *Label2。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 43 页,共 45 页40 / 45 TTable *Table1 。TDataSource *DataSource1 。TQuery *Query1 。TDBGrid *DBGrid1 。void _fastcall FormClose(TObject *Sender, TCloseAction &
85、Action。void _fastcall Table1AfterScroll(TDataSet *DataSet。void _fastcall CheckListBox1ClickCheck(TObject *Sender。private: / User declarations public: / User declarations _fastcall TfmRightManage(TComponent* Owner。 。/- extern PACKAGE TfmRightManage *fmRightManage。/- #endif 参考文献1 梅成刚,马进德,陆正武等.C+Builde
86、r工程开发实践 M. 北京:中国铁道出版社,2003. 2 王晟.C+Builder数据库开发经典案例解读 M. 北京:清华大学出版 ,2005. 3 闪四清 .SQL Server 2000数据库管理 M. 北京:希望电子出版社, 2002. 4 赵燕, 姜薇. 基于数据仓库的化妆品销售系统的研究J. 微计算机信息 ,2007. 36:126-151. 5 林宇. 数据仓库原理与实践 M. 北京:人民邮电出版社 ,2003. 6 郝春吉 . 统计行业数据仓库构建及应用J.微机算计信息 ,2006.22:147-185. 7 陈涛 , 邓斌 . 数据仓库技术在高等学校的应用研究J.山东农业大学
87、学报 ,2005,36-4:561-594. 8 陈京民 . 数据仓库与数据挖掘技术M. 北京:电子工业出版社 ,2002. 9吕 俊 亚 . 超 市 进 销 存 管 理 系 统 的 设 计 与 实 现 探 讨 J.现 代 商 贸 工业,2008.20:(3243-272. 10 脱西萍 , 马蓉. 浅谈存货信息化管理 J.现代审计与经济 ,2007.5:17-35. 11 王建华 , 彭映辉 , 王哲等 . 基于 NET的进销存管理系统的构建与设计J. 微计算机信息,2007.3:155-177. 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第
88、44 页,共 45 页41 / 45 12 温一军 . 系统权限管理策略 J.中国科技信息 ,2005.18:43-67. 13 龚向坚 , 邹腊梅 , 左贵启 .MIS 系统权限管理研究与开发J. 福建电脑 ,2004.12:31-38. 14 晏汀 , 晏 暐, 沈 成武 等.Three Levels of Tensor TheoryJ.北 京理 工大 学学报,(256. 15 宋敬月 . 档案信息自动化系统管理若干问题的思考J. 兰台世界 ,2008.1: 37-41. 致谢这次毕业设计,使我对这四年所学的专业知识有了一个更加深刻的认识。在运用所学知识解决实际应用问题时遇到了很多困难,感
89、谢刘朋军老师耐心和热情地指导。通过大四 1年以来的刻苦学习和钻研,我终于完成了进销存管理系统中的库存管理,销售和权限管理模块的设计工作。在此论文中,我完成了数据库的设计与创建,熟练掌握了C+Builder 和SQL Server的开发工具的应用。同时对数据库的安全与管理以及备份和恢复数据库都作了比较深入的探讨。在所做的论文中,我完成了系统主窗体的设计和系统用户登录功能,并且对库存查询和权限管理模块的设计有了比较清楚的了解,使其能与其它模块协调运行。当然,论文中也存在一些不足,希望得到老师的帮助和指正。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 45 页,共 45 页