From 7bbee82e13efb0cd7119655ba63ebb5c409a0a2e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?REBUILD=20=E4=BC=81=E4=B8=9A=E7=AE=A1=E7=90=86=E7=B3=BB?=
=?UTF-8?q?=E7=BB=9F?= <42044143+getrebuild@users.noreply.github.com>
Date: Sat, 23 Aug 2025 14:09:12 +0800
Subject: [PATCH] Fix 4.1.5 (#948)
* Improve entity creation checks and logging
* Update @rbv
* 4.1.5
* BOOTING_TIME415
* Add includeHide parameter to picklist and multiselect methods
---
@rbv | 2 +-
pom.xml | 2 +-
.../java/com/rebuild/core/Application.java | 6 ++---
.../com/rebuild/core/BootApplication.java | 3 +++
.../configuration/general/FormsBuilder.java | 6 ++---
.../general/MultiSelectManager.java | 14 ++++++++---
.../general/PickListManager.java | 13 +++++++++--
.../core/privileges/PrivilegesManager.java | 5 +++-
.../core/privileges/bizz/CombinedRole.java | 23 ++++++++++++++-----
.../com/rebuild/web/admin/ProtectedAdmin.java | 2 +-
src/main/resources/application-bean.xml | 2 +-
.../resources/web/assets/js/rb-components.js | 4 +++-
12 files changed, 59 insertions(+), 23 deletions(-)
diff --git a/@rbv b/@rbv
index 41eb5c36a..d938751de 160000
--- a/@rbv
+++ b/@rbv
@@ -1 +1 @@
-Subproject commit 41eb5c36ae11dd4703a5969a3feef93dd25409d7
+Subproject commit d938751dea6125086bec9ea09bc95e9430475da6
diff --git a/pom.xml b/pom.xml
index 480ced4c7..50858e069 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
com.rebuild
rebuild
- 4.1.4
+ 4.1.5
rebuild
Building your business-systems freely!
https://getrebuild.com/
diff --git a/src/main/java/com/rebuild/core/Application.java b/src/main/java/com/rebuild/core/Application.java
index 46c80df20..4b97e9673 100644
--- a/src/main/java/com/rebuild/core/Application.java
+++ b/src/main/java/com/rebuild/core/Application.java
@@ -76,11 +76,11 @@ public class Application implements ApplicationListener
/**
* Rebuild Version
*/
- public static final String VER = "4.1.4";
+ public static final String VER = "4.1.5";
/**
* Rebuild Build [MAJOR]{1}[MINOR]{2}[PATCH]{2}[BUILD]{2}
*/
- public static final int BUILD = 4010409;
+ public static final int BUILD = 4010510;
static {
// Driver for DB
@@ -129,7 +129,7 @@ public class Application implements ApplicationListener
_CONTEXT = event.getApplicationContext();
- long time = System.currentTimeMillis();
+ long time = BootApplication.BOOTING_TIME415;
boolean started = false;
final Timer timer = new Timer("Boot-Timer");
diff --git a/src/main/java/com/rebuild/core/BootApplication.java b/src/main/java/com/rebuild/core/BootApplication.java
index c52274f6f..83f746dbb 100644
--- a/src/main/java/com/rebuild/core/BootApplication.java
+++ b/src/main/java/com/rebuild/core/BootApplication.java
@@ -62,6 +62,7 @@ public class BootApplication extends SpringBootServletInitializer {
private static String CONTEXT_PATH;
private static String TOMCAT_PORT;
+ protected static long BOOTING_TIME415 = System.currentTimeMillis();
/**
* 获取上下文地址,注意此地址尾部不含 `/`
@@ -107,6 +108,7 @@ public class BootApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
log.info("REBUILD starting ...");
+ BOOTING_TIME415 = System.currentTimeMillis();
if (devMode()) System.setProperty("spring.profiles.active", "dev");
// kill -15 `cat ~/.rebuild/rebuild.pid`
@@ -123,6 +125,7 @@ public class BootApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
log.info("REBUILD starting ...");
+ BOOTING_TIME415 = System.currentTimeMillis();
if (SystemUtils.IS_OS_WINDOWS) AnsiConsole.systemInstall();
if (devMode()) System.setProperty("spring.profiles.active", "dev");
diff --git a/src/main/java/com/rebuild/core/configuration/general/FormsBuilder.java b/src/main/java/com/rebuild/core/configuration/general/FormsBuilder.java
index b17e4a8e0..b228b0ffa 100644
--- a/src/main/java/com/rebuild/core/configuration/general/FormsBuilder.java
+++ b/src/main/java/com/rebuild/core/configuration/general/FormsBuilder.java
@@ -497,14 +497,14 @@ public class FormsBuilder extends FormsManager {
// 不同字段类型的处理
if (dt == DisplayType.PICKLIST) {
- JSONArray options = PickListManager.instance.getPickList(fieldMeta);
+ JSONArray options = PickListManager.instance.getPickList(fieldMeta, true);
field.put("options", options);
} else if (dt == DisplayType.STATE) {
JSONArray options = StateManager.instance.getStateOptions(fieldMeta);
field.put("options", options);
field.remove(EasyFieldConfigProps.STATE_CLASS);
} else if (dt == DisplayType.MULTISELECT) {
- JSONArray options = MultiSelectManager.instance.getSelectList(fieldMeta);
+ JSONArray options = MultiSelectManager.instance.getSelectList(fieldMeta, true);
field.put("options", options);
} else if (dt == DisplayType.TAG) {
field.put("options", ObjectUtils.defaultIfNull(field.remove("tagList"), JSONUtils.EMPTY_ARRAY));
@@ -525,7 +525,7 @@ public class FormsBuilder extends FormsManager {
} else if (dt == DisplayType.REFERENCE || dt == DisplayType.N2NREFERENCE) {
Entity refEntity = fieldMeta.getReferenceEntity();
boolean quickNew = field.getBooleanValue(EasyFieldConfigProps.REFERENCE_QUICKNEW);
- if (quickNew) {
+ if (quickNew && refEntity.isCreatable() && refEntity.getMainEntity() == null) {
field.put(EasyFieldConfigProps.REFERENCE_QUICKNEW,
Application.getPrivilegesManager().allowCreate(user, refEntity.getEntityCode()));
field.put("referenceEntity", EasyMetaFactory.toJSON(refEntity));
diff --git a/src/main/java/com/rebuild/core/configuration/general/MultiSelectManager.java b/src/main/java/com/rebuild/core/configuration/general/MultiSelectManager.java
index 0a67c4604..1470e5a93 100644
--- a/src/main/java/com/rebuild/core/configuration/general/MultiSelectManager.java
+++ b/src/main/java/com/rebuild/core/configuration/general/MultiSelectManager.java
@@ -27,15 +27,23 @@ public class MultiSelectManager extends PickListManager {
public static final MultiSelectManager instance = new MultiSelectManager();
- private MultiSelectManager() {
- }
+ private MultiSelectManager() {}
/**
* @param field
* @return
*/
public JSONArray getSelectList(Field field) {
- ConfigBean[] entries = getPickListRaw(field, true);
+ return getSelectList(field, false);
+ }
+
+ /**
+ * @param field
+ * @param includeHide
+ * @return
+ */
+ public JSONArray getSelectList(Field field, boolean includeHide) {
+ ConfigBean[] entries = getPickListRaw(field, includeHide);
for (ConfigBean e : entries) {
e.remove("id");
}
diff --git a/src/main/java/com/rebuild/core/configuration/general/PickListManager.java b/src/main/java/com/rebuild/core/configuration/general/PickListManager.java
index 5e9540d87..b67b7dbac 100644
--- a/src/main/java/com/rebuild/core/configuration/general/PickListManager.java
+++ b/src/main/java/com/rebuild/core/configuration/general/PickListManager.java
@@ -30,14 +30,23 @@ public class PickListManager implements ConfigManager {
public static final PickListManager instance = new PickListManager();
- protected PickListManager() { }
+ protected PickListManager() {}
/**
* @param field
* @return
*/
public JSONArray getPickList(Field field) {
- ConfigBean[] entries = getPickListRaw(field, true);
+ return getPickList(field, false);
+ }
+
+ /**
+ * @param field
+ * @param includeHide
+ * @return
+ */
+ public JSONArray getPickList(Field field, boolean includeHide) {
+ ConfigBean[] entries = getPickListRaw(field, includeHide);
for (ConfigBean e : entries) {
e.remove("mask");
}
diff --git a/src/main/java/com/rebuild/core/privileges/PrivilegesManager.java b/src/main/java/com/rebuild/core/privileges/PrivilegesManager.java
index 12dcd10c5..d711b696b 100644
--- a/src/main/java/com/rebuild/core/privileges/PrivilegesManager.java
+++ b/src/main/java/com/rebuild/core/privileges/PrivilegesManager.java
@@ -31,6 +31,7 @@ import com.rebuild.core.privileges.bizz.User;
import com.rebuild.core.privileges.bizz.ZeroEntry;
import com.rebuild.core.privileges.bizz.ZeroPrivileges;
import com.rebuild.core.service.NoRecordFoundException;
+import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
@@ -45,6 +46,7 @@ import java.text.MessageFormat;
* @see BizzDepthEntry
* @see CustomEntityPrivileges
*/
+@Slf4j
@Service
public class PrivilegesManager {
@@ -243,7 +245,8 @@ public class PrivilegesManager {
// 明细实体不能使用此方法检查创建权限
// 明细实体创建 = 主实体更新,因此应该检查主实体记录是否有更新权限
if (action == BizzPermission.CREATE) {
- throw new PrivilegesException("Unsupported checks detail-entity : " + entity);
+ log.warn("Unsupported checks detail-entity : {}", entity);
+ return false; // be:4.1.5
}
// 明细无分配/共享
else if (action == BizzPermission.ASSIGN || action == BizzPermission.SHARE) {
diff --git a/src/main/java/com/rebuild/core/privileges/bizz/CombinedRole.java b/src/main/java/com/rebuild/core/privileges/bizz/CombinedRole.java
index 9d3b03e40..6db2f2e4d 100644
--- a/src/main/java/com/rebuild/core/privileges/bizz/CombinedRole.java
+++ b/src/main/java/com/rebuild/core/privileges/bizz/CombinedRole.java
@@ -17,6 +17,8 @@ import cn.devezhao.persist4j.engine.ID;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import java.io.Serializable;
@@ -129,17 +131,25 @@ public class CombinedRole extends Role {
if (p instanceof ZeroPrivileges) continue;
System.out.println();
System.out.println("Combined Privileges : " + p.getIdentity());
- System.out.println("MAIN. " + roleMain.getPrivileges(p.getIdentity()));
+ System.out.println("MAIN. " + descPrivileges(roleMain.getPrivileges(p.getIdentity())));
for (Role ra : roleAppends) {
- System.out.println("APPE. " + ra.getPrivileges(p.getIdentity()));
+ System.out.println("APPE. " + descPrivileges(ra.getPrivileges(p.getIdentity())));
}
System.out.println("--");
- System.out.println("MERG. " + getPrivileges(p.getIdentity()));
+ System.out.println("MERG. " + descPrivileges(getPrivileges(p.getIdentity())));
}
System.out.println();
}
}
+ private String descPrivileges(Privileges p) {
+ String d = p.getIdentity().toString();
+ if (p instanceof CustomEntityPrivileges) {
+ d += "; FP:" + ObjectUtils.defaultIfNull(((CustomEntityPrivileges) p).getFpDefinition(), "N");
+ }
+ return d;
+ }
+
private Privileges mergePrivileges(Privileges a, Privileges b) {
if (b == null || b == Privileges.NONE) return a;
if (b == Privileges.ROOT) return b;
@@ -191,11 +201,12 @@ public class CombinedRole extends Role {
// 字段权限
- Map useFpDefinition;
Map aFpDefinition = ((CustomEntityPrivileges) a).getFpDefinition();
Map bFpDefinition = ((CustomEntityPrivileges) b).getFpDefinition();
- if (aFpDefinition == null || bFpDefinition == null) useFpDefinition = null;
- else useFpDefinition = aFpDefinition; // 无法比较字段权限高低,因此随便选一个
+ // be:4.1.5 无法比较字段权限高低,因此随便选一个非空的更合理
+ Map useFpDefinition = null;
+ if (MapUtils.isEmpty(aFpDefinition)) useFpDefinition = bFpDefinition;
+ else if (MapUtils.isEmpty(bFpDefinition)) useFpDefinition = aFpDefinition;
String definition = StringUtils.join(defs.iterator(), ",");
return new CustomEntityPrivileges(((EntityPrivileges) a).getEntity(), definition, useCustomFilters, useFpDefinition);
diff --git a/src/main/java/com/rebuild/web/admin/ProtectedAdmin.java b/src/main/java/com/rebuild/web/admin/ProtectedAdmin.java
index 7ce9e7909..a573afa69 100644
--- a/src/main/java/com/rebuild/web/admin/ProtectedAdmin.java
+++ b/src/main/java/com/rebuild/web/admin/ProtectedAdmin.java
@@ -97,7 +97,7 @@ public class ProtectedAdmin {
EXF("/extform", "外部表单"),
PRO("/project", "项目"),
FJS("/frontjs-code", "FrontJS"),
- USR("/bizuser/users;bizuser/departments", "部门用户"),
+ USR("/bizuser/users;/bizuser/departments", "部门用户"),
ROL("/bizuser/role-privileges;/bizuser/role", "角色权限"),
TEM("/bizuser/teams", "团队"),
LLG("/audit/login-logs", "登录日志"),
diff --git a/src/main/resources/application-bean.xml b/src/main/resources/application-bean.xml
index 179b33c48..48aa55c38 100644
--- a/src/main/resources/application-bean.xml
+++ b/src/main/resources/application-bean.xml
@@ -53,7 +53,7 @@
-
+
diff --git a/src/main/resources/web/assets/js/rb-components.js b/src/main/resources/web/assets/js/rb-components.js
index de43d65ec..7df87c1e5 100644
--- a/src/main/resources/web/assets/js/rb-components.js
+++ b/src/main/resources/web/assets/js/rb-components.js
@@ -1171,7 +1171,9 @@ class Md2Html extends React.Component {
md = md.replace(/>/g, '>').replace(/ ')
}
- let cHtml = marked.parse(md.replace(/\n/g, '
'))
+
+ // 替换换行并保持表格换行
+ let cHtml = marked.parse(md.replace(/(?