diff --git a/README.md b/README.md index 96b94ab..ea222a2 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Jenkins 使用 `Jenkinsfile` 执行: 3. `pnpm run build:antdv-next` 4. 将 `apps/web-antdv-next/dist` 原子发布到 Nginx 挂载的 Admin 静态目录 -Nginx 配置见 `deploy/nginx-admin.conf`,默认监听 `5999`,静态根目录为 `/usr/share/nginx/html/admin`,并将浏览器侧 `/api/*` 转发到后端 `192.168.31.224:48085`。配置保留 gzip、静态资源长缓存、入口 HTML 不缓存和 SPA 回退。 +Nginx 配置见 `deploy/nginx-admin.conf`,默认监听 `5999`,静态根目录为 `/usr/share/nginx/html/admin`,并将浏览器侧 `/api/*` 转发到后端 `192.168.31.224:48085`,将 `/napcat-webui/*` 转发到 NapCat WebUI Gateway `192.168.31.224:48086`。配置保留 gzip、静态资源长缓存、入口 HTML 不缓存、WebUI WebSocket 转发和 SPA 回退。 ## 提交规范 diff --git a/apps/web-antdv-next/src/api/qqbot/napcat.spec.ts b/apps/web-antdv-next/src/api/qqbot/napcat.spec.ts index d4776f9..091e7c2 100644 --- a/apps/web-antdv-next/src/api/qqbot/napcat.spec.ts +++ b/apps/web-antdv-next/src/api/qqbot/napcat.spec.ts @@ -246,8 +246,6 @@ describe('napcat login display helpers', () => { selfId: '10001', }, container: { - id: 'container-1', - name: 'kt-qqbot-napcat-10001', webuiStatus: 'online' as const, }, expiresAt: 1_782_000_000, diff --git a/apps/web-antdv-next/src/api/qqbot/napcat.ts b/apps/web-antdv-next/src/api/qqbot/napcat.ts index 138d8d4..fdcbb3a 100644 --- a/apps/web-antdv-next/src/api/qqbot/napcat.ts +++ b/apps/web-antdv-next/src/api/qqbot/napcat.ts @@ -31,8 +31,6 @@ export namespace QqbotNapcatApi { } export interface WebuiGatewaySessionContainer { - id: string; - name: string; webuiStatus: 'offline' | 'online' | 'unknown'; } diff --git a/apps/web-antdv-next/src/views/qqbot/account/napcat-boundary.spec.ts b/apps/web-antdv-next/src/views/qqbot/account/napcat-boundary.spec.ts index d9b4038..383d1f6 100644 --- a/apps/web-antdv-next/src/views/qqbot/account/napcat-boundary.spec.ts +++ b/apps/web-antdv-next/src/views/qqbot/account/napcat-boundary.spec.ts @@ -12,6 +12,15 @@ const accountRoot = resolve( const readAccountSource = (relativePath: string) => readFileSync(resolve(accountRoot, relativePath), 'utf8'); +/** + * Reads repository-root files that define browser-facing deployment boundaries. + * + * @param relativePath - Repository-relative path to read. + * @returns Source text for boundary assertions. + */ +const readRepoSource = (relativePath: string) => + readFileSync(resolve(cwd(), relativePath), 'utf8'); + /** * Reads QQBot router module source for route boundary assertions. */ @@ -71,4 +80,15 @@ describe('qqbot account NapCat login view boundary', () => { expect(source).toContain('hideInMenu: true'); expect(source).toContain("activePath: '/qqbot/account'"); }); + + it('exposes the NapCat WebUI gateway through the Admin same-origin dev and nginx routes', () => { + const viteSource = readRepoSource('apps/web-antdv-next/vite.config.mts'); + const nginxSource = readRepoSource('deploy/nginx-admin.conf'); + + expect(viteSource).toContain("'/napcat-webui'"); + expect(viteSource).toContain('http://localhost:48086'); + expect(nginxSource).toContain('location ^~ /napcat-webui/'); + expect(nginxSource).toContain('48086'); + expect(nginxSource).toContain('proxy_http_version 1.1'); + }); }); diff --git a/apps/web-antdv-next/src/views/qqbot/account/napcat-webui/index.tsx b/apps/web-antdv-next/src/views/qqbot/account/napcat-webui/index.tsx index d4a24f6..5caf469 100644 --- a/apps/web-antdv-next/src/views/qqbot/account/napcat-webui/index.tsx +++ b/apps/web-antdv-next/src/views/qqbot/account/napcat-webui/index.tsx @@ -161,7 +161,7 @@ export default defineComponent({
- {session.container.value?.name || 'NapCat Gateway'} + NapCat WebUI {expiresAtText.value ? ( 有效期:{expiresAtText.value} ) : null} diff --git a/apps/web-antdv-next/src/views/qqbot/account/napcat-webui/napcat-webui.spec.tsx b/apps/web-antdv-next/src/views/qqbot/account/napcat-webui/napcat-webui.spec.tsx index c7b8f67..ecf0f57 100644 --- a/apps/web-antdv-next/src/views/qqbot/account/napcat-webui/napcat-webui.spec.tsx +++ b/apps/web-antdv-next/src/views/qqbot/account/napcat-webui/napcat-webui.spec.tsx @@ -148,8 +148,6 @@ function createSessionFixture(overrides = {}) { selfId: '10001', }, container: { - id: 'container-1', - name: 'kt-qqbot-napcat-10001', webuiStatus: 'online' as const, }, expiresAt: new Date('2026-06-24T15:30:00+08:00').getTime(), @@ -193,6 +191,8 @@ describe('qqbot account NapCat WebUI page', () => { '/qqbot/napcat/webui/session/session-1/', ); expect(wrapper.text()).toContain('主账号(10001)'); + expect(wrapper.text()).toContain('NapCat WebUI'); + expect(wrapper.text()).not.toContain('kt-qqbot-napcat'); }); it('revokes the active session and pauses heartbeat on unmount', async () => { diff --git a/apps/web-antdv-next/vite.config.mts b/apps/web-antdv-next/vite.config.mts index 69e70d7..08f361e 100644 --- a/apps/web-antdv-next/vite.config.mts +++ b/apps/web-antdv-next/vite.config.mts @@ -13,6 +13,11 @@ const config = defineConfig(async () => { target: 'http://localhost:48085', ws: true, }, + '/napcat-webui': { + changeOrigin: true, + target: 'http://localhost:48086', + ws: true, + }, }, }, }, diff --git a/deploy/nginx-admin.conf b/deploy/nginx-admin.conf index a38b170..1dc0cc9 100644 --- a/deploy/nginx-admin.conf +++ b/deploy/nginx-admin.conf @@ -23,6 +23,17 @@ server { proxy_set_header X-Forwarded-Proto $scheme; } + location ^~ /napcat-webui/ { + proxy_pass http://192.168.31.224:48086/napcat-webui/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable";