Files
hzdyjs/mobile/src/uni.scss
T
zlwu afe3e234e9 feat(mobile): 实现全局路由守卫功能,自动处理用户未登录跳转
✨ 新增功能:
- 全局路由守卫模块 (route-guard.js)
- 多层次权限验证 (登录状态+Token存在+Token过期检查)
- 自动拦截机制 (页面级+跳转级+HTTP级+应用级)
- 401响应自动处理和跳转
- 路由守卫测试页面

🔧 技术实现:
- checkPageAccess() 全局页面权限检查
- guardedNavigate/guardedSwitchTab 带权限检查的跳转
- handleUnauthorized() HTTP拦截器401处理
- 公开页面配置管理
- 优雅的错误提示和跳转逻辑

📱 页面集成:
- App.vue 初始化路由守卫
- profile/workbench 页面添加权限检查
- index 页面优化跳转逻辑
- 新增测试页面验证功能

📚 文档完善:
- 移动端路由守卫使用指南
- 详细的变更记录和技术说明
- 最佳实践和注意事项

🎯 核心效果:
用户登录失效或未登录时,访问任何需要权限的页面都自动跳转到登录页,提升安全性和用户体验。
2025-07-04 22:28:49 +08:00

309 lines
7.2 KiB
SCSS

/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
*/
// 引入 uview-plus 样式
@import 'uview-plus/theme.scss';
// 引入 uview-plus 图标字体 - 使用阿里CDN
@font-face {
font-family: 'uicon-iconfont';
src: url('https://at.alicdn.com/t/font_2225171_8kdcwk4po24.ttf') format('truetype');
}
/* 原有的Sass变量定义 - 保持向后兼容 */
$uni-color-primary: rgb(93, 135, 255);
$uni-color-primary-dark: rgb(73, 115, 235);
$uni-color-primary-light: rgba(93, 135, 255, 0.1);
/* 状态颜色 */
$uni-color-success: #52c41a;
$uni-color-warning: #faad14;
$uni-color-error: #ff4d4f;
$uni-color-info: #1890ff;
/* 文字基本颜色 */
$uni-text-color: #333333;
$uni-text-color-inverse: #fff;
$uni-text-color-secondary: #666666;
$uni-text-color-grey: #999999;
$uni-text-color-placeholder: #c0c0c0;
$uni-text-color-disable: #d9d9d9;
/* 背景颜色 */
$uni-bg-color: #ffffff;
$uni-bg-color-grey: #f8f9fa;
$uni-bg-color-hover: #f1f1f1;
$uni-bg-color-mask: rgba(0, 0, 0, 0.4);
/* 边框颜色 */
$uni-border-color: #e0e0e0;
/* 阴影 */
$uni-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
$uni-shadow-hover: 0 4px 20px rgba(0, 0, 0, 0.15);
/* 文字尺寸 */
$uni-font-size-sm: 12px;
$uni-font-size-base: 14px;
$uni-font-size-lg: 16px;
$uni-font-size-xl: 18px;
$uni-font-size-xxl: 20px;
/* 图片尺寸 */
$uni-img-size-sm: 20px;
$uni-img-size-base: 26px;
$uni-img-size-lg: 40px;
/* Border Radius */
$uni-border-radius-sm: 6px;
$uni-border-radius-base: 8px;
$uni-border-radius-lg: 12px;
$uni-border-radius-xl: 16px;
$uni-border-radius-circle: 50%;
/* 间距 */
$uni-spacing-row-sm: 8px;
$uni-spacing-row-base: 12px;
$uni-spacing-row-lg: 16px;
$uni-spacing-row-xl: 20px;
$uni-spacing-col-sm: 8px;
$uni-spacing-col-base: 12px;
$uni-spacing-col-lg: 16px;
$uni-spacing-col-xl: 20px;
/* 透明度 */
$uni-opacity-disabled: 0.3;
/* 文章场景相关 */
$uni-color-title: #2c405a;
$uni-font-size-title: 20px;
$uni-color-subtitle: #555;
$uni-font-size-subtitle: 18px;
$uni-color-paragraph: #3f536e;
$uni-font-size-paragraph: 15px;
/* 动画 */
$uni-transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
$uni-transition-fast: all 0.15s ease-out;
/* 主题色彩变量 - CSS变量版本 */
:root {
--primary-color: rgb(93, 135, 255);
--primary-light: rgba(93, 135, 255, 0.1);
--primary-dark: rgb(73, 115, 235);
--success-color: #52c41a;
--warning-color: #faad14;
--error-color: #ff4d4f;
--text-primary: #262626;
--text-secondary: #595959;
--text-disabled: #bfbfbf;
--border-color: #f0f0f0;
--background-color: #f8f9fa;
--white: #ffffff;
--shadow-light: 0 2px 8px rgba(0, 0, 0, 0.06);
--shadow-medium: 0 4px 16px rgba(0, 0, 0, 0.12);
--radius-small: 4px;
--radius-medium: 8px;
--radius-large: 12px;
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
--transition-fast: 0.2s ease;
--transition-medium: 0.3s ease;
--font-size-xs: 12px;
--font-size-sm: 14px;
--font-size-md: 16px;
--font-size-lg: 18px;
--font-size-xl: 20px;
}
/* 全局样式重置 */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
color: var(--text-primary);
background-color: var(--background-color);
line-height: 1.6;
}
page {
background-color: var(--background-color);
color: var(--text-primary);
font-size: var(--font-size-md);
line-height: 1.6;
}
/* 通用工具类 */
.flex {
display: flex;
}
.flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.flex-between {
display: flex;
align-items: center;
justify-content: space-between;
}
.flex-column {
display: flex;
flex-direction: column;
}
.text-center {
text-align: center;
}
.text-primary {
color: var(--primary-color);
}
.text-secondary {
color: var(--text-secondary);
}
.bg-primary {
background-color: var(--primary-color);
}
.bg-white {
background-color: var(--white);
}
.rounded {
border-radius: var(--radius-medium);
}
.shadow {
box-shadow: var(--shadow-light);
}
.mt-sm { margin-top: var(--spacing-sm); }
.mt-md { margin-top: var(--spacing-md); }
.mt-lg { margin-top: var(--spacing-lg); }
.mb-sm { margin-bottom: var(--spacing-sm); }
.mb-md { margin-bottom: var(--spacing-md); }
.mb-lg { margin-bottom: var(--spacing-lg); }
.ml-sm { margin-left: var(--spacing-sm); }
.ml-md { margin-left: var(--spacing-md); }
.mr-sm { margin-right: var(--spacing-sm); }
.mr-md { margin-right: var(--spacing-md); }
.p-sm { padding: var(--spacing-sm); }
.p-md { padding: var(--spacing-md); }
.p-lg { padding: var(--spacing-lg); }
.px-sm { padding-left: var(--spacing-sm); padding-right: var(--spacing-sm); }
.px-md { padding-left: var(--spacing-md); padding-right: var(--spacing-md); }
.py-sm { padding-top: var(--spacing-sm); padding-bottom: var(--spacing-sm); }
.py-md { padding-top: var(--spacing-md); padding-bottom: var(--spacing-md); }
/* 按钮基础样式 */
.btn {
padding: var(--spacing-sm) var(--spacing-md);
border-radius: var(--radius-medium);
border: none;
font-size: var(--font-size-md);
cursor: pointer;
transition: var(--transition-fast);
display: inline-flex;
align-items: center;
justify-content: center;
text-decoration: none;
}
.btn-primary {
background-color: var(--primary-color);
color: var(--white);
}
.btn-primary:hover {
background-color: var(--primary-dark);
}
/* 输入框样式 */
.input {
padding: var(--spacing-sm) var(--spacing-md);
border: 1px solid var(--border-color);
border-radius: var(--radius-medium);
font-size: var(--font-size-md);
transition: var(--transition-fast);
}
.input:focus {
border-color: var(--primary-color);
outline: none;
box-shadow: 0 0 0 2px rgba(93, 135, 255, 0.2);
}
/* 卡片样式 */
.card {
background: var(--white);
border-radius: var(--radius-large);
box-shadow: var(--shadow-light);
padding: var(--spacing-md);
margin-bottom: var(--spacing-md);
}
.card-header {
font-size: var(--font-size-lg);
font-weight: 600;
margin-bottom: var(--spacing-md);
color: var(--text-primary);
}
/* 动画类 */
.fade-in {
animation: fadeIn var(--transition-medium);
}
.slide-up {
animation: slideUp var(--transition-medium);
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 响应式断点 */
@media (max-width: 768px) {
.card {
margin: var(--spacing-sm);
padding: var(--spacing-sm);
}
}