Explorar o código

Merge branch 'chuanyin-2020-v1.0' into chuanyin-2020-v2.0

xiaof %!s(int64=4) %!d(string=hai) anos
pai
achega
9a69d71e8d

+ 2 - 1
.gitignore

@@ -1,4 +1,5 @@
 /.idea
 /logs
 /stmms-ms-main/src/main/resources/static
-stmms-ms-**.iml
+stmms-ms-**.iml
+/*/target

+ 572 - 0
sql/美术阅卷改版-表结构20200905.sql

@@ -0,0 +1,572 @@
+-- MySQL dump 10.13  Distrib 5.7.12, for Win64 (x86_64)
+--
+-- Host: localhost    Database: stmms-ms-zj-1
+-- ------------------------------------------------------
+-- Server version	5.7.17-log
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `attachment`
+--
+
+DROP TABLE IF EXISTS `attachment`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `attachment` (
+  `id` bigint(64) NOT NULL AUTO_INCREMENT,
+  `work_id` bigint(20) DEFAULT NULL,
+  `subject` varchar(10) DEFAULT NULL,
+  `exam_number` varchar(20) DEFAULT NULL,
+  `file_path_local` varchar(512) NOT NULL,
+  `file_name` varchar(128) NOT NULL,
+  `file_type` varchar(8) DEFAULT NULL,
+  `file_ext` varchar(16) DEFAULT NULL,
+  `bucket` varchar(64) NOT NULL,
+  `object_key` varchar(128) NOT NULL,
+  `oss_name` varchar(500) NOT NULL,
+  `oss_status` varchar(20) NOT NULL,
+  `oss_fail_msg` varchar(500) DEFAULT NULL COMMENT '上传oss失败原因',
+  `delete_status` varchar(20) DEFAULT NULL,
+  `time` datetime NOT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `change_level`
+--
+
+DROP TABLE IF EXISTS `change_level`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `change_level` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `work_id` bigint(20) DEFAULT NULL,
+  `subject` varchar(50) DEFAULT NULL,
+  `paper_id` bigint(20) DEFAULT NULL,
+  `original_level` varchar(45) DEFAULT NULL COMMENT '原档位',
+  `suggest_stage` varchar(45) DEFAULT NULL COMMENT '建议档位',
+  `audit_status` tinyint(1) DEFAULT NULL COMMENT '改档审核:0-申请,1-同意,2-不同意',
+  `create_id` bigint(20) DEFAULT NULL COMMENT '申请改档用户id',
+  `create_date` datetime DEFAULT NULL COMMENT '申请改档时间',
+  `audit_id` bigint(20) DEFAULT NULL COMMENT '审核用户id',
+  `audit_date` datetime DEFAULT NULL COMMENT '审核时间',
+  `suggest_level` varchar(255) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='改档记录表';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `exam_question`
+--
+
+DROP TABLE IF EXISTS `exam_question`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `exam_question` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `area_code` varchar(255) CHARACTER SET utf8mb4 NOT NULL,
+  `area_name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `name` varchar(255) CHARACTER SET utf8mb4 NOT NULL,
+  `subject` varchar(50) CHARACTER SET utf8mb4 NOT NULL,
+  `work_id` bigint(20) NOT NULL,
+  `is_test` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否试评,0:不是,1:数据已导入,2:试评中',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=179 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `exam_score_prop`
+--
+
+DROP TABLE IF EXISTS `exam_score_prop`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `exam_score_prop` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
+  `subject` varchar(50) DEFAULT NULL COMMENT '科目',
+  `exclude` varchar(100) DEFAULT NULL COMMENT '打分阶段配置过滤档位(可选一个或多个档位,多个档位用","号隔开)',
+  `task_sort` varchar(50) DEFAULT NULL COMMENT '打分阶段配置档位排序规则(可选random/paper,为paper时,score.level.exclude置为空)',
+  `enable` bit(1) DEFAULT b'0' COMMENT '打分阶段配置是否启用(为false则不启用打分阶段分档),0:不启用,1:启用',
+  `work_id` bigint(20) DEFAULT NULL COMMENT '工作区id',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='考试打分配置';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `inspect_range`
+--
+
+DROP TABLE IF EXISTS `inspect_range`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `inspect_range` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `condition` int(11) DEFAULT NULL,
+  `enabled` bit(1) DEFAULT NULL,
+  `student_count` int(11) DEFAULT NULL,
+  `type` varchar(255) DEFAULT NULL,
+  `work_id` bigint(20) DEFAULT NULL,
+  `active` bit(1) NOT NULL,
+  `editable` bit(1) NOT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `inspect_student`
+--
+
+DROP TABLE IF EXISTS `inspect_student`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `inspect_student` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `exam_number` varchar(255) NOT NULL,
+  `inspect_range_id` bigint(20) NOT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `inspect_task`
+--
+
+DROP TABLE IF EXISTS `inspect_task`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `inspect_task` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `created_on` datetime DEFAULT NULL,
+  `inspect_range_id` bigint(20) NOT NULL,
+  `marker_id` bigint(20) NOT NULL,
+  `marker_name` varchar(50) NOT NULL,
+  `question_id` bigint(20) DEFAULT NULL,
+  `subject` varchar(50) DEFAULT NULL,
+  `updated_on` datetime DEFAULT NULL,
+  `work_id` bigint(20) NOT NULL,
+  `paper_id` bigint(20) NOT NULL,
+  `level` varchar(255) DEFAULT NULL,
+  `score` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  KEY `FK4e9mfahf522t4ej4y4yd065dh` (`paper_id`) USING BTREE,
+  CONSTRAINT `FK4e9mfahf522t4ej4y4yd065dh` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`),
+  CONSTRAINT `inspect_task_ibfk_1` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`),
+  CONSTRAINT `inspect_task_ibfk_2` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`),
+  CONSTRAINT `inspect_task_ibfk_3` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`),
+  CONSTRAINT `inspect_task_ibfk_4` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`),
+  CONSTRAINT `inspect_task_ibfk_5` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`),
+  CONSTRAINT `inspect_task_ibfk_6` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`),
+  CONSTRAINT `inspect_task_ibfk_7` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `level`
+--
+
+DROP TABLE IF EXISTS `level`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `level` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `code` varchar(50) CHARACTER SET utf8mb4 NOT NULL,
+  `interval_score` int(11) NOT NULL,
+  `level_type` int(11) DEFAULT NULL,
+  `level_value` int(11) NOT NULL,
+  `max_score` int(11) NOT NULL,
+  `min_score` int(11) NOT NULL,
+  `pt` int(11) NOT NULL,
+  `score_list` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `weight` int(11) NOT NULL,
+  `work_id` bigint(20) DEFAULT NULL,
+  `kdpt` int(11) NOT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE KEY `idx_level_workId_code` (`work_id`,`code`) USING BTREE,
+  CONSTRAINT `FK3km0g7jbkt78oj20csqeh26f2` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`),
+  CONSTRAINT `level_ibfk_1` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`),
+  CONSTRAINT `level_ibfk_2` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`),
+  CONSTRAINT `level_ibfk_3` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`),
+  CONSTRAINT `level_ibfk_4` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`),
+  CONSTRAINT `level_ibfk_5` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`),
+  CONSTRAINT `level_ibfk_6` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`),
+  CONSTRAINT `level_ibfk_7` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=155 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `mark_log`
+--
+
+DROP TABLE IF EXISTS `mark_log`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `mark_log` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
+  `create_user_id` bigint(20) DEFAULT NULL COMMENT '操作人id',
+  `create_user_name` varchar(100) DEFAULT NULL COMMENT '操作人名字',
+  `create_role` varchar(50) DEFAULT NULL COMMENT '操作人角色',
+  `subject` varchar(50) DEFAULT NULL COMMENT '科目',
+  `exam_number` varchar(50) DEFAULT NULL COMMENT '准考证号',
+  `student_name` varchar(100) DEFAULT NULL COMMENT '学生姓名',
+  `login_time` datetime DEFAULT NULL COMMENT '登录时间(采集专用)',
+  `logout_time` datetime DEFAULT NULL COMMENT '登出时间(采集专用)',
+  `oper_type` int(11) DEFAULT NULL COMMENT '操作类型,1:分档,2:打分,3:回评档位,4:回评分数,5:档位打回,6:档位打回回评,7:一键定档,8:标准卷设置',
+  `oper_data_before` varchar(255) DEFAULT NULL COMMENT '操作前数据',
+  `oper_data_after` varchar(255) DEFAULT NULL COMMENT '操作后数据',
+  `create_time` datetime DEFAULT NULL COMMENT '操作时间',
+  `work_id` bigint(20) DEFAULT NULL COMMENT '考区id',
+  `paper_id` bigint(20) DEFAULT NULL COMMENT '试卷id',
+  `remark` varchar(500) DEFAULT NULL COMMENT '备注',
+  `stage` bigint(20) DEFAULT NULL COMMENT '试卷阶段,0:初始,1:分档,2:打分',
+  `work_name` varchar(255) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  KEY `union_001_index` (`create_user_id`,`oper_type`,`subject`,`exam_number`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=243 DEFAULT CHARSET=utf8 COMMENT='操作日志';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `mark_subject`
+--
+
+DROP TABLE IF EXISTS `mark_subject`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `mark_subject` (
+  `id` varchar(50) CHARACTER SET utf8mb4 NOT NULL,
+  `collect_config` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `stage` int(11) DEFAULT NULL,
+  `total_score` int(11) NOT NULL,
+  `work_id` bigint(20) DEFAULT NULL,
+  `sample_count` int(11) NOT NULL DEFAULT '100',
+  `is_test` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否试评,0:不是,1:数据已导入,2:试评中',
+  `is_formal` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否正评,0:不是,1:是',
+  `all_level` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否全部根据档位分配完,0:不是,1:是',
+  `enable` tinyint(1) DEFAULT '1' COMMENT '是否启用 0:禁用 1:启用',
+  PRIMARY KEY (`id`) USING BTREE,
+  KEY `FK1tvc2mil1ebqgt08912t4hxqw` (`work_id`) USING BTREE,
+  CONSTRAINT `FK1tvc2mil1ebqgt08912t4hxqw` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`),
+  CONSTRAINT `mark_subject_ibfk_1` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`),
+  CONSTRAINT `mark_subject_ibfk_2` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`),
+  CONSTRAINT `mark_subject_ibfk_3` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`),
+  CONSTRAINT `mark_subject_ibfk_4` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`),
+  CONSTRAINT `mark_subject_ibfk_5` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`),
+  CONSTRAINT `mark_subject_ibfk_6` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`),
+  CONSTRAINT `mark_subject_ibfk_7` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `mark_task`
+--
+
+DROP TABLE IF EXISTS `mark_task`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `mark_task` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `created_on` datetime DEFAULT NULL,
+  `is_rejected` bit(1) NOT NULL,
+  `level_value` int(11) DEFAULT NULL,
+  `marker_id` bigint(20) NOT NULL,
+  `marker_name` varchar(50) CHARACTER SET utf8mb4 NOT NULL,
+  `origin_level` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `question_id` bigint(20) DEFAULT NULL,
+  `result` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `stage` int(11) NOT NULL,
+  `subject` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `updated_on` datetime DEFAULT NULL,
+  `work_id` bigint(20) NOT NULL,
+  `paper_id` bigint(20) NOT NULL,
+  `random_seq` int(11) DEFAULT NULL,
+  `secret_number` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+  `random_seq_new` bigint(20) DEFAULT NULL COMMENT '随机号',
+  `is_active` bit(1) DEFAULT b'0' COMMENT '是否激活',
+  `is_test` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否试评,0:不是,1:数据已导入,2:试评中',
+  `batch_no` bigint(45) DEFAULT NULL COMMENT '批次号',
+  `is_change_stage` tinyint(1) DEFAULT NULL COMMENT '是否改档',
+  `serial_number` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '叫号序号',
+  `display_number` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  KEY `idx_mark_task_paper_id` (`paper_id`) USING BTREE,
+  KEY `question_id` (`question_id`,`marker_id`,`stage`,`result`) USING BTREE,
+  CONSTRAINT `FKa6xqlu9ml2e47x1o2u2yec7vm` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`),
+  CONSTRAINT `mark_task_ibfk_1` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`),
+  CONSTRAINT `mark_task_ibfk_2` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`),
+  CONSTRAINT `mark_task_ibfk_3` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`),
+  CONSTRAINT `mark_task_ibfk_4` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`),
+  CONSTRAINT `mark_task_ibfk_5` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`),
+  CONSTRAINT `mark_task_ibfk_6` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`),
+  CONSTRAINT `mark_task_ibfk_7` FOREIGN KEY (`paper_id`) REFERENCES `paper` (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `mark_task_job`
+--
+
+DROP TABLE IF EXISTS `mark_task_job`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `mark_task_job` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
+  `data_object` varchar(4000) DEFAULT NULL COMMENT 'object',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  `status` bit(1) DEFAULT b'0' COMMENT '状态,0:未记录,1:已记录',
+  `work_id` bigint(20) DEFAULT NULL COMMENT '工作区id',
+  `version` int(11) DEFAULT '0' COMMENT '版本号',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=latin1 COMMENT='定时任务调度表';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `mark_user`
+--
+
+DROP TABLE IF EXISTS `mark_user`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `mark_user` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `enabled` bit(1) NOT NULL,
+  `last_login_time` datetime DEFAULT NULL,
+  `login_name` varchar(50) CHARACTER SET utf8mb4 NOT NULL,
+  `name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `password` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `pw_changed_count` int(11) NOT NULL,
+  `session_id` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `group_id` bigint(20) DEFAULT NULL,
+  `mark_right` int(11) DEFAULT NULL,
+  `role` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `subject` varchar(50) CHARACTER SET utf8mb4 NOT NULL,
+  `work_id` bigint(20) NOT NULL,
+  `inspect_sc` bit(1) DEFAULT NULL,
+  `inspect_sm` bit(1) DEFAULT NULL,
+  `inspect_sx` bit(1) DEFAULT NULL,
+  `weight` double DEFAULT NULL,
+  `one_click_level` bit(1) DEFAULT b'0' COMMENT '科组长是否开启一键定档',
+  `standard_volume` bit(1) NOT NULL,
+  `level_callback` bit(1) NOT NULL,
+  `display_count` int(1) DEFAULT NULL COMMENT '显示数量:4-4张显示,6-6张显示,8-8张显示',
+  `default_account` tinyint(1) DEFAULT NULL COMMENT '是否默认账号(采集账号)',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE KEY `UK_cyf7k1neuij8lma85x19omo07` (`login_name`) USING BTREE,
+  KEY `FKinr4i9gbxj9njwo82s7cc89q5` (`group_id`) USING BTREE,
+  CONSTRAINT `FKinr4i9gbxj9njwo82s7cc89q5` FOREIGN KEY (`group_id`) REFERENCES `marker_group` (`id`),
+  CONSTRAINT `mark_user_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `marker_group` (`id`),
+  CONSTRAINT `mark_user_ibfk_2` FOREIGN KEY (`group_id`) REFERENCES `marker_group` (`id`),
+  CONSTRAINT `mark_user_ibfk_3` FOREIGN KEY (`group_id`) REFERENCES `marker_group` (`id`),
+  CONSTRAINT `mark_user_ibfk_4` FOREIGN KEY (`group_id`) REFERENCES `marker_group` (`id`),
+  CONSTRAINT `mark_user_ibfk_5` FOREIGN KEY (`group_id`) REFERENCES `marker_group` (`id`),
+  CONSTRAINT `mark_user_ibfk_6` FOREIGN KEY (`group_id`) REFERENCES `marker_group` (`id`),
+  CONSTRAINT `mark_user_ibfk_7` FOREIGN KEY (`group_id`) REFERENCES `marker_group` (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=98 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `marker_group`
+--
+
+DROP TABLE IF EXISTS `marker_group`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `marker_group` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `subject` varchar(50) CHARACTER SET utf8mb4 NOT NULL,
+  `work_id` bigint(20) NOT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `paper`
+--
+
+DROP TABLE IF EXISTS `paper`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `paper` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `area_code` varchar(50) CHARACTER SET utf8mb4 NOT NULL,
+  `exam_number` varchar(50) CHARACTER SET utf8mb4 NOT NULL,
+  `idx` bigint(20) DEFAULT NULL,
+  `is_arbitrated` bit(1) NOT NULL,
+  `is_manual` bit(1) NOT NULL,
+  `is_rejected` bit(1) NOT NULL,
+  `is_tagged` bit(1) NOT NULL,
+  `level` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `mark_by_leader` bit(1) NOT NULL,
+  `marked_logic` bit(1) NOT NULL,
+  `question_id` bigint(20) NOT NULL,
+  `question_name` varchar(255) CHARACTER SET utf8mb4 NOT NULL,
+  `redo_level` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `score` double DEFAULT NULL,
+  `secret_number` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `student_name` varchar(50) CHARACTER SET utf8mb4 NOT NULL,
+  `subject` varchar(50) CHARACTER SET utf8mb4 NOT NULL,
+  `updated_on` datetime DEFAULT NULL,
+  `uploaded_count` int(11) NOT NULL,
+  `uploaded_on` datetime DEFAULT NULL,
+  `work_id` bigint(20) NOT NULL,
+  `inspect_range` bigint(20) DEFAULT NULL,
+  `inspect_score` double DEFAULT NULL,
+  `source_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+  `inspect_level` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+  `inspector` bigint(20) DEFAULT NULL,
+  `is_sample` bit(1) NOT NULL,
+  `sheet_md5` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+  `slice_md5` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+  `random_seq` bigint(20) DEFAULT NULL COMMENT '随机号',
+  `is_missing` bit(1) NOT NULL,
+  `exam_room` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+  `is_test` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否试评,0:不是,1:数据已导入,2:试评中',
+  `is_active` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否激活',
+  `batch_no` bigint(45) DEFAULT NULL COMMENT '批次号',
+  `score_batch_no` bigint(45) DEFAULT NULL COMMENT '打分任务发布批次号',
+  `is_shift` bit(1) DEFAULT b'0' COMMENT '是否改档',
+  `is_shift_score` bit(1) DEFAULT b'0' COMMENT '是否改档打分',
+  `is_one_click` bit(1) DEFAULT b'0' COMMENT '是否一键定档',
+  `is_rejected_by_leader` bit(1) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  KEY `idx_paper_index` (`idx`) USING BTREE,
+  KEY `idx_paper_exam_number` (`exam_number`) USING BTREE,
+  KEY `idx_paper_area_code` (`area_code`) USING BTREE,
+  KEY `idx_paper_student_name` (`student_name`) USING BTREE,
+  KEY `is_missing` (`is_missing`,`is_test`,`batch_no`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=234 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `param_setting`
+--
+
+DROP TABLE IF EXISTS `param_setting`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `param_setting` (
+  `id` bigint(10) NOT NULL AUTO_INCREMENT,
+  `work_id` bigint(10) DEFAULT NULL COMMENT '工作id',
+  `package_scan` tinyint(1) DEFAULT NULL COMMENT '是否整包扫描1:是 0:否',
+  `image_encrypt` tinyint(1) DEFAULT NULL COMMENT '是否加密1:是 0:否',
+  `name_rule` tinyint(1) DEFAULT NULL COMMENT '图片命名规则(1:考号命名、0:随机码命名)',
+  `paper_stage` tinyint(1) DEFAULT NULL COMMENT '试卷档位状态(1:已知、0:未知)',
+  `deviation` int(2) DEFAULT NULL COMMENT '仲裁档位差',
+  `auto_callback` tinyint(1) DEFAULT NULL COMMENT '是否自动打回(1:是、0:否)',
+  `majority` tinyint(1) DEFAULT NULL COMMENT '是否过半定档(1:是、0:否)',
+  `cumulative_error` int(3) DEFAULT NULL COMMENT '打回累计误差',
+  `level_show_all_paper` tinyint(1) DEFAULT NULL COMMENT '分档阶段阅卷员是否显示所有试卷(1:是、0:否)',
+  `round_up` tinyint(1) DEFAULT NULL COMMENT '分数处理方式(1:四舍五入、0:非零进一)',
+  `change_stage` tinyint(1) DEFAULT NULL COMMENT '改档及改档打分(1:显示、0:不显示)',
+  `score_show_all_paper` tinyint(1) DEFAULT NULL COMMENT '打分阶段阅卷员是否显示所有试卷(1:是、0:否)',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 COMMENT='参数设置';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `shiwai`
+--
+
+DROP TABLE IF EXISTS `shiwai`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `shiwai` (
+  `姓名` varchar(255) DEFAULT NULL,
+  `性别` varchar(255) DEFAULT NULL,
+  `地区` varchar(255) DEFAULT NULL,
+  `报名号(按顺序编号)` varchar(255) DEFAULT NULL,
+  `准考证号` varchar(255) DEFAULT NULL,
+  `考场号` varchar(255) DEFAULT NULL,
+  `座位号` varchar(255) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `student`
+--
+
+DROP TABLE IF EXISTS `student`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `student` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `area_code` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `area_name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `exam_number` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `exam_room` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `school` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '学校',
+  `is_absent` bit(1) NOT NULL,
+  `name` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `upload_status` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  `work_id` bigint(20) DEFAULT NULL,
+  `source_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+  `is_test` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '是否试评,0:不是,1:数据已导入,2:试评中',
+  `relate_exam_number` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '关联考号',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE KEY `exam_number` (`exam_number`,`work_id`,`is_test`) USING BTREE,
+  KEY `idx_student_name` (`name`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=355 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `task_publish_setting`
+--
+
+DROP TABLE IF EXISTS `task_publish_setting`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `task_publish_setting` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `work_id` bigint(20) DEFAULT NULL,
+  `question_id` bigint(45) DEFAULT NULL COMMENT '考区',
+  `subject` varchar(50) DEFAULT NULL,
+  `code` varchar(45) DEFAULT NULL COMMENT '档位',
+  `total_count` int(11) DEFAULT NULL COMMENT '总数量',
+  `success_count` int(11) DEFAULT NULL COMMENT '已评数量',
+  `wait_count` varchar(45) DEFAULT NULL COMMENT '待评数量',
+  `sort_rule` tinyint(1) DEFAULT NULL COMMENT '排序规则:0-乱序,1-定序',
+  `display_number` tinyint(1) DEFAULT NULL COMMENT '是否显示序号:0-否,1-是',
+  `task_count` int(11) DEFAULT NULL COMMENT '本次任务数',
+  `batch_no` bigint(45) DEFAULT NULL,
+  `publish_count` int(3) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8 COMMENT='发布打分任务';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `work`
+--
+
+DROP TABLE IF EXISTS `work`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `work` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `active` bit(1) NOT NULL,
+  `created_on` date DEFAULT NULL,
+  `name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2020-09-05 17:10:01

+ 6 - 5
stmms-ms-accesscontrol/src/main/java/cn/com/qmth/stmms/ms/accesscontrol/LoginInterceptor.java

@@ -29,17 +29,18 @@ public class LoginInterceptor extends HandlerInterceptorAdapter {
             String[] strs = token.split("#");
             String loginName = strs[1];
             if (loginConfig.adminLoginConfig().getLoginName().equals(loginName)
-                    || loginConfig.inspectionLoginConfig().getLoginName().equals(loginName)) {
+//                    || loginConfig.inspectionLoginConfig().getLoginName().equals(loginName)
+            ) {
                 return true;
             }
 //            else if (loginConfig.clientLoginConfig().getLoginName().equals(loginName)) {
 //                response.sendError(HttpStatus.UNAUTHORIZED.value(), "该账户只能在采集端登录");
 //                return false;
 //            }
-            else if (loginConfig.uploadLoginConfig().getLoginName().equals(loginName)) {
-                response.sendError(HttpStatus.UNAUTHORIZED.value(), "该账户只能在图片客户端登录");
-                return false;
-            }
+//            else if (loginConfig.uploadLoginConfig().getLoginName().equals(loginName)) {
+//                response.sendError(HttpStatus.UNAUTHORIZED.value(), "该账户只能在图片客户端登录");
+//                return false;
+//            }
             AbstractUser user = markUserRepo.findByLoginName(loginName);
             if (Objects.equals(Role.COLLECTOR, ((MarkUser) user).getRole())) {
                 response.sendError(HttpStatus.UNAUTHORIZED.value(), "该账户只能在采集端登录");

+ 7 - 4
stmms-ms-accesscontrol/src/main/java/cn/com/qmth/stmms/ms/accesscontrol/api/AuthApi.java

@@ -48,15 +48,18 @@ public class AuthApi {
 //            domain = markUserRepo.findByLoginName(loginName);
             domain = markUserRepo.findByLoginName(user.getLoginName());
             if (domain == null) {
-                if ((loginConfig.adminLoginConfig().getLoginName().equals(user.getLoginName()) && !loginConfig.adminLoginConfig().getPassword().equals(user.getPassword())) || (loginConfig.inspectionLoginConfig().getLoginName().equals(user.getLoginName()) && !loginConfig.inspectionLoginConfig().getPassword().equals(user.getPassword()))) {
+                if ((loginConfig.adminLoginConfig().getLoginName().equals(user.getLoginName()) && !loginConfig.adminLoginConfig().getPassword().equals(user.getPassword()))
+//                        || (loginConfig.inspectionLoginConfig().getLoginName().equals(user.getLoginName()) && !loginConfig.inspectionLoginConfig().getPassword().equals(user.getPassword()))
+                ) {
                     throw new RuntimeException("用户或密码错误");
                 }
 //                else if (loginConfig.clientLoginConfig().getLoginName().equals(user.getLoginName())) {
 //                    throw new RuntimeException("该账户只能在采集端登录");
 //                }
-                else if (loginConfig.uploadLoginConfig().getLoginName().equals(user.getLoginName())) {
-                    throw new RuntimeException("该账户只能在图片客户端登录");
-                } else {
+//                else if (loginConfig.uploadLoginConfig().getLoginName().equals(user.getLoginName())) {
+//                    throw new RuntimeException("该账户只能在图片客户端登录");
+//                }
+                else {
                     throw new RuntimeException("用户不存在");
                 }
             }

+ 2 - 1
stmms-ms-accesscontrol/src/main/java/cn/com/qmth/stmms/ms/accesscontrol/config/AccessConfig.java

@@ -32,6 +32,7 @@ public class AccessConfig extends WebMvcConfigurerAdapter {
     public void addInterceptors(InterceptorRegistry registry) {
         registry.addInterceptor(loginInterceptor()).addPathPatterns("/api/**").excludePathPatterns("/api/admin/users/login","/api/login","/api/logout","/api/*/password",
                 "/api/user/login", "/api/user/getClientUser", "/api/exam/students", "/api/upload/student/*", "/api/file/image/**", "/api/marklog/saveCollectLog",
-                "/api/file/ms-slice/**", "/api/subject/collect-config", "/api/file/ms-sheet/**", "/api/oss/**", "/api/exam/listStudents/*", "/api/exam/getStudent/*","/api/level/*");
+                "/api/file/ms-slice/**", "/api/subject/collect-config", "/api/file/ms-sheet/**", "/api/oss/**", "/api/exam/listStudents/*", "/api/exam/getStudent/*","/api/level/*",
+                "/api/file/image/getExportData","/api/file/image/exportScorePicturesFromCollect","/api/admin/works","/api/score/missing/*");
     }
 }

+ 2 - 1
stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/api/WorkApi.java

@@ -83,6 +83,8 @@ public class WorkApi {
     @RequestMapping(method = RequestMethod.POST)
     public void create(@RequestBody Work work) {
         workService.save(work);
+        //生成随机数
+        randomUtil.getRandom(work.getId(), false);
     }
 
     /**
@@ -116,7 +118,6 @@ public class WorkApi {
             w.setActive(false);
             if (w.getId().equals(workId)) {
                 w.setActive(true);
-                randomUtil.getRandom(w.getId(), false);
             }
         }
         workRepo.save(works);

+ 272 - 8
stmms-ms-collect/src/main/java/cn/com/qmth/stmms/ms/collect/api/CollectApi.java

@@ -39,6 +39,7 @@ import javax.servlet.http.HttpServletResponse;
 import java.awt.*;
 import java.awt.image.BufferedImage;
 import java.io.*;
+import java.net.URLEncoder;
 import java.security.MessageDigest;
 import java.text.SimpleDateFormat;
 import java.util.List;
@@ -127,6 +128,15 @@ public class CollectApi {
             loginDTO = new LoginDTO();
             loginDTO.setExamId(activeWork.getId());
             loginDTO.setExamName(activeWork.getName());
+        } else if (loginname.equals(loginConfig.adminLoginConfig().getLoginName()) && password.equals(loginConfig.adminLoginConfig().getPassword())) {
+            activeWork = workRepo.findByActiveTrue();
+            if (Objects.isNull(activeWork)) {
+                throw new Exception("没有work");
+            }
+            loginDTO = new LoginDTO();
+            loginDTO.setExamId(activeWork.getId());
+            loginDTO.setExamName(activeWork.getName());
+            loginDTO.setRoleCode("ADMIN");
         } else {
             MarkUser markUser = markUserRepo.findByLoginName(loginname);
             //账号不存在
@@ -240,16 +250,17 @@ public class CollectApi {
 
     @CrossOrigin(maxAge = 3600) //支持跨域
     @RequestMapping(value = "upload/student/{subjectId}", method = RequestMethod.POST)
-    public List<CollectStuDTO> saveStudent(HttpServletRequest request, @PathVariable Integer subjectId,
-                                           CollectStuDTO dto) throws Exception {
+    public CollectStuDTO saveStudent(HttpServletRequest request, @PathVariable Integer subjectId,
+                                     CollectStuDTO dto) throws Exception {
         Subject subject = Subject.values()[subjectId - 1];
         Work activeWork = workRepo.findByActiveTrue();
         List<CollectStuDTO> list = new ArrayList<>();
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
 //        for (CollectStuDTO dto : uploadStudentArray) {
         Student student = studentRepo.findByWorkIdAndRelateExamNumberAndTest(activeWork.getId(), dto.getExamNumber(), String.valueOf(TrialEnum.DEFAULT.getId()));
+        Paper paper = null;
         if (!dto.isAbsent()) {
-            dataUploadService.savePaper(student, subject, dto.isManual(), dto.getLevel());
+            paper = dataUploadService.savePaper(student, subject, dto.isManual(), dto.getLevel());
         }
         //已知档位,更新阶段
         if (Objects.nonNull(dto.getLevel()) && dto.getLevel() != "") {
@@ -260,9 +271,10 @@ public class CollectApi {
             }
         }
         dto.setUploadTime(sdf.format(new Date()));
-        list.add(dto);
-//        }
-        return list;
+        if (paper != null) {
+            dto.setPaperId(paper.getId());
+        }
+        return dto;
     }
 
 //    File srcFile = new File("/Users/king/stmms-ms/static/images/2/SM/1/1901040150.jpg"); //初始文件
@@ -951,7 +963,7 @@ public class CollectApi {
                                     long s3 = System.currentTimeMillis();
                                     LOGGER.info("【{},{}】加水印开始,总耗时:{}秒", examNumber, studentName, (s3 - s2) / 1000);
                                     BufferedImage watermarkImage = createWaterImage(score.intValue() + "分");
-                                    Thumbnails.of(sheetFileTemp).scale(1).watermark(Positions.BOTTOM_CENTER, watermarkImage, 1f).toFile(expFile);
+                                    Thumbnails.of(sheetFileTemp).scale(1f).outputQuality(0.98f).watermark(Positions.BOTTOM_CENTER, watermarkImage, 1f).toFile(expFile);
                                     long s4 = System.currentTimeMillis();
                                     LOGGER.info("【{},{}】加水印结束,总耗时:{}秒", examNumber, studentName, (s4 - s3) / 1000);
                                     sheetFileTemp.delete();
@@ -979,7 +991,7 @@ public class CollectApi {
                                 if (Objects.equals("1", isWatermark)) {
                                     //生成分数水印图片
                                     BufferedImage watermarkImage = createWaterImage(score.intValue() + "分");
-                                    Thumbnails.of(file).scale(1).watermark(Positions.BOTTOM_CENTER, watermarkImage, 1f).toFile(expFile);
+                                    Thumbnails.of(file).scale(1f).outputQuality(0.98f).watermark(Positions.BOTTOM_CENTER, watermarkImage, 1f).toFile(expFile);
                                 }
                             }
                             long end = System.currentTimeMillis();
@@ -1166,6 +1178,258 @@ public class CollectApi {
         return stringJoiner.toString();
     }
 
+    //客户端图片导出,查询需要导出试卷
+    @RequestMapping("/file/image/getExportData")
+    public List<Map<String, Object>> getExportData(@RequestParam Long workId,
+                                                   @RequestParam String imageType,
+                                                   @RequestParam(required = false) Integer startScore,
+                                                   @RequestParam(required = false) Integer endScore) {
+        StringBuffer sql = new StringBuffer();
+        sql.append("SELECT s.id studentId,s.name studentName,s.school, p.work_id workId, p.subject, p.area_code areaCode,s.area_name areaName, p.exam_number examNumber,ms.name subjectName, 0+cast(p.score as char) as score FROM paper p LEFT JOIN student s ON p.work_id = s.work_id AND p.exam_number = s.exam_number left join mark_subject ms on concat(p.work_id,'-', p.subject) = ms.id WHERE p.score is not null and p.work_id = ").append(workId);
+        if (startScore != null && endScore != null) {
+            sql.append(" and p.score >= ").append(startScore);
+            sql.append(" and p.score <= ").append(endScore);
+        }
+        if (startScore != null && endScore == null) {
+            sql.append(" and p.score = ").append(startScore);
+        }
+        if (startScore == null && endScore != null) {
+            sql.append(" and p.score = ").append(endScore);
+        }
+        List<Map<String, Object>> paperList = jdbcTemplate.queryForList(sql.toString());
+        //图片后缀
+        String suffix = ".jpg";
+        String dir,localUrl;
+        if (Objects.equals("1", imageType)) {
+            dir = systemConfig.getSheetDir();
+            localUrl = imageServerConfig.getImageServer() + "/sheet";
+        } else if (Objects.equals("2", imageType)) {
+            dir = systemConfig.getImageDir();
+            localUrl = imageServerConfig.getImageServer() + "/images";
+        } else {
+            throw new RuntimeException("图片类型有误");
+        }
+        if(paperList != null && paperList.size() >0){
+            paperList.stream().map(m->{
+                Long studentId = Long.valueOf(m.get("studentId").toString());
+                String subject = m.get("subject").toString();
+                Subject subject1 = Subject.valueOf(subject);
+                String areaCode = m.get("areaCode").toString();
+                String examNumber = m.get("examNumber").toString();
+                //默认命名为考号
+                String fileName = examNumber;
+                //图片加密、命名规则为随机码的,都是需要md5
+                if (ParamCache.paramMap.get(workId).getNameRule() == 1 || ParamCache.paramMap.get(workId).getImageEncrypt() == 1) {
+                    fileName = MD5Util.getImageRuleMd5(workId, subject1.ordinal(), areaCode, examNumber, studentId);
+                }
+                String filePath = null;
+                if (imageServerConfig.isAliyunOss()) {
+                    StringJoiner ossPath = new StringJoiner("/").add(aliYunOssConfig.getUrl()).add(imageServerConfig.getDir()).add(dir.replace("\\", "/")).add(String.valueOf(workId)).add(subject).add(areaCode);
+                    filePath = ossPath.toString().concat("/").concat(fileName + suffix);
+                } else {
+                    String path = localUrl + File.separator + workId + File.separator + subject1 + File.separator + areaCode;
+                    filePath = path + File.separator + fileName + suffix;
+                }
+                //oss或者本地图片访问路径
+                m.put("url", filePath);
+                return m;
+            }).collect(Collectors.toList());
+
+        }
+        return paperList;
+    }
+
+    //客户端图片导出,单个导出
+    @RequestMapping("/file/image/exportScorePicturesFromCollect")
+    public void getExportData(@RequestParam Long workId,
+                              @RequestParam String imageType,
+                              @RequestParam String isWatermark,
+                              @RequestParam String nameRule,
+                              @RequestParam Long studentId,
+                              @RequestParam String studentName,
+                              @RequestParam String subject,
+                              @RequestParam String areaCode,
+                              @RequestParam String examNumber,
+                              @RequestParam Double score,
+                              @RequestParam Integer idx,
+                              HttpServletRequest request,
+                              HttpServletResponse response) {
+        //图片后缀
+        String suffix = ".jpg";
+
+        try {
+            if (StringUtils.isBlank(imageType)) {
+                throw new RuntimeException("请选择图片类型");
+            }
+            if (StringUtils.isBlank(nameRule)) {
+                throw new RuntimeException("请选择命名规则");
+            }
+
+            InputStream inputStream = null;
+            OutputStream outputStream = null;
+            long start = System.currentTimeMillis();
+            try {
+                Subject subject1 = Subject.valueOf(subject);
+
+                //默认命名为考号
+                String fileName = examNumber;
+                //图片加密、命名规则为随机码的,都是需要md5
+                if (ParamCache.paramMap.get(workId).getNameRule() == 1 || ParamCache.paramMap.get(workId).getImageEncrypt() == 1) {
+                    fileName = MD5Util.getImageRuleMd5(workId, subject1.ordinal(), areaCode, examNumber, studentId);
+                }
+
+                //组装导出目录
+                StringJoiner expSj = new StringJoiner(File.separator);
+                expSj.add(systemConfig.getLocalhostPath()).add("image-export");
+                //原图或者裁切图
+                String imageTypeStr = Objects.equals("1", imageType) ? "sheet" : Objects.equals("2", imageType) ? "images" : "default";
+                //是否水印
+                String waterTypeStr = Objects.equals("1", isWatermark) ? "y" : Objects.equals("0", isWatermark) ? "n" : "default";
+                expSj.add(imageTypeStr.concat("-").concat(waterTypeStr));
+                LOGGER.info("【{},{}】开始导出,参数:图片类型:{},是否有水印:{},命名规则:{}", examNumber, studentName, imageTypeStr, waterTypeStr, Objects.equals(nameRule, "1") ? "考号+姓名" : "流水号");
+                File out = new File(expSj.toString());
+                if (!out.exists()) {
+                    out.mkdirs();
+                }
+                //输出命名
+                String outFileName;
+                if (Objects.equals("1", nameRule)) {
+                    StringJoiner sj = new StringJoiner("-");
+                    sj.add(examNumber).add(studentName);
+                    outFileName = sj.toString();
+                } else if (Objects.equals("2", nameRule)) {
+                    outFileName = String.valueOf(idx);
+                } else {
+                    throw new RuntimeException("命名参数有误");
+                }
+
+                String dir;
+                if (Objects.equals("1", imageType)) {
+                    dir = systemConfig.getSheetDir();
+
+                } else if (Objects.equals("2", imageType)) {
+                    dir = systemConfig.getImageDir();
+                } else {
+                    throw new RuntimeException("图片类型有误");
+                }
+
+                String outFile = expSj.toString() + File.separator + outFileName + suffix;
+                File expFile = null;
+                float outputQuality = Objects.equals("1", imageType) ? 0.98f : Objects.equals("2", imageType) ? 0.99f : 1f;
+                if (imageServerConfig.isAliyunOss()) {
+                    StringJoiner ossSavePath = new StringJoiner("/").add(imageServerConfig.getDir()).add(dir.replace("\\", "/")).add(String.valueOf(workId)).add(subject).add(areaCode);
+                    String saveFileName = fileName + suffix;
+                    String saveFile = ossSavePath.toString().concat("/").concat(saveFileName);
+                    if (Objects.equals("0", isWatermark)) {
+                        expFile = ossUtil.ossDownload(saveFile, outFile);
+                    }
+                    //下载临时原图
+                    if (Objects.equals("1", isWatermark)) {
+                        long s1 = System.currentTimeMillis();
+                        LOGGER.info("【{},{}】下载临时原图开始", examNumber, studentName);
+                        String outSheetFile = expSj.toString() + File.separator + outFileName + "_" + start + suffix;
+                        File sheetFileTemp = ossUtil.ossDownload(saveFile, outSheetFile);
+                        long s2 = System.currentTimeMillis();
+                        LOGGER.info("【{},{}】下载临时原图结束,总耗时:{}秒", examNumber, studentName, (s2 - s1) / 1000);
+                        expFile = new File(outFile);
+                        //生成分数水印图片
+                        long s3 = System.currentTimeMillis();
+                        LOGGER.info("【{},{}】加水印开始,总耗时:{}秒", examNumber, studentName, (s3 - s2) / 1000);
+                        BufferedImage watermarkImage = createWaterImage(score.intValue() + "分");
+                        Thumbnails.of(sheetFileTemp).scale(1f).outputQuality(outputQuality).watermark(Positions.BOTTOM_CENTER, watermarkImage, 0.8f).toFile(expFile);
+                        long s4 = System.currentTimeMillis();
+                        LOGGER.info("【{},{}】加水印结束,总耗时:{}秒", examNumber, studentName, (s4 - s3) / 1000);
+                        sheetFileTemp.delete();
+                    }
+                } else {
+                    String path = dir + File.separator + workId + File.separator + subject1 + File.separator + areaCode;
+                    File file = new File(path + File.separator + fileName + suffix);
+                    expFile = new File(outFile);
+                    if (Objects.equals("0", isWatermark)) {
+                        //读取指定路径下面的文件
+                        inputStream = new FileInputStream(file);
+                        outputStream = new FileOutputStream(expFile);
+                        if (ParamCache.paramMap.get(workId).getImageEncrypt() == 1) {
+                            outputStream = SystemConstant.writeStream(inputStream, outputStream);
+                        } else {
+                            outputStream = SystemConstant.writeStreamFomal(inputStream, outputStream);
+                        }
+                        inputStream.close();
+                        outputStream.flush();
+                        outputStream.close();
+                    }
+                    if (Objects.equals("1", isWatermark)) {
+                        //生成分数水印图片
+                        BufferedImage watermarkImage = createWaterImage(score.intValue() + "分");
+                        Thumbnails.of(file).scale(1f).outputQuality(outputQuality).watermark(Positions.BOTTOM_CENTER, watermarkImage, 1f).toFile(expFile);
+                    }
+                }
+                //返回
+                exportImage(outFileName + suffix, expFile, response, true);
+                long end = System.currentTimeMillis();
+                LOGGER.info("【{},{}】结束导出,总耗时:{}秒", examNumber, studentName, (end - start) / 1000);
+            } catch (Exception e) {
+                e.printStackTrace();
+                LOGGER.info("导出失败:{}", e.getMessage());
+            } finally {
+                try {
+                    //强制将缓存区的数据进行输出
+                    if (Objects.nonNull(outputStream)) {
+                        outputStream.flush();
+                        //关流
+                        outputStream.close();
+                    }
+                    if (Objects.nonNull(inputStream)) {
+                        inputStream.close();
+                    }
+
+                } catch (Exception e) {
+
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    public static void exportImage(String fileName, File file, HttpServletResponse response, boolean isDeleteLocal) {
+        try {
+            try {
+                if (!file.exists()) {
+                    response.sendError(404, "File not found!");
+                }
+
+                BufferedInputStream br = new BufferedInputStream(new FileInputStream(file));
+                byte[] buf = new byte[1024];
+                int len = 0;
+
+                String fName = new String(fileName.getBytes(), "ISO-8859-1");
+
+                response.reset();
+                response.setContentType("image/jpeg");
+                response.setHeader("Content-Disposition", "attachment; filename=" + fName);
+
+                OutputStream outStream = response.getOutputStream();
+
+                while ((len = br.read(buf)) > 0) {
+                    outStream.write(buf, 0, len);
+                }
+
+                br.close();
+                outStream.close();
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally {
+                if(isDeleteLocal){
+                    file.delete();
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
     public static void main(String[] args) throws IOException {
         String msg1 = "90分";
         BufferedImage bi = createWaterImage(msg1);

+ 9 - 0
stmms-ms-collect/src/main/java/cn/com/qmth/stmms/ms/collect/dto/CollectStuDTO.java

@@ -16,6 +16,7 @@ public class CollectStuDTO {
     private String uploadTime;
 
     private String level;
+    private Long paperId;
 
     public Long getExamId() {
         return examId;
@@ -88,4 +89,12 @@ public class CollectStuDTO {
     public void setLevel(String level) {
         this.level = level;
     }
+
+    public Long getPaperId() {
+        return paperId;
+    }
+
+    public void setPaperId(Long paperId) {
+        this.paperId = paperId;
+    }
 }

+ 9 - 0
stmms-ms-collect/src/main/java/cn/com/qmth/stmms/ms/collect/dto/LoginDTO.java

@@ -17,6 +17,7 @@ public class LoginDTO {
     private boolean imageEnc;
     private ParamSetting paramSetting;
     private List<CollectSubjectDTO> subjects = new ArrayList<>();
+    private String roleCode;
 
     public boolean isImageEnc() {
         return imageEnc;
@@ -73,4 +74,12 @@ public class LoginDTO {
     public void setParamSetting(ParamSetting paramSetting) {
         this.paramSetting = paramSetting;
     }
+
+    public String getRoleCode() {
+        return roleCode;
+    }
+
+    public void setRoleCode(String roleCode) {
+        this.roleCode = roleCode;
+    }
 }

+ 7 - 1
stmms-ms-main/src/main/java/cn/com/qmth/stmms/ms/StartRunning.java

@@ -13,6 +13,7 @@ import org.springframework.boot.CommandLineRunner;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -37,11 +38,16 @@ public class StartRunning implements CommandLineRunner {
     @Override
     public void run(String... args) {
         LOGGER.info("服务器启动时执行 start");
-        Work work = workRepo.findByActiveTrue();
+        /*Work work = workRepo.findByActiveTrue();
         if (Objects.isNull(work)) {
             LOGGER.info("没有创建工作区");
         } else {
             randomUtil.getRandom(work.getId(), false);
+        }*/
+        //对所有工作都生成随机数
+        List<Work> works = workRepo.findAll();
+        for (Work work : works) {
+            randomUtil.getRandom(work.getId(), false);
         }
         LOGGER.info("服务器启动时执行 end");
     }

+ 47 - 37
stmms-ms-main/src/main/resources/application-dev.properties

@@ -2,9 +2,9 @@
 #spring.datasource.username=root
 #spring.datasource.password=root
 
-spring.datasource.url=jdbc:mysql://localhost:3306/stmms-ms-3?useUnicode=true&characterEncoding=UTF-8
+spring.datasource.url=jdbc:mysql://localhost:3306/stmms-ms-zj-2?useUnicode=true&characterEncoding=UTF-8
 spring.datasource.username=root
-spring.datasource.password=123456789
+spring.datasource.password=root
 
 spring.datasource.validation-query=SELECT 1 FROM DUAL
 spring.datasource.test-on-borrow=true
@@ -19,7 +19,7 @@ server.compression.mime-types: application/json,application/xml,text/html,text/x
 
 
 logging.file=./logs/sys.log
-#logging.level.root上线改为error
+#logging.level.root\u4E0A\u7EBF\u6539\u4E3Aerror
 logging.level.root=info
 logging.level.org.springframework=info
 logging.level.org.hibernate=info
@@ -27,37 +27,47 @@ logging.level.org.hibernate=info
 spring.jpa.show-sql=true
 spring.jpa.hibernate.ddl-auto=update
 
+spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
+spring.jackson.time-zone=GMT+8
+
 
 spring.http.multipart.max-file-size=10Mb
 app.config.roundUp=true
 app.config.deviation=4
 app.config.majority=true
-#超级管理员账号
-app.admin.loginName=admin-cy
-#超级管理员密码
+#\u8D85\u7EA7\u7BA1\u7406\u5458\u8D26\u53F7
+app.admin.loginName=admin
+#\u8D85\u7EA7\u7BA1\u7406\u5458\u5BC6\u7801
 app.admin.password=123456
-#采集端-超级管理员账号
+#\u91C7\u96C6\u7AEF-\u8D85\u7EA7\u7BA1\u7406\u5458\u8D26\u53F7
 #app.client.loginName=client-cy
-#采集端-超级管理员密码
+#\u91C7\u96C6\u7AEF-\u8D85\u7EA7\u7BA1\u7406\u5458\u5BC6\u7801
 #app.client.password=123456
-#客户端-超级管理员账号
-app.upload.loginName=upload-cy
-#客户端-超级管理员密码
-app.upload.password=123456
-#纪检角色账号
-app.inspection.loginName=inspection-cy
-#纪检角色密码
-app.inspection.password=123456
-
-sys.config.imageDir=/Users/king/stmms-ms/static/images
-sys.config.thumbDir=/Users/king/stmms-ms/static/thumbs
-sys.config.sheetDir=/Users/king/stmms-ms/static/sheet
-sys.config.watermark=/Users/king/stmms-ms/static/watermark
-#是否开启图片加密
+#\u5BA2\u6237\u7AEF-\u8D85\u7EA7\u7BA1\u7406\u5458\u8D26\u53F7
+#app.upload.loginName=upload-cy
+#\u5BA2\u6237\u7AEF-\u8D85\u7EA7\u7BA1\u7406\u5458\u5BC6\u7801
+#app.upload.password=123456
+#\u7EAA\u68C0\u89D2\u8272\u8D26\u53F7
+#app.inspection.loginName=inspection-cy
+#\u7EAA\u68C0\u89D2\u8272\u5BC6\u7801
+#app.inspection.password=123456
+
+#\u4E34\u65F6\u76EE\u5F55
+sys.config.locationTempDir=data\\msyj\\temp
+
+server.tomcat.basedir=\\data\\msyj\\temp
+
+#\u56FE\u7247\u4FDD\u5B58\u76EE\u5F55
+sys.config.localhostPath=upload
+sys.config.imageDir=upload\\images
+sys.config.thumbDir=upload\\thumbs
+sys.config.sheetDir=upload\\sheet
+sys.config.watermark=upload\\watermark
+#\u662F\u5426\u5F00\u542F\u56FE\u7247\u52A0\u5BC6
 sys.open.imageEnc=false
-#是否开启自定义科目考试
-sys.open.customSubject=true
-#是否开启档位仲裁自动打回
+#\u662F\u5426\u5F00\u542F\u81EA\u5B9A\u4E49\u79D1\u76EE\u8003\u8BD5
+sys.open.customSubject=false
+#\u662F\u5426\u5F00\u542F\u6863\u4F4D\u4EF2\u88C1\u81EA\u52A8\u6253\u56DE
 sys.level.autoCallback=true
 #sys.config.imageDir=.\\static\\images
 #sys.config.thumbDir=.\\static\\thumbs
@@ -66,39 +76,39 @@ sys.config.compression.percent=60
 sys.config.imageServer.port=9000
 sys.config.imageServer.ip=localhost
 sys.config.imageServer.aliyunOss=true
-sys.config.imageServer.dir=ms_test
+sys.config.imageServer.dir=ms-test
 
-#打分阶段配置是否启用(为false则不启用打分阶段分档)
+#\u6253\u5206\u9636\u6BB5\u914D\u7F6E\u662F\u5426\u542F\u7528(\u4E3Afalse\u5219\u4E0D\u542F\u7528\u6253\u5206\u9636\u6BB5\u5206\u6863)
 score.level.enable=false
-#打分阶段配置过滤档位(可选一个或多个档位,多个档位用","号隔开)
+#\u6253\u5206\u9636\u6BB5\u914D\u7F6E\u8FC7\u6EE4\u6863\u4F4D(\u53EF\u9009\u4E00\u4E2A\u6216\u591A\u4E2A\u6863\u4F4D\uFF0C\u591A\u4E2A\u6863\u4F4D\u7528","\u53F7\u9694\u5F00)
 score.level.exclude=
-#打分阶段配置档位排序规则(可选random/paper,为paper时,score.level.exclude置为空)
+#\u6253\u5206\u9636\u6BB5\u914D\u7F6E\u6863\u4F4D\u6392\u5E8F\u89C4\u5219(\u53EF\u9009random/paper\uFF0C\u4E3Apaper\u65F6\uFF0Cscore.level.exclude\u7F6E\u4E3A\u7A7A)
 score.level.taskSort=paper
 
-#样例1
+#\u6837\u4F8B1
 #score.level.exclude=K
 #score.level.taskSort=random
-#样例2
+#\u6837\u4F8B2
 #score.level.exclude=
 #score.level.taskSort=paper
 
-#\u524d\u7aef\u9759\u6001\u8d44\u6e90\u76ee\u5f55
-web.upload-path=/Users/king/stmms-ms/static/
+#\u524D\u7AEF\u9759\u6001\u8D44\u6E90\u76EE\u5F55
+web.upload-path=D:\\company\\qmth\\bat-pro\\msyj-202008\\static\\
 spring.mvc.static-path-pattern=/**
-spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${web.upload-path}
+spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${sys.config.localhostPath},file:${web.upload-path}
 
 app.snapshot.initsql=/Users/yuanpan/dumps/stmms-ms-2-init.sql
 app.snapshot.fdsql=/Users/yuanpan/dumps/stmms-ms-2-fendang.sql
 app.snapshot.dfsql=/Users/yuanpan/dumps/stmms-ms-2-dafen.sql
 app.snapshot.fpsql=/Users/yuanpan/dumps/stmms-ms-2-fuping.sql
 
-#阿里云OSS配置
+#\u963F\u91CC\u4E91OSS\u914D\u7F6E
 aliyun.oss.endpointInner=http://oss-cn-beijing-internal.aliyuncs.com
-aliyun.oss.endpoint=http://oss-cn-beijing.aliyuncs.com
+aliyun.oss.endpoint=https://oss-cn-beijing.aliyuncs.com
 aliyun.oss.accessKeyId=LTAIhiBoG7CsLnoy
 aliyun.oss.accessKeySecret=HqTvxO1RYiPT3SiZKv4VeoXab4AHjz
 aliyun.oss.bucket=epcc-test
-aliyun.oss.url=http://${aliyun.oss.bucket}.oss-cn-beijing.aliyuncs.com
+aliyun.oss.url=https://${aliyun.oss.bucket}.oss-cn-beijing.aliyuncs.com
 aliyun.oss.imageDir=oss://${aliyun.oss.bucket}/${sys.config.imageServer.dir}/images/ -u
 aliyun.oss.thumbDir=oss://${aliyun.oss.bucket}/${sys.config.imageServer.dir}/thumbs/ -u
 aliyun.oss.sheetDir=oss://${aliyun.oss.bucket}/${sys.config.imageServer.dir}/sheet/ -u

+ 1 - 1
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/MarkTaskApi.java

@@ -146,7 +146,7 @@ public class MarkTaskApi {
 //            predicates.add(builder.equal(root.get("isActive"), false));
             return builder.and(predicates.toArray(new Predicate[predicates.size()]));
         };
-        Sort sort = new Sort("paper.level", "randomSeq", "serialNumber", "randomSeqNew");
+        Sort sort = new Sort( "randomSeq","paper.level", "serialNumber", "randomSeqNew");
         Pageable pageable1 = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), sort);
         Page<MarkTask> markTasks = markTaskRepo.findAll(specification, pageable1);