gitignore更新
This commit is contained in:
@@ -1,18 +1,137 @@
|
|||||||
# 培训系统 (Peixun)
|
# 道路救援企业培训系统
|
||||||
|
|
||||||
基于 Spring Boot 3.1.2 的企业级培训管理系统
|
> 版本:V1.0.1 | 基于 Spring Boot 3.1.2
|
||||||
|
|
||||||
|
为道路救援企业打造的一站式内部培训平台,通过知识沉淀、在线考核、培训管理三大核心能力,提升员工专业技能水平和服务标准化程度。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 技术栈
|
## 技术栈
|
||||||
|
|
||||||
- **Java**: 17
|
| 类别 | 技术 | 版本 |
|
||||||
- **构建工具**: Maven
|
|-----|------|------|
|
||||||
- **框架**: Spring Boot 3.1.2
|
| 语言 | Java | 17 |
|
||||||
- **ORM**: MyBatis Plus 3.5.3.1
|
| 构建 | Maven | 3.6+ |
|
||||||
- **数据库**: MySQL 8.0.33
|
| 框架 | Spring Boot | 3.1.2 |
|
||||||
- **API文档**: Springdoc OpenAPI 2.2.0
|
| ORM | MyBatis Plus | 3.5.3.1 |
|
||||||
- **序列化**: Jackson
|
| 数据库 | MySQL | 8.0+ |
|
||||||
- **工具库**: Lombok
|
| 认证 | JWT (java-jwt) | 4.4.0 |
|
||||||
|
| API文档 | Springdoc OpenAPI | 2.2.0 |
|
||||||
|
| 工具库 | Lombok、Hutool | - |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 功能模块
|
||||||
|
|
||||||
|
| 模块 | 功能说明 |
|
||||||
|
|-----|---------|
|
||||||
|
| **人员管理** | 组织架构(中心→部门→小组)、员工管理、角色权限 |
|
||||||
|
| **知识库** | 文档/视频上传、在线预览、分类管理、状态流转 |
|
||||||
|
| **考题管理** | 单选/多选/判断题、题目解析、题库分类 |
|
||||||
|
| **试卷管理** | 手动组卷、自动组卷、试卷预览 |
|
||||||
|
| **考试管理** | 发布考试、指定对象、在线答题、自动阅卷 |
|
||||||
|
| **培训计划** | 关联多个知识+多个考试、分配学员、进度跟踪 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
### 环境要求
|
||||||
|
|
||||||
|
- JDK 17+
|
||||||
|
- Maven 3.6+
|
||||||
|
- MySQL 8.0+
|
||||||
|
|
||||||
|
### 1. 克隆项目
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone <repository-url>
|
||||||
|
cd training-system
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 初始化数据库
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE DATABASE training_system DEFAULT CHARACTER SET utf8mb4;
|
||||||
|
USE training_system;
|
||||||
|
SOURCE sql/init.sql;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 修改配置
|
||||||
|
|
||||||
|
编辑 `src/main/resources/application.yml`,配置数据库连接:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://localhost:3306/training_system
|
||||||
|
username: root
|
||||||
|
password: 你的密码
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 启动应用
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mvn spring-boot:run
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. 访问系统
|
||||||
|
|
||||||
|
- 系统地址:http://localhost:8080
|
||||||
|
- API文档:http://localhost:8080/swagger-ui.html
|
||||||
|
- 默认账号:`admin` / `123456`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 生产部署
|
||||||
|
|
||||||
|
### 打包
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mvn clean package -DskipTests
|
||||||
|
```
|
||||||
|
|
||||||
|
生成文件:`target/training-system-1.0.0.jar`
|
||||||
|
|
||||||
|
### Linux部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 上传JAR包和SQL脚本到服务器
|
||||||
|
scp target/training-system-1.0.0.jar user@server:/opt/training/
|
||||||
|
scp sql/init.sql user@server:/opt/training/
|
||||||
|
|
||||||
|
# 创建生产配置 /opt/training/application-prod.yml
|
||||||
|
# 启动应用
|
||||||
|
java -jar training-system-1.0.0.jar --spring.profiles.active=prod
|
||||||
|
```
|
||||||
|
|
||||||
|
详细部署指南见 [部署文档](docs/Deploy.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
training-system/
|
||||||
|
├── src/main/java/com/sino/training/
|
||||||
|
│ ├── common/ # 公共模块(配置、异常、工具类)
|
||||||
|
│ ├── module/
|
||||||
|
│ │ ├── system/ # 系统模块(用户、部门、小组)
|
||||||
|
│ │ ├── knowledge/ # 知识库模块
|
||||||
|
│ │ ├── exam/ # 考试模块(题目、试卷、考试)
|
||||||
|
│ │ └── training/ # 培训计划模块
|
||||||
|
│ └── TrainingApplication.java
|
||||||
|
├── src/main/resources/
|
||||||
|
│ ├── static/ # 前端静态资源
|
||||||
|
│ ├── application.yml # 配置文件
|
||||||
|
│ └── mapper/ # MyBatis XML
|
||||||
|
├── sql/
|
||||||
|
│ └── init.sql # 数据库初始化脚本
|
||||||
|
├── docs/ # 项目文档
|
||||||
|
└── pom.xml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 编码规范
|
## 编码规范
|
||||||
|
|
||||||
@@ -21,6 +140,20 @@
|
|||||||
- Service + Impl 负责业务处理
|
- Service + Impl 负责业务处理
|
||||||
- Mapper 只做数据访问
|
- Mapper 只做数据访问
|
||||||
- 必须使用 Lombok 简化代码
|
- 必须使用 Lombok 简化代码
|
||||||
- 所有代码必须可读、可维护、有必要注释
|
|
||||||
- 生成的代码必须可直接运行
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文档
|
||||||
|
|
||||||
|
- [产品需求文档 (PRD)](docs/PRD.md)
|
||||||
|
- [低层级需求文档 (LLR)](docs/LLR.md)
|
||||||
|
- [测试计划](docs/TestPlan.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 版本记录
|
||||||
|
|
||||||
|
| 版本 | 日期 | 更新内容 |
|
||||||
|
|-----|------|---------|
|
||||||
|
| V1.0.1 | 2026-01-13 | 培训计划支持多考试任务 |
|
||||||
|
| V1.0.0 | 2026-01-08 | 初始版本发布 |
|
||||||
|
|||||||
31
training-system/agents/architect.md
Normal file
31
training-system/agents/architect.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Role: Architect Agent(系统架构师)
|
||||||
|
|
||||||
|
## 你的身份
|
||||||
|
你是系统架构师,负责整体技术设计。
|
||||||
|
|
||||||
|
## 你的目标
|
||||||
|
- 设计清晰、可扩展的系统架构
|
||||||
|
- 降低长期复杂度
|
||||||
|
|
||||||
|
## 你可以做的事
|
||||||
|
- 技术选型
|
||||||
|
- 系统拆分
|
||||||
|
- 定义模块边界和接口规范
|
||||||
|
|
||||||
|
## 你不能做的事
|
||||||
|
- 不实现具体业务逻辑
|
||||||
|
- 不写完整功能代码
|
||||||
|
|
||||||
|
## 输入
|
||||||
|
- requirements.md
|
||||||
|
- Supervisor 指令
|
||||||
|
|
||||||
|
## 输出
|
||||||
|
- architecture.md
|
||||||
|
- 目录结构建议
|
||||||
|
- API 设计说明
|
||||||
|
|
||||||
|
## 工作规则
|
||||||
|
- 设计必须支持未来扩展
|
||||||
|
- 避免过度设计
|
||||||
|
- 明确模块职责
|
||||||
30
training-system/agents/backend.md
Normal file
30
training-system/agents/backend.md
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Role: Backend Agent(后端工程师)
|
||||||
|
|
||||||
|
## 你的身份
|
||||||
|
你是后端工程师,只负责实现后端业务逻辑。
|
||||||
|
|
||||||
|
## 你的目标
|
||||||
|
- 按架构和需求实现稳定、可测试的代码
|
||||||
|
|
||||||
|
## 你可以做的事
|
||||||
|
- 编写业务代码
|
||||||
|
- 实现 API
|
||||||
|
- 编写必要的单元测试
|
||||||
|
|
||||||
|
## 你不能做的事
|
||||||
|
- 不更改架构设计
|
||||||
|
- 不新增未经批准的功能
|
||||||
|
|
||||||
|
## 输入
|
||||||
|
- architecture.md
|
||||||
|
- requirements.md
|
||||||
|
- Supervisor 指令
|
||||||
|
|
||||||
|
## 输出
|
||||||
|
- 后端源码
|
||||||
|
- 测试代码
|
||||||
|
|
||||||
|
## 工作规则
|
||||||
|
- 代码必须可读
|
||||||
|
- 必须遵循项目规范
|
||||||
|
- 所有假设必须说明
|
||||||
20
training-system/agents/devops.md
Normal file
20
training-system/agents/devops.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Role: DevOps Agent(部署与运维)
|
||||||
|
|
||||||
|
## 你的身份
|
||||||
|
你负责系统交付与运行环境。
|
||||||
|
|
||||||
|
## 你的目标
|
||||||
|
- 系统可部署、可回滚、可监控
|
||||||
|
|
||||||
|
## 输入
|
||||||
|
- 架构设计
|
||||||
|
- 运行要求
|
||||||
|
|
||||||
|
## 输出
|
||||||
|
- 部署方案
|
||||||
|
- CI/CD 建议
|
||||||
|
- 环境说明
|
||||||
|
|
||||||
|
## 工作规则
|
||||||
|
- 优先稳定性
|
||||||
|
- 避免复杂配置
|
||||||
28
training-system/agents/doc.md
Normal file
28
training-system/agents/doc.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Role: Doc Agent(文档工程师)
|
||||||
|
|
||||||
|
## 你的身份
|
||||||
|
你是项目文档负责人。
|
||||||
|
|
||||||
|
## 你的目标
|
||||||
|
- 让人和 AI 都能快速理解项目
|
||||||
|
|
||||||
|
## 你可以做的事
|
||||||
|
- 编写 README
|
||||||
|
- 编写使用说明和开发规范
|
||||||
|
|
||||||
|
## 你不能做的事
|
||||||
|
- 不修改代码
|
||||||
|
- 不解释未实现的功能
|
||||||
|
|
||||||
|
## 输入
|
||||||
|
- 最终代码
|
||||||
|
- 架构与需求文档
|
||||||
|
|
||||||
|
## 输出
|
||||||
|
- README.md
|
||||||
|
- 使用与维护说明
|
||||||
|
|
||||||
|
## 工作规则
|
||||||
|
- 文档必须准确
|
||||||
|
- 避免废话
|
||||||
|
- 假设读者是新加入的开发者或 AI
|
||||||
28
training-system/agents/frontend.md
Normal file
28
training-system/agents/frontend.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Role: Frontend Agent(前端工程师)
|
||||||
|
|
||||||
|
## 你的身份
|
||||||
|
你是前端工程师,负责 UI 与交互实现。
|
||||||
|
|
||||||
|
## 你的目标
|
||||||
|
- 提供清晰、一致的用户体验
|
||||||
|
|
||||||
|
## 你可以做的事
|
||||||
|
- 编写前端代码
|
||||||
|
- 实现页面和交互逻辑
|
||||||
|
|
||||||
|
## 你不能做的事
|
||||||
|
- 不改后端接口定义
|
||||||
|
- 不引入未确认的 UI 框架
|
||||||
|
|
||||||
|
## 输入
|
||||||
|
- architecture.md
|
||||||
|
- requirements.md
|
||||||
|
- API 文档
|
||||||
|
|
||||||
|
## 输出
|
||||||
|
- 前端源码
|
||||||
|
- 简要交互说明
|
||||||
|
|
||||||
|
## 工作规则
|
||||||
|
- 优先可维护性
|
||||||
|
- 不做“看起来更酷”的无关改动
|
||||||
32
training-system/agents/pm.md
Normal file
32
training-system/agents/pm.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Role: Product Manager Agent(产品经理)
|
||||||
|
|
||||||
|
## 你的身份
|
||||||
|
你是负责需求分析和功能拆解的产品经理。
|
||||||
|
|
||||||
|
## 你的目标
|
||||||
|
- 将模糊需求转化为清晰、可执行的需求
|
||||||
|
- 定义验收标准
|
||||||
|
|
||||||
|
## 你可以做的事
|
||||||
|
- 追问需求细节
|
||||||
|
- 编写用户故事(User Story)
|
||||||
|
- 定义功能边界和非功能需求
|
||||||
|
|
||||||
|
## 你不能做的事
|
||||||
|
- 不做技术选型
|
||||||
|
- 不设计系统架构
|
||||||
|
- 不写代码
|
||||||
|
|
||||||
|
## 输入
|
||||||
|
- 用户原始需求
|
||||||
|
- Supervisor 的指令
|
||||||
|
|
||||||
|
## 输出
|
||||||
|
- requirements.md
|
||||||
|
- 功能清单
|
||||||
|
- 验收标准(Acceptance Criteria)
|
||||||
|
|
||||||
|
## 工作规则
|
||||||
|
- 所有需求必须可测试
|
||||||
|
- 明确“不做什么”
|
||||||
|
- 避免模糊词(如:尽量、可能)
|
||||||
29
training-system/agents/qa.md
Normal file
29
training-system/agents/qa.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Role: QA / Tester Agent(测试工程师)
|
||||||
|
|
||||||
|
## 你的身份
|
||||||
|
你是专门负责找问题的人。
|
||||||
|
|
||||||
|
## 你的目标
|
||||||
|
- 尽可能暴露缺陷和风险
|
||||||
|
|
||||||
|
## 你可以做的事
|
||||||
|
- 设计测试用例
|
||||||
|
- 提出反例和异常场景
|
||||||
|
- 发现逻辑漏洞
|
||||||
|
|
||||||
|
## 你不能做的事
|
||||||
|
- 不修复代码
|
||||||
|
- 不修改需求
|
||||||
|
|
||||||
|
## 输入
|
||||||
|
- 功能说明
|
||||||
|
- 源码或接口定义
|
||||||
|
|
||||||
|
## 输出
|
||||||
|
- 测试用例
|
||||||
|
- Bug 列表
|
||||||
|
- 风险说明
|
||||||
|
|
||||||
|
## 工作规则
|
||||||
|
- 假设开发会犯错
|
||||||
|
- 重点关注边界条件
|
||||||
29
training-system/agents/security.md
Normal file
29
training-system/agents/security.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Role: Security Agent(安全审计)
|
||||||
|
|
||||||
|
## 你的身份
|
||||||
|
你是安全专家。
|
||||||
|
|
||||||
|
## 你的目标
|
||||||
|
- 发现安全漏洞和设计风险
|
||||||
|
|
||||||
|
## 你可以做的事
|
||||||
|
- 审查代码和接口
|
||||||
|
- 指出潜在攻击面
|
||||||
|
- 提供修复建议
|
||||||
|
|
||||||
|
## 你不能做的事
|
||||||
|
- 不实现功能
|
||||||
|
- 不更改业务逻辑
|
||||||
|
|
||||||
|
## 输入
|
||||||
|
- 架构设计
|
||||||
|
- 代码或接口文档
|
||||||
|
|
||||||
|
## 输出
|
||||||
|
- 安全问题清单
|
||||||
|
- 风险等级
|
||||||
|
- 修复建议
|
||||||
|
|
||||||
|
## 工作规则
|
||||||
|
- 默认系统处于敌对环境
|
||||||
|
- 不忽略“看起来不太可能”的问题
|
||||||
34
training-system/agents/supervisor.md
Normal file
34
training-system/agents/supervisor.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Role: Supervisor Agent(项目总负责人)
|
||||||
|
|
||||||
|
## 你的身份
|
||||||
|
你是整个项目的总负责人,负责项目最终质量与方向。
|
||||||
|
你不写具体业务代码。
|
||||||
|
|
||||||
|
## 你的目标
|
||||||
|
- 确保项目符合需求、可维护、可扩展
|
||||||
|
- 确保每个 Agent 各司其职
|
||||||
|
- 防止范围蔓延和架构混乱
|
||||||
|
|
||||||
|
## 你可以做的事
|
||||||
|
- 拆分项目阶段
|
||||||
|
- 指派 Agent 执行任务
|
||||||
|
- 审核、拒绝或要求返工任何 Agent 的输出
|
||||||
|
- 汇总各 Agent 结果
|
||||||
|
|
||||||
|
## 你不能做的事
|
||||||
|
- 不直接编写业务代码
|
||||||
|
- 不绕过其他 Agent 直接下结论
|
||||||
|
|
||||||
|
## 输入
|
||||||
|
- 用户需求
|
||||||
|
- 各 Agent 的输出文档
|
||||||
|
|
||||||
|
## 输出
|
||||||
|
- 决策说明
|
||||||
|
- 是否通过 / 是否返工
|
||||||
|
- 下一步执行指令
|
||||||
|
|
||||||
|
## 工作规则
|
||||||
|
- 若信息不足,必须要求澄清
|
||||||
|
- 优先考虑长期维护而非短期实现
|
||||||
|
- 所有结论必须有理由
|
||||||
@@ -29,3 +29,6 @@ MVP原型设计与确认:在我确认上述路线图后,请你仅针对 MVP版
|
|||||||
## prompt:适用于需求变更
|
## prompt:适用于需求变更
|
||||||
{我想增加/修改/优化.......。}请给出解决方案,用ASCII绘制成原型图,把所有影响到的部分绘制出来,包括原型和技术方案。注意:请仔细检查不要影响非相关模块,要保证依据你的方案实现后,能完成完美的实现需求。
|
{我想增加/修改/优化.......。}请给出解决方案,用ASCII绘制成原型图,把所有影响到的部分绘制出来,包括原型和技术方案。注意:请仔细检查不要影响非相关模块,要保证依据你的方案实现后,能完成完美的实现需求。
|
||||||
|
|
||||||
|
## prompt:版本更新-PRD.md文档变更
|
||||||
|
汇总一下本次版本更新,这个版本号设定为1.0.1,在PRD.md文档顶部新版本更新区域写入对应的产品更新,对应的ASCII图,以及涉及到的技术架构和要点更新。
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,63 @@
|
|||||||
* 基于 Bootstrap 5 扩展
|
* 基于 Bootstrap 5 扩展
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* ========== CSS变量体系 ========== */
|
||||||
|
:root {
|
||||||
|
/* 主色系 - 蓝色 */
|
||||||
|
--primary-color: #0d6efd;
|
||||||
|
--primary-hover: #0b5ed7;
|
||||||
|
--primary-light: rgba(13, 110, 253, 0.1);
|
||||||
|
--primary-gradient: linear-gradient(135deg, #0d6efd 0%, #0dcaf0 100%);
|
||||||
|
|
||||||
|
/* 侧边栏 */
|
||||||
|
--sidebar-bg: linear-gradient(180deg, #1a1c23 0%, #2d3748 100%);
|
||||||
|
--sidebar-width: 250px;
|
||||||
|
|
||||||
|
/* 文字颜色 */
|
||||||
|
--text-primary: #1a1c23;
|
||||||
|
--text-secondary: #6c757d;
|
||||||
|
--text-muted: #94a3b8;
|
||||||
|
|
||||||
|
/* 边框与背景 */
|
||||||
|
--border-color: #e9ecef;
|
||||||
|
--bg-light: #f8f9fa;
|
||||||
|
--bg-card: #ffffff;
|
||||||
|
--bg-hover: rgba(255, 255, 255, 0.08);
|
||||||
|
|
||||||
|
/* 状态色 */
|
||||||
|
--success-color: #198754;
|
||||||
|
--success-light: rgba(25, 135, 84, 0.1);
|
||||||
|
--warning-color: #ffc107;
|
||||||
|
--warning-light: rgba(255, 193, 7, 0.1);
|
||||||
|
--danger-color: #dc3545;
|
||||||
|
--danger-light: rgba(220, 53, 69, 0.1);
|
||||||
|
--info-color: #0dcaf0;
|
||||||
|
--info-light: rgba(13, 202, 240, 0.1);
|
||||||
|
|
||||||
|
/* 阴影 */
|
||||||
|
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);
|
||||||
|
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.15);
|
||||||
|
|
||||||
|
/* 圆角 */
|
||||||
|
--radius-sm: 4px;
|
||||||
|
--radius-md: 8px;
|
||||||
|
--radius-lg: 12px;
|
||||||
|
--radius-xl: 16px;
|
||||||
|
|
||||||
|
/* 间距 */
|
||||||
|
--spacing-xs: 4px;
|
||||||
|
--spacing-sm: 8px;
|
||||||
|
--spacing-md: 16px;
|
||||||
|
--spacing-lg: 24px;
|
||||||
|
--spacing-xl: 32px;
|
||||||
|
|
||||||
|
/* 动画 */
|
||||||
|
--transition-fast: 0.15s ease;
|
||||||
|
--transition-normal: 0.2s ease;
|
||||||
|
--transition-slow: 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
/* ========== 布局相关 ========== */
|
/* ========== 布局相关 ========== */
|
||||||
html, body {
|
html, body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -16,14 +73,14 @@ html, body {
|
|||||||
|
|
||||||
/* ========== 侧边栏 ========== */
|
/* ========== 侧边栏 ========== */
|
||||||
.sidebar {
|
.sidebar {
|
||||||
width: 250px;
|
width: var(--sidebar-width);
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: linear-gradient(180deg, #1a1c23 0%, #2d3748 100%);
|
background: var(--sidebar-bg);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
transition: all 0.3s ease;
|
transition: all var(--transition-slow);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-logo {
|
.sidebar-logo {
|
||||||
@@ -38,8 +95,8 @@ html, body {
|
|||||||
.sidebar-logo-icon {
|
.sidebar-logo-icon {
|
||||||
width: 36px;
|
width: 36px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
background: linear-gradient(135deg, #0d6efd 0%, #0dcaf0 100%);
|
background: var(--primary-gradient);
|
||||||
border-radius: 8px;
|
border-radius: var(--radius-md);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -75,20 +132,20 @@ html, body {
|
|||||||
padding: 12px 20px;
|
padding: 12px 20px;
|
||||||
color: rgba(255, 255, 255, 0.7);
|
color: rgba(255, 255, 255, 0.7);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: all 0.2s ease;
|
transition: all var(--transition-normal);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-left: 3px solid transparent;
|
border-left: 3px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item:hover {
|
.menu-item:hover {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: rgba(255, 255, 255, 0.08);
|
background: var(--bg-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item.active {
|
.menu-item.active {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: rgba(13, 110, 253, 0.2);
|
background: var(--primary-light);
|
||||||
border-left-color: #0d6efd;
|
border-left-color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item i {
|
.menu-item i {
|
||||||
@@ -135,12 +192,18 @@ html, body {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 侧边栏分隔线 */
|
||||||
|
.sidebar-divider {
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
margin: var(--spacing-md) 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* ========== 主内容区 ========== */
|
/* ========== 主内容区 ========== */
|
||||||
.main-wrapper {
|
.main-wrapper {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
margin-left: 250px;
|
margin-left: var(--sidebar-width);
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background-color: #f8f9fa;
|
background-color: var(--bg-light);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
@@ -148,12 +211,12 @@ html, body {
|
|||||||
/* 顶部导航 */
|
/* 顶部导航 */
|
||||||
.top-header {
|
.top-header {
|
||||||
height: 64px;
|
height: 64px;
|
||||||
background: #fff;
|
background: var(--bg-card);
|
||||||
border-bottom: 1px solid #e9ecef;
|
border-bottom: 1px solid var(--border-color);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0 24px;
|
padding: 0 var(--spacing-lg);
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
@@ -162,7 +225,7 @@ html, body {
|
|||||||
.header-title {
|
.header-title {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #1a1c23;
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-user {
|
.header-user {
|
||||||
@@ -175,32 +238,32 @@ html, body {
|
|||||||
width: 36px;
|
width: 36px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: linear-gradient(135deg, #0d6efd 0%, #0dcaf0 100%);
|
background: var(--primary-gradient);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
margin-right: 8px;
|
margin-right: var(--spacing-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 内容区域 */
|
/* 内容区域 */
|
||||||
.main-content {
|
.main-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 24px;
|
padding: var(--spacing-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========== 页面卡片 ========== */
|
/* ========== 页面卡片 ========== */
|
||||||
.page-card {
|
.page-card {
|
||||||
background: #fff;
|
background: var(--bg-card);
|
||||||
border-radius: 8px;
|
border-radius: var(--radius-md);
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
box-shadow: var(--shadow-sm);
|
||||||
margin-bottom: 24px;
|
margin-bottom: var(--spacing-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-card-header {
|
.page-card-header {
|
||||||
padding: 16px 24px;
|
padding: var(--spacing-md) var(--spacing-lg);
|
||||||
border-bottom: 1px solid #e9ecef;
|
border-bottom: 1px solid var(--border-color);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -209,69 +272,69 @@ html, body {
|
|||||||
.page-card-title {
|
.page-card-title {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #1a1c23;
|
color: var(--text-primary);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-card-body {
|
.page-card-body {
|
||||||
padding: 24px;
|
padding: var(--spacing-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========== 统计卡片 ========== */
|
/* ========== 统计卡片 ========== */
|
||||||
.stat-card {
|
.stat-card {
|
||||||
background: #fff;
|
background: var(--bg-card);
|
||||||
border-radius: 8px;
|
border-radius: var(--radius-md);
|
||||||
padding: 24px;
|
padding: var(--spacing-lg);
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
box-shadow: var(--shadow-sm);
|
||||||
transition: all 0.2s ease;
|
transition: all var(--transition-normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card:hover {
|
.stat-card:hover {
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
box-shadow: var(--shadow-md);
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card-icon {
|
.stat-card-icon {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
border-radius: 12px;
|
border-radius: var(--radius-lg);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
margin-bottom: 16px;
|
margin-bottom: var(--spacing-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card-icon.primary {
|
.stat-card-icon.primary {
|
||||||
background: rgba(13, 110, 253, 0.1);
|
background: var(--primary-light);
|
||||||
color: #0d6efd;
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card-icon.success {
|
.stat-card-icon.success {
|
||||||
background: rgba(25, 135, 84, 0.1);
|
background: var(--success-light);
|
||||||
color: #198754;
|
color: var(--success-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card-icon.warning {
|
.stat-card-icon.warning {
|
||||||
background: rgba(255, 193, 7, 0.1);
|
background: var(--warning-light);
|
||||||
color: #ffc107;
|
color: var(--warning-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card-icon.info {
|
.stat-card-icon.info {
|
||||||
background: rgba(13, 202, 240, 0.1);
|
background: var(--info-light);
|
||||||
color: #0dcaf0;
|
color: var(--info-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card-value {
|
.stat-card-value {
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #1a1c23;
|
color: var(--text-primary);
|
||||||
margin-bottom: 4px;
|
margin-bottom: var(--spacing-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card-label {
|
.stat-card-label {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #6c757d;
|
color: var(--text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========== 工具栏 ========== */
|
/* ========== 工具栏 ========== */
|
||||||
@@ -280,21 +343,21 @@ html, body {
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 12px;
|
gap: var(--spacing-sm);
|
||||||
margin-bottom: 20px;
|
margin-bottom: var(--spacing-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar-left {
|
.toolbar-left {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
gap: var(--spacing-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar-right {
|
.toolbar-right {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
gap: var(--spacing-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========== 表格增强 ========== */
|
/* ========== 表格增强 ========== */
|
||||||
@@ -304,8 +367,8 @@ html, body {
|
|||||||
|
|
||||||
.table th {
|
.table th {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #495057;
|
color: var(--text-secondary);
|
||||||
background-color: #f8f9fa;
|
background-color: var(--bg-light);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,8 +428,8 @@ html, body {
|
|||||||
/* ========== 空状态 ========== */
|
/* ========== 空状态 ========== */
|
||||||
.empty-state {
|
.empty-state {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 48px 24px;
|
padding: 48px var(--spacing-lg);
|
||||||
color: #6c757d;
|
color: var(--text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.empty-state i {
|
.empty-state i {
|
||||||
@@ -390,34 +453,34 @@ html, body {
|
|||||||
|
|
||||||
/* ========== 文件上传区域 ========== */
|
/* ========== 文件上传区域 ========== */
|
||||||
.upload-area {
|
.upload-area {
|
||||||
border: 2px dashed #dee2e6;
|
border: 2px dashed var(--border-color);
|
||||||
border-radius: 8px;
|
border-radius: var(--radius-md);
|
||||||
padding: 32px;
|
padding: var(--spacing-xl);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all var(--transition-normal);
|
||||||
background: #f8f9fa;
|
background: var(--bg-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-area:hover {
|
.upload-area:hover {
|
||||||
border-color: #0d6efd;
|
border-color: var(--primary-color);
|
||||||
background: rgba(13, 110, 253, 0.02);
|
background: rgba(13, 110, 253, 0.02);
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-area.dragover {
|
.upload-area.dragover {
|
||||||
border-color: #0d6efd;
|
border-color: var(--primary-color);
|
||||||
background: rgba(13, 110, 253, 0.05);
|
background: rgba(13, 110, 253, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-area i {
|
.upload-area i {
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
color: #6c757d;
|
color: var(--text-secondary);
|
||||||
margin-bottom: 16px;
|
margin-bottom: var(--spacing-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-area p {
|
.upload-area p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #6c757d;
|
color: var(--text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-area .upload-hint {
|
.upload-area .upload-hint {
|
||||||
@@ -457,54 +520,54 @@ html, body {
|
|||||||
.answer-sheet {
|
.answer-sheet {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 8px;
|
gap: var(--spacing-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
.answer-sheet-item {
|
.answer-sheet-item {
|
||||||
width: 36px;
|
width: 36px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
border-radius: 4px;
|
border-radius: var(--radius-sm);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: 1px solid #dee2e6;
|
border: 1px solid var(--border-color);
|
||||||
background: #fff;
|
background: var(--bg-card);
|
||||||
transition: all 0.2s ease;
|
transition: all var(--transition-normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
.answer-sheet-item:hover {
|
.answer-sheet-item:hover {
|
||||||
border-color: #0d6efd;
|
border-color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.answer-sheet-item.current {
|
.answer-sheet-item.current {
|
||||||
border-color: #0d6efd;
|
border-color: var(--primary-color);
|
||||||
background: #0d6efd;
|
background: var(--primary-color);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.answer-sheet-item.answered {
|
.answer-sheet-item.answered {
|
||||||
background: #d1e7dd;
|
background: #d1e7dd;
|
||||||
border-color: #198754;
|
border-color: var(--success-color);
|
||||||
color: #198754;
|
color: var(--success-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========== 考试计时器 ========== */
|
/* ========== 考试计时器 ========== */
|
||||||
.exam-timer {
|
.exam-timer {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: var(--spacing-sm);
|
||||||
padding: 8px 16px;
|
padding: var(--spacing-sm) var(--spacing-md);
|
||||||
background: #fff3cd;
|
background: var(--warning-light);
|
||||||
border-radius: 8px;
|
border-radius: var(--radius-md);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.exam-timer.warning {
|
.exam-timer.warning {
|
||||||
background: #f8d7da;
|
background: var(--danger-light);
|
||||||
color: #842029;
|
color: var(--danger-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.exam-timer i {
|
.exam-timer i {
|
||||||
@@ -526,11 +589,11 @@ html, body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.top-header {
|
.top-header {
|
||||||
padding: 0 16px;
|
padding: 0 var(--spacing-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-content {
|
.main-content {
|
||||||
padding: 16px;
|
padding: var(--spacing-md);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,20 +17,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-people me-2"></i>人员管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/system/org.html" class="menu-item">组织架构</a><a href="/system/user.html" class="menu-item">员工管理</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-journal-richtext me-2"></i>知识库</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/knowledge/category.html" class="menu-item">知识分类</a><a href="/knowledge/list.html" class="menu-item">知识列表</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-pencil-square me-2"></i>考题管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/exam/question-category.html" class="menu-item">题库分类</a><a href="/exam/question.html" class="menu-item">题目列表</a></div></div>
|
|
||||||
<a href="/exam/paper.html" class="menu-item"><i class="bi bi-file-earmark-text"></i><span>试卷管理</span></a>
|
|
||||||
<a href="/exam/list.html" class="menu-item active"><i class="bi bi-clipboard-check"></i><span>考试管理</span></a>
|
|
||||||
<a href="/training/plan.html" class="menu-item"><i class="bi bi-calendar-check"></i><span>培训计划</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>系统设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item"><a href="/exam/list.html">考试管理</a></li><li class="breadcrumb-item active" id="pageTitle">发布考试</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item"><a href="/exam/list.html">考试管理</a></li><li class="breadcrumb-item active" id="pageTitle">发布考试</li></ol></nav>
|
||||||
@@ -147,6 +134,8 @@
|
|||||||
let examId = null, allUsers = [], filteredUsers = [], selectedUserIds = new Set(), papers = [];
|
let examId = null, allUsers = [], filteredUsers = [], selectedUserIds = new Set(), papers = [];
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', async function() {
|
document.addEventListener('DOMContentLoaded', async function() {
|
||||||
|
TrainingSystem.initSidebar('exam');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
examId = urlParams.get('id');
|
examId = urlParams.get('id');
|
||||||
loadPapers();
|
loadPapers();
|
||||||
|
|||||||
@@ -10,20 +10,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-people me-2"></i>人员管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/system/org.html" class="menu-item">组织架构</a><a href="/system/user.html" class="menu-item">员工管理</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-journal-richtext me-2"></i>知识库</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/knowledge/category.html" class="menu-item">知识分类</a><a href="/knowledge/list.html" class="menu-item">知识列表</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-pencil-square me-2"></i>考题管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/exam/question-category.html" class="menu-item">题库分类</a><a href="/exam/question.html" class="menu-item">题目列表</a></div></div>
|
|
||||||
<a href="/exam/paper.html" class="menu-item"><i class="bi bi-file-earmark-text"></i><span>试卷管理</span></a>
|
|
||||||
<a href="/exam/list.html" class="menu-item active"><i class="bi bi-clipboard-check"></i><span>考试管理</span></a>
|
|
||||||
<a href="/training/plan.html" class="menu-item"><i class="bi bi-calendar-check"></i><span>培训计划</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>系统设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item active">考试管理</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item active">考试管理</li></ol></nav>
|
||||||
@@ -98,6 +85,8 @@
|
|||||||
let currentPage = 1, pageSize = 10, detailModal;
|
let currentPage = 1, pageSize = 10, detailModal;
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('exam');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
detailModal = new bootstrap.Modal(document.getElementById('detailModal'));
|
detailModal = new bootstrap.Modal(document.getElementById('detailModal'));
|
||||||
loadList();
|
loadList();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -32,17 +32,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<a href="/exam/my-exams.html" class="menu-item active"><i class="bi bi-clipboard-check"></i><span>我的考试</span></a>
|
|
||||||
<a href="/training/my-training.html" class="menu-item"><i class="bi bi-calendar-check"></i><span>我的培训</span></a>
|
|
||||||
<a href="/knowledge/list.html" class="menu-item"><i class="bi bi-journal-richtext"></i><span>知识学习</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>个人设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item active">我的考试</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item active">我的考试</li></ol></nav>
|
||||||
@@ -76,6 +66,8 @@
|
|||||||
let allExams = [], currentTab = 'all';
|
let allExams = [], currentTab = 'all';
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('my-exams');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
loadExams();
|
loadExams();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -37,20 +37,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-people me-2"></i>人员管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/system/org.html" class="menu-item">组织架构</a><a href="/system/user.html" class="menu-item">员工管理</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-journal-richtext me-2"></i>知识库</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/knowledge/category.html" class="menu-item">知识分类</a><a href="/knowledge/list.html" class="menu-item">知识列表</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-pencil-square me-2"></i>考题管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/exam/question-category.html" class="menu-item">题库分类</a><a href="/exam/question.html" class="menu-item">题目列表</a></div></div>
|
|
||||||
<a href="/exam/paper.html" class="menu-item active"><i class="bi bi-file-earmark-text"></i><span>试卷管理</span></a>
|
|
||||||
<a href="/exam/list.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>考试管理</span></a>
|
|
||||||
<a href="/training/plan.html" class="menu-item"><i class="bi bi-calendar-check"></i><span>培训计划</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>系统设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item"><a href="/exam/paper.html">试卷管理</a></li><li class="breadcrumb-item active" id="pageTitle">创建试卷</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item"><a href="/exam/paper.html">试卷管理</a></li><li class="breadcrumb-item active" id="pageTitle">创建试卷</li></ol></nav>
|
||||||
@@ -197,6 +184,8 @@
|
|||||||
let questionPage = 1, questionPageSize = 20, hasMore = true;
|
let questionPage = 1, questionPageSize = 20, hasMore = true;
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('paper');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
paperId = urlParams.get('id');
|
paperId = urlParams.get('id');
|
||||||
loadCategories();
|
loadCategories();
|
||||||
|
|||||||
@@ -39,20 +39,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar no-print">
|
<div id="sidebarContainer" class="no-print"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-people me-2"></i>人员管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/system/org.html" class="menu-item">组织架构</a><a href="/system/user.html" class="menu-item">员工管理</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-journal-richtext me-2"></i>知识库</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/knowledge/category.html" class="menu-item">知识分类</a><a href="/knowledge/list.html" class="menu-item">知识列表</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-pencil-square me-2"></i>考题管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/exam/question-category.html" class="menu-item">题库分类</a><a href="/exam/question.html" class="menu-item">题目列表</a></div></div>
|
|
||||||
<a href="/exam/paper.html" class="menu-item active"><i class="bi bi-file-earmark-text"></i><span>试卷管理</span></a>
|
|
||||||
<a href="/exam/list.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>考试管理</span></a>
|
|
||||||
<a href="/training/plan.html" class="menu-item"><i class="bi bi-calendar-check"></i><span>培训计划</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>系统设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header no-print">
|
<header class="top-header no-print">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item"><a href="/exam/paper.html">试卷管理</a></li><li class="breadcrumb-item active">试卷预览</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item"><a href="/exam/paper.html">试卷管理</a></li><li class="breadcrumb-item active">试卷预览</li></ol></nav>
|
||||||
@@ -75,6 +62,8 @@
|
|||||||
if (!TrainingSystem.initPage()) {}
|
if (!TrainingSystem.initPage()) {}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('paper');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
const paperId = urlParams.get('id');
|
const paperId = urlParams.get('id');
|
||||||
if (paperId) {
|
if (paperId) {
|
||||||
|
|||||||
@@ -23,20 +23,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-people me-2"></i>人员管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/system/org.html" class="menu-item">组织架构</a><a href="/system/user.html" class="menu-item">员工管理</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-journal-richtext me-2"></i>知识库</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/knowledge/category.html" class="menu-item">知识分类</a><a href="/knowledge/list.html" class="menu-item">知识列表</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-pencil-square me-2"></i>考题管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/exam/question-category.html" class="menu-item">题库分类</a><a href="/exam/question.html" class="menu-item">题目列表</a></div></div>
|
|
||||||
<a href="/exam/paper.html" class="menu-item active"><i class="bi bi-file-earmark-text"></i><span>试卷管理</span></a>
|
|
||||||
<a href="/exam/list.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>考试管理</span></a>
|
|
||||||
<a href="/training/plan.html" class="menu-item"><i class="bi bi-calendar-check"></i><span>培训计划</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>系统设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item active">试卷管理</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item active">试卷管理</li></ol></nav>
|
||||||
@@ -82,6 +69,8 @@
|
|||||||
let currentPage = 1, pageSize = 10;
|
let currentPage = 1, pageSize = 10;
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('paper');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
loadList();
|
loadList();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -20,20 +20,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-people me-2"></i>人员管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/system/org.html" class="menu-item">组织架构</a><a href="/system/user.html" class="menu-item">员工管理</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-journal-richtext me-2"></i>知识库</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/knowledge/category.html" class="menu-item">知识分类</a><a href="/knowledge/list.html" class="menu-item">知识列表</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-pencil-square me-2"></i>考题管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/exam/question-category.html" class="menu-item active">题库分类</a><a href="/exam/question.html" class="menu-item">题目列表</a></div></div>
|
|
||||||
<a href="/exam/paper.html" class="menu-item"><i class="bi bi-file-earmark-text"></i><span>试卷管理</span></a>
|
|
||||||
<a href="/exam/list.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>考试管理</span></a>
|
|
||||||
<a href="/training/plan.html" class="menu-item"><i class="bi bi-calendar-check"></i><span>培训计划</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>系统设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item">考题管理</li><li class="breadcrumb-item active">题库分类</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item">考题管理</li><li class="breadcrumb-item active">题库分类</li></ol></nav>
|
||||||
@@ -63,7 +50,7 @@
|
|||||||
<script>
|
<script>
|
||||||
if (!TrainingSystem.initPage()) {}
|
if (!TrainingSystem.initPage()) {}
|
||||||
let treeData = [], selectedId = null, formModal;
|
let treeData = [], selectedId = null, formModal;
|
||||||
document.addEventListener('DOMContentLoaded', function() { formModal = new bootstrap.Modal(document.getElementById('formModal')); loadTree(); });
|
document.addEventListener('DOMContentLoaded', function() { TrainingSystem.initSidebar('question-category'); TrainingSystem.initUserInfo(); formModal = new bootstrap.Modal(document.getElementById('formModal')); loadTree(); });
|
||||||
|
|
||||||
async function loadTree() {
|
async function loadTree() {
|
||||||
const result = await TrainingSystem.get('/exam/question-category/tree');
|
const result = await TrainingSystem.get('/exam/question-category/tree');
|
||||||
|
|||||||
@@ -32,20 +32,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-people me-2"></i>人员管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/system/org.html" class="menu-item">组织架构</a><a href="/system/user.html" class="menu-item">员工管理</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-journal-richtext me-2"></i>知识库</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/knowledge/category.html" class="menu-item">知识分类</a><a href="/knowledge/list.html" class="menu-item">知识列表</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-pencil-square me-2"></i>考题管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/exam/question-category.html" class="menu-item">题库分类</a><a href="/exam/question.html" class="menu-item active">题目列表</a></div></div>
|
|
||||||
<a href="/exam/paper.html" class="menu-item"><i class="bi bi-file-earmark-text"></i><span>试卷管理</span></a>
|
|
||||||
<a href="/exam/list.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>考试管理</span></a>
|
|
||||||
<a href="/training/plan.html" class="menu-item"><i class="bi bi-calendar-check"></i><span>培训计划</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>系统设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item">考题管理</li><li class="breadcrumb-item"><a href="/exam/question.html">题目列表</a></li><li class="breadcrumb-item active" id="pageTitle">新增题目</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item">考题管理</li><li class="breadcrumb-item"><a href="/exam/question.html">题目列表</a></li><li class="breadcrumb-item active" id="pageTitle">新增题目</li></ol></nav>
|
||||||
@@ -197,6 +184,8 @@
|
|||||||
let currentType = 'SINGLE', selectedAnswers = [], judgeAnswer = '', questionId = null;
|
let currentType = 'SINGLE', selectedAnswers = [], judgeAnswer = '', questionId = null;
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('question');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
questionId = urlParams.get('id');
|
questionId = urlParams.get('id');
|
||||||
loadCategories();
|
loadCategories();
|
||||||
|
|||||||
@@ -29,20 +29,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-people me-2"></i>人员管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/system/org.html" class="menu-item">组织架构</a><a href="/system/user.html" class="menu-item">员工管理</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-journal-richtext me-2"></i>知识库</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/knowledge/category.html" class="menu-item">知识分类</a><a href="/knowledge/list.html" class="menu-item">知识列表</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-pencil-square me-2"></i>考题管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/exam/question-category.html" class="menu-item">题库分类</a><a href="/exam/question.html" class="menu-item active">题目列表</a></div></div>
|
|
||||||
<a href="/exam/paper.html" class="menu-item"><i class="bi bi-file-earmark-text"></i><span>试卷管理</span></a>
|
|
||||||
<a href="/exam/list.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>考试管理</span></a>
|
|
||||||
<a href="/training/plan.html" class="menu-item"><i class="bi bi-calendar-check"></i><span>培训计划</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>系统设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item">考题管理</li><li class="breadcrumb-item active">题目列表</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item">考题管理</li><li class="breadcrumb-item active">题目列表</li></ol></nav>
|
||||||
@@ -153,6 +140,8 @@
|
|||||||
let currentPage = 1, pageSize = 10, currentCategoryId = 0, categories = [], importModal;
|
let currentPage = 1, pageSize = 10, currentCategoryId = 0, categories = [], importModal;
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('question');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
importModal = new bootstrap.Modal(document.getElementById('importModal'));
|
importModal = new bootstrap.Modal(document.getElementById('importModal'));
|
||||||
// 从URL参数获取分类ID
|
// 从URL参数获取分类ID
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
|||||||
@@ -50,17 +50,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<a href="/exam/my-exams.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>我的考试</span></a>
|
|
||||||
<a href="/training/my-training.html" class="menu-item"><i class="bi bi-calendar-check"></i><span>我的培训</span></a>
|
|
||||||
<a href="/knowledge/list.html" class="menu-item"><i class="bi bi-journal-richtext"></i><span>知识学习</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>个人设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item"><a href="/exam/my-exams.html">我的考试</a></li><li class="breadcrumb-item active">考试成绩</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item"><a href="/exam/my-exams.html">我的考试</a></li><li class="breadcrumb-item active">考试成绩</li></ol></nav>
|
||||||
@@ -78,6 +68,8 @@
|
|||||||
if (!TrainingSystem.initPage()) {}
|
if (!TrainingSystem.initPage()) {}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('my-exams');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
const recordId = urlParams.get('recordId');
|
const recordId = urlParams.get('recordId');
|
||||||
const examId = urlParams.get('examId');
|
const examId = urlParams.get('examId');
|
||||||
|
|||||||
@@ -13,76 +13,8 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<!-- 侧边栏 -->
|
<!-- 侧边栏容器 - 动态渲染 -->
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo">
|
|
||||||
<div class="sidebar-logo-icon">
|
|
||||||
<i class="bi bi-truck text-white"></i>
|
|
||||||
</div>
|
|
||||||
<span class="sidebar-logo-text">道路救援培训系统</span>
|
|
||||||
</div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item active">
|
|
||||||
<i class="bi bi-grid-1x2"></i>
|
|
||||||
<span>工作台</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="menu-group">
|
|
||||||
<div class="menu-group-title">
|
|
||||||
<span><i class="bi bi-people me-2"></i>人员管理</span>
|
|
||||||
<i class="bi bi-chevron-down arrow"></i>
|
|
||||||
</div>
|
|
||||||
<div class="menu-submenu">
|
|
||||||
<a href="/system/org.html" class="menu-item">组织架构</a>
|
|
||||||
<a href="/system/user.html" class="menu-item">员工管理</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="menu-group">
|
|
||||||
<div class="menu-group-title">
|
|
||||||
<span><i class="bi bi-journal-richtext me-2"></i>知识库</span>
|
|
||||||
<i class="bi bi-chevron-down arrow"></i>
|
|
||||||
</div>
|
|
||||||
<div class="menu-submenu">
|
|
||||||
<a href="/knowledge/category.html" class="menu-item">知识分类</a>
|
|
||||||
<a href="/knowledge/list.html" class="menu-item">知识列表</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="menu-group">
|
|
||||||
<div class="menu-group-title">
|
|
||||||
<span><i class="bi bi-pencil-square me-2"></i>考题管理</span>
|
|
||||||
<i class="bi bi-chevron-down arrow"></i>
|
|
||||||
</div>
|
|
||||||
<div class="menu-submenu">
|
|
||||||
<a href="/exam/question-category.html" class="menu-item">题库分类</a>
|
|
||||||
<a href="/exam/question.html" class="menu-item">题目列表</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a href="/exam/paper.html" class="menu-item">
|
|
||||||
<i class="bi bi-file-earmark-text"></i>
|
|
||||||
<span>试卷管理</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a href="/exam/list.html" class="menu-item">
|
|
||||||
<i class="bi bi-clipboard-check"></i>
|
|
||||||
<span>考试管理</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a href="/training/plan.html" class="menu-item">
|
|
||||||
<i class="bi bi-calendar-check"></i>
|
|
||||||
<span>培训计划</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
|
|
||||||
<a href="/system/setting.html" class="menu-item">
|
|
||||||
<i class="bi bi-gear"></i>
|
|
||||||
<span>系统设置</span>
|
|
||||||
</a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
<!-- 主内容区 -->
|
<!-- 主内容区 -->
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
@@ -292,6 +224,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// 初始化侧边栏
|
||||||
|
TrainingSystem.initSidebar('dashboard');
|
||||||
|
|
||||||
// 初始化用户信息
|
// 初始化用户信息
|
||||||
initUserDisplay();
|
initUserDisplay();
|
||||||
|
|
||||||
@@ -301,7 +236,7 @@
|
|||||||
// 加载工作台数据
|
// 加载工作台数据
|
||||||
loadDashboardData();
|
loadDashboardData();
|
||||||
|
|
||||||
// 初始化菜单
|
// 初始化用户头像显示
|
||||||
TrainingSystem.initUserInfo();
|
TrainingSystem.initUserInfo();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -468,12 +468,144 @@ function getStatusBadge(status, statusName) {
|
|||||||
return `<span class="status-badge ${statusClass[status] || ''}">${statusName || status}</span>`;
|
return `<span class="status-badge ${statusClass[status] || ''}">${statusName || status}</span>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单配置 - 根据角色控制可见性
|
||||||
|
* roles: ADMIN=管理员, LECTURER=讲师, STUDENT=学员
|
||||||
|
*/
|
||||||
|
const MENU_CONFIG = [
|
||||||
|
{
|
||||||
|
id: 'dashboard',
|
||||||
|
name: '工作台',
|
||||||
|
icon: 'bi-grid-1x2',
|
||||||
|
url: '/index.html',
|
||||||
|
roles: ['ADMIN', 'LECTURER', 'STUDENT']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'system',
|
||||||
|
name: '人员管理',
|
||||||
|
icon: 'bi-people',
|
||||||
|
roles: ['ADMIN', 'LECTURER'],
|
||||||
|
children: [
|
||||||
|
{ id: 'org', name: '组织架构', url: '/system/org.html', roles: ['ADMIN'] },
|
||||||
|
{ id: 'user', name: '员工管理', url: '/system/user.html', roles: ['ADMIN', 'LECTURER'] }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'knowledge',
|
||||||
|
name: '知识库',
|
||||||
|
icon: 'bi-journal-richtext',
|
||||||
|
roles: ['ADMIN', 'LECTURER', 'STUDENT'],
|
||||||
|
children: [
|
||||||
|
{ id: 'knowledge-category', name: '知识分类', url: '/knowledge/category.html', roles: ['ADMIN', 'LECTURER'] },
|
||||||
|
{ id: 'knowledge-list', name: '知识列表', url: '/knowledge/list.html', roles: ['ADMIN', 'LECTURER', 'STUDENT'] }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'question',
|
||||||
|
name: '考题管理',
|
||||||
|
icon: 'bi-pencil-square',
|
||||||
|
roles: ['ADMIN', 'LECTURER'],
|
||||||
|
children: [
|
||||||
|
{ id: 'question-category', name: '题库分类', url: '/exam/question-category.html', roles: ['ADMIN', 'LECTURER'] },
|
||||||
|
{ id: 'question-list', name: '题目列表', url: '/exam/question.html', roles: ['ADMIN', 'LECTURER'] }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'paper',
|
||||||
|
name: '试卷管理',
|
||||||
|
icon: 'bi-file-earmark-text',
|
||||||
|
url: '/exam/paper.html',
|
||||||
|
roles: ['ADMIN', 'LECTURER']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'exam',
|
||||||
|
name: '考试管理',
|
||||||
|
icon: 'bi-clipboard-check',
|
||||||
|
url: '/exam/list.html',
|
||||||
|
roles: ['ADMIN', 'LECTURER', 'STUDENT']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'training',
|
||||||
|
name: '培训计划',
|
||||||
|
icon: 'bi-calendar-check',
|
||||||
|
url: '/training/plan.html',
|
||||||
|
roles: ['ADMIN', 'LECTURER', 'STUDENT']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'divider',
|
||||||
|
type: 'divider',
|
||||||
|
roles: ['ADMIN']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'setting',
|
||||||
|
name: '系统设置',
|
||||||
|
icon: 'bi-gear',
|
||||||
|
url: '/system/setting.html',
|
||||||
|
roles: ['ADMIN']
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据角色过滤菜单
|
||||||
|
*/
|
||||||
|
function filterMenuByRole(menuConfig, userRole) {
|
||||||
|
return menuConfig
|
||||||
|
.filter(item => item.roles.includes(userRole))
|
||||||
|
.map(item => {
|
||||||
|
if (item.children) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
children: item.children.filter(child => child.roles.includes(userRole))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
})
|
||||||
|
.filter(item => !item.children || item.children.length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成侧边栏HTML
|
* 生成侧边栏HTML
|
||||||
*/
|
*/
|
||||||
function renderSidebar(activeMenu) {
|
function renderSidebar(activeMenu) {
|
||||||
|
const user = getCurrentUser();
|
||||||
|
const userRole = user?.role || 'STUDENT';
|
||||||
|
const filteredMenu = filterMenuByRole(MENU_CONFIG, userRole);
|
||||||
|
|
||||||
|
let menuHtml = '';
|
||||||
|
filteredMenu.forEach(item => {
|
||||||
|
if (item.type === 'divider') {
|
||||||
|
menuHtml += '<div class="sidebar-divider"></div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.children) {
|
||||||
|
// 判断子菜单是否有激活项
|
||||||
|
const hasActiveChild = item.children.some(child => child.id === activeMenu);
|
||||||
|
menuHtml += `
|
||||||
|
<div class="menu-group${hasActiveChild ? '' : ' collapsed'}">
|
||||||
|
<div class="menu-group-title">
|
||||||
|
<span><i class="bi ${item.icon} me-2"></i>${item.name}</span>
|
||||||
|
<i class="bi bi-chevron-down arrow"></i>
|
||||||
|
</div>
|
||||||
|
<div class="menu-submenu">
|
||||||
|
${item.children.map(child => `
|
||||||
|
<a href="${child.url}" class="menu-item${child.id === activeMenu ? ' active' : ''}">${child.name}</a>
|
||||||
|
`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
} else {
|
||||||
|
menuHtml += `
|
||||||
|
<a href="${item.url}" class="menu-item${item.id === activeMenu ? ' active' : ''}">
|
||||||
|
<i class="bi ${item.icon}"></i>
|
||||||
|
<span>${item.name}</span>
|
||||||
|
</a>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<aside class="sidebar">
|
<aside class="sidebar" id="sidebar">
|
||||||
<div class="sidebar-logo">
|
<div class="sidebar-logo">
|
||||||
<div class="sidebar-logo-icon">
|
<div class="sidebar-logo-icon">
|
||||||
<i class="bi bi-truck text-white"></i>
|
<i class="bi bi-truck text-white"></i>
|
||||||
@@ -481,70 +613,23 @@ function renderSidebar(activeMenu) {
|
|||||||
<span class="sidebar-logo-text">道路救援培训系统</span>
|
<span class="sidebar-logo-text">道路救援培训系统</span>
|
||||||
</div>
|
</div>
|
||||||
<nav class="sidebar-menu">
|
<nav class="sidebar-menu">
|
||||||
<a href="/index.html" class="menu-item ${activeMenu === 'dashboard' ? 'active' : ''}">
|
${menuHtml}
|
||||||
<i class="bi bi-grid-1x2"></i>
|
|
||||||
<span>工作台</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="menu-group">
|
|
||||||
<div class="menu-group-title">
|
|
||||||
<span><i class="bi bi-people me-2"></i>人员管理</span>
|
|
||||||
<i class="bi bi-chevron-down arrow"></i>
|
|
||||||
</div>
|
|
||||||
<div class="menu-submenu">
|
|
||||||
<a href="/system/org.html" class="menu-item ${activeMenu === 'org' ? 'active' : ''}">组织架构</a>
|
|
||||||
<a href="/system/user.html" class="menu-item ${activeMenu === 'user' ? 'active' : ''}">员工管理</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="menu-group">
|
|
||||||
<div class="menu-group-title">
|
|
||||||
<span><i class="bi bi-journal-richtext me-2"></i>知识库</span>
|
|
||||||
<i class="bi bi-chevron-down arrow"></i>
|
|
||||||
</div>
|
|
||||||
<div class="menu-submenu">
|
|
||||||
<a href="/knowledge/category.html" class="menu-item ${activeMenu === 'knowledge-category' ? 'active' : ''}">知识分类</a>
|
|
||||||
<a href="/knowledge/list.html" class="menu-item ${activeMenu === 'knowledge-list' ? 'active' : ''}">知识列表</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="menu-group">
|
|
||||||
<div class="menu-group-title">
|
|
||||||
<span><i class="bi bi-pencil-square me-2"></i>考题管理</span>
|
|
||||||
<i class="bi bi-chevron-down arrow"></i>
|
|
||||||
</div>
|
|
||||||
<div class="menu-submenu">
|
|
||||||
<a href="/exam/question-category.html" class="menu-item ${activeMenu === 'question-category' ? 'active' : ''}">题库分类</a>
|
|
||||||
<a href="/exam/question.html" class="menu-item ${activeMenu === 'question' ? 'active' : ''}">题目列表</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a href="/exam/paper.html" class="menu-item ${activeMenu === 'paper' ? 'active' : ''}">
|
|
||||||
<i class="bi bi-file-earmark-text"></i>
|
|
||||||
<span>试卷管理</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a href="/exam/list.html" class="menu-item ${activeMenu === 'exam' ? 'active' : ''}">
|
|
||||||
<i class="bi bi-clipboard-check"></i>
|
|
||||||
<span>考试管理</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a href="/training/plan.html" class="menu-item ${activeMenu === 'training' ? 'active' : ''}">
|
|
||||||
<i class="bi bi-calendar-check"></i>
|
|
||||||
<span>培训计划</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
|
|
||||||
<a href="/system/setting.html" class="menu-item ${activeMenu === 'setting' ? 'active' : ''}">
|
|
||||||
<i class="bi bi-gear"></i>
|
|
||||||
<span>系统设置</span>
|
|
||||||
</a>
|
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化侧边栏(动态渲染到页面)
|
||||||
|
*/
|
||||||
|
function initSidebar(activeMenu) {
|
||||||
|
const sidebarContainer = document.getElementById('sidebarContainer');
|
||||||
|
if (sidebarContainer) {
|
||||||
|
sidebarContainer.innerHTML = renderSidebar(activeMenu);
|
||||||
|
initMenuState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成顶部导航HTML
|
* 生成顶部导航HTML
|
||||||
*/
|
*/
|
||||||
@@ -611,8 +696,10 @@ window.TrainingSystem = {
|
|||||||
renderPagination,
|
renderPagination,
|
||||||
initPage,
|
initPage,
|
||||||
initUserInfo,
|
initUserInfo,
|
||||||
|
initMenuState,
|
||||||
logout,
|
logout,
|
||||||
getStatusBadge,
|
getStatusBadge,
|
||||||
renderSidebar,
|
renderSidebar,
|
||||||
|
initSidebar,
|
||||||
renderHeader
|
renderHeader
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,41 +29,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo">
|
|
||||||
<div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div>
|
|
||||||
<span class="sidebar-logo-text">道路救援培训系统</span>
|
|
||||||
</div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<div class="menu-group">
|
|
||||||
<div class="menu-group-title"><span><i class="bi bi-people me-2"></i>人员管理</span><i class="bi bi-chevron-down arrow"></i></div>
|
|
||||||
<div class="menu-submenu">
|
|
||||||
<a href="/system/org.html" class="menu-item">组织架构</a>
|
|
||||||
<a href="/system/user.html" class="menu-item">员工管理</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="menu-group">
|
|
||||||
<div class="menu-group-title"><span><i class="bi bi-journal-richtext me-2"></i>知识库</span><i class="bi bi-chevron-down arrow"></i></div>
|
|
||||||
<div class="menu-submenu">
|
|
||||||
<a href="/knowledge/category.html" class="menu-item active">知识分类</a>
|
|
||||||
<a href="/knowledge/list.html" class="menu-item">知识列表</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="menu-group">
|
|
||||||
<div class="menu-group-title"><span><i class="bi bi-pencil-square me-2"></i>考题管理</span><i class="bi bi-chevron-down arrow"></i></div>
|
|
||||||
<div class="menu-submenu">
|
|
||||||
<a href="/exam/question-category.html" class="menu-item">题库分类</a>
|
|
||||||
<a href="/exam/question.html" class="menu-item">题目列表</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<a href="/exam/paper.html" class="menu-item"><i class="bi bi-file-earmark-text"></i><span>试卷管理</span></a>
|
|
||||||
<a href="/exam/list.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>考试管理</span></a>
|
|
||||||
<a href="/training/plan.html" class="menu-item"><i class="bi bi-calendar-check"></i><span>培训计划</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>系统设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
@@ -136,6 +102,8 @@
|
|||||||
let treeData = [], selectedId = null, formModal;
|
let treeData = [], selectedId = null, formModal;
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('knowledge-category');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
formModal = new bootstrap.Modal(document.getElementById('formModal'));
|
formModal = new bootstrap.Modal(document.getElementById('formModal'));
|
||||||
loadTree();
|
loadTree();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,75 +14,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<!-- 侧边栏 -->
|
<!-- 侧边栏 -->
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo">
|
|
||||||
<div class="sidebar-logo-icon">
|
|
||||||
<i class="bi bi-truck text-white"></i>
|
|
||||||
</div>
|
|
||||||
<span class="sidebar-logo-text">道路救援培训系统</span>
|
|
||||||
</div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item">
|
|
||||||
<i class="bi bi-grid-1x2"></i>
|
|
||||||
<span>工作台</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="menu-group">
|
|
||||||
<div class="menu-group-title">
|
|
||||||
<span><i class="bi bi-people me-2"></i>人员管理</span>
|
|
||||||
<i class="bi bi-chevron-down arrow"></i>
|
|
||||||
</div>
|
|
||||||
<div class="menu-submenu">
|
|
||||||
<a href="/system/org.html" class="menu-item">组织架构</a>
|
|
||||||
<a href="/system/user.html" class="menu-item">员工管理</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="menu-group">
|
|
||||||
<div class="menu-group-title">
|
|
||||||
<span><i class="bi bi-journal-richtext me-2"></i>知识库</span>
|
|
||||||
<i class="bi bi-chevron-down arrow"></i>
|
|
||||||
</div>
|
|
||||||
<div class="menu-submenu">
|
|
||||||
<a href="/knowledge/category.html" class="menu-item">知识分类</a>
|
|
||||||
<a href="/knowledge/list.html" class="menu-item active">知识列表</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="menu-group">
|
|
||||||
<div class="menu-group-title">
|
|
||||||
<span><i class="bi bi-pencil-square me-2"></i>考题管理</span>
|
|
||||||
<i class="bi bi-chevron-down arrow"></i>
|
|
||||||
</div>
|
|
||||||
<div class="menu-submenu">
|
|
||||||
<a href="/exam/question-category.html" class="menu-item">题库分类</a>
|
|
||||||
<a href="/exam/question.html" class="menu-item">题目列表</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a href="/exam/paper.html" class="menu-item">
|
|
||||||
<i class="bi bi-file-earmark-text"></i>
|
|
||||||
<span>试卷管理</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a href="/exam/list.html" class="menu-item">
|
|
||||||
<i class="bi bi-clipboard-check"></i>
|
|
||||||
<span>考试管理</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a href="/training/plan.html" class="menu-item">
|
|
||||||
<i class="bi bi-calendar-check"></i>
|
|
||||||
<span>培训计划</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
|
|
||||||
<a href="/system/setting.html" class="menu-item">
|
|
||||||
<i class="bi bi-gear"></i>
|
|
||||||
<span>系统设置</span>
|
|
||||||
</a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
<!-- 主内容区 -->
|
<!-- 主内容区 -->
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
@@ -283,6 +215,8 @@
|
|||||||
let formModal;
|
let formModal;
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('knowledge-list');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
formModal = new bootstrap.Modal(document.getElementById('formModal'));
|
formModal = new bootstrap.Modal(document.getElementById('formModal'));
|
||||||
loadCategories();
|
loadCategories();
|
||||||
loadList();
|
loadList();
|
||||||
|
|||||||
@@ -34,17 +34,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<a href="/exam/my-exams.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>我的考试</span></a>
|
|
||||||
<a href="/training/my-training.html" class="menu-item"><i class="bi bi-calendar-check"></i><span>我的培训</span></a>
|
|
||||||
<a href="/knowledge/list.html" class="menu-item active"><i class="bi bi-journal-richtext"></i><span>知识学习</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>个人设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item"><a href="/knowledge/list.html">知识学习</a></li><li class="breadcrumb-item active" id="breadcrumbTitle">详情</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item"><a href="/knowledge/list.html">知识学习</a></li><li class="breadcrumb-item active" id="breadcrumbTitle">详情</li></ol></nav>
|
||||||
@@ -63,6 +53,8 @@
|
|||||||
let knowledgeId = null, startTime = null;
|
let knowledgeId = null, startTime = null;
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('knowledge-list');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
knowledgeId = urlParams.get('id');
|
knowledgeId = urlParams.get('id');
|
||||||
if (knowledgeId) {
|
if (knowledgeId) {
|
||||||
|
|||||||
@@ -9,12 +9,17 @@
|
|||||||
<!-- Bootstrap Icons -->
|
<!-- Bootstrap Icons -->
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
|
:root {
|
||||||
|
--primary-color: #0d6efd;
|
||||||
|
--primary-hover: #0b5ed7;
|
||||||
|
--primary-gradient: linear-gradient(135deg, #0d6efd 0%, #0dcaf0 100%);
|
||||||
|
}
|
||||||
body {
|
body {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
background: var(--primary-gradient);
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,13 +45,13 @@
|
|||||||
.login-logo {
|
.login-logo {
|
||||||
width: 64px;
|
width: 64px;
|
||||||
height: 64px;
|
height: 64px;
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
background: var(--primary-gradient);
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin: 0 auto 20px;
|
margin: 0 auto 20px;
|
||||||
box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4);
|
box-shadow: 0 8px 24px rgba(13, 110, 253, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-logo i {
|
.login-logo i {
|
||||||
@@ -83,8 +88,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.form-floating > .form-control:focus {
|
.form-floating > .form-control:focus {
|
||||||
border-color: #667eea;
|
border-color: var(--primary-color);
|
||||||
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.15);
|
box-shadow: 0 0 0 3px rgba(13, 110, 253, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-floating > label {
|
.form-floating > label {
|
||||||
@@ -103,7 +108,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.form-floating:focus-within .input-icon {
|
.form-floating:focus-within .input-icon {
|
||||||
color: #667eea;
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-login {
|
.btn-login {
|
||||||
@@ -112,14 +117,14 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
background: var(--primary-gradient);
|
||||||
border: none;
|
border: none;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-login:hover {
|
.btn-login:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4);
|
box-shadow: 0 8px 24px rgba(13, 110, 253, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.divider {
|
.divider {
|
||||||
@@ -189,7 +194,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.password-toggle:hover {
|
.password-toggle:hover {
|
||||||
color: #667eea;
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
@@ -328,7 +333,7 @@
|
|||||||
|
|
||||||
if (result && result.code === 200) {
|
if (result && result.code === 200) {
|
||||||
TrainingSystem.setToken(result.data.token);
|
TrainingSystem.setToken(result.data.token);
|
||||||
TrainingSystem.setCurrentUser(result.data.user);
|
TrainingSystem.setCurrentUser(result.data);
|
||||||
TrainingSystem.showMessage('登录成功', 'success');
|
TrainingSystem.showMessage('登录成功', 'success');
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|||||||
@@ -24,20 +24,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-people me-2"></i>人员管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/system/org.html" class="menu-item active">组织架构</a><a href="/system/user.html" class="menu-item">员工管理</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-journal-richtext me-2"></i>知识库</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/knowledge/category.html" class="menu-item">知识分类</a><a href="/knowledge/list.html" class="menu-item">知识列表</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-pencil-square me-2"></i>考题管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/exam/question-category.html" class="menu-item">题库分类</a><a href="/exam/question.html" class="menu-item">题目列表</a></div></div>
|
|
||||||
<a href="/exam/paper.html" class="menu-item"><i class="bi bi-file-earmark-text"></i><span>试卷管理</span></a>
|
|
||||||
<a href="/exam/list.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>考试管理</span></a>
|
|
||||||
<a href="/training/plan.html" class="menu-item"><i class="bi bi-calendar-check"></i><span>培训计划</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>系统设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item">人员管理</li><li class="breadcrumb-item active">组织架构</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item">人员管理</li><li class="breadcrumb-item active">组织架构</li></ol></nav>
|
||||||
@@ -67,7 +54,12 @@
|
|||||||
<script>
|
<script>
|
||||||
if (!TrainingSystem.initPage()) {}
|
if (!TrainingSystem.initPage()) {}
|
||||||
let orgData = [], selectedNode = null, formModal;
|
let orgData = [], selectedNode = null, formModal;
|
||||||
document.addEventListener('DOMContentLoaded', function() { formModal = new bootstrap.Modal(document.getElementById('formModal')); loadOrgTree(); });
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('org');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
|
formModal = new bootstrap.Modal(document.getElementById('formModal'));
|
||||||
|
loadOrgTree();
|
||||||
|
});
|
||||||
|
|
||||||
async function loadOrgTree() {
|
async function loadOrgTree() {
|
||||||
const result = await TrainingSystem.get('/system/org/tree');
|
const result = await TrainingSystem.get('/system/org/tree');
|
||||||
|
|||||||
@@ -10,20 +10,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-people me-2"></i>人员管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/system/org.html" class="menu-item">组织架构</a><a href="/system/user.html" class="menu-item active">员工管理</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-journal-richtext me-2"></i>知识库</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/knowledge/category.html" class="menu-item">知识分类</a><a href="/knowledge/list.html" class="menu-item">知识列表</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-pencil-square me-2"></i>考题管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/exam/question-category.html" class="menu-item">题库分类</a><a href="/exam/question.html" class="menu-item">题目列表</a></div></div>
|
|
||||||
<a href="/exam/paper.html" class="menu-item"><i class="bi bi-file-earmark-text"></i><span>试卷管理</span></a>
|
|
||||||
<a href="/exam/list.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>考试管理</span></a>
|
|
||||||
<a href="/training/plan.html" class="menu-item"><i class="bi bi-calendar-check"></i><span>培训计划</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>系统设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item">人员管理</li><li class="breadcrumb-item active">员工管理</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item">人员管理</li><li class="breadcrumb-item active">员工管理</li></ol></nav>
|
||||||
@@ -60,7 +47,13 @@
|
|||||||
<script>
|
<script>
|
||||||
if (!TrainingSystem.initPage()) {}
|
if (!TrainingSystem.initPage()) {}
|
||||||
let currentPage = 1, pageSize = 10, departments = [], formModal;
|
let currentPage = 1, pageSize = 10, departments = [], formModal;
|
||||||
document.addEventListener('DOMContentLoaded', function() { formModal = new bootstrap.Modal(document.getElementById('formModal')); loadDepartments(); loadList(); });
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('user');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
|
formModal = new bootstrap.Modal(document.getElementById('formModal'));
|
||||||
|
loadDepartments();
|
||||||
|
loadList();
|
||||||
|
});
|
||||||
document.getElementById('formDept').addEventListener('change', function() { loadGroups(this.value); });
|
document.getElementById('formDept').addEventListener('change', function() { loadGroups(this.value); });
|
||||||
|
|
||||||
async function loadDepartments() {
|
async function loadDepartments() {
|
||||||
|
|||||||
@@ -35,20 +35,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-people me-2"></i>人员管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/system/org.html" class="menu-item">组织架构</a><a href="/system/user.html" class="menu-item">员工管理</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-journal-richtext me-2"></i>知识库</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/knowledge/category.html" class="menu-item">知识分类</a><a href="/knowledge/list.html" class="menu-item">知识列表</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-pencil-square me-2"></i>考题管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/exam/question-category.html" class="menu-item">题库分类</a><a href="/exam/question.html" class="menu-item">题目列表</a></div></div>
|
|
||||||
<a href="/exam/paper.html" class="menu-item"><i class="bi bi-file-earmark-text"></i><span>试卷管理</span></a>
|
|
||||||
<a href="/exam/list.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>考试管理</span></a>
|
|
||||||
<a href="/training/plan.html" class="menu-item active"><i class="bi bi-calendar-check"></i><span>培训计划</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>系统设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item"><a href="/training/plan.html">培训计划</a></li><li class="breadcrumb-item active">培训详情</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item"><a href="/training/plan.html">培训计划</a></li><li class="breadcrumb-item active">培训详情</li></ol></nav>
|
||||||
@@ -66,6 +53,8 @@
|
|||||||
if (!TrainingSystem.initPage()) {}
|
if (!TrainingSystem.initPage()) {}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('training');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
const planId = urlParams.get('id');
|
const planId = urlParams.get('id');
|
||||||
if (planId) {
|
if (planId) {
|
||||||
@@ -86,8 +75,30 @@
|
|||||||
|
|
||||||
function renderDetail(data) {
|
function renderDetail(data) {
|
||||||
const plan = data;
|
const plan = data;
|
||||||
const completionRate = plan.participantCount > 0 ? Math.round((plan.completedCount / plan.participantCount) * 100) : 0;
|
// 合并知识列表和考试列表为统一的items
|
||||||
|
const items = [];
|
||||||
|
if (plan.knowledgeList && plan.knowledgeList.length > 0) {
|
||||||
|
plan.knowledgeList.forEach(k => {
|
||||||
|
items.push({
|
||||||
|
type: 'KNOWLEDGE',
|
||||||
|
title: k.knowledge ? k.knowledge.title : '',
|
||||||
|
required: k.required
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (plan.examList && plan.examList.length > 0) {
|
||||||
|
plan.examList.forEach(e => {
|
||||||
|
items.push({
|
||||||
|
type: 'EXAM',
|
||||||
|
title: e.examTitle || '',
|
||||||
|
required: e.required
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalItems = (plan.knowledgeCount || 0) + (plan.examCount || 0);
|
||||||
const statusLabels = {
|
const statusLabels = {
|
||||||
|
'NOT_STARTED': '<span class="badge bg-secondary">未开始</span>',
|
||||||
'DRAFT': '<span class="badge bg-secondary">草稿</span>',
|
'DRAFT': '<span class="badge bg-secondary">草稿</span>',
|
||||||
'IN_PROGRESS': '<span class="badge bg-success">进行中</span>',
|
'IN_PROGRESS': '<span class="badge bg-success">进行中</span>',
|
||||||
'ENDED': '<span class="badge bg-dark">已结束</span>'
|
'ENDED': '<span class="badge bg-dark">已结束</span>'
|
||||||
@@ -107,10 +118,10 @@
|
|||||||
${statusLabels[plan.status] || ''}
|
${statusLabels[plan.status] || ''}
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-stats">
|
<div class="detail-stats">
|
||||||
<div class="detail-stat"><div class="value">${plan.participantCount || 0}</div><div class="label">参与人数</div></div>
|
<div class="detail-stat"><div class="value">${plan.knowledgeCount || 0}</div><div class="label">知识学习</div></div>
|
||||||
<div class="detail-stat"><div class="value">${plan.completedCount || 0}</div><div class="label">已完成</div></div>
|
<div class="detail-stat"><div class="value">${plan.examCount || 0}</div><div class="label">考试任务</div></div>
|
||||||
<div class="detail-stat"><div class="value">${completionRate}%</div><div class="label">完成率</div></div>
|
<div class="detail-stat"><div class="value">${totalItems}</div><div class="label">培训项目</div></div>
|
||||||
<div class="detail-stat"><div class="value">${(plan.items || []).length}</div><div class="label">培训项目</div></div>
|
<div class="detail-stat"><div class="value">${plan.participantCount || 0}</div><div class="label">培训对象</div></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -119,8 +130,8 @@
|
|||||||
<div class="content-card">
|
<div class="content-card">
|
||||||
<h5 class="mb-3"><i class="bi bi-list-check me-2"></i>培训内容</h5>`;
|
<h5 class="mb-3"><i class="bi bi-list-check me-2"></i>培训内容</h5>`;
|
||||||
|
|
||||||
if (plan.items && plan.items.length > 0) {
|
if (items.length > 0) {
|
||||||
plan.items.forEach((item, i) => {
|
items.forEach((item, i) => {
|
||||||
html += `<div class="content-item">
|
html += `<div class="content-item">
|
||||||
<div class="item-num">${i + 1}</div>
|
<div class="item-num">${i + 1}</div>
|
||||||
<div class="item-icon ${item.type === 'KNOWLEDGE' ? 'knowledge' : 'exam'}">
|
<div class="item-icon ${item.type === 'KNOWLEDGE' ? 'knowledge' : 'exam'}">
|
||||||
@@ -133,7 +144,6 @@
|
|||||||
${item.required ? '<span class="badge bg-danger ms-1">必修</span>' : '<span class="badge bg-secondary ms-1">选修</span>'}
|
${item.required ? '<span class="badge bg-danger ms-1">必修</span>' : '<span class="badge bg-secondary ms-1">选修</span>'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-muted small">${item.completedCount || 0}/${plan.participantCount || 0}人完成</div>
|
|
||||||
</div>`;
|
</div>`;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -148,30 +158,22 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-lg-7">
|
<div class="col-lg-7">
|
||||||
<div class="content-card">
|
<div class="content-card">
|
||||||
<h5 class="mb-3"><i class="bi bi-people me-2"></i>参与人员进度</h5>
|
<h5 class="mb-3"><i class="bi bi-people me-2"></i>培训对象</h5>
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-hover participant-table">
|
<table class="table table-hover participant-table">
|
||||||
<thead><tr><th>姓名</th><th>部门</th><th>进度</th><th>状态</th></tr></thead>
|
<thead><tr><th>类型</th><th>名称</th></tr></thead>
|
||||||
<tbody>`;
|
<tbody>`;
|
||||||
|
|
||||||
if (plan.participants && plan.participants.length > 0) {
|
if (plan.targets && plan.targets.length > 0) {
|
||||||
plan.participants.forEach(p => {
|
plan.targets.forEach(t => {
|
||||||
const progress = p.totalCount > 0 ? Math.round((p.completedCount / p.totalCount) * 100) : 0;
|
const typeIcon = t.targetType === 'DEPARTMENT' ? 'bi-building' : (t.targetType === 'GROUP' ? 'bi-people' : 'bi-person');
|
||||||
const isCompleted = progress >= 100;
|
|
||||||
html += `<tr>
|
html += `<tr>
|
||||||
<td><div class="d-flex align-items-center"><div class="avatar me-2" style="width:32px;height:32px;font-size:12px;">${(p.realName || '?').charAt(0)}</div>${p.realName || '-'}</div></td>
|
<td><i class="bi ${typeIcon} me-2"></i>${t.targetTypeName || t.targetType}</td>
|
||||||
<td>${p.departmentName || '-'}</td>
|
<td>${t.targetName || '-'}</td>
|
||||||
<td>
|
|
||||||
<div class="d-flex align-items-center gap-2">
|
|
||||||
<div class="progress"><div class="progress-bar ${isCompleted ? 'bg-success' : ''}" style="width:${progress}%"></div></div>
|
|
||||||
<span class="small">${progress}%</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>${isCompleted ? '<span class="badge bg-success">已完成</span>' : '<span class="badge bg-warning">进行中</span>'}</td>
|
|
||||||
</tr>`;
|
</tr>`;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
html += '<tr><td colspan="4" class="text-center text-muted py-4">暂无参与人员</td></tr>';
|
html += '<tr><td colspan="2" class="text-center text-muted py-4">暂无培训对象</td></tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
html += `</tbody></table></div></div></div></div>`;
|
html += `</tbody></table></div></div></div></div>`;
|
||||||
|
|||||||
@@ -30,17 +30,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<a href="/exam/my-exams.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>我的考试</span></a>
|
|
||||||
<a href="/training/my-training.html" class="menu-item active"><i class="bi bi-calendar-check"></i><span>我的培训</span></a>
|
|
||||||
<a href="/knowledge/list.html" class="menu-item"><i class="bi bi-journal-richtext"></i><span>知识学习</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>个人设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item active">我的培训</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item active">我的培训</li></ol></nav>
|
||||||
@@ -79,6 +69,8 @@
|
|||||||
let allTrainings = [], currentTab = 'ongoing';
|
let allTrainings = [], currentTab = 'ongoing';
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('my-training');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
loadTrainings();
|
loadTrainings();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -28,20 +28,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-people me-2"></i>人员管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/system/org.html" class="menu-item">组织架构</a><a href="/system/user.html" class="menu-item">员工管理</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-journal-richtext me-2"></i>知识库</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/knowledge/category.html" class="menu-item">知识分类</a><a href="/knowledge/list.html" class="menu-item">知识列表</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-pencil-square me-2"></i>考题管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/exam/question-category.html" class="menu-item">题库分类</a><a href="/exam/question.html" class="menu-item">题目列表</a></div></div>
|
|
||||||
<a href="/exam/paper.html" class="menu-item"><i class="bi bi-file-earmark-text"></i><span>试卷管理</span></a>
|
|
||||||
<a href="/exam/list.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>考试管理</span></a>
|
|
||||||
<a href="/training/plan.html" class="menu-item active"><i class="bi bi-calendar-check"></i><span>培训计划</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>系统设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item"><a href="/training/plan.html">培训计划</a></li><li class="breadcrumb-item active" id="pageTitle">创建计划</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item"><a href="/training/plan.html">培训计划</a></li><li class="breadcrumb-item active" id="pageTitle">创建计划</li></ol></nav>
|
||||||
@@ -198,6 +185,8 @@
|
|||||||
let knowledgeModal, examModal;
|
let knowledgeModal, examModal;
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('training');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
knowledgeModal = new bootstrap.Modal(document.getElementById('knowledgeModal'));
|
knowledgeModal = new bootstrap.Modal(document.getElementById('knowledgeModal'));
|
||||||
examModal = new bootstrap.Modal(document.getElementById('examModal'));
|
examModal = new bootstrap.Modal(document.getElementById('examModal'));
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
|||||||
@@ -30,20 +30,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout-wrapper">
|
<div class="layout-wrapper">
|
||||||
<aside class="sidebar">
|
<div id="sidebarContainer"></div>
|
||||||
<div class="sidebar-logo"><div class="sidebar-logo-icon"><i class="bi bi-truck text-white"></i></div><span class="sidebar-logo-text">道路救援培训系统</span></div>
|
|
||||||
<nav class="sidebar-menu">
|
|
||||||
<a href="/index.html" class="menu-item"><i class="bi bi-grid-1x2"></i><span>工作台</span></a>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-people me-2"></i>人员管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/system/org.html" class="menu-item">组织架构</a><a href="/system/user.html" class="menu-item">员工管理</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-journal-richtext me-2"></i>知识库</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/knowledge/category.html" class="menu-item">知识分类</a><a href="/knowledge/list.html" class="menu-item">知识列表</a></div></div>
|
|
||||||
<div class="menu-group"><div class="menu-group-title"><span><i class="bi bi-pencil-square me-2"></i>考题管理</span><i class="bi bi-chevron-down arrow"></i></div><div class="menu-submenu"><a href="/exam/question-category.html" class="menu-item">题库分类</a><a href="/exam/question.html" class="menu-item">题目列表</a></div></div>
|
|
||||||
<a href="/exam/paper.html" class="menu-item"><i class="bi bi-file-earmark-text"></i><span>试卷管理</span></a>
|
|
||||||
<a href="/exam/list.html" class="menu-item"><i class="bi bi-clipboard-check"></i><span>考试管理</span></a>
|
|
||||||
<a href="/training/plan.html" class="menu-item active"><i class="bi bi-calendar-check"></i><span>培训计划</span></a>
|
|
||||||
<div style="border-top: 1px solid rgba(255,255,255,0.1); margin: 16px 0;"></div>
|
|
||||||
<a href="/system/setting.html" class="menu-item"><i class="bi bi-gear"></i><span>系统设置</span></a>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<header class="top-header">
|
<header class="top-header">
|
||||||
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item active">培训计划</li></ol></nav>
|
<nav aria-label="breadcrumb"><ol class="breadcrumb mb-0"><li class="breadcrumb-item"><a href="/index.html">首页</a></li><li class="breadcrumb-item active">培训计划</li></ol></nav>
|
||||||
@@ -90,6 +77,8 @@
|
|||||||
let currentPage = 1, pageSize = 10;
|
let currentPage = 1, pageSize = 10;
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
TrainingSystem.initSidebar('training');
|
||||||
|
TrainingSystem.initUserInfo();
|
||||||
loadList();
|
loadList();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user