Template
UI / layout - rebuild left mode: full-width blue header (60px) + white sidebar below + card-style tags view - introduce design tokens in variables.css (brand #347df9, sidebar 240px, menu item 49px) and theme overrides for dark / dark-blue themes - restyle navigation bar (logo + platform name / top nav / tools + user), logo, sidebar (selected state: light blue bg + blue bar + bold), tags view, app main - global styles: .app-container white card, .head-title, .btn-blue/.btn-white, el-table / el-dialog look, brand color injected into --el-color-primary - add favorites store (localStorage) wired to sidebar star and header top nav - disable template watermark / footer / promo notifications by default Login (serverschool) - port school-iot-admin login page (background art, right side card, keep-login) - OAuth2 password mode: GET /oauth/token (raw axios) + GET /uc/account/current - port phone lookup (/wx/getAccoutList) and forget-password flow (/sms/sendCode + /sms/verifyCode) as components/login/Forget.vue - user store exposes accountInfo / accountType / teamId / roleId and strips password Infra - move all devServer proxies and env vars from school-iot-admin/vue.config.js (default targets point to production) - fix empty sidebar: guard short-circuit skipped setRoutes when login page already fetched user info
118 lines
2.3 KiB
SCSS
118 lines
2.3 KiB
SCSS
// 全局 CSS 变量
|
||
@import "./variables.css";
|
||
// Transition
|
||
@import "./transition.scss";
|
||
// Element Plus
|
||
@import "./element-plus.css";
|
||
@import "./element-plus.scss";
|
||
// Vxe Table
|
||
@import "./vxe-table.css";
|
||
@import "./vxe-table.scss";
|
||
// 注册多主题
|
||
@import "./theme/register.scss";
|
||
// Mixins
|
||
@import "./mixins.scss";
|
||
// View Transition
|
||
@import "./view-transition.scss";
|
||
|
||
// 业务页面几乎都应该在根元素上挂载 class="app-container",以保持页面美观
|
||
// 视觉规范对齐 school-iot-admin:白卡片 + 10px 圆角 + 淡蓝阴影
|
||
.app-container {
|
||
padding: 16px 20px 20px;
|
||
background-color: var(--el-bg-color);
|
||
border-radius: 10px;
|
||
box-shadow: 0 0 10px rgba(32, 76, 131, 0.12);
|
||
}
|
||
|
||
// 页面标题(对齐 school-iot-admin 的 .head-title:左侧 6px 蓝色竖条)
|
||
.head-title {
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
margin: 4px 0 16px;
|
||
padding-left: 14px;
|
||
font-size: 20px;
|
||
font-weight: 500;
|
||
color: var(--el-text-color-primary);
|
||
&::before {
|
||
content: "";
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 0;
|
||
transform: translateY(-50%);
|
||
width: 6px;
|
||
height: 17px;
|
||
border-radius: 10px;
|
||
background-color: #347df9;
|
||
}
|
||
.tle {
|
||
margin: 0 5px;
|
||
}
|
||
}
|
||
|
||
// 主按钮(对齐 school-iot-admin 的 .btn-blue)
|
||
.btn-blue {
|
||
min-width: 68px;
|
||
border-radius: 2px;
|
||
font-weight: 500;
|
||
color: #ffffff;
|
||
background-color: #347df9;
|
||
border-color: #347df9;
|
||
}
|
||
|
||
// 次按钮(对齐 school-iot-admin 的 .btn-white)
|
||
.btn-white {
|
||
min-width: 68px;
|
||
border-radius: 2px;
|
||
font-weight: 500;
|
||
color: #347df9;
|
||
background-color: #ffffff;
|
||
border: 1px solid #347df9;
|
||
}
|
||
|
||
html {
|
||
height: 100%;
|
||
// 灰色模式
|
||
&.grey-mode {
|
||
filter: grayscale(1);
|
||
}
|
||
// 色弱模式
|
||
&.color-weakness {
|
||
filter: invert(0.8);
|
||
}
|
||
}
|
||
|
||
body {
|
||
height: 100%;
|
||
color: var(--v3-body-text-color);
|
||
background-color: var(--v3-body-bg-color);
|
||
-moz-osx-font-smoothing: grayscale;
|
||
-webkit-font-smoothing: antialiased;
|
||
font-family:
|
||
Inter, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial,
|
||
sans-serif;
|
||
@extend %scrollbar;
|
||
}
|
||
|
||
#app {
|
||
height: 100%;
|
||
}
|
||
|
||
*,
|
||
*::before,
|
||
*::after {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
a,
|
||
a:focus,
|
||
a:hover {
|
||
color: inherit;
|
||
outline: none;
|
||
text-decoration: none;
|
||
}
|
||
|
||
div:focus {
|
||
outline: none;
|
||
}
|