Merge branch 'dev' into pr@dev@feat_relationship_analyze
@ -48,6 +48,9 @@ DataEase 是开源的数据可视化分析工具,帮助用户快速分析数
|
||||
<img src="https://dataease.io/images/dataSource/TiDB.jpg" alt="TiDB" border="0" width="155" height="107"/>
|
||||
<img src="https://dataease.io/images/dataSource/StarRocks.jpg" alt="StarRocks" border="0" width="155" height="107"/>
|
||||
<img src="https://dataease.io/images/dataSource/PrestoDB.jpg" alt="PrestoDB" border="0" width="155" height="107"/>
|
||||
<img src="https://dataease.io/images/dataSource/dm.jpg" alt="dm" border="0" width="155" height="107"/>
|
||||
<img src="https://dataease.io/images/dataSource/kingbase.jpg" alt="KingBase" border="0" width="155" height="107"/>
|
||||
<img src="https://dataease.io/images/dataSource/kylin.jpg" alt="Kylin" border="0" width="180" height="107"/>
|
||||
</p>
|
||||
|
||||
> 更多数据源支持持续增加中...
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package io.dataease.auth.filter;
|
||||
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import io.dataease.auth.entity.ASKToken;
|
||||
import io.dataease.auth.entity.JWTToken;
|
||||
@ -24,10 +23,8 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
|
||||
public class JWTFilter extends BasicHttpAuthenticationFilter {
|
||||
@ -161,18 +158,4 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
|
||||
httpServletResponse.setHeader("authentication-status", "login_expire");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onAccessDenied(ServletRequest req, ServletResponse res, Object mappedValue) throws Exception {
|
||||
HttpServletResponse response = (HttpServletResponse) res;
|
||||
HttpServletRequest request = (HttpServletRequest) req;
|
||||
String requestURI = request.getRequestURI();
|
||||
String msg = requestURI + " has been denied";
|
||||
String encode = URLUtil.encode(msg, Charset.forName("UTF-8"));
|
||||
Cookie cookie_error = new Cookie("onAccessDeniedMsg", encode);
|
||||
cookie_error.setPath("/");
|
||||
response.addCookie(cookie_error);
|
||||
response.sendRedirect("/");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -20,9 +20,9 @@ public class PanelConstants {
|
||||
|
||||
public final static String PANEL_NODE_TYPE_PANEL = "panel";
|
||||
|
||||
public final static String OPT_TYPE_INSERT="insert";
|
||||
public final static String OPT_TYPE_INSERT = "insert";
|
||||
|
||||
public final static String OPT_TYPE_UPDATE="update";
|
||||
public final static String OPT_TYPE_UPDATE = "update";
|
||||
|
||||
public final static String PANEL_GATHER_DEFAULT_PANEL = "default_panel";
|
||||
|
||||
@ -68,4 +68,16 @@ public class PanelConstants {
|
||||
|
||||
}
|
||||
|
||||
|
||||
//应用数据源来源
|
||||
public static final class APP_DATASOURCE_FROM {
|
||||
|
||||
// 新建
|
||||
public static final String NEW = "new";
|
||||
|
||||
// 复用
|
||||
public static final String HISTORY = "history";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package io.dataease.commons.utils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class IPUtils {
|
||||
@ -42,4 +43,12 @@ public class IPUtils {
|
||||
ipStr = Arrays.stream(ipStr.split(",")).filter(item -> StringUtils.isNotBlank(item) && !StringUtils.equalsIgnoreCase(UNKNOWN, item.trim())).findFirst().orElse(ipStr);
|
||||
return StringUtils.equals(LOCAL_IP_KEY, ipStr) ? LOCAL_IP_VAL : ipStr;
|
||||
}
|
||||
|
||||
public static String domain() {
|
||||
try {
|
||||
return InetAddress.getLocalHost().getHostAddress();
|
||||
} catch (Exception e) {
|
||||
return LOCAL_IP_VAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,6 +247,12 @@ public class DataSetTableController {
|
||||
return dataSetTableService.paramsWithIds(type, viewIds);
|
||||
}
|
||||
|
||||
@ApiOperation("数据集的SQL变量")
|
||||
@PostMapping("/params/{id}/{type}")
|
||||
List<SqlVariableDetails> paramsWithIds(@PathVariable String type, @PathVariable String id) {
|
||||
return dataSetTableService.datasetParams(type, id);
|
||||
}
|
||||
|
||||
@ApiOperation("根据数据集文件夹ID查询数据集名称")
|
||||
@PostMapping("/getDatasetNameFromGroup/{sceneId}")
|
||||
public List<String> getDatasetNameFromGroup(@PathVariable String sceneId) {
|
||||
|
||||
@ -200,6 +200,7 @@ public class DataSetTableFieldController {
|
||||
|
||||
}
|
||||
List<Object> list = results.stream().distinct().collect(Collectors.toList());
|
||||
list = dataSetFieldService.chineseSort(list, multFieldValuesRequest.getSort());
|
||||
return list;
|
||||
}
|
||||
|
||||
@ -246,7 +247,7 @@ public class DataSetTableFieldController {
|
||||
@DePermission(type = DePermissionType.DATASET)
|
||||
@ApiOperation("时间格式")
|
||||
@PostMapping("dateformats/{tableId}")
|
||||
public List<Dateformat> dateformats(@PathVariable String tableId) throws Exception{
|
||||
public List<Dateformat> dateformats(@PathVariable String tableId) throws Exception {
|
||||
DatasetTable datasetTable = dataSetTableService.get(tableId);
|
||||
Datasource ds = datasetTable.getMode() == 0 ? datasourceService.get(datasetTable.getDataSourceId()) : engineService.getDeEngine();
|
||||
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
|
||||
|
||||
@ -19,7 +19,6 @@ import io.dataease.plugins.common.base.domain.Datasource;
|
||||
import io.dataease.service.datasource.DatasourceService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -49,10 +48,24 @@ public class DatasourceController {
|
||||
positionIndex = 0, positionKey = "type",
|
||||
value = "id"
|
||||
)
|
||||
public Datasource addDatasource(@RequestBody Datasource datasource) throws Exception {
|
||||
public Datasource addDatasource(@RequestBody DatasourceDTO datasource) throws Exception {
|
||||
return datasourceService.addDatasource(datasource);
|
||||
}
|
||||
|
||||
@RequiresPermissions("datasource:read")
|
||||
@DePermission(type = DePermissionType.DATASOURCE, value = "id", level = ResourceAuthLevel.DATASOURCE_LEVEL_MANAGE)
|
||||
@ApiOperation("更新数据源")
|
||||
@PostMapping("/update")
|
||||
@DeLog(
|
||||
operatetype = SysLogConstants.OPERATE_TYPE.MODIFY,
|
||||
sourcetype = SysLogConstants.SOURCE_TYPE.DATASOURCE,
|
||||
positionIndex = 0, positionKey = "type",
|
||||
value = "id"
|
||||
)
|
||||
public void updateDatasource(@RequestBody UpdataDsRequest dsRequest) throws Exception {
|
||||
datasourceService.updateDatasource(dsRequest);
|
||||
}
|
||||
|
||||
@RequiresPermissions("datasource:read")
|
||||
@ApiOperation("数据源类型")
|
||||
@GetMapping("/types")
|
||||
@ -62,7 +75,7 @@ public class DatasourceController {
|
||||
|
||||
@ApiIgnore
|
||||
@PostMapping("/validate")
|
||||
public ResultHolder validate(@RequestBody Datasource datasource) throws Exception {
|
||||
public ResultHolder validate(@RequestBody DatasourceDTO datasource) throws Exception {
|
||||
return datasourceService.validate(datasource);
|
||||
}
|
||||
|
||||
@ -107,20 +120,6 @@ public class DatasourceController {
|
||||
return resultHolder;
|
||||
}
|
||||
|
||||
@RequiresPermissions("datasource:read")
|
||||
@DePermission(type = DePermissionType.DATASOURCE, value = "id", level = ResourceAuthLevel.DATASOURCE_LEVEL_MANAGE)
|
||||
@ApiOperation("更新数据源")
|
||||
@PostMapping("/update")
|
||||
@DeLog(
|
||||
operatetype = SysLogConstants.OPERATE_TYPE.MODIFY,
|
||||
sourcetype = SysLogConstants.SOURCE_TYPE.DATASOURCE,
|
||||
positionIndex = 0, positionKey = "type",
|
||||
value = "id"
|
||||
)
|
||||
public void updateDatasource(@RequestBody UpdataDsRequest dsRequest) throws Exception {
|
||||
datasourceService.updateDatasource(dsRequest);
|
||||
}
|
||||
|
||||
@DePermission(type = DePermissionType.DATASOURCE)
|
||||
@ApiOperation("查询数据源下属所有表")
|
||||
@PostMapping("/getTables/{id}")
|
||||
@ -130,7 +129,7 @@ public class DatasourceController {
|
||||
|
||||
@ApiIgnore
|
||||
@PostMapping("/getSchema")
|
||||
public List<String> getSchema(@RequestBody Datasource datasource) throws Exception {
|
||||
public List<String> getSchema(@RequestBody DatasourceDTO datasource) throws Exception {
|
||||
return datasourceService.getSchema(datasource);
|
||||
}
|
||||
|
||||
|
||||
@ -15,4 +15,5 @@ public class UpdataDsRequest {
|
||||
private String type;
|
||||
@ApiModelProperty(value = "配置详情", required = true)
|
||||
private String configuration;
|
||||
private boolean configurationEncryption = false;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package io.dataease.controller.request.panel;
|
||||
|
||||
import io.dataease.plugins.common.base.domain.Datasource;
|
||||
import io.dataease.dto.DatasourceDTO;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
@ -29,5 +29,9 @@ public class PanelAppTemplateApplyRequest {
|
||||
|
||||
private String appTemplateId;
|
||||
|
||||
private List<Datasource> datasourceList;
|
||||
private String datasourceFrom;
|
||||
|
||||
private String datasourceHistoryId;
|
||||
|
||||
private List<DatasourceDTO> datasourceList;
|
||||
}
|
||||
|
||||
@ -19,6 +19,8 @@ public class DatasourceDTO extends Datasource {
|
||||
@ApiModelProperty("权限")
|
||||
private String privileges;
|
||||
private List<ApiDefinition> apiConfiguration;
|
||||
private String apiConfigurationStr;
|
||||
private String typeDesc;
|
||||
private DatasourceCalculationMode calculationMode;
|
||||
private boolean isConfigurationEncryption = false;
|
||||
}
|
||||
|
||||
@ -16,40 +16,42 @@
|
||||
</resultMap>
|
||||
<select id="query" parameterType="io.dataease.service.panel.applog.AppLogQueryParam" resultMap="BaseResultMapDTO">
|
||||
select
|
||||
logInfo.*,
|
||||
get_auths(logInfo.dataset_group_id,'dataset',#{userId}) as `dataset_privileges`,
|
||||
get_auths(logInfo.panel_id,'panel',#{userId}) as `panel_privileges`,
|
||||
get_auths(logInfo.datasource_id,'link',#{userId}) as `datasource_privileges`
|
||||
from
|
||||
logInfo.*,
|
||||
get_auths(logInfo.dataset_group_id,'dataset',#{userId}) as `dataset_privileges`,
|
||||
get_auths(logInfo.panel_id,'panel',#{userId}) as `panel_privileges`,
|
||||
get_auths(logInfo.datasource_id,'link',#{userId}) as `datasource_privileges`
|
||||
from
|
||||
(select * from
|
||||
(SELECT
|
||||
panel_app_template_log.id,
|
||||
panel_app_template_log.app_template_id,
|
||||
panel_app_template_log.app_template_name,
|
||||
datasource.id as datasource_id,
|
||||
panel_app_template_log.source_datasource_name,
|
||||
dataset_group.id as dataset_group_id,
|
||||
panel_app_template_log.source_dataset_group_name,
|
||||
panel_group.id as panel_id,
|
||||
panel_app_template_log.source_panel_name,
|
||||
panel_app_template_log.apply_time,
|
||||
panel_app_template_log.apply_persion,
|
||||
panel_app_template_log.is_success,
|
||||
panel_app_template_log.remark,
|
||||
panel_group.pid as panel_group_pid,
|
||||
datasource.type as datasource_type,
|
||||
dataset_group.pid as dataset_group_pid,
|
||||
IFNULL(panel_app_template.name,CONCAT(panel_app_template_log.app_template_name,'(Deleted)')) as app_name,
|
||||
IFNULL(panel_group.name,CONCAT(panel_app_template_log.source_panel_name,'(Deleted)')) as panel_name,
|
||||
IFNULL(dataset_group.name,CONCAT(panel_app_template_log.source_dataset_group_name,'(Deleted)')) as dataset_group_name,
|
||||
IFNULL(datasource.`name`,CONCAT(panel_app_template_log.source_datasource_name,'(Deleted)')) as datasource_name
|
||||
FROM
|
||||
panel_app_template_log
|
||||
LEFT JOIN panel_group ON panel_app_template_log.panel_id = panel_group.id
|
||||
left join dataset_group on panel_app_template_log.dataset_group_id = dataset_group.id
|
||||
left join datasource on panel_app_template_log.datasource_id = datasource.id
|
||||
left join panel_app_template on panel_app_template_log.app_template_id = panel_app_template.id
|
||||
) t
|
||||
(SELECT
|
||||
panel_app_template_log.id,
|
||||
panel_app_template_log.app_template_id,
|
||||
panel_app_template_log.app_template_name,
|
||||
datasource.id as datasource_id,
|
||||
panel_app_template_log.source_datasource_name,
|
||||
panel_app_template_log.datasource_from,
|
||||
dataset_group.id as dataset_group_id,
|
||||
panel_app_template_log.source_dataset_group_name,
|
||||
panel_group.id as panel_id,
|
||||
panel_app_template_log.source_panel_name,
|
||||
panel_app_template_log.apply_time,
|
||||
panel_app_template_log.apply_persion,
|
||||
panel_app_template_log.is_success,
|
||||
panel_app_template_log.remark,
|
||||
panel_group.pid as panel_group_pid,
|
||||
datasource.type as datasource_type,
|
||||
dataset_group.pid as dataset_group_pid,
|
||||
IFNULL(panel_app_template.name,CONCAT(panel_app_template_log.app_template_name,'(Deleted)')) as app_name,
|
||||
IFNULL(panel_group.name,CONCAT(panel_app_template_log.source_panel_name,'(Deleted)')) as panel_name,
|
||||
IFNULL(dataset_group.name,CONCAT(panel_app_template_log.source_dataset_group_name,'(Deleted)')) as
|
||||
dataset_group_name,
|
||||
IFNULL(datasource.`name`,CONCAT(panel_app_template_log.source_datasource_name,'(Deleted)')) as datasource_name
|
||||
FROM
|
||||
panel_app_template_log
|
||||
LEFT JOIN panel_group ON panel_app_template_log.panel_id = panel_group.id
|
||||
left join dataset_group on panel_app_template_log.dataset_group_id = dataset_group.id
|
||||
left join datasource on panel_app_template_log.datasource_id = datasource.id
|
||||
left join panel_app_template on panel_app_template_log.app_template_id = panel_app_template.id
|
||||
) t
|
||||
where 1=1
|
||||
<if test="extendCondition != null">
|
||||
and
|
||||
|
||||
@ -8,14 +8,11 @@
|
||||
<result column="privileges" property="privileges"/>
|
||||
</resultMap>
|
||||
|
||||
<select id ="findByPanelId" resultMap="BaseResultMapDTO">
|
||||
SELECT
|
||||
chart_view.*
|
||||
FROM
|
||||
chart_view
|
||||
LEFT JOIN panel_view ON chart_view.id = panel_view.chart_view_id
|
||||
WHERE
|
||||
panel_view.panel_id = #{panelId}
|
||||
<select id="findByPanelId" resultMap="BaseResultMapDTO">
|
||||
SELECT chart_view.*
|
||||
FROM chart_view
|
||||
LEFT JOIN panel_view ON chart_view.id = panel_view.chart_view_id
|
||||
WHERE panel_view.panel_id = #{panelId}
|
||||
</select>
|
||||
|
||||
<select id="searchOneWithPrivileges" resultMap="BaseResultMapDTO">
|
||||
@ -25,198 +22,210 @@
|
||||
</select>
|
||||
|
||||
<select id="searchOne" resultMap="BaseResultMapDTO">
|
||||
select
|
||||
chart_view.*
|
||||
from chart_view where id = #{id}
|
||||
select chart_view.*
|
||||
from chart_view
|
||||
where id = #{id}
|
||||
</select>
|
||||
|
||||
<insert id="copyToCache">
|
||||
INSERT INTO chart_view_cache (
|
||||
id,
|
||||
`name`,
|
||||
title,
|
||||
scene_id,
|
||||
table_id,
|
||||
`type`,
|
||||
render,
|
||||
result_count,
|
||||
result_mode,
|
||||
create_by,
|
||||
create_time,
|
||||
update_time,
|
||||
style_priority,
|
||||
chart_type,
|
||||
is_plugin,
|
||||
x_axis,
|
||||
x_axis_ext,
|
||||
y_axis,
|
||||
y_axis_ext,
|
||||
ext_stack,
|
||||
ext_bubble,
|
||||
custom_attr,
|
||||
custom_style,
|
||||
custom_filter,
|
||||
drill_fields,
|
||||
senior,
|
||||
SNAPSHOT,
|
||||
data_from
|
||||
) SELECT
|
||||
id,
|
||||
`name`,
|
||||
title,
|
||||
scene_id,
|
||||
table_id,
|
||||
`type`,
|
||||
render,
|
||||
result_count,
|
||||
result_mode,
|
||||
create_by,
|
||||
create_time,
|
||||
update_time,
|
||||
style_priority,
|
||||
chart_type,
|
||||
is_plugin,
|
||||
x_axis,
|
||||
x_axis_ext,
|
||||
y_axis,
|
||||
y_axis_ext,
|
||||
ext_stack,
|
||||
ext_bubble,
|
||||
custom_attr,
|
||||
custom_style,
|
||||
custom_filter,
|
||||
drill_fields,
|
||||
senior,
|
||||
SNAPSHOT,
|
||||
data_from from chart_view
|
||||
WHERE
|
||||
chart_view.id = #{id}
|
||||
INSERT INTO chart_view_cache (id,
|
||||
`name`,
|
||||
title,
|
||||
scene_id,
|
||||
table_id,
|
||||
`type`,
|
||||
render,
|
||||
result_count,
|
||||
result_mode,
|
||||
create_by,
|
||||
create_time,
|
||||
update_time,
|
||||
style_priority,
|
||||
chart_type,
|
||||
is_plugin,
|
||||
x_axis,
|
||||
x_axis_ext,
|
||||
y_axis,
|
||||
y_axis_ext,
|
||||
ext_stack,
|
||||
ext_bubble,
|
||||
custom_attr,
|
||||
custom_style,
|
||||
custom_filter,
|
||||
drill_fields,
|
||||
senior,
|
||||
SNAPSHOT,
|
||||
data_from,
|
||||
refresh_view_enable,
|
||||
refresh_unit,
|
||||
refresh_time)
|
||||
SELECT id,
|
||||
`name`,
|
||||
title,
|
||||
scene_id,
|
||||
table_id,
|
||||
`type`,
|
||||
render,
|
||||
result_count,
|
||||
result_mode,
|
||||
create_by,
|
||||
create_time,
|
||||
update_time,
|
||||
style_priority,
|
||||
chart_type,
|
||||
is_plugin,
|
||||
x_axis,
|
||||
x_axis_ext,
|
||||
y_axis,
|
||||
y_axis_ext,
|
||||
ext_stack,
|
||||
ext_bubble,
|
||||
custom_attr,
|
||||
custom_style,
|
||||
custom_filter,
|
||||
drill_fields,
|
||||
senior,
|
||||
SNAPSHOT,
|
||||
data_from,
|
||||
refresh_view_enable,
|
||||
refresh_unit,
|
||||
refresh_time
|
||||
from chart_view
|
||||
WHERE chart_view.id = #{id}
|
||||
</insert>
|
||||
|
||||
<insert id="copyCache">
|
||||
INSERT INTO chart_view_cache (
|
||||
id,
|
||||
`name`,
|
||||
title,
|
||||
scene_id,
|
||||
table_id,
|
||||
`type`,
|
||||
render,
|
||||
result_count,
|
||||
result_mode,
|
||||
create_by,
|
||||
create_time,
|
||||
update_time,
|
||||
style_priority,
|
||||
chart_type,
|
||||
is_plugin,
|
||||
x_axis,
|
||||
x_axis_ext,
|
||||
y_axis,
|
||||
y_axis_ext,
|
||||
ext_stack,
|
||||
ext_bubble,
|
||||
custom_attr,
|
||||
custom_style,
|
||||
custom_filter,
|
||||
drill_fields,
|
||||
senior,
|
||||
SNAPSHOT,
|
||||
data_from
|
||||
) SELECT
|
||||
#{newViewId} as id,
|
||||
`name`,
|
||||
title,
|
||||
scene_id,
|
||||
table_id,
|
||||
`type`,
|
||||
render,
|
||||
result_count,
|
||||
result_mode,
|
||||
create_by,
|
||||
create_time,
|
||||
update_time,
|
||||
style_priority,
|
||||
chart_type,
|
||||
is_plugin,
|
||||
x_axis,
|
||||
x_axis_ext,
|
||||
y_axis,
|
||||
y_axis_ext,
|
||||
ext_stack,
|
||||
ext_bubble,
|
||||
custom_attr,
|
||||
custom_style,
|
||||
custom_filter,
|
||||
drill_fields,
|
||||
senior,
|
||||
SNAPSHOT,
|
||||
data_from from chart_view_cache
|
||||
WHERE
|
||||
chart_view_cache.id = #{sourceViewId}
|
||||
INSERT INTO chart_view_cache (id,
|
||||
`name`,
|
||||
title,
|
||||
scene_id,
|
||||
table_id,
|
||||
`type`,
|
||||
render,
|
||||
result_count,
|
||||
result_mode,
|
||||
create_by,
|
||||
create_time,
|
||||
update_time,
|
||||
style_priority,
|
||||
chart_type,
|
||||
is_plugin,
|
||||
x_axis,
|
||||
x_axis_ext,
|
||||
y_axis,
|
||||
y_axis_ext,
|
||||
ext_stack,
|
||||
ext_bubble,
|
||||
custom_attr,
|
||||
custom_style,
|
||||
custom_filter,
|
||||
drill_fields,
|
||||
senior,
|
||||
SNAPSHOT,
|
||||
data_from,
|
||||
refresh_view_enable,
|
||||
refresh_unit,
|
||||
refresh_time)
|
||||
SELECT #{newViewId} as id,
|
||||
`name`,
|
||||
title,
|
||||
scene_id,
|
||||
table_id,
|
||||
`type`,
|
||||
render,
|
||||
result_count,
|
||||
result_mode,
|
||||
create_by,
|
||||
create_time,
|
||||
update_time,
|
||||
style_priority,
|
||||
chart_type,
|
||||
is_plugin,
|
||||
x_axis,
|
||||
x_axis_ext,
|
||||
y_axis,
|
||||
y_axis_ext,
|
||||
ext_stack,
|
||||
ext_bubble,
|
||||
custom_attr,
|
||||
custom_style,
|
||||
custom_filter,
|
||||
drill_fields,
|
||||
senior,
|
||||
SNAPSHOT,
|
||||
data_from,
|
||||
refresh_view_enable,
|
||||
refresh_unit,
|
||||
refresh_time
|
||||
from chart_view_cache
|
||||
WHERE chart_view_cache.id = #{sourceViewId}
|
||||
</insert>
|
||||
|
||||
<insert id="initPanelChartViewCache">
|
||||
INSERT INTO chart_view_cache (
|
||||
id,
|
||||
`name`,
|
||||
title,
|
||||
scene_id,
|
||||
table_id,
|
||||
`type`,
|
||||
render,
|
||||
result_count,
|
||||
result_mode,
|
||||
create_by,
|
||||
create_time,
|
||||
update_time,
|
||||
style_priority,
|
||||
chart_type,
|
||||
is_plugin,
|
||||
x_axis,
|
||||
x_axis_ext,
|
||||
y_axis,
|
||||
y_axis_ext,
|
||||
ext_stack,
|
||||
ext_bubble,
|
||||
custom_attr,
|
||||
custom_style,
|
||||
custom_filter,
|
||||
drill_fields,
|
||||
senior,
|
||||
SNAPSHOT,
|
||||
data_from
|
||||
) SELECT
|
||||
id,
|
||||
`name`,
|
||||
title,
|
||||
scene_id,
|
||||
table_id,
|
||||
`type`,
|
||||
render,
|
||||
result_count,
|
||||
result_mode,
|
||||
create_by,
|
||||
create_time,
|
||||
update_time,
|
||||
style_priority,
|
||||
chart_type,
|
||||
is_plugin,
|
||||
x_axis,
|
||||
x_axis_ext,
|
||||
y_axis,
|
||||
y_axis_ext,
|
||||
ext_stack,
|
||||
ext_bubble,
|
||||
custom_attr,
|
||||
custom_style,
|
||||
custom_filter,
|
||||
drill_fields,
|
||||
senior,
|
||||
SNAPSHOT,
|
||||
data_from from chart_view
|
||||
WHERE
|
||||
chart_view.scene_id = #{panelId}
|
||||
INSERT INTO chart_view_cache (id,
|
||||
`name`,
|
||||
title,
|
||||
scene_id,
|
||||
table_id,
|
||||
`type`,
|
||||
render,
|
||||
result_count,
|
||||
result_mode,
|
||||
create_by,
|
||||
create_time,
|
||||
update_time,
|
||||
style_priority,
|
||||
chart_type,
|
||||
is_plugin,
|
||||
x_axis,
|
||||
x_axis_ext,
|
||||
y_axis,
|
||||
y_axis_ext,
|
||||
ext_stack,
|
||||
ext_bubble,
|
||||
custom_attr,
|
||||
custom_style,
|
||||
custom_filter,
|
||||
drill_fields,
|
||||
senior,
|
||||
SNAPSHOT,
|
||||
data_from,
|
||||
refresh_view_enable,
|
||||
refresh_unit,
|
||||
refresh_time)
|
||||
SELECT id,
|
||||
`name`,
|
||||
title,
|
||||
scene_id,
|
||||
table_id,
|
||||
`type`,
|
||||
render,
|
||||
result_count,
|
||||
result_mode,
|
||||
create_by,
|
||||
create_time,
|
||||
update_time,
|
||||
style_priority,
|
||||
chart_type,
|
||||
is_plugin,
|
||||
x_axis,
|
||||
x_axis_ext,
|
||||
y_axis,
|
||||
y_axis_ext,
|
||||
ext_stack,
|
||||
ext_bubble,
|
||||
custom_attr,
|
||||
custom_style,
|
||||
custom_filter,
|
||||
drill_fields,
|
||||
senior,
|
||||
SNAPSHOT,
|
||||
data_from,
|
||||
refresh_view_enable,
|
||||
refresh_unit,
|
||||
refresh_time
|
||||
from chart_view
|
||||
WHERE chart_view.scene_id = #{panelId}
|
||||
</insert>
|
||||
|
||||
<select id="search" resultMap="BaseResultMapDTO">
|
||||
@ -299,11 +308,11 @@
|
||||
`senior`,
|
||||
`data_from`)
|
||||
SELECT #{newChartId},
|
||||
GET_CHART_VIEW_COPY_NAME(#{oldChartId},#{panelId}) as `name`,
|
||||
GET_CHART_VIEW_COPY_NAME(#{oldChartId}, #{panelId}) as `name`,
|
||||
#{panelId},
|
||||
`table_id`,
|
||||
`type`,
|
||||
GET_CHART_VIEW_COPY_NAME(#{oldChartId},#{panelId}) as `title`,
|
||||
GET_CHART_VIEW_COPY_NAME(#{oldChartId}, #{panelId}) as `title`,
|
||||
`x_axis`,
|
||||
`x_axis_ext`,
|
||||
`y_axis`,
|
||||
@ -312,8 +321,8 @@
|
||||
`custom_filter`,
|
||||
`drill_fields`,
|
||||
`create_by`,
|
||||
unix_timestamp()*1000 as `create_time`,
|
||||
unix_timestamp()*1000 as `update_time`,
|
||||
unix_timestamp() * 1000 as `create_time`,
|
||||
unix_timestamp() * 1000 as `update_time`,
|
||||
`snapshot`,
|
||||
`style_priority`,
|
||||
`ext_stack`,
|
||||
@ -405,13 +414,11 @@
|
||||
SNAPSHOT,
|
||||
senior,
|
||||
data_from
|
||||
FROM (
|
||||
SELECT panel_id,
|
||||
copy_from_view,
|
||||
chart_view_id
|
||||
FROM panel_view
|
||||
WHERE copy_id = #{copyId}
|
||||
) pv_copy
|
||||
FROM (SELECT panel_id,
|
||||
copy_from_view,
|
||||
chart_view_id
|
||||
FROM panel_view
|
||||
WHERE copy_id = #{copyId}) pv_copy
|
||||
INNER JOIN chart_view ON chart_view.id = pv_copy.copy_from_view
|
||||
</insert>
|
||||
|
||||
@ -459,16 +466,11 @@
|
||||
|
||||
|
||||
<select id="searchViewsWithPanelId" resultMap="BaseResultMapDTO">
|
||||
SELECT * FROM chart_view
|
||||
WHERE
|
||||
id IN (
|
||||
SELECT
|
||||
chart_view_id
|
||||
FROM
|
||||
panel_view
|
||||
WHERE
|
||||
panel_id = #{panelId}
|
||||
)
|
||||
SELECT *
|
||||
FROM chart_view
|
||||
WHERE id IN (SELECT chart_view_id
|
||||
FROM panel_view
|
||||
WHERE panel_id = #{panelId})
|
||||
</select>
|
||||
|
||||
<delete id="deleteCacheWithPanel">
|
||||
@ -480,10 +482,12 @@
|
||||
#{viewId}
|
||||
</foreach>
|
||||
</if>
|
||||
</delete>
|
||||
</delete>
|
||||
<delete id="deleteViewCache">
|
||||
delete from chart_view_cache where id = #{viewId}
|
||||
</delete>
|
||||
delete
|
||||
from chart_view_cache
|
||||
where id = #{viewId}
|
||||
</delete>
|
||||
|
||||
<update id="copyCacheToView">
|
||||
UPDATE chart_view cv,
|
||||
@ -514,7 +518,10 @@
|
||||
cv.drill_fields = cve.drill_fields,
|
||||
cv.senior = cve.senior,
|
||||
cv.SNAPSHOT = cve.SNAPSHOT,
|
||||
cv.data_from = cve.data_from
|
||||
cv.data_from = cve.data_from,
|
||||
cv.refresh_view_enable = cve.refresh_view_enable,
|
||||
cv.refresh_unit = cve.refresh_unit,
|
||||
cv.refresh_time = cve.refresh_time
|
||||
where cve.id = cv.id and cv.id in
|
||||
<foreach collection="viewIds" item="viewId" open='(' separator=',' close=')'>
|
||||
#{viewId}
|
||||
@ -523,69 +530,75 @@
|
||||
|
||||
<update id="updateToCache">
|
||||
UPDATE chart_view_cache cv,
|
||||
chart_view cve
|
||||
chart_view cve
|
||||
SET cv.`name` = cve.`name`,
|
||||
cv.title = cve.title,
|
||||
cv.scene_id = cve.scene_id,
|
||||
cv.table_id = cve.table_id,
|
||||
cv.`type` = cve.`type`,
|
||||
cv.render = cve.render,
|
||||
cv.result_count = cve.result_count,
|
||||
cv.result_mode = cve.result_mode,
|
||||
cv.create_by = cve.create_by,
|
||||
cv.create_time = cve.create_time,
|
||||
cv.update_time = cve.update_time,
|
||||
cv.style_priority = cve.style_priority,
|
||||
cv.chart_type = cve.chart_type,
|
||||
cv.is_plugin = cve.is_plugin,
|
||||
cv.x_axis = cve.x_axis,
|
||||
cv.x_axis_ext = cve.x_axis_ext,
|
||||
cv.y_axis = cve.y_axis,
|
||||
cv.y_axis_ext = cve.y_axis_ext,
|
||||
cv.ext_stack = cve.ext_stack,
|
||||
cv.ext_bubble = cve.ext_bubble,
|
||||
cv.custom_attr = cve.custom_attr,
|
||||
cv.custom_style = cve.custom_style,
|
||||
cv.custom_filter = cve.custom_filter,
|
||||
cv.drill_fields = cve.drill_fields,
|
||||
cv.senior = cve.senior,
|
||||
cv.SNAPSHOT = cve.SNAPSHOT,
|
||||
cv.data_from = cve.data_from
|
||||
where cve.id = cv.id and cv.id =#{viewId}
|
||||
cv.title = cve.title,
|
||||
cv.scene_id = cve.scene_id,
|
||||
cv.table_id = cve.table_id,
|
||||
cv.`type` = cve.`type`,
|
||||
cv.render = cve.render,
|
||||
cv.result_count = cve.result_count,
|
||||
cv.result_mode = cve.result_mode,
|
||||
cv.create_by = cve.create_by,
|
||||
cv.create_time = cve.create_time,
|
||||
cv.update_time = cve.update_time,
|
||||
cv.style_priority = cve.style_priority,
|
||||
cv.chart_type = cve.chart_type,
|
||||
cv.is_plugin = cve.is_plugin,
|
||||
cv.x_axis = cve.x_axis,
|
||||
cv.x_axis_ext = cve.x_axis_ext,
|
||||
cv.y_axis = cve.y_axis,
|
||||
cv.y_axis_ext = cve.y_axis_ext,
|
||||
cv.ext_stack = cve.ext_stack,
|
||||
cv.ext_bubble = cve.ext_bubble,
|
||||
cv.custom_attr = cve.custom_attr,
|
||||
cv.custom_style = cve.custom_style,
|
||||
cv.custom_filter = cve.custom_filter,
|
||||
cv.drill_fields = cve.drill_fields,
|
||||
cv.senior = cve.senior,
|
||||
cv.SNAPSHOT = cve.SNAPSHOT,
|
||||
cv.data_from = cve.data_from,
|
||||
cv.refresh_view_enable = cve.refresh_view_enable,
|
||||
cv.refresh_unit = cve.refresh_unit,
|
||||
cv.refresh_time = cve.refresh_time
|
||||
where cve.id = cv.id and cv.id =#{viewId}
|
||||
</update>
|
||||
|
||||
|
||||
<update id="updateToViewFromCache">
|
||||
UPDATE chart_view_cache cve,
|
||||
chart_view cv
|
||||
chart_view cv
|
||||
SET cv.`name` = cve.`name`,
|
||||
cv.title = cve.title,
|
||||
cv.scene_id = cve.scene_id,
|
||||
cv.table_id = cve.table_id,
|
||||
cv.`type` = cve.`type`,
|
||||
cv.render = cve.render,
|
||||
cv.result_count = cve.result_count,
|
||||
cv.result_mode = cve.result_mode,
|
||||
cv.create_by = cve.create_by,
|
||||
cv.create_time = cve.create_time,
|
||||
cv.update_time = cve.update_time,
|
||||
cv.style_priority = cve.style_priority,
|
||||
cv.chart_type = cve.chart_type,
|
||||
cv.is_plugin = cve.is_plugin,
|
||||
cv.x_axis = cve.x_axis,
|
||||
cv.x_axis_ext = cve.x_axis_ext,
|
||||
cv.y_axis = cve.y_axis,
|
||||
cv.y_axis_ext = cve.y_axis_ext,
|
||||
cv.ext_stack = cve.ext_stack,
|
||||
cv.ext_bubble = cve.ext_bubble,
|
||||
cv.custom_attr = cve.custom_attr,
|
||||
cv.custom_style = cve.custom_style,
|
||||
cv.custom_filter = cve.custom_filter,
|
||||
cv.drill_fields = cve.drill_fields,
|
||||
cv.senior = cve.senior,
|
||||
cv.SNAPSHOT = cve.SNAPSHOT,
|
||||
cv.data_from = cve.data_from
|
||||
where cve.id = cv.id and cv.id =#{viewId}
|
||||
cv.title = cve.title,
|
||||
cv.scene_id = cve.scene_id,
|
||||
cv.table_id = cve.table_id,
|
||||
cv.`type` = cve.`type`,
|
||||
cv.render = cve.render,
|
||||
cv.result_count = cve.result_count,
|
||||
cv.result_mode = cve.result_mode,
|
||||
cv.create_by = cve.create_by,
|
||||
cv.create_time = cve.create_time,
|
||||
cv.update_time = cve.update_time,
|
||||
cv.style_priority = cve.style_priority,
|
||||
cv.chart_type = cve.chart_type,
|
||||
cv.is_plugin = cve.is_plugin,
|
||||
cv.x_axis = cve.x_axis,
|
||||
cv.x_axis_ext = cve.x_axis_ext,
|
||||
cv.y_axis = cve.y_axis,
|
||||
cv.y_axis_ext = cve.y_axis_ext,
|
||||
cv.ext_stack = cve.ext_stack,
|
||||
cv.ext_bubble = cve.ext_bubble,
|
||||
cv.custom_attr = cve.custom_attr,
|
||||
cv.custom_style = cve.custom_style,
|
||||
cv.custom_filter = cve.custom_filter,
|
||||
cv.drill_fields = cve.drill_fields,
|
||||
cv.senior = cve.senior,
|
||||
cv.SNAPSHOT = cve.SNAPSHOT,
|
||||
cv.data_from = cve.data_from,
|
||||
cv.refresh_view_enable = cve.refresh_view_enable,
|
||||
cv.refresh_unit = cve.refresh_unit,
|
||||
cv.refresh_time = cve.refresh_time
|
||||
where cve.id = cv.id and cv.id =#{viewId}
|
||||
</update>
|
||||
|
||||
<delete id="deleteNoUseView">
|
||||
@ -600,53 +613,49 @@
|
||||
</delete>
|
||||
|
||||
<select id="chartOptions" resultType="io.dataease.dto.chart.ViewOption">
|
||||
select id, title as name from chart_view where scene_id = #{panelId}
|
||||
select id, title as name
|
||||
from chart_view
|
||||
where scene_id = #{panelId}
|
||||
</select>
|
||||
|
||||
<insert id='chartFiledCopyWithPanel'>
|
||||
INSERT INTO chart_view_field (
|
||||
id,
|
||||
table_id,
|
||||
chart_id,
|
||||
`name`,
|
||||
dataease_name,
|
||||
group_type,
|
||||
`type`,
|
||||
`size`,
|
||||
de_type,
|
||||
de_type_format,
|
||||
de_extract_type,
|
||||
ext_field,
|
||||
`checked`,
|
||||
column_index,
|
||||
last_sync_time
|
||||
) SELECT
|
||||
uuid() AS id,
|
||||
chart_view_field.table_id,
|
||||
chart_view_field.pv_copy.chart_view_id AS chart_id,
|
||||
chart_view_field.`name`,
|
||||
chart_view_field.dataease_name,
|
||||
chart_view_field.group_type,
|
||||
chart_view_field.`type`,
|
||||
chart_view_field.`size`,
|
||||
chart_view_field.de_type,
|
||||
chart_view_field.de_type_format,
|
||||
chart_view_field.de_extract_type,
|
||||
chart_view_field.ext_field,
|
||||
chart_view_field.`checked`,
|
||||
chart_view_field.column_index,
|
||||
chart_view_field.last_sync_time
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
panel_id,
|
||||
copy_from_view,
|
||||
chart_view_id
|
||||
FROM
|
||||
panel_view
|
||||
WHERE
|
||||
copy_id = #{copyId}
|
||||
) pv_copy
|
||||
INNER JOIN chart_view_field ON chart_view_field.chart_id = pv_copy.copy_from_view
|
||||
INSERT INTO chart_view_field (id,
|
||||
table_id,
|
||||
chart_id,
|
||||
origin_name,
|
||||
`name`,
|
||||
dataease_name,
|
||||
group_type,
|
||||
`type`,
|
||||
`size`,
|
||||
de_type,
|
||||
de_type_format,
|
||||
de_extract_type,
|
||||
ext_field,
|
||||
`checked`,
|
||||
column_index,
|
||||
last_sync_time)
|
||||
SELECT uuid() AS id,
|
||||
chart_view_field.table_id,
|
||||
chart_view_field.pv_copy.chart_view_id AS chart_id,
|
||||
chart_view_field.origin_name,
|
||||
chart_view_field.`name`,
|
||||
chart_view_field.dataease_name,
|
||||
chart_view_field.group_type,
|
||||
chart_view_field.`type`,
|
||||
chart_view_field.`size`,
|
||||
chart_view_field.de_type,
|
||||
chart_view_field.de_type_format,
|
||||
chart_view_field.de_extract_type,
|
||||
chart_view_field.ext_field,
|
||||
chart_view_field.`checked`,
|
||||
chart_view_field.column_index,
|
||||
chart_view_field.last_sync_time
|
||||
FROM (SELECT panel_id,
|
||||
copy_from_view,
|
||||
chart_view_id
|
||||
FROM panel_view
|
||||
WHERE copy_id = #{copyId}) pv_copy
|
||||
INNER JOIN chart_view_field ON chart_view_field.chart_id = pv_copy.copy_from_view
|
||||
</insert>
|
||||
</mapper>
|
||||
|
||||
@ -21,6 +21,7 @@ public abstract class TaskHandler implements InitializingBean {
|
||||
if (CronUtils.taskExpire(endTime)) { // 过期了就删除任务
|
||||
return;
|
||||
}
|
||||
if (!taskEntity.getStatus()) return;
|
||||
JobKey jobKey = new JobKey(taskEntity.getTaskId().toString());
|
||||
TriggerKey triggerKey = new TriggerKey(taskEntity.getTaskId().toString());
|
||||
Date start = new Date(taskEntity.getStartTime());
|
||||
|
||||
@ -94,7 +94,7 @@ public class EmailTaskHandler extends TaskHandler implements Job {
|
||||
Boolean isTempTask = (Boolean) jobDataMap.getOrDefault(IS_TEMP_TASK, false);
|
||||
GlobalTaskEntity taskEntity = (GlobalTaskEntity) jobDataMap.get("taskEntity");
|
||||
ScheduleManager scheduleManager = SpringContextUtil.getBean(ScheduleManager.class);
|
||||
if (!isTempTask && CronUtils.taskExpire(taskEntity.getEndTime())) {
|
||||
if (!isTempTask && (CronUtils.taskExpire(taskEntity.getEndTime()) || !taskEntity.getStatus())) {
|
||||
removeTask(scheduleManager, taskEntity);
|
||||
return;
|
||||
}
|
||||
@ -167,7 +167,7 @@ public class EmailTaskHandler extends TaskHandler implements Job {
|
||||
try {
|
||||
XpackEmailTemplateDTO emailTemplateDTO = emailXpackService.emailTemplate(taskInstance.getTaskId());
|
||||
XpackEmailTaskRequest taskForm = emailXpackService.taskForm(taskInstance.getTaskId());
|
||||
if (ObjectUtils.isEmpty(taskForm) || (!isTempTask && CronUtils.taskExpire(taskForm.getEndTime()))) {
|
||||
if (ObjectUtils.isEmpty(taskForm) || (!isTempTask && (CronUtils.taskExpire(taskForm.getEndTime()) || !taskForm.getStatus()))) {
|
||||
removeInstance(taskInstance);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
package io.dataease.plugins.entity;
|
||||
|
||||
import io.dataease.plugins.common.base.domain.MyPlugin;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class PluginOperate implements Serializable {
|
||||
|
||||
private String type;
|
||||
|
||||
private MyPlugin plugin;
|
||||
|
||||
private String senderIp;
|
||||
}
|
||||
@ -115,6 +115,11 @@ public class XDingtalkServer {
|
||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.LOGIN, SysLogConstants.SOURCE_TYPE.USER, sysUserEntity.getUserId(), null, null, null);
|
||||
|
||||
Cookie cookie_token = new Cookie("Authorization", token);
|
||||
if (withoutLogin) {
|
||||
Cookie platformCookie = new Cookie("inOtherPlatform", "true");
|
||||
platformCookie.setPath("/");
|
||||
response.addCookie(platformCookie);
|
||||
}
|
||||
cookie_token.setPath("/");
|
||||
|
||||
response.addCookie(cookie_token);
|
||||
|
||||
@ -80,7 +80,7 @@ public class XEmailTaskServer {
|
||||
List<XpackTaskGridDTO> tasks = emailXpackService.taskGrid(request);
|
||||
if (CollectionUtils.isNotEmpty(tasks)) {
|
||||
tasks.forEach(item -> {
|
||||
if (CronUtils.taskExpire(item.getEndTime())) {
|
||||
if (CronUtils.taskExpire(item.getEndTime()) || !item.getStatus()) {
|
||||
item.setNextExecTime(null);
|
||||
} else {
|
||||
GlobalTaskEntity globalTaskEntity = new GlobalTaskEntity();
|
||||
@ -110,8 +110,16 @@ public class XEmailTaskServer {
|
||||
EmailXpackService emailXpackService = SpringContextUtil.getBean(EmailXpackService.class);
|
||||
XpackEmailTaskRequest request = emailXpackService.taskForm(taskId);
|
||||
GlobalTaskEntity globalTaskEntity = BeanUtils.copyBean(new GlobalTaskEntity(), request);
|
||||
Boolean invalid = false;
|
||||
if (CronUtils.taskExpire(globalTaskEntity.getEndTime())) {
|
||||
globalTaskEntity.setEndTime(null);
|
||||
invalid = true;
|
||||
}
|
||||
if (!globalTaskEntity.getStatus()) {
|
||||
globalTaskEntity.setStatus(true);
|
||||
invalid = true;
|
||||
}
|
||||
if (invalid) {
|
||||
scheduleService.addTempSchedule(globalTaskEntity);
|
||||
return;
|
||||
}
|
||||
@ -270,6 +278,12 @@ public class XEmailTaskServer {
|
||||
emailXpackService.stop(taskId);
|
||||
}
|
||||
|
||||
@PostMapping("/start/{taskId}")
|
||||
public Boolean start(@PathVariable Long taskId) throws Exception {
|
||||
EmailXpackService emailXpackService = SpringContextUtil.getBean(EmailXpackService.class);
|
||||
return emailXpackService.start(taskId);
|
||||
}
|
||||
|
||||
@PostMapping("/queryInstancies/{goPage}/{pageSize}")
|
||||
public Pager<List<XpackTaskInstanceDTO>> instancesGrid(@PathVariable int goPage, @PathVariable int pageSize,
|
||||
@RequestBody XpackGridRequest request) {
|
||||
|
||||
@ -141,6 +141,11 @@ public class XLarkServer {
|
||||
cookie_token.setPath("/");
|
||||
|
||||
response.addCookie(cookie_token);
|
||||
if (withoutLogin) {
|
||||
Cookie platformCookie = new Cookie("inOtherPlatform", "true");
|
||||
platformCookie.setPath("/");
|
||||
response.addCookie(platformCookie);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
String msg = e.getMessage();
|
||||
|
||||
@ -558,6 +558,12 @@ public class ChartViewService {
|
||||
return data;
|
||||
}
|
||||
|
||||
public Boolean containDetailField(ChartViewDTO view) {
|
||||
List<String> detailFieldViewTypes = new ArrayList<>();
|
||||
detailFieldViewTypes.add("map");
|
||||
return detailFieldViewTypes.contains(view.getType());
|
||||
}
|
||||
|
||||
public ChartViewDTO calcData(ChartViewDTO view, ChartExtRequest chartExtRequest, boolean cache) throws Exception {
|
||||
ChartViewDTO chartViewDTO = new ChartViewDTO();
|
||||
if (ObjectUtils.isEmpty(view)) {
|
||||
@ -906,6 +912,9 @@ public class ChartViewService {
|
||||
pageInfo.setGoPage(chartExtRequest.getGoPage());
|
||||
pageInfo.setPageSize(chartExtRequest.getPageSize());
|
||||
|
||||
List<ChartViewFieldDTO> detailFieldList = new ArrayList<>();
|
||||
String detailFieldSql = null;
|
||||
List<String[]> detailData = new ArrayList<>();
|
||||
//如果不是插件视图 走原生逻辑
|
||||
if (table.getMode() == 0) {// 直连
|
||||
if (ObjectUtils.isEmpty(ds)) {
|
||||
@ -931,6 +940,11 @@ public class ChartViewService {
|
||||
totalPageSql = qp.getResultCount(true, dataTableInfoDTO.getTable(), xAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, ds, view);
|
||||
} else {
|
||||
querySql = qp.getSQL(dataTableInfoDTO.getTable(), xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, ds, view);
|
||||
if (containDetailField(view) && CollectionUtils.isNotEmpty(viewFields)) {
|
||||
detailFieldList.addAll(xAxis);
|
||||
detailFieldList.addAll(viewFields);
|
||||
detailFieldSql = qp.getSQLWithPage(true, dataTableInfoDTO.getTable(), detailFieldList, fieldCustomFilter, rowPermissionsTree, extFilterList, ds, view, pageInfo);
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.equalsIgnoreCase(table.getType(), DatasetType.SQL.name())) {
|
||||
String sql = dataTableInfoDTO.isBase64Encryption() ? new String(java.util.Base64.getDecoder().decode(dataTableInfoDTO.getSql())) : dataTableInfoDTO.getSql();
|
||||
@ -946,6 +960,11 @@ public class ChartViewService {
|
||||
totalPageSql = qp.getResultCount(false, sql, xAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, ds, view);
|
||||
} else {
|
||||
querySql = qp.getSQLAsTmp(sql, xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, view);
|
||||
if (containDetailField(view) && CollectionUtils.isNotEmpty(viewFields)) {
|
||||
detailFieldList.addAll(xAxis);
|
||||
detailFieldList.addAll(viewFields);
|
||||
detailFieldSql = qp.getSQLWithPage(false, sql, detailFieldList, fieldCustomFilter, rowPermissionsTree, extFilterList, ds, view, pageInfo);
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.equalsIgnoreCase(table.getType(), DatasetType.CUSTOM.name())) {
|
||||
DataTableInfoDTO dt = gson.fromJson(table.getInfo(), DataTableInfoDTO.class);
|
||||
@ -962,6 +981,11 @@ public class ChartViewService {
|
||||
totalPageSql = qp.getResultCount(false, sql, xAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, ds, view);
|
||||
} else {
|
||||
querySql = qp.getSQLAsTmp(sql, xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, view);
|
||||
if (containDetailField(view) && CollectionUtils.isNotEmpty(viewFields)) {
|
||||
detailFieldList.addAll(xAxis);
|
||||
detailFieldList.addAll(viewFields);
|
||||
detailFieldSql = qp.getSQLWithPage(false, sql, detailFieldList, fieldCustomFilter, rowPermissionsTree, extFilterList, ds, view, pageInfo);
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.equalsIgnoreCase(table.getType(), DatasetType.UNION.name())) {
|
||||
DataTableInfoDTO dt = gson.fromJson(table.getInfo(), DataTableInfoDTO.class);
|
||||
@ -978,6 +1002,11 @@ public class ChartViewService {
|
||||
totalPageSql = qp.getResultCount(false, sql, xAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, ds, view);
|
||||
} else {
|
||||
querySql = qp.getSQLAsTmp(sql, xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, view);
|
||||
if (containDetailField(view) && CollectionUtils.isNotEmpty(viewFields)) {
|
||||
detailFieldList.addAll(xAxis);
|
||||
detailFieldList.addAll(viewFields);
|
||||
detailFieldSql = qp.getSQLWithPage(false, sql, detailFieldList, fieldCustomFilter, rowPermissionsTree, extFilterList, ds, view, pageInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotEmpty(totalPageSql) && StringUtils.equalsIgnoreCase((String) mapSize.get("tablePageMode"), "page")) {
|
||||
@ -994,6 +1023,11 @@ public class ChartViewService {
|
||||
logger.info(datasourceAssistRequest.getQuery());
|
||||
assistData = datasourceProvider.getData(datasourceAssistRequest);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(detailFieldSql)) {
|
||||
datasourceRequest.setQuery(detailFieldSql);
|
||||
detailData = datasourceProvider.getData(datasourceRequest);
|
||||
}
|
||||
} else if (table.getMode() == 1) {// 抽取
|
||||
// 连接doris,构建doris数据源查询
|
||||
datasourceRequest.setDatasource(ds);
|
||||
@ -1010,6 +1044,11 @@ public class ChartViewService {
|
||||
datasourceRequest.setQuery(qp.getSQLTableInfo(tableName, xAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, ds, view));
|
||||
} else {
|
||||
datasourceRequest.setQuery(qp.getSQL(tableName, xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, ds, view));
|
||||
if (containDetailField(view) && CollectionUtils.isNotEmpty(viewFields)) {
|
||||
detailFieldList.addAll(xAxis);
|
||||
detailFieldList.addAll(viewFields);
|
||||
detailFieldSql = qp.getSQLTableInfo(tableName, detailFieldList, fieldCustomFilter, rowPermissionsTree, extFilterList, ds, view);
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(assistFields)) {
|
||||
datasourceAssistRequest.setQuery(assistSQL(datasourceRequest.getQuery(), assistFields));
|
||||
@ -1036,6 +1075,10 @@ public class ChartViewService {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank(detailFieldSql)) {
|
||||
datasourceRequest.setQuery(detailFieldSql);
|
||||
detailData = datasourceProvider.getData(datasourceRequest);
|
||||
}
|
||||
}
|
||||
// 自定义排序
|
||||
if (StringUtils.containsIgnoreCase(view.getType(), "stack")) {
|
||||
@ -1199,7 +1242,12 @@ public class ChartViewService {
|
||||
}
|
||||
}
|
||||
// table组件,明细表,也用于导出数据
|
||||
Map<String, Object> mapTableNormal = ChartDataBuild.transTableNormal(xAxis, yAxis, view, data, extStack, desensitizationList);
|
||||
Map<String, Object> mapTableNormal = null;
|
||||
if (CollectionUtils.isNotEmpty(detailData)) {
|
||||
mapTableNormal = ChartDataBuild.transTableNormalWithDetail(xAxis, yAxis, data, detailFieldList, detailData, desensitizationList);
|
||||
} else {
|
||||
mapTableNormal = ChartDataBuild.transTableNormal(xAxis, yAxis, view, data, extStack, desensitizationList);
|
||||
}
|
||||
chartViewDTO = uniteViewResult(datasourceRequest.getQuery(), mapChart, mapTableNormal, view, isDrill, drillFilters, dynamicAssistFields, assistData);
|
||||
chartViewDTO.setTotalPage(totalPage);
|
||||
chartViewDTO.setTotalItems(totalItems);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package io.dataease.service.chart.util;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs;
|
||||
import io.dataease.dto.chart.*;
|
||||
import io.dataease.plugins.common.dto.chart.ChartViewFieldDTO;
|
||||
@ -14,6 +15,9 @@ import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ChartDataBuild {
|
||||
|
||||
private final static String format = "(%s)";
|
||||
|
||||
// AntV
|
||||
public static Map<String, Object> transChartDataAntV(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewWithBLOBs view, List<String[]> data, boolean isDrill) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
@ -952,6 +956,46 @@ public class ChartDataBuild {
|
||||
return transTableNormal(fields, view, data, desensitizationList);
|
||||
}
|
||||
|
||||
public static Map<String, Object> transTableNormalWithDetail(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<String[]> data, List<ChartViewFieldDTO> detailFields, List<String[]> detailData, Map<String, ColumnPermissionItem> desensitizationList) {
|
||||
int detailIndex = xAxis.size();
|
||||
|
||||
List<ChartViewFieldDTO> realDetailFields = detailFields.subList(detailIndex, detailFields.size());
|
||||
|
||||
List<ChartViewFieldDTO> fields = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(xAxis))
|
||||
fields.addAll(xAxis);
|
||||
if (CollectionUtils.isNotEmpty(yAxis))
|
||||
fields.addAll(yAxis);
|
||||
Map<String, Object> map = transTableNormal(fields, null, data, desensitizationList);
|
||||
List<Map<String, Object>> tableRow = (List<Map<String, Object>>) map.get("tableRow");
|
||||
final int xEndIndex = detailIndex;
|
||||
Map<String, List<String[]>> groupDataList = detailData.stream().collect(Collectors.groupingBy(item -> ArrayUtil.join(ArrayUtil.sub(item, 0, xEndIndex), "-de-", "(", ")")));
|
||||
|
||||
tableRow.forEach(row -> {
|
||||
String key = xAxis.stream().map(x -> String.format(format, row.get(x.getDataeaseName()).toString())).collect(Collectors.joining("-de-"));
|
||||
List<String[]> detailFieldValueList = groupDataList.get(key);
|
||||
List<Map<String, Object>> detailValueMapList = detailFieldValueList.stream().map((detailArr -> {
|
||||
Map<String, Object> temp = new HashMap<>();
|
||||
for (int i = 0; i < realDetailFields.size(); i++) {
|
||||
ChartViewFieldDTO realDetailField = realDetailFields.get(i);
|
||||
temp.put(realDetailField.getDataeaseName(), detailArr[detailIndex + i]);
|
||||
}
|
||||
return temp;
|
||||
})).collect(Collectors.toList());
|
||||
row.put("details", detailValueMapList);
|
||||
});
|
||||
|
||||
ChartViewFieldDTO detailFieldDTO = new ChartViewFieldDTO();
|
||||
detailFieldDTO.setId("DataEase-Detail");
|
||||
detailFieldDTO.setName("detail");
|
||||
detailFieldDTO.setDataeaseName("detail");
|
||||
fields.add(detailFieldDTO);
|
||||
map.put("fields", fields);
|
||||
map.put("detailFields", realDetailFields);
|
||||
map.put("tableRow", tableRow);
|
||||
return map;
|
||||
}
|
||||
|
||||
// 表格
|
||||
public static Map<String, Object> transTableNormal(Map<String, List<ChartViewFieldDTO>> fieldMap, ChartViewWithBLOBs view, List<String[]> data, Map<String, ColumnPermissionItem> desensitizationList) {
|
||||
|
||||
@ -1014,7 +1058,7 @@ public class ChartDataBuild {
|
||||
if (StringUtils.isEmpty(originStr) || originStr.length() <= columnPermissionItem.getDesensitizationRule().getM() + columnPermissionItem.getDesensitizationRule().getN() + 1) {
|
||||
desensitizationStr = String.join("", Collections.nCopies(columnPermissionItem.getDesensitizationRule().getM(), "X")) + "***" + String.join("", Collections.nCopies(columnPermissionItem.getDesensitizationRule().getN(), "X"));
|
||||
} else {
|
||||
desensitizationStr = StringUtils.substring(originStr, 0, columnPermissionItem.getDesensitizationRule().getM() - 1) + "***" + StringUtils.substring(originStr, originStr.length() - columnPermissionItem.getDesensitizationRule().getN(), originStr.length() - 1);
|
||||
desensitizationStr = StringUtils.substring(originStr, 0, columnPermissionItem.getDesensitizationRule().getM()) + "***" + StringUtils.substring(originStr, originStr.length() - columnPermissionItem.getDesensitizationRule().getN() - 1, originStr.length() - 1);
|
||||
}
|
||||
break;
|
||||
case RetainMToN:
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
package io.dataease.service.dataset;
|
||||
|
||||
|
||||
|
||||
|
||||
import io.dataease.dto.dataset.DeSortDTO;
|
||||
|
||||
import java.util.List;
|
||||
@ -14,4 +12,6 @@ public interface DataSetFieldService {
|
||||
List<Object> fieldValues(String fieldId, DeSortDTO sortDTO, Long userId, Boolean userPermissions, Boolean rowAndColumnMgm) throws Exception;
|
||||
|
||||
List<Object> fieldValues(List<String> fieldIds, DeSortDTO sortDTO, Long userId, Boolean userPermissions, Boolean needMapping, Boolean rowAndColumnMgm) throws Exception;
|
||||
|
||||
List<Object> chineseSort(List<Object> list, DeSortDTO sortDTO) throws Exception;
|
||||
}
|
||||
|
||||
@ -967,26 +967,15 @@ public class DataSetTableService {
|
||||
return map;
|
||||
}
|
||||
|
||||
public List<SqlVariableDetails> paramsWithIds(String type, List<String> viewIds) {
|
||||
if (CollectionUtils.isEmpty(viewIds)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<SqlVariableDetails> datasetParams(String type, String id) {
|
||||
if (!Arrays.asList("DATE", "TEXT", "NUM").contains(type)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
ChartViewExample chartViewExample = new ChartViewExample();
|
||||
chartViewExample.createCriteria().andIdIn(viewIds);
|
||||
List<String> datasetIds = chartViewMapper.selectByExample(chartViewExample).stream().map(ChartView::getTableId).collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(datasetIds)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
DatasetTableExample datasetTableExample = new DatasetTableExample();
|
||||
datasetTableExample.createCriteria().andIdIn(datasetIds);
|
||||
List<DatasetTable> datasetTables = datasetTableMapper.selectByExample(datasetTableExample);
|
||||
if (CollectionUtils.isEmpty(datasetTables)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(id);
|
||||
return getSqlVariableDetails(type, Arrays.asList(datasetTable));
|
||||
}
|
||||
|
||||
private List<SqlVariableDetails> getSqlVariableDetails(String type, List<DatasetTable> datasetTables) {
|
||||
List<SqlVariableDetails> sqlVariableDetails = new ArrayList<>();
|
||||
for (DatasetTable datasetTable : datasetTables) {
|
||||
if (StringUtils.isNotEmpty(datasetTable.getSqlVariableDetails())) {
|
||||
@ -999,6 +988,7 @@ public class DataSetTableService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case "DATE":
|
||||
sqlVariableDetails = sqlVariableDetails.stream().filter(item -> item.getType().get(0).contains("DATETIME")).collect(Collectors.toList());
|
||||
@ -1022,6 +1012,29 @@ public class DataSetTableService {
|
||||
return sqlVariableDetails;
|
||||
}
|
||||
|
||||
public List<SqlVariableDetails> paramsWithIds(String type, List<String> viewIds) {
|
||||
if (CollectionUtils.isEmpty(viewIds)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
if (!Arrays.asList("DATE", "TEXT", "NUM").contains(type)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
ChartViewExample chartViewExample = new ChartViewExample();
|
||||
chartViewExample.createCriteria().andIdIn(viewIds);
|
||||
List<String> datasetIds = chartViewMapper.selectByExample(chartViewExample).stream().map(ChartView::getTableId).collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(datasetIds)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
DatasetTableExample datasetTableExample = new DatasetTableExample();
|
||||
datasetTableExample.createCriteria().andIdIn(datasetIds);
|
||||
List<DatasetTable> datasetTables = datasetTableMapper.selectByExample(datasetTableExample);
|
||||
if (CollectionUtils.isEmpty(datasetTables)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return getSqlVariableDetails(type, datasetTables);
|
||||
}
|
||||
|
||||
|
||||
public void checkVariable(final String sql, String dsType) throws Exception {
|
||||
String tmpSql = removeVariables(sql, dsType);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package io.dataease.service.dataset.impl.direct;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.google.gson.Gson;
|
||||
import io.dataease.commons.exception.DEException;
|
||||
import io.dataease.commons.model.BaseTreeNode;
|
||||
@ -32,6 +33,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.text.Collator;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -77,6 +79,26 @@ public class DirectFieldService implements DataSetFieldService {
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> chineseSort(List<Object> list, DeSortDTO sortDTO) throws Exception {
|
||||
if (ObjectUtils.isEmpty(sortDTO) || CollectionUtil.isEmpty(list)) return list;
|
||||
String sort = sortDTO.getSort();
|
||||
if (!StringUtils.equals(sort, "chinese")) {
|
||||
return list;
|
||||
}
|
||||
String id = sortDTO.getId();
|
||||
String sortStr = StringUtils.equalsIgnoreCase("chineseDesc", id) ? "desc" : "asc";
|
||||
List<Object> result = CollectionUtil.sort(list, (v1, v2) -> {
|
||||
Collator instance = Collator.getInstance(Locale.CHINESE);
|
||||
if (StringUtils.equals("desc", sortStr)) {
|
||||
return instance.compare(v2, v1);
|
||||
}
|
||||
return instance.compare(v1, v2);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> fieldValues(List<String> fieldIds, DeSortDTO sortDTO, Long userId, Boolean userPermissions, Boolean needMapping, Boolean rowAndColumnMgm) throws Exception {
|
||||
String fieldId = fieldIds.get(0);
|
||||
@ -146,7 +168,7 @@ public class DirectFieldService implements DataSetFieldService {
|
||||
datasourceRequest.setQuery(qp.createQuerySQL(dataTableInfoDTO.getTable(), permissionFields, !needSort, ds, customFilter, rowPermissionsTree, deSortFields));
|
||||
} else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), DatasetType.SQL.toString())) {
|
||||
String sql = dataTableInfoDTO.getSql();
|
||||
if(dataTableInfoDTO.isBase64Encryption()){
|
||||
if (dataTableInfoDTO.isBase64Encryption()) {
|
||||
sql = new String(java.util.Base64.getDecoder().decode(sql));
|
||||
}
|
||||
sql = dataSetTableService.removeVariables(sql, ds.getType());
|
||||
|
||||
@ -104,11 +104,13 @@ public class DatasourceService {
|
||||
|
||||
@DeCleaner(DePermissionType.DATASOURCE)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Datasource addDatasource(Datasource datasource) throws Exception {
|
||||
public Datasource addDatasource(DatasourceDTO datasource) throws Exception {
|
||||
if (!types().stream().map(DataSourceType::getType).collect(Collectors.toList()).contains(datasource.getType())) {
|
||||
throw new Exception("Datasource type not supported.");
|
||||
}
|
||||
|
||||
if(datasource.isConfigurationEncryption()){
|
||||
datasource.setConfiguration(new String(java.util.Base64.getDecoder().decode(datasource.getConfiguration())));
|
||||
}
|
||||
Provider datasourceProvider = ProviderFactory.getProvider(datasource.getType());
|
||||
datasourceProvider.checkConfiguration(datasource);
|
||||
|
||||
@ -212,6 +214,14 @@ public class DatasourceService {
|
||||
}
|
||||
}
|
||||
}
|
||||
if(StringUtils.isNotEmpty(datasourceDTO.getConfiguration())){
|
||||
datasourceDTO.setConfiguration(new String(java.util.Base64.getEncoder().encode(datasourceDTO.getConfiguration().getBytes())));
|
||||
}
|
||||
if(CollectionUtils.isNotEmpty(datasourceDTO.getApiConfiguration())){
|
||||
String config = new Gson().toJson(datasourceDTO.getApiConfiguration());
|
||||
datasourceDTO.setApiConfigurationStr(new String(java.util.Base64.getEncoder().encode(config.getBytes())));
|
||||
datasourceDTO.setApiConfiguration(null);
|
||||
}
|
||||
}
|
||||
|
||||
public DatasourceDTO getDataSourceDetails(String datasourceId){
|
||||
@ -253,6 +263,9 @@ public class DatasourceService {
|
||||
if (!types().stream().map(DataSourceType::getType).collect(Collectors.toList()).contains(updataDsRequest.getType())) {
|
||||
throw new Exception("Datasource type not supported.");
|
||||
}
|
||||
if(updataDsRequest.isConfigurationEncryption()){
|
||||
updataDsRequest.setConfiguration(new String(java.util.Base64.getDecoder().decode(updataDsRequest.getConfiguration())));
|
||||
}
|
||||
checkName(updataDsRequest.getName(), updataDsRequest.getType(), updataDsRequest.getId());
|
||||
Datasource datasource = new Datasource();
|
||||
datasource.setName(updataDsRequest.getName());
|
||||
@ -261,15 +274,22 @@ public class DatasourceService {
|
||||
datasource.setCreateTime(null);
|
||||
datasource.setType(updataDsRequest.getType());
|
||||
datasource.setUpdateTime(System.currentTimeMillis());
|
||||
|
||||
Provider datasourceProvider = ProviderFactory.getProvider(updataDsRequest.getType());
|
||||
datasourceProvider.checkConfiguration(datasource);
|
||||
|
||||
checkAndUpdateDatasourceStatus(datasource);
|
||||
DatasourceExample example = new DatasourceExample();
|
||||
example.createCriteria().andIdEqualTo(updataDsRequest.getId());
|
||||
datasourceMapper.updateByExampleSelective(datasource, example);
|
||||
handleConnectionPool(updataDsRequest.getId());
|
||||
if(StringUtils.isNotEmpty(updataDsRequest.getId())){
|
||||
DatasourceExample example = new DatasourceExample();
|
||||
example.createCriteria().andIdEqualTo(updataDsRequest.getId());
|
||||
datasourceMapper.updateByExampleSelective(datasource, example);
|
||||
handleConnectionPool(updataDsRequest.getId());
|
||||
}else {
|
||||
datasource.setId(UUID.randomUUID().toString());
|
||||
datasource.setCreateTime(System.currentTimeMillis());
|
||||
datasourceMapper.insert(datasource);
|
||||
handleConnectionPool(datasource, "add");
|
||||
sysAuthService.copyAuth(datasource.getId(), SysAuthConstants.AUTH_SOURCE_TYPE_DATASOURCE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void handleConnectionPool(String datasourceId) {
|
||||
@ -283,7 +303,10 @@ public class DatasourceService {
|
||||
}
|
||||
}
|
||||
|
||||
public ResultHolder validate(Datasource datasource) throws Exception {
|
||||
public ResultHolder validate(DatasourceDTO datasource) throws Exception {
|
||||
if(datasource.isConfigurationEncryption()){
|
||||
datasource.setConfiguration(new String(java.util.Base64.getDecoder().decode(datasource.getConfiguration())));
|
||||
}
|
||||
DatasourceDTO datasourceDTO = new DatasourceDTO();
|
||||
BeanUtils.copyBean(datasourceDTO, datasource);
|
||||
try {
|
||||
@ -371,7 +394,10 @@ public class DatasourceService {
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getSchema(Datasource datasource) throws Exception {
|
||||
public List<String> getSchema(DatasourceDTO datasource) throws Exception {
|
||||
if(datasource.isConfigurationEncryption()){
|
||||
datasource.setConfiguration(new String(java.util.Base64.getDecoder().decode(datasource.getConfiguration())));
|
||||
}
|
||||
Provider datasourceProvider = ProviderFactory.getProvider(datasource.getType());
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
datasourceRequest.setDatasource(datasource);
|
||||
|
||||
@ -11,6 +11,7 @@ import io.dataease.controller.request.dataset.DataSetTableRequest;
|
||||
import io.dataease.controller.request.panel.PanelAppTemplateApplyRequest;
|
||||
import io.dataease.controller.request.panel.PanelAppTemplateRequest;
|
||||
import io.dataease.controller.request.panel.PanelGroupRequest;
|
||||
import io.dataease.dto.DatasourceDTO;
|
||||
import io.dataease.ext.ExtPanelAppTemplateMapper;
|
||||
import io.dataease.plugins.common.base.domain.*;
|
||||
import io.dataease.plugins.common.base.mapper.PanelAppTemplateMapper;
|
||||
@ -137,13 +138,18 @@ public class PanelAppTemplateService {
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Map<String, String> applyDatasource(List<Datasource> oldDatasourceList, List<Datasource> newDatasourceList) throws Exception {
|
||||
public Map<String, String> applyDatasource(List<Datasource> oldDatasourceList, PanelAppTemplateApplyRequest request) throws Exception {
|
||||
Map<String, String> datasourceRealMap = new HashMap<>();
|
||||
for (int i = 0; i < newDatasourceList.size(); i++) {
|
||||
Datasource datasource = newDatasourceList.get(0);
|
||||
datasource.setId(null);
|
||||
Datasource newDatasource = datasourceService.addDatasource(datasource);
|
||||
datasourceRealMap.put(oldDatasourceList.get(i).getId(), newDatasource.getId());
|
||||
if (PanelConstants.APP_DATASOURCE_FROM.HISTORY.equals(request.getDatasourceFrom())) {
|
||||
datasourceRealMap.put(oldDatasourceList.get(0).getId(), request.getDatasourceHistoryId());
|
||||
} else {
|
||||
List<DatasourceDTO> newDatasourceList = request.getDatasourceList();
|
||||
for (int i = 0; i < newDatasourceList.size(); i++) {
|
||||
DatasourceDTO datasource = newDatasourceList.get(0);
|
||||
datasource.setId(null);
|
||||
Datasource newDatasource = datasourceService.addDatasource(datasource);
|
||||
datasourceRealMap.put(oldDatasourceList.get(i).getId(), newDatasource.getId());
|
||||
}
|
||||
}
|
||||
return datasourceRealMap;
|
||||
}
|
||||
@ -366,24 +372,28 @@ public class PanelAppTemplateService {
|
||||
datasetGroup.setPid(request.getDatasetGroupPid());
|
||||
datasetGroup.setName(request.getDatasetGroupName());
|
||||
dataSetGroupService.checkName(datasetGroup);
|
||||
request.getDatasourceList().stream().forEach(datasource -> {
|
||||
datasourceService.checkName(datasource.getName(), datasource.getType(), null);
|
||||
});
|
||||
if (PanelConstants.APP_DATASOURCE_FROM.NEW.equals(request.getDatasourceFrom())) {
|
||||
request.getDatasourceList().stream().forEach(datasource -> {
|
||||
datasourceService.checkName(datasource.getName(), datasource.getType(), null);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
DatasetGroup datasetGroup = new DatasetGroup();
|
||||
datasetGroup.setPid(request.getDatasetGroupPid());
|
||||
datasetGroup.setName(request.getDatasetGroupName());
|
||||
datasetGroup.setId(request.getDatasetGroupId());
|
||||
dataSetGroupService.checkName(datasetGroup);
|
||||
request.getDatasourceList().stream().forEach(datasource -> {
|
||||
datasourceService.checkName(datasource.getName(), datasource.getType(), datasource.getId());
|
||||
});
|
||||
if (PanelConstants.APP_DATASOURCE_FROM.NEW.equals(request.getDatasourceFrom())) {
|
||||
request.getDatasourceList().stream().forEach(datasource -> {
|
||||
datasourceService.checkName(datasource.getName(), datasource.getType(), datasource.getId());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void editDatasource(List<Datasource> updateDatasourceList) throws Exception {
|
||||
public void editDatasource(List<DatasourceDTO> updateDatasourceList) throws Exception {
|
||||
for (int i = 0; i < updateDatasourceList.size(); i++) {
|
||||
UpdataDsRequest updataDsRequest = new UpdataDsRequest();
|
||||
BeanUtils.copyBean(updataDsRequest, updateDatasourceList.get(i));
|
||||
|
||||
@ -898,7 +898,7 @@ public class PanelGroupService {
|
||||
List<PanelView> panelViewsInfo = gson.fromJson(appInfo.getPanelViewsInfo(), new TypeToken<List<PanelView>>() {
|
||||
}.getType());
|
||||
|
||||
Map<String, String> datasourceRealMap = panelAppTemplateService.applyDatasource(oldDatasourceInfo, request.getDatasourceList());
|
||||
Map<String, String> datasourceRealMap = panelAppTemplateService.applyDatasource(oldDatasourceInfo, request);
|
||||
|
||||
Map<String, String> datasetsRealMap = panelAppTemplateService.applyDataset(datasetTablesInfo, datasourceRealMap, asideDatasetGroupId);
|
||||
|
||||
@ -909,7 +909,7 @@ public class PanelGroupService {
|
||||
Map<String, String> datasetFieldsRealMap = panelAppTemplateService.applyDatasetField(datasetTableFieldsInfo, datasetsRealMap, datasetTypeRealMap, datasetFieldsMd5FormatRealMap);
|
||||
|
||||
panelAppTemplateService.createDorisTable(datasetTablesInfo);
|
||||
|
||||
|
||||
panelAppTemplateService.resetCustomAndUnionDataset(datasetTablesInfo, datasetsRealMap, datasetFieldsRealMap);
|
||||
|
||||
Map<String, String> chartViewsRealMap = panelAppTemplateService.applyViews(chartViewsInfo, datasetsRealMap, datasetFieldsRealMap, datasetFieldsMd5FormatRealMap, newPanelId);
|
||||
@ -922,17 +922,19 @@ public class PanelGroupService {
|
||||
|
||||
String newDatasourceId = datasourceRealMap.entrySet().stream().findFirst().get().getValue();
|
||||
|
||||
String newDatasourceName = request.getDatasourceList().get(0).getName();
|
||||
|
||||
PanelAppTemplateLog templateLog = new PanelAppTemplateLog();
|
||||
templateLog.setPanelId(newPanelId);
|
||||
templateLog.setSourcePanelName(request.getPanelName());
|
||||
templateLog.setDatasourceId(newDatasourceId);
|
||||
templateLog.setSourceDatasourceName(newDatasourceName);
|
||||
if (PanelConstants.APP_DATASOURCE_FROM.NEW.equals(request.getDatasourceFrom())) {
|
||||
templateLog.setSourceDatasourceName(request.getDatasourceList().get(0).getName());
|
||||
}
|
||||
templateLog.setDatasetGroupId(asideDatasetGroupId);
|
||||
templateLog.setSourceDatasetGroupName(request.getDatasetGroupName());
|
||||
templateLog.setAppTemplateId(appInfo.getId());
|
||||
templateLog.setAppTemplateName(appInfo.getName());
|
||||
templateLog.setDatasourceFrom(request.getDatasourceFrom());
|
||||
appTemplateLogService.newAppApplyLog(templateLog);
|
||||
return newPanelId;
|
||||
}
|
||||
|
||||
@ -1,13 +1,57 @@
|
||||
package io.dataease.service.redis.impl;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.dataease.commons.utils.IPUtils;
|
||||
import io.dataease.commons.utils.LogUtil;
|
||||
import io.dataease.plugins.common.base.domain.MyPlugin;
|
||||
import io.dataease.plugins.entity.PluginOperate;
|
||||
import io.dataease.service.redis.RedisMessageBroadcast;
|
||||
import io.dataease.service.sys.PluginService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Service
|
||||
public class PluginMsgService implements RedisMessageBroadcast {
|
||||
|
||||
private static Gson json = new Gson();
|
||||
|
||||
@Resource
|
||||
private PluginService pluginService;
|
||||
|
||||
@Override
|
||||
public void messageCallBack(Object arg) {
|
||||
PluginOperate operate = json.fromJson(json.toJson(arg), PluginOperate.class);
|
||||
String domain = IPUtils.domain();
|
||||
if (StringUtils.equals(domain, operate.getSenderIp())) return;
|
||||
String operateType = operate.getType();
|
||||
MyPlugin plugin = operate.getPlugin();
|
||||
if (StringUtils.equals("install", operateType)) {
|
||||
LogUtil.info("start install plugin [{}] in domain {}", plugin.getName(), domain);
|
||||
install(plugin);
|
||||
}
|
||||
if (StringUtils.equals("uninstall", operateType)) {
|
||||
LogUtil.info("start uninstall plugin [{}] in domain {}", plugin.getName(), domain);
|
||||
uninstall(plugin);
|
||||
}
|
||||
if (StringUtils.equals("update", operateType)) {
|
||||
LogUtil.info("start update plugin [{}] in domain {}", plugin.getName(), domain);
|
||||
updateInstall(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
private void install(MyPlugin plugin) {
|
||||
pluginService.redisBroadcastInstall(plugin);
|
||||
}
|
||||
|
||||
private void uninstall(MyPlugin plugin) {
|
||||
pluginService.redisBroadcastUnInstall(plugin);
|
||||
}
|
||||
|
||||
private void updateInstall(MyPlugin plugin) {
|
||||
if (pluginService.redisBroadcastUnInstall(plugin)) {
|
||||
pluginService.redisBroadcastInstall(plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
package io.dataease.service.sys;
|
||||
|
||||
import io.dataease.commons.condition.RedisStatusCondition;
|
||||
import io.dataease.commons.constants.RedisConstants;
|
||||
import io.dataease.commons.model.RedisMessage;
|
||||
import io.dataease.plugins.entity.PluginOperate;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Component
|
||||
@Conditional({RedisStatusCondition.class})
|
||||
public class DistributedPluginService {
|
||||
|
||||
@Resource
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
|
||||
public void pushBroadcast(PluginOperate operate) {
|
||||
if (ObjectUtils.isEmpty(operate) || ObjectUtils.isEmpty(operate.getPlugin()) || StringUtils.isBlank(operate.getSenderIp()))
|
||||
return;
|
||||
|
||||
RedisMessage<PluginOperate> msg = new RedisMessage();
|
||||
msg.setType(RedisConstants.PLUGIN_INSTALL_MSG);
|
||||
msg.setData(operate);
|
||||
redisTemplate.convertAndSend(RedisConstants.GLOBAL_REDIS_TOPIC, msg);
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ package io.dataease.service.sys;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import com.google.gson.Gson;
|
||||
import io.dataease.commons.utils.IPUtils;
|
||||
import io.dataease.dto.MyPluginDTO;
|
||||
import io.dataease.ext.ExtSysPluginMapper;
|
||||
import io.dataease.ext.query.GridExample;
|
||||
@ -17,6 +18,7 @@ import io.dataease.listener.util.CacheUtils;
|
||||
import io.dataease.plugins.common.base.domain.MyPlugin;
|
||||
import io.dataease.plugins.common.base.mapper.MyPluginMapper;
|
||||
import io.dataease.plugins.config.LoadjarUtil;
|
||||
import io.dataease.plugins.entity.PluginOperate;
|
||||
import io.dataease.service.datasource.DatasourceService;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
@ -56,6 +58,9 @@ public class PluginService {
|
||||
@Autowired
|
||||
private LoadjarUtil loadjarUtil;
|
||||
|
||||
@Autowired(required = false)
|
||||
private DistributedPluginService distributedPluginService;
|
||||
|
||||
@Value("${version}")
|
||||
private String version;
|
||||
|
||||
@ -71,7 +76,7 @@ public class PluginService {
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
public Map<String, Object> localInstall(MultipartFile file) throws Exception{
|
||||
public Map<String, Object> localInstall(MultipartFile file) throws Exception {
|
||||
//1.上传文件到服务器pluginDir目录下
|
||||
File dest = DeFileUtils.upload(file, pluginDir + "temp/");
|
||||
//2.解压目标文件dest 得到plugin.json和jar
|
||||
@ -113,7 +118,7 @@ public class PluginService {
|
||||
}
|
||||
|
||||
if (pluginExist(myPlugin)) {
|
||||
String msg = "插件【"+myPlugin.getName()+"】已存在,请先卸载";
|
||||
String msg = "插件【" + myPlugin.getName() + "】已存在,请先卸载";
|
||||
LogUtil.error(msg);
|
||||
DEException.throwException(msg);
|
||||
}
|
||||
@ -123,7 +128,7 @@ public class PluginService {
|
||||
targetDir = makeTargetDir(myPlugin);
|
||||
String jarPath;
|
||||
jarPath = DeFileUtils.copy(jarFile, targetDir);
|
||||
if(myPlugin.getCategory().equalsIgnoreCase("datasource")){
|
||||
if (myPlugin.getCategory().equalsIgnoreCase("datasource")) {
|
||||
DeFileUtils.copyFolder(folder + "/" + myPlugin.getDsType() + "Driver", targetDir + myPlugin.getDsType() + "Driver");
|
||||
}
|
||||
loadJar(jarPath, myPlugin);
|
||||
@ -142,13 +147,49 @@ public class PluginService {
|
||||
DeFileUtils.deleteFile(pluginDir + "temp/");
|
||||
DeFileUtils.deleteFile(folder);
|
||||
}
|
||||
distributeOperate(myPlugin, "install");
|
||||
return null;
|
||||
}
|
||||
|
||||
public void distributeOperate(MyPlugin plugin, String type) {
|
||||
|
||||
if (ObjectUtils.isNotEmpty(distributedPluginService)) {
|
||||
PluginOperate operate = new PluginOperate();
|
||||
operate.setPlugin(plugin);
|
||||
operate.setSenderIp(IPUtils.domain());
|
||||
operate.setType(type);
|
||||
if (ObjectUtils.isEmpty(plugin) || StringUtils.isBlank(type) || StringUtils.isBlank(operate.getSenderIp()))
|
||||
return;
|
||||
distributedPluginService.pushBroadcast(operate);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadJar(String jarPath, MyPlugin myPlugin) throws Exception {
|
||||
loadjarUtil.loadJar(jarPath, myPlugin);
|
||||
}
|
||||
|
||||
public void redisBroadcastInstall(MyPlugin plugin) {
|
||||
String path = getPath(plugin);
|
||||
try {
|
||||
if (FileUtil.exist(path)) {
|
||||
loadJar(path, plugin);
|
||||
} else {
|
||||
LogUtil.error("插件路径不存在 {} ", path);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getPath(MyPlugin plugin) {
|
||||
String store = plugin.getStore();
|
||||
String version = plugin.getVersion();
|
||||
String moduleName = plugin.getModuleName();
|
||||
String fileName = moduleName + "-" + version + ".jar";
|
||||
String path = pluginDir + store + "/" + fileName;
|
||||
return path;
|
||||
}
|
||||
|
||||
private String makeTargetDir(MyPlugin myPlugin) {
|
||||
String store = myPlugin.getStore();
|
||||
String dir = pluginDir + store + "/";
|
||||
@ -161,6 +202,7 @@ public class PluginService {
|
||||
|
||||
/**
|
||||
* 检测插件是否已存在
|
||||
*
|
||||
* @param myPlugin
|
||||
* @return
|
||||
*/
|
||||
@ -190,13 +232,29 @@ public class PluginService {
|
||||
CacheUtils.removeAll(AuthConstants.USER_ROLE_CACHE_NAME);
|
||||
CacheUtils.removeAll(AuthConstants.USER_PERMISSION_CACHE_NAME);
|
||||
|
||||
if(myPlugin.getCategory().equalsIgnoreCase("datasource")){
|
||||
if(CollectionUtils.isNotEmpty(datasourceService.selectByType(myPlugin.getDsType()))){
|
||||
if (myPlugin.getCategory().equalsIgnoreCase("datasource")) {
|
||||
if (CollectionUtils.isNotEmpty(datasourceService.selectByType(myPlugin.getDsType()))) {
|
||||
DEException.throwException(Translator.get("i18n_plugin_not_allow_delete"));
|
||||
}
|
||||
loadjarUtil.deleteModule(myPlugin.getModuleName() + "-" + myPlugin.getVersion());
|
||||
}
|
||||
myPluginMapper.deleteByPrimaryKey(pluginId);
|
||||
distributeOperate(myPlugin, "uninstall");
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean redisBroadcastUnInstall(MyPlugin myPlugin) {
|
||||
CacheUtils.removeAll(AuthConstants.USER_ROLE_CACHE_NAME);
|
||||
CacheUtils.removeAll(AuthConstants.USER_CACHE_NAME);
|
||||
CacheUtils.removeAll(AuthConstants.USER_PERMISSION_CACHE_NAME);
|
||||
|
||||
if (myPlugin.getCategory().equalsIgnoreCase("datasource")) {
|
||||
if (CollectionUtils.isNotEmpty(datasourceService.selectByType(myPlugin.getDsType()))) {
|
||||
DEException.throwException(Translator.get("i18n_plugin_not_allow_delete"));
|
||||
}
|
||||
loadjarUtil.deleteModule(myPlugin.getModuleName() + "-" + myPlugin.getVersion());
|
||||
}
|
||||
myPluginMapper.deleteByPrimaryKey(myPlugin.getPluginId());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -208,7 +266,7 @@ public class PluginService {
|
||||
File jarFile = new File(path);
|
||||
FileUtil.del(jarFile);
|
||||
|
||||
if(plugin.getCategory().equalsIgnoreCase("datasource")){
|
||||
if (plugin.getCategory().equalsIgnoreCase("datasource")) {
|
||||
File driverFile = new File(pluginDir + plugin.getStore() + "/" + plugin.getDsType() + "Driver");
|
||||
FileUtil.del(driverFile);
|
||||
}
|
||||
@ -259,7 +317,7 @@ public class PluginService {
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(result.getCategory().equalsIgnoreCase("datasource") && (StringUtils.isEmpty(result.getStore()) || !result.getStore().equalsIgnoreCase("default"))){
|
||||
if (result.getCategory().equalsIgnoreCase("datasource") && (StringUtils.isEmpty(result.getStore()) || !result.getStore().equalsIgnoreCase("default"))) {
|
||||
result.setStore("thirdpart");
|
||||
}
|
||||
|
||||
|
||||
@ -29,56 +29,56 @@ import java.util.stream.Collectors;
|
||||
@Service
|
||||
public class TemplateMarketService {
|
||||
|
||||
private final static String POSTS_API="/api/content/posts?page=0&size=2000";
|
||||
private final static String CATEGORIES_API="/api/content/categories";
|
||||
private final static String POSTS_API = "/api/content/posts?page=0&size=2000";
|
||||
private final static String CATEGORIES_API = "/api/content/categories";
|
||||
|
||||
@Resource
|
||||
private SystemParameterService systemParameterService;
|
||||
|
||||
/**
|
||||
* @Description Get template file from template market
|
||||
* @param templateUrl template url
|
||||
* @Description Get template file from template market
|
||||
*/
|
||||
public PanelTemplateFileDTO getTemplateFromMarket(String templateUrl){
|
||||
if(StringUtils.isNotEmpty(templateUrl)){
|
||||
public PanelTemplateFileDTO getTemplateFromMarket(String templateUrl) {
|
||||
if (StringUtils.isNotEmpty(templateUrl)) {
|
||||
String sufUrl = systemParameterService.templateMarketInfo().getTemplateMarketUlr();
|
||||
Gson gson = new Gson();
|
||||
String templateInfo = HttpClientUtil.get(sufUrl+templateUrl,null);
|
||||
String templateInfo = HttpClientUtil.get(sufUrl + templateUrl, null);
|
||||
return gson.fromJson(templateInfo, PanelTemplateFileDTO.class);
|
||||
}else{
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description Get info from template market content api
|
||||
* @param url content api url
|
||||
* @Description Get info from template market content api
|
||||
*/
|
||||
public String marketGet(String url,String accessKey){
|
||||
public String marketGet(String url, String accessKey) {
|
||||
HttpClientConfig config = new HttpClientConfig();
|
||||
config.addHeader("API-Authorization",accessKey);
|
||||
return HttpClientUtil.get(url,config);
|
||||
config.addHeader("API-Authorization", accessKey);
|
||||
return HttpClientUtil.get(url, config);
|
||||
}
|
||||
|
||||
public MarketBaseResponse searchTemplate(TemplateMarketSearchRequest request){
|
||||
try{
|
||||
public MarketBaseResponse searchTemplate(TemplateMarketSearchRequest request) {
|
||||
try {
|
||||
BasicInfo basicInfo = systemParameterService.templateMarketInfo();
|
||||
String result = marketGet(basicInfo.getTemplateMarketUlr()+POSTS_API,basicInfo.getTemplateAccessKey());
|
||||
List<TemplateMarketDTO> postsResult = JSONObject.parseObject(result).getJSONObject("data").getJSONArray("content").toJavaList(TemplateMarketDTO.class);
|
||||
return new MarketBaseResponse(basicInfo.getTemplateMarketUlr(),postsResult);
|
||||
}catch (Exception e){
|
||||
String result = marketGet(basicInfo.getTemplateMarketUlr() + POSTS_API, basicInfo.getTemplateAccessKey());
|
||||
List<TemplateMarketDTO> postsResult = JSONObject.parseObject(result).getJSONObject("data").getJSONArray("content").toJavaList(TemplateMarketDTO.class);
|
||||
return new MarketBaseResponse(basicInfo.getTemplateMarketUlr(), postsResult);
|
||||
} catch (Exception e) {
|
||||
DataEaseException.throwException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> getCategories(){
|
||||
public List<String> getCategories() {
|
||||
BasicInfo basicInfo = systemParameterService.templateMarketInfo();
|
||||
String resultStr = marketGet(basicInfo.getTemplateMarketUlr()+CATEGORIES_API,basicInfo.getTemplateAccessKey());
|
||||
String resultStr = marketGet(basicInfo.getTemplateMarketUlr() + CATEGORIES_API, basicInfo.getTemplateAccessKey());
|
||||
List<TemplateCategory> categories = JSONObject.parseObject(resultStr).getJSONArray("data").toJavaList(TemplateCategory.class);
|
||||
if(CollectionUtils.isNotEmpty(categories)){
|
||||
return categories.stream().sorted(Comparator.comparing(TemplateCategory::getPriority)).map(TemplateCategory :: getName).collect(Collectors.toList());
|
||||
}else{
|
||||
if (CollectionUtils.isNotEmpty(categories)) {
|
||||
return categories.stream().filter(item -> !"应用系列".equals(item.getName())).sorted(Comparator.comparing(TemplateCategory::getPriority)).map(TemplateCategory::getName).collect(Collectors.toList());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
4
backend/src/main/resources/db/migration/V45__1.17.1.sql
Normal file
@ -0,0 +1,4 @@
|
||||
INSERT INTO `my_plugin` (`name`, `store`, `free`, `cost`, `category`, `descript`, `version`, `creator`, `load_mybatis`,
|
||||
`install_time`, `module_name`, `ds_type`)
|
||||
VALUES ('人大金仓数据源插件', 'default', '0', '0', 'datasource', '人大金仓数据源插件', '1.0-SNAPSHOT', 'DATAEASE', '0',
|
||||
'1650765903630', 'kingbase-backend', 'kingbase');
|
||||
34
backend/src/main/resources/db/migration/V46__1.18.sql
Normal file
@ -0,0 +1,34 @@
|
||||
ALTER TABLE `panel_app_template_log`
|
||||
ADD COLUMN `datasource_from` varchar(255) NULL DEFAULT 'new' COMMENT '数据源来源' AFTER `datasource_id`;
|
||||
|
||||
UPDATE `panel_subject`
|
||||
SET `details` = '{\"width\":1600,\"height\":900,\"scale\":100,\"scaleWidth\":100,\"scaleHeight\":100,\"selfAdaption\":true,\"auxiliaryMatrix\":true,\"openCommonStyle\":true,\"panel\":{\"themeColor\":\"light\",\"color\":\"#F1F3F5\",\"imageUrl\":{},\"backgroundType\":\"color\",\"gap\":\"yes\",\"resultMode\":\"all\",\"resultCount\":1000},\"aidedDesign\":{\"showGrid\":false,\"matrixBase\":4},\"refreshViewLoading\":true,\"refreshUnit\":\"minute\",\"refreshTime\":5,\"themeId\":\"251a25d0-7ac5-11ed-9e50-5f9360ac1250\",\"chartInfo\":{\"chartTitle\":{\"show\":true,\"fontSize\":\"18\",\"color\":\"#000000\",\"hPosition\":\"left\",\"vPosition\":\"top\",\"isItalic\":false,\"isBolder\":true},\"chartColor\":{\"value\":\"default\",\"colors\":[\"#5470c6\",\"#91cc75\",\"#fac858\",\"#ee6666\",\"#73c0de\",\"#3ba272\",\"#fc8452\",\"#9a60b4\",\"#ea7ccc\"],\"alpha\":100,\"tableHeaderBgColor\":\"#6D9A49\",\"tableItemBgColor\":\"#FFFFFF\",\"tableFontColor\":\"#000000\",\"tableStripe\":true,\"dimensionColor\":\"#000000\",\"quotaColor\":\"#4E81BB\",\"tableBorderColor\":\"#E6E7E4\",\"seriesColors\":[],\"tableHeaderFontColor\":\"#000000\"},\"chartCommonStyle\":{\"backgroundColorSelect\":true,\"color\":\"#FFFFFF\",\"alpha\":100,\"borderRadius\":5,\"innerPadding\":0},\"filterStyle\":{\"horizontal\":\"left\",\"vertical\":\"top\",\"color\":\"#000000\",\"brColor\":\"#DCDFE6\",\"wordColor\":\"#606266\",\"innerBgColor\":\"#FFFFFF\"}}}'
|
||||
WHERE `id` = 'system_1';
|
||||
|
||||
|
||||
ALTER TABLE `sys_task`
|
||||
ADD COLUMN `status` tinyint(1) NULL DEFAULT 1 COMMENT '运行状态' AFTER `create_time`;
|
||||
|
||||
|
||||
INSERT INTO `sys_menu` (`menu_id`, `pid`, `sub_count`, `type`, `title`, `name`, `component`, `menu_sort`, `icon`,
|
||||
`path`, `i_frame`, `cache`, `hidden`, `permission`)
|
||||
VALUES (1100, 1, 0, 1, '血缘关系', 'sys-relationship', 'system/relationship/index', 1002, 'sys-relationship',
|
||||
'relationship', 0, 0, 0, 'relationship:read');
|
||||
|
||||
UPDATE `sys_menu`
|
||||
SET `menu_sort` = 1003
|
||||
WHERE (`menu_id` = 101);
|
||||
|
||||
UPDATE `my_plugin`
|
||||
SET `version` = '1.18.0'
|
||||
where `plugin_id` > 0;
|
||||
|
||||
ALTER TABLE `chart_view`
|
||||
ADD COLUMN `refresh_view_enable` tinyint(1) NULL DEFAULT 0 COMMENT '是否开启刷新' AFTER `view_fields`,
|
||||
ADD COLUMN `refresh_unit` varchar(255) NULL DEFAULT 'minute' COMMENT '刷新时间单位' AFTER `refresh_view_enable`,
|
||||
ADD COLUMN `refresh_time` int(13) NULL DEFAULT 5 COMMENT '刷新时间' AFTER `refresh_unit`;
|
||||
|
||||
ALTER TABLE `chart_view_cache`
|
||||
ADD COLUMN `refresh_view_enable` tinyint(1) NULL DEFAULT 0 COMMENT '是否开启刷新' AFTER `view_fields`,
|
||||
ADD COLUMN `refresh_unit` varchar(255) NULL DEFAULT 'minute' COMMENT '刷新时间单位' AFTER `refresh_view_enable`,
|
||||
ADD COLUMN `refresh_time` int(13) NULL DEFAULT 5 COMMENT '刷新时间' AFTER `refresh_unit`;
|
||||
@ -259,4 +259,5 @@ I18N_LOG_FORMAT_PREFIX=With authority of %s\u3010%s\u3011
|
||||
\u7F16\u8F91\u8BB0\u5F55=Edit record
|
||||
\u5220\u9664\u8BB0\u5F55=Delete record
|
||||
\u6C34\u5370\u7BA1\u7406=Watermark
|
||||
\u8840\u7F18\u5173\u7CFB=Relationship
|
||||
|
||||
|
||||
@ -259,5 +259,6 @@ I18N_LOG_FORMAT_PREFIX=\u4EE5%s\u3010%s\u3011\u6743\u9650
|
||||
\u7F16\u8F91\u8BB0\u5F55=\u7F16\u8F91\u8BB0\u5F55
|
||||
\u5220\u9664\u8BB0\u5F55=\u5220\u9664\u8BB0\u5F55
|
||||
\u6C34\u5370\u7BA1\u7406=\u6C34\u5370\u7BA1\u7406
|
||||
\u8840\u7F18\u5173\u7CFB=\u8840\u7F18\u5173\u7CFB
|
||||
|
||||
|
||||
|
||||
@ -255,3 +255,4 @@ I18N_LOG_FORMAT_PREFIX=\u4EE5%s\u3010%s\u3011\u6B0A\u9650
|
||||
\u7F16\u8F91\u8BB0\u5F55=\u7DE8\u8F2F\u8A18\u9304
|
||||
\u5220\u9664\u8BB0\u5F55=\u522A\u9664\u8A18\u9304
|
||||
\u6C34\u5370\u7BA1\u7406=\u6C34\u5370\u7BA1\u7406
|
||||
\u8840\u7F18\u5173\u7CFB=\u8840\u7DE3\u95DC\u7CFB
|
||||
|
||||
@ -8,11 +8,12 @@ export function post(url, data, loading = false) {
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function tableField(id) {
|
||||
return request({
|
||||
url: '/dataset/table/getWithPermission/' + id,
|
||||
method: 'post',
|
||||
loading: true,
|
||||
loading: false,
|
||||
hideMsg: true,
|
||||
timeout: 60000
|
||||
})
|
||||
@ -34,6 +35,7 @@ export function chartCopy(id, panelId) {
|
||||
loading: false
|
||||
})
|
||||
}
|
||||
|
||||
export function chartBatchCopy(params, panelId) {
|
||||
return request({
|
||||
url: '/chart/view/chartBatchCopy/' + panelId,
|
||||
@ -42,6 +44,7 @@ export function chartBatchCopy(params, panelId) {
|
||||
loading: false
|
||||
})
|
||||
}
|
||||
|
||||
export function chartGroupTree(data) {
|
||||
return request({
|
||||
url: '/chart/group/tree',
|
||||
@ -116,6 +119,7 @@ export function resetViewCacheCallBack(viewId, panelId, callback) {
|
||||
callback(rep)
|
||||
})
|
||||
}
|
||||
|
||||
export function resetViewCache(viewId, panelId) {
|
||||
return request({
|
||||
url: '/chart/view/resetViewCache/' + viewId + '/' + panelId,
|
||||
|
||||
@ -128,6 +128,14 @@ export function fieldListWithPermission(id, showLoading = true) {
|
||||
})
|
||||
}
|
||||
|
||||
export function datasetParams(id, type, showLoading = true) {
|
||||
return request({
|
||||
url: '/dataset/table/params/' + id + '/' + type,
|
||||
loading: showLoading,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
export function fieldListDQ(id, showLoading = true) {
|
||||
return request({
|
||||
url: '/dataset/field/listByDQ/' + id,
|
||||
|
||||
@ -108,7 +108,6 @@ import { ApplicationContext } from '@/utils/ApplicationContext'
|
||||
import { chartCopy } from '@/api/chart/chart'
|
||||
import { adaptCurThemeCommonStyle } from '@/components/canvas/utils/style'
|
||||
import toast from '@/components/canvas/utils/toast'
|
||||
import generateID from '@/components/canvas/utils/generateID'
|
||||
import ButtonDialog from '@/views/panel/filter/ButtonDialog'
|
||||
import ButtonResetDialog from '@/views/panel/filter/ButtonResetDialog'
|
||||
import FilterDialog from '@/views/panel/filter/FilterDialog'
|
||||
@ -432,7 +431,7 @@ export default {
|
||||
uploadFileResult(file, (fileUrl) => {
|
||||
const component = {
|
||||
...commonAttr,
|
||||
id: generateID(),
|
||||
id: uuid.v1(),
|
||||
component: 'Picture',
|
||||
type: 'picture-add',
|
||||
label: '图片',
|
||||
|
||||
@ -44,6 +44,7 @@
|
||||
:in-screen="inScreen"
|
||||
:edit-mode="'preview'"
|
||||
:h="config.style.height"
|
||||
:search-count="searchCount"
|
||||
:canvas-id="canvasId"
|
||||
/>
|
||||
<component
|
||||
|
||||
@ -137,7 +137,7 @@
|
||||
:target="curComponent.hyperlinks.openMode "
|
||||
:href="curComponent.hyperlinks.content "
|
||||
>
|
||||
<i class="icon iconfont icon-com-jump" />
|
||||
<i class="icon iconfont icon-com-jump"/>
|
||||
</a>
|
||||
</span>
|
||||
|
||||
@ -496,19 +496,7 @@ export default {
|
||||
},
|
||||
// 清除相同sourceViewId 的 联动条件
|
||||
clearLinkage() {
|
||||
this.componentData.forEach(item => {
|
||||
if (item.linkageFilters && item.linkageFilters.length > 0) {
|
||||
const newList = item.linkageFilters.filter(linkage => linkage.sourceViewId !== this.element.propValue.viewId)
|
||||
item.linkageFilters.splice(0, item.linkageFilters.length)
|
||||
// 重新push 可保证数组指针不变 可以watch到
|
||||
if (newList.length > 0) {
|
||||
newList.forEach(newLinkage => {
|
||||
item.linkageFilters.push(newLinkage)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
bus.$emit('clear_panel_linkage', { viewId: this.element.propValue.viewId })
|
||||
this.$store.commit('clearViewLinkage', this.element.propValue.viewId)
|
||||
},
|
||||
goFile() {
|
||||
this.$refs.files.click()
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
@scroll="canvasScroll"
|
||||
>
|
||||
<canvas-opt-bar
|
||||
v-if="canvasId==='canvas-main'"
|
||||
ref="canvas-opt-bar"
|
||||
:canvas-style-data="canvasStyleData"
|
||||
@link-export-pdf="downloadAsPDF"
|
||||
@ -155,7 +156,7 @@ import bus from '@/utils/bus'
|
||||
import { buildFilterMap, buildViewKeyMap, formatCondition, valueValid, viewIdMatch } from '@/utils/conditionUtil'
|
||||
import { hasDataPermission } from '@/utils/permission'
|
||||
import { activeWatermark } from '@/components/canvas/tools/watermark'
|
||||
import { userLoginInfo } from '@/api/systemInfo/userLogin'
|
||||
import { proxyUserLoginInfo, userLoginInfo } from '@/api/systemInfo/userLogin'
|
||||
import html2canvas from 'html2canvasde'
|
||||
import { queryAll } from '@/api/panel/pdfTemplate'
|
||||
import PDFPreExport from '@/views/panel/export/PDFPreExport'
|
||||
@ -443,6 +444,9 @@ export default {
|
||||
bus.$off('trigger-reset-button', this.triggerResetButton)
|
||||
},
|
||||
methods: {
|
||||
getCanvasHeight() {
|
||||
return this.mainHeightCount
|
||||
},
|
||||
openChartDetailsDialog(paramInfo) {
|
||||
if (this.canvasId === 'canvas-main') {
|
||||
this.showChartInfo = paramInfo.showChartInfo
|
||||
@ -456,7 +460,8 @@ export default {
|
||||
if (this.userInfo) {
|
||||
activeWatermark(this.panelInfo.watermarkInfo.settingContent, this.userInfo, waterDomId, this.canvasId, this.panelInfo.watermarkOpen)
|
||||
} else {
|
||||
userLoginInfo().then(res => {
|
||||
const method = this.userId ? proxyUserLoginInfo : userLoginInfo
|
||||
method(this.userId).then(res => {
|
||||
this.userInfo = res.data
|
||||
activeWatermark(this.panelInfo.watermarkInfo.settingContent, this.userInfo, waterDomId, this.canvasId, this.panelInfo.watermarkOpen)
|
||||
})
|
||||
@ -781,14 +786,6 @@ export default {
|
||||
padding: 10px 20px 20px;
|
||||
}
|
||||
|
||||
.mobile-dialog-css ::v-deep .el-dialog__headerbtn {
|
||||
top: 7px
|
||||
}
|
||||
|
||||
.mobile-dialog-css ::v-deep .el-dialog__body {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 0px !important;
|
||||
height: 0px !important;
|
||||
|
||||
@ -29,7 +29,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
canvasId: 'canvas-main',
|
||||
dataLoading: false,
|
||||
dataLoading: true,
|
||||
backScreenShot: false,
|
||||
mainHeight: '100vh!important',
|
||||
shareUserId: null
|
||||
@ -171,12 +171,12 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bg {
|
||||
width: 100%;
|
||||
height: 100vh!important;
|
||||
min-width: 200px;
|
||||
min-height: 300px;
|
||||
background-color: #f7f8fa;
|
||||
}
|
||||
.bg {
|
||||
width: 100%;
|
||||
height: 100vh !important;
|
||||
min-width: 200px;
|
||||
min-height: 300px;
|
||||
background-color: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@ -44,7 +44,12 @@
|
||||
v-else
|
||||
class="info-class"
|
||||
>
|
||||
{{ $t('panel.web_add_tips') }}
|
||||
<span>{{ $t('panel.web_add_tips_pre') }}</span>
|
||||
<i
|
||||
slot="reference"
|
||||
class="icon iconfont icon-chaolianjie"
|
||||
/>
|
||||
<span>{{ $t('panel.web_add_tips_suf') }}</span>
|
||||
</div>
|
||||
</el-row>
|
||||
</template>
|
||||
@ -53,6 +58,7 @@
|
||||
import { mapState } from 'vuex'
|
||||
import bus from '@/utils/bus'
|
||||
import eventBus from '@/components/canvas/utils/eventBus'
|
||||
|
||||
export default {
|
||||
name: 'DeFrame',
|
||||
props: {
|
||||
@ -121,51 +127,56 @@ export default {
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.info-class{
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(255,255,255,0.3);
|
||||
font-size: 12px;
|
||||
color: #9ea6b2;
|
||||
}
|
||||
.info-class {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
font-size: 12px;
|
||||
color: #9ea6b2;
|
||||
}
|
||||
|
||||
.main-frame{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.frame-mask {
|
||||
display: flex;
|
||||
opacity: 0.5;
|
||||
position:absolute;
|
||||
top:0px;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.edit-mask{
|
||||
left: 0px;
|
||||
background-color: #5c5e61;
|
||||
height: 100%!important;
|
||||
width: 100% !important;
|
||||
}
|
||||
.preview-top-mask{
|
||||
left: 0px;
|
||||
height: 15px!important;
|
||||
width: 100% !important;
|
||||
}
|
||||
.preview-right-mask{
|
||||
right: 0px;
|
||||
height: 100%!important;
|
||||
width: 15px !important;
|
||||
}
|
||||
.preview-left-mask{
|
||||
left: 0px;
|
||||
height: 100%!important;
|
||||
width: 15px !important;
|
||||
}
|
||||
.main-frame {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.frame-mask {
|
||||
display: flex;
|
||||
opacity: 0.5;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.edit-mask {
|
||||
left: 0px;
|
||||
background-color: #5c5e61;
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.preview-top-mask {
|
||||
left: 0px;
|
||||
height: 15px !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.preview-right-mask {
|
||||
right: 0px;
|
||||
height: 100% !important;
|
||||
width: 15px !important;
|
||||
}
|
||||
|
||||
.preview-left-mask {
|
||||
left: 0px;
|
||||
height: 100% !important;
|
||||
width: 15px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@ -305,6 +305,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
innerRefreshTimer: null,
|
||||
mobileChartDetailsVisible: false,
|
||||
chartDetailsVisible: false,
|
||||
showChartInfo: {},
|
||||
@ -350,6 +351,10 @@ export default {
|
||||
},
|
||||
|
||||
computed: {
|
||||
// 首次加载且非编辑状态新复制的视图,使用外部filter
|
||||
initLoad() {
|
||||
return !(this.isEdit && this.currentCanvasNewId.includes(this.element.id)) && this.isFirstLoad
|
||||
},
|
||||
scaleCoefficient() {
|
||||
if (this.terminal === 'pc' && !this.mobileLayoutStatus) {
|
||||
return 1.1
|
||||
@ -389,14 +394,14 @@ export default {
|
||||
return this.httpRequest.status && this.chart.type && this.chart.type === 'label'
|
||||
},
|
||||
loadingFlag() {
|
||||
return (this.canvasStyleData.refreshViewLoading || this.searchCount === 0) && this.requestStatus === 'waiting'
|
||||
return (this.canvasStyleData.refreshViewLoading || (!this.innerRefreshTimer && this.searchCount === 0)) && this.requestStatus === 'waiting'
|
||||
},
|
||||
panelInfo() {
|
||||
return this.$store.state.panel.panelInfo
|
||||
},
|
||||
filter() {
|
||||
const filter = {}
|
||||
filter.filter = this.isFirstLoad ? this.filters : this.cfilters
|
||||
filter.filter = this.initLoad ? this.filters : this.cfilters
|
||||
filter.linkageFilters = this.element.linkageFilters
|
||||
filter.outerParamsFilters = this.element.outerParamsFilters
|
||||
filter.drill = this.drillClickDimensionList
|
||||
@ -455,6 +460,7 @@ export default {
|
||||
return this.element.commonBackground && this.element.commonBackground.innerPadding || 0
|
||||
},
|
||||
...mapState([
|
||||
'currentCanvasNewId',
|
||||
'nowPanelTrackInfo',
|
||||
'nowPanelJumpInfo',
|
||||
'publicLinkStatus',
|
||||
@ -515,7 +521,8 @@ export default {
|
||||
},
|
||||
// 监听外部计时器变化
|
||||
searchCount: function(val1) {
|
||||
if (val1 > 0 && this.requestStatus !== 'waiting') {
|
||||
// 内部计时器启动 忽略外部计时器
|
||||
if (val1 > 0 && this.requestStatus !== 'waiting' && !this.innerRefreshTimer) {
|
||||
this.getData(this.element.propValue.viewId)
|
||||
}
|
||||
},
|
||||
@ -542,6 +549,7 @@ export default {
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.innerRefreshTimer && clearInterval(this.innerRefreshTimer)
|
||||
bus.$off('plugin-chart-click', this.pluginChartClick)
|
||||
bus.$off('plugin-jump-click', this.pluginJumpClick)
|
||||
bus.$off('plugin-add-view-track-filter', this.pluginAddViewTrackFilter)
|
||||
@ -561,6 +569,20 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//编辑状态下 不启动刷新
|
||||
buildInnerRefreshTimer(refreshViewEnable = false, refreshUnit = 'minute', refreshTime = 5) {
|
||||
if (this.editMode === 'preview' && !this.innerRefreshTimer && refreshViewEnable) {
|
||||
this.innerRefreshTimer && clearInterval(this.innerRefreshTimer)
|
||||
const timerRefreshTime = refreshUnit === 'second' ? refreshTime * 1000 : refreshTime * 60000
|
||||
this.innerRefreshTimer = setInterval(() => {
|
||||
this.clearViewLinkage()
|
||||
this.getData(this.element.propValue.viewId)
|
||||
}, timerRefreshTime)
|
||||
}
|
||||
},
|
||||
clearViewLinkage() {
|
||||
this.$store.commit('clearViewLinkage', this.element.propValue.viewId)
|
||||
},
|
||||
responseResetButton() {
|
||||
if (!this.cfilters?.length) {
|
||||
this.getData(this.element.propValue.viewId, false)
|
||||
@ -736,6 +758,7 @@ export default {
|
||||
if (response.success) {
|
||||
this.chart = response.data
|
||||
this.view = response.data
|
||||
this.buildInnerRefreshTimer(this.chart.refreshViewEnable, this.chart.refreshUnit, this.chart.refreshTime)
|
||||
this.$emit('fill-chart-2-parent', this.chart)
|
||||
this.getDataOnly(response.data, dataBroadcast)
|
||||
this.chart['position'] = this.inTab ? 'tab' : 'panel'
|
||||
@ -1263,4 +1286,12 @@ export default {
|
||||
z-index: 2;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.mobile-dialog-css ::v-deep .el-dialog__headerbtn {
|
||||
top: 7px
|
||||
}
|
||||
|
||||
.mobile-dialog-css ::v-deep .el-dialog__body {
|
||||
padding: 0px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -14,7 +14,6 @@ export default {
|
||||
toast('已经到顶了')
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
downComponent({ componentData, curComponent }) {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { sin, cos } from '@/components/canvas/utils/translate'
|
||||
import { cos, sin } from '@/components/canvas/utils/translate'
|
||||
import store from '@/store'
|
||||
import Vue from 'vue'
|
||||
|
||||
@ -361,7 +361,13 @@ export function adaptCurTheme(customStyle, customAttr, chartType) {
|
||||
}
|
||||
}
|
||||
customAttr['color'] = { ...canvasStyle.chartInfo.chartColor }
|
||||
customStyle['text'] = { ...canvasStyle.chartInfo.chartTitle, title: customStyle['text']['title'], show: customStyle['text']['show'], remarkShow: customStyle['text']['remarkShow'], remark: customStyle['text']['remark'] }
|
||||
customStyle['text'] = {
|
||||
...canvasStyle.chartInfo.chartTitle,
|
||||
title: customStyle['text']['title'],
|
||||
show: customStyle['text']['show'],
|
||||
remarkShow: customStyle['text']['remarkShow'],
|
||||
remark: customStyle['text']['remark']
|
||||
}
|
||||
if (customStyle.background) {
|
||||
delete customStyle.background
|
||||
}
|
||||
@ -370,7 +376,7 @@ export function adaptCurTheme(customStyle, customAttr, chartType) {
|
||||
export function adaptCurThemeCommonStyle(component) {
|
||||
const commonStyle = store.state.canvasStyleData.chartInfo.chartCommonStyle
|
||||
for (const key in commonStyle) {
|
||||
component.commonBackground[key] = commonStyle[key]
|
||||
Vue.set(component.commonBackground, key, commonStyle[key])
|
||||
}
|
||||
if (isFilterComponent(component.component)) {
|
||||
const filterStyle = store.state.canvasStyleData.chartInfo.filterStyle
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import {
|
||||
BASE_MOBILE_STYLE,
|
||||
COMMON_BACKGROUND,
|
||||
COMMON_BACKGROUND_NONE,
|
||||
HYPERLINKS
|
||||
} from '@/components/canvas/customComponent/component-list'
|
||||
@ -86,7 +87,18 @@ export function panelDataPrepare(componentData, componentStyle, callback) {
|
||||
componentStyle.chartInfo.tabStyle = (componentStyle.chartInfo.tabStyle || deepCopy(TAB_COMMON_STYLE))
|
||||
componentStyle.themeId = (componentStyle.themeId || 'NO_THEME')
|
||||
componentStyle.panel.themeColor = (componentStyle.panel.themeColor || 'light')
|
||||
componentStyle.panel.mobileSetting = (componentStyle.panel.mobileSetting || MOBILE_SETTING)
|
||||
componentStyle.panel.mobileSetting = (componentStyle.panel.mobileSetting || deepCopy(MOBILE_SETTING))
|
||||
|
||||
// 主题增加组件背景设置
|
||||
if (componentStyle.chartCommonStyle) {
|
||||
componentStyle.chartCommonStyle.enable = componentStyle.chartCommonStyle.enable || false
|
||||
componentStyle.chartCommonStyle.backgroundType = componentStyle.chartCommonStyle.backgroundType || 'innerImage'
|
||||
componentStyle.chartCommonStyle.innerImageColor = componentStyle.chartCommonStyle.innerImageColor || '#1094E5'
|
||||
componentStyle.chartCommonStyle.innerImage = componentStyle.chartCommonStyle.innerImage || 'board/blue_1.svg'
|
||||
componentStyle.chartCommonStyle.outerImage = componentStyle.chartCommonStyle.outerImage || null
|
||||
} else {
|
||||
componentStyle.chartCommonStyle = deepCopy(COMMON_BACKGROUND)
|
||||
}
|
||||
componentData.forEach((item, index) => {
|
||||
if (item.component && item.component === 'de-date') {
|
||||
const widget = ApplicationContext.getService(item.serviceName)
|
||||
|
||||
@ -48,7 +48,6 @@
|
||||
:element="element"
|
||||
:in-draw="inDraw"
|
||||
:in-screen="inScreen"
|
||||
:size="sizeInfo"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -97,10 +96,16 @@ export default {
|
||||
isRelation: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
searchCount: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
needRefreshComponents: ['de-select', 'de-select-grid', 'de-select-tree'],
|
||||
inputMaxSize: 46,
|
||||
inputLargeSize: 42,
|
||||
inputSmallSize: 38,
|
||||
@ -127,17 +132,6 @@ export default {
|
||||
transform: 'scale(' + this.scale + ')'
|
||||
}
|
||||
},
|
||||
sizeInfo() {
|
||||
let size
|
||||
if (this.duHeight > this.inputLargeSize) {
|
||||
size = 'medium'
|
||||
} else if (this.duHeight > this.inputSmallSize) {
|
||||
size = 'small'
|
||||
} else {
|
||||
size = 'mini'
|
||||
}
|
||||
return size
|
||||
},
|
||||
deSelectGridBg() {
|
||||
if (this.element.component !== 'de-select-grid') return null
|
||||
const { backgroundColorSelect, color } = this.element.commonBackground
|
||||
@ -150,6 +144,7 @@ export default {
|
||||
return ['de-select', 'de-select-grid', 'de-date', 'de-input-search', 'de-number-range', 'de-select-tree'].includes(this.element.component)
|
||||
},
|
||||
...mapState([
|
||||
'curComponent',
|
||||
'previewCanvasScale'
|
||||
])
|
||||
},
|
||||
@ -160,6 +155,13 @@ export default {
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
},
|
||||
// 监听外部计时器变化
|
||||
searchCount: function(val1) {
|
||||
// 正在操作的组件不进行刷新
|
||||
if (val1 > 0 && this.needRefreshComponents.includes(this.element.component) && (!this.curComponent || this.curComponent.id !== this.element.id)) {
|
||||
this.$refs['deOutWidget'].refreshLoad()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@ -222,7 +224,7 @@ export default {
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
.ccondition-main {
|
||||
.condition-main {
|
||||
position: absolute;
|
||||
overflow: auto;
|
||||
top: 0px;
|
||||
@ -281,6 +283,11 @@ export default {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.first-element-container ::v-deep .el-input__inner {
|
||||
height: 40px !important;
|
||||
line-height: 40px !important;
|
||||
}
|
||||
|
||||
.first-element-grid-container {
|
||||
background: #fff;
|
||||
border: 1px solid #d7dae2;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<el-input
|
||||
v-count="{value, maxlength}"
|
||||
v-count="{value, maxlength, buttonDisabled}"
|
||||
:placeholder="$t('fu.search_bar.please_input')"
|
||||
show-word-limit
|
||||
:disabled="disabled"
|
||||
@ -16,14 +16,16 @@ export default {
|
||||
directives: {
|
||||
count: {
|
||||
update: function(el, binding) {
|
||||
const lg = binding.value.value?.length || 0
|
||||
const { value, maxlength, buttonDisabled } = binding.value
|
||||
if (buttonDisabled) return
|
||||
const lg = value?.length || 0
|
||||
const count = el.querySelector('.el-input__count')
|
||||
if (!count) return
|
||||
if (!lg) {
|
||||
if (count?.classList?.contains('no-zore')) {
|
||||
count.classList.remove('no-zore')
|
||||
}
|
||||
count.innerHTML = `0/${binding.value.maxlength || 200}`
|
||||
count.innerHTML = `0/${maxlength || 200}`
|
||||
return
|
||||
}
|
||||
if (el.querySelector('.no-zore')) {
|
||||
@ -34,7 +36,7 @@ export default {
|
||||
const num = document.createElement('span')
|
||||
const total = document.createElement('span')
|
||||
num.style.color = '#1F2329'
|
||||
total.innerHTML = `/${binding.value.maxlength || 200}`
|
||||
total.innerHTML = `/${maxlength || 200}`
|
||||
num.innerHTML = lg
|
||||
if (!newCount) return
|
||||
newCount.classList.add('el-input__count', 'no-zore')
|
||||
@ -44,6 +46,11 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
inject: {
|
||||
elForm: {
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
props: {
|
||||
disabled: Boolean,
|
||||
value: String,
|
||||
@ -52,6 +59,13 @@ export default {
|
||||
default: 200
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
buttonDisabled() {
|
||||
return Object.prototype.hasOwnProperty.call(this.$options.propsData, 'disabled')
|
||||
? this.disabled
|
||||
: (this.elForm || {}).disabled
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleChange(val) {
|
||||
this.$emit('input', val)
|
||||
|
||||
@ -17,8 +17,8 @@
|
||||
},
|
||||
className
|
||||
]"
|
||||
@mousedown="elementMouseDown"
|
||||
@touchstart="elementTouchDown"
|
||||
@mousedown="outerElementMouseDown"
|
||||
@mouseenter="enter"
|
||||
@mouseleave="leave"
|
||||
>
|
||||
@ -73,6 +73,22 @@
|
||||
:style="mainSlotStyleInner"
|
||||
class="main-background"
|
||||
>
|
||||
<div
|
||||
class="de-drag-area de-drag-top"
|
||||
@mousedown="elementMouseDown"
|
||||
/>
|
||||
<div
|
||||
class="de-drag-area de-drag-right"
|
||||
@mousedown="elementMouseDown"
|
||||
/>
|
||||
<div
|
||||
class="de-drag-area de-drag-bottom"
|
||||
@mousedown="elementMouseDown"
|
||||
/>
|
||||
<div
|
||||
class="de-drag-area de-drag-left"
|
||||
@mousedown="elementMouseDown"
|
||||
/>
|
||||
<svg-icon
|
||||
v-if="svgInnerEnable"
|
||||
:style="{'color':element.commonBackground.innerImageColor}"
|
||||
@ -863,6 +879,18 @@ export default {
|
||||
eventsFor = events.touch
|
||||
this.elementDown(e)
|
||||
},
|
||||
outerElementMouseDown(e) {
|
||||
// private 设置当前组件数据及状态
|
||||
this.$store.commit('setClickComponentStatus', true)
|
||||
if (this.element.component !== 'user-view' && this.element.component !== 'de-frame' && this.element.component !== 'v-text' && this.element.component !== 'de-rich-text' && this.element.component !== 'rect-shape' && this.element.component !== 'de-input-search' && this.element.component !== 'de-select-grid' && this.element.component !== 'de-number-range' && this.element.component !== 'de-date') {
|
||||
e.preventDefault()
|
||||
}
|
||||
// 阻止冒泡事件
|
||||
e.stopPropagation()
|
||||
this.$nextTick(() => {
|
||||
this.$store.commit('setCurComponent', { component: this.element, index: this.index })
|
||||
})
|
||||
},
|
||||
elementMouseDown(e) {
|
||||
// private 设置当前组件数据及状态
|
||||
this.$store.commit('setClickComponentStatus', true)
|
||||
@ -2131,4 +2159,42 @@ export default {
|
||||
.drag-on-tab-collision {
|
||||
z-index: 1000 !important;
|
||||
}
|
||||
|
||||
.de-drag-area {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.de-drag-area:hover {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.de-drag-top {
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.de-drag-right {
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 16px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.de-drag-bottom {
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.de-drag-left {
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 16px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
573
frontend/src/components/deIconPicker/deIconGroupPicker/index.vue
Normal file
@ -0,0 +1,573 @@
|
||||
<template>
|
||||
<div
|
||||
class="ui-fas"
|
||||
:class="'ui-fas-' + id"
|
||||
>
|
||||
<div
|
||||
v-if="!!name"
|
||||
class="selected-icon-container"
|
||||
>
|
||||
<span
|
||||
title="icon"
|
||||
:style="{ color: color }"
|
||||
>
|
||||
<e-icon
|
||||
:icon-name="name"
|
||||
:title="name"
|
||||
class="e-icon"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<el-popover
|
||||
ref="popover"
|
||||
v-model="visible"
|
||||
:disabled="disabled"
|
||||
:placement="myPlacement"
|
||||
popper-class="el-icon-popper"
|
||||
:width="popoverWidth"
|
||||
show-arrow
|
||||
trigger="manual"
|
||||
@show="setTempSelected"
|
||||
>
|
||||
<template slot="reference">
|
||||
<slot
|
||||
name="default"
|
||||
:data="{ prefixIcon, visible, placeholder, disabled, clearable, readonly, size }"
|
||||
>
|
||||
|
||||
<el-input
|
||||
ref="input"
|
||||
v-model="proxyValue"
|
||||
class="de-icon-picker-input"
|
||||
:placeholder="dynamicPlaceholder"
|
||||
:style="styles"
|
||||
:clearable="clearable"
|
||||
:disabled="disabled"
|
||||
:readonly="true"
|
||||
:size="size"
|
||||
@input="_change"
|
||||
@clear="_initIcon(false)"
|
||||
@focus="_popoverShowFun(false)"
|
||||
>
|
||||
<template
|
||||
v-if="showPrefix"
|
||||
slot="prepend"
|
||||
>
|
||||
<slot
|
||||
name="prepend"
|
||||
:icon="prefixIcon"
|
||||
>
|
||||
<e-icon
|
||||
:icon-name="prefixIcon"
|
||||
class="e-icon"
|
||||
/>
|
||||
</slot>
|
||||
</template>
|
||||
</el-input>
|
||||
</slot>
|
||||
</template>
|
||||
<div :class="'de-icon-picker-container-' + id">
|
||||
<div class="top-container">
|
||||
<el-color-picker
|
||||
v-model="curColor"
|
||||
:popper-class="'icon-picker-inner-color-' + id"
|
||||
show-alpha
|
||||
@change="colorChange"
|
||||
/>
|
||||
|
||||
<div class="top-sure-button-div">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
icon="el-icon-check"
|
||||
@click.stop="sure"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<el-divider class="top-divider" />
|
||||
|
||||
<el-scrollbar
|
||||
v-if="!destroy"
|
||||
ref="eScrollbar"
|
||||
tag="div"
|
||||
wrap-class="el-select-dropdown__wrap"
|
||||
view-class="el-select-dropdown__list"
|
||||
:class="'is-empty-' + id"
|
||||
>
|
||||
<div
|
||||
v-for="(group, gname, i) in dataGroup"
|
||||
:key="i"
|
||||
>
|
||||
<el-divider
|
||||
class="icon-type-line"
|
||||
content-position="left"
|
||||
>{{ $t('chart.' + gname.substr(1)) }}</el-divider>
|
||||
<ul
|
||||
v-if="group && group.length > 0"
|
||||
ref="fasIconList"
|
||||
class="fas-icon-list"
|
||||
>
|
||||
<li
|
||||
v-for="(item, index) in group"
|
||||
:key="index"
|
||||
class="picker-li"
|
||||
:style="tempSelected === item && (highLightColor !== '' || !!curColor) ? { color: highLightColor || curColor, border: '1px solid ' + curColor } : ''"
|
||||
@click="_selectedIcon(item)"
|
||||
>
|
||||
<slot
|
||||
name="icon"
|
||||
:icon="item"
|
||||
>
|
||||
<e-icon
|
||||
:icon-name="item"
|
||||
:title="item"
|
||||
class="e-icon"
|
||||
/>
|
||||
</slot>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul
|
||||
v-if="dataList && dataList.length > 0"
|
||||
ref="fasIconList"
|
||||
class="fas-icon-list"
|
||||
>
|
||||
<li
|
||||
v-for="(item, index) in dataList"
|
||||
:key="index"
|
||||
class="picker-li"
|
||||
:style="tempSelected === item && (highLightColor !== '' || !!curColor) ? { color: highLightColor || curColor, border: '1px solid ' + curColor } : ''"
|
||||
@click="_selectedIcon(item)"
|
||||
>
|
||||
<slot
|
||||
name="icon"
|
||||
:icon="item"
|
||||
>
|
||||
<e-icon
|
||||
:icon-name="item"
|
||||
:title="item"
|
||||
class="e-icon"
|
||||
/>
|
||||
</slot>
|
||||
</li>
|
||||
</ul>
|
||||
<span
|
||||
v-if="!dataGroup && (!dataList || !dataList.length)"
|
||||
class="fas-no-data"
|
||||
v-text="emptyText"
|
||||
/>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import iconList from '../iconList'
|
||||
import { off, on } from '../utils/index'
|
||||
import EIcon from '../eIcon/e-icon'
|
||||
import ElInput from 'element-ui/lib/input'
|
||||
import ElPopover from 'element-ui/lib/popover'
|
||||
import ElScrollbar from 'element-ui/lib/scrollbar'
|
||||
import { PopupManager } from 'element-ui/lib/utils/popup'
|
||||
|
||||
export default {
|
||||
name: 'DeIconGroupPicker',
|
||||
components: {
|
||||
EIcon,
|
||||
ElInput,
|
||||
ElPopover,
|
||||
ElScrollbar
|
||||
},
|
||||
props: {
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false
|
||||
}
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false
|
||||
}
|
||||
},
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false
|
||||
}
|
||||
},
|
||||
styles: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
placement: {
|
||||
type: String,
|
||||
default() {
|
||||
return 'bottom'
|
||||
}
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default() {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default() {
|
||||
return -1
|
||||
}
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default() {
|
||||
return 'medium'
|
||||
}
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default() {
|
||||
return '请选择图标'
|
||||
}
|
||||
},
|
||||
defaultIcon: {
|
||||
type: String,
|
||||
default() {
|
||||
return 'eiconfont e-icon-bi'
|
||||
}
|
||||
},
|
||||
emptyText: {
|
||||
type: String,
|
||||
default() {
|
||||
return '暂无可选图标'
|
||||
}
|
||||
},
|
||||
highLightColor: {
|
||||
type: String,
|
||||
default() {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
zIndex: {
|
||||
type: Number,
|
||||
default() {
|
||||
return null
|
||||
}
|
||||
},
|
||||
showPrefix: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false
|
||||
}
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default() {
|
||||
return 'rgba(255, 0, 0, 1.0)'
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
iconList: [],
|
||||
visible: false,
|
||||
prefixIcon: 'eiconfont e-icon-bi',
|
||||
name: '',
|
||||
icon: {},
|
||||
myPlacement: 'bottom',
|
||||
popoverWidth: 200,
|
||||
destroy: false,
|
||||
id: new Date().getTime(),
|
||||
proxyValue: '',
|
||||
curColor: '',
|
||||
tempSelected: '',
|
||||
iconGroup: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
dataList: function() {
|
||||
const arr1 = []
|
||||
for (let i = 0, len = this.iconList.length; i < len; i++) {
|
||||
if (arr1.indexOf(this.iconList[i]) === -1) {
|
||||
arr1.push(this.iconList[i])
|
||||
}
|
||||
}
|
||||
return arr1
|
||||
},
|
||||
dataGroup: function() {
|
||||
return JSON.parse(JSON.stringify(this.iconGroup))
|
||||
},
|
||||
dynamicPlaceholder() {
|
||||
return this.name ? '' : this.placeholder
|
||||
}
|
||||
|
||||
},
|
||||
watch: {
|
||||
value: function(val) {
|
||||
setTimeout(() => {
|
||||
this.name = val
|
||||
this.prefixIcon = this.name ? this.name : this.defaultIcon
|
||||
}, 50)
|
||||
},
|
||||
visible: function(val) {
|
||||
if (val === false) {
|
||||
this.$nextTick(() => {
|
||||
off(document, 'mouseup', this._popoverHideFun)
|
||||
})
|
||||
} else {
|
||||
this.$nextTick(() => {
|
||||
this.createIconList()
|
||||
on(document, 'mouseup', this._popoverHideFun)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
options: {
|
||||
handler(newV, oldV) {
|
||||
const self = this
|
||||
setTimeout(() => {
|
||||
self._initIcon(true)
|
||||
}, 50)
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this._updateW()
|
||||
},
|
||||
beforeDestroy() {
|
||||
off(document, 'mouseup', this._popoverHideFun)
|
||||
this.destroyIconList()
|
||||
},
|
||||
created() {
|
||||
this.createIconList()
|
||||
this._initIcon(true)
|
||||
this.curColor = this.color
|
||||
},
|
||||
methods: {
|
||||
colorChange(c) {
|
||||
this.color = c
|
||||
this.$emit('set-color', c)
|
||||
},
|
||||
setTempSelected() {
|
||||
this.tempSelected = this.name
|
||||
},
|
||||
sure() {
|
||||
this.visible = false
|
||||
this.name = this.tempSelected
|
||||
this.prefixIcon = this.name
|
||||
this.color = this.curColor
|
||||
this._emitFun(this.name)
|
||||
this.$emit('set-color', this.curColor)
|
||||
},
|
||||
_change(val) {
|
||||
this.iconList = this.icon.list.filter(function(i) {
|
||||
return i.indexOf(val) !== -1
|
||||
})
|
||||
},
|
||||
_initIcon(type) {
|
||||
this.prefixIcon = this.value && type && type === true ? this.value : this.defaultIcon
|
||||
this.name = type === true ? this.value : ''
|
||||
this.icon = Object.assign({}, iconList)
|
||||
if (this.options) {
|
||||
this.icon.list = []
|
||||
if (this.options.addIconList !== undefined &&
|
||||
this.options.addIconList &&
|
||||
this.options.addIconList.length > 0) {
|
||||
this.icon.addIcon(this.options.addIconList)
|
||||
}
|
||||
if (this.options.removeIconList !== undefined &&
|
||||
this.options.removeIconList &&
|
||||
this.options.removeIconList.length > 0) {
|
||||
this.icon.removeIcon(this.options.removeIconList)
|
||||
}
|
||||
if (this.options?.addIconGroup) {
|
||||
this.icon.initGroup(this.options.addIconGroup)
|
||||
}
|
||||
}
|
||||
this.iconList = this.icon.list
|
||||
this.iconGroup = this.icon.group
|
||||
|
||||
if (this.placement && (this.placement === 'bottom' || this.placement === 'top')) {
|
||||
this.myPlacement = this.placement
|
||||
}
|
||||
if (type === false) {
|
||||
this._emitFun('')
|
||||
}
|
||||
},
|
||||
|
||||
addIcon(item = []) {
|
||||
if (item !== undefined && item && item.length > 0) {
|
||||
this.icon.addIcon(item)
|
||||
this.iconList = this.icon.list
|
||||
}
|
||||
},
|
||||
removeIcon(item = []) {
|
||||
if (item !== undefined && item && item.length > 0) {
|
||||
this.icon.removeIcon(item)
|
||||
this.iconList = this.icon.list
|
||||
}
|
||||
},
|
||||
updatePopper(zIndex) {
|
||||
if (zIndex) {
|
||||
PopupManager.zIndex = zIndex
|
||||
}
|
||||
this._popoverShowFun(true)
|
||||
setTimeout(() => {
|
||||
this.$refs.popover.updatePopper()
|
||||
}, 100)
|
||||
},
|
||||
_selectedIcon(item) {
|
||||
this.tempSelected = item
|
||||
},
|
||||
_updateW() {
|
||||
this.$nextTick(() => {
|
||||
if (this.width === -1 && this.$refs.input && this.$refs.input.$el) {
|
||||
this.popoverWidth = this.$refs.input.$el.getBoundingClientRect().width - 36
|
||||
} else {
|
||||
this.popoverWidth = this.width
|
||||
}
|
||||
if (this.$refs.eScrollbar && this.$refs.eScrollbar.wrap) {
|
||||
this.$refs.eScrollbar.wrap.scrollTop = 0
|
||||
this.$refs.eScrollbar.handleScroll()
|
||||
this.$refs.eScrollbar.update()
|
||||
}
|
||||
})
|
||||
},
|
||||
_popoverShowFun(flag) {
|
||||
const _this = this
|
||||
if (_this.readonly !== true && _this.disabled !== true) {
|
||||
if (!flag && _this.zIndex) {
|
||||
PopupManager.zIndex = this.zIndex
|
||||
}
|
||||
_this.visible = true
|
||||
_this._updateW()
|
||||
}
|
||||
},
|
||||
_popoverHideFun(e) {
|
||||
const path = e.path || (e.composedPath && e.composedPath())
|
||||
const insideClassNameList = ['ui-fas-', 'de-icon-picker-container-', 'icon-picker-inner-color-']
|
||||
const isInside = path.some(list => {
|
||||
return list.className && typeof list.className === 'string' && insideClassNameList.some(cName => list.className.includes(cName + this.id))
|
||||
})
|
||||
|
||||
if (!isInside) {
|
||||
this.visible = false
|
||||
}
|
||||
},
|
||||
_emitFun(val) {
|
||||
this.$emit('input', val)
|
||||
this.$emit('change', val)
|
||||
},
|
||||
|
||||
destroyIconList() {
|
||||
this.destroy = true
|
||||
},
|
||||
|
||||
createIconList() {
|
||||
this.destroy = false
|
||||
},
|
||||
show() {
|
||||
this._popoverShowFun(false)
|
||||
},
|
||||
hide() {
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~element-ui/lib/theme-chalk/input.css';
|
||||
@import '~element-ui/lib/theme-chalk/popover.css';
|
||||
@import '~element-ui/lib/theme-chalk/scrollbar.css';
|
||||
@import '~element-ui/lib/theme-chalk/select-dropdown.css';
|
||||
|
||||
.fas-icon-list {
|
||||
list-style-type: none;
|
||||
margin: 0 0 0 -4px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.ui-fas .el-input__inner {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.fas-icon-list li {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.fas-icon-list li i,
|
||||
.fas-icon-list li svg {
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.el-icon-popper {
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.el-icon-popper[x-placement^="bottom"] {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.fas-no-data {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.e-icon {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.top-divider {
|
||||
margin: 5px 0 0 0 !important;
|
||||
}
|
||||
|
||||
.top-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.top-sure-button-div {
|
||||
margin: 4px 15px 0 auto;
|
||||
|
||||
::v-deep button {
|
||||
width: 25px;
|
||||
height: 20px;
|
||||
padding: 4px 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.selected-icon-container {
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
width: 21%;
|
||||
text-align: center;
|
||||
margin-top: 2px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.picker-li {
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
}
|
||||
.icon-type-line {
|
||||
margin: 13px 0;
|
||||
}
|
||||
</style>
|
||||
86
frontend/src/components/deIconPicker/eIcon/e-icon.vue
Normal file
@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<i
|
||||
v-if="fontClass"
|
||||
:class="iconName"
|
||||
@click="click(iconName,$event)"
|
||||
/>
|
||||
<svg
|
||||
v-else-if="svg"
|
||||
:class="svgClass"
|
||||
aria-hidden="true"
|
||||
@click="click(iconName,$event)"
|
||||
>
|
||||
<use :xlink:href="iconName" />
|
||||
</svg>
|
||||
<div
|
||||
v-else-if="isExternal"
|
||||
:style="styleExternalIcon"
|
||||
:class="className"
|
||||
class="icon external-icon"
|
||||
@click="click(iconName,$event)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isExternal } from '../utils/index'
|
||||
|
||||
export default {
|
||||
name: 'EIcon',
|
||||
props: {
|
||||
iconName: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
className: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
fontClass() {
|
||||
return this.iconName && this.iconName.trim().length > 2 && (!isExternal(this.iconName) && !this.iconName.startsWith('#'))
|
||||
},
|
||||
svg() {
|
||||
return this.iconName && this.iconName.trim().length > 2 && (!isExternal(this.iconName) && this.iconName.startsWith('#'))
|
||||
},
|
||||
isExternal() {
|
||||
return isExternal(this.iconName)
|
||||
},
|
||||
svgClass() {
|
||||
if (this.className) {
|
||||
return 'icon ' + this.className
|
||||
} else {
|
||||
return 'icon'
|
||||
}
|
||||
},
|
||||
styleExternalIcon() {
|
||||
return {
|
||||
'background-image': `url(${this.iconName})`,
|
||||
'background-repeat': 'no-repeat',
|
||||
'background-size': '100% 100%',
|
||||
'-moz-background-size': '100% 100%'
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
click(iconName, event) {
|
||||
if (event) event.preventDefault()
|
||||
this.$emit('click', iconName)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.external-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
1
frontend/src/components/deIconPicker/eIconList.js
Normal file
@ -0,0 +1 @@
|
||||
export default ['xianxingbenzitubiao1', 'xianxinganquansuotubiao', 'xianxingbenzitubiao2', 'xianxingdianzantubiao', 'xianxingdiannaotubiao', 'xianxingjishibentubiao', 'xianxingdianhuatubiao', 'xianxinghuishouzhantubiao', 'xianxingWIFItubiao', 'xianxingduihuakuangtubiao', 'xianxinglajitongtubiao', 'xianxingjiangpaitubiao2', 'xianxingjiaoyoutubiao', 'xianxingquerentubiao', 'xianxingrenwutubiao', 'xianxingjiangpaitubiao1', 'xianxingshoujitubiao', 'xianxinglianxirentubiao', 'xianxingrenyuantubiao', 'xianxinggongjutubiao', 'xianxingshenfentubiao', 'xianxingxiangjitubiao', 'xianxingwendatubiao', 'xianxingyanjingtubiao', 'xianxingxinxitubiao', 'xianxingxinjiantubiao', 'xianxingtudingtubiao', 'xianxingshijiantubiao', 'xianxingqianbaotubiao', 'xianxingtupiantubiao', 'xianxingzhifubaotubiao', 'xianxingyoujiantubiao', 'xianxingzhifeijitubiao', 'xianxingyuantubiao', 'xianxingxiangfatubiao', 'diannao-01', 'jiaojuan-01', 'shuji-01', 'gujianzhu-01', 'simiao-01', 'yundong-yumaoqiu', 'sanjiaojia-01', 'zhaoxiangji-01', 'shuihu-01', 'yumaopai-01', 'yanjing-01', 'chalaoban-01', 'shouji-01', 'yinzhang-01', 'xiangyan-01', 'guangpan-01', 'kafei-01', 'erji-01', 'foling-01', 'xiong-01', 'bingxiang', 'diannao', 'chufangcheng', 'biludianshi', 'dayinji', 'guangpan', 'jiashiqi', 'fengshan', 'kongtiao', 'dianfanbao', 'fengrenji', 'dianzicheng', 'mensuo', 'shexiangji', 'saodijiqiren', 'lvshuiji', 'shuzhuodeng', 'kafeiji', 'jisuanqi', 'xiyiji', 'shexiangtou'].map(s => 'eiconfont e-icon-' + s)
|
||||
1
frontend/src/components/deIconPicker/elementUI.js
Normal file
@ -0,0 +1 @@
|
||||
export default ['platform-eleme', 'eleme', 'delete-solid', 'delete', 's-tools', 'setting', 'user-solid', 'user', 'phone', 'phone-outline', 'more', 'more-outline', 'star-on', 'star-off', 's-goods', 'goods', 'warning', 'warning-outline', 'question', 'info', 'remove', 'circle-plus', 'success', 'error', 'zoom-in', 'zoom-out', 'remove-outline', 'circle-plus-outline', 'circle-check', 'circle-close', 's-help', 'help', 'minus', 'plus', 'check', 'close', 'picture', 'picture-outline', 'picture-outline-round', 'upload', 'upload2', 'download', 'camera-solid', 'camera', 'video-camera-solid', 'video-camera', 'message-solid', 'bell', 's-cooperation', 's-order', 's-platform', 's-fold', 's-unfold', 's-operation', 's-promotion', 's-home', 's-release', 's-ticket', 's-management', 's-open', 's-shop', 's-marketing', 's-flag', 's-comment', 's-finance', 's-claim', 's-custom', 's-opportunity', 's-data', 's-check', 's-grid', 'menu', 'share', 'd-caret', 'caret-left', 'caret-right', 'caret-bottom', 'caret-top', 'bottom-left', 'bottom-right', 'back', 'right', 'bottom', 'top', 'top-left', 'top-right', 'arrow-left', 'arrow-right', 'arrow-down', 'arrow-up', 'd-arrow-left', 'd-arrow-right', 'video-pause', 'video-play', 'refresh', 'refresh-right', 'refresh-left', 'finished', 'sort', 'sort-up', 'sort-down', 'rank', 'loading', 'view', 'c-scale-to-original', 'date', 'edit', 'edit-outline', 'folder', 'folder-opened', 'folder-add', 'folder-remove', 'folder-delete', 'folder-checked', 'tickets', 'document-remove', 'document-delete', 'document-copy', 'document-checked', 'document', 'document-add', 'printer', 'paperclip', 'takeaway-box', 'search', 'monitor', 'attract', 'mobile', 'scissors', 'umbrella', 'headset', 'brush', 'mouse', 'coordinate', 'magic-stick', 'reading', 'data-line', 'data-board', 'pie-chart', 'data-analysis', 'collection-tag', 'film', 'suitcase', 'suitcase-1', 'receiving', 'collection', 'files', 'notebook-1', 'notebook-2', 'toilet-paper', 'office-building', 'school', 'table-lamp', 'house', 'no-smoking', 'smoking', 'shopping-cart-full', 'shopping-cart-1', 'shopping-cart-2', 'shopping-bag-1', 'shopping-bag-2', 'sold-out', 'sell', 'present', 'box', 'bank-card', 'money', 'coin', 'wallet', 'discount', 'price-tag', 'news', 'guide', 'male', 'female', 'thumb', 'cpu', 'link', 'connection', 'open', 'turn-off', 'set-up', 'chat-round', 'chat-line-round', 'chat-square', 'chat-dot-round', 'chat-dot-square', 'chat-line-square', 'message', 'postcard', 'position', 'turn-off-microphone', 'microphone', 'close-notification', 'bangzhu', 'time', 'odometer', 'crop', 'aim', 'switch-button', 'full-screen', 'copy-document', 'mic', 'stopwatch', 'medal-1', 'medal', 'trophy', 'trophy-1', 'first-aid-kit', 'discover', 'place', 'location', 'location-outline', 'location-information', 'add-location', 'delete-location', 'map-location', 'alarm-clock', 'timer', 'watch-1', 'watch', 'lock', 'unlock', 'key', 'service', 'mobile-phone', 'bicycle', 'truck', 'ship', 'basketball', 'football', 'soccer', 'baseball', 'wind-power', 'light-rain', 'lightning', 'heavy-rain', 'sunrise', 'sunrise-1', 'sunset', 'sunny', 'cloudy', 'partly-cloudy', 'cloudy-and-sunny', 'moon', 'moon-night', 'dish', 'dish-1', 'food', 'chicken', 'fork-spoon', 'knife-fork', 'burger', 'tableware', 'sugar', 'dessert', 'ice-cream', 'hot-water', 'water-cup', 'coffee-cup', 'cold-drink', 'goblet', 'goblet-full', 'goblet-square', 'goblet-square-full', 'refrigerator', 'grape', 'watermelon', 'cherry', 'apple', 'pear', 'orange', 'coffee', 'ice-tea', 'ice-drink', 'milk-tea', 'potato-strips', 'lollipop', 'ice-cream-square', 'ice-cream-round'].map(s => 'el-icon-' + s)
|
||||
1
frontend/src/components/deIconPicker/fontAwesome.js
Normal file
61
frontend/src/components/deIconPicker/iconList.js
Normal file
@ -0,0 +1,61 @@
|
||||
import { TypeUtil } from './utils/index'
|
||||
import fontAwesome from './fontAwesome'
|
||||
import elementUI from './elementUI'
|
||||
import eIconList from './eIconList'
|
||||
|
||||
const add = function(list, item) {
|
||||
let arr = []
|
||||
if (item && TypeUtil.isArray(item)) {
|
||||
arr = list.concat(item)
|
||||
} else if (item && TypeUtil.isString(item)) {
|
||||
arr = arr.concat(list)
|
||||
arr.push(item)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
const remove = function(list, item) {
|
||||
if (item && TypeUtil.isArray(item)) {
|
||||
for (let i = 0; i < item.length; i++) {
|
||||
for (let j = 0; j < list.length; j++) {
|
||||
if (list[j] === item[i]) {
|
||||
list.splice(j, 1)
|
||||
j--
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (item && TypeUtil.isString(item)) {
|
||||
list = list.filter(function(i) {
|
||||
return i !== item
|
||||
})
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
const iconList = {
|
||||
list: [],
|
||||
group: {},
|
||||
|
||||
addIcon: function(item) {
|
||||
this.list = add(this.list, item)
|
||||
},
|
||||
addGroup: function(item) {
|
||||
const { value, type } = item
|
||||
this.group[type] = this.group[type] ? this.group[type] : []
|
||||
if (TypeUtil.isArray(value)) {
|
||||
this.group[type] = this.group[type].concat(value)
|
||||
} else {
|
||||
this.group[type].push(value)
|
||||
}
|
||||
},
|
||||
initGroup: function(data) {
|
||||
this.group = JSON.parse(JSON.stringify(data))
|
||||
},
|
||||
|
||||
removeIcon: function(item) {
|
||||
this.list = remove(this.list, item)
|
||||
}
|
||||
}
|
||||
|
||||
export { fontAwesome, elementUI, eIconList }
|
||||
export default iconList
|
||||
542
frontend/src/components/deIconPicker/index.vue
Normal file
@ -0,0 +1,542 @@
|
||||
<template>
|
||||
<div class="ui-fas">
|
||||
<div
|
||||
v-if="!!name"
|
||||
class="selected-icon-container"
|
||||
>
|
||||
<span
|
||||
title="icon"
|
||||
:style="{color: color}"
|
||||
>
|
||||
<e-icon
|
||||
:icon-name="name"
|
||||
:title="name"
|
||||
class="e-icon"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<el-popover
|
||||
ref="popover"
|
||||
v-model="visible"
|
||||
:disabled="disabled"
|
||||
:placement="myPlacement"
|
||||
popper-class="el-icon-popper"
|
||||
:width="popoverWidth"
|
||||
show-arrow
|
||||
trigger="manual"
|
||||
@show="setTempSelected"
|
||||
>
|
||||
<template slot="reference">
|
||||
<slot
|
||||
name="default"
|
||||
:data="{prefixIcon,visible,placeholder,disabled,clearable,readonly,size}"
|
||||
>
|
||||
|
||||
<el-input
|
||||
ref="input"
|
||||
v-model="proxyValue"
|
||||
class="de-icon-picker-input"
|
||||
:placeholder="dynamicPlaceholder"
|
||||
:style="styles"
|
||||
:clearable="clearable"
|
||||
:disabled="disabled"
|
||||
:readonly="true"
|
||||
:size="size"
|
||||
@input="_change"
|
||||
@clear="_initIcon(false)"
|
||||
@focus="_popoverShowFun(false)"
|
||||
>
|
||||
<template
|
||||
v-if="showPrefix"
|
||||
slot="prepend"
|
||||
>
|
||||
<slot
|
||||
name="prepend"
|
||||
:icon="prefixIcon"
|
||||
>
|
||||
<e-icon
|
||||
:icon-name="prefixIcon"
|
||||
class="e-icon"
|
||||
/>
|
||||
</slot>
|
||||
</template>
|
||||
</el-input>
|
||||
</slot>
|
||||
</template>
|
||||
<div class="de-icon-picker-container">
|
||||
<div class="top-container">
|
||||
<el-color-picker
|
||||
v-model="curColor"
|
||||
show-alpha
|
||||
@change="colorChange"
|
||||
/>
|
||||
|
||||
<div class="top-sure-button-div">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
icon="el-icon-check"
|
||||
@click.stop="sure"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<el-divider class="top-divider" />
|
||||
|
||||
<el-scrollbar
|
||||
v-if="!destroy"
|
||||
ref="eScrollbar"
|
||||
tag="div"
|
||||
wrap-class="el-select-dropdown__wrap"
|
||||
view-class="el-select-dropdown__list"
|
||||
:class="'is-empty-'+id"
|
||||
>
|
||||
<ul
|
||||
v-if="dataList && dataList.length > 0"
|
||||
ref="fasIconList"
|
||||
class="fas-icon-list"
|
||||
>
|
||||
<li
|
||||
v-for="(item, index) in dataList"
|
||||
:key="index"
|
||||
class="picker-li"
|
||||
:style="tempSelected === item && (highLightColor !== '' || !!curColor) ? {color: highLightColor || curColor, border: '1px solid ' + curColor} : ''"
|
||||
@click="_selectedIcon(item)"
|
||||
>
|
||||
<slot
|
||||
name="icon"
|
||||
:icon="item"
|
||||
>
|
||||
<e-icon
|
||||
:icon-name="item"
|
||||
:title="item"
|
||||
class="e-icon"
|
||||
/>
|
||||
</slot>
|
||||
</li>
|
||||
</ul>
|
||||
<span
|
||||
v-else
|
||||
class="fas-no-data"
|
||||
v-text="emptyText"
|
||||
/>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import iconList, { eIconList, elementUI, fontAwesome } from './iconList'
|
||||
import { off, on } from './utils/index'
|
||||
import EIcon from './eIcon/e-icon'
|
||||
import ElInput from 'element-ui/lib/input'
|
||||
import ElPopover from 'element-ui/lib/popover'
|
||||
import ElScrollbar from 'element-ui/lib/scrollbar'
|
||||
import { PopupManager } from 'element-ui/lib/utils/popup'
|
||||
|
||||
export default {
|
||||
name: 'EIconPicker',
|
||||
components: {
|
||||
EIcon,
|
||||
ElInput,
|
||||
ElPopover,
|
||||
ElScrollbar
|
||||
},
|
||||
props: {
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false
|
||||
}
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false
|
||||
}
|
||||
},
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false
|
||||
}
|
||||
},
|
||||
styles: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
placement: {
|
||||
type: String,
|
||||
default() {
|
||||
return 'bottom'
|
||||
}
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default() {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default() {
|
||||
return -1
|
||||
}
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default() {
|
||||
return 'medium'
|
||||
}
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default() {
|
||||
return '请选择图标'
|
||||
}
|
||||
},
|
||||
defaultIcon: {
|
||||
type: String,
|
||||
default() {
|
||||
return 'eiconfont e-icon-bi'
|
||||
}
|
||||
},
|
||||
emptyText: {
|
||||
type: String,
|
||||
default() {
|
||||
return '暂无可选图标'
|
||||
}
|
||||
},
|
||||
highLightColor: {
|
||||
type: String,
|
||||
default() {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
zIndex: {
|
||||
type: Number,
|
||||
default() {
|
||||
return null
|
||||
}
|
||||
},
|
||||
showPrefix: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false
|
||||
}
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default() {
|
||||
return 'rgba(255, 0, 0, 1.0)'
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
iconList: [],
|
||||
visible: false,
|
||||
prefixIcon: 'eiconfont e-icon-bi',
|
||||
name: '',
|
||||
icon: {},
|
||||
myPlacement: 'bottom',
|
||||
popoverWidth: 200,
|
||||
destroy: false,
|
||||
id: new Date().getTime(),
|
||||
proxyValue: '',
|
||||
curColor: '',
|
||||
tempSelected: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
dataList: function() {
|
||||
const arr1 = []
|
||||
for (let i = 0, len = this.iconList.length; i < len; i++) {
|
||||
if (arr1.indexOf(this.iconList[i]) === -1) {
|
||||
arr1.push(this.iconList[i])
|
||||
}
|
||||
}
|
||||
return arr1
|
||||
},
|
||||
dynamicPlaceholder() {
|
||||
return this.name ? '' : this.placeholder
|
||||
}
|
||||
|
||||
},
|
||||
watch: {
|
||||
value: function(val) {
|
||||
setTimeout(() => {
|
||||
this.name = val
|
||||
this.prefixIcon = this.name ? this.name : this.defaultIcon
|
||||
}, 50)
|
||||
},
|
||||
visible: function(val) {
|
||||
if (val === false) {
|
||||
this.$nextTick(() => {
|
||||
off(document, 'mouseup', this._popoverHideFun)
|
||||
})
|
||||
} else {
|
||||
this.$nextTick(() => {
|
||||
this.createIconList()
|
||||
on(document, 'mouseup', this._popoverHideFun)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
options: {
|
||||
handler(newV, oldV) {
|
||||
const self = this
|
||||
setTimeout(() => {
|
||||
self._initIcon(true)
|
||||
}, 50)
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this._updateW()
|
||||
},
|
||||
beforeDestroy() {
|
||||
off(document, 'mouseup', this._popoverHideFun)
|
||||
this.destroyIconList()
|
||||
},
|
||||
created() {
|
||||
this.createIconList()
|
||||
this._initIcon(true)
|
||||
this.curColor = this.color
|
||||
},
|
||||
methods: {
|
||||
colorChange(c) {
|
||||
this.color = c
|
||||
this.$emit('set-color', c)
|
||||
},
|
||||
setTempSelected() {
|
||||
this.tempSelected = this.name
|
||||
},
|
||||
sure() {
|
||||
this.visible = false
|
||||
this.name = this.tempSelected
|
||||
this.prefixIcon = this.name
|
||||
this.color = this.curColor
|
||||
this._emitFun(this.name)
|
||||
this.$emit('set-color', this.curColor)
|
||||
},
|
||||
_change(val) {
|
||||
this.iconList = this.icon.list.filter(function(i) {
|
||||
return i.indexOf(val) !== -1
|
||||
})
|
||||
},
|
||||
_initIcon(type) {
|
||||
this.prefixIcon = this.value && type && type === true ? this.value : this.defaultIcon
|
||||
this.name = type === true ? this.value : ''
|
||||
this.icon = Object.assign({}, iconList)
|
||||
if (this.options) {
|
||||
this.icon.list = []
|
||||
if (this.options.addIconList !== undefined &&
|
||||
this.options.addIconList &&
|
||||
this.options.addIconList.length > 0) {
|
||||
this.icon.addIcon(this.options.addIconList)
|
||||
}
|
||||
if (this.options.removeIconList !== undefined &&
|
||||
this.options.removeIconList &&
|
||||
this.options.removeIconList.length > 0) {
|
||||
this.icon.removeIcon(this.options.removeIconList)
|
||||
}
|
||||
if (this.options.FontAwesome === true) {
|
||||
this.icon.addIcon(fontAwesome)
|
||||
}
|
||||
if (this.options.ElementUI === true) {
|
||||
this.icon.addIcon(elementUI)
|
||||
}
|
||||
if (this.options.eIcon === true) {
|
||||
if (this.options.eIconSymbol) {
|
||||
const list = eIconList.map((item) => {
|
||||
return item.replace('eiconfont ', '#')
|
||||
})
|
||||
this.icon.addIcon(list)
|
||||
} else {
|
||||
this.icon.addIcon(eIconList)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.iconList = this.icon.list
|
||||
|
||||
if (this.placement && (this.placement === 'bottom' || this.placement === 'top')) {
|
||||
this.myPlacement = this.placement
|
||||
}
|
||||
if (type === false) {
|
||||
this._emitFun('')
|
||||
}
|
||||
},
|
||||
|
||||
addIcon(item = []) {
|
||||
if (item !== undefined && item && item.length > 0) {
|
||||
this.icon.addIcon(item)
|
||||
this.iconList = this.icon.list
|
||||
}
|
||||
},
|
||||
removeIcon(item = []) {
|
||||
if (item !== undefined && item && item.length > 0) {
|
||||
this.icon.removeIcon(item)
|
||||
this.iconList = this.icon.list
|
||||
}
|
||||
},
|
||||
updatePopper(zIndex) {
|
||||
if (zIndex) {
|
||||
PopupManager.zIndex = zIndex
|
||||
}
|
||||
this._popoverShowFun(true)
|
||||
setTimeout(() => {
|
||||
this.$refs.popover.updatePopper()
|
||||
}, 100)
|
||||
},
|
||||
_selectedIcon(item) {
|
||||
this.tempSelected = item
|
||||
},
|
||||
_updateW() {
|
||||
this.$nextTick(() => {
|
||||
if (this.width === -1 && this.$refs.input && this.$refs.input.$el) {
|
||||
this.popoverWidth = this.$refs.input.$el.getBoundingClientRect().width - 36
|
||||
} else {
|
||||
this.popoverWidth = this.width
|
||||
}
|
||||
if (this.$refs.eScrollbar && this.$refs.eScrollbar.wrap) {
|
||||
this.$refs.eScrollbar.wrap.scrollTop = 0
|
||||
this.$refs.eScrollbar.handleScroll()
|
||||
this.$refs.eScrollbar.update()
|
||||
}
|
||||
})
|
||||
},
|
||||
_popoverShowFun(flag) {
|
||||
const _this = this
|
||||
if (_this.readonly !== true && _this.disabled !== true) {
|
||||
if (!flag && _this.zIndex) {
|
||||
PopupManager.zIndex = this.zIndex
|
||||
}
|
||||
_this.visible = true
|
||||
_this._updateW()
|
||||
}
|
||||
},
|
||||
_popoverHideFun(e) {
|
||||
const path = e.path || (e.composedPath && e.composedPath())
|
||||
|
||||
const isInside = path.some(list => {
|
||||
return list.className && typeof list.className === 'string' && (list.className.indexOf('ui-fas') !== -1 || list.className.indexOf('de-icon-picker-container') !== -1)
|
||||
})
|
||||
|
||||
if (!isInside) {
|
||||
this.visible = false
|
||||
}
|
||||
|
||||
const isInput = path.some(list => {
|
||||
return list.className && typeof list.className === 'string' && list.className.indexOf('de-icon-picker-input') !== -1
|
||||
})
|
||||
|
||||
if (this.visible && isInput) {
|
||||
// this.visible = false
|
||||
}
|
||||
},
|
||||
_emitFun(val) {
|
||||
this.$emit('input', val)
|
||||
this.$emit('change', val)
|
||||
},
|
||||
|
||||
destroyIconList() {
|
||||
this.destroy = true
|
||||
},
|
||||
|
||||
createIconList() {
|
||||
this.destroy = false
|
||||
},
|
||||
show() {
|
||||
this._popoverShowFun(false)
|
||||
},
|
||||
hide() {
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~element-ui/lib/theme-chalk/input.css';
|
||||
@import '~element-ui/lib/theme-chalk/popover.css';
|
||||
@import '~element-ui/lib/theme-chalk/scrollbar.css';
|
||||
@import '~element-ui/lib/theme-chalk/select-dropdown.css';
|
||||
|
||||
.fas-icon-list {
|
||||
list-style-type: none;
|
||||
margin: 0 0 0 -4px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.ui-fas .el-input__inner {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.fas-icon-list li {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.fas-icon-list li i, .fas-icon-list li svg {
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.el-icon-popper {
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.el-icon-popper[x-placement^="bottom"] {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.fas-no-data {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.e-icon {
|
||||
font-size: 16px;
|
||||
}
|
||||
.top-divider {
|
||||
margin: 5px 0 0 0 !important;
|
||||
}
|
||||
.top-container {
|
||||
display: flex;
|
||||
}
|
||||
.top-sure-button-div {
|
||||
margin: 4px 15px 0 auto;
|
||||
::v-deep button {
|
||||
width: 25px;
|
||||
height: 20px;
|
||||
padding: 4px 5px;
|
||||
}
|
||||
}
|
||||
.selected-icon-container {
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
width: 21%;
|
||||
text-align: center;
|
||||
margin-top: 2px;
|
||||
pointer-events: none;
|
||||
}
|
||||
.picker-li {
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
}
|
||||
</style>
|
||||
27
frontend/src/components/deIconPicker/utils/TypeUtil.js
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
export const TypeUtil = {
|
||||
|
||||
isArray: function(obj) {
|
||||
return (typeof obj === 'object') && obj.constructor === Array
|
||||
},
|
||||
|
||||
isString: function(obj) {
|
||||
return (typeof obj === 'string') && obj.constructor === String
|
||||
},
|
||||
|
||||
isNumber: function(obj) {
|
||||
return (typeof obj === 'number') && obj.constructor === Number
|
||||
},
|
||||
|
||||
isDate: function(obj) {
|
||||
return (typeof obj === 'object') && obj.constructor === Date
|
||||
},
|
||||
|
||||
isFunction: function(obj) {
|
||||
return (typeof obj === 'function') && obj.constructor === Function
|
||||
},
|
||||
|
||||
isObject: function(obj) {
|
||||
return (typeof obj === 'object') && obj.constructor === Object
|
||||
}
|
||||
}
|
||||
36
frontend/src/components/deIconPicker/utils/dom.js
Normal file
@ -0,0 +1,36 @@
|
||||
import { isServer } from './util'
|
||||
|
||||
export const on = (function() {
|
||||
if (!isServer) {
|
||||
if (document && document.addEventListener) {
|
||||
return function(element, event, handler) {
|
||||
if (element && event && handler) {
|
||||
element.addEventListener(event, handler, false)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return function(element, event, handler) {
|
||||
if (element && event && handler) {
|
||||
element.attachEvent('on' + event, handler)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})()
|
||||
export const off = (function() {
|
||||
if (!isServer) {
|
||||
if (document && document.removeEventListener) {
|
||||
return function(element, event, handler) {
|
||||
if (element && event) {
|
||||
element.removeEventListener(event, handler, false)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return function(element, event, handler) {
|
||||
if (element && event) {
|
||||
element.detachEvent('on' + event, handler)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})()
|
||||
15
frontend/src/components/deIconPicker/utils/getSvg.js
Normal file
@ -0,0 +1,15 @@
|
||||
const req = require.context(process.env.VUE_APP_SVG, false, /\.svg$/)
|
||||
|
||||
const requireAllFile = requireContext => requireContext.keys().map(requireContext)
|
||||
requireAllFile(req)
|
||||
|
||||
const re = /\.\/(.*)\.svg/
|
||||
|
||||
const requireAll = requireContext => requireContext.keys()
|
||||
|
||||
const svgIcons = requireAll(req).map(i => {
|
||||
return '#' + i.match(re)[1]
|
||||
})
|
||||
|
||||
export default svgIcons
|
||||
|
||||
28
frontend/src/components/deIconPicker/utils/index.js
Normal file
@ -0,0 +1,28 @@
|
||||
(function(e, d, w) {
|
||||
if (!e.composedPath) {
|
||||
e.composedPath = function() {
|
||||
if (this.path) {
|
||||
return this.path
|
||||
}
|
||||
let target = this.target
|
||||
|
||||
this.path = []
|
||||
while (target.parentNode !== null) {
|
||||
this.path.push(target)
|
||||
target = target.parentNode
|
||||
}
|
||||
this.path.push(d, w)
|
||||
return this.path
|
||||
}
|
||||
}
|
||||
if (!String.prototype.startsWith) {
|
||||
// eslint-disable-next-line no-extend-native
|
||||
String.prototype.startsWith = function(search, pos) {
|
||||
return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search
|
||||
}
|
||||
}
|
||||
})(Event.prototype, document, window)
|
||||
|
||||
export * from './util'
|
||||
export * from './dom'
|
||||
export * from './TypeUtil'
|
||||
53
frontend/src/components/deIconPicker/utils/util.js
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
export const analyzingIconForIconfont = function(json) {
|
||||
let font_family = ''
|
||||
let css_prefix_text = ''
|
||||
let list = []
|
||||
if (json) {
|
||||
if (json.font_family) {
|
||||
font_family = json.font_family
|
||||
}
|
||||
if (json.css_prefix_text) {
|
||||
css_prefix_text = json.css_prefix_text
|
||||
}
|
||||
if (json.glyphs) {
|
||||
list = json.glyphs.map(function(value, index, array) {
|
||||
return font_family + ' ' + css_prefix_text + value.font_class
|
||||
})
|
||||
}
|
||||
}
|
||||
return {
|
||||
font_family,
|
||||
css_prefix_text,
|
||||
list
|
||||
}
|
||||
}
|
||||
|
||||
export const eIconSymbol = function(json) {
|
||||
let font_family = ''
|
||||
let css_prefix_text = ''
|
||||
let list = []
|
||||
if (json) {
|
||||
if (json.font_family) {
|
||||
font_family = json.font_family
|
||||
}
|
||||
if (json.css_prefix_text) {
|
||||
css_prefix_text = json.css_prefix_text
|
||||
}
|
||||
if (json.glyphs) {
|
||||
list = json.glyphs.map(function(value, index, array) {
|
||||
return '#' + css_prefix_text + value.font_class
|
||||
})
|
||||
}
|
||||
}
|
||||
return {
|
||||
font_family,
|
||||
css_prefix_text,
|
||||
list
|
||||
}
|
||||
}
|
||||
|
||||
export function isExternal(path) {
|
||||
return /^(https?:|data:|\/\/?)/.test(path)
|
||||
}
|
||||
export const isServer = typeof window === 'undefined'
|
||||
@ -47,6 +47,7 @@ import { isSameVueObj, mergeCustomSortOption } from '@/utils'
|
||||
import { getLinkToken, getToken } from '@/utils/auth'
|
||||
import customInput from '@/components/widget/deWidget/customInput'
|
||||
import { textSelectWidget } from '@/components/widget/deWidget/serviceNameFn.js'
|
||||
|
||||
export default {
|
||||
components: { ElVisualSelect },
|
||||
mixins: [customInput],
|
||||
@ -251,10 +252,20 @@ export default {
|
||||
handleElTagStyle() {
|
||||
setTimeout(() => {
|
||||
this.$refs['deSelect'] && this.$refs['deSelect'].$el && textSelectWidget(this.$refs['deSelect'].$el, this.element.style)
|
||||
}, 50)
|
||||
}, 500)
|
||||
},
|
||||
initLoad() {
|
||||
this.value = this.fillValueDerfault()
|
||||
this.initOptions()
|
||||
if (this.element.options.value) {
|
||||
this.value = this.fillValueDerfault()
|
||||
this.changeValue(this.value)
|
||||
}
|
||||
},
|
||||
refreshLoad() {
|
||||
this.initOptions()
|
||||
},
|
||||
initOptions() {
|
||||
this.data = []
|
||||
if (this.element.options.attrs.fieldId) {
|
||||
let method = multFieldValues
|
||||
@ -273,10 +284,6 @@ export default {
|
||||
bus.$emit('valid-values-change', false)
|
||||
})
|
||||
}
|
||||
if (this.element.options.value) {
|
||||
this.value = this.fillValueDerfault()
|
||||
this.changeValue(this.value)
|
||||
}
|
||||
},
|
||||
visualChange(value) {
|
||||
this.value = value
|
||||
|
||||
@ -286,6 +286,16 @@ export default {
|
||||
textSelectGridWidget: textSelectGridWidget,
|
||||
initLoad() {
|
||||
this.value = this.element.options.attrs.multiple ? [] : null
|
||||
this.initOptions()
|
||||
if (this.element.options.value) {
|
||||
this.value = this.fillValueDerfault()
|
||||
this.changeValue(this.value)
|
||||
}
|
||||
},
|
||||
refreshLoad() {
|
||||
this.initOptions()
|
||||
},
|
||||
initOptions() {
|
||||
if (this.element.options.attrs.fieldId) {
|
||||
let method = multFieldValues
|
||||
const token = this.$store.getters.token || getToken()
|
||||
@ -305,10 +315,6 @@ export default {
|
||||
}
|
||||
})
|
||||
}
|
||||
if (this.element.options.value) {
|
||||
this.value = this.fillValueDerfault()
|
||||
this.changeValue(this.value)
|
||||
}
|
||||
},
|
||||
changeValue(value) {
|
||||
if (!this.inDraw) {
|
||||
|
||||
@ -265,6 +265,17 @@ export default {
|
||||
},
|
||||
initLoad() {
|
||||
this.value = this.fillValueDerfault()
|
||||
this.data = []
|
||||
this.initOptions()
|
||||
if (this.element.options.value) {
|
||||
this.value = this.fillValueDerfault()
|
||||
this.changeValue(this.value)
|
||||
}
|
||||
},
|
||||
refreshLoad() {
|
||||
this.initOptions()
|
||||
},
|
||||
initOptions() {
|
||||
this.data = []
|
||||
if (this.element.options.attrs.fieldId) {
|
||||
let method = mappingFieldValues
|
||||
@ -283,10 +294,6 @@ export default {
|
||||
})
|
||||
})
|
||||
}
|
||||
if (this.element.options.value) {
|
||||
this.value = this.fillValueDerfault()
|
||||
this.changeValue(this.value)
|
||||
}
|
||||
},
|
||||
changeValue(value) {
|
||||
if (!this.inDraw) {
|
||||
|
||||
@ -79,7 +79,7 @@
|
||||
:canvas-style-data="canvasStyleData"
|
||||
:canvas-id="element.id+'-'+item.name"
|
||||
:panel-info="panelInfo"
|
||||
:in-screen="true"
|
||||
:in-screen="inScreen"
|
||||
:show-position="showPosition"
|
||||
/>
|
||||
</div>
|
||||
@ -232,6 +232,11 @@ export default {
|
||||
name: 'DeTabs',
|
||||
components: { TextAttr, Preview, DeCanvasTab, TabUseList, ViewSelect, DataeaseTabs },
|
||||
props: {
|
||||
inScreen: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
canvasId: {
|
||||
type: String,
|
||||
default: 'canvas-main'
|
||||
@ -635,7 +640,7 @@ export default {
|
||||
while (len--) {
|
||||
if (this.element.options.tabList[len].name === param.name) {
|
||||
this.element.options.tabList.splice(len, 1)
|
||||
|
||||
this.$store.commit('deleteComponentsWithCanvasId', this.element.id + '-' + param.name)
|
||||
const activeIndex = (len - 1 + this.element.options.tabList.length) % this.element.options.tabList.length
|
||||
this.activeTabName = this.element.options.tabList[activeIndex].name
|
||||
}
|
||||
|
||||
@ -99,6 +99,9 @@ class TextSelectGridServiceImpl extends WidgetService {
|
||||
isCustomSortWidget() {
|
||||
return true
|
||||
}
|
||||
isChinesSortWidget() {
|
||||
return true
|
||||
}
|
||||
fillValueDerfault(element) {
|
||||
const defaultV = element.options.value === null ? '' : element.options.value.toString()
|
||||
if (element.options.attrs.multiple) {
|
||||
|
||||
@ -105,7 +105,9 @@ class TextSelectServiceImpl extends WidgetService {
|
||||
isParamWidget() {
|
||||
return true
|
||||
}
|
||||
|
||||
isChinesSortWidget() {
|
||||
return true
|
||||
}
|
||||
fillValueDerfault(element) {
|
||||
const defaultV = element.options.value === null ? '' : element.options.value.toString()
|
||||
if (element.options.attrs.multiple) {
|
||||
|
||||
15
frontend/src/deicons/index.js
Normal file
@ -0,0 +1,15 @@
|
||||
const req = require.context('./svg', false, /\.svg$/)
|
||||
|
||||
const requireAllFile = requireContext => requireContext.keys().map(requireContext)
|
||||
requireAllFile(req)
|
||||
|
||||
const re = /\.\/(.*)\.svg/
|
||||
|
||||
const requireAll = requireContext => requireContext.keys()
|
||||
|
||||
const deSvgIcons = requireAll(req).map(i => {
|
||||
return '#' + i.match(re)[1]
|
||||
})
|
||||
|
||||
export default deSvgIcons
|
||||
|
||||
1
frontend/src/deicons/svg/1-trend-01-topright.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M423.731142 161.571862 423.731142 249.306043 713.416847 249.306043 160.428318 802.295596 221.877855 863.682711 774.803963 310.790372 774.803963 600.443331 862.637404 600.443331 862.637404 161.571862Z" /></svg>
|
||||
|
After Width: | Height: | Size: 476 B |
1
frontend/src/deicons/svg/1-trend-02-bottomright.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1000 1000" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M362.57 764.226h364.149c28.44 0 51.491-23.051 51.491-51.491v-364.149c0-28.44-23.051-51.491-51.491-51.491s-51.491 23.051-51.491 51.491v239.829l-349.073-349.073c-20.119-20.119-52.711-20.119-72.831 0s-20.119 52.711 0 72.831l349.073 349.073h-239.829c-14.202-0.001-27.093 5.754-36.415 15.076s-15.094 22.195-15.076 36.415c0 28.44 23.051 51.491 51.491 51.491z" /></svg>
|
||||
|
After Width: | Height: | Size: 629 B |
1
frontend/src/deicons/svg/1-trend-03-topleft.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1000 1000" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M661.43 259.774h-364.149c-28.44 0-51.491 23.051-51.491 51.491v364.149c0 28.44 23.051 51.491 51.491 51.491s51.491-23.051 51.491-51.491v-239.829l349.073 349.073c20.119 20.119 52.711 20.119 72.831 0s20.119-52.711 0-72.831l-349.073-349.073h239.829c14.202 0.001 27.093-5.754 36.415-15.076s15.094-22.195 15.076-36.415c0-28.44-23.051-51.491-51.491-51.491z" /></svg>
|
||||
|
After Width: | Height: | Size: 625 B |
1
frontend/src/deicons/svg/1-trend-04-bottomleft.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1000 1000" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M259.774 362.57v364.149c0 28.44 23.051 51.491 51.491 51.491h364.149c28.44 0 51.491-23.051 51.491-51.491s-23.051-51.491-51.491-51.491h-239.829l349.073-349.073c20.119-20.119 20.119-52.711 0-72.831s-52.711-20.119-72.831 0l-349.073 349.073v-239.829c0.001-14.202-5.754-27.093-15.076-36.415s-22.195-15.094-36.415-15.076c-28.44 0-51.491 23.051-51.491 51.491z" /></svg>
|
||||
|
After Width: | Height: | Size: 628 B |
1
frontend/src/deicons/svg/1-trend-05-top.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M470.016 976.896q-44.032 0-59.392-20.48t-15.36-65.536q0-20.48-0.512-64.512t-1.024-93.696-1.536-96.768-1.024-74.752q0-39.936-7.68-62.464t-35.328-21.504q-20.48 0-48.64-1.024t-49.664 0q-35.84 0-45.568-19.456t13.824-50.176q24.576-30.72 57.344-72.704t67.584-86.016 68.096-87.04 58.88-75.776q23.552-29.696 45.568-30.72t46.592 26.624q24.576 29.696 56.832 69.632t67.072 82.432 68.608 83.968 60.416 73.216q29.696 35.84 23.04 58.88t-43.52 23.04q-11.264 0-25.088 0.512t-29.184 1.024-30.208 1.024-27.136 0.512q-25.6 1.024-32.256 16.384t-5.632 41.984q0 29.696 0.512 77.824t1.024 100.352 1.536 101.376 1.024 79.872q0 13.312-2.048 27.648t-9.728 26.112-21.504 19.968-36.352 8.192q-27.648 0-52.736 0.512t-56.832 1.536z" /></svg>
|
||||
|
After Width: | Height: | Size: 978 B |
1
frontend/src/deicons/svg/1-trend-06-right.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M47.104 453.632q0-43.008 20.992-57.856t66.048-14.848q20.48 0 64.512 0.512t93.696 0.512 96.768 0.512 74.752 0.512q38.912 1.024 61.44-6.656t22.528-35.328q0-20.48 1.536-48.64t1.536-48.64q1.024-35.84 20.48-45.568t49.152 14.848q30.72 24.576 71.68 58.368t84.992 69.12 86.016 69.632 74.752 59.904q29.696 24.576 30.208 46.592t-28.16 45.568q-29.696 24.576-70.144 56.32t-83.968 65.536-85.504 67.072-74.752 58.88q-35.84 28.672-58.88 21.504t-22.016-44.032l0-24.576 0-29.696q0-15.36-0.512-30.208t-0.512-27.136q0-25.6-15.36-32.256t-41.984-6.656q-29.696 0-77.824-0.512t-100.352-0.512-101.376-0.512-79.872-0.512q-13.312 0-27.648-2.56t-26.112-9.728-18.944-20.992-7.168-37.376q0-27.648-0.512-53.248t0.512-57.344z" /></svg>
|
||||
|
After Width: | Height: | Size: 971 B |
1
frontend/src/deicons/svg/1-trend-07-left.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M966.656 567.296q0 43.008-20.48 58.368t-65.536 15.36l-64.512 0q-44.032 0-93.696 0.512t-96.768 0.512l-74.752 0q-38.912 0-61.952 7.68t-22.016 35.328q0 20.48-1.024 48.64t-1.024 49.664q0 35.84-19.456 45.568t-50.176-13.824q-30.72-24.576-72.704-57.856t-85.504-68.096-86.016-68.608-75.264-59.392q-30.72-24.576-31.232-46.592t28.16-45.568q28.672-24.576 68.608-56.832t82.944-66.56 84.48-68.096 74.24-60.416q35.84-28.672 58.88-22.016t23.04 43.52l0 25.6q0 14.336 0.512 29.696t1.024 30.208 0.512 26.112q1.024 25.6 16.384 32.256t41.984 6.656q29.696 0 77.824-0.512t100.352-0.512 101.376-0.512 79.872-0.512q13.312 0 27.648 2.048t26.112 9.728 19.456 21.504 7.68 36.352q0 27.648 0.512 53.248t0.512 57.344z" /></svg>
|
||||
|
After Width: | Height: | Size: 964 B |
1
frontend/src/deicons/svg/1-trend-08-bottom.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M564.224 44.032q43.008 0 58.368 20.48t15.36 65.536q0 20.48 0.512 64.512t0.512 93.696 0.512 96.768 0.512 74.752q0 38.912 7.68 61.952t35.328 22.016q19.456 0 48.128 1.024t49.152 1.024q35.84 0 45.568 18.944t-13.824 49.664q-24.576 30.72-57.344 72.704t-68.096 86.016-69.12 86.528-59.392 75.264q-23.552 29.696-45.568 30.72t-45.568-27.648q-24.576-29.696-57.344-69.632t-67.072-82.432-67.584-83.968-59.904-74.24q-29.696-35.84-22.528-58.88t44.032-23.04l24.576 0q14.336 0 29.696-0.512t30.208-1.536 26.112-1.024q26.624 0 32.768-15.36t6.144-41.984q0-29.696-0.512-77.824t-0.512-100.352-0.512-101.376-0.512-79.872q0-13.312 2.048-27.648t9.728-26.112 20.992-19.456 36.864-7.68q27.648 0 53.248-0.512t57.344-0.512z" /></svg>
|
||||
|
After Width: | Height: | Size: 971 B |
1
frontend/src/deicons/svg/1-trend-09-top1.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M65.582671 735.208665l446.417329-446.41733 446.417329 446.41733z" /></svg>
|
||||
|
After Width: | Height: | Size: 341 B |
1
frontend/src/deicons/svg/1-trend-10-bottom1.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M65.582671 288.791335l446.417329 446.41733 446.417329-446.41733z" /></svg>
|
||||
|
After Width: | Height: | Size: 341 B |
1
frontend/src/deicons/svg/1-trend-11-left1.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M735.208665 65.582671l-446.41733 446.417329 446.41733 446.417329z" /></svg>
|
||||
|
After Width: | Height: | Size: 342 B |
1
frontend/src/deicons/svg/1-trend-12-right1.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M288.791335 65.582671l446.41733 446.417329-446.41733 446.417329z" /></svg>
|
||||
|
After Width: | Height: | Size: 341 B |
1
frontend/src/deicons/svg/2-state-01-diamond.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 69.479l442.498 442.498-442.498 442.498-442.498-442.498 442.498-442.498z" /></svg>
|
||||
|
After Width: | Height: | Size: 353 B |
1
frontend/src/deicons/svg/2-state-02-triangle.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M71.675 893.33l440.325-762.683 440.325 762.683z" /></svg>
|
||||
|
After Width: | Height: | Size: 324 B |
1
frontend/src/deicons/svg/2-state-03-circle.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M62 512c0 248.528 201.472 450 450 450s450-201.472 450-450c0-248.528-201.472-450-450-450-248.528 0-450 201.472-450 450z" /></svg>
|
||||
|
After Width: | Height: | Size: 395 B |
1
frontend/src/deicons/svg/2-state-04-pentagon.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 63.34l141.072 285.815 315.433 45.84-228.24 222.503 53.879 314.185-282.144-148.368-282.144 148.368 53.879-314.185-228.24-222.503 315.433-45.84z" /></svg>
|
||||
|
After Width: | Height: | Size: 424 B |
1
frontend/src/deicons/svg/2-state-05-square.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M62 62h900v900h-900v-900z" /></svg>
|
||||
|
After Width: | Height: | Size: 302 B |
1
frontend/src/deicons/svg/2-state-06-flag.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M152.474 62.225c-26.856 0-56.286 21.748-56.286 48.663v802.451c0 26.798 28.773 48.653 55.579 48.653 26.789 0 56.286-21.857 56.286-48.663v-802.434c0-26.914-28.78-48.663-55.579-48.663zM730.146 129.011c-157.836 0-157.836-64.694-315.663-64.694-91.108 0-161.46 42.504-161.46 42.504l-0.658 484.313s71.010-42.446 162.119-42.446c157.827 0 157.827 64.694 315.663 64.694 98.74 0 197.923-51.845 197.923-51.845v-484.264s-99.183 51.737-197.923 51.737z" /></svg>
|
||||
|
After Width: | Height: | Size: 714 B |
1
frontend/src/deicons/svg/2-state-07-error.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 64C264.8 64 64 264.8 64 512s200.8 448 448 448 448-200.8 448-448S759.2 64 512 64z m238.4 641.6l-45.6 45.6L512 557.6 318.4 750.4l-45.6-45.6L467.2 512 273.6 318.4l45.6-45.6L512 467.2l193.6-193.6 45.6 45.6L557.6 512l192.8 193.6z" /></svg>
|
||||
|
After Width: | Height: | Size: 506 B |
1
frontend/src/deicons/svg/2-state-08-warn.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 64C264.8 64 64 264.8 64 512s200.8 448 448 448 448-200.8 448-448S759.2 64 512 64z m32 704h-64v-64h64v64z m-64-128V256h64v384h-64z" /></svg>
|
||||
|
After Width: | Height: | Size: 410 B |
1
frontend/src/deicons/svg/2-state-09-question.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 64C264.8 64 64 264.8 64 512s200.8 448 448 448 448-200.8 448-448S759.2 64 512 64z m32 704h-64v-64h64v64z m11.2-203.2l-5.6 4.8c-3.2 2.4-5.6 8-5.6 12.8v58.4h-64v-58.4c0-24.8 11.2-48 29.6-63.2l5.6-4.8c56-44.8 83.2-68 83.2-108C598.4 358.4 560 320 512 320c-49.6 0-86.4 36.8-86.4 86.4h-64C361.6 322.4 428 256 512 256c83.2 0 150.4 67.2 150.4 150.4 0 72.8-49.6 112.8-107.2 158.4z" /></svg>
|
||||
|
After Width: | Height: | Size: 652 B |
1
frontend/src/deicons/svg/2-state-10-ok.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 64C264.8 64 64 264.8 64 512s200.8 448 448 448 448-200.8 448-448S759.2 64 512 64zM428 718.4l-45.6 45.6-45.6-45.6-116-117.6 45.6-45.6L383.2 672l367.2-367.2 45.6 45.6-368 368z" /></svg>
|
||||
|
After Width: | Height: | Size: 454 B |
1
frontend/src/deicons/svg/3-rank-01-half.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M883.075899 428.228061l-267.119757-22.906709-104.369046-246.226914-104.363929 246.226914-267.122827 22.906709 202.63714 175.596274-60.72606 261.081227 229.575676-138.430816 229.577722 138.374534-60.780295-261.134439L883.075899 428.228061zM511.587096 656.715963 511.587096 311.183322l63.559595 149.966547 162.695452 14.038738-123.465986 106.871029 37.002752 158.998247L511.587096 656.715963z" /></svg>
|
||||
|
After Width: | Height: | Size: 667 B |
1
frontend/src/deicons/svg/3-rank-02-full.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M509.867 189.867L608 411.733l243.2 25.6-181.333 162.134 51.2 238.933-211.2-121.6-211.2 121.6 51.2-238.933L168.533 435.2l243.2-25.6 98.134-219.733z" /></svg>
|
||||
|
After Width: | Height: | Size: 423 B |
1
frontend/src/deicons/svg/3-rank-03-nice.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 128c52 0 102.4 10.4 149.6 30.4 45.6 19.2 86.4 47.2 122.4 82.4s63.2 76 82.4 122.4c20 47.2 30.4 97.6 30.4 149.6s-10.4 102.4-30.4 149.6c-19.2 45.6-47.2 86.4-82.4 122.4s-76.8 63.2-122.4 82.4c-47.2 20-97.6 30.4-149.6 30.4s-102.4-10.4-149.6-30.4c-45.6-19.2-86.4-47.2-122.4-82.4s-63.2-76.8-82.4-122.4C138.4 614.4 128 564 128 512s10.4-102.4 30.4-149.6C177.6 316.8 204.8 276 240 240s76-63.2 122.4-82.4C409.6 138.4 460 128 512 128m0-64C264.8 64 64 264.8 64 512s200.8 448 448 448 448-200.8 448-448S759.2 64 512 64zM288 384c0 35.2 28.8 64 64 64s64-28.8 64-64-28.8-64-64-64-64 28.8-64 64z m320 0.8c0 35.2 28.8 64 64 64s64-28.8 64-64-28.8-64-64-64-64 28-64 64zM512 768c46.4 0 92-15.2 132-44.8 37.6-28 68.8-67.2 91.2-114.4 8-16 0.8-35.2-15.2-42.4-16-8-35.2-0.8-42.4 15.2-17.6 37.6-43.2 68.8-72 90.4-28 20.8-60.8 32-93.6 32s-64.8-11.2-93.6-32.8c-28.8-21.6-53.6-52.8-72-90.4-8-16-27.2-22.4-42.4-15.2-16 8-22.4 26.4-15.2 42.4 22.4 47.2 54.4 86.4 91.2 114.4 40 30.4 85.6 45.6 132 45.6z" /></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
1
frontend/src/deicons/svg/3-rank-04-commonly.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 128c52 0 102.4 10.4 149.6 30.4 45.6 19.2 86.4 47.2 122.4 82.4s63.2 76 82.4 122.4c20 47.2 30.4 97.6 30.4 149.6s-10.4 102.4-30.4 149.6c-19.2 45.6-47.2 86.4-82.4 122.4s-76.8 63.2-122.4 82.4c-47.2 20-97.6 30.4-149.6 30.4s-102.4-10.4-149.6-30.4c-45.6-19.2-86.4-47.2-122.4-82.4s-63.2-76.8-82.4-122.4C138.4 614.4 128 564 128 512s10.4-102.4 30.4-149.6C177.6 316.8 204.8 276 240 240s76-63.2 122.4-82.4C409.6 138.4 460 128 512 128m0-64C264.8 64 64 264.8 64 512s200.8 448 448 448 448-200.8 448-448S759.2 64 512 64zM288 384c0 35.2 28.8 64 64 64s64-28.8 64-64-28.8-64-64-64-64 28-64 64z m320 0c0 35.2 28.8 64 64 64s64-28.8 64-64-28.8-64-64-64-64 28.8-64 64z m96 288c0-17.6-14.4-32-32-32H352c-17.6 0-32 14.4-32 32s14.4 32 32 32h320c17.6 0 32-14.4 32-32z" /></svg>
|
||||
|
After Width: | Height: | Size: 1021 B |
1
frontend/src/deicons/svg/3-rank-05-bad.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 128c52 0 102.4 10.4 149.6 30.4 45.6 19.2 86.4 47.2 122.4 82.4s63.2 76 82.4 122.4c20 47.2 30.4 97.6 30.4 149.6s-10.4 102.4-30.4 149.6c-19.2 45.6-47.2 86.4-82.4 122.4s-76.8 63.2-122.4 82.4c-47.2 20-97.6 30.4-149.6 30.4s-102.4-10.4-149.6-30.4c-45.6-19.2-86.4-47.2-122.4-82.4s-63.2-76.8-82.4-122.4C138.4 614.4 128 564 128 512s10.4-102.4 30.4-149.6C177.6 316.8 204.8 276 240 240s76-63.2 122.4-82.4C409.6 138.4 460 128 512 128m0-64C264.8 64 64 264.8 64 512s200.8 448 448 448 448-200.8 448-448S759.2 64 512 64z" /><path d="M288 384c0 35.2 28.8 64 64 64s64-28.8 64-64-28.8-64-64-64-64 28.8-64 64zM608 384c0 35.2 28.8 64 64 64s64-28.8 64-64-28.8-64-64-64-64 28.8-64 64zM513.6 512.8c-46.4 0-92 15.2-132 44.8C344 585.6 312 624.8 289.6 672c-8 16-0.8 35.2 15.2 42.4 16 7.2 35.2 0.8 42.4-15.2 17.6-37.6 42.4-68.8 72-90.4C448 587.2 480 576 512.8 576s64.8 11.2 93.6 32.8c28.8 21.6 53.6 52.8 72 90.4 7.2 16 26.4 22.4 42.4 15.2 16-7.2 22.4-26.4 15.2-42.4-22.4-47.2-54.4-86.4-91.2-114.4-39.2-29.6-84.8-44.8-131.2-44.8z" /></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
frontend/src/deicons/svg/3-rank-06-goodevaluate.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M320 834.4V491.2c0-10.4 5.6-20 14.4-25.6 79.2-48 220-168.8 220-271.2 0-4.8-5.6-66.4 40.8-66.4 0 0 118.4 28 44.8 320h208s47.2-4 47.2 48.8c0 0 2.4 66.4-67.2 324.8 0 0-21.6 74.4-48.8 74.4 0 0-340-32-431.2-32-15.2 0-28-13.6-28-29.6z m-173.6 34.4l96-4c8-1.6 13.6-8 13.6-16V494.4c0-8-5.6-14.4-13.6-16l-96-3.2c-9.6-1.6-18.4 5.6-18.4 16v361.6c-0.8 10.4 8 17.6 18.4 16z" /></svg>
|
||||
|
After Width: | Height: | Size: 637 B |
1
frontend/src/deicons/svg/3-rank-07-badevaluate.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M320 189.6v343.2c0 10.4 5.6 20 14.4 25.6 80 48 220.8 168.8 220.8 271.2 0 4.8-5.6 66.4 40.8 66.4 0 0 118.4-28 44.8-320h208s48 4 48-48.8c0 0 2.4-66.4-68-324.8 0 0-21.6-74.4-48.8-74.4 0 0-340 32-430.4 32-16.8 0-29.6 12.8-29.6 29.6zM146.4 155.2l96 4c8 1.6 13.6 8 13.6 16v355.2c0 8-5.6 14.4-13.6 16l-96 3.2c-9.6 1.6-18.4-5.6-18.4-16V171.2c0-10.4 8.8-17.6 18.4-16z" /></svg>
|
||||
|
After Width: | Height: | Size: 635 B |
1
frontend/src/deicons/svg/3-rank-08-badevaluatecircle.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 64C264.8 64 64 264.8 64 512s200.8 448 448 448 448-200.8 448-448S759.2 64 512 64zM340.8 525.6c0 4.8-4 9.6-8.8 10.4l-64 2.4c-5.6 0.8-12-4-12-10.4V288c0-6.4 5.6-11.2 12.8-10.4l64 2.4c4.8 0.8 8.8 5.6 8.8 10.4v235.2z m424-2.4c0 35.2-31.2 32.8-31.2 32.8H596C644.8 749.6 566.4 768 566.4 768c-30.4 0-27.2-40.8-27.2-44C539.2 656 446.4 576 393.6 544c-5.6-3.2-9.6-9.6-9.6-16.8V299.2c0-10.4 8.8-19.2 19.2-19.2 60 0 284-21.6 284-21.6 17.6 0 32 49.6 32 49.6 47.2 171.2 45.6 215.2 45.6 215.2z" /></svg>
|
||||
|
After Width: | Height: | Size: 759 B |