Merge pull request #169 from getrebuild/api-metadata-587

RB-587 Api metadata
This commit is contained in:
RB 2020-05-15 01:50:37 +08:00 committed by GitHub
commit 93fa38191f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 734 additions and 592 deletions

1
.gitignore vendored
View file

@ -42,3 +42,4 @@ rebuild.iml
.DS_Store .DS_Store
node_modules node_modules
test.*

View file

@ -9,7 +9,7 @@
"url": "https://github.com/getrebuild/rebuild.git" "url": "https://github.com/getrebuild/rebuild.git"
}, },
"scripts": { "scripts": {
"lint": "eslint --ext .jsx,.js ./src/main/webapp/assets/js &" "lint": "eslint --ext .jsx,.js src/main/webapp/assets/js &"
}, },
"devDependencies": { "devDependencies": {
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",

View file

@ -127,7 +127,7 @@
<dependency> <dependency>
<groupId>com.github.devezhao</groupId> <groupId>com.github.devezhao</groupId>
<artifactId>persist4j</artifactId> <artifactId>persist4j</artifactId>
<version>3aa38dabbd</version> <version>1beaf8f565</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>

View file

@ -0,0 +1,97 @@
/*
Copyright (c) REBUILD <https://getrebuild.com/> and 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.api.metadata;
import cn.devezhao.persist4j.Field;
import cn.devezhao.persist4j.engine.ID;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rebuild.api.ApiContext;
import com.rebuild.api.ApiInvokeException;
import com.rebuild.api.BaseApi;
import com.rebuild.server.Application;
import com.rebuild.server.configuration.portals.ClassificationManager;
import com.rebuild.server.metadata.MetadataHelper;
import com.rebuild.server.metadata.entity.DisplayType;
import com.rebuild.server.metadata.entity.EasyMeta;
import com.rebuild.utils.JSONUtils;
/**
* 分类数据
*
* @author devezhao
* @since 2020/5/14
*/
public class ClassificationData extends BaseApi {
private ID dataId;
private int openLevel;
@Override
protected String getApiName() {
return "metadata/classification-data";
}
@Override
public JSON execute(ApiContext context) throws ApiInvokeException {
String entity = context.getParameterNotBlank("entity");
String field = context.getParameterNotBlank("field");
Field thatField = MetadataHelper.getField(entity, field);
if (EasyMeta.getDisplayType(thatField) != DisplayType.CLASSIFICATION) {
return formatFailure("None CLASSIFICATION field : " + entity + "." + field);
}
dataId = ClassificationManager.instance.getUseClassification(thatField, true);
if (dataId == null) {
return formatFailure("Bad CLASSIFICATION field : " + entity + "." + field);
}
openLevel = ClassificationManager.instance.getOpenLevel(thatField);
Object[][] array = Application.createQueryNoFilter(
"select itemId,name from ClassificationData where level = 0 and dataId = ?")
.setParameter(1, dataId)
.array();
JSONArray dest = new JSONArray();
for (Object[] o : array) {
JSONObject item = buildItem(o);
appendChildren((ID) o[0], item, 1);
dest.add(item);
}
return formatSuccess(dest);
}
private void appendChildren(ID itemId, JSONObject into, int level) {
if (level > openLevel) {
return;
}
Object[][] array = Application.createQueryNoFilter(
"select itemId,name from ClassificationData where dataId = ? and parent = ?")
.setParameter(1, dataId)
.setParameter(2, itemId)
.array();
JSONArray children = new JSONArray();
for (Object[] o : array) {
JSONObject item = buildItem(o);
appendChildren((ID) o[0], item, level + 1);
children.add(item);
}
into.put("children", children);
}
private JSONObject buildItem(Object[] o) {
return JSONUtils.toJSONObject(
new String[] { "id", "text" },
new Object[] { o[0], o[1] });
}
}

View file

@ -0,0 +1,61 @@
/*
Copyright (c) REBUILD <https://getrebuild.com/> and 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.api.metadata;
import cn.devezhao.persist4j.Entity;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rebuild.api.ApiContext;
import com.rebuild.api.ApiInvokeException;
import com.rebuild.api.BaseApi;
import com.rebuild.server.metadata.MetadataSorter;
import com.rebuild.server.metadata.entity.EasyMeta;
/**
* 获取实体列表
*
* @author devezhao
* @since 2020/5/14
*/
public class EntityList extends BaseApi {
@Override
protected String getApiName() {
return "metadata/entities";
}
@Override
public JSON execute(ApiContext context) throws ApiInvokeException {
JSONArray array = new JSONArray();
for (Entity e : MetadataSorter.sortEntities()) {
array.add(buildEntity(e));
}
return formatSuccess(array);
}
private JSONObject buildEntity(Entity entity) {
JSONObject o = new JSONObject();
o.put("type_code", entity.getEntityCode());
o.put("entity_name", entity.getName());
o.put("entity_label", EasyMeta.getLabel(entity));
o.put("creatable", entity.isCreatable());
o.put("updatable", entity.isUpdatable());
o.put("queryable", entity.isQueryable());
o.put("deletable", entity.isDeletable());
if (entity.getMasterEntity() != null) {
o.put("master_entity", entity.getMasterEntity().getName());
}
if (entity.getSlaveEntity() != null) {
o.put("slave_entity", entity.getSlaveEntity().getName());
}
return o;
}
}

View file

@ -0,0 +1,83 @@
/*
Copyright (c) REBUILD <https://getrebuild.com/> and 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.api.metadata;
import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.Field;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rebuild.api.ApiContext;
import com.rebuild.api.ApiInvokeException;
import com.rebuild.api.BaseApi;
import com.rebuild.server.configuration.portals.ClassificationManager;
import com.rebuild.server.configuration.portals.MultiSelectManager;
import com.rebuild.server.configuration.portals.PickListManager;
import com.rebuild.server.metadata.MetadataHelper;
import com.rebuild.server.metadata.entity.DisplayType;
import com.rebuild.server.metadata.entity.EasyMeta;
/**
* 获取字段列表
*
* @author devezhao
* @since 2020/5/14
*/
public class FieldList extends BaseApi {
@Override
protected String getApiName() {
return "metadata/fields";
}
@Override
public JSON execute(ApiContext context) throws ApiInvokeException {
String entity = context.getParameterNotBlank("entity");
Entity thatEntity = MetadataHelper.getEntity(entity);
JSONArray array = new JSONArray();
for (Field field : thatEntity.getFields()) {
if (MetadataHelper.isSystemField(field) || !field.isQueryable()) {
continue;
}
array.add(buildField(field));
}
return formatSuccess(array);
}
private JSONObject buildField(Field field) {
final EasyMeta easyMeta = EasyMeta.valueOf(field);
final DisplayType dt = easyMeta.getDisplayType();
JSONObject o = new JSONObject();
o.put("field_name", field.getName());
o.put("field_label", easyMeta.getLabel());
o.put("display_type", dt.name());
o.put("creatable", field.isCreatable());
o.put("updatable", field.isUpdatable());
o.put("nullable", field.isNullable());
o.put("repeatable", field.isRepeatable());
o.put("queryable", field.isQueryable());
if (dt == DisplayType.REFERENCE) {
o.put("reference_entity", field.getReferenceEntity().getName());
}
if (dt == DisplayType.CLASSIFICATION) {
o.put("use_classification", ClassificationManager.instance.getUseClassification(field, true));
}
if (dt == DisplayType.MULTISELECT) {
o.put("options", MultiSelectManager.instance.getSelectList(field));
}
if (dt == DisplayType.PICKLIST) {
o.put("options", PickListManager.instance.getPickList(field));
}
return o;
}
}

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server; package com.rebuild.server;
@ -49,6 +38,7 @@ import java.util.List;
*/ */
public final class ServerStatus { public final class ServerStatus {
private static long LastCheckTime = 0;
private static final List<Status> LAST_STATUS = new ArrayList<>(); private static final List<Status> LAST_STATUS = new ArrayList<>();
/** /**
@ -57,6 +47,11 @@ public final class ServerStatus {
* @return * @return
*/ */
public static List<Status> getLastStatus() { public static List<Status> getLastStatus() {
// 60 秒缓存
if (System.currentTimeMillis() - LastCheckTime > 60 * 1000) {
checkAll();
}
synchronized (LAST_STATUS) { synchronized (LAST_STATUS) {
return Collections.unmodifiableList(LAST_STATUS); return Collections.unmodifiableList(LAST_STATUS);
} }
@ -92,7 +87,8 @@ public final class ServerStatus {
LAST_STATUS.clear(); LAST_STATUS.clear();
LAST_STATUS.addAll(last); LAST_STATUS.addAll(last);
} }
return isStatusOK(); LastCheckTime = System.currentTimeMillis();
return isStatusOK();
} }
/** /**

View file

@ -159,7 +159,7 @@ public class MetaSchemaGenerator {
schemaField.put("items", performPickList(field)); schemaField.put("items", performPickList(field));
} }
JSONObject extConfig = easyField.getFieldExtConfig(); JSONObject extConfig = easyField.getExtraAttrs(true);
if (!extConfig.isEmpty()) { if (!extConfig.isEmpty()) {
schemaField.put("extConfig", extConfig); schemaField.put("extConfig", extConfig);
} }

View file

@ -135,7 +135,9 @@ public class MetaschemaImporter extends HeavyTask<String> {
} }
for (Object[] picklist : picklistHolders) { for (Object[] picklist : picklistHolders) {
Application.getBean(PickListService.class).updateBatch((Field) picklist[0], (JSONObject) picklist[1]); Field refreshField = (Field) picklist[0];
refreshField = MetadataHelper.getField(refreshField.getOwnEntity().getName(), refreshField.getName());
Application.getBean(PickListService.class).updateBatch(refreshField, (JSONObject) picklist[1]);
} }
setCompleted(100); setCompleted(100);

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server.business.series; package com.rebuild.server.business.series;
@ -45,7 +34,7 @@ public class SeriesGenerator {
*/ */
public SeriesGenerator(EasyMeta field) { public SeriesGenerator(EasyMeta field) {
this.field = (Field) field.getBaseMeta(); this.field = (Field) field.getBaseMeta();
this.config = field.getFieldExtConfig(); this.config = field.getExtraAttrs(true);
} }
/** /**
@ -73,7 +62,7 @@ public class SeriesGenerator {
return seriesFormat; return seriesFormat;
} }
private static final Pattern VAR_PATTERN = Pattern.compile("\\{(\\w+)\\}"); private static final Pattern VAR_PATTERN = Pattern.compile("\\{(\\w+)}");
/** /**
* @param format * @param format
* @return * @return

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server.business.series; package com.rebuild.server.business.series;
@ -24,6 +13,7 @@ import cn.devezhao.persist4j.Field;
import com.rebuild.server.metadata.MetadataHelper; import com.rebuild.server.metadata.MetadataHelper;
import com.rebuild.server.metadata.entity.DisplayType; import com.rebuild.server.metadata.entity.DisplayType;
import com.rebuild.server.metadata.entity.EasyMeta; import com.rebuild.server.metadata.entity.EasyMeta;
import com.rebuild.server.metadata.entity.FieldExtConfigProps;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionContext;
@ -60,7 +50,7 @@ public class SeriesZeroResetJob extends QuartzJobBean {
for (Field field : entity.getFields()) { for (Field field : entity.getFields()) {
EasyMeta easy = EasyMeta.valueOf(field); EasyMeta easy = EasyMeta.valueOf(field);
if (easy.getDisplayType() == DisplayType.SERIES) { if (easy.getDisplayType() == DisplayType.SERIES) {
String zeroFlag = easy.getFieldExtConfig().getString("seriesZero"); String zeroFlag = easy.getExtraAttr(FieldExtConfigProps.SERIES_SERIESZERO);
if ("D".equalsIgnoreCase(zeroFlag)) { if ("D".equalsIgnoreCase(zeroFlag)) {
SeriesGeneratorFactory.zero(field); SeriesGeneratorFactory.zero(field);
LOG.info("Zero field by [D] : " + field); LOG.info("Zero field by [D] : " + field);

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2019 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server.configuration.portals; package com.rebuild.server.configuration.portals;
@ -24,6 +13,7 @@ import com.rebuild.server.Application;
import com.rebuild.server.configuration.ConfigManager; import com.rebuild.server.configuration.ConfigManager;
import com.rebuild.server.metadata.EntityHelper; import com.rebuild.server.metadata.EntityHelper;
import com.rebuild.server.metadata.entity.EasyMeta; import com.rebuild.server.metadata.entity.EasyMeta;
import com.rebuild.server.metadata.entity.FieldExtConfigProps;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -152,7 +142,7 @@ public class ClassificationManager implements ConfigManager<ID> {
* @return * @return
*/ */
public ID getUseClassification(Field field, boolean verfiy) { public ID getUseClassification(Field field, boolean verfiy) {
String use = EasyMeta.valueOf(field).getFieldExtConfig().getString("classification"); String use = EasyMeta.valueOf(field).getExtraAttr(FieldExtConfigProps.CLASSIFICATION_USE);
ID dataId = ID.isId(use) ? ID.valueOf(use) : null; ID dataId = ID.isId(use) ? ID.valueOf(use) : null;
if (dataId == null) { if (dataId == null) {
LOG.error("Field [ " + field + " ] unconfig classification"); LOG.error("Field [ " + field + " ] unconfig classification");

View file

@ -64,7 +64,7 @@ public class FieldPortalAttrs {
* @return * @return
*/ */
public boolean allowDataList(Field field) { public boolean allowDataList(Field field) {
return !disallowAll(field) && !isPasswd(field); return !disallowAll(field) && field.isQueryable();
} }
/** /**
@ -72,7 +72,7 @@ public class FieldPortalAttrs {
* @return * @return
*/ */
public boolean allowSearch(Field field) { public boolean allowSearch(Field field) {
return !disallowAll(field) && !isPasswd(field); return !disallowAll(field) && field.isQueryable();
} }
/** /**
@ -84,13 +84,4 @@ public class FieldPortalAttrs {
return field.getType() == FieldType.ANY_REFERENCE return field.getType() == FieldType.ANY_REFERENCE
|| EntityHelper.ApprovalStepNode.equalsIgnoreCase(fieldName); || EntityHelper.ApprovalStepNode.equalsIgnoreCase(fieldName);
} }
/**
* @param field
* @return
*/
private boolean isPasswd(Field field) {
String fieldName = field.getName();
return fieldName.contains("password") || fieldName.contains("passwd");
}
} }

View file

@ -22,6 +22,7 @@ import com.rebuild.server.metadata.EntityHelper;
import com.rebuild.server.metadata.MetadataHelper; import com.rebuild.server.metadata.MetadataHelper;
import com.rebuild.server.metadata.entity.DisplayType; import com.rebuild.server.metadata.entity.DisplayType;
import com.rebuild.server.metadata.entity.EasyMeta; import com.rebuild.server.metadata.entity.EasyMeta;
import com.rebuild.server.metadata.entity.FieldExtConfigProps;
import com.rebuild.utils.JSONUtils; import com.rebuild.utils.JSONUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
@ -139,7 +140,7 @@ public class FieldValueWrapper {
* @return * @return
*/ */
public String wrapDate(Object value, EasyMeta field) { public String wrapDate(Object value, EasyMeta field) {
String format = field.getFieldExtConfig().getString("dateFormat"); String format = field.getExtraAttr(FieldExtConfigProps.DATE_DATEFORMAT);
format = StringUtils.defaultIfEmpty(format, field.getDisplayType().getDefaultFormat()); format = StringUtils.defaultIfEmpty(format, field.getDisplayType().getDefaultFormat());
return CalendarUtils.getDateFormat(format).format(value); return CalendarUtils.getDateFormat(format).format(value);
} }
@ -150,7 +151,7 @@ public class FieldValueWrapper {
* @return * @return
*/ */
public String wrapDatetime(Object value, EasyMeta field) { public String wrapDatetime(Object value, EasyMeta field) {
String format = field.getFieldExtConfig().getString("datetimeFormat"); String format = field.getExtraAttr(FieldExtConfigProps.DATETIME_DATEFORMAT);
format = StringUtils.defaultIfEmpty(format, field.getDisplayType().getDefaultFormat()); format = StringUtils.defaultIfEmpty(format, field.getDisplayType().getDefaultFormat());
return CalendarUtils.getDateFormat(format).format(value); return CalendarUtils.getDateFormat(format).format(value);
} }
@ -161,7 +162,7 @@ public class FieldValueWrapper {
* @return * @return
*/ */
public String wrapNumber(Object value, EasyMeta field) { public String wrapNumber(Object value, EasyMeta field) {
String format = field.getFieldExtConfig().getString("numberFormat"); String format = field.getExtraAttr(FieldExtConfigProps.NUMBER_FORMAT);
format = StringUtils.defaultIfEmpty(format, field.getDisplayType().getDefaultFormat()); format = StringUtils.defaultIfEmpty(format, field.getDisplayType().getDefaultFormat());
return new DecimalFormat(format).format(value); return new DecimalFormat(format).format(value);
} }
@ -172,7 +173,7 @@ public class FieldValueWrapper {
* @return * @return
*/ */
public String wrapDecimal(Object value, EasyMeta field) { public String wrapDecimal(Object value, EasyMeta field) {
String format = field.getFieldExtConfig().getString("decimalFormat"); String format = field.getExtraAttr(FieldExtConfigProps.DECIMAL_FORMAT);
format = StringUtils.defaultIfEmpty(format, field.getDisplayType().getDefaultFormat()); format = StringUtils.defaultIfEmpty(format, field.getDisplayType().getDefaultFormat());
return new DecimalFormat(format).format(value); return new DecimalFormat(format).format(value);
} }
@ -187,10 +188,12 @@ public class FieldValueWrapper {
Object text = ((ID) value).getLabelRaw(); Object text = ((ID) value).getLabelRaw();
if (text == null) { if (text == null) {
text = getLabelNotry((ID) value); text = getLabelNotry((ID) value);
} else { } else {
Field nameField = ((Field) field.getBaseMeta()).getReferenceEntity().getNameField(); Field nameField = ((Field) field.getBaseMeta()).getReferenceEntity().getNameField();
text = instance.wrapFieldValue(text, nameField, true); text = instance.wrapFieldValue(text, nameField, true);
} }
return wrapMixValue((ID) value, text == null ? null : text.toString()); return wrapMixValue((ID) value, text == null ? null : text.toString());
} }
@ -219,7 +222,7 @@ public class FieldValueWrapper {
* @return * @return
*/ */
public String wrapState(Object value, EasyMeta field) { public String wrapState(Object value, EasyMeta field) {
String stateClass = field.getFieldExtConfig().getString("stateClass"); String stateClass = field.getExtraAttr(FieldExtConfigProps.STATE_STATECLASS);
return StateHelper.valueOf(stateClass, (Integer) value).getName(); return StateHelper.valueOf(stateClass, (Integer) value).getName();
} }
@ -280,21 +283,19 @@ public class FieldValueWrapper {
* @return * @return
*/ */
protected Object wrapSpecialField(Object value, EasyMeta field) { protected Object wrapSpecialField(Object value, EasyMeta field) {
String fieldName = field.getName().toLowerCase(); if (!field.isQueryable()) {
// 密码型字段返回
if (fieldName.contains("password") || fieldName.contains("passwd")) {
return "******"; return "******";
} }
// 审批 // 审批
if (fieldName.equalsIgnoreCase(EntityHelper.ApprovalState)) { if (field.getName().equalsIgnoreCase(EntityHelper.ApprovalState)) {
if (value == null) { if (value == null) {
return ApprovalState.DRAFT.getName(); return ApprovalState.DRAFT.getName();
} else { } else {
return ApprovalState.valueOf((Integer) value).getName(); return ApprovalState.valueOf((Integer) value).getName();
} }
} else if (fieldName.equalsIgnoreCase(EntityHelper.ApprovalId) && value == null) {
} else if (field.getName().equalsIgnoreCase(EntityHelper.ApprovalId) && value == null) {
return wrapMixValue(null, APPROVAL_UNSUBMITTED); return wrapMixValue(null, APPROVAL_UNSUBMITTED);
} }

View file

@ -39,7 +39,6 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Set; import java.util.Set;
/** /**
@ -242,9 +241,9 @@ public class FormsBuilder extends FormsManager {
ID masterRecordId = MASTERID4NEWSLAVE.get(); ID masterRecordId = MASTERID4NEWSLAVE.get();
if (masterRecordId == null) { if (masterRecordId == null) {
Field stm = MetadataHelper.getSlaveToMasterField(entity); Field stmField = MetadataHelper.getSlaveToMasterField(entity);
String sql = String.format("select %s from %s where %s = ?", String sql = String.format("select %s from %s where %s = ?",
Objects.requireNonNull(stm).getName(), entity.getName(), entity.getPrimaryField().getName()); stmField.getName(), entity.getName(), entity.getPrimaryField().getName());
Object[] o = Application.createQueryNoFilter(sql).setParameter(1, recordId).unique(); Object[] o = Application.createQueryNoFilter(sql).setParameter(1, recordId).unique();
if (o == null) { if (o == null) {
return null; return null;
@ -303,7 +302,7 @@ public class FormsBuilder extends FormsManager {
} }
// 字段扩展配置 FieldExtConfigProps // 字段扩展配置 FieldExtConfigProps
JSONObject fieldExt = easyField.getFieldExtConfig(); JSONObject fieldExt = easyField.getExtraAttrs(true);
for (Map.Entry<String, Object> e : fieldExt.entrySet()) { for (Map.Entry<String, Object> e : fieldExt.entrySet()) {
el.put(e.getKey(), e.getValue()); el.put(e.getKey(), e.getValue());
} }
@ -529,7 +528,7 @@ public class FormsBuilder extends FormsManager {
// 主实体字段 // 主实体字段
else if (field.equals(DV_MASTER)) { else if (field.equals(DV_MASTER)) {
Field stmField = MetadataHelper.getSlaveToMasterField(entity); Field stmField = MetadataHelper.getSlaveToMasterField(entity);
Object mixValue = inFormFields.contains(Objects.requireNonNull(stmField).getName()) ? readyReferenceValue(value) : value; Object mixValue = inFormFields.contains(stmField.getName()) ? readyReferenceValue(value) : value;
if (mixValue != null) { if (mixValue != null) {
initialValReady.put(stmField.getName(), mixValue); initialValReady.put(stmField.getName(), mixValue);
initialValKeeps.add(stmField.getName()); initialValKeeps.add(stmField.getName());

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2018-2019 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server.configuration.portals; package com.rebuild.server.configuration.portals;
@ -46,8 +35,7 @@ public class MultiSelectManager extends PickListManager {
public JSONArray getSelectList(Field field) { public JSONArray getSelectList(Field field) {
ConfigEntry[] entries = getPickListRaw(field, false); ConfigEntry[] entries = getPickListRaw(field, false);
for (ConfigEntry e : entries) { for (ConfigEntry e : entries) {
e.set("hide", null); e.set("hide", null).set("id", null);
e.set("id", null);
} }
return JSONUtils.toJSONArray(entries); return JSONUtils.toJSONArray(entries);
} }

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server.helper.cache; package com.rebuild.server.helper.cache;
@ -76,8 +65,8 @@ public class RecordOwningCache extends BaseCacheTemplate<ID> {
String sql = "select owningUser from %s where %s = '%s'"; String sql = "select owningUser from %s where %s = '%s'";
// 使用主记录 // 使用主记录
if (useMaster != null) { if (useMaster != null) {
Field stm = MetadataHelper.getSlaveToMasterField(entity); Field stmField = MetadataHelper.getSlaveToMasterField(entity);
sql = sql.replaceFirst("owningUser", stm.getName() + ".owningUser"); sql = sql.replaceFirst("owningUser", stmField.getName() + ".owningUser");
} }
sql = String.format(sql, entity.getName(), entity.getPrimaryField().getName(), record.toLiteral()); sql = String.format(sql, entity.getName(), entity.getPrimaryField().getName(), record.toLiteral());

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2018-2019 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server.helper.state; package com.rebuild.server.helper.state;
@ -22,6 +11,7 @@ import cn.devezhao.persist4j.Field;
import com.rebuild.server.business.approval.ApprovalState; import com.rebuild.server.business.approval.ApprovalState;
import com.rebuild.server.metadata.EntityHelper; import com.rebuild.server.metadata.EntityHelper;
import com.rebuild.server.metadata.entity.EasyMeta; import com.rebuild.server.metadata.entity.EasyMeta;
import com.rebuild.server.metadata.entity.FieldExtConfigProps;
import org.apache.commons.lang.ClassUtils; import org.apache.commons.lang.ClassUtils;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -58,7 +48,7 @@ public class StateHelper {
return ApprovalState.class; return ApprovalState.class;
} }
String stateClass = new EasyMeta(stateField).getFieldExtConfig().getString("stateClass"); String stateClass = new EasyMeta(stateField).getExtraAttr(FieldExtConfigProps.STATE_STATECLASS);
return getSatetClass(stateClass); return getSatetClass(stateClass);
} }
@ -72,7 +62,7 @@ public class StateHelper {
public static Class<?> getSatetClass(String stateClass) throws IllegalArgumentException { public static Class<?> getSatetClass(String stateClass) throws IllegalArgumentException {
Assert.notNull(stateClass, "[stateClass] not be null"); Assert.notNull(stateClass, "[stateClass] not be null");
Class<?> stateEnum = null; Class<?> stateEnum;
try { try {
stateEnum = ClassUtils.getClass(stateClass); stateEnum = ClassUtils.getClass(stateClass);
if (stateEnum.isEnum() && ClassUtils.isAssignable(stateEnum, StateSpec.class)) { if (stateEnum.isEnum() && ClassUtils.isAssignable(stateEnum, StateSpec.class)) {

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2019 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server.helper.state; package com.rebuild.server.helper.state;
@ -25,6 +14,7 @@ import com.rebuild.server.Application;
import com.rebuild.server.business.approval.ApprovalState; import com.rebuild.server.business.approval.ApprovalState;
import com.rebuild.server.metadata.EntityHelper; import com.rebuild.server.metadata.EntityHelper;
import com.rebuild.server.metadata.entity.EasyMeta; import com.rebuild.server.metadata.entity.EasyMeta;
import com.rebuild.server.metadata.entity.FieldExtConfigProps;
import com.rebuild.utils.JSONUtils; import com.rebuild.utils.JSONUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
@ -48,7 +38,7 @@ public class StateManager {
if (EntityHelper.ApprovalState.equalsIgnoreCase(stateField.getName())) { if (EntityHelper.ApprovalState.equalsIgnoreCase(stateField.getName())) {
stateClass = ApprovalState.class.getName(); stateClass = ApprovalState.class.getName();
} else { } else {
stateClass = EasyMeta.valueOf(stateField).getFieldExtConfig().getString("stateClass"); stateClass = EasyMeta.valueOf(stateField).getExtraAttr(FieldExtConfigProps.STATE_STATECLASS);
} }
return getStateOptions(stateClass); return getStateOptions(stateClass);
} }

View file

@ -7,21 +7,20 @@ See LICENSE and COMMERCIAL in the project root for license information.
package com.rebuild.server.metadata; package com.rebuild.server.metadata;
import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.Field;
import cn.devezhao.persist4j.dialect.Dialect; import cn.devezhao.persist4j.dialect.Dialect;
import cn.devezhao.persist4j.metadata.impl.ConfigurationMetadataFactory; import cn.devezhao.persist4j.metadata.impl.ConfigurationMetadataFactory;
import cn.devezhao.persist4j.util.XmlHelper; import cn.devezhao.persist4j.util.XmlHelper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.rebuild.server.Application; import com.rebuild.server.Application;
import com.rebuild.server.metadata.entity.DisplayType; import com.rebuild.server.metadata.entity.DisplayType;
import org.apache.commons.collections4.map.CaseInsensitiveMap; import com.rebuild.utils.JSONUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.Element; import org.dom4j.Element;
import java.util.Map;
/** /**
* @author zhaofang123@gmail.com * @author zhaofang123@gmail.com
* @since 08/04/2018 * @since 08/04/2018
@ -31,11 +30,6 @@ public class DynamicMetadataFactory extends ConfigurationMetadataFactory {
private static final Log LOG = LogFactory.getLog(DynamicMetadataFactory.class); private static final Log LOG = LogFactory.getLog(DynamicMetadataFactory.class);
// <Name, [ID, COMMENTS, ICON]>
private static final Map<String, Object[]> ENTITY_EXTMETA = new CaseInsensitiveMap<>();
// <Name, [ID, COMMENTS]>
private static final Map<String, Object[]> FIELD_EXTMETA = new CaseInsensitiveMap<>();
public DynamicMetadataFactory(String configLocation, Dialect dialect) { public DynamicMetadataFactory(String configLocation, Dialect dialect) {
super(configLocation, dialect); super(configLocation, dialect);
} }
@ -57,84 +51,84 @@ public class DynamicMetadataFactory extends ConfigurationMetadataFactory {
private void appendConfig4Db(Document config) { private void appendConfig4Db(Document config) {
final Element rootElement = config.getRootElement(); final Element rootElement = config.getRootElement();
ENTITY_EXTMETA.clear(); Object[][] customEntities = Application.createQueryNoFilter(
FIELD_EXTMETA.clear();
Object[][] customEntity = Application.createQueryNoFilter(
"select typeCode,entityName,physicalName,entityLabel,entityId,comments,icon,nameField,masterEntity from MetaEntity") "select typeCode,entityName,physicalName,entityLabel,entityId,comments,icon,nameField,masterEntity from MetaEntity")
.array(); .array();
for (Object[] custom : customEntity) { for (Object[] c : customEntities) {
String name = (String) custom[1]; String name = (String) c[1];
Element entity = rootElement.addElement("entity"); Element entity = rootElement.addElement("entity");
entity.addAttribute("type-code", custom[0].toString()) entity.addAttribute("type-code", c[0].toString())
.addAttribute("name", name) .addAttribute("name", name)
.addAttribute("physical-name", (String) custom[2]) .addAttribute("physical-name", (String) c[2])
.addAttribute("description", (String) custom[3]) .addAttribute("description", (String) c[3])
.addAttribute("parent", "false") .addAttribute("parent", "false")
.addAttribute("name-field", (String) custom[7]) .addAttribute("name-field", (String) c[7])
.addAttribute("master", (String) custom[8]); .addAttribute("master", (String) c[8])
ENTITY_EXTMETA.put(name, new Object[] { custom[4], custom[5], custom[6] }); .addAttribute("creatable", "true")
.addAttribute("updatable", "true")
.addAttribute("queryable", "true")
.addAttribute("deletable", "true");
JSONObject extraAttrs = JSONUtils.toJSONObject(
new String[] { "metaId", "comments", "icon" },
new Object[] { c[4], c[5], c[6] });
entity.addAttribute("extra-attrs", extraAttrs.toJSONString());
} }
Object[][] customFields = Application.createQueryNoFilter( Object[][] customFields = Application.createQueryNoFilter(
"select belongEntity,fieldName,physicalName,fieldLabel,displayType,nullable,creatable,updatable," "select belongEntity,fieldName,physicalName,fieldLabel,displayType,nullable,creatable,updatable,"
+ "maxLength,defaultValue,refEntity,cascade,fieldId,comments,extConfig,repeatable from MetaField") + "maxLength,defaultValue,refEntity,cascade,fieldId,comments,extConfig,repeatable from MetaField")
.array(); .array();
for (Object[] custom : customFields) { for (Object[] c : customFields) {
String entityName = (String) custom[0]; String entityName = (String) c[0];
String fieldName = (String) custom[1]; String fieldName = (String) c[1];
Element entityElement = (Element) rootElement.selectSingleNode("entity[@name='" + entityName + "']"); Element entityElement = (Element) rootElement.selectSingleNode("entity[@name='" + entityName + "']");
if (entityElement == null) { if (entityElement == null) {
LOG.warn("无效字段 [ " + entityName + "." + fieldName + " ] 无有效依附实体"); LOG.warn("No entity found : " + entityName + "." + fieldName);
continue; continue;
} }
Element field = entityElement.addElement("field"); Element field = entityElement.addElement("field");
field.addAttribute("name", fieldName) field.addAttribute("name", fieldName)
.addAttribute("physical-name", (String) custom[2]) .addAttribute("physical-name", (String) c[2])
.addAttribute("description", (String) custom[3]) .addAttribute("description", (String) c[3])
.addAttribute("nullable", String.valueOf(custom[5])) // true .addAttribute("max-length", String.valueOf(c[8]))
.addAttribute("creatable", String.valueOf(custom[6])) // true .addAttribute("default-value", (String) c[9])
.addAttribute("updatable", String.valueOf(custom[7])) // true .addAttribute("nullable", String.valueOf(c[5]))
.addAttribute("max-length", String.valueOf(custom[8])) .addAttribute("creatable", String.valueOf(c[6]))
.addAttribute("default-value", (String) custom[9]) .addAttribute("updatable", String.valueOf(c[7]))
.addAttribute("repeatable", String.valueOf(custom[15])); // true .addAttribute("repeatable", String.valueOf(c[15]))
.addAttribute("queryable", "true");
if (fieldName.equals(EntityHelper.AutoId)) { if (fieldName.equals(EntityHelper.AutoId)) {
field.addAttribute("auto-value", "true"); field.addAttribute("auto-value", "true");
} }
DisplayType dt = DisplayType.valueOf((String) custom[4]); DisplayType dt = DisplayType.valueOf((String) c[4]);
field.addAttribute("type", dt.getFieldType().getName()); field.addAttribute("type", dt.getFieldType().getName());
if (dt == DisplayType.DECIMAL) { if (dt == DisplayType.DECIMAL) {
field.addAttribute("decimal-scale", "8"); field.addAttribute("decimal-scale", "8");
} else if (dt == DisplayType.ANYREFERENCE || dt == DisplayType.REFERENCE } else if (dt == DisplayType.ANYREFERENCE || dt == DisplayType.REFERENCE
|| dt == DisplayType.PICKLIST || dt == DisplayType.CLASSIFICATION) { || dt == DisplayType.PICKLIST || dt == DisplayType.CLASSIFICATION) {
field.addAttribute("ref-entity", (String) custom[10]) field.addAttribute("ref-entity", (String) c[10])
.addAttribute("cascade", (String) custom[11]); .addAttribute("cascade", (String) c[11]);
} }
FIELD_EXTMETA.put(entityName + "." + fieldName, new Object[] { custom[12], custom[13], dt, custom[14] }); JSONObject extraAttrs;
if (StringUtils.isBlank((String) c[14])) {
extraAttrs = new JSONObject();
} else {
extraAttrs = JSON.parseObject((String) c[14]);
}
extraAttrs.put("metaId", c[12]);
extraAttrs.put("comments", c[13]);
extraAttrs.put("displayType", dt.name());
field.addAttribute("extra-attrs", extraAttrs.toJSONString());
} }
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
XmlHelper.dump(rootElement); XmlHelper.dump(rootElement);
} }
} }
/**
* @param entity
* @return
*/
public Object[] getEntityExtmeta(Entity entity) {
return ENTITY_EXTMETA.get(entity.getName());
}
/**
* @param field
* @return
*/
public Object[] getFieldExtmeta(Field field) {
return FIELD_EXTMETA.get(field.getOwnEntity().getName() + "." + field.getName());
}
} }

View file

@ -11,10 +11,10 @@ import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.Field; import cn.devezhao.persist4j.Field;
import cn.devezhao.persist4j.dialect.FieldType; import cn.devezhao.persist4j.dialect.FieldType;
import cn.devezhao.persist4j.engine.ID; import cn.devezhao.persist4j.engine.ID;
import cn.devezhao.persist4j.metadata.BaseMeta;
import cn.devezhao.persist4j.metadata.MetadataException; import cn.devezhao.persist4j.metadata.MetadataException;
import com.rebuild.server.Application; import com.rebuild.server.Application;
import com.rebuild.server.metadata.entity.EasyMeta; import com.rebuild.server.metadata.entity.EasyMeta;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -33,7 +33,7 @@ public class MetadataHelper {
private static final Log LOG = LogFactory.getLog(MetadataHelper.class); private static final Log LOG = LogFactory.getLog(MetadataHelper.class);
/** /**
* 元数据 * 元数据工厂
* *
* @return * @return
*/ */
@ -42,6 +42,8 @@ public class MetadataHelper {
} }
/** /**
* 全部实体
*
* @return * @return
*/ */
public static Entity[] getEntities() { public static Entity[] getEntities() {
@ -53,9 +55,6 @@ public class MetadataHelper {
* @return * @return
*/ */
public static boolean containsEntity(String entityName) { public static boolean containsEntity(String entityName) {
if (StringUtils.isBlank(entityName)) {
return false;
}
try { try {
getEntity(entityName); getEntity(entityName);
return true; return true;
@ -93,16 +92,18 @@ public class MetadataHelper {
/** /**
* @param entityName * @param entityName
* @return * @return
* @throws MetadataException If not exists
*/ */
public static Entity getEntity(String entityName) { public static Entity getEntity(String entityName) throws MetadataException {
return getMetadataFactory().getEntity(entityName); return getMetadataFactory().getEntity(entityName);
} }
/** /**
* @param entityCode * @param entityCode
* @return * @return
* @throws MetadataException If not exists
*/ */
public static Entity getEntity(int entityCode) { public static Entity getEntity(int entityCode) throws MetadataException {
return getMetadataFactory().getEntity(entityCode); return getMetadataFactory().getEntity(entityCode);
} }
@ -117,6 +118,7 @@ public class MetadataHelper {
/** /**
* @param record * @param record
* @return * @return
* @see EasyMeta#getLabel(BaseMeta)
*/ */
public static String getEntityLabel(ID record) { public static String getEntityLabel(ID record) {
return EasyMeta.getLabel(getEntity(record.getEntityCode())); return EasyMeta.getLabel(getEntity(record.getEntityCode()));
@ -128,8 +130,7 @@ public class MetadataHelper {
* @return * @return
*/ */
public static Field getField(String entityName, String fieldName) { public static Field getField(String entityName, String fieldName) {
Entity entity = getEntity(entityName); return getEntity(entityName).getField(fieldName);
return entity.getField(fieldName);
} }
/** /**
@ -173,8 +174,7 @@ public class MetadataHelper {
continue; continue;
} }
Entity ref = field.getReferenceEntities()[0]; if (field.getReferenceEntity().getEntityCode().equals(source.getEntityCode())) {
if (ref.getEntityCode().equals(source.getEntityCode())) {
fields.add(field); fields.add(field);
} }
} }
@ -299,7 +299,7 @@ public class MetadataHelper {
return field; return field;
} }
} }
return null; throw new MetadataException("Bad slave entity (No STM)");
} }
/** /**

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server.metadata.entity; package com.rebuild.server.metadata.entity;
@ -80,9 +69,26 @@ public class EasyMeta implements BaseMeta {
@Override @Override
public JSONObject getExtraAttrs() { public JSONObject getExtraAttrs() {
return baseMeta.getExtraAttrs(); return getExtraAttrs(false);
} }
/**
* @param clean
* @return
*/
public JSONObject getExtraAttrs(boolean clean) {
// see DynamicMetadataFactory
if (clean) {
JSONObject clone = (JSONObject) JSONUtils.clone(baseMeta.getExtraAttrs());
clone.remove("metaId");
clone.remove("comments");
clone.remove("icon");
clone.remove("displayType");
return clone;
}
return baseMeta.getExtraAttrs() == null ? JSONUtils.EMPTY_OBJECT : baseMeta.getExtraAttrs();
}
@Override @Override
public boolean isCreatable() { public boolean isCreatable() {
return baseMeta.isCreatable(); return baseMeta.isCreatable();
@ -108,10 +114,44 @@ public class EasyMeta implements BaseMeta {
return baseMeta.isQueryable(); return baseMeta.isQueryable();
} }
// -- /**
* 获取扩展属性
*
* @param name
* @return
*/
public String getExtraAttr(String name) {
return getExtraAttrs().getString(name);
}
/**
* 系统内建字段/实体不可更改
*
* @return
* @see MetadataHelper#isCommonsField(Field)
*/
public boolean isBuiltin() {
if (this.getMetaId() == null) {
return true;
}
if (isField()) {
Field field = (Field) baseMeta;
if (MetadataHelper.isCommonsField(field)) {
return true;
} else if (getDisplayType() == DisplayType.REFERENCE) {
// 明细-引用主记录的字段也是内建
// @see MetadataHelper#getSlaveToMasterField
Entity hasMaster = field.getOwnEntity().getMasterEntity();
return hasMaster != null && hasMaster.equals(field.getReferenceEntity()) && !field.isCreatable();
}
}
return false;
}
/** /**
* also #getDescription() * Use #getDescription()
*
* @return * @return
*/ */
public String getLabel() { public String getLabel() {
@ -120,77 +160,15 @@ public class EasyMeta implements BaseMeta {
} }
return StringUtils.defaultIfBlank(getDescription(), getName().toUpperCase()); return StringUtils.defaultIfBlank(getDescription(), getName().toUpperCase());
} }
/** /**
* @param fullName * 自定义实体/字段 ID
* @return *
*/
public String getDisplayType(boolean fullName) {
DisplayType dt = getDisplayType();
if (fullName) {
return dt.getDisplayName() + " (" + dt.name() + ")";
} else {
return dt.name();
}
}
/**
* @return
*/
public DisplayType getDisplayType() {
Assert.isTrue(isField(), "Field supports only");
Object[] ext = getMetaExt();
if (ext != null) {
return (DisplayType) ext[2];
}
DisplayType dt;
String dtInExtra = getExtraAttrs().getString("displayType");
if (dtInExtra != null) {
dt = DisplayType.valueOf(dtInExtra);
} else {
dt = converBuiltinFieldType((Field) baseMeta);
}
if (dt != null) {
return dt;
}
throw new RebuildException("Unsupported field type : " + baseMeta);
}
/**
* 系统内建字段/实体不可更改
*
* @return
* @see MetadataHelper#isSystemField(Field)
*/
public boolean isBuiltin() {
if (this.getMetaId() == null) {
return true;
}
if (isField()) {
Field field = (Field) baseMeta;
if (MetadataHelper.isCommonsField(field)) {
return true;
} else if (getDisplayType() == DisplayType.REFERENCE) {
// 明细-引用主记录的字段也是内建
// @see MetadataHelper#getSlaveToMasterField
Entity hasMaster = field.getOwnEntity().getMasterEntity();
return hasMaster != null && hasMaster.equals(field.getReferenceEntity()) && !field.isCreatable();
}
}
return false;
}
/**
* 保存的 ID
*
* @return * @return
*/ */
public ID getMetaId() { public ID getMetaId() {
Object[] ext = getMetaExt(); String metaId = getExtraAttr("metaId");
return ext == null ? null : (ID) ext[0]; return metaId == null ? null : ID.valueOf(metaId);
} }
/** /**
@ -199,12 +177,19 @@ public class EasyMeta implements BaseMeta {
* @return * @return
*/ */
public String getComments() { public String getComments() {
Object[] ext = getMetaExt(); String comments = getExtraAttr("comments");
if (ext != null) { if (getMetaId() != null) {
return (String) ext[1]; return comments;
} }
return StringUtils.defaultIfBlank(getExtraAttrs().getString("comments"), "系统内建"); return StringUtils.defaultIfBlank(comments, "系统内建");
} }
@Override
public String toString() {
return "EASY#" + baseMeta.toString();
}
// -- ENTITY
/** /**
* 实体图标 * 实体图标
@ -213,73 +198,55 @@ public class EasyMeta implements BaseMeta {
*/ */
public String getIcon() { public String getIcon() {
Assert.isTrue(!isField(), "Entity supports only"); Assert.isTrue(!isField(), "Entity supports only");
String customIcon = null; return StringUtils.defaultIfBlank(getExtraAttr("icon"), "texture");
Object[] ext = getMetaExt();
if (ext != null) {
customIcon = StringUtils.defaultIfBlank((String) ext[2], "texture");
}
if (StringUtils.isNotBlank(customIcon)) {
return customIcon;
}
return StringUtils.defaultIfBlank(getExtraAttrs().getString("icon"), "texture");
}
/**
* 字段扩展配置
*
* @return
* @see FieldExtConfigProps
*/
public JSONObject getFieldExtConfig() {
Assert.isTrue(isField(), "Field supports only");
Object[] ext = getMetaExt();
if (ext == null || StringUtils.isBlank((String) ext[3])) {
JSONObject extConfig = getExtraAttrs().getJSONObject("extConfig");
return extConfig == null ? JSONUtils.EMPTY_OBJECT : extConfig;
}
return JSON.parseObject((String) ext[3]);
} }
/** /**
* 字段扩展配置 * 指定实体具有和业务实体一样的特性除权限以外指定实体无权限字段
* *
* @param name
* @return
*
* @see #getFieldExtConfig()
* @see FieldExtConfigProps
*/
public Object getPropOfFieldExtConfig(String name) {
return getFieldExtConfig().get(name);
}
/**
* 指定实体具有和业务实体一样的特性除权限以外指定实体无权限字段
* @return * @return
*/ */
public boolean isPlainEntity() { public boolean isPlainEntity() {
return !isField() && getExtraAttrs().getBooleanValue("plainEntity"); Assert.isTrue(!isField(), "Entity supports only");
return getExtraAttrs().getBooleanValue("plainEntity");
}
// -- FIELD
/**
* @return
*/
private boolean isField() {
return baseMeta instanceof Field;
}
/**
* @param fullName
* @return
*/
public String getDisplayType(boolean fullName) {
DisplayType dt = getDisplayType();
if (fullName) {
return dt.getDisplayName() + " (" + dt.name() + ")";
} else {
return dt.name();
}
} }
/** /**
* @return * @return
*/ */
private boolean isField() { public DisplayType getDisplayType() {
return baseMeta instanceof Field; Assert.isTrue(isField(), "Field supports only");
}
/** String displayType = getExtraAttr("displayType");
* @return DisplayType dt = displayType != null
*/ ? DisplayType.valueOf(displayType) : converBuiltinFieldType((Field) baseMeta);
private Object[] getMetaExt() { if (dt != null) {
Object[] ext; return dt;
if (isField()) { }
ext = MetadataHelper.getMetadataFactory().getFieldExtmeta((Field) baseMeta); throw new RebuildException("Unsupported field type : " + baseMeta);
} else { }
ext = MetadataHelper.getMetadataFactory().getEntityExtmeta((Entity) baseMeta);
}
return ext;
}
/** /**
* 将字段类型转成 DisplayType * 将字段类型转成 DisplayType
@ -292,13 +259,14 @@ public class EasyMeta implements BaseMeta {
if (ft == FieldType.PRIMARY) { if (ft == FieldType.PRIMARY) {
return DisplayType.ID; return DisplayType.ID;
} else if (ft == FieldType.REFERENCE) { } else if (ft == FieldType.REFERENCE) {
int rec = field.getReferenceEntity().getEntityCode(); int typeCode = field.getReferenceEntity().getEntityCode();
if (rec == EntityHelper.PickList) { if (typeCode == EntityHelper.PickList) {
return DisplayType.PICKLIST; return DisplayType.PICKLIST;
} else if (rec == EntityHelper.Classification) { } else if (typeCode == EntityHelper.Classification) {
return DisplayType.CLASSIFICATION; return DisplayType.CLASSIFICATION;
} } else {
return DisplayType.REFERENCE; return DisplayType.REFERENCE;
}
} else if (ft == FieldType.ANY_REFERENCE) { } else if (ft == FieldType.ANY_REFERENCE) {
return DisplayType.ANYREFERENCE; return DisplayType.ANYREFERENCE;
} else if (ft == FieldType.TIMESTAMP) { } else if (ft == FieldType.TIMESTAMP) {
@ -315,23 +283,18 @@ public class EasyMeta implements BaseMeta {
return DisplayType.NUMBER; return DisplayType.NUMBER;
} else if (ft == FieldType.DOUBLE || ft == FieldType.DECIMAL) { } else if (ft == FieldType.DOUBLE || ft == FieldType.DECIMAL) {
return DisplayType.DECIMAL; return DisplayType.DECIMAL;
} }
return null; return null;
} }
@Override // -- QUICK
public String toString() {
return "EASY#" + baseMeta.toString();
}
// --
/** /**
* @param baseMeta * @param entityOrField
* @return * @return
*/ */
public static EasyMeta valueOf(BaseMeta baseMeta) { public static EasyMeta valueOf(BaseMeta entityOrField) {
return new EasyMeta(baseMeta); return new EasyMeta(entityOrField);
} }
/** /**
@ -355,15 +318,15 @@ public class EasyMeta implements BaseMeta {
* @return * @return
*/ */
public static DisplayType getDisplayType(Field field) { public static DisplayType getDisplayType(Field field) {
return new EasyMeta(field).getDisplayType(); return valueOf(field).getDisplayType();
} }
/** /**
* @param meta * @param entityOrField
* @return * @return
*/ */
public static String getLabel(BaseMeta meta) { public static String getLabel(BaseMeta entityOrField) {
return StringUtils.defaultIfBlank(meta.getDescription(), meta.getName().toUpperCase()); return valueOf(entityOrField).getLabel();
} }
/** /**

View file

@ -96,15 +96,7 @@ public class Field2Schema {
Application.getMetadataFactory().refresh(false); Application.getMetadataFactory().refresh(false);
return fieldName; return fieldName;
} }
/**
* @param field
* @return
*/
public boolean dropField(Field field) {
return dropField(field, false);
}
/** /**
* @param field * @param field
* @param force * @param force
@ -230,8 +222,7 @@ public class Field2Schema {
Record recordOfField = EntityHelper.forNew(EntityHelper.MetaField, user); Record recordOfField = EntityHelper.forNew(EntityHelper.MetaField, user);
recordOfField.setString("belongEntity", entity.getName()); recordOfField.setString("belongEntity", entity.getName());
recordOfField.setString("fieldName", fieldName); recordOfField.setString("fieldName", fieldName);
// String physicalName = fieldName.toUpperCase(); final String physicalName = StringHelper.hyphenate(fieldName).toUpperCase();
String physicalName = StringHelper.hyphenate(fieldName).toUpperCase();
recordOfField.setString("physicalName", physicalName); recordOfField.setString("physicalName", physicalName);
recordOfField.setString("fieldLabel", fieldLabel); recordOfField.setString("fieldLabel", fieldLabel);
recordOfField.setString("displayType", dt.name()); recordOfField.setString("displayType", dt.name());
@ -239,6 +230,7 @@ public class Field2Schema {
recordOfField.setBoolean("creatable", creatable); recordOfField.setBoolean("creatable", creatable);
recordOfField.setBoolean("updatable", updatable); recordOfField.setBoolean("updatable", updatable);
recordOfField.setBoolean("repeatable", repeatable); recordOfField.setBoolean("repeatable", repeatable);
if (StringUtils.isNotBlank(comments)) { if (StringUtils.isNotBlank(comments)) {
recordOfField.setString("comments", comments); recordOfField.setString("comments", comments);
} }

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2018-2019 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server.metadata.entity; package com.rebuild.server.metadata.entity;
@ -30,24 +19,35 @@ public class FieldExtConfigProps {
* 是否允许负数 * 是否允许负数
*/ */
public static final String NUMBER_NOTNEGATIVE = "notNegative"; public static final String NUMBER_NOTNEGATIVE = "notNegative";
/**
* 格式
*/
public static final String NUMBER_FORMAT = "numberFormat";
/** /**
* 是否允许负数 * 是否允许负数
*/ */
public static final String DECIMAL_NOTNEGATIVE = NUMBER_NOTNEGATIVE; public static final String DECIMAL_NOTNEGATIVE = NUMBER_NOTNEGATIVE;
/**
* 格式
*/
public static final String DECIMAL_FORMAT = "decimalFormat";
/** /**
* 日期格式 * 日期格式
*/ */
public static final String DATE_DATEFORMAT = "dateFormat"; public static final String DATE_DATEFORMAT = "dateFormat";
/** /**
* 日期格式 * 日期格式
*/ */
public static final String DATETIME_DATEFORMAT = DATE_DATEFORMAT; public static final String DATETIME_DATEFORMAT = "datetimeFormat";
/** /**
* 允许上传数量 * 允许上传数量
*/ */
public static final String FILE_UPLOADNUMBER = "uploadNumber"; public static final String FILE_UPLOADNUMBER = "uploadNumber";
/** /**
* 允许上传数量 * 允许上传数量
*/ */
@ -65,7 +65,7 @@ public class FieldExtConfigProps {
/** /**
* 使用哪个分类数据 * 使用哪个分类数据
*/ */
public static final String CLASSIFICATION_USECLASSIFICATION = "useClassification"; public static final String CLASSIFICATION_USE = "classification";
/** /**
* 使用哪个状态类 * 使用哪个状态类

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server.service.base; package com.rebuild.server.service.base;
@ -62,7 +51,6 @@ import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Observer; import java.util.Observer;
import java.util.Set; import java.util.Set;
@ -452,8 +440,8 @@ public class GeneralEntityService extends ObservableService {
// 验证新建明细相当于更新主记录 // 验证新建明细相当于更新主记录
Entity masterEntity = entity.getMasterEntity(); Entity masterEntity = entity.getMasterEntity();
if (masterEntity != null && masterEntity.containsField(EntityHelper.ApprovalId)) { if (masterEntity != null && masterEntity.containsField(EntityHelper.ApprovalId)) {
Field smt = MetadataHelper.getSlaveToMasterField(entity); Field stmField = MetadataHelper.getSlaveToMasterField(entity);
ApprovalState state = getApprovalState(newRecord.getID(Objects.requireNonNull(smt).getName())); ApprovalState state = getApprovalState(newRecord.getID(stmField.getName()));
if (state == ApprovalState.APPROVED || state == ApprovalState.PROCESSING) { if (state == ApprovalState.APPROVED || state == ApprovalState.PROCESSING) {
String stateType = state == ApprovalState.APPROVED ? "已完成审批" : "正在审批中"; String stateType = state == ApprovalState.APPROVED ? "已完成审批" : "正在审批中";
throw new DataSpecificationException("主记录" + stateType + ",不能添加明细"); throw new DataSpecificationException("主记录" + stateType + ",不能添加明细");
@ -513,8 +501,8 @@ public class GeneralEntityService extends ObservableService {
* @throws NoRecordFoundException * @throws NoRecordFoundException
*/ */
private ID getMasterId(Entity slaveEntity, ID slaveId) throws NoRecordFoundException { private ID getMasterId(Entity slaveEntity, ID slaveId) throws NoRecordFoundException {
Field stm = MetadataHelper.getSlaveToMasterField(slaveEntity); Field stmField = MetadataHelper.getSlaveToMasterField(slaveEntity);
Object[] o = Application.getQueryFactory().uniqueNoFilter(slaveId, Objects.requireNonNull(stm).getName()); Object[] o = Application.getQueryFactory().uniqueNoFilter(slaveId, stmField.getName());
if (o == null) { if (o == null) {
throw new NoRecordFoundException(slaveId); throw new NoRecordFoundException(slaveId);
} }

View file

@ -21,7 +21,6 @@ import com.rebuild.server.metadata.EntityHelper;
import com.rebuild.server.metadata.MetadataHelper; import com.rebuild.server.metadata.MetadataHelper;
import com.rebuild.server.metadata.entity.EasyMeta; import com.rebuild.server.metadata.entity.EasyMeta;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.util.Assert;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -113,16 +112,14 @@ public class EntityQueryFilter implements Filter, QueryFilter {
} }
String ownFormat = "%s = '%s'"; String ownFormat = "%s = '%s'";
Field toMasterField = null; Field stmField = null;
if (useMaster != null) { if (useMaster != null) {
toMasterField = MetadataHelper.getSlaveToMasterField(entity); stmField = MetadataHelper.getSlaveToMasterField(entity);
Assert.notNull(toMasterField, "No STM field found : " + entity); ownFormat = stmField.getName() + "." + ownFormat;
ownFormat = toMasterField.getName() + "." + ownFormat;
} }
if (de == BizzDepthEntry.PRIVATE) { if (de == BizzDepthEntry.PRIVATE) {
return appendShareFilter(entity, toMasterField, return appendShareFilter(entity, stmField,
String.format(ownFormat, EntityHelper.OwningUser, user.getIdentity())); String.format(ownFormat, EntityHelper.OwningUser, user.getIdentity()));
} }
@ -130,7 +127,7 @@ public class EntityQueryFilter implements Filter, QueryFilter {
String deptSql = String.format(ownFormat, EntityHelper.OwningDept, dept.getIdentity()); String deptSql = String.format(ownFormat, EntityHelper.OwningDept, dept.getIdentity());
if (de == BizzDepthEntry.LOCAL) { if (de == BizzDepthEntry.LOCAL) {
return appendShareFilter(entity, toMasterField, deptSql); return appendShareFilter(entity, stmField, deptSql);
} else if (de == BizzDepthEntry.DEEPDOWN) { } else if (de == BizzDepthEntry.DEEPDOWN) {
Set<String> sqls = new HashSet<>(); Set<String> sqls = new HashSet<>();
sqls.add(deptSql); sqls.add(deptSql);
@ -138,7 +135,7 @@ public class EntityQueryFilter implements Filter, QueryFilter {
for (BusinessUnit child : dept.getAllChildren()) { for (BusinessUnit child : dept.getAllChildren()) {
sqls.add(String.format(ownFormat, EntityHelper.OwningDept, child.getIdentity())); sqls.add(String.format(ownFormat, EntityHelper.OwningDept, child.getIdentity()));
} }
return appendShareFilter(entity, toMasterField, "(" + StringUtils.join(sqls, " or ") + ")"); return appendShareFilter(entity, stmField, "(" + StringUtils.join(sqls, " or ") + ")");
} }
return DENIED.evaluate(null); return DENIED.evaluate(null);

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server.service.bizz.privileges; package com.rebuild.server.service.bizz.privileges;
@ -123,15 +112,15 @@ public class PrivilegesGuardInterceptor implements MethodInterceptor, Guard {
if (action == BizzPermission.CREATE) { if (action == BizzPermission.CREATE) {
// 明细实体 // 明细实体
if (entity.getMasterEntity() != null) { if (entity.getMasterEntity() != null) {
Field field = MetadataHelper.getSlaveToMasterField(entity);
Assert.notNull(field, "No STM field found : " + entity);
Assert.isTrue(Record.class.isAssignableFrom(idOrRecord.getClass()), "First argument must be Record!"); Assert.isTrue(Record.class.isAssignableFrom(idOrRecord.getClass()), "First argument must be Record!");
ID masterId = ((Record) idOrRecord).getID(field.getName());
Field stmField = MetadataHelper.getSlaveToMasterField(entity);
ID masterId = ((Record) idOrRecord).getID(stmField.getName());
if (masterId == null || !Application.getSecurityManager().allowUpdate(caller, masterId)) { if (masterId == null || !Application.getSecurityManager().allowUpdate(caller, masterId)) {
throw new AccessDeniedException("你没有添加明细的权限"); throw new AccessDeniedException("你没有添加明细的权限");
} }
allowed = true; allowed = true;
} else { } else {
allowed = Application.getSecurityManager().allow(caller, entity.getEntityCode(), action); allowed = Application.getSecurityManager().allow(caller, entity.getEntityCode(), action);
} }

View file

@ -26,7 +26,6 @@ import com.rebuild.server.metadata.entity.EasyMeta;
import com.rebuild.server.service.EntityService; import com.rebuild.server.service.EntityService;
import com.rebuild.server.service.bizz.RoleService; import com.rebuild.server.service.bizz.RoleService;
import com.rebuild.server.service.bizz.UserService; import com.rebuild.server.service.bizz.UserService;
import org.springframework.util.Assert;
/** /**
* 实体安全/权限 管理 * 实体安全/权限 管理
@ -412,8 +411,7 @@ public class SecurityManager {
private ID getMasterRecordId(ID slaveId) { private ID getMasterRecordId(ID slaveId) {
Entity entity = MetadataHelper.getEntity(slaveId.getEntityCode()); Entity entity = MetadataHelper.getEntity(slaveId.getEntityCode());
Field stmField = MetadataHelper.getSlaveToMasterField(entity); Field stmField = MetadataHelper.getSlaveToMasterField(entity);
Assert.isTrue(stmField != null, "Non slave entty : " + slaveId);
Object[] primary = Application.getQueryFactory().uniqueNoFilter(slaveId, stmField.getName()); Object[] primary = Application.getQueryFactory().uniqueNoFilter(slaveId, stmField.getName());
return primary == null ? null : (ID) primary[0]; return primary == null ? null : (ID) primary[0];
} }

View file

@ -25,6 +25,7 @@ import com.rebuild.server.metadata.MetadataSorter;
import com.rebuild.server.metadata.entity.DisplayType; import com.rebuild.server.metadata.entity.DisplayType;
import com.rebuild.server.metadata.entity.EasyMeta; import com.rebuild.server.metadata.entity.EasyMeta;
import com.rebuild.server.metadata.entity.Field2Schema; import com.rebuild.server.metadata.entity.Field2Schema;
import com.rebuild.server.metadata.entity.FieldExtConfigProps;
import com.rebuild.server.service.bizz.UserHelper; import com.rebuild.server.service.bizz.UserHelper;
import com.rebuild.utils.CommonsUtils; import com.rebuild.utils.CommonsUtils;
import com.rebuild.utils.JSONUtils; import com.rebuild.utils.JSONUtils;
@ -119,8 +120,8 @@ public class MetaFieldControll extends BasePageControll {
// 明细实体 // 明细实体
if (((Entity) easyEntity.getBaseMeta()).getMasterEntity() != null) { if (((Entity) easyEntity.getBaseMeta()).getMasterEntity() != null) {
Field stf = MetadataHelper.getSlaveToMasterField((Entity) easyEntity.getBaseMeta()); Field stmField = MetadataHelper.getSlaveToMasterField((Entity) easyEntity.getBaseMeta());
mv.getModel().put("isSlaveToMasterField", stf.equals(fieldMeta)); mv.getModel().put("isSlaveToMasterField", stmField.equals(fieldMeta));
} else { } else {
mv.getModel().put("isSlaveToMasterField", false); mv.getModel().put("isSlaveToMasterField", false);
} }
@ -132,7 +133,7 @@ public class MetaFieldControll extends BasePageControll {
mv.getModel().put("fieldRefentity", refentity.getName()); mv.getModel().put("fieldRefentity", refentity.getName());
mv.getModel().put("fieldRefentityLabel", new EasyMeta(refentity).getLabel()); mv.getModel().put("fieldRefentityLabel", new EasyMeta(refentity).getLabel());
} }
mv.getModel().put("fieldExtConfig", easyField.getFieldExtConfig()); mv.getModel().put("fieldExtConfig", easyField.getExtraAttrs(true));
return mv; return mv;
} }
@ -156,13 +157,13 @@ public class MetaFieldControll extends BasePageControll {
JSON extConfig = null; JSON extConfig = null;
if (dt == DisplayType.CLASSIFICATION) { if (dt == DisplayType.CLASSIFICATION) {
ID dataId = ID.valueOf(refClassification); ID dataId = ID.valueOf(refClassification);
extConfig = JSONUtils.toJSONObject("classification", dataId); extConfig = JSONUtils.toJSONObject(FieldExtConfigProps.CLASSIFICATION_USE, dataId);
} else if (dt == DisplayType.STATE) { } else if (dt == DisplayType.STATE) {
if (!StateHelper.isStateClass(stateClass)) { if (!StateHelper.isStateClass(stateClass)) {
writeFailure(response, "无效状态类"); writeFailure(response, "无效状态类");
return; return;
} }
extConfig = JSONUtils.toJSONObject("stateClass", stateClass); extConfig = JSONUtils.toJSONObject(FieldExtConfigProps.STATE_STATECLASS, stateClass);
} }
String fieldName; String fieldName;

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.web.base.configuration; package com.rebuild.web.base.configuration;
@ -119,12 +108,12 @@ public class DataListSettingsControll extends BaseControll implements PortalsCon
} }
// 明细关联字段 // 明细关联字段
final Field stmfField = entityMeta.getMasterEntity() == null ? null : MetadataHelper.getSlaveToMasterField(entityMeta); final Field stmField = entityMeta.getMasterEntity() == null ? null : MetadataHelper.getSlaveToMasterField(entityMeta);
// 引用实体的字段 // 引用实体的字段
for (Field field : MetadataSorter.sortFields(entityMeta, DisplayType.REFERENCE)) { for (Field field : MetadataSorter.sortFields(entityMeta, DisplayType.REFERENCE)) {
// 过滤所属用户/所属部门等系统字段除了明细引用主实体字段 // 过滤所属用户/所属部门等系统字段除了明细引用主实体字段
if (EasyMeta.valueOf(field).isBuiltin() && (stmfField == null || !stmfField.equals(field))) { if (EasyMeta.valueOf(field).isBuiltin() && (stmField == null || !stmField.equals(field))) {
continue; continue;
} }

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2018-2019 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.web.base.general; package com.rebuild.web.base.general;
@ -123,18 +112,22 @@ public class BatchUpdateControll extends BaseControll {
// 字段选项 // 字段选项
if (dt == DisplayType.PICKLIST) { if (dt == DisplayType.PICKLIST) {
map.put("options", PickListManager.instance.getPickList(field)); map.put("options", PickListManager.instance.getPickList(field));
} else if (dt == DisplayType.STATE) { } else if (dt == DisplayType.STATE) {
map.put("options", StateManager.instance.getStateOptions(field)); map.put("options", StateManager.instance.getStateOptions(field));
} else if (dt == DisplayType.MULTISELECT) { } else if (dt == DisplayType.MULTISELECT) {
map.put("options", MultiSelectManager.instance.getSelectList(field)); map.put("options", MultiSelectManager.instance.getSelectList(field));
} else if (dt == DisplayType.BOOL) { } else if (dt == DisplayType.BOOL) {
JSONArray options = new JSONArray(); JSONArray options = new JSONArray();
options.add(JSONUtils.toJSONObject(new String[] { "id", "text" }, new Object[] { true, ""})); options.add(JSONUtils.toJSONObject(new String[] { "id", "text" }, new Object[] { true, "" }));
options.add(JSONUtils.toJSONObject(new String[] { "id", "text" }, new Object[] { false, ""})); options.add(JSONUtils.toJSONObject(new String[] { "id", "text" }, new Object[] { false, "" }));
map.put("options", options); map.put("options", options);
} else if (dt == DisplayType.NUMBER || dt == DisplayType.DECIMAL) { } else if (dt == DisplayType.NUMBER || dt == DisplayType.DECIMAL) {
map.put(FieldExtConfigProps.NUMBER_NOTNEGATIVE, map.put(FieldExtConfigProps.NUMBER_NOTNEGATIVE,
EasyMeta.valueOf(field).getPropOfFieldExtConfig(FieldExtConfigProps.NUMBER_NOTNEGATIVE)); EasyMeta.valueOf(field).getExtraAttr(FieldExtConfigProps.NUMBER_NOTNEGATIVE));
} }
return map; return map;

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.web.base.general; package com.rebuild.web.base.general;
@ -62,7 +51,13 @@ public class GeneralDataListControll extends BaseEntityControll {
return null; return null;
} }
Entity thatEntity = MetadataHelper.getEntity(entity); final Entity thatEntity = MetadataHelper.getEntity(entity);
if (!thatEntity.isQueryable()) {
response.sendError(404);
return null;
}
if (!Application.getSecurityManager().allowRead(user, thatEntity.getEntityCode())) { if (!Application.getSecurityManager().allowRead(user, thatEntity.getEntityCode())) {
response.sendError(403, "你没有访问此实体的权限"); response.sendError(403, "你没有访问此实体的权限");
return null; return null;

View file

@ -40,7 +40,7 @@ public class GeneralModelControll extends BaseEntityControll {
public ModelAndView pageView(@PathVariable String entity, @PathVariable String id, public ModelAndView pageView(@PathVariable String entity, @PathVariable String id,
HttpServletRequest request, HttpServletResponse response) throws IOException { HttpServletRequest request, HttpServletResponse response) throws IOException {
final ID user = getRequestUser(request); final ID user = getRequestUser(request);
Entity thatEntity = MetadataHelper.getEntity(entity); final Entity thatEntity = MetadataHelper.getEntity(entity);
if (!Application.getSecurityManager().allowRead(user, thatEntity.getEntityCode())) { if (!Application.getSecurityManager().allowRead(user, thatEntity.getEntityCode())) {
response.sendError(403, "你没有访问此实体的权限"); response.sendError(403, "你没有访问此实体的权限");

View file

@ -13,7 +13,7 @@
<entity name="User" type-code="001" description="用户" name-field="fullName" extra-attrs="{icon:'account'}"> <entity name="User" type-code="001" description="用户" name-field="fullName" extra-attrs="{icon:'account'}">
<field name="userId" type="primary" /> <field name="userId" type="primary" />
<field name="loginName" type="string" max-length="100" nullable="false" updatable="false" repeatable="false" description="登录名" /> <field name="loginName" type="string" max-length="100" nullable="false" updatable="false" repeatable="false" description="登录名" />
<field name="password" type="string" max-length="100" nullable="false" updatable="false" description="登录密码" /> <field name="password" type="string" max-length="100" nullable="false" updatable="false" description="登录密码" queryable="false" />
<field name="email" type="string" max-length="100" description="邮箱" repeatable="false" extra-attrs="{displayType:'EMAIL'}" /> <field name="email" type="string" max-length="100" description="邮箱" repeatable="false" extra-attrs="{displayType:'EMAIL'}" />
<field name="fullName" type="string" max-length="100" description="姓名" /> <field name="fullName" type="string" max-length="100" description="姓名" />
<field name="avatarUrl" type="string" max-length="200" description="头像" extra-attrs="{displayType:'AVATAR'}" /> <field name="avatarUrl" type="string" max-length="200" description="头像" extra-attrs="{displayType:'AVATAR'}" />
@ -75,7 +75,7 @@
<index field-list="teamId,userId" type="unique" /> <index field-list="teamId,userId" type="unique" />
</entity> </entity>
<entity name="MetaEntity" type-code="010" name-field="entityName"> <entity name="MetaEntity" type-code="010" name-field="entityName" queryable="false">
<field name="entityId" type="primary" /> <field name="entityId" type="primary" />
<field name="typeCode" type="small-int" nullable="false" updatable="false" /> <field name="typeCode" type="small-int" nullable="false" updatable="false" />
<field name="entityName" type="string" max-length="100" nullable="false" updatable="false" /> <field name="entityName" type="string" max-length="100" nullable="false" updatable="false" />
@ -90,7 +90,7 @@
<index type="unique" field-list="physicalName" /> <index type="unique" field-list="physicalName" />
</entity> </entity>
<entity name="MetaField" type-code="011" name-field="fieldName"> <entity name="MetaField" type-code="011" name-field="fieldName" queryable="false">
<field name="fieldId" type="primary" /> <field name="fieldId" type="primary" />
<field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" /> <field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" />
<field name="fieldName" type="string" max-length="100" nullable="false" updatable="false" /> <field name="fieldName" type="string" max-length="100" nullable="false" updatable="false" />
@ -111,7 +111,7 @@
<index type="unique" field-list="belongEntity,physicalName" /> <index type="unique" field-list="belongEntity,physicalName" />
</entity> </entity>
<entity name="PickList" type-code="012" name-field="text" description="下拉列表字段配置选项"> <entity name="PickList" type-code="012" name-field="text" description="下拉列表字段配置选项" queryable="false">
<field name="itemId" type="primary" /> <field name="itemId" type="primary" />
<field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" /> <field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" />
<field name="belongField" type="string" max-length="100" nullable="false" updatable="false" /> <field name="belongField" type="string" max-length="100" nullable="false" updatable="false" />
@ -123,7 +123,7 @@
<index field-list="belongEntity,belongField" /> <index field-list="belongEntity,belongField" />
</entity> </entity>
<entity name="LayoutConfig" type-code="013" description="布局配置(表单/列表/导航/视图(相关项/新建))"> <entity name="LayoutConfig" type-code="013" description="布局配置(表单/列表/导航/视图(相关项/新建))" queryable="false">
<field name="configId" type="primary" /> <field name="configId" type="primary" />
<field name="config" type="text" description="JSON格式配置" nullable="false" /> <field name="config" type="text" description="JSON格式配置" nullable="false" />
<field name="shareTo" type="string" max-length="420" default-value="SELF" description="共享给哪些人, 可选值: ALL/SELF/$MemberID(U/D/R)" /> <field name="shareTo" type="string" max-length="420" default-value="SELF" description="共享给哪些人, 可选值: ALL/SELF/$MemberID(U/D/R)" />
@ -132,7 +132,7 @@
<field name="configName" type="string" max-length="100" /> <field name="configName" type="string" max-length="100" />
</entity> </entity>
<entity name="FilterConfig" type-code="014" description="过滤条件配置"> <entity name="FilterConfig" type-code="014" description="过滤条件配置" queryable="false">
<field name="configId" type="primary" /> <field name="configId" type="primary" />
<field name="config" type="text" description="JSON格式配置" nullable="false" /> <field name="config" type="text" description="JSON格式配置" nullable="false" />
<field name="shareTo" type="string" max-length="420" default-value="SELF" description="共享给哪些人, 可选值: ALL/SELF/$MemberID(U/D/R)" /> <field name="shareTo" type="string" max-length="420" default-value="SELF" description="共享给哪些人, 可选值: ALL/SELF/$MemberID(U/D/R)" />
@ -140,14 +140,14 @@
<field name="filterName" type="string" max-length="100" nullable="false" /> <field name="filterName" type="string" max-length="100" nullable="false" />
</entity> </entity>
<entity name="DashboardConfig" type-code="016" description="仪表盘配置"> <entity name="DashboardConfig" type-code="016" description="仪表盘配置" queryable="false">
<field name="configId" type="primary" /> <field name="configId" type="primary" />
<field name="config" type="text" description="JSON格式配置" nullable="false" /> <field name="config" type="text" description="JSON格式配置" nullable="false" />
<field name="shareTo" type="string" max-length="420" default-value="SELF" description="共享给哪些人, 可选值: ALL/SELF/$MemberID(U/D/R)" /> <field name="shareTo" type="string" max-length="420" default-value="SELF" description="共享给哪些人, 可选值: ALL/SELF/$MemberID(U/D/R)" />
<field name="title" type="string" max-length="100" nullable="false" /> <field name="title" type="string" max-length="100" nullable="false" />
</entity> </entity>
<entity name="ChartConfig" type-code="017" description="图表配置"> <entity name="ChartConfig" type-code="017" description="图表配置" queryable="false">
<field name="chartId" type="primary" /> <field name="chartId" type="primary" />
<field name="config" type="text" description="JSON格式配置" nullable="false" /> <field name="config" type="text" description="JSON格式配置" nullable="false" />
<field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" /> <field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" />
@ -177,7 +177,7 @@
<index field-list="dataId,fullName,quickCode" /> <index field-list="dataId,fullName,quickCode" />
</entity> </entity>
<entity name="ShareAccess" type-code="020" description="记录共享"> <entity name="ShareAccess" type-code="020" description="记录共享" queryable="false">
<field name="accessId" type="primary" /> <field name="accessId" type="primary" />
<field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" description="哪个实体" /> <field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" description="哪个实体" />
<field name="recordId" type="any-reference" nullable="false" updatable="false" description="记录ID" cascade="ignore" /> <field name="recordId" type="any-reference" nullable="false" updatable="false" description="记录ID" cascade="ignore" />
@ -186,7 +186,7 @@
<index field-list="belongEntity,recordId,shareTo" /> <index field-list="belongEntity,recordId,shareTo" />
</entity> </entity>
<entity name="SystemConfig" type-code="021" parent="false" description="系统全局配置"> <entity name="SystemConfig" type-code="021" parent="false" description="系统全局配置" queryable="false">
<field name="configId" type="primary" /> <field name="configId" type="primary" />
<field name="item" type="string" max-length="100" nullable="false" updatable="false" /> <field name="item" type="string" max-length="100" nullable="false" updatable="false" />
<field name="value" type="string" max-length="600" nullable="false" /> <field name="value" type="string" max-length="600" nullable="false" />
@ -238,7 +238,7 @@
<index field-list="user,loginTime" /> <index field-list="user,loginTime" />
</entity> </entity>
<entity name="AutoFillinConfig" type-code="026" description="字段自动回填配置"> <entity name="AutoFillinConfig" type-code="026" description="字段自动回填配置" queryable="false">
<field name="configId" type="primary" /> <field name="configId" type="primary" />
<field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" /> <field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" />
<field name="belongField" type="string" max-length="100" nullable="false" updatable="false" /> <field name="belongField" type="string" max-length="100" nullable="false" updatable="false" />
@ -247,7 +247,7 @@
<field name="extConfig" type="string" max-length="700" description="更多扩展配置, JSON格式KV" /> <field name="extConfig" type="string" max-length="700" description="更多扩展配置, JSON格式KV" />
</entity> </entity>
<entity name="RobotTriggerConfig" type-code="027" description="动作触发器"> <entity name="RobotTriggerConfig" type-code="027" description="动作触发器" queryable="false">
<field name="configId" type="primary" /> <field name="configId" type="primary" />
<field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" /> <field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" />
<field name="when" type="int" default-value="0" description="动作(累加值)" /> <field name="when" type="int" default-value="0" description="动作(累加值)" />
@ -259,7 +259,7 @@
<field name="isDisabled" type="bool" default-value="F" description="是否停用" /> <field name="isDisabled" type="bool" default-value="F" description="是否停用" />
</entity> </entity>
<entity name="RobotApprovalConfig" type-code="028" name-field="name" description="审批流程"> <entity name="RobotApprovalConfig" type-code="028" name-field="name" description="审批流程" queryable="false">
<field name="configId" type="primary" /> <field name="configId" type="primary" />
<field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" description="应用实体" /> <field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" description="应用实体" />
<field name="name" type="string" max-length="100" nullable="false" description="流程名称" /> <field name="name" type="string" max-length="100" nullable="false" description="流程名称" />
@ -267,7 +267,7 @@
<field name="isDisabled" type="bool" default-value="F" description="是否停用" /> <field name="isDisabled" type="bool" default-value="F" description="是否停用" />
</entity> </entity>
<entity name="RobotApprovalStep" type-code="029" description="审批步骤记录"> <entity name="RobotApprovalStep" type-code="029" description="审批步骤记录" queryable="false">
<field name="stepId" type="primary" /> <field name="stepId" type="primary" />
<field name="recordId" type="any-reference" nullable="false" updatable="false" description="审批记录" /> <field name="recordId" type="any-reference" nullable="false" updatable="false" description="审批记录" />
<field name="approvalId" type="reference" ref-entity="RobotApprovalConfig" nullable="false" updatable="false" description="审批流程" /> <field name="approvalId" type="reference" ref-entity="RobotApprovalConfig" nullable="false" updatable="false" description="审批流程" />
@ -303,7 +303,7 @@
<index field-list="appId,remoteIp,requestUrl,requestTime" /> <index field-list="appId,remoteIp,requestUrl,requestTime" />
</entity> </entity>
<entity name="DataReportConfig" type-code="032" description="报表"> <entity name="DataReportConfig" type-code="032" description="报表" queryable="false">
<field name="configId" type="primary" /> <field name="configId" type="primary" />
<field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" description="应用实体" /> <field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" description="应用实体" />
<field name="name" type="string" max-length="100" nullable="false" description="报表名称" /> <field name="name" type="string" max-length="100" nullable="false" description="报表名称" />
@ -381,7 +381,7 @@
<index field-list="source,createdBy" /> <index field-list="source,createdBy" />
</entity> </entity>
<entity name="FeedsMention" type-code="043" description="用户提及" parent="false"> <entity name="FeedsMention" type-code="043" description="用户提及" parent="false" queryable="false">
<field name="mentionId" type="primary" /> <field name="mentionId" type="primary" />
<field name="feedsId" type="reference" ref-entity="Feeds" nullable="false" updatable="false" description="哪个动态" cascade="delete" /> <field name="feedsId" type="reference" ref-entity="Feeds" nullable="false" updatable="false" description="哪个动态" cascade="delete" />
<field name="commentId" type="reference" ref-entity="FeedsComment" updatable="false" description="哪个评论" cascade="delete" /> <field name="commentId" type="reference" ref-entity="FeedsComment" updatable="false" description="哪个评论" cascade="delete" />

View file

@ -318,7 +318,7 @@
window.__PageConfig = { window.__PageConfig = {
metaId: '${fieldMetaId}', metaId: '${fieldMetaId}',
fieldType: '${fieldType}', fieldType: '${fieldType}',
extConfig: $.parseJSON('${fieldExtConfig}' || '{}'), extConfig: $.parseJSON('${fieldExtConfig}'),
entityName: '${entityName}', entityName: '${entityName}',
fieldName: '${fieldName}', fieldName: '${fieldName}',
fieldBuildin: ${fieldBuildin}, fieldBuildin: ${fieldBuildin},

View file

@ -323,7 +323,7 @@ class DlgImports extends RbModalHandler {
</div> </div>
<div className="clearfix"></div> <div className="clearfix"></div>
<div className="form-text"> <div className="form-text">
支持 Excel CSV 文件文件格式请 <a href="https://getrebuild.com/docs/admin/classifcation" target="_blank" className="link">参考文档</a> 支持 Excel CSV 文件文件格式请 <a href="https://getrebuild.com/docs/admin/classifications" target="_blank" className="link">参考文档</a>
</div> </div>
</div> </div>
</div> </div>

View file

@ -0,0 +1,39 @@
/*
Copyright (c) REBUILD <https://getrebuild.com/> and 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.api.metadata;
import com.alibaba.fastjson.JSONObject;
import com.rebuild.api.ApiContext;
import com.rebuild.server.TestSupport;
import com.rebuild.utils.JSONUtils;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
/**
* @author devezhao
* @since 2020/5/14
*/
public class ClassificationDataTest extends TestSupport {
@Test
public void execute() {
Map<String, String> reqParams = new HashMap<>();
reqParams.put("entity", "TestAllFields");
reqParams.put("field", "CLASSIFICATION");
ApiContext apiContext = new ApiContext(reqParams, null);
JSONObject ret = (JSONObject) new ClassificationData().execute(apiContext);
System.out.println(JSONUtils.prettyPrint(ret));
Assert.assertNotNull(ret.get("error_code"));
}
}

View file

@ -0,0 +1,35 @@
/*
Copyright (c) REBUILD <https://getrebuild.com/> and 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.api.metadata;
import com.alibaba.fastjson.JSONObject;
import com.rebuild.api.ApiContext;
import com.rebuild.server.TestSupport;
import com.rebuild.utils.JSONUtils;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
/**
* @author devezhao
* @since 2020/5/14
*/
public class EntityListTest extends TestSupport {
@Test
public void execute() {
Map<String, String> reqParams = new HashMap<>();
ApiContext apiContext = new ApiContext(reqParams, null);
JSONObject ret = (JSONObject) new EntityList().execute(apiContext);
System.out.println(JSONUtils.prettyPrint(ret));
Assert.assertNotNull(ret.get("error_code"));
}
}

View file

@ -0,0 +1,36 @@
/*
Copyright (c) REBUILD <https://getrebuild.com/> and 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.api.metadata;
import com.alibaba.fastjson.JSONObject;
import com.rebuild.api.ApiContext;
import com.rebuild.server.TestSupport;
import com.rebuild.utils.JSONUtils;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
/**
* @author devezhao
* @since 2020/5/14
*/
public class FieldListTest extends TestSupport {
@Test
public void execute() {
Map<String, String> reqParams = new HashMap<>();
reqParams.put("entity", "TestAllFields");
ApiContext apiContext = new ApiContext(reqParams, null);
JSONObject ret = (JSONObject) new FieldList().execute(apiContext);
System.out.println(JSONUtils.prettyPrint(ret));
Assert.assertNotNull(ret.get("error_code"));
}
}

View file

@ -93,16 +93,22 @@ public class TestSupport {
} }
String fieldName = dt.name().toUpperCase(); String fieldName = dt.name().toUpperCase();
if (dt == DisplayType.DATE) fieldName = "DATE1"; // Black
if (dt == DisplayType.REFERENCE) { if (dt == DisplayType.REFERENCE) {
new Field2Schema(UserService.ADMIN_USER).createField(testEntity, fieldName, dt, null, entityName, null); new Field2Schema(UserService.ADMIN_USER)
.createField(testEntity, fieldName, dt, null, entityName, null);
} else if (dt == DisplayType.CLASSIFICATION) { } else if (dt == DisplayType.CLASSIFICATION) {
JSON area = JSON.parseObject("{classification:'018-0000000000000001'}"); JSON area = JSON.parseObject("{classification:'018-0000000000000001'}");
new Field2Schema(UserService.ADMIN_USER).createField(testEntity, fieldName, dt, null, entityName, area); new Field2Schema(UserService.ADMIN_USER)
.createField(testEntity, fieldName, dt, null, entityName, area);
} else if (dt == DisplayType.STATE) { } else if (dt == DisplayType.STATE) {
JSON area = JSON.parseObject("{stateClass:'com.rebuild.server.helper.state.HowtoState'}"); JSON area = JSON.parseObject("{stateClass:'com.rebuild.server.helper.state.HowtoState'}");
new Field2Schema(UserService.ADMIN_USER).createField(testEntity, fieldName, dt, null, entityName, area); new Field2Schema(UserService.ADMIN_USER)
.createField(testEntity, fieldName, dt, null, entityName, area);
} else { } else {
new Field2Schema(UserService.ADMIN_USER).createField(testEntity, fieldName, dt, null, null, null); new Field2Schema(UserService.ADMIN_USER)
.createField(testEntity, fieldName, dt, null, null, null);
} }
} }
} }
@ -138,7 +144,7 @@ public class TestSupport {
String content = FileUtils.readFileToString(new File(url.toURI())); String content = FileUtils.readFileToString(new File(url.toURI()));
MetaschemaImporter importer = new MetaschemaImporter(JSON.parseObject(content)); MetaschemaImporter importer = new MetaschemaImporter(JSON.parseObject(content));
if (this instanceof TestSupportWithUser) { if (this instanceof TestSupportWithUser) {
TaskExecutors.exec(importer); TaskExecutors.exec(importer);
} else { } else {
TaskExecutors.run(importer.setUser(UserService.ADMIN_USER)); TaskExecutors.run(importer.setUser(UserService.ADMIN_USER));

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2019 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server.configuration; package com.rebuild.server.configuration;
@ -51,7 +40,7 @@ public class AutoFillinManagerTest extends TestSupportWithUser {
System.out.println( System.out.println(
AutoFillinManager.instance.conversionCompatibleValue(test.getField("datetime"), textField, CalendarUtils.now())); AutoFillinManager.instance.conversionCompatibleValue(test.getField("datetime"), textField, CalendarUtils.now()));
System.out.println( System.out.println(
AutoFillinManager.instance.conversionCompatibleValue(test.getField("datetime"), test.getField("date"), CalendarUtils.now())); AutoFillinManager.instance.conversionCompatibleValue(test.getField("datetime"), test.getField("date1"), CalendarUtils.now()));
} }
@Test @Test

View file

@ -1,24 +1,12 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2019 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server.metadata; package com.rebuild.server.metadata;
import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.Field; import cn.devezhao.persist4j.Field;
import com.rebuild.server.TestSupport; import com.rebuild.server.TestSupport;
import org.junit.Test; import org.junit.Test;
@ -31,14 +19,11 @@ public class DefaultValueHelperTest extends TestSupport {
@Test @Test
public void testExprDefaultValue() throws Exception { public void testExprDefaultValue() throws Exception {
Entity e = MetadataHelper.getEntity(TEST_ENTITY); Field dateField = MetadataHelper.getField(TEST_ENTITY, "DATE1");
Field date = e.getField("date"); System.out.println(DefaultValueHelper.exprDefaultValue(dateField, "{NOW}"));
System.out.println(DefaultValueHelper.exprDefaultValue(dateField, "{NOW - 1H}"));
System.out.println(DefaultValueHelper.exprDefaultValue(date, "{NOW}")); System.out.println(DefaultValueHelper.exprDefaultValue(dateField, "{NOW + 1M}"));
System.out.println(DefaultValueHelper.exprDefaultValue(date, "{NOW - 1H}")); System.out.println(DefaultValueHelper.exprDefaultValue(dateField, "2019-09-01"));
System.out.println(DefaultValueHelper.exprDefaultValue(date, "{NOW + 1M}")); System.out.println(DefaultValueHelper.exprDefaultValue(dateField, "2019-09-01 01:01"));
System.out.println(DefaultValueHelper.exprDefaultValue(date, "2019-09-01"));
System.out.println(DefaultValueHelper.exprDefaultValue(date, "2019-09-01 01:01"));
} }
} }

View file

@ -1,19 +1,8 @@
/* /*
rebuild - Building your business-systems freely. Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
Copyright (C) 2019 devezhao <zhaofang123@gmail.com>
This program is free software: you can redistribute it and/or modify rebuild is dual-licensed under commercial and open source licenses (GPLv3).
it under the terms of the GNU General Public License as published by See LICENSE and COMMERCIAL in the project root for license information.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.rebuild.server.metadata.entity; package com.rebuild.server.metadata.entity;
@ -30,9 +19,16 @@ import org.junit.Test;
public class EasyMetaTest extends TestSupport { public class EasyMetaTest extends TestSupport {
@Test @Test
public void test() throws Exception { public void getLabel() throws Exception {
Entity user = MetadataHelper.getEntity("User"); Entity user = MetadataHelper.getEntity("User");
EasyMeta.getLabel(user, "roleId.name"); EasyMeta.getLabel(user, "roleId.name");
System.out.println(EasyMeta.getEntityShow(user)); System.out.println(EasyMeta.getEntityShow(user));
} }
@Test
public void testEntities() {
for (Entity entity : MetadataHelper.getEntities()) {
System.out.println(entity);
}
}
} }