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
node_modules
test.*

View file

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

View file

@ -127,7 +127,7 @@
<dependency>
<groupId>com.github.devezhao</groupId>
<artifactId>persist4j</artifactId>
<version>3aa38dabbd</version>
<version>1beaf8f565</version>
</dependency>
<dependency>
<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) 2018 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server;
@ -49,6 +38,7 @@ import java.util.List;
*/
public final class ServerStatus {
private static long LastCheckTime = 0;
private static final List<Status> LAST_STATUS = new ArrayList<>();
/**
@ -57,6 +47,11 @@ public final class ServerStatus {
* @return
*/
public static List<Status> getLastStatus() {
// 60 秒缓存
if (System.currentTimeMillis() - LastCheckTime > 60 * 1000) {
checkAll();
}
synchronized (LAST_STATUS) {
return Collections.unmodifiableList(LAST_STATUS);
}
@ -92,7 +87,8 @@ public final class ServerStatus {
LAST_STATUS.clear();
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));
}
JSONObject extConfig = easyField.getFieldExtConfig();
JSONObject extConfig = easyField.getExtraAttrs(true);
if (!extConfig.isEmpty()) {
schemaField.put("extConfig", extConfig);
}

View file

@ -135,7 +135,9 @@ public class MetaschemaImporter extends HeavyTask<String> {
}
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);

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server.business.series;
@ -45,7 +34,7 @@ public class SeriesGenerator {
*/
public SeriesGenerator(EasyMeta field) {
this.field = (Field) field.getBaseMeta();
this.config = field.getFieldExtConfig();
this.config = field.getExtraAttrs(true);
}
/**
@ -73,7 +62,7 @@ public class SeriesGenerator {
return seriesFormat;
}
private static final Pattern VAR_PATTERN = Pattern.compile("\\{(\\w+)\\}");
private static final Pattern VAR_PATTERN = Pattern.compile("\\{(\\w+)}");
/**
* @param format
* @return

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server.business.series;
@ -24,6 +13,7 @@ import cn.devezhao.persist4j.Field;
import com.rebuild.server.metadata.MetadataHelper;
import com.rebuild.server.metadata.entity.DisplayType;
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.LogFactory;
import org.quartz.JobExecutionContext;
@ -60,7 +50,7 @@ public class SeriesZeroResetJob extends QuartzJobBean {
for (Field field : entity.getFields()) {
EasyMeta easy = EasyMeta.valueOf(field);
if (easy.getDisplayType() == DisplayType.SERIES) {
String zeroFlag = easy.getFieldExtConfig().getString("seriesZero");
String zeroFlag = easy.getExtraAttr(FieldExtConfigProps.SERIES_SERIESZERO);
if ("D".equalsIgnoreCase(zeroFlag)) {
SeriesGeneratorFactory.zero(field);
LOG.info("Zero field by [D] : " + field);

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2019 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server.configuration.portals;
@ -24,6 +13,7 @@ import com.rebuild.server.Application;
import com.rebuild.server.configuration.ConfigManager;
import com.rebuild.server.metadata.EntityHelper;
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.LogFactory;
@ -152,7 +142,7 @@ public class ClassificationManager implements ConfigManager<ID> {
* @return
*/
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;
if (dataId == null) {
LOG.error("Field [ " + field + " ] unconfig classification");

View file

@ -64,7 +64,7 @@ public class FieldPortalAttrs {
* @return
*/
public boolean allowDataList(Field field) {
return !disallowAll(field) && !isPasswd(field);
return !disallowAll(field) && field.isQueryable();
}
/**
@ -72,7 +72,7 @@ public class FieldPortalAttrs {
* @return
*/
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
|| 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.entity.DisplayType;
import com.rebuild.server.metadata.entity.EasyMeta;
import com.rebuild.server.metadata.entity.FieldExtConfigProps;
import com.rebuild.utils.JSONUtils;
import org.apache.commons.lang.StringUtils;
@ -139,7 +140,7 @@ public class FieldValueWrapper {
* @return
*/
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());
return CalendarUtils.getDateFormat(format).format(value);
}
@ -150,7 +151,7 @@ public class FieldValueWrapper {
* @return
*/
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());
return CalendarUtils.getDateFormat(format).format(value);
}
@ -161,7 +162,7 @@ public class FieldValueWrapper {
* @return
*/
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());
return new DecimalFormat(format).format(value);
}
@ -172,7 +173,7 @@ public class FieldValueWrapper {
* @return
*/
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());
return new DecimalFormat(format).format(value);
}
@ -187,10 +188,12 @@ public class FieldValueWrapper {
Object text = ((ID) value).getLabelRaw();
if (text == null) {
text = getLabelNotry((ID) value);
} else {
Field nameField = ((Field) field.getBaseMeta()).getReferenceEntity().getNameField();
text = instance.wrapFieldValue(text, nameField, true);
}
return wrapMixValue((ID) value, text == null ? null : text.toString());
}
@ -219,7 +222,7 @@ public class FieldValueWrapper {
* @return
*/
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();
}
@ -280,21 +283,19 @@ public class FieldValueWrapper {
* @return
*/
protected Object wrapSpecialField(Object value, EasyMeta field) {
String fieldName = field.getName().toLowerCase();
// 密码型字段返回
if (fieldName.contains("password") || fieldName.contains("passwd")) {
if (!field.isQueryable()) {
return "******";
}
// 审批
if (fieldName.equalsIgnoreCase(EntityHelper.ApprovalState)) {
if (field.getName().equalsIgnoreCase(EntityHelper.ApprovalState)) {
if (value == null) {
return ApprovalState.DRAFT.getName();
} else {
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);
}

View file

@ -39,7 +39,6 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
@ -242,9 +241,9 @@ public class FormsBuilder extends FormsManager {
ID masterRecordId = MASTERID4NEWSLAVE.get();
if (masterRecordId == null) {
Field stm = MetadataHelper.getSlaveToMasterField(entity);
Field stmField = MetadataHelper.getSlaveToMasterField(entity);
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();
if (o == null) {
return null;
@ -303,7 +302,7 @@ public class FormsBuilder extends FormsManager {
}
// 字段扩展配置 FieldExtConfigProps
JSONObject fieldExt = easyField.getFieldExtConfig();
JSONObject fieldExt = easyField.getExtraAttrs(true);
for (Map.Entry<String, Object> e : fieldExt.entrySet()) {
el.put(e.getKey(), e.getValue());
}
@ -529,7 +528,7 @@ public class FormsBuilder extends FormsManager {
// 主实体字段
else if (field.equals(DV_MASTER)) {
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) {
initialValReady.put(stmField.getName(), mixValue);
initialValKeeps.add(stmField.getName());

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2018-2019 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server.configuration.portals;
@ -46,8 +35,7 @@ public class MultiSelectManager extends PickListManager {
public JSONArray getSelectList(Field field) {
ConfigEntry[] entries = getPickListRaw(field, false);
for (ConfigEntry e : entries) {
e.set("hide", null);
e.set("id", null);
e.set("hide", null).set("id", null);
}
return JSONUtils.toJSONArray(entries);
}

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server.helper.cache;
@ -76,8 +65,8 @@ public class RecordOwningCache extends BaseCacheTemplate<ID> {
String sql = "select owningUser from %s where %s = '%s'";
// 使用主记录
if (useMaster != null) {
Field stm = MetadataHelper.getSlaveToMasterField(entity);
sql = sql.replaceFirst("owningUser", stm.getName() + ".owningUser");
Field stmField = MetadataHelper.getSlaveToMasterField(entity);
sql = sql.replaceFirst("owningUser", stmField.getName() + ".owningUser");
}
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) 2018-2019 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server.helper.state;
@ -22,6 +11,7 @@ import cn.devezhao.persist4j.Field;
import com.rebuild.server.business.approval.ApprovalState;
import com.rebuild.server.metadata.EntityHelper;
import com.rebuild.server.metadata.entity.EasyMeta;
import com.rebuild.server.metadata.entity.FieldExtConfigProps;
import org.apache.commons.lang.ClassUtils;
import org.springframework.util.Assert;
@ -58,7 +48,7 @@ public class StateHelper {
return ApprovalState.class;
}
String stateClass = new EasyMeta(stateField).getFieldExtConfig().getString("stateClass");
String stateClass = new EasyMeta(stateField).getExtraAttr(FieldExtConfigProps.STATE_STATECLASS);
return getSatetClass(stateClass);
}
@ -72,7 +62,7 @@ public class StateHelper {
public static Class<?> getSatetClass(String stateClass) throws IllegalArgumentException {
Assert.notNull(stateClass, "[stateClass] not be null");
Class<?> stateEnum = null;
Class<?> stateEnum;
try {
stateEnum = ClassUtils.getClass(stateClass);
if (stateEnum.isEnum() && ClassUtils.isAssignable(stateEnum, StateSpec.class)) {

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2019 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server.helper.state;
@ -25,6 +14,7 @@ import com.rebuild.server.Application;
import com.rebuild.server.business.approval.ApprovalState;
import com.rebuild.server.metadata.EntityHelper;
import com.rebuild.server.metadata.entity.EasyMeta;
import com.rebuild.server.metadata.entity.FieldExtConfigProps;
import com.rebuild.utils.JSONUtils;
import org.apache.commons.lang.StringUtils;
@ -48,7 +38,7 @@ public class StateManager {
if (EntityHelper.ApprovalState.equalsIgnoreCase(stateField.getName())) {
stateClass = ApprovalState.class.getName();
} else {
stateClass = EasyMeta.valueOf(stateField).getFieldExtConfig().getString("stateClass");
stateClass = EasyMeta.valueOf(stateField).getExtraAttr(FieldExtConfigProps.STATE_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;
import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.Field;
import cn.devezhao.persist4j.dialect.Dialect;
import cn.devezhao.persist4j.metadata.impl.ConfigurationMetadataFactory;
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.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.LogFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import java.util.Map;
/**
* @author zhaofang123@gmail.com
* @since 08/04/2018
@ -31,11 +30,6 @@ public class DynamicMetadataFactory extends ConfigurationMetadataFactory {
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) {
super(configLocation, dialect);
}
@ -57,84 +51,84 @@ public class DynamicMetadataFactory extends ConfigurationMetadataFactory {
private void appendConfig4Db(Document config) {
final Element rootElement = config.getRootElement();
ENTITY_EXTMETA.clear();
FIELD_EXTMETA.clear();
Object[][] customEntity = Application.createQueryNoFilter(
Object[][] customEntities = Application.createQueryNoFilter(
"select typeCode,entityName,physicalName,entityLabel,entityId,comments,icon,nameField,masterEntity from MetaEntity")
.array();
for (Object[] custom : customEntity) {
String name = (String) custom[1];
for (Object[] c : customEntities) {
String name = (String) c[1];
Element entity = rootElement.addElement("entity");
entity.addAttribute("type-code", custom[0].toString())
entity.addAttribute("type-code", c[0].toString())
.addAttribute("name", name)
.addAttribute("physical-name", (String) custom[2])
.addAttribute("description", (String) custom[3])
.addAttribute("physical-name", (String) c[2])
.addAttribute("description", (String) c[3])
.addAttribute("parent", "false")
.addAttribute("name-field", (String) custom[7])
.addAttribute("master", (String) custom[8]);
ENTITY_EXTMETA.put(name, new Object[] { custom[4], custom[5], custom[6] });
.addAttribute("name-field", (String) c[7])
.addAttribute("master", (String) c[8])
.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(
"select belongEntity,fieldName,physicalName,fieldLabel,displayType,nullable,creatable,updatable,"
+ "maxLength,defaultValue,refEntity,cascade,fieldId,comments,extConfig,repeatable from MetaField")
.array();
for (Object[] custom : customFields) {
String entityName = (String) custom[0];
String fieldName = (String) custom[1];
for (Object[] c : customFields) {
String entityName = (String) c[0];
String fieldName = (String) c[1];
Element entityElement = (Element) rootElement.selectSingleNode("entity[@name='" + entityName + "']");
if (entityElement == null) {
LOG.warn("无效字段 [ " + entityName + "." + fieldName + " ] 无有效依附实体");
LOG.warn("No entity found : " + entityName + "." + fieldName);
continue;
}
Element field = entityElement.addElement("field");
field.addAttribute("name", fieldName)
.addAttribute("physical-name", (String) custom[2])
.addAttribute("description", (String) custom[3])
.addAttribute("nullable", String.valueOf(custom[5])) // true
.addAttribute("creatable", String.valueOf(custom[6])) // true
.addAttribute("updatable", String.valueOf(custom[7])) // true
.addAttribute("max-length", String.valueOf(custom[8]))
.addAttribute("default-value", (String) custom[9])
.addAttribute("repeatable", String.valueOf(custom[15])); // true
.addAttribute("physical-name", (String) c[2])
.addAttribute("description", (String) c[3])
.addAttribute("max-length", String.valueOf(c[8]))
.addAttribute("default-value", (String) c[9])
.addAttribute("nullable", String.valueOf(c[5]))
.addAttribute("creatable", String.valueOf(c[6]))
.addAttribute("updatable", String.valueOf(c[7]))
.addAttribute("repeatable", String.valueOf(c[15]))
.addAttribute("queryable", "true");
if (fieldName.equals(EntityHelper.AutoId)) {
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());
if (dt == DisplayType.DECIMAL) {
field.addAttribute("decimal-scale", "8");
} else if (dt == DisplayType.ANYREFERENCE || dt == DisplayType.REFERENCE
|| dt == DisplayType.PICKLIST || dt == DisplayType.CLASSIFICATION) {
field.addAttribute("ref-entity", (String) custom[10])
.addAttribute("cascade", (String) custom[11]);
field.addAttribute("ref-entity", (String) c[10])
.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()) {
XmlHelper.dump(rootElement);
if (LOG.isDebugEnabled()) {
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.dialect.FieldType;
import cn.devezhao.persist4j.engine.ID;
import cn.devezhao.persist4j.metadata.BaseMeta;
import cn.devezhao.persist4j.metadata.MetadataException;
import com.rebuild.server.Application;
import com.rebuild.server.metadata.entity.EasyMeta;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
@ -33,7 +33,7 @@ public class MetadataHelper {
private static final Log LOG = LogFactory.getLog(MetadataHelper.class);
/**
* 元数据
* 元数据工厂
*
* @return
*/
@ -42,6 +42,8 @@ public class MetadataHelper {
}
/**
* 全部实体
*
* @return
*/
public static Entity[] getEntities() {
@ -53,9 +55,6 @@ public class MetadataHelper {
* @return
*/
public static boolean containsEntity(String entityName) {
if (StringUtils.isBlank(entityName)) {
return false;
}
try {
getEntity(entityName);
return true;
@ -93,16 +92,18 @@ public class MetadataHelper {
/**
* @param entityName
* @return
* @throws MetadataException If not exists
*/
public static Entity getEntity(String entityName) {
public static Entity getEntity(String entityName) throws MetadataException {
return getMetadataFactory().getEntity(entityName);
}
/**
* @param entityCode
* @return
* @throws MetadataException If not exists
*/
public static Entity getEntity(int entityCode) {
public static Entity getEntity(int entityCode) throws MetadataException {
return getMetadataFactory().getEntity(entityCode);
}
@ -117,6 +118,7 @@ public class MetadataHelper {
/**
* @param record
* @return
* @see EasyMeta#getLabel(BaseMeta)
*/
public static String getEntityLabel(ID record) {
return EasyMeta.getLabel(getEntity(record.getEntityCode()));
@ -128,8 +130,7 @@ public class MetadataHelper {
* @return
*/
public static Field getField(String entityName, String fieldName) {
Entity entity = getEntity(entityName);
return entity.getField(fieldName);
return getEntity(entityName).getField(fieldName);
}
/**
@ -173,8 +174,7 @@ public class MetadataHelper {
continue;
}
Entity ref = field.getReferenceEntities()[0];
if (ref.getEntityCode().equals(source.getEntityCode())) {
if (field.getReferenceEntity().getEntityCode().equals(source.getEntityCode())) {
fields.add(field);
}
}
@ -299,7 +299,7 @@ public class MetadataHelper {
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) 2018 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server.metadata.entity;
@ -80,9 +69,26 @@ public class EasyMeta implements BaseMeta {
@Override
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
public boolean isCreatable() {
return baseMeta.isCreatable();
@ -108,10 +114,44 @@ public class EasyMeta implements BaseMeta {
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
*/
public String getLabel() {
@ -120,77 +160,15 @@ public class EasyMeta implements BaseMeta {
}
return StringUtils.defaultIfBlank(getDescription(), getName().toUpperCase());
}
/**
* @param fullName
* @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
*
* 自定义实体/字段 ID
*
* @return
*/
public ID getMetaId() {
Object[] ext = getMetaExt();
return ext == null ? null : (ID) ext[0];
String metaId = getExtraAttr("metaId");
return metaId == null ? null : ID.valueOf(metaId);
}
/**
@ -199,12 +177,19 @@ public class EasyMeta implements BaseMeta {
* @return
*/
public String getComments() {
Object[] ext = getMetaExt();
if (ext != null) {
return (String) ext[1];
}
return StringUtils.defaultIfBlank(getExtraAttrs().getString("comments"), "系统内建");
String comments = getExtraAttr("comments");
if (getMetaId() != null) {
return 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() {
Assert.isTrue(!isField(), "Entity supports only");
String customIcon = null;
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]);
return StringUtils.defaultIfBlank(getExtraAttr("icon"), "texture");
}
/**
* 字段扩展配置
* 指定实体具有和业务实体一样的特性除权限以外指定实体无权限字段
*
* @param name
* @return
*
* @see #getFieldExtConfig()
* @see FieldExtConfigProps
*/
public Object getPropOfFieldExtConfig(String name) {
return getFieldExtConfig().get(name);
}
/**
* 指定实体具有和业务实体一样的特性除权限以外指定实体无权限字段
* @return
*/
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
*/
private boolean isField() {
return baseMeta instanceof Field;
}
public DisplayType getDisplayType() {
Assert.isTrue(isField(), "Field supports only");
/**
* @return
*/
private Object[] getMetaExt() {
Object[] ext;
if (isField()) {
ext = MetadataHelper.getMetadataFactory().getFieldExtmeta((Field) baseMeta);
} else {
ext = MetadataHelper.getMetadataFactory().getEntityExtmeta((Entity) baseMeta);
}
return ext;
}
String displayType = getExtraAttr("displayType");
DisplayType dt = displayType != null
? DisplayType.valueOf(displayType) : converBuiltinFieldType((Field) baseMeta);
if (dt != null) {
return dt;
}
throw new RebuildException("Unsupported field type : " + baseMeta);
}
/**
* 将字段类型转成 DisplayType
@ -292,13 +259,14 @@ public class EasyMeta implements BaseMeta {
if (ft == FieldType.PRIMARY) {
return DisplayType.ID;
} else if (ft == FieldType.REFERENCE) {
int rec = field.getReferenceEntity().getEntityCode();
if (rec == EntityHelper.PickList) {
int typeCode = field.getReferenceEntity().getEntityCode();
if (typeCode == EntityHelper.PickList) {
return DisplayType.PICKLIST;
} else if (rec == EntityHelper.Classification) {
} else if (typeCode == EntityHelper.Classification) {
return DisplayType.CLASSIFICATION;
}
return DisplayType.REFERENCE;
} else {
return DisplayType.REFERENCE;
}
} else if (ft == FieldType.ANY_REFERENCE) {
return DisplayType.ANYREFERENCE;
} else if (ft == FieldType.TIMESTAMP) {
@ -315,23 +283,18 @@ public class EasyMeta implements BaseMeta {
return DisplayType.NUMBER;
} else if (ft == FieldType.DOUBLE || ft == FieldType.DECIMAL) {
return DisplayType.DECIMAL;
}
}
return null;
}
@Override
public String toString() {
return "EASY#" + baseMeta.toString();
}
// --
// -- QUICK
/**
* @param baseMeta
* @param entityOrField
* @return
*/
public static EasyMeta valueOf(BaseMeta baseMeta) {
return new EasyMeta(baseMeta);
public static EasyMeta valueOf(BaseMeta entityOrField) {
return new EasyMeta(entityOrField);
}
/**
@ -355,15 +318,15 @@ public class EasyMeta implements BaseMeta {
* @return
*/
public static DisplayType getDisplayType(Field field) {
return new EasyMeta(field).getDisplayType();
return valueOf(field).getDisplayType();
}
/**
* @param meta
* @param entityOrField
* @return
*/
public static String getLabel(BaseMeta meta) {
return StringUtils.defaultIfBlank(meta.getDescription(), meta.getName().toUpperCase());
public static String getLabel(BaseMeta entityOrField) {
return valueOf(entityOrField).getLabel();
}
/**

View file

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

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2018-2019 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server.metadata.entity;
@ -30,24 +19,35 @@ public class FieldExtConfigProps {
* 是否允许负数
*/
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_FORMAT = "decimalFormat";
/**
* 日期格式
*/
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";
/**
* 允许上传数量
*/
@ -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) 2018 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server.service.base;
@ -62,7 +51,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Observer;
import java.util.Set;
@ -452,8 +440,8 @@ public class GeneralEntityService extends ObservableService {
// 验证新建明细相当于更新主记录
Entity masterEntity = entity.getMasterEntity();
if (masterEntity != null && masterEntity.containsField(EntityHelper.ApprovalId)) {
Field smt = MetadataHelper.getSlaveToMasterField(entity);
ApprovalState state = getApprovalState(newRecord.getID(Objects.requireNonNull(smt).getName()));
Field stmField = MetadataHelper.getSlaveToMasterField(entity);
ApprovalState state = getApprovalState(newRecord.getID(stmField.getName()));
if (state == ApprovalState.APPROVED || state == ApprovalState.PROCESSING) {
String stateType = state == ApprovalState.APPROVED ? "已完成审批" : "正在审批中";
throw new DataSpecificationException("主记录" + stateType + ",不能添加明细");
@ -513,8 +501,8 @@ public class GeneralEntityService extends ObservableService {
* @throws NoRecordFoundException
*/
private ID getMasterId(Entity slaveEntity, ID slaveId) throws NoRecordFoundException {
Field stm = MetadataHelper.getSlaveToMasterField(slaveEntity);
Object[] o = Application.getQueryFactory().uniqueNoFilter(slaveId, Objects.requireNonNull(stm).getName());
Field stmField = MetadataHelper.getSlaveToMasterField(slaveEntity);
Object[] o = Application.getQueryFactory().uniqueNoFilter(slaveId, stmField.getName());
if (o == null) {
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.entity.EasyMeta;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.Assert;
import java.util.HashSet;
import java.util.Set;
@ -113,16 +112,14 @@ public class EntityQueryFilter implements Filter, QueryFilter {
}
String ownFormat = "%s = '%s'";
Field toMasterField = null;
Field stmField = null;
if (useMaster != null) {
toMasterField = MetadataHelper.getSlaveToMasterField(entity);
Assert.notNull(toMasterField, "No STM field found : " + entity);
ownFormat = toMasterField.getName() + "." + ownFormat;
stmField = MetadataHelper.getSlaveToMasterField(entity);
ownFormat = stmField.getName() + "." + ownFormat;
}
if (de == BizzDepthEntry.PRIVATE) {
return appendShareFilter(entity, toMasterField,
return appendShareFilter(entity, stmField,
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());
if (de == BizzDepthEntry.LOCAL) {
return appendShareFilter(entity, toMasterField, deptSql);
return appendShareFilter(entity, stmField, deptSql);
} else if (de == BizzDepthEntry.DEEPDOWN) {
Set<String> sqls = new HashSet<>();
sqls.add(deptSql);
@ -138,7 +135,7 @@ public class EntityQueryFilter implements Filter, QueryFilter {
for (BusinessUnit child : dept.getAllChildren()) {
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);

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server.service.bizz.privileges;
@ -123,15 +112,15 @@ public class PrivilegesGuardInterceptor implements MethodInterceptor, Guard {
if (action == BizzPermission.CREATE) {
// 明细实体
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!");
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)) {
throw new AccessDeniedException("你没有添加明细的权限");
}
allowed = true;
} else {
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.bizz.RoleService;
import com.rebuild.server.service.bizz.UserService;
import org.springframework.util.Assert;
/**
* 实体安全/权限 管理
@ -412,8 +411,7 @@ public class SecurityManager {
private ID getMasterRecordId(ID slaveId) {
Entity entity = MetadataHelper.getEntity(slaveId.getEntityCode());
Field stmField = MetadataHelper.getSlaveToMasterField(entity);
Assert.isTrue(stmField != null, "Non slave entty : " + slaveId);
Object[] primary = Application.getQueryFactory().uniqueNoFilter(slaveId, stmField.getName());
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.EasyMeta;
import com.rebuild.server.metadata.entity.Field2Schema;
import com.rebuild.server.metadata.entity.FieldExtConfigProps;
import com.rebuild.server.service.bizz.UserHelper;
import com.rebuild.utils.CommonsUtils;
import com.rebuild.utils.JSONUtils;
@ -119,8 +120,8 @@ public class MetaFieldControll extends BasePageControll {
// 明细实体
if (((Entity) easyEntity.getBaseMeta()).getMasterEntity() != null) {
Field stf = MetadataHelper.getSlaveToMasterField((Entity) easyEntity.getBaseMeta());
mv.getModel().put("isSlaveToMasterField", stf.equals(fieldMeta));
Field stmField = MetadataHelper.getSlaveToMasterField((Entity) easyEntity.getBaseMeta());
mv.getModel().put("isSlaveToMasterField", stmField.equals(fieldMeta));
} else {
mv.getModel().put("isSlaveToMasterField", false);
}
@ -132,7 +133,7 @@ public class MetaFieldControll extends BasePageControll {
mv.getModel().put("fieldRefentity", refentity.getName());
mv.getModel().put("fieldRefentityLabel", new EasyMeta(refentity).getLabel());
}
mv.getModel().put("fieldExtConfig", easyField.getFieldExtConfig());
mv.getModel().put("fieldExtConfig", easyField.getExtraAttrs(true));
return mv;
}
@ -156,13 +157,13 @@ public class MetaFieldControll extends BasePageControll {
JSON extConfig = null;
if (dt == DisplayType.CLASSIFICATION) {
ID dataId = ID.valueOf(refClassification);
extConfig = JSONUtils.toJSONObject("classification", dataId);
extConfig = JSONUtils.toJSONObject(FieldExtConfigProps.CLASSIFICATION_USE, dataId);
} else if (dt == DisplayType.STATE) {
if (!StateHelper.isStateClass(stateClass)) {
writeFailure(response, "无效状态类");
return;
}
extConfig = JSONUtils.toJSONObject("stateClass", stateClass);
extConfig = JSONUtils.toJSONObject(FieldExtConfigProps.STATE_STATECLASS, stateClass);
}
String fieldName;

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.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)) {
// 过滤所属用户/所属部门等系统字段除了明细引用主实体字段
if (EasyMeta.valueOf(field).isBuiltin() && (stmfField == null || !stmfField.equals(field))) {
if (EasyMeta.valueOf(field).isBuiltin() && (stmField == null || !stmField.equals(field))) {
continue;
}

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2018-2019 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.web.base.general;
@ -123,18 +112,22 @@ public class BatchUpdateControll extends BaseControll {
// 字段选项
if (dt == DisplayType.PICKLIST) {
map.put("options", PickListManager.instance.getPickList(field));
} else if (dt == DisplayType.STATE) {
map.put("options", StateManager.instance.getStateOptions(field));
} else if (dt == DisplayType.MULTISELECT) {
map.put("options", MultiSelectManager.instance.getSelectList(field));
} else if (dt == DisplayType.BOOL) {
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[] { false, ""}));
options.add(JSONUtils.toJSONObject(new String[] { "id", "text" }, new Object[] { true, "" }));
options.add(JSONUtils.toJSONObject(new String[] { "id", "text" }, new Object[] { false, "" }));
map.put("options", options);
} else if (dt == DisplayType.NUMBER || dt == DisplayType.DECIMAL) {
map.put(FieldExtConfigProps.NUMBER_NOTNEGATIVE,
EasyMeta.valueOf(field).getPropOfFieldExtConfig(FieldExtConfigProps.NUMBER_NOTNEGATIVE));
EasyMeta.valueOf(field).getExtraAttr(FieldExtConfigProps.NUMBER_NOTNEGATIVE));
}
return map;

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.web.base.general;
@ -62,7 +51,13 @@ public class GeneralDataListControll extends BaseEntityControll {
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())) {
response.sendError(403, "你没有访问此实体的权限");
return null;

View file

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

View file

@ -13,7 +13,7 @@
<entity name="User" type-code="001" description="用户" name-field="fullName" extra-attrs="{icon:'account'}">
<field name="userId" type="primary" />
<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="fullName" type="string" max-length="100" description="姓名" />
<field name="avatarUrl" type="string" max-length="200" description="头像" extra-attrs="{displayType:'AVATAR'}" />
@ -75,7 +75,7 @@
<index field-list="teamId,userId" type="unique" />
</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="typeCode" type="small-int" 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" />
</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="belongEntity" 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" />
</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="belongEntity" 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" />
</entity>
<entity name="LayoutConfig" type-code="013" description="布局配置(表单/列表/导航/视图(相关项/新建))">
<entity name="LayoutConfig" type-code="013" description="布局配置(表单/列表/导航/视图(相关项/新建))" queryable="false">
<field name="configId" type="primary" />
<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)" />
@ -132,7 +132,7 @@
<field name="configName" type="string" max-length="100" />
</entity>
<entity name="FilterConfig" type-code="014" description="过滤条件配置">
<entity name="FilterConfig" type-code="014" description="过滤条件配置" queryable="false">
<field name="configId" type="primary" />
<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)" />
@ -140,14 +140,14 @@
<field name="filterName" type="string" max-length="100" nullable="false" />
</entity>
<entity name="DashboardConfig" type-code="016" description="仪表盘配置">
<entity name="DashboardConfig" type-code="016" description="仪表盘配置" queryable="false">
<field name="configId" type="primary" />
<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="title" type="string" max-length="100" nullable="false" />
</entity>
<entity name="ChartConfig" type-code="017" description="图表配置">
<entity name="ChartConfig" type-code="017" description="图表配置" queryable="false">
<field name="chartId" type="primary" />
<field name="config" type="text" description="JSON格式配置" nullable="false" />
<field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" />
@ -177,7 +177,7 @@
<index field-list="dataId,fullName,quickCode" />
</entity>
<entity name="ShareAccess" type-code="020" description="记录共享">
<entity name="ShareAccess" type-code="020" description="记录共享" queryable="false">
<field name="accessId" type="primary" />
<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" />
@ -186,7 +186,7 @@
<index field-list="belongEntity,recordId,shareTo" />
</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="item" type="string" max-length="100" nullable="false" updatable="false" />
<field name="value" type="string" max-length="600" nullable="false" />
@ -238,7 +238,7 @@
<index field-list="user,loginTime" />
</entity>
<entity name="AutoFillinConfig" type-code="026" description="字段自动回填配置">
<entity name="AutoFillinConfig" type-code="026" description="字段自动回填配置" queryable="false">
<field name="configId" type="primary" />
<field name="belongEntity" 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" />
</entity>
<entity name="RobotTriggerConfig" type-code="027" description="动作触发器">
<entity name="RobotTriggerConfig" type-code="027" description="动作触发器" queryable="false">
<field name="configId" type="primary" />
<field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" />
<field name="when" type="int" default-value="0" description="动作(累加值)" />
@ -259,7 +259,7 @@
<field name="isDisabled" type="bool" default-value="F" description="是否停用" />
</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="belongEntity" type="string" max-length="100" nullable="false" updatable="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="是否停用" />
</entity>
<entity name="RobotApprovalStep" type-code="029" description="审批步骤记录">
<entity name="RobotApprovalStep" type-code="029" description="审批步骤记录" queryable="false">
<field name="stepId" type="primary" />
<field name="recordId" type="any-reference" 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" />
</entity>
<entity name="DataReportConfig" type-code="032" description="报表">
<entity name="DataReportConfig" type-code="032" description="报表" queryable="false">
<field name="configId" type="primary" />
<field name="belongEntity" type="string" max-length="100" nullable="false" updatable="false" description="应用实体" />
<field name="name" type="string" max-length="100" nullable="false" description="报表名称" />
@ -381,7 +381,7 @@
<index field-list="source,createdBy" />
</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="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" />

View file

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

View file

@ -323,7 +323,7 @@ class DlgImports extends RbModalHandler {
</div>
<div className="clearfix"></div>
<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>

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();
if (dt == DisplayType.DATE) fieldName = "DATE1"; // Black
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) {
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) {
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 {
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()));
MetaschemaImporter importer = new MetaschemaImporter(JSON.parseObject(content));
if (this instanceof TestSupportWithUser) {
if (this instanceof TestSupportWithUser) {
TaskExecutors.exec(importer);
} else {
TaskExecutors.run(importer.setUser(UserService.ADMIN_USER));

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2019 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server.configuration;
@ -51,7 +40,7 @@ public class AutoFillinManagerTest extends TestSupportWithUser {
System.out.println(
AutoFillinManager.instance.conversionCompatibleValue(test.getField("datetime"), textField, CalendarUtils.now()));
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

View file

@ -1,24 +1,12 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2019 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server.metadata;
import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.Field;
import com.rebuild.server.TestSupport;
import org.junit.Test;
@ -31,14 +19,11 @@ public class DefaultValueHelperTest extends TestSupport {
@Test
public void testExprDefaultValue() throws Exception {
Entity e = MetadataHelper.getEntity(TEST_ENTITY);
Field date = e.getField("date");
System.out.println(DefaultValueHelper.exprDefaultValue(date, "{NOW}"));
System.out.println(DefaultValueHelper.exprDefaultValue(date, "{NOW - 1H}"));
System.out.println(DefaultValueHelper.exprDefaultValue(date, "{NOW + 1M}"));
System.out.println(DefaultValueHelper.exprDefaultValue(date, "2019-09-01"));
System.out.println(DefaultValueHelper.exprDefaultValue(date, "2019-09-01 01:01"));
Field dateField = MetadataHelper.getField(TEST_ENTITY, "DATE1");
System.out.println(DefaultValueHelper.exprDefaultValue(dateField, "{NOW}"));
System.out.println(DefaultValueHelper.exprDefaultValue(dateField, "{NOW - 1H}"));
System.out.println(DefaultValueHelper.exprDefaultValue(dateField, "{NOW + 1M}"));
System.out.println(DefaultValueHelper.exprDefaultValue(dateField, "2019-09-01"));
System.out.println(DefaultValueHelper.exprDefaultValue(dateField, "2019-09-01 01:01"));
}
}

View file

@ -1,19 +1,8 @@
/*
rebuild - Building your business-systems freely.
Copyright (C) 2019 devezhao <zhaofang123@gmail.com>
Copyright (c) REBUILD <https://getrebuild.com/> and its owners. All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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/>.
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.server.metadata.entity;
@ -30,9 +19,16 @@ import org.junit.Test;
public class EasyMetaTest extends TestSupport {
@Test
public void test() throws Exception {
public void getLabel() throws Exception {
Entity user = MetadataHelper.getEntity("User");
EasyMeta.getLabel(user, "roleId.name");
System.out.println(EasyMeta.getEntityShow(user));
}
@Test
public void testEntities() {
for (Entity entity : MetadataHelper.getEntities()) {
System.out.println(entity);
}
}
}