This commit is contained in:
hujiale 2024-10-24 11:49:12 +08:00
parent fde6c4cb9e
commit 57d40475cd
3 changed files with 1705 additions and 1489 deletions

View File

@ -1,36 +1,65 @@
<template>
<div class="custom-card w-[100%] h-[100%] flex flex-col">
<div class="card-name titlt-top" v-if="isEdit"><div>我的应用</div><EditOutlined /></div>
<div class="card-name titlt-top" v-else >
<Input v-model:value="cardName" >
<template #addonAfter>
<CheckOutlined />
</template>
</Input></div>
<GridGroup :list="data.childer" class="flex-1"></GridGroup>
</div>
</template>
<script setup lang="ts">
import { toRefs ,ref} from 'vue'
import { ref, toRefs } from 'vue';
import {
CheckOutlined,
CloseOutlined,
EditOutlined,
} from '@ant-design/icons-vue';
import { Input, Space } from 'ant-design-vue';
import GridGroup from '../GridGroup/index.vue';
import { CheckOutlined,EditOutlined} from '@ant-design/icons-vue';
import { Input } from 'ant-design-vue';
let cardName = ref('我的应用')
const props = defineProps({
data: {
type: Object,
default: {}
default: {},
},
})
let isEdit = ref(true)
console.log('propsprops', props.data);
let { data } = toRefs(props);
});
const cardName = ref(props.data.name);
const newCardName = ref(cardName.value);
const isEdit = ref(true);
const setNewName = () => {
isEdit.value = !isEdit.value;
cardName.value = newCardName.value;
};
const { data } = toRefs(props);
</script>
<template>
<div class="custom-card flex h-[100%] w-[100%] flex-col">
<div
v-if="isEdit"
class="card-name titlt-top flex items-center justify-between"
>
<div>{{ cardName }}</div>
<EditOutlined
class="cursor-pointer"
style="font-size: 16px"
@click="isEdit = !isEdit"
/>
</div>
<div v-else class="card-name titlt-top">
<Input
v-model:value="newCardName"
:autofocus="true"
:bordered="false"
size="small"
>
<template #addonAfter>
<Space warp>
<CheckOutlined @click="setNewName" />
<CloseOutlined @click="isEdit = !isEdit" />
</Space>
</template>
</Input>
</div>
<GridGroup :list="data.childer" class="flex-1" />
</div>
</template>
<style lang="scss" scoped>
.card-name {
font-weight: 500;
padding: 5px 0;
border-bottom: 1px solid #ddd;
}
</style>
</style>

View File

@ -1,15 +1,38 @@
<script setup>
import { defineAsyncComponent, getCurrentInstance, markRaw, onMounted, ref, nextTick } from 'vue';
import {
defineAsyncComponent,
getCurrentInstance,
markRaw,
nextTick,
onMounted,
ref,
} from 'vue';
import { useRouter } from 'vue-router';
import { UndoOutlined, CheckOutlined, CloseCircleFilled, QuestionCircleOutlined, SyncOutlined, ShoppingCartOutlined, EditOutlined } from '@ant-design/icons-vue';
import { CheckboxGroup, Checkbox, Collapse, CollapsePanel, FloatButtonGroup, FloatButton, BackTop, Popover } from 'ant-design-vue';
import {
CheckOutlined,
CloseCircleFilled,
EditOutlined,
ShoppingCartOutlined,
UndoOutlined,
} from '@ant-design/icons-vue';
import {
Button,
Checkbox,
CheckboxGroup,
Collapse,
CollapsePanel,
FloatButton,
FloatButtonGroup,
Popover,
} from 'ant-design-vue';
import { storeToRefs } from 'pinia';
import { tilesList } from './tiles'
import { useRouter } from "vue-router";
import { UseTilesStore } from '#/store';
import { storeToRefs } from 'pinia'
const tilesStore = UseTilesStore();
import { tilesList } from './tiles';
const tilesStore = UseTilesStore();
const router = useRouter();
@ -18,18 +41,17 @@ const router = useRouter();
const { proxy, ctx: that } = getCurrentInstance();
const layout = ref([]);
onMounted(() => {
let layoutStr = JSON.parse(localStorage.getItem('layout'));
const layoutStr = JSON.parse(localStorage.getItem('layout'));
if (layoutStr && layoutStr.length > 0) {
for (let i = 0; i < layoutStr.length; i++) {
if (layoutStr[i]&&layoutStr[i].component) {
// layoutStr[i].component = loadComponent(layoutStr[i].component);
}
}
layout.value = layoutStr
// for (const element of layoutStr) {
// if (element && element.component) {
// layoutStr[i].component = loadComponent(layoutStr[i].component);
// }
// }
layout.value = layoutStr;
}
console.log('oooo',layout.value);
})
console.log('oooo', layout.value);
});
const colNum = 12;
let defaultH = 2;
let defaultW = 2;
@ -44,7 +66,7 @@ const DragPos = {
h: null,
i: null,
};
const componentsInfo = tilesList
const componentsInfo = tilesList;
let currentDragCom = null;
onMounted(() => {
document.addEventListener(
@ -111,7 +133,7 @@ const drag = (e, item) => {
try {
proxy.$refs.gridItem[layout.value.length - 1].$refs.item.style.display =
'none';
} catch { }
} catch {}
const el = proxy.$refs.gridItem ? proxy.$refs.gridItem[index] : null;
if (el) {
@ -198,12 +220,12 @@ const dragend = (e) => {
try {
proxy.$refs.gridItem[layout.value.length].$refs.item.style.display =
'block';
} catch {
}
} catch {}
}
nextTick(() => {
// eslint-disable-next-line no-use-before-define
tilesIsMove.value = true;
})
});
};
// resize使resize
const resizedEvent = (e) => {
@ -221,73 +243,142 @@ const delItem = (item) => {
};
//
let shop = ref(false)
const shop = ref(false);
//
let editTiles = ref(false)
const editTiles = ref(false);
//
let activeKeyArr = ref(['1', '2', '3'])
const activeKeyArr = ref(['1', '2', '3']);
//
let selectTilseArr = ref([])
const selectTilseArr = ref([]);
//
let addTiles = (val) => {
let arr = JSON.parse(JSON.stringify(selectTilseArr.value))
const addTiles = (val) => {
let arr = JSON.parse(JSON.stringify(selectTilseArr.value));
if (arr.includes(val)) {
arr = arr.filter((item) => {
return item != val
})
return item != val;
});
} else {
arr.push(val)
arr.push(val);
}
selectTilseArr.value = arr
}
selectTilseArr.value = arr;
};
//
let { tilesIsMove } = storeToRefs(tilesStore)
let { tilesIsMove } = storeToRefs(tilesStore);
//
let cancelOrSure = (type) => {
const cancelOrSure = (type) => {
if (type == 'cance') {
editTiles.value = false;
tilesStore.setTilesIsMove(false)
layout.value = layout.value.filter((item) => {
return !item.isNew
})
tilesStore.setTilesIsMove(false);
const layoutStr = JSON.parse(localStorage.getItem('layout'));
if (layoutStr && layoutStr.length > 0) {
for (const element of layoutStr) {
if (element && element.component) {
element.loadComp = loadComponent(element.component);
}
}
layout.value = layoutStr;
}
} else if (type == 'sure') {
editTiles.value = false;
tilesStore.setTilesIsMove(false)
tilesStore.setTilesIsMove(false);
layout.value.forEach((element, index) => {
delete element.isNew
delete element.isNew;
});
let newLayout = JSON.parse(JSON.stringify(layout.value));
const newLayout = JSON.parse(JSON.stringify(layout.value));
window.localStorage.setItem('layout', JSON.stringify(newLayout));
} else if (type == 'edit') {
editTiles.value = true;
tilesStore.setTilesIsMove(true)
tilesStore.setTilesIsMove(true);
}
}
};
//
let goPage = (item) => {
const goPage = (item) => {
if (tilesIsMove.value) return;
router.push(item?.path);
}
};
//
const addGroup = () => {
const arr = JSON.parse(JSON.stringify(layout.value));
const maxY = arr.reduce((max, item) => {
return Math.max(max, item.y);
}, -Infinity);
const obj = {
name: '新建分组',
w: 4,
h: 6,
component: './components/Output5/index.vue',
dom: '.titlt-top',
isResize: true,
X: 0,
y: 0,
i: Math.random() * 100,
loadComp: loadComponent('./components/Output5/index.vue'),
childer: [
{
name1: 'AUTO_1612159241967.png',
name2: 'AUTO_1612159241967_C车辆调度.png',
size: '2x2',
name: '车辆调度',
w: 1,
h: 2,
i: 0,
x: 1,
y: 1,
component: '../../components/Output1/index.vue',
},
],
};
layout.value.push(obj);
console.log(layout.value, '00000');
};
</script>
<template>
<div class="container h-[calc(100%-10px)] px-[20px]">
<!-- 自定义布局的部分 -->
<div class="grid-box select-none index-grid">
<grid-layout ref="gridLayout" v-model:layout="layout" :col-num="12" :is-draggable="tilesIsMove"
:is-mirrored="false" :auto-size="false" :responsive="false" :is-resizable="tilesIsMove" :margin="[10, 10]"
:row-height="70" :vertical-compact="true">
<grid-item v-for="(item, index ) in layout" :key="item.i" ref="gridItem" :h="item.h" :i="item.i" :w="item.w"
:x="item.x" :y="item.y" :dragAllowFrom="item && item.dom ? item.dom : null"
:isResizable="tilesIsMove && item && item.isResize ? item.isResize : false" @resized="resizedEvent">
<span class="close" @click="delItem(item)" v-if="tilesIsMove">
<CloseCircleFilled style="color: #f10215;" />
<div class="grid-box index-grid select-none">
<Button type="primary" @click="addGroup">新增分组</Button>
<grid-layout
ref="gridLayout"
v-model:layout="layout"
:auto-size="false"
:col-num="12"
:is-draggable="tilesIsMove"
:is-mirrored="false"
:is-resizable="tilesIsMove"
:margin="[10, 10]"
:responsive="false"
:row-height="70"
:vertical-compact="true"
>
<grid-item
v-for="(item, index) in layout"
:key="item.i"
ref="gridItem"
:drag-allow-from="item && item.dom ? item.dom : null"
:h="item.h"
:i="item.i"
:is-resizable="
tilesIsMove && item && item.isResize ? item.isResize : false
"
:w="item.w"
:x="item.x"
:y="item.y"
@resized="resizedEvent"
>
<span v-if="tilesIsMove" class="close" @click="delItem(item)">
<CloseCircleFilled style="color: #f10215" />
</span>
<div class="py-2 px-4 box-border w-[100%] h-[100%] us-card-box bg-background" @click="goPage(item)">
<component :is="item.loadComp" :data="item" :key="item.i" />
<div
class="us-card-box bg-background box-border h-[100%] w-[100%] px-4 py-2"
@click="goPage(item)"
>
<component :is="item.loadComp" :key="item.i" :data="item" />
</div>
</grid-item>
@ -300,113 +391,207 @@ let goPage = (item) => {
</div>
<!-- 右侧悬浮部分 -->
<FloatButtonGroup shape="circle" :style="{ right: '40px' }">
<FloatButtonGroup :style="{ right: '40px' }" shape="circle">
<template v-if="!editTiles">
<FloatButton tooltip="编辑磁贴" @click="cancelOrSure('edit')">
<template #icon>
<EditOutlined style="font-size: 20px;" />
<EditOutlined style="font-size: 20px" />
</template>
</FloatButton>
</template>
<template v-else>
<FloatButton tooltip="保存修改" @click="cancelOrSure('sure')">
<template #icon>
<CheckOutlined style="font-size: 20px;" />
<CheckOutlined style="font-size: 20px" />
</template>
</FloatButton>
<FloatButton tooltip="取消修改" @click="cancelOrSure('cance')">
<template #icon>
<UndoOutlined style="font-size: 20px;" />
<UndoOutlined style="font-size: 20px" />
</template>
</FloatButton>
<Popover v-model:open="shop" title="磁贴商店127" trigger="click" placement="topRight">
<Popover
v-model:open="shop"
placement="topRight"
title="磁贴商店127"
trigger="click"
>
<template #content>
<div class="shop-box">
<CheckboxGroup style="width: 100%" v-model:value="selectTilseArr">
<Collapse v-model:activeKey="activeKeyArr" style="width: 100%">
<CheckboxGroup v-model:value="selectTilseArr" style="width: 100%">
<Collapse v-model:active-key="activeKeyArr" style="width: 100%">
<CollapsePanel key="1" header="个人工作台22">
<!-- 可拖入的组件部分 -->
<div class="components-box">
<div v-for="item in componentsInfo.slice(0, 22)" :key="item.name" class="ctrl-box bg-background"
draggable="true" @drag="drag" @dragend="dragend($event)" @dragstart="dragstart($event, item)"
@click="addTiles(item.name)" :class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '(' + item.size + ')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" class="absolute bottom-0 right-1" />
<div
v-for="item in componentsInfo.slice(0, 22)"
:key="item.name"
:class="{ active: selectTilseArr.includes(item.name) }"
class="ctrl-box bg-background"
draggable="true"
@click="addTiles(item.name)"
@drag="drag"
@dragend="dragend($event)"
@dragstart="dragstart($event, item)"
>
<div class="ctrl-name">
{{ `${item.name}(${item.size})` }}
</div>
<img :src="`/xbyt/${item.name2}`" alt="" />
<Checkbox
:value="item.name"
class="absolute bottom-0 right-1"
/>
</div>
</div>
</CollapsePanel>
<CollapsePanel key="2" header="综合行政12">
<div class="components-box">
<div v-for="item in componentsInfo.slice(22, 34)" :key="item.name" class="ctrl-box bg-background"
draggable="true" @drag="drag" @dragend="dragend" @dragstart="dragstart($event, item)"
@click="addTiles(item.name)" :class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '(' + item.size + ')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" :checked="selectTilseArr.includes(item.name)"
class="absolute bottom-0 right-1" />
<div
v-for="item in componentsInfo.slice(22, 34)"
:key="item.name"
:class="{ active: selectTilseArr.includes(item.name) }"
class="ctrl-box bg-background"
draggable="true"
@click="addTiles(item.name)"
@drag="drag"
@dragend="dragend"
@dragstart="dragstart($event, item)"
>
<div class="ctrl-name">
{{ `${item.name}(${item.size})` }}
</div>
<img :src="`/xbyt/${item.name2}`" alt="" />
<Checkbox
:checked="selectTilseArr.includes(item.name)"
:value="item.name"
class="absolute bottom-0 right-1"
/>
</div>
</div>
</CollapsePanel>
<CollapsePanel key="3" header="经营管理22">
<div class="components-box">
<div v-for="item in componentsInfo.slice(34, 56)" :key="item.name" class="ctrl-box bg-background"
draggable="true" @drag="drag" @dragend="dragend" @dragstart="dragstart($event, item)"
@click="addTiles(item.name)" :class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '(' + item.size + ')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" :checked="selectTilseArr.includes(item.name)"
class="absolute bottom-0 right-1" />
<div
v-for="item in componentsInfo.slice(34, 56)"
:key="item.name"
:class="{ active: selectTilseArr.includes(item.name) }"
class="ctrl-box bg-background"
draggable="true"
@click="addTiles(item.name)"
@drag="drag"
@dragend="dragend"
@dragstart="dragstart($event, item)"
>
<div class="ctrl-name">
{{ `${item.name}(${item.size})` }}
</div>
<img :src="`/xbyt/${item.name2}`" alt="" />
<Checkbox
:checked="selectTilseArr.includes(item.name)"
:value="item.name"
class="absolute bottom-0 right-1"
/>
</div>
</div>
</CollapsePanel>
<CollapsePanel key="4" header="安全生产19">
<div class="components-box">
<div v-for="item in componentsInfo.slice(56, 75)" :key="item.name" class="ctrl-box bg-background"
draggable="true" @drag="drag" @dragend="dragend" @dragstart="dragstart($event, item)"
@click="addTiles(item.name)" :class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '(' + item.size + ')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" :checked="selectTilseArr.includes(item.name)"
class="absolute bottom-0 right-1" />
<div
v-for="item in componentsInfo.slice(56, 75)"
:key="item.name"
:class="{ active: selectTilseArr.includes(item.name) }"
class="ctrl-box bg-background"
draggable="true"
@click="addTiles(item.name)"
@drag="drag"
@dragend="dragend"
@dragstart="dragstart($event, item)"
>
<div class="ctrl-name">
{{ `${item.name}(${item.size})` }}
</div>
<img :src="`/xbyt/${item.name2}`" alt="" />
<Checkbox
:checked="selectTilseArr.includes(item.name)"
:value="item.name"
class="absolute bottom-0 right-1"
/>
</div>
</div>
</CollapsePanel>
<CollapsePanel key="5" header="勘探开发26">
<div class="components-box">
<div v-for="item in componentsInfo.slice(75, 101)" :key="item.name" class="ctrl-box bg-background"
draggable="true" @drag="drag" @dragend="dragend" @dragstart="dragstart($event, item)"
@click="addTiles(item.name)" :class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '(' + item.size + ')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" :checked="selectTilseArr.includes(item.name)"
class="absolute bottom-0 right-1" />
<div
v-for="item in componentsInfo.slice(75, 101)"
:key="item.name"
:class="{ active: selectTilseArr.includes(item.name) }"
class="ctrl-box bg-background"
draggable="true"
@click="addTiles(item.name)"
@drag="drag"
@dragend="dragend"
@dragstart="dragstart($event, item)"
>
<div class="ctrl-name">
{{ `${item.name}(${item.size})` }}
</div>
<img :src="`/xbyt/${item.name2}`" alt="" />
<Checkbox
:checked="selectTilseArr.includes(item.name)"
:value="item.name"
class="absolute bottom-0 right-1"
/>
</div>
</div>
</CollapsePanel>
<CollapsePanel key="6" header="数据管理1">
<div class="components-box">
<div v-for="item in componentsInfo.slice(101, 102)" :key="item.name"
class="ctrl-box bg-background" draggable="true" @drag="drag" @dragend="dragend"
@dragstart="dragstart($event, item)" @click="addTiles(item.name)"
:class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '(' + item.size + ')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" :checked="selectTilseArr.includes(item.name)"
class="absolute bottom-0 right-1" />
<div
v-for="item in componentsInfo.slice(101, 102)"
:key="item.name"
:class="{ active: selectTilseArr.includes(item.name) }"
class="ctrl-box bg-background"
draggable="true"
@click="addTiles(item.name)"
@drag="drag"
@dragend="dragend"
@dragstart="dragstart($event, item)"
>
<div class="ctrl-name">
{{ `${item.name}(${item.size})` }}
</div>
<img :src="`/xbyt/${item.name2}`" alt="" />
<Checkbox
:checked="selectTilseArr.includes(item.name)"
:value="item.name"
class="absolute bottom-0 right-1"
/>
</div>
</div>
</CollapsePanel>
<CollapsePanel key="7" header="总部系统25">
<div class="components-box">
<div v-for="item in componentsInfo.slice(102, 127)" :key="item.name"
class="ctrl-box bg-background" draggable="true" @drag="drag" @dragend="dragend"
@dragstart="dragstart($event, item)" @click="addTiles(item.name)"
:class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '(' + item.size + ')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" :checked="selectTilseArr.includes(item.name)"
class="absolute bottom-0 right-1" />
<div
v-for="item in componentsInfo.slice(102, 127)"
:key="item.name"
:class="{ active: selectTilseArr.includes(item.name) }"
class="ctrl-box bg-background"
draggable="true"
@click="addTiles(item.name)"
@drag="drag"
@dragend="dragend"
@dragstart="dragstart($event, item)"
>
<div class="ctrl-name">
{{ `${item.name}(${item.size})` }}
</div>
<img :src="`/xbyt/${item.name2}`" alt="" />
<Checkbox
:checked="selectTilseArr.includes(item.name)"
:value="item.name"
class="absolute bottom-0 right-1"
/>
</div>
</div>
</CollapsePanel>
@ -416,7 +601,10 @@ let goPage = (item) => {
</template>
<FloatButton tooltip="磁贴商店">
<template #icon>
<ShoppingCartOutlined style="font-size: 20px;" :visibility-height="0" />
<ShoppingCartOutlined
:visibility-height="0"
style="font-size: 20px"
/>
</template>
</FloatButton>
</Popover>
@ -476,11 +664,10 @@ let goPage = (item) => {
margin-bottom: 8px;
}
img {
width: 100%;
// height: 100%;
object-fit: contain
object-fit: contain;
}
}
}
@ -498,7 +685,7 @@ let goPage = (item) => {
</style>
<style lang="scss" scoped>
.index-grid>:deep(.vue-grid-layout) {
.index-grid > :deep(.vue-grid-layout) {
height: 100% !important;
overflow: auto;
background: transparent;

File diff suppressed because it is too large Load Diff