Skip to content

Commit

Permalink
Lazy wait details finished (#678)
Browse files Browse the repository at this point in the history
* lazy HookUrl

* fix: $same

* enh: 记录转换 AnyRef
  • Loading branch information
getrebuild authored Nov 13, 2023
1 parent 6147c36 commit c9b81f9
Show file tree
Hide file tree
Showing 14 changed files with 110 additions and 100 deletions.
2 changes: 1 addition & 1 deletion @rbv
Submodule @rbv updated from 12e3c9 to 416bec
Original file line number Diff line number Diff line change
Expand Up @@ -126,30 +126,44 @@ public Record createOrUpdate(Record record) {
// 含明细
final boolean hasDetails = details != null && !details.isEmpty();

boolean lazyAutoApprovalForDetails = false;
boolean lazyAutoTransformForDetails = false;
// 延迟执行触发器,因为明细尚未保存好
boolean lazyAutoApproval4Details = false;
boolean lazyAutoTransform4Details = false;
boolean lazyHookUrl4Details = false;
if (hasDetails) {
// fix: v3.2.2

// 自动审批 fix: v3.2.2

TriggerAction[] hasAutoApprovalTriggers = getSpecTriggers(
record.getEntity(), ActionType.AUTOAPPROVAL, TriggerWhen.CREATE, TriggerWhen.UPDATE);
lazyAutoApprovalForDetails = hasAutoApprovalTriggers.length > 0;
lazyAutoApproval4Details = hasAutoApprovalTriggers.length > 0;
// FIXME 此判断可能无意义,待进一步测试后确定是否保留
if (!lazyAutoApprovalForDetails) {
if (!lazyAutoApproval4Details) {
TriggerAction[] hasOnApprovedTriggers = getSpecTriggers(
record.getEntity().getDetailEntity(), null, TriggerWhen.APPROVED);
lazyAutoApprovalForDetails = hasOnApprovedTriggers.length > 0;
lazyAutoApproval4Details = hasOnApprovedTriggers.length > 0;
}
// 自动审批延迟执行,因为明细尚未保存好
if (lazyAutoApprovalForDetails) AutoApproval.setLazyAutoApproval();
if (lazyAutoApproval4Details) AutoApproval.setLazy();

// 自动转换

TriggerAction[] hasAutoTransformTriggers = getSpecTriggers(
record.getEntity(), ActionType.AUTOTRANSFORM, TriggerWhen.CREATE, TriggerWhen.UPDATE);
lazyAutoTransformForDetails = hasAutoTransformTriggers.length > 0;
lazyAutoTransform4Details = hasAutoTransformTriggers.length > 0;
// 记录转换延迟执行,因为明细尚未保存好
if (lazyAutoTransformForDetails) CommonsUtils.invokeMethod("com.rebuild.rbv.trigger.AutoTransform#setLazyAutoTransform");
if (lazyAutoTransform4Details) CommonsUtils.invokeMethod("com.rebuild.rbv.trigger.AutoTransform#setLazy");

// URL 回调 v3.5

TriggerAction[] hasHookUrlTriggers = getSpecTriggers(
record.getEntity(), ActionType.HOOKURL, TriggerWhen.CREATE, TriggerWhen.UPDATE, TriggerWhen.DELETE);
lazyHookUrl4Details = hasHookUrlTriggers.length > 0;
// 对于全量推送,明细尚未保存好
if (lazyHookUrl4Details) CommonsUtils.invokeMethod("com.rebuild.rbv.trigger.HookUrl#setLazy");
}

// 保证顺序
// 保证执行顺序
Map<Integer, ID> detaileds = new TreeMap<>();

try {
Expand Down Expand Up @@ -200,12 +214,9 @@ record = record.getPrimary() == null ? create(record) : update(record);
return record;

} finally {
if (lazyAutoApprovalForDetails) {
AutoApproval.executeLazyAutoApproval();
}
if (lazyAutoTransformForDetails) {
CommonsUtils.invokeMethod("com.rebuild.rbv.trigger.AutoTransform#executeLazyAutoTransform");
}
if (lazyAutoApproval4Details) AutoApproval.executeLazy();
if (lazyAutoTransform4Details) CommonsUtils.invokeMethod("com.rebuild.rbv.trigger.AutoTransform#executeLazy");
if (lazyHookUrl4Details) CommonsUtils.invokeMethod("com.rebuild.rbv.trigger.HookUrl#executeLazy");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,11 @@ public ID transform(ID sourceRecordId, ID specMainId) {
final boolean checkNullable = transConfig.getBooleanValue("checkNullable35");

Record main = transformRecord(sourceEntity, targetEntity, fieldsMapping, sourceRecordId, dvMap, false, false, checkNullable);
ID newId;
ID theNewId;

// v3.5 需要先回填
// 因为可能以回填字段作为条件进行转换一次判断
final boolean fillbackFix = fillback(sourceRecordId, EntityHelper.newUnsavedId(main.getEntity().getEntityCode()));

// 有多条(主+明细)
if (sourceDetails != null && sourceDetails.length > 0) {
Expand All @@ -155,15 +159,15 @@ public ID transform(ID sourceRecordId, ID specMainId) {
transformRecord(sourceDetailEntity, targetDetailEntity, fieldsMappingDetail, (ID) d[0], null, false, false, checkNullable));
}

newId = saveRecord(main, detailsList);
theNewId = saveRecord(main, detailsList);
} else {
newId = saveRecord(main, null);
theNewId = saveRecord(main, null);
}

// 回填
fillback(sourceRecordId, newId);
// 回填修正
if (fillbackFix) fillback(sourceRecordId, theNewId);

return newId;
return theNewId;
}

private ID saveRecord(Record record, List<Record> detailsList) {
Expand Down Expand Up @@ -204,15 +208,15 @@ protected boolean fillback(ID sourceRecordId, ID newId) {

// 此配置未开放
int fillbackMode = transConfig.getIntValue("fillbackMode");
if (fillbackMode == 2) {
if (fillbackMode == 2 && !EntityHelper.isUnsavedId(newId)) {
GeneralEntityServiceContextHolder.setAllowForceUpdate(updateSource.getPrimary());
try {
Application.getEntityService(sourceEntity.getEntityCode()).update(updateSource);
} finally {
GeneralEntityServiceContextHolder.isAllowForceUpdateOnce();
}
} else {
// FIXME 回填仅更新,无业务规则
// 无传播更新
Application.getCommonsService().update(updateSource, false);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*!
Copyright (c) REBUILD <https://getrebuild.com/> and/or its owners. All rights reserved.
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
See LICENSE and COMMERCIAL in the project root for license information.
*/

package com.rebuild.core.service.trigger;

/**
* 部分触发器执行需要等到明细记录处理完成才能执行
*
* @author devezhao
* @since 2023/11/11
*/
public interface LazyWaitDetailsFinished {

String FLAG_LAZY = "lazy";

// setLazy
// isLazy
// executeLazy
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.rebuild.core.service.general.OperatingContext;
import com.rebuild.core.service.trigger.ActionContext;
import com.rebuild.core.service.trigger.ActionType;
import com.rebuild.core.service.trigger.LazyWaitDetailsFinished;
import com.rebuild.core.service.trigger.TriggerAction;
import com.rebuild.core.service.trigger.TriggerException;
import com.rebuild.core.service.trigger.TriggerResult;
Expand All @@ -37,10 +38,11 @@
* @since 2020/7/31
*/
@Slf4j
public class AutoApproval extends TriggerAction {
public class AutoApproval extends TriggerAction implements LazyWaitDetailsFinished {

// 延迟执行
private static final ThreadLocal<List<AutoApproval>> LAZY_AUTOAPPROVAL = new NamedThreadLocal<>("Lazy AutoApproval");
private OperatingContext operatingContext;
private OperatingContext keepOperatingContext;

public AutoApproval(ActionContext context) {
super(context);
Expand All @@ -58,19 +60,19 @@ public boolean isUsableSourceEntity(int entityCode) {

@Override
public Object execute(OperatingContext operatingContext) throws TriggerException {
this.operatingContext = operatingContext;
this.keepOperatingContext = operatingContext;
List<AutoApproval> lazyed;
if ((lazyed = isLazyAutoApproval(Boolean.FALSE)) != null) {
if ((lazyed = isLazy(false)) != null) {
lazyed.add(this);
log.info("Lazy AutoApproval : {}", lazyed);
return "lazy";
return FLAG_LAZY;
}

ID recordId = operatingContext.getFixedRecordId();
String useApproval = ((JSONObject) actionContext.getActionContent()).getString("useApproval");

// 优先使用当前用户
ID approver = ObjectUtils.defaultIfNull(UserContextHolder.getUser(Boolean.TRUE), UserService.SYSTEM_USER);
ID approver = ObjectUtils.defaultIfNull(UserContextHolder.getUser(true), UserService.SYSTEM_USER);
ID approvalId = ID.isId(useApproval) ? ID.valueOf(useApproval) : null;

// v2.10
Expand All @@ -89,24 +91,23 @@ public Object execute(OperatingContext operatingContext) throws TriggerException
@Override
public String toString() {
String s = super.toString();
if (operatingContext != null) s += "#OperatingContext:" + operatingContext;
if (keepOperatingContext != null) s += "#OperatingContext:" + keepOperatingContext;
return s;
}

// --

/**
* 跳过自动审批
* @see #isLazyAutoApproval(boolean)
*/
public static void setLazyAutoApproval() {
public static void setLazy() {
LAZY_AUTOAPPROVAL.set(new ArrayList<>());
}

/**
* @param once
* @return
*/
public static List<AutoApproval> isLazyAutoApproval(boolean once) {
public static List<AutoApproval> isLazy(boolean once) {
List<AutoApproval> lazyed = LAZY_AUTOAPPROVAL.get();
if (lazyed != null && once) LAZY_AUTOAPPROVAL.remove();
return lazyed;
Expand All @@ -115,12 +116,12 @@ public static List<AutoApproval> isLazyAutoApproval(boolean once) {
/**
* @return
*/
public static int executeLazyAutoApproval() {
List<AutoApproval> lazyed = isLazyAutoApproval(Boolean.TRUE);
public static int executeLazy() {
List<AutoApproval> lazyed = isLazy(true);
if (lazyed != null) {
for (AutoApproval a : lazyed) {
log.info("Lazy AutoApproval execute : {}", a);
Object res = a.execute(a.operatingContext);
Object res = a.execute(a.keepOperatingContext);

CommonsLog.createLog(TYPE_TRIGGER,
UserService.SYSTEM_USER, a.getActionContext().getConfigId(), res.toString());
Expand Down
17 changes: 13 additions & 4 deletions src/main/java/com/rebuild/utils/OkHttpUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,21 @@
import com.rebuild.core.Application;
import com.rebuild.core.support.RebuildConfiguration;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;
import org.springframework.http.HttpHeaders;

import java.io.*;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Locale;
Expand Down Expand Up @@ -56,8 +65,8 @@ synchronized public static OkHttpClient getHttpClient() {
if (okHttpClient == null) {
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.hostnameVerifier((s, sslSession) -> true) // NOT SAFE!!!
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ public RespBody transform(HttpServletRequest request) {
}

try {
ID newId = transfomer.transform(sourceRecord, mainid);
return RespBody.ok(newId);
ID theNewId = transfomer.transform(sourceRecord, mainid);
return RespBody.ok(theNewId);
} catch (Exception ex) {
log.warn(">>>>> {}", ex.getLocalizedMessage());

Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/web/assets/js/admin/transform-design.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ $(document).ready(() => {

const fillbackFields = []
wpc.sourceEntity.fields.forEach((item) => {
if (!item.name.includes('.') && item.type === 'REFERENCE' && item.ref[0] === wpc.targetEntity.entity) {
if (item.name.includes('.')) return
if ((item.type === 'REFERENCE' && item.ref[0] === wpc.targetEntity.entity) || item.type === 'ANYREFERENCE') {
fillbackFields.push({ id: item.name, text: item.label })
}
})
Expand Down
11 changes: 1 addition & 10 deletions src/main/resources/web/assets/js/bizuser/role-privileges.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,16 +165,7 @@ const loadRoles = function () {
extrasAction={(item) => {
return (
<RF>
<span
className="action"
onClick={() => {
RbFormModal.create({
title: $L('编辑角色'),
entity: 'Role',
icon: 'lock',
id: item.id,
})
}}>
<span className="action" onClick={() => RbFormModal.create({ title: $L('编辑角色'), entity: 'Role', icon: 'lock', id: item.id }, true)}>
<i className="zmdi zmdi-edit" />
</span>
<span
Expand Down
7 changes: 3 additions & 4 deletions src/main/resources/web/assets/js/rb-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,12 +390,11 @@ var $random = function (prefix, alphabetic, maxLength) {
var $same = function (a, b) {
if (Object.is(a, b)) return true
if (a && b) {
if ($.type(a) === 'object' && $.type(b) === 'object') {
var aType = $.type(a)
var bType = $.type(b)
if ((aType === 'object' && bType === 'object') || (aType === 'array' && bType === 'array')) {
a = JSON.stringify(a)
b = JSON.stringify(b)
} else if ($.type(a) === 'array' && $.type(b) === 'array') {
a = a.join(',')
b = b.join(',')
}
}
if (a === b) return true
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/web/assets/js/rb-datalist.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const RbListPage = {
$('.J_edit').on('click', () => {
const ids = this._RbList.getSelectedIds()
if (ids.length >= 1) {
RbFormModal.create({ id: ids[0], title: $L('编辑%s', entity[1]), entity: entity[0], icon: entity[2] })
RbFormModal.create({ id: ids[0], title: $L('编辑%s', entity[1]), entity: entity[0], icon: entity[2] }, true)
}
})

Expand Down
17 changes: 2 additions & 15 deletions src/main/resources/web/assets/js/rb-forms.js
Original file line number Diff line number Diff line change
Expand Up @@ -708,12 +708,7 @@ class RbForm extends React.Component {
} else if (next === RbForm.NEXT_ADDDETAIL) {
const iv = $$$parent.props.initialValue
const dm = this.props.rawModel.entityMeta
RbFormModal.create({
title: $L('添加%s', dm.entityLabel),
entity: dm.entity,
icon: dm.icon,
initialValue: iv,
})
RbFormModal.create({ title: $L('添加%s', dm.entityLabel), entity: dm.entity, icon: dm.icon, initialValue: iv })
} else if (next === RbForm.NEXT_VIEW && window.RbViewModal) {
window.RbViewModal.create({ id: recordId, entity: this.state.entity })
if (window.RbListPage) {
Expand Down Expand Up @@ -2077,15 +2072,7 @@ class RbFormReference extends RbFormElement {

quickNew() {
const e = this.props.referenceEntity
RbFormModal.create(
{
title: $L('新建%s', e.entityLabel),
entity: e.entity,
icon: e.icon,
postAfter: (id) => this.showSearcher_call([id], this),
},
true
)
RbFormModal.create({ title: $L('新建%s', e.entityLabel), entity: e.entity, icon: e.icon, postAfter: (id) => this.showSearcher_call([id], this) }, true)
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/main/resources/web/assets/js/rb-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
/* !!! KEEP IT ES5 COMPATIBLE !!! */

// GA
(function () {
;(function () {
const gaScript = document.createElement('script')
gaScript.src = 'https://www.googletagmanager.com/gtag/js?id=G-ZCZHJPMEG7'
gaScript.async = true
Expand Down Expand Up @@ -180,8 +180,7 @@ $(function () {
})
})

// __LAB
if (rb.env === 'dev' && window.sessionStorage) {
if (window.sessionStorage) {
$('.navbar .navbar-collapse>.navbar-nav a').on('click', function (e) {
sessionStorage.setItem('AppHome._InTab', e.target.href.split('?')[1])
})
Expand Down
Loading

0 comments on commit c9b81f9

Please sign in to comment.