mirror of
https://github.com/getrebuild/rebuild.git
synced 2024-09-20 15:35:55 +08:00
Merge branch 'master' into develop
This commit is contained in:
commit
b644bbee0a
|
@ -418,6 +418,9 @@ public class ApprovalStepService extends InternalPersistService {
|
|||
if (useApprover == null) useApprover = UserService.SYSTEM_USER;
|
||||
if (useApproval == null) useApproval = APPROVAL_NOID;
|
||||
|
||||
// 作废之前
|
||||
cancelAliveSteps(recordId, null, null, null, false);
|
||||
|
||||
ID stepId = createStepIfNeed(recordId, useApproval,
|
||||
FlowNode.NODE_AUTOAPPROVAL, useApprover, false, FlowNode.NODE_ROOT,
|
||||
CalendarUtils.now(), getBatchNo(recordId, useApproval, FlowNode.NODE_ROOT));
|
||||
|
|
|
@ -34,6 +34,7 @@ import com.rebuild.core.service.general.series.SeriesGeneratorFactory;
|
|||
import com.rebuild.core.service.notification.NotificationObserver;
|
||||
import com.rebuild.core.service.query.QueryHelper;
|
||||
import com.rebuild.core.service.trigger.*;
|
||||
import com.rebuild.core.service.trigger.impl.AutoApproval;
|
||||
import com.rebuild.core.service.trigger.impl.GroupAggregation;
|
||||
import com.rebuild.core.support.i18n.Language;
|
||||
import com.rebuild.core.support.task.TaskExecutors;
|
||||
|
@ -95,44 +96,63 @@ public class GeneralEntityService extends ObservableService implements EntitySer
|
|||
}
|
||||
}
|
||||
|
||||
record = super.createOrUpdate(record);
|
||||
if (details == null || details.isEmpty()) return record;
|
||||
// 含明细
|
||||
final boolean hasDetails = details != null && !details.isEmpty();
|
||||
|
||||
// 主记录+明细记录处理
|
||||
|
||||
String dtf = MetadataHelper.getDetailToMainField(record.getEntity().getDetailEntity()).getName();
|
||||
ID mainid = record.getPrimary();
|
||||
|
||||
boolean checkDetailsRepeated = rcm == GeneralEntityServiceContextHolder.RCM_CHECK_DETAILS
|
||||
|| rcm == GeneralEntityServiceContextHolder.RCM_CHECK_ALL;
|
||||
|
||||
// 先删除
|
||||
for (Record d : details) {
|
||||
if (d instanceof DeleteRecord) delete(d.getPrimary());
|
||||
boolean hasAutoApprovalForDetails = false;
|
||||
if (hasDetails) {
|
||||
Entity de = record.getEntity().getDetailEntity();
|
||||
TriggerAction[] hasTriggers = de == null ? null
|
||||
: RobotTriggerManager.instance.getActions(de, TriggerWhen.APPROVED);
|
||||
hasAutoApprovalForDetails = hasTriggers != null && hasTriggers.length > 0;
|
||||
AutoApproval.setLazyAutoApproval();
|
||||
}
|
||||
|
||||
// 再保存
|
||||
for (Record d : details) {
|
||||
if (d instanceof DeleteRecord) continue;
|
||||
try {
|
||||
record = super.createOrUpdate(record);
|
||||
if (!hasDetails) return record;
|
||||
|
||||
if (checkDetailsRepeated) {
|
||||
d.setID(dtf, mainid); // for check
|
||||
// 主记录+明细记录处理
|
||||
|
||||
List<Record> repeated = getAndCheckRepeated(d, 20);
|
||||
if (!repeated.isEmpty()) {
|
||||
throw new RepeatedRecordsException(repeated);
|
||||
final String dtf = MetadataHelper.getDetailToMainField(record.getEntity().getDetailEntity()).getName();
|
||||
final ID mainid = record.getPrimary();
|
||||
|
||||
final boolean checkDetailsRepeated = rcm == GeneralEntityServiceContextHolder.RCM_CHECK_DETAILS
|
||||
|| rcm == GeneralEntityServiceContextHolder.RCM_CHECK_ALL;
|
||||
|
||||
// 先删除
|
||||
for (Record d : details) {
|
||||
if (d instanceof DeleteRecord) delete(d.getPrimary());
|
||||
}
|
||||
|
||||
// 再保存
|
||||
for (Record d : details) {
|
||||
if (d instanceof DeleteRecord) continue;
|
||||
|
||||
if (checkDetailsRepeated) {
|
||||
d.setID(dtf, mainid); // for check
|
||||
|
||||
List<Record> repeated = getAndCheckRepeated(d, 20);
|
||||
if (!repeated.isEmpty()) {
|
||||
throw new RepeatedRecordsException(repeated);
|
||||
}
|
||||
}
|
||||
|
||||
if (d.getPrimary() == null) {
|
||||
d.setID(dtf, mainid);
|
||||
create(d);
|
||||
} else {
|
||||
update(d);
|
||||
}
|
||||
}
|
||||
|
||||
if (d.getPrimary() == null) {
|
||||
d.setID(dtf, mainid);
|
||||
create(d);
|
||||
} else {
|
||||
update(d);
|
||||
return record;
|
||||
|
||||
} finally {
|
||||
if (hasAutoApprovalForDetails) {
|
||||
AutoApproval.executeLazyAutoApproval();
|
||||
}
|
||||
}
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -152,8 +172,7 @@ public class GeneralEntityService extends ObservableService implements EntitySer
|
|||
// 先更新
|
||||
record = super.update(record);
|
||||
|
||||
// 传导给明细(若有)
|
||||
// 仅分组聚合触发器
|
||||
// 主记录修改时传导给明细(若有),以便触发分组聚合触发器
|
||||
Entity de = record.getEntity().getDetailEntity();
|
||||
if (de != null) {
|
||||
TriggerAction[] hasTriggers = RobotTriggerManager.instance.getActions(de, TriggerWhen.UPDATE);
|
||||
|
@ -699,6 +718,7 @@ public class GeneralEntityService extends ObservableService implements EntitySer
|
|||
RobotTriggerManual triggerManual = new RobotTriggerManual();
|
||||
|
||||
// 传导给明细(若有)
|
||||
// FIXME 此时明细可能尚未做好变更(例如新建自动审批)
|
||||
|
||||
Entity de = approvalRecord.getEntity().getDetailEntity();
|
||||
TriggerAction[] hasTriggers = de == null ? null : RobotTriggerManager.instance.getActions(de,
|
||||
|
|
|
@ -17,13 +17,23 @@ import com.rebuild.core.service.trigger.ActionContext;
|
|||
import com.rebuild.core.service.trigger.ActionType;
|
||||
import com.rebuild.core.service.trigger.TriggerAction;
|
||||
import com.rebuild.core.service.trigger.TriggerException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.NamedThreadLocal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author devezhao
|
||||
* @since 2020/7/31
|
||||
*/
|
||||
@Slf4j
|
||||
public class AutoApproval extends TriggerAction {
|
||||
|
||||
private static final ThreadLocal<List<AutoApproval>> LAZY_AUTOAPPROVAL = new NamedThreadLocal<>("Lazy AutoApproval");
|
||||
|
||||
private OperatingContext operatingContext;
|
||||
|
||||
public AutoApproval(ActionContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
@ -40,6 +50,15 @@ public class AutoApproval extends TriggerAction {
|
|||
|
||||
@Override
|
||||
public void execute(OperatingContext operatingContext) throws TriggerException {
|
||||
this.operatingContext = operatingContext;
|
||||
|
||||
List<AutoApproval> lazyed;
|
||||
if ((lazyed = isLazyAutoApproval(false)) != null) {
|
||||
lazyed.add(this);
|
||||
log.info("Lazy AutoApproval : {}", lazyed);
|
||||
return;
|
||||
}
|
||||
|
||||
ID recordId = operatingContext.getAnyRecord().getPrimary();
|
||||
String useApprover = ((JSONObject) actionContext.getActionContent()).getString("useApprover");
|
||||
String useApproval = ((JSONObject) actionContext.getActionContent()).getString("useApproval");
|
||||
|
@ -49,4 +68,44 @@ public class AutoApproval extends TriggerAction {
|
|||
ID.isId(useApprover) ? ID.valueOf(useApprover) : null,
|
||||
ID.isId(useApproval) ? ID.valueOf(useApproval) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String s = super.toString();
|
||||
if (operatingContext != null) s += "#OperatingContext:" + operatingContext;
|
||||
return s;
|
||||
}
|
||||
|
||||
// --
|
||||
|
||||
/**
|
||||
* 跳过自动审批
|
||||
* @see #isLazyAutoApproval(boolean)
|
||||
*/
|
||||
public static void setLazyAutoApproval() {
|
||||
LAZY_AUTOAPPROVAL.set(new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public static List<AutoApproval> isLazyAutoApproval(boolean once) {
|
||||
List<AutoApproval> lazyed = LAZY_AUTOAPPROVAL.get();
|
||||
if (lazyed != null && once) LAZY_AUTOAPPROVAL.remove();
|
||||
return lazyed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public static int executeLazyAutoApproval() {
|
||||
List<AutoApproval> lazyed = isLazyAutoApproval(true);
|
||||
if (lazyed != null) {
|
||||
for (AutoApproval a : lazyed) {
|
||||
log.info("Lazy AutoApproval execute : {}", a);
|
||||
a.execute(a.operatingContext);
|
||||
}
|
||||
}
|
||||
return lazyed == null ? 0 : lazyed.size();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -610,13 +610,13 @@ class RbFormElement extends React.Component {
|
|||
*/
|
||||
checkValue() {
|
||||
const err = this.isValueError()
|
||||
this.setState({ hasError: err || null })
|
||||
const errMsg = err ? this.props.label + err : null
|
||||
|
||||
if (this.isValueUnchanged() && !this.props.$$$parent.isNew) {
|
||||
if (err) this.props.$$$parent.setFieldValue(this.props.field, this.state.value, errMsg)
|
||||
else this.props.$$$parent.setFieldUnchanged(this.props.field, this.state.value)
|
||||
} else {
|
||||
this.setState({ hasError: err })
|
||||
this.props.$$$parent.setFieldValue(this.props.field, this.state.value, errMsg)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue