feat: 补充注释
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
// server/utils/lsky.ts - Lsky 图床上传工具:下载上游图片、重命名、打标签并上传归档。
|
||||
import { createError } from "h3";
|
||||
|
||||
interface ILskyUploadInput {
|
||||
@@ -29,6 +30,14 @@ export interface ILskyUploadedImage {
|
||||
response: ILskyUploadResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从远程图片 URL 下载图片并上传到 Lsky。
|
||||
*
|
||||
* 注意:
|
||||
* - Lsky 地址、Token、storage_id 都来自环境变量,代码不写死密钥。
|
||||
* - 文件名包含 userId、username、时间戳、recordId,方便图床侧追踪来源。
|
||||
* - 返回完整 Lsky 响应供数据库保存,但调用方不要把 token 写入日志。
|
||||
*/
|
||||
export const uploadImageFromUrl = async (
|
||||
input: ILskyUploadInput
|
||||
): Promise<ILskyUploadedImage> => {
|
||||
@@ -85,6 +94,7 @@ export const uploadImageFromUrl = async (
|
||||
};
|
||||
};
|
||||
|
||||
/** 读取并校验 Lsky 环境变量配置 */
|
||||
const getLskyConfig = () => {
|
||||
const baseUrl = process.env.LSKY_BASE_URL?.replace(/\/+$/, "");
|
||||
const token = process.env.LSKY_TOKEN;
|
||||
@@ -109,6 +119,7 @@ const getLskyConfig = () => {
|
||||
};
|
||||
};
|
||||
|
||||
/** 下载上游图片二进制,保留 content-type 供上传和入库使用 */
|
||||
const downloadImage = async (imageUrl: string) => {
|
||||
const response = await fetch(imageUrl);
|
||||
if (!response.ok) {
|
||||
@@ -121,6 +132,7 @@ const downloadImage = async (imageUrl: string) => {
|
||||
};
|
||||
};
|
||||
|
||||
/** 构造图床文件名:userId_username_timestamp_recordId.ext */
|
||||
const buildArchiveFilename = ({
|
||||
userId,
|
||||
username,
|
||||
@@ -139,6 +151,7 @@ const buildArchiveFilename = ({
|
||||
return `${userId}_${safeUsername}_${timestamp}_${recordId.toString()}.${extension}`;
|
||||
};
|
||||
|
||||
/** 给图片打固定标签,便于后续在图床里按项目、用户、记录和模型筛选 */
|
||||
const buildArchiveTags = (userId: number, recordId: bigint) => {
|
||||
return [
|
||||
"AIArtStudio",
|
||||
@@ -148,6 +161,7 @@ const buildArchiveTags = (userId: number, recordId: bigint) => {
|
||||
];
|
||||
};
|
||||
|
||||
/** 清理文件名片段,避免中文/英文/数字/下划线/短横线以外的字符影响上传 */
|
||||
const sanitizeFilenamePart = (value: string) => {
|
||||
const sanitized = value
|
||||
.trim()
|
||||
@@ -158,10 +172,12 @@ const sanitizeFilenamePart = (value: string) => {
|
||||
return sanitized || "user";
|
||||
};
|
||||
|
||||
/** 文件名使用紧凑 UTC 时间戳,避免冒号等字符影响跨平台兼容性 */
|
||||
const formatTimestamp = (date: Date) => {
|
||||
return date.toISOString().replace(/\D/g, "").slice(0, 14);
|
||||
};
|
||||
|
||||
/** 优先按 MIME 推断扩展名,MIME 不认识时再从 URL 路径兜底 */
|
||||
const getImageExtension = (mimeType: string, imageUrl: string) => {
|
||||
const fromMimeType = mimeType.split(";")[0]?.trim().toLowerCase();
|
||||
if (fromMimeType === "image/jpeg") return "jpg";
|
||||
@@ -174,6 +190,7 @@ const getImageExtension = (mimeType: string, imageUrl: string) => {
|
||||
return extension && /^[a-z0-9]+$/.test(extension) ? extension : "png";
|
||||
};
|
||||
|
||||
/** 兼容 Lsky 可能返回的布尔或字符串成功状态 */
|
||||
const isSuccessStatus = (status: unknown) => {
|
||||
return status === true || status === "success" || status === "ok";
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user