feat(V0.2): 克隆卡片跟手浮层 + 列表组内排序 + 把手统一移到最左
Docker Build and Push / build-image (push) Successful in 1m1s

- 浮层改为激活时克隆原卡片 (DOM clone, 淡化+投影) 挂 body 顶层,
  移动直接改 transform —— 替代蓝色信息条, 所见即所拖
- 任务列表支持组内排序: 拖到本组某行上/下半显示插入指示, 松手提交
  POST /projects/:id/tasks/reorder (顶层任务按展平顺序重写 sortOrder);
  拖到其他分组仍为换列
- ⠿ 把手统一移到卡片最左: 打卡 / 列表任务行 / 看板卡片 (看板新增把手
  即按即拖路径, 与列表同款 touchstart preventDefault 双保险)
- useColumnDrag onDrop 经 ref 桥接防陈旧闭包
This commit is contained in:
jif2.zhang
2026-10-25 02:07:58 +08:00
parent 9a8313173d
commit 5066007d9d
12 changed files with 300 additions and 158 deletions
+21
View File
@@ -124,6 +124,27 @@ router.post('/projects/:id/tasks', async (req, res, next) => {
} catch (e) { next(e) }
})
// POST /api/projects/:id/tasks/reorder { ids: [顶层任务 id 的新顺序] }
// 按数组下标重写 sortOrder (组内拖动排序; 子任务不参与, 跟随父任务)
router.post('/projects/:id/tasks/reorder', async (req, res, next) => {
try {
const userId = req.user.sub
const project = await loadProjectForUser(req.params.id, userId)
if (!project) return res.status(404).json({ error: '项目不存在或无权限' })
const ids = Array.isArray((req.body || {}).ids) ? req.body.ids.map(Number).filter(Number.isFinite) : []
if (!ids.length) return res.status(400).json({ error: 'ids 不能为空' })
const rows = await prisma.task.findMany({
where: { projectId: project.id, id: { in: ids }, parentId: null },
select: { id: true },
})
if (rows.length !== new Set(ids).size) return res.status(400).json({ error: '包含无效的任务' })
await prisma.$transaction(
ids.map((id, i) => prisma.task.update({ where: { id }, data: { sortOrder: i } })),
)
res.json({ ok: true })
} catch (e) { next(e) }
})
// ---------- 单条任务 ----------
// GET /api/tasks/:id