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'
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,
})

View File

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

View File

@ -2,14 +2,28 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore
import { mapFun } from '@/hooks/ceshiFun.hook';
import { router } from '@/router';
import { previewUrl } from '@/utils';
import { EventBus } from '@/utils/eventBus';
const chartEditStore = useChartEditStore();
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 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 j = 0; j < elementList.length; j++) {
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 { 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;
for (let i = 0; i < list.length; i++) {
if (list[i].type == 'click') {
for (let j = 0; j < list[i].movementList.length; j++) {
clickElementItem.value.push(list[i].movementList[j]);
}
} 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 clickBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'click',
val,
);
};
const dblclickBtn = () => {
eventHandlerHook(chartEditStore.getComponentList, dbclickElementItem.value);
const dblclickBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'dblclick',
val,
);
};
const rightclickBtn = (event) => {
event.preventDefault(); //
eventHandlerHook(chartEditStore.getComponentList, rightclickElementItem.value);
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'rightclick',
);
};
const mouseenterBtn = () => {
eventHandlerHook(chartEditStore.getComponentList, mouseenterElementItem.value);
const mouseenterBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'mousein',
val,
);
};
const mouseleaveBtn = () => {
eventHandlerHook(chartEditStore.getComponentList, mouseleaveElementItem.value);
const mouseleaveBtn = (val) => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'mouseout',
val,
);
};
</script>

View File

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

View File

@ -50,7 +50,7 @@
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.smallColor1 = optionData.dataStyleClone.smallColor1"
@click="optionData.dataStyle.smallColor1 = dataStyleClone.smallColor1"
>
恢复默认
</n-button>
@ -65,7 +65,7 @@
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.smallColor2 = optionData.dataStyleClone.smallColor2"
@click="optionData.dataStyle.smallColor2 = dataStyleClone.smallColor2"
>
恢复默认
</n-button>
@ -80,7 +80,7 @@
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.largeColor1 = optionData.dataStyleClone.largeColor1"
@click="optionData.dataStyle.largeColor1 = dataStyleClone.largeColor1"
>
恢复默认
</n-button>
@ -95,7 +95,7 @@
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.largeColor2 = optionData.dataStyleClone.largeColor2"
@click="optionData.dataStyle.largeColor2 = dataStyleClone.largeColor2"
>
恢复默认
</n-button>
@ -116,4 +116,11 @@
required: true,
},
});
const dataStyleClone = {
smallColor1: '#00D586',
smallColor2: '#00AB4E',
largeColor1: '#007343',
largeColor2: '#89E5A1',
};
</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/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: {
// 自动播放
autoplay: true,
@ -60,6 +34,24 @@ export const option = {
showArrow: true,
// 图片样式
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 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>
</n-input-number>
</SettingItem>
<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>
</n-input-number>
</SettingItem>
@ -102,14 +102,11 @@
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.buttonStyle.dotColor1"
v-model:value="optionData.dataStyle.dotColor1"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.buttonStyle.dotColor1 = optionData.buttonStyleClone.dotColor1"
>
<n-button size="small" @click="optionData.dataStyle.dotColor1 = dataStyleClone.dotColor1">
恢复默认
</n-button>
</SettingItem>
@ -117,14 +114,11 @@
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.buttonStyle.dotColor2"
v-model:value="optionData.dataStyle.dotColor2"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.buttonStyle.dotColor2 = optionData.buttonStyleClone.dotColor2"
>
<n-button size="small" @click="optionData.dataStyle.dotColor2 = dataStyleClone.dotColor2">
恢复默认
</n-button>
</SettingItem>
@ -132,26 +126,26 @@
<SettingItem-box name="箭头样式" v-if="optionData.dataStyle.showArrow">
<SettingItem name="箭头按钮宽度">
<n-input-number
v-model:value="optionData.buttonStyle.buttonWidth"
v-model:value="optionData.dataStyle.buttonWidth"
size="small"
:min="0"
></n-input-number>
</SettingItem>
<SettingItem name="箭头按钮长度">
<n-input-number
v-model:value="optionData.buttonStyle.buttonHeight"
v-model:value="optionData.dataStyle.buttonHeight"
size="small"
:min="0"
></n-input-number>
</SettingItem>
<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>
</n-input-number>
</SettingItem>
<SettingItem name="箭头位置(边界)">
<n-input-number
v-model:value="optionData.buttonStyle.buttonLeftAndRight"
v-model:value="optionData.dataStyle.buttonLeftAndRight"
size="small"
:min="0"
>
@ -162,13 +156,13 @@
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.buttonStyle.buttonColor"
v-model:value="optionData.dataStyle.buttonColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.buttonStyle.buttonColor = optionData.buttonStyleClone.buttonColor"
@click="optionData.dataStyle.buttonColor = dataStyleClone.buttonColor"
>
恢复默认
</n-button>
@ -177,20 +171,17 @@
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.buttonStyle.iconColor"
v-model:value="optionData.dataStyle.iconColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.buttonStyle.iconColor = optionData.buttonStyleClone.iconColor"
>
<n-button size="small" @click="optionData.dataStyle.iconColor = dataStyleClone.iconColor">
恢复默认
</n-button>
</SettingItem>
<SettingItem name="箭头图标大小">
<n-input-number
v-model:value="optionData.buttonStyle.iconFontSize"
v-model:value="optionData.dataStyle.iconFontSize"
size="small"
:min="0"
></n-input-number>
@ -202,20 +193,20 @@
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.buttonStyle.borderColor"
v-model:value="optionData.dataStyle.borderColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.buttonStyle.borderColor = optionData.buttonStyleClone.borderColor"
@click="optionData.dataStyle.borderColor = dataStyleClone.borderColor"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="边框宽度">
<n-input-number
v-model:value="optionData.buttonStyle.borderWidth"
v-model:value="optionData.dataStyle.borderWidth"
size="small"
:min="0"
></n-input-number>
@ -237,6 +228,14 @@
},
});
const dataStyleClone = {
dotColor1: '#00611a',
dotColor2: '#00cc13',
buttonColor: '#A4A4A4FF',
iconColor: '#1EC233',
borderColor: '#008000',
};
//
const dotTypes = [
{

View File

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

View File

@ -30,25 +30,6 @@ export const option = {
// 底部矩形块颜色
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 {

View File

@ -63,10 +63,7 @@
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.backgroud = optionData.dataStyleClone.backgroud"
>
<n-button size="small" @click="optionData.dataStyle.backgroud = dataStyleClone.backgroud">
恢复默认
</n-button>
</SettingItem>
@ -78,10 +75,7 @@
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.lineColor1 = optionData.dataStyleClone.lineColor1"
>
<n-button size="small" @click="optionData.dataStyle.lineColor1 = dataStyleClone.lineColor1">
恢复默认
</n-button>
</SettingItem>
@ -93,10 +87,7 @@
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.lineColor2 = optionData.dataStyleClone.lineColor2"
>
<n-button size="small" @click="optionData.dataStyle.lineColor2 = dataStyleClone.lineColor2">
恢复默认
</n-button>
</SettingItem>
@ -108,10 +99,7 @@
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.lineColor3 = optionData.dataStyleClone.lineColor3"
>
<n-button size="small" @click="optionData.dataStyle.lineColor3 = dataStyleClone.lineColor3">
恢复默认
</n-button>
</SettingItem>
@ -125,7 +113,7 @@
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.pathLineColor1 = optionData.dataStyleClone.pathLineColor1"
@click="optionData.dataStyle.pathLineColor1 = dataStyleClone.pathLineColor1"
>
恢复默认
</n-button>
@ -140,7 +128,7 @@
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.pathLineColor2 = optionData.dataStyleClone.pathLineColor2"
@click="optionData.dataStyle.pathLineColor2 = dataStyleClone.pathLineColor2"
>
恢复默认
</n-button>
@ -155,7 +143,7 @@
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.topPolygonColor = optionData.dataStyleClone.topPolygonColor"
@click="optionData.dataStyle.topPolygonColor = dataStyleClone.topPolygonColor"
>
恢复默认
</n-button>
@ -170,7 +158,7 @@
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.topEllipseColor = optionData.dataStyleClone.topEllipseColor"
@click="optionData.dataStyle.topEllipseColor = dataStyleClone.topEllipseColor"
>
恢复默认
</n-button>
@ -185,7 +173,7 @@
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.bottomUseColor = optionData.dataStyleClone.bottomUseColor"
@click="optionData.dataStyle.bottomUseColor = dataStyleClone.bottomUseColor"
>
恢复默认
</n-button>
@ -206,4 +194,24 @@
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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -49,7 +49,7 @@
>
{{ item.time }}
</div>
-------------------------------
<span v-if="option.dataStyle.showLine">-------------------------------</span>
<!-- 文本 -->
<div
v-if="index == 0"
@ -69,8 +69,9 @@
>
{{ item.content }}
</div>
<!-- 图片 -->
<div
v-if="item.imageurl"
v-if="item.imageUrl"
:style="{
display: 'flex',
alignItems: 'center',
@ -82,32 +83,46 @@
>
<n-image
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"
:width="`${option.dataStyle.imageWidth}`"
:height="`${option.dataStyle.imageHeight}`"
lazy
/>
</div>
<div
v-if="item.videourl"
:style="{
display: 'flex',
alignItems: 'center',
justifyContent: `${option.dataStyle.videoAlign}`,
marginTop: `${option.dataStyle.videoMarginTop}px`,
}"
>
<!-- 视频 -->
<div v-if="item.videoUrl" class="timeLineVideoDiv">
<!-- 编辑状态 -->
<video
v-if="isEdit"
class="TCPlayer-video-contaiiner"
preload="auto"
crossOrigin="anonymous"
playsinline
autoplay
:loop="option.dataStyle.videoLoop"
:muted="option.dataStyle.videoMuted"
:width="`${option.dataStyle.videoWidth}`"
:height="`${option.dataStyle.videoHeight}`"
:src="item.videourl"
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
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>
</div>
</template>
@ -117,7 +132,7 @@
</template>
<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 { icon } from '@/plugins';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
@ -137,6 +152,47 @@
dataset: props.chartConfig.option.dataset,
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>
<style lang="scss" scoped>
@ -160,6 +216,18 @@
-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 {
display: block;
object-fit: v-bind('option.dataStyle.videoFit');

View File

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

View File

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

View File

@ -1,6 +1,9 @@
<template>
<div class="WuRenJiShiShiHuaMian">
<div class="ModalVideo">
<!-- 编辑状态 -->
<video
v-if="isEdit"
class="TCPlayer-video-contaiiner"
preload="auto"
crossOrigin="anonymous"
playsinline
@ -8,15 +11,30 @@
:object-fit="option.dataset.fit"
:loop="option.dataStyle.videoLoop"
:muted="option.dataStyle.videoMuted"
:width="`${w - option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
:height="`${h - option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
:src="option.dataset"
:width="`${w - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
:height="`${h - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
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>
</template>
<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 { icon } from '@/plugins';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
@ -36,28 +54,57 @@
dataset: props.chartConfig.option.dataset,
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>
<style lang="scss" scoped>
.WuRenJiShiShiHuaMian {
.ModalVideo {
overflow-y: auto;
border: v-bind('`${option.dataStyle.borderWidth}px`') solid
v-bind('`${option.dataStyle.borderColor}`');
background: v-bind('`${option.dataStyle.backgroud}`');
padding: v-bind('`${option.dataStyle.padding}px`');
width: v-bind('`${w}px`');
height: v-bind('`${h}px`');
}
.WuRenJiShiShiHuaMian::-webkit-scrollbar {
.ModalVideo::-webkit-scrollbar {
display: none;
}
.WuRenJiShiShiHuaMian {
.ModalVideo {
scrollbar-width: none;
-ms-overflow-style: none;
}
video {
display: block;
object-fit: v-bind('option.dataStyle.videoFit');
padding-top: v-bind('`${option.dataStyle.padding}px`');
padding-left: v-bind('`${option.dataStyle.padding}px`');
}
</style>

View File

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

View File

@ -40,23 +40,6 @@ export const option = {
bottomComponentColor1: '#6FEF94',
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 {

View File

@ -54,10 +54,7 @@
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.iconColor1 = optionData.dataStyleClone.iconColor1"
>
<n-button size="small" @click="optionData.dataStyle.iconColor1 = dataStyleClone.iconColor1">
恢复默认
</n-button>
</SettingItem>
@ -69,10 +66,7 @@
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.iconColor2 = optionData.dataStyleClone.iconColor2"
>
<n-button size="small" @click="optionData.dataStyle.iconColor2 = dataStyleClone.iconColor2">
恢复默认
</n-button>
</SettingItem>
@ -134,9 +128,7 @@
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.bottomFontColor1 = optionData.dataStyleClone.bottomFontColor1
"
@click="optionData.dataStyle.bottomFontColor1 = dataStyleClone.bottomFontColor1"
>
恢复默认
</n-button>
@ -151,9 +143,7 @@
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.bottomFontColor2 = optionData.dataStyleClone.bottomFontColor2
"
@click="optionData.dataStyle.bottomFontColor2 = dataStyleClone.bottomFontColor2"
>
恢复默认
</n-button>
@ -166,10 +156,7 @@
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.lineColor = optionData.dataStyleClone.lineColor"
>
<n-button size="small" @click="optionData.dataStyle.lineColor = dataStyleClone.lineColor">
恢复默认
</n-button>
</SettingItem>
@ -183,9 +170,7 @@
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.bottomFontColor3 = optionData.dataStyleClone.bottomFontColor3
"
@click="optionData.dataStyle.bottomFontColor3 = dataStyleClone.bottomFontColor3"
>
恢复默认
</n-button>
@ -225,9 +210,7 @@
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.bottomLineColor1 = optionData.dataStyleClone.bottomLineColor1
"
@click="optionData.dataStyle.bottomLineColor1 = dataStyleClone.bottomLineColor1"
>
恢复默认
</n-button>
@ -242,9 +225,7 @@
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.bottomLineColor2 = optionData.dataStyleClone.bottomLineColor2
"
@click="optionData.dataStyle.bottomLineColor2 = dataStyleClone.bottomLineColor2"
>
恢复默认
</n-button>
@ -260,10 +241,7 @@
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.bottomComponentColor1 =
optionData.dataStyleClone.bottomComponentColor1
"
@click="optionData.dataStyle.bottomComponentColor1 = dataStyleClone.bottomComponentColor1"
>
恢复默认
</n-button>
@ -278,10 +256,7 @@
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.bottomComponentColor2 =
optionData.dataStyleClone.bottomComponentColor2
"
@click="optionData.dataStyle.bottomComponentColor2 = dataStyleClone.bottomComponentColor2"
>
恢复默认
</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 = [
{

View File

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

View File

@ -20,7 +20,7 @@ export const option = {
titleWidth: 181,
titleHeight: 30,
videoloop: true, // 视频-循环播放
videoloop: false, // 视频-循环播放
videomuted: true, // 视频-静音
videofit: 'fill', // 视频-适应方式
videowidth: 181,
@ -40,17 +40,6 @@ export const option = {
iconFillColor: '#0A251E',
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 {

View File

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

View File

@ -2,27 +2,27 @@
"source": [
{
"title":"DJA-72无人机监控画面",
"videoUrl": "/src/assets/videos/earth.mp4"
"videoUrl": "http://221.2.83.254:7012/live/37130100181328000001.m3u8"
},
{
"title":"DJ-057无人机监控画面",
"videoUrl": "/src/assets/videos/earth.mp4"
"videoUrl": "http://221.2.83.254:7012/live/37130100181328000001.m3u8"
},
{
"title":"DJA-20无人机监控画面",
"videoUrl": "/src/assets/videos/earth.mp4"
"videoUrl": "http://221.2.83.254:7012/live/37130100181328000001.m3u8"
},
{
"title":"DJA-035无人机监控画面",
"videoUrl": "/src/assets/videos/earth.mp4"
"videoUrl": "http://221.2.83.254:7012/live/37130100181328000001.m3u8"
},
{
"title":"DJA-11无人机监控画面",
"videoUrl": "/src/assets/videos/earth.mp4"
"videoUrl": "http://221.2.83.254:7012/live/37130100181328000001.m3u8"
},
{
"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>
<div class="WuRenJiShiShiHuaMian">
<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">
<video
:style="{
border: `${option.dataStyle.borderWidth}px solid ${option.dataStyle.borderColor}`,
padding: `${option.dataStyle.padding}px`,
}"
preload="auto"
crossOrigin="anonymous"
playsinline
autoplay
:object-fit="option.dataset.fit"
:loop="option.dataStyle.videoloop"
:muted="option.dataStyle.videomuted"
:width="`${option.dataStyle.videowidth}`"
:height="`${option.dataStyle.videoheight}`"
:src="item.videoUrl"
/>
<!-- 编辑状态 -->
<div class="videoDiv">
<video
v-if="isEdit"
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}`"
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" />
</div>
</div>
@ -27,7 +43,7 @@
</template>
<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 { icon } from '@/plugins';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
@ -60,6 +76,47 @@
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>
<style lang="scss" scoped>
@ -92,6 +149,14 @@
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 {
display: block;
object-fit: v-bind('option.dataStyle.videofit');

View File

@ -45,17 +45,6 @@ export const option = {
listTypeWidth: 66,
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 {

View File

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

View File

@ -15,6 +15,9 @@ import {
ConfigType,
FetchComFlagType,
} from '@/packages/index.d';
import { useGlobSetting } from '@/hooks/setting';
const { apiUrl } = useGlobSetting();
const configModules: Record<string, { default: string }> = import.meta.glob(
'./components/**/config.vue',
@ -119,9 +122,14 @@ export const fetchImages = async (targetData?: ConfigType) => {
// 正则判断图片是否为 url是则直接返回该 url
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);
for (const key in imagesModules) {

View File

@ -73,6 +73,8 @@ export const useChartEditStore = defineStore({
},
// 右键菜单
rightMenuShow: false,
// 多组合组件预览图
groupImgShow: false,
// 鼠标定位
mousePosition: {
startX: 0,
@ -160,6 +162,9 @@ export const useChartEditStore = defineStore({
getRightMenuShow(): boolean {
return this.rightMenuShow;
},
getSaveGroupImgShow(): boolean {
return this.groupImgShow;
},
getEditCanvas(): EditCanvasType {
return this.editCanvas;
},
@ -231,6 +236,10 @@ export const useChartEditStore = defineStore({
setRightMenuShow(value: boolean) {
this.rightMenuShow = value;
},
// 设置多组合组件预览图
setSaveGroupImgShow(value: boolean) {
this.groupImgShow = value;
},
// * 设置目标数据 hover
setTargetHoverChart(hoverId?: TargetChartType['hoverId']) {
this.targetChart.hoverId = hoverId;
@ -1042,7 +1051,7 @@ export const useChartEditStore = defineStore({
}
},
// 保存至分组
saveToGroup() {
saveToGroup(img: string) {
if (this.getTargetChart.selectId.length > 1) {
window['$message'].warning('多个组件,请先创建分组后保存');
return;
@ -1052,7 +1061,7 @@ export const useChartEditStore = defineStore({
if (item.id == this.getTargetChart.selectId[0]) {
obj = {
title: item.chartConfig.title,
image: 'upload.png',
image: img,
key: 'GroupItem',
json: {
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="[chartMode === ChartModeEnum.DOUBLE ? 'double' : 'single']"
>
<div v-if="reloadShow" class="reloadDiv" title="刷新" @click="reloadBtn">
<ReloadIcon v-if="reloadShow" />
</div>
<!-- 每一项组件的渲染 -->
<div
class="item-box"
v-for="(item, index) in menuOptions"
v-for="(item, index) in menuOptionsList"
:key="item.title"
draggable
@dragstart="!item.disabled && dragStartHandle($event, item)"
@ -98,13 +101,13 @@
import { GoIconify } from '@/components/GoIconify';
import { icon } from '@/plugins';
import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d';
import { Modal } from 'ant-design-vue';
import omit from 'lodash/omit';
import cloneDeep from 'lodash/cloneDeep';
import { customComponentSaveDelete } from '@/api/path/project.api';
import { customComponentSaveDelete, customComponentList } from '@/api/path/project.api';
const chartEditStore = useChartEditStore();
const { TrashIcon } = icon.ionicons5;
const { TrashIcon, ReloadIcon } = icon.ionicons5;
const emit = defineEmits(['deletePhoto']);
const props = defineProps({
@ -113,7 +116,12 @@
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 contentChartsItemBoxRef = ref();
@ -150,11 +158,9 @@
//
const dblclickHandle = async (item: ConfigType) => {
console.log('双击添加', item);
if (item.disabled) return;
// 使
if (item.key == 'GroupItem') {
console.log('分组');
try {
loadingStart();
const recordCharts = item.json;
@ -265,20 +271,52 @@
},
);
const deleteComponent = (item: ConfigType, index: number) => {
props.menuOptions.splice(index, 1);
customComponentSaveDelete({
ids: item.id,
}).then((res) => {
if (res) {
window['$message'].success(`删除成功`);
} else {
window['$message'].success(`删除失败`);
}
Modal.confirm({
title: '是否确认删除?',
onCancel() {},
async onOk() {
await customComponentSaveDelete({
ids: item.id,
}).then((res) => {
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>
<style lang="scss" scoped>
.reloadDiv {
width: 20px;
height: 20px;
margin-right: 20px;
cursor: pointer;
}
/* 列表项宽度 */
$itemWidth: 100%;
$maxItemWidth: 180px;

View File

@ -12,151 +12,154 @@
></n-menu>
<div class="chart-content-list">
<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>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, watch, computed, reactive } from 'vue'
import { ConfigType } from '@/packages/index.d'
import { useSettingStore } from '@/store/modules/settingStore/settingStore'
import { loadAsyncComponent } from '@/utils'
import { usePackagesStore } from '@/store/modules/packagesStore/packagesStore'
import { PackagesCategoryEnum } from '@/packages/index.d'
import { ref, watch, computed, reactive } from 'vue';
import { ConfigType } from '@/packages/index.d';
import { useSettingStore } from '@/store/modules/settingStore/settingStore';
import { loadAsyncComponent } from '@/utils';
import { usePackagesStore } from '@/store/modules/packagesStore/packagesStore';
import { PackagesCategoryEnum } from '@/packages/index.d';
const ChartsItemBox = loadAsyncComponent(() => import('../ChartsItemBox/index.vue'))
const packagesStore = usePackagesStore()
const ChartsItemBox = loadAsyncComponent(() => import('../ChartsItemBox/index.vue'));
const packagesStore = usePackagesStore();
const props = defineProps({
selectOptions: {
type: Object,
default: () => {}
}
})
const props = defineProps({
selectOptions: {
type: Object,
default: () => {},
},
});
//
const settingStore = useSettingStore()
//
const settingStore = useSettingStore();
const hidePackageOneCategory = computed(() => {
if (packages.categorysNum > 2) return true
return !settingStore.getHidePackageOneCategory
})
const hidePackageOneCategory = computed(() => {
if (packages.categorysNum > 2) return true;
return !settingStore.getHidePackageOneCategory;
});
let packages = reactive<{
[T: string]: any
}>({
//
menuOptions: [],
//
selectOptions: {},
//
categorys: {
all: []
},
categoryNames: {
all: '所有'
},
//
categorysNum: 0,
//
saveSelectOptions: {}
})
let packages = reactive<{
[T: string]: any;
}>({
//
menuOptions: [],
//
selectOptions: {},
//
categorys: {
all: [],
},
categoryNames: {
all: '所有',
},
//
categorysNum: 0,
//
saveSelectOptions: {},
});
const selectValue = ref<string>('all')
const selectValue = ref<string>('all');
//
const setSelectOptions = (categorys: any) => {
for (const val in categorys) {
packages.selectOptions = categorys[val]
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]
})
//
const setSelectOptions = (categorys: any) => {
for (const val in categorys) {
packages.selectOptions = categorys[val];
break;
}
setSelectOptions(packages.categorys)
//
selectValue.value = packages.menuOptions[0]['key']
},
{
immediate: true
}
)
};
watch(
() => packagesStore.newPhoto,
newPhoto => {
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)
}
)
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,
},
);
//
const deleteHandle = (item: ConfigType, index: number) => {
packages.categorys[item.category].splice(index, 1)
packages.categorys['all'].splice(index, 1)
}
watch(
() => packagesStore.newPhoto,
(newPhoto) => {
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) => {
packages.selectOptions = packages.categorys[key]
}
//
const deleteHandle = (item: ConfigType, index: number) => {
packages.categorys[item.category].splice(index, 1);
packages.categorys['all'].splice(index, 1);
};
//
const clickItemHandle = (key: string) => {
packages.selectOptions = packages.categorys[key];
};
</script>
<style lang="scss" scoped>
/* 此高度与 ContentBox 组件关联*/
$topHeight: 40px;
$menuWidth: 65px;
@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;
/* 此高度与 ContentBox 组件关联*/
$topHeight: 40px;
$menuWidth: 65px;
@include go('chart-common') {
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);
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;
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>

View File

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

View File

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

View File

@ -37,6 +37,59 @@
></n-dropdown>
<!-- 加载蒙层 -->
<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>
</template>
@ -46,10 +99,18 @@
import { useContextMenu } from './hooks/useContextMenu.hook';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore';
import { useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks'
import { NConfigProvider } from 'naive-ui'
import { useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks';
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 chartEditStore = useChartEditStore();
@ -85,6 +146,35 @@
},
{ 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>
<style lang="scss" scoped>

View File

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