/* * (#)TreeGrid.java 1.0 2011-3-3 2011-3-3 */ package com.yc.action.grid; import com.yc.action.BaseAction; import com.yc.exception.ApplicationException; import com.yc.factory.FactoryBean; import com.yc.multiData.SpObserver; import com.yc.service.build.type.T_22_Ifc; import com.yc.service.grid.GridServiceIfc; import com.yc.service.impl.DBHelper; import com.yc.utils.EncodeUtil; import com.yc.utils.FileUtil; import com.yc.utils.YCBase64; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.jdbc.support.rowset.SqlRowSetMetaData; import org.springframework.stereotype.Service; import java.io.File; import java.io.UnsupportedEncodingException; import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Pattern; /*** * TreeGrid表格生成, * * * @author 邓文峰 2011-3-3 **/ @SuppressWarnings("all") @Service("treeGrid") public class TreeGrid extends BaseAction implements TreeGridIfc { private static final int GRID_HEIGHT = 300; /** * 表格处理的业务类 */ @Autowired private GridServiceIfc gridService;//表格处理的业务类 //static String domain= AttachmentConfig.get("attachment.server"); /** * 取得与树设置有关的字段名, * 格式:树1字段1;树1字段2,树2字段1;树2字段2 * by danaus 2018-11-20 支持3类型显示多树功能而修改 **/ private synchronized String getTreeFields(int formid, String dbid) { try { SpObserver.setDBtoInstance("_" + dbid); return gridService.getSimpleJdbcTemplate().queryForObject("SELECT stuff((SELECT',' + CONVERT(VARCHAR, nodeid) FROM _systreeset where formid=? FOR XML PATH ('')),1,1,'') ", new Object[]{formid}, String.class); } finally { SpObserver.setDBtoInstance(); } } /** * 根据功能号取得格线高度 **/ public synchronized int getGrigHieght(int formID, int type, String dbid) { if (type != 8) { try { SpObserver.setDBtoInstance("_" + dbid); Integer in = gridService.getSimpleJdbcTemplate().queryForObject("select GridHeight from gform where formid=" + formID, Integer.class); return in == null ? 0 : in; } finally { SpObserver.setDBtoInstance(); } } else if (type == 8) {//3表结构 int temp = 0; int tg = 0; List list = null; try { SpObserver.setDBtoInstance("_" + dbid); list = gridService.getThreeTableInfo(formID); } finally { SpObserver.setDBtoInstance(); } if (list.size() == 0) { throw new ApplicationException("三表关联未设置好--9825"); } for (Map map : list) { temp = (Integer) map.get("DetailFormID"); tg = (map.get("gridHeight") == null) ? 0 : (Integer) map.get("gridHeight"); } list = null; try { SpObserver.setDBtoInstance("_" + dbid); int h = gridService.getSimpleJdbcTemplate().queryForObject("select GridHeight from gform where formid=" + formID, Integer.class); if (tg == 0) tg = gridService.getSimpleJdbcTemplate().queryForObject("select GridHeight from gform where formid=" + temp, Integer.class); return (tg == 0 ? GRID_HEIGHT : tg) + (h == 0 ? GRID_HEIGHT : h); } finally { SpObserver.setDBtoInstance(); } } else { return 0; } } /** * 根据类型选用不同的字段作为排序 * * @return 1表示清单,2表示明细 **/ private int setOrderName(TreeGridDTO dto) { switch (dto.winType) { case 9: case 15: case 17: case 499: case 497: if (dto.conNum == 0) { //isList=t return 1; } else return 2; case 1: if (dto.b497 || dto.b499) return 2; else return 1; default: return 1; } } private int setToolAdd(TreeGridDTO dto) { switch (dto.winType) { case 9: case 15: case 17: case 499: case 497: if (dto.conNum == 0) return 1; else return 2; case 18: case 38: case 19: return 1; default: return 2; } } //只有明细表才需要执行,其他的都只是输出{} private String setToolAddForNew(TreeGridDTO dto) { if (dto.postStatusAddNew) return "<%=bdMap.toString()%>"; switch (dto.winType) { case 9: case 15: case 17: case 499: case 497: if (dto.conNum == 0) return "{}"; else return "<%=bdMap.toString()%>"; case 18: case 38: case 19: return "{}"; default: return "{}"; } } /** * 根据窗体类型取得应当读取哪一个表的数据. **/ private synchronized int setGetPrivaryTable(int winType) { switch (winType) { case 5: case 9: case 2: case 30: case 301: case 10: case 19: case 304: return 1;//从表 case 8://三表 return 2; default: return 0; } } /** * 是否为单据类型, **/ private synchronized boolean isDanJun(TreeGridDTO dto) { if (dto.winType == 15 || dto.winType == 9 || dto.winType == 17 || dto.winType == 499 || dto.winType == 497) return true; else return false; } /** * 根据功能号取得主从表名称 -----9801信息---增加新窗体类型都需要增加相应判断 **/ public String getTableName(int formid, String winType, TreeGridDTO dto) { SqlRowSet gform = null; try { SpObserver.setDBtoInstance("_" + dto.dbid); gform = gridService.getGformByFormID(formid); } finally { SpObserver.setDBtoInstance(); } String[] temp = winType.split("\\|"); dto.winType = Integer.parseInt(temp[0]); dto.conNum = temp.length > 1 ? Integer.parseInt(temp[1]) : 0; if (!gform.wasNull()) { gform.first(); dto.HDTable = gform.getString("hdtable"); dto.dataformid = (gform.getString("dataformid") == null || gform.getString("dataformid").length() == 0 || gform.getString("dataformid").equalsIgnoreCase("0")) ? "" : (gform.getString("dataformid") + (!this.isDanJun(dto) ? "" : "@p@" + gform.getInt("predocstatus"))); dto.tranformid = (gform.getString("dataformid") == null || gform.getString("dataformid").length() == 0 || gform.getString("dataformid").equalsIgnoreCase("0")) ? "" : (gform.getString("dataformid")); dto.DTtable = gform.getString("dttable"); dto.frozencols = gform.getInt("frozencols"); dto.formname = gform.getString("formname"); dto.gantt = gform.getBoolean("isGantt");//是否为甘特图类型的功能号 dto.predocstatus = gform.getInt("predocstatus");//确认前状态,为了给格线在确认后不能再修改(新增,修改,删除) by 2013-02-01 dto.rowcopyfields = gform.getString("rowcopyfields");//行复制时排除字段 dto.pageSize = gform.getInt("pageSize");//页记录数 dto.autopaging = gform.getInt("autopaging");//是否分页 dto.optype = gform.getInt("optype");//功能号权限 dto.lockGridSort = gform.getInt("LockGridSort");//冻结列排序 dto.colset = gform.getInt("isShowCell");//是否显示列过滤 dto.mainCol = gform.getString("byGroup");//树分组显示字段 dto.isFilter = gform.getInt("isFilter");//是否打开过滤功能 boolean blactions = gform.getBoolean("addNewRow");//直接增行 // try { // dto.postStatusAddNew=gform.getInt("PostStatusGridAddNew");//根据状态值是否可以显示增行按钮,用在OA审核中 // }catch(Exception e) { // dto.postStatusAddNew=0; // } if (blactions) dto.actions = ""; dto.defaultRowCount = gform.getInt("DefaultRowCount");//格线默认加载时显示行数 if (!"".equalsIgnoreCase(dto.tolkey) && (dto.b497 || dto.b499) && dto.PriFormID > 0) {//是多表的情况 且是第一个子功能号 SqlRowSet f = null; try { SpObserver.setDBtoInstance("_" + dto.dbid); f = gridService.getGformByFormID(dto.PriFormID); } finally { SpObserver.setDBtoInstance(); } if (!f.wasNull()) { f.first(); dto.rowcopyformids = f.getString("rowcopyformids");//复单时排除功能号 } } else { dto.rowcopyformids = gform.getString("rowcopyformids");//复单时排除功能号 } if (dto.gridHeight == 0) dto.gridHeight = gform.getInt("GridHeight");//表格高度 dto.glcodefield = gform.getString("glcodefield");//会计科目需要的字段 if (!this.isNullOrEmptry(dto.glcodefield)) {//格式:主表汇总,明细表汇总|平衡字段|平衡值公式字段 List> map = null; try { SpObserver.setDBtoInstance("_" + dto.dbid); map = gridService.getSimpleJdbcTemplate().queryForList("select MasterSumFields,DetailSumFields from _sysmasterdetail where FormID=?", dto.formID); } finally { SpObserver.setDBtoInstance(); } if (map.size() > 0) { Map m = map.get(0); dto.gltotal = m.get("MasterSumFields") + "," + m.get("DetailSumFields") + "|" + gform.getString("checkblncfields") + "|" + gform.getString("chkFormula"); m = null; } map = null; } dto.index1 = gform.getString("index1");//列表的排序字段-9类型 dto.index2 = gform.getString("index2");//明细表的排序字段-5类型 dto.formdatafilters = gform.getString("formdatafilters") == null ? "" : this.replaceBlank(gform.getString("formdatafilters")); dto.ProcGroupafterSavedoc = gform.getString("ProcGroupafterSavedoc") == null ? "" : this.replaceBlank(gform.getString("ProcGroupafterSavedoc")); dto.trangroup = gform.getString("transgroupcode") == null ? "" : gform.getString("transgroupcode"); dto.DealAfterDocSave = gform.getString("DealAfterDocSave") == null ? "" : this.replaceBlank(gform.getString("DealAfterDocSave")); dto.cancelProc = gform.getString("CancelBtnProcName") == null ? "" : this.replaceBlank(gform.getString("CancelBtnProcName")); dto.revokeProc = gform.getString("RevokeBtnProcName") == null ? "" : this.replaceBlank(gform.getString("RevokeBtnProcName")); dto.cancelisSave = gform.getBoolean("CancelIsSave") ? 1 : 0; dto.isExchangeDataWithHost = gform.getBoolean("isExchangeDataWithHost") ? 1 : 0; if (dto.winType == 0 || dto.winType == 7 || dto.winType == 1 || dto.winType == 5 || (dto.winType == 9 && dto.conNum == 0) || dto.winType == 3 || dto.winType == 4 || dto.winType == 17 || dto.winType == 302 || dto.winType == 19 || (dto.winType == 499 && dto.conNum == 0) || (dto.winType == 497 && dto.conNum == 0) || (dto.winType == 15 && (dto.conNum == 0 || dto.conNum == 2))) { dto.table = dto.HDTable; dto.isList = true; } else { dto.table = dto.DTtable; } gform = null; return dto.table; } else return null; } private void getFirstField(TreeGridDTO dto) throws DataAccessException, SQLException { //1先读表关键功能,如果没有相关的再读表结构 String keyfields = null; try { SpObserver.setDBtoInstance("_" + dto.dbid); keyfields = gridService.getTableKeyFields(dto.table); } finally { SpObserver.setDBtoInstance(); } if (keyfields == null || "".equals(keyfields)) { //2只取主表,主从表情况 及18,19类型,三表暂时不考虑 List keys = null; try { SpObserver.setDBtoInstance("_" + dto.dbid); keys = gridService.getPrimaryKey(dto.table); } finally { SpObserver.setDBtoInstance(); } for (String str : keys) { if ("".equals(dto.field)) dto.field += str; else dto.field += ";" + str; } keys = null; } else { String[] arry = keyfields.split(";"); for (int i = 0; i < arry.length; i++) { if ("".equals(dto.field)) dto.field += arry[i].toLowerCase(); else dto.field += ";" + arry[i].toLowerCase(); } arry = null; } dto.primeKey = dto.field; } private void print(String root, TreeGridDTO dto) throws DataAccessException, SQLException {//输出表格 String sql = "select top 1 fieldid from gfield where formid=? and HeadFlag=? and ShowOnGrid=1 order by statisid desc"; if (dto.winType != 9 && dto.winType != 15) {//针对只生成一个表格的情况,17类型由于第二个没有表格所以也存在这里了 try { SpObserver.setDBtoInstance("_" + dto.dbid); dto.gfields = gridService.getGfiledByFormID9(dto.formID, this.setGetPrivaryTable(dto.winType));//取得所有字段信息 增加类型 } finally { SpObserver.setDBtoInstance(); } } else { if (dto.winType == 15 && dto.conNum == 1) { List list = null; try { SpObserver.setDBtoInstance("_" + dto.dbid); list = gridService.getThreeTableInfo(dto.formID); } finally { SpObserver.setDBtoInstance(); } if (list.size() == 0) { throw new ApplicationException(";;" + dto.formID + "-三表关联未设置好--9825"); } for (Map map : list) { int temp = (Integer) map.get("DetailFormID"); dto.masterKey = (String) map.get("MasterKeys"); dto.detailKey = (String) map.get("DetailKeys"); dto.formID3 = temp; dto.tempGridHeight = (map.get("gridHeight") == null) ? 0 : (Integer) map.get("gridHeight"); } list = null; } if (dto.conNum < 2) { try { SpObserver.setDBtoInstance("_" + dto.dbid); dto.gfields = gridService.getGfiledByFormID9(dto.formID, dto.conNum);//取得所有字段信息 dto.lastField = gridService.getSimpleJdbcTemplate().queryForObject(sql, new Object[]{dto.formID, 1}, String.class); } catch (DataAccessException e) { dto.lastField = ""; throw new ApplicationException(dto.formID + "-列表没设置需要显示的字段,请在9802重新设置"); } finally { SpObserver.setDBtoInstance(); } } else {//三表中的第三张表 dto.minID = dto.formID;//为了生成页面时取第一表的功能号 dto.formID = dto.formID3; try { SpObserver.setDBtoInstance("_" + dto.dbid); dto.gfields = gridService.getGfiledByFormID9(dto.formID, 0);//取得所有 字段信息 dto.lastField = gridService.getSimpleJdbcTemplate().queryForObject(sql, new Object[]{dto.formID, 0}, String.class); } finally { SpObserver.setDBtoInstance(); } } } //try { this.getTableName(dto.formID, dto.winType + "|" + dto.conNum, dto);// 增加类型 if (dto.table == null) throw new ApplicationException(dto.formID + "--未设置明细表,请在9802设置后重新生成!"); if (dto.isTable) { this.getFirstField(dto); } if (dto.conNum >= 2) if (dto.tempGridHeight != 0) dto.gridHeight = dto.tempGridHeight; gridConfig(root, dto); createCoumtHeader(dto); //} catch (Exception e) { // e.printStackTrace(); //} } private synchronized void fillColumnNumTree(int num, TreeGridDTO dto) {//根据最大行值填充列 StringBuilder mps = new StringBuilder(); int j = 0; //dto.gfields.first(); try { //do{ for (Map map : dto.gfields) { if ("1".equalsIgnoreCase(map.get("ShowOnGrid") + "")) { String dec = map.get("gridcaption") == null ? "" : map.get("gridcaption") + "";//表格描述 String fieldname = map.get("fieldname") == null ? "" : map.get("fieldname") + "";//字段描述 String id = map.get("fieldid") + "";//字段名 if (id.equalsIgnoreCase("id")) id = "_ycid_";//避免id与格线中的id冲突而增加,页面返回时需要转换 String cap = (dec == null || "".equalsIgnoreCase(dec)) ? fieldname : dec;//如果没定义表描述就取字段名称作为表格显示字段 if (cap == null || cap == "" || cap.length() == 0) cap = id; String[] temp = cap.split("\\|");//分割字符串,外表|接收数据|外表字段 int tempN = this.getColumnNumOf(temp[0], dto.tempStr, 0, dto);//取得当前列最大行数是多少. int colNum = this.getColumnNum(temp[0], dto.tempStr, 0, temp[0], 0, dto);//跨列值 int ts = num - temp.length; StringBuilder mp = new StringBuilder(); if (j != 0) mps.append("'"); if (tempN == num && temp.length < num) {//全行都有但长度不够需要在后面补足 for (int i = 0; i < ts; i++) { mp.append("|¥"); } mps.append(cap + mp.toString()); } else { if (colNum > 1) { for (int i = 0; i < ts; i++) { mp.append("|¥"); } mps.append(cap + mp.toString()); } else { for (int i = 0; i < ts; i++) { mp.append("¥|"); } mps.append(mp.toString() + cap); } } j++; mp = null; } } //while(dto.gfields.next()); } catch (Exception e) { //System.out.println(e+"错误3"); } dto.tempStr = mps.toString(); mps = null; } /** * 获取当前表定义的列格式最大数,作为自定义表头列分割的依据 * 循环gfields集合中{表格|描述}字段值,分割”|”生成数组,返回最大数组长度,及取得表所有字段描述和长度分布情况 * * @return int 最大值 */ private synchronized int getMaxColumnNum(TreeGridDTO dto) { int num = 0; int j = 0; //dto.gfields.first(); try { //do{ for (Map map : dto.gfields) { if (GridUtils.prossRowSetDataType_Int(map, "ShowOnGrid") > 0) { String dec = map.get("gridcaption") == null ? "" : map.get("gridcaption") + "";//表格描述 String fieldname = map.get("fieldname") == null ? "" : map.get("fieldname") + "";//字段描述 String id = map.get("fieldid") + "";//字段名 if (id.equalsIgnoreCase("id")) id = "_ycid_";//避免id与格线中的id冲突而增加,页面返回时需要转换 String cap = (dec == null || "".equals(dec)) ? fieldname : dec;//如果没定义表描述就取字段名称作为表格显示字段 if (cap == null || cap == "" || cap.length() == 0) cap = id; String[] temp = cap.split("\\|");//分割字符串,外表|接收数据|外表字段 if (j != 0) dto.tempStr += "'";//特殊分隔符 dto.tempStr += cap; if (!dto.decMap.containsKey(temp[0])) {//不存在这个key时放到map保存 dto.decMap.put(temp[0], temp.length);//保存字段分割最大长度 } else if (temp.length > dto.decMap.get(temp[0])) {//当前值比map里的值大时候,换为新值 dto.decMap.remove(temp[0]); dto.decMap.put(temp[0], temp.length); } if (num < temp.length) { num = temp.length; } j++; } } //while(dto.gfields.next()); } catch (Exception e) { //System.out.println(e+"错误4"); } return num; } /** * 查找类似“表格|显示,表格|描述,表格|类型,表格|长度”中表格出现的次数 * * @param String colName---列名称 * @param String gridcaption---列名称的组合串,在getMaxColumnNum方法生成 */ private synchronized int getColumnNum(String colName, String gridcaption, int index, String per, int m, TreeGridDTO dto) { if (colName.equalsIgnoreCase("¥")) return 0; int num = 0; String temp1 = colName; String temp2 = dto.tempStr; String[] temp3 = temp2.split("'"); String temp4 = "";//保存前一个值 int j = 0; for (int k = 0; k < temp3.length; k++) { j++; String s = temp3[k]; String[] ts = s.split("\\|"); if (ts.length < index + 1) continue; if (ts[index].equalsIgnoreCase(temp1.toLowerCase()) && per.equals(ts[index == 0 ? 0 : index - 1]) && j >= m) {//判断需要计算的列的前一个值与当前列的前一个列是否相同 num++; temp4 = ts[index]; } else if (temp4 != "" && !temp4.equals(ts[index])) {//不匹配时 break; } else { continue; } } temp3 = null; temp1 = null; temp2 = null; return num; } /** * 查找类似“表格|显示,表格|描述,表格|类型,表格|长度”中在表格所属的最大行数 * * @param String colName---列名称 * @param String gridcaption---列名称的组合串,在getMaxColumnNum方法生成 */ private synchronized int getColumnNumOf(String colName, String gridcaption, int index, TreeGridDTO dto) { int num = 0; int temp = 0;//临时值 String temp1 = colName;//列名 String temp2 = dto.tempStr;//列串 String[] temp3 = temp2.split("'");//分割为数组 String temp4 = "";//保存前一个值 int j = 0; for (int k = 0; k < temp3.length; k++) { String s = temp3[k]; String[] ts = s.split("\\|"); if (ts.length < index + 1) continue; if (ts[index].equalsIgnoreCase(temp1) && (temp4 == "" || temp4.equalsIgnoreCase(ts[index]))) { temp = ts.length; temp4 = ts[index]; if (temp > num) num = temp; } else if (temp4 != "" && !temp4.equalsIgnoreCase(ts[index])) {//不匹配时 break; } else { continue; } } temp3 = null; temp1 = null; temp2 = null; return num; } /** * 动态根据表描述字段的如下规律 * 表格|显示|表格|描述|表格|类型|表格|长度 * 外表|表号|外表|类型|外表|清空关联 * 生成跨行跨列的表头格式生成 * 首先是查找最大跨行数,由最大跨行数得到需要输出多少行 * 再一行行的输出每列信息,在每列输出时需要根据表描述字段决定跨行跨列设置 * 全局控制都是根据分割表描述字段所得的数组来处理 * * @return String 表头html代码 **/ private void createCoumtHeader(TreeGridDTO dto) throws DataAccessException { //生成自定义表头 StringBuilder gridHeader = new StringBuilder();//表头html int num = getMaxColumnNum(dto);//返回需要分行,分列的值 this.fillColumnNumTree(num, dto); String temID = "";//保存之前字段描述值,以便当下一次与这个值相等时可以跳过不输出 String temPa = "";//temID的上级值,区分{外表|接收数据|自身字段,外表|条件|自身字段 }情况 String top = ""; String[] str = dto.tempStr.split("'");//填充后的列格式 for (int i = 0; i < num; i++) {//循环分行取值 int k = 0; //dto.gfields.first(); if (dto.gantt && !dto.isList && i == 0) gridHeader.append("
map = dto.gfields.get(y); if (GridUtils.prossRowSetDataType_Boolean(map, "ShowOnGrid")) {//设置为隐藏 String dec = GridUtils.prossRowSetDataType_String(map, "gridcaption");//表格描述 String fieldname = GridUtils.prossRowSetDataType_String(map, "fieldname");//字段描述 String id = map.get("fieldid") + "".trim();//字段名,去掉空格 if (id.equalsIgnoreCase("id") && (!dto.gantt)) id = "_ycid_";//避免id与格线中的id冲突而增加,页面返回时需要转换 String temp = (dec == null || "".equalsIgnoreCase(dec)) ? fieldname : dec;//如果没定义表描述就取字段名称作为表格显示字段 if (temp == null || temp == "" || temp.length() == 0) temp = id; String[] capf = temp.split("\\|");//分割字符串,外表|接收数据|外表字段 去掉 .replaceAll("'", "\\\\'"),因为用""括进来了,为的就是动态标题传参数有单引号的情况 String[] cap = str[k].split("\\|"); if (cap[i].trim().indexOf("!") == 0) {//动态标题,替换参数 if (k > 0 && dto.setInfo_dy.length() > 1 && cap[i].indexOf("@") > -1) dto.setInfo_dy += ","; this.prossIntoSessionForFilter_dy(cap[i], dto); } k++; boolean flag = false;//标记是否需要隐藏 String show = ""; String hidden = ""; int colNum = 0; if (i > 0 && cap.length > 1 && i < cap.length) { if (!cap[i].equalsIgnoreCase("¥") && temID.equalsIgnoreCase(cap[i]) && temPa.equalsIgnoreCase(cap[i - 1]) && top.equalsIgnoreCase(cap[0])) { continue;//只输出一个,表格|显示,表格|描述,表格|类型,表格|长度 } } try { colNum = this.getColumnNum(cap[i], dto.tempStr, i, i == 0 ? cap[0] : cap[i - 1], k, dto);//取得跨列值 if (colNum == 0) flag = true;//表示存在¥,则不需要显示 show = id.toLowerCase() + "=\"" + this.getFormCap(cap[i]) + "\" " + id.toLowerCase() + "Align='Center' " + (colNum > 1 ? (" " + id.toLowerCase() + "Span='" + colNum + "' ") : ""); hidden = id.toLowerCase() + "Visible='-1' "; if (flag) gridHeader.append(hidden); else gridHeader.append(show); } catch (Exception e) { throw new ApplicationException(dto.formID + "-字段设置有问题-" + id); } flag = false; top = capf[0];//取得第一个字段值 if (i < capf.length) temID = capf[i]; if (i > 0 && i < capf.length) temPa = capf[i - 1];//得到上级值 } } //while(dto.gfields.next()); if (!dto.isList && dto.gantt) gridHeader.append(" G='Gantt'"); gridHeader.append(" />\n"); } try { if (gridHeader.length() > 0) dto.header = gridHeader.substring(0, gridHeader.length() - 1); } catch (Exception e) { throw new ApplicationException("生成格线表头出错,因为格线所有栏位都设为不显示"); } finally { gridHeader = null; dto.gfields = null; } } ; /** * 根据当前值是否有特定标记@day,@moth,@year,等。以替换成真实值 */ private synchronized String getFormCap(String id) { String s = id.toLowerCase().trim(); String[] day = null; if (s.indexOf("@day") > -1) {//日 if (s.indexOf("+") > -1) { day = s.split("\\+"); } else if (s.indexOf("-") > -1) {//-号 day = s.split("\\-"); day[1] = "-" + day[1]; } else { day = s.split("\\+"); } if (day.length > 1) { return "#GT.getDay(" + Integer.parseInt(day[1]) + ")"; } else { return "#GT.getDay(0)"; } } else if (id.toLowerCase().indexOf("@month") > -1) {//月 if (s.indexOf("+") > -1) { day = s.split("\\+"); } else if (s.indexOf("-") > -1) {//-号 day = s.split("\\-"); day[1] = "-" + day[1]; } else { day = s.split("\\+"); } if (day.length > 1) { return "#GT.getMonth(" + Integer.parseInt(day[1]) + ")"; } else { return "#GT.getMonth(0)"; } } else if (id.toLowerCase().indexOf("@quarter") > -1) {//季 return id; } else if (id.toLowerCase().indexOf("@year") > -1) {//年 if (s.indexOf("+") > -1) { day = s.split("\\+"); } else if (s.indexOf("-") > -1) {//-号 day = s.split("\\-"); day[1] = "-" + day[1]; } else { day = s.split("\\+"); } if (day.length > 1) { return "#GT.getYear(" + Integer.parseInt(day[1]) + ")"; } else { return "#GT.getYear(0)"; } } else { return id.replaceAll("<", "<").replaceAll(">", ">"); } } /** * 取得自动编号的类型 */ private synchronized List getAutoCodeType(int formid, String dbid) { try { SpObserver.setDBtoInstance("_" + dbid); String sql = "select precodetype,codelength,preFixcode from gform where formid=?"; return gridService.getJdbcTemplate().queryForList(sql, new Object[]{formid}); } finally { SpObserver.setDBtoInstance(); } } private List getCodeInfo(int formid, String dbid) { try { SpObserver.setDBtoInstance("_" + dbid); String sql = "select g.formid,g.codelength,g.preFixcode,g.precodetype,c.Formtype,c.Curcode,c.Fieldid from gform g,_sysautocode c where g.formid=c.formid and g.formid=?"; return gridService.getJdbcTemplate().queryForList(sql, new Object[]{formid}); } finally { SpObserver.setDBtoInstance(); } } /** * 查找字符串中是否存在指定的内容 * 返回需要替换的字段名 */ private synchronized String getString(String str) { Pattern p = Pattern.compile("@\\w+"); String s = ""; java.util.regex.Matcher propsMatcher = p.matcher(str != null ? str.toLowerCase() : ""); while (propsMatcher.find()) { s += propsMatcher.group() + ";"; } return s; } /** * 填充参数值列表,下拉列表控件时,需要填充数据,用作2类型控件 * * @param type 控件类型 * @param ft --参数号 * @return */ private StringBuilder fillFT(int type, int ft, String sql, TreeGridDTO dto) { StringBuilder sb = new StringBuilder(); SqlRowSet rst = null; try { SpObserver.setDBtoInstance("_" + dto.dbid); rst = gridService.getFTData(ft); } finally { SpObserver.setDBtoInstance(); } sb.append(""); boolean flag = false; if (type == 31 || type == 2 || type == 35 || type == 43 || type == 30 || type == 32) {//2,类型,31类型下拉列表控件时,为三种情况,一个是静态sql,一个是动态sql,需要用页面的值替换再用ajax提交返回,另一个就是表号生成 StringBuilder id = new StringBuilder(); StringBuilder value = new StringBuilder(); if (type != 30 && type != 32) { id.append("| "); value.append("| "); } try { if (sql != null && sql != "" && sql.length() > 0) {//有sql参数 if (sql.indexOf("&") > -1 || sql.indexOf("@") > -1) {//表示需要在页面替换参数,取页面值,ajax提交填充 this.prossIntoSession(getString(sql), dto); sb.append("dySql=\"" + sql + "\""); } else { if (type == 2) { SqlRowSet set = null; try { SpObserver.setDBtoInstance("_" + dto.dbid); set = gridService.getJdbcTemplate().queryForRowSet(sql); } finally { SpObserver.setDBtoInstance(); } if (!set.wasNull()) { while (set.next()) { id.append("|").append(this.replaceBlank(set.getString(1))); value.append("|").append(this.replaceBlank(set.getString(2))); } set = null; } } else {//31,35 sb.append("dySql=\"" + sql + "\""); } } flag = true; } if (!flag) { if (!rst.wasNull()) { while (rst.next()) { id.append("|").append(this.replaceBlank(rst.getString("interValue"))); value.append("|").append(this.replaceBlank(rst.getString("dictvalue"))); } } } } catch (Exception e) { sb.append(""); } finally { rst = null; } if (type == 31) if (ft != 0)//有表号才会有新增选项 sb.append(" EnumKeys='").append(id.toString() + "|-add-").append("' Enum='").append(value.toString() + "|<<新增>>").append("' "); else//当没表号表示不需要新增选项 sb.append(" EnumKeys='").append(id.toString()).append("' Enum='").append(value.toString()).append("' "); else { if (type != 35) { sb.append(" EnumKeys='").append(id.toString()).append("' Enum='").append(value.toString()).append("' "); } } if (type == 35) {//可编辑列表,值与键需要一样 sb.append(" Button='Defaults' Defaults='").append(("|".equals(value.toString().trim())?"":value.toString())).append("' "); } if (type == 43 || type == 30) { sb.append(" Range='1' "); } id = null; value = null; } // else if(type==35){//可编辑列表,值与键相同 // StringBuilder value=new StringBuilder(); // try{ // if(!rst.wasNull()){ // while(rst.next()){ // value.append("|").append(this.replaceBlank(rst.getString("dictvalue"))); // } // } // }catch(Exception e){ // sb.append(""); // }finally{ // rst=null; // } // sb.append(" Button='Defaults' Defaults='").append(value.toString()).append("' "); // value=null; // } return sb; } private synchronized String setJsName(TreeGridDTO dto) { return "grid_" + dto.formID + "_" + dto.winType + ".xml"; } /** * 生成页面时需要检查的关键字段名,避免生成格线有问题 */ private synchronized boolean checkKey(String id) { String[] keys = {"_ycid_", "added", "Deleted", "Changed", "Moved", "Panel", "Prev", "Next", "id"}; for (String k : keys) { if (k.equalsIgnoreCase(id)) { return true; } } return false; } private String getFileter(TreeGridDTO dto) { StringBuffer temp = new StringBuffer(); temp.append(""); try { // dto.gfields.first(); // do{ for (int y = 0; y < dto.gfields.size(); y++) { Map map = dto.gfields.get(y); String top = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "SeekGroupID") + "".toLowerCase()); String sf = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "HyperlinkSPremissField") + "".toLowerCase()); String ft = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "HyperlinkFT") + "".toLowerCase()); String initValue = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "initValue") + ""); if (top.length() > 0) temp.append(top).append(";"); if (sf.length() > 0) temp.append(sf).append(";"); if (ft.length() > 0) temp.append(ft).append(";"); if (initValue.length() > 0) temp.append(initValue).append(";"); } //while(dto.gfields.next()); } catch (ArrayIndexOutOfBoundsException e) { throw new ApplicationException("读取不到" + dto.formID + "在9802里面的字段信息,请检查9802是否已做了相关设置"); } return temp.toString(); } /** * sugg--列表显示的字段 * backFilds-取外表字段,以便选择后返回哪些值。 * tp ---自表字段,返回给哪些字段 */ public String getSuggestFilds(String fromid, int type, String sugg, String backFilds, String to, String form, boolean one, int rod, String dbid, String sf, String df) {//取得需要的字段名称 int flg = this.setGetPrivaryTable(type); StringBuffer sb = new StringBuffer(); StringBuffer exps = new StringBuffer(); String sql = " select FieldID,fieldname,GridCaption,ShowOnGrid,showFieldValueExpression from gfield where formid=? and HeadFlag=? order by statisid asc"; List> list = null; try { SpObserver.setDBtoInstance("_" + dbid); list = gridService.getSimpleJdbcTemplate().queryForList(sql, new Object[]{fromid, flg}); } finally { SpObserver.setDBtoInstance(); } String[] tem = sugg.replaceAll(",", ";").split(";"); int i = 0; String str = "";//保存哪些字段是隐藏的 for (String s : tem) { for (Map map : list) { if (s.equalsIgnoreCase((String) map.get("FieldID"))) { if ((Integer) (map.get("ShowOnGrid") == null ? 0 : map.get("ShowOnGrid")) == 1) sb.append("").append(map.get("fieldname") == null ? (String) map.get("GridCaption") : (String) map.get("fieldname")).append(""); else { if (str == "") str += map.get("FieldID"); else str += ";" + map.get("FieldID"); sb.append("").append(map.get("fieldname") == null ? (String) map.get("GridCaption") : (String) map.get("fieldname")).append(""); } //取权限表达式输出到页面 String strexp = GridUtils.prossRowSetDataType_String(map, "showFieldValueExpression"); if (!"".equalsIgnoreCase(strexp)) { if (exps.length() == 0) exps.append(s + "|").append(strexp).append(";"); else exps.append(";").append(s + "|").append(strexp); } break; } } i++; } String strexps = ""; try { strexps = new String(YCBase64.encode(exps.toString().getBytes())); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } String json = "{\"data\":\";" + str + ";\",\"backfilds\":\"" + backFilds + "\",\"sf\":\"" + sf + "\",\"df\":\"" + df + "\",\"to\":\"" + to + "\",\"form\":\"" + form + "\",\"exp\":\"" + strexps + "\",\"one\":\"" + (one ? 1 : 0) + "\"}"; return "\t\n"; } /** * 处理9802里面设置了取值的字段但又不需要显示的所有字段 * 针对超链接的参数进行处理 */ private Map prossDisable(TreeGridDTO dto) { Map map = new HashMap(); //dto.gfields.first(); //do{ for (int y = 0; y < dto.gfields.size(); y++) { Map map1 = dto.gfields.get(y); String ft = GridUtils.prossRowSetDataType_String(map1, "HyperlinkFT"); String type = GridUtils.prossRowSetDataType_String(map1, "HyperlinkFTFormType"); String field = GridUtils.prossRowSetDataType_String(map1, "HyperlinkSPremissField"); String filter = GridUtils.prossRowSetDataType_String(map1, "HyperlinkEFilter"); pullValue(map, ft); pullValue(map, type); pullValue(map, field); pullValue(map, filter); } //while(dto.gfields.next()); return map; } private void pullValue(Map m, String ft) { if (ft != null && !"".equalsIgnoreCase(ft)) { ft = ft.replaceAll(",", ";"); String[] str = ft.split(";"); for (String s : str) { m.put(s, "1"); } } } /** * grid定义数据集及列定义 */ private void gridConfig(String root, TreeGridDTO dto) throws DataAccessException { StringBuilder left = new StringBuilder();//leftcols定义 StringBuilder cols = new StringBuilder();//列定义json StringBuilder formn = new StringBuilder();//自定义公式 StringBuilder values = new StringBuilder();//初始值 StringBuilder sumfu = new StringBuilder();//统计公式 StringBuilder valExp = new StringBuilder();//权限控制值 StringBuilder cssExp = new StringBuilder();//css控制值 StringBuilder tipsExp = new StringBuilder();//提示信息 StringBuilder msgInfo = new StringBuilder();//错误提示信息 StringBuilder exportInfo = new StringBuilder();//保存导出字段 StringBuilder rowCopys = new StringBuilder();//保存复单时排除字段,读9802 //StringBuilder exportTitle=new StringBuilder();//保存导出文件名称,在生成下载的excel文件时候用到 //List sugId=new ArrayList();//保存生成div的功能号,以便排队生成相同的div dto.filter = new StringBuilder();//过滤设置,读9802 dto.filter.append(" len = new HashMap(); if (!dto.isList) {//只有是有明细表才需要有长度限制 String lengthInfo = null; try { SpObserver.setDBtoInstance("_" + dto.dbid); lengthInfo = gridService.getTypeLengthInfo(dto.table.split("\\|")[0]); } finally { SpObserver.setDBtoInstance(); } if (lengthInfo != null) { String[] tem = lengthInfo.split(","); for (String s : tem) { String[] ss = s.split("-"); if (ss.length < 3) len.put(ss[0].toLowerCase(), ss[1]); else len.put(ss[0].toLowerCase(), ss[2]); } } } //String fileter=this.getFileter();//保存需要隐藏输出的字段,只取自身字段 boolean iscopy = false;//标记当前9802是否有复制时排除字段,为了兼用不存在出错的情况 boolean isref = false;//标记当前9802是否有自动刷新和加载到页面的字段,为了兼用不存在出错的情况 int fumIndex = 0;//标记导出时候字段位置 Map vMap = this.prossDisable(dto); //dto.gfields.first(); // do{ for (int i = 0; i < dto.gfields.size(); i++) { boolean fileterID = false;//标记为需要隐藏输出 Map map = dto.gfields.get(i); // //----处理动态sql // Map map9801= SqlFormatUtils.createSQLFormat(map,9801); // Map map9802= SqlFormatUtils.createSQLFormat(map,9802); // //----- String id = GridUtils.prossRowSetDataType_String(map, "fieldid");//字段名 String dec = GridUtils.prossRowSetDataType_String(map, "gridcaption");//表格描述 String fieldname = GridUtils.prossRowSetDataType_String(map, "fieldname");//字段描述 String temp = (dec == null || "".equalsIgnoreCase(dec)) ? fieldname : dec;//如果没定义表描述就取字段名称作为表格显示字段 if (this.checkKey(id.toLowerCase())) { msgInfo.append("警告:格线所用字段不能使用[" + id + "]关键字!"); } if (id.equalsIgnoreCase("id") && (!dto.gantt)) id = "_ycid_";//避免id与格线中的id冲突而增加,页面返回时需要转换 if (temp == null || "".equalsIgnoreCase(temp) || temp.length() == 0) temp = id; if (firstID == "") firstID = id; int type = GridUtils.prossRowSetDataType_Int(map, "gridcontroltype");//表格单元格控件类型 int ft = GridUtils.prossRowSetDataType_Int(map, "ft");//外表|表号 int wiType = GridUtils.prossRowSetDataType_Int(map, "FTFormType");//外表|窗体类型 int width = GridUtils.prossRowSetDataType_Int(map, "GridLength");//单元格宽度 if (width == 0) { width = 100; } else { width *= 10; } if (width < 100 && width > 50) width = 100; if (width < 50) width = 50; int calcuField = GridUtils.prossRowSetDataType_Int(map, "calcuField");//自定义公式|1,表示是否当前字段变化后需要重新计算包括有这个字段的所有公式内容 String fua = GridUtils.prossRowSetDataType_String(map, "formula");//自定义公式 if (fua != null && !"".equalsIgnoreCase(fua)) { this.prossIntoSessionForFilter(fua, dto); } String value = GridUtils.prossRowSetDataType_String(map, "initValue");//初始值 String emptyrefdata = GridUtils.prossRowSetDataType_String(map, "emptyrefdata");//清空关联 int SumField = GridUtils.prossRowSetDataType_Int(map, "SumField");//统计方式 String funclinkname = GridUtils.prossRowSetDataType_String(map, "funclinkname");//自定义统计公式 boolean activefuns = GridUtils.prossRowSetDataType_Boolean(map, "activefuns");//公式是否生效 boolean ShowOnGrid = GridUtils.prossRowSetDataType_Boolean(map, "ShowOnGrid");//是否显示 boolean KeyInput = GridUtils.prossRowSetDataType_Boolean(map, "KeyInput");//是否必录 String passwordchar = GridUtils.prossRowSetDataType_String(map, "passwordchar");//是否为密码字符 String displayformat = GridUtils.prossRowSetDataType_String(map, "displayformat");//数字格式 String ef = GridUtils.prossRowSetDataType_String(map, "eFilter"); boolean readOnly = GridUtils.prossRowSetDataType_Boolean(map, "ReadOnly");//只读 boolean dataLink = GridUtils.prossRowSetDataType_Boolean(map, "DataLink");//感应字段 boolean uppercase = GridUtils.prossRowSetDataType_Boolean(map, "uppercase");//大写 String ValueExp = GridUtils.prossRowSetDataType_String(map, "showFieldValueExpression");//权限控制是否显示该值 String editStatus = GridUtils.prossRowSetDataType_String(map, "editStatus");//权限控制是否显示该值 boolean oneRec = GridUtils.prossRowSetDataType_Boolean(map, "return_one_record");//是否返回到单记录 boolean onlyOne = GridUtils.prossRowSetDataType_Boolean(map, "onlyOne");//只返回单条记录 String sqlScript = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "SqlScript"));// 控件sql String sqlWhere = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "sqlWhere"));// 下拉控件(31),编辑状态时需要附加这个条件 this.prossIntoSessionForFilter_dy(sqlWhere, dto); boolean rowspan = GridUtils.prossRowSetDataType_Boolean(map, "rowSpan");//是否合并行 boolean isExport = GridUtils.prossRowSetDataType_Boolean(map, "isExport");//是否导出 boolean statisFlag = GridUtils.prossRowSetDataType_Boolean(map, "StatisFlag");//是否可查询 boolean cpltrow = GridUtils.prossRowSetDataType_Boolean(map, "copyfromlastrow");//插入时从上行复制 String cs = GridUtils.prossRowSetDataType_String(map, "stylecss");//css样式 String tips = GridUtils.prossRowSetDataType_String(map, "TipsExpression"); valExp.append((ValueExp != null && !"".equalsIgnoreCase(ValueExp)) ? id + "|" + this.replaceBlank(ValueExp) + ";" : ""); cssExp.append((cs != null && !"".equalsIgnoreCase(cs)) ? id + "|" + this.replaceBlank(cs.replaceAll(";", "~")) + ";" : ""); tipsExp.append((tips != null && !"".equalsIgnoreCase(tips)) ? id + "|" + this.replaceBlank(tips.replaceAll(";", "~")) + ";" : ""); String cellAlign = GridUtils.prossRowSetDataType_String(map, "cellAlign");//单元格对齐属性 //int expTitle=GridUtils.prossRowSetDataType_Int(map,"exportTitle");//下载文件名称 String dataType = ""; int dIndex = 1; if (metaData != null) { dIndex = this.getType(metaData, id);//取得每个字段的数据类型,1数字 ,3字符,4日期 switch (dIndex) { case 1: dataType = "n";//数值 break; case 3: dataType = "s";//字符串 break; case 4: dataType = "d";//时间 break; } } int isAudit = 0; //if(ShowOnGrid&&statisFlag)//可显示且可查询 setFilter(id.toLowerCase(), type, dto.filter, dIndex); try { if (!iscopy) { boolean isCopyExclude = GridUtils.prossRowSetDataType_Boolean(map, "isCopyExclude");//复单时是否排除 if (isCopyExclude) rowCopys.append(id.toLowerCase()).append(";"); } //是否审计,1: //表示当前字段分二种情况来处理, //第一个情况是值没变化的 情况 下只作为后期审计查询的唯一条件,附加进有变化的审计字段的行,插入数据表 //第二个情况是值有变化的情况下,除了作为后期审计查询的唯一条件,附加进有变化的审计字段的行,也需要记录本身的新旧值变化的情况 //第三种情况是删行的情况下,也需要记录本身的新旧值变化的情况 //2: //只作为有变化的情况的审计字段,记录新旧值插入数据表 isAudit = GridUtils.prossRowSetDataType_Int(map, "audit"); } catch (Exception e) { iscopy = true; isAudit = 0; } boolean isLoad = false; try { if (!isref) { if (dto.order == 1//表示是列表的情况(很少存在需要取隐藏字段值的情况) by 2015-4-7 去掉这个限制 && (type == 33 || type == 34 || type == 36 || type == 38 || type == 41)) isLoad = false; else isLoad = GridUtils.prossRowSetDataType_Boolean(map, "isLoad");//是否加载到页面 } //在超接连中有参数,需要再判断是否需要加载到页面 if (vMap.containsKey(id.toLowerCase())) { isLoad = true; } } catch (Exception e) { isref = true; } if (cellAlign == null || cellAlign.length() == 0) cellAlign = "Center"; if (!this.checkFormat(displayformat)) msgInfo.append(id + "-的格式设置不正确,存在连续二个分隔符,[" + displayformat + "]"); if (displayformat != null && displayformat.contains("#")) msgInfo.append(id + "-的格式设置不正确,不能以#号分隔,[" + displayformat + "]"); //上面的都是读取9802的设置信息,接下来的才是逻辑处理 if (isExport) { //if(expTitle==1) exportTitle.append(id.toLowerCase()).append(";");//拼接所有需要组成的id if (displayformat != null && !displayformat.isEmpty()) exportInfo.append(id.toLowerCase()).append("#").append(temp.replaceAll("-", "_")).append("#").append(displayformat.replaceAll("-", "~")).append(";");//-转成~是为了兼容之前的代码 else exportInfo.append(id.toLowerCase()).append("#").append(temp.replaceAll("-", "_")).append(";"); if (SumField > 0) SumFieldInfo.append(id.toLowerCase()).append("#").append(SumField).append("|").append(funclinkname).append("|").append(fumIndex).append("|").append((displayformat != null && !displayformat.isEmpty()) ? displayformat.replaceAll("-", "~") : "0").append(";"); fumIndex++; } boolean listShow = ((dto.order == 1//表示是列表的情况(很少存在需要取隐藏字段值的情况) by 2015-4-7 去掉这个限制 // &&(type==33||type==34||type==36||type==38||type==41) && (dto.winType == 9 || dto.winType == 15 || dto.winType == 17 || dto.winType == 499 || dto.winType == 497) )) ? true : false; //增加作为主键时,但没勾选上加载到页面时,也需要生成出来。 boolean isprimeKey = false; if ((";" + dto.primeKey.toLowerCase()).contains(";" + id.toLowerCase() + ";")) isprimeKey = true;//判断是主键,不管有没选上加载到页面都需要生成到页面 if (!isprimeKey && (!isLoad || listShow)) {//不加载到页面或是列表的情况 if ((!isref && !isLoad && !id.equalsIgnoreCase("doccode")//这二个字段特殊,需要区别对待,需要取出来 && !id.equalsIgnoreCase("docdate")) //|| //(!ShowOnGrid&&listShow)//表示不选显示,但又是列情的情况则不需要理会是否加载到页面的选项,也就是在列表的情况下,不选显示的优先级高 || (dto.winType != 18 && !dataLink && !ShowOnGrid) ) continue;//条件为在9802中设置不显示且是在明细表的情况下才输出显示 } //检查当前是否有会计科目设置 if (!this.isNullOrEmptry(dto.glcodefield)) { if (id.toLowerCase().matches("cv\\d{1}") || id.toLowerCase().matches("cv\\d{1}name")) { type = -3;//会计核算之用 } } if (dto.order == 1 && "".equalsIgnoreCase(dto.orderFiled)) {//排序字段 if (id.equalsIgnoreCase("doccode")) { dto.orderFiled = id + " desc"; } if (id.equalsIgnoreCase("docdate")) { dto.orderFiled = dto.orderFiled.length() == 0 ? id + " desc" : "," + id + " desc"; } } else if (dto.order == 2 && "".equalsIgnoreCase(dto.orderFiled)) { if (id.equalsIgnoreCase("docitem")) dto.orderFiled = id + " asc"; } if (!dataLink) {//不感应但可能数据库存在有字段 if (gridService.getColumnInfo(dto.table, id.toLowerCase()) == 1) {//存在,表示要在页面显示出来,但在新增,修改时需要过滤 dataLink = true; dto.columns = id.toLowerCase() + ","; } } if (fua != null && !fua.equalsIgnoreCase("") && activefuns&&calcuField!=0) { formn.append(id.toLowerCase()).append("@p@").append(fua).append(":"); } if (value != null && !value.equalsIgnoreCase("")) {//自动编号功能 if (value.equalsIgnoreCase("autocode")) { List ct = this.getAutoCodeType(dto.formID, dto.dbid); if (ct.size() == 0) msgInfo.append(id + "字段设置autocode,但没在9801进行相关设置!"); Map ma = ct.get(0); if (ma.get("precodetype") == null || ma.get("codelength") == null || ma.get("preFixcode") == null) msgInfo.append(id + "-字段设置autocode,但没在9801对【precodetype,preFixcode,codelength】进行相关设置!"); if ((Integer) ma.get("precodetype") == 1) { List> li = this.getCodeInfo(dto.formID, dto.dbid); if (li.size() == 0) msgInfo.append(id + "字段设置autocode,但没在[_sysautocode]表进行相关设置!"); Map map1 = li.get(0); value = "autocode|1|" + (Integer) map1.get("formid") + "," + (Integer) map1.get("Formtype") + "," + (String) map1.get("Fieldid") + "," + (Integer) map1.get("codelength") + "," + (String) map1.get("preFixcode"); map1 = null; } else if ((Integer) ma.get("precodetype") == 2) { try { SpObserver.setDBtoInstance("_" + dto.dbid); String table = gridService.getTreeTable(dto.formID);//TODO 暂时只取第一个,以后需要修正能处理多树的情况 String[] strings = table.split(";");//TODO 以后去掉 value = "autocode|2|~," + (Integer) ma.get("codelength") + ",#," + (String) ma.get("preFixcode") + "," + strings[0]; } finally { SpObserver.setDBtoInstance(); } } values.append(id.toLowerCase()).append("#").append(value).append("&p&"); ma = null; } else if (!value.equalsIgnoreCase("@now") && (value.indexOf("@") > -1 || value.indexOf("!") > -1)) {//替换成当前session的值 //@now 表示需要取当前时间,所以通过js调用 String temp1 = DBHelper.getValRep(value, false); values.append(id.toLowerCase()).append("#").append(temp1).append("&p&"); } else values.append(id.toLowerCase()).append("#").append(value).append("&p&"); } if (SumField != 0) sumfu.append(id.toLowerCase()).append("#").append(SumField).append(":").append(funclinkname.replaceAll(",", "@p@")).append(",");//自定义公式有可能存在有,号需要处理 if ((passwordchar != null && !"".equalsIgnoreCase(passwordchar) && "1".equalsIgnoreCase(passwordchar))) type = 101; //控件类型 String typeName = Control.getTypeName(type == 0 ? 1 : type, typeInfo, id, displayformat, dto.winType); StringBuilder sb = new StringBuilder(); if (type == 9 || type == 40) { if (dto.picFild != null && dto.picFild != "") { if (!dto.picFild.contains(id + ";")) dto.picFild += id.toLowerCase() + ";";//保存是哪一个字段是图片字段 } else { dto.picFild += id.toLowerCase() + ";";//保存是哪一个字段是图片字段 } sb.append(" CanFocus='0' ");//图片不需要取得焦点,避免在进入编辑状态时上传图片,返回不显示的问题 sb.append(" showType='" + (type == 9 ? 0 : 2) + "' ");//以后增加格线支持多附件显示需要用到,区别出到时应该取哪一个附件表(_sys_Attachment9,_sys_Attachment)的数据 } if (type == 2 || type == 35 || type == 31 || type == 43 || type == 30 || type == 32) { sb = fillFT(type, ft, sqlScript, dto);//2类型 sb.append(" CanEmpty='0' "); dto.foot2 += id.toLowerCase() + ";";//解决针对2,35类型有值时候统计列会显示出来的问题 dto.footb.append(id.toLowerCase()).append("Type='Text' ").append(id.toLowerCase()).append("Button='' ");//汇总页需要屏蔽单元格类型为Text } if (isAudit != 0) sb.append(" audit='").append(isAudit).append("'");//增加审计标记 if (rowspan) {//合并行 sb.append(" Spanned='1' ");//表示需要合并 dto.rowspanStr += id + ";";//保存需要合并的字段,加载时需要用到 } if (type == 3 || type == 31 || type == -3 || type == 42) { //3类型 String suggest = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "SuggestFileds").replaceAll("\\bid\\b", "_ycid_").toLowerCase()); String RelationField = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "RelationField").replaceAll("\\bid\\b", "_ycid_").toLowerCase()); if ("".equalsIgnoreCase(suggest) && type == 42) msgInfo.append(temp + "字段为42类型控件,但列表字段[SuggestFileds]未设置"); //String path="/"+dto.verNo+ft+"/"+wiType+"/"; String path = "app#spellPath#" + ft + "/" + wiType + "/index.jsp";//#spellPath#在页面js替换, 解决定制页面生成时,数据源用了当前而造成移植到其他系统不对的问题 String top = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "SeekGroupID").replaceAll("\\bid\\b", "_ycid_").toLowerCase()); String form = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "FK").replaceAll("\\bid\\b", "_ycid_").toLowerCase()); String sf = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "sPremissField").replaceAll("\\bid\\b", "_ycid_").toLowerCase()); String df = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "dPremissField").replaceAll("\\bid\\b", "_ycid_").toLowerCase()); if(StringUtils.isNotBlank(top)&&StringUtils.isBlank(form)){ throw new ApplicationException("【9802】里【"+id+"】设置了【外表|接收自身字段名】,则【外表|接收外表字段名】不能为空"); } if(StringUtils.isNotBlank(sf)&&StringUtils.isBlank(df)){ throw new ApplicationException("【9802】里【"+id+"】设置了【外表|自身条件字段名】,则【外表|外表条件字段名】不能为空"); } sb.append(" formid='").append(ft) .append("' toParm=\"").append(top) .append("\" formParm=\"").append(form) .append("\" sField=\"").append(sf) .append("\" dField=\"").append(df) .append("\" id='").append(id.toLowerCase()) .append("' wtype='").append(wiType) .append("' oneRec='").append(oneRec ? 1 : 0) .append("' onlyOne='").append(onlyOne ? 1 : 0) .append("' sqlWhere=\"").append(sqlWhere)// by danaus 2019/12/20 15:28 .append("\" path='").append(path) .append(uppercase ? "' uppercase='" + uppercase : "") .append("' eFilter=\"").append(ef == null ? "" : (ef.replaceAll("'", "\\\\'").replaceAll("\n\t", ""))).append("\""); String sug = ""; if (!"".equalsIgnoreCase(suggest)) {//加上自动补全功能 if (!"".equalsIgnoreCase(RelationField)) {//关联查询字段 sb.append(" refield='").append(RelationField + "'"); } //去掉重复字段 String[] temp1 = suggest.toLowerCase().split(";"); for (String s : temp1) { if (sug.indexOf(s + ";") < 0) { sug += s + ";"; } } sug = sug.substring(0, sug.length() - 1); sb.append(" suggest='" + sug + "'"); //生成显示的数据名称 //if(!sugId.contains(ft)){ // sugId.add(ft); rod++;//生成100之内的随机数 sb.append(" rand='10" + rod + "'"); dto.sugList.append(this.getSuggestFilds(ft + "", wiType, sug, sug, top, form, oneRec, rod, dto.dbid, sf, df)); // } } if (type == -3)//表示为辅助核算 sb.append(" curType='gl' "); if (type == 3 || type == -3) sb.append(" Button='/images/ppp.gif' WidthPad='20'"); this.prossIntoSession(top, dto); this.prossIntoSession(form, dto); this.prossIntoSession(sf, dto); this.prossIntoSession(df, dto); this.prossIntoSessionForFilter(ef, dto); dto.footb.append(id.toLowerCase()).append("Type='Text' ").append(id.toLowerCase()).append("Button='' ");//汇总页需要屏蔽单元格类型为Text } else if (type == 6) { sb.append(" CanEmpty='0' ");//解决在只读时候,没值会显示不正确的情况 dto.footb.append(id.toLowerCase()).append("Type='Text' ");//汇总页需要屏蔽单元格类型为Text } else if (type == 1 || type == 0 || type == 7) { sb.append(uppercase ? " uppercase='" + uppercase + "'" : ""); } else if (type == 9) {//图片控件 sb.append(" Button='/images/d.jpg' WidthPad='20' "); dto.footb.append(id.toLowerCase()).append("Type='Text' ").append(id.toLowerCase()).append("Button='' ");//汇总页需要屏蔽单元格类型为Text } if (type != 2 && type != 31) {//下拉类型的不需要显示 if (len.get(id.toLowerCase()) != null && Integer.parseInt(len.get(id.toLowerCase())) > 0) { //存在varchar(max),nvarchar(max)的情况 String rep = "^\\\\\\s*[\\\\\\s\\\\\\S]{0," + len.get(id.toLowerCase()) + "}\\\\\\s*\\$"; sb.append(" EditMask='").append(rep).append("' ") .append(" Tsize='").append(len.get(id.toLowerCase())).append("' ") .append(" Tip='").append("最长").append(len.get(id.toLowerCase())) .append("个字符(每汉字占2个字符)'"); } } sb.append(calcuField != 0 ? " calcuField='" + calcuField + "'" : ""); sb.append(KeyInput ? " KeyIn='1'" : "").append(" dataType='").append(dataType).append("' "); if (emptyrefdata != null && !emptyrefdata.equalsIgnoreCase("") && !emptyrefdata.equalsIgnoreCase("0") && type != 6) sb.append(" emptyrefdata='").append(this.replaceBlank(emptyrefdata)).append("'");//增加清空关联 if (!this.isNullOrEmptry(GridUtils.prossRowSetDataType_String(map, "HyperlinkFT")) && !this.isNullOrEmptry(GridUtils.prossRowSetDataType_String(map, "HyperlinkFTFormType"))) { //判断22类型的主表是不是自定义.do。 String execdo = ""; if ("22".equals(GridUtils.prossRowSetDataType_String(map, "HyperlinkFTFormType")) && org.apache.commons.lang.StringUtils.isNumeric(GridUtils.prossRowSetDataType_String(map, "HyperlinkFT"))) { T_22_Ifc t22ifc = (T_22_Ifc) FactoryBean.getBean("T_22_Impl"); execdo = t22ifc.getProcName(GridUtils.prossRowSetDataType_String(map, "HyperlinkFT")); if (execdo != null && !"".equals(execdo)) { execdo = (execdo.indexOf(".do") != -1 ? execdo : ""); } } String efl = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "HyperlinkEFilter").toLowerCase()); String op = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "Hyperlinkmode").toLowerCase()); int save = GridUtils.prossRowSetDataType_Int(map, "isAutoSaved"); // String openType=this.prossRowSetDataType_String(map,"openType")==null?"0":this.replaceBlank(this.prossRowSetDataType_String(map,"openType").toLowerCase()); String sf = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "HyperlinkSPremissField").replaceAll("\\bid\\b", "_ycid_").toLowerCase()); String df = this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "HyperlinkDPremissField").replaceAll("\\bid\\b", "_ycid_").toLowerCase()); boolean autoref = false; try { autoref = GridUtils.prossRowSetDataType_Boolean(map, "isAutoRefresh"); } catch (Exception e) { } sb.append(" Fformid='").append(this.replaceBlank(GridUtils.prossRowSetDataType_String(map, "HyperlinkFT").toLowerCase())) .append("' FsField=\"").append(sf) .append("\" FdField=\"").append(df) .append("\" Fref=\"").append(autoref ? 1 : 0) // .append("\" FopenType=\"").append(openType)//增加弹出层的功能 1表示正常的页卡,2表示弹出层显示 .append("\" Fwtype='").append(GridUtils.prossRowSetDataType_String(map, "HyperlinkFTFormType")) .append("' Fop='").append(op == null ? "0" : (op.replaceAll("'", "\\\\'").replaceAll("\n\t", ""))) .append("' Fsave='").append(save) .append("' Fexec='").append(execdo) .append("' FeFilter=\"").append(efl == null ? "" : (efl.replaceAll("'", "\\\\'").replaceAll("\n\t", ""))).append("\""); this.prossIntoSession(sf, dto); this.prossIntoSession(df, dto); this.prossIntoSessionForFilter(efl, dto); } if ((dto.order == 1 && id.equalsIgnoreCase("doccode") && this.isNullOrEmptry(GridUtils.prossRowSetDataType_String(map, "HyperlinkFT")) && this.isNullOrEmptry(GridUtils.prossRowSetDataType_String(map, "HyperlinkFTFormType")))//当是单据时候增加对doccode字段自动超链接 ) { sb.append(" Fformid='").append(dto.formID) .append("' FsField=\"").append("doccode") .append("\" FdField=\"").append("doccode") .append("\" Fwtype='").append(dto.othType) .append("' FeFilter=\"").append("\""); } if (ShowOnGrid && id.equalsIgnoreCase(dto.lastField.toLowerCase())) sb.append(" ent='1' ");//增加标记为最后一个字段 if (index < dto.frozencols) {// left.append("\n"); if (ValueExp != null && !"".equalsIgnoreCase(ValueExp)) {//增加一个有权限控制的关联字段 left.append("\n"); } if (!fileterID&&ShowOnGrid) index++; } else { cols.append("\n"); if (ValueExp != null && !"".equalsIgnoreCase(ValueExp)) {//增加一个有权限控制的关联字段 cols.append("\n"); } } } //while(dto.gfields.next()); if ("".equalsIgnoreCase(dto.orderFiled)) dto.orderFiled = firstID + " desc"; dto.expr = valExp.length() > 0 ? valExp.substring(0, valExp.length() - 1) : ""; dto.cspr = cssExp.length() > 0 ? cssExp.substring(0, cssExp.length() - 1) : ""; dto.tipspr = tipsExp.length() > 0 ? tipsExp.substring(0, tipsExp.length() - 1) : ""; if (cols.length() == 0 && !dto.gantt) { msgInfo.append(dto.formID + "-格线未设置显示字段或9801定义的冻结列数大于需要显示的列数或加载项(isLoad)未勾选!"); } if (cols.length() > 0) dto.colsConfig = cols.substring(0, cols.length() - 1); dto.LeftCols = left.length() > 0 ? "" + left.substring(0, left.length() - 1) + "" : ""; dto.formula = formn.length() > 1 ? formn.substring(0, formn.length() - 1) : ""; dto.initValue = values.length() > 1 ? values.substring(0, values.length() - 3) : ""; dto.totalCols = sumfu.length() > 1 ? sumfu.substring(0, sumfu.length() - 1) : ""; if (!iscopy && rowCopys != null) { dto.rowcopyfields = rowCopys.length() > 1 ? rowCopys.substring(0, rowCopys.length() - 1) : ""; } if (dto.totalCols == "") { dto.foot = ""; dto.foot2 = ""; }//当没有统计列时候不需要显示 else { dto.foot = ""; } if ((exportInfo.lastIndexOf("-") + 1) < exportInfo.length()) { int tsm = dto.conNum == 0 ? dto.winType : dto.othType; exportInfo.append("-").append(tsm).append("-").append(SumFieldInfo.toString());//后面跟窗体类型 // String titles=""; // if(exportTitle.length()>0) { // titles=exportTitle.toString(); // if(titles.lastIndexOf(";")>0) titles=titles.substring(0, titles.length()-1); // } // titles=titles+"@p@"+exportInfo.toString(); FileUtil.writeFile(exportInfo.toString(), root.replaceAll("\\\\", "/") + File.separator + dto.verNo + "/" + dto.formID + "/" + tsm + "/data");//写到文件里面 } if (msgInfo.length() > 0) throw new ApplicationException(msgInfo.toString()); } catch (ArrayIndexOutOfBoundsException e1) { throw new ApplicationException("读取不到" + dto.formID + "在9802里面的字段信息,请检查9802是否已做了相关设置"); } catch (Exception e) { e.printStackTrace(); throw new ApplicationException(e.getCause() == null ? e.getMessage() + "\n" + msgInfo.toString() + "_" + dto.dbid : e.getCause().getMessage() + "\n" + msgInfo.toString() + "_" + dto.dbid); } finally { left = null; cols = null; formn = null; values = null; sumfu = null; valExp = null; msgInfo = null; } } private void setFilter(String id, int type, StringBuilder filter, int dIndex) { switch (type) { case 1: case 7: if (dIndex == 4)//是日期类型,虽然定义为1类型也显示日期 filter.append(id).append("Range=\"1\" ") .append(id).append("Filter=\"0\" ") .append(id).append("ShowMenu=\"0\" "); else filter.append(id).append("Range=\"1\" ") .append(id).append("Filter=\"0\" ") .append(id).append("ShowMenu=\"1\" "); break; case 5: filter.append(id).append("Range=\"1\" ") .append(id).append("Filter=\"0\" ") .append(id).append("ShowMenu=\"0\" "); break; case 2: case 31: case 35: filter.append(id).append("Range=\"1\" ") .append(id).append("Type='Text'") .append(id).append("ShowMenu=\"1\" "); break; case 3: filter.append(id).append("Range=\"1\" ") .append(id).append("Button='' ") .append(id).append("Type='Text'") .append(id).append("ShowMenu=\"1\" "); break; case 9: case 19: case 40: filter.append(id).append("CanEdit='0' ") .append(id).append("Button='' ") .append(id).append("Type='Text' ") .append(id).append("ShowMenu='0' "); break; case 6: filter.append(id).append("Range=\"1\" ") .append(id).append("Button=\"Defaults\" ") .append(id).append("Defaults=\"|*FilterOff|*RowsAll\" ") .append(id).append("ShowMenu=\"0\" "); break; } } /** * 把需要从会话中替换的值写到页面里 **/ private void prossIntoSession(String str, TreeGridDTO dto) { if (str != null && str.length() > 0) { StringBuilder sb = new StringBuilder(); String[] s = str.split(";"); int index = 0; String kk = "";//中间变量 for (String te : s) { if (te.indexOf("@") == 0) {//需要从会话里读 //处理会话值为空的情况,导致页面js的json对象出现脚本错误 String temp = "<%=(session.getAttribute(\"" + te.toLowerCase() + "\")==null||((String)session.getAttribute(\"" + te.toLowerCase() + "\")).length()==0)?\"\":session.getAttribute(\"" + te.toLowerCase() + "\")%>";//DBHelper.getValRep(te.toLowerCase(),false); if (te.equalsIgnoreCase(kk)) continue; kk = te; if (index > 0) sb.append(","); if (dto.setInfo != null && dto.setInfo.trim().length() > 0 && index == 0) dto.setInfo += ","; sb.append(te.replaceAll("'", "").replaceAll("@", "").toLowerCase()) .append(":") .append("'") .append(temp) .append("'");//还原引号是因为需要引号括起来,在页面才不会出现脚本错误 index++; } } dto.setInfo += sb.toString(); } } /** * 把需要从会话中替换的值写到页面里 ,适用是自定义条件的情况 * 也就是一条sql语句中需要查出来替换,isnull(cccode,'')='@cccode' **/ private void prossIntoSessionForFilter(String str, TreeGridDTO dto) { if (str != null && str.length() > 0) { StringBuilder sb = new StringBuilder(); Pattern p = Pattern.compile("@.*?\\w+");// 匹配以@开头的单词 java.util.regex.Matcher propsMatcher = p.matcher(str); int index = 0; String kk = ""; String kt = ""; while (propsMatcher.find()) { String te = propsMatcher.group(); String temp = "<%=(session.getAttribute(\"" + te.toLowerCase() + "\")==null||((String)session.getAttribute(\"" + te.toLowerCase() + "\")).length()==0)?\"\":session.getAttribute(\"" + te.toLowerCase() + "\")%>";//DBHelper.getValRep(te.toLowerCase(),false); if (te.equalsIgnoreCase(kk)) continue; if (dto.setInfo.indexOf(kt + ":") > 0) continue; kk = te; if (index > 0) sb.append(","); if (dto.setInfo != null && dto.setInfo.trim().length() > 0 && index == 0) dto.setInfo += ","; kt = te.replaceAll("@", "").toLowerCase(); sb.append(te.replaceAll("@", "").toLowerCase()) .append(":") .append("'") .append(temp) .append("'"); index++; } dto.setInfo += sb.toString(); } } private void prossIntoSessionForFilter_dy(String str, TreeGridDTO dto) { if (str != null && str.length() > 0) { StringBuilder sb = new StringBuilder(); Pattern p = Pattern.compile("@.*?\\w+");// 匹配以@开头的单词 java.util.regex.Matcher propsMatcher = p.matcher(str); int index = 0; String kk = ""; while (propsMatcher.find()) { String te = propsMatcher.group(); String temp = "<%=(session.getAttribute(\"" + te.toLowerCase() + "\")==null||((String)session.getAttribute(\"" + te.toLowerCase() + "\")).length()==0)?\"\":session.getAttribute(\"" + te.toLowerCase() + "\")%>";//DBHelper.getValRep(te.toLowerCase(),false); if (te.equalsIgnoreCase(kk)) continue; kk = te; if (index > 0) sb.append(","); sb.append(te.replaceAll("@", "").toLowerCase()) .append(":") .append("'") .append(temp) .append("'"); index++; if(!"".equalsIgnoreCase(dto.setInfo_dy)){ dto.setInfo_dy +=","; } } dto.setInfo_dy += sb.toString(); } } /** * 处理生成多表结构中的多表格 **/ public void setTabPage(int formType, int height, int count, TreeGridDTO dto) { dto.tabPage = formType; dto.gridHeight = height; dto.masterKey = count == 0 ? "" : count + ""; dto.b499 = true; } public void setTabPage497(int type, int height1, String indexs, String tolkey, int formid, int index, TreeGridDTO dto) { dto.tabPage = type; dto.gridHeight = height1; dto.masterKey = indexs; dto.b497 = true; dto.b499 = true; dto.tolkey = tolkey; dto.PriFormID = formid;//取得主功能号里面的排除功能号和字段列表用 by 11-5-28 dto.PriIndex = index; } /** * 根据不同类型决定不同的排序规则 * //1,读取9801设置, * //2,根据不同类型再进行不同的设置(单据清单desc,明细 以docitem asc,) * //3,对于不是上面的二种情况不用排序 */ private String setOrderBy(TreeGridDTO dto) { String temp = ""; if (dto.order == 1 && dto.index1 != null && !dto.index1.isEmpty()) { //9801 主表 temp = setSqlOrderBy(dto.index1, " asc"); } else if (dto.order == 2 && dto.index2 != null && !dto.index2.isEmpty()) {//明细表 temp = setSqlOrderBy(dto.index2, " asc"); } else { if (dto.field.isEmpty()) temp = dto.orderFiled; else { //处理8类型第三表的排序不是默认的docitm的情况,也就是9801定义有排序 if(dto.winType==15&&dto.order==2&& org.apache.commons.lang3.StringUtils.isNotBlank(dto.index1)){ temp = setSqlOrderBy(dto.index1, " asc"); }else { temp = setSqlOrderBy(dto.field, dto.order == 1 ? " desc" : " asc"); } } } dto.field = ""; if ("".equalsIgnoreCase(temp)) return ""; String[] s = temp.replaceAll(",", " ").split("\\s+");// String cols = "SortCols='"; String types = "SortTypes='"; for (int j = 0; j < s.length; j += 2) { if (j > 0) { cols += ","; types += ","; } cols += s[j].equalsIgnoreCase("_ycid_") ? "id" : s[j]; types += "asc".equalsIgnoreCase(s[j + 1]) ? "0" : "1"; } return cols + "' " + types + "'"; } private String setSqlOrderBy(String index22, String x) {//x为desc,asc String temp = ""; index22 = index22.replaceAll(";", ","); String[] sorts = index22.split(","); int index = 0; for (String s : sorts) { String[] str = s.split("\\s"); if (str.length == 2) { if (index > 0) temp += "," + str[0] + " " + str[1]; else temp += str[0] + " " + str[1]; } else { if (index > 0) temp += "," + str[0] + " " + x; else temp += str[0] + " " + x; } index++; } return temp; } /** * 设置表格高度 */ private String setGridHight(TreeGridDTO dto) { if (((dto.winType != 1 || dto.winType != 10) && dto.order == 2) && dto.gridHeight == 0) dto.gridHeight = GRID_HEIGHT; String temp = dto.gridHeight > 0 ? dto.gridHeight + "px" : GRID_HEIGHT + "px"; dto.gridHeight = 0; return temp; } /* (non-Javadoc) * @see com.yc.action.grid.TreeGridIfc#createGrid(int, int, java.lang.String, java.lang.String, java.lang.String[]) */ @Override public void createGrid(int type, int formID, String root, String path, String fileName[], String tempPath, String pst, TMuiDTO dt, String dbid) throws DataAccessException, SQLException { try { StringBuilder sb = new StringBuilder();//总的js StringBuilder jsp = new StringBuilder();//总的jsp StringBuilder main = new StringBuilder();//临时main标记 StringBuilder hd = new StringBuilder();//临时header标记 TreeGridDTO dto = new TreeGridDTO(); String refgrid = "";//保存需要引用多少个grid dto.verNo = path.replaceAll("\\\\", "/");//系统号+版本号+语言 dto.formID = formID; dto.winType = type; dto.othType = 0; dto.dbid = dbid; if (dt != null) {//把多表的值传过来填充 this.setTabPage497(dt.type, dt.height1, dt.indexs, dt.tolkey, dt.fromid, dt.index,dto); this.setXxk(dt.xxk, dto); dto.formTabName=dt.formTabName; } if (dt != null && dt.addnew) dto.postStatusAddNew = dt.addnew; int ty = gridService.getwinType(dto.winType); if (ty == 4 || ty == 5) { dto.isTable = false; dto.action = ty == 4 ? "func" : "proc"; } String hasGrid = ""; int num = 1;//循环次数 if (dto.winType == 9) { num = 2; dto.othType = 5; } if (dto.winType == 17) { num = 1; dto.othType = 16; hasGrid = "0"; } if (dto.winType == 15) { num = 3; dto.othType = 8; dto.muilGrid = true; }//三表有关联 if (dto.winType == 152) { num = 3; dto.othType = 151; dto.muilGrid = true; }//三表无关联 if (dto.winType == 499 || dto.winType == 498) { dto.othType = 498; hasGrid = "many"; }//多表 if (dto.winType == 497 || dto.winType == 496) { dto.othType = 496; hasGrid = "many"; }//多表且有关联 for (int i = 0; i < num; i++) { if (dto.winType == 3 || dto.winType == 4 || dto.winType == 30 || dto.winType == 301) {//树类型,需要生成与树相关的值 dto.treefield = this.getTreeFields(formID, dto.dbid); } String str = FileUtil.readFile(tempPath + "/grid.jsp");//页面模板 if (dto.muilGrid && i == 0) jsp.append(str).append("\n"); //先保存好模板,以便生成多表时候用 dto.conNum = i; dto.order = setOrderName(dto); this.print(root, dto); String strJs = FileUtil.readFile(tempPath + (((dto.gantt && dto.order == 2) || (dto.gantt && dto.winType == 18)) ? "/grid_Gantt.js" : "/grid.js"));//页面js String[] ver = dto.verNo.split("/"); String ddsave = ""; try { if (dto.DealAfterDocSave != null && dto.DealAfterDocSave.trim().length() > 0) ddsave = "&DealAfterDocSave=" + this.replaceBlank(EncodeUtil.base64Encode(dto.DealAfterDocSave)); } catch (UnsupportedEncodingException e) { throw new ApplicationException("加密保存后执行组出错-" + dto.DealAfterDocSave); } try { String js = FileUtil.readFile(tempPath + (((dto.gantt && dto.order == 2) || (dto.gantt && dto.winType == 18)) ? "/gridDef_Gantt.xml" : "/gridDef.xml"));//js结构 js = js .replaceAll("@id", "T_" + dto.formID)//功能号 .replaceAll("@lang", ver[ver.length - 1])//语言 .replaceAll("@Cols", dto.colsConfig + "")//列定义 .replaceAll("@LeftCols", dto.LeftCols + "")//列定义 .replaceAll("@Header", dto.header.replaceAll("\\$", "\\\\\\$") + "")//列标题,转义$为\$ .replaceAll("@minHeight", GRID_HEIGHT + "")//最小高度 .replaceAll("@formidType", dto.winType + "|" + i)//当前grid的窗体类型 .replaceAll("@formid", dto.formID + "")//当前grid的功能号 .replaceAll("@formula", this.replaceBlank(dto.formula))//自定义公式 //增加判断是否存在死循环的可能 .replaceAll("@rowSpan", this.replaceBlank(dto.rowspanStr))//合并行的字段 .replaceAll("@totalCols", this.replaceBlank(dto.totalCols))//统计列 .replaceAll("@rowcopyfields", dto.rowcopyfields == null ? "" : this.replaceBlank(dto.rowcopyfields)) .replaceAll("@rowcopyformids", dto.rowcopyformids == null ? "" : this.replaceBlank(dto.rowcopyformids)) .replaceAll("@t302", dto.winType == 302 ? true + "" : false + "")//302类型 .replaceAll("@t15", (dto.winType == 15 && dto.conNum == 1) ? true + "" : false + "")//15类型中单击查询第二个grid .replaceAll("@gType", (dto.tabPage > 0) ? ((dto.tabPage == 77 || dto.tabPage == 7) ? "77" : (dto.b497 ? 497 : 499) + "") : dto.winType + "")//当前grid的窗体类型 .replaceAll("@Disabled", (dto.winType == 18 && dto.gantt) ? "GanttDisabled=\"2\"" : "") .replaceAll("@glcodefield", dto.glcodefield == null ? "" : dto.glcodefield + "") .replaceAll("@treefield", this.replaceBlank(dto.treefield))//用在格线对应字段没设置初始值时,需要从树里取得值,所以需要在这里 .replaceAll("@expr", this.replaceBlank(dto.expr.replaceAll("<", "<").replaceAll(">", ">"))) .replaceAll("@css", this.replaceBlank(dto.cspr)) .replaceAll("@tips", this.replaceBlank(dto.tipspr)) .replaceAll("@tolkey", this.replaceBlank(dto.tolkey)) .replaceAll("@colns", this.replaceBlank(dto.columns)) .replaceAll("@MainCol", (dto.mainCol == null || "".equalsIgnoreCase(dto.mainCol)) ? "" : "MainCol='" + dto.mainCol.toLowerCase() + "'") .replaceAll("@isNine", ((dto.othType > 0) && i == 0) ? ("/" + dto.verNo + dto.formID + "/" + dto.othType + "/index.jsp") : "null")//双击打开 .replaceAll("@nineType", dto.othType + "")////双击打开页面指定的类型 .replaceAll("@keyid", (dto.b499 || dto.b497) ? (dto.masterKey.trim().equalsIgnoreCase(",") ? "" : dto.masterKey.trim()) : (dto.masterKey + "," + dto.detailKey).trim().equalsIgnoreCase(",") ? "" : (dto.masterKey + "," + dto.detailKey)) .replaceAll("@Sorting", (dto.lockGridSort == 0 ? 1 : 0) + "")//取相反值,因为是冻结排序 .replaceAll("@Sort", this.replaceBlank(this.setOrderBy(dto)))//主键列,可以有多个,以"|"分隔 .replaceAll("@foot", this.replaceBlank(dto.foot))//汇总列 .replaceAll("@panelID", dto.PriIndex + "")//针对77类型取哪一个面板数据进行过滤 .replaceAll("@ycadd", this.setToolAdd(dto) == 2 ? "Add, " : "")//清单和查询页面不需要增行和删行 .replaceAll("@predocstatus", dto.predocstatus + "")//确认前状态值 //.replaceAll("@PostStatusGridAddNew",dto.postStatusAddNew+"")//确认前状态值 .replaceAll("@Columns", dto.colset == 1 ? "Columns," : "")//列过滤 .replaceAll("@Actions", dto.actions)// .replace("@Tree", (dto.conNum == 0 || (dto.mainCol == null || "".equalsIgnoreCase(dto.mainCol))) ? "" : " AddChild,")// .replace("@isTree", (dto.conNum == 0 || (dto.mainCol == null || "".equalsIgnoreCase(dto.mainCol))) ? "0" : "1") .replace("@formTabName", dto.formTabName) .replaceAll("@primeKey", (dto.primeKey == null || "".equalsIgnoreCase(dto.primeKey)) ? "" : dto.primeKey + ";") .replaceAll("@Filter", (dto.isFilter == 1) ? dto.filter.append(" />").toString() : "")//DIV .replaceAll("@defaultRowCount", dto.order == 2 ? dto.defaultRowCount + "" : "0")//格线默认行数 .replaceAll("@gltotal", this.replaceBlank(dto.gltotal));//辅助核算需要的汇兑,平衡字段 strJs = strJs .replaceAll("@dataformid", (i == 0) ? (dto.dataformid != "" ? "&dataformid=" + this.replaceBlank(dto.dataformid) : "") : "")//dataformid功能,i==0表示只有单据清单才需要过滤 .replaceAll("@tranformid", (dto.tranformid != "" ? "&tranformid=" + this.replaceBlank(dto.tranformid) : ""))//dataformid功能,确认时候调用来断定 .replaceAll("@action", dto.action) .replaceAll("@lang", ver[ver.length - 1])//语言 .replaceAll("@foot2", this.replaceBlank(dto.foot2)) .replaceAll("@_ycaddnew_@", this.setToolAddForNew(dto))//当前用户是否存在OA审核按钮,其中有为1的则格线需要显示增行按钮 //.replaceAll("@_attachment_server_@", domain==null?"":domain)//附件服务器地址 .replaceAll("@picFild", this.replaceBlank("&picFild=" + dto.picFild)) .replaceAll("@TBCols", "&tbCols=" + EncodeUtil.base64Encode(this.replaceBlank(dto.totalCols)))//统计列 .replaceAll("@initValue", this.replaceBlank(dto.initValue))//初始值 .replaceAll("@verNo", this.replaceBlank(dto.verNo))//系统号+版本号+语言 .replaceAll("@setInfo", this.replaceBlank(dto.setInfo_dy.length() > 0 ? (dto.setInfo.length() > 0 ? dto.setInfo + "," + dto.setInfo_dy : dto.setInfo_dy) : dto.setInfo))//会话信息 .replaceAll("@optype", this.replaceBlank(dto.optype + ""))//权限信息 .replaceAll("@num", setGridNum(dto)) .replaceAll("@fileTime", this.setFilePath(path.replaceAll("\\\\", "/"), this.setJsName(dto), pst, dto)) .replaceAll("@divID", "T_" + dto.formID)//div所在的id .replaceAll("@trangroup", dto.trangroup)//过帐类型 .replaceAll("@layout", this.setJsName(dto))//js文件名称 .replaceAll("@hasGrid", hasGrid)//js文件名称 .replaceAll("@isTree", (dto.mainCol == null || "".equalsIgnoreCase(dto.mainCol)) ? "" : "&isTree=1") .replaceAll("@winType", dto.winType + "@p@" + i)//表的顺序 0表示读取主表 1表示读取从表 .replaceAll("@id", dto.formID + "")//功能号 .replaceAll("@DealAfterDocSave", ddsave)//保存时执行 .replaceAll("@CancelProc", "&cancelProc=" + this.replaceBlank(EncodeUtil.base64Encode(dto.cancelProc)) + "&cancelisSave=" + dto.cancelisSave + "&isExchangeDataWithHost=" + dto.isExchangeDataWithHost)//取消确认 .replaceAll("@revokeProc", "&revokeProc=" + this.replaceBlank(EncodeUtil.base64Encode(dto.revokeProc)))//审核撤回 .replaceAll("@pageSize", this.replaceBlank(dto.pageSize + ""))// .replaceAll("@paging", "&autopaging=" + this.replaceBlank((dto.autopaging == 1 ? 3 : 2) + ""))// .replaceAll("@formdatafilters", this.replaceBlank(i == 0 ? dto.formdatafilters.replaceAll("'", "\\\\'").replaceAll("%", "@~") : ""))//i==0表示只有单据清单才需要过滤 .replaceAll("@ProcGroupafterSavedoc", (dto.othType > 0 && i > 0 && dto.ProcGroupafterSavedoc != null && dto.ProcGroupafterSavedoc.trim().length() > 0) ? "&ProcGroupafterSavedoc=" + dto.ProcGroupafterSavedoc : ""); String tableType = null; try { SpObserver.setDBtoInstance("_" + dto.dbid); tableType = this.gridService.getSimpleJdbcTemplate().queryForObject("select TABLE_TYPE from information_schema.TABLES where table_name=?", new Object[]{dto.table.split("\\|")[0]}, String.class); } catch (DataAccessException e) { if (e instanceof EmptyResultDataAccessException) { tableType = ""; } else { throw e; } } finally { SpObserver.setDBtoInstance(); } if (dto.conNum != 0 && ("BASE TABLE".equals(tableType) || "VIEW".equals(tableType))) {//表示为基本表,需要有主键 if ((dto.primeKey == null || "".equalsIgnoreCase(dto.primeKey))) throw new ApplicationException(dto.formID + "-" + dto.table + "表没有设置主键!"); } //-------------------- String hi = this.setGridHight(dto); dto.headerDiv = "\n
" + ("90%".equalsIgnoreCase(hi) ? "" : "
");//增加多表加载时不显示所有格线 if ((i <= 1 && !dto.muilGrid) || (dto.muilGrid && i < 1 && num < 4)) {//不是多表,只需要生成一个gt-grid 单表,清单表(二表,三表,多表) if ((dto.winType != 7 && dto.winType != 77) && (dto.b497 && dto.PriFormID == -1 || dto.b499 && dto.PriFormID == -1)) {//表示496,498多表的第一个表 int value = Integer.parseInt(dto.tolkey); String create = ""; for (int v = 1; v <= value; v++) create += "create" + v + "(where,flag,cp);";//为了引用其它grid,3表 strJs = strJs.replaceAll("@create", create); } else { if (dto.winType == 15) {//表示15类型的第二表需要增加一个定时执行功能,以便处理第三表的过滤问题 //create1(where,flag,cp); if (i == 1) { strJs = strJs.replaceAll("@create", "var def=jQuery.Deferred();\n setTimeout(function() {def.resolve('ok');}, 3000);"); } } //前端处理,通过从表调用过滤 避免主表还没加载完的情况 by danaus 2021/1/28 16:05 // else if (dto.b497) {//表示多表增加一个定时执行功能,以便处理关联表的过滤问题 // strJs = strJs.replaceAll("@create", "setTimeout(function() {mygrid" + setGridNum(dto) + ".setFilter496();}, 3000);"); // } strJs = strJs.replaceAll("@create", ""); } str = str .replaceAll("@main", strJs) .replaceAll("@head", dto.headerDiv)//DIV .replaceAll("@suggstDiv", dto.sugList.toString())//自动补全 .replaceAll("@gridconnum", String.valueOf(dto.conNum));//判断单表用来计算grid高度需要。。。替换grid.jsp里面的@gridconnum FileUtil.writeFile(js, root.replaceAll("\\\\", "/") + File.separatorChar + this.setFilePath(path.replaceAll("\\\\", "/"), this.setJsName(dto), pst, dto));//生成新页面js FileUtil.writeFile(str, root.replaceAll("\\\\", "/") + File.separatorChar + this.setFilePath(path.replaceAll("\\\\", "/"), fileName[0], pst, dto));//生成新页面 } else {//多表,整个页面生成多个表格 if (refgrid != "") refgrid += ","; refgrid += ("T_" + dto.formID);//为了引用其它grid,3表 if (!"".equalsIgnoreCase(setGridNum(dto))) { if (dto.winType == 15) {//表示15类型的第二表需要增加一个定时执行功能,以便处理第三表的过滤问题 if (i == 2) { strJs = strJs.replaceAll("@create", " var def=jQuery.Deferred(); \n setTimeout(function() { def.resolve('ok');}, 3000);"); strJs = strJs.replaceAll("@jspromise", " return def;"); } } strJs = strJs.replaceAll("@create", ""); //create+="setTimeout(function() {create"+setGridNum()+"(where,flag,cp);}, 1000);"; if (Integer.parseInt(setGridNum(dto)) == 1 && dto.winType == 15) { // dto.create+=" setTimeout(function() {create"+setGridNum(dto)+"(where,flag,cp);}, 500);"; dto.create += " var def=jQuery.Deferred(); setTimeout(function() {def.resolve('ok');}, 2000);"; } else dto.create += "create" + setGridNum(dto) + "(where,flag,cp);";//为了引用其它grid,3表 } main.append(strJs).append("\n"); hd.append(dto.headerDiv).append("\n"); FileUtil.writeFile(js, root.replaceAll("\\\\", "/") + File.separatorChar + this.setFilePath(path.replaceAll("\\\\", "/"), this.setJsName(dto), pst, dto));//生成各个表的js } dto.gfields = null; } catch (Exception e) { throw new ApplicationException(e.toString()); } } if (dto.muilGrid && dto.conNum > 1) {//多表,需要把几个gt-grid生成在同一个页面 String strd = jsp.toString() .replaceAll("@main", main.toString().replaceAll("@refgrid", refgrid)).replaceAll("@create", dto.create) .replaceAll("@head", hd.toString())//自定义表头 .replaceAll("@suggstDiv", dto.sugList.toString())//自动补全 .replaceAll("@gridconnum", String.valueOf(dto.conNum));//判断多表用来计算grid高度需要。。。替换grid.jsp里面的@gridconnum FileUtil.writeFile(strd, root.replaceAll("\\\\", "/") + this.setFilePath(path.replaceAll("\\\\", "/"), fileName[0], pst, dto));//生成新页面 } sb = null; jsp = null; main = null; hd = null; } catch (DataAccessException e) { throw new ApplicationException(e.toString()); } } /** * 解决5,9 16,17 8,15的关联生成问题 * * @param root TODO **/ private String setFilePath(String p, String name, String root, TreeGridDTO dto) { StringBuilder sb = new StringBuilder(); if (!dto.b497 || !dto.b499) root = sb.append("/").append(dto.minID == 0 ? dto.formID : dto.minID).append("/").append(dto.conNum == 0 ? dto.winType : dto.othType).append("/").toString(); return new StringBuilder().append(p).append(root).append(name).toString(); } /** * 根据当前grid的次数而生成需要的标记,以区别同一页面不同grid的引用 */ private String setGridNum(TreeGridDTO dto) { if (dto.b497 || dto.b499) return dto.PriIndex == 0 ? "" : dto.PriIndex + ""; else return dto.conNum <= 1 ? "" : (dto.conNum - 1) + ""; } @Override public void setTabPage(int type, int height1, String indexs, String tolkey, int formid, int index, TreeGridDTO dto) { dto.tabPage = type; dto.gridHeight = height1; dto.masterKey = indexs; dto.b497 = true; dto.tolkey = tolkey; dto.PriFormID = formid;//取得主功能号里面的排除功能号和字段列表用 by 11-5-28 dto.PriIndex = index; } @Override public Grid getGridInfo(int formid, String type, boolean excel, TreeGridDTO dto) { Grid grid = new Grid(); this.getTableName(formid, type, dto);//type:"9|0" grid.setFormID(formid); grid.setWinType(type); String ddsave = ""; grid.setExcel(excel); try { if (dto.DealAfterDocSave != null && dto.DealAfterDocSave.trim().length() > 0) ddsave = EncodeUtil.base64Encode(dto.DealAfterDocSave); } catch (UnsupportedEncodingException e) { throw new ApplicationException("加密保存后执行组出错-" + dto.DealAfterDocSave); } grid.setDealAfterDocSave(ddsave); if (dto.ProcGroupafterSavedoc != null && !"".equals(dto.ProcGroupafterSavedoc)) { grid.setProcGroupafterSavedoc(Integer.parseInt(dto.ProcGroupafterSavedoc)); } grid.setTrangroup(dto.trangroup);//过账逻辑号 return grid; } @Override public void setXxk(int xxk, TreeGridDTO dto) { // TODO Auto-generated method stub dto.xxk = xxk; } }