一、登录页面
1.加载单位信息
登录页面加载时会先调用Scripts/Application/LoginApp.js中383行$scope.Fn.Clear.Select("City.Left")方法清除市级“左边的下拉选择框”(这样是为了防止某个单位如市级有两个选择框而设计的),然后接着调用$http.get方法,向后台Login/Read方法(参数unitcode即为要获取下级单位的本级单位代码)获取该单位的所有下级单位,在获取相应的数据后,将各下级单位信息存放在各自命名空间下的Select变量里,如District.City.Left.Select、District.County.Select。
以上主要介绍了登录页面的控制器,该控制器使用的模板是Views/Release/Login.html,在该模板中通过Attr.Login.Quick.Enable属性控制普通登录(260行Normal方法)和快速登录(256行Quick方法),各市、县的下级单位数据都跟相应的Select标签绑定在一起。
2.点击登录
点击登录时调用249行In方法,该方法用于区分普通登录、快速登录并调用各自的方法获取所选择的单位信息,最后调用292行Validate方法,将用户信息发送给后台Login/Validate方法验证,验证失败时提示错误消息,通过后将单位信息写入到浏览器的Cookie里并跳转到相应的界面(省、市、县跳转到主界面,乡镇跳转到独立的乡镇页面)。
二、主界面
主界面主要负责展示洪涝系统各个主要功能,主要有洪涝报表功能、蓄水报表功能、历年灾情、统计分析、基础数据、系统维护功能,因这些功能在页面都是以链接的方式显示的即点击相应的功能会跳转到对应的路由里。所以这些功能的实现方式很简单,在此不做阐述。
最后,该页面所用的模板是Views/Release/Main.cshtml。
三、新建页面
1.左侧报表树的加载
在访问该页面时会先进入Scripts/Controller/IndexController.js中4350行IndexNewCtrl控制器,并执行该控制器中的代码。该段代码首先获取新建页面的命名空间即$scope.New,该命名空间其实就是597行整个$rootScope.New对象,获取命名空间并给它去一个别名$CurrentScope,然后调用43行InitTree方法实例化一个RptTypeTree即表类树形菜单,并绑定各节点的onClick事件,通过点击选择菜单进入onClick方法变换所选择的条件。
2.新建报表
主要有三种报表的新建即洪涝报表、湖南蓄水报表、内蒙古蓄水报表,这些报表的新建都是调用同一个方法即Scripts/Controller/IndexController.js中651行CreateReport方法,该方法会根据所选择的信息生成一套新的空表,这里还有一个地方需要说一下,就是在新建这些报表切换选择条件时都会调用同一个方法即607行Search方法搜索历史建表信息。该页面所用的模板是Scripts/Templates/Index/New.htm。
新建这些报表时,在选择各个条件后点击新建按钮时调用651行CreateReport方法,在该方法中先请求后台Index/GetReportTitleInfo方法获取最近的报表,然后回调进入700行fn方法生成一套新的空表,这里需要注意的是如果新建内蒙古蓄水报表时会先调用后台Index/NP_Operate方法在数据库中创建一个空的报表并将该表的页号返回给前台使用(保存时后台的处理方式只是Update,因为内蒙古蓄水省、市、县用的都是同一张表)
在CreateReport方法创建新的空表后,通过代码RedictUrl("/Open")定向到打开页面,并将新建的空表通过参数Params["Open"]传过去。
四、打开页面
1.左侧报表树的加载
在加载打开页面时会先调用Scripts/Directives/PublicDirective.js中1行ngTree指令,然后依次调用一下方法。
1)调用IndexController.js中3687行NodeState方法记录或者还原之前的报表数的收展状态,第一次默认只展开今年的年份节点,去年报表的节点收起来。
2)调用IndexController.js中3600行Report方法生成当前的报表树,在该方法中主要区分我的表箱报表树、已收表箱报表树,前者点击报表时调用$scope.Open.Report.Fn.Core.Open方法打开报表,后者调用$scope.Fn.ViewUnderRpt方法在弹出的新窗口打开报表,最后调用CheckBox方法根据当前报表的类型显示或隐藏复选框checkbox。
2.打开报表
打开报表的方式有以下三种。
1)在左侧报表树打开本级报表,点击报表时会调用IndexController.js中2035行Open方法(参数obj是一个包含报表页号等信息object对象),在该方法中,会先判断之前是否打开过该报表,如果之前打开过则直接从$rootScope.Open.Report.Opened属性里读取该报表,若没有则请求后台 Index/OpenReport方法获取报表数据然后在模板里显示。
2)在收表箱打开下级报表,点击报表时进会调用IndexController.js中213行ViewUnderRpt方法(参数obj包含待打开的报表信息),然后根据参数生成一串get请求的url:Index/ViewUnderReport?……并在弹出的新窗口中打开该url请求后台获取获取数据并打开报表。
3)打开新建页面新建的报表,之前说了新建报表后会将新建好的空表通过参数Params["Open"]传过来,并跳转到打开页面,在跳转到打开页面时会先进入IndexController.js中4384行IndexOpenCtrl控制器并执行该控制器中的代码,在该段代码中通过switch分支语句区分蓄水、洪涝的新建、打开,新建时$scope.Params["Open"].method为Create。
该页面所用的模板文件是Scripts/Templates/Index/Open.htm。各种类型的报表所用的模板分别是
1)洪涝报表表1至表9所有表格的模板文件全在Scripts/Templates/Public/HL/Table文件夹下,在该Table文件中分别有根据数字1~9命名的子文件夹,分别表示表1~表9,例如名字为1的文件夹表示表1,在表1文件夹下有以单位代码(前2位)命名的子文件夹并有一个通用Common文件夹,这样设计的用意是,如果某个单位的表格有变化可根据其单位代码创建相关文件夹,这样在读取THead.htm、TBody_Edit.htm(编辑)、TBody_View.htm(预览)时会优先到该文件夹中找,如果没找到再使用通用Common文件夹下的相关文件,其它表格也都是这么设计的,所以在此不一一阐述。
2)山洪报表的模板都在Scripts/Templates/Public/SH/Table文件夹下,这里的文件夹设计不像洪涝报表那样,所以比较简单,故不再介绍了。
3)蓄水报表的模板都在Scripts/Templates/Public/XS/Table文件夹下,该文件目前主要有2各子文件夹即15、43分别表示内蒙古蓄水模板、湖南蓄水模板。
3.保存报表
点击保存时调用IndexController.js中2498行Call方法,通过该方法区分开各省洪涝保存、蓄水保存后调用2590行RelationCheck方法校验待保存的报表数据是否规范、完整,校验通过后再调用2837行Save方法处理洪涝、蓄水待保存的数据并发送给后台Index/SaveUpdateReport保存。
Call方法参数:
fnName:回调的方法名
queryExcute:默认为false,是否查询并调用各个省份重写的方法
param:调用指定的方法时传入的参数。
RelationCheck方法参数:
leftField:等式左边即被校验的字段名
rightVal:leftField的值,基础数据校验时用到即rightVal不能超过某个值
sumType:是百分比运算,还是简单的加、减运算
fixed:数值的保留位数
formulaType:校验类型,如a<20、a = b+c、a <= b+c+d
report:被校验的报表
Save方法参数:
type:保存类型,是复制保存还是仅保存
rpt:通过校验的后报表
4.另存为数据表
点击时调用IndexController.js中2837行Save方法,第一个参数type为‘Copy’,第二个参数rpt为空,表示复制当前的报表为一个副本并发送给后台Index/SaveUpdateReport保存。
5.导出
点击导出时直接在页面上打开一个新窗口并访问该该导出按钮a标签的href属性对应的url(导出处理的比较简单,该导出按钮其实就是一个a标签,href属性就是下载地址),如ReportOperate/ExportExcel?pageno=1847&rpttype=HL01&sTime=2017-4-13&eTime=2017-4-13,参数:pageno为页号、rpttype为表类、sTime为报表开始时间、eTime为结束时间。
6.灾情综述
点击时调用IndexController.js中1393行ReportDetails方法,该方法的处理有以下几种情况。
1)如果是广西(单位代码:45000000)、四川(51000000)只直接访问后台BaseData/ExportDisasterReview?report=...下载Word版灾情综述,后台处理原理是利用邮件合并生成Word文档,其中四川灾情综述Word里有饼状图,饼状图生成原理是先在前台某个页面隐藏的div中根据现有数据生成饼状图,生成后该div下有一个叫svg的标签,然后把整个svg标签获取并传给后台,后台SVG.dll根据传过来的svg代码生成饼状图并保存在服务器,保存完成后再插入待导出的Word文档里然后一起下载。
2)如果不是以上单位,则直接访问后台Index/ReportData方法,根据单位代码返回对应的页面,例如,如果当前单位是内蒙古(单位代码:15000000)则返回Views/Release/ReportDetails/HL01/15.html页面,如果是浙江省33000000则后台返回.../33.html,如果是其它单位(如湖南)则返回Common.html
7.流域数据
该功能只有省级才有,当点击时调用IndexController.js中1819行ViewRiverData方法,在该方法中先判断之前是否打开过流域数据,如打开过直接从当前报表的RiverData属性读取,若没有请求后台Index/GetRiverPageNOByPageNO获取当前行政表下各流域表的页号,然后在页面上显示一个对话框,对话框中显示的便是各流域报表,点击对话框中的流域表时,会调用前台212行ViewUnderRpt方法,该方法请求后台Index/ViewUnderReport已查看下级表的方式打开流域表。
8.打印
点击打印时,调用Scripts/Others/Print.js中15行printClick方法,该方法通过Jquery拷贝父窗口待打印的表格显示在本窗口的打印页面中,然后调用浏览器自带的print方法打印。该页面所用的模板是Views\Release\Print.html。
9.增加行
该功能只有洪涝表表5、表6才有,点击增加行时调用IndexController.js中840行AddRow方法,直接追加一条新纪录到$rootScope.Open.Report.Current.HL012数组里,然后根据angular的绑定原理页面会创建一个新的tr,如果是表6点击增加行则在$rootScope.Open.Report.Current.HL013数组里新增一条记录。
10.删除行
该功能同样只有洪涝表表5、表6才有,点击时调用IndexController.js中1516行DelRow方法,删除用户信息。
11.删除
该删除功能不是真的删除报表而是标记ReportTitle表中Del字段为1表示删除,真正删除报表的操作在回收站里。当点击删除时调用IndexController.js中1479行Report方法,该方法将当前报表信息传递给后台Index/DeleteReport方法标记删除当前报表。
12.粘贴
打开或新建一张空表有粘贴功能,该粘贴功能是通过jquery的live("paste")方法实现的。当系统加载时会执行Scripts/Others/IndexReady.js中68行paste方法绑定表格粘贴事件。
13.国统表
该功能只有湖南省蓄水报表才有,主要用于导出各单位的大型水库、中型水库、小(I)型水库、其他水库的需水量、常年同期需水量的数据到Excel中,点击时其实是点击一个a链接,可通过浏览器右键审查“国统表”的按钮元素,这个按钮其实是个下载链接,该链接是根据当前报表的页面及类型自动生成的,如ReportOperate/ExportExcel?pageno=5818&rpttype=GT,点击时则在新窗口直接访问这个链接下载生成的国统表。
14.通报
该功能只有湖南省蓄水报表才有,主要用于分析实际蓄水量、计划蓄水量,点击时调用IndexController.js中1395行ReportDetails方法,在该方法中检测到当前报表是蓄水时,将当前蓄水表的信息发送给后台Index/ReportData方法处理,处理完后返回Views/Release/ReportDetails/HP01/Common.cshtml动态文件显示蓄水信息。
15.加表
该功能主要用于累计、汇总,在打开页面左侧报表树选择好报表后点击加表时调用IndexController.js中878行Sum方法加表,该方法通过左侧报表树查询出勾选的报表信息,然后将这些报表信息发送给后台Index/SummaryReport方法该方法处理完后返回一个运算后的“总表”,然后前台接收这个“总表”并显示在页面上,完成这次加表操作。
16.减表
减表跟加表一样只有累计汇总的时候才会用到,点击时调用IndexController.js中1097行Sub方法减表,该方法在左侧报表树获取所选择的报表信息后将这些信息传递给后台Index/SummaryReport方法进行运算并返回运算后的“总表”,然后前台接收这个“总表”并显示在页面上,完成这次减表操作。
五、接收页面
该页面有三个表箱,其中收表箱自动收集下级已发送的报表(ReportTitle表State字段值为3并且ReceiveState字段值为0,在打开接收页面时默认搜索一次收表箱)、已收表箱用于存放在收表箱已装入的报表(State字段值为3、ReceiveState字段值为2)、拒收表箱用于存放在收表箱中被拒收的报表(State字段值为3、ReceiveState字段值为1),各个表箱切换时搜索也会自动执行,三个表箱调用的搜索方法均为IndexController.js中364行Server方法,该方法处理完参数后调用后台Index/InboxRecycleSearch方法为各表箱搜索相应的报表。
各表箱均有相应的操作,其中接收表箱有删除、装入、拒收操作,已收表箱只有删除操作,拒收表箱有删除、恢复操作,因这些操作都是通过更改ReportTitle表receivestate字段值来实现的,所以它们都调用同一个方法即IndexController.js中3960行Operate方法,该方法只接受一个参数action即操作类型,在处理好各参数后将更改请求发送到后台Index/ReportOperate方法更改数据库,这里有一个需要注意的地方就是如果是收表箱拒收操作,则在拒收请求处理完成后,还需要通过后台UrgeReport/AddUrgeReport方法给被拒收的单位发送一个拒收消息。该页面所用的模板是Scripts\Templates\Index\Receive.htm。
六、回收站页面
回收站功能比较简单,搜索条件跟接收页面一样,只是表箱只有本级单位、下级单位两个表箱,这两个表箱里面的表均可以删除、恢复且这两个操作都是调用IndexController.js中4169行Operate方法,参数Type即为操作类型,如删除 Delete、恢复Resume。该页面所用的模板是Scripts\Templates\Index\RecycleBin.htm。
七、催报页面
催报的页面相对其它页面来说功能很简单,该功能是选择单位并填写催报内容后发给消息被催报的单位,页面上的“未选择”和“已选择”选择框都是通过同一个jquery插件来实现的,但是此插件要集成angularjs中,所以这个jquery插件被封装到了一个指令中即Scripts/Directives/Index/IndexDirective.js中17行mutiselect指令,该页面所使用的模板是Scripts/Templates/Index/UrgeReport.htm。
八、历年灾情页面
历年灾情只有一个页面,且该页面的功能比较简单,左侧是报表树,点击报表时,在右侧打开报表,被打开的报表都是只读的,然后可对这些只读的报表打印、导出等操作,这些功能其实跟打开页面的报表树打开报表一模一样,但是没有那么多复杂的功能,所以历年灾情的页面所用到的脚本Scripts/Controllers/HistoryDisasterController.js跟打开页面所用到的脚本Scripts/Controllers/HistoryDisasterController.js在某些程度上很相似。
一开始进入历年灾情时,会先加载左侧的报表树,报表树加载时跟打开页面一样会先调用Scripts/Directives/PublicDirective.js中1行ngTree指令,然后依次执行Tree.Refresh.NodeState方法还原、记录报表树的收展状态,然后调用Tree.Refresh.Report生成报表树,并在生成时绑定我的表箱、已收表箱的打开方法,前者点击报表时调用IndexController.js中2035行Open方法,后者则调用IndexController.js中213行ViewUnderRpt方法,如果想更详细的了解,可参考打开页面相关功能,最后该页面所用的模板是Scripts/Templates/HistoryDisaster/Main.htm。
九、基础数据
在主界面点击基础数据时,会弹出一个对话框,这个对话框对应的HTML标记其实就隐藏在Views/Release/Main.cshtml中的一个id为“Dialog”的div,控制显示、隐藏的脚本在Scripts/Application/MainApp.js中,在弹出的对话框中输入密码“zizo”即可进入基础数据功能
在进入基础数据页面后,执行Scripts/Controllers/BaseData/BaseDataController.js中340行MainCtrl控制器中的代码初始化单位树。
1.基础数据
该页面主要用于设置各个单位的某些指标的最大值,当选择某个单位并设置该单位的基础数据后点击保存调用Scripts/Controllers/BaseData/BaseDataController.js中172行Save方法将设置好的后基础数据发送给后台BaseData/SaveBaseData方法更新到数据库中。
2.蓄水数据
该页面只有湖南省才有,主要用于更改各时间的各单位的需水量,在选择时间之后,会有一个列表显示该时间各个单位的蓄水数据,更改后点击保存调用Scripts/Controllers/BaseData/BaseDataController.js中35行Save方法直接将更改的数据发送给后台BaseData/UpdateHpData方法更新到数据库中。
3.单位管理
该页面主要用于增加、删除、更改、重置单位信息。
1)新增单位,点击新增时调用252行New方法插入一条新纪录到$scope.Unit.Unders.Array数组里,然后更具angular的绑定原理,视图会新建一个tr供用户输入新的单位信息。
2) 更改单位,当在左侧单位树选择某个单位后,单位管理页面会加载所选择的单位的所有下级单位,然后直接在页面上更改即可,更改完点击保存即可。
3)删除单位,当光标移到每个单位记录最后一列的右边框外时会显示删除和重置图标,点击删除时调用265行Delete方法将要删除的信息发送给后台BaseData/DeleteUnit方法在数据库中删除
4)重置单位,这里重置功能仅仅是重置所选择的单位的登录密码,重置的选择有重置本级、重置所有下级单位、或在显示的某个下级单位后面点击浮现的出重置按钮重置该单位的登录密码,不管是哪种重置方式都是调用282行Reset方法将待重置的单位信息发送给后台BaseData/ResetPassword方法重置单位登录密码。
十、系统维护
该功能只有省级才有,同时该页面只有一个功能即利用拼写的sql语句备份数据,点击时调用Scripts/Application/SystemManintain.js中26行mouseup方法请求后台SystemMaintain/BackupData方法备份数据库。
十一、其它功能
1.返回主界面
该功能比较简单,在各个页面点击时都是调用Scripts/Others/Head.js中9行BackToMain方法将url变为“/main”以达到返回主界面的目的。
2.退出
该同能同返回主界面一样点击时调用Scripts/Others/Head.js中4行Exit方法退出到登录页面。
3.更改密码
点击时调用IndexController.js中245行UpdatePassword方法,该方法通过调用$rootScope.Dialog组件显示一个对话框,该组件用的模板是Scripts/Templates/Public/Dialog.htm,在显示的对话框中输入新的密码后点击确认修改时调用IndexController.js中257行CallBack方法,将通过验证后的信息发送给后台Head/ModifyPwd方法更改密码。