diff --git a/npm-demo/src/components/GanttTest.vue b/npm-demo/src/components/GanttTest.vue index e92bb37..5d6dc1a 100644 --- a/npm-demo/src/components/GanttTest.vue +++ b/npm-demo/src/components/GanttTest.vue @@ -251,8 +251,8 @@ const onTaskAdded = (res) => { @@ -400,23 +400,23 @@ const onTaskAdded = (res) => { transition: all 0.3s; } -.btn-primary { +.gantt-btn-primary { background: #409eff; color: white; border-color: #409eff; } -.btn-primary:hover { +.gantt-btn-primary:hover { background: #66b1ff; border-color: #66b1ff; } -.btn-default { +.gantt-btn-default { background: white; color: #606266; } -.btn-default:hover { +.gantt-btn-default:hover { color: #409eff; border-color: #409eff; } diff --git a/npm-webpack-demo/src/App.vue b/npm-webpack-demo/src/App.vue index ec08be0..1e226b4 100644 --- a/npm-webpack-demo/src/App.vue +++ b/npm-webpack-demo/src/App.vue @@ -24,8 +24,8 @@
- - + +
@@ -54,8 +54,8 @@ @@ -409,23 +409,23 @@ const onTaskAdded = (res) => { transition: all 0.3s; } -.btn-primary { +.gantt-btn-primary { background: #409eff; color: white; border-color: #409eff; } -.btn-primary:hover { +.gantt-btn-primary:hover { background: #66b1ff; border-color: #66b1ff; } -.btn-default { +.gantt-btn-default { background: white; color: #606266; } -.btn-default:hover { +.gantt-btn-default:hover { color: #409eff; border-color: #409eff; } diff --git a/package.json b/package.json index cee9db7..e2895b9 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,22 @@ "name": "jordium-gantt-vue3", "version": "1.4.6-patch.1", "type": "module", - "main": "dist/jordium-gantt-vue3.cjs.js", - "module": "dist/jordium-gantt-vue3.es.js", - "types": "dist/jordium-gantt-vue3.d.ts", + "main": "npm-package/dist/jordium-gantt-vue3.cjs.js", + "module": "npm-package/dist/jordium-gantt-vue3.es.js", + "types": "npm-package/dist/index.d.ts", + "exports": { + ".": { + "types": "./npm-package/dist/index.d.ts", + "require": "./npm-package/dist/jordium-gantt-vue3.cjs.js", + "import": "./npm-package/dist/jordium-gantt-vue3.es.js" + }, + "./styles": "./npm-package/dist/jordium-gantt-vue3-styles.js", + "./styles.js": "./npm-package/dist/jordium-gantt-vue3-styles.js", + "./index.css": "./npm-package/dist/assets/jordium-gantt-vue3.css", + "./npm-package/*": "./npm-package/*" + }, "files": [ - "dist" + "npm-package" ], "license": "MIT", "repository": { diff --git a/scripts/generate-css-export.js b/scripts/generate-css-export.js index 73ec745..2cb698f 100644 --- a/scripts/generate-css-export.js +++ b/scripts/generate-css-export.js @@ -9,7 +9,7 @@ const __dirname = path.dirname(__filename) // 构建后生成CSS导出文件 function generateCssExport() { - const distDir = path.resolve(__dirname, '../../npm-package/dist') + const distDir = path.resolve(__dirname, '../npm-package/dist') const assetsDir = path.join(distDir, 'assets') const expectedCssFile = path.join(assetsDir, 'jordium-gantt-vue3.css') const outputFile = path.join(distDir, 'jordium-gantt-vue3-styles.js') diff --git a/src/components/ConfirmTimerDialog.vue b/src/components/ConfirmTimerDialog.vue index 7bd4785..8f3a64e 100644 --- a/src/components/ConfirmTimerDialog.vue +++ b/src/components/ConfirmTimerDialog.vue @@ -46,8 +46,8 @@ const messageTaskName = computed(() => { rows="3" >
- - + +
@@ -108,7 +108,7 @@ const messageTaskName = computed(() => { gap: 12px; margin-top: 8px; } -.btn { +.gantt-btn { min-width: 96px; padding: 10px 0; border: none; @@ -122,11 +122,11 @@ const messageTaskName = computed(() => { align-items: center; justify-content: center; } -.btn-confirm { +.gantt-btn-confirm { background: #4caf50; color: #fff; } -.btn-confirm:hover { +.gantt-btn-confirm:hover { background: #43a047; } diff --git a/src/components/GanttChart.vue b/src/components/GanttChart.vue index e922c75..264eb7b 100644 --- a/src/components/GanttChart.vue +++ b/src/components/GanttChart.vue @@ -65,6 +65,8 @@ const emit = defineEmits([ 'task-deleted', 'task-added', 'task-updated', + 'task-collapse-change', // 任务折叠状态变化事件 + 'link-deleted', // 链接删除事件 // 工具栏事件 'add-task', 'add-milestone', @@ -72,6 +74,9 @@ const emit = defineEmits([ 'milestone-saved', 'milestone-deleted', 'milestone-icon-changed', + // 任务关系事件 + 'add-predecessor', + 'add-successor', // TaskRow拖拽事件 'task-row-moved', ]) @@ -584,6 +589,9 @@ const handleTaskCollapseChange = (task: Task) => { // 触发Timeline重新计算 updateTaskTrigger.value++ + + // 向外发出折叠状态变化事件 + emit('task-collapse-change', task) } // 全部展开任务 @@ -744,6 +752,11 @@ const expandTaskListText = computed(() => t.value.expandTaskList) // 为TaskList提供层级数据(保持原始层级结构,只扁平化里程碑) const tasksForTaskList = computed(() => { + // 通过条件判断访问触发器,确保折叠状态变化时重新计算 + if (updateTaskTrigger.value >= 0) { + // 触发器起作用,继续执行计算逻辑 + } + const result: Task[] = [] // 如果有里程碑,创建里程碑分组行(扁平化显示) @@ -2004,6 +2017,9 @@ function handleTimelineEditTask(task: Task) { function handleAddPredecessor(targetTask: Task) { if (!targetTask) return + // 触发事件供外部使用 + emit('add-predecessor', targetTask) + // 1. 记录要添加前置任务的目标任务 taskToAddPredecessorTo.value = targetTask @@ -2036,6 +2052,10 @@ function handleAddPredecessor(targetTask: Task) { // 处理添加后置任务事件 function handleAddSuccessor(targetTask: Task) { if (!targetTask) return + + // 触发事件供外部使用 + emit('add-successor', targetTask) + // 记录要添加后置任务的目标任务 taskToAddSuccessorTo.value = targetTask // 构造新任务,parentId 与目标任务一致,predecessor 仅包含目标任务 id @@ -2063,6 +2083,18 @@ function handleAddSuccessor(targetTask: Task) { taskDrawerVisible.value = true } +// 处理前置任务已添加事件(拖拽连接完成) +function handlePredecessorAdded(event: { targetTask: Task; newTask: Task }) { + // 直接转发事件给外部 + emit('predecessor-added', event) +} + +// 处理后置任务已添加事件(拖拽连接完成) +function handleSuccessorAdded(event: { targetTask: Task; newTask: Task }) { + // 直接转发事件给外部 + emit('successor-added', event) +} + // 新增Task插入到任务树中 // 插入新任务到任务树(parentId 已在打开 TaskDrawer 时预设好) const insertTask = (tasks: Task[], newTask: Task) => { @@ -2161,6 +2193,39 @@ function handleTaskDelete(task: Task, deleteChildren?: boolean) { emit('task-deleted', { task }) } +// 处理链接删除事件 +function handleLinkDeleted(event: { + sourceTaskId: number + targetTaskId: number + updatedTask: Task +}) { + if (props.tasks) { + // 在 tasks 树中找到目标任务并更新 + const updateTaskInTree = (taskList: Task[]): boolean => { + for (let i = 0; i < taskList.length; i++) { + if (taskList[i].id === event.targetTaskId) { + // 使用新对象替换,确保响应式更新 + taskList[i] = { ...taskList[i], predecessor: event.updatedTask.predecessor } + return true + } + if (taskList[i].children && taskList[i].children!.length > 0) { + if (updateTaskInTree(taskList[i].children!)) { + return true + } + } + } + return false + } + updateTaskInTree(props.tasks) + } + + // 触发任务更新事件 + emit('task-updated', { task: event.updatedTask }) + + // 向外部发送链接删除事件 + emit('link-deleted', event) +} + // 处理里程碑双击事件 function handleMilestoneDoubleClick(milestone: Milestone) { // 先触发外部事件,让外部可以自定义处理 @@ -2295,7 +2360,10 @@ function handleMilestoneDialogDelete(milestoneId: number) { @stop-timer="handleStopTimer" @add-predecessor="handleAddPredecessor" @add-successor="handleAddSuccessor" + @predecessor-added="handlePredecessorAdded" + @successor-added="handleSuccessorAdded" @delete="handleTaskDelete" + @link-deleted="handleLinkDeleted" >