From c086d402a7c1ac67b09cdbde0eb36eb91103a905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E8=87=AA=E8=BE=BE?= <980324341@qq.com> Date: Mon, 7 Sep 2026 17:11:33 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20=E5=93=81=E7=89=8C=E6=A3=80?= =?UTF-8?q?=E6=B5=8B/=E5=9B=BE=E7=89=87=E7=94=9F=E6=88=90=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E7=AB=AF=E5=8C=96=E2=80=94=E2=80=94URL=20=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=20https+=E5=9F=9F=E5=90=8D=EF=BC=8C=E5=85=A5=E5=8F=A3?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=B8=A6=20hash=20=E9=98=B2=E9=95=BF?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E5=A4=B1=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - brand/image 本地执行 API 服务端化(主机A shufu-web-api:15126,nginx 转发 /api/brand/* 等) - 前端撤销本地回连逻辑(local-http 删除,http.ts/brand.ts 还原为域名相对路径) - 版本更新改桌面桥 do_update_app(原 Flask /api/update/do 桥化,Web 无更新入口) - 品牌检测页 Web 可用(hasBridge 恢复 blanket 判定:文件选择走浏览器降级、任务/SSE 走域名) - vite 入口文件带内容 hash(/assets 配了 immutable 长缓存,无 hash 入口导致更新永不生效) - public/logo.jpg:Web 版 /logo.jpg 素材(原 app_client/logo.jpg 随桌面瘦身移除) --- frontend-vue/public/logo.jpg | Bin 0 -> 10772 bytes .../pages/brand/components/BrandBrandTab.vue | 5 +- .../src/pages/home/DesktopHomePage.vue | 38 +- .../src/pages/image/ImageWorkbenchPage.vue | 1519 +++++++++++++++++ frontend-vue/src/shared/api/http.ts | 11 + frontend-vue/src/shared/bridges/pywebview.ts | 9 +- frontend-vue/src/shared/runtime-env.ts | 14 + frontend-vue/vite.config.ts | 6 +- 8 files changed, 1576 insertions(+), 26 deletions(-) create mode 100644 frontend-vue/public/logo.jpg create mode 100644 frontend-vue/src/pages/image/ImageWorkbenchPage.vue create mode 100644 frontend-vue/src/shared/runtime-env.ts diff --git a/frontend-vue/public/logo.jpg b/frontend-vue/public/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ab825d78d2d14fd25b4602fb19a8ccb814d9fcf1 GIT binary patch literal 10772 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 Q0eSltA}n%)Wgq7M2gHA@#Q*>R literal 0 HcmV?d00001 diff --git a/frontend-vue/src/pages/brand/components/BrandBrandTab.vue b/frontend-vue/src/pages/brand/components/BrandBrandTab.vue index 06fad2db..d1fd23be 100644 --- a/frontend-vue/src/pages/brand/components/BrandBrandTab.vue +++ b/frontend-vue/src/pages/brand/components/BrandBrandTab.vue @@ -148,8 +148,9 @@ const runMode = ref<'immediate' | 'queue'>('immediate') const submitting = ref(false) const tasks = ref([]) -// 品牌检测由桌面客户端本地执行:以"文件夹选择"桥(Web 降级桥不提供)判定桌面运行时,浏览器下仅可预览 -const hasBridge = computed(() => Boolean(getPywebviewApi()?.select_brand_folder)) +// 品牌检测已服务端化(/api/brand/* 走域名):浏览器降级桥提供文件选择,Web 端可用; +// 文件夹选择/模板桥等降级桥未实现的方法在点击时提示"仅桌面端" +const hasBridge = computed(() => Boolean(getPywebviewApi())) const hasUid = computed(() => { const raw = typeof window === 'undefined' ? '' : window.localStorage.getItem('uid') || '' const numeric = Number(raw.trim()) diff --git a/frontend-vue/src/pages/home/DesktopHomePage.vue b/frontend-vue/src/pages/home/DesktopHomePage.vue index e1753129..6892bd8d 100644 --- a/frontend-vue/src/pages/home/DesktopHomePage.vue +++ b/frontend-vue/src/pages/home/DesktopHomePage.vue @@ -76,10 +76,10 @@ diff --git a/frontend-vue/src/pages/image/ImageWorkbenchPage.vue b/frontend-vue/src/pages/image/ImageWorkbenchPage.vue new file mode 100644 index 00000000..0e3148e0 --- /dev/null +++ b/frontend-vue/src/pages/image/ImageWorkbenchPage.vue @@ -0,0 +1,1519 @@ + + + diff --git a/frontend-vue/src/shared/api/http.ts b/frontend-vue/src/shared/api/http.ts index 2193fe25..94f264bf 100644 --- a/frontend-vue/src/shared/api/http.ts +++ b/frontend-vue/src/shared/api/http.ts @@ -60,6 +60,17 @@ function createHttpClient(): AxiosInstance { }) instance.interceptors.request.use((config: InternalAxiosRequestConfig) => { + // 携带本地登录令牌:桌面端同源 cookie 仍可用;dev(5173) 无 cookie 时靠 Bearer 过 Java 鉴权 + try { + if (config.url && config.url.indexOf('/newApi') === 0 && typeof window !== 'undefined') { + const token = window.localStorage.getItem('aiimage_auth_token') || '' + if (token) { + config.headers.Authorization = `Bearer ${token}` + } + } + } catch { + /* 忽略读取令牌异常 */ + } return config }) diff --git a/frontend-vue/src/shared/bridges/pywebview.ts b/frontend-vue/src/shared/bridges/pywebview.ts index 57e7df09..a50efb69 100644 --- a/frontend-vue/src/shared/bridges/pywebview.ts +++ b/frontend-vue/src/shared/bridges/pywebview.ts @@ -1,6 +1,5 @@ -import { ref } from 'vue'; - import { webFallbackApi } from './web-fallback'; +import { isDesktopRuntime } from '@/shared/runtime-env'; export interface UploadedJavaFile { fileKey: string; @@ -122,6 +121,8 @@ export interface PywebviewApi { not_found?: boolean; error?: string; }>; + /** 版本更新(桌面专属):下载更新包并启动 update.exe 后退出主程序(原 Flask /api/update/do 桥化) */ + do_update_app?: (fileUrl: string) => Promise<{ success: boolean; error?: string }>; launch_yaoayanui?: () => Promise<{ success: boolean; path?: string; @@ -197,8 +198,8 @@ declare global { let cachedPywebviewApi: PywebviewApi | undefined; let pywebviewReadyBound = false; -/** 当前是否运行在桌面客户端(pywebview)运行时;Web 独立部署下恒为 false */ -export const isDesktopRuntime = ref(false); +/** 当前是否运行在桌面客户端(pywebview)运行时;Web 独立部署下恒为 false(见 runtime-env.ts 注释) */ +export { isDesktopRuntime }; function syncPywebviewApi() { cachedPywebviewApi = window.pywebview?.api; diff --git a/frontend-vue/src/shared/runtime-env.ts b/frontend-vue/src/shared/runtime-env.ts new file mode 100644 index 00000000..02a5a27c --- /dev/null +++ b/frontend-vue/src/shared/runtime-env.ts @@ -0,0 +1,14 @@ +/** + * 桌面运行时环境标志 + * + * 独立模块避免共享模块之间循环依赖(pywebview.ts 写入、各页面读取)。 + * 桌面客户端窗口加载 Web 版 URL 后 pywebview 桥注入完成即置 true; + * 初始为 false,页面在 pywebviewready 之后的交互/挂载阶段读取时已为 true。 + * + * 注意:前端 URL 已全部统一走 https+域名(品牌检测/图片生成已服务端化), + * 本地不再有任何 Flask API 回连,无需 LOCAL_API_BASE。 + */ +import { ref } from 'vue' + +/** 桌面客户端(pywebview 桥已注入)运行时标志;Web 独立部署下恒为 false */ +export const isDesktopRuntime = ref(false) diff --git a/frontend-vue/vite.config.ts b/frontend-vue/vite.config.ts index cb25a116..e7b9678a 100644 --- a/frontend-vue/vite.config.ts +++ b/frontend-vue/vite.config.ts @@ -71,13 +71,15 @@ export default defineConfig({ 'variant-collection': resolve(__dirname, 'variant-collection.html'), brand: resolve(__dirname, 'brand.html'), 'image-video': resolve(__dirname, 'image-video.html'), + image: resolve(__dirname, 'image.html'), 'amazon-console': resolve(__dirname, 'amazon-console.html'), home: resolve(__dirname, 'home.html'), login: resolve(__dirname, 'login.html'), }, output: { - entryFileNames: (chunkInfo) => - chunkInfo.name === 'image-video' ? 'assets/[name]-[hash].js' : 'assets/[name].js', + // 入口文件同样带内容 hash:/assets/ 静态服务配了 immutable 长缓存, + // 无 hash 的入口文件会导致前端更新对用户永不生效(旧文件名被永久缓存) + entryFileNames: 'assets/[name]-[hash].js', chunkFileNames: 'assets/[name]-[hash].js', assetFileNames: 'assets/[name]-[hash][extname]', },