refactor(Charts): 重构报警列表组件配置和数据获取
- 更新配置文件,使用深拷贝初始化配置选项 - 添加默认属性设置,包括位置和尺寸 - 优化模板结构,移除冗余空行 - 修改数据获取 API,添加场景码参数
This commit is contained in:
parent
bdeac87abd
commit
417d458775
@ -2,6 +2,8 @@ import { PublicConfigClass } from '@/packages/public'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { AlarmListHazCConfig } from './index'
|
||||
import dataJson from './data.json'
|
||||
import { chartInitConfig } from '@/settings/designSetting'
|
||||
import { cloneDeep } from 'lodash'
|
||||
export enum FontWeightEnum {
|
||||
NORMAL = '常规',
|
||||
BOLD = '加粗',
|
||||
@ -38,20 +40,12 @@ export const option = {
|
||||
itemHeight: 28,
|
||||
fontSize: 12,
|
||||
titleText: '近60分钟报警信息',
|
||||
titleSize: 16,
|
||||
titleColor: '#eee',
|
||||
fontWeight: 'normal',
|
||||
fontStyle: 'italic',
|
||||
paddingX: 45,
|
||||
paddingY: -25,
|
||||
letterSpacing: 0.5,
|
||||
isShowButton: false
|
||||
}
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
public key = AlarmListHazCConfig.key
|
||||
public chartConfig = AlarmListHazCConfig
|
||||
public option = option
|
||||
|
||||
public option = cloneDeep(option)
|
||||
public attr = { ...chartInitConfig, x: 0, y: 0, w: 450, h: 300, zIndex: 1 }
|
||||
|
||||
}
|
||||
|
@ -33,18 +33,13 @@
|
||||
</div>
|
||||
</PublicSmallBorder>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, computed, ref, onMounted, onUnmounted } from 'vue'
|
||||
import { option as configOption } from './config'
|
||||
import SmallBorder from '../SmallBorder/index.vue'
|
||||
import axiosInstance from '@/api/axios'
|
||||
import PublicSmallBorder from '../../Public_SmallBorder/index.vue'
|
||||
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<{ option: typeof configOption }>,
|
||||
@ -73,7 +68,7 @@ const convertTimestampToDateTime = (timestamp: number | string) => {
|
||||
const fetchRecentAlarms = async () => {
|
||||
try {
|
||||
const res: any = await axiosInstance.get(
|
||||
`/awjt/space/getRecentAlarms`,
|
||||
`/awjt/space/getRecentAlarms/${option.value.sceneCode}`,
|
||||
{
|
||||
responseType: 'json',
|
||||
baseURL: ''
|
||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 174 KiB |
@ -3,13 +3,12 @@ import { LineDropdownConfig } from './index'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import dataJson from './data.json'
|
||||
|
||||
import { chartInitConfig } from '@/settings/designSetting'
|
||||
export const includes = ['xAxis', 'yAxis', 'grid']
|
||||
|
||||
// 其它配置
|
||||
const otherConfig = {
|
||||
dateTime: {
|
||||
show: true,
|
||||
selectValue: 'day',
|
||||
dataset: [
|
||||
{
|
||||
@ -144,4 +143,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
|
||||
public key: string = LineDropdownConfig.key
|
||||
public chartConfig = cloneDeep(LineDropdownConfig)
|
||||
public option = echartOptionProfixHandle(option, includes)
|
||||
public attr = { ...chartInitConfig, x: 0, y: 0, w: 450, h: 300, zIndex: 1 }
|
||||
}
|
@ -35,7 +35,7 @@ import config, { includes } from './config'
|
||||
import { DatasetComponent, GridComponent, TooltipComponent } from 'echarts/components'
|
||||
import CustomSelect from './select.vue'
|
||||
import axiosInstance from '@/api/axios'
|
||||
import PublicSmallBorder from '../../Public_SmallBorder/index.vue'
|
||||
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
|
||||
|
||||
const props = defineProps({
|
||||
themeSetting: {
|
||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 174 KiB |
@ -4,6 +4,7 @@ import { CreateComponentType } from '@/packages/index.d'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { chartInitConfig } from '@/settings/designSetting'
|
||||
import dataJson from './data.json'
|
||||
|
||||
export interface DataSourceItem {
|
||||
dataname: string;
|
||||
values: number[];
|
||||
@ -17,7 +18,9 @@ export interface DatasType {
|
||||
dataSource: DataSourceItem[];
|
||||
}
|
||||
|
||||
|
||||
const otherOption = {
|
||||
titleText: '报警处置情况'
|
||||
}
|
||||
export const includes = ['legend', 'xAxis', 'yAxis', 'grid']
|
||||
export const seriesItem = {
|
||||
type: 'line',
|
||||
@ -57,31 +60,32 @@ export const seriesItem = {
|
||||
}
|
||||
}
|
||||
export const option = {
|
||||
...otherOption,
|
||||
sceneCode: 'T04',
|
||||
dateTime: {
|
||||
selectValue: 'day',
|
||||
dataset: [
|
||||
{
|
||||
label: '当天',
|
||||
value: 'day'
|
||||
},
|
||||
{
|
||||
label: '本周',
|
||||
value: 'week'
|
||||
},
|
||||
{
|
||||
label: '当月',
|
||||
value: 'month'
|
||||
},
|
||||
{
|
||||
label: '本季度',
|
||||
value: 'quarter'
|
||||
},
|
||||
{
|
||||
label: '当年',
|
||||
value: 'year'
|
||||
}
|
||||
]
|
||||
selectValue: 'day',
|
||||
dataset: [
|
||||
{
|
||||
label: '当天',
|
||||
value: 'day'
|
||||
},
|
||||
{
|
||||
label: '本周',
|
||||
value: 'week'
|
||||
},
|
||||
{
|
||||
label: '当月',
|
||||
value: 'month'
|
||||
},
|
||||
{
|
||||
label: '本季度',
|
||||
value: 'quarter'
|
||||
},
|
||||
{
|
||||
label: '当年',
|
||||
value: 'year'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
dataset: {
|
||||
|
@ -1,38 +1,38 @@
|
||||
<template>
|
||||
<div class="go-border-box">
|
||||
|
||||
<img src="./assets/title.svg" class="svg" />
|
||||
<div class="buttonContent">
|
||||
<span class="title">报警处置情况</span>
|
||||
</div>
|
||||
|
||||
<!-- 使用新的下拉选择器组件 -->
|
||||
<CustomSelect :options="option.dateTime.dataset" :selectedValue="option.dateTime.selectValue"
|
||||
@change="handleSelectChange" />
|
||||
<!-- <CustomSelect :options="option.dateTime.dataset" :selectedValue="option.dateTime.selectValue"
|
||||
@change="handleSelectChange" /> -->
|
||||
<PublicSmallBorder :title-text="option.titleText" :select-option="option.dateTime" @change="handleSelectChange">
|
||||
<div class="content">
|
||||
<div class="textContent">
|
||||
<div class="textInContent">
|
||||
<span class="smallText">报警总数 </span>
|
||||
<span class="bigText">{{ currentData.alertTotal?.toLocaleString('en-US') || '0' }}</span>
|
||||
</div>
|
||||
<div class="textInContent">
|
||||
<span class="smallText">未处置报警数</span>
|
||||
<span class="bigText">{{ currentData.unprocessedAlert?.toLocaleString('en-US') || '0' }}</span>
|
||||
</div>
|
||||
<div class="textInContent">
|
||||
<span class="smallText">平均处置时长</span>
|
||||
<span class="bigText">{{ currentData.averageResolutionTime?.toLocaleString('en-US') || '0' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chartsContent">
|
||||
<span class="smallText Tips">
|
||||
<img class="icon" src="./icon01.png" alt="">
|
||||
数据统计图表</span>
|
||||
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="chartOption"
|
||||
:update-options="{
|
||||
replaceMerge: replaceMergeArr
|
||||
}" autoresize>
|
||||
</v-chart>
|
||||
</div>
|
||||
</div>
|
||||
</PublicSmallBorder>
|
||||
|
||||
<div class="textContent">
|
||||
<div class="textInContent">
|
||||
<span class="smallText">报警总数 </span>
|
||||
<span class="bigText">{{ currentData.alertTotal?.toLocaleString('en-US') || '0' }}</span>
|
||||
</div>
|
||||
<div class="textInContent">
|
||||
<span class="smallText">未处置报警数</span>
|
||||
<span class="bigText">{{ currentData.unprocessedAlert?.toLocaleString('en-US') || '0' }}</span>
|
||||
</div>
|
||||
<div class="textInContent">
|
||||
<span class="smallText">平均处置时长</span>
|
||||
<span class="bigText">{{ currentData.averageResolutionTime?.toLocaleString('en-US') || '0' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chartsContent">
|
||||
<span class="smallText Tips">
|
||||
<img class="icon" src="./icon01.png" alt="">
|
||||
数据统计图表</span>
|
||||
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="chartOption" :update-options="{
|
||||
replaceMerge: replaceMergeArr
|
||||
}" autoresize>
|
||||
</v-chart>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
@ -50,7 +50,7 @@ import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } fr
|
||||
import isObject from 'lodash/isObject'
|
||||
import CustomSelect from './select.vue'
|
||||
import axiosInstance from '@/api/axios'
|
||||
|
||||
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
|
||||
const props = defineProps({
|
||||
themeSetting: {
|
||||
type: Object,
|
||||
@ -82,7 +82,7 @@ const selectedTimeRange = ref('day')
|
||||
// API调用函数
|
||||
const fetchChartData = async (option: string) => {
|
||||
try {
|
||||
const response:any = await axiosInstance.get(`/awjt/screen/handleByOption/${option}/${props.chartConfig.option.sceneCode}`,{baseURL:''})
|
||||
const response: any = await axiosInstance.get(`/awjt/screen/handleByOption/${option}/${props.chartConfig.option.sceneCode}`, { baseURL: '' })
|
||||
if (response.state === true) {
|
||||
return response.value || []
|
||||
} else {
|
||||
@ -251,41 +251,13 @@ onMounted(() => {
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@include go(border-box) {
|
||||
position: relative;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
// 不渐变
|
||||
// background-color: #0E121B;
|
||||
// 渐变
|
||||
background: linear-gradient(to top,
|
||||
rgba(14, 18, 27, 1) 0%,
|
||||
rgba(14, 18, 27, 0.6) 100%);
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 10px;
|
||||
padding: 2px;
|
||||
/* 边框宽度 */
|
||||
background: linear-gradient(to top,
|
||||
rgba(128, 128, 128, 0.3),
|
||||
rgba(128, 128, 128, 0));
|
||||
-webkit-mask:
|
||||
linear-gradient(#fff, #fff) content-box,
|
||||
linear-gradient(#fff, #fff);
|
||||
-webkit-mask-composite: xor;
|
||||
mask-composite: exclude;
|
||||
pointer-events: none;
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,159 +0,0 @@
|
||||
<template>
|
||||
<div class="custom-select" @click="toggleDropdown">
|
||||
<div class="select-display">
|
||||
<span class="select-text">{{ getSelectedLabel() }}</span>
|
||||
<span class="select-arrow" :class="{ 'arrow-up': isDropdownOpen }">▼</span>
|
||||
</div>
|
||||
<div class="select-dropdown" v-show="isDropdownOpen">
|
||||
<div
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
class="select-option"
|
||||
:class="{ 'selected': item.value === selectedValue }"
|
||||
@click.stop="selectOption(item)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
// 定义props
|
||||
const props = defineProps<{
|
||||
options: Array<{ label: string; value: any }>
|
||||
selectedValue: any
|
||||
}>()
|
||||
|
||||
// 定义emits
|
||||
const emit = defineEmits<{
|
||||
change: [value: any]
|
||||
}>()
|
||||
|
||||
// 响应式数据
|
||||
const isDropdownOpen = ref(false)
|
||||
|
||||
// 切换下拉菜单显示状态
|
||||
const toggleDropdown = (event: Event) => {
|
||||
event.stopPropagation()
|
||||
isDropdownOpen.value = !isDropdownOpen.value
|
||||
}
|
||||
|
||||
// 选择选项
|
||||
const selectOption = (item: any) => {
|
||||
emit('change', item.value)
|
||||
isDropdownOpen.value = false
|
||||
}
|
||||
|
||||
// 获取选中项的标签
|
||||
const getSelectedLabel = () => {
|
||||
const selectedItem = props.options.find(
|
||||
(item: any) => item.value === props.selectedValue
|
||||
)
|
||||
return selectedItem ? selectedItem.label : '请选择'
|
||||
}
|
||||
|
||||
// 点击外部关闭下拉菜单
|
||||
const handleClickOutside = (event: Event) => {
|
||||
const target = event.target as HTMLElement
|
||||
if (!target.closest('.custom-select')) {
|
||||
isDropdownOpen.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 组件挂载时添加全局点击事件监听
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', handleClickOutside)
|
||||
})
|
||||
|
||||
// 组件卸载时移除事件监听
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('click', handleClickOutside)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.custom-select {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 14px;
|
||||
font-size: 12px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.select-display {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 22px;
|
||||
padding: 0 10px;
|
||||
background-color: #086C67;
|
||||
color: #fff;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.select-text {
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.select-arrow {
|
||||
margin-left: 8px;
|
||||
font-size: 10px;
|
||||
transition: transform 0.3s ease;
|
||||
|
||||
&.arrow-up {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
.select-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: #086C67;
|
||||
border-radius: 6px;
|
||||
margin-top: 2px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||
overflow: hidden;
|
||||
animation: slideDown 0.2s ease;
|
||||
}
|
||||
|
||||
.select-option {
|
||||
padding: 10px 12px;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideDown {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
</style>
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 174 KiB |
@ -3,12 +3,13 @@ import { PieCenterConfig } from './index'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import dataJson from './data.json'
|
||||
|
||||
import { chartInitConfig } from '@/settings/designSetting'
|
||||
export const includes = ['legend']
|
||||
|
||||
// 其它配置
|
||||
const otherConfig = {
|
||||
sceneCode:'T04',
|
||||
titleText: "报警统计",
|
||||
sceneCode: 'T04',
|
||||
dateTime: {
|
||||
selectValue: 'day',
|
||||
dataset: [
|
||||
@ -236,4 +237,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
|
||||
public key: string = PieCenterConfig.key
|
||||
public chartConfig = cloneDeep(PieCenterConfig)
|
||||
public option = echartOptionProfixHandle(option, includes)
|
||||
public attr = { ...chartInitConfig, x: 0, y: 0, w: 450, h: 300, zIndex: 1 }
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div class="go-border-box">
|
||||
<img src="./assets/title.svg" class="svg" />
|
||||
<div class="header-title">报警统计</div>
|
||||
<v-chart ref="vChartRef" autoresize :init-options="initOptions" :theme="themeColor" :option="option"></v-chart>
|
||||
<!-- 使用新的下拉选择器组件 -->
|
||||
<CustomSelect :options="option.dateTime.dataset" :selectedValue="option.dateTime.selectValue"
|
||||
@change="handleSelectChange" />
|
||||
<PublicSmallBorder :title-text="option.titleText" :select-option="option.dateTime" @change="handleSelectChange">
|
||||
|
||||
<!-- <div class="content"> -->
|
||||
<v-chart ref="vChartRef" autoresize :init-options="initOptions" :theme="themeColor"
|
||||
:option="option"></v-chart>
|
||||
</PublicSmallBorder>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
@ -25,6 +25,7 @@ import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent, Gra
|
||||
import CustomSelect from './select.vue'
|
||||
import dataJson from './data.json'
|
||||
import axiosInstance from '@/api/axios'
|
||||
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
|
||||
|
||||
const props = defineProps({
|
||||
themeSetting: {
|
||||
@ -285,64 +286,4 @@ const handleSelectChange = async (value: string) => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@include go(border-box) {
|
||||
position: relative;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
// 不渐变
|
||||
// background-color: #0E121B;
|
||||
// 渐变
|
||||
background: linear-gradient(to top,
|
||||
rgba(14, 18, 27, 1) 0%,
|
||||
rgba(14, 18, 27, 0.6) 100%);
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 5px;
|
||||
padding: 2px;
|
||||
/* 边框宽度 */
|
||||
background: linear-gradient(to top,
|
||||
rgba(128, 128, 128, 0.3),
|
||||
rgba(128, 128, 128, 0));
|
||||
-webkit-mask:
|
||||
linear-gradient(#fff, #fff) content-box,
|
||||
linear-gradient(#fff, #fff);
|
||||
-webkit-mask-composite: xor;
|
||||
mask-composite: exclude;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.header-title {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
height: 45px;
|
||||
line-height: 45px;
|
||||
left: 80px;
|
||||
white-space: nowrap;
|
||||
font-family: 'CustomFont';
|
||||
font-style: italic;
|
||||
letter-spacing: 0.5px;
|
||||
color: #eee;
|
||||
text-shadow: 1px 3px 10px #000000;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
|
||||
.svg {
|
||||
width: 100%;
|
||||
height: 45px;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 174 KiB |
@ -1,17 +0,0 @@
|
||||
import { PublicConfigClass } from '@/packages/public'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { SmallBorderConfig } from './index'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
export const option = {
|
||||
colors: ['#1089ff', '#0000ff'],
|
||||
backgroundColor: '#00000000'
|
||||
}
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
public key = SmallBorderConfig.key
|
||||
public chartConfig = cloneDeep(SmallBorderConfig)
|
||||
public option = cloneDeep(option)
|
||||
|
||||
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
<template>
|
||||
<CollapseItem name="边框" :expanded="true">
|
||||
<SettingItemBox
|
||||
:name="`颜色-${index + 1}`"
|
||||
v-for="(item, index) in optionData.colors"
|
||||
:key="index"
|
||||
>
|
||||
<SettingItem name="颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.colors[index]"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem>
|
||||
<n-button
|
||||
size="small"
|
||||
@click="optionData.colors[index] = option.colors[index]"
|
||||
>
|
||||
恢复默认
|
||||
</n-button>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
|
||||
<CollapseItem name="背景" :expanded="true">
|
||||
<SettingItemBox name="颜色">
|
||||
<SettingItem>
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.backgroundColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import {
|
||||
CollapseItem,
|
||||
SettingItemBox,
|
||||
SettingItem
|
||||
} from '@/components/Pages/ChartItemSetting'
|
||||
import { option } from './config'
|
||||
|
||||
const props = defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<typeof option>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
@ -1,17 +0,0 @@
|
||||
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
|
||||
// import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
|
||||
// 曲线图
|
||||
export const SmallBorderConfig: ConfigType = {
|
||||
key: 'SmallBorder',
|
||||
chartKey: 'VSmallBorder',
|
||||
conKey: 'VCSmallBorder',
|
||||
title: '带标题小边框',
|
||||
category: 'MyComponents',
|
||||
categoryName: '自定义组件',
|
||||
package: 'Charts',
|
||||
chartFrame: ChartFrameEnum.COMMON,
|
||||
image: "SmallBorder.png",
|
||||
}
|
||||
|
||||
// 默认导出配置对象
|
||||
export default SmallBorderConfig
|
@ -1,83 +0,0 @@
|
||||
<template>
|
||||
<div class="go-small-border">
|
||||
<div class="border-content">
|
||||
<div class="svg-content">
|
||||
<img src="./assets/title.svg" class="svg" />
|
||||
</div>
|
||||
<div class="content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">export default { name: "SmallBorder" }</script>
|
||||
<style lang="scss" scoped>
|
||||
$border-radius: 10px;
|
||||
$border-width: 2px;
|
||||
$bg-color-start: rgba(14, 18, 27, 1);
|
||||
$bg-color-end: rgba(14, 18, 27, 0.6);
|
||||
$border-gradient-start: rgba(128, 128, 128, 0.3);
|
||||
$border-gradient-end: rgba(128, 128, 128, 0);
|
||||
|
||||
@include go(small-border) {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
& .border-content {
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
border-radius: $border-radius;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background: linear-gradient(to top, $bg-color-start, $bg-color-end);
|
||||
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: $border-radius;
|
||||
padding: $border-width;
|
||||
background: linear-gradient(to top, $border-gradient-start, $border-gradient-end);
|
||||
// 实现边框遮罩效果,只显示边框区域
|
||||
-webkit-mask:
|
||||
linear-gradient(#fff, #fff) content-box,
|
||||
linear-gradient(#fff, #fff);
|
||||
-webkit-mask-composite: xor;
|
||||
mask:
|
||||
linear-gradient(#fff, #fff) content-box,
|
||||
linear-gradient(#fff, #fff);
|
||||
mask-composite: exclude;
|
||||
pointer-events: none; // 确保点击能穿透到下层元素
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
& .svg-content {
|
||||
// z-index: 2;
|
||||
width: 100%;
|
||||
height: 12%;
|
||||
|
||||
.svg {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// background-color: antiquewhite;
|
||||
|
||||
& .svg {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
@ -3,8 +3,9 @@ import { CreateComponentType } from '@/packages/index.d'
|
||||
import { TopAlarmsConfig } from './index'
|
||||
import dataJson from './data.json'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import { chartInitConfig } from '@/settings/designSetting'
|
||||
export const option = {
|
||||
sceneCode: 'T04',
|
||||
sceneCode: 'T05',
|
||||
componentIndexKey: "a",
|
||||
dateTime: {
|
||||
selectValue: 'day',
|
||||
@ -34,24 +35,16 @@ export const option = {
|
||||
|
||||
dataset: dataJson.source,
|
||||
titleText: '未处置报警数TOP5',
|
||||
titleColor: '#eee',
|
||||
titleSize: 16,
|
||||
rankColor: '#5AA1AD',
|
||||
nameColor: '#eeeeee',
|
||||
valueColor: '#eeeeee',
|
||||
barColorStart: '#2f72b5',
|
||||
barColorEnd: '#99C6E6',
|
||||
dropdownOptions: ['当日', '当月', '当年'],
|
||||
dropdownDefault: '当日',
|
||||
iconColor: '#00E5FF',
|
||||
letterSpacing: 0.5,
|
||||
paddingX: 45,
|
||||
paddingY: -5,
|
||||
isShowButton: false
|
||||
}
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
public key = TopAlarmsConfig.key
|
||||
public chartConfig = TopAlarmsConfig
|
||||
public option = cloneDeep(option)
|
||||
|
||||
public attr = { ...chartInitConfig, x: 0, y: 0, w: 450, h: 300, zIndex: 1 }
|
||||
}
|
||||
|
@ -1,40 +1,8 @@
|
||||
<template>
|
||||
<SmallBorder class="SmallBorder">
|
||||
<div class="go-top-alarms">
|
||||
<CustomSelect :options="option.dateTime.dataset" :selectedValue="option.dateTime.selectValue"
|
||||
@change="handleSelectChange" class="top-select" />
|
||||
<div class="header">
|
||||
<div class="title">
|
||||
<div class="title-text">
|
||||
<span :style="{
|
||||
color: option.titleColor,
|
||||
fontSize: option.titleSize + 'px',
|
||||
marginTop: option.paddingY + 'px',
|
||||
marginLeft: option.paddingX + 'px',
|
||||
letterSpacing: option.letterSpacing + 'px'
|
||||
}">{{ option.titleText }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<n-dropdown v-if='option.isShowButton' trigger="hover" :options="dropdownOptions" @select="handleSelect">
|
||||
<div class="dropdown-button">
|
||||
{{ selectedOption }}
|
||||
<div class="arrow-down-icon">
|
||||
<svg viewBox="0 0 1024 1024" width="14" height="14">
|
||||
<path
|
||||
d="M512 768c-6.3 0-12.6-2.4-17.4-7.3L285.3 551.4c-9.8-9.8-9.8-25.6 0-35.4s25.6-9.8 35.4 0L512 707.3l191.3-191.3c9.8-9.8 25.6-9.8 35.4 0s9.8 25.6 0 35.4L529.4 760.7c-4.8 4.9-11.1 7.3-17.4 7.3z"
|
||||
fill="currentColor"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</n-dropdown>
|
||||
<!-- <n-dropdown v-if='option.isShowButton' trigger="hover" :options="dropdownOptions" @select="handleSelect">
|
||||
<div class="dropdown-button">
|
||||
{{ selectedOption }}
|
||||
<svg-icon icon-class="arrow-down" class="arrow-down-icon" />
|
||||
</div>
|
||||
|
||||
</n-dropdown> -->
|
||||
</div>
|
||||
<div class="go-top-alarms">
|
||||
<!-- <CustomSelect :options="option.dateTime.dataset" :selectedValue="option.dateTime.selectValue"
|
||||
@change="handleSelectChange" class="top-select" /> -->
|
||||
<PublicSmallBorder :title-text="option.titleText" :select-option="option.dateTime" @change="handleSelectChange">
|
||||
<div class="content">
|
||||
<ul>
|
||||
<li v-for="(item, index) in displayData" :key="index" class="alarm-item">
|
||||
@ -59,8 +27,8 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</SmallBorder>
|
||||
</PublicSmallBorder>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -71,6 +39,7 @@ import CustomSelect from './select.vue'
|
||||
import axiosInstance from '@/api/axios'
|
||||
import { TopAlarmsConfig } from './index'
|
||||
import axios from 'axios'
|
||||
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<{ option: typeof configOption }>,
|
||||
@ -79,18 +48,10 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const option = computed(() => props.chartConfig.option)
|
||||
const selectedOption = ref(props.chartConfig.option.dropdownDefault)
|
||||
|
||||
// 新增:存储API返回的数据
|
||||
const displayData: any = ref([])
|
||||
|
||||
const dropdownOptions = computed(() => {
|
||||
return props.chartConfig.option.dropdownOptions.map(opt => ({
|
||||
label: opt,
|
||||
key: opt
|
||||
}))
|
||||
})
|
||||
|
||||
// 修改:基于API数据计算进度条宽度
|
||||
const calculateWidth = (value: number) => {
|
||||
if (displayData.value.length === 0 || displayData.value[0].value === 0) {
|
||||
@ -157,9 +118,6 @@ const fetchCorpsData = async (option: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
const handleSelect = (key: string) => {
|
||||
selectedOption.value = key
|
||||
}
|
||||
|
||||
// 修改:处理下拉选择器变化,调用API
|
||||
const handleSelectChange = async (value: any) => {
|
||||
@ -191,26 +149,19 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.SmallBorder {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.go-top-alarms {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-top: -10px;
|
||||
// background-color: #0a162b;
|
||||
padding: 15px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #fff;
|
||||
|
||||
.top-select {
|
||||
top: 20px;
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
// background-color: #00e5ff;
|
||||
}
|
||||
|
||||
.header {
|
||||
@ -260,16 +211,12 @@ onMounted(async () => {
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
margin-top: -15px;
|
||||
padding-right: 10px;
|
||||
font-size: 12.5px;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
height: 90%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
|
@ -2,8 +2,9 @@ import { PublicConfigClass } from '@/packages/public'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { yushiVideoConfig } from './index'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
import { chartInitConfig } from '@/settings/designSetting'
|
||||
export const option = {
|
||||
titleText: '实时视频',
|
||||
sceneCode: 'T04',
|
||||
// 摄像头id
|
||||
dataset: {
|
||||
@ -33,4 +34,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
|
||||
public key = yushiVideoConfig.key
|
||||
public chartConfig = cloneDeep(yushiVideoConfig)
|
||||
public option = cloneDeep(option)
|
||||
public attr = { ...chartInitConfig, x: 0, y: 0, w: 450, h: 300, zIndex: 1 }
|
||||
}
|
||||
|
@ -1,30 +1,32 @@
|
||||
<!-- eslint-disable vue/multi-word-component-names -->
|
||||
<template>
|
||||
<div class="go-border-box">
|
||||
<img src="./assets/title.svg" class="svg" />
|
||||
<div class="header-title">实时视频</div>
|
||||
<div :class="option.isOldStyle ? 'video_title' : 'video_title video_title_new'" v-if="option.showBtn">
|
||||
<div class="title_text" v-if="option.showTree && option.showBtn">{{ option.videoTitle }}</div>
|
||||
<n-select v-if="!option.showTree" class="video_select" placement="top-end"
|
||||
v-model:value="option.selectedDataSource" :options="option.dataSource" :style="`width:${w / 2}px;`"
|
||||
@update:value="handleSelectDataSource" />
|
||||
<n-button tertiary v-else-if="option.showTree && option.showBtn && option.isOldStyle"
|
||||
:class="option.isOldStyle ? 'videoChangBtn' : 'videoChangBtn videoChangBtn_new'"
|
||||
@click="handleClick">切换</n-button>
|
||||
<n-button tertiary v-else-if="option.showTree && option.showBtn && !option.isOldStyle"
|
||||
:class="option.isOldStyle ? 'videoChangBtn' : 'videoChangBtn videoChangBtn_new'"
|
||||
@click="handleClick"></n-button>
|
||||
<PublicSmallBorder :title-text="option.titleText">
|
||||
<div :class="option.isOldStyle ? 'video_title' : 'video_title video_title_new'" v-if="option.showBtn">
|
||||
<div class="title_text" v-if="option.showTree && option.showBtn">{{ option.videoTitle }}</div>
|
||||
<n-select v-if="!option.showTree" class="video_select" placement="top-end"
|
||||
v-model:value="option.selectedDataSource" :options="option.dataSource" :style="`width:${w / 2}px;`"
|
||||
@update:value="handleSelectDataSource" />
|
||||
<n-button tertiary v-else-if="option.showTree && option.showBtn && option.isOldStyle"
|
||||
:class="option.isOldStyle ? 'videoChangBtn' : 'videoChangBtn videoChangBtn_new'"
|
||||
@click="handleClick">切换</n-button>
|
||||
<n-button tertiary v-else-if="option.showTree && option.showBtn && !option.isOldStyle"
|
||||
:class="option.isOldStyle ? 'videoChangBtn' : 'videoChangBtn videoChangBtn_new'"
|
||||
@click="handleClick"></n-button>
|
||||
|
||||
<n-modal v-model:show="showDialog" :mask-closable="false" preset="card" title="选择摄像头"
|
||||
:class="['custom-tab-modal']" :draggable="{ bounds: 'none' }" :style="{ width: '644px', height: '420px' }">
|
||||
<n-tree-select ref="cameraTree" class="cameraTree" :menu-props="{
|
||||
class: 'custom-dropdown'
|
||||
}" v-model:value="option.selectedDataSource" :options="option.dataset.list" clearable
|
||||
:default-expanded-keys="option.expandedKeys" style="width: 615px; margin-top: 16px" :show="isDropdownOpen"
|
||||
@update:show="handleShowChange" @update:value="handleSelectDataSource" />
|
||||
</n-modal>
|
||||
</div>
|
||||
<div ref="vYushiVideoRef" class="go-video" :id="uuid"></div>
|
||||
</PublicSmallBorder>
|
||||
|
||||
|
||||
<n-modal v-model:show="showDialog" :mask-closable="false" preset="card" title="选择摄像头"
|
||||
:class="['custom-tab-modal']" :draggable="{ bounds: 'none' }" :style="{ width: '644px', height: '420px' }">
|
||||
<n-tree-select ref="cameraTree" class="cameraTree" :menu-props="{
|
||||
class: 'custom-dropdown'
|
||||
}" v-model:value="option.selectedDataSource" :options="option.dataset.list" clearable
|
||||
:default-expanded-keys="option.expandedKeys" style="width: 615px; margin-top: 16px" :show="isDropdownOpen"
|
||||
@update:show="handleShowChange" @update:value="handleSelectDataSource" />
|
||||
</n-modal>
|
||||
</div>
|
||||
<div ref="vYushiVideoRef" class="go-video" :id="uuid"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -41,7 +43,7 @@ import { PageEnum } from '@/enums/pageEnum'
|
||||
import axios from 'axios'
|
||||
import { getUUID, isPreview } from '@/utils'
|
||||
import { useYushiVideoStore } from '@/store/modules/yushiVideoStore/yushiVideoStore'
|
||||
|
||||
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
|
||||
const yushiStore = useYushiVideoStore()
|
||||
let selectedList = []
|
||||
|
||||
@ -704,63 +706,3 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (n
|
||||
transform: translateX(7px) translateY(104px) !important;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
@include go(border-box) {
|
||||
position: relative;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
// 不渐变
|
||||
// background-color: #0E121B;
|
||||
// 渐变
|
||||
background: linear-gradient(to top,
|
||||
rgba(14, 18, 27, 1) 0%,
|
||||
rgba(14, 18, 27, 0.6) 100%);
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 5px;
|
||||
padding: 2px;
|
||||
/* 边框宽度 */
|
||||
background: linear-gradient(to top,
|
||||
rgba(128, 128, 128, 0.3),
|
||||
rgba(128, 128, 128, 0));
|
||||
-webkit-mask:
|
||||
linear-gradient(#fff, #fff) content-box,
|
||||
linear-gradient(#fff, #fff);
|
||||
-webkit-mask-composite: xor;
|
||||
mask-composite: exclude;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.header-title {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
height: 45px;
|
||||
line-height: 45px;
|
||||
left: 80px;
|
||||
white-space: nowrap;
|
||||
font-family: 'CustomFont';
|
||||
font-style: italic;
|
||||
letter-spacing: 0.5px;
|
||||
color: #eee;
|
||||
text-shadow: 1px 3px 10px #000000;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.svg {
|
||||
width: 100%;
|
||||
height: 45px;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user