219 lines
5.7 KiB
Vue
219 lines
5.7 KiB
Vue
<script lang="ts" setup>
|
|
import {GridItem, GridLayout} from 'grid-layout-plus'
|
|
import ICard from "~/components/Cards/ICard.vue";
|
|
import IChart from "~/components/Cards/IChart.vue";
|
|
import {type IGridItem, type Layouts, useMainLayoutStore} from "~/strores/UseMainLayoutStore";
|
|
import {UseDraggable} from '@vueuse/components'
|
|
import AddCard from "~/components/AddCard.vue";
|
|
import {type dataHistoryType, useDataStore} from "~/strores/DataStore";
|
|
import _ from "lodash";
|
|
import {useLoadStore} from "~/strores/LoadStore";
|
|
import type {HttpType} from "~/types/baseType";
|
|
import type {UserInfoType} from "~/types/UserType";
|
|
import {deepEqual} from "~/utils";
|
|
|
|
const layout = ref<IGridItem[]>([])
|
|
const presetLayouts = ref<Layouts>(<Layouts>{})
|
|
const {width, height} = useWindowSize()
|
|
const el = ref(null)
|
|
const {width: gridWidth, height: gridHeight} = useElementSize(el)
|
|
const mainLayoutStore = useMainLayoutStore()
|
|
const loadStore = useLoadStore()
|
|
const dataStore = useDataStore()
|
|
onMounted(() => {
|
|
layout.value = mainLayoutStore.LayoutsConfig.lg
|
|
presetLayouts.value = mainLayoutStore.LayoutsConfig
|
|
console.log(layout.value)
|
|
console.log(presetLayouts.value)
|
|
})
|
|
const visible = ref(false)
|
|
const cardVisible = ref(false)
|
|
const items = ref([
|
|
{
|
|
label: '添加图表',
|
|
icon: 'pi pi-chart-line',
|
|
command: () => {
|
|
visible.value = true
|
|
}
|
|
},
|
|
{
|
|
label: '添加信息卡片',
|
|
icon: 'pi pi-plus',
|
|
command: () => {
|
|
cardVisible.value = true
|
|
}
|
|
},
|
|
{
|
|
label: 'Delete',
|
|
icon: 'pi pi-trash',
|
|
command: () => {
|
|
toast.add({severity: 'error', summary: 'Delete', detail: 'Data Deleted'});
|
|
}
|
|
},
|
|
{
|
|
label: 'Upload',
|
|
icon: 'pi pi-upload',
|
|
command: () => {
|
|
router.push('/fileupload');
|
|
}
|
|
},
|
|
{
|
|
label: 'Vue Website',
|
|
icon: 'pi pi-external-link',
|
|
command: () => {
|
|
window.location.href = 'https://vuejs.org/'
|
|
}
|
|
}
|
|
])
|
|
|
|
const layoutChangedEvent = _.throttle((newLayout: IGridItem[]) => {
|
|
let breakPoint = 'lg';
|
|
//计算对应的breakPoint
|
|
if (gridWidth.value <= 1200) {
|
|
breakPoint = 'md';
|
|
}
|
|
if (gridWidth.value <= 992) {
|
|
breakPoint = 'sm';
|
|
}
|
|
if (gridWidth.value <= 768) {
|
|
breakPoint = 'xs';
|
|
}
|
|
mainLayoutStore.LayoutsConfig[breakPoint] = newLayout;
|
|
presetLayouts.value[breakPoint] = newLayout;
|
|
}, 500)
|
|
onMounted(() => {
|
|
$fetch('/Api/User/GetLayoutConfig', {
|
|
method: 'POST',
|
|
responseType: "json",
|
|
body: {
|
|
layout: JSON.stringify(mainLayoutStore.LayoutsConfig),
|
|
},
|
|
headers: {
|
|
'Authorization': 'Bearer ' + useCookie('token').value
|
|
},
|
|
baseURL: useRuntimeConfig().public.baseUrl,
|
|
}).then((res) => {
|
|
if (res === 'null') return;
|
|
const data = JSON.parse(res as string) as Layouts
|
|
console.log(data)
|
|
mainLayoutStore.LayoutsConfig = data;
|
|
presetLayouts.value = data;
|
|
if (loadStore.LayoutLoad) return;
|
|
loadStore.LayoutLoad = true
|
|
window.location.reload()
|
|
})
|
|
})
|
|
watchDebounced(
|
|
layout,
|
|
() => {
|
|
$fetch('/Api/User/PutLayoutConfig', {
|
|
method: 'PUT',
|
|
body: {
|
|
Layout: JSON.stringify(mainLayoutStore.LayoutsConfig),
|
|
},
|
|
headers: {
|
|
'Authorization': 'Bearer ' + useCookie('token').value
|
|
},
|
|
baseURL: useRuntimeConfig().public.baseUrl,
|
|
}).catch((err) => {
|
|
console.log(err)
|
|
})
|
|
},
|
|
{debounce: 15000, maxWait: 60000}
|
|
)
|
|
</script>
|
|
<template>
|
|
<div class="main-grid-layout">
|
|
<UseDraggable v-slot="{x,y}"
|
|
:initial-value="{ x: width-150, y: height-350 }"
|
|
class="draggable-action"
|
|
>
|
|
<SpeedDial :model="items"
|
|
:radius="80"
|
|
:tooltipOptions="{ position: 'right' }"
|
|
type="circle"/>
|
|
</UseDraggable>
|
|
<Dialog
|
|
v-model:visible="visible"
|
|
:pt="{
|
|
root: {
|
|
style:'border:unset;background-color:unset;'
|
|
},
|
|
mask: {
|
|
style: 'backdrop-filter: blur(20px)'
|
|
}
|
|
}"
|
|
modal
|
|
>
|
|
<template #container="{ closeCallback }">
|
|
<SettingCard :close-callback="closeCallback"/>
|
|
</template>
|
|
</Dialog>
|
|
<Dialog
|
|
v-model:visible="cardVisible"
|
|
:pt="{
|
|
root: {
|
|
style:'border:unset;background-color:unset;'
|
|
},
|
|
mask: {
|
|
style: 'backdrop-filter: blur(20px)'
|
|
}
|
|
|
|
}"
|
|
modal
|
|
>
|
|
<template #container="{ closeCallback }">
|
|
<AddCard :close-callback="closeCallback"/>
|
|
</template>
|
|
</Dialog>
|
|
<GridLayout
|
|
ref="el"
|
|
v-model:layout="layout"
|
|
:breakpoints="{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }"
|
|
:col-num="16"
|
|
:cols="{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }"
|
|
:responsive-layouts="presetLayouts"
|
|
:row-height="30"
|
|
is-draggable
|
|
is-resizables
|
|
responsive
|
|
use-css-transforms
|
|
vertical-compact
|
|
@layoutUpdated="layoutChangedEvent"
|
|
>
|
|
<GridItem
|
|
v-for="item in layout"
|
|
:key="item.i"
|
|
:h="item.h"
|
|
:i="item.i"
|
|
:w="item.w"
|
|
:x="item.x"
|
|
:y="item.y"
|
|
drag-allow-from=".vue-draggable-handle"
|
|
drag-ignore-from=".no-drag"
|
|
>
|
|
<IChart v-if="item.type==='chart'&&item.serverValues&&item.selectChart" :id="String(item.i)"
|
|
:chart="item.selectChart"
|
|
:title="item.cardConfig?.['name'].value??'默认标题'" :values="item.serverValues"/>
|
|
<ICard v-if="item.type==='card'&&item.selectCard" :id="String(item.i)" :card-id="item.selectCard"/>
|
|
</GridItem>
|
|
</GridLayout>
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.main-grid-layout {
|
|
//min-width: 950px;
|
|
}
|
|
|
|
.draggable-action {
|
|
background: red;
|
|
position: fixed;
|
|
z-index: 100;
|
|
}
|
|
|
|
.vgl-layout {
|
|
margin: -10px;
|
|
}
|
|
</style> |