常规功能和模块自定义系统 (cfcmms)—019自定义grid方案(3)

原创 2015年11月20日 11:27:09

常规功能和模块自定义系统 (cfcmms)—019自定义grid方案(3)


  这一节开始进入自定义的内部,来看看第一个自定义的功能是如何实现的。
  
  1、在系统登录的时候,将所有的登录用户有权限的模块定义信息全部发送到前端。这段代码在app/view/main/MainModel.js中。在MainModel创建的时候,通过会发送一个同步的ajax请求来获取数据。取得数据后将所有的module信息放到MainView的data中。
						Ext.Ajax
								.request({
									url : 'applicationinfo.do',
									async : false, // 同步
									success : function(response) {
										var text = response.responseText;
										var applicationInfo = Ext.decode(text, true);
										applicationInfo.tf_previewExts = applicationInfo.tf_previewExts
												.split(',');
										for (i in applicationInfo.modules) {
											var moduleinfo = applicationInfo.modules[i];
											for (j in applicationInfo.roleInfo.tf_userRoleDetails) {
												if (applicationInfo.roleInfo.tf_userRoleDetails[j].tf_moduleId == moduleinfo.tf_moduleId) {
													//加入每个模块的权限信息
													moduleinfo.tf_userRole = applicationInfo.roleInfo.tf_userRoleDetails[j];
													break;
												}
											}
											if (!moduleinfo.tf_userRole)
												moduleinfo.tf_userRole = {};
											// 给每个模块创建一个ModuleInfo的模块信息类
											me.data.modules.add(moduleinfo.tf_moduleName,
													new Ext.create('app.module.ModuleInfo', moduleinfo));
										}
										delete applicationInfo.modules;
										delete applicationInfo.roleInfo.tf_userRoleDetails;
										Ext.apply(me.data, applicationInfo);
									}
								});
  “省份”模块的所有从后台加载过来的数据如下图所示:


  2、在创建模块显示的时候,会根据tf_gridSchemes中的定义来生成grid的columns。在app/module/factory/中建立了一个columnsFactory.js用来根据模块的grid的定义来生成columns。其主要的一段代码如下:
						/**
						 * module是模块的字义,schemeOrderId 为要生成的columns的 顺序号,不指定顺序号,则默认第一个方案
						 */
						getColumns : function(module, schemeOrderId) {

							var scheme = module.getGridScheme(schemeOrderId);

							var columns = [];
							// 是否有附件,有附件则加入附件按钮
							if (module.tf_hasAttachment
									&& module.tf_userRole.tf_attachmentBrowse)
								columns.push({
									locked : true,
									xtype : 'attachmentnumbercolumn'
								});

							// 是否模块具有审核功能
							if (module.tf_hasAuditing) {
								columns.push({
									locked : true,
									xtype : 'auditingactioncolumn'
								});
							}
							// 是否模块具有审批功能
							if (module.tf_hasApprove) {
								columns.push({
									locked : true,
									xtype : 'approveactioncolumn'
								});
							}

							// 是否模块具有支付功能
							if (module.tf_hasPayment) {
								columns.push({
									locked : true,
									xtype : 'payoutactioncolumn'
								});
							}
							// 如果是附件模块,加一个可以预览的列
							if (module.tf_moduleName == '_Attachment') {
								columns
										.push({
											dataIndex : 'tf_attachmentId',
											text : '预览',
											align : 'center',
											menuDisabled : true,
											sortable : true,
											width : 56,
											resizable : false,
											renderer : function(val, rd, model) {
												if (model.get('tf_filename'))
													return '<img height="16" width="16" src="attachment/preview.do?id='
															+ model.get('tf_attachmentId') + '" />';
												else
													return '<img height="16" width="16" src="" />';
											}
										});
							}
							// 如果模块有记录icon,则加入记录字段icon列
							if (module.tf_hasRecordIcon){
								columns.push({
									xtype : 'recordiconcolumn'
								})
							}
							
							for ( var i in scheme.tf_schemeGroups) {
								var sg = scheme.tf_schemeGroups[i];
								// 是否需要分组
								var isgroup = sg.tf_isShowHeaderSpans;
								var group = {
									gridGroupId : sg.tf_gridGroupId,
									text : sg.tf_gridGroupName,
									locked : sg.tf_isLocked,
									columns : []
								};
								for ( var j in sg.tf_groupFields) {
									var gf = sg.tf_groupFields[j];
									var fd = module.getFieldDefine(gf.tf_fieldId);
									var field;
									if (fd) {
										if (fd.tf_isHidden)
											continue;
										field = this.getColumn(gf, fd, module);
									} else { // 如果不是本模块的基本字段,那么在附加字段中找(可能是父模块,祖父模块的字段,或者子模块的聚合字段)
										var fd = module.getAdditionFieldDefine(gf.tf_fieldId);
										field = this.getColumn(gf, fd, module);
										if (field.dataIndex.search('C_') == 0) {
											field.moduleName = field.dataIndex.slice(2);
											field.renderer = this.childCountFieldRenderer;
										}
									}
									field.locked = sg.tf_isLocked || gf.tf_isLocked;
									// 如果列显示字段有附加的属性,如renderer 可以放在这里加入进去
									if (gf.tf_otherSetting) {
										try {
											eval('Ext.apply(field,' + gf.tf_otherSetting + ')');
										} catch (err) {
										}
									}
									if (isgroup) {
										this.canReduceTitle(group, field);
										group.columns.push(field);
									} else
										columns.push(field);
								}
								if (isgroup) {
									this.canReduceTitle(group, field);
									columns.push(group);
								}
							}

							console.log(columns);

							return columns;
						}

  上面这段代码首先根据模块的设置,判断是否有一些独立的信息显示字段,例如附件、图标、预览列等。然后将gridScheme中的分组定义依次加入到columns中。在加入的时候还要判断是否显示分组。
  这里处理了一个title显示的问题,例如有个分组的名称叫:“本年”,而分组下的字段名叫 “本年新增金额”,那么字段名中的“本年”将是可以被省掉的,下面的函数用来处理这个操作。
						// 看看分组名称是不是 下面column 的开头,如果是开头的话,并且columntitle 后面有内容,就把
						// 相同的部分截掉
						canReduceTitle : function(group, field) {
							if (field.text.indexOf(group.text) == 0) {
								field.text = field.text.slice(group.text.length).replace('(',
										'').replace(')', '').replace('(', '').replace(')', '');
								if (field.text.indexOf("<br/>") == 0)
									field.text = field.text.slice(5);
							}
						},

  如果一个字段有计量单位,那么需要在表头里显示一下。
						getTextAndUnit : function(fd) {
							var result = fd.tf_title.replace(new RegExp('--', 'gm'), '<br/>');// title中间有--表示换行
							var unitText = Ext.monetary.unitText === '个' ? ''
									: Ext.monetary.unitText;
							if (fd.tf_isMonetary && Ext.monetaryPosition === 'columntitle') {// 可能选择金额单位千,万,百万,亿
								if (fd.tf_unitText || unitText)
									result += '<br/><span style="color:green;">(' + unitText
											+ (fd.tf_unitText ? fd.tf_unitText : '') + ')</span>';
							} else {
								if (fd.tf_unitText)
									result += '<br/><span style="color:green;">('
											+ fd.tf_unitText + ')</span>';
							}
							return result;
						},

  其中还有一个 getColumn函数是用来生成每一列的定义的。
						/**
						 * 根据groupField,fieldDefine的定义,生成一个column的定义
						 */
						getColumn : function(gf, fd, module) {

							var field = {
								filter : {},
								maxWidth : 800,
								fieldDefine : fd,
								gridFieldId : gf.tf_gridFieldId, // 加上这个属性,用于在列改变了宽度过后,传到后台
								sortable : true,
								text : this.getTextAndUnit(fd),
								dataIndex : (fd.baseField || fd.tf_aggregate) ? fd.tf_fieldName
										: fd.manytoone_TitleName
							};

							if (fd.tf_tooltipTpl) {
								field.tooltipTpl = fd.tf_tooltipTpl; // 显示在字段值上的tooltip的tpl值
								field.tooltipXTemplate = new Ext.XTemplate(fd.tf_tooltipTpl);
							}
							if (gf.tf_ishidden)
								field.hidden = true;
							// 如果是此人可以审批的字段,那么加上一个可以审批的标记
							if (module.tf_hasApprove
									&& module.tf_userRole.tf_approveOrder >= 1) {
								if (field.dataIndex.indexOf('tf_sh') == 0
										&& field.dataIndex.substr(field.dataIndex.length - 1, 1) == module.tf_userRole.tf_approveOrder)
									field.text = '<span class="approvethisgridheadicon" >'
											+ '<img src="images/approve/approve_edit.png" />'
											+ fd.tf_title + '</span>';
							}
							
							switch (fd.tf_fieldType) {
							case 'Image':
								Ext.apply(field, {
									xtype : 'imagecolumn',
									align : 'center',
									width : 100,
								});
								break;
							case 'Date':
								Ext.apply(field, {
									xtype : 'datecolumn',
									align : 'center',
									width : 100,
									renderer : Ext.util.Format.dateRenderer
								});
								break;

							case 'Datetime':
								Ext.apply(field, {
									xtype : 'datecolumn',
									align : 'center',
									width : 130,
									renderer : Ext.util.Format.dateRenderer
								});
								break;

							case 'Boolean':
								field.xtype = 'checkcolumn';
								field.stopSelection = false;
								field.processEvent = function(type) {
									if (type == 'click')
										return false;
								};
								break;
							case 'Integer':
								Ext.apply(field, {
									align : 'right',
									xtype : 'numbercolumn',
									tdCls : 'intcolor',
									format : '#',
									renderer : Ext.util.Format.intRenderer
								});
								break;
							case 'Double':
								Ext.apply(field, {
									align : 'right',
									xtype : 'numbercolumn',
									width : 110,
									renderer : Ext.util.Format.floatRenderer
								});
								break;
							case 'Float':
								Ext.apply(field, {
									align : 'right',
									xtype : 'numbercolumn',
									width : 110,
									renderer : Ext.util.Format.floatRenderer
								});
								break;
							case 'Percent':
								Ext.apply(field, {
									align : 'center',
									xtype : 'widgetcolumn',
									width : 110,
									// renderer : Ext.util.Format.percentRenderer
									widget : {
										xtype : 'progressbarwidget',
										animate : true,
										textTpl : [ '{percent:number("0")}%' ]
									}
								});
								break;
							case 'String':
								if (module.tf_nameFields == fd.tf_fieldName)
									Ext.apply(field, {
										text : '<span class="fa fa-key"> ' + fd.tf_title
												+ '</span>',
										renderer : Ext.util.Format.nameFieldRenderer,
										summaryType : 'count',
										summaryRenderer : function(value) {
											return Ext.String.format('小计 ( {0} 条记录)', value);
										}

									});
								else
									Ext.apply(field, {
										renderer : Ext.util.Format.defaultRenderer
									});

								break;

							default:
								Ext.apply(field, {
									renderer : Ext.util.Format.defaultRenderer
								});
								break;
							}

							if (fd.s) { // tf_allowSummary
								Ext.apply(field, {
									hasSummary : true,
									summaryType : 'sum'
								});
							}
							// 如果是可以改变显示单位的数值,可以选择万,千,百万,亿
							if (fd.tf_isMonetary)
								field.renderer = Ext.util.Format.monetaryRenderer;
							if (gf.tf_columnWidth > 0)
								field.width = gf.tf_columnWidth;
							else if (gf.tf_columnWidth == -1) {
								field.flex = 1;
								field.minWidth = 120;
							}
							if (fd.manytoone_TitleName) {
								var pmodule = app.modules.getModuleInfo(fd.tf_fieldType);
								var icon = '';
								if (pmodule && pmodule.iconURL)
									icon = '<img src="' + pmodule.iconURL + '" />';
								Ext.apply(field, {
									renderer : Ext.util.Format.manytoOneFieldRenderer,
									text : '<span class="gridheadicon" >' + icon + fd.tf_title
											+ '</span>',
									manytooneIdName : fd.manytoone_IdName,
									moduleName : fd.tf_fieldType
								});
							}
							// 如果一个字段是一个附加字段,这个字段正好是父模块的父模块的一个namefileds字段,那么也要加成单击可以显示的功能
							// P__t1020___tf_title,例如这样的
							if (Ext.String.startsWith(fd.tf_fieldName, "P_")) {
								var fn = fd.tf_fieldName;
								var ppAsName = fn.substring(2, 10);
								if (ppAsName[6] == '_')
									ppAsName = ppAsName.substring(0, 6);
								var pmodule = app.modules.getModuleInfo(ppAsName);

								if (Ext.String.endsWith(fn, pmodule.tf_nameFields)) {
									var icon = '';
									if (pmodule && pmodule.iconURL)
										icon = '<img src="' + pmodule.iconURL + '" />';
									Ext.apply(field, {
										renderer : Ext.util.Format.manytoOneFieldRenderer,
										text : '<span class="gridheadicon" >' + icon
												+ fd.tf_title.replace(new RegExp('--', 'gm'), '<br/>')
												+ '</span>',
										manytooneIdName : pmodule.tableAsName + '___'
												+ pmodule.tf_primaryKey,
										moduleName : pmodule.tf_moduleName
									});
								}
							}

							return field;
						},


  还有一些函数是用来生成父级模块记录链接字段和子模块聚合字段,详见程序。

  通过以上的这些函数就可以根据配置信息动态的生成一个grid所需要的各个列了。



版权声明:本文为博主原创文章,未经博主允许不得转载。

常规功能和模块自定义系统 (cfcmms)—035开发日志(每个tab有各自模式window的备忘录)

035开发日志(每个tab有各自模式window的备忘录)   模式(modal)化的window在显示的时候会有一个遮罩面板,把整个界面遮住,不能够进行操作;在关闭window的时候,再把遮罩面...
  • jfok
  • jfok
  • 2016年02月17日 11:46
  • 1275

常规功能和模块自定义系统 (cfcmms)—042模块Grid的排序和筛选

pagingtoolbar042模块Grid的排序和筛选   一、排序   Grid界面排序可以点击列头直接来进行,这个是很方便。但是还有二个问题需要解决:无法取消排序至默认,单字段和多字段排序不可以...
  • jfok
  • jfok
  • 2016年05月13日 10:13
  • 1187

常规功能和模块自定义系统 (cfcmms)—041模块附加字段和新的Grid方案设计器

041模块附加字段的设计   在整个自定义系统,模块附加字段也是有必要的。对于一个模块来说附加的字段有二种,一种是父模块中的字段,另一种是子模块中的聚合字段。在模块记录生成sql语句的时候,只是生成了...
  • jfok
  • jfok
  • 2016年05月10日 09:43
  • 1396

常规功能和模块自定义系统 (cfcmms)—018自定义grid方案(2)

常规功能和模块自定义系统 (cfcmms)—018自定义grid方案(2)   下面来看看在系统中如何定义一个grid方案。当前定义grid方案也是采用对记录模块操作的方式,并没有采用所见即所得得...
  • jfok
  • jfok
  • 2015年11月20日 09:19
  • 2337

常规功能和模块自定义系统 (cfcmms)—020自定义grid方案(4改成任意层表头)

常规功能和模块自定义系统 (cfcmms)—020自定义grid方案(4改成任意层表头)   在现在的系统中grid表头是可以分组的,但是只能分一层,现在我想把它改成可以分成多层的。比如象这样的表...
  • jfok
  • jfok
  • 2015年11月23日 08:59
  • 2531

常规功能和模块自定义系统 (cfcmms)—017自定义grid方案(1)

常规功能和模块自定义系统 (cfcmms)—017自定义grid方案   在定义好了模块和字段这二个最基本的系统元素之后,就可以开始其他功能的加入了。最先想到的功能应该就是grid了。   gri...
  • jfok
  • jfok
  • 2015年11月19日 10:56
  • 1964

常规功能和模块自定义系统 (cfcmms)—053把一对多(OneToMany)字段的grid加入到form中

053把一对多(OneToMany)字段的grid加入到form中   前二章中加入了oneToMany字段,并且加入到form中显示条数,并且有一个按钮可以用来打开oneToMany的模块来进行...
  • jfok
  • jfok
  • 2016年07月08日 16:39
  • 756

常规功能和模块自定义系统 (cfcmms)—028开发日志(创建ManyToMany的column3)

028开发日志(创建ManyToMany的column3)   三、给“模块字段”增加一个字段,用来存放ManyToMany字段的joinTable值,也就是中间表的表名。给“用户模块”增加一个字...
  • jfok
  • jfok
  • 2015年12月29日 15:42
  • 1672

常规功能和模块自定义系统 (cfcmms)—021自定义grid列(5附件列)

常规功能和模块自定义系统 (cfcmms)—021自定义grid列(附件个数)   模块列表Grid是由多个列组成的,在实际的系统构建过程中需要有一些自定义的类来完成一些特殊的功能。现在来看看一个...
  • jfok
  • jfok
  • 2015年12月05日 21:29
  • 2447

常规功能和模块自定义系统 (cfcmms)—022自定义grid列(6图标列)

常规功能和模块自定义系统 (cfcmms)—022自定义grid列(6图标列)   某些模块可能需要一个记录图标...
  • jfok
  • jfok
  • 2015年12月08日 10:15
  • 1379
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:常规功能和模块自定义系统 (cfcmms)—019自定义grid方案(3)
举报原因:
原因补充:

(最多只允许输入30个字)