Преглед изворни кода

Squashed commit of the following:

commit 89d6e5d275b5b24f8066d5764e5ae58bf6e17b5c
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Jun 24 16:53:26 2022 +0800

    fix

commit 59827e93e347e06d2728daaf2d7b9d5c69920892
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Jun 24 16:34:17 2022 +0800

    update

commit 9aa2c39b782b32c7ca941befce65bd07ebdb6905
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Jun 24 15:33:56 2022 +0800

    update

commit 311983e7b909aa6340e1948ca2423a696332bf44
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Jun 24 11:39:16 2022 +0800

    fix bugs

commit 0f98ce8a5cd8555d78fc0faab30655e1bd0d7f56
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu Jun 23 10:02:11 2022 +0800

    fix bugs

commit 1ec02476e1b4c50821d9c6050bed443eaacb3f60
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu Jun 23 09:37:23 2022 +0800

    fix bugs

commit 57cf170fc5963cfd74e0b3135d1c5bd3ee342502
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Jun 22 16:56:43 2022 +0800

    update

commit a6e3949bf8ebab752b3ab4b937a4a75867e88a37
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Jun 22 16:09:52 2022 +0800

    fix

commit a835bae432382ea4e6bb7073b52bb463e36c5c23
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Jun 22 15:07:53 2022 +0800

    update

commit 85e2da340d75596f0153b7c38c033994cce71981
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Jun 22 14:32:19 2022 +0800

    fix bugs

commit eb9ca29eb9f3bf7bec6f9ea6eea972707cc99459
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Jun 22 13:49:56 2022 +0800

    绑定试卷是更新考生状态

commit 24c1e4f5fe96a0992e161e5f291208f147d833ed
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Jun 21 17:37:27 2022 +0800

    update

commit 6115d2ccad4fae65568f7a90fd257b883e7bfb44
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Jun 21 16:42:21 2022 +0800

    修复解绑以后的考生如没有试卷则属于未扫描,不缺页非人工置顶

commit ccdf9a17f6d256b65068f88e07bfc0e3abd560c1
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Jun 21 14:46:26 2022 +0800

    fixbugs

commit 37306af80e5c7113372534c80594027d9aa8fa5d
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon Jun 20 14:33:07 2022 +0800

    fix bugs

commit 17e9b72624f0b0b286c767d9157a1b415ff6af91
Author: luoshi <luoshi@qmth.com.cn>
Date:   Fri Jun 17 19:40:16 2022 +0800

    修正重扫保存与实时审核通过时未同步更新考生缺页状态的bug

commit e118fd50809f57301329d585c6cca79cffc7bf98
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Jun 17 17:51:33 2022 +0800

    修改对任务操作的读写锁

commit d2eadf3448d9532c3667c92ef084a381969c571f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Jun 17 16:40:36 2022 +0800

    fix

commit 1fd2c529454eac9a7f5d49ceead8cf5f584e28dc
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Jun 17 13:57:25 2022 +0800

    fix

commit 575bb97166d4851f8a090bec739d49ecfb4650de
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Jun 17 13:53:12 2022 +0800

    fix

commit cffc4313805998acbe6a5f0330cd04d4246ba126
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Jun 17 09:58:27 2022 +0800

    fix

commit e4e30d24540e8a6df82d5044de819f818159a4e6
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Jun 17 09:47:53 2022 +0800

    fix

commit 651fd323ccfb173636482d2b4f023050ebb36a93
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Jun 16 16:15:24 2022 +0800

    fix

commit 7f5a3fb3c5f8eb65fc5319111984bd086c9e99ac
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Jun 16 15:57:01 2022 +0800

    fix

commit b99efac700411a37967403e3c54c723c94612a65
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Jun 16 15:37:31 2022 +0800

    fix

commit db09498a6061d6e295897e9d552a480e4db68f5d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Jun 16 11:40:26 2022 +0800

    fix

commit 7b57dce4d35a32b84907797295048c9611e7f275
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Jun 16 09:59:01 2022 +0800

    fix

commit 0e54374e80cbab49f0d72ba51eeb475c9d5c9bf6
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Jun 15 17:19:35 2022 +0800

    fix bugs

commit 6d09387157d5c1919d138375c2a49cade0236bc7
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Jun 15 17:13:31 2022 +0800

    fix

commit dab04098f6d80086407e188793d978fa90c0c11e
Merge: 3b5ab0c 4550ef3
Author: luoshi <luoshi@qmth.com.cn>
Date:   Wed Jun 15 16:01:52 2022 +0800

    Merge remote-tracking branch 'origin/dev_1.0.0' into dev_1.0.0

commit 3b5ab0c2cf5d989e4a453c3ae1b413186257509d
Author: luoshi <luoshi@qmth.com.cn>
Date:   Wed Jun 15 16:01:41 2022 +0800

    修改数据库初始化脚本,调整初始字段长度,增加必要的索引

commit 4550ef3e602eb148014e196bae9465849cd795d7
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Jun 15 15:39:41 2022 +0800

    update

commit 1944a973333336ea18aa1ef26813de671590dfe5
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Jun 15 13:49:20 2022 +0800

    fix

commit a3a9a0a55cc75358925cc40c64d4ba09a6aa7302
Author: luoshi <luoshi@qmth.com.cn>
Date:   Tue Jun 14 15:54:22 2022 +0800

    管理员更新裁切图时,同步修改考生文件上传状态

commit 1a0fe94c468466da7a09abd09b5f6454a1dd28e3
Author: luoshi <luoshi@qmth.com.cn>
Date:   Tue Jun 14 14:24:42 2022 +0800

    修复Excel导入缺考名时首行判断与漏处理bug

commit 64aae0b16a7b2ccc86cfda4a04c220a44ead9345
Author: luoshi <luoshi@qmth.com.cn>
Date:   Tue Jun 14 14:18:05 2022 +0800

    调整重新绑定后识别对照任务未生成的问题

commit 914d9c1985397a0e53f4e4d32989aacd6078b0ba
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Jun 13 17:49:26 2022 +0800

    fix

commit 0fa23a3ac9bbe59f664610c1e8ef6d7497dafe7e
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Jun 13 17:27:36 2022 +0800

    fix

commit 53b8acb0a43550a8f6c1ccb28b93d6053e2fa3dd
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Jun 13 17:01:04 2022 +0800

    fix

commit e092bf218caf0344a8dc48c6f98e7f456ba7cc6f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Jun 13 16:55:23 2022 +0800

    fix

commit f32d528ae6859a493e765f02f0b6ce449ee1b1df
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Jun 13 16:39:28 2022 +0800

    fix

commit 3961433607b4d9a69f2b9a87cee28377be7dbe33
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Jun 13 14:15:57 2022 +0800

    重新绑定时重新生成识别对照任务

commit 51ee21a2d722671f3d2af31d5b202ba2c89ca5c9
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Jun 10 17:17:09 2022 +0800

    fix

commit dbf1769870006e233ca532f447ee70c57a51db41
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Jun 10 15:50:44 2022 +0800

    fix

commit d75cd46b52179df290a09d63959a652aa6ca8f75
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Jun 10 14:22:05 2022 +0800

    转存任务跳过删除结果的

commit cb94c1de3e2aa885a40285f773726859dd55d8dc
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Jun 10 13:54:46 2022 +0800

    fix

commit 8086eda83e8d5ec42ff3543129a2e09f92441725
Merge: 0cfe8a1 01d00c1
Author: luoshi <luoshi@qmth.com.cn>
Date:   Fri Jun 10 10:55:08 2022 +0800

    Merge remote-tracking branch 'origin/dev_1.0.0' into dev_1.0.0

commit 0cfe8a19f217bdbc6bcb78d4bcfd4aba5791ff51
Author: luoshi <luoshi@qmth.com.cn>
Date:   Fri Jun 10 10:54:47 2022 +0800

    针对识别对照仲裁、实时审核等接口,修改没有任务时的异常码和类型

commit 01d00c11ef4fe96afe2c380eaed9f4bc68c5c051
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Jun 9 17:11:32 2022 +0800

    fix

commit e08221949549bf1c2848cc254cc7295916556ea6
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Jun 9 15:34:28 2022 +0800

    fix

commit bbc5bb52f8a3dd86e545d7c6e4beef1739c63aca
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Jun 8 17:48:38 2022 +0800

    fix

commit e0bce280b4de611eea37763a962e1cc15756fb35
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Jun 8 16:43:08 2022 +0800

    fix

commit 587d99c911e0ff63de733fdda9752b274b3239cf
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Jun 8 14:12:58 2022 +0800

    答题卡卡格式查询

commit d54648aec5c4906a11b38cdd0fd86d969a3c7ed2
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Jun 8 14:05:57 2022 +0800

    fix

commit f013088d3892611dbe1fe5ec26f42f8b8cc086f9
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Jun 8 13:47:40 2022 +0800

    fix

commit f83a4b2914f06828cdfadd62c764fd733640024f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Jun 8 10:06:58 2022 +0800

    fix

commit a730dbfde97699844ff499ebf25e33b282cf589d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Jun 8 09:58:31 2022 +0800

    fix

commit 37f796540dd3ba476d10092fcc1ca5a2574aaa83
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Jun 8 09:38:01 2022 +0800

    fix

commit 9bf9caef1e5dd934151fe28bdb7425ed02d9e536
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Jun 7 16:25:09 2022 +0800

    fix

commit e512f8bb93111c389d4b2839dc357ba178061531
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Jun 7 16:18:16 2022 +0800

    fix

commit eaf8ee41cc277d2f69b8537a9f679b72a67e87e1
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Jun 7 15:04:40 2022 +0800

    fix

commit a94ccb4c479be48dcaee970879ed210c3190948d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Jun 6 09:05:08 2022 +0800

    fix

commit 590c7b4802b41936dede1865d01ccbb4fff4d609
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Jun 2 14:44:10 2022 +0800

    fix

commit 2bb0926bb02226e063ee59b8e019d9e5c8009d71
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Jun 2 14:22:14 2022 +0800

    重新绑定

commit 56b77863fbb9a48cc64ec3c9643a1e6e278e6f11
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Jun 2 09:41:19 2022 +0800

    fix

commit 7a0942039ffe31274180c76eeb376c65dcb07e73
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Jun 2 09:29:38 2022 +0800

    考生表加papertype

commit 121d29e2b60e9b784b5303c3362476432cd5e7ee
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Jun 1 14:44:10 2022 +0800

    fix

commit c69ba6f66e25b5e3f58f5b70daf5baa7d5023fe4
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Jun 1 10:50:08 2022 +0800

    fix

commit b96b1b03c9d21d14e3e46641b20693585179cee9
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Jun 1 10:27:35 2022 +0800

    删除扫描结果更新考生状态

commit 86d94f33e472ee944690b6cfc13a52b1899d2850
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Jun 1 10:19:14 2022 +0800

    fix

commit 9215148413bf9f4385af384c043da107d6e7eacc
Author: luoshi <luoshi@qmth.com.cn>
Date:   Tue May 31 19:21:28 2022 +0800

    修改AnswerQueryVo的status字段类型

commit dc7bbaaf92b1d33ff58472a8232defd5bed0c617
Author: luoshi <luoshi@qmth.com.cn>
Date:   Tue May 31 19:16:31 2022 +0800

    去掉重复计算md5的逻辑;增加文件上传相关的错误日志

commit a6d4d5de04d8925234f475501f4ab5674c7c8937
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue May 31 19:05:08 2022 +0800

    fix bugs

commit 8522b48fca0afdfccb0d098f882f47608bf0dd86
Author: luoshi <luoshi@qmth.com.cn>
Date:   Tue May 31 18:49:10 2022 +0800

    去掉未绑卡格式的扫描员,重复执行解绑卡格式时的报错

commit e7163ef6ef291ddaa0617da811cae06c05f82924
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 31 16:58:49 2022 +0800

    fix

commit 09776397f81bc65986800750eb60fc2982364602
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri May 27 17:58:03 2022 +0800

    fix

commit 7709696200326e3db8f43e8803854f22cb7c820c
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri May 27 17:56:24 2022 +0800

    fix

commit a643a82b161113acd7f6b3f24dad465e914a070c
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri May 27 14:26:36 2022 +0800

    fix

commit 52534b6068749a1dca9834b8426a4fab296c0599
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri May 27 14:07:32 2022 +0800

    fix

commit d9c766be230af48e5e78770834946f0206cacaeb
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri May 27 11:50:30 2022 +0800

    fix

commit 0b0b1ecd1093d3cd275fd4f22f2000015cfabd24
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri May 27 11:18:24 2022 +0800

    fix

commit 1a7bfe35aa195fd8be08454061af069ed9578143
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 26 13:42:22 2022 +0800

    fix

commit 29a01b04cc5b4e0fd05700cbfc006df619782bc8
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed May 25 10:14:48 2022 +0800

    fix

commit 7821e05756df925826796ff08a7448b6c7026215
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed May 25 10:00:03 2022 +0800

    fix

commit c39f3af5529092ec5fcc711d94eefe5eb64c93a2
Author: luoshi <luoshi@qmth.com.cn>
Date:   Tue May 24 19:43:04 2022 +0800

    修改识别对照任务提交逻辑,区分仲裁任务和普通任务,仲裁任务只包含实际需要处理的识别项

commit f8c23bf154ddfbf5a83440646b4821e7e7c4a8cc
Author: luoshi <luoshi@qmth.com.cn>
Date:   Tue May 24 19:35:29 2022 +0800

    修改识别对照获取仲裁任务逻辑,只返回需要仲裁的识别项

commit 965a03e0d9b1ef49264a505e41e2f2a65791e8c9
Author: luoshi <luoshi@qmth.com.cn>
Date:   Tue May 24 18:19:12 2022 +0800

    修改答题卡扫描图片绑定考生接口,对修改对paper增加强制置为assigned逻辑

commit bfa30ef5356e56c4a857762c419ed61abc35b043
Author: luoshi <luoshi@qmth.com.cn>
Date:   Tue May 24 17:56:58 2022 +0800

    修改识别对照任务提交时仲裁判断bug;修改识别对照任务数量统计逻辑错误

commit 76d9216c9826fd9c319cff4bc1fc192b6e090f76
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 24 16:33:24 2022 +0800

    fix

commit e7cc54a6ccec2dfcb16a6df5750dc668c33d7d14
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 24 14:22:02 2022 +0800

    fix

commit b35706dba261d9162e3486ae484d882ac8402262
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 24 11:13:58 2022 +0800

    fix

commit 4af1b3904e632ca8cdbb7d7721ca447a699b4b0a
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon May 23 14:55:39 2022 +0800

    fix

commit 24d1493ff15a59c2592a43d99df0e492a22d2984
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon May 23 14:50:40 2022 +0800

    fix

commit 417cfa5b5daac071d33ff99beb810b0a3c8d1859
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon May 23 14:46:39 2022 +0800

    fix

commit 7dddd0db81a97b9f023b9b0a8437bee93e52a24b
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon May 23 14:41:14 2022 +0800

    fix

commit 8b25d28d493278fe6f94a5c590b1219df857ae85
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon May 23 11:40:39 2022 +0800

    释放任务锁

commit a31d3f6a8233f43fef41f31ddbdde30c635beb37
Author: luoshi <luoshi@qmth.com.cn>
Date:   Fri May 20 18:33:49 2022 +0800

    修复exam/info查询卡格式数量bug

commit d3342d1c42eb34af8ec40b95a033d432deef5e1b
Author: luoshi <luoshi@qmth.com.cn>
Date:   Fri May 20 17:46:58 2022 +0800

    修改/api/scan/exam/info中cardCount的计算bug

commit fc2bd2ee9215e1cb447a1e870399c0f918fcf3ee
Author: luoshi <luoshi@qmth.com.cn>
Date:   Fri May 20 17:23:38 2022 +0800

    修复SQL中查询到sc_student已删除的subject_name字段的bug

commit a296779fe6bceae45c43ad8f89b13b5579d06df3
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri May 20 14:32:59 2022 +0800

    fix bugs

commit 47e0e1f8c5a053da19dee8a57d9e566fb6f10ab6
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri May 20 14:23:48 2022 +0800

    fix bugs

commit ec2abe3108fffcd00680009b9d6abb6567d35930
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri May 20 10:16:54 2022 +0800

    fixbugs

commit 4fac6ea96db3dc09eae1182e566ae180f28a4aca
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 19 15:49:39 2022 +0800

    fix

commit 909a7b270bea45e753ee8c8ac354344874d68a10
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 19 13:48:12 2022 +0800

    fix

commit de401693199f6e01998e811c81911439e2c0be87
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 19 11:44:05 2022 +0800

    fix

commit d86de14fbb16f85817715cd3af511ff45d8d56c9
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 19 11:37:01 2022 +0800

    fix

commit 82d1caaabf9f765cc8ed9ff60b57571bfd9e2fca
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 19 11:35:50 2022 +0800

    fix

commit 541f0f6f7524f3f89225924de4eeb77f432e5e03
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 19 11:15:48 2022 +0800

    fix

commit 4d08d66b34661f1cee8063128ede4b9d93248aed
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 19 11:07:56 2022 +0800

    fix

commit 89178b2b0ca95cfdffbbbcb88dee4ea874634e0f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 19 10:45:50 2022 +0800

    fix

commit 1b0a1d2e7f340455301da4e6f7596fd26796f369
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 19 10:21:59 2022 +0800

    fix

commit 4ea0eaf4a06801dc9f00ab94b79c82a4c8bdaf5f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 19 09:57:38 2022 +0800

    fix

commit 79faa48eb7154d6aad386644d9cbbf153764999d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 19 08:29:12 2022 +0800

    fix

commit 9d84ca73f681a8727fcfc8c4c34047c7b8710118
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed May 18 15:38:47 2022 +0800

    fix

commit d5e1e4d20f512c1bb57326910e57f9807d5108ad
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed May 18 10:00:00 2022 +0800

    fix

commit 1370430f4959e34c3ead8b9a4c8686d6c320e695
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed May 18 09:54:28 2022 +0800

    fix

commit 13fbf09849b57beecfd2411278590a288ff52569
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed May 18 09:42:10 2022 +0800

    fix

commit 56044be7590dacd65ba460dbeaed95b23614a75d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed May 18 09:36:28 2022 +0800

    fix

commit 7c87cb1695bcbe7158d1c04dae77ca87a6328519
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 17 17:32:48 2022 +0800

    上传进度

commit a356df2179b28e9b667c0b5178ac1b60876f1a4e
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 17 10:54:38 2022 +0800

    fix

commit 86f8f4e37c2ee6a26f9586d3b7ff0a0c8fbd2042
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sat May 14 11:59:46 2022 +0800

    md5bug

commit b8749743e2e56f4caebb5628dc8a6f2c5ad3fef0
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 12 15:22:04 2022 +0800

    fix

commit d23f622a453c32bba7828613a23c004f04f79365
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu May 12 13:59:58 2022 +0800

    fix

commit 5d6f035086b2c57f57f6e67c79d2f8ceaf4f45a8
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu May 12 13:39:55 2022 +0800

    fix

commit 58ce365a00d724e30a1fca607a5ac80664a48d9a
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu May 12 11:38:30 2022 +0800

    fix

commit 9f93575291f062d7e2c88c1cc62303ffd2f9795a
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 12 09:41:45 2022 +0800

    fix

commit 528631a9e095a8140646f616cf02c081e771135d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 12 08:11:10 2022 +0800

    fix

commit 2285090ec87fc27f13dc71daed424ea35df5a4a5
Author: deason <fdeason@foxmail.com>
Date:   Wed May 11 18:14:21 2022 +0800

    update

commit 5dd0d50aad4905e07841afe0413b4103da675287
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed May 11 09:51:14 2022 +0800

    fix

commit b48744078ebb9a760ab5debf04caed51e063398f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed May 11 09:42:03 2022 +0800

    fix

commit adc52969d7655753069bf5ce71b5d964edd6e012
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed May 11 09:41:39 2022 +0800

    fix

commit 19c674f6e10a01d8b3ab3bc9d3eadb24c251825f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed May 11 09:26:50 2022 +0800

    fix

commit cb17a429c1668fff5743e324017c4fe31837c290
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 10 16:59:27 2022 +0800

    fix

commit e1464044e1c6eed2999514790101900e08bce713
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 10 16:56:45 2022 +0800

    fix

commit d8ebe37f8b935ab2c43d542fb4e19306ec561b70
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue May 10 16:53:16 2022 +0800

    update

commit 6f93398b6e7601691278d0dfc44d908179d4e0c9
Merge: 3df01bb fac878c
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 10 16:29:33 2022 +0800

    Merge branch 'dev_1.0.0' of http://git.qmth.com.cn/scancloud/server.git into dev_1.0.0

commit 3df01bba181c9b2973e004d4885728cedcdcffe4
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 10 16:29:27 2022 +0800

    fix

commit fac878c99e2b519ae03fd030ee777c2c4091c51b
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue May 10 16:22:57 2022 +0800

    fix

commit ac6c9365f68e6491ede4532930c99d0ce63caab6
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 10 16:19:02 2022 +0800

    fix

commit 90dc9e272100af0c057c762c7d05d4519828d56f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 10 16:13:11 2022 +0800

    fix

commit f8fa4db53872e0f692ae62477bd293877e7fa72f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 10 16:09:23 2022 +0800

    fix

commit cc0e05e58d3ded4f1e367cd780d937dda3faf710
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue May 10 16:04:20 2022 +0800

    fix

commit 9d9614302b99aeaf041c270980d26f03f220e09a
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 10 15:59:36 2022 +0800

    fix

commit 01eaf8670a4621f4fb036df2fc40fc1bb4c755a2
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue May 10 15:48:44 2022 +0800

    fix

commit 8f179375e8b4cff027b6db7c0182b46cfd4a8f15
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue May 10 14:37:25 2022 +0800

    fix

commit a9959df7849990a2011fe177a2dc667d858621a2
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue May 10 11:21:24 2022 +0800

    fix

commit def4eac5f53699545a53e7d940fb75143e52395d
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue May 10 10:22:43 2022 +0800

    新增Semaphore,更改taskExecutor的支持

commit aeba56eb794ea51808b7b480ca00d0998fe89043
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue May 10 08:32:23 2022 +0800

    只开启单评识别对照时,处理结果未同步更新到paper记录中

commit 23236eb0a07ecd6d49120f19fccacf8aefa913e7
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue May 10 08:18:55 2022 +0800

    fixbugs

commit 74fd17ae7522079ddc05e8739748091793d7788f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon May 9 17:18:51 2022 +0800

    fix

commit bd0d7ad09f6bb6310ab035b98005c1885a55e9ee
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon May 9 17:13:46 2022 +0800

    fix

commit 8e1e6bae1ea57ac69c8a9a4d3197aa51eedc8eb8
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon May 9 17:11:42 2022 +0800

    测试

commit 8e141462a2a9c681df94218ec8691a84adbe87eb
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon May 9 16:47:22 2022 +0800

    测试

commit 9aed8cf394df13a181af6456f2a23497606f16e4
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon May 9 10:17:02 2022 +0800

    fix

commit 032886183a862507f803b0b64e7ab7592f520471
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon May 9 09:58:01 2022 +0800

    fix

commit 5708755d461de76d9300e40b940b669111acc146
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon May 9 08:42:26 2022 +0800

    fix

commit d6f121347f53e4ba595dc56183a0ce6e5ae268e0
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sat May 7 16:41:05 2022 +0800

    fix

commit f6b7dfb2052df6fe44c30c402b9d4387e547e6f8
Merge: fbc9757 0a8ba2b
Author: ting.yin <yinting@qmth.com.cn>
Date:   Sat May 7 15:27:45 2022 +0800

    Merge branch 'dev_1.0.0' of http://git.qmth.com.cn/scancloud/server into dev_1.0.0

    * 'dev_1.0.0' of http://git.qmth.com.cn/scancloud/server:
      fix
      fix
      转存图片任务

commit fbc975722e4d794c2a7bc34dc7c25c10ead9328e
Author: ting.yin <yinting@qmth.com.cn>
Date:   Sat May 7 15:26:49 2022 +0800

    fix

commit 0a8ba2be2c9d1cfba69a03a9233f251299eacbde
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sat May 7 15:13:56 2022 +0800

    fix

commit 6e14e40e23d248fc54fb089ddea553b3fc81f98f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sat May 7 15:06:31 2022 +0800

    fix

commit c97238bfd1f31a7d10fac3445c8bcd8e131b2216
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sat May 7 15:01:52 2022 +0800

    转存图片任务

commit 0475298c3e345d252c4b6ea02f877168b18a826f
Author: ting.yin <yinting@qmth.com.cn>
Date:   Sat May 7 14:58:03 2022 +0800

    本地工具查询新增paperType

commit 69510daf89b749f402d22992220c7d2a947bfce1
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sat May 7 14:34:13 2022 +0800

    人工指定保存逻辑修改

commit 1d04a5d048fd5ca1a2772c0f8d9751cf81cf7299
Author: ting.yin <yinting@qmth.com.cn>
Date:   Sat May 7 14:19:28 2022 +0800

    fix

commit e6e51f560f13d65dd3b2a802cfeb7f172ed2d00b
Author: ting.yin <yinting@qmth.com.cn>
Date:   Sat May 7 12:28:52 2022 +0800

    fix

commit 2bf8401231fb7c9800baace8251305a57332646c
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sat May 7 11:46:15 2022 +0800

    任务创建逻辑修改

commit afd3515fe139c551dede672d3cdf5f235c881bb5
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sat May 7 08:41:34 2022 +0800

    fix

commit 8f7a5958ceef402829d9e5aeb8d46314aaf23feb
Author: deason <fdeason@foxmail.com>
Date:   Fri May 6 19:18:28 2022 +0800

    update tool api

commit 1befffd73e8a289b7df76092fa9ea7ba20220765
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri May 6 15:34:12 2022 +0800

    fix

commit 8431688edd80aaecd7a0e489ee459dad3c7c26ef
Merge: 86ab800 40f52e5
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri May 6 15:19:15 2022 +0800

    Merge branch 'dev_1.0.0' of http://git.qmth.com.cn/scancloud/server.git into dev_1.0.0

commit 86ab8004f6359f30680ccda3ade6c625b3dd36f8
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri May 6 15:19:09 2022 +0800

    fix

commit 40f52e5d3f40d2dd016e2d76b60fed10d4a1443e
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri May 6 15:03:57 2022 +0800

    fix

commit b7dc92fd015afb03e281e6e4386de1e293b0513f
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri May 6 14:29:36 2022 +0800

    fix

commit 968754cad4012d51280113846d113dca3aa8a9da
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri May 6 13:51:15 2022 +0800

    update

commit 3437eb8ee8d13c13ee87e506fcacdce7bd79dcf0
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri May 6 10:49:42 2022 +0800

    图片检查

commit 705a53b4b11b4c8a6f7ab3801edde3d1a0c4a481
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri May 6 09:55:16 2022 +0800

    fix

commit aac3b202fb40d1f3f6d8629cc3a9a4e25c0be610
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu May 5 18:06:51 2022 +0800

    新增导入工具接口

commit 193270791e4f4e283c91c1fd822d05b059e7821e
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 5 17:36:17 2022 +0800

    fix

commit 849d88f4d2195666742e0f9b3f2be654037f79ad
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 5 16:59:41 2022 +0800

    fix

commit 2909c436fbc6d0a5ecbc64a4a49770bc9bff7666
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 5 15:40:43 2022 +0800

    fix

commit 57d27ba26712cf262757e1293e60d6bd6457558d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 5 15:26:16 2022 +0800

    fix

commit 4481e0de15370bea22b671183ea2a1b8449701fc
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 5 15:13:08 2022 +0800

    fix

commit 1f337cf0b5fa0d35752d233fa00905b416db5c35
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 5 15:07:29 2022 +0800

    fix识别任务创建

commit 281319b62a62db4b420835a5bd9b6126a30e4df6
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu May 5 10:12:32 2022 +0800

    fixbugs

commit 292e6292bdf26f2f9b80bce749dab666b348949a
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu May 5 09:52:53 2022 +0800

    多线程修改

commit b58c8c1b05b886c7ffd537d846313cfe0e2a6778
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 28 17:18:49 2022 +0800

    fix

commit b40f2d406bf10c3a5a7aa909c873b2a0b34d19aa
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 28 15:42:55 2022 +0800

    fix

commit 0cfae017972d93d861c9b45da951729dc274317a
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 28 15:38:32 2022 +0800

    fix

commit 65ead5424fe2d02fe1b4ed1171f1fb584d4ffaaa
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu Apr 28 15:34:05 2022 +0800

    生成默认识别对照分组

commit ab5c58905b28ca9eee6d5852ec60cb2457dd8468
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Apr 27 17:29:18 2022 +0800

    update

commit c71645c92b8548cd59adcc0f39dbb0c46e47177a
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 27 16:04:31 2022 +0800

    fix

commit b7cc5341525aa741c2b4d7cade0e373a73d93791
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 27 16:03:20 2022 +0800

    fix

commit be13c75f605fbc7cb47424b09023510ae4ef8b08
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 27 15:58:45 2022 +0800

    fix

commit c7d759fed67182f900177ca9b0fb499912b6434a
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 27 15:50:57 2022 +0800

    fix

commit e59b76588cb227e6e22047f5415a67056a102ec2
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 27 15:45:46 2022 +0800

    fix

commit 600abcd5336a1c1ec05d928b77c4ddaeb2c4eefc
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 27 15:45:12 2022 +0800

    fix

commit cba1427dc7b26d549ca88ba749bbf6b0318e098b
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 27 15:39:57 2022 +0800

    fix

commit aab62633543f18eee5b83653ac373f582e9abb1e
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 27 15:34:10 2022 +0800

    fix

commit 9bd7d200656523964c4732d120ad8a4db5c0051c
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 27 15:28:20 2022 +0800

    fix

commit 7780b0209acecb584b3836252ab355a19a0d0268
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Apr 27 09:16:04 2022 +0800

    update

commit d0e91306a1474d30be0f561bfb5cf4d7503bc488
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Apr 26 16:47:11 2022 +0800

    update

commit 13d9178c37a6cc0f1d324bb2f020ede6248e4d62
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Apr 26 15:26:01 2022 +0800

    fix

commit e3ddc0f0f48384abbd5c5ed3c36d9bd772d8cbb2
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Apr 26 14:52:11 2022 +0800

    fix bugs

commit 314ea662e91c64dbed4a28a644826661c9a0f507
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Apr 26 10:23:49 2022 +0800

    fix

commit 2070663b7b330aa19128f547389e347dc95f848e
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Apr 26 09:44:52 2022 +0800

    update

commit 9ee452485a56217f73f29a3964a21d730d54d455
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Apr 26 09:08:32 2022 +0800

    fix bugs

commit 0cd6a6afe165252add9361169d78d9d328306263
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Apr 26 08:38:35 2022 +0800

    fix

commit 359d0274f2932c3b19882d058b8d30c9d256978e
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Apr 26 08:37:46 2022 +0800

    fix

commit f8204ea3655505af27bc96e47089d6f3805e658a
Merge: 5e5f13e 60873fe
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon Apr 25 17:33:09 2022 +0800

    Merge branch 'dev_1.0.0' of http://git.qmth.com.cn/scancloud/server into dev_1.0.0

    * 'dev_1.0.0' of http://git.qmth.com.cn/scancloud/server:
      fix

commit 5e5f13e6b089c31111622cddc638d7ca9f17209c
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon Apr 25 17:33:02 2022 +0800

    fix bugs

commit 60873fe543018e9d0b1af2f9d1318f2d5c129755
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Apr 25 17:10:11 2022 +0800

    fix

commit 648b4de3538b5992981df7369343ae6a0280c929
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon Apr 25 17:07:32 2022 +0800

    update

commit b61ee9314d20da4c9fff58e18b4859c83792132d
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon Apr 25 16:50:12 2022 +0800

    fix

commit d42e4c1a472e6b6a33e76af2e2942dbd4ce3f323
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon Apr 25 16:29:13 2022 +0800

    update

commit bc164407ee6be180832073b3dccd724a5e09ad9b
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon Apr 25 15:35:27 2022 +0800

    fixbugs

commit 66165baaaebbf17f9aa80e90c9751582e073bc9f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Apr 25 15:09:14 2022 +0800

    fix

commit d634329182ede913de2c54211e13556afc1c601b
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Apr 25 14:49:18 2022 +0800

    fix

commit 34d2598c6d65efb046c7b2323a091f2f9cce672a
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Apr 25 14:04:05 2022 +0800

    fix

commit 1289cd8695e8f1057aaae68796a748d3a38ecbd5
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Apr 25 13:58:15 2022 +0800

    fix

commit 02f23ef2b42194561de56cf2e0e480aaf4f557f7
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon Apr 25 11:43:52 2022 +0800

    fixbugs

commit 4eb59bbb4c51143b89f3499775c54ddaadb662c4
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon Apr 25 11:11:31 2022 +0800

    fix bugs

commit f11699212007cf8ddfd96c79808d5887e218326b
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon Apr 25 09:59:42 2022 +0800

    fixbugs

commit 680ca88abacc62f16f044ca09683ca110359f9ae
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sun Apr 24 17:20:24 2022 +0800

    fix

commit 7d200c4ab8275046a25a469c33a21c48e38bb02c
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sun Apr 24 15:14:51 2022 +0800

    fix

commit c557f84e9d7a07331b8d89ec2dc7c594131d9205
Author: ting.yin <yinting@qmth.com.cn>
Date:   Sun Apr 24 14:48:06 2022 +0800

    update

commit d4c5fbbf276837e512cbe3798e451722621d4576
Merge: 4f6f0be 13d8746
Author: ting.yin <yinting@qmth.com.cn>
Date:   Sun Apr 24 13:36:49 2022 +0800

    Merge branch 'dev_1.0.0' of http://git.qmth.com.cn/scancloud/server into dev_1.0.0

    * 'dev_1.0.0' of http://git.qmth.com.cn/scancloud/server:
      fix

commit 4f6f0bef38c749896b503b4af08d9c4eb0ed79c7
Author: ting.yin <yinting@qmth.com.cn>
Date:   Sun Apr 24 13:36:41 2022 +0800

    update

commit 13d87468783aec697f662e061d68f07389ed1fbb
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sun Apr 24 11:44:59 2022 +0800

    fix

commit 32283aa864e94ccb54192c091a16f039de072dc0
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Apr 22 11:04:03 2022 +0800

    update

commit ed1ef79179924977280ac1daa382020a53536f7a
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 21 17:35:32 2022 +0800

    fix

commit ebfd97c7afab7afd2c9e9058f3740ac3e0720e8c
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 21 16:55:40 2022 +0800

    fix

commit 13adc8bf9e6ef7ee44cbfe022f287b48e734e8a3
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 21 15:03:03 2022 +0800

    fix

commit 355836a2e3b2d3ae1b6bbd2ff90c687469282d7a
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu Apr 21 14:59:19 2022 +0800

    update

commit b1f1089f841ab161bfdd5973d5db7fb1e9ac97bc
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 20 16:52:14 2022 +0800

    fix

commit e7223ddb4cbe04b18afb0f390689b3b54ab93c43
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 20 16:46:43 2022 +0800

    fix

commit 17c1516004d7d8c599108d66fe939a017a59129f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 20 14:22:58 2022 +0800

    recogData原始识别数据字符串

commit 2d98f3578e1d48db82373e70b72ea90a395b69af
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 20 10:45:59 2022 +0800

    fix

commit c61683b0510bb8dc0b2a9017391444eee41f7239
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 20 09:55:46 2022 +0800

    fix

commit a68978f1f12465f12df5a0c993a391bf5412fbba
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 20 09:50:58 2022 +0800

    fix

commit 499a373776e860ef96d0d90b216ed3fea66ffe6f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 20 09:32:47 2022 +0800

    fix

commit 6e4ea6be7586f2326e8dbd21692aeae47dbdd0ca
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 20 09:26:55 2022 +0800

    打包

commit a04ec9eab2703f4b77efcff421c462c39c02721b
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 20 09:24:50 2022 +0800

    打包

commit d51b0924f89a6908ce5235341291b2851353e136
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Apr 19 17:19:57 2022 +0800

    fix

commit 88e12bdeaefa41c476cdad2703884789cfde29fa
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Apr 19 16:14:29 2022 +0800

    fix

commit 3894c4a04768cccabbb36f1f239efec825e6c1ba
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Apr 18 16:47:00 2022 +0800

    fix

commit 3940c0f118837191ed6371e47424eb004f4fd9fa
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Apr 13 14:10:36 2022 +0800

    fixbugs,新增清理过期任务定时任务

commit 8a57468d4f735d8d37d76d0a642d26370c548c3f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Apr 11 16:27:35 2022 +0800

    fix

commit d090529222214562f586a2270453e923cedd2078
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Apr 11 16:16:53 2022 +0800

    fix

commit e526d1fba5d4214e773f439dc109be3949628c26
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Apr 11 15:59:34 2022 +0800

    fix

commit e5391197d937de27cae2c1486322225851a2e427
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Apr 11 14:24:11 2022 +0800

    fix

commit 34871592f039c209b4f7e3975dc38cc5dd159009
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Apr 11 13:57:09 2022 +0800

    fix

commit da9dcb68a499ae428fd78206aa83b21cf9a45d1b
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Apr 11 13:55:52 2022 +0800

    fix

commit fa6043525092946311aabc071ace9487515722e9
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Apr 11 10:54:28 2022 +0800

    fix

commit d8ec3b47ea00b53db50be692330a914b258ea601
Author: luoshi <luoshi@qmth.com.cn>
Date:   Sat Apr 9 19:08:59 2022 +0800

    修复导入指定缺考名单的异常数量统计bug

commit f5cb5ba61af043fab6d4d71a7b21ac5171428dc7
Author: luoshi <luoshi@qmth.com.cn>
Date:   Sat Apr 9 19:05:01 2022 +0800

    bugfix

commit 22b9513f7c38bf161ac0c40c3081b8ee7226456b
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 18:55:00 2022 +0800

    fix

commit 9ef4df6b09e3f33e184c9f674eaa16b00c2d4bd8
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 18:42:39 2022 +0800

    fix

commit 19b1195950485335db03445c30ae982121171f7d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 18:37:18 2022 +0800

    fix

commit b7b3eb85b3dac9ea165a99dc917b20ea66a42df0
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 18:33:56 2022 +0800

    fix

commit 258c892ab3d6bdeac403b285cc69ed5e6b5da1a2
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 18:30:52 2022 +0800

    fix

commit 02d2fe7eb2b38106e0f212794f4d8da56943effb
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 18:18:39 2022 +0800

    fix

commit e575ecc628b170b42e32d1de0dc747e96f782145
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 17:58:58 2022 +0800

    fix

commit 9c73f5ba1a9bd9f2dbb5e6f343e59557db01f9a7
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 17:34:38 2022 +0800

    fix

commit 538da2845b848f345eb85a4582dbdaf8fb474884
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 17:24:18 2022 +0800

    fix

commit b3d120009f27dc15adf70b7fcd53424c29dff86c
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 17:01:19 2022 +0800

    fix

commit b5bcfbd3ead50f45bf4db031c8c46ff02b3dc666
Merge: eec1e13 a82f5e3
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Apr 8 16:50:53 2022 +0800

    Merge branch 'dev_1.0.0' of http://git.qmth.com.cn/scancloud/server into dev_1.0.0

    * 'dev_1.0.0' of http://git.qmth.com.cn/scancloud/server:
      fix
      fix
      fix

commit eec1e13ba5250c4d36ba7c44bdc35ad6692ace68
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Apr 8 16:50:45 2022 +0800

    fix bugs

commit a82f5e35aa743d2cd7d5711010771563fd99d61d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 16:09:36 2022 +0800

    fix

commit 4ccb77a7ede58fc865b645ba0c982d81e3eb5d8b
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 15:13:51 2022 +0800

    fix

commit 8f9a5200cdcf6661acf404080f1e7dbeb91c046b
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 13:37:28 2022 +0800

    fix

commit a9e647863414d932413cf6ae04e59f33ce0e5618
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 13:33:14 2022 +0800

    fix

commit 2beb68b935dad4f41ab251410ae0a6c2124c565d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 10:55:37 2022 +0800

    fix

commit ab5dd2b0136d13afacced123f8f9bd031ed68d69
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 10:14:40 2022 +0800

    fix

commit ba69b5c375618aaafa2c8af04ea73116cbf8eb4f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 8 09:55:02 2022 +0800

    fix

commit 729c4fdefedb47062a8f5d34203e1065e10c6be4
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Apr 8 09:51:56 2022 +0800

    update

commit 7b21fb670f8933ecb7b5ba07e40d3a188ed1c978
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 17:27:23 2022 +0800

    fix

commit c3f4da5923353373f4d482afe677909e2c16a862
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 17:21:53 2022 +0800

    fix

commit a18407644647802406f10eaafa682aea73cd6fd6
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 17:21:13 2022 +0800

    fix

commit c210fe17e5762369005aceb576d438693ee492bc
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 17:17:31 2022 +0800

    fix

commit 5c81e96686b94a8d8c9fac072925464d857f5d65
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 16:58:59 2022 +0800

    fix

commit 4cb6bc4df07ad783444221b0b802ee9398b18936
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 15:16:39 2022 +0800

    fix

commit 4106a8d37b5478a5542d0d797b4c66670f0925ba
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 15:00:46 2022 +0800

    fix

commit a8191b44589e4d85051131415ad18009a8ddf245
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 14:09:44 2022 +0800

    fix

commit 99d5deb40fcdc0cc43a9f62f2a3fe96a325b05f4
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 13:45:12 2022 +0800

    fix

commit 53776bb539a8e199bb461ed7bedb8d5b6e3fb89b
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 11:21:15 2022 +0800

    fix

commit 948536f832ea1ccaafd2c3e94d42ca8811bcf772
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 11:10:52 2022 +0800

    fix

commit fa868165616e644f4356511f3d58f2bd38b91468
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 11:05:05 2022 +0800

    fix

commit cc2f6d0fc9eaac1854944dbb84b48d399d32c824
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 10:54:20 2022 +0800

    fix

commit ec7694fdef189774114d8bd76a1690df540e55ad
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 10:37:13 2022 +0800

    fix

commit 8b2c952e3221a7b426dda714b7fdd95a78666904
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 09:39:41 2022 +0800

    fix

commit da60b9f2c4d5de1b4bf771c88c48c7a0c2a8f992
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 09:31:43 2022 +0800

    json映射

commit 9ff2da4146042e5e8b01abbad10b915343768614
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Apr 7 09:24:39 2022 +0800

    联合主键

commit 2588647a2c68adda4a495d1fb3a5680df3981c30
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu Apr 7 08:27:38 2022 +0800

    update

commit 6c55bf1b1e67decd7c917d45db15561b3b02be61
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Apr 6 16:19:30 2022 +0800

    update

commit 91b8cf95b89b42e8061e6b390c51287279ccfaaf
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Apr 6 11:33:49 2022 +0800

    卡格式解析

commit ce5c284287b89738b1418e0a61207375e8ab1ced
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Apr 6 11:27:52 2022 +0800

    update

commit 3b47863ba62e0acd8ecdb8a34509797ea42edff9
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sat Apr 2 10:31:21 2022 +0800

    答题卡试卷结构解析

commit f7738f75ca45ad767e8e300ab2f8ee1d014805ec
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 1 16:16:53 2022 +0800

    fix

commit 60494db216c32ef71b916ef5d055c3f53c391a70
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 1 10:55:37 2022 +0800

    fix

commit d956755c802d1f8d8b0234455ad4d9b4c37aeaf6
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 1 09:53:41 2022 +0800

    fix

commit d0b56d9615cff1311390d6f3b0c51510531fef2e
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 1 09:45:36 2022 +0800

    fix

commit 1a9d178607bdf629243520700800c308577c8a69
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 1 09:43:50 2022 +0800

    fix

commit 41e793497fe6dcc91a1ed78ee4d7b53790848cff
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Apr 1 09:14:21 2022 +0800

    fix

commit a5611a2b600ed16441d6ae66fd9092051652ed53
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Apr 1 09:04:07 2022 +0800

    fix

commit 167b02e1df519d5bf2a1564acb86abf78943f52e
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 31 18:14:28 2022 +0800

    fix

commit 1684033f0392dc876e90d2d680d660a9f838e97b
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 31 17:28:32 2022 +0800

    fix

commit b687f9087afbf03b510e7b496cbe0fd614cf13f5
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 31 17:11:13 2022 +0800

    fix

commit ace497a29cfa7df31aab4191663b7c4585a52717
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 31 17:05:30 2022 +0800

    fix

commit 3576b5a901459a29e560298bbfd6b43e3bb509ea
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 31 16:28:38 2022 +0800

    fix

commit 05cc9a777c1967ac5a0cbf5db56a1a55388da6c2
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 31 16:28:17 2022 +0800

    fix

commit 24595b33f2bf9b4de4f83d39a998fb2198be96c9
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 31 15:52:08 2022 +0800

    fix

commit b0f331822acc51db774528f94b8f17e8be75e10a
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 31 15:39:28 2022 +0800

    导出

commit 137dab7f20c7e5039f48ff625b5faf525bfa2e11
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu Mar 31 15:29:08 2022 +0800

    fix

commit 3152d26290d35a6ae4e3407f28b380f0a59a7216
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 31 14:43:13 2022 +0800

    fix

commit 559cd7111877b8b8a7633d098661d7d98c236705
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 31 14:32:03 2022 +0800

    修改考试参数

commit 481be16db170b505a422c0c0ed2a14b311c5ac4a
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 31 14:14:51 2022 +0800

    fix

commit 98aa4311fe28571fa5e3ed1f768988465f5fa397
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu Mar 31 13:36:54 2022 +0800

    fix

commit 29d66250dbc4d875288dba928c756f744a49bc25
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 31 10:52:37 2022 +0800

    fix

commit 02dafdce61698af8521e3556d330efad28f99364
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 31 10:48:26 2022 +0800

    上传多线程

commit 1c8551a082d4f7d0f39342523b2c04499a025591
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu Mar 31 09:21:59 2022 +0800

    fix

commit 2c31ce459a083dab671bb494524530d4fbf674e3
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Mar 30 17:05:28 2022 +0800

    update

commit d08530f7dfe03ccad6ad2877df2ee58c116ff9aa
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Mar 30 16:34:14 2022 +0800

    update

commit 80012c3f71fccaac8c420db6b57b70526f488089
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 30 14:59:44 2022 +0800

    fix

commit 0424928a639f54b8deaeaf9b4055ebf18e54652d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 30 14:57:51 2022 +0800

    fix

commit 8601a637b36b719556bda3f66a895a57e66ee055
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 30 14:51:39 2022 +0800

    fix

commit 584db4888e57810f947f9169bd659dcf5b106bd1
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 30 14:23:03 2022 +0800

    fix

commit 07564a4745538b566d9d8db77a194c759b0506d5
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 30 13:58:58 2022 +0800

    fix

commit 80450958bc2e694b0cbd6e761a2980a674a17ec1
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Mar 30 13:57:58 2022 +0800

    update

commit 67fb7199787937a29b31054817397a34ee959126
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 30 13:51:08 2022 +0800

    fix

commit 7be5b4a605e613b72b772dceeaf7478a7c81a810
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 30 11:08:10 2022 +0800

    fix

commit 17b7f627f2966285516332701d8669d5b6833e30
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 30 10:37:55 2022 +0800

    fix

commit cffbf6310eff670c4ef825edd8584ed9924a9366
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 29 11:49:59 2022 +0800

    fix

commit c3f513d91c268f4f1551e6b0cb17021c18d564cf
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 29 11:23:14 2022 +0800

    fix

commit 0ebe5b90dba89d46007e7af31027f29460ccea29
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 29 10:04:58 2022 +0800

    数据文件上传

commit 9b119fdecfdc2f3f7c8f5a24eda3b9b78d2c415f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 29 09:47:51 2022 +0800

    fix

commit 23fb45bef496bed5050e706fddd95b3ad06e9e9d
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon Mar 28 16:20:49 2022 +0800

    管理员登录、获取答题卡扫描实时审核任务

commit 517d121b6a00accf9136295de513a5aebb3e3478
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Mar 28 15:52:44 2022 +0800

    数据图片上传任务

commit 7ba9add42c3a14df6952f2011a85b38246dd57e6
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Mar 25 16:42:41 2022 +0800

    fix

commit ea318e3bb0622a2515ca8f3797c53596d1b45577
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Mar 25 15:29:23 2022 +0800

    登出接口

commit 321a648e45f0c29c65016500cdff1e36eb91ba6d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Mar 25 15:24:04 2022 +0800

    删除答题卡扫描结果

commit 694bfce9a3ee4b6caab030eb14f90da4489aeb62
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Mar 25 15:17:10 2022 +0800

    删除答题卡单页扫描结果

commit b463458217f938023f6604f77542d5f27ab13df4
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Mar 25 14:53:45 2022 +0800

    修改答题卡扫描图片绑定考生

commit 6ee6486e447bd4f1eff0e99163dcd70149d8533a
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 24 17:40:38 2022 +0800

    fix

commit e9f5e80cf16cc6ff66f86f5c2ebdfb4f4cdd67f6
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 24 17:29:37 2022 +0800

    fix

commit c99b1b6c63df56fa3de9005d6a71ec66474f0b84
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 24 17:01:12 2022 +0800

    上传答题卡裁切图

commit 973fe896b3dae2e7b1949808953469e58f451df9
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 24 15:36:36 2022 +0800

    修改答题卡识别结果

commit 28a71f988e6f5665f7ff49e17667f2ad07519dd5
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 24 14:21:57 2022 +0800

    查询答题卡扫描详情

commit 7d321ad8b27feb9a93d1263f116487ffe3abb7d4
Merge: 51204dd f2f1f26
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Mar 23 17:34:11 2022 +0800

    Merge branch 'dev_1.0.0' of http://git.qmth.com.cn/scancloud/server into dev_1.0.0

    * 'dev_1.0.0' of http://git.qmth.com.cn/scancloud/server:
      fix

commit 51204dd5d7dd92354db9ed02acd77ab9111f0069
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Mar 23 17:33:50 2022 +0800

    update

commit f2f1f2604136c28d612ad4a8986448f1e33cf867
Merge: bedf847 2ce9dd5
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 23 17:32:31 2022 +0800

    Merge branch 'dev_1.0.0' of http://git.qmth.com.cn/scancloud/server.git into dev_1.0.0

commit bedf847ff0fc80a0662fc4620e1d12abf0b3f5c8
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 23 17:32:23 2022 +0800

    fix

commit 2ce9dd53e04b026492b90862a4635b9e88078b92
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Mar 23 17:32:15 2022 +0800

    识别对照任务获取 | 识别对照任务提交 | 识别对照仲裁任务获取 | 识别对照仲裁结果提交

commit 965264c174b40537973c480f59be16ef817cebdf
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 23 17:25:40 2022 +0800

    fix

commit b75ec444d551885f3dc228fcacfe631a14799970
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 23 17:00:37 2022 +0800

    答题卡扫描汇总

commit 1ee19e4ba41c286262f4448aab257b31499f4160
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 23 16:45:24 2022 +0800

    修改异常答题卡标记

commit 26684ccfbdd80a47557739281687e7aa0938bd4d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 23 16:39:36 2022 +0800

    fix

commit a647368a1fe0d1d7266067df4dc2ecf2d710fc4a
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 23 16:26:51 2022 +0800

    查询异常答题卡信息

commit 83b5b97cef8b329c430c644e34502561c1ad2623
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 23 14:09:46 2022 +0800

    查询答题卡扫描批次详情

commit f3fd51cb31cf7d1827fdde85cfde710d4c64a2b5
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 23 10:49:58 2022 +0800

    查询答题卡扫描批次信息

commit 9d4129fe4f252d5c041b8da7975a859ba395ea03
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 23 10:47:44 2022 +0800

    查询答题卡扫描批次信息

commit b9441550b20acc7c3bc682f57aed57bc02dbb4f0
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Mar 22 18:44:11 2022 +0800

    update

commit f55115694ed945d2e82f9180fc6f92cb468dd4d5
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 22 18:34:17 2022 +0800

    更新批次信息

commit 77ce2752a7a3c4c29e6c6290b9ab7542a72c0564
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 22 17:57:33 2022 +0800

    取消缺考标记嫌疑

commit e3dafbd2d1bd096583851e46928609752dbed92a
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 22 17:49:57 2022 +0800

    导入指定缺考名单

commit 5ae01df28c9a1ff091f8e3bf2e794a52dc812537
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 22 17:49:52 2022 +0800

    导入指定缺考名单

commit 313d4537929c01c1283af3bae72723fec2feba2d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 22 16:24:31 2022 +0800

    查询缺考数据

commit 63cc99c3d3ad445c8339eeb5d8109ddc2f7d5e86
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Mar 22 16:12:00 2022 +0800

    识别对照仲裁进度状态 | 识别对照任务状态

commit b1782ea14b22b46f8c9315862dc83ba7367ab282
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Mar 22 14:02:57 2022 +0800

    查询识别对照任务列表 | 修改识别对照任务组阶段

commit 1f9c15d547d9a6bc253ec036dbb9ef48455d06ad
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Mar 21 17:52:31 2022 +0800

    缺考数据汇总

commit 1c6a9839819c0091de6019413608d217e1741e72
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon Mar 21 17:08:37 2022 +0800

    update

commit 6f2dbaac25341a327fcbe9dddff4fc57329cc0cd
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Mar 21 17:02:12 2022 +0800

    修改扫描员绑定卡格式

commit c403dc71ae82018974b4e1b3389f49a649ff1438
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Mar 21 14:30:37 2022 +0800

    图片上传、结果保存需求改动

commit ffb217f8a4dd1f4373d7e7c89490ca5c00c38a7e
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Mar 21 13:54:41 2022 +0800

    修改扫描员登陆控制

commit 0785c7579db039f728eeef344f57ccdd3f5aa445
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Mar 21 11:17:22 2022 +0800

    扫描员工作量统计

commit 87ca85a929cf1d162215ba5e03afaedabe4d0d51
Author: ting.yin <yinting@qmth.com.cn>
Date:   Sat Mar 19 15:22:49 2022 +0800

    识别对照任务组生成任务 | 重置识别对照任务组 | 删除识别对照任务组

commit e0073665e108f04367ad246f593269e69d2de602
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sat Mar 19 14:42:51 2022 +0800

    扫描员管理详情

commit 35db4dfadc9704f5bf09f2ddaee5cd8efe774bda
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sat Mar 19 12:24:16 2022 +0800

    答题卡扫描批次完成

commit 6539e223ce8d24cf0dc91764ce25f70d65b9e3eb
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sat Mar 19 11:56:29 2022 +0800

    答题卡扫描批次提交审核/查询审核结果

commit 0ca129f06879f5cb69dd74f73fdb9e7e83158213
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sat Mar 19 11:42:27 2022 +0800

    答题卡扫描裁切图上传

commit cdb79059b335d1ff64ff0af4dc5e5ce3848ee7c1
Author: xiatian <xiatian@qmth.com.cn>
Date:   Sat Mar 19 11:19:02 2022 +0800

    原图上传

commit 15152943a7f89e78bc7e9994f058a209a9a116ae
Author: ting.yin <yinting@qmth.com.cn>
Date:   Sat Mar 19 10:43:57 2022 +0800

    update

commit 61b8e224b2edf95efb8339b13f9557843917f5df
Author: ting.yin <yinting@qmth.com.cn>
Date:   Sat Mar 19 10:22:03 2022 +0800

    update

commit c593c2d903f435bc575f55edb26cf3beb0981ae2
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Mar 18 17:33:26 2022 +0800

    获取答题卡扫描实时审核任务 | 答题卡扫描实时审核任务处理

commit d722201aec3b8e652b88b2da792c38230583279d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Mar 18 17:11:17 2022 +0800

    答题卡扫描历史标记/取消异常

commit eb413a2686eb0d25b19273c2c78eff05959fb770
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Mar 18 16:42:29 2022 +0800

    fix

commit e805dcf1e62ebdfda25269066721ced2d7b8873c
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Mar 18 16:28:32 2022 +0800

    保存扫描结果

commit 026e4ded7c0cf8cdd831f5375a238025edcb4117
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Mar 18 16:00:48 2022 +0800

    扫描结果保存

commit aff5e41317d4866911f4461030192580e04e53a0
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Mar 18 15:50:21 2022 +0800

    保存扫描结果

commit eb2bde91508543dedbaed4d75646005ad6009dbd
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Mar 18 14:07:34 2022 +0800

    答题卡扫描结果保存

commit 315f79039485cd4bc4924f3ba5c33aa5ed895e53
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Mar 18 13:44:52 2022 +0800

    update

commit e9b7239ddf9509245e9cc78a73ec24c1ebd8ab22
Author: xiatian <xiatian@qmth.com.cn>
Date:   Fri Mar 18 10:33:47 2022 +0800

    答题卡扫描批次创建

commit 7f0c6e5da5a9b5ae8bbbfbeb90e91fe5e28c2ce2
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 17 18:20:03 2022 +0800

    批次创建

commit 567a8466dd6c95b0617062b47de6a2e0c227009f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 17 18:08:26 2022 +0800

    db

commit fe7945fc2bae73b79f31ab8faa635d10c504ca4e
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu Mar 17 17:54:02 2022 +0800

    update

commit 41a0b0409b91530327e7082838ff551abdb3ded2
Author: ting.yin <yinting@qmth.com.cn>
Date:   Thu Mar 17 13:49:20 2022 +0800

    update

commit 1793fec69dae55265912a2831e52476b8f127878
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 17 11:08:58 2022 +0800

    整袋考生查询

commit dfd6ee8748a4afe9ddd1786c3a8cef61a3a4cfaa
Author: xiatian <xiatian@qmth.com.cn>
Date:   Thu Mar 17 10:17:24 2022 +0800

    fix

commit 11494787fe9b14f551bae6dd5ec0b6766cfca8ce
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Mar 15 17:51:11 2022 +0800

     卡格式详情 | 卡格式同步状态 | 创建/修改题卡卡格式

commit e2696b0814e30e695200992d860de38b54034377
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 15 16:58:20 2022 +0800

    答题卡卡格式列表

commit 6ac3e2ece5a98c9957d6110ac19650fc6023afe3
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Mar 15 15:55:32 2022 +0800

    update

commit fb7cfb752790bb5f3936969c2c1f73416ae0a697
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 15 15:45:39 2022 +0800

    考试列表

commit 098a43cd6eb45e6ea14c1063f25ab5c12cef1efa
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 15 15:32:20 2022 +0800

    fix

commit 6cba68632657d63617ee96d550037e1e2f388c7e
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 15 15:23:32 2022 +0800

    fix

commit b7df20145ff42c534407d413af912988a044683d
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 15 15:22:29 2022 +0800

    考试详情

commit 3e90fde38065ba7a0dbd00c99268344a027ae9c3
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 15 15:14:38 2022 +0800

    fix

commit 45ca0f672bc557054070d6d59bfb1cda503cb977
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Mar 15 15:14:12 2022 +0800

    update

commit d4d824eaee5fcde70a3ff3bf5408f6e5c8480e0c
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 15 15:11:15 2022 +0800

    考试详情

commit e68f9236c894dc658f37841a651464f645447b13
Merge: eb8ab46 aa73ec3
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 15 15:10:25 2022 +0800

    Merge branch 'dev_1.0.0' of http://git.qmth.com.cn/scancloud/server.git
    into dev_1.0.0

    Conflicts:
    	src/main/java/cn/com/qmth/scancloud/service/AnswerCardService.java
    	src/main/java/cn/com/qmth/scancloud/service/impl/AnswerCardServiceImpl.java
    	src/main/java/cn/com/qmth/scancloud/service/impl/ExamServiceImpl.java

commit eb8ab4689a8a45a9efe23d3ba329463ffe21c3cc
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 15 15:04:28 2022 +0800

    merge

commit aa73ec3365be085644a17c3213b75f772a272509
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Mar 15 14:58:17 2022 +0800

     创建/修改题卡卡格式

commit 73b5a14f51c175b94b3a590fc9c177348cf22831
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 15 10:41:53 2022 +0800

    扫描考试详情

commit ec9f5ab83775de76e11e44b5ef64f0224614c1ba
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Mar 15 09:09:09 2022 +0800

    update

commit 84daa4e18e3e844f7b083d5971708dfa8f102eff
Author: xiatian <xiatian@qmth.com.cn>
Date:   Tue Mar 15 09:08:33 2022 +0800

    fix

commit 4a037ffd7c9fb15179ede291a61922b2e9582ef9
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon Mar 14 18:04:52 2022 +0800

    获取考生信息 | 获取科目列表 | 获取科目信息 | 获取所有学习中心 | 获取所有考点

commit abb7e557c79acea959b7c213cefeb1d77ac34761
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Mar 14 17:57:30 2022 +0800

    fix

commit c858e4ae3a97f25548e2107ed0a42c99a6ea8e1f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Mar 14 17:24:23 2022 +0800

    异常处理

commit 0767918204a9160bd04216d63c519f5257ceee0f
Author: xiatian <xiatian@qmth.com.cn>
Date:   Mon Mar 14 16:53:59 2022 +0800

    扫描员登录、心跳

commit 6e8e66e6956958deac9434a8eb896fd41091398f
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Mar 11 15:30:30 2022 +0800

    update

commit 712e9a68c931e1effb569bd5428230b050df58bc
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Mar 11 15:25:23 2022 +0800

    update

commit a4a1565128d073c3ff8fa7324f68b084500b2583
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 9 20:04:38 2022 +0800

    扫描员登录

commit ae467c5597960cb0831b62897080360985d0b393
Author: xiatian <xiatian@qmth.com.cn>
Date:   Wed Mar 9 18:22:46 2022 +0800

    扫描员登录

commit 594ce809c2bea4dc16b6961218dd6e219a5f715c
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Mar 9 15:58:46 2022 +0800

    update

commit 892e87ce8f43d0ddb00baa6fcbb5568b89d6ed07
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Mar 9 09:33:52 2022 +0800

    update
luoshi пре 3 година
родитељ
комит
91ba56398f
100 измењених фајлова са 5128 додато и 251 уклоњено
  1. 410 0
      db/init.sql
  2. 3 0
      db/system_config_cet.sql
  3. 1 0
      db/system_config_marking.sql
  4. 3 0
      db/system_config_ow.sql
  5. 11 0
      jenkins.sh
  6. 240 104
      pom.xml
  7. 1 0
      shell/start.args
  8. 28 0
      shell/start.sh
  9. 1 0
      shell/start.vmoptions
  10. 17 0
      shell/stop.sh
  11. 18 0
      src/main/java/cn/com/qmth/scancloud/ApiApplication.java
  12. 66 0
      src/main/java/cn/com/qmth/scancloud/bean/AbsentQueryDomain.java
  13. 18 0
      src/main/java/cn/com/qmth/scancloud/bean/AnswerDeleteDomain.java
  14. 132 0
      src/main/java/cn/com/qmth/scancloud/bean/AnswerQueryDomain.java
  15. 21 0
      src/main/java/cn/com/qmth/scancloud/bean/BatchCreateDomain.java
  16. 42 0
      src/main/java/cn/com/qmth/scancloud/bean/BatchQueryDomain.java
  17. 28 0
      src/main/java/cn/com/qmth/scancloud/bean/CardAnswerDomain.java
  18. 79 0
      src/main/java/cn/com/qmth/scancloud/bean/ExamConfigDomain.java
  19. 104 0
      src/main/java/cn/com/qmth/scancloud/bean/ImportExamDomain.java
  20. 122 0
      src/main/java/cn/com/qmth/scancloud/bean/ImportStudentDomain.java
  21. 35 0
      src/main/java/cn/com/qmth/scancloud/bean/ImportSubjectDomain.java
  22. 59 0
      src/main/java/cn/com/qmth/scancloud/bean/ImportUserDomain.java
  23. 21 0
      src/main/java/cn/com/qmth/scancloud/bean/MismatchQueryDomain.java
  24. 19 0
      src/main/java/cn/com/qmth/scancloud/bean/MismatchToggleDomain.java
  25. 28 0
      src/main/java/cn/com/qmth/scancloud/bean/OmrTaskDto.java
  26. 45 0
      src/main/java/cn/com/qmth/scancloud/bean/OmrTaskPageDto.java
  27. 26 0
      src/main/java/cn/com/qmth/scancloud/bean/PageDeleteDomain.java
  28. 31 0
      src/main/java/cn/com/qmth/scancloud/bean/ScannerLoginInfo.java
  29. 62 0
      src/main/java/cn/com/qmth/scancloud/bean/SchoolSession.java
  30. 115 0
      src/main/java/cn/com/qmth/scancloud/bean/User.java
  31. 26 0
      src/main/java/cn/com/qmth/scancloud/bean/WorkloadDomain.java
  32. 36 0
      src/main/java/cn/com/qmth/scancloud/bean/answersave/AnswerDomain.java
  33. 72 0
      src/main/java/cn/com/qmth/scancloud/bean/answersave/AnswerPage.java
  34. 30 0
      src/main/java/cn/com/qmth/scancloud/bean/answersave/AnswerPaper.java
  35. 29 0
      src/main/java/cn/com/qmth/scancloud/bean/answersave/ArrayResult.java
  36. 27 0
      src/main/java/cn/com/qmth/scancloud/bean/answersave/BoolResult.java
  37. 27 0
      src/main/java/cn/com/qmth/scancloud/bean/answersave/StringResult.java
  38. 28 0
      src/main/java/cn/com/qmth/scancloud/bean/omredit/OmrEditDomain.java
  39. 50 0
      src/main/java/cn/com/qmth/scancloud/bean/omredit/OmrEditPage.java
  40. 21 0
      src/main/java/cn/com/qmth/scancloud/bean/omredit/OmrEditPaper.java
  41. 51 0
      src/main/java/cn/com/qmth/scancloud/bean/papermigrate/PaperMigrateDomain.java
  42. 68 0
      src/main/java/cn/com/qmth/scancloud/bean/papermigrate/PaperMigratePage.java
  43. 96 0
      src/main/java/cn/com/qmth/scancloud/client/MarkingcloudApiClient.java
  44. 21 0
      src/main/java/cn/com/qmth/scancloud/client/MarkingcloudApiConfiguration.java
  45. 62 0
      src/main/java/cn/com/qmth/scancloud/client/MarkingcloudProperties.java
  46. 35 0
      src/main/java/cn/com/qmth/scancloud/config/FillMetaObjectHandler.java
  47. 23 0
      src/main/java/cn/com/qmth/scancloud/config/InitData.java
  48. 15 0
      src/main/java/cn/com/qmth/scancloud/config/MyBatisPlusConfig.java
  49. 31 0
      src/main/java/cn/com/qmth/scancloud/config/ScanResourceManager.java
  50. 31 0
      src/main/java/cn/com/qmth/scancloud/config/ScanWebMvcConfigurer.java
  51. 42 0
      src/main/java/cn/com/qmth/scancloud/config/SwaggerConfig.java
  52. 68 0
      src/main/java/cn/com/qmth/scancloud/config/SysProperty.java
  53. 165 0
      src/main/java/cn/com/qmth/scancloud/controller/BaseController.java
  54. 92 0
      src/main/java/cn/com/qmth/scancloud/controller/SystemController.java
  55. 71 0
      src/main/java/cn/com/qmth/scancloud/controller/admin/ArbitrateController.java
  56. 33 0
      src/main/java/cn/com/qmth/scancloud/controller/admin/AuthController.java
  57. 136 0
      src/main/java/cn/com/qmth/scancloud/controller/admin/CardController.java
  58. 190 0
      src/main/java/cn/com/qmth/scancloud/controller/admin/CheckController.java
  59. 177 0
      src/main/java/cn/com/qmth/scancloud/controller/admin/ExamController.java
  60. 64 0
      src/main/java/cn/com/qmth/scancloud/controller/admin/ExamWorkController.java
  61. 142 0
      src/main/java/cn/com/qmth/scancloud/controller/admin/OmrGroupController.java
  62. 163 0
      src/main/java/cn/com/qmth/scancloud/controller/admin/ScanAnswerController.java
  63. 72 0
      src/main/java/cn/com/qmth/scancloud/controller/admin/ScannerController.java
  64. 125 0
      src/main/java/cn/com/qmth/scancloud/controller/admin/ToolController.java
  65. 58 0
      src/main/java/cn/com/qmth/scancloud/controller/admin/VerifyController.java
  66. 103 0
      src/main/java/cn/com/qmth/scancloud/controller/scan/AnswerController.java
  67. 71 0
      src/main/java/cn/com/qmth/scancloud/controller/scan/OmrTaskController.java
  68. 43 0
      src/main/java/cn/com/qmth/scancloud/controller/scan/ScanExamController.java
  69. 38 0
      src/main/java/cn/com/qmth/scancloud/controller/scan/ScannerAuthController.java
  70. 43 0
      src/main/java/cn/com/qmth/scancloud/controller/scan/StudentController.java
  71. 9 0
      src/main/java/cn/com/qmth/scancloud/dao/AnswerCardDao.java
  72. 37 0
      src/main/java/cn/com/qmth/scancloud/dao/BatchDao.java
  73. 22 0
      src/main/java/cn/com/qmth/scancloud/dao/ExamDao.java
  74. 8 0
      src/main/java/cn/com/qmth/scancloud/dao/FilePropertyDao.java
  75. 11 0
      src/main/java/cn/com/qmth/scancloud/dao/OmrGroupDao.java
  76. 17 0
      src/main/java/cn/com/qmth/scancloud/dao/OmrTaskDao.java
  77. 9 0
      src/main/java/cn/com/qmth/scancloud/dao/PackageCardDao.java
  78. 9 0
      src/main/java/cn/com/qmth/scancloud/dao/PackageResultDao.java
  79. 9 0
      src/main/java/cn/com/qmth/scancloud/dao/PackageTaskDao.java
  80. 30 0
      src/main/java/cn/com/qmth/scancloud/dao/PaperDao.java
  81. 9 0
      src/main/java/cn/com/qmth/scancloud/dao/PaperPageDao.java
  82. 9 0
      src/main/java/cn/com/qmth/scancloud/dao/PaperStructureDao.java
  83. 9 0
      src/main/java/cn/com/qmth/scancloud/dao/ScannerCardDao.java
  84. 14 0
      src/main/java/cn/com/qmth/scancloud/dao/ScannerDao.java
  85. 49 0
      src/main/java/cn/com/qmth/scancloud/dao/StudentDao.java
  86. 17 0
      src/main/java/cn/com/qmth/scancloud/dao/StudentPaperDao.java
  87. 9 0
      src/main/java/cn/com/qmth/scancloud/dao/SubjectDao.java
  88. 9 0
      src/main/java/cn/com/qmth/scancloud/dao/SystemConfigDao.java
  89. 9 0
      src/main/java/cn/com/qmth/scancloud/dao/UserDao.java
  90. 3 0
      src/main/java/cn/com/qmth/scancloud/entity/AnswerCardEntity.java
  91. 0 10
      src/main/java/cn/com/qmth/scancloud/entity/BatchEntity.java
  92. 53 3
      src/main/java/cn/com/qmth/scancloud/entity/ExamEntity.java
  93. 49 0
      src/main/java/cn/com/qmth/scancloud/entity/FilePropertyEntity.java
  94. 11 9
      src/main/java/cn/com/qmth/scancloud/entity/OmrGroupEntity.java
  95. 39 3
      src/main/java/cn/com/qmth/scancloud/entity/OmrTaskEntity.java
  96. 0 55
      src/main/java/cn/com/qmth/scancloud/entity/OmrTaskPaperEntity.java
  97. 7 3
      src/main/java/cn/com/qmth/scancloud/entity/PackageResultEntity.java
  98. 20 0
      src/main/java/cn/com/qmth/scancloud/entity/PaperEntity.java
  99. 121 64
      src/main/java/cn/com/qmth/scancloud/entity/PaperPageEntity.java
  100. 69 0
      src/main/java/cn/com/qmth/scancloud/entity/PaperStructureEntity.java

+ 410 - 0
db/init.sql

@@ -0,0 +1,410 @@
+-- ----------------------------
+-- Table structure for sc_answer_card
+-- ----------------------------
+DROP TABLE IF EXISTS `sc_answer_card`;
+CREATE TABLE `sc_answer_card`
+(
+    `exam_id`      bigint       NOT NULL,
+    `number`       int          NOT NULL,
+    `subject_code` varchar(64)  DEFAULT NULL,
+    `subject_name` varchar(64)  DEFAULT NULL,
+    `paper_count`  int          NOT NULL,
+    `path`         varchar(255) NOT NULL,
+    `md5`          varchar(32)  NOT NULL,
+    `source`       varchar(16)  NOT NULL,
+    `need_adapte`  bit(1)       NOT NULL,
+    `single_page`  bit(1)       NOT NULL,
+    `parameter`    text         DEFAULT NULL,
+    `remark`       varchar(255) DEFAULT NULL,
+    `creator_id`   bigint       DEFAULT NULL,
+    `updater_id`   bigint       DEFAULT NULL,
+    `create_time`  bigint       DEFAULT NULL,
+    `update_time`  bigint       DEFAULT NULL,
+    PRIMARY KEY (`exam_id`, `number`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+-- ----------------------------
+-- Table structure for sc_exam
+-- ----------------------------
+DROP TABLE IF EXISTS `sc_exam`;
+CREATE TABLE `sc_exam`
+(
+    `id`                         bigint       NOT NULL AUTO_INCREMENT,
+    `school_id`                  bigint       NOT NULL,
+    `school_name`                varchar(64)  NOT NULL,
+    `name`                       varchar(128) NOT NULL,
+    `enable`                     bit(1)       NOT NULL,
+    `mode`                       varchar(16)  NOT NULL,
+    `scan_by_package`            bit(1)       NOT NULL,
+    `allow_unexist_paper`        bit(1)       NOT NULL,
+    `answer_front_card_type`     int          NOT NULL,
+    `enable_single_page_answer`  bit(1)       NOT NULL,
+    `answer_paper_number_figure` int          NOT NULL,
+    `enable_upload`              bit(1)       NOT NULL,
+    `enable_sync_verify`         bit(1)       NOT NULL,
+    `paper_type_barcode_content` text        DEFAULT NULL,
+    `absent_barcode_content`     varchar(16) DEFAULT NULL,
+    `creator_id`                 bigint      DEFAULT NULL,
+    `updater_id`                 bigint      DEFAULT NULL,
+    `create_time`                bigint      DEFAULT NULL,
+    `update_time`                bigint      DEFAULT NULL,
+    PRIMARY KEY (`id`),
+    INDEX `school_enable` (`enable`, `school_id`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+-- ----------------------------
+-- Table structure for sc_omr_task
+-- ----------------------------
+DROP TABLE IF EXISTS `sc_omr_task`;
+CREATE TABLE `sc_omr_task`
+(
+    `id`           bigint      NOT NULL AUTO_INCREMENT,
+    `exam_id`      bigint      NOT NULL,
+    `group_id`     bigint      NOT NULL,
+    `student_id`   bigint      NOT NULL,
+    `paper_number` int         NOT NULL,
+    `paper_id`     int         NOT NULL,
+    `card_number`  int         NOT NULL,
+    `status`       varchar(16) NOT NULL,
+    `device`       varchar(64) DEFAULT NULL,
+    `pages`        text        NOT NULL,
+    `creator_id`   bigint DEFAULT NULL,
+    `updater_id`   bigint DEFAULT NULL,
+    `create_time`  bigint DEFAULT NULL,
+    `update_time`  bigint DEFAULT NULL,
+    PRIMARY KEY (`id`),
+    UNIQUE KEY `group_paper` (`group_id`, `paper_id`),
+    KEY `exam_status` (`exam_id`, `status`, `student_id`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+-- ----------------------------
+-- Table structure for sc_package_card
+-- ----------------------------
+DROP TABLE IF EXISTS `sc_package_card`;
+CREATE TABLE `sc_package_card`
+(
+    `id`          bigint       NOT NULL AUTO_INCREMENT,
+    `exam_id`     bigint       NOT NULL,
+    `path`        varchar(255) NOT NULL,
+    `md5`         varchar(32)  NOT NULL,
+    `source`      varchar(16)  NOT NULL,
+    `creator_id`  bigint DEFAULT NULL,
+    `updater_id`  bigint DEFAULT NULL,
+    `create_time` bigint DEFAULT NULL,
+    `update_time` bigint DEFAULT NULL,
+    PRIMARY KEY (`id`),
+    KEY `exam` (`exam_id`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+-- ----------------------------
+-- Table structure for sc_package_task
+-- ----------------------------
+DROP TABLE IF EXISTS `sc_package_task`;
+CREATE TABLE `sc_package_task`
+(
+    `id`           bigint      NOT NULL AUTO_INCREMENT,
+    `exam_id`      bigint      NOT NULL,
+    `package_code` varchar(64) NOT NULL,
+    `status`       varchar(16) NOT NULL,
+    `device`       varchar(64) NOT NULL,
+    `creator_id`   bigint DEFAULT NULL,
+    `updater_id`   bigint DEFAULT NULL,
+    `create_time`  bigint DEFAULT NULL,
+    `update_time`  bigint DEFAULT NULL,
+    PRIMARY KEY (`id`),
+    KEY `exam_package` (`exam_id`, `package_code`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+-- ----------------------------
+-- Table structure for sc_scanner
+-- ----------------------------
+DROP TABLE IF EXISTS `sc_scanner`;
+CREATE TABLE `sc_scanner`
+(
+    `device`          varchar(64) NOT NULL,
+    `last_login_time` bigint DEFAULT NULL,
+    `create_time`     bigint DEFAULT NULL,
+    `update_time`     bigint DEFAULT NULL,
+    PRIMARY KEY (`device`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+-- ----------------------------
+-- Table structure for ss_system_config
+-- ----------------------------
+DROP TABLE IF EXISTS `sc_system_config`;
+CREATE TABLE `sc_system_config`
+(
+    `id`                   bigint      NOT NULL AUTO_INCREMENT,
+    `scanner_enable_login` bit(1)       DEFAULT NULL,
+    `scanner_password`     varchar(16)  DEFAULT NULL,
+    `image_transfer_mode`  varchar(16)  DEFAULT NULL,
+    `system_mode`          varchar(16) NOT NULL,
+    `client_version`       varchar(16)  DEFAULT NULL,
+    `client_uri`           varchar(255) DEFAULT NULL,
+    `client_md5`           varchar(32)  DEFAULT NULL,
+    `client_update_time`   bigint       DEFAULT NULL,
+    `creator_id`           bigint       DEFAULT NULL,
+    `updater_id`           bigint       DEFAULT NULL,
+    `create_time`          bigint       DEFAULT NULL,
+    `update_time`          bigint       DEFAULT NULL,
+    PRIMARY KEY (`id`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+DROP TABLE IF EXISTS `sc_package_result`;
+CREATE TABLE `sc_package_result`
+(
+    `exam_id`      bigint      NOT NULL,
+    `package_code` varchar(64) NOT NULL,
+    `device`       varchar(64) NOT NULL,
+    `path`         text        NOT NULL,
+    `assigned`     bit(1)      NOT NULL,
+    `creator_id`   bigint DEFAULT NULL,
+    `updater_id`   bigint DEFAULT NULL,
+    `create_time`  bigint DEFAULT NULL,
+    `update_time`  bigint DEFAULT NULL,
+    `upload_time`  bigint DEFAULT NULL,
+    PRIMARY KEY (`exam_id`, `package_code`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+DROP TABLE IF EXISTS `sc_scanner_card`;
+CREATE TABLE `sc_scanner_card`
+(
+    `exam_id`     bigint      NOT NULL,
+    `device`      varchar(64) NOT NULL,
+    `card_number` int         NOT NULL,
+    `creator_id`  bigint DEFAULT NULL,
+    `updater_id`  bigint DEFAULT NULL,
+    `create_time` bigint DEFAULT NULL,
+    `update_time` bigint DEFAULT NULL,
+    PRIMARY KEY (`exam_id`, `device`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+DROP TABLE IF EXISTS `sc_batch`;
+CREATE TABLE `sc_batch`
+(
+    `id`             bigint      NOT NULL AUTO_INCREMENT,
+    `exam_id`        bigint      NOT NULL,
+    `device`         varchar(64) NOT NULL,
+    `package_code`   varchar(64) DEFAULT NULL,
+    `scan_count`     int         NOT NULL,
+    `assigned_count` int         NOT NULL,
+    `status`         varchar(16) NOT NULL,
+    `verify_status`  varchar(16) DEFAULT NULL,
+    `creator_id`     bigint      DEFAULT NULL,
+    `updater_id`     bigint      DEFAULT NULL,
+    `create_time`    bigint      DEFAULT NULL,
+    `update_time`    bigint      DEFAULT NULL,
+    PRIMARY KEY (`id`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+DROP TABLE IF EXISTS `sc_paper`;
+CREATE TABLE `sc_paper`
+(
+    `id`              bigint       NOT NULL AUTO_INCREMENT,
+    `exam_id`         bigint       NOT NULL,
+    `student_id`      bigint       NOT NULL,
+    `batch_id`        bigint       NOT NULL,
+    `card_number`     int          NOT NULL,
+    `exam_number`     varchar(128) NOT NULL,
+    `number`          int          NOT NULL,
+    `page_count`      int          NOT NULL,
+    `mismatch`        bit(1)       NOT NULL,
+    `assigned`        bit(1)       NOT NULL,
+    `question_filled` bit(1)       NOT NULL,
+    `creator_id`      bigint DEFAULT NULL,
+    `updater_id`      bigint DEFAULT NULL,
+    `create_time`     bigint DEFAULT NULL,
+    `update_time`     bigint DEFAULT NULL,
+    PRIMARY KEY (`id`),
+    UNIQUE KEY `batch_student_number` (`batch_id`, `student_id`, `number`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+DROP TABLE IF EXISTS `sc_paper_page`;
+CREATE TABLE `sc_paper_page`
+(
+    `paper_id`    bigint       NOT NULL,
+    `page_index`  int          NOT NULL,
+    `batch_id`    bigint       NOT NULL,
+    `student_id`  bigint       NOT NULL,
+    `exam_id`     bigint       NOT NULL,
+    `absent`      text     DEFAULT NULL,
+    `breach`      text     DEFAULT NULL,
+    `paper_type`  text     DEFAULT NULL,
+    `question`    text     DEFAULT NULL,
+    `selective`   text     DEFAULT NULL,
+    `sheet_path`  varchar(255) NOT NULL,
+    `slice_path`  text     DEFAULT NULL,
+    `recog_data`  longtext DEFAULT NULL,
+    `create_time` bigint   DEFAULT NULL,
+    `update_time` bigint   DEFAULT NULL,
+    `creator_id`  bigint   DEFAULT NULL,
+    `updater_id`  bigint   DEFAULT NULL,
+    PRIMARY KEY (`paper_id`, `page_index`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+DROP TABLE IF EXISTS `sc_paper_structure`;
+CREATE TABLE `sc_paper_structure`
+(
+    `id`              bigint      NOT NULL AUTO_INCREMENT,
+    `exam_id`         bigint      NOT NULL,
+    `card_number`     int         NOT NULL,
+    `paper_number`    int         NOT NULL,
+    `page_index`      int         NOT NULL,
+    `field`           varchar(16) NOT NULL,
+    `question_number` int         NOT NULL,
+    `single`          bit(1)      NOT NULL,
+    `creator_id`      bigint DEFAULT NULL,
+    `updater_id`      bigint DEFAULT NULL,
+    `create_time`     bigint DEFAULT NULL,
+    `update_time`     bigint DEFAULT NULL,
+    PRIMARY KEY (`id`),
+    UNIQUE KEY `IDX_PAPER_STRUCTURE_001` (`exam_id`, `card_number`, `paper_number`, `page_index`, `field`,
+                                          `question_number`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+
+DROP TABLE IF EXISTS `sc_omr_group`;
+CREATE TABLE `sc_omr_group`
+(
+    `id`          bigint      NOT NULL AUTO_INCREMENT,
+    `exam_id`     bigint      NOT NULL,
+    `fixed`       bit(1)      NOT NULL,
+    `stage`       varchar(16) NOT NULL,
+    `conditions`  text        NOT NULL,
+    `total_count` int         NOT NULL,
+    `creator_id`  bigint DEFAULT NULL,
+    `updater_id`  bigint DEFAULT NULL,
+    `create_time` bigint DEFAULT NULL,
+    `update_time` bigint DEFAULT NULL,
+    PRIMARY KEY (`id`),
+    KEY `exam_fixed` (`exam_id`, `fixed`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+
+DROP TABLE IF EXISTS `sc_refix_batch`;
+CREATE TABLE `sc_refix_batch`
+(
+    `id`           bigint NOT NULL AUTO_INCREMENT,
+    `exam_id`      bigint NOT NULL,
+    `card_number`  int    NOT NULL,
+    `conditions`   text   NOT NULL,
+    `update_slice` bit(1) NOT NULL,
+    `total_count`  int    NOT NULL,
+    `sucess_count` int    NOT NULL,
+    `finished`     bit(1) NOT NULL,
+    `creator_id`   bigint DEFAULT NULL,
+    `updater_id`   bigint DEFAULT NULL,
+    `create_time`  bigint DEFAULT NULL,
+    `update_time`  bigint DEFAULT NULL,
+    PRIMARY KEY (`id`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+DROP TABLE IF EXISTS `sc_student`;
+CREATE TABLE `sc_student`
+(
+    `id`                 bigint      NOT NULL AUTO_INCREMENT,
+    `exam_id`            bigint      NOT NULL,
+    `exam_number`        varchar(64) NOT NULL,
+    `student_code`       varchar(64) NOT NULL,
+    `name`               varchar(64) NOT NULL,
+    `subject_code`       varchar(64) NOT NULL,
+    `package_code`       varchar(64) DEFAULT NULL,
+    `exam_site`          varchar(64) DEFAULT NULL,
+    `exam_room`          varchar(64) DEFAULT NULL,
+    `seat_number`        varchar(16) DEFAULT NULL,
+    `campus_name`        varchar(64) DEFAULT NULL,
+    `status`             varchar(16) NOT NULL,
+    `omr_absent`         bit(1)      NOT NULL,
+    `question_filled`    bit(1)      NOT NULL,
+    `assigned`           bit(1)      NOT NULL,
+    `absent_suspect`     bit(1)      NOT NULL,
+    `incomplete`         bit(1)      NOT NULL,
+    `card_number`        int         DEFAULT NULL,
+    `paper_type`         varchar(16) NOT NULL,
+    `file_upload_status` varchar(16) DEFAULT NULL,
+    `data_upload_status` varchar(16) DEFAULT NULL,
+    `creator_id`         bigint      DEFAULT NULL,
+    `updater_id`         bigint      DEFAULT NULL,
+    `create_time`        bigint      DEFAULT NULL,
+    `update_time`        bigint      DEFAULT NULL,
+    PRIMARY KEY (`id`),
+    UNIQUE KEY `exam_number` (`exam_id`, `exam_number`),
+    UNIQUE KEY `exam_student_subject` (`exam_id`, `student_code`, `subject_code`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+DROP TABLE IF EXISTS `sc_student_paper`;
+CREATE TABLE `sc_student_paper`
+(
+    `student_id`   bigint NOT NULL,
+    `paper_number` int    NOT NULL,
+    `paper_id`     bigint NOT NULL,
+    `creator_id`   bigint DEFAULT NULL,
+    `updater_id`   bigint DEFAULT NULL,
+    `create_time`  bigint DEFAULT NULL,
+    `update_time`  bigint DEFAULT NULL,
+    PRIMARY KEY (`student_id`, `paper_number`),
+    UNIQUE KEY `paper_id` (`paper_id`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+DROP TABLE IF EXISTS `sc_subject`;
+CREATE TABLE `sc_subject`
+(
+    `exam_id`     bigint      NOT NULL,
+    `code`        varchar(64) NOT NULL,
+    `name`        varchar(64) NOT NULL,
+    `creator_id`  bigint DEFAULT NULL,
+    `updater_id`  bigint DEFAULT NULL,
+    `create_time` bigint DEFAULT NULL,
+    `update_time` bigint DEFAULT NULL,
+    PRIMARY KEY (`exam_id`, `code`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+DROP TABLE IF EXISTS `sc_file_property`;
+CREATE TABLE `sc_file_property`
+(
+    `path`        varchar(255) NOT NULL,
+    `md5`         varchar(32)  NOT NULL,
+    `exam_id`     bigint       NOT NULL,
+    `create_time` bigint DEFAULT NULL,
+    `update_time` bigint DEFAULT NULL,
+    PRIMARY KEY (`path`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+
+DROP TABLE IF EXISTS `sc_user`;
+CREATE TABLE `sc_user`
+(
+    `id`          int(11)     NOT NULL AUTO_INCREMENT,
+    `login_name`  varchar(64) NOT NULL,
+    `name`        varchar(64) NOT NULL,
+    `password`    varchar(64) NOT NULL,
+    `role`        varchar(16) NOT NULL,
+    `enable`      tinyint(1)  NOT NULL,
+    `school_id`   bigint      NOT NULL,
+    `creator_id`  bigint DEFAULT NULL,
+    `updater_id`  bigint DEFAULT NULL,
+    `create_time` bigint DEFAULT NULL,
+    `update_time` bigint DEFAULT NULL,
+    PRIMARY KEY (`id`),
+    UNIQUE KEY `login_name` (`login_name`)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4;
+

+ 3 - 0
db/system_config_cet.sql

@@ -0,0 +1,3 @@
+INSERT INTO `sc_user` (`id`,`school_id`,`role`, `create_time`, `update_time`, `enable`, `login_name`, `name`, `password`,`creator_id`,`updater_id`) VALUES (1,1,'SCHOOL_ADMIN', unix_timestamp(now())*1000, unix_timestamp(now())*1000, 1, 'admin', '学校管理员', UPPER(SHA2('123456',256)),1,1);
+
+INSERT INTO `sc_system_config` (`id`, `create_time`, `update_time`, `creator_id`, `updater_id`, `scanner_enable_login`, `scanner_password`, `system_mode`, `client_version`, `client_uri`, `client_md5`, `client_update_time`,`image_transfer_mode`) VALUES (1, NULL, NULL, NULL, NULL, 1, NULL, 'STANDALONE', NULL, NULL, NULL, NULL,'CET');

+ 1 - 0
db/system_config_marking.sql

@@ -0,0 +1 @@
+INSERT INTO `sc_system_config` (`id`, `create_time`, `update_time`, `creator_id`, `updater_id`, `scanner_enable_login`, `scanner_password`, `system_mode`, `client_version`, `client_uri`, `client_md5`, `client_update_time`,`image_transfer_mode`) VALUES (1, NULL, NULL, NULL, NULL, 1, NULL, 'MARKING_CLOUD', NULL, NULL, NULL, NULL,NULL);

+ 3 - 0
db/system_config_ow.sql

@@ -0,0 +1,3 @@
+INSERT INTO `sc_user` (`id`,`school_id`,`role`, `create_time`, `update_time`, `enable`, `login_name`, `name`, `password`,`creator_id`,`updater_id`) VALUES (1,1,'SCHOOL_ADMIN', unix_timestamp(now())*1000, unix_timestamp(now())*1000, 1, 'admin', '学校管理员', UPPER(SHA2('123456',256)),1,1);
+
+INSERT INTO `sc_system_config` (`id`, `create_time`, `update_time`, `creator_id`, `updater_id`, `scanner_enable_login`, `scanner_password`, `system_mode`, `client_version`, `client_uri`, `client_md5`, `client_update_time`,`image_transfer_mode`) VALUES (1, NULL, NULL, NULL, NULL, 1, NULL, 'STANDALONE', NULL, NULL, NULL, NULL,'OW');

+ 11 - 0
jenkins.sh

@@ -0,0 +1,11 @@
+#!/bin/bash
+
+pwd
+
+cp target/scancloud.jar ~/project/scancloud/scancloud
+BUILD_ID=DONTKILLME
+bash ~/project/scancloud/scancloud/stop.sh
+sleep 5s
+bash ~/project/scancloud/scancloud/start.sh
+
+echo "finished..."

+ 240 - 104
pom.xml

@@ -1,112 +1,248 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	<groupId>cn.com.qmth</groupId>
-	<artifactId>scancloud</artifactId>
-	<version>1.0.0</version>
-	<packaging>jar</packaging>
-	<name>api-demo</name>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>cn.com.qmth</groupId>
+    <artifactId>scancloud</artifactId>
+    <version>1.0.0</version>
+    <packaging>jar</packaging>
 
-	<properties>
-		<spring-boot.version>2.3.12.RELEASE</spring-boot.version>
-		<qmth-boot-version>1.0.2</qmth-boot-version>
-		<maven-compiler-version>3.8.1</maven-compiler-version>
-		<maven-surefire-version>2.22.2</maven-surefire-version>
-		<maven.compiler.source>1.8</maven.compiler.source>
-		<maven.compiler.target>1.8</maven.compiler.target>
-		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-	</properties>
-	<repositories>
-		<repository>
-			<id>nexus</id>
-			<name>nexus</name>
-			<url>http://192.168.10.201:8081/repository/maven-public/</url>
-		</repository>
-	</repositories>
-	<pluginRepositories>
-		<pluginRepository>
-			<id>nexus</id>
-			<name>nexus</name>
-			<url>http://192.168.10.201:8081/repository/maven-public/</url>
-		</pluginRepository>
-	</pluginRepositories>
-	<dependencies>
-		<dependency>
-			<groupId>com.qmth.boot</groupId>
-			<artifactId>starter-api</artifactId>
-			<version>${qmth-boot-version}</version>
-		</dependency>
+	<parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.3.12.RELEASE</version>
+        <relativePath/>
+    </parent>
 
-		<dependency>
-			<groupId>com.qmth.boot</groupId>
-			<artifactId>data-mybatis-plus</artifactId>
-			<version>${qmth-boot-version}</version>
-		</dependency>
+    <properties>
+        <spring-boot.version>2.3.12.RELEASE</spring-boot.version>
+        <mybatis-plus.version>3.4.3.3</mybatis-plus.version>
+        <maven-compiler-version>3.8.1</maven-compiler-version>
+        <maven-surefire-version>2.22.2</maven-surefire-version>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <qmth-boot-version>1.0.3</qmth-boot-version>
+    </properties>
 
-		<dependency>
-			<groupId>com.qmth.boot</groupId>
-			<artifactId>core-uid</artifactId>
-			<version>${qmth-boot-version}</version>
-		</dependency>
-		<dependency>
-			<groupId>com.qmth.boot</groupId>
-			<artifactId>core-solar</artifactId>
-			<version>${qmth-boot-version}</version>
-		</dependency>
+    <repositories>
+        <repository>
+            <id>nexus</id>
+            <name>nexus</name>
+            <url>http://192.168.10.201:8081/repository/maven-public/</url>
+        </repository>
+    </repositories>
+    <pluginRepositories>
+        <pluginRepository>
+            <id>nexus</id>
+            <name>nexus</name>
+            <url>http://192.168.10.201:8081/repository/maven-public/</url>
+        </pluginRepository>
+    </pluginRepositories>
 
-	</dependencies>
-	<dependencyManagement>
-		<dependencies>
-			<dependency>
-				<groupId>org.springframework.boot</groupId>
-				<artifactId>spring-boot-dependencies</artifactId>
-				<version>${spring-boot.version}</version>
-				<type>pom</type>
-				<scope>import</scope>
-			</dependency>
-		</dependencies>
-	</dependencyManagement>
+    <dependencies>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>core-security</artifactId>
+            <version>${qmth-boot-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>starter-api</artifactId>
+            <version>${qmth-boot-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>data-mybatis-plus</artifactId>
+            <version>${qmth-boot-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>core-schedule</artifactId>
+            <version>${qmth-boot-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.jeffreyning</groupId>
+            <artifactId>mybatisplus-plus</artifactId>
+            <version>1.5.1-RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>core-fss</artifactId>
+            <version>${qmth-boot-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>core-retrofit</artifactId>
+            <version>${qmth-boot-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>core-concurrent</artifactId>
+            <version>${qmth-boot-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>tools-poi</artifactId>
+            <version>${qmth-boot-version}</version>
+        </dependency>
 
-	<build>
-		<finalName>${project.artifactId}</finalName>
-		<plugins>
-			<plugin>
-				<groupId>org.springframework.boot</groupId>
-				<artifactId>spring-boot-maven-plugin</artifactId>
-			</plugin>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-surefire-plugin</artifactId>
-				<version>${maven-surefire-version}</version>
-				<configuration>
-					<testFailureIgnore>true</testFailureIgnore>
-					<skipTests>true</skipTests>
-					<skip>true</skip>
-				</configuration>
-			</plugin>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-jar-plugin</artifactId>
-				<configuration>
-					<archive>
-						<manifest>
-							<mainClass>cn.com.qmth.print.manage.ApiApplication</mainClass>
-							<addClasspath>true</addClasspath>
-							<classpathPrefix>./</classpathPrefix>
-						</manifest>
-						<manifestEntries>
-							<Class-Path>../config/</Class-Path>
-						</manifestEntries>
-					</archive>
-					<excludes>
-						<exclude>*.properties</exclude>
-						<exclude>*.xml</exclude>
-					</excludes>
-				</configuration>
-			</plugin>
-		</plugins>
-	</build>
+
+        <!-- Swagger jars start -->
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>knife4j-spring-boot-starter</artifactId>
+            <version>2.0.9</version>
+        </dependency>
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-annotations</artifactId>
+            <version>1.5.24</version>
+        </dependency>
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-models</artifactId>
+            <version>1.5.24</version>
+        </dependency>
+        <!-- Swagger jars end -->
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>30.1.1-jre</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-collections4</artifactId>
+            <version>4.4</version>
+        </dependency>
+        <dependency>
+            <groupId>com.thoughtworks.xstream</groupId>
+            <artifactId>xstream</artifactId>
+            <version>1.4.16</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.8.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-text</artifactId>
+            <version>1.9</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+            <version>1.4</version>
+        </dependency>
+        <dependency>
+            <groupId>org.quartz-scheduler</groupId>
+            <artifactId>quartz</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>c3p0</artifactId>
+                    <groupId>com.mchange</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>*</artifactId>
+                    <groupId>com.zaxxer</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.quartz-scheduler</groupId>
+            <artifactId>quartz-jobs</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>net.sf.json-lib</groupId>
+            <artifactId>json-lib-ext-spring</artifactId>
+            <version>1.0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>core-cache</artifactId>
+            <version>${qmth-boot-version}</version>
+        </dependency>
+    </dependencies>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <!-- 
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>${maven-surefire-version}</version>
+                <configuration>
+                    <testFailureIgnore>true</testFailureIgnore>
+                    <skipTests>true</skipTests>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+            
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <mainClass>cn.com.qmth.scancloud.ApiApplication</mainClass>
+                            <addClasspath>true</addClasspath>
+                            <classpathPrefix>./</classpathPrefix>
+                        </manifest>
+                        <manifestEntries>
+                            <Class-Path>../config/</Class-Path>
+                        </manifestEntries>
+                    </archive>
+                    <excludes>
+                        <exclude>importtemplates/*</exclude>
+                        <exclude>mapper/*</exclude>
+                        <exclude>*.properties</exclude>
+                        <exclude>*.xml</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <configuration>
+                    <finalName>${project.artifactId}</finalName>
+                    <descriptors>
+                        <descriptor>assembly.xml</descriptor>
+                    </descriptors>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>make-assembly</id>
+                        <phase>install</phase>
+                        <goals>
+                            <goal>assembly</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            -->
+        </plugins>
+    </build>
 </project>

+ 1 - 0
shell/start.args

@@ -0,0 +1 @@
+--spring.profiles.active=dev

+ 28 - 0
shell/start.sh

@@ -0,0 +1,28 @@
+#!/bin/bash
+
+FILE_PATH=$(cd `dirname $0`; pwd)
+
+APP_MAIN_JAR="scancloud.jar"
+
+JAVA_OPTS=`cat $FILE_PATH/start.vmoptions`
+APP_ARGS=`cat $FILE_PATH/start.args`
+
+PID_LIST=`ps -ef|grep $APP_MAIN_JAR|grep java|awk '{print $2}'`
+
+if [ ! -z "$PID_LIST" ]; then
+    echo "[ERROR] : APP is already running!"
+    exit -1
+fi
+
+
+
+echo "java options:"
+echo "$JAVA_OPTS"
+echo "args:"
+echo "$APP_ARGS"
+    
+nohup java $JAVA_OPTS -jar $FILE_PATH/$APP_MAIN_JAR $APP_ARGS >/dev/null 2>&1 &
+
+echo "starting......"
+
+exit 0

+ 1 - 0
shell/start.vmoptions

@@ -0,0 +1 @@
+-server -Xms256m -Xmx256m -XX:-UseGCOverheadLimit -Dlog.commonLevel=INFO

+ 17 - 0
shell/stop.sh

@@ -0,0 +1,17 @@
+#!/bin/bash
+FILE_PATH=$(cd `dirname $0`; pwd)
+
+APP_MAIN_JAR="scancloud.jar"
+
+PID_LIST=`ps -ef|grep $APP_MAIN_JAR|grep java|awk '{print $2}'`
+
+if [ ! -z "$PID_LIST" ]; then
+    echo "Runnable jar is $APP_MAIN_JAR."
+    for PID in $PID_LIST 
+    do
+        kill -9 $PID
+    done
+    echo "stopped !"
+fi
+
+exit 0

+ 18 - 0
src/main/java/cn/com/qmth/scancloud/ApiApplication.java

@@ -3,15 +3,33 @@ package cn.com.qmth.scancloud;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
+import com.github.jeffreyning.mybatisplus.conf.EnableMPP;
+import com.qmth.boot.core.retrofit.annotatioin.RetrofitScan;
+
+import cn.com.qmth.scancloud.client.MarkingcloudApiConfiguration;
+import cn.com.qmth.scancloud.client.MarkingcloudProperties;
+
+@EnableMPP
 @SpringBootApplication
+@EnableAsync
+@EnableScheduling
 @Configuration
 @MapperScan("cn.com.qmth.scancloud.dao")
+@RetrofitScan("cn.com.qmth.scancloud.client")
 public class ApiApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(ApiApplication.class, args);
     }
 
+    @Bean
+    public MarkingcloudApiConfiguration apiConfiguration(MarkingcloudProperties p) {
+        return new MarkingcloudApiConfiguration(p);
+    }
+
 }

+ 66 - 0
src/main/java/cn/com/qmth/scancloud/bean/AbsentQueryDomain.java

@@ -0,0 +1,66 @@
+package cn.com.qmth.scancloud.bean;
+
+import java.util.List;
+
+import cn.com.qmth.scancloud.enums.GroupType;
+import cn.com.qmth.scancloud.util.PagerQuery;
+
+public class AbsentQueryDomain extends PagerQuery{
+	private Long examId;
+	private GroupType groupType;
+	private List<String> status;
+	private String campusName;
+	private String subjectCode;
+	private String examSite;
+	private String examRoom;
+	private Boolean scanned;
+	public Long getExamId() {
+		return examId;
+	}
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+	public GroupType getGroupType() {
+		return groupType;
+	}
+	public void setGroupType(GroupType groupType) {
+		this.groupType = groupType;
+	}
+	public List<String> getStatus() {
+		return status;
+	}
+	public void setStatus(List<String> status) {
+		this.status = status;
+	}
+	public String getCampusName() {
+		return campusName;
+	}
+	public void setCampusName(String campusName) {
+		this.campusName = campusName;
+	}
+	public String getSubjectCode() {
+		return subjectCode;
+	}
+	public void setSubjectCode(String subjectCode) {
+		this.subjectCode = subjectCode;
+	}
+	public String getExamSite() {
+		return examSite;
+	}
+	public void setExamSite(String examSite) {
+		this.examSite = examSite;
+	}
+	public String getExamRoom() {
+		return examRoom;
+	}
+	public void setExamRoom(String examRoom) {
+		this.examRoom = examRoom;
+	}
+	public Boolean getScanned() {
+		return scanned;
+	}
+	public void setScanned(Boolean scanned) {
+		this.scanned = scanned;
+	}
+	
+}

+ 18 - 0
src/main/java/cn/com/qmth/scancloud/bean/AnswerDeleteDomain.java

@@ -0,0 +1,18 @@
+package cn.com.qmth.scancloud.bean;
+
+public class AnswerDeleteDomain {
+	private Long examId;
+	private String examNumber;
+	public Long getExamId() {
+		return examId;
+	}
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+	public String getExamNumber() {
+		return examNumber;
+	}
+	public void setExamNumber(String examNumber) {
+		this.examNumber = examNumber;
+	}
+}

+ 132 - 0
src/main/java/cn/com/qmth/scancloud/bean/AnswerQueryDomain.java

@@ -0,0 +1,132 @@
+package cn.com.qmth.scancloud.bean;
+
+import java.util.List;
+
+import cn.com.qmth.scancloud.enums.ScanStatus;
+import cn.com.qmth.scancloud.util.PagerQuery;
+
+public class AnswerQueryDomain extends PagerQuery{
+	private Long examId;
+	private List<ScanStatus> status;
+	private String examNumber;
+	private String studentCode;
+	private String name;
+	private String packageCode;
+	private String campusName;
+	private String subjectCode;
+	private String examSite;
+	private String examRoom;
+	private Boolean absentSuspect;
+	private Boolean omrAbsent;
+	private Boolean assigned;
+	private Boolean incomplete;
+	private Boolean questionFilled;
+	private Boolean withOmrDetail;
+	private String paperType;
+	public Long getExamId() {
+		return examId;
+	}
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+	
+    public List<ScanStatus> getStatus() {
+        return status;
+    }
+    
+    public void setStatus(List<ScanStatus> status) {
+        this.status = status;
+    }
+    public String getExamNumber() {
+		return examNumber;
+	}
+	public void setExamNumber(String examNumber) {
+		this.examNumber = examNumber;
+	}
+	public String getStudentCode() {
+		return studentCode;
+	}
+	public void setStudentCode(String studentCode) {
+		this.studentCode = studentCode;
+	}
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public String getPackageCode() {
+		return packageCode;
+	}
+	public void setPackageCode(String packageCode) {
+		this.packageCode = packageCode;
+	}
+	public String getCampusName() {
+		return campusName;
+	}
+	public void setCampusName(String campusName) {
+		this.campusName = campusName;
+	}
+	public String getSubjectCode() {
+		return subjectCode;
+	}
+	public void setSubjectCode(String subjectCode) {
+		this.subjectCode = subjectCode;
+	}
+	public String getExamSite() {
+		return examSite;
+	}
+	public void setExamSite(String examSite) {
+		this.examSite = examSite;
+	}
+	public String getExamRoom() {
+		return examRoom;
+	}
+	public void setExamRoom(String examRoom) {
+		this.examRoom = examRoom;
+	}
+	public Boolean getAbsentSuspect() {
+		return absentSuspect;
+	}
+	public void setAbsentSuspect(Boolean absentSuspect) {
+		this.absentSuspect = absentSuspect;
+	}
+	public Boolean getOmrAbsent() {
+		return omrAbsent;
+	}
+	public void setOmrAbsent(Boolean omrAbsent) {
+		this.omrAbsent = omrAbsent;
+	}
+	public Boolean getAssigned() {
+		return assigned;
+	}
+	public void setAssigned(Boolean assigned) {
+		this.assigned = assigned;
+	}
+	public Boolean getIncomplete() {
+		return incomplete;
+	}
+	public void setIncomplete(Boolean incomplete) {
+		this.incomplete = incomplete;
+	}
+	public Boolean getQuestionFilled() {
+		return questionFilled;
+	}
+	public void setQuestionFilled(Boolean questionFilled) {
+		this.questionFilled = questionFilled;
+	}
+	public Boolean getWithOmrDetail() {
+		return withOmrDetail;
+	}
+	public void setWithOmrDetail(Boolean withOmrDetail) {
+		this.withOmrDetail = withOmrDetail;
+	}
+	public String getPaperType() {
+		return paperType;
+	}
+	public void setPaperType(String paperType) {
+		this.paperType = paperType;
+	}
+	
+	
+}

+ 21 - 0
src/main/java/cn/com/qmth/scancloud/bean/BatchCreateDomain.java

@@ -0,0 +1,21 @@
+package cn.com.qmth.scancloud.bean;
+
+import java.util.List;
+
+public class BatchCreateDomain {
+	private Long examId;
+	private List<String> examNumbers;
+	public Long getExamId() {
+		return examId;
+	}
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+	public List<String> getExamNumbers() {
+		return examNumbers;
+	}
+	public void setExamNumbers(List<String> examNumbers) {
+		this.examNumbers = examNumbers;
+	}
+	
+}

+ 42 - 0
src/main/java/cn/com/qmth/scancloud/bean/BatchQueryDomain.java

@@ -0,0 +1,42 @@
+package cn.com.qmth.scancloud.bean;
+
+import cn.com.qmth.scancloud.util.PagerQuery;
+
+public class BatchQueryDomain extends PagerQuery{
+	private Long examId;
+	private String device;
+	private Long startTime;
+	private Long endTime;
+	private Boolean withVerify;
+	public Long getExamId() {
+		return examId;
+	}
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+	public String getDevice() {
+		return device;
+	}
+	public void setDevice(String device) {
+		this.device = device;
+	}
+	public Long getStartTime() {
+		return startTime;
+	}
+	public void setStartTime(Long startTime) {
+		this.startTime = startTime;
+	}
+	public Long getEndTime() {
+		return endTime;
+	}
+	public void setEndTime(Long endTime) {
+		this.endTime = endTime;
+	}
+	public Boolean getWithVerify() {
+		return withVerify;
+	}
+	public void setWithVerify(Boolean withVerify) {
+		this.withVerify = withVerify;
+	}
+	
+}

+ 28 - 0
src/main/java/cn/com/qmth/scancloud/bean/CardAnswerDomain.java

@@ -0,0 +1,28 @@
+package cn.com.qmth.scancloud.bean;
+
+import java.util.List;
+
+public class CardAnswerDomain {
+	private Long examId;
+	private List<String> device;
+	private Integer cardNumber;
+	public Long getExamId() {
+		return examId;
+	}
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+	public List<String> getDevice() {
+		return device;
+	}
+	public void setDevice(List<String> device) {
+		this.device = device;
+	}
+	public Integer getCardNumber() {
+		return cardNumber;
+	}
+	public void setCardNumber(Integer cardNumber) {
+		this.cardNumber = cardNumber;
+	}
+	
+}

+ 79 - 0
src/main/java/cn/com/qmth/scancloud/bean/ExamConfigDomain.java

@@ -0,0 +1,79 @@
+package cn.com.qmth.scancloud.bean;
+
+import java.util.List;
+
+import cn.com.qmth.scancloud.enums.ExamMode;
+
+public class ExamConfigDomain {
+	private Long id;
+	private ExamMode mode;
+	private Boolean scanByPackage;
+	private Boolean enableSyncVerify;
+	private Boolean allowUnexistPaper;
+	private Integer answerFrontCardType;
+	private Boolean enableSinglePageAnswer;
+	private Integer answerPaperNumberFigure;
+	private List<String> paperTypeBarcodeContent;
+	private String absentBarcodeContent;
+	public Long getId() {
+		return id;
+	}
+	public void setId(Long id) {
+		this.id = id;
+	}
+	public ExamMode getMode() {
+		return mode;
+	}
+	public void setMode(ExamMode mode) {
+		this.mode = mode;
+	}
+	public Boolean getScanByPackage() {
+		return scanByPackage;
+	}
+	public void setScanByPackage(Boolean scanByPackage) {
+		this.scanByPackage = scanByPackage;
+	}
+	public Boolean getEnableSyncVerify() {
+		return enableSyncVerify;
+	}
+	public void setEnableSyncVerify(Boolean enableSyncVerify) {
+		this.enableSyncVerify = enableSyncVerify;
+	}
+	public Boolean getAllowUnexistPaper() {
+		return allowUnexistPaper;
+	}
+	public void setAllowUnexistPaper(Boolean allowUnexistPaper) {
+		this.allowUnexistPaper = allowUnexistPaper;
+	}
+	public Integer getAnswerFrontCardType() {
+		return answerFrontCardType;
+	}
+	public void setAnswerFrontCardType(Integer answerFrontCardType) {
+		this.answerFrontCardType = answerFrontCardType;
+	}
+	public Boolean getEnableSinglePageAnswer() {
+		return enableSinglePageAnswer;
+	}
+	public void setEnableSinglePageAnswer(Boolean enableSinglePageAnswer) {
+		this.enableSinglePageAnswer = enableSinglePageAnswer;
+	}
+	public Integer getAnswerPaperNumberFigure() {
+		return answerPaperNumberFigure;
+	}
+	public void setAnswerPaperNumberFigure(Integer answerPaperNumberFigure) {
+		this.answerPaperNumberFigure = answerPaperNumberFigure;
+	}
+	public List<String> getPaperTypeBarcodeContent() {
+		return paperTypeBarcodeContent;
+	}
+	public void setPaperTypeBarcodeContent(List<String> paperTypeBarcodeContent) {
+		this.paperTypeBarcodeContent = paperTypeBarcodeContent;
+	}
+	public String getAbsentBarcodeContent() {
+		return absentBarcodeContent;
+	}
+	public void setAbsentBarcodeContent(String absentBarcodeContent) {
+		this.absentBarcodeContent = absentBarcodeContent;
+	}
+	
+}

+ 104 - 0
src/main/java/cn/com/qmth/scancloud/bean/ImportExamDomain.java

@@ -0,0 +1,104 @@
+package cn.com.qmth.scancloud.bean;
+
+import java.util.List;
+
+import cn.com.qmth.scancloud.enums.ExamMode;
+
+public class ImportExamDomain {
+	private Long id;
+	private Long schoolId;
+	private String schoolName;
+	private String name;
+	private ExamMode mode;
+	private Boolean scanByPackage;
+	private Boolean enableSyncVerify;
+	private Boolean allowUnexistPaper;
+	private Integer answerFrontCardType;
+	private Boolean enableSinglePageAnswer;
+	private Integer answerPaperNumberFigure;
+	private List<String> paperTypeBarcodeContent;
+	private String absentBarcodeContent;
+	public Long getId() {
+		return id;
+	}
+	public void setId(Long id) {
+		this.id = id;
+	}
+	public ExamMode getMode() {
+		return mode;
+	}
+	public void setMode(ExamMode mode) {
+		this.mode = mode;
+	}
+	public Boolean getScanByPackage() {
+		return scanByPackage;
+	}
+	public void setScanByPackage(Boolean scanByPackage) {
+		this.scanByPackage = scanByPackage;
+	}
+	public Boolean getEnableSyncVerify() {
+		return enableSyncVerify;
+	}
+	public void setEnableSyncVerify(Boolean enableSyncVerify) {
+		this.enableSyncVerify = enableSyncVerify;
+	}
+	public Boolean getAllowUnexistPaper() {
+		return allowUnexistPaper;
+	}
+	public void setAllowUnexistPaper(Boolean allowUnexistPaper) {
+		this.allowUnexistPaper = allowUnexistPaper;
+	}
+	public Integer getAnswerFrontCardType() {
+		return answerFrontCardType;
+	}
+	public void setAnswerFrontCardType(Integer answerFrontCardType) {
+		this.answerFrontCardType = answerFrontCardType;
+	}
+	public Boolean getEnableSinglePageAnswer() {
+		return enableSinglePageAnswer;
+	}
+	public void setEnableSinglePageAnswer(Boolean enableSinglePageAnswer) {
+		this.enableSinglePageAnswer = enableSinglePageAnswer;
+	}
+	public Integer getAnswerPaperNumberFigure() {
+		return answerPaperNumberFigure;
+	}
+	public void setAnswerPaperNumberFigure(Integer answerPaperNumberFigure) {
+		this.answerPaperNumberFigure = answerPaperNumberFigure;
+	}
+	public List<String> getPaperTypeBarcodeContent() {
+		return paperTypeBarcodeContent;
+	}
+	public void setPaperTypeBarcodeContent(List<String> paperTypeBarcodeContent) {
+		this.paperTypeBarcodeContent = paperTypeBarcodeContent;
+	}
+	public String getAbsentBarcodeContent() {
+		return absentBarcodeContent;
+	}
+	public void setAbsentBarcodeContent(String absentBarcodeContent) {
+		this.absentBarcodeContent = absentBarcodeContent;
+	}
+    
+    public Long getSchoolId() {
+        return schoolId;
+    }
+    
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+	public String getSchoolName() {
+		return schoolName;
+	}
+	public void setSchoolName(String schoolName) {
+		this.schoolName = schoolName;
+	}
+	
+}

+ 122 - 0
src/main/java/cn/com/qmth/scancloud/bean/ImportStudentDomain.java

@@ -0,0 +1,122 @@
+package cn.com.qmth.scancloud.bean;
+
+public class ImportStudentDomain {
+
+    private Long examId;
+    private String subjectCode;
+    private String subjectName;
+    private String examNumber;
+    private String name;
+    private String studentCode;
+    private String packageCode;
+    private String examSite;
+    private String examRoom;
+    private String seatNumber;
+    private String campusName;
+
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+
+    public String getSubjectCode() {
+        return subjectCode;
+    }
+
+    public void setSubjectCode(String subjectCode) {
+        this.subjectCode = subjectCode;
+    }
+
+    
+    public String getExamNumber() {
+        return examNumber;
+    }
+
+    
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
+    }
+
+    
+    public String getName() {
+        return name;
+    }
+
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    
+    public String getStudentCode() {
+        return studentCode;
+    }
+
+    
+    public void setStudentCode(String studentCode) {
+        this.studentCode = studentCode;
+    }
+
+    
+    public String getPackageCode() {
+        return packageCode;
+    }
+
+    
+    public void setPackageCode(String packageCode) {
+        this.packageCode = packageCode;
+    }
+
+    
+    public String getExamSite() {
+        return examSite;
+    }
+
+    
+    public void setExamSite(String examSite) {
+        this.examSite = examSite;
+    }
+
+    
+    public String getExamRoom() {
+        return examRoom;
+    }
+
+    
+    public void setExamRoom(String examRoom) {
+        this.examRoom = examRoom;
+    }
+
+    
+    public String getSeatNumber() {
+        return seatNumber;
+    }
+
+    
+    public void setSeatNumber(String seatNumber) {
+        this.seatNumber = seatNumber;
+    }
+
+    
+    public String getCampusName() {
+        return campusName;
+    }
+
+    
+    public void setCampusName(String campusName) {
+        this.campusName = campusName;
+    }
+
+	public String getSubjectName() {
+		return subjectName;
+	}
+
+	public void setSubjectName(String subjectName) {
+		this.subjectName = subjectName;
+	}
+
+
+}

+ 35 - 0
src/main/java/cn/com/qmth/scancloud/bean/ImportSubjectDomain.java

@@ -0,0 +1,35 @@
+package cn.com.qmth.scancloud.bean;
+
+public class ImportSubjectDomain {
+
+    private Long examId;
+
+    private String subjectCode;
+
+    private String subjectName;
+
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+
+    public String getSubjectCode() {
+        return subjectCode;
+    }
+
+    public void setSubjectCode(String subjectCode) {
+        this.subjectCode = subjectCode;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+
+}

+ 59 - 0
src/main/java/cn/com/qmth/scancloud/bean/ImportUserDomain.java

@@ -0,0 +1,59 @@
+package cn.com.qmth.scancloud.bean;
+
+import cn.com.qmth.scancloud.enums.Role;
+
+public class ImportUserDomain {
+
+	private Long schoolId;
+	
+    private String name;
+
+    private String loginName;
+
+    private String password;
+
+    private Role role;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getLoginName() {
+        return loginName;
+    }
+
+    public void setLoginName(String loginName) {
+        this.loginName = loginName;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public Role getRole() {
+        return role;
+    }
+
+    public void setRole(Role role) {
+        this.role = role;
+    }
+
+	public Long getSchoolId() {
+		return schoolId;
+	}
+
+	public void setSchoolId(Long schoolId) {
+		this.schoolId = schoolId;
+	}
+    
+    
+
+}

+ 21 - 0
src/main/java/cn/com/qmth/scancloud/bean/MismatchQueryDomain.java

@@ -0,0 +1,21 @@
+package cn.com.qmth.scancloud.bean;
+
+import cn.com.qmth.scancloud.util.PagerQuery;
+
+public class MismatchQueryDomain extends PagerQuery{
+	private Long examId;
+	private String subjectCode;
+	public Long getExamId() {
+		return examId;
+	}
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+	public String getSubjectCode() {
+		return subjectCode;
+	}
+	public void setSubjectCode(String subjectCode) {
+		this.subjectCode = subjectCode;
+	}
+	
+}

+ 19 - 0
src/main/java/cn/com/qmth/scancloud/bean/MismatchToggleDomain.java

@@ -0,0 +1,19 @@
+package cn.com.qmth.scancloud.bean;
+
+public class MismatchToggleDomain {
+	private Long paperId;
+	private Boolean enable;
+	public Long getPaperId() {
+		return paperId;
+	}
+	public void setPaperId(Long paperId) {
+		this.paperId = paperId;
+	}
+	public Boolean getEnable() {
+		return enable;
+	}
+	public void setEnable(Boolean enable) {
+		this.enable = enable;
+	}
+	
+}

+ 28 - 0
src/main/java/cn/com/qmth/scancloud/bean/OmrTaskDto.java

@@ -0,0 +1,28 @@
+package cn.com.qmth.scancloud.bean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import cn.com.qmth.scancloud.entity.OmrTaskEntity;
+
+public class OmrTaskDto {
+	private OmrTaskEntity task;
+	List<OmrTaskPageDto> page=new ArrayList<>();
+	public OmrTaskDto(OmrTaskEntity task) {
+		super();
+		this.task = task;
+	}
+	public OmrTaskEntity getTask() {
+		return task;
+	}
+	public void setTask(OmrTaskEntity task) {
+		this.task = task;
+	}
+	public List<OmrTaskPageDto> getPage() {
+		return page;
+	}
+	public void setPage(List<OmrTaskPageDto> page) {
+		this.page = page;
+	}
+	
+}

+ 45 - 0
src/main/java/cn/com/qmth/scancloud/bean/OmrTaskPageDto.java

@@ -0,0 +1,45 @@
+package cn.com.qmth.scancloud.bean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import cn.com.qmth.scancloud.model.OmrTaskItem;
+
+public class OmrTaskPageDto {
+	private Integer pageIndex;
+	List<OmrTaskItem> items=new ArrayList<>();
+	List<OmrTaskItem> pageMultiBlankItems=new ArrayList<>();
+	List<OmrTaskItem> pageSingleBlankItems=new ArrayList<>();
+	
+	
+	public OmrTaskPageDto(Integer pageIndex) {
+		super();
+		this.pageIndex = pageIndex;
+	}
+	public Integer getPageIndex() {
+		return pageIndex;
+	}
+	public void setPageIndex(Integer pageIndex) {
+		this.pageIndex = pageIndex;
+	}
+	public List<OmrTaskItem> getItems() {
+		return items;
+	}
+	public void setItems(List<OmrTaskItem> items) {
+		this.items = items;
+	}
+	public List<OmrTaskItem> getPageMultiBlankItems() {
+		return pageMultiBlankItems;
+	}
+	public void setPageMultiBlankItems(List<OmrTaskItem> pageMultiBlankItems) {
+		this.pageMultiBlankItems = pageMultiBlankItems;
+	}
+	public List<OmrTaskItem> getPageSingleBlankItems() {
+		return pageSingleBlankItems;
+	}
+	public void setPageSingleBlankItems(List<OmrTaskItem> pageSingleBlankItems) {
+		this.pageSingleBlankItems = pageSingleBlankItems;
+	}
+
+	
+}

+ 26 - 0
src/main/java/cn/com/qmth/scancloud/bean/PageDeleteDomain.java

@@ -0,0 +1,26 @@
+package cn.com.qmth.scancloud.bean;
+
+public class PageDeleteDomain {
+	private Long examId;
+	private String examNumber;
+	private Integer paperNumber;
+	public Long getExamId() {
+		return examId;
+	}
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+	public String getExamNumber() {
+		return examNumber;
+	}
+	public void setExamNumber(String examNumber) {
+		this.examNumber = examNumber;
+	}
+	public Integer getPaperNumber() {
+		return paperNumber;
+	}
+	public void setPaperNumber(Integer paperNumber) {
+		this.paperNumber = paperNumber;
+	}
+	
+}

+ 31 - 0
src/main/java/cn/com/qmth/scancloud/bean/ScannerLoginInfo.java

@@ -0,0 +1,31 @@
+package cn.com.qmth.scancloud.bean;
+
+import cn.com.qmth.scancloud.support.JsonSerializable;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * 登陆信息
+ * 
+ */
+public class ScannerLoginInfo implements JsonSerializable {
+
+	private static final long serialVersionUID = 1305354276321732681L;
+
+
+	/**
+	 * 密码
+	 */
+	@ApiModelProperty(value = "密码")
+	private String password;
+
+
+	public String getPassword() {
+		return password;
+	}
+
+	public void setPassword(String password) {
+		this.password = password;
+	}
+
+	
+}

+ 62 - 0
src/main/java/cn/com/qmth/scancloud/bean/SchoolSession.java

@@ -0,0 +1,62 @@
+package cn.com.qmth.scancloud.bean;
+
+import cn.com.qmth.scancloud.enums.Role;
+
+public class SchoolSession{
+
+    private Long id;
+
+    private String account;
+
+    private Role role;
+    
+    private String markingCloudToken;
+
+
+    public String getAccount() {
+        return account;
+    }
+
+    public void setAccount(String account) {
+        this.account = account;
+    }
+
+
+    public Role getRole() {
+        return role;
+    }
+
+    public void setRole(Role role) {
+        this.role = role;
+    }
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+
+    
+    public String getMarkingCloudToken() {
+        return markingCloudToken;
+    }
+
+    
+    public void setMarkingCloudToken(String markingCloudToken) {
+        this.markingCloudToken = markingCloudToken;
+    }
+    
+    public static SchoolSession of(User user) {
+    	SchoolSession s=new SchoolSession();
+    	s.setId(user.getSchoolId());
+    	s.setAccount(user.getAccount());
+    	s.setMarkingCloudToken(user.getMarkingCloudToken());
+    	s.setRole(user.getRole());
+    	return s;
+    }
+    
+}

+ 115 - 0
src/main/java/cn/com/qmth/scancloud/bean/User.java

@@ -0,0 +1,115 @@
+package cn.com.qmth.scancloud.bean;
+
+import com.qmth.boot.core.security.model.AccessEntity;
+
+import cn.com.qmth.scancloud.enums.Role;
+
+public class User implements AccessEntity{
+
+    private Long id;
+
+    private String name;
+
+    private String account;
+
+    private String sessionId;
+
+    private String accessToken;
+
+    private Role role;
+
+    private Long activeTime;
+
+    private Long schoolId;
+    
+    private String markingCloudToken;
+
+    public String buildKey() {
+        this.sessionId = new StringBuilder().append(role.name()).append("_").append(account).toString();
+        return this.sessionId;
+    }
+
+    public String getAccount() {
+        return account;
+    }
+
+    public void setAccount(String account) {
+        this.account = account;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getSessionId() {
+        return sessionId;
+    }
+
+    public void setSessionId(String sessionId) {
+        this.sessionId = sessionId;
+    }
+
+    public String getAccessToken() {
+        return accessToken;
+    }
+
+    public void setAccessToken(String accessToken) {
+        this.accessToken = accessToken;
+    }
+
+    public Role getRole() {
+        return role;
+    }
+
+    public void setRole(Role role) {
+        this.role = role;
+    }
+
+    public Long getActiveTime() {
+        return activeTime;
+    }
+
+    public void setActiveTime(Long activeTime) {
+        this.activeTime = activeTime;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+    @Override
+    public String getIdentity() {
+        return sessionId;
+    }
+
+    @Override
+    public String getSecret() {
+        return accessToken;
+    }
+
+    
+    public String getMarkingCloudToken() {
+        return markingCloudToken;
+    }
+
+    
+    public void setMarkingCloudToken(String markingCloudToken) {
+        this.markingCloudToken = markingCloudToken;
+    }
+    
+}

+ 26 - 0
src/main/java/cn/com/qmth/scancloud/bean/WorkloadDomain.java

@@ -0,0 +1,26 @@
+package cn.com.qmth.scancloud.bean;
+
+public class WorkloadDomain {
+	private Long examId;
+	private Long startTime;
+	private Long endTime;
+	public Long getExamId() {
+		return examId;
+	}
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+	public Long getStartTime() {
+		return startTime;
+	}
+	public void setStartTime(Long startTime) {
+		this.startTime = startTime;
+	}
+	public Long getEndTime() {
+		return endTime;
+	}
+	public void setEndTime(Long endTime) {
+		this.endTime = endTime;
+	}
+	
+}

+ 36 - 0
src/main/java/cn/com/qmth/scancloud/bean/answersave/AnswerDomain.java

@@ -0,0 +1,36 @@
+package cn.com.qmth.scancloud.bean.answersave;
+
+import java.util.List;
+
+public class AnswerDomain {
+	private Long batchId;
+	private String examNumber;
+	private Integer cardNumber;
+	private List<AnswerPaper> papers;
+	public Long getBatchId() {
+		return batchId;
+	}
+	public void setBatchId(Long batchId) {
+		this.batchId = batchId;
+	}
+	public String getExamNumber() {
+		return examNumber;
+	}
+	public void setExamNumber(String examNumber) {
+		this.examNumber = examNumber;
+	}
+	public Integer getCardNumber() {
+		return cardNumber;
+	}
+	public void setCardNumber(Integer cardNumber) {
+		this.cardNumber = cardNumber;
+	}
+	public List<AnswerPaper> getPapers() {
+		return papers;
+	}
+	public void setPapers(List<AnswerPaper> papers) {
+		this.papers = papers;
+	}
+	
+	
+}

+ 72 - 0
src/main/java/cn/com/qmth/scancloud/bean/answersave/AnswerPage.java

@@ -0,0 +1,72 @@
+package cn.com.qmth.scancloud.bean.answersave;
+
+import java.util.List;
+
+public class AnswerPage {
+	private Integer index;
+    private String sheetUri;
+    private List<String> sliceUri;
+	private BoolResult absent;
+	private BoolResult breach;
+	private StringResult paperType;
+	private ArrayResult question;
+	private ArrayResult selective;
+	private String recogData;
+	public Integer getIndex() {
+		return index;
+	}
+	public void setIndex(Integer index) {
+		this.index = index;
+	}
+	public BoolResult getAbsent() {
+		return absent;
+	}
+	public void setAbsent(BoolResult absent) {
+		this.absent = absent;
+	}
+	public BoolResult getBreach() {
+		return breach;
+	}
+	public void setBreach(BoolResult breach) {
+		this.breach = breach;
+	}
+	public StringResult getPaperType() {
+		return paperType;
+	}
+	public void setPaperType(StringResult paperType) {
+		this.paperType = paperType;
+	}
+	public ArrayResult getQuestion() {
+		return question;
+	}
+	public void setQuestion(ArrayResult question) {
+		this.question = question;
+	}
+	public ArrayResult getSelective() {
+		return selective;
+	}
+	public void setSelective(ArrayResult selective) {
+		this.selective = selective;
+	}
+	public String getSheetUri() {
+		return sheetUri;
+	}
+	public void setSheetUri(String sheetUri) {
+		this.sheetUri = sheetUri;
+	}
+	public List<String> getSliceUri() {
+		return sliceUri;
+	}
+	public void setSliceUri(List<String> sliceUri) {
+		this.sliceUri = sliceUri;
+	}
+	public String getRecogData() {
+		return recogData;
+	}
+	public void setRecogData(String recogData) {
+		this.recogData = recogData;
+	}
+	
+	
+	
+}

+ 30 - 0
src/main/java/cn/com/qmth/scancloud/bean/answersave/AnswerPaper.java

@@ -0,0 +1,30 @@
+package cn.com.qmth.scancloud.bean.answersave;
+
+import java.util.List;
+
+
+public class AnswerPaper {
+	private Integer number;
+	private Boolean assigned;
+	private List<AnswerPage> pages;
+	public Integer getNumber() {
+		return number;
+	}
+	public void setNumber(Integer number) {
+		this.number = number;
+	}
+	public Boolean getAssigned() {
+		return assigned;
+	}
+	public void setAssigned(Boolean assigned) {
+		this.assigned = assigned;
+	}
+	public List<AnswerPage> getPages() {
+		return pages;
+	}
+	public void setPages(List<AnswerPage> pages) {
+		this.pages = pages;
+	}
+	
+	
+}

+ 29 - 0
src/main/java/cn/com/qmth/scancloud/bean/answersave/ArrayResult.java

@@ -0,0 +1,29 @@
+package cn.com.qmth.scancloud.bean.answersave;
+
+import java.util.List;
+
+import cn.com.qmth.scancloud.enums.OmrType;
+
+public class ArrayResult {
+    private OmrType type;
+
+    private List<String> result;
+
+	public OmrType getType() {
+		return type;
+	}
+
+	public void setType(OmrType type) {
+		this.type = type;
+	}
+
+	public List<String> getResult() {
+		return result;
+	}
+
+	public void setResult(List<String> result) {
+		this.result = result;
+	}
+    
+    
+}

+ 27 - 0
src/main/java/cn/com/qmth/scancloud/bean/answersave/BoolResult.java

@@ -0,0 +1,27 @@
+package cn.com.qmth.scancloud.bean.answersave;
+
+import cn.com.qmth.scancloud.enums.OmrType;
+
+public class BoolResult {
+    private OmrType type;
+
+    private Boolean result;
+
+	public OmrType getType() {
+		return type;
+	}
+
+	public void setType(OmrType type) {
+		this.type = type;
+	}
+
+	public Boolean getResult() {
+		return result;
+	}
+
+	public void setResult(Boolean result) {
+		this.result = result;
+	}
+    
+    
+}

+ 27 - 0
src/main/java/cn/com/qmth/scancloud/bean/answersave/StringResult.java

@@ -0,0 +1,27 @@
+package cn.com.qmth.scancloud.bean.answersave;
+
+import cn.com.qmth.scancloud.enums.OmrType;
+
+public class StringResult {
+    private OmrType type;
+
+    private String result;
+
+	public OmrType getType() {
+		return type;
+	}
+
+	public void setType(OmrType type) {
+		this.type = type;
+	}
+
+	public String getResult() {
+		return result;
+	}
+
+	public void setResult(String result) {
+		this.result = result;
+	}
+    
+    
+}

+ 28 - 0
src/main/java/cn/com/qmth/scancloud/bean/omredit/OmrEditDomain.java

@@ -0,0 +1,28 @@
+package cn.com.qmth.scancloud.bean.omredit;
+
+import java.util.List;
+
+public class OmrEditDomain {
+	private Long examId;
+	private String examNumber;
+	private List<OmrEditPaper> papers;
+	public Long getExamId() {
+		return examId;
+	}
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+	public String getExamNumber() {
+		return examNumber;
+	}
+	public void setExamNumber(String examNumber) {
+		this.examNumber = examNumber;
+	}
+	public List<OmrEditPaper> getPapers() {
+		return papers;
+	}
+	public void setPapers(List<OmrEditPaper> papers) {
+		this.papers = papers;
+	}
+	
+}

+ 50 - 0
src/main/java/cn/com/qmth/scancloud/bean/omredit/OmrEditPage.java

@@ -0,0 +1,50 @@
+package cn.com.qmth.scancloud.bean.omredit;
+
+import cn.com.qmth.scancloud.bean.answersave.ArrayResult;
+import cn.com.qmth.scancloud.bean.answersave.BoolResult;
+import cn.com.qmth.scancloud.bean.answersave.StringResult;
+
+public class OmrEditPage {
+	private Integer index;
+	private BoolResult absent;
+	private BoolResult breach;
+	private StringResult paperType;
+	private ArrayResult question;
+	private ArrayResult selective;
+	public Integer getIndex() {
+		return index;
+	}
+	public void setIndex(Integer index) {
+		this.index = index;
+	}
+	public BoolResult getAbsent() {
+		return absent;
+	}
+	public void setAbsent(BoolResult absent) {
+		this.absent = absent;
+	}
+	public BoolResult getBreach() {
+		return breach;
+	}
+	public void setBreach(BoolResult breach) {
+		this.breach = breach;
+	}
+	public StringResult getPaperType() {
+		return paperType;
+	}
+	public void setPaperType(StringResult paperType) {
+		this.paperType = paperType;
+	}
+	public ArrayResult getQuestion() {
+		return question;
+	}
+	public void setQuestion(ArrayResult question) {
+		this.question = question;
+	}
+	public ArrayResult getSelective() {
+		return selective;
+	}
+	public void setSelective(ArrayResult selective) {
+		this.selective = selective;
+	}
+}

+ 21 - 0
src/main/java/cn/com/qmth/scancloud/bean/omredit/OmrEditPaper.java

@@ -0,0 +1,21 @@
+package cn.com.qmth.scancloud.bean.omredit;
+
+import java.util.List;
+
+public class OmrEditPaper {
+	private Integer number;
+	private List<OmrEditPage> pages;
+	public Integer getNumber() {
+		return number;
+	}
+	public void setNumber(Integer number) {
+		this.number = number;
+	}
+	public List<OmrEditPage> getPages() {
+		return pages;
+	}
+	public void setPages(List<OmrEditPage> pages) {
+		this.pages = pages;
+	}
+	
+}

+ 51 - 0
src/main/java/cn/com/qmth/scancloud/bean/papermigrate/PaperMigrateDomain.java

@@ -0,0 +1,51 @@
+package cn.com.qmth.scancloud.bean.papermigrate;
+
+import java.util.List;
+
+public class PaperMigrateDomain {
+	private Long paperId;
+	private Long examId;
+	private String examNumber;
+	private Integer paperNumber;
+	private Integer cardNumber;
+	private List<PaperMigratePage> pages;
+	public Long getPaperId() {
+		return paperId;
+	}
+	public void setPaperId(Long paperId) {
+		this.paperId = paperId;
+	}
+	public Long getExamId() {
+		return examId;
+	}
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+	public String getExamNumber() {
+		return examNumber;
+	}
+	public void setExamNumber(String examNumber) {
+		this.examNumber = examNumber;
+	}
+	public Integer getPaperNumber() {
+		return paperNumber;
+	}
+	public void setPaperNumber(Integer paperNumber) {
+		this.paperNumber = paperNumber;
+	}
+	
+	
+	public Integer getCardNumber() {
+		return cardNumber;
+	}
+	public void setCardNumber(Integer cardNumber) {
+		this.cardNumber = cardNumber;
+	}
+	public List<PaperMigratePage> getPages() {
+		return pages;
+	}
+	public void setPages(List<PaperMigratePage> pages) {
+		this.pages = pages;
+	}
+	
+}

+ 68 - 0
src/main/java/cn/com/qmth/scancloud/bean/papermigrate/PaperMigratePage.java

@@ -0,0 +1,68 @@
+package cn.com.qmth.scancloud.bean.papermigrate;
+
+import java.util.List;
+
+import cn.com.qmth.scancloud.bean.answersave.ArrayResult;
+import cn.com.qmth.scancloud.bean.answersave.BoolResult;
+import cn.com.qmth.scancloud.bean.answersave.StringResult;
+
+public class PaperMigratePage {
+	private Integer index;
+    private List<String> sliceUri;
+	private BoolResult absent;
+	private BoolResult breach;
+	private StringResult paperType;
+	private ArrayResult question;
+	private ArrayResult selective;
+	private String recogData;
+	public Integer getIndex() {
+		return index;
+	}
+	public void setIndex(Integer index) {
+		this.index = index;
+	}
+	public BoolResult getAbsent() {
+		return absent;
+	}
+	public void setAbsent(BoolResult absent) {
+		this.absent = absent;
+	}
+	public BoolResult getBreach() {
+		return breach;
+	}
+	public void setBreach(BoolResult breach) {
+		this.breach = breach;
+	}
+	public StringResult getPaperType() {
+		return paperType;
+	}
+	public void setPaperType(StringResult paperType) {
+		this.paperType = paperType;
+	}
+	public ArrayResult getQuestion() {
+		return question;
+	}
+	public void setQuestion(ArrayResult question) {
+		this.question = question;
+	}
+	public ArrayResult getSelective() {
+		return selective;
+	}
+	public void setSelective(ArrayResult selective) {
+		this.selective = selective;
+	}
+	public List<String> getSliceUri() {
+		return sliceUri;
+	}
+	public void setSliceUri(List<String> sliceUri) {
+		this.sliceUri = sliceUri;
+	}
+	public String getRecogData() {
+		return recogData;
+	}
+	public void setRecogData(String recogData) {
+		this.recogData = recogData;
+	}
+	
+	
+}

+ 96 - 0
src/main/java/cn/com/qmth/scancloud/client/MarkingcloudApiClient.java

@@ -0,0 +1,96 @@
+package cn.com.qmth.scancloud.client;
+
+import java.util.List;
+
+import com.qmth.boot.core.retrofit.annotatioin.RetrofitClient;
+import com.qmth.boot.core.retrofit.utils.SignatureInfo;
+
+import cn.com.qmth.scancloud.enums.CardSource;
+import cn.com.qmth.scancloud.model.AnswerCardInfo;
+import cn.com.qmth.scancloud.model.DataUploadDto;
+import cn.com.qmth.scancloud.model.DataUploadResponse;
+import cn.com.qmth.scancloud.model.ExamInfoDto;
+import cn.com.qmth.scancloud.model.FileUploadResponse;
+import cn.com.qmth.scancloud.model.StudentInfo;
+import cn.com.qmth.scancloud.model.UserInfo;
+import okhttp3.MultipartBody;
+import retrofit2.http.Body;
+import retrofit2.http.Field;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.Header;
+import retrofit2.http.Multipart;
+import retrofit2.http.POST;
+import retrofit2.http.Part;
+import retrofit2.http.Path;
+import retrofit2.http.Query;
+
+@RetrofitClient(configuration = MarkingcloudApiConfiguration.class)
+public interface MarkingcloudApiClient {
+
+    @FormUrlEncoded
+    @POST("card/answer/query")
+    List<AnswerCardInfo> getAnswerCardInfo(@Header(SignatureInfo.HEADER_NAME) String signatureInfo,
+            @Field("examId") Long examId, @Field("number") Integer number);
+
+    @FormUrlEncoded
+    @POST("card/answer/delete")
+    String deleteAnswerCard(@Header(SignatureInfo.HEADER_NAME) String signatureInfo, @Field("examId") Long examId,
+            @Field("number") Integer number);
+
+    @Multipart
+    @POST("card/answer/save")
+    AnswerCardInfo saveAnswerCard(@Header(SignatureInfo.HEADER_NAME) String signatureInfo, @Query("examId") Long examId,
+            @Query("number") Integer number, @Query("source") CardSource source,
+            @Query("subjectCode") String subjectCode, @Query("parameter") String parameter,
+            @Query("remark") String remark, @Query("paperCount") Integer paperCount,
+            @Query("singlePage") Boolean singlePage, @Query("needAdapte") Boolean needAdapte, @Query("md5") String md5,
+            @Part MultipartBody.Part file);
+
+    @Multipart
+    @POST("file/sheet/upload")
+    FileUploadResponse sheetFileUpload(@Header(SignatureInfo.HEADER_NAME) String signatureInfo,
+            @Query("examId") Long examId, @Query("examNumber") String examNumber, @Query("index") Integer index,
+            @Query("md5") String md5, @Part MultipartBody.Part file);
+
+    @Multipart
+    @POST("file/slice/upload")
+    FileUploadResponse sliceFileUpload(@Header(SignatureInfo.HEADER_NAME) String signatureInfo,
+            @Query("examId") Long examId, @Query("examNumber") String examNumber, @Query("index") Integer index,
+            @Query("md5") String md5, @Part MultipartBody.Part file);
+
+//    @FormUrlEncoded
+//    @POST("scan/student/{examId}")
+//    DataUploadResponse dataUpload(@Header(SignatureInfo.HEADER_NAME) String signatureInfo, @Path("examId") Long examId,
+//            @Field("examNumber") String examNumber, @Field("sliceCount") Integer sliceCount,
+//            @Field("sheetCount") Integer sheetCount, @Field("answers") String answers, @Field("absent") Boolean absent,
+//            @Field("batchCode") String batchCode, @Field("paperType") String paperType,
+//            @Field("manual") Boolean manual);
+    
+    @POST("scan/student/{examId}")
+    List<DataUploadResponse> dataUpload(@Header(SignatureInfo.HEADER_NAME) String signatureInfo, @Path("examId") Long examId,
+    		@Body List<DataUploadDto> scStudentParameter);
+
+    @FormUrlEncoded
+    @POST("admin/login")
+    UserInfo login(@Field("loginName") String loginName, @Field("password") String password);
+
+    @FormUrlEncoded
+    @POST("exam/query")
+    List<ExamInfoDto> examQuery(@Header(SignatureInfo.HEADER_NAME) String signatureInfo,
+            @Field("pageNumber") long pageNumber, @Field("pageSize") long pageSize);
+
+    @FormUrlEncoded
+    @POST("exam/config/save")
+    ExamInfoDto examConfig(@Header(SignatureInfo.HEADER_NAME) String signatureInfo, @Field("examId") Long examId,
+            @Field("config") String config);
+
+    @FormUrlEncoded
+    @POST("exam/students/count")
+    long studentCount(@Header(SignatureInfo.HEADER_NAME) String signatureInfo, @Field("examId") Long examId);
+
+    @FormUrlEncoded
+    @POST("exam/students")
+    List<StudentInfo> getStudents(@Header(SignatureInfo.HEADER_NAME) String signatureInfo, @Field("examId") Long examId,
+            @Field("pageNumber") int pageNumber, @Field("pageSize") int pageSize);
+    
+}

+ 21 - 0
src/main/java/cn/com/qmth/scancloud/client/MarkingcloudApiConfiguration.java

@@ -0,0 +1,21 @@
+package cn.com.qmth.scancloud.client;
+
+import com.qmth.boot.core.retrofit.interfaces.CustomizeRetrofitConfiguration;
+import com.qmth.boot.core.retrofit.interfaces.SignatureProvider;
+
+public class MarkingcloudApiConfiguration implements CustomizeRetrofitConfiguration {
+
+    private MarkingcloudProperties properties;
+
+    public MarkingcloudApiConfiguration(MarkingcloudProperties properties) {
+        this.properties = properties;
+    }
+
+    public String getBaseUrl() {
+        return properties.getServer() + "/api/";
+    }
+
+    public SignatureProvider getSignature() {
+        return null;
+    }
+}

+ 62 - 0
src/main/java/cn/com/qmth/scancloud/client/MarkingcloudProperties.java

@@ -0,0 +1,62 @@
+package cn.com.qmth.scancloud.client;
+
+import javax.validation.constraints.NotNull;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "scancloud.markingcloud")
+public class MarkingcloudProperties {
+
+    @NotNull
+    private String server = "https://www.markingcloud.com";
+    
+    @NotNull
+    private String fileServer = "https://www.markingcloud.com/";
+    
+    private String invoker;
+    
+     private String accessToken;
+
+    // private String license;
+
+    public String getServer() {
+        return server;
+    }
+
+    public void setServer(String server) {
+        this.server = server;
+    }
+
+    
+    public String getAccessToken() {
+        return accessToken;
+    }
+
+    
+    public void setAccessToken(String accessToken) {
+        this.accessToken = accessToken;
+    }
+
+    
+    public String getInvoker() {
+        return invoker;
+    }
+
+    
+    public void setInvoker(String invoker) {
+        this.invoker = invoker;
+    }
+
+    
+    public String getFileServer() {
+        return fileServer;
+    }
+
+    
+    public void setFileServer(String fileServer) {
+        this.fileServer = fileServer;
+    }
+
+}

+ 35 - 0
src/main/java/cn/com/qmth/scancloud/config/FillMetaObjectHandler.java

@@ -0,0 +1,35 @@
+package cn.com.qmth.scancloud.config;
+
+import java.util.Date;
+
+import org.apache.ibatis.reflection.MetaObject;
+
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+
+import cn.com.qmth.scancloud.bean.User;
+import cn.com.qmth.scancloud.util.ServletUtil;
+
+public class FillMetaObjectHandler implements MetaObjectHandler {
+
+	@Override
+	public void insertFill(MetaObject metaObject) {
+		User user = ServletUtil.getSessionUser();
+		if (user != null) {
+			this.setFieldValByName("creatorId", user.getId(), metaObject);
+		}
+		if(this.getFieldValByName("createTime", metaObject)==null) {
+			this.setFieldValByName("createTime", new Date().getTime(), metaObject);
+		}
+		this.setFieldValByName("updateTime", new Date().getTime(), metaObject);
+	}
+
+	@Override
+	public void updateFill(MetaObject metaObject) {
+		User user = ServletUtil.getSessionUser();
+		if (user != null) {
+			this.setFieldValByName("updaterId", user.getId(), metaObject);
+		}
+		this.setFieldValByName("updateTime", new Date().getTime(), metaObject);
+	}
+
+}

+ 23 - 0
src/main/java/cn/com/qmth/scancloud/config/InitData.java

@@ -0,0 +1,23 @@
+package cn.com.qmth.scancloud.config;
+
+import java.io.File;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+@Component
+public class InitData implements CommandLineRunner {
+
+    @Autowired
+    private SysProperty sysProperty;
+
+    @Override
+    public void run(String... args) throws Exception {
+        String dir = sysProperty.getTransferDir();
+        File dfile = new File(dir);
+        if(!dfile.exists()) {
+        	dfile.mkdirs();
+        }
+    }
+}

+ 15 - 0
src/main/java/cn/com/qmth/scancloud/config/MyBatisPlusConfig.java

@@ -0,0 +1,15 @@
+package cn.com.qmth.scancloud.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class MyBatisPlusConfig {
+
+
+    @Bean
+    public FillMetaObjectHandler metaObjectHandler() {
+        return new FillMetaObjectHandler();
+    }
+
+}

+ 31 - 0
src/main/java/cn/com/qmth/scancloud/config/ScanResourceManager.java

@@ -0,0 +1,31 @@
+package cn.com.qmth.scancloud.config;
+
+import org.springframework.stereotype.Component;
+
+import cn.com.qmth.scancloud.support.ApiInfo;
+import cn.com.qmth.scancloud.support.ResourceManager;
+
+
+@Component
+public class ScanResourceManager implements ResourceManager {
+
+    @Override
+    public boolean isNaked(ApiInfo apiInfo, String mapping) {
+        if (null == apiInfo) {
+            return true;
+        }
+
+        if (mapping.matches(".*swagger.*")) {
+            return true;
+        }
+
+        if (null != apiInfo) {
+            if (apiInfo.isNaked()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+}

+ 31 - 0
src/main/java/cn/com/qmth/scancloud/config/ScanWebMvcConfigurer.java

@@ -0,0 +1,31 @@
+package cn.com.qmth.scancloud.config;
+
+import cn.com.qmth.scancloud.interceptor.FirstInterceptor;
+import cn.com.qmth.scancloud.support.ResourceManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * WebMvcConfigurer
+ */
+@Configuration
+public class ScanWebMvcConfigurer implements WebMvcConfigurer {
+
+    @Autowired
+    ResourceManager resourceManager;
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(new FirstInterceptor()).addPathPatterns("/**");
+    }
+
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+        registry.addMapping("/**").allowedOrigins("*").allowCredentials(false).allowedMethods("*").maxAge(3600);
+    }
+
+}
+

+ 42 - 0
src/main/java/cn/com/qmth/scancloud/config/SwaggerConfig.java

@@ -0,0 +1,42 @@
+package cn.com.qmth.scancloud.config;
+
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
+
+@EnableSwagger2WebMvc
+@Configuration
+public class SwaggerConfig {
+
+    private static final Logger log = LoggerFactory.getLogger(SwaggerConfig.class);
+
+    @Bean
+    public Docket buildDocket() {
+        log.info("swagger init...");
+        return new Docket(DocumentationType.SWAGGER_2)
+                .groupName("default")
+                .apiInfo(buildApiInfo())
+                .useDefaultResponseMessages(false)
+                .select()
+                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
+                .paths(PathSelectors.any())
+                .build();
+    }
+
+    public ApiInfo buildApiInfo() {
+        return new ApiInfoBuilder()
+                .title("接口文档")
+                .version("v1.0.0")
+                .build();
+    }
+
+}

+ 68 - 0
src/main/java/cn/com/qmth/scancloud/config/SysProperty.java

@@ -0,0 +1,68 @@
+package cn.com.qmth.scancloud.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SysProperty {
+
+	/**
+	 * 心跳超时时间(秒)
+	 */
+	@Value("${scancloud.heartbeat-timeout}")
+    private Integer heartbeatTimeout;
+    
+	@Value("${scancloud.thread.count}")
+    private Integer threadCount;
+	
+	@Value("${scancloud.file-uri-prefix}")
+    private String fileUriPrefix;
+	
+	@Value("${scancloud.version}")
+    private String version;
+	@Value("${scancloud.image-transfer.dir}")
+    private String transferDir;
+	
+	public Integer getHeartbeatTimeout() {
+		return heartbeatTimeout;
+	}
+
+	public void setHeartbeatTimeout(Integer heartbeatTimeout) {
+		this.heartbeatTimeout = heartbeatTimeout;
+	}
+
+	public Integer getThreadCount() {
+		return threadCount;
+	}
+
+	public void setThreadCount(Integer threadCount) {
+		this.threadCount = threadCount;
+	}
+
+	public String getFileUriPrefix() {
+		return fileUriPrefix;
+	}
+
+	public void setFileUriPrefix(String fileUriPrefix) {
+		this.fileUriPrefix = fileUriPrefix;
+	}
+
+	public String getVersion() {
+		return version;
+	}
+
+	public void setVersion(String version) {
+		this.version = version;
+	}
+
+	public String getTransferDir() {
+		return transferDir;
+	}
+
+	public void setTransferDir(String transferDir) {
+		this.transferDir = transferDir;
+	}
+
+	
+    
+}

+ 165 - 0
src/main/java/cn/com/qmth/scancloud/controller/BaseController.java

@@ -0,0 +1,165 @@
+package cn.com.qmth.scancloud.controller;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.net.URLEncoder;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import cn.com.qmth.scancloud.bean.User;
+import cn.com.qmth.scancloud.util.ObjectUtil;
+import cn.com.qmth.scancloud.util.ServletUtil;
+import cn.com.qmth.scancloud.vo.UpdateTimeVo;
+
+public class BaseController {
+
+    protected HttpServletRequest currentRequest() {
+        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+    }
+
+    /**
+     * 获取接入用户
+     *
+     * @return
+     */
+    protected User getAccessUser() {
+        User user = (User) ServletUtil.getRequest().getAttribute("accessEntity");
+        return user;
+    }
+
+    /**
+     * 参数trim
+     *
+     * @param bean
+     * @param nullIfBlank
+     * @author
+     */
+    protected void trim(Object bean, boolean nullIfBlank) {
+        if (null == bean) {
+            return;
+        }
+        Class<? extends Object> clazz = bean.getClass();
+        if (clazz.equals(Map.class)) {
+            return;
+        } else if (clazz.equals(List.class)) {
+            return;
+        } else if (clazz.equals(Set.class)) {
+            return;
+        } else if (clazz.isEnum()) {
+            return;
+        } else if (ObjectUtil.isBaseDataType(clazz)) {
+            return;
+        }
+
+        Field[] fields = clazz.getDeclaredFields();
+        try {
+            for (int i = 0; i < fields.length; i++) {
+                Field f = fields[i];
+                f.setAccessible(true);
+                Object value = f.get(bean);
+                if (null == value) {
+                    continue;
+                }
+                if (f.getType().equals(String.class)) {
+                    if (null != value) {
+                        String s = (String) value;
+                        s = s.trim();
+                        if (nullIfBlank && StringUtils.isBlank(s)) {
+                            s = null;
+                        }
+                        f.set(bean, s);
+                    }
+                } else if (f.getType().equals(Map.class)) {
+                } else if (f.getType().equals(List.class)) {
+                } else if (f.getType().equals(Set.class)) {
+                } else if (f.getType().isEnum()) {
+                } else if (ObjectUtil.isBaseDataType(f.getType())) {
+                } else {
+                    trim(value);
+                }
+
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 参数trim.<br>
+     * set null if blank.
+     *
+     * @param bean
+     * @author
+     */
+    protected void trim(Object bean) {
+        trim(bean, false);
+    }
+    @SuppressWarnings("deprecation")
+    protected void exportFile(String fileName, InputStream in) {
+        OutputStream out = null;
+        try {
+            fileName = URLEncoder.encode(fileName, "UTF-8");
+            HttpServletResponse response = getResponse();
+            response.reset();
+            response.setHeader("Content-Disposition", "inline; filename=" + fileName);
+            response.setContentType("application/octet-stream;charset=UTF-8");
+            out = new BufferedOutputStream(response.getOutputStream());
+            IOUtils.copy(in, out);
+            out.flush();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+            IOUtils.closeQuietly(out);
+            IOUtils.closeQuietly(in);
+        }
+    }
+    @SuppressWarnings("deprecation")
+    protected void exportFile(String fileName, File file) {
+        OutputStream out = null;
+        InputStream in = null;
+        try {
+            in = new FileInputStream(file);
+            fileName = URLEncoder.encode(fileName, "UTF-8");
+            HttpServletResponse response = getResponse();
+            response.reset();
+            response.setHeader("Content-Disposition", "inline; filename=" + fileName);
+            response.addHeader("Content-Length", "" + file.length());
+            response.setContentType("application/octet-stream;charset=UTF-8");
+            out = new BufferedOutputStream(response.getOutputStream());
+            IOUtils.copy(in, out);
+            out.flush();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+            IOUtils.closeQuietly(out);
+            IOUtils.closeQuietly(in);
+        }
+    }
+
+    protected HttpServletResponse getResponse() {
+        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
+                .getRequestAttributes();
+        HttpServletResponse response = requestAttributes.getResponse();
+        return response;
+    }
+
+    protected UpdateTimeVo result(Long updateTime) {
+        UpdateTimeVo vo = new UpdateTimeVo();
+        vo.setUpdateTime(System.currentTimeMillis());
+        return vo;
+    }
+}

+ 92 - 0
src/main/java/cn/com/qmth/scancloud/controller/SystemController.java

@@ -0,0 +1,92 @@
+package cn.com.qmth.scancloud.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+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.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.boot.core.exception.ParameterException;
+
+import cn.com.qmth.scancloud.bean.User;
+import cn.com.qmth.scancloud.config.SysProperty;
+import cn.com.qmth.scancloud.entity.AnswerCardEntity;
+import cn.com.qmth.scancloud.entity.ExamEntity;
+import cn.com.qmth.scancloud.exception.ParameterExceptions;
+import cn.com.qmth.scancloud.service.AnswerCardService;
+import cn.com.qmth.scancloud.service.ExamService;
+import cn.com.qmth.scancloud.service.SessionService;
+import cn.com.qmth.scancloud.support.WithoutStackTrace;
+import cn.com.qmth.scancloud.vo.ActiveTimeVo;
+import cn.com.qmth.scancloud.vo.AnswerCardVo;
+import cn.com.qmth.scancloud.vo.LogoutTimeVo;
+import cn.com.qmth.scancloud.vo.apistatus.ApiStatusVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@RestController
+@Api(tags = "系统接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX)
+@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+public class SystemController extends BaseController {
+	
+	@Autowired
+	private SessionService sessionService;
+	
+	@Autowired
+	private SysProperty sysProperty;
+	
+	 @Autowired
+	private AnswerCardService answerCardService;
+	 
+	 @Autowired
+	 private ExamService examService;
+
+	@WithoutStackTrace
+	@ApiOperation(value = "心跳接口")
+	@PostMapping("heartbeat")
+	public ActiveTimeVo heartbeat() {
+		User user=getAccessUser();
+		ActiveTimeVo vo=new ActiveTimeVo();
+		vo.setActiveTime(sessionService.updateUserSession(user));
+		return vo;
+	}
+
+	@ApiOperation(value = "登出接口")
+	@PostMapping("logout")
+	public LogoutTimeVo logout() {
+		User user=getAccessUser();
+		sessionService.userLogout(user);
+		LogoutTimeVo vo=new LogoutTimeVo();
+		vo.setLogoutTime(System.currentTimeMillis());
+		return vo;
+	}
+	
+	@Aac(strict = BOOL.FALSE, auth = BOOL.FALSE)
+	@ApiOperation(value = "服务端状态")
+	@PostMapping("status")
+	public ApiStatusVo status() {
+		ApiStatusVo vo=new ApiStatusVo();
+		vo.setFileUriPrefix(sysProperty.getFileUriPrefix());
+		vo.setVersion(sysProperty.getVersion());
+		vo.setTime(System.currentTimeMillis());
+		return vo;
+	}
+	
+    @ApiOperation(value = "答题卡卡格式查询")
+    @PostMapping("/card/answer")
+    public AnswerCardVo cardAnswer(@RequestParam Long examId,@RequestParam Integer number) {
+        ExamEntity exam =examService.getById(examId);
+        if(exam ==null ||!exam.getEnable()) {
+            throw ParameterExceptions.EXAM_NOT_FOUND;
+        }
+        AnswerCardEntity  card =answerCardService.findByExamAndNumber(examId, number);
+        if(card ==null ) {
+            throw new ParameterException("找不到卡格式");
+        }
+        return new AnswerCardVo(card);
+    }
+}

+ 71 - 0
src/main/java/cn/com/qmth/scancloud/controller/admin/ArbitrateController.java

@@ -0,0 +1,71 @@
+package cn.com.qmth.scancloud.controller.admin;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+
+import cn.com.qmth.scancloud.bean.User;
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.service.OmrTaskService;
+import cn.com.qmth.scancloud.vo.task.TaskResultVo;
+import cn.com.qmth.scancloud.vo.task.TaskSaveVo;
+import cn.com.qmth.scancloud.vo.task.TaskStatusVo;
+import cn.com.qmth.scancloud.vo.task.TaskVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import net.sf.json.JSONObject;
+
+@RestController
+@Api(tags = "识别对照接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/admin/check/omr/arbitrate")
+@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+public class ArbitrateController extends BaseController {
+
+    protected static final Logger log = LoggerFactory.getLogger(ArbitrateController.class);
+
+    @Autowired
+    private OmrTaskService taskService;
+    @Autowired
+    private OmrTaskService omrTaskService;
+
+    @ApiOperation(value = "识别对照仲裁任务获取")
+    @RequestMapping(value = "/get", method = RequestMethod.POST)
+    public TaskVo get(@RequestParam Long examId) {
+        User user = getAccessUser();
+        TaskVo task = taskService.getArbitrateTask(examId, user.getAccount());
+        return task;
+    }
+
+    @ApiOperation(value = "识别对照仲裁结果提交")
+    @RequestMapping(value = "/save", method = RequestMethod.POST)
+    public TaskSaveVo save(@RequestBody TaskResultVo result) {
+        User user = getAccessUser();
+        return taskService.submitTask(result, user.getAccount());
+    }
+
+    @ApiOperation(value = "识别对照仲裁进度状态")
+    @RequestMapping(value = "/status", method = RequestMethod.POST)
+    public TaskStatusVo status(@RequestParam Long examId) {
+        User user = getAccessUser();
+        return taskService.getStatus(examId, true,user.getAccount());
+    }
+    
+    @ApiOperation(value = "识别对照仲裁任务释放")
+    @RequestMapping(value = "/release", method = RequestMethod.POST)
+    public JSONObject release(@RequestParam Long examId) {
+        User user = getAccessUser();
+        omrTaskService.releaseByUser(examId, user.getAccount());
+        JSONObject result = new JSONObject();
+        result.accumulate("success", true);
+        return result;
+    }
+}

+ 33 - 0
src/main/java/cn/com/qmth/scancloud/controller/admin/AuthController.java

@@ -0,0 +1,33 @@
+package cn.com.qmth.scancloud.controller.admin;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+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.qmth.boot.api.constant.ApiConstant;
+
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.service.AuthService;
+import cn.com.qmth.scancloud.vo.AdminLoginVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@RestController
+@Api(tags = "管理员登录接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/admin")
+public class AuthController extends BaseController {
+
+    @Autowired
+    private AuthService authService;
+
+    @ApiOperation(value = "管理员登录")
+    @PostMapping("/login")
+    public AdminLoginVo login(@RequestParam String loginName, @RequestParam String password, HttpServletRequest request) {
+        return AdminLoginVo.of(authService.adminLogin(loginName, password));
+    }
+
+}

+ 136 - 0
src/main/java/cn/com/qmth/scancloud/controller/admin/CardController.java

@@ -0,0 +1,136 @@
+package cn.com.qmth.scancloud.controller.admin;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.annotation.Resource;
+
+import net.sf.json.JSONObject;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.task.AsyncTaskExecutor;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.entity.AnswerCardEntity;
+import cn.com.qmth.scancloud.enums.LockType;
+import cn.com.qmth.scancloud.service.AnswerCardService;
+import cn.com.qmth.scancloud.task.CardSyncThread;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.boot.core.concurrent.service.ConcurrentService;
+import com.qmth.boot.core.exception.ReentrantException;
+
+@RestController
+@Api(tags = "卡格式接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/admin/card")
+@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+public class CardController extends BaseController {
+
+    protected static final Logger log = LoggerFactory.getLogger(CardController.class);
+
+    @Autowired
+    private AnswerCardService answerCardService;
+
+    @Resource
+    private ConcurrentService concurrentService;
+
+    // @Qualifier("task-executor")
+    @Autowired
+    private AsyncTaskExecutor taskExecutor;
+
+    @ApiOperation(value = "卡格式详情")
+    @RequestMapping(value = "/info", method = RequestMethod.POST)
+    public Map<String, Object> info(@RequestParam Long examId) {
+        Map<String, Object> status = new HashMap<String, Object>();
+        status.put("synching", concurrentService.isLocked(LockType.CARD_SYNC + "-" + examId));
+        status.put("updateTime", System.currentTimeMillis());
+        Map<String, Object> result = new HashMap<String, Object>();
+        result.put("status", status);
+        result.put("answer", answerCardService.listByExamId(examId));
+        result.put("package", new ArrayList<>());
+        return result;
+    }
+
+    @ApiOperation(value = "同步卡格式信息")
+    @RequestMapping(value = "/sync", method = RequestMethod.POST)
+    public JSONObject sync(@RequestParam Long examId) {
+        if (!concurrentService.isLocked(LockType.CARD_SYNC + "-" + examId)) {
+            taskExecutor.submit(new CardSyncThread(getAccessUser(), examId, answerCardService, concurrentService));
+            JSONObject status = new JSONObject();
+            status.accumulate("synching", true);
+            status.accumulate("startTime", System.currentTimeMillis());
+            return status;
+        } else {
+            throw new ReentrantException("正在同步卡格式,请稍后再试");
+        }
+    }
+
+    @ApiOperation(value = "卡格式同步状态息")
+    @RequestMapping(value = "/sync/status", method = RequestMethod.POST)
+    public JSONObject syncStatus(@RequestParam Long examId) {
+        JSONObject status = new JSONObject();
+        status.accumulate("synching", concurrentService.isLocked(LockType.CARD_SYNC + "-" + examId));
+        status.accumulate("updateTime", System.currentTimeMillis());
+        return status;
+    }
+
+    @ApiOperation(value = "创建/修改题卡卡格式")
+    @RequestMapping(value = "/answer/save", method = RequestMethod.POST)
+    public JSONObject answerSave(@RequestParam Long examId, @RequestParam(required = false) Integer number,
+            @RequestParam(required = false) String subjectCode, @RequestParam(required = false) String parameter,
+            @RequestParam(required = false) String remark, @RequestParam Integer paperCount,
+            @RequestParam Boolean singlePage, @RequestParam String md5, @RequestParam MultipartFile file) {
+        if (concurrentService.getLock(LockType.CARD_SYNC + "-" + examId).tryLock()) {
+            try {
+                JSONObject result = new JSONObject();
+                AnswerCardEntity card = answerCardService.save(getAccessUser(), examId, number, subjectCode, parameter,
+                        remark, paperCount, singlePage, md5, file);
+                result.accumulate("number", card.getNumber());
+                result.accumulate("updateTime", System.currentTimeMillis());
+                return result;
+            } finally {
+                concurrentService.getLock(LockType.CARD_SYNC + "-" + examId).unlock();
+            }
+        } else {
+            throw new ReentrantException("正在同步卡格式,请稍后再试");
+        }
+    }
+
+    @ApiOperation(value = "删除答题卡卡格式")
+    @RequestMapping(value = "/answer/delete", method = RequestMethod.POST)
+    public JSONObject answerDelete(@RequestParam Long examId, @RequestParam Integer number) {
+        if (concurrentService.getLock(LockType.CARD_SYNC + "-" + examId).tryLock()) {
+            try {
+                answerCardService.delete(getAccessUser(), examId, number);
+                JSONObject result = new JSONObject();
+                result.accumulate("number", number);
+                result.accumulate("updateTime", System.currentTimeMillis());
+                return result;
+            } finally {
+                concurrentService.getLock(LockType.CARD_SYNC + "-" + examId).unlock();
+            }
+        } else {
+            throw new ReentrantException("正在同步卡格式,请稍后再试");
+        }
+    }
+
+    @ApiOperation(value = "创建/修改签到表卡格式")
+    @RequestMapping(value = "/package/save", method = RequestMethod.POST)
+    public JSONObject packageSave() {
+        JSONObject result = new JSONObject();
+        return result;
+    }
+}

+ 190 - 0
src/main/java/cn/com/qmth/scancloud/controller/admin/CheckController.java

@@ -0,0 +1,190 @@
+package cn.com.qmth.scancloud.controller.admin;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.boot.core.collection.PageResult;
+import com.qmth.boot.core.exception.StatusException;
+import com.qmth.boot.tools.excel.ExcelWriter;
+import com.qmth.boot.tools.excel.enums.ExcelType;
+import com.qmth.boot.tools.excel.model.DataMap;
+
+import cn.com.qmth.scancloud.bean.AbsentQueryDomain;
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.entity.SubjectEntity;
+import cn.com.qmth.scancloud.enums.ConditionType;
+import cn.com.qmth.scancloud.enums.GroupType;
+import cn.com.qmth.scancloud.service.StudentService;
+import cn.com.qmth.scancloud.service.SubjectService;
+import cn.com.qmth.scancloud.util.ResouceUtil;
+import cn.com.qmth.scancloud.vo.AbsentInfoVo;
+import cn.com.qmth.scancloud.vo.AbsentManualImportVo;
+import cn.com.qmth.scancloud.vo.AbsentQueryVo;
+import cn.com.qmth.scancloud.vo.OmrConditionsVo;
+import cn.com.qmth.scancloud.vo.UpdateTimeVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@RestController
+@Api(tags = "缺考接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/admin/check")
+@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+public class CheckController extends BaseController {
+
+	@Autowired
+	private StudentService studentService;
+	
+	@Autowired
+	private SubjectService subjectService;
+	
+	@ApiOperation(value = "所有可用的识别对照条件")
+	@PostMapping("omr/conditions")
+	public List<OmrConditionsVo> omrConditions() {
+		List<OmrConditionsVo> list=new ArrayList<>();
+		for(ConditionType c:ConditionType.values()) {
+			OmrConditionsVo vo=new OmrConditionsVo();
+			vo.setCode(c);
+			vo.setName(c.getName());
+			if (ConditionType.QUESTION_SINGLE_BLANK.equals(c)
+            		||ConditionType.QUESTION_MULTI_BLANK.equals(c)
+            		||ConditionType.SELECTIVE_EXCEED.equals(c)
+            		||ConditionType.SELECTIVE_BLANK.equals(c)) {
+				vo.setNeedValue(true);
+			}else {
+				vo.setNeedValue(false);
+			}
+			list.add(vo);
+		}
+		return list;
+	}
+
+	@ApiOperation(value = "缺考数据汇总")
+	@PostMapping("absent/info")
+	public AbsentInfoVo absentInfo(@RequestParam Long examId) {
+		return studentService.absentInfo(examId);
+	}
+
+	@ApiOperation(value = "查询缺考数据")
+	@RequestMapping(value = "absent/query", method = RequestMethod.POST)
+	public PageResult<AbsentQueryVo> absentQuery(AbsentQueryDomain query) {
+		return studentService.absentQuery(query);
+	}
+
+	@ApiOperation(value = "导出缺考数据")
+	@RequestMapping(value = "absent/export", method = RequestMethod.POST)
+	public void absentExport(AbsentQueryDomain query, HttpServletResponse response) throws IOException {
+        String fileName = URLEncoder.encode("缺考数据", "UTF-8");
+        response.setHeader("Content-Disposition", "inline; filename=" + fileName + ".xlsx");
+        response.setContentType("application/vnd.ms-excel");
+
+		List<AbsentQueryVo> list = studentService.absentExportList(query);
+		List<DataMap> ret=new ArrayList<>();
+		ExcelWriter writer = ExcelWriter.create(ExcelType.XLSX);
+		
+		String groupNameCol = null;
+		if (GroupType.PACKAGE.equals(query.getGroupType())) {
+			groupNameCol = "卷袋";
+		}
+		if (GroupType.SUBJECT.equals(query.getGroupType())) {
+			groupNameCol = "科目代码";
+		}
+		if (GroupType.CAMPUS.equals(query.getGroupType())) {
+			groupNameCol = "学习中心";
+		}
+		if (GroupType.EXAM_SITE.equals(query.getGroupType())) {
+			groupNameCol = "考点";
+		}
+		if (GroupType.EXAM_ROOM.equals(query.getGroupType())) {
+			groupNameCol = "考场";
+		}
+		if (GroupType.STUDENT_CODE.equals(query.getGroupType())) {
+			groupNameCol = "学号";
+		}
+		if(CollectionUtils.isNotEmpty(list)) {
+			Map<String,SubjectEntity> subMap=new HashMap<>();
+			for(AbsentQueryVo vo:list) {
+				DataMap map=new DataMap();
+				ret.add(map);
+				map.put(groupNameCol,vo.getGroupName());
+				if (GroupType.SUBJECT.equals(query.getGroupType())) {
+					map.put("科目名称",getSubjectName(subMap, vo.getGroupName(), query.getExamId()));
+				}
+				map.put("考生总数",getStringVal(vo.getTotalCount()));
+				map.put("已扫描",getStringVal(vo.getScannedCount()));
+				map.put("未扫描",getStringVal(vo.getUnexistCount()));
+				map.put("指定缺考",getStringVal(vo.getManualAbsentCount()));
+				map.put("识别缺考",getStringVal(vo.getOmrAbsentCount()));
+				map.put("缺考异常",getStringVal(vo.getAbsentSuspectCount()));
+			}
+		}
+		String[] head;
+		if (GroupType.SUBJECT.equals(query.getGroupType())) {
+			head=new String[] {groupNameCol,"科目名称","考生总数","已扫描","未扫描","指定缺考","识别缺考","缺考异常"};
+		}else {
+			head=new String[] {groupNameCol,"考生总数","已扫描","未扫描","指定缺考","识别缺考","缺考异常"};
+		}
+		writer.writeDataMaps("sheet1", null,head, ret.iterator());
+		writer.output(response.getOutputStream());
+	}
+	
+	private String getSubjectName(Map<String,SubjectEntity> subMap,String subjectCode,Long examId) {
+		SubjectEntity  sub=subMap.get(subjectCode);
+		if(subMap.get(subjectCode)==null) {
+			sub=subjectService.findByExamIdAndCode(examId, subjectCode);
+			if(sub==null) {
+				throw new StatusException("未找到科目信息:"+subjectCode);
+			}
+			subMap.put(subjectCode, sub);
+		}
+		return sub.getName();
+	}
+	
+	private String getStringVal(Integer val) {
+		if(val==null) {
+			return "0";
+		}
+		return val.toString();
+	}
+
+	@PostMapping("absent/manual/import")
+	@ApiOperation(value = "导入指定缺考名单")
+	public AbsentManualImportVo absentManualImport(@RequestParam Long examId, @RequestParam MultipartFile file) {
+		return studentService.absentManualImport(examId, file);
+	}
+
+	@ApiOperation(value = "下载导入指定缺考名单模板")
+	@PostMapping("absent/manual/template")
+	public void getImportTemplate() throws IOException {
+		exportFile("指定缺考名单导入模板.xlsx", ResouceUtil.getStream("importtemplates/absentManualImportTemplate.xlsx"));
+	}
+
+	@ApiOperation(value = "更新为指定缺考")
+	@PostMapping("absent/manual/update")
+	public UpdateTimeVo absentManualUpdate(@RequestParam Long examId, @RequestParam String examNumber) {
+		return studentService.absentManualUpdate(examId, examNumber);
+	}
+
+	@ApiOperation(value = "取消缺考标记嫌疑")
+	@PostMapping("absent/suspect/remove")
+	public UpdateTimeVo absentSuspectRemove(@RequestParam Long examId, @RequestParam String examNumber) {
+		return studentService.absentSuspectRemove(examId, examNumber);
+	}
+}

+ 177 - 0
src/main/java/cn/com/qmth/scancloud/controller/admin/ExamController.java

@@ -0,0 +1,177 @@
+package cn.com.qmth.scancloud.controller.admin;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.annotation.Resource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.task.AsyncTaskExecutor;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.boot.core.collection.PageResult;
+import com.qmth.boot.core.concurrent.service.ConcurrentService;
+import com.qmth.boot.core.exception.ReentrantException;
+import com.qmth.boot.mybatis.query.BaseQuery;
+
+import cn.com.qmth.scancloud.bean.ExamConfigDomain;
+import cn.com.qmth.scancloud.bean.User;
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.entity.ExamEntity;
+import cn.com.qmth.scancloud.enums.LockType;
+import cn.com.qmth.scancloud.exception.ParameterExceptions;
+import cn.com.qmth.scancloud.service.ExamService;
+import cn.com.qmth.scancloud.service.StudentService;
+import cn.com.qmth.scancloud.task.ExamStudentSyncThread;
+import cn.com.qmth.scancloud.vo.ExamConfigVo;
+import cn.com.qmth.scancloud.vo.ExamRemoteVo;
+import cn.com.qmth.scancloud.vo.ExamUploadVo;
+import cn.com.qmth.scancloud.vo.ExamVo;
+import cn.com.qmth.scancloud.vo.examinfo.ExamInfoVo;
+import cn.com.qmth.scancloud.vo.examinfo.ExamQuery;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import net.sf.json.JSONObject;
+
+@RestController
+@Api(tags = "考试接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/admin/exam")
+@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+public class ExamController extends BaseController {
+
+    @Autowired
+    private ExamService examService;
+    
+    @Autowired
+    private StudentService studentService;
+
+    @Resource
+    private ConcurrentService concurrentService;
+
+    @Autowired
+    private AsyncTaskExecutor taskExecutor;
+
+    @ApiOperation(value = "获取考试详情")
+    @RequestMapping(value = "/info", method = RequestMethod.POST)
+    public ExamInfoVo info(@RequestParam Long id) {
+    	User user = getAccessUser();
+        return examService.getExamInfoVo(id,user);
+    }
+
+    @ApiOperation(value = "获取考试列表")
+    @RequestMapping(value = "/list", method = RequestMethod.POST)
+    public PageResult<ExamVo> list(ExamQuery query) {
+    	User user = getAccessUser();
+        return examService.pageQuery(query,user);
+    }
+
+    @ApiOperation(value = "启用/关闭考试")
+    @RequestMapping(value = "/toggle", method = RequestMethod.POST)
+    public JSONObject enable(@RequestParam Long id, @RequestParam Boolean enable) {
+    	User user = getAccessUser();
+        JSONObject result = new JSONObject();
+        ExamEntity exam = examService.getById(id);
+        if (exam == null) {
+            throw ParameterExceptions.EXAM_NOT_FOUND;
+        }
+        if (!exam.getSchoolId().equals(user.getSchoolId())) {
+            throw ParameterExceptions.EXAM_NOT_FOUND;
+        }
+        exam.setEnable(enable);
+        examService.saveOrUpdate(exam);
+        result.accumulate("enable", enable);
+        result.accumulate("updateTime", exam.getUpdateTime());
+        return result;
+    }
+
+    @ApiOperation(value = "未启用考试")
+    @RequestMapping(value = "/remote/list", method = RequestMethod.POST)
+    public PageResult<ExamRemoteVo> remote(BaseQuery<?> query) {
+        User user = getAccessUser();
+        return examService.listRemote(query, user);
+    }
+
+    @ApiOperation(value = "启用新考试")
+    @RequestMapping(value = "/init", method = RequestMethod.POST)
+    public Map<String, Object> init(ExamConfigDomain domain) {
+        User user = getAccessUser();
+        ExamConfigVo vo=examService.init(user, domain);
+        Map<String, Object> result = new HashMap<String, Object>();
+        result.put("updateTime", vo.getUpdateTime());
+        return result;
+    }
+
+    @ApiOperation(value = "修改考试参数")
+    @RequestMapping(value = "/config", method = RequestMethod.POST)
+    public ExamConfigVo config(ExamConfigDomain domain) {
+        User user = getAccessUser();
+        return examService.config(user, domain);
+    }
+
+    @ApiOperation(value = "修改考试上传状态")
+    @RequestMapping(value = "/upload", method = RequestMethod.POST)
+    public ExamUploadVo upload(@RequestParam Long id, @RequestParam Boolean enable) {
+    	User user = getAccessUser();
+        ExamUploadVo vo = new ExamUploadVo();
+        ExamEntity exam = examService.getById(id);
+        if (exam == null) {
+            throw ParameterExceptions.EXAM_NOT_FOUND;
+        }
+        if (!exam.getSchoolId().equals(user.getSchoolId())) {
+            throw ParameterExceptions.EXAM_NOT_FOUND;
+        }
+        exam.setEnableUpload(enable);
+        examService.saveOrUpdate(exam);
+        vo.setEnable(exam.getEnableUpload());
+        vo.setUpdateTime(exam.getUpdateTime());
+        vo.setProgress(studentService.getUploadProgress(id));
+        return vo;
+    }
+
+    @ApiOperation(value = "同步考务数据")
+    @RequestMapping(value = "/data/sync", method = RequestMethod.POST)
+    public JSONObject sync(@RequestParam Long examId) {
+        User user = getAccessUser();
+        ExamEntity exam = examService.getById(examId);
+        if (exam == null) {
+            throw ParameterExceptions.EXAM_NOT_FOUND;
+        }
+        if (!exam.getSchoolId().equals(user.getSchoolId())) {
+            throw ParameterExceptions.EXAM_NOT_FOUND;
+        }
+        if (!concurrentService.isLocked(LockType.EXAM_SYNC + "-" + examId)) {
+            taskExecutor.submit(new ExamStudentSyncThread(getAccessUser(), examId, examService, concurrentService));
+        } else {
+            throw new ReentrantException("正在同步,请稍后再试");
+        }
+        JSONObject result = new JSONObject();
+        result.put("synching", concurrentService.isLocked(LockType.EXAM_SYNC + "-" + examId));
+        result.put("progress", examService.syncProgress(user, examId));
+        result.put("updateTime", examService.getById(examId).getUpdateTime());
+        return result;
+    }
+
+    @ApiOperation(value = "考务数据同步状态")
+    @RequestMapping(value = "/data/sync/status", method = RequestMethod.POST)
+    public Map<String, Object> syncStatus(@RequestParam Long examId) {
+        User user = getAccessUser();
+        ExamEntity exam = examService.getById(examId);
+        if (exam == null) {
+            throw ParameterExceptions.EXAM_NOT_FOUND;
+        }
+        if (!exam.getSchoolId().equals(user.getSchoolId())) {
+            throw ParameterExceptions.EXAM_NOT_FOUND;
+        }
+        Map<String, Object> result = new HashMap<String, Object>();
+        result.put("synching", concurrentService.isLocked(LockType.EXAM_SYNC + "-" + examId));
+        result.put("progress", examService.syncProgress(user, examId));
+        result.put("updateTime", examService.getById(examId).getUpdateTime());
+        return result;
+    }
+}

+ 64 - 0
src/main/java/cn/com/qmth/scancloud/controller/admin/ExamWorkController.java

@@ -0,0 +1,64 @@
+package cn.com.qmth.scancloud.controller.admin;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+
+import cn.com.qmth.scancloud.entity.SubjectEntity;
+import cn.com.qmth.scancloud.service.StudentService;
+import cn.com.qmth.scancloud.service.SubjectService;
+import cn.com.qmth.scancloud.vo.student.StudentQuery;
+import cn.com.qmth.scancloud.vo.student.StudentVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@RestController
+@Api(tags = "考务接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/admin")
+@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+public class ExamWorkController {
+
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private SubjectService subjectService;
+
+    @ApiOperation(value = "获取考生信息")
+    @RequestMapping(value = "/student/find", method = RequestMethod.POST)
+    public StudentVo student(StudentQuery query) {
+        return studentService.findOne(query);
+    }
+
+    @ApiOperation(value = "获取科目列表")
+    @RequestMapping(value = "/subject/list", method = RequestMethod.POST)
+    public List<SubjectEntity> subjectList(@RequestParam Long examId) {
+        return subjectService.listByExamId(examId);
+    }
+
+    @ApiOperation(value = "获取科目信息")
+    @RequestMapping(value = "/subject/find", method = RequestMethod.POST)
+    public SubjectEntity subjectFind(@RequestParam Long examId, @RequestParam String code) {
+        return subjectService.findByExamIdAndCode(examId, code);
+    }
+
+    @ApiOperation(value = "获取所有学习中心")
+    @RequestMapping(value = "/campus/list", method = RequestMethod.POST)
+    public List<String> campusList(@RequestParam Long examId) {
+        return studentService.listCampusByExamId(examId);
+    }
+
+    @ApiOperation(value = "获取所有考点")
+    @RequestMapping(value = "/exam_site/list", method = RequestMethod.POST)
+    public List<String> siteList(@RequestParam Long examId) {
+        return studentService.listSiteByExamId(examId);
+    }
+}

+ 142 - 0
src/main/java/cn/com/qmth/scancloud/controller/admin/OmrGroupController.java

@@ -0,0 +1,142 @@
+package cn.com.qmth.scancloud.controller.admin;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.task.AsyncTaskExecutor;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.boot.core.concurrent.model.Semaphore;
+import com.qmth.boot.core.concurrent.service.ConcurrentService;
+import com.qmth.boot.core.exception.ParameterException;
+import com.qmth.boot.core.exception.ReentrantException;
+
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.entity.OmrGroupEntity;
+import cn.com.qmth.scancloud.enums.LockType;
+import cn.com.qmth.scancloud.enums.Stage;
+import cn.com.qmth.scancloud.service.OmrGroupService;
+import cn.com.qmth.scancloud.task.OmrGroupBuildThread;
+import cn.com.qmth.scancloud.task.OmrGroupDeleteThread;
+import cn.com.qmth.scancloud.task.OmrGroupResetThread;
+import cn.com.qmth.scancloud.vo.OmrGroupUpdateVo;
+import cn.com.qmth.scancloud.vo.OmrGroupVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import net.sf.json.JSONObject;
+
+@RestController
+@Api(tags = "识别对照任务组接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/admin/check/omr/group")
+@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+public class OmrGroupController extends BaseController {
+
+    @Autowired
+    private OmrGroupService groupService;
+
+    @Autowired
+    private ConcurrentService concurrentService;
+
+    @Autowired
+    private AsyncTaskExecutor taskExecutor;
+
+    @ApiOperation(value = "查询识别对照任务列表")
+    @RequestMapping(value = "/list", method = RequestMethod.POST)
+    public List<OmrGroupVo> list(@RequestParam Long examId) {
+        return groupService.listByExamId(examId);
+    }
+
+    @ApiOperation(value = "创建/修改识别对照任务组")
+    @RequestMapping(value = "/save", method = RequestMethod.POST)
+    public JSONObject save(@RequestBody OmrGroupUpdateVo omrGroupUpdateVo) {
+        OmrGroupEntity group = groupService.save(omrGroupUpdateVo.getId(), omrGroupUpdateVo.getExamId(),
+                omrGroupUpdateVo.getConditionList(), getAccessUser().getId());
+        JSONObject result = new JSONObject();
+        result.accumulate("id", group.getId());
+        result.accumulate("updateTime", System.currentTimeMillis());
+        return result;
+    }
+
+    @ApiOperation(value = "修改识别对照任务组阶段")
+    @RequestMapping(value = "/toggle", method = RequestMethod.POST)
+    public JSONObject toggle(@RequestParam Long id) {
+        groupService.updateStage(id, getAccessUser().getId());
+        JSONObject result = new JSONObject();
+        result.accumulate("stage", Stage.SECOND);
+        result.accumulate("updateTime", System.currentTimeMillis());
+        return result;
+    }
+
+    @ApiOperation(value = "识别对照任务组生成任务")
+    @RequestMapping(value = "/build", method = RequestMethod.POST)
+    public JSONObject build(@RequestParam Long id) {
+        OmrGroupEntity group = groupService.getById(id);
+        if (group == null) {
+            throw new ParameterException("分组不存在");
+        }
+        if (group.getFixed()) {
+            throw new ParameterException("固定分组不支持手动创建任务");
+        }
+        Semaphore semaphore = concurrentService.getSemaphore(LockType.GROUP_BUILD + "-" + id);
+        if (semaphore.tryAcquire()) {
+            taskExecutor.submit(new OmrGroupBuildThread(id, groupService, concurrentService, semaphore));
+        } else {
+            throw new ReentrantException("该分组数据操作繁忙,请稍后重试");
+        }
+        JSONObject result = new JSONObject();
+        result.accumulate("id", id);
+        result.accumulate("building", !semaphore.isAvailable());
+        result.accumulate("updateTime", System.currentTimeMillis());
+        return result;
+    }
+
+    @ApiOperation(value = "重置识别对照任务组")
+    @RequestMapping(value = "/reset", method = RequestMethod.POST)
+    public JSONObject reset(@RequestParam Long id) {
+        OmrGroupEntity group = groupService.getById(id);
+        if (group == null) {
+            throw new ParameterException("分组不存在");
+        }
+        Semaphore semaphore = concurrentService.getSemaphore(LockType.GROUP_RESET + "-" + id);
+        if (semaphore.tryAcquire()) {
+            taskExecutor.submit(new OmrGroupResetThread(id, groupService, concurrentService, semaphore));
+        } else {
+            throw new ReentrantException("该分组数据操作繁忙,请稍后重试");
+        }
+        JSONObject result = new JSONObject();
+        result.accumulate("id", id);
+        result.accumulate("reseting", !semaphore.isAvailable());
+        result.accumulate("updateTime", System.currentTimeMillis());
+        return result;
+    }
+
+    @ApiOperation(value = "删除识别对照任务组")
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    public JSONObject delete(@RequestParam Long id) {
+        OmrGroupEntity group = groupService.getById(id);
+        if (group == null) {
+            throw new ParameterException("分组不存在");
+        }
+        if (group.getFixed()) {
+            throw new ParameterException("固定分组不能删除");
+        }
+        Semaphore semaphore = concurrentService.getSemaphore(LockType.GROUP_DELETE + "-" + id);
+        if (semaphore.tryAcquire()) {
+            taskExecutor.submit(new OmrGroupDeleteThread(id, groupService, concurrentService, semaphore));
+        } else {
+            throw new ReentrantException("该分组数据操作繁忙,请稍后重试");
+        }
+        JSONObject result = new JSONObject();
+        result.accumulate("id", id);
+        result.accumulate("deleting", !semaphore.isAvailable());
+        result.accumulate("updateTime", System.currentTimeMillis());
+        return result;
+    }
+}

+ 163 - 0
src/main/java/cn/com/qmth/scancloud/controller/admin/ScanAnswerController.java

@@ -0,0 +1,163 @@
+package cn.com.qmth.scancloud.controller.admin;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.List;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.boot.core.collection.PageResult;
+import com.qmth.boot.tools.excel.ExcelWriter;
+import com.qmth.boot.tools.excel.enums.ExcelType;
+
+import cn.com.qmth.scancloud.bean.AnswerDeleteDomain;
+import cn.com.qmth.scancloud.bean.AnswerQueryDomain;
+import cn.com.qmth.scancloud.bean.BatchQueryDomain;
+import cn.com.qmth.scancloud.bean.MismatchQueryDomain;
+import cn.com.qmth.scancloud.bean.MismatchToggleDomain;
+import cn.com.qmth.scancloud.bean.PageDeleteDomain;
+import cn.com.qmth.scancloud.bean.omredit.OmrEditDomain;
+import cn.com.qmth.scancloud.bean.papermigrate.PaperMigrateDomain;
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.service.BatchService;
+import cn.com.qmth.scancloud.service.PaperPageService;
+import cn.com.qmth.scancloud.service.PaperService;
+import cn.com.qmth.scancloud.service.StudentService;
+import cn.com.qmth.scancloud.vo.AnswerDeleteVo;
+import cn.com.qmth.scancloud.vo.AnswerExportVo;
+import cn.com.qmth.scancloud.vo.BatchQueryVo;
+import cn.com.qmth.scancloud.vo.MismatchToggleVo;
+import cn.com.qmth.scancloud.vo.PageDeleteVo;
+import cn.com.qmth.scancloud.vo.PaperMigrateVo;
+import cn.com.qmth.scancloud.vo.ScanAnswerInfoVo;
+import cn.com.qmth.scancloud.vo.UpdateTimeVo;
+import cn.com.qmth.scancloud.vo.UriVo;
+import cn.com.qmth.scancloud.vo.answerquery.AnswerQueryVo;
+import cn.com.qmth.scancloud.vo.batchdetail.BatchDetailVo;
+import cn.com.qmth.scancloud.vo.mismatchquery.MismatchQueryVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@RestController
+@Api(tags = "扫描管理-答题卡接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/admin/scan/answer")
+@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+public class ScanAnswerController extends BaseController {
+
+
+	@Autowired
+	private BatchService batchService;
+	
+	@Autowired
+	private PaperService paperService;
+	
+	@Autowired
+	private PaperPageService paperPageService;
+	
+	@Autowired
+	private StudentService studentService;
+
+    @ApiOperation(value = "查询答题卡扫描批次所有关联的扫描员")
+    @RequestMapping(value = "batch/scanner", method = RequestMethod.POST)
+    public List<String> batchScanner(@RequestParam Long examId) {
+        return batchService.batchScanner(examId);
+    }
+	
+    @ApiOperation(value = "查询答题卡扫描批次信息")
+    @RequestMapping(value = "batch/query", method = RequestMethod.POST)
+    public PageResult<BatchQueryVo> batchQuery(BatchQueryDomain query) {
+        return batchService.batchQuery(query);
+    }
+    
+    @ApiOperation(value = "查询答题卡扫描批次详情")
+    @RequestMapping(value = "batch/detail", method = RequestMethod.POST)
+    public List<BatchDetailVo> batchDetail(@RequestParam Long id) {
+        return batchService.batchDetail(id);
+    }
+    
+    @ApiOperation(value = "查询异常答题卡信息")
+    @RequestMapping(value = "mismatch/query", method = RequestMethod.POST)
+    public PageResult<MismatchQueryVo> mismatchQuery(MismatchQueryDomain query) {
+        return batchService.mismatchQuery(query);
+    }
+    
+	@ApiOperation(value = "修改异常答题卡标记")
+	@RequestMapping(value = "mismatch/toggle", method = RequestMethod.POST)
+	public MismatchToggleVo mismatchToggle(MismatchToggleDomain domain) {
+		return paperService.mismatchToggle(domain);
+	}
+	
+	@ApiOperation(value = "答题卡扫描汇总")
+	@PostMapping("info")
+	public ScanAnswerInfoVo scanAnswerInfo(@RequestParam Long examId) {
+		return studentService.scanAnswerInfo(examId);
+	}
+	
+    @ApiOperation(value = "查询答题卡扫描详情")
+    @RequestMapping(value = "query", method = RequestMethod.POST)
+    public PageResult<AnswerQueryVo> query(AnswerQueryDomain query) {
+        return studentService.query(query);
+    }
+    
+    @ApiOperation(value = "导出答题卡扫描详情")
+    @RequestMapping(value = "export", method = RequestMethod.POST)
+    public void export(AnswerQueryDomain query, HttpServletResponse response) throws IOException {
+    	String fileName = URLEncoder.encode("答题卡扫描详情", "UTF-8");
+        response.setHeader("Content-Disposition", "inline; filename=" + fileName + ".xlsx");
+        response.setContentType("application/vnd.ms-excel");
+        List<AnswerExportVo> list = studentService.exportList(query);
+		ExcelWriter writer = ExcelWriter.create(ExcelType.XLSX);
+		writer.writeObjects("sheet1", null, AnswerExportVo.class, list.iterator());
+		writer.output(response.getOutputStream());
+    }
+    
+	@ApiOperation(value = "修改答题卡识别结果")
+	@RequestMapping(value = "omr/edit", method = RequestMethod.POST)
+	public UpdateTimeVo omrEdit(@RequestBody OmrEditDomain domain) {
+		return paperPageService.omrEdit(domain);
+	}
+	
+	@ApiOperation(value = "更新答题卡裁切图")
+	@RequestMapping(value = "slice/update", method = RequestMethod.POST)
+	public UriVo sliceUpdate(@RequestParam Long paperId, @RequestParam Integer pageIndex,@RequestParam Integer index, @RequestParam MultipartFile file,
+			@RequestParam String md5) {
+		return paperService.adminSliceUpdate(paperId,pageIndex,index, file, md5);
+	}
+	
+	@ApiOperation(value = "上传答题卡裁切图")
+	@RequestMapping(value = "slice/upload", method = RequestMethod.POST)
+	public UriVo sliceUpload(@RequestParam Long paperId, @RequestParam Integer pageIndex,@RequestParam Integer index, @RequestParam MultipartFile file,
+			@RequestParam String md5) {
+		return paperService.adminSliceUpload(paperId,pageIndex,index, file, md5);
+	}
+	
+	@ApiOperation(value = "修改答题卡扫描图片绑定考生")
+	@RequestMapping(value = "paper/migrate", method = RequestMethod.POST)
+	public PaperMigrateVo paperMigrate(@RequestBody PaperMigrateDomain domain) {
+		return paperPageService.paperMigrate(getAccessUser(),domain);
+	}
+	
+	@ApiOperation(value = "删除答题卡单页扫描结果")
+	@RequestMapping(value = "page/delete", method = RequestMethod.POST)
+	public PageDeleteVo pageDelete(PageDeleteDomain domain) {
+		return paperService.pageDelete(getAccessUser(),domain);
+	}
+	
+	@ApiOperation(value = "删除答题卡扫描结果")
+	@RequestMapping(value = "delete", method = RequestMethod.POST)
+	public AnswerDeleteVo answerDelete(AnswerDeleteDomain domain) {
+		return paperService.answerDelete(getAccessUser(),domain);
+	}
+}

+ 72 - 0
src/main/java/cn/com/qmth/scancloud/controller/admin/ScannerController.java

@@ -0,0 +1,72 @@
+package cn.com.qmth.scancloud.controller.admin;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+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.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+
+import cn.com.qmth.scancloud.bean.CardAnswerDomain;
+import cn.com.qmth.scancloud.bean.WorkloadDomain;
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.service.PaperService;
+import cn.com.qmth.scancloud.service.ScannerCardService;
+import cn.com.qmth.scancloud.service.ScannerService;
+import cn.com.qmth.scancloud.service.SystemConfigService;
+import cn.com.qmth.scancloud.vo.ScannerWorkloadVo;
+import cn.com.qmth.scancloud.vo.UpdateCountVo;
+import cn.com.qmth.scancloud.vo.scannerinfo.Control;
+import cn.com.qmth.scancloud.vo.scannerinfo.ScannerInfoVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@RestController
+@Api(tags = "扫描员管理接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/admin/scanner")
+@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+public class ScannerController extends BaseController {
+
+	@Autowired
+	private ScannerService scannerService;
+	
+	@Autowired
+	private ScannerCardService scannerCardService;
+	
+	@Autowired
+	private PaperService paperService; 
+	
+	@Autowired
+	private SystemConfigService systemConfigService;
+
+	@ApiOperation(value = "扫描员管理详情")
+	@PostMapping("info")
+	public ScannerInfoVo scannerInfo(@RequestParam Long examId) {
+
+		return scannerService.scannerInfo(examId);
+	}
+
+	@ApiOperation(value = "扫描员工作量统计")
+	@PostMapping("workload")
+	public List<ScannerWorkloadVo> workload(WorkloadDomain domain) {
+
+		return paperService.workload(domain);
+	}
+	@ApiOperation(value = "修改扫描员登陆控制")
+	@PostMapping("control")
+	public Control control(Control control) {
+
+		return systemConfigService.control(control);
+	}
+	@ApiOperation(value = "修改扫描员绑定卡格式")
+	@PostMapping("card/answer")
+	public UpdateCountVo cardAnswer(CardAnswerDomain domain) {
+
+		return scannerCardService.cardAnswer(domain);
+	}
+}

+ 125 - 0
src/main/java/cn/com/qmth/scancloud/controller/admin/ToolController.java

@@ -0,0 +1,125 @@
+package cn.com.qmth.scancloud.controller.admin;
+
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.boot.core.exception.ParameterException;
+
+import cn.com.qmth.scancloud.bean.ImportExamDomain;
+import cn.com.qmth.scancloud.bean.ImportStudentDomain;
+import cn.com.qmth.scancloud.bean.ImportSubjectDomain;
+import cn.com.qmth.scancloud.bean.ImportUserDomain;
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.entity.ExamEntity;
+import cn.com.qmth.scancloud.entity.SubjectEntity;
+import cn.com.qmth.scancloud.service.ExamService;
+import cn.com.qmth.scancloud.service.StudentService;
+import cn.com.qmth.scancloud.service.SubjectService;
+import cn.com.qmth.scancloud.service.ToolExportService;
+import cn.com.qmth.scancloud.service.UserService;
+import cn.com.qmth.scancloud.vo.CountVo;
+import cn.com.qmth.scancloud.vo.ImportExamVo;
+import cn.com.qmth.scancloud.vo.ImportStudentQueryVo;
+import cn.com.qmth.scancloud.vo.ImportStudentVo;
+import cn.com.qmth.scancloud.vo.SubjectCheckVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@RestController
+@Api(tags = "本地工具接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/tool")
+public class ToolController extends BaseController {
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private ExamService examService;
+
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private SubjectService subjectService;
+
+    @Autowired
+    private ToolExportService toolExportService;
+
+    @ApiOperation(value = "批量创建管理员用户接口")
+    @PostMapping("/import/user")
+    public CountVo importUser(@RequestBody List<ImportUserDomain> users) {
+        return new CountVo(userService.importUser(users));
+    }
+
+    @ApiOperation(value = "创建考试接口")
+    @PostMapping("/import/exam")
+    public ImportExamVo importExam(@RequestBody ImportExamDomain exam) {
+        return new ImportExamVo(examService.save(exam).getId());
+    }
+
+    @ApiOperation(value = "批量创建科目接口")
+    @PostMapping("/import/course")
+    public CountVo importCourse(@RequestBody List<ImportSubjectDomain> subjects) {
+        return new CountVo(subjectService.importSubject(subjects));
+    }
+
+    @ApiOperation(value = "批量新建考生数量接口")
+    @PostMapping("/import/exam/student")
+    public CountVo importStudent(@RequestBody List<ImportStudentDomain> students) {
+        return new CountVo(studentService.importStudent(students));
+    }
+
+    @ApiOperation(value = "查询考生数量接口")
+    @PostMapping("/exam/student/count")
+    public CountVo countStudent(@RequestBody ImportStudentQueryVo query) {
+        return new CountVo(studentService.countByQuery(query));
+    }
+
+    @ApiOperation(value = "分页查询考生接口")
+    @PostMapping("/exam/student/find")
+    public List<ImportStudentVo> findStudent(@RequestBody ImportStudentQueryVo query) {
+        return studentService.findByQuery(query);
+    }
+
+    @ApiOperation(value = "检查并修复考生导出图片接口")
+    @PostMapping("/exam/student/check")
+    public void studentCheck(@RequestParam Long studentId) {
+        toolExportService.studentCheck(studentId);
+    }
+    
+    @ApiOperation(value = "获取考试详情")
+    @RequestMapping(value = "/exam/info", method = RequestMethod.POST)
+    public ExamEntity examInfo(@RequestParam Long examId) {
+        return examService.getById(examId);
+    }
+    
+    @ApiOperation(value = "获取科目详情")
+    @RequestMapping(value = "/exam/subject/info", method = RequestMethod.POST)
+    public SubjectEntity subjectInfo(@RequestBody SubjectCheckVo query) {
+    	Long examId=query.getExamId();
+    	String code=query.getSubjectCode();
+    	if(examId==null) {
+    		throw new ParameterException("examId 不能为空");
+    	}
+    	if(StringUtils.isBlank(code)) {
+    		throw new ParameterException("subjectCode 不能为空");
+    	}
+        return subjectService.findByExamIdAndCode(examId, code);
+    }
+    
+    @ApiOperation(value = "清空考生数据")
+    @RequestMapping(value = "/exam/student/clean", method = RequestMethod.POST)
+    public void studentClean(@RequestParam Long examId) {
+        studentService.studentClean(examId);
+    }
+
+}

+ 58 - 0
src/main/java/cn/com/qmth/scancloud/controller/admin/VerifyController.java

@@ -0,0 +1,58 @@
+package cn.com.qmth.scancloud.controller.admin;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+
+import cn.com.qmth.scancloud.bean.User;
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.service.BatchService;
+import cn.com.qmth.scancloud.vo.UpdateTimeVo;
+import cn.com.qmth.scancloud.vo.verify.VerifyTaskVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import net.sf.json.JSONObject;
+
+@RestController
+@Api(tags = "答题卡扫描实时审核接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/admin/verify/scan")
+@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+public class VerifyController extends BaseController {
+
+    protected static final Logger log = LoggerFactory.getLogger(VerifyController.class);
+
+    @Autowired
+    private BatchService batchService;
+
+    @ApiOperation(value = "获取答题卡扫描实时审核任务")
+    @RequestMapping(value = "/answer/get", method = RequestMethod.POST)
+    public VerifyTaskVo answerGet(@RequestParam Long examId) {
+        User user = getAccessUser();
+        return batchService.getVerifyTask(examId, user);
+    }
+
+    @ApiOperation(value = "答题卡扫描实时审核任务处理")
+    @RequestMapping(value = "/answer/submit", method = RequestMethod.POST)
+    public UpdateTimeVo answerSubmit(@RequestParam Long batchId, @RequestParam Boolean confirm) {
+        User user = getAccessUser();
+        batchService.verify(batchId, confirm,user);
+        return result(System.currentTimeMillis());
+    }
+    @ApiOperation(value = "答题卡扫描实时审核任务释放")
+    @RequestMapping(value = "/answer/release", method = RequestMethod.POST)
+    public JSONObject answerRelease(@RequestParam Long examId) {
+    	User user = getAccessUser();
+    	batchService.releaseByUser(examId, user.getAccount());
+        JSONObject result = new JSONObject();
+        result.accumulate("success", true);
+        return result;
+    }
+}

+ 103 - 0
src/main/java/cn/com/qmth/scancloud/controller/scan/AnswerController.java

@@ -0,0 +1,103 @@
+package cn.com.qmth.scancloud.controller.scan;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+
+import cn.com.qmth.scancloud.bean.BatchCreateDomain;
+import cn.com.qmth.scancloud.bean.MismatchToggleDomain;
+import cn.com.qmth.scancloud.bean.User;
+import cn.com.qmth.scancloud.bean.answersave.AnswerDomain;
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.service.AnswerCardService;
+import cn.com.qmth.scancloud.service.BatchService;
+import cn.com.qmth.scancloud.service.PaperService;
+import cn.com.qmth.scancloud.vo.AnswerCardVo;
+import cn.com.qmth.scancloud.vo.BatchFinishVo;
+import cn.com.qmth.scancloud.vo.BatchVerifyVo;
+import cn.com.qmth.scancloud.vo.MismatchToggleVo;
+import cn.com.qmth.scancloud.vo.SheetUploadVo;
+import cn.com.qmth.scancloud.vo.SliceUploadVo;
+import cn.com.qmth.scancloud.vo.batch.AnswerSaveVo;
+import cn.com.qmth.scancloud.vo.batch.BatchCreateVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@RestController
+@Api(tags = "扫描功能-答题卡接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/scan/answer")
+@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+public class AnswerController extends BaseController {
+
+	@Autowired
+	private AnswerCardService answerCardService;
+
+	@Autowired
+	private BatchService batchService;
+
+	@Autowired
+	private PaperService paperService;
+	
+    @ApiOperation(value = "答题卡扫描批次创建")
+    @RequestMapping(value = "/batch/create", method = RequestMethod.POST)
+    public BatchCreateVo batchCreate(@RequestBody BatchCreateDomain domain) {
+        return batchService.batchCreate(domain,getAccessUser());
+    }
+
+	@ApiOperation(value = "答题卡卡格式列表")
+	@RequestMapping(value = "/card/list", method = RequestMethod.POST)
+	public List<AnswerCardVo> cardList(@RequestParam Long examId) {
+		return answerCardService.listByExamIdForScanner(examId, getAccessUser());
+	}
+
+	@ApiOperation(value = "答题卡扫描结果保存")
+	@RequestMapping(value = "/batch/save", method = RequestMethod.POST)
+	public AnswerSaveVo batchSave(@RequestBody AnswerDomain domain) {
+	    User user = getAccessUser();
+		return batchService.batchSave(domain,user);
+	}
+
+	@ApiOperation(value = "答题卡扫描历史标记/取消异常")
+	@RequestMapping(value = "/mismatch/toggle", method = RequestMethod.POST)
+	public MismatchToggleVo mismatchToggle(MismatchToggleDomain domain) {
+		return paperService.mismatchToggle(domain);
+	}
+
+	@ApiOperation(value = "答题卡扫描原图上传")
+	@RequestMapping(value = "/sheet/upload", method = RequestMethod.POST)
+	public SheetUploadVo sheetUpload(@RequestParam Long batchId, @RequestParam String examNumber,
+			@RequestParam Integer paperNumber, @RequestParam Integer pageIndex, @RequestParam MultipartFile file,
+			@RequestParam String md5) {
+		return paperService.sheetUpload(batchId, examNumber, paperNumber, pageIndex, file, md5);
+	}
+	
+	@ApiOperation(value = "答题卡扫描裁切图上传")
+	@RequestMapping(value = "/slice/upload", method = RequestMethod.POST)
+	public SliceUploadVo sliceUpload(@RequestParam Long batchId, @RequestParam String examNumber,
+			@RequestParam Integer paperNumber, @RequestParam Integer pageIndex,@RequestParam Integer index, @RequestParam MultipartFile file,
+			@RequestParam String md5) {
+		return paperService.sliceUpload(batchId, examNumber, paperNumber, pageIndex,index, file, md5);
+	}
+	
+	@ApiOperation(value = "答题卡扫描批次提交审核/查询审核结果")
+	@RequestMapping(value = "/batch/verify", method = RequestMethod.POST)
+	public BatchVerifyVo batchVerify(@RequestParam Long id) {
+		return batchService.batchVerify(id);
+	}
+	
+	@ApiOperation(value = "答题卡扫描批次完成")
+	@RequestMapping(value = "/batch/finish", method = RequestMethod.POST)
+	public BatchFinishVo batchFinish(@RequestParam Long id) {
+		return batchService.batchFinish(id);
+	}
+}

+ 71 - 0
src/main/java/cn/com/qmth/scancloud/controller/scan/OmrTaskController.java

@@ -0,0 +1,71 @@
+package cn.com.qmth.scancloud.controller.scan;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+
+import cn.com.qmth.scancloud.bean.User;
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.service.OmrTaskService;
+import cn.com.qmth.scancloud.vo.task.TaskResultVo;
+import cn.com.qmth.scancloud.vo.task.TaskSaveVo;
+import cn.com.qmth.scancloud.vo.task.TaskStatusVo;
+import cn.com.qmth.scancloud.vo.task.TaskVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import net.sf.json.JSONObject;
+
+@RestController
+@Api(tags = "识别对照任务接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/scan/task/omr")
+@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+public class OmrTaskController extends BaseController {
+
+    protected static final Logger log = LoggerFactory.getLogger(OmrTaskController.class);
+
+    @Autowired
+    private OmrTaskService taskService;
+    @Autowired
+    private OmrTaskService omrTaskService;
+    
+    @ApiOperation(value = "识别对照任务获取")
+    @RequestMapping(value = "/get", method = RequestMethod.POST)
+    public TaskVo get(@RequestParam Long examId) {
+        User user = getAccessUser();
+        TaskVo task = taskService.getTask(examId, user.getAccount());
+        return task;
+    }
+
+    @ApiOperation(value = "识别对照任务提交")
+    @RequestMapping(value = "/save", method = RequestMethod.POST)
+    public TaskSaveVo save(@RequestBody TaskResultVo result) {
+        User user = getAccessUser();
+        return taskService.submitTask(result, user.getAccount());
+    }
+
+    @ApiOperation(value = "识别对照任务状态")
+    @RequestMapping(value = "/status", method = RequestMethod.POST)
+    public TaskStatusVo status(@RequestParam Long examId) {
+        User user = getAccessUser();
+        return taskService.getStatus(examId, false,user.getAccount());
+    }
+    
+    @ApiOperation(value = "识别对照任务状态")
+    @RequestMapping(value = "/release", method = RequestMethod.POST)
+    public JSONObject release(@RequestParam Long examId) {
+        User user = getAccessUser();
+        omrTaskService.releaseByUser(examId, user.getAccount());
+        JSONObject result = new JSONObject();
+        result.accumulate("success", true);
+        return result;
+    }
+}

+ 43 - 0
src/main/java/cn/com/qmth/scancloud/controller/scan/ScanExamController.java

@@ -0,0 +1,43 @@
+package cn.com.qmth.scancloud.controller.scan;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.service.ExamService;
+import cn.com.qmth.scancloud.vo.scanexaminfo.ScanExamInfoVo;
+import cn.com.qmth.scancloud.vo.scanexamlist.ScanExamListVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@RestController
+@Api(tags = "扫描功能-考试接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/scan/exam")
+@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+public class ScanExamController extends BaseController {
+
+    @Autowired
+    private ExamService examService;
+
+    @ApiOperation(value = "考试详情")
+    @RequestMapping(value = "/info", method = RequestMethod.POST)
+    public ScanExamInfoVo info(@RequestParam Long id) {
+        return examService.getScanExamInfo(id,getAccessUser());
+    }
+    
+    @ApiOperation(value = "考试列表")
+    @RequestMapping(value = "/list", method = RequestMethod.POST)
+    public List<ScanExamListVo> list() {
+        return examService.getScanExamList();
+    }
+
+}

+ 38 - 0
src/main/java/cn/com/qmth/scancloud/controller/scan/ScannerAuthController.java

@@ -0,0 +1,38 @@
+package cn.com.qmth.scancloud.controller.scan;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.qmth.boot.api.constant.ApiConstant;
+
+import cn.com.qmth.scancloud.bean.ScannerLoginInfo;
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.service.AuthService;
+import cn.com.qmth.scancloud.util.IpUtil;
+import cn.com.qmth.scancloud.vo.ScannerLoginVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@RestController
+@Api(tags = "扫描员登录接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/scan")
+public class ScannerAuthController extends BaseController {
+
+	@Autowired
+	private AuthService authService;
+
+	@ApiOperation(value = "扫描员登录")
+	@PostMapping("login")
+	public ScannerLoginVo login(ScannerLoginInfo loginInfo, HttpServletRequest request) {
+
+		String ip = IpUtil.getRemoteIp(request);
+
+		return ScannerLoginVo.of(authService.login(ip,loginInfo));
+	}
+
+
+}

+ 43 - 0
src/main/java/cn/com/qmth/scancloud/controller/scan/StudentController.java

@@ -0,0 +1,43 @@
+package cn.com.qmth.scancloud.controller.scan;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+
+import cn.com.qmth.scancloud.controller.BaseController;
+import cn.com.qmth.scancloud.service.StudentService;
+import cn.com.qmth.scancloud.vo.student.StudentQuery;
+import cn.com.qmth.scancloud.vo.student.StudentVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@RestController
+@Api(tags = "扫描功能-考生接口")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/scan/student")
+@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
+public class StudentController extends BaseController {
+
+    @Autowired
+    private StudentService studentService;
+
+    
+    @ApiOperation(value = "整袋考生查询")
+    @RequestMapping(value = "/package/list", method = RequestMethod.POST)
+    public List<StudentVo> packageList(StudentQuery query) {
+        return studentService.packageList(query);
+    }
+    
+    @ApiOperation(value = "考生查询")
+    @RequestMapping(value = "/find", method = RequestMethod.POST)
+    public StudentVo student(StudentQuery query) {
+        return studentService.findOne(query);
+    }
+    
+}

+ 9 - 0
src/main/java/cn/com/qmth/scancloud/dao/AnswerCardDao.java

@@ -0,0 +1,9 @@
+package cn.com.qmth.scancloud.dao;
+
+import com.github.jeffreyning.mybatisplus.base.MppBaseMapper;
+
+import cn.com.qmth.scancloud.entity.AnswerCardEntity;
+
+public interface AnswerCardDao extends MppBaseMapper<AnswerCardEntity> {
+
+}

+ 37 - 0
src/main/java/cn/com/qmth/scancloud/dao/BatchDao.java

@@ -0,0 +1,37 @@
+package cn.com.qmth.scancloud.dao;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import cn.com.qmth.scancloud.bean.BatchQueryDomain;
+import cn.com.qmth.scancloud.bean.MismatchQueryDomain;
+import cn.com.qmth.scancloud.entity.BatchEntity;
+import cn.com.qmth.scancloud.enums.VerifyStatus;
+import cn.com.qmth.scancloud.vo.BatchQueryVo;
+import cn.com.qmth.scancloud.vo.batchdetail.BatchDetailVo;
+import cn.com.qmth.scancloud.vo.mismatchquery.MismatchQueryVo;
+
+public interface BatchDao extends BaseMapper<BatchEntity> {
+
+    void updateScanCount(@Param("id") Long id);
+
+    void updateAssignedCount(@Param("id") Long id);
+
+    IPage<BatchQueryVo> batchQueryPage(Page<BatchQueryVo> page, @Param("query") BatchQueryDomain query);
+
+    List<BatchDetailVo> batchDetailList(@Param("id") Long id);
+
+    IPage<MismatchQueryVo> mismatchQueryPage(Page<MismatchQueryVo> page, @Param("query") MismatchQueryDomain query);
+
+    IPage<BatchEntity> findUnVerify(Page<BatchEntity> page,@Param("examId") Long examId,@Param("status") VerifyStatus status);
+
+	List<BatchQueryVo> findAssignedCount(@Param("batchIds")List<Long> batchIds);
+
+	List<String> batchScanner(@Param("examId")Long examId);
+
+}

+ 22 - 0
src/main/java/cn/com/qmth/scancloud/dao/ExamDao.java

@@ -0,0 +1,22 @@
+package cn.com.qmth.scancloud.dao;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+
+import cn.com.qmth.scancloud.entity.ExamEntity;
+import cn.com.qmth.scancloud.vo.ExamVo;
+import cn.com.qmth.scancloud.vo.examinfo.ExamQuery;
+import cn.com.qmth.scancloud.vo.scanexamlist.ScanExamListQuery;
+import cn.com.qmth.scancloud.vo.scanexamlist.ScanExamListVo;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+public interface ExamDao extends BaseMapper<ExamEntity> {
+
+    List<ScanExamListVo> getExamList(@Param("query") ScanExamListQuery query);
+
+    IPage<ExamVo> pageExam(Page<ExamVo> page, @Param("query") ExamQuery query,@Param("schoolId")Long schoolId);
+}

+ 8 - 0
src/main/java/cn/com/qmth/scancloud/dao/FilePropertyDao.java

@@ -0,0 +1,8 @@
+package cn.com.qmth.scancloud.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import cn.com.qmth.scancloud.entity.FilePropertyEntity;
+
+public interface FilePropertyDao extends BaseMapper<FilePropertyEntity> {
+}

+ 11 - 0
src/main/java/cn/com/qmth/scancloud/dao/OmrGroupDao.java

@@ -0,0 +1,11 @@
+package cn.com.qmth.scancloud.dao;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import cn.com.qmth.scancloud.entity.OmrGroupEntity;
+
+public interface OmrGroupDao extends BaseMapper<OmrGroupEntity> {
+	void updateTotalCount(@Param(value = "id") Long id);
+}

+ 17 - 0
src/main/java/cn/com/qmth/scancloud/dao/OmrTaskDao.java

@@ -0,0 +1,17 @@
+package cn.com.qmth.scancloud.dao;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import cn.com.qmth.scancloud.entity.OmrTaskEntity;
+import cn.com.qmth.scancloud.enums.TaskStatus;
+
+public interface OmrTaskDao extends BaseMapper<OmrTaskEntity> {
+
+    List<OmrTaskEntity> findUnMarked(@Param(value = "examId") Long examId, @Param(value = "startNumber") int startNumber,
+            @Param(value = "pageSize") int pageSize, @Param(value = "status") TaskStatus status);
+
+}

+ 9 - 0
src/main/java/cn/com/qmth/scancloud/dao/PackageCardDao.java

@@ -0,0 +1,9 @@
+package cn.com.qmth.scancloud.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import cn.com.qmth.scancloud.entity.PackageCardEntity;
+
+public interface PackageCardDao extends BaseMapper<PackageCardEntity> {
+
+}

+ 9 - 0
src/main/java/cn/com/qmth/scancloud/dao/PackageResultDao.java

@@ -0,0 +1,9 @@
+package cn.com.qmth.scancloud.dao;
+
+import com.github.jeffreyning.mybatisplus.base.MppBaseMapper;
+
+import cn.com.qmth.scancloud.entity.PackageResultEntity;
+
+public interface PackageResultDao extends MppBaseMapper<PackageResultEntity> {
+
+}

+ 9 - 0
src/main/java/cn/com/qmth/scancloud/dao/PackageTaskDao.java

@@ -0,0 +1,9 @@
+package cn.com.qmth.scancloud.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import cn.com.qmth.scancloud.entity.PackageTaskEntity;
+
+public interface PackageTaskDao extends BaseMapper<PackageTaskEntity> {
+
+}

+ 30 - 0
src/main/java/cn/com/qmth/scancloud/dao/PaperDao.java

@@ -0,0 +1,30 @@
+package cn.com.qmth.scancloud.dao;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import cn.com.qmth.scancloud.entity.PaperEntity;
+import cn.com.qmth.scancloud.vo.ScannerWorkloadVo;
+import cn.com.qmth.scancloud.vo.answerquery.StudentPaperVo;
+import cn.com.qmth.scancloud.vo.mismatchquery.MismatchQueryVo;
+import cn.com.qmth.scancloud.vo.paper.PaperVo;
+
+public interface PaperDao extends BaseMapper<PaperEntity> {
+	
+	public List<PaperEntity> findStudentPaperEffective(@Param(value = "studentId") Long studentId);
+	public List<PaperVo> findStudentPaper(@Param(value = "studentId") Long studentId);
+
+	public List<ScannerWorkloadVo> workload(@Param(value = "examId") Long examId,
+			@Param(value = "startTime") Long startTime, @Param(value = "endTime") Long endTime);
+
+	public Integer findStudentCountByBatch(@Param(value = "batchId")Long batchId);
+
+	public List<PaperEntity> listByMismatchQuery(@Param(value = "paramList")List<MismatchQueryVo> paramList);
+
+	public List<StudentPaperVo> listByStudentIds(@Param(value = "paramList")List<Long> paramList);
+
+	public List<PaperEntity> findAssigneByBatch(@Param(value = "batchId")Long batchId);
+}

+ 9 - 0
src/main/java/cn/com/qmth/scancloud/dao/PaperPageDao.java

@@ -0,0 +1,9 @@
+package cn.com.qmth.scancloud.dao;
+
+import com.github.jeffreyning.mybatisplus.base.MppBaseMapper;
+
+import cn.com.qmth.scancloud.entity.PaperPageEntity;
+
+public interface PaperPageDao extends MppBaseMapper<PaperPageEntity> {
+
+}

+ 9 - 0
src/main/java/cn/com/qmth/scancloud/dao/PaperStructureDao.java

@@ -0,0 +1,9 @@
+package cn.com.qmth.scancloud.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import cn.com.qmth.scancloud.entity.PaperStructureEntity;
+
+public interface PaperStructureDao extends BaseMapper<PaperStructureEntity> {
+	
+}

+ 9 - 0
src/main/java/cn/com/qmth/scancloud/dao/ScannerCardDao.java

@@ -0,0 +1,9 @@
+package cn.com.qmth.scancloud.dao;
+
+import com.github.jeffreyning.mybatisplus.base.MppBaseMapper;
+
+import cn.com.qmth.scancloud.entity.ScannerCardEntity;
+
+public interface ScannerCardDao extends MppBaseMapper<ScannerCardEntity> {
+
+}

+ 14 - 0
src/main/java/cn/com/qmth/scancloud/dao/ScannerDao.java

@@ -0,0 +1,14 @@
+package cn.com.qmth.scancloud.dao;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import cn.com.qmth.scancloud.entity.ScannerEntity;
+import cn.com.qmth.scancloud.vo.scannerinfo.ScannerInfo;
+
+public interface ScannerDao extends BaseMapper<ScannerEntity> {
+	public List<ScannerInfo> getInfoByExam(@Param(value = "examId") Long examId);
+}

+ 49 - 0
src/main/java/cn/com/qmth/scancloud/dao/StudentDao.java

@@ -0,0 +1,49 @@
+package cn.com.qmth.scancloud.dao;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import cn.com.qmth.scancloud.bean.AbsentQueryDomain;
+import cn.com.qmth.scancloud.bean.AnswerQueryDomain;
+import cn.com.qmth.scancloud.entity.StudentEntity;
+import cn.com.qmth.scancloud.vo.AbsentQueryVo;
+import cn.com.qmth.scancloud.vo.AnswerExportVo;
+import cn.com.qmth.scancloud.vo.ImportStudentQueryVo;
+import cn.com.qmth.scancloud.vo.ImportStudentVo;
+import cn.com.qmth.scancloud.vo.StudentUploadVo;
+import cn.com.qmth.scancloud.vo.answerquery.AnswerQueryVo;
+
+public interface StudentDao extends BaseMapper<StudentEntity> {
+
+    List<String> listCampusByExamId(@Param("examId") Long examId);
+
+    List<String> listSiteByExamId(@Param("examId") Long examId);
+
+    IPage<AbsentQueryVo> absentQueryPage(Page<AbsentQueryVo> page, @Param("groupNameCol") String groupNameCol,
+            @Param("query") AbsentQueryDomain query);
+
+    IPage<AnswerQueryVo> queryPage(Page<AnswerQueryVo> page, @Param("query") AnswerQueryDomain query);
+
+    List<StudentUploadVo> findToUpload(@Param("pageSize") Integer pageSize, @Param("schoolId") Long schoolId);
+
+    List<AbsentQueryVo> absentQueryList(@Param("groupNameCol") String groupNameCol,
+            @Param("query") AbsentQueryDomain query);
+
+    List<AnswerExportVo> queryList(@Param("query") AnswerQueryDomain query);
+
+    int getPackageCountByExam(@Param("examId") Long examId);
+
+    int countByQuery(@Param("query") ImportStudentQueryVo query);
+
+    IPage<ImportStudentVo> listPageQuery(Page<ImportStudentVo> page, @Param("query") ImportStudentQueryVo query);
+
+	List<StudentUploadVo> findToPictureCopy(@Param("pageSize") Integer pageSize);
+
+	int getUploadedCount(@Param("examId")Long examId);
+
+}

+ 17 - 0
src/main/java/cn/com/qmth/scancloud/dao/StudentPaperDao.java

@@ -0,0 +1,17 @@
+package cn.com.qmth.scancloud.dao;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.github.jeffreyning.mybatisplus.base.MppBaseMapper;
+
+import cn.com.qmth.scancloud.entity.StudentPaperEntity;
+import cn.com.qmth.scancloud.vo.StudentPaperCountVo;
+
+public interface StudentPaperDao extends MppBaseMapper<StudentPaperEntity> {
+
+    List<StudentPaperEntity> findPaperIdByExamId(@Param("examId") Long examId);
+    
+    public List<StudentPaperCountVo> findStudentPaperCount(@Param(value = "paramList")List<Long> paramList);
+}

+ 9 - 0
src/main/java/cn/com/qmth/scancloud/dao/SubjectDao.java

@@ -0,0 +1,9 @@
+package cn.com.qmth.scancloud.dao;
+
+import com.github.jeffreyning.mybatisplus.base.MppBaseMapper;
+
+import cn.com.qmth.scancloud.entity.SubjectEntity;
+
+public interface SubjectDao extends MppBaseMapper<SubjectEntity> {
+
+}

+ 9 - 0
src/main/java/cn/com/qmth/scancloud/dao/SystemConfigDao.java

@@ -0,0 +1,9 @@
+package cn.com.qmth.scancloud.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import cn.com.qmth.scancloud.entity.SystemConfigEntity;
+
+public interface SystemConfigDao extends BaseMapper<SystemConfigEntity> {
+
+}

+ 9 - 0
src/main/java/cn/com/qmth/scancloud/dao/UserDao.java

@@ -0,0 +1,9 @@
+package cn.com.qmth.scancloud.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import cn.com.qmth.scancloud.entity.UserEntity;
+
+public interface UserDao extends BaseMapper<UserEntity> {
+
+}

+ 3 - 0
src/main/java/cn/com/qmth/scancloud/entity/AnswerCardEntity.java

@@ -4,6 +4,7 @@ import cn.com.qmth.scancloud.entity.base.AuditingWithoutIdEntity;
 import cn.com.qmth.scancloud.enums.CardSource;
 
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.github.jeffreyning.mybatisplus.anno.MppMultiId;
 
 // 试卷卡格式
 @TableName("sc_answer_card")
@@ -14,8 +15,10 @@ public class AnswerCardEntity extends AuditingWithoutIdEntity {
      */
     private static final long serialVersionUID = -7904338527706136352L;
 
+    @MppMultiId
     private Long examId;
 
+    @MppMultiId
     private Integer number;
 
     // 可选

+ 0 - 10
src/main/java/cn/com/qmth/scancloud/entity/BatchEntity.java

@@ -15,8 +15,6 @@ public class BatchEntity extends AuditingEntity {
      */
     private static final long serialVersionUID = 6630267744496706862L;
 
-    private String code;
-
     private Long examId;
 
     private String device;
@@ -34,14 +32,6 @@ public class BatchEntity extends AuditingEntity {
 
     private VerifyStatus verifyStatus;
 
-    public String getCode() {
-        return code;
-    }
-
-    public void setCode(String code) {
-        this.code = code;
-    }
-
     public Long getExamId() {
         return examId;
     }

+ 53 - 3
src/main/java/cn/com/qmth/scancloud/entity/ExamEntity.java

@@ -1,12 +1,18 @@
 package cn.com.qmth.scancloud.entity;
 
-import cn.com.qmth.scancloud.entity.base.AuditingWithoutIdEntity;
-import cn.com.qmth.scancloud.enums.ExamMode;
+import java.util.List;
 
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.GsonTypeHandler;
+
+import cn.com.qmth.scancloud.entity.base.AuditingWithoutIdEntity;
+import cn.com.qmth.scancloud.enums.ExamMode;
 
 // 考试
-@TableName("sc_exam")
+@TableName(value ="sc_exam",autoResultMap = true)
 public class ExamEntity extends AuditingWithoutIdEntity {
 
     /**
@@ -14,6 +20,7 @@ public class ExamEntity extends AuditingWithoutIdEntity {
      */
     private static final long serialVersionUID = 2232451399940497087L;
 
+    @TableId(type = IdType.INPUT)
     private Long id;
 
     private Long schoolId;
@@ -34,7 +41,16 @@ public class ExamEntity extends AuditingWithoutIdEntity {
 
     private Boolean enableSinglePageAnswer;
 
+    private Integer answerPaperNumberFigure;
+
     private Boolean enableUpload;
+    
+    private Boolean enableSyncVerify;
+    
+    @TableField(value = "paper_type_barcode_content", typeHandler = GsonTypeHandler.class)
+    private List<String> paperTypeBarcodeContent;
+    
+    private String absentBarcodeContent;
 
     public Long getId() {
         return id;
@@ -123,4 +139,38 @@ public class ExamEntity extends AuditingWithoutIdEntity {
     public void setEnableUpload(Boolean enableUpload) {
         this.enableUpload = enableUpload;
     }
+
+    public Integer getAnswerPaperNumberFigure() {
+        return answerPaperNumberFigure;
+    }
+
+    public void setAnswerPaperNumberFigure(Integer answerPaperNumberFigure) {
+        this.answerPaperNumberFigure = answerPaperNumberFigure;
+    }
+
+	public Boolean getEnableSyncVerify() {
+		return enableSyncVerify;
+	}
+
+	public void setEnableSyncVerify(Boolean enableSyncVerify) {
+		this.enableSyncVerify = enableSyncVerify;
+	}
+
+	public List<String> getPaperTypeBarcodeContent() {
+		return paperTypeBarcodeContent;
+	}
+
+	public void setPaperTypeBarcodeContent(List<String> paperTypeBarcodeContent) {
+		this.paperTypeBarcodeContent = paperTypeBarcodeContent;
+	}
+
+	public String getAbsentBarcodeContent() {
+		return absentBarcodeContent;
+	}
+
+	public void setAbsentBarcodeContent(String absentBarcodeContent) {
+		this.absentBarcodeContent = absentBarcodeContent;
+	}
+    
+    
 }

+ 49 - 0
src/main/java/cn/com/qmth/scancloud/entity/FilePropertyEntity.java

@@ -0,0 +1,49 @@
+package cn.com.qmth.scancloud.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import cn.com.qmth.scancloud.entity.base.BaseEntity;
+
+@TableName("sc_file_property")
+public class FilePropertyEntity extends BaseEntity {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 8795800729334229171L;
+
+    private Long examId;
+
+    @TableId(type = IdType.INPUT)
+    private String path;
+
+    private String md5;
+
+	public Long getExamId() {
+		return examId;
+	}
+
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+
+	public String getPath() {
+		return path;
+	}
+
+	public void setPath(String path) {
+		this.path = path;
+	}
+
+	public String getMd5() {
+		return md5;
+	}
+
+	public void setMd5(String md5) {
+		this.md5 = md5;
+	}
+
+
+}

+ 11 - 9
src/main/java/cn/com/qmth/scancloud/entity/OmrGroupEntity.java

@@ -1,19 +1,20 @@
 package cn.com.qmth.scancloud.entity;
 
-import java.util.List;
-
 import cn.com.qmth.scancloud.entity.base.AuditingEntity;
 import cn.com.qmth.scancloud.enums.Stage;
-import cn.com.qmth.scancloud.model.OcrCondition;
-
+import cn.com.qmth.scancloud.handle.OmrConditionListTypeHandler;
+import cn.com.qmth.scancloud.model.OmrCondition;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 
+import java.util.List;
+
 // 识别对照任务分组
-@TableName("sc_omr_group")
+@TableName(value = "sc_omr_group", autoResultMap = true)
 public class OmrGroupEntity extends AuditingEntity {
 
     /**
-     * 
+     *
      */
     private static final long serialVersionUID = 3713052032605963927L;
 
@@ -23,7 +24,8 @@ public class OmrGroupEntity extends AuditingEntity {
 
     private Stage stage;
 
-    private List<OcrCondition> conditions;
+    @TableField(value = "conditions", typeHandler = OmrConditionListTypeHandler.class)
+    private List<OmrCondition> conditions;
 
     private Integer totalCount;
 
@@ -51,11 +53,11 @@ public class OmrGroupEntity extends AuditingEntity {
         this.stage = stage;
     }
 
-    public List<OcrCondition> getConditions() {
+    public List<OmrCondition> getConditions() {
         return conditions;
     }
 
-    public void setConditions(List<OcrCondition> conditions) {
+    public void setConditions(List<OmrCondition> conditions) {
         this.conditions = conditions;
     }
 

+ 39 - 3
src/main/java/cn/com/qmth/scancloud/entity/OmrTaskEntity.java

@@ -1,12 +1,17 @@
 package cn.com.qmth.scancloud.entity;
 
-import cn.com.qmth.scancloud.entity.base.AuditingEntity;
-import cn.com.qmth.scancloud.enums.TaskStatus;
+import java.util.List;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 
+import cn.com.qmth.scancloud.entity.base.AuditingEntity;
+import cn.com.qmth.scancloud.enums.TaskStatus;
+import cn.com.qmth.scancloud.handle.OmrTaskPageListTypeHandler;
+import cn.com.qmth.scancloud.model.OmrTaskPage;
+
 // 识别对照任务
-@TableName("sc_omr_task")
+@TableName(value ="sc_omr_task",autoResultMap = true)
 public class OmrTaskEntity extends AuditingEntity {
 
     /**
@@ -26,6 +31,13 @@ public class OmrTaskEntity extends AuditingEntity {
 
     private String device;
 
+    private Integer paperNumber;
+
+    private Long paperId;
+
+    @TableField(value = "pages", typeHandler = OmrTaskPageListTypeHandler.class)
+    private List<OmrTaskPage> pages;
+
     public Long getExamId() {
         return examId;
     }
@@ -74,4 +86,28 @@ public class OmrTaskEntity extends AuditingEntity {
         this.device = device;
     }
 
+    public Integer getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(Integer paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+
+    public Long getPaperId() {
+        return paperId;
+    }
+
+    public void setPaperId(Long paperId) {
+        this.paperId = paperId;
+    }
+
+    public List<OmrTaskPage> getPages() {
+        return pages;
+    }
+
+    public void setPages(List<OmrTaskPage> pages) {
+        this.pages = pages;
+    }
+
 }

+ 0 - 55
src/main/java/cn/com/qmth/scancloud/entity/OmrTaskPaperEntity.java

@@ -1,55 +0,0 @@
-package cn.com.qmth.scancloud.entity;
-
-import java.util.List;
-
-import cn.com.qmth.scancloud.entity.base.AuditingEntity;
-import cn.com.qmth.scancloud.model.OmrTaskPage;
-
-import com.baomidou.mybatisplus.annotation.TableName;
-
-@TableName("sc_omr_task_paper")
-public class OmrTaskPaperEntity extends AuditingEntity {
-
-    private static final long serialVersionUID = 2083448665203245516L;
-
-    private Long taskId;
-
-    private Integer number;
-
-    private Integer paperId;
-
-    private List<OmrTaskPage> pages;
-
-    public Long getTaskId() {
-        return taskId;
-    }
-
-    public void setTaskId(Long taskId) {
-        this.taskId = taskId;
-    }
-
-    public Integer getNumber() {
-        return number;
-    }
-
-    public void setPaperNumber(Integer number) {
-        this.number = number;
-    }
-
-    public Integer getPaperId() {
-        return paperId;
-    }
-
-    public void setPaperId(Integer paperId) {
-        this.paperId = paperId;
-    }
-
-    public List<OmrTaskPage> getPages() {
-        return pages;
-    }
-
-    public void setPages(List<OmrTaskPage> pages) {
-        this.pages = pages;
-    }
-
-}

+ 7 - 3
src/main/java/cn/com/qmth/scancloud/entity/PackageResultEntity.java

@@ -4,23 +4,27 @@ import java.util.List;
 
 import cn.com.qmth.scancloud.entity.base.AuditingWithoutIdEntity;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.GsonTypeHandler;
+import com.github.jeffreyning.mybatisplus.anno.MppMultiId;
 
 // 签到表
-@TableName("sc_package_result")
+@TableName(value ="sc_package_result",autoResultMap = true)
 public class PackageResultEntity extends AuditingWithoutIdEntity {
 
     /**
      * 
      */
     private static final long serialVersionUID = -2443714675814813665L;
-
+    @MppMultiId
     private Long examId;
-
+    @MppMultiId
     private String packageCode;
 
     private String device;
 
+    @TableField(value = "path", typeHandler = GsonTypeHandler.class)
     private List<String> path;
 
     private Boolean assigned;

+ 20 - 0
src/main/java/cn/com/qmth/scancloud/entity/PaperEntity.java

@@ -26,6 +26,10 @@ public class PaperEntity extends AuditingEntity {
 
     private Boolean mismatch;
 
+    private Boolean assigned;
+
+    private Boolean questionFilled;
+
     public Long getExamId() {
         return examId;
     }
@@ -90,4 +94,20 @@ public class PaperEntity extends AuditingEntity {
         this.mismatch = mismatch;
     }
 
+    public Boolean getAssigned() {
+        return assigned;
+    }
+
+    public void setAssigned(Boolean assigned) {
+        this.assigned = assigned;
+    }
+
+    public Boolean getQuestionFilled() {
+        return questionFilled;
+    }
+
+    public void setQuestionFilled(Boolean questionFilled) {
+        this.questionFilled = questionFilled;
+    }
+
 }

+ 121 - 64
src/main/java/cn/com/qmth/scancloud/entity/PaperPageEntity.java

@@ -2,11 +2,17 @@ package cn.com.qmth.scancloud.entity;
 
 import java.util.List;
 
-import cn.com.qmth.scancloud.entity.base.AuditingWithoutIdEntity;
-
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.GsonTypeHandler;
+import com.github.jeffreyning.mybatisplus.anno.MppMultiId;
+
+import cn.com.qmth.scancloud.bean.answersave.ArrayResult;
+import cn.com.qmth.scancloud.bean.answersave.BoolResult;
+import cn.com.qmth.scancloud.bean.answersave.StringResult;
+import cn.com.qmth.scancloud.entity.base.AuditingWithoutIdEntity;
 
-@TableName("sc_paper_page")
+@TableName(value ="sc_paper_page",autoResultMap = true)
 public class PaperPageEntity extends AuditingWithoutIdEntity {
 
     /**
@@ -14,94 +20,145 @@ public class PaperPageEntity extends AuditingWithoutIdEntity {
      */
     private static final long serialVersionUID = -182520914017960004L;
 
+    @MppMultiId
     private Long paperId;
 
-    private Integer index;
+    @MppMultiId
+    private Integer pageIndex;
+    
+    private Long batchId;
+    
+    private Long examId;
+    
+    private Long studentId;
 
-    private Boolean absent;
+    @TableField(value = "absent", typeHandler = GsonTypeHandler.class)
+    private BoolResult absent;
 
-    private Boolean breach;
+    @TableField(value = "breach", typeHandler = GsonTypeHandler.class)
+    private BoolResult breach;
 
-    private String paperType;
+    @TableField(value = "paper_type", typeHandler = GsonTypeHandler.class)
+    private StringResult paperType;
 
-    private List<String> question;
+    @TableField(value = "question", typeHandler = GsonTypeHandler.class)
+    private ArrayResult question;
 
-    private List<String> selective;
+    @TableField(value = "selective", typeHandler = GsonTypeHandler.class)
+    private ArrayResult selective;
 
     private String sheetPath;
 
-    private List<String> sliceParh;
+    @TableField(value = "slice_path", typeHandler = GsonTypeHandler.class)
+    private List<String> slicePath;
+
+    private String recogData;
+    
+    
+	public Long getPaperId() {
+		return paperId;
+	}
+
+	public void setPaperId(Long paperId) {
+		this.paperId = paperId;
+	}
+
+
+	public Integer getPageIndex() {
+		return pageIndex;
+	}
+
+	public void setPageIndex(Integer pageIndex) {
+		this.pageIndex = pageIndex;
+	}
+
+	public BoolResult getAbsent() {
+		return absent;
+	}
+
+	public void setAbsent(BoolResult absent) {
+		this.absent = absent;
+	}
+
+	public BoolResult getBreach() {
+		return breach;
+	}
+
+	public void setBreach(BoolResult breach) {
+		this.breach = breach;
+	}
 
-    public Long getPaperId() {
-        return paperId;
-    }
+	public StringResult getPaperType() {
+		return paperType;
+	}
 
-    public void setPaperId(Long paperId) {
-        this.paperId = paperId;
-    }
+	public void setPaperType(StringResult paperType) {
+		this.paperType = paperType;
+	}
 
-    public Integer getIndex() {
-        return index;
-    }
+	public ArrayResult getQuestion() {
+		return question;
+	}
 
-    public void setIndex(Integer index) {
-        this.index = index;
-    }
+	public void setQuestion(ArrayResult question) {
+		this.question = question;
+	}
 
-    public Boolean getAbsent() {
-        return absent;
-    }
+	public ArrayResult getSelective() {
+		return selective;
+	}
 
-    public void setAbsent(Boolean absent) {
-        this.absent = absent;
-    }
+	public void setSelective(ArrayResult selective) {
+		this.selective = selective;
+	}
 
-    public Boolean getBreach() {
-        return breach;
-    }
+	public String getSheetPath() {
+		return sheetPath;
+	}
 
-    public void setBreach(Boolean breach) {
-        this.breach = breach;
-    }
+	public void setSheetPath(String sheetPath) {
+		this.sheetPath = sheetPath;
+	}
 
-    public String getPaperType() {
-        return paperType;
-    }
+	public List<String> getSlicePath() {
+		return slicePath;
+	}
 
-    public void setPaperType(String paperType) {
-        this.paperType = paperType;
-    }
+	public void setSlicePath(List<String> slicePath) {
+		this.slicePath = slicePath;
+	}
 
-    public List<String> getQuestion() {
-        return question;
-    }
+	public Long getBatchId() {
+		return batchId;
+	}
 
-    public void setQuestion(List<String> question) {
-        this.question = question;
-    }
+	public void setBatchId(Long batchId) {
+		this.batchId = batchId;
+	}
 
-    public List<String> getSelective() {
-        return selective;
-    }
+	public Long getStudentId() {
+		return studentId;
+	}
 
-    public void setSelective(List<String> selective) {
-        this.selective = selective;
-    }
+	public void setStudentId(Long studentId) {
+		this.studentId = studentId;
+	}
 
-    public String getSheetPath() {
-        return sheetPath;
-    }
+	public Long getExamId() {
+		return examId;
+	}
 
-    public void setSheetPath(String sheetPath) {
-        this.sheetPath = sheetPath;
-    }
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
 
-    public List<String> getSliceParh() {
-        return sliceParh;
-    }
+	public String getRecogData() {
+		return recogData;
+	}
 
-    public void setSliceParh(List<String> sliceParh) {
-        this.sliceParh = sliceParh;
-    }
+	public void setRecogData(String recogData) {
+		this.recogData = recogData;
+	}
 
+    
 }

+ 69 - 0
src/main/java/cn/com/qmth/scancloud/entity/PaperStructureEntity.java

@@ -0,0 +1,69 @@
+package cn.com.qmth.scancloud.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import cn.com.qmth.scancloud.entity.base.AuditingEntity;
+import cn.com.qmth.scancloud.enums.OmrField;
+
+@TableName("sc_paper_structure")
+public class PaperStructureEntity extends AuditingEntity {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 7509644639392197500L;
+	
+	private Long examId;
+	private Integer cardNumber;
+	private Integer paperNumber;
+	private Integer pageIndex;
+	private OmrField field;
+	private Integer questionNumber;
+	private Boolean single;
+	
+	
+	public Integer getCardNumber() {
+		return cardNumber;
+	}
+	public void setCardNumber(Integer cardNumber) {
+		this.cardNumber = cardNumber;
+	}
+	public Long getExamId() {
+		return examId;
+	}
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+	public Integer getPaperNumber() {
+		return paperNumber;
+	}
+	public void setPaperNumber(Integer paperNumber) {
+		this.paperNumber = paperNumber;
+	}
+	public Integer getPageIndex() {
+		return pageIndex;
+	}
+	public void setPageIndex(Integer pageIndex) {
+		this.pageIndex = pageIndex;
+	}
+	public OmrField getField() {
+		return field;
+	}
+	public void setField(OmrField field) {
+		this.field = field;
+	}
+	public Integer getQuestionNumber() {
+		return questionNumber;
+	}
+	public void setQuestionNumber(Integer questionNumber) {
+		this.questionNumber = questionNumber;
+	}
+	public Boolean getSingle() {
+		return single;
+	}
+	public void setSingle(Boolean single) {
+		this.single = single;
+	}
+
+	
+}

Неке датотеке нису приказане због велике количине промена