Files
ERP/ofbiz-framework/plugins/modern-ui/app/src/App.vue
T
QiufengandClaude Opus 4.8 5e51dc3f56 SNAPSHOT W7 已部署稳定态 — 凯迪ERP+OA一体化平台 (MET 73.3%)
恢复点(restore point)。别人改崩后可 git reset --hard 回到此提交。

== 此快照内容 ==
- 后端 oa-backend: 734 控制器 / 711 实体 (Spring Boot 3.2.5 + SQLite, 端口8091)
- 前端 modern-ui/app: Vue3+Vite, 约700页 (构建产物已在 oa-backend/src/main/resources/static)
- 数据库 oa-backend/data/oa.db: 含全部演示数据 (强制入库, 6.6MB)
- 交接文档 go.md + go-code-reference/endpoints/entities/database.md
- 多代理建设脚本 .claude/wf-*.js

== 状态 ==
- 对 凯迪科技ERP_20260507.xlsx 合规 MET ~73.3% (PARTIAL 75: 34可建+6种子/bug+35外部硬天花板)
- 安全: 5轮红队+5轮复检, default-deny分级鉴权, 连续零可利用
- W3~W7 累计补完436缺口; W8末轮(40缺口)为半成品(源码树可编译但未集成)
- 运行: cd oa-backend; java -jar build/libs/oa-backend-0.1.0.jar --server.port=8091; admin/123456

== 排除(gitignore, 可再生) ==
node_modules / oa-backend/build / .jdks / *.log / Backup-ERP-* / 弃用的OFBiz核心(只保留modern-ui)
完整文件夹备份见同目录 Backup-ERP-20260615-191517/ (含上述全部, 仅缺 node_modules)

时间戳: 20260615-191517

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 19:19:15 +08:00

99 lines
3.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { computed, onMounted, onBeforeUnmount, onErrorCaptured, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import OaAppShell from './oa/OaAppShell.vue'
import OaLogin from './oa/OaLogin.vue'
import ErrorFallback from './components/erp/ErrorFallback.vue'
import { useSession } from './oa/session'
import { OA_AUTH_REQUIRED_EVENT } from './oa/api'
// 独立窗口路由(meta.standalone)整页渲染,不套顶部外壳——复刻致远 window.open 弹窗形态。
const route = useRoute()
const router = useRouter()
const isStandalone = computed(() => route.meta?.standalone === true)
// ----- 全局错误边界 -----
// 子树渲染/生命周期抛出未捕获异常时,捕获并渲染友好降级页,避免整窗白屏。
// 返回 false 阻止异常继续向上冒泡(同时仍由 main.ts errorHandler 记日志+轻提示)。
const renderError = ref<Error | null>(null)
onErrorCaptured((err) => {
renderError.value = err instanceof Error ? err : new Error(String(err))
return false
})
// 路由切换后清掉错误态,让用户导航到别的页面可正常恢复。
watch(
() => route.fullPath,
() => {
renderError.value = null
}
)
function retryRender() {
renderError.value = null
}
function goHome() {
renderError.value = null
void router.push('/')
}
// App 级登录门:启动用已存 token 拉会话;未登录铺登录页,已登录进主壳。
// 任意请求 401 -> 清会话回到登录门。
const session = useSession()
function onAuthRequired() {
session.clear()
}
onMounted(() => {
void session.init()
window.addEventListener(OA_AUTH_REQUIRED_EVENT, onAuthRequired)
})
onBeforeUnmount(() => {
window.removeEventListener(OA_AUTH_REQUIRED_EVENT, onAuthRequired)
})
</script>
<template>
<div v-if="!session.ready.value" class="oa-boot" v-loading="true" element-loading-text="加载中…" />
<OaLogin v-else-if="!session.isAuthed.value" />
<!-- 独立窗口路由整页渲染不套外壳 -->
<template v-else-if="isStandalone">
<div v-if="renderError" class="oa-errboundary oa-errboundary--full">
<ErrorFallback @retry="retryRender" @home="goHome" />
</div>
<RouterView v-else />
</template>
<OaAppShell v-else>
<div v-if="renderError" class="oa-errboundary">
<ErrorFallback @retry="retryRender" @home="goHome" />
</div>
<RouterView v-else v-slot="{ Component }">
<component :is="Component" />
</RouterView>
</OaAppShell>
</template>
<style scoped>
.oa-boot {
position: fixed;
inset: 0;
}
/* 错误边界容器:壳内场景给一张卡片包住降级页;独立窗口铺满整屏。 */
.oa-errboundary {
max-width: 1360px;
margin: 0 auto;
background: var(--erp-color-surface);
border: 1px solid var(--erp-color-border-soft);
border-radius: var(--erp-radius-md);
}
.oa-errboundary--full {
min-height: 100vh;
border: 0;
border-radius: 0;
display: flex;
align-items: center;
justify-content: center;
}
</style>