feat(数据大屏): 添加时间组件格式即样式优化 #8157

This commit is contained in:
wangjiahao 2024-03-18 16:27:36 +08:00
parent 3453ad540f
commit 18c78379bd
13 changed files with 336 additions and 292 deletions

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="1710744481632" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5131" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M928 960H576c-17.67 0-32-14.33-32-32V576c0-17.67 14.33-32 32-32h352c17.67 0 32 14.33 32 32v352c0 17.67-14.33 32-32 32z m-320-64h288V608H608v288zM448 960H96c-17.67 0-32-14.33-32-32V576c0-17.67 14.33-32 32-32h352c17.67 0 32 14.33 32 32v352c0 17.67-14.33 32-32 32z m-320-64h288V608H128v288zM448 480H96c-17.67 0-32-14.33-32-32V96c0-17.67 14.33-32 32-32h352c17.67 0 32 14.33 32 32v352c0 17.67-14.33 32-32 32z m-320-64h288V128H128v288zM752 480c-8.19 0-16.38-3.12-22.63-9.37l-176-176c-12.5-12.5-12.5-32.76 0-45.25l176-176c12.5-12.5 32.76-12.5 45.25 0l176 176c12.5 12.5 12.5 32.76 0 45.25l-176 176c-6.24 6.25-14.43 9.37-22.62 9.37zM621.25 272L752 402.75 882.75 272 752 141.25 621.25 272z" p-id="5132"></path></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

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="1710745564820" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4252" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 924c-55.6 0-109.6-10.9-160.4-32.4-49.1-20.8-93.1-50.5-131-88.3-37.8-37.8-67.5-81.9-88.3-131C110.9 621.6 100 567.6 100 512s10.9-109.6 32.4-160.4c20.8-49.1 50.5-93.1 88.3-131 37.8-37.8 81.9-67.5 131-88.3C402.4 110.9 456.4 100 512 100c75.8 0 150 20.8 214.4 60.1 11.8 7.2 15.5 22.6 8.3 34.4-7.2 11.8-22.6 15.5-34.4 8.3C643.8 168.2 578.6 150 512 150c-199.6 0-362 162.4-362 362s162.4 362 362 362 362-162.4 362-362c0-11.6-0.6-23.3-1.7-34.8-1.3-13.7 8.8-26 22.5-27.3 13.7-1.3 26 8.8 27.3 22.5 1.2 13.1 1.9 26.4 1.9 39.6 0 55.6-10.9 109.6-32.4 160.4-20.8 49.1-50.5 93.1-88.3 131-37.8 37.8-81.9 67.5-131 88.3C621.6 913.1 567.6 924 512 924z" p-id="4253"></path><path d="M696.4 512.5H508.3c-13.8 0-25 11.3-25 25s11.2 25 25 25h188.1c13.8 0 25-11.3 25-25s-11.2-25-25-25z" p-id="4254"></path><path d="M508.3 313c-13.8 0-25 11.3-25 25v199.5c0 13.8 11.3 25 25 25s25-11.3 25-25V338c0-13.7-11.2-25-25-25z m357.4-54.1l-42.4-137.7c-7.2-23.4-37.9-28.8-52.6-9.3L669 246.4c-14.8 19.5-1.2 47.5 23.3 48.1l144.1 3.2c20.4 0.5 35.3-19.2 29.3-38.8zM510 798.3c-13.8 0-25 11.3-25 25v11.5c0 13.8 11.3 25 25 25s25-11.3 25-25v-11.5c0-13.8-11.2-25-25-25z m-1-631c-13.8 0-25 11.3-25 25v11.5c0 13.8 11.3 25 25 25s25-11.3 25-25v-11.5c0-13.8-11.2-25-25-25zM205.3 515.5h-11.5c-13.8 0-25 11.3-25 25s11.3 25 25 25h11.5c13.8 0 25-11.3 25-25s-11.3-25-25-25z m623 0h-12.5c-13.8 0-25 11.3-25 25s11.3 25 25 25h12.5c13.8 0 25-11.3 25-25s-11.3-25-25-25z" p-id="4255"></path></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -15,6 +15,7 @@ import CommonGroup from '@/custom-component/component-group/CommonGroup.vue'
import DeResourceGroupOpt from '@/views/common/DeResourceGroupOpt.vue'
import { canvasSave } from '@/utils/canvasUtils'
import { changeSizeWithScale } from '@/utils/changeComponentsSizeWithScale'
import MoreComGroup from '@/custom-component/component-group/MoreComGroup.vue'
let nameEdit = ref(false)
let inputName = ref('')
let nameInput = ref(null)
@ -201,6 +202,9 @@ eventBus.on('clearCanvas', clearCanvas)
<component-group is-label :base-width="115" icon-name="dv-media" title="媒体">
<media-group></media-group>
</component-group>
<component-group is-label :base-width="115" icon-name="dv-more-com" title="更多">
<more-com-group></more-com-group>
</component-group>
<component-group is-label :base-width="410" icon-name="dv-material" title="素材">
<common-group></common-group>
</component-group>

View File

@ -134,7 +134,7 @@ const stopEvent = e => {
:background-border-select-width="backgroundBorderSelectWidth"
/>
</el-collapse-item>
<slot></slot>
<el-collapse-item
v-if="showStyle"
:effect="themes"
@ -257,7 +257,6 @@ const stopEvent = e => {
</el-row>
</el-form>
</el-collapse-item>
<slot></slot>
</el-collapse>
</div>
</template>

View File

@ -0,0 +1,64 @@
<script setup lang="ts">
import { toRefs } from 'vue'
import eventBus from '@/utils/eventBus'
import DragComponent from '@/custom-component/component-group/DragComponent.vue'
import { commonHandleDragEnd, commonHandleDragStart } from '@/utils/canvasUtils'
const props = defineProps({
propValue: {
type: Array,
default: () => []
},
dvModel: {
type: String,
default: 'dv'
},
element: {
type: Object,
default() {
return {
propValue: null
}
}
},
themes: {
type: String,
default: 'dark'
}
})
const { dvModel } = toRefs(props)
const newComponent = () => {
eventBus.emit('handleNew', { componentName: 'DeTimeClock', innerType: 'DeTimeClock' })
}
const handleDragStart = e => {
commonHandleDragStart(e, dvModel.value)
}
const handleDragEnd = e => {
commonHandleDragEnd(e, dvModel.value)
}
</script>
<template>
<div
class="group"
@dragstart="handleDragStart"
@dragend="handleDragEnd"
v-on:click="newComponent"
>
<drag-component
:themes="themes"
name="YYYY-MM-DD 08:00:00"
label="日期时间"
drag-info="DeTimeClock&DeTimeClock"
></drag-component>
</div>
</template>
<style lang="less" scoped>
.group {
padding: 12px 8px;
}
</style>

View File

@ -119,6 +119,36 @@ const list = [
},
matrixStyle: {}
},
{
component: 'DeTimeClock',
name: '时间组件',
label: '时间组件',
icon: 'dv-more-time-clock',
innerType: 'DeTimeClock',
editing: false,
canvasActive: false,
x: 1,
y: 1,
sizeX: 18,
sizeY: 6,
propValue: {},
style: {
width: 300,
height: 100,
fontSize: 22,
fontWeight: 400,
textAlign: 'center',
color: '#000000'
},
formatInfo: {
openMode: '0',
showWeek: false,
showDate: true,
dateFormat: 'yyyy-MM-dd',
timeFormat: 'hh:mm:ss'
},
matrixStyle: {}
},
{
component: 'Picture',
name: '图片',

View File

@ -1,257 +0,0 @@
<template>
<div>
<canvas :id="'complex_canvas' + element.id" width="500" height="500" />
</div>
</template>
<script lang="ts" setup>
import { toRefs } from 'vue/dist/vue'
import { getCurrentInstance, onMounted, reactive } from 'vue'
let milliseconds = 0
let minutes = 0
let hour = 0
let date = ''
const props = defineProps({
element: {
type: Object
}
})
const { element } = toRefs(props)
const state = reactive({
time: '',
date: '',
week: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
canvas: null,
ctx: null,
ctxBack: null,
numBack: null,
timer: null
})
const currentTime = () => {
state.timer = setInterval(pageInit, 500)
}
const initCtx = () => {
state.ctx = state.canvas.getContext('2d')
state.ctx.strokeStyle = '#7FFFD4'
state.ctx.lineWidth = 3
state.ctx.shadowBlur = 5
state.ctx.shadowColor = '#7FFFD4'
}
const initCtxBack = () => {
state.ctxBack = state.canvas.getContext('2d')
state.ctxBack.lineWidth = 1
state.ctxBack.shadowBlur = 0
state.ctxBack.shadowColor = '#F0F8FF'
}
const initNumBack = () => {
state.numBack = state.canvas.getContext('2d')
}
const pageInit = () => {
showTime()
showBack()
drawSecPin()
drawMinPin()
drawHouPin()
setPoint()
setNum()
},
setNum = () => {
state.numBack.save()
state.numBack.translate(250, 250)
state.numBack.beginPath()
state.numBack.fillStyle = '#7FFFD4'
state.numBack.font = '30px Helvetica'
for (let i = 0; i < 60; i++) {
if (i % 5 === 0) {
state.numBack.lineWidth = 5
let xPoint = Math.sin((i * 6 * 2 * Math.PI) / 360) * 195
let yPoint = -Math.cos((i * 6 * 2 * Math.PI) / 360) * 195
state.numBack.fillText(
i === 0 ? 12 : i / 5,
i === 0 ? -15 : xPoint - 10,
i === 0 ? -185 : i <= 30 ? yPoint + 5 : yPoint + 10
)
}
}
state.numBack.stroke()
state.numBack.closePath()
state.numBack.restore()
}
const drawSecPin = () => {
state.ctxBack.save()
state.ctxBack.translate(250, 250)
state.ctxBack.rotate((milliseconds / 60) * 2 * Math.PI)
state.ctxBack.beginPath()
state.ctxBack.strokeStyle = '#AFEEEE'
state.ctxBack.lineWidth = 1
state.ctxBack.lineJoin = 'bevel'
state.ctxBack.miterLimit = 10
state.ctxBack.moveTo(0, 30)
state.ctxBack.lineTo(3, -175)
state.ctxBack.lineTo(13, -165)
state.ctxBack.lineTo(0, -210)
state.ctxBack.lineTo(-13, -165)
state.ctxBack.lineTo(-3, -175)
state.ctxBack.lineTo(0, 30)
state.ctxBack.stroke()
state.ctxBack.closePath()
state.ctxBack.restore()
}
const drawMinPin = () => {
state.ctxBack.save()
state.ctxBack.translate(250, 250)
state.ctxBack.rotate((minutes * 6 * Math.PI) / 180)
state.ctxBack.beginPath()
state.ctxBack.strokeStyle = '#20B2AA'
state.ctxBack.lineWidth = 1
state.ctxBack.lineJoin = 'bevel'
state.ctxBack.miterLimit = 10
state.ctxBack.moveTo(0, 20)
state.ctxBack.lineTo(3, -145)
state.ctxBack.lineTo(10, -135)
state.ctxBack.lineTo(0, -180)
state.ctxBack.lineTo(-10, -135)
state.ctxBack.lineTo(-3, -145)
state.ctxBack.lineTo(0, 20)
state.ctxBack.stroke()
state.ctxBack.closePath()
state.ctxBack.restore()
}
const drawHouPin = () => {
state.ctxBack.save()
state.ctxBack.translate(250, 250)
state.ctxBack.rotate((hour * 30 * Math.PI) / 180)
state.ctxBack.beginPath()
state.ctxBack.strokeStyle = '#87CEFA'
state.ctxBack.lineWidth = 1
state.ctxBack.lineJoin = 'bevel'
state.ctxBack.miterLimit = 10
state.ctxBack.moveTo(0, 20)
state.ctxBack.lineTo(3, -110)
state.ctxBack.lineTo(10, -100)
state.ctxBack.lineTo(0, -150)
state.ctxBack.lineTo(-10, -100)
state.ctxBack.lineTo(-3, -110)
state.ctxBack.lineTo(0, 20)
state.ctxBack.stroke()
state.ctxBack.closePath()
state.ctxBack.restore()
}
const setPoint = () => {
state.ctxBack.beginPath()
state.ctxBack.fillStyle = 'black'
state.ctxBack.arc(250, 250, 3, 0, 2 * Math.PI)
state.ctxBack.stroke()
}
const showBack = () => {
for (let i = 0; i < 60; i++) {
state.ctxBack.save()
state.ctxBack.translate(250, 250)
state.ctxBack.rotate((i / 60) * 2 * Math.PI)
state.ctxBack.beginPath()
state.ctxBack.strokeStyle = '#7FFFD4'
state.ctxBack.moveTo(0, -250)
state.ctxBack.lineWidth = i % 5 === 0 ? 5 : 2
state.ctxBack.lineTo(0, -230)
state.ctxBack.stroke()
state.ctxBack.closePath()
state.ctxBack.restore()
}
state.ctxBack.beginPath()
state.ctxBack.arc(250, 250, 230, 0, 2 * Math.PI)
state.ctxBack.stroke()
}
const degToRad = degree => {
let result
let factor = Math.PI / 180
if (degree === 0) {
result = 270 * factor
} else {
result = degree * factor
}
return result
}
const showTime = () => {
let now = new Date()
let today = now.toLocaleDateString()
let time = now.toLocaleTimeString()
let day = now.getDay()
let hrs = now.getHours()
let min = now.getMinutes()
let sec = now.getSeconds()
let mil = now.getMilliseconds()
let smoothsec = sec + mil / 1000
let smoothmin = min + smoothsec / 60
let hours = hrs + smoothmin / 60
milliseconds = smoothsec
minutes = smoothmin
hour = hours
switch (day) {
case 1:
date = '一'
break
case 2:
date = '二'
break
case 3:
date = '三'
break
case 4:
date = '四'
break
case 5:
date = '五'
break
case 6:
date = '六'
break
case 0:
date = '日'
break
}
const gradient = state.ctx.createRadialGradient(250, 250, 5, 250, 250, 300)
gradient.addColorStop(0, '#03303a')
gradient.addColorStop(1, 'black')
state.ctx.fillStyle = gradient
state.ctx.fillRect(0, 0, 500, 500)
state.ctx.beginPath()
state.ctx.strokeStyle = '#87CEFA'
state.ctx.arc(250, 250, 215, degToRad(0), degToRad(hours * 30 - 90))
state.ctx.stroke()
state.ctx.beginPath()
state.ctx.strokeStyle = '#20B2AA'
state.ctx.arc(250, 250, 220, degToRad(0), degToRad(smoothmin * 6 - 90))
state.ctx.stroke()
state.ctx.beginPath()
state.ctx.strokeStyle = '#AFEEEE'
state.ctx.arc(250, 250, 225, degToRad(0), degToRad(smoothsec * 6 - 90))
state.ctx.stroke()
state.ctx.font = '25px Helvetica Bold'
state.ctx.fillStyle = '#7FFFD4'
state.ctx.fillText(today + '/星期' + date, 150, 230)
state.ctx.font = '23px Helvetica Bold'
state.ctx.fillStyle = '#7FFFD4'
state.ctx.fillText(time, 190, 280)
}
onMounted(() => {
state.canvas = document.getElementById('complex_canvas' + element.value.id)
initCtx()
initCtxBack()
initNumBack()
currentTime()
})
</script>
<style lang="less" scoped></style>

View File

@ -10,6 +10,7 @@ import { beforeUploadCheck, uploadFileResult } from '@/api/staticResource'
import { imgUrlTrans } from '@/utils/imgUtils'
import eventBus from '@/utils/eventBus'
import ImgViewDialog from '@/custom-component/ImgViewDialog.vue'
import TimeClockFormat from '@/custom-component/de-time-clock/TimeClockFormat.vue'
withDefaults(
defineProps<{
@ -101,6 +102,17 @@ onBeforeUnmount(() => {
:background-color-picker-width="197"
:background-border-select-width="197"
>
<el-collapse-item
:effect="themes"
title="日期格式"
name="timeClockFormat"
v-if="curComponent && curComponent.formatInfo"
>
<time-clock-format
:format-info="curComponent.formatInfo"
:themes="themes"
></time-clock-format>
</el-collapse-item>
</CommonAttr>
</div>
</template>

View File

@ -1,29 +1,12 @@
<template>
<div style="height: 100%">
<time-default
v-if="element?.formatInfo?.openMode === '0'"
:ref="element.id"
:element="element"
/>
<time-elec v-if="element?.formatInfo?.openMode === '1'" :ref="element.id" :element="element" />
<time-simple
v-if="element?.formatInfo?.openMode === '2'"
:ref="element.id"
:element="element"
/>
<time-complex
v-if="element?.formatInfo?.openMode === '3'"
:ref="element.id"
:element="element"
/>
<time-default :ref="element.id" :element="element" />
</div>
</template>
<script setup lang="ts">
import { computed, nextTick, toRefs, getCurrentInstance, onMounted } from 'vue'
import TimeDefault from '@/custom-component/de-time-clock/TimeDefault.vue'
const props = defineProps({
element: {
type: Object

View File

@ -0,0 +1,133 @@
<script setup lang="ts">
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
import { storeToRefs } from 'pinia'
import {onMounted, reactive} from "vue";
const state = reactive({
})
const dvMainStore = dvMainStoreWithOut()
const snapshotStore = snapshotStoreWithOut()
const { curComponent } = storeToRefs(dvMainStore)
</script>
<template>
<el-collapse-item :effect="themes" title="位置" name="position" v-if="!dashboardActive">
<component-position :themes="themes" />
</el-collapse-item>
</template>
<style lang="less" scoped>
.de-collapse-style {
:deep(.ed-collapse-item__header) {
height: 36px !important;
line-height: 36px !important;
font-size: 12px !important;
padding: 0 !important;
font-weight: 500 !important;
.ed-collapse-item__arrow {
margin: 0 6px 0 8px;
}
}
:deep(.ed-collapse-item__content) {
padding: 16px 8px 0;
}
:deep(.ed-form-item) {
display: block;
margin-bottom: 8px;
}
:deep(.ed-form-item__label) {
justify-content: flex-start;
}
}
.disabled :deep(.el-upload--picture-card) {
display: none;
}
.avatar-uploader :deep(.ed-upload) {
width: 80px;
height: 80px;
line-height: 90px;
}
.avatar-uploader :deep(.ed-upload-list li) {
width: 80px !important;
height: 80px !important;
}
:deep(.ed-upload--picture-card) {
background: #eff0f1;
border: 1px dashed #dee0e3;
border-radius: 4px;
.ed-icon {
color: #1f2329;
}
&:hover {
.ed-icon {
color: var(--ed-color-primary);
}
}
}
.img-area {
height: 80px;
width: 80px;
margin-top: 10px;
overflow: hidden;
&.img-area_dark {
:deep(.ed-upload-list__item).is-success {
border-color: #434343;
}
:deep(.ed-upload--picture-card) {
background: #373737;
border-color: #434343;
.ed-icon {
color: #ebebeb;
}
&:hover {
.ed-icon {
color: var(--ed-color-primary);
}
}
}
}
&.img-area_light {
:deep(.ed-upload-list__item).is-success {
border-color: #dee0e3;
}
}
}
.image-hint {
color: #8f959e;
size: 14px;
line-height: 22px;
font-weight: 400;
margin-top: 2px;
&.image-hint_dark {
color: #757575;
}
}
.re-update-span {
cursor: pointer;
color: var(--ed-color-primary);
size: 14px;
line-height: 22px;
font-weight: 400;
}
</style>

View File

@ -0,0 +1,81 @@
<template>
<el-row>
<el-form ref="form">
<el-form-item v-show="formatInfo.showDate" label="显示日期">
<el-select
v-model="formatInfo.dateFormat"
:effect="themes"
style="width: 100%"
@change="onFormatChange"
>
<el-option
v-for="item in state.dateOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="显示时间">
<el-select
v-model="formatInfo.timeFormat"
:effect="themes"
filterable
allow-create
default-first-option
style="width: 100%"
@change="onFormatChange"
>
<el-option
v-for="item in state.timeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
</el-row>
</template>
<script setup lang="ts">
import { reactive, toRefs } from 'vue'
const state = reactive({
timeOptions: [
{ value: 'hh:mm:ss', label: 'hh:mm:ss' },
{ value: 'hh时mm分ss秒', label: 'hh时mm分ss秒' },
{ value: '', label: '无' }
],
dateOptions: [
{ value: 'yyyy-MM-dd', label: 'yyyy-MM-dd' },
{ value: 'yyyy/MM/dd', label: 'yyyy/MM/dd' },
{ value: 'yyyy年MM月dd日', label: 'yyyy年MM月dd日' }
]
})
const props = defineProps({
canvasId: {
type: String,
require: true
},
formatInfo: {
type: Object,
required: true
},
themes: {
type: String,
required: true,
default: 'dark'
}
})
const { formatInfo } = toRefs(props)
const onFormatChange = () => {
// doFormatChange
}
</script>
<style lang="less" scoped></style>

View File

@ -1,9 +1,6 @@
<template>
<div
style="display: flex; align-items: center"
:style="{ height: containerHeight, margin: timeMargin + 'px' }"
>
<p style="width: 100%; margin: auto">{{ nowDate }}</p>
<div style="width: 100%; height: 100%; display: flex; align-items: center">
<p>{{ state.nowDate }}</p>
</div>
</template>
@ -22,13 +19,6 @@ const state = reactive({
nowWeek: '',
timer: null
})
const timeMargin = computed(() => {
return element.value.style.time_margin
})
const containerHeight = computed(() => {
return 'calc(100% - ' + element.value.style.time_margin * 2 + 'px)'
})
const currentTime = () => {
state.timer = setInterval(formatDate, 500)

View File

@ -21,7 +21,8 @@ import RectShape from '@/custom-component/rect-shape/Component.vue'
import RectShapeAttr from '@/custom-component/rect-shape/Attr.vue'
import SvgTriangle from '@/custom-component/svgs/svg-triangle/Component.vue'
import SvgTriangleAttr from '@/custom-component/svgs/svg-triangle/Attr.vue'
import DeTimeClock from '@/custom-component/de-time-clock/Component.vue'
import DeTimeClockAttr from '@/custom-component/de-time-clock/Attr.vue'
export const componentsMap = {
VText: VText,
VQuery,
@ -45,7 +46,9 @@ export const componentsMap = {
RectShape: RectShape,
RectShapeAttr: RectShapeAttr,
SvgTriangle: SvgTriangle,
SvgTriangleAttr: SvgTriangleAttr
SvgTriangleAttr: SvgTriangleAttr,
DeTimeClock: DeTimeClock,
DeTimeClockAttr: DeTimeClockAttr
}
export default function findComponent(key) {