feat(web): 桌面端前端 Web 独立部署适配——浏览器降级桥+登录态引导+页面动态修正
- 新增 web-fallback.ts:无 pywebview 时以浏览器能力降级(文件选择/上传/模板下载/配置), 其余桌面能力(enqueue_json/vc_*/folder 选择等)保持 undefined 交由页面既有请在本地客户端中打开提示 - 新增 ensure-auth.ts:无 uid 时经 /newApi/check_login 恢复登录态,无 token/失效跳登录页; 21 个入口 main.ts 挂载前先引导(桌面端已注入 uid 时零开销) - pywebview.ts:getPywebviewApi() 在纯浏览器环境返回降级桥;新增 isDesktopRuntime 标志 (首页更新面板/退出链接据此区分桌面与 Web);hasPywebview 语义修正为真实桥判定 - 登录页跳转、首页登出链接、品牌检测页 hasBridge 判定(select_brand_folder 存在性)适配 Web
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
<span class="header-title">数富AI</span>
|
||||
<div class="header-right">
|
||||
<button
|
||||
v-if="isDesktopRuntime"
|
||||
type="button"
|
||||
class="header-update-btn"
|
||||
title="检测更新"
|
||||
@@ -25,7 +26,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<span class="username-text">{{ username || '未登录' }}</span>
|
||||
<a href="/logout" class="logout-link">退出</a>
|
||||
<a :href="logoutHref" class="logout-link">退出</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -78,6 +79,7 @@
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { requestGetJson } from '@/shared/api/http'
|
||||
import { buildJavaUrl } from '@/shared/api/url'
|
||||
import { isDesktopRuntime } from '@/shared/bridges/pywebview'
|
||||
import { resolvePageHref } from '@/shared/page-prefix'
|
||||
|
||||
const username = ref('')
|
||||
@@ -88,6 +90,11 @@ const updateReady = ref(false)
|
||||
const updateFileUrl = ref('')
|
||||
const toastText = ref('')
|
||||
|
||||
// 桌面端走 Flask /logout(清 cookie 302 登录页);Web 独立部署 / dev 跳登录页并清本地 token(login.html?logout=1)
|
||||
const logoutHref = computed(() =>
|
||||
isDesktopRuntime.value ? '/logout' : `${resolvePageHref('/new_web_source/login.html')}?logout=1`,
|
||||
)
|
||||
|
||||
type PermissionState = { amazon: boolean; video: boolean; image: boolean }
|
||||
const permissionState = ref<PermissionState>({ amazon: false, video: false, image: false })
|
||||
const permissionUnavailable = ref(false)
|
||||
@@ -95,7 +102,7 @@ const permissionReady = ref(false)
|
||||
|
||||
const amazonHref = computed(() => resolvePageHref('/new_web_source/amazon-console.html'))
|
||||
const videoHref = computed(() => resolvePageHref('/new_web_source/image-video.html'))
|
||||
const imageHref = computed(() => resolvePageHref('/image'))
|
||||
const imageHref = computed(() => resolvePageHref('/new_web_source/image.html'))
|
||||
|
||||
const canShow = computed(() =>
|
||||
permissionUnavailable.value ? { amazon: true, video: true, image: true } : permissionState.value,
|
||||
@@ -172,7 +179,11 @@ async function loadCurrentUser() {
|
||||
try {
|
||||
const localName = typeof window === 'undefined' ? '' : window.localStorage.getItem('username') || ''
|
||||
if (localName) username.value = localName
|
||||
const resp = await window.fetch('/newApi/check_login', { credentials: 'include' })
|
||||
const token = typeof window === 'undefined' ? '' : window.localStorage.getItem('aiimage_auth_token') || ''
|
||||
const resp = await window.fetch('/newApi/check_login', {
|
||||
credentials: 'include',
|
||||
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
||||
})
|
||||
const body = await resp.json().catch(() => ({}))
|
||||
if (body?.success && body.data) {
|
||||
if (body.data.username) username.value = body.data.username
|
||||
@@ -257,7 +268,10 @@ async function doUpdate() {
|
||||
onMounted(() => {
|
||||
void loadCurrentUser()
|
||||
void loadPermissions()
|
||||
void fetchVersion().catch(() => undefined)
|
||||
// 版本检测/更新由桌面客户端 Flask 提供,Web 版不发起
|
||||
if (isDesktopRuntime.value) {
|
||||
void fetchVersion().catch(() => undefined)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user