Fix 4.0.6 (#911)

* fix:表单回填 N2N>Ref

* fix: N2N 填值

* fix: 分类缓存

* fix:月的最大日

* 4.0.6

* Update @rbv
This commit is contained in:
REBUILD 企业管理系统 2025-06-18 20:25:57 +08:00 committed by GitHub
parent bbcf932dc6
commit 58590fd796
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 69 additions and 40 deletions

2
@rbv

@ -1 +1 @@
Subproject commit 6c98fdaf00ec81ce787d9adffb96b6e277a62bd0
Subproject commit be43ef7f6ac8376d713eb2cbb46db4672556cd52

View file

@ -10,7 +10,7 @@
</parent>
<groupId>com.rebuild</groupId>
<artifactId>rebuild</artifactId>
<version>4.0.5</version>
<version>4.0.6</version>
<name>rebuild</name>
<description>Building your business-systems freely!</description>
<url>https://getrebuild.com/</url>

View file

@ -76,11 +76,11 @@ public class Application implements ApplicationListener<ApplicationStartedEvent>
/**
* Rebuild Version
*/
public static final String VER = "4.0.5";
public static final String VER = "4.0.6";
/**
* Rebuild Build [MAJOR]{1}[MINOR]{2}[PATCH]{2}[BUILD]{2}
*/
public static final int BUILD = 4000512;
public static final int BUILD = 4000613;
static {
// Driver for DB

View file

@ -344,7 +344,7 @@ public class AutoFillinManager implements ConfigManager {
if (sourceEasyType == DisplayType.ID
&& (targetEasyType == DisplayType.REFERENCE || targetEasyType == DisplayType.N2NREFERENCE || targetEasyType == DisplayType.ANYREFERENCE)) {
newValue = FieldValueHelper.wrapFieldValue(newValue, targetEasy);
} else if (targetEasyType == DisplayType.N2NREFERENCE) {
} else if (targetEasyType == DisplayType.N2NREFERENCE || targetEasyType == DisplayType.REFERENCE) {
newValue = targetEasy.wrapValue(newValue);
} else if (sourceEasy instanceof MixValue) {
if (!(newValue instanceof String) || sourceEasyType == DisplayType.FILE) {

View file

@ -7,7 +7,6 @@ See LICENSE and COMMERCIAL in the project root for license information.
package com.rebuild.core.configuration.general;
import cn.devezhao.commons.ThreadPool;
import cn.devezhao.persist4j.PersistManagerFactory;
import cn.devezhao.persist4j.Record;
import cn.devezhao.persist4j.engine.ID;
@ -20,6 +19,7 @@ import com.rebuild.core.privileges.UserService;
import com.rebuild.core.service.DataSpecificationException;
import com.rebuild.core.service.general.QuickCodeReindexTask;
import com.rebuild.core.support.i18n.Language;
import com.rebuild.core.support.task.TaskExecutors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
@ -27,7 +27,7 @@ import org.springframework.stereotype.Service;
/**
* 分类数据
*
* @author devezhao zhaofang123@gmail.com
* @author devezhao
* @since 2019/04/10
*/
@Slf4j
@ -64,7 +64,7 @@ public class ClassificationService extends BaseConfigurationService implements A
ClassificationManager.instance.clean(cfgid);
}
// -- for DataItem
// -- for Item
/**
* @param record
@ -82,17 +82,11 @@ public class ClassificationService extends BaseConfigurationService implements A
if (reindex) {
final ID itemId = record.getPrimary();
cleanCache(itemId);
final long start = System.currentTimeMillis();
ThreadPool.exec(() -> {
try {
reindexFullNameByParent(itemId);
} finally {
long cost = System.currentTimeMillis() - start;
if (cost > 2000 || Application.devMode()) {
log.info("Reindex FullName [ {} ] in {} ms", itemId, cost);
}
}
});
// v4.1 延迟以便事物提交完成
TaskExecutors.schedule(() -> {
reindexFullNameByParent(itemId);
}, 1000);
}
return record;
}
@ -147,9 +141,7 @@ public class ClassificationService extends BaseConfigurationService implements A
"select dataId from ClassificationData where itemId = ?")
.setParameter(1, parent)
.unique();
if (data == null) {
return 0;
}
if (data == null) return 0;
return reindexFullNameByParent(parent, (ID) data[0]);
}

View file

@ -24,6 +24,7 @@ import com.rebuild.core.metadata.impl.EasyFieldConfigProps;
import com.rebuild.core.service.query.AdvFilterParser;
import com.rebuild.core.service.query.ParseHelper;
import com.rebuild.core.support.general.FieldValueHelper;
import com.rebuild.utils.CommonsUtils;
import com.rebuild.utils.JSONUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
@ -31,6 +32,7 @@ import org.apache.commons.lang.StringUtils;
import java.text.Collator;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
@ -299,6 +301,9 @@ public class DataListCategory38 {
s = s.substring(0, 10);
e = e.substring(0, 10);
}
// fix:月的做大日
int maxDayOfMonth = CalendarUtils.getInstance(CalendarUtils.parse(s)).getActualMaximum(Calendar.DAY_OF_MONTH);
if (maxDayOfMonth != 31) e = e.replace("-31", "-" + maxDayOfMonth);
String filter = MessageFormat.format("({0} >= ''{1}'' and {0} <= ''{2}'')", fieldName, s, e);
and.add(filter);

View file

@ -76,7 +76,8 @@ public class EasyN2NReference extends EasyReference implements MultiValue {
@Override
public Object wrapValue(Object value) {
ID[] idArrayValue = (ID[]) value;
// fix:4.0.6
ID[] idArrayValue = value instanceof ID ? new ID[]{(ID) value} : (ID[]) value;
JSONArray array = new JSONArray();
for (ID id : idArrayValue) {

View file

@ -28,7 +28,7 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
// !!!! 请勿对本文件做任何改动否则导致的一切损失由您自行承担
// !!!! 请勿对本文件做任何改动否则导致的一切风险/损失由您自行承担
// !!!! 请严格遵守REBUILD 用户服务协议https://getrebuild.com/legal/service-terms
@Slf4j
public final class License {
@ -54,7 +54,7 @@ public final class License {
SN = newsn.getString("sn");
if (SN != null) {
RebuildConfiguration.setValue(ConfigurationItem.SN.name(), SN);
queryAuthority(false);
queryAuthority(false); // reset
}
if (SN == null) {
@ -65,7 +65,7 @@ public final class License {
CalendarUtils.format("wwyy", new Date()),
CodecUtils.randomCode(6)).toUpperCase();
RebuildConfiguration.setValue(ConfigurationItem.SN.name(), SN);
queryAuthority(false);
queryAuthority(false); // reset
}
USE_SN = SN;
@ -77,14 +77,16 @@ public final class License {
}
private static JSONObject queryAuthority(boolean cached) {
final String api = "api/authority/query";
JSONObject auth = TaskExecutors.invoke(() -> {
if (cached) return siteApi("api/authority/query");
return siteApiNoCache("api/authority/query");
}, 10);
if (auth == null) {
if (cached) return siteApi(api);
return siteApiNoCache(api);
}, 10 * 1000);
if (auth == null || auth.getString("error") != null) {
try {
String ik = ComputerIdentifier.generateIdentifierKey();
String c = FileUtils.readFileToString(RebuildConfiguration.getFileOfData(".license"), "ISO-8859-1");
String ik = ComputerIdentifier.generateIdentifierKey();
log.warn("Use _LA : {},{}", c, ik);
auth = JSON.parseObject(AES.decrypt(c, ik));
} catch (Exception ignored) {}
@ -97,6 +99,8 @@ public final class License {
new String[]{SN(), "开源社区版", "OSC", ""});
}
if ("BLOCKED".equals(error)) System.exit(110);
CACHED.put(api, auth);
return auth;
}

View file

@ -22,8 +22,10 @@ import java.util.Queue;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@ -43,17 +45,20 @@ public class TaskExecutors extends DistributedJobLock {
// 线程池
private static final ExecutorService EXEC = new ThreadPoolExecutor(
MAX_TASKS_NUMBER, MAX_TASKS_NUMBER, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(MAX_TASKS_NUMBER * 6));
MAX_TASKS_NUMBER, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>());
// 异步任务
private static final Map<String, HeavyTask<?>> ASYNC_TASKS = new ConcurrentHashMap<>();
// 队列执行
private static final ExecutorService SINGLE_QUEUE = new ThreadPoolExecutor(
1, 1, 0L, TimeUnit.MILLISECONDS,
1, 1, 0L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>());
// 延迟执行
private static final ScheduledExecutorService SCHEDULED41 = Executors.newScheduledThreadPool(MAX_TASKS_NUMBER);
/**
* 异步执行提交给任务调度
*
@ -124,15 +129,17 @@ public class TaskExecutors extends DistributedJobLock {
}
/**
* 超时功能的执行
*
* @param task
* @param timeout in seconds
* @param timeout in ms
* @return
* @param <T>
*/
public static <T> T invoke(Callable<T> task, int timeout) {
Future<T> future = EXEC.submit(task);
try {
return future.get(timeout, TimeUnit.SECONDS);
return future.get(timeout, TimeUnit.MILLISECONDS);
} catch (Exception e) {
log.error("Invoke method timeout : {}",
StringUtils.defaultIfBlank(e.getMessage(), e.getClass().getSimpleName()));
@ -140,6 +147,16 @@ public class TaskExecutors extends DistributedJobLock {
return null;
}
/**
* 延迟执行
*
* @param command
* @param delay in ms
*/
public static void schedule(Runnable command, int delay) {
SCHEDULED41.schedule(command, delay, TimeUnit.MILLISECONDS);
}
/**
* 停止任务执行器
*/
@ -149,9 +166,14 @@ public class TaskExecutors extends DistributedJobLock {
log.warn("{} task(s) were interrupted", t.size());
}
List<Runnable> c = SINGLE_QUEUE.shutdownNow();
if (!c.isEmpty()) {
log.warn("{} command(s) were interrupted", c.size());
t = SINGLE_QUEUE.shutdownNow();
if (!t.isEmpty()) {
log.warn("{} command(s) were interrupted", t.size());
}
t = SCHEDULED41.shutdownNow();
if (!t.isEmpty()) {
log.warn("{} scheduled command(s) were interrupted", t.size());
}
}

View file

@ -635,7 +635,12 @@ class RbForm extends React.Component {
let iv = child.props.value
if (!$empty(iv) && (!this.props.readonly || (this.props.readonly && this.props.readonlyw === 3))) {
if (typeof iv === 'object') {
if (child.props.type === 'TAG') {
if (child.props.type === 'N2NREFERENCE') {
// fix: 4.0.6
let iv2 = []
iv.forEach((item) => iv2.push(item.id))
iv = iv2.join(',')
} else if (child.props.type === 'TAG') {
// eg. 标签
iv = iv.join('$$$$')
} else if (child.props.type === 'LOCATION') {