feat(前端): 登录页与各端布局展示版本号
统一从 package.json 注入 __APP_VERSION__,并在登录页、管理端、学校端、教师端和家长端菜单底部展示一致版本信息,提升发布可识别性。 Made-with: Cursor
This commit is contained in:
parent
3e2ccf40bc
commit
28e189e38f
@ -62,6 +62,9 @@
|
|||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
</a-menu>
|
</a-menu>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="sider-version" :title="`版本 v${appVersion}`">
|
||||||
|
<span>v{{ appVersion }}</span>
|
||||||
|
</div>
|
||||||
</a-layout-sider>
|
</a-layout-sider>
|
||||||
|
|
||||||
<a-layout>
|
<a-layout>
|
||||||
@ -133,6 +136,7 @@ import { useUserStore } from '@/stores/user';
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const appVersion = __APP_VERSION__;
|
||||||
|
|
||||||
const collapsed = ref(false);
|
const collapsed = ref(false);
|
||||||
const selectedKeys = ref<string[]>(['dashboard']);
|
const selectedKeys = ref<string[]>(['dashboard']);
|
||||||
@ -222,6 +226,8 @@ $bg-dark: #111827;
|
|||||||
background: white !important;
|
background: white !important;
|
||||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.04);
|
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.04);
|
||||||
border-right: 1px solid $border-color;
|
border-right: 1px solid $border-color;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
height: 72px;
|
height: 72px;
|
||||||
@ -314,7 +320,8 @@ $bg-dark: #111827;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sider-menu-wrapper {
|
.sider-menu-wrapper {
|
||||||
height: calc(100vh - 72px);
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
// 自定义侧边栏滚动条样式
|
// 自定义侧边栏滚动条样式
|
||||||
@ -332,6 +339,17 @@ $bg-dark: #111827;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sider-version {
|
||||||
|
padding: 10px 12px 14px;
|
||||||
|
border-top: 1px solid $border-color;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #9CA3AF;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.2;
|
||||||
|
background: #fff;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.admin-header {
|
.admin-header {
|
||||||
background: white;
|
background: white;
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
|
|||||||
@ -66,6 +66,7 @@
|
|||||||
<!-- 底部版权 -->
|
<!-- 底部版权 -->
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<span>© 2026 少儿智慧阅读服务平台</span>
|
<span>© 2026 少儿智慧阅读服务平台</span>
|
||||||
|
<span class="app-version">版本 v{{ appVersion }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -83,6 +84,7 @@ import {
|
|||||||
import { useUserStore } from '@/stores/user';
|
import { useUserStore } from '@/stores/user';
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const appVersion = __APP_VERSION__;
|
||||||
|
|
||||||
// 是否启用默认账号填充(开发/测试环境启用,生产环境禁用)
|
// 是否启用默认账号填充(开发/测试环境启用,生产环境禁用)
|
||||||
const enableDefaultAccount = import.meta.env.VITE_ENABLE_DEFAULT_ACCOUNT === 'true';
|
const enableDefaultAccount = import.meta.env.VITE_ENABLE_DEFAULT_ACCOUNT === 'true';
|
||||||
@ -413,5 +415,14 @@ $bg-cream: #FEFEFE;
|
|||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: $text-light;
|
color: $text-light;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-version {
|
||||||
|
font-size: 11px;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -46,6 +46,9 @@
|
|||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
</a-menu>
|
</a-menu>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="sider-version" :title="`版本 v${appVersion}`">
|
||||||
|
<span>v{{ appVersion }}</span>
|
||||||
|
</div>
|
||||||
</a-layout-sider>
|
</a-layout-sider>
|
||||||
|
|
||||||
<!-- 移动端抽屉菜单 -->
|
<!-- 移动端抽屉菜单 -->
|
||||||
@ -60,47 +63,50 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<a-menu v-model:selectedKeys="selectedKeys" mode="inline" theme="light" @click="handleMobileMenuClick"
|
<div class="drawer-menu-wrapper">
|
||||||
class="drawer-menu">
|
<a-menu v-model:selectedKeys="selectedKeys" mode="inline" theme="light" @click="handleMobileMenuClick"
|
||||||
<a-menu-item key="dashboard">
|
class="drawer-menu">
|
||||||
<template #icon>
|
<a-menu-item key="dashboard">
|
||||||
<HomeOutlined />
|
<template #icon>
|
||||||
</template>
|
<HomeOutlined />
|
||||||
<span>首页</span>
|
</template>
|
||||||
</a-menu-item>
|
<span>首页</span>
|
||||||
<a-menu-item key="children">
|
</a-menu-item>
|
||||||
<template #icon>
|
<a-menu-item key="children">
|
||||||
<TeamOutlined />
|
<template #icon>
|
||||||
</template>
|
<TeamOutlined />
|
||||||
<span>我的孩子</span>
|
</template>
|
||||||
</a-menu-item>
|
<span>我的孩子</span>
|
||||||
<a-menu-item key="lessons">
|
</a-menu-item>
|
||||||
<template #icon>
|
<a-menu-item key="lessons">
|
||||||
<BookOutlined />
|
<template #icon>
|
||||||
</template>
|
<BookOutlined />
|
||||||
<span>阅读记录</span>
|
</template>
|
||||||
</a-menu-item>
|
<span>阅读记录</span>
|
||||||
<a-menu-item key="tasks">
|
</a-menu-item>
|
||||||
<template #icon>
|
<a-menu-item key="tasks">
|
||||||
<CheckSquareOutlined />
|
<template #icon>
|
||||||
</template>
|
<CheckSquareOutlined />
|
||||||
<span>阅读任务</span>
|
</template>
|
||||||
</a-menu-item>
|
<span>阅读任务</span>
|
||||||
<a-menu-item key="growth">
|
</a-menu-item>
|
||||||
<template #icon>
|
<a-menu-item key="growth">
|
||||||
<FileImageOutlined />
|
<template #icon>
|
||||||
</template>
|
<FileImageOutlined />
|
||||||
<span>成长档案</span>
|
</template>
|
||||||
</a-menu-item>
|
<span>成长档案</span>
|
||||||
<a-menu-item key="profile">
|
</a-menu-item>
|
||||||
<template #icon>
|
<a-menu-item key="profile">
|
||||||
<UserOutlined />
|
<template #icon>
|
||||||
</template>
|
<UserOutlined />
|
||||||
<span>个人信息</span>
|
</template>
|
||||||
</a-menu-item>
|
<span>个人信息</span>
|
||||||
</a-menu>
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="drawer-footer">
|
<div class="drawer-footer">
|
||||||
|
<div class="drawer-version">版本 v{{ appVersion }}</div>
|
||||||
<a-button block @click="handleLogout" class="logout-btn">
|
<a-button block @click="handleLogout" class="logout-btn">
|
||||||
<LogoutOutlined /> 退出登录
|
<LogoutOutlined /> 退出登录
|
||||||
</a-button>
|
</a-button>
|
||||||
@ -191,6 +197,7 @@ import { useUserStore } from '@/stores/user';
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const appVersion = __APP_VERSION__;
|
||||||
|
|
||||||
const collapsed = ref(false);
|
const collapsed = ref(false);
|
||||||
const selectedKeys = ref(['dashboard']);
|
const selectedKeys = ref(['dashboard']);
|
||||||
@ -335,6 +342,8 @@ $bg-light: #FAFAFA;
|
|||||||
background: white !important;
|
background: white !important;
|
||||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.06);
|
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.06);
|
||||||
border-right: 1px solid $border-color;
|
border-right: 1px solid $border-color;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
height: 80px;
|
height: 80px;
|
||||||
@ -407,7 +416,8 @@ $bg-light: #FAFAFA;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sider-menu-wrapper {
|
.sider-menu-wrapper {
|
||||||
height: calc(100vh - 80px);
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
// 自定义侧边栏滚动条样式
|
// 自定义侧边栏滚动条样式
|
||||||
@ -425,6 +435,17 @@ $bg-light: #FAFAFA;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sider-version {
|
||||||
|
padding: 10px 12px 14px;
|
||||||
|
border-top: 1px solid $border-color;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #9CA3AF;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.2;
|
||||||
|
background: #fff;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
// 桌面端顶部栏
|
// 桌面端顶部栏
|
||||||
.parent-header {
|
.parent-header {
|
||||||
background: white;
|
background: white;
|
||||||
@ -488,6 +509,13 @@ $bg-light: #FAFAFA;
|
|||||||
|
|
||||||
// 移动端抽屉
|
// 移动端抽屉
|
||||||
.mobile-drawer {
|
.mobile-drawer {
|
||||||
|
:deep(.ant-drawer-body) {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 0 0 16px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.drawer-header {
|
.drawer-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -539,12 +567,25 @@ $bg-light: #FAFAFA;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.drawer-menu-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: auto;
|
||||||
|
padding: 0 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.drawer-footer {
|
.drawer-footer {
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
|
border-top: 1px solid $border-color;
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
.drawer-version {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #9CA3AF;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
.logout-btn {
|
.logout-btn {
|
||||||
height: 44px;
|
height: 44px;
|
||||||
|
|||||||
@ -144,6 +144,9 @@
|
|||||||
</a-sub-menu>
|
</a-sub-menu>
|
||||||
</a-menu>
|
</a-menu>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="sider-version" :title="`版本 v${appVersion}`">
|
||||||
|
<span>v{{ appVersion }}</span>
|
||||||
|
</div>
|
||||||
</a-layout-sider>
|
</a-layout-sider>
|
||||||
|
|
||||||
<a-layout>
|
<a-layout>
|
||||||
@ -225,6 +228,7 @@ import { useUserStore } from '@/stores/user';
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const appVersion = __APP_VERSION__;
|
||||||
|
|
||||||
const collapsed = ref(false);
|
const collapsed = ref(false);
|
||||||
const selectedKeys = ref(['dashboard']);
|
const selectedKeys = ref(['dashboard']);
|
||||||
@ -329,6 +333,8 @@ $bg-light: #FAFAFA;
|
|||||||
background: white !important;
|
background: white !important;
|
||||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.06);
|
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.06);
|
||||||
border-right: 1px solid $border-color;
|
border-right: 1px solid $border-color;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
height: 80px;
|
height: 80px;
|
||||||
@ -457,7 +463,8 @@ $bg-light: #FAFAFA;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sider-menu-wrapper {
|
.sider-menu-wrapper {
|
||||||
height: calc(100vh - 80px);
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
// 自定义侧边栏滚动条样式
|
// 自定义侧边栏滚动条样式
|
||||||
@ -475,6 +482,17 @@ $bg-light: #FAFAFA;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sider-version {
|
||||||
|
padding: 10px 12px 14px;
|
||||||
|
border-top: 1px solid $border-color;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #9CA3AF;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.2;
|
||||||
|
background: #fff;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.school-header {
|
.school-header {
|
||||||
background: white;
|
background: white;
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
|
|||||||
@ -69,6 +69,9 @@
|
|||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
</a-menu>
|
</a-menu>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="sider-version" :title="`版本 v${appVersion}`">
|
||||||
|
<span>v{{ appVersion }}</span>
|
||||||
|
</div>
|
||||||
</a-layout-sider>
|
</a-layout-sider>
|
||||||
|
|
||||||
<a-layout>
|
<a-layout>
|
||||||
@ -140,6 +143,7 @@ import { useUserStore } from '@/stores/user';
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const appVersion = __APP_VERSION__;
|
||||||
|
|
||||||
const collapsed = ref(false);
|
const collapsed = ref(false);
|
||||||
const selectedKeys = ref(['dashboard']);
|
const selectedKeys = ref(['dashboard']);
|
||||||
@ -225,6 +229,8 @@ $bg-light: #FAFAFA;
|
|||||||
background: white !important;
|
background: white !important;
|
||||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.06);
|
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.06);
|
||||||
border-right: 1px solid $border-color;
|
border-right: 1px solid $border-color;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
height: 80px;
|
height: 80px;
|
||||||
@ -316,7 +322,8 @@ $bg-light: #FAFAFA;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sider-menu-wrapper {
|
.sider-menu-wrapper {
|
||||||
height: calc(100vh - 80px);
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
// 自定义侧边栏滚动条样式
|
// 自定义侧边栏滚动条样式
|
||||||
@ -334,6 +341,17 @@ $bg-light: #FAFAFA;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sider-version {
|
||||||
|
padding: 10px 12px 14px;
|
||||||
|
border-top: 1px solid $border-color;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #9CA3AF;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.2;
|
||||||
|
background: #fff;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.teacher-header {
|
.teacher-header {
|
||||||
background: white;
|
background: white;
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
|
|||||||
@ -9,3 +9,5 @@ interface ImportMetaEnv {
|
|||||||
interface ImportMeta {
|
interface ImportMeta {
|
||||||
readonly env: ImportMetaEnv
|
readonly env: ImportMetaEnv
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare const __APP_VERSION__: string
|
||||||
|
|||||||
@ -7,13 +7,18 @@ import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers';
|
|||||||
import viteCompression from 'vite-plugin-compression';
|
import viteCompression from 'vite-plugin-compression';
|
||||||
import fileRouter from 'unplugin-vue-router/vite';
|
import fileRouter from 'unplugin-vue-router/vite';
|
||||||
import UnoCSS from 'unocss/vite';
|
import UnoCSS from 'unocss/vite';
|
||||||
|
import packageJson from './package.json';
|
||||||
|
|
||||||
export default defineConfig(({ mode }) => {
|
export default defineConfig(({ mode }) => {
|
||||||
const env = loadEnv(mode, process.cwd(), '');
|
const env = loadEnv(mode, process.cwd(), '');
|
||||||
const port = parseInt(env.VITE_APP_PORT) || 5173;
|
const port = parseInt(env.VITE_APP_PORT) || 5173;
|
||||||
const backendPort = env.VITE_BACKEND_PORT || '8480';
|
const backendPort = env.VITE_BACKEND_PORT || '8480';
|
||||||
|
const appVersion = packageJson.version;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
define: {
|
||||||
|
__APP_VERSION__: JSON.stringify(appVersion),
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
vue(),
|
vue(),
|
||||||
UnoCSS(),
|
UnoCSS(),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user