mirror of
https://github.com/getrebuild/rebuild.git
synced 2025-03-13 15:44:26 +08:00
Merge branch 'master' into develop
This commit is contained in:
commit
eb77a77f41
7 changed files with 84 additions and 24 deletions
|
@ -29,7 +29,6 @@ import com.rebuild.core.privileges.bizz.User;
|
|||
import com.rebuild.core.service.NoRecordFoundException;
|
||||
import com.rebuild.core.service.approval.ApprovalState;
|
||||
import com.rebuild.core.service.approval.RobotApprovalManager;
|
||||
import com.rebuild.core.service.general.EntityService;
|
||||
import com.rebuild.core.support.general.FieldValueHelper;
|
||||
import com.rebuild.core.support.i18n.Language;
|
||||
import com.rebuild.core.support.state.StateManager;
|
||||
|
@ -114,8 +113,7 @@ public class FormsBuilder extends FormsManager {
|
|||
ID mainId = FormBuilderContextHolder.getMainIdOfDetail();
|
||||
Assert.notNull(mainId, "Call `FormBuilderContextHolder#setMainIdOfDetail` first!");
|
||||
|
||||
approvalState = getHadApproval(entityMeta, null);
|
||||
|
||||
approvalState = EntityHelper.isUnsavedId(mainId) ? null : getHadApproval(mainEntity, mainId);
|
||||
if ((approvalState == ApprovalState.PROCESSING || approvalState == ApprovalState.APPROVED)) {
|
||||
return formatModelError(approvalState == ApprovalState.APPROVED
|
||||
? Language.L("主记录已完成审批,不能添加明细")
|
||||
|
@ -125,9 +123,11 @@ public class FormsBuilder extends FormsManager {
|
|||
// 明细无需审批
|
||||
approvalState = null;
|
||||
|
||||
if (!Application.getPrivilegesManager().allowUpdate(user, mainId)) {
|
||||
if (!EntityHelper.isUnsavedId(mainId)
|
||||
&& !Application.getPrivilegesManager().allowUpdate(user, mainId)) {
|
||||
return formatModelError(Language.L("你没有添加明细权限"));
|
||||
}
|
||||
|
||||
} else if (!Application.getPrivilegesManager().allowCreate(user, entityMeta.getEntityCode())) {
|
||||
return formatModelError(Language.L("你没有新建权限" ));
|
||||
} else {
|
||||
|
@ -225,23 +225,28 @@ public class FormsBuilder extends FormsManager {
|
|||
* @see RobotApprovalManager#hadApproval(Entity, ID)
|
||||
*/
|
||||
private ApprovalState getHadApproval(Entity entity, ID recordId) {
|
||||
Entity mainEntity = entity.getMainEntity();
|
||||
if (mainEntity == null) {
|
||||
// 新建时
|
||||
if (recordId == null) {
|
||||
return RobotApprovalManager.instance.hadApproval(entity, null);
|
||||
}
|
||||
|
||||
// 无明细实体
|
||||
if (entity.getMainEntity() == null) {
|
||||
return RobotApprovalManager.instance.hadApproval(entity, recordId);
|
||||
}
|
||||
|
||||
ID mainId = FormBuilderContextHolder.getMainIdOfDetail();
|
||||
if (mainId == null) {
|
||||
Field dtmField = MetadataHelper.getDetailToMainField(entity);
|
||||
String sql = String.format("select %s from %s where %s = ?",
|
||||
dtmField.getName(), entity.getName(), entity.getPrimaryField().getName());
|
||||
Object[] o = Application.createQueryNoFilter(sql).setParameter(1, recordId).unique();
|
||||
Object[] o = Application.getQueryFactory().uniqueNoFilter(recordId, dtmField.getName());
|
||||
if (o == null) {
|
||||
log.warn("No main-id found : {}", recordId);
|
||||
return null;
|
||||
}
|
||||
|
||||
mainId = (ID) o[0];
|
||||
}
|
||||
return RobotApprovalManager.instance.hadApproval(mainEntity, mainId);
|
||||
return RobotApprovalManager.instance.hadApproval(entity, mainId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -544,7 +549,7 @@ public class FormsBuilder extends FormsManager {
|
|||
else if (field.equals(DV_MAINID)) {
|
||||
Field dtmField = MetadataHelper.getDetailToMainField(entity);
|
||||
Object mixValue = inFormFields.contains(dtmField.getName()) ? getReferenceMixValue(value)
|
||||
: (DV_MAINID.equals(value) ? EntityService.UNSAVED_RECORD : value);
|
||||
: (DV_MAINID.equals(value) ? EntityHelper.UNSAVED_ID : value);
|
||||
if (mixValue != null) {
|
||||
initialValReady.put(dtmField.getName(), mixValue);
|
||||
initialValKeeps.add(dtmField.getName());
|
||||
|
@ -592,7 +597,7 @@ public class FormsBuilder extends FormsManager {
|
|||
*/
|
||||
private JSON getReferenceMixValue(String idValue) {
|
||||
if (DV_MAINID.equals(idValue)) {
|
||||
return FieldValueHelper.wrapMixValue(EntityService.UNSAVED_RECORD, Language.L("新的"));
|
||||
return FieldValueHelper.wrapMixValue(EntityHelper.UNSAVED_ID, Language.L("新的"));
|
||||
} else if (!ID.isId(idValue)) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,11 @@ import java.util.Date;
|
|||
*/
|
||||
public class EntityHelper {
|
||||
|
||||
// 虚拟 ID 后缀
|
||||
private static final String UNSAVED_ID_SUFFIX = "-0000000000000000";
|
||||
// 将新建的记录 ID
|
||||
public static final ID UNSAVED_ID = ID.valueOf("000" + UNSAVED_ID_SUFFIX);
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* @param user
|
||||
|
@ -154,6 +159,26 @@ public class EntityHelper {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 未保存记录 ID
|
||||
*
|
||||
* @param entityCode
|
||||
* @return
|
||||
* @see #isUnsavedId(ID)
|
||||
*/
|
||||
public static ID newUnsavedId(int entityCode) {
|
||||
if (entityCode == 0) return UNSAVED_ID;
|
||||
return ID.valueOf(String.format("%03d", entityCode) + UNSAVED_ID_SUFFIX);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public static boolean isUnsavedId(ID id) {
|
||||
return UNSAVED_ID.equals(id) || id.toLiteral().endsWith(UNSAVED_ID_SUFFIX);
|
||||
}
|
||||
|
||||
// 公共字段/保留字段
|
||||
|
||||
public static final String CreatedOn = "createdOn";
|
||||
|
|
|
@ -44,7 +44,7 @@ public class ApprovalStepService extends InternalPersistService {
|
|||
/**
|
||||
* 虚拟审批
|
||||
*/
|
||||
public static final ID APPROVAL_NOID = ID.valueOf("028-0000000000000000");
|
||||
public static final ID APPROVAL_NOID = EntityHelper.newUnsavedId(28);
|
||||
|
||||
protected ApprovalStepService(PersistManagerFactory aPMFactory) {
|
||||
super(aPMFactory);
|
||||
|
|
|
@ -26,7 +26,7 @@ import java.util.List;
|
|||
public interface EntityService extends ServiceSpec {
|
||||
|
||||
// 将新建的记录 ID
|
||||
ID UNSAVED_RECORD = ID.valueOf("000-0000000000000000");
|
||||
|
||||
|
||||
/**
|
||||
* 取消共享,跟随共享权限
|
||||
|
|
|
@ -20,6 +20,7 @@ import com.rebuild.core.configuration.general.FormBuilderContextHolder;
|
|||
import com.rebuild.core.configuration.general.FormsBuilder;
|
||||
import com.rebuild.core.configuration.general.TransformManager;
|
||||
import com.rebuild.core.configuration.general.ViewAddonsManager;
|
||||
import com.rebuild.core.metadata.EntityHelper;
|
||||
import com.rebuild.core.metadata.MetadataHelper;
|
||||
import com.rebuild.core.privileges.UserHelper;
|
||||
import com.rebuild.core.support.ConfigurationItem;
|
||||
|
@ -37,7 +38,9 @@ import org.springframework.web.servlet.ModelAndView;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 表单/视图
|
||||
|
@ -113,7 +116,7 @@ public class GeneralModelController extends EntityController {
|
|||
}
|
||||
// v2.8
|
||||
else if (FormsBuilder.DV_MAINID.equals(mainid)) {
|
||||
ID fakeMainid = ID.newId(metaEntity.getMainEntity().getEntityCode());
|
||||
ID fakeMainid = EntityHelper.newUnsavedId(metaEntity.getMainEntity().getEntityCode());
|
||||
FormBuilderContextHolder.setMainIdOfDetail(fakeMainid);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,11 @@ button {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
a[disabled],
|
||||
button[disabled] {
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
/* 1280 */
|
||||
.container-smart {
|
||||
max-width: 1160px;
|
||||
|
@ -1186,7 +1191,8 @@ select.form-control:not([disabled]) {
|
|||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.col-form-label.required::after {
|
||||
.col-form-label.required::after,
|
||||
.protable thead > tr > th.required::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
|
@ -1196,6 +1202,10 @@ select.form-control:not([disabled]) {
|
|||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.protable thead > tr > th.required::after {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.form-text {
|
||||
color: #878787;
|
||||
line-height: 1.41;
|
||||
|
|
|
@ -18,8 +18,16 @@ class ProTable extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const formFields = this.state.formFields || []
|
||||
const details = this.state.details || []
|
||||
if (this.state.hasError) {
|
||||
$('.detail-form-table .btn-group .btn').attr('disabled', true)
|
||||
return <RbAlertBox message={this.state.hasError} />
|
||||
}
|
||||
|
||||
// 等待初始化
|
||||
if (!this.state.formFields) return null
|
||||
|
||||
const formFields = this.state.formFields
|
||||
const details = this.state.details || [] // 编辑时有
|
||||
|
||||
// fixed 模式大概 5 个字段
|
||||
const ww = $(window).width()
|
||||
|
@ -35,8 +43,9 @@ class ProTable extends React.Component {
|
|||
<tr>
|
||||
<th className="col-index" />
|
||||
{formFields.map((item) => {
|
||||
if (item.field === TYPE_DIVIDER) return null
|
||||
return (
|
||||
<th key={item.field} data-field={item.field} style={colStyles}>
|
||||
<th key={item.field} data-field={item.field} style={colStyles} className={item.nullable ? '' : 'required'}>
|
||||
{item.label}
|
||||
<i className="dividing hide" />
|
||||
</th>
|
||||
|
@ -46,12 +55,12 @@ class ProTable extends React.Component {
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{(this.state.inlineForms || []).map((form, idx) => {
|
||||
const key = form.key
|
||||
{(this.state.inlineForms || []).map((FORM, idx) => {
|
||||
const key = FORM.key
|
||||
return (
|
||||
<tr key={`inline-${key}`}>
|
||||
<th className="col-index">{details.length + idx + 1}</th>
|
||||
{form}
|
||||
{FORM}
|
||||
|
||||
<td className={`col-action ${fixed && 'column-fixed'}`}>
|
||||
<button className="btn btn-light hide" title={$L('编辑')} onClick={() => this.editLine(key)}>
|
||||
|
@ -77,6 +86,13 @@ class ProTable extends React.Component {
|
|||
}
|
||||
|
||||
$.post(`/app/${entity.entity}/form-model?id=`, JSON.stringify(initialValue), (res) => {
|
||||
// 包含错误
|
||||
if (res.error_code > 0 || !!res.data.error) {
|
||||
const error = (res.data || {}).error || res.error_msg
|
||||
this.setState({ hasError: error })
|
||||
return
|
||||
}
|
||||
|
||||
this._initModel = res.data // 新建用
|
||||
this.setState({ formFields: res.data.elements }, () => {
|
||||
$(this._$scroller).perfectScrollbar()
|
||||
|
@ -177,7 +193,8 @@ class InlineForm extends RbForm {
|
|||
return (
|
||||
<React.Fragment>
|
||||
{this.props.children.map((fieldComp) => {
|
||||
const refid = fieldComp.props.field === TYPE_DIVIDER ? null : `fieldcomp-${fieldComp.props.field}`
|
||||
if (fieldComp.props.field === TYPE_DIVIDER) return null
|
||||
const refid = `fieldcomp-${fieldComp.props.field}`
|
||||
return (
|
||||
<td key={`td-${refid}`} ref={(c) => (this._$ref = c)}>
|
||||
{React.cloneElement(fieldComp, { $$$parent: this, ref: refid })}
|
||||
|
|
Loading…
Reference in a new issue