介绍

        ctjee框架,前身为BMS(Business Manage SYS)架构。2009年始创于珠海。作者一直在寻求以原为本设计思想,内容可控。摒弃第三方框架(Spring、Struts)分层迭代、接口调用、映射Bean、配置文件等等繁琐的方法。以MVC为模型,简单、直接、迅速,技术化繁为简,而非把时间浪费在架构的配置、学习、调试、使用和问题处理上。

        ctjee框架经过近十年,1000多个,大中小软件项目的测试、应用、改造、升级的演变。也逐步开放服务于个人、企业及政府机构。最终的目的是实现用户自主构建应用平台。

        ctjee框架在设计和使用上,基于本身的Servlet技术,完全采用源码的驱动方法。通过OP层调用SQL层。配备变量监听、安全访问、事务模式及完善的异常追踪日志记录。同时在原框架中配置有基础数据输入校验功能(必输项、长度),减少开发人员的工作量增强软件质量。

        ctjee框架以数据库表为单元或称之为模块。 使用代码生成器时必须要确保单元表包含:表中文名、表主键(一个)、以及字段和字段描述。在Dao层采用面向原子的操作结构设计,在访问数据时可以交叉使用非常方便。

        ctjee框架可以开发所有的WEB、手机、微信、小程序应用系统,或者您可以在它的基础上封装更多个性化的结构。

        ctjee框架未来的发展方向:持续迭代MySql、Oracle及多UI版本;为使用者提供配套的应用小程序、及前后台应用服务组件;为企业提供安全责任制的应用级服务。

系统结构

主要特性

        访问路径具有安全验证机制。分别支持.ext|.com|.ando。
        单点登录
        完整的后台管理,具备人员-部门-权限-菜单机制,人员多角色切换功能。
        分页、查询、新增、修改、删除、数据字段验证(必输项+长度)+ java后台管理代码。一建生成,直接可用。
        支持界面跳转及异步处理两种数据交互模式,并通过数据缓冲区直接与持久层进行封装,方便数据赋值。
        框架完整封装与JBPM工作流的无缝对接,支持表单的审批、核准、退回、完成等流程任务。
        使用多线程分布式计算技术,解决大数量实时数据统计、报表查询及大数据量计算任务。
        通过缓存字典+自定义标签,实现实时字典翻译功能。
        支持多维数据源访问链路,用于交互系统数据报表检索和查询。支持数据库事务模式;支持存储过程调用。
        支持自定义表单,自定义工作流。
        支持框架自由伸缩式业务扩展。

基础组件

  •         Bootstrap ace
  •         jQuery
  •         dwr
  •         Ajax
  •         MiniUI
  •         bootstrapAutocomplete
  •         zeroModal
  •         mloading
  •         My97DatePicker
  •         ppfiledown(多文件流传输)
  •         jquery.tips.js
  •         zTree_v3
  •         b.tag(自定义标签)
  1. .druid-1.0.1(数据库连接池)
  2. .template.xlsx(百万大数据导出xlsx)
  3. .jacob(文档转换工具)
  4. .jbpm(工作流引擎)
  5. .netty-all-5.0.0(通讯服务组件)
  6. .json-lib-2.2.2-jdk15
  7. .log4j-1.2.17(日志工具)
  8. .Highcharts(图表工具)
  9. .fckeditor(在线编辑器)

技术选型

        1、系统环境:Java EE 8 ,Servlet 3.0

        2、持久层:Alibaba Druid 1.2.x

        3、视图层:Bootstrap ace

基础功能

        用户档案:创建系统操作者的基础档案信息、用户名、账号、密码等等。
        用户角色:设置用户的角色、根据角色分配用户的操作菜单及功能,支持用户多角色。
        角色管理:用于维护角色的基础信息。为角色分配提供基础数据支撑。
        部门管理:隶属系统组织机构(总公司、分公司、部门),为用户档案做数据支撑。
        菜单管理:主要配置菜单项及菜单树结构。
        缓存字典:运行时加载固定数据字典,通常指不经常维护的数据字典。结合系统函数及标签一起使用。
        运行参数:系统运行时的一些调整配置。
        日志查询:系统记录用户操作日志记录和查询。
        代码生成:前后端代码的生成(java、jsp)及动态CRUD语句。
        资源监控:系统CPU、内存、磁盘、堆栈等相关信息。
        表单设计器:拖动表单元素生成相应的HTML代码。
        连接池监视:监视当期系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。

代码案例

Code view

@function(id = "insertSql.ext", name = "新增单笔数据到测试")
public void insertSql() throws Exception{
    try{
       String submitData = (String)getValueAt("submitData");
       JSONObject json = JSONObject.fromObject(submitData);   
       map.put("testid", (String)toNvlNull(json.get("testid")));//主键id
       map.put("my_zd", (String)toNvlNull(json.get("my_zd")));//地址
       map.put("opuser", (String)toNvlNull(json.get("opuser")));//提交人
       map.put("opdaytime", (String)toNvlNull(json.get("opdaytime")));//提交时间yyyy-mm-dd
       map.put("pny", (String)toNvlNull(json.get("pny")));//审批状态 
       Update( zftestSql.insertDynamicSql(_param, _map) );//执行SQL
       msg = new Message(true, "操作成功!"); 
       commitStraction(); 
    }catch(Exception e){ 
       rollbackStraction();
       msg = new Message(false, "操作失败!"+e.getLocalizedMessage()); 	
    } 
       setReplyPage("STREAM"+toJsonMap(msg)); 
}

目录结构


ctjee     
├──src            
│   │──com                     
│   │   └──ctjee
│   │        │──assist                      // 工具类
│   │        └──web                         // 核心业务后台java模块
│   │──dbconfig.properties                  // 业务数据库配置文件
│   │──fckeditor.properties                 // 网页编辑器配置文件
│   │──jbpm.cfg.xml                         // jbpm工作流配置文件
│   │──jbpm.hibernate.cfg.xml               // jbpm数据库配置文件
│   │──jbpm.mail.properties                 // jbpm工作流配置文件
│   │──jbpm.mail.templates.xml              // jbpm工作流配置文件
│   │──log4j.properties                     // log4j日志配置
│   │──sys.properties                       // 配置框架服务
├── WebContent                              // 框架核心Web
│       │──assets                           // 工具服务组件
│       │──fckeditor                        // 网页编辑器组件
│       │──Highcharts-4.1.9                 // Highcharts图表
│       │──web                              // 核心业务前端jsp/html模块
│       │──header_ace.jsp                   // 头文件
│       │──mainH5.jsp                       // 首页文件
│       └──login.jsp                        // 登录界面 

开发工具下载


Eclipse

Eclipse Java EE IDE for Web Developers. Version: Neon Release (4.6.0)

Eclipse Neon Release (4.6.0) 下载

MySql(5.5.28)

MySql (5.5.28) 下载

MySql客户端工具heidisql.exe

heidisql.exe 下载

JAVA JDK 8.0

jdk1.8.0_131_64 下载

jdk1.8.0_131_32bit 下载

Apache-tomcat-8.0.29

apache-tomcat-8.0.29_64_ok.rar 下载

ChromePortable.exe

ChromePortable.exe 浏览器下载


安装及配置工具


安装,JDK

            

1、双击运行“jdk_8.0.1310.11_64.exe”;


            

2、弹出安装程序的对话框,点击“下一步”;


            
            

3、选择安装JDK的目录,“D:\Program Files\Java\jdk1.8.0_131”,点击“下一步”;


            
            

4、选择JRE的安装目录,“D:\Program Files\Java\jre1.8.0_131”,点击“下一步”;


            
            

5、安装就结束啦。


            
            

6、配置JDK环境变量,1、桌面图标“计算机”(或者“我的电脑”)右击,单击“属性”;


            
            

7、在弹出框,单击“高级系统设置”,选择“高级”,单击按钮“环境变量”;


            
            

8、在弹出的“环境变量”框中,选择下方“系统变量(S)”下面的按钮“新建”;


            
            

9、设置环境变量,3个变量都设置好;


            

安装,apache-tomcat-8.0.29_64_ok.rar

            

1、apache-tomcat-8.0.29_64_ok.rar 解压到D:\apache-tomcat-8.0.29


            

安装,MySql (5.5.28)

            

1. 双击mysql-5.5.28-win32.exe(或者mysql-5.5.28-winx64)点击下一步,接受许可。


            

2. 点击custom


            
            

3. 将安装路径修改为d盘


            
            
            
            

4. 点击下一步,安装


            

5. 安装过程中弹出如下窗口,一直点击下一步即可


            
            

6. 完成安装时注意勾选运行mysql实例配置工具


            
            

7. 在弹出的实例配置向导中点击下一步


            
            

8. 选择detailed配置,点击下一步


            
            

9. 选择develop Machine,点击下一步


            
            

10. 选择Multifunctional Database,点击下一步


            
            

11. 下图中直接点击下一步


            
            

12. 选择Decision Support,点击下一步


            
            

13. 按下图配置后,点击下一步


            
            

14. 编码选择utf8


            
            

15. 配置服务及环境变量,点击下一步


            
            

16. 输入新密码,新密码为root,点击下一步


            
            

17. 点击执行


            
            

18. 配置成功,点击完成


            

安装,MySql客户端工具heidisql.exe

            

1、mysqlsqlClient.rar 解压到D:\D:\mysqlsqlClient。双击heidisql.exe即可使用。


            


导入ctjee项目

            

在网站首页或者定制版中,下载ctjee框架.rar和mysql数据库脚本文件。http://www.ctjee.com/并将下载后的ctjee.rar解压。


            

1、在电脑盘符创建一个文件夹,做为工程目录(文件夹名称非中文)


            

            

2、双击打开eclipse.exe,选择已创建的工程名称


            

            

3、点击[OK],进入编辑环境


            

            

4、选择[File]菜单下的[Import]导入


            

            

5、在弹出框中选择[General]-[Existing Projects into Workspace] 点击[Next]


            

            

6、在弹出框中选择[Browse]-弹出项目导入对话框,ctjee已解压的项目路径。


            
            

7、ctjee已解压的项目路径。是将下载的ctjee.rar解压后的文件夹位置,选择好后点击[确定]


            

            

8、选择[Copy projects into Workspace],点击[Finish]


            
            

9、项目导入完成。


            


配置运行ctjee


            

1、设置开发工具编码集UTF-8,选择[windows]-[Preferences]


            
            

2、输入workspace,[Other] 选择UTF-8编码


            
            

3、配置运行服务器 Tomcat 8.0


            
            

4、选择服务器 Tomcat 8.0,选择[Next]


            
            

5、选择服务器 Tomcat 8.0安装路径


            
            

6、选择apache-tomcat-8.0.29_64_ok.rar解压后的Tomcat 8.0路径,选择[确定]


            
            

7、选择[Next]


            
            

8、选择ctjee工程,点击[Add]发布到Tomcat 8.0服务器,选择[Finish]完成


            
            
            

9、 配置Java构建路径


            
            
            

10、 添加运行库Server Runtime,选择[Next]


            
            
            

11、 添加JRE System Libray,选择[Add Libray]


            
            
            
            

12、 配置完成


            
            

13、 配置数据库账号/密码

            

配置dbconfig.properties数据库账号/密码


            
            

配置jbpm.hibernate.cfg.xml数据库账号/密码


            
            

15、 导入mysql数据库脚本


            
            

16、 选择[Server]-[Tomcat v8.0 Server at localhost]启动运行


            
            

17、 运行成功


            
            

18、 前后台的basePath与web.xml中设置有关


WEBPATH的值都取自于<param-name>webpath</param-name>


Code view

<%=WEBPATH%>  //前台base_path
String webpath = (String)InitContextParams.getSysParamsTable().get("WEBPATH");   //后台base_path

<init-param>
  <param-name>webpath</param-name>
  <param-value>/ctjee</param-value>
</init-param>

开发流程介绍


1、以数据库为系统设计核心,我们把一张物理表称之为一个模块或一个单元。表中包含表名、表描述、主键、字段描述。

2、使用生成器对单元表进行代码生成。包含jsp-op-sql三层代码。代码生成器的使用

3、jsp中分别有文件后缀_list(列表页)、_add(新增页)、_edit(修改页)、_detail(详情页)、_ing(审批中)、_end(审批结束)

4、java中OpManger表示:业务逻辑处理、Sql表示:单元表DML语句

5、jsp表单提交到OpManger业务逻辑处理,通过OP中的@function注解进行定位

         表单提交的映射名称有三种:*.ext、*.com、*.ando、*.home

         *.ext:转义并对客户端进行安全验证(可使用)

         *.com:转义;对客户端不验证(可使用)

         *.ando:不转义;对客户端不验证;通常用作接口或移动端访问使用(可使用)

         *.home:不转义;对客户端不验证;服务器端首页跳转,仅用一次。(不建议使用)

6、获取jsp表单的字段值,可以使用getValueAt("字段名");

7、获取Session值,可以使用getSessionData("字段名");

8、在Op中有三类执行SQL语句的方法

         List(String sql);查询 sql select 集合语句;

         Map(String sql); 查询 sql select 单行语句;

         Update(String sql); 执行 sql insert\update\delete语句;

9、事务处理

         事务提交:commitStraction();

         事务回滚:rollbackStraction();

10、Response相应结果返回

         STREAM模式返回数据流:setReplyPage("STREAM"+toJsonMap(msg));

         跳转模式:setReplyPage(webpath+"/web/main/profile.jsp");

11、开发流程示例:


查询表格jqGrid

            bootsrap这个版本中table数据列表使用jqGri插件实现。
            

jqGrid plug-in components

html/jsp
前台数据展示采用jqGrid展现
java
调用使用两个语句完成分页
String selectPageListCount(_param,_map)
String selectPageListBootstrapJqGrid(_param,_map)
List ListPage(String sql,StringBuffer totalCount)
调用步骤
1.StringBuffer totalCount = new StringBuffer( zftestSql.selectPageListCount(_param,_map) );
2.List _nList = ListPage(zftestSql.selectPageList(_param,_map), totalCount);
3.setReplyPage("STREAM"+toJsonPageArrayBootstrapJqGridAddTotalPropertys(_nList,totalCount.toString()));

1.页面包含 grid-table、grid-pager 标签

Code view

<div class="form-group"/p> 
 <div class="col-sm-12" /p>
  <table id="grid-table"/p></table/p> 
 </div/p> 
</div/p>
<div class="form-group"/p> 
 <div class="col-sm-12" /p>
  <div id="grid-pager"/p></div/p>
 </div/p> 
</div/p> 

2.js部分 url、colNames、colModel关键参数

Code view

<script type="text/javascript"/p>
//direction: "rtl", 
//subgrid options
//子项管理subGrid : true,
//subGridModel: [{ name : ['No','Item Name','Qty'], width : [55,200,80] }],
//datatype: "xml",
/*子项管理
subGridOptions : {
	plusicon : "ace-icon fa fa-plus center bigger-110 blue",
	minusicon  : "ace-icon fa fa-minus center bigger-110 blue",
	openicon : "ace-icon fa fa-chevron-right center orange"
},
*/
//for this example we are using local data
/*子项管理
subGridRowExpanded: function (subgridDivId, rowId) {
	var subgridTableId = subgridDivId + "_t";
	$("#" + subgridDivId).html("<table id='" + subgridTableId + "'/p></table/p>");
	$("#" + subgridTableId).jqGrid({ 
		datatype: 'local',
		data: subgrid_data,
		colNames: ['No','Item Name','Qty'],
		colModel: [
			{ name: 'id', width: 50 },
			{ name: 'name', width: 150 },
			{ name: 'qty', width: 50 }
		]
	});
},
*/ 		
url: '<b:submitForm name="zftest_selectPageListBootstrap.ext"//p>', //获取数据源 
postData : {submitData: JSON.stringify($(defaultForm).serializeObject())}, 
datatype: "json", 
         serializeRowData: function(postData) { 
             return postData;
         },
height: 650,
colNames:['详情','主键id','地址','提交人','提交时间yyyy-mm-dd','p=审批中n=最终审批不通过y=最终审批通过','流程实例id'],
colModel:[
/*		
{name:'XXXXX',index:'', width:60, fixed:true, sortable:false, resize:false,
	formatter:'actions', 
	formatoptions:{ 
		keys:true,
		delbutton: false,
		editbutton:false
        delbutton: true,//disable delete button 
//行删除
delOptions:{
		url: '<b:submitForm name="zftest_deleteByPk.ext"//p>' ,
                      onclickSubmit: function(params, posdata) { 
				var rowId=$(grid_selector).jqGrid('getGridParam','selrow'); 
				var rowData = $(grid_selector).jqGrid('getRowData',rowId);
				return {"code":rowData.code}; 
                                     },
               afterSubmit: function(response, postData) { 
                             	 result_text = response.responseText ;
                             	 var result = eval('(' + result_text + ')'); 
                                  if (result.success) {
                                 	 return [true]; 
                                  } else {
                                 	 return [false, result.msg];  
                                  } 
                              },recreateForm: true,beforeShowForm:beforeDeleteCallback},  
//行编辑 
editbutton:false,  
//editformbutton:true,
editOptions:{
	url: '<b:submitForm name="zftest_updateByPk.ext"//p>' ,
	onclickSubmit: function(params, posdata) {   
	var rowId=$(grid_selector).jqGrid('getGridParam','selrow'); 
	var rowData = $(grid_selector).jqGrid('getRowData',rowId); 
	return {"submitData":JSON.stringify(rowData)};},
    afterSubmit: function(response, postData) { 
      alert(response.responseText);
   	 result_text = response.responseText ;
   	 var result = eval('(' + result_text + ')'); 
        if (result.success) {
       	 return [true]; 
        } else {
       	 return [false, result.msg];  
        } 
   },recreateForm: true, beforeShowForm:beforeEditCallback} 
//editOptions:{recreateForm: true, beforeShowForm:beforeEditCallback}    
	}
},
*/ 
    {editable: true,formatter:function(cellvalue, options, rowObject){   
              	   return "<a herf='javascript:;' onclick='shwoTabDetail(\""+rowObject.testid+"\")'/p>详情查看</a/p>";   
	   }},
               {name:'testid',index:'testid',editable: true},
               {name:'my_zd',index:'my_zd',editable: true},
               {name:'opuser',index:'opuser',editable: true},
               {name:'opdaytime',index:'opdaytime',editable: true},
               {name:'pny',index:'pny',editable: true},
               {name:'processinstanceid',index:'processinstanceid',editable: true}
	], 
	reloadAfterSubmit: true,
	viewrecords : true,
	rowNum:20,
	rowList:[20,50,100,1000],
	pager : pager_selector,
//底部合计   footerrow : true, 
	altRows: true,
//toppager: true,
					
	multiselect: true,
//multikey: "ctrlKey",
    multiboxonly: true,
    rownumbers: true,
	loadComplete : function() {
		var table = this;
		setTimeout(function(){
			styleCheckbox(table);
			updateActionIcons(table);
			updatePagerIcons(table);
			enableTooltips(table);
		}, 0);
	},
					
/*底部合计
     gridComplete : function() { 
         var $form = $("#" + $("#pageGrid").attr("rel"));
         $.ajax({
             type :'POST',
             url : common.ctx + "/deal/getAllOrded",
             data : $form.serializeArray(),
             dataType : "json",
             cache : false,
             success : function(json) {
                 $("#pageGrid").footerData("set", {
                     code : "支付总花费:",        //设置的是哪个列的名称,数据就显示在哪个列
                     dict_name : '合计数量'     //设置的是哪个列的名称,数据就显示在哪个列
                 });
             },
             error : YUNM.ajaxError
         }); 
     }
*/
			
// 					editurl: '<b:submitForm name="zftest_updateByPk.ext"//p>',//nothing is saved
//					caption: "测试-信息表管理" 
//,autowidth: true, 
/**
	,
	grouping:true, 
	groupingView : { 
		 groupField : ['name'],
		 groupDataSorted : true,
		 plusicon : 'fa fa-chevron-down bigger-110',
		 minusicon : 'fa fa-chevron-up bigger-110'
	},
	caption: "Grouping"
*/
			
});$(window).triggerHandler('resize.jqGrid');//trigger window resize to make the grid get the correct size</script/p> 

3.java 通过@function(id = "zftest_selectPageListBootstrap.ext", name = "查询分页数据") 注解进入selectPageListBootstrap()函数

Code view

@function(id = "zftest_selectPageListBootstrap.ext", name = "查询分页数据")
public void selectPageListBootstrap() throws Exception {
  String submitData = (String)getValueAt("submitData");
  JSONObject json = JSONObject.fromObject(submitData);   
  _map.put("name_key",(String)toNvlNull(json.get("name_key")));
  //分页:总数据SQL
  StringBuffer totalCount = new StringBuffer( zftestSql.selectPageListCount(_param,_map) ); 
  //分页:分页数据SQL
  ListPage(zftestSql.selectPageListBootstrapJqGrid(_param,_map), totalCount); 
  List _nList = (List)getValueAt("_nList");   
  //分页:分页数据Json格式
  setReplyPage("STREAM"+toJsonPageArrayBootstrapJqGridAddTotalPropertys(_nList,totalCount.toString()));
} 
参考来源: http://www.trirand.com/blog/?page_id=6

弹出子窗口

Code view

<link rel="stylesheet" type="text/css" href="<%=WEBPATH%>/assets/zeroModal/css/zeroModal.css" /> 
<script type="text/javascript" src="<%=WEBPATH%>/assets/zeroModal/js/zeroModal.js"></script>

<script type="text/javascript">
zeroModal.show({
 title: '信息',                      //子窗口标题
 iframe: true,
 url: 'read.jsp?timer='+new Date(),  //URL地址
 width: '80%',                       //宽度
 height: '90%',                      //高度
 cancel: false,
 onComplete:function () {
    //弹出子窗口后调用         
 }, 
 onClosed:function(action){ 
    //关闭子窗口后时调用         
 }
}); 
</script> 

关闭子窗口

子窗口页面中调用

<link rel="stylesheet" type="text/css" href="<%=WEBPATH%>/assets/zeroModal/css/zeroModal.css" /> 
<script type="text/javascript" src="<%=WEBPATH%>/assets/zeroModal/js/zeroModal.js"></script>
		
<script type="text/javascript"> 
//标准方法接口定义 -关闭窗口
function CloseWindow(action) {    
	try{window.parent.zeroModal.closeAll(action);}catch(err){} 
}
</script> 

新增功能

调用弹出新增页窗口

zeroModal.show({
 title: '信息表新增',
 iframe: true,
 url: '/web/add.jsp?timer='+new Date(),
 width: '80%',
 height: '90%',
 cancel: false,
 onComplete:function () { 
    //var data = { action: "edit"};
    //this.getIFrameEl.contentWindow.SetData(data);  //向子窗口页面传递参数,同时调用子窗口函数SetData(data)
 }, 
 onClosed:function(action){ 
    jQuery(grid_selector).trigger('reloadGrid');  //关闭时刷新数据
 }
}); 

表单

<form id="defaultForm" name="defaultForm" class="form-horizontal" role="form">  
<table id="simple-table" class="table table-striped table-bordered table-hover" >
<tr>
<td align="right" style="width:300px;">
  <label > 用户电话 <font color="red">*</font></label>
</td>
<td>
  <input id="user_phone" type="text"/>
</td>
</tr>
<tr>
<td align="right" style="width:300px;">
  <label > 用户住址 <font color="red">*</font></label>
</td>
<td>
  <input id="user_add" type="text"/>
</td>
</tr>
</table>
<table class="table">  
  <tr> 
   <td align="center"> 
       <button onclick="thisWindClose()">
		<i class="ace-icon fa fa-undo bigger-110"></i>
		关闭
	</button> 
	<button type="button"  onclick="dosubmit()">
       <i class="ace-icon fa fa-check bigger-110"></i>
		提交
	</button> 
	   </td> 
	  </tr>
</table> 
</form>

提交表单

<script type="text/javascript">
/*表单序列化*/
$.fn.serializeObject = function(){  
  var o = {};  
  var a = this.serializeArray();  
  $.each(a, function() {  
      if (o[this.name]) {  
          if (!o[this.name].push) {  
              o[this.name] = [o[this.name]];  
          }  
          o[this.name].push(this.value || '');  
      } else {  
          o[this.name] = this.value || '';  
      }  
  });  
  return o;  
};
/*表单验证*/
function formDataValidate(){                  //表单验证 
 if($("#user_phone").val() == ""){ 
	$("#user_phone").tips({                   //tips提示 
		side : 1,                          //tips提示位置 
		msg : '*-该项为必输项',             //tips提示内容 
		bg : '#FF5080',                    //tips提示颜色 
		time : 3                           //tips提示时间(秒)
	}); 
    $("#user_phone").focus();
    return true;
 } 
 if($("#user_add").val() == ""){ 
	$("#user_add").tips({
		side : 1,
		msg : '*-该项为必输项',
		bg : '#FF5080',
		time : 3
	}); 
    $("#user_add").focus();
    return true;
 } 
 return false;                                 //验证成功
}
/*表单提交*/
function dosubmit(){  
 var defaultForm = $('#defaultForm');          //获取表单对象
 if (formDataValidate()) return;               //表单验证 
 $("body").mLoading();                         //开启遮罩loading组件
 var json = JSON.stringify(defaultForm.serializeObject()); //表单Json 
 $.ajax({
        url: '/link/scev',
        type: 'post',
        data: {submitData: json},
        cache: false,
        success: function (result_text) {
             $("body").mLoading("hide");          //关闭遮罩loading组件
            //后台返回值
        	var result = eval('(' + result_text + ')');
            if (result.success) { 
                zeroModal.success({              //成功提示
                       content: '提示!',
                       contentDetail: result.msg,//后台返回操作成功
                       okFn: function(){
                	       CloseWindow("save");  //关闭弹出子窗口
                       }
                     }); 
            } else { 
            	zeroModal.error({                //失败提示
                       content: '提示!',
                       contentDetail: result.msg,  //后台返回操作失败
                       okFn: function(){
            		       CloseWindow("save");  //关闭弹出子窗口
                       }
                }); 
            }
        }
    });
} 
function thisWindClose(){
 CloseWindow("");
}
//标准方法接口定义 -关闭窗口
function CloseWindow(action) {    
 try{window.parent.zeroModal.closeAll(action);}catch(err){} 
}
</script>

后台处理

@function(id = "/link/scev", name = "信息表")
public void insertSql() throws Exception{
try{
 String submitData = (String)getValueAt("submitData");
 JSONObject json = JSONObject.fromObject(submitData);    
 map.put("user_phone", (String)toNvlNull(json.get("user_phone")));//用户电话
 map.put("user_add", (String)toNvlNull(json.get("user_add")));//用户住址 
 Update( zTestSql.insertSql(_param, _map) );            //执行SQL
 msg = new Message(true, "操作成功!"); 
 commitStraction(); 
}catch(Exception e){ 
 rollbackStraction();
 msg = new Message(false, "操作失败!"+e.getLocalizedMessage()); 	
} 
 setReplyPage("STREAM"+toJsonMap(msg)); 
} 

修改功能

调用弹出修改页窗口

zeroModal.show({
 title: '信息表修改',
 iframe: true,
 url: '/web/edit.jsp?timer='+new Date(),
 width: '80%',
 height: '90%',
 cancel: false,
 onComplete:function () { 
    var data = { action: "edit"};
    this.getIFrameEl.contentWindow.SetData(data);  //向子窗口页面传递参数,同时调用子窗口函数SetData(data)
 }, 
 onClosed:function(action){ 
    jQuery(grid_selector).trigger('reloadGrid');  //关闭时刷新数据
 }
}); 

表单

<form id="defaultForm" name="defaultForm" class="form-horizontal" role="form">  
<table id="simple-table" class="table table-striped table-bordered table-hover" >
<tr>
<td align="right" style="width:300px;">
  <label > 用户电话 <font color="red">*</font></label>
</td>
<td>
  <input id="user_phone" type="text"/>
</td>
</tr>
<tr>
<td align="right" style="width:300px;">
  <label > 用户住址 <font color="red">*</font></label>
</td>
<td>
  <input id="user_add" type="text"/>
</td>
</tr>
</table>
<table class="table">  
  <tr> 
   <td align="center"> 
       <button onclick="thisWindClose()">
		<i class="ace-icon fa fa-undo bigger-110"></i>
		关闭
	</button> 
	<button type="button"  onclick="dosubmit()">
       <i class="ace-icon fa fa-check bigger-110"></i>
		提交
	</button> 
	   </td> 
	  </tr>
</table> 
</form>

提交表单

<script type="text/javascript">
/*表单序列化*/
$.fn.serializeObject = function(){  
  var o = {};  
  var a = this.serializeArray();  
  $.each(a, function() {  
      if (o[this.name]) {  
          if (!o[this.name].push) {  
              o[this.name] = [o[this.name]];  
          }  
          o[this.name].push(this.value || '');  
      } else {  
          o[this.name] = this.value || '';  
      }  
  });  
  return o;  
};
/*表单验证*/
function formDataValidate(){                  //表单验证 
 if($("#user_phone").val() == ""){ 
	$("#user_phone").tips({                   //tips提示 
		side : 1,                          //tips提示位置 
		msg : '*-该项为必输项',             //tips提示内容 
		bg : '#FF5080',                    //tips提示颜色 
		time : 3                           //tips提示时间(秒)
	}); 
    $("#user_phone").focus();
    return true;
 } 
 if($("#user_add").val() == ""){ 
	$("#user_add").tips({
		side : 1,
		msg : '*-该项为必输项',
		bg : '#FF5080',
		time : 3
	}); 
    $("#user_add").focus();
    return true;
 } 
 return false;                                 //验证成功
}
/*表单提交*/
function dosubmit(){  
 var defaultForm = $('#defaultForm');          //获取表单对象
 if (formDataValidate()) return;               //表单验证 
 $("body").mLoading();                         //开启遮罩loading组件
 var json = JSON.stringify(defaultForm.serializeObject()); //表单Json 
 $.ajax({
        url: '/link/scev',
        type: 'post',
        data: {submitData: json},
        cache: false,
        success: function (result_text) {
             $("body").mLoading("hide");          //关闭遮罩loading组件
            //后台返回值
        	var result = eval('(' + result_text + ')');
            if (result.success) { 
                zeroModal.success({              //成功提示
                       content: '提示!',
                       contentDetail: result.msg,//后台返回操作成功
                       okFn: function(){
                	       CloseWindow("save");  //关闭弹出子窗口
                       }
                     }); 
            } else { 
            	zeroModal.error({                //失败提示
                       content: '提示!',
                       contentDetail: result.msg,  //后台返回操作失败
                       okFn: function(){
            		       CloseWindow("save");  //关闭弹出子窗口
                       }
                }); 
            }
        }
    });
}
//标准方法接口定义 
function SetData(data) {  
 $.ajax({
      url: '/relosd/link',
      type: 'post',
      data: {submitData: data.id},
      cache: false,
      success: function (result_text) {             //后台返回值 
      	var result = eval('(' + result_text + ')'); //json转对象 
      	loadData(result_text);                      //控件赋值
      }
 }); 
}
/*关闭窗口*/
function thisWindClose(){
 CloseWindow("");
}
//标准方法接口定义 -关闭窗口
function CloseWindow(action) {    
 try{window.parent.zeroModal.closeAll(action);}catch(err){} 
}
/*控件赋值*/ 
function loadData(jsonStr){
 $('#defaultForm').bootstrapValidator('resetForm', true);
 var obj = eval("("+jsonStr+")"); 
 var key,value,tagName,type,arr;
 for(x in obj){
  key = x;
  value = obj[x];
  $("[name='"+key+"'],[name='"+key+"[]']").each(function(){
  tagName = $(this)[0].tagName;
  type = $(this).attr('type');
  if(tagName=='INPUT'){
    if(type=='radio'){
      $(this).attr('checked',$(this).val()==value);
    }else if(type=='checkbox'){
    arr = value.split(',');
    for(var i =0;i<arr.length;i++){
      if($(this).val()==arr[i]){
        $(this).attr('checked',true);
          break;
	  }
    }
	}else{
		$(this).val(value);
	}
	}else if(tagName=='SELECT' || tagName=='TEXTAREA'){
		$(this).val(value);
	} 
  });
 }
} 
</script>

后台处理

@function(id = "/link/scev", name = "信息表")
public void insertSql() throws Exception{
try{
 String submitData = (String)getValueAt("submitData");
 JSONObject json = JSONObject.fromObject(submitData);    
 map.put("user_phone", (String)toNvlNull(json.get("user_phone")));//用户电话
 map.put("user_add", (String)toNvlNull(json.get("user_add")));//用户住址 
 Update( zTestSql.updateSql(_param, _map) );            //执行SQL
 msg = new Message(true, "操作成功!"); 
 commitStraction(); 
}catch(Exception e){ 
 rollbackStraction();
 msg = new Message(false, "操作失败!"+e.getLocalizedMessage()); 	
} 
 setReplyPage("STREAM"+toJsonMap(msg)); 
} 

删除功能

Code view

	
<script type="text/javascript"> 
//根据主键删除数据
$("#itme_delete").click(function(){  
 var rowids = $(grid_selector).jqGrid('getGridParam','selarrrow');   //获取选择的数据
 if(rowids == ''){
		 zeroModal.alert('提示:请选择一条记录');                     
		 return;
 }else{ 
  zeroModal.confirm("提示:[确定删除记录?]", function() { 
   var ids = [];
   for (var i = 0; i < rowids.length;  i++) { 
  	 var rowData = $(grid_selector).jqGrid('getRowData',rowids[i]);
       ids.push("'"+rowData.testid+"'"); 
   }
   var id = ids.join(',');                                           //将数据拼接'001','002'格式
        $.ajax({
            url: '/ssek/del/',                                       //URL地址
            type: 'post',
            data: {testid: id},                                      //传值
            cache: false,
            success: function (result_text) {
            	var result = eval('(' + result_text + ')');
              if (result.success) {  
              	zeroModal.success({
                     content: '提示!',
                     contentDetail: result.msg,
                     okFn: function(){
              		jQuery(grid_selector).trigger('reloadGrid');    //刷新列表
                     }
                   });
              } else {
              	zeroModal.error('提示:'+result.msg );  
              } 
            }
        });
	}); 
 } 
});
</script>

遮罩功能

Code view

<link rel="stylesheet" href="<%=WEBPATH%>/assets/mloading/jquery.mloading.css"> 
<script src="<%=WEBPATH%>/assets/mloading/jquery.mloading.js"></script>

<script type="text/javascript">
$("body").mLoading();      //开启遮罩
$("body").mLoading("hide");//关闭loading组件
</script> 

后台跳转和异步

setReplyPage()函数

java
跳转模式:setReplyPage(webpath+"/web/main/profile.jsp");
异步模式:setReplyPage("STREAM"+toJsonMap(msg)); //STREAM模式返回数据流

前后端文件上传

ppfiledown plug-in components

html/jsp
前台数据展示采用ppfiledown展现
java
使用cos.jar
multi.getFile(String filesName)
renameTo(File inf)
支持上传多文件,解决并发覆盖的问题

1.页面包含 ppfiledown.js 标签

Code view

<!DOCTYPE html>
<!-- release v4.3.6, copyright 2014 - 2017 Kartik Visweswaran -->
<html lang="utf-8">
    <head>
        <meta charset="UTF-8"/>
        <meta http-equiv="Content-Type" content="multipart/form-data; charset=UTF-8">
		<title></title>
		<link rel="stylesheet" type="text/css" href="<%=WEBPATH%>/assetspfiledown/css/bootstrap.css">
		<link rel="stylesheet" type="text/css" href="<%=WEBPATH%>/assetspfiledown/css/bootstrap-theme.min.css">
		<link rel="stylesheet" type="text/css" href="<%=WEBPATH%>/assetspfiledown/css/style.css">
		<link rel="stylesheet" type="text/css" href="<%=WEBPATH%>/assetspfiledown/css/demo.css">
		<link rel="stylesheet" type="text/css" href="<%=WEBPATH%>/assetspfiledown/webuploader-0.1.5/webuploader.css">
        
    </head>
    <body>

   <div class="page-container">
		<div id="uploader" class="wu-example">
			<div class="queueList">
				<div id="dndArea" class="placeholder">
					<div id="filePicker"></div>
					<p>或将文件拖到这里<>
				</div>
			</div>
			<div class="statusBar" style="display:none">
				<div class="progress">
					<span class="text">0%</span>
					<span class="percentage"></span>
				</div>    
				<div class="info"></div>
				<div class="btns">
					<div id="filePicker2"></div>
					<div class="uploadBtn">开始上传</div>
				</div>
			</div>
		</div>
	</div>
</body>
	<script type="text/javascript" src="<%=WEBPATH%>/assetspfiledown/js/jquery.min.js"></script>
	<script type="text/javascript" src="<%=WEBPATH%>/assetspfiledown/js/bootstrap.min.js"></script>
	<script type="text/javascript" src="<%=WEBPATH%>/assetspfiledown/webuploader-0.1.5/webuploader.js"></script>
	<script src="<%=WEBPATH%>/assetspfiledown/webuploader-0.1.5/extend-webuploader.js" type="text/javascript"></script> 
	
    <!--//弹出模态窗口       https://my.oschina.net/u/2391658/blog/711625 --> 
	<link rel="stylesheet" type="text/css" href="<%=WEBPATH%>/assets/zeroModal/css/zeroModal.css" /> 
	<script type="text/javascript" src="<%=WEBPATH%>/assets/zeroModal/js/zeroModal.js"></script>
	<script type="text/javascript">
	window.webuploader = {
		config:{
			wrapId: 'uploader', //必填
		},
		pickLabel: '点击选择文件',//按钮文字
		extensions: 'jpg,png,gif,jpeg',//后缀
		fileNumLimit: 1,//最大数量
		fileSingleSizeLimit: 100 * 1024 * 1024,//单个文件最大
		WEBPATH: '<%=WEBPATH%>/',//文件图片地址
		//处理客户端新文件上传时,需要调用后台处理的地址, 必填
		uploadUrl: "<b:submitForm name='upUserImgAndUpImgBySessUserId.ext'/>",
	}
	//全部完成后执行
	function finishCallBack(data){
		zeroModal.alert({
            content: '提示!',
            contentDetail: data,
            okFn: function(){
	            CloseWindow(data);
            }
          }); 
	}
	//每次上传成功后执行
	function uploadSuccessCallBack(data){  
		CloseWindow(data.data); 
	}
	//标准方法接口定义 
	function SetData(data) { 
	
	} 	
	//标准方法接口定义 -关闭窗口
	function CloseWindow(action) {    
		try{window.parent.zeroModal.closeAll(action);}catch(err){} 
	}
	</script>
</html>

2.java 通过注解注入函数@function(id = "upUserImgAndUpImgBySessUserId.ext", name = "更新用户头像根据SessionID") 调用upUserImgAndUpImgBySessUserId()

Code view

@function(id = "upUserImgAndUpImgBySessUserId.ext", name = "更新用户头像根据SessionID")
public void upUserImgAndUpImgBySessUserId() throws Exception{
	Map fileProperMap = new HashMap();
	try{ 
		String fileName = "";//文件名+后扩展名 
		String newFilename = "";  
		String uploadPath = "tmpfiles"; 
		String path = thisRequest.getSession().getServletContext().getRealPath(uploadPath); 
		MultipartRequest multi = new MultipartRequest(thisRequest,path, 100 * 1024 * 1024, "UTF-8"); 
		//如果有上传文件, 则保存到数据内
		Enumeration files = multi.getFileNames();
		String filesName = null;
		while (files.hasMoreElements()) {
			filesName = (String)files.nextElement();// 文件文本框的名称  
			// 从上传图片筐中获取图片
			File uploadFile = multi.getFile(filesName);        
			long len = uploadFile.length();
			if (null != uploadFile && uploadFile.length() > 0) {  
				//fileName为原文件名   
				fileName = uploadFile.getName();
				//图片后缀  
				String extention= fileName.substring(fileName.lastIndexOf("."));   
				if(!".jar".equalsIgnoreCase(extention)){ 
				}  
				Date date=new Date();
				DateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");//设置当前系统时间格式
				String nowtime= df.format(date);
				//新的图片名(时间+后缀)  
				newFilename = nowtime + extention;  
				//将上传图片改名字
				File inf = new File(path + "/" +newFilename);   
				uploadFile.renameTo(inf);  
                msg = new Message(true, "操作成功!");   
                msg.setData(uploadPath+"/" +newFilename); 
                _wheremap.clear();
                _map.clear();
    			_wheremap.put("userid", getSessionData("_@userid"));//人员编号 主键
    			_map.put("photo_url", uploadPath+"/" +newFilename);//人事所属分公司 
    	    	Update(mainSql.updateDynamicSql(_param, _map, _wheremap));
    	    	commitStraction();  
			}
		} 
		commitStraction(); 
	}catch(Exception e){ 
		rollbackStraction();
		msg = new Message(false, "操作失败!"+e.getLocalizedMessage()); 	
	} 
	setReplyPage("STREAM"+toJsonMap(msg)); 
}

前后端文件下载


BufferedInputStream plug-in components

html/jsp
前台iframe标签,通过js提交后台
java
使用BufferedInputStream将文件输出

1.页面包含 iframe 标签

Code view

<iframe id="exportIFrame" style="display:none;"></iframe> 
  <!--下载浏览器-->
  <form id="excelForm" name="excelForm"  action="<b:submitForm name='logdownfile.com'/>" method="post" target="excelIFrame">
     <input type="hidden" id="submitData" name="submitData"  />
  </form>
<iframe id="excelIFrame" name="excelIFrame" style="display:none;"></iframe>
<script type="text/javascript"> 
//下载浏览器
function logdownfile(file_type){     
   $('#submitData').val(file_type); 
   $('#excelForm').submit();
}
</script>

2.java 通过注解注入函数@function(id = "logdownfile.com", name = "下载浏览器") 调用logdownfile()

Code view

 //下载浏览器
@function(id = "logdownfile.com", name = "下载浏览器")
public void logdownfile() throws Exception{ 
    String know_file_path = "tmpfiles/GoogleChromePortable.rar";
    String dowFileName = "GoogleChrome.rar";
    String submitData = (String)this.getValueAt("submitData");
    if("browser".equals(submitData)){
	      know_file_path = "tmpfiles/GoogleChromePortable.rar";
	      dowFileName = "GoogleChrome.rar";
    }else if("office".equals(submitData)){
    	  know_file_path = "tmpfiles/[Microsoft.Office.2007.中文专业增强版(微软原版)].Microsoft.Office2007.rar";
	      dowFileName = "[Microsoft.Office.2007.中文专业增强版(微软原版)].Microsoft.Office2007.rar";
    } 
	String rootFileFullPath = thisRequest.getRealPath("") +  know_file_path; 
	File f = new File(rootFileFullPath);
       if (!f.exists()) {
           thisResponse.sendError(404, "File not found!");
           return;
       }
       BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));
       byte[] buf = new byte[1024];
       int len = 0; 
       thisResponse.reset(); // 非常重要
       if (false) { // 在线打开方式
           URL u = new URL("file:///" + rootFileFullPath);
           thisResponse.setContentType(u.openConnection().getContentType());
           thisResponse.setHeader("Content-Disposition", "inline; filename=" + URLEncoder.encode(dowFileName, "UTF-8"));
           // 文件名应该编码成UTF-8
       } else { // 纯下载方式
       	thisResponse.setContentType("application/x-msdownload");
       	thisResponse.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(dowFileName, "UTF-8"));
       }
       OutputStream out = thisResponse.getOutputStream();
       while ((len = br.read(buf)) > 0)
           out.write(buf, 0, len);
       br.close();
       out.flush();
       out.close(); 
}

前后端Excel导入


ppfiledown plug-in components

html/jsp
前台数据展示采用ppfiledown展现
extensions: 'xlx,xlsx',//后缀
fileNumLimit: 1,//最大数量
fileSingleSizeLimit: 100 * 1024 * 1024,//单个文件最大
java
使用cos.jar
multi.getFile(String filesName)
renameTo(File inf)
使用ExcelSheetParser工具类

1.页面包含 ppfiledown.js 标签

Code view

<!DOCTYPE html>
<!-- release v4.3.6, copyright 2014 - 2017 Kartik Visweswaran -->
<html lang="utf-8">
    <head>
        <meta charset="UTF-8"/>
        <meta http-equiv="Content-Type" content="multipart/form-data; charset=UTF-8">
		<title></title>
		<link rel="stylesheet" type="text/css" href="<%=WEBPATH%>/assetspfiledown/css/bootstrap.css">
		<link rel="stylesheet" type="text/css" href="<%=WEBPATH%>/assetspfiledown/css/bootstrap-theme.min.css">
		<link rel="stylesheet" type="text/css" href="<%=WEBPATH%>/assetspfiledown/css/style.css">
		<link rel="stylesheet" type="text/css" href="<%=WEBPATH%>/assetspfiledown/css/demo.css">
		<link rel="stylesheet" type="text/css" href="<%=WEBPATH%>/assetspfiledown/webuploader-0.1.5/webuploader.css">
        
    </head>
    <body>

   <div class="page-container">
		<div id="uploader" class="wu-example">
			<div class="queueList">
				<div id="dndArea" class="placeholder">
					<div id="filePicker"></div>
					<p>或将文件拖到这里<>
				</div>
			</div>
			<div class="statusBar" style="display:none">
				<div class="progress">
					<span class="text">0%</span>
					<span class="percentage"></span>
				</div>    
				<div class="info"></div>
				<div class="btns">
					<div id="filePicker2"></div>
					<div class="uploadBtn">开始上传</div>
				</div>
			</div>
		</div>
	</div>
</body>
	<script type="text/javascript" src="<%=WEBPATH%>/assetspfiledown/js/jquery.min.js"></script>
	<script type="text/javascript" src="<%=WEBPATH%>/assetspfiledown/js/bootstrap.min.js"></script>
	<script type="text/javascript" src="<%=WEBPATH%>/assetspfiledown/webuploader-0.1.5/webuploader.js"></script>
	<script src="<%=WEBPATH%>/assetspfiledown/webuploader-0.1.5/extend-webuploader.js" type="text/javascript"></script> 
	
    <!--//弹出模态窗口       https://my.oschina.net/u/2391658/blog/711625 --> 
	<link rel="stylesheet" type="text/css" href="<%=WEBPATH%>/assets/zeroModal/css/zeroModal.css" /> 
	<script type="text/javascript" src="<%=WEBPATH%>/assets/zeroModal/js/zeroModal.js"></script>
	<script type="text/javascript">
	window.webuploader = {
		config:{
			wrapId: 'uploader', //必填
		},
		pickLabel: '点击选择文件',//按钮文字
		extensions: 'xls,xlsx',//后缀
		fileNumLimit: 1,//最大数量
		fileSingleSizeLimit: 100 * 1024 * 1024,//单个文件最大
		WEBPATH: '<%=WEBPATH%>/',//文件图片地址
		//处理客户端新文件上传时,需要调用后台处理的地址, 必填
		uploadUrl: "<b:submitForm name='upUserImgAndUpImgBySessUserId.ext'/>",
	}
	//全部完成后执行
	function finishCallBack(data){
		zeroModal.alert({
            content: '提示!',
            contentDetail: data,
            okFn: function(){
	            CloseWindow(data);
            }
          }); 
	}
	//每次上传成功后执行
	function uploadSuccessCallBack(data){  
		CloseWindow(data.data); 
	}
	//标准方法接口定义 
	function SetData(data) { 
	
	} 	
	//标准方法接口定义 -关闭窗口
	function CloseWindow(action) {    
		try{window.parent.zeroModal.closeAll(action);}catch(err){} 
	}
	</script>
</html>

2.java 通过注解注入函数@function(id = "wagesFileImport.ext", name = "导入业务Excel") 调用wagesFileImport()

Code view

/**
 * 上传excel文件
 * @param List param,Map map 
 * @throws Exception
 */
private void wagesFileImport() throws Exception{ 
    String date1 = (String)getValueAt("date1"); 
	String fileName = "";//文件名+后扩展名
	String extStr = "";//扩展名
	String newFilename = "";  
	String uploadPath = "tmpfiles"; 
	String path = thisRequest.getSession().getServletContext().getRealPath(uploadPath);
	MultipartRequest multi = new MultipartRequest(thisRequest,path, 100 * 1024 * 1024, "UTF-8"); 
	try{ 
		//如果有上传文件, 则保存到数据内
		Enumeration files = multi.getFileNames();
		String filesName = null;  
        while (files.hasMoreElements()) {
	    filesName = (String)files.nextElement();// 文件文本框的名称  
        // 获取该文件框中上传的文件,即对应到上传到服务器中的文件  
        File uploadFile = multi.getFile(filesName);    
        if (null != uploadFile && uploadFile.length() > 0) {  
        	 //fileName为原文件名   
            fileName = uploadFile.getName();
            //文件后缀  
            String extention= fileName.substring(fileName.lastIndexOf("."));   
            Date date=new Date();
			DateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");//设置当前系统时间格式
			String nowtime= df.format(date); 
            //新的文件名(时间+后缀)  
			newFilename = nowtime + extention;   
			//将上传文件改名字
            File f = new File(path + "/" +newFilename);  
            uploadFile.renameTo(f); 
            //解析CSV文件内容 
			ExcelSheetParser parser = new ExcelSheetParser(f);
			List<List> datas = parser.getDatasInSheet(0); 
			_wheremap.clear();
			_wheremap.put("wages_time", date1);
			Update( sxoaWagesSql.deleteDynamicSql(_param, _wheremap) );
	       for (int i = 1; i < datas.size(); i++) {
		    List row = datas.get(i);					    
	        String i_info = "";
		    for (short j = 0; j < row.size(); j++) {
			  if(row.get(0) == null){ 
				//dbRollBack();
				//msg = new Message(false, "操作失败。请使用标准文件格式!" ); 
				//setReplyPage("STREAM"+toJsonMap(msg)); 
				//return; 
			  }
		      Object value;
		      if(row.get(j) == null){
		    	  value = "-";					    	  
		      }else{
		    	  value = row.get(j);
		      }
		      i_info += "," +toNvlNull(String.valueOf(value));			 
		    } 
		    //插入业务表
		    _map.clear();
		    String wages_id = getKeyGuid();
		    _map.put("wages_id", wages_id);//表主键
		    _map.put("wages_time", date1);  
		    try{_map.put("wages_name", 	i_info.split(",")[1]);}catch (Exception e){_map.put("wages_name",e.getMessage());} 
		    try{_map.put("wages_department", i_info.split(",")[2]);}catch (Exception e){_map.put("wages_department", e.getMessage());}
		    try{_map.put("wages_post", 	i_info.split(",")[3]);}catch (Exception e){_map.put("wages_post",e.getMessage());}
		    try{_map.put("wages_post_pay", 	i_info.split(",")[4]);}catch (Exception e){_map.put("wages_post_pay",e.getMessage());} 
		    _map.put("opusercode", (String)getSessionData("_@usercode"));//操作人代码
		    _map.put("opuserdaytime", create_date);//操作时间yyyy-mm-dd hh24:mi:ss
	    	int _nInt = Update( sxoaWagesSql.insertDynamicSql(_param, _map) );  
		    } 
           }
    	 }   
        msg = new Message(true, "操作成功!"); 
        commitStraction();
    }catch(Exception e){ 
    	rollbackStraction();
        msg = new Message(false, "操作失败!"+e.getLocalizedMessage()); 	
    } 
        setReplyPage("STREAM"+toJsonMap(msg)); 
}

前后端Excel导出


导出Excel数据(标题行格式) plug-in components

html/jsp
前台iframe标签,通过js提交后台
java
1.首先在sys.properties配置列名、列宽、和列变量名称
2.查询数据结果集合
3.重新封装结果集到List中
4.自动出现下载提示框

1.页面包含 iframe 标签

Code view

<iframe id="exportIFrame" style="display:none;"></iframe> 
  <!--下载浏览器-->
  <form id="excelForm" name="excelForm"  action="<b:submitForm name='downfileExc.ext'/>" method="post" target="excelIFrame">
     <input type="hidden" id="submitData" name="submitData"  />
  </form>
<iframe id="excelIFrame" name="excelIFrame" style="display:none;"></iframe>
<script type="text/javascript"> 
//下载浏览器
function logdownfile(file_type){     
   $('#submitData').val(file_type); 
   $('#excelForm').submit();
}
</script>

2.在文件sys.properties中配置列名、列宽、和列变量名称

Code view

/**
  * PsonAll: 导出的文件的名称
  * PsonAll.xlsx  : 单元格位置内容设置
  *                 |0,2,F,考勤人员统计信息表|
  *                 0=行
  *                 2=列
  *                 F=固定字段类型
  *                 考勤人员统计信息表=具体内容
  *                 |1,0,LV,list1|
  *                 LV=集合数据字段类型
  *                 list1=集合数据字段变量名称
  * PsonAll.cols  :列的宽度  
  * PsonAll.list1 :集合数据字段变量初始化
  */
PsonAll.xlsx=|0,2,F,考勤人员统计信息表|1,0,F,日期|0,1,F,员工名称|0,2,F,考勤分类|0,3,F,签到名称|0,4,F,签到时间|0,5,F,签到状态|1,0,LV,list1
PsonAll.cols=2,30|3,20|4,20|5,20|6,20|7,20|8,20|9,20|
PsonAll.list1=

3.java 通过注解注入函数@function(id = "downfileExc.ext", name = "下载浏览器") 调用downfileExc()

Code view

@function(id = "downfileExc.ext", name = "生成并下载Excel")
public void selectAllList() throws Exception{
    //数据查询
    List _nList = List( zftestSql.selectAllList(_param,_map) );
    /**
    *设置导出标识
    *_IMPXLSX=固定格式,不变
    *PsonAll=在文件sys.properties中配置的导出的文件的名称
    */
    setValueAt("_IMPXLSX", "PsonAll");
	xlsxBuild();    
}
//继承父类来的函数,固定函数名,做一个转换调用就可以
private void xlsxSetData(String varflag) {
	if(super.xlsxReqUrl.equals("PsonAll")){
		xlsx_Exc(varflag);//继续传递变量
	}
}
private void xlsx_Exc(String varflag){
       if("list1".equals(varflag)){
       	List list = (List)getValueAt("_nList");
       	List list1 = new ArrayList();
   		for(int i=0;i<list.size();i++){
   			List listItem = new ArrayList();
   			Map map = (Map)list.get(i);  
   			listItem.add(toNvlNull(map.get("protype_name_cn")));
   			listItem.add(toNvlNull(map.get("pro_name")));
   			listItem.add(toNvlNull(map.get("project_def_time"))); 
   			listItem.add(toNvlNull(map.get("depart_name_cn")));
   			listItem.add(toNvlNull(map.get("code_cn"))); 
   			listItem.add(toNvlNull(map.get("subproject_name")));
   			listItem.add(toNvlNull(map.get("ys_new"))); 
   			listItem.add(toNvlNull(map.get("year_ys")));
   			listItem.add(toNvlNull(map.get("year"))); 
   			listItem.add(toNvlNull(map.get("los_year"))); 
       		list1.add(listItem);
       		listItem=null;
   		}
   		xlsxWriteCell(varflag,list1);//继承父类来的函数,继续传递变量
   		list1 = null; 
       }
}
//完成

缓冲区数据在Java端翻译字典


java端字典编码翻译 plug-in components

系统启动时加载base_sysdictdef表,将数据存放在应用端数据缓冲区中,缓冲区数据通过标签及内部函数为系统业务字段编码做翻译使用。
java
1.toJsonMapDictAddColumn()
2.toJsonArrayDictAddColumn()

1.在java端调用继承类中的toJsonMapDictAddColumn()/toJsonArrayDictAddColumn()

Code view

/*
 * 翻译Map对象中的字段列
 * _nMap=Map对象
 *  base_department=缓存表的表名称
 * later_depart=Map对象中的要被翻译的数据编码字段
 * depart_name=缓存表的表翻译字段
 * depart_name_cn=Map对象中自动扩展一个翻译字段
 */
toJsonMapDictAddColumn(_nMap,"base_department", "later_depart", "depart_name", "depart_name_cn"); 
/*
 * 翻译List对象中的字段列
 * _nList=List对象
 *  base_department=缓存表的表名称
 * later_dept=List对象中的要被翻译的数据编码字段
 * depart_name=缓存表的表翻译字段
 * depart_name_cn=List对象中自动扩展一个翻译字段
 */
toJsonArrayDictAddColumn(_nList, "base_department", "user_dept", "depart_name", "depart_name_cn");

properties配置文件使用


sys.properties

框架提供一个sys.properties配置文件使用
通过SysProperty类对sys.properties文件进行读写操作

b标签使用


B.tag plug-in components

通过B.tag标签可实现select控件
1.<b:submitForm name=""/>
2.<b:dynamicoption dictTableSQL="" optionTextCode="" optionValueCode="" currentCode=""/ >
3.<b:sessionCheck> </b:sessionCheck>
4.<b:option dictTableName="" optionTextCode="" optionValueCode="" >
5.<b:dictToText dictTableName="" indexDictColumName="" indexDictCode="" >

Code view

/*
 * 转义后台访问地址 zftest_insertSql.ext
 * 例如:转义后 980FC75A1D423A9F37AF8DA11B583CF8F7E8921427E52CA0.h5html
 */
<b:submitForm name="zftest_insertSql.ext"/> 
/*
 * dictTableSQL=sql语句
 * optionTextCode=名字(option 名字)
 * optionValueCode=值(option Value)
 */
<select id="role_id" name="role_id" class="chosen-select"> 
  <b:dynamicoption  
  optionTextCode="rolename" 
  optionValueCode="rolecode"  
  dictTableSQL="select * from base_role order by 1"/> 				 
</select>
/*
 * 在页面上将body范围,用此标签。可防止跳过登录查看界面
 * 必须在登录认证后的jsp使用
 */
<b:sessionCheck> </b:sessionCheck> 
/*
 * dictTableName=缓冲区字典名称
 * optionTextCode=名字(option 名字)
 * optionValueCode=值(option Value)
 */
<select name="imenutype">
  <b:option dictTableName="dict_menutype" optionTextCode="name" optionValueCode="code"/>
</select>  
/*
 * dictTableName=缓冲区字典名称
 * indexDictCode=翻译的字段编码
 * indexDictColumName=缓冲区翻译字段名称
 */
<b:dictToText dictTableName="dict_appstutas" indexDictCode="<%= utl.nvl((String)map.get("appstutascode"),0)%>" indexDictColumName="name"/>

数据主键生成


数据主键生成 plug-in components

java 获取主键
1.this.getKeyGuid(); 32位UUID
2.this.getKeySys("OAID"); 每日流水号。函数可以自动获得业务表定义主键/单号/业务关联码

Code view

/*
 * 32位UUID 
 */
this.getKeyGuid(); 
/*
 * 每日流水号。函数可以自动获得业务表定义主键/单号/业务关联码 
 */
this.getKeySys("OAID");

调用存储过程


call函数调用存储过程 plug-in components

call函数调用存储过程
1.this.call("{call protest(?,?,?)}", callPara);

Code view

/**
*存储过程调用此函数
*参数1 inOut:IN  或者 OUT
*参数2 OracleTypes:VARCHAR2 
*参数3 paraPrintName:如果是输入参数为取变量值、如果是输出参数为Key键值
*参考如下: 
CallPara callPara=new CallPara();
callPara.addPara("IN","VARCHAR2","helloWord");
callPara.addPara("OUT","VARCHAR2","flg"); 
callPara.addPara("OUT","VARCHAR2","msg");    
Map callMap = this.call("{call protest(?,?,?)}", callPara);
System.out.println(callMap.get("flg"));
System.out.println(callMap.get("msg"));
System.out.println("结束");  
* @throws SQLException 
*/
  CallPara callPara=new CallPara();
  callPara.addPara("IN","VARCHAR2","helloWord");
  callPara.addPara("OUT","VARCHAR2","flg"); 
  callPara.addPara("OUT","VARCHAR2","msg");    
  Map callMap = this.call("{call protest(?,?,?)}", callPara);
  System.out.println(callMap.get("flg"));
  System.out.println(callMap.get("msg"));
  System.out.println("结束");

代码生成器的使用


1、打开[系统工具]-[代码生成]

2、输入数据库表名称,[确定]完成,代码生成完成

3、停止服务

4、刷新工程

5、代码生成完毕

6、配置菜单即可使用


数据交互方法


1、系统将统一管理前后台交互数据的Request变量,通过中间数据缓存区进行操作

通过这个变量监控,你可以看见所有传递的变量值

2、系统提供,两个方可以操作缓存区的值

         设置值:setValueAt(dataName, fieldValue);

         获取值:getValueAt(dataName);


Session获取


1、用户登录Session值

         页面添加 标签<% ctjee.CMisSessionMgr sn = new ctjee.CMisSessionMgr(request);%>

         调用方法获取<%=sn.getSessionData("字段名")%>

         _@userid=/用户编码

         _@usercode=/用户编码

         _@useraccount=/用户编码

         _@username/用户名称中文

         _@birthday/生日

         _@obstaclecode/允许登录标志

         _@company_code/公司编码

         _@job_number/员工编号

         _@photo_url/头像图片

         _@create_date/创建时间

         _@email/电子邮箱

         _@sex/性别

         _@departcode/入职部门

         _@isjob/是否离职

         _@marital/婚姻状态

         _@age/年龄

         _@tell_num/联系电话

2、切换权限时获取的活动权限Session值

         _@activity_rolecode/活动权限编码

         _@activity_atv_rolecode_name/活动权限

         _@activity_atv_processinstanceid/活动权限唯一标识

         _@activity_atv_company_code_name/活动权限公司名称

         _@activity_departcode/活动权限部门编码

         _@activity_company_code/活动权限公司编码

         _@activity_atv_depart_code_name/活动权限部门名称

         _@activity_usercode/活动权限用户编码


SQL调用


1、在Op中有三类执行SQL语句的方法

         List(String sql);查询 sql select 集合语句;

         Map(String sql); 查询 sql select 单行语句;

         Update(String sql); 执行 sql insert\update\delete语句;


数据库事务操作


1、事务处理

         事务提交:commitStraction();

         事务回滚:rollbackStraction();


请求结束返回值


1、Response相应结果返回

         跳转模式:setReplyPage(webpath+"/web/main/profile.jsp");

         //Map对象转JSON格式

         STREAM模式返回数据流:setReplyPage("STREAM"+toJsonMap(msg));

         //List对象转JSON格式

         STREAM模式返回数据流:setReplyPage("STREAM"+toJsonArray(obj));

         //分页:分页数据Json格式

         STREAM模式返回数据流:setReplyPage("STREAM"+toJsonPageArrayBootstrapJqGridAddTotalPropertys(_nList));


数据缓存区操作


         系统架构自动转换 页面变量及JSON格式数据为Key/Value格式存储缓存区

         preparedStatementParameters 数据区

         op和dao中提供给2个方法,用于操作缓存区的数据

         设置值:setValueAtPreparedStatementParameters(dataName, fieldValue);

         获取值:getValueAtPreparedStatementParameters(dataName);


占位符如何使用


         再SQL语句中关于占位符由三种:

         第一种是等号占位:${变量名}

         第二种是LIKE占位:${%,变量名,%}

         第三种是IN占位:${(,变量名,)} 数据格式:aaa,0bbb

         例如:select * from base_role where rolecode=${rolecode}


Pre执行SQL语句


         Pre语句是在原Update、Map、List、ContainIs+Pre,可执行SQL占位语句

         UpdatePre(String sql):执行delete、insert、update语句。

         UpdatePre(String sql,String key):执行delete、insert、update语句,自定临时变量名。

         ContainIsPre(String sql):判断主键是否被引用,多用于删除前执行。

         MapPre(String sql):单条数据查询。

         MapPre(String sql,String key):单条数据查询,自定临时变量名。

         ListPre(String sql):多条数据查询。

         ListPre(String sql,String key):多条数据查询,自定临时变量名。

         ListPagePre(String sql,String totalCount):分页数据查询。

         ListPagePre(String sql,StringBuffer totalCount,String key):分页数据查询,自定临时变量名。


开发者模式


         1、完全免费

         2、官网定期更换开发者许可证密钥

         3、控制台到期提醒

         4、[系统工具]-[资源监控]中查看

开发者密钥使用


1、开发者许可证密钥获取

         2、官网定期更换开发者许可证密钥http://www.ctjee.com/

                     

2、通过[运行参数]-[修改]替换,即可。重新启动服务。

                     


发布者模式


         1、官网购买发布者许可证


发布者密钥购买与使用


1、导出服务器序列号

                     

2、导入服务器序列号,立即购买。

                     

3、输入订单编号,点击[查询]。许可证密钥认领

                     

4、通过[运行参数]-[修改]替换,即可。重新启动服务。