userName 2025-02-25 17:01:41 +08:00
commit 3df2f6d67f
41 changed files with 924 additions and 560 deletions

View File

@ -4,7 +4,7 @@ import { ErrorPageNameMap } from "@/enums/pageEnum"
import { redirectErrorPage } from '@/utils' import { redirectErrorPage } from '@/utils'
const axiosInstance = axios.create({ const axiosInstance = axios.create({
baseURL: import.meta.env.DEV ? import.meta.env.VITE_DEV_PATH : import.meta.env.VITE_PRO_PATH, baseURL: import.meta.env.VITE_GLOB_API_URL,
timeout: ResultEnum.TIMEOUT, timeout: ResultEnum.TIMEOUT,
}) })

View File

@ -3,29 +3,29 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, PropType, watch } from 'vue' import { ref, PropType, watch } from 'vue';
import { fetchImages } from '@/packages' import { fetchImages } from '@/packages';
import { ConfigType } from '@/packages/index.d' import { ConfigType } from '@/packages/index.d';
const props = defineProps({ const props = defineProps({
chartConfig: { chartConfig: {
type: Object as PropType<ConfigType>, type: Object as PropType<ConfigType>,
required: true required: true,
} },
}) });
const imageInfo = ref('') const imageInfo = ref('');
// //
const fetchImageUrl = async () => { const fetchImageUrl = async () => {
imageInfo.value = await fetchImages(props.chartConfig) imageInfo.value = await fetchImages(props.chartConfig);
} };
watch( watch(
() => props.chartConfig.key, () => props.chartConfig.key,
() => fetchImageUrl(), () => fetchImageUrl(),
{ {
immediate: true immediate: true,
} },
) );
</script> </script>

View File

@ -2,14 +2,28 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore
import { mapFun } from '@/hooks/ceshiFun.hook'; import { mapFun } from '@/hooks/ceshiFun.hook';
import { router } from '@/router'; import { router } from '@/router';
import { previewUrl } from '@/utils'; import { previewUrl } from '@/utils';
import { EventBus } from '@/utils/eventBus';
const chartEditStore = useChartEditStore(); const chartEditStore = useChartEditStore();
const ceshiFunction = mapFun(); const ceshiFunction = mapFun();
// 交互事件 // 交互事件
export const eventHandlerHook = (comonentList: any, elementList: any, params: any = null) => { export const eventHandlerHook = (
comonentList: any,
interactConfigEvents: any,
type: string,
params: any = null,
) => {
let obj: any = {}; let obj: any = {};
let index = 0; let index = 0;
const elementList: any = [];
for (let i = 0; i < interactConfigEvents.length; i++) {
if (interactConfigEvents[i].type == type) {
for (let j = 0; j < interactConfigEvents[i].movementList.length; j++) {
elementList.push(interactConfigEvents[i].movementList[j]);
}
}
}
for (let i = 0; i < comonentList.length; i++) { for (let i = 0; i < comonentList.length; i++) {
for (let j = 0; j < elementList.length; j++) { for (let j = 0; j < elementList.length; j++) {
if (elementList[j].movement == 'newaddress') { if (elementList[j].movement == 'newaddress') {
@ -77,6 +91,13 @@ export const eventHandlerHook = (comonentList: any, elementList: any, params: an
} }
} }
} }
} else if (elementList[j].movement == 'communication') {
// 组件通信
for (let k = 0; k < elementList[j].elementId.length; k++) {
if (comonentList[i].id == elementList[j].elementId[k]) {
EventBus.emit(elementList[j].elementId[k] + type, params);
}
}
} }
} }
} }

View File

@ -30,56 +30,46 @@
}); });
const { w, h } = toRefs(props.chartConfig.attr); const { w, h } = toRefs(props.chartConfig.attr);
const { dataset, color, size, rotate } = toRefs(props.chartConfig.option); const { dataset, color, size, rotate } = toRefs(props.chartConfig.option);
//
const clickElementItem = ref([]);
//
const dbclickElementItem = ref([]);
//
const rightclickElementItem = ref([]);
//
const mouseenterElementItem = ref([]);
//
const mouseleaveElementItem = ref([]);
const list = props.chartConfig.events.interactConfigEvents; const clickBtn = (val) => {
for (let i = 0; i < list.length; i++) { eventHandlerHook(
if (list[i].type == 'click') { chartEditStore.getComponentList,
for (let j = 0; j < list[i].movementList.length; j++) { props.chartConfig.events.interactConfigEvents,
clickElementItem.value.push(list[i].movementList[j]); 'click',
} val,
} else if (list[i].type == 'dblclick') { );
for (let j = 0; j < list[i].movementList.length; j++) {
dbclickElementItem.value.push(list[i].movementList[j]);
}
} else if (list[i].type == 'rightclick') {
for (let j = 0; j < list[i].movementList.length; j++) {
rightclickElementItem.value.push(list[i].movementList[j]);
}
} else if (list[i].type == 'mousein') {
for (let j = 0; j < list[i].movementList.length; j++) {
mouseenterElementItem.value.push(list[i].movementList[j]);
}
} else if (list[i].type == 'mouseout') {
for (let j = 0; j < list[i].movementList.length; j++) {
mouseleaveElementItem.value.push(list[i].movementList[j]);
}
}
}
const clickBtn = () => {
eventHandlerHook(chartEditStore.getComponentList, clickElementItem.value);
}; };
const dblclickBtn = () => { const dblclickBtn = (val) => {
eventHandlerHook(chartEditStore.getComponentList, dbclickElementItem.value); eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'dblclick',
val,
);
}; };
const rightclickBtn = (event) => { const rightclickBtn = (event) => {
event.preventDefault(); // event.preventDefault(); //
eventHandlerHook(chartEditStore.getComponentList, rightclickElementItem.value); eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'rightclick',
);
}; };
const mouseenterBtn = () => { const mouseenterBtn = (val) => {
eventHandlerHook(chartEditStore.getComponentList, mouseenterElementItem.value); eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'mousein',
val,
);
}; };
const mouseleaveBtn = () => { const mouseleaveBtn = (val) => {
eventHandlerHook(chartEditStore.getComponentList, mouseleaveElementItem.value); eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'mouseout',
val,
);
}; };
</script> </script>

View File

@ -17,12 +17,6 @@ export const option = {
largeColor1: '#007343', largeColor1: '#007343',
largeColor2: '#89E5A1', largeColor2: '#89E5A1',
}, },
dataStyleClone:{
smallColor1: '#00D586',
smallColor2: '#00AB4E',
largeColor1: '#007343',
largeColor2: '#89E5A1',
}
} }
export default class Config extends PublicConfigClass implements CreateComponentType { export default class Config extends PublicConfigClass implements CreateComponentType {

View File

@ -50,7 +50,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.smallColor1 = optionData.dataStyleClone.smallColor1" @click="optionData.dataStyle.smallColor1 = dataStyleClone.smallColor1"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -65,7 +65,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.smallColor2 = optionData.dataStyleClone.smallColor2" @click="optionData.dataStyle.smallColor2 = dataStyleClone.smallColor2"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -80,7 +80,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.largeColor1 = optionData.dataStyleClone.largeColor1" @click="optionData.dataStyle.largeColor1 = dataStyleClone.largeColor1"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -95,7 +95,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.largeColor2 = optionData.dataStyleClone.largeColor2" @click="optionData.dataStyle.largeColor2 = dataStyleClone.largeColor2"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -116,4 +116,11 @@
required: true, required: true,
}, },
}); });
const dataStyleClone = {
smallColor1: '#00D586',
smallColor2: '#00AB4E',
largeColor1: '#007343',
largeColor2: '#89E5A1',
};
</script> </script>

View File

@ -11,32 +11,6 @@ export const option = {
'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel2.jpeg', 'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel2.jpeg',
'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel3.jpeg', 'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel3.jpeg',
], ],
buttonStyle:{
dotBottom: 5,
dotLeft: 37,
dotColor1: '#00611a',
dotColor2: '#00cc13',
buttonWidth: 20,
buttonHeight: 60,
buttonBottom: 37,
buttonLeftAndRight: 0,
buttonColor: '#A4A4A4FF',
iconFontSize: 20,
iconColor: '#1EC233',
borderWidth: 2,
borderColor: '#008000',
},
buttonStyleClone:{
dotColor1: '#00611a',
dotColor2: '#00cc13',
buttonColor: '#A4A4A4FF',
iconColor: '#1EC233',
borderColor: '#008000',
},
dataStyle: { dataStyle: {
// 自动播放 // 自动播放
autoplay: true, autoplay: true,
@ -60,6 +34,24 @@ export const option = {
showArrow: true, showArrow: true,
// 图片样式 // 图片样式
fit: "contain", fit: "contain",
dotBottom: 5,
dotLeft: 37,
dotColor1: '#00611a',
dotColor2: '#00cc13',
buttonWidth: 20,
buttonHeight: 60,
buttonBottom: 37,
buttonLeftAndRight: 0,
buttonColor: '#A4A4A4FF',
iconFontSize: 20,
iconColor: '#1EC233',
borderWidth: 2,
borderColor: '#008000',
} }
} }

View File

@ -89,12 +89,12 @@
<SettingItem-box name="控制点样式" v-if="optionData.dataStyle.showDots"> <SettingItem-box name="控制点样式" v-if="optionData.dataStyle.showDots">
<SettingItem name="控制点位置(下)"> <SettingItem name="控制点位置(下)">
<n-input-number v-model:value="optionData.buttonStyle.dotBottom" size="small"> <n-input-number v-model:value="optionData.dataStyle.dotBottom" size="small">
<template #suffix> % </template> <template #suffix> % </template>
</n-input-number> </n-input-number>
</SettingItem> </SettingItem>
<SettingItem name="控制点位置(左)"> <SettingItem name="控制点位置(左)">
<n-input-number v-model:value="optionData.buttonStyle.dotLeft" size="small" :min="0"> <n-input-number v-model:value="optionData.dataStyle.dotLeft" size="small" :min="0">
<template #suffix> % </template> <template #suffix> % </template>
</n-input-number> </n-input-number>
</SettingItem> </SettingItem>
@ -102,14 +102,11 @@
<n-color-picker <n-color-picker
size="small" size="small"
:modes="['hex']" :modes="['hex']"
v-model:value="optionData.buttonStyle.dotColor1" v-model:value="optionData.dataStyle.dotColor1"
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.dotColor1 = dataStyleClone.dotColor1">
size="small"
@click="optionData.buttonStyle.dotColor1 = optionData.buttonStyleClone.dotColor1"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -117,14 +114,11 @@
<n-color-picker <n-color-picker
size="small" size="small"
:modes="['hex']" :modes="['hex']"
v-model:value="optionData.buttonStyle.dotColor2" v-model:value="optionData.dataStyle.dotColor2"
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.dotColor2 = dataStyleClone.dotColor2">
size="small"
@click="optionData.buttonStyle.dotColor2 = optionData.buttonStyleClone.dotColor2"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -132,26 +126,26 @@
<SettingItem-box name="箭头样式" v-if="optionData.dataStyle.showArrow"> <SettingItem-box name="箭头样式" v-if="optionData.dataStyle.showArrow">
<SettingItem name="箭头按钮宽度"> <SettingItem name="箭头按钮宽度">
<n-input-number <n-input-number
v-model:value="optionData.buttonStyle.buttonWidth" v-model:value="optionData.dataStyle.buttonWidth"
size="small" size="small"
:min="0" :min="0"
></n-input-number> ></n-input-number>
</SettingItem> </SettingItem>
<SettingItem name="箭头按钮长度"> <SettingItem name="箭头按钮长度">
<n-input-number <n-input-number
v-model:value="optionData.buttonStyle.buttonHeight" v-model:value="optionData.dataStyle.buttonHeight"
size="small" size="small"
:min="0" :min="0"
></n-input-number> ></n-input-number>
</SettingItem> </SettingItem>
<SettingItem name="箭头位置(下)"> <SettingItem name="箭头位置(下)">
<n-input-number v-model:value="optionData.buttonStyle.buttonBottom" size="small" :min="0"> <n-input-number v-model:value="optionData.dataStyle.buttonBottom" size="small" :min="0">
<template #suffix> % </template> <template #suffix> % </template>
</n-input-number> </n-input-number>
</SettingItem> </SettingItem>
<SettingItem name="箭头位置(边界)"> <SettingItem name="箭头位置(边界)">
<n-input-number <n-input-number
v-model:value="optionData.buttonStyle.buttonLeftAndRight" v-model:value="optionData.dataStyle.buttonLeftAndRight"
size="small" size="small"
:min="0" :min="0"
> >
@ -162,13 +156,13 @@
<n-color-picker <n-color-picker
size="small" size="small"
:modes="['hex']" :modes="['hex']"
v-model:value="optionData.buttonStyle.buttonColor" v-model:value="optionData.dataStyle.buttonColor"
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.buttonStyle.buttonColor = optionData.buttonStyleClone.buttonColor" @click="optionData.dataStyle.buttonColor = dataStyleClone.buttonColor"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -177,20 +171,17 @@
<n-color-picker <n-color-picker
size="small" size="small"
:modes="['hex']" :modes="['hex']"
v-model:value="optionData.buttonStyle.iconColor" v-model:value="optionData.dataStyle.iconColor"
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.iconColor = dataStyleClone.iconColor">
size="small"
@click="optionData.buttonStyle.iconColor = optionData.buttonStyleClone.iconColor"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
<SettingItem name="箭头图标大小"> <SettingItem name="箭头图标大小">
<n-input-number <n-input-number
v-model:value="optionData.buttonStyle.iconFontSize" v-model:value="optionData.dataStyle.iconFontSize"
size="small" size="small"
:min="0" :min="0"
></n-input-number> ></n-input-number>
@ -202,20 +193,20 @@
<n-color-picker <n-color-picker
size="small" size="small"
:modes="['hex']" :modes="['hex']"
v-model:value="optionData.buttonStyle.borderColor" v-model:value="optionData.dataStyle.borderColor"
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.buttonStyle.borderColor = optionData.buttonStyleClone.borderColor" @click="optionData.dataStyle.borderColor = dataStyleClone.borderColor"
> >
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
<SettingItem name="边框宽度"> <SettingItem name="边框宽度">
<n-input-number <n-input-number
v-model:value="optionData.buttonStyle.borderWidth" v-model:value="optionData.dataStyle.borderWidth"
size="small" size="small"
:min="0" :min="0"
></n-input-number> ></n-input-number>
@ -237,6 +228,14 @@
}, },
}); });
const dataStyleClone = {
dotColor1: '#00611a',
dotColor2: '#00cc13',
buttonColor: '#A4A4A4FF',
iconColor: '#1EC233',
borderColor: '#008000',
};
// //
const dotTypes = [ const dotTypes = [
{ {

View File

@ -27,20 +27,20 @@
<div class="arrow-left"> <div class="arrow-left">
<n-button <n-button
type="text" type="text"
:color="option.buttonStyle.buttonColor" :color="option.dataStyle.buttonColor"
:style="{ :style="{
display: flex, display: flex,
alignItems: center, alignItems: center,
justifyContent: center, justifyContent: center,
width: option.buttonStyle.buttonWidth + 'px', width: option.dataStyle.buttonWidth + 'px',
height: option.buttonStyle.buttonHeight + 'px', height: option.dataStyle.buttonHeight + 'px',
}" }"
@click="prev" @click="prev"
> >
<LeftOutlined <LeftOutlined
:style="{ :style="{
color: option.buttonStyle.iconColor, color: option.dataStyle.iconColor,
fontSize: option.buttonStyle.iconFontSize + 'px', fontSize: option.dataStyle.iconFontSize + 'px',
}" }"
/> />
</n-button> </n-button>
@ -48,20 +48,20 @@
<div class="arrow-right"> <div class="arrow-right">
<n-button <n-button
type="text" type="text"
:color="option.buttonStyle.buttonColor" :color="option.dataStyle.buttonColor"
:style="{ :style="{
display: flex, display: flex,
alignItems: center, alignItems: center,
justifyContent: center, justifyContent: center,
width: option.buttonStyle.buttonWidth + 'px', width: option.dataStyle.buttonWidth + 'px',
height: option.buttonStyle.buttonHeight + 'px', height: option.dataStyle.buttonHeight + 'px',
}" }"
@click="next" @click="next"
> >
<RightOutlined <RightOutlined
:style="{ :style="{
color: option.buttonStyle.iconColor, color: option.dataStyle.iconColor,
fontSize: option.buttonStyle.iconFontSize + 'px', fontSize: option.dataStyle.iconFontSize + 'px',
}" }"
/> />
</n-button> </n-button>
@ -103,15 +103,14 @@
const option = reactive({ const option = reactive({
dataset: props.chartConfig.option.dataset, dataset: props.chartConfig.option.dataset,
dataStyle: props.chartConfig.option.dataStyle, dataStyle: props.chartConfig.option.dataStyle,
buttonStyle: props.chartConfig.option.buttonStyle,
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.ModalCarousel { .ModalCarousel {
// overflow-y: auto; // overflow-y: auto;
border: v-bind('`${option.buttonStyle.borderWidth}px`') solid border: v-bind('`${option.dataStyle.borderWidth}px`') solid
v-bind('`${option.buttonStyle.borderColor}`'); v-bind('`${option.dataStyle.borderColor}`');
padding: 2px; padding: 2px;
width: v-bind('`${w}px`'); width: v-bind('`${w}px`');
height: v-bind('`${h}px`'); height: v-bind('`${h}px`');
@ -127,14 +126,14 @@
.arrow-left { .arrow-left {
display: flex; display: flex;
position: absolute; position: absolute;
bottom: v-bind('`${option.buttonStyle.buttonBottom}%`'); bottom: v-bind('`${option.dataStyle.buttonBottom}%`');
left: v-bind('`${option.buttonStyle.buttonLeftAndRight}%`'); left: v-bind('`${option.dataStyle.buttonLeftAndRight}%`');
} }
.arrow-right { .arrow-right {
display: flex; display: flex;
position: absolute; position: absolute;
bottom: v-bind('`${option.buttonStyle.buttonBottom}%`'); bottom: v-bind('`${option.dataStyle.buttonBottom}%`');
right: v-bind('`${option.buttonStyle.buttonLeftAndRight}%`'); right: v-bind('`${option.dataStyle.buttonLeftAndRight}%`');
} }
.dots { .dots {
@ -142,8 +141,8 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
position: absolute; position: absolute;
bottom: v-bind('`${option.buttonStyle.dotBottom}%`'); bottom: v-bind('`${option.dataStyle.dotBottom}%`');
left: v-bind('`${option.buttonStyle.dotLeft}%`'); left: v-bind('`${option.dataStyle.dotLeft}%`');
} }
.dots li { .dots li {
@ -152,7 +151,7 @@
height: 4px; height: 4px;
margin: 0 3px; margin: 0 3px;
border-radius: 4px; border-radius: 4px;
background-color: v-bind('`${option.buttonStyle.dotColor1}`'); background-color: v-bind('`${option.dataStyle.dotColor1}`');
transition: transition:
width 0.3s, width 0.3s,
background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1); background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1);
@ -161,7 +160,7 @@
.dots li.is-active { .dots li.is-active {
width: 40px; width: 40px;
background: v-bind('`${option.buttonStyle.dotColor2}`'); background: v-bind('`${option.dataStyle.dotColor2}`');
} }
::v-deep .n-button { ::v-deep .n-button {

View File

@ -30,25 +30,6 @@ export const option = {
// 底部矩形块颜色 // 底部矩形块颜色
bottomUseColor: '#FFE4AC', bottomUseColor: '#FFE4AC',
}, },
dataStyleClone:{
maskColor:'#000000FF',
// 背景颜色
backgroud: '#161A1A',
// 左上、右下角装饰颜色
lineColor1: '#25673D',
lineColor2: '#3E674A',
lineColor3: '#8BE8A3',
// 外侧边框线颜色
pathLineColor1: '#7CA791',
// 内侧边框线颜色
pathLineColor2: '#435A4E',
// 顶部矩形块颜色
topPolygonColor: '#4D815D',
// 顶部椭圆形块颜色
topEllipseColor: '#4A5C4A',
// 底部矩形块颜色
bottomUseColor: '#FFE4AC',
}
} }
export default class Config extends PublicConfigClass implements CreateComponentType { export default class Config extends PublicConfigClass implements CreateComponentType {

View File

@ -63,10 +63,7 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.backgroud = dataStyleClone.backgroud">
size="small"
@click="optionData.dataStyle.backgroud = optionData.dataStyleClone.backgroud"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -78,10 +75,7 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.lineColor1 = dataStyleClone.lineColor1">
size="small"
@click="optionData.dataStyle.lineColor1 = optionData.dataStyleClone.lineColor1"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -93,10 +87,7 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.lineColor2 = dataStyleClone.lineColor2">
size="small"
@click="optionData.dataStyle.lineColor2 = optionData.dataStyleClone.lineColor2"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -108,10 +99,7 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.lineColor3 = dataStyleClone.lineColor3">
size="small"
@click="optionData.dataStyle.lineColor3 = optionData.dataStyleClone.lineColor3"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -125,7 +113,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.pathLineColor1 = optionData.dataStyleClone.pathLineColor1" @click="optionData.dataStyle.pathLineColor1 = dataStyleClone.pathLineColor1"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -140,7 +128,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.pathLineColor2 = optionData.dataStyleClone.pathLineColor2" @click="optionData.dataStyle.pathLineColor2 = dataStyleClone.pathLineColor2"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -155,7 +143,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.topPolygonColor = optionData.dataStyleClone.topPolygonColor" @click="optionData.dataStyle.topPolygonColor = dataStyleClone.topPolygonColor"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -170,7 +158,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.topEllipseColor = optionData.dataStyleClone.topEllipseColor" @click="optionData.dataStyle.topEllipseColor = dataStyleClone.topEllipseColor"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -185,7 +173,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.bottomUseColor = optionData.dataStyleClone.bottomUseColor" @click="optionData.dataStyle.bottomUseColor = dataStyleClone.bottomUseColor"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -206,4 +194,24 @@
required: true, required: true,
}, },
}); });
const dataStyleClone = {
maskColor: '#000000FF',
//
backgroud: '#161A1A',
//
lineColor1: '#25673D',
lineColor2: '#3E674A',
lineColor3: '#8BE8A3',
// 线
pathLineColor1: '#7CA791',
// 线
pathLineColor2: '#435A4E',
//
topPolygonColor: '#4D815D',
//
topEllipseColor: '#4A5C4A',
//
bottomUseColor: '#FFE4AC',
};
</script> </script>

View File

@ -9,10 +9,6 @@ export const option = {
color: '#005516', color: '#005516',
fontColor: '#FFFFFF' fontColor: '#FFFFFF'
}, },
dataStyleClone: {
color: '#005516',
fontColor: '#FFFFFF'
},
} }
export default class Config extends PublicConfigClass implements CreateComponentType { export default class Config extends PublicConfigClass implements CreateComponentType {

View File

@ -9,7 +9,7 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button size="small" @click="optionData.dataStyle.color = option.dataStyleClone.color"> <n-button size="small" @click="optionData.dataStyle.color = dataStyleClone.color">
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -21,10 +21,7 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.fontColor = dataStyleClone.fontColor">
size="small"
@click="optionData.dataStyle.fontColor = option.dataStyleClone.fontColor"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -44,4 +41,9 @@
required: true, required: true,
}, },
}); });
const dataStyleClone = {
color: '#005516',
fontColor: '#FFFFFF',
};
</script> </script>

View File

@ -16,11 +16,6 @@ export const option = {
startColor: '#1F6B55', startColor: '#1F6B55',
endColor: '#0A392A', endColor: '#0A392A',
}, },
dataStyleClone: {
leftColor: '#00611A',
startColor: '#1F6B55',
endColor: '#0A392A',
},
} }
export default class Config extends PublicConfigClass implements CreateComponentType { export default class Config extends PublicConfigClass implements CreateComponentType {

View File

@ -45,10 +45,7 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.leftColor = dataStyleClone.leftColor">
size="small"
@click="optionData.dataStyle.leftColor = option.dataStyleClone.leftColor"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -60,10 +57,7 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.startColor = dataStyleClone.startColor">
size="small"
@click="optionData.dataStyle.startColor = option.dataStyleClone.startColor"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -75,10 +69,7 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.endColor = dataStyleClone.endColor">
size="small"
@click="optionData.dataStyle.endColor = option.dataStyleClone.endColor"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -98,4 +89,10 @@
required: true, required: true,
}, },
}); });
const dataStyleClone = {
leftColor: '#00611A',
startColor: '#1F6B55',
endColor: '#0A392A',
};
</script> </script>

View File

@ -32,15 +32,19 @@ export const option = {
timeFontSize: 16, timeFontSize: 16,
contentColor: '#06936A', contentColor: '#06936A',
contentFontSize: 16, contentFontSize: 16,
showLine: true,
// 图片-适应方式 // 图片-适应方式
imageFit: 'contain', imageFit: 'contain',
imageBorderRadius: 10, imageBorderRadius: 0,
imageWidth: 150, imageWidth: 150,
imageHeight: 150, imageHeight: 150,
imageMarginTop: 10, imageMarginTop: 10,
imageAlign: 'left', imageAlign: 'left',
imageBorderWidth: 2,
imageBorderColor: '#008000',
imagePadding: 4,
// 视频-循环播放 // 视频-循环播放
videoLoop: true, videoLoop: false,
// 视频-静音 // 视频-静音
videoMuted: true, videoMuted: true,
// 视频-适应方式 // 视频-适应方式
@ -49,12 +53,10 @@ export const option = {
videoHeight: 150, videoHeight: 150,
videoMarginTop: 10, videoMarginTop: 10,
videoAlign: 'left', videoAlign: 'left',
videoBorderWidth: 2,
videoBorderColor: '#008000',
videoPadding: 4,
}, },
dataStyleClone: {
borderColor: '#0C2411',
bordercolor: '#0C2411',
lineColor: '#103A26',
}
} }
export default class Config extends PublicConfigClass implements CreateComponentType { export default class Config extends PublicConfigClass implements CreateComponentType {

View File

@ -9,10 +9,7 @@
/> />
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.background = dataStyleClone.background">
size="small"
@click="optionData.dataStyle.background = optionData.dataStyleClone.background"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -26,7 +23,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.borderColor = optionData.dataStyleClone.borderColor" @click="optionData.dataStyle.borderColor = dataStyleClone.borderColor"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -39,10 +36,7 @@
/> />
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.lineColor = dataStyleClone.lineColor">
size="small"
@click="optionData.dataStyle.lineColor = optionData.dataStyleClone.lineColor"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -80,7 +74,13 @@
size="small" size="small"
/> />
</SettingItem> </SettingItem>
<SettingItem name="是否显示时间和文本之间的虚线">
<n-space>
<n-switch v-model:value="optionData.dataStyle.showLine" size="small"></n-switch>
</n-space>
</SettingItem>
</SettingItemBox> </SettingItemBox>
<SettingItemBox name="最新内容设置"> <SettingItemBox name="最新内容设置">
<SettingItem name="标题字体颜色"> <SettingItem name="标题字体颜色">
<n-color-picker <n-color-picker
@ -217,7 +217,30 @@
:options="textAlignOptions" :options="textAlignOptions"
/> />
</SettingItem> </SettingItem>
<SettingItem name="边框颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.dataStyle.imageBorderColor"
></n-color-picker>
</SettingItem>
<SettingItem name="边框宽度">
<n-input-number
v-model:value="optionData.dataStyle.imageBorderWidth"
size="small"
:min="0"
></n-input-number>
</SettingItem>
<SettingItem name="边框距离">
<n-input-number
v-model:value="optionData.dataStyle.imagePadding"
size="small"
:min="0"
></n-input-number>
</SettingItem>
</SettingItemBox> </SettingItemBox>
<n-tag type="primary">编辑页面修改视频数据配置后请在预览页面查看效果</n-tag>
<SettingItemBox name="视频设置"> <SettingItemBox name="视频设置">
<SettingItem> <SettingItem>
<n-checkbox v-model:checked="optionData.dataStyle.videoLoop" size="small"> <n-checkbox v-model:checked="optionData.dataStyle.videoLoop" size="small">
@ -263,6 +286,27 @@
:options="textAlignOptions" :options="textAlignOptions"
/> />
</SettingItem> </SettingItem>
<SettingItem name="边框颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.dataStyle.videoBorderColor"
></n-color-picker>
</SettingItem>
<SettingItem name="边框宽度">
<n-input-number
v-model:value="optionData.dataStyle.videoBorderWidth"
size="small"
:min="0"
></n-input-number>
</SettingItem>
<SettingItem name="边框距离">
<n-input-number
v-model:value="optionData.dataStyle.videoPadding"
size="small"
:min="0"
></n-input-number>
</SettingItem>
</SettingItemBox> </SettingItemBox>
</CollapseItem> </CollapseItem>
</template> </template>
@ -280,6 +324,13 @@
}, },
}); });
const dataStyleClone = {
background: '#0C2411',
borderColor: '#0C2411',
lineColor: '#103A26',
videoBorderColor: '#008000',
};
// //
const fitList = [ const fitList = [
{ {

View File

@ -5,32 +5,32 @@
"type": "success", "type": "success",
"content": "临沂市山东省辖地级市位于山东省东南部地跨北纬34°2236°13东经117°24119°11之间属温带季风气候四季分明雨热同季地势自北而南有沂山、蒙山、尼山3条主要山脉延伸控制着沂沭河上游及其支流的流向向南构成的扇状临郯苍平原是山东三平原之一。", "content": "临沂市山东省辖地级市位于山东省东南部地跨北纬34°2236°13东经117°24119°11之间属温带季风气候四季分明雨热同季地势自北而南有沂山、蒙山、尼山3条主要山脉延伸控制着沂沭河上游及其支流的流向向南构成的扇状临郯苍平原是山东三平原之一。",
"time": "2025-02-11 01:27:14", "time": "2025-02-11 01:27:14",
"imageurl": "/src/assets/logo.png", "imageUrl": "/src/assets/logo.png",
"videourl": "/src/assets/videos/earth.mp4" "videoUrl": "http://221.2.83.254:7012/live/37130100181328000001.m3u8"
}, },
{ {
"title":"临沂市", "title":"临沂市",
"type": "success", "type": "success",
"content": "", "content": "",
"time": "2025-02-11 01:27:14" "time": "2025-02-11 01:27:15"
}, },
{ {
"title":"临沂市", "title":"临沂市",
"type": "success", "type": "success",
"content": "7142", "content": "7142",
"time": "2025-02-11 01:27:14" "time": "2025-02-11 01:27:16"
}, },
{ {
"title":"临沂市", "title":"临沂市",
"type": "success", "type": "success",
"content": "7142", "content": "7142",
"time": "2025-02-11 01:27:14" "time": "2025-02-11 01:27:17"
}, },
{ {
"title":"临沂市", "title":"临沂市",
"type": "success", "type": "success",
"content": "7142", "content": "7142",
"time": "2025-02-11 01:27:14" "time": "2025-02-11 01:27:18"
} }
] ]
} }

View File

@ -49,7 +49,7 @@
> >
{{ item.time }} {{ item.time }}
</div> </div>
------------------------------- <span v-if="option.dataStyle.showLine">-------------------------------</span>
<!-- 文本 --> <!-- 文本 -->
<div <div
v-if="index == 0" v-if="index == 0"
@ -69,8 +69,9 @@
> >
{{ item.content }} {{ item.content }}
</div> </div>
<!-- 图片 -->
<div <div
v-if="item.imageurl" v-if="item.imageUrl"
:style="{ :style="{
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
@ -82,32 +83,46 @@
> >
<n-image <n-image
preview-disabled preview-disabled
:src="item.imageurl" :src="item.imageUrl"
:style="{
border: `${option.dataStyle.imageBorderWidth}px solid ${option.dataStyle.imageBorderColor}`,
padding: `${option.dataStyle.imagePadding}px`,
}"
:object-fit="option.dataset.imageFit" :object-fit="option.dataset.imageFit"
:width="`${option.dataStyle.imageWidth}`" :width="`${option.dataStyle.imageWidth}`"
:height="`${option.dataStyle.imageHeight}`" :height="`${option.dataStyle.imageHeight}`"
lazy lazy
/> />
</div> </div>
<div <!-- 视频 -->
v-if="item.videourl" <div v-if="item.videoUrl" class="timeLineVideoDiv">
:style="{ <!-- 编辑状态 -->
display: 'flex',
alignItems: 'center',
justifyContent: `${option.dataStyle.videoAlign}`,
marginTop: `${option.dataStyle.videoMarginTop}px`,
}"
>
<video <video
v-if="isEdit"
class="TCPlayer-video-contaiiner"
preload="auto" preload="auto"
crossOrigin="anonymous" crossOrigin="anonymous"
playsinline playsinline
autoplay autoplay
:loop="option.dataStyle.videoLoop" :loop="option.dataStyle.videoLoop"
:muted="option.dataStyle.videoMuted" :muted="option.dataStyle.videoMuted"
:width="`${option.dataStyle.videoWidth}`" :width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
:height="`${option.dataStyle.videoHeight}`" :height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
:src="item.videourl" src="/src/assets/videos/earth.mp4"
></video>
<!-- 其他情况 -->
<video
v-else
:id="item.title + item.index"
class="TCPlayer-video-contaiiner"
preload="auto"
crossOrigin="anonymous"
playsinline
autoplay
:loop="option.dataStyle.videoLoop"
:muted="option.dataStyle.videoMuted"
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
></video> ></video>
</div> </div>
</template> </template>
@ -117,7 +132,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, PropType, toRefs, watch, reactive, ref } from 'vue'; import { PropType, toRefs, watch, reactive, ref, onMounted, onBeforeUnmount } from 'vue';
import { CreateComponentType } from '@/packages/index.d'; import { CreateComponentType } from '@/packages/index.d';
import { icon } from '@/plugins'; import { icon } from '@/plugins';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'; import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
@ -137,6 +152,47 @@
dataset: props.chartConfig.option.dataset, dataset: props.chartConfig.option.dataset,
dataStyle: props.chartConfig.option.dataStyle, dataStyle: props.chartConfig.option.dataStyle,
}); });
//
const isEdit = window.location.href.includes('/chart/home/');
//
let players: any = [];
function handlerPlayVideo() {
option.dataset.forEach((element, index) => {
if (players[index]) {
players[index].src(element.videoUrl);
} else {
players[index] = TCPlayer(element.title + element.index, {});
players[index].src(element.videoUrl);
}
});
}
//
onMounted(() => {
option.dataset.forEach((element) => {
let player: any = null;
players.push(player);
});
if (!window.location.href.includes('/chart/home/')) {
setTimeout(function () {
handlerPlayVideo();
}, 1000);
}
});
//
onBeforeUnmount(() => {
if (players) {
players.forEach((player) => {
if (player) {
player.dispose();
player = null;
}
});
}
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -160,6 +216,18 @@
-ms-overflow-style: none; -ms-overflow-style: none;
} }
.timeLineVideoDiv {
display: flex;
align-items: center;
justify-content: v-bind('option.dataStyle.videoAlign');
width: v-bind('`${option.dataStyle.videoWidth}px`');
height: v-bind('`${option.dataStyle.videoHeight}px`');
margin-top: v-bind('`${option.dataStyle.videoMarginTop}px`');
border: v-bind('`${option.dataStyle.videoBorderWidth}px`') solid
v-bind('`${option.dataStyle.videoBorderColor}`');
padding: v-bind('`${option.dataStyle.videoPadding}px`');
}
video { video {
display: block; display: block;
object-fit: v-bind('option.dataStyle.videoFit'); object-fit: v-bind('option.dataStyle.videoFit');

View File

@ -5,10 +5,10 @@ import { chartInitConfig } from '@/settings/designSetting'
import { ModalVideoConfig } from './index' import { ModalVideoConfig } from './index'
export const option = { export const option = {
dataset: '/src/assets/videos/earth.mp4', dataset: 'http://221.2.83.254:7012/live/37130100181328000001.m3u8',
dataStyle: { dataStyle: {
backgroud: '#FFFFFF00', backgroud: '#FFFFFF00',
videoLoop: true, // 视频-循环播放 videoLoop: false, // 视频-循环播放
videoMuted: true, // 视频-静音 videoMuted: true, // 视频-静音
videoFit: 'fill', // 视频-适应方式 videoFit: 'fill', // 视频-适应方式
// videoWidth: 10, // videoWidth: 10,

View File

@ -1,13 +1,8 @@
<template> <template>
<CollapseItem name="数据设置" :expanded="true"> <CollapseItem name="数据设置" :expanded="true">
<SettingItemBox name="主题设置"> <n-tag type="primary">编辑页面修改视频数据配置后请在预览页面查看效果</n-tag>
<SettingItem name="背景颜色"> <SettingItemBox name="默认路径" :alone="true">
<n-color-picker <n-input v-model:value="optionData.dataset" size="small"></n-input>
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.backgroud"
></n-color-picker>
</SettingItem>
</SettingItemBox> </SettingItemBox>
<SettingItemBox name="视频设置"> <SettingItemBox name="视频设置">
@ -26,7 +21,7 @@
</SettingItem> </SettingItem>
</SettingItemBox> </SettingItemBox>
<SettingItemBox name="边框设置"> <SettingItemBox name="样式设置">
<SettingItem name="边框颜色"> <SettingItem name="边框颜色">
<n-color-picker <n-color-picker
size="small" size="small"
@ -56,6 +51,13 @@
:min="0" :min="0"
></n-input-number> ></n-input-number>
</SettingItem> </SettingItem>
<SettingItem name="背景颜色">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.backgroud"
></n-color-picker>
</SettingItem>
</SettingItemBox> </SettingItemBox>
</CollapseItem> </CollapseItem>
</template> </template>

View File

@ -1,6 +1,9 @@
<template> <template>
<div class="WuRenJiShiShiHuaMian"> <div class="ModalVideo">
<!-- 编辑状态 -->
<video <video
v-if="isEdit"
class="TCPlayer-video-contaiiner"
preload="auto" preload="auto"
crossOrigin="anonymous" crossOrigin="anonymous"
playsinline playsinline
@ -8,15 +11,30 @@
:object-fit="option.dataset.fit" :object-fit="option.dataset.fit"
:loop="option.dataStyle.videoLoop" :loop="option.dataStyle.videoLoop"
:muted="option.dataStyle.videoMuted" :muted="option.dataStyle.videoMuted"
:width="`${w - option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`" :width="`${w - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
:height="`${h - option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`" :height="`${h - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
:src="option.dataset" src="/src/assets/videos/earth.mp4"
/>
<!-- 其他情况 -->
<video
v-else
id="TCPlaeyrContainer"
class="TCPlayer-video-contaiiner"
preload="auto"
crossOrigin="anonymous"
playsinline
autoplay
:object-fit="option.dataset.fit"
:loop="option.dataStyle.videoLoop"
:muted="option.dataStyle.videoMuted"
:width="`${w - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
:height="`${h - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
/> />
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, PropType, toRefs, watch, reactive, ref } from 'vue'; import { PropType, toRefs, reactive, ref, onMounted, onBeforeUnmount } from 'vue';
import { CreateComponentType } from '@/packages/index.d'; import { CreateComponentType } from '@/packages/index.d';
import { icon } from '@/plugins'; import { icon } from '@/plugins';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'; import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
@ -36,28 +54,57 @@
dataset: props.chartConfig.option.dataset, dataset: props.chartConfig.option.dataset,
dataStyle: props.chartConfig.option.dataStyle, dataStyle: props.chartConfig.option.dataStyle,
}); });
//
const isEdit = window.location.href.includes('/chart/home/');
//
let player: any = null;
function handlerPlayVideo() {
if (player) {
player.src(option.dataset);
} else {
player = TCPlayer('TCPlaeyrContainer', {});
player.src(option.dataset);
}
}
//
onMounted(() => {
if (!window.location.href.includes('/chart/home/')) {
setTimeout(function () {
handlerPlayVideo();
}, 1000);
}
});
//
onBeforeUnmount(() => {
if (player) {
player.dispose();
player = null;
}
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.WuRenJiShiShiHuaMian { .ModalVideo {
overflow-y: auto; overflow-y: auto;
border: v-bind('`${option.dataStyle.borderWidth}px`') solid border: v-bind('`${option.dataStyle.borderWidth}px`') solid
v-bind('`${option.dataStyle.borderColor}`'); v-bind('`${option.dataStyle.borderColor}`');
background: v-bind('`${option.dataStyle.backgroud}`'); background: v-bind('`${option.dataStyle.backgroud}`');
padding: v-bind('`${option.dataStyle.padding}px`');
width: v-bind('`${w}px`'); width: v-bind('`${w}px`');
height: v-bind('`${h}px`'); height: v-bind('`${h}px`');
} }
.WuRenJiShiShiHuaMian::-webkit-scrollbar { .ModalVideo::-webkit-scrollbar {
display: none; display: none;
} }
.WuRenJiShiShiHuaMian { .ModalVideo {
scrollbar-width: none; scrollbar-width: none;
-ms-overflow-style: none; -ms-overflow-style: none;
} }
video { video {
display: block; display: block;
object-fit: v-bind('option.dataStyle.videoFit'); object-fit: v-bind('option.dataStyle.videoFit');
padding-top: v-bind('`${option.dataStyle.padding}px`');
padding-left: v-bind('`${option.dataStyle.padding}px`');
} }
</style> </style>

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="WeiXingYaoGan"> <div class="WeiXingYaoGan">
<div class="list"> <div class="list">
<div v-for="item in option.dataset" :key="item.key"> <div v-for="item in option.dataset" :key="item.key" @click="clickBtn(item)">
<Xinxi <Xinxi
:style="{ marginBottom: `${option.dataStyle.listMarginbottom}px` }" :style="{ marginBottom: `${option.dataStyle.listMarginbottom}px` }"
:item="item" :item="item"
@ -19,6 +19,9 @@
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'; import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { useChartDataFetch } from '@/hooks'; import { useChartDataFetch } from '@/hooks';
import Xinxi from './svg/xinxi.vue'; import Xinxi from './svg/xinxi.vue';
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
const chartEditStore = useChartEditStore();
const props = defineProps({ const props = defineProps({
chartConfig: { chartConfig: {
@ -55,6 +58,14 @@
deep: true, deep: true,
}, },
); );
const clickBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'click',
val,
);
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -40,23 +40,6 @@ export const option = {
bottomComponentColor1: '#6FEF94', bottomComponentColor1: '#6FEF94',
bottomComponentColor2: '#A8F8C6', bottomComponentColor2: '#A8F8C6',
}, },
dataStyleClone: {
iconColor1: '#B8FDB4',
iconColor2: '#60EC8D',
rectStrokeColor: '#00611A',
rectFillColor: '#0A251E',
gFillColor: '#4FE985',
bottomFontColor1: '#A4F9AB',
bottomFontColor2: '#FFFFFF',
lineColor: '#A4F9AB',
bottomFontColor3: '#FFFFFF',
bottomComponentColor1: '#337D4E',
bottomComponentColor2: '#2D593B',
bottomLineColor1: '#6FEF94',
bottomLineColor2: '#A8F8C6',
}
} }
export default class Config extends PublicConfigClass implements CreateComponentType { export default class Config extends PublicConfigClass implements CreateComponentType {

View File

@ -54,10 +54,7 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.iconColor1 = dataStyleClone.iconColor1">
size="small"
@click="optionData.dataStyle.iconColor1 = optionData.dataStyleClone.iconColor1"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -69,10 +66,7 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.iconColor2 = dataStyleClone.iconColor2">
size="small"
@click="optionData.dataStyle.iconColor2 = optionData.dataStyleClone.iconColor2"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -134,9 +128,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click=" @click="optionData.dataStyle.bottomFontColor1 = dataStyleClone.bottomFontColor1"
optionData.dataStyle.bottomFontColor1 = optionData.dataStyleClone.bottomFontColor1
"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -151,9 +143,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click=" @click="optionData.dataStyle.bottomFontColor2 = dataStyleClone.bottomFontColor2"
optionData.dataStyle.bottomFontColor2 = optionData.dataStyleClone.bottomFontColor2
"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -166,10 +156,7 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.lineColor = dataStyleClone.lineColor">
size="small"
@click="optionData.dataStyle.lineColor = optionData.dataStyleClone.lineColor"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -183,9 +170,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click=" @click="optionData.dataStyle.bottomFontColor3 = dataStyleClone.bottomFontColor3"
optionData.dataStyle.bottomFontColor3 = optionData.dataStyleClone.bottomFontColor3
"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -225,9 +210,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click=" @click="optionData.dataStyle.bottomLineColor1 = dataStyleClone.bottomLineColor1"
optionData.dataStyle.bottomLineColor1 = optionData.dataStyleClone.bottomLineColor1
"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -242,9 +225,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click=" @click="optionData.dataStyle.bottomLineColor2 = dataStyleClone.bottomLineColor2"
optionData.dataStyle.bottomLineColor2 = optionData.dataStyleClone.bottomLineColor2
"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -260,10 +241,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click=" @click="optionData.dataStyle.bottomComponentColor1 = dataStyleClone.bottomComponentColor1"
optionData.dataStyle.bottomComponentColor1 =
optionData.dataStyleClone.bottomComponentColor1
"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -278,10 +256,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click=" @click="optionData.dataStyle.bottomComponentColor2 = dataStyleClone.bottomComponentColor2"
optionData.dataStyle.bottomComponentColor2 =
optionData.dataStyleClone.bottomComponentColor2
"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -320,6 +295,24 @@
}, },
}); });
const dataStyleClone = {
iconColor1: '#B8FDB4',
iconColor2: '#60EC8D',
rectStrokeColor: '#00611A',
rectFillColor: '#0A251E',
gFillColor: '#4FE985',
bottomFontColor1: '#A4F9AB',
bottomFontColor2: '#FFFFFF',
lineColor: '#A4F9AB',
bottomFontColor3: '#FFFFFF',
bottomComponentColor1: '#337D4E',
bottomComponentColor2: '#2D593B',
bottomLineColor1: '#6FEF94',
bottomLineColor2: '#A8F8C6',
};
// //
const fitList = [ const fitList = [
{ {

View File

@ -8,12 +8,13 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, PropType, toRefs, watch, reactive, ref } from 'vue'; import { computed, PropType, toRefs, watch, reactive, ref, onMounted } from 'vue';
import { CreateComponentType } from '@/packages/index.d'; import { CreateComponentType } from '@/packages/index.d';
import { icon } from '@/plugins'; import { icon } from '@/plugins';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'; import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { useChartDataFetch } from '@/hooks'; import { useChartDataFetch } from '@/hooks';
import Tupian from './svg/tupian.vue'; import Tupian from './svg/tupian.vue';
import { EventBus } from '@/utils/eventBus';
const props = defineProps({ const props = defineProps({
chartConfig: { chartConfig: {
@ -21,12 +22,17 @@
required: true, required: true,
}, },
}); });
const { w, h } = toRefs(props.chartConfig.attr); const { w, h } = toRefs(props.chartConfig.attr);
const option = reactive({ const option = reactive({
dataset: props.chartConfig.option.dataset, dataset: props.chartConfig.option.dataset,
}); });
onMounted(() => {
//
EventBus.on(props.chartConfig.id + 'click', (data) => {
console.log('data', data);
});
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -20,7 +20,7 @@ export const option = {
titleWidth: 181, titleWidth: 181,
titleHeight: 30, titleHeight: 30,
videoloop: true, // 视频-循环播放 videoloop: false, // 视频-循环播放
videomuted: true, // 视频-静音 videomuted: true, // 视频-静音
videofit: 'fill', // 视频-适应方式 videofit: 'fill', // 视频-适应方式
videowidth: 181, videowidth: 181,
@ -40,17 +40,6 @@ export const option = {
iconFillColor: '#0A251E', iconFillColor: '#0A251E',
iconBottomColor: '#0E4030', iconBottomColor: '#0E4030',
}, },
dataStyleClone:{
borderColor: '#008000',
titleColorStop1: '#1F6B55',
titleColorStop2: '#0A392A',
titleRightrColor: '#00611A',
iconColorStop1: '#73F095',
iconColorStop2: '#BBFDB5',
iconStrokeColor: '#00611A',
iconFillColor: '#0A251E',
iconBottomColor: '#0E4030',
}
} }
export default class Config extends PublicConfigClass implements CreateComponentType { export default class Config extends PublicConfigClass implements CreateComponentType {

View File

@ -25,7 +25,7 @@
/> />
</SettingItem> </SettingItem>
</SettingItemBox> </SettingItemBox>
<n-tag type="primary">编辑页面修改视频数据配置后请在预览页面查看效果</n-tag>
<SettingItemBox name="视频设置"> <SettingItemBox name="视频设置">
<SettingItem> <SettingItem>
<n-checkbox v-model:checked="optionData.dataStyle.videoloop" size="small"> <n-checkbox v-model:checked="optionData.dataStyle.videoloop" size="small">
@ -69,7 +69,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.borderColor = optionData.dataStyleClone.borderColor" @click="optionData.dataStyle.borderColor = dataStyleClone.borderColor"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -101,7 +101,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.titleColorStop1 = optionData.dataStyleClone.titleColorStop1" @click="optionData.dataStyle.titleColorStop1 = dataStyleClone.titleColorStop1"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -116,7 +116,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.titleColorStop2 = optionData.dataStyleClone.titleColorStop2" @click="optionData.dataStyle.titleColorStop2 = dataStyleClone.titleColorStop2"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -131,9 +131,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click=" @click="optionData.dataStyle.titleRightrColor = dataStyleClone.titleRightrColor"
optionData.dataStyle.titleRightrColor = optionData.dataStyleClone.titleRightrColor
"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -148,7 +146,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.iconColorStop1 = optionData.dataStyleClone.iconColorStop1" @click="optionData.dataStyle.iconColorStop1 = dataStyleClone.iconColorStop1"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -163,7 +161,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.iconColorStop2 = optionData.dataStyleClone.iconColorStop2" @click="optionData.dataStyle.iconColorStop2 = dataStyleClone.iconColorStop2"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -178,7 +176,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.iconStrokeColor = optionData.dataStyleClone.iconStrokeColor" @click="optionData.dataStyle.iconStrokeColor = dataStyleClone.iconStrokeColor"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -193,7 +191,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.iconFillColor = optionData.dataStyleClone.iconFillColor" @click="optionData.dataStyle.iconFillColor = dataStyleClone.iconFillColor"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -208,7 +206,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click="optionData.dataStyle.iconBottomColor = optionData.dataStyleClone.iconBottomColor" @click="optionData.dataStyle.iconBottomColor = dataStyleClone.iconBottomColor"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -294,4 +292,16 @@
label: 'none', label: 'none',
}, },
]; ];
const dataStyleClone = {
borderColor: '#008000',
titleColorStop1: '#1F6B55',
titleColorStop2: '#0A392A',
titleRightrColor: '#00611A',
iconColorStop1: '#73F095',
iconColorStop2: '#BBFDB5',
iconStrokeColor: '#00611A',
iconFillColor: '#0A251E',
iconBottomColor: '#0E4030',
};
</script> </script>

View File

@ -2,27 +2,27 @@
"source": [ "source": [
{ {
"title":"DJA-72无人机监控画面", "title":"DJA-72无人机监控画面",
"videoUrl": "/src/assets/videos/earth.mp4" "videoUrl": "http://221.2.83.254:7012/live/37130100181328000001.m3u8"
}, },
{ {
"title":"DJ-057无人机监控画面", "title":"DJ-057无人机监控画面",
"videoUrl": "/src/assets/videos/earth.mp4" "videoUrl": "http://221.2.83.254:7012/live/37130100181328000001.m3u8"
}, },
{ {
"title":"DJA-20无人机监控画面", "title":"DJA-20无人机监控画面",
"videoUrl": "/src/assets/videos/earth.mp4" "videoUrl": "http://221.2.83.254:7012/live/37130100181328000001.m3u8"
}, },
{ {
"title":"DJA-035无人机监控画面", "title":"DJA-035无人机监控画面",
"videoUrl": "/src/assets/videos/earth.mp4" "videoUrl": "http://221.2.83.254:7012/live/37130100181328000001.m3u8"
}, },
{ {
"title":"DJA-11无人机监控画面", "title":"DJA-11无人机监控画面",
"videoUrl": "/src/assets/videos/earth.mp4" "videoUrl": "http://221.2.83.254:7012/live/37130100181328000001.m3u8"
}, },
{ {
"title":"DJ-021无人机监控画面", "title":"DJ-021无人机监控画面",
"videoUrl": "/src/assets/videos/earth.mp4" "videoUrl": "http://221.2.83.254:7012/live/37130100181328000001.m3u8"
} }
] ]
} }

View File

@ -1,24 +1,40 @@
<template> <template>
<div class="WuRenJiShiShiHuaMian"> <div class="WuRenJiShiShiHuaMian">
<div class="list"> <div class="list">
<div v-for="item in option.dataset" :key="item.key"> <div v-for="(item, index) in option.dataset" :key="item.title">
<div class="item"> <div class="item">
<video <!-- 编辑状态 -->
:style="{ <div class="videoDiv">
border: `${option.dataStyle.borderWidth}px solid ${option.dataStyle.borderColor}`, <video
padding: `${option.dataStyle.padding}px`, v-if="isEdit"
}" class="TCPlayer-video-contaiiner"
preload="auto" preload="auto"
crossOrigin="anonymous" crossOrigin="anonymous"
playsinline playsinline
autoplay autoplay
:object-fit="option.dataset.fit" :object-fit="option.dataset.fit"
:loop="option.dataStyle.videoloop" :loop="option.dataStyle.videoloop"
:muted="option.dataStyle.videomuted" :muted="option.dataStyle.videomuted"
:width="`${option.dataStyle.videowidth}`" :width="`${option.dataStyle.videowidth - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
:height="`${option.dataStyle.videoheight}`" :height="`${option.dataStyle.videoheight - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
:src="item.videoUrl" src="/src/assets/videos/earth.mp4"
/> />
<!-- 其他情况 -->
<video
v-else
:id="item.title + item.index"
class="TCPlayer-video-contaiiner"
preload="auto"
crossOrigin="anonymous"
playsinline
autoplay
:object-fit="option.dataset.fit"
:loop="option.dataStyle.videoloop"
:muted="option.dataStyle.videomuted"
:width="`${option.dataStyle.videowidth - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
:height="`${option.dataStyle.videoheight - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
/>
</div>
<Title class="title" :item="item" :dataStyle="option.dataStyle" /> <Title class="title" :item="item" :dataStyle="option.dataStyle" />
</div> </div>
</div> </div>
@ -27,7 +43,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, PropType, toRefs, watch, reactive, ref } from 'vue'; import { PropType, toRefs, watch, reactive, ref, onMounted, onBeforeUnmount } from 'vue';
import { CreateComponentType } from '@/packages/index.d'; import { CreateComponentType } from '@/packages/index.d';
import { icon } from '@/plugins'; import { icon } from '@/plugins';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'; import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
@ -60,6 +76,47 @@
deep: true, deep: true,
}, },
); );
//
const isEdit = window.location.href.includes('/chart/home/');
//
let players: any = [];
function handlerPlayVideo() {
option.dataset.forEach((element, index) => {
if (players[index]) {
players[index].src(element.videoUrl);
} else {
players[index] = TCPlayer(element.title + element.index, {});
players[index].src(element.videoUrl);
}
});
}
//
onMounted(() => {
option.dataset.forEach((element) => {
let player: any = null;
players.push(player);
});
if (!window.location.href.includes('/chart/home/')) {
setTimeout(function () {
handlerPlayVideo();
}, 1000);
}
});
//
onBeforeUnmount(() => {
if (players) {
players.forEach((player) => {
if (player) {
player.dispose();
player = null;
}
});
}
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -92,6 +149,14 @@
display: inline-block; display: inline-block;
} }
.videoDiv {
width: v-bind('`${option.dataStyle.videowidth}px`');
height: v-bind('`${option.dataStyle.videoheight}px`');
border: v-bind('`${option.dataStyle.borderWidth}px`') solid
v-bind('`${option.dataStyle.borderColor}`');
padding: v-bind('`${option.dataStyle.padding}px`');
}
video { video {
display: block; display: block;
object-fit: v-bind('option.dataStyle.videofit'); object-fit: v-bind('option.dataStyle.videofit');

View File

@ -45,17 +45,6 @@ export const option = {
listTypeWidth: 66, listTypeWidth: 66,
listTypeHeight: 30, listTypeHeight: 30,
}, },
dataStyleClone:{
typeColor1: '#FFC600',
typeColor2: '#08B47A',
listTitlePathStrokeColor: '#049D73',
listTitlePathFillColor: '#05A074',
listTitlePathStrokeColor2: '#049D72',
listTitleRectFillColor: '#05A074',
listTypePathStrokeColor: '#06A475',
listTypePathFillColor: '#FFFFFF00',
listTypeRactFillColor: '#06A475',
}
} }
export default class Config extends PublicConfigClass implements CreateComponentType { export default class Config extends PublicConfigClass implements CreateComponentType {

View File

@ -9,10 +9,7 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.typeColor1 = dataStyleClone.typeColor1">
size="small"
@click="optionData.dataStyle.typeColor1 = optionData.dataStyleClone.typeColor1"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -24,10 +21,7 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem> <SettingItem>
<n-button <n-button size="small" @click="optionData.dataStyle.typeColor2 = dataStyleClone.typeColor2">
size="small"
@click="optionData.dataStyle.typeColor2 = optionData.dataStyleClone.typeColor2"
>
恢复默认 恢复默认
</n-button> </n-button>
</SettingItem> </SettingItem>
@ -138,8 +132,7 @@
<n-button <n-button
size="small" size="small"
@click=" @click="
optionData.dataStyle.listTitlePathStrokeColor = optionData.dataStyle.listTitlePathStrokeColor = dataStyleClone.listTitlePathStrokeColor
optionData.dataStyleClone.listTitlePathStrokeColor
" "
> >
恢复默认 恢复默认
@ -156,8 +149,7 @@
<n-button <n-button
size="small" size="small"
@click=" @click="
optionData.dataStyle.listTitlePathFillColor = optionData.dataStyle.listTitlePathFillColor = dataStyleClone.listTitlePathFillColor
optionData.dataStyleClone.listTitlePathFillColor
" "
> >
恢复默认 恢复默认
@ -175,7 +167,7 @@
size="small" size="small"
@click=" @click="
optionData.dataStyle.listTitlePathStrokeColor2 = optionData.dataStyle.listTitlePathStrokeColor2 =
optionData.dataStyleClone.listTitlePathStrokeColor2 dataStyleClone.listTitlePathStrokeColor2
" "
> >
恢复默认 恢复默认
@ -192,8 +184,7 @@
<n-button <n-button
size="small" size="small"
@click=" @click="
optionData.dataStyle.listTitleRectFillColor = optionData.dataStyle.listTitleRectFillColor = dataStyleClone.listTitleRectFillColor
optionData.dataStyleClone.listTitleRectFillColor
" "
> >
恢复默认 恢复默认
@ -211,8 +202,7 @@
<n-button <n-button
size="small" size="small"
@click=" @click="
optionData.dataStyle.listTypePathStrokeColor = optionData.dataStyle.listTypePathStrokeColor = dataStyleClone.listTypePathStrokeColor
optionData.dataStyleClone.listTypePathStrokeColor
" "
> >
恢复默认 恢复默认
@ -228,10 +218,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click=" @click="optionData.dataStyle.listTypePathFillColor = dataStyleClone.listTypePathFillColor"
optionData.dataStyle.listTypePathFillColor =
optionData.dataStyleClone.listTypePathFillColor
"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -246,10 +233,7 @@
<SettingItem> <SettingItem>
<n-button <n-button
size="small" size="small"
@click=" @click="optionData.dataStyle.listTypeRactFillColor = dataStyleClone.listTypeRactFillColor"
optionData.dataStyle.listTypeRactFillColor =
optionData.dataStyleClone.listTypeRactFillColor
"
> >
恢复默认 恢复默认
</n-button> </n-button>
@ -270,4 +254,16 @@
required: true, required: true,
}, },
}); });
const dataStyleClone = {
typeColor1: '#FFC600',
typeColor2: '#08B47A',
listTitlePathStrokeColor: '#049D73',
listTitlePathFillColor: '#05A074',
listTitlePathStrokeColor2: '#049D72',
listTitleRectFillColor: '#05A074',
listTypePathStrokeColor: '#06A475',
listTypePathFillColor: '#FFFFFF00',
listTypeRactFillColor: '#06A475',
};
</script> </script>

View File

@ -15,6 +15,9 @@ import {
ConfigType, ConfigType,
FetchComFlagType, FetchComFlagType,
} from '@/packages/index.d'; } from '@/packages/index.d';
import { useGlobSetting } from '@/hooks/setting';
const { apiUrl } = useGlobSetting();
const configModules: Record<string, { default: string }> = import.meta.glob( const configModules: Record<string, { default: string }> = import.meta.glob(
'./components/**/config.vue', './components/**/config.vue',
@ -119,9 +122,14 @@ export const fetchImages = async (targetData?: ConfigType) => {
// 正则判断图片是否为 url是则直接返回该 url // 正则判断图片是否为 url是则直接返回该 url
if (/^(http|https):\/\/([\w.]+\/?)\S*/.test(targetData.image)) return targetData.image; if (/^(http|https):\/\/([\w.]+\/?)\S*/.test(targetData.image)) return targetData.image;
// 新数据动态处理 // 新数据动态处理
const { image } = targetData; const { image, key } = targetData;
// 兼容旧数据 // 兼容旧数据
if (image.includes('@') || image.includes('base64')) return image; if (image.includes('@') || image.includes('base64')) {
return image;
} else if (key == 'GroupItem') {
// 兼容多组件保存成自定义组件
return apiUrl + '/' + image;
}
const imageName = image.substring(image.lastIndexOf('/') + 1); const imageName = image.substring(image.lastIndexOf('/') + 1);
for (const key in imagesModules) { for (const key in imagesModules) {

View File

@ -73,6 +73,8 @@ export const useChartEditStore = defineStore({
}, },
// 右键菜单 // 右键菜单
rightMenuShow: false, rightMenuShow: false,
// 多组合组件预览图
groupImgShow: false,
// 鼠标定位 // 鼠标定位
mousePosition: { mousePosition: {
startX: 0, startX: 0,
@ -160,6 +162,9 @@ export const useChartEditStore = defineStore({
getRightMenuShow(): boolean { getRightMenuShow(): boolean {
return this.rightMenuShow; return this.rightMenuShow;
}, },
getSaveGroupImgShow(): boolean {
return this.groupImgShow;
},
getEditCanvas(): EditCanvasType { getEditCanvas(): EditCanvasType {
return this.editCanvas; return this.editCanvas;
}, },
@ -231,6 +236,10 @@ export const useChartEditStore = defineStore({
setRightMenuShow(value: boolean) { setRightMenuShow(value: boolean) {
this.rightMenuShow = value; this.rightMenuShow = value;
}, },
// 设置多组合组件预览图
setSaveGroupImgShow(value: boolean) {
this.groupImgShow = value;
},
// * 设置目标数据 hover // * 设置目标数据 hover
setTargetHoverChart(hoverId?: TargetChartType['hoverId']) { setTargetHoverChart(hoverId?: TargetChartType['hoverId']) {
this.targetChart.hoverId = hoverId; this.targetChart.hoverId = hoverId;
@ -1042,7 +1051,7 @@ export const useChartEditStore = defineStore({
} }
}, },
// 保存至分组 // 保存至分组
saveToGroup() { saveToGroup(img: string) {
if (this.getTargetChart.selectId.length > 1) { if (this.getTargetChart.selectId.length > 1) {
window['$message'].warning('多个组件,请先创建分组后保存'); window['$message'].warning('多个组件,请先创建分组后保存');
return; return;
@ -1052,7 +1061,7 @@ export const useChartEditStore = defineStore({
if (item.id == this.getTargetChart.selectId[0]) { if (item.id == this.getTargetChart.selectId[0]) {
obj = { obj = {
title: item.chartConfig.title, title: item.chartConfig.title,
image: 'upload.png', image: img,
key: 'GroupItem', key: 'GroupItem',
json: { json: {
charts: item, charts: item,

15
src/utils/eventBus.ts Normal file
View File

@ -0,0 +1,15 @@
// eventBus
import { reactive } from 'vue';
export const EventBus = reactive({
events: {},
emit(event, data) {
this.events[event] && this.events[event].forEach((callback) => callback(data));
},
on(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
},
});

View File

@ -5,10 +5,13 @@
class="go-content-charts-item-box" class="go-content-charts-item-box"
:class="[chartMode === ChartModeEnum.DOUBLE ? 'double' : 'single']" :class="[chartMode === ChartModeEnum.DOUBLE ? 'double' : 'single']"
> >
<div v-if="reloadShow" class="reloadDiv" title="刷新" @click="reloadBtn">
<ReloadIcon v-if="reloadShow" />
</div>
<!-- 每一项组件的渲染 --> <!-- 每一项组件的渲染 -->
<div <div
class="item-box" class="item-box"
v-for="(item, index) in menuOptions" v-for="(item, index) in menuOptionsList"
:key="item.title" :key="item.title"
draggable draggable
@dragstart="!item.disabled && dragStartHandle($event, item)" @dragstart="!item.disabled && dragStartHandle($event, item)"
@ -98,13 +101,13 @@
import { GoIconify } from '@/components/GoIconify'; import { GoIconify } from '@/components/GoIconify';
import { icon } from '@/plugins'; import { icon } from '@/plugins';
import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'; import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d';
import { Modal } from 'ant-design-vue';
import omit from 'lodash/omit'; import omit from 'lodash/omit';
import cloneDeep from 'lodash/cloneDeep'; import cloneDeep from 'lodash/cloneDeep';
import { customComponentSaveDelete } from '@/api/path/project.api'; import { customComponentSaveDelete, customComponentList } from '@/api/path/project.api';
const chartEditStore = useChartEditStore(); const chartEditStore = useChartEditStore();
const { TrashIcon } = icon.ionicons5; const { TrashIcon, ReloadIcon } = icon.ionicons5;
const emit = defineEmits(['deletePhoto']); const emit = defineEmits(['deletePhoto']);
const props = defineProps({ const props = defineProps({
@ -113,7 +116,12 @@
default: () => [], default: () => [],
}, },
}); });
const menuOptionsList = ref(props.menuOptions);
const reloadShow = ref(false);
if (props.menuOptions.length > 0 && props.menuOptions[0].key === 'GroupItem') {
reloadShow.value = true;
}
const chartLayoutStore = useChartLayoutStore(); const chartLayoutStore = useChartLayoutStore();
const contentChartsItemBoxRef = ref(); const contentChartsItemBoxRef = ref();
@ -150,11 +158,9 @@
// //
const dblclickHandle = async (item: ConfigType) => { const dblclickHandle = async (item: ConfigType) => {
console.log('双击添加', item);
if (item.disabled) return; if (item.disabled) return;
// 使 // 使
if (item.key == 'GroupItem') { if (item.key == 'GroupItem') {
console.log('分组');
try { try {
loadingStart(); loadingStart();
const recordCharts = item.json; const recordCharts = item.json;
@ -265,20 +271,52 @@
}, },
); );
const deleteComponent = (item: ConfigType, index: number) => { const deleteComponent = (item: ConfigType, index: number) => {
props.menuOptions.splice(index, 1); Modal.confirm({
customComponentSaveDelete({ title: '是否确认删除?',
ids: item.id, onCancel() {},
}).then((res) => { async onOk() {
if (res) { await customComponentSaveDelete({
window['$message'].success(`删除成功`); ids: item.id,
} else { }).then((res) => {
window['$message'].success(`删除失败`); if (res) {
} props.menuOptions.splice(index, 1);
window['$message'].success(`删除成功`);
} else {
window['$message'].success(`删除失败`);
}
});
},
});
};
const getCustomComponentList = async () => {
const data = await customComponentList({
page: 1,
limit: 999,
});
let list = [];
data.items.forEach((item) => {
let obj = JSON.parse(item.content);
list.push({
...obj,
id: item.id,
});
});
return list;
};
const reloadBtn = () => {
getCustomComponentList().then((res) => {
menuOptionsList.value = res;
}); });
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.reloadDiv {
width: 20px;
height: 20px;
margin-right: 20px;
cursor: pointer;
}
/* 列表项宽度 */ /* 列表项宽度 */
$itemWidth: 100%; $itemWidth: 100%;
$maxItemWidth: 180px; $maxItemWidth: 180px;

View File

@ -12,151 +12,154 @@
></n-menu> ></n-menu>
<div class="chart-content-list"> <div class="chart-content-list">
<n-scrollbar trigger="none"> <n-scrollbar trigger="none">
<charts-item-box :menuOptions="packages.selectOptions" @deletePhoto="deleteHandle"></charts-item-box> <charts-item-box
:menuOptions="packages.selectOptions"
@deletePhoto="deleteHandle"
></charts-item-box>
</n-scrollbar> </n-scrollbar>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch, computed, reactive } from 'vue' import { ref, watch, computed, reactive } from 'vue';
import { ConfigType } from '@/packages/index.d' import { ConfigType } from '@/packages/index.d';
import { useSettingStore } from '@/store/modules/settingStore/settingStore' import { useSettingStore } from '@/store/modules/settingStore/settingStore';
import { loadAsyncComponent } from '@/utils' import { loadAsyncComponent } from '@/utils';
import { usePackagesStore } from '@/store/modules/packagesStore/packagesStore' import { usePackagesStore } from '@/store/modules/packagesStore/packagesStore';
import { PackagesCategoryEnum } from '@/packages/index.d' import { PackagesCategoryEnum } from '@/packages/index.d';
const ChartsItemBox = loadAsyncComponent(() => import('../ChartsItemBox/index.vue')) const ChartsItemBox = loadAsyncComponent(() => import('../ChartsItemBox/index.vue'));
const packagesStore = usePackagesStore() const packagesStore = usePackagesStore();
const props = defineProps({ const props = defineProps({
selectOptions: { selectOptions: {
type: Object, type: Object,
default: () => {} default: () => {},
} },
}) });
// //
const settingStore = useSettingStore() const settingStore = useSettingStore();
const hidePackageOneCategory = computed(() => { const hidePackageOneCategory = computed(() => {
if (packages.categorysNum > 2) return true if (packages.categorysNum > 2) return true;
return !settingStore.getHidePackageOneCategory return !settingStore.getHidePackageOneCategory;
}) });
let packages = reactive<{ let packages = reactive<{
[T: string]: any [T: string]: any;
}>({ }>({
// //
menuOptions: [], menuOptions: [],
// //
selectOptions: {}, selectOptions: {},
// //
categorys: { categorys: {
all: [] all: [],
}, },
categoryNames: { categoryNames: {
all: '所有' all: '所有',
}, },
// //
categorysNum: 0, categorysNum: 0,
// //
saveSelectOptions: {} saveSelectOptions: {},
}) });
const selectValue = ref<string>('all') const selectValue = ref<string>('all');
// //
const setSelectOptions = (categorys: any) => { const setSelectOptions = (categorys: any) => {
for (const val in categorys) { for (const val in categorys) {
packages.selectOptions = categorys[val] packages.selectOptions = categorys[val];
break break;
}
}
watch(
// @ts-ignore
() => props.selectOptions,
(newData: { list: ConfigType[] }) => {
packages.categorysNum = 0
if (!newData) return
newData.list.forEach((e: ConfigType) => {
const value: ConfigType[] = (packages.categorys as any)[e.category]
packages.categorys[e.category] = value && value.length ? [...value, e] : [e]
packages.categoryNames[e.category] = e.categoryName
packages.categorys['all'].push(e)
})
for (const val in packages.categorys) {
packages.categorysNum += 1
packages.menuOptions.push({
key: val,
label: packages.categoryNames[val]
})
} }
setSelectOptions(packages.categorys) };
//
selectValue.value = packages.menuOptions[0]['key']
},
{
immediate: true
}
)
watch( watch(
() => packagesStore.newPhoto, // @ts-ignore
newPhoto => { () => props.selectOptions,
if (!newPhoto || newPhoto.length <= 0) return (newData: { list: ConfigType[] }) => {
const newPhotoCategory = newPhoto[0].category packages.categorysNum = 0;
packages.categorys[newPhotoCategory].splice(1, 0, ...newPhoto) if (!newData) return;
packages.categorys['all'].splice(1, 0, ...newPhoto) newData.list.forEach((e: ConfigType) => {
} const value: ConfigType[] = (packages.categorys as any)[e.category];
) packages.categorys[e.category] = value && value.length ? [...value, e] : [e];
packages.categoryNames[e.category] = e.categoryName;
packages.categorys['all'].push(e);
});
for (const val in packages.categorys) {
packages.categorysNum += 1;
packages.menuOptions.push({
key: val,
label: packages.categoryNames[val],
});
}
setSelectOptions(packages.categorys);
//
selectValue.value = packages.menuOptions[0]['key'];
},
{
immediate: true,
},
);
// watch(
const deleteHandle = (item: ConfigType, index: number) => { () => packagesStore.newPhoto,
packages.categorys[item.category].splice(index, 1) (newPhoto) => {
packages.categorys['all'].splice(index, 1) if (!newPhoto || newPhoto.length <= 0) return;
} const newPhotoCategory = newPhoto[0].category;
packages.categorys[newPhotoCategory].splice(1, 0, ...newPhoto);
packages.categorys['all'].splice(1, 0, ...newPhoto);
},
);
// //
const clickItemHandle = (key: string) => { const deleteHandle = (item: ConfigType, index: number) => {
packages.selectOptions = packages.categorys[key] packages.categorys[item.category].splice(index, 1);
} packages.categorys['all'].splice(index, 1);
};
//
const clickItemHandle = (key: string) => {
packages.selectOptions = packages.categorys[key];
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
/* 此高度与 ContentBox 组件关联*/ /* 此高度与 ContentBox 组件关联*/
$topHeight: 40px; $topHeight: 40px;
$menuWidth: 65px; $menuWidth: 65px;
@include go('chart-common') { @include go('chart-common') {
display: flex;
height: calc(100vh - #{$--header-height} - #{$topHeight});
.chart-menu-width {
width: $menuWidth;
flex-shrink: 0;
@include fetch-bg-color('background-color2-shallow');
}
.chart-content-list {
width: 200px;
flex: 1;
display: flex; display: flex;
flex-direction: column; height: calc(100vh - #{$--header-height} - #{$topHeight});
align-items: center; .chart-menu-width {
} width: $menuWidth;
@include deep() { flex-shrink: 0;
.n-menu-item { @include fetch-bg-color('background-color2-shallow');
height: 30px; }
&.n-menu-item--selected { .chart-content-list {
&::before { width: 200px;
background-color: rgba(0, 0, 0, 0); flex: 1;
display: flex;
flex-direction: column;
align-items: center;
}
@include deep() {
.n-menu-item {
height: 30px;
&.n-menu-item--selected {
&::before {
background-color: rgba(0, 0, 0, 0);
}
}
.n-menu-item-content {
text-align: center;
padding: 0px 14px !important;
font-size: 12px !important;
} }
}
.n-menu-item-content {
text-align: center;
padding: 0px 14px !important;
font-size: 12px !important;
} }
} }
} }
}
</style> </style>

View File

@ -45,4 +45,8 @@ export const movementTypeOptions: EventOptionsItemType[] = [
label: '地图联动', label: '地图联动',
value: 'map', value: 'map',
}, },
{
label: '组件通信',
value: 'communication',
},
]; ];

View File

@ -36,6 +36,9 @@ export const divider = (n: number = 3) => {
key: `d${n}`, key: `d${n}`,
}; };
}; };
const saveGroup = () => {
chartEditStore.setSaveGroupImgShow(true);
};
// * 默认单组件选项 // * 默认单组件选项
export const defaultOptions: MenuOptionsItemType[] = [ export const defaultOptions: MenuOptionsItemType[] = [
@ -133,7 +136,8 @@ export const defaultOptions: MenuOptionsItemType[] = [
label: '保存至分组', label: '保存至分组',
key: MenuEnum.SAVETOGROUP, key: MenuEnum.SAVETOGROUP,
icon: renderIcon(GridIcon), icon: renderIcon(GridIcon),
fnHandle: chartEditStore.saveToGroup, // fnHandle: chartEditStore.saveToGroup,
fnHandle: saveGroup,
}, },
]; ];

View File

@ -37,6 +37,59 @@
></n-dropdown> ></n-dropdown>
<!-- 加载蒙层 --> <!-- 加载蒙层 -->
<content-load></content-load> <content-load></content-load>
<n-modal
class="go-chart-data-monaco-editor"
v-model:show="chartEditStore.getSaveGroupImgShow"
:mask-closable="false"
>
<n-card
:bordered="false"
role="dialog"
size="small"
aria-modal="true"
style="width: 400px; height: 400px"
>
<template #header>
<n-space>
<n-text>上传组件预览图</n-text>
</n-space>
</template>
<template #header-extra> </template>
<n-layout has-sider sider-placement="right">
<n-layout style="height: 340px; padding-right: 20px">
<!-- 编辑主体 -->
<n-upload
:default-file-list="previewFileList"
list-type="image-card"
@finish="handleFinish"
max="1"
@beforeUpload="beforeUpload"
/>
<n-text class="go-ml-2" depth="2">上传多组合组件预览图</n-text>
</n-layout>
</n-layout>
<template #action>
<n-space justify="space-between">
<div class="go-flex-items-center">
<n-tag :bordered="false" type="primary">
<template #icon>
<n-icon :component="DocumentTextIcon" />
</template>
说明
</n-tag>
<n-text class="go-ml-2" depth="2">上传多组合组件预览图</n-text>
</div>
<n-space>
<n-button size="medium" @click="closeModel"></n-button>
<n-button size="medium" type="primary" @click="saveCopyData"></n-button>
</n-space>
</n-space>
</template>
</n-card>
</n-modal>
</NConfigProvider> </NConfigProvider>
</template> </template>
@ -46,10 +99,18 @@
import { useContextMenu } from './hooks/useContextMenu.hook'; import { useContextMenu } from './hooks/useContextMenu.hook';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'; import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore'; import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore';
import { useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks' import { useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks';
import { NConfigProvider } from 'naive-ui' import { NConfigProvider } from 'naive-ui';
import { icon } from '@/plugins';
import { ref } from 'vue';
import { useGlobSetting } from '@/hooks/setting';
import { uploadFile } from '@/api/demo/files';
const { apiUrl } = useGlobSetting();
const uploadFileUrl = apiUrl + '/api/Files/Upload';
const { DocumentTextIcon } = icon.ionicons5;
// //
const darkNTheme = useDarkThemeHook() const darkNTheme = useDarkThemeHook();
const chartHistoryStoreStore = useChartHistoryStore(); const chartHistoryStoreStore = useChartHistoryStore();
const chartEditStore = useChartEditStore(); const chartEditStore = useChartEditStore();
@ -85,6 +146,35 @@
}, },
{ passive: false }, { passive: false },
); );
const previewFileList = ref([]);
//
const closeModel = () => {
chartEditStore.setSaveGroupImgShow(false);
};
const filePath = ref();
//
const saveCopyData = () => {
if (!filePath.value) {
window['$message'].warning('预览图不能为空');
return;
}
chartEditStore.saveToGroup(filePath.value);
closeModel();
};
const beforeUpload = async (options) => {
const Loading = window['$loading'];
Loading && Loading.start();
let uploadParams = new FormData();
uploadParams.append('files', options.file.file);
const uploadRes = await uploadFile(uploadParams);
if (uploadRes.length > 0) {
window['$message'].success('上传成功!');
filePath.value = uploadRes[0].filePath;
Loading && Loading.finish();
} else {
window['$message'].error('上传失败!');
}
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -3,7 +3,7 @@
<div class="filter"> <div class="filter">
<a-select <a-select
v-model:value="state" v-model:value="state"
style="width: 200px" style="width: 100%"
@change="changeState" @change="changeState"
> >
<a-select-option value="0">全部</a-select-option> <a-select-option value="0">全部</a-select-option>