release: v1.2.5 — 图库页、图片详情弹层与列表体验优化
This commit is contained in:
1 parent
81dcc2c15e
commit
270af4e707
22 files changed
+587
-52
No files matched your search
@@ -6,7 +6,7 @@ import {
|
||||
MAX_LIST_LIMIT
|
||||
} from '../../utils/constants'
|
||||
import { createApiError } from '../../utils/api-error'
|
||||
import { listUserIdUsernameMap } from '../../utils/db'
|
||||
import { getUploadSourcesForKeys, listUserIdUsernameMap } from '../../utils/db'
|
||||
import { mapStoredImageToItem } from '../../utils/image-response'
|
||||
import { listStorageBackendNameMap } from '../../utils/storage-backends'
|
||||
import { readBackendIdQuery } from '../../utils/image-query'
|
||||
@@ -38,8 +38,9 @@ export default defineEventHandler(async (event) => {
|
||||
const user = await getCurrentUser(event)
|
||||
const ownerMap = user?.role === 'admin' ? listUserIdUsernameMap() : undefined
|
||||
const backendMap = listStorageBackendNameMap()
|
||||
const sourceMap = getUploadSourcesForKeys(listing.items.map(item => item.key))
|
||||
const items = listing.items.map(stored =>
|
||||
mapStoredImageToItem(event, stored, { ownerMap, backendMap })
|
||||
mapStoredImageToItem(event, stored, { ownerMap, backendMap, sourceMap })
|
||||
)
|
||||
|
||||
items.sort((a, b) => b.uploadedAt.localeCompare(a.uploadedAt))
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
MAX_LIST_LIMIT
|
||||
} from '../../utils/constants'
|
||||
import { createApiError } from '../../utils/api-error'
|
||||
import { listUserIdUsernameMap } from '../../utils/db'
|
||||
import { getUploadSourcesForKeys, listUserIdUsernameMap } from '../../utils/db'
|
||||
import { mapStoredImageToItem } from '../../utils/image-response'
|
||||
import { listStorageBackendNameMap } from '../../utils/storage-backends'
|
||||
import { readBackendIdQuery } from '../../utils/image-query'
|
||||
@@ -47,8 +47,9 @@ export default defineEventHandler(async (event) => {
|
||||
const user = await getCurrentUser(event)
|
||||
const ownerMap = user?.role === 'admin' ? listUserIdUsernameMap() : undefined
|
||||
const backendMap = listStorageBackendNameMap()
|
||||
const sourceMap = getUploadSourcesForKeys(result.items.map(item => item.key))
|
||||
const items = result.items.map(stored =>
|
||||
mapStoredImageToItem(event, stored, { ownerMap, backendMap })
|
||||
mapStoredImageToItem(event, stored, { ownerMap, backendMap, sourceMap })
|
||||
)
|
||||
|
||||
items.sort((a, b) => b.uploadedAt.localeCompare(a.uploadedAt))
|
||||
|
||||
@@ -445,6 +445,34 @@ export function insertActivityLog(input: ActivityLogInput): void {
|
||||
}
|
||||
}
|
||||
|
||||
/** 按图片 key 查最近一次上传记录的来源(网页 / API) */
|
||||
export function getUploadSourcesForKeys(keys: string[]): Map<string, LogSource> {
|
||||
const result = new Map<string, LogSource>()
|
||||
if (!keys.length) return result
|
||||
|
||||
const placeholders = keys.map(() => '?').join(', ')
|
||||
const rows = getDb().prepare(`
|
||||
SELECT al.key, al.source
|
||||
FROM activity_logs al
|
||||
INNER JOIN (
|
||||
SELECT key, MAX(id) AS max_id
|
||||
FROM activity_logs
|
||||
WHERE action = 'upload' AND key IN (${placeholders})
|
||||
GROUP BY key
|
||||
) latest ON al.id = latest.max_id
|
||||
`).all(...keys) as Array<{ key: string, source: string }>
|
||||
|
||||
for (const row of rows) {
|
||||
const raw = row.source
|
||||
const source = raw === 'twikoo' ? 'api' : raw
|
||||
if (source === 'web' || source === 'api') {
|
||||
result.set(row.key, source)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export function listActivityLogs(options: {
|
||||
limit: number
|
||||
page?: number
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { H3Event } from 'h3'
|
||||
import type { ImageItem } from '~/types/image'
|
||||
import type { LogSource } from './db'
|
||||
import type { AllowedMimeType } from './constants'
|
||||
import type { StoredImage } from './storage'
|
||||
import { getImageBaseUrl, isHideFolderInUrl } from './env'
|
||||
@@ -50,6 +51,7 @@ export function mapStoredImageToItem(
|
||||
options?: {
|
||||
ownerMap?: Map<number, string>
|
||||
backendMap?: Map<string, { name: string, type: StorageBackendType }>
|
||||
sourceMap?: Map<string, LogSource>
|
||||
}
|
||||
): ImageItem {
|
||||
const item = buildImageItem({
|
||||
@@ -64,16 +66,14 @@ export function mapStoredImageToItem(
|
||||
|
||||
const owner = resolveImageOwner(stored.userId, options?.ownerMap)
|
||||
const storage = resolveImageStorage(stored.backendId, options?.backendMap)
|
||||
const uploadSource = options?.sourceMap?.get(stored.key)
|
||||
|
||||
if (owner || storage) {
|
||||
return {
|
||||
...item,
|
||||
...(owner ? { owner } : {}),
|
||||
...(storage ? { storage } : {})
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
...(owner ? { owner } : {}),
|
||||
...(storage ? { storage } : {}),
|
||||
...(uploadSource ? { uploadSource } : {})
|
||||
}
|
||||
|
||||
return item
|
||||
}
|
||||
|
||||
export function buildImageUrl(
|
||||
|
||||
@@ -169,14 +169,17 @@ export async function processSingleImageUpload(
|
||||
})
|
||||
|
||||
return {
|
||||
item: buildImageItem({
|
||||
key,
|
||||
event,
|
||||
originalName,
|
||||
contentType: compressed.mime,
|
||||
size: compressed.bytes.byteLength,
|
||||
uploadedAt
|
||||
})
|
||||
item: {
|
||||
...buildImageItem({
|
||||
key,
|
||||
event,
|
||||
originalName,
|
||||
contentType: compressed.mime,
|
||||
size: compressed.bytes.byteLength,
|
||||
uploadedAt
|
||||
}),
|
||||
uploadSource: input.source ?? 'web'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user