Merge branch 'test' of http://49.233.254.41:5256/z9130/pansoft-plrl into test
Frontend CI/CD / build (web-office) (push) Failing after 6s Details

This commit is contained in:
hujiale 2024-10-25 12:39:38 +08:00
commit 2149877576
7 changed files with 218 additions and 37 deletions

View File

@ -0,0 +1,19 @@
import { ref } from 'vue';
import { defineStore } from 'pinia';
export const useCanvasStore = defineStore('canvas', () => {
// 存储孙组件的 gridLayoutRef,以id为key
const gridLayoutRefs = ref(new Map());
// 设置 gridLayoutRef
const setGridLayoutRef = (id: string, refValue: any) => {
// id 格式化为字符串格式
gridLayoutRefs.value.set(`${id}`, refValue);
};
return {
gridLayoutRefs,
setGridLayoutRef,
};
});

View File

@ -1,2 +1,3 @@
export * from './auth'; export * from './auth';
export * from './tiles' export * from './canvas';
export * from './tiles';

View File

@ -1,14 +1,14 @@
import {defineStore} from 'pinia' import { defineStore } from 'pinia';
export const UseTilesStore = defineStore('tiles',{
export const UseTilesStore = defineStore('tiles', {
state: () => { state: () => {
return { return {
tilesIsMove : !1, // 磁贴是否是可编辑状态 tilesIsMove: !1, // 磁贴是否是可编辑状态
};
}
}, },
actions: { actions: {
setTilesIsMove(data: boolean){ setTilesIsMove(data: boolean) {
this.tilesIsMove = data this.tilesIsMove = data;
} },
} },
}) });

View File

@ -14,7 +14,7 @@ import {
import { CloseCircleFilled } from '@ant-design/icons-vue'; import { CloseCircleFilled } from '@ant-design/icons-vue';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { UseTilesStore } from '#/store'; import { useCanvasStore, UseTilesStore } from '#/store';
import { import {
debounce, debounce,
@ -23,6 +23,10 @@ import {
} from '../../utils'; } from '../../utils';
const props = defineProps({ const props = defineProps({
i: {
type: String,
default: '',
},
list: { list: {
type: Object, type: Object,
default: [], default: [],
@ -31,6 +35,7 @@ const props = defineProps({
const emit = defineEmits(['provideGridLayoutRef']); const emit = defineEmits(['provideGridLayoutRef']);
const canvasStore = useCanvasStore();
const tilesStore = UseTilesStore(); const tilesStore = UseTilesStore();
const { list } = toRefs(props); const { list } = toRefs(props);
@ -303,8 +308,21 @@ onMounted(() => {
nextTick(() => { nextTick(() => {
console.log('我是孙组件', gridLayoutRef.value); console.log('我是孙组件', gridLayoutRef.value);
emit('provideGridLayoutRef', gridLayoutRef); canvasStore.setGridLayoutRef(props.i, gridLayoutRef.value);
}); });
// const boxes = document.querySelectorAll(`#${domId}`);
// // box
// boxes.forEach((box) => {
// box.addEventListener('mouseover', () => {
// console.log(`: ${box.id}`);
// });
// box.addEventListener('mouseout', () => {
// console.log(`: ${box.id}`);
// });
// });
}); });
defineExpose({ defineExpose({
gridLayoutRef: gridLayoutRef.value, gridLayoutRef: gridLayoutRef.value,

View File

@ -11,12 +11,18 @@ import { Input, Space } from 'ant-design-vue';
import GridGroup from '../GridGroup/index.vue'; import GridGroup from '../GridGroup/index.vue';
const props = defineProps({ const props = defineProps({
//
i: {
type: String,
default: '',
},
data: { data: {
type: Object, type: Object,
default: {}, default: {},
}, },
}); });
const emits = defineEmits(['editGroupName']); const emits = defineEmits(['editGroupName', 'provideGridLayoutRef']);
const cardName = ref(props.data.name); const cardName = ref(props.data.name);
const newCardName = ref(cardName.value); const newCardName = ref(cardName.value);
const isEdit = ref(true); const isEdit = ref(true);
@ -37,6 +43,7 @@ setTimeout(() => {
const handleGridLayoutRef = (ref) => { const handleGridLayoutRef = (ref) => {
// ref // ref
console.log('子组件 B 收到孙组件的 ref:', ref.value); console.log('子组件 B 收到孙组件的 ref:', ref.value);
emits('provideGridLayoutRef', ref.value);
}; };
defineExpose({ defineExpose({
@ -70,6 +77,7 @@ defineExpose({
</div> </div>
<GridGroup <GridGroup
ref="gridLayoutRef" ref="gridLayoutRef"
:i="props.i"
:list="data.childer" :list="data.childer"
class="flex-1" class="flex-1"
@provide-grid-layout-ref="handleGridLayoutRef" @provide-grid-layout-ref="handleGridLayoutRef"

View File

@ -1,8 +1,7 @@
<script setup> <script setup lang="ts">
import { import {
defineAsyncComponent, defineAsyncComponent,
getCurrentInstance, getCurrentInstance,
inject,
markRaw, markRaw,
nextTick, nextTick,
onBeforeUnmount, onBeforeUnmount,
@ -38,15 +37,18 @@ import {
} from 'ant-design-vue'; } from 'ant-design-vue';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { UseTilesStore } from '#/store'; import { useCanvasStore, UseTilesStore } from '#/store';
import { tilesList } from './tiles'; import { tilesList } from './tiles';
import { debounce, updateRowHeight } from './utils'; import { debounce, isElementInFolder, isGroup, updateRowHeight } from './utils';
const tilesStore = UseTilesStore(); const tilesStore = UseTilesStore();
const canvasStore = useCanvasStore();
const router = useRouter(); const router = useRouter();
/** 是否拖动中 */
const isDragging = ref(false);
// ref map // ref map
const componentsRef = ref(new Map()); const componentsRef = ref(new Map());
// ref // ref
@ -93,22 +95,18 @@ const rowHeight = ref(0);
/** 屏幕宽度 */ /** 屏幕宽度 */
const screenW = ref(0); const screenW = ref(0);
/** 记录当前拖动的元素 */
const currentDragItem = ref(null);
// updateRowHeight 200ms // updateRowHeight 200ms
const debouncedUpdateRowHeight = debounce(() => { const debouncedUpdateRowHeight = debounce(() => {
rowHeight.value = updateRowHeight('#container-canvas'); rowHeight.value = updateRowHeight('#container-canvas');
}, 0); }, 0);
// 使 inject C ref
const gridLayoutRef = inject('gridLayoutRef');
onMounted(() => { onMounted(() => {
window.addEventListener('resize', debouncedUpdateRowHeight); window.addEventListener('resize', debouncedUpdateRowHeight);
rowHeight.value = updateRowHeight('#container-canvas'); // rowHeight.value = updateRowHeight('#container-canvas'); //
setTimeout(() => {
console.log(gridLayoutRef); // C ref
}, 1000);
document.addEventListener( document.addEventListener(
'dragover', 'dragover',
(e) => { (e) => {
@ -123,6 +121,29 @@ onMounted(() => {
event.preventDefault(); event.preventDefault();
}); });
processLayout(layout.value); processLayout(layout.value);
document.addEventListener('mousemove', (event) => {
//
const mouseX = event.clientX;
const mouseY = event.clientY;
console.log('mousemove', mouseX, mouseY);
// 使 elementFromPoint
const hoveredElement = document.elementFromPoint(mouseX, mouseY);
//
if (hoveredElement) {
console.log('hoveredElement', hoveredElement);
const gridItem = hoveredElement.closest('.grid-item');
if (gridItem) {
console.log('鼠标松开时位于 grid-item 上:', gridItem);
console.log('grid-item ID:', gridItem.dataset.id);
} else {
console.log('鼠标松开时不在任何 grid-item 上');
}
// console.log(`: ${hoveredElement.id || hoveredElement.tagName}`);
}
});
}); });
// //
@ -290,13 +311,52 @@ const resizedEvent = (e) => {
const domIdxxxxx = ref(null); const domIdxxxxx = ref(null);
/** 布局更新事件 */ /** 布局更新事件,也是元素拖动结束事件 */
const layoutUpdatedEvent = (e) => { const layoutUpdatedEvent = (e) => {
// dom // dom,map
// gridLayoutRefs map
if (isDragging.value) {
tilesIsMove.value = false;
const groups = [];
const gridLayoutRefs = canvasStore.gridLayoutRefs;
console.log(layout.value);
for (const item of layout.value) {
if (isGroup(item.component)) {
groups.push(item);
}
}
// for (const [key, value] of gridLayoutRefs) {
// console.log(`: ${key}, :`, value);
// }
console.log('分组元素dom', JSON.parse(JSON.stringify(groups)));
//
const dragItem = currentDragItem.value;
console.log('当前拖动的元素', dragItem);
//
const folderId = isElementInFolder(dragItem, groups);
console.log('当前拖动的元素是否进入目标画布区域', folderId);
// const dom = gridLayoutRefs.get('7303');
// console.log(dom);
// dragItem.component = pathToComponent(dragItem.component, 'component');
// dom.layout.push({ ...dragItem, i: generateRandomString(12) });
// delItem(dragItem);
// console.log(domIdxxxxx.value); // console.log(domIdxxxxx.value);
// console.log(dom); // console.log(dom);
console.log('layoutUpdatedEvent', e); console.log('layoutUpdatedEvent', e);
isDragging.value = false;
nextTick(() => {
tilesIsMove.value = true;
});
}
}; };
/** /**
@ -325,6 +385,7 @@ const checkIfOverTargetCanvas = (item) => {
return isOver; return isOver;
}; };
//
const moveEvent = (e) => { const moveEvent = (e) => {
// //
const group = findGroup(); const group = findGroup();
@ -336,8 +397,10 @@ const moveEvent = (e) => {
// console.log(dom); // console.log(dom);
if (dom !== -1) { if (dom !== -1) {
isDragging.value = true;
targetLayout.value = layout.value[dom]; targetLayout.value = layout.value[dom];
console.log(layout.value[dom]); console.log(layout.value[dom]);
currentDragItem.value = layout.value[dom];
// //
checkIfOverTargetCanvas(e); checkIfOverTargetCanvas(e);
} }
@ -455,6 +518,18 @@ const addGroup = () => {
}); });
}; };
const receiveGridLayoutRef = (ref) => {
console.log('我是父组件', ref);
ref.layout.val;
console.log(ref.layout);
setTimeout(() => {
console
.log
// ref.layout.push(),
();
}, 2000);
};
// //
const editGroupName = (i, name) => { const editGroupName = (i, name) => {
layout.value.forEach((element) => { layout.value.forEach((element) => {
@ -488,7 +563,7 @@ const formState = reactive({
<template> <template>
<div id="container-canvas" class="container h-[calc(100%-10px)] px-[20px]"> <div id="container-canvas" class="container h-[calc(100%-10px)] px-[20px]">
<!-- 自定义布局的部分 --> <!-- 自定义布局的部分 -->
<!-- {{ screenW }} - {{ rowHeight }} {{ screenW }} - {{ rowHeight }}
<div class="layoutJSON"> <div class="layoutJSON">
Displayed as <code>[x, y, w, h]</code>: Displayed as <code>[x, y, w, h]</code>:
@ -498,7 +573,7 @@ const formState = reactive({
>: [{{ item.x }}, {{ item.y }}, {{ item.w }}, {{ item.h }}] >: [{{ item.x }}, {{ item.y }}, {{ item.w }}, {{ item.h }}]
</div> </div>
</div> </div>
</div> --> </div>
<div class="grid-box index-grid select-none"> <div class="grid-box index-grid select-none">
<grid-layout <grid-layout
@ -545,9 +620,10 @@ const formState = reactive({
<component <component
:is="item.loadComp" :is="item.loadComp"
:key="item.i" :key="item.i"
:ref="(el) => setComponentRef(el, item.i)"
:data="item" :data="item"
:i="item.i"
@edit-group-name="editGroupName" @edit-group-name="editGroupName"
@provide-grid-layout-ref="receiveGridLayoutRef"
/> />
</div> </div>
</grid-item> </grid-item>

View File

@ -114,6 +114,24 @@ export const updateRowHeightByGroup = (domId: string): [number, number] => {
return [rowHeight, colNum]; return [rowHeight, colNum];
}; };
/** 元素路径转换 */
export const pathToComponent = (path: string, type: 'component' | 'home') => {
// 先分隔元素,取出绝对路径
// ../Output1/index.vue -> ./components/Output1/index.vue
if (type === 'home') {
const arr = path.split('../');
const realPath = arr[arr.length - 1];
console.log(realPath);
return `./components/${realPath}`;
}
// ./components/Output1/index.vue -> ../Output1/index.vue
if (type === 'component') {
const arr = path.split('./components/');
const realPath = arr[arr.length - 1];
return `../${realPath}`;
}
};
/** /**
* 12 * 12
* @returns {string} 12 * @returns {string} 12
@ -127,3 +145,44 @@ export function generateRandomString(len: number = 12): string {
} }
return result; return result;
} }
/**
*
*/
export const isGroup = (path: string) => {
return path.includes('Output5');
};
export function isElementInFolder(
draggedElement: Element,
folders: Element[],
): null | string {
// 计算拖拽元素的边界
const draggedLeft = draggedElement.x;
const draggedRight = draggedElement.x + draggedElement.w;
const draggedTop = draggedElement.y;
const draggedBottom = draggedElement.y + draggedElement.h;
// 遍历文件夹,检查拖拽元素是否在某个文件夹内
for (const folder of folders) {
// 计算文件夹的边界
const folderLeft = folder.x;
const folderRight = folder.x + folder.w;
const folderTop = folder.y;
const folderBottom = folder.y + folder.h;
// 判断拖拽元素是否在文件夹内(重叠)
if (
draggedRight > folderLeft && // 拖拽元素的右边界在文件夹的左边界右侧
draggedLeft < folderRight && // 拖拽元素的左边界在文件夹的右边界左侧
draggedBottom > folderTop && // 拖拽元素的下边界在文件夹的上边界下方
draggedTop < folderBottom // 拖拽元素的上边界在文件夹的下边界上方
) {
// 拖拽元素位于该文件夹内或与该文件夹重叠
return folder.i; // 返回文件夹的索引
}
}
// 如果不在任何文件夹内
return null;
}