Merge pull request #415 from getrebuild/copy-entity

Copy entity
This commit is contained in:
RB 2021-12-20 11:27:13 +08:00 committed by GitHub
commit 51f59ab36f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 478 additions and 233 deletions

2
@rbv

@ -1 +1 @@
Subproject commit f6f4a5f87e30c9865e580d117d30e1b8a4c9a41b
Subproject commit 29deac78d1ba561dc503aefb2ab6530a9438b460

View file

@ -8,19 +8,31 @@ See LICENSE and COMMERCIAL in the project root for license information.
package com.rebuild.core;
import cn.devezhao.commons.ObjectUtils;
import cn.devezhao.commons.xml.XMLHelper;
import com.rebuild.core.support.ConfigurationItem;
import com.rebuild.core.support.RebuildConfiguration;
import com.rebuild.core.support.distributed.KnownJedisPool;
import com.rebuild.core.support.setup.InstallState;
import com.rebuild.utils.CommonsUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.springframework.cache.CacheManager;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
/**
* NOTE JRebel reloading error
*
* @author devezhao
* @since 2020/9/23
*/
@ -41,9 +53,24 @@ public class BootConfiguration implements InstallState {
@Bean
CacheManager createCacheManager() throws IOException {
net.sf.ehcache.CacheManager cacheManager;
String datadir = BootEnvironmentPostProcessor.getProperty(ConfigurationItem.DataDirectory.name());
if (StringUtils.isBlank(datadir)) {
cacheManager = new net.sf.ehcache.CacheManager(CommonsUtils.getStreamOfRes("ehcache.xml"));
} else {
// 使用数据目录存储缓存文件
Document config = XMLHelper.createDocument(CommonsUtils.getStreamOfRes("ehcache.xml"));
Element diskStore = (Element) config.getRootElement().selectSingleNode("//diskStore");
File tempdir = RebuildConfiguration.getFileOfTemp(".ehcache");
diskStore.addAttribute("path", tempdir.getAbsolutePath());
InputStream is = new ByteArrayInputStream(config.asXML().getBytes(StandardCharsets.UTF_8));
cacheManager = new net.sf.ehcache.CacheManager(is);
}
EhCacheCacheManager manager = new EhCacheCacheManager();
manager.setCacheManager(
new net.sf.ehcache.CacheManager(CommonsUtils.getStreamOfRes("ehcache.xml")));
manager.setCacheManager(cacheManager);
return manager;
}
@ -56,12 +83,16 @@ public class BootConfiguration implements InstallState {
* @return
*/
public static JedisPool createJedisPoolInternal() {
String use = BootEnvironmentPostProcessor.getProperty("db.CacheHost");
if ("0".equals(use)) return USE_EHCACHE;
String useHost = BootEnvironmentPostProcessor.getProperty("db.CacheHost");
if ("0".equals(useHost)) return USE_EHCACHE;
String spec = BootEnvironmentPostProcessor.getProperty(ConfigurationItem.RedisDatabase.name());
int database = NumberUtils.toInt(spec, (Integer) ConfigurationItem.RedisDatabase.getDefaultValue());
return new KnownJedisPool(
StringUtils.defaultIfBlank(use, "127.0.0.1"),
StringUtils.defaultIfBlank(useHost, "127.0.0.1"),
ObjectUtils.toInt(BootEnvironmentPostProcessor.getProperty("db.CachePort"), 6379),
BootEnvironmentPostProcessor.getProperty("db.CachePassword", null));
BootEnvironmentPostProcessor.getProperty("db.CachePassword", null),
database);
}
}

View file

@ -13,7 +13,6 @@ import com.rebuild.core.support.RebuildConfiguration;
import com.rebuild.core.support.setup.InstallState;
import com.rebuild.core.support.setup.Installer;
import com.rebuild.utils.AES;
import com.rebuild.utils.RebuildBanner;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.slf4j.impl.StaticLoggerBinder;
@ -170,6 +169,7 @@ public class BootEnvironmentPostProcessor implements EnvironmentPostProcessor, I
String value = null;
// in CLI
if (ConfigurationItem.DataDirectory.name().equalsIgnoreCase(name)
|| ConfigurationItem.RedisDatabase.name().equalsIgnoreCase(name)
|| ConfigurationItem.MobileUrl.name().equalsIgnoreCase(name)
|| ConfigurationItem.RbStoreUrl.name().equalsIgnoreCase(name)) {
value = StringUtils.defaultIfBlank(System.getProperty(name), System.getProperty(V2_PREFIX + name));

View file

@ -46,8 +46,7 @@ public abstract class BaseCacheTemplate<V extends Serializable> implements Cache
this.delegate = new EhcacheDriver<>(backup);
}
String fix = StringUtils.defaultIfBlank(System.getProperty("cache.keyprefix"), "RB.");
this.keyPrefix = fix + StringUtils.defaultIfBlank(keyPrefix, StringUtils.EMPTY);
this.keyPrefix = "RB." + StringUtils.defaultIfBlank(keyPrefix, StringUtils.EMPTY);
}
@Override

View file

@ -8,7 +8,6 @@ See LICENSE and COMMERCIAL in the project root for license information.
package com.rebuild.core.cache;
import com.rebuild.core.Application;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;

View file

@ -133,8 +133,8 @@ public class NavBuilder extends NavManager {
return true;
}
return !Application.getPrivilegesManager().allowRead(user,
MetadataHelper.getEntity(value).getEntityCode());
return !Application.getPrivilegesManager().allowRead(
user, MetadataHelper.getEntity(value).getEntityCode());
} else if ("URL".equals(type)) {
String[] split = value.split(URL_BIND_EP);

View file

@ -30,9 +30,9 @@ public class RebuildApiManager implements ConfigManager {
*/
public ConfigBean getApp(String appid) {
final String ckey = CKEY_PREFIX + appid;
ConfigBean config = (ConfigBean) Application.getCommonsCache().getx(ckey);
if (config != null) {
return config;
ConfigBean cb = (ConfigBean) Application.getCommonsCache().getx(ckey);
if (cb != null) {
return cb;
}
Object[] o = Application.createQueryNoFilter(
@ -41,13 +41,13 @@ public class RebuildApiManager implements ConfigManager {
.unique();
if (o == null) return null;
config = new ConfigBean()
cb = new ConfigBean()
.set("appId", appid)
.set("appSecret", o[0])
.set("bindUser", o[1])
.set("bindIps", o[2]);
Application.getCommonsCache().putx(ckey, config);
return config;
Application.getCommonsCache().putx(ckey, cb);
return cb;
}
@Override

View file

@ -61,9 +61,9 @@ public class PickListManager implements ConfigManager {
*/
public ConfigBean[] getPickListRaw(String entity, String field, boolean includeHide) {
final String ckey = String.format("PickList-%s.%s", entity, field);
ConfigBean[] entries = (ConfigBean[]) Application.getCommonsCache().getx(ckey);
ConfigBean[] cached = (ConfigBean[]) Application.getCommonsCache().getx(ckey);
if (entries == null) {
if (cached == null) {
Object[][] array = Application.createQueryNoFilter(
"select itemId,text,isDefault,isHide,maskValue from PickList where belongEntity = ? and belongField = ? order by seq asc")
.setParameter(1, entity)
@ -80,12 +80,12 @@ public class PickListManager implements ConfigManager {
list.add(entry);
}
entries = list.toArray(new ConfigBean[0]);
Application.getCommonsCache().putx(ckey, entries);
cached = list.toArray(new ConfigBean[0]);
Application.getCommonsCache().putx(ckey, cached);
}
List<ConfigBean> ret = new ArrayList<>();
for (ConfigBean entry : entries) {
for (ConfigBean entry : cached) {
if (includeHide || !entry.getBoolean("hide")) {
ret.add(entry.clone());
}

View file

@ -0,0 +1,92 @@
/*
Copyright (c) Ruifang Tech <http://ruifang-tech.com/> and/or its owners. All rights reserved.
*/
package com.rebuild.core.metadata.impl;
import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.engine.ID;
import com.alibaba.fastjson.JSONObject;
import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.privileges.UserHelper;
import com.rebuild.core.rbstore.MetaSchemaGenerator;
import com.rebuild.core.rbstore.MetaschemaImporter;
import com.rebuild.core.support.i18n.Language;
import com.rebuild.core.support.task.TaskExecutors;
import com.rebuild.utils.RbAssert;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.RandomUtils;
/**
* 复制实体
*
* @author devezhao
* @see MetaSchemaGenerator
* @see MetaschemaImporter
* @since 2021/12/17
*/
public class CopyEntity extends Entity2Schema {
final private Entity sourceEntity;
public CopyEntity(Entity sourceEntity) {
this.sourceEntity = sourceEntity;
}
/**
* @param entityName
* @param detailName
* @return
*/
public String copy(String entityName, String detailName) {
final ID user = getUser();
RbAssert.isAllow(UserHelper.isSuperAdmin(user), Language.L("仅超级管理员可操作"));
// 导出
JSONObject schemadata = (JSONObject) new MetaSchemaGenerator(sourceEntity).generate();
String uniqueEntityName = clearConfig(schemadata, entityName);
JSONObject detailSchema = schemadata.getJSONObject("detail");
if (StringUtils.isBlank(detailName)) {
schemadata.remove("detail");
} else if (detailSchema != null) {
clearConfig(detailSchema, detailName);
}
// 导入
MetaschemaImporter importer = new MetaschemaImporter(schemadata);
importer.setUser(user);
TaskExecutors.run(importer);
// TODO 保留审批字段
return uniqueEntityName;
}
private String clearConfig(JSONObject schema, String entityName) {
schema.remove(MetaSchemaGenerator.CFG_TRANSFORMS);
schema.remove(MetaSchemaGenerator.CFG_APPROVALS);
schema.remove(MetaSchemaGenerator.CFG_TRIGGERS);
schema.remove(MetaSchemaGenerator.CFG_FILTERS);
// 以下保留
// schema.remove(MetaSchemaGenerator.CFG_FILLINS);
// schema.remove(MetaSchemaGenerator.CFG_LAYOUTS);
String uniqueEntityName = toPinyinName(entityName);
for (int i = 0; i < 5; i++) {
if (MetadataHelper.containsEntity(uniqueEntityName)) {
uniqueEntityName += RandomUtils.nextInt(99);
} else {
break;
}
}
schema.put("entity", uniqueEntityName);
schema.put("entityLabel", entityName);
return uniqueEntityName;
}
}

View file

@ -23,7 +23,6 @@ import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.metadata.easymeta.DisplayType;
import com.rebuild.core.metadata.easymeta.EasyEntity;
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
import com.rebuild.core.privileges.UserService;
import com.rebuild.core.support.License;
import com.rebuild.core.support.i18n.Language;
import lombok.extern.slf4j.Slf4j;
@ -39,11 +38,12 @@ import org.apache.commons.lang.math.RandomUtils;
@Slf4j
public class Entity2Schema extends Field2Schema {
/**
* @param user
*/
public Entity2Schema() {
super();
}
public Entity2Schema(ID user) {
super(user);
super.setUser(user);
}
/**
@ -70,7 +70,6 @@ public class Entity2Schema extends Field2Schema {
if (MetadataHelper.containsEntity(entityName)) {
throw new MetadataModificationException(Language.L("实体已存在 : %s", entityName));
}
} else {
entityName = toPinyinName(entityLabel);
for (int i = 0; i < 5; i++) {
@ -103,7 +102,7 @@ public class Entity2Schema extends Field2Schema {
nameFiled = entityName + "Name";
}
Record record = EntityHelper.forNew(EntityHelper.MetaEntity, user);
Record record = EntityHelper.forNew(EntityHelper.MetaEntity, getUser());
record.setString("entityLabel", entityLabel);
record.setString("entityName", entityName);
record.setString("physicalName", physicalName);
@ -179,9 +178,7 @@ public class Entity2Schema extends Field2Schema {
* @return
*/
public boolean dropEntity(Entity entity, boolean force) {
if (!user.equals(UserService.ADMIN_USER)) {
throw new MetadataModificationException(Language.L("仅超级管理员可删除实体"));
}
getUser(); // Check admin
EasyEntity easy = EasyMetaFactory.valueOf(entity);
ID metaRecordId = easy.getMetaId();
@ -224,7 +221,7 @@ public class Entity2Schema extends Field2Schema {
// 先删配置
final ID sessionUser = UserContextHolder.getUser(true);
if (sessionUser == null) UserContextHolder.setUser(user);
if (sessionUser == null) UserContextHolder.setUser(getUser());
try {
Application.getBean(MetaEntityService.class).delete(metaRecordId);

View file

@ -27,6 +27,7 @@ import com.rebuild.core.metadata.easymeta.DisplayType;
import com.rebuild.core.metadata.easymeta.EasyField;
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
import com.rebuild.core.privileges.UserHelper;
import com.rebuild.core.support.SetUser;
import com.rebuild.core.support.i18n.Language;
import com.rebuild.core.support.setup.Installer;
import com.rebuild.utils.BlockList;
@ -46,20 +47,26 @@ import java.util.Set;
* @since 08/13/2018
*/
@Slf4j
public class Field2Schema {
public class Field2Schema extends SetUser {
// 小数位真实长度
private static final int DECIMAL_SCALE = 8;
final protected ID user;
final protected Set<ID> recordedMetaId = new HashSet<>();
/**
* @param user
*/
public Field2Schema() {
super();
}
public Field2Schema(ID user) {
super.setUser(user);
}
@Override
public ID getUser() {
ID user = super.getUser();
RbAssert.isAllow(UserHelper.isSuperAdmin(user), Language.L("仅超级管理员可操作"));
this.user = user;
return user;
}
/**
@ -234,7 +241,7 @@ public class Field2Schema {
String physicalName = StringHelper.hyphenate(fieldName).toUpperCase();
Record recordOfField = EntityHelper.forNew(EntityHelper.MetaField, user);
Record recordOfField = EntityHelper.forNew(EntityHelper.MetaField, getUser());
recordOfField.setString("belongEntity", entity.getName());
recordOfField.setString("fieldName", fieldName);
recordOfField.setString("physicalName", physicalName);

View file

@ -17,10 +17,10 @@ import com.rebuild.core.Application;
import com.rebuild.core.configuration.ConfigBean;
import com.rebuild.core.configuration.general.PickListManager;
import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.metadata.easymeta.DisplayType;
import com.rebuild.core.metadata.easymeta.EasyEntity;
import com.rebuild.core.metadata.easymeta.EasyField;
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
import com.rebuild.core.metadata.easymeta.DisplayType;
import com.rebuild.core.privileges.UserService;
import com.rebuild.utils.JSONUtils;
import org.apache.commons.io.FileUtils;
@ -38,6 +38,13 @@ import java.io.IOException;
*/
public class MetaSchemaGenerator {
public static final String CFG_FILLINS = "fillins";
public static final String CFG_LAYOUTS = "layouts";
public static final String CFG_FILTERS = "filters";
public static final String CFG_TRIGGERS = "triggers";
public static final String CFG_APPROVALS = "approvals";
public static final String CFG_TRANSFORMS = "transforms";
final private Entity mainEntity;
/**
@ -68,12 +75,7 @@ public class MetaSchemaGenerator {
return schema;
}
/**
* @param entity
* @param isDetail
* @return
*/
private JSON performEntity(Entity entity, boolean isDetail) {
private JSON performEntity(Entity entity, boolean detail) {
JSONObject schemaEntity = new JSONObject(true);
// 实体
@ -92,29 +94,31 @@ public class MetaSchemaGenerator {
for (Field field : entity.getFields()) {
if (field.getType() == FieldType.PRIMARY
|| MetadataHelper.isCommonsField(field)
|| (isDetail && MetadataHelper.getDetailToMainField(entity).equals(field))) {
|| (detail && MetadataHelper.getDetailToMainField(entity).equals(field))) {
continue;
}
metaFields.add(performField(field));
}
schemaEntity.put("fields", metaFields);
// 布局
schemaEntity.put("layouts", performLayouts(entity));
// 表单回填
schemaEntity.put("fillins", performFillins(entity));
// 高级过滤
schemaEntity.put("filters", performFilters(entity));
schemaEntity.put(CFG_FILLINS, performFillins(entity));
// 布局
schemaEntity.put(CFG_LAYOUTS, performLayouts(entity));
// 高级查询
schemaEntity.put(CFG_FILTERS, performFilters(entity));
// 触发器
schemaEntity.put("triggers", performTriggers(entity));
schemaEntity.put(CFG_TRIGGERS, performTriggers(entity));
if (!isDetail) {
if (!detail) {
// 审批流程
schemaEntity.put("approvals", performApprovals(entity));
schemaEntity.put(CFG_APPROVALS, performApprovals(entity));
// 字段转换
schemaEntity.put("transforms", performTransforms(entity));
schemaEntity.put(CFG_TRANSFORMS, performTransforms(entity));
}
// TODO 报表模板?
return schemaEntity;
}

View file

@ -10,10 +10,12 @@ package com.rebuild.core.rbstore;
import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.Field;
import cn.devezhao.persist4j.Record;
import cn.devezhao.persist4j.engine.ID;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rebuild.core.Application;
import com.rebuild.core.UserContextHolder;
import com.rebuild.core.configuration.general.*;
import com.rebuild.core.metadata.EntityHelper;
import com.rebuild.core.metadata.EntityRecordCreator;
@ -36,6 +38,7 @@ import com.rebuild.utils.JSONUtils;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -51,7 +54,7 @@ public class MetaschemaImporter extends HeavyTask<String> {
private JSONObject data;
private List<Object[]> picklistHolders = new ArrayList<>();
private Map<Field, JSONObject> picklistHolders = new HashMap<>();
private boolean needClearContextHolder = false;
@ -69,9 +72,7 @@ public class MetaschemaImporter extends HeavyTask<String> {
*/
public String verfiy() {
String hasError = verfiyEntity(data);
if (hasError != null) {
return hasError;
}
if (hasError != null) return hasError;
JSONObject detailData = data.getJSONObject("detail");
if (detailData == null) detailData = data.getJSONObject("slave");
@ -93,13 +94,16 @@ public class MetaschemaImporter extends HeavyTask<String> {
for (Object o : entity.getJSONArray("fields")) {
JSONObject field = (JSONObject) o;
String dt = field.getString("displayType");
if (DisplayType.REFERENCE.name().equals(dt) || DisplayType.N2NREFERENCE.name().equals(dt)) {
if (DisplayType.REFERENCE.name().equals(dt)
|| DisplayType.N2NREFERENCE.name().equals(dt)) {
String refEntity = field.getString("refEntity");
if (!entityName.equals(refEntity) && !MetadataHelper.containsEntity(refEntity)) {
return Language.L("缺少必要的引用实体 : %s (%s)", field.getString("fieldLabel"), refEntity);
}
}
}
return null;
}
@ -136,10 +140,18 @@ public class MetaschemaImporter extends HeavyTask<String> {
}
}
for (Object[] picklist : picklistHolders) {
Field refreshField = (Field) picklist[0];
refreshField = MetadataHelper.getField(refreshField.getOwnEntity().getName(), refreshField.getName());
Application.getBean(PickListService.class).updateBatch(refreshField, (JSONObject) picklist[1]);
final ID sessionUser = UserContextHolder.getUser(true);
if (sessionUser == null) UserContextHolder.setUser(getUser());
// 字段选项
try {
for (Map.Entry<Field, JSONObject> e : picklistHolders.entrySet()) {
Field field = e.getKey();
Application.getBean(PickListService.class).updateBatch(
MetadataHelper.getField(field.getOwnEntity().getName(), field.getName()), e.getValue());
}
} finally {
if (sessionUser == null) UserContextHolder.clear();
}
setCompleted(100);
@ -156,34 +168,35 @@ public class MetaschemaImporter extends HeavyTask<String> {
}
/**
* @param schemaEntity
* @param mainEntityName
* @param schema
* @param mainEntity
* @return
* @throws MetadataModificationException
*/
private String performEntity(JSONObject schemaEntity, String mainEntityName) throws MetadataModificationException {
final String entityName = schemaEntity.getString("entity");
final String entityLabel = schemaEntity.getString("entityLabel");
private String performEntity(JSONObject schema, String mainEntity) throws MetadataModificationException {
final String entityName = schema.getString("entity");
final String entityLabel = schema.getString("entityLabel");
Entity2Schema entity2Schema = new Entity2Schema(this.getUser());
entity2Schema.createEntity(
entityName, entityLabel, schemaEntity.getString("comments"), mainEntityName, false);
Entity entity = MetadataHelper.getEntity(entityName);
entityName, entityLabel, schema.getString("comments"), mainEntity, false);
Entity newEntity = MetadataHelper.getEntity(entityName);
this.setCompleted((int) (this.getCompleted() * 1.5));
JSONArray fields = schemaEntity.getJSONArray("fields");
JSONArray fields = schema.getJSONArray("fields");
try {
List<Field> fieldsList = new ArrayList<>();
for (Object field : fields) {
Field unsafe = performField((JSONObject) field, entity);
Field unsafe = performField((JSONObject) field, newEntity);
if (unsafe != null) fieldsList.add(unsafe);
}
// 同步字段到数据库
new Field2Schema(UserService.ADMIN_USER).schema2Database(entity, fieldsList.toArray(new Field[0]));
new Field2Schema(UserService.ADMIN_USER).schema2Database(newEntity, fieldsList.toArray(new Field[0]));
} catch (Exception ex) {
entity2Schema.dropEntity(entity, true);
entity2Schema.dropEntity(newEntity, true);
if (ex instanceof MetadataModificationException) {
throw ex;
@ -192,17 +205,18 @@ public class MetaschemaImporter extends HeavyTask<String> {
}
}
Record needUpdate = EntityHelper.forUpdate(EasyMetaFactory.valueOf(entity).getMetaId(), this.getUser(), false);
Record needUpdate = EntityHelper.forUpdate(
EasyMetaFactory.valueOf(newEntity).getMetaId(), this.getUser(), false);
String nameField = schemaEntity.getString("nameField");
String nameField = schema.getString("nameField");
if (nameField != null) {
needUpdate.setString("nameField", nameField);
}
String entityIcon = schemaEntity.getString("entityIcon");
String entityIcon = schema.getString("entityIcon");
if (entityIcon != null) {
needUpdate.setString("icon", entityIcon);
}
String quickFields = schemaEntity.getString("quickFields");
String quickFields = schema.getString("quickFields");
if (quickFields != null) {
needUpdate.setString("extConfig", JSONUtils.toJSONObject("quickFields", quickFields).toJSONString());
}
@ -214,24 +228,24 @@ public class MetaschemaImporter extends HeavyTask<String> {
// 刷新元数据
MetadataHelper.getMetadataFactory().refresh(false);
// 布局
JSONObject layouts = schemaEntity.getJSONObject("layouts");
if (layouts != null) {
for (Map.Entry<String, Object> e : layouts.entrySet()) {
performLayout(entityName, e.getKey(), (JSON) e.getValue());
}
}
// 表单回填
JSONArray fillins = schemaEntity.getJSONArray("fillins");
JSONArray fillins = schema.getJSONArray(MetaSchemaGenerator.CFG_FILLINS);
if (fillins != null) {
for (Object o : fillins) {
performFillin(entityName, (JSONObject) o);
}
}
// 布局
JSONObject layouts = schema.getJSONObject(MetaSchemaGenerator.CFG_LAYOUTS);
if (layouts != null) {
for (Map.Entry<String, Object> e : layouts.entrySet()) {
performLayout(entityName, e.getKey(), (JSON) e.getValue());
}
}
// 高级查询
JSONArray filters = schemaEntity.getJSONArray("filters");
JSONArray filters = schema.getJSONArray(MetaSchemaGenerator.CFG_FILTERS);
if (filters != null) {
for (Object o : filters) {
performFilter(entityName, (JSONObject) o);
@ -239,7 +253,7 @@ public class MetaschemaImporter extends HeavyTask<String> {
}
// 触发器
JSONArray triggers = schemaEntity.getJSONArray("triggers");
JSONArray triggers = schema.getJSONArray(MetaSchemaGenerator.CFG_TRIGGERS);
if (triggers != null) {
for (Object o : triggers) {
performTrigger(entityName, (JSONObject) o);
@ -247,7 +261,7 @@ public class MetaschemaImporter extends HeavyTask<String> {
}
// 审批流程
JSONArray approvals = schemaEntity.getJSONArray("approvals");
JSONArray approvals = schema.getJSONArray(MetaSchemaGenerator.CFG_APPROVALS);
if (approvals != null) {
for (Object o : approvals) {
performApproval(entityName, (JSONObject) o);
@ -255,7 +269,7 @@ public class MetaschemaImporter extends HeavyTask<String> {
}
// 记录转换
JSONArray transforms = schemaEntity.getJSONArray("transforms");
JSONArray transforms = schema.getJSONArray(MetaSchemaGenerator.CFG_TRANSFORMS);
if (transforms != null) {
for (Object o : transforms) {
performTransform(entityName, (JSONObject) o);
@ -277,7 +291,10 @@ public class MetaschemaImporter extends HeavyTask<String> {
}
Field unsafeField = new Field2Schema(this.getUser()).createUnsafeField(
belong, fieldName, fieldLabel, dt,
belong,
fieldName,
fieldLabel,
dt,
schemaField.getBooleanValue("nullable"),
true,
schemaField.getBooleanValue("updatable"),
@ -290,8 +307,7 @@ public class MetaschemaImporter extends HeavyTask<String> {
schemaField.getString("defaultValue"));
if (DisplayType.PICKLIST == dt || DisplayType.MULTISELECT == dt) {
picklistHolders.add(new Object[] {
unsafeField, performPickList(schemaField.getJSONArray("items")) });
picklistHolders.put(unsafeField, performPickList(schemaField.getJSONArray("items")));
}
return unsafeField;
@ -300,7 +316,7 @@ public class MetaschemaImporter extends HeavyTask<String> {
private JSONObject performPickList(JSONArray items) {
JSONArray shown = new JSONArray();
for (Object o : items) {
JSONArray item = (JSONArray) o;
JSONArray item = o instanceof Object[] ? (JSONArray) JSON.toJSON(o) : (JSONArray) o;
JSONObject option = JSONUtils.toJSONObject(
new String[] { "text", "default" },

View file

@ -43,9 +43,9 @@ public class ChartManager implements ConfigManager {
*/
public ConfigBean getChart(ID chartid) {
final String ckey = "Chart-" + chartid;
ConfigBean entry = (ConfigBean) Application.getCommonsCache().getx(ckey);
if (entry != null) {
return entry.clone();
ConfigBean cb = (ConfigBean) Application.getCommonsCache().getx(ckey);
if (cb != null) {
return cb.clone();
}
Object[] o = Application.createQueryNoFilter(
@ -64,13 +64,13 @@ public class ChartManager implements ConfigManager {
}
}
entry = new ConfigBean()
cb = new ConfigBean()
.set("title", o[0])
.set("type", o[1])
.set("config", o[2] instanceof JSON ? o[2] : JSON.parse((String) o[2]))
.set("createdBy", o[3]);
Application.getCommonsCache().putx(ckey, entry);
return entry.clone();
Application.getCommonsCache().putx(ckey, cb);
return cb.clone();
}
/**

View file

@ -82,9 +82,9 @@ public class ProjectManager implements ConfigManager {
* @return
*/
private ConfigBean[] getProjects() {
ConfigBean[] projects = (ConfigBean[]) Application.getCommonsCache().getx(CKEY_PROJECTS);
ConfigBean[] cached = (ConfigBean[]) Application.getCommonsCache().getx(CKEY_PROJECTS);
if (projects == null) {
if (cached == null) {
Object[][] array = Application.createQueryNoFilter(
"select configId,projectCode,projectName,iconName,scope,members,principal,extraDefinition,status from ProjectConfig")
.array();
@ -117,11 +117,11 @@ public class ProjectManager implements ConfigManager {
alist.add(e);
}
projects = alist.toArray(new ConfigBean[0]);
Application.getCommonsCache().putx(CKEY_PROJECTS, projects);
cached = alist.toArray(new ConfigBean[0]);
Application.getCommonsCache().putx(CKEY_PROJECTS, cached);
}
for (ConfigBean p : projects) {
for (ConfigBean p : cached) {
Set<ID> members = Collections.emptySet();
String userDefs = p.getString("_members");
if (StringUtils.isNotBlank(userDefs) && userDefs.length() >= 20) {
@ -129,7 +129,7 @@ public class ProjectManager implements ConfigManager {
}
p.set("members", members);
}
return projects;
return cached;
}
/**
@ -160,9 +160,9 @@ public class ProjectManager implements ConfigManager {
Assert.notNull(projectId, "[projectId] cannot be null");
final String ckey = CKEY_PLANS + projectId;
ConfigBean[] cache = (ConfigBean[]) Application.getCommonsCache().getx(ckey);
ConfigBean[] cached = (ConfigBean[]) Application.getCommonsCache().getx(ckey);
if (cache == null) {
if (cached == null) {
Object[][] array = Application.createQueryNoFilter(
"select configId,planName,flowStatus,flowNexts from ProjectPlanConfig where projectId = ? order by seq")
.setParameter(1, projectId)
@ -185,10 +185,10 @@ public class ProjectManager implements ConfigManager {
alist.add(e);
}
cache = alist.toArray(new ConfigBean[0]);
Application.getCommonsCache().putx(ckey, cache);
cached = alist.toArray(new ConfigBean[0]);
Application.getCommonsCache().putx(ckey, cached);
}
return cache.clone();
return cached.clone();
}
/**

View file

@ -93,9 +93,10 @@ public enum ConfigurationItem {
SamlIdPEntityid, SamlIdPEndpoint, SamlIdPSloEndpoint, SamlIdPCert,
// !!! 仅命令行适用
DataDirectory, // 数据目录
MobileUrl, // 移动端地址
RbStoreUrl // 在线仓库地址
DataDirectory, // 数据目录
RedisDatabase(0), // Redis DB
MobileUrl, // 移动端地址
RbStoreUrl // 在线仓库地址
;

View file

@ -82,9 +82,10 @@ public class RebuildConfiguration extends KVStorage {
File temp = getFileOfData("temp");
if (!temp.exists()) {
if (!temp.mkdirs()) {
throw new RebuildException("Cannot mkdirs for temp : " + temp);
throw new RebuildException("Cannot mkdir for temp directory : " + temp);
}
}
return filepath == null ? temp : new File(temp, filepath);
}

View file

@ -16,16 +16,12 @@ import redis.clients.jedis.JedisPoolConfig;
*/
public class KnownJedisPool extends JedisPool {
public static final int TIMEOUT = 5000;
public static final int DATABASE = 0;
private String host;
private int port;
private String password;
public KnownJedisPool(String host, int port, String password) {
super(new JedisPoolConfig(), host, port, TIMEOUT, password, DATABASE);
public KnownJedisPool(String host, int port, String password, int database) {
super(new JedisPoolConfig(), host, port, 5000, password, database);
this.host = host;
this.port = port;
this.password = password;

View file

@ -20,6 +20,7 @@ import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.metadata.MetadataSorter;
import com.rebuild.core.metadata.easymeta.EasyEntity;
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
import com.rebuild.core.metadata.impl.CopyEntity;
import com.rebuild.core.metadata.impl.Entity2Schema;
import com.rebuild.core.metadata.impl.MetaEntityService;
import com.rebuild.core.privileges.UserHelper;
@ -64,6 +65,8 @@ public class MetaEntityController extends BaseController {
@GetMapping("entity/{entity}/base")
public ModelAndView pageBase(@PathVariable String entity, HttpServletResponse response) throws IOException {
Entity metaEntity = MetadataHelper.getEntity(entity);
// 不允许访问
if (!(MetadataHelper.isBusinessEntity(metaEntity) || MetadataHelper.isBizzEntity(metaEntity))) {
response.sendError(403);
return null;
@ -129,7 +132,6 @@ public class MetaEntityController extends BaseController {
@PostMapping("entity/entity-new")
public RespBody entityNew(HttpServletRequest request) {
final ID user = getRequestUser(request);
final JSONObject reqJson = (JSONObject) ServletUtils.getRequestJson(request);
String label = reqJson.getString("label");
@ -149,7 +151,7 @@ public class MetaEntityController extends BaseController {
}
try {
String entityName = new Entity2Schema(user)
String entityName = new Entity2Schema()
.createEntity(label, comments, mainEntity, getBoolParameter(request, "nameField"));
return RespBody.ok(entityName);
} catch (Exception ex) {
@ -158,6 +160,23 @@ public class MetaEntityController extends BaseController {
}
}
@PostMapping("entity/entity-copy")
public RespBody entityCopy(HttpServletRequest request) {
final JSONObject reqJson = (JSONObject) ServletUtils.getRequestJson(request);
Entity sourceEntity = MetadataHelper.getEntity(reqJson.getString("sourceEntity"));
String entityName = reqJson.getString("entityName");
String detailEntityName = reqJson.getString("detailEntityName");
try {
entityName = new CopyEntity(sourceEntity).copy(entityName, detailEntityName);
return RespBody.ok(entityName);
} catch (Exception ex) {
log.error("entity-copy", ex);
return RespBody.error(ex.getLocalizedMessage());
}
}
@PostMapping("entity/entity-update")
public RespBody entityUpdate(HttpServletRequest request) {
final ID user = getRequestUser(request);
@ -193,12 +212,11 @@ public class MetaEntityController extends BaseController {
@RequestMapping("entity/entity-drop")
public RespBody entityDrop(HttpServletRequest request) {
final ID user = getRequestUser(request);
final Entity entity = getEntityById(getIdParameterNotNull(request, "id"));
final boolean force = getBoolParameter(request, "force", false);
try {
boolean drop = new Entity2Schema(user).dropEntity(entity, force);
boolean drop = new Entity2Schema().dropEntity(entity, force);
return drop ? RespBody.ok() : RespBody.error();
} catch (Exception ex) {

View file

@ -39,7 +39,10 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author zhaofang123@gmail.com
@ -134,7 +137,6 @@ public class MetaFieldController extends BaseController {
@PostMapping("field-new")
public RespBody fieldNew(HttpServletRequest request) {
final ID user = getRequestUser(request);
JSONObject reqJson = (JSONObject) ServletUtils.getRequestJson(request);
String entityName = reqJson.getString("entity");
@ -162,7 +164,7 @@ public class MetaFieldController extends BaseController {
}
try {
String fieldName = new Field2Schema(user).createField(entity, label, dt, comments, refEntity, extConfig);
String fieldName = new Field2Schema().createField(entity, label, dt, comments, refEntity, extConfig);
return RespBody.ok(fieldName);
} catch (Exception ex) {
@ -181,16 +183,14 @@ public class MetaFieldController extends BaseController {
}
@RequestMapping("field-drop")
public RespBody fieldDrop(@IdParam ID fieldId, HttpServletRequest request) {
final ID user = getRequestUser(request);
public RespBody fieldDrop(@IdParam ID fieldId) {
Object[] fieldRecord = Application.createQueryNoFilter(
"select belongEntity,fieldName from MetaField where fieldId = ?")
.setParameter(1, fieldId)
.unique();
Field field = MetadataHelper.getEntity((String) fieldRecord[0]).getField((String) fieldRecord[1]);
boolean drop = new Field2Schema(user).dropField(field, false);
boolean drop = new Field2Schema().dropField(field, false);
return drop ? RespBody.ok() : RespBody.error();
}

View file

@ -2,10 +2,10 @@
<ehcache>
<diskStore path="java.io.tmpdir"/>
<cache name="rebuild"
maxElementsInMemory="100"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="true"
maxElementsOnDisk="100000000"
maxElementsOnDisk="1000000"
diskPersistent="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"

View file

@ -2044,5 +2044,16 @@
"排列方式":"排列方式",
"更早":"更早",
"任务排序,或切换任务排列方式":"任务排序,或切换任务排列方式",
"显示方式":"显示方式"
"显示方式":"显示方式",
"请至少添加 1 个字段映射":"请至少添加 1 个字段映射",
"不填写则不复制明细实体":"不填写则不复制明细实体",
"请选择从哪个实体复制":"请选择从哪个实体复制",
"数据库自动备份":"数据库自动备份",
"明细实体名称":"明细实体名称",
"无法读取文件":"无法读取文件",
"部分必填字段未映射,可能导致转换失败。是否继续保存?":"部分必填字段未映射,可能导致转换失败。是否继续保存?",
"无法读取图片":"无法读取图片",
"复制哪个实体":"复制哪个实体",
"免费版不支持此功能 [(查看详情)](https://getrebuild.com/docs/rbv-features)":"免费版不支持此功能 [(查看详情)](https://getrebuild.com/docs/rbv-features)",
"升级":"升级"
}

View file

@ -20,7 +20,7 @@
<script th:src="@{/assets/js/rb-page.js}"></script>
<script th:src="@{/assets/js/rb-components.js}" type="text/babel"></script>
<script th:src="@{/assets/js/file-preview.js}" type="text/babel"></script>
<th:block th:if="${user != null && commercial > 0}">
<th:block th:if="${user != null && commercial > 1}">
<script th:src="@{/assets/js/frontjs/frontjs-sdk.js}" type="text/babel"></script>
<script th:src="@{/commons/frontjs/use-frontjs}" type="text/babel"></script>
</th:block>

View file

@ -15,7 +15,7 @@
<link rel="stylesheet" type="text/css" th:href="@{/assets/lib/widget/simplemde.min.css}" />
<link rel="stylesheet" type="text/css" th:href="@{/assets/css/rb-base.css}" />
<link rel="stylesheet" type="text/css" th:href="@{/assets/css/rb-page.css}" />
<link rel="stylesheet" type="text/css" th:href="@{/commons/theme/use-theme}" th:if="${user != null && commercial > 0}" />
<link rel="stylesheet" type="text/css" th:href="@{/commons/theme/use-theme}" th:if="${user != null && commercial > 1}" />
<meta name="rb.env" th:content="${env}" />
<meta name="rb.commercial" th:content="${commercial}" />
<meta name="rb.locale" th:content="${locale}" />
@ -33,7 +33,7 @@
<!--[if lt IE 10]><script>location.href = '[[${baseUrl}]]/error/unsupported-browser'</script><![endif]-->
<script th:if="${T(com.rebuild.utils.AppUtils).isIE11(#request)}" th:src="@{/assets/lib/react/polyfill.min.js?v=7.6.0}"></script>
<script th:if="${markWatermark == 'true'}" th:src="@{/assets/lib/watermark.js?v=2.3.2.2}"></script>
<style th:if="${commercial > 0}" type="text/css">
<style th:if="${commercial > 1}" type="text/css">
.logo-img,
.rb-top-header .rb-navbar-header .navbar-brand {
background-image: url('[[${baseUrl}]]/commons/theme/use-logo');

View file

@ -11,9 +11,8 @@
margin: 0 -10px;
}
.dialog-footer {
margin: 15px -15px 0;
margin: 15px -40px 0;
padding-top: 20px;
text-align: center;
}
</style>
</head>
@ -23,9 +22,10 @@
<ul class="nav nav-tabs">
<li class="nav-item"><a class="nav-link active" href="#MANUAL" data-toggle="tab">[[${bundle.L('手动')}]]</a></li>
<li class="nav-item">
<a class="nav-link J_imports" href="#IMPORTS" data-toggle="tab">
<i class="icon zmdi zmdi-cloud-outline-alt"></i> [[${bundle.L('从 RB 仓库导入')}]]
</a>
<a class="nav-link" href="#COPY" data-toggle="tab">[[${bundle.L('复制')}]] <sup class="rbv" th:title="${bundle.L('增值功能')}"></sup></a>
</li>
<li class="nav-item">
<a class="nav-link J_imports" href="#IMPORTS" data-toggle="tab"> <i class="icon zmdi zmdi-cloud-outline-alt"></i> [[${bundle.L('从 RB 仓库导入')}]] </a>
</li>
</ul>
<div class="tab-content m-0 pb-0">
@ -59,11 +59,7 @@
<input class="custom-control-input" type="checkbox" id="isDetail" />
<span class="custom-control-label">
[[${bundle.L('这是一个明细实体')}]]
<i
class="zmdi zmdi-help zicon"
data-toggle="tooltip"
th:title="${bundle.L('通过明细实体可以更好的组织业务关系。例如订单明细通常依附于订单,而非独立存在')}"
></i>
<i class="zmdi zmdi-help zicon" data-toggle="tooltip" th:title="${bundle.L('通过明细实体可以更好的组织业务关系。例如订单明细通常依附于订单,而非独立存在')}"></i>
</span>
</label>
</div>
@ -76,7 +72,36 @@
</div>
<div class="form-group row footer">
<div class="col-sm-7 offset-sm-3">
<button class="btn btn-primary" type="button">[[${bundle.L('确定')}]]</button>
<button class="btn btn-primary new" type="button">[[${bundle.L('确定')}]]</button>
<button class="btn btn-link" type="button" onclick="parent.RbModal.hide()">[[${bundle.L('取消')}]]</button>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="COPY">
<div class="form">
<div class="form-group row">
<label class="col-sm-3 col-form-label text-sm-right">[[${bundle.L('复制哪个实体')}]]</label>
<div class="col-sm-7">
<select class="form-control form-control-sm" id="copySourceEntity"></select>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label text-sm-right">[[${bundle.L('实体名称')}]]</label>
<div class="col-sm-7">
<input class="form-control form-control-sm" type="text" id="newEntityLabel" maxlength="40" />
</div>
</div>
<div class="form-group row hide J_newDetailLabel">
<label class="col-sm-3 col-form-label text-sm-right">[[${bundle.L('明细实体名称')}]]</label>
<div class="col-sm-7">
<input class="form-control form-control-sm" type="text" id="newDetailLabel" maxlength="40" />
<p class="form-text">[[${bundle.L('不填写则不复制明细实体')}]]</p>
</div>
</div>
<div class="form-group row footer">
<div class="col-sm-7 offset-sm-3">
<button class="btn btn-primary copy" type="button">[[${bundle.L('确定')}]]</button>
<button class="btn btn-link" type="button" onclick="parent.RbModal.hide()">[[${bundle.L('取消')}]]</button>
</div>
</div>

View file

@ -76,7 +76,7 @@
<div class="clearfix"></div>
</div>
<div class="tab-pane" id="adv-control">
<table th:if="${commercial > 0}" class="table table-hover table-p">
<table th:if="${commercial > 1}" class="table table-hover table-p">
<thead>
<tr>
<th>[[${bundle.L('字段')}]]</th>

View file

@ -55,6 +55,8 @@ $(document).ready(() => {
const fm = fieldsMapping.buildMapping()
const fmd = fieldsMappingDetail ? fieldsMappingDetail.buildMapping() : null
if (Object.keys(fm).length === 0) return RbHighbar.create($L('请至少添加 1 个字段映射'))
function _save() {
const config = {
fieldsMapping: fm,

View file

@ -8,7 +8,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
// ~~ 图片/文档预览
const TYPE_DOCS = ['.doc', '.docx', '.rtf', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf']
const TYPE_TEXTS = ['.txt', '.xml', '.json', '.md', '.yml', '.css', '.js', '.htm', '.html', '.log', '.sql']
const TYPE_TEXTS = ['.txt', '.xml', '.json', '.md', '.yml', '.css', '.js', '.htm', '.html', '.log', '.sql', '.conf']
const TYPE_IMGS = ['.jpg', '.jpeg', '.gif', '.png', '.bmp']
const TYPE_AUDIOS = ['.mp3', '.wav', '.ogg', '.acc']
const TYPE_VIDEOS = ['.mp4', '.webm']
@ -94,7 +94,7 @@ class RbPreview extends React.Component {
alt="Loading"
onLoad={() => this.setState({ imgRendered: true })}
onError={() => {
RbHighbar.error($L('无法加载图片'))
RbHighbar.error($L('无法读取图片'))
this.hide()
}}
/>
@ -203,7 +203,8 @@ class RbPreview extends React.Component {
success: function (res) {
that.setState({ previewText: res })
},
error: function () {
error: function (res) {
if (res.status > 0) RbHighbar.error(`${$L('无法读取文件')} (${res.status})`)
that.hide()
},
})

View file

@ -7,56 +7,109 @@ See LICENSE and COMMERCIAL in the project root for license information.
/* global InitModels */
$(document).ready(function () {
const $btn = $('.btn-primary').click(function () {
const $new = $('.btn-primary.new').on('click', function () {
const entityLabel = $val('#entityLabel'),
comments = $val('#comments')
if (!entityLabel) {
RbHighbar.create($L('请输入实体名称'))
return
}
if (!entityLabel) return RbHighbar.create($L('请输入实体名称'))
const data = {
label: entityLabel,
comments: comments,
}
if ($val('#isDetail')) {
data.mainEntity = $val('#mainEntity')
if (!data.mainEntity) {
RbHighbar.create($L('请选择主实体'))
return
}
if (!data.mainEntity) return RbHighbar.create($L('请选择主实体'))
}
$btn.button('loading')
$.post(`/admin/entity/entity-new?nameField=${$val('#nameField')}`, JSON.stringify(data), function (res) {
$new.button('loading')
$.post(`/admin/entity/entity-new?nameField=${$val('#nameField')}`, JSON.stringify(data), (res) => {
if (res.error_code === 0) parent.location.href = `${rb.baseUrl}/admin/entity/${res.data}/base`
else RbHighbar.error(res.error_msg)
})
})
let entityLoaded = false
$('#isDetail').click(function () {
const $copy = $('.btn-primary.copy').on('click', () => {
if (rb.commercial < 1) return
const sourceEntity = $val('#copySourceEntity')
if (!sourceEntity) RbHighbar.create($L('请选择从哪个实体复制'))
const entityLabel = $val('#newEntityLabel')
if (!entityLabel) return RbHighbar.create($L('请输入实体名称'))
const data = {
sourceEntity: sourceEntity,
entityName: entityLabel,
detailEntityName: $val('#newDetailLabel'),
keepConfig: [],
}
$copy.button('loading')
$.post('/admin/entity/entity-copy', JSON.stringify(data), (res) => {
if (res.error_code === 0) parent.location.href = `${rb.baseUrl}/admin/entity/${res.data}/base`
else RbHighbar.error(res.error_msg)
})
})
let entities
function _loadEntities(call) {
if (entities) {
typeof call === 'function' && call(entities)
} else {
$.get('/admin/entity/entity-list', (res) => {
entities = res.data
typeof call === 'function' && call(entities)
})
}
}
_loadEntities((e) => {
e.forEach(function (item) {
$(`<option value="${item.entityName}" data-detail="${item.detailEntity || ''}">${item.entityLabel}</option>`).appendTo('#copySourceEntity')
})
$('#copySourceEntity')
.on('change', function () {
const $s = $('#copySourceEntity option:selected')
if ($s.data('detail')) $('.J_newDetailLabel').removeClass('hide')
else $('.J_newDetailLabel').addClass('hide')
parent.RbModal.resize()
})
.trigger('change')
})
$('#isDetail').on('click', function () {
$('.J_mainEntity').toggleClass('hide')
parent.RbModal.resize()
if (entityLoaded === false) {
entityLoaded = true
$.get('/admin/entity/entity-list', function (res) {
$(res.data).each(function () {
if (!this.detailEntity) $(`<option value="${this.entityName}">${this.entityLabel}</option>`).appendTo('#mainEntity')
if ($('#mainEntity option').length === 0) {
_loadEntities((e) => {
e.forEach(function (item) {
if (!item.detailEntity) $(`<option value="${item.entityName}">${item.entityLabel}</option>`).appendTo('#mainEntity')
})
})
}
})
$('.nav-tabs a').click(() => parent.RbModal.resize())
let _MetaschemaList
$('.J_imports').click(() => {
$('.J_imports').on('click', () => {
if (_MetaschemaList) return
renderRbcomp(<MetaschemaList />, 'metaschemas', function () {
_MetaschemaList = this
})
})
$('.nav-tabs a').on('click', function (e) {
if (rb.commercial < 1 && $(this).find('.rbv').length > 0) {
RbHighbar.error(WrapHtml($L('免费版不支持此功能 [(查看详情)](https://getrebuild.com/docs/rbv-features)')))
$stopEvent(e, true)
return false
}
parent.RbModal.resize()
})
})
class MetaschemaList extends React.Component {
@ -65,10 +118,15 @@ class MetaschemaList extends React.Component {
<div>
<InitModels ref={(c) => (this._InitModels = c)} onLoad={() => parent.RbModal.resize()} />
<div className="dialog-footer">
<button className="btn btn-primary" onClick={() => this.imports()} ref={(c) => (this._$btn = c)}>
{$L('开始导入')}
</button>
<p className="protips mt-2">{$L('可在导入后根据自身需求做适当调整/修改')}</p>
<div className="float-right">
<button className="btn btn-primary" onClick={() => this.imports()} ref={(c) => (this._$btn = c)}>
{$L('开始导入')}
</button>
</div>
<div className="float-right">
<p className="protips mt-2 pr-2">{$L('可在导入后根据自身需求做适当调整/修改')}</p>
</div>
<div className="clearfix" />
</div>
</div>
)

View file

@ -1,20 +0,0 @@
/*
Copyright (c) REBUILD <https://getrebuild.com/> and/or its owners. All rights reserved.
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
See LICENSE and COMMERCIAL in the project root for license information.
*/
package com.rebuild.core.metadata.easymeta;
import com.rebuild.TestSupport;
/**
* @author devezhao
* @since 2020/11/18
*/
class EasyEntityTest extends TestSupport {
}

View file

@ -1,19 +0,0 @@
/*
Copyright (c) REBUILD <https://getrebuild.com/> and/or its owners. All rights reserved.
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
See LICENSE and COMMERCIAL in the project root for license information.
*/
package com.rebuild.core.metadata.easymeta;
import com.rebuild.TestSupport;
/**
* @author devezhao
* @since 2020/11/18
*/
class EasyFieldTest extends TestSupport {
}

View file

@ -5,13 +5,11 @@ rebuild is dual-licensed under commercial and open source licenses (GPLv3).
See LICENSE and COMMERCIAL in the project root for license information.
*/
package com.rebuild.core.metadata.entity;
package com.rebuild.core.metadata.easymeta;
import cn.devezhao.persist4j.Entity;
import com.rebuild.TestSupport;
import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
import com.rebuild.core.metadata.easymeta.EasyPhone;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@ -19,7 +17,7 @@ import org.junit.jupiter.api.Test;
* @author devezhao-mbp zhaofang123@gmail.com
* @since 2019/05/30
*/
public class EasyMetaTest extends TestSupport {
class EasyMetaTest extends TestSupport {
@Test
void getLabel() {

View file

@ -0,0 +1,30 @@
/*
Copyright (c) REBUILD <https://getrebuild.com/> and/or its owners. All rights reserved.
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
See LICENSE and COMMERCIAL in the project root for license information.
*/
package com.rebuild.core.metadata.impl;
import com.rebuild.TestSupport;
import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.privileges.UserService;
import org.junit.jupiter.api.Test;
/**
* @author zhaofang123@gmail.com
* @since 12/17/2021
*/
class CopyEntityTest extends TestSupport {
@Test
void copy() {
String sourceName = TestAllFields;
String newName =
((CopyEntity) new CopyEntity(MetadataHelper.getEntity(sourceName)).setUser(UserService.ADMIN_USER))
.copy(sourceName + "Copy", null);
System.out.println("New entity : " + newName);
}
}

View file

@ -5,15 +5,13 @@ rebuild is dual-licensed under commercial and open source licenses (GPLv3).
See LICENSE and COMMERCIAL in the project root for license information.
*/
package com.rebuild.core.metadata.entity;
package com.rebuild.core.metadata.impl;
import cn.devezhao.persist4j.Entity;
import com.rebuild.TestSupport;
import com.rebuild.core.UserContextHolder;
import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.metadata.easymeta.DisplayType;
import com.rebuild.core.metadata.impl.Entity2Schema;
import com.rebuild.core.metadata.impl.Field2Schema;
import com.rebuild.core.privileges.UserService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -22,7 +20,7 @@ import org.junit.jupiter.api.Test;
* @author zhaofang123@gmail.com
* @since 08/03/2018
*/
public class Meta2SchemaTest extends TestSupport {
class Meta2SchemaTest extends TestSupport {
@BeforeEach
public void setUpPerMethod() {
@ -30,7 +28,7 @@ public class Meta2SchemaTest extends TestSupport {
}
@Test
public void testCreateEntity() {
void testCreateEntity() {
String newEntityName = new Entity2Schema(UserService.ADMIN_USER)
.createEntity("测试实体", null, null, false);
System.out.println("New Entity is created : " + newEntityName);
@ -41,7 +39,7 @@ public class Meta2SchemaTest extends TestSupport {
}
@Test
public void testCreateField() {
void testCreateField() {
String newEntityName = new Entity2Schema(UserService.ADMIN_USER)
.createEntity("测试字段", null, null, false);
Entity newEntity = MetadataHelper.getEntity(newEntityName);