release: v1.4.0 — 标签系统、操作日志扩展与文档截图更新
ci / ci (22, ubuntu-latest) (push) Canceled after 0s
GitHub Release / release (push) Canceled after 0s
Publish Docker image / build (linux/amd64, ubuntu-latest, amd64) (push) Canceled after 0s
Publish Docker image / build (linux/arm64, ubuntu-24.04-arm, arm64) (push) Canceled after 0s
Publish Docker image / merge (push) Canceled after 0s

- 每用户标签与彩色打标,图库 OR/AND 筛选与批量打标
- 操作日志记录登录、删除、设置与标签操作
- API 标签/打标接口;README 与文档站截图同步
This commit is contained in:
O96u committed 2026-09-09 14:46:52 +08:00
1 parent f17d79b236
commit 737235acff
110 files changed
+5881 -778

No files matched your search

+24 -14
View File
@@ -15,7 +15,8 @@ import type { LogSource } from './db'
import { generateImageKey } from './image-key'
import { buildImageItem, sanitizeOriginalName } from './image-response'
import { getStorageLayout, getWebpQuality } from './env'
import { insertActivityLog } from './db'
import { logActivity } from './activity-log'
import { attachTagsAfterUpload, getTagsForImageKeys } from './tags'
import { putImage } from './storage'
import { logInfo, logException } from './logger'
@@ -64,6 +65,7 @@ export async function processSingleImageUpload(
filename?: string
source?: LogSource
userId?: number | null
tagIds?: number[]
}
): Promise<{ item: ImageItem } | { error: UploadErrorItem }> {
const originalName = sanitizeOriginalName(input.filename ?? 'image')
@@ -149,16 +151,15 @@ export async function processSingleImageUpload(
}
}
insertActivityLog({
logActivity(event, {
action: 'upload',
key,
originalName,
size: compressed.bytes.byteLength,
contentType: compressed.mime,
source: input.source ?? 'web',
source: input.source,
userId: input.userId ?? null,
backendId,
createdAt: uploadedAt
backendId
})
logInfo('upload success', {
@@ -168,17 +169,26 @@ export async function processSingleImageUpload(
source: input.source ?? 'web'
})
if (input.tagIds?.length && input.userId != null) {
attachTagsAfterUpload(key, input.tagIds, input.userId)
}
const item = buildImageItem({
key,
event,
originalName,
contentType: compressed.mime,
size: compressed.bytes.byteLength,
uploadedAt
})
const tags = getTagsForImageKeys([key]).get(key) ?? []
return {
item: {
...buildImageItem({
key,
event,
originalName,
contentType: compressed.mime,
size: compressed.bytes.byteLength,
uploadedAt
}),
uploadSource: input.source ?? 'web'
...item,
uploadSource: input.source === 'api' ? 'api' : 'web',
...(tags.length ? { tags } : {})
}
}
}