// server/api/images/history/[id]/public.post.ts - 生图历史公开接口:将当前用户单条生图记录发布到广场。 import type { IImagePublicStateData } from "#shared/types/openai"; import { clearNewApiAuthCookies, createApiLogger, createErrorResponse, createSuccessResponse, createUpstreamErrorResponse, getNewApiUserIdFromCookie, isUnauthorizedError, publishImageGenerationToPlaza, toSafeLogError } from "~~/server/utils"; /** * POST /api/images/history/:id/public * * 流程: * 1. 从 httpOnly cookie 读取当前用户 ID。 * 2. 只允许公开当前用户、未软删除的生图记录。 * 3. 允许图片尚未归档时先创建公开记录;广场列表会等 hostedImageUrl 可用后再展示。 * 4. 不返回上游响应、图床响应或内部错误详情。 */ export default defineEventHandler(async (event) => { const logger = createApiLogger("images.history.public.publish"); logger.info("开始"); try { const userId = getNewApiUserIdFromCookie(event); const recordId = parseRecordId(getRouterParam(event, "id")); logger.info("公开参数", { userId, recordId: recordId.toString() }); const result = await publishImageGenerationToPlaza(userId, recordId); if (!result) { logger.warn("记录不存在", { userId, recordId: recordId.toString() }); return createErrorResponse(404, "生图记录不存在"); } if (result === "REMOVED") { logger.warn("记录已下架,不能重新公开", { userId, recordId: recordId.toString() }); return createErrorResponse(403, "图片已下架,无法公开"); } logger.done("成功", { userId, recordId: recordId.toString() }); return createSuccessResponse(result, "图片已公开"); } catch (error) { if (isUnauthorizedError(error)) { clearNewApiAuthCookies(event); logger.warn("未登录或登录态失效", { error: toSafeLogError(error) }); return createErrorResponse(401, "未登录"); } if (isBadRequestError(error)) { return createErrorResponse(400, "生图记录 ID 不正确"); } logger.error("失败", { error: toSafeLogError(error) }); return createUpstreamErrorResponse(error, "公开图片失败"); } }); /** 校验并解析路由里的生图记录 ID */ const parseRecordId = (value: string | undefined): bigint => { if (!value || !/^\d+$/.test(value)) { throw createError({ statusCode: 400, statusMessage: "生图记录 ID 不正确" }); } return BigInt(value); }; const isBadRequestError = (error: unknown): boolean => { return ( typeof error === "object" && error !== null && "statusCode" in error && error.statusCode === 400 ); };