Initial commit of akmon project

This commit is contained in:
2026-01-20 08:04:15 +08:00
commit 77a2bab985
1309 changed files with 343305 additions and 0 deletions

158
utils/mediaCacheService.uts Normal file
View File

@@ -0,0 +1,158 @@
export type MediaCacheIndex =UTSJSONObject
type DownloadFileResult = {
statusCode?: number
tempFilePath?: string
tempFilePathArray?: string[]
apFilePath?: string
// UTS不支持索引签名已移除
}
export class MediaCacheService {
static STORAGE_KEY: string = 'media-cache-index'
static index: MediaCacheIndex | null = null
static async init(): Promise<void> {
if (this.index != null) return
try {
const res = await new Promise<UTSJSONObject | null>((resolve) => {
uni.getStorage({
key: this.STORAGE_KEY,
success: (result) => {
const json = result.data as UTSJSONObject
const data = json['data'] as UTSJSONObject | null
resolve(data)
},
fail: () => resolve(null)
})
})
if (res != null) {
this.index = res
} else {
this.index = {}
}
} catch (_) {
this.index = {}
}
}
static async persist(): Promise<void> {
try {
// @ts-ignore
await uni.setStorage({ key: this.STORAGE_KEY, data: this.index ?? {} })
} catch (_) {}
}
static async getCachedPath(url: string): Promise<string> {
await this.init()
if (this.index == null) return url
const index = this.index!
const existing = index[url] as string | null
if (existing != null && await this.fileExists(existing)) {
return existing
}
const saved = await this.downloadAndSave(url)
if (saved != null) {
this.index[url] = saved
await this.persist()
return saved
}
// fallback to remote url if save failed
return url
}
static async clear(url?: string): Promise<void> {
await this.init()
if (this.index == null) return
if (url != null && url != '') {
this.index[url] = null
} else {
this.index = {}
}
await this.persist()
}
private static async fileExists(filePath: string): Promise<boolean> {
return await new Promise<boolean>((resolve) => {
try {
const fs = uni.getFileSystemManager()
let settled = false
const finish = (value: boolean) => {
if (settled) {
return
}
settled = true
resolve(value)
}
fs.access({
path: filePath,
success: () => finish(true),
fail: () => finish(false)
})
} catch (_) {
resolve(false)
}
})
}
private static async downloadAndSave(url: string): Promise<string | null> {
const dlRes = await new Promise<DownloadFileResult | null>((resolve) => {
try {
uni.downloadFile({
url,
success: (res) => {
const result: DownloadFileResult = {
statusCode: res.statusCode,
tempFilePath: res['tempFilePath'] as string | null,
tempFilePathArray: res['tempFilePathArray'] as string[] | null,
apFilePath: res['apFilePath'] as string | null
}
resolve(result)
},
fail: () => resolve(null)
})
} catch (_) {
resolve(null)
}
})
const statusCode = dlRes?.statusCode
if (dlRes == null || statusCode == null || statusCode < 200 || statusCode >= 400) {
return null
}
const tempFilePath = dlRes.tempFilePath ?? (dlRes.tempFilePathArray != null ? dlRes.tempFilePathArray[0] : null) ?? dlRes.apFilePath ?? null
if (tempFilePath == null) return null
const savedPath = await new Promise<string | null>((resolve) => {
try {
const fs = uni.getFileSystemManager()
let settled = false
const finish = (value: string | null) => {
if (settled) {
return
}
settled = true
resolve(value)
}
const options: SaveFileOptions = {
tempFilePath: tempFilePath,
success: (res) => {
const savedPath = res.savedFilePath
if (savedPath != null && savedPath.length > 0) {
finish(savedPath)
return
}
finish(null)
},
fail: () => finish(null)
}
fs.saveFile(options as SaveFileOptions)
} catch (_) {
resolve(null)
}
})
if (savedPath != null && savedPath.length > 0) {
return savedPath
}
return null
}
}
export default MediaCacheService