feat: 重构 IdentifyFace.vue 为 Hooks 架构
- 新增 hooks/ 目录,包含三个专用 Hook: * useVoiceGeneration - 语音生成和校验逻辑 * useDigitalHumanGeneration - 数字人视频生成逻辑 * useIdentifyFaceController - 协调两个子 Hook 的控制器 - 新增 types/identify-face.ts 完整类型定义 - 重构 IdentifyFace.vue 使用 hooks 架构: * 视图层与业务逻辑分离 * 状态管理清晰化 * 模块解耦,逻辑清晰 - 遵循单一职责原则,每个 Hook 只负责一个领域 - 提升代码可测试性和可维护性 - 支持两种视频素材来源:素材库选择和直接上传 - 实现语音生成优先校验的业务规则 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,30 @@ class TokenManager {
|
||||
this.subscribers = [] // 订阅token变化的回调
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 LocalDateTime 格式为毫秒时间戳(使用 dayjs)
|
||||
* @param {string} dateTimeStr - LocalDateTime 格式字符串,如 "2025-12-27T10:27:42"
|
||||
* @returns {number} Unix 时间戳(毫秒)
|
||||
*/
|
||||
parseLocalDateTime(dateTimeStr) {
|
||||
if (!dateTimeStr) return 0
|
||||
|
||||
// 使用 dayjs 解析 LocalDateTime 格式
|
||||
const normalizedStr = dateTimeStr.includes(' ')
|
||||
? dateTimeStr.replace(' ', 'T')
|
||||
: dateTimeStr
|
||||
|
||||
const dayjs = require('dayjs')
|
||||
const parsedTime = dayjs(normalizedStr)
|
||||
|
||||
if (!parsedTime.isValid()) {
|
||||
console.warn('[TokenManager] 无法解析过期时间:', dateTimeStr)
|
||||
return 0
|
||||
}
|
||||
|
||||
return parsedTime.valueOf() // 返回毫秒时间戳
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取访问令牌
|
||||
* @returns {string|null} 访问令牌,如果不存在则返回 null
|
||||
@@ -100,6 +124,7 @@ class TokenManager {
|
||||
* @param {string} tokenInfo.accessToken - 访问令牌(必填)
|
||||
* @param {string} tokenInfo.refreshToken - 刷新令牌(可选)
|
||||
* @param {number} tokenInfo.expiresIn - 令牌有效期(秒,可选)
|
||||
* @param {string|number} tokenInfo.expiresTime - 过期时间(可选,支持 LocalDateTime 字符串、数字格式)
|
||||
* @param {string} tokenInfo.tokenType - 令牌类型,默认为 'Bearer'
|
||||
*/
|
||||
setTokens(tokenInfo) {
|
||||
@@ -107,6 +132,7 @@ class TokenManager {
|
||||
accessToken,
|
||||
refreshToken,
|
||||
expiresIn,
|
||||
expiresTime,
|
||||
tokenType = 'Bearer'
|
||||
} = tokenInfo
|
||||
|
||||
@@ -116,9 +142,6 @@ class TokenManager {
|
||||
return
|
||||
}
|
||||
|
||||
// 将过期时间从秒转换为毫秒时间戳
|
||||
const expiresTime = expiresIn ? Date.now() + (expiresIn * 1000) : 0
|
||||
|
||||
// 存储到 localStorage
|
||||
localStorage.setItem(TOKEN_KEYS.ACCESS_TOKEN, accessToken)
|
||||
|
||||
@@ -126,8 +149,24 @@ class TokenManager {
|
||||
localStorage.setItem(TOKEN_KEYS.REFRESH_TOKEN, refreshToken)
|
||||
}
|
||||
|
||||
// 处理过期时间
|
||||
let expiresTimeMs = 0
|
||||
if (expiresTime) {
|
||||
localStorage.setItem(TOKEN_KEYS.EXPIRES_TIME, String(expiresTime))
|
||||
// 检查类型并转换
|
||||
if (typeof expiresTime === 'string' && expiresTime.includes('T')) {
|
||||
// LocalDateTime 格式
|
||||
expiresTimeMs = this.parseLocalDateTime(expiresTime)
|
||||
} else if (typeof expiresTime === 'number') {
|
||||
// 数字格式(可能是秒或毫秒)
|
||||
expiresTimeMs = expiresTime > 10000000000 ? expiresTime : expiresTime * 1000
|
||||
} else if (expiresIn) {
|
||||
// 通过 expiresIn 计算
|
||||
expiresTimeMs = Date.now() + (expiresIn * 1000)
|
||||
}
|
||||
|
||||
if (expiresTimeMs) {
|
||||
localStorage.setItem(TOKEN_KEYS.EXPIRES_TIME, String(expiresTimeMs))
|
||||
}
|
||||
}
|
||||
|
||||
localStorage.setItem(TOKEN_KEYS.TOKEN_TYPE, tokenType)
|
||||
|
||||
Reference in New Issue
Block a user