forked from github/dataease
feat: 可视化资源支持显示水印
This commit is contained in:
parent
9497450d58
commit
f3413e91fa
@ -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";
|
||||
|
||||
/**
|
||||
* 下面两个配置基本上不用动
|
||||
|
@ -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 +
|
||||
"}";
|
||||
}
|
||||
}
|
@ -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> {
|
||||
|
||||
}
|
@ -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("资源不存在或已经被删除...");
|
||||
|
@ -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' })
|
||||
|
4
core/core-frontend/src/api/watermark.ts
Normal file
4
core/core-frontend/src/api/watermark.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
export const searchRoleApi = (keyword: string) =>
|
||||
request.post({ url: '/role/query', data: { keyword } })
|
1
core/core-frontend/src/assets/svg/watermark.svg
Normal file
1
core/core-frontend/src/assets/svg/watermark.svg
Normal 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 |
@ -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
|
||||
)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -861,7 +861,8 @@ export const dvMainStore = defineStore('dataVisualization', {
|
||||
pid: null,
|
||||
status: null,
|
||||
selfWatermarkStatus: null,
|
||||
type: null
|
||||
type: null,
|
||||
watermarkInfo: null
|
||||
}
|
||||
},
|
||||
setViewDataDetails(viewId, dataInfo) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 +
|
||||
"}";
|
||||
}
|
||||
}
|
54
sdk/common/src/main/java/io/dataease/utils/IPUtils.java
Normal file
54
sdk/common/src/main/java/io/dataease/utils/IPUtils.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user