diff --git a/backend/src/main/java/io/dataease/auth/config/F2CRealm.java b/backend/src/main/java/io/dataease/auth/config/F2CRealm.java index c91dbe1ff3..29c269f10f 100644 --- a/backend/src/main/java/io/dataease/auth/config/F2CRealm.java +++ b/backend/src/main/java/io/dataease/auth/config/F2CRealm.java @@ -8,6 +8,8 @@ import io.dataease.auth.entity.TokenInfo; import io.dataease.auth.service.AuthUserService; import io.dataease.auth.util.JWTUtils; import io.dataease.commons.utils.BeanUtils; +import io.dataease.commons.utils.LogUtil; +import io.dataease.listener.util.CacheUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; @@ -54,6 +56,11 @@ public class F2CRealm extends AuthorizingRealm { @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException { + try { + CacheUtils.get("lic_info", "lic"); + }catch (Exception e) { + LogUtil.error(e); + } String token = (String) auth.getCredentials(); // 解密获得username,用于和数据库进行对比 TokenInfo tokenInfo = JWTUtils.tokenInfoByToken(token); diff --git a/backend/src/main/java/io/dataease/auth/util/JWTUtils.java b/backend/src/main/java/io/dataease/auth/util/JWTUtils.java index 8b3b7e4c92..1fa0a37f8f 100644 --- a/backend/src/main/java/io/dataease/auth/util/JWTUtils.java +++ b/backend/src/main/java/io/dataease/auth/util/JWTUtils.java @@ -6,12 +6,9 @@ import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTDecodeException; import com.auth0.jwt.interfaces.DecodedJWT; import io.dataease.auth.entity.TokenInfo; -import io.dataease.auth.filter.JWTFilter; import io.dataease.commons.utils.CommonBeanFactory; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.authc.AuthenticationException; - import org.springframework.core.env.Environment; import java.util.Date; diff --git a/backend/src/main/java/io/dataease/base/mapper/ext/ExtDataSetTableMapper.xml b/backend/src/main/java/io/dataease/base/mapper/ext/ExtDataSetTableMapper.xml index 8b51a258e0..1f1d6ad214 100644 --- a/backend/src/main/java/io/dataease/base/mapper/ext/ExtDataSetTableMapper.xml +++ b/backend/src/main/java/io/dataease/base/mapper/ext/ExtDataSetTableMapper.xml @@ -21,6 +21,12 @@ and mode = #{mode,jdbcType=INTEGER} + + and type in + + #{item,jdbcType=INTEGER} + + order by ${sort} diff --git a/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java b/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java index 7f1a4fe577..b40d009e66 100644 --- a/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java +++ b/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java @@ -25,12 +25,12 @@ public class DataSetTableController { private DataSetTableService dataSetTableService; @PostMapping("batchAdd") - public void batchAdd(@RequestBody List datasetTable) throws Exception { + public void batchAdd(@RequestBody List datasetTable) throws Exception { dataSetTableService.batchInsert(datasetTable); } @PostMapping("update") - public DatasetTable save(@RequestBody DatasetTable datasetTable) throws Exception { + public DatasetTable save(@RequestBody DataSetTableRequest datasetTable) throws Exception { return dataSetTableService.save(datasetTable); } diff --git a/backend/src/main/java/io/dataease/controller/request/dataset/DataSetTableRequest.java b/backend/src/main/java/io/dataease/controller/request/dataset/DataSetTableRequest.java index 9eea8a6819..a71b592fc4 100644 --- a/backend/src/main/java/io/dataease/controller/request/dataset/DataSetTableRequest.java +++ b/backend/src/main/java/io/dataease/controller/request/dataset/DataSetTableRequest.java @@ -16,6 +16,8 @@ public class DataSetTableRequest extends DatasetTable { private String sort; private List tableNames; private String row = "1000"; - private String userId; + private Integer editType; + private Boolean isRename; + private List typeFilter; } diff --git a/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java b/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java index 8055b25533..116ddba542 100644 --- a/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java +++ b/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java @@ -35,7 +35,9 @@ public class JdbcProvider extends DatasourceProvider { } catch (Exception e) { throw new Exception("ERROR:" + e.getMessage(), e); } finally { - connection.close(); + if(connection != null){ + connection.close(); + } } return list; } @@ -52,7 +54,9 @@ public class JdbcProvider extends DatasourceProvider { } catch (Exception e) { throw new Exception("ERROR:" + e.getMessage(), e); } finally { - connection.close(); + if(connection != null){ + connection.close(); + } } } @@ -70,7 +74,9 @@ public class JdbcProvider extends DatasourceProvider { } catch (Exception e) { throw new Exception("ERROR:" + e.getMessage(), e); } finally { - connection.close(); + if(connection != null){ + connection.close(); + } } } @@ -110,7 +116,9 @@ public class JdbcProvider extends DatasourceProvider { } catch (Exception e) { throw new Exception("ERROR:" + e.getMessage(), e); } finally { - connection.close(); + if(connection != null){ + connection.close(); + } } } @@ -135,7 +143,9 @@ public class JdbcProvider extends DatasourceProvider { } catch (Exception e) { throw new Exception("ERROR:" + e.getMessage(), e); } finally { - connection.close(); + if(connection != null){ + connection.close(); + } } } @@ -175,7 +185,9 @@ public class JdbcProvider extends DatasourceProvider { } catch (Exception e) { throw new Exception("ERROR: " + e.getMessage(), e); } finally { - con.close(); + if(con != null){ + con.close(); + } } } @@ -214,7 +226,9 @@ public class JdbcProvider extends DatasourceProvider { } catch (Exception e) { throw new Exception("ERROR:" + e.getMessage(), e); } finally { - connection.close(); + if(connection != null){ + connection.close(); + } } return list; } diff --git a/backend/src/main/java/io/dataease/job/sechedule/ScheduleManager.java b/backend/src/main/java/io/dataease/job/sechedule/ScheduleManager.java index 1521cb2346..fa7cdcf96f 100644 --- a/backend/src/main/java/io/dataease/job/sechedule/ScheduleManager.java +++ b/backend/src/main/java/io/dataease/job/sechedule/ScheduleManager.java @@ -73,7 +73,7 @@ public class ScheduleManager { triggerBuilder.withIdentity(triggerKey); - Date nTimeByCron = getNTimeByCron(cron); + Date nTimeByCron = getNTimeByCron(cron, startTime); if (startTime.before(new Date())) { triggerBuilder.startAt(nTimeByCron); } @@ -156,7 +156,7 @@ public class ScheduleManager { triggerBuilder.withIdentity(triggerKey);// 触发器名,触发器组 - Date nTimeByCron = getNTimeByCron(cron); + Date nTimeByCron = getNTimeByCron(cron, startTime); if (startTime.before(new Date())) { triggerBuilder.startAt(nTimeByCron); } @@ -410,22 +410,38 @@ public class ScheduleManager { return returnMap; } - public static Date getNTimeByCron(String cron) { - try { - CronTriggerImpl cronTriggerImpl = new CronTriggerImpl(); - cronTriggerImpl.setCronExpression(cron); - Calendar calendar = Calendar.getInstance(); - Date now = calendar.getTime(); -// calendar.add(java.util.Calendar.YEAR, 1); - calendar.add(Calendar.MONTH, 2); +// public static Date getNTimeByCron(String cron) { +// try { +// CronTriggerImpl cronTriggerImpl = new CronTriggerImpl(); +// cronTriggerImpl.setCronExpression(cron); +// Calendar calendar = Calendar.getInstance(); +// Date now = calendar.getTime(); +//// calendar.add(java.util.Calendar.YEAR, 1); +// calendar.add(Calendar.MONTH, 2); +// +// List dates = TriggerUtils.computeFireTimesBetween(cronTriggerImpl, null, now, calendar.getTime()); +// SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); +// String nextTime = dateFormat.format(dates.get(0)); +// Date date = dateFormat.parse(nextTime); +// return date; +// } catch (Exception e) { +// throw new RuntimeException(e); +// } +// } - List dates = TriggerUtils.computeFireTimesBetween(cronTriggerImpl, null, now, calendar.getTime()); - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - String nextTime = dateFormat.format(dates.get(0)); - Date date = dateFormat.parse(nextTime); - return date; - } catch (Exception e) { - throw new RuntimeException(e); + public static CronTrigger getCronTrigger(String cron) { + if (!CronExpression.isValidExpression(cron)) { + throw new RuntimeException("cron :" + cron + " error"); } + return TriggerBuilder.newTrigger().withIdentity("Calculate Date").withSchedule(CronScheduleBuilder.cronSchedule(cron)).build(); + + } + + public static Date getNTimeByCron(String cron, Date start) { + CronTrigger trigger = getCronTrigger(cron); + if (start == null) { + start = trigger.getStartTime(); + } + return trigger.getFireTimeAfter(start); } } diff --git a/backend/src/main/java/io/dataease/listener/LicCacheEventListener.java b/backend/src/main/java/io/dataease/listener/LicCacheEventListener.java new file mode 100644 index 0000000000..632916a56f --- /dev/null +++ b/backend/src/main/java/io/dataease/listener/LicCacheEventListener.java @@ -0,0 +1,80 @@ +package io.dataease.listener; + +import io.dataease.commons.constants.AuthConstants; +import io.dataease.listener.util.CacheUtils; +import net.sf.ehcache.CacheException; +import net.sf.ehcache.Ehcache; +import net.sf.ehcache.Element; +import net.sf.ehcache.event.CacheEventListener; +import net.sf.ehcache.event.CacheEventListenerFactory; +import org.springframework.stereotype.Component; +import java.util.Properties; + +@Component +public class LicCacheEventListener extends CacheEventListenerFactory implements CacheEventListener { + + private static CacheEventListener cacheEventListener; + + public LicCacheEventListener() { + cacheEventListener = cacheEventListener == null ? this : cacheEventListener; + } + + @Override + public void notifyElementRemoved(Ehcache ehcache, Element element) throws CacheException { + /*System.out.println("notifyElementRemoved");*/ + } + + @Override + public void notifyElementPut(Ehcache ehcache, Element element) throws CacheException { + + /*long expirationTime = element.getExpirationTime(); + System.out.println(expirationTime); + System.out.println("notifyElementPut");*/ + } + + @Override + public void notifyElementUpdated(Ehcache ehcache, Element element) throws CacheException { + /*System.out.println("notifyElementUpdated");*/ + } + + /** + * lic过期触发: 清除用户、角色、权限缓存 + * @param ehcache + * @param element + */ + @Override + public void notifyElementExpired(Ehcache ehcache, Element element) { + // System.out.println("notifyElementExpired"); + /*String token = ServletUtils.getToken(); + Long userId = JWTUtils.tokenInfoByToken(token).getUserId(); + authUserService.clearCache(userId);*/ + CacheUtils.removeAll(AuthConstants.USER_CACHE_NAME); + CacheUtils.removeAll(AuthConstants.USER_ROLE_CACHE_NAME); + CacheUtils.removeAll(AuthConstants.USER_PERMISSION_CACHE_NAME); + } + + @Override + public void notifyElementEvicted(Ehcache ehcache, Element element) { + /*System.out.println("notifyElementEvicted");*/ + } + + @Override + public void notifyRemoveAll(Ehcache ehcache) { + /*System.out.println("notifyRemoveAll");*/ + } + + @Override + public void dispose() { + + } + + @Override + public CacheEventListener createCacheEventListener(Properties properties) { + return cacheEventListener; + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } +} diff --git a/backend/src/main/java/io/dataease/listener/util/CacheUtils.java b/backend/src/main/java/io/dataease/listener/util/CacheUtils.java new file mode 100644 index 0000000000..09e656315a --- /dev/null +++ b/backend/src/main/java/io/dataease/listener/util/CacheUtils.java @@ -0,0 +1,61 @@ +package io.dataease.listener.util; + +import net.sf.ehcache.Cache; +import net.sf.ehcache.Element; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.CacheManager; +import org.springframework.cache.ehcache.EhCacheCacheManager; +import org.springframework.context.annotation.Configuration; +import java.util.Date; + +@Configuration +public class CacheUtils { + + private static CacheManager manager; + + @Autowired + public void setManager(CacheManager manager) { + CacheUtils.manager = manager; + } + + public static Object get(String cacheName, Object key) { + Element element = cache(cacheName).get(key); + if (null == element) return null; + return element.getObjectValue(); + } + + private static void put(String cacheName, Object key, Object value, Integer ttl, Integer tti) { + Element e = new Element(key, value); + //不设置则使用xml配置 + if (ttl != null) + e.setEternal(false); + e.setTimeToLive(ttl); + if (tti != null) + e.setTimeToIdle(tti); + cache(cacheName).put(e); + } + + private static boolean remove(String cacheName, Object key) { + return cache(cacheName).remove(key); + } + + public static void removeAll(String cacheName) { + cache(cacheName).removeAll(); + } + + private static Cache cache(String cacheName) { + net.sf.ehcache.CacheManager cacheManager = ((EhCacheCacheManager) manager).getCacheManager(); + if (!cacheManager.cacheExists(cacheName)) + cacheManager.addCache(cacheName); + Cache cacheManagerCache = cacheManager.getCache(cacheName); + return cacheManagerCache; + } + + public static void updateLicCache(Date expDate){ + long time = expDate.getTime(); + long exp = (time - System.currentTimeMillis()) / 1000; + int intExp = (int)exp; + removeAll("lic_info"); + put("lic_info", "lic", "lic", intExp, intExp); + } +} diff --git a/backend/src/main/java/io/dataease/plugins/server/XAuthServer.java b/backend/src/main/java/io/dataease/plugins/server/XAuthServer.java index 3c7d0665d4..9121d531d1 100644 --- a/backend/src/main/java/io/dataease/plugins/server/XAuthServer.java +++ b/backend/src/main/java/io/dataease/plugins/server/XAuthServer.java @@ -2,18 +2,22 @@ package io.dataease.plugins.server; import io.dataease.auth.api.dto.CurrentUserDto; +import io.dataease.commons.constants.AuthConstants; import io.dataease.commons.utils.AuthUtils; import io.dataease.controller.handler.annotation.I18n; +import io.dataease.listener.util.CacheUtils; import io.dataease.plugins.config.SpringContextUtil; import io.dataease.plugins.xpack.auth.dto.request.XpackBaseTreeRequest; import io.dataease.plugins.xpack.auth.dto.request.XpackSysAuthRequest; import io.dataease.plugins.xpack.auth.dto.response.XpackSysAuthDetail; import io.dataease.plugins.xpack.auth.dto.response.XpackSysAuthDetailDTO; import io.dataease.plugins.xpack.auth.dto.response.XpackVAuthModelDTO; +import org.apache.commons.lang3.StringUtils; import org.springframework.web.bind.annotation.*; import io.dataease.plugins.xpack.auth.service.AuthXpackService; import java.util.List; import java.util.Map; +import java.util.Optional; @RequestMapping("/plugin/auth") @RestController @@ -45,5 +49,13 @@ public class XAuthServer { AuthXpackService sysAuthService = SpringContextUtil.getBean(AuthXpackService.class); CurrentUserDto user = AuthUtils.getUser(); sysAuthService.authChange(request, user.getUserId(), user.getUsername(), user.getIsAdmin()); + // 当权限发生变化 前端实时刷新对应菜单 + Optional.ofNullable(request.getAuthSourceType()).ifPresent(type -> { + if (StringUtils.equals("menu", type)) { + CacheUtils.removeAll(AuthConstants.USER_CACHE_NAME); + CacheUtils.removeAll(AuthConstants.USER_ROLE_CACHE_NAME); + CacheUtils.removeAll(AuthConstants.USER_PERMISSION_CACHE_NAME); + } + }); } } diff --git a/backend/src/main/java/io/dataease/provider/doris/DorisQueryProvider.java b/backend/src/main/java/io/dataease/provider/doris/DorisQueryProvider.java index 48755a72ca..b4385f66e9 100644 --- a/backend/src/main/java/io/dataease/provider/doris/DorisQueryProvider.java +++ b/backend/src/main/java/io/dataease/provider/doris/DorisQueryProvider.java @@ -295,7 +295,8 @@ public class DorisQueryProvider extends QueryProvider { filter.append(" ") .append(transMysqlFilterTerm(request.getTerm())) .append(" "); - if (StringUtils.containsIgnoreCase(request.getTerm(), "in")) { + if (StringUtils.containsIgnoreCase(request.getTerm(), "null")) { + } else if (StringUtils.containsIgnoreCase(request.getTerm(), "in")) { filter.append("('").append(StringUtils.join(value, "','")).append("')"); } else if (StringUtils.containsIgnoreCase(request.getTerm(), "like")) { filter.append("'%").append(value).append("%'"); diff --git a/backend/src/main/java/io/dataease/provider/mysql/MysqlQueryProvider.java b/backend/src/main/java/io/dataease/provider/mysql/MysqlQueryProvider.java index 095a8ecb5b..846e4c7468 100644 --- a/backend/src/main/java/io/dataease/provider/mysql/MysqlQueryProvider.java +++ b/backend/src/main/java/io/dataease/provider/mysql/MysqlQueryProvider.java @@ -302,7 +302,8 @@ public class MysqlQueryProvider extends QueryProvider { filter.append(" ") .append(transMysqlFilterTerm(request.getTerm())) .append(" "); - if (StringUtils.containsIgnoreCase(request.getTerm(), "in")) { + if (StringUtils.containsIgnoreCase(request.getTerm(), "null")) { + } else if (StringUtils.containsIgnoreCase(request.getTerm(), "in")) { filter.append("('").append(StringUtils.join(value, "','")).append("')"); } else if (StringUtils.containsIgnoreCase(request.getTerm(), "like")) { filter.append("'%").append(value).append("%'"); diff --git a/backend/src/main/java/io/dataease/service/AboutService.java b/backend/src/main/java/io/dataease/service/AboutService.java index e144a975e9..9568c4f6b9 100644 --- a/backend/src/main/java/io/dataease/service/AboutService.java +++ b/backend/src/main/java/io/dataease/service/AboutService.java @@ -1,16 +1,18 @@ package io.dataease.service; +import io.dataease.commons.constants.AuthConstants; import io.dataease.commons.license.DefaultLicenseService; import io.dataease.commons.license.F2CLicenseResponse; import io.dataease.commons.utils.CommonBeanFactory; import io.dataease.commons.utils.LogUtil; +import io.dataease.listener.util.CacheUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; - import javax.annotation.Resource; import java.io.File; +import java.util.Date; import java.util.Optional; @Service @@ -23,6 +25,15 @@ public class AboutService { public F2CLicenseResponse updateLicense(String licenseKey) { F2CLicenseResponse f2CLicenseResponse = defaultLicenseService.updateLicense(product, licenseKey); + Optional.ofNullable(f2CLicenseResponse).ifPresent(resp -> { + if (resp.getStatus() == F2CLicenseResponse.Status.valid){ + CacheUtils.updateLicCache(new Date(f2CLicenseResponse.getLicense().getExpired())); + + CacheUtils.removeAll(AuthConstants.USER_CACHE_NAME); + CacheUtils.removeAll(AuthConstants.USER_ROLE_CACHE_NAME); + CacheUtils.removeAll(AuthConstants.USER_PERMISSION_CACHE_NAME); + } + }); return f2CLicenseResponse; } diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java index 9c88a595c2..2659965af7 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java @@ -84,13 +84,13 @@ public class DataSetTableService { @Value("${upload.file.path}") private String path; - public void batchInsert(List datasetTable) throws Exception { - for (DatasetTable table : datasetTable) { + public void batchInsert(List datasetTable) throws Exception { + for (DataSetTableRequest table : datasetTable) { save(table); } } - public DatasetTable save(DatasetTable datasetTable) throws Exception { + public DatasetTable save(DataSetTableRequest datasetTable) throws Exception { checkName(datasetTable); if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "sql")) { DataSetTableRequest dataSetTableRequest = new DataSetTableRequest(); @@ -114,12 +114,25 @@ public class DataSetTableService { } } else { int update = datasetTableMapper.updateByPrimaryKeySelective(datasetTable); - // sql 更新 - if (update == 1) { - if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "sql") || StringUtils.equalsIgnoreCase(datasetTable.getType(), "custom")) { - // 删除所有字段,重新抽象 - dataSetTableFieldsService.deleteByTableId(datasetTable.getId()); - saveTableField(datasetTable); + if (datasetTable.getIsRename() == null || !datasetTable.getIsRename()) { + // 更新数据和字段 + if (update == 1) { + if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "sql") || StringUtils.equalsIgnoreCase(datasetTable.getType(), "custom")) { + // 删除所有字段,重新抽象 + dataSetTableFieldsService.deleteByTableId(datasetTable.getId()); + saveTableField(datasetTable); + } + if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "excel")) { + if (datasetTable.getEditType() == 0) { + commonThreadPool.addTask(() -> { + extractDataService.extractData(datasetTable.getId(), null, "all_scope", null); + }); + } else if (datasetTable.getEditType() == 1) { + commonThreadPool.addTask(() -> { + extractDataService.extractData(datasetTable.getId(), null, "add_scope", null); + }); + } + } } } } @@ -135,9 +148,12 @@ public class DataSetTableService { // 删除关联关系 dataSetTableUnionService.deleteUnionByTableId(id); try { - deleteDorisTable(id, table); + // 抽取的数据集删除doris + if (table.getMode() == 1) { + deleteDorisTable(id, table); + } } catch (Exception e) { - + e.printStackTrace(); } } @@ -163,6 +179,7 @@ public class DataSetTableService { public List list(DataSetTableRequest dataSetTableRequest) { dataSetTableRequest.setUserId(String.valueOf(AuthUtils.getUser().getUserId())); + dataSetTableRequest.setTypeFilter(dataSetTableRequest.getTypeFilter()); return extDataSetTableMapper.search(dataSetTableRequest); } @@ -706,10 +723,17 @@ public class DataSetTableService { } else { rows = sheet0.getPhysicalNumberOfRows(); } + int columnNum = 0; for (int i = 0; i < rows; i++) { HSSFRow row = sheet0.getRow(i); - String[] r = new String[row.getPhysicalNumberOfCells()]; - for (int j = 0; j < row.getPhysicalNumberOfCells(); j++) { + if (i == 0) { + if (row == null) { + throw new RuntimeException(Translator.get("i18n_excel_header_empty")); + } + columnNum = row.getPhysicalNumberOfCells(); + } + String[] r = new String[columnNum]; + for (int j = 0; j < columnNum; j++) { if (i == 0) { TableFiled tableFiled = new TableFiled(); tableFiled.setFieldType("TEXT"); @@ -722,8 +746,14 @@ public class DataSetTableService { tableFiled.setRemarks(columnName); fields.add(tableFiled); } else if (i == 1) { + if (row == null) { + break; + } r[j] = readCell(row.getCell(j), true, fields.get(j)); } else { + if (row == null) { + break; + } r[j] = readCell(row.getCell(j), false, null); } } @@ -746,10 +776,17 @@ public class DataSetTableService { } else { rows = sheet0.getPhysicalNumberOfRows(); } + int columnNum = 0; for (int i = 0; i < rows; i++) { XSSFRow row = sheet0.getRow(i); - String[] r = new String[row.getPhysicalNumberOfCells()]; - for (int j = 0; j < row.getPhysicalNumberOfCells(); j++) { + if (i == 0) { + if (row == null) { + throw new RuntimeException(Translator.get("i18n_excel_header_empty")); + } + columnNum = row.getPhysicalNumberOfCells(); + } + String[] r = new String[columnNum]; + for (int j = 0; j < columnNum; j++) { if (i == 0) { TableFiled tableFiled = new TableFiled(); tableFiled.setFieldType("TEXT"); @@ -762,8 +799,14 @@ public class DataSetTableService { tableFiled.setRemarks(columnName); fields.add(tableFiled); } else if (i == 1) { + if (row == null) { + break; + } r[j] = readCell(row.getCell(j), true, fields.get(j)); } else { + if (row == null) { + break; + } r[j] = readCell(row.getCell(j), false, null); } } @@ -815,6 +858,9 @@ public class DataSetTableService { } private String readCell(Cell cell, boolean cellType, TableFiled tableFiled) { + if (cell == null) { + return ""; + } CellType cellTypeEnum = cell.getCellTypeEnum(); if (cellTypeEnum.equals(CellType.STRING)) { if (cellType) { @@ -915,7 +961,7 @@ public class DataSetTableService { } DatasetTable record = new DatasetTable(); - record.setSyncStatus(JobStatus.Completed.name()); + record.setSyncStatus(JobStatus.Error.name()); example.clear(); example.createCriteria().andSyncStatusEqualTo(JobStatus.Underway.name()).andIdIn(jobStoppeddDatasetTables.stream().map(DatasetTable::getId).collect(Collectors.toList())); datasetTableMapper.updateByExampleSelective(record, example); diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskLogService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskLogService.java index b4ee6d2929..4dd2198247 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskLogService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskLogService.java @@ -69,6 +69,7 @@ public class DataSetTableTaskLogService { if(StringUtils.isNotEmpty(datasetTableTaskLog.getTaskId())){ criteria.andTaskIdEqualTo(datasetTableTaskLog.getTaskId()); } + example.setOrderByClause("create_time desc"); return datasetTableTaskLogMapper.selectByExampleWithBLOBs(example); } } diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java index 88659a2354..e696aaaeb4 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableTaskService.java @@ -7,6 +7,7 @@ import io.dataease.commons.constants.ScheduleType; import io.dataease.controller.request.dataset.DataSetTaskRequest; import io.dataease.i18n.Translator; import io.dataease.service.ScheduleService; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.quartz.CronExpression; @@ -61,7 +62,16 @@ public class DataSetTableTaskService { datasetTableTask.setCreateTime(System.currentTimeMillis()); // SIMPLE 类型,提前占位 if (datasetTableTask.getRate().equalsIgnoreCase(ScheduleType.SIMPLE.toString())) { - if (extractDataService.updateSyncStatus(dataSetTableService.get(datasetTableTask.getTableId()))) { + if(datasetTableTask.getType().equalsIgnoreCase("add_scope")){ + DatasetTableTaskLog request = new DatasetTableTaskLog(); + request.setTableId(datasetTableTask.getTableId()); + request.setStatus(JobStatus.Completed.name()); + List datasetTableTaskLogs = dataSetTableTaskLogService.select(request); + if (CollectionUtils.isEmpty(datasetTableTaskLogs)) { + throw new Exception(Translator.get("i18n_not_exec_add_sync")); + } + } + if (extractDataService.updateSyncStatusIsNone(dataSetTableService.get(datasetTableTask.getTableId()))) { throw new Exception(Translator.get("i18n_sync_job_exists")); }else { //write log diff --git a/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java b/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java index 1dd7b19c67..df1866bcbd 100644 --- a/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java +++ b/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java @@ -27,6 +27,9 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFSheet; @@ -34,6 +37,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.pentaho.di.cluster.SlaveServer; import org.pentaho.di.core.database.DatabaseMeta; import org.pentaho.di.core.row.ValueMetaInterface; +import org.pentaho.di.core.util.HttpClientManager; import org.pentaho.di.job.Job; import org.pentaho.di.job.JobExecutionConfiguration; import org.pentaho.di.job.JobHopMeta; @@ -66,6 +70,7 @@ import javax.annotation.Resource; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; +import java.net.InetAddress; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -124,6 +129,181 @@ public class ExtractDataService { " exit 1\n" + "fi\n" + "rm -rf %s\n"; + + public synchronized boolean updateSyncStatusIsNone(DatasetTable datasetTable ){ + datasetTable.setSyncStatus(JobStatus.Underway.name()); + DatasetTableExample example = new DatasetTableExample(); + example.createCriteria().andIdEqualTo(datasetTable.getId()); + datasetTableMapper.selectByExample(example); + example.clear(); + example.createCriteria().andIdEqualTo(datasetTable.getId()).andSyncStatusNotEqualTo(JobStatus.Underway.name()); + example.or(example.createCriteria().andIdEqualTo(datasetTable.getId()).andSyncStatusIsNull()); + return datasetTableMapper.updateByExampleSelective(datasetTable, example) == 0; + } + + public void extractData(String datasetTableId, String taskId, String type, JobExecutionContext context) { + DatasetTable datasetTable = getDatasetTable(datasetTableId); + if(datasetTable == null){ + LogUtil.error("Can not find DatasetTable: " + datasetTableId); + } + DatasetTableTask datasetTableTask = datasetTableTaskMapper.selectByPrimaryKey(taskId); + boolean isCronJob = (datasetTableTask != null && datasetTableTask.getRate().equalsIgnoreCase(ScheduleType.CRON.toString())); + if(updateSyncStatusIsNone(datasetTable) && isCronJob){ + LogUtil.info("Skip synchronization task for table : " + datasetTableId); + return; + } + DatasetTableTaskLog datasetTableTaskLog = new DatasetTableTaskLog(); + UpdateType updateType = UpdateType.valueOf(type); + Datasource datasource = new Datasource(); + if(context != null){ + datasetTable.setQrtzInstance(context.getFireInstanceId()); + datasetTableMapper.updateByPrimaryKeySelective(datasetTable); + } + if (StringUtils.isNotEmpty(datasetTable.getDataSourceId())) { + datasource = datasourceMapper.selectByPrimaryKey(datasetTable.getDataSourceId()); + } else { + datasource.setType(datasetTable.getType()); + } + + List datasetTableFields = dataSetTableFieldsService.list(DatasetTableField.builder().tableId(datasetTable.getId()).build()); + datasetTableFields.sort((o1, o2) -> { + if (o1.getColumnIndex() == null) { + return -1; + } + if (o2.getColumnIndex() == null) { + return 1; + } + return o1.getColumnIndex().compareTo(o2.getColumnIndex()); + }); + String dorisTablColumnSql = createDorisTablColumnSql(datasetTableFields); + + switch (updateType) { + case all_scope: // 全量更新 + try{ + if(datasource.getType().equalsIgnoreCase("excel")){ + datasetTableTaskLog = writeDatasetTableTaskLog(datasetTableTaskLog, datasetTableId, null); + } + if(datasetTableTask != null && datasetTableTask.getRate().equalsIgnoreCase(ScheduleType.CRON.toString())) { + datasetTableTaskLog = writeDatasetTableTaskLog(datasetTableTaskLog, datasetTableId, taskId); + } + if(datasetTableTask != null && datasetTableTask.getRate().equalsIgnoreCase(ScheduleType.SIMPLE.toString())) { + datasetTableTaskLog = getDatasetTableTaskLog(datasetTableTaskLog, datasetTableId, taskId); + } + createDorisTable(DorisTableUtils.dorisName(datasetTableId), dorisTablColumnSql); + createDorisTable(DorisTableUtils.dorisTmpName(DorisTableUtils.dorisName(datasetTableId)), dorisTablColumnSql); + generateTransFile("all_scope", datasetTable, datasource, datasetTableFields, null); + generateJobFile("all_scope", datasetTable, String.join(",", datasetTableFields.stream().map(DatasetTableField::getDataeaseName).collect(Collectors.toList()))); + extractData(datasetTable, "all_scope"); + replaceTable(DorisTableUtils.dorisName(datasetTableId)); + saveSucessLog(datasetTableTaskLog); + updateTableStatus(datasetTableId, datasetTable, JobStatus.Completed); + }catch (Exception e){ + saveErrorLog(datasetTableId, taskId, e); + updateTableStatus(datasetTableId, datasetTable, JobStatus.Error); + dropDorisTable(DorisTableUtils.dorisTmpName(DorisTableUtils.dorisName(datasetTableId))); + }finally { + if (datasetTableTask != null && datasetTableTask.getRate().equalsIgnoreCase(ScheduleType.SIMPLE.toString())) { + datasetTableTask.setRate(ScheduleType.SIMPLE_COMPLETE.toString()); + dataSetTableTaskService.update(datasetTableTask); + } + deleteFile("all_scope", datasetTableId); + } + break; + + case add_scope: // 增量更新 + try { + if(datasource.getType().equalsIgnoreCase("excel")){ + datasetTableTaskLog = writeDatasetTableTaskLog(datasetTableTaskLog, datasetTableId, null); + generateTransFile("incremental_add", datasetTable, datasource, datasetTableFields, null); + generateJobFile("incremental_add", datasetTable, String.join(",", datasetTableFields.stream().map(DatasetTableField::getDataeaseName).collect(Collectors.toList()))); + extractData(datasetTable, "incremental_add"); + saveSucessLog(datasetTableTaskLog); + updateTableStatus(datasetTableId, datasetTable, JobStatus.Completed); + }else { + DatasetTableIncrementalConfig datasetTableIncrementalConfig = dataSetTableService.incrementalConfig(datasetTableId); + if (datasetTableIncrementalConfig == null || StringUtils.isEmpty(datasetTableIncrementalConfig.getTableId())) { + return; + } + DatasetTableTaskLog request = new DatasetTableTaskLog(); + request.setTableId(datasetTableId); + request.setStatus(JobStatus.Completed.name()); + List datasetTableTaskLogs = dataSetTableTaskLogService.select(request); + if (CollectionUtils.isEmpty(datasetTableTaskLogs)) { + return; + } + + if(datasetTableTask != null && datasetTableTask.getRate().equalsIgnoreCase(ScheduleType.CRON.toString())) { + datasetTableTaskLog = writeDatasetTableTaskLog(datasetTableTaskLog, datasetTableId, taskId); + } + if(datasetTableTask != null && datasetTableTask.getRate().equalsIgnoreCase(ScheduleType.SIMPLE.toString())) { + datasetTableTaskLog = getDatasetTableTaskLog(datasetTableTaskLog, datasetTableId, taskId); + } + + if (StringUtils.isNotEmpty(datasetTableIncrementalConfig.getIncrementalAdd().replace(" ", ""))) {// 增量添加 + String sql = datasetTableIncrementalConfig.getIncrementalAdd().replace(lastUpdateTime, datasetTableTaskLogs.get(0).getStartTime().toString()) + .replace(currentUpdateTime, Long.valueOf(System.currentTimeMillis()).toString()); + generateTransFile("incremental_add", datasetTable, datasource, datasetTableFields, sql); + generateJobFile("incremental_add", datasetTable, fetchSqlField(sql, datasource)); + extractData(datasetTable, "incremental_add"); + } + + if (StringUtils.isNotEmpty(datasetTableIncrementalConfig.getIncrementalDelete().replace(" ", ""))) {// 增量删除 + String sql = datasetTableIncrementalConfig.getIncrementalDelete().replace(lastUpdateTime, datasetTableTaskLogs.get(0).getStartTime().toString()) + .replace(currentUpdateTime, Long.valueOf(System.currentTimeMillis()).toString()); + generateTransFile("incremental_delete", datasetTable, datasource, datasetTableFields, sql); + generateJobFile("incremental_delete", datasetTable, fetchSqlField(sql, datasource)); + extractData(datasetTable, "incremental_delete"); + } + saveSucessLog(datasetTableTaskLog); + updateTableStatus(datasetTableId, datasetTable, JobStatus.Completed); + } + }catch (Exception e){ + saveErrorLog(datasetTableId, taskId, e); + updateTableStatus(datasetTableId, datasetTable, JobStatus.Error); + }finally { + if (datasetTableTask != null && datasetTableTask.getRate().equalsIgnoreCase(ScheduleType.SIMPLE.toString())) { + datasetTableTask.setRate(ScheduleType.SIMPLE_COMPLETE.toString()); + dataSetTableTaskService.update(datasetTableTask); + } + deleteFile("incremental_add", datasetTableId); + deleteFile("incremental_delete", datasetTableId); + } + break; + } + } + + private void updateTableStatus(String datasetTableId, DatasetTable datasetTable, JobStatus completed) { + datasetTable.setSyncStatus(completed.name()); + DatasetTableExample example = new DatasetTableExample(); + example.createCriteria().andIdEqualTo(datasetTableId); + datasetTableMapper.updateByExampleSelective(datasetTable, example); + } + + private void saveSucessLog(DatasetTableTaskLog datasetTableTaskLog) { + datasetTableTaskLog.setStatus(JobStatus.Completed.name()); + datasetTableTaskLog.setEndTime(System.currentTimeMillis()); + dataSetTableTaskLogService.save(datasetTableTaskLog); + } + + private void saveErrorLog(String datasetTableId, String taskId, Exception e){ + LogUtil.error("Extract data error: " + datasetTableId, e); + DatasetTableTaskLog datasetTableTaskLog = new DatasetTableTaskLog(); + datasetTableTaskLog.setTableId(datasetTableId); + datasetTableTaskLog.setStatus(JobStatus.Underway.name()); + if(StringUtils.isNotEmpty(taskId)){ + datasetTableTaskLog.setTaskId(taskId); + } + List datasetTableTaskLogs = dataSetTableTaskLogService.select(datasetTableTaskLog); + if(CollectionUtils.isNotEmpty(datasetTableTaskLogs)){ + datasetTableTaskLog = datasetTableTaskLogs.get(0); + datasetTableTaskLog.setStatus(JobStatus.Error.name()); + datasetTableTaskLog.setInfo(ExceptionUtils.getStackTrace(e)); + datasetTableTaskLog.setEndTime(System.currentTimeMillis()); + dataSetTableTaskLogService.save(datasetTableTaskLog); + } + + } + private String createDorisTablColumnSql(List datasetTableFields) { String Column_Fields = "dataease_uuid varchar(50), `"; for (DatasetTableField datasetTableField : datasetTableFields) { @@ -189,133 +369,6 @@ public class ExtractDataService { jdbcProvider.exec(datasourceRequest); } - public synchronized boolean updateSyncStatus(DatasetTable datasetTable ){ - datasetTable.setSyncStatus(JobStatus.Underway.name()); - DatasetTableExample example = new DatasetTableExample(); - example.createCriteria().andIdEqualTo(datasetTable.getId()); - datasetTableMapper.selectByExample(example); - example.clear(); - example.createCriteria().andIdEqualTo(datasetTable.getId()).andSyncStatusNotEqualTo(JobStatus.Underway.name()); - example.or(example.createCriteria().andIdEqualTo(datasetTable.getId()).andSyncStatusIsNull()); - return datasetTableMapper.updateByExampleSelective(datasetTable, example) == 0; - } - - public void extractData(String datasetTableId, String taskId, String type, JobExecutionContext context) { - DatasetTable datasetTable = getDatasetTable(datasetTableId); - if(datasetTable == null){ - LogUtil.error("Can not find DatasetTable: " + datasetTableId); - } - DatasetTableTask datasetTableTask = datasetTableTaskMapper.selectByPrimaryKey(taskId); - boolean isCronJob = (datasetTableTask != null && datasetTableTask.getRate().equalsIgnoreCase(ScheduleType.CRON.toString())); - if(updateSyncStatus(datasetTable) && isCronJob){ - LogUtil.info("Skip synchronization task for table : " + datasetTableId); - return; - } - DatasetTableTaskLog datasetTableTaskLog = new DatasetTableTaskLog(); - UpdateType updateType = UpdateType.valueOf(type); - Datasource datasource = new Datasource(); - try { - if(context != null){ - datasetTable.setQrtzInstance(context.getFireInstanceId()); - datasetTableMapper.updateByPrimaryKeySelective(datasetTable); - } - if (StringUtils.isNotEmpty(datasetTable.getDataSourceId())) { - datasource = datasourceMapper.selectByPrimaryKey(datasetTable.getDataSourceId()); - } else { - datasource.setType(datasetTable.getType()); - } - - List datasetTableFields = dataSetTableFieldsService.list(DatasetTableField.builder().tableId(datasetTable.getId()).build()); - datasetTableFields.sort((o1, o2) -> { - if (o1.getColumnIndex() == null) { - return -1; - } - if (o2.getColumnIndex() == null) { - return 1; - } - return o1.getColumnIndex().compareTo(o2.getColumnIndex()); - }); - String dorisTablColumnSql = createDorisTablColumnSql(datasetTableFields); - switch (updateType) { - // 全量更新 - case all_scope: - datasetTableTaskLog = getDatasetTableTaskLog(datasetTableTaskLog, datasetTableId, taskId); - createDorisTable(DorisTableUtils.dorisName(datasetTableId), dorisTablColumnSql); - createDorisTable(DorisTableUtils.dorisTmpName(DorisTableUtils.dorisName(datasetTableId)), dorisTablColumnSql); - generateTransFile("all_scope", datasetTable, datasource, datasetTableFields, null); - generateJobFile("all_scope", datasetTable, String.join(",", datasetTableFields.stream().map(DatasetTableField::getDataeaseName).collect(Collectors.toList()))); - extractData(datasetTable, "all_scope"); - replaceTable(DorisTableUtils.dorisName(datasetTableId)); - datasetTableTaskLog.setStatus(JobStatus.Completed.name()); - datasetTableTaskLog.setEndTime(System.currentTimeMillis()); - dataSetTableTaskLogService.save(datasetTableTaskLog); - break; - - // 增量更新 - case add_scope: - DatasetTableIncrementalConfig datasetTableIncrementalConfig = dataSetTableService.incrementalConfig(datasetTableId); - if (datasetTableIncrementalConfig == null || StringUtils.isEmpty(datasetTableIncrementalConfig.getTableId())) { - return; - } - DatasetTableTaskLog request = new DatasetTableTaskLog(); - request.setTableId(datasetTableId); - request.setStatus(JobStatus.Completed.name()); - List dataSetTaskLogDTOS = dataSetTableTaskLogService.list(request); - if (CollectionUtils.isEmpty(dataSetTaskLogDTOS)) { - return; - } - datasetTableTaskLog = writeDatasetTableTaskLog(datasetTableTaskLog, datasetTableId, taskId); - - // 增量添加 - if (StringUtils.isNotEmpty(datasetTableIncrementalConfig.getIncrementalAdd().replace(" ", ""))) { - String sql = datasetTableIncrementalConfig.getIncrementalAdd().replace(lastUpdateTime, dataSetTaskLogDTOS.get(0).getStartTime().toString() - .replace(currentUpdateTime, Long.valueOf(System.currentTimeMillis()).toString())); - generateTransFile("incremental_add", datasetTable, datasource, datasetTableFields, sql); - generateJobFile("incremental_add", datasetTable, fetchSqlField(sql, datasource)); - extractData(datasetTable, "incremental_add"); - } - - // 增量删除 - if (StringUtils.isNotEmpty(datasetTableIncrementalConfig.getIncrementalDelete())) { - String sql = datasetTableIncrementalConfig.getIncrementalDelete().replace(lastUpdateTime, dataSetTaskLogDTOS.get(0).getStartTime().toString() - .replace(currentUpdateTime, Long.valueOf(System.currentTimeMillis()).toString())); - generateTransFile("incremental_delete", datasetTable, datasource, datasetTableFields, sql); - generateJobFile("incremental_delete", datasetTable, fetchSqlField(sql, datasource)); - extractData(datasetTable, "incremental_delete"); - } - datasetTableTaskLog.setStatus(JobStatus.Completed.name()); - datasetTableTaskLog.setEndTime(System.currentTimeMillis()); - dataSetTableTaskLogService.save(datasetTableTaskLog); - break; - } - datasetTable.setSyncStatus(JobStatus.Completed.name()); - DatasetTableExample example = new DatasetTableExample(); - example.createCriteria().andIdEqualTo(datasetTableId); - datasetTableMapper.updateByExampleSelective(datasetTable, example); - } catch (Exception e) { - e.printStackTrace(); - LogUtil.error("Extract data error: " + datasetTableId, e); - datasetTableTaskLog.setStatus(JobStatus.Error.name()); - datasetTableTaskLog.setInfo(ExceptionUtils.getStackTrace(e)); - datasetTableTaskLog.setEndTime(System.currentTimeMillis()); - dataSetTableTaskLogService.save(datasetTableTaskLog); - - datasetTable.setSyncStatus(JobStatus.Error.name()); - DatasetTableExample example = new DatasetTableExample(); - example.createCriteria().andIdEqualTo(datasetTableId); - datasetTableMapper.updateByExampleSelective(datasetTable, example); - - if(updateType.name().equalsIgnoreCase("all_scope")){ - dropDorisTable(DorisTableUtils.dorisTmpName(DorisTableUtils.dorisName(datasetTableId))); - } - } finally { - if (datasetTableTask != null && datasetTableTask.getRate().equalsIgnoreCase(ScheduleType.SIMPLE.toString())) { - datasetTableTask.setRate(ScheduleType.SIMPLE_COMPLETE.toString()); - dataSetTableTaskService.update(datasetTableTask); - } - } - } - private DatasetTable getDatasetTable(String datasetTableId){ for (int i=0;i<5;i++){ DatasetTable datasetTable = dataSetTableService.get(datasetTableId); @@ -353,6 +406,9 @@ public class ExtractDataService { if(CollectionUtils.isNotEmpty(datasetTableTaskLogs)){ return datasetTableTaskLogs.get(0); } + try { + Thread.sleep(1000); + }catch (Exception ignore){} } datasetTableTaskLog.setStartTime(System.currentTimeMillis()); dataSetTableTaskLogService.save(datasetTableTaskLog); @@ -360,8 +416,6 @@ public class ExtractDataService { } private void extractData(DatasetTable datasetTable, String extractType) throws Exception { - - KettleFileRepository repository = CommonBeanFactory.getBean(KettleFileRepository.class); RepositoryDirectoryInterface repositoryDirectoryInterface = repository.loadRepositoryDirectoryTree(); JobMeta jobMeta = null; @@ -643,7 +697,7 @@ public class ExtractDataService { ExcelInputField field = new ExcelInputField(); field.setName(datasetTableFields.get(i).getOriginName()); if(datasetTableFields.get(i).getDeExtractType() == 1){ - field.setType("Date"); + field.setType("String"); field.setFormat("yyyy-MM-dd HH:mm:ss"); }else { field.setType("String"); @@ -692,6 +746,7 @@ public class ExtractDataService { tmp_code = tmp_code.replace("handleExcelWraps", handleExcelWraps); }else { tmp_code = tmp_code.replace("handleExcelIntColumn", ""); + tmp_code = tmp_code.replace("handleExcelWraps", ""); } UserDefinedJavaClassDef userDefinedJavaClassDef = new UserDefinedJavaClassDef(UserDefinedJavaClassDef.ClassType.TRANSFORM_CLASS, "Processor", tmp_code); @@ -705,28 +760,57 @@ public class ExtractDataService { return userDefinedJavaClassStep; } + private void deleteFile(String type, String dataSetTableId){ + String transName = null; + String jobName = null; + + switch (type) { + case "all_scope": + transName = "trans_" + dataSetTableId; + jobName = "job_" + dataSetTableId; + break; + case "incremental_add": + transName = "trans_add_" + dataSetTableId; + jobName = "job_add_" + dataSetTableId; + break; + case "incremental_delete": + transName = "trans_delete_" + dataSetTableId; + jobName = "job_delete_" + dataSetTableId; + break; + default: + break; + } + try{ + File file = new File(root_path + jobName + ".kjb"); + FileUtils.forceDelete(file); + }catch (Exception e){} + try{ + File file = new File(root_path + transName + ".ktr"); + FileUtils.forceDelete(file); + }catch (Exception e){} + } + public boolean isKettleRunning() { - return true; -// try { -// if (!InetAddress.getByName(carte).isReachable(1000)) { -// return false; -// } -// HttpClient httpClient; -// HttpGet getMethod = new HttpGet("http://" + carte + ":" + port); -// HttpClientManager.HttpClientBuilderFacade clientBuilder = HttpClientManager.getInstance().createBuilder(); -// clientBuilder.setConnectionTimeout(1); -// clientBuilder.setCredentials(user, passwd); -// httpClient = clientBuilder.build(); -// HttpResponse httpResponse = httpClient.execute(getMethod); -// int statusCode = httpResponse.getStatusLine().getStatusCode(); -// if (statusCode != -1 && statusCode < 400) { -// return true; -// } else { -// return false; -// } -// } catch (Exception e) { -// return false; -// } + try { + if (!InetAddress.getByName(carte).isReachable(1000)) { + return false; + } + HttpClient httpClient; + HttpGet getMethod = new HttpGet("http://" + carte + ":" + port); + HttpClientManager.HttpClientBuilderFacade clientBuilder = HttpClientManager.getInstance().createBuilder(); + clientBuilder.setConnectionTimeout(1); + clientBuilder.setCredentials(user, passwd); + httpClient = clientBuilder.build(); + HttpResponse httpResponse = httpClient.execute(getMethod); + int statusCode = httpResponse.getStatusLine().getStatusCode(); + if (statusCode != -1 && statusCode < 400) { + return true; + } else { + return false; + } + } catch (Exception e) { + return false; + } } private static String alterColumnTypeCode = " if(\"FILED\".equalsIgnoreCase(filed)){\n" + diff --git a/backend/src/main/java/io/dataease/service/sys/PluginService.java b/backend/src/main/java/io/dataease/service/sys/PluginService.java index b911103bcf..880a5df0c9 100644 --- a/backend/src/main/java/io/dataease/service/sys/PluginService.java +++ b/backend/src/main/java/io/dataease/service/sys/PluginService.java @@ -5,9 +5,11 @@ import io.dataease.base.domain.MyPlugin; import io.dataease.base.mapper.MyPluginMapper; import io.dataease.base.mapper.ext.ExtSysPluginMapper; import io.dataease.base.mapper.ext.query.GridExample; +import io.dataease.commons.constants.AuthConstants; import io.dataease.commons.utils.DeFileUtils; import io.dataease.commons.utils.ZipUtils; import io.dataease.controller.sys.base.BaseGridRequest; +import io.dataease.listener.util.CacheUtils; import io.dataease.plugins.config.LoadjarUtil; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; @@ -89,6 +91,10 @@ public class PluginService { jarPath = DeFileUtils.copy(jarFile, targetDir); loadJar(jarPath, myPlugin); myPluginMapper.insert(myPlugin); + + CacheUtils.removeAll(AuthConstants.USER_CACHE_NAME); + CacheUtils.removeAll(AuthConstants.USER_ROLE_CACHE_NAME); + CacheUtils.removeAll(AuthConstants.USER_PERMISSION_CACHE_NAME); } catch (Exception e) { if (StringUtils.isNotEmpty(targetDir)) { DeFileUtils.deleteFile(targetDir); @@ -137,6 +143,9 @@ public class PluginService { * @return */ public Boolean uninstall(Long pluginId) { + CacheUtils.removeAll(AuthConstants.USER_CACHE_NAME); + CacheUtils.removeAll(AuthConstants.USER_ROLE_CACHE_NAME); + CacheUtils.removeAll(AuthConstants.USER_PERMISSION_CACHE_NAME); myPluginMapper.deleteByPrimaryKey(pluginId); return true; } @@ -148,6 +157,9 @@ public class PluginService { * @return */ public Boolean changeStatus(Long pluginId, Boolean status) { + CacheUtils.removeAll(AuthConstants.USER_CACHE_NAME); + CacheUtils.removeAll(AuthConstants.USER_ROLE_CACHE_NAME); + CacheUtils.removeAll(AuthConstants.USER_PERMISSION_CACHE_NAME); return false; } diff --git a/backend/src/main/resources/db/migration/V6__alter_table.sql b/backend/src/main/resources/db/migration/V6__alter_table.sql index 37106309dd..08febbdd3d 100644 --- a/backend/src/main/resources/db/migration/V6__alter_table.sql +++ b/backend/src/main/resources/db/migration/V6__alter_table.sql @@ -1,2 +1,33 @@ ALTER TABLE `dataset_table` ADD COLUMN `sync_status` VARCHAR(45) NULL AFTER `create_time`; ALTER TABLE `dataset_table` ADD COLUMN `qrtz_instance` VARCHAR(1024) NULL AFTER `create_time`; + + +BEGIN; +INSERT INTO `sys_auth` VALUES ('05e5440f-b9c1-4998-bb7e-cabdb293183f', '25', 'menu', '2', 'role', 1622713311975, NULL, 'admin', NULL); +INSERT INTO `sys_auth` VALUES ('19569764-ad2e-4d7b-b575-508913495ccf', '8', 'menu', '2', 'role', 1622713307681, NULL, 'admin', NULL); +INSERT INTO `sys_auth` VALUES ('4541d582-b532-47b1-9e64-b4937c7b614f', '30', 'menu', '2', 'role', 1622713299688, NULL, 'admin', NULL); +INSERT INTO `sys_auth` VALUES ('45dacd42-e9a4-4ce5-a03c-61c8850cf5b1', '10', 'menu', '2', 'role', 1622713304841, NULL, 'admin', NULL); +INSERT INTO `sys_auth` VALUES ('8b1e1e02-b6c2-49dc-9118-10ab31f78b46', '34', 'menu', '2', 'role', 1623142236719, NULL, 'admin', NULL); +INSERT INTO `sys_auth` VALUES ('a11f5705-887d-403b-9a9d-d3a1317ed91f', '24', 'menu', '2', 'role', 1622713311583, NULL, 'admin', NULL); +INSERT INTO `sys_auth` VALUES ('c318d302-457d-43d8-bb01-96a7cbbf6cb7', '27', 'menu', '2', 'role', 1622713313044, NULL, 'admin', NULL); +INSERT INTO `sys_auth` VALUES ('c3349d14-1433-41e6-9ddc-ba947c3b523c', '26', 'menu', '2', 'role', 1622713312606, NULL, 'admin', NULL); +COMMIT; + +BEGIN; +INSERT INTO `sys_auth_detail` VALUES ('980c14e1-c836-11eb-bbcc-00163e0c8d3f', '8b1e1e02-b6c2-49dc-9118-10ab31f78b46', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1623142236000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('980c1674-c836-11eb-bbcc-00163e0c8d3f', '8b1e1e02-b6c2-49dc-9118-10ab31f78b46', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1623142236000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('e59001d3-c44f-11eb-bbcc-00163e0c8d3f', '4541d582-b532-47b1-9e64-b4937c7b614f', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1622713299000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('e59003a0-c44f-11eb-bbcc-00163e0c8d3f', '4541d582-b532-47b1-9e64-b4937c7b614f', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1622713299000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('e8a4bdbf-c44f-11eb-bbcc-00163e0c8d3f', '45dacd42-e9a4-4ce5-a03c-61c8850cf5b1', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1622713304000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('e8a4bf70-c44f-11eb-bbcc-00163e0c8d3f', '45dacd42-e9a4-4ce5-a03c-61c8850cf5b1', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1622713304000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('ea536049-c44f-11eb-bbcc-00163e0c8d3f', '19569764-ad2e-4d7b-b575-508913495ccf', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1622713307000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('ea5361d6-c44f-11eb-bbcc-00163e0c8d3f', '19569764-ad2e-4d7b-b575-508913495ccf', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1622713307000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('eca67ad0-c44f-11eb-bbcc-00163e0c8d3f', 'a11f5705-887d-403b-9a9d-d3a1317ed91f', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1622713311000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('eca67c74-c44f-11eb-bbcc-00163e0c8d3f', 'a11f5705-887d-403b-9a9d-d3a1317ed91f', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1622713311000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('ece430b9-c44f-11eb-bbcc-00163e0c8d3f', '05e5440f-b9c1-4998-bb7e-cabdb293183f', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1622713312000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('ece4330e-c44f-11eb-bbcc-00163e0c8d3f', '05e5440f-b9c1-4998-bb7e-cabdb293183f', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1622713312000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('ed4328d0-c44f-11eb-bbcc-00163e0c8d3f', 'c3349d14-1433-41e6-9ddc-ba947c3b523c', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1622713312000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('ed432abc-c44f-11eb-bbcc-00163e0c8d3f', 'c3349d14-1433-41e6-9ddc-ba947c3b523c', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1622713312000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('ed8722a7-c44f-11eb-bbcc-00163e0c8d3f', 'c318d302-457d-43d8-bb01-96a7cbbf6cb7', 'i18n_auth_grant', 15, 0, 'grant', '基础权限-授权', 'admin', 1622713313000, NULL); +INSERT INTO `sys_auth_detail` VALUES ('ed872435-c44f-11eb-bbcc-00163e0c8d3f', 'c318d302-457d-43d8-bb01-96a7cbbf6cb7', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1622713313000, NULL); +COMMIT; \ No newline at end of file diff --git a/backend/src/main/resources/ehcache/ehcache.xml b/backend/src/main/resources/ehcache/ehcache.xml index 9491e0fa0d..a85f1cbf10 100644 --- a/backend/src/main/resources/ehcache/ehcache.xml +++ b/backend/src/main/resources/ehcache/ehcache.xml @@ -69,5 +69,18 @@ memoryStoreEvictionPolicy="LRU" /> + + + + \ No newline at end of file diff --git a/backend/src/main/resources/i18n/messages_en_US.properties b/backend/src/main/resources/i18n/messages_en_US.properties index 8526143f3b..6104b1f290 100644 --- a/backend/src/main/resources/i18n/messages_en_US.properties +++ b/backend/src/main/resources/i18n/messages_en_US.properties @@ -252,3 +252,5 @@ i18n_id_or_pwd_error=Invalid ID or password i18n_datasource_delete=Data source is delete i18n_dataset_delete=Data set is delete i18n_chart_delete=Chart is delete +i18n_not_exec_add_sync=There is no completed synchronization task. Incremental synchronization cannot be performed +i18n_excel_header_empty=Excel first row can not empty \ No newline at end of file diff --git a/backend/src/main/resources/i18n/messages_zh_CN.properties b/backend/src/main/resources/i18n/messages_zh_CN.properties index 75459b9951..b84e2e707f 100644 --- a/backend/src/main/resources/i18n/messages_zh_CN.properties +++ b/backend/src/main/resources/i18n/messages_zh_CN.properties @@ -252,3 +252,5 @@ i18n_id_or_pwd_error=无效的ID或密码 i18n_datasource_delete=当前用到的数据源已被删除 i18n_dataset_delete=当前用到的数据集已被删除 i18n_chart_delete=当前用到的视图已被删除 +i18n_not_exec_add_sync=没有已完成的同步任务,无法进行增量同步 +i18n_excel_header_empty=Excel第一行为空 diff --git a/backend/src/main/resources/i18n/messages_zh_TW.properties b/backend/src/main/resources/i18n/messages_zh_TW.properties index 94d480cab4..c3f19a9647 100644 --- a/backend/src/main/resources/i18n/messages_zh_TW.properties +++ b/backend/src/main/resources/i18n/messages_zh_TW.properties @@ -254,3 +254,5 @@ i18n_id_or_pwd_error=無效的ID或密碼 i18n_datasource_delete=當前用到的數據源已被刪除 i18n_dataset_delete=當前用到的數據集已被刪除 i18n_chart_delete=當前用到的視圖已被刪除 +i18n_not_exec_add_sync=沒有已經完成的同步任務,無法進行增量同步 +i18n_excel_header_empty=Excel第一行為空 \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index abaab1bdb3..a131c3b570 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -18,7 +18,7 @@ "@riophae/vue-treeselect": "0.4.0", "axios": "^0.21.1", "core-js": "^2.6.5", - "echarts": "^5.0.2", + "echarts": "^5.0.1", "element-resize-detector": "^1.2.2", "element-ui": "2.13.0", "file-saver": "^2.0.5", @@ -58,8 +58,8 @@ "eslint": "5.15.3", "eslint-plugin-vue": "5.2.2", "html-webpack-plugin": "3.2.0", - "less": "^4.1.1", - "less-loader": "^8.0.0", + "less": "^3.0.0", + "less-loader": "^5.0.0", "mockjs": "1.0.1-beta3", "runjs": "^4.1.3", "sass": "^1.32.5", diff --git a/frontend/src/api/system/dynamic.js b/frontend/src/api/system/dynamic.js index 3ab521ed0e..053c405aaa 100644 --- a/frontend/src/api/system/dynamic.js +++ b/frontend/src/api/system/dynamic.js @@ -3,7 +3,8 @@ import request from '@/utils/request' export function get(url) { return request({ url: url, - method: 'get' + method: 'get', + loading: true }) } diff --git a/frontend/src/components/SvgIcon/index.vue b/frontend/src/components/SvgIcon/index.vue index 9a3318e5e6..0446ae9079 100644 --- a/frontend/src/components/SvgIcon/index.vue +++ b/frontend/src/components/SvgIcon/index.vue @@ -19,6 +19,10 @@ export default { className: { type: String, default: '' + }, + customClass: { + type: String, + default: '' } }, computed: { @@ -31,9 +35,11 @@ export default { svgClass() { if (this.className) { return 'svg-icon ' + this.className - } else { - return 'svg-icon' } + if (this.customClass) { + return this.customClass + } + return 'svg-icon' }, styleExternalIcon() { return { diff --git a/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue b/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue index afaec2cfc8..57ec8b0c8e 100644 --- a/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue +++ b/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue @@ -17,7 +17,6 @@ :style="getStyle(config.style)" :prop-value="config.propValue" :element="config" - :filter="filter" /> @@ -32,11 +31,13 @@ export default { props: { config: { type: Object, - require: true + require: true, + default: null }, filter: { type: Object, - require: false + require: false, + default: null } }, mounted() { diff --git a/frontend/src/components/canvas/components/Editor/ContextMenu.vue b/frontend/src/components/canvas/components/Editor/ContextMenu.vue index 81173c5546..d0216824da 100644 --- a/frontend/src/components/canvas/components/Editor/ContextMenu.vue +++ b/frontend/src/components/canvas/components/Editor/ContextMenu.vue @@ -89,7 +89,7 @@ export default { deleteCurCondition() { if (this.curComponent.type === 'custom') { - this.$store.dispatch('conditions/delete', { componentId: this.curComponent.id }) + this.$store.commit('removeViewFilter', this.curComponent.id) bus.$emit('delete-condition', { componentId: this.curComponent.id }) } }, diff --git a/frontend/src/components/canvas/components/Editor/Preview.vue b/frontend/src/components/canvas/components/Editor/Preview.vue index 41fe23c0cb..a0d82477b2 100644 --- a/frontend/src/components/canvas/components/Editor/Preview.vue +++ b/frontend/src/components/canvas/components/Editor/Preview.vue @@ -102,7 +102,7 @@ export default { }, created() { // 先清除查询条件 - this.$store.dispatch('conditions/clear') + // this.$store.dispatch('conditions/clear') }, methods: { changeStyleWithScale, diff --git a/frontend/src/components/canvas/components/Editor/Shape.vue b/frontend/src/components/canvas/components/Editor/Shape.vue index 2fdc44c1b8..2191c2886e 100644 --- a/frontend/src/components/canvas/components/Editor/Shape.vue +++ b/frontend/src/components/canvas/components/Editor/Shape.vue @@ -36,15 +36,18 @@ export default { }, element: { require: true, - type: Object + type: Object, + default: null }, defaultStyle: { require: true, - type: Object + type: Object, + default: null }, index: { require: true, - type: [Number, String] + type: [Number, String], + default: null } }, data() { @@ -200,6 +203,7 @@ export default { pointList.forEach(point => { const angle = mod360(initialAngle[point] + rotate) const len = angleToCursor.length + // eslint-disable-next-line no-constant-condition while (true) { lastMatchIndex = (lastMatchIndex + 1) % len const angleLimit = angleToCursor[lastMatchIndex] diff --git a/frontend/src/components/canvas/components/Editor/index.vue b/frontend/src/components/canvas/components/Editor/index.vue index 932fce6ff6..00169fe067 100644 --- a/frontend/src/components/canvas/components/Editor/index.vue +++ b/frontend/src/components/canvas/components/Editor/index.vue @@ -50,7 +50,6 @@ :style="getComponentStyle(item.style)" :prop-value="item.propValue" :element="item" - :filter="filter" :out-style="getShapeStyleInt(item.style)" /> { this.hideArea() }) - bus.$on('delete-condition', condition => { - this.deleteCondition(condition) - }) + // bus.$on('delete-condition', condition => { + // this.deleteCondition(condition) + // }) }, created() { - this.$store.dispatch('conditions/clear') + // this.$store.dispatch('conditions/clear') }, methods: { changeStyleWithScale, @@ -446,40 +447,6 @@ export default { return height > newHeight ? height : newHeight }, - filterValueChange(value) { - // console.log('emit:' + value) - }, - - setConditionValue(obj) { - const { component, value, operator } = obj - const fieldId = component.options.attrs.fieldId - const viewIds = component.options.attrs.viewIds - const condition = new Condition(component.id, fieldId, operator, value, viewIds) - this.addCondition(condition) - }, - addCondition(condition) { - let conditionExist = false - for (let index = 0; index < this.conditions.length; index++) { - const element = this.conditions[index] - if (condition.componentId === element.componentId) { - this.conditions[index] = condition - conditionExist = true - } - } - !conditionExist && this.conditions.push(condition) - this.executeSearch() - }, - deleteCondition(condition) { - this.conditions = this.conditions.filter(item => { - const componentIdSuitable = !condition.componentId || (item.componentId === condition.componentId) - const fieldIdSuitable = !condition.fieldId || (item.fieldId === condition.fieldId) - return !(componentIdSuitable && fieldIdSuitable) - }) - this.executeSearch() - }, - executeSearch() { - // console.log('当前查询条件是: ' + JSON.stringify(this.conditions)) - }, format(value, scale) { // 自适应画布区域 返回原值 if (this.canvasStyleData.selfAdaption) { diff --git a/frontend/src/components/canvas/custom-component/UserView.vue b/frontend/src/components/canvas/custom-component/UserView.vue index aef84fac77..12cd71c0e2 100644 --- a/frontend/src/components/canvas/custom-component/UserView.vue +++ b/frontend/src/components/canvas/custom-component/UserView.vue @@ -22,7 +22,7 @@ import LabelNormal from '../../../views/chart/components/normal/LabelNormal' import { uuid } from 'vue-uuid' import { mapState } from 'vuex' - +import { isChange } from '@/utils/conditionUtil' import { DEFAULT_COLOR_CASE, DEFAULT_SIZE, @@ -40,17 +40,14 @@ export default { components: { ChartComponent, TableNormal, LabelNormal }, props: { element: { - type: Object - }, - filter: { type: Object, - required: false, - default: function() { - return { - filter: [] - } - } + default: null }, + // filters: { + // type: Array, + // required: false, + // default: null + // }, outStyle: { type: Object, required: false, @@ -59,38 +56,6 @@ export default { } } }, - watch: { - '$store.getters.conditions': function(newVal, oldVal) { - this.filter.filter = newVal - this.getData(this.element.propValue.viewId) - }, - filter(val) { - this.getData(this.element.propValue.viewId) - }, - // deep监听panel 如果改变 提交到 store - canvasStyleData: { - handler(newVal, oldVla) { - // this.chart.stylePriority == panel 优先使用仪表板样式 - this.mergeStyle() - }, - deep: true - }, - // 监听外部的样式变化 - outStyle: { - handler(newVal, oldVla) { - if (this.$refs[this.element.propValue.id]) { - this.$refs[this.element.propValue.id].chartResize() - } - }, - deep: true - } - }, - created() { - this.refId = uuid.v1 - }, - computed: mapState([ - 'canvasStyleData' - ]), data() { return { refId: null, @@ -120,8 +85,49 @@ export default { message: null } }, + computed: { + filter() { + const filter = {} + filter.filter = this.element.filters + return filter + }, + filters() { + // 必要 勿删勿该 watch数组,哪怕发生变化 oldValue等于newValue ,深拷贝解决 + if (!this.element.filters) return [] + return JSON.parse(JSON.stringify(this.element.filters)) + }, + ...mapState([ + 'canvasStyleData' + ]) + }, + + watch: { + 'filters': function(val1, val2) { + // this.getData(this.element.propValue.viewId) + isChange(val1, val2) && this.getData(this.element.propValue.viewId) + }, + // deep监听panel 如果改变 提交到 store + canvasStyleData: { + handler(newVal, oldVla) { + // this.chart.stylePriority == panel 优先使用仪表板样式 + this.mergeStyle() + }, + deep: true + }, + // 监听外部的样式变化 + outStyle: { + handler(newVal, oldVla) { + if (this.$refs[this.element.propValue.id]) { + this.$refs[this.element.propValue.id].chartResize() + } + }, + deep: true + } + }, + created() { - this.filter.filter = this.$store.getters.conditions + this.refId = uuid.v1 + // this.filter.filter = this.$store.getters.conditions this.getData(this.element.propValue.viewId) }, mounted() { @@ -173,6 +179,9 @@ export default { return true }) } + }, + viewIdMatch(viewIds, viewId) { + return !viewIds || viewIds.length === 0 || viewIds.includes(viewId) } } } diff --git a/frontend/src/components/widget/DeWidget/DeDate.vue b/frontend/src/components/widget/DeWidget/DeDate.vue index 1370afde61..bdc86c10cc 100644 --- a/frontend/src/components/widget/DeWidget/DeDate.vue +++ b/frontend/src/components/widget/DeWidget/DeDate.vue @@ -47,7 +47,7 @@ export default { operator: this.operator } param.value = this.formatValues(param.value) - this.inDraw && this.$store.dispatch('conditions/add', param) + this.inDraw && this.$store.commit('addViewFilter', param) }, dateChange(value) { this.setCondition() diff --git a/frontend/src/components/widget/DeWidget/DeInputSearch.vue b/frontend/src/components/widget/DeWidget/DeInputSearch.vue index 988dad687f..3927e7822e 100644 --- a/frontend/src/components/widget/DeWidget/DeInputSearch.vue +++ b/frontend/src/components/widget/DeWidget/DeInputSearch.vue @@ -49,7 +49,7 @@ export default { value: [this.options.value], operator: this.operator } - this.inDraw && this.$store.dispatch('conditions/add', param) + this.inDraw && this.$store.commit('addViewFilter', param) }, setEdit() { this.canEdit = true diff --git a/frontend/src/components/widget/DeWidget/DeSelect.vue b/frontend/src/components/widget/DeWidget/DeSelect.vue index 267f116da4..cb9e8d8326 100644 --- a/frontend/src/components/widget/DeWidget/DeSelect.vue +++ b/frontend/src/components/widget/DeWidget/DeSelect.vue @@ -37,8 +37,6 @@ export default { data() { return { options: null, - // operator: 'eq', - values: null, showNumber: false } }, @@ -49,26 +47,32 @@ export default { }, watch: { 'options.attrs.multiple': function(value) { + const sourceValue = this.options.value if (value) { - this.values = [] + !sourceValue && (this.options.value = []) + sourceValue && !Array.isArray(sourceValue) && (this.options.value = sourceValue.split(',')) + !this.inDraw && (this.options.value = []) } else { - this.values = null + !sourceValue && (this.options.value = null) + sourceValue && Array.isArray(sourceValue) && (this.options.value = sourceValue[0]) + !this.inDraw && (this.options.value = null) } } }, created() { this.options = this.element.options - this.setCondition() + + // this.setCondition() }, mounted() { - this.$nextTick(() => { - - }) + // this.$nextTick(() => { + // this.options && this.options.value && this.changeValue(this.options.value) + // }) + this.options && this.options.value && this.changeValue(this.options.value) }, methods: { changeValue(value) { this.setCondition() - // this.inDraw && this.$emit('set-condition-value', { component: this.element, value: [value], operator: this.operator }) this.showNumber = false this.$nextTick(() => { if (!this.$refs.deSelect.$refs.tags || !this.options.attrs.multiple) { @@ -89,7 +93,7 @@ export default { value: Array.isArray(this.options.value) ? this.options.value : [this.options.value], operator: this.operator } - this.inDraw && this.$store.dispatch('conditions/add', param) + this.inDraw && this.$store.commit('addViewFilter', param) } } } diff --git a/frontend/src/components/widget/serviceImpl/TextSelectServiceImpl.js b/frontend/src/components/widget/serviceImpl/TextSelectServiceImpl.js index 61d378baea..a915ba308c 100644 --- a/frontend/src/components/widget/serviceImpl/TextSelectServiceImpl.js +++ b/frontend/src/components/widget/serviceImpl/TextSelectServiceImpl.js @@ -27,7 +27,7 @@ const drawPanel = { type: 'custom', style: { width: 300, - height: 47, + height: 38, fontSize: 14, fontWeight: 500, lineHeight: '', diff --git a/frontend/src/icons/svg/DataEase.svg b/frontend/src/icons/svg/DataEase.svg new file mode 100644 index 0000000000..c3fdc13e07 --- /dev/null +++ b/frontend/src/icons/svg/DataEase.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 2a2a42c68e..d78249c451 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -455,7 +455,7 @@ export default { admin: 'Administrator', org_admin: 'Organization Administrator', org_member: 'Organization Member', - add: 'Add Role', + add: 'Create Role', delete: 'Delete Role', modify: 'Modify Role', tips: 'Tips', @@ -532,15 +532,15 @@ export default { cancel: 'Cancel', search: 'Search', back: 'Back', - add_table: 'Add Table', + add_table: 'Add Dataset', process: 'Speed of progress', add_chart: 'Add Chart', - db_data: 'Database Table', + db_data: 'Database Dataset', sql_data: 'SQL data set', excel_data: 'Excel data set', custom_data: 'Custom data set', pls_slc_tbl_left: 'Please select the chart from the left', - add_db_table: 'Add database table', + add_db_table: 'Add Database Dataset', pls_slc_data_source: 'Please select data source', table: 'Table', edit: 'Edit', @@ -663,7 +663,7 @@ export default { radius_mode: 'Radius', area_mode: 'Area', rose_radius: 'Fillet', - view_name: 'Chart Name', + view_name: 'Chart Title', name_can_not_empty: 'Name cannot be empty', template_can_not_empty: 'Please check a Template', custom_count: 'Number of records', @@ -715,7 +715,8 @@ export default { date_split: 'yyyy/MM/dd', chartName: 'New Chart', chart_show_error: 'can not show normal', - chart_error_tips: 'Please contact admin ' + chart_error_tips: 'Please contact admin ', + title_cannot_empty: 'Title can not be empty' }, dataset: { sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default', @@ -737,12 +738,12 @@ export default { add_table: 'Add Table', process: 'Speed of progress', update: 'update', - db_data: 'Database Table', + db_data: 'Database Dataset', sql_data: 'SQL data set', excel_data: 'Excel data set', custom_data: 'Custom data set', pls_slc_tbl_left: 'Please select the chart from the left', - add_db_table: 'Add database table', + add_db_table: 'Add Database Dataset', pls_slc_data_source: 'Please select data source', table: 'Table', edit: 'Edit', @@ -753,7 +754,7 @@ export default { field_origin_name: 'Field Origin Name', field_check: 'Selected', update_info: 'Update Info', - join_view: 'Associated view', + join_view: 'Data Associated', text: 'Text', time: 'Time', value: 'Value', @@ -785,7 +786,7 @@ export default { close: 'Close', required: 'Required', input_content: 'Please input the content', - add_sql_table: 'Add SQL', + add_sql_table: 'Add SQL Dataset', preview: 'Preview', pls_input_name: 'Please enter a name', connect_mode: 'Connection Mode', @@ -795,7 +796,7 @@ export default { last_update_time: 'Last update time', current_update_time: 'Current update time', param: 'Parameter', - edit_sql: 'Edit SQL', + edit_sql: 'Edit SQL Dataset', showRow: 'Display line', add_excel_table: 'Add excel dataset', add_custom_table: 'Add self help dataset', @@ -811,7 +812,7 @@ export default { field_edit: 'Edit Field', table_already_add_to: 'This table is already add to', uploading: 'Uploading...', - add_union: 'Add Associations', + add_union: 'Create Associations', union_setting: 'Association Settings', pls_slc_union_field: 'Please select associated field', pls_slc_union_table: 'Please select association table', @@ -830,7 +831,15 @@ export default { preview_100_data: 'Show 100 lines data', invalid_table_check: 'Please sync data first.', parse_error: 'Parse Error', - origin_field_type: 'Origin Type' + origin_field_type: 'Origin Type', + edit_excel_table: 'Edit Excel Dataset', + edit_excel: 'Edit Excel', + excel_replace: 'Replace', + excel_add: 'Add', + dataset_group: 'Dataset Group', + m1: 'Move ', + m2: ' To', + char_can_not_more_50: 'Dataset name can not more 50' }, datasource: { datasource: 'Data Source', @@ -840,7 +849,7 @@ export default { data_base: 'Database name', user_name: 'User Name', password: 'Password', - host: 'Host', + host: 'Host name / IP address', port: 'Port', please_input_data_base: 'Please enter the database name', please_input_user_name: 'Please enter user name', @@ -1015,6 +1024,7 @@ export default { datasetAuth: 'Dataset Permissions', chartAuth: 'Chart Permissions', panelAuth: 'Dashboard Permissions', + menuAuth: 'Menu and operation permission', deptHead: 'All Dept', roleHead: 'All Role', userHead: 'All User', diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index deb4b2a023..9882cf983b 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -425,7 +425,7 @@ export default { no_such_user: '无此用戶信息, 請輸入正确的用戶 ID 或者 用戶郵箱!' }, user: { - create: '創建用戶', + create: '新建用戶', modify: '修改用戶', input_name: '請輸入用戶姓名', input_id: '請輸入ID', @@ -455,7 +455,7 @@ export default { admin: '系統管理員', org_admin: '組織管理员', org_member: '組織成員', - add: '添加角色', + add: '新建角色', delete: '删除角色', modify: '修改角色', tips: '提示', @@ -489,7 +489,7 @@ export default { sort: '組織排序', sub_organizations: '下屬組織數', create_time: '創建日期', - create: '創建組織', + create: '新建組織', modify: '修改組織', delete: '删除組織', delete_confirm: '删除該組織會關聯刪除該組織的下屬組織,確定要删除吗?', @@ -532,13 +532,13 @@ export default { cancel: '取消', search: '搜索', back: '返回', - add_table: '添加表', + add_table: '添加數據集', process: '進度', add_chart: '添加視圖', - db_data: '數據庫表', + db_data: '數據庫數據集', sql_data: 'SQL數據集', excel_data: 'Excel數據集', - custom_data: '自助數據集', + custom_data: '自定義數據集', pls_slc_tbl_left: '請從左側選擇視圖', add_db_table: '添加數據庫表', pls_slc_data_source: '請選擇數據源', @@ -663,7 +663,7 @@ export default { radius_mode: '半徑', area_mode: '面積', rose_radius: '園角', - view_name: '視圖名稱', + view_name: '視圖標題', name_can_not_empty: '名稱不能為空', template_can_not_empty: '请选择仪表板', custom_count: '記錄數', @@ -715,7 +715,8 @@ export default { date_split: 'yyyy/MM/dd', chartName: '新建視圖', chart_show_error: '無法正常顯示', - chart_error_tips: '如有疑問請聯系管理員' + chart_error_tips: '如有疑問請聯系管理員', + title_cannot_empty: '標題不能為空' }, dataset: { sheet_warn: '有多個sheet頁面,默認抽取第一個', @@ -734,15 +735,15 @@ export default { cancel: '取消', search: '搜索', back: '返回', - add_table: '添加表', + add_table: '添加數據集', process: '進度', update: '更新', - db_data: '數據庫表', - sql_data: 'SQL數據集', - excel_data: 'Excel數據集', - custom_data: '自助數據集', + db_data: '數據庫數據集', + sql_data: 'SQL 數據集', + excel_data: 'Excel 數據集', + custom_data: '自定義數據集', pls_slc_tbl_left: '請從左側選擇表', - add_db_table: '添加數據庫表', + add_db_table: '添加數據庫數據集', pls_slc_data_source: '請選擇數據源', table: '表', edit: '編輯', @@ -753,7 +754,7 @@ export default { field_origin_name: '原始名', field_check: '選中', update_info: '更新信息', - join_view: '關聯視圖', + join_view: '數據關聯', text: '文本', time: '時間', value: '數值', @@ -785,7 +786,7 @@ export default { close: '關閉', required: '必填', input_content: '請輸入內容', - add_sql_table: '添加 SQL', + add_sql_table: '添加 SQL 數據集', preview: '預覽', pls_input_name: '請輸入名稱', connect_mode: '鏈接模式', @@ -795,10 +796,10 @@ export default { last_update_time: '上次更新時間', current_update_time: '當前更新時間', param: '參數', - edit_sql: '編輯 SQL', + edit_sql: '編輯 SQL 數據集', showRow: '顯示行', add_excel_table: ' 添加 Excel 數據集', - add_custom_table: '添加自助數據集', + add_custom_table: '添加自定義數據集', upload_file: '上傳文件', detail: '詳情', type: '類型', @@ -811,7 +812,7 @@ export default { field_edit: '編輯字段', table_already_add_to: '該表已添加至', uploading: '上傳中...', - add_union: '添加關聯', + add_union: '新建關聯', union_setting: '關聯設置', pls_slc_union_field: '請選擇關聯字段', pls_slc_union_table: '請選擇關聯表', @@ -830,7 +831,15 @@ export default { preview_100_data: '顯示前100行數據', invalid_table_check: '非直連數據集請先完成數據同步', parse_error: '解析錯誤', - origin_field_type: '原始類型' + origin_field_type: '原始類型', + edit_excel_table: '編輯Excel數據集', + edit_excel: '編輯Excel', + excel_replace: '替換', + excel_add: '追加', + dataset_group: '數據集分組', + m1: '將 ', + m2: ' 移動到', + char_can_not_more_50: '數據集名稱不能超過50個字符' }, datasource: { datasource: '數據源', @@ -840,7 +849,7 @@ export default { data_base: '數據庫名稱', user_name: '用戶名', password: '密碼', - host: '主機', + host: '主機名/IP地址', port: '端口', please_input_data_base: '請輸入數據庫名稱', please_input_user_name: '請輸入用戶名', @@ -1015,6 +1024,7 @@ export default { datasetAuth: '數據集權限', chartAuth: '視圖權限', panelAuth: '儀表板權限', + menuAuth: '菜單和操作權限', deptHead: '所有组织', roleHead: '所有角色', userHead: '所有用戶', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 1bafe36a32..fd6a4295ed 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -425,7 +425,7 @@ export default { no_such_user: '无此用户信息, 请输入正确的用户 ID 或者 用户邮箱!' }, user: { - create: '创建用户', + create: '新建用户', modify: '修改用户', input_name: '请输入用户姓名', input_id: '请输入ID', @@ -455,7 +455,7 @@ export default { admin: '系统管理员', org_admin: '组织管理员', org_member: '组织成员', - add: '添加角色', + add: '新建角色', delete: '删除角色', modify: '修改角色', tips: '提示', @@ -489,7 +489,7 @@ export default { sort: '组织排序', sub_organizations: '下属组织数', create_time: '创建日期', - create: '创建组织', + create: '新建组织', modify: '修改组织', delete: '删除组织', delete_confirm: '删除该组织会关联删除该组织的下属组织,确定要删除吗?', @@ -532,15 +532,15 @@ export default { cancel: '取消', search: '搜索', back: '返回', - add_table: '添加表', + add_table: '添加数据集', process: '进度', add_chart: '添加视图', - db_data: '数据库表', + db_data: '数据库数据集', sql_data: 'SQL数据集', excel_data: 'Excel数据集', - custom_data: '自助数据集', + custom_data: '自定义数据集', pls_slc_tbl_left: '请从左侧选视图', - add_db_table: '添加数据库表', + add_db_table: '添加数据库数据集', pls_slc_data_source: '请选择数据源', table: '表', edit: '编辑', @@ -663,7 +663,7 @@ export default { radius_mode: '半径', area_mode: '面积', rose_radius: '圆角', - view_name: '视图名称', + view_name: '视图标题', name_can_not_empty: '名称不能为空', template_can_not_empty: '请选择仪表版', custom_count: '记录数', @@ -715,10 +715,11 @@ export default { date_split: 'yyyy/MM/dd', chartName: '新建视图', chart_show_error: '无法正常显示', - chart_error_tips: '如有疑问请联系管理员' + chart_error_tips: '如有疑问请联系管理员', + title_cannot_empty: '标题不能为空' }, dataset: { - sheet_warn: '有多个Sheet页,默认抽取第一个', + sheet_warn: '有多个 Sheet 页,默认抽取第一个', datalist: '数据集', add_group: '添加分组', add_scene: '添加场景', @@ -734,15 +735,15 @@ export default { cancel: '取消', search: '搜索', back: '返回', - add_table: '添加表', + add_table: '添加数据集', process: '进度', update: '更新', - db_data: '数据库表', - sql_data: 'SQL数据集', - excel_data: 'Excel数据集', - custom_data: '自助数据集', + db_data: '数据库数据集', + sql_data: 'SQL 数据集', + excel_data: 'Excel 数据集', + custom_data: '自定义数据集', pls_slc_tbl_left: '请从左侧选择表', - add_db_table: '添加数据库表', + add_db_table: '添加数据库数据集', pls_slc_data_source: '请选择数据源', table: '表', edit: '编辑', @@ -753,7 +754,7 @@ export default { field_origin_name: '原始名', field_check: '选中', update_info: '更新信息', - join_view: '关联视图', + join_view: '数据关联', text: '文本', time: '时间', value: '数值', @@ -785,7 +786,7 @@ export default { close: '关闭', required: '必填', input_content: '请输入内容', - add_sql_table: '添加SQL', + add_sql_table: '添加 SQL 数据集', preview: '预览', pls_input_name: '请输入名称', connect_mode: '连接模式', @@ -795,10 +796,10 @@ export default { last_update_time: '上次更新时间', current_update_time: '当前更新时间', param: '参数', - edit_sql: '编辑SQL', + edit_sql: '编辑 SQL 数据集', showRow: '显示行', add_excel_table: '添加Excel数据集', - add_custom_table: '添加自助数据集', + add_custom_table: '添加自定义数据集', upload_file: '上传文件', detail: '详情', type: '类型', @@ -811,7 +812,7 @@ export default { field_edit: '编辑字段', table_already_add_to: '该表已添加至', uploading: '上传中...', - add_union: '添加关联', + add_union: '新建关联', union_setting: '关联设置', pls_slc_union_field: '请选择关联字段', pls_slc_union_table: '请选择关联表', @@ -825,12 +826,20 @@ export default { check_all: '全选', can_not_union_self: '被关联表不能与关联表相同', float: '小数', - edit_custom_table: '编辑自助数据集', + edit_custom_table: '编辑自定义数据集', edit_field: '编辑字段', preview_100_data: '显示前100行数据', invalid_table_check: '非直连数据集请先完成数据同步', parse_error: '解析错误', - origin_field_type: '原始类型' + origin_field_type: '原始类型', + edit_excel_table: '编辑Excel数据集', + edit_excel: '编辑Excel', + excel_replace: '替换', + excel_add: '追加', + dataset_group: '数据集分组', + m1: '将 ', + m2: ' 移动到', + char_can_not_more_50: '数据集名称不能超过50个字符' }, datasource: { datasource: '数据源', @@ -840,7 +849,7 @@ export default { data_base: '数据库名称', user_name: '用户名', password: '密码', - host: '主机', + host: '主机名/IP地址', port: '端口', please_input_data_base: '请输入数据库名称', please_input_user_name: '请输入用户名', diff --git a/frontend/src/layout/components/Topbar.vue b/frontend/src/layout/components/Topbar.vue index 03c016a265..56993f6b4a 100644 --- a/frontend/src/layout/components/Topbar.vue +++ b/frontend/src/layout/components/Topbar.vue @@ -1,7 +1,8 @@ + + diff --git a/frontend/src/views/login/index.vue b/frontend/src/views/login/index.vue index b2ebe6e7c0..a3e86c78a6 100644 --- a/frontend/src/views/login/index.vue +++ b/frontend/src/views/login/index.vue @@ -5,11 +5,14 @@ -