Merge branch 'dev' into pr@dev@feat_union_dataset

This commit is contained in:
XiaJunjie2020 2021-11-29 15:33:43 +08:00 committed by GitHub
commit 95f55ddf8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
74 changed files with 729 additions and 810 deletions

View File

@ -1,5 +1,6 @@
package io.dataease.auth.filter;
import com.auth0.jwt.algorithms.Algorithm;
import io.dataease.auth.entity.ASKToken;
import io.dataease.auth.entity.JWTToken;
import io.dataease.auth.entity.SysUserEntity;
@ -115,9 +116,9 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
DataEaseException.throwException(Translator.get("i18n_not_find_user"));
}
String password = user.getPassword();
Algorithm algorithm = Algorithm.HMAC256(password);
JWTUtils.verifySign(algorithm, token);
String newToken = JWTUtils.sign(tokenInfo, password);
// 设置响应的Header头新Token
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.addHeader("Access-Control-Expose-Headers", "RefreshAuthorization");

View File

@ -41,7 +41,6 @@ public class ShiroServiceImpl implements ShiroService {
filterChainDefinitionMap.put("/link/**", ANON);
filterChainDefinitionMap.put("/index.html", ANON);
filterChainDefinitionMap.put("/link.html", ANON);
filterChainDefinitionMap.put("/xggznb/**", ANON);
//获取主题信息

View File

@ -35,15 +35,23 @@ public class JWTUtils {
* @return 是否正确
*/
public static boolean verify(String token, TokenInfo tokenInfo, String secret) {
Algorithm algorithm = Algorithm.HMAC256(secret);
Verification verification = JWT.require(algorithm)
.withClaim("username", tokenInfo.getUsername())
.withClaim("userId", tokenInfo.getUserId());
JWTVerifier verifier = verification.build();
verifySign(algorithm, token);
verifier.verify(token);
return true;
}
public static void verifySign(Algorithm algorithm, String token) {
DecodedJWT decode = JWT.decode(token);
algorithm.verify(decode);
}
/**
* 获得token中的信息无需secret解密也能获得
*

View File

@ -21,5 +21,7 @@ public class VAuthModel implements Serializable {
private Long level;
private Long mode;
private static final long serialVersionUID = 1L;
}

View File

@ -653,6 +653,66 @@ public class VAuthModelExample {
addCriterion("`level` not between", value1, value2, "level");
return (Criteria) this;
}
public Criteria andModeIsNull() {
addCriterion("`mode` is null");
return (Criteria) this;
}
public Criteria andModeIsNotNull() {
addCriterion("`mode` is not null");
return (Criteria) this;
}
public Criteria andModeEqualTo(Long value) {
addCriterion("`mode` =", value, "mode");
return (Criteria) this;
}
public Criteria andModeNotEqualTo(Long value) {
addCriterion("`mode` <>", value, "mode");
return (Criteria) this;
}
public Criteria andModeGreaterThan(Long value) {
addCriterion("`mode` >", value, "mode");
return (Criteria) this;
}
public Criteria andModeGreaterThanOrEqualTo(Long value) {
addCriterion("`mode` >=", value, "mode");
return (Criteria) this;
}
public Criteria andModeLessThan(Long value) {
addCriterion("`mode` <", value, "mode");
return (Criteria) this;
}
public Criteria andModeLessThanOrEqualTo(Long value) {
addCriterion("`mode` <=", value, "mode");
return (Criteria) this;
}
public Criteria andModeIn(List<Long> values) {
addCriterion("`mode` in", values, "mode");
return (Criteria) this;
}
public Criteria andModeNotIn(List<Long> values) {
addCriterion("`mode` not in", values, "mode");
return (Criteria) this;
}
public Criteria andModeBetween(Long value1, Long value2) {
addCriterion("`mode` between", value1, value2, "mode");
return (Criteria) this;
}
public Criteria andModeNotBetween(Long value1, Long value2) {
addCriterion("`mode` not between", value1, value2, "mode");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -10,6 +10,7 @@
<result column="auth_type" jdbcType="VARCHAR" property="authType" />
<result column="create_by" jdbcType="VARCHAR" property="createBy" />
<result column="level" jdbcType="BIGINT" property="level" />
<result column="mode" jdbcType="BIGINT" property="mode" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.dataease.base.domain.VAuthModelWithBLOBs">
<result column="name" jdbcType="LONGVARCHAR" property="name" />
@ -74,7 +75,8 @@
</where>
</sql>
<sql id="Base_Column_List">
id, pid, node_type, model_type, model_inner_type, auth_type, create_by, `level`
id, pid, node_type, model_type, model_inner_type, auth_type, create_by, `level`,
`mode`
</sql>
<sql id="Blob_Column_List">
`name`, `label`
@ -118,12 +120,12 @@
<insert id="insert" parameterType="io.dataease.base.domain.VAuthModelWithBLOBs">
insert into v_auth_model (id, pid, node_type,
model_type, model_inner_type, auth_type,
create_by, `level`, `name`,
`label`)
create_by, `level`, `mode`,
`name`, `label`)
values (#{id,jdbcType=VARCHAR}, #{pid,jdbcType=VARCHAR}, #{nodeType,jdbcType=VARCHAR},
#{modelType,jdbcType=VARCHAR}, #{modelInnerType,jdbcType=VARCHAR}, #{authType,jdbcType=VARCHAR},
#{createBy,jdbcType=VARCHAR}, #{level,jdbcType=BIGINT}, #{name,jdbcType=LONGVARCHAR},
#{label,jdbcType=LONGVARCHAR})
#{createBy,jdbcType=VARCHAR}, #{level,jdbcType=BIGINT}, #{mode,jdbcType=BIGINT},
#{name,jdbcType=LONGVARCHAR}, #{label,jdbcType=LONGVARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.dataease.base.domain.VAuthModelWithBLOBs">
insert into v_auth_model
@ -152,6 +154,9 @@
<if test="level != null">
`level`,
</if>
<if test="mode != null">
`mode`,
</if>
<if test="name != null">
`name`,
</if>
@ -184,6 +189,9 @@
<if test="level != null">
#{level,jdbcType=BIGINT},
</if>
<if test="mode != null">
#{mode,jdbcType=BIGINT},
</if>
<if test="name != null">
#{name,jdbcType=LONGVARCHAR},
</if>
@ -225,6 +233,9 @@
<if test="record.level != null">
`level` = #{record.level,jdbcType=BIGINT},
</if>
<if test="record.mode != null">
`mode` = #{record.mode,jdbcType=BIGINT},
</if>
<if test="record.name != null">
`name` = #{record.name,jdbcType=LONGVARCHAR},
</if>
@ -246,6 +257,7 @@
auth_type = #{record.authType,jdbcType=VARCHAR},
create_by = #{record.createBy,jdbcType=VARCHAR},
`level` = #{record.level,jdbcType=BIGINT},
`mode` = #{record.mode,jdbcType=BIGINT},
`name` = #{record.name,jdbcType=LONGVARCHAR},
`label` = #{record.label,jdbcType=LONGVARCHAR}
<if test="_parameter != null">
@ -261,7 +273,8 @@
model_inner_type = #{record.modelInnerType,jdbcType=VARCHAR},
auth_type = #{record.authType,jdbcType=VARCHAR},
create_by = #{record.createBy,jdbcType=VARCHAR},
`level` = #{record.level,jdbcType=BIGINT}
`level` = #{record.level,jdbcType=BIGINT},
`mode` = #{record.mode,jdbcType=BIGINT}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>

View File

@ -22,4 +22,6 @@ public interface ExtChartViewMapper {
String searchAdviceSceneId(@Param("userId") String userId,@Param("panelId") String panelId);
int checkSameDataSet(@Param("viewIdSource") String viewIdSource,@Param("viewIdTarget") String viewIdTarget);
ChartViewDTO searchOneWithPrivileges(@Param("userId") String userId,@Param("id") String id );
}

View File

@ -8,6 +8,13 @@
<result column="privileges" property="privileges"/>
</resultMap>
<select id="searchOneWithPrivileges" resultMap="BaseResultMapDTO">
select
chart_view.*,
get_auths(id,'chart',#{userId}) as `privileges`
from chart_view where id = #{id}
</select>
<select id="searchOne" resultMap="BaseResultMapDTO">
select
id, `name`, scene_id, table_id, `type`, title, create_by, create_time, update_time,

View File

@ -11,9 +11,8 @@
select
id, `name`, scene_id, data_source_id, `type`, `mode`,`info`, create_by, create_time,
get_auths(id,'dataset',#{userId}) as `privileges`
from (select GET_V_AUTH_MODEL_ID_P_USE (#{userId}, 'dataset') cids) t,dataset_table
from dataset_table
<where>
FIND_IN_SET(dataset_table.id,cids)
<if test="id != null">
and id = #{id,jdbcType=VARCHAR}
</if>

View File

@ -160,7 +160,7 @@
and panel_group.level = #{level}
</if>
</where>
ORDER BY CONVERT(panel_group.name using gbk)
ORDER BY panel_group.node_type desc, CONVERT(panel_group.name using gbk)
</select>
<delete id="deleteCircle">

View File

@ -18,6 +18,7 @@
v_auth_model.auth_type,
v_auth_model.create_by,
v_auth_model.level,
v_auth_model.mode,
authInfo.PRIVILEGES AS `privileges`
FROM
( SELECT GET_V_AUTH_MODEL_ID_P_USE ( #{request.userId}, #{request.modelType} ) cids ) t,
@ -33,7 +34,7 @@
`sys_auth`.`id` = `sys_auth_detail`.`auth_id`
)))
WHERE
sys_auth_detail.privilege_value = #{request.userId}
sys_auth_detail.privilege_value = 1
AND sys_auth.auth_source_type = #{request.modelType}
AND (
(
@ -54,7 +55,7 @@
) authInfo ON v_auth_model.id = authInfo.auth_source
WHERE
FIND_IN_SET( v_auth_model.id, cids )
ORDER BY CONVERT(v_auth_model.label using gbk) asc
ORDER BY v_auth_model.node_type desc, CONVERT(v_auth_model.label using gbk) asc
</select>
</mapper>

View File

@ -32,15 +32,6 @@ public class IndexController {
return "index.html";
}
@GetMapping("/link")
public String link() {
return "link.html";
}
@GetMapping("/test")
public String test() {
return "test.html";
}
@GetMapping("/deApi")
public String deApi() {
@ -53,12 +44,12 @@ public class IndexController {
}
}
@GetMapping("/xggznb/{index}")
public String xggznb(@PathVariable(value = "index", required = true) Long index) {
@GetMapping("/link/{index}")
public String link(@PathVariable(value = "index", required = true) Long index) {
String url = panelLinkService.getUrlByIndex(index);
HttpServletResponse response = ServletUtils.response();
String param = url.substring(url.indexOf("?") + 1);
Cookie cookie = new Cookie("link", param);
Cookie cookie = new Cookie("link", param.split("=")[1]);
response.addCookie(cookie);
return url;
}

View File

@ -88,10 +88,6 @@ public class ChartViewController {
public ChartViewDTO getOneWithPermission(@PathVariable String id, @RequestBody ChartExtRequest requestList) throws Exception {
//如果能获取用户 则添加对应的权限
ChartViewDTO dto = chartViewService.getData(id, requestList);
if (dto != null && AuthUtils.getUser() != null) {
ChartViewDTO permissionDto = chartViewService.getOneWithPermission(dto.getId());
dto.setPrivileges(permissionDto.getPrivileges());
}
return dto;
}

View File

@ -10,9 +10,7 @@ import io.dataease.dto.datasource.TableFiled;
import io.dataease.dto.dataset.DataSetTableDTO;
import io.dataease.dto.dataset.ExcelFileData;
import io.dataease.service.dataset.DataSetTableService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@ -132,8 +130,13 @@ public class DataSetTableController {
return dataSetTableService.getDatasetDetail(id);
}
// @ApiOperation("excel上传")
@ApiOperation("excel上传")
@PostMapping("excel/upload")
@ApiImplicitParams({
@ApiImplicitParam(name = "file", value = "文件", required = true, dataType = "MultipartFile"),
@ApiImplicitParam(name = "tableId", value = "数据表ID", required = true, dataType = "String"),
@ApiImplicitParam(name = "editType", value = "编辑类型", required = true, dataType = "Integer")
})
public ExcelFileData excelUpload(@RequestParam("file") MultipartFile file, @RequestParam("tableId") String tableId, @RequestParam("editType") Integer editType) throws Exception {
return dataSetTableService.excelSaveAndParse(file, tableId, editType);
}

View File

@ -2,7 +2,6 @@ package io.dataease.controller.panel.server;
import io.dataease.base.domain.PanelLink;
import io.dataease.controller.ResultHolder;
import io.dataease.controller.panel.api.LinkApi;
import io.dataease.controller.request.chart.ChartExtRequest;
import io.dataease.controller.request.panel.link.*;
@ -17,6 +16,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.net.URLDecoder;
import java.util.Map;
@ -24,7 +24,6 @@ import java.util.Map;
public class LinkServer implements LinkApi {
@Autowired
private PanelLinkService panelLinkService;
@ -42,12 +41,11 @@ public class LinkServer implements LinkApi {
panelLinkService.changeEnablePwd(request);
}
@Override
public void resetOverTime(@RequestBody OverTimeRequest request) {
panelLinkService.overTime(request);
}
@Override
@ -61,15 +59,16 @@ public class LinkServer implements LinkApi {
}
@Override
public ValidateDto validate(@RequestBody LinkValidateRequest request) throws Exception{
public ValidateDto validate(@RequestBody LinkValidateRequest request) throws Exception {
String link = request.getLink();
link = URLDecoder.decode(link, "UTF-8");
String json = panelLinkService.decryptParam(link);
ValidateDto dto = new ValidateDto();
String resourceId = json;
PanelLink one = panelLinkService.findOne(resourceId);
dto.setResourceId(resourceId);
if (ObjectUtils.isEmpty(one)){
if (ObjectUtils.isEmpty(one)) {
dto.setValid(false);
return dto;
}
@ -91,14 +90,13 @@ public class LinkServer implements LinkApi {
}
@Override
public Object viewDetail(String viewId, ChartExtRequest requestList) throws Exception{
public Object viewDetail(String viewId, ChartExtRequest requestList) throws Exception {
return chartViewService.getData(viewId, requestList);
}
@Override
public String shortUrl(Map<String,String> param) {
public String shortUrl(Map<String, String> param) {
String resourceId = param.get("resourceId");
return panelLinkService.getShortUrl(resourceId);
}

View File

@ -1,6 +1,7 @@
package io.dataease.controller.request.chart;
import io.dataease.base.domain.ChartViewWithBLOBs;
import io.dataease.dto.chart.ChartViewDTO;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -11,7 +12,7 @@ import lombok.Data;
@Data
public class ChartCalRequest {
@ApiModelProperty("视图")
private ChartViewWithBLOBs view;
private ChartViewDTO view;
@ApiModelProperty("额外请求参数")
private ChartExtRequest requestList;
}

View File

@ -121,6 +121,9 @@ public class JdbcProvider extends DatasourceProvider {
row[j] = rs.getDate(j + 1).toString();
}
break;
case Types.BOOLEAN:
row[j] = rs.getBoolean(j + 1) ? "1" : "0";
break;
default:
row[j] = rs.getString(j + 1);
break;

View File

@ -40,6 +40,7 @@ public class HiveQueryProvider extends QueryProvider {
@Override
public Integer transFieldType(String field) {
field = field.toLowerCase();
switch (field) {
case "varchar":
case "string":

View File

@ -79,11 +79,6 @@ public class ChartViewService {
Optional.ofNullable(chartView.getId()).ifPresent(id -> {
CacheUtils.remove(JdbcConstants.VIEW_CACHE_KEY, id);
});
try {
calcData(chartView, new ChartExtRequest(), true);
} catch (Exception e) {
}
return getOneWithPermission(chartView.getId());
}
@ -167,12 +162,9 @@ public class ChartViewService {
}
public ChartViewDTO getOneWithPermission(String id) {
ChartViewRequest chartViewRequest = new ChartViewRequest();
chartViewRequest.setId(id);
chartViewRequest.setUserId(String.valueOf(AuthUtils.getUser().getUserId()));
return extChartViewMapper.searchOne(chartViewRequest);
String userId = AuthUtils.getUser()!=null?String.valueOf(AuthUtils.getUser().getUserId()):"NONE";
return extChartViewMapper.searchOneWithPrivileges(userId,id);
}
public void delete(String id) {
chartViewMapper.deleteByPrimaryKey(id);
}
@ -184,7 +176,7 @@ public class ChartViewService {
}
public ChartViewDTO getData(String id, ChartExtRequest request) throws Exception {
ChartViewWithBLOBs view = chartViewMapper.selectByPrimaryKey(id);
ChartViewDTO view = this.getOneWithPermission(id);
// 如果是从仪表板获取视图数据则仪表板的查询模式查询结果的数量覆盖视图对应的属性
if (CommonConstants.VIEW_QUERY_FROM.PANEL.equals(request.getQueryFrom()) && CommonConstants.VIEW_RESULT_MODE.CUSTOM.equals(request.getResultMode())) {
view.setResultMode(request.getResultMode());
@ -193,7 +185,7 @@ public class ChartViewService {
return calcData(view, request, request.isCache());
}
public ChartViewDTO calcData(ChartViewWithBLOBs view, ChartExtRequest requestList, boolean cache) throws Exception {
public ChartViewDTO calcData(ChartViewDTO view, ChartExtRequest requestList, boolean cache) throws Exception {
if (ObjectUtils.isEmpty(view)) {
throw new RuntimeException(Translator.get("i18n_chart_delete"));
}

View File

@ -980,6 +980,7 @@ public class DataSetTableService {
datasetTableField.setTableId(datasetTable.getId());
datasetTableField.setColumnIndex(i);
}
dataSetTableFieldsService.deleteByTableId(datasetTable.getId());
dataSetTableFieldsService.batchEdit(fieldList);
// custom 创建doris视图
if (datasetTable.getMode() == 1) {

View File

@ -32,7 +32,7 @@ import java.util.List;
public class PanelLinkService {
private static final String BASEURL = "/link.html?link=";
private static final String SHORT_URL_PREFIX = "/xggznb/";
private static final String SHORT_URL_PREFIX = "/link/";
@Resource
private PanelLinkMapper mapper;

File diff suppressed because one or more lines are too long

View File

@ -80,8 +80,6 @@ CREATE TABLE `sys_menu` (
`create_time` bigint(13) DEFAULT NULL COMMENT '创建日期',
`update_time` bigint(13) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`menu_id`) USING BTREE,
UNIQUE KEY `uniq_title` (`title`),
UNIQUE KEY `uniq_name` (`name`),
KEY `inx_pid` (`pid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci AUTO_INCREMENT=53 ROW_FORMAT=COMPACT COMMENT='系统菜单';
@ -103,10 +101,6 @@ CREATE TABLE `sys_user` (
`update_time` bigint(13) DEFAULT NULL COMMENT '更新时间',
`language` varchar(20) DEFAULT NULL COMMENT '语言',
PRIMARY KEY (`user_id`) USING BTREE,
UNIQUE KEY `UK_kpubos9gc2cvtkb0thktkbkes` (`email`) USING BTREE,
UNIQUE KEY `username` (`username`) USING BTREE,
UNIQUE KEY `uniq_username` (`username`),
UNIQUE KEY `uniq_email` (`email`),
KEY `FK5rwmryny6jthaaxkogownknqp` (`dept_id`) USING BTREE,
KEY `inx_enabled` (`enabled`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci AUTO_INCREMENT=3 ROW_FORMAT=COMPACT COMMENT='系统用户';
@ -119,23 +113,19 @@ CREATE TABLE `sys_role` (
`update_by` varchar(255) DEFAULT NULL COMMENT '更新者',
`create_time` bigint(13) DEFAULT NULL COMMENT '创建日期',
`update_time` bigint(13) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`role_id`) USING BTREE,
UNIQUE KEY `uniq_name` (`name`),
KEY `role_name_index` (`name`)
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci AUTO_INCREMENT=3 ROW_FORMAT=COMPACT COMMENT='角色表';
CREATE TABLE `sys_roles_menus` (
`menu_id` bigint(20) NOT NULL COMMENT '菜单ID',
`role_id` bigint(20) NOT NULL COMMENT '角色ID',
PRIMARY KEY (`menu_id`,`role_id`) USING BTREE,
KEY `FKcngg2qadojhi3a651a5adkvbq` (`role_id`) USING BTREE
PRIMARY KEY (`menu_id`,`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='角色菜单关联';
CREATE TABLE `sys_users_roles` (
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`role_id` bigint(20) NOT NULL COMMENT '角色ID',
PRIMARY KEY (`user_id`,`role_id`) USING BTREE,
KEY `FKq4eq273l04bpu4efj0jd0jb98` (`role_id`) USING BTREE
PRIMARY KEY (`user_id`,`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='用户角色关联';
CREATE TABLE `my_plugin` (
@ -184,9 +174,7 @@ CREATE TABLE IF NOT EXISTS `dataset_table_field` (
`checked` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否选中',
`column_index` int(10) NOT NULL COMMENT '列位置',
`last_sync_time` bigint(13) DEFAULT NULL COMMENT '同步时间',
PRIMARY KEY (`id`),
KEY `IDX_TABLE_ID` (`table_id`),
KEY `IDX_DE_TYPE` (`de_type`)
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `dataset_table_task`(
@ -200,8 +188,7 @@ CREATE TABLE IF NOT EXISTS `dataset_table_task`(
`end` varchar(50) NOT NULL COMMENT '结束限制 0 无限制 1 设定结束时间',
`end_time` bigint(13) COMMENT '结束时间',
`create_time` bigint(13) COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `IDX_TABLE_ID` (`table_id`)
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS `dataset_table_task_log` (
@ -213,8 +200,7 @@ CREATE TABLE IF NOT EXISTS `dataset_table_task_log` (
`status` varchar(50) NOT NULL COMMENT '执行状态',
`info` longtext COMMENT '错误信息',
`create_time` bigint(13) DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `IDX_TABLE_ID` (`task_id`)
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
-- chart start
@ -246,8 +232,7 @@ CREATE TABLE `chart_view` (
`update_time` bigint(13) DEFAULT NULL COMMENT '更新时间',
`snapshot` longtext COMMENT '缩略图 ',
`style_priority` varchar(255) DEFAULT 'panel' COMMENT '样式优先级 panel 仪表板 view 视图',
PRIMARY KEY (`id`),
KEY `IDX_TABLE_ID` (`table_id`)
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
-- chart end
@ -300,8 +285,7 @@ CREATE TABLE `panel_store` (
`panel_group_id` varchar(50) NOT NULL COMMENT '仪表板ID',
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`create_time` bigint(13) DEFAULT NULL COMMENT '创建日期',
PRIMARY KEY (`store_id`) USING BTREE,
KEY `UK_store_user_id` (`user_id`)
PRIMARY KEY (`store_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci AUTO_INCREMENT=7 ROW_FORMAT=COMPACT COMMENT='仪表板收藏';
@ -311,10 +295,7 @@ CREATE TABLE `panel_share` (
`target_id` bigint(20) DEFAULT NULL COMMENT '目标ID',
`create_time` bigint(13) DEFAULT NULL COMMENT '创建日期',
`type` int(8) DEFAULT NULL COMMENT '类型0:user,1:role,2dept',
PRIMARY KEY (`share_id`) USING BTREE,
KEY `UK_share_arget_id` (`target_id`) ,
KEY `UK_share_panel_group_id` (`panel_group_id`) ,
KEY `UK_share_type` (`type`)
PRIMARY KEY (`share_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci AUTO_INCREMENT=7 ROW_FORMAT=COMPACT COMMENT='仪表板分享';
CREATE TABLE `panel_link` (

View File

@ -4,10 +4,30 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="shortcut icon" href="<%= BASE_URL %>favicon.ico">
<title>DataEase</title>
</head>
<body style="height: 100%;">
<div id="link"></div>
</body>
<script>
function getQueryVariable(variable) {
debugger
let query = window.location.search.substring(1)
let vars = []
if (!query) {
query = document.cookie
vars = query.split(';')
}else {
vars = query.split('&')
}
for (var i = 0; i < vars.length; i++) {
const pair = vars[i].split('=')
if (pair[0].trim() === variable) { return pair[1] }
}
return (false)
}
const link = getQueryVariable('link')
const url = "/#/delink?link="+encodeURIComponent(link)
window.location.href = url
</script>
</html>

View File

@ -4,10 +4,10 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="shortcut icon" href="<%= BASE_URL %>favicon.ico">
<title>DataEase</title>
</head>
<body style="height: 100%;">
<div id="nolic"></div>
<div>缺少许可</div>
</body>
</html>

View File

@ -1,11 +1,11 @@
import request from '@/utils/request'
export function queryAuthModel(data) {
export function queryAuthModel(data, loading = true, timeout = 30000) {
return request({
url: 'authModel/queryAuthModel',
method: 'post',
loading: true,
timeout: 30000,
loading: loading,
timeout: timeout,
data
})
}

View File

@ -40,7 +40,7 @@ export function chartGroupTree(data) {
return request({
url: '/chart/group/tree',
method: 'post',
loading: true,
loading: false,
data
})
}

View File

@ -80,7 +80,7 @@ export function listDatasource() {
export function getTable(id, hideMsg = false) {
return request({
url: '/dataset/table/get/' + id,
loading: true,
loading: false,
method: 'post',
hideMsg: hideMsg
})

View File

@ -36,20 +36,22 @@ export function querySubjectWithGroup(data) {
})
}
export function defaultTree(data) {
export function defaultTree(data, loading = true, timeout = 30000) {
return request({
url: '/panel/group/defaultTree',
method: 'post',
loading: true,
loading: loading,
timeout: timeout,
data
})
}
export function groupTree(data) {
export function groupTree(data, loading = true, timeout = 30000) {
return request({
url: '/panel/group/tree',
method: 'post',
loading: true,
loading: loading,
timeout: timeout,
data
})
}

View File

@ -1,6 +1,6 @@
<template>
<div v-loading="dataLoading" class="bg">
<Preview v-show="!dataLoading" />
<Preview v-if="!dataLoading" />
</div>
</template>
<script>
@ -53,8 +53,10 @@ export default {
sourceFieldId: jumpParam.sourceFieldId,
targetPanelId: this.panelId
}
this.dataLoading = true
//
queryTargetPanelJumpInfo(jumpRequestParam).then(rsp => {
this.dataLoading = false
this.$store.commit('setNowTargetPanelJumpInfo', rsp.data)
this.$store.commit('addViewTrackFilter', jumpParam)
})

View File

@ -31,7 +31,10 @@ export default {
},
methods: {
trackButtonClick() {
this.$refs.trackButton.click()
const _this = this
setTimeout(() => {
_this.$refs.trackButton.click()
}, 50)
},
trackMenuClick(menu) {
this.$emit('trackClick', menu)

View File

@ -78,12 +78,12 @@
<el-input v-model="styleInfo.margin" type="number" size="mini" min="0" max="99" @change="styleChange" />
</div>
<el-tooltip v-if="attrShow('time_margin')" :content="$t('panel.margin')">
<el-tooltip v-if="attrShow('padding')" :content="$t('panel.margin')">
<i style="float: left;margin-top: 3px;margin-left: 2px;" class="icon iconfont icon-margin" />
</el-tooltip>
<div v-if="attrShow('time_margin')" style="width: 70px;float: left;margin-top: 2px;margin-left: 2px;">
<el-input v-model="styleInfo.time_margin" type="number" size="mini" min="0" max="99" @change="styleChange" />
<div v-if="attrShow('padding')" style="width: 70px;float: left;margin-top: 2px;margin-left: 2px;">
<el-input v-model="styleInfo.padding" type="number" size="mini" min="0" max="99" @change="styleChange" />
</div>
<el-tooltip v-if="attrShow('opacity')" :content="$t('panel.opacity')">
@ -268,7 +268,8 @@ export default {
'color',
'backgroundColor',
'date-format',
'time_margin'
'time_margin',
'padding'
/* 'margin' */
],
//

View File

@ -11,9 +11,6 @@
</span>
</div>
<div v-else class="toolbar">
<el-tooltip :content="'移动端布局'">
<el-button class="icon iconfont-tb icon-yidongduan" size="mini" circle @click="openMobileLayout" />
</el-tooltip>
<el-tooltip v-if="!canvasStyleData.auxiliaryMatrix" :content="$t('panel.new_element_distribution')+':'+$t('panel.suspension')">
<el-button class="icon iconfont-tb icon-xuanfuanniu" size="mini" circle @click="auxiliaryMatrixChange" />
</el-tooltip>

View File

@ -307,8 +307,8 @@ const list = [
borderStyle: 'solid',
borderColor: '#000000',
borderRadius: 0,
/* margin: 10, */
time_margin: 0
time_margin: 0,
padding: 10
},
formatInfo: {
openMode: '0',

View File

@ -10,7 +10,8 @@ export function getStyle(style, filter = []) {
'borderWidth',
'letterSpacing',
'borderRadius',
'margin'
'margin',
'padding'
]
const result = {}
@ -75,7 +76,7 @@ export function colorRgb(color, opacity) {
}
// 处理六位的颜色值
var sColorChange = []
for (var i = 1; i < 7; i += 2) {
for (let i = 1; i < 7; i += 2) {
sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2)))
}
if (opacity || opacity === 0) {

View File

@ -162,11 +162,11 @@ export default {
height: 100%;
}
.first-element-contaner {
width: calc(100% - 10px);
width: 100%;
background: initial;
position:absolute;
bottom: 5px;
margin: 0 4px;
bottom: 0px;
margin: 0 0px;
div {
width: 100%;
}
@ -174,7 +174,7 @@ export default {
.first-element-grid-contaner {
background: #fff;
border: 1px solid #d7dae2;
top: 5px;
top: 0px;
}
.condition-main-line {
height: 40px !important;

View File

@ -18,7 +18,7 @@
<span style="display: flex;flex: 1;width: 0;">
<el-radio v-if="!options.attrs.multiple" v-model="options.value" :label="data.id" @change="changeRadioBox"><span> {{ node.label }} </span></el-radio>
<el-checkbox v-if="options.attrs.multiple && data.id !== allNode.id" v-model="data.checked" :label="data.id" @change="changeCheckBox(data)"><span> {{ node.label }} </span></el-checkbox>
<el-checkbox v-if="inDraw && options.attrs.multiple && data.id === allNode.id" v-model="data.checked" :indeterminate="data.indeterminate" :label="data.id" @change="allCheckChange(data)"><span> {{ node.label }} </span></el-checkbox>
<el-checkbox v-if="options.attrs.multiple && data.id === allNode.id" v-model="data.checked" :indeterminate="data.indeterminate" :label="data.id" @change="allCheckChange(data)"><span> {{ node.label }} </span></el-checkbox>
</span>
<span v-if="!options.attrs.multiple && options.value && options.value === data.id" class="child">
<span style="margin-left: 12px;" @click.stop>
@ -100,7 +100,7 @@ export default {
this.allNode.indeterminate = false
this.allNode.checked = false
}
this.setMutiBox()
// this.setMutiBox()
} else {
!sourceValid && (this.options.value = null)
sourceValid && Array.isArray(sourceValue) && (this.options.value = sourceValue[0])
@ -169,6 +169,14 @@ export default {
if (index >= 0 && !data.checked) {
values.splice(index, 1)
}
const datas = JSON.parse(JSON.stringify(this.options.attrs.datas))
this.options.attrs.datas = []
datas.forEach(item => {
if (item.id === data.id) {
item.checked = data.checked
}
})
this.options.attrs.datas = datas
this.setAllNodeStatus()
@ -194,13 +202,15 @@ export default {
allCheckChange(data) {
data.indeterminate = false
const values = []
// this.options.value = []
this.options.attrs.datas.forEach(item => {
this.options.value = []
const datas = JSON.parse(JSON.stringify(this.options.attrs.datas))
this.options.attrs.datas = []
datas.forEach(item => {
item.checked = data.checked
// data.checked && this.options.value.push(item.id)
data.checked && values.push(item.id)
})
this.options.attrs.datas = datas
this.options.value = values
this.setCondition()
},

View File

@ -1,12 +1,12 @@
<template>
<div style="height: 100%">
<time-default v-if="element.formatInfo.openMode === '0'" :ref="element.id" :element="element" />
<time-default v-if="element.formatInfo.openMode === '0'" :ref="element.id" :element="element" />
<time-elec v-if="element.formatInfo.openMode === '1'" :ref="element.id" :element="element" />
<time-elec v-if="element.formatInfo.openMode === '1'" :ref="element.id" :element="element" />
<time-simple v-if="element.formatInfo.openMode === '2'" :ref="element.id" :element="element" />
<time-simple v-if="element.formatInfo.openMode === '2'" :ref="element.id" :element="element" />
<time-complex v-if="element.formatInfo.openMode === '3'" :ref="element.id" :element="element" />
<time-complex v-if="element.formatInfo.openMode === '3'" :ref="element.id" :element="element" />
</div>
</template>

View File

@ -1,6 +1,6 @@
<template>
<div>
<canvas id="canvas" width="500" height="500" />
<canvas :id="'complex_canvas'+element.id" width="500" height="500" />
</div>
</template>
@ -30,7 +30,7 @@ export default {
}
},
mounted() {
this.canvas = document.getElementById('canvas')
this.canvas = document.getElementById('complex_canvas' + this.element.id)
this.initCtx()
this.initCtxBack()
this.initNumBack()

View File

@ -2,15 +2,14 @@
<div :style="{ 'height': containerHeight}">
<div ref="canvasContainer" class="time-s-class" style="height: calc(100% - 50px);" :style="{'margin':timeMargin +'px'}">
<canvas
id="canvas"
:id="'simple-canvas'+element.id"
class="de-canvas"
:width="canvas_width"
:height="canvas_height"
/>
<!-- <canvas id="canvas" class="de-canvas" :width="$refs.canvasContainer.clientWidth" :height="$refs.canvasContainer.clientHeight" /> -->
</div>
<div style="height: 50px;display: flex;align-items: center;">
<p id="fulltime" :style="{'fontSize': (parseInt(element.style.fontSize) * 1) + 'px', 'color':element.style.color}" style="width:100%;margin:auto;" />
<p :id="element.id + '_fulltime'" :style="{'fontSize': (parseInt(element.style.fontSize) * 1) + 'px', 'color':element.style.color}" style="width:100%;margin:auto;" />
</div>
</div>
</template>
@ -47,7 +46,7 @@ export default {
}
},
mounted() {
this.canvas = document.getElementById('canvas')
this.canvas = document.getElementById('simple-canvas' + this.element.id)
this.draw = this.canvas.getContext('2d')
this.canvas_width = this.element.style.width
this.canvas_height = this.element.style.height
@ -119,7 +118,7 @@ export default {
}
const nowWeek = this.week[time.getDay()]
var fullTime = showWeek ? (nowDate + ' ' + nowWeek) : nowDate
var fullDoc = document.getElementById('fulltime')
var fullDoc = document.getElementById(this.element.id + '_fulltime')
fullDoc.innerHTML = fullTime
const draw = draws
@ -140,8 +139,6 @@ export default {
draw.beginPath()
draw.moveTo(0, side_length / 2 - 0)
/* draw.moveTo(0, side_length / 2 - 70)
draw.lineTo(0, side_length / 2 - 50) */
draw.lineTo(0, side_length / 2 - 20)
draw.closePath()
draw.stroke()
@ -157,8 +154,6 @@ export default {
draw.beginPath()
draw.moveTo(0, side_length / 2 - 0)
// draw.lineTo(0, side_length / 2 - 50)
// draw.lineTo(0, side_length / 2 - 60)
draw.lineTo(0, side_length / 2 - 10)
draw.closePath()
draw.stroke()
@ -169,21 +164,18 @@ export default {
//
draw.save()
draw.strokeStyle = this.element.style.color
// draw.translate(250, 250)
draw.translate(canvas_w / 2, canvas_h / 2)
const hourzs = h + min / 60//
draw.rotate(hourzs * 30 * Math.PI / 180)
draw.lineWidth = 6
draw.beginPath()
draw.moveTo(0, 0)
/* draw.lineTo(0, -(side_length / 2 - 60) / 3) */
draw.lineTo(0, -(side_length / 2) * 0.5)
draw.closePath()
draw.stroke()
draw.restore()
//
draw.save()
// draw.translate(250, 250)
draw.translate(canvas_w / 2, canvas_h / 2)
draw.rotate(min * 6 * Math.PI / 180)
@ -192,13 +184,11 @@ export default {
draw.beginPath()
draw.moveTo(0, 0)
draw.lineTo(0, -(side_length / 2) * 0.7)
/* draw.lineTo(0, -(side_length / 2 - 60) * 3 / 5) */
draw.closePath()
draw.stroke()
draw.restore()
//
draw.save()
// draw.translate(250, 250)
draw.translate(canvas_w / 2, canvas_h / 2)
draw.rotate(s * 6 * Math.PI / 180)
draw.strokeStyle = this.element.style.color
@ -206,16 +196,13 @@ export default {
draw.beginPath()
draw.moveTo(0, 15)
draw.lineTo(0, -(side_length / 2) * 0.9)
/* draw.lineTo(0, -(side_length / 2 - 60)) */
draw.closePath()
draw.stroke()
draw.restore()
//
// draw.fillStyle = 'rgba(255,255,255,1)'
draw.lineWidth = 2
draw.beginPath()
// draw.arc(250, 250, 4, 0, 360, false)
draw.arc(canvas_w / 2, canvas_h / 2, 4, 0, 360, false)
draw.closePath()
draw.fill()

View File

@ -12,14 +12,6 @@
<app-main />
</de-main-container>
</de-container>
<!-- <de-main-container>
<app-main />
</de-main-container> -->
<!-- <div :class="{sidebarHide: sidebar.hide}" class="main-container">
<app-main />
</div> -->
</div>
</template>
@ -62,7 +54,7 @@ export default {
return this.$store.state.settings.showSettings
},
fullHeightFlag() {
return this.componentName === 'PanelEdit' || this.componentName === 'ChartEdit'
return this.$route.path.indexOf('panel') > -1 && (this.componentName === 'PanelEdit' || this.componentName === 'ChartEdit')
},
mainStyle() {
if (this.fullHeightFlag) {

View File

@ -1,15 +0,0 @@
<template>
<div id="link" style="height:100%;"><router-view />
</div>
</template>
<script>
export default {
data() {
return {
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,17 +0,0 @@
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: () => import('../views/link/index.vue'),
meta: {
title: '首页'
}
}
]
})

View File

@ -1,26 +0,0 @@
import Vue from 'vue'
import Link from './Link.vue'
import router from './link-router'
import store from '../store'
import '@/styles/index.scss' // global css
import i18n from '../lang' // internationalization
import ElementUI from 'element-ui'
import '@/components/canvas/custom-component' // 注册自定义组件
import widgets from '@/components/widget'
import * as echarts from 'echarts'
import UmyUi from 'umy-ui'
import '@/utils/DateUtil'
Vue.use(UmyUi)
Vue.prototype.$echarts = echarts
Vue.config.productionTip = false
Vue.use(widgets)
Vue.use(ElementUI, {
i18n: (key, value) => i18n.t(key, value)
})
new Vue({
router,
store,
i18n,
render: h => h(Link)
}).$mount('#link')

View File

@ -1,16 +0,0 @@
<template>
<div id="nolic" style="height:100%;">
<router-view />
</div>
</template>
<script>
export default {
data() {
return {
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,17 +0,0 @@
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: () => import('../views/nolic/index.vue'),
meta: {
title: '首页'
}
}
]
})

View File

@ -1,26 +0,0 @@
import Vue from 'vue'
import Nolic from './Nolic.vue'
import router from './nolic-router'
import store from '../store'
import '@/styles/index.scss' // global css
import i18n from '../lang' // internationalization
import ElementUI from 'element-ui'
import '@/components/canvas/custom-component' // 注册自定义组件
import widgets from '@/components/widget'
import * as echarts from 'echarts'
import UmyUi from 'umy-ui'
Vue.use(UmyUi)
Vue.prototype.$echarts = echarts
Vue.config.productionTip = false
Vue.use(widgets)
Vue.use(ElementUI, {
i18n: (key, value) => i18n.t(key, value)
})
new Vue({
router,
store,
i18n,
render: h => h(Nolic)
}).$mount('#nolic')

View File

@ -11,7 +11,7 @@ import { filterAsyncRouter } from '@/store/modules/permission'
NProgress.configure({ showSpinner: false }) // NProgress Configuration
const whiteList = ['/login', '/401', '/404'] // no redirect whitelist
const whiteList = ['/login', '/401', '/404', '/delink', '/nolic'] // no redirect whitelist
router.beforeEach(async(to, from, next) => {
// start progress bar
@ -29,7 +29,7 @@ router.beforeEach(async(to, from, next) => {
NProgress.done()
} else {
const hasGetUserInfo = store.getters.name
if (hasGetUserInfo || to.path.indexOf('/preview/') > -1) {
if (hasGetUserInfo || to.path.indexOf('/preview/') > -1 || to.path.indexOf('/delink') > -1 || to.path.indexOf('/nolic') > -1) {
next()
store.dispatch('permission/setCurrentPath', to.path)
} else {

View File

@ -71,6 +71,12 @@ export const constantRoutes = [
}
]
},
{
path: '/delink',
component: () => import('@/views/link'),
hidden: true
},
{
path: '/preview/:reportId',
component: () => import('@/components/canvas/components/Editor/PreviewEject'),
@ -208,7 +214,7 @@ export const constantRoutes = [
]
const createRouter = () => new Router({
// mode: 'history', // require service support
// mode: 'history', // require service support
mode: 'hash',
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes

View File

@ -693,39 +693,38 @@ div:focus {
.rate-date-class > .el-picker-panel__footer > .el-button--text:first-child{
display: none;
}
.rate-date-class > .el-picker-panel__body-wrapper > .el-picker-panel__body {
>.el-date-picker__header {
display: none;
}
.rate-date-class > .el-picker-panel__body-wrapper > .el-picker-panel__body {
>.el-date-picker__header {
display: none;
}
>.el-picker-panel__content{
>table > tbody {
>tr:first-child {
display: none;
}
>tr >td.prev-month,td.next-month {
display: none;
}
}
}
}
.rate-day-class > .el-picker-panel__footer > .el-button--text:first-child{
display: none;
}
.rate-day-class > .el-picker-panel__body-wrapper > .el-picker-panel__body {
>.el-date-picker__header {
>.el-picker-panel__content{
>table > tbody {
>tr:first-child {
display: none;
}
>.el-picker-panel__content{
>table > tbody {
>tr:not(:nth-child(3)) {
display: none;
}
}
}
>tr >td.prev-month,td.next-month {
display: none;
}
}
}
}
.rate-day-class > .el-picker-panel__footer > .el-button--text:first-child{
display: none;
}
.rate-day-class > .el-picker-panel__body-wrapper > .el-picker-panel__body {
>.el-date-picker__header {
display: none;
}
>.el-picker-panel__content{
>table > tbody {
>tr:not(:nth-child(3)) {
display: none;
}
}
}
}
.chart-type .el-radio__input{
display: none!important;
@ -735,6 +734,12 @@ div:focus {
padding-left: 0!important;
}
.chart-type .radio-row .radio-style{
width: 80px;
height: 60px;
padding: 0;
}
.el-color-predefine__color-selector{
border: 1px solid #999999!important;
margin: 0 0 6px 6px!important;

View File

@ -10,7 +10,6 @@
<script>
import { baseLiquid } from '@/views/chart/chart/liquid/liquid'
// import eventBus from '@/components/canvas/utils/eventBus'
import { uuid } from 'vue-uuid'
import ViewTrackBar from '@/components/canvas/components/Editor/ViewTrackBar'
import { hexColorToRGBA } from '@/views/chart/chart/util'
@ -183,15 +182,7 @@ export default {
if (this.antVRenderStatus) {
this.myChart.render()
}
// } else {
// if (this.myChart) {
// this.antVRenderStatus = false
// this.myChart.destroy()
// }
// }
this.setBackGroundBorder()
// console.log(JSON.stringify(chart_option))
},
antVAction(param) {
@ -205,20 +196,10 @@ export default {
this.trackClick(this.trackMenu[0])
} else { //
this.trackBarStyle.left = param.x + 'px'
this.trackBarStyle.top = (param.y - 15) + 'px'
this.trackBarStyle.top = (param.y + 10) + 'px'
this.$refs.viewTrack.trackButtonClick()
}
},
// myEcharts(option) {
// //
// const chart = this.myChart
// this.setBackGroundBorder()
// setTimeout(chart.setOption(option, true), 500)
// window.onresize = function() {
// chart.resize()
// }
// },
setBackGroundBorder() {
if (this.chart.customStyle) {
const customStyle = JSON.parse(this.chart.customStyle)

View File

@ -337,6 +337,11 @@ export default {
type: String,
required: false,
default: null
},
mountedInit: {
type: Boolean,
required: false,
default: true
}
},
data() {
@ -440,10 +445,11 @@ export default {
},
mounted() {
this.treeNode(this.groupForm)
this.refresh()
// this.chartTree()
this.getChartGroupTree()
if (this.mountedInit) {
this.treeNode(true)
this.refresh()
this.getChartGroupTree()
}
},
methods: {
clickAdd(param) {
@ -620,9 +626,17 @@ export default {
})
},
treeNode(group) {
queryAuthModel({ modelType: 'chart' }).then(res => {
this.tData = res.data
treeNode(cache = false) {
const modelInfo = localStorage.getItem('chart-tree')
const userCache = (modelInfo && cache)
if (userCache) {
this.tData = JSON.parse(modelInfo)
}
queryAuthModel({ modelType: 'chart' }, !userCache).then(res => {
localStorage.setItem('chart-tree', JSON.stringify(res.data))
if (!userCache) {
this.tData = res.data
}
})
},

View File

@ -487,10 +487,4 @@ export default {
white-space: pre;
font-size: 12px;
}
.radio-style{
width: 80px;
height: 60px;
padding: 0;
}
</style>

View File

@ -100,6 +100,7 @@ export default {
for (let i = 0; i < this.options.length; i++) {
if (this.options[i].id === val) {
this.selectedDatasource = this.options[i]
this.mode = '0'
}
}
}
@ -133,8 +134,6 @@ export default {
})
},
save() {
// console.log(this.checkTableList);
// console.log(this.scene);
let ds = {}
this.options.forEach(ele => {
if (ele.id === this.dataSource) {
@ -158,7 +157,6 @@ export default {
})
})
post('/dataset/table/batchAdd', tables).then(response => {
// this.$store.dispatch('dataset/setSceneData', new Date().getTime())
this.$emit('saveSuccess', tables[0])
this.cancel()
})
@ -166,7 +164,6 @@ export default {
cancel() {
this.dataReset()
// this.$router.push('/dataset/home')
this.$emit('switchComponent', { name: '' })
},

View File

@ -1,7 +1,7 @@
<template>
<el-col class="tree-style">
<!-- group -->
<el-col v-if="!sceneMode" v-loading="dsLoading">
<el-col>
<el-row class="title-css">
<span class="title-text">
{{ $t('dataset.datalist') }}
@ -9,36 +9,46 @@
</el-row>
<el-divider />
<el-row>
<el-form>
<el-form-item class="form-item">
<el-input
v-model="search"
size="mini"
:placeholder="$t('dataset.search')"
prefix-icon="el-icon-search"
clearable
/>
</el-form-item>
</el-form>
<el-row style="margin-bottom: 10px">
<el-col :span="16">
<el-input
v-model="filterText"
size="mini"
:placeholder="$t('commons.search')"
prefix-icon="el-icon-search"
clearable
class="main-area-input"
/>
</el-col>
<el-col :span="8">
<el-dropdown>
<el-button size="mini" type="primary">
{{ searchMap[searchType] }}<i class="el-icon-arrow-down el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="searchTypeClick('all')">{{ $t('commons.all') }}</el-dropdown-item>
<el-dropdown-item @click.native="searchTypeClick('folder')">{{ this.$t('commons.folder') }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
</el-row>
<el-col class="custom-tree-container">
<div class="block" :style="treeStyle">
<el-tree
ref="datasetTreeRef"
:default-expanded-keys="expandedArray"
:data="data"
node-key="id"
:expand-on-click-node="true"
:load="loadNode"
lazy
:props="treeProps"
highlight-current
:expand-on-click-node="true"
:filter-node-method="filterNode"
@node-click="nodeClick"
>
<span v-if="data.type === 'group'" slot-scope="{ node, data }" class="custom-tree-node">
<span v-if="data.modelInnerType === 'group'" slot-scope="{ node, data }" class="custom-tree-node">
<span style="display: flex;flex: 1;width: 0;">
<span v-if="data.type === 'scene'">
<span v-if="data.modelInnerType === 'scene'">
<svg-icon icon-class="scene" class="ds-icon-scene" />
</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" :title="data.name">{{ data.name }}</span>
@ -47,12 +57,12 @@
<span v-else slot-scope="{ node, data }" class="custom-tree-node-list">
<span :id="data.id" style="display: flex;flex: 1;width: 0;">
<span>
<svg-icon v-if="data.type === 'db'" icon-class="ds-db" class="ds-icon-db" />
<svg-icon v-if="data.type === 'sql'" icon-class="ds-sql" class="ds-icon-sql" />
<svg-icon v-if="data.type === 'excel'" icon-class="ds-excel" class="ds-icon-excel" />
<svg-icon v-if="data.type === 'custom'" icon-class="ds-custom" class="ds-icon-custom" />
<svg-icon v-if="data.modelInnerType === 'db'" icon-class="ds-db" class="ds-icon-db" />
<svg-icon v-if="data.modelInnerType === 'sql'" icon-class="ds-sql" class="ds-icon-sql" />
<svg-icon v-if="data.modelInnerType === 'excel'" icon-class="ds-excel" class="ds-icon-excel" />
<svg-icon v-if="data.modelInnerType === 'custom'" icon-class="ds-custom" class="ds-icon-custom" />
</span>
<span v-if="data.type === 'db' || data.type === 'sql'">
<span v-if="data.modelInnerType === 'db' || data.modelInnerType === 'sql'">
<span v-if="data.mode === 0" style="margin-left: 6px"><i class="el-icon-s-operation" /></span>
<span v-if="data.mode === 1" style="margin-left: 6px"><i class="el-icon-alarm-clock" /></span>
</span>
@ -69,6 +79,8 @@
<script>
import { isKettleRunning, post } from '@/api/dataset/dataset'
import { hasDataPermission } from '@/utils/permission'
import { queryAuthModel } from '@/api/authModel/authModel'
export default {
name: 'DatasetGroupSelectorTree',
@ -121,6 +133,13 @@ export default {
},
data() {
return {
searchPids: [], // pid
filterText: '',
searchType: 'all',
searchMap: {
all: this.$t('commons.all'),
folder: this.$t('commons.folder')
},
kettleRunning: false,
sceneMode: false,
search: '',
@ -162,22 +181,19 @@ export default {
this.unionDataChange()
},
'table': function() {
this.treeNode(this.groupForm)
this.treeNode()
},
search(val) {
this.$emit('switchComponent', { name: '' })
this.data = []
this.expandedArray = []
if (this.timer) {
clearTimeout(this.timer)
}
this.timer = setTimeout(() => {
this.getTreeData(val)
}, (val && val !== '') ? 500 : 0)
filterText(val) {
this.searchPids = []
this.$refs.datasetTreeRef.filter(val)
},
searchType(val) {
this.searchPids = []
this.$refs.datasetTreeRef.filter(this.filterText)
}
},
mounted() {
this.treeNode(this.groupForm)
this.treeNode(true)
},
created() {
this.kettleState()
@ -207,48 +223,31 @@ export default {
}
},
treeNode(group) {
post('/dataset/group/treeNode', group).then(res => {
this.data = res.data
this.dsLoading = false
treeNode(cache) {
const modelInfo = localStorage.getItem('dataset-tree')
const userCache = (modelInfo && cache)
if (userCache) {
this.data = JSON.parse(modelInfo)
}
queryAuthModel({ modelType: 'dataset' }, !userCache).then(res => {
localStorage.setItem('dataset-tree', JSON.stringify(res.data))
if (!userCache) {
this.data = res.data
}
})
},
tableTree() {
this.tableData = []
if (this.currGroup) {
this.dsLoading = true
this.tables = []
post('/dataset/table/list', {
sort: 'type asc,name asc,create_time desc',
sceneId: this.currGroup.id,
mode: this.mode < 0 ? null : this.mode,
typeFilter: this.customType ? this.customType : null
}, false).then(response => {
for (let i = 0; i < response.data.length; i++) {
if (response.data[i].mode === 1 && this.kettleRunning === false) {
this.$set(response.data[i], 'disabled', true)
}
if (hasDataPermission(this.privileges, response.data[i].privileges)) {
this.tables.push(response.data[i])
}
}
this.tableData = JSON.parse(JSON.stringify(this.tables))
this.$nextTick(function() {
this.unionDataChange()
})
this.dsLoading = false
}).catch(res => {
this.dsLoading = false
})
}
},
nodeClick(data, node) {
if (data.type !== 'group') {
if (data.modelInnerType !== 'group') {
this.sceneClick(data, node)
}
if (node.expanded) {
this.expandedArray.push(data.id)
} else {
const index = this.expandedArray.indexOf(data.id)
if (index > -1) {
this.expandedArray.splice(index, 1)
}
}
},
back() {
@ -329,118 +328,28 @@ export default {
this.expandedArray.splice(this.expandedArray.indexOf(data.id), 1)
}
},
loadNode(node, resolve) {
if (!this.isTreeSearch) {
if (node.data.id) {
this.dsLoading = true
this.tables = []
post('/dataset/table/listAndGroup', {
sort: 'type asc,name asc,create_time desc',
sceneId: node.data.id,
mode: this.mode < 0 ? null : this.mode,
type: this.type,
typeFilter: this.customType ? this.customType : null
}, false).then(response => {
for (let i = 0; i < response.data.length; i++) {
if (response.data[i].mode === 1 && this.kettleRunning === false) {
this.$set(response.data[i], 'disabled', true)
}
if (hasDataPermission(this.privileges, response.data[i].privileges)) {
this.tables.push(response.data[i])
}
}
this.tableData = JSON.parse(JSON.stringify(this.tables))
this.$nextTick(function() {
this.unionDataChange()
})
this.dsLoading = false
resolve(this.tableData)
}).catch(res => {
this.dsLoading = false
})
filterNode(value, data) {
if (!value) return true
if (this.searchType === 'folder') {
if (data.modelInnerType === 'group' && data.label.indexOf(value) !== -1) {
this.searchPids.push(data.id)
return true
}
if (this.searchPids.indexOf(data.pid) !== -1) {
if (data.modelInnerType === 'group') {
this.searchPids.push(data.id)
}
return true
}
} else {
node.data.children ? resolve(node.data.children) : resolve([])
return data.label.indexOf(value) !== -1
}
return false
},
refreshNodeBy(id) {
if (this.isTreeSearch) {
this.data = []
this.expandedArray = []
this.searchTree(this.search)
} else {
if (!id || id === '0') {
this.treeNode(this.groupForm)
} else {
const node = this.$refs.asyncTree.getNode(id) // id
node.loaded = false
node.expand() //
}
}
},
searchTree(val) {
const queryCondition = {
name: val,
sort: 'type asc,name asc,create_time desc',
mode: this.mode < 0 ? null : this.mode,
type: this.type,
typeFilter: this.customType ? this.customType : null
}
post('/dataset/table/search', queryCondition).then(res => {
this.data = this.buildTree(res.data)
})
},
buildTree(arrs) {
const idMapping = arrs.reduce((acc, el, i) => {
acc[el[this.treeProps.id]] = i
return acc
}, {})
const roots = []
arrs.forEach(el => {
// ###
if (el[this.treeProps.parentId] === null || el[this.treeProps.parentId] === 0 || el[this.treeProps.parentId] === '0') {
roots.push(el)
return
}
//
const parentEl = arrs[idMapping[el[this.treeProps.parentId]]]
// `children`
parentEl.children = [...(parentEl.children || []), el]
//
if (parentEl.children.length > 0) {
this.expandedArray.push(parentEl[this.treeProps.id])
}
})
return roots
},
//
highlights(data) {
if (data && this.search && this.search.length > 0) {
const replaceReg = new RegExp(this.search, 'g')//
const replaceString = '<span style="color: #0a7be0">' + this.search + '</span>' // v-html
data.forEach(item => {
item.name = item.name.replace(replaceReg, replaceString) //
item.label = item.label.replace(replaceReg, replaceString) //
})
}
},
getTreeData(val) {
if (val) {
this.isTreeSearch = true
this.searchTree(val)
} else {
this.isTreeSearch = false
this.treeNode(this.groupForm)
}
searchTypeClick(searchTypeInfo) {
this.searchType = searchTypeInfo
}
}
}
</script>

View File

@ -1,7 +1,7 @@
<template>
<el-col class="tree-style">
<!-- group -->
<el-col v-if="!sceneMode">
<el-col>
<el-row class="title-css">
<span class="title-text">
{{ $t('dataset.datalist') }}
@ -10,36 +10,44 @@
</el-row>
<el-divider />
<el-row>
<el-form>
<el-form-item class="form-item">
<el-input
v-model="search"
size="mini"
:placeholder="$t('dataset.search')"
prefix-icon="el-icon-search"
clearable
class="main-area-input"
/>
</el-form-item>
</el-form>
<el-row style="margin-bottom: 10px">
<el-col :span="16">
<el-input
v-model="filterText"
size="mini"
:placeholder="$t('commons.search')"
prefix-icon="el-icon-search"
clearable
class="main-area-input"
/>
</el-col>
<el-col :span="8">
<el-dropdown>
<el-button size="mini" type="primary">
{{ searchMap[searchType] }}<i class="el-icon-arrow-down el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="searchTypeClick('all')">{{ $t('commons.all') }}</el-dropdown-item>
<el-dropdown-item @click.native="searchTypeClick('folder')">{{ this.$t('commons.folder') }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
</el-row>
<el-col class="custom-tree-container">
<div class="block">
<el-tree
ref="asyncTree"
ref="datasetTreeRef"
:default-expanded-keys="expandedArray"
:data="tData"
node-key="id"
:expand-on-click-node="true"
:load="loadNode"
lazy
:props="treeProps"
highlight-current
:expand-on-click-node="true"
:filter-node-method="filterNode"
@node-click="nodeClick"
>
<span v-if="data.type === 'group'" slot-scope="{ node, data }" class="custom-tree-node father">
<span v-if="data.modelInnerType === 'group'" slot-scope="{ node, data }" class="custom-tree-node father">
<span style="display: flex;flex: 1;width: 0;">
<span>
<i class="el-icon-folder" />
@ -47,7 +55,7 @@
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" :title="data.name">{{ data.name }}</span>
</span>
<span v-if="hasDataPermission('manage',data.privileges)" class="child">
<span v-if="data.type ==='group'" @click.stop>
<span v-if="data.modelInnerType ==='group'" @click.stop>
<el-dropdown trigger="click" size="small" @command="clickAdd">
<span class="el-dropdown-link">
<el-button
@ -128,7 +136,7 @@
<svg-icon v-if="data.type === 'custom'" icon-class="ds-custom" class="ds-icon-custom" />
<svg-icon v-if="data.type === 'union'" icon-class="ds-union" class="ds-icon-union" />
</span>
<span v-if="data.type === 'db' || data.type === 'sql'">
<span v-if="data.modelInnerType === 'db' || data.modelInnerType === 'sql'">
<span v-if="data.mode === 0" style="margin-left: 6px"><i class="el-icon-s-operation" /></span>
<span v-if="data.mode === 1" style="margin-left: 6px"><i class="el-icon-alarm-clock" /></span>
</span>
@ -216,6 +224,7 @@
import { loadTable, getScene, addGroup, delGroup, delTable, post, isKettleRunning, alter } from '@/api/dataset/dataset'
import GroupMoveSelector from './GroupMoveSelector'
import DsMoveSelector from './DsMoveSelector'
import { queryAuthModel } from '@/api/authModel/authModel'
export default {
name: 'Group',
@ -287,32 +296,36 @@ export default {
parentId: 'pid'
},
isTreeSearch: false,
kettleRunning: false
kettleRunning: false,
searchPids: [], // pid
filterText: '',
searchType: 'all',
searchMap: {
all: this.$t('commons.all'),
folder: this.$t('commons.folder')
}
}
},
computed: {
},
watch: {
search(val) {
this.$emit('switchComponent', { name: '' })
this.tData = []
this.expandedArray = []
if (this.timer) {
clearTimeout(this.timer)
}
this.timer = setTimeout(() => {
this.getTreeData(val)
}, (val && val !== '') ? 500 : 0)
},
saveStatus() {
this.refreshNodeBy(this.saveStatus.sceneId)
this.treeNode()
},
filterText(val) {
this.searchPids = []
this.$refs.datasetTreeRef.filter(val)
},
searchType(val) {
this.searchPids = []
this.$refs.datasetTreeRef.filter(this.filterText)
}
},
created() {
this.kettleState()
},
mounted() {
this.treeNode(this.groupForm)
this.treeNode(true)
this.refresh()
},
methods: {
@ -337,7 +350,7 @@ export default {
clickMore(param) {
switch (param.type) {
case 'rename':
this.add(param.data.type)
this.add(param.data.modelInnerType)
this.groupForm = JSON.parse(JSON.stringify(param.data))
break
case 'move':
@ -393,7 +406,8 @@ export default {
type: 'success',
showClose: true
})
this.refreshNodeBy(group.pid)
this.expandedArray.push(group.pid)
this.treeNode()
})
} else {
return false
@ -403,6 +417,7 @@ export default {
saveTable(table) {
table.mode = parseInt(table.mode)
const _this = this
this.$refs['tableForm'].validate((valid) => {
if (valid) {
table.isRename = true
@ -413,7 +428,9 @@ export default {
type: 'success',
showClose: true
})
this.refreshNodeBy(table.sceneId)
_this.expandedArray.push(table.sceneId)
_this.$refs.datasetTreeRef.setCurrentKey(table.id)
_this.treeNode()
this.$store.dispatch('dataset/setTable', new Date().getTime())
})
} else {
@ -434,7 +451,7 @@ export default {
message: this.$t('dataset.delete_success'),
showClose: true
})
this.refreshNodeBy(data.pid)
this.treeNode()
})
}).catch(() => {
})
@ -452,7 +469,7 @@ export default {
message: this.$t('dataset.delete_success'),
showClose: true
})
this.refreshNodeBy(data.sceneId)
this.treeNode()
this.$store.dispatch('dataset/setTable', new Date().getTime())
})
}).catch(() => {
@ -479,9 +496,17 @@ export default {
}
},
treeNode(group) {
post('/dataset/group/treeNode', group).then(res => {
this.tData = res.data
treeNode(cache) {
const modelInfo = localStorage.getItem('dataset-tree')
const userCache = (modelInfo && cache)
if (userCache) {
this.tData = JSON.parse(modelInfo)
}
queryAuthModel({ modelType: 'dataset' }, !userCache).then(res => {
localStorage.setItem('dataset-tree', JSON.stringify(res.data))
if (!userCache) {
this.tData = res.data
}
})
},
@ -500,9 +525,17 @@ export default {
},
nodeClick(data, node) {
if (data.type !== 'group') {
if (data.modelInnerType !== 'group') {
this.$emit('switchComponent', { name: 'ViewTable', param: data })
}
if (node.expanded) {
this.expandedArray.push(data.id)
} else {
const index = this.expandedArray.indexOf(data.id)
if (index > -1) {
this.expandedArray.splice(index, 1)
}
}
},
back() {
@ -588,7 +621,7 @@ export default {
this.groupForm.pid = this.tGroup.id
addGroup(this.groupForm).then(res => {
this.closeMoveGroup()
this.refreshNodeBy(this.groupForm.pid)
this.treeNode()
})
},
targetGroup(val) {
@ -612,14 +645,13 @@ export default {
}
},
saveMoveDs() {
const oldSceneId = this.dsForm.sceneId
const newSceneId = this.tDs.id
this.dsForm.sceneId = newSceneId
this.dsForm.isRename = true
alter(this.dsForm).then(res => {
this.closeMoveDs()
this.refreshNodeBy(oldSceneId)
this.refreshNodeBy(newSceneId)
this.expandedArray.push(newSceneId)
this.treeNode()
})
},
targetDs(val) {
@ -652,77 +684,35 @@ export default {
}
},
refreshNodeBy(id) {
if (this.isTreeSearch) {
this.tData = []
this.expandedArray = []
this.searchTree(this.search)
} else {
if (!id || id === '0') {
this.treeNode(this.groupForm)
} else {
const node = this.$refs.asyncTree.getNode(id) // id
node.loaded = false
node.expand() //
}
}
},
searchTree(val) {
const queryCondition = {
name: val
}
post('/dataset/table/search', queryCondition).then(res => {
this.tData = this.buildTree(res.data)
})
},
buildTree(arrs) {
const idMapping = arrs.reduce((acc, el, i) => {
acc[el[this.treeProps.id]] = i
return acc
}, {})
const roots = []
arrs.forEach(el => {
// ###
if (el[this.treeProps.parentId] === null || el[this.treeProps.parentId] === 0 || el[this.treeProps.parentId] === '0') {
roots.push(el)
return
}
//
const parentEl = arrs[idMapping[el[this.treeProps.parentId]]]
// `children`
parentEl.children = [...(parentEl.children || []), el]
//
if (parentEl.children.length > 0) {
this.expandedArray.push(parentEl[this.treeProps.id])
}
})
return roots
},
//
highlights(data) {
if (data && this.search && this.search.length > 0) {
const replaceReg = new RegExp(this.search, 'g')//
const replaceString = '<span style="color: #0a7be0">' + this.search + '</span>' // v-html
data.forEach(item => {
item.name = item.name.replace(replaceReg, replaceString) //
item.label = item.label.replace(replaceReg, replaceString) //
})
}
},
getTreeData(val) {
if (val) {
this.isTreeSearch = true
this.searchTree(val)
} else {
this.isTreeSearch = false
this.treeNode(this.groupForm)
this.treeNode()
}
},
filterNode(value, data) {
if (!value) return true
if (this.searchType === 'folder') {
if (data.modelInnerType === 'group' && data.label.indexOf(value) !== -1) {
this.searchPids.push(data.id)
return true
}
if (this.searchPids.indexOf(data.pid) !== -1) {
if (data.modelInnerType === 'group') {
this.searchPids.push(data.id)
}
return true
}
} else {
return data.label.indexOf(value) !== -1
}
return false
},
searchTypeClick(searchTypeInfo) {
this.searchType = searchTypeInfo
}
}
}

View File

@ -17,6 +17,7 @@ export default {
components: {
LinkError, LinkPwd, LinkView, LinkExpire
},
data() {
return {
resourceId: null,
@ -32,8 +33,16 @@ export default {
loadInit() {
debugger
this.link = getQueryVariable(this.PARAMKEY)
validate({ link: this.link }).then(res => {
// this.link = getQueryVariable(this.PARAMKEY)
this.link = this.$route.query.link
if (!this.link) {
this.link = getQueryVariable(this.PARAMKEY)
}
if (!this.link) {
this.showError()
return
}
validate({ link: encodeURIComponent(this.link) }).then(res => {
const { resourceId, valid, enablePwd, passPwd, expire } = res.data
this.resourceId = resourceId
//

View File

@ -85,10 +85,10 @@ export default {
},
// LINK-PWD-TOKEN=entrypt(pwd)
refresh() {
this.msg = null
this.$refs.pwdForm.validate(valid => {
if (!valid) return false
const param = {
/* password: encrypt(this.form.password), */
password: this.form.password,
resourceId: this.resourceId
}
@ -96,7 +96,6 @@ export default {
if (!res.data) {
this.msg = this.$t('pblink.pwd_error')
} else {
// window.location.reload()
this.$emit('fresh-token')
}
})

View File

@ -92,7 +92,13 @@ export default {
axiosFinished: false,
loginTypes: [0],
isPluginLoaded: false,
contentShow: false
contentShow: false,
clearLocalStorage: [
'panel-main-tree',
'panel-default-tree',
'chart-tree',
'dataset-tree'
]
}
},
computed: {
@ -178,8 +184,14 @@ export default {
}
} */
},
initCache() {
this.clearLocalStorage.forEach(item => {
localStorage.removeItem(item)
})
},
handleLogin() {
this.initCache()
this.clearOidcMsg()
this.$refs.loginForm.validate(valid => {
if (valid) {

View File

@ -1,9 +0,0 @@
<template>
<div>缺少许可</div>
</template>
<script>
export default {
}
</script>

View File

@ -7,22 +7,20 @@
</el-col>
<el-col :span="8" style="text-overflow:ellipsis;overflow: hidden;white-space: nowrap;font-size: 14px">
<span>{{ $t('panel.when_share') + ': ' + (granterTime ? new Date(granterTime).format('yyyy年-MM月-dd日') : '') }}</span>
<span>{{ $t('panel.when_share') + ': ' + (granterTime ? new Date(granterTime).format('yyyy-MM-dd hh:mm:ss') : '') }}</span>
</el-col>
<el-col :span="8" style="text-overflow:ellipsis;overflow: hidden;white-space: nowrap;font-size: 14px">
<el-link type="primary" disabled class="share-checked">
<!-- <el-checkbox v-model="checked" disabled>组织</el-checkbox> -->
<!-- 分享维度提醒 先注释 因为后面有可能还是需要的 -->
<!-- <el-link type="primary" disabled class="share-checked">
{{ $t('panel.org') }}
</el-link>
<el-link type="success" disabled class="share-checked">
<!-- <el-checkbox v-model="checked" disabled>角色</el-checkbox> -->
{{ $t('panel.role') }}
</el-link>
<el-link type="info" disabled class="share-checked">
<!-- <el-checkbox v-model="checked" disabled>用户</el-checkbox> -->
{{ $t('panel.user') }}
</el-link>
</el-link> -->
</el-col>
</el-row>
<el-row style="display: flex;">
@ -68,6 +66,7 @@
<script>
import GrantAuth from '../index'
import { shareTargets, removeShares } from '@/api/panel/share'
import bus from '@/utils/bus'
export default {
name: 'ShareHead',
components: { GrantAuth },
@ -135,7 +134,13 @@ export default {
this.granterTime = item.createTime
return item
}).sort((a, b) => b.type - a.type)
if (!this.dynamicTags || this.dynamicTags.length === 0) {
this.afterRemoveAll()
}
})
},
afterRemoveAll() {
bus.$emit('refresh-my-share-out')
}
}
}

View File

@ -18,13 +18,13 @@
>
<span slot-scope="{ node, data }" class="custom-tree-node">
<span>
<span style="margin-left: 6px">{{ data.name }}</span>
<span style="margin-left: 6px">{{ node.data.name }}</span>
</span>
<span @click.stop>
<div>
<span class="auth-span">
<el-checkbox v-model="data.checked" />
<el-checkbox v-model="data.checked" @change="nodeStatusChange(data)" />
</span>
</div>
</span>
@ -68,7 +68,8 @@ export default {
return !data.hasChildren
}
},
expandNodeIds: []
expandNodeIds: [],
sharesLoad: false
}
},
watch: {
@ -125,33 +126,36 @@ export default {
} else {
param = { conditions: [this.defaultCondition] }
}
this.queryShareNodeIds(() => {
loadTable(param).then(res => {
let data = res.data
data = data.map(obj => {
if (obj.subCount > 0) {
obj.hasChildren = true
}
return obj
})
this.setCheckExpandNodes(data)
this.expandNodeIds = []
if (condition && condition.value) {
// data = data.map(node => {
// delete (node.hasChildren)
// return node
// })
this.data = this.buildTree(data)
this.$nextTick(() => {
// this.expandNodeIds.push()
this.expandResult(this.data)
})
} else {
this.data = data
}
if (!this.sharesLoad) {
this.queryShareNodeIds(() => {
this.sharesLoad = true
this.loadTreeData(param, condition)
})
} else {
this.loadTreeData(param, condition)
}
},
loadTreeData(param, condition) {
loadTable(param).then(res => {
let data = res.data
data = data.map(obj => {
if (obj.subCount > 0) {
obj.hasChildren = true
}
return obj
})
this.setCheckExpandNodes(data)
this.expandNodeIds = []
if (condition && condition.value) {
this.data = this.buildTree(data)
this.$nextTick(() => {
this.expandResult(this.data)
})
} else {
this.data = data
}
})
},
@ -185,18 +189,8 @@ export default {
},
getSelected() {
// const ids = []
// this.searchChecked(ids)
// return {
// deptIds: ids
// }
// const ids = []
const nodesMap = this.$refs.tree.store.nodesMap
const ids = Object.values(nodesMap).filter(node => node.data.checked).map(item => item.data.deptId)
return {
deptIds: ids
deptIds: this.shares
}
},
@ -221,24 +215,26 @@ export default {
const shares = res.data
const nodeIds = shares.map(share => share.targetId)
this.shares = nodeIds
// this.$nextTick(() => {
// this.setCheckNodes()
// })
callBack && callBack()
})
},
// setCheckNodes() {
// this.data.forEach(node => {
// const nodeId = node.deptId
// this.shares.includes(nodeId) && (node.checked = true)
// })
// },
setCheckExpandNodes(rows) {
rows.forEach(node => {
const nodeId = node.deptId
this.shares.includes(nodeId) && (node.checked = true)
})
},
nodeStatusChange(val) {
if (val.checked) {
if (!this.shares.includes(val.deptId)) {
this.shares.push(val.deptId)
}
} else {
this.shares = this.shares.filter(deptId => deptId !== val.deptId)
}
}
}

View File

@ -59,8 +59,6 @@ export default {
this.showSearchInput = false
},
save() {
// this.$refs[this.activeName].save(this.$t('commons.share_success'))
// this.$emit('close-grant', 0)
this.fineSave()
},
fineSave() {

View File

@ -2,11 +2,12 @@
<div class="my_table">
<el-table
ref="table"
:data="data.filter(node => !keyWord || node[fieldName].toLowerCase().includes(keyWord.toLowerCase()))"
:data="tableData"
:show-header="true"
style="width: 100%"
:row-style="{height: '35px'}"
@filter-change="filterChange"
@select="selectOne"
@select-all="selectAll"
>
<el-table-column :column-key="fieldName" :label="columnLabel" :prop="fieldName" filter-placement="right-start" :filters="filter_options" :filter-multiple="false" :filter-method="filterHandler" />
<el-table-column type="selection" fixd />
@ -18,7 +19,6 @@
import { roleGrid } from '@/api/system/user'
import { formatCondition } from '@/utils/index'
import { loadShares } from '@/api/panel/share'
/* import { saveShare, loadShares } from '@/api/panel/share' */
export default {
name: 'GrantRole',
props: {
@ -39,7 +39,15 @@ export default {
filter_options: [{ text: this.$t('panel.no_auth_role'), value: 0 }, { text: this.$t('panel.auth_role'), value: 1 }],
fieldName: 'name',
type: 1, // 1
shares: []
shares: [],
tableData: []
}
},
watch: {
'keyWord': function(val) {
this.tableData = this.data.filter(node => !val || node[this.fieldName].toLowerCase().includes(val.toLowerCase()))
this.setCheckNodes()
}
},
created() {
@ -56,48 +64,22 @@ export default {
const param = temp || {}
roleGrid(1, 0, param).then(response => {
const data = response.data
// this.total = data.itemCount
this.data = data.listObject
this.tableData = data.listObject
this.queryShareNodeIds()
})
},
filterHandler(value, row, column) {
// const property = column['property']
// return row[property] === value
const roleId = row['roleId']
return !(value ^ this.shares.includes(roleId))
},
filterChange(obj) {
const arr = obj[this.fieldName]
if (arr.length === 0) {
this.initColumnLabel()
} else {
this.columnLabel = this.filter_options[arr[0]].text
}
this.$nextTick(() => {
this.setCheckNodes()
})
},
getSelected() {
return {
roleIds: this.$refs.table.store.states.selection.map(item => item.roleId)
roleIds: this.shares
}
},
/* save(msg) {
const rows = this.$refs.table.store.states.selection
const request = this.buildRequest(rows)
saveShare(request).then(res => {
this.$success(msg)
return true
}).catch(err => {
this.$error(err.message)
return false
})
}, */
cancel() {
},
buildRequest(rows) {
@ -126,10 +108,39 @@ export default {
},
setCheckNodes() {
this.data.forEach(node => {
const nodeId = node.roleId
this.shares.includes(nodeId) && this.$refs.table.toggleRowSelection(node, true)
this.$nextTick(() => {
this.$refs.table.store.states.data.forEach(node => {
const nodeId = node.roleId
this.shares.includes(nodeId) && this.$refs.table.toggleRowSelection(node, true)
})
})
},
selectOne(selection, row) {
if (selection.some(node => node.roleId === row.roleId)) {
//
if (!this.shares.includes(row.roleId)) {
this.shares.push(row.roleId)
}
} else {
//
this.shares = this.shares.filter(nodeId => row.roleId !== nodeId)
// this.shares.splice(this.shares.findIndex(item => item.roleId === row.roleId), 1)
}
},
selectAll(selection) {
// 1.
if (selection && selection.length > 0) {
selection.forEach(node => {
if (!this.shares.includes(node.roleId)) {
this.shares.push(node.roleId)
}
})
} else {
// 2.
const currentNodes = this.$refs.table.store.states.data
const currentNodeIds = currentNodes.map(node => node.roleId)
this.shares = this.shares.filter(nodeId => !currentNodeIds.includes(nodeId))
}
}
}

View File

@ -11,15 +11,7 @@
</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{ data.name }}</span>
</span>
<!-- <span :class="!!data.msgNode ? 'msg-node-class': ''">
<span v-if="!!data.id">
<el-button
icon="el-icon-picture-outline"
type="text"
/>
</span>
<span style="margin-left: 6px">{{ data.name }}</span>
</span> -->
</span>
</el-tree>
</div>
@ -28,9 +20,9 @@
<el-row>
<span class="header-title">{{ $t('panel.share_out') }}</span>
<div class="block" style="margin-top:8px;">
<el-tree :data="outDatas" :props="defaultProps" :highlight-current="true" node-key="name" :default-expand-all="true" @node-click="viewMyShare">
<el-tree :data="outDatas" :props="defaultProps" :highlight-current="true" node-key="name" :default-expand-all="true">
<span slot-scope="{ data }" class="custom-tree-node father">
<span style="display: flex; flex: 1 1 0%; width: 0px;">
<span style="display: flex; flex: 1 1 0%; width: 0px;" @click="viewMyShare(data)">
<span v-if="!!data.id">
<svg-icon icon-class="panel" class="ds-icon-scene" />
</span>
@ -79,7 +71,18 @@ export default {
outDatas: []
}
},
computed: {
panelInfo() {
return this.$store.state.panel.panelInfo
}
},
created() {
bus.$on('refresh-my-share-out', () => {
this.initOutData().then(res => {
this.outDatas = res.data
this.setMainNull()
})
})
this.initData().then(res => {
this.datas = res.data
if (this.msgPanelIds && this.msgPanelIds.length > 0) {
@ -145,7 +148,6 @@ export default {
})
},
removeCurrent(node) {
console.log(node)
const param = {
panelId: node.id
}
@ -156,6 +158,7 @@ export default {
type: 'warning'
}).then(() => {
removeShares(param).then(res => {
this.panelInfo && this.panelInfo.id && node.id === this.panelInfo.id && this.setMainNull()
this.initOutData().then(res => {
this.outDatas = res.data
})
@ -167,6 +170,9 @@ export default {
message: this.$t('commons.delete_cancelled')
})
})
},
setMainNull() {
this.$store.dispatch('panel/setPanelInfo', { id: null, name: '', preStyle: null })
}
}

View File

@ -2,11 +2,12 @@
<div class="my_table">
<el-table
ref="table"
:data="data.filter(node => !keyWord || node[fieldName].toLowerCase().includes(keyWord.toLowerCase()))"
:data="tableData"
:show-header="true"
style="width: 100%"
:row-style="{height: '35px'}"
@filter-change="filterChange"
@select="selectOne"
@select-all="selectAll"
>
<el-table-column
:column-key="fieldName"
@ -47,7 +48,14 @@ export default {
filter_options: [{ text: this.$t('panel.unshared_people'), value: 0 }, { text: this.$t('panel.shared_people'), value: 1 }],
fieldName: 'nickName',
type: 0, // 0
shares: []
shares: [],
tableData: []
}
},
watch: {
'keyWord': function(val) {
this.tableData = this.data.filter(node => !val || node[this.fieldName].toLowerCase().includes(val.toLowerCase()))
this.setCheckNodes()
}
},
created() {
@ -63,48 +71,22 @@ export default {
const param = temp || {}
userLists(1, 0, param).then(response => {
const data = response.data
// this.total = data.itemCount
this.data = data.listObject.filter(ele => ele.id !== this.$store.getters.user.userId)
this.tableData = data.listObject.filter(ele => ele.id !== this.$store.getters.user.userId)
this.queryShareNodeIds()
})
},
filterHandler(value, row, column) {
// const property = column['property']
// return row[property] === value
const userId = row['userId']
return !(value ^ this.shares.includes(userId))
},
filterChange(obj) {
const arr = obj[this.fieldName]
if (arr.length === 0) {
this.initColumnLabel()
} else {
this.columnLabel = this.filter_options[arr[0]].text
}
this.$nextTick(() => {
this.setCheckNodes()
})
},
getSelected() {
return {
userIds: this.$refs.table.store.states.selection.map(item => item.userId)
userIds: this.shares
}
},
/* save(msg) {
const rows = this.$refs.table.store.states.selection
const request = this.buildRequest(rows)
saveShare(request).then(response => {
this.$success(msg)
return true
}).catch(err => {
this.$error(err.message)
return false
})
}, */
cancel() {
console.log('user cancel')
},
@ -134,10 +116,38 @@ export default {
},
setCheckNodes() {
this.data.forEach(node => {
const nodeId = node.userId
this.shares.includes(nodeId) && this.$refs.table.toggleRowSelection(node, true)
this.$nextTick(() => {
this.$refs.table.store.states.data.forEach(node => {
const nodeId = node.userId
this.shares.includes(nodeId) && this.$refs.table.toggleRowSelection(node, true)
})
})
},
selectOne(selection, row) {
if (selection.some(node => node.userId === row.userId)) {
//
if (!this.shares.includes(row.userId)) {
this.shares.push(row.userId)
}
} else {
//
this.shares = this.shares.filter(nodeId => row.userId !== nodeId)
}
},
selectAll(selection) {
// 1.
if (selection && selection.length > 0) {
selection.forEach(node => {
if (!this.shares.includes(node.userId)) {
this.shares.push(node.userId)
}
})
} else {
// 2.
const currentNodes = this.$refs.table.store.states.data
const currentNodeIds = currentNodes.map(node => node.userId)
this.shares = this.shares.filter(nodeId => !currentNodeIds.includes(nodeId))
}
}
}

View File

@ -1,7 +1,7 @@
<template>
<el-row class="slider-container">
<div
style="height: 40px; line-height: 40px; padding-left: 15px; text-align: left; white-space: pre; text-overflow: ellipsis; left: 0px; right: 0px; top: 0px; font-weight: 700"
style="height: 40px; padding-left: 15px; text-align: left; white-space: pre; text-overflow: ellipsis; left: 0px; right: 0px; top: 0px; font-weight: 700"
>
{{ $t('panel.dashboard_theme') }}
</div>

View File

@ -191,6 +191,7 @@
:opt-from="'panel'"
:advice-group-id="adviceGroupId"
style="height: 0px;width:0px;padding:0px;overflow: hidden"
:mounted-init="false"
@newViewInfo="newViewInfo"
/>

View File

@ -28,7 +28,7 @@ export default {
},
computed: {
fullHeightFlag() {
return this.componentName === 'PanelEdit' || this.componentName === 'ChartEdit'
return this.$route.path.indexOf('panel') > -1 && (this.componentName === 'PanelEdit' || this.componentName === 'ChartEdit')
}
},
watch: {
@ -49,6 +49,7 @@ export default {
})
},
created() {
bus.$emit('PanelSwitchComponent', { name: 'PanelMain' })
this.$store.dispatch('app/toggleSideBarHide', true)
const routerParam = this.$router.currentRoute.params
this.toMsgShare(routerParam)

View File

@ -233,6 +233,7 @@ import {
DEFAULT_COMMON_CANVAS_STYLE_STRING
} from '@/views/panel/panel'
import TreeSelector from '@/components/TreeSelector'
import { queryAuthModel } from '@/api/authModel/authModel'
export default {
name: 'PanelList',
@ -334,7 +335,11 @@ export default {
searchMap: {
all: this.$t('commons.all'),
folder: this.$t('commons.folder')
}
},
initLocalStorage: [
'chart',
'dataset'
]
}
},
computed: {
@ -367,9 +372,20 @@ export default {
this.$store.commit('setComponentData', [])
this.$store.commit('setCanvasStyle', DEFAULT_COMMON_CANVAS_STYLE_STRING)
this.defaultTree()
this.tree(this.groupForm)
this.tree(true)
this.initCache()
},
methods: {
initCache() {
//
this.initLocalStorage.forEach(item => {
if (!localStorage.getItem(item + '-tree')) {
queryAuthModel({ modelType: item }, false).then(res => {
localStorage.setItem(item + '-tree', JSON.stringify(res.data))
})
}
})
},
closeEditPanelDialog(panelInfo) {
this.editPanel.visible = false
if (panelInfo) {
@ -392,7 +408,7 @@ export default {
}
this.activeNodeAndClick(panelInfo)
} else {
this.tree(this.groupForm)
this.tree()
}
}
},
@ -535,7 +551,7 @@ export default {
type: 'success',
showClose: true
})
this.tree(this.groupForm)
this.tree()
this.defaultTree()
})
} else {
@ -562,7 +578,7 @@ export default {
showClose: true
})
this.clearCanvas()
this.tree(this.groupForm)
this.tree()
this.defaultTree()
})
}).catch(() => {
@ -591,17 +607,32 @@ export default {
sort: 'node_type desc,name asc'
}
},
tree(group) {
groupTree(group).then(res => {
this.tData = res.data
tree(cache = false) {
const modelInfo = localStorage.getItem('panel-main-tree')
const userCache = (modelInfo && cache)
if (userCache) {
this.tData = JSON.parse(modelInfo)
}
groupTree(this.groupForm, !userCache).then(res => {
localStorage.setItem('panel-main-tree', JSON.stringify(res.data))
if (!userCache) {
this.tData = res.data
}
})
},
defaultTree() {
const requestInfo = {
panelType: 'system'
}
defaultTree(requestInfo).then(res => {
this.defaultData = res.data
const modelInfo = localStorage.getItem('panel-default-tree')
if (modelInfo) {
this.defaultData = JSON.parse(modelInfo)
}
defaultTree(requestInfo, false).then(res => {
localStorage.setItem('panel-default-tree', JSON.stringify(res.data))
if (!modelInfo) {
this.defaultData = res.data
}
})
},
@ -768,7 +799,7 @@ export default {
this.moveInfo.pid = this.tGroup.id
this.moveInfo['optType'] = 'move'
panelSave(this.moveInfo).then(response => {
this.tree(this.groupForm)
this.tree()
this.closeMoveGroup()
})
},

View File

@ -4,7 +4,7 @@
<el-tabs v-model="activeName" class="tab-panel" :stretch="true" @tab-click="handleClick">
<el-tab-pane name="PanelList">
<span slot="label"><i class="el-icon-document tablepanel-i" />{{ $t('panel.panel_list') }}</span>
<panel-list ref="panelList" v-if="activeName==='PanelList'" />
<panel-list v-if="activeName==='PanelList'" ref="panelList" />
</el-tab-pane>
<el-tab-pane name="panels_star" :lazy="true">
<span slot="label"><i class="el-icon-star-off tablepanel-i" />{{ $t('panel.store') }}</span>
@ -17,7 +17,7 @@
</el-tabs>
</de-aside-container>
<de-main-container>
<PanelViewShow v-if="mainActiveName==='PanelMain'" :active-tab="activeName" @editPanel="editPanel"/>
<PanelViewShow v-if="mainActiveName==='PanelMain'" :active-tab="activeName" @editPanel="editPanel" />
</de-main-container>
</de-container>
</template>

View File

@ -241,6 +241,7 @@ export default {
}).then(() => {
delDs(datasource.id).then(res => {
this.$success(this.$t('commons.delete_success'))
this.switchMain('DataHome')
this.refreshType(datasource)
})
}).catch(() => {

View File

@ -10,7 +10,7 @@
<el-form ref="dsForm" :model="form" :rules="rule" size="small"
:disabled="params && params.id && params.showModel && params.showModel === 'show' && !canEdit "
label-width="auto" label-position="right">
label-width="180px" label-position="right">
<el-form-item :label="$t('commons.name')" prop="name">
<el-input v-model="form.name" autocomplete="off"/>
</el-form-item>

View File

@ -36,16 +36,6 @@ module.exports = {
entry: 'src/main.js',
template: 'public/index.html',
filename: 'index.html'
},
link: {
entry: 'src/link/link.js',
template: 'public/link.html',
filename: 'link.html'
},
nolic: {
entry: 'src/nolic/nolic.js',
template: 'public/nolic.html',
filename: 'nolic.html'
}
},
configureWebpack: {