# zxyj-web Vue.js 2 Web管理端,Element UI组件库,用于后台管理。 ## WHERE TO LOOK | Task | Location | Notes | |------|----------|-------| | 页面组件 | `src/views/` | 管理界面页面组件 | | API调用 | `src/api/` | 后端API接口封装 | | 路由配置 | `src/router/` | Vue Router配置 | | 工具函数 | `src/utils/` | 通用工具函数 | | 状态管理 | `src/store/` | Vuex状态管理 | | 公共组件 | `src/components/` | 可复用UI组件 | ## STRUCTURE ``` src/ ├── views/ # 页面视图组件 │ ├── Dashboard.vue # 管理员首页(8统计卡片+趋势图+系统健康+快捷操作) │ ├── TeacherDashboard.vue # 规划师首页(独立角色仪表板) │ ├── admin/ # 管理员页面 │ └── teacher/ # 规划师页面 (7个) ├── api/ # API接口 ├── router/ # 路由配置 ├── store/ # Vuex状态 ├── utils/ # 工具函数 └── components/ # 公共组件 ``` ## CONVENTIONS - **Vue 2:** 使用 Options API - **UI框架:** Element UI组件库 - **状态管理:** Vuex进行全局状态管理 - **路由:** Vue Router,路由守卫处理权限 - **API封装:** 使用axios,统一错误处理和拦截器 - **权限控制:** 基于角色(admin/teacher)的菜单权限,Layout.vue 侧边栏以 v-if 控制规划师专属菜单项 ## 时间显示规范 页面时间展示必须统一以下两种格式: | 使用场景 | 格式 | 示例 | |------|------|------| | **时间(年月日+时分秒)** | `yyyy-MM-dd HH:mm:ss` | `2026-08-15 14:30:00` | | **仅日期(不带时间)** | `yyyy-MM-dd` | `2026-08-15` | 后端返回 ISO 8601 格式(`2026-08-15T14:30:00`),页面对时间字段统一使用: `formatTime(t) { return t ? t.replace('T', ' ').substring(0, 19) : '-' }`(时间场景) 或截取前 10 位得到日期(date-only 场景,如 `el-date-picker` 的 `value-format="yyyy-MM-dd"` 日期筛选)。 禁止使用 `new Date(str).toLocaleString()` / `toLocaleTimeString()`(输出格式因浏览器而异,用 `yyyy/MM/dd` 分号分割而非规定格式)。 ## ANTI-PATTERNS - **DO NOT** 在组件中直接调用axios,使用api目录的封装 - **DO NOT** 硬编码API地址,使用环境变量配置 - **DO NOT** 在前端处理敏感业务逻辑 - **NEVER** 跳过权限检查直接访问受保护路由 - **NEVER** 在前端存储管理员凭证 ## UNIQUE FEATURES - 管理员仪表板: 数据统计和系统概览 - 任务审核界面: 批量审核任务功能 - 用户角色管理: 管理员/成长规划师权限分配,侧边栏以 v-if 控制规划师专属菜单项 - 街道统计: 家庭和成长规划师的街道分布统计 ## ROUTE GUARD router.beforeEach 执行以下检查: 1. 无Token → 跳转 /login 2. Token 有效性验证(调用 /api/admin-auth/info) 3. 规划师访问 /dashboard → 自动跳转 /teacher-dashboard 4. 规划师专属路由 → 非 teacher 角色拦截 5. 管理员专属路由 → teacher 角色拦截 ## COMMANDS ```bash npm install # 安装依赖 npm run serve # 开发模式 (localhost:8082) npm run build # 生产构建 ``` ## NOTES - 开发端口: 8082 (避免与后端8080冲突) - 后端地址: 配置在环境变量中 - 权限系统: 基于JWT token和角色权限 - Element UI: 使用最新稳定版本,注意兼容性 - Layout.vue 侧边栏: 单个 el-menu,规划师专属项使用 v-if="isTeacher" 控制显隐 - 遮罩防御: Layout.vue 中全局 `.v-modal { display: none !important }` 防止 Element UI 组件残留遮罩 - 路由错误抑制: main.js 中覆盖 VueRouter.prototype.push 捕获 Redirected 导航错误