forked from github/dataease
refactor: 冲突
This commit is contained in:
commit
fa06823e44
@ -118,6 +118,7 @@ public class ShiroServiceImpl implements ShiroService {
|
||||
|
||||
filterChainDefinitionMap.put("/api/link/resourceDetail/**", "link");
|
||||
filterChainDefinitionMap.put("/api/link/viewDetail/**", "link");
|
||||
filterChainDefinitionMap.put("/api/link/viewLog", "link");
|
||||
filterChainDefinitionMap.put("/panel/group/exportDetails", ANON);
|
||||
filterChainDefinitionMap.put("/dataset/field/linkMultFieldValues", "link");
|
||||
filterChainDefinitionMap.put("/dataset/field/linkMappingFieldValues", "link");
|
||||
|
@ -37,6 +37,7 @@ public class SysLogConstants {
|
||||
UNBIND(17, "OPERATE_TYPE_UNBIND");
|
||||
private Integer value;
|
||||
private String name;
|
||||
|
||||
OPERATE_TYPE(Integer value, String name) {
|
||||
this.value = value;
|
||||
this.name = name;
|
||||
@ -62,7 +63,7 @@ public class SysLogConstants {
|
||||
DATASET(2, "SOURCE_TYPE_DATASET"),
|
||||
PANEL(3, "SOURCE_TYPE_PANEL"),
|
||||
VIEW(4, "SOURCE_TYPE_VIEW"),
|
||||
/*LINK(5, "SOURCE_TYPE_LINK"),*/
|
||||
LINK(5, "SOURCE_TYPE_LINK"),
|
||||
USER(6, "SOURCE_TYPE_USER"),
|
||||
DEPT(7, "SOURCE_TYPE_DEPT"),
|
||||
ROLE(8, "SOURCE_TYPE_ROLE"),
|
||||
|
@ -34,14 +34,14 @@ public class DeLogUtils {
|
||||
DeLogUtils.logService = logService;
|
||||
}
|
||||
|
||||
public static SysLogDTO buildLog(OPERATE_TYPE operatetype, SOURCE_TYPE sourcetype, Object sourceIdValue, Object targetId, SOURCE_TYPE target_type ) {
|
||||
public static SysLogDTO buildLog(OPERATE_TYPE operatetype, SOURCE_TYPE sourcetype, Object sourceIdValue, Object targetId, SOURCE_TYPE target_type) {
|
||||
SysLogDTO sysLogDTO = buildLog(operatetype, sourcetype, sourceIdValue, null, targetId, target_type);
|
||||
if (sourcetype == SysLogConstants.SOURCE_TYPE.DATASOURCE) {
|
||||
FolderItem folderItem = logManager.dsTypeInfoById(sourceIdValue.toString());
|
||||
List<FolderItem> items = new ArrayList<>();
|
||||
items.add(folderItem);
|
||||
sysLogDTO.setPositions(items);
|
||||
}else {
|
||||
} else {
|
||||
List<FolderItem> parentsAndSelf = logManager.justParents(sourceIdValue.toString(), sourcetype);
|
||||
sysLogDTO.setPositions(parentsAndSelf);
|
||||
}
|
||||
@ -66,7 +66,7 @@ public class DeLogUtils {
|
||||
return sysLogDTO;
|
||||
}
|
||||
|
||||
public static SysLogDTO buildLog(OPERATE_TYPE operatetype, SOURCE_TYPE sourcetype, Object sourceIdValue, Object positionId, Object targetId, SOURCE_TYPE target_type ) {
|
||||
public static SysLogDTO buildLog(OPERATE_TYPE operatetype, SOURCE_TYPE sourcetype, Object sourceIdValue, Object positionId, Object targetId, SOURCE_TYPE target_type) {
|
||||
SysLogDTO sysLogDTO = new SysLogDTO();
|
||||
sysLogDTO.setOperateType(operatetype.getValue());
|
||||
sysLogDTO.setSourceType(sourcetype.getValue());
|
||||
@ -83,14 +83,14 @@ public class DeLogUtils {
|
||||
List<FolderItem> items = new ArrayList<>();
|
||||
items.add(folderItem);
|
||||
sysLogDTO.setPositions(items);
|
||||
}else {
|
||||
if(sourcetype == SOURCE_TYPE.DRIVER_FILE){
|
||||
} else {
|
||||
if (sourcetype == SOURCE_TYPE.DRIVER_FILE) {
|
||||
List<FolderItem> parentsAndSelf = logManager.parentsAndSelf(positionId.toString(), SOURCE_TYPE.DRIVER);
|
||||
sysLogDTO.setPositions(parentsAndSelf);
|
||||
}else if(sourcetype == SOURCE_TYPE.VIEW){
|
||||
} else if (sourcetype == SOURCE_TYPE.VIEW || sourcetype == SOURCE_TYPE.LINK) {
|
||||
List<FolderItem> parentsAndSelf = logManager.parentsAndSelf(positionId.toString(), SOURCE_TYPE.PANEL);
|
||||
sysLogDTO.setPositions(parentsAndSelf);
|
||||
}else {
|
||||
} else {
|
||||
List<FolderItem> parentsAndSelf = logManager.parentsAndSelf(positionId.toString(), sourcetype);
|
||||
sysLogDTO.setPositions(parentsAndSelf);
|
||||
}
|
||||
|
45
backend/src/main/java/io/dataease/commons/utils/IPUtils.java
Normal file
45
backend/src/main/java/io/dataease/commons/utils/IPUtils.java
Normal file
@ -0,0 +1,45 @@
|
||||
package io.dataease.commons.utils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class IPUtils {
|
||||
|
||||
private static final String HEAD_KEYS = "x-forwarded-for, Proxy-Client-IP, WL-Proxy-Client-IP";
|
||||
|
||||
private static final String UNKNOWN = "unknown";
|
||||
|
||||
private static final String LOCAL_IP_KEY = "0:0:0:0:0:0:0:1";
|
||||
private static final String LOCAL_IP_VAL = "127.0.0.1";
|
||||
|
||||
public static String get() {
|
||||
|
||||
String ipStr = null;
|
||||
boolean isProxy = false;
|
||||
|
||||
HttpServletRequest request = null;
|
||||
try {
|
||||
request = ServletUtils.request();
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
String[] keyArr = HEAD_KEYS.split(",");
|
||||
for (String key : keyArr) {
|
||||
String header = request.getHeader(key.trim());
|
||||
if (StringUtils.isNotBlank(header) && !StringUtils.equalsIgnoreCase(UNKNOWN, header)) {
|
||||
ipStr = header;
|
||||
isProxy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isProxy) {
|
||||
ipStr = request.getRemoteAddr();
|
||||
}
|
||||
ipStr = Arrays.stream(ipStr.split(",")).filter(item -> StringUtils.isNotBlank(item) && !StringUtils.equalsIgnoreCase(UNKNOWN, item.trim())).findFirst().orElse(ipStr);
|
||||
return StringUtils.equals(LOCAL_IP_KEY, ipStr) ? LOCAL_IP_VAL : ipStr;
|
||||
}
|
||||
}
|
@ -4,12 +4,14 @@ import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.dataease.auth.annotation.DePermission;
|
||||
import io.dataease.commons.constants.DePermissionType;
|
||||
import io.dataease.controller.request.chart.ChartExtRequest;
|
||||
import io.dataease.controller.request.panel.PanelViewLogRequest;
|
||||
import io.dataease.controller.request.panel.link.*;
|
||||
import io.dataease.dto.panel.link.GenerateDto;
|
||||
import io.dataease.dto.panel.link.ValidateDto;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -58,9 +60,15 @@ public interface LinkApi {
|
||||
@ApiOperation("视图详细信息")
|
||||
@PostMapping("/viewDetail/{viewId}/{panelId}")
|
||||
Object viewDetail(@PathVariable("viewId") String viewId, @PathVariable("panelId") String panelId,
|
||||
@RequestBody ChartExtRequest requestList) throws Exception;
|
||||
@RequestBody ChartExtRequest requestList) throws Exception;
|
||||
|
||||
@ApiOperation("压缩链接")
|
||||
@PostMapping("/shortUrl")
|
||||
String shortUrl(@RequestBody Map<String, String> param);
|
||||
|
||||
@ApiIgnore
|
||||
@PostMapping("/viewLog")
|
||||
void viewLinkLog(@RequestBody LinkViewLogRequest request);
|
||||
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ package io.dataease.controller.panel.server;
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import io.dataease.auth.filter.F2CLinkFilter;
|
||||
import io.dataease.commons.constants.SysLogConstants;
|
||||
import io.dataease.commons.utils.DeLogUtils;
|
||||
import io.dataease.plugins.common.base.domain.PanelGroupWithBLOBs;
|
||||
import io.dataease.plugins.common.base.domain.PanelLink;
|
||||
import io.dataease.controller.panel.api.LinkApi;
|
||||
import io.dataease.controller.request.chart.ChartExtRequest;
|
||||
@ -111,4 +114,19 @@ public class LinkServer implements LinkApi {
|
||||
String resourceId = param.get("resourceId");
|
||||
return panelLinkService.getShortUrl(resourceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void viewLinkLog(LinkViewLogRequest request) {
|
||||
String panelId = request.getPanelId();
|
||||
Boolean mobile = request.getMobile();
|
||||
Long userId = request.getUserId();
|
||||
SysLogConstants.OPERATE_TYPE operateType = SysLogConstants.OPERATE_TYPE.PC_VIEW;
|
||||
if (ObjectUtils.isNotEmpty(mobile) && mobile) {
|
||||
operateType = SysLogConstants.OPERATE_TYPE.MB_VIEW;
|
||||
}
|
||||
if (ObjectUtils.isEmpty(userId)) return;
|
||||
PanelGroupWithBLOBs panelGroupWithBLOBs = panelLinkService.resourceInfo(panelId);
|
||||
String pid = panelGroupWithBLOBs.getPid();
|
||||
DeLogUtils.save(operateType, SysLogConstants.SOURCE_TYPE.LINK, panelId, pid, userId, SysLogConstants.SOURCE_TYPE.USER);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
package io.dataease.controller.request.panel.link;
|
||||
|
||||
import io.dataease.controller.request.panel.PanelViewLogRequest;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class LinkViewLogRequest extends PanelViewLogRequest implements Serializable {
|
||||
|
||||
private Long userId;
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package io.dataease.controller.sys;
|
||||
|
||||
import io.dataease.dto.UserLoginInfoDTO;
|
||||
import io.dataease.service.SystemInfoService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
|
||||
@ApiIgnore
|
||||
@RestController
|
||||
@RequestMapping("systemInfo")
|
||||
public class SystemInfoController {
|
||||
@Resource
|
||||
private SystemInfoService systemInfoService;
|
||||
|
||||
@GetMapping("userLoginInfo")
|
||||
public UserLoginInfoDTO userLoginInfo() throws IOException {
|
||||
return systemInfoService.getUserLoginInfo();
|
||||
}
|
||||
}
|
@ -22,4 +22,7 @@ public class SysLogGridDTO implements Serializable {
|
||||
|
||||
@ApiModelProperty("操作时间")
|
||||
private Long time;
|
||||
|
||||
@ApiModelProperty("IP地址")
|
||||
private String ip;
|
||||
}
|
||||
|
25
backend/src/main/java/io/dataease/dto/UserLoginInfoDTO.java
Normal file
25
backend/src/main/java/io/dataease/dto/UserLoginInfoDTO.java
Normal file
@ -0,0 +1,25 @@
|
||||
package io.dataease.dto;
|
||||
|
||||
import io.dataease.auth.api.dto.CurrentUserDto;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Author: wangjiahao
|
||||
* Date: 2022/11/10
|
||||
* Description:
|
||||
*/
|
||||
@Data
|
||||
public class UserLoginInfoDTO {
|
||||
|
||||
private CurrentUserDto userInfo;
|
||||
|
||||
private String ip;
|
||||
|
||||
public UserLoginInfoDTO() {
|
||||
}
|
||||
|
||||
public UserLoginInfoDTO(CurrentUserDto userInfo, String ip) {
|
||||
this.userInfo = userInfo;
|
||||
this.ip = ip;
|
||||
}
|
||||
}
|
@ -18,12 +18,13 @@ public class VAuthModelDTO extends VAuthModelWithBLOBs implements ITreeBase<VAut
|
||||
|
||||
private List<VAuthModelDTO> children;
|
||||
|
||||
private long allLeafs = 0l;
|
||||
private long allLeafs = 0L;
|
||||
|
||||
private String innerId;
|
||||
|
||||
private Boolean isPlugin = false;
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return this.getName();
|
||||
}
|
||||
|
@ -2,9 +2,11 @@ package io.dataease.dto.panel;
|
||||
|
||||
import io.dataease.dto.chart.ChartViewDTO;
|
||||
import io.dataease.plugins.common.base.domain.PanelGroupWithBLOBs;
|
||||
import io.dataease.plugins.common.base.domain.PanelWatermark;
|
||||
import io.dataease.plugins.common.model.ITreeBase;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -43,4 +45,7 @@ public class PanelGroupDTO extends PanelGroupWithBLOBs implements ITreeBase<Pane
|
||||
private String requestId;
|
||||
@ApiModelProperty("数据返回来源")
|
||||
private String responseSource;
|
||||
@ApiModelProperty("水印信息")
|
||||
private PanelWatermark watermarkInfo;
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package io.dataease.job.sechedule;
|
||||
|
||||
import com.fit2cloud.quartz.anno.QuartzScheduled;
|
||||
import io.dataease.commons.utils.LogUtil;
|
||||
import io.dataease.service.CleaningRebotService;
|
||||
import io.dataease.service.datasource.DatasourceService;
|
||||
import io.dataease.service.dataset.DataSetTableService;
|
||||
import io.dataease.service.kettle.KettleService;
|
||||
@ -17,6 +19,9 @@ public class Schedular {
|
||||
@Resource
|
||||
private KettleService kettleService;
|
||||
|
||||
@Resource
|
||||
private CleaningRebotService cleaningRebotService;
|
||||
|
||||
@QuartzScheduled(cron = "0 0/3 * * * ?")
|
||||
public void updateDatasetTableStatus() {
|
||||
dataSetTableService.updateDatasetTableStatus();
|
||||
@ -32,4 +37,10 @@ public class Schedular {
|
||||
kettleService.updateKettleStatus();
|
||||
}
|
||||
|
||||
@QuartzScheduled(cron = "0 0 0 ? * *")
|
||||
public void cheanDisusedData() {
|
||||
LogUtil.info("start execute clean task...");
|
||||
cleaningRebotService.execute();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
@ -40,20 +41,20 @@ public class PluginCommonServer {
|
||||
BufferedInputStream bis = null;
|
||||
InputStream inputStream = null;
|
||||
OutputStream os = null; //输出流
|
||||
try{
|
||||
try {
|
||||
inputStream = service.vueResource(jsName);
|
||||
byte[] buffer = new byte[1024];
|
||||
os = response.getOutputStream();
|
||||
bis = new BufferedInputStream(inputStream);
|
||||
int i = bis.read(buffer);
|
||||
while(i != -1){
|
||||
while (i != -1) {
|
||||
os.write(buffer, 0, i);
|
||||
i = bis.read(buffer);
|
||||
}
|
||||
os.flush();
|
||||
}catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
} finally {
|
||||
try {
|
||||
bis.close();
|
||||
inputStream.close();
|
||||
@ -69,28 +70,28 @@ public class PluginCommonServer {
|
||||
|
||||
@GetMapping("/component/{componentName}")
|
||||
public void componentInfo(@PathVariable String componentName) {
|
||||
Map<String, PluginComponentService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType(PluginComponentService.class);
|
||||
beansOfType.values().stream().forEach(service -> {
|
||||
Map<String, PluginComponentService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType(PluginComponentService.class);
|
||||
beansOfType.values().stream().forEach(service -> {
|
||||
List<String> components = service.components();
|
||||
if (components.contains(componentName)) {
|
||||
HttpServletResponse response = ServletUtils.response();
|
||||
BufferedInputStream bis = null;
|
||||
InputStream inputStream = null;
|
||||
OutputStream os = null; //输出流
|
||||
try{
|
||||
try {
|
||||
inputStream = service.vueResource(componentName);
|
||||
byte[] buffer = new byte[1024];
|
||||
os = response.getOutputStream();
|
||||
bis = new BufferedInputStream(inputStream);
|
||||
int i = bis.read(buffer);
|
||||
while(i != -1){
|
||||
while (i != -1) {
|
||||
os.write(buffer, 0, i);
|
||||
i = bis.read(buffer);
|
||||
}
|
||||
os.flush();
|
||||
}catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
} finally {
|
||||
try {
|
||||
bis.close();
|
||||
inputStream.close();
|
||||
@ -101,7 +102,7 @@ public class PluginCommonServer {
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@GetMapping("/staticInfo/{name}/{suffix}")
|
||||
@ -115,22 +116,24 @@ public class PluginCommonServer {
|
||||
BufferedInputStream bis = null;
|
||||
InputStream inputStream = null;
|
||||
OutputStream os = null; //输出流
|
||||
try{
|
||||
try {
|
||||
inputStream = service.vueResource(name, suffix);
|
||||
byte[] buffer = new byte[1024];
|
||||
os = response.getOutputStream();
|
||||
bis = new BufferedInputStream(inputStream);
|
||||
int i = bis.read(buffer);
|
||||
while(i != -1){
|
||||
while (i != -1) {
|
||||
os.write(buffer, 0, i);
|
||||
i = bis.read(buffer);
|
||||
}
|
||||
if (suffix.indexOf("svg") != -1)
|
||||
response.setContentType("image/svg+xml");
|
||||
if (suffix.indexOf("png") != -1)
|
||||
response.setContentType("image/png");
|
||||
os.flush();
|
||||
}catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
} finally {
|
||||
try {
|
||||
bis.close();
|
||||
inputStream.close();
|
||||
|
@ -0,0 +1,33 @@
|
||||
package io.dataease.plugins.server;
|
||||
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
import io.dataease.plugins.xpack.watermark.WatermarkService;
|
||||
import io.dataease.plugins.xpack.watermark.dto.PanelWatermarkDTO;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
/**
|
||||
* Author: wangjiahao
|
||||
* Date: 2022/11/11
|
||||
* Description:
|
||||
*/
|
||||
@ApiIgnore
|
||||
@RequestMapping("/plugin/watermark")
|
||||
@RestController
|
||||
public class XWatermarkServer {
|
||||
|
||||
@ApiOperation("查询水印配置")
|
||||
@GetMapping("/find")
|
||||
public PanelWatermarkDTO find() {
|
||||
WatermarkService userXpackService = SpringContextUtil.getBean(WatermarkService.class);
|
||||
return userXpackService.getWatermarkInfo();
|
||||
}
|
||||
|
||||
@ApiOperation("保存水印配置")
|
||||
@PostMapping("/save")
|
||||
public void save(@RequestBody PanelWatermarkDTO panelWatermark) {
|
||||
WatermarkService userXpackService = SpringContextUtil.getBean(WatermarkService.class);
|
||||
userXpackService.saveWatermarkInfo(panelWatermark);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package io.dataease.service;
|
||||
|
||||
import io.dataease.ext.CleaningRebotMapper;
|
||||
import io.dataease.service.message.SysMsgService;
|
||||
import io.dataease.service.sys.log.LogService;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -20,6 +21,9 @@ public class CleaningRebotService {
|
||||
@Resource
|
||||
private LogService logService;
|
||||
|
||||
@Resource
|
||||
private SysMsgService sysMsgService;
|
||||
|
||||
public void execute() {
|
||||
int floatDept = 0;
|
||||
do {
|
||||
@ -38,5 +42,6 @@ public class CleaningRebotService {
|
||||
cleaningRebotMapper.delFloatingCreatorLinkMapping();
|
||||
}
|
||||
logService.cleanDisusedLog();
|
||||
sysMsgService.cleanDisusedMsg();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
package io.dataease.service;
|
||||
|
||||
import io.dataease.commons.utils.AuthUtils;
|
||||
import io.dataease.commons.utils.IPUtils;
|
||||
import io.dataease.dto.UserLoginInfoDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
@Service
|
||||
public class SystemInfoService {
|
||||
|
||||
public UserLoginInfoDTO getUserLoginInfo() {
|
||||
return new UserLoginInfoDTO(AuthUtils.getUser(), IPUtils.get());
|
||||
}
|
||||
|
||||
}
|
@ -45,13 +45,10 @@ public class VAuthModelService {
|
||||
return result;
|
||||
}
|
||||
if (request.getPrivileges() != null) {
|
||||
result = result.stream().filter(vAuthModelDTO -> {
|
||||
if (vAuthModelDTO.getNodeType().equalsIgnoreCase("spine") || (vAuthModelDTO.getNodeType().equalsIgnoreCase("leaf") && vAuthModelDTO.getPrivileges() != null && vAuthModelDTO.getPrivileges().contains(request.getPrivileges()))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
result = result.stream().filter(vAuthModelDTO -> "spine".equalsIgnoreCase(vAuthModelDTO.getNodeType())
|
||||
|| ("leaf".equalsIgnoreCase(vAuthModelDTO.getNodeType())
|
||||
&& vAuthModelDTO.getPrivileges() != null
|
||||
&& vAuthModelDTO.getPrivileges().contains(request.getPrivileges()))).collect(Collectors.toList());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -60,10 +57,10 @@ public class VAuthModelService {
|
||||
if (CollectionUtils.isEmpty(result)) {
|
||||
return;
|
||||
}
|
||||
Iterator iterator = result.listIterator();
|
||||
Iterator<VAuthModelDTO> iterator = result.listIterator();
|
||||
while (iterator.hasNext()) {
|
||||
VAuthModelDTO tmp = (VAuthModelDTO) iterator.next();
|
||||
if (tmp.getNodeType().equalsIgnoreCase("spine") && tmp.getAllLeafs() == 0) {
|
||||
VAuthModelDTO tmp = iterator.next();
|
||||
if ("spine".equalsIgnoreCase(tmp.getNodeType()) && tmp.getAllLeafs() == 0) {
|
||||
iterator.remove();
|
||||
} else {
|
||||
removeEmptyDir(tmp.getChildren());
|
||||
@ -77,9 +74,9 @@ public class VAuthModelService {
|
||||
vAuthModelDTO.setAllLeafs(0);
|
||||
continue;
|
||||
}
|
||||
long leafs = 0l;
|
||||
long leafs = 0L;
|
||||
for (VAuthModelDTO child : vAuthModelDTO.getChildren()) {
|
||||
if (child.getNodeType().equalsIgnoreCase("leaf")) {
|
||||
if ("leaf".equalsIgnoreCase(child.getNodeType())) {
|
||||
leafs = leafs + 1;
|
||||
} else {
|
||||
leafs = +leafs + getLeafs(child);
|
||||
@ -90,13 +87,13 @@ public class VAuthModelService {
|
||||
}
|
||||
|
||||
private long getLeafs(VAuthModelDTO child) {
|
||||
long leafs = 0l;
|
||||
long leafs = 0L;
|
||||
if (CollectionUtils.isEmpty(child.getChildren())) {
|
||||
child.setAllLeafs(0);
|
||||
return leafs;
|
||||
}
|
||||
for (VAuthModelDTO childChild : child.getChildren()) {
|
||||
if (childChild.getNodeType().equalsIgnoreCase("leaf")) {
|
||||
if ("leaf".equalsIgnoreCase(childChild.getNodeType())) {
|
||||
leafs = leafs + 1;
|
||||
} else {
|
||||
leafs = +leafs + getLeafs(childChild);
|
||||
|
@ -577,7 +577,9 @@ public class ChartViewService {
|
||||
List<ChartViewFieldDTO> xAxisBase = gson.fromJson(view.getXAxis(), tokenType);
|
||||
List<ChartViewFieldDTO> xAxis = gson.fromJson(view.getXAxis(), tokenType);
|
||||
List<ChartViewFieldDTO> xAxisExt = gson.fromJson(view.getXAxisExt(), tokenType);
|
||||
if (StringUtils.equalsIgnoreCase(view.getType(), "table-pivot") || StringUtils.containsIgnoreCase(view.getType(), "group")) {
|
||||
if (StringUtils.equalsIgnoreCase(view.getType(), "table-pivot")
|
||||
|| StringUtils.containsIgnoreCase(view.getType(), "group")
|
||||
|| ("antv".equalsIgnoreCase(view.getRender()) && "line".equalsIgnoreCase(view.getType()))) {
|
||||
xAxis.addAll(xAxisExt);
|
||||
}
|
||||
List<ChartViewFieldDTO> yAxis = gson.fromJson(view.getYAxis(), tokenType);
|
||||
@ -698,7 +700,13 @@ public class ChartViewService {
|
||||
if (sqlVariables.stream().map(SqlVariableDetails::getVariableName).collect(Collectors.toList()).contains(parameter)) {
|
||||
hasParameters = true;
|
||||
}
|
||||
if (parameter.contains("|DE|") && table.getId().equals(parameter.split("\\|DE\\|")[0]) && sqlVariables.stream().map(SqlVariableDetails::getVariableName).collect(Collectors.toList()).contains(parameter.split("\\|DE\\|")[1])) {
|
||||
if (parameter.contains("|DE|")
|
||||
&& table.getId().equals(parameter.split("\\|DE\\|")[0])
|
||||
&& sqlVariables
|
||||
.stream()
|
||||
.map(SqlVariableDetails::getVariableName)
|
||||
.collect(Collectors.toList())
|
||||
.contains(parameter.split("\\|DE\\|")[1])) {
|
||||
hasParameters = true;
|
||||
}
|
||||
}
|
||||
@ -890,7 +898,7 @@ public class ChartViewService {
|
||||
if (ObjectUtils.isEmpty(ds)) {
|
||||
throw new RuntimeException(Translator.get("i18n_datasource_delete"));
|
||||
}
|
||||
if (StringUtils.isNotEmpty(ds.getStatus()) && ds.getStatus().equalsIgnoreCase("Error")) {
|
||||
if (StringUtils.isNotEmpty(ds.getStatus()) && "Error".equalsIgnoreCase(ds.getStatus())) {
|
||||
throw new Exception(Translator.get("i18n_invalid_ds"));
|
||||
}
|
||||
pageInfo.setDsVersion(datasourceProvider.dsVersion(ds));
|
||||
@ -899,8 +907,8 @@ public class ChartViewService {
|
||||
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
|
||||
if (StringUtils.equalsIgnoreCase(table.getType(), DatasetType.DB.name())) {
|
||||
datasourceRequest.setTable(dataTableInfoDTO.getTable());
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) {
|
||||
querySql = qp.getSQLSummary(dataTableInfoDTO.getTable(), yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, view, ds);
|
||||
if (StringUtils.equalsAnyIgnoreCase(view.getType(), "text", "gauge", "liquid")) {
|
||||
datasourceRequest.setQuery(qp.getSQLSummary(dataTableInfoDTO.getTable(), yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, view, ds));
|
||||
} else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) {
|
||||
querySql = qp.getSQLStack(dataTableInfoDTO.getTable(), xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, extStack, ds, view);
|
||||
} else if (StringUtils.containsIgnoreCase(view.getType(), "scatter")) {
|
||||
@ -914,7 +922,7 @@ public class ChartViewService {
|
||||
} else if (StringUtils.equalsIgnoreCase(table.getType(), DatasetType.SQL.name())) {
|
||||
String sql = dataTableInfoDTO.isBase64Encryption() ? new String(java.util.Base64.getDecoder().decode(dataTableInfoDTO.getSql())) : dataTableInfoDTO.getSql();
|
||||
sql = handleVariable(sql, chartExtRequest, qp, table, ds);
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) {
|
||||
if (StringUtils.equalsAnyIgnoreCase(view.getType(), "text", "gauge", "liquid")) {
|
||||
querySql = qp.getSQLSummaryAsTmp(sql, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, view);
|
||||
} else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) {
|
||||
querySql = qp.getSQLAsTmpStack(sql, xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, extStack, view);
|
||||
@ -930,7 +938,7 @@ public class ChartViewService {
|
||||
DataTableInfoDTO dt = gson.fromJson(table.getInfo(), DataTableInfoDTO.class);
|
||||
List<DataSetTableUnionDTO> list = dataSetTableUnionService.listByTableId(dt.getList().get(0).getTableId());
|
||||
String sql = dataSetTableService.getCustomSQLDatasource(dt, list, ds);
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) {
|
||||
if (StringUtils.equalsAnyIgnoreCase(view.getType(), "text", "gauge", "liquid")) {
|
||||
querySql = qp.getSQLSummaryAsTmp(sql, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, view);
|
||||
} else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) {
|
||||
querySql = qp.getSQLAsTmpStack(sql, xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, extStack, view);
|
||||
@ -946,8 +954,7 @@ public class ChartViewService {
|
||||
DataTableInfoDTO dt = gson.fromJson(table.getInfo(), DataTableInfoDTO.class);
|
||||
Map<String, Object> sqlMap = dataSetTableService.getUnionSQLDatasource(dt, ds);
|
||||
String sql = (String) sqlMap.get("sql");
|
||||
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) {
|
||||
if (StringUtils.equalsAnyIgnoreCase(view.getType(), "text", "gauge", "liquid")) {
|
||||
querySql = qp.getSQLSummaryAsTmp(sql, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, view);
|
||||
} else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) {
|
||||
querySql = qp.getSQLAsTmpStack(sql, xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, extStack, view);
|
||||
@ -979,7 +986,7 @@ public class ChartViewService {
|
||||
String tableName = "ds_" + table.getId().replaceAll("-", "_");
|
||||
datasourceRequest.setTable(tableName);
|
||||
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
|
||||
if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) {
|
||||
if (StringUtils.equalsAnyIgnoreCase(view.getType(), "text", "gauge", "liquid")) {
|
||||
datasourceRequest.setQuery(qp.getSQLSummary(tableName, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, view, ds));
|
||||
} else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) {
|
||||
datasourceRequest.setQuery(qp.getSQLStack(tableName, xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, extStack, ds, view));
|
||||
@ -999,7 +1006,9 @@ public class ChartViewService {
|
||||
if (!cache || CollectionUtils.isNotEmpty(chartExtRequest.getFilter())
|
||||
|| CollectionUtils.isNotEmpty(chartExtRequest.getLinkageFilters())
|
||||
|| CollectionUtils.isNotEmpty(chartExtRequest.getOuterParamsFilters())
|
||||
|| CollectionUtils.isNotEmpty(chartExtRequest.getDrill()) || CollectionUtils.isNotEmpty(rowPermissionsTree) || fields.size() != columnPermissionFields.size()) {
|
||||
|| CollectionUtils.isNotEmpty(chartExtRequest.getDrill())
|
||||
|| CollectionUtils.isNotEmpty(rowPermissionsTree)
|
||||
|| fields.size() != columnPermissionFields.size()) {
|
||||
data = datasourceProvider.getData(datasourceRequest);
|
||||
} else {
|
||||
try {
|
||||
@ -1151,7 +1160,7 @@ public class ChartViewService {
|
||||
mapChart = ChartDataBuild.transChartData(xAxis, yAxis, view, data, isDrill);
|
||||
}
|
||||
} else if (StringUtils.equalsIgnoreCase(view.getRender(), "antv")) {
|
||||
if (StringUtils.equalsIgnoreCase(view.getType(), "bar-group")) {
|
||||
if (StringUtils.equalsAnyIgnoreCase(view.getType(), "bar-group","line")) {
|
||||
mapChart = ChartDataBuild.transBaseGroupDataAntV(xAxisBase, xAxis, xAxisExt, yAxis, view, data, isDrill);
|
||||
} else if (StringUtils.equalsIgnoreCase(view.getType(), "bar-group-stack")) {
|
||||
mapChart = ChartDataBuild.transGroupStackDataAntV(xAxisBase, xAxis, xAxisExt, yAxis, extStack, data, view, isDrill);
|
||||
|
@ -158,7 +158,11 @@ public class ChartDataBuild {
|
||||
} catch (Exception e) {
|
||||
axisChartDataDTO.setValue(new BigDecimal(0));
|
||||
}
|
||||
axisChartDataDTO.setCategory(b.toString());
|
||||
if ("line".equals(view.getType()) && CollectionUtils.isEmpty(xAxisExt)) {
|
||||
axisChartDataDTO.setCategory(yAxis.get(j).getName());
|
||||
} else {
|
||||
axisChartDataDTO.setCategory(b.toString());
|
||||
}
|
||||
dataList.add(axisChartDataDTO);
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ public class DataSetTableService {
|
||||
@Value("${upload.file.path}")
|
||||
private String path;
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(ClassloaderResponsity.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(ClassloaderResponsity.class);
|
||||
|
||||
@DeCleaner(value = DePermissionType.DATASET, key = "sceneId")
|
||||
public List<DatasetTable> batchInsert(List<DataSetTableRequest> datasetTable) throws Exception {
|
||||
@ -185,7 +185,7 @@ public class DataSetTableService {
|
||||
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
@DeCleaner(value = DePermissionType.DATASET, key = "sceneId")
|
||||
public List<DatasetTable> saveExcel(DataSetTableRequest datasetTable) throws Exception {
|
||||
public List<DatasetTable> saveExcel(DataSetTableRequest datasetTable) {
|
||||
List<String> datasetIdList = new ArrayList<>();
|
||||
|
||||
if (StringUtils.isEmpty(datasetTable.getId())) {
|
||||
@ -234,10 +234,9 @@ public class DataSetTableService {
|
||||
list.add(sheetTable);
|
||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.CREATE, SysLogConstants.SOURCE_TYPE.DATASET, datasetTable.getId(), datasetTable.getSceneId(), null, null);
|
||||
}
|
||||
datasetIdList.forEach(datasetId -> {
|
||||
commonThreadPool.addTask(() -> extractDataService.extractExcelData(datasetId, "all_scope", "初始导入",
|
||||
null, datasetIdList));
|
||||
});
|
||||
datasetIdList.forEach(datasetId -> commonThreadPool.addTask(() ->
|
||||
extractDataService.extractExcelData(datasetId, "all_scope", "初始导入",
|
||||
null, datasetIdList)));
|
||||
} else {
|
||||
for (ExcelSheetData sheet : datasetTable.getSheets()) {
|
||||
String[] fieldArray = sheet.getFields().stream().map(TableField::getFieldName)
|
||||
@ -269,10 +268,9 @@ public class DataSetTableService {
|
||||
list.add(sheetTable);
|
||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.MODIFY, SysLogConstants.SOURCE_TYPE.DATASET, datasetTable.getId(), datasetTable.getSceneId(), null, null);
|
||||
}
|
||||
datasetIdList.forEach(datasetId -> {
|
||||
commonThreadPool.addTask(() -> extractDataService.extractExcelData(datasetId, "all_scope", "初始导入",
|
||||
null, datasetIdList));
|
||||
});
|
||||
datasetIdList.forEach(datasetId -> commonThreadPool.addTask(() ->
|
||||
extractDataService.extractExcelData(datasetId, "all_scope", "初始导入",
|
||||
null, datasetIdList)));
|
||||
}
|
||||
|
||||
return list;
|
||||
@ -303,15 +301,15 @@ public class DataSetTableService {
|
||||
DataTableInfoDTO info = new DataTableInfoDTO();
|
||||
info.setExcelSheetDataList(excelSheetDataList);
|
||||
datasetTable.setInfo(new Gson().toJson(info));
|
||||
int update = datasetTableMapper.updateByPrimaryKeySelective(datasetTable);
|
||||
datasetTableMapper.updateByPrimaryKeySelective(datasetTable);
|
||||
// 替換時,先不刪除旧字段;同步成功后再删除
|
||||
if (datasetTable.getEditType() == 0) {
|
||||
commonThreadPool.addTask(() -> extractDataService.extractExcelData(datasetTable.getId(), "all_scope", "替换",
|
||||
saveExcelTableField(datasetTable.getId(), datasetTable.getSheets().get(0).getFields(), false),
|
||||
Arrays.asList(datasetTable.getId())));
|
||||
Collections.singletonList(datasetTable.getId())));
|
||||
} else if (datasetTable.getEditType() == 1) {
|
||||
commonThreadPool.addTask(() -> extractDataService.extractExcelData(datasetTable.getId(), "add_scope", "追加",
|
||||
null, Arrays.asList(datasetTable.getId())));
|
||||
null, Collections.singletonList(datasetTable.getId())));
|
||||
}
|
||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.MODIFY, SysLogConstants.SOURCE_TYPE.DATASET, datasetTable.getId(), datasetTable.getSceneId(), null, null);
|
||||
return Collections.singletonList(datasetTable);
|
||||
@ -362,12 +360,12 @@ public class DataSetTableService {
|
||||
return datasetTable;
|
||||
}
|
||||
|
||||
public void alter(DataSetTableRequest request) throws Exception {
|
||||
public void alter(DataSetTableRequest request) {
|
||||
checkName(request);
|
||||
datasetTableMapper.updateByPrimaryKeySelective(request);
|
||||
}
|
||||
|
||||
public void delete(String id) throws Exception {
|
||||
public void delete(String id) {
|
||||
DatasetTable table = datasetTableMapper.selectByPrimaryKey(id);
|
||||
SysLogDTO sysLogDTO = DeLogUtils.buildLog(SysLogConstants.OPERATE_TYPE.DELETE, SysLogConstants.SOURCE_TYPE.DATASET, table.getId(), table.getSceneId(), null, null);
|
||||
datasetTableMapper.deleteByPrimaryKey(id);
|
||||
@ -489,9 +487,8 @@ public class DataSetTableService {
|
||||
List<DataSetTableDTO> res = new ArrayList<>();
|
||||
Map<String, DataSetTableDTO> map = new TreeMap<>();
|
||||
group.forEach(ele -> map.put(ele.getId(), ele));
|
||||
Iterator<Map.Entry<String, DataSetTableDTO>> iterator = map.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
res.add(iterator.next().getValue());
|
||||
for (Map.Entry<String, DataSetTableDTO> stringDataSetTableDTOEntry : map.entrySet()) {
|
||||
res.add(stringDataSetTableDTOEntry.getValue());
|
||||
}
|
||||
res.sort(Comparator.comparing(DatasetTable::getName));
|
||||
res.addAll(ds);
|
||||
@ -521,8 +518,7 @@ public class DataSetTableService {
|
||||
return datasourceProvider.getTableFields(datasourceRequest);
|
||||
}
|
||||
|
||||
public Map<String, List<DatasetTableField>> getFieldsFromDE(DataSetTableRequest dataSetTableRequest)
|
||||
throws Exception {
|
||||
public Map<String, List<DatasetTableField>> getFieldsFromDE(DataSetTableRequest dataSetTableRequest) {
|
||||
DatasetTableField datasetTableField = DatasetTableField.builder().build();
|
||||
datasetTableField.setTableId(dataSetTableRequest.getId());
|
||||
datasetTableField.setChecked(Boolean.TRUE);
|
||||
@ -1015,15 +1011,11 @@ public class DataSetTableService {
|
||||
break;
|
||||
case "TEXT":
|
||||
sqlVariableDetails = sqlVariableDetails.stream().filter(item -> item.getType().get(0).contains("TEXT")).collect(Collectors.toList());
|
||||
sqlVariableDetails.forEach(item -> {
|
||||
item.setAlias(item.getVariableName());
|
||||
});
|
||||
sqlVariableDetails.forEach(item -> item.setAlias(item.getVariableName()));
|
||||
break;
|
||||
case "NUM":
|
||||
sqlVariableDetails = sqlVariableDetails.stream().filter(item -> item.getType().get(0).contains("LONG") || item.getType().get(0).contains("DOUBLE")).collect(Collectors.toList());
|
||||
sqlVariableDetails.forEach(item -> {
|
||||
item.setAlias(item.getVariableName());
|
||||
});
|
||||
sqlVariableDetails.forEach(item -> item.setAlias(item.getVariableName()));
|
||||
break;
|
||||
}
|
||||
return sqlVariableDetails;
|
||||
@ -1087,15 +1079,15 @@ public class DataSetTableService {
|
||||
if (select.getSelectBody() instanceof PlainSelect) {
|
||||
return handlePlainSelect((PlainSelect) select.getSelectBody(), select, dsType);
|
||||
} else {
|
||||
String result = "";
|
||||
StringBuilder result = new StringBuilder();
|
||||
SetOperationList setOperationList = (SetOperationList) select.getSelectBody();
|
||||
for (int i = 0; i < setOperationList.getSelects().size(); i++) {
|
||||
result = result + handlePlainSelect((PlainSelect) setOperationList.getSelects().get(i), null, dsType);
|
||||
result.append(handlePlainSelect((PlainSelect) setOperationList.getSelects().get(i), null, dsType));
|
||||
if (i < setOperationList.getSelects().size() - 1) {
|
||||
result = result + " " + setOperationList.getOperations().get(i).toString() + " ";
|
||||
result.append(" ").append(setOperationList.getOperations().get(i).toString()).append(" ");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1140,14 +1132,14 @@ public class DataSetTableService {
|
||||
builder.append(" ");
|
||||
for (Iterator<WithItem> iter = select.getWithItemsList().iterator(); iter.hasNext(); ) {
|
||||
WithItem withItem = iter.next();
|
||||
builder.append(withItem.getName() + " AS ( " + removeVariables(withItem.getSubSelect().toString(), dsType) + " ) ");
|
||||
builder.append(withItem.getName()).append(" AS ( ").append(removeVariables(withItem.getSubSelect().toString(), dsType)).append(" ) ");
|
||||
if (iter.hasNext()) {
|
||||
builder.append(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builder.append(" " + plainSelect);
|
||||
builder.append(" ").append(plainSelect);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@ -1230,7 +1222,7 @@ public class DataSetTableService {
|
||||
String sqlAsTable = qp.createSQLPreview(sql, null);
|
||||
datasourceRequest.setQuery(sqlAsTable);
|
||||
|
||||
Map<String, List> result = new HashMap<>();
|
||||
Map<String, List> result;
|
||||
try {
|
||||
datasetSqlLog.setStartTime(System.currentTimeMillis());
|
||||
result = datasourceProvider.fetchResultAndField(datasourceRequest);
|
||||
@ -1275,7 +1267,7 @@ public class DataSetTableService {
|
||||
|
||||
public Map<String, Object> getUnionPreview(DataSetTableRequest dataSetTableRequest) throws Exception {
|
||||
DataTableInfoDTO dataTableInfoDTO = new Gson().fromJson(dataSetTableRequest.getInfo(), DataTableInfoDTO.class);
|
||||
Map<String, Object> sqlMap = new HashMap<>();
|
||||
Map<String, Object> sqlMap;
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
Datasource ds;
|
||||
if (dataSetTableRequest.getMode() == 0) {
|
||||
@ -1289,7 +1281,6 @@ public class DataSetTableService {
|
||||
}
|
||||
String sql = (String) sqlMap.get("sql");
|
||||
List<DatasetTableField> fieldList = (List<DatasetTableField>) sqlMap.get("field");
|
||||
List<UnionParamDTO> join = (List<UnionParamDTO>) sqlMap.get("join");
|
||||
|
||||
Map<String, Object> res = new HashMap<>();
|
||||
// 处理结果
|
||||
@ -1423,9 +1414,7 @@ public class DataSetTableService {
|
||||
DataTableInfoCustomUnion first = dataTableInfoDTO.getList().get(0);
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
StringBuilder field = new StringBuilder();
|
||||
Iterator<Map.Entry<String, String[]>> iterator = customInfo.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, String[]> next = iterator.next();
|
||||
for (Map.Entry<String, String[]> next : customInfo.entrySet()) {
|
||||
field.append(StringUtils.join(next.getValue(), ",")).append(",");
|
||||
}
|
||||
String f = field.substring(0, field.length() - 1);
|
||||
@ -1493,9 +1482,7 @@ public class DataSetTableService {
|
||||
String tableName = new Gson().fromJson(table.getInfo(), DataTableInfoDTO.class).getTable();
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
StringBuilder field = new StringBuilder();
|
||||
Iterator<Map.Entry<String, String[]>> iterator = customInfo.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, String[]> next = iterator.next();
|
||||
for (Map.Entry<String, String[]> next : customInfo.entrySet()) {
|
||||
field.append(StringUtils.join(next.getValue(), ",")).append(",");
|
||||
}
|
||||
String f = field.substring(0, field.length() - 1);
|
||||
@ -1601,9 +1588,7 @@ public class DataSetTableService {
|
||||
if (CollectionUtils.isNotEmpty(unionList)) {
|
||||
// field
|
||||
StringBuilder field = new StringBuilder();
|
||||
Iterator<Map.Entry<String, String[]>> iterator = checkedInfo.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, String[]> next = iterator.next();
|
||||
for (Map.Entry<String, String[]> next : checkedInfo.entrySet()) {
|
||||
field.append(StringUtils.join(next.getValue(), ",")).append(",");
|
||||
}
|
||||
String f = subPrefixSuffixChar(field.toString());
|
||||
@ -1664,8 +1649,7 @@ public class DataSetTableService {
|
||||
// 递归计算出所有子级的checkedFields和unionParam
|
||||
private void getUnionSQLDorisJoin(List<UnionDTO> childrenDs, Map<String, String[]> checkedInfo,
|
||||
List<UnionParamDTO> unionList, List<DatasetTableField> checkedFields) {
|
||||
for (int i = 0; i < childrenDs.size(); i++) {
|
||||
UnionDTO unionDTO = childrenDs.get(i);
|
||||
for (UnionDTO unionDTO : childrenDs) {
|
||||
String tableId = unionDTO.getCurrentDs().getId();
|
||||
String table = TableUtils.tableName(tableId);
|
||||
DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(tableId);
|
||||
@ -1752,9 +1736,7 @@ public class DataSetTableService {
|
||||
if (CollectionUtils.isNotEmpty(unionList)) {
|
||||
// field
|
||||
StringBuilder field = new StringBuilder();
|
||||
Iterator<Map.Entry<String, String[]>> iterator = checkedInfo.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, String[]> next = iterator.next();
|
||||
for (Map.Entry<String, String[]> next : checkedInfo.entrySet()) {
|
||||
field.append(StringUtils.join(next.getValue(), ",")).append(",");
|
||||
}
|
||||
String f = subPrefixSuffixChar(field.toString());
|
||||
@ -1825,9 +1807,7 @@ public class DataSetTableService {
|
||||
// 递归计算出所有子级的checkedFields和unionParam
|
||||
private void getUnionSQLDatasourceJoin(List<UnionDTO> childrenDs, Map<String, String[]> checkedInfo,
|
||||
List<UnionParamDTO> unionList, String keyword, List<DatasetTableField> checkedFields) {
|
||||
for (int i = 0; i < childrenDs.size(); i++) {
|
||||
UnionDTO unionDTO = childrenDs.get(i);
|
||||
|
||||
for (UnionDTO unionDTO : childrenDs) {
|
||||
DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(unionDTO.getCurrentDs().getId());
|
||||
String tableId = unionDTO.getCurrentDs().getId();
|
||||
if (ObjectUtils.isEmpty(datasetTable)) {
|
||||
@ -1976,7 +1956,7 @@ public class DataSetTableService {
|
||||
Map<String, Object> sqlMap = getUnionSQLDoris(dataTableInfoDTO);
|
||||
String sql = (String) sqlMap.get("sql");
|
||||
List<DatasetTableField> fieldList = (List<DatasetTableField>) sqlMap.get("field");
|
||||
List<UnionParamDTO> join = (List<UnionParamDTO>) sqlMap.get("join");
|
||||
|
||||
|
||||
// custom 创建doris视图
|
||||
createDorisView(TableUtils.tableName(datasetTable.getId()), sql);
|
||||
@ -2003,7 +1983,7 @@ public class DataSetTableService {
|
||||
Map<String, Object> sqlMap = getUnionSQLDatasource(dt, ds);
|
||||
String sql = (String) sqlMap.get("sql");
|
||||
List<DatasetTableField> fieldList = (List<DatasetTableField>) sqlMap.get("field");
|
||||
List<UnionParamDTO> join = (List<UnionParamDTO>) sqlMap.get("join");
|
||||
|
||||
|
||||
datasourceRequest.setQuery(sql);
|
||||
fields = datasourceProvider.fetchResultField(datasourceRequest);
|
||||
@ -2157,16 +2137,15 @@ public class DataSetTableService {
|
||||
private void checkColumes(DatasetTableIncrementalConfig datasetTableIncrementalConfig) throws Exception {
|
||||
DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(datasetTableIncrementalConfig.getTableId());
|
||||
List<DatasetTableField> datasetTableFields = dataSetTableFieldsService.getFieldsByTableId(datasetTable.getId())
|
||||
.stream().filter(datasetTableField -> datasetTableField.getExtField() == 0).collect(Collectors.toList());
|
||||
datasetTableFields.sort((o1, o2) -> {
|
||||
if (o1.getColumnIndex() == null) {
|
||||
return -1;
|
||||
}
|
||||
if (o2.getColumnIndex() == null) {
|
||||
return 1;
|
||||
}
|
||||
return o1.getColumnIndex().compareTo(o2.getColumnIndex());
|
||||
});
|
||||
.stream().filter(datasetTableField -> datasetTableField.getExtField() == 0).sorted((o1, o2) -> {
|
||||
if (o1.getColumnIndex() == null) {
|
||||
return -1;
|
||||
}
|
||||
if (o2.getColumnIndex() == null) {
|
||||
return 1;
|
||||
}
|
||||
return o1.getColumnIndex().compareTo(o2.getColumnIndex());
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
List<String> originNameFields = datasetTableFields.stream().map(DatasetTableField::getOriginName)
|
||||
.collect(Collectors.toList());
|
||||
@ -2184,9 +2163,7 @@ public class DataSetTableService {
|
||||
List<String> sqlFields = new ArrayList<>();
|
||||
try {
|
||||
datasourceProvider.fetchResultField(datasourceRequest).stream().map(TableField::getFieldName)
|
||||
.forEach(field -> {
|
||||
sqlFields.add(field);
|
||||
});
|
||||
.forEach(sqlFields::add);
|
||||
} catch (Exception e) {
|
||||
DataEaseException.throwException(Translator.get("i18n_check_sql_error") + e.getMessage());
|
||||
}
|
||||
@ -2204,7 +2181,7 @@ public class DataSetTableService {
|
||||
List<String> sqlFields = new ArrayList<>();
|
||||
try {
|
||||
datasourceProvider.fetchResultField(datasourceRequest).stream().map(TableField::getFieldName)
|
||||
.forEach(field -> sqlFields.add(field));
|
||||
.forEach(sqlFields::add);
|
||||
} catch (Exception e) {
|
||||
DataEaseException.throwException(Translator.get("i18n_check_sql_error") + e.getMessage());
|
||||
}
|
||||
@ -2228,7 +2205,7 @@ public class DataSetTableService {
|
||||
criteria.andNameEqualTo(datasetTable.getName());
|
||||
}
|
||||
List<DatasetTable> list = datasetTableMapper.selectByExample(datasetTableExample);
|
||||
if (list.size() > 0) {
|
||||
if (!list.isEmpty()) {
|
||||
throw new RuntimeException(Translator.get("i18n_name_cant_repeat_same_group"));
|
||||
}
|
||||
}
|
||||
@ -2253,7 +2230,7 @@ public class DataSetTableService {
|
||||
criteria.andNameIn(new ArrayList<>(nameSet));
|
||||
}
|
||||
List<DatasetTable> list = datasetTableMapper.selectByExample(datasetTableExample);
|
||||
if (list.size() > 0) {
|
||||
if (!list.isEmpty()) {
|
||||
throw new RuntimeException(Translator.get("i18n_name_cant_repeat_same_group"));
|
||||
}
|
||||
}
|
||||
@ -2278,8 +2255,7 @@ public class DataSetTableService {
|
||||
|
||||
if (StringUtils.isNotEmpty(tableId)) {
|
||||
List<DatasetTableField> fields = dataSetTableFieldsService.getFieldsByTableId(tableId);
|
||||
List<DatasetTableField> datasetTableFields = fields.stream().filter(datasetTableField -> datasetTableField.getExtField() == 0).collect(Collectors.toList());
|
||||
datasetTableFields.sort((o1, o2) -> {
|
||||
List<DatasetTableField> datasetTableFields = fields.stream().filter(datasetTableField -> datasetTableField.getExtField() == 0).sorted((o1, o2) -> {
|
||||
if (o1.getColumnIndex() == null) {
|
||||
return -1;
|
||||
}
|
||||
@ -2287,7 +2263,7 @@ public class DataSetTableService {
|
||||
return 1;
|
||||
}
|
||||
return o1.getColumnIndex().compareTo(o2.getColumnIndex());
|
||||
});
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
List<String> oldFields = datasetTableFields.stream().map(DatasetTableField::getOriginName).collect(Collectors.toList());
|
||||
|
||||
@ -2299,7 +2275,7 @@ public class DataSetTableService {
|
||||
returnSheetDataList.add(excelSheetData);
|
||||
}
|
||||
}
|
||||
if (returnSheetDataList.size() == 0) {
|
||||
if (returnSheetDataList.isEmpty()) {
|
||||
DataEaseException.throwException(Translator.get("i18n_excel_column_change"));
|
||||
}
|
||||
} else {
|
||||
@ -2321,22 +2297,19 @@ public class DataSetTableService {
|
||||
for (ExcelSheetData excelSheetData : excelSheetDataList) {
|
||||
List<TableField> tableFields = excelSheetData.getFields();
|
||||
List<String> newFields = tableFields.stream().map(TableField::getRemarks).collect(Collectors.toList());
|
||||
if (oldFields.equals(newFields)) {
|
||||
excelSheetData.setChangeFiled(false);
|
||||
} else {
|
||||
excelSheetData.setChangeFiled(true);
|
||||
}
|
||||
excelSheetData.setChangeFiled(!oldFields.equals(newFields));
|
||||
boolean effectExtField = false;
|
||||
for (String extFieldsRefName : extFieldsRefNames) {
|
||||
if (!newFields.contains(extFieldsRefName)) {
|
||||
effectExtField = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
excelSheetData.setEffectExtField(effectExtField);
|
||||
|
||||
returnSheetDataList.add(excelSheetData);
|
||||
}
|
||||
if (returnSheetDataList.size() == 0) {
|
||||
if (returnSheetDataList.isEmpty()) {
|
||||
DataEaseException.throwException(Translator.get("i18n_excel_column_change"));
|
||||
}
|
||||
}
|
||||
@ -2403,7 +2376,7 @@ public class DataSetTableService {
|
||||
}
|
||||
List<List<String>> data = new ArrayList<>();
|
||||
int num = 1;
|
||||
String line = null;
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (num > 100) {
|
||||
break;
|
||||
@ -2450,7 +2423,7 @@ public class DataSetTableService {
|
||||
try {
|
||||
double d = cell.getNumericCellValue();
|
||||
try {
|
||||
Double value = new Double(d);
|
||||
Double value = d;
|
||||
double eps = 1e-10;
|
||||
if (value - Math.floor(value) < eps) {
|
||||
if (cellType) {
|
||||
@ -2469,7 +2442,7 @@ public class DataSetTableService {
|
||||
return nf.format(value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
BigDecimal b = new BigDecimal(d);
|
||||
BigDecimal b = BigDecimal.valueOf(d);
|
||||
return b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() + "";
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
@ -2502,7 +2475,7 @@ public class DataSetTableService {
|
||||
} else {
|
||||
double d = cell.getNumericCellValue();
|
||||
try {
|
||||
Double value = new Double(d);
|
||||
Double value = d;
|
||||
double eps = 1e-10;
|
||||
if (value - Math.floor(value) < eps) {
|
||||
if (cellType) {
|
||||
@ -2521,7 +2494,7 @@ public class DataSetTableService {
|
||||
return nf.format(value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
BigDecimal b = new BigDecimal(d);
|
||||
BigDecimal b = BigDecimal.valueOf(d);
|
||||
return b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() + "";
|
||||
}
|
||||
}
|
||||
@ -2655,18 +2628,14 @@ public class DataSetTableService {
|
||||
* 判断数组中是否有重复的值
|
||||
*/
|
||||
public static boolean checkIsRepeat(String[] array) {
|
||||
HashSet<String> hashSet = new HashSet<String>();
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
if (StringUtils.isEmpty(array[i])) {
|
||||
HashSet<String> hashSet = new HashSet<>();
|
||||
for (String s : array) {
|
||||
if (StringUtils.isEmpty(s)) {
|
||||
throw new RuntimeException(Translator.get("i18n_excel_empty_column"));
|
||||
}
|
||||
hashSet.add(array[i]);
|
||||
}
|
||||
if (hashSet.size() == array.length) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
hashSet.add(s);
|
||||
}
|
||||
return hashSet.size() != array.length;
|
||||
}
|
||||
|
||||
public DatasetTable syncDatasetTableField(String id) throws Exception {
|
||||
@ -2857,7 +2826,7 @@ public class DataSetTableService {
|
||||
return expressionDeParser;
|
||||
}
|
||||
|
||||
static private boolean hasVariable(String sql) {
|
||||
private static boolean hasVariable(String sql) {
|
||||
return sql.contains(SubstitutedParams);
|
||||
}
|
||||
|
||||
@ -2886,6 +2855,7 @@ public class DataSetTableService {
|
||||
if (StringUtils.isNotEmpty(request.getExpressionTree())) {
|
||||
Gson gson = new Gson();
|
||||
tree = gson.fromJson(request.getExpressionTree(), DatasetRowPermissionsTreeObj.class);
|
||||
permissionsTreeService.getField(tree);
|
||||
}
|
||||
Map<String, Object> previewData = getPreviewData(request, 1, 100000, null, tree);
|
||||
List<DatasetTableField> fields = (List<DatasetTableField>) previewData.get("fields");
|
||||
@ -2935,7 +2905,7 @@ public class DataSetTableService {
|
||||
//设置列的宽度
|
||||
detailsSheet.setColumnWidth(j, 255 * 20);
|
||||
} else {
|
||||
if ((fields.get(j).getDeType() == DeTypeConstants.DE_INT || fields.get(j).getDeType() == DeTypeConstants.DE_FLOAT) && StringUtils.isNotEmpty(rowData.get(j))) {
|
||||
if ((fields.get(j).getDeType().equals(DeTypeConstants.DE_INT) || fields.get(j).getDeType() == DeTypeConstants.DE_FLOAT) && StringUtils.isNotEmpty(rowData.get(j))) {
|
||||
try {
|
||||
cell.setCellValue(Double.valueOf(rowData.get(j)));
|
||||
} catch (Exception e) {
|
||||
|
@ -153,7 +153,7 @@ public class PermissionsTreeService {
|
||||
return result;
|
||||
}
|
||||
|
||||
private void getField(DatasetRowPermissionsTreeObj tree) {
|
||||
public void getField(DatasetRowPermissionsTreeObj tree) {
|
||||
if (ObjectUtils.isNotEmpty(tree)) {
|
||||
if (ObjectUtils.isNotEmpty(tree.getItems())) {
|
||||
for (DatasetRowPermissionsTreeItem item : tree.getItems()) {
|
||||
|
@ -55,6 +55,13 @@ public class SysMsgService {
|
||||
@Autowired
|
||||
private SystemParameterService systemParameterService;
|
||||
|
||||
public void cleanDisusedMsg() {
|
||||
Long overTime = overTime();
|
||||
SysMsgExample example = new SysMsgExample();
|
||||
example.createCriteria().andCreateTimeLessThan(overTime);
|
||||
sysMsgMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
public List<MsgGridDto> queryGrid(Long userId, MsgRequest msgRequest, List<Long> typeIds, Long startTime) {
|
||||
String orderClause = " create_time desc";
|
||||
SysMsgExample example = new SysMsgExample();
|
||||
|
@ -29,6 +29,7 @@ import io.dataease.listener.util.CacheUtils;
|
||||
import io.dataease.plugins.common.base.domain.*;
|
||||
import io.dataease.plugins.common.base.mapper.*;
|
||||
import io.dataease.plugins.common.constants.DeTypeConstants;
|
||||
import io.dataease.service.SystemInfoService;
|
||||
import io.dataease.service.chart.ChartViewService;
|
||||
import io.dataease.service.dataset.DataSetGroupService;
|
||||
import io.dataease.service.dataset.DataSetTableService;
|
||||
@ -131,6 +132,10 @@ public class PanelGroupService {
|
||||
private DataSetGroupService dataSetGroupService;
|
||||
@Resource
|
||||
private DatasetGroupMapper datasetGroupMapper;
|
||||
@Resource
|
||||
private PanelWatermarkMapper panelWatermarkMapper;
|
||||
@Resource
|
||||
private SystemInfoService systemInfoService;
|
||||
|
||||
public List<PanelGroupDTO> tree(PanelGroupRequest panelGroupRequest) {
|
||||
String userId = String.valueOf(AuthUtils.getUser().getUserId());
|
||||
@ -304,6 +309,7 @@ public class PanelGroupService {
|
||||
panelGroup.setPanelStyle(sourcePanel.getPanelStyle());
|
||||
panelGroup.setSourcePanelName(sourcePanel.getName());
|
||||
}
|
||||
panelGroup.setWatermarkInfo(panelWatermarkMapper.selectByPrimaryKey("system_default"));
|
||||
return panelGroup;
|
||||
}
|
||||
|
||||
@ -750,7 +756,9 @@ public class PanelGroupService {
|
||||
if (cache == null) {
|
||||
return null;
|
||||
} else {
|
||||
return (PanelGroupRequest) cache;
|
||||
PanelGroupDTO result = (PanelGroupRequest) cache;
|
||||
result.setWatermarkInfo(panelWatermarkMapper.selectByPrimaryKey("system_default"));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,26 +4,26 @@ import io.dataease.auth.config.RsaProperties;
|
||||
import io.dataease.auth.util.JWTUtils;
|
||||
import io.dataease.auth.util.RsaUtil;
|
||||
import io.dataease.commons.constants.SysLogConstants;
|
||||
import io.dataease.commons.utils.AuthUtils;
|
||||
import io.dataease.commons.utils.CodingUtil;
|
||||
import io.dataease.commons.utils.DeLogUtils;
|
||||
import io.dataease.commons.utils.ServletUtils;
|
||||
import io.dataease.commons.utils.*;
|
||||
import io.dataease.controller.request.panel.link.EnablePwdRequest;
|
||||
import io.dataease.controller.request.panel.link.LinkRequest;
|
||||
import io.dataease.controller.request.panel.link.OverTimeRequest;
|
||||
import io.dataease.controller.request.panel.link.PasswordRequest;
|
||||
import io.dataease.dto.panel.PanelGroupDTO;
|
||||
import io.dataease.dto.panel.link.GenerateDto;
|
||||
import io.dataease.ext.ExtPanelLinkMapper;
|
||||
import io.dataease.plugins.common.base.domain.*;
|
||||
import io.dataease.plugins.common.base.mapper.PanelGroupMapper;
|
||||
import io.dataease.plugins.common.base.mapper.PanelLinkMapper;
|
||||
import io.dataease.plugins.common.base.mapper.PanelLinkMappingMapper;
|
||||
import io.dataease.plugins.common.base.mapper.PanelWatermarkMapper;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import io.dataease.ext.ExtPanelLinkMapper;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
@ -47,6 +47,8 @@ public class PanelLinkService {
|
||||
private ExtPanelLinkMapper extPanelLinkMapper;
|
||||
@Resource
|
||||
private PanelLinkMappingMapper panelLinkMappingMapper;
|
||||
@Resource
|
||||
private PanelWatermarkMapper panelWatermarkMapper;
|
||||
|
||||
@Transactional
|
||||
public void changeValid(LinkRequest request) {
|
||||
@ -67,7 +69,7 @@ public class PanelLinkService {
|
||||
if (!request.isValid()) {
|
||||
operateType = SysLogConstants.OPERATE_TYPE.DELETELINK;
|
||||
}
|
||||
DeLogUtils.save(operateType, SysLogConstants.SOURCE_TYPE.PANEL, panel.getId(), panel.getPid(), null, null) ;
|
||||
DeLogUtils.save(operateType, SysLogConstants.SOURCE_TYPE.PANEL, panel.getId(), panel.getPid(), null, null);
|
||||
}
|
||||
|
||||
private PanelLinkExample example(String panelLinkId, Long userId) {
|
||||
@ -82,7 +84,7 @@ public class PanelLinkService {
|
||||
po.setEnablePwd(request.isEnablePwd());
|
||||
mapper.updateByExampleSelective(po, example(request.getResourceId(), AuthUtils.getUser().getUserId()));
|
||||
PanelGroupWithBLOBs panel = panelGroupMapper.selectByPrimaryKey(request.getResourceId());
|
||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.MODIFYLINK, SysLogConstants.SOURCE_TYPE.PANEL, panel.getId(), panel.getPid(), null, null) ;
|
||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.MODIFYLINK, SysLogConstants.SOURCE_TYPE.PANEL, panel.getId(), panel.getPid(), null, null);
|
||||
}
|
||||
|
||||
public void password(PasswordRequest request) {
|
||||
@ -93,14 +95,14 @@ public class PanelLinkService {
|
||||
|
||||
|
||||
PanelGroupWithBLOBs panel = panelGroupMapper.selectByPrimaryKey(request.getResourceId());
|
||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.MODIFYLINK, SysLogConstants.SOURCE_TYPE.PANEL, panel.getId(), panel.getPid(), null, null) ;
|
||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.MODIFYLINK, SysLogConstants.SOURCE_TYPE.PANEL, panel.getId(), panel.getPid(), null, null);
|
||||
}
|
||||
|
||||
public void overTime(OverTimeRequest request) {
|
||||
request.setUserId(AuthUtils.getUser().getUserId());
|
||||
extPanelLinkMapper.updateOverTime(request);
|
||||
PanelGroupWithBLOBs panel = panelGroupMapper.selectByPrimaryKey(request.getResourceId());
|
||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.MODIFYLINK, SysLogConstants.SOURCE_TYPE.PANEL, panel.getId(), panel.getPid(), null, null) ;
|
||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.MODIFYLINK, SysLogConstants.SOURCE_TYPE.PANEL, panel.getId(), panel.getPid(), null, null);
|
||||
}
|
||||
|
||||
private PanelLink findOne(String resourceId) {
|
||||
@ -232,8 +234,12 @@ public class PanelLinkService {
|
||||
return pass;
|
||||
}
|
||||
|
||||
public PanelGroupWithBLOBs resourceInfo(String resourceId) {
|
||||
return panelGroupMapper.selectByPrimaryKey(resourceId);
|
||||
public PanelGroupDTO resourceInfo(String resourceId) {
|
||||
PanelGroupWithBLOBs result = panelGroupMapper.selectByPrimaryKey(resourceId);
|
||||
PanelGroupDTO panelGroupDTO = new PanelGroupDTO();
|
||||
BeanUtils.copyBean(panelGroupDTO, result);
|
||||
panelGroupDTO.setWatermarkInfo(panelWatermarkMapper.selectByPrimaryKey("system_default"));
|
||||
return panelGroupDTO;
|
||||
}
|
||||
|
||||
public String getShortUrl(String resourceId) {
|
||||
|
@ -74,7 +74,7 @@ public class SysUserService {
|
||||
List<SysUserGridResponse> lists = extSysUserMapper.query(gridExample);
|
||||
lists.forEach(item -> {
|
||||
List<SysUserRole> roles = item.getRoles();
|
||||
List<Long> roleIds = roles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
|
||||
List<Long> roleIds = roles.stream().filter(ObjectUtils::isNotEmpty).map(SysUserRole::getRoleId).collect(Collectors.toList());
|
||||
item.setRoleIds(roleIds);
|
||||
});
|
||||
return lists;
|
||||
|
@ -28,15 +28,12 @@ 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();
|
||||
|
||||
protected Type type = new TypeToken<List<FolderItem>>() {
|
||||
}.getType();
|
||||
|
||||
|
||||
@Resource
|
||||
@ -47,26 +44,28 @@ public class LogManager {
|
||||
|
||||
|
||||
public String detailInfo(SysLogWithBLOBs vo) {
|
||||
String sourceName = vo.getSourceName();
|
||||
String position = 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);
|
||||
|
||||
String result = operateTypeName + sourceTypeName + String.format(contentFormat, vo.getSourceName());
|
||||
if (vo.getSourceType() != SysLogConstants.SOURCE_TYPE.LINK.getValue()) {
|
||||
result += remarkInfo(vo, false);
|
||||
}
|
||||
if ((position = vo.getPosition()) != null) {
|
||||
List<FolderItem> folderItems = gson.fromJson(position, type);
|
||||
String template = folderItems.stream().map(folderItem -> folderItem.getName()).collect(Collectors.joining("/"));
|
||||
String positionResult = String.format(positionFormat, template);
|
||||
return positionResult + result;
|
||||
String positionResult = String.format(Translator.get("I18N_LOG_FORMAT_POSITION"), template);
|
||||
result = positionResult + result;
|
||||
}
|
||||
if (vo.getSourceType() == SysLogConstants.SOURCE_TYPE.LINK.getValue()) {
|
||||
result = remarkInfo(vo, true) + result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String remarkInfo(SysLogWithBLOBs vo) {
|
||||
public String remarkInfo(SysLogWithBLOBs vo, Boolean isPrefix) {
|
||||
String remakrk = null;
|
||||
if ((remakrk = vo.getRemark()) != null) {
|
||||
String targetTypeName = null;
|
||||
@ -77,14 +76,16 @@ public class LogManager {
|
||||
Integer targetType = item.getType();
|
||||
targetTypeName = SysLogConstants.sourceTypeName(targetType);
|
||||
targetTypeName = Translator.get(targetTypeName);
|
||||
return String.format(format, targetTypeName, template);
|
||||
if (isPrefix) {
|
||||
return String.format(Translator.get("I18N_LOG_FORMAT_PREFIX"), targetTypeName, template);
|
||||
}
|
||||
return String.format(Translator.get("I18N_LOG_FORMAT"), targetTypeName, template);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
private LogTypeItem parentIds(String id, Integer value) {
|
||||
LogTypeItem result = new LogTypeItem();
|
||||
String typeValue = "";
|
||||
@ -119,7 +120,7 @@ public class LogManager {
|
||||
}
|
||||
|
||||
|
||||
private List<FolderItem> parentInfos(List<String> ids, Integer value){
|
||||
private List<FolderItem> parentInfos(List<String> ids, Integer value) {
|
||||
List<FolderItem> folderItems = extSysLogMapper.idAndName(ids, value);
|
||||
if (value == 3) {
|
||||
folderItems.forEach(item -> {
|
||||
@ -164,7 +165,7 @@ public class LogManager {
|
||||
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)){
|
||||
if (dataSourceTypes.get(i).getType().equals(typeId)) {
|
||||
name = dataSourceTypes.get(i).getName();
|
||||
break;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import io.dataease.commons.constants.ParamConstants;
|
||||
import io.dataease.commons.constants.SysLogConstants;
|
||||
import io.dataease.commons.utils.AuthUtils;
|
||||
import io.dataease.commons.utils.BeanUtils;
|
||||
import io.dataease.commons.utils.IPUtils;
|
||||
import io.dataease.commons.utils.ServletUtils;
|
||||
import io.dataease.controller.sys.base.ConditionEntity;
|
||||
import io.dataease.controller.sys.request.KeyGridRequest;
|
||||
@ -28,6 +29,7 @@ import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.hssf.usermodel.*;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@ -46,6 +48,8 @@ public class LogService {
|
||||
// 仪表板的额外操作 分享以及公共链接
|
||||
private static Integer[] panel_ext_ope = {4, 5, 8, 9, 10};
|
||||
|
||||
private static Integer[] link_ext_ope = {13, 14};
|
||||
|
||||
// 驱动文件操作 上传, 删除
|
||||
private static Integer[] driver_file_ope = {11, 3};
|
||||
|
||||
@ -247,6 +251,16 @@ public class LogService {
|
||||
results.add(folderItem);
|
||||
}
|
||||
|
||||
for (int i = 0; i < link_ext_ope.length; i++) {
|
||||
SysLogConstants.SOURCE_TYPE sourceType = SysLogConstants.SOURCE_TYPE.LINK;
|
||||
FolderItem folderItem = new FolderItem();
|
||||
folderItem.setId(link_ext_ope[i] + "-" + sourceType.getValue());
|
||||
String operateTypeName = SysLogConstants.operateTypeName(link_ext_ope[i]);
|
||||
String sourceTypeName = sourceType.getName();
|
||||
folderItem.setName(Translator.get(operateTypeName) + Translator.get(sourceTypeName));
|
||||
results.add(folderItem);
|
||||
}
|
||||
|
||||
FolderItem userLogin = new FolderItem();
|
||||
SysLogConstants.OPERATE_TYPE operateTypeLogin = SysLogConstants.OPERATE_TYPE.LOGIN;
|
||||
SysLogConstants.SOURCE_TYPE sourceTypeLogin = SysLogConstants.SOURCE_TYPE.USER;
|
||||
@ -308,6 +322,7 @@ public class LogService {
|
||||
sysLogGridDTO.setTime(vo.getTime());
|
||||
sysLogGridDTO.setUser(vo.getNickName());
|
||||
sysLogGridDTO.setDetail(logManager.detailInfo(vo));
|
||||
sysLogGridDTO.setIp(vo.getIp());
|
||||
return sysLogGridDTO;
|
||||
}
|
||||
|
||||
@ -330,12 +345,14 @@ public class LogService {
|
||||
sysLogWithBLOBs.setLoginName(sysLogDTO.getSourceName());
|
||||
sysLogWithBLOBs.setNickName(sysLogDTO.getSourceName());
|
||||
}
|
||||
sysLogWithBLOBs.setIp(IPUtils.get());
|
||||
|
||||
sysLogMapper.insert(sysLogWithBLOBs);
|
||||
}
|
||||
|
||||
|
||||
public void exportExcel(KeyGridRequest request) throws Exception {
|
||||
request = logRetentionProxy(request);
|
||||
request = detailRequest(request);
|
||||
String keyWord = request.getKeyWord();
|
||||
List<String> ids = null;
|
||||
@ -355,24 +372,25 @@ public class LogService {
|
||||
List<String[]> details = lists.stream().map(item -> {
|
||||
String operateTypeName = SysLogConstants.operateTypeName(item.getOperateType());
|
||||
String sourceTypeName = SysLogConstants.sourceTypeName(item.getSourceType());
|
||||
String[] row = new String[4];
|
||||
String[] row = new String[5];
|
||||
row[0] = Translator.get(operateTypeName) + " " + Translator.get(sourceTypeName);
|
||||
row[1] = logManager.detailInfo(item);
|
||||
row[2] = item.getNickName();
|
||||
row[3] = DateUtil.formatDateTime(new Date(item.getTime()));
|
||||
row[3] = item.getIp();
|
||||
row[4] = DateUtil.formatDateTime(new Date(item.getTime()));
|
||||
return row;
|
||||
}).collect(Collectors.toList());
|
||||
String[] headArr = {"操作类型", "详情", "用户", "时间"};
|
||||
String[] headArr = {"操作类型", "详情", "用户", "IP地址", "时间"};
|
||||
details.add(0, headArr);
|
||||
|
||||
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
XSSFWorkbook wb = new XSSFWorkbook();
|
||||
//明细sheet
|
||||
HSSFSheet detailsSheet = wb.createSheet("数据");
|
||||
XSSFSheet detailsSheet = wb.createSheet("数据");
|
||||
|
||||
//给单元格设置样式
|
||||
CellStyle cellStyle = wb.createCellStyle();
|
||||
Font font = wb.createFont();
|
||||
XSSFCellStyle cellStyle = wb.createCellStyle();
|
||||
XSSFFont font = wb.createFont();
|
||||
//设置字体大小
|
||||
font.setFontHeightInPoints((short) 12);
|
||||
//设置字体加粗
|
||||
@ -386,11 +404,11 @@ public class LogService {
|
||||
|
||||
if (CollectionUtils.isNotEmpty(details)) {
|
||||
for (int i = 0; i < details.size(); i++) {
|
||||
HSSFRow row = detailsSheet.createRow(i);
|
||||
XSSFRow row = detailsSheet.createRow(i);
|
||||
String[] rowData = details.get(i);
|
||||
if (rowData != null) {
|
||||
for (int j = 0; j < rowData.length; j++) {
|
||||
HSSFCell cell = row.createCell(j);
|
||||
XSSFCell cell = row.createCell(j);
|
||||
cell.setCellValue(rowData[j]);
|
||||
if (i == 0) {// 头部
|
||||
cell.setCellStyle(cellStyle);
|
||||
@ -406,7 +424,7 @@ public class LogService {
|
||||
//文件名称
|
||||
String fileName = "DataEase操作日志";
|
||||
String encodeFileName = URLEncoder.encode(fileName, "UTF-8");
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + encodeFileName + ".xls");
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + encodeFileName + ".xlsx");
|
||||
wb.write(outputStream);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
38
backend/src/main/resources/db/migration/V44__1.17.sql
Normal file
38
backend/src/main/resources/db/migration/V44__1.17.sql
Normal file
@ -0,0 +1,38 @@
|
||||
ALTER TABLE `sys_log`
|
||||
CHANGE COLUMN `user_id` `user_id` BIGINT NULL COMMENT '操作人',
|
||||
CHANGE COLUMN `login_name` `login_name` VARCHAR (255) NULL COMMENT '登录账号',
|
||||
CHANGE COLUMN `nick_name` `nick_name` VARCHAR (255) NULL COMMENT '姓名';
|
||||
|
||||
ALTER TABLE `panel_group`
|
||||
ADD COLUMN `watermark_open` tinyint(1) NULL DEFAULT 1 COMMENT '是否单独打开水印' AFTER `update_time`;
|
||||
|
||||
DROP TABLE IF EXISTS `panel_watermark`;
|
||||
CREATE TABLE `panel_watermark`
|
||||
(
|
||||
`id` varchar(50) NOT NULL,
|
||||
`version` varchar(255) DEFAULT NULL COMMENT '版本号',
|
||||
`setting_content` longtext COMMENT '设置内容',
|
||||
`create_by` varchar(255) DEFAULT NULL,
|
||||
`create_time` bigint(13) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
INSERT INTO `panel_watermark` (`id`, `version`, `setting_content`, `create_by`, `create_time`)
|
||||
VALUES ('system_default', '1.0',
|
||||
'{\"enable\":false,\"enablePanelCustom\":true,\"type\":\"custom\",\"content\":\"${time}-${nickName}\",\"watermark_color\":\"#999999\",\"watermark_x_space\":20,\"watermark_y_space\":100,\"watermark_fontsize\":20}',
|
||||
'admin', NULL);
|
||||
|
||||
SET
|
||||
FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
UPDATE `sys_menu`
|
||||
SET `component` = 'dataset/Form'
|
||||
WHERE (`menu_id` = '800');
|
||||
|
||||
|
||||
UPDATE `sys_menu`
|
||||
SET `component` = 'msg/All'
|
||||
WHERE (`component` = 'msg/all');
|
||||
UPDATE `sys_menu`
|
||||
SET `component` = 'msg/Setting'
|
||||
WHERE (`component` = 'msg/setting');
|
@ -167,6 +167,7 @@ SOURCE_TYPE_ROLE=ROLE
|
||||
SOURCE_TYPE_DRIVER=DRIVER
|
||||
SOURCE_TYPE_DRIVER_FILE=DRIVER FILE
|
||||
SOURCE_TYPE_MENU=MENU
|
||||
SOURCE_TYPE_LINK=PUBLIC LINK
|
||||
I18N_OPERATE_TYPE=Operation type
|
||||
I18N_DETAIL=Operation details
|
||||
I18N_USER=Operator
|
||||
@ -241,3 +242,7 @@ I18N_APP_NO_DATASOURCE=This panel don't have datasource
|
||||
I18N_APP_ONE_DATASOURCE_TIPS=This panel should have only one datasource
|
||||
I18N_PROHIBIT_SCANNING_TO_CREATE_USER=Prohibit scanning code to create user
|
||||
|
||||
I18N_LOG_FORMAT_POSITION=IN\u3010%s\u3011
|
||||
I18N_LOG_FORMAT=TO %s\u3010%s\u3011
|
||||
I18N_LOG_FORMAT_PREFIX=With authority of %s\u3010%s\u3011
|
||||
|
||||
|
@ -167,6 +167,7 @@ SOURCE_TYPE_ROLE=\u89D2\u8272
|
||||
SOURCE_TYPE_DRIVER=\u9A71\u52A8
|
||||
SOURCE_TYPE_DRIVER_FILE=\u9A71\u52A8\u6587\u4EF6
|
||||
SOURCE_TYPE_MENU=\u83DC\u5355
|
||||
SOURCE_TYPE_LINK=\u516C\u5171\u94FE\u63A5
|
||||
I18N_OPERATE_TYPE=\u64CD\u4F5C\u7C7B\u578B
|
||||
I18N_DETAIL=\u64CD\u4F5C\u8BE6\u60C5
|
||||
I18N_USER=\u64CD\u4F5C\u4EBA
|
||||
@ -241,3 +242,7 @@ I18N_APP_NO_DATASOURCE=\u6CA1\u6709\u627E\u5230\u6570\u636E\u6E90
|
||||
I18N_APP_ONE_DATASOURCE_TIPS=\u8BE5\u4EEA\u8868\u677F\u53EA\u80FD\u5B58\u5728\u4E00\u4E2A\u6570\u636E\u6E90
|
||||
I18N_PROHIBIT_SCANNING_TO_CREATE_USER=\u7981\u6B62\u626B\u7801\u521B\u5EFA\u7528\u6237\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\uFF01
|
||||
|
||||
I18N_LOG_FORMAT_POSITION=\u5728\u3010%s\u3011
|
||||
I18N_LOG_FORMAT=\u7ED9%s\u3010%s\u3011
|
||||
I18N_LOG_FORMAT_PREFIX=\u4EE5%s\u3010%s\u3011\u6743\u9650
|
||||
|
||||
|
@ -167,6 +167,7 @@ SOURCE_TYPE_ROLE=\u89D2\u8272
|
||||
SOURCE_TYPE_DRIVER=\u9A45\u52D5
|
||||
SOURCE_TYPE_DRIVER_FILE=\u9A45\u52D5\u6587\u4EF6
|
||||
SOURCE_TYPE_MENU=\u83DC\u55AE
|
||||
SOURCE_TYPE_LINK=\u516C\u5171\u93C8\u63A5
|
||||
I18N_DRIVER_NOT_DELETE=\u4F7F\u7528\u4E2D\u7684\u9A45\u52D5\u4E0D\u5141\u8A31\u5220\u9664
|
||||
I18N_DRIVER_REPEAT_NAME=\u540D\u7A31\u91CD\u8907
|
||||
I18N_DRIVER_NOT_FOUND=\u672A\u627E\u5230\u9A45\u52D5
|
||||
@ -236,3 +237,7 @@ I18N_APP_ERROR_DATASET=\u5100\u8868\u677F\u4E2D\u4E0D\u80FD\u5B58\u5728API\u6578
|
||||
I18N_APP_NO_DATASOURCE=\u6C92\u6709\u627E\u5230\u6578\u64DA\u6E90
|
||||
I18N_APP_ONE_DATASOURCE_TIPS=\u8A72\u5100\u8868\u677F\u53EA\u80FD\u5B58\u5728\u4E00\u500B\u6578\u64DA\u6E90
|
||||
I18N_PROHIBIT_SCANNING_TO_CREATE_USER=\u7981\u6B62\u6383\u78BC\u5275\u5EFA\u7528\u6236\uFF0C\u8ACB\u806F\u7CFB\u7BA1\u7406\u54E1\uFF01
|
||||
|
||||
I18N_LOG_FORMAT_POSITION=\u5728\u3010%s\u3011
|
||||
I18N_LOG_FORMAT=\u7D66%s\u3010%s\u3011
|
||||
I18N_LOG_FORMAT_PREFIX=\u4EE5%s\u3010%s\u3011\u6B0A\u9650
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<artifactId>dataease-server</artifactId>
|
||||
@ -44,7 +44,7 @@
|
||||
</goals>
|
||||
<!-- Optional configuration which provides for running any npm command -->
|
||||
<configuration>
|
||||
<arguments>install --force</arguments>
|
||||
<arguments>install</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
@ -62,4 +62,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
@ -1,38 +0,0 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function post(url, data) {
|
||||
return request({
|
||||
url: url,
|
||||
method: 'post',
|
||||
loading: true,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function get(url) {
|
||||
return request({
|
||||
url: url,
|
||||
method: 'get',
|
||||
loading: true
|
||||
})
|
||||
}
|
||||
|
||||
export function fileUpload(url, file, files, param) {
|
||||
const formData = new FormData()
|
||||
if (file) {
|
||||
formData.append('file', file)
|
||||
}
|
||||
if (files) {
|
||||
files.forEach(f => {
|
||||
formData.append('files', f)
|
||||
})
|
||||
}
|
||||
formData.append('request', new Blob([JSON.stringify(param)], { type: 'application/json' }))
|
||||
return request({
|
||||
method: 'POST',
|
||||
loading: true,
|
||||
url: url,
|
||||
data: formData
|
||||
})
|
||||
}
|
||||
export default { fileUpload }
|
@ -50,6 +50,15 @@ export function switchEnablePwd(data) {
|
||||
})
|
||||
}
|
||||
|
||||
export function viewLinkLog(data) {
|
||||
return request({
|
||||
url: 'api/link/viewLog',
|
||||
method: 'post',
|
||||
loading: true,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function loadGenerate(resourceId) {
|
||||
return request({
|
||||
url: 'api/link/currentGenerate/' + resourceId,
|
||||
|
@ -66,6 +66,7 @@ export function viewData(id, panelId, data) {
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function panelSave(data) {
|
||||
return request({
|
||||
url: 'panel/group/save',
|
||||
@ -162,6 +163,10 @@ export function initPanelData(panelId, useCache = false, callback) {
|
||||
if (response.data) {
|
||||
// 初始化视图data和style 数据
|
||||
panelInit(JSON.parse(response.data.panelData), JSON.parse(response.data.panelStyle))
|
||||
const watermarkInfo = {
|
||||
...response.data.watermarkInfo,
|
||||
settingContent: JSON.parse(response.data.watermarkInfo.settingContent)
|
||||
}
|
||||
// 设置当前仪表板全局信息
|
||||
store.dispatch('panel/setPanelInfo', {
|
||||
id: response.data.id,
|
||||
@ -174,7 +179,9 @@ export function initPanelData(panelId, useCache = false, callback) {
|
||||
creatorName: response.data.creatorName,
|
||||
updateBy: response.data.updateBy,
|
||||
updateName: response.data.updateName,
|
||||
updateTime: response.data.updateTime
|
||||
updateTime: response.data.updateTime,
|
||||
watermarkOpen: response.data.watermarkOpen,
|
||||
watermarkInfo: watermarkInfo
|
||||
})
|
||||
// 刷新联动信息
|
||||
getPanelAllLinkageInfo(panelId).then(rsp => {
|
||||
@ -230,6 +237,7 @@ export function initViewCache(panelId) {
|
||||
loading: false
|
||||
})
|
||||
}
|
||||
|
||||
export function exportDetails(data) {
|
||||
// 初始化仪表板视图缓存
|
||||
return request({
|
||||
@ -268,6 +276,7 @@ export function saveCache(data) {
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function findUserCacheRequest(panelId) {
|
||||
return request({
|
||||
url: 'panel/group/findUserCache/' + panelId,
|
||||
|
@ -10,6 +10,10 @@ export function proxyInitPanelData(panelId, proxy, callback) {
|
||||
if (response.data) {
|
||||
// 初始化视图data和style 数据
|
||||
panelInit(JSON.parse(response.data.panelData), JSON.parse(response.data.panelStyle))
|
||||
const watermarkInfo = {
|
||||
...response.data.watermarkInfo,
|
||||
settingContent: JSON.parse(response.data.watermarkInfo.settingContent)
|
||||
}
|
||||
// 设置当前仪表板全局信息
|
||||
store.dispatch('panel/setPanelInfo', {
|
||||
id: response.data.id,
|
||||
@ -23,7 +27,9 @@ export function proxyInitPanelData(panelId, proxy, callback) {
|
||||
creatorName: response.data.creatorName,
|
||||
updateBy: response.data.updateBy,
|
||||
updateName: response.data.updateName,
|
||||
updateTime: response.data.updateTime
|
||||
updateTime: response.data.updateTime,
|
||||
watermarkOpen: response.data.watermarkOpen,
|
||||
watermarkInfo: watermarkInfo
|
||||
})
|
||||
// 刷新联动信息
|
||||
getPanelAllLinkageInfo(panelId, proxy).then(rsp => {
|
||||
|
13
frontend/src/api/systemInfo/userLogin.js
Normal file
13
frontend/src/api/systemInfo/userLogin.js
Normal file
@ -0,0 +1,13 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function userLoginInfo() {
|
||||
return request({
|
||||
url: '/systemInfo/userLoginInfo',
|
||||
method: 'get',
|
||||
loading: false
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
userLoginInfo
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 262 KiB After Width: | Height: | Size: 272 KiB |
@ -1,85 +0,0 @@
|
||||
<!-- @author zhengjie -->
|
||||
<template>
|
||||
<div class="icon-body">
|
||||
<el-input
|
||||
v-model="name"
|
||||
style="position: relative;"
|
||||
clearable
|
||||
placeholder="请输入图标名称"
|
||||
@clear="filterIcons"
|
||||
@input.native="filterIcons"
|
||||
>
|
||||
<i
|
||||
slot="suffix"
|
||||
class="el-icon-search el-input__icon"
|
||||
/>
|
||||
</el-input>
|
||||
<div class="icon-list">
|
||||
<div
|
||||
v-for="(item, index) in iconList"
|
||||
:key="index"
|
||||
@click="selectedIcon(item)"
|
||||
>
|
||||
<svg-icon
|
||||
:icon-class="item"
|
||||
style="height: 30px;width: 16px;"
|
||||
/>
|
||||
<span>{{ item }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import icons from './requireIcons'
|
||||
export default {
|
||||
name: 'IconSelect',
|
||||
data() {
|
||||
return {
|
||||
name: '',
|
||||
iconList: icons
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
filterIcons() {
|
||||
this.iconList = icons
|
||||
if (this.name) {
|
||||
this.iconList = this.iconList.filter(item => item.includes(this.name))
|
||||
}
|
||||
},
|
||||
selectedIcon(name) {
|
||||
this.$emit('selected', name)
|
||||
document.body.click()
|
||||
},
|
||||
reset() {
|
||||
this.name = ''
|
||||
this.iconList = icons
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.icon-body {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
.icon-list {
|
||||
height: 200px;
|
||||
overflow-y: scroll;
|
||||
div {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
margin-bottom: -5px;
|
||||
cursor: pointer;
|
||||
width: 33%;
|
||||
float: left;
|
||||
}
|
||||
span {
|
||||
display: inline-block;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,11 +0,0 @@
|
||||
|
||||
const req = require.context('@/icons/svg', false, /\.svg$/)
|
||||
const requireAll = requireContext => requireContext.keys()
|
||||
|
||||
const re = /\.\/(.*)\.svg/
|
||||
|
||||
const icons = requireAll(req).map(i => {
|
||||
return i.match(re)[1]
|
||||
})
|
||||
|
||||
export default icons
|
@ -1,76 +0,0 @@
|
||||
<template>
|
||||
<component
|
||||
:is="mode"
|
||||
:ref="refId"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<template #default>
|
||||
<slot name="default" />
|
||||
</template>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { uuid } from 'vue-uuid'
|
||||
import { get } from '@/api/system/dynamic'
|
||||
|
||||
export default {
|
||||
name: 'AsyncComponent',
|
||||
inheritAttrs: true,
|
||||
props: {
|
||||
// 父组件提供请求地址
|
||||
url: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
resData: '',
|
||||
mode: '',
|
||||
refId: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
url: {
|
||||
immediate: true,
|
||||
async handler(val, oldVal) {
|
||||
if (!this.url) return
|
||||
// Cache 缓存 根据 url 参数
|
||||
if (!window.SyncComponentCache) {
|
||||
window.SyncComponentCache = {}
|
||||
}
|
||||
let res
|
||||
if (!window.SyncComponentCache[this.url]) {
|
||||
window.SyncComponentCache[this.url] = get(this.url)
|
||||
|
||||
// window.SyncComponentCache[this.url] = Axios.get(this.url)
|
||||
res = await window.SyncComponentCache[this.url]
|
||||
} else {
|
||||
res = await window.SyncComponentCache[this.url]
|
||||
}
|
||||
|
||||
const Fn = Function
|
||||
this.mode = new Fn(`return ${res.data || res}`)()
|
||||
/* if (res && res.data) {
|
||||
const Fn = Function
|
||||
this.mode = new Fn(`return ${res.data || res}`)()
|
||||
} */
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.refId = uuid.v1
|
||||
},
|
||||
methods: {
|
||||
/* chartResize() {
|
||||
this.$refs[this.refId] && this.$refs[this.refId].chartResize && this.$refs[this.refId].chartResize()
|
||||
}, */
|
||||
callPluginInner(param) {
|
||||
const { methodName, methodParam } = param
|
||||
this.$refs[this.refId] && this.$refs[this.refId][methodName] && this.$refs[this.refId][methodName](methodParam)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,92 +0,0 @@
|
||||
<template>
|
||||
<el-breadcrumb
|
||||
class="app-breadcrumb"
|
||||
separator="/"
|
||||
>
|
||||
<transition-group name="breadcrumb">
|
||||
<el-breadcrumb-item
|
||||
v-for="(item,index) in levelList"
|
||||
:key="item.path"
|
||||
>
|
||||
<span v-if="index === 0">当前位置:</span>
|
||||
<span
|
||||
v-if="item.redirect==='noRedirect'||index==levelList.length-1"
|
||||
class="no-redirect"
|
||||
>{{ item.meta.title }}</span>
|
||||
<a
|
||||
v-else
|
||||
@click.prevent="handleLink(item)"
|
||||
>{{ item.meta.title }}</a>
|
||||
</el-breadcrumb-item>
|
||||
</transition-group>
|
||||
</el-breadcrumb>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import pathToRegexp from 'path-to-regexp'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
levelList: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getBreadcrumb()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getBreadcrumb()
|
||||
},
|
||||
methods: {
|
||||
getBreadcrumb() {
|
||||
// only show routes with meta.title
|
||||
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
|
||||
const first = matched[0]
|
||||
|
||||
if (!this.isDashboard(first)) {
|
||||
matched = [{ path: '/panel', meta: { title: '仪表板' }}].concat(matched)
|
||||
}
|
||||
|
||||
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
|
||||
},
|
||||
isDashboard(route) {
|
||||
const name = route && route.name
|
||||
if (!name) {
|
||||
return false
|
||||
}
|
||||
// return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
|
||||
return name.trim().toLocaleLowerCase() === 'panel'.toLocaleLowerCase()
|
||||
},
|
||||
pathCompile(path) {
|
||||
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
|
||||
const { params } = this.$route
|
||||
var toPath = pathToRegexp.compile(path)
|
||||
return toPath(params)
|
||||
},
|
||||
handleLink(item) {
|
||||
const { redirect, path } = item
|
||||
if (redirect) {
|
||||
this.$router.push(redirect)
|
||||
return
|
||||
}
|
||||
this.$router.push(this.pathCompile(path))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-breadcrumb.el-breadcrumb {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
line-height: 50px;
|
||||
margin-left: 8px;
|
||||
|
||||
.no-redirect {
|
||||
color: #97a8be;
|
||||
cursor: text;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,128 +0,0 @@
|
||||
<template>
|
||||
<el-select
|
||||
v-model="selected"
|
||||
multiple
|
||||
v-bind="$attrsAll"
|
||||
v-on="$listenserAll"
|
||||
@change="onChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in mdoptionsList"
|
||||
:key="item.key"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
<slot name="default" />
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ElSelectAll',
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
}
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const selected = this.value || []
|
||||
return {
|
||||
selected,
|
||||
mdoptionsValue: [],
|
||||
oldMdoptionsValue: [],
|
||||
mdoptionsList: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
$attrsAll() {
|
||||
// const val = this.$vnode.data.model && this.$vnode.data.model.value;
|
||||
const result = {
|
||||
// value: val,
|
||||
...this.$attrs
|
||||
}
|
||||
return result
|
||||
},
|
||||
$listenserAll() {
|
||||
const _this = this
|
||||
return Object.assign({}, this.$listeners, {
|
||||
change: () => {
|
||||
this.$emit('change', (_this.selected || []).filter(v => {
|
||||
return v !== 'all'
|
||||
}))
|
||||
},
|
||||
input: () => {
|
||||
this.$emit('input', (_this.selected || []).filter(v => {
|
||||
return v !== 'all'
|
||||
}))
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
selected: {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
handler(val) {
|
||||
this.$emit('input', (val || []).filter(v => {
|
||||
return v !== 'all'
|
||||
}))
|
||||
}
|
||||
},
|
||||
options: {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
handler(val) {
|
||||
if ((!val || val.length === 0) && !this.$slots) {
|
||||
this.mdoptionsList = []
|
||||
} else {
|
||||
this.mdoptionsList = [{
|
||||
key: 'all',
|
||||
value: 'all',
|
||||
label: '全部'
|
||||
}, ...val]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
onChange(val) {
|
||||
// eslint-disable-next-line no-debugger
|
||||
const allValues = []
|
||||
// 保留所有值
|
||||
for (const item of this.mdoptionsList) {
|
||||
allValues.push(item.value)
|
||||
}
|
||||
// 用来储存上一次的值,可以进行对比
|
||||
const oldVal = this.oldMdoptionsValue.length === 1 ? [] : this.oldMdoptionsValue[1] || []
|
||||
// 若是全部选择
|
||||
if (val.includes('all')) this.selected = allValues
|
||||
// 取消全部选中 上次有 当前没有 表示取消全选
|
||||
if (oldVal.includes('all') && !val.includes('all')) this.selected = []
|
||||
// 点击非全部选中 需要排除全部选中 以及 当前点击的选项
|
||||
// 新老数据都有全部选中
|
||||
if (oldVal.includes('all') && val.includes('all')) {
|
||||
const index = val.indexOf('all')
|
||||
val.splice(index, 1) // 排除全选选项
|
||||
this.selected = val
|
||||
}
|
||||
// 全选未选 但是其他选项全部选上 则全选选上 上次和当前 都没有全选
|
||||
if (!oldVal.includes('all') && !val.includes('all')) {
|
||||
if (val.length === allValues.length - 1) this.selected = ['all'].concat(val)
|
||||
}
|
||||
// 储存当前最后的结果 作为下次的老数据
|
||||
this.oldMdoptionsValue[1] = this.selected
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,131 +0,0 @@
|
||||
|
||||
<template>
|
||||
<div class="complex-table">
|
||||
<div
|
||||
v-if="$slots.header || header"
|
||||
class="complex-table__header"
|
||||
>
|
||||
<slot name="header">{{ header }}</slot>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="$slots.toolbar || searchConfig"
|
||||
class="complex-table__toolbar"
|
||||
>
|
||||
<div>
|
||||
<slot name="toolbar" />
|
||||
</div>
|
||||
<fu-search-bar
|
||||
ref="search"
|
||||
v-bind="searchConfig"
|
||||
@exec="search"
|
||||
>
|
||||
<template #complex>
|
||||
<slot name="complex" />
|
||||
</template>
|
||||
<slot name="buttons" />
|
||||
<fu-table-column-select
|
||||
v-if="!hideColumns"
|
||||
:columns="columns"
|
||||
/>
|
||||
</fu-search-bar>
|
||||
</div>
|
||||
|
||||
<div class="complex-table__body">
|
||||
<fu-table
|
||||
v-bind="$attrs"
|
||||
:columns="columns"
|
||||
:local-key="localKey"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<slot />
|
||||
</fu-table>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="$slots.pagination || paginationConfig"
|
||||
class="complex-table__pagination"
|
||||
>
|
||||
<slot name="pagination">
|
||||
<fu-table-pagination
|
||||
:current-page.sync="paginationConfig.currentPage"
|
||||
:page-size.sync="paginationConfig.pageSize"
|
||||
v-bind="paginationConfig"
|
||||
@change="search"
|
||||
/>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'ComplexTable',
|
||||
props: {
|
||||
columns: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
hideColumns: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
localKey: String, // 如果需要记住选择的列,则这里添加一个唯一的Key
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
header: String,
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
searchConfig: Object,
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
paginationConfig: Object,
|
||||
transCondition: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
condition: {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.transCondition !== null) {
|
||||
this.$refs.search.setConditions(this.transCondition)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
search(condition, e) {
|
||||
if (condition) {
|
||||
this.condition = condition
|
||||
}
|
||||
this.$emit('search', this.condition, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "~@/styles/mixin.scss";
|
||||
.complex-table {
|
||||
.complex-table__header {
|
||||
@include flex-row(flex-start, center);
|
||||
line-height: 60px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.complex-table__toolbar {
|
||||
@include flex-row(space-between, center);
|
||||
|
||||
.fu-search-bar {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.complex-table__pagination {
|
||||
margin-top: 20px;
|
||||
@include flex-row(flex-end);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -1,98 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <el-switch v-model="value" active-text="当前用户" /> -->
|
||||
|
||||
<treeselect
|
||||
v-model="value"
|
||||
:options="options"
|
||||
:load-options="loadData"
|
||||
style="width: 200px"
|
||||
:no-children-text="$t('commons.treeselect.no_children_text')"
|
||||
:no-options-text="$t('commons.treeselect.no_options_text')"
|
||||
:no-results-text="$t('commons.treeselect.no_results_text')"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ComplexCondition } from 'fit2cloud-ui/src/components/search-bar/model'
|
||||
import { getDeptTree } from '@/api/system/dept'
|
||||
import { LOAD_CHILDREN_OPTIONS, LOAD_ROOT_OPTIONS } from '@riophae/vue-treeselect'
|
||||
import Treeselect from '@riophae/vue-treeselect'
|
||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
||||
export default {
|
||||
components: { Treeselect },
|
||||
props: {
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
field: String,
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
label: String,
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
defaultOperator: String
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
// options: Array
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
// loadData: Function
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
value: undefined,
|
||||
operator: 'dept',
|
||||
operatorLabel: '组织',
|
||||
options: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
valueLabel() {
|
||||
return this.value
|
||||
}
|
||||
},
|
||||
// 自定义搜索控件的2个方法
|
||||
methods: {
|
||||
init() { // 初始化方法,在打开复合搜索界面时会被调用
|
||||
// 例如清空之前填写的内容
|
||||
this.value = undefined
|
||||
},
|
||||
getCondition() { // 点击确认时调用
|
||||
const { field, label, operator, operatorLabel, value, valueLabel } = this
|
||||
// 必须返回ComplexCondition类型的对象
|
||||
return new ComplexCondition({ field, label, operator, operatorLabel, value, valueLabel })
|
||||
},
|
||||
|
||||
// 获取弹窗内部门数据
|
||||
loadData({ action, parentNode, callback }) {
|
||||
if (action === LOAD_ROOT_OPTIONS) {
|
||||
const _self = this
|
||||
!this.options && getDeptTree('0').then(res => {
|
||||
_self.options = res.data.map(node => _self.normalizer(node))
|
||||
callback()
|
||||
})
|
||||
}
|
||||
|
||||
if (action === LOAD_CHILDREN_OPTIONS) {
|
||||
const _self = this
|
||||
getDeptTree(parentNode.id).then(res => {
|
||||
parentNode.children = res.data.map(function(obj) {
|
||||
return _self.normalizer(obj)
|
||||
})
|
||||
callback()
|
||||
})
|
||||
}
|
||||
},
|
||||
normalizer(node) {
|
||||
if (node.hasChildren) {
|
||||
node.children = null
|
||||
}
|
||||
return {
|
||||
id: node.deptId,
|
||||
label: node.name,
|
||||
children: node.children
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -1,115 +0,0 @@
|
||||
<template>
|
||||
<div class="complex-table">
|
||||
<div
|
||||
v-if="$slots.header || header"
|
||||
class="complex-table__header"
|
||||
>
|
||||
<slot name="header">{{ header }}</slot>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="$slots.toolbar || searchConfig"
|
||||
class="complex-table__toolbar"
|
||||
>
|
||||
<!-- <slot name="toolbar">
|
||||
<fu-search-bar v-bind="searchConfig" @exec="search">
|
||||
<slot name="buttons" />
|
||||
<fu-table-column-select :columns="columns" />
|
||||
</fu-search-bar>
|
||||
</slot> -->
|
||||
<div>
|
||||
<slot name="toolbar" />
|
||||
</div>
|
||||
<fu-search-bar
|
||||
v-bind="searchConfig"
|
||||
@exec="search"
|
||||
>
|
||||
<template #complex>
|
||||
<slot name="complex" />
|
||||
</template>
|
||||
<slot name="buttons" />
|
||||
<fu-table-column-select :columns="columns" />
|
||||
</fu-search-bar>
|
||||
</div>
|
||||
|
||||
<div class="complex-table__body">
|
||||
<slot />
|
||||
<!-- <fu-table ref="table" v-bind="$attrs" :columns="columns" :local-key="localKey" v-on="$listeners">
|
||||
<slot />
|
||||
</fu-table> -->
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="$slots.pagination || paginationConfig"
|
||||
class="complex-table__pagination"
|
||||
>
|
||||
<slot name="pagination">
|
||||
<fu-table-pagination
|
||||
:current-page.sync="paginationConfig.currentPage"
|
||||
:page-size.sync="paginationConfig.pageSize"
|
||||
v-bind="paginationConfig"
|
||||
@change="search"
|
||||
/>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'TreeTable',
|
||||
props: {
|
||||
columns: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
localKey: String, // 如果需要记住选择的列,则这里添加一个唯一的Key
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
header: String,
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
searchConfig: Object,
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
paginationConfig: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
condition: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
search(condition, e) {
|
||||
if (condition) {
|
||||
this.condition = condition
|
||||
}
|
||||
this.$emit('search', this.condition, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "~@/styles/mixin.scss";
|
||||
.complex-table {
|
||||
.complex-table__header {
|
||||
@include flex-row(flex-start, center);
|
||||
line-height: 60px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.complex-table__toolbar {
|
||||
@include flex-row(space-between, center);
|
||||
|
||||
.fu-search-bar {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.complex-table__pagination {
|
||||
margin-top: 20px;
|
||||
@include flex-row(flex-end);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -112,7 +112,9 @@ import toast from '@/components/canvas/utils/toast'
|
||||
import generateID from '@/components/canvas/utils/generateID'
|
||||
import ButtonDialog from '@/views/panel/filter/ButtonDialog'
|
||||
import ButtonResetDialog from '@/views/panel/filter/ButtonResetDialog'
|
||||
import FilterDialog from '@/views/panel/filter/filterDialog'
|
||||
import FilterDialog from '@/views/panel/filter/FilterDialog'
|
||||
import { userLoginInfo } from '@/api/systemInfo/userLogin'
|
||||
import { activeWatermark } from '@/components/canvas/tools/watermark'
|
||||
|
||||
export default {
|
||||
components: { FilterDialog, ButtonResetDialog, ButtonDialog, DeEditor },
|
||||
@ -233,12 +235,19 @@ export default {
|
||||
watch: {
|
||||
mobileLayoutStatus() {
|
||||
this.restore()
|
||||
},
|
||||
panelInfo: {
|
||||
handler(newVal, oldVla) {
|
||||
this.initWatermark()
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
mounted() {
|
||||
const _this = this
|
||||
this.initWatermark()
|
||||
// 监听div变动事件
|
||||
const erd = elementResizeDetectorMaker()
|
||||
erd.listenTo(document.getElementById(this.canvasDomId), element => {
|
||||
@ -252,6 +261,14 @@ export default {
|
||||
bus.$off('button-dialog-edit', this.editButtonDialog)
|
||||
},
|
||||
methods: {
|
||||
initWatermark() {
|
||||
if (this.panelInfo.watermarkInfo) {
|
||||
userLoginInfo().then(res => {
|
||||
const userInfo = res.data
|
||||
activeWatermark(this.panelInfo.watermarkInfo.settingContent, userInfo, this.canvasDomId, this.canvasId, this.panelInfo.watermarkOpen)
|
||||
})
|
||||
}
|
||||
},
|
||||
initEvents() {
|
||||
bus.$on('component-dialog-edit', this.editDialog)
|
||||
bus.$on('button-dialog-edit', this.editButtonDialog)
|
||||
@ -289,6 +306,7 @@ export default {
|
||||
}
|
||||
},
|
||||
canvasScroll(e) {
|
||||
this.scrollTop = e.target.scrollTop
|
||||
this.$emit('canvasScroll', { scrollLeft: e.target.scrollLeft, scrollTop: e.target.scrollTop })
|
||||
bus.$emit('onScroll')
|
||||
},
|
||||
|
@ -1,539 +0,0 @@
|
||||
/* Logo 字体 */
|
||||
@font-face {
|
||||
font-family: "iconfont logo";
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-family: "iconfont logo";
|
||||
font-size: 160px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/* tabs */
|
||||
.nav-tabs {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-more {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#tabs {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#tabs li {
|
||||
cursor: pointer;
|
||||
width: 100px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
border-bottom: 2px solid transparent;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-bottom: -1px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
|
||||
#tabs .active {
|
||||
border-bottom-color: #f00;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.tab-container .content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 页面布局 */
|
||||
.main {
|
||||
padding: 30px 100px;
|
||||
width: 960px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.main .logo {
|
||||
color: #333;
|
||||
text-align: left;
|
||||
margin-bottom: 30px;
|
||||
line-height: 1;
|
||||
height: 110px;
|
||||
margin-top: -50px;
|
||||
overflow: hidden;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.main .logo a {
|
||||
font-size: 160px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.helps {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.helps pre {
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
border: solid 1px #e7e1cd;
|
||||
background-color: #fffdef;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.icon_lists {
|
||||
width: 100% !important;
|
||||
overflow: hidden;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.icon_lists li {
|
||||
width: 100px;
|
||||
margin-bottom: 10px;
|
||||
margin-right: 20px;
|
||||
text-align: center;
|
||||
list-style: none !important;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.icon_lists li .code-name {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.icon_lists .icon {
|
||||
display: block;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
font-size: 42px;
|
||||
margin: 10px auto;
|
||||
color: #333;
|
||||
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
-moz-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
transition: font-size 0.25s linear, width 0.25s linear;
|
||||
}
|
||||
|
||||
.icon_lists .icon:hover {
|
||||
font-size: 100px;
|
||||
}
|
||||
|
||||
.icon_lists .svg-icon {
|
||||
/* 通过设置 font-size 来改变图标大小 */
|
||||
width: 1em;
|
||||
/* 图标和文字相邻时,垂直对齐 */
|
||||
vertical-align: -0.15em;
|
||||
/* 通过设置 color 来改变 SVG 的颜色/fill */
|
||||
fill: currentColor;
|
||||
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
|
||||
normalize.css 中也包含这行 */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.icon_lists li .name,
|
||||
.icon_lists li .code-name {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* markdown 样式 */
|
||||
.markdown {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
color: #404040;
|
||||
font-weight: 500;
|
||||
line-height: 40px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
color: #404040;
|
||||
margin: 1.6em 0 0.6em 0;
|
||||
font-weight: 500;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.markdown h5 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown h6 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
height: 1px;
|
||||
border: 0;
|
||||
background: #e9e9e9;
|
||||
margin: 16px 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown > p,
|
||||
.markdown > blockquote,
|
||||
.markdown > .highlight,
|
||||
.markdown > ol,
|
||||
.markdown > ul {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.markdown ul > li {
|
||||
list-style: circle;
|
||||
}
|
||||
|
||||
.markdown > ul li,
|
||||
.markdown blockquote ul > li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown > ul li p,
|
||||
.markdown > ol li p {
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
|
||||
.markdown ol > li {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.markdown > ol li,
|
||||
.markdown blockquote ol > li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown code {
|
||||
margin: 0 3px;
|
||||
padding: 0 5px;
|
||||
background: #eee;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.markdown strong,
|
||||
.markdown b {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown > table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0px;
|
||||
empty-cells: show;
|
||||
border: 1px solid #e9e9e9;
|
||||
width: 95%;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown > table th {
|
||||
white-space: nowrap;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown > table th,
|
||||
.markdown > table td {
|
||||
border: 1px solid #e9e9e9;
|
||||
padding: 8px 16px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown > table th {
|
||||
background: #F7F7F7;
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
font-size: 90%;
|
||||
color: #999;
|
||||
border-left: 4px solid #e9e9e9;
|
||||
padding-left: 0.8em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown blockquote p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown .anchor {
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.markdown .waiting {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.markdown h1:hover .anchor,
|
||||
.markdown h2:hover .anchor,
|
||||
.markdown h3:hover .anchor,
|
||||
.markdown h4:hover .anchor,
|
||||
.markdown h5:hover .anchor,
|
||||
.markdown h6:hover .anchor {
|
||||
opacity: 1;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.markdown > br,
|
||||
.markdown > p > br {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
background: white;
|
||||
padding: 0.5em;
|
||||
color: #333333;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-meta {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-strong,
|
||||
.hljs-emphasis,
|
||||
.hljs-quote {
|
||||
color: #df5000;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-type {
|
||||
color: #a71d5d;
|
||||
}
|
||||
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-attribute {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name {
|
||||
color: #63a35c;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-attr,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #795da3;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #55a532;
|
||||
background-color: #eaffea;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #bd2c00;
|
||||
background-color: #ffecec;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 代码高亮 */
|
||||
/* PrismJS 1.15.0
|
||||
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
background: none;
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::-moz-selection,
|
||||
pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection,
|
||||
code[class*="language-"] ::-moz-selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::selection,
|
||||
pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection,
|
||||
code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #9a6e3a;
|
||||
background: hsla(0, 0%, 100%, .5);
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #DD4A68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
@ -1,307 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>IconFont Demo</title>
|
||||
<link rel="shortcut icon" href="https://img.alicdn.com/tps/i4/TB1_oz6GVXXXXaFXpXXJDFnIXXX-64-64.ico" type="image/x-icon"/>
|
||||
<link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
|
||||
<link rel="stylesheet" href="demo.css">
|
||||
<link rel="stylesheet" href="iconfont.css">
|
||||
<script src="iconfont.js"></script>
|
||||
<!-- jQuery -->
|
||||
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
|
||||
<!-- 代码高亮 -->
|
||||
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="main">
|
||||
<h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank"></a></h1>
|
||||
<div class="nav-tabs">
|
||||
<ul id="tabs" class="dib-box">
|
||||
<li class="dib active"><span>Unicode</span></li>
|
||||
<li class="dib"><span>Font class</span></li>
|
||||
<li class="dib"><span>Symbol</span></li>
|
||||
</ul>
|
||||
|
||||
<a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=2373406" target="_blank" class="nav-more">查看项目</a>
|
||||
|
||||
</div>
|
||||
<div class="tab-container">
|
||||
<div class="content unicode" style="display: block;">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">向右旋转</div>
|
||||
<div class="code-name">&#xe66a;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">图片</div>
|
||||
<div class="code-name">&#xe616;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">锁</div>
|
||||
<div class="code-name">&#xe672;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">矩形</div>
|
||||
<div class="code-name">&#xe790;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">文本</div>
|
||||
<div class="code-name">&#xe652;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">按钮</div>
|
||||
<div class="code-name">&#xe648;</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="article markdown">
|
||||
<h2 id="unicode-">Unicode 引用</h2>
|
||||
<hr>
|
||||
|
||||
<p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
|
||||
<ul>
|
||||
<li>兼容性最好,支持 IE6+,及所有现代浏览器。</li>
|
||||
<li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
|
||||
<li>但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式</p>
|
||||
</blockquote>
|
||||
<p>Unicode 使用步骤如下:</p>
|
||||
<h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
|
||||
<pre><code class="language-css"
|
||||
>@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('iconfont.eot');
|
||||
src: url('iconfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('iconfont.woff2') format('woff2'),
|
||||
url('iconfont.woff') format('woff'),
|
||||
url('iconfont.ttf') format('truetype');
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||
<pre><code class="language-css"
|
||||
>.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
|
||||
<pre>
|
||||
<code class="language-html"
|
||||
><span class="iconfont">&#x33;</span>
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content font-class">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-xiangyouxuanzhuan"></span>
|
||||
<div class="name">
|
||||
向右旋转
|
||||
</div>
|
||||
<div class="code-name">.icon-xiangyouxuanzhuan
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-tupian"></span>
|
||||
<div class="name">
|
||||
图片
|
||||
</div>
|
||||
<div class="code-name">.icon-tupian
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-suo"></span>
|
||||
<div class="name">
|
||||
锁
|
||||
</div>
|
||||
<div class="code-name">.icon-suo
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-juxing"></span>
|
||||
<div class="name">
|
||||
矩形
|
||||
</div>
|
||||
<div class="code-name">.icon-juxing
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-wenben"></span>
|
||||
<div class="name">
|
||||
文本
|
||||
</div>
|
||||
<div class="code-name">.icon-wenben
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-button"></span>
|
||||
<div class="name">
|
||||
按钮
|
||||
</div>
|
||||
<div class="code-name">.icon-button
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="article markdown">
|
||||
<h2 id="font-class-">font-class 引用</h2>
|
||||
<hr>
|
||||
|
||||
<p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
|
||||
<p>与 Unicode 使用方式相比,具有如下特点:</p>
|
||||
<ul>
|
||||
<li>兼容性良好,支持 IE8+,及所有现代浏览器。</li>
|
||||
<li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
|
||||
<li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
|
||||
<li>不过因为本质上还是使用的字体,所以多色图标还是不支持的。</li>
|
||||
</ul>
|
||||
<p>使用步骤如下:</p>
|
||||
<h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
|
||||
<pre><code class="language-html"><link rel="stylesheet" href="./iconfont.css">
|
||||
</code></pre>
|
||||
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
|
||||
<pre><code class="language-html"><span class="iconfont icon-xxx"></span>
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<p>"
|
||||
iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<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-xiangyouxuanzhuan"></use>
|
||||
</svg>
|
||||
<div class="name">向右旋转</div>
|
||||
<div class="code-name">#icon-xiangyouxuanzhuan</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-tupian"></use>
|
||||
</svg>
|
||||
<div class="name">图片</div>
|
||||
<div class="code-name">#icon-tupian</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-suo"></use>
|
||||
</svg>
|
||||
<div class="name">锁</div>
|
||||
<div class="code-name">#icon-suo</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-juxing"></use>
|
||||
</svg>
|
||||
<div class="name">矩形</div>
|
||||
<div class="code-name">#icon-juxing</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-wenben"></use>
|
||||
</svg>
|
||||
<div class="name">文本</div>
|
||||
<div class="code-name">#icon-wenben</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-button"></use>
|
||||
</svg>
|
||||
<div class="name">按钮</div>
|
||||
<div class="code-name">#icon-button</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="article markdown">
|
||||
<h2 id="symbol-">Symbol 引用</h2>
|
||||
<hr>
|
||||
|
||||
<p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
|
||||
这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
|
||||
<ul>
|
||||
<li>支持多色图标了,不再受单色限制。</li>
|
||||
<li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
|
||||
<li>兼容性较差,支持 IE9+,及现代浏览器。</li>
|
||||
<li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
|
||||
</ul>
|
||||
<p>使用步骤如下:</p>
|
||||
<h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
|
||||
<pre><code class="language-html"><script src="./iconfont.js"></script>
|
||||
</code></pre>
|
||||
<h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
|
||||
<pre><code class="language-html"><style>
|
||||
.icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</code></pre>
|
||||
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
|
||||
<pre><code class="language-html"><svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-xxx"></use>
|
||||
</svg>
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('.tab-container .content:first').show()
|
||||
|
||||
$('#tabs li').click(function (e) {
|
||||
var tabContent = $('.tab-container .content')
|
||||
var index = $(this).index()
|
||||
|
||||
if ($(this).hasClass('active')) {
|
||||
return
|
||||
} else {
|
||||
$('#tabs li').removeClass('active')
|
||||
$(this).addClass('active')
|
||||
|
||||
tabContent.hide().eq(index).fadeIn()
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,123 +0,0 @@
|
||||
<template>
|
||||
<div class="animation-list">
|
||||
<div class="div-animation">
|
||||
<el-button @click="isShowAnimation = true">添加动画</el-button>
|
||||
<el-button @click="previewAnimate">预览动画</el-button>
|
||||
<div>
|
||||
<el-tag
|
||||
v-for="(tag, index) in curComponent.animations"
|
||||
:key="index"
|
||||
closable
|
||||
@close="removeAnimation(index)"
|
||||
>
|
||||
{{ tag.label }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 选择动画 -->
|
||||
<Modal v-model="isShowAnimation">
|
||||
<el-tabs v-model="animationActiveName">
|
||||
<el-tab-pane
|
||||
v-for="item in animationClassData"
|
||||
:key="item.label"
|
||||
:label="item.label"
|
||||
:name="item.label"
|
||||
>
|
||||
<el-scrollbar class="animate-container">
|
||||
<div
|
||||
v-for="(animate, index) in item.children"
|
||||
:key="index"
|
||||
class="animate"
|
||||
@mouseover="hoverPreviewAnimate = animate.value"
|
||||
@click="addAnimation(animate)"
|
||||
>
|
||||
<div :class="[hoverPreviewAnimate === animate.value && animate.value + ' animated']">
|
||||
{{ animate.label }}
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Modal from '@/components/canvas/components/Modal'
|
||||
import eventBus from '@/components/canvas/utils/eventBus'
|
||||
import animationClassData from '@/components/canvas/utils/animationClassData'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
components: { Modal },
|
||||
data() {
|
||||
return {
|
||||
isShowAnimation: false,
|
||||
hoverPreviewAnimate: '',
|
||||
animationActiveName: '进入',
|
||||
animationClassData,
|
||||
showAnimatePanel: false
|
||||
}
|
||||
},
|
||||
computed: mapState([
|
||||
'curComponent'
|
||||
]),
|
||||
methods: {
|
||||
addAnimation(animate) {
|
||||
this.$store.commit('addAnimation', animate)
|
||||
this.isShowAnimation = false
|
||||
},
|
||||
|
||||
previewAnimate() {
|
||||
eventBus.$emit('runAnimation')
|
||||
},
|
||||
|
||||
removeAnimation(index) {
|
||||
this.$store.commit('removeAnimation', index)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.animation-list {
|
||||
.div-animation {
|
||||
text-align: center;
|
||||
|
||||
& > div {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.el-tag {
|
||||
display: block;
|
||||
width: 50%;
|
||||
margin: auto;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-scrollbar__view {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
padding-left: 10px;
|
||||
|
||||
.animate > div {
|
||||
width: 100px;
|
||||
height: 60px;
|
||||
background: #f5f8fb;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 0 12px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
border-radius: 3px;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,153 +0,0 @@
|
||||
<!-- TODO: 这个页面后续将用 JSX 重构 -->
|
||||
<template>
|
||||
<div class="attr-list">
|
||||
<el-form>
|
||||
<el-form-item
|
||||
v-for="(key, index) in styleKeys.filter(item => item != 'rotate')"
|
||||
:key="index"
|
||||
:label="map[key]"
|
||||
>
|
||||
<el-color-picker
|
||||
v-if="key == 'borderColor'"
|
||||
v-model="curComponent.style[key]"
|
||||
/>
|
||||
<el-color-picker
|
||||
v-else-if="key == 'color'"
|
||||
v-model="curComponent.style[key]"
|
||||
/>
|
||||
<el-color-picker
|
||||
v-else-if="key == 'backgroundColor'"
|
||||
v-model="curComponent.style[key]"
|
||||
/>
|
||||
<el-select
|
||||
v-else-if="selectKey.includes(key)"
|
||||
v-model="curComponent.style[key]"
|
||||
>
|
||||
<template v-if="key == 'textAlign'">
|
||||
<el-option
|
||||
v-for="item in textAlignOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="key == 'borderStyle'">
|
||||
<el-option
|
||||
v-for="item in borderStyleOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-option
|
||||
v-for="item in verticalAlignOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</template>
|
||||
</el-select>
|
||||
<el-input
|
||||
v-else
|
||||
v-model="curComponent.style[key]"
|
||||
type="number"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="curComponent && !excludes.includes(curComponent.component)"
|
||||
:label="$t('panel.content')"
|
||||
>
|
||||
<el-input
|
||||
v-model="curComponent.propValue"
|
||||
type="textarea"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
excludes: ['Picture', 'Group', 'user-view'], // 这些组件不显示内容
|
||||
textAlignOptions: [
|
||||
{
|
||||
label: this.$t('panel.text_align_left'),
|
||||
value: 'left'
|
||||
},
|
||||
{
|
||||
label: this.$t('panel.text_align_center'),
|
||||
value: 'center'
|
||||
},
|
||||
{
|
||||
label: this.$t('panel.text_align_right'),
|
||||
value: 'right'
|
||||
}
|
||||
],
|
||||
borderStyleOptions: [
|
||||
{
|
||||
label: this.$t('panel.border_style_solid'),
|
||||
value: 'solid'
|
||||
},
|
||||
{
|
||||
label: this.$t('panel.border_style_dashed'),
|
||||
value: 'dashed'
|
||||
}
|
||||
],
|
||||
verticalAlignOptions: [
|
||||
{
|
||||
label: this.$t('panel.vertical_align_top'),
|
||||
value: 'top'
|
||||
},
|
||||
{
|
||||
label: this.$t('panel.vertical_align_middle'),
|
||||
value: 'middle'
|
||||
},
|
||||
{
|
||||
label: this.$t('panel.vertical_align_bottom'),
|
||||
value: 'bottom'
|
||||
}
|
||||
],
|
||||
selectKey: ['textAlign', 'borderStyle', 'verticalAlign'],
|
||||
map: {
|
||||
left: this.$t('panel.left'),
|
||||
top: this.$t('panel.top'),
|
||||
height: this.$t('panel.height'),
|
||||
width: this.$t('panel.width'),
|
||||
color: this.$t('panel.color'),
|
||||
backgroundColor: this.$t('panel.backgroundColor'),
|
||||
borderStyle: this.$t('panel.borderStyle'),
|
||||
borderWidth: this.$t('panel.borderWidth'),
|
||||
borderColor: this.$t('panel.borderColor'),
|
||||
borderRadius: this.$t('panel.borderRadius'),
|
||||
fontSize: this.$t('panel.fontSize'),
|
||||
fontWeight: this.$t('panel.fontWeight'),
|
||||
lineHeight: this.$t('panel.lineHeight'),
|
||||
letterSpacing: this.$t('panel.letterSpacing'),
|
||||
textAlign: this.$t('panel.textAlign'),
|
||||
opacity: this.$t('panel.opacity'),
|
||||
verticalAlign: this.$t('panel.verticalAlign')
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
styleKeys() {
|
||||
return this.$store.state.curComponent ? Object.keys(this.$store.state.curComponent.style) : []
|
||||
},
|
||||
curComponent() {
|
||||
return this.$store.state.curComponent
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.attr-list {
|
||||
overflow: auto;
|
||||
padding: 20px;
|
||||
padding-top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
@ -1,204 +0,0 @@
|
||||
<!-- TODO: 这个页面后续将用 JSX 重构 -->
|
||||
<template>
|
||||
<div class="attr-list">
|
||||
<el-form
|
||||
label-width="80px"
|
||||
size="mini"
|
||||
>
|
||||
<el-form-item
|
||||
v-for="(key, index) in styleKeys.filter(item => styleFilter.includes(item))"
|
||||
:key="index"
|
||||
:label="map[key]+':'"
|
||||
>
|
||||
<el-color-picker
|
||||
v-if="key == 'borderColor'"
|
||||
v-model="curComponent.style[key]"
|
||||
/>
|
||||
<el-color-picker
|
||||
v-else-if="key == 'color'"
|
||||
v-model="curComponent.style[key]"
|
||||
/>
|
||||
<el-color-picker
|
||||
v-else-if="key == 'backgroundColor'"
|
||||
v-model="curComponent.style[key]"
|
||||
/>
|
||||
<el-select
|
||||
v-else-if="selectKey.includes(key)"
|
||||
v-model="curComponent.style[key]"
|
||||
>
|
||||
<template v-if="key == 'textAlign'">
|
||||
<el-option
|
||||
v-for="item in textAlignOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="key == 'borderStyle'">
|
||||
<el-option
|
||||
v-for="item in borderStyleOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-option
|
||||
v-for="item in verticalAlignOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</template>
|
||||
</el-select>
|
||||
<el-input
|
||||
v-else
|
||||
v-model="curComponent.style[key]"
|
||||
type="number"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('panel.content_style')+':'">
|
||||
<div
|
||||
v-if="curComponent.type==='v-text'"
|
||||
style="width: 100%;max-height: 400px;overflow: auto"
|
||||
>
|
||||
<VText
|
||||
style="border: 1px solid #dcdfe6;border-radius:4px;background-color: #f7f8fa;"
|
||||
:prop-value="curComponent.propValue"
|
||||
:element="curComponent"
|
||||
:edit-mode="'edit'"
|
||||
:style="getComponentStyleDefault(curComponent.style)"
|
||||
/>
|
||||
</div>
|
||||
<rect-shape
|
||||
v-if="curComponent.type==='rect-shape'"
|
||||
style="width: 200px!important;height: 100px!important;"
|
||||
:prop-value="curComponent.propValue"
|
||||
:element="curComponent"
|
||||
:style="getComponentStyleDefault(curComponent.style)"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VText from '@/components/canvas/customComponent/VText'
|
||||
import RectShape from '@/components/canvas/customComponent/RectShape'
|
||||
import { getStyle } from '@/components/canvas/utils/style'
|
||||
|
||||
export default {
|
||||
components: { VText, RectShape },
|
||||
data() {
|
||||
return {
|
||||
excludes: ['Picture', 'Group', 'view'], // 这些组件不显示内容
|
||||
textAlignOptions: [
|
||||
{
|
||||
label: this.$t('panel.text_align_left'),
|
||||
value: 'left'
|
||||
},
|
||||
{
|
||||
label: this.$t('panel.text_align_center'),
|
||||
value: 'center'
|
||||
},
|
||||
{
|
||||
label: this.$t('panel.text_align_right'),
|
||||
value: 'right'
|
||||
}
|
||||
],
|
||||
borderStyleOptions: [
|
||||
{
|
||||
label: this.$t('panel.border_style_solid'),
|
||||
value: 'solid'
|
||||
},
|
||||
{
|
||||
label: this.$t('panel.border_style_dashed'),
|
||||
value: 'dashed'
|
||||
}
|
||||
],
|
||||
verticalAlignOptions: [
|
||||
{
|
||||
label: this.$t('panel.vertical_align_top'),
|
||||
value: 'top'
|
||||
},
|
||||
{
|
||||
label: this.$t('panel.vertical_align_middle'),
|
||||
value: 'middle'
|
||||
},
|
||||
{
|
||||
label: this.$t('panel.vertical_align_bottom'),
|
||||
value: 'bottom'
|
||||
}
|
||||
],
|
||||
selectKey: ['textAlign', 'borderStyle', 'verticalAlign'],
|
||||
map: {
|
||||
left: this.$t('panel.left'),
|
||||
top: this.$t('panel.top'),
|
||||
height: this.$t('panel.height'),
|
||||
width: this.$t('panel.width'),
|
||||
color: this.$t('panel.color'),
|
||||
backgroundColor: this.$t('panel.backgroundColor'),
|
||||
borderStyle: this.$t('panel.borderStyle'),
|
||||
borderWidth: this.$t('panel.borderWidth'),
|
||||
borderColor: this.$t('panel.borderColor'),
|
||||
borderRadius: this.$t('panel.borderRadius'),
|
||||
fontSize: this.$t('panel.fontSize'),
|
||||
fontWeight: this.$t('panel.fontWeight'),
|
||||
lineHeight: this.$t('panel.lineHeight'),
|
||||
letterSpacing: this.$t('panel.letterSpacing'),
|
||||
textAlign: this.$t('panel.textAlign'),
|
||||
opacity: this.$t('panel.opacity'),
|
||||
verticalAlign: this.$t('panel.verticalAlign')
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
styleKeys() {
|
||||
return this.$store.state.curComponent ? Object.keys(this.$store.state.curComponent.style) : []
|
||||
},
|
||||
curComponent() {
|
||||
return this.$store.state.curComponent
|
||||
},
|
||||
styleFilter() {
|
||||
const filter = [
|
||||
'fontSize',
|
||||
'fontWeight',
|
||||
'lineHeight',
|
||||
'letterSpacing',
|
||||
'textAlign',
|
||||
'color',
|
||||
'borderColor',
|
||||
'borderWidth',
|
||||
'backgroundColor',
|
||||
'borderStyle',
|
||||
'verticalAlign'
|
||||
]
|
||||
if (this.$store.state.curComponent.type === 'v-text') {
|
||||
filter.push('width', 'height')
|
||||
}
|
||||
return filter
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getComponentStyleDefault(style) {
|
||||
if (this.$store.state.curComponent.type === 'v-text') {
|
||||
return getStyle(style, ['top', 'left', 'rotate'])
|
||||
} else {
|
||||
return getStyle(style, ['top', 'left', 'rotate', 'height', 'width'])
|
||||
}
|
||||
// return style
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.attr-list {
|
||||
overflow: auto;
|
||||
padding: 5px;
|
||||
padding-top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
@ -1,73 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
class="component-list"
|
||||
@dragstart="handleDragStart"
|
||||
>
|
||||
<div
|
||||
v-for="(item, index) in componentList"
|
||||
:key="index"
|
||||
class="list"
|
||||
draggable
|
||||
:data-index="index"
|
||||
>
|
||||
<span
|
||||
class="iconfont"
|
||||
:class="'icon-' + item.icon"
|
||||
/>
|
||||
<span>{{ item.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import componentList from '@/components/canvas/customComponent/component-list'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
componentList
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleDragStart(e) {
|
||||
e.dataTransfer.setData('index', e.target.dataset.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.component-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
padding: 10px;
|
||||
|
||||
.list {
|
||||
width: 45%;
|
||||
border: 1px solid #ddd;
|
||||
cursor: grab;
|
||||
margin-bottom: 10px;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
padding: 2px 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
margin-right: 4px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.icon-wenben,
|
||||
.icon-tupian {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,99 +0,0 @@
|
||||
<template>
|
||||
<div class="event-list">
|
||||
<div class="div-events">
|
||||
<el-button @click="isShowEvent = true">添加事件</el-button>
|
||||
<div>
|
||||
<el-tag
|
||||
v-for="event in Object.keys(curComponent.events)"
|
||||
:key="event"
|
||||
closable
|
||||
@close="removeEvent(event)"
|
||||
>
|
||||
{{ event }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 选择事件 -->
|
||||
<Modal v-model="isShowEvent">
|
||||
<el-tabs v-model="eventActiveName">
|
||||
<el-tab-pane
|
||||
v-for="item in eventList"
|
||||
:key="item.key"
|
||||
:label="item.label"
|
||||
:name="item.key"
|
||||
style="padding: 0 20px"
|
||||
>
|
||||
<el-input
|
||||
v-if="item.key == 'redirect'"
|
||||
v-model="item.param"
|
||||
type="textarea"
|
||||
placeholder="请输入完整的 URL"
|
||||
/>
|
||||
<el-input
|
||||
v-if="item.key == 'alert'"
|
||||
v-model="item.param"
|
||||
type="textarea"
|
||||
placeholder="请输入要 alert 的内容"
|
||||
/>
|
||||
<el-button
|
||||
style="margin-top: 20px;"
|
||||
@click="addEvent(item.key, item.param)"
|
||||
>确定</el-button>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import Modal from '@/components/canvas/components/Modal'
|
||||
import { eventList } from '@/components/canvas/utils/events'
|
||||
|
||||
export default {
|
||||
components: { Modal },
|
||||
data() {
|
||||
return {
|
||||
isShowEvent: false,
|
||||
eventURL: '',
|
||||
eventActiveName: 'redirect',
|
||||
eventList
|
||||
}
|
||||
},
|
||||
computed: mapState([
|
||||
'curComponent'
|
||||
]),
|
||||
methods: {
|
||||
addEvent(event, param) {
|
||||
this.isShowEvent = false
|
||||
this.$store.commit('addEvent', { event, param })
|
||||
},
|
||||
|
||||
removeEvent(event) {
|
||||
this.$store.commit('removeEvent', event)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.event-list {
|
||||
.div-events {
|
||||
text-align: center;
|
||||
padding: 0 20px;
|
||||
|
||||
.el-button {
|
||||
display: inline-block;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.el-tag {
|
||||
display: block;
|
||||
width: 50%;
|
||||
margin: auto;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,56 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="show"
|
||||
class="modal-bg"
|
||||
@click="hide"
|
||||
>
|
||||
<div
|
||||
class="fadeInLeft animated modal"
|
||||
@click="stopPropagation"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
model: {
|
||||
prop: 'show',
|
||||
event: 'change'
|
||||
},
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
hide() {
|
||||
this.$emit('change')
|
||||
},
|
||||
|
||||
stopPropagation(e) {
|
||||
e.stopPropagation()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.modal-bg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,.5);
|
||||
z-index: 1001;
|
||||
|
||||
.modal {
|
||||
width: 400px;
|
||||
background: #fff;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -138,6 +138,18 @@
|
||||
<span class="icon iconfont icon-icon_clear_outlined icon16" />
|
||||
<span class="text14 margin-left8">{{ $t('panel.clean_canvas') }}</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="showWatermarkSetting"
|
||||
>
|
||||
<span class="icon iconfont icon-WATERMARK icon16" />
|
||||
<span class="text14 margin-left8">{{ $t('panel.watermark') }}</span>
|
||||
<el-switch
|
||||
v-model="panelInfo.watermarkOpen"
|
||||
:class="[{['grid-active']: panelInfo.watermarkOpen},'margin-left8']"
|
||||
size="mini"
|
||||
@change="styleChange"
|
||||
/>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</span>
|
||||
@ -250,6 +262,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showWatermarkSetting() {
|
||||
return this.panelInfo.watermarkInfo && this.panelInfo.watermarkInfo.settingContent.enable && this.panelInfo.watermarkInfo.settingContent.enablePanelCustom
|
||||
},
|
||||
panelInfo() {
|
||||
return this.$store.state.panel.panelInfo
|
||||
},
|
||||
@ -428,9 +443,10 @@ export default {
|
||||
if (_this.$store.state.cacheStyleChangeTimes > 0) {
|
||||
const requestInfo = _this.savePrepare()
|
||||
const cacheRequest = {
|
||||
...this.panelInfo,
|
||||
...deepCopy(this.panelInfo),
|
||||
...requestInfo
|
||||
}
|
||||
cacheRequest.watermarkInfo.settingContent = JSON.stringify(this.panelInfo.watermarkInfo.settingContent)
|
||||
saveCache(cacheRequest)
|
||||
_this.$store.state.cacheStyleChangeTimes = 0
|
||||
}
|
||||
@ -440,6 +456,7 @@ export default {
|
||||
// 保存到数据库
|
||||
const requestInfo = {
|
||||
id: this.panelInfo.id,
|
||||
watermarkOpen: this.panelInfo.watermarkOpen,
|
||||
panelStyle: JSON.stringify(this.canvasStyleData),
|
||||
panelData: JSON.stringify(this.componentData)
|
||||
}
|
||||
@ -610,6 +627,9 @@ export default {
|
||||
}
|
||||
})
|
||||
this.cancelMobileLayoutStatue(sourceComponentData)
|
||||
},
|
||||
styleChange() {
|
||||
this.$store.commit('canvasChange')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,16 @@
|
||||
v-show="existLinkage"
|
||||
class="bar-main"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
v-show="isPublicLink && !isNewBlank"
|
||||
class="bar-main-left"
|
||||
>
|
||||
<el-button
|
||||
size="mini"
|
||||
@click="back2Last"
|
||||
><i class="icon iconfont el-icon-back" />{{ $t('chart.back') }}</el-button>
|
||||
</div>
|
||||
<div class="bar-main-right">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="warning"
|
||||
@ -28,6 +37,12 @@ export default {
|
||||
})
|
||||
return linkageFiltersCount
|
||||
},
|
||||
isPublicLink() {
|
||||
return this.$router.currentRoute.path === '/delink'
|
||||
},
|
||||
isNewBlank() {
|
||||
return window.history.length === 1
|
||||
},
|
||||
...mapState([
|
||||
'componentData'
|
||||
])
|
||||
@ -36,23 +51,39 @@ export default {
|
||||
clearAllLinkage() {
|
||||
this.$store.commit('clearPanelLinkageInfo')
|
||||
bus.$emit('clear_panel_linkage', { viewId: 'all' })
|
||||
},
|
||||
back2Last() {
|
||||
this.$router.back(-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bar-main{
|
||||
position: absolute;
|
||||
.bar-main {
|
||||
display: flex;
|
||||
div {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
height: 20px;
|
||||
border-radius:2px;
|
||||
padding-left: 3px;
|
||||
padding-right: 0px;
|
||||
cursor:pointer!important;
|
||||
}
|
||||
}
|
||||
.bar-main-right{
|
||||
right: 0px;
|
||||
z-index: 10;
|
||||
height: 20px;
|
||||
border-radius:2px;
|
||||
padding-left: 3px;
|
||||
padding-right: 0px;
|
||||
cursor:pointer!important;
|
||||
opacity: 0.8;
|
||||
/*background-color: #0a7be0;*/
|
||||
}
|
||||
|
||||
.bar-main-left {
|
||||
left: 0px;
|
||||
opacity: 0;
|
||||
height: fit-content;
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -11,6 +11,7 @@
|
||||
:terminal="terminal"
|
||||
:element="config"
|
||||
:canvas-id="canvasId"
|
||||
:chart="chart"
|
||||
:show-position="showPosition"
|
||||
@showViewDetails="showViewDetails"
|
||||
/>
|
||||
@ -65,6 +66,7 @@
|
||||
:screen-shot="screenShot"
|
||||
:canvas-style-data="canvasStyleData"
|
||||
:show-position="showPosition"
|
||||
@fill-chart-2-parent="setChartData"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -146,7 +148,8 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
previewVisible: false
|
||||
previewVisible: false,
|
||||
chart: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -211,6 +214,9 @@ export default {
|
||||
runAnimation(this.$el, this.config.animations)
|
||||
},
|
||||
methods: {
|
||||
setChartData(chart) {
|
||||
this.chart = chart
|
||||
},
|
||||
getStyle,
|
||||
getShapeStyleIntDeDrag(style, prop) {
|
||||
if (prop === 'rotate') {
|
||||
@ -342,7 +348,7 @@ export default {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
</style>
|
||||
|
@ -107,6 +107,7 @@
|
||||
:canvas-style-data="canvasStyleData"
|
||||
@input="handleInput"
|
||||
@trigger-plugin-edit="pluginEditHandler"
|
||||
@fill-chart-2-parent="setChartData"
|
||||
/>
|
||||
</de-drag>
|
||||
<!--拖拽阴影部分-->
|
||||
@ -162,7 +163,7 @@ import UserViewDialog from '@/components/canvas/customComponent/UserViewDialog'
|
||||
import DeOutWidget from '@/components/dataease/DeOutWidget'
|
||||
import DragShadow from '@/components/deDrag/Shadow'
|
||||
import bus from '@/utils/bus'
|
||||
import LinkJumpSet from '@/views/panel/LinkJumpSet'
|
||||
import LinkJumpSet from '@/views/panel/linkJumpSet'
|
||||
import { buildFilterMap, buildViewKeyMap, formatCondition, valueValid, viewIdMatch } from '@/utils/conditionUtil'
|
||||
// 挤占式画布
|
||||
import _ from 'lodash'
|
||||
@ -931,7 +932,7 @@ export default {
|
||||
return !this.linkageSettingStatus && !this.batchOptStatus
|
||||
},
|
||||
showGrid() {
|
||||
if (this.canvasStyleData && this.canvasStyleData.aidedDesign) {
|
||||
if (this.canvasStyleData && this.canvasStyleData.aidedDesign && this.canvasId === 'canvas-main') {
|
||||
return this.canvasStyleData.aidedDesign.showGrid
|
||||
} else {
|
||||
return false
|
||||
@ -1096,6 +1097,13 @@ export default {
|
||||
created() {
|
||||
},
|
||||
methods: {
|
||||
setChartData(chart) {
|
||||
this.componentData.forEach((item, index) => {
|
||||
if (item.type === 'view' && item.component === 'user-view' && item.propValue.viewId === chart.id) {
|
||||
this.$refs['deDragRef'][index].setChartData(chart)
|
||||
}
|
||||
})
|
||||
},
|
||||
triggerResetButton() {
|
||||
this.triggerSearchButton(true)
|
||||
},
|
||||
|
@ -94,7 +94,7 @@
|
||||
>
|
||||
<i
|
||||
class="icon iconfont icon-shezhi"
|
||||
style="margin-top:2px"
|
||||
style="margin-top:2px; width: 16px;"
|
||||
/>
|
||||
</span>
|
||||
</setting-menu>
|
||||
@ -140,6 +140,11 @@
|
||||
<i class="icon iconfont icon-com-jump" />
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<map-layer-controller
|
||||
v-if="chart && showMapLayerController"
|
||||
:chart="chart"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!--跳转设置-->
|
||||
@ -182,12 +187,13 @@ import bus from '@/utils/bus'
|
||||
import SettingMenu from '@/components/canvas/components/editor/SettingMenu'
|
||||
import LinkageField from '@/components/canvas/components/editor/LinkageField'
|
||||
import toast from '@/components/canvas/utils/toast'
|
||||
import FieldsList from '@/components/canvas/components/editor/fieldsList'
|
||||
import LinkJumpSet from '@/views/panel/LinkJumpSet'
|
||||
import FieldsList from '@/components/canvas/components/editor/FieldsList'
|
||||
import LinkJumpSet from '@/views/panel/linkJumpSet'
|
||||
import Background from '@/views/background/index'
|
||||
import MapLayerController from '@/views/chart/components/map/MapLayerController'
|
||||
|
||||
export default {
|
||||
components: { Background, LinkJumpSet, FieldsList, SettingMenu, LinkageField },
|
||||
components: { Background, LinkJumpSet, FieldsList, SettingMenu, LinkageField, MapLayerController },
|
||||
|
||||
props: {
|
||||
canvasId: {
|
||||
@ -226,6 +232,10 @@ export default {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'NotProvided'
|
||||
},
|
||||
chart: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@ -249,6 +259,13 @@ export default {
|
||||
},
|
||||
|
||||
computed: {
|
||||
yaxis() {
|
||||
if (!this.chart) return []
|
||||
return JSON.parse(this.chart.yaxis)
|
||||
},
|
||||
showMapLayerController() {
|
||||
return this.curComponent.type === 'view' && this.terminal === 'pc' && this.curComponent.propValue.innerType === 'map' && this.yaxis.length > 1
|
||||
},
|
||||
detailsShow() {
|
||||
return this.curComponent.type === 'view' && this.terminal === 'pc' && this.curComponent.propValue.innerType !== 'richTextView'
|
||||
},
|
||||
@ -519,7 +536,7 @@ export default {
|
||||
background-color: var(--primary, #3370ff);
|
||||
}
|
||||
|
||||
.bar-main i {
|
||||
.bar-main ::v-deep i {
|
||||
color: white;
|
||||
float: right;
|
||||
margin-right: 3px;
|
||||
|
@ -1,148 +0,0 @@
|
||||
<template>
|
||||
|
||||
<el-popover
|
||||
ref="popover"
|
||||
width="340"
|
||||
trigger="click"
|
||||
>
|
||||
<el-row>
|
||||
<el-form
|
||||
ref="form"
|
||||
size="mini"
|
||||
label-width="70px"
|
||||
>
|
||||
<el-form-item :label="$t('panel.enable_jump')">
|
||||
<el-switch
|
||||
v-model="linkInfo.enable"
|
||||
size="mini"
|
||||
/>
|
||||
<span
|
||||
v-show="linkInfo.enable"
|
||||
style="color: #909399; font-size: 8px;margin-left: 3px"
|
||||
>
|
||||
Tips:{{ $t('panel.link_open_tips') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('panel.open_mode')">
|
||||
<el-radio-group
|
||||
v-model="linkInfo.openMode"
|
||||
:disabled="!linkInfo.enable"
|
||||
>
|
||||
<el-radio label="_blank">{{ $t('panel.new_window') }}</el-radio>
|
||||
<el-radio label="_self">{{ $t('panel.now_window') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('panel.hyperLinks')">
|
||||
<el-input
|
||||
v-model="linkInfo.content"
|
||||
:disabled="!linkInfo.enable"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="onSubmit"
|
||||
>{{ $t('panel.confirm') }}</el-button>
|
||||
<el-button @click="onClose">{{ $t('panel.cancel') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<i
|
||||
slot="reference"
|
||||
class="icon iconfont icon-font icon-chaolianjie1"
|
||||
/>
|
||||
</el-popover>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import { deepCopy } from '@/components/canvas/utils/utils'
|
||||
import { checkAddHttp } from '@/utils/urlUtils'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
linkInfo: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
componentType: null,
|
||||
linkageActiveStatus: false,
|
||||
editFilter: [
|
||||
'view',
|
||||
'custom'
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'curComponent'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
this.linkInfo.content = checkAddHttp(this.linkInfo.content)
|
||||
this.curComponent.hyperlinks = deepCopy(this.linkInfo)
|
||||
this.$store.commit('canvasChange')
|
||||
this.popoverClose()
|
||||
},
|
||||
onClose() {
|
||||
this.$emit('close')
|
||||
this.popoverClose()
|
||||
},
|
||||
popoverClose() {
|
||||
this.$refs.popover.showPopper = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.slot-class{
|
||||
color: white;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
.ellip{
|
||||
/*width: 100%;*/
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
overflow: hidden;/*超出部分隐藏*/
|
||||
white-space: nowrap;/*不换行*/
|
||||
text-overflow:ellipsis;/*超出部分文字以...显示*/
|
||||
background-color: #f7f8fa;
|
||||
color: #3d4d66;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
height: 24px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.select-filed{
|
||||
/*width: 100%;*/
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
overflow: hidden;/*超出部分隐藏*/
|
||||
white-space: nowrap;/*不换行*/
|
||||
text-overflow:ellipsis;/*超出部分文字以...显示*/
|
||||
color: #3d4d66;
|
||||
font-size: 12px;
|
||||
line-height: 35px;
|
||||
height: 35px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
::v-deep .el-popover{
|
||||
height: 200px;
|
||||
overflow: auto;
|
||||
}
|
||||
.icon-font{
|
||||
color: white;
|
||||
}
|
||||
|
||||
</style>
|
@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
:id="previewMainDomId"
|
||||
class="bg"
|
||||
:style="customStyle"
|
||||
@scroll="canvasScroll"
|
||||
@ -72,6 +73,8 @@ import CanvasOptBar from '@/components/canvas/components/editor/CanvasOptBar'
|
||||
import bus from '@/utils/bus'
|
||||
import { buildFilterMap, buildViewKeyMap, formatCondition, valueValid, viewIdMatch } from '@/utils/conditionUtil'
|
||||
import { hasDataPermission } from '@/utils/permission'
|
||||
import { activeWatermark } from '@/components/canvas/tools/watermark'
|
||||
import { userLoginInfo } from '@/api/systemInfo/userLogin'
|
||||
|
||||
const erd = elementResizeDetectorMaker()
|
||||
|
||||
@ -141,6 +144,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
previewMainDomId: 'preview-main-' + this.canvasId,
|
||||
previewDomId: 'preview-' + this.canvasId,
|
||||
previewRefId: 'preview-ref-' + this.canvasId,
|
||||
previewTempDomId: 'preview-temp-' + this.canvasId,
|
||||
@ -291,6 +295,7 @@ export default {
|
||||
this.$cancelRequest('/static-resource/**')
|
||||
},
|
||||
mounted() {
|
||||
this.initWatermark()
|
||||
this._isMobile()
|
||||
this.initListen()
|
||||
this.$store.commit('clearLinkageSettingInfo', false)
|
||||
@ -309,6 +314,14 @@ export default {
|
||||
bus.$off('trigger-reset-button', this.triggerResetButton)
|
||||
},
|
||||
methods: {
|
||||
initWatermark() {
|
||||
if (this.panelInfo.watermarkInfo) {
|
||||
userLoginInfo().then(res => {
|
||||
const userInfo = res.data
|
||||
activeWatermark(this.panelInfo.watermarkInfo.settingContent, userInfo, 'preview-main-canvas-main', this.canvasId, this.panelInfo.watermarkOpen)
|
||||
})
|
||||
}
|
||||
},
|
||||
isMainCanvas() {
|
||||
return this.canvasId === 'canvas-main'
|
||||
},
|
||||
|
@ -1,295 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
class="bg"
|
||||
:style="customStyle"
|
||||
>
|
||||
<canvas-opt-bar />
|
||||
<div
|
||||
id="canvasInfoMain"
|
||||
ref="canvasInfoMain"
|
||||
style="width: 100%;height: 100%"
|
||||
>
|
||||
<div
|
||||
id="canvasInfoTemp"
|
||||
ref="canvasInfoTemp"
|
||||
:style="[{height:mainHeight},screenShotStyle]"
|
||||
class="main-class"
|
||||
@mouseup="deselectCurComponent"
|
||||
@mousedown="handleMouseDown"
|
||||
>
|
||||
<el-row
|
||||
v-if="componentDataShow.length===0"
|
||||
style="height: 100%;"
|
||||
class="custom-position"
|
||||
>
|
||||
{{ $t('panel.panelNull') }}
|
||||
</el-row>
|
||||
<ComponentWrapper
|
||||
v-for="(item, index) in componentDataInfo"
|
||||
:key="index"
|
||||
:canvas-id="canvasId"
|
||||
:config="item"
|
||||
:search-count="searchCount"
|
||||
:canvas-style-data="canvasStyleData"
|
||||
:in-screen="inScreen"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getStyle } from '@/components/canvas/utils/style'
|
||||
import { mapState } from 'vuex'
|
||||
import ComponentWrapper from './ComponentWrapper'
|
||||
import { changeStyleWithScale } from '@/components/canvas/utils/translate'
|
||||
import { uuid } from 'vue-uuid'
|
||||
import { deepCopy, imgUrlTrans } from '@/components/canvas/utils/utils'
|
||||
import eventBus from '@/components/canvas/utils/eventBus'
|
||||
import elementResizeDetectorMaker from 'element-resize-detector'
|
||||
import CanvasOptBar from '@/components/canvas/components/editor/CanvasOptBar'
|
||||
|
||||
export default {
|
||||
components: { ComponentWrapper, CanvasOptBar },
|
||||
model: {
|
||||
prop: 'show',
|
||||
event: 'change'
|
||||
},
|
||||
props: {
|
||||
canvasId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
screenShot: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showType: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'full'
|
||||
},
|
||||
inScreen: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isShowPreview: false,
|
||||
panelId: '',
|
||||
needToChangeHeight: [
|
||||
'top',
|
||||
'height'
|
||||
],
|
||||
needToChangeWidth: [
|
||||
'left',
|
||||
'width',
|
||||
'fontSize',
|
||||
'borderWidth',
|
||||
'letterSpacing'
|
||||
],
|
||||
scaleWidth: '100',
|
||||
scaleHeight: '100',
|
||||
timer: null,
|
||||
componentDataShow: [],
|
||||
mainWidth: '100%',
|
||||
mainHeight: '100%',
|
||||
searchCount: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
customStyle() {
|
||||
let style = {
|
||||
width: '100%'
|
||||
}
|
||||
if (this.canvasStyleData.openCommonStyle) {
|
||||
if (this.canvasStyleData.panel.backgroundType === 'image' && this.canvasStyleData.panel.imageUrl) {
|
||||
style = {
|
||||
background: `url(${imgUrlTrans(this.canvasStyleData.panel.imageUrl)}) no-repeat`,
|
||||
...style
|
||||
}
|
||||
} else if (this.canvasStyleData.panel.backgroundType === 'color') {
|
||||
style = {
|
||||
background: this.canvasStyleData.panel.color,
|
||||
...style
|
||||
}
|
||||
}
|
||||
}
|
||||
return style
|
||||
},
|
||||
screenShotStyle() {
|
||||
return this.screenShot ? this.customStyle : {}
|
||||
},
|
||||
// 此处单独计算componentData的值 不放入全局mapState中
|
||||
componentDataInfo() {
|
||||
return this.componentDataShow
|
||||
},
|
||||
...mapState([
|
||||
'isClickComponent',
|
||||
'curComponent',
|
||||
'componentData',
|
||||
'canvasStyleData',
|
||||
'componentGap'
|
||||
])
|
||||
},
|
||||
watch: {
|
||||
componentData: {
|
||||
handler(newVal, oldVla) {
|
||||
this.restore()
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
canvasStyleData: {
|
||||
handler(newVal, oldVla) {
|
||||
this.canvasStyleDataInit()
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const _this = this
|
||||
const erd = elementResizeDetectorMaker()
|
||||
// 监听div变动事件
|
||||
const mainDom = document.getElementById('canvasInfoMain')
|
||||
erd.listenTo(mainDom, element => {
|
||||
_this.$nextTick(() => {
|
||||
_this.restore()
|
||||
})
|
||||
})
|
||||
// 监听div变动事件
|
||||
const tempCanvas = document.getElementById('canvasInfoTemp')
|
||||
erd.listenTo(tempCanvas, element => {
|
||||
_this.$nextTick(() => {
|
||||
// 将mainHeight 修改为px 临时解决html2canvas 截图不全的问题
|
||||
_this.mainHeight = tempCanvas.scrollHeight + 'px!important'
|
||||
})
|
||||
})
|
||||
eventBus.$on('openChartDetailsDialog', this.openChartDetailsDialog)
|
||||
_this.$store.commit('clearLinkageSettingInfo', false)
|
||||
_this.canvasStyleDataInit()
|
||||
},
|
||||
beforeDestroy() {
|
||||
eventBus.$off('openChartDetailsDialog', this.openChartDetailsDialog)
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
methods: {
|
||||
canvasStyleDataInit() {
|
||||
// 数据刷新计时器
|
||||
this.searchCount = 0
|
||||
this.timer && clearInterval(this.timer)
|
||||
let refreshTime = 300000
|
||||
if (this.canvasStyleData.refreshTime && this.canvasStyleData.refreshTime > 0) {
|
||||
if (this.canvasStyleData.refreshUnit === 'second') {
|
||||
refreshTime = this.canvasStyleData.refreshTime * 1000
|
||||
} else {
|
||||
refreshTime = this.canvasStyleData.refreshTime * 60000
|
||||
}
|
||||
}
|
||||
this.timer = setInterval(() => {
|
||||
this.searchCount++
|
||||
}, refreshTime)
|
||||
},
|
||||
changeStyleWithScale,
|
||||
getStyle,
|
||||
restore() {
|
||||
const canvasHeight = document.getElementById('canvasInfoMain').offsetHeight
|
||||
const canvasWidth = document.getElementById('canvasInfoMain').offsetWidth
|
||||
this.scaleWidth = canvasWidth * 100 / parseInt(this.canvasStyleData.width)// 获取宽度比
|
||||
this.scaleHeight = canvasHeight * 100 / parseInt(this.canvasStyleData.height)// 获取高度比
|
||||
this.handleScaleChange()
|
||||
},
|
||||
resetID(data) {
|
||||
if (data) {
|
||||
data.forEach(item => {
|
||||
item.type !== 'custom' && (item.id = uuid.v1())
|
||||
})
|
||||
}
|
||||
return data
|
||||
},
|
||||
format(value, scale) {
|
||||
return value * parseInt(scale) / 100
|
||||
},
|
||||
handleScaleChange() {
|
||||
if (this.componentData) {
|
||||
const componentData = deepCopy(this.componentData)
|
||||
componentData.forEach(component => {
|
||||
Object.keys(component.style).forEach(key => {
|
||||
if (this.needToChangeHeight.includes(key)) {
|
||||
component.style[key] = this.format(component.style[key], this.scaleHeight)
|
||||
}
|
||||
if (this.needToChangeWidth.includes(key)) {
|
||||
component.style[key] = this.format(component.style[key], this.scaleWidth)
|
||||
}
|
||||
})
|
||||
})
|
||||
this.componentDataShow = componentData
|
||||
this.$nextTick(() => (eventBus.$emit('resizing', '')))
|
||||
}
|
||||
},
|
||||
deselectCurComponent(e) {
|
||||
if (!this.isClickComponent) {
|
||||
this.$store.commit('setCurComponent', { component: null, index: null })
|
||||
}
|
||||
},
|
||||
handleMouseDown() {
|
||||
this.$store.commit('setClickComponentStatus', false)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bg {
|
||||
padding: 5px;
|
||||
min-width: 600px;
|
||||
min-height: 300px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
background-size: 100% 100% !important;
|
||||
}
|
||||
|
||||
.main-class {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: 100% 100% !important;
|
||||
}
|
||||
|
||||
.custom-position {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
flex-flow: row nowrap;
|
||||
color: #9ea6b2;
|
||||
}
|
||||
|
||||
.gap_class {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.dialog-css ::v-deep .el-dialog__title {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.dialog-css ::v-deep .el-dialog__header {
|
||||
padding: 40px 20px 0;
|
||||
}
|
||||
|
||||
.dialog-css ::v-deep .el-dialog__body {
|
||||
padding: 10px 20px 20px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 0px !important;
|
||||
height: 0px !important;
|
||||
}
|
||||
|
||||
</style>
|
@ -1,204 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="width: 100%;">
|
||||
<el-dropdown
|
||||
trigger="click"
|
||||
@mouseup="handleMouseUp"
|
||||
>
|
||||
<el-button
|
||||
ref="trackButton"
|
||||
class="icon iconfont icon-shezhi"
|
||||
>TEST</el-button>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
icon="el-icon-document-copy"
|
||||
@click.native="copy"
|
||||
>{{ $t('panel.copy') }}</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
icon="el-icon-delete"
|
||||
@click.native="deleteComponent"
|
||||
>{{ $t('panel.delete') }}</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
icon="el-icon-upload2"
|
||||
@click.native="topComponent"
|
||||
>{{ $t('panel.topComponent') }}</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
icon="el-icon-download"
|
||||
@click.native="bottomComponent"
|
||||
>{{ $t('panel.bottomComponent') }}</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
icon="el-icon-arrow-up"
|
||||
@click.native="upComponent"
|
||||
>{{ $t('panel.upComponent') }}</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
icon="el-icon-arrow-down"
|
||||
@click.native="downComponent"
|
||||
>{{ $t('panel.downComponent') }}</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
icon="el-icon-link"
|
||||
@click.native="linkageSetting"
|
||||
>联动设置</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import bus from '@/utils/bus'
|
||||
import { getViewLinkageGather } from '@/api/panel/linkage'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
copyData: null,
|
||||
editFilter: [
|
||||
'view',
|
||||
'custom'
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: mapState([
|
||||
'menuTop',
|
||||
'menuLeft',
|
||||
'menuShow',
|
||||
'curComponent',
|
||||
'componentData',
|
||||
'canvasStyleData'
|
||||
]),
|
||||
methods: {
|
||||
trackButtonClick() {
|
||||
this.$refs.trackButton.click()
|
||||
this.$refs.trackButton.$el.click()
|
||||
},
|
||||
edit() {
|
||||
if (this.curComponent.type === 'view') {
|
||||
this.$store.dispatch('chart/setViewId', null)
|
||||
this.$store.dispatch('chart/setViewId', this.curComponent.propValue.viewId)
|
||||
bus.$emit('PanelSwitchComponent', { name: 'ChartEdit', param: { 'id': this.curComponent.propValue.viewId, 'optType': 'edit' }})
|
||||
}
|
||||
if (this.curComponent.type === 'custom') {
|
||||
bus.$emit('component-dialog-edit')
|
||||
}
|
||||
|
||||
// 编辑样式组件
|
||||
|
||||
if (this.curComponent.type === 'v-text' || this.curComponent.type === 'rect-shape') {
|
||||
bus.$emit('component-dialog-style')
|
||||
}
|
||||
},
|
||||
lock() {
|
||||
this.$store.commit('lock')
|
||||
},
|
||||
|
||||
unlock() {
|
||||
this.$store.commit('unlock')
|
||||
},
|
||||
|
||||
// 点击菜单时不取消当前组件的选中状态
|
||||
handleMouseUp() {
|
||||
this.$store.commit('setClickComponentStatus', true)
|
||||
},
|
||||
|
||||
cut() {
|
||||
this.deleteCurCondition()
|
||||
this.$store.commit('cut')
|
||||
},
|
||||
|
||||
copy() {
|
||||
this.$store.commit('copy')
|
||||
this.paste()
|
||||
},
|
||||
|
||||
paste() {
|
||||
this.$store.commit('paste', true)
|
||||
this.$store.commit('recordSnapshot')
|
||||
},
|
||||
|
||||
deleteComponent() {
|
||||
this.deleteCurCondition()
|
||||
this.$store.commit('deleteComponent')
|
||||
this.$store.commit('recordSnapshot')
|
||||
this.$store.commit('setCurComponent', { component: null, index: null })
|
||||
},
|
||||
|
||||
deleteCurCondition() {
|
||||
if (this.curComponent.type === 'custom') {
|
||||
this.$store.commit('removeViewFilter', this.curComponent.id)
|
||||
bus.$emit('delete-condition', { componentId: this.curComponent.id })
|
||||
}
|
||||
},
|
||||
|
||||
upComponent() {
|
||||
this.$store.commit('upComponent')
|
||||
this.$store.commit('recordSnapshot')
|
||||
},
|
||||
|
||||
downComponent() {
|
||||
this.$store.commit('downComponent')
|
||||
this.$store.commit('recordSnapshot')
|
||||
},
|
||||
|
||||
topComponent() {
|
||||
this.$store.commit('topComponent')
|
||||
this.$store.commit('recordSnapshot')
|
||||
},
|
||||
|
||||
bottomComponent() {
|
||||
this.$store.commit('bottomComponent')
|
||||
this.$store.commit('recordSnapshot')
|
||||
},
|
||||
linkageSetting() {
|
||||
// sourceViewId 也加入查询
|
||||
const targetViewIds = this.componentData.filter(item => item.type === 'view' && item.propValue && item.propValue.viewId)
|
||||
.map(item => item.propValue.viewId)
|
||||
|
||||
// 获取当前仪表板当前视图联动信息
|
||||
const requestInfo = {
|
||||
'panelId': this.$store.state.panel.panelInfo.id,
|
||||
'sourceViewId': this.curComponent.propValue.viewId,
|
||||
'targetViewIds': targetViewIds
|
||||
}
|
||||
getViewLinkageGather(requestInfo).then(rsp => {
|
||||
this.$store.commit('setLinkageInfo', rsp.data)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.contextmenu {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
|
||||
ul {
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
|
||||
box-sizing: border-box;
|
||||
margin: 5px 0;
|
||||
padding: 6px 0;
|
||||
|
||||
li {
|
||||
font-size: 14px;
|
||||
padding: 0 20px;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: #606266;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--background-color-base, #f5f7fa);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
File diff suppressed because it is too large
Load Diff
@ -1,69 +0,0 @@
|
||||
<template>
|
||||
<de-container style="height: 500px">
|
||||
<de-aside-container>
|
||||
this is test
|
||||
</de-aside-container>
|
||||
<de-main-container>
|
||||
this is test2
|
||||
</de-main-container>
|
||||
</de-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import DeMainContainer from '@/components/dataease/DeMainContainer'
|
||||
import DeContainer from '@/components/dataease/DeContainer'
|
||||
import DeAsideContainer from '@/components/dataease/DeAsideContainer'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'UserView',
|
||||
components: { DeMainContainer, DeContainer, DeAsideContainer },
|
||||
props: {
|
||||
chart: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
chartTable: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
refId: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'isClickComponent',
|
||||
'curComponent',
|
||||
'componentData',
|
||||
'canvasStyleData'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ms-aside-container {
|
||||
height: 50vh;
|
||||
min-width: 400px;
|
||||
max-width: 400px;
|
||||
padding: 0 0;
|
||||
}
|
||||
.ms-main-container {
|
||||
height: 50vh;
|
||||
border: 1px solid #E6E6E6;
|
||||
border-left: 0 solid;
|
||||
}
|
||||
.chart-class{
|
||||
height: 100%;
|
||||
}
|
||||
.table-class{
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
@ -526,6 +526,9 @@ export default {
|
||||
this.chartScale(this.changeScaleIndex)
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
'chart.yaxis': function(newVal, oldVal) {
|
||||
this.$emit('fill-chart-2-parent', this.chart)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@ -711,6 +714,7 @@ export default {
|
||||
// 将视图传入echart组件
|
||||
if (response.success) {
|
||||
this.chart = response.data
|
||||
this.$emit('fill-chart-2-parent', this.chart)
|
||||
this.getDataOnly(response.data, dataBroadcast)
|
||||
this.chart['position'] = this.inTab ? 'tab' : 'panel'
|
||||
// 记录当前数据
|
||||
|
@ -1,158 +0,0 @@
|
||||
<template>
|
||||
<div class="home">
|
||||
<Toolbar />
|
||||
<main>
|
||||
<section class="center">
|
||||
<div
|
||||
class="content"
|
||||
@drop="handleDrop"
|
||||
@dragover="handleDragOver"
|
||||
@mousedown="handleMouseDown"
|
||||
@mouseup="deselectCurComponent"
|
||||
>
|
||||
<Editor />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Editor from '@/components/Editor/index'
|
||||
import componentList from '@/components/canvas/customComponent/component-list' // 左侧列表数据
|
||||
import Toolbar from '@/components/Toolbar'
|
||||
import { deepCopy } from '@/utils/utils'
|
||||
import { mapState } from 'vuex'
|
||||
import generateID from '@/utils/generateID'
|
||||
import { uuid } from 'vue-uuid'
|
||||
|
||||
export default {
|
||||
components: { Editor, Toolbar },
|
||||
data() {
|
||||
return {
|
||||
activeName: 'attr',
|
||||
reSelectAnimateIndex: undefined
|
||||
}
|
||||
},
|
||||
computed: mapState([
|
||||
'componentData',
|
||||
'curComponent',
|
||||
'isClickComponent',
|
||||
'canvasStyleData'
|
||||
]),
|
||||
created() {
|
||||
this.restore()
|
||||
},
|
||||
methods: {
|
||||
restore() {
|
||||
// 用保存的数据恢复画布
|
||||
if (localStorage.getItem('canvasData')) {
|
||||
this.$store.commit('setComponentData', this.resetID(JSON.parse(localStorage.getItem('canvasData'))))
|
||||
}
|
||||
|
||||
if (localStorage.getItem('canvasStyle')) {
|
||||
this.$store.commit('setCanvasStyle', JSON.parse(localStorage.getItem('canvasStyle')))
|
||||
}
|
||||
},
|
||||
|
||||
resetID(data) {
|
||||
if (data) {
|
||||
data.forEach(item => {
|
||||
item.type !== 'custom' && (item.id = uuid.v1())
|
||||
})
|
||||
}
|
||||
|
||||
return data
|
||||
},
|
||||
|
||||
handleDrop(e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
let component
|
||||
const id = e.dataTransfer.getData('componentId')
|
||||
componentList.forEach(componentTemp => {
|
||||
if (id === componentTemp.id) {
|
||||
component = deepCopy(componentTemp)
|
||||
}
|
||||
})
|
||||
// const component = deepCopy(componentList[e.dataTransfer.getData('index')])
|
||||
component.style.top = e.offsetY
|
||||
component.style.left = e.offsetX
|
||||
component.id = generateID()
|
||||
this.$store.commit('addComponent', { component })
|
||||
this.$store.commit('recordSnapshot', 'handleDrop')
|
||||
},
|
||||
|
||||
handleDragOver(e) {
|
||||
e.preventDefault()
|
||||
e.dataTransfer.dropEffect = 'copy'
|
||||
},
|
||||
|
||||
handleMouseDown() {
|
||||
this.$store.commit('setClickComponentStatus', false)
|
||||
},
|
||||
|
||||
deselectCurComponent(e) {
|
||||
if (!this.isClickComponent) {
|
||||
this.$store.commit('setCurComponent', { component: null, index: null })
|
||||
}
|
||||
|
||||
// 0 左击 1 滚轮 2 右击
|
||||
if (e.button !== 2) {
|
||||
this.$store.commit('hideContextMenu')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.home {
|
||||
height: 100vh;
|
||||
background: #fff;
|
||||
|
||||
main {
|
||||
height: calc(100% - 64px);
|
||||
position: relative;
|
||||
|
||||
.left {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 200px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.right {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 262px;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.center {
|
||||
margin-left: 200px;
|
||||
margin-right: 262px;
|
||||
background: #f5f5f5;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
padding: 20px;
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
text-align: center;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,52 +0,0 @@
|
||||
body,
|
||||
button,
|
||||
input,
|
||||
p,
|
||||
li,
|
||||
ol,
|
||||
ul,
|
||||
div,
|
||||
section,
|
||||
article,
|
||||
td,
|
||||
th,
|
||||
span,
|
||||
textarea,
|
||||
form,
|
||||
footer,
|
||||
header,
|
||||
nav,
|
||||
main,
|
||||
address,
|
||||
aside,
|
||||
pre,
|
||||
canvas {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#app {
|
||||
/*overflow: hidden;*/
|
||||
}
|
||||
|
||||
.el-tabs {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.el-tabs__content {
|
||||
height: calc(100% - 55px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.el-tabs__nav-scroll {
|
||||
padding-left: 20px;
|
||||
}
|
154
frontend/src/components/canvas/tools/watermark.js
Normal file
154
frontend/src/components/canvas/tools/watermark.js
Normal file
@ -0,0 +1,154 @@
|
||||
// 动态创建水印元素的封装函数
|
||||
|
||||
export function watermark(settings, domId) {
|
||||
const watermarkDom = document.getElementById(domId)
|
||||
// 默认设置
|
||||
const defaultSettings = {
|
||||
watermark_txt: '',
|
||||
watermark_x: 20, // 水印起始位置x轴坐标
|
||||
watermark_y: 20, // 水印起始位置Y轴坐标
|
||||
watermark_rows: 20, // 水印行数
|
||||
watermark_cols: 20, // 水印列数
|
||||
watermark_x_space: 100, // 水印x轴间隔
|
||||
watermark_y_space: 50, // 水印y轴间隔
|
||||
watermark_color: '#aaa', // 水印字体颜色
|
||||
watermark_alpha: 0.4, // 水印透明度
|
||||
watermark_fontsize: '15px', // 水印字体大小
|
||||
watermark_font: '微软雅黑', // 水印字体
|
||||
watermark_width: 210, // 水印宽度
|
||||
watermark_height: 80, // 水印长度
|
||||
watermark_angle: 20 // 水印倾斜度数
|
||||
}
|
||||
// 根据函数的入参调整设置
|
||||
if (settings && typeof settings === 'object') {
|
||||
const src = settings || {}
|
||||
for (const key in src) {
|
||||
if (src[key] && defaultSettings[key] && src[key] === defaultSettings[key]) {
|
||||
continue
|
||||
} else if (src[key]) defaultSettings[key] = src[key]
|
||||
}
|
||||
}
|
||||
// 创建虚拟节点对象,在该节点对象中可以放元素,最后只需在页面中添加该节点对象即可。可提高性能
|
||||
const oTemp = document.createElement('p')
|
||||
// 获取页面最大宽度
|
||||
let page_width = watermarkDom.clientWidth
|
||||
const cutWidth = page_width * 0.0150
|
||||
page_width = page_width - cutWidth
|
||||
// 获取页面最大高度
|
||||
let page_height = watermarkDom.clientHeight - 56
|
||||
page_height = page_height < 400 ? 400 : page_height
|
||||
// page_height = Math.max(page_height, window.innerHeight - 30)
|
||||
// 如果将水印列数设置为0,或水印列数设置过大,超过页面最大宽度,则重新计算水印列数和水印x轴间隔
|
||||
if (defaultSettings.watermark_cols === 0 || (parseInt(defaultSettings.watermark_x + defaultSettings.watermark_width * defaultSettings.watermark_cols + defaultSettings.watermark_x_space * (defaultSettings.watermark_cols - 1)) > page_width)) {
|
||||
defaultSettings.watermark_cols = parseInt((page_width - defaultSettings.watermark_x + defaultSettings.watermark_x_space) / (defaultSettings.watermark_width + defaultSettings.watermark_x_space))
|
||||
defaultSettings.watermark_x_space = parseInt((page_width - defaultSettings.watermark_x - defaultSettings.watermark_width * defaultSettings.watermark_cols) / (defaultSettings.watermark_cols - 1))
|
||||
}
|
||||
// 如果将水印行数设置为0,或水印行数设置过大,超过页面最大长度,则重新计算水印行数和水印y轴间隔
|
||||
if (defaultSettings.watermark_rows === 0 || (parseInt(defaultSettings.watermark_y + defaultSettings.watermark_height * defaultSettings.watermark_rows + defaultSettings.watermark_y_space * (defaultSettings.watermark_rows - 1)) > page_height)) {
|
||||
defaultSettings.watermark_rows = parseInt((defaultSettings.watermark_y_space + page_height - defaultSettings.watermark_y) / (defaultSettings.watermark_height + defaultSettings.watermark_y_space))
|
||||
defaultSettings.watermark_y_space = parseInt(((page_height - defaultSettings.watermark_y) - defaultSettings.watermark_height * defaultSettings.watermark_rows) / (defaultSettings.watermark_rows - 1))
|
||||
}
|
||||
defaultSettings.watermark_rows = defaultSettings.watermark_rows < 2 ? 2 : defaultSettings.watermark_rows
|
||||
defaultSettings.watermark_cols = defaultSettings.watermark_cols < 2 ? 2 : defaultSettings.watermark_cols
|
||||
let x
|
||||
let y
|
||||
for (let i = 0; i < defaultSettings.watermark_rows; i++) {
|
||||
y = defaultSettings.watermark_y + (defaultSettings.watermark_y_space + defaultSettings.watermark_height) * i
|
||||
for (let j = 0; j < defaultSettings.watermark_cols; j++) {
|
||||
x = defaultSettings.watermark_x + (defaultSettings.watermark_width + defaultSettings.watermark_x_space) * j
|
||||
const mask_div = document.createElement('div')
|
||||
mask_div.id = 'mask_div' + i + j
|
||||
mask_div.className = 'mask_div'
|
||||
mask_div.appendChild(document.createTextNode(defaultSettings.watermark_txt))
|
||||
// 设置水印div倾斜显示
|
||||
mask_div.style.webkitTransform = 'rotate(-' + defaultSettings.watermark_angle + 'deg)'
|
||||
mask_div.style.MozTransform = 'rotate(-' + defaultSettings.watermark_angle + 'deg)'
|
||||
mask_div.style.msTransform = 'rotate(-' + defaultSettings.watermark_angle + 'deg)'
|
||||
mask_div.style.OTransform = 'rotate(-' + defaultSettings.watermark_angle + 'deg)'
|
||||
mask_div.style.transform = 'rotate(-' + defaultSettings.watermark_angle + 'deg)'
|
||||
mask_div.style.visibility = ''
|
||||
mask_div.style.position = 'absolute'
|
||||
mask_div.style.left = x + 'px'
|
||||
mask_div.style.top = y + 'px'
|
||||
mask_div.style.overflow = 'hidden'
|
||||
mask_div.style.zIndex = '9999'
|
||||
// 让水印不遮挡页面的点击事件
|
||||
mask_div.style.pointerEvents = 'none'
|
||||
mask_div.style.opacity = defaultSettings.watermark_alpha
|
||||
mask_div.style.fontSize = defaultSettings.watermark_fontsize
|
||||
mask_div.style.fontFamily = defaultSettings.watermark_font
|
||||
mask_div.style.color = defaultSettings.watermark_color
|
||||
mask_div.style.textAlign = 'center'
|
||||
mask_div.style.width = defaultSettings.watermark_width + 'px'
|
||||
mask_div.style.height = defaultSettings.watermark_height + 'px'
|
||||
mask_div.style.display = 'block'
|
||||
oTemp.appendChild(mask_div)
|
||||
}
|
||||
}
|
||||
oTemp.setAttribute('id', 'de-watermark-server')
|
||||
watermarkDom.appendChild(oTemp)
|
||||
}
|
||||
|
||||
export function getNow() {
|
||||
const d = new Date()
|
||||
const year = d.getFullYear()
|
||||
const month = change(d.getMonth() + 1)
|
||||
const day = change(d.getDate())
|
||||
const hour = change(d.getHours())
|
||||
const minute = change(d.getMinutes())
|
||||
|
||||
function change(t) {
|
||||
if (t < 10) {
|
||||
return '0' + t
|
||||
} else {
|
||||
return t
|
||||
}
|
||||
}
|
||||
|
||||
const time = year + '-' + month + '-' + day + ' ' + hour + ':' + minute
|
||||
return time
|
||||
}
|
||||
|
||||
export function activeWatermark(watermarkForm, userLoginInfo, domId, canvasId, watermarkOpen) {
|
||||
// 清理历史水印
|
||||
const historyWatermarkDom = document.getElementById('de-watermark-server')
|
||||
if (historyWatermarkDom) {
|
||||
historyWatermarkDom.remove()
|
||||
}
|
||||
if (!(canvasId === 'canvas-main' && ((watermarkForm.enable && !watermarkForm.enablePanelCustom) ||
|
||||
(watermarkForm.enable && watermarkOpen)))) {
|
||||
return
|
||||
}
|
||||
let watermark_txt
|
||||
let watermark_width = 120
|
||||
if (watermarkForm.type === 'custom') {
|
||||
watermark_txt = watermarkForm.content
|
||||
watermark_txt = watermark_txt.replaceAll('${ip}', userLoginInfo.ip)
|
||||
watermark_txt = watermark_txt.replaceAll('${userName}', userLoginInfo.userInfo.userName)
|
||||
watermark_txt = watermark_txt.replaceAll('${nickName}', userLoginInfo.userInfo.nickName)
|
||||
watermark_txt = watermark_txt.replaceAll('${time}', getNow())
|
||||
watermark_width = watermark_txt.length * watermarkForm.watermark_fontsize * 0.75
|
||||
watermark_width = watermark_width > 350 ? 350 : watermark_width
|
||||
} else if (watermarkForm.type === 'nickName') {
|
||||
watermark_txt = userLoginInfo.userInfo.nickName
|
||||
} else if (watermarkForm.type === 'ip') {
|
||||
watermark_txt = userLoginInfo.ip
|
||||
watermark_width = 150
|
||||
} else if (watermarkForm.type === 'time') {
|
||||
watermark_txt = getNow()
|
||||
watermark_width = 200
|
||||
} else {
|
||||
watermark_txt = userLoginInfo.userInfo.userName
|
||||
}
|
||||
const settings = {
|
||||
watermark_txt: watermark_txt,
|
||||
watermark_width: watermark_width,
|
||||
watermark_color: watermarkForm.watermark_color,
|
||||
watermark_x_space: watermarkForm.watermark_x_space,
|
||||
watermark_y_space: watermarkForm.watermark_y_space,
|
||||
watermark_fontsize: watermarkForm.watermark_fontsize + 'px'
|
||||
}
|
||||
watermark(settings, domId)
|
||||
}
|
||||
|
||||
export default { watermark, getNow, activeWatermark }
|
@ -1,94 +0,0 @@
|
||||
export default [
|
||||
{
|
||||
label: '进入',
|
||||
children: [
|
||||
{ label: '渐显', value: 'fadeIn' },
|
||||
{ label: '向右进入', value: 'fadeInLeft' },
|
||||
{ label: '向左进入', value: 'fadeInRight' },
|
||||
{ label: '向上进入', value: 'fadeInUp' },
|
||||
{ label: '向下进入', value: 'fadeInDown' },
|
||||
{ label: '向右长距进入', value: 'fadeInLeftBig' },
|
||||
{ label: '向左长距进入', value: 'fadeInRightBig' },
|
||||
{ label: '向上长距进入', value: 'fadeInUpBig' },
|
||||
{ label: '向下长距进入', value: 'fadeInDownBig' },
|
||||
{ label: '旋转进入', value: 'rotateIn' },
|
||||
{ label: '左顺时针旋转', value: 'rotateInDownLeft' },
|
||||
{ label: '右逆时针旋转', value: 'rotateInDownRight' },
|
||||
{ label: '左逆时针旋转', value: 'rotateInUpLeft' },
|
||||
{ label: '右逆时针旋转', value: 'rotateInUpRight' },
|
||||
{ label: '弹入', value: 'bounceIn' },
|
||||
{ label: '向右弹入', value: 'bounceInLeft' },
|
||||
{ label: '向左弹入', value: 'bounceInRight' },
|
||||
{ label: '向上弹入', value: 'bounceInUp' },
|
||||
{ label: '向下弹入', value: 'bounceInDown' },
|
||||
{ label: '光速从右进入', value: 'lightSpeedInRight' },
|
||||
{ label: '光速从左进入', value: 'lightSpeedInLeft' },
|
||||
{ label: '光速从右退出', value: 'lightSpeedOutRight' },
|
||||
{ label: '光速从左退出', value: 'lightSpeedOutLeft' },
|
||||
{ label: 'Y轴旋转', value: 'flip' },
|
||||
{ label: '中心X轴旋转', value: 'flipInX' },
|
||||
{ label: '中心Y轴旋转', value: 'flipInY' },
|
||||
{ label: '左长半径旋转', value: 'rollIn' },
|
||||
{ label: '由小变大进入', value: 'zoomIn' },
|
||||
{ label: '左变大进入', value: 'zoomInLeft' },
|
||||
{ label: '右变大进入', value: 'zoomInRight' },
|
||||
{ label: '向上变大进入', value: 'zoomInUp' },
|
||||
{ label: '向下变大进入', value: 'zoomInDown' },
|
||||
{ label: '向右滑动展开', value: 'slideInLeft' },
|
||||
{ label: '向左滑动展开', value: 'slideInRight' },
|
||||
{ label: '向上滑动展开', value: 'slideInUp' },
|
||||
{ label: '向下滑动展开', value: 'slideInDown' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '强调',
|
||||
children: [
|
||||
{ label: '弹跳', value: 'bounce' },
|
||||
{ label: '闪烁', value: 'flash' },
|
||||
{ label: '放大缩小', value: 'pulse' },
|
||||
{ label: '放大缩小弹簧', value: 'rubberBand' },
|
||||
{ label: '左右晃动', value: 'headShake' },
|
||||
{ label: '左右扇形摇摆', value: 'swing' },
|
||||
{ label: '放大晃动缩小', value: 'tada' },
|
||||
{ label: '扇形摇摆', value: 'wobble' },
|
||||
{ label: '左右上下晃动', value: 'jello' },
|
||||
{ label: 'Y轴旋转', value: 'flip' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '退出',
|
||||
children: [
|
||||
{ label: '渐隐', value: 'fadeOut' },
|
||||
{ label: '向左退出', value: 'fadeOutLeft' },
|
||||
{ label: '向右退出', value: 'fadeOutRight' },
|
||||
{ label: '向上退出', value: 'fadeOutUp' },
|
||||
{ label: '向下退出', value: 'fadeOutDown' },
|
||||
{ label: '向左长距退出', value: 'fadeOutLeftBig' },
|
||||
{ label: '向右长距退出', value: 'fadeOutRightBig' },
|
||||
{ label: '向上长距退出', value: 'fadeOutUpBig' },
|
||||
{ label: '向下长距退出', value: 'fadeOutDownBig' },
|
||||
{ label: '旋转退出', value: 'rotateOut' },
|
||||
{ label: '左顺时针旋转', value: 'rotateOutDownLeft' },
|
||||
{ label: '右逆时针旋转', value: 'rotateOutDownRight' },
|
||||
{ label: '左逆时针旋转', value: 'rotateOutUpLeft' },
|
||||
{ label: '右逆时针旋转', value: 'rotateOutUpRight' },
|
||||
{ label: '弹出', value: 'bounceOut' },
|
||||
{ label: '向左弹出', value: 'bounceOutLeft' },
|
||||
{ label: '向右弹出', value: 'bounceOutRight' },
|
||||
{ label: '向上弹出', value: 'bounceOutUp' },
|
||||
{ label: '向下弹出', value: 'bounceOutDown' },
|
||||
{ label: '中心X轴旋转', value: 'flipOutX' },
|
||||
{ label: '中心Y轴旋转', value: 'flipOutY' },
|
||||
{ label: '左长半径旋转', value: 'rollOut' },
|
||||
{ label: '由小变大退出', value: 'zoomOut' },
|
||||
{ label: '左变大退出', value: 'zoomOutLeft' },
|
||||
{ label: '右变大退出', value: 'zoomOutRight' },
|
||||
{ label: '向上变大退出', value: 'zoomOutUp' },
|
||||
{ label: '向下变大退出', value: 'zoomOutDown' },
|
||||
{ label: '向左滑动收起', value: 'slideOutLeft' },
|
||||
{ label: '向右滑动收起', value: 'slideOutRight' },
|
||||
{ label: '向上滑动收起', value: 'slideOutUp' },
|
||||
{ label: '向下滑动收起', value: 'slideOutDown' }
|
||||
]
|
||||
}
|
||||
]
|
@ -114,12 +114,12 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SecondAndMinute from './cron/secondAndMinute'
|
||||
import hour from './cron/hour'
|
||||
import day from './cron/day'
|
||||
import month from './cron/month'
|
||||
import week from './cron/week'
|
||||
import year from './cron/year'
|
||||
import SecondAndMinute from './cron/SecondAndMinute'
|
||||
import hour from './cron/Hour'
|
||||
import day from './cron/Day'
|
||||
import month from './cron/Month'
|
||||
import week from './cron/Week'
|
||||
import year from './cron/Year'
|
||||
export default {
|
||||
components: {
|
||||
SecondAndMinute, hour, day, month, week, year
|
@ -60,7 +60,6 @@
|
||||
|
||||
<script>
|
||||
import inputStyleMixin from '@/components/widget/deWidget/inputStyleMixin'
|
||||
|
||||
export default {
|
||||
name: 'DeOutWidget',
|
||||
mixins: [inputStyleMixin],
|
||||
|
@ -1,30 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
v-bottom-to-top-drag
|
||||
class="drag-bar"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'DeBottom2TopDragBar'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.drag-bar {
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
cursor: row-resize;
|
||||
position: fixed;
|
||||
background-color: #E6E6E6;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.drag-bar:hover {
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
</style>
|
@ -1,31 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
v-right-to-left-drag
|
||||
class="drag-bar"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'DeRight2LeftDragBar'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.drag-bar {
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0;
|
||||
cursor: col-resize;
|
||||
background-color: #E6E6E6;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.drag-bar:hover {
|
||||
width: 3px;
|
||||
}
|
||||
|
||||
</style>
|
@ -39,6 +39,7 @@
|
||||
:active-model="'edit'"
|
||||
:canvas-id="canvasId"
|
||||
:element="element"
|
||||
:chart="chart"
|
||||
@showViewDetails="showViewDetails"
|
||||
@amRemoveItem="amRemoveItem"
|
||||
@amAddItem="amAddItem"
|
||||
@ -384,6 +385,7 @@ export default {
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
chart: null,
|
||||
contentDisplay: true,
|
||||
// 当画布在tab中是 宽度左右拓展的余量
|
||||
parentWidthTabOffset: 40,
|
||||
@ -802,6 +804,9 @@ export default {
|
||||
this.beforeDestroyFunction()
|
||||
},
|
||||
methods: {
|
||||
setChartData(chart) {
|
||||
this.chart = chart
|
||||
},
|
||||
// 重置边界和鼠标状态
|
||||
resetBoundsAndMouseState() {
|
||||
this.mouseClickPosition = { mouseX: 0, mouseY: 0, x: 0, y: 0, w: 0, h: 0 }
|
||||
@ -1929,6 +1934,7 @@ export default {
|
||||
const nodes = this.$el.parentNode.childNodes // 获取当前父节点下所有子节点
|
||||
for (const item of nodes) {
|
||||
if (
|
||||
item.tagName !== 'svg' &&
|
||||
item.className !== undefined &&
|
||||
!item.className.split(' ').includes(this.classNameActive) &&
|
||||
item.getAttribute('tab-is-check') !== null &&
|
||||
@ -2114,8 +2120,8 @@ export default {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.drag-on-tab-collision {
|
||||
|
@ -1,32 +0,0 @@
|
||||
|
||||
export const on = (function() {
|
||||
if (document.addEventListener) {
|
||||
return function(element, event, handler) {
|
||||
if (element && event && handler) {
|
||||
element.addEventListener(event, handler, false)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return function(element, event, handler) {
|
||||
if (element && event && handler) {
|
||||
element.attachEvent('on' + event, handler)
|
||||
}
|
||||
}
|
||||
}
|
||||
})()
|
||||
export const off = (function() {
|
||||
if (document.removeEventListener) {
|
||||
return function(element, event, handler) {
|
||||
if (element && event) {
|
||||
element.removeEventListener(event, handler, false)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return function(element, event, handler) {
|
||||
if (element && event) {
|
||||
element.detachEvent('on' + event, handler)
|
||||
}
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
@ -139,6 +139,10 @@ export default {
|
||||
this.innerValues = this.value
|
||||
this.viewLoaded = false
|
||||
this.panelId && findOne(this.panelId).then(response => {
|
||||
const watermarkInfo = {
|
||||
...response.data.watermarkInfo,
|
||||
settingContent: JSON.parse(response.data.watermarkInfo.settingContent)
|
||||
}
|
||||
this.panelInfo = {
|
||||
id: response.data.id,
|
||||
name: response.data.name,
|
||||
@ -148,7 +152,9 @@ export default {
|
||||
createBy: response.data.createBy,
|
||||
createTime: response.data.createTime,
|
||||
updateBy: response.data.updateBy,
|
||||
updateTime: response.data.updateTime
|
||||
updateTime: response.data.updateTime,
|
||||
watermarkOpen: response.data.watermarkOpen,
|
||||
watermarkInfo: watermarkInfo
|
||||
}
|
||||
this.$store.dispatch('panel/setPanelInfo', this.panelInfo)
|
||||
panelDataPrepare(JSON.parse(response.data.panelData), JSON.parse(response.data.panelStyle), rsp => {
|
||||
|
@ -1,19 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<svg-icon
|
||||
icon-class="doc"
|
||||
@click="click"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Doc',
|
||||
methods: {
|
||||
click() {
|
||||
window.open(process.env.VUE_APP_BASE_API + 'doc.html', '_blank')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -171,7 +171,7 @@ export default {
|
||||
this.options = this.newList.slice(0, this.maxLength)
|
||||
},
|
||||
customInputStyle() {
|
||||
if (!this.$parent.$parent.handlerInputStyle) return
|
||||
if (!this.$parent.$parent.handlerInputStyle || !this.$refs.visualSelect) return
|
||||
handlerInputStyle(this.$refs.visualSelect.$el.querySelector('.el-input__inner'), this.$parent.element.style)
|
||||
handlerInputStyle(this.$refs.visualSelect.$el.querySelector('.el-select__input'), { wordColor: this.$parent.element.style.wordColor })
|
||||
},
|
||||
|
@ -1,44 +0,0 @@
|
||||
<template>
|
||||
<el-tooltip :content="tooltip">
|
||||
<el-button
|
||||
circle
|
||||
class="fu-search-bar-button"
|
||||
:type="type"
|
||||
:size="size"
|
||||
@click="click"
|
||||
>
|
||||
<slot>
|
||||
<i :class="icon" />
|
||||
</slot>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'GridButton',
|
||||
props: {
|
||||
size: {
|
||||
type: String,
|
||||
default: 'mini'
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
tooltip: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
click(e) {
|
||||
this.$emit('click', e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -27,7 +27,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import tableBody from './tableBody'
|
||||
import tableBody from './TableBody'
|
||||
export default {
|
||||
components: { tableBody },
|
||||
props: {
|
||||
|
@ -1,47 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
style="padding: 0 15px;"
|
||||
@click="toggleClick"
|
||||
>
|
||||
<svg
|
||||
:class="{'is-active':isActive}"
|
||||
class="hamburger"
|
||||
viewBox="0 0 1024 1024"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="64"
|
||||
height="64"
|
||||
>
|
||||
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Hamburger',
|
||||
props: {
|
||||
isActive: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleClick() {
|
||||
this.$emit('toggleClick')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hamburger {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.hamburger.is-active {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
</style>
|
@ -1,104 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
:class="{'hidden':hidden}"
|
||||
class="pagination-container"
|
||||
>
|
||||
<el-pagination
|
||||
:background="background"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
:layout="layout"
|
||||
:page-sizes="pageSizes"
|
||||
:total="total"
|
||||
v-bind="$attrs"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { scrollTo } from '@/utils/scroll-to'
|
||||
|
||||
export default {
|
||||
name: 'Pagination',
|
||||
props: {
|
||||
total: {
|
||||
required: true,
|
||||
type: Number
|
||||
},
|
||||
page: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
pageSizes: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [10, 20, 30, 50]
|
||||
}
|
||||
},
|
||||
layout: {
|
||||
type: String,
|
||||
default: 'total, sizes, prev, pager, next, jumper'
|
||||
},
|
||||
background: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
autoScroll: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
hidden: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentPage: {
|
||||
get() {
|
||||
return this.page
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:page', val)
|
||||
}
|
||||
},
|
||||
pageSize: {
|
||||
get() {
|
||||
return this.limit
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:limit', val)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSizeChange(val) {
|
||||
this.$emit('pagination', { page: this.currentPage, limit: val })
|
||||
if (this.autoScroll) {
|
||||
scrollTo(0, 800)
|
||||
}
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.$emit('pagination', { page: val, limit: this.pageSize })
|
||||
if (this.autoScroll) {
|
||||
scrollTo(0, 800)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.pagination-container {
|
||||
background: #fff;
|
||||
padding: 32px 16px;
|
||||
}
|
||||
.pagination-container.hidden {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
@ -1,63 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<svg-icon
|
||||
:icon-class="isFullscreen?'exit-fullscreen':'fullscreen'"
|
||||
@click="click"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import screenfull from 'screenfull'
|
||||
|
||||
export default {
|
||||
name: 'Screenfull',
|
||||
data() {
|
||||
return {
|
||||
isFullscreen: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.destroy()
|
||||
},
|
||||
methods: {
|
||||
click() {
|
||||
if (!screenfull.enabled) {
|
||||
this.$message({
|
||||
message: 'you browser can not work',
|
||||
type: 'warning'
|
||||
})
|
||||
return false
|
||||
}
|
||||
screenfull.toggle()
|
||||
},
|
||||
change() {
|
||||
this.isFullscreen = screenfull.isFullscreen
|
||||
},
|
||||
init() {
|
||||
if (screenfull.enabled) {
|
||||
screenfull.on('change', this.change)
|
||||
}
|
||||
},
|
||||
destroy() {
|
||||
if (screenfull.enabled) {
|
||||
screenfull.off('change', this.change)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.screenfull-svg {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
fill: #5a5e66;;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
vertical-align: 10px;
|
||||
}
|
||||
</style>
|
@ -1,67 +0,0 @@
|
||||
<template>
|
||||
<el-dropdown
|
||||
trigger="click"
|
||||
@command="handleSetSize"
|
||||
>
|
||||
<div>
|
||||
<svg-icon
|
||||
class-name="size-icon"
|
||||
icon-class="size"
|
||||
/>
|
||||
</div>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item
|
||||
v-for="item of sizeOptions"
|
||||
:key="item.value"
|
||||
:disabled="size===item.value"
|
||||
:command="item.value"
|
||||
>
|
||||
{{
|
||||
item.label }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
sizeOptions: [
|
||||
{ label: 'Default', value: 'default' },
|
||||
{ label: 'Medium', value: 'medium' },
|
||||
{ label: 'Small', value: 'small' },
|
||||
{ label: 'Mini', value: 'mini' }
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
size() {
|
||||
return this.$store.getters.size
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSetSize(size) {
|
||||
this.$ELEMENT.size = size
|
||||
this.$store.dispatch('app/setSize', size)
|
||||
this.refreshView()
|
||||
this.$message({
|
||||
message: '布局设置成功',
|
||||
type: 'success'
|
||||
})
|
||||
},
|
||||
refreshView() {
|
||||
// In order to make the cached page re-rendered
|
||||
// this.$store.dispatch('tagsView/delAllCachedViews', this.$route)
|
||||
const { fullPath } = this.$route
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$router.replace({
|
||||
path: '/redirect' + fullPath
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
129
frontend/src/components/suspensionSelector/index.vue
Normal file
129
frontend/src/components/suspensionSelector/index.vue
Normal file
@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<div style="width: 100%;">
|
||||
<el-col>
|
||||
<el-form
|
||||
ref="suspensionForm"
|
||||
:model="suspensionForm"
|
||||
label-width="80px"
|
||||
size="mini"
|
||||
>
|
||||
<el-form-item
|
||||
v-show="showProperty('show')"
|
||||
:label="$t('chart.show')"
|
||||
class="form-item"
|
||||
>
|
||||
<el-checkbox
|
||||
v-model="suspensionForm.show"
|
||||
@change="changeSuspensionAttr('show')"
|
||||
>{{ $t('chart.show') }}
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</el-col>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DEFAULT_SUSPENSION } from '@/views/chart/chart/chart'
|
||||
|
||||
export default {
|
||||
name: 'SuspensionForm',
|
||||
props: {
|
||||
param: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
chart: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
propertyInner: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: function() {
|
||||
return []
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
suspensionForm: JSON.parse(JSON.stringify(DEFAULT_SUSPENSION)),
|
||||
fontSize: []
|
||||
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'chart': {
|
||||
handler: function() {
|
||||
this.initData()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initData()
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
const chart = JSON.parse(JSON.stringify(this.chart))
|
||||
if (chart.customAttr) {
|
||||
let customAttr = null
|
||||
if (Object.prototype.toString.call(chart.customAttr) === '[object Object]') {
|
||||
customAttr = JSON.parse(JSON.stringify(chart.customAttr))
|
||||
} else {
|
||||
customAttr = JSON.parse(chart.customAttr)
|
||||
}
|
||||
if (customAttr.suspension) {
|
||||
this.suspensionForm = customAttr.suspension
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
changeSuspensionAttr(modifyName) {
|
||||
this.suspensionForm['modifyName'] = modifyName
|
||||
this.$emit('onSuspensionChange', this.suspensionForm)
|
||||
},
|
||||
|
||||
showProperty(property) {
|
||||
return this.propertyInner.includes(property)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.shape-item{
|
||||
padding: 6px;
|
||||
border: none;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.form-item-slider ::v-deep .el-form-item__label{
|
||||
font-size: 12px;
|
||||
line-height: 38px;
|
||||
}
|
||||
.form-item ::v-deep .el-form-item__label{
|
||||
font-size: 12px;
|
||||
}
|
||||
.el-select-dropdown__item{
|
||||
padding: 0 20px;
|
||||
}
|
||||
span{
|
||||
font-size: 12px
|
||||
}
|
||||
.el-form-item{
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.switch-style{
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
margin-top: -4px;
|
||||
}
|
||||
.color-picker-style{
|
||||
cursor: pointer;
|
||||
z-index: 1003;
|
||||
}
|
||||
</style>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user