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 './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', {
state: () => {
return {
tilesIsMove: !1, // 磁贴是否是可编辑状态
}
};
},
actions: {
setTilesIsMove(data: boolean) {
this.tilesIsMove = data
}
}
})
this.tilesIsMove = data;
},
},
});

View File

@ -14,7 +14,7 @@ import {
import { CloseCircleFilled } from '@ant-design/icons-vue';
import { storeToRefs } from 'pinia';
import { UseTilesStore } from '#/store';
import { useCanvasStore, UseTilesStore } from '#/store';
import {
debounce,
@ -23,6 +23,10 @@ import {
} from '../../utils';
const props = defineProps({
i: {
type: String,
default: '',
},
list: {
type: Object,
default: [],
@ -31,6 +35,7 @@ const props = defineProps({
const emit = defineEmits(['provideGridLayoutRef']);
const canvasStore = useCanvasStore();
const tilesStore = UseTilesStore();
const { list } = toRefs(props);
@ -303,8 +308,21 @@ onMounted(() => {
nextTick(() => {
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({
gridLayoutRef: gridLayoutRef.value,

View File

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

View File

@ -1,8 +1,7 @@
<script setup>
<script setup lang="ts">
import {
defineAsyncComponent,
getCurrentInstance,
inject,
markRaw,
nextTick,
onBeforeUnmount,
@ -38,15 +37,18 @@ import {
} from 'ant-design-vue';
import { storeToRefs } from 'pinia';
import { UseTilesStore } from '#/store';
import { useCanvasStore, UseTilesStore } from '#/store';
import { tilesList } from './tiles';
import { debounce, updateRowHeight } from './utils';
import { debounce, isElementInFolder, isGroup, updateRowHeight } from './utils';
const tilesStore = UseTilesStore();
const canvasStore = useCanvasStore();
const router = useRouter();
/** 是否拖动中 */
const isDragging = ref(false);
// ref map
const componentsRef = ref(new Map());
// ref
@ -93,22 +95,18 @@ const rowHeight = ref(0);
/** 屏幕宽度 */
const screenW = ref(0);
/** 记录当前拖动的元素 */
const currentDragItem = ref(null);
// updateRowHeight 200ms
const debouncedUpdateRowHeight = debounce(() => {
rowHeight.value = updateRowHeight('#container-canvas');
}, 0);
// 使 inject C ref
const gridLayoutRef = inject('gridLayoutRef');
onMounted(() => {
window.addEventListener('resize', debouncedUpdateRowHeight);
rowHeight.value = updateRowHeight('#container-canvas'); //
setTimeout(() => {
console.log(gridLayoutRef); // C ref
}, 1000);
document.addEventListener(
'dragover',
(e) => {
@ -123,6 +121,29 @@ onMounted(() => {
event.preventDefault();
});
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 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(dom);
console.log('layoutUpdatedEvent', e);
isDragging.value = false;
nextTick(() => {
tilesIsMove.value = true;
});
}
};
/**
@ -325,6 +385,7 @@ const checkIfOverTargetCanvas = (item) => {
return isOver;
};
//
const moveEvent = (e) => {
//
const group = findGroup();
@ -336,8 +397,10 @@ const moveEvent = (e) => {
// console.log(dom);
if (dom !== -1) {
isDragging.value = true;
targetLayout.value = layout.value[dom];
console.log(layout.value[dom]);
currentDragItem.value = layout.value[dom];
//
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) => {
layout.value.forEach((element) => {
@ -488,7 +563,7 @@ const formState = reactive({
<template>
<div id="container-canvas" class="container h-[calc(100%-10px)] px-[20px]">
<!-- 自定义布局的部分 -->
<!-- {{ screenW }} - {{ rowHeight }}
{{ screenW }} - {{ rowHeight }}
<div class="layoutJSON">
Displayed as <code>[x, y, w, h]</code>:
@ -498,7 +573,7 @@ const formState = reactive({
>: [{{ item.x }}, {{ item.y }}, {{ item.w }}, {{ item.h }}]
</div>
</div>
</div> -->
</div>
<div class="grid-box index-grid select-none">
<grid-layout
@ -545,9 +620,10 @@ const formState = reactive({
<component
:is="item.loadComp"
:key="item.i"
:ref="(el) => setComponentRef(el, item.i)"
:data="item"
:i="item.i"
@edit-group-name="editGroupName"
@provide-grid-layout-ref="receiveGridLayoutRef"
/>
</div>
</grid-item>

View File

@ -114,6 +114,24 @@ export const updateRowHeightByGroup = (domId: string): [number, number] => {
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
* @returns {string} 12
@ -127,3 +145,44 @@ export function generateRandomString(len: number = 12): string {
}
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;
}