From 8ed4183e6f7dfb6f28cb8067641df10ae8e666e3 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 16 Jan 2026 11:03:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8F=91=E5=B8=83=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=AD=90=E4=BB=BB=E5=8A=A1=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=8B=96=E6=8B=BD=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/views/CreateTask.vue | 113 +++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/frontend/src/views/CreateTask.vue b/frontend/src/views/CreateTask.vue index dd9e6a4..139f833 100644 --- a/frontend/src/views/CreateTask.vue +++ b/frontend/src/views/CreateTask.vue @@ -68,10 +68,21 @@
+ +
+ +
>({}) +// 拖拽排序相关 +const dragIndex = ref(null) +const dragOverIndex = ref(null) + // 表单数据 const formData = reactive({ title: '', @@ -920,6 +935,55 @@ const removeTaskType = (index: number) => { } } +// 拖拽开始 +const handleDragStart = (e: DragEvent, index: number) => { + dragIndex.value = index + if (e.dataTransfer) { + e.dataTransfer.effectAllowed = 'move' + e.dataTransfer.setData('text/plain', String(index)) + } +} + +// 拖拽结束 +const handleDragEnd = () => { + dragIndex.value = null + dragOverIndex.value = null +} + +// 拖拽经过 +const handleDragOver = (e: DragEvent, index: number) => { + e.preventDefault() + if (dragIndex.value !== null && dragIndex.value !== index) { + dragOverIndex.value = index + } +} + +// 拖拽离开 +const handleDragLeave = () => { + dragOverIndex.value = null +} + +// 放置 +const handleDrop = (e: DragEvent, targetIndex: number) => { + e.preventDefault() + if (dragIndex.value === null || dragIndex.value === targetIndex) { + handleDragEnd() + return + } + + // 交换位置 + const sourceIndex = dragIndex.value + const items = [...formData.taskTypes] + const [removed] = items.splice(sourceIndex, 1) + items.splice(targetIndex, 0, removed) + formData.taskTypes = items + + // 重新计算积分 + calculateScore() + + handleDragEnd() +} + // 处理SPU输入(只允许大写字母、数字和横杠) const handleSpuInput = (e: Event) => { const input = e.target as HTMLInputElement @@ -2169,10 +2233,57 @@ onUnmounted(() => { .task-types-list { .task-type-item { margin-bottom: $space-md; + padding: 12px; + background: rgba(255, 255, 255, 0.02); + border: 1px solid transparent; + border-radius: 8px; + transition: all 0.2s ease; + cursor: grab; &:last-child { margin-bottom: $space-lg; } + + &:hover { + background: rgba(49, 240, 139, 0.05); + border-color: rgba(49, 240, 139, 0.2); + } + + &.dragging { + opacity: 0.5; + cursor: grabbing; + border-color: $brand-primary; + background: rgba(49, 240, 139, 0.1); + } + + &.drag-over { + border-color: $brand-primary; + border-style: dashed; + background: rgba(49, 240, 139, 0.15); + transform: scale(1.02); + } + } + + .drag-handle { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 40px; + color: #666; + cursor: grab; + border-radius: 4px; + transition: all 0.2s ease; + flex-shrink: 0; + + &:hover { + color: $brand-primary; + background: rgba(49, 240, 139, 0.1); + } + + &:active { + cursor: grabbing; + } } .task-type-row {