优化功能,增加微信扫码登录

main
lj7788 2025-08-24 17:46:44 +08:00
parent f5fb4d910a
commit 249755b5ba
43 changed files with 2078 additions and 466 deletions

View File

@ -1,3 +1,47 @@
# yzexam
在线考试系统
## 功能特性
- 用户登录/注销
- 微信扫码登录
- 考试管理
- 题库管理
- 成绩统计
## 微信扫码登录配置
系统已集成微信扫码登录功能,用户可以通过微信扫描二维码的方式登录系统。
### 配置步骤
1. 在微信公众平台申请服务号并获取AppID和AppSecret
2. 在`exam-online-api/ruoyi-admin/src/main/resources/application.yml`中配置微信参数:
```yaml
wechat:
# 微信公众号AppId
app-id: your_wechat_appid
# 微信公众号AppSecret
app-secret: your_wechat_app_secret
# 授权回调地址
redirect-uri: http://your-domain.com/examapi/wechat/callback
```
3. 执行数据库脚本`doc/微信登录字段添加.sql`更新数据库表结构
### 使用说明
1. 访问系统登录页面
2. 点击"微信扫码登录"按钮
3. 使用微信扫描生成的二维码
4. 在微信中确认登录
5. 系统将自动跳转到主页
## 技术栈
- 后端Spring Boot + MyBatis + Spring Security
- 前端Vue.js + Element UI
- 数据库MySQL
- 微信集成Weixin Java SDK

View File

@ -1,303 +1,303 @@
-- 预置数据可以多次选中导入
-- 预置数据可以多次选中导入
-- ----------------------------
-- 初始化-部门表数据
-- 初始化-部门表数据
-- ----------------------------
insert into sys_dept(dept_id,parent_id,ancestors,dept_code,dept_name,order_num,leader,phone,email,status,del_flag,create_by,create_time) values (100,0,'0','5301001','测试用单位',0,'','13512345678','','0','0','admin',sysdate);
insert into sys_dept(dept_id,parent_id,ancestors,dept_code,dept_name,order_num,leader,phone,email,status,del_flag,create_by,create_time) values (100,0,'0','5301001','测试用单位',0,'','13512345678','','0','0','admin',sysdate);
-- ----------------------------
-- 初始化-用户信息表数据
-- 初始化-用户信息表数据
-- ----------------------------
insert into SYS_USER (user_id, user_code, dept_id, user_name, nick_name, user_type, email, phonenumber, sex, avatar, password, status, del_flag, login_ip, login_date, create_by, create_time, update_by, update_time, remark)
values (2, '40288b0186e867550186e867559d0000', 100, 'user1', '用户一', null, null, '13654128596', null, null, '$2a$10$aqSRTGVSqrZFwp.s5JXic.5JtZDYFq.19hriwW7seEdPGo6SJu3.W', '0', '0', '127.0.0.1', to_date('16-03-2023 11:16:56', 'dd-mm-yyyy hh24:mi:ss'), 'admin', to_date('16-03-2023 11:11:57', 'dd-mm-yyyy hh24:mi:ss'), null, to_date('16-03-2023 11:16:42', 'dd-mm-yyyy hh24:mi:ss'), null);
values (2, '40288b0186e867550186e867559d0000', 100, 'user1', '用户一', null, null, '13654128596', null, null, '$2a$10$aqSRTGVSqrZFwp.s5JXic.5JtZDYFq.19hriwW7seEdPGo6SJu3.W', '0', '0', '127.0.0.1', to_date('16-03-2023 11:16:56', 'dd-mm-yyyy hh24:mi:ss'), 'admin', to_date('16-03-2023 11:11:57', 'dd-mm-yyyy hh24:mi:ss'), null, to_date('16-03-2023 11:16:42', 'dd-mm-yyyy hh24:mi:ss'), null);
insert into SYS_USER (user_id, user_code, dept_id, user_name, nick_name, user_type, email, phonenumber, sex, avatar, password, status, del_flag, login_ip, login_date, create_by, create_time, update_by, update_time, remark)
values (3, '40288b0186e867550186e86911cc0001', 100, 'user2', '用户二', null, null, '13698568741', null, null, '$2a$10$Sh3WZ3ozH8Q88oG7mla.jerm3f3rCaq0QzD1KEPXXFrzcay0Hgz.S', '0', '0', null, null, 'admin', to_date('16-03-2023 11:13:51', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (3, '40288b0186e867550186e86911cc0001', 100, 'user2', '用户二', null, null, '13698568741', null, null, '$2a$10$Sh3WZ3ozH8Q88oG7mla.jerm3f3rCaq0QzD1KEPXXFrzcay0Hgz.S', '0', '0', null, null, 'admin', to_date('16-03-2023 11:13:51', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_USER (user_id, user_code, dept_id, user_name, nick_name, user_type, email, phonenumber, sex, avatar, password, status, del_flag, login_ip, login_date, create_by, create_time, update_by, update_time, remark)
values (1, 'F6FFFC4E3A50062DE0534479C80A75C1', 100, 'admin', '系统管理员', '00', 'abc@qq.com', '13512345678', '0', null, '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', to_date('16-03-2023 11:19:58', 'dd-mm-yyyy hh24:mi:ss'), 'admin', null, null, to_date('16-03-2023 11:19:44', 'dd-mm-yyyy hh24:mi:ss'), null);
values (1, 'F6FFFC4E3A50062DE0534479C80A75C1', 100, 'admin', '系统管理员', '00', 'abc@qq.com', '13512345678', '0', null, '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', to_date('16-03-2023 11:19:58', 'dd-mm-yyyy hh24:mi:ss'), 'admin', null, null, to_date('16-03-2023 11:19:44', 'dd-mm-yyyy hh24:mi:ss'), null);
-- 初始化-岗位信息表数据
-- 初始化-岗位信息表数据
-- ----------------------------
insert into sys_post (post_id,post_code,post_name,post_sort,status,del_flag,create_by,create_time) values(1, 'ceo', '董事长', 1, '0', '0','admin', sysdate);
insert into sys_post (post_id,post_code,post_name,post_sort,status,del_flag,create_by,create_time) values(1, 'ceo', '董事长', 1, '0', '0','admin', sysdate);
-- ----------------------------
-- 初始化-角色信息表数据
-- 初始化-角色信息表数据
-- ----------------------------
insert into SYS_ROLE (role_id, role_name, role_key, role_sort, data_scope, menu_check_strictly, dept_check_strictly, status, del_flag, create_by, create_time, update_by, update_time, remark)
values (2, '学员', 'student', 2, null, 1, 1, '0', '0', 'admin', to_date('16-03-2023 11:01:28', 'dd-mm-yyyy hh24:mi:ss'), 'admin', to_date('16-03-2023 11:16:25', 'dd-mm-yyyy hh24:mi:ss'), null);
values (2, '学员', 'student', 2, null, 1, 1, '0', '0', 'admin', to_date('16-03-2023 11:01:28', 'dd-mm-yyyy hh24:mi:ss'), 'admin', to_date('16-03-2023 11:16:25', 'dd-mm-yyyy hh24:mi:ss'), null);
insert into SYS_ROLE (role_id, role_name, role_key, role_sort, data_scope, menu_check_strictly, dept_check_strictly, status, del_flag, create_by, create_time, update_by, update_time, remark)
values (1, '超级管理员', 'admin', 1, '1', 1, 1, '0', '0', 'admin', to_date('16-03-2023 10:31:19', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1, '超级管理员', 'admin', 1, '1', 1, 1, '0', '0', 'admin', to_date('16-03-2023 10:31:19', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
commit;
-- ----------------------------
-- 初始化-菜单信息表数据
-- 初始化-菜单信息表数据
-- ----------------------------
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1, '系统管理', 0, 1, 'system', null, 1, 0, 'M', '0', '0', '0', null, 'system', 'admin', null, null, null, '系统管理目录');
values (1, '系统管理', 0, 1, 'system', null, 1, 0, 'M', '0', '0', '0', null, 'system', 'admin', null, null, null, '系统管理目录');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (2, '系统监控', 0, 3, 'monitor', null, 1, 0, 'M', '0', '0', '0', null, 'monitor', 'admin', null, null, null, '系统监控目录');
values (2, '系统监控', 0, 3, 'monitor', null, 1, 0, 'M', '0', '0', '0', null, 'monitor', 'admin', null, null, null, '系统监控目录');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (3, '系统工具', 0, 4, 'tool', null, 1, 0, 'M', '0', '0', '0', null, 'tool', 'admin', null, null, null, '系统工具目录');
values (3, '系统工具', 0, 4, 'tool', null, 1, 0, 'M', '0', '0', '0', null, 'tool', 'admin', null, null, null, '系统工具目录');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (8, '资料管理', 0, 8, 'fms', null, 1, 0, 'M', '0', '0', '0', null, 'files', 'admin', null, null, null, '文件管理目录');
values (8, '资料管理', 0, 8, 'fms', null, 1, 0, 'M', '0', '0', '0', null, 'files', 'admin', null, null, null, '文件管理目录');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (9, '试题管理', 0, 9, 'questions', null, 1, 0, 'M', '0', '0', '0', null, 'questions', 'admin', null, null, null, '试题管理目录');
values (9, '试题管理', 0, 9, 'questions', null, 1, 0, 'M', '0', '0', '0', null, 'questions', 'admin', null, null, null, '试题管理目录');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (10, '考试管理', 0, 10, 'exammanager', null, 1, 0, 'M', '0', '0', '0', null, 'exammanager', 'admin', null, null, null, '考试管理目录');
values (10, '考试管理', 0, 10, 'exammanager', null, 1, 0, 'M', '0', '0', '0', null, 'exammanager', 'admin', null, null, null, '考试管理目录');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (11, '在线考试', 0, 11, 'onlineexam', null, 1, 0, 'M', '0', '0', '0', null, 'onlineexam', 'admin', null, null, null, '在线考试目录');
values (11, '在线考试', 0, 11, 'onlineexam', null, 1, 0, 'M', '0', '0', '0', null, 'onlineexam', 'admin', null, null, null, '在线考试目录');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (100, '用户管理', 1, 1, 'user', 'system/user/index', 1, 0, 'C', '0', '0', '0', 'system:user:list', 'user', 'admin', null, null, null, '用户管理菜单');
values (100, '用户管理', 1, 1, 'user', 'system/user/index', 1, 0, 'C', '0', '0', '0', 'system:user:list', 'user', 'admin', null, null, null, '用户管理菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (101, '角色管理', 1, 2, 'role', 'system/role/index', 1, 0, 'C', '0', '0', '0', 'system:role:list', 'peoples', 'admin', null, null, null, '角色管理菜单');
values (101, '角色管理', 1, 2, 'role', 'system/role/index', 1, 0, 'C', '0', '0', '0', 'system:role:list', 'peoples', 'admin', null, null, null, '角色管理菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (102, '菜单管理', 1, 3, 'menu', 'system/menu/index', 1, 0, 'C', '0', '0', '0', 'system:menu:list', 'tree-table', 'admin', null, null, null, '菜单管理菜单');
values (102, '菜单管理', 1, 3, 'menu', 'system/menu/index', 1, 0, 'C', '0', '0', '0', 'system:menu:list', 'tree-table', 'admin', null, null, null, '菜单管理菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (103, '部门管理', 1, 4, 'dept', 'system/dept/index', 1, 0, 'C', '0', '0', '0', 'system:dept:list', 'tree', 'admin', null, null, null, '部门管理菜单');
values (103, '部门管理', 1, 4, 'dept', 'system/dept/index', 1, 0, 'C', '0', '0', '0', 'system:dept:list', 'tree', 'admin', null, null, null, '部门管理菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (104, '岗位管理', 1, 5, 'post', 'system/post/index', 1, 0, 'C', '0', '0', '0', 'system:post:list', 'post', 'admin', null, null, null, '岗位管理菜单');
values (104, '岗位管理', 1, 5, 'post', 'system/post/index', 1, 0, 'C', '0', '0', '0', 'system:post:list', 'post', 'admin', null, null, null, '岗位管理菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (105, '字典管理', 1, 6, 'dict', 'system/dict/index', 1, 0, 'C', '0', '0', '0', 'system:dict:list', 'dict', 'admin', null, null, null, '字典管理菜单');
values (105, '字典管理', 1, 6, 'dict', 'system/dict/index', 1, 0, 'C', '0', '0', '0', 'system:dict:list', 'dict', 'admin', null, null, null, '字典管理菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (106, '参数设置', 1, 7, 'config', 'system/config/index', 1, 0, 'C', '0', '0', '0', 'system:config:list', 'edit', 'admin', null, null, null, '参数设置菜单');
values (106, '参数设置', 1, 7, 'config', 'system/config/index', 1, 0, 'C', '0', '0', '0', 'system:config:list', 'edit', 'admin', null, null, null, '参数设置菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (107, '通知公告', 1, 8, 'notice', 'system/notice/index', 1, 0, 'C', '0', '0', '0', 'system:notice:list', 'message', 'admin', null, null, null, '通知公告菜单');
values (107, '通知公告', 1, 8, 'notice', 'system/notice/index', 1, 0, 'C', '0', '0', '0', 'system:notice:list', 'message', 'admin', null, null, null, '通知公告菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (108, '日志管理', 1, 9, 'log', null, 1, 0, 'M', '0', '0', '0', null, 'log', 'admin', null, null, null, '日志管理菜单');
values (108, '日志管理', 1, 9, 'log', null, 1, 0, 'M', '0', '0', '0', null, 'log', 'admin', null, null, null, '日志管理菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (109, '在线用户', 2, 1, 'online', 'monitor/online/index', 1, 0, 'C', '0', '0', '0', 'monitor:online:list', 'online', 'admin', null, null, null, '在线用户菜单');
values (109, '在线用户', 2, 1, 'online', 'monitor/online/index', 1, 0, 'C', '0', '0', '0', 'monitor:online:list', 'online', 'admin', null, null, null, '在线用户菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (110, '定时任务', 2, 2, 'job', 'monitor/job/index', 1, 0, 'C', '0', '0', '0', 'monitor:job:list', 'job', 'admin', null, null, null, '定时任务菜单');
values (110, '定时任务', 2, 2, 'job', 'monitor/job/index', 1, 0, 'C', '0', '0', '0', 'monitor:job:list', 'job', 'admin', null, null, null, '定时任务菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (111, '数据监控', 2, 3, 'druid', 'monitor/druid/index', 1, 0, 'C', '0', '0', '0', 'monitor:druid:list', 'druid', 'admin', null, null, null, '数据监控菜单');
values (111, '数据监控', 2, 3, 'druid', 'monitor/druid/index', 1, 0, 'C', '0', '0', '0', 'monitor:druid:list', 'druid', 'admin', null, null, null, '数据监控菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (112, '服务监控', 2, 4, 'server', 'monitor/server/index', 1, 0, 'C', '0', '0', '0', 'monitor:server:list', 'server', 'admin', null, null, null, '服务监控菜单');
values (112, '服务监控', 2, 4, 'server', 'monitor/server/index', 1, 0, 'C', '0', '0', '0', 'monitor:server:list', 'server', 'admin', null, null, null, '服务监控菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (113, '缓存监控', 2, 5, 'cache', 'monitor/cache/index', 1, 0, 'C', '0', '0', '0', 'monitor:cache:list', 'redis', 'admin', null, null, null, '缓存监控菜单');
values (113, '缓存监控', 2, 5, 'cache', 'monitor/cache/index', 1, 0, 'C', '0', '0', '0', 'monitor:cache:list', 'redis', 'admin', null, null, null, '缓存监控菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (114, '表单构建', 3, 1, 'build', 'tool/build/index', 1, 0, 'C', '0', '0', '0', 'tool:build:list', 'build', 'admin', null, null, null, '表单构建菜单');
values (114, '表单构建', 3, 1, 'build', 'tool/build/index', 1, 0, 'C', '0', '0', '0', 'tool:build:list', 'build', 'admin', null, null, null, '表单构建菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (115, '代码生成', 3, 2, 'gen', 'tool/gen/index', 1, 0, 'C', '0', '0', '0', 'tool:gen:list', 'code', 'admin', null, null, null, '代码生成菜单');
values (115, '代码生成', 3, 2, 'gen', 'tool/gen/index', 1, 0, 'C', '0', '0', '0', 'tool:gen:list', 'code', 'admin', null, null, null, '代码生成菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (116, '系统接口', 3, 3, 'swagger', 'tool/swagger/index', 1, 0, 'C', '0', '0', '0', 'tool:swagger:list', 'swagger', 'admin', null, null, null, '系统接口菜单');
values (116, '系统接口', 3, 3, 'swagger', 'tool/swagger/index', 1, 0, 'C', '0', '0', '0', 'tool:swagger:list', 'swagger', 'admin', null, null, null, '系统接口菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (121, '人员分组', 1, 11, 'group', 'system/group/index', 1, 0, 'C', '0', '0', null, 'system:group:list', 'group', 'admin', to_date('28-01-2023 19:40:40', 'dd-mm-yyyy hh24:mi:ss'), null, null, '人员分组菜单');
values (121, '人员分组', 1, 11, 'group', 'system/group/index', 1, 0, 'C', '0', '0', null, 'system:group:list', 'group', 'admin', to_date('28-01-2023 19:40:40', 'dd-mm-yyyy hh24:mi:ss'), null, null, '人员分组菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (220, '操作日志', 108, 1, 'operlog', 'monitor/operlog/index', 1, 0, 'C', '0', '0', '0', 'monitor:operlog:list', 'form', 'admin', null, null, null, '操作日志菜单');
values (220, '操作日志', 108, 1, 'operlog', 'monitor/operlog/index', 1, 0, 'C', '0', '0', '0', 'monitor:operlog:list', 'form', 'admin', null, null, null, '操作日志菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (230, '登录日志', 108, 2, 'logininfor', 'monitor/logininfor/index', 1, 0, 'C', '0', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', null, null, null, '登录日志菜单');
values (230, '登录日志', 108, 2, 'logininfor', 'monitor/logininfor/index', 1, 0, 'C', '0', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', null, null, null, '登录日志菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (300, '图片管理', 8, 1, 'photo', 'fms/photo/index', 1, 0, 'C', '0', '0', null, 'fms:photo:list', 'photo', 'admin', to_date('14-12-2021 15:24:20', 'dd-mm-yyyy hh24:mi:ss'), null, null, '图片管理菜单');
values (300, '图片管理', 8, 1, 'photo', 'fms/photo/index', 1, 0, 'C', '0', '0', null, 'fms:photo:list', 'photo', 'admin', to_date('14-12-2021 15:24:20', 'dd-mm-yyyy hh24:mi:ss'), null, null, '图片管理菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (305, '文件管理', 8, 1, 'files', 'fms/files/index', 1, 0, 'C', '0', '0', null, 'fms:files:list', 'film', 'admin', to_date('17-12-2021 23:15:50', 'dd-mm-yyyy hh24:mi:ss'), null, null, '文件管理菜单');
values (305, '文件管理', 8, 1, 'files', 'fms/files/index', 1, 0, 'C', '0', '0', null, 'fms:files:list', 'film', 'admin', to_date('17-12-2021 23:15:50', 'dd-mm-yyyy hh24:mi:ss'), null, null, '文件管理菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (320, '题库分类', 9, 1, 'examtype', 'questions/examtype/index', 1, 0, 'C', '0', '0', null, 'questions:examtype:list', 'examtype', 'admin', to_date('14-12-2022 14:28:22', 'dd-mm-yyyy hh24:mi:ss'), null, null, '考试分类菜单');
values (320, '题库分类', 9, 1, 'examtype', 'questions/examtype/index', 1, 0, 'C', '0', '0', null, 'questions:examtype:list', 'examtype', 'admin', to_date('14-12-2022 14:28:22', 'dd-mm-yyyy hh24:mi:ss'), null, null, '考试分类菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (325, '题库设置', 9, 2, 'questionsbank', 'questions/questionsbank/index', 1, 0, 'C', '0', '0', null, 'questions:questionsbank:list', 'questionsbank', 'admin', to_date('19-12-2022 14:10:57', 'dd-mm-yyyy hh24:mi:ss'), null, null, '题库管理菜单');
values (325, '题库设置', 9, 2, 'questionsbank', 'questions/questionsbank/index', 1, 0, 'C', '0', '0', null, 'questions:questionsbank:list', 'questionsbank', 'admin', to_date('19-12-2022 14:10:57', 'dd-mm-yyyy hh24:mi:ss'), null, null, '题库管理菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (330, '考试题目管理', 9, 5, 'examquestions', 'questions/examquestions/index', 1, 0, 'C', '0', '0', null, 'questions:examquestions:list', 'examquestions', 'admin', to_date('27-12-2022 20:08:00', 'dd-mm-yyyy hh24:mi:ss'), null, null, '考试题目管理菜单');
values (330, '考试题目管理', 9, 5, 'examquestions', 'questions/examquestions/index', 1, 0, 'C', '0', '0', null, 'questions:examquestions:list', 'examquestions', 'admin', to_date('27-12-2022 20:08:00', 'dd-mm-yyyy hh24:mi:ss'), null, null, '考试题目管理菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (350, '创建考试', 10, 1, 'examtask', 'exam/examtask/index', 1, 0, 'C', '0', '0', null, 'exam:examtask:list', 'examtask', 'admin', to_date('06-01-2023 13:53:00', 'dd-mm-yyyy hh24:mi:ss'), null, null, '创建考试菜单');
values (350, '创建考试', 10, 1, 'examtask', 'exam/examtask/index', 1, 0, 'C', '0', '0', null, 'exam:examtask:list', 'examtask', 'admin', to_date('06-01-2023 13:53:00', 'dd-mm-yyyy hh24:mi:ss'), null, null, '创建考试菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (360, '开始考试', 11, 1, 'examstart', 'onlineexam/examstart/index', 1, 0, 'C', '0', '0', null, 'onlineexam:data:list', 'examstart', 'admin', to_date('06-01-2023 13:53:00', 'dd-mm-yyyy hh24:mi:ss'), null, null, '开始考试菜单');
values (360, '开始考试', 11, 1, 'examstart', 'onlineexam/examstart/index', 1, 0, 'C', '0', '0', null, 'onlineexam:data:list', 'examstart', 'admin', to_date('06-01-2023 13:53:00', 'dd-mm-yyyy hh24:mi:ss'), null, null, '开始考试菜单');
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1001, '用户查询', 100, 1, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:query', '#', 'admin', null, null, null, null);
values (1001, '用户查询', 100, 1, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:query', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1002, '用户新增', 100, 2, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:add', '#', 'admin', null, null, null, null);
values (1002, '用户新增', 100, 2, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:add', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1003, '用户修改', 100, 3, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:edit', '#', 'admin', null, null, null, null);
values (1003, '用户修改', 100, 3, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:edit', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1004, '用户删除', 100, 4, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:remove', '#', 'admin', null, null, null, null);
values (1004, '用户删除', 100, 4, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:remove', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1005, '用户导出', 100, 5, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:export', '#', 'admin', null, null, null, null);
values (1005, '用户导出', 100, 5, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:export', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1006, '用户导入', 100, 6, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:import', '#', 'admin', null, null, null, null);
values (1006, '用户导入', 100, 6, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:import', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1007, '重置密码', 100, 7, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:resetPwd', '#', 'admin', null, null, null, null);
values (1007, '重置密码', 100, 7, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:resetPwd', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1008, '角色查询', 101, 1, null, null, 1, 0, 'F', '0', '0', '0', 'system:role:query', '#', 'admin', null, null, null, null);
values (1008, '角色查询', 101, 1, null, null, 1, 0, 'F', '0', '0', '0', 'system:role:query', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1009, '角色新增', 101, 2, null, null, 1, 0, 'F', '0', '0', '0', 'system:role:add', '#', 'admin', null, null, null, null);
values (1009, '角色新增', 101, 2, null, null, 1, 0, 'F', '0', '0', '0', 'system:role:add', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1010, '角色修改', 101, 3, null, null, 1, 0, 'F', '0', '0', '0', 'system:role:edit', '#', 'admin', null, null, null, null);
values (1010, '角色修改', 101, 3, null, null, 1, 0, 'F', '0', '0', '0', 'system:role:edit', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1011, '角色删除', 101, 4, null, null, 1, 0, 'F', '0', '0', '0', 'system:role:remove', '#', 'admin', null, null, null, null);
values (1011, '角色删除', 101, 4, null, null, 1, 0, 'F', '0', '0', '0', 'system:role:remove', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1012, '角色导出', 101, 5, null, null, 1, 0, 'F', '0', '0', '0', 'system:role:export', '#', 'admin', null, null, null, null);
values (1012, '角色导出', 101, 5, null, null, 1, 0, 'F', '0', '0', '0', 'system:role:export', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1013, '菜单查询', 102, 1, null, null, 1, 0, 'F', '0', '0', '0', 'system:menu:query', '#', 'admin', null, null, null, null);
values (1013, '菜单查询', 102, 1, null, null, 1, 0, 'F', '0', '0', '0', 'system:menu:query', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1014, '菜单新增', 102, 2, null, null, 1, 0, 'F', '0', '0', '0', 'system:menu:add', '#', 'admin', null, null, null, null);
values (1014, '菜单新增', 102, 2, null, null, 1, 0, 'F', '0', '0', '0', 'system:menu:add', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1015, '菜单修改', 102, 3, null, null, 1, 0, 'F', '0', '0', '0', 'system:menu:edit', '#', 'admin', null, null, null, null);
values (1015, '菜单修改', 102, 3, null, null, 1, 0, 'F', '0', '0', '0', 'system:menu:edit', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1016, '菜单删除', 102, 4, null, null, 1, 0, 'F', '0', '0', '0', 'system:menu:remove', '#', 'admin', null, null, null, null);
values (1016, '菜单删除', 102, 4, null, null, 1, 0, 'F', '0', '0', '0', 'system:menu:remove', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1017, '部门查询', 103, 1, null, null, 1, 0, 'F', '0', '0', '0', 'system:dept:query', '#', 'admin', null, null, null, null);
values (1017, '部门查询', 103, 1, null, null, 1, 0, 'F', '0', '0', '0', 'system:dept:query', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1018, '部门新增', 103, 2, null, null, 1, 0, 'F', '0', '0', '0', 'system:dept:add', '#', 'admin', null, null, null, null);
values (1018, '部门新增', 103, 2, null, null, 1, 0, 'F', '0', '0', '0', 'system:dept:add', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1019, '部门修改', 103, 3, null, null, 1, 0, 'F', '0', '0', '0', 'system:dept:edit', '#', 'admin', null, null, null, null);
values (1019, '部门修改', 103, 3, null, null, 1, 0, 'F', '0', '0', '0', 'system:dept:edit', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1020, '部门删除', 103, 4, null, null, 1, 0, 'F', '0', '0', '0', 'system:dept:remove', '#', 'admin', null, null, null, null);
values (1020, '部门删除', 103, 4, null, null, 1, 0, 'F', '0', '0', '0', 'system:dept:remove', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1021, '岗位查询', 104, 1, null, null, 1, 0, 'F', '0', '0', '0', 'system:post:query', '#', 'admin', null, null, null, null);
values (1021, '岗位查询', 104, 1, null, null, 1, 0, 'F', '0', '0', '0', 'system:post:query', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1022, '岗位新增', 104, 2, null, null, 1, 0, 'F', '0', '0', '0', 'system:post:add', '#', 'admin', null, null, null, null);
values (1022, '岗位新增', 104, 2, null, null, 1, 0, 'F', '0', '0', '0', 'system:post:add', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1023, '岗位修改', 104, 3, null, null, 1, 0, 'F', '0', '0', '0', 'system:post:edit', '#', 'admin', null, null, null, null);
values (1023, '岗位修改', 104, 3, null, null, 1, 0, 'F', '0', '0', '0', 'system:post:edit', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1024, '岗位删除', 104, 4, null, null, 1, 0, 'F', '0', '0', '0', 'system:post:remove', '#', 'admin', null, null, null, null);
values (1024, '岗位删除', 104, 4, null, null, 1, 0, 'F', '0', '0', '0', 'system:post:remove', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1025, '岗位导出', 104, 5, null, null, 1, 0, 'F', '0', '0', '0', 'system:post:export', '#', 'admin', null, null, null, null);
values (1025, '岗位导出', 104, 5, null, null, 1, 0, 'F', '0', '0', '0', 'system:post:export', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1026, '字典查询', 105, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'system:dict:query', '#', 'admin', null, null, null, null);
values (1026, '字典查询', 105, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'system:dict:query', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1027, '字典新增', 105, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'system:dict:add', '#', 'admin', null, null, null, null);
values (1027, '字典新增', 105, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'system:dict:add', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1028, '字典修改', 105, 3, '#', null, 1, 0, 'F', '0', '0', '0', 'system:dict:edit', '#', 'admin', null, null, null, null);
values (1028, '字典修改', 105, 3, '#', null, 1, 0, 'F', '0', '0', '0', 'system:dict:edit', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1029, '字典删除', 105, 4, '#', null, 1, 0, 'F', '0', '0', '0', 'system:dict:remove', '#', 'admin', null, null, null, null);
values (1029, '字典删除', 105, 4, '#', null, 1, 0, 'F', '0', '0', '0', 'system:dict:remove', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1030, '字典导出', 105, 5, '#', null, 1, 0, 'F', '0', '0', '0', 'system:dict:export', '#', 'admin', null, null, null, null);
values (1030, '字典导出', 105, 5, '#', null, 1, 0, 'F', '0', '0', '0', 'system:dict:export', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1031, '参数查询', 106, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'system:config:query', '#', 'admin', null, null, null, null);
values (1031, '参数查询', 106, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'system:config:query', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1032, '参数新增', 106, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'system:config:add', '#', 'admin', null, null, null, null);
values (1032, '参数新增', 106, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'system:config:add', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1033, '参数修改', 106, 3, '#', null, 1, 0, 'F', '0', '0', '0', 'system:config:edit', '#', 'admin', null, null, null, null);
values (1033, '参数修改', 106, 3, '#', null, 1, 0, 'F', '0', '0', '0', 'system:config:edit', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1034, '参数删除', 106, 4, '#', null, 1, 0, 'F', '0', '0', '0', 'system:config:remove', '#', 'admin', null, null, null, null);
values (1034, '参数删除', 106, 4, '#', null, 1, 0, 'F', '0', '0', '0', 'system:config:remove', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1035, '参数导出', 106, 5, '#', null, 1, 0, 'F', '0', '0', '0', 'system:config:export', '#', 'admin', null, null, null, null);
values (1035, '参数导出', 106, 5, '#', null, 1, 0, 'F', '0', '0', '0', 'system:config:export', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1036, '公告查询', 107, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'system:notice:query', '#', 'admin', null, null, null, null);
values (1036, '公告查询', 107, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'system:notice:query', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1037, '公告新增', 107, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'system:notice:add', '#', 'admin', null, null, null, null);
values (1037, '公告新增', 107, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'system:notice:add', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1038, '公告修改', 107, 3, '#', null, 1, 0, 'F', '0', '0', '0', 'system:notice:edit', '#', 'admin', null, null, null, null);
values (1038, '公告修改', 107, 3, '#', null, 1, 0, 'F', '0', '0', '0', 'system:notice:edit', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1039, '公告删除', 107, 4, '#', null, 1, 0, 'F', '0', '0', '0', 'system:notice:remove', '#', 'admin', null, null, null, null);
values (1039, '公告删除', 107, 4, '#', null, 1, 0, 'F', '0', '0', '0', 'system:notice:remove', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1040, '操作查询', 220, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:operlog:query', '#', 'admin', null, null, null, null);
values (1040, '操作查询', 220, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:operlog:query', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1041, '操作删除', 220, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:operlog:remove', '#', 'admin', null, null, null, null);
values (1041, '操作删除', 220, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:operlog:remove', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1042, '日志导出', 220, 4, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:operlog:export', '#', 'admin', null, null, null, null);
values (1042, '日志导出', 220, 4, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:operlog:export', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1043, '登录查询', 230, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:logininfor:query', '#', 'admin', null, null, null, null);
values (1043, '登录查询', 230, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:logininfor:query', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1044, '登录删除', 230, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:logininfor:remove', '#', 'admin', null, null, null, null);
values (1044, '登录删除', 230, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:logininfor:remove', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1045, '日志导出', 230, 3, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:logininfor:export', '#', 'admin', null, null, null, null);
values (1045, '日志导出', 230, 3, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:logininfor:export', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1046, '在线查询', 109, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:online:query', '#', 'admin', null, null, null, null);
values (1046, '在线查询', 109, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:online:query', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1047, '批量强退', 109, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:online:batchLogout', '#', 'admin', null, null, null, null);
values (1047, '批量强退', 109, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:online:batchLogout', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1048, '单条强退', 109, 3, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:online:forceLogout', '#', 'admin', null, null, null, null);
values (1048, '单条强退', 109, 3, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:online:forceLogout', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1049, '任务查询', 110, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:job:query', '#', 'admin', null, null, null, null);
values (1049, '任务查询', 110, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:job:query', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1050, '任务新增', 110, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:job:add', '#', 'admin', null, null, null, null);
values (1050, '任务新增', 110, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:job:add', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1051, '任务修改', 110, 3, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:job:edit', '#', 'admin', null, null, null, null);
values (1051, '任务修改', 110, 3, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:job:edit', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1052, '任务删除', 110, 4, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:job:remove', '#', 'admin', null, null, null, null);
values (1052, '任务删除', 110, 4, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:job:remove', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1053, '状态修改', 110, 5, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:job:changeStatus', '#', 'admin', null, null, null, null);
values (1053, '状态修改', 110, 5, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:job:changeStatus', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1054, '任务导出', 110, 7, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:job:export', '#', 'admin', null, null, null, null);
values (1054, '任务导出', 110, 7, '#', null, 1, 0, 'F', '0', '0', '0', 'monitor:job:export', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1055, '生成查询', 115, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'tool:gen:query', '#', 'admin', null, null, null, null);
values (1055, '生成查询', 115, 1, '#', null, 1, 0, 'F', '0', '0', '0', 'tool:gen:query', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1056, '生成修改', 115, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'tool:gen:edit', '#', 'admin', null, null, null, null);
values (1056, '生成修改', 115, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'tool:gen:edit', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1057, '生成删除', 115, 3, '#', null, 1, 0, 'F', '0', '0', '0', 'tool:gen:remove', '#', 'admin', null, null, null, null);
values (1057, '生成删除', 115, 3, '#', null, 1, 0, 'F', '0', '0', '0', 'tool:gen:remove', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1058, '导入代码', 115, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'tool:gen:import', '#', 'admin', null, null, null, null);
values (1058, '导入代码', 115, 2, '#', null, 1, 0, 'F', '0', '0', '0', 'tool:gen:import', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1059, '预览代码', 115, 4, '#', null, 1, 0, 'F', '0', '0', '0', 'tool:gen:preview', '#', 'admin', null, null, null, null);
values (1059, '预览代码', 115, 4, '#', null, 1, 0, 'F', '0', '0', '0', 'tool:gen:preview', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1060, '生成代码', 115, 5, '#', null, 1, 0, 'F', '0', '0', '0', 'tool:gen:code', '#', 'admin', null, null, null, null);
values (1060, '生成代码', 115, 5, '#', null, 1, 0, 'F', '0', '0', '0', 'tool:gen:code', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1061, '部门导入', 103, 5, null, null, 1, 0, 'F', '0', '0', '0', 'system:dept:wechatin', '#', 'admin', null, null, null, null);
values (1061, '部门导入', 103, 5, null, null, 1, 0, 'F', '0', '0', '0', 'system:dept:wechatin', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1062, '用户导入', 100, 7, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:wechatin', '#', 'admin', null, null, null, null);
values (1062, '用户导入', 100, 7, null, null, 1, 0, 'F', '0', '0', '0', 'system:user:wechatin', '#', 'admin', null, null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1080, '人员分组查询', 121, 1, '#', null, 1, 0, 'F', '0', '0', null, 'system:group:query', '#', 'admin', to_date('28-01-2023 20:02:09', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1080, '人员分组查询', 121, 1, '#', null, 1, 0, 'F', '0', '0', null, 'system:group:query', '#', 'admin', to_date('28-01-2023 20:02:09', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1081, '人员分组新增', 121, 2, '#', null, 1, 0, 'F', '0', '0', null, 'system:group:add', '#', 'admin', to_date('28-01-2023 20:02:09', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1081, '人员分组新增', 121, 2, '#', null, 1, 0, 'F', '0', '0', null, 'system:group:add', '#', 'admin', to_date('28-01-2023 20:02:09', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1082, '人员分组修改', 121, 3, '#', null, 1, 0, 'F', '0', '0', null, 'system:group:edit', '#', 'admin', to_date('28-01-2023 20:02:09', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1082, '人员分组修改', 121, 3, '#', null, 1, 0, 'F', '0', '0', null, 'system:group:edit', '#', 'admin', to_date('28-01-2023 20:02:09', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1083, '人员分组删除', 121, 4, '#', null, 1, 0, 'F', '0', '0', null, 'system:group:remove', '#', 'admin', to_date('28-01-2023 20:02:10', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1083, '人员分组删除', 121, 4, '#', null, 1, 0, 'F', '0', '0', null, 'system:group:remove', '#', 'admin', to_date('28-01-2023 20:02:10', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1084, '人员分组导出', 121, 5, '#', null, 1, 0, 'F', '0', '0', null, 'system:group:export', '#', 'admin', to_date('28-01-2023 20:02:10', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1084, '人员分组导出', 121, 5, '#', null, 1, 0, 'F', '0', '0', null, 'system:group:export', '#', 'admin', to_date('28-01-2023 20:02:10', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1390, '图片管理查询', 300, 1, '#', null, 1, 0, 'F', '0', '0', null, 'fms:photo:query', '#', 'admin', to_date('14-12-2021 15:28:21', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1390, '图片管理查询', 300, 1, '#', null, 1, 0, 'F', '0', '0', null, 'fms:photo:query', '#', 'admin', to_date('14-12-2021 15:28:21', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1391, '图片管理新增', 300, 2, '#', null, 1, 0, 'F', '0', '0', null, 'fms:photo:add', '#', 'admin', to_date('14-12-2021 15:28:21', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1391, '图片管理新增', 300, 2, '#', null, 1, 0, 'F', '0', '0', null, 'fms:photo:add', '#', 'admin', to_date('14-12-2021 15:28:21', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1392, '图片管理修改', 300, 3, '#', null, 1, 0, 'F', '0', '0', null, 'fms:photo:edit', '#', 'admin', to_date('14-12-2021 15:28:21', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1392, '图片管理修改', 300, 3, '#', null, 1, 0, 'F', '0', '0', null, 'fms:photo:edit', '#', 'admin', to_date('14-12-2021 15:28:21', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1393, '图片管理删除', 300, 4, '#', null, 1, 0, 'F', '0', '0', null, 'fms:photo:remove', '#', 'admin', to_date('14-12-2021 15:28:21', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1393, '图片管理删除', 300, 4, '#', null, 1, 0, 'F', '0', '0', null, 'fms:photo:remove', '#', 'admin', to_date('14-12-2021 15:28:21', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1394, '图片管理下载', 300, 5, '#', null, 1, 0, 'F', '0', '0', null, 'fms:photo:export', '#', 'admin', to_date('14-12-2021 15:28:21', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1394, '图片管理下载', 300, 5, '#', null, 1, 0, 'F', '0', '0', null, 'fms:photo:export', '#', 'admin', to_date('14-12-2021 15:28:21', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1420, '文件管理查询', 305, 1, '#', null, 1, 0, 'F', '0', '0', null, 'fms:files:query', '#', 'admin', to_date('17-12-2021 23:18:56', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1420, '文件管理查询', 305, 1, '#', null, 1, 0, 'F', '0', '0', null, 'fms:files:query', '#', 'admin', to_date('17-12-2021 23:18:56', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1421, '文件管理新增', 305, 2, '#', null, 1, 0, 'F', '0', '0', null, 'fms:files:add', '#', 'admin', to_date('17-12-2021 23:18:56', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1421, '文件管理新增', 305, 2, '#', null, 1, 0, 'F', '0', '0', null, 'fms:files:add', '#', 'admin', to_date('17-12-2021 23:18:56', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1422, '文件管理修改', 305, 3, '#', null, 1, 0, 'F', '0', '0', null, 'fms:files:edit', '#', 'admin', to_date('17-12-2021 23:18:56', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1422, '文件管理修改', 305, 3, '#', null, 1, 0, 'F', '0', '0', null, 'fms:files:edit', '#', 'admin', to_date('17-12-2021 23:18:56', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1423, '文件管理删除', 305, 4, '#', null, 1, 0, 'F', '0', '0', null, 'fms:files:remove', '#', 'admin', to_date('17-12-2021 23:18:56', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1423, '文件管理删除', 305, 4, '#', null, 1, 0, 'F', '0', '0', null, 'fms:files:remove', '#', 'admin', to_date('17-12-2021 23:18:56', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1424, '文件管理下载', 305, 5, '#', null, 1, 0, 'F', '0', '0', null, 'fms:files:export', '#', 'admin', to_date('17-12-2021 23:18:57', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1424, '文件管理下载', 305, 5, '#', null, 1, 0, 'F', '0', '0', null, 'fms:files:export', '#', 'admin', to_date('17-12-2021 23:18:57', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1501, '考试分类查询', 320, 1, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examtype:query', '#', 'admin', to_date('14-12-2022 14:32:15', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1501, '考试分类查询', 320, 1, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examtype:query', '#', 'admin', to_date('14-12-2022 14:32:15', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1502, '考试分类新增', 320, 2, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examtype:add', '#', 'admin', to_date('14-12-2022 14:32:15', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1502, '考试分类新增', 320, 2, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examtype:add', '#', 'admin', to_date('14-12-2022 14:32:15', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1503, '考试分类修改', 320, 3, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examtype:edit', '#', 'admin', to_date('14-12-2022 14:32:15', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1503, '考试分类修改', 320, 3, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examtype:edit', '#', 'admin', to_date('14-12-2022 14:32:15', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1504, '考试分类删除', 320, 4, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examtype:remove', '#', 'admin', to_date('14-12-2022 14:32:16', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1504, '考试分类删除', 320, 4, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examtype:remove', '#', 'admin', to_date('14-12-2022 14:32:16', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1505, '考试分类导出', 320, 5, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examtype:export', '#', 'admin', to_date('14-12-2022 14:32:16', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1505, '考试分类导出', 320, 5, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examtype:export', '#', 'admin', to_date('14-12-2022 14:32:16', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1525, '题库管理查询', 325, 1, '#', null, 1, 0, 'F', '0', '0', null, 'questions:questionsbank:query', '#', 'admin', to_date('19-12-2022 14:10:57', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1525, '题库管理查询', 325, 1, '#', null, 1, 0, 'F', '0', '0', null, 'questions:questionsbank:query', '#', 'admin', to_date('19-12-2022 14:10:57', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1526, '题库管理新增', 325, 2, '#', null, 1, 0, 'F', '0', '0', null, 'questions:questionsbank:add', '#', 'admin', to_date('19-12-2022 14:10:57', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1526, '题库管理新增', 325, 2, '#', null, 1, 0, 'F', '0', '0', null, 'questions:questionsbank:add', '#', 'admin', to_date('19-12-2022 14:10:57', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1527, '题库管理修改', 325, 3, '#', null, 1, 0, 'F', '0', '0', null, 'questions:questionsbank:edit', '#', 'admin', to_date('19-12-2022 14:10:58', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1527, '题库管理修改', 325, 3, '#', null, 1, 0, 'F', '0', '0', null, 'questions:questionsbank:edit', '#', 'admin', to_date('19-12-2022 14:10:58', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1528, '题库管理删除', 325, 4, '#', null, 1, 0, 'F', '0', '0', null, 'questions:questionsbank:remove', '#', 'admin', to_date('19-12-2022 14:10:58', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1528, '题库管理删除', 325, 4, '#', null, 1, 0, 'F', '0', '0', null, 'questions:questionsbank:remove', '#', 'admin', to_date('19-12-2022 14:10:58', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1529, '题库管理导出', 325, 5, '#', null, 1, 0, 'F', '0', '0', null, 'questions:questionsbank:export', '#', 'admin', to_date('19-12-2022 14:10:58', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1529, '题库管理导出', 325, 5, '#', null, 1, 0, 'F', '0', '0', null, 'questions:questionsbank:export', '#', 'admin', to_date('19-12-2022 14:10:58', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1541, '考试题目查询', 330, 1, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examquestions:query', '#', 'admin', to_date('27-12-2022 20:10:55', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1541, '考试题目查询', 330, 1, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examquestions:query', '#', 'admin', to_date('27-12-2022 20:10:55', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1542, '考试题目新增', 330, 2, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examquestions:add', '#', 'admin', to_date('27-12-2022 20:10:55', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1542, '考试题目新增', 330, 2, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examquestions:add', '#', 'admin', to_date('27-12-2022 20:10:55', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1543, '考试题目修改', 330, 3, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examquestions:edit', '#', 'admin', to_date('27-12-2022 20:10:56', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1543, '考试题目修改', 330, 3, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examquestions:edit', '#', 'admin', to_date('27-12-2022 20:10:56', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1544, '考试题目删除', 330, 4, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examquestions:remove', '#', 'admin', to_date('27-12-2022 20:10:56', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1544, '考试题目删除', 330, 4, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examquestions:remove', '#', 'admin', to_date('27-12-2022 20:10:56', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1545, '考试题目导出', 330, 5, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examquestions:export', '#', 'admin', to_date('27-12-2022 20:10:56', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1545, '考试题目导出', 330, 5, '#', null, 1, 0, 'F', '0', '0', null, 'questions:examquestions:export', '#', 'admin', to_date('27-12-2022 20:10:56', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1601, '创建考试查询', 350, 1, '#', null, 1, 0, 'F', '0', '0', null, 'exam:examtask:query', '#', 'admin', to_date('06-01-2023 13:56:00', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1601, '创建考试查询', 350, 1, '#', null, 1, 0, 'F', '0', '0', null, 'exam:examtask:query', '#', 'admin', to_date('06-01-2023 13:56:00', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1602, '创建考试新增', 350, 2, '#', null, 1, 0, 'F', '0', '0', null, 'exam:examtask:add', '#', 'admin', to_date('06-01-2023 13:56:01', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1602, '创建考试新增', 350, 2, '#', null, 1, 0, 'F', '0', '0', null, 'exam:examtask:add', '#', 'admin', to_date('06-01-2023 13:56:01', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1603, '创建考试修改', 350, 3, '#', null, 1, 0, 'F', '0', '0', null, 'exam:examtask:edit', '#', 'admin', to_date('06-01-2023 13:56:01', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1603, '创建考试修改', 350, 3, '#', null, 1, 0, 'F', '0', '0', null, 'exam:examtask:edit', '#', 'admin', to_date('06-01-2023 13:56:01', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1604, '创建考试删除', 350, 4, '#', null, 1, 0, 'F', '0', '0', null, 'exam:examtask:remove', '#', 'admin', to_date('06-01-2023 13:56:01', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1604, '创建考试删除', 350, 4, '#', null, 1, 0, 'F', '0', '0', null, 'exam:examtask:remove', '#', 'admin', to_date('06-01-2023 13:56:01', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
insert into SYS_MENU (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, del_flag, perms, icon, create_by, create_time, update_by, update_time, remark)
values (1605, '创建考试导出', 350, 5, '#', null, 1, 0, 'F', '0', '0', null, 'exam:examtask:export', '#', 'admin', to_date('06-01-2023 13:56:01', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
values (1605, '创建考试导出', 350, 5, '#', null, 1, 0, 'F', '0', '0', null, 'exam:examtask:export', '#', 'admin', to_date('06-01-2023 13:56:01', 'dd-mm-yyyy hh24:mi:ss'), null, null, null);
commit;
-- ----------------------------
-- 初始化-用户和角色关联表数据
-- 初始化-用户和角色关联表数据
-- ----------------------------
insert into SYS_USER_ROLE (user_id, role_id)
values (1, 1);
@ -307,7 +307,7 @@ insert into SYS_USER_ROLE (user_id, role_id)
values (3, 2);
-- ----------------------------
-- 初始化-角色和菜单关联表数据
-- 初始化-角色和菜单关联表数据
-- ----------------------------
insert into sys_role_menu values ('2', '1');
insert into sys_role_menu values ('2', '2');
@ -395,76 +395,76 @@ insert into sys_role_menu values ('2', '1059');
insert into sys_role_menu values ('2', '1060');
-- ----------------------------
-- 初始化-角色和部门关联表数据
-- 初始化-角色和部门关联表数据
-- ----------------------------
insert into sys_role_dept values ('2', '100');
insert into sys_role_dept values ('2', '101');
insert into sys_role_dept values ('2', '105');
-- ----------------------------
-- 初始化-用户与岗位关联表数据
-- 初始化-用户与岗位关联表数据
-- ----------------------------
insert into sys_user_post values ('1', '1');
insert into sys_user_post values ('2', '2');
-- ----------------------------
-- 初始化-字典类型表
-- 初始化-字典类型表
-- ----------------------------
insert into sys_dict_type values(1, '用户性别', 'sys_user_sex', '0', 'admin', sysdate, '', null, '用户性别列表');
insert into sys_dict_type values(2, '菜单状态', 'sys_show_hide', '0', 'admin', sysdate, '', null, '菜单状态列表');
insert into sys_dict_type values(3, '系统开关', 'sys_normal_disable', '0', 'admin', sysdate, '', null, '系统开关列表');
insert into sys_dict_type values(4, '任务状态', 'sys_job_status', '0', 'admin', sysdate, '', null, '任务状态列表');
insert into sys_dict_type values(5, '任务分组', 'sys_job_group', '0', 'admin', sysdate, '', null, '任务分组列表');
insert into sys_dict_type values(6, '系统是否', 'sys_yes_no', '0', 'admin', sysdate, '', null, '系统是否列表');
insert into sys_dict_type values(7, '通知类型', 'sys_notice_type', '0', 'admin', sysdate, '', null, '通知类型列表');
insert into sys_dict_type values(8, '通知状态', 'sys_notice_status', '0', 'admin', sysdate, '', null, '通知状态列表');
insert into sys_dict_type values(9, '操作类型', 'sys_oper_type', '0', 'admin', sysdate, '', null, '操作类型列表');
insert into sys_dict_type values(10, '系统状态', 'sys_common_status', '0', 'admin', sysdate, '', null, '登录状态列表');
insert into sys_dict_type values(1, '用户性别', 'sys_user_sex', '0', 'admin', sysdate, '', null, '用户性别列表');
insert into sys_dict_type values(2, '菜单状态', 'sys_show_hide', '0', 'admin', sysdate, '', null, '菜单状态列表');
insert into sys_dict_type values(3, '系统开关', 'sys_normal_disable', '0', 'admin', sysdate, '', null, '系统开关列表');
insert into sys_dict_type values(4, '任务状态', 'sys_job_status', '0', 'admin', sysdate, '', null, '任务状态列表');
insert into sys_dict_type values(5, '任务分组', 'sys_job_group', '0', 'admin', sysdate, '', null, '任务分组列表');
insert into sys_dict_type values(6, '系统是否', 'sys_yes_no', '0', 'admin', sysdate, '', null, '系统是否列表');
insert into sys_dict_type values(7, '通知类型', 'sys_notice_type', '0', 'admin', sysdate, '', null, '通知类型列表');
insert into sys_dict_type values(8, '通知状态', 'sys_notice_status', '0', 'admin', sysdate, '', null, '通知状态列表');
insert into sys_dict_type values(9, '操作类型', 'sys_oper_type', '0', 'admin', sysdate, '', null, '操作类型列表');
insert into sys_dict_type values(10, '系统状态', 'sys_common_status', '0', 'admin', sysdate, '', null, '登录状态列表');
-- ----------------------------
-- 初始化-字典数据表
-- 初始化-字典数据表
-- ----------------------------
insert into sys_dict_data values(1, 1, '', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', sysdate, '', null, '性别男');
insert into sys_dict_data values(2, 2, '', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate, '', null, '性别女');
insert into sys_dict_data values(3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate, '', null, '性别未知');
insert into sys_dict_data values(4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', sysdate, '', null, '显示菜单');
insert into sys_dict_data values(5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '隐藏菜单');
insert into sys_dict_data values(6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', sysdate, '', null, '正常状态');
insert into sys_dict_data values(7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '停用状态');
insert into sys_dict_data values(8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', sysdate, '', null, '正常状态');
insert into sys_dict_data values(9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '停用状态');
insert into sys_dict_data values(10, 1, '默认', 'DEFAULT', 'sys_job_group', '', '', 'Y', '0', 'admin', sysdate, '', null, '默认分组');
insert into sys_dict_data values(11, 2, '系统', 'SYSTEM', 'sys_job_group', '', '', 'N', '0', 'admin', sysdate, '', null, '系统分组');
insert into sys_dict_data values(12, 1, '', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', sysdate, '', null, '系统默认是');
insert into sys_dict_data values(13, 2, '', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '系统默认否');
insert into sys_dict_data values(14, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', sysdate, '', null, '通知');
insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', sysdate, '', null, '公告');
insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', sysdate, '', null, '正常状态');
insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '关闭状态');
insert into sys_dict_data values(18, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate, '', null, '新增操作');
insert into sys_dict_data values(19, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate, '', null, '修改操作');
insert into sys_dict_data values(20, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '删除操作');
insert into sys_dict_data values(21, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', sysdate, '', null, '授权操作');
insert into sys_dict_data values(22, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate, '', null, '导出操作');
insert into sys_dict_data values(23, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate, '', null, '导入操作');
insert into sys_dict_data values(24, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '强退操作');
insert into sys_dict_data values(25, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate, '', null, '生成操作');
insert into sys_dict_data values(26, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '清空操作');
insert into sys_dict_data values(27, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', sysdate, '', null, '正常状态');
insert into sys_dict_data values(28, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '停用状态');
insert into sys_dict_data values(1, 1, '', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', sysdate, '', null, '性别男');
insert into sys_dict_data values(2, 2, '', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate, '', null, '性别女');
insert into sys_dict_data values(3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate, '', null, '性别未知');
insert into sys_dict_data values(4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', sysdate, '', null, '显示菜单');
insert into sys_dict_data values(5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '隐藏菜单');
insert into sys_dict_data values(6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', sysdate, '', null, '正常状态');
insert into sys_dict_data values(7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '停用状态');
insert into sys_dict_data values(8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', sysdate, '', null, '正常状态');
insert into sys_dict_data values(9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '停用状态');
insert into sys_dict_data values(10, 1, '默认', 'DEFAULT', 'sys_job_group', '', '', 'Y', '0', 'admin', sysdate, '', null, '默认分组');
insert into sys_dict_data values(11, 2, '系统', 'SYSTEM', 'sys_job_group', '', '', 'N', '0', 'admin', sysdate, '', null, '系统分组');
insert into sys_dict_data values(12, 1, '', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', sysdate, '', null, '系统默认是');
insert into sys_dict_data values(13, 2, '', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '系统默认否');
insert into sys_dict_data values(14, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', sysdate, '', null, '通知');
insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', sysdate, '', null, '公告');
insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', sysdate, '', null, '正常状态');
insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '关闭状态');
insert into sys_dict_data values(18, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate, '', null, '新增操作');
insert into sys_dict_data values(19, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate, '', null, '修改操作');
insert into sys_dict_data values(20, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '删除操作');
insert into sys_dict_data values(21, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', sysdate, '', null, '授权操作');
insert into sys_dict_data values(22, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate, '', null, '导出操作');
insert into sys_dict_data values(23, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate, '', null, '导入操作');
insert into sys_dict_data values(24, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '强退操作');
insert into sys_dict_data values(25, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate, '', null, '生成操作');
insert into sys_dict_data values(26, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '清空操作');
insert into sys_dict_data values(27, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', sysdate, '', null, '正常状态');
insert into sys_dict_data values(28, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '停用状态');
-- ----------------------------
-- 初始化-参数配置表
-- 初始化-参数配置表
-- ----------------------------
insert into sys_config values(1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', sysdate, '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' );
insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate, '', null, '初始化密码 123456' );
insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate, '', null, '深色主题theme-dark浅色主题theme-light' );
insert into sys_config values(4, '账号自助-验证码开关', 'sys.account.captchaOnOff', 'true', 'Y', 'admin', sysdate, '', null, '是否开启登录验证码功能true开启false关闭');
insert into sys_config values(1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', sysdate, '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' );
insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate, '', null, '初始化密码 123456' );
insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate, '', null, '深色主题theme-dark浅色主题theme-light' );
insert into sys_config values(4, '账号自助-验证码开关', 'sys.account.captchaOnOff', 'true', 'Y', 'admin', sysdate, '', null, '是否开启登录验证码功能true开启false关闭');
-- ----------------------------
-- 初始化-公告信息表数据
-- 初始化-公告信息表数据
-- ----------------------------
insert into sys_notice values('1', '温馨提醒2018-07-01 新版本发布啦', '2', '新版本内容', '0', 'admin', sysdate, '', null, '管理员');
insert into sys_notice values('2', '维护通知2018-07-01 系统凌晨维护', '1', '维护内容', '0', 'admin', sysdate, '', null, '管理员');
insert into sys_notice values('1', '温馨提醒2018-07-01 新版本发布啦', '2', '新版本内容', '0', 'admin', sysdate, '', null, '管理员');
insert into sys_notice values('2', '维护通知2018-07-01 系统凌晨维护', '1', '维护内容', '0', 'admin', sysdate, '', null, '管理员');
commit;

View File

@ -0,0 +1,75 @@
# 微信扫码登录功能测试指南
## 1. 功能概述
本系统已集成微信扫码登录功能,用户可以通过微信扫描二维码的方式登录系统,无需输入用户名和密码。
## 2. 配置要求
在测试前,请确保已完成以下配置:
1. 在`application.yml`中配置了正确的微信公众号信息:
```yaml
wechat:
app-id: your_wechat_appid
app-secret: your_wechat_app_secret
redirect-uri: http://your-domain.com/examapi/wechat/callback
```
2. 数据库已执行了微信登录字段添加脚本:
- `/doc/微信登录字段添加.sql`
## 3. 功能测试步骤
### 3.1 前端功能测试
1. 访问系统登录页面
2. 点击"微信扫码登录"按钮
3. 观察是否能正常生成二维码
4. 使用微信扫描二维码
5. 在微信中确认登录
6. 观察前端是否能正确跳转到系统主页
### 3.2 后端接口测试
可以通过Postman等工具测试以下接口
1. 生成二维码接口:
- URL: `GET /examapi/wechat/qrcode`
- 预期结果返回二维码信息和登录ID
2. 检查登录状态接口:
- URL: `GET /examapi/wechat/status?loginId={loginId}`
- 预期结果:返回当前登录状态
3. 微信登录接口:
- URL: `POST /examapi/wechat/login?loginId={loginId}`
- 预期结果登录成功并返回token
### 3.3 数据库验证
1. 检查`sys_user`表是否添加了微信相关字段
2. 检查`wechat_login_status`表是否能正常记录登录状态
3. 验证用户绑定微信后,`sys_user`表中的微信字段是否正确更新
## 4. 常见问题及解决方案
### 4.1 二维码无法生成
- 检查微信配置是否正确
- 检查网络连接是否正常
- 查看后端日志是否有错误信息
### 4.2 扫码后无法登录
- 检查微信回调接口是否正常
- 检查用户是否已正确绑定微信
- 查看数据库记录是否正常更新
### 4.3 登录成功但无法跳转
- 检查token是否正确返回
- 检查前端路由配置是否正确
## 5. 注意事项
1. 微信扫码登录功能需要在微信公众号平台配置正确的授权回调域名
2. 测试时建议使用真实的微信客户端扫描二维码
3. 二维码有有效期限制默认为10分钟
4. 同一个二维码只能使用一次
## 6. 安全建议
1. 建议在生产环境中使用HTTPS协议
2. 微信AppSecret应妥善保管不要暴露在前端代码中
3. 建议定期清理过期的登录状态记录

View File

@ -0,0 +1,27 @@
-- 为用户表添加微信登录相关字段
ALTER TABLE sys_user ADD COLUMN wechat_openid VARCHAR(100) NULL COMMENT '微信openid';
ALTER TABLE sys_user ADD COLUMN wechat_unionid VARCHAR(100) NULL COMMENT '微信unionid';
ALTER TABLE sys_user ADD COLUMN wechat_nickname VARCHAR(100) NULL COMMENT '微信昵称';
ALTER TABLE sys_user ADD COLUMN wechat_avatar VARCHAR(300) NULL COMMENT '微信头像';
ALTER TABLE sys_user ADD COLUMN bind_wechat CHAR(1) DEFAULT '0' NULL COMMENT '是否绑定微信(0-未绑定 1-已绑定)';
-- 为微信相关字段添加索引
ALTER TABLE sys_user ADD INDEX idx_wechat_openid (wechat_openid);
ALTER TABLE sys_user ADD INDEX idx_wechat_unionid (wechat_unionid);
-- 创建微信登录状态表,用于扫码登录状态管理
CREATE TABLE wechat_login_status (
id VARCHAR(64) NOT NULL COMMENT '登录状态ID',
qr_code_url VARCHAR(500) NULL COMMENT '二维码URL',
status CHAR(1) DEFAULT '0' NOT NULL COMMENT '登录状态(0-待扫码 1-已扫码 2-已确认 3-已过期)',
user_id INT NULL COMMENT '用户ID',
openid VARCHAR(100) NULL COMMENT '微信openid',
expire_time DATETIME NOT NULL COMMENT '过期时间',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '创建时间',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL COMMENT '更新时间',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='微信登录状态表';
-- 为微信登录状态表添加索引
ALTER TABLE wechat_login_status ADD INDEX idx_openid (openid);
ALTER TABLE wechat_login_status ADD INDEX idx_expire_time (expire_time);

View File

@ -61,6 +61,11 @@
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.25</version>
</dependency>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>

View File

@ -45,7 +45,7 @@ import com.ruoyi.common.core.page.TableDataInfo;
@RequestMapping("/exam/examtask")
public class ExamTaskManagerController extends BaseController
{
@Value("${cms.exam.photo-path}")
@Value("${cms.exam.photo-path:/photo/exam}")
private String photopath;
@Autowired

View File

@ -49,6 +49,27 @@ public class ExamTaskManager extends BaseEntity
@Excel(name = "考试题库文字")
private String examBankText;
@Excel(name = "考试类型1 固定时间考试 2固定时间段考试")
private Integer examType;
public Integer getExamType() {
return examType;
}
public void setExamType(Integer examType) {
this.examType = examType;
}
public Integer getExamTimes() {
return examTimes;
}
public void setExamTimes(Integer examTimes) {
this.examTimes = examTimes;
}
@Excel(name = "考试次数")
private Integer examTimes;
/** 图片链接 */
@Excel(name = "图片链接")

View File

@ -2,6 +2,7 @@ package com.hig.exam.mapper;
import java.util.List;
import com.hig.exam.domain.ExamTaskManager;
import org.apache.ibatis.annotations.Param;
/**
* Mapper
@ -59,4 +60,10 @@ public interface ExamTaskManagerMapper
* @return
*/
public int deleteExamTaskManagerByIds(String[] examCodes);
public List<ExamTaskManager> selectCurrentExam(@Param("userCode") String userCode);
public List<ExamTaskManager> countExamScore(@Param("examCodeList") List<String> examCodeList);
public List<ExamTaskManager> groupExamTypeCount(@Param("examCodeList") List<String> examCodeList);
}

View File

@ -2,6 +2,7 @@ package com.hig.exam.service;
import java.util.List;
import com.hig.exam.domain.ExamTaskManager;
import com.hig.onlineexam.domain.dto.ExamTitleData;
/**
* Service
@ -58,4 +59,11 @@ public interface IExamTaskManagerService
* @return
*/
public int deleteExamTaskManagerById(String examCode);
/**
*
* @param userCode
* @return
*/
public List<ExamTitleData> selectCurrentExam(String userCode);
}

View File

@ -1,6 +1,14 @@
package com.hig.exam.service.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.bean.BeanUtil;
import com.hig.onlineexam.domain.dto.ExamTitleData;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -111,4 +119,66 @@ public class ExamTaskManagerServiceImpl implements IExamTaskManagerService
{
return examTaskManagerMapper.deleteExamTaskManagerById(examCode);
}
/**
*
* @param userCode
* @return
*/
@Override
public List<ExamTitleData> selectCurrentExam(String userCode) {
//先根据当前时间和startDate和endDate过滤一下
List<ExamTaskManager> list=examTaskManagerMapper.selectCurrentExam(userCode);
List<ExamTitleData> retList=new ArrayList<>();
List<String> examCodeList=new ArrayList<>();
for(ExamTaskManager examTaskManager:list){
if(examTaskManager.getExamType()==1){
if(!checkCanRun(examTaskManager)){
continue;
}
}else{
}
ExamTitleData ed=new ExamTitleData();
examCodeList.add(examTaskManager.getExamCode());
// 使用 Hutool 的 BeanUtil.copyProperties 方法复制属性
BeanUtil.copyProperties(examTaskManager, ed);
retList.add(ed);
}
List<ExamTaskManager> listScore=examTaskManagerMapper.countExamScore(examCodeList);
List<ExamTaskManager> listTypeCount=examTaskManagerMapper.groupExamTypeCount(examCodeList);
for(ExamTitleData item :retList){
List<ExamTaskManager> tmp= listScore.stream().filter(d->d.getExamCode().equals(item.getExamCode())).collect(Collectors.toList());
if(tmp.size()>0){
item.setQuestionsScore(tmp.get(0).getExamType());
}
tmp=listTypeCount.stream().filter(d->d.getExamCode().equals(item.getExamCode()) && d.getExamId()==1).collect(Collectors.toList());
if(tmp.size()>0){
item.setJudgeNumber(tmp.get(0).getExamType());
}
tmp=listTypeCount.stream().filter(d->d.getExamCode().equals(item.getExamCode()) && d.getExamId()==2).collect(Collectors.toList());
if(tmp.size()>0){
item.setRadioNumber(tmp.get(0).getExamType());
}
tmp=listTypeCount.stream().filter(d->d.getExamCode().equals(item.getExamCode()) && d.getExamId()==3).collect(Collectors.toList());
if(tmp.size()>0){
item.setChoiceNumber(tmp.get(0).getExamType());
}
}
return retList;
}
private boolean checkCanRun(ExamTaskManager examTaskManager) {
//开始时间+考试时长 小于当前时间表示考试已发结束,大于表示还可能继续考试
DateTime dtStart=new DateTime( examTaskManager.getStartTime());
String sp=examTaskManager.getExamDuration();
String[] timeParts = sp.split(":");
int hours = Integer.parseInt(timeParts[0]);
int minutes = Integer.parseInt(timeParts[1]);
// 计算结束时间
DateTime endDateTime = dtStart.offset(DateField.HOUR_OF_DAY, hours)
.offset(DateField.MINUTE, minutes);
return endDateTime.isAfter(DateUtils.getNowDate());
}
}

View File

@ -2,6 +2,10 @@ package com.hig.onlineexam.controller;
import java.util.List;
import com.hig.exam.domain.ExamTaskManager;
import com.hig.exam.service.IExamTaskManagerService;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@ -19,10 +23,17 @@ public class ExamTitleController {
@Autowired
IExamTitleDataService examTitleDataService;
@GetMapping(value = "/{userCode}")
public AjaxResult selectCurrentExam(@PathVariable("userCode") String userCode)
@Autowired
IExamTaskManagerService examTaskManagerService;
@GetMapping(value = "/selectCurrentExam")
public AjaxResult selectCurrentExam()
{
ExamTitleData examTitleData = examTitleDataService.selectCurrentExam(userCode);
return AjaxResult.success(examTitleData);
LoginUser user=SecurityUtils.getLoginUser();
List<ExamTitleData> list= examTaskManagerService.selectCurrentExam(user.getUser().getUserCode());
//ExamTitleData examTitleData = examTitleDataService.selectCurrentExam(user.getUser().getUserCode());
//return AjaxResult.success(examTitleData);
return AjaxResult.success(list);
}
}

View File

@ -27,6 +27,17 @@ public class ExamTaskAnswer extends BaseEntity
@Excel(name = "题目代码")
private String questionsCode;
private String examTimes;
public String getExamTimes() {
return examTimes;
}
public void setExamTimes(String examTimes) {
this.examTimes = examTimes;
}
/** 题号 */
@Excel(name = "题号")
private Long questionsNumber;

View File

@ -16,6 +16,8 @@ public class ExamTitleData {
/** 考试名称 */
private String examName;
private Integer examType;
private Integer examTimes;
/** 考试说明 */
private String examDescribe;

View File

@ -46,7 +46,7 @@ public class ExamQuestionsBankController extends BaseController
{
private static final Logger log = LoggerFactory.getLogger(ExamQuestionsBankController.class);
@Value("${cms.exam.photo-path}")
@Value("${cms.exam.photo-path:/photo/exam}")
private String photopath;
@Autowired

View File

@ -12,6 +12,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="buildType" column="build_type" />
<result property="forceDone" column="force_done" />
<result property="examBank" column="exam_bank" />
<result property="examType" column="exam_type" />
<result property="examTimes" column="exam_times" />
<result property="examBankText" column="exam_bank_text" />
<result property="pictureUrl" column="picture_url" />
<result property="startTime" column="start_time" />
@ -24,7 +26,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<sql id="selectExamTaskManagerVo">
select exam_id, exam_code, exam_name, exam_describe, build_type, force_done, exam_bank, exam_bank_text, picture_url, start_time, end_time, exam_duration, status, create_by, create_dept, create_time from exam_task_manager
select exam_id, exam_code, exam_name,exam_type,exam_times, exam_describe, build_type, force_done, exam_bank, exam_bank_text, picture_url, start_time, end_time, exam_duration, status, create_by, create_dept, create_time from exam_task_manager
</sql>
<select id="selectExamTaskManagerList" parameterType="ExamTaskManager" resultMap="ExamTaskManagerResult">
@ -55,6 +57,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="examName != null and examName != ''">exam_name,</if>
<if test="examDescribe != null">exam_describe,</if>
<if test="buildType != null and buildType != ''">build_type,</if>
<if test="examType != null and examType != ''">exam_type,</if>
<if test="examTimes != null and examTimes != ''">exam_times,</if>
<if test="forceDone != null">force_done,</if>
<if test="examBank != null">exam_bank,</if>
<if test="examBankText != null">exam_bank_text,</if>
@ -72,6 +76,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="examName != null and examName != ''">#{examName},</if>
<if test="examDescribe != null">#{examDescribe},</if>
<if test="buildType != null and buildType != ''">#{buildType},</if>
<if test="examType != null and examType != ''">#{examType},</if>
<if test="examTimes != null and examTimes != ''">#{examTimes},</if>
<if test="forceDone != null">#{forceDone},</if>
<if test="examBank != null">#{examBank},</if>
<if test="examBankText != null">#{examBankText},</if>
@ -92,6 +98,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="examName != null and examName != ''">exam_name = #{examName},</if>
<if test="examDescribe != null">exam_describe = #{examDescribe},</if>
<if test="buildType != null and buildType != ''">build_type = #{buildType},</if>
<if test="examType != null and examType != ''">exam_type = #{examType},</if>
<if test="examTimes != null and examTimes != ''">exam_times = #{examTimes},</if>
<if test="forceDone != null">force_done = #{forceDone},</if>
<if test="examBank != null">exam_bank = #{examBank},</if>
<if test="examBankText != null">exam_bank_text = #{examBankText},</if>
@ -117,4 +125,33 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{examCode}
</foreach>
</delete>
<select id="selectCurrentExam" parameterType="String" resultMap="ExamTaskManagerResult">
<include refid="selectExamTaskManagerVo"/>
where status=0
AND exam_code in(select exam_code from exam_task_person where user_code=#{userCode})
and start_time &lt;=now() and end_time &gt; now()
</select>
<select id="countExamScore" parameterType="List" resultMap="ExamTaskManagerResult">
select tq.exam_code,sum(qp.questions_score) exam_type
from exam_task_questions tq ,exam_questions_property qp
where tq.questions_code=qp.questions_code
and tq.exam_code in
<foreach item="examCode" collection="examCodeList" open="(" separator="," close=")">
#{examCode}
</foreach>
GROUP BY tq.exam_code
</select>
<select id="groupExamTypeCount" parameterType="List" resultMap="ExamTaskManagerResult">
select tq.exam_code,qp.questions_type exam_id,count(1) exam_type
from exam_task_questions tq ,exam_questions_property qp
where tq.questions_code=qp.questions_code
and tq.exam_code in
<foreach item="examCode" collection="examCodeList" open="(" separator="," close=")">
#{examCode}
</foreach>
GROUP BY tq.exam_code,qp.questions_type
</select>
</mapper>

View File

@ -7,6 +7,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="ExamTaskAnswer" id="ExamTaskAnswerResult">
<result property="examCode" column="exam_code" />
<result property="userCode" column="user_code" />
<result property="examTimes" column="exam_times" />
<result property="questionsCode" column="questions_code" />
<result property="questionsNumber" column="questions_number" />
<result property="questionsType" column="questions_type" />
@ -16,7 +17,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<sql id="selectExamTaskAnswerVo">
select exam_code, user_code, questions_code, questions_number, questions_type, questions_answer, is_mark, is_current from exam_task_answer
select exam_code, user_code,exam_times, questions_code, questions_number, questions_type, questions_answer, is_mark, is_current from exam_task_answer
</sql>
<select id="selectExamTaskAnswerList" parameterType="ExamTaskAnswer" resultMap="ExamTaskAnswerResult">
@ -35,6 +36,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="examCode != null and examCode != ''">exam_code,</if>
<if test="userCode != null and userCode != ''">user_code,</if>
<if test="examTimes != null and examTimes != ''">exam_times,</if>
<if test="questionsCode != null and questionsCode != ''">questions_code,</if>
<if test="questionsNumber != null">questions_number,</if>
<if test="questionsType != null">questions_type,</if>
@ -45,6 +47,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="examCode != null and examCode != ''">#{examCode},</if>
<if test="userCode != null and userCode != ''">#{userCode},</if>
<if test="examTimes != null and examTimes != ''">#{examTimes},</if>
<if test="questionsCode != null and questionsCode != ''">#{questionsCode},</if>
<if test="questionsNumber != null">#{questionsNumber},</if>
<if test="questionsType != null">#{questionsType},</if>

View File

@ -27,7 +27,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<sql id="selectExamQuestionsBankVo">
select a.bank_id, a.bank_code, a.bank_name, a.bank_describe, a.bank_version, a.exam_type, b.type_name,a.online_date, a.picture_url, ifnull(c.judge_number,0) as judge_number,ifnull(d.radio_number,0) as radio_number,ifnull(e.choice_number,0) as choice_number,a.radio_score, a.choice_score, a.judge_score, a.status, a.create_by, a.create_dept, a.create_time from exam_questions_bank a
select a.bank_id, a.bank_code, a.bank_name, a.bank_describe, a.bank_version, a.exam_type, b.type_name,a.online_date, a.picture_url,
ifnull(c.judge_number,0) as judge_number,ifnull(d.radio_number,0) as radio_number,ifnull(e.choice_number,0) as choice_number,a.radio_score,
a.choice_score, a.judge_score, a.status, a.create_by, a.create_dept, a.create_time
from exam_questions_bank a
left join exam_type b on b.type_id = a.exam_type
left join
(

View File

@ -35,6 +35,8 @@
<velocity.version>2.3</velocity.version>
<jwt.version>0.9.1</jwt.version>
<mysql.version>8.0.33</mysql.version>
<weixin.version>4.5.0</weixin.version>
<qrgen.version>3.0.1</qrgen.version>
</properties>
<!-- 依赖声明 -->
@ -180,6 +182,20 @@
<version>${kaptcha.version}</version>
</dependency>
<!-- 微信开发SDK -->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>${weixin.version}</version>
</dependency>
<!-- 二维码生成工具 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.5.3</version>
</dependency>
<!-- 定时任务-->
<dependency>
<groupId>com.ruoyi</groupId>

View File

@ -2,6 +2,7 @@ package com.ruoyi.web.controller.system;
import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.Date;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
@ -10,18 +11,24 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.entity.WechatLoginStatus;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.framework.web.service.WechatService;
import com.ruoyi.system.mapper.WechatLoginStatusMapper;
import com.ruoyi.system.service.ISysMenuService;
import com.ruoyi.system.service.ISysUserService;
/**
*
@ -44,6 +51,15 @@ public class SysLoginController
@Autowired
private TokenService tokenService;
@Autowired
private WechatService wechatService;
@Autowired
private WechatLoginStatusMapper wechatLoginStatusMapper;
@Autowired
private ISysUserService userService;
/**
*
*
@ -108,4 +124,59 @@ public class SysLoginController
List<SysMenu> menus = menuService.selectMenuTreeByUserId(user.getUserId());
return AjaxResult.success(menuService.buildMenus(menus));
}
/**
*
*
* @param loginId ID
* @return
*/
@PostMapping("/wechat/login")
public AjaxResult wechatLogin(@RequestParam String loginId)
{
try {
// 查询登录状态
WechatLoginStatus loginStatus = wechatLoginStatusMapper.selectWechatLoginStatusById(loginId);
if (loginStatus == null) {
return AjaxResult.error("登录状态不存在");
}
// 检查状态是否为已确认
if (!"2".equals(loginStatus.getStatus())) {
return AjaxResult.error("登录状态不正确");
}
// 根据openid查询用户
SysUser user = userService.selectUserByWechatOpenid(loginStatus.getOpenid());
if (user == null) {
return AjaxResult.error("未找到绑定的用户");
}
// 检查用户状态
if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
return AjaxResult.error("用户已被删除");
}
if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
return AjaxResult.error("用户已被禁用");
}
// 创建登录用户对象
LoginUser loginUser = new LoginUser(user, permissionService.getMenuPermission(user));
// 生成令牌
String token = tokenService.createToken(loginUser);
// 更新登录状态为已使用
loginStatus.setStatus("4"); // 已使用
loginStatus.setUpdateTime(new Date());
wechatLoginStatusMapper.updateWechatLoginStatus(loginStatus);
AjaxResult ajax = AjaxResult.success();
ajax.put(Constants.TOKEN, token);
return ajax;
} catch (Exception e) {
log.error("微信登录失败", e);
return AjaxResult.error("微信登录失败: " + e.getMessage());
}
}
}

View File

@ -0,0 +1,69 @@
package com.ruoyi.web.controller.system;
import java.io.IOException;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.google.zxing.WriterException;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.framework.web.service.WechatService;
import me.chanjar.weixin.common.error.WxErrorException;
/**
*
*
* @author ruoyi
*/
@RestController
@RequestMapping("/wechat")
public class WechatLoginController extends BaseController
{
@Autowired
private WechatService wechatService;
/**
*
*/
@GetMapping("/qrcode")
public AjaxResult generateQrCode()
{
try
{
Map<String, Object> result = wechatService.generateLoginQrCode();
return AjaxResult.success(result);
}
catch (WxErrorException | IOException | WriterException e)
{
return AjaxResult.error("生成二维码失败: " + e.getMessage());
}
}
/**
*
*/
@GetMapping("/status")
public AjaxResult checkLoginStatus(@RequestParam String loginId)
{
Map<String, Object> result = wechatService.checkLoginStatus(loginId);
return AjaxResult.success(result);
}
/**
*
*/
@GetMapping("/callback")
public AjaxResult wechatCallback(
@RequestParam(required = false) String code,
@RequestParam(required = false) String state)
{
return wechatService.handleWechatCallback(code, state);
}
}

View File

@ -7,9 +7,11 @@ spring:
druid:
# 主库数据源
master:
url: jdbc:mysql://62.234.3.186:3306/yanzhu_exam?useSSL=false&characterEncoding=UTF-8&serverTimezone=GMT%2B8
#url: jdbc:mysql://62.234.3.186:3306/yanzhu_exam?useSSL=false&characterEncoding=UTF-8&serverTimezone=GMT%2B8
url: jdbc:mysql://127.0.0.1:3306/yanzhu_exam?useSSL=false&characterEncoding=UTF-8&serverTimezone=GMT%2B8
username: root
password: Sxyanzhu@cf123
#password: Sxyanzhu@cf123
password: haha123321
#url: jdbc:oracle:thin:@127.0.0.1:1521/xchwdb
#username: exam_user

View File

@ -74,6 +74,8 @@ cms:
# 内容管理相关
news:
photo-path: /photo/news
exam:
photo-path: /photo/exam
# 文件管理相关
fms:
photo-path: /photo/fms
@ -83,6 +85,21 @@ cms:
# 流程附件相关
workflow:
file-path: /photo/ueditor
# 微信配置
wechat:
# 微信公众号AppId
app-id: your_wechat_appid
# 微信公众号AppSecret
app-secret: your_wechat_app_secret
# 授权回调地址
redirect-uri: http://your-domain.com/examapi/wechat/callback
# 二维码场景值前缀
qr-scene-prefix: LOGIN_
# 二维码有效期(秒)
qr-expire-time: 600
# 登录状态检查间隔(毫秒)
status-check-interval: 2000
# 考试系统
exam:
photo-path: /photo/exam

View File

@ -68,6 +68,21 @@ public class SysUser extends BaseEntity
/** 用户头像 */
private String avatar;
/** 微信openid */
private String wechatOpenid;
/** 微信unionid */
private String wechatUnionid;
/** 微信昵称 */
private String wechatNickname;
/** 微信头像 */
private String wechatAvatar;
/** 是否绑定微信 */
private String bindWechat;
/** 密码 */
private String password;
@ -222,6 +237,56 @@ public class SysUser extends BaseEntity
this.avatar = avatar;
}
public String getWechatOpenid()
{
return wechatOpenid;
}
public void setWechatOpenid(String wechatOpenid)
{
this.wechatOpenid = wechatOpenid;
}
public String getWechatUnionid()
{
return wechatUnionid;
}
public void setWechatUnionid(String wechatUnionid)
{
this.wechatUnionid = wechatUnionid;
}
public String getWechatNickname()
{
return wechatNickname;
}
public void setWechatNickname(String wechatNickname)
{
this.wechatNickname = wechatNickname;
}
public String getWechatAvatar()
{
return wechatAvatar;
}
public void setWechatAvatar(String wechatAvatar)
{
this.wechatAvatar = wechatAvatar;
}
public String getBindWechat()
{
return bindWechat;
}
public void setBindWechat(String bindWechat)
{
this.bindWechat = bindWechat;
}
@JsonIgnore
@JsonProperty
public String getPassword()
@ -347,6 +412,11 @@ public class SysUser extends BaseEntity
.append("phonenumber", getPhonenumber())
.append("sex", getSex())
.append("avatar", getAvatar())
.append("wechatOpenid", getWechatOpenid())
.append("wechatUnionid", getWechatUnionid())
.append("wechatNickname", getWechatNickname())
.append("wechatAvatar", getWechatAvatar())
.append("bindWechat", getBindWechat())
.append("password", getPassword())
.append("salt", getSalt())
.append("status", getStatus())

View File

@ -0,0 +1,128 @@
package com.ruoyi.common.core.domain.entity;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
/**
*
*
* @author ruoyi
* @date 2024-08-24
*/
public class WechatLoginStatus
{
/** 登录状态ID */
private String id;
/** 二维码URL */
@Excel(name = "二维码URL")
private String qrCodeUrl;
/** 登录状态(0-待扫码 1-已扫码 2-已确认 3-已过期) */
@Excel(name = "登录状态", readConverterExp = "0=待扫码,1=已扫码,2=已确认,3=已过期")
private String status;
/** 用户ID */
@Excel(name = "用户ID")
private Long userId;
/** 微信openid */
@Excel(name = "微信openid")
private String openid;
/** 过期时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "过期时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date expireTime;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
public void setId(String id)
{
this.id = id;
}
public String getId()
{
return id;
}
public void setQrCodeUrl(String qrCodeUrl)
{
this.qrCodeUrl = qrCodeUrl;
}
public String getQrCodeUrl()
{
return qrCodeUrl;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public void setOpenid(String openid)
{
this.openid = openid;
}
public String getOpenid()
{
return openid;
}
public void setExpireTime(Date expireTime)
{
this.expireTime = expireTime;
}
public Date getExpireTime()
{
return expireTime;
}
public void setCreateTime(Date createTime)
{
this.createTime = createTime;
}
public Date getCreateTime()
{
return createTime;
}
public void setUpdateTime(Date updateTime)
{
this.updateTime = updateTime;
}
public Date getUpdateTime()
{
return updateTime;
}
}

View File

@ -47,6 +47,19 @@
</exclusions>
</dependency>
<!-- 微信开发SDK -->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
</dependency>
<!-- 二维码生成工具 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.5.3</version>
</dependency>
<!-- 获取系统信息 -->
<dependency>
<groupId>com.github.oshi</groupId>

View File

@ -98,6 +98,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
.authorizeRequests()
// 对于登录login 验证码captchaImage 允许匿名访问
.antMatchers("/login", "/captchaImage").anonymous()
// 微信登录相关接口允许匿名访问
.antMatchers("/wechat/**").anonymous()
.antMatchers(
HttpMethod.GET,
"/",

View File

@ -0,0 +1,40 @@
package com.ruoyi.framework.config;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
*
*
* @author ruoyi
*/
@Configuration
@EnableConfigurationProperties(WechatProperties.class)
public class WechatConfig
{
@Autowired
private WechatProperties wechatProperties;
@Bean
public WxMpConfigStorage wxMpConfigStorage()
{
WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();
configStorage.setAppId(wechatProperties.getAppId());
configStorage.setSecret(wechatProperties.getAppSecret());
return configStorage;
}
@Bean
public WxMpService wxMpService(WxMpConfigStorage configStorage)
{
WxMpService wxMpService = new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(configStorage);
return wxMpService;
}
}

View File

@ -0,0 +1,92 @@
package com.ruoyi.framework.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
*
*
* @author ruoyi
*/
@Component
@ConfigurationProperties(prefix = "wechat")
public class WechatProperties
{
/** 微信公众号AppId */
private String appId;
/** 微信公众号AppSecret */
private String appSecret;
/** 授权回调地址 */
private String redirectUri;
/** 二维码场景值前缀 */
private String qrScenePrefix = "LOGIN_";
/** 二维码有效期(秒) */
private Integer qrExpireTime = 600;
/** 登录状态检查间隔(毫秒) */
private Long statusCheckInterval = 2000L;
public String getAppId()
{
return appId;
}
public void setAppId(String appId)
{
this.appId = appId;
}
public String getAppSecret()
{
return appSecret;
}
public void setAppSecret(String appSecret)
{
this.appSecret = appSecret;
}
public String getRedirectUri()
{
return redirectUri;
}
public void setRedirectUri(String redirectUri)
{
this.redirectUri = redirectUri;
}
public String getQrScenePrefix()
{
return qrScenePrefix;
}
public void setQrScenePrefix(String qrScenePrefix)
{
this.qrScenePrefix = qrScenePrefix;
}
public Integer getQrExpireTime()
{
return qrExpireTime;
}
public void setQrExpireTime(Integer qrExpireTime)
{
this.qrExpireTime = qrExpireTime;
}
public Long getStatusCheckInterval()
{
return statusCheckInterval;
}
public void setStatusCheckInterval(Long statusCheckInterval)
{
this.statusCheckInterval = statusCheckInterval;
}
}

View File

@ -0,0 +1,294 @@
package com.ruoyi.framework.web.service;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.imageio.ImageIO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.entity.WechatLoginStatus;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.config.WechatProperties;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.mapper.WechatLoginStatusMapper;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
/**
*
*
* @author ruoyi
*/
@Service
public class WechatService
{
private static final Logger log = LoggerFactory.getLogger(WechatService.class);
@Autowired
private WxMpService wxMpService;
@Autowired
private WechatProperties wechatProperties;
@Autowired
private WechatLoginStatusMapper wechatLoginStatusMapper;
@Autowired
private SysUserMapper userMapper;
/**
*
*
* @return Map
*/
public Map<String, Object> generateLoginQrCode() throws WxErrorException, IOException, com.google.zxing.WriterException
{
// 生成唯一的登录状态ID
String loginId = UUID.randomUUID().toString().replace("-", "");
String sceneStr = wechatProperties.getQrScenePrefix() + loginId;
// 创建临时二维码
WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(sceneStr, wechatProperties.getQrExpireTime());
String qrCodeUrl = wxMpService.getQrcodeService().qrCodePictureUrl(ticket.getTicket());
// 生成本地二维码图片
try {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrCodeWriter.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 200, 200);
BufferedImage qrCodeImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(qrCodeImage, "png", baos);
String base64Image = "data:image/png;base64," + java.util.Base64.getEncoder().encodeToString(baos.toByteArray());
// 保存登录状态到数据库
WechatLoginStatus loginStatus = new WechatLoginStatus();
loginStatus.setId(loginId);
loginStatus.setQrCodeUrl(qrCodeUrl);
loginStatus.setStatus("0"); // 待扫码
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, wechatProperties.getQrExpireTime());
loginStatus.setExpireTime(calendar.getTime());
loginStatus.setCreateTime(new Date());
loginStatus.setUpdateTime(new Date());
wechatLoginStatusMapper.insertWechatLoginStatus(loginStatus);
// 返回结果
Map<String, Object> result = new HashMap<>();
result.put("loginId", loginId);
result.put("qrCodeUrl", qrCodeUrl);
result.put("qrCodeImage", base64Image);
result.put("expireTime", wechatProperties.getQrExpireTime());
return result;
} catch (com.google.zxing.WriterException e) {
log.error("生成二维码失败", e);
throw e;
}
}
/**
* OAuth2URL
*
* @param state
* @return URL
*/
public String getOAuth2AuthorizeUrl(String state)
{
return wxMpService.getOAuth2Service().buildAuthorizationUrl(
wechatProperties.getRedirectUri(),
"snsapi_userinfo",
state
);
}
/**
*
*
* @param code
* @return
*/
public WxOAuth2UserInfo getUserInfo(String code) throws WxErrorException
{
WxOAuth2AccessToken accessToken = wxMpService.getOAuth2Service().getAccessToken(code);
return wxMpService.getOAuth2Service().getUserInfo(accessToken, null);
}
/**
*
*
* @param loginId ID
* @return
*/
public Map<String, Object> checkLoginStatus(String loginId)
{
WechatLoginStatus loginStatus = wechatLoginStatusMapper.selectWechatLoginStatusById(loginId);
Map<String, Object> result = new HashMap<>();
if (loginStatus == null) {
result.put("status", "3"); // 已过期
result.put("message", "登录状态不存在或已过期");
return result;
}
// 检查是否过期
if (new Date().after(loginStatus.getExpireTime())) {
result.put("status", "3"); // 已过期
result.put("message", "二维码已过期");
return result;
}
result.put("status", loginStatus.getStatus());
result.put("userId", loginStatus.getUserId());
switch (loginStatus.getStatus()) {
case "0":
result.put("message", "等待扫码");
break;
case "1":
result.put("message", "已扫码,等待确认");
break;
case "2":
result.put("message", "登录成功");
break;
default:
result.put("message", "未知状态");
break;
}
return result;
}
/**
*
*
* @param loginId ID
* @param status
* @param userId ID
* @param openid openid
*/
public void updateLoginStatus(String loginId, String status, Long userId, String openid)
{
WechatLoginStatus loginStatus = new WechatLoginStatus();
loginStatus.setId(loginId);
loginStatus.setStatus(status);
loginStatus.setUserId(userId);
loginStatus.setOpenid(openid);
loginStatus.setUpdateTime(new Date());
wechatLoginStatusMapper.updateWechatLoginStatus(loginStatus);
}
/**
* ID
*
* @param sceneStr
* @return ID
*/
public String parseLoginIdFromScene(String sceneStr)
{
if (StringUtils.isNotEmpty(sceneStr) && sceneStr.startsWith(wechatProperties.getQrScenePrefix())) {
return sceneStr.substring(wechatProperties.getQrScenePrefix().length());
}
return null;
}
/**
*
*
* @param code
* @param state
* @return
*/
public AjaxResult handleWechatCallback(String code, String state)
{
try {
if (StringUtils.isEmpty(code)) {
return AjaxResult.error("授权码不能为空");
}
// 获取用户信息
WxOAuth2UserInfo userInfo = getUserInfo(code);
// 解析登录ID
String loginId = parseLoginIdFromScene(state);
if (StringUtils.isEmpty(loginId)) {
return AjaxResult.error("无效的登录状态");
}
// 查询登录状态
WechatLoginStatus loginStatus = wechatLoginStatusMapper.selectWechatLoginStatusById(loginId);
if (loginStatus == null) {
return AjaxResult.error("登录状态不存在或已过期");
}
// 检查是否过期
if (new Date().after(loginStatus.getExpireTime())) {
return AjaxResult.error("二维码已过期");
}
// 更新登录状态为已扫码
updateLoginStatus(loginId, "1", null, userInfo.getOpenid());
// 查询用户是否已绑定
SysUser user = userMapper.selectUserByWechatOpenid(userInfo.getOpenid());
Long userId = null;
if (user != null) {
// 用户已绑定,直接更新用户微信信息
user.setWechatNickname(userInfo.getNickname());
user.setWechatAvatar(userInfo.getHeadImgUrl());
userMapper.updateUser(user);
userId = user.getUserId();
} else {
// 用户未绑定,创建新用户或提示绑定
// 这里可以根据业务需求决定是自动创建用户还是提示用户绑定
// 为了演示,我们创建一个新用户
user = new SysUser();
user.setUserName("wechat_" + userInfo.getOpenid().substring(0, 10));
user.setNickName(userInfo.getNickname());
user.setWechatOpenid(userInfo.getOpenid());
user.setWechatUnionid(userInfo.getUnionId());
user.setWechatNickname(userInfo.getNickname());
user.setWechatAvatar(userInfo.getHeadImgUrl());
user.setBindWechat("1");
user.setStatus("0"); // 正常状态
user.setDelFlag("0"); // 未删除
user.setPassword("123456"); // 默认密码
userMapper.insertUser(user);
userId = user.getUserId();
}
// 更新登录状态为已确认
updateLoginStatus(loginId, "2", userId, userInfo.getOpenid());
return AjaxResult.success("登录成功");
} catch (WxErrorException e) {
log.error("微信回调处理失败", e);
return AjaxResult.error("微信回调处理失败: " + e.getMessage());
}
}
}

View File

@ -35,6 +35,22 @@ public interface SysUserMapper
*/
public List<SysUser> selectUnallocatedList(SysUser user);
/**
* openid
*
* @param openid openid
* @return
*/
public SysUser selectUserByWechatOpenid(String openid);
/**
*
*
* @param user
* @return
*/
public int bindWechatUser(SysUser user);
/**
*
*

View File

@ -0,0 +1,77 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.common.core.domain.entity.WechatLoginStatus;
import org.apache.ibatis.annotations.Param;
/**
* Mapper
*
* @author ruoyi
* @date 2024-08-24
*/
public interface WechatLoginStatusMapper
{
/**
*
*
* @param id
* @return
*/
public WechatLoginStatus selectWechatLoginStatusById(String id);
/**
*
*
* @param wechatLoginStatus
* @return
*/
public List<WechatLoginStatus> selectWechatLoginStatusList(WechatLoginStatus wechatLoginStatus);
/**
*
*
* @param wechatLoginStatus
* @return
*/
public int insertWechatLoginStatus(WechatLoginStatus wechatLoginStatus);
/**
*
*
* @param wechatLoginStatus
* @return
*/
public int updateWechatLoginStatus(WechatLoginStatus wechatLoginStatus);
/**
*
*
* @param id
* @return
*/
public int deleteWechatLoginStatusById(String id);
/**
*
*
* @param ids
* @return
*/
public int deleteWechatLoginStatusByIds(String[] ids);
/**
* openid
*
* @param openid openid
* @return
*/
public WechatLoginStatus selectWechatLoginStatusByOpenid(@Param("openid") String openid);
/**
*
*
* @return
*/
public int deleteExpiredWechatLoginStatus();
}

View File

@ -10,6 +10,22 @@ import com.ruoyi.common.core.domain.entity.SysUser;
*/
public interface ISysUserService
{
/**
* openid
*
* @param openid openid
* @return
*/
public SysUser selectUserByWechatOpenid(String openid);
/**
*
*
* @param user
* @return
*/
public int bindWechatUser(SysUser user);
/**
*
*

View File

@ -56,6 +56,30 @@ public class SysUserServiceImpl implements ISysUserService
@Autowired
private ISysConfigService configService;
/**
* openid
*
* @param openid openid
* @return
*/
@Override
public SysUser selectUserByWechatOpenid(String openid)
{
return userMapper.selectUserByWechatOpenid(openid);
}
/**
*
*
* @param user
* @return
*/
@Override
public int bindWechatUser(SysUser user)
{
return userMapper.bindWechatUser(user);
}
/**
*

View File

@ -129,6 +129,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
${params.dataScope}
</select>
<select id="selectUserByWechatOpenid" parameterType="String" resultMap="SysUserResult">
select u.user_id, u.user_code,u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
where u.wechat_openid = #{openid} and u.del_flag = '0'
</select>
<update id="bindWechatUser" parameterType="SysUser">
update sys_user
<set>
<if test="wechatOpenid != null and wechatOpenid != ''">wechat_openid = #{wechatOpenid},</if>
<if test="wechatUnionid != null and wechatUnionid != ''">wechat_unionid = #{wechatUnionid},</if>
<if test="wechatNickname != null and wechatNickname != ''">wechat_nickname = #{wechatNickname},</if>
<if test="wechatAvatar != null and wechatAvatar != ''">wechat_avatar = #{wechatAvatar},</if>
<if test="bindWechat != null and bindWechat != ''">bind_wechat = #{bindWechat},</if>
update_time = now()
</set>
where user_id = #{userId}
</update>
<select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult">
<include refid="selectUserVo"/>
where u.user_name = #{userName}

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.WechatLoginStatusMapper">
<resultMap type="WechatLoginStatus" id="WechatLoginStatusResult">
<result property="id" column="id" />
<result property="qrCodeUrl" column="qr_code_url" />
<result property="status" column="status" />
<result property="userId" column="user_id" />
<result property="openid" column="openid" />
<result property="expireTime" column="expire_time" />
<result property="createTime" column="create_time" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectWechatLoginStatusVo">
select id, qr_code_url, status, user_id, openid, expire_time, create_time, update_time from wechat_login_status
</sql>
<select id="selectWechatLoginStatusList" parameterType="WechatLoginStatus" resultMap="WechatLoginStatusResult">
<include refid="selectWechatLoginStatusVo"/>
<where>
<if test="qrCodeUrl != null and qrCodeUrl != ''"> and qr_code_url = #{qrCodeUrl}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
<if test="userId != null "> and user_id = #{userId}</if>
<if test="openid != null and openid != ''"> and openid = #{openid}</if>
<if test="expireTime != null "> and expire_time = #{expireTime}</if>
</where>
</select>
<select id="selectWechatLoginStatusById" parameterType="String" resultMap="WechatLoginStatusResult">
<include refid="selectWechatLoginStatusVo"/>
where id = #{id}
</select>
<select id="selectWechatLoginStatusByOpenid" parameterType="String" resultMap="WechatLoginStatusResult">
<include refid="selectWechatLoginStatusVo"/>
where openid = #{openid} and expire_time > now() order by create_time desc limit 1
</select>
<insert id="insertWechatLoginStatus" parameterType="WechatLoginStatus">
insert into wechat_login_status
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">id,</if>
<if test="qrCodeUrl != null">qr_code_url,</if>
<if test="status != null">status,</if>
<if test="userId != null">user_id,</if>
<if test="openid != null">openid,</if>
<if test="expireTime != null">expire_time,</if>
<if test="createTime != null">create_time,</if>
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},</if>
<if test="qrCodeUrl != null">#{qrCodeUrl},</if>
<if test="status != null">#{status},</if>
<if test="userId != null">#{userId},</if>
<if test="openid != null">#{openid},</if>
<if test="expireTime != null">#{expireTime},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateTime != null">#{updateTime},</if>
</trim>
</insert>
<update id="updateWechatLoginStatus" parameterType="WechatLoginStatus">
update wechat_login_status
<trim prefix="SET" suffixOverrides=",">
<if test="qrCodeUrl != null">qr_code_url = #{qrCodeUrl},</if>
<if test="status != null">status = #{status},</if>
<if test="userId != null">user_id = #{userId},</if>
<if test="openid != null">openid = #{openid},</if>
<if test="expireTime != null">expire_time = #{expireTime},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteWechatLoginStatusById" parameterType="String">
delete from wechat_login_status where id = #{id}
</delete>
<delete id="deleteWechatLoginStatusByIds" parameterType="String">
delete from wechat_login_status where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<delete id="deleteExpiredWechatLoginStatus">
delete from wechat_login_status where expire_time &lt; now()
</delete>
</mapper>

View File

@ -40,6 +40,7 @@
"axios": "^1.7.9",
"clipboard": "^2.0.11",
"core-js": "^3.39.0",
"dayjs": "^1.11.13",
"echarts": "4.9.0",
"element-ui": "^2.15.13",
"file-saver": "^2.0.5",
@ -70,7 +71,6 @@
"babel-eslint": "^10.1.0",
"chalk": "^4.1.2",
"connect": "^3.7.0",
"vue-ueditor-wrap": "^2.5.6",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^7.20.0",
"lint-staged": "^10.5.4",
@ -79,7 +79,8 @@
"sass-loader": "^10.5.2",
"script-ext-html-webpack-plugin": "^2.1.5",
"svg-sprite-loader": "^5.2.1",
"vue-template-compiler": "^2.7.16"
"vue-template-compiler": "^2.7.16",
"vue-ueditor-wrap": "^2.5.6"
},
"engines": {
"node": ">=14.0.0",
@ -89,5 +90,8 @@
"browserslist": [
"> 1%",
"last 2 versions"
]
],
"resolutions": {
"@achrinza/node-ipc": "^10.1.11"
}
}

View File

@ -1,9 +1,9 @@
import request from '@/utils/request'
// 取得考试的标题信息
export function getTitle(userCode) {
export function getTitle() {
return request({
url: '/onlineexam/examtitle/' + userCode,
url: '/onlineexam/examtitle/selectCurrentExam',
method: 'get'
})
}

View File

@ -0,0 +1,27 @@
import request from '@/utils/request'
// 生成微信登录二维码
export function generateWechatQrCode() {
return request({
url: '/wechat/qrcode',
method: 'get'
})
}
// 检查微信登录状态
export function checkWechatLoginStatus(loginId) {
return request({
url: '/wechat/status',
method: 'get',
params: { loginId }
})
}
// 微信登录
export function wechatLogin(loginId) {
return request({
url: '/wechat/login',
method: 'post',
params: { loginId }
})
}

View File

@ -33,6 +33,7 @@ import VueMeta from 'vue-meta'
// 大文件上传
import uploader from 'vue-simple-uploader'
import dayjs from 'dayjs'
// 全局方法挂载
Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey
@ -43,6 +44,7 @@ Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.selectDictLabels = selectDictLabels
Vue.prototype.download = download
Vue.prototype.handleTree = handleTree
Vue.prototype.$dt=dayjs
Vue.prototype.msgSuccess = function (msg) {
this.$message({ showClose: true, message: msg, type: "success" });

View File

@ -3,19 +3,8 @@
<div v-if="choiceVisible">
<div class="content-area" :style="ui_style">
<div class="button-panel" v-if="isUpdate">
<el-button
@click="onClose"
plain
icon="el-icon-delete"
size="mini"
>返回</el-button>
<el-button
type="success"
plain
icon="el-icon-check"
size="mini"
@click="onSave"
>保存</el-button>
<el-button @click="onClose" plain icon="el-icon-delete" size="mini">返回</el-button>
<el-button type="success" plain icon="el-icon-check" size="mini" @click="onSave"></el-button>
</div>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="考试名称" prop="examName">
@ -28,27 +17,37 @@
<el-col :span="12" :xs="24">
<el-form-item label="组卷方式" prop="buildType">
<el-select v-model="form.buildType" placeholder="请选择组卷方式">
<el-option
v-for="dict in buildTypeOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
<el-option v-for="dict in buildTypeOptions" :key="dict.dictValue" :label="dict.dictLabel"
:value="dict.dictValue"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" :xs="24">
<el-form-item label="强制抽卷" prop="forceDone">
<el-radio-group v-model="form.forceDone">
<el-radio
v-for="dict in forceDoneOptions"
:key="dict.dictValue"
:label="parseInt(dict.dictValue)"
>{{dict.dictLabel}}</el-radio>
<el-radio v-for="dict in forceDoneOptions" :key="dict.dictValue"
:label="parseInt(dict.dictValue)">{{ dict.dictLabel }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12" :xs="24">
<el-form-item label="考试方式" prop="examType">
<el-select v-model="form.examType" placeholder="请选择考试方式">
<el-option label="固定时间考试"
:value="1"></el-option>
<el-option label="固定时间段考试"
:value="2"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" :xs="24">
<el-form-item label="考试次数" prop="examTimes">
<el-input-number :min="1" v-model="form.examTimes" placeholder="请输入考试次数"/>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="选择题库" prop="examBank">
<el-row>
<el-col :span="20">
@ -62,72 +61,50 @@
</el-row>
</el-form-item>
<el-form-item label="标题图片">
<el-upload
class="avatar-uploader"
:action="url"
:data="upLoadData"
:show-file-list="false"
:before-upload="beforeAvatarUpload"
>
<img
v-if="imageUrl"
:src="imageUrl"
class="avatar"
>
<i
v-else
class="el-icon-plus avatar-uploader-icon"
></i>
<el-upload class="avatar-uploader" :action="url" :data="upLoadData" :show-file-list="false"
:before-upload="beforeAvatarUpload">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-row :gutter="20">
<el-col :span="12" :xs="24">
<el-form-item label="开始时间">
<el-date-picker
v-model="startDate"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetime"
<el-date-picker v-model="startDate" value-format="yyyy-MM-dd HH:mm:ss" type="datetime"
placeholder="选择考试开始日期时间">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12" :xs="24" v-if="form.examType==2">
<el-form-item label="结束时间">
<el-date-picker v-model="endDate" value-format="yyyy-MM-dd HH:mm:ss" type="datetime"
placeholder="选择考试结束日期时间">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12" :xs="24">
<el-form-item label="考试时长" prop="examDuration">
<el-time-select
v-model="form.examDuration"
:picker-options="{
<el-time-select v-model="form.examDuration" :picker-options="{
start: '00:15',
step: '00:15',
end: '9:30'
}"
@change="onTimeChange"
placeholder="选择时间">
}" @change="onTimeChange" placeholder="选择时间">
</el-time-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in statusOptions"
:key="dict.dictValue"
:label="parseInt(dict.dictValue)"
>{{dict.dictLabel}}</el-radio>
<el-radio v-for="dict in statusOptions" :key="dict.dictValue"
:label="parseInt(dict.dictValue)">{{ dict.dictLabel }}</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<!-- 剪裁组件弹窗 -->
<el-dialog
title="裁切题库封面"
:visible.sync="cropperModel"
width="950px"
center
>
<cropper-image
:Name="cropperName"
@uploadImgSuccess="handleUploadSuccess"
ref="child"
>
<el-dialog title="裁切题库封面" :visible.sync="cropperModel" width="950px" center>
<cropper-image :Name="cropperName" @uploadImgSuccess="handleUploadSuccess" ref="child">
</cropper-image>
</el-dialog>
</div>
@ -190,6 +167,7 @@ export default {
],
imageUrl: null,
startDate: null,
endDate:null,
url: '',
upLoadData: {
guidCode: ''
@ -199,6 +177,24 @@ export default {
isUpdate: false
}
},
watch: {
//
startDate(newVal, oldVal) {
if (this.form.examType == 2 && this.endDate) {
this.validateTimeRange();
}
},
endDate(newVal, oldVal) {
if (this.form.examType == 2 && this.startDate) {
this.validateTimeRange();
}
},
'form.examType'(newVal, oldVal) {
if (newVal == 2 && this.startDate && this.endDate) {
this.validateTimeRange();
}
}
},
created() {
const s_width = document.body.clientWidth
if (s_width < 1000) {
@ -221,6 +217,8 @@ export default {
init_data(contentdata, choicelist) {
this.isUpdate = false
if (contentdata.examCode !== undefined && contentdata.examCode !== null) {
contentdata.examType=contentdata.examType||1;
contentdata.examTimes=contentdata.examTimes||1;
this.form = contentdata
if (this.form.pictureUrl !== undefined && this.form.pictureUrl !== null) {
this.imageUrl = this.hosturl + this.form.pictureUrl
@ -287,7 +285,12 @@ export default {
const addminute = Number(timeitem[1]) * 60 * 1000
const datestr = dateRemoveSeconds(new Date(this.startDate))
this.form.startTime = Number(new Date(datestr).getTime())
if(this.form.examType==1){
this.form.endTime = this.form.startTime + addhour + addminute
}else{
const dateEnd=dateRemoveSeconds(new Date(this.endDate))
this.form.endTime = Number(new Date(dateEnd).getTime())
}
},
getData() {
if (this.onCheck()) {
@ -302,6 +305,13 @@ export default {
},
saveData() {
if (this.onCheck()) {
//
if (this.form.examType == 2) {
if (!this.validateTimeRange()) {
return false;
}
}
this.set_time()
updateExamtask(this.form).then(response => {
this.msgSuccess("修改成功");
@ -348,6 +358,22 @@ export default {
return false
}
//
if (this.form.examType == 2) {
if (this.endDate === undefined || this.endDate === null) {
this.$message.error('需要输入考试结束时间')
return false
}
const startDateTime = new Date(this.startDate).getTime();
const endDateTime = new Date(this.endDate).getTime();
if (startDateTime >= endDateTime) {
this.$message.error('开始时间不能晚于或等于结束时间')
return false
}
}
if (this.form.examDuration === undefined || this.form.examDuration === null) {
this.$message.error('需要输入考试时长')
return false
@ -371,6 +397,19 @@ export default {
this.imageUrl = this.hosturl + data.photoUrl
this.form.pictureUrl = data.photoUrl
this.cropperModel = false
},
//
validateTimeRange() {
if (this.startDate && this.endDate) {
const startDateTime = new Date(this.startDate).getTime();
const endDateTime = new Date(this.endDate).getTime();
if (startDateTime >= endDateTime) {
this.$message.error('开始时间不能晚于或等于结束时间');
return false;
}
}
return true;
}
}
};
@ -403,9 +442,11 @@ export default {
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409eff;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
@ -415,11 +456,10 @@ export default {
text-align: center;
background-color: #fff;
}
.avatar {
width: 128px;
height: 128px;
display: block;
}
</style>

View File

@ -45,16 +45,43 @@
<span v-else> ...</span>
</el-button>
</el-form-item>
<el-form-item style="width:100%;">
<el-button
size="medium"
type="success"
style="width:100%;"
@click.native.prevent="showWechatLogin"
>
微信扫码登录
</el-button>
</el-form-item>
</el-form>
<!-- 底部 -->
<div class="el-login-footer">
<span>Copyright © 2022 All Rights Reserved.</span>
</div>
<!-- 微信登录对话框 -->
<el-dialog
title="微信扫码登录"
:visible.sync="wechatLoginVisible"
width="300px"
:before-close="handleWechatLoginClose">
<div style="text-align: center;">
<img :src="wechatQrCode" alt="微信二维码" style="width: 200px; height: 200px;" v-if="wechatQrCode">
<div v-else>...</div>
<p style="margin-top: 10px;">请使用微信扫描二维码登录</p>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="handleWechatLoginClose"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { getCodeImg } from "@/api/login";
import { generateWechatQrCode, checkWechatLoginStatus, wechatLogin } from "@/api/wechat";
import Cookies from "js-cookie";
import { encrypt, decrypt } from '@/utils/jsencrypt'
// import { encode, decode } from '@/utils/base64'
@ -65,7 +92,20 @@ export default {
return {
codeUrl: "",
cookiePassword: "",
//
loginForm: {
username: "",
password: "",
rememberMe: false,
code: "",
uuid: ""
},
//
wechatLoginVisible: false,
wechatQrCode: "",
wechatLoginId: "",
wechatCheckTimer: null,
wechatLoginForm: {
username: null,
password: null,
rememberMe: false,
@ -145,6 +185,106 @@ export default {
});
}
});
},
//
showWechatLogin() {
this.wechatLoginVisible = true;
this.generateWechatQrCode();
},
//
generateWechatQrCode() {
generateWechatQrCode().then(res => {
if (res.code === 200) {
this.wechatQrCode = res.data.qrCodeImage;
this.wechatLoginId = res.data.loginId;
//
this.startCheckWechatLoginStatus();
} else {
this.$message.error("生成二维码失败: " + res.msg);
}
}).catch(error => {
this.$message.error("生成二维码失败: " + error.message);
});
},
//
startCheckWechatLoginStatus() {
//
if (this.wechatCheckTimer) {
clearInterval(this.wechatCheckTimer);
}
// 2
this.wechatCheckTimer = setInterval(() => {
this.checkWechatLoginStatus();
}, 2000);
},
//
checkWechatLoginStatus() {
if (!this.wechatLoginId) return;
checkWechatLoginStatus(this.wechatLoginId).then(res => {
if (res.code === 200) {
const status = res.data.status;
if (status === "2") { //
this.handleWechatLoginSuccess();
} else if (status === "3") { //
this.handleWechatLoginExpired();
}
}
}).catch(error => {
console.error("检查登录状态失败:", error);
});
},
//
handleWechatLoginSuccess() {
//
if (this.wechatCheckTimer) {
clearInterval(this.wechatCheckTimer);
this.wechatCheckTimer = null;
}
//
wechatLogin(this.wechatLoginId).then(res => {
if (res.code === 200) {
//
this.$store.dispatch("GetInfo").then(() => {
this.$router.push({ path: this.redirect || "/" }).catch(() => {});
});
} else {
this.$message.error("微信登录失败: " + res.msg);
}
}).catch(error => {
this.$message.error("微信登录失败: " + error.message);
});
},
//
handleWechatLoginExpired() {
//
if (this.wechatCheckTimer) {
clearInterval(this.wechatCheckTimer);
this.wechatCheckTimer = null;
}
this.$message.warning("二维码已过期,请重新获取");
this.wechatQrCode = "";
this.wechatLoginId = "";
},
//
handleWechatLoginClose() {
this.wechatLoginVisible = false;
//
if (this.wechatCheckTimer) {
clearInterval(this.wechatCheckTimer);
this.wechatCheckTimer = null;
}
this.wechatQrCode = "";
this.wechatLoginId = "";
}
}
};

View File

@ -2,89 +2,8 @@
<div>
<div v-if="showUi === 1">
<div class="welcome-panel">
<el-row :gutter="20">
<el-col :span="12">
<div v-if = "isRun">
<div class="questions-panel">
<div class= "content_col">
<div class = "title_panel">
<div class = "photo-area">
<img class ="title-photo" :src="hosturl + examTitle.pictureUrl"/>
</div>
<div class = "describe-area">
<div class = "title-name">{{examTitle.examName}}</div>
<div class = "title-describe">
<div class = "describe-text">{{examTitle.examDescribe}}</div>
<div class="create-time">{{ dateFormat(examTitle.createTime) }}</div>
</div>
</div>
</div>
<div class="date-panel">
<div>
<el-statistic title="考试开始时间">
<template slot="prefix">
<i class="el-icon-date" style="color: blue"></i>
</template>
<template slot="formatter"> {{startTimeText}} </template>
</el-statistic>
</div>
<div>
<el-statistic title="考试结束时间">
<template slot="prefix">
<i class="el-icon-date" style="color: green"></i>
</template>
<template slot="formatter"> {{endTimeText}} </template>
</el-statistic>
</div>
<div>
<el-statistic title="考试时长">
<template slot="prefix">
<i class="el-icon-timer" style="color: red"></i>
</template>
<template slot="formatter"> {{examTitle.examDuration}} </template>
</el-statistic>
</div>
</div>
<div class="score-panel">
<div>
<el-statistic title="总分数">
<template slot="prefix">
<i class="el-icon-monitor" style="color: blue"></i>
</template>
<template slot="formatter"> {{examTitle.questionsScore}} </template>
</el-statistic>
</div>
<div>
<el-statistic title="判断题数">
<template slot="prefix">
<i class="el-icon-document-checked" style="color: blue"></i>
</template>
<template slot="formatter"> {{examTitle.judgeNumber}} </template>
</el-statistic>
</div>
<div>
<el-statistic title="单选题数">
<template slot="prefix">
<i class="el-icon-folder-checked" style="color: blue"></i>
</template>
<template slot="formatter"> {{examTitle.radioNumber}} </template>
</el-statistic>
</div>
<div>
<el-statistic title="多选题数">
<template slot="prefix">
<i class="el-icon-folder-checked" style="color: blue"></i>
</template>
<template slot="formatter"> {{examTitle.choiceNumber}} </template>
</el-statistic>
</div>
</div>
</div>
</div>
</div>
<div v-else class = "show-msg">当前无考试</div>
</el-col>
<el-col :span="12">
<el-row>
<el-col :span="24">
<div class="readme-panel">
<div class="readme-title">
<p>在线考试说明:</p>
@ -97,24 +16,109 @@
</el-col>
</el-row>
<el-divider></el-divider>
<div v-if = "isRun">
<div v-if = "!isStart">
<el-statistic
ref="statistic"
@finish="runStart"
format="HH:mm:ss"
:value="currentTime"
prefix="距考试开始还有:"
:value-style="statisticStyle"
time-indices
>
<el-row :gutter="20">
<el-col :span="12" v-for="(item, idx) in examList" :key="idx">
<div class="questions-panel">
<div class="content_col">
<div class="title_panel">
<div class="photo-area">
<img class="title-photo" :src="hosturl + item.pictureUrl" />
</div>
<div class="describe-area">
<div class="title-name">{{ item.examName }}</div>
<div class="title-describe">
<div class="describe-text">{{ item.examDescribe }}</div>
<div class="create-time">{{ dateFormat(item.createTime) }}</div>
</div>
</div>
</div>
<div class="date-panel">
<div>
<el-statistic title="考试开始时间">
<template slot="prefix">
<i class="el-icon-date" style="color: blue"></i>
</template>
<template slot="formatter"> {{ dtFormat(item.startTime) }} </template>
</el-statistic>
</div>
<div>
<el-statistic title="考试结束时间">
<template slot="prefix">
<i class="el-icon-date" style="color: green"></i>
</template>
<template slot="formatter"> {{ dtFormat( item.endTime) }} </template>
</el-statistic>
</div>
<div>
<el-statistic title="考试时长">
<template slot="prefix">
<i class="el-icon-timer" style="color: red"></i>
</template>
<template slot="formatter"> {{ item.examDuration }} </template>
</el-statistic>
</div>
</div>
<div class="score-panel">
<div>
<el-statistic title="总分数">
<template slot="prefix">
<i class="el-icon-monitor" style="color: blue"></i>
</template>
<template slot="formatter"> {{ item.questionsScore }} </template>
</el-statistic>
</div>
<div>
<el-statistic title="判断题数">
<template slot="prefix">
<i class="el-icon-document-checked" style="color: blue"></i>
</template>
<template slot="formatter"> {{ item.judgeNumber }} </template>
</el-statistic>
</div>
<div>
<el-statistic title="单选题数">
<template slot="prefix">
<i class="el-icon-folder-checked" style="color: blue"></i>
</template>
<template slot="formatter"> {{ item.radioNumber }} </template>
</el-statistic>
</div>
<div>
<el-statistic title="多选题数">
<template slot="prefix">
<i class="el-icon-folder-checked" style="color: blue"></i>
</template>
<template slot="formatter"> {{ item.choiceNumber }} </template>
</el-statistic>
</div>
</div>
<el-divider></el-divider>
<div v-if="item.examType==1">
<!-- <div v-if="!isStart">
<el-statistic ref="statistic" @finish="runStart(item)" format="HH:mm:ss" :value="item.currentTime"
prefix="距考试开始还有:" :value-style="statisticStyle" time-indices>
</el-statistic>
</div> -->
<div class="button-area">
<span class="tips-text">考试已经开始点击按钮进入</span>
<el-button type="success" class="into-button" @click="doEnter(item)"></el-button>
</div>
</div>
<div v-else class="button-area">
<span class="tips-text">考试已经开始点击按钮进入</span>
<el-button type="success" class = "into-button" @click = "doEnter">进入考试</el-button>
<el-button type="success" class="into-button" @click="doEnter(item)"></el-button>
</div>
</div>
</div>
</el-col>
</el-row>
</div>
</div>
<div v-else-if="showUi === 2">
@ -136,6 +140,7 @@ export default {
},
data() {
return {
examList: [],
examTitle: {},
examStartTime: null,
currentDate: null,
@ -166,11 +171,13 @@ export default {
methods: {
/** 查询题目列表 */
getData() {
getTitle(this.$store.state.user.userCode).then(response => {
getTitle().then(response => {
debugger
if (response.data !== undefined && response.data !== null) {
this.examTitle = response.data
this.isRun = true
this.setShow()
this.examList = response.data;
//this.examTitle = response.data[0]
//this.isRun = true
//this.setShow()
} else {
this.isRun = false
this.msgSuccess("当天没有考试或者考试已结束");
@ -200,7 +207,10 @@ export default {
}
},
doEnter () {
doEnter(item) {
item.examTimes="EXAM-"+ +new Date();
this.examTitle = item
this.setShow()
this.handleEnter()
},
handleEnter() {
@ -213,7 +223,10 @@ export default {
},
dateFormat(str) {
return dateTextToDateString(str)
return this.$dt(str).format("YYYY-MM-DD")
},
dtFormat(str) {
return this.$dt(str).format("YYYY-MM-DD HH:mm:ss")
}
}
}
@ -279,7 +292,6 @@ export default {
-webkit-box-orient: vertical;
padding-left: 0.8rem;
width: 100%
}
.title-name {

View File

@ -361,6 +361,7 @@ export default {
const saveQuestion = {
examCode: questionData.examCode,
examTimes:this.examData.examTimes,
userCode: this.$store.state.user.userCode,
questionsCode: questionData.questionsCode,
questionsNumber: questionData.questionsNumber,