diff --git a/.env b/.env index 50527b1..fcc0588 100644 --- a/.env +++ b/.env @@ -17,4 +17,5 @@ VITE_GLOB_APP_CAPTCHA_ENABLE = true VITE_APP_DOCALERT_ENABLE=false # 百度统计 +VITE_APP_BAIDU_ENABLE = false VITE_APP_BAIDU_CODE = eb21166668bf766b9d059a6fd1c10777 diff --git a/.env.production b/.env.production index 839f3bc..d34cf98 100644 --- a/.env.production +++ b/.env.production @@ -24,4 +24,5 @@ VITE_GLOB_API_URL_PREFIX = VITE_USE_PWA = false # 百度统计 +VITE_APP_BAIDU_ENABLE = false VITE_APP_BAIDU_CODE = eb21166668bf766b9d059a6fd1c10777 diff --git a/.env.static b/.env.static index 9bfa7ac..f4d03d1 100644 --- a/.env.static +++ b/.env.static @@ -24,7 +24,8 @@ VITE_GLOB_API_URL_PREFIX = VITE_USE_PWA = false # 百度统计 +VITE_APP_BAIDU_ENABLE = false VITE_APP_BAIDU_CODE = eb21166668bf766b9d059a6fd1c10777 # 验证码的开关 -VITE_GLOB_APP_CAPTCHA_ENABLE = false \ No newline at end of file +VITE_GLOB_APP_CAPTCHA_ENABLE = false diff --git a/package.json b/package.json index ca9d14a..6afa12a 100644 --- a/package.json +++ b/package.json @@ -25,9 +25,9 @@ "serve": "pnpm dev", "dev": "vite", "front": "vite --mode front", - "build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 vite build && tsx ./build/script/postBuild.ts", - "build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode test && tsx ./build/script/postBuild.ts", - "build:static": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode static && tsx ./build/script/postBuild.ts", + "build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 vite build && pnpm exec esno ./build/script/postBuild.ts", + "build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode test && pnpm exec esno ./build/script/postBuild.ts", + "build:static": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode static && pnpm exec esno ./build/script/postBuild.ts", "build:no-cache": "pnpm store prune && pnpm build", "report": "cross-env REPORT=true pnpm build", "type:check": "vue-tsc --noEmit --skipLibCheck", diff --git a/src/components/Drawer/src/BasicDrawer.vue b/src/components/Drawer/src/BasicDrawer.vue index 5440169..14939a5 100644 --- a/src/components/Drawer/src/BasicDrawer.vue +++ b/src/components/Drawer/src/BasicDrawer.vue @@ -52,11 +52,26 @@ const getProps = computed((): DrawerProps => { if (!width) opt.width = '100%' + // detail 模式默认挂载到内容区容器,避免遮挡侧边栏/头部等 + // 但某些部署场景下内容区容器不存在或高度为 0,会导致 Drawer 由于 `position: absolute` 看起来“空白” const detailCls = `${prefixCls}__detail` - opt.rootClassName = wrapClassName ? `${wrapClassName} ${detailCls}` : detailCls - if (!getContainer) - opt.getContainer = `.${prefixVar}-layout-content` + const selector = `.${prefixVar}-layout-content` + const layoutEl = typeof document === 'undefined' + ? null + : (document.querySelector(selector) as HTMLElement | null) + + const canUseLayoutContainer = !!layoutEl && layoutEl.getBoundingClientRect().height > 0 + + if (canUseLayoutContainer) { + opt.rootClassName = wrapClassName ? `${wrapClassName} ${detailCls}` : detailCls + if (!getContainer) + opt.getContainer = layoutEl + } + else { + // 回退到默认容器(body);同时不要挂 `__detail` 类,避免 absolute 导致不可见 + opt.rootClassName = wrapClassName + } } return opt as DrawerProps }) diff --git a/src/components/Icon/src/Icon.vue b/src/components/Icon/src/Icon.vue index 528667a..b650884 100644 --- a/src/components/Icon/src/Icon.vue +++ b/src/components/Icon/src/Icon.vue @@ -50,8 +50,8 @@ async function update() { } else { const span = document.createElement('span') - span.className = 'iconify' - span.dataset.icon = icon + span.className = 'iconify-missing' + span.title = icon el.textContent = '' el.appendChild(span) } @@ -99,4 +99,22 @@ span.iconify { background-color: @iconify-bg-color; border-radius: 100%; } + +span.iconify-missing { + display: flex; + align-items: center; + justify-content: center; + min-width: 1em; + min-height: 1em; + background-color: @iconify-bg-color; + border-radius: 100%; + font-size: 0.75em; + color: currentcolor; + + &::after { + content: '?'; + line-height: 1; + opacity: 0.65; + } +} diff --git a/src/router/routes/index.ts b/src/router/routes/index.ts index 976093a..59ab86e 100644 --- a/src/router/routes/index.ts +++ b/src/router/routes/index.ts @@ -119,6 +119,28 @@ export const basicRoutes = [ RootRoute, ProfileRoute, CodegenRoute, + { + path: '/model/create', + name: 'ModelCreateBasic', + component: LAYOUT, + meta: { + title: '新建模型', + hideMenu: true, + hideBreadcrumb: true, + }, + children: [ + { + path: '', + name: 'ModelCreate', + component: () => import('@/views/model/create/index.vue'), + meta: { + title: '新建模型', + hideMenu: true, + currentActiveMenu: '/model/list', + }, + }, + ], + }, { path: '/model/assess-report/:id?', name: 'AssessReportBasic', diff --git a/src/utils/tongji.ts b/src/utils/tongji.ts index 270074f..d82bf00 100644 --- a/src/utils/tongji.ts +++ b/src/utils/tongji.ts @@ -1,23 +1,35 @@ import { router } from '@/router' -// 用于 router push -window._hmt = window._hmt || [] -// HM_ID +declare global { + interface Window { + _hmt?: any[] + } +} + +// HM_ID(构建时注入) const HM_ID = import.meta.env.VITE_APP_BAIDU_CODE -;(function () { - // 有值的时候,才开启 - if (!HM_ID) - return - - const hm = document.createElement('script') - hm.src = `https://hm.baidu.com/hm.js?${HM_ID}` - const s = document.getElementsByTagName('script')[0] - s.parentNode.insertBefore(hm, s) -})() - -router.afterEach((to) => { - if (!HM_ID) - return - - _hmt.push(['_trackPageview', to.fullPath]) -}) + +// 统计开关:默认关闭,离线/内网部署建议保持关闭 +const BAIDU_TONGJI_ENABLED = import.meta.env.VITE_APP_BAIDU_ENABLE === 'true' + +const shouldEnable = BAIDU_TONGJI_ENABLED && !!HM_ID + +if (shouldEnable) { + window._hmt = window._hmt || [] + + ;(function () { + const existing = document.querySelector(`script[data-hm-id="${HM_ID}"]`) + if (existing) + return + + const hm = document.createElement('script') + hm.setAttribute('data-hm-id', HM_ID) + hm.src = `https://hm.baidu.com/hm.js?${HM_ID}` + const s = document.getElementsByTagName('script')[0] + s?.parentNode?.insertBefore(hm, s) + })() + + router.afterEach((to) => { + window._hmt?.push(['_trackPageview', to.fullPath]) + }) +} diff --git a/src/views/model/create/index.vue b/src/views/model/create/index.vue new file mode 100644 index 0000000..8a1d00f --- /dev/null +++ b/src/views/model/create/index.vue @@ -0,0 +1,177 @@ + + + + + diff --git a/src/views/model/list/ModelCard.vue b/src/views/model/list/ModelCard.vue index c31207b..38a98f4 100644 --- a/src/views/model/list/ModelCard.vue +++ b/src/views/model/list/ModelCard.vue @@ -3,12 +3,10 @@ import { Card, Dropdown, Menu, Popconfirm } from 'ant-design-vue' import type { PropType } from 'vue' import { ref, watch } from 'vue' import type { ModelItem } from './data' -import CreateModel from './CreateModel.vue' import Icon from '@/components/Icon/index' import { modelCardListApi, modelDeleteApi } from '@/api/alert/model/models' import type { ModelQueryParams } from '@/api/alert/model/model/models' import { useGo } from '@/hooks/web/usePage' -import { useDrawer } from '@/components/Drawer' import { useMessage } from '@/hooks/web/useMessage' const props = defineProps({ @@ -26,7 +24,6 @@ const props = defineProps({ }, }) -const [registerDraw, { openDrawer }] = useDrawer() const { createMessage } = useMessage() // 点击模型卡片跳转训练页面 @@ -97,6 +94,15 @@ async function confirmDelete(id: number | string) { createMessage.success('删除成功') await loadModelList(props.selectData) } + +function goCreateModel() { + const query: string[] = [] + if (props.systemId !== undefined && props.systemId !== null) + query.push(`systemId=${encodeURIComponent(String(props.systemId))}`) + if (props.unitId !== undefined && props.unitId !== null) + query.push(`unitId=${encodeURIComponent(String(props.unitId))}`) + go(`/model/create${query.length ? `?${query.join('&')}` : ''}`) +} - + -