Skip to content

Commit

Permalink
Approval edit details 111 (#860)
Browse files Browse the repository at this point in the history
* task-num show

* feat: 审批可修改字段明细支持

* trigger job cron

* entity-truncate
  • Loading branch information
getrebuild authored Jan 16, 2025
1 parent 88986b5 commit e03c733
Show file tree
Hide file tree
Showing 24 changed files with 404 additions and 105 deletions.
2 changes: 1 addition & 1 deletion @rbv
Submodule @rbv updated from 3e4b5e to fd2547
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.service.NoRecordFoundException;
import com.rebuild.utils.JSONUtils;
import org.apache.commons.collections4.CollectionUtils;

/**
* 轻量级表单
Expand Down Expand Up @@ -60,9 +61,11 @@ public LiteFormBuilder(Entity entity, ID user) {
* @return
*/
public JSONArray build(JSONArray fieldElements) {
if (fieldElements == null || fieldElements.isEmpty()) {
if (CollectionUtils.isEmpty(fieldElements)) {
throw new DefinedException("No field elements");
}
// Use clone
fieldElements = (JSONArray) JSONUtils.clone(fieldElements);

Record recordData = null;
if (recordId != null) {
Expand All @@ -85,7 +88,7 @@ public JSONArray build(String[] fields) {
for (String field : fields) {
if (entity.containsField(field)) {
fieldElements.add(JSONUtils.toJSONObject(
new String[] { "field", "colspan" }, new Object[] { field, 4 }));
new String[]{"field", "colspan"}, new Object[]{field, 4}));
}
}
return build(fieldElements);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public void txApprove(Record stepRecord, String signMode, Set<ID> ccUsers, Set<S
if (addedData != null) {
GeneralEntityServiceContextHolder.setAllowForceUpdate(addedData.getPrimary());
try {
Application.getEntityService(addedData.getEntity().getEntityCode()).update(addedData);
Application.getEntityService(addedData.getEntity().getEntityCode()).createOrUpdate(addedData);
} finally {
GeneralEntityServiceContextHolder.isAllowForceUpdateOnce();
}
Expand Down
104 changes: 104 additions & 0 deletions src/main/java/com/rebuild/core/service/approval/EditableFields.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*!
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.approval;

import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.engine.ID;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rebuild.core.configuration.general.LiteFormBuilder;
import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
import com.rebuild.core.service.query.QueryHelper;
import com.rebuild.utils.JSONUtils;
import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* 可编辑字段
*
* @author ZiXin
* @since 2015/1/15
*/
public class EditableFields {

private final JSONArray editableFields;

public EditableFields(JSONArray editableFields) {
this.editableFields = editableFields;
}

/**
* @param recordId
* @param user
* @return
*/
public JSONObject buildForms(ID recordId, ID user) {
final Entity entity = MetadataHelper.getEntity(recordId.getEntityCode());

Map<String, JSONArray> fieldsByEntity = getEditableFieldsByEntity(entity.getName());
JSONObject aforms = new JSONObject();

JSONArray mFields = fieldsByEntity.remove(entity.getName());
if (CollectionUtils.isNotEmpty(mFields)) {
JSONArray aform = new LiteFormBuilder(recordId, user).build(mFields);
if (CollectionUtils.isNotEmpty(aform)) {
aforms.put("aform", aform);
aforms.put("aentity", entity.getName());
}
}

List<JSONObject> detailsByEntity = new ArrayList<>();
for (Map.Entry<String, JSONArray> e : fieldsByEntity.entrySet()) {
Entity dEntity = MetadataHelper.getEntity(e.getKey());
JSONArray dFields = e.getValue();

JSONArray dForms = new JSONArray();
for (ID did : QueryHelper.detailIdsNoFilter(recordId, dEntity)) {
JSONArray aform = new LiteFormBuilder(did, user).build(dFields);
if (CollectionUtils.isNotEmpty(aform)) {
aform.add(did); // Last is ID
dForms.add(aform);
}
}

if (!dForms.isEmpty()) {
JSONObject d = JSONUtils.toJSONObject(
new String[]{"aentity", "aentityLabel", "aforms"},
new Object[]{dEntity.getName(), EasyMetaFactory.getLabel(dEntity), dForms});
detailsByEntity.add(d);
}
}

if (!detailsByEntity.isEmpty()) {
aforms.put("aform_details", detailsByEntity);
}

return aforms;
}

private Map<String, JSONArray> getEditableFieldsByEntity(String entityName) {
Map<String, JSONArray> fieldsByEntity = new HashMap<>();
for (Object o : editableFields) {
JSONObject item = (JSONObject) o;
String fieldName = item.getString("field");
String[] ef;
if (fieldName.contains(".")) ef = fieldName.split("\\.");
else ef = new String[]{entityName, fieldName};

JSONArray fields = fieldsByEntity.computeIfAbsent(ef[0], k -> new JSONArray());
item.put("field", ef[1]);
fields.add(item);
}
return fieldsByEntity;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ protected boolean checkModifications(Record record, Permission action) throws Da

// 审批时/已通过强制修改
if (unallow) {
boolean forceUpdate = GeneralEntityServiceContextHolder.isAllowForceUpdateOnce();
boolean forceUpdate = GeneralEntityServiceContextHolder.isAllowForceUpdate(false);
if (forceUpdate) unallow = false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,17 @@ public static void setAllowForceUpdate(ID recordId) {
* @see #setAllowForceUpdate(ID)
*/
public static boolean isAllowForceUpdateOnce() {
return isAllowForceUpdate(true);
}

/**
* @param once
* @return
* @see #setAllowForceUpdate(ID)
*/
public static boolean isAllowForceUpdate(boolean once) {
ID recordId = ALLOW_FORCE_UPDATE.get();
if (recordId != null) ALLOW_FORCE_UPDATE.remove();
if (recordId != null && once) ALLOW_FORCE_UPDATE.remove();
return recordId != null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import com.rebuild.core.privileges.UserHelper;
import com.rebuild.core.rbstore.MetaschemaExporter;
import com.rebuild.core.service.general.QuickCodeReindexTask;
import com.rebuild.core.service.general.series.SeriesGeneratorFactory;
import com.rebuild.core.support.RebuildConfiguration;
import com.rebuild.core.support.general.FieldValueHelper;
import com.rebuild.core.support.task.TaskExecutors;
Expand Down Expand Up @@ -262,6 +263,25 @@ public RespBody entityDrop(HttpServletRequest request) {
}
}

@RequestMapping("entity/entity-truncate")
public RespBody entityTruncate(HttpServletRequest request) {
final Entity entity = getEntityById(getIdParameterNotNull(request, "id"));

try {
String dsql = String.format("TRUNCATE TABLE `%s`", entity.getPhysicalName());
Application.getSqlExecutor().execute(dsql);
// 置零
for (Field s : MetadataSorter.sortFields(entity, DisplayType.SERIES)) {
SeriesGeneratorFactory.zero(s);
}
return RespBody.ok();

} catch (Exception ex) {
log.error("entity-truncate", ex);
return RespBody.error(ex.getLocalizedMessage());
}
}

@GetMapping("entity/entity-export")
public void entityExport(HttpServletRequest request, HttpServletResponse response) throws IOException {
final Entity entity = getEntityById(getIdParameterNotNull(request, "id"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import com.rebuild.api.RespBody;
import com.rebuild.core.Application;
import com.rebuild.core.DefinedException;
import com.rebuild.core.configuration.general.LiteFormBuilder;
import com.rebuild.core.metadata.EntityHelper;
import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.privileges.UserHelper;
Expand All @@ -29,16 +28,19 @@
import com.rebuild.core.service.approval.ApprovalState;
import com.rebuild.core.service.approval.ApprovalStatus;
import com.rebuild.core.service.approval.ApprovalStepService;
import com.rebuild.core.service.approval.EditableFields;
import com.rebuild.core.service.approval.FlowDefinition;
import com.rebuild.core.service.approval.FlowNode;
import com.rebuild.core.service.approval.FlowNodeGroup;
import com.rebuild.core.service.approval.RobotApprovalManager;
import com.rebuild.core.service.general.GeneralEntityService;
import com.rebuild.core.service.trigger.DataValidateException;
import com.rebuild.utils.CommonsUtils;
import com.rebuild.utils.JSONUtils;
import com.rebuild.web.BaseController;
import com.rebuild.web.IdParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.transaction.UnexpectedRollbackException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand All @@ -48,7 +50,9 @@
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import static com.rebuild.core.privileges.bizz.ZeroEntry.AllowRevokeApproval;
Expand Down Expand Up @@ -173,21 +177,15 @@ public JSON fetchNextStep(HttpServletRequest request,
// 可修改字段
JSONArray editableFields = currentFlowNode.getEditableFields();
if (editableFields != null && !editableFields.isEmpty()) {
JSONArray aform = new LiteFormBuilder(recordId, user).build(editableFields);
if (aform != null && !aform.isEmpty()) {
data.put("aform", aform);
data.put("aentity", MetadataHelper.getEntityName(recordId));
}
data.putAll(new EditableFields(editableFields).buildForms(recordId, user));
}

return data;
}

private JSONArray formatUsers(Collection<ID> users) {
JSONArray array = new JSONArray();
for (ID u : users) {
array.add(new Object[] { u, UserHelper.getName(u) });
}
for (ID u : users) array.add(new Object[]{u, UserHelper.getName(u)});
return array;
}

Expand Down Expand Up @@ -227,13 +225,22 @@ public RespBody doApprove(HttpServletRequest request, @IdParam(name = "record")
String useGroup = post.getString("useGroup");

// 可编辑字段
JSONObject aformData = post.getJSONObject("aformData");
JSONArray aformData = post.getJSONArray("aformData");
Record addedRecord = null;
// v3.9 弱校验
final ID weakMode = getIdParameter(request, "weakMode");
if (aformData != null && aformData.size() > 1) {
if (CollectionUtils.isNotEmpty(aformData)) {
List<Record> details = new ArrayList<>();
try {
addedRecord = EntityHelper.parse(aformData, getRequestUser(request));
for (Object o : aformData) {
Record a = EntityHelper.parse((JSONObject) o, approver);
if (a.getEntity().getEntityCode().equals(recordId.getEntityCode())) addedRecord = a;
else details.add(a);
}

if (addedRecord == null) addedRecord = EntityHelper.forUpdate(recordId, approver);
if (!details.isEmpty()) addedRecord.setObjectValue(GeneralEntityService.HAS_DETAILS, details);

} catch (DataSpecificationException known) {
log.warn(">>>>> {}", known.getLocalizedMessage());
return RespBody.error(known.getLocalizedMessage());
Expand Down Expand Up @@ -349,12 +356,11 @@ public RespBody getFlowDefinition(@IdParam ID approvalId) {
return RespBody.errorl("无效审批流程,可能已被删除");
}

FlowDefinition def = RobotApprovalManager.instance
.getFlowDefinition(MetadataHelper.getEntity((String) belongEntity[0]), approvalId);

Entity applyEntity = MetadataHelper.getEntity((String) belongEntity[0]);
FlowDefinition def = RobotApprovalManager.instance.getFlowDefinition(applyEntity, approvalId);
JSONObject data = JSONUtils.toJSONObject(
new String[] { "applyEntity", "flowDefinition" },
new Object[] { belongEntity[0], def.getJSON("flowDefinition") });
new String[]{"applyEntity", "flowDefinition"},
new Object[]{applyEntity.getName(), def.getJSON("flowDefinition")});
return RespBody.ok(data);
}

Expand Down
14 changes: 7 additions & 7 deletions src/main/resources/web/admin/bizuser/role-privileges.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
margin-left: 15px;
margin-top: 2px;
font-size: 15px;
color: #999;
color: #999 !important;
display: none;
}
.table.table-priv tr:hover > td > a.cp,
Expand Down Expand Up @@ -174,29 +174,29 @@
<td class="name">
<a th:data-entity="${entity[1]}" th:data-name="${entity[0]}" th:title="${bundle.L('批量选择')}">[[${entity[2]}]]</a>
<span>
<a th:data-entity="${entity[1]}" th:title="${bundle.L('字段权限')}"><i class="mdi mdi-filter-variant-remove"></i></a>
<a th:data-entity="${entity[1]}" th:title="${bundle.L('字段权限')}"><i class="mdi mdi-filter-variant-plus"></i></a>
</span>
</td>
<td><i data-action="C" class="priv R0"></i><a></a></td>
<td>
<i data-action="R" class="priv R0"></i>
<a data-action="R9" class="cp" th:title="${bundle.L('自定义权限')}"><i class="mdi mdi-filter-cog-outline"></i></a>
<a data-action="R9" class="cp" th:title="${bundle.L('自定义权限')}"><i class="mdi mdi-filter-check-outline"></i></a>
</td>
<td>
<i data-action="U" class="priv R0"></i>
<a data-action="U9" class="cp" th:title="${bundle.L('自定义权限')}"><i class="mdi mdi-filter-cog-outline"></i></a>
<a data-action="U9" class="cp" th:title="${bundle.L('自定义权限')}"><i class="mdi mdi-filter-check-outline"></i></a>
</td>
<td>
<i data-action="D" class="priv R0"></i>
<a data-action="D9" class="cp" th:title="${bundle.L('自定义权限')}"><i class="mdi mdi-filter-cog-outline"></i></a>
<a data-action="D9" class="cp" th:title="${bundle.L('自定义权限')}"><i class="mdi mdi-filter-check-outline"></i></a>
</td>
<td>
<i data-action="A" class="priv R0"></i>
<a data-action="A9" class="cp" th:title="${bundle.L('自定义权限')}"><i class="mdi mdi-filter-cog-outline"></i></a>
<a data-action="A9" class="cp" th:title="${bundle.L('自定义权限')}"><i class="mdi mdi-filter-check-outline"></i></a>
</td>
<td>
<i data-action="S" class="priv R0"></i>
<a data-action="S9" class="cp" th:title="${bundle.L('自定义权限')}"><i class="mdi mdi-filter-cog-outline"></i></a>
<a data-action="S9" class="cp" th:title="${bundle.L('自定义权限')}"><i class="mdi mdi-filter-check-outline"></i></a>
</td>
</tr>
</tbody>
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/web/admin/metadata/entity-advanced.html
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ <h5 class="font-weight-bold">[[${bundle.L('卡片模式')}]]</h5>
</div>
<div>
<button type="button" class="btn btn-danger J_drop-confirm" disabled="disabled"><i class="zmdi zmdi-delete icon"></i> [[${bundle.L('确定')}]]</button>
<button type="button" class="btn btn-warning J_truncate-confirm ml-2 bosskey-show" disabled="disabled">
<i class="mdi mdi-flask-empty-remove icon"></i> [[${bundle.L('清空数据')}]]
</button>
<div class="alert alert-warning alert-icon hide col-sm-6 mb-0">
<div class="icon"><span class="zmdi zmdi-alert-triangle"></span></div>
<div class="message">[[${bundle.L('系统内置,不允许删除')}]]</div>
Expand Down
Loading

0 comments on commit e03c733

Please sign in to comment.