码迷,mamicode.com
首页 > 编程语言 > 详细

基于ExtJS 4.2.1 + Hibernate 4.1.7 + Spring MVC 3.2.8 的通用后台管理系统

时间:2014-08-06 17:29:31      阅读:939      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   java   os   io   

一、系统介绍

1、基于最新的ExtJS 4.2.1.883开发。

2、支持MySQL、SQL Server、Oracle、DB2等关系数据库。

3、本系统可作为OA、网站、电子政务、ERP、CRM等基于B/S架构的应用软件系统的快速开发框架。

 

源码有50多M(包括Jar包和SQL文件),点此获取

 

二、特色功能
1、采用Spring MVC的静态加载缓存功能,在首页将Javascript文件、CSS文件和图片等静态资源文件加载进来放进内存,极大提高ExtJS的加载速度。
2、增加新的ExtJS Neptune Theme,让系统显得时髦,更具现代感,创造最佳的应用体验和多浏览器支持。

3、分别封装了模型层、控制层、业务逻辑层和数据持久层的通用操作模块,层次分明,大大减少代码冗余,二次开发效率高。

 

三、图片欣赏

1、修改信息

bubuko.com,布布扣

 

2、ExtJS的HtmlEditor的图片文件上传插件。

bubuko.com,布布扣

 

3、Grid列表,包含添加、删除、批量删除、修改、查看、图片查看等功能。

bubuko.com,布布扣

 

4、按条件查询列表。

bubuko.com,布布扣

 

5、导入Excel数据,支持xlsx和xls文件。

bubuko.com,布布扣

 

6、用户管理列表。

bubuko.com,布布扣

 

7、权限管理。不仅可管理各个功能模块的权限,也可以管理功能模块里的页面按钮权限。

bubuko.com,布布扣

 

8、报表统计。

bubuko.com,布布扣

 

9、采用开源的互动地图Javascript库Leaflet,处理自定义在线地图。Panel里包含2个组件,在2个组件间传递参数显示数据。

bubuko.com,布布扣

 

四、开发工具和采用技术
1、开发工具:MyEclipse 2014。
2、采用ExtJS 4.2.1.883商用版本。注:根据ExtJS License,只要不把ExtJS封装到工具软件里出售就不构成侵权,可放心用于网站开发。
3、采用Spring 3中最新最稳定的Spring MVC 3.2.8版本。
4、Spring MVC 3.2.8支持的最高Hibernate版本是4.1.7,更高的Hibernate版本和Spring MVC 3.2.8组合会遇到兼容问题。
5、Hibernate集成二级缓存框架Ehcache。
6、数据库是MySQL 5,Hibernate的Dialect可使程序移植到其他数据库。

7、采用开源的互动地图Javascript库Leaflet,处理自定义在线地图。

 

五、代码结构

bubuko.com,布布扣bubuko.com,布布扣

部分代码作用:

1、BaseParameter、ExtJSBaseController、BaseService、BaseDao:分别封装了模型层、控制层、业务逻辑层和数据持久层的通用操作模块。

2、ListView、PageView和QueryResult:作为ExtJS的后台分页模块。

3、SystemInitListener:加载以XML格式的数据字典,放进内存供调用。
4、LoginFilter:处理登录各种情况,将session为null的操作重定向到登录页面。
5、CustomDateEditor:处理日期参数并注册到控制器里,否则Spring MVC的参数处理将出错。
6、ExceptionCode、ServiceException:处理异常信息。
7、CacheFactory:处理Ehcache二级缓存。

8、还有其他很多工具类等等。

 

六、技术要点讲解

1、处理POST和GET的中文乱码问题。

1.1、POST的中文乱码处理可在web.xml上加上Spring提供的字符编码处理Filter。

 

	<filter>
	    <filter-name>characterEncoding</filter-name>
	    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
	    <init-param>
		<param-name>encoding</param-name>
		<param-value>UTF-8</param-value>
	    </init-param>
	    <init-param> 
                <param-name>forceEncoding</param-name> 
                <param-value>true</param-value> 
            </init-param> 
	</filter>
	<filter-mapping>
	    <filter-name>characterEncoding</filter-name>
	    <url-pattern>/*</url-pattern>
	</filter-mapping>

 

 

 

 1.2、GET的中文乱码处理可继承HttpServletRequestWrapper建立一个类来处理request。不用在应用服务器里设置URIEncoding。

package core.web;

import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class GetHttpServletRequestWrapper extends HttpServletRequestWrapper {

	private String charset = "UTF-8";

	public GetHttpServletRequestWrapper(HttpServletRequest request) {
		super(request);
	}

	/**
	 * 获得被装饰对象的引用和采用的字符编码
	 * 
	 * @param request
	 * @param charset
	 */
	public GetHttpServletRequestWrapper(HttpServletRequest request, String charset) {
		super(request);
		this.charset = charset;
	}

	/**
	 * 调用被包装的请求对象的getParameter方法获得参数,然后再进行编码转换
	 */
	public String getParameter(String name) {
		String value = super.getParameter(name);
		value = value == null ? null : convert(value);
		return value;
	}

	public String convert(String target) {
		try {
			return new String(target.trim().getBytes("ISO-8859-1"), charset);
		} catch (UnsupportedEncodingException e) {
			return target;
		}
	}
}

 

2、开发ExtJS的HtmlEditor的图片文件上传插件。建议:不要在ExtJS里集成百度编辑器、KindEditor或CKEditor等HTML编辑器,因为在某种情况下会遇到界面扭曲、浏览器兼容问题。

2.1、ExtJS的图片文件上传插件界面如下。

bubuko.com,布布扣bubuko.com,布布扣

 

2.2.1、ExtJS的图片文件上传插件Javascript代码如下。

 

Ext.define(‘Ext.ux.custom.ImageHtmlEditor‘, {
	extend : ‘Ext.util.Observable‘,
	alias : ‘widget.imagehtmleditor‘,
	langTitle : ‘插入图片‘,
	langIconCls : ‘icon-image‘,
	init : function(view) {
		var scope = this;
		view.on(‘render‘, function() {
			scope.onRender(view);
		});
	},

	/**
	 * 添加"插入图片"按钮
	 */
	onRender : function(view) {
		var scope = this;
		view.getToolbar().add({
			iconCls : scope.langIconCls,
			tooltip : {
				title : scope.langTitle,
				width : 160,
				text : ‘上传本地图片或链接网络图片‘
			},
			handler : function() {
				scope.showImgWindow(view);
			}
		});
	},

	/**
	 * 显示"插入图片"窗体
	 */
	showImgWindow : function(view) {
		var scope = this;
		Ext.create(‘Ext.window.Window‘, {
			width : 400,
			height : 310,
			title : scope.langTitle,
			layout : ‘fit‘,
			autoShow : true,
			modal : true,
			resizable : false,
			maximizable : false,
			constrain : true,
			plain : true,
			enableTabScroll : true,
			border : false,
			items : [ {
				xtype : ‘tabpanel‘,
				enableTabScroll : true,
				bodyPadding : 10,
				items : [ {
					title : ‘上传本地图片‘,
					items : [ {
						xtype : ‘form‘,
						layout : ‘column‘,
						autoScroll : true,
						border : false,
						defaults : {
							columnWidth : 1,
							labelWidth : 80,
							labelAlign : ‘left‘,
							padding : 5,
							allowBlank : false
						},
						items : [ {
							xtype : ‘fileuploadfield‘,
							fieldLabel : ‘选择文件‘,
							afterLabelTextTpl : ‘<span style="color:#FF0000;">*</span>‘,
							buttonText : ‘请选择...‘,
							name : ‘uploadAttachment‘,
							emptyText : ‘请选择图片‘,
							blankText : ‘图片不能为空‘,
							listeners : {
								change : function(view, value, eOpts) {
									scope.uploadImgCheck(view, value);
								}
							}
						}, {
							xtype : ‘fieldcontainer‘,
							fieldLabel : ‘图片大小‘,
							layout : ‘hbox‘,
							defaultType : ‘numberfield‘,
							defaults : {
								flex : 1,
								labelWidth : 20,
								labelAlign : ‘left‘,
								allowBlank : true
							},
							items : [ {
								fieldLabel : ‘宽‘,
								name : ‘width‘,
								minValue : 1
							}, {
								fieldLabel : ‘高‘,
								name : ‘height‘,
								minValue : 1
							} ]
						}, {
							xtype : ‘textfield‘,
							fieldLabel : ‘图片说明‘,
							name : ‘content‘,
							allowBlank : true,
							maxLength : 100,
							emptyText : ‘简短的图片说明‘
						}, {
							columnWidth : 1,
							xtype : ‘fieldset‘,
							title : ‘上传须知‘,
							layout : {
								type : ‘table‘,
								columns : 1
							},
							collapsible : false,// 是否可折叠
							defaultType : ‘label‘,// 默认的Form表单组件
							items : [ {
								html : ‘1、上传图片大小不超过2MB.‘
							}, {
								html : ‘2、支持以下格式的图片:jpg,jpeg,png,gif,bmp.‘
							} ]
						} ],
						buttons : [ ‘->‘, {
							text : ‘保存‘,
							action : ‘btn_save‘,
							iconCls : ‘icon-save‘,
							handler : function(btn) {
								scope.saveUploadImg(btn, view);
							}
						}, {
							text : ‘取消‘,
							iconCls : ‘icon-cancel‘,
							handler : function(btn) {
								btn.up(‘window‘).close();
							}
						}, ‘->‘ ]
					} ]
				}, {
					title : ‘链接网络图片‘,
					items : [ {
						xtype : ‘form‘,
						layout : ‘column‘,
						autoScroll : true,
						border : false,
						defaults : {
							columnWidth : 1,
							labelWidth : 80,
							labelAlign : ‘left‘,
							padding : 5,
							allowBlank : false
						},
						items : [ {
							xtype : ‘textfield‘,
							fieldLabel : ‘图片地址‘,
							afterLabelTextTpl : ‘<span style="color:#FF0000;">*</span>‘,
							name : ‘url‘,
							emptyText : ‘请填入支持外链的长期有效的图片URL‘,
							blankText : ‘图片地址不能为空‘,
							vtype : ‘url‘
						}, {
							xtype : ‘fieldcontainer‘,
							fieldLabel : ‘图片大小‘,
							layout : ‘hbox‘,
							defaultType : ‘numberfield‘,
							defaults : {
								flex : 1,
								labelWidth : 20,
								labelAlign : ‘left‘,
								allowBlank : true
							},
							items : [ {
								fieldLabel : ‘宽‘,
								name : ‘width‘,
								minValue : 1
							}, {
								fieldLabel : ‘高‘,
								name : ‘height‘,
								minValue : 1
							} ]
						}, {
							xtype : ‘textfield‘,
							fieldLabel : ‘图片说明‘,
							name : ‘content‘,
							allowBlank : true,
							maxLength : 100,
							emptyText : ‘简短的图片说明‘
						} ],
						buttons : [ ‘->‘, {
							text : ‘保存‘,
							action : ‘btn_save‘,
							iconCls : ‘icon-save‘,
							handler : function(btn) {
								scope.saveRemoteImg(btn, view);
							}
						}, {
							text : ‘取消‘,
							iconCls : ‘icon-cancel‘,
							handler : function(btn) {
								btn.up(‘window‘).close();
							}
						}, ‘->‘ ]
					} ]
				} ]
			} ]
		});
	},

	/**
	 * 上传图片验证
	 */
	uploadImgCheck : function(fileObj, fileName) {
		var scope = this;
		// 图片类型验证
		if (!(scope.getImgTypeCheck(scope.getImgHZ(fileName)))) {
			globalObject.errTip(‘上传图片类型有误!‘);
			fileObj.reset();// 清空上传内容
			return;
		}
	},

	/**
	 * 获取图片后缀(小写)
	 */
	getImgHZ : function(imgName) {
		// 后缀
		var hz = ‘‘;
		// 图片名称中最后一个.的位置
		var index = imgName.lastIndexOf(‘.‘);
		if (index != -1) {
			// 后缀转成小写
			hz = imgName.substr(index + 1).toLowerCase();
		}
		return hz;
	},

	/**
	 * 图片类型验证
	 */
	getImgTypeCheck : function(hz) {
		var typestr = ‘jpg,jpeg,png,gif,bmp‘;
		var types = typestr.split(‘,‘);// 图片类型
		for (var i = 0; i < types.length; i++) {
			if (hz == types[i]) {
				return true;
			}
		}
		return false;
	},

	/**
	 * 上传图片
	 */
	saveUploadImg : function(btn, view) {
		var scope = this;
		var windowObj = btn.up(‘window‘);// 获取Window对象
		var formObj = btn.up(‘form‘);// 获取Form对象
		if (formObj.isValid()) { // 验证Form表单
			formObj.form.doAction(‘submit‘, {
				url : appBaseUri + ‘/sys/forestrytype/uploadAttachement‘,
				method : ‘POST‘,
				submitEmptyText : false,
				waitMsg : ‘正在上传图片,请稍候...‘,
				timeout : 60000, // 60s
				success : function(response, options) {
					var result = options.result;
					if (!result.success) {
						globalObject.errTip(result.msg);
						return;
					}
					var url = result.data;
					var content = formObj.getForm().findField("content").getValue();
					var width = formObj.getForm().findField("width").getValue();
					var height = formObj.getForm().findField("height").getValue();
					var values = {
						url : appBaseUri + ‘/static/img/upload/‘ + url,
						content : content,
						width : width,
						height : height
					};
					scope.insertImg(view, values);
					windowObj.close();// 关闭窗体
				},
				failure : function(response, options) {
					globalObject.errTip(options.result.msg);
				}
			});
		}
	},

	/**
	 * 保存远程的图片
	 */
	saveRemoteImg : function(btn, view) {
		var scope = this;
		var windowObj = btn.up(‘window‘);// 获取Window对象
		var formObj = btn.up(‘form‘);// 获取Form对象
		if (formObj.isValid()) {// 验证Form表单
			var values = formObj.getValues();// 获取Form表单的值
			scope.insertImg(view, values);
			windowObj.close();// 关闭窗体
		}
	},

	/**
	 * 插入图片
	 */
	insertImg : function(view, data) {
		var url = data.url;
		var content = data.content;
		var width = data.width;
		var height = data.height;
		var str = ‘<img src="‘ + url + ‘" border="0" ‘;
		if (content != undefined && content != null && content != ‘‘) {
			str += ‘ title="‘ + content + ‘" ‘;
		}
		if (width != undefined && width != null && width != 0) {
			str += ‘ width="‘ + width + ‘" ‘;
		}
		if (height != undefined && height != null && height != 0) {
			str += ‘ height="‘ + height + ‘" ‘;
		}
		str += ‘ />‘;
		view.insertAtCursor(str);
	}
});

 

 

 

2.2.2、ExtJS的图片文件上传插件Java后台代码如下。Spring MVC对文件上传已有直接处理,不用再自写文件上传组件。

 

	@RequestMapping(value = "/uploadAttachement", method = RequestMethod.POST)
	public void uploadAttachement(@RequestParam(value = "uploadAttachment", required = false) MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws Exception {
		RequestContext requestContext = new RequestContext(request);
		JSONObject json = new JSONObject();
		if (!file.isEmpty()) {
			if (file.getSize() > 2097152) {
				json.put("msg", requestContext.getMessage("g_fileTooLarge"));
			} else {
				try {
					String originalFilename = file.getOriginalFilename();
					String fileName = sdf.format(new Date()) + ForestryUtils.getRandomString(3) + originalFilename.substring(originalFilename.lastIndexOf("."));
					File filePath = new File(getClass().getClassLoader().getResource("/").getPath().replace("/WEB-INF/classes/", "/static/img/upload/" + DateFormatUtils.format(new Date(), "yyyyMM")));
					if (!filePath.exists()) {
						filePath.mkdirs();
					}
					file.transferTo(new File(filePath.getAbsolutePath() + "\\" + fileName));
					json.put("success", true);
					json.put("data", DateFormatUtils.format(new Date(), "yyyyMM") + "/" + fileName);
					json.put("msg", requestContext.getMessage("g_uploadSuccess"));
				} catch (Exception e) {
					e.printStackTrace();
					json.put("msg", requestContext.getMessage("g_uploadFailure"));
				}
			}
		} else {
			json.put("msg", requestContext.getMessage("g_uploadNotExists"));
		}
		writeJSON(response, json.toString());
	}

 

 

 

3、继承Ext.grid.Panel重写列表组件,在toolbar上定义全局通用的“添加”、“导入”、“删除”等功能点,减少了代码冗余。

 

Ext.define(‘Ext.ux.custom.GlobalGridPanel‘, {
	extend : ‘Ext.grid.Panel‘,
	alias : ‘widget.globalgrid‘,
	xtype : ‘cell-editing‘,
	initComponent : function() {
		var me = this;
		var singleId;
		
		var uniqueID = me.cName + (me.cId ? me.cId : ‘‘) + (me.myId ? me.myId : ‘‘);

		this.cellEditing = Ext.create(‘Ext.grid.plugin.CellEditing‘, {
			clicksToEdit : 2
		});

		var tbarMenus = new Array();
		if (globalObject.haveActionMenu(me.cButtons, ‘Add‘)) {
			tbarMenus.push({
				xtype : ‘button‘,
				itemId : ‘btnAdd‘,
				iconCls : ‘icon-add‘,
				text : ‘添加‘,
				scope : this,
				handler : me.onAddClick
			});
		}
		if (globalObject.haveActionMenu(me.cButtons, ‘Import‘)) {
			tbarMenus.push({
				xtype : ‘button‘,
				itemId : ‘btnImport‘,
				iconCls : ‘icon-excel‘,
				text : ‘导入‘,
				scope : this,
				handler : me.onImportClick
			});
		}
		if (globalObject.haveActionMenu(me.cButtons, ‘Delete‘)) {
			tbarMenus.push({
				xtype : ‘button‘,
				itemId : ‘btnDelete‘,
				iconCls : ‘icon-delete‘,
				text : ‘删除‘,
				scope : this,
				disabled : true,
				handler : me.onDeleteClick
			});
		}
		if (globalObject.haveActionMenu(me.cButtons, ‘Export‘)) {
			tbarMenus.push({
				xtype : ‘splitbutton‘,
				itemId : ‘btnImport‘,
				text : ‘导出‘,
				scope : this,
				handler : function() {
					me.onExportClick(false);
				},
				menu : [ {
					text : ‘导出(包括隐藏列)‘,
					handler : function() {
						me.onExportClick(true);
					}
				}, {
					text : ‘导出选中数据‘,
					handler : function() {
						me.onExportClick(false, true);
					}
				}, {
					text : ‘导出选中数据(包括隐藏列)‘,
					handler : function() {
						me.onExportClick(true, true);
					}
				} ]
			});
		}

		if (tbarMenus.length == 0)
			me.hideTBar = true;
		this.ttoolbar = Ext.create(‘Ext.toolbar.Toolbar‘, {
			hidden : me.hideTBar || false,
			items : tbarMenus
		});

		Ext.apply(this, {
			stateful : me.cName ? true : false,
			stateId : me.cName ? (uniqueID + ‘gird‘) : null,
			enableColumnMove : me.cName ? true : false,
			plugins : this.plugins,
			selModel : Ext.create(‘Ext.selection.CheckboxModel‘),
			border : false,
			tbar : this.ttoolbar,
			bbar : me.hideBBar ? null : Ext.create(‘Ext.PagingToolbar‘, {
				store : me.getStore(),
				displayInfo : true
			}),
			listeners : {
				itemdblclick : function(dataview, record, item, index, e) {
					me.onViewClick();
				}
			}
		});
		this.getSelectionModel().on(‘selectionchange‘, function(sm, records) {
			if (me.down(‘#btnDelete‘))
				me.down(‘#btnDelete‘).setDisabled(sm.getCount() == 0);
		});

		this.callParent(arguments);
	},
	createStore : function(config) {
		Ext.applyIf(this, config);

		return Ext.create(‘Ext.data.Store‘, {
			model : config.modelName,
			// autoDestroy: true,
			// autoLoad: true,
			remoteSort : true,
			pageSize : globalPageSize,
			proxy : {
				type : ‘ajax‘,
				url : config.proxyUrl,
				extraParams : config.extraParams || null,
				reader : {
					type : ‘json‘,
					root : ‘data‘,
					totalProperty : ‘totalRecord‘,
					successProperty : "success"
				}
			},
			sorters : [ {
				property : config.sortProperty || ‘id‘,
				direction : config.sortDirection || ‘DESC‘
			} ]
		});
	},
	getTabId : function() {
		return this.up(‘panel‘).getId();
	},
	onAddClick : function() {
	},
	onEditClick : function() {
	},
	onImportClick : function() {
	},
	onViewClick : function() {
	},
	onDeleteClick : function() {
		var me = this;
		globalObject.confirmTip(‘删除的记录不可恢复,继续吗?‘, function(btn) {
			if (btn == ‘yes‘) {
				var s = me.getSelectionModel().getSelection();
				var ids = [];
				var idProperty = me.idProperty || ‘id‘;
				for (var i = 0, r; r = s[i]; i++) {
					ids.push(r.get(idProperty));
				}
				Ext.Ajax.request({
					url : me.proxyDeleteUrl,
					params : {
						ids : ids.join(‘,‘) || singleId
					},
					success : function(response) {
						if (response.responseText != ‘‘) {
							var res = Ext.JSON.decode(response.responseText);
							if (res.success) {
								globalObject.msgTip(‘操作成功!‘);
								// Ext.example.msg(‘系统信息‘, ‘{0}‘, "操作成功!");
								me.getStore().reload();
							} else {
								globalObject.errTip(‘操作失败!‘ + res.msg);
							}
						}
					}
				});
			}
		});
	},
	onExportClick : function(importHideColumn, onlySelected) {
		globalObject.exportToExcel(this, importHideColumn, onlySelected);
	}
});

 

 

 

4、开发Excel数据导入模块,同时支持xls和xlsx文件,在Java后台代码对导入过程中各种条件判断和异常有严格的处理。

4.1、Excel数据导入模块的界面如下。

bubuko.com,布布扣

 

4.2、Excel数据导入模块的Java后台代码如下。

 

	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");

	@RequestMapping(value = "/importForestryFile", method = RequestMethod.POST)
	public void importForestryFile(@RequestParam(value = "importedFile", required = false) MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws Exception {
		RequestContext requestContext = new RequestContext(request);
		JSONObject json = new JSONObject();
		if (!file.isEmpty()) {
			if (file.getSize() > 2097152) {
				json.put("msg", requestContext.getMessage("g_fileTooLarge"));
			} else {
				try {
					String originalFilename = file.getOriginalFilename();
					String fileName = sdf.format(new Date()) + ForestryUtils.getRandomString(3) + originalFilename.substring(originalFilename.lastIndexOf("."));
					File filePath = new File(getClass().getClassLoader().getResource("/").getPath().replace("/WEB-INF/classes/", "/static/download/attachment/" + DateFormatUtils.format(new Date(), "yyyyMM")));
					if (!filePath.exists()) {
						filePath.mkdirs();
					}
					String serverFile = filePath.getAbsolutePath() + "\\" + fileName;
					file.transferTo(new File(serverFile));

					String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
					if (!fileType.equalsIgnoreCase("xls") && !fileType.equalsIgnoreCase("xlsx")) {
						json.put("success", false);
						json.put("msg", requestContext.getMessage("g_notValidExcel"));
						writeJSON(response, json.toString());
						return;
					}
					int count = 0;
					StringBuilder stringBuilder = new StringBuilder();
					InputStream xls = new FileInputStream(serverFile);
					Workbook wb = null;
					Sheet sheet = null;
					Row currentRow = null;
					Row headRow = null;
					Cell currentCell = null;
					if (fileType.equals("xls")) {
						wb = new HSSFWorkbook(xls);
					} else if (fileType.equals("xlsx")) {
						wb = new XSSFWorkbook(xls);
					}
					sheet = wb.getSheetAt(0);// excel中至少会存在一个sheet页
					int rowNum = sheet.getPhysicalNumberOfRows();// 物理有效行数
					Object[] rowValues = null;// excel中一行树木信息
					List<Object[]> models = new ArrayList<Object[]>();// excel中全部树木信息
					if (rowNum > 1) {
						headRow = sheet.getRow(0);
						columns: for (int i = 1; i < rowNum; i++) {
							currentRow = sheet.getRow(i);
							if (currentRow != null) {
								rowValues = new Object[5];
								// int cellNum = currentRow.getLastCellNum();// 总单元格数目
								for (short j = 0; j < 5; j++) {
									try {
										currentCell = currentRow.getCell(j);
										Object obj = null;
										if (currentCell == null) {
											obj = "";
										} else {
											switch (currentCell.getCellType()) {
												case Cell.CELL_TYPE_BLANK:
													obj = "";
													break;
												case Cell.CELL_TYPE_STRING:
													obj = currentCell.getRichStringCellValue();
													break;
												case Cell.CELL_TYPE_NUMERIC:
													if (HSSFDateUtil.isCellDateFormatted(currentCell)) {
														double d = currentCell.getNumericCellValue();
														Date date = HSSFDateUtil.getJavaDate(d);
														obj = sdfDate.format(date);
													} else {
														NumberFormat nf = NumberFormat.getInstance();
														nf.setGroupingUsed(false);//true时的格式:1,234,567,890
														obj = nf.format(currentCell.getNumericCellValue());
													}
													break;
												default:
													obj = "";
													break;
											}
										}
										String cellVal = obj.toString();
										rowValues[j] = cellVal;
									} catch (IllegalStateException e) {
										rowValues = null;
										stringBuilder.append("第" + i + "行," + headRow.getCell(j).getRichStringCellValue() + "列输入了非法值,未导入成功!");
										continue columns;
									} catch (NullPointerException e) {
										rowValues = null;
										stringBuilder.append("第" + i + "行," + headRow.getCell(j).getRichStringCellValue() + "列输入了空值,未导入成功!");
										continue columns;
									} catch (Exception e) {
										rowValues = null;
										stringBuilder.append(e.getMessage());
										continue columns;
									}
								}
								if (rowValues != null) {
									models.add(rowValues);
								}
							}
						}
					} else if (rowNum <= 1 && rowNum > 0) {// 表示模版中只存在头部信息
						json.put("success", false);
						json.put("msg", "Excel表格中没有需要导入 的内容!");
						writeJSON(response, json.toString());
						return;
					} else if (rowNum <= 0) {// 表示这是一个空sheet页
						json.put("success", false);
						json.put("msg", "所导入文件格式不正确,请下载模板!");
						writeJSON(response, json.toString());
						return;
					}
					List<Forestry> list = objectToForestry(models);// Object-->Forestry
					for (int i = 0; i < list.size(); i++) {
						if (StringUtils.isBlank(list.get(i).getEpcId()) || StringUtils.isBlank(list.get(i).getName())) {
							stringBuilder.append("第" + (i + 1) + "行记录的必填项有空值,导入失败。");
							continue;
						}
						Forestry checkForestryEpcId = forestryService.getByProerties("epcId", list.get(i).getEpcId());
						if (checkForestryEpcId != null) {
							stringBuilder.append("第" + (i + 1) + "行记录的epc编码已存在,导入失败。");
							continue;
						}
						if (list.get(i).getForestryType() == null) {
							stringBuilder.append("第" + (i + 1) + "行记录的种类为空或不存在,导入失败。");
							continue;
						}
						forestryService.persist(list.get(i));
						count++;
					}

					json.put("success", true);
					json.put("msg", count + "条记录导入完成。" + stringBuilder.toString());
				} catch (Exception e) {
					e.printStackTrace();
					json.put("success", false);
					json.put("msg", requestContext.getMessage("g_operateFailure"));
					writeJSON(response, json.toString());
				}
			}
		} else {
			json.put("success", false);
			json.put("msg", requestContext.getMessage("g_uploadNotExists"));
		}
		writeJSON(response, json.toString());
	}

	private List<Forestry> objectToForestry(List<Object[]> models) {
		List<Forestry> forestryList = new ArrayList<Forestry>();
		Forestry forestry = null;
		for (int i = 0; i < models.size(); i++) {
			try {
				forestry = new Forestry();
				forestry.setEpcId(models.get(i)[0].toString());
				forestry.setName(models.get(i)[1].toString());
				if (StringUtils.isBlank(models.get(i)[2].toString())) {
					forestry.setPlantTime(null);
				} else {
					forestry.setPlantTime(sdfDate.parse(models.get(i)[2].toString()));
				}
				if (StringUtils.isBlank(models.get(i)[3].toString())) {
					forestry.setEntryTime(null);
				} else {
					forestry.setEntryTime(sdfDate.parse(models.get(i)[3].toString()));
				}
				ForestryType forestryType = forestryTypeService.getByProerties("name", models.get(i)[4].toString());
				forestry.setForestryType(forestryType);
				forestryList.add(forestry);
			} catch (Exception e) {
				e.printStackTrace();
				continue;
			}
		}
		return forestryList;
	}

 

 

 

5、开发权限管理。不仅可以管理功能模块的权限,也可以管理功能模块里面各个按钮的权限。

5.1、权限管理的界面如下。

bubuko.com,布布扣

 

5.2、权限管理的代码如下。

 

// 权限管理
Ext.define(‘Forestry.app.systemManage.AuthorizationManagement‘, {
	extend : ‘Ext.panel.Panel‘,
	initComponent : function() {
		var me = this;
		Ext.apply(this, {
			layout : ‘border‘,
			items : [ Ext.create(‘Forestry.app.systemManage.AuthorizationManagement.SysUserGrid‘, {
				cButtons : me.cButtons,
				cName : me.cName
			}), Ext.create(‘Forestry.app.systemManage.AuthorizationManagement.MenuTree‘) ]
		});
		this.callParent(arguments);
	}
});

// 角色列表
Ext.define(‘Forestry.app.systemManage.AuthorizationManagement.SysUserGrid‘, {
	extend : ‘Ext.grid.Panel‘,
	id : ‘authorizationmanagement-sysusergrid‘,
	region : ‘west‘,
	width : ‘18%‘,
	initComponent : function() {
		var me = this;
		Ext.define(‘SysUserRoleList‘, {
			extend : ‘Ext.data.Model‘,
			idProperty : ‘role‘,
			fields : [ {
				name : ‘role‘,
				type : ‘short‘
			}, ‘roleName‘ ]
		});
		var sysusergridstore = Ext.create(‘Ext.data.Store‘, {
			model : ‘SysUserRoleList‘,
			// autoDestroy: true,
			autoLoad : true,
			remoteSort : true,
			pageSize : globalPageSize,
			proxy : {
				type : ‘ajax‘,
				url : appBaseUri + ‘/sys/sysuser/getRoleNameList‘,
				extraParams : me.extraParams || null,
				reader : {
					type : ‘json‘,
					root : ‘data‘,
					totalProperty : ‘totalRecord‘,
					successProperty : "success"
				}
			}
		});
		var sysusergridcolumns = [ {
			text : "roleId",
			dataIndex : ‘role‘,
			hidden : true,
			sortable : false,
			editor : {
				allowBlank : false
			}
		}, {
			text : "角色",
			dataIndex : ‘roleName‘,
			sortable : false,
			width : ‘85%‘,
			editor : {
				allowBlank : false
			}
		} ];
		Ext.apply(this, {
			store : sysusergridstore,
			selModel : Ext.create(‘Ext.selection.CheckboxModel‘),
			columns : sysusergridcolumns,
			listeners : {
				‘itemclick‘ : function(item, record) {
					me.currentRole = record.get(‘role‘);
					Ext.getCmp(‘authorizationmanagement-rolemenu‘).getStore().load({
						params : {
							‘role‘ : me.currentRole
						}
					});
				}
			}
		});
		this.callParent(arguments);
	}
});

// 树形菜单
Ext.define(‘Forestry.app.systemManage.AuthorizationManagement.MenuTree‘, {
	extend : ‘Ext.tree.Panel‘,
	id : ‘authorizationmanagement-rolemenu‘,
	plain : true,
	border : true,
	region : ‘center‘,
	autoScroll : true,
	initComponent : function() {
		var me = this;
		var menutreestore = Ext.create(‘Ext.data.TreeStore‘, {
			autoLoad : true,
			proxy : {
				type : ‘ajax‘,
				url : appBaseUri + ‘/sys/authority/getAuthorizationList‘,
				reader : {
					type : ‘json‘,
					root : ‘children‘
				}
			}
		});
		Ext.apply(this, {
			// title : ‘菜单权限‘,
			store : menutreestore,
			rootVisible : false,
			tbar : [ {
				xtype : ‘button‘,
				iconCls : ‘icon-save‘,
				text : ‘保存菜单权限‘,
				scope : this,
				handler : me.saveMenuPermission
			} ]
		});
		this.callParent(arguments);
	},
	saveMenuPermission : function() {
		var me = this;
		var roleId = Ext.getCmp(‘authorizationmanagement-sysusergrid‘).currentRole;
		if (!roleId) {
			globalObject.infoTip(‘请先选择角色!‘);
			return;
		};
		var s = me.getChecked();
		var ids = [];
		for (var i = 0, r; r = s[i]; i++) {
			if (r.get(‘id‘) != ‘root‘)
				ids.push(r.get(‘id‘));
		}
		me.setLoading(‘权限保存中...‘);
		Ext.Ajax.request({
			url : appBaseUri + ‘/sys/roleauthority/saveRoleAuthority‘,
			params : {
				ids : ids.join(‘,‘),
				role : roleId
			},
			success : function(response) {
				me.setLoading(false);
				var res = Ext.JSON.decode(response.responseText);
				if (res && !res.success) {
					Ext.Msg.alert(‘出错信息‘, res.msg);
				} else {
					globalObject.msgTip(‘保存成功!‘);
				}
			},
			failure : function(response, opts) {
				me.setLoading(false);
				Ext.Msg.alert(‘出错信息‘, ‘操作失败!‘);
			}
		});
	}
});

 

 

 

源码有50多M(包括Jar包和SQL文件),点此获取

 

基于ExtJS 4.2.1 + Hibernate 4.1.7 + Spring MVC 3.2.8 的通用后台管理系统,布布扣,bubuko.com

基于ExtJS 4.2.1 + Hibernate 4.1.7 + Spring MVC 3.2.8 的通用后台管理系统

标签:des   style   blog   http   color   java   os   io   

原文地址:http://www.cnblogs.com/yangtian/p/ExtJS4.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!