标签: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、修改信息
2、ExtJS的HtmlEditor的图片文件上传插件。
3、Grid列表,包含添加、删除、批量删除、修改、查看、图片查看等功能。
4、按条件查询列表。
5、导入Excel数据,支持xlsx和xls文件。
6、用户管理列表。
7、权限管理。不仅可管理各个功能模块的权限,也可以管理功能模块里的页面按钮权限。
8、报表统计。
9、采用开源的互动地图Javascript库Leaflet,处理自定义在线地图。Panel里包含2个组件,在2个组件间传递参数显示数据。
四、开发工具和采用技术
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,处理自定义在线地图。
五、代码结构
部分代码作用:
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的图片文件上传插件界面如下。
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数据导入模块的界面如下。
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、权限管理的界面如下。
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