Merge branch 'dev-v2' into pr@dev-v2@refactor_label

This commit is contained in:
王嘉豪 2023-12-27 15:30:46 +08:00 committed by GitHub
commit 2a7655e885
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
224 changed files with 2344 additions and 1057 deletions

8
.gitattributes vendored
View File

@ -1 +1,9 @@
*.sql linguist-language=java *.sql linguist-language=java
*.java linguist-language=Java
*.md linguist-language=Java
*.yml linguist-language=Java
*.html linguist-language=Java
*.js linguist-language=Java
*.xml linguist-language=Java
*.css linguist-language=Java
*.ts linguist-language=Java

View File

@ -3,7 +3,7 @@ name: Bug 提交
about: 提交产品缺陷帮助我们更好的改进 about: 提交产品缺陷帮助我们更好的改进
title: "[Bug]" title: "[Bug]"
labels: 状态:待处理 labels: 状态:待处理
assignees: BBchicken-9527, zrfit assignees: BBchicken-9527, Shenguobin0102, zrfit
--- ---

View File

@ -6,11 +6,6 @@
<a href="https://github.com/dataease/dataease"><img src="https://img.shields.io/github/stars/dataease/dataease?color=%231890FF&style=flat-square" alt="Stars"></a> <a href="https://github.com/dataease/dataease"><img src="https://img.shields.io/github/stars/dataease/dataease?color=%231890FF&style=flat-square" alt="Stars"></a>
</p> </p>
|说明|
|------------------|
|此分支为 DataEase v2 版本的开发分支DataEase v2 正在快速迭代中如是在生产环境部署 DataEase建议使用 v1.18.* 的最新稳定版本|
<hr/>
## 什么是 DataEase ## 什么是 DataEase
DataEase 是开源的数据可视化分析工具帮助用户快速分析数据并洞察业务趋势从而实现业务的改进与优化DataEase 支持丰富的数据源连接能够通过拖拉拽方式快速制作图表并可以方便的与他人分享 DataEase 是开源的数据可视化分析工具帮助用户快速分析数据并洞察业务趋势从而实现业务的改进与优化DataEase 支持丰富的数据源连接能够通过拖拉拽方式快速制作图表并可以方便的与他人分享
@ -56,6 +51,7 @@ DataEase 是开源的数据可视化分析工具,帮助用户快速分析数
- [在线文档](https://dataease.io/docs/) - [在线文档](https://dataease.io/docs/)
- [社区论坛](https://bbs.fit2cloud.com/c/de/6) - [社区论坛](https://bbs.fit2cloud.com/c/de/6)
- [快速入门视频](https://www.bilibili.com/video/BV1Z84y1X7eF/)
## License ## License

View File

@ -124,11 +124,11 @@
<phase>generate-resources</phase> <phase>generate-resources</phase>
<configuration> <configuration>
<target> <target>
<move todir="src/main/resources/static"> <copy todir="src/main/resources/static">
<fileset dir="../core-frontend/dist"> <fileset dir="../core-frontend/dist">
<include name="**"/> <include name="**"/>
</fileset> </fileset>
</move> </copy>
</target> </target>
</configuration> </configuration>
<goals> <goals>
@ -137,18 +137,7 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
</plugins> </plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>static/**</include>
</includes>
</resource>
</resources>
</build> </build>
</profile> </profile>
@ -207,25 +196,16 @@
</executions> </executions>
</plugin> </plugin>
</plugins> </plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>static/**</include>
</includes>
</resource>
</resources>
</build> </build>
</profile> </profile>
<!-- 分布式版(企业版/saas版) --> <!-- 分布式版(企业版) -->
<profile> <profile>
<id>distributed</id> <id>distributed</id>
<properties> <properties>
<profiles.active>distributed</profiles.active> <profiles.active>distributed</profiles.active>
</properties> </properties>
<dependencies> <dependencies>
<!-- 分布式版(企业版/saas版) 引入分布式组件 --> <!-- 分布式版(企业版) 引入分布式组件 -->
<dependency> <dependency>
<groupId>io.dataease</groupId> <groupId>io.dataease</groupId>
<artifactId>distributed</artifactId> <artifactId>distributed</artifactId>
@ -239,7 +219,7 @@
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<configuration> <configuration>
<excludes> <excludes>
<!-- 分布式版(企业版/saas版) 需要排除权限替补实现 否则就会出现多个权限实现 报错 --> <!-- 分布式版(企业版) 需要排除权限替补实现 否则就会出现多个权限实现 报错 -->
<exclude>io/dataease/substitute/**</exclude> <exclude>io/dataease/substitute/**</exclude>
</excludes> </excludes>
</configuration> </configuration>
@ -262,16 +242,30 @@
<include>**/*.sql</include> <include>**/*.sql</include>
<include>**/*.xlsx</include> <include>**/*.xlsx</include>
</includes> </includes>
<excludes>
<exclude>static/**/*.*</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>static/**/*.*</include>
</includes>
</resource> </resource>
</resources> </resources>
<!-- springboot打包插件 --> <!-- springboot打包插件 -->
<plugins> <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<!--<configuration>
<mainClass>io.dataease.CoreApplication</mainClass>
</configuration>-->
<executions> <executions>
<execution> <execution>
<goals> <goals>

View File

@ -67,6 +67,8 @@ public class ChartDataManage {
@Resource @Resource
private CorePermissionManage corePermissionManage; private CorePermissionManage corePermissionManage;
public static final String START_END_SEPARATOR = "_START_END_SPLIT";
private static Logger logger = LoggerFactory.getLogger(ChartDataManage.class); private static Logger logger = LoggerFactory.getLogger(ChartDataManage.class);
public ChartViewDTO calcData(ChartViewDTO view) throws Exception { public ChartViewDTO calcData(ChartViewDTO view) throws Exception {
@ -246,7 +248,8 @@ public class ChartDataManage {
List<SqlVariableDetails> sqlVariables = datasetGroupManage.getSqlParams(Arrays.asList(view.getTableId())); List<SqlVariableDetails> sqlVariables = datasetGroupManage.getSqlParams(Arrays.asList(view.getTableId()));
if (CollectionUtil.isNotEmpty(sqlVariables)) { if (CollectionUtil.isNotEmpty(sqlVariables)) {
for (SqlVariableDetails parameter : Optional.ofNullable(request.getParameters()).orElse(new ArrayList<>())) { for (SqlVariableDetails parameter : Optional.ofNullable(request.getParameters()).orElse(new ArrayList<>())) {
if (sqlVariables.stream().map(SqlVariableDetails::getId).collect(Collectors.toList()).contains(parameter.getId())) { String parameterId = StringUtils.endsWith(parameter.getId(), START_END_SEPARATOR) ? parameter.getId().split(START_END_SEPARATOR)[0] : parameter.getId();
if (sqlVariables.stream().map(SqlVariableDetails::getId).collect(Collectors.toList()).contains(parameterId)) {
hasParameters = true; hasParameters = true;
} }
} }

View File

@ -1105,14 +1105,13 @@ public class ChartDataBuild {
desensitizationStr = "*** ***"; desensitizationStr = "*** ***";
break; break;
} }
if (originStr.length() >= columnPermissionItem.getDesensitizationRule().getM() && originStr.length() >= columnPermissionItem.getDesensitizationRule().getN()) { if (columnPermissionItem.getDesensitizationRule().getM() == 1) {
desensitizationStr = StringUtils.substring(originStr, columnPermissionItem.getDesensitizationRule().getM() - 1, columnPermissionItem.getDesensitizationRule().getN()) + "***"; desensitizationStr = StringUtils.substring(originStr, columnPermissionItem.getDesensitizationRule().getM() - 1, columnPermissionItem.getDesensitizationRule().getN()) + "***";
break; break;
} else {
desensitizationStr = "***" + StringUtils.substring(originStr, columnPermissionItem.getDesensitizationRule().getM() - 1, columnPermissionItem.getDesensitizationRule().getN()) + "***";
break;
} }
if (originStr.length() >= columnPermissionItem.getDesensitizationRule().getM() && originStr.length() < columnPermissionItem.getDesensitizationRule().getN()) {
desensitizationStr = StringUtils.substring(originStr, columnPermissionItem.getDesensitizationRule().getM() - 1, originStr.length());
}
break;
default: default:
break; break;

View File

@ -20,6 +20,7 @@ import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static io.dataease.chart.manage.ChartDataManage.START_END_SEPARATOR;
import static org.apache.calcite.sql.SqlKind.*; import static org.apache.calcite.sql.SqlKind.*;
public class SqlparserUtils { public class SqlparserUtils {
@ -166,7 +167,11 @@ public class SqlparserUtils {
return "'" + String.join("','", sqlVariableDetails.getValue()) + "'"; return "'" + String.join("','", sqlVariableDetails.getValue()) + "'";
} else if (sqlVariableDetails.getOperator().equals("between")) { } else if (sqlVariableDetails.getOperator().equals("between")) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(sqlVariableDetails.getType().size() > 1 ? (String) sqlVariableDetails.getType().get(1).replace("DD", "dd") : "YYYY"); SimpleDateFormat simpleDateFormat = new SimpleDateFormat(sqlVariableDetails.getType().size() > 1 ? (String) sqlVariableDetails.getType().get(1).replace("DD", "dd") : "YYYY");
return simpleDateFormat.format(new Date(Long.parseLong((String) sqlVariableDetails.getValue().get(0)))); if (StringUtils.endsWith(sqlVariableDetails.getId(), START_END_SEPARATOR)) {
return simpleDateFormat.format(new Date(Long.parseLong((String) sqlVariableDetails.getValue().get(1))));
} else {
return simpleDateFormat.format(new Date(Long.parseLong((String) sqlVariableDetails.getValue().get(0))));
}
} else { } else {
return (String) sqlVariableDetails.getValue().get(0); return (String) sqlVariableDetails.getValue().get(0);
} }

View File

@ -498,4 +498,26 @@ public class DatasetGroupManage {
geFullName(parent.getPid(), fullName); geFullName(parent.getPid(), fullName);
} }
} }
public List<DatasetTableDTO> getDetailWithPerm(List<Long> ids) {
var result = new ArrayList<DatasetTableDTO>();
if (CollectionUtil.isNotEmpty(ids)) {
var dsList = coreDatasetGroupMapper.selectBatchIds(ids);
if (CollectionUtil.isNotEmpty(dsList)) {
dsList.forEach(ds -> {
DatasetTableDTO dto = new DatasetTableDTO();
BeanUtils.copyBean(dto, ds);
var fields = datasetTableFieldManage.listFieldsWithPermissions(ds.getId());
List<DatasetTableFieldDTO> dimensionList = fields.stream().filter(ele -> StringUtils.equalsIgnoreCase(ele.getGroupType(), "d")).toList();
List<DatasetTableFieldDTO> quotaList = fields.stream().filter(ele -> StringUtils.equalsIgnoreCase(ele.getGroupType(), "q")).toList();
Map<String, List<DatasetTableFieldDTO>> map = new LinkedHashMap<>();
map.put("dimensionList", dimensionList);
map.put("quotaList", quotaList);
dto.setFields(map);
result.add(dto);
});
}
}
return result;
}
} }

View File

@ -1,6 +1,9 @@
package io.dataease.dataset.manage; package io.dataease.dataset.manage;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.dataease.api.chart.dto.ColumnPermissionItem;
import io.dataease.auth.bo.TokenUserBO;
import io.dataease.dataset.dao.auto.entity.CoreDatasetTableField; import io.dataease.dataset.dao.auto.entity.CoreDatasetTableField;
import io.dataease.dataset.dao.auto.mapper.CoreDatasetGroupMapper; import io.dataease.dataset.dao.auto.mapper.CoreDatasetGroupMapper;
import io.dataease.dataset.dao.auto.mapper.CoreDatasetTableFieldMapper; import io.dataease.dataset.dao.auto.mapper.CoreDatasetTableFieldMapper;
@ -9,6 +12,7 @@ import io.dataease.datasource.provider.CalciteProvider;
import io.dataease.dto.dataset.DatasetTableFieldDTO; import io.dataease.dto.dataset.DatasetTableFieldDTO;
import io.dataease.exception.DEException; import io.dataease.exception.DEException;
import io.dataease.i18n.Translator; import io.dataease.i18n.Translator;
import io.dataease.utils.AuthUtils;
import io.dataease.utils.BeanUtils; import io.dataease.utils.BeanUtils;
import io.dataease.utils.IDUtils; import io.dataease.utils.IDUtils;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@ -18,9 +22,7 @@ import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.util.LinkedHashMap; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -187,6 +189,20 @@ public class DatasetTableFieldManage {
return map; return map;
} }
public List<DatasetTableFieldDTO> listFieldsWithPermissions(Long id) {
List<DatasetTableFieldDTO> fields = selectByDatasetGroupId(id);
Map<String, ColumnPermissionItem> desensitizationList = new HashMap<>();
Long userId = AuthUtils.getUser() == null ? null : AuthUtils.getUser().getUserId();
List<DatasetTableFieldDTO> tmp = permissionManage
.filterColumnPermissions(fields, desensitizationList, id, userId)
.stream()
.sorted(Comparator.comparing(DatasetTableFieldDTO::getGroupType))
.toList();
tmp.forEach(ele -> ele.setDesensitized(desensitizationList.containsKey(ele.getDataeaseName())));
return tmp;
}
public List<DatasetTableFieldDTO> transDTO(List<CoreDatasetTableField> list) { public List<DatasetTableFieldDTO> transDTO(List<CoreDatasetTableField> list) {
return list.stream().map(ele -> { return list.stream().map(ele -> {
DatasetTableFieldDTO dto = new DatasetTableFieldDTO(); DatasetTableFieldDTO dto = new DatasetTableFieldDTO();

View File

@ -53,6 +53,11 @@ public class DatasetFieldServer implements DatasetTableApi {
return datasetTableFieldManage.listByDQ(id); return datasetTableFieldManage.listByDQ(id);
} }
@Override
public List<DatasetTableFieldDTO> listFieldsWithPermissions(Long id) {
return datasetTableFieldManage.listFieldsWithPermissions(id);
}
@Override @Override
public List<String> multFieldValuesForPermissions(@RequestBody MultFieldValuesRequest multFieldValuesRequest) throws Exception { public List<String> multFieldValuesForPermissions(@RequestBody MultFieldValuesRequest multFieldValuesRequest) throws Exception {
return datasetDataManage.getFieldEnum(multFieldValuesRequest.getFieldIds()); return datasetDataManage.getFieldEnum(multFieldValuesRequest.getFieldIds());

View File

@ -77,4 +77,10 @@ public class DatasetTreeServer implements DatasetTreeApi {
public List<SqlVariableDetails> getSqlParams(List<Long> ids) throws Exception { public List<SqlVariableDetails> getSqlParams(List<Long> ids) throws Exception {
return datasetGroupManage.getSqlParams(ids); return datasetGroupManage.getSqlParams(ids);
} }
@Override
public List<DatasetTableDTO> detailWithPerm(List<Long> ids) throws Exception {
return datasetGroupManage.getDetailWithPerm(ids);
}
} }

View File

@ -302,6 +302,9 @@ public class ExcelUtils {
sdf.parse(value); sdf.parse(value);
return "DATETIME"; return "DATETIME";
} catch (Exception e1) { } catch (Exception e1) {
if(value.length()> 19){
return "TEXT";
}
try { try {
Double d = Double.valueOf(value); Double d = Double.valueOf(value);
double eps = 1e-10; double eps = 1e-10;
@ -413,9 +416,6 @@ public class ExcelUtils {
} }
List<String[]> data = new ArrayList<>(noModelDataListener.getData()); List<String[]> data = new ArrayList<>(noModelDataListener.getData());
if (isPreview) { if (isPreview) {
if (data.size() > 100) {
data = data.subList(0, 100);
}
for (int i = 0; i < data.size(); i++) { for (int i = 0; i < data.size(); i++) {
for (int j = 0; j < data.get(i).length; j++) { for (int j = 0; j < data.get(i).length; j++) {
if (j < fields.size()) { if (j < fields.size()) {
@ -423,6 +423,9 @@ public class ExcelUtils {
} }
} }
} }
if (data.size() > 100) {
data = data.subList(0, 100);
}
} }
for (int i = 0; i < fields.size(); i++) { for (int i = 0; i < fields.size(); i++) {
@ -469,6 +472,9 @@ public class ExcelUtils {
} }
} }
} }
if (data.size() > 100) {
data = data.subList(0, 100);
}
} }
for (int i = 0; i < fields.size(); i++) { for (int i = 0; i < fields.size(); i++) {
if (StringUtils.isEmpty(fields.get(i).getFieldType())) { if (StringUtils.isEmpty(fields.get(i).getFieldType())) {

View File

@ -87,6 +87,8 @@ public class SQLConstants {
public static final String WHERE_BETWEEN = "'%s' AND '%s'"; public static final String WHERE_BETWEEN = "'%s' AND '%s'";
public static final String WHERE_VALUE_BETWEEN = "%s AND %s";
public static final String BRACKETS = "(%s)"; public static final String BRACKETS = "(%s)";
public static final String ROUND = "ROUND(%s,%s)"; public static final String ROUND = "ROUND(%s,%s)";

View File

@ -67,6 +67,7 @@ public class ExtWhere2Str {
String cast = String.format(SQLConstants.CAST, originName, SQLConstants.DEFAULT_INT_FORMAT); String cast = String.format(SQLConstants.CAST, originName, SQLConstants.DEFAULT_INT_FORMAT);
// 此处获取标准格式的日期 // 此处获取标准格式的日期
whereName = String.format(SQLConstants.FROM_UNIXTIME, cast, date_format); whereName = String.format(SQLConstants.FROM_UNIXTIME, cast, date_format);
whereName = String.format(SQLConstants.UNIX_TIMESTAMP, whereName);
} }
if (field.getDeExtractType() == 1) { if (field.getDeExtractType() == 1) {
// 此处获取标准格式的日期 // 此处获取标准格式的日期
@ -109,7 +110,7 @@ public class ExtWhere2Str {
if (request.getDatasetTableField().getDeExtractType() == 2 if (request.getDatasetTableField().getDeExtractType() == 2
|| request.getDatasetTableField().getDeExtractType() == 3 || request.getDatasetTableField().getDeExtractType() == 3
|| request.getDatasetTableField().getDeExtractType() == 4) { || request.getDatasetTableField().getDeExtractType() == 4) {
whereValue = String.format(SQLConstants.WHERE_BETWEEN, value.get(0), value.get(1)); whereValue = String.format(SQLConstants.WHERE_VALUE_BETWEEN, value.get(0), value.get(1));
} else { } else {
whereName = String.format(SQLConstants.UNIX_TIMESTAMP, whereName); whereName = String.format(SQLConstants.UNIX_TIMESTAMP, whereName);
whereValue = String.format(SQLConstants.WHERE_BETWEEN, Long.parseLong(value.get(0)), Long.parseLong(value.get(1))); whereValue = String.format(SQLConstants.WHERE_BETWEEN, Long.parseLong(value.get(0)), Long.parseLong(value.get(1)));

View File

@ -18,7 +18,7 @@ public abstract class DeScheduleJob implements Job {
this.expression = jobDataMap.getString("expression"); this.expression = jobDataMap.getString("expression");
this.taskId = jobDataMap.getLong("taskId"); this.taskId = jobDataMap.getLong("taskId");
this.updateType = jobDataMap.getString("updateType"); this.updateType = jobDataMap.getString("updateType");
LogUtil.info(jobKey.getGroup() + " Running: " + datasetTableId); LogUtil.info(jobKey.getName() + " Running: " + datasetTableId);
LogUtil.info("CronExpression: " + expression); LogUtil.info("CronExpression: " + expression);
businessExecute(context); businessExecute(context);
} }

View File

@ -1,5 +1,8 @@
package io.dataease.map.manage; package io.dataease.map.manage;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.dataease.api.map.dto.GeometryNodeCreator; import io.dataease.api.map.dto.GeometryNodeCreator;
import io.dataease.api.map.vo.AreaNode; import io.dataease.api.map.vo.AreaNode;
import io.dataease.constant.StaticResourceConstants; import io.dataease.constant.StaticResourceConstants;
@ -29,6 +32,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import static io.dataease.constant.CacheConstant.CommonCacheConstant.WORLD_MAP_CACHE; import static io.dataease.constant.CacheConstant.CommonCacheConstant.WORLD_MAP_CACHE;
@ -107,6 +111,13 @@ public class MapManage {
@CacheEvict(cacheNames = WORLD_MAP_CACHE, key = "'world_map'") @CacheEvict(cacheNames = WORLD_MAP_CACHE, key = "'world_map'")
@Transactional @Transactional
public void saveMapGeo(GeometryNodeCreator request, MultipartFile file) { public void saveMapGeo(GeometryNodeCreator request, MultipartFile file) {
if (ObjectUtils.isEmpty(file) || file.isEmpty()) {
DEException.throwException("geometry file is require");
}
String suffix = FileUtil.getSuffix(file.getOriginalFilename());
if (!StringUtils.equalsIgnoreCase("json", suffix)) {
DEException.throwException("仅支持json格式文件");
}
List<Area> areas = proxy().defaultArea(); List<Area> areas = proxy().defaultArea();
String code = getBusiGeoCode(request.getCode()); String code = getBusiGeoCode(request.getCode());
@ -147,10 +158,30 @@ public class MapManage {
if (!StringUtils.startsWith(code, GEO_PREFIX)) { if (!StringUtils.startsWith(code, GEO_PREFIX)) {
DEException.throwException("内置Geometry禁止删除"); DEException.throwException("内置Geometry禁止删除");
} }
coreAreaCustomMapper.deleteById(code); CoreAreaCustom coreAreaCustom = coreAreaCustomMapper.selectById(code);
File file = buildGeoFile(code); if (ObjectUtils.isEmpty(coreAreaCustom)) {
if (file.exists()) { DEException.throwException("Geometry code 不存在!");
file.delete(); }
List<String> codeResultList = new ArrayList<>();
codeResultList.add(code);
childTreeIdList(ListUtil.of(code), codeResultList);
coreAreaCustomMapper.deleteBatchIds(codeResultList);
codeResultList.forEach(id -> {
File file = buildGeoFile(id);
if (file.exists()) {
file.delete();
}
});
}
public void childTreeIdList(List<String> pidList, List<String> resultList) {
QueryWrapper<CoreAreaCustom> queryWrapper = new QueryWrapper<>();
queryWrapper.in("pid", pidList);
List<CoreAreaCustom> coreAreaCustoms = coreAreaCustomMapper.selectList(queryWrapper);
if (CollectionUtils.isNotEmpty(coreAreaCustoms)) {
List<String> codeList = coreAreaCustoms.stream().map(CoreAreaCustom::getId).toList();
resultList.addAll(codeList);
childTreeIdList(codeList, resultList);
} }
} }

View File

@ -96,6 +96,7 @@ public class MenuManage {
|| coreMenu.getId().equals(21L) || coreMenu.getId().equals(21L)
|| coreMenu.getPid().equals(21L) || coreMenu.getPid().equals(21L)
|| coreMenu.getId().equals(25L) || coreMenu.getId().equals(25L)
|| coreMenu.getId().equals(26L); || coreMenu.getId().equals(26L)
|| coreMenu.getId().equals(35L);
} }
} }

View File

@ -22,12 +22,6 @@ spring:
port: 6379 port: 6379
password: 123456 password: 123456
database: 0 database: 0
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
api-docs:
path: /v3/api-docs
jackson: jackson:
parser: parser:
allow-numeric-leading-zeros: true allow-numeric-leading-zeros: true
@ -52,12 +46,21 @@ quartz:
dataease: dataease:
version: '@project.version@' version: '@project.version@'
origin-list: localhost:8081,127.0.0.1:8081,https://de2.fit2cloud.com,http://localhost:8080
apisix-api: apisix-api:
domain: http://192.168.0.121:9180 domain: http://192.168.0.121:9180
key: edd1c9f034335f136f87ad84b625c8f1 key: edd1c9f034335f136f87ad84b625c8f1
# springdoc-openapi项目配置
springdoc:
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
#operations-sorter: alpha
api-docs:
path: /v3/api-docs
# knife4j的增强配置不需要增强可以不配
knife4j: knife4j:
enable: true enable: true
setting: setting:
language: zh_cn language: zh_cn
enable-swagger-models: false

View File

@ -14,64 +14,78 @@ CREATE TABLE `visualization_template` (
`template_data` longtext COMMENT 'template 数据', `template_data` longtext COMMENT 'template 数据',
`dynamic_data` longtext COMMENT '预存数据', `dynamic_data` longtext COMMENT '预存数据',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
CREATE TABLE `visualization_template`
(
`id` varchar(50) NOT NULL COMMENT '主键',
`name` varchar(255) DEFAULT NULL COMMENT '名称',
`pid` varchar(255) DEFAULT NULL COMMENT '父级id',
`level` int DEFAULT NULL COMMENT '层级',
`dv_type` varchar(255) DEFAULT NULL COMMENT '模板种类 dataV or dashboard 目录或者文件夹',
`node_type` varchar(255) DEFAULT NULL COMMENT '节点类型 folder or panel 目录或者文件夹',
`create_by` varchar(255) DEFAULT NULL COMMENT '创建人',
`create_time` bigint DEFAULT NULL COMMENT '创建时间',
`snapshot` longtext COMMENT '缩略图',
`template_type` varchar(255) DEFAULT NULL COMMENT '模版类型 system 系统内置 self 用户自建 ',
`template_style` longtext COMMENT 'template 样式',
`template_data` longtext COMMENT 'template 数据',
`dynamic_data` longtext COMMENT '预存数据',
PRIMARY KEY (`id`)
); );
-- ---------------------------- -- ----------------------------
-- Table structure for visualization_template_category -- Table structure for visualization_template_category
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `visualization_template_category`; DROP TABLE IF EXISTS `visualization_template_category`;
CREATE TABLE `visualization_template_category` ( CREATE TABLE `visualization_template_category`
`id` varchar(50) NOT NULL COMMENT '主键', (
`name` varchar(255) DEFAULT NULL COMMENT '名称', `id` varchar(50) NOT NULL COMMENT '主键',
`pid` varchar(255) DEFAULT NULL COMMENT '父级id', `name` varchar(255) DEFAULT NULL COMMENT '名称',
`level` int DEFAULT NULL COMMENT '层级', `pid` varchar(255) DEFAULT NULL COMMENT '父级id',
`dv_type` varchar(255) DEFAULT NULL COMMENT '模板种类 dataV or dashboard 目录或者文件夹', `level` int DEFAULT NULL COMMENT '层级',
`node_type` varchar(255) DEFAULT NULL COMMENT '节点类型 folder or panel 目录或者文件夹', `dv_type` varchar(255) DEFAULT NULL COMMENT '模板种类 dataV or dashboard 目录或者文件夹',
`create_by` varchar(255) DEFAULT NULL COMMENT '创建人', `node_type` varchar(255) DEFAULT NULL COMMENT '节点类型 folder or panel 目录或者文件夹',
`create_time` bigint DEFAULT NULL COMMENT '创建时间', `create_by` varchar(255) DEFAULT NULL COMMENT '创建人',
`snapshot` longtext COMMENT '缩略图', `create_time` bigint DEFAULT NULL COMMENT '创建时间',
`template_type` varchar(255) DEFAULT NULL, `snapshot` longtext COMMENT '缩略图',
PRIMARY KEY (`id`) `template_type` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
); );
-- ---------------------------- -- ----------------------------
-- Table structure for visualization_template_category_map -- Table structure for visualization_template_category_map
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `visualization_template_category_map`; DROP TABLE IF EXISTS `visualization_template_category_map`;
CREATE TABLE `visualization_template_category_map` ( CREATE TABLE `visualization_template_category_map`
`id` varchar(50) NOT NULL COMMENT '主键', (
`category_id` varchar(255) DEFAULT NULL COMMENT '名称', `id` varchar(50) NOT NULL COMMENT '主键',
`template_id` varchar(255) DEFAULT NULL COMMENT '父级id', `category_id` varchar(255) DEFAULT NULL COMMENT '名称',
PRIMARY KEY (`id`) `template_id` varchar(255) DEFAULT NULL COMMENT '父级id',
PRIMARY KEY (`id`)
); );
-- ---------------------------- -- ----------------------------
-- Table structure for visualization_template_extend_data -- Table structure for visualization_template_extend_data
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `visualization_template_extend_data`; DROP TABLE IF EXISTS `visualization_template_extend_data`;
CREATE TABLE `visualization_template_extend_data` ( CREATE TABLE `visualization_template_extend_data`
`id` bigint NOT NULL, (
`dv_id` bigint DEFAULT NULL, `id` bigint NOT NULL,
`view_id` bigint DEFAULT NULL, `dv_id` bigint DEFAULT NULL,
`view_details` longtext , `view_id` bigint DEFAULT NULL,
`copy_from` varchar(255) DEFAULT NULL, `view_details` longtext,
`copy_id` varchar(255) DEFAULT NULL, `copy_from` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`) `copy_id` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
); );
BEGIN;
INSERT INTO `core_menu` INSERT INTO `core_menu`
VALUES (19, 0, 2, 'template-market', 'template-market', 4, NULL, '/template-market', 1, 1, 0); VALUES (19, 0, 2, 'template-market', 'template-market', 4, NULL, '/template-market', 1, 1, 0);
INSERT INTO `core_menu` INSERT INTO `core_menu`
VALUES (30, 0, 1, 'toolbox', null, 7, 'icon_template', '/toolbox', 1, 1, 0); VALUES (30, 0, 1, 'toolbox', null, 7, 'icon_template', '/toolbox', 1, 1, 0);
INSERT INTO `core_menu` INSERT INTO `core_menu`
VALUES (31, 30, 2, 'template-setting', 'toolbox/template-setting', 1, 'icon_template', '/template-setting', 0, 1, 1); VALUES (31, 30, 2, 'template-setting', 'toolbox/template-setting', 1, 'icon_template', '/template-setting', 0, 1, 1);
COMMIT;
ALTER TABLE core_opt_recent ADD `resource_name` varchar(255) NULL COMMENT '资源名称';
ALTER TABLE `core_opt_recent`
MODIFY COLUMN `resource_id` bigint NULL COMMENT '资源ID' AFTER `id`,
ADD COLUMN `resource_name` varchar(255) NULL COMMENT '资源名称' AFTER `resource_id`;
DROP TABLE IF EXISTS `core_area_custom`; DROP TABLE IF EXISTS `core_area_custom`;
CREATE TABLE `core_area_custom` CREATE TABLE `core_area_custom`
@ -82,11 +96,11 @@ CREATE TABLE `core_area_custom`
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
); );
BEGIN;
INSERT INTO `core_sys_setting` INSERT INTO `core_sys_setting`
VALUES (1, 'basic.dsIntervalTime', '6', 'text', 2); VALUES (1, 'basic.dsIntervalTime', '6', 'text', 2);
INSERT INTO `core_sys_setting` INSERT INTO `core_sys_setting`
VALUES (2, 'basic.dsExecuteTime', 'minute', 'text', 3); VALUES (2, 'basic.dsExecuteTime', 'minute', 'text', 3);
INSERT INTO `core_sys_setting` (`id`, `pkey`, `pval`, `type`, `sort`) VALUES (7, 'template.url', 'https://templates.dataease.cn', 'text', 0); INSERT INTO `core_sys_setting` (`id`, `pkey`, `pval`, `type`, `sort`)
INSERT INTO `core_sys_setting` (`id`, `pkey`, `pval`, `type`, `sort`) VALUES (8, 'template.accessKey', 'dataease', 'text', 1); VALUES (7, 'template.url', 'https://templates.dataease.cn', 'text', 0);
COMMIT; INSERT INTO `core_sys_setting` (`id`, `pkey`, `pval`, `type`, `sort`)
VALUES (8, 'template.accessKey', 'dataease', 'text', 1);

View File

@ -3748,7 +3748,7 @@ CREATE TABLE QRTZ_JOB_DETAILS
JOB_DATA BLOB NULL, JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME, JOB_NAME, JOB_GROUP) PRIMARY KEY (SCHED_NAME, JOB_NAME, JOB_GROUP)
); );
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE QRTZ_TRIGGERS CREATE TABLE QRTZ_TRIGGERS
( (
SCHED_NAME VARCHAR(120) NOT NULL, SCHED_NAME VARCHAR(120) NOT NULL,
@ -3827,9 +3827,7 @@ CREATE TABLE QRTZ_BLOB_TRIGGERS
PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
CREATE TABLE QRTZ_CALENDARS CREATE TABLE QRTZ_CALENDARS
( (
@ -3896,9 +3894,7 @@ CREATE TABLE `visualization_background`
`base_url` varchar(255) DEFAULT NULL, `base_url` varchar(255) DEFAULT NULL,
`url` varchar(255) DEFAULT NULL, `url` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
INSERT INTO `visualization_background` (`id`, `name`, `classification`, `content`, `remark`, `sort`, `upload_time`, INSERT INTO `visualization_background` (`id`, `name`, `classification`, `content`, `remark`, `sort`, `upload_time`,
`base_url`, `url`) `base_url`, `url`)
@ -3947,11 +3943,7 @@ CREATE TABLE `visualization_background_image`
`base_url` varchar(255) DEFAULT NULL, `base_url` varchar(255) DEFAULT NULL,
`url` varchar(255) DEFAULT NULL, `url` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for visualization_subject -- Table structure for visualization_subject
@ -3959,7 +3951,7 @@ CREATE TABLE `visualization_background_image`
DROP TABLE IF EXISTS `visualization_subject`; DROP TABLE IF EXISTS `visualization_subject`;
CREATE TABLE `visualization_subject` CREATE TABLE `visualization_subject`
( (
`id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `id` varchar(50) NOT NULL,
`name` varchar(255) DEFAULT NULL COMMENT '主题名称', `name` varchar(255) DEFAULT NULL COMMENT '主题名称',
`type` varchar(255) DEFAULT NULL COMMENT '主题类型 system 系统主题self 自定义主题', `type` varchar(255) DEFAULT NULL COMMENT '主题类型 system 系统主题self 自定义主题',
`details` longtext COMMENT '主题内容', `details` longtext COMMENT '主题内容',
@ -3973,11 +3965,7 @@ CREATE TABLE `visualization_subject`
`delete_time` bigint DEFAULT NULL COMMENT '删除时间', `delete_time` bigint DEFAULT NULL COMMENT '删除时间',
`delete_by` bigint DEFAULT NULL COMMENT '删除人', `delete_by` bigint DEFAULT NULL COMMENT '删除人',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
commit; commit;
DROP TABLE IF EXISTS `core_dataset_table_sql_log`; DROP TABLE IF EXISTS `core_dataset_table_sql_log`;
@ -3991,9 +3979,7 @@ CREATE TABLE `core_dataset_table_sql_log`
`sql` longtext NOT NULL COMMENT '详细信息', `sql` longtext NOT NULL COMMENT '详细信息',
`status` varchar(45) DEFAULT NULL COMMENT '状态', `status` varchar(45) DEFAULT NULL COMMENT '状态',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE utf8mb4_0900_ai_ci;
INSERT INTO `visualization_subject` (`id`, `name`, `type`, `details`, `delete_flag`, `cover_url`, `create_num`, INSERT INTO `visualization_subject` (`id`, `name`, `type`, `details`, `delete_flag`, `cover_url`, `create_num`,
@ -4024,9 +4010,7 @@ CREATE TABLE `core_store`
`resource_type` int NOT NULL COMMENT '资源类型', `resource_type` int NOT NULL COMMENT '资源类型',
`time` bigint NOT NULL COMMENT '收藏时间', `time` bigint NOT NULL COMMENT '收藏时间',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for xpack_share -- Table structure for xpack_share
@ -4044,9 +4028,7 @@ CREATE TABLE `xpack_share`
`oid` bigint NOT NULL COMMENT '组织ID', `oid` bigint NOT NULL COMMENT '组织ID',
`type` int NOT NULL COMMENT '业务类型', `type` int NOT NULL COMMENT '业务类型',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for xpack_setting_authentication -- Table structure for xpack_setting_authentication
@ -4061,25 +4043,8 @@ CREATE TABLE `xpack_setting_authentication`
`sync_time` bigint NOT NULL COMMENT '同步时间', `sync_time` bigint NOT NULL COMMENT '同步时间',
`relational_ids` varchar(255) DEFAULT NULL COMMENT '相关的ID', `relational_ids` varchar(255) DEFAULT NULL COMMENT '相关的ID',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
/*
Navicat Premium Data Transfer
Source Server : de2-qa-123.56.90.236
Source Server Type : MySQL
Source Server Version : 80100
Source Host : 123.56.90.236:3306
Source Schema : dataease
Target Server Type : MySQL
Target Server Version : 80100
File Encoding : 65001
Date: 22/09/2023 00:30:08
*/
SET NAMES utf8mb4; SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0; SET FOREIGN_KEY_CHECKS = 0;
@ -4093,14 +4058,12 @@ CREATE TABLE `visualization_link_jump`
`id` bigint NOT NULL, `id` bigint NOT NULL,
`source_dv_id` bigint DEFAULT NULL COMMENT '源仪表板ID', `source_dv_id` bigint DEFAULT NULL COMMENT '源仪表板ID',
`source_view_id` bigint DEFAULT NULL COMMENT '源视图ID', `source_view_id` bigint DEFAULT NULL COMMENT '源视图ID',
`link_jump_info` varchar(4000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '跳转信息', `link_jump_info` varchar(4000) DEFAULT NULL COMMENT '跳转信息',
`checked` tinyint(1) DEFAULT NULL COMMENT '是否启用', `checked` tinyint(1) DEFAULT NULL COMMENT '是否启用',
`copy_from` bigint DEFAULT NULL, `copy_from` bigint DEFAULT NULL,
`copy_id` bigint DEFAULT NULL, `copy_id` bigint DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for visualization_link_jump_info -- Table structure for visualization_link_jump_info
@ -4110,19 +4073,17 @@ CREATE TABLE `visualization_link_jump_info`
( (
`id` bigint NOT NULL, `id` bigint NOT NULL,
`link_jump_id` bigint DEFAULT NULL COMMENT 'link jump ID', `link_jump_id` bigint DEFAULT NULL COMMENT 'link jump ID',
`link_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '关联类型 inner 内部仪表板outer 外部链接', `link_type` varchar(255) DEFAULT NULL COMMENT '关联类型 inner 内部仪表板outer 外部链接',
`jump_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '跳转类型 _blank 新开页面 _self 当前窗口', `jump_type` varchar(255) DEFAULT NULL COMMENT '跳转类型 _blank 新开页面 _self 当前窗口',
`target_dv_id` bigint DEFAULT NULL COMMENT '关联仪表板ID', `target_dv_id` bigint DEFAULT NULL COMMENT '关联仪表板ID',
`source_field_id` bigint DEFAULT NULL COMMENT '字段ID', `source_field_id` bigint DEFAULT NULL COMMENT '字段ID',
`content` varchar(4000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '内容 linkType = outer时使用', `content` varchar(4000) DEFAULT NULL COMMENT '内容 linkType = outer时使用',
`checked` tinyint(1) DEFAULT NULL COMMENT '是否可用', `checked` tinyint(1) DEFAULT NULL COMMENT '是否可用',
`attach_params` tinyint(1) DEFAULT NULL COMMENT '是否附加点击参数', `attach_params` tinyint(1) DEFAULT NULL COMMENT '是否附加点击参数',
`copy_from` bigint DEFAULT NULL, `copy_from` bigint DEFAULT NULL,
`copy_id` bigint DEFAULT NULL, `copy_id` bigint DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for visualization_link_jump_target_view_info -- Table structure for visualization_link_jump_target_view_info
@ -4138,9 +4099,7 @@ CREATE TABLE `visualization_link_jump_target_view_info`
`copy_from` bigint DEFAULT NULL, `copy_from` bigint DEFAULT NULL,
`copy_id` bigint DEFAULT NULL, `copy_id` bigint DEFAULT NULL,
PRIMARY KEY (`target_id`) USING BTREE PRIMARY KEY (`target_id`) USING BTREE
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for visualization_linkage -- Table structure for visualization_linkage
@ -4160,9 +4119,7 @@ CREATE TABLE `visualization_linkage`
`copy_from` bigint DEFAULT NULL, `copy_from` bigint DEFAULT NULL,
`copy_id` bigint DEFAULT NULL, `copy_id` bigint DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for visualization_linkage_field -- Table structure for visualization_linkage_field
@ -4178,16 +4135,11 @@ CREATE TABLE `visualization_linkage_field`
`copy_from` bigint DEFAULT NULL, `copy_from` bigint DEFAULT NULL,
`copy_id` bigint DEFAULT NULL, `copy_id` bigint DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
SET FOREIGN_KEY_CHECKS = 1;
ALTER TABLE `core_datasource` ALTER TABLE `core_datasource`
ADD COLUMN `update_by` bigint NULL COMMENT '变更人' AFTER `update_time`; ADD COLUMN `update_by` bigint NULL COMMENT '变更人' AFTER `update_time`;
DROP TABLE IF EXISTS `core_ds_finish_page`; DROP TABLE IF EXISTS `core_ds_finish_page`;
CREATE TABLE `core_ds_finish_page` CREATE TABLE `core_ds_finish_page`
( (
@ -4205,9 +4157,7 @@ CREATE TABLE `core_opt_recent`
`opt_type` int DEFAULT NULL COMMENT '1 新建 2 修改', `opt_type` int DEFAULT NULL COMMENT '1 新建 2 修改',
`time` bigint NOT NULL COMMENT '收藏时间', `time` bigint NOT NULL COMMENT '收藏时间',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for core_sys_setting -- Table structure for core_sys_setting
@ -4221,6 +4171,4 @@ CREATE TABLE `core_sys_setting`
`type` varchar(255) NOT NULL COMMENT '类型', `type` varchar(255) NOT NULL COMMENT '类型',
`sort` int NOT NULL DEFAULT '0' COMMENT '顺序', `sort` int NOT NULL DEFAULT '0' COMMENT '顺序',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE = InnoDB );
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;

View File

@ -14,7 +14,7 @@ CREATE TABLE `visualization_template` (
`template_data` longtext COMMENT 'template 数据', `template_data` longtext COMMENT 'template 数据',
`dynamic_data` longtext COMMENT '预存数据', `dynamic_data` longtext COMMENT '预存数据',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='模板表'; ) COMMENT='模板表';
-- ---------------------------- -- ----------------------------
-- Table structure for visualization_template_category -- Table structure for visualization_template_category
@ -32,7 +32,7 @@ CREATE TABLE `visualization_template_category` (
`snapshot` longtext COMMENT '缩略图', `snapshot` longtext COMMENT '缩略图',
`template_type` varchar(255) DEFAULT NULL, `template_type` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='模板表'; ) COMMENT='模板表';
-- ---------------------------- -- ----------------------------
-- Table structure for visualization_template_category_map -- Table structure for visualization_template_category_map
@ -43,7 +43,7 @@ CREATE TABLE `visualization_template_category_map` (
`category_id` varchar(255) DEFAULT NULL COMMENT '名称', `category_id` varchar(255) DEFAULT NULL COMMENT '名称',
`template_id` varchar(255) DEFAULT NULL COMMENT '父级id', `template_id` varchar(255) DEFAULT NULL COMMENT '父级id',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='模板表'; ) COMMENT='模板表';
-- ---------------------------- -- ----------------------------
-- Table structure for visualization_template_extend_data -- Table structure for visualization_template_extend_data
@ -57,7 +57,7 @@ CREATE TABLE `visualization_template_extend_data` (
`copy_from` varchar(255) DEFAULT NULL, `copy_from` varchar(255) DEFAULT NULL,
`copy_id` varchar(255) DEFAULT NULL, `copy_id` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; );
BEGIN; BEGIN;
INSERT INTO `core_menu` INSERT INTO `core_menu`

View File

@ -10,26 +10,6 @@
<persistence directory="/opt/dataease2.0/cache" /> <persistence directory="/opt/dataease2.0/cache" />
<!--<cache alias="AlertsConfig" uses-template="heap-cache"/>
<cache alias="Alerts" uses-template="alerts-template"/>
<cache-template name="heap-cache">
<resources>
<heap unit="entries">1</heap>
<offheap unit="MB">1</offheap>
<disk persistent="true" unit="MB">100</disk>
</resources>
</cache-template>
<cache-template name="alerts-template">
<resources>
<heap unit="entries">1</heap>
<offheap unit="MB">1</offheap>
<disk persistent="true" unit="MB">100</disk>
</resources>
</cache-template>-->
<cache-template name="common-cache"> <cache-template name="common-cache">
<expiry> <expiry>
<none/> <none/>
@ -138,14 +118,6 @@
<cache alias="core_menu_cache" uses-template="common-cache"> <cache alias="core_menu_cache" uses-template="common-cache">
<key-type>java.lang.String</key-type> <key-type>java.lang.String</key-type>
<value-type>java.util.List</value-type> <value-type>java.util.List</value-type>
<!--<expiry>
<none/>
</expiry>
<resources>
<heap unit="entries">20</heap>
<offheap unit="MB">2</offheap>
<disk unit="MB" persistent="true">5</disk>
</resources>-->
</cache> </cache>
</config> </config>

View File

@ -21,6 +21,7 @@ export function pathResolve(dir: string) {
return resolve(root, '.', dir) return resolve(root, '.', dir)
} }
export default { export default {
base: './',
plugins: [ plugins: [
Vue(), Vue(),
VueJsx(), VueJsx(),

View File

@ -2,18 +2,12 @@ export default {
server: { server: {
proxy: { proxy: {
'/api/f': { '/api/f': {
// target: 'http://192.168.31.38:8100',
target: 'http://localhost:8100', target: 'http://localhost:8100',
changeOrigin: true, changeOrigin: true,
rewrite: path => path.replace(/^\/api\/f/, '') rewrite: path => path.replace(/^\/api\/f/, '')
}, },
// 使用 proxy 实例 // 使用 proxy 实例
'/api': { '/api': {
// target: 'http://qa-de2.fit2cloud.com',
// target: 'http://192.168.31.74:8100',
// target: 'https://de2.fit2cloud.com',
// target: 'http://localhost:8100',
// target: 'http://192.168.0.121:9080',
target: 'http://localhost:8100', target: 'http://localhost:8100',
changeOrigin: true, changeOrigin: true,
rewrite: path => path.replace(/^\/api/, 'de2api') rewrite: path => path.replace(/^\/api/, 'de2api')

View File

@ -15,6 +15,7 @@ export interface Field {
extField: number extField: number
checked: boolean checked: boolean
fieldShortName: string fieldShortName: string
desensitized: boolean
} }
export interface ComponentInfo { export interface ComponentInfo {

View File

@ -154,6 +154,11 @@ export const getDsDetails = async (data): Promise<DatasetDetail[]> => {
return res?.data return res?.data
}) })
} }
export const getDsDetailsWithPerm = async (data): Promise<DatasetDetail[]> => {
return request.post({ url: '/datasetTree/detailWithPerm', data }).then(res => {
return res?.data
})
}
export const getSqlParams = async (data): Promise<ParamsDetail[]> => { export const getSqlParams = async (data): Promise<ParamsDetail[]> => {
return request.post({ url: '/datasetTree/getSqlParams', data }).then(res => { return request.post({ url: '/datasetTree/getSqlParams', data }).then(res => {
return res?.data return res?.data
@ -175,6 +180,10 @@ export const multFieldValuesForPermissions = (data = {}) => {
return request.post({ url: '/datasetField/multFieldValuesForPermissions', data }) return request.post({ url: '/datasetField/multFieldValuesForPermissions', data })
} }
export const listFieldsWithPermissions = (datasetId: number) => {
return request.get({ url: '/datasetField/listWithPermissions/' + datasetId })
}
export const saveRowPermission = (data = {}) => { export const saveRowPermission = (data = {}) => {
return request.post({ url: '/dataset/rowPermissions/save', data }) return request.post({ url: '/dataset/rowPermissions/save', data })
} }

View File

@ -0,0 +1,6 @@
@font-face {
font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
src: url('AlibabaPuHuiTi-3-55-RegularL3.woff2') format('woff2');
font-weight: normal;
font-style: normal;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 880 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 KiB

View File

@ -1,4 +1,4 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.59845 0 3.57025 0H14.4298C16.4015 0 18 1.34315 18 3V15C18 16.6569 16.4015 18 14.4298 18H3.57025C1.59845 18 0 16.6569 0 15V3Z" fill="#3370FF"/> <path d="M0 3C0 1.34315 1.59845 0 3.57025 0H14.4298C16.4015 0 18 1.34315 18 3V15C18 16.6569 16.4015 18 14.4298 18H3.57025C1.59845 18 0 16.6569 0 15V3Z" fill="#00d6b9"/>
<path d="M13.25 4.5C13.3826 4.5 13.5098 4.55268 13.6036 4.64645C13.6973 4.74021 13.75 4.86739 13.75 5V11C13.75 11.1326 13.6973 11.2598 13.6036 11.3536C13.5098 11.4473 13.3826 11.5 13.25 11.5H10.0337L11.5822 12.8762L10.9177 13.6237L9 11.9187L7.08225 13.6237L6.41775 12.8762L7.966 11.5H4.75C4.61739 11.5 4.49021 11.4473 4.39645 11.3536C4.30268 11.2598 4.25 11.1326 4.25 11V5C4.25 4.86739 4.30268 4.74021 4.39645 4.64645C4.49021 4.55268 4.61739 4.5 4.75 4.5H13.25ZM12.75 5.5H5.25V10.5H12.75V5.5ZM10.7192 6.3965L11.4262 7.1035L9.05875 9.471L7.90425 8.31675L7.1035 9.11775L6.3965 8.4105L7.90425 6.90275L9.0585 8.057L10.7192 6.3965Z" fill="white"/> <path d="M13.25 4.5C13.3826 4.5 13.5098 4.55268 13.6036 4.64645C13.6973 4.74021 13.75 4.86739 13.75 5V11C13.75 11.1326 13.6973 11.2598 13.6036 11.3536C13.5098 11.4473 13.3826 11.5 13.25 11.5H10.0337L11.5822 12.8762L10.9177 13.6237L9 11.9187L7.08225 13.6237L6.41775 12.8762L7.966 11.5H4.75C4.61739 11.5 4.49021 11.4473 4.39645 11.3536C4.30268 11.2598 4.25 11.1326 4.25 11V5C4.25 4.86739 4.30268 4.74021 4.39645 4.64645C4.49021 4.55268 4.61739 4.5 4.75 4.5H13.25ZM12.75 5.5H5.25V10.5H12.75V5.5ZM10.7192 6.3965L11.4262 7.1035L9.05875 9.471L7.90425 8.31675L7.1035 9.11775L6.3965 8.4105L7.90425 6.90275L9.0585 8.057L10.7192 6.3965Z" fill="white"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 915 B

After

Width:  |  Height:  |  Size: 915 B

View File

@ -1,6 +1,6 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_181_24877)"> <g clip-path="url(#clip0_181_24877)">
<path d="M0 4C0 1.79086 2.13127 0 4.76033 0H19.2397C21.8687 0 24 1.79086 24 4V20C24 22.2091 21.8687 24 19.2397 24H4.76033C2.13127 24 0 22.2091 0 20V4Z" fill="#3370FF"/> <path d="M0 4C0 1.79086 2.13127 0 4.76033 0H19.2397C21.8687 0 24 1.79086 24 4V20C24 22.2091 21.8687 24 19.2397 24H4.76033C2.13127 24 0 22.2091 0 20V4Z" fill="#16c0ff"/>
<path d="M4.66669 9.09589C4.66669 8.83447 4.81949 8.59716 5.05749 8.48898L11.7242 5.45868C11.8994 5.37901 12.1006 5.37901 12.2759 5.45868L18.9426 8.48898C19.1806 8.59716 19.3334 8.83447 19.3334 9.0959V15.5879C19.3334 15.8404 19.1907 16.0713 18.9648 16.1842L12.2982 19.5175C12.1105 19.6114 11.8896 19.6114 11.7019 19.5175L5.03521 16.1842C4.80936 16.0713 4.66669 15.8404 4.66669 15.5879V9.09589ZM16.8119 8.98512L12 6.7979L7.16215 8.99693L11.9733 11.0694L16.8119 8.98512ZM12.6667 12.2225V17.8426L18 15.1759V9.9251L12.6667 12.2225ZM6.00002 9.9481V15.1759L11.3334 17.8426V12.2455L6.00002 9.9481Z" fill="white"/> <path d="M4.66669 9.09589C4.66669 8.83447 4.81949 8.59716 5.05749 8.48898L11.7242 5.45868C11.8994 5.37901 12.1006 5.37901 12.2759 5.45868L18.9426 8.48898C19.1806 8.59716 19.3334 8.83447 19.3334 9.0959V15.5879C19.3334 15.8404 19.1907 16.0713 18.9648 16.1842L12.2982 19.5175C12.1105 19.6114 11.8896 19.6114 11.7019 19.5175L5.03521 16.1842C4.80936 16.0713 4.66669 15.8404 4.66669 15.5879V9.09589ZM16.8119 8.98512L12 6.7979L7.16215 8.99693L11.9733 11.0694L16.8119 8.98512ZM12.6667 12.2225V17.8426L18 15.1759V9.9251L12.6667 12.2225ZM6.00002 9.9481V15.1759L11.3334 17.8426V12.2455L6.00002 9.9481Z" fill="white"/>
</g> </g>
<defs> <defs>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -187,7 +187,7 @@ const resetCustomColor = () => {
.custom-title { .custom-title {
justify-content: space-between; justify-content: space-between;
color: #646a73; color: #646a73;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 12px; font-size: 12px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;

View File

@ -90,7 +90,7 @@ const handleCheckAllChange = (val: CheckboxValueType) => {
.title, .title,
.ed-checkbox { .ed-checkbox {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
padding: 5px 0; padding: 5px 0;

View File

@ -411,7 +411,6 @@ onMounted(() => {
> >
<tabs-group themes="light" :dv-model="dvModel"></tabs-group> <tabs-group themes="light" :dv-model="dvModel"></tabs-group>
</component-group> </component-group>
<!-- <component-button :show-split-line="true" icon-name="dv-tab" title="Tab"></component-button>-->
<component-button-label <component-button-label
icon-name="icon_copy_filled" icon-name="icon_copy_filled"
title="复用" title="复用"

View File

@ -57,7 +57,7 @@ defineExpose({
> :nth-child(1) { > :nth-child(1) {
color: var(--deTextSecondary, #1f2329); color: var(--deTextSecondary, #1f2329);
font-family: 'PingFang SC'; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;
@ -71,7 +71,7 @@ defineExpose({
.item, .item,
.more { .more {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
white-space: nowrap; white-space: nowrap;
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;

View File

@ -1,8 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
import { ElSelect, ElPopover, ElOption, ElIcon } from 'element-plus-secondary' import { ElSelect, ElOption } from 'element-plus-secondary'
import { computed, reactive, nextTick, ref } from 'vue' import { computed, reactive } from 'vue'
import { Icon } from '@/components/icon-custom'
const props = defineProps({ const props = defineProps({
optionList: propTypes.arrayOf( optionList: propTypes.arrayOf(
@ -15,28 +14,19 @@ const props = defineProps({
}) })
const state = reactive({ const state = reactive({
currentStatus: [],
activeStatus: [] activeStatus: []
}) })
const emits = defineEmits(['filter-change'])
const elPopoverU = ref(null)
const more = ref(null)
const statusChange = (id: string | number) => {
state.activeStatus = state.activeStatus.filter(ele => ele.id !== id)
}
const selectStatus = ids => { const selectStatus = ids => {
const [item] = ids emits(
state.activeStatus.push(item) 'filter-change',
state.currentStatus = [] ids.map(item => item.label)
nextTick(() => { )
elPopoverU.value?.hide()
more.value?.click()
})
} }
const optionListNotSelect = computed(() => { const optionListNotSelect = computed(() => {
return props.optionList.filter(ele => !state.activeStatus.map(t => t.id).includes(ele.id)) return [...props.optionList]
}) })
const clear = () => { const clear = () => {
state.activeStatus = [] state.activeStatus = []
@ -50,48 +40,22 @@ defineExpose({
<div class="filter"> <div class="filter">
<span>{{ title }}</span> <span>{{ title }}</span>
<div class="filter-item"> <div class="filter-item">
<span <el-select
v-for="ele in state.activeStatus" :teleported="false"
:key="ele.id" style="width: 100%"
class="item active" v-model="state.activeStatus"
@click="statusChange(ele.id)" value-key="id"
>{{ $t(ele.name) }}</span filterable
multiple
@change="selectStatus"
> >
<slot v-if="!!optionListNotSelect.length"> <el-option
<el-popover v-for="item in optionListNotSelect"
:show-arrow="false" :key="item.name"
ref="elPopoverU" :label="item.name"
placement="bottom" :value="item"
popper-class="filter-popper" />
width="200" </el-select>
trigger="click"
>
<el-select
:teleported="false"
style="width: 100%"
v-model="state.currentStatus"
value-key="id"
filterable
multiple
@change="selectStatus"
>
<el-option
v-for="item in optionListNotSelect"
:key="item.name"
:label="item.name"
:value="item"
/>
</el-select>
<template #reference>
<span ref="more" class="more">
<el-icon>
<Icon name="icon_add_outlined"> </Icon>
</el-icon>
更多
</span>
</template>
</el-popover>
</slot>
</div> </div>
</div> </div>
</template> </template>
@ -102,7 +66,7 @@ defineExpose({
> :nth-child(1) { > :nth-child(1) {
color: var(--deTextSecondary, #1f2329); color: var(--deTextSecondary, #1f2329);
font-family: 'PingFang SC'; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;
@ -113,45 +77,6 @@ defineExpose({
.filter-item { .filter-item {
flex: 1; flex: 1;
.item,
.more {
font-family: PingFang SC;
white-space: nowrap;
font-size: 14px;
font-weight: 400;
line-height: 24px;
margin-right: 12px;
text-align: center;
padding: 1px 6px;
background: var(--deTextPrimary5, #f5f6f7);
color: var(--deTextPrimary, #1f2329);
border-radius: 2px;
cursor: pointer;
display: inline-block;
margin-bottom: 12px;
}
.active,
.more:hover {
background: var(--primary10, rgba(51, 112, 255, 0.1));
color: var(--primaryselect, #0c296e);
}
.more {
white-space: nowrap;
display: inline-flex;
align-items: center;
i {
margin-right: 5px;
}
}
} }
} }
</style> </style>
<style lang="less">
.filter-popper {
padding: 0 !important;
background: #fff !important;
}
</style>

View File

@ -100,7 +100,7 @@ defineExpose({
> :nth-child(1) { > :nth-child(1) {
color: var(--deTextSecondary, #1f2329); color: var(--deTextSecondary, #1f2329);
font-family: 'PingFang SC'; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;
@ -114,7 +114,7 @@ defineExpose({
.item, .item,
.more { .more {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
white-space: nowrap; white-space: nowrap;
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;

View File

@ -1,8 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
import { ElTreeSelect, ElPopover, ElIcon } from 'element-plus-secondary' import { ElTreeSelect } from 'element-plus-secondary'
import { computed, reactive, ref, watch } from 'vue' import { computed, reactive, ref } from 'vue'
import { Icon } from '@/components/icon-custom'
const props = defineProps({ const props = defineProps({
optionList: propTypes.arrayOf( optionList: propTypes.arrayOf(
@ -21,18 +20,8 @@ const state = reactive({
activeStatus: [] activeStatus: []
}) })
const elPopoverU = ref(null) const emits = defineEmits(['filter-change'])
const more = ref(null) const filterTree = ref()
const filterTree = ref(null)
const statusChange = (value: string | number) => {
state.activeStatus = state.activeStatus.filter(ele => ele?.value !== value)
state.currentStatus = state.currentStatus.filter(val => val !== value)
emits(
'filter-change',
state.activeStatus.map(item => item.value)
)
}
const treeChange = () => { const treeChange = () => {
const nodes = state.currentStatus.map(id => { const nodes = state.currentStatus.map(id => {
return filterTree.value?.getNode(id).data return filterTree.value?.getNode(id).data
@ -43,23 +32,12 @@ const treeChange = () => {
state.activeStatus.map(item => item.value) state.activeStatus.map(item => item.value)
) )
} }
watch(
() => state.currentStatus,
() => {
treeChange()
},
{ deep: true, immediate: true }
)
const optionListNotSelect = computed(() => { const optionListNotSelect = computed(() => {
return [...props.optionList] return [...props.optionList]
}) })
const clear = () => { const clear = () => {
state.activeStatus = []
state.currentStatus = [] state.currentStatus = []
} }
const emits = defineEmits(['filter-change'])
defineExpose({ defineExpose({
clear clear
}) })
@ -69,46 +47,21 @@ defineExpose({
<div class="filter"> <div class="filter">
<span>{{ title }}</span> <span>{{ title }}</span>
<div class="filter-item"> <div class="filter-item">
<span <el-tree-select
v-for="ele in state.activeStatus" node-key="value"
:key="ele.value" ref="filterTree"
class="item active" :teleported="false"
@click="statusChange(ele.value)" style="width: 100%"
>{{ $t(ele.label) }}</span @change="treeChange"
> v-model="state.currentStatus"
<slot v-if="!!optionListNotSelect.length"> :data="optionListNotSelect"
<el-popover :highlight-current="true"
:show-arrow="false" multiple
ref="elPopoverU" :render-after-expand="false"
placement="bottom" :placeholder="$t('common.please_select') + $t('user.role')"
popper-class="filter-popper" show-checkbox
width="200" check-on-click-node
trigger="click" />
>
<el-tree-select
ref="filterTree"
node-key="value"
:teleported="false"
style="width: 100%"
v-model="state.currentStatus"
:data="optionListNotSelect"
:highlight-current="true"
multiple
:render-after-expand="false"
:placeholder="$t('common.please_select') + $t('user.role')"
show-checkbox
check-on-click-node
/>
<template #reference>
<span ref="more" class="more">
<el-icon>
<Icon name="icon_add_outlined"> </Icon>
</el-icon>
更多
</span>
</template>
</el-popover>
</slot>
</div> </div>
</div> </div>
</template> </template>
@ -119,7 +72,7 @@ defineExpose({
> :nth-child(1) { > :nth-child(1) {
color: var(--deTextSecondary, #1f2329); color: var(--deTextSecondary, #1f2329);
font-family: 'PingFang SC'; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;
@ -130,45 +83,6 @@ defineExpose({
.filter-item { .filter-item {
flex: 1; flex: 1;
.item,
.more {
font-family: PingFang SC;
white-space: nowrap;
font-size: 14px;
font-weight: 400;
line-height: 24px;
margin-right: 12px;
text-align: center;
padding: 1px 6px;
background: var(--deTextPrimary5, #f5f6f7);
color: var(--deTextPrimary, #1f2329);
border-radius: 2px;
cursor: pointer;
display: inline-block;
margin-bottom: 12px;
}
.active,
.more:hover {
background: var(--primary10, rgba(51, 112, 255, 0.1));
color: var(--primaryselect, #0c296e);
}
.more {
white-space: nowrap;
display: inline-flex;
align-items: center;
i {
margin-right: 5px;
}
}
} }
} }
</style> </style>
<style lang="less">
.filter-popper {
padding: 0 !important;
background: #fff !important;
}
</style>

View File

@ -55,7 +55,7 @@ const getAssetsFile = {
color: var(--N600, #646a73); color: var(--N600, #646a73);
text-align: center; text-align: center;
/* 正文-字号 14行高 22字重适中Regular用于列表Feed会话 */ /* 正文-字号 14行高 22字重适中Regular用于列表Feed会话 */
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;

View File

@ -71,7 +71,7 @@ watch(
display: flex; display: flex;
align-items: center; align-items: center;
margin: 17px 0; margin: 17px 0;
font-family: 'PingFang SC'; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-weight: 400; font-weight: 400;
.sum { .sum {

View File

@ -859,7 +859,7 @@ defineExpose({
color: var(--neutral-900, #1f2329); color: var(--neutral-900, #1f2329);
/* 中文/桌面端/正文 14 22 Regular */ /* 中文/桌面端/正文 14 22 Regular */
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;

View File

@ -103,10 +103,6 @@ const downloadViewDetails = () => {
const chart = { ...viewInfo.value, chartExtRequest, data: viewDataInfo } const chart = { ...viewInfo.value, chartExtRequest, data: viewDataInfo }
exportExcelDownload(chart) exportExcelDownload(chart)
} }
//
// const htmlToImage = () => {
// downloadCanvas('img', viewContainer.value, viewInfo.value.title)
// }
const htmlToImage = () => { const htmlToImage = () => {
toPng(viewContainer.value) toPng(viewContainer.value)

View File

@ -266,7 +266,7 @@ defineExpose({
<style lang="less"> <style lang="less">
.jump-linkage { .jump-linkage {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
.chart-dataset-name { .chart-dataset-name {

View File

@ -35,6 +35,10 @@ const cacheRequest = cb => {
} }
export const configHandler = config => { export const configHandler = config => {
const desktop = wsCache.get('app.desktop')
if (desktop) {
return config
}
if (wsCache.get('user.token')) { if (wsCache.get('user.token')) {
config.headers['X-DE-TOKEN'] = wsCache.get('user.token') config.headers['X-DE-TOKEN'] = wsCache.get('user.token')
const expired = isExpired() const expired = isExpired()

View File

@ -1,8 +1,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import eventBus from '@/utils/eventBus' import eventBus from '@/utils/eventBus'
import { ElMessage } from 'element-plus-secondary'
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot' import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
import QueryConditionConfiguration from './QueryConditionConfiguration.vue' import QueryConditionConfiguration from './QueryConditionConfiguration.vue'
import type { ComponentInfo } from '@/api/chart' import type { ComponentInfo } from '@/api/chart'
import { infoFormat } from './options'
import { import {
onBeforeUnmount, onBeforeUnmount,
reactive, reactive,
@ -15,7 +17,6 @@ import {
} from 'vue' } from 'vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { guid } from '@/views/visualized/data/dataset/form/util.js'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { comInfo } from './com-info' import { comInfo } from './com-info'
import { useEmitt } from '@/hooks/web/useEmitt' import { useEmitt } from '@/hooks/web/useEmitt'
@ -191,48 +192,6 @@ const dragover = () => {
// do // do
} }
const infoFormat = (obj: ComponentInfo) => {
const { id, name, deType, type, datasetId } = obj
return {
id: guid(),
name,
showError: true,
timeGranularity: 'date',
timeGranularityMultiple: 'datetimerange',
field: {
id,
type,
name,
deType
},
timeType: 'fixed',
relativeToCurrent: 'custom',
timeNum: 0,
relativeToCurrentType: 'year',
around: 'f',
arbitraryTime: new Date(),
auto: false,
defaultValue: undefined,
selectValue: undefined,
optionValueSource: 0,
valueSource: [],
dataset: {
id: datasetId,
name: '',
fields: []
},
visible: true,
defaultValueCheck: false,
multiple: false,
displayType: '0',
checkedFields: [],
parameters: [],
parametersCheck: false,
parametersList: [],
checkedFieldsMap: {}
}
}
const drop = e => { const drop = e => {
const componentInfo: ComponentInfo = JSON.parse(e.dataTransfer.getData('dimension') || '{}') const componentInfo: ComponentInfo = JSON.parse(e.dataTransfer.getData('dimension') || '{}')
if (!componentInfo.id) return if (!componentInfo.id) return
@ -260,34 +219,9 @@ const editeQueryConfig = (queryId: string) => {
queryConfig.value.setCondition(queryId) queryConfig.value.setCondition(queryId)
} }
const addQueryCriteria = () => {
const componentInfo: ComponentInfo = {
id: '',
name: '未命名',
deType: 0,
type: 'VARCHAR',
datasetId: ''
}
list.value.push(infoFormat(componentInfo))
element.value.propValue = [...list.value]
snapshotStore.recordSnapshotCache()
editeQueryConfig(list.value[list.value.length - 1].id)
}
const addQueryCriteriaConfig = () => {
const componentInfo: ComponentInfo = {
id: '',
name: '未命名',
deType: 0,
type: 'VARCHAR',
datasetId: ''
}
return infoFormat(componentInfo)
}
const editQueryCriteria = () => { const editQueryCriteria = () => {
if (!list.value.length) { if (!list.value.length) {
addQueryCriteria() addCriteriaConfigOut()
return return
} }
editeQueryConfig(list.value[0].id) editeQueryConfig(list.value[0].id)
@ -333,12 +267,21 @@ const listVisible = computed(() => {
return list.value.filter(itx => itx.visible) return list.value.filter(itx => itx.visible)
}) })
const addCriteriaConfig = () => {
queryConfig.value.setConditionInit(queryConfig.value.addCriteriaConfig())
}
const queryData = () => { const queryData = () => {
let requiredName = ''
const emitterList = (element.value.propValue || []).reduce((pre, next) => { const emitterList = (element.value.propValue || []).reduce((pre, next) => {
if (next.required) {
if (!next.defaultValueCheck) {
requiredName = next.name
}
if (
(Array.isArray(next.selectValue) && !next.selectValue.length) ||
(next.selectValue !== 0 && !next.selectValue)
) {
requiredName = next.name
}
}
const keyList = Object.entries(next.checkedFieldsMap) const keyList = Object.entries(next.checkedFieldsMap)
.filter(ele => next.checkedFields.includes(ele[0])) .filter(ele => next.checkedFields.includes(ele[0]))
.filter(ele => !!ele[1]) .filter(ele => !!ele[1])
@ -346,6 +289,10 @@ const queryData = () => {
pre = [...new Set([...keyList, ...pre])] pre = [...new Set([...keyList, ...pre])]
return pre return pre
}, []) }, [])
if (!!requiredName) {
ElMessage.error(`${requiredName}】查询条件是必填项,请设置选项值后,再进行查询!`)
return
}
if (!emitterList.length) return if (!emitterList.length) return
emitterList.forEach(ele => { emitterList.forEach(ele => {
@ -390,7 +337,7 @@ const opacityStyle = computed(() => {
<div v-if="!listVisible.length" class="no-list-label flex-align-center"> <div v-if="!listVisible.length" class="no-list-label flex-align-center">
<div class="container flex-align-center"> <div class="container flex-align-center">
将右侧的字段拖拽到这里 点击 将右侧的字段拖拽到这里 点击
<el-button :disabled="showPosition === 'preview'" @click="addCriteriaConfig" text> <el-button :disabled="showPosition === 'preview'" @click="addCriteriaConfigOut" text>
添加查询条件 添加查询条件
</el-button> </el-button>
</div> </div>
@ -404,6 +351,7 @@ const opacityStyle = computed(() => {
<el-tooltip effect="dark" :content="ele.name" placement="top"> <el-tooltip effect="dark" :content="ele.name" placement="top">
{{ ele.name }} {{ ele.name }}
</el-tooltip> </el-tooltip>
<span v-if="ele.required" class="required">*</span>
</div> </div>
</div> </div>
<div class="label-wrapper-tooltip" v-if="showPosition !== 'preview'"> <div class="label-wrapper-tooltip" v-if="showPosition !== 'preview'">
@ -445,7 +393,6 @@ const opacityStyle = computed(() => {
</div> </div>
<Teleport to="body"> <Teleport to="body">
<QueryConditionConfiguration <QueryConditionConfiguration
:add-query-criteria-config="addQueryCriteriaConfig"
:query-element="element" :query-element="element"
ref="queryConfig" ref="queryConfig"
></QueryConditionConfiguration> ></QueryConditionConfiguration>
@ -471,7 +418,7 @@ const opacityStyle = computed(() => {
justify-content: center; justify-content: center;
color: #646a73; color: #646a73;
text-align: center; text-align: center;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 16px; font-size: 16px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
@ -487,7 +434,7 @@ const opacityStyle = computed(() => {
.title { .title {
color: #1f2329; color: #1f2329;
font-feature-settings: 'clig' off, 'liga' off; font-feature-settings: 'clig' off, 'liga' off;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
@ -538,6 +485,7 @@ const opacityStyle = computed(() => {
overflow: hidden; overflow: hidden;
} }
.label-wrapper-text { .label-wrapper-text {
position: relative;
cursor: pointer; cursor: pointer;
flex: 0 1 auto; flex: 0 1 auto;
max-width: 100%; max-width: 100%;
@ -545,11 +493,18 @@ const opacityStyle = computed(() => {
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
color: #1f2329; color: #1f2329;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
line-height: 22px; line-height: 22px;
.required {
font-size: 14px;
color: #f54a45;
margin-left: 3px;
line-height: 22px;
}
} }
.label-wrapper-tooltip { .label-wrapper-tooltip {
align-items: center; align-items: center;

View File

@ -0,0 +1,151 @@
<script lang="ts" setup>
import { toRefs, PropType, ref, onBeforeMount, watch, computed } from 'vue'
import { Calendar } from '@element-plus/icons-vue'
import { type DatePickType } from 'element-plus-secondary'
import { getCustomTime } from './time-format'
interface SelectConfig {
timeType: string
defaultValue: [Date, Date]
selectValue: [Date, Date]
defaultValueCheck: boolean
id: string
timeNum: number
relativeToCurrentType: string
around: string
arbitraryTime: Date
timeGranularity: DatePickType
timeNumRange: number
relativeToCurrentTypeRange: string
aroundRange: string
arbitraryTimeRange: Date
}
const props = defineProps({
config: {
type: Object as PropType<SelectConfig>,
default: () => {
return {
defaultValue: [],
selectValue: [],
timeType: 'fixed',
timeNum: 0,
relativeToCurrentType: 'year',
around: 'f',
arbitraryTime: new Date(),
defaultValueCheck: false,
timeGranularity: 'date',
timeNumRange: 0,
relativeToCurrentTypeRange: 'year',
aroundRange: 'f',
arbitraryTimeRange: new Date()
}
}
}
})
const selectValue = ref<[Date, Date]>([new Date(), new Date()])
const { config } = toRefs(props)
const timeConfig = computed(() => {
const {
timeNum,
relativeToCurrentType,
around,
defaultValueCheck,
arbitraryTime,
timeGranularity,
timeNumRange,
relativeToCurrentTypeRange,
aroundRange,
arbitraryTimeRange
} = config.value
return {
timeNum,
relativeToCurrentType,
around,
defaultValueCheck,
arbitraryTime,
timeGranularity,
timeNumRange,
relativeToCurrentTypeRange,
aroundRange,
arbitraryTimeRange
}
})
watch(
() => timeConfig.value,
() => {
init()
},
{
deep: true
}
)
watch(
() => selectValue.value,
val => {
config.value.defaultValue = val
config.value.selectValue = val
}
)
watch(
() => config.value.id,
() => {
init()
}
)
const init = () => {
const {
timeNum,
relativeToCurrentType,
around,
defaultValueCheck,
arbitraryTime,
timeGranularity,
timeNumRange,
relativeToCurrentTypeRange,
aroundRange,
arbitraryTimeRange
} = timeConfig.value
if (!defaultValueCheck) {
selectValue.value = [new Date(), new Date()]
return
}
const startTime = getCustomTime(
timeNum,
relativeToCurrentType,
timeGranularity,
around,
arbitraryTime
)
const endTime = getCustomTime(
timeNumRange,
relativeToCurrentTypeRange,
timeGranularity,
aroundRange,
arbitraryTimeRange
)
selectValue.value = [startTime, endTime]
}
onBeforeMount(() => {
init()
})
</script>
<template>
<el-date-picker
disabled
v-model="selectValue"
type="datetimerange"
:prefix-icon="Calendar"
:range-separator="$t('cron.to')"
:start-placeholder="$t('datasource.start_time')"
:end-placeholder="$t('datasource.end_time')"
/>
</template>

View File

@ -1,18 +1,21 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, reactive, nextTick, computed, shallowRef, toRefs, watch } from 'vue' import { ref, reactive, nextTick, computed, shallowRef, toRefs, watch } from 'vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { addQueryCriteriaConfig } from './options'
import { getCustomTime } from './time-format'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot' import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { fieldType } from '@/utils/attr' import { fieldType } from '@/utils/attr'
import { ElMessage } from 'element-plus-secondary' import { ElMessage } from 'element-plus-secondary'
import type { DatasetDetail } from '@/api/dataset' import type { DatasetDetail } from '@/api/dataset'
import { getDsDetails, getSqlParams } from '@/api/dataset' import { getDsDetailsWithPerm, getSqlParams, listFieldsWithPermissions } from '@/api/dataset'
import EmptyBackground from '@/components/empty-background/src/EmptyBackground.vue' import EmptyBackground from '@/components/empty-background/src/EmptyBackground.vue'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
import Select from './Select.vue' import Select from './Select.vue'
import Time from './Time.vue' import Time from './Time.vue'
import DynamicTime from './DynamicTime.vue' import DynamicTime from './DynamicTime.vue'
import DynamicTimeRange from './DynamicTimeRange.vue'
import { getDatasetTree } from '@/api/dataset' import { getDatasetTree } from '@/api/dataset'
import { Tree } from '@/views/visualized/data/dataset/form/CreatDsGroup.vue' import { Tree } from '@/views/visualized/data/dataset/form/CreatDsGroup.vue'
import draggable from 'vuedraggable' import draggable from 'vuedraggable'
@ -30,10 +33,6 @@ interface DatasetField {
} }
const props = defineProps({ const props = defineProps({
addQueryCriteriaConfig: {
type: Function,
default: () => ({})
},
queryElement: { queryElement: {
type: Object, type: Object,
default() { default() {
@ -109,6 +108,10 @@ const parametersFilter = computed(() => {
if (curComponent.value.displayType === '2') { if (curComponent.value.displayType === '2') {
return [2, 3].includes(ele.deType) return [2, 3].includes(ele.deType)
} }
if (curComponent.value.displayType === '7') {
return [1, 7].includes(ele.deType)
}
return ele.deType === +curComponent.value.displayType return ele.deType === +curComponent.value.displayType
}) })
}) })
@ -258,7 +261,59 @@ const validate = () => {
return true return true
} }
if ([1, 7].includes(+ele.displayType)) { if (ele.required) {
if (!ele.defaultValueCheck) {
ElMessage.error('查询条件为必填项,默认值不能为空')
return true
}
if (
(Array.isArray(ele.defaultValue) && !ele.defaultValue.length) ||
(ele.defaultValue !== 0 && !ele.defaultValue)
) {
ElMessage.error('查询条件为必填项,默认值不能为空')
return true
}
}
if (+ele.displayType === 7) {
if (!ele.defaultValueCheck) {
return false
}
const {
timeNum,
relativeToCurrentType,
around,
arbitraryTime,
timeGranularity,
timeNumRange,
relativeToCurrentTypeRange,
aroundRange,
arbitraryTimeRange
} = ele
const startTime = getCustomTime(
timeNum,
relativeToCurrentType,
timeGranularity,
around,
arbitraryTime
)
const endTime = getCustomTime(
timeNumRange,
relativeToCurrentTypeRange,
timeGranularity,
aroundRange,
arbitraryTimeRange
)
if (+startTime > +endTime) {
ElMessage.error('结束时间必须大于开始时间!')
return true
}
return false
}
if ([1].includes(+ele.displayType)) {
return false return false
} }
@ -335,8 +390,10 @@ const confirmValueSource = () => {
const filterTypeCom = computed(() => { const filterTypeCom = computed(() => {
const { displayType, timeType = 'fixed' } = curComponent.value const { displayType, timeType = 'fixed' } = curComponent.value
return ['1', '7'].includes(displayType) return ['1', '7'].includes(displayType)
? timeType === 'dynamic' && displayType === '1' ? timeType === 'dynamic'
? DynamicTime ? displayType === '1'
? DynamicTime
: DynamicTimeRange
: Time : Time
: Select : Select
}) })
@ -346,10 +403,6 @@ const setCondition = (queryId: string) => {
init(queryId) init(queryId)
} }
const setConditionInit = (queryId: string) => {
init(queryId)
}
const setConditionOut = () => { const setConditionOut = () => {
conditions.value = cloneDeep(props.queryElement.propValue) || [] conditions.value = cloneDeep(props.queryElement.propValue) || []
addQueryCriteria() addQueryCriteria()
@ -388,15 +441,10 @@ const init = (queryId: string) => {
return { ...datasetMap[ele.tableId], componentId: ele.id } return { ...datasetMap[ele.tableId], componentId: ele.id }
}) })
.filter(ele => !!ele) .filter(ele => !!ele)
return
} }
getDsDetails([ const params = [...new Set(datasetFieldList.value.map(ele => ele.tableId).filter(ele => !!ele))]
...new Set( if (!params.length) return
datasetFieldList.value getDsDetailsWithPerm(params)
.map(ele => ele.tableId)
.filter(ele => !datasetMapKeyList.includes(ele) && ele)
)
])
.then(res => { .then(res => {
res res
.filter(ele => !!ele) .filter(ele => !!ele)
@ -426,11 +474,18 @@ const weightlessness = () => {
const parameterCompletion = () => { const parameterCompletion = () => {
const attributes = { const attributes = {
timeType: 'fixed', timeType: 'fixed',
required: false,
parametersStart: null,
parametersEnd: null,
relativeToCurrent: 'custom', relativeToCurrent: 'custom',
timeNum: 0, timeNum: 0,
relativeToCurrentType: 'year', relativeToCurrentType: 'year',
around: 'f', around: 'f',
arbitraryTime: new Date() arbitraryTime: new Date(),
timeNumRange: 0,
relativeToCurrentTypeRange: 'year',
aroundRange: 'f',
arbitraryTimeRange: new Date()
} }
Object.entries(attributes).forEach(([key, val]) => { Object.entries(attributes).forEach(([key, val]) => {
!curComponent.value[key] && (curComponent.value[key] = val) !curComponent.value[key] && (curComponent.value[key] = val)
@ -443,7 +498,7 @@ const handleCondition = item => {
curComponent.value = conditions.value.find(ele => ele.id === item.id) curComponent.value = conditions.value.find(ele => ele.id === item.id)
multiple.value = curComponent.value.multiple multiple.value = curComponent.value.multiple
if (!curComponent.value.dataset.fields.length) { if (!curComponent.value.dataset.fields.length && curComponent.value.dataset.id) {
getOptions(curComponent.value.dataset.id, curComponent.value) getOptions(curComponent.value.dataset.id, curComponent.value)
} }
datasetFieldList.value.forEach(ele => { datasetFieldList.value.forEach(ele => {
@ -473,12 +528,8 @@ const handleCondition = item => {
} }
const getOptions = (id, component) => { const getOptions = (id, component) => {
getDsDetails([id]).then(res => { listFieldsWithPermissions(id).then(res => {
res.forEach(ele => { component.dataset.fields = res.data
if (!ele) return
const { dimensionList, quotaList } = ele.fields
component.dataset.fields = [...dimensionList, ...quotaList]
})
}) })
} }
@ -579,7 +630,7 @@ const relativeToCurrentList = computed(() => {
}) })
const dynamicTime = computed(() => { const dynamicTime = computed(() => {
return curComponent.value.timeType === 'dynamic' && curComponent.value.displayType === '1' return curComponent.value.timeType === 'dynamic'
}) })
const relativeToCurrentTypeList = computed(() => { const relativeToCurrentTypeList = computed(() => {
@ -686,7 +737,7 @@ const renameInputBlur = () => {
} }
const addQueryCriteria = () => { const addQueryCriteria = () => {
conditions.value.push(props.addQueryCriteriaConfig()) conditions.value.push(addQueryCriteriaConfig())
} }
const addCriteriaConfig = () => { const addCriteriaConfig = () => {
@ -696,7 +747,6 @@ const addCriteriaConfig = () => {
defineExpose({ defineExpose({
setCondition, setCondition,
setConditionInit,
addCriteriaConfig, addCriteriaConfig,
setConditionOut setConditionOut
}) })
@ -845,8 +895,12 @@ defineExpose({
:key="ele.id" :key="ele.id"
:label="ele.name" :label="ele.name"
:value="ele.id" :value="ele.id"
:disabled="ele.desensitized"
> >
<div class="flex-align-center icon"> <div
class="flex-align-center icon"
:title="ele.desensitized ? '脱敏字段,不能被设置为查询条件' : ''"
>
<el-icon> <el-icon>
<Icon <Icon
:name="`field_${fieldType[ele.deType]}`" :name="`field_${fieldType[ele.deType]}`"
@ -865,7 +919,14 @@ defineExpose({
</div> </div>
<div class="condition-configuration"> <div class="condition-configuration">
<div class="mask condition" v-if="curComponent.auto"></div> <div class="mask condition" v-if="curComponent.auto"></div>
<div class="title">查询条件配置</div> <div class="title flex-align-center">
查询条件配置
<el-checkbox
:disabled="curComponent.auto"
v-model="curComponent.required"
label="必填项"
/>
</div>
<div v-show="showConfiguration && !showTypeError" class="configuration-list"> <div v-show="showConfiguration && !showTypeError" class="configuration-list">
<div class="list-item"> <div class="list-item">
<div class="label">展示类型</div> <div class="label">展示类型</div>
@ -995,8 +1056,12 @@ defineExpose({
:key="ele.id" :key="ele.id"
:label="ele.name" :label="ele.name"
:value="ele.id" :value="ele.id"
:disabled="ele.desensitized"
> >
<div class="flex-align-center icon"> <div
class="flex-align-center icon"
:title="ele.desensitized ? '脱敏字段,不能被设置为查询条件' : ''"
>
<el-icon> <el-icon>
<Icon <Icon
:name="`field_${fieldType[ele.deType]}`" :name="`field_${fieldType[ele.deType]}`"
@ -1088,27 +1153,73 @@ defineExpose({
<div class="label"> <div class="label">
<el-checkbox v-model="curComponent.parametersCheck" label="绑定参数" /> <el-checkbox v-model="curComponent.parametersCheck" label="绑定参数" />
</div> </div>
<div v-if="curComponent.parametersCheck" class="parameters"> <template v-if="curComponent.parametersCheck">
<el-select <div v-if="curComponent.displayType !== '7'" class="parameters">
popper-class="dataset-parameters" <el-select
value-key="id" popper-class="dataset-parameters"
multiple value-key="id"
v-model="curComponent.parameters" multiple
clearable v-model="curComponent.parameters"
> clearable
<el-option
v-for="item in parametersFilter"
:key="item.id"
:label="item.variableName"
:value="item"
> >
<div class="variable-name ellipsis">{{ item.variableName }}</div> <el-option
<el-tooltip effect="dark" :content="item.datasetFullName" placement="top"> v-for="item in parametersFilter"
<div class="dataset-full-name ellipsis">{{ item.datasetFullName }}</div> :key="item.id"
</el-tooltip> :label="item.variableName"
</el-option> :value="item"
</el-select> >
</div> <div class="variable-name ellipsis">{{ item.variableName }}</div>
<el-tooltip effect="dark" :content="item.datasetFullName" placement="top">
<div class="dataset-full-name ellipsis">{{ item.datasetFullName }}</div>
</el-tooltip>
</el-option>
</el-select>
</div>
<div v-else class="parameters-range">
<div class="range-title">开始时间</div>
<div class="range-title">结束时间</div>
<div class="params-start">
<el-select
popper-class="dataset-parameters"
value-key="id"
v-model="curComponent.parametersStart"
clearable
>
<el-option
v-for="item in parametersFilter"
:key="item.id"
:label="item.variableName"
:value="item"
>
<div class="variable-name ellipsis">{{ item.variableName }}</div>
<el-tooltip effect="dark" :content="item.datasetFullName" placement="top">
<div class="dataset-full-name ellipsis">{{ item.datasetFullName }}</div>
</el-tooltip>
</el-option>
</el-select>
</div>
<div class="params-end">
<el-select
popper-class="dataset-parameters"
value-key="id"
v-model="curComponent.parametersEnd"
clearable
>
<el-option
v-for="item in parametersFilter"
:key="item.id"
:label="item.variableName"
:value="item"
>
<div class="variable-name ellipsis">{{ item.variableName }}</div>
<el-tooltip effect="dark" :content="item.datasetFullName" placement="top">
<div class="dataset-full-name ellipsis">{{ item.datasetFullName }}</div>
</el-tooltip>
</el-option>
</el-select>
</div>
</div>
</template>
</div> </div>
<div class="list-item"> <div class="list-item">
<div class="label"> <div class="label">
@ -1116,7 +1227,7 @@ defineExpose({
</div> </div>
<div <div
class="setting-content" class="setting-content"
v-if="curComponent.defaultValueCheck && curComponent.displayType === '1'" v-if="curComponent.defaultValueCheck && ['1', '7'].includes(curComponent.displayType)"
> >
<div class="setting"> <div class="setting">
<el-radio-group v-model="curComponent.timeType"> <el-radio-group v-model="curComponent.timeType">
@ -1124,7 +1235,7 @@ defineExpose({
<el-radio label="dynamic">动态时间</el-radio> <el-radio label="dynamic">动态时间</el-radio>
</el-radio-group> </el-radio-group>
</div> </div>
<template v-if="dynamicTime"> <template v-if="dynamicTime && curComponent.displayType === '1'">
<div class="setting"> <div class="setting">
<div class="setting-label">相对当前</div> <div class="setting-label">相对当前</div>
<div class="setting-value select"> <div class="setting-value select">
@ -1171,6 +1282,62 @@ defineExpose({
</div> </div>
</div> </div>
</template> </template>
<template v-else-if="dynamicTime && curComponent.displayType === '7'">
<div class="setting">
<div class="setting-label">开始时间</div>
<div class="setting-input with-date range">
<el-input-number
v-model="curComponent.timeNum"
:min="0"
controls-position="right"
/>
<el-select v-model="curComponent.relativeToCurrentType">
<el-option
v-for="item in relativeToCurrentTypeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-select v-model="curComponent.around">
<el-option
v-for="item in aroundList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-time-picker v-model="curComponent.arbitraryTime" />
</div>
</div>
<div class="setting">
<div class="setting-label">结束时间</div>
<div class="setting-input with-date range">
<el-input-number
v-model="curComponent.timeNumRange"
:min="0"
controls-position="right"
/>
<el-select v-model="curComponent.relativeToCurrentTypeRange">
<el-option
v-for="item in relativeToCurrentTypeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-select v-model="curComponent.aroundRange">
<el-option
v-for="item in aroundList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-time-picker v-model="curComponent.arbitraryTimeRange" />
</div>
</div>
</template>
</div> </div>
<div <div
v-if="curComponent.defaultValueCheck" v-if="curComponent.defaultValueCheck"
@ -1208,7 +1375,7 @@ defineExpose({
<style lang="less"> <style lang="less">
.dataset-parameters { .dataset-parameters {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
.ed-select-dropdown__item { .ed-select-dropdown__item {
@ -1240,7 +1407,7 @@ defineExpose({
} }
.container { .container {
font-size: 14px; font-size: 14px;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
width: 1152px; width: 1152px;
height: 454px; height: 454px;
border-radius: 4px; border-radius: 4px;
@ -1261,7 +1428,7 @@ defineExpose({
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
@ -1309,7 +1476,6 @@ defineExpose({
} }
.chart-field { .chart-field {
border-right: 1px solid #dee0e3;
height: calc(100% - 16px); height: calc(100% - 16px);
padding: 0 16px 16px 16px; padding: 0 16px 16px 16px;
width: 474px; width: 474px;
@ -1329,7 +1495,7 @@ defineExpose({
} }
.title { .title {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
@ -1381,6 +1547,7 @@ defineExpose({
.condition-configuration { .condition-configuration {
padding: 16px; padding: 16px;
border-left: 1px solid #dee0e3;
width: 467px; width: 467px;
position: relative; position: relative;
.mask { .mask {
@ -1392,7 +1559,7 @@ defineExpose({
color: #646a73; color: #646a73;
height: 16px; height: 16px;
padding: 0px 4px; padding: 0px 4px;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 10px; font-size: 10px;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
@ -1401,9 +1568,20 @@ defineExpose({
background: rgba(31, 35, 41, 0.1); background: rgba(31, 35, 41, 0.1);
margin-left: 8px; margin-left: 8px;
} }
.flex-align-center {
position: sticky;
top: 0;
justify-content: space-between;
background: #fff;
z-index: 5;
.ed-checkbox {
height: 20px;
}
}
.title { .title {
margin-bottom: 16px; margin-bottom: 16px;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
@ -1449,6 +1627,7 @@ defineExpose({
.parameters { .parameters {
margin-left: auto; margin-left: auto;
margin-top: 8px;
.w100 { .w100 {
width: 100%; width: 100%;
@ -1466,8 +1645,38 @@ defineExpose({
} }
} }
} }
.parameters-range {
width: 100%;
padding-left: 24px;
display: flex;
flex-wrap: wrap;
.range-title,
.params-start,
.params-end {
width: 50%;
}
.params-start,
.params-end {
margin-top: 8px;
.ed-select {
width: 100%;
}
}
.params-end {
padding-left: 4px;
}
.params-start {
padding-right: 4px;
}
}
.setting { .setting {
&.setting {
margin-top: 8px;
}
&.parameters { &.parameters {
width: 100%; width: 100%;
padding-left: 24px; padding-left: 24px;
@ -1498,6 +1707,9 @@ defineExpose({
padding-left: 86px; padding-left: 86px;
justify-content: flex-end; justify-content: flex-end;
align-items: center; align-items: center;
&.range {
padding-left: 0px;
}
& > div + div { & > div + div {
margin-left: 8px; margin-left: 8px;
} }

View File

@ -182,7 +182,7 @@ watch(
watch( watch(
() => config.value.valueSource, () => config.value.valueSource,
() => { () => {
debounceOptions(2) config.value.optionValueSource === 2 && debounceOptions(2)
} }
) )

View File

@ -0,0 +1,64 @@
import type { ComponentInfo } from '@/api/chart'
import { guid } from '@/views/visualized/data/dataset/form/util.js'
const infoFormat = (obj: ComponentInfo) => {
const { id, name, deType, type, datasetId } = obj
return {
id: guid(),
name,
showError: true,
timeGranularity: 'date',
timeGranularityMultiple: 'datetimerange',
field: {
id,
type,
name,
deType
},
timeType: 'fixed',
relativeToCurrent: 'custom',
required: false,
timeNum: 0,
relativeToCurrentType: 'year',
around: 'f',
parametersStart: null,
parametersEnd: null,
arbitraryTime: new Date(),
timeNumRange: 0,
relativeToCurrentTypeRange: 'year',
aroundRange: 'f',
arbitraryTimeRange: new Date(),
auto: false,
defaultValue: undefined,
selectValue: undefined,
optionValueSource: 0,
valueSource: [],
dataset: {
id: datasetId,
name: '',
fields: []
},
visible: true,
defaultValueCheck: false,
multiple: false,
displayType: '0',
checkedFields: [],
parameters: [],
parametersCheck: false,
parametersList: [],
checkedFieldsMap: {}
}
}
const addQueryCriteriaConfig = () => {
const componentInfo: ComponentInfo = {
id: '',
name: '未命名',
deType: 0,
type: 'VARCHAR',
datasetId: ''
}
return infoFormat(componentInfo)
}
export { infoFormat, addQueryCriteriaConfig }

View File

@ -50,7 +50,7 @@ function getCustomTime(
timeType: string, timeType: string,
timeGranularity: string, timeGranularity: string,
around: string, around: string,
arbitraryTime?: string arbitraryTime?: Date
) { ) {
const date = new Date() const date = new Date()
const num = around === 'f' ? -timeNum : timeNum const num = around === 'f' ? -timeNum : timeNum
@ -80,7 +80,7 @@ function getCustomTime(
if (!!arbitraryTime) { if (!!arbitraryTime) {
const time = new Date(arbitraryTime) const time = new Date(arbitraryTime)
time.setFullYear(resultYear) time.setFullYear(resultYear)
time.setMonth(resultMonth) time.setMonth(resultMonth - 1)
time.setDate(resultDate) time.setDate(resultDate)
return time return time
} }

View File

@ -1,6 +1,6 @@
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { getDynamicRange } from '@/custom-component/v-query/time-format' import { getDynamicRange, getCustomTime } from '@/custom-component/v-query/time-format'
const dvMainStore = dvMainStoreWithOut() const dvMainStore = dvMainStoreWithOut()
const { componentData } = storeToRefs(dvMainStore) const { componentData } = storeToRefs(dvMainStore)
@ -90,6 +90,8 @@ export const searchQuery = (queryComponentList, filter, curComponentId, firstLoa
let selectValue = '' let selectValue = ''
const { const {
selectValue: value, selectValue: value,
parametersStart,
parametersEnd,
defaultValueCheck, defaultValueCheck,
timeType = 'fixed', timeType = 'fixed',
defaultValue, defaultValue,
@ -100,10 +102,43 @@ export const searchQuery = (queryComponentList, filter, curComponentId, firstLoa
displayType, displayType,
multiple multiple
} = item } = item
if (timeType === 'dynamic' && +displayType === 1 && firstLoad && !value?.length) {
selectValue = getDynamicRange(item) if (timeType === 'dynamic' && [1, 7].includes(+displayType) && firstLoad) {
item.defaultValue = new Date(selectValue[0]) if (+displayType === 1) {
item.selectValue = new Date(selectValue[0]) selectValue = getDynamicRange(item)
item.defaultValue = new Date(selectValue[0])
item.selectValue = new Date(selectValue[0])
} else {
const {
timeNum,
relativeToCurrentType,
around,
arbitraryTime,
timeGranularity,
timeNumRange,
relativeToCurrentTypeRange,
aroundRange,
arbitraryTimeRange
} = item
const startTime = getCustomTime(
timeNum,
relativeToCurrentType,
timeGranularity,
around,
arbitraryTime
)
const endTime = getCustomTime(
timeNumRange,
relativeToCurrentTypeRange,
timeGranularity,
aroundRange,
arbitraryTimeRange
)
item.defaultValue = [startTime, endTime]
item.selectValue = [startTime, endTime]
}
} else { } else {
selectValue = getValueByDefaultValueCheckOrFirstLoad( selectValue = getValueByDefaultValueCheckOrFirstLoad(
defaultValueCheck, defaultValueCheck,
@ -123,7 +158,16 @@ export const searchQuery = (queryComponentList, filter, curComponentId, firstLoa
fieldId: item.checkedFieldsMap[curComponentId], fieldId: item.checkedFieldsMap[curComponentId],
operator: [1, 7].includes(+displayType) ? 'between' : multiple ? 'in' : 'eq', operator: [1, 7].includes(+displayType) ? 'between' : multiple ? 'in' : 'eq',
value: values, value: values,
parameters: parametersCheck ? parameters : [], parameters: parametersCheck
? +displayType === 7
? [
parametersStart,
parametersEnd?.id
? { ...parametersEnd, id: `${parametersEnd.id}_START_END_SPLIT` }
: parametersEnd
]
: parameters
: [],
isTree isTree
}) })
} }

View File

@ -10,6 +10,8 @@ import { useEmitt } from '@/hooks/web/useEmitt'
import AboutPage from '@/views/about/index.vue' import AboutPage from '@/views/about/index.vue'
import LangSelector from './LangSelector.vue' import LangSelector from './LangSelector.vue'
import router from '@/router' import router from '@/router'
import { useCache } from '@/hooks/web/useCache'
const { wsCache } = useCache()
const userStore = useUserStoreWithOut() const userStore = useUserStoreWithOut()
const { t } = useI18n() const { t } = useI18n()
@ -30,6 +32,16 @@ const linkLoaded = items => {
items.forEach(item => linkList.value.push(item)) items.forEach(item => linkList.value.push(item))
linkList.value.sort(compare('id')) linkList.value.sort(compare('id'))
} }
const xpackLinkLoaded = items => {
let len = linkList.value.length
while (len--) {
if (linkList.value[len]?.id === 2 && linkList.value[len]?.link === '/modify-pwd/index') {
linkList.value.splice(len, 1)
}
}
items.forEach(item => linkList.value.push(item))
linkList.value.sort(compare('id'))
}
const compare = (property: string) => { const compare = (property: string) => {
return (a, b) => a[property] - b[property] return (a, b) => a[property] - b[property]
@ -68,6 +80,10 @@ const openPopover = () => {
if (uid.value === '1') { if (uid.value === '1') {
linkLoaded([{ id: 4, link: '/sys-setting/parameter', label: t('commons.system_setting') }]) linkLoaded([{ id: 4, link: '/sys-setting/parameter', label: t('commons.system_setting') }])
const desktop = wsCache.get('app.desktop')
if (!desktop) {
linkLoaded([{ id: 2, link: '/modify-pwd/index', label: t('user.change_password') }])
}
} }
</script> </script>
@ -138,7 +154,7 @@ if (uid.value === '1') {
</el-popover> </el-popover>
<AboutPage /> <AboutPage />
<XpackComponent jsname="dWNlbnRlci1oYW5kbGVy" @loaded="linkLoaded" /> <XpackComponent jsname="dWNlbnRlci1oYW5kbGVy" @loaded="xpackLinkLoaded" />
</template> </template>
<style lang="less"> <style lang="less">

View File

@ -32,7 +32,7 @@ const backToMain = () => {
<style lang="less" scoped> <style lang="less" scoped>
.system-header { .system-header {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
.logo { .logo {
width: 134px; width: 134px;

View File

@ -28,7 +28,7 @@ const backToMain = () => {
<style lang="less" scoped> <style lang="less" scoped>
.system-header { .system-header {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
.logo { .logo {
width: 134px; width: 134px;

View File

@ -1353,8 +1353,8 @@ export default {
export_filter: '筛选条件', export_filter: '筛选条件',
pls_input_filename: '请输入文件名称', pls_input_filename: '请输入文件名称',
calc_tips: { calc_tips: {
tip1: '表达式语法请遵循该数据源对应的数据库语法', tip1: '表达式语法请遵循calcite语法',
tip2: '数据集中不支持聚合运算', tip2: '聚合运算仅能在图表中生效',
tip3: '引用字段以 "[" 开始 "]" 结束', tip3: '引用字段以 "[" 开始 "]" 结束',
tip4: '请勿修改引用内容否则将引用失败', tip4: '请勿修改引用内容否则将引用失败',
tip5: '若输入与引用字段相同格式的内容将被当作引用字段处理', tip5: '若输入与引用字段相同格式的内容将被当作引用字段处理',

View File

@ -1,4 +1,5 @@
import { createApp } from 'vue' import { createApp } from 'vue'
import '../../assets/font/index.css'
import '@/style/index.less' import '@/style/index.less'
import '@/plugins/svg-icon' import '@/plugins/svg-icon'
import 'normalize.css/normalize.css' import 'normalize.css/normalize.css'

View File

@ -8,6 +8,10 @@ const DashboardEditor = defineAsyncComponent(() => import('@/views/dashboard/ind
const Dashboard = defineAsyncComponent(() => import('./DashboardPreview.vue')) const Dashboard = defineAsyncComponent(() => import('./DashboardPreview.vue'))
const ViewWrapper = defineAsyncComponent(() => import('./ViewWrapper.vue')) const ViewWrapper = defineAsyncComponent(() => import('./ViewWrapper.vue'))
const Dataset = defineAsyncComponent(() => import('@/views/visualized/data/dataset/index.vue'))
const Datasource = defineAsyncComponent(
() => import('@/views/visualized/data/datasource/index.vue')
)
const props = defineProps({ const props = defineProps({
componentName: propTypes.string.def('DashboardEditor') componentName: propTypes.string.def('DashboardEditor')
}) })
@ -17,7 +21,9 @@ const componentMap = {
DashboardEditor, DashboardEditor,
VisualizationEditor, VisualizationEditor,
ViewWrapper, ViewWrapper,
Dashboard Dashboard,
Dataset,
Datasource
} }
currentComponent.value = componentMap[props.componentName] currentComponent.value = componentMap[props.componentName]

View File

@ -96,6 +96,22 @@ export const routes: AppRouteRecordRaw[] = [
hidden: true, hidden: true,
meta: {}, meta: {},
component: () => import('@/custom-component/rich-text/DeRichTextView.vue') component: () => import('@/custom-component/rich-text/DeRichTextView.vue')
},
{
path: '/modify-pwd',
name: 'modify-pwd',
hidden: true,
meta: {},
component: () => import('@/layout/index.vue'),
children: [
{
path: 'index',
name: 'mpi',
hidden: true,
component: () => import('@/views/system/modify-pwd/index.vue'),
meta: { hidden: true }
}
]
} }
] ]

View File

@ -85,6 +85,9 @@ export const userStore = defineStore('user', {
this.oid = oid this.oid = oid
}, },
setLanguage(language: string) { setLanguage(language: string) {
if (!language || language === 'zh_CN') {
language = 'zh-CN'
}
wsCache.set('user.language', language) wsCache.set('user.language', language)
this.language = language this.language = language
locale.setLang(language) locale.setLang(language)

View File

@ -1,12 +1,12 @@
:root { :root {
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, \5fae\8f6f\96c5\9ed1, Arial, sans-serif; font-family: '阿里巴巴普惠体 3.0 55 Regular L3', Helvetica Neue, Helvetica, '阿里巴巴普惠体 3.0 55 Regular L3', Hiragino Sans GB, Microsoft YaHei,
\5fae\8f6f\96c5\9ed1, Arial, sans-serif;
line-height: 1.5; line-height: 1.5;
font-weight: 400; font-weight: 400;
color-scheme: light dark; color-scheme: light dark;
font-synthesis: none; font-synthesis: none;
// text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;
@ -54,7 +54,6 @@ body {
white-space: nowrap; white-space: nowrap;
} }
.list-item_primary { .list-item_primary {
height: 40px; height: 40px;
border-radius: 4px; border-radius: 4px;
@ -70,7 +69,7 @@ body {
.label { .label {
width: 85%; width: 85%;
font-size: 14px; font-size: 14px;
.ellipsis .ellipsis;
} }
&:not(.active):hover { &:not(.active):hover {
@ -79,7 +78,7 @@ body {
&.active { &.active {
background: rgba(51, 112, 255, 0.1); background: rgba(51, 112, 255, 0.1);
color: #3370FF; color: #3370ff;
} }
} }
@ -101,7 +100,7 @@ body {
} }
.title-form_primary { .title-form_primary {
font-family: 'PingFang SC'; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
font-size: 14px; font-size: 14px;
@ -130,28 +129,28 @@ body {
background-color: #f5f6f7 !important; background-color: #f5f6f7 !important;
.ed-table-v2__header-cell { .ed-table-v2__header-cell {
background-color: transparent background-color: transparent;
} }
} }
.field-icon-text { .field-icon-text {
color: #3370FF; color: #3370ff;
} }
.field-icon-time { .field-icon-time {
color: #3370FF; color: #3370ff;
} }
.field-icon-value { .field-icon-value {
color: #04B49C; color: #04b49c;
} }
.field-icon-location { .field-icon-location {
color: #3370FF; color: #3370ff;
} }
.field-icon-red { .field-icon-red {
color: #F54A45; color: #f54a45;
} }
.field-icon-sort { .field-icon-sort {
@ -161,24 +160,22 @@ body {
} }
.field-icon-dimension { .field-icon-dimension {
color: #3370FF; color: #3370ff;
} }
.field-icon-quota { .field-icon-quota {
color: #04B49C; color: #04b49c;
} }
.hover-icon { .hover-icon {
cursor: pointer; cursor: pointer;
height: 24px !important; height: 24px !important;
width: 24px !important; width: 24px !important;
font-size: 16px !important; font-size: 16px !important;
border-radius: 4px; border-radius: 4px;
color: #646A73 !important; color: #646a73 !important;
&[aria-expanded="true"] { &[aria-expanded='true'] {
background: rgba(31, 35, 41, 0.1); background: rgba(31, 35, 41, 0.1);
} }
@ -198,25 +195,24 @@ body {
} }
.hover-icon-in-table { .hover-icon-in-table {
color: #3370FF !important; color: #3370ff !important;
&[aria-expanded="true"] { &[aria-expanded='true'] {
background: rgba(51,112,255,.1); background: rgba(51, 112, 255, 0.1);
} }
&:hover { &:hover {
background: rgba(51,112,255,.1); background: rgba(51, 112, 255, 0.1);
} }
} }
.custom-popover-dark { .custom-popover-dark {
min-width: 50px!important; min-width: 50px !important;
background: @side-content-background !important; background: @side-content-background !important;
padding: 0px 4px 0 4px !important; padding: 0px 4px 0 4px !important;
border: 1px solid @side-outline-border-color !important; border: 1px solid @side-outline-border-color !important;
} }
.custom-popover-light { .custom-popover-light {
min-width: 50px!important; min-width: 50px !important;
background: @side-content-background-light !important; background: @side-content-background-light !important;
padding: 0px 4px 0 4px !important; padding: 0px 4px 0 4px !important;
border: 1px solid @side-outline-border-color-light !important; border: 1px solid @side-outline-border-color-light !important;
@ -235,7 +231,7 @@ body {
border-radius: 4px; border-radius: 4px;
&:hover { &:hover {
background: rgba(235, 235, 235, 0.10); background: rgba(235, 235, 235, 0.1);
} }
&:active { &:active {
@ -281,7 +277,7 @@ body {
} }
.primary-color { .primary-color {
color: var(--ed-color-primary, #3370FF); color: var(--ed-color-primary, #3370ff);
} }
// .ed-drawer__footer { // .ed-drawer__footer {
@ -298,7 +294,6 @@ body {
display: none; display: none;
} }
.create-dialog { .create-dialog {
.ed-form-item { .ed-form-item {
margin-bottom: 16px; margin-bottom: 16px;
@ -323,7 +318,6 @@ em {
text-align: left !important; text-align: left !important;
} }
.cell { .cell {
.is-text { .is-text {
.ed-icon { .ed-icon {
@ -337,28 +331,28 @@ em {
max-height: 100vh; max-height: 100vh;
overflow-y: auto; overflow-y: auto;
background: none !important; background: none !important;
.ed-dialog__header{ .ed-dialog__header {
padding: 0px; padding: 0px;
.ed-dialog__headerbtn{ .ed-dialog__headerbtn {
.ed-icon { .ed-icon {
font-size: 24px; font-size: 24px;
color: white; color: white;
} }
background: rgba(31, 35, 41, 0.90); background: rgba(31, 35, 41, 0.9);
height: 48px; height: 48px;
width: 48px; width: 48px;
top:24px; top: 24px;
right: 24px; right: 24px;
padding: 12px; padding: 12px;
border-radius: 50%; border-radius: 50%;
&:hover { &:hover {
background: #646A73; background: #646a73;
} }
} }
} }
.ed-dialog__body{ .ed-dialog__body {
padding: 0px; padding: 0px;
background-color: #1F232999; background-color: #1f232999;
} }
} }
@ -367,3 +361,31 @@ em {
width: 16px !important; width: 16px !important;
height: 12px !important; height: 12px !important;
} }
.color-panel {
background: #3370ff;
}
.color-dashboard {
background: #3370ff;
}
.color-screen {
background: rgb(0, 214, 185);
}
.color-dataV {
background: rgb(0, 214, 185);
}
.color-dataset {
background: rgb(22, 192, 255);
}
.color-datasource {
background: rgb(127, 59, 246);
}
.ed-table {
--ed-table-row-hover-bg-color: #e8e9e9 !important;
}

View File

@ -198,14 +198,6 @@ export function getCanvasStyle(canvasStyleData) {
return style return style
} }
// export function createGroupStyle(groupComponent) {
// const parentStyle = groupComponent.style
// groupComponent.propValue.forEach(component => {
// component.style.left = component.style.left - parentStyle.left
// component.style.top = component.style.top - parentStyle.top
// })
// }
export function createGroupStyle(groupComponent) { export function createGroupStyle(groupComponent) {
const parentStyle = groupComponent.style const parentStyle = groupComponent.style
groupComponent.propValue.forEach(component => { groupComponent.propValue.forEach(component => {

View File

@ -171,11 +171,11 @@ const update = (licKey: string) => {
</div> </div>
<div class="item"> <div class="item">
<div class="label">{{ $t('about.serial_no') }}</div> <div class="label">{{ $t('about.serial_no') }}</div>
<div class="value">{{ license.serialNo }}</div> <div class="value">{{ license.serialNo || '-' }}</div>
</div> </div>
<div class="item"> <div class="item">
<div class="label">{{ $t('about.remark') }}</div> <div class="label">{{ $t('about.remark') }}</div>
<div class="value ellipsis">{{ license.remark }}</div> <div class="value ellipsis">{{ license.remark || '-' }}</div>
</div> </div>
<div v-if="isAdmin" style="margin-top: 24px" class="lic_rooter"> <div v-if="isAdmin" style="margin-top: 24px" class="lic_rooter">
@ -220,7 +220,7 @@ const update = (licKey: string) => {
margin-top: -7px; margin-top: -7px;
.item { .item {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 16px; font-size: 16px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;

View File

@ -264,22 +264,6 @@ onMounted(() => {
<span class="set-text-info" :class="{ 'set-text-info-dark': themes === 'dark' }"> <span class="set-text-info" :class="{ 'set-text-info-dark': themes === 'dark' }">
已设置 已设置
</span> </span>
<!-- <el-button
class="circle-button font14"
:title="t('chart.delete')"
:class="'label-' + props.themes"
text
size="small"
:style="{ width: '24px', marginLeft: '6px' }"
@click="linkageSetOpen"
>
<template #icon>
<el-icon size="14px">
<Icon name="icon_delete-trash_outlined" />
</el-icon>
</template>
</el-button>-->
</template> </template>
<el-button <el-button
class="circle-button font14" class="circle-button font14"
@ -406,7 +390,7 @@ span {
} }
.label-dark { .label-dark {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
line-height: 20px; line-height: 20px;

View File

@ -318,7 +318,7 @@ span {
} }
.label-dark { .label-dark {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
line-height: 20px; line-height: 20px;

View File

@ -767,7 +767,7 @@ span {
} }
} }
.label-dark { .label-dark {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
line-height: 20px; line-height: 20px;

View File

@ -479,7 +479,7 @@ watch(
} }
.remark-label { .remark-label {
color: var(--N600, #646a73); color: var(--N600, #646a73);
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 12px; font-size: 12px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;

View File

@ -554,6 +554,7 @@ onMounted(() => {
<el-checkbox <el-checkbox
:disabled="!formatterEditable" :disabled="!formatterEditable"
v-model="curSeriesFormatter.show" v-model="curSeriesFormatter.show"
:effect="themes"
size="small" size="small"
label="quota" label="quota"
@change="changeTooltipAttr('seriesTooltipFormatter', true)" @change="changeTooltipAttr('seriesTooltipFormatter', true)"

View File

@ -202,7 +202,7 @@ span {
:deep(span) { :deep(span) {
color: var(--N900, #1f2329); color: var(--N900, #1f2329);
/* 中文/桌面端/正文 14 22 Regular */ /* 中文/桌面端/正文 14 22 Regular */
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;

View File

@ -412,7 +412,7 @@ span {
:deep(span) { :deep(span) {
color: var(--N900, #1f2329); color: var(--N900, #1f2329);
/* 中文/桌面端/正文 14 22 Regular */ /* 中文/桌面端/正文 14 22 Regular */
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;

View File

@ -187,13 +187,6 @@ const getFields = (id, chartId) => {
state.quotaData = [] state.quotaData = []
} }
} }
watch(
[() => state.searchField],
newVal => {
fieldFilter(newVal[0])
},
{ deep: true }
)
const chartStyleShow = computed(() => { const chartStyleShow = computed(() => {
return view.value.type !== 'richText' return view.value.type !== 'richText'
@ -263,39 +256,39 @@ const queryList = computed(() => {
}) })
const quotaData = computed(() => { const quotaData = computed(() => {
let result = JSON.parse(JSON.stringify(state.quota))
if (view.value?.type === 'table-info') { if (view.value?.type === 'table-info') {
return state.quota?.filter(item => item.id !== '-1') result = result?.filter(item => item.id !== '-1')
} }
return state.quota if (state.searchField) {
result = result.filter(item =>
item.name.toLowerCase().includes(state.searchField.toLowerCase())
)
}
return result
}) })
provide('quotaData', quotaData) const dimensionData = computed(() => {
let result = JSON.parse(JSON.stringify(state.dimensionData))
if (state.searchField) {
result = result.filter(item =>
item.name.toLowerCase().includes(state.searchField.toLowerCase())
)
}
return result
})
const realQuota = computed(() => {
let result = JSON.parse(JSON.stringify(state.quota))
if (view.value?.type === 'table-info') {
result = result?.filter(item => item.id !== '-1')
}
return result
})
provide('quotaData', realQuota)
const startToMove = (e, item) => { const startToMove = (e, item) => {
e.dataTransfer.setData('dimension', JSON.stringify({ ...item, datasetId: view.value.tableId })) e.dataTransfer.setData('dimension', JSON.stringify({ ...item, datasetId: view.value.tableId }))
} }
const fieldFilter = val => {
if (val && val !== '') {
state.dimensionData = JSON.parse(
JSON.stringify(
state.dimension.filter(ele => {
return ele.name.toLocaleLowerCase().includes(val.toLocaleLowerCase())
})
)
)
state.quotaData = JSON.parse(
JSON.stringify(
state.quota.filter(ele => {
return ele.name.toLocaleLowerCase().includes(val.toLocaleLowerCase())
})
)
)
} else {
state.dimensionData = JSON.parse(JSON.stringify(state.dimension))
state.quotaData = JSON.parse(JSON.stringify(state.quota))
}
}
const dimensionItemChange = () => { const dimensionItemChange = () => {
recordSnapshotInfo('calcData') recordSnapshotInfo('calcData')
// do dimensionItemChange // do dimensionItemChange
@ -1853,7 +1846,7 @@ const onRefreshChange = val => {
<label>{{ t('chart.dimension') }}</label> <label>{{ t('chart.dimension') }}</label>
<el-scrollbar class="drag-list"> <el-scrollbar class="drag-list">
<draggable <draggable
:list="state.dimensionData" :list="dimensionData"
:group="dsFieldDragOptions.group" :group="dsFieldDragOptions.group"
:move="onMove" :move="onMove"
item-key="id" item-key="id"
@ -2233,7 +2226,7 @@ const onRefreshChange = val => {
height: 35px; height: 35px;
line-height: 35px; line-height: 35px;
color: #3370ff; color: #3370ff;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 12px; font-size: 12px;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
@ -3097,7 +3090,7 @@ span {
margin-bottom: 16px !important; margin-bottom: 16px !important;
.text { .text {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
@ -3106,7 +3099,7 @@ span {
--ed-input-height: 32px; --ed-input-height: 32px;
:deep(.ed-input__inner) { :deep(.ed-input__inner) {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
@ -3117,7 +3110,7 @@ span {
:deep(.ed-form-item__label) { :deep(.ed-form-item__label) {
color: #1f2329; color: #1f2329;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;

View File

@ -4,6 +4,7 @@ import { parseJson } from '../../../util'
import { S2ChartView, S2DrawOptions } from '../../types/impl/s2' import { S2ChartView, S2DrawOptions } from '../../types/impl/s2'
import { TABLE_EDITOR_PROPERTY, TABLE_EDITOR_PROPERTY_INNER } from './common' import { TABLE_EDITOR_PROPERTY, TABLE_EDITOR_PROPERTY_INNER } from './common'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { isNumber } from 'lodash-es'
const { t } = useI18n() const { t } = useI18n()
@ -70,17 +71,14 @@ export class TableInfo extends S2ChartView<TableSheet> {
if (value === null || value === undefined) { if (value === null || value === undefined) {
return value return value
} }
if (f.groupType === 'd') { if (f.groupType === 'd' || !isNumber(value)) {
return value return value
} else {
if (f.formatterCfg) {
const v = valueFormatter(value, f.formatterCfg)
return v.includes('NaN') ? value : v
} else {
const v = valueFormatter(value, formatterItem)
return v.includes('NaN') ? value : v
}
} }
let formatCfg = f.formatterCfg
if (!formatCfg) {
formatCfg = formatterItem
}
return valueFormatter(value, formatCfg)
} }
}) })
}) })

View File

@ -5,6 +5,7 @@ import { formatterItem, valueFormatter } from '@/views/chart/components/js/forma
import { getCurrentField } from '@/views/chart/components/js/panel/common/common_table' import { getCurrentField } from '@/views/chart/components/js/panel/common/common_table'
import { TABLE_EDITOR_PROPERTY, TABLE_EDITOR_PROPERTY_INNER } from './common' import { TABLE_EDITOR_PROPERTY, TABLE_EDITOR_PROPERTY_INNER } from './common'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { isNumber } from 'lodash-es'
const { t } = useI18n() const { t } = useI18n()
/** /**
@ -70,11 +71,14 @@ export class TableNormal extends S2ChartView<TableSheet> {
if (value === null || value === undefined) { if (value === null || value === undefined) {
return value return value
} }
if (f.formatterCfg) { if (f.groupType === 'd' || !isNumber(value)) {
return valueFormatter(value, f.formatterCfg) return value
} else {
return valueFormatter(value, formatterItem)
} }
let formatCfg = f.formatterCfg
if (!formatCfg) {
formatCfg = formatterItem
}
return valueFormatter(value, formatCfg)
} }
}) })
}) })

View File

@ -165,17 +165,6 @@ export function getColors(chart, colors, reset) {
} else { } else {
if (chart.data) { if (chart.data) {
const data = chart.data.data const data = chart.data.data
// data 的维度值需要根据自定义顺序排序
// let customSortData
// if (Object.prototype.toString.call(chart.customSort) === '[object Array]') {
// customSortData = JSON.parse(JSON.stringify(chart.customSort))
// } else {
// customSortData = JSON.parse(chart.customSort)
// }
// if (customSortData && customSortData.length > 0) {
// data = customSort(customSortData, data)
// }
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
const s = data[i] const s = data[i]
seriesColors.push({ seriesColors.push({

View File

@ -10,7 +10,8 @@ import {
shallowRef, shallowRef,
ShallowRef, ShallowRef,
toRaw, toRaw,
toRefs toRefs,
watch
} from 'vue' } from 'vue'
import { getData } from '@/api/chart' import { getData } from '@/api/chart'
import chartViewManager from '@/views/chart/components/js/panel' import chartViewManager from '@/views/chart/components/js/panel'
@ -149,10 +150,6 @@ const renderChart = (viewInfo: Chart, resetPageInfo: boolean) => {
initScroll() initScroll()
} }
const pageColor = computed(() => {
const text = view.value?.customStyle?.text
return text.color ?? 'white'
})
const setupPage = (chart: ChartObj, resetPageInfo?: boolean) => { const setupPage = (chart: ChartObj, resetPageInfo?: boolean) => {
const customAttr = chart.customAttr const customAttr = chart.customAttr
if (chart.type !== 'table-info' || customAttr.basicStyle.tablePageMode !== 'page') { if (chart.type !== 'table-info' || customAttr.basicStyle.tablePageMode !== 'page') {
@ -172,7 +169,7 @@ const setupPage = (chart: ChartObj, resetPageInfo?: boolean) => {
} }
} }
let scrollTimer let scrollTimer: number
let scrollTop = 0 let scrollTop = 0
const initScroll = () => { const initScroll = () => {
clearInterval(scrollTimer) clearInterval(scrollTimer)
@ -216,7 +213,7 @@ const showPage = computed(() => {
const handleCurrentChange = pageNum => { const handleCurrentChange = pageNum => {
let extReq = { goPage: pageNum } let extReq = { goPage: pageNum }
if (chartExtRequest) { if (chartExtRequest.value) {
extReq = { ...extReq, ...chartExtRequest.value } extReq = { ...extReq, ...chartExtRequest.value }
} }
const chart = { ...view.value, chartExtRequest: extReq } const chart = { ...view.value, chartExtRequest: extReq }
@ -317,7 +314,7 @@ const resize = (width, height) => {
} }
const preSize = [0, 0] const preSize = [0, 0]
const TOLERANCE = 1 const TOLERANCE = 1
let resizeObserver let resizeObserver: ResizeObserver
onMounted(() => { onMounted(() => {
isDataEaseBi.value = !!window.DataEaseBi isDataEaseBi.value = !!window.DataEaseBi
resizeObserver = new ResizeObserver(([entry] = []) => { resizeObserver = new ResizeObserver(([entry] = []) => {
@ -359,13 +356,12 @@ onBeforeUnmount(() => {
<div style="height: 100%" :id="containerId"></div> <div style="height: 100%" :id="containerId"></div>
</div> </div>
<div class="table-page-info" v-if="showPage && !isError"> <div class="table-page-info" v-if="showPage && !isError">
<div :style="{ color: pageColor }">{{ state.pageInfo.total }}</div> <div>{{ state.pageInfo.total }}</div>
<el-pagination <el-pagination
class="table-page-content" class="table-page-content"
layout="prev, pager, next" layout="prev, pager, next"
v-model:page-size="state.pageInfo.pageSize" v-model:page-size="state.pageInfo.pageSize"
v-model:current-page="state.pageInfo.currentPage" v-model:current-page="state.pageInfo.currentPage"
:style="{ color: pageColor }"
:pager-count="5" :pager-count="5"
:total="state.pageInfo.total" :total="state.pageInfo.total"
@update:current-page="handleCurrentChange" @update:current-page="handleCurrentChange"
@ -396,14 +392,16 @@ onBeforeUnmount(() => {
display: flex; display: flex;
width: 100%; width: 100%;
justify-content: space-between; justify-content: space-between;
color: grey;
:deep(.table-page-content) { :deep(.table-page-content) {
button { button,
color: inherit; button[disabled] {
color: grey;
background: transparent !important; background: transparent !important;
} }
ul li { ul li {
&:not(.is-active) { &:not(.is-active) {
color: inherit; color: grey;
} }
background: transparent !important; background: transparent !important;
} }

View File

@ -270,8 +270,8 @@ const initTitle = () => {
} }
} }
const drillJump = index => { const drillJump = (index: number) => {
state.drillClickDimensionList = state.drillClickDimensionList.slice(0, index) state.drillClickDimensionList.splice(index)
view.value.chartExtRequest = filter() view.value.chartExtRequest = filter()
calcData(view.value) calcData(view.value)
} }

View File

@ -409,7 +409,7 @@ const emits = defineEmits(['finish'])
margin-bottom: 8px; margin-bottom: 8px;
} }
span { span {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
line-height: 22px; line-height: 22px;

View File

@ -374,7 +374,7 @@ defineExpose({
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item @click="addOperation('newLeaf', null, 'leaf', true)"> <el-dropdown-item @click="addOperation('newLeaf', null, 'leaf', true)">
<el-icon class="handle-icon"> <el-icon :class="`handle-icon color-${curCanvasType}`">
<Icon :name="dvSvgType"></Icon> <Icon :name="dvSvgType"></Icon>
</el-icon> </el-icon>
空白新建 空白新建
@ -427,7 +427,7 @@ defineExpose({
<el-icon style="font-size: 18px" v-else-if="curCanvasType === 'dashboard'"> <el-icon style="font-size: 18px" v-else-if="curCanvasType === 'dashboard'">
<Icon name="dv-dashboard-spine"></Icon> <Icon name="dv-dashboard-spine"></Icon>
</el-icon> </el-icon>
<el-icon class="icon-screen-new" style="font-size: 18px" v-else> <el-icon class="icon-screen-new color-dataV" style="font-size: 18px" v-else>
<Icon name="icon_operation-analysis_outlined"></Icon> <Icon name="icon_operation-analysis_outlined"></Icon>
</el-icon> </el-icon>
<span :title="node.label" class="label-tooltip">{{ node.label }}</span> <span :title="node.label" class="label-tooltip">{{ node.label }}</span>
@ -579,7 +579,6 @@ defineExpose({
} }
.icon-screen-new { .icon-screen-new {
background: #3370ff;
border-radius: 4px; border-radius: 4px;
color: #fff; color: #fff;
padding: 3px; padding: 3px;

View File

@ -33,7 +33,7 @@ const timestampFormatDate = value => {
<style lang="less" scoped> <style lang="less" scoped>
.info-card { .info-card {
font-family: 'PingFang SC'; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-style: normal; font-style: normal;
padding-left: 4px; padding-left: 4px;
font-weight: 400; font-weight: 400;

View File

@ -85,7 +85,6 @@ watch(
</el-popover> </el-popover>
</div> </div>
<div class="canvas-opt-button"> <div class="canvas-opt-button">
<!-- <el-button type="primary" @click="download()">导出</el-button>-->
<el-button @click="preview()"> <el-button @click="preview()">
<template #icon> <template #icon>
<icon name="icon_pc_outlined"></icon> <icon name="icon_pc_outlined"></icon>

View File

@ -15,7 +15,6 @@ import { XpackComponent } from '@/components/plugin'
import { logoutHandler } from '@/utils/logout' import { logoutHandler } from '@/utils/logout'
import DeImage from '@/assets/login-desc-de.png' import DeImage from '@/assets/login-desc-de.png'
import elementResizeDetectorMaker from 'element-resize-detector' import elementResizeDetectorMaker from 'element-resize-detector'
import PreheatImage from '@/assets/preheat.png'
import { isLarkPlatform } from '@/utils/utils' import { isLarkPlatform } from '@/utils/utils'
const { wsCache } = useCache() const { wsCache } = useCache()
const appStore = useAppStoreWithOut() const appStore = useAppStoreWithOut()
@ -145,16 +144,6 @@ const cleanPlatformFlag = () => {
} }
const preheat = ref(true) const preheat = ref(true)
const svg = `
<path class="path" d="
M 30 15
L 28 17
M 25.61 25.61
A 15 15, 0, 0, 1, 15 30
A 15 15, 0, 1, 1, 27.99 7.5
L 15 15
" style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
`
const showLoginErrorMsg = () => { const showLoginErrorMsg = () => {
if (!loginErrorMsg.value) { if (!loginErrorMsg.value) {
return return
@ -209,13 +198,9 @@ onMounted(() => {
ref="loginContainer" ref="loginContainer"
class="preheat-container" class="preheat-container"
v-loading="true" v-loading="true"
element-loading-text="Loading..." element-loading-text="登录中..."
:element-loading-spinner="svg" element-loading-background="#F5F6F7"
element-loading-svg-view-box="-10, -10, 50, 50" />
element-loading-background="rgba(122, 122, 122, 0.8)"
>
<el-image class="preheat-image" fit="cover" :src="PreheatImage" />
</div>
<div v-show="contentShow" class="login-background" v-loading="duringLogin"> <div v-show="contentShow" class="login-background" v-loading="duringLogin">
<div class="login-container" ref="loginContainer"> <div class="login-container" ref="loginContainer">
<div class="login-image-content" v-loading="!axiosFinished" v-if="showLoginImage"> <div class="login-image-content" v-loading="!axiosFinished" v-if="showLoginImage">
@ -354,10 +339,6 @@ onMounted(() => {
background: #000; background: #000;
position: absolute; position: absolute;
z-index: 100; z-index: 100;
.preheat-image {
width: 98%;
height: 98%;
}
} }
.login-background { .login-background {
background-color: #f5f7fa; background-color: #f5f7fa;
@ -426,7 +407,7 @@ onMounted(() => {
text-align: center; text-align: center;
margin-top: 8px; margin-top: 8px;
color: #646a73; color: #646a73;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
@ -464,7 +445,7 @@ onMounted(() => {
:deep(.ed-divider__text) { :deep(.ed-divider__text) {
color: #8f959e; color: #8f959e;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 12px; font-size: 12px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;

View File

@ -0,0 +1,140 @@
<script lang="ts" setup>
import { ref, reactive } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import { cloneDeep } from 'lodash-es'
import request from '@/config/axios'
import { rsaEncryp } from '@/utils/encryption'
import { ElMessage } from 'element-plus-secondary'
import { logoutHandler } from '@/utils/logout'
import { CustomPassword } from '@/components/custom-password'
const { t } = useI18n()
const defaultForm = {
pwd: '',
newPwd: '',
confirm: ''
}
const pwdForm = reactive(cloneDeep(defaultForm))
const validatePwd = (_: any, value: any, callback: any) => {
if (value === pwdForm.pwd) {
callback(new Error('新旧密码不能相同'))
}
const pattern =
/^.*(?=.{6,20})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[~!@#$%^&*()_+\-\={}|":<>?`[\];',.\/])[a-zA-Z0-9~!@#$%^&*()_+\-\={}|":<>?`[\];',.\/]*$/
const regep = new RegExp(pattern)
if (!regep.test(value)) {
const msg = t('user.pwd_pattern_error')
callback(new Error(msg))
} else {
callback()
}
}
const validateConfirmPwd = (_: any, value: any, callback: any) => {
if (value !== pwdForm.newPwd) {
callback(new Error('两次输入的密码不一致'))
} else {
callback()
}
}
const rule = {
pwd: [
{
required: true,
message: t('common.require'),
trigger: 'blur'
},
{
min: 6,
max: 20,
message: t('commons.input_limit', [6, 20]),
trigger: 'blur'
}
],
newPwd: [
{
required: true,
message: t('common.require'),
trigger: 'blur'
},
{ validator: validatePwd, trigger: 'blur' }
],
confirm: [
{
required: true,
message: t('common.require'),
trigger: 'blur'
},
{
min: 6,
max: 20,
message: t('commons.input_limit', [6, 20]),
trigger: 'blur'
},
{ validator: validateConfirmPwd, trigger: 'blur' }
]
}
const updatePwdForm = ref()
const save = () => {
updatePwdForm.value.validate(val => {
if (val) {
const pwd = rsaEncryp(pwdForm.pwd)
const newPwd = rsaEncryp(pwdForm.newPwd)
request.post({ url: '/user/modifyPwd', data: { pwd, newPwd } }).then(() => {
ElMessage.success('修改成功,请重新登录')
logoutHandler()
})
}
})
}
</script>
<template>
<el-form
ref="updatePwdForm"
require-asterisk-position="right"
:model="pwdForm"
:rules="rule"
class="mt16"
label-width="80px"
label-position="top"
>
<el-form-item label="原始密码" prop="pwd">
<CustomPassword
v-model="pwdForm.pwd"
show-password
type="password"
placeholder="请输入原始密码"
/>
</el-form-item>
<el-form-item label="新密码" prop="newPwd">
<CustomPassword
v-model="pwdForm.newPwd"
show-password
type="password"
placeholder="请输入新密码"
/>
</el-form-item>
<el-form-item label="确认密码" prop="confirm">
<CustomPassword
v-model="pwdForm.confirm"
show-password
type="password"
placeholder="请输入确认密码"
/>
</el-form-item>
<el-button style="margin-top: 12px" @click="save" type="primary">
{{ t('common.save') }}
</el-button>
</el-form>
</template>
<style lang="less" scoped>
.mt16 {
margin-top: 16px;
}
</style>

View File

@ -0,0 +1,198 @@
<template>
<div class="user-center flex-align-center">
<div class="user-center-container">
<div class="user-tabs">
<div class="tabs-title flex-align-center">用户中心</div>
<el-divider />
<div class="list-item_primary active">
{{ t('user.change_password') }}
</div>
</div>
<div class="user-info">
<div class="base-info">
<div class="info-title flex-align-center">
<span class="title">
{{ t('user.change_password') }}
</span>
</div>
<update-pwd />
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import UpdatePwd from './UpdatePwd.vue'
import { useI18n } from '@/hooks/web/useI18n'
const { t } = useI18n()
</script>
<style lang="less" scoped>
.user-center {
width: 100%;
flex-direction: column;
padding-top: 24px;
.user-center-container {
display: flex;
font-family: PingFang SC;
font-style: normal;
}
.user-tabs {
width: 200px;
height: 201px;
border-radius: 4px;
background: #fff;
padding: 16px;
.list-item_primary {
padding: 9px 8px;
}
.ed-divider {
margin: 4px 0;
border-color: rgba(31, 35, 41, 0.15);
}
.tabs-title {
padding-left: 8px;
color: #8d9199;
font-family: PingFang SC;
font-size: 14px;
font-style: normal;
font-weight: 500;
line-height: 22px;
height: 40px;
}
}
.user-info {
margin-left: 16px;
width: 864px;
height: 326px;
.base-info {
& + .base-info {
margin-top: 12px;
.bind-info {
margin-top: 16px;
display: flex;
align-items: center;
width: 100%;
padding: 16px 24px 16px 24px;
border-radius: 4px;
border: 1px solid #dee0e3;
.bind {
font-size: 48px;
margin-right: 12px;
}
.info {
font-family: PingFang SC;
font-style: normal;
font-weight: 400;
width: 80%;
.name {
color: #1f2329;
font-size: 16px;
line-height: 24px;
font-weight: 500;
width: 100%;
}
.tip {
color: #646a73;
font-size: 14px;
line-height: 22px;
max-width: 600px;
white-space: pre-wrap;
}
}
.delete {
margin-left: auto;
}
}
}
padding: 20px 24px 24px 24px;
border-radius: 4px;
background: #fff;
.role {
& + .role {
margin-left: 4px;
}
display: inline-flex;
height: 20px;
padding: 0 6px;
align-items: center;
font-size: 12px;
color: #2b5fd9;
border-radius: 2px;
background: rgba(51, 112, 255, 0.2);
}
.info-title {
.ed-button {
margin-left: auto;
}
.title {
color: #1f2329;
font-size: 16px;
font-weight: 500;
line-height: 24px;
}
}
}
}
.base-info-item {
margin-top: 16px;
font-size: 14px;
font-weight: 400;
line-height: 22px;
width: 100%;
.label {
color: #646a73;
}
.value {
margin-top: 4px;
color: #1f2329;
}
}
.mr12 {
margin-top: 12px;
}
}
</style>
<style lang="less">
.qr-code-dialog {
font-family: PingFang SC;
font-style: normal;
.ed-dialog__body {
display: flex;
flex-direction: column;
align-items: center;
}
.qr-code-img {
margin-top: 16px;
display: inline-block;
padding: 8px 12px;
img {
width: 184px;
height: 184px;
}
border-radius: 8px;
border: 1px solid #bbbfc4;
}
.refresh-login {
margin: 0 auto;
margin-top: 9px;
color: #646a73;
font-size: 14px;
font-weight: 400;
line-height: 22px;
.ed-icon {
margin-left: 4px;
}
}
}
</style>

View File

@ -44,6 +44,20 @@ const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return if (!formEl) return
await formEl.validate(valid => { await formEl.validate(valid => {
if (valid) { if (valid) {
if (
state.form.dsExecuteTime === 'minute' &&
(Number(state.form.dsIntervalTime) < 1 || Number(state.form.dsIntervalTime) > 59)
) {
ElMessage.error('分钟超出范围【1-59】')
return
}
if (
state.form.dsExecuteTime === 'hour' &&
(Number(state.form.dsIntervalTime) < 1 || Number(state.form.dsIntervalTime) > 23)
) {
ElMessage.error('小时超出范围【1-23】')
return
}
const param = buildSettingList() const param = buildSettingList()
if (param.length < 2) { if (param.length < 2) {
return return
@ -153,34 +167,6 @@ defineExpose({
</div> </div>
<div v-else /> <div v-else />
</el-form-item> </el-form-item>
<!-- <el-form-item label="禁止扫码创建用户" prop="autoCreateUser">
<el-switch v-model="state.form.autoCreateUser" />
</el-form-item> -->
<!-- <el-form-item label="数据源检测时间间隔" prop="dsIntervalTime">
<div class="ds-task-form-inline">
<span></span>
<el-input-number
v-model="state.form.dsIntervalTime"
autocomplete="off"
step-strictly
class="text-left"
:min="1"
:placeholder="t('common.inputText')"
controls-position="right"
type="number"
/>
<el-select v-model="state.form.dsExecuteTime">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<span class="ds-span">执行一次</span>
</div>
</el-form-item> -->
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">

View File

@ -139,7 +139,7 @@ defineExpose({
} }
.pwd { .pwd {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
line-height: 22px; line-height: 22px;
@ -158,7 +158,7 @@ defineExpose({
padding: 0 20px; padding: 0 20px;
color: #1f2329; color: #1f2329;
text-align: center; text-align: center;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;

View File

@ -7,7 +7,6 @@
<div class="container-sys-param"> <div class="container-sys-param">
<map-setting v-if="activeName === 'map'" /> <map-setting v-if="activeName === 'map'" />
<basic-info v-if="activeName === 'basic'" /> <basic-info v-if="activeName === 'basic'" />
<!-- <email-info v-if="activeName === 'email'" /> -->
</div> </div>
</div> </div>
</template> </template>
@ -32,7 +31,7 @@ const activeName = ref('basic')
.router-title { .router-title {
color: #1f2329; color: #1f2329;
font-feature-settings: 'clig' off, 'liga' off; font-feature-settings: 'clig' off, 'liga' off;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 20px; font-size: 20px;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;

View File

@ -40,6 +40,7 @@
<template #default="{ node, data }"> <template #default="{ node, data }">
<span class="custom-tree-node" :class="{ 'is-disabled': node.disabled || data.root }"> <span class="custom-tree-node" :class="{ 'is-disabled': node.disabled || data.root }">
<span <span
class="geo-name-span"
:title="data.name" :title="data.name"
v-html="data.colorName && keyword ? data.colorName : data.name" v-html="data.colorName && keyword ? data.colorName : data.name"
/> />
@ -304,14 +305,19 @@ loadTreeData(true)
padding-right: 4px; padding-right: 4px;
overflow: hidden; overflow: hidden;
justify-content: space-between; justify-content: space-between;
.geo-name-span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.geo-operate-container { .geo-operate-container {
display: none; display: none;
} }
&:hover { &:hover {
.geo-operate-container { .geo-operate-container {
display: contents; display: inline-flex;
padding-left: 4px;
} }
} }
} }

View File

@ -17,12 +17,12 @@ const dialogVisible = ref(false)
const loadingInstance = ref(null) const loadingInstance = ref(null)
const geoForm = ref<FormInstance>() const geoForm = ref<FormInstance>()
const geoFile = ref() const geoFile = ref()
const fileName = ref()
const state = reactive({ const state = reactive({
form: reactive<GeometryFrom>({ form: reactive<GeometryFrom>({
pid: null, pid: null,
code: null, code: null,
name: null name: null,
fileName: null
}), }),
treeData: [] treeData: []
}) })
@ -53,6 +53,13 @@ const rule = reactive<FormRules>({
message: t('common.require'), message: t('common.require'),
trigger: 'blur' trigger: 'blur'
} }
],
fileName: [
{
required: true,
message: t('common.require'),
trigger: 'blur'
}
] ]
}) })
@ -63,7 +70,7 @@ const edit = (pid?: string) => {
state.form.code = null state.form.code = null
state.form.name = null state.form.name = null
geoFile.value = null geoFile.value = null
fileName.value = null state.form.fileName = null
dialogVisible.value = true dialogVisible.value = true
} }
@ -71,7 +78,7 @@ const emits = defineEmits(['saved'])
const submitForm = async (formEl: FormInstance | undefined) => { const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return if (!formEl) return
await formEl.validate((valid, fields) => { await formEl.validate(valid => {
if (valid) { if (valid) {
const param = { ...state.form } const param = { ...state.form }
const formData = buildFormData(geoFile.value, param) const formData = buildFormData(geoFile.value, param)
@ -96,7 +103,6 @@ const submitForm = async (formEl: FormInstance | undefined) => {
const resetForm = (formEl: FormInstance | undefined) => { const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return if (!formEl) return
geoFile.value = null geoFile.value = null
fileName.value = null
formEl.resetFields() formEl.resetFields()
dialogVisible.value = false dialogVisible.value = false
} }
@ -119,7 +125,7 @@ const handleError = () => {
} }
const setFile = (options: UploadRequestOptions) => { const setFile = (options: UploadRequestOptions) => {
geoFile.value = options.file geoFile.value = options.file
fileName.value = options.file.name state.form.fileName = options.file.name
} }
const uploadValidate = file => { const uploadValidate = file => {
const suffix = file.name.substring(file.name.lastIndexOf('.') + 1) const suffix = file.name.substring(file.name.lastIndexOf('.') + 1)
@ -185,7 +191,7 @@ defineExpose({
</el-form-item> </el-form-item>
<div class="geo-label-mask" /> <div class="geo-label-mask" />
<el-form-item label="坐标文件"> <el-form-item label="坐标文件" prop="fileName">
<el-upload <el-upload
class="upload-geo" class="upload-geo"
action="" action=""
@ -196,14 +202,18 @@ defineExpose({
:show-file-list="false" :show-file-list="false"
:http-request="setFile" :http-request="setFile"
> >
<el-input :placeholder="t('userimport.placeholder')" readonly v-model="fileName"> <el-input
:placeholder="t('userimport.placeholder')"
readonly
v-model="state.form.fileName"
>
<template #suffix> <template #suffix>
<el-icon> <el-icon>
<Icon name="icon_upload_outlined" /> <Icon name="icon_upload_outlined" />
</el-icon> </el-icon>
</template> </template>
<template #prefix> <template #prefix>
<el-icon v-if="!!fileName"> <el-icon v-if="!!state.form.fileName">
<Icon name="de-json" /> <Icon name="de-json" />
</el-icon> </el-icon>
</template> </template>

View File

@ -2,4 +2,5 @@ export interface GeometryFrom {
pid?: string pid?: string
code?: string code?: string
name?: string name?: string
fileName?: string
} }

View File

@ -371,7 +371,7 @@ onMounted(() => {
.insert-filter { .insert-filter {
display: inline-block; display: inline-block;
font-weight: 400 !important; font-weight: 400 !important;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
line-height: 1; line-height: 1;
white-space: nowrap; white-space: nowrap;
cursor: pointer; cursor: pointer;
@ -400,7 +400,7 @@ onMounted(() => {
.insert { .insert {
display: inline-block; display: inline-block;
font-weight: 400 !important; font-weight: 400 !important;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
line-height: 1; line-height: 1;
white-space: nowrap; white-space: nowrap;
cursor: pointer; cursor: pointer;

View File

@ -492,7 +492,7 @@ onMounted(() => {
.insert-filter { .insert-filter {
display: inline-block; display: inline-block;
font-weight: 400 !important; font-weight: 400 !important;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
line-height: 1; line-height: 1;
white-space: nowrap; white-space: nowrap;
cursor: pointer; cursor: pointer;
@ -525,7 +525,7 @@ onMounted(() => {
display: inline-block; display: inline-block;
font-size: 34px; font-size: 34px;
font-weight: 400 !important; font-weight: 400 !important;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
line-height: 1; line-height: 1;
white-space: nowrap; white-space: nowrap;
cursor: pointer; cursor: pointer;

View File

@ -14,10 +14,10 @@
{{ template.title }} {{ template.title }}
</el-row> </el-row>
<el-row class="template-button"> <el-row class="template-button">
<el-button size="mini" style="width: 100px" @click="templateInnerPreview">{{ <el-button size="mini" style="width: calc(50% - 18px)" @click="templateInnerPreview">{{
t('visualization.preview') t('visualization.preview')
}}</el-button> }}</el-button>
<el-button size="mini" style="width: 100px" type="primary" @click="apply">{{ <el-button size="mini" style="width: calc(50% - 18px)" type="primary" @click="apply">{{
t('visualization.apply') t('visualization.apply')
}}</el-button> }}</el-button>
</el-row> </el-row>

View File

@ -148,7 +148,7 @@ const handleCommand = key => {
.de-model-text { .de-model-text {
margin-left: 8px; margin-left: 8px;
font-family: 'PingFang SC'; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;

View File

@ -153,7 +153,7 @@ defineExpose({
align-items: center; align-items: center;
border-radius: 4px; border-radius: 4px;
color: var(--deTextPrimary, #1f2329); color: var(--deTextPrimary, #1f2329);
font-family: 'PingFang SC'; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
font-size: 14px; font-size: 14px;

View File

@ -592,7 +592,7 @@ onMounted(() => {
.active-template { .active-template {
height: 56px; height: 56px;
padding: 0px 24px; padding: 0px 24px;
font-family: 'PingFang SC'; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
font-size: 16px; font-size: 16px;
@ -618,7 +618,7 @@ onMounted(() => {
.router-title { .router-title {
color: #1f2329; color: #1f2329;
font-feature-settings: 'clig' off, 'liga' off; font-feature-settings: 'clig' off, 'liga' off;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 20px; font-size: 20px;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;

View File

@ -36,7 +36,7 @@ const { t } = useI18n()
<style lang="less" scoped> <style lang="less" scoped>
.info-card { .info-card {
font-family: 'PingFang SC'; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-style: normal; font-style: normal;
padding-left: 4px; padding-left: 4px;
font-weight: 400; font-weight: 400;

View File

@ -149,7 +149,7 @@ const del = (index, child) => {
z-index: 10; z-index: 10;
.operate-title { .operate-title {
font-family: PingFang SC, Hiragino Sans GB, Microsoft YaHei, sans-serif; font-family: '阿里巴巴普惠体 3.0 55 Regular L3', Hiragino Sans GB, Microsoft YaHei, sans-serif;
word-wrap: break-word; word-wrap: break-word;
box-sizing: border-box; box-sizing: border-box;
color: rgba(0, 0, 0, 0.65); color: rgba(0, 0, 0, 0.65);

View File

@ -553,7 +553,7 @@ const emits = defineEmits(['update:item', 'del'])
} }
.bottom-line { .bottom-line {
font-family: PingFang SC, Hiragino Sans GB, Microsoft YaHei, sans-serif; font-family: '阿里巴巴普惠体 3.0 55 Regular L3', Hiragino Sans GB, Microsoft YaHei, sans-serif;
font-variant: tabular-nums; font-variant: tabular-nums;
font-feature-settings: 'tnum'; font-feature-settings: 'tnum';
word-wrap: break-word; word-wrap: break-word;
@ -601,7 +601,7 @@ const emits = defineEmits(['update:item', 'del'])
border-radius: 0; border-radius: 0;
box-shadow: none; box-shadow: none;
height: 26px; height: 26px;
font-family: PingFang SC, Hiragino Sans GB, Microsoft YaHei, sans-serif; font-family: '阿里巴巴普惠体 3.0 55 Regular L3', Hiragino Sans GB, Microsoft YaHei, sans-serif;
word-wrap: break-word; word-wrap: break-word;
text-align: left; text-align: left;
color: rgba(0, 0, 0, 0.65); color: rgba(0, 0, 0, 0.65);
@ -714,8 +714,8 @@ const emits = defineEmits(['update:item', 'del'])
} }
.ed-input { .ed-input {
font-family: Alibaba-PuHuiTi-Regular, Helvetica Neue, Helvetica, Arial, PingFang SC, font-family: Alibaba-PuHuiTi-Regular, Helvetica Neue, Helvetica, Arial,
Hiragino Sans GB, Microsoft YaHei, sans-serif; '阿里巴巴普惠体 3.0 55 Regular L3', Hiragino Sans GB, Microsoft YaHei, sans-serif;
box-sizing: border-box; box-sizing: border-box;
margin: 0; margin: 0;
color: rgba(0, 0, 0, 0.65); color: rgba(0, 0, 0, 0.65);
@ -748,7 +748,7 @@ const emits = defineEmits(['update:item', 'del'])
box-shadow: none; box-shadow: none;
border: 1px solid rgba(0, 0, 0, 0.05); border: 1px solid rgba(0, 0, 0, 0.05);
.mod-left { .mod-left {
font-family: PingFang SC, Hiragino Sans GB, Microsoft YaHei, sans-serif; font-family: '阿里巴巴普惠体 3.0 55 Regular L3', Hiragino Sans GB, Microsoft YaHei, sans-serif;
color: rgba(0, 0, 0, 0.65); color: rgba(0, 0, 0, 0.65);
font-size: 12px; font-size: 12px;
vertical-align: top; vertical-align: top;
@ -794,7 +794,7 @@ const emits = defineEmits(['update:item', 'del'])
border-left: 1px solid hsla(0, 0%, 59%, 0.1); border-left: 1px solid hsla(0, 0%, 59%, 0.1);
} }
.autochecker-list { .autochecker-list {
font-family: PingFang SC, Hiragino Sans GB, Microsoft YaHei, sans-serif; font-family: '阿里巴巴普惠体 3.0 55 Regular L3', Hiragino Sans GB, Microsoft YaHei, sans-serif;
color: rgba(0, 0, 0, 0.65); color: rgba(0, 0, 0, 0.65);
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
@ -839,7 +839,8 @@ const emits = defineEmits(['update:item', 'del'])
} }
label { label {
font-family: PingFang SC, Hiragino Sans GB, Microsoft YaHei, sans-serif; font-family: '阿里巴巴普惠体 3.0 55 Regular L3', Hiragino Sans GB, Microsoft YaHei,
sans-serif;
font-size: 12px; font-size: 12px;
direction: ltr; direction: ltr;
color: #333; color: #333;

View File

@ -858,7 +858,7 @@ const mousedownDrag = () => {
height: 100%; height: 100%;
width: 240px; width: 240px;
float: left; float: left;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
border-right: 1px solid rgba(31, 35, 41, 0.15); border-right: 1px solid rgba(31, 35, 41, 0.15);
.list-item_primary { .list-item_primary {
@ -960,7 +960,7 @@ const mousedownDrag = () => {
float: right; float: right;
height: calc(100vh - 156px); height: calc(100vh - 156px);
.sql-result { .sql-result {
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
overflow-y: auto; overflow-y: auto;
box-sizing: border-box; box-sizing: border-box;
@ -1122,7 +1122,7 @@ const mousedownDrag = () => {
.sql-tips { .sql-tips {
color: #646a73; color: #646a73;
text-align: center; text-align: center;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
@ -1146,7 +1146,7 @@ const mousedownDrag = () => {
.num { .num {
margin-left: auto; margin-left: auto;
color: #646a73; color: #646a73;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
@ -1235,7 +1235,7 @@ const mousedownDrag = () => {
background: #e1eaff; background: #e1eaff;
position: relative; position: relative;
padding: 9px 0 9px 40px; padding: 9px 0 9px 40px;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;

View File

@ -498,7 +498,7 @@ initFunction()
& > :nth-child(2) { & > :nth-child(2) {
margin: 0 -0.67px 0 2px; margin: 0 -0.67px 0 2px;
color: #f54a45; color: #f54a45;
font-family: PingFang SC; font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;

Some files were not shown because too many files have changed in this diff Show More