This commit is contained in:
Your Name
2026-03-23 18:02:16 +08:00
parent 18fee2e8f8
commit 250d173c2f
525 changed files with 10659 additions and 793 deletions
+35
View File
@@ -0,0 +1,35 @@
/** 从视频通话区域截取当前最大的一路 video 帧(WebRTC 画面) */
export async function captureVideoFrameFromElement(
container: HTMLElement
): Promise<Blob | null> {
const videos = Array.from(container.querySelectorAll('video')) as HTMLVideoElement[]
let best: HTMLVideoElement | null = null
let bestArea = 0
for (const v of videos) {
if (v.readyState < 2) continue
const vw = v.videoWidth || v.clientWidth
const vh = v.videoHeight || v.clientHeight
const area = vw * vh
if (area > bestArea) {
bestArea = area
best = v
}
}
if (!best) return null
const vw = best.videoWidth || best.clientWidth
const vh = best.videoHeight || best.clientHeight
if (!vw || !vh) return null
const canvas = document.createElement('canvas')
canvas.width = vw
canvas.height = vh
const ctx = canvas.getContext('2d')
if (!ctx) return null
try {
ctx.drawImage(best, 0, 0, vw, vh)
} catch {
return null
}
return new Promise((resolve) => {
canvas.toBlob((b) => resolve(b), 'image/jpeg', 0.92)
})
}
-5
View File
@@ -1,6 +1,5 @@
import { AxiosError, type AxiosRequestConfig } from 'axios'
import { merge } from 'lodash'
import NProgress from 'nprogress'
import configs from '@/config'
import { PageEnum } from '@/enums/pageEnum'
@@ -15,7 +14,6 @@ import type { AxiosHooks } from './type'
// 处理axios的钩子函数
const axiosHooks: AxiosHooks = {
requestInterceptorsHook(config) {
NProgress.start()
const { withToken, isParamsToData } = config.requestOptions
const params = config.params || {}
const headers = config.headers || {}
@@ -38,11 +36,9 @@ const axiosHooks: AxiosHooks = {
return config
},
requestInterceptorsCatchHook(err) {
NProgress.done()
return err
},
async responseInterceptorsHook(response) {
NProgress.done()
const { isTransformResponse, isReturnDefaultResponse } = response.config.requestOptions
//返回默认响应,当需要获取响应头及其他数据时可使用
@@ -80,7 +76,6 @@ const axiosHooks: AxiosHooks = {
}
},
responseInterceptorsCatchHook(error) {
NProgress.done()
if (error.code !== AxiosError.ERR_CANCELED) {
error.message && feedback.msgError(error.message)
}
+56
View File
@@ -0,0 +1,56 @@
function collectErrorText(err: unknown): string {
const parts: string[] = []
let cur: unknown = err
let depth = 0
while (cur != null && depth < 6) {
if (typeof cur === 'string') {
parts.push(cur)
break
}
if (typeof cur === 'object') {
const o = cur as Record<string, unknown>
if (typeof o.message === 'string') parts.push(o.message)
if (typeof o.name === 'string') parts.push(o.name)
if (typeof o.code !== 'undefined') parts.push(String(o.code))
cur = o.cause
} else {
parts.push(String(cur))
break
}
depth++
}
return parts.join(' ').toLowerCase()
}
/** 腾讯云通话套餐/能力类错误常见码(如 wasm 日志 error_code:-1001 */
export const TUICALL_PACKAGE_ERROR_CODE = -1001
/** 是否为「套餐不含该能力 / 需续费」类错误(如 TUICallEngineError: The package you purchased does not support this ability */
export function isTUICallPackageAbilityError(err: unknown): boolean {
if (err && typeof err === 'object') {
const o = err as Record<string, unknown>
const code = o.code ?? o.error_code
if (code === TUICALL_PACKAGE_ERROR_CODE || code === String(TUICALL_PACKAGE_ERROR_CODE)) {
return true
}
}
const text = collectErrorText(err)
return (
text.includes('does not support this ability') ||
text.includes('package you purchased') ||
(text.includes('-1001') && text.includes('does not support'))
)
}
/** 用户可见短文案 */
export function getTUICallPackageArrearsMessage(): string {
return '套餐欠费或未开通该能力,请联系管理员在腾讯云续费或升级套餐。'
}
/** 发起通话等失败时:套餐类错误用友好文案,否则返回原始信息 */
export function formatTUICallUserError(err: unknown, defaultMessage = '通话操作失败'): string {
if (isTUICallPackageAbilityError(err)) return getTUICallPackageArrearsMessage()
if (err instanceof Error) return err.message || defaultMessage
if (typeof err === 'string') return err || defaultMessage
return defaultMessage
}