Docker Build and Push / build-image (push) Successful in 1m27s
- 数据: Project.autoArchive + Task.archived/archivedAt/archiveSource, 迁移 20261026000000_task_archive (两索引) - 领域: server/task-domain/archive.js —— hiddenAtOf 与保留口径精确同源, autoArchiveDue 到期判定, runAutoArchiveForProject (读时惰性) + runAutoArchiveSweep (每小时 cron 兜底) - 接口: POST /tasks/:id/archive|unarchive (连带子任务, 幂等); GET /projects/:id/tasks/archived (keyword/kind/columnId/from/to 过滤, archivedAt+id 游标分页); 项目 PUT 收 autoArchive (枚举校验); 主列表/子任务/项目 taskCount 全部排除归档 - 前端: ⋯ 菜单「归档」(确认含子任务条数); 项目栏「已归档」入口 → ArchivedTasks 弹层 (关键词/类型/列/归档时段过滤 + 加载更多 + 恢复/删除); 项目管理「归档设置」四档 Picker
45 lines
2.0 KiB
JavaScript
45 lines
2.0 KiB
JavaScript
import { api } from './client.js'
|
|
|
|
const q = (params) => {
|
|
const s = new URLSearchParams()
|
|
Object.entries(params || {}).forEach(([k, v]) => {
|
|
if (v !== undefined && v !== null && v !== '') s.set(k, v)
|
|
})
|
|
const str = s.toString()
|
|
return str ? '?' + str : ''
|
|
}
|
|
|
|
// 项目
|
|
export const projectApi = {
|
|
list: () => api('/projects'),
|
|
detail: (id) => api(`/projects/${id}`),
|
|
create: (body) => api('/projects', { method: 'POST', body }),
|
|
update: (id, body) => api(`/projects/${id}`, { method: 'PUT', body }),
|
|
remove: (id) => api(`/projects/${id}`, { method: 'DELETE' }),
|
|
addMember: (id, body) => api(`/projects/${id}/members`, { method: 'POST', body }),
|
|
removeMember: (id, uid) => api(`/projects/${id}/members/${uid}`, { method: 'DELETE' }),
|
|
}
|
|
|
|
// 看板列
|
|
export const columnApi = {
|
|
list: (projectId) => api(`/projects/${projectId}/columns`),
|
|
add: (projectId, body) => api(`/projects/${projectId}/columns`, { method: 'POST', body }),
|
|
update: (id, body) => api(`/columns/${id}`, { method: 'PUT', body }),
|
|
remove: (id, moveToColumnId) => api(`/columns/${id}${q({ moveToColumnId })}`, { method: 'DELETE' }),
|
|
order: (projectId, ids) => api(`/projects/${projectId}/columns/order`, { method: 'PUT', body: { ids } }),
|
|
}
|
|
|
|
// 任务
|
|
export const taskApi = {
|
|
list: (projectId) => api(`/projects/${projectId}/tasks`),
|
|
create: (projectId, body) => api(`/projects/${projectId}/tasks`, { method: 'POST', body }),
|
|
detail: (id) => api(`/tasks/${id}`),
|
|
update: (id, body) => api(`/tasks/${id}`, { method: 'PUT', body }),
|
|
reorder: (projectId, ids) => api(`/projects/${projectId}/tasks/reorder`, { method: 'POST', body: { ids } }),
|
|
remove: (id) => api(`/tasks/${id}`, { method: 'DELETE' }),
|
|
copy: (id, projectId) => api(`/tasks/${id}/copy`, { method: 'POST', body: { projectId } }),
|
|
archive: (id) => api(`/tasks/${id}/archive`, { method: 'POST', body: {} }),
|
|
unarchive: (id) => api(`/tasks/${id}/unarchive`, { method: 'POST', body: {} }),
|
|
archivedList: (projectId, params) => api(`/projects/${projectId}/tasks/archived` + q(params)),
|
|
}
|