fix: Browser mode 404 error for meeting-detail page

- Preserve query parameters (e.g., ?id=123) when opening in browser
- Add packaged mode detection for CLIENT_DIR path resolution
- Include client files in extraResources for backend to serve
- Add debug logging for client directory detection

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
egg
2025-12-22 17:50:14 +08:00
parent 7d3fc72bd2
commit 771655e03e
3 changed files with 45 additions and 2 deletions

View File

@@ -11,10 +11,23 @@ from .routers import auth, meetings, ai, export, sidecar
from .sidecar_manager import get_sidecar_manager from .sidecar_manager import get_sidecar_manager
# Determine client directory path # Determine client directory path
# In development: backend/../client/src
# In packaged mode: backend/backend/_internal/../../client (relative to backend executable)
BACKEND_DIR = Path(__file__).parent.parent BACKEND_DIR = Path(__file__).parent.parent
PROJECT_DIR = BACKEND_DIR.parent PROJECT_DIR = BACKEND_DIR.parent
CLIENT_DIR = PROJECT_DIR / "client" / "src" CLIENT_DIR = PROJECT_DIR / "client" / "src"
# Check for packaged mode (PyInstaller sets _MEIPASS)
import sys
if getattr(sys, 'frozen', False):
# Packaged mode: look for client folder relative to executable
# Backend runs from resources/backend/, client files at resources/backend/client/
EXEC_DIR = Path(sys.executable).parent.parent # up from backend/backend.exe
CLIENT_DIR = EXEC_DIR / "client"
print(f"[Backend] Packaged mode: CLIENT_DIR={CLIENT_DIR}")
else:
print(f"[Backend] Development mode: CLIENT_DIR={CLIENT_DIR}")
@asynccontextmanager @asynccontextmanager
async def lifespan(app: FastAPI): async def lifespan(app: FastAPI):
@@ -77,6 +90,7 @@ async def health_check():
# ======================================== # ========================================
# Check if client directory exists for browser mode # Check if client directory exists for browser mode
print(f"[Backend] CLIENT_DIR exists: {CLIENT_DIR.exists()}")
if CLIENT_DIR.exists(): if CLIENT_DIR.exists():
# Serve static assets (CSS, JS, etc.) # Serve static assets (CSS, JS, etc.)
app.mount("/styles", StaticFiles(directory=CLIENT_DIR / "styles"), name="styles") app.mount("/styles", StaticFiles(directory=CLIENT_DIR / "styles"), name="styles")

View File

@@ -41,6 +41,26 @@
{ {
"from": "config.json", "from": "config.json",
"to": "config.json" "to": "config.json"
},
{
"from": "src/pages",
"to": "backend/client/pages",
"filter": ["**/*"]
},
{
"from": "src/styles",
"to": "backend/client/styles",
"filter": ["**/*"]
},
{
"from": "src/services",
"to": "backend/client/services",
"filter": ["**/*"]
},
{
"from": "src/config",
"to": "backend/client/config",
"filter": ["**/*"]
} }
], ],
"win": { "win": {

View File

@@ -734,10 +734,19 @@ ipcMain.handle("open-in-browser", async () => {
const host = backendConfig.host || "127.0.0.1"; const host = backendConfig.host || "127.0.0.1";
const port = backendConfig.port || 8000; const port = backendConfig.port || 8000;
// Determine the current page URL // Determine the current page URL and preserve query parameters
let currentPage = "login"; let currentPage = "login";
let queryString = "";
if (mainWindow) { if (mainWindow) {
const currentUrl = mainWindow.webContents.getURL(); const currentUrl = mainWindow.webContents.getURL();
// Parse query string from current URL (e.g., ?id=123)
const urlMatch = currentUrl.match(/\?(.+)$/);
if (urlMatch) {
queryString = "?" + urlMatch[1];
}
if (currentUrl.includes("meetings.html")) { if (currentUrl.includes("meetings.html")) {
currentPage = "meetings"; currentPage = "meetings";
} else if (currentUrl.includes("meeting-detail.html")) { } else if (currentUrl.includes("meeting-detail.html")) {
@@ -745,7 +754,7 @@ ipcMain.handle("open-in-browser", async () => {
} }
} }
const browserUrl = `http://${host}:${port}/${currentPage}`; const browserUrl = `http://${host}:${port}/${currentPage}${queryString}`;
try { try {
await shell.openExternal(browserUrl); await shell.openExternal(browserUrl);