mirror of
https://github.com/getrebuild/rebuild.git
synced 2024-09-20 23:45:55 +08:00
commit
51f59ab36f
2
@rbv
2
@rbv
|
@ -1 +1 @@
|
|||
Subproject commit f6f4a5f87e30c9865e580d117d30e1b8a4c9a41b
|
||||
Subproject commit 29deac78d1ba561dc503aefb2ab6530a9438b460
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
92
src/main/java/com/rebuild/core/metadata/impl/CopyEntity.java
Normal file
92
src/main/java/com/rebuild/core/metadata/impl/CopyEntity.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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" },
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -93,9 +93,10 @@ public enum ConfigurationItem {
|
|||
SamlIdPEntityid, SamlIdPEndpoint, SamlIdPSloEndpoint, SamlIdPCert,
|
||||
|
||||
// !!! 仅命令行适用
|
||||
DataDirectory, // 数据目录
|
||||
MobileUrl, // 移动端地址
|
||||
RbStoreUrl // 在线仓库地址
|
||||
DataDirectory, // 数据目录
|
||||
RedisDatabase(0), // Redis DB
|
||||
MobileUrl, // 移动端地址
|
||||
RbStoreUrl // 在线仓库地址
|
||||
|
||||
;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -2044,5 +2044,16 @@
|
|||
"排列方式":"排列方式",
|
||||
"更早":"更早",
|
||||
"任务排序,或切换任务排列方式":"任务排序,或切换任务排列方式",
|
||||
"显示方式":"显示方式"
|
||||
"显示方式":"显示方式",
|
||||
"请至少添加 1 个字段映射":"请至少添加 1 个字段映射",
|
||||
"不填写则不复制明细实体":"不填写则不复制明细实体",
|
||||
"请选择从哪个实体复制":"请选择从哪个实体复制",
|
||||
"数据库自动备份":"数据库自动备份",
|
||||
"明细实体名称":"明细实体名称",
|
||||
"无法读取文件":"无法读取文件",
|
||||
"部分必填字段未映射,可能导致转换失败。是否继续保存?":"部分必填字段未映射,可能导致转换失败。是否继续保存?",
|
||||
"无法读取图片":"无法读取图片",
|
||||
"复制哪个实体":"复制哪个实体",
|
||||
"免费版不支持此功能 [(查看详情)](https://getrebuild.com/docs/rbv-features)":"免费版不支持此功能 [(查看详情)](https://getrebuild.com/docs/rbv-features)",
|
||||
"升级":"升级"
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
},
|
||||
})
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
||||
|
||||
}
|
|
@ -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() {
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
Loading…
Reference in a new issue