feat: 新增背景 顶栏 全屏按钮 时间组件 修复通用组件无法刷新bug

This commit is contained in:
huanghao1412 2024-01-23 20:57:40 +08:00
parent 0a3cbab613
commit abb99c6f77
32 changed files with 448 additions and 13 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -49,10 +49,9 @@ export const useChartCommonData = (
else {
series = [seriesItem]
}
Object.assign(targetComponent.option, {
series,
dataset,
})
if (vChartRef.value) {
setOption(vChartRef.value, { series, dataset })
}
}
}
}

View File

@ -0,0 +1,30 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { chartInitConfig } from '@/settings/designSetting'
import { FullScreenBtnConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
export enum FontWeightEnum {
NORMAL = '常规',
BOLD = '加粗',
}
export const FontWeightObject = {
[FontWeightEnum.NORMAL]: 'normal',
[FontWeightEnum.BOLD]: 'bold',
}
export const option = {
color: '#4396fd',
fontSize: 14,
fontWeight: 'normal',
border: 1,
borderColor: '#4396fd'
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = FullScreenBtnConfig.key
public attr = { ...chartInitConfig, w: 100, h: 40, zIndex: -1 }
public chartConfig = cloneDeep(FullScreenBtnConfig)
public option = cloneDeep(option)
}

View File

@ -0,0 +1,45 @@
<template>
<CollapseItem name="全屏按钮" expanded>
<SettingItemBox name="按钮">
<SettingItem name="字体颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.color"></n-color-picker>
</SettingItem>
<SettingItem name="字体大小">
<n-input-number v-model:value="optionData.fontSize" size="small" :step="0.5" :min="0"></n-input-number>
</SettingItem>
<setting-item name="字体粗细">
<n-select v-model:value="optionData.fontWeight" size="small" :options="fontWeightOptions" />
</setting-item>
<SettingItem name="边框色">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.borderColor"></n-color-picker>
</SettingItem>
<SettingItem name="边框大小">
<n-input-number v-model:value="optionData.border" size="small" :step="0.5" :min="0"></n-input-number>
</SettingItem>
</SettingItemBox>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { option, FontWeightEnum, FontWeightObject } from "./config";
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
const fontWeightOptions = [
{
label: FontWeightEnum.NORMAL,
value: FontWeightObject[FontWeightEnum.NORMAL]
},
{
label: FontWeightEnum.BOLD,
value: FontWeightObject[FontWeightEnum.BOLD]
}
]
</script>

View File

@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const FullScreenBtnConfig: ConfigType = {
key: 'FullScreenBtn',
chartKey: 'VFullScreenBtn',
conKey: 'VCFullScreenBtn',
title: '全屏按钮',
category: ChatCategoryEnum.MORE,
categoryName: ChatCategoryEnumName.MORE,
package: PackagesCategoryEnum.DECORATES,
chartFrame: ChartFrameEnum.STATIC,
image: 'FullScreenBtn.png'
}

View File

@ -0,0 +1,56 @@
<template>
<div
id="fullscreenButton"
class="full-screen-btn"
:style="{color: color, fontSize: `${fontSize}px`, fontWeight, border: `${border}px solid ${borderColor}`}"
@click="toggleFullscreen"
>
<i class="iconfont icon-quanping full-screen" :title="showMoreMenuBts ? '全屏' : '退出全屏'"></i>
{{ showMoreMenuBts ? '全屏' : '退出全屏' }}
</div>
</template>
<script setup lang="ts">
import { PropType, ref, toRefs, watch } from "vue";
import { postMessageToParent } from "@/utils";
import { isPreview } from '@/utils/router'
import { CreateComponentType } from '@/packages/index.d'
import { option } from "./config";
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType & typeof option>,
required: true
}
})
let { color, fontSize, fontWeight, border, borderColor } = toRefs(props.chartConfig.option)
const showMoreMenuBts = ref(true)
//
function toggleFullscreen() {
if(!isPreview()) return
postMessageToParent({type: 'fullScreen'})
showMoreMenuBts.value = !showMoreMenuBts.value
}
</script>
<style lang="scss" scoped>
.full-screen-btn {
width: 100%;
height: 100%;
z-index: 999;
border: #4396fd 1px solid;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
padding: 3px 10px;
box-sizing: border-box;
cursor: pointer;
color: #4396fd;
.full-screen {
font-size: 16px;
margin-right: 5px;
}
}
</style>

View File

@ -0,0 +1,13 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { TimeCommon1Config } from './index'
import cloneDeep from 'lodash/cloneDeep'
import { chartInitConfig } from '@/settings/designSetting'
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = TimeCommon1Config.key
public attr = { ...chartInitConfig, w: 200, h: 50, zIndex: -1 }
public chartConfig = cloneDeep(TimeCommon1Config)
public option = cloneDeep({})
}

View File

@ -0,0 +1,7 @@
<template>
</template>
<script setup lang="ts">
</script>

View File

@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum,ChatCategoryEnumName } from '../../index.d'
export const TimeCommon1Config: ConfigType = {
key: 'TimeCommon1',
chartKey: 'VTimeCommon1',
conKey: 'VCTimeCommon1',
title: '通用时间1',
category: ChatCategoryEnum.MORE,
categoryName: ChatCategoryEnumName.MORE,
package: PackagesCategoryEnum.DECORATES,
chartFrame: ChartFrameEnum.STATIC,
image: 'TimeCommon1.png'
}

View File

@ -0,0 +1,76 @@
<template>
<div class="TimeCommon1">
<AccessTimeFilledIcon class="left"/>
<div class="right">
<div class="top">{{ date }}</div>
<div class="bottom">{{ time }}</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import { icon } from '@/plugins/icon'
import moment from "moment";
const { AccessTimeFilledIcon } = icon.material
import { isPreview } from '@/utils/router'
let date = ref(moment().format('yyyy-MM-DD'))
const weeks = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
let time = ref(moment().format('HH:mm:ss ') + weeks[Number(moment().format('e'))])
let timer: any
onMounted(() => {
if(!isPreview()) return
timer = setInterval(() => {
date.value = moment().format('yyyy-MM-DD')
time.value = moment().format('HH:mm:ss ') + weeks[Number(moment().format('e'))]
}, 1000)
})
onUnmounted(() => {
if(timer) clearInterval(timer)
})
</script>
<style lang="scss" scoped>
.TimeCommon1{
display: flex;
align-items: center;
.left{
font-size: 40px;
width: 40px;
height: 40px;
min-width: 40px;
color: rgb(35, 75, 155);
}
.right{
margin-left: 10px;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
.top{
color: rgb(156, 164, 175);
height: 14px;
font-size: 14px;
line-height: 14px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.bottom{
margin-top: 4px;
color: #fff;
height: 14px;
font-size: 14px;
line-height: 14px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
}
}
</style>

View File

@ -1,7 +1,9 @@
import { NumberConfig } from './Number/index'
import { TimeCommonConfig } from './TimeCommon/index'
import { TimeCommon1Config } from './TimeCommon1/index'
import { ClockConfig } from './Clock/index'
import { FullScreenConfig } from './FullScreen/index'
import { FullScreenBtnConfig } from './FullScreenBtn/index'
// import { FullScreenConfig } from './FullScreen/index'
import { CountDownConfig } from './CountDown/index'
import { FlipperNumberConfig } from './FlipperNumber'
import { PipelineHConfig } from './PipelineH/index'
@ -11,6 +13,8 @@ export default [
// NumberConfig,
// FlipperNumberConfig,
TimeCommonConfig,
TimeCommon1Config,
FullScreenBtnConfig,
// CountDownConfig,
ClockConfig,
// FullScreenConfig,

View File

@ -0,0 +1,28 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { TopBarsConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
export const option = {
// 图片
dataset: '',
// 适应方式
fit: 'fill',
// 圆角
borderRadius: 0
}
export default class Config extends PublicConfigClass implements CreateComponentType
{
constructor() {
super();
this.attr = {
...this.attr,
w: 1920,
h: 80,
}
}
public key = TopBarsConfig.key
public chartConfig = cloneDeep(TopBarsConfig)
public option = cloneDeep(option)
}

View File

@ -0,0 +1,62 @@
<template>
<collapse-item name="属性" :expanded="true">
<setting-item-box name="样式">
<setting-item name="类型">
<n-select
v-model:value="optionData.fit"
size="small"
:options="fitList"
></n-select>
</setting-item>
<setting-item name="圆角">
<n-input-number
v-model:value="optionData.borderRadius"
size="small"
:min="0"
placeholder="圆角"
></n-input-number>
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { option } from './config'
import {
CollapseItem,
SettingItemBox,
SettingItem,
} from '@/components/Pages/ChartItemSetting'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true,
},
})
//
const fitList = [
{
value: 'fill',
label: 'fill'
},
{
value: 'contain',
label: 'contain'
},
{
value: 'cover',
label: 'cover'
},
{
value: 'scale-down',
label: 'scale-down'
},
{
value: 'none',
label: 'none'
},
]
</script>

View File

@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum,ChatCategoryEnumName } from '@/packages/components/Decorates/index.d'
export const TopBarsConfig: ConfigType = {
key: 'TopBars',
chartKey: 'VTopBars',
conKey: 'VCTopBars',
title: '顶栏',
category: ChatCategoryEnum.TOPBARS,
categoryName: ChatCategoryEnumName.TOPBARS,
package: PackagesCategoryEnum.DECORATES,
chartFrame: ChartFrameEnum.STATIC,
image: ''
}

View File

@ -0,0 +1,40 @@
<template>
<div :style="getStyle(borderRadius)">
<n-image
:object-fit="fit"
preview-disabled
:src="`/src/assets/images/chart/decorates/${dataset}`"
:fallback-src="requireErrorImg()"
:width="w"
lazy
style="position: absolute;left: 0;width: 100%;height: 100%"
/>
</div>
</template>
<script setup lang="ts">
import { PropType, toRefs } from 'vue'
import { requireErrorImg } from '@/utils'
import { CreateComponentType } from '@/packages/index.d'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const { w, h } = toRefs(props.chartConfig.attr)
const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option)
const getStyle = (radius: number) => {
return {
borderRadius: `${radius}px`,
overflow: 'hidden'
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,27 @@
import { TopBarsConfig } from './TopBars/index'
import { PackagesCategoryEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../index.d'
const topbarNames = [
'TopBar1.png',
'TopBar2.png',
'TopBar3.png',
'TopBar4.png',
'TopBar5.png',
'TopBar6.png',
'TopBar7.png',
'TopBar8.png',
]
const topbars = topbarNames.map((name, i) => ({
...TopBarsConfig,
category: ChatCategoryEnum.TOPBARS,
categoryName: ChatCategoryEnumName.TOPBARS,
package: PackagesCategoryEnum.DECORATES,
dataset: name,
// 既是缩略图 又是背景图
image: name,
title: `顶栏${i + 1}`,
redirectComponent: `${TopBarsConfig.package}/${TopBarsConfig.category}/${TopBarsConfig.key}` // 跳转组件路径规则packageName/categoryName/componentKey
}))
export default topbars

View File

@ -2,12 +2,14 @@ export enum ChatCategoryEnum {
BORDER = 'Borders',
DECORATE = 'Decorates',
THREE = 'Three',
MORE = 'Mores'
MORE = 'Mores',
TOPBARS = 'TopBars'
}
export enum ChatCategoryEnumName {
BORDER = '边框',
DECORATE = '装饰',
THREE = '三维',
MORE = '更多'
MORE = '更多',
TOPBARS = '顶栏'
}

View File

@ -1,7 +1,8 @@
import Borders from './Borders'
import TopBars from './TopBars'
import Decorates from './Decorates'
// import Three from './Three'
import Mores from './Mores'
// export const DecorateList = [...Borders, ...Decorates, ...Three, ...Mores]
export const DecorateList = [...Borders, ...Decorates, ...Mores]
export const DecorateList = [...Borders, ...TopBars, ...Decorates, ...Mores]

View File

@ -118,6 +118,7 @@ import {
AssignmentTurnedInRound as AssignmentTurnedInRoundIcon,
CheckCircleOutlined as CheckCircleOutlinedIcon,
InsertPhotoSharp as InsertPhotoSharpIcon,
AccessTimeFilled as AccessTimeFilledIcon,
} from '@vicons/material'
const ionicons5 = {
@ -338,6 +339,8 @@ const material = {
CheckCircleOutlinedIcon,
// 背景图
InsertPhotoSharpIcon,
// 时间
AccessTimeFilledIcon,
}
// https://www.xicons.org/#/ 还有很多

View File

@ -124,6 +124,7 @@ const dblclickHandle = async (item: ConfigType) => {
let newComponent: CreateComponentType = await createComponent(item)
if (item.redirectComponent) {
item.dataset && (newComponent.option.dataset = item.dataset)
if(!newComponent.chartConfig.image && item.dataset) newComponent.chartConfig.image = item.dataset
newComponent.chartConfig.title = item.title
newComponent.chartConfig.chartFrame = item.chartFrame
}

View File

@ -55,7 +55,7 @@ import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
import { useTargetData } from '../hooks/useTargetData.hook'
import { sourceOptions, selectTimeOptions } from './index.d'
import { CurrentSourceEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
import { PackagesCategoryEnum, CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
import { PackagesCategoryEnum, CreateComponentType, CreateComponentGroupType, ChartFrameEnum } from '@/packages/index.d'
// const ChartDataStatic = loadAsyncComponent(() => import('./components/ChartDataStatic/index.vue'))
@ -70,9 +70,6 @@ const { targetData } = useTargetData() as { targetData: Ref<CreateComponentType
//
const IsStatic = () => {
let arr = [
PackagesCategoryEnum.BACKGROUNDS
]
return arr.some(_ => _ === targetData.value.chartConfig.category)
return targetData.value.chartConfig.chartFrame === ChartFrameEnum.STATIC
}
</script>

View File

@ -35,6 +35,7 @@ export const dragHandle = async (e: DragEvent) => {
let newComponent: CreateComponentType = await createComponent(dropData)
if (dropData.redirectComponent) {
dropData.dataset && (newComponent.option.dataset = dropData.dataset)
if(!newComponent.chartConfig.image && dropData.dataset) newComponent.chartConfig.image = dropData.dataset
newComponent.chartConfig.title = dropData.title
newComponent.chartConfig.chartFrame = dropData.chartFrame
}

View File

@ -7,6 +7,7 @@
preview-disabled
:src="imageInfo"
:fallback-src="requireErrorImg()"
width="58.8"
></n-image>
<n-ellipsis style="margin-right: auto">
<span class="list-text">