pref(仪表板): 公共链接导出等组件优化

This commit is contained in:
wangjiahao 2024-02-22 14:11:08 +08:00
parent 9b321a172a
commit 25e2e4afb8
5 changed files with 431 additions and 0 deletions

View File

@ -0,0 +1,225 @@
<template>
<div
:id="previewMainDomId"
:ref="previewOutRefId"
class="bg"
:style="customStyle"
>
<link-opt-bar/>
<Preview />
</div>
</template>
<script>
import { mapState } from 'vuex'
import { imgUrlTrans } from '@/components/canvas/utils/utils'
import { hasDataPermission } from '@/utils/permission'
import { hexColorToRGBA } from '@/views/chart/chart/util'
export default {
model: {
prop: 'show',
event: 'change'
},
props: {
},
data() {
return {
backToTopBtnShow: false,
imageDownloading: false,
chartDetailsVisible: false,
canvasMain: null,
tempCanvas: null,
showChartInfo: {},
showChartTableInfo: {},
showChartInfoType: 'details',
mainHeightCount: null,
userInfo: null,
previewMainDomId: 'preview-main-' + this.canvasId,
previewDomId: 'preview-' + this.canvasId,
previewRefId: 'preview-ref-' + this.canvasId,
previewOutRefId: 'preview-out-ref-' + this.canvasId,
previewTempDomId: 'preview-temp-' + this.canvasId,
previewTempRefId: 'preview-temp-ref-' + this.canvasId,
isShowPreview: false,
panelId: '',
needToChangeHeight: [
'top',
'height'
],
needToChangeWidth: [
'left',
'width'
],
needToChangeInnerWidth: [
'fontSize',
'activeFontSize',
'borderWidth',
'letterSpacing'
],
scaleWidth: '100',
scaleHeight: '100',
timer: null,
componentDataShow: null,
mainWidth: '100%',
mainHeight: '100%',
searchCount: 0,
filterMapCache: {},
// 1.pc pc 2.mobile
terminal: 'pc',
buttonFilterMap: null,
pdfExportShow: false,
dataLoading: false,
exporting: false,
snapshotInfo: '',
pdfTemplateSelectedIndex: 0,
pdfTemplateContent: '',
templateInfo: {},
pdfTemplateAll: [],
pixel: '1280 * 720'
}
},
computed: {
screenShotStatues() {
return this.exporting || this.screenShot || this.backScreenShot
},
mainActiveName() {
return this.$store.state.panel.mainActiveName
},
showUnpublishedArea() {
if (this.canvasId !== 'canvas-main') {
return false
}
if (this.showPosition === 'edit') {
return false
} else if (this.panelInfo && this.panelInfo.showType === 'view') {
return false
} else if ((this.mainActiveName === 'PanelMain' && this.activeTab === 'PanelList') || this.showPosition.includes('multiplexing')) {
return this.panelInfo.status === 'unpublished' && !hasDataPermission('manage', this.panelInfo.privileges)
} else {
return this.panelInfo.status === 'unpublished'
}
},
canvasInfoMainStyle() {
if (this.backScreenShot) {
return {
width: '100%',
height: this.mainHeight
}
} else {
return {
width: '100%',
height: '100%'
}
}
},
canvasInfoTempStyle() {
if (this.screenShot) {
return {
width: '100%',
height: this.mainHeight
}
} else {
return {
width: '100%',
height: '100%'
}
}
},
customStyle() {
let style = {
width: '100%'
}
if (this.canvasStyleData.openCommonStyle && this.isMainCanvas()) {
const styleInfo = this.terminal === 'mobile' && this.canvasStyleData.panel.mobileSetting && this.canvasStyleData.panel.mobileSetting.customSetting
? this.canvasStyleData.panel.mobileSetting : this.canvasStyleData.panel
if (styleInfo.backgroundType === 'image' && typeof (styleInfo.imageUrl) === 'string') {
style = {
background: `url(${imgUrlTrans(styleInfo.imageUrl)}) no-repeat`
}
} else if (styleInfo.backgroundType === 'color') {
const colorRGBA = hexColorToRGBA(styleInfo.color, styleInfo.alpha === undefined ? 100 : styleInfo.alpha)
style = {
background: colorRGBA
}
} else {
style = {
background: '#f7f8fa'
}
}
}
if (this.backScreenShot) {
style.height = this.mainHeight
} else {
style.padding = '5px'
}
return style
},
screenShotStyle() {
return this.screenShot ? this.customStyle : {}
},
// componentData mapState
componentDataInfo() {
return this.componentDataShow || []
},
...mapState([
'previewCanvasScale',
'isClickComponent'
])
}
}
</script>
<style lang="scss" scoped>
.bg {
min-width: 200px;
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 {
line-height: 30px;
width: 100%;
z-index: 100;
height: 100%;
text-align: center;
cursor: not-allowed;
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
flex-flow: row nowrap;
color: #9ea6b2;
}
.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;
}
::v-deep .el-tabs__nav {
z-index: 0;
}
</style>

View File

@ -0,0 +1,34 @@
<template>
<div class="circle-shape">
<v-text
:prop-value="element.propValue"
:element="element"
/>
</div>
</template>
<script>
export default {
props: {
propValue: {
type: String,
required: true,
default: ''
},
element: {
type: Object,
default: () => {}
}
}
}
</script>
<style lang="scss" scoped>
.circle-shape {
width: 100%;
height: 100%;
border-radius: 50%;
overflow: auto;
}
</style>

View File

@ -0,0 +1,14 @@
<template>
<div class="line-shape"></div>
</template>
<script>
</script>
<style lang="scss" scoped>
.line-shape {
width: 100%;
height: 100%;
overflow: auto;
}
</style>

View File

@ -0,0 +1,93 @@
<template>
<div class="svg-triangle-container">
<svg
version="1.1"
baseProfile="full"
xmlns="http://www.w3.org/2000/svg"
>
<polygon
ref="triangle"
:points="points"
:stroke="element.style.borderColor"
:fill="element.style.backgroundColor"
stroke-width="1"
/>
</svg>
<v-text
:prop-value="element.propValue"
:element="element"
/>
</div>
</template>
<script>
export default {
props: {
propValue: {
type: String,
required: true,
default: ''
},
element: {
type: Object,
default: () => {}
}
},
data() {
return {
points: ''
}
},
watch: {
'element.style.width': function() {
this.draw()
},
'element.style.height': function() {
this.draw()
}
},
mounted() {
this.draw()
},
methods: {
draw() {
const { width, height } = this.element.style
this.drawTriangle(width, height)
},
drawTriangle(width, height) {
//
const points = [
[0.5, 0.05],
[1, 0.95],
[0, 0.95]
]
const coordinatePoints = points.map(point => width * point[0] + ' ' + height * point[1])
this.points = coordinatePoints.toString()
}
}
}
</script>
<style lang="scss" scoped>
.svg-triangle-container {
width: 100%;
height: 100%;
svg {
width: 100%;
height: 100%;
}
.v-text {
position: absolute;
top: 72%;
left: 50%;
transform: translate(-50%, -50%);
width: 50%;
height: 40%;
}
}
</style>

View File

@ -1,4 +1,5 @@
import { toPng } from 'html-to-image' import { toPng } from 'html-to-image'
import store from "@/store";
export function toPngUrl(refContainer, callBack) { export function toPngUrl(refContainer, callBack) {
toPng(refContainer) toPng(refContainer)
@ -9,3 +10,67 @@ export function toPngUrl(refContainer, callBack) {
console.error('oops, toPngUrl went wrong!', error) console.error('oops, toPngUrl went wrong!', error)
}) })
} }
export function dataURLToBlobCheck(dataurl) { // ie 图片转格式
const arr = dataurl.split(',')
const mime = arr[0].match(/:(.*?);/)[1]
const bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: mime })
}
export function colorReverseCheck(OldColorValue) {
OldColorValue = '0x' + OldColorValue.replace(/#/g, '')
const str = '000000' + (0xFFFFFF - OldColorValue).toString(16)
return '#' + str.substring(str.length - 6, str.length)
}
export function imgUrlTransCheck(url) {
if (url && typeof url === 'string' && url.indexOf('static-resource') > -1) {
return process.env.VUE_APP_BASE_API + url.replace('/static-resource', 'static-resource')
} else {
return url
}
}
export function getNowCanvasComponentDataCheck(canvasId, showPosition) {
if (showPosition && (showPosition.includes('email-task') || showPosition.includes('multiplexing'))) {
return store.state.previewComponentData.filter(item => item.canvasId === canvasId)
} else {
return store.state.componentData.filter(item => item.canvasId === canvasId)
}
}
export function findCurComponentIndexCheck(componentData, curComponent) {
let curIndex = 0
for (let index = 0; index < componentData.length; index++) {
const element = componentData[index]
if (element.id && element.id === curComponent.id) {
curIndex = index
break
}
}
return curIndex
}
export function deleteTreeNodeCheck(nodeId, tree, nodeTarget) {
if (!nodeId || !tree || !tree.length) {
return
}
for (let i = 0, len = tree.length; i < len; i++) {
if (tree[i].id === nodeId) {
if (nodeTarget) {
nodeTarget['target'] = tree[i]
}
tree.splice(i, 1)
return
} else if (tree[i].children && tree[i].children.length) {
deleteTreeNode(nodeId, tree[i].children, nodeTarget)
}
}
}