龙卷风系列(二)区域的后台管理+前端EasyUI实现基于领域驱动模型-研发项目管理

>>龙卷风系列(二)区域的后台管理+前端EasyUI实现基于领域驱动模型-研发项目管理

龙卷风系列(二)区域的后台管理+前端EasyUI实现基于领域驱动模型-研发项目管理

引言:当今社会市场竞争激烈,软件开发企业想要占据前列需要在研发管理上下功夫,“向管理要效益”已经成为软件开发企业的共识,研发项目管理在软件企业中的普及也是大势所趋。国内做软件项目管理工具的开发商翼发云近几年发展十分迅速,越来越多的软件开发企业认识到研发项目管理的重要性,能切实有效降低成本,规范软件开发流程,提高软件产品质量。国内研发项目管理系统、敏捷开发管理工具的领导品牌翼发云敏捷项目管理系统采用可视化业务流程技术,支持瀑布模型等传统软件研发项目管理,同时也支持scrum等敏捷开发流程,是理想的敏捷开发管理工具,涵盖软件项目管理工作的整个生命周期。为提高国内软件开发企业的项目管理水平,分享一篇企业管理相关的知识文章。

本项目是一个系列项目,最终的目的是开发出一个类似京东商城的网站。本文主要介绍后台管理中的区域管理,以及前端基于easyui插件的使用。本次增删改查因数据量少,因此采用模态对话框方式进行,关于数据量大采用跳转方式修改,详见博主后续博文。

后台界面展示: scrum

【tornado】系列项目(二)基于领域驱动模型的区域后台管理+前端easyui实现

地区管理包含省市县的管理。详见下文。 软件项目管理

一、数据库设计

类省(基地):”“”“”“__tablename__ = ‘province’nid =柱(整数,primary_key = true)标题栏(varchar(16),指数= true)级城市(基地):“城市”和“__tablename__”= ‘城市’ NID =柱(整数,primary_key =真实=柱(varchar)标题(16)指数= true,province_id =柱(整数),外键(’province。NID’))类县(基地):“县(区)”__tablename__ = ‘county的NID =柱(整数,primary_key = true)标题栏(varchar(16),指数=真(city_id)=柱(同城。nid’integer,ForeignKey))

  本次采用的是sqlAlchemy模块创建数据库,关于sqlAlchemy的数据库链接以及数据库创建本文不做介绍,详细见Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy(点击进入详细介绍) 敏捷开发流程

表关系分析:上述表关系比较简单,市中有外键,代表这是市是属于哪个省;同理县中也有外键,代表这个县是属于哪个市。

两。目录结构

【tornado】系列项目(二)基于领域驱动模型的区域后台管理+前端easyui实现 研发项目管理

该目录结构在前面博文【tornado】系列项目(一)之基于领域驱动模型架构设计的京东用户管理后台中有详细介绍,本博文不再赘述。

三。路由映射

(R / provincemanager美元。html”区域。provincemanagerhandler),#省份(R模板显示“/省。HTML $”,区域。provincehandler),#省份CRUD(R / citymanager .html美元区域。citymanagerhandler),#城市显示模板(R /城市。HTML美元区域。cityhandler),#,CRUD(R / countymanager .html美元区域。countymanagerhandler)#县,显示模板(R /县。HTML美元区域。countyhandler),#县CRUD

四。后台模板显示汉德勒。

#以省份为例进行介绍(市县类似):

数据获取Handler:

类provincemanagerhandler(adminrequesthandler):def get(自我,* * *中,被#):打开页面,显示所有self.render(’region / provincemanager .html”)

 本Handler主要用于从模板展示,默认如果只有这一个handler,用户看到的将是空页面。关于数据的增删改查,详见下文。

五、核心添加、删除和修改操作

再介绍增删改查之前,我们先介绍母板文件layout的前端html和继承该模板的ProvinceManager.html部分JavaScript代码:

母版layouthtml:

&lt;DOCTYPE &lt;HTML & gt!Html> < head; lang= en > &lt meta; charset= “UTF-8” > < title> < /title> < link rel= “stylesheet” type= “text/css” href= “/Statics/Admin/Plugins/jquery-easyui/themes/ default/easyui.css” &gt easyUI CSS &lt #; import link rel=; “stylesheet” type= “text/css” href= “/Statics/Admin/Plugins/jquery-easyui/themes/icon.css” > # import easyUI icon &lt link; rel= “stylesheet” type= “text/css” href= “&gt / Statics/Admin/Css/Common.css” # custom CSS < script; type= “text/javascript” src= “/Statics/Admin/Plugins/jquery-easyui/jquery.min.js” > < /script> jQuery &lt script type= # import; text/javascript “src=” /Statics/Admin/ Plugins/jquery-easyui/jquery.easyui.min.js “> < /script> # import easyUI JS < /head> < body class= “easyui-layout” > &lt div; data-options= “region:’north'” style= “height:50px” > < /div> < div data-options= “region:’south’, split:true” style= “height:30px; > < /div> < div data-options=” region:’west’, split:true “title=” admin “style=” width:200px; > < div “id=” AA “class=” easyui-accordion “data-options=” fit:true, border:false “&gt div title=”; < > #easyui custom area management “menu on the left side of the < a id=” jd_menu_province “class=” jd-menu “href=” /ProvinceManager.html “&gt Province; < /a> < a id=” jd_menu_city “class=” jd-menu “href=” /CityManager.html “> < /a> < a id= jd_me Nu_county “class=” jd-menu “href=” /CountyManager.html “&gt county (District); < /a> < /div> < div title=” user management “> < a id=” user “class=” jd-menu “href=” &gt “#; user management < /a> < a id=” jd_menu_merchant “class=” jd-menu “href=” /MerchantManager.html “> &lt /a> business management; < /div> < div title=” JD “> < a – id=” jd_menu_product “class=” jd-menu “href=” /ProductManager.html “> &lt /a> product management; < /div> < /div> < /div&gt < div; data-options=” region:’center'”title=” block {% crumbs%} {% end%} “> # content display area {% block content%} {% end%} & < /div> Lt; /body> < /html>

  省份内容展示区html:

< div> < table id= “DG” > < /table> #easyui table &lt div id= custom; “DLG” class= “easyui-dialog” style= “width:400px; height:200px padding:10px; 20px” closed= “true” buttons= “#dlg-buttons” > #easyui made a modal dialog box, the default &lt form id= closed; “FM1” &gt div class= “input-group; < > < Clearfix” div class= “group-label” style= “width: 80px; < span> > < /span> provinces: < /div> < div class=” group-input “style=” width: 300px; > < input “id=” dlg_nid “style=” width: 200px; display: none “name=” NID “/> &lt input; id=” dlg_province “style=” width: 200px “class=” easyui-te Xtbox “type=” text “name=” caption “data-options=” required:true, missingMessage:'”/&gt’ provinCES不能为空;# EasyUI表单自定义的验证错误消息+ & lt;/ DIV &gt;&lt;/ DIV &gt;&lt;/形式&gt;&lt;/ DIV &gt;&lt;div id=“DLG按钮“&gt;# EasyUI & lt跨度ID =自定义按钮;“dlg_summary”风格=“颜色:红色”&gt;&lt;跨&gt;&lt;a href =“#”class=“EasyUI LinkButton”iconcls =“图标OK”onclick=“保存”(& gt);/ &gt;&lt;&lt;a href =“#”class=“EasyUI LinkButton”iconcls =”图标取消”onclick=“$(’ # JavaScript:DLG”)。对话框(’关闭’)& gt;& lt / &gt;&lt;取消;/ DIV &gt;&lt;/格& gt;

  JavaScript代码:

(($函数){ //加载表数据(inittable);内容#初始化表(查询)(initpagination);(initmenu);#初始化初始化页面左侧菜单# });

  首先介绍两个简单的js:

/ * * /功能initmenu初始化菜单左边(){ $(’ # AA”)。手风琴(’select ‘,0);# EasyUI:语法标签(“左零美元# jd_menu_province”)。AddClass(主动的);#让省份默认}
功能initpagination(* / / *初始寻呼){ var = $(“寻呼机# DG”)。Datagrid(’getpager ‘);$(寻呼机)。分页({ beforepagetext:’文章’,afterpagetext:“页页} {页面displaymsg:当前显示{ } { }记录-从{ } })}总数据

键表数据初始化js(查询js):

功能(inittable){ $(’ # DG”)。Datagrid({标题:“iconcls:’icon-save”名单,省、省、#图标网址:/省。HTML的URL的方法:’ ‘ #数据采集模式,# / fitcolumns:真的,idfield:’nid”单选:真的,rownumbers:真正的#默认无线,#显示行号的条纹:真的,#奇数行和偶数的色彩差异列:[ [ #每列标题(根据后台数据表字段根据显示默认EasyUI){场:’ck”复选框:真正的#显示复选框},{场:’nid,NID标题:从数据库中检索# ‘id’,#显示名称ID宽度:80,80px对齐:’center”#宽度#展示中心},{场:’caption,标题:’width:180、对齐:’center”}“标题”按钮,{文字:’工具栏:[ #显示添加”按钮#名字iconcls:’icon-add ‘,#按钮图标句柄:addRow #点击按钮返回函数执行后} {。文字:’ iconcls:’icon-remove’handler:RemoveRow,删除,修改文本:“},{处理:}”,iconcls:’icon-edit ‘,EditRow,pageposition:’both ‘,#都显示分页分页:真的,#显示分页大小:10,#默认页面显示数据的书页数总数:1,#默认第一页的pagelist:[ 10,20,50 ],#分页可选数页(lOAdfilter:功能数据返回数据#滤波函数){ };});}

  上述js代码即查询时的js代码,接下来我们先看查询的后端业务处理类:

def get(自我,* * *中,被“参数args)::::::返回参数被收购:“如果self.get_argument(类型”,没有)=“”#:如果是获得所有数据RET = { ‘status”:真的,’rows”:“’summary”,“}:#将返回字典的前面。国家是否成功,包括数据采集、错误消息尝试:region_service = regionservice(regionrepository())#对象数据库加工成数据库服务协调all_province_list = region_service.get_province(RET [ ‘rows’] = #)访问所有省份all_province_list #省份数据添加到返回的除了例外为E的前端:词典[ ‘status’] = false RET RET [ ‘summary’] = str(E)self.write(json.dumps(RET))#回到其他前端:#如果是获取分页数据ret = { ‘status”:真的,综合的:0,’rows”:’summary:试试:’ } [ ],行= int(self.get_argument(’rows ‘,10))#页10页= int(self.get_argument(页,1))#显示开始的第一页(页—1)*行= = regionservice region_service(开始数regionrepository(row_list))= region_service.get_province_by_page(开始、行)#根据各省数据分页row_count = region_service.get_province_count(#)获得总数省RET [综合] = row_count RET [ ‘rows’] = row_list除了例外:RET [ ‘status ] =假RET [ ‘summary ] = str(E)self.write(json.dumps(RET))#重返前线

数据库业务协调处理类的对应操作:

类regionservice:def __init__(自我,region_repository):self.regionrepository = region_repository DEF get_province_count(自我):数= self.regionrepository.fetch_province_count(回数)#省总DEF get_province_by_page(自我,开始偏移):根据#寻呼省(开始,结果= self.regionrepository.fetch_province_by_page偏移)返回结果后,get_province(自我):#获取所有的回报(自我。regionrepository。fetch_province)省

 数据库操作类相关操作:

类regionrepository(iregionrepository):def __init__(自我):self.db_conn = dbconnection() #实例化数据库链接对象(只需创建一次对象,下面所有方法都不需要再创建),fetch_province(自我):#获取所有省份光标=自我。db_conn。connect() SQL =“”“选择NID,字幕从省通过NID desc”“光标。执行(SQL)db_result =光标。fetchall()自我。db_conn。()返回db_result DEF fetch_province_by_page(自我,开始偏移):#根据分页获取省份ret =没有光标=自我。db_conn。connect() SQL =“”“选择NID,字幕从省通过NID DESC LIMIT %s %s”“抵消”光标。执行(平方L(偏移,开始cursor.fetchall))=(db_result)self.db_conn.close(返回)db_result DEF fetch_province_count(自我):#省总光标= self.db_conn.connect(SQL)=》选择“计数(1)作为计数从省“cursor.execute(SQL)= cursor.fetchone(db_result)self.db_conn.close(返回)db_result [计数]

  以上就是查询操作的所有过程。

增加:

js:

添加功能(addRow)/ * * / / / {显示对话框,因为我想添加设置后的方法(“美元# FM1”)。形式(’清’);$ #空最后形式的内容(“# DLG”)。对话框(打开”对话框(’settitle”)。,“创建省);#设置对话框标签模式是创建$省(“# dlg_summary ‘)(空);#空错误消息的方法= ‘post”;集#提交后}

  增加操作实际上就做了一个操作:打开模态对话框。

前端页面展示:

  【tornado】系列项目(二)基于领域驱动模型的区域后台管理+前端easyui实现

当用户输入需要添加的省份,接下来点击保存按钮,数据将被写入数据库并在前端显示:

保存的js代码:

/ * * / function Save (Save button) {var isValid = $(‘#fm1’).Form (‘validate’); form if (isValid) front-end verification {$.ajax {url: (‘/province.html’URL type: METHOD, # submitted, # according to previously defined methods were submitted to data: {caption: ($dlg_province’),.Val (‘#) nid: ($’#dlg_nid'(.Val))}, dataType:’json’ # data submitted by # data format of success: function (data) {# if the back-end successfully returned data if (data.status) {$# back-end operation success (‘#fm1’).Form (‘clear’); # empty form $(‘#dlg’).Dialog (‘close’) # closed; Modal dialog $(‘#dg’).Datagrid (‘relOAd’); # relOAd data}else{$(‘#dlg_summary’).Text (data.summary); #}}} or display an error message)}else{/ / / / $} by front-end verification (‘#fm’).Form(’清’);}

  增加对应的后端业务处理方法:

DEF后(自我,*参数,**被):”参数:参数:参数:被:补充道:“回:“RET”= { ‘status”:虚假,’summary ‘:’ }标题self.get_argument(’caption ‘,没有)如果没有字幕:RET [ ‘summary’] =其他:尝试:省不能为空region_service = regionservice(regionrepository)(结果)= region_service.create_province(字幕)#创建省、各省是否已经存在,如果返回None不结果:RET [ ‘summary’] =其他:RET [ ‘status ]现有的省份# =真的只是例外E:RET [ ‘summa成功运作RY’] = str(E)self.write(json.dumps(RET))#重返前线

 数据库协调处理类对应的方法:

DEF create_province(自我描述):存在= self.regionrepository.exist_province(字幕)#首先确定是否存在如果省的方法,返回值是没有如果不存在:self.regionrepository.add_province(字幕)还真#创建省

 数据库对应操作:

DEF exist_province(自我描述):光标= self.db_conn.connect #省份存在(SQL)=》选择“计数(1)作为计数从省标题= %s”和“cursor.execute”(SQL,(标题,db_result))= cursor.fetchone(自我。db_conn。关闭)(返回)db_result [ count”],add_province(自我描述):#创建光标= self.db_conn.connect(SQL)省=“”插入省(字幕)值(%)”(SQL,effect_rows = cursor.execute(标题、自我。db_conn。关闭)effect_rows(回))

  以上就是省份添加的全部过程。

修改:

实际上修改和添加基本上是一样的,接下来只介绍与添加不同的地方:

js:

功能(editrow)/ * * /修改{ //显示对话框,因为你想要修改的放/设置方法获得所选择的值,它指定的网页,然后提交Ajax无功行(“# DG的)=美元。DataGrid($ ‘getselected ‘(’);# dlg_summary ‘)(空);如果(行){方法=火”;(“# FM1的美元)。形式(’清’);$(’ # FM1”)。形式(载荷、行);$(’ # DLG”)。对话框(打开”对话框)。(’settitle ‘、’ }否则{ $。messager.alert ‘修改省);(’警告’,’请选择要修改的行,’warning ‘);} }

  这里弹出模态对话框,与添加不同的是,修改需要将用户原有数据存放在input标签中,方便用户进行修改。同时,将提交方法修改为put。

修改模态对话框示例截图:

【tornado】系列项目(二)基于领域驱动模型的区域后台管理+前端easyui实现

接下来用户修改完成后的点击保存,关于保存的js代码详见上文添加部分。

保存的后台业务处理handler方法:

DEF把(自我,* * *中,被“args参数)::::::返回参数被更新:“RET”= { ‘status”:虚假,’summary ‘:’ } NID = self.get_argument(’nid ‘,没有)标题self.get_argument(’caption ‘,没有)如果没有字幕或没有标识:RET [ ‘summary’] =”不能为空,其他省份:试试:region_service(regionrepository)= regionservice(结果)= region_service.modify_province(NID,字幕)如果没有结果:RET [ ‘summary’] =其他:RET [ ‘status ]现有的省份已除例外:RET [ ‘summary ] =真实= str(E)self.write(json.dumps(RET))

  该方法与添加时的方法基本一致,这里不做过多介绍。

数据库协调处理类对应的方法:

DEF modify_province(自我,NID,字幕):存在= self.regionrepository.exist_province(字幕)如果不存在:self.regionrepository.update_province(NID,字幕)#更新还真省

数据库操作对应类的方法:

DEF update_province(自我,NID,字幕):光标= self.db_conn.connect(#更新省)SQL =“更新省设置标题= %s,NID = %s”(SQL,effect_rows = cursor.execute(标题、NID,自我。db_conn。关闭)effect_rows(回))

  以上就是省份数据修改的全部过程。

删除:

js:

功能(removerow)/ * * /删除{ //采集已被选定为无功行=(美元的# DG”)。Datagrid(’getselections ‘);console.log(行);如果(行。长度&lt;= 0){ //美元。messager.alert(警告框’警告’,’请选择要删除的行”warning”}人(如果);行。长度& gt;1){ $。messager.alert(“警告”,“不支持批量删除’);// } {美元其他复选框。messager.confirm(“好吧”,“你确定要删除吗?’, function (status) to confirm the custom box if {#easyui (status) {/ / / / click OK to get the current value of the selected row, Ajax is sent to the background var row = rows[0]; $.ajax {url:’province.html’, type: (‘delete’data:, {nid: row.nid}, dataType:’json’, success: function (data) if (data.status) {{the success of $.messager.show ({#easyui / / delete custom messager box msg:’ Delete success, showType:’slide’, # out of showSpeed: 500, timeout: 5 # speed, # display 5 seconds style:{right:”, top:document.body.scrollTop+document.documentElement.scrollTop, bottom:”}} # display at the top of the screen); / / relOAd table var rowIndex = $(‘#dg’).Datagrid (‘getRowIndex’, row); $(‘#dg’).Datagrid (‘deleteRow’, rowIndex); $(‘#dg’).Datagrid (’relOAd ‘);//删除指定行(’getrowindex ‘,开始= / /无功dt.datagrid行);/ / dt.datagrid(’deleterow”开始);// }否则{ //美元。messager.alert(删除失败’错误’,数据总结,错误”);messager.show(#美元。{显示错误图标:错误的标题:“错误信息,味精:data.summary,显示类型:’slide,超时:0、风格:{右:”,顶部:文档。身体。scrollTop + document.documentelement.scrolltop,底:’);}}}}}}})} });

  后台handler类对应方法:

DEF删除(自我,* * *中,被“参数args)::::::返回参数被删除:“RET”= { ‘status”:虚假,’summary ‘:’ } NID = self.get_argument(’nid ‘,没有)如果没有标识:RET [ ‘summary’] = ‘选择删除其他:#呼叫服务删除…#如果删除失败,则显示错误信息的尝试:region_service = regionservice(regionrepository)(region_service。delete_province)(NID)#根据NID =真除例外RET [ ‘status ]省删除电子邮件:RET [ ‘summary’] = str(E)self.write(json.dumps(RET))

  数据库业务协调处理类对应的方法:

DEF delete_province(自我,NID):self.regionrepository.remove_province(NID)

  数据库操作类对应方法:

DEF remove_province(自我,NID):光标= self.db_conn.connect()语句”“删除从省哪里哪里”“”“= =”(“(”、“)”)

  以上就是删除的全部过程。

总结:本文主要以省份的增删改查为例介绍了前端easyui的使用,后端handler、数据库业务协调处理类、数据库操作类的整个流程。下节我们将介绍市县管理中与省份不同的部分,欢迎下次收看!如果本文对您有参考价值,欢迎帮博主点下文章下方的推荐,谢谢!

文章从互联网整理而来,旨在传播scrum、软件项目管理、研发项目管理、敏捷开发管理工具的知识与应用,帮助软件开发企业真正了解研发项目管理的价值和意义,如果本文侵犯了您的权益或者您需要具体了解更多国内做研发项目管理系统的公司翼发云敏捷项目管理系统的相关信息,欢迎和我们联络:

【网址】www.effapp.com

2018-03-01T05:45:26+08:002018-03-01 05:45:26|Categories: scrum项目管理|