- 更新陈云、鲁迅、聂耳等故居的展品图片素材 - 更新拼图细节图片 - 优化学习地图底图和详情图 - 更新音频素材 - 优化各故居 store 和页面组件
224 lines
6.3 KiB
TypeScript
224 lines
6.3 KiB
TypeScript
import { useUserStore } from '@/store/userStore'
|
|
|
|
//超时时间
|
|
const TIMEOUT_MS = 1000 * 6
|
|
|
|
// 声明外部依赖(由运行环境提供)
|
|
declare function videoAjax(): VideoAjax
|
|
|
|
interface UserDefineParam {
|
|
lessonId: string
|
|
key?: string | number
|
|
order?: string | number
|
|
content?: string
|
|
}
|
|
|
|
interface VideoAjaxResponseItem {
|
|
content?: string
|
|
}
|
|
|
|
interface VideoAjaxResponse {
|
|
code: number
|
|
msg?: string
|
|
data: {
|
|
value?: VideoAjaxResponseItem[] | string
|
|
}
|
|
}
|
|
|
|
export type UserDefineFetchStatus = 'success' | 'empty' | 'unauthenticated' | 'error'
|
|
|
|
export interface UserDefineFetchResult {
|
|
status: UserDefineFetchStatus
|
|
content: string
|
|
code?: number
|
|
message?: string
|
|
}
|
|
|
|
interface VideoAjax {
|
|
setHost(host: string): void
|
|
addUserDefine(param: UserDefineParam): void
|
|
getUserDefineInfoByUser(
|
|
param: UserDefineParam,
|
|
callback: (data: VideoAjaxResponse | undefined) => void
|
|
): void
|
|
getUserDefineInfo(
|
|
param: UserDefineParam,
|
|
callback: (data: VideoAjaxResponse | undefined) => void
|
|
): void
|
|
finishCourse(param: { order: number; co: string; process: number }): void
|
|
}
|
|
|
|
const LESSON_PREFIX = 'hsgrl'
|
|
|
|
export type StorageBackend = 'auto' | 'yiban' | 'session'
|
|
|
|
export interface StorageOptions {
|
|
backend?: StorageBackend
|
|
}
|
|
|
|
const getStorageKey = (lessonId: string | number, key: string | number) =>
|
|
`${LESSON_PREFIX}_${lessonId}_${key}`
|
|
|
|
const resolveStorageBackend = (backend: StorageBackend = 'auto'): 'yiban' | 'session' => {
|
|
if (backend === 'yiban' || backend === 'session') return backend
|
|
return useUserStore.getState().yibanConnectionStatus === 'connected' ? 'yiban' : 'session'
|
|
}
|
|
|
|
const videoajax: VideoAjax = videoAjax()
|
|
videoajax.setHost('/')
|
|
|
|
// lessonId(课时唯一ID)
|
|
export function setUserDefine(
|
|
lessonId: string | number,
|
|
key: string | number,
|
|
value: string,
|
|
options: StorageOptions = {}
|
|
): void {
|
|
const backend = resolveStorageBackend(options.backend)
|
|
|
|
if (backend === 'session') {
|
|
sessionStorage.setItem(getStorageKey(lessonId, key), value)
|
|
return
|
|
}
|
|
|
|
const param: UserDefineParam = {
|
|
lessonId: `${LESSON_PREFIX}_${lessonId}`,
|
|
key,
|
|
content: value,
|
|
}
|
|
videoajax.addUserDefine(param)
|
|
}
|
|
|
|
// 内部:将回调形式封装为 Promise
|
|
function getUserDefineResultAsyncInternal(
|
|
lessonId: string | number,
|
|
key: string | number,
|
|
options: StorageOptions = {}
|
|
): Promise<UserDefineFetchResult> {
|
|
const backend = resolveStorageBackend(options.backend)
|
|
|
|
if (backend === 'session') {
|
|
const itemValue = sessionStorage.getItem(getStorageKey(lessonId, key))
|
|
return Promise.resolve(
|
|
itemValue === undefined || itemValue === null || itemValue === 'null' || itemValue === ''
|
|
? { status: 'empty', content: '' }
|
|
: { status: 'success', content: itemValue }
|
|
)
|
|
}
|
|
|
|
const param: UserDefineParam = {
|
|
lessonId: `${LESSON_PREFIX}_${lessonId}`,
|
|
order: key,
|
|
}
|
|
|
|
return new Promise((resolve) => {
|
|
let settled = false
|
|
const timeout = setTimeout(() => {
|
|
console.warn(`getUserDefine timeout: lessonId=${lessonId}, key=${key}`)
|
|
done({ status: 'error', content: '', message: '学习进度获取超时' })
|
|
}, TIMEOUT_MS)
|
|
|
|
const done = (result: UserDefineFetchResult) => {
|
|
if (settled) return
|
|
settled = true
|
|
clearTimeout(timeout)
|
|
resolve(result)
|
|
}
|
|
|
|
try {
|
|
videoajax.getUserDefineInfoByUser(param, (res) => {
|
|
try {
|
|
console.log(res)
|
|
|
|
if (res === undefined || res === null || res === ('null' as unknown)) {
|
|
done({ status: 'empty', content: '' })
|
|
return
|
|
}
|
|
|
|
if (res.code === 202) {
|
|
done({ status: 'unauthenticated', content: '', code: res.code, message: res.msg })
|
|
return
|
|
}
|
|
|
|
if (res.code !== 200) {
|
|
done({
|
|
status: 'error',
|
|
content: '',
|
|
code: res.code,
|
|
message: res.msg || '学习进度获取失败',
|
|
})
|
|
return
|
|
}
|
|
|
|
const value = res.data?.value
|
|
if (value === undefined || value === null || value === 'null' || value === '') {
|
|
done({ status: 'empty', content: '' })
|
|
return
|
|
}
|
|
|
|
const json = Array.isArray(value) ? value : []
|
|
const content = json[0]?.content || ''
|
|
done(
|
|
content === '' || content === 'null'
|
|
? { status: 'empty', content: '' }
|
|
: { status: 'success', content }
|
|
)
|
|
} catch (error) {
|
|
console.error('Failed to handle getUserDefine response', error)
|
|
done({ status: 'error', content: '', message: '学习进度解析失败' })
|
|
}
|
|
})
|
|
} catch (error) {
|
|
console.error('Failed to call getUserDefine', error)
|
|
done({ status: 'error', content: '', message: '学习进度获取失败' })
|
|
}
|
|
})
|
|
}
|
|
|
|
// Promise 版本:获取用户自定义数据
|
|
export async function getUserDefineResult(
|
|
lessonId: string | number,
|
|
key: string | number,
|
|
options: StorageOptions = {}
|
|
): Promise<UserDefineFetchResult> {
|
|
return getUserDefineResultAsyncInternal(lessonId, key, options)
|
|
}
|
|
|
|
export function parseUserDefineContent<T>(content: string): T {
|
|
const raw = JSON.parse(content)
|
|
if (useUserStore.getState().yibanConnectionStatus === 'connected') {
|
|
return raw as T
|
|
}
|
|
if (raw && typeof raw === 'object' && 'state' in raw) {
|
|
return (raw as { state: T }).state
|
|
}
|
|
return raw as T
|
|
}
|
|
|
|
// 根据课时顺序号(所处课程的第几课时)更新对应易班平台上的每个环节进度(异步)
|
|
export async function setCourseTimeProgress(order: number): Promise<boolean> {
|
|
if (useUserStore.getState().yibanConnectionStatus !== 'connected') {
|
|
console.info(`[yiban] skip finishCourse: disconnected, order=${order}`)
|
|
return false
|
|
}
|
|
|
|
const courseid = useUserStore.getState().courseId
|
|
// var courseid = getCookie(lesson+"_course_id");//获取url链接的课程ID
|
|
// const courseid = await getLtDefine('10000')
|
|
|
|
if (courseid === undefined || courseid === null || courseid === '') {
|
|
console.info(`[yiban] skip finishCourse: missing courseId, order=${order}`)
|
|
return false
|
|
}
|
|
|
|
if (order <= 0) {
|
|
console.info(`[yiban] skip finishCourse: invalid order=${order}`)
|
|
return false
|
|
}
|
|
|
|
const param2 = { order, co: courseid, process: 100 }
|
|
console.info('[yiban] finishCourse', param2)
|
|
videoajax.finishCourse(param2)
|
|
return true
|
|
}
|