From 97c1d0e36c0143fec0a218d9ab795418f607edeb Mon Sep 17 00:00:00 2001 From: "LINING-PC\\lining" Date: Thu, 3 Jul 2025 12:04:41 +0800 Subject: [PATCH] v1.0.6 - TaskDrawer progressbar style updates --- demo/data.json | 25 +++- src/components/TaskDrawer.vue | 275 +++++++++++++++++++++++++++++++++- 2 files changed, 284 insertions(+), 16 deletions(-) diff --git a/demo/data.json b/demo/data.json index aa08f65..8da5a0a 100644 --- a/demo/data.json +++ b/demo/data.json @@ -20,7 +20,8 @@ "progress": 100, "estimatedHours": 16, "actualHours": 15, - "type": "task" + "type": "task", + "parentId": 1 }, { "id": 3, @@ -32,6 +33,7 @@ "estimatedHours": 24, "actualHours": 28, "type": "story", + "parentId": 1, "children": [ { "id": 4, @@ -43,7 +45,8 @@ "progress": 80, "estimatedHours": 8, "actualHours": 10, - "type": "task" + "type": "task", + "parentId": 3 }, { "id": 5, @@ -55,7 +58,8 @@ "progress": 0, "estimatedHours": 16, "actualHours": 0, - "type": "task" + "type": "task", + "parentId": 3 } ], "collapsed": false @@ -84,7 +88,8 @@ "estimatedHours": 80, "actualHours": 35, "type": "task", - "predecessor": "5" + "predecessor": "5", + "parentId": 7 }, { "id": 11, @@ -96,7 +101,8 @@ "estimatedHours": 80, "actualHours": 0, "type": "task", - "predecessor": "5" + "predecessor": "5", + "parentId": 7 }, { "id": 12, @@ -108,7 +114,8 @@ "estimatedHours": 88, "actualHours": 0, "type": "task", - "predecessor": "5" + "predecessor": "5", + "parentId": 7 } ], "collapsed": false @@ -134,7 +141,8 @@ "estimatedHours": 48, "actualHours": 0, "type": "task", - "predecessor": "7" + "predecessor": "7", + "parentId": 13 }, { "id": 15, @@ -146,7 +154,8 @@ "estimatedHours": 24, "actualHours": 0, "type": "task", - "predecessor": "7" + "predecessor": "7", + "parentId": 13 } ], "collapsed": false diff --git a/src/components/TaskDrawer.vue b/src/components/TaskDrawer.vue index 9febe7f..59eb958 100644 --- a/src/components/TaskDrawer.vue +++ b/src/components/TaskDrawer.vue @@ -55,7 +55,7 @@ const allTasks = ref([]) // 获取可作为前置任务的任务列表(只包含type="task"的任务,且不包含当前任务) const availablePredecessorTasks = computed(() => { return allTasks.value.filter( - task => task.type === 'task' && task.id !== props.task?.id, // 排除当前任务自己 + task => task.type === 'task' && task.id !== props.task?.id // 排除当前任务自己 ) }) @@ -65,7 +65,7 @@ const availableParentTasks = computed(() => { .filter( task => task.id !== props.task?.id && // 排除当前任务自己 - (task.type === 'story' || task.type === 'task'), // 只显示story和task类型 + (task.type === 'story' || task.type === 'task') // 只显示story和task类型 ) .map(task => ({ ...task, @@ -78,6 +78,97 @@ const getTaskTypeDisplay = (type: string): string => { return (t.value.taskTypeMap as Record)?.[type] || type } +// 计算进度条样式 +const progressSliderStyle = computed(() => { + const progressPercent = formData.progress || 0 + return { + '--progress-percent': `${progressPercent}%`, + } +}) + +// 进度输入框的显示值 +const progressDisplayValue = ref('0') + +// 处理进度输入 +const handleProgressInput = (event: Event) => { + const target = event.target as HTMLInputElement + let value = target.value + + // 只保留数字 + value = value.replace(/[^\d]/g, '') + + // 更新输入框显示 + target.value = value + progressDisplayValue.value = value +} + +// 处理进度输入失焦或回车 +const handleProgressInputBlur = () => { + const value = progressDisplayValue.value + + // 转换为数字 + let progress = parseInt(value) || 0 + + // 数据验证:小于0或非数字显示0,大于100显示100 + if (progress < 0 || isNaN(progress)) { + progress = 0 + } else if (progress > 100) { + progress = 100 + } + + // 更新数据和显示 + formData.progress = progress + progressDisplayValue.value = progress.toString() +} + +// 处理进度输入框聚焦(选中全部文本) +const handleProgressInputFocus = (event: Event) => { + const target = event.target as HTMLInputElement + // 延迟选中,确保聚焦完成 + setTimeout(() => { + target.select() + }, 0) +} + +// 处理键盘事件 +const handleProgressKeydown = (event: KeyboardEvent) => { + const key = event.key + + // 允许的按键:数字、退格、删除、方向键、Tab等 + const allowedKeys = [ + 'Backspace', + 'Delete', + 'Tab', + 'Escape', + 'Enter', + 'ArrowLeft', + 'ArrowRight', + 'ArrowUp', + 'ArrowDown', + 'Home', + 'End', + 'Control', + 'Meta', + 'Alt', + 'Shift', + ] + + // 允许数字 + const isNumber = /^[0-9]$/.test(key) + const isAllowedKey = allowedKeys.includes(key) + + // 如果是Ctrl+A、Ctrl+C、Ctrl+V、Ctrl+X等组合键,允许通过 + if (event.ctrlKey || event.metaKey) { + return + } + + // 如果不是允许的按键或数字,阻止输入 + if (!isNumber && !isAllowedKey) { + event.preventDefault() + return + } +} + // 错误信息 const errors = reactive({ name: '', @@ -100,7 +191,7 @@ watch( // 抽屉显示时重新请求任务数据,确保前置任务列表是最新的 window.dispatchEvent(new CustomEvent('request-task-list')) } - }, + } ) // 监听 isVisible 变化,同步到父组件 @@ -264,6 +355,15 @@ const showMessage = (message: string, type: 'success' | 'error') => { } }, 3000) } + +// 监听 formData.progress 变化,同步更新显示值 +watch( + () => formData.progress, + newValue => { + progressDisplayValue.value = (newValue || 0).toString() + }, + { immediate: true } +)