From d53f8610bf67974f983de2602c0319a82df5b919 Mon Sep 17 00:00:00 2001 From: ShineKOT <1917095344@qq.com> Date: Mon, 29 Sep 2025 19:57:28 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/resource-schedule-tree.tsx | 1 + .../schedule-table/schedule-table.tsx | 12 +- src/resource-scheduler/hooks/use-drag.ts | 135 +++++++++--------- .../interface/i-drag-data.ts | 6 + 4 files changed, 88 insertions(+), 66 deletions(-) diff --git a/src/resource-schedule-tree/src/resource-schedule-tree.tsx b/src/resource-schedule-tree/src/resource-schedule-tree.tsx index d2d876c..8e104f9 100644 --- a/src/resource-schedule-tree/src/resource-schedule-tree.tsx +++ b/src/resource-schedule-tree/src/resource-schedule-tree.tsx @@ -976,6 +976,7 @@ export const ResourceScheduleTree = defineComponent({ scheduleType, dragType: 'add', data: node._deData, + dataId: createUUID(), }; payload.dataTransfer?.setData('data', JSON.stringify(item)); ghostState.value.text = node._text; diff --git a/src/resource-scheduler/components/schedule-table/schedule-table.tsx b/src/resource-scheduler/components/schedule-table/schedule-table.tsx index d182446..d6d5552 100644 --- a/src/resource-scheduler/components/schedule-table/schedule-table.tsx +++ b/src/resource-scheduler/components/schedule-table/schedule-table.tsx @@ -166,16 +166,24 @@ export const ScheduleTable = defineComponent({ (taskViewModel: ITaskViewModel) => { return (
+ this.handleDragStart(evt, taskViewModel.originalId, taskViewModel.data) + } > {taskViewModel.data.name}
diff --git a/src/resource-scheduler/hooks/use-drag.ts b/src/resource-scheduler/hooks/use-drag.ts index a9623e5..1c51fd4 100644 --- a/src/resource-scheduler/hooks/use-drag.ts +++ b/src/resource-scheduler/hooks/use-drag.ts @@ -1,37 +1,45 @@ -import { Ref } from 'vue'; -import dayjs from 'dayjs'; -import { createUUID } from 'qx-util'; -import { IDragData, IScheduleTask } from '../interface'; -import useStore from '../store'; +import { Ref } from "vue"; +import dayjs from "dayjs"; +import { IDragData, IScheduleResource, IScheduleTask } from "../interface"; +import useStore from "../store"; +import { useCommonAbility } from "./use-schedule-table"; export function useDrag( props: any, coordinateElement: Ref, - bodyCanvas: Ref, + bodyCanvas: Ref ): { handleDragOver: (payload: DragEvent) => void; handleDragLeave: (payload: DragEvent) => void; handleDrop: (payload: DragEvent) => Promise; - handleDragStart: (payload: DragEvent, task: IScheduleTask) => void; + handleDragStart: ( + payload: DragEvent, + dataId: string, + task: IScheduleTask + ) => void; } { - const { $bgLayer, $renderLayer, $uiCoordinate, $config } = useStore(); + const { $renderLayer, $uiCoordinate, $config } = useStore(); const config = $config.getConfig(); + const resources = $renderLayer.getResources(); + + const { refresh } = useCommonAbility(coordinateElement); + /** * @description 根据拖拽事件源计算位置 * @param {DragEvent} payload * @returns {*} {{ * date: Date; - * resourceId: string; + * resourceId: IScheduleResource; * position: { x: number; y: number }; * }} */ const calcPositionByEvent = ( - payload: DragEvent, + payload: DragEvent ): { date: dayjs.Dayjs; - resourceId: string; + resource: IScheduleResource; position: { x: number; y: number }; } => { const rect = bodyCanvas.value!.getBoundingClientRect(); @@ -47,22 +55,22 @@ export function useDrag( payload.clientX - rect.left - resourceColumnWidth - scaleColumnWidth; const y = payload.clientY - rect.top; const resourceIndex = Math.ceil(y / resourceBodyRowHeight) - 1; - // 资源标识 - const resourceId = $renderLayer.resourceViewModels[resourceIndex].id; + // 资源 + const resource = resources[resourceIndex]; // 天索引 const dayIndex = Math.ceil(x / $uiCoordinate.cellWidth) - 1; // 刻度开始时间 const startDate = dayjs(startTime) - .add(dayIndex, 'day') - .startOf('day') + .add(dayIndex, "day") + .startOf("day") .hour(scaleRange[0]); const range = scaleRange[1] - scaleRange[0]; // 拖拽精度的高度(使用分钟来计算) const intervalHeight = resourceBodyRowHeight / ((range * 60) / (dragInterval * 60)); const height = y - resourceIndex * config.resourceBodyRowHeight; - const date = startDate.add(Math.round(height / intervalHeight), 'hour'); - return { position: { x, y }, date, resourceId }; + const date = startDate.add(Math.round(height / intervalHeight), "hour"); + return { position: { x, y }, date, resource }; }; /** @@ -71,10 +79,10 @@ export function useDrag( */ const handleDragOver = (payload: DragEvent): void => { payload.preventDefault(); - const element = document.querySelector('#drag-ghost-date'); + const element = document.querySelector("#drag-ghost-date"); if (element) { const { date, position } = calcPositionByEvent(payload); - element.innerHTML = position.x > 0 ? date.format('YYYY-MM-DD HH:mm') : ''; + element.innerHTML = position.x > 0 ? date.format("YYYY-MM-DD HH:mm") : ""; } }; @@ -83,8 +91,8 @@ export function useDrag( * @param {DragEvent} payload */ const handleDragLeave = (payload: DragEvent): void => { - const element = document.querySelector('#drag-ghost-date'); - if (element) element.innerHTML = ''; + const element = document.querySelector("#drag-ghost-date"); + if (element) element.innerHTML = ""; }; /** @@ -96,31 +104,23 @@ export function useDrag( payload.preventDefault(); if (!coordinateElement.value || !bodyCanvas.value) return; try { - const str = payload.dataTransfer?.getData('data'); + const str = payload.dataTransfer?.getData("data"); if (!str) return; const dragData: IDragData = JSON.parse(str); - const { dragType, data, scheduleType } = dragData; - if (!dragType || !['resource', 'task'].includes(scheduleType)) return; - - // 拖拽校验 - const { position, date, resourceId } = calcPositionByEvent(payload); - const start = new Date(date.format('YYYY-MM-DD HH:mm')); - if (props.dragVerify && props.dragVerify instanceof Function) { - const result = await props.dragVerify(dragData, start); - if (!result) return; - } - - // TODO 资源标识 - const id = dragType === 'add' ? createUUID() : data.id; + const { dragType, data, scheduleType, dataId } = dragData; + if (!dragType || !["resource", "task"].includes(scheduleType)) return; - if (scheduleType === 'resource') { - $renderLayer.updateResource({ - id: id, - name: data.name, - tasks: [], - data, - }); + if (scheduleType === "resource") { + const result = await props.beforeResourceDrop(data); + if (result) + $renderLayer.updateResource({ + data, + tasks: [], + id: dataId, + name: data.name, + }); } else { + const { position, date, resource } = calcPositionByEvent(payload); // 任务未拖拽到任务区或时长为零时不做处理 // TODO: 有些任务又时长,有些任务没有时长,有开始时间和结束时间, let duration = data.planned_duration @@ -129,26 +129,27 @@ export function useDrag( // TODO 临时测试时长默认为2小时 duration = 120; if (position.x < 0 || duration === 0) return; + const start = new Date(date.format("YYYY-MM-DD HH:mm")); const end = new Date( - date.add(duration, 'minute').format('YYYY-MM-DD HH:mm'), + date.add(duration, "minute").format("YYYY-MM-DD HH:mm") ); - const task = { - end, - start, - id: id, - resourceId, - name: data.name, - data: dragType === 'add' ? data : data.data, - }; - $renderLayer.updateTask(task); + const result = await props.beforeTaskDrop(data, resource, { + startTime: start, + endTime: end, + }); + if (result) + $renderLayer.updateTask({ + end, + start, + id: dataId, + name: data.name, + resourceId: resource.id, + data: dragType === "add" ? data : data.data, + }); } // 更新绘制 - $uiCoordinate.buildCoordinate( - coordinateElement.value, - $renderLayer.getResources(), - ); - $bgLayer.draw($uiCoordinate, $renderLayer.getResources()); - $renderLayer.buildViewModels($uiCoordinate); + refresh(); + console.log($renderLayer); } catch (error) { ibiz.log.error(error); } @@ -157,16 +158,22 @@ export function useDrag( /** * @description 处理开始拖拽 * @param {DragEvent} payload + * @param {string} dataId * @param {IScheduleTask} task */ - const handleDragStart = (payload: DragEvent, task: IScheduleTask): void => { - payload.dataTransfer!.effectAllowed = 'copy'; - const item = { + const handleDragStart = ( + payload: DragEvent, + dataId: string, + task: IScheduleTask + ): void => { + payload.dataTransfer!.effectAllowed = "copy"; + const item: IDragData = { + dataId, data: task, - dragType: 'update', - scheduleType: 'task', + dragType: "update", + scheduleType: "task", }; - payload.dataTransfer!.setData('data', JSON.stringify(item)); + payload.dataTransfer!.setData("data", JSON.stringify(item)); }; return { handleDrop, handleDragOver, handleDragStart, handleDragLeave }; diff --git a/src/resource-scheduler/interface/i-drag-data.ts b/src/resource-scheduler/interface/i-drag-data.ts index e5f459d..ab7e26a 100644 --- a/src/resource-scheduler/interface/i-drag-data.ts +++ b/src/resource-scheduler/interface/i-drag-data.ts @@ -22,4 +22,10 @@ export interface IDragData { * @memberof IDragData */ data: IData; + /** + * @description 数据标识(唯一) + * @type {string} + * @memberof IDragData + */ + dataId: string; } \ No newline at end of file -- Gitee From bb7c6af060400077f1f51ce72900c04b0b805fde Mon Sep 17 00:00:00 2001 From: ShineKOT <1917095344@qq.com> Date: Mon, 29 Sep 2025 20:00:09 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/resource-scheduler/hooks/use-drag.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/resource-scheduler/hooks/use-drag.ts b/src/resource-scheduler/hooks/use-drag.ts index 1c51fd4..2614702 100644 --- a/src/resource-scheduler/hooks/use-drag.ts +++ b/src/resource-scheduler/hooks/use-drag.ts @@ -149,7 +149,6 @@ export function useDrag( } // 更新绘制 refresh(); - console.log($renderLayer); } catch (error) { ibiz.log.error(error); } -- Gitee