Merge branch 'dev-0.2.1' into dev-0.2

# Conflicts:
#	generated/prisma/internal/class.ts
#	generated/prisma/internal/prismaNamespace.ts
#	generated/prisma/internal/prismaNamespaceBrowser.ts
#	generated/prisma/models/BoardColumn.ts
#	generated/prisma/models/Project.ts
#	generated/prisma/models/ProjectMember.ts
#	generated/prisma/models/Task.ts
#	generated/prisma/models/TaskMember.ts
#	generated/prisma/models/TaskTag.ts
#	generated/prisma/models/User.ts
#	server/routes/projects.js
#	server/routes/tasks.js
#	src/api/task.js
This commit is contained in:
jif2.zhang
2026-10-26 20:46:25 +08:00
95 changed files with 8694 additions and 1609 deletions
+26 -23
View File
@@ -9,6 +9,7 @@ import { resolveTaskWrite } from '../task-domain/resolveStatus.js'
import { filterVisible } from '../task-domain/retention.js'
import { copyTask } from '../task-domain/copyTask.js'
import { runAutoArchiveForProject } from '../task-domain/archive.js'
import { genUuid, withUuid, withTaskNumber } from '../task-domain/identity.js'
const router = Router()
router.use(authRequired)
@@ -184,28 +185,30 @@ router.post('/projects/:id/tasks', async (req, res, next) => {
}
const firstCol = columns[0]
const row = await prisma.task.create({
data: {
projectId: project.id,
columnId: firstCol.id,
parentId: pid,
title: cleanTitle,
description: String(description || ''),
kind: kind ? String(kind).trim().slice(0, 20) : null,
markDate: mark,
status: firstCol.boundStatus || 'todo',
assigneeId: finalAssignee,
creatorId: userId,
extras: [],
members: {
create: (Array.isArray(memberIds) ? memberIds : [])
.map(Number).filter((id) => memberSet.has(id))
.map((uid) => ({ userId: uid })),
},
tags: { create: (Array.isArray(tags) ? tags : []).filter(Boolean).map((n) => ({ name: String(n).slice(0, 20) })) },
const taskData = {
uuid: req.body?.uuid || genUuid(),
projectId: project.id,
columnId: firstCol.id,
parentId: pid,
title: cleanTitle,
description: String(description || ''),
kind: kind ? String(kind).trim().slice(0, 20) : null,
markDate: mark,
status: firstCol.boundStatus || 'todo',
assigneeId: finalAssignee,
creatorId: userId,
extras: [],
members: {
create: withUuid((Array.isArray(memberIds) ? memberIds : [])
.map(Number).filter((id) => memberSet.has(id))
.map((uid) => ({ userId: uid }))),
},
include: TASK_INCLUDE,
})
tags: { create: withUuid((Array.isArray(tags) ? tags : []).filter(Boolean).map((n) => ({ name: String(n).slice(0, 20) }))) },
}
// 项目内自增编号 (展示 `code-number`): 服务端分配, 并发冲突时重取 max+1 重试
const { value: row } = await withTaskNumber(project.id, (number) =>
prisma.task.create({ data: { ...taskData, number }, include: TASK_INCLUDE }),
)
res.json({ item: shape(row) })
} catch (e) { next(e) }
})
@@ -333,7 +336,7 @@ router.put('/tasks/:id', async (req, res, next) => {
await prisma.taskMember.deleteMany({ where: { taskId: task.id } })
if (ids.length) {
await prisma.taskMember.createMany({
data: ids.map((uid) => ({ taskId: task.id, userId: uid })),
data: withUuid(ids.map((uid) => ({ taskId: task.id, userId: uid }))),
})
}
}
@@ -341,7 +344,7 @@ router.put('/tasks/:id', async (req, res, next) => {
await prisma.taskTag.deleteMany({ where: { taskId: task.id } })
const names = body.tags.map((n) => String(n).trim()).filter(Boolean).slice(0, 10)
if (names.length) {
await prisma.taskTag.createMany({ data: names.map((name) => ({ taskId: task.id, name: name.slice(0, 20) })) })
await prisma.taskTag.createMany({ data: withUuid(names.map((name) => ({ taskId: task.id, name: name.slice(0, 20) }))) })
}
}