Merge branch 'dev-v2' into pr@dev-v2_dzz
This commit is contained in:
commit
bc2f8ac020
@ -67,6 +67,8 @@ public class ChartDataManage {
|
||||
@Resource
|
||||
private CorePermissionManage corePermissionManage;
|
||||
|
||||
public static final String START_END_SEPARATOR = "_START_END_SPLIT";
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(ChartDataManage.class);
|
||||
|
||||
public ChartViewDTO calcData(ChartViewDTO view) throws Exception {
|
||||
@ -246,7 +248,8 @@ public class ChartDataManage {
|
||||
List<SqlVariableDetails> sqlVariables = datasetGroupManage.getSqlParams(Arrays.asList(view.getTableId()));
|
||||
if (CollectionUtil.isNotEmpty(sqlVariables)) {
|
||||
for (SqlVariableDetails parameter : Optional.ofNullable(request.getParameters()).orElse(new ArrayList<>())) {
|
||||
if (sqlVariables.stream().map(SqlVariableDetails::getId).collect(Collectors.toList()).contains(parameter.getId())) {
|
||||
String parameterId = StringUtils.endsWith(parameter.getId(), START_END_SEPARATOR) ? parameter.getId().split(START_END_SEPARATOR)[0] : parameter.getId();
|
||||
if (sqlVariables.stream().map(SqlVariableDetails::getId).collect(Collectors.toList()).contains(parameterId)) {
|
||||
hasParameters = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static io.dataease.chart.manage.ChartDataManage.START_END_SEPARATOR;
|
||||
import static org.apache.calcite.sql.SqlKind.*;
|
||||
|
||||
public class SqlparserUtils {
|
||||
@ -166,7 +167,11 @@ public class SqlparserUtils {
|
||||
return "'" + String.join("','", sqlVariableDetails.getValue()) + "'";
|
||||
} else if (sqlVariableDetails.getOperator().equals("between")) {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(sqlVariableDetails.getType().size() > 1 ? (String) sqlVariableDetails.getType().get(1).replace("DD", "dd") : "YYYY");
|
||||
return simpleDateFormat.format(new Date(Long.parseLong((String) sqlVariableDetails.getValue().get(0))));
|
||||
if (StringUtils.endsWith(sqlVariableDetails.getId(), START_END_SEPARATOR)) {
|
||||
return simpleDateFormat.format(new Date(Long.parseLong((String) sqlVariableDetails.getValue().get(1))));
|
||||
} else {
|
||||
return simpleDateFormat.format(new Date(Long.parseLong((String) sqlVariableDetails.getValue().get(0))));
|
||||
}
|
||||
} else {
|
||||
return (String) sqlVariableDetails.getValue().get(0);
|
||||
}
|
||||
|
||||
@ -416,9 +416,6 @@ public class ExcelUtils {
|
||||
}
|
||||
List<String[]> data = new ArrayList<>(noModelDataListener.getData());
|
||||
if (isPreview) {
|
||||
if (data.size() > 100) {
|
||||
data = data.subList(0, 100);
|
||||
}
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
for (int j = 0; j < data.get(i).length; j++) {
|
||||
if (j < fields.size()) {
|
||||
@ -426,6 +423,9 @@ public class ExcelUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data.size() > 100) {
|
||||
data = data.subList(0, 100);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
@ -472,6 +472,9 @@ public class ExcelUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data.size() > 100) {
|
||||
data = data.subList(0, 100);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
if (StringUtils.isEmpty(fields.get(i).getFieldType())) {
|
||||
|
||||
@ -17,4 +17,14 @@ public interface ExtVisualizationTemplateMapper{
|
||||
|
||||
List<TemplateManageDTO> findBaseTemplateList();
|
||||
|
||||
Long checkCategoryMap(@Param("categoryId") String categoryId);
|
||||
|
||||
Long checkRepeatTemplateId(@Param("categoryId") String categoryId, @Param("templateId") String templateId);
|
||||
|
||||
void deleteCategoryMapByTemplate(@Param("templateName") String templateName, @Param("templateId") String templateId);
|
||||
|
||||
Long checkCategoryTemplateName(@Param("templateName") String templateName,@Param("categories") List<String> categories);
|
||||
|
||||
List<String> findTemplateCategories(@Param("templateId") String templateId);
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package io.dataease.template.service;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import io.dataease.api.template.TemplateManageApi;
|
||||
import io.dataease.api.template.dto.TemplateManageDTO;
|
||||
import io.dataease.api.template.request.TemplateManageBatchRequest;
|
||||
import io.dataease.api.template.request.TemplateManageRequest;
|
||||
import io.dataease.api.template.vo.VisualizationTemplateVO;
|
||||
import io.dataease.constant.CommonConstants;
|
||||
@ -56,16 +57,16 @@ public class TemplateManageService implements TemplateManageApi {
|
||||
request.setWithBlobs("N");
|
||||
List<TemplateManageDTO> templateList = extTemplateMapper.findTemplateList(request);
|
||||
if (request.getWithChildren()) {
|
||||
getTreeChildren(templateList,request.getLeafDvType());
|
||||
getTreeChildren(templateList, request.getLeafDvType());
|
||||
}
|
||||
return templateList;
|
||||
}
|
||||
|
||||
public void getTreeChildren(List<TemplateManageDTO> parentTemplateList,String dvType) {
|
||||
public void getTreeChildren(List<TemplateManageDTO> parentTemplateList, String dvType) {
|
||||
Optional.ofNullable(parentTemplateList).ifPresent(parent -> parent.forEach(parentTemplate -> {
|
||||
List<TemplateManageDTO> panelTemplateDTOChildren = extTemplateMapper.findTemplateList(new TemplateManageRequest(parentTemplate.getId(),dvType));
|
||||
List<TemplateManageDTO> panelTemplateDTOChildren = extTemplateMapper.findTemplateList(new TemplateManageRequest(parentTemplate.getId(), dvType));
|
||||
parentTemplate.setChildren(panelTemplateDTOChildren);
|
||||
getTreeChildren(panelTemplateDTOChildren,dvType);
|
||||
getTreeChildren(panelTemplateDTOChildren, dvType);
|
||||
}));
|
||||
}
|
||||
|
||||
@ -96,17 +97,21 @@ public class TemplateManageService implements TemplateManageApi {
|
||||
DEException.throwException("名称已存在");
|
||||
}
|
||||
VisualizationTemplateCategory templateCategory = new VisualizationTemplateCategory();
|
||||
BeanUtils.copyBean(templateCategory,request);
|
||||
BeanUtils.copyBean(templateCategory, request);
|
||||
templateCategoryMapper.insert(templateCategory);
|
||||
} else {//模板插入 同名的模板进行覆盖(先删除)
|
||||
// 分类映射删除
|
||||
extTemplateMapper.deleteCategoryMapByTemplate(request.getName(),null);
|
||||
// 模版删除
|
||||
QueryWrapper<VisualizationTemplate> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("name",request.getName());
|
||||
wrapper.eq("name", request.getName());
|
||||
templateMapper.delete(wrapper);
|
||||
|
||||
VisualizationTemplate template = new VisualizationTemplate();
|
||||
BeanUtils.copyBean(template,request);
|
||||
BeanUtils.copyBean(template, request);
|
||||
templateMapper.insert(template);
|
||||
// 插入分类关系
|
||||
request.getCategories().forEach(categoryId ->{
|
||||
request.getCategories().forEach(categoryId -> {
|
||||
VisualizationTemplateCategoryMap categoryMap = new VisualizationTemplateCategoryMap();
|
||||
categoryMap.setId(UUID.randomUUID().toString());
|
||||
categoryMap.setCategoryId(categoryId);
|
||||
@ -122,16 +127,27 @@ public class TemplateManageService implements TemplateManageApi {
|
||||
DEException.throwException("名称已存在");
|
||||
}
|
||||
VisualizationTemplateCategory templateCategory = new VisualizationTemplateCategory();
|
||||
BeanUtils.copyBean(templateCategory,request);
|
||||
BeanUtils.copyBean(templateCategory, request);
|
||||
templateCategoryMapper.updateById(templateCategory);
|
||||
}else{
|
||||
} else {
|
||||
String nameCheckResult = this.nameCheck(CommonConstants.OPT_TYPE.UPDATE, request.getName(), request.getId());
|
||||
if (CommonConstants.CHECK_RESULT.EXIST_ALL.equals(nameCheckResult)) {
|
||||
DEException.throwException("名称已存在");
|
||||
}
|
||||
VisualizationTemplate template = new VisualizationTemplate();
|
||||
BeanUtils.copyBean(template,request);
|
||||
BeanUtils.copyBean(template, request);
|
||||
templateMapper.updateById(template);
|
||||
//更新分类
|
||||
// 分类映射删除
|
||||
extTemplateMapper.deleteCategoryMapByTemplate(null,request.getId());
|
||||
// 插入分类关系
|
||||
request.getCategories().forEach(categoryId -> {
|
||||
VisualizationTemplateCategoryMap categoryMap = new VisualizationTemplateCategoryMap();
|
||||
categoryMap.setId(UUID.randomUUID().toString());
|
||||
categoryMap.setCategoryId(categoryId);
|
||||
categoryMap.setTemplateId(request.getId());
|
||||
categoryMapMapper.insert(categoryMap);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -141,14 +157,14 @@ public class TemplateManageService implements TemplateManageApi {
|
||||
return templateManageDTO;
|
||||
}
|
||||
|
||||
//名称检查
|
||||
public String nameCheck(String optType, String name,String id) {
|
||||
//模版名称检查
|
||||
public String nameCheck(String optType, String name, String id) {
|
||||
QueryWrapper<VisualizationTemplate> wrapper = new QueryWrapper<>();
|
||||
if (CommonConstants.OPT_TYPE.INSERT.equals(optType)) {
|
||||
wrapper.eq("name",name);
|
||||
wrapper.eq("name", name);
|
||||
} else if (CommonConstants.OPT_TYPE.UPDATE.equals(optType)) {
|
||||
wrapper.eq("name",name);
|
||||
wrapper.ne("id",id);
|
||||
wrapper.eq("name", name);
|
||||
wrapper.ne("id", id);
|
||||
}
|
||||
List<VisualizationTemplate> templateList = templateMapper.selectList(wrapper);
|
||||
if (CollectionUtils.isEmpty(templateList)) {
|
||||
@ -158,14 +174,25 @@ public class TemplateManageService implements TemplateManageApi {
|
||||
}
|
||||
}
|
||||
|
||||
//名称检查
|
||||
//分类下模版名称检查
|
||||
@Override
|
||||
public String categoryTemplateNameCheck(TemplateManageRequest request) {
|
||||
Long result = extTemplateMapper.checkCategoryTemplateName(request.getName(), request.getCategories());
|
||||
if (result == 0) {
|
||||
return CommonConstants.CHECK_RESULT.NONE;
|
||||
} else {
|
||||
return CommonConstants.CHECK_RESULT.EXIST_ALL;
|
||||
}
|
||||
}
|
||||
|
||||
//分类名称检查
|
||||
public String categoryNameCheck(String optType, String name, String id) {
|
||||
QueryWrapper<VisualizationTemplateCategory> wrapper = new QueryWrapper<>();
|
||||
if (CommonConstants.OPT_TYPE.INSERT.equals(optType)) {
|
||||
wrapper.eq("name",name);
|
||||
wrapper.eq("name", name);
|
||||
} else if (CommonConstants.OPT_TYPE.UPDATE.equals(optType)) {
|
||||
wrapper.eq("name",name);
|
||||
wrapper.ne("id",id);
|
||||
wrapper.eq("name", name);
|
||||
wrapper.ne("id", id);
|
||||
}
|
||||
List<VisualizationTemplateCategory> templateList = templateCategoryMapper.selectList(wrapper);
|
||||
if (CollectionUtils.isEmpty(templateList)) {
|
||||
@ -174,31 +201,59 @@ public class TemplateManageService implements TemplateManageApi {
|
||||
return CommonConstants.CHECK_RESULT.EXIST_ALL;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nameCheck(TemplateManageRequest request) {
|
||||
return nameCheck(request.getOptType(), request.getName(), request.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String id) {
|
||||
public void delete(String id, String categoryId) {
|
||||
Assert.notNull(id, "id cannot be null");
|
||||
templateMapper.deleteById(id);
|
||||
Assert.notNull(categoryId, "categoryId cannot be null");
|
||||
QueryWrapper<VisualizationTemplateCategoryMap> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("template_id", id);
|
||||
queryWrapper.eq("category_id", categoryId);
|
||||
categoryMapMapper.delete(queryWrapper);
|
||||
// 如何是最后一个 则实际模版需要删除
|
||||
Long result = extTemplateMapper.checkRepeatTemplateId(categoryId, id);
|
||||
if (result == 0) {
|
||||
templateMapper.deleteById(id);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCategory(String id) {
|
||||
public String deleteCategory(String id) {
|
||||
Assert.notNull(id, "id cannot be null");
|
||||
templateCategoryMapper.deleteById(id);
|
||||
// 该分类下是否有其他分类公用的模版
|
||||
|
||||
Long checkResult = extTemplateMapper.checkCategoryMap(id);
|
||||
if (checkResult == 0) {
|
||||
templateCategoryMapper.deleteById(id);
|
||||
QueryWrapper<VisualizationTemplateCategoryMap> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("category_id", id);
|
||||
categoryMapMapper.delete(queryWrapper);
|
||||
return "success";
|
||||
} else {
|
||||
return "repeat";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisualizationTemplateVO findOne(String templateId) {
|
||||
VisualizationTemplate template = templateMapper.selectById(templateId);
|
||||
if(template != null){
|
||||
if (template != null) {
|
||||
VisualizationTemplateVO templateVO = new VisualizationTemplateVO();
|
||||
BeanUtils.copyBean(templateVO,template);
|
||||
BeanUtils.copyBean(templateVO, template);
|
||||
//查找分类
|
||||
List<String> categories = extTemplateMapper.findTemplateCategories(templateId);
|
||||
templateVO.setCategories(categories);
|
||||
return templateVO;
|
||||
}else{
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TemplateManageDTO> find(TemplateManageRequest request) {
|
||||
return extTemplateMapper.findTemplateList(request);
|
||||
@ -208,4 +263,39 @@ public class TemplateManageService implements TemplateManageApi {
|
||||
public List<TemplateManageDTO> findCategories(TemplateManageRequest request) {
|
||||
return extTemplateMapper.findCategories(request);
|
||||
}
|
||||
@Override
|
||||
public void batchUpdate(TemplateManageBatchRequest request) {
|
||||
request.getTemplateIds().forEach(templateId ->{
|
||||
// 分类映射删除
|
||||
extTemplateMapper.deleteCategoryMapByTemplate(null,templateId);
|
||||
// 插入分类关系
|
||||
request.getCategories().forEach(categoryId -> {
|
||||
VisualizationTemplateCategoryMap categoryMap = new VisualizationTemplateCategoryMap();
|
||||
categoryMap.setId(UUID.randomUUID().toString());
|
||||
categoryMap.setCategoryId(categoryId);
|
||||
categoryMap.setTemplateId(templateId);
|
||||
categoryMapMapper.insert(categoryMap);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchDelete(TemplateManageBatchRequest request) {
|
||||
request.getTemplateIds().forEach(templateId ->{
|
||||
request.getCategories().forEach(categoryId -> {
|
||||
QueryWrapper<VisualizationTemplateCategoryMap> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("template_id", templateId);
|
||||
queryWrapper.eq("category_id", categoryId);
|
||||
categoryMapMapper.delete(queryWrapper);
|
||||
// 如何是最后一个 则实际模版需要删除
|
||||
Long result = extTemplateMapper.checkRepeatTemplateId(categoryId, templateId);
|
||||
if (result == 0) {
|
||||
templateMapper.deleteById(templateId);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,24 +3,24 @@
|
||||
<mapper namespace="io.dataease.template.dao.ext.ExtVisualizationTemplateMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="io.dataease.api.template.vo.VisualizationTemplateVO">
|
||||
<id column="id" jdbcType="VARCHAR" property="id" />
|
||||
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||
<result column="pid" jdbcType="VARCHAR" property="pid" />
|
||||
<result column="level" jdbcType="INTEGER" property="level" />
|
||||
<result column="dv_type" jdbcType="VARCHAR" property="dvType" />
|
||||
<result column="node_type" jdbcType="VARCHAR" property="nodeType" />
|
||||
<result column="create_by" jdbcType="VARCHAR" property="createBy" />
|
||||
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||
<result column="template_type" jdbcType="VARCHAR" property="templateType" />
|
||||
<result column="snapshot" jdbcType="LONGVARCHAR" property="snapshot" />
|
||||
<result column="template_style" jdbcType="LONGVARCHAR" property="templateStyle" />
|
||||
<result column="template_data" jdbcType="LONGVARCHAR" property="templateData" />
|
||||
<result column="dynamic_data" jdbcType="LONGVARCHAR" property="dynamicData" />
|
||||
<id column="id" jdbcType="VARCHAR" property="id"/>
|
||||
<result column="name" jdbcType="VARCHAR" property="name"/>
|
||||
<result column="pid" jdbcType="VARCHAR" property="pid"/>
|
||||
<result column="level" jdbcType="INTEGER" property="level"/>
|
||||
<result column="dv_type" jdbcType="VARCHAR" property="dvType"/>
|
||||
<result column="node_type" jdbcType="VARCHAR" property="nodeType"/>
|
||||
<result column="create_by" jdbcType="VARCHAR" property="createBy"/>
|
||||
<result column="create_time" jdbcType="BIGINT" property="createTime"/>
|
||||
<result column="template_type" jdbcType="VARCHAR" property="templateType"/>
|
||||
<result column="snapshot" jdbcType="LONGVARCHAR" property="snapshot"/>
|
||||
<result column="template_style" jdbcType="LONGVARCHAR" property="templateStyle"/>
|
||||
<result column="template_data" jdbcType="LONGVARCHAR" property="templateData"/>
|
||||
<result column="dynamic_data" jdbcType="LONGVARCHAR" property="dynamicData"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="BaseResultMapDTO" type="io.dataease.api.template.dto.TemplateManageDTO"
|
||||
extends="BaseResultMap">
|
||||
<result column="recent_use_time" jdbcType="BIGINT" property="recentUseTime" />
|
||||
<result column="recent_use_time" jdbcType="BIGINT" property="recentUseTime"/>
|
||||
<result column="label" jdbcType="VARCHAR" property="label"/>
|
||||
<result column="childrenCount" jdbcType="VARCHAR" property="childrenCount"/>
|
||||
</resultMap>
|
||||
@ -33,57 +33,55 @@
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
vt.id, vt.`name`, vt.pid, vt.`level`,vt.`dv_type`, vt.node_type, vt.create_by, vt.create_time, vt.template_type, vt.snapshot
|
||||
</sql>
|
||||
vt
|
||||
.
|
||||
id
|
||||
, vt.`name`, vt.pid, vt.`level`,vt.`dv_type`, vt.node_type, vt.create_by, vt.create_time, vt.template_type, vt.snapshot
|
||||
</sql>
|
||||
<sql id="Blob_Column_List">
|
||||
,vt.template_style, vt.template_data, vt.dynamic_data
|
||||
</sql>
|
||||
,vt.template_style, vt.template_data, vt.dynamic_data
|
||||
</sql>
|
||||
|
||||
<select id="findBaseTemplateList" resultMap="BaseResultMapCollectionDTO">
|
||||
SELECT
|
||||
vt.id,
|
||||
vt.`name`,
|
||||
vt.pid,
|
||||
vt.`level`,
|
||||
vt.`dv_type`,
|
||||
vt.node_type,
|
||||
vt.create_by,
|
||||
vt.create_time,
|
||||
vt.template_type,
|
||||
vt.SNAPSHOT,
|
||||
vtcm.category_id,
|
||||
cor.time as 'recent_use_time'
|
||||
FROM
|
||||
visualization_template vt
|
||||
LEFT JOIN visualization_template_category_map vtcm ON vt.id = vtcm.template_id
|
||||
left JOIN core_opt_recent cor on cor.resource_type=6 and vt.id= cor.resource_name
|
||||
ORDER BY
|
||||
vt.create_time DESC
|
||||
SELECT vt.id,
|
||||
vt.`name`,
|
||||
vt.pid,
|
||||
vt.`level`,
|
||||
vt.`dv_type`,
|
||||
vt.node_type,
|
||||
vt.create_by,
|
||||
vt.create_time,
|
||||
vt.template_type,
|
||||
vt.SNAPSHOT,
|
||||
vtcm.category_id,
|
||||
cor.time as 'recent_use_time'
|
||||
FROM visualization_template vt
|
||||
LEFT JOIN visualization_template_category_map vtcm ON vt.id = vtcm.template_id
|
||||
left JOIN core_opt_recent cor on cor.resource_type = 6 and vt.id = cor.resource_name
|
||||
ORDER BY vt.create_time DESC
|
||||
</select>
|
||||
|
||||
<select id="findCategories" resultMap="BaseResultMapDTO">
|
||||
SELECT
|
||||
id,
|
||||
`name`,
|
||||
`name` as lable,
|
||||
pid,
|
||||
`level`,
|
||||
`dv_type`,
|
||||
node_type,
|
||||
create_by,
|
||||
create_time,
|
||||
template_type,
|
||||
SNAPSHOT
|
||||
FROM
|
||||
visualization_template_category
|
||||
SELECT id,
|
||||
`name`,
|
||||
`name` as lable,
|
||||
pid,
|
||||
`level`,
|
||||
`dv_type`,
|
||||
node_type,
|
||||
create_by,
|
||||
create_time,
|
||||
template_type,
|
||||
SNAPSHOT
|
||||
FROM visualization_template_category
|
||||
order by visualization_template_category.create_time desc
|
||||
</select>
|
||||
|
||||
<select id="findTemplateList" resultMap="BaseResultMapDTO">
|
||||
SELECT
|
||||
<include refid="Base_Column_List" />
|
||||
<include refid="Base_Column_List"/>
|
||||
<if test='withBlobs == "Y"'>
|
||||
<include refid="Blob_Column_List" />
|
||||
<include refid="Blob_Column_List"/>
|
||||
</if>
|
||||
FROM
|
||||
visualization_template vt
|
||||
@ -91,4 +89,51 @@
|
||||
where vtcm.category_id=#{categoryId}
|
||||
order by vt.create_time desc
|
||||
</select>
|
||||
|
||||
<select id="checkCategoryMap" resultType="Long">
|
||||
SELECT count(1)
|
||||
FROM visualization_template_category_map cm
|
||||
WHERE cm.category_id = #{categoryId}
|
||||
</select>
|
||||
|
||||
<select id="checkRepeatTemplateId" resultType="Long">
|
||||
SELECT count(1)
|
||||
FROM visualization_template_category_map cm
|
||||
where cm.category_id != #{categoryId}
|
||||
and cm.template_id =#{templateId}
|
||||
</select>
|
||||
|
||||
<select id="checkCategoryTemplateName" resultType="Long">
|
||||
SELECT
|
||||
count(1)
|
||||
FROM
|
||||
visualization_template vt
|
||||
LEFT JOIN visualization_template_category_map vtcm ON vt.id = vtcm.template_id
|
||||
WHERE
|
||||
vt.NAME = #{templateName}
|
||||
AND vtcm.category_id IN
|
||||
<foreach collection="categories" item="categoryId" index="index" open="(" close=")" separator=",">
|
||||
#{categoryId}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<delete id="deleteCategoryMapByTemplate">
|
||||
delete from visualization_template_category_map tcm
|
||||
<where>
|
||||
<if test="templateName">
|
||||
tcm.template_id in (
|
||||
select id from visualization_template vt where vt.name = #{templateName})
|
||||
</if>
|
||||
|
||||
<if test="templateId">
|
||||
and tcm.template_id = #{templateId}
|
||||
</if>
|
||||
</where>
|
||||
</delete>
|
||||
|
||||
<select id="findTemplateCategories" resultType="String">
|
||||
select category_id
|
||||
from visualization_template_category_map
|
||||
where template_id = #{templateId}
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@ -7,9 +7,9 @@ export function save(data) {
|
||||
loading: true
|
||||
})
|
||||
}
|
||||
export function templateDelete(id) {
|
||||
export function templateDelete(id, categoryId) {
|
||||
return request.post({
|
||||
url: '/templateManage/delete/' + id
|
||||
url: '/templateManage/delete/' + id + '/' + categoryId
|
||||
})
|
||||
}
|
||||
|
||||
@ -54,3 +54,24 @@ export function nameCheck(data) {
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function categoryTemplateNameCheck(data) {
|
||||
return request.post({
|
||||
url: '/templateManage/categoryTemplateNameCheck',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function batchDelete(data) {
|
||||
return request.post({
|
||||
url: '/templateManage/batchDelete',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function batchUpdate(data) {
|
||||
return request.post({
|
||||
url: '/templateManage/batchUpdate',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
@ -49,6 +49,7 @@
|
||||
:style="getPointStyle(item)"
|
||||
@mousedown="handleMouseDownOnPoint(item, $event)"
|
||||
></div>
|
||||
<div class="shape-shadow" v-show="batchOptStatus" @mousedown="batchSelected"></div>
|
||||
<template v-if="boardMoveActive">
|
||||
<div
|
||||
v-show="!element.editing"
|
||||
@ -517,6 +518,15 @@ const selectCurComponent = e => {
|
||||
}
|
||||
}
|
||||
|
||||
const batchSelected = e => {
|
||||
if (dvMainStore.batchOptStatus) {
|
||||
componentEditBarRef.value.batchOptCheckOut()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const handleMouseDownOnPoint = (point, e) => {
|
||||
dashboardActive.value && emit('onStartResize', e)
|
||||
dvMainStore.setInEditorStatus(true)
|
||||
@ -833,6 +843,15 @@ onMounted(() => {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.shape-shadow {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
background-size: 100% 100% !important;
|
||||
}
|
||||
|
||||
.shape-inner {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
@ -10,6 +10,8 @@ import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import AboutPage from '@/views/about/index.vue'
|
||||
import LangSelector from './LangSelector.vue'
|
||||
import router from '@/router'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
const { wsCache } = useCache()
|
||||
const userStore = useUserStoreWithOut()
|
||||
const { t } = useI18n()
|
||||
|
||||
@ -30,6 +32,16 @@ const linkLoaded = items => {
|
||||
items.forEach(item => linkList.value.push(item))
|
||||
linkList.value.sort(compare('id'))
|
||||
}
|
||||
const xpackLinkLoaded = items => {
|
||||
let len = linkList.value.length
|
||||
while (len--) {
|
||||
if (linkList.value[len]?.id === 2 && linkList.value[len]?.link === '/modify-pwd/index') {
|
||||
linkList.value.splice(len, 1)
|
||||
}
|
||||
}
|
||||
items.forEach(item => linkList.value.push(item))
|
||||
linkList.value.sort(compare('id'))
|
||||
}
|
||||
|
||||
const compare = (property: string) => {
|
||||
return (a, b) => a[property] - b[property]
|
||||
@ -68,6 +80,10 @@ const openPopover = () => {
|
||||
|
||||
if (uid.value === '1') {
|
||||
linkLoaded([{ id: 4, link: '/sys-setting/parameter', label: t('commons.system_setting') }])
|
||||
const desktop = wsCache.get('app.desktop')
|
||||
if (!desktop) {
|
||||
linkLoaded([{ id: 2, link: '/modify-pwd/index', label: t('user.change_password') }])
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -138,7 +154,7 @@ if (uid.value === '1') {
|
||||
</el-popover>
|
||||
|
||||
<AboutPage />
|
||||
<XpackComponent jsname="dWNlbnRlci1oYW5kbGVy" @loaded="linkLoaded" />
|
||||
<XpackComponent jsname="dWNlbnRlci1oYW5kbGVy" @loaded="xpackLinkLoaded" />
|
||||
</template>
|
||||
|
||||
<style lang="less">
|
||||
|
||||
@ -1354,7 +1354,7 @@ export default {
|
||||
pls_input_filename: '请输入文件名称',
|
||||
calc_tips: {
|
||||
tip1: '表达式语法请遵循calcite语法。',
|
||||
tip2: '数据集中不支持聚合运算。',
|
||||
tip2: '聚合运算仅能在图表中生效。',
|
||||
tip3: '引用字段以 "[" 开始, "]" 结束',
|
||||
tip4: '请勿修改引用内容,否则将引用失败',
|
||||
tip5: '若输入与引用字段相同格式的内容,将被当作引用字段处理',
|
||||
|
||||
@ -96,6 +96,22 @@ export const routes: AppRouteRecordRaw[] = [
|
||||
hidden: true,
|
||||
meta: {},
|
||||
component: () => import('@/custom-component/rich-text/DeRichTextView.vue')
|
||||
},
|
||||
{
|
||||
path: '/modify-pwd',
|
||||
name: 'modify-pwd',
|
||||
hidden: true,
|
||||
meta: {},
|
||||
component: () => import('@/layout/index.vue'),
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: 'mpi',
|
||||
hidden: true,
|
||||
component: () => import('@/views/system/modify-pwd/index.vue'),
|
||||
meta: { hidden: true }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@ -554,6 +554,7 @@ onMounted(() => {
|
||||
<el-checkbox
|
||||
:disabled="!formatterEditable"
|
||||
v-model="curSeriesFormatter.show"
|
||||
:effect="themes"
|
||||
size="small"
|
||||
label="quota"
|
||||
@change="changeTooltipAttr('seriesTooltipFormatter', true)"
|
||||
|
||||
140
core/core-frontend/src/views/system/modify-pwd/UpdatePwd.vue
Normal file
140
core/core-frontend/src/views/system/modify-pwd/UpdatePwd.vue
Normal file
@ -0,0 +1,140 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import request from '@/config/axios'
|
||||
import { rsaEncryp } from '@/utils/encryption'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
import { logoutHandler } from '@/utils/logout'
|
||||
import { CustomPassword } from '@/components/custom-password'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const defaultForm = {
|
||||
pwd: '',
|
||||
newPwd: '',
|
||||
confirm: ''
|
||||
}
|
||||
const pwdForm = reactive(cloneDeep(defaultForm))
|
||||
|
||||
const validatePwd = (_: any, value: any, callback: any) => {
|
||||
if (value === pwdForm.pwd) {
|
||||
callback(new Error('新旧密码不能相同'))
|
||||
}
|
||||
const pattern =
|
||||
/^.*(?=.{6,20})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[~!@#$%^&*()_+\-\={}|":<>?`[\];',.\/])[a-zA-Z0-9~!@#$%^&*()_+\-\={}|":<>?`[\];',.\/]*$/
|
||||
const regep = new RegExp(pattern)
|
||||
if (!regep.test(value)) {
|
||||
const msg = t('user.pwd_pattern_error')
|
||||
callback(new Error(msg))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const validateConfirmPwd = (_: any, value: any, callback: any) => {
|
||||
if (value !== pwdForm.newPwd) {
|
||||
callback(new Error('两次输入的密码不一致'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const rule = {
|
||||
pwd: [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.require'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 20,
|
||||
message: t('commons.input_limit', [6, 20]),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
newPwd: [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.require'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{ validator: validatePwd, trigger: 'blur' }
|
||||
],
|
||||
confirm: [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.require'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 20,
|
||||
message: t('commons.input_limit', [6, 20]),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{ validator: validateConfirmPwd, trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
const updatePwdForm = ref()
|
||||
|
||||
const save = () => {
|
||||
updatePwdForm.value.validate(val => {
|
||||
if (val) {
|
||||
const pwd = rsaEncryp(pwdForm.pwd)
|
||||
const newPwd = rsaEncryp(pwdForm.newPwd)
|
||||
request.post({ url: '/user/modifyPwd', data: { pwd, newPwd } }).then(() => {
|
||||
ElMessage.success('修改成功,请重新登录')
|
||||
logoutHandler()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-form
|
||||
ref="updatePwdForm"
|
||||
require-asterisk-position="right"
|
||||
:model="pwdForm"
|
||||
:rules="rule"
|
||||
class="mt16"
|
||||
label-width="80px"
|
||||
label-position="top"
|
||||
>
|
||||
<el-form-item label="原始密码" prop="pwd">
|
||||
<CustomPassword
|
||||
v-model="pwdForm.pwd"
|
||||
show-password
|
||||
type="password"
|
||||
placeholder="请输入原始密码"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPwd">
|
||||
<CustomPassword
|
||||
v-model="pwdForm.newPwd"
|
||||
show-password
|
||||
type="password"
|
||||
placeholder="请输入新密码"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="confirm">
|
||||
<CustomPassword
|
||||
v-model="pwdForm.confirm"
|
||||
show-password
|
||||
type="password"
|
||||
placeholder="请输入确认密码"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-button style="margin-top: 12px" @click="save" type="primary">
|
||||
{{ t('common.save') }}
|
||||
</el-button>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.mt16 {
|
||||
margin-top: 16px;
|
||||
}
|
||||
</style>
|
||||
198
core/core-frontend/src/views/system/modify-pwd/index.vue
Normal file
198
core/core-frontend/src/views/system/modify-pwd/index.vue
Normal file
@ -0,0 +1,198 @@
|
||||
<template>
|
||||
<div class="user-center flex-align-center">
|
||||
<div class="user-center-container">
|
||||
<div class="user-tabs">
|
||||
<div class="tabs-title flex-align-center">用户中心</div>
|
||||
<el-divider />
|
||||
<div class="list-item_primary active">
|
||||
{{ t('user.change_password') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="base-info">
|
||||
<div class="info-title flex-align-center">
|
||||
<span class="title">
|
||||
{{ t('user.change_password') }}
|
||||
</span>
|
||||
</div>
|
||||
<update-pwd />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import UpdatePwd from './UpdatePwd.vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.user-center {
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
padding-top: 24px;
|
||||
.user-center-container {
|
||||
display: flex;
|
||||
font-family: PingFang SC;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.user-tabs {
|
||||
width: 200px;
|
||||
height: 201px;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
padding: 16px;
|
||||
.list-item_primary {
|
||||
padding: 9px 8px;
|
||||
}
|
||||
|
||||
.ed-divider {
|
||||
margin: 4px 0;
|
||||
border-color: rgba(31, 35, 41, 0.15);
|
||||
}
|
||||
|
||||
.tabs-title {
|
||||
padding-left: 8px;
|
||||
color: #8d9199;
|
||||
font-family: PingFang SC;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 22px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
.user-info {
|
||||
margin-left: 16px;
|
||||
width: 864px;
|
||||
height: 326px;
|
||||
|
||||
.base-info {
|
||||
& + .base-info {
|
||||
margin-top: 12px;
|
||||
.bind-info {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 16px 24px 16px 24px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #dee0e3;
|
||||
.bind {
|
||||
font-size: 48px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.info {
|
||||
font-family: PingFang SC;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
width: 80%;
|
||||
|
||||
.name {
|
||||
color: #1f2329;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 500;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tip {
|
||||
color: #646a73;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
max-width: 600px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.delete {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
padding: 20px 24px 24px 24px;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
.role {
|
||||
& + .role {
|
||||
margin-left: 4px;
|
||||
}
|
||||
display: inline-flex;
|
||||
height: 20px;
|
||||
padding: 0 6px;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
color: #2b5fd9;
|
||||
border-radius: 2px;
|
||||
background: rgba(51, 112, 255, 0.2);
|
||||
}
|
||||
.info-title {
|
||||
.ed-button {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #1f2329;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.base-info-item {
|
||||
margin-top: 16px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
width: 100%;
|
||||
.label {
|
||||
color: #646a73;
|
||||
}
|
||||
.value {
|
||||
margin-top: 4px;
|
||||
color: #1f2329;
|
||||
}
|
||||
}
|
||||
.mr12 {
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="less">
|
||||
.qr-code-dialog {
|
||||
font-family: PingFang SC;
|
||||
font-style: normal;
|
||||
.ed-dialog__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.qr-code-img {
|
||||
margin-top: 16px;
|
||||
display: inline-block;
|
||||
padding: 8px 12px;
|
||||
img {
|
||||
width: 184px;
|
||||
height: 184px;
|
||||
}
|
||||
border-radius: 8px;
|
||||
border: 1px solid #bbbfc4;
|
||||
}
|
||||
|
||||
.refresh-login {
|
||||
margin: 0 auto;
|
||||
margin-top: 9px;
|
||||
color: #646a73;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
|
||||
.ed-icon {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<div class="template-import">
|
||||
<el-form
|
||||
ref="templateImportForm"
|
||||
class="de-form-item"
|
||||
:model="state.templateInfo"
|
||||
:rules="state.templateInfoRules"
|
||||
label-position="top"
|
||||
>
|
||||
<el-form-item :label="'选择分类'" prop="categories" style="margin-top: 16px">
|
||||
<el-select v-model="state.templateInfo.categories" multiple style="width: 100%">
|
||||
<el-option
|
||||
v-for="option in templateCategories"
|
||||
:key="option.id"
|
||||
:label="option.name"
|
||||
:value="option.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row> </el-row>
|
||||
<el-row class="de-root-class">
|
||||
<el-button secondary @click="cancel()">{{ t('commons.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="saveChange()">{{ t('commons.confirm') }}</el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { batchUpdate } from '@/api/template'
|
||||
const emits = defineEmits(['closeBatchEditTemplateDialog', 'refresh'])
|
||||
const { t } = useI18n()
|
||||
const props = defineProps({
|
||||
templateCategories: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
templateIds: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const state = reactive({
|
||||
templateInfo: {
|
||||
categories: []
|
||||
},
|
||||
categories: [],
|
||||
templateInfoRules: {
|
||||
categories: [
|
||||
{
|
||||
required: true,
|
||||
message: t('commons.input_content'),
|
||||
trigger: 'change'
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
// showCurrentTemplate(props.pid)
|
||||
})
|
||||
|
||||
const cancel = () => {
|
||||
emits('closeBatchEditTemplateDialog')
|
||||
}
|
||||
|
||||
const saveChange = () => {
|
||||
const params = {
|
||||
templateIds: props.templateIds,
|
||||
categories: state.templateInfo.categories
|
||||
}
|
||||
batchUpdate(params).then(rsp => {
|
||||
emits('refresh')
|
||||
emits('closeBatchEditTemplateDialog')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.de-root-class {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
@ -23,11 +23,7 @@
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-row
|
||||
v-show="!!state.importTemplateInfo.snapshot"
|
||||
class="preview"
|
||||
:style="classBackground"
|
||||
/>
|
||||
<el-row v-show="!!state.templateInfo.snapshot" class="preview" :style="classBackground" />
|
||||
<el-form-item :label="'选择分类'" prop="categories" style="margin-top: 16px">
|
||||
<el-select v-model="state.templateInfo.categories" multiple style="width: 100%">
|
||||
<el-option
|
||||
@ -36,6 +32,16 @@
|
||||
:label="option.name"
|
||||
:value="option.id"
|
||||
/>
|
||||
<div class="custom-option-line"></div>
|
||||
<div>
|
||||
<el-button
|
||||
@click="doAddCategory"
|
||||
icon="Plus"
|
||||
text
|
||||
style="width: 100%; justify-content: flex-start"
|
||||
>添加分类</el-button
|
||||
>
|
||||
</div>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@ -48,12 +54,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { save, nameCheck, find } from '@/api/template'
|
||||
import { save, nameCheck, find, findOne, categoryTemplateNameCheck } from '@/api/template'
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { imgUrlTrans } from '@/utils/imgUtils'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus-secondary'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
const emits = defineEmits(['closeEditTemplateDialog', 'refresh'])
|
||||
const emits = defineEmits(['closeEditTemplateDialog', 'refresh', 'addCategoryInfo'])
|
||||
const { t } = useI18n()
|
||||
const filesRef = ref(null)
|
||||
const props = defineProps({
|
||||
@ -64,6 +70,15 @@ const props = defineProps({
|
||||
templateCategories: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
optType: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: 'insert'
|
||||
},
|
||||
templateId: {
|
||||
type: String,
|
||||
required: false
|
||||
}
|
||||
})
|
||||
|
||||
@ -105,9 +120,9 @@ const state = reactive({
|
||||
})
|
||||
|
||||
const classBackground = computed(() => {
|
||||
if (state.importTemplateInfo.snapshot) {
|
||||
if (state.templateInfo.snapshot) {
|
||||
return {
|
||||
background: `url(${imgUrlTrans(state.importTemplateInfo.snapshot)}) no-repeat`
|
||||
background: `url(${imgUrlTrans(state.templateInfo.snapshot)}) no-repeat`
|
||||
}
|
||||
} else {
|
||||
return {}
|
||||
@ -119,6 +134,7 @@ const showCurrentTemplate = pid => {
|
||||
state.nameList = response.data
|
||||
})
|
||||
}
|
||||
|
||||
const cancel = () => {
|
||||
emits('closeEditTemplateDialog')
|
||||
}
|
||||
@ -138,40 +154,63 @@ const saveTemplate = () => {
|
||||
return false
|
||||
}
|
||||
|
||||
if (props.optType === 'insert') {
|
||||
importTemplate()
|
||||
} else {
|
||||
editTemplate()
|
||||
}
|
||||
}
|
||||
|
||||
const editTemplate = () => {
|
||||
const nameCheckRequest = {
|
||||
pid: state.templateInfo.pid,
|
||||
name: state.templateInfo.name,
|
||||
categories: state.templateInfo.categories,
|
||||
optType: 'insert'
|
||||
optType: props.optType
|
||||
}
|
||||
// 全局名称校验
|
||||
nameCheck(nameCheckRequest).then(response => {
|
||||
if (response.data.indexOf('exist') > -1) {
|
||||
ElMessage.warning(t('当前模版名称已经存在'))
|
||||
// const options = {
|
||||
// title: 'commons.prompt',
|
||||
// content: 'system_parameter_setting.to_overwrite_them',
|
||||
// type: 'primary',
|
||||
// cb: () =>
|
||||
// save(state.templateInfo).then(response => {
|
||||
// ElMessage.success('导入成功')
|
||||
// emits('refresh')
|
||||
// emits('closeEditTemplateDialog')
|
||||
// }),
|
||||
// confirmButtonText: t('template.override')
|
||||
// }
|
||||
// handlerConfirm(options)
|
||||
} else {
|
||||
save(state.templateInfo).then(response => {
|
||||
ElMessage.success(t('导入成功'))
|
||||
emits('refresh')
|
||||
emits('closeEditTemplateDialog')
|
||||
})
|
||||
}
|
||||
save(state.templateInfo).then(response => {
|
||||
ElMessage.success(t('编辑成功'))
|
||||
emits('refresh')
|
||||
emits('closeEditTemplateDialog')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const handlerConfirm = option => {
|
||||
// do handlerConfirm
|
||||
const importTemplate = () => {
|
||||
const nameCheckRequest = {
|
||||
pid: state.templateInfo.pid,
|
||||
name: state.templateInfo.name,
|
||||
categories: state.templateInfo.categories,
|
||||
optType: props.optType
|
||||
}
|
||||
categoryTemplateNameCheck(nameCheckRequest).then(response => {
|
||||
if (response.data.indexOf('exist') > -1) {
|
||||
ElMessageBox.confirm('提示?', {
|
||||
tip: '当前分类存在相同模版名称,是否覆盖?',
|
||||
confirmButtonType: 'danger',
|
||||
type: 'warning',
|
||||
autofocus: false,
|
||||
showClose: false
|
||||
}).then(() => {
|
||||
save(state.templateInfo).then(response => {
|
||||
ElMessage.success(t('覆盖成功'))
|
||||
emits('refresh')
|
||||
emits('closeEditTemplateDialog')
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// 全局名称校验
|
||||
nameCheck(nameCheckRequest).then(response => {
|
||||
save(state.templateInfo).then(response => {
|
||||
ElMessage.success(t('导入成功'))
|
||||
emits('refresh')
|
||||
emits('closeEditTemplateDialog')
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleFileChange = e => {
|
||||
@ -195,9 +234,19 @@ const goFile = () => {
|
||||
filesRef.value.click()
|
||||
}
|
||||
|
||||
const doAddCategory = () => {
|
||||
emits('addCategoryInfo')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
showCurrentTemplate(props.pid)
|
||||
// showCurrentTemplate(props.pid)
|
||||
})
|
||||
|
||||
if (props.templateId) {
|
||||
findOne(props.templateId).then(rsp => {
|
||||
state.templateInfo = rsp.data
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
@ -245,4 +294,11 @@ onMounted(() => {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-option-line {
|
||||
width: calc(100% -8px);
|
||||
margin: 4px;
|
||||
height: 1px;
|
||||
background-color: rgba(31, 35, 41, 0.15);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,19 +1,15 @@
|
||||
<template>
|
||||
<div :style="classBackground" class="de-card-model">
|
||||
<div
|
||||
:style="classBackground"
|
||||
class="de-card-model"
|
||||
:class="{ 'de-card-model-active': batchState, 'de-card-model-checked': model.checked }"
|
||||
>
|
||||
<el-checkbox class="custom-item-checkbox" v-model="model.checked" />
|
||||
<div class="card-img-model" :style="classImg">
|
||||
<img :src="imgUrlTrans(model.snapshot)" alt="" />
|
||||
</div>
|
||||
<div class="card-info">
|
||||
<div style="display: flex; align-items: center; width: calc(100% - 24px)">
|
||||
<el-tooltip class="item" effect="dark" :content="dvTypeName" placement="top">
|
||||
<el-icon style="font-size: 18px" v-if="model.dvType === 'dashboard'">
|
||||
<Icon name="dv-dashboard-spine"></Icon>
|
||||
</el-icon>
|
||||
<el-icon class="icon-screen-new" style="font-size: 18px" v-else>
|
||||
<Icon name="icon_operation-analysis_outlined"></Icon>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
|
||||
<el-tooltip class="item" effect="dark" :content="model.name" placement="top">
|
||||
<span class="de-model-text">{{ model.name }}</span>
|
||||
</el-tooltip>
|
||||
@ -24,7 +20,7 @@
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu class="de-card-dropdown">
|
||||
<slot>
|
||||
<el-dropdown-item command="rename">
|
||||
<el-dropdown-item command="templateEdit">
|
||||
<el-icon><EditPen /></el-icon>
|
||||
编辑
|
||||
</el-dropdown-item>
|
||||
@ -42,7 +38,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { imgUrlTrans } from '@/utils/imgUtils'
|
||||
import { computed } from 'vue'
|
||||
import { computed, toRefs } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
const { t } = useI18n()
|
||||
const emits = defineEmits(['command'])
|
||||
@ -53,9 +49,14 @@ const props = defineProps({
|
||||
},
|
||||
width: {
|
||||
type: Number
|
||||
},
|
||||
batchState: {
|
||||
type: Boolean
|
||||
}
|
||||
})
|
||||
|
||||
const { model, width, batchState } = toRefs(props)
|
||||
|
||||
const dvTypeName = computed(() => {
|
||||
return props.model.dvType === 'dashboard' ? '仪表板' : '数据大屏'
|
||||
})
|
||||
@ -79,13 +80,28 @@ const handleCommand = key => {
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.de-card-model-checked {
|
||||
border: 1px solid #3370ff !important;
|
||||
}
|
||||
.de-card-model-active {
|
||||
.custom-item-checkbox {
|
||||
display: inline !important;
|
||||
}
|
||||
}
|
||||
.de-card-model {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
background: #ffffff;
|
||||
border: 1px solid var(--deCardStrokeColor, #dee0e3);
|
||||
border: 1px solid #dee0e3;
|
||||
border-radius: 4px;
|
||||
margin: 0 24px 25px 0;
|
||||
overflow: hidden;
|
||||
.custom-item-checkbox {
|
||||
position: absolute;
|
||||
display: none;
|
||||
right: 8px;
|
||||
top: 8px;
|
||||
}
|
||||
.card-img-model {
|
||||
border-bottom: 1px solid var(--deCardStrokeColor, #dee0e3);
|
||||
height: 144px;
|
||||
@ -106,7 +122,7 @@ const handleCommand = key => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 4px 12px 9px 12px;
|
||||
padding: 4px 12px 9px 0px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.el-icon-more {
|
||||
@ -147,6 +163,12 @@ const handleCommand = key => {
|
||||
}
|
||||
}
|
||||
|
||||
.de-card-model:hover {
|
||||
.custom-item-checkbox {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.de-card-model:hover {
|
||||
box-shadow: 0px 6px 24px rgba(31, 35, 41, 0.08);
|
||||
}
|
||||
|
||||
@ -105,7 +105,7 @@ const add = () => {
|
||||
}
|
||||
const categoryDelete = template => {
|
||||
ElMessageBox.confirm('确定删除该分类吗?', {
|
||||
tip: '删除后,该分类下的所有模版也将删除。',
|
||||
tip: '',
|
||||
confirmButtonType: 'danger',
|
||||
type: 'warning',
|
||||
autofocus: false,
|
||||
|
||||
@ -62,10 +62,22 @@
|
||||
v-for="item in currentTemplateShowListComputed"
|
||||
:key="item.id"
|
||||
:width="state.templateCurWidth"
|
||||
:batch-state="batchState > 0"
|
||||
:model="item"
|
||||
@command="key => handleCommand(key, item)"
|
||||
/>
|
||||
</div>
|
||||
<div v-show="batchState" class="batch-opt-area">
|
||||
<el-button @click="batchUpdate" type="danger" plain style="margin-left: 24px"
|
||||
>修改分类</el-button
|
||||
>
|
||||
<el-button @click="batchPreDelete" type="danger" plain>批量删除</el-button>
|
||||
<span style="margin-left: 24px; font-size: 14px">已选 {{ batchState }} 项</span>
|
||||
<el-button @click="batchFullSelect" style="margin-left: 16px" text
|
||||
>全选 {{ currentTemplateShowListComputed.length }} 项</el-button
|
||||
>
|
||||
<el-button @click="batchClear" text>清空</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -74,16 +86,17 @@
|
||||
v-model="state.editTemplate"
|
||||
append-to-body
|
||||
class="de-dialog-form"
|
||||
width="600px"
|
||||
width="420px"
|
||||
>
|
||||
<el-form
|
||||
ref="templateEditFormRef"
|
||||
label-position="top"
|
||||
class="de-form-item"
|
||||
:model="state.templateEditForm"
|
||||
:rules="state.templateEditFormRules"
|
||||
>
|
||||
<el-form-item :label="state.dialogTitleLabel" prop="name">
|
||||
<el-input v-model="state.templateEditForm.name" />
|
||||
<el-input :placeholder="'请输入分类名称'" v-model="state.templateEditForm.name" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
@ -100,28 +113,77 @@
|
||||
:title="state.templateDialog.title"
|
||||
v-model="state.templateDialog.visible"
|
||||
:show-close="true"
|
||||
:destroy-on-close="true"
|
||||
class="de-dialog-form"
|
||||
width="600px"
|
||||
>
|
||||
<de-template-import
|
||||
v-if="state.templateDialog.visible"
|
||||
:pid="state.templateDialog.pid"
|
||||
:template-id="state.templateDialog.templateId"
|
||||
:opt-type="state.templateDialog.optType"
|
||||
:template-categories="state.templateCategories"
|
||||
@addCategoryInfo="showTemplateEditDialog('new', null)"
|
||||
@refresh="showCurrentTemplate(state.currentTemplateId, state.currentTemplateLabel)"
|
||||
@closeEditTemplateDialog="closeEditTemplateDialog"
|
||||
/>
|
||||
</el-dialog>
|
||||
|
||||
<!--导入templateDialog-->
|
||||
<el-dialog
|
||||
:title="state.templateDialog.title"
|
||||
v-model="state.templateDialog.visible"
|
||||
:show-close="true"
|
||||
:destroy-on-close="true"
|
||||
class="de-dialog-form"
|
||||
width="600px"
|
||||
>
|
||||
<de-template-import
|
||||
v-if="state.templateDialog.visible"
|
||||
:pid="state.templateDialog.pid"
|
||||
:template-id="state.templateDialog.templateId"
|
||||
:opt-type="state.templateDialog.optType"
|
||||
:template-categories="state.templateCategories"
|
||||
@refresh="showCurrentTemplate(state.currentTemplateId, state.currentTemplateLabel)"
|
||||
@closeEditTemplateDialog="closeEditTemplateDialog"
|
||||
/>
|
||||
</el-dialog>
|
||||
|
||||
<!--导入templateDialog-->
|
||||
<el-dialog
|
||||
:title="'修改分类'"
|
||||
v-model="state.batchOptDialogShow"
|
||||
:show-close="true"
|
||||
:destroy-on-close="true"
|
||||
class="de-dialog-form"
|
||||
width="600px"
|
||||
>
|
||||
<de-category-change
|
||||
v-if="state.batchOptDialogShow"
|
||||
:template-ids="batchTemplateIds"
|
||||
:template-categories="state.templateCategories"
|
||||
@refresh="showCurrentTemplate(state.currentTemplateId, state.currentTemplateLabel)"
|
||||
@closeBatchEditTemplateDialog="closeBatchOptDialog"
|
||||
></de-category-change>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { save, templateDelete, find, findCategories, deleteCategory } from '@/api/template'
|
||||
import {
|
||||
save,
|
||||
templateDelete,
|
||||
find,
|
||||
findCategories,
|
||||
deleteCategory,
|
||||
batchDelete
|
||||
} from '@/api/template'
|
||||
import elementResizeDetectorMaker from 'element-resize-detector'
|
||||
import { computed, nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus-secondary'
|
||||
import DeTemplateList from '@/views/template/component/DeTemplateList.vue'
|
||||
const { t } = useI18n()
|
||||
const templateEditFormRef = ref(null)
|
||||
@ -129,6 +191,7 @@ const templateListRef = ref(null)
|
||||
import NoneImage from '@/assets/none.png'
|
||||
import DeTemplateImport from '@/views/template/component/DeTemplateImport.vue'
|
||||
import DeTemplateItem from '@/views/template/component/DeTemplateItem.vue'
|
||||
import DeCategoryChange from '@/views/template/component/DeCategoryChange.vue'
|
||||
|
||||
const roleValidator = (rule, value, callback) => {
|
||||
if (nameRepeat(value)) {
|
||||
@ -148,6 +211,8 @@ const roleValidator = (rule, value, callback) => {
|
||||
}
|
||||
|
||||
const state = reactive({
|
||||
batchOptDialogShow: false,
|
||||
batchOptList: [],
|
||||
templateFilterText: '',
|
||||
showShare: false,
|
||||
currentTemplateShowList: [],
|
||||
@ -183,11 +248,54 @@ const state = reactive({
|
||||
templateDialog: {
|
||||
title: t('visualization.import_template'),
|
||||
visible: false,
|
||||
templateId: null,
|
||||
optType: 'insert',
|
||||
pid: '',
|
||||
categories: []
|
||||
}
|
||||
})
|
||||
|
||||
const batchUpdate = () => {
|
||||
state.batchOptDialogShow = true
|
||||
}
|
||||
|
||||
const batchPreDelete = () => {
|
||||
ElMessageBox.confirm(`确定删除${batchState.value}个模板吗?`, {
|
||||
confirmButtonType: 'danger',
|
||||
type: 'warning',
|
||||
autofocus: false,
|
||||
showClose: false
|
||||
}).then(() => {
|
||||
const params = {
|
||||
templateIds: batchTemplateIds.value,
|
||||
categories: [state.currentTemplateId]
|
||||
}
|
||||
batchDelete(params).then(rsp => {
|
||||
showCurrentTemplate(state.currentTemplateId, state.currentTemplateLabel)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const batchFullSelect = () => {
|
||||
currentTemplateShowListComputed.value.forEach(item => {
|
||||
item.checked = true
|
||||
})
|
||||
}
|
||||
|
||||
const batchClear = () => {
|
||||
currentTemplateShowListComputed.value.forEach(item => {
|
||||
item.checked = false
|
||||
})
|
||||
}
|
||||
|
||||
const batchState = computed(() => {
|
||||
return currentTemplateShowListComputed.value.filter(ele => ele.checked).length
|
||||
})
|
||||
|
||||
const batchTemplateIds = computed(() => {
|
||||
return currentTemplateShowListComputed.value.filter(ele => ele.checked).map(item => item.id)
|
||||
})
|
||||
|
||||
const currentTemplateShowListComputed = computed(() => {
|
||||
if (!state.templateFilterText) return [...state.currentTemplateShowList]
|
||||
return state.currentTemplateShowList.filter(ele =>
|
||||
@ -220,7 +328,7 @@ const nameRepeat = value => {
|
||||
|
||||
const handleCommand = (key, data) => {
|
||||
switch (key) {
|
||||
case 'rename':
|
||||
case 'templateEdit':
|
||||
templateEdit(data)
|
||||
break
|
||||
case 'delete':
|
||||
@ -256,24 +364,44 @@ const showCurrentTemplate = (pid, label) => {
|
||||
const categoryDelete = id => {
|
||||
if (id) {
|
||||
deleteCategory(id).then(response => {
|
||||
ElMessage({
|
||||
message: t('commons.delete_success'),
|
||||
type: 'success',
|
||||
showClose: true
|
||||
})
|
||||
getTree()
|
||||
if (response.data === 'success') {
|
||||
ElMessage({
|
||||
message: t('commons.delete_success'),
|
||||
type: 'success',
|
||||
showClose: true
|
||||
})
|
||||
getTree()
|
||||
} else {
|
||||
ElMessageBox.confirm('无法删除分类?', {
|
||||
tip: '请移除该分类下所有模版再进行删除分类操作',
|
||||
confirmButtonText: '知道了',
|
||||
confirmButtonType: 'default',
|
||||
showCancelButton: false,
|
||||
type: 'warning',
|
||||
autofocus: false,
|
||||
showClose: false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
const templateDeleteInfo = id => {
|
||||
if (id) {
|
||||
templateDelete(id).then(response => {
|
||||
ElMessage({
|
||||
message: t('commons.delete_success'),
|
||||
type: 'success',
|
||||
showClose: true
|
||||
ElMessageBox.confirm('确定删除该模版吗?', {
|
||||
tip: '',
|
||||
confirmButtonType: 'danger',
|
||||
type: 'warning',
|
||||
autofocus: false,
|
||||
showClose: false
|
||||
}).then(() => {
|
||||
templateDelete(id, state.currentTemplateId).then(response => {
|
||||
ElMessage({
|
||||
message: t('commons.delete_success'),
|
||||
type: 'success',
|
||||
showClose: true
|
||||
})
|
||||
showCurrentTemplate(state.currentTemplateId, state.currentTemplateLabel)
|
||||
})
|
||||
showCurrentTemplate(state.currentTemplateId, state.currentTemplateLabel)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -283,7 +411,7 @@ const showTemplateEditDialog = (type, templateInfo) => {
|
||||
state.formType = type
|
||||
if (type === 'edit') {
|
||||
state.templateEditForm = JSON.parse(JSON.stringify(templateInfo))
|
||||
state.dialogTitle = state.templateEditForm['nodeType'] === 'folder' ? '编辑分类' : '编辑模板'
|
||||
state.dialogTitle = state.templateEditForm['nodeType'] === 'folder' ? '重命名' : '编辑模板'
|
||||
state.originName = state.templateEditForm['label']
|
||||
} else {
|
||||
state.dialogTitle = t('visualization.add_category')
|
||||
@ -299,7 +427,10 @@ const showTemplateEditDialog = (type, templateInfo) => {
|
||||
}
|
||||
|
||||
const templateEdit = templateInfo => {
|
||||
showTemplateEditDialog('edit', templateInfo)
|
||||
state.templateDialog.visible = true
|
||||
state.templateDialog.title = '编辑模版'
|
||||
state.templateDialog.optType = 'update'
|
||||
state.templateDialog.templateId = templateInfo.id
|
||||
}
|
||||
|
||||
const categoryClick = params => {
|
||||
@ -356,12 +487,18 @@ const showFirst = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const closeBatchOptDialog = () => {
|
||||
state.batchOptDialogShow = false
|
||||
}
|
||||
|
||||
const closeEditTemplateDialog = () => {
|
||||
state.templateDialog.visible = false
|
||||
}
|
||||
|
||||
const templateImport = pid => {
|
||||
state.templateDialog.visible = true
|
||||
state.templateDialog.templateId = null
|
||||
state.templateDialog.optType = 'insert'
|
||||
state.templateDialog.pid = pid
|
||||
}
|
||||
|
||||
@ -404,7 +541,7 @@ onMounted(() => {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
background: rgba(239, 240, 241, 1);
|
||||
|
||||
position: relative;
|
||||
.template-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@ -430,6 +567,15 @@ onMounted(() => {
|
||||
background: #fff;
|
||||
border-bottom: 1px solid rgba(31, 35, 41, 0.15);
|
||||
}
|
||||
.batch-opt-area {
|
||||
background-color: #ffffff;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 48px;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
de-xpack
2
de-xpack
@ -1 +1 @@
|
||||
Subproject commit dfef649cb7d7d2490891ba7acb0ecfb342673a7b
|
||||
Subproject commit 08ae0222ed43c0b19caab179e0ef5a96c4a69f94
|
||||
@ -4,7 +4,6 @@ target=$2
|
||||
|
||||
DE_BASE=/opt
|
||||
DE_RUNNING_BASE=${DE_BASE}/dataease2.0
|
||||
DE_PORT=8100
|
||||
need_init_apisix=false
|
||||
compose_files="-f docker-compose.yml"
|
||||
compose_cmd="docker-compose"
|
||||
|
||||
@ -185,9 +185,6 @@ if [[ -d images ]]; then
|
||||
docker load -i images/$i 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||
done
|
||||
else
|
||||
log "拉取镜像"
|
||||
cd ${DE_RUN_BASE} && docker-compose $compose_files pull 2>&1
|
||||
|
||||
DEVERSION=$(cat ${CURRENT_DIR}/dataease/templates/version)
|
||||
curl -sfL https://resource.fit2cloud.com/installation-log.sh | sh -s de ${INSTALL_TYPE} ${DEVERSION}
|
||||
cd -
|
||||
@ -244,5 +241,9 @@ log "启动服务"
|
||||
dectl start | tee -a ${CURRENT_DIR}/install.log
|
||||
dectl status 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||
|
||||
access_port=$DE_PORT
|
||||
if [[ $DE_INSTALL_MODE != "community" ]];then
|
||||
access_port=9080
|
||||
fi
|
||||
echo -e "======================= 安装完成 =======================\n" 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||
echo -e "系统登录信息如下:\n 用户名: admin\n 初始密码: DataEase@123456" 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||
echo -e "系统登录信息如下:\n 访问地址: http://服务器IP:$access_port\n 用户名: admin\n 初始密码: DataEase@123456" 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||
41
installer/uninstall.sh
Normal file
41
installer/uninstall.sh
Normal file
@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
DE_BASE=/opt
|
||||
|
||||
read -r -p "即将卸载 DataEase 服务,包括删除运行目录、数据及相关镜像,是否继续? [Y/n] " input
|
||||
|
||||
case $input in
|
||||
[yY][eE][sS]|[yY])
|
||||
echo "Yes"
|
||||
;;
|
||||
[nN][oO]|[nN])
|
||||
echo "No"
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
echo "无效输入..."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -f /usr/bin/dectl ]; then
|
||||
# 获取已安装的 DataEase 的运行目录
|
||||
DE_BASE=$(grep "^DE_BASE=" /usr/bin/dectl | cut -d'=' -f2)
|
||||
fi
|
||||
|
||||
echo "停止 DataEase 服务"
|
||||
dectl stop
|
||||
|
||||
# 清理 DataEase 相关镜像
|
||||
if test ! -z "$(docker images -f dangling=true -q)"; then
|
||||
echo "清理虚悬镜像"
|
||||
docker rmi $(docker images -f dangling=true -q)
|
||||
fi
|
||||
|
||||
if test -n "$(docker images | grep 'registry.cn-qingdao.aliyuncs.com/dataease')"; then
|
||||
echo "清理 DataEase 镜像"
|
||||
docker rmi $(docker images | grep "registry.cn-qingdao.aliyuncs.com/dataease" | awk -F' ' '{print $1":"$2}')
|
||||
fi
|
||||
|
||||
# 清理 DataEase 运行目录及命令行工具 dectl
|
||||
rm -rf ${DE_BASE}/dataease2.0 /usr/bin/dectl
|
||||
@ -3,6 +3,7 @@ package io.dataease.api.chart;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.dataease.api.chart.dto.ChartViewDTO;
|
||||
import io.dataease.api.chart.request.ChartExcelRequest;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@ -18,13 +19,15 @@ import java.util.List;
|
||||
@Tag(name = "视图管理:数据")
|
||||
@ApiSupport(order = 989)
|
||||
public interface ChartDataApi {
|
||||
@Operation(summary = "获取视图数据")
|
||||
@PostMapping("getData")
|
||||
ChartViewDTO getData(@RequestBody ChartViewDTO chartViewDTO) throws Exception;
|
||||
|
||||
@Operation(summary = "导出数据")
|
||||
@PostMapping("innerExportDetails")
|
||||
void innerExportDetails(@RequestBody ChartExcelRequest request, HttpServletResponse response) throws Exception;
|
||||
|
||||
|
||||
@Operation(summary = "获取字段值")
|
||||
@PostMapping("getFieldData/{fieldId}/{fieldType}")
|
||||
List<String> getFieldData(@RequestBody ChartViewDTO view, @PathVariable Long fieldId, @PathVariable String fieldType) throws Exception;
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package io.dataease.api.chart;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.dataease.api.chart.dto.ChartViewDTO;
|
||||
import io.dataease.api.chart.dto.ChartViewFieldDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@ -18,18 +19,23 @@ import java.util.Map;
|
||||
@Tag(name = "视图管理:查看")
|
||||
@ApiSupport(order = 988)
|
||||
public interface ChartViewApi {
|
||||
@Operation(summary = "查询视图详情并同时计算数据", hidden = true)
|
||||
@PostMapping("getChart/{id}")
|
||||
ChartViewDTO getData(@PathVariable Long id) throws Exception;
|
||||
|
||||
@Operation(summary = "获取视图字段")
|
||||
@PostMapping("listByDQ/{id}/{chartId}")
|
||||
Map<String, List<ChartViewFieldDTO>> listByDQ(@PathVariable Long id, @PathVariable Long chartId);
|
||||
|
||||
@Operation(summary = "保存视图")
|
||||
@PostMapping("save")
|
||||
ChartViewDTO save(@RequestBody ChartViewDTO dto) throws Exception;
|
||||
|
||||
@Operation(summary = "检查是否同数据集")
|
||||
@GetMapping("/checkSameDataSet/{viewIdSource}/{viewIdTarget}")
|
||||
String checkSameDataSet(@PathVariable String viewIdSource, @PathVariable String viewIdTarget);
|
||||
|
||||
@Operation(summary = "查询视图详情")
|
||||
@PostMapping("getDetail/{id}")
|
||||
ChartViewDTO getDetail(@PathVariable Long id);
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import io.dataease.api.dataset.dto.DatasetTableDTO;
|
||||
import io.dataease.api.dataset.dto.PreviewSqlDTO;
|
||||
import io.dataease.api.dataset.union.DatasetGroupInfoDTO;
|
||||
import io.dataease.dto.dataset.DatasetTableFieldDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@ -18,21 +19,27 @@ import java.util.Map;
|
||||
@Tag(name = "数据集管理:数据")
|
||||
@ApiSupport(order = 978)
|
||||
public interface DatasetDataApi {
|
||||
@Operation(summary = "预览数据")
|
||||
@PostMapping("previewData")
|
||||
Map<String, Object> previewData(@RequestBody DatasetGroupInfoDTO datasetGroupInfoDTO) throws Exception;
|
||||
|
||||
@Operation(summary = "获取数据集节点字段")
|
||||
@PostMapping("tableField")
|
||||
List<DatasetTableFieldDTO> tableField(@RequestBody DatasetTableDTO datasetTableDTO) throws Exception;
|
||||
|
||||
@Operation(summary = "SQL预览")
|
||||
@PostMapping("previewSql")
|
||||
Map<String, Object> previewSql(@RequestBody PreviewSqlDTO dto) throws Exception;
|
||||
|
||||
@Operation(summary = "sql片段校验", hidden = true)
|
||||
@PostMapping("previewSqlCheck")
|
||||
Map<String, Object> previewSqlCheck(@RequestBody PreviewSqlDTO dto) throws Exception;
|
||||
|
||||
@Operation(summary = "获取字段枚举值")
|
||||
@PostMapping("enumValue")
|
||||
List<String> getFieldEnum(@RequestBody List<Long> ids) throws Exception;
|
||||
|
||||
@Operation(summary = "获取数据集总数据量", hidden = true)
|
||||
@PostMapping("getDatasetCount")
|
||||
Long getDatasetCount(@RequestBody DatasetGroupInfoDTO datasetGroupInfoDTO) throws Exception;
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.dataease.api.dataset.dto.MultFieldValuesRequest;
|
||||
import io.dataease.api.dataset.engine.SQLFunctionDTO;
|
||||
import io.dataease.dto.dataset.DatasetTableFieldDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@ -27,31 +28,39 @@ public interface DatasetTableApi {
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Operation(summary = "保存字段")
|
||||
@PostMapping("save")
|
||||
DatasetTableFieldDTO save(@RequestBody DatasetTableFieldDTO datasetTableFieldDTO) throws Exception;
|
||||
|
||||
@Operation(summary = "查询字段")
|
||||
@PostMapping("get/{id}")
|
||||
DatasetTableFieldDTO get(@PathVariable Long id);
|
||||
|
||||
@Operation(summary = "获取数据集字段")
|
||||
@PostMapping("listByDatasetGroup/{id}")
|
||||
List<DatasetTableFieldDTO> listByDatasetGroup(@PathVariable Long id);
|
||||
|
||||
@Operation(summary = "删除字段")
|
||||
@PostMapping("delete/{id}")
|
||||
void delete(@PathVariable Long id);
|
||||
|
||||
@Operation(summary = "获取字段分组")
|
||||
@PostMapping("listByDQ/{id}")
|
||||
Map<String, List<DatasetTableFieldDTO>> listByDQ(@PathVariable Long id);
|
||||
|
||||
@GetMapping ("listWithPermissions/{id}")
|
||||
@Operation(summary = "获取字段")
|
||||
@GetMapping("listWithPermissions/{id}")
|
||||
List<DatasetTableFieldDTO> listFieldsWithPermissions(@PathVariable Long id);
|
||||
|
||||
|
||||
@Operation(summary = "获取枚举值")
|
||||
@PostMapping("multFieldValuesForPermissions")
|
||||
List<String> multFieldValuesForPermissions(@RequestBody MultFieldValuesRequest multFieldValuesRequest) throws Exception;
|
||||
|
||||
@Operation(summary = "获取计算字段函数")
|
||||
@PostMapping("getFunction")
|
||||
List<SQLFunctionDTO> getFunction();
|
||||
|
||||
@Operation(summary = "删除视图计算字段", hidden = true)
|
||||
@PostMapping("deleteByChartId/{id}")
|
||||
void deleteByChartId(@PathVariable Long id);
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import io.dataease.auth.DeApiPath;
|
||||
import io.dataease.auth.DePermit;
|
||||
import io.dataease.model.BusiNodeRequest;
|
||||
import io.dataease.model.BusiNodeVO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@ -19,6 +20,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import java.util.List;
|
||||
|
||||
import static io.dataease.constant.AuthResourceEnum.DATASET;
|
||||
|
||||
@Tag(name = "数据集管理:树")
|
||||
@ApiSupport(order = 979)
|
||||
@DeApiPath(value = "/datasetTree", rt = DATASET)
|
||||
@ -31,10 +33,12 @@ public interface DatasetTreeApi {
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Operation(summary = "保存数据集", hidden = true)
|
||||
@DePermit({"#p0.id+':manage'"})
|
||||
@PostMapping("save")
|
||||
DatasetNodeDTO save(@RequestBody DatasetGroupInfoDTO dto) throws Exception;
|
||||
|
||||
@Operation(summary = "重命名数据集")
|
||||
@DePermit({"#p0.id+':manage'"})
|
||||
@PostMapping("rename")
|
||||
DatasetNodeDTO rename(@RequestBody DatasetGroupInfoDTO dto) throws Exception;
|
||||
@ -46,36 +50,46 @@ public interface DatasetTreeApi {
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Operation(summary = "创建数据集")
|
||||
@DePermit({"#p0.pid+':manage'"})
|
||||
@PostMapping("create")
|
||||
DatasetNodeDTO create(@RequestBody DatasetGroupInfoDTO dto) throws Exception;
|
||||
|
||||
@Operation(summary = "移动数据集")
|
||||
@DePermit({"#p0.id+':manage'", "#p0.pid+':manage'"})
|
||||
@PostMapping("move")
|
||||
DatasetNodeDTO move(@RequestBody DatasetGroupInfoDTO dto) throws Exception;
|
||||
|
||||
@Operation(summary = "删除数据集")
|
||||
@DePermit({"#p0+':manage'"})
|
||||
@PostMapping("delete/{id}")
|
||||
void delete(@PathVariable("id") Long id);
|
||||
|
||||
@Operation(summary = "查询文件夹以及数据集tree")
|
||||
@PostMapping("tree")
|
||||
List<BusiNodeVO> tree(@RequestBody BusiNodeRequest request);
|
||||
|
||||
@Operation(summary = "查询数据集对应用户信息")
|
||||
@GetMapping("/barInfo/{id}")
|
||||
DataSetBarVO barInfo(@PathVariable("id") Long id);
|
||||
|
||||
@Operation(summary = "查询数据集")
|
||||
@PostMapping("get/{id}")
|
||||
DatasetGroupInfoDTO get(@PathVariable("id") Long id) throws Exception;
|
||||
|
||||
@Operation(summary = "获取数据集详情")
|
||||
@PostMapping("details/{id}")
|
||||
DatasetGroupInfoDTO details(@PathVariable("id") Long id) throws Exception;
|
||||
|
||||
@Operation(summary = "获取数据集详情")
|
||||
@PostMapping("dsDetails")
|
||||
List<DatasetTableDTO> panelGetDsDetails(@RequestBody List<Long> ids) throws Exception;
|
||||
|
||||
@Operation(summary = "获取SQL参数")
|
||||
@PostMapping("getSqlParams")
|
||||
List<SqlVariableDetails> getSqlParams(@RequestBody List<Long> ids) throws Exception;
|
||||
|
||||
@Operation(summary = "带权限查询数据集详情")
|
||||
@PostMapping("detailWithPerm")
|
||||
List<DatasetTableDTO> detailWithPerm(@RequestBody List<Long> ids) throws Exception;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package io.dataease.api.template;
|
||||
|
||||
import io.dataease.api.template.dto.TemplateManageDTO;
|
||||
import io.dataease.api.template.request.TemplateManageBatchRequest;
|
||||
import io.dataease.api.template.request.TemplateManageRequest;
|
||||
import io.dataease.api.template.vo.VisualizationTemplateVO;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -14,11 +15,11 @@ public interface TemplateManageApi {
|
||||
@PostMapping("/save")
|
||||
TemplateManageDTO save(@RequestBody TemplateManageRequest request);
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
void delete(@PathVariable String id);
|
||||
@PostMapping("/delete/{id}/{categoryId}")
|
||||
void delete(@PathVariable String id,@PathVariable String categoryId);
|
||||
|
||||
@PostMapping("/deleteCategory/{id}")
|
||||
void deleteCategory(@PathVariable String id);
|
||||
String deleteCategory(@PathVariable String id);
|
||||
|
||||
@GetMapping("/findOne/{templateId}")
|
||||
VisualizationTemplateVO findOne(@PathVariable String templateId) throws Exception;
|
||||
@ -32,4 +33,13 @@ public interface TemplateManageApi {
|
||||
@PostMapping("/nameCheck")
|
||||
String nameCheck(@RequestBody TemplateManageRequest request);
|
||||
|
||||
@PostMapping("/categoryTemplateNameCheck")
|
||||
String categoryTemplateNameCheck(@RequestBody TemplateManageRequest request);
|
||||
|
||||
@PostMapping("/batchUpdate")
|
||||
void batchUpdate(@RequestBody TemplateManageBatchRequest request);
|
||||
|
||||
@PostMapping("/batchDelete")
|
||||
void batchDelete(@RequestBody TemplateManageBatchRequest request);
|
||||
|
||||
}
|
||||
|
||||
@ -18,6 +18,8 @@ public class TemplateManageDTO extends VisualizationTemplateVO {
|
||||
|
||||
private Long recentUseTime;
|
||||
|
||||
private Boolean checked = false;
|
||||
|
||||
private List<TemplateManageDTO> children;
|
||||
|
||||
private List<String> categories;
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
package io.dataease.api.template.request;
|
||||
|
||||
import io.dataease.api.template.vo.VisualizationTemplateVO;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author: wangjiahao
|
||||
* Description:
|
||||
*/
|
||||
@Data
|
||||
public class TemplateManageBatchRequest {
|
||||
|
||||
private String optType;
|
||||
|
||||
private List<String> templateIds;
|
||||
|
||||
private List<String> categories;
|
||||
|
||||
}
|
||||
@ -2,6 +2,8 @@ package io.dataease.api.template.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : WangJiaHao
|
||||
* @date : 2023/11/7 13:22
|
||||
@ -73,4 +75,9 @@ public class VisualizationTemplateVO {
|
||||
* 预存数据
|
||||
*/
|
||||
private String dynamicData;
|
||||
|
||||
/**
|
||||
* 分类
|
||||
*/
|
||||
private List<String> categories;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user