refactor: 冲突

This commit is contained in:
taojinlong 2022-05-22 10:16:23 +08:00
commit df17468447
139 changed files with 1751 additions and 1352 deletions

View File

@ -0,0 +1,34 @@
package io.dataease.auth.annotation;
import io.dataease.commons.constants.SysLogConstants.OPERATE_TYPE;
import io.dataease.commons.constants.SysLogConstants.SOURCE_TYPE;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface DeLog {
OPERATE_TYPE operatetype();
SOURCE_TYPE sourcetype();
int positionIndex() default -1;
String positionKey() default "";
int sourceIndex() default 0;
String sourceKey() default "";
int targetIndex() default -1;
String targetKey() default "";
SOURCE_TYPE targetType() default SOURCE_TYPE.USER;
String value() default "";
}

View File

@ -2,10 +2,10 @@ package io.dataease.auth.aop;
import io.dataease.auth.annotation.DeCleaner;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.auth.util.ReflectUtil;
import io.dataease.commons.constants.AuthConstants;
import io.dataease.commons.constants.DePermissionType;
import io.dataease.commons.model.AuthURD;
import io.dataease.commons.utils.AopUtils;
import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.LogUtil;
import io.dataease.listener.util.CacheUtils;
@ -19,11 +19,8 @@ import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Aspect
@ -43,7 +40,7 @@ public class DeCleanerAnnotationHandler {
if (ObjectUtils.isNotEmpty(key) && ArrayUtils.isNotEmpty(args)) {
int pi = deCleaner.paramIndex();
Object arg = point.getArgs()[pi];
paramValue = getParamValue(arg, key, 0);
paramValue = AopUtils.getParamValue(arg, key, 0);
}
switch (type.name()) {
@ -136,44 +133,5 @@ public class DeCleanerAnnotationHandler {
});
}
private Object getParamValue(Object arg, String key, int layer) throws Exception{
if (ObjectUtils.isNotEmpty(arg)) return null;
Class<?> parameterType = arg.getClass();
if (parameterType.isPrimitive() || ReflectUtil.isWrapClass(parameterType) || ReflectUtil.isString(parameterType)) {
return arg;
} else if (ReflectUtil.isArray(parameterType)) {
Object result;
for (int i = 0; i < Array.getLength(arg); i++) {
Object o = Array.get(arg, i);
if (ObjectUtils.isNotEmpty((result = getParamValue(o, key, layer)))) {
return result;
}
}
return null;
} else if (ReflectUtil.isCollection(parameterType)) {
Object[] array = ((Collection) arg).toArray();
Object result;
for (int i = 0; i < array.length; i++) {
Object o = array[i];
if (ObjectUtils.isNotEmpty((result = getParamValue(o, key, layer)))) {
return result;
}
}
return null;
} else if (ReflectUtil.isMap(parameterType)) {
Map<String, Object> argMap = (Map) arg;
String[] values = key.split("\\.");
Object o = argMap.get(values[layer]);
return getParamValue(o, key, ++layer);
} else {
// 当作自定义类处理
String[] values = key.split("\\.");
String fieldName = values[layer];
Object fieldValue = ReflectUtil.getFieldValue(arg, values[layer]);
return getParamValue(fieldValue, key, ++layer);
}
}
}

View File

@ -0,0 +1,143 @@
package io.dataease.auth.aop;
import io.dataease.auth.annotation.DeLog;
import io.dataease.commons.constants.SysLogConstants;
import io.dataease.commons.utils.AopUtils;
import io.dataease.controller.ResultHolder;
import io.dataease.dto.SysLogDTO;
import io.dataease.dto.log.FolderItem;
import io.dataease.service.sys.log.LogManager;
import io.dataease.service.sys.log.LogService;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Aspect
@Component
public class DeLogAnnotationHandler {
@Resource
private LogManager logManager;
@Resource
private LogService logService;
private static List<Integer> befores = new ArrayList<>();
@PostConstruct
public void init() {
befores.add(SysLogConstants.OPERATE_TYPE.DELETE.getValue());
befores.add(SysLogConstants.OPERATE_TYPE.UNSHARE.getValue());
befores.add(SysLogConstants.OPERATE_TYPE.UNAUTHORIZE.getValue());
}
private SysLogDTO exec(JoinPoint point, DeLog deLog) throws Exception{
Object[] args = point.getArgs();
if (ArrayUtils.isEmpty(args)) return null;
SysLogConstants.OPERATE_TYPE operatetype = deLog.operatetype();
SysLogConstants.SOURCE_TYPE sourcetype = deLog.sourcetype();
String sourceKey = StringUtils.isNotBlank(deLog.sourceKey()) ? deLog.sourceKey() : deLog.value();
int sourceIndex = deLog.sourceIndex();
if (args.length <= sourceIndex) return null;
Object arg = args[sourceIndex];
Object sourceIdValue = AopUtils.getParamValue(arg, sourceKey, 0);
if (ObjectUtils.isEmpty(sourceIdValue)) return null;
SysLogDTO sysLogDTO = new SysLogDTO();
sysLogDTO.setOperateType(operatetype.getValue());
sysLogDTO.setSourceType(sourcetype.getValue());
sysLogDTO.setSourceId(sourceIdValue.toString());
FolderItem sourceInfo = logManager.nameWithId(sourceIdValue.toString(), sourcetype.getValue());
if (ObjectUtils.isEmpty(sourceInfo)) {
return null;
}
sysLogDTO.setSourceName(sourceInfo.getName());
// 填充资源位置信息
int positionIndex = deLog.positionIndex();
if (positionIndex > -1 && args.length > positionIndex){
String positionKey = deLog.positionKey();
Object positionArg = args[positionIndex];
Object bottomPositionValue = AopUtils.getParamValue(positionArg, positionKey, 0);
if (ObjectUtils.isNotEmpty(bottomPositionValue)) {
if (sourcetype == SysLogConstants.SOURCE_TYPE.DATASOURCE) {
FolderItem folderItem = logManager.dsTypeInfo(bottomPositionValue.toString());
List<FolderItem> items = new ArrayList<>();
items.add(folderItem);
sysLogDTO.setPositions(items);
}else {
List<FolderItem> parentsAndSelf = parents(bottomPositionValue.toString(), sourcetype);
sysLogDTO.setPositions(parentsAndSelf);
}
}
}
// 填充资源目标位置信息
int targetIndex = deLog.targetIndex();
if (targetIndex > -1 && args.length > targetIndex){
String targetKey = deLog.targetKey();
Object targetArg = args[targetIndex];
SysLogConstants.SOURCE_TYPE targetType = deLog.targetType();
Object bottomTargetValue = AopUtils.getParamValue(targetArg, targetKey, 0);
if (ObjectUtils.isNotEmpty(bottomTargetValue)) {
List<FolderItem> parentsAndSelf = parents(bottomTargetValue.toString(), targetType);
sysLogDTO.setRemarks(parentsAndSelf);
}
}
return sysLogDTO;
}
@Around(value = "@annotation(io.dataease.auth.annotation.DeLog)")
public Object logAround(ProceedingJoinPoint point) throws Throwable {
SysLogDTO logDTO = null;
Object result = null;
DeLog log = getLog(point);
if(befores.contains(log.operatetype().getValue())) {
// 前置处理 比如删除操作 需要在数据删除之前查询
logDTO = exec(point, log);
result = point.proceed(point.getArgs());
}else {
// 后置处理 比如保存操作 需要在保存之后才有主键
result = point.proceed(point.getArgs());
logDTO = exec(point, log);
}
if (ObjectUtils.isNotEmpty(result) && result instanceof ResultHolder && !((ResultHolder) result).isSuccess()) {
return result;
}
Optional.ofNullable(logDTO).ifPresent(logService::saveLog);
return result;
}
private DeLog getLog(JoinPoint point) {
MethodSignature ms = (MethodSignature) point.getSignature();
Method method = ms.getMethod();
DeLog deLog = method.getAnnotation(DeLog.class);
return deLog;
}
public List<FolderItem> parents(String value, SysLogConstants.SOURCE_TYPE type) {
return logManager.parentsAndSelf(value, type);
}
}

View File

@ -0,0 +1,72 @@
package io.dataease.commons.constants;
import java.util.Arrays;
import java.util.Optional;
public class SysLogConstants {
public static String operateTypeName(Integer value) {
Optional<OPERATE_TYPE> any = Arrays.stream(OPERATE_TYPE.class.getEnumConstants()).filter(e -> e.value == value).findAny();
if (any.isPresent()) return any.get().name;
return null;
}
public enum OPERATE_TYPE {
CREATE(1, "OPERATE_TYPE_CREATE"),
MODIFY(2, "OPERATE_TYPE_MODIFY"),
DELETE(3, "OPERATE_TYPE_DELETE"),
SHARE(4, "OPERATE_TYPE_SHARE"),
UNSHARE(5, "OPERATE_TYPE_UNSHARE"),
AUTHORIZE(6, "OPERATE_TYPE_AUTHORIZE"),
UNAUTHORIZE(7, "OPERATE_TYPE_UNAUTHORIZE"),
CREATELINK(8, "OPERATE_TYPE_CREATELINK"),
DELETELINK(9, "OPERATE_TYPE_DELETELINK"),
MODIFYLINK(10, "OPERATE_TYPE_MODIFYLINK");
private Integer value;
private String name;
OPERATE_TYPE(Integer value, String name) {
this.value = value;
this.name = name;
}
public Integer getValue() {
return value;
}
public String getName() {
return name;
}
}
public static String sourceTypeName(Integer value) {
Optional<SOURCE_TYPE> any = Arrays.stream(SOURCE_TYPE.class.getEnumConstants()).filter(e -> e.value == value).findAny();
if (any.isPresent()) return any.get().name;
return null;
}
public enum SOURCE_TYPE {
DATASOURCE(1, "SOURCE_TYPE_DATASOURCE"),
DATASET(2, "SOURCE_TYPE_DATASET"),
PANEL(3, "SOURCE_TYPE_PANEL"),
VIEW(4, "SOURCE_TYPE_VIEW"),
/*LINK(5, "SOURCE_TYPE_LINK"),*/
USER(6, "SOURCE_TYPE_USER"),
DEPT(7, "SOURCE_TYPE_DEPT"),
ROLE(8, "SOURCE_TYPE_ROLE");
private Integer value;
private String name;
SOURCE_TYPE(Integer value, String name) {
this.value = value;
this.name = name;
}
public Integer getValue() {
return value;
}
public String getName() {
return name;
}
}
}

View File

@ -0,0 +1,52 @@
package io.dataease.commons.utils;
import io.dataease.auth.util.ReflectUtil;
import org.apache.commons.lang3.ObjectUtils;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Map;
public class AopUtils {
public static Object getParamValue(Object arg, String key, int layer) throws Exception{
if (ObjectUtils.isEmpty(arg)) return null;
Class<?> parameterType = arg.getClass();
if (parameterType.isPrimitive() || ReflectUtil.isWrapClass(parameterType) || ReflectUtil.isString(parameterType)) {
return arg;
} else if (ReflectUtil.isArray(parameterType)) {
Object result;
for (int i = 0; i < Array.getLength(arg); i++) {
Object o = Array.get(arg, i);
if (ObjectUtils.isNotEmpty((result = getParamValue(o, key, layer)))) {
return result;
}
}
return null;
} else if (ReflectUtil.isCollection(parameterType)) {
Object[] array = ((Collection) arg).toArray();
Object result;
for (int i = 0; i < array.length; i++) {
Object o = array[i];
if (ObjectUtils.isNotEmpty((result = getParamValue(o, key, layer)))) {
return result;
}
}
return null;
} else if (ReflectUtil.isMap(parameterType)) {
Map<String, Object> argMap = (Map) arg;
String[] values = key.split("\\.");
Object o = argMap.get(values[layer]);
return getParamValue(o, key, ++layer);
} else {
// 当作自定义类处理
String[] values = key.split("\\.");
String fieldName = values[layer];
Object fieldValue = ReflectUtil.getFieldValue(arg, values[layer]);
return getParamValue(fieldValue, key, ++layer);
}
}
}

View File

@ -1,7 +1,10 @@
package io.dataease.controller.datasource;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.auth.annotation.DeLog;
import io.dataease.auth.annotation.DePermission;
import io.dataease.commons.constants.SysLogConstants;
import io.dataease.controller.datasource.request.DeleteDsRequest;
import io.dataease.plugins.common.base.domain.Datasource;
import io.dataease.commons.constants.DePermissionType;
import io.dataease.commons.constants.ResourceAuthLevel;
@ -39,6 +42,12 @@ public class DatasourceController {
@DePermission(type = DePermissionType.DATASOURCE, value = "id")
@ApiOperation("新增数据源")
@PostMapping("/add")
@DeLog(
operatetype = SysLogConstants.OPERATE_TYPE.CREATE,
sourcetype = SysLogConstants.SOURCE_TYPE.DATASOURCE,
positionIndex = 0,positionKey = "type",
value = "id"
)
public Datasource addDatasource(@RequestBody Datasource datasource) throws Exception{
return datasourceService.addDatasource(datasource);
}
@ -81,15 +90,27 @@ public class DatasourceController {
@RequiresPermissions("datasource:read")
@DePermission(type = DePermissionType.DATASOURCE, level = ResourceAuthLevel.DATASOURCE_LEVEL_MANAGE)
@ApiOperation("删除数据源")
@PostMapping("/delete/{datasourceID}")
public ResultHolder deleteDatasource(@PathVariable(value = "datasourceID") String datasourceID) throws Exception {
return datasourceService.deleteDatasource(datasourceID);
@PostMapping("/delete")
@DeLog(
operatetype = SysLogConstants.OPERATE_TYPE.DELETE,
sourcetype = SysLogConstants.SOURCE_TYPE.DATASOURCE,
positionIndex = 0,positionKey = "type",
value = "id"
)
public ResultHolder deleteDatasource(@RequestBody DeleteDsRequest request) throws Exception {
return datasourceService.deleteDatasource(request.getId());
}
@RequiresPermissions("datasource:read")
@DePermission(type = DePermissionType.DATASOURCE, value = "id", level = ResourceAuthLevel.DATASOURCE_LEVEL_MANAGE)
@ApiOperation("更新数据源")
@PostMapping("/update")
@DeLog(
operatetype = SysLogConstants.OPERATE_TYPE.MODIFY,
sourcetype = SysLogConstants.SOURCE_TYPE.DATASOURCE,
positionIndex = 0,positionKey = "type",
value = "id"
)
public void updateDatasource(@RequestBody UpdataDsRequest dsRequest) throws Exception{
datasourceService.updateDatasource(dsRequest);
}

View File

@ -35,9 +35,9 @@ public class DriverMgmController {
@RequiresPermissions("datasource:read")
@ApiOperation("删除驱动")
@PostMapping("/delete/{id}")
public void delete(@PathVariable String id) throws Exception{
driverService.delete(id);
@PostMapping("/delete")
public void delete(@RequestBody DeDriver deDriver) throws Exception{
driverService.delete(deDriver.getId());
}
@RequiresPermissions("datasource:read")

View File

@ -0,0 +1,16 @@
package io.dataease.controller.datasource.request;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
public class DeleteDsRequest implements Serializable {
@ApiModelProperty(value = "ID",required = true)
private String id;
@ApiModelProperty(value = "类型", required = true)
private String type;
}

View File

@ -0,0 +1,57 @@
package io.dataease.controller.sys;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.commons.utils.PageUtils;
import io.dataease.commons.utils.Pager;
import io.dataease.controller.handler.annotation.I18n;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.dto.SysLogGridDTO;
import io.dataease.dto.log.FolderItem;
import io.dataease.service.sys.log.LogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
@RestController
@Api(tags = "系统:日志管理")
@ApiSupport(order = 220)
@RequestMapping("/api/log")
public class SysLogController {
@Resource
private LogService logService;
@I18n
@ApiOperation("查询日志")
@PostMapping("/logGrid/{goPage}/{pageSize}")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "path", name = "goPage", value = "页码", required = true, dataType = "Integer"),
@ApiImplicitParam(paramType = "path", name = "pageSize", value = "页容量", required = true, dataType = "Integer"),
@ApiImplicitParam(name = "request", value = "查询条件", required = true)
})
public Pager<List<SysLogGridDTO>> logGrid(@PathVariable int goPage, @PathVariable int pageSize,
@RequestBody BaseGridRequest request) {
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
return PageUtils.setPageInfo(page, logService.query(request));
}
@ApiOperation("操作类型")
@PostMapping("/opTypes")
public List<FolderItem> types() {
return logService.types();
}
@ApiOperation("导出操作日志")
@PostMapping("/export")
public void export(HttpServletResponse response) throws Exception{
logService.exportExcel(response);
}
}

View File

@ -3,7 +3,9 @@ package io.dataease.controller.sys;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.auth.annotation.DeLog;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.commons.constants.SysLogConstants;
import io.dataease.exception.DataEaseException;
import io.dataease.i18n.Translator;
import io.dataease.plugins.common.base.domain.SysRole;
@ -69,6 +71,11 @@ public class SysUserController {
@ApiOperation("创建用户")
@RequiresPermissions("user:add")
@PostMapping("/create")
@DeLog(
operatetype = SysLogConstants.OPERATE_TYPE.CREATE,
sourcetype = SysLogConstants.SOURCE_TYPE.USER,
value = "userId"
)
public void create(@RequestBody SysUserCreateRequest request) {
sysUserService.save(request);
}
@ -76,6 +83,11 @@ public class SysUserController {
@ApiOperation("更新用户")
@RequiresPermissions("user:edit")
@PostMapping("/update")
@DeLog(
operatetype = SysLogConstants.OPERATE_TYPE.MODIFY,
sourcetype = SysLogConstants.SOURCE_TYPE.USER,
value = "userId"
)
public void update(@RequestBody SysUserCreateRequest request) {
sysUserService.update(request);
}
@ -84,6 +96,10 @@ public class SysUserController {
@RequiresPermissions("user:del")
@PostMapping("/delete/{userId}")
@ApiImplicitParam(paramType = "path", value = "用户ID", name = "userId", required = true, dataType = "Integer")
@DeLog(
operatetype = SysLogConstants.OPERATE_TYPE.DELETE,
sourcetype = SysLogConstants.SOURCE_TYPE.USER
)
public void delete(@PathVariable("userId") Long userId) {
sysUserService.delete(userId);
}
@ -92,6 +108,11 @@ public class SysUserController {
@RequiresPermissions("user:edit")
@RequiresRoles("1")
@PostMapping("/updateStatus")
@DeLog(
operatetype = SysLogConstants.OPERATE_TYPE.MODIFY,
sourcetype = SysLogConstants.SOURCE_TYPE.USER,
value = "userId"
)
public void updateStatus(@RequestBody SysUserStateRequest request) {
sysUserService.updateStatus(request);
}

View File

@ -0,0 +1,24 @@
package io.dataease.dto;
import io.dataease.dto.log.FolderItem;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class SysLogDTO implements Serializable {
private Integer sourceType;
private String sourceId;
private String sourceName;
private Integer operateType;
private List<FolderItem> positions;
private List<FolderItem> remarks;
}

View File

@ -0,0 +1,25 @@
package io.dataease.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
public class SysLogGridDTO implements Serializable {
@ApiModelProperty("操作类型")
private String opType;
@ApiModelProperty("资源类型")
private String sourceType;
@ApiModelProperty("详细信息")
private String detail;
@ApiModelProperty("操作人")
private String user;
@ApiModelProperty("操作时间")
private Long time;
}

View File

@ -0,0 +1,16 @@
package io.dataease.dto.log;
import lombok.Data;
import java.io.Serializable;
@Data
public class FolderItem implements Serializable {
private String id;
private String name;
private Integer type;
}

View File

@ -27,4 +27,7 @@ public class PanelShareOutDTO implements Serializable {
@ApiModelProperty("分享时间")
private Long createTime;
@ApiModelProperty("仪表板状态")
private String status;
}

View File

@ -16,5 +16,7 @@ public class PanelSharePo {
private String creator;
@ApiModelProperty("分享人ID")
private Long userId;
@ApiModelProperty("仪表板状态")
private String status;
}

View File

@ -13,5 +13,7 @@ public class PanelStoreDto {
private String name;
@ApiModelProperty("仪表板Id")
private String panelGroupId;
@ApiModelProperty("仪表板状态")
private String status;
}

View File

@ -91,9 +91,9 @@
<if test="level != null">
and panel_group.level = #{level}
</if>
<if test="isAdmin != null and !isAdmin">
and (panel_group.node_type='folder' or (panel_group.node_type='panel' and panel_group.`status`='publish') or (panel_group.node_type='panel' and panel_group.`status`='unpublished' and authInfo.privileges like '%manage%') )
</if>
<!-- <if test="isAdmin != null and !isAdmin">-->
<!-- and (panel_group.node_type='folder' or (panel_group.node_type='panel' and panel_group.`status`='publish') or (panel_group.node_type='panel' and panel_group.`status`='unpublished' and authInfo.privileges like '%manage%') )-->
<!-- </if>-->
</where>
ORDER BY CONVERT(panel_group.name using gbk)
</select>
@ -170,9 +170,9 @@
<if test="level != null">
and panel_group.level = #{level}
</if>
<if test="isAdmin != null and !isAdmin">
and (panel_group.node_type='folder' or (panel_group.node_type='panel' and panel_group.`status`='publish') or (panel_group.node_type='panel' and panel_group.`status`='unpublished' and authInfo.privileges like '%manage%') )
</if>
<!-- <if test="isAdmin != null and !isAdmin">-->
<!-- and (panel_group.node_type='folder' or (panel_group.node_type='panel' and panel_group.`status`='publish') or (panel_group.node_type='panel' and panel_group.`status`='unpublished' and authInfo.privileges like '%manage%') )-->
<!-- </if>-->
</where>
ORDER BY panel_group.node_type desc, CONVERT(panel_group.name using gbk)
</select>

View File

@ -5,6 +5,7 @@
<resultMap id="treeNodeMap" type="io.dataease.dto.panel.PanelSharePo">
<id column="id" property="id" />
<result column="name" property="name" />
<result column="status" property="status" />
<result column="creator" property="creator" />
<result column="user_id" jdbcType="BIGINT" property="userId" />
</resultMap>
@ -20,7 +21,7 @@
<insert id="batchInsert" parameterType="io.dataease.plugins.common.base.domain.PanelShare">
INSERT INTO panel_share (panel_group_id,target_id,granter,create_time,type)
VALUES
VALUES
<foreach collection="shares" item="share" separator=",">
(#{share.panelGroupId}, #{share.targetId}, #{userName}, #{share.createTime}, #{share.type})
</foreach>
@ -35,7 +36,7 @@
</delete>
<select id="query" resultMap="treeNodeMap">
select distinct s.panel_group_id as id, u.nick_name as creator, g.name, u.user_id
select distinct s.panel_group_id as id, u.nick_name as creator, g.name, u.user_id, g.status
from panel_share s
left join panel_group g on g.id = s.panel_group_id
left join sys_user u on u.username = IFNULL(s.granter,g.create_by)
@ -54,7 +55,7 @@
</select>
<select id="queryOut" resultMap="treeNodeMap">
select distinct s.panel_group_id as id, g.name
select distinct s.panel_group_id as id, g.name, g.status
from panel_share s
left join panel_group g on g.id = s.panel_group_id
where ( s.granter is not null and s.granter = #{userName} ) or ( s.granter is null and g.create_by = #{userName} )
@ -63,10 +64,10 @@
</select>
<select id="queryWithResource" parameterType="io.dataease.controller.request.panel.PanelShareSearchRequest" resultMap="io.dataease.plugins.common.base.mapper.PanelShareMapper.BaseResultMap">
select s.*
select s.*
from panel_share s
left join panel_group g on g.id = s.panel_group_id
where
where
s.panel_group_id = #{resourceId}
<if test="type != null">
and s.type = #{type}

View File

@ -6,13 +6,14 @@
<id column="store_id" property="storeId"></id>
<result column="panel_group_id" property="panelGroupId"></result>
<result column="name" property="name"></result>
<result column="status" property="status"></result>
</resultMap>
<select id="query" parameterType="io.dataease.ext.query.GridExample" resultMap="panelStoreMap">
select s.store_id,s.panel_group_id, g.name
select s.store_id,s.panel_group_id, g.name ,g.status
from panel_store s
inner join panel_group g on g.id = s.panel_group_id
<if test="_parameter != null">

View File

@ -0,0 +1,15 @@
package io.dataease.ext;
import io.dataease.dto.log.FolderItem;
import io.dataease.ext.query.GridExample;
import io.dataease.plugins.common.base.domain.SysLogWithBLOBs;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ExtSysLogMapper {
List<SysLogWithBLOBs> query(GridExample example);
List<FolderItem> idAndName(@Param("ids") List<String> ids, @Param("type") Integer type);
}

View File

@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="io.dataease.ext.ExtSysLogMapper">
<select id="query" parameterType="io.dataease.ext.query.GridExample" resultMap="io.dataease.plugins.common.base.mapper.SysLogMapper.ResultMapWithBLOBs">
select * from sys_log
<if test="_parameter != null">
<include refid="io.dataease.ext.query.GridSql.gridCondition" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
<if test="orderByClause == null">
order by time desc
</if>
</select>
<select id="idAndName" resultType="io.dataease.dto.log.FolderItem" >
select
<if test="type == 1">
id, name
from datasource
<where>
id in
<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</where>
</if>
<if test="type == 2">
id, name
from dataset_group
<where>
id in
<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</where>
</if>
<if test="type == 3">
id, name
from panel_group
<where>
id in
<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</where>
</if>
<if test="type == 4">
id, name
from chart_view
<where>
id in
<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</where>
</if>
<if test="type == 5">
id, name
from panel_group
<where>
id in
<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</where>
</if>
<if test="type == 6">
user_id as id, nick_name as name
from sys_user
<where>
user_id in
<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</where>
</if>
<if test="type == 7">
dept_id as id, name
from sys_dept
<where>
dept_id in
<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</where>
</if>
<if test="type == 8">
role_id as id, name
from sys_role
<where>
role_id in
<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</where>
</if>
</select>
</mapper>

View File

@ -1,7 +1,9 @@
package io.dataease.plugins.server;
import io.dataease.auth.annotation.DeLog;
import io.dataease.auth.service.ExtAuthService;
import io.dataease.commons.constants.SysLogConstants;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.controller.sys.response.DeptNodeResponse;
import io.dataease.plugins.common.entity.XpackGridRequest;
@ -70,6 +72,12 @@ public class XDeptServer {
@RequiresPermissions("dept:add")
@ApiOperation("创建")
@PostMapping("/create")
@DeLog(
operatetype = SysLogConstants.OPERATE_TYPE.CREATE,
sourcetype = SysLogConstants.SOURCE_TYPE.DEPT,
positionIndex = 0,positionKey = "pid",
value = "deptId"
)
public int create(@RequestBody XpackCreateDept dept){
DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class);
return deptService.add(dept);
@ -78,6 +86,12 @@ public class XDeptServer {
@RequiresPermissions("dept:del")
@ApiOperation("删除")
@PostMapping("/delete")
@DeLog(
operatetype = SysLogConstants.OPERATE_TYPE.DELETE,
sourcetype = SysLogConstants.SOURCE_TYPE.DEPT,
positionIndex = 0,positionKey = "pid",
value = "deptId"
)
public void delete(@RequestBody List<XpackDeleteDept> requests){
DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class);
requests.forEach(request -> {
@ -89,6 +103,12 @@ public class XDeptServer {
@RequiresPermissions("dept:edit")
@ApiOperation("更新")
@PostMapping("/update")
@DeLog(
operatetype = SysLogConstants.OPERATE_TYPE.MODIFY,
sourcetype = SysLogConstants.SOURCE_TYPE.DEPT,
positionIndex = 0,positionKey = "pid",
value = "deptId"
)
public int update(@RequestBody XpackCreateDept dept){
DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class);
return deptService.update(dept);

View File

@ -3,7 +3,9 @@ package io.dataease.plugins.server;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.dataease.auth.annotation.DeLog;
import io.dataease.auth.service.ExtAuthService;
import io.dataease.commons.constants.SysLogConstants;
import io.dataease.commons.utils.PageUtils;
import io.dataease.commons.utils.Pager;
import io.dataease.plugins.common.entity.XpackGridRequest;
@ -30,6 +32,11 @@ public class XRoleServer {
@RequiresPermissions("role:add")
@ApiOperation("新增角色")
@PostMapping("/create")
@DeLog(
operatetype = SysLogConstants.OPERATE_TYPE.CREATE,
sourcetype = SysLogConstants.SOURCE_TYPE.ROLE,
value = "roleId"
)
public void create(@RequestBody XpackRoleDto role){
RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class);
roleXpackService.save(role);
@ -39,6 +46,10 @@ public class XRoleServer {
@RequiresPermissions("role:del")
@ApiOperation("删除角色")
@PostMapping("/delete/{roleId}")
@DeLog(
operatetype = SysLogConstants.OPERATE_TYPE.DELETE,
sourcetype = SysLogConstants.SOURCE_TYPE.ROLE
)
public void delete(@PathVariable("roleId") Long roleId){
RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class);
extAuthService.clearDeptResource(roleId);
@ -49,6 +60,11 @@ public class XRoleServer {
@RequiresPermissions("role:edit")
@ApiOperation("更新角色")
@PostMapping("/update")
@DeLog(
operatetype = SysLogConstants.OPERATE_TYPE.MODIFY,
sourcetype = SysLogConstants.SOURCE_TYPE.ROLE,
value = "roleId"
)
public void update(@RequestBody XpackRoleDto role){
RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class);
roleXpackService.update(role);

View File

@ -124,7 +124,7 @@ public class PanelGroupService {
if (StringUtils.isEmpty(panelId)) { // 新建
checkPanelName(request.getName(), request.getPid(), PanelConstants.OPT_TYPE_INSERT, null, request.getNodeType());
panelId = newPanel(request);
panelGroupMapper.insert(request);
panelGroupMapper.insertSelective(request);
// 清理权限缓存
clearPermissionCache();
sysAuthService.copyAuth(panelId, SysAuthConstants.AUTH_SOURCE_TYPE_PANEL);

View File

@ -94,6 +94,7 @@ public class SysUserService {
}
int insert = sysUserMapper.insert(user);
SysUser dbUser = findOne(user);
request.setUserId(dbUser.getUserId());
saveUserRoles(dbUser.getUserId(), request.getRoleIds());//插入用户角色关联
return insert;
}

View File

@ -0,0 +1,133 @@
package io.dataease.service.sys.log;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.dataease.commons.constants.SysLogConstants;
import io.dataease.commons.utils.AuthUtils;
import io.dataease.dto.log.FolderItem;
import io.dataease.ext.ExtSysLogMapper;
import io.dataease.i18n.Translator;
import io.dataease.plugins.common.base.domain.SysLogWithBLOBs;
import io.dataease.plugins.common.dto.datasource.DataSourceType;
import io.dataease.service.datasource.DatasourceService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Component
public class LogManager {
protected static final String contentFormat = "【%s】";
protected static final String positionFormat = "在【%s】";
protected static final String format = "给%s【%s】";
protected Gson gson = new Gson();
protected Type type = new TypeToken<List<FolderItem>>() {}.getType();
@Resource
private ExtSysLogMapper extSysLogMapper;
@Resource
private DatasourceService datasourceService;
public String detailInfo(SysLogWithBLOBs vo) {
String sourceName = vo.getSourceName();
String postion = null;
String operateTypeName = SysLogConstants.operateTypeName(vo.getOperateType());
operateTypeName = Translator.get(operateTypeName);
String sourceTypeName = SysLogConstants.sourceTypeName(vo.getSourceType());
sourceTypeName = Translator.get(sourceTypeName);
String result = operateTypeName + sourceTypeName + String.format(contentFormat, sourceName) + remarkInfo(vo);
if ((postion = vo.getPosition()) != null) {
List<FolderItem> folderItems = gson.fromJson(postion, type);
String template = folderItems.stream().map(folderItem -> folderItem.getName()).collect(Collectors.joining("/"));
String postionResult = String.format(positionFormat, template);
return postionResult + result;
}
return result;
}
public String remarkInfo(SysLogWithBLOBs vo) {
String remakrk = null;
if ((remakrk = vo.getRemark()) != null) {
List<FolderItem> targetInfos = gson.fromJson(remakrk, type);
String target = targetInfos.stream().map(item -> {
Integer targetType = item.getType();
String targetTypeName = SysLogConstants.sourceTypeName(targetType);
return String.format(format, targetTypeName, item.getName());
}).collect(Collectors.joining("/"));
return target;
}
return "";
}
public List<FolderItem> parentsAndSelf(String id, SysLogConstants.SOURCE_TYPE type) {
Integer value = type.getValue();
String typeValue = "";
switch (value) {
case 2:
typeValue = "dataset";
break;
case 3:
typeValue = "panel";
break;
case 7:
typeValue = "dept";
break;
default:
break;
}
List<String> ids = new ArrayList<>();
if (StringUtils.isNotBlank(typeValue)) {
ids.addAll(AuthUtils.parentResources(id, typeValue));
}else {
ids.add(id);
}
List<FolderItem> folderItems = extSysLogMapper.idAndName(ids, value);
folderItems.forEach(item -> item.setType(value));
return folderItems;
}
public FolderItem nameWithId(String id, Integer type) {
List<String> ids = new ArrayList<>();
ids.add(id);
List<FolderItem> folderItems = extSysLogMapper.idAndName(ids, type);
if (CollectionUtils.isNotEmpty(folderItems)) {
return folderItems.get(0);
}
return null;
}
public FolderItem dsTypeInfo(String typeId) {
ArrayList<DataSourceType> dataSourceTypes = new ArrayList<>(datasourceService.types());
String name = null;
for (int i = 0; i < dataSourceTypes.size(); i++) {
if (dataSourceTypes.get(i).getType().equals(typeId)){
name = dataSourceTypes.get(i).getName();
break;
}
}
FolderItem folderItem = new FolderItem();
folderItem.setId(typeId);
folderItem.setName(StringUtils.isNotBlank(name) ? name : typeId);
return folderItem;
}
}

View File

@ -0,0 +1,148 @@
package io.dataease.service.sys.log;
import com.google.gson.Gson;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.commons.constants.SysLogConstants;
import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.base.ConditionEntity;
import io.dataease.dto.SysLogDTO;
import io.dataease.dto.SysLogGridDTO;
import io.dataease.dto.log.FolderItem;
import io.dataease.ext.ExtSysLogMapper;
import io.dataease.ext.query.GridExample;
import io.dataease.i18n.Translator;
import io.dataease.plugins.common.base.domain.SysLogWithBLOBs;
import io.dataease.plugins.common.base.mapper.SysLogMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class LogService {
private Gson gson = new Gson();
private static Integer[] unPanelOperates = {4, 5, 8, 9, 10};
@Resource
private SysLogMapper sysLogMapper;
@Resource
private ExtSysLogMapper extSysLogMapper;
@Resource
private LogManager logManager;
public List<SysLogGridDTO> query(BaseGridRequest request) {
List<ConditionEntity> conditions = request.getConditions();
if (CollectionUtils.isNotEmpty(conditions)) {
ConditionEntity optypeCondition = null;
ConditionEntity sourceCondition = null;
int matchIndex = -1;
for (int i = 0; i < conditions.size(); i++) {
ConditionEntity conditionEntity = conditions.get(i);
String field = conditionEntity.getField();
Object value = conditionEntity.getValue();
if (StringUtils.isNotBlank(field) && StringUtils.equals("optype", field) && ObjectUtils.isNotEmpty(value)) {
matchIndex = i;
optypeCondition = new ConditionEntity();
sourceCondition = new ConditionEntity();
List<String> values = (List<String>) value;
sourceCondition.setField("source_type");
optypeCondition.setField("operate_type");
List<Integer> opValue = values.stream().map(v -> Integer.parseInt(v.split("-")[0])).collect(Collectors.toList());
List<Integer> soValue = values.stream().map(v -> Integer.parseInt(v.split("-")[1])).collect(Collectors.toList());
optypeCondition.setValue(opValue);
sourceCondition.setValue(soValue);
optypeCondition.setOperator(conditionEntity.getOperator());
sourceCondition.setOperator(conditionEntity.getOperator());
}
}
if (matchIndex >= 0 ) {
conditions.remove(matchIndex);
if (ObjectUtils.isNotEmpty(optypeCondition))conditions.add(optypeCondition);
if (ObjectUtils.isNotEmpty(sourceCondition))conditions.add(sourceCondition);
}
}
GridExample gridExample = request.convertExample();
List<SysLogWithBLOBs> voLogs = extSysLogMapper.query(gridExample);
List<SysLogGridDTO> dtos = voLogs.stream().map(this::convertDTO).collect(Collectors.toList());
return dtos;
}
public List<FolderItem> types() {
List<Integer> integers = Arrays.stream(unPanelOperates).collect(Collectors.toList());
List<FolderItem> results = new ArrayList<>();
SysLogConstants.SOURCE_TYPE[] sourceTypes = SysLogConstants.SOURCE_TYPE.values();
SysLogConstants.OPERATE_TYPE[] operateTypes = SysLogConstants.OPERATE_TYPE.values();
for (int i = 0; i < sourceTypes.length; i++) {
SysLogConstants.SOURCE_TYPE sourceType = sourceTypes[i];
for (int j = 0; j < operateTypes.length; j++) {
SysLogConstants.OPERATE_TYPE operateType = operateTypes[j];
if (sourceType.getValue() > 3 && operateType.getValue() > 3){
continue;
}
if (sourceType.getValue() != 3 && integers.contains(operateType.getValue())) {
continue;
}
FolderItem folderItem = new FolderItem();
folderItem.setId(operateType.getValue() + "-" + sourceType.getValue());
String operateTypeName = operateType.getName();
String sourceTypeName = sourceType.getName();
folderItem.setName( Translator.get(operateTypeName) + Translator.get(sourceTypeName));
results.add(folderItem);
}
}
return results;
}
public SysLogGridDTO convertDTO(SysLogWithBLOBs vo) {
SysLogGridDTO sysLogGridDTO = new SysLogGridDTO();
sysLogGridDTO.setOpType(SysLogConstants.operateTypeName(vo.getOperateType()));
sysLogGridDTO.setSourceType(SysLogConstants.sourceTypeName(vo.getSourceType()));
sysLogGridDTO.setTime(vo.getTime());
sysLogGridDTO.setUser(vo.getNickName());
sysLogGridDTO.setDetail(logManager.detailInfo(vo));
return sysLogGridDTO;
}
public void saveLog(SysLogDTO sysLogDTO) {
// String ip = "";
CurrentUserDto user = AuthUtils.getUser();
SysLogWithBLOBs sysLogWithBLOBs = BeanUtils.copyBean(new SysLogWithBLOBs(), sysLogDTO);
if (CollectionUtils.isNotEmpty(sysLogDTO.getPositions())) {
sysLogWithBLOBs.setPosition(gson.toJson(sysLogDTO.getPositions()));
}
if (CollectionUtils.isNotEmpty(sysLogDTO.getRemarks())) {
sysLogWithBLOBs.setRemark(gson.toJson(sysLogDTO.getRemarks()));
}
sysLogWithBLOBs.setTime(System.currentTimeMillis());
sysLogWithBLOBs.setUserId(user.getUserId());
sysLogWithBLOBs.setLoginName(user.getUsername());
sysLogWithBLOBs.setNickName(user.getNickName());
// sysLogWithBLOBs.setIp(ip);
sysLogMapper.insert(sysLogWithBLOBs);
}
public void exportExcel(HttpServletResponse response) throws Exception{
}
}

View File

@ -1,7 +1,6 @@
ALTER TABLE `panel_group`
ADD COLUMN `status` varchar(255) NULL DEFAULT 'publish' COMMENT '1.publish--发布 2.unpublished--未发布' AFTER `mobile_layout`;
CREATE TABLE `de_driver` (
`id` varchar(50) NOT NULL COMMENT '主键',
`name` varchar(50) NOT NULL COMMENT '用户ID',
@ -20,4 +19,33 @@ CREATE TABLE `de_driver_details` (
`version` varchar(255) DEFAULT NULL COMMENT '版本',
`driver_class` longtext DEFAULT NULL COMMENT '驱动类',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='驱动详情';
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='驱动详情';
UPDATE `sys_menu` SET `sub_count` = 1 WHERE `menu_id` = 40;
INSERT INTO `sys_menu` (`menu_id`, `pid`, `sub_count`, `type`, `title`, `name`, `component`, `menu_sort`, `icon`, `path`, `i_frame`, `cache`, `hidden`, `permission`, `create_by`, `update_by`, `create_time`, `update_time`) VALUES (401, 40, 0, 2, '查看系统模板', NULL, NULL, 999, NULL, NULL, 0, 0, 0, 'sys-template:read', NULL, NULL, 1614930862373, 1614930862373);
-- ----------------------------
-- Table structure for sys_log
-- ----------------------------
DROP TABLE IF EXISTS `sys_log`;
CREATE TABLE `sys_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`user_id` bigint(20) NOT NULL COMMENT '操作人',
`login_name` varchar(255) NOT NULL COMMENT '登录账号',
`nick_name` varchar(255) NOT NULL COMMENT '姓名',
`ip` varchar(255) DEFAULT NULL COMMENT 'ip',
`source_type` int(8) NOT NULL COMMENT '资源类型',
`source_id` varchar(255) NOT NULL COMMENT '资源ID',
`source_name` varchar(255) NOT NULL COMMENT '资源名称',
`operate_type` int(8) NOT NULL COMMENT '操作类型',
`position` longtext COMMENT '资源位置',
`remark` longtext COMMENT '备注信息',
`time` bigint(13) NOT NULL COMMENT '操作时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
SET FOREIGN_KEY_CHECKS = 1;
INSERT INTO `sys_menu` VALUES (618, 1, 1, 1, '日志管理', 'system-log', 'system/log/index', 15, 'peoples', 'log', b'0', b'0', b'0', 'log:read', NULL, NULL, NULL, 1620281952752);
INSERT INTO `sys_menu` VALUES (619, 618, 0, 2, '导出日志', NULL, NULL, 1, NULL, NULL, b'0', b'0', b'0', 'log:export', NULL, NULL, NULL, NULL);

View File

@ -128,3 +128,23 @@ i18n_wrong_content=Wrong content
i18n_wrong_tel=Wrong tel format
i18n_wrong_email=Wrong email format
i18n_wrong_name_format=Wrong name format
OPERATE_TYPE_CREATE=Create
OPERATE_TYPE_MODIFY=Modify
OPERATE_TYPE_DELETE=Delete
OPERATE_TYPE_SHARE=Share
OPERATE_TYPE_UNSHARE=Unshare
OPERATE_TYPE_AUTHORIZE=Authorize
OPERATE_TYPE_UNAUTHORIZE=Unauthorize
OPERATE_TYPE_CREATELINK=Create Link
OPERATE_TYPE_DELETELINK=Delete Link
OPERATE_TYPE_MODIFYLINK=Modify Link
SOURCE_TYPE_DATASOURCE=数据源
SOURCE_TYPE_DATASET=数据集
SOURCE_TYPE_PANEL=仪表板
SOURCE_TYPE_VIEW=视图
SOURCE_TYPE_USER=用户
SOURCE_TYPE_DEPT=组织
SOURCE_TYPE_ROLE=角色

View File

@ -128,3 +128,26 @@ i18n_wrong_tel=电话格式错误
i18n_wrong_email=邮箱格式错误
i18n_wrong_name_format=姓名格式错误
OPERATE_TYPE_CREATE=创建
OPERATE_TYPE_MODIFY=修改
OPERATE_TYPE_DELETE=删除
OPERATE_TYPE_SHARE=分享
OPERATE_TYPE_UNSHARE=取消分享
OPERATE_TYPE_AUTHORIZE=授权
OPERATE_TYPE_UNAUTHORIZE=取消授权
OPERATE_TYPE_CREATELINK=创建公共链接
OPERATE_TYPE_DELETELINK=删除公共链接
OPERATE_TYPE_MODIFYLINK=修改公共链接
SOURCE_TYPE_DATASOURCE=数据源
SOURCE_TYPE_DATASET=数据集
SOURCE_TYPE_PANEL=仪表板
SOURCE_TYPE_VIEW=视图
SOURCE_TYPE_USER=用户
SOURCE_TYPE_DEPT=组织
SOURCE_TYPE_ROLE=角色
I18N_OPERATE_TYPE=操作类型
I18N_DETAIL=操作详情
I18N_USER=操作人
I18N_TIME=操作时间

View File

@ -128,3 +128,22 @@ i18n_wrong_content=內容不合法
i18n_wrong_tel=電話格式錯誤
i18n_wrong_email=郵箱格式錯誤
i18n_wrong_name_format=姓名格式錯誤
OPERATE_TYPE_CREATE=創建
OPERATE_TYPE_MODIFY=修改
OPERATE_TYPE_DELETE=刪除
OPERATE_TYPE_SHARE=分享
OPERATE_TYPE_UNSHARE=取消分享
OPERATE_TYPE_AUTHORIZE=授權
OPERATE_TYPE_UNAUTHORIZE=取消授權
OPERATE_TYPE_CREATELINK=創建公共鏈接
OPERATE_TYPE_DELETELINK=刪除公共鏈接
OPERATE_TYPE_MODIFYLINK=修改公共鏈接
SOURCE_TYPE_DATASOURCE=數據源
SOURCE_TYPE_DATASET=數據集
SOURCE_TYPE_PANEL=儀表板
SOURCE_TYPE_VIEW=視圖
SOURCE_TYPE_USER=用戶
SOURCE_TYPE_DEPT=組織
SOURCE_TYPE_ROLE=角色

View File

@ -27,7 +27,7 @@
"element-ui": "2.15.7",
"file-save": "^0.2.0",
"file-saver": "^2.0.5",
"fit2cloud-ui": "1.5.4",
"fit2cloud-ui": "^1.8.0",
"flv.js": "^1.6.2",
"html2canvasde": "^v1.1.4-de",
"jquery": "^3.1.1",

View File

@ -4,11 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*/
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
line-height: 1.4;
margin: 1rem;
}
table {
border-collapse: collapse;

View File

@ -12,7 +12,8 @@ export function proxyInitPanelData(panelId, proxy, callback) {
id: response.data.id,
name: response.data.name,
privileges: response.data.privileges,
proxy: proxy.userId
proxy: proxy.userId,
status: response.data
})
// 刷新联动信息
getPanelAllLinkageInfo(panelId, proxy).then(rsp => {

View File

@ -61,11 +61,12 @@ export function editDs(data) {
})
}
export function delDs(id) {
export function delDs(data) {
return request({
url: 'datasource/delete/' + id,
url: 'datasource/delete',
loading: true,
method: 'post'
method: 'post',
data
})
}
@ -95,7 +96,7 @@ export function getSchema(data) {
})
}
export function checkApiDatasource(data){
export function checkApiDatasource(data) {
return request({
url: 'datasource/checkApiDatasource',
method: 'post',
@ -129,11 +130,12 @@ export function deleteDriverFile(id) {
})
}
export function delDriver(id) {
export function delDriver(data) {
return request({
url: 'driver/delete/' + id,
url: 'driver/delete',
loading: true,
method: 'post'
method: 'post',
data
})
}
export function updateDriver(data) {

View File

@ -0,0 +1,26 @@
import request from '@/utils/request'
export function logGrid(page, size, data) {
return request({
url: '/api/log/logGrid/' + page + '/' + size,
method: 'post',
data,
loading: true
})
}
export function opTypes() {
return request({
url: '/api/log/opTypes',
method: 'post',
loading: true
})
}
export function exportExcel() {
return request({
url: '/api/log/export',
method: 'post',
loading: true
})
}

View File

@ -50,7 +50,6 @@ export default {
background: 'gray',
position: 'absolute'
}
// console.log('style=>' + JSON.stringify(style))
return style
},
...mapState([

View File

@ -661,15 +661,12 @@ export default {
this.maxH = val
},
w(val) {
// console.log('changeWidthCK' + this.resizing)
if (this.resizing || this.dragging) {
return
}
if (this.parent) {
this.bounds = this.calcResizeLimits()
}
// console.log('changeWidth' + val)
this.changeWidth(val)
},
h(val) {
@ -762,7 +759,7 @@ export default {
elementMouseDown(e) {
// private
this.$store.commit('setClickComponentStatus', true)
if (this.element.component !== 'v-text' && this.element.component !== 'rect-shape' && this.element.component !== 'de-input-search' && this.element.component !== 'de-select-grid' && this.element.component !== 'de-number-range' && this.element.component !== 'de-date') {
if (this.element.component !== 'v-text' && this.element.component !== 'de-rich-text' && this.element.component !== 'rect-shape' && this.element.component !== 'de-input-search' && this.element.component !== 'de-select-grid' && this.element.component !== 'de-number-range' && this.element.component !== 'de-date') {
e.preventDefault()
}
//
@ -1005,7 +1002,7 @@ export default {
move(e) {
if (this.resizing) {
this.handleResize(e)
} else if (this.dragging) {
} else if (this.dragging && !this.element.editing) {
this.handleDrag(e)
} else if (this.rotating) {
this.handleRotate(e)
@ -1051,7 +1048,6 @@ export default {
const tmpDeltaY = axis && axis !== 'x' ? mouseClickPosition.mouseY - mY : 0
// mY mY - this.latestMoveY
const offsetY = mY - this.latestMoveY
// console.log('mY:' + mY + ';latestMoveY=' + this.latestMoveY + ';offsetY=' + offsetY)
this.$emit('canvasDragging', mY, offsetY)
this.latestMoveY = mY
const [deltaX, deltaY] = snapToGrid(grid, tmpDeltaX, tmpDeltaY, this.scaleRatio)
@ -1237,7 +1233,6 @@ export default {
newH = restrictToBounds(newH, this.miniHeight || 0, this.maxH)
//
if (this.lockAspectRatio) {
// console.log(this.lockAspectRatio, this.aspectFactor)
if (newW / newH > this.aspectFactor) {
newW = newH * this.aspectFactor
} else {
@ -1245,7 +1240,6 @@ export default {
}
}
this.width = newW
// console.log('width2:' + this.width)
this.height = newH
// this.$emit('resizing', this.left, this.top, this.width, this.height)
@ -1256,8 +1250,6 @@ export default {
this.element.propValue && this.element.propValue.viewId && eventBus.$emit('resizing', this.element.propValue.viewId)
},
changeWidth(val) {
// console.log('parentWidth', this.parentWidth)
// console.log('parentHeight', this.parentHeight)
// eslint-disable-next-line no-unused-vars
const [newWidth, _] = snapToGrid(this.grid, val, 0, this.scale)
// const right = restrictToBounds(this.parentWidth - newWidth - this.left, this.bounds.minRight, this.bounds.maxRight)
@ -1272,7 +1264,6 @@ export default {
this.right = right
this.bottom = bottom
this.width = width
// console.log('width3:' + this.width)
this.height = height
},
changeHeight(val) {
@ -1291,7 +1282,6 @@ export default {
this.right = right
this.bottom = bottom
this.width = width
// console.log('width4:' + this.width)
this.height = height
},
//
@ -1309,7 +1299,6 @@ export default {
this.lastMouseY = mouseY
if (this.resizing) {
this.resizing = false
// console.log('resizing2:' + this.resizing)
this.conflictCheck()
this.$emit('refLineParams', refLine)
// this.$emit('resizestop', this.left, this.top, this.width, this.height)
@ -1396,7 +1385,6 @@ export default {
this.top = this.mouseClickPosition.top
this.left = this.mouseClickPosition.left
this.width = this.mouseClickPosition.width
// console.log('width5:' + this.width)
this.height = this.mouseClickPosition.height
}
}
@ -1580,7 +1568,6 @@ export default {
let groupLeft = 0
let groupTop = 0
for (const item of nodes) {
// console.log('===' + typeof item.tagName)
//
// if (item.className !== undefined && item.className.split(' ').includes(this.classNameActive)) {
if (item.tagName !== 'svg' && item.className !== undefined && item.className.split(' ').includes(this.classNameActive)) {
@ -1680,7 +1667,6 @@ export default {
style.height = height
style.rotate = this.rotate
// this.hasMove = true
// console.log('recordMatrixCurShadowStyle:t1:' + JSON.stringify(style))
this.$store.commit('setShapeStyle', style)
@ -1710,7 +1696,6 @@ export default {
this.aspectFactor = this.outsideAspectRatio
}
this.width = this.w !== 'auto' ? this.w : width
// console.log('width1:' + this.width)
this.height = this.h !== 'auto' ? this.h : height
this.right = this.parentWidth - this.width - this.left
this.bottom = this.parentHeight - this.height - this.top
@ -1866,7 +1851,7 @@ export default {
}
.batchSetting{
opacity: 0.7;
opacity: 0.9;
}
.positionChange{

View File

@ -11,16 +11,12 @@ export default {
name: 'Shadow',
computed: {
styleInfo() {
// console.log('styleInfo==>')
// console.log('dragComponentInfo==>' + this.dragComponentInfo.shadowStyle.x)
let left = 0
let top = 0
let width = 0
let height = 0
let transition = 0
// if (this.dragComponentInfo && !this.dragComponentInfo.auxiliaryMatrix) {
if (this.dragComponentInfo) {
// console.log('shadowDrag=')
//
if (this.dragComponentInfo.auxiliaryMatrix) {
left = (this.dragComponentInfo.x - 1) * this.curCanvasScale.matrixStyleWidth
@ -36,7 +32,6 @@ export default {
height = this.dragComponentInfo.style.height
}
// console.log('left:' + left + 'top:' + top + 'width:' + width + 'height:' + height)
} else {
// temp
// left = this.curComponent.style.left * this.curCanvasScale.scaleWidth / 100
@ -49,12 +44,10 @@ export default {
if (this.curComponent.optStatus.dragging) {
transition = 0.1
}
// console.log('curComponent left:' + left + 'top:' + top + 'width:' + width + 'height:' + height)
}
//
const xGap = left + width - this.canvasWidth
// console.log('canvasWidth:' + this.canvasWidth + ';xGap:' + xGap)
if (xGap > 0) {
left = left - xGap
}
@ -66,7 +59,6 @@ export default {
if (transition > 0) {
style.transition = transition + 's'
}
// console.log('style=>' + JSON.stringify(style))
//
if (this.dragComponentInfo) {
this.recordShadowStyle(left, top, width, height)

View File

@ -107,7 +107,6 @@ export default {
})
bus.$on('web-msg-topic-call', msg => {
console.log('收到websocket消息')
this.count = (this.count || this.paginationConfig.total) + 1
// this.queryCount()
// this.search()

View File

@ -14,7 +14,8 @@ export default {
props: {
iconClass: {
type: String,
required: true
required: false,
default: 'non-existent'
},
className: {
type: String,

View File

@ -1,136 +0,0 @@
<template>
<div class="tinymce-editor" style="background-color: #8a8b8d!important;">
<Editor
:id="tinymceId"
v-model="myValue"
:init="init"
:disabled="disabled"
@onClick="onClick"
/>
</div>
</template>
<script>
import tinymce from 'tinymce/tinymce' // tinymcehidden
import Editor from '@tinymce/tinymce-vue'//
import 'tinymce/themes/silver/theme'//
import 'tinymce/icons/default' // icon
//
import 'tinymce/plugins/advlist' //
import 'tinymce/plugins/autolink' //
import 'tinymce/plugins/link' //
import 'tinymce/plugins/image' //
import 'tinymce/plugins/lists' //
import 'tinymce/plugins/charmap' //
import 'tinymce/plugins/media' //
import 'tinymce/plugins/wordcount'//
// const fonts = [
// '=',
// '=',
// '=',
// '=',
// '=',
// '=',
// 'Courier New=courier new,courier',
// 'AkrutiKndPadmini=Akpdmi-n',
// 'Andale Mono=andale mono,times',
// 'Arial=arial,helvetica,sans-serif',
// 'Arial Black=arial black,avant garde',
// 'Book Antiqua=book antiqua,palatino',
// 'Comic Sans MS=comic sans ms,sans-serif',
// 'Courier New=courier new,courier',
// 'Georgia=georgia,palatino',
// 'Helvetica=helvetica',
// 'Impact=impact,chicago',
// 'Symbol=symbol',
// 'Tahoma=tahoma,arial,helvetica,sans-serif',
// 'Terminal=terminal,monaco',
// 'Times New Roman=times new roman,times',
// 'Trebuchet MS=trebuchet ms,geneva',
// 'Verdana=verdana,geneva',
// 'Webdings=webdings',
// 'Wingdings=wingdings,zapf dingbats'
// ]
export default {
components: {
Editor
},
props: {
//
value: {
type: String,
default: ''
},
//
disabled: {
type: Boolean,
default: false
},
//
plugins: {
type: [String, Array],
default: 'advlist autolink link image lists charmap media wordcount'
},
//
toolbar: {
type: [String, Array],
// default: 'fontsizeselect bold italic alignleft aligncenter alignright forecolor backcolor link'
default: 'undo redo | fontsizeselect | bold italic forecolor backcolor| alignleft aligncenter alignright | link'
}
},
data() {
return {
//
tinymceId: 'tinymce',
myValue: this.value,
init: {
selector: '#tinymce',
toolbar_items_size: 'small',
language_url: '/tinymce/langs/zh_CN.js', // publicstatic
language: 'zh_CN',
skin_url: '/tinymce/skins/ui/oxide', //
content_css: '/tinymce/skins/content/default/content.css',
plugins: this.plugins, //
//
toolbar: this.toolbar,
toolbar_location: '/',
fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 28px 32px 36px 48px 56px 72px', //
// font_formats: fonts.join(';'),
menubar: false,
// height: 500, //
placeholder: '在这里输入文字',
branding: false
}
}
},
watch: {
//
value(newValue) {
this.myValue = (newValue == null ? '' : newValue)
},
myValue(newValue) {
if (this.triggerChange) {
this.$emit('change', newValue)
} else {
this.$emit('input', newValue)
}
}
},
mounted() {
tinymce.init({})
// console.log(this.toolbar,'======')
},
methods: {
onClick(e) {
this.$emit('onClick', e, tinymce)
},
//
clear() {
this.myValue = ''
}
}
}
</script>

View File

@ -108,7 +108,6 @@ export default {
},
computed: {
styleKeys() {
// console.log(this.$store.state.curComponent.style)
return this.$store.state.curComponent ? Object.keys(this.$store.state.curComponent.style) : []
},
curComponent() {

View File

@ -129,7 +129,6 @@ export default {
},
computed: {
styleKeys() {
// console.log(this.$store.state.curComponent.style)
return this.$store.state.curComponent ? Object.keys(this.$store.state.curComponent.style) : []
},
curComponent() {

View File

@ -58,7 +58,7 @@ export default {
//
if (this.curComponent.type === 'v-text' || this.curComponent.type === 'rect-shape') {
if (this.curComponent.type === 'v-text' || this.curComponent.type === 'de-rich-text' || this.curComponent.type === 'rect-shape') {
bus.$emit('component-dialog-style')
}
},

View File

@ -91,7 +91,7 @@ export default {
},
// batch operation area
batchOptAreaShow() {
return this.batchOptStatus && this.element.type === 'view'
return this.batchOptStatus && this.element.type === 'view' && !this.element.isPlugin
},
//
linkageAreaShow() {
@ -148,13 +148,6 @@ export default {
closePreview() {
this.$emit('closePreview')
},
createTimer() {
if (!this.timer) {
this.timer = setInterval(() => {
console.log('t=' + this.curComponent.auxiliaryMatrix)
}, 5000)
}
},
destroyTimer() {
if (this.timer) {
clearInterval(this.timer)
@ -224,7 +217,7 @@ export default {
edit() {
if (this.curComponent.type === 'custom') {
bus.$emit('component-dialog-edit')
} else if (this.curComponent.type === 'v-text' || this.curComponent.type === 'rect-shape') {
} else if (this.curComponent.type === 'v-text' || this.curComponent.type === 'de-rich-text' || this.curComponent.type === 'rect-shape') {
bus.$emit('component-dialog-style')
} else { bus.$emit('change_panel_right_draw', true) }
},
@ -277,11 +270,9 @@ export default {
if (val) {
// push
this.$store.commit('addCurBatchComponent', this.element.propValue.viewId)
console.log('push')
} else {
// remove
this.$store.commit('removeCurBatchComponentWithId', this.element.propValue.viewId)
console.log('remove')
}
}
}

View File

@ -5,7 +5,7 @@
<path
:d="smallGridPathD"
fill="none"
stroke="rgba(207, 207, 207, 0.5)"
stroke="rgba(207, 207, 207, 0.3)"
stroke-width="1"
/>
</pattern>
@ -14,7 +14,7 @@
<path
:d="middleGridPathD"
fill="none"
stroke="rgba(207, 207, 207, 0.7)"
stroke="rgba(207, 207, 207, 0.3)"
stroke-width="1.5"
/>
</pattern>
@ -23,8 +23,8 @@
<path
:d="pathD"
fill="none"
stroke="rgba(64,158,255,0.5)"
stroke-width="2"
stroke="rgba(207, 207, 207, 0.7)"
stroke-width="2.5"
/>
</pattern>
</defs>

View File

@ -108,7 +108,6 @@ export default {
mounted() {
//
checkSameDataSet(this.curLinkageView.propValue.viewId, this.element.propValue.viewId).then(res => {
console.log('linkageFields:' + JSON.stringify(this.linkageInfo.linkageFields))
if (res.data === 'YES' && this.linkageInfo.linkageFields.length === 0) {
this.sourceLinkageInfo.targetViewFields.forEach(item => {
this.addLinkageField(item.id, item.id)

View File

@ -1,7 +1,17 @@
<template>
<div class="bg" :style="customStyle" @scroll="canvasScroll">
<div id="canvasInfoMain" ref="canvasInfoMain" :style="canvasInfoMainStyle">
<el-row v-if="showUnpublishedArea" class="custom-position">
<pre>
<svg-icon icon-class="unpublished" style="font-size: 75px" />
{{ $t('panel.panel_off') }}
</pre>
</el-row>
<el-row v-else-if="componentDataShow.length===0" class="custom-position">
{{ $t('panel.panelNull') }}
</el-row>
<div
v-else
id="canvasInfoTemp"
ref="canvasInfoTemp"
:style="[canvasInfoTempStyle,screenShotStyle]"
@ -9,9 +19,6 @@
@mouseup="deselectCurComponent"
@mousedown="handleMouseDown"
>
<el-row v-if="componentDataShow.length===0" class="custom-position">
{{ $t('panel.panelNull') }}
</el-row>
<canvas-opt-bar />
<ComponentWrapper
v-for="(item, index) in componentDataInfo"
@ -137,6 +144,20 @@ export default {
created() {
},
computed: {
mainActiveName() {
return this.$store.state.panel.mainActiveName
},
showUnpublishedArea() {
return this.panelInfo.status === 'unpublished'
// if (this.mainActiveName === 'PanelMain') {
// return this.panelInfo.status === 'unpublished' && this.panelInfo.privileges.indexOf('manage') === -1
// } else {
// return this.panelInfo.status === 'unpublished'
// }
},
panelInfo() {
return this.$store.state.panel.panelInfo
},
showExportImgButton() {
return this.showChartInfo.type && !this.showChartInfo.type.includes('table')
},
@ -235,13 +256,15 @@ export default {
})
// div
const tempCanvas = document.getElementById('canvasInfoTemp')
erd.listenTo(document.getElementById('canvasInfoTemp'), element => {
_this.$nextTick(() => {
// mainHeight px html2canvas
_this.mainHeight = tempCanvas.scrollHeight + 'px!important'
this.$emit('mainHeightChange', _this.mainHeight)
if (tempCanvas) {
erd.listenTo(document.getElementById('canvasInfoTemp'), element => {
_this.$nextTick(() => {
// mainHeight px html2canvas
_this.mainHeight = tempCanvas.scrollHeight + 'px!important'
this.$emit('mainHeightChange', _this.mainHeight)
})
})
})
}
eventBus.$on('openChartDetailsDialog', this.openChartDetailsDialog)
_this.$store.commit('clearLinkageSettingInfo', false)
_this.canvasStyleDataInit()
@ -372,7 +395,12 @@ export default {
}
.custom-position {
line-height: 30px;
width: 100%;
z-index: 100;
height: 100%;
text-align: center;
cursor:not-allowed;
flex: 1;
display: flex;
align-items: center;

View File

@ -104,7 +104,6 @@ export default {
message: this.$t('panel.outer_param_decode_error'),
type: 'error'
})
console.log('outerParams Decode error', e)
}
}
if (tempParam) {
@ -129,7 +128,6 @@ export default {
if (--loadingCount === 0) {
this.dataLoading = false
}
console.log('queryTargetPanelJumpInfo error', e)
}
}
if (loadingCount === 0) {

View File

@ -67,7 +67,7 @@ export default {
edit() {
if (this.curComponent.type === 'custom') {
bus.$emit('component-dialog-edit')
} else if (this.curComponent.type === 'v-text' || this.curComponent.type === 'rect-shape') {
} else if (this.curComponent.type === 'v-text' || this.curComponent.type === 'de-rich-text' || this.curComponent.type === 'rect-shape') {
bus.$emit('component-dialog-style')
} else { bus.$emit('change_panel_right_draw', true) }
},

View File

@ -339,7 +339,6 @@ export default {
curPoint,
symmetricPoint
})
// console.log('this is test:' + JSON.stringify(this.element.propValue.viewId))
this.$store.commit('setShapeStyle', style)
this.element.propValue && this.element.propValue.viewId && eventBus.$emit('resizing', this.element.propValue.viewId)
}

View File

@ -61,22 +61,8 @@
@canvasDragging="canvasDragging"
@editComponent="editComponent(index,item)"
>
<component
:is="item.component"
v-if="renderOk&&item.type==='v-text'"
:id="'component' + item.id"
ref="wrapperChild"
class="component"
:style="getComponentStyleDefault(item.style)"
:prop-value="item.propValue"
:element="item"
:out-style="getShapeStyleInt(item.style)"
:edit-mode="'edit'"
:active="item === curComponent"
@input="handleInput"
/>
<de-out-widget
v-else-if="renderOk&&item.type==='custom'"
v-if="renderOk&&item.type==='custom'"
:id="'component' + item.id"
ref="wrapperChild"
class="component"
@ -113,6 +99,7 @@
:active="item === curComponent"
:edit-mode="'edit'"
:h="getShapeStyleIntDeDrag(item.style,'height')"
@input="handleInput"
/>
</de-drag>
<!--拖拽阴影部分-->
@ -264,11 +251,9 @@ function debounce(func, time) {
function scrollScreen(e) {
if (e.clientY + 50 >= window.innerHeight) {
// console.log('scrollScreen+')
const body = $(document.body)
body.scrollTop(body.scrollTop() + 20)
} else if (e.clientY <= 150) {
// console.log('scrollScreen-')
const body = $(document.body)
body.scrollTop(body.scrollTop() - 20)
}
@ -312,7 +297,6 @@ function addItemToPositionBox(item) {
}
} catch (e) {
// igonre
console.log('addItemToPositionBox failed')
}
}
@ -514,7 +498,6 @@ function removeItem(index) {
})
this.yourList.splice(index, 1, {})
} catch (e) {
console.log('removeItem have some ignore error')
}
}
@ -527,7 +510,6 @@ function initPosition(_this) {
}
function addItem(item, index) {
// console.log('addItem')
if (index < 0) {
index = this.yourList.length
}
@ -1057,7 +1039,6 @@ export default {
if (newVal.length !== this.lastComponentDataLength) {
this.lastComponentDataLength = newVal.length
this.initMatrix()
// console.log('componentData-initMatrix')
}
},
deep: true
@ -1300,7 +1281,6 @@ export default {
this.baseHeight = this.matrixStyle.height
this.cellWidth = this.matrixStyle.width
this.cellHeight = this.matrixStyle.height
// console.log('.initMatrix1')
this.initMatrix()
this.scaleWidth = this.outStyle.width * 100 / this.canvasStyleData.width
@ -1339,7 +1319,6 @@ export default {
}
if (prop === 'top') {
const top = this.format(style['top'], this.scaleHeight)
// console.log('top:' + top)
return top
}
},
@ -1467,7 +1446,6 @@ export default {
infoBox.oldSizeY = item.sizey
},
onMouseUp(e) {
// console.log('onMouseUp')
const vm = this
if (_.isEmpty(vm.infoBox)) return
if (vm.infoBox.cloneItem) {
@ -1510,9 +1488,7 @@ export default {
newY = newY > 0 ? newY : 1
debounce((function(newX, oldX, newY, oldY, addSizex, addSizey) {
return function() {
// console.log('move1')
if (newX !== oldX || oldY !== newY) {
// console.log('move2')
movePlayer.call(vm, resizeItem, {
x: newX,
y: newY
@ -1545,9 +1521,7 @@ export default {
newY = newY > 0 ? newY : 1
debounce((function(newX, oldX, newY, oldY) {
return function() {
// console.log('move1')
if (newX !== oldX || oldY !== newY) {
// console.log('move2')
movePlayer.call(vm, moveItem, {
x: newX,
y: newY
@ -1598,8 +1572,6 @@ export default {
* @returns
*/
getMaxCell() {
// console.log('getMaxCell:')
return this.maxCell
},
/**
@ -1608,8 +1580,6 @@ export default {
* @returns
*/
getRenderState() {
// console.log('getRenderState:')
return this.moveAnimate
},
addItem: addItem,
@ -1624,7 +1594,6 @@ export default {
}, 100)
},
addItemBox(item) {
// console.log('addItemBox:' + JSON.stringify(item))
this.yourList.push(item)
this.$nextTick(function() {
@ -1632,7 +1601,6 @@ export default {
})
},
removeLastItem() {
// console.log('rlI:' + JSON.stringify(this.yourList))
if (this.canvasStyleData.auxiliaryMatrix) {
this.removeItem(this.yourList.length - 1)
}

View File

@ -139,7 +139,6 @@ export default {
}
// toolbar
const xGap = ps + 295 - this.canvasWidth
// console.log('canvasWidth:' + this.canvasWidth + ';xGap:' + xGap)
if (xGap > 0) {
return ps - xGap
} else {

View File

@ -191,7 +191,6 @@ export default {
}
// toolbar
const xGap = ps + 345 - this.canvasWidth
// console.log('canvasWidth:' + this.canvasWidth + ';xGap:' + xGap)
if (xGap > 0) {
return ps - xGap
} else {

View File

@ -394,7 +394,6 @@ export default {
this.$nextTick(() => {
this.init()
})
// console.log('curComponent change')
}
}
},
@ -417,14 +416,11 @@ export default {
} else {
this.mainWidthOffset = document.getElementById('main-attr').offsetWidth - 50
}
// console.log('mainWidthOffset:' + this.mainWidthOffset)
},
attrTabShow(attr) {
// console.log('attr:' + attr + this[this.curComponent.type].includes(attr))
return this.curActiveTabInner && this[this.curActiveTabInner.type] && this[this.curActiveTabInner.type].includes(attr)
},
attrShow(attr) {
// console.log('attr:' + attr + this[this.curComponent.type].includes(attr))
return this[this.curComponent.type].includes(attr)
},
goColor() {

View File

@ -76,10 +76,8 @@ export default {
},
methods: {
loaded(e) {
console.log('loaded:', e)
},
onError(e) {
console.log('onError:', e)
}
}

View File

@ -0,0 +1,207 @@
<template>
<div class="rich-main-class" @dblclick="setEdit">
<Editor
v-if="editShow"
:id="tinymceId"
v-model="myValue"
style="width: 100%;height: 100%"
:init="init"
:disabled="!canEdit"
@onClick="onClick"
/>
<!-- <div v-show="!canEdit" style="width: 100%;height: 100%" @dblclick="setEdit" v-html="myValue" />-->
</div>
<!-- <div v-else class="rich-main-class">-->
<!-- <Editor :id="tinymceId"/>-->
<!-- <div v-html="myValue" />-->
<!-- </div>-->
</template>
<script>
import tinymce from 'tinymce/tinymce' // tinymcehidden
import Editor from '@tinymce/tinymce-vue'//
import 'tinymce/themes/silver/theme'//
import 'tinymce/icons/default' // icon
//
import 'tinymce/plugins/advlist' //
import 'tinymce/plugins/autolink' //
import 'tinymce/plugins/link' //
import 'tinymce/plugins/image' //
import 'tinymce/plugins/lists' //
import 'tinymce/plugins/charmap' //
import 'tinymce/plugins/media' //
import 'tinymce/plugins/wordcount'//
import 'tinymce/plugins/table'//
import 'tinymce/plugins/contextmenu'// contextmenu
import 'tinymce/plugins/directionality'
import 'tinymce/plugins/nonbreaking'
import 'tinymce/plugins/pagebreak'
import { mapState } from 'vuex'
// const fonts = [
// '=',
// '=',
// '=',
// '=',
// '=',
// '=',
// 'Courier New=courier new,courier',
// 'AkrutiKndPadmini=Akpdmi-n',
// 'Andale Mono=andale mono,times',
// 'Arial=arial,helvetica,sans-serif',
// 'Arial Black=arial black,avant garde',
// 'Book Antiqua=book antiqua,palatino',
// 'Comic Sans MS=comic sans ms,sans-serif',
// 'Courier New=courier new,courier',
// 'Georgia=georgia,palatino',
// 'Helvetica=helvetica',
// 'Impact=impact,chicago',
// 'Symbol=symbol',
// 'Tahoma=tahoma,arial,helvetica,sans-serif',
// 'Terminal=terminal,monaco',
// 'Times New Roman=times new roman,times',
// 'Trebuchet MS=trebuchet ms,geneva',
// 'Verdana=verdana,geneva',
// 'Webdings=webdings',
// 'Wingdings=wingdings,zapf dingbats'
// ]
export default {
name: 'DeRichText',
components: {
Editor
},
props: {
propValue: {
type: String,
require: true
},
element: {
type: Object
},
editMode: {
type: String,
require: false,
default: 'preview'
},
active: {
type: Boolean,
require: false,
default: false
},
//
disabled: {
type: Boolean,
default: false
}
},
data() {
return {
editShow: true,
canEdit: false,
//
tinymceId: 'tinymce',
myValue: this.propValue,
init: {
selector: '#tinymce',
toolbar_items_size: 'small',
language_url: '/tinymce/langs/zh_CN.js', // publicstatic
language: 'zh_CN',
skin_url: '/tinymce/skins/ui/oxide', //
content_css: '/tinymce/skins/content/default/content.css',
plugins: 'advlist autolink link image lists charmap media wordcount table contextmenu directionality pagebreak', //
//
// toolbar: 'undo redo | fontsizeselect fontselect | bold italic forecolor backcolor underline strikethrough | alignleft aligncenter alignright | lists image media table link | bullist numlist ',
toolbar: 'undo redo |fontsizeselect forecolor backcolor bold italic underline strikethrough link | ' +
'alignleft aligncenter alignright | bullist numlist |' +
' blockquote subscript superscript removeformat | table image media | fullscreen ' +
'| bdmap indent2em lineheight formatpainter axupimgs',
toolbar_location: '/',
fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 28px 32px 36px 48px 56px 72px', //
menubar: false,
placeholder: '双击输入文字',
inline: true, //
branding: false
}
}
},
computed: {
editStatus() {
return this.editMode === 'edit' && !this.mobileLayoutStatus
},
...mapState([
'mobileLayoutStatus'
])
},
watch: {
//
active(val) {
if (!val) {
this.editShow = false
this.canEdit = false
this.$nextTick(() => {
this.editShow = true
})
}
},
//
propValue(newValue) {
this.myValue = (newValue == null ? '' : newValue)
},
myValue(newValue) {
this.element.propValue = newValue
this.$store.state.styleChangeTimes++
}
},
mounted() {
tinymce.init({})
},
methods: {
onClick(e) {
this.$emit('onClick', e, tinymce)
},
setEdit() {
if (this.editStatus) {
this.canEdit = true
this.element.editing = true
}
}
}
}
</script>
<style lang="scss" scoped>
.rich-main-class {
width: 100%;
height: 100%;
overflow-y: auto!important;
}
::-webkit-scrollbar {
width: 0px!important;
height: 0px!important;
}
::v-deep ol {
display: block!important;
list-style-type: decimal;
margin-block-start: 1em!important;
margin-block-end: 1em!important;
margin-inline-start: 0px!important;
margin-inline-end: 0px!important;
padding-inline-start: 40px!important;
}
::v-deep ul {
display: block!important;
list-style-type: disc;
margin-block-start: 1em!important;
margin-block-end: 1em!important;
margin-inline-start: 0px!important;
margin-inline-end: 0px!important;
padding-inline-start: 40px!important;
}
::v-deep li {
display: list-item!important;
text-align: -webkit-match-parent!important;
}
</style>

View File

@ -109,40 +109,29 @@ export default {
},
// listen event
onPlayerPlay(player) {
// console.log('player play!', player)
},
onPlayerEnded(player) {
// console.log('player ended!', player)
},
onPlayerLoadeddata(player) {
// console.log('player Loadeddata!', player)
},
onPlayerWaiting(player) {
// console.log('player Waiting!', player)
},
onPlayerPlaying(player) {
// console.log('player Playing!', player)
},
onPlayerTimeupdate(player) {
// console.log('player Timeupdate!', player.currentTime())
},
onPlayerCanplay(player) {
// console.log('player Canplay!', player)
},
onPlayerCanplaythrough(player) {
// console.log('player Ca
// console.log('example 01nplaythrough!', player)
},
// or listen state event
playerStateChanged(playerCurrentState) {
// console.log('player current update state', playerCurrentState)
},
// player is ready
playerReadied(player) {
// seek to 10s
// console.log('example player 1 readied', player)
// player.currentTime(10): the player is readied', player)
}
}

View File

@ -1,30 +0,0 @@
<template>
<TinyMCE v-model="curComponent.propValue" />
</template>
<script>
import TinyMCE from '@/components/TinyMCE/index.vue'
export default {
components: { TinyMCE },
data() {
return {
}
},
computed: {
curComponent() {
return this.$store.state.curComponent
}
}
}
</script>
<style lang="scss" scoped>
.attr-list {
overflow: auto;
padding: 20px;
padding-top: 0;
height: 100%;
}
</style>

View File

@ -412,8 +412,11 @@ export default {
this.chart.customAttr = this.sourceCustomAttrStr
updateParams['customAttr'] = this.sourceCustomAttrStr
} else if (param.custom === 'customStyle') {
this.sourceCustomStyleStr = this.chart.customStyle
const sourceCustomStyle = JSON.parse(this.sourceCustomStyleStr)
// view's title use history
if (param.property === 'text') {
param.value.title = sourceCustomStyle.text.title
}
sourceCustomStyle[param.property] = param.value
this.sourceCustomStyleStr = JSON.stringify(sourceCustomStyle)
this.chart.customStyle = this.sourceCustomStyleStr

View File

@ -1,150 +0,0 @@
<template>
<div v-if="editMode == 'edit'" class="v-text" @keydown="handleKeydown" @keyup="handleKeyup">
<!-- tabindex >= 0 使得双击时聚集该元素 -->
<div
ref="text"
:contenteditable="canEdit"
:class="{ canEdit }"
:tabindex="element.id"
:style="{ verticalAlign: element.style.verticalAlign }"
@dblclick="setEdit"
@paste="clearStyle"
@mousedown="handleMousedown"
@blur="handleBlur"
@input="handleInput"
v-html="element.propValue"
/>
</div>
<div v-else class="v-text">
<div :style="{ verticalAlign: element.style.verticalAlign }" v-html="element.propValue" />
</div>
</template>
<script>
import { keycodes } from '@/components/canvas/utils/shortcutKey.js'
export default {
props: {
// eslint-disable-next-line vue/require-default-prop
propValue: {
type: String,
require: true
},
// eslint-disable-next-line vue/require-default-prop
element: {
type: Object
},
editMode: {
type: String,
require: false,
default: 'preview'
},
active: {
type: Boolean,
require: false,
default: false
}
},
data() {
return {
canEdit: false,
ctrlKey: 17,
isCtrlDown: false
}
},
computed: {
},
watch: {
active: {
handler(newVal, oldVla) {
this.removeSelectText()
},
deep: true
}
},
methods: {
handleInput(e) {
this.$emit('input', this.element, e.target.innerHTML)
},
handleKeydown(e) {
if (e.keyCode === this.ctrlKey) {
this.isCtrlDown = true
} else if (this.isCtrlDown && this.canEdit && keycodes.includes(e.keyCode)) {
e.stopPropagation()
} else if (e.keyCode === 46) { // deleteKey
e.stopPropagation()
}
},
handleKeyup(e) {
if (e.keyCode === this.ctrlKey) {
this.isCtrlDown = false
}
},
handleMousedown(e) {
if (this.canEdit) {
e.stopPropagation()
}
},
clearStyle(e) {
e.preventDefault()
const clp = e.clipboardData
const text = clp.getData('text/plain') || ''
if (text !== '') {
document.execCommand('insertText', false, text)
}
this.$emit('input', this.element, e.target.innerHTML)
},
handleBlur(e) {
this.element.propValue = e.target.innerHTML || '&nbsp;'
this.canEdit = false
},
setEdit() {
this.canEdit = true
//
this.selectText(this.$refs.text)
},
selectText(element) {
const selection = window.getSelection()
const range = document.createRange()
range.selectNodeContents(element)
selection.removeAllRanges()
selection.addRange(range)
},
removeSelectText() {
const selection = window.getSelection()
selection.removeAllRanges()
}
}
}
</script>
<style lang="scss" scoped>
.v-text {
width: 100%;
height: 100%;
display: table;
div {
display: table-cell;
width: 100%;
height: 100%;
outline: none;
}
.canEdit {
cursor: text;
height: 100%;
}
}
</style>

View File

@ -126,6 +126,14 @@ export const assistList = [
icon: 'iconfont icon-text',
defaultClass: 'text-filter'
},
{
id: '10002',
component: 'de-rich-text',
type: 'de-rich-text',
label: '富文本',
icon: 'iconfont icon-fuwenbenkuang',
defaultClass: 'text-filter'
},
{
id: '10004',
component: 'rect-shape',
@ -249,26 +257,21 @@ const list = [
},
{
id: '10002',
component: 'v-button',
label: '按钮',
propValue: '按钮',
icon: 'button',
type: 'v-button',
component: 'de-rich-text',
label: '富文本',
propValue: '双击输入文字',
icon: 'icon-fuwenbenkuang',
type: 'de-rich-text',
mobileStyle: BASE_MOBILE_STYLE,
hyperlinks: HYPERLINKS,
style: {
width: 100,
height: 34,
borderWidth: '',
borderColor: '',
borderRadius: '',
fontSize: 14,
fontWeight: 400,
lineHeight: '',
letterSpacing: 0,
textAlign: '',
color: '',
backgroundColor: ''
width: 400,
height: 100
},
x: 1,
y: 1,
sizex: 10,
sizey: 2,
miniSizex: 1,
miniSizey: 1
},

View File

@ -9,7 +9,8 @@ import UserView from '@/components/canvas/custom-component/UserView'
import DeVideo from '@/components/canvas/custom-component/DeVideo'
import DeFrame from '@/components/canvas/custom-component/DeFrame'
import DeStreamMedia from '@/components/canvas/custom-component/DeStreamMedia'
import DeRichText from '@/components/canvas/custom-component/DeRichText'
Vue.component('DeRichText', DeRichText)
Vue.component('DeStreamMedia', DeStreamMedia)
Vue.component('Picture', Picture)
Vue.component('VText', VText)

View File

@ -112,7 +112,6 @@ export default {
this.watchSize()
},
created() {
// console.log('aaaaaa')
},
methods: {

View File

@ -37,7 +37,6 @@ export default {
methods: {
chartResize() {
// console.log('11111')
this.$nextTick(() => {
this.$refs[this.element.id] && this.$refs[this.element.id].resize && this.$refs[this.element.id].resize()
})

View File

@ -378,7 +378,6 @@ export default {
},
setComponentInfo() {
console.log('aaa')
},
editCurTitle(param) {

View File

@ -0,0 +1,2 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1653050060477" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3697" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); }
</style></defs><path d="M512 953.6a441.6 441.6 0 1 1 0-883.2 441.6 441.6 0 0 1 0 883.2z m0-64a377.6 377.6 0 1 0 0-755.2 377.6 377.6 0 0 0 0 755.2z" p-id="3698"></path><path d="M182.1696 227.4304l45.2608-45.2608 614.4 614.4-45.2608 45.2608z" p-id="3699"></path></svg>

After

Width:  |  Height:  |  Size: 934 B

View File

@ -0,0 +1,2 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1652951914828" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2768" data-spm-anchor-id="a313x.7781069.0.i0" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); }
</style></defs><path d="M327.59296 687.74912l511.36 1.28512c23.89504-1.47456 43.82208-17.0752 49.68448-39.38304l99.29216-416.4864c3.8912-14.69952 0.71168-30.13632-8.72448-42.37312-10.25536-13.30688-26.84928-21.248-44.42112-21.248l-203.86304 0c-13.79328 0-24.98048 11.17696-24.98048 24.95488 0 13.78304 11.1872 24.96512 24.98048 24.96512l203.86816 0c3.24608 0 4.73088 1.53088 4.69504 1.53088l-99.2512 416.37376c-0.23552 0.44544-1.69472 1.68448-2.75968 1.80736l-489.42592-1.27488L245.39648 219.45344l213.34016 0c13.79328 0 24.97536-11.17696 24.97536-24.96 0-13.77792-11.18208-24.96-24.97536-24.96l-225.5872 0-27.776-113.22368L59.10528 56.30976c-13.79328 0-24.97536 11.17184-24.97536 24.96 0 13.78304 11.18208 24.96 24.97536 24.96l107.06944 0 131.584 536.35584c-40.72448 12.99968-70.30784 51.16928-70.30784 96.11264 0 30.23872 13.40416 57.39008 34.56 75.89888-21.15584 18.5088-34.56 45.66016-34.56 75.89376 0 55.64928 45.29664 100.90496 100.97152 100.90496 55.68 0 100.97664-45.25568 100.97152-100.90496 0-18.5856-5.07904-36.00384-13.88544-50.9696l360.82688 0c-8.81152 14.96576-13.89056 32.384-13.89056 50.9696 0 55.64928 45.29664 100.90496 100.97152 100.90496 55.68 0 100.97152-45.25568 100.97152-100.90496 0-55.62368-45.29152-100.8896-100.97152-100.8896L328.4224 789.60128c-0.51712 0-1.024 0.03072-1.536 0.04096-27.42272-0.81408-49.47968-23.34208-49.47968-50.944C277.40672 710.86592 299.84256 688.19968 327.59296 687.74912L327.59296 687.74912zM863.4112 839.52128c28.13952 0 51.0208 22.86592 51.0208 50.97472 0 28.11392-22.88128 50.99008-51.0208 50.99008-28.1344 0-51.01056-22.87616-51.01056-50.99008C812.40064 862.3872 835.2768 839.52128 863.4112 839.52128L863.4112 839.52128zM326.97344 839.55712c0.4864 0.01024 0.96256 0.04096 1.44896 0.04096 0.32768 0 0.64512-0.03584 0.96768-0.04608 27.69408 0.51712 50.048 23.15776 50.048 50.944 0 28.11904-22.88128 50.99008-51.0208 50.99008-28.1344 0-51.01568-22.87104-51.01568-50.99008C277.40672 862.8736 299.50976 840.33024 326.97344 839.55712L326.97344 839.55712zM472.99584 297.43616l106.24 102.5536c0.23552 0.22528 0.50176 0.42496 0.7424 0.64512 0.31232 0.27136 0.6144 0.54784 0.93696 0.80896 0.3072 0.256 0.62464 0.47616 0.9472 0.71168 0.33792 0.25088 0.67072 0.49664 1.024 0.73216 0.32256 0.20992 0.64 0.39424 0.96256 0.58368 0.37888 0.22528 0.75264 0.45056 1.14176 0.65024 0.3072 0.16384 0.6144 0.30208 0.93184 0.45056 0.42496 0.19968 0.8448 0.40448 1.28 0.57856 0.28672 0.10752 0.57344 0.20992 0.86016 0.31232 0.47104 0.17408 0.9472 0.34816 1.4336 0.49664 0.256 0.0768 0.52224 0.128 0.768 0.19456 0.52736 0.13312 1.0496 0.27136 1.58208 0.37888 0.23552 0.04608 0.48128 0.07168 0.7168 0.10752 0.55296 0.09216 1.10592 0.18432 1.664 0.24064 0.20992 0.01536 0.4096 0.01024 0.61952 0.03072 0.57856 0.03584 1.16224 0.08704 1.75616 0.08704 0.58368 0 1.15712-0.0512 1.73056-0.08704 0.21504-0.01536 0.42496-0.01024 0.64-0.03072 0.55296-0.0512 1.1008-0.14848 1.6384-0.2304 0.25088-0.04096 0.50176-0.06656 0.74752-0.11776 0.52736-0.1024 1.03936-0.23552 1.55648-0.36864 0.26624-0.07168 0.53248-0.128 0.79872-0.2048 0.48128-0.14336 0.95232-0.31744 1.41312-0.4864 0.29696-0.10752 0.58368-0.2048 0.88064-0.32256 0.43008-0.17408 0.83968-0.37376 1.25952-0.57344 0.32256-0.14848 0.64-0.29184 0.95744-0.4608 0.37376-0.19968 0.7424-0.41984 1.11616-0.64 0.32768-0.19456 0.66048-0.384 0.98304-0.59904 0.34304-0.22528 0.67584-0.47616 1.00352-0.7168 0.32256-0.23552 0.65024-0.46592 0.96256-0.7168 0.31744-0.256 0.6144-0.53248 0.91648-0.80384 0.25088-0.22016 0.512-0.42496 0.75264-0.65536l106.23488-102.5536c9.92256-9.57952 10.19904-25.3696 0.60928-35.28704-4.89984-5.07392-11.42784-7.61344-17.96608-7.61344-6.25152 0-12.49792 2.3296-17.3568 7.00928l-63.90272 61.68064L621.57824 66.79552c0-13.77792-11.1872-24.96-24.98048-24.96s-24.97536 11.18208-24.97536 24.96l0 256.42496L507.70944 261.53472c-9.93792-9.59488-25.72288-9.32352-35.32288 0.60416C462.7968 272.06656 463.0784 287.85152 472.99584 297.43616L472.99584 297.43616z" p-id="2769"></path><path d="M596.59264 358.2464 596.59264 358.2464z" p-id="2770"></path></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -1447,6 +1447,7 @@ export default {
sure_bt: 'Confirm'
},
panel: {
panel_off: 'Off the shelf',
batch_opt: 'Batch Operation',
edit_leave_tips: 'Do You Want To Abandon And Leave The Current Page?',
hyperlinks: 'Hyperlinks',

View File

@ -1448,6 +1448,7 @@ export default {
sure_bt: '確定'
},
panel: {
panel_off: '仪表板已下架',
batch_opt: '批量操作',
edit_leave_tips: '是否放弃编辑离开当前界面?',
hyperlinks: '超鏈接',

View File

@ -1455,6 +1455,7 @@ export default {
sure_bt: '确定'
},
panel: {
panel_off: '仪表板已下架',
batch_opt: '批量操作',
edit_leave_tips: '是否放弃编辑离开当前界面?',
hyperlinks: '超链接',
@ -2056,5 +2057,14 @@ export default {
port: '端口',
user: '用户名',
passwd: '密码'
},
log: {
title: '操作日志',
optype: '操作类型',
detail: '操作详情',
user: '操作用户',
time: '操作时间',
export: '导出',
search_by_key: '搜索详情'
}
}

View File

@ -125,7 +125,8 @@ const data = {
changeProperties: {
customStyle: {},
customAttr: {}
}
},
allViewRender: []
},
mutations: {
...animation.mutations,
@ -159,6 +160,12 @@ const data = {
dragging: false,
resizing: false
}
// Is the current component in editing status
if (!state.curComponent) {
component['editing'] = false
} else if (component.id !== state.curComponent.id) {
component['editing'] = false
}
}
state.styleChangeTimes = 0
state.curComponent = component
@ -544,7 +551,7 @@ const data = {
// get view base info
const viewBaseInfo = state.componentViewsData[id]
// get properties
const viewConfig = TYPE_CONFIGS.filter(item => item.render === viewBaseInfo.render && item.value === viewBaseInfo.type)
const viewConfig = state.allViewRender.filter(item => item.render === viewBaseInfo.render && item.value === viewBaseInfo.type)
const viewProperties = viewConfig ? viewConfig[0].properties : []
if (state.mixProperties.length > 0) {
// If it exists , taking the intersection
@ -635,6 +642,12 @@ const data = {
customStyle: {},
customAttr: {}
}
},
initViewRender(state, pluginViews) {
pluginViews.forEach(plugin => {
plugin.isPlugin = true
})
state.allViewRender = [...TYPE_CONFIGS, ...pluginViews]
}
},
modules: {

View File

@ -54,6 +54,12 @@
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe670;</span>
<div class="name">富文本框</div>
<div class="code-name">&amp;#xe670;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6e5;</span>
<div class="name">下架</div>
@ -588,9 +594,9 @@
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2?t=1652670008819') format('woff2'),
url('iconfont.woff?t=1652670008819') format('woff'),
url('iconfont.ttf?t=1652670008819') format('truetype');
src: url('iconfont.woff2?t=1652937715816') format('woff2'),
url('iconfont.woff?t=1652937715816') format('woff'),
url('iconfont.ttf?t=1652937715816') format('truetype');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@ -616,6 +622,15 @@
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-fuwenbenkuang"></span>
<div class="name">
富文本框
</div>
<div class="code-name">.icon-fuwenbenkuang
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-unpublish"></span>
<div class="name">
@ -1417,6 +1432,14 @@
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-fuwenbenkuang"></use>
</svg>
<div class="name">富文本框</div>
<div class="code-name">#icon-fuwenbenkuang</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-unpublish"></use>

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 2459092 */
src: url('iconfont.woff2?t=1652670008819') format('woff2'),
url('iconfont.woff?t=1652670008819') format('woff'),
url('iconfont.ttf?t=1652670008819') format('truetype');
src: url('iconfont.woff2?t=1652937715816') format('woff2'),
url('iconfont.woff?t=1652937715816') format('woff'),
url('iconfont.ttf?t=1652937715816') format('truetype');
}
.iconfont {
@ -13,6 +13,10 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-fuwenbenkuang:before {
content: "\e670";
}
.icon-unpublish:before {
content: "\e6e5";
}

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,13 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "2471358",
"name": "富文本框",
"font_class": "fuwenbenkuang",
"unicode": "e670",
"unicode_decimal": 58992
},
{
"icon_id": "1236927",
"name": "下架",

View File

@ -827,3 +827,6 @@ div:focus {
// position: relative !important;
right: 0px;
}
.fu-operator-component__operator {
display: none !important;
}

View File

@ -1,7 +0,0 @@
<template>
<TEditor />
</template>
<script>
</script>

View File

@ -192,7 +192,6 @@ export default {
uploadFileResult(file, (fileUrl) => {
_this.curComponent.commonBackground.outerImage = fileUrl
})
// console.log('this is upload')
}
}

View File

@ -8,7 +8,8 @@ export const DEFAULT_COLOR_CASE = {
tableStripe: true,
dimensionColor: '#000000',
quotaColor: '#000000',
tableBorderColor: '#cfdaf4'
tableBorderColor: '#cfdaf4',
seriesColors: [] // 格式:{"name":"s1","color":"","isCustom":false}
}
export const DEFAULT_SIZE = {
barDefault: true,

View File

@ -223,7 +223,6 @@ export default {
} else if (chart.type === 'chart-mix') {
chart_option = baseMixOption(JSON.parse(JSON.stringify(BASE_MIX)), chart)
}
// console.log(JSON.stringify(chart_option))
if (this.myChart && this.searchCount > 0) {
chart_option.animation = false
}

View File

@ -191,7 +191,6 @@ export default {
},
antVAction(param) {
console.log(param)
if (this.chart.type === 'treemap') {
this.pointParam = param.data.data
} else {

View File

@ -213,10 +213,8 @@ export default {
},
antVAction(param) {
console.log(param, 'param')
const cell = this.myChart.getCell(param.target)
const meta = cell.getMeta()
console.log(meta, 'meta')
let xAxis = []
if (this.chart.xaxis) {
@ -251,7 +249,6 @@ export default {
dimensionList: dimensionList
}
}
console.log(this.pointParam, 'pointParam')
if (this.trackMenu.length < 2) { //
this.trackClick(this.trackMenu[0])

View File

@ -6,7 +6,7 @@
<el-checkbox v-model="titleForm.show" @change="changeTitleStyle">{{ $t('chart.show') }}</el-checkbox>
</el-form-item>
<div v-show="titleForm.show">
<el-form-item :label="$t('chart.title')" class="form-item">
<el-form-item v-if="!batchOptStatus" :label="$t('chart.title')" class="form-item">
<el-input
v-model="titleForm.title"
size="mini"
@ -51,6 +51,7 @@
<script>
import { COLOR_PANEL, DEFAULT_TITLE_STYLE } from '../../chart/chart'
import { checkViewTitle } from '@/components/canvas/utils/utils'
import { mapState } from 'vuex'
export default {
name: 'TitleSelector',
@ -79,6 +80,11 @@ export default {
}
}
},
computed: {
...mapState([
'batchOptStatus'
])
},
mounted() {
this.init()
this.initData()
@ -96,7 +102,9 @@ export default {
if (customStyle.text) {
this.titleForm = customStyle.text
}
this.titleForm.title = this.chart.title
if (!this.batchOptStatus) {
this.titleForm.title = this.chart.title
}
}
},
init() {
@ -110,15 +118,17 @@ export default {
this.fontSize = arr
},
changeTitleStyle() {
if (this.titleForm.title.length < 1) {
this.$error(this.$t('chart.title_cannot_empty'))
this.titleForm.title = this.chart.title
return
}
if (checkViewTitle('update', this.chart.id, this.titleForm.title)) {
this.$error(this.$t('chart.title_repeat'))
this.titleForm.title = this.chart.title
return
if (!this.batchOptStatus) {
if (this.titleForm.title.length < 1) {
this.$error(this.$t('chart.title_cannot_empty'))
this.titleForm.title = this.chart.title
return
}
if (checkViewTitle('update', this.chart.id, this.titleForm.title)) {
this.$error(this.$t('chart.title_repeat'))
this.titleForm.title = this.chart.title
return
}
}
if (!this.titleForm.show) {
this.isSetting = false

View File

@ -6,7 +6,7 @@
<el-checkbox v-model="titleForm.show" @change="changeTitleStyle">{{ $t('chart.show') }}</el-checkbox>
</el-form-item>
<div v-show="titleForm.show">
<el-form-item :label="$t('chart.title')" class="form-item">
<el-form-item v-if="!this.batchOptStatus" :label="$t('chart.title')" class="form-item">
<el-input
v-model="titleForm.title"
size="mini"
@ -43,8 +43,8 @@
<script>
import { COLOR_PANEL, DEFAULT_TITLE_STYLE } from '../../chart/chart'
import { checkTitle } from '@/api/chart/chart'
import { checkViewTitle } from '@/components/canvas/utils/utils'
import { mapState } from 'vuex'
export default {
name: 'TitleSelectorAntV',
@ -66,6 +66,11 @@ export default {
predefineColors: COLOR_PANEL
}
},
computed: {
...mapState([
'batchOptStatus'
])
},
watch: {
'chart': {
handler: function() {
@ -90,7 +95,9 @@ export default {
if (customStyle.text) {
this.titleForm = customStyle.text
}
this.titleForm.title = this.chart.title
if (!this.batchOptStatus) {
this.titleForm.title = this.chart.title
}
}
},
init() {
@ -104,15 +111,17 @@ export default {
this.fontSize = arr
},
changeTitleStyle() {
if (this.titleForm.title.length < 1) {
this.$error(this.$t('chart.title_cannot_empty'))
this.titleForm.title = this.chart.title
return
}
if (checkViewTitle('update', this.chart.id, this.titleForm.title)) {
this.$error(this.$t('chart.title_repeat'))
this.titleForm.title = this.chart.title
return
if (!this.batchOptStatus) {
if (this.titleForm.title.length < 1) {
this.$error(this.$t('chart.title_cannot_empty'))
this.titleForm.title = this.chart.title
return
}
if (checkViewTitle('update', this.chart.id, this.titleForm.title)) {
this.$error(this.$t('chart.title_repeat'))
this.titleForm.title = this.chart.title
return
}
}
this.$emit('onTextChange', this.titleForm)
},

View File

@ -1,5 +1,6 @@
<template>
<span>
<span style="position: relative;display: inline-block;">
<i class="el-icon-arrow-down el-icon-delete" style="position: absolute;top: 6px;right: 24px;color: #878d9f;cursor: pointer;z-index: 1;" @click="removeItem" />
<el-dropdown trigger="click" size="mini" @command="clickItem">
<span class="el-dropdown-link">
<el-tag size="small" class="item-axis" :type="tagType">
@ -177,7 +178,6 @@ export default {
}
},
sort(param) {
// console.log(param)
this.item.sort = param.type
this.$emit('onItemChange', this.item)
},
@ -187,7 +187,6 @@ export default {
}
},
summary(param) {
// console.log(param)
this.item.summary = param.type
this.$emit('onItemChange', this.item)
},
@ -202,7 +201,6 @@ export default {
},
dateStyle(param) {
// console.log(param)
this.item.dateStyle = param.type
this.$emit('onItemChange', this.item)
},
@ -212,7 +210,6 @@ export default {
}
},
datePattern(param) {
// console.log(param)
this.item.datePattern = param.type
this.$emit('onItemChange', this.item)
},

View File

@ -1,5 +1,6 @@
<template>
<span>
<span style="position: relative;display: inline-block;">
<i class="el-icon-arrow-down el-icon-delete" style="position: absolute;top: 6px;right: 24px;color: #878d9f;cursor: pointer;z-index: 1;" @click="removeItem" />
<el-dropdown trigger="click" size="mini" @command="clickItem">
<span class="el-dropdown-link">
<el-tag size="small" class="item-axis" :type="tagType">
@ -157,7 +158,6 @@ export default {
}
},
sort(param) {
// console.log(param)
this.item.sort = param.type
this.$emit('onDimensionItemChange', this.item)
},
@ -167,7 +167,6 @@ export default {
}
},
dateStyle(param) {
// console.log(param)
this.item.dateStyle = param.type
this.$emit('onDimensionItemChange', this.item)
},

View File

@ -1,6 +1,6 @@
<template>
<span style="position: relative;display: inline-block;">
<i v-show="false" class="el-icon-arrow-down el-icon-delete" style="position: absolute;top: 6px;right: 24px;color: #878d9f;cursor: pointer;z-index: 1;" @click="removeItem" />
<i class="el-icon-arrow-down el-icon-delete" style="position: absolute;top: 6px;right: 24px;color: #878d9f;cursor: pointer;z-index: 1;" @click="removeItem" />
<el-dropdown trigger="click" size="mini" @command="clickItem">
<span class="el-dropdown-link">
<el-tag size="small" class="item-axis" :type="tagType">
@ -181,7 +181,6 @@ export default {
}
},
sort(param) {
// console.log(param)
if (param.type === 'custom_sort') {
const item = {
index: this.index,
@ -201,7 +200,6 @@ export default {
}
},
dateStyle(param) {
// console.log(param)
this.item.dateStyle = param.type
this.$emit('onDimensionItemChange', this.item)
},
@ -211,7 +209,6 @@ export default {
}
},
datePattern(param) {
// console.log(param)
this.item.datePattern = param.type
this.$emit('onDimensionItemChange', this.item)
},

View File

@ -1,5 +1,6 @@
<template>
<span>
<span style="position: relative;display: inline-block;">
<i class="el-icon-arrow-down el-icon-delete" style="position: absolute;top: 6px;right: 24px;color: #878d9f;cursor: pointer;z-index: 1;" @click="removeItem" />
<el-dropdown trigger="click" size="mini" @command="clickItem">
<span class="el-dropdown-link">
<el-tag size="small" class="item-axis" :type="tagType">

View File

@ -1,5 +1,6 @@
<template>
<span>
<span style="position: relative;display: inline-block;">
<i class="el-icon-arrow-down el-icon-delete" style="position: absolute;top: 6px;right: 24px;color: #878d9f;cursor: pointer;z-index: 1;" @click="removeItem" />
<el-dropdown trigger="click" size="mini" @command="clickItem">
<span class="el-dropdown-link">
<el-tag size="small" class="item-axis" :type="tagType">

View File

@ -1,5 +1,6 @@
<template>
<span>
<span style="position: relative;display: inline-block;">
<i class="el-icon-arrow-down el-icon-delete" style="position: absolute;top: 6px;right: 24px;color: #878d9f;cursor: pointer;z-index: 1;" @click="removeItem" />
<el-dropdown trigger="click" size="mini" @command="clickItem">
<span class="el-dropdown-link">
<el-tag size="small" class="item-axis" :type="tagType">
@ -232,7 +233,6 @@ export default {
},
summary(param) {
// console.log(param)
this.item.summary = param.type
this.$emit('onQuotaItemChange', this.item)
},
@ -243,7 +243,6 @@ export default {
},
switchChartType(param) {
// console.log(param)
this.item.chartType = param.type
this.$emit('onQuotaItemChange', this.item)
},
@ -273,7 +272,6 @@ export default {
},
sort(param) {
// console.log(param)
this.item.sort = param.type
this.$emit('onQuotaItemChange', this.item)
},
@ -349,7 +347,7 @@ export default {
margin-left: 4px;
color: #878d9f;
position: absolute;
right: 25px;
right: 40px;
}
.inner-dropdown-menu{

View File

@ -1,5 +1,6 @@
<template>
<span>
<span style="position: relative;display: inline-block;">
<i class="el-icon-arrow-down el-icon-delete" style="position: absolute;top: 6px;right: 24px;color: #878d9f;cursor: pointer;z-index: 1;" @click="removeItem" />
<el-dropdown trigger="click" size="mini" @command="clickItem">
<span class="el-dropdown-link">
<el-tag size="small" class="item-axis" :type="tagType">
@ -228,7 +229,6 @@ export default {
},
summary(param) {
// console.log(param)
this.item.summary = param.type
this.$emit('onQuotaItemChange', this.item)
},
@ -239,7 +239,6 @@ export default {
},
switchChartType(param) {
// console.log(param)
this.item.chartType = param.type
this.$emit('onQuotaItemChange', this.item)
},
@ -269,7 +268,6 @@ export default {
},
sort(param) {
// console.log(param)
this.item.sort = param.type
this.$emit('onQuotaItemChange', this.item)
},
@ -345,7 +343,7 @@ export default {
margin-left: 4px;
color: #878d9f;
position: absolute;
right: 25px;
right: 40px;
}
.inner-dropdown-menu{

View File

@ -235,7 +235,6 @@ export default {
value: 0
}
}
console.log(this.pointParam)
this.$refs['textData'].offsetTop
if (this.trackMenu.length < 2) { //
this.trackClick(this.trackMenu[0])

View File

@ -280,12 +280,10 @@ export default {
const table = document.getElementsByClassName(this.chart.id)
for (let i = 0; i < table.length; i++) {
const s_table = table[i].getElementsByClassName('elx-table--footer')
// console.log(s_table)
let s = ''
for (const i in this.table_header_class) {
s += (i === 'fontSize' ? 'font-size' : i) + ':' + this.table_header_class[i] + ';'
}
// console.log(s_table)
for (let i = 0; i < s_table.length; i++) {
s_table[i].setAttribute('style', s)
}

View File

@ -1018,11 +1018,9 @@ import ValueFormatterEdit from '@/views/chart/components/value-formatter/ValueFo
import ChartStyle from '@/views/chart/view/ChartStyle'
import CustomSortEdit from '@/views/chart/components/compare/CustomSortEdit'
import { TYPE_CONFIGS } from '@/views/chart/chart/util'
import ChartStyleBack from '@/views/chart/view/ChartStyleBack'
export default {
name: 'ChartEdit',
components: {
ChartStyleBack,
CustomSortEdit,
ChartStyle,
ValueFormatterEdit,
@ -1062,6 +1060,11 @@ export default {
type: String,
required: false,
default: 'view'
},
editStatue: {
type: Boolean,
required: false,
default: false
}
},
data() {
@ -1167,8 +1170,8 @@ export default {
chartProperties() {
const _this = this
if (_this.chart && _this.chart.render) {
const viewConfig = TYPE_CONFIGS.filter(item => item.render === _this.chart.render && item.value === _this.chart.type)
if (viewConfig) {
const viewConfig = this.allViewRender.filter(item => item.render === _this.chart.render && item.value === _this.chart.type)
if (viewConfig && viewConfig.length) {
return viewConfig[0].properties
} else {
return null
@ -1185,7 +1188,8 @@ export default {
},
...mapState([
'curComponent',
'panelViewEditInfo'
'panelViewEditInfo',
'allViewRender'
])
/* pluginRenderOptions() {
const plugins = localStorage.getItem('plugin-views') && JSON.parse(localStorage.getItem('plugin-views')) || []
@ -1196,13 +1200,18 @@ export default {
} */
},
watch: {
'editStatue': function(val) {
if (val && this.param.id !== this.preChartId) {
this.preChartId = this.param.id
this.chartInit()
}
},
'param': function(val) {
if (this.param.optType === 'new') {
//
} else if (this.param.id !== this.preChartId) {
} else if (this.param.id !== this.preChartId && this.editStatue) {
this.preChartId = this.param.id
this.chartInit()
// console.log('fromwatch:' + JSON.stringify(val))
}
},
searchField(val) {
@ -1237,7 +1246,6 @@ export default {
this.bindPluginEvent()
this.initFromPanel()
this.chartInit()
// console.log('mounted')
},
activated() {
},
@ -1251,7 +1259,6 @@ export default {
this.pluginRenderOptions = [...this.renderOptions, ...pluginOptions]
},
emptyTableData(id) {
console.log('emptyTableData:' + id)
this.table = {}
this.dimension = []
this.quota = []
@ -1560,7 +1567,6 @@ export default {
// echart
// this.chart = response.data
// this.data = response.data.data
// // console.log(JSON.stringify(this.chart))
// this.httpRequest.status = true
// if (this.chart.privileges) {
// this.param.privileges = this.chart.privileges
@ -1667,7 +1673,6 @@ export default {
// echart
this.chart = response.data
this.data = response.data.data
// console.log(JSON.stringify(this.chart))
this.httpRequest.status = true
if (this.chart.privileges) {
this.param.privileges = this.chart.privileges
@ -1732,7 +1737,6 @@ export default {
// move
onMove(e, originalEvent) {
// console.log(e)
this.moveId = e.draggedContext.element.id
return true
},

View File

@ -12,7 +12,7 @@
style="overflow:auto;border-right: 1px solid #e6e6e6;height: 100%;width: 100%;padding-right: 6px"
class="attr-style theme-border-class"
>
<el-row v-if="chart.mode!=='batchOpt'" class="padding-lr">
<el-row v-if="!batchOptStatus" class="padding-lr">
<span class="title-text">{{ $t('chart.style_priority') }}</span>
<el-row>
<el-radio-group
@ -274,6 +274,7 @@ import LegendSelectorAntV from '@/views/chart/components/component-style/LegendS
import BackgroundColorSelector from '@/views/chart/components/component-style/BackgroundColorSelector'
import SplitSelector from '@/views/chart/components/component-style/SplitSelector'
import SplitSelectorAntV from '@/views/chart/components/component-style/SplitSelectorAntV'
import { mapState } from 'vuex'
export default {
name: 'ChartStyle',
@ -321,7 +322,9 @@ export default {
}
},
computed: {
...mapState([
'batchOptStatus'
])
},
created() {

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