Files
X-Financial/web/src/composables/useSystemState.js

691 lines
19 KiB
JavaScript
Raw Normal View History

import { computed, ref } from 'vue'
import {
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
fetchBootstrapBackendStatus,
fetchBootstrapState,
saveBootstrapConfig,
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
startBootstrapBackend,
testBootstrapDatabase,
testBootstrapRuntime
} from '../services/bootstrap.js'
import { login as loginByAccount } from '../services/auth.js'
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
import { setRuntimeApiBaseUrl } from '../services/api.js'
import { checkBackendHealth } from './useBackendHealth.js'
import { resolveDefaultAuthorizedRoute } from '../utils/accessControl.js'
import { useToast } from './useToast.js'
const AUTH_STORAGE_KEY = 'x-financial-authenticated'
const AUTH_USERNAME_KEY = 'x-financial-auth-username'
const AUTH_USER_KEY = 'x-financial-auth-user'
const AUTH_LAST_ACTIVITY_KEY = 'x-financial-auth-last-activity'
const DEFAULT_USER_NAME = '系统管理员'
const DEFAULT_USER_ROLE = '管理员'
const SESSION_ACTIVITY_EVENTS = ['pointerdown', 'keydown', 'scroll', 'touchstart', 'visibilitychange']
const authIdleTimeoutMinutes = Number(import.meta.env.VITE_AUTH_IDLE_TIMEOUT_MINUTES || 30)
const authIdleTimeoutMs =
Number.isFinite(authIdleTimeoutMinutes) && authIdleTimeoutMinutes > 0
? authIdleTimeoutMinutes * 60 * 1000
: 30 * 60 * 1000
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
function resolveBrowserApiBaseUrl(state) {
const server = state?.server || {}
const configuredHost = String(server.host || '127.0.0.1').trim()
const port = Number(server.port || 8000)
const apiPrefix = String(import.meta.env.VITE_API_BASE_PREFIX || '/api/v1').replace(/\/$/, '') || '/api/v1'
if (typeof window === 'undefined') {
return `http://${configuredHost}:${port}${apiPrefix}`
}
const browserHost = window.location.hostname
const normalizedHost = configuredHost.toLowerCase()
const host =
normalizedHost === '0.0.0.0' ||
normalizedHost === '::' ||
(normalizedHost === '127.0.0.1' && browserHost && browserHost !== '127.0.0.1' && browserHost !== 'localhost')
? browserHost
: configuredHost
return `http://${host}:${port}${apiPrefix}`
}
let sessionRouter = null
let sessionTimeoutHandle = 0
let sessionMonitoringInstalled = false
let lastActivityWriteAt = 0
function readClientBootstrapState() {
const env = import.meta.env
return {
initialized: String(env.VITE_SETUP_COMPLETED || '').toLowerCase() === 'true',
company: {
name: env.VITE_COMPANY_NAME || '',
code: env.VITE_COMPANY_CODE || '',
admin_email: env.VITE_ADMIN_EMAIL || ''
},
web: {
host: env.VITE_WEB_HOST || '0.0.0.0',
port: Number(env.VITE_WEB_PORT || 5173)
},
server: {
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
host: env.VITE_SERVER_HOST || '0.0.0.0',
port: Number(env.VITE_SERVER_PORT || 8000)
},
database: {
driver: 'postgresql',
host: env.VITE_POSTGRES_HOST || '127.0.0.1',
port: Number(env.VITE_POSTGRES_PORT || 5432),
name: env.VITE_POSTGRES_DB || 'x_financial',
username: env.VITE_POSTGRES_USER || 'postgres',
password_configured: false
},
redis: {
enabled: Boolean(env.VITE_REDIS_URL),
url: env.VITE_REDIS_URL || ''
}
}
}
function readAuthState() {
if (typeof window === 'undefined') {
return false
}
return window.sessionStorage.getItem(AUTH_STORAGE_KEY) === 'true'
}
function readStoredUsername() {
if (typeof window === 'undefined') {
return ''
}
return window.sessionStorage.getItem(AUTH_USERNAME_KEY) || ''
}
function buildAnonymousUser() {
return {
username: '',
name: '',
role: '',
roleCodes: [],
email: '',
avatar: '',
isAdmin: false
}
}
function buildLegacyAdminUser(username = '') {
const normalized = String(username || '').trim()
const name = normalized || DEFAULT_USER_NAME
return {
username: normalized,
name,
role: DEFAULT_USER_ROLE,
roleCodes: ['manager'],
email: '',
avatar: name.slice(0, 1).toUpperCase(),
isAdmin: true
}
}
function readStoredUser() {
if (typeof window === 'undefined') {
return buildAnonymousUser()
}
const raw = window.sessionStorage.getItem(AUTH_USER_KEY)
if (raw) {
try {
const payload = JSON.parse(raw)
if (payload && typeof payload === 'object') {
const username = String(payload.username || '').trim()
const name = String(payload.name || username || DEFAULT_USER_NAME).trim()
const roleCodes = Array.isArray(payload.roleCodes) ? payload.roleCodes.filter(Boolean) : []
return {
username,
name,
role: String(payload.role || DEFAULT_USER_ROLE),
roleCodes,
email: String(payload.email || ''),
avatar: String(payload.avatar || name.slice(0, 1).toUpperCase()),
isAdmin: Boolean(payload.isAdmin)
}
}
} catch {
return buildLegacyAdminUser(readStoredUsername())
}
}
const legacyUsername = readStoredUsername()
return legacyUsername ? buildLegacyAdminUser(legacyUsername) : buildAnonymousUser()
}
function readLastActivityAt() {
if (typeof window === 'undefined') {
return 0
}
return Number(window.sessionStorage.getItem(AUTH_LAST_ACTIVITY_KEY) || 0)
}
function isSessionExpired(now = Date.now()) {
if (!readAuthState()) {
return false
}
const lastActivityAt = readLastActivityAt()
if (!lastActivityAt) {
return true
}
return now - lastActivityAt > authIdleTimeoutMs
}
function persistAuthState(value, user = null) {
if (typeof window === 'undefined') {
return
}
if (value) {
window.sessionStorage.setItem(AUTH_STORAGE_KEY, 'true')
const normalizedUser = user || buildAnonymousUser()
window.sessionStorage.setItem(AUTH_USERNAME_KEY, String(normalizedUser.username || '').trim())
window.sessionStorage.setItem(AUTH_USER_KEY, JSON.stringify(normalizedUser))
return
}
window.sessionStorage.removeItem(AUTH_STORAGE_KEY)
window.sessionStorage.removeItem(AUTH_USERNAME_KEY)
window.sessionStorage.removeItem(AUTH_USER_KEY)
window.sessionStorage.removeItem(AUTH_LAST_ACTIVITY_KEY)
}
function clearSessionTimeout() {
if (typeof window === 'undefined' || !sessionTimeoutHandle) {
return
}
window.clearTimeout(sessionTimeoutHandle)
sessionTimeoutHandle = 0
}
function redirectToLogin() {
if (sessionRouter?.currentRoute?.value?.name === 'login') {
return
}
if (sessionRouter) {
sessionRouter.replace({ name: 'login' })
return
}
if (typeof window !== 'undefined' && window.location.pathname !== '/login') {
window.location.assign('/login')
}
}
function scheduleSessionTimeout() {
clearSessionTimeout()
if (typeof window === 'undefined' || !readAuthState()) {
return
}
const lastActivityAt = readLastActivityAt()
if (!lastActivityAt) {
return
}
const remaining = authIdleTimeoutMs - (Date.now() - lastActivityAt)
if (remaining <= 0) {
logout('timeout', { notify: true })
return
}
sessionTimeoutHandle = window.setTimeout(() => {
logout('timeout', { notify: true })
}, remaining)
}
function touchAuthActivity(force = false) {
if (typeof window === 'undefined' || !readAuthState()) {
return
}
const now = Date.now()
if (!force && now - lastActivityWriteAt < 1000) {
scheduleSessionTimeout()
return
}
window.sessionStorage.setItem(AUTH_LAST_ACTIVITY_KEY, String(now))
lastActivityWriteAt = now
scheduleSessionTimeout()
}
function handleSessionActivity(event) {
if (typeof document !== 'undefined' && event?.type === 'visibilitychange' && document.visibilityState !== 'visible') {
return
}
touchAuthActivity()
}
function installSessionMonitoring() {
if (sessionMonitoringInstalled || typeof window === 'undefined') {
return
}
sessionMonitoringInstalled = true
SESSION_ACTIVITY_EVENTS.forEach((eventName) => {
window.addEventListener(eventName, handleSessionActivity, { passive: true })
})
}
function syncAuthSession(options = {}) {
const shouldNotify = Boolean(options.notify)
if (!readAuthState()) {
loggedIn.value = false
currentUser.value = buildAnonymousUser()
clearSessionTimeout()
return false
}
if (isSessionExpired()) {
logout('timeout', { notify: shouldNotify, redirect: false })
return false
}
loggedIn.value = true
currentUser.value = readStoredUser()
scheduleSessionTimeout()
return true
}
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
function reconcileEntryRoute(router) {
const target = resolveEntryRoute()
const current = router.currentRoute.value
if (!current.name || current.name === 'root' || current.name === 'setup' || target.name === 'setup') {
router.replace(target)
}
}
export function installSessionNavigation(router) {
sessionRouter = router
installSessionMonitoring()
if (readAuthState() && !isSessionExpired()) {
scheduleSessionTimeout()
}
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
fetchBootstrapState()
.then((state) => {
applyBootstrapState(state)
router.isReady().then(() => reconcileEntryRoute(router))
})
.catch(() => {
router.isReady().then(() => {
if (!isInitialized.value && router.currentRoute.value.name !== 'setup') {
router.replace({ name: 'setup' })
}
})
})
}
const bootstrapState = ref(readClientBootstrapState())
const setupSubmitting = ref(false)
const setupError = ref('')
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
const setupProgressMessage = ref('')
const setupStartupVisible = ref(false)
const setupStartupSteps = ref([])
const setupStartupLog = ref('')
const setupCountdownSeconds = ref(0)
const runtimeTesting = ref(false)
const databaseTesting = ref(false)
const runtimeTestPassed = ref(false)
const databaseTestPassed = ref(false)
const runtimeTestMessage = ref('')
const databaseTestMessage = ref('')
const loginSubmitting = ref(false)
const loginError = ref('')
const loggedIn = ref(readAuthState() && !isSessionExpired())
const currentUser = ref(readStoredUser())
if (!loggedIn.value && readAuthState()) {
persistAuthState(false)
}
const { toast } = useToast()
const companyProfile = computed(() => ({
name: bootstrapState.value.company?.name || '',
code: bootstrapState.value.company?.code || '',
adminEmail: bootstrapState.value.company?.admin_email || ''
}))
function updateCompanyProfilePreview(payload = {}) {
const currentCompany = bootstrapState.value.company || {}
bootstrapState.value = {
...bootstrapState.value,
company: {
...currentCompany,
...(payload.name !== undefined ? { name: payload.name } : {}),
...(payload.code !== undefined ? { code: payload.code } : {}),
...(payload.adminEmail !== undefined ? { admin_email: payload.adminEmail } : {})
}
}
}
const isInitialized = computed(() => Boolean(bootstrapState.value.initialized))
function applyBootstrapState(state) {
bootstrapState.value = state
if (!state.initialized) {
logout('reset', { redirect: false })
}
}
function clearSetupRuntimeState() {
runtimeTesting.value = false
databaseTesting.value = false
runtimeTestPassed.value = false
databaseTestPassed.value = false
runtimeTestMessage.value = ''
databaseTestMessage.value = ''
setupError.value = ''
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
setupProgressMessage.value = ''
setupStartupVisible.value = false
setupStartupSteps.value = []
setupStartupLog.value = ''
setupCountdownSeconds.value = 0
}
function resetFromClientEnv() {
applyBootstrapState(readClientBootstrapState())
clearSetupRuntimeState()
loginError.value = ''
currentUser.value = readStoredUser()
}
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
}
function applyBackendStartupStatus(status) {
setupStartupVisible.value = true
setupStartupSteps.value = Array.isArray(status?.steps) ? status.steps : []
setupStartupLog.value = status?.logTail || ''
setupProgressMessage.value = status?.detail || setupProgressMessage.value
}
async function waitForBackendStartup() {
const started = await startBootstrapBackend()
applyBackendStartupStatus(started)
while (true) {
const status = await fetchBootstrapBackendStatus()
applyBackendStartupStatus(status)
if (status?.completed) {
return status
}
if (status?.failed) {
throw new Error(status.detail || 'FastAPI 后端启动失败。')
}
await sleep(1000)
}
}
async function runLoginCountdown() {
for (let second = 5; second > 0; second -= 1) {
setupCountdownSeconds.value = second
setupProgressMessage.value = `配置成功,${second} 秒后进入登录页...`
await sleep(1000)
}
}
async function handleSetupSubmit(payload) {
if (!runtimeTestPassed.value) {
setupError.value = '请先完成运行端口检测。'
toast(setupError.value)
return false
}
if (!databaseTestPassed.value) {
setupError.value = '请先完成数据库连接检测。'
toast(setupError.value)
return false
}
setupSubmitting.value = true
setupError.value = ''
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
setupProgressMessage.value = '正在写入初始化配置...'
setupStartupVisible.value = true
setupStartupSteps.value = [
{ id: 'config', label: '第一步:写入初始化配置', status: 'running', detail: '正在保存企业、管理员、端口和数据库配置。' },
{ id: 'deps', label: '第二步:安装/检查后端虚拟环境', status: 'pending', detail: '等待后端启动任务开始。' },
{ id: 'server', label: '第三步:启动 FastAPI 服务', status: 'pending', detail: '等待启动 uvicorn。' },
{ id: 'health', label: '第四步:检测后端健康状态', status: 'pending', detail: '等待 /api/v1/health。' },
{ id: 'done', label: '第五步:配置完成', status: 'pending', detail: '后端就绪后进入登录页。' }
]
setupStartupLog.value = ''
setupCountdownSeconds.value = 0
try {
const state = await saveBootstrapConfig(payload)
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
setupStartupSteps.value = setupStartupSteps.value.map((step) =>
step.id === 'config'
? { ...step, status: 'success', detail: '初始化配置已写入。' }
: step
)
setupProgressMessage.value = '配置已写入,正在启动 FastAPI 后端...'
await waitForBackendStartup()
setRuntimeApiBaseUrl(resolveBrowserApiBaseUrl(state))
setupProgressMessage.value = '后端已启动,正在检测服务连通性...'
const backendReady = await checkBackendHealth({ force: true })
if (!backendReady) {
throw new Error('FastAPI 后端已启动,但浏览器暂时无法连接后端接口。请确认 Server Host 使用 0.0.0.0,且防火墙允许访问后端端口。')
}
setupStartupSteps.value = setupStartupSteps.value.map((step) =>
step.id === 'done'
? { ...step, status: 'success', detail: '配置成功,准备进入登录页。' }
: step
)
setupProgressMessage.value = '配置成功,准备进入登录页...'
applyBootstrapState(state)
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
toast('初始化完成,后端已启动。')
await runLoginCountdown()
return true
} catch (error) {
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
setupError.value = error.message || '初始化配置写入或后端启动失败,请稍后重试。'
setupStartupVisible.value = true
setupStartupSteps.value = setupStartupSteps.value.map((step) =>
step.id === 'done'
? { ...step, status: 'error', detail: setupError.value }
: step
)
toast(setupError.value)
return false
} finally {
setupSubmitting.value = false
}
}
async function handleRuntimeTest(payload) {
runtimeTesting.value = true
runtimeTestMessage.value = ''
setupError.value = ''
try {
const result = await testBootstrapRuntime(payload)
runtimeTestPassed.value = true
runtimeTestMessage.value = result.detail || '端口占用检测通过。'
toast(runtimeTestMessage.value)
} catch (error) {
runtimeTestPassed.value = false
runtimeTestMessage.value = error.message || '端口占用检测失败。'
toast(runtimeTestMessage.value)
} finally {
runtimeTesting.value = false
}
}
async function handleDatabaseTest(payload) {
databaseTesting.value = true
databaseTestMessage.value = ''
setupError.value = ''
try {
const result = await testBootstrapDatabase(payload)
databaseTestPassed.value = true
databaseTestMessage.value = result.detail || '数据库连接检测通过。'
toast(databaseTestMessage.value)
} catch (error) {
databaseTestPassed.value = false
databaseTestMessage.value = error.message || '数据库连接检测失败。'
toast(databaseTestMessage.value)
} finally {
databaseTesting.value = false
}
}
function handleRuntimeDirty() {
runtimeTestPassed.value = false
runtimeTestMessage.value = ''
if (setupError.value === '请先完成运行端口检测。') {
setupError.value = ''
}
}
function handleDatabaseDirty() {
databaseTestPassed.value = false
databaseTestMessage.value = ''
if (setupError.value === '请先完成数据库连接检测。') {
setupError.value = ''
}
}
async function handleLogin(credentials) {
loginSubmitting.value = true
loginError.value = ''
try {
const response = await loginByAccount({
username: credentials.username,
password: credentials.password
})
const user = response?.user || buildAnonymousUser()
loggedIn.value = true
persistAuthState(true, user)
currentUser.value = user
touchAuthActivity(true)
return true
} catch (error) {
logout('invalid', { redirect: false })
loginError.value = error.message || '登录失败,请检查账号和密码。'
toast(loginError.value)
return false
} finally {
loginSubmitting.value = false
}
}
function logout(reason = 'manual', options = {}) {
const notify = options.notify ?? reason === 'timeout'
const redirect = options.redirect ?? reason !== 'invalid'
loggedIn.value = false
persistAuthState(false)
currentUser.value = buildAnonymousUser()
clearSessionTimeout()
if (notify) {
toast(reason === 'timeout' ? '登录已超时,请重新登录。' : '已退出登录。')
}
if (redirect) {
redirectToLogin()
}
}
function handleRecoverPassword() {
toast('请联系系统管理员重置账号密码。')
}
function handleSsoLogin() {
toast('SSO 登录暂未启用。')
}
function resolveEntryRoute() {
loggedIn.value = syncAuthSession()
currentUser.value = readStoredUser()
if (!isInitialized.value) {
return { name: 'setup' }
}
if (!loggedIn.value) {
return { name: 'login' }
}
return resolveDefaultAuthorizedRoute(currentUser.value)
}
export function useSystemState() {
return {
bootstrapState,
companyProfile,
currentUser,
databaseTestMessage,
databaseTestPassed,
databaseTesting,
handleDatabaseDirty,
handleDatabaseTest,
handleLogin,
handleRecoverPassword,
handleRuntimeDirty,
handleRuntimeTest,
handleSetupSubmit,
handleSsoLogin,
isInitialized,
loggedIn,
loginError,
loginSubmitting,
logout,
resetFromClientEnv,
resolveEntryRoute,
runtimeTestMessage,
runtimeTestPassed,
runtimeTesting,
setupError,
feat: 启用后端自动启动与 Setup 引导流程增强 主要修改点: 1. 网络绑定扩展至 Server - .env.example: SERVER_HOST/VITE_SERVER_HOST 从 127.0.0.1 改为 0.0.0.0 - server/src/app/core/config.py: 默认 app_host 从 127.0.0.1 改为 0.0.0.0 2. 启动脚本重构(重命名以区分职责) - server/start.sh → server/server_start.sh - web/start.sh → web/web_start.sh - 根目录 start.sh: 更新调用路径(./start.sh → ./server_start.sh, ./web_start.sh) - 根目录 start.sh: 新增 setup_ready() 检测函数 - 根目录 start.sh: server_probe_host() 支持 0.0.0.0 探测转换为 127.0.0.1 - 根目录 start.sh: start_setup_web() 新增 X_FINANCIAL_FORCE_SETUP=true 3. API URL 动态化 (web/src/services/api.js) - 从 localStorage 持久化读取 API Base URL - 新增 setRuntimeApiBaseUrl() / getRuntimeApiBaseUrl() 导出函数 - buildUrl() 改用运行时 runtimeApiBaseUrl 4. 浏览器 Host 智能解析 (web/vite.config.js) - 新增 resolveBrowserApiHost(): 根据 server_host/web_host 配置决定浏览器端使用的 API Host - buildApiBaseUrl() 改用 resolveBrowserApiHost() - 新增后端启动状态管理: backendStartState / cloneBackendStartState() / updateBackendStep() - 后端启动分 5 步追踪: config → deps → server → health → done - 新增 backendStartPromise 避免重复启动 5. Setup 表单逻辑增强 (web/src/composables/useSetupView.js) - 新增 shouldExposeServerHost(): 判断浏览器 host 是否非本地 - 新增 resolveInitialServerHost(): 当浏览器访问且 server_host 为本地时暴露 0.0.0.0 - buildPayload(): 根据 shouldExposeServerHost() 自动将 127.0.0.1/localhost 转为 0.0.0.0 6. Bootstrap API 扩展 (web/src/services/bootstrap.js) - 新增 startBootstrapBackend(): POST /bootstrap/backend 触发后端启动 - 新增 fetchBootstrapBackendStatus(): GET /bootstrap/backend 查询后端状态 7. Session 导航增强 (web/src/composables/useSystemState.js) - 新增 resolveBrowserApiBaseUrl(): 智能解析浏览器端 API Base URL - installSessionNavigation(): 调用 fetchBootstrapState() 同步引导状态 - 新增 reconcileEntryRoute(): 根据引导状态协调路由 - VITE_SERVER_HOST 默认值从 127.0.0.1 改为 0.0.0.0 8. Setup 视图增强 (web/src/views/SetupRouteView.vue) - 向 SetupView 传递启动进度相关 props: startupCountdownSeconds, startupLog, startupSteps, startupVisible, progressMessage 9. CSS 新增 (web/src/assets/styles/views/setup-view.css) - .setup-complete-progress: 进度文字样式 - .setup-modal-backdrop: 模态框遮罩 - .setup-startup-modal: 启动模态框容器 - .setup-startup-head / .setup-startup-body / .setup-startup-spinner: 模态框头部/内容/加载动画 - .setup-startup-steps / .setup-startup-step: 步骤列表及单个步骤 - .setup-startup-step.is-running / .is-success / .is-failed: 步骤状态样式 - .setup-startup-log: 启动日志区域
2026-05-08 10:52:54 +08:00
setupCountdownSeconds,
setupProgressMessage,
setupStartupLog,
setupStartupSteps,
setupStartupVisible,
setupSubmitting,
syncAuthSession,
updateCompanyProfilePreview
}
}