mirror of
https://github.com/getrebuild/rebuild.git
synced 2024-11-11 01:14:42 +08:00
Merge pull request #398 from getrebuild/last-approver-732
Last approver RB-732
This commit is contained in:
commit
537f597bbc
15 changed files with 95 additions and 42 deletions
2
@rbv
2
@rbv
|
@ -1 +1 @@
|
|||
Subproject commit 9a4de36241ba367728a2c45c4b6b4ec475fb9d34
|
||||
Subproject commit 0662169c52c11b0bdb04e0935f7da4a18289026c
|
|
@ -165,6 +165,7 @@ public class EntityHelper {
|
|||
public static final String ApprovalId = "approvalId";
|
||||
public static final String ApprovalState = "approvalState";
|
||||
public static final String ApprovalStepNode = "approvalStepNode";
|
||||
public static final String ApprovalLastUser = "approvalLastUser";
|
||||
|
||||
// 权限
|
||||
|
||||
|
|
|
@ -249,7 +249,8 @@ public class MetadataHelper {
|
|||
public static boolean isApprovalField(String fieldName) {
|
||||
return EntityHelper.ApprovalId.equalsIgnoreCase(fieldName)
|
||||
|| EntityHelper.ApprovalState.equalsIgnoreCase(fieldName)
|
||||
|| EntityHelper.ApprovalStepNode.equalsIgnoreCase(fieldName);
|
||||
|| EntityHelper.ApprovalStepNode.equalsIgnoreCase(fieldName)
|
||||
|| EntityHelper.ApprovalLastUser.equalsIgnoreCase(fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -93,7 +93,7 @@ public class Entity2Schema extends Field2Schema {
|
|||
"select min(typeCode) from MetaEntity").unique();
|
||||
int typeCode = maxTypeCode == null || ObjectUtils.toInt(maxTypeCode[0]) == 0
|
||||
? 999 : (ObjectUtils.toInt(maxTypeCode[0]) - 1);
|
||||
if (typeCode <= (License.isCommercial() ? 500 : 900)) {
|
||||
if (typeCode <= (License.isCommercial() ? 399 : 949)) {
|
||||
throw new MetadataModificationException("ENTITY CODE EXCEEDS SYSTEM LIMIT : " + typeCode);
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ public class Entity2Schema extends Field2Schema {
|
|||
}
|
||||
record.setString("nameField", nameFiled);
|
||||
record = Application.getCommonsService().create(record);
|
||||
tempMetaId.add(record.getPrimary());
|
||||
recordedMetaId.add(record.getPrimary());
|
||||
|
||||
Entity tempEntity = new UnsafeEntity(entityName, physicalName, entityLabel, typeCode, nameFiled);
|
||||
try {
|
||||
|
@ -151,13 +151,13 @@ public class Entity2Schema extends Field2Schema {
|
|||
}
|
||||
} catch (Throwable ex) {
|
||||
log.error(null, ex);
|
||||
Application.getCommonsService().delete(tempMetaId.toArray(new ID[0]));
|
||||
Application.getCommonsService().delete(recordedMetaId.toArray(new ID[0]));
|
||||
throw new MetadataModificationException(Language.L("无法同步元数据到数据库 : %s", ex.getLocalizedMessage()));
|
||||
}
|
||||
|
||||
boolean schemaReady = schema2Database(tempEntity);
|
||||
if (!schemaReady) {
|
||||
Application.getCommonsService().delete(tempMetaId.toArray(new ID[0]));
|
||||
Application.getCommonsService().delete(recordedMetaId.toArray(new ID[0]));
|
||||
throw new MetadataModificationException(Language.L("无法同步元数据到数据库"));
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ public class Field2Schema {
|
|||
private static final int DECIMAL_SCALE = 8;
|
||||
|
||||
final protected ID user;
|
||||
final protected Set<ID> tempMetaId = new HashSet<>();
|
||||
final protected Set<ID> recordedMetaId = new HashSet<>();
|
||||
|
||||
/**
|
||||
* @param user
|
||||
|
@ -91,7 +91,7 @@ public class Field2Schema {
|
|||
|
||||
boolean schemaReady = schema2Database(entity, new Field[]{field});
|
||||
if (!schemaReady) {
|
||||
Application.getCommonsService().delete(tempMetaId.toArray(new ID[0]));
|
||||
Application.getCommonsService().delete(recordedMetaId.toArray(new ID[0]));
|
||||
throw new MetadataModificationException(Language.L("无法同步元数据到数据库"));
|
||||
}
|
||||
|
||||
|
@ -292,7 +292,7 @@ public class Field2Schema {
|
|||
}
|
||||
|
||||
recordOfField = Application.getCommonsService().create(recordOfField);
|
||||
tempMetaId.add(recordOfField.getPrimary());
|
||||
recordedMetaId.add(recordOfField.getPrimary());
|
||||
|
||||
// 以下会改变一些属性,因为并不想他们保存在元数据中
|
||||
|
||||
|
|
|
@ -40,10 +40,15 @@ public class ApprovalFields2Schema extends Field2Schema {
|
|||
*/
|
||||
public boolean createFields(Entity approvalEntity) throws MetadataModificationException {
|
||||
if (MetadataHelper.hasApprovalField(approvalEntity)) {
|
||||
if (!approvalEntity.containsField(EntityHelper.ApprovalLastUser)) {
|
||||
return createApporvalLastUser(approvalEntity);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (!(MetadataHelper.hasPrivilegesField(approvalEntity) || EasyMetaFactory.valueOf(approvalEntity).isPlainEntity())) {
|
||||
throw new RebuildException("Unsupported entity : " + approvalEntity.getName());
|
||||
|
||||
if (!(MetadataHelper.hasPrivilegesField(approvalEntity)
|
||||
|| EasyMetaFactory.valueOf(approvalEntity).isPlainEntity())) {
|
||||
throw new RebuildException("UNSUPPORTED ENTITY : " + approvalEntity.getName());
|
||||
}
|
||||
|
||||
Field apporvalId = createUnsafeField(approvalEntity, EntityHelper.ApprovalId, Language.L("审批流程"),
|
||||
|
@ -52,16 +57,36 @@ public class ApprovalFields2Schema extends Field2Schema {
|
|||
DisplayType.STATE, true, false, false, true, true, null, null, null, null, ApprovalState.DRAFT.getState());
|
||||
Field apporvalStepId = createUnsafeField(approvalEntity, EntityHelper.ApprovalStepNode, Language.L("审批步骤"),
|
||||
DisplayType.TEXT, true, false, false, true, false, null, null, null, null, null);
|
||||
Field apporvalLastUser = buildApporvalLastUser(approvalEntity);
|
||||
|
||||
boolean schemaReady = schema2Database(approvalEntity,
|
||||
new Field[] { apporvalId, apporvalState, apporvalStepId });
|
||||
new Field[] { apporvalId, apporvalState, apporvalStepId, apporvalLastUser });
|
||||
|
||||
if (!schemaReady) {
|
||||
Application.getCommonsService().delete(tempMetaId.toArray(new ID[0]));
|
||||
Application.getCommonsService().delete(recordedMetaId.toArray(new ID[0]));
|
||||
throw new MetadataModificationException(Language.L("无法同步元数据到数据库"));
|
||||
}
|
||||
|
||||
MetadataHelper.getMetadataFactory().refresh(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
// v2.7 最后审批人
|
||||
private boolean createApporvalLastUser(Entity approvalEntity) {
|
||||
Field apporvalLastUser = buildApporvalLastUser(approvalEntity);
|
||||
boolean schemaReady = schema2Database(approvalEntity, new Field[] { apporvalLastUser });
|
||||
|
||||
if (!schemaReady) {
|
||||
Application.getCommonsService().delete(recordedMetaId.toArray(new ID[0]));
|
||||
throw new MetadataModificationException(Language.L("无法同步元数据到数据库"));
|
||||
}
|
||||
|
||||
MetadataHelper.getMetadataFactory().refresh(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
private Field buildApporvalLastUser(Entity approvalEntity) {
|
||||
return createUnsafeField(approvalEntity, EntityHelper.ApprovalLastUser, Language.L("最后审批人"),
|
||||
DisplayType.REFERENCE, true, false, false, true, true, null, "User", CascadeModel.Ignore, null, null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,11 +93,14 @@ public class ApprovalProcessor extends SetUser {
|
|||
Set<ID> ccs = nextNodes.getCcUsers(this.getUser(), this.record, selectNextUsers);
|
||||
Set<ID> ccs4share = nextNodes.getCcUsers4Share(this.getUser(), this.record, selectNextUsers);
|
||||
|
||||
Record mainRecord = EntityHelper.forUpdate(this.record, this.getUser(), false);
|
||||
mainRecord.setID(EntityHelper.ApprovalId, this.approval);
|
||||
mainRecord.setInt(EntityHelper.ApprovalState, ApprovalState.PROCESSING.getState());
|
||||
mainRecord.setString(EntityHelper.ApprovalStepNode, nextNodes.getApprovalNode().getNodeId());
|
||||
Application.getBean(ApprovalStepService.class).txSubmit(mainRecord, ccs, nextApprovers);
|
||||
Record recordOfMain = EntityHelper.forUpdate(this.record, this.getUser(), false);
|
||||
recordOfMain.setID(EntityHelper.ApprovalId, this.approval);
|
||||
recordOfMain.setInt(EntityHelper.ApprovalState, ApprovalState.PROCESSING.getState());
|
||||
recordOfMain.setString(EntityHelper.ApprovalStepNode, nextNodes.getApprovalNode().getNodeId());
|
||||
if (recordOfMain.getEntity().containsField(EntityHelper.ApprovalLastUser)) {
|
||||
recordOfMain.setNull(EntityHelper.ApprovalLastUser);
|
||||
}
|
||||
Application.getBean(ApprovalStepService.class).txSubmit(recordOfMain, ccs, nextApprovers);
|
||||
|
||||
// 非主事物
|
||||
shareIfNeed(this.record, ccs4share);
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.rebuild.core.service.DataSpecificationNoRollbackException;
|
|||
import com.rebuild.core.service.general.GeneralEntityServiceContextHolder;
|
||||
import com.rebuild.core.service.notification.MessageBuilder;
|
||||
import com.rebuild.core.support.i18n.Language;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Set;
|
||||
|
@ -36,6 +37,7 @@ import java.util.Set;
|
|||
* @author devezhao
|
||||
* @since 07/11/2019
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ApprovalStepService extends BaseService {
|
||||
|
||||
|
@ -167,6 +169,9 @@ public class ApprovalStepService extends BaseService {
|
|||
// 更新主记录状态
|
||||
Record recordOfMain = EntityHelper.forUpdate(recordId, UserService.SYSTEM_USER, false);
|
||||
recordOfMain.setInt(EntityHelper.ApprovalState, ApprovalState.REJECTED.getState());
|
||||
if (recordOfMain.getEntity().containsField(EntityHelper.ApprovalLastUser)) {
|
||||
recordOfMain.setID(EntityHelper.ApprovalLastUser, approver);
|
||||
}
|
||||
super.update(recordOfMain);
|
||||
|
||||
String rejectedMsg = Language.L("@%s 驳回了你的 %s 审批", approver, entityLabel);
|
||||
|
@ -218,7 +223,7 @@ public class ApprovalStepService extends BaseService {
|
|||
|
||||
// 最终状态(审批通过)
|
||||
if (goNextNode && (nextApprovers == null || nextNode == null)) {
|
||||
Application.getEntityService(recordId.getEntityCode()).approve(recordId, ApprovalState.APPROVED);
|
||||
Application.getEntityService(recordId.getEntityCode()).approve(recordId, ApprovalState.APPROVED, approver);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -226,6 +231,9 @@ public class ApprovalStepService extends BaseService {
|
|||
if (goNextNode) {
|
||||
Record recordOfMain = EntityHelper.forUpdate(recordId, UserService.SYSTEM_USER, false);
|
||||
recordOfMain.setString(EntityHelper.ApprovalStepNode, nextNode);
|
||||
if (recordOfMain.getEntity().containsField(EntityHelper.ApprovalLastUser)) {
|
||||
recordOfMain.setID(EntityHelper.ApprovalLastUser, approver);
|
||||
}
|
||||
super.update(recordOfMain);
|
||||
}
|
||||
|
||||
|
@ -269,7 +277,7 @@ public class ApprovalStepService extends BaseService {
|
|||
|
||||
// 撤销
|
||||
if (isRevoke) {
|
||||
Application.getEntityService(recordId.getEntityCode()).approve(recordId, ApprovalState.REVOKED);
|
||||
Application.getEntityService(recordId.getEntityCode()).approve(recordId, ApprovalState.REVOKED, null);
|
||||
} else {
|
||||
Record recordOfMain = EntityHelper.forUpdate(recordId, UserService.SYSTEM_USER, false);
|
||||
recordOfMain.setInt(EntityHelper.ApprovalState, useState.getState());
|
||||
|
@ -387,8 +395,10 @@ public class ApprovalStepService extends BaseService {
|
|||
final ApprovalState currentState = ApprovalHelper.getApprovalState(recordId);
|
||||
|
||||
// 其他状态不能自动审批
|
||||
if (currentState == ApprovalState.DRAFT || currentState == ApprovalState.REJECTED
|
||||
if (currentState == ApprovalState.DRAFT
|
||||
|| currentState == ApprovalState.REJECTED
|
||||
|| currentState == ApprovalState.REVOKED) {
|
||||
|
||||
if (useApprover == null) useApprover = UserService.SYSTEM_USER;
|
||||
if (useApproval == null) useApproval = APPROVAL_NOID;
|
||||
|
||||
|
@ -404,10 +414,13 @@ public class ApprovalStepService extends BaseService {
|
|||
recordOfMain.setID(EntityHelper.ApprovalId, useApproval);
|
||||
recordOfMain.setString(EntityHelper.ApprovalStepNode, FlowNode.NODE_AUTOAPPROVAL);
|
||||
super.update(recordOfMain);
|
||||
Application.getEntityService(recordId.getEntityCode()).approve(recordId, ApprovalState.APPROVED);
|
||||
|
||||
Application.getEntityService(recordId.getEntityCode()).approve(recordId, ApprovalState.APPROVED, useApprover);
|
||||
return true;
|
||||
}
|
||||
|
||||
} else {
|
||||
log.warn("Invalid state {} for auto approval", currentState);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,7 +114,8 @@ public interface EntityService extends ServiceSpec {
|
|||
*
|
||||
* @param record
|
||||
* @param state 只接受通过或撤销
|
||||
* @param approvalUser 审批人
|
||||
* @see com.rebuild.core.service.approval.ApprovalStepService
|
||||
*/
|
||||
void approve(ID record, ApprovalState state);
|
||||
void approve(ID record, ApprovalState state, ID approvalUser);
|
||||
}
|
||||
|
|
|
@ -541,13 +541,19 @@ public class GeneralEntityService extends ObservableService implements EntitySer
|
|||
}
|
||||
|
||||
@Override
|
||||
public void approve(ID record, ApprovalState state) {
|
||||
public void approve(ID record, ApprovalState state, ID approvalUser) {
|
||||
Assert.isTrue(
|
||||
state == ApprovalState.REVOKED || state == ApprovalState.APPROVED,
|
||||
"Only REVOKED or APPROVED allowed");
|
||||
|
||||
Record approvalRecord = EntityHelper.forUpdate(record, UserService.SYSTEM_USER, false);
|
||||
approvalRecord.setInt(EntityHelper.ApprovalState, state.getState());
|
||||
if (state == ApprovalState.APPROVED
|
||||
&& approvalUser != null
|
||||
&& MetadataHelper.getEntity(record.getEntityCode()).containsField(EntityHelper.ApprovalLastUser)) {
|
||||
approvalRecord.setID(EntityHelper.ApprovalLastUser, approvalUser);
|
||||
}
|
||||
|
||||
delegateService.update(approvalRecord);
|
||||
|
||||
// 触发器
|
||||
|
|
|
@ -177,7 +177,7 @@ public class ReferenceSearchController extends EntityController {
|
|||
private List<Object> resultSearch(String sqlWhere, Entity entity, int maxResults) {
|
||||
Field nameField = entity.getNameField();
|
||||
|
||||
String sql = MessageFormat.format("select {0},{1} from {2} where {3}",
|
||||
String sql = MessageFormat.format("select {0},{1} from {2} where ({3})",
|
||||
entity.getPrimaryField().getName(), nameField.getName(), entity.getName(), sqlWhere);
|
||||
|
||||
if (!sqlWhere.contains(" order by ")) {
|
||||
|
|
|
@ -2840,21 +2840,27 @@ form {
|
|||
margin: 0 -5px;
|
||||
}
|
||||
|
||||
.form.approval-form .form-group {
|
||||
.form.approval-form > .form-group {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.form.approval-form .form-group .zicon {
|
||||
.form.approval-form > .form-group .zicon {
|
||||
float: left;
|
||||
padding-right: 6px;
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
.form.approval-form .form-group .zicon.zmdi-mail-send {
|
||||
.form.approval-form > .form-group .zicon.zmdi-mail-send {
|
||||
font-size: 1.1rem;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.form.approval-form .rbform {
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 2px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.form.approval-form .approval-list {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
@ -3011,16 +3017,6 @@ form {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.form.approval-form .rbform {
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 3px;
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
.form.approval-form .rbform .form-group.row {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.notification-page {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
|
|
@ -419,6 +419,7 @@ class ApprovalApproveForm extends ApprovalUsersForm {
|
|||
<label>{$L('信息完善 (驳回时无需填写)')}</label>
|
||||
<EditableForm $$$parent={fake} entity={this.props.entity} ref={(c) => (this._rbform = c)}>
|
||||
{this.state.aform.map((item) => {
|
||||
item.isFull = true
|
||||
// eslint-disable-next-line no-undef
|
||||
return detectElement(item)
|
||||
})}
|
||||
|
|
|
@ -555,7 +555,7 @@ const RbListCommon = {
|
|||
})
|
||||
|
||||
// via 过滤
|
||||
const via = $urlp('via', location.hash)
|
||||
const via = $urlp('via') || $urlp('via', location.hash)
|
||||
if (via) {
|
||||
wpc.protocolFilter = `via:${via}`
|
||||
const $cleanVia = $(`<div class="badge filter-badge">${$L('当前数据已过滤')}<a class="close" title="${$L('查看全部数据')}">×</a></div>`).appendTo('.dataTables_filter')
|
||||
|
|
|
@ -36,15 +36,21 @@ class RbViewForm extends React.Component {
|
|||
}
|
||||
|
||||
let hadApproval = res.data.hadApproval
|
||||
let hadAlert = null
|
||||
if (wpc.type === 'DetailView') {
|
||||
if (hadApproval === 2) $('.J_edit, .J_delete').attr({ disabled: true, title: $L('主记录正在审批中') })
|
||||
else if (hadApproval === 10) $('.J_edit, .J_delete').remove()
|
||||
if (hadApproval === 2 || hadApproval === 10) {
|
||||
if (window.RbViewPage) window.RbViewPage.setReadonly()
|
||||
else $('.J_edit, .J_delete').remove()
|
||||
|
||||
hadAlert = <RbAlertBox message={hadApproval === 2 ? $L('主记录正在审批中,明细记录禁止修改') : $L('主记录已审批完成,明细记录禁止修改')} />
|
||||
}
|
||||
hadApproval = null
|
||||
}
|
||||
|
||||
const viewData = {}
|
||||
const VFORM = (
|
||||
<React.Fragment>
|
||||
{hadAlert}
|
||||
{hadApproval && <ApprovalProcessor id={this.props.id} entity={this.props.entity} />}
|
||||
<div className="row">
|
||||
{res.data.elements.map((item) => {
|
||||
|
|
Loading…
Reference in a new issue