Merge pull request #3736 from dataease/pr@dev@feat_watermark

feat: 支持水印设置
This commit is contained in:
Junjun 2022-11-14 16:51:43 +08:00 committed by GitHub
commit 9f98fd5bed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 3925 additions and 36 deletions

View File

@ -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();
}
}

View 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;
}
}

View File

@ -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;
}

View File

@ -0,0 +1,36 @@
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.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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(PanelWatermarkDTO panelWatermark) {
WatermarkService userXpackService = SpringContextUtil.getBean(WatermarkService.class);
userXpackService.saveWatermarkInfo(panelWatermark);
}
}

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -3,6 +3,27 @@ ALTER TABLE `sys_log`
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`;
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);
CREATE TABLE `panel_watermark`
(
`id` varchar(50) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`version` varchar(255) DEFAULT NULL COMMENT '版本',
`type` varchar(255) DEFAULT NULL COMMENT '类型',
`content` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
SET
FOREIGN_KEY_CHECKS = 1;
UPDATE `sys_menu` SET `component` = 'dataset/Form' WHERE (`menu_id` = '800');

View File

@ -66,6 +66,7 @@ export function viewData(id, panelId, data) {
data
})
}
export function panelSave(data) {
return request({
url: 'panel/group/save',
@ -174,7 +175,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: response.data.watermarkInfo
})
// 刷新联动信息
getPanelAllLinkageInfo(panelId).then(rsp => {
@ -230,6 +233,7 @@ export function initViewCache(panelId) {
loading: false
})
}
export function exportDetails(data) {
// 初始化仪表板视图缓存
return request({
@ -268,6 +272,7 @@ export function saveCache(data) {
data
})
}
export function findUserCacheRequest(panelId) {
return request({
url: 'panel/group/findUserCache/' + panelId,

View File

@ -23,7 +23,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: response.data.watermarkInfo
})
// 刷新联动信息
getPanelAllLinkageInfo(panelId, proxy).then(rsp => {

View 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.

After

Width:  |  Height:  |  Size: 509 KiB

View File

@ -8,7 +8,7 @@
@mouseup="deselectCurComponent"
@scroll="canvasScroll"
>
<slot name="optBar" />
<slot name="optBar"/>
<de-editor
:ref="editorRefName"
:canvas-style-data="canvasStyleData"
@ -113,6 +113,8 @@ 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 { 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(JSON.parse(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)

View File

@ -7,10 +7,10 @@
@change="openMobileLayout"
>
<el-radio-button :label="false">
<span class="icon iconfont icon-icon_pc_outlined icon16_only" />
<span class="icon iconfont icon-icon_pc_outlined icon16_only"/>
</el-radio-button>
<el-radio-button :label="true">
<span class="icon iconfont icon-icon_phone_outlined icon16_only" />
<span class="icon iconfont icon-icon_phone_outlined icon16_only"/>
</el-radio-button>
</el-radio-group>
</div>
@ -95,7 +95,7 @@
<el-dropdown-item>
<el-dropdown placement="right-start">
<span>
<span class="icon iconfont icon-icon_moments-categories_outlined icon16" />
<span class="icon iconfont icon-icon_moments-categories_outlined icon16"/>
<span class="text14 margin-left8">{{ $t('panel.new_element_distribution') }}</span>
<svg-icon
icon-class="icon_right_outlined"
@ -121,7 +121,7 @@
</el-dropdown>
</el-dropdown-item>
<el-dropdown-item>
<span class="icon iconfont icon-icon_dialpad_outlined icon16" />
<span class="icon iconfont icon-icon_dialpad_outlined icon16"/>
<span class="text14 margin-left8">{{ $t('panel.aided_grid') }}</span>
<el-switch
v-model="showGridSwitch"
@ -131,13 +131,22 @@
/>
</el-dropdown-item>
<el-dropdown-item @click.native="openOuterParamsSet">
<span class="icon iconfont icon-icon-quicksetting icon16" />
<span class="icon iconfont icon-icon-quicksetting icon16"/>
<span class="text14 margin-left8">{{ $t('panel.params_setting') }}</span>
</el-dropdown-item>
<el-dropdown-item @click.native="clearCanvas">
<span class="icon iconfont icon-icon_clear_outlined icon16" />
<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>
<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"
/>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</span>
@ -182,8 +191,8 @@
</el-col>
<el-col :span="20">
<span style="font-size: 13px;margin-left: 10px;font-weight: bold;line-height: 20px">{{
$t('panel.panel_save_warn_tips')
}}</span>
$t('panel.panel_save_warn_tips')
}}</span>
</el-col>
</el-row>
<div

View File

@ -1,10 +1,11 @@
<template>
<div
class="bg"
:id="previewMainDomId"
:style="customStyle"
@scroll="canvasScroll"
>
<canvas-opt-bar />
<canvas-opt-bar/>
<div
:id="previewDomId"
:ref="previewRefId"
@ -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,12 @@ export default {
bus.$off('trigger-reset-button', this.triggerResetButton)
},
methods: {
initWatermark() {
userLoginInfo().then(res => {
const userInfo = res.data
activeWatermark(JSON.parse(this.panelInfo.watermarkInfo.settingContent), userInfo, 'preview-main-canvas-main', this.canvasId, this.panelInfo.watermarkOpen)
})
},
isMainCanvas() {
return this.canvasId === 'canvas-main'
},

View File

@ -0,0 +1,156 @@
//动态创建水印元素的封装函数
export function watermark(settings, domId) {
const watermarkDom = document.getElementById(domId)
//默认设置
let 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') {
let 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]
}
}
//创建虚拟节点对象,在该节点对象中可以放元素,最后只需在页面中添加该节点对象即可。可提高性能
let oTemp = document.createElement('p')
//获取页面最大宽度
let page_width = watermarkDom.clientWidth
let 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
let 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() {
let d = new Date()
let year = d.getFullYear()
let month = change(d.getMonth() + 1)
let day = change(d.getDate())
let hour = change(d.getHours())
let minute = change(d.getMinutes())
let second = change(d.getSeconds())
function change(t) {
if (t < 10) {
return '0' + t
} else {
return t
}
}
let 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 }

View File

@ -148,7 +148,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: response.data.watermarkInfo
}
this.$store.dispatch('panel/setPanelInfo', this.panelInfo)
panelDataPrepare(JSON.parse(response.data.panelData), JSON.parse(response.data.panelStyle), rsp => {

View File

@ -1451,7 +1451,7 @@ export default {
field_rename: 'Rename Field',
params_work: 'Effective only when editing SQL',
sql_variable_limit_1: '1、SQL variables can only be used in where conditions',
sql_variable_limit_2: "2、Exampleselect * from table_name where column_name1='${param_name1}' and column_name2 in '${param_name2}'",
sql_variable_limit_2: '2、Exampleselect * from table_name where column_name1=\'${param_name1}\' and column_name2 in \'${param_name2}\'',
select_year: 'Select Year',
select_month: 'Select Month',
select_date: 'Select Date',
@ -1865,10 +1865,11 @@ export default {
sure_bt: 'Confirm'
},
panel: {
watermark: 'Watermark',
panel_get_data_error: 'Failed to obtain panel information. The panel may have been deleted. Please check the panel status',
panel_no_save_tips: 'There are unsaved panel',
panel_cache_use_tips: 'It was checked that the last dashboard could not be saved normally. Do you want to use the panel that was not saved last time?',
template_name_tips: "Panel\'s name should not be null",
template_name_tips: 'Panel\'s name should not be null',
panel_background_item: 'Customize panel background',
panel_background_image_tips: 'Currently.Jpeg,.Jpg,.Png,.Gif files are supported, and the size should not exceed 15m',
reUpload: 'reUpload',
@ -1934,15 +1935,15 @@ export default {
repeat_params: 'Repeat Params Exist',
enable_outer_param_set: 'Enable Outer Param Set',
select_param: 'Please Select Param...',
add_param_link_field: "Add Params' Linked Field",
add_param_link_field: 'Add Params\' Linked Field',
add_param: 'Add Param',
enable_param: 'Enable Param',
param_name: 'Param Name',
outer_param_set: 'Outer Param Set',
outer_param_decode_error: 'External Parameter Parsing Error And Does Not Take Effect, Please Check',
input_param_name: "Please Input Param's Name",
input_param_name: 'Please Input Param\'s Name',
params_setting: 'Outer Params Setting',
template_view_tips: "Template's Views. Please Change",
template_view_tips: 'Template\'s Views. Please Change',
edit_web_tips: 'The Inner Event Can Be Used When Then Panel Not In Edit Status',
no_auth_role: 'Unshared roles',
auth_role: 'Shared roles',
@ -2098,8 +2099,8 @@ export default {
content_style: 'Content Style',
canvas_self_adaption: 'Canvas Self Adaption',
panel_save_tips: 'Do you want to save the changes you made to.',
panel_save_warn_tips: "Your changes will be lost if you don't save them",
do_not_save: "Don't Save",
panel_save_warn_tips: 'Your changes will be lost if you don\'t save them',
do_not_save: 'Don\'t Save',
save_and_close: 'Save',
drill: 'drill',
linkage: 'linkage',

View File

@ -1451,7 +1451,7 @@ export default {
field_rename: '字段重命名',
params_work: '僅在編輯 sql 時生效',
sql_variable_limit_1: '1、SQL變數只能在WHERE條件中使用',
sql_variable_limit_2: "2、示例select * from table_name where column_name1='${param_name1}' and column_name2 in '${param_name2}'",
sql_variable_limit_2: '2、示例select * from table_name where column_name1=\'${param_name1}\' and column_name2 in \'${param_name2}\'',
selesql_variable_limit_2ct_year: '選擇年',
select_month: '選擇月',
select_date: '選擇日期',
@ -1865,6 +1865,7 @@ export default {
sure_bt: '確定'
},
panel: {
watermark: '水印',
panel_get_data_error: '獲取儀表板信息失敗,儀表板可能已經被刪除,請檢查儀表板狀態',
panel_no_save_tips: '存在未保存的儀表板',
panel_cache_use_tips: '檢查到上次有儀表板未能正常保存,是否使用上次未保存的儀表板?',

View File

@ -1451,7 +1451,7 @@ export default {
params_work: '仅在编辑sql时生效',
select_year: '选择年',
sql_variable_limit_1: '1、SQL 变量只能在 WHERE 条件中使用',
sql_variable_limit_2: "2、示例select * from table_name where column_name1='${param_name1}' and column_name2 in '${param_name2}'",
sql_variable_limit_2: '2、示例select * from table_name where column_name1=\'${param_name1}\' and column_name2 in \'${param_name2}\'',
select_month: '选择月',
select_date: '选择日期',
select_time: '选择时间',
@ -1865,6 +1865,7 @@ export default {
sure_bt: '确定'
},
panel: {
watermark: '水印',
panel_get_data_error: '获取仪表板信息失败,仪表板可能已经被删除,请检查仪表板状态',
panel_no_save_tips: '存在未保存的仪表板',
panel_cache_use_tips: '检查到上次有仪表板未能正常保存,是否使用上次未保存的仪表板?',

View File

@ -0,0 +1,539 @@
/* 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;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 2459092 */
src: url('iconfont.woff2?t=1662616551987') format('woff2'),
url('iconfont.woff?t=1662616551987') format('woff'),
url('iconfont.ttf?t=1662616551987') format('truetype');
src: url('iconfont.woff2?t=1668397590143') format('woff2'),
url('iconfont.woff?t=1668397590143') format('woff'),
url('iconfont.ttf?t=1668397590143') format('truetype');
}
.iconfont {
@ -13,6 +13,14 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-WATERMARK:before {
content: "\ea16";
}
.icon-layer:before {
content: "\e63b";
}
.icon-application:before {
content: "\e89e";
}

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,20 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "23072499",
"name": "WATERMARK",
"font_class": "WATERMARK",
"unicode": "ea16",
"unicode_decimal": 59926
},
{
"icon_id": "10904998",
"name": "图层",
"font_class": "layer",
"unicode": "e63b",
"unicode_decimal": 58939
},
{
"icon_id": "12253601",
"name": "application",

View File

@ -76,7 +76,9 @@ export default {
createBy: res.data.createBy,
createTime: res.data.createTime,
updateBy: res.data.updateBy,
updateTime: res.data.updateTime
updateTime: res.data.updateTime,
watermarkOpen: res.data.watermarkOpen,
watermarkInfo: res.data.watermarkInfo
}
this.$store.dispatch('panel/setPanelInfo', this.panelInfo)

View File

@ -161,7 +161,7 @@
/>
</span>
<span v-if="data.nodeType === 'folder'">
<svg-icon icon-class="scene" />
<svg-icon icon-class="scene"/>
</span>
<span
:class="data.status"
@ -198,7 +198,7 @@
<el-dropdown-item
:command="beforeClickEdit('folder', 'new', data, node)"
>
<svg-icon icon-class="scene" />
<svg-icon icon-class="scene"/>
<span style="margin-left: 5px">{{ $t('panel.groupAdd') }}</span>
</el-dropdown-item>
<el-dropdown-item
@ -321,7 +321,7 @@
:label="$t('commons.name')"
prop="name"
>
<el-input v-model="groupForm.name" />
<el-input v-model="groupForm.name"/>
</el-form-item>
</el-form>
<div
@ -332,8 +332,8 @@
size="mini"
@click="close()"
>{{
$t('panel.cancel')
}}
$t('panel.cancel')
}}
</el-button>
<el-button
type="primary"
@ -409,8 +409,8 @@
size="mini"
@click="closeMoveGroup()"
>{{
$t('dataset.cancel')
}}
$t('dataset.cancel')
}}
</el-button>
<el-button
:disabled="groupMoveConfirmDisabled"
@ -969,7 +969,9 @@ export default {
createBy: data.createBy,
createTime: data.createTime,
updateBy: data.updateBy,
updateTime: data.updateTime
updateTime: data.updateTime,
watermarkOpen: data.watermarkOpen,
watermarkInfo: data.watermarkInfo
})
bus.$emit('PanelSwitchComponent', { name: 'PanelEdit' })
},