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
Frontend CI/CD / build (web-office) (push) Failing after 6s
Details
This commit is contained in:
commit
2149877576
|
@ -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,
|
||||||
|
};
|
||||||
|
});
|
|
@ -1,2 +1,3 @@
|
||||||
export * from './auth';
|
export * from './auth';
|
||||||
export * from './tiles'
|
export * from './canvas';
|
||||||
|
export * from './tiles';
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import {defineStore} from 'pinia'
|
import { defineStore } from 'pinia';
|
||||||
export const UseTilesStore = defineStore('tiles',{
|
|
||||||
state: () => {
|
|
||||||
return {
|
|
||||||
tilesIsMove : !1, // 磁贴是否是可编辑状态
|
|
||||||
|
|
||||||
}
|
export const UseTilesStore = defineStore('tiles', {
|
||||||
|
state: () => {
|
||||||
|
return {
|
||||||
|
tilesIsMove: !1, // 磁贴是否是可编辑状态
|
||||||
|
};
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
setTilesIsMove(data: boolean) {
|
||||||
|
this.tilesIsMove = data;
|
||||||
},
|
},
|
||||||
actions: {
|
},
|
||||||
setTilesIsMove(data: boolean){
|
});
|
||||||
this.tilesIsMove = data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
// console.log(domIdxxxxx.value);
|
for (const item of layout.value) {
|
||||||
// console.log(dom);
|
if (isGroup(item.component)) {
|
||||||
console.log('layoutUpdatedEvent', e);
|
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;
|
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>
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue