feat: 可视化资源支持显示水印

This commit is contained in:
wangjiahao 2024-01-09 17:08:28 +08:00
parent 9497450d58
commit f3413e91fa
14 changed files with 310 additions and 34 deletions

View File

@ -21,11 +21,11 @@ public class MybatisPlusGenerator {
/**
* 业务模块例如datasource,dataset,panel等
*/
private static final String busi = "template";
private static final String busi = "visualization";
/**
* 这是要生成代码的表名称
*/
private static final String TABLE_NAME = "visualization_template_category_map";
private static final String TABLE_NAME = "visualization_watermark";
/**
* 下面两个配置基本上不用动

View File

@ -0,0 +1,94 @@
package io.dataease.visualization.dao.auto.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
/**
* <p>
* 仪表板水印设置表
* </p>
*
* @author fit2cloud
* @since 2024-01-09
*/
@TableName("visualization_watermark")
public class VisualizationWatermark implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
private String id;
/**
* 版本号
*/
private String version;
/**
* 设置内容
*/
private String settingContent;
/**
* 创建人
*/
private String createBy;
/**
* 创建时间
*/
private Long createTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getSettingContent() {
return settingContent;
}
public void setSettingContent(String settingContent) {
this.settingContent = settingContent;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public Long getCreateTime() {
return createTime;
}
public void setCreateTime(Long createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "VisualizationWatermark{" +
"id = " + id +
", version = " + version +
", settingContent = " + settingContent +
", createBy = " + createBy +
", createTime = " + createTime +
"}";
}
}

View File

@ -0,0 +1,18 @@
package io.dataease.visualization.dao.auto.mapper;
import io.dataease.visualization.dao.auto.entity.VisualizationWatermark;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 仪表板水印设置表 Mapper 接口
* </p>
*
* @author fit2cloud
* @since 2024-01-09
*/
@Mapper
public interface VisualizationWatermarkMapper extends BaseMapper<VisualizationWatermark> {
}

View File

@ -10,6 +10,7 @@ import io.dataease.api.visualization.request.DataVisualizationBaseRequest;
import io.dataease.api.visualization.request.VisualizationWorkbranchQueryRequest;
import io.dataease.api.visualization.vo.DataVisualizationVO;
import io.dataease.api.visualization.vo.VisualizationResourceVO;
import io.dataease.api.visualization.vo.VisualizationWatermarkVO;
import io.dataease.chart.dao.auto.entity.CoreChartView;
import io.dataease.chart.manage.ChartDataManage;
import io.dataease.chart.manage.ChartViewManege;
@ -31,7 +32,9 @@ import io.dataease.utils.BeanUtils;
import io.dataease.utils.IDUtils;
import io.dataease.utils.JsonUtil;
import io.dataease.visualization.dao.auto.entity.DataVisualizationInfo;
import io.dataease.visualization.dao.auto.entity.VisualizationWatermark;
import io.dataease.visualization.dao.auto.mapper.DataVisualizationInfoMapper;
import io.dataease.visualization.dao.auto.mapper.VisualizationWatermarkMapper;
import io.dataease.visualization.dao.ext.mapper.ExtDataVisualizationMapper;
import io.dataease.visualization.manage.CoreVisualizationManage;
import jakarta.annotation.Resource;
@ -83,6 +86,9 @@ public class DataVisualizationServer implements DataVisualizationApi {
@Resource
private CoreOptRecentManage coreOptRecentManage;
@Resource
private VisualizationWatermarkMapper watermarkMapper;
@Override
@XpackInteract(value = "dataVisualizationServer", original = true)
public DataVisualizationVO findById(Long dvId, String busiFlag) {
@ -94,6 +100,10 @@ public class DataVisualizationServer implements DataVisualizationApi {
Map<Long, ChartViewDTO> viewInfo = chartViewDTOS.stream().collect(Collectors.toMap(ChartViewDTO::getId, chartView -> chartView));
result.setCanvasViewInfo(viewInfo);
}
VisualizationWatermark watermark = watermarkMapper.selectById("system_default");
VisualizationWatermarkVO watermarkVO = new VisualizationWatermarkVO();
BeanUtils.copyBean(watermarkVO,watermark);
result.setWatermarkInfo(watermarkVO);
return result;
} else {
DEException.throwException("资源不存在或已经被删除...");

View File

@ -77,5 +77,3 @@ export const defaultPwdApi = () => request.get({ url: '/user/defaultPwd' })
export const resetPwdApi = uid => request.post({ url: `/user/resetPwd/${uid}` })
export const switchEnableApi = data => request.post({ url: '/user/enable', data })
export const userLoginInfo = () => request.get({ url: '/user/userLoginInfo' })

View File

@ -0,0 +1,4 @@
import request from '@/config/axios'
export const searchRoleApi = (keyword: string) =>
request.post({ url: '/role/query', data: { keyword } })

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1704786169626" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6487" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M490.666667 896c-153.6 0-277.333333-123.733333-277.333334-277.333333 0-147.2 249.6-469.333333 260.266667-482.133334 8.533333-10.666667 25.6-10.666667 34.133333 0C518.4 149.333333 768 471.466667 768 618.666667c0 153.6-123.733333 277.333333-277.333333 277.333333z m0-712.533333C411.733333 288 256 516.266667 256 618.666667c0 130.133333 104.533333 234.666667 234.666667 234.666666s234.666667-104.533333 234.666666-234.666666c0-102.4-155.733333-330.666667-234.666666-435.2z" p-id="6488"></path><path d="M832 384H149.333333c-12.8 0-21.333333-8.533333-21.333333-21.333333s8.533333-21.333333 21.333333-21.333334h682.666667c12.8 0 21.333333 8.533333 21.333333 21.333334s-8.533333 21.333333-21.333333 21.333333zM832 554.666667H149.333333c-12.8 0-21.333333-8.533333-21.333333-21.333334s8.533333-21.333333 21.333333-21.333333h682.666667c12.8 0 21.333333 8.533333 21.333333 21.333333s-8.533333 21.333333-21.333333 21.333334zM832 725.333333H149.333333c-12.8 0-21.333333-8.533333-21.333333-21.333333s8.533333-21.333333 21.333333-21.333333h682.666667c12.8 0 21.333333 8.533333 21.333333 21.333333s-8.533333 21.333333-21.333333 21.333333z" p-id="6489"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -11,7 +11,7 @@ import UserViewEnlarge from '@/components/visualization/UserViewEnlarge.vue'
import CanvasOptBar from '@/components/visualization/CanvasOptBar.vue'
import { isMainCanvas } from '@/utils/canvasUtils'
import { activeWatermark } from '@/components/watermark/watermark'
import { userLoginInfo } from '@/api/user'
import { personInfoApi } from '@/api/user'
const dvMainStore = dvMainStoreWithOut()
const { pcMatrixCount, curComponent } = storeToRefs(dvMainStore)
@ -49,6 +49,10 @@ const props = defineProps({
downloadStatus: {
type: Boolean,
default: false
},
userId: {
type: String,
require: false
}
})
@ -60,7 +64,8 @@ const {
canvasViewInfo,
showPosition,
previewActive,
downloadStatus
downloadStatus,
userId
} = toRefs(props)
const domId = 'preview-' + canvasId.value
const scaleWidth = ref(100)
@ -175,30 +180,29 @@ const initRefreshTimer = () => {
}
}
const initWatermark = () => {
if (dvInfo.value.watermarkInfo) {
nextTick(() => {
if (userInfo.value) {
const initWatermark = (waterDomId = 'preview-canvas-main') => {
if (dvInfo.value.watermarkInfo && isMainCanvas(canvasId.value)) {
if (userInfo.value) {
activeWatermark(
dvInfo.value.watermarkInfo.settingContent,
userInfo.value,
waterDomId,
canvasId.value,
dvInfo.value.watermarkOpen
)
} else {
const method = personInfoApi
method().then(res => {
userInfo.value = res.data
activeWatermark(
dvInfo.value.watermarkInfo.settingContent,
userInfo.value,
'canvasInfo-main',
waterDomId,
canvasId.value,
dvInfo.value.watermarkOpen
)
} else {
userLoginInfo().then(res => {
userInfo.value = res.data
activeWatermark(
dvInfo.value.watermarkInfo.settingContent,
userInfo.value,
'canvasInfo-main',
canvasId.value,
dvInfo.value.watermarkOpen
)
})
}
})
})
}
}
}

View File

@ -35,7 +35,7 @@ export function watermark(settings, domId) {
const cutWidth = page_width * 0.015
page_width = page_width - cutWidth
// 获取页面最大高度
let page_height = watermarkDom.clientHeight - 56
let page_height = watermarkDom.scrollHeight - 56
page_height = page_height < 400 ? 400 : page_height
// page_height = Math.max(page_height, window.innerHeight - 30)
// 如果将水印列数设置为0或水印列数设置过大超过页面最大宽度则重新计算水印列数和水印x轴间隔
@ -165,13 +165,13 @@ export function activeWatermark(watermarkForm, userLoginInfo, domId, canvasId, w
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('${username}', userLoginInfo.account)
watermark_txt = watermark_txt.replaceAll('${nickName}', userLoginInfo.name)
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
watermark_txt = userLoginInfo.name
} else if (watermarkForm.type === 'ip') {
watermark_txt = userLoginInfo.ip
watermark_width = 150
@ -179,7 +179,7 @@ export function activeWatermark(watermarkForm, userLoginInfo, domId, canvasId, w
watermark_txt = getNow()
watermark_width = 200
} else {
watermark_txt = userLoginInfo.userInfo.username
watermark_txt = userLoginInfo.name
}
const settings = {
watermark_txt: watermark_txt,

View File

@ -861,7 +861,8 @@ export const dvMainStore = defineStore('dataVisualization', {
pid: null,
status: null,
selfWatermarkStatus: null,
type: null
type: null,
watermarkInfo: null
}
},
setViewDataDetails(viewId, dataInfo) {

View File

@ -11,7 +11,6 @@ import { getPanelAllLinkageInfo } from '@/api/visualization/linkage'
import { queryVisualizationJumpInfo } from '@/api/visualization/linkJump'
import { getViewConfig } from '@/views/chart/components/editor/util/chart'
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
import { toPercent } from '@/utils/translate'
const dvMainStore = dvMainStoreWithOut()
const { curBatchOptComponents, dvInfo, canvasStyleData, componentData, canvasViewInfo } =
storeToRefs(dvMainStore)
@ -81,18 +80,25 @@ export function commonHandleDragEnd(e, dvModel) {
export function initCanvasDataPrepare(dvId, busiFlag, callBack) {
findById(dvId, busiFlag).then(res => {
const canvasInfo = res.data
const watermarkInfo = {
...canvasInfo.watermarkInfo,
settingContent: JSON.parse(canvasInfo.watermarkInfo.settingContent)
}
const dvInfo = {
id: canvasInfo.id,
name: canvasInfo.name,
pid: canvasInfo.pid,
status: canvasInfo.status,
selfWatermarkStatus: canvasInfo.selfWatermarkStatus,
watermarkOpen: canvasInfo.selfWatermarkStatus,
type: canvasInfo.type,
creatorName: canvasInfo.creatorName,
updateName: canvasInfo.updateName,
createTime: canvasInfo.createTime,
updateTime: canvasInfo.updateTime
updateTime: canvasInfo.updateTime,
watermarkInfo: watermarkInfo
}
const canvasDataResult = JSON.parse(canvasInfo.componentData)
const canvasStyleResult = JSON.parse(canvasInfo.canvasStyleData)
const canvasViewInfoPreview = canvasInfo.canvasViewInfo
@ -157,7 +163,8 @@ export function canvasSave(callBack) {
canvasStyleData: JSON.stringify(canvasStyleData.value),
componentData: JSON.stringify(componentDataToSave),
canvasViewInfo: canvasViewInfo.value,
...dvInfo.value
...dvInfo.value,
watermarkInfo: null
}
const method = dvInfo.value.id ? updateCanvas : saveCanvas

View File

@ -129,6 +129,11 @@ public class DataVisualizationVO implements Serializable {
*/
private Map<Long, VisualizationTemplateExtendDataDTO> extendDataInfo = new HashMap<>();
/**
* 水印信息
*/
private VisualizationWatermarkVO watermarkInfo;
public DataVisualizationVO(Long id, String name, String type, String canvasStyleData, String componentData, Map<Long, ChartViewDTO> canvasViewInfo, Map<Long, VisualizationTemplateExtendDataDTO> extendDataInfo) {
this.id = id;
this.name = name;

View File

@ -0,0 +1,80 @@
package io.dataease.api.visualization.vo;
public class VisualizationWatermarkVO{
/**
* 主键
*/
private String id;
/**
* 版本号
*/
private String version;
/**
* 设置内容
*/
private String settingContent;
/**
* 创建人
*/
private String createBy;
/**
* 创建时间
*/
private Long createTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getSettingContent() {
return settingContent;
}
public void setSettingContent(String settingContent) {
this.settingContent = settingContent;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public Long getCreateTime() {
return createTime;
}
public void setCreateTime(Long createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "VisualizationWatermark{" +
"id = " + id +
", version = " + version +
", settingContent = " + settingContent +
", createBy = " + createBy +
", createTime = " + createTime +
"}";
}
}

View File

@ -0,0 +1,54 @@
package io.dataease.utils;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import java.net.InetAddress;
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;
}
public static String domain() {
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (Exception e) {
return LOCAL_IP_VAL;
}
}
}