library-picturebook-activity/lesingle-aicreate-client/src/utils/store.js
En 3c24cc3102 feat: 添加CLAUDE.md项目指导文件及AI创作客户端更新
添加 CLAUDE.md 用于 Claude Code 项目导航,包含架构说明和开发规范。
更新 AI 创作客户端至 V4.0,新增后端对接示例项目。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 12:11:15 +08:00

109 lines
3.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { reactive } from 'vue'
/**
* 简单全局状态(不用 PiniaC端足够轻量
*
* ★ 企业集成关键:
* - phone: 当前登录用户手机号(企业从自己的登录系统获取)
* - orgId: 机构ID乐读派分配给企业的唯一标识
* - sessionToken: 会话令牌(企业后端调用 /api/v1/auth/session 换取,短期有效)
*
* 企业集成流程:
* 1. 企业后端调用 POST /api/v1/auth/session { orgId, appSecret, phone } 换取 sessionToken
* 2. 企业重定向用户到 H5: ?token=sess_xxx&phone=138xxx
* 3. H5 自动读取 token所有 API 调用使用 Authorization: Bearer sess_xxx
*
* 安全说明: appSecret 只存在于企业服务端,不会到达浏览器
*/
export const store = reactive({
phone: localStorage.getItem('le_phone') || '',
orgId: localStorage.getItem('le_orgId') || '',
appSecret: localStorage.getItem('le_appSecret') || '',
sessionToken: sessionStorage.getItem('le_sessionToken') || '', // 企业生产模式用
// 创作流程数据
imageUrl: '',
extractId: '',
characters: [],
selectedCharacter: null,
selectedStyle: '',
storyData: null,
workId: '',
workDetail: null,
setPhone(phone) {
this.phone = phone
localStorage.setItem('le_phone', phone)
},
// 开发调试模式:直接设 orgId + appSecretHMAC 签名)
setOrg(orgId, appSecret) {
this.orgId = orgId
this.appSecret = appSecret
localStorage.setItem('le_orgId', orgId)
localStorage.setItem('le_appSecret', appSecret)
},
// 企业生产模式:通过 auth/session 换取 sessionTokenBearer Token
setSession(orgId, sessionToken) {
this.orgId = orgId
this.sessionToken = sessionToken
localStorage.setItem('le_orgId', orgId)
sessionStorage.setItem('le_orgId', orgId)
sessionStorage.setItem('le_sessionToken', sessionToken)
},
reset() {
this.imageUrl = ''
this.extractId = ''
this.characters = []
this.selectedCharacter = null
this.selectedStyle = ''
this.storyData = null
this.workId = ''
this.workDetail = null
localStorage.removeItem('le_workId')
},
// 企业认证回调URL
authRedirectUrl: '',
clearSession() {
this.sessionToken = ''
sessionStorage.removeItem('le_sessionToken')
},
saveRecoveryState() {
const recovery = {
path: window.location.pathname || '/',
workId: this.workId || localStorage.getItem('le_workId') || '',
imageUrl: this.imageUrl || '',
extractId: this.extractId || '',
selectedStyle: this.selectedStyle || '',
savedAt: Date.now()
}
sessionStorage.setItem('le_recovery', JSON.stringify(recovery))
},
restoreRecoveryState() {
const raw = sessionStorage.getItem('le_recovery')
if (!raw) return null
try {
const recovery = JSON.parse(raw)
if (Date.now() - recovery.savedAt > 30 * 60 * 1000) {
sessionStorage.removeItem('le_recovery')
return null
}
if (recovery.workId) this.workId = recovery.workId
if (recovery.imageUrl) this.imageUrl = recovery.imageUrl
if (recovery.extractId) this.extractId = recovery.extractId
if (recovery.selectedStyle) this.selectedStyle = recovery.selectedStyle
sessionStorage.removeItem('le_recovery')
return recovery
} catch {
sessionStorage.removeItem('le_recovery')
return null
}
}
})