136 lines
4.0 KiB
TypeScript
136 lines
4.0 KiB
TypeScript
/**
|
||
* 任务-详情单图编辑接口
|
||
*
|
||
* PATCH - 重命名包内图片(只改文件名,不改扩展名)
|
||
* POST - 替换包内图片(body: { uploadId },文件先走受控分片上传)
|
||
* DELETE - 删除包内图片(连带重建分组 ZIP 与 all.zip)
|
||
*
|
||
* 仅任务-详情已完成素材可用;权限走 canManageMaterial
|
||
* (上传者 / 托管部门成员 / 系统管理员)。
|
||
*/
|
||
|
||
import { NextRequest, NextResponse } from 'next/server'
|
||
import { getServerSession } from 'next-auth'
|
||
import { authOptions } from '@/lib/auth'
|
||
import {
|
||
TaskDetailAssetEditError,
|
||
} from '@/lib/task-detail-asset-edit'
|
||
import {
|
||
submitTaskDetailChange,
|
||
TaskDetailChangeApprovalError,
|
||
} from '@/lib/task-detail-change-approval'
|
||
|
||
export const runtime = 'nodejs'
|
||
export const dynamic = 'force-dynamic'
|
||
export const maxDuration = 10800
|
||
|
||
type RouteParams = { params: { id: string; assetId: string } }
|
||
|
||
function getSessionUser(session: unknown): { id: string; role?: string | null; isSuperAdmin?: boolean } | null {
|
||
const user = (session as { user?: { id?: string; role?: string; isSuperAdmin?: boolean } } | null)?.user
|
||
if (!user?.id) {
|
||
return null
|
||
}
|
||
return { id: user.id, role: user.role ?? null, isSuperAdmin: Boolean(user.isSuperAdmin) }
|
||
}
|
||
|
||
function handleEditError(error: unknown) {
|
||
if (error instanceof TaskDetailAssetEditError || error instanceof TaskDetailChangeApprovalError) {
|
||
return NextResponse.json(
|
||
{ success: false, error: error.message },
|
||
{ status: error.statusCode },
|
||
)
|
||
}
|
||
console.error('[materials/asset-edit] error:', error)
|
||
return NextResponse.json(
|
||
{ success: false, error: '图片编辑失败,请稍后重试' },
|
||
{ status: 500 },
|
||
)
|
||
}
|
||
|
||
export async function PATCH(
|
||
request: NextRequest,
|
||
{ params }: RouteParams,
|
||
) {
|
||
try {
|
||
const session = await getServerSession(authOptions)
|
||
const operator = getSessionUser(session)
|
||
if (!operator) {
|
||
return NextResponse.json({ success: false, error: '未登录' }, { status: 401 })
|
||
}
|
||
|
||
const body = await request.json().catch(() => null)
|
||
const newFileName = String((body as { newFileName?: unknown } | null)?.newFileName || '').trim()
|
||
if (!newFileName) {
|
||
return NextResponse.json(
|
||
{ success: false, error: '缺少新文件名' },
|
||
{ status: 400 },
|
||
)
|
||
}
|
||
|
||
const result = await submitTaskDetailChange(params.id, operator, [{
|
||
kind: 'rename',
|
||
assetId: params.assetId,
|
||
newFileName,
|
||
}])
|
||
|
||
return NextResponse.json({ success: true, ...result })
|
||
} catch (error) {
|
||
return handleEditError(error)
|
||
}
|
||
}
|
||
|
||
export async function POST(
|
||
request: NextRequest,
|
||
{ params }: RouteParams,
|
||
) {
|
||
try {
|
||
const session = await getServerSession(authOptions)
|
||
const operator = getSessionUser(session)
|
||
if (!operator) {
|
||
return NextResponse.json({ success: false, error: '未登录' }, { status: 401 })
|
||
}
|
||
|
||
const body = await request.json().catch(() => null)
|
||
const uploadId = String((body as { uploadId?: unknown } | null)?.uploadId || '').trim()
|
||
if (!uploadId) {
|
||
return NextResponse.json(
|
||
{ success: false, error: '缺少替换文件的上传会话,请重新选择文件' },
|
||
{ status: 400 },
|
||
)
|
||
}
|
||
|
||
const result = await submitTaskDetailChange(params.id, operator, [{
|
||
kind: 'replace',
|
||
assetId: params.assetId,
|
||
uploadId,
|
||
}])
|
||
|
||
return NextResponse.json({ success: true, ...result })
|
||
} catch (error) {
|
||
return handleEditError(error)
|
||
}
|
||
}
|
||
|
||
export async function DELETE(
|
||
_request: NextRequest,
|
||
{ params }: RouteParams,
|
||
) {
|
||
try {
|
||
const session = await getServerSession(authOptions)
|
||
const operator = getSessionUser(session)
|
||
if (!operator) {
|
||
return NextResponse.json({ success: false, error: '未登录' }, { status: 401 })
|
||
}
|
||
|
||
const result = await submitTaskDetailChange(params.id, operator, [{
|
||
kind: 'delete',
|
||
assetId: params.assetId,
|
||
}])
|
||
|
||
return NextResponse.json({ success: true, ...result })
|
||
} catch (error) {
|
||
return handleEditError(error)
|
||
}
|
||
}
|