feat: 补全皮肤站管理台 Mod 页上传与批量操作
- 新增 Mod 上传弹窗:拖拽或选择 .jar、多文件、大小限制、规则标签附加 - 上传流程:xxHash64 查重、同名检测、名称冲突确认(覆盖/跳过)、429 限流退避重试、HashDiff 重传 - Mod 列表支持多选模式:全选本页、取消选择、批量删除 - 新增服务器地址过滤,配合名称搜索与标签筛选 - 补充 Mod 相关 API:文件哈希、按哈希/名称查重、上传、批量更新 - 引入 xxhash-wasm 依赖 - 中英文各补 32 个文案
This commit is contained in:
1 parent
fbcbb803ac
commit
87de306245
7 files changed
+767
-4
No files matched your search
@@ -2015,3 +2015,59 @@ export function skinSiteAdminInviteUser(email: string): Promise<SkinSiteResponse
|
||||
body: { email },
|
||||
})
|
||||
}
|
||||
|
||||
export function skinSiteModHashFromFile(file: File): Promise<string> {
|
||||
return import('xxhash-wasm').then(async ({ default: xxhash }) => {
|
||||
const { create64 } = await xxhash()
|
||||
const hasher = create64()
|
||||
const reader = file.stream().getReader()
|
||||
for (;;) {
|
||||
const { done, value } = await reader.read()
|
||||
if (done) break
|
||||
hasher.update(value)
|
||||
}
|
||||
const raw: bigint = hasher.digest()
|
||||
const mask = (1n << 64n) - 1n
|
||||
const v = raw & mask
|
||||
const signed = v >= 1n << 63n ? v - (1n << 64n) : v
|
||||
return signed.toString()
|
||||
})
|
||||
}
|
||||
|
||||
export function skinSiteModExistsByHash(hash: string): Promise<SkinSiteResponse<unknown>> {
|
||||
return skinSiteRequest<unknown>('query/hash/' + encodeURIComponent(hash), { type: 'mod' })
|
||||
}
|
||||
|
||||
export function skinSiteModExistsByName(modName: string): Promise<SkinSiteResponse<unknown>> {
|
||||
const q = new URLSearchParams({ mod_name: modName })
|
||||
return skinSiteRequest<unknown>('query/name?' + q.toString(), { type: 'mod' })
|
||||
}
|
||||
|
||||
export async function skinSiteUploadMod(
|
||||
file: File,
|
||||
ruleTagIds: number[] = [],
|
||||
overwrite = false,
|
||||
): Promise<SkinSiteResponse<string>> {
|
||||
const hash = await skinSiteModHashFromFile(file)
|
||||
const form = new FormData()
|
||||
form.append('mods', file, file.name)
|
||||
const query = new URLSearchParams()
|
||||
if (ruleTagIds.length) query.set('rule_tag_ids', ruleTagIds.join(','))
|
||||
if (overwrite) query.set('overwrite', 'true')
|
||||
const suffix = query.size ? '?' + query.toString() : ''
|
||||
return skinSiteRequest<string>('upload/' + hash + suffix, {
|
||||
method: 'POST',
|
||||
type: 'mod',
|
||||
form,
|
||||
})
|
||||
}
|
||||
|
||||
export function skinSiteUpdateMultiModInfo(
|
||||
mods: SkinSiteModInfo[],
|
||||
): Promise<SkinSiteResponse<SkinSiteModInfo[]>> {
|
||||
return skinSiteRequest<SkinSiteModInfo[]>('update/info/multi', {
|
||||
method: 'POST',
|
||||
type: 'mod',
|
||||
body: mods,
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user