提交 e2619528 编写于 作者: NoSubject's avatar NoSubject

Merge branch 'wrdp' into 'feature/menu_group'

# Conflicts:
#   o2web/source/o2_core/o2/xDesktop/Default.js
{
"mock": {
"x_processplatform_assemble_surface": {
"put": {
"to": "post",
"append": "mockputtopost"
},
"delete": {
"to": "get",
"append": "mockdeletetoget"
}
},
"x_cms_assemble_control": {
"put": {
"to": "post",
"append": "mockputtopost"
},
"delete": {
"to": "get",
"append": "mockdeletetoget"
}
},
"x_query_assemble_surface": {
"put": {
"to": "post",
"append": "mockputtopost"
},
"delete": {
"to": "get",
"append": "mockdeletetoget"
}
},
"x_organization_assemble_authentication": {
"put": {
"to": "post",
"append": "mockputtopost"
},
"delete": {
"to": "get",
"append": "mockdeletetoget"
}
},
"x_organization_assemble_personal": {
"put": {
"to": "post",
"append": "mockputtopost"
},
"delete": {
"to": "get",
"append": "mockdeletetoget"
}
}
}
}
{
"mock": {},
"###mock": "使用Post模拟Put,Get模拟Delete的模块.###"
}
\ No newline at end of file
"###web": "web端使用到的全局参数配置,没有特定业务含义,满足json格式即可.###"
}
......@@ -81,6 +81,7 @@ public class Config {
public static final String PATH_CONFIG_COMPONENTS = "config/components.json";
public static final String PATH_CONFIG_EMAIL = "config/email.json";
public static final String PATH_CONFIG_WEB = "config/web.json";
public static final String PATH_CONFIG_MOCK = "config/mock.json";
public static final String DIR_COMMONS = "commons";
public static final String DIR_COMMONS_TESS4J_TESSDATA = "commons/tess4j/tessdata";
......@@ -1176,6 +1177,19 @@ public class Config {
return instance().web;
}
public JsonObject mock;
public static synchronized JsonObject mock() throws Exception {
if (null == instance().mock) {
JsonObject obj = BaseTools.readConfigObject(PATH_CONFIG_MOCK, JsonObject.class);
if (null == obj) {
obj = new JsonObject();
}
instance().mock = obj;
}
return instance().mock;
}
public Map<String, JsonObject> customConfig = new HashMap<>();
public static synchronized JsonObject customConfig(String configName) throws Exception {
......
package com.x.base.core.project.config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
import java.io.File;
import java.util.*;
import java.util.concurrent.ConcurrentSkipListMap;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.x.base.core.project.gson.XGsonBuilder;
import com.x.base.core.project.tools.DefaultCharset;
import com.x.base.core.project.tools.Host;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.ObjectUtils;
import com.x.base.core.project.tools.ListTools;
import org.apache.commons.lang3.StringUtils;
public class WebServers extends ConcurrentSkipListMap<String, WebServer> {
private static final long serialVersionUID = -706102090064680898L;
private static final String MAP_LOGINPAGE = "loginPage";
public WebServers() {
super();
}
......@@ -66,4 +73,92 @@ public class WebServers extends ConcurrentSkipListMap<String, WebServer> {
});
}
public static void updateWebServerConfigJson() throws Exception {
File dir = new File(Config.base(), "servers/webServer/x_desktop/res/config");
FileUtils.forceMkdir(dir);
File file = new File(dir, "config.json");
Gson gson = XGsonBuilder.instance();
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
/** 覆盖掉配置的参数 */
com.x.base.core.project.config.CenterServer centerServerConfig = Config.nodes().centerServers().first()
.getValue();
map.putAll(centerServerConfig.getConfig());
List<Map<String, String>> centers = new ArrayList<>();
map.put("center", centers);
/** 写入center地址 */
Map<String, String> center = new HashMap<String, String>();
center = new HashMap<String, String>();
center.put("host", "");
center.put("port", centerServerConfig.getPort().toString());
centers.add(center);
if (!Objects.equals(centerServerConfig.getProxyPort(), centerServerConfig.getPort())) {
center = new HashMap<String, String>();
center.put("host", "");
center.put("port", centerServerConfig.getProxyPort().toString());
centers.add(center);
}
String host = Config.nodes().primaryCenterNode();
if (!Host.isRollback(host)) {
center = new HashMap<String, String>();
center.put("host", host);
center.put("port", centerServerConfig.getPort().toString());
centers.add(center);
}
/** 写入proxy地址 */
if (StringUtils.isNotEmpty(centerServerConfig.getProxyHost())) {
center = new HashMap<String, String>();
center.put("host", centerServerConfig.getProxyHost());
center.put("port", centerServerConfig.getProxyPort().toString());
centers.add(center);
}
/** 写入systemName */
map.put("footer", Config.collect().getFooter());
map.put("title", Config.collect().getTitle());
map.put("appUrl", Config.collect().getAppUrl());
/***/
if (centerServerConfig.getSslEnable()) {
map.put("app_protocol", "https:");
} else {
map.put("app_protocol", "http:");
}
/* 上面的无效 */
map.put("app_protocol", "auto");
if ((null != Config.portal().getLoginPage())
&& (BooleanUtils.isTrue(Config.portal().getLoginPage().getEnable()))) {
map.put(MAP_LOGINPAGE, Config.portal().getLoginPage());
} else if ((null != Config.person().getLoginPage())
&& (BooleanUtils.isTrue(Config.person().getLoginPage().getEnable()))) {
map.put(MAP_LOGINPAGE, Config.person().getLoginPage());
} else {
map.put(MAP_LOGINPAGE, Config.portal().getLoginPage());
}
map.put("indexPage", Config.portal().getIndexPage());
map.put("webSocketEnable", Config.communicate().wsEnable());
map.put("urlMapping", Config.portal().getUrlMapping());
/* 密码规则 */
map.put("passwordRegex", Config.person().getPasswordRegex());
map.put("passwordRegexHint", Config.person().getPasswordRegexHint());
/* RSA */
File publicKeyFile = new File(Config.base(), "config/public.key");
if (publicKeyFile.exists() && publicKeyFile.isFile()) {
String publicKey = FileUtils.readFileToString(publicKeyFile, "utf-8");
byte[] publicKeyB = org.apache.commons.codec.binary.Base64.decodeBase64(publicKey);
publicKey = new String(Base64.encodeBase64(publicKeyB));
map.put("publicKey", publicKey);
}
for (Entry<String, JsonElement> en : Config.web().entrySet()) {
map.put(en.getKey(), en.getValue());
}
for (Entry<String, JsonElement> en : Config.mock().entrySet()) {
map.put(en.getKey(), en.getValue());
}
FileUtils.writeStringToFile(file, gson.toJson(map), DefaultCharset.charset);
}
}
......@@ -145,16 +145,12 @@ public class BaseTools {
public static boolean executeSyncFile(String syncFilePath) throws Exception {
boolean Syncflag = false;
String localip = getIpAddress();
Nodes nodes = Config.nodes();
//同步config文件
if(Config.nodes().centerServers().first().getValue().getConfigApiEnable()) {
for (String node : nodes.keySet()) {
//其他服务器
if (!node.equalsIgnoreCase(localip)) {
if (nodes.get(node).getApplication().getEnable() || nodes.get(node).getCenter().getEnable()) {
Syncflag = executeSyncFile(syncFilePath, node, nodes.get(node).nodeAgentPort());
}
if (nodes.get(node).getApplication().getEnable() || nodes.get(node).getCenter().getEnable()) {
Syncflag = executeSyncFile(syncFilePath, node, nodes.get(node).nodeAgentPort());
}
}
}
......@@ -172,7 +168,7 @@ public class BaseTools {
fileInputStream= new FileInputStream(syncFile);
socket.setKeepAlive(true);
socket.setSoTimeout(5000);
socket.setSoTimeout(2000);
DataOutputStream dos = null;
DataInputStream dis = null;
try {
......@@ -236,4 +232,4 @@ public class BaseTools {
}
return "";
}
}
\ No newline at end of file
}
package com.x.base.core.project.tools;
import org.apache.commons.lang3.StringUtils;
import java.security.NoSuchAlgorithmException;
/**
* @author louguodong
*
*/
public class MD5Tool {
public static String getMD5(byte[] source) {
String s = null;
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };// 用来将字节转换成16进制表示的字符
try {
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
md.update(source);
byte tmp[] = md.digest();// MD5 的计算结果是一个 128 位的长整数,
// 用字节表示就是 16 个字节
char str[] = new char[16 * 2];// 每个字节用 16 进制表示的话,使用两个字符, 所以表示成 16
// 进制需要 32 个字符
int k = 0;// 表示转换结果中对应的字符位置
for (int i = 0; i < 16; i++) {// 从第一个字节开始,对 MD5 的每一个字节// 转换成 16
// 进制字符的转换
byte byte0 = tmp[i];// 取第 i 个字节
str[k++] = hexDigits[byte0 >>> 4 & 0xf];// 取字节中高 4 位的数字转换,// >>>
// 为逻辑右移,将符号位一起右移
str[k++] = hexDigits[byte0 & 0xf];// 取字节中低 4 位的数字转换
}
s = new String(str);// 换后的结果转换为字符串
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return s;
}
public static String getMD5Str(String source) {
if (StringUtils.isNotEmpty(source)) {
return getMD5(source.getBytes());
} else {
return "";
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String test = MD5Tool.getMD5("1qaz2wsx".getBytes());
System.out.println(test);
}
}
......@@ -201,7 +201,7 @@ public class ActionPersistPublishContent extends BaseAction {
wi.setCreatorIdentity( userManagerService.getMajorIdentityWithPerson( wi.getCreatorPerson() ) );
}
}
if ( !StringUtils.equals( "cipher", wi.getCreatorIdentity() ) && !StringUtils.equals( "xadmin", wi.getCreatorIdentity() )) {
//说明是实际的用户,并不使用cipher和xadmin代替
if (StringUtils.isNotEmpty( wi.getCreatorIdentity() )) {
......@@ -283,8 +283,44 @@ public class ActionPersistPublishContent extends BaseAction {
}
}
//从CMS其他文档中复制所有的附件到CMS
if (check) {
try {
if ( wi.getCms_attachmentIds() != null && wi.getCms_attachmentIds().length > 0 ) {
FileInfo fileInfo = null;
FileInfo copyFileInfo = null;
StorageMapping mapping_attachment = null;
StorageMapping mapping_fileInfo = null;
byte[] attachment_content = null;
for (String attachmentId : wi.getCms_attachmentIds()) {
try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
document = emc.find(document.getId(), Document.class, ExceptionWhen.not_found);
copyFileInfo = emc.find(attachmentId, FileInfo.class, ExceptionWhen.not_found);
if (copyFileInfo != null) {
emc.beginTransaction(FileInfo.class);
emc.beginTransaction(Document.class);
mapping_attachment = ThisApplication.context().storageMappings().get(FileInfo.class, copyFileInfo.getStorage());
attachment_content = copyFileInfo.readContent(mapping_attachment);
mapping_fileInfo = ThisApplication.context().storageMappings().random(FileInfo.class);
fileInfo = concreteFileInfo(effectivePerson.getDistinguishedName(), document, mapping_fileInfo, copyFileInfo.getName(), copyFileInfo.getSite());
fileInfo.saveContent(mapping_fileInfo, attachment_content, copyFileInfo.getName());
fileInfo.setName(copyFileInfo.getName());
emc.check(document, CheckPersistType.all);
emc.persist(fileInfo, CheckPersistType.all);
emc.commit();
}
} catch (Throwable th) {
th.printStackTrace();
result.error(th);
}
}
}
}
if (check) {
try {
Wo wo = new Wo();
wo.setId( document.getId() );
result.setData( wo );
......@@ -397,7 +433,7 @@ public class ActionPersistPublishContent extends BaseAction {
if( categoryInfo.getSendNotify() == null ) {
if( StringUtils.equals("信息", categoryInfo.getDocumentType()) ) {
notify = true;
}
}
}else {
if( categoryInfo.getSendNotify() ) {
notify = true;
......@@ -454,40 +490,43 @@ public class ActionPersistPublishContent extends BaseAction {
}
public static class Wi {
public static WrapCopier<Wi, Document> copier = WrapCopierFactory.wi( Wi.class, Document.class, null, null);
private String id = null;
@FieldDescribe( "文档操作者身份" )
private String identity = null;
// @FieldDescribe( "数据的路径列表." )
// private String[] dataPaths = null;
@FieldDescribe( "启动流程的JobId." )
private String wf_jobId = null;
@FieldDescribe( "启动流程的WorkId." )
private String wf_workId = null;
@FieldDescribe( "启动流程的附件列表." )
private String[] wf_attachmentIds = null;
private String[] wf_attachmentIds = null;
@FieldDescribe( "内容管理其他文档的附件列表,非必填" )
private String[] cms_attachmentIds = null;
@FieldDescribe( "文档数据JSON对象." )
private Map<?, ?> docData = null;
@FieldDescribe( "文档读者,Json数组,权限对象需要包含四个属性:<br/>permission权限类别:读者|阅读|作者|管理, <br/>permissionObjectType使用者类别:所有人|组织|人员|群组, <br/>permissionObjectCode使用者编码:所有人|组织编码|人员UID|群组编码, <br/>permissionObjectName使用者名称:所有人|组织名称|人员名称|群组名称" )
private List<PermissionInfo> readerList = null;
@FieldDescribe( "文档编辑者, ,Json数组,权限对象需要包含四个属性:<br/>permission权限类别:读者|阅读|作者|管理, <br/>permissionObjectType使用者类别:所有人|组织|人员|群组, <br/>permissionObjectCode使用者编码:所有人|组织编码|人员UID|群组编码, <br/>permissionObjectName使用者名称:所有人|组织名称|人员名称|群组名称" )
private List<PermissionInfo> authorList = null;
private List<String> cloudPictures = null;
@FieldDescribe( "不修改权限(跳过权限设置,保留原来的设置), True|False." )
private Boolean skipPermission = false;
@FieldDescribe("文档摘要,70字以内")
private String summary;
......@@ -538,7 +577,7 @@ public class ActionPersistPublishContent extends BaseAction {
private Long commendCount = 0L;
private Long commentCount = 0L;
private Date publishTime;
private Date modifyTime;
......@@ -1033,9 +1072,16 @@ public class ActionPersistPublishContent extends BaseAction {
this.authorList = authorList;
}
public String[] getCms_attachmentIds() {
return cms_attachmentIds;
}
public void setCms_attachmentIds(String[] cms_attachmentIds) {
this.cms_attachmentIds = cms_attachmentIds;
}
}
public static class Wo extends WoId {
}
}
\ No newline at end of file
}
......@@ -23,6 +23,7 @@ import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import com.x.base.core.project.config.WebServers;
import com.x.base.core.project.tools.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
......@@ -133,6 +134,12 @@ public class NodeAgent extends Thread {
fos.flush();
}
fos.close();
Config.flush();
if(syncFilePath.indexOf("web.json") > -1 || syncFilePath.indexOf("collect.json") > -1
|| syncFilePath.indexOf("portal.json") > -1){
// 更新web服务配置信息
WebServers.updateWebServerConfigJson();
}
logger.info("同步完成");
continue;
......
......@@ -4,19 +4,13 @@ import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.stream.Stream;
import javax.servlet.DispatcherType;
import org.apache.commons.codec.binary.Base64;
import com.x.base.core.project.config.WebServers;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.BooleanUtils;
......@@ -31,8 +25,6 @@ import org.eclipse.jetty.webapp.WebAppContext;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.x.base.core.project.x_program_center;
import com.x.base.core.project.config.Config;
import com.x.base.core.project.config.WebServer;
......@@ -40,7 +32,6 @@ import com.x.base.core.project.gson.XGsonBuilder;
import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory;
import com.x.base.core.project.tools.DefaultCharset;
import com.x.base.core.project.tools.Host;
import com.x.server.console.server.JettySeverTools;
public class WebServerTools extends JettySeverTools {
......@@ -54,8 +45,8 @@ public class WebServerTools extends JettySeverTools {
public static Server start(WebServer webServer) throws Exception {
// 更新x_desktop的center指向
updateCenterConfigJson();
// 更新web服务配置信息
WebServers.updateWebServerConfigJson();
// 更新 favicon.ico
updateFavicon();
// 创建index.html
......@@ -172,90 +163,6 @@ public class WebServerTools extends JettySeverTools {
}
private static void updateCenterConfigJson() throws Exception {
File dir = new File(Config.base(), "servers/webServer/x_desktop/res/config");
FileUtils.forceMkdir(dir);
File file = new File(dir, "config.json");
Gson gson = XGsonBuilder.instance();
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
/** 覆盖掉配置的参数 */
com.x.base.core.project.config.CenterServer centerServerConfig = Config.nodes().centerServers().first()
.getValue();
map.putAll(centerServerConfig.getConfig());
List<Map<String, String>> centers = new ArrayList<>();
map.put("center", centers);
/** 写入center地址 */
Map<String, String> center = new HashMap<String, String>();
center = new HashMap<String, String>();
center.put("host", "");
center.put("port", centerServerConfig.getPort().toString());
centers.add(center);
if (!Objects.equals(centerServerConfig.getProxyPort(), centerServerConfig.getPort())) {
center = new HashMap<String, String>();
center.put("host", "");
center.put("port", centerServerConfig.getProxyPort().toString());
centers.add(center);
}
String host = Config.nodes().primaryCenterNode();
if (!Host.isRollback(host)) {
center = new HashMap<String, String>();
center.put("host", host);
center.put("port", centerServerConfig.getPort().toString());
centers.add(center);
}
/** 写入proxy地址 */
if (StringUtils.isNotEmpty(centerServerConfig.getProxyHost())) {
center = new HashMap<String, String>();
center.put("host", centerServerConfig.getProxyHost());
center.put("port", centerServerConfig.getProxyPort().toString());
centers.add(center);
}
/** 写入systemName */
map.put("footer", Config.collect().getFooter());
map.put("title", Config.collect().getTitle());
map.put("appUrl", Config.collect().getAppUrl());
/***/
if (centerServerConfig.getSslEnable()) {
map.put("app_protocol", "https:");
} else {
map.put("app_protocol", "http:");
}
/* 上面的无效 */
map.put("app_protocol", "auto");
if ((null != Config.portal().getLoginPage())
&& (BooleanUtils.isTrue(Config.portal().getLoginPage().getEnable()))) {
map.put(MAP_LOGINPAGE, Config.portal().getLoginPage());
} else if ((null != Config.person().getLoginPage())
&& (BooleanUtils.isTrue(Config.person().getLoginPage().getEnable()))) {
map.put(MAP_LOGINPAGE, Config.person().getLoginPage());
} else {
map.put(MAP_LOGINPAGE, Config.portal().getLoginPage());
}
map.put("indexPage", Config.portal().getIndexPage());
map.put("webSocketEnable", Config.communicate().wsEnable());
map.put("urlMapping", Config.portal().getUrlMapping());
/* 密码规则 */
map.put("passwordRegex", Config.person().getPasswordRegex());
map.put("passwordRegexHint", Config.person().getPasswordRegexHint());
/* RSA */
File publicKeyFile = new File(Config.base(), "config/public.key");
if (publicKeyFile.exists() && publicKeyFile.isFile()) {
String publicKey = FileUtils.readFileToString(publicKeyFile, "utf-8");
byte[] publicKeyB = Base64.decodeBase64(publicKey);
publicKey = new String(Base64.encodeBase64(publicKeyB));
map.put("publicKey", publicKey);
}
for (Entry<String, JsonElement> en : Config.web().entrySet()) {
map.put(en.getKey(), en.getValue());
}
FileUtils.writeStringToFile(file, gson.toJson(map), DefaultCharset.charset);
}
private static void createIndexPage() throws Exception {
if (null != Config.nodes().webServers()) {
StringBuffer buffer = new StringBuffer();
......
......@@ -3,6 +3,7 @@ package com.x.organization.assemble.authentication.jaxrs.authentication;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.x.base.core.project.tools.MD5Tool;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
......@@ -78,11 +79,12 @@ class ActionCaptchaLogin extends BaseAction {
Person o = null;
// 处理同中文问题
if (personId.indexOf(",") > -1) {
String[] arrPersion = personId.split(",");
for (int i = 0; i < arrPersion.length; i++) {
personId = arrPersion[i];
String[] arrPerson = personId.split(",");
for (int i = 0; i < arrPerson.length; i++) {
personId = arrPerson[i];
o = emc.find(personId, Person.class);
if (StringUtils.equals(Crypto.encrypt(password, Config.token().getKey()), o.getPassword())) {
if (StringUtils.equals(Crypto.encrypt(password, Config.token().getKey()), o.getPassword())
|| StringUtils.equals(MD5Tool.getMD5Str(password), o.getPassword())) {
break;
}
}
......@@ -97,7 +99,8 @@ class ActionCaptchaLogin extends BaseAction {
if (this.failureLocked(o)) {
throw new ExceptionFailureLocked(o.getName(), Config.person().getFailureInterval());
} else {
if (!StringUtils.equals(Crypto.encrypt(password, Config.token().getKey()), o.getPassword())) {
if (!StringUtils.equals(Crypto.encrypt(password, Config.token().getKey()), o.getPassword())
&& !StringUtils.equals(MD5Tool.getMD5Str(password), o.getPassword())) {
emc.beginTransaction(Person.class);
this.failure(o);
emc.commit();
......@@ -231,4 +234,4 @@ class ActionCaptchaLogin extends BaseAction {
private static final long serialVersionUID = 4940814657548190978L;
}
}
\ No newline at end of file
}
......@@ -3,6 +3,7 @@ package com.x.organization.assemble.authentication.jaxrs.authentication;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.x.base.core.project.tools.MD5Tool;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
......@@ -58,7 +59,8 @@ class ActionLogin extends BaseAction {
if (BooleanUtils.isTrue(Config.person().getSuperPermission())
&& StringUtils.equals(Config.token().getPassword(), password)) {
logger.warn("user: {} use superPermission.", credential);
} else if (!StringUtils.equals(Crypto.encrypt(password, Config.token().getKey()), o.getPassword())) {
} else if (!StringUtils.equals(Crypto.encrypt(password, Config.token().getKey()), o.getPassword())
&& !StringUtils.equals(MD5Tool.getMD5Str(password), o.getPassword())) {
/* 普通用户认证密码 */
throw new ExceptionPersonNotExistOrInvalidPassword();
}
......@@ -101,4 +103,4 @@ class ActionLogin extends BaseAction {
private static final long serialVersionUID = -5397186305200946501L;
}
}
\ No newline at end of file
}
......@@ -122,9 +122,11 @@ class ActionListIdentityWithUnitWithNameObject extends BaseAction {
public static class Wo extends com.x.base.core.project.organization.Identity {
private Integer unitOrder;
private String matchUnitName;
private String matchUnitLevelName;
private Integer matchUnitLevel;
private Integer matchUnitOrder;
private String matchUnitDutyName;
private String matchUnitDutyId;
private Integer matchUnitDutyNumber;
......@@ -176,6 +178,22 @@ class ActionListIdentityWithUnitWithNameObject extends BaseAction {
public void setMatchUnitDutyNumber(Integer matchUnitDutyNumber) {
this.matchUnitDutyNumber = matchUnitDutyNumber;
}
public Integer getUnitOrder() {
return unitOrder;
}
public void setUnitOrder(Integer unitOrder) {
this.unitOrder = unitOrder;
}
public Integer getMatchUnitOrder() {
return matchUnitOrder;
}
public void setMatchUnitOrder(Integer matchUnitOrder) {
this.matchUnitOrder = matchUnitOrder;
}
}
private List<Wo> list(Business business, List<String> names, List<String> units, Boolean recursiveUnit) throws Exception {
......@@ -246,9 +264,11 @@ class ActionListIdentityWithUnitWithNameObject extends BaseAction {
wo.setMatchUnitLevelName(matchUnit.getLevelName());
wo.setMatchUnitName(matchUnit.getName());
wo.setMatchUnitLevel(matchUnit.getLevel());
wo.setMatchUnitOrder(matchUnit.getOrderNumber());
}
if (null != unit) {
wo.setUnit(unit.getDistinguishedName());
wo.setUnitOrder(unit.getOrderNumber());
}else{
wo.setUnit(identity.getUnit());
}
......
......@@ -35,12 +35,12 @@ class ActionCreate extends BaseAction {
}
emc.beginTransaction(View.class);
View view = Wi.copier.copy(wi);
switch (StringUtils.trimToEmpty(view.getType())) {
switch (StringUtils.trimToEmpty(wi.getType())) {
case View.TYPE_CMS:
view.setData(gson.toJson(gson.fromJson(view.getData(), CmsPlan.class)));
//view.setData(gson.toJson(gson.fromJson(view.getData(), CmsPlan.class)));
break;
case View.TYPE_PROCESSPLATFORM:
view.setData(gson.toJson(gson.fromJson(view.getData(), ProcessPlatformPlan.class)));
//view.setData(gson.toJson(gson.fromJson(view.getData(), ProcessPlatformPlan.class)));
break;
default:
throw new ExceptionTypeValue(wi.getType());
......@@ -75,4 +75,4 @@ class ActionCreate extends BaseAction {
}
}
\ No newline at end of file
}
......@@ -37,13 +37,12 @@ class ActionEdit extends BaseAction {
if (!business.editable(effectivePerson, query)) {
throw new ExceptionQueryAccessDenied(effectivePerson.getDistinguishedName(), query.getName());
}
Wi.copier.copy(wi, view);
switch (StringUtils.trimToEmpty(view.getType())) {
switch (StringUtils.trimToEmpty(wi.getType())) {
case View.TYPE_CMS:
view.setData(gson.toJson(gson.fromJson(view.getData(), CmsPlan.class)));
//view.setData(gson.toJson(gson.fromJson(view.getData(), CmsPlan.class)));
break;
case View.TYPE_PROCESSPLATFORM:
view.setData(gson.toJson(gson.fromJson(view.getData(), ProcessPlatformPlan.class)));
//view.setData(gson.toJson(gson.fromJson(view.getData(), ProcessPlatformPlan.class)));
break;
default:
throw new ExceptionTypeValue(wi.getType());
......@@ -77,4 +76,4 @@ class ActionEdit extends BaseAction {
static WrapCopier<Wi, View> copier = WrapCopierFactory.wi(Wi.class, View.class, null, JpaObject.FieldsUnmodify);
}
}
\ No newline at end of file
}
......@@ -49,6 +49,8 @@ public class FilterEntry extends GsonPropertyObject {
public static final String DEFINE_UNITALLLIST = "@unitAllList";
public static final String WILDCARD = "*";
/** 用于customFilterEntry */
public String title;
......@@ -137,31 +139,31 @@ public class FilterEntry extends GsonPropertyObject {
p = cb.and(p, cb.equal(root.get(Item_.path0), paths[0]));
}
if ((paths.length > 1) && StringUtils.isNotEmpty(paths[1])) {
if ((paths.length > 1) && StringUtils.isNotEmpty(paths[1]) && !WILDCARD.equals(paths[1])) {
p = cb.and(p, cb.equal(root.get(Item_.path1), paths[1]));
}
if ((paths.length > 2) && StringUtils.isNotEmpty(paths[2])) {
if ((paths.length > 2) && StringUtils.isNotEmpty(paths[2]) && !WILDCARD.equals(paths[2])) {
p = cb.and(p, cb.equal(root.get(Item_.path2), paths[2]));
}
if ((paths.length > 3) && StringUtils.isNotEmpty(paths[3])) {
if ((paths.length > 3) && StringUtils.isNotEmpty(paths[3]) && !WILDCARD.equals(paths[3])) {
p = cb.and(p, cb.equal(root.get(Item_.path3), paths[3]));
}
if ((paths.length > 4) && StringUtils.isNotEmpty(paths[4])) {
if ((paths.length > 4) && StringUtils.isNotEmpty(paths[4]) && !WILDCARD.equals(paths[4])) {
p = cb.and(p, cb.equal(root.get(Item_.path4), paths[4]));
}
if ((paths.length > 5) && StringUtils.isNotEmpty(paths[5])) {
if ((paths.length > 5) && StringUtils.isNotEmpty(paths[5]) && !WILDCARD.equals(paths[5])) {
p = cb.and(p, cb.equal(root.get(Item_.path5), paths[5]));
}
if ((paths.length > 6) && StringUtils.isNotEmpty(paths[6])) {
if ((paths.length > 6) && StringUtils.isNotEmpty(paths[6]) && !WILDCARD.equals(paths[6])) {
p = cb.and(p, cb.equal(root.get(Item_.path6), paths[6]));
}
if ((paths.length > 7) && StringUtils.isNotEmpty(paths[7])) {
if ((paths.length > 7) && StringUtils.isNotEmpty(paths[7]) && !WILDCARD.equals(paths[7])) {
p = cb.and(p, cb.equal(root.get(Item_.path7), paths[7]));
}
......@@ -993,4 +995,4 @@ public class FilterEntry extends GsonPropertyObject {
return p;
}
}
\ No newline at end of file
}
package com.x.query.core.express.plan;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
......@@ -13,10 +9,7 @@ import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.*;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
......@@ -89,7 +82,7 @@ public abstract class Plan extends GsonPropertyObject {
/**
* !!这个类最后要输出.不能gson scriptEngine对象
*
*
*/
private transient ScriptEngine scriptEngine;
......@@ -135,6 +128,8 @@ public abstract class Plan extends GsonPropertyObject {
comp = -1;
} else if (null == o2) {
comp = 1;
} else if (o1 instanceof Collection<?> || o2 instanceof Collection<?>) {
comp = 0;
} else {
if (o1.getClass() == o2.getClass()) {
c1 = (Comparable) o1;
......@@ -456,43 +451,72 @@ public abstract class Plan extends GsonPropertyObject {
Root<Item> root = cq.from(Item.class);
Predicate p = cb.isMember(root.get(Item_.bundle), cb.literal(bundles));
String[] paths = StringUtils.split(selectEntry.path, ".");
List<Order> orderList = new ArrayList<>();
if ((paths.length > 0) && StringUtils.isNotEmpty(paths[0])) {
p = cb.and(p, cb.equal(root.get(Item_.path0), paths[0]));
} else {
p = cb.and(p, cb.or(cb.isNull(root.get(Item_.path0)), cb.equal(root.get(Item_.path0), "")));
}
if ((paths.length > 1) && StringUtils.isNotEmpty(paths[1])) {
p = cb.and(p, cb.equal(root.get(Item_.path1), paths[1]));
if(!FilterEntry.WILDCARD.equals(paths[1])) {
p = cb.and(p, cb.equal(root.get(Item_.path1), paths[1]));
}else{
orderList.add(cb.asc(root.get(Item_.path1)));
}
} else {
p = cb.and(p, cb.or(cb.isNull(root.get(Item_.path1)), cb.equal(root.get(Item_.path1), "")));
}
if ((paths.length > 2) && StringUtils.isNotEmpty(paths[2])) {
p = cb.and(p, cb.equal(root.get(Item_.path2), paths[2]));
if(!FilterEntry.WILDCARD.equals(paths[2])) {
p = cb.and(p, cb.equal(root.get(Item_.path2), paths[2]));
}else{
orderList.add(cb.asc(root.get(Item_.path2)));
}
} else {
p = cb.and(p, cb.or(cb.isNull(root.get(Item_.path2)), cb.equal(root.get(Item_.path2), "")));
}
if ((paths.length > 3) && StringUtils.isNotEmpty(paths[3])) {
p = cb.and(p, cb.equal(root.get(Item_.path3), paths[3]));
if(!FilterEntry.WILDCARD.equals(paths[3])) {
p = cb.and(p, cb.equal(root.get(Item_.path3), paths[3]));
}else{
orderList.add(cb.asc(root.get(Item_.path3)));
}
} else {
p = cb.and(p, cb.or(cb.isNull(root.get(Item_.path3)), cb.equal(root.get(Item_.path3), "")));
}
if ((paths.length > 4) && StringUtils.isNotEmpty(paths[4])) {
p = cb.and(p, cb.equal(root.get(Item_.path4), paths[4]));
if(!FilterEntry.WILDCARD.equals(paths[4])) {
p = cb.and(p, cb.equal(root.get(Item_.path4), paths[4]));
}else{
orderList.add(cb.asc(root.get(Item_.path4)));
}
} else {
p = cb.and(p, cb.or(cb.isNull(root.get(Item_.path4)), cb.equal(root.get(Item_.path4), "")));
}
if ((paths.length > 5) && StringUtils.isNotEmpty(paths[5])) {
p = cb.and(p, cb.equal(root.get(Item_.path5), paths[5]));
if(!FilterEntry.WILDCARD.equals(paths[5])) {
p = cb.and(p, cb.equal(root.get(Item_.path5), paths[5]));
}else{
orderList.add(cb.asc(root.get(Item_.path5)));
}
} else {
p = cb.and(p, cb.or(cb.isNull(root.get(Item_.path5)), cb.equal(root.get(Item_.path5), "")));
}
if ((paths.length > 6) && StringUtils.isNotEmpty(paths[6])) {
p = cb.and(p, cb.equal(root.get(Item_.path6), paths[6]));
if(!FilterEntry.WILDCARD.equals(paths[6])) {
p = cb.and(p, cb.equal(root.get(Item_.path6), paths[6]));
}else{
orderList.add(cb.asc(root.get(Item_.path6)));
}
} else {
p = cb.and(p, cb.or(cb.isNull(root.get(Item_.path6)), cb.equal(root.get(Item_.path6), "")));
}
if ((paths.length > 7) && StringUtils.isNotEmpty(paths[7])) {
p = cb.and(p, cb.equal(root.get(Item_.path7), paths[7]));
if(!FilterEntry.WILDCARD.equals(paths[7])) {
p = cb.and(p, cb.equal(root.get(Item_.path7), paths[7]));
}else{
orderList.add(cb.asc(root.get(Item_.path7)));
}
} else {
p = cb.and(p, cb.or(cb.isNull(root.get(Item_.path7)), cb.equal(root.get(Item_.path7), "")));
}
......@@ -500,6 +524,11 @@ public abstract class Plan extends GsonPropertyObject {
root.get(Item_.itemStringValueType), root.get(Item_.stringShortValue),
root.get(Item_.stringLongValue), root.get(Item_.dateValue), root.get(Item_.timeValue),
root.get(Item_.dateTimeValue), root.get(Item_.booleanValue), root.get(Item_.numberValue)).where(p);
boolean isList = false;
if(!orderList.isEmpty()){
isList = true;
cq.orderBy(orderList);
}
List<Tuple> list = em.createQuery(cq).getResultList();
Row row = null;
for (Tuple o : list) {
......@@ -510,25 +539,25 @@ public abstract class Plan extends GsonPropertyObject {
case s:
if (null != o.get(3)) {
if ((null != o.get(4)) && StringUtils.isNotEmpty(Objects.toString(o.get(4)))) {
row.put(selectEntry.getColumn(), Objects.toString(o.get(4)));
row.put(selectEntry.getColumn(), Objects.toString(o.get(4)), isList);
} else {
row.put(selectEntry.getColumn(), Objects.toString(o.get(3)));
row.put(selectEntry.getColumn(), Objects.toString(o.get(3)), isList);
}
}
break;
case d:
if (null != o.get(5)) {
row.put(selectEntry.getColumn(), JpaObjectTools.confirm((Date) o.get(5)));
row.put(selectEntry.getColumn(), JpaObjectTools.confirm((Date) o.get(5)), isList);
}
break;
case t:
if (null != o.get(6)) {
row.put(selectEntry.getColumn(), JpaObjectTools.confirm((Date) o.get(6)));
row.put(selectEntry.getColumn(), JpaObjectTools.confirm((Date) o.get(6)), isList);
}
break;
case dt:
if (null != o.get(7)) {
row.put(selectEntry.getColumn(), JpaObjectTools.confirm((Date) o.get(7)));
row.put(selectEntry.getColumn(), JpaObjectTools.confirm((Date) o.get(7)), isList);
}
break;
default:
......@@ -537,12 +566,12 @@ public abstract class Plan extends GsonPropertyObject {
break;
case b:
if (null != o.get(8)) {
row.put(selectEntry.getColumn(), (Boolean) o.get(8));
row.put(selectEntry.getColumn(), (Boolean) o.get(8), isList);
}
break;
case n:
if (null != o.get(9)) {
row.put(selectEntry.getColumn(), (Number) o.get(9));
row.put(selectEntry.getColumn(), (Number) o.get(9), isList);
}
break;
default:
......
package com.x.query.core.express.plan;
import java.util.List;
import java.util.Objects;
import java.util.TreeMap;
import com.x.base.core.project.tools.ListTools;
import org.apache.commons.lang3.math.NumberUtils;
import com.x.base.core.project.gson.GsonPropertyObject;
......@@ -26,6 +28,23 @@ public class Row extends GsonPropertyObject {
this.data.put(key, value);
}
public void put(String key, Object value, boolean isList) {
if (isList) {
Object o = this.data.get(key);
if (o != null) {
if (o instanceof List<?>) {
((List) o).add(value);
} else {
this.data.put(key, ListTools.toList(value));
}
} else {
this.data.put(key, ListTools.toList(value));
}
}else{
this.data.put(key, value);
}
}
/** 统计计算时用于转换值,不可转换的值默认为0 */
public Double getAsDouble(String key) {
Object o = this.data.get(key);
......@@ -37,4 +56,4 @@ public class Row extends GsonPropertyObject {
}
}
}
\ No newline at end of file
}
......@@ -20,7 +20,8 @@
"include": [ //需要抽取文档的源文件夹
"./o2web/source/x_component_process_Xform",
"./o2web/source/x_component_cms_Xform",
"./o2web/source/o2_core/o2/xScript"
"./o2web/source/o2_core/o2/xScript",
"./o2web/source/x_desktop/js/o2m.api.js"
],
"includePattern": ".+\\.js(doc|x)?$", //抽取的源文件名称正则表达式
"excludePattern": "(^|\\/|\\\\)_" //排除的源文件正则表达式
......@@ -41,7 +42,9 @@
}
},
"metadata": {
"title": "O2OA前台API" //最终生成的文档中标题
"title": "O2OA前台API", //最终生成的文档中标题
"title_prefix" : "O2OA WebAPI", //html title标题前缀
"title_suffix" : " | O2OA开发平台" //标题后缀
},
"o2" : {
"actionOutPath" : "./o2server/{actionRoot}/src/main/webapp/describe/jsdoc/{actionName}.json",
......
......@@ -41,9 +41,9 @@
<td><a href="module-session.html">当前用户 - session</a></td>
</tr>
<tr>
<td><a href="module-o2m.html">平台移动APP API - o2m</a></td>
<td><a href="module-wait.html">表单等待 - wait</a></td>
<td></td>
<td></td>
</tr>
</table>
......
......@@ -50,5 +50,10 @@
"readline-sync": "^1.4.10",
"gulp-cli": "^2.3.0",
"gulp-git": "^2.10.1"
},
"dependencies": {
"gulp-cli": "^2.3.0",
"jsdoc": "^3.6.6",
"tidy-jsdoc-o2": "0.0.8"
}
}
}
\ No newline at end of file
......@@ -77,7 +77,7 @@ if (!window.Promise){
}
this.o2 = window.o2 || {};
this.o2.version = {
"v": "5.1.1",
"v": "5.4.1",
"build": "2020.06.12",
"info": "O2OA 活力办公 创意无限. Copyright © 2020, o2oa.net O2 Team All rights reserved."
};
......
......@@ -1040,33 +1040,34 @@ o2.xDesktop.Default.StartMenu = new Class({
}
},
searchApplicatins: function(value){
var user = this.layout.session.user;
var currentNames = [user.name, user.distinguishedName, user.id, user.unique];
if (user.roleList) currentNames = currentNames.concat(user.roleList);
if (user.groupList) currentNames = currentNames.concat(user.groupList);
if (this.layoutJson && this.layoutJson.length) this.layoutJson.each(function(v){
if ( this.checkMenuItem(v, currentNames) ){
if ((v.title.toPYFirst().toLowerCase().indexOf(value)!==-1) || (v.title.toPY().toLowerCase().indexOf(value)!==-1) || (v.title.indexOf(value)!==-1)){
this.createApplicationMenuItem(v);
// var user = this.layout.session.user;
// // var currentNames = [user.name, user.distinguishedName, user.id, user.unique];
// // if (user.roleList) currentNames = currentNames.concat(user.roleList);
// // if (user.groupList) currentNames = currentNames.concat(user.groupList);
this.getCurrentName( function (currentNames) {
if (this.layoutJson && this.layoutJson.length) this.layoutJson.each(function(v){
if ( this.checkMenuItem(v, currentNames) ){
if ((v.title.toPYFirst().toLowerCase().indexOf(value)!==-1) || (v.title.toPY().toLowerCase().indexOf(value)!==-1) || (v.title.indexOf(value)!==-1)){
this.createApplicationMenuItem(v);
}
}
}
}.bind(this));
}.bind(this));
if (this.componentJson && this.componentJson.length) this.componentJson.each(function(v){
if ( this.checkMenuItem(v, currentNames) ){
if ((v.title.toPYFirst().toLowerCase().indexOf(value)!==-1) || (v.title.toPY().toLowerCase().indexOf(value)!==-1) || (v.title.indexOf(value)!==-1)){
this.createApplicationMenuItem(v);
if (this.componentJson && this.componentJson.length) this.componentJson.each(function(v){
if ( this.checkMenuItem(v, currentNames) ){
if ((v.title.toPYFirst().toLowerCase().indexOf(value)!==-1) || (v.title.toPY().toLowerCase().indexOf(value)!==-1) || (v.title.indexOf(value)!==-1)){
this.createApplicationMenuItem(v);
}
}
}
}.bind(this));
if (this.portalJson && this.portalJson.length) this.portalJson.each(function(v){
if ((v.name.toPYFirst().toLowerCase().indexOf(value)!==-1) || (v.name.toPY().toLowerCase().indexOf(value)!==-1) || (v.name.indexOf(value)!==-1)){
this.createPortalMenuItem(v);
}
}.bind(this));
}.bind(this));
if (this.portalJson && this.portalJson.length) this.portalJson.each(function(v){
if ((v.name.toPYFirst().toLowerCase().indexOf(value)!==-1) || (v.name.toPY().toLowerCase().indexOf(value)!==-1) || (v.name.indexOf(value)!==-1)){
this.createPortalMenuItem(v);
}
}.bind(this));
})
},
searchProcesses: function(value){
if (this.processJson && this.processJson.length) this.processJson.each(function(v){
......@@ -1268,17 +1269,20 @@ o2.xDesktop.Default.StartMenu = new Class({
this.createPortalMenuItem(appData);
}
}
}
}.bind(this));
}
if (json_layout && json_layout.length) json_layout.each(function(value){
if ( this.checkMenuItem(value, currentNames) ) this.createApplicationMenuItem(value);
}.bind(this));
}
if (json_layout && json_layout.length) json_layout.each(function(value){
if ( this.checkMenuItem(value, currentNames) ) this.createApplicationMenuItem(value);
}.bind(this));
if (json_component && json_component.length) json_component.each(function(value){
if ( this.checkMenuItem(value, currentNames) ) this.createApplicationMenuItem(value);
}.bind(this));
if (json_component && json_component.length) json_component.each(function(value){
if ( this.checkMenuItem(value, currentNames) ) this.createApplicationMenuItem(value);
}.bind(this));
if (json_portal && json_portal.length) json_portal.each(function(value){
this.createPortalMenuItem(value);
}.bind(this));
if (json_portal && json_portal.length) json_portal.each(function(value){
value.type = "portal";
......
......@@ -5,6 +5,8 @@ MWF.xApplication.cms.Xform.Htmleditor = MWF.CMSHtmleditor = new Class({
_loadUserInterface: function(){
this.node.empty();
if (this.readonly){
// var html = this.parseImage( this._getBusinessData() );
// this.node.set("html", html);
this.node.set("html", this._getBusinessData());
this.node.setStyles({
"-webkit-user-select": "text",
......@@ -32,8 +34,31 @@ MWF.xApplication.cms.Xform.Htmleditor = MWF.CMSHtmleditor = new Class({
this.loadCkeditor(config);
}
// this._loadValue();
},
// parseImage : function( html ){
// html = ( html || "" ).replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi, function (img, capture) {
// if( img.indexOf( "data-id" ) > -1 && img.indexOf("setImageSrc()") > -1 ){
// var ids = img.match( /(?<=data-id=").*?(?=")/g );
// if( ids && ids.length > 0 ){
// var newSrc = MWF.xDesktop.getImageSrc( ids[0] );
// var newImg = this.replaceAttr( img, "img", "src", newSrc );
// return newImg;
// }
// }
// return img;
// }.bind(this));
// return html
// },
// replaceAttr: function(src_str, tag, attr, val) {
// if(src_str.indexOf(attr) > 0) {
// //包含attr属性,替换attr
// var sub_reg = new RegExp(attr + '=[\'\"]([^"]*)[\'\"]', 'gi');
// return src_str.replace(sub_reg, attr +'=' + val);
// }else{
// //不包含attr属性,添加attr
// return src_str.substr(0, tag.length + 1) + ' ' + attr + '=' + val + ' ' + src_str.substr(tag.length + 2, src_str.length);
// }
// },
loadCkeditor: function(config){
_self = this;
COMMON.AjaxModule.loadDom("ckeditor", function(){
......
......@@ -106,6 +106,9 @@
<div class="MWFFormulaArea" name="defaultValue" title="默认值脚本 (S)"></div>
<div style="height: 28px; font-weight: bold; line-height:28px; background-color: #EEE; padding: 0px 6px; border-top: 1px solid #999">显示文本:</div>
<div class="MWFFormulaArea" name="displayTextScript" title="显示文本脚本 (S)"></div>
<div class="MWFValidation" name="validationConfig"></div>
<div class="MWFScriptArea" name="validation" title="校验脚本 (S)"></div>
......
......@@ -175,11 +175,15 @@ MWF.xApplication.portal.Portal.Main = new Class({
var check = function(){
if (!!pageJson && loadModuleFlag){
this.pageJson = pageJson;
layout.sessionPromise.then(function(){
if (layout.session && layout.session.user){
this.openPage(pageJson, par, callback);
}.bind(this), function(){
this.openPage(pageJson, par, callback);
}.bind(this));
}else if( layout.sessionPromise ){
layout.sessionPromise.then(function () {
this.openPage(pageJson, par, callback);
}.bind(this), function () {
this.openPage(pageJson, par, callback);
}.bind(this));
}
}
}.bind(this);
......
......@@ -28,6 +28,13 @@
<input class="editTableRadio" name="isShow" text{($.isShow==false)?'checked':''} type="radio" value="false"/>隐藏该列 <br/>
</td>
</tr>
<tr>
<td class="editTableTitle">导入导出:</td>
<td class="editTableValue">
<input class="editTableRadio" name="isImpExp" text{($.isImpExp!==false)?'checked':''} type="radio" value="true"/>允许 <br/>
<input class="editTableRadio" name="isImpExp" text{($.isImpExp==false)?'checked':''} type="radio" value="false"/>不允许 <br/>
</td>
</tr>
</table>
<div class="MWFMaplist" name="styles" title="样式"></div>
......
......@@ -60,6 +60,57 @@
</table>
<div class="MWFScriptArea" name="editableScript" title="是否可编辑(S)"></div>
<div style="height:24px; text-align: center; line-height: 24px; background-color: #EEE; border-top: 1px solid #999;">导出导入</div>
<table width="100%" border="0" cellpadding="5" cellspacing="0" class="editTable">
<tr>
<td class="editTableTitle">启用:</td>
<td class="editTableValue">
<input type="radio" name="impexpType" value="none" text{(!$.impexpType || $.impexpType==='none')?'checked':''}
onclick="if (this.checked){ $('text{$.pid}impexpArea').setStyle('display', 'none')}" />禁用
<input type="radio" name="impexpType" value="impexp" text{($.impexpType==='impexp')?'checked':''}
onclick="if (this.checked){ $('text{$.pid}impexpArea').setStyle('display', 'block')}" />导出导入
<input type="radio" name="impexpType" value="exp" text{($.impexpType==='exp')?'checked':''}
onclick="if (this.checked){ $('text{$.pid}impexpArea').setStyle('display', 'block')}" />仅导出
<input type="radio" name="impexpType" value="imp" text{($.impexpType==='imp')?'checked':''}
onclick="if (this.checked){ $('text{$.pid}impexpArea').setStyle('display', 'block')}" />仅导入
</td>
</tr>
</table>
<div id="text{$.pid}impexpArea" style="display: text{($.impexpType && $.impexpType!=='none')?'block':'none'};">
<table width="100%" border="0" cellpadding="5" cellspacing="0" class="editTable">
<tr>
<td class="editTableTitle"></td>
<td class="editTableValue">
注:序号、图片、附件和隐藏列不能导入导出。
</td>
</tr>
<tr>
<td class="editTableTitle">按钮位置:</td>
<td class="editTableValue">
<input type="radio" name="impexpPosition" value="leftTop" text{(!$.impexpPosition || $.impexpPosition==='leftTop')?'checked':''}/>左上
<input type="radio" name="impexpPosition" value="centerTop" text{($.impexpPosition==='centerTop')?'checked':''}/>中上
<input type="radio" name="impexpPosition" value="rightTop" text{($.impexpPosition==='rightTop')?'checked':''}/>右上
<input type="radio" name="impexpPosition" value="leftBottom" text{($.impexpPosition==='leftBottom')?'checked':''}/>左下
<input type="radio" name="impexpPosition" value="centerBottom" text{($.impexpPosition==='centerBottom')?'checked':''}/>中下
<input type="radio" name="impexpPosition" value="rightBottom" text{($.impexpPosition==='rightBottom')?'checked':''}/>右下
</td>
</tr>
<tr>
<td class="editTableTitle">导入按钮文本:</td>
<td class="editTableValue"><input type="text" name="importActionText" value="text{$.importActionText || '导入Excel'}" class="editTableInput"/></td>
</tr>
</table>
<div class="MWFMaplist" name="importActionStyles" collapse="true" title="导入按钮样式"></div>
<table width="100%" border="0" cellpadding="5" cellspacing="0" class="editTable">
<tr>
<td class="editTableTitle">导出按钮文本:</td>
<td class="editTableValue"><input type="text" name="exportActionText" value="text{$.exportActionText || '导出Excel'}" class="editTableInput"/></td>
</tr>
</table>
<div class="MWFMaplist" name="exportActionStyles" collapse="true" title="导出按钮样式"></div>
<div class="MWFFormulaArea" name="excelName" title="导出文件名称"></div>
</div>
<div class="MWFValidation" name="validationConfig"></div>
<div class="MWFScriptArea" name="validation" title="校验脚本 (S)"></div>
</div>
......
......@@ -6,6 +6,8 @@
"sequence": "yes",
"section": "no",
"sectionBy": "person",
"importActionText" : "导入Excel",
"exportActionText" : "导出Excel",
"sectionByScript": {
"code": "",
"html": ""
......@@ -51,6 +53,14 @@
"code": "",
"html": ""
},
"export": {
"code": "",
"html": ""
},
"import": {
"code": "",
"html": ""
},
"click": {
"code": "",
"html": ""
......
......@@ -269,6 +269,30 @@
"font-weight": "bold",
"border-bottom": "0px solid #DCDFE6"
},
"importActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"exportActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"properties": {
"border": "0",
"cellpadding": "3",
......
......@@ -244,6 +244,30 @@
"font-weight": "bold",
"border-bottom": "0px solid #cccccc"
},
"importActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"exportActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"properties": {
"border": "0",
"cellpadding": "3",
......
......@@ -252,6 +252,30 @@
"font-weight": "bold",
"border-bottom": "0px solid #cccccc"
},
"importActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"exportActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"properties": {
"border": "0",
"cellpadding": "3",
......
......@@ -249,6 +249,30 @@
"font-weight": "bold",
"border-bottom": "0px solid #cccccc"
},
"importActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"exportActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"properties": {
"width": "100%",
"border": "0",
......
......@@ -232,6 +232,30 @@
"font-weight": "bold",
"border-bottom": "0px solid #cccccc"
},
"importActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"exportActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"properties": {
"border": "0",
"cellpadding": "5",
......
......@@ -302,6 +302,30 @@
"margin-bottom" : "10px",
"margin-top" : "10px"
},
"importActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"exportActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"properties": {
"width": "100%",
"border": "0",
......
......@@ -126,6 +126,8 @@
"editStyles": {},
"amountStyles": {},
"itemTitleStyles": {},
"importActionStyles" : {},
"exportActionStyles" : {},
"properties": {}
},
"datagrid$Title": {
......
......@@ -264,6 +264,30 @@
"font-weight": "bold",
"border-bottom": "0px solid #cccccc"
},
"importActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"exportActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"properties": {
"width": "90%",
"border": "0",
......
......@@ -244,6 +244,30 @@
"font-weight": "bold",
"border-bottom": "0px solid #cccccc"
},
"importActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"exportActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"properties": {
"width": "90%",
"border": "0",
......
......@@ -140,6 +140,12 @@ MWF.xApplication.process.FormDesigner.LP = {
"delete_title": "删除校验内容确认",
"delete_text": "您确定要删除此项校验码?"
},
"datagrid" : {
"import" : "导入",
"export" : "导出"
},
"selectIcon": "选择图标",
"selectImage": "选择图片",
"selectApplication" : "选择应用",
......
......@@ -426,6 +426,33 @@
"border-radius": "5px",
"text-align": "center"
},
"gridImpExpAreaNode" : {
"display" : "block"
},
"gridImportActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"gridExportActionStyles" : {
"color" : "#777",
"border-radius": "5px",
"border": "1px solid #ccc",
"cursor": "pointer",
"height": "26px",
"float" : "left",
"line-height": "26px",
"padding": "0px 5px",
"background-color": "#efefef",
"margin" : "5px"
},
"mobileGridHelpNode": {
"width": "30px",
"height": "30px",
......
......@@ -1710,7 +1710,7 @@ MWF.xApplication.process.Xform.Attachment = MWF.APPAttachment = new Class(
*/
setData: function(data){
this.attachmentController.clear();
data.each(function (att) {
( data || [] ).each(function (att) {
var attachment = this.form.businessData.attachmentList.find(function(a){
return a.id==att.id;
});
......
......@@ -108,12 +108,15 @@ MWF.xApplication.process.Xform.Checkbox = MWF.APPCheckbox = new Class(
this.node.empty();
this.setOptions();
},
/**
* @summary 获取选择项数组.
* @example
* var array = this.form.get('fieldId').getOptions();
* @return {Array} 选择项数组,如果配置为脚本返回计算结果.
*/
/**
* @summary 获取选择项。
* @return {Array} 返回选择项数组,如果使用选择项脚本,根据脚本返回决定,如:<pre><code class='language-js'>[
* "女|female",
* "男|male"
* ]</code></pre>
* @example
* this.form.get('fieldId').getOptions();
*/
getOptions: function(){
if (this.json.itemType == "values"){
return this.json.itemValues;
......@@ -123,6 +126,29 @@ MWF.xApplication.process.Xform.Checkbox = MWF.APPCheckbox = new Class(
//return [];
},
/**
* @summary 获取整理后的选择项。
* @return {Object} 返回整理后的选择项,如:
* <pre><code class='language-js'>{"valueList": ["","female","male"], "textList": ["","女","男"]}
* </code></pre>
* @example
* var optionData = this.form.get('fieldId').getOptionsObj();
*/
getOptionsObj : function(){
var textList = [];
var valueList = [];
var optionItems = this.getOptions();
if (!optionItems) optionItems = [];
if (o2.typeOf(optionItems)==="array"){
optionItems.each(function(item){
var tmps = item.split("|");
textList.push( tmps[0] );
valueList.push( tmps[1] || tmps[0] );
}.bind(this));
}
return { textList : textList, valueList : valueList };
},
setOptions: function(){
var optionItems = this.getOptions();
this._setOptions(optionItems);
......
......@@ -66,7 +66,9 @@ MWF.xApplication.process.Xform.DatagridMobile = new Class(
this.editable = (!this.readonly);
if (this.editable) this.editable = this.form.Macro.exec(((this.json.editableScript) ? this.json.editableScript.code : ""), this);
if (this.editable && this.json.editableScript && this.json.editableScript.code){
this.editable = this.form.Macro.exec(((this.json.editableScript) ? this.json.editableScript.code : ""), this);
}
//this.editable = false;
this.deleteable = this.json.deleteable !== "no";
......
......@@ -185,25 +185,31 @@ MWF.xApplication.process.Xform.Log = MWF.APPLog = new Class(
if (this.isNumber(value1) && this.isNumber(value2)) {
if (parseFloat(value1) !== parseFloat(value2)) {
return parseFloat(value1) - parseFloat(value2);
}else{
if( this.json.sortTypeInCategory === "none" ){
return 0;
}else{
return Date.parse(a.recordTime) - Date.parse(b.recordTime);
}
}
} else if (!this.isNumber(value1) && !this.isNumber(value2)) {
if( this.json.sortTypeInCategory === "none" ){
return -1;
return 0;
}else{
return Date.parse(a.fromTime) - Date.parse(b.fromTime);
return Date.parse(a.recordTime) - Date.parse(b.recordTime);
}
} else {
return this.isNumber(value1) ? -1 : 1;
}
}
return Date.parse(a.fromTime) - Date.parse(b.fromTime);
return Date.parse(a.recordTime) - Date.parse(b.recordTime);
}else if( a.properties.fromOpinionGroup || b.properties.fromOpinionGroup ){
return a.properties.fromOpinionGroup ? -1 : 1;
}else{
if( this.json.sortTypeInCategory === "none" ){
return -1;
return 0;
}else{
return Date.parse(a.fromTime) - Date.parse(b.fromTime);
return Date.parse(a.recordTime) - Date.parse(b.recordTime);
}
}
}.bind(this))
......@@ -800,10 +806,16 @@ MWF.xApplication.process.Xform.Log = MWF.APPLog = new Class(
if (this.isNumber(value1) && this.isNumber(value2)) {
if (parseFloat(value1) !== parseFloat(value2)) {
return parseFloat(value1) - parseFloat(value2);
}
}else{
if( this.json.sortTypeInCategory === "none" ){
return 0;
}else{
return Date.parse(a.fromTime) - Date.parse(b.fromTime);
}
}
} else if (!this.isNumber(value1) && !this.isNumber(value2)) {
if( this.json.sortTypeInCategory === "none" ){
return -1;
return 0;
}else{
return Date.parse(a.fromTime) - Date.parse(b.fromTime);
}
......@@ -816,7 +828,7 @@ MWF.xApplication.process.Xform.Log = MWF.APPLog = new Class(
return a.fromOpinionGroup ? -1 : 1;
}else{
if( this.json.sortTypeInCategory === "none" ){
return -1;
return 0;
}else{
return Date.parse(a.fromTime) - Date.parse(b.fromTime);
}
......
......@@ -126,12 +126,15 @@ MWF.xApplication.process.Xform.Radio = MWF.APPRadio = new Class(
this.node.empty();
this.setOptions();
},
/**
* @summary 获取选择项。
* @return {Array} 返回选择项数组,如果使用选择项脚本,根据脚本返回决定
* @example
* this.form.get('fieldId').getOptions();
*/
/**
* @summary 获取选择项。
* @return {Array} 返回选择项数组,如果使用选择项脚本,根据脚本返回决定,如:<pre><code class='language-js'>[
* "女|female",
* "男|male"
* ]</code></pre>
* @example
* this.form.get('fieldId').getOptions();
*/
getOptions: function(){
if (this.json.itemType == "values"){
return this.json.itemValues;
......@@ -140,6 +143,30 @@ MWF.xApplication.process.Xform.Radio = MWF.APPRadio = new Class(
}
return [];
},
/**
* @summary 获取整理后的选择项。
* @return {Object} 返回整理后的选择项,如:
* <pre><code class='language-js'>{"valueList": ["","female","male"], "textList": ["","女","男"]}
* </code></pre>
* @example
* var optionData = this.form.get('fieldId').getOptionsObj();
*/
getOptionsObj : function(){
var textList = [];
var valueList = [];
var optionItems = this.getOptions();
if (!optionItems) optionItems = [];
if (o2.typeOf(optionItems)==="array"){
optionItems.each(function(item){
var tmps = item.split("|");
textList.push( tmps[0] );
valueList.push( tmps[1] || tmps[0] );
}.bind(this));
}
return { textList : textList, valueList : valueList };
},
setOptions: function(){
var optionItems = this.getOptions();
this._setOptions(optionItems);
......@@ -362,6 +389,7 @@ MWF.xApplication.process.Xform.Radio = MWF.APPRadio = new Class(
resetData: function(){
this.setData(this.getValue());
},
/**
* @summary 获取选中的Dom对象。
* @return {Element} 返回选中的Dom对象
......
......@@ -158,7 +158,10 @@ MWF.xApplication.process.Xform.Select = MWF.APPSelect = new Class(
},
/**
* @summary 获取选择项。
* @return {Array} 返回选择项数组,如果使用选择项脚本,根据脚本返回决定
* @return {Array} 返回选择项数组,如果使用选择项脚本,根据脚本返回决定,如:<pre><code class='language-js'>[
* "女|female",
* "男|male"
* ]</code></pre>
* @example
* this.form.get('fieldId').getOptions();
*/
......@@ -170,6 +173,30 @@ MWF.xApplication.process.Xform.Select = MWF.APPSelect = new Class(
}
return [];
},
/**
* @summary 获取整理后的选择项。
* @return {Object} 返回整理后的选择项,如:
* <pre><code class='language-js'>{"valueList": ["","female","male"], "textList": ["","女","男"]}
* </code></pre>
* @example
* var optionData = this.form.get('fieldId').getOptionsObj();
*/
getOptionsObj : function(){
var textList = [];
var valueList = [];
var optionItems = this.getOptions();
if (!optionItems) optionItems = [];
if (o2.typeOf(optionItems)==="array"){
optionItems.each(function(item){
var tmps = item.split("|");
textList.push( tmps[0] );
valueList.push( tmps[1] || tmps[0] );
}.bind(this));
}
return { textList : textList, valueList : valueList };
},
setOptions: function(){
var optionItems = this.getOptions();
this._setOptions(optionItems);
......@@ -389,28 +416,6 @@ MWF.xApplication.process.Xform.Select = MWF.APPSelect = new Class(
this.setData(this.getValue());
},
/**
* @summary 获取整理后的选择项。
* @return {Object} 返回整理后的选择项,如:
* <pre><code class='language-js'>{"value": ["","female","male"], "text": ["","女","男"]}
* </code></pre>
* @example
* var optionData = this.form.get('fieldId').getOptionsObj();
*/
getOptionsObj : function(){
var textList = [];
var valueList = [];
var optionItems = this.getOptions();
if (!optionItems) optionItems = [];
if (o2.typeOf(optionItems)==="array"){
optionItems.each(function(item){
var tmps = item.split("|");
textList.push( tmps[0] );
valueList.push( tmps[1] || tmps[0] );
}.bind(this));
}
return { textList : textList, valueList : valueList };
},
setData: function(data){
return this._setValue(data, "__setData");
......
......@@ -8,6 +8,20 @@ MWF.xApplication.process.Xform.LP = {
"cancelDatagridLineEditTitle" : "取消编辑数据网格确认",
"cancelDatagridLineEdit" : "是否确定取消编辑数据网格?",
"datagridImport" : "导入Excel",
"datagridExport" : "导出Excel",
"exportDefaultName" : "数据网格",
"importSuccess" : "导入成功!",
"validationInfor" : "校验信息",
"importFail" : "导入失败",
"importValidationColumnText" : "第{n}列:",
"importValidationColumnTextExcel" : "列{n}:",
"notValidNumber" : "不是数字",
"notValidDate" : "不是日期格式",
"fullstop" : "",
"notExistInSystem" : "在系统中不存在",
"uploadedFilesCannotHaveSpaces" : "上传的文件不能带空格",
"browserNotActiveX": "您的浏览器不支持ActiveX控件,不能加载Office控件,请使用IE浏览器",
"activity": "活动",
......
......@@ -24,6 +24,7 @@
<script src="../o2_core/o2.min.js"></script>
<script src="../o2_lib/Decimal.js"></script>
<script src="js/base_portal.min.js"></script>
<script src="js/o2m.api.min.js"></script>
<script src="js/portal.min.js"></script>
<script>layout.mobile = true;</script>
</body>
......
......@@ -44,7 +44,7 @@
}.bind(this)
});
res.setHeader("Content-Type", "application/json; charset=utf-8");
var json = {"token": xtoken, "client": client};
var json = {"token": encodeURIComponent(xtoken), "client": client};
res.send(JSON.encode(json));
}else{
......
......@@ -32,7 +32,7 @@
<script src="../o2_core/o2.min.js"></script>
<script src="js/base_work.min.js"></script>
<script src="js/o2m.api.js"></script>
<script src="js/o2m.api.min.js"></script>
<script src="js/work.min.js"></script>
<script src="../o2_lib/Decimal.js"></script>
<script>layout.mobile = true;</script>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册