Browse Source

初始化项目

zengxj 5 years ago
parent
commit
fc51319e5f
100 changed files with 8462 additions and 96 deletions
  1. 22 22
      .gitignore
  2. 12 0
      Jenkins.txt
  3. 0 72
      LICENSE
  4. 2068 0
      OMML2MML.XSL
  5. 10 2
      README.md
  6. 2 0
      a.html
  7. BIN
      image/image1.jpeg
  8. 0 0
      log/history/logback-error-2019-03-31.log
  9. 54 0
      log/history/logback-info-2019-03-31.log
  10. 70 0
      log/history/logback-info-2019-04-30.log
  11. 3 0
      log/history/logback-warn-2019-03-31.log
  12. 2 0
      log/history/logback-warn-2019-04-30.log
  13. 0 0
      log/logback-debug-%d{yyyy-MM-dd}.log
  14. 339 0
      log/logback-error-%d{yyyy-MM-dd}.log
  15. 93 0
      log/logback-info-%d{yyyy-MM-dd}.log
  16. 4 0
      log/logback-warn-%d{yyyy-MM-dd}.log
  17. 191 0
      pom.xml
  18. 73 0
      result.html
  19. 6 0
      src/main/docker/Dockerfile
  20. 1 0
      src/main/frontend/README.md
  21. 18 0
      src/main/java/edu/math/diagnosis/BootApplication.java
  22. 45 0
      src/main/java/edu/math/diagnosis/cache/DbCache.java
  23. 74 0
      src/main/java/edu/math/diagnosis/cache/DbCacheFactory.java
  24. 16 0
      src/main/java/edu/math/diagnosis/cache/instance/DbCacheDemo.java
  25. 43 0
      src/main/java/edu/math/diagnosis/cache/instance/OptionCache.java
  26. 31 0
      src/main/java/edu/math/diagnosis/cache/instance/PaperCache.java
  27. 43 0
      src/main/java/edu/math/diagnosis/cache/instance/QuestionCache.java
  28. 19 0
      src/main/java/edu/math/diagnosis/config/AjaxAuthenticationEntryPoint.java
  29. 14 0
      src/main/java/edu/math/diagnosis/config/AjaxRequestMatcher.java
  30. 28 0
      src/main/java/edu/math/diagnosis/config/ConfigConstants.java
  31. 15 0
      src/main/java/edu/math/diagnosis/config/Constants.java
  32. 31 0
      src/main/java/edu/math/diagnosis/config/CsrfHeaderFilter.java
  33. 64 0
      src/main/java/edu/math/diagnosis/config/DiagnosisConfig.java
  34. 53 0
      src/main/java/edu/math/diagnosis/config/LogOperator.java
  35. 58 0
      src/main/java/edu/math/diagnosis/config/LoginSuccessHandler.java
  36. 21 0
      src/main/java/edu/math/diagnosis/config/LogoutHandler.java
  37. 18 0
      src/main/java/edu/math/diagnosis/config/Md5PasswordEncoder.java
  38. 36 0
      src/main/java/edu/math/diagnosis/config/MvcConfig.java
  39. 76 0
      src/main/java/edu/math/diagnosis/config/RedisConfig.java
  40. 36 0
      src/main/java/edu/math/diagnosis/config/StartUpWork.java
  41. 45 0
      src/main/java/edu/math/diagnosis/config/Swagger2Config.java
  42. 39 0
      src/main/java/edu/math/diagnosis/config/UploadProperties.java
  43. 17 0
      src/main/java/edu/math/diagnosis/config/WebAuthenticationProvider.java
  44. 143 0
      src/main/java/edu/math/diagnosis/config/WebSecurityConfig.java
  45. 467 0
      src/main/java/edu/math/diagnosis/controller/CommitController.java
  46. 64 0
      src/main/java/edu/math/diagnosis/controller/FileController.java
  47. 42 0
      src/main/java/edu/math/diagnosis/controller/OptionController.java
  48. 99 0
      src/main/java/edu/math/diagnosis/controller/PaperController.java
  49. 84 0
      src/main/java/edu/math/diagnosis/controller/QuestionController.java
  50. 61 0
      src/main/java/edu/math/diagnosis/controller/TempController.java
  51. 109 0
      src/main/java/edu/math/diagnosis/controller/TestController.java
  52. 45 0
      src/main/java/edu/math/diagnosis/controller/UserInfoController.java
  53. 43 0
      src/main/java/edu/math/diagnosis/controller/UserManagerController.java
  54. 7 0
      src/main/java/edu/math/diagnosis/dao/AuthorityRepo.java
  55. 8 0
      src/main/java/edu/math/diagnosis/dao/CommitRepo.java
  56. 20 0
      src/main/java/edu/math/diagnosis/dao/OptionRepo.java
  57. 12 0
      src/main/java/edu/math/diagnosis/dao/PaperCommitRepo.java
  58. 14 0
      src/main/java/edu/math/diagnosis/dao/PaperRepo.java
  59. 14 0
      src/main/java/edu/math/diagnosis/dao/PaperResultRepo.java
  60. 11 0
      src/main/java/edu/math/diagnosis/dao/PaperTemplateRepo.java
  61. 19 0
      src/main/java/edu/math/diagnosis/dao/QuestionRepo.java
  62. 12 0
      src/main/java/edu/math/diagnosis/dao/ReportRepo.java
  63. 11 0
      src/main/java/edu/math/diagnosis/dao/RoleRepo.java
  64. 11 0
      src/main/java/edu/math/diagnosis/dao/SectionRepo.java
  65. 11 0
      src/main/java/edu/math/diagnosis/dao/SubjectRepo.java
  66. 19 0
      src/main/java/edu/math/diagnosis/dao/UserRepo.java
  67. 94 0
      src/main/java/edu/math/diagnosis/entity/AbilityScore.java
  68. 39 0
      src/main/java/edu/math/diagnosis/entity/Authority.java
  69. 41 0
      src/main/java/edu/math/diagnosis/entity/BaseMatter.java
  70. 68 0
      src/main/java/edu/math/diagnosis/entity/CommentAfterExam.java
  71. 87 0
      src/main/java/edu/math/diagnosis/entity/Commit.java
  72. 60 0
      src/main/java/edu/math/diagnosis/entity/CommonMatter.java
  73. 96 0
      src/main/java/edu/math/diagnosis/entity/DiagnosisReport.java
  74. 114 0
      src/main/java/edu/math/diagnosis/entity/KnowledgeMatter.java
  75. 50 0
      src/main/java/edu/math/diagnosis/entity/MistakeMatter.java
  76. 277 0
      src/main/java/edu/math/diagnosis/entity/Paper.java
  77. 144 0
      src/main/java/edu/math/diagnosis/entity/PaperCommit.java
  78. 162 0
      src/main/java/edu/math/diagnosis/entity/PaperResult.java
  79. 194 0
      src/main/java/edu/math/diagnosis/entity/PaperTemplate.java
  80. 76 0
      src/main/java/edu/math/diagnosis/entity/PaperType.java
  81. 289 0
      src/main/java/edu/math/diagnosis/entity/Question.java
  82. 106 0
      src/main/java/edu/math/diagnosis/entity/QuestionOption.java
  83. 76 0
      src/main/java/edu/math/diagnosis/entity/QuestionType.java
  84. 79 0
      src/main/java/edu/math/diagnosis/entity/RemarkTemplate.java
  85. 76 0
      src/main/java/edu/math/diagnosis/entity/Role.java
  86. 4 0
      src/main/java/edu/math/diagnosis/entity/ScoreSegment.java
  87. 129 0
      src/main/java/edu/math/diagnosis/entity/Section.java
  88. 76 0
      src/main/java/edu/math/diagnosis/entity/Subject.java
  89. 95 0
      src/main/java/edu/math/diagnosis/entity/SubjectAbility.java
  90. 4 0
      src/main/java/edu/math/diagnosis/entity/SubjectKnowledge.java
  91. 96 0
      src/main/java/edu/math/diagnosis/entity/SubjectLabel.java
  92. 196 0
      src/main/java/edu/math/diagnosis/entity/UserInfo.java
  93. 88 0
      src/main/java/edu/math/diagnosis/model/AuthUser.java
  94. 42 0
      src/main/java/edu/math/diagnosis/model/GeneralInfo.java
  95. 86 0
      src/main/java/edu/math/diagnosis/model/PaperVo.java
  96. 65 0
      src/main/java/edu/math/diagnosis/model/QuestionDetail.java
  97. 87 0
      src/main/java/edu/math/diagnosis/model/Report.java
  98. 30 0
      src/main/java/edu/math/diagnosis/model/ResponseMessage.java
  99. 82 0
      src/main/java/edu/math/diagnosis/model/Result.java
  100. 138 0
      src/main/java/edu/math/diagnosis/model/UserVo.java

+ 22 - 22
.gitignore

@@ -1,25 +1,25 @@
-# ---> Maven
-target/
-pom.xml.tag
-pom.xml.releaseBackup
-pom.xml.versionsBackup
-pom.xml.next
-release.properties
-dependency-reduced-pom.xml
-buildNumber.properties
-.mvn/timing.properties
+/target/
+!.mvn/wrapper/maven-wrapper.jar
 
-# ---> Java
-*.class
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
 
-# Mobile Tools for Java (J2ME)
-.mtj.tmp/
-
-# Package Files #
-*.jar
-*.war
-*.ear
-
-# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
-hs_err_pid*
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
 
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+/build/

+ 12 - 0
Jenkins.txt

@@ -0,0 +1,12 @@
+pwd
+#export BUILD_ID=dontKillMe
+#ps axu | grep diagnosis808 | awk '{print $2}' |xargs kill
+#cp /opt/diagnosis/8080/diagnosis8080.jar /opt/diagnosis/8080/diagnosis8080.jar.bak
+#cp $WORKSPACE/target/diagnosis.jar /home/jenkins/diagnosis.jar
+
+#/opt/diagnosis/8080/starh.sh &
+#cp /opt/diagnosis/8081/diagnosis8081.jar /opt/diagnosis/8081/diagnosis8081.jar.bak
+#cp $WORKSPACE/target/diagnosis.jar /home/jenkins/diagnosis8081.jar
+#/opt/diagnosis/8081/starh.sh &
+
+docker run -itd --name=gogs -p10080:3000 -v gogs-data:/data gogs/gogs

+ 0 - 72
LICENSE

@@ -1,72 +0,0 @@
-Apache License 
-Version 2.0, January 2004 
-http://www.apache.org/licenses/
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
-
-"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
-
-"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
-
-"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
-
-"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
-
-"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
-
-"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
-
-"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
-
-"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
-
-"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
-
-(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
-
-(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
-
-(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
-
-(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
-
-You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
-To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License"); 
-you may not use this file except in compliance with the License. 
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software 
-distributed under the License is distributed on an "AS IS" BASIS, 
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-See the License for the specific language governing permissions and 
-limitations under the License.

+ 2068 - 0
OMML2MML.XSL

@@ -0,0 +1,2068 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mml="http://www.w3.org/1998/Math/MathML"
+	xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math">
+  <xsl:output method="xml" encoding="UTF-16" />
+
+  <!-- %% Global Definitions -->
+
+  <!-- Every single unicode character that is recognized by OMML as an operator -->
+  <xsl:variable name="sOperators"
+		select="concat(
+          '&#x00A8;&#x0021;&#x0022;&#x0023;&#x0026;&#x0028;&#x0029;&#x002B;&#x002C;&#x002D;&#x002E;&#x002F;&#x003A;',
+          '&#x003B;&#x003C;&#x003D;&#x003E;&#x003F;&#x0040;&#x005B;&#x005C;&#x005D;&#x005E;&#x005F;&#x0060;&#x007B;',
+          '&#x007C;&#x007D;&#x007E;&#x00A1;&#x00A6;&#x00AC;&#x00AF;&#x00B0;&#x00B1;&#x00B2;&#x00B3;&#x00B4;&#x00B7;&#x00B9;&#x00BF;',
+          '&#x00D7;&#x007E;&#x00F7;&#x02C7;&#x02D8;&#x02D9;&#x02DC;&#x02DD;&#x0300;&#x0301;&#x0302;&#x0303;&#x0304;&#x0305;&#x0306;&#x0307;&#x0308;&#x0309;',
+          '&#x030A;&#x030B;&#x030C;&#x030D;&#x030E;&#x030F;&#x0310;&#x0311;&#x0312;&#x0313;&#x0314;&#x0315;',
+          '&#x0316;&#x0317;&#x0318;&#x0319;&#x031A;&#x031B;&#x031C;&#x031D;&#x031E;&#x031F;&#x0320;&#x0321;',
+          '&#x0322;&#x0323;&#x0324;&#x0325;&#x0326;&#x0327;&#x0328;&#x0329;&#x032A;&#x032B;&#x032C;&#x032D;',
+          '&#x032E;&#x032F;&#x0330;&#x0331;&#x0332;&#x0333;&#x0334;&#x0335;&#x0336;&#x0337;&#x0338;&#x033F;',
+          '&#x2000;&#x2001;&#x2002;&#x2003;&#x2004;&#x2005;&#x2006;&#x2009;&#x200A;&#x2010;&#x2012;&#x2013;',
+          '&#x2014;&#x2016;&#x2020;&#x2021;&#x2022;&#x2024;&#x2025;&#x2026;&#x2032;&#x2033;&#x2034;&#x203C;',
+          '&#x2040;&#x2044;&#x204E;&#x204F;&#x2050;&#x2057;&#x2061;&#x2062;&#x2063;&#x2070;&#x2074;&#x2075;',
+          '&#x2076;&#x2077;&#x2078;&#x2079;&#x207A;&#x207B;&#x207C;&#x207D;&#x207E;&#x2080;&#x2081;&#x2082;',
+          '&#x2083;&#x2084;&#x2085;&#x2086;&#x2087;&#x2088;&#x2089;&#x208A;&#x208B;&#x208C;&#x208D;&#x208E;',
+          '&#x20D0;&#x20D1;&#x20D2;&#x20D3;&#x20D4;&#x20D5;&#x20D6;&#x20D7;&#x20D8;&#x20D9;&#x20DA;&#x20DB;',
+          '&#x20DC;&#x20DD;&#x20DE;&#x20DF;&#x20E0;&#x20E1;&#x20E4;&#x20E5;&#x20E6;&#x20E7;&#x20E8;&#x20E9;',
+          '&#x20EA;&#x2140;&#x2146;&#x2190;&#x2191;&#x2192;&#x2193;&#x2194;&#x2195;&#x2196;&#x2197;&#x2198;&#x2199;',
+          '&#x219A;&#x219B;&#x219C;&#x219D;&#x219E;&#x219F;&#x21A0;&#x21A1;&#x21A2;&#x21A3;&#x21A4;&#x21A5;',
+          '&#x21A6;&#x21A7;&#x21A8;&#x21A9;&#x21AA;&#x21AB;&#x21AC;&#x21AD;&#x21AE;&#x21AF;&#x21B0;&#x21B1;',
+          '&#x21B2;&#x21B3;&#x21B6;&#x21B7;&#x21BA;&#x21BB;&#x21BC;&#x21BD;&#x21BE;&#x21BF;&#x21C0;&#x21C1;',
+          '&#x21C2;&#x21C3;&#x21C4;&#x21C5;&#x21C6;&#x21C7;&#x21C8;&#x21C9;&#x21CA;&#x21CB;&#x21CC;&#x21CD;',
+          '&#x21CE;&#x21CF;&#x21D0;&#x21D1;&#x21D2;&#x21D3;&#x21D4;&#x21D5;&#x21D6;&#x21D7;&#x21D8;&#x21D9;',
+          '&#x21DA;&#x21DB;&#x21DC;&#x21DD;&#x21DE;&#x21DF;&#x21E0;&#x21E1;&#x21E2;&#x21E3;&#x21E4;&#x21E5;',
+          '&#x21E6;&#x21E7;&#x21E8;&#x21E9;&#x21F3;&#x21F4;&#x21F5;&#x21F6;&#x21F7;&#x21F8;&#x21F9;&#x21FA;',
+          '&#x21FB;&#x21FC;&#x21FD;&#x21FE;&#x21FF;&#x2200;&#x2201;&#x2202;&#x2203;&#x2204;&#x2206;&#x2207;',
+          '&#x2208;&#x2209;&#x220A;&#x220B;&#x220C;&#x220D;&#x220F;&#x2210;&#x2211;&#x2212;&#x2213;&#x2214;',
+          '&#x2215;&#x2216;&#x2217;&#x2218;&#x2219;&#x221A;&#x221B;&#x221C;&#x221D;&#x2223;&#x2224;&#x2225;',
+          '&#x2226;&#x2227;&#x2228;&#x2229;&#x222A;&#x222B;&#x222C;&#x222D;&#x222E;&#x222F;&#x2230;&#x2231;',
+          '&#x2232;&#x2233;&#x2234;&#x2235;&#x2236;&#x2237;&#x2238;&#x2239;&#x223A;&#x223B;&#x223C;&#x223D;',
+          '&#x223E;&#x2240;&#x2241;&#x2242;&#x2243;&#x2244;&#x2245;&#x2246;&#x2247;&#x2248;&#x2249;&#x224A;',
+          '&#x224B;&#x224C;&#x224D;&#x224E;&#x224F;&#x2250;&#x2251;&#x2252;&#x2253;&#x2254;&#x2255;&#x2256;',
+          '&#x2257;&#x2258;&#x2259;&#x225A;&#x225B;&#x225C;&#x225D;&#x225E;&#x225F;&#x2260;&#x2261;&#x2262;',
+          '&#x2263;&#x2264;&#x2265;&#x2266;&#x2267;&#x2268;&#x2269;&#x226A;&#x226B;&#x226C;&#x226D;&#x226E;',
+          '&#x226F;&#x2270;&#x2271;&#x2272;&#x2273;&#x2274;&#x2275;&#x2276;&#x2277;&#x2278;&#x2279;&#x227A;',
+          '&#x227B;&#x227C;&#x227D;&#x227E;&#x227F;&#x2280;&#x2281;&#x2282;&#x2283;&#x2284;&#x2285;&#x2286;',
+          '&#x2287;&#x2288;&#x2289;&#x228A;&#x228B;&#x228C;&#x228D;&#x228E;&#x228F;&#x2290;&#x2291;&#x2292;',
+          '&#x2293;&#x2294;&#x2295;&#x2296;&#x2297;&#x2298;&#x2299;&#x229A;&#x229B;&#x229C;&#x229D;&#x229E;',
+          '&#x229F;&#x22A0;&#x22A1;&#x22A2;&#x22A3;&#x22A5;&#x22A6;&#x22A7;&#x22A8;&#x22A9;&#x22AA;&#x22AB;',
+          '&#x22AC;&#x22AD;&#x22AE;&#x22AF;&#x22B0;&#x22B1;&#x22B2;&#x22B3;&#x22B4;&#x22B5;&#x22B6;&#x22B7;',
+          '&#x22B8;&#x22B9;&#x22BA;&#x22BB;&#x22BC;&#x22BD;&#x22C0;&#x22C1;&#x22C2;&#x22C3;&#x22C4;&#x22C5;',
+          '&#x22C6;&#x22C7;&#x22C8;&#x22C9;&#x22CA;&#x22CB;&#x22CC;&#x22CD;&#x22CE;&#x22CF;&#x22D0;&#x22D1;',
+          '&#x22D2;&#x22D3;&#x22D4;&#x22D5;&#x22D6;&#x22D7;&#x22D8;&#x22D9;&#x22DA;&#x22DB;&#x22DC;&#x22DD;',
+          '&#x22DE;&#x22DF;&#x22E0;&#x22E1;&#x22E2;&#x22E3;&#x22E4;&#x22E5;&#x22E6;&#x22E7;&#x22E8;&#x22E9;',
+          '&#x22EA;&#x22EB;&#x22EC;&#x22ED;&#x22EE;&#x22EF;&#x22F0;&#x22F1;&#x22F2;&#x22F3;&#x22F4;&#x22F5;',
+          '&#x22F6;&#x22F7;&#x22F8;&#x22F9;&#x22FA;&#x22FB;&#x22FC;&#x22FD;&#x22FE;&#x22FF;&#x2305;&#x2306;',
+          '&#x2308;&#x2309;&#x230A;&#x230B;&#x231C;&#x231D;&#x231E;&#x231F;&#x2322;&#x2323;&#x2329;&#x232A;',
+          '&#x233D;&#x233F;&#x23B0;&#x23B1;&#x23DC;&#x23DD;&#x23DE;&#x23DF;&#x23E0;&#x2502;&#x251C;&#x2524;',
+          '&#x252C;&#x2534;&#x2581;&#x2588;&#x2592;&#x25A0;&#x25A1;&#x25AD;&#x25B2;&#x25B3;&#x25B4;&#x25B5;',
+          '&#x25B6;&#x25B7;&#x25B8;&#x25B9;&#x25BC;&#x25BD;&#x25BE;&#x25BF;&#x25C0;&#x25C1;&#x25C2;&#x25C3;',
+          '&#x25C4;&#x25C5;&#x25CA;&#x25CB;&#x25E6;&#x25EB;&#x25EC;&#x25F8;&#x25F9;&#x25FA;&#x25FB;&#x25FC;',
+          '&#x25FD;&#x25FE;&#x25FF;&#x2605;&#x2606;&#x2772;&#x2773;&#x27D1;&#x27D2;&#x27D3;&#x27D4;&#x27D5;',
+          '&#x27D6;&#x27D7;&#x27D8;&#x27D9;&#x27DA;&#x27DB;&#x27DC;&#x27DD;&#x27DE;&#x27DF;&#x27E0;&#x27E1;',
+          '&#x27E2;&#x27E3;&#x27E4;&#x27E5;&#x27E6;&#x27E7;&#x27E8;&#x27E9;&#x27EA;&#x27EB;&#x27F0;&#x27F1;',
+          '&#x27F2;&#x27F3;&#x27F4;&#x27F5;&#x27F6;&#x27F7;&#x27F8;&#x27F9;&#x27FA;&#x27FB;&#x27FC;&#x27FD;',
+          '&#x27FE;&#x27FF;&#x2900;&#x2901;&#x2902;&#x2903;&#x2904;&#x2905;&#x2906;&#x2907;&#x2908;&#x2909;',
+          '&#x290A;&#x290B;&#x290C;&#x290D;&#x290E;&#x290F;&#x2910;&#x2911;&#x2912;&#x2913;&#x2914;&#x2915;',
+          '&#x2916;&#x2917;&#x2918;&#x2919;&#x291A;&#x291B;&#x291C;&#x291D;&#x291E;&#x291F;&#x2920;&#x2921;',
+          '&#x2922;&#x2923;&#x2924;&#x2925;&#x2926;&#x2927;&#x2928;&#x2929;&#x292A;&#x292B;&#x292C;&#x292D;',
+          '&#x292E;&#x292F;&#x2930;&#x2931;&#x2932;&#x2933;&#x2934;&#x2935;&#x2936;&#x2937;&#x2938;&#x2939;',
+          '&#x293A;&#x293B;&#x293C;&#x293D;&#x293E;&#x293F;&#x2940;&#x2941;&#x2942;&#x2943;&#x2944;&#x2945;',
+          '&#x2946;&#x2947;&#x2948;&#x2949;&#x294A;&#x294B;&#x294C;&#x294D;&#x294E;&#x294F;&#x2950;&#x2951;',
+          '&#x2952;&#x2953;&#x2954;&#x2955;&#x2956;&#x2957;&#x2958;&#x2959;&#x295A;&#x295B;&#x295C;&#x295D;',
+          '&#x295E;&#x295F;&#x2960;&#x2961;&#x2962;&#x2963;&#x2964;&#x2965;&#x2966;&#x2967;&#x2968;&#x2969;',
+          '&#x296A;&#x296B;&#x296C;&#x296D;&#x296E;&#x296F;&#x2970;&#x2971;&#x2972;&#x2973;&#x2974;&#x2975;',
+          '&#x2976;&#x2977;&#x2978;&#x2979;&#x297A;&#x297B;&#x297C;&#x297D;&#x297E;&#x297F;&#x2980;&#x2982;',
+          '&#x2983;&#x2984;&#x2985;&#x2986;&#x2987;&#x2988;&#x2989;&#x298A;&#x298B;&#x298C;&#x298D;&#x298E;',
+          '&#x298F;&#x2990;&#x2991;&#x2992;&#x2993;&#x2994;&#x2995;&#x2996;&#x2997;&#x2998;&#x2999;&#x299A;',
+          '&#x29B6;&#x29B7;&#x29B8;&#x29B9;&#x29C0;&#x29C1;&#x29C4;&#x29C5;&#x29C6;&#x29C7;&#x29C8;&#x29CE;',
+          '&#x29CF;&#x29D0;&#x29D1;&#x29D2;&#x29D3;&#x29D4;&#x29D5;&#x29D6;&#x29D7;&#x29D8;&#x29D9;&#x29DA;',
+          '&#x29DB;&#x29DF;&#x29E1;&#x29E2;&#x29E3;&#x29E4;&#x29E5;&#x29E6;&#x29EB;&#x29F4;&#x29F5;&#x29F6;',
+          '&#x29F7;&#x29F8;&#x29F9;&#x29FA;&#x29FB;&#x29FC;&#x29FD;&#x29FE;&#x29FF;&#x2A00;&#x2A01;&#x2A02;',
+          '&#x2A03;&#x2A04;&#x2A05;&#x2A06;&#x2A07;&#x2A08;&#x2A09;&#x2A0A;&#x2A0B;&#x2A0C;&#x2A0D;&#x2A0E;',
+          '&#x2A0F;&#x2A10;&#x2A11;&#x2A12;&#x2A13;&#x2A14;&#x2A15;&#x2A16;&#x2A17;&#x2A18;&#x2A19;&#x2A1A;',
+          '&#x2A1B;&#x2A1C;&#x2A1D;&#x2A1E;&#x2A1F;&#x2A20;&#x2A21;&#x2A22;&#x2A23;&#x2A24;&#x2A25;&#x2A26;',
+          '&#x2A27;&#x2A28;&#x2A29;&#x2A2A;&#x2A2B;&#x2A2C;&#x2A2D;&#x2A2E;&#x2A2F;&#x2A30;&#x2A31;&#x2A32;',
+          '&#x2A33;&#x2A34;&#x2A35;&#x2A36;&#x2A37;&#x2A38;&#x2A39;&#x2A3A;&#x2A3B;&#x2A3C;&#x2A3D;&#x2A3E;',
+          '&#x2A3F;&#x2A40;&#x2A41;&#x2A42;&#x2A43;&#x2A44;&#x2A45;&#x2A46;&#x2A47;&#x2A48;&#x2A49;&#x2A4A;',
+          '&#x2A4B;&#x2A4C;&#x2A4D;&#x2A4E;&#x2A4F;&#x2A50;&#x2A51;&#x2A52;&#x2A53;&#x2A54;&#x2A55;&#x2A56;',
+          '&#x2A57;&#x2A58;&#x2A59;&#x2A5A;&#x2A5B;&#x2A5C;&#x2A5D;&#x2A5E;&#x2A5F;&#x2A60;&#x2A61;&#x2A62;',
+          '&#x2A63;&#x2A64;&#x2A65;&#x2A66;&#x2A67;&#x2A68;&#x2A69;&#x2A6A;&#x2A6B;&#x2A6C;&#x2A6D;&#x2A6E;',
+          '&#x2A6F;&#x2A70;&#x2A71;&#x2A72;&#x2A73;&#x2A74;&#x2A75;&#x2A76;&#x2A77;&#x2A78;&#x2A79;&#x2A7A;',
+          '&#x2A7B;&#x2A7C;&#x2A7D;&#x2A7E;&#x2A7F;&#x2A80;&#x2A81;&#x2A82;&#x2A83;&#x2A84;&#x2A85;&#x2A86;',
+          '&#x2A87;&#x2A88;&#x2A89;&#x2A8A;&#x2A8B;&#x2A8C;&#x2A8D;&#x2A8E;&#x2A8F;&#x2A90;&#x2A91;&#x2A92;',
+          '&#x2A93;&#x2A94;&#x2A95;&#x2A96;&#x2A97;&#x2A98;&#x2A99;&#x2A9A;&#x2A9B;&#x2A9C;&#x2A9D;&#x2A9E;',
+          '&#x2A9F;&#x2AA0;&#x2AA1;&#x2AA2;&#x2AA3;&#x2AA4;&#x2AA5;&#x2AA6;&#x2AA7;&#x2AA8;&#x2AA9;&#x2AAA;',
+          '&#x2AAB;&#x2AAC;&#x2AAD;&#x2AAE;&#x2AAF;&#x2AB0;&#x2AB1;&#x2AB2;&#x2AB3;&#x2AB4;&#x2AB5;&#x2AB6;',
+          '&#x2AB7;&#x2AB8;&#x2AB9;&#x2ABA;&#x2ABB;&#x2ABC;&#x2ABD;&#x2ABE;&#x2ABF;&#x2AC0;&#x2AC1;&#x2AC2;',
+          '&#x2AC3;&#x2AC4;&#x2AC5;&#x2AC6;&#x2AC7;&#x2AC8;&#x2AC9;&#x2ACA;&#x2ACB;&#x2ACC;&#x2ACD;&#x2ACE;',
+          '&#x2ACF;&#x2AD0;&#x2AD1;&#x2AD2;&#x2AD3;&#x2AD4;&#x2AD5;&#x2AD6;&#x2AD7;&#x2AD8;&#x2AD9;&#x2ADA;',
+          '&#x2ADB;&#x2ADC;&#x2ADD;&#x2ADE;&#x2ADF;&#x2AE0;&#x2AE2;&#x2AE3;&#x2AE4;&#x2AE5;&#x2AE6;&#x2AE7;',
+          '&#x2AE8;&#x2AE9;&#x2AEA;&#x2AEB;&#x2AEC;&#x2AED;&#x2AEE;&#x2AEF;&#x2AF0;&#x2AF2;&#x2AF3;&#x2AF4;',
+          '&#x2AF5;&#x2AF6;&#x2AF7;&#x2AF8;&#x2AF9;&#x2AFA;&#x2AFB;&#x2AFC;&#x2AFD;&#x2AFE;&#x2AFF;&#x2B04;',
+          '&#x2B06;&#x2B07;&#x2B0C;&#x2B0D;&#x3014;&#x3015;&#x3016;&#x3017;&#x3018;&#x3019;&#xFF01;&#xFF06;',
+          '&#xFF08;&#xFF09;&#xFF0B;&#xFF0C;&#xFF0D;&#xFF0E;&#xFF0F;&#xFF1A;&#xFF1B;&#xFF1C;&#xFF1D;&#xFF1E;',
+          '&#xFF1F;&#xFF20;&#xFF3B;&#xFF3C;&#xFF3D;&#xFF3E;&#xFF3F;&#xFF5B;&#xFF5C;&#xFF5D;')" />
+
+  <!-- A string of '-'s repeated exactly as many times as the operators above -->
+  <xsl:variable name="sMinuses">
+    <xsl:call-template name="SRepeatChar">
+      <xsl:with-param name="cchRequired" select="string-length($sOperators)" />
+      <xsl:with-param name="ch" select="'-'" />
+    </xsl:call-template>
+  </xsl:variable>
+
+  <!-- Every single unicode character that is recognized by OMML as a number -->
+  <xsl:variable name="sNumbers" select="'0123456789'" />
+
+  <!-- A string of '0's repeated exactly as many times as the list of numbers above -->
+  <xsl:variable name="sZeros">
+    <xsl:call-template name="SRepeatChar">
+      <xsl:with-param name="cchRequired" select="string-length($sNumbers)" />
+      <xsl:with-param name="ch" select="'0'" />
+    </xsl:call-template>
+  </xsl:variable>
+
+  <!-- %%Template: SReplace
+
+		Replace all occurences of sOrig in sInput with sReplacement
+		and return the resulting string. -->
+  <xsl:template name="SReplace">
+    <xsl:param name="sInput" />
+    <xsl:param name="sOrig" />
+    <xsl:param name="sReplacement" />
+
+    <xsl:choose>
+      <xsl:when test="not(contains($sInput, $sOrig))">
+        <xsl:value-of select="$sInput" />
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:variable name="sBefore" select="substring-before($sInput, $sOrig)" />
+        <xsl:variable name="sAfter" select="substring-after($sInput, $sOrig)" />
+        <xsl:variable name="sAfterProcessed">
+          <xsl:call-template name="SReplace">
+            <xsl:with-param name="sInput" select="$sAfter" />
+            <xsl:with-param name="sOrig" select="$sOrig" />
+            <xsl:with-param name="sReplacement" select="$sReplacement" />
+          </xsl:call-template>
+        </xsl:variable>
+
+        <xsl:value-of select="concat($sBefore, concat($sReplacement, $sAfterProcessed))" />
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!-- Templates -->
+  <xsl:template match="/">
+    <mml:math>
+      <xsl:apply-templates select="*" />
+    </mml:math>
+  </xsl:template>
+
+  <xsl:template match="m:borderBox">
+
+    <!-- Get Lowercase versions of properties -->
+    <xsl:variable name="sLowerCaseHideTop" select="translate(m:borderBoxPr[last()]/m:hideTop[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                             'abcdefghijklmnopqrstuvwxyz')" />
+    <xsl:variable name="sLowerCaseHideBot" select="translate(m:borderBoxPr[last()]/m:hideBot[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                             'abcdefghijklmnopqrstuvwxyz')" />
+    <xsl:variable name="sLowerCaseHideLeft" select="translate(m:borderBoxPr[last()]/m:hideLeft[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                             'abcdefghijklmnopqrstuvwxyz')" />
+    <xsl:variable name="sLowerCaseHideRight" select="translate(m:borderBoxPr[last()]/m:hideRight[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                             'abcdefghijklmnopqrstuvwxyz')" />
+    <xsl:variable name="sLowerCaseStrikeH" select="translate(m:borderBoxPr[last()]/m:strikeH[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                             'abcdefghijklmnopqrstuvwxyz')" />
+    <xsl:variable name="sLowerCaseStrikeV" select="translate(m:borderBoxPr[last()]/m:strikeV[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                             'abcdefghijklmnopqrstuvwxyz')" />
+    <xsl:variable name="sLowerCaseStrikeBLTR" select="translate(m:borderBoxPr[last()]/m:strikeBLTR[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                             'abcdefghijklmnopqrstuvwxyz')" />
+    <xsl:variable name="sLowerCaseStrikeTLBR" select="translate(m:borderBoxPr[last()]/m:strikeTLBR[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                             'abcdefghijklmnopqrstuvwxyz')" />
+    <xsl:variable name="fHideTop">
+      <xsl:call-template name="ForceTrueStrVal">
+        <xsl:with-param name="str" select="$sLowerCaseHideTop" />
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:variable name="fHideBot">
+      <xsl:call-template name="ForceTrueStrVal">
+        <xsl:with-param name="str" select="$sLowerCaseHideBot" />
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:variable name="fHideLeft">
+      <xsl:call-template name="ForceTrueStrVal">
+        <xsl:with-param name="str" select="$sLowerCaseHideLeft" />
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:variable name="fHideRight">
+      <xsl:call-template name="ForceTrueStrVal">
+        <xsl:with-param name="str" select="$sLowerCaseHideRight" />
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:variable name="fStrikeH">
+      <xsl:call-template name="ForceTrueStrVal">
+        <xsl:with-param name="str" select="$sLowerCaseStrikeH" />
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:variable name="fStrikeV">
+      <xsl:call-template name="ForceTrueStrVal">
+        <xsl:with-param name="str" select="$sLowerCaseStrikeV" />
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:variable name="fStrikeBLTR">
+      <xsl:call-template name="ForceTrueStrVal">
+        <xsl:with-param name="str" select="$sLowerCaseStrikeBLTR" />
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:variable name="fStrikeTLBR">
+      <xsl:call-template name="ForceTrueStrVal">
+        <xsl:with-param name="str" select="$sLowerCaseStrikeTLBR" />
+      </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:choose>
+      <xsl:when test="$fHideTop=1 
+                      and $fHideBot=1 
+                      and $fHideLeft=1 
+                      and $fHideRight=1 
+                      and $fStrikeH=0 
+                      and $fStrikeV=0 
+                      and $fStrikeBLTR=0 
+                      and $fStrikeTLBR=0">
+        <mml:mrow>
+          <xsl:apply-templates select="m:e[1]" />
+        </mml:mrow>
+      </xsl:when>
+      <xsl:otherwise>
+        <mml:menclose>
+          <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+            <xsl:with-param name="fHideTop" select="$fHideTop" />
+            <xsl:with-param name="fHideBot" select="$fHideBot" />
+            <xsl:with-param name="fHideLeft" select="$fHideLeft" />
+            <xsl:with-param name="fHideRight" select="$fHideRight" />
+            <xsl:with-param name="fStrikeH" select="$fStrikeH" />
+            <xsl:with-param name="fStrikeV" select="$fStrikeV" />
+            <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+            <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+          </xsl:call-template>
+          <xsl:apply-templates select="m:e[1]" />
+        </mml:menclose>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="*">
+    <xsl:apply-templates select="*" />
+  </xsl:template>
+
+  <!--
+      { Non-combining, Upper-combining, Lower-combining }
+      {U+02D8, U+0306, U+032E}, // BREVE
+      {U+00B8, U+0312, U+0327}, // CEDILLA
+      {U+0060, U+0300, U+0316}, // GRAVE ACCENT
+      {U+002D, U+0305, U+0332}, // HYPHEN-MINUS/OVERLINE
+      {U+2212, U+0305, U+0332}, // MINUS SIGN/OVERLINE
+      {U+002E, U+0305, U+0323}, // FULL STOP/DOT ABOVE
+      {U+02D9, U+0307, U+0323}, // DOT ABOVE
+      {U+02DD, U+030B, U+02DD}, // DOUBLE ACUTE ACCENT
+      {U+00B4, U+0301, U+0317}, // ACUTE ACCENT
+      {U+007E, U+0303, U+0330}, // TILDE
+      {U+02DC, U+0303, U+0330}, // SMALL TILDE
+      {U+00A8, U+0308, U+0324}, // DIAERESIS
+      {U+02C7, U+030C, U+032C}, // CARON
+      {U+005E, U+0302, U+032D}, // CIRCUMFLEX ACCENT
+      {U+00AF, U+0305, ::::::}, // MACRON
+      {U+005F, ::::::, U+0332}, // LOW LINE
+      {U+2192, U+20D7, U+20EF}, // RIGHTWARDS ARROW
+      {U+27F6, U+20D7, U+20EF}, // LONG RIGHTWARDS ARROW
+      {U+2190, U+20D6, U+20EE}, // LEFT ARROW
+  -->
+  <xsl:template name="ToNonCombining">
+    <xsl:param name="ch" />
+    <xsl:choose>
+      <!-- BREVE -->
+      <xsl:when test="$ch='&#x0306;' or $ch='&#x032e;'">&#x02D8;</xsl:when>
+      <!-- CEDILLA -->
+      <xsl:when test="$ch='&#x0312;' or $ch='&#x0327;'">&#x00B8;</xsl:when>
+      <!-- GRAVE ACCENT -->
+      <xsl:when test="$ch='&#x0300;' or $ch='&#x0316;'">&#x0060;</xsl:when>
+      <!-- HYPHEN-MINUS/OVERLINE -->
+      <xsl:when test="$ch='&#x0305;' or $ch='&#x0332;'">&#x002D;</xsl:when>
+      <!-- MINUS SIGN/OVERLINE -->
+      <xsl:when test="$ch='&#x0305;' or $ch='&#x0332;'">&#x2212;</xsl:when>
+      <!-- FULL STOP/DOT ABOVE -->
+      <xsl:when test="$ch='&#x0305;' or $ch='&#x0323;'">&#x002E;</xsl:when>
+      <!-- DOT ABOVE -->
+      <xsl:when test="$ch='&#x0307;' or $ch='&#x0323;'">&#x02D9;</xsl:when>
+      <!-- DOUBLE ACUTE ACCENT -->
+      <xsl:when test="$ch='&#x030B;' or $ch='&#x02DD;'">&#x02DD;</xsl:when>
+      <!-- ACUTE ACCENT -->
+      <xsl:when test="$ch='&#x0301;' or $ch='&#x0317;'">&#x00B4;</xsl:when>
+      <!-- TILDE -->
+      <xsl:when test="$ch='&#x0303;' or $ch='&#x0330;'">&#x007E;</xsl:when>
+      <!-- SMALL TILDE -->
+      <xsl:when test="$ch='&#x0303;' or $ch='&#x0330;'">&#x02DC;</xsl:when>
+      <!-- DIAERESIS -->
+      <xsl:when test="$ch='&#x0308;' or $ch='&#x0324;'">&#x00A8;</xsl:when>
+      <!-- CARON -->
+      <xsl:when test="$ch='&#x030C;' or $ch='&#x032C;'">&#x02C7;</xsl:when>
+      <!-- CIRCUMFLEX ACCENT -->
+      <xsl:when test="$ch='&#x0302;' or $ch='&#x032D;'">&#x005E;</xsl:when>
+      <!-- MACRON -->
+      <xsl:when test="$ch='&#x0305;'                   ">&#x00AF;</xsl:when>
+      <!-- LOW LINE -->
+      <xsl:when test="                   $ch='&#x0332;'">&#x005F;</xsl:when>
+      <!-- RIGHTWARDS ARROW -->
+      <xsl:when test="$ch='&#x20D7;' or $ch='&#x20EF;'">&#x2192;</xsl:when>
+      <!-- LONG RIGHTWARDS ARROW -->
+      <xsl:when test="$ch='&#x20D7;' or $ch='&#x20EF;'">&#x27F6;</xsl:when>
+      <!-- LEFT ARROW -->
+      <xsl:when test="$ch='&#x20D6;' or $ch='&#x20EE;'">&#x2190;</xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$ch"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="m:acc">
+    <mml:mover>
+      <xsl:attribute name="accent">true</xsl:attribute>
+      <mml:mrow>
+        <xsl:apply-templates select="m:e[1]" />
+      </mml:mrow>
+      <xsl:variable name="chAcc">
+        <xsl:choose>
+          <xsl:when test="not(m:accPr[last()]/m:chr)">
+            <xsl:value-of select="'&#x0302;'" />
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="substring(m:accPr/m:chr/@m:val,1,1)" />
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="chNonComb">
+        <xsl:call-template name="ToNonCombining">
+          <xsl:with-param name="ch" select="$chAcc" />
+        </xsl:call-template>
+      </xsl:variable>
+      <xsl:choose>
+        <xsl:when test="string-length($chAcc)=0">
+          <mml:mo/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="ParseMt">
+            <xsl:with-param name="sToParse" select="$chNonComb" />
+            <xsl:with-param name="scr" select="m:e[1]/*/m:rPr[last()]/m:scr/@m:val" />
+            <xsl:with-param name="sty" select="m:e[1]/*/m:rPr[last()]/m:sty/@m:val" />
+            <xsl:with-param name="nor">
+              <xsl:choose>
+                <xsl:when test="count(m:e[1]/*/m:rPr[last()]/m:nor) = 0">0</xsl:when>
+                <xsl:otherwise>
+                  <xsl:call-template name="ForceFalseStrVal">
+                    <xsl:with-param name="str" select="translate(m:e[1]/*/m:rPr[last()]/m:nor/@m:val, 
+                                                                     'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                                 'abcdefghijklmnopqrstuvwxyz')" />
+                  </xsl:call-template>
+                </xsl:otherwise>
+              </xsl:choose>
+            </xsl:with-param>
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </mml:mover>
+  </xsl:template>
+
+  <xsl:template name="OutputScript">
+    <xsl:param name="ndCur" select="." />
+    <xsl:choose>
+      <!-- Only output contents of $ndCur if $ndCur exists
+           and $ndCur has children -->
+      <xsl:when test="count($ndCur/*) &gt; 0">
+        <mml:mrow>
+          <xsl:apply-templates select="$ndCur" />
+        </mml:mrow>
+      </xsl:when>
+      <xsl:otherwise>
+        <mml:none />
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="m:sPre">
+    <mml:mmultiscripts>
+      <mml:mrow>
+        <xsl:apply-templates select="m:e[1]" />
+      </mml:mrow>
+      <mml:mprescripts />
+      <xsl:call-template name="OutputScript">
+        <xsl:with-param name="ndCur" select="m:sub[1]"/>
+      </xsl:call-template>
+      <xsl:call-template name="OutputScript">
+        <xsl:with-param name="ndCur" select="m:sup[1]" />
+      </xsl:call-template>
+    </mml:mmultiscripts>
+  </xsl:template>
+
+  <xsl:template match="m:m">
+    <mml:mtable>
+      <xsl:call-template name="CreateMathMLMatrixAttr">
+        <xsl:with-param name="mcJc" select="m:mPr[last()]/m:mcs/m:mc/m:mcPr[last()]/m:mcJc/@m:val" />
+      </xsl:call-template>
+      <xsl:for-each select="m:mr">
+        <mml:mtr>
+          <xsl:for-each select="m:e">
+            <mml:mtd>
+              <xsl:apply-templates select="." />
+            </mml:mtd>
+          </xsl:for-each>
+        </mml:mtr>
+      </xsl:for-each>
+    </mml:mtable>
+  </xsl:template>
+
+  <xsl:template name="CreateMathMLMatrixAttr">
+    <xsl:param name="mcJc" />
+    <xsl:variable name="sLowerCaseMcjc" select="translate($mcJc, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                             'abcdefghijklmnopqrstuvwxyz')" />
+    <xsl:choose>
+      <xsl:when test="$sLowerCaseMcjc='left'">
+        <xsl:attribute name="columnalign">left</xsl:attribute>
+      </xsl:when>
+      <xsl:when test="$sLowerCaseMcjc='right'">
+        <xsl:attribute name="columnalign">right</xsl:attribute>
+      </xsl:when>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="m:phant">
+    <xsl:variable name="sLowerCaseZeroWidVal" select="translate(m:phantPr[last()]/m:zeroWid[last()]/@m:val, 
+		                                                       'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                       'abcdefghijklmnopqrstuvwxyz')" />
+    <xsl:variable name="sLowerCaseZeroAscVal" select="translate(m:phantPr[last()]/m:zeroAsc[last()]/@m:val, 
+		                                                     'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                     'abcdefghijklmnopqrstuvwxyz')" />
+    <xsl:variable name="sLowerCaseZeroDescVal" select="translate(m:phantPr[last()]/m:zeroDesc[last()]/@m:val, 
+		                                                     'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                     'abcdefghijklmnopqrstuvwxyz')" />
+    <xsl:variable name="sLowerCaseShowVal" select="translate(m:phantPr[last()]/m:show[last()]/@m:val, 
+		                                                     'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                     'abcdefghijklmnopqrstuvwxyz')" />
+
+
+    <!-- The following properties default to 'yes' unless the last value equals 'no' or there isn't any node for 
+         the property -->
+
+    <xsl:variable name="fZeroWid">
+      <xsl:choose>
+        <xsl:when test="count(m:phantPr[last()]/m:zeroWid[last()]) = 0">0</xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="ForceFalseStrVal">
+            <xsl:with-param name="str" select="$sLowerCaseZeroWidVal" />
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="fZeroAsc">
+      <xsl:choose>
+        <xsl:when test="count(m:phantPr[last()]/m:zeroAsc[last()]) = 0">0</xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="ForceFalseStrVal">
+            <xsl:with-param name="str" select="$sLowerCaseZeroAscVal" />
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="fZeroDesc">
+      <xsl:choose>
+        <xsl:when test="count(m:phantPr[last()]/m:zeroDesc[last()]) = 0">0</xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="ForceFalseStrVal">
+            <xsl:with-param name="str" select="$sLowerCaseZeroDescVal" />
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <!-- The show property defaults to 'on' unless there exists a show property and its value is 'off' -->
+
+    <xsl:variable name="fShow">
+      <xsl:call-template name="ForceFalseStrVal">
+        <xsl:with-param name="str" select="$sLowerCaseShowVal" />
+      </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:choose>
+      <!-- Show the phantom contents, therefore, just use mpadded. -->
+      <xsl:when test="$fShow = 1">
+        <xsl:element name="mml:mpadded">
+          <xsl:call-template name="CreateMpaddedAttributes">
+            <xsl:with-param name="fZeroWid" select="$fZeroWid" />
+            <xsl:with-param name="fZeroAsc" select="$fZeroAsc" />
+            <xsl:with-param name="fZeroDesc" select="$fZeroDesc" />
+          </xsl:call-template>
+          <mml:mrow>
+            <xsl:apply-templates select="m:e" />
+          </mml:mrow>
+        </xsl:element>
+      </xsl:when>
+      <!-- Don't show phantom contents, but don't smash anything, therefore, just 
+           use mphantom -->
+      <xsl:when test="$fZeroWid=0 and $fZeroAsc=0 and $fZeroDesc=0">
+        <xsl:element name="mml:mphantom">
+          <mml:mrow>
+            <xsl:apply-templates select="m:e" />
+          </mml:mrow>
+        </xsl:element>
+      </xsl:when>
+      <!-- Combination -->
+      <xsl:otherwise>
+        <xsl:element name="mml:mphantom">
+          <xsl:element name="mml:mpadded">
+            <xsl:call-template name="CreateMpaddedAttributes">
+              <xsl:with-param name="fZeroWid" select="$fZeroWid" />
+              <xsl:with-param name="fZeroAsc" select="$fZeroAsc" />
+              <xsl:with-param name="fZeroDesc" select="$fZeroDesc" />
+            </xsl:call-template>
+            <mml:mrow>
+              <xsl:apply-templates select="m:e" />
+            </mml:mrow>
+          </xsl:element>
+        </xsl:element>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template name="CreateMpaddedAttributes">
+    <xsl:param name="fZeroWid" />
+    <xsl:param name="fZeroAsc" />
+    <xsl:param name="fZeroDesc" />
+
+    <xsl:if test="$fZeroWid=1">
+      <xsl:attribute name="width">0in</xsl:attribute>
+    </xsl:if>
+    <xsl:if test="$fZeroAsc=1">
+      <xsl:attribute name="height">0in</xsl:attribute>
+    </xsl:if>
+    <xsl:if test="$fZeroDesc=1">
+      <xsl:attribute name="depth">0in</xsl:attribute>
+    </xsl:if>
+  </xsl:template>
+
+
+
+  <xsl:template match="m:rad">
+    <xsl:variable name="fDegHide">
+      <xsl:choose>
+        <xsl:when test="count(m:radPr[last()]/m:degHide)=0">0</xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="ForceFalseStrVal">
+            <xsl:with-param name="str" select="translate(m:radPr[last()]/m:degHide/@m:val, 
+		                                                          'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                          'abcdefghijklmnopqrstuvwxyz')" />
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:choose>
+      <xsl:when test="$fDegHide=1">
+        <mml:msqrt>
+          <xsl:apply-templates select="m:e[1]" />
+        </mml:msqrt>
+      </xsl:when>
+      <xsl:otherwise>
+        <mml:mroot>
+          <mml:mrow>
+            <xsl:apply-templates select="m:e[1]" />
+          </mml:mrow>
+          <mml:mrow>
+            <xsl:apply-templates select="m:deg[1]" />
+          </mml:mrow>
+        </mml:mroot>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template name="OutputNaryMo">
+    <xsl:param name="ndCur" select="." />
+    <xsl:param name="fGrow" select="0" />
+    <mml:mo>
+      <xsl:choose>
+        <xsl:when test="$fGrow=1">
+          <xsl:attribute name="stretchy">true</xsl:attribute>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:attribute name="stretchy">false</xsl:attribute>
+        </xsl:otherwise>
+      </xsl:choose>
+      <xsl:choose>
+        <xsl:when test="not($ndCur/m:naryPr[last()]/m:chr/@m:val) or
+			                            $ndCur/m:naryPr[last()]/m:chr/@m:val=''">
+          <xsl:text>&#x222b;</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$ndCur/m:naryPr[last()]/m:chr/@m:val" />
+        </xsl:otherwise>
+      </xsl:choose>
+    </mml:mo>
+  </xsl:template>
+
+  <!-- %%Template match m:nary 
+		Process an n-ary. 
+		
+		Decides, based on which arguments are supplied, between
+		using an mo, msup, msub, or msubsup for the n-ary operator		
+	-->
+  <xsl:template match="m:nary">
+    <xsl:variable name="sLowerCaseSubHide">
+      <xsl:choose>
+        <xsl:when test="count(m:naryPr[last()]/m:subHide) = 0">
+          <xsl:text>off</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="translate(m:naryPr[last()]/m:subHide/@m:val, 
+	                                  'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+	                                  'abcdefghijklmnopqrstuvwxyz')" />
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <xsl:variable name="sLowerCaseSupHide">
+      <xsl:choose>
+        <xsl:when test="count(m:naryPr[last()]/m:supHide) = 0">
+          <xsl:text>off</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="translate(m:naryPr[last()]/m:supHide/@m:val, 
+	                                  'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+	                                  'abcdefghijklmnopqrstuvwxyz')" />
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <xsl:variable name="sLowerCaseLimLoc">
+      <xsl:value-of select="translate(m:naryPr[last()]/m:limLoc/@m:val, 
+	                                  'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+	                                  'abcdefghijklmnopqrstuvwxyz')" />
+    </xsl:variable>
+
+    <xsl:variable name="sLowerGrow">
+      <xsl:choose>
+        <xsl:when test="count(m:naryPr[last()]/m:grow)=0">off</xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="translate(m:naryPr[last()]/m:grow/@m:val, 
+	                                  'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+	                                  'abcdefghijklmnopqrstuvwxyz')" />
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <xsl:variable name="fLimLocSubSup">
+      <xsl:choose>
+        <xsl:when test="count(m:naryPr[last()]/m:limLoc)=0 or $sLowerCaseLimLoc='subsup'">1</xsl:when>
+        <xsl:otherwise>0</xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <xsl:variable name="fGrow">
+      <xsl:call-template name="ForceFalseStrVal">
+        <xsl:with-param name="str" select="$sLowerGrow" />
+      </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:variable name="fSupHide">
+      <xsl:call-template name="ForceFalseStrVal">
+        <xsl:with-param name="str" select="$sLowerCaseSupHide" />
+      </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:variable name="fSubHide">
+      <xsl:call-template name="ForceFalseStrVal">
+        <xsl:with-param name="str" select="$sLowerCaseSubHide" />
+      </xsl:call-template>
+    </xsl:variable>
+
+    <mml:mrow>
+      <xsl:choose>
+        <xsl:when test="$fSupHide=1 and $fSubHide=1">
+          <xsl:call-template name="OutputNaryMo">
+            <xsl:with-param name="ndCur" select="." />
+            <xsl:with-param name="fGrow" select="$fGrow" />
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:when test="$fSubHide=1">
+          <xsl:choose>
+            <xsl:when test="$fLimLocSubSup=1">
+              <mml:msup>
+                <xsl:call-template name="OutputNaryMo">
+                  <xsl:with-param name="ndCur" select="." />
+                  <xsl:with-param name="fGrow" select="$fGrow" />
+                </xsl:call-template>
+                <mml:mrow>
+                  <xsl:apply-templates select="m:sup[1]" />
+                </mml:mrow>
+              </mml:msup>
+            </xsl:when>
+            <xsl:otherwise>
+              <mml:mover>
+                <xsl:call-template name="OutputNaryMo">
+                  <xsl:with-param name="ndCur" select="." />
+                  <xsl:with-param name="fGrow" select="$fGrow" />
+                </xsl:call-template>
+                <mml:mrow>
+                  <xsl:apply-templates select="m:sup[1]" />
+                </mml:mrow>
+              </mml:mover>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:when>
+        <xsl:when test="$fSupHide=1">
+          <xsl:choose>
+            <xsl:when test="$fLimLocSubSup=1">
+              <mml:msub>
+                <xsl:call-template name="OutputNaryMo">
+                  <xsl:with-param name="ndCur" select="." />
+                  <xsl:with-param name="fGrow" select="$fGrow" />
+                </xsl:call-template>
+                <mml:mrow>
+                  <xsl:apply-templates select="m:sub[1]" />
+                </mml:mrow>
+              </mml:msub>
+            </xsl:when>
+            <xsl:otherwise>
+              <mml:munder>
+                <xsl:call-template name="OutputNaryMo">
+                  <xsl:with-param name="ndCur" select="." />
+                  <xsl:with-param name="fGrow" select="$fGrow" />
+                </xsl:call-template>
+                <mml:mrow>
+                  <xsl:apply-templates select="m:sub[1]" />
+                </mml:mrow>
+              </mml:munder>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:choose>
+            <xsl:when test="$fLimLocSubSup=1">
+              <mml:msubsup>
+                <xsl:call-template name="OutputNaryMo">
+                  <xsl:with-param name="ndCur" select="." />
+                  <xsl:with-param name="fGrow" select="$fGrow" />
+                </xsl:call-template>
+                <mml:mrow>
+                  <xsl:apply-templates select="m:sub[1]" />
+                </mml:mrow>
+                <mml:mrow>
+                  <xsl:apply-templates select="m:sup[1]" />
+                </mml:mrow>
+              </mml:msubsup>
+            </xsl:when>
+            <xsl:otherwise>
+              <mml:munderover>
+                <xsl:call-template name="OutputNaryMo">
+                  <xsl:with-param name="ndCur" select="." />
+                  <xsl:with-param name="fGrow" select="$fGrow" />
+                </xsl:call-template>
+                <mml:mrow>
+                  <xsl:apply-templates select="m:sub[1]" />
+                </mml:mrow>
+                <mml:mrow>
+                  <xsl:apply-templates select="m:sup[1]" />
+                </mml:mrow>
+              </mml:munderover>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:otherwise>
+      </xsl:choose>
+      <mml:mrow>
+        <xsl:apply-templates select="m:e[1]" />
+      </mml:mrow>
+    </mml:mrow>
+  </xsl:template>
+
+  <xsl:template match="m:limLow">
+    <mml:munder>
+      <mml:mrow>
+        <xsl:apply-templates select="m:e[1]" />
+      </mml:mrow>
+      <mml:mrow>
+        <xsl:apply-templates select="m:lim[1]" />
+      </mml:mrow>
+    </mml:munder>
+  </xsl:template>
+
+  <xsl:template match="m:limUpp">
+    <mml:mover>
+      <mml:mrow>
+        <xsl:apply-templates select="m:e[1]" />
+      </mml:mrow>
+      <mml:mrow>
+        <xsl:apply-templates select="m:lim[1]" />
+      </mml:mrow>
+    </mml:mover>
+  </xsl:template>
+
+  <xsl:template match="m:sSub">
+    <mml:msub>
+      <mml:mrow>
+        <xsl:apply-templates select="m:e[1]" />
+      </mml:mrow>
+      <mml:mrow>
+        <xsl:apply-templates select="m:sub[1]" />
+      </mml:mrow>
+    </mml:msub>
+  </xsl:template>
+
+  <xsl:template match="m:sSup">
+    <mml:msup>
+      <mml:mrow>
+        <xsl:apply-templates select="m:e[1]" />
+      </mml:mrow>
+      <mml:mrow>
+        <xsl:apply-templates select="m:sup[1]" />
+      </mml:mrow>
+    </mml:msup>
+  </xsl:template>
+
+  <xsl:template match="m:sSubSup">
+    <mml:msubsup>
+      <mml:mrow>
+        <xsl:apply-templates select="m:e[1]" />
+      </mml:mrow>
+      <mml:mrow>
+        <xsl:apply-templates select="m:sub[1]" />
+      </mml:mrow>
+      <mml:mrow>
+        <xsl:apply-templates select="m:sup[1]" />
+      </mml:mrow>
+    </mml:msubsup>
+  </xsl:template>
+
+  <xsl:template match="m:groupChr">
+    <xsl:variable name="ndLastGroupChrPr" select="m:groupChrPr[last()]" />
+    <xsl:variable name="sLowerCasePos" select="translate($ndLastGroupChrPr/m:pos/@m:val, 
+		                                                     'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                     'abcdefghijklmnopqrstuvwxyz')" />
+
+    <xsl:variable name="sLowerCaseVertJc" select="translate($ndLastGroupChrPr/m:vertJc/@m:val, 
+		                                                     'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                     'abcdefghijklmnopqrstuvwxyz')" />
+    <xsl:variable name="ndLastChr" select="$ndLastGroupChrPr/m:chr" />
+
+    <xsl:variable name="chr">
+      <xsl:choose>
+        <xsl:when test="$ndLastChr and (not($ndLastChr/@m:val) or string-length($ndLastChr/@m:val) = 0)"></xsl:when>
+        <xsl:when test="string-length($ndLastChr/@m:val) &gt;= 1">
+          <xsl:value-of select="substring($ndLastChr/@m:val,1,1)" />
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>&#x023DF;</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:choose>
+      <xsl:when test="$sLowerCasePos = 'top'">
+        <xsl:choose>
+          <xsl:when test="$sLowerCaseVertJc = 'bot'">
+            <mml:mover accent="false">
+              <mml:mrow>
+                <xsl:apply-templates select="m:e[1]" />
+              </mml:mrow>
+              <mml:mo>
+                <xsl:value-of select="$chr" />
+              </mml:mo>
+            </mml:mover>
+          </xsl:when>
+          <xsl:otherwise>
+            <mml:munder accentunder="false">
+              <mml:mo>
+                <xsl:value-of select="$chr" />
+              </mml:mo>
+              <mml:mrow>
+                <xsl:apply-templates select="m:e[1]" />
+              </mml:mrow>
+            </mml:munder>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:choose>
+          <xsl:when test="$sLowerCaseVertJc = 'bot'">
+            <mml:mover accent="false">
+              <mml:mo>
+                <xsl:value-of select="$chr" />
+              </mml:mo>
+              <mml:mrow>
+                <xsl:apply-templates select="m:e[1]" />
+              </mml:mrow>
+            </mml:mover>
+          </xsl:when>
+          <xsl:otherwise>
+            <mml:munder accentunder="false">
+              <mml:mrow>
+                <xsl:apply-templates select="m:e[1]" />
+              </mml:mrow>
+              <mml:mo>
+                <xsl:value-of select="$chr" />
+              </mml:mo>
+            </mml:munder>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template name="fName">
+    <xsl:for-each select="m:fName/*">
+      <xsl:apply-templates select="." />
+    </xsl:for-each>
+  </xsl:template>
+
+  <xsl:template match="m:func">
+    <mml:mrow>
+      <mml:mrow>
+        <xsl:call-template name="fName" />
+      </mml:mrow>
+      <mml:mo>&#x02061;</mml:mo>
+      <mml:mrow>
+        <xsl:apply-templates select="m:e" />
+      </mml:mrow>
+    </mml:mrow>
+  </xsl:template>
+
+  <!-- %%Template: match m:f 
+		
+		m:f maps directly to mfrac. 
+	-->
+  <xsl:template match="m:f">
+    <xsl:variable name="sLowerCaseType" select="translate(m:fPr[last()]/m:type/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" />
+    <xsl:choose>
+      <xsl:when test="$sLowerCaseType='lin'">
+        <mml:mrow>
+          <mml:mrow>
+            <xsl:apply-templates select="m:num[1]" />
+          </mml:mrow>
+          <mml:mo>/</mml:mo>
+          <mml:mrow>
+            <xsl:apply-templates select="m:den[1]" />
+          </mml:mrow>
+        </mml:mrow>
+      </xsl:when>
+      <xsl:otherwise>
+        <mml:mfrac>
+          <xsl:call-template name="CreateMathMLFracProp">
+            <xsl:with-param name="type" select="$sLowerCaseType" />
+          </xsl:call-template>
+          <mml:mrow>
+            <xsl:apply-templates select="m:num[1]" />
+          </mml:mrow>
+          <mml:mrow>
+            <xsl:apply-templates select="m:den[1]" />
+          </mml:mrow>
+        </mml:mfrac>
+      </xsl:otherwise>
+    </xsl:choose>
+
+  </xsl:template>
+
+
+  <!-- %%Template: CreateMathMLFracProp 
+		
+			Make fraction properties based on supplied parameters.
+			OMML differentiates between a linear fraction and a skewed
+			one. For MathML, we write both as bevelled.
+	-->
+  <xsl:template name="CreateMathMLFracProp">
+    <xsl:param name="type" />
+    <xsl:variable name="sLowerCaseType" select="translate($type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" />
+
+    <xsl:if test="$sLowerCaseType='skw' or $sLowerCaseType='lin'">
+      <xsl:attribute name="bevelled">true</xsl:attribute>
+    </xsl:if>
+    <xsl:if test="$sLowerCaseType='nobar'">
+      <xsl:attribute name="linethickness">0pt</xsl:attribute>
+    </xsl:if>
+    <xsl:choose>
+      <xsl:when test="sLowerCaseNumJc='right'">
+        <xsl:attribute name="numalign">right</xsl:attribute>
+      </xsl:when>
+      <xsl:when test="sLowerCaseNumJc='left'">
+        <xsl:attribute name="numalign">left</xsl:attribute>
+      </xsl:when>
+    </xsl:choose>
+    <xsl:choose>
+      <xsl:when test="sLowerCaseDenJc='right'">
+        <xsl:attribute name="numalign">right</xsl:attribute>
+      </xsl:when>
+      <xsl:when test="sLowerCaseDenJc='left'">
+        <xsl:attribute name="numalign">left</xsl:attribute>
+      </xsl:when>
+    </xsl:choose>
+  </xsl:template>
+
+  <!-- %%Template: match m:e | m:den | m:num | m:lim | m:sup | m:sub 
+		
+		These element delinate parts of an expression (like the numerator).  -->
+  <xsl:template match="m:e | m:den | m:num | m:lim | m:sup | m:sub">
+    <xsl:choose>
+
+      <!-- If there is no scriptLevel specified, just call through -->
+      <xsl:when test="not(m:argPr[last()]/m:scrLvl/@m:val)">
+        <xsl:apply-templates select="*" />
+      </xsl:when>
+
+      <!-- Otherwise, create an mstyle and set the script level -->
+      <xsl:otherwise>
+        <mml:mstyle>
+          <xsl:attribute name="scriptlevel">
+            <xsl:value-of select="m:argPr[last()]/m:scrLvl/@m:val" />
+          </xsl:attribute>
+          <xsl:apply-templates select="*" />
+        </mml:mstyle>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="m:bar">
+    <xsl:variable name="sLowerCasePos" select="translate(m:barPr/m:pos/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                                       'abcdefghijklmnopqrstuvwxyz')" />
+
+    <xsl:variable name="fTop">
+
+      <xsl:choose>
+        <xsl:when test="$sLowerCasePos='top'">1</xsl:when>
+        <xsl:otherwise>0</xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:choose>
+      <xsl:when test="$fTop=1">
+        <mml:mover accent="false">
+          <mml:mrow>
+            <xsl:apply-templates select="m:e[1]" />
+          </mml:mrow>
+          <mml:mo>
+            <xsl:text>&#x00AF;</xsl:text>
+          </mml:mo>
+        </mml:mover>
+      </xsl:when>
+      <xsl:otherwise>
+        <mml:munder underaccent="false">
+          <mml:mrow>
+            <xsl:apply-templates select="m:e[1]" />
+          </mml:mrow>
+          <mml:mo>
+            <xsl:text>&#x005F;</xsl:text>
+          </mml:mo>
+        </mml:munder>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!-- %%Template match m:d
+
+		Process a delimiter. 
+	-->
+  <xsl:template match="m:d">
+    <mml:mfenced>
+      <!-- open: default is '(' for both OMML and MathML -->
+      <xsl:if test="m:dPr[1]/m:begChr/@m:val and not(m:dPr[1]/m:begChr/@m:val ='(')">
+        <xsl:attribute name="open">
+          <xsl:value-of select="m:dPr[1]/m:begChr/@m:val" />
+        </xsl:attribute>
+      </xsl:if>
+
+      <!-- close: default is ')' for both OMML and MathML -->
+      <xsl:if test="m:dPr[1]/m:endChr/@m:val and not(m:dPr[1]/m:endChr/@m:val =')')">
+        <xsl:attribute name="close">
+          <xsl:value-of select="m:dPr[1]/m:endChr/@m:val" />
+        </xsl:attribute>
+      </xsl:if>
+
+      <!-- separator: the default is ',' for MathML, and '|' for OMML -->
+      <xsl:choose>
+        <!-- Matches MathML default. Write nothing -->
+        <xsl:when test="m:dPr[1]/m:sepChr/@m:val = ','" />
+
+        <!-- OMML default: | -->
+        <xsl:when test="not(m:dPr[1]/m:sepChr/@m:val)">
+          <xsl:attribute name="separators">
+            <xsl:value-of select="'|'" />
+          </xsl:attribute>
+        </xsl:when>
+
+        <xsl:otherwise>
+          <xsl:attribute name="separators">
+            <xsl:value-of select="m:dPr[1]/m:sepChr/@m:val" />
+          </xsl:attribute>
+        </xsl:otherwise>
+      </xsl:choose>
+
+      <!-- now write all the children. Put each one into an mrow
+			just in case it produces multiple runs, etc -->
+      <xsl:for-each select="m:e">
+        <mml:mrow>
+          <xsl:apply-templates select="." />
+        </mml:mrow>
+      </xsl:for-each>
+    </mml:mfenced>
+  </xsl:template>
+
+  <xsl:template match="m:r">
+    <xsl:variable name="fNor">
+      <xsl:choose>
+        <xsl:when test="count(child::m:rPr[last()]/m:nor) = 0">0</xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="ForceFalseStrVal">
+            <xsl:with-param name="str" select="translate(child::m:rPr[last()]/m:nor/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                                       'abcdefghijklmnopqrstuvwxyz')" />
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <xsl:choose>
+      <xsl:when test="$fNor=1">
+        <mml:mtext>
+          <xsl:variable name="sOutput" select="translate(.//m:t, ' ', '&#xa0;')" />
+          <xsl:value-of select="$sOutput" />
+        </mml:mtext>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:for-each select=".//m:t">
+          <xsl:call-template name="ParseMt">
+            <xsl:with-param name="sToParse" select="text()" />
+            <xsl:with-param name="scr" select="../m:rPr[last()]/m:scr/@m:val" />
+            <xsl:with-param name="sty" select="../m:rPr[last()]/m:sty/@m:val" />
+            <xsl:with-param name="nor">0</xsl:with-param>
+          </xsl:call-template>
+        </xsl:for-each>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+
+  <xsl:template name="CreateTokenAttributes">
+    <xsl:param name="scr" />
+    <xsl:param name="sty" />
+    <xsl:param name="nor" />
+    <xsl:param name="nCharToPrint" />
+    <xsl:param name="sTokenType" />
+
+    <xsl:choose>
+      <xsl:when test="$nor=1">
+        <xsl:attribute name="mathvariant">normal</xsl:attribute>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:variable name="mathvariant">
+          <xsl:choose>
+            <!-- numbers don't care -->
+            <xsl:when test="$sTokenType='mn'" />
+
+            <xsl:when test="$scr='monospace'">monospace</xsl:when>
+            <xsl:when test="$scr='sans-serif' and $sty='i'">sans-serif-italic</xsl:when>
+            <xsl:when test="$scr='sans-serif' and $sty='b'">bold-sans-serif</xsl:when>
+            <xsl:when test="$scr='sans-serif' and $sty='bi'">sans-serif-bold-italic</xsl:when>
+            <xsl:when test="$scr='sans-serif'">sans-serif</xsl:when>
+            <xsl:when test="$scr='fraktur' and ($sty='b' or $sty='bi')">bold-fraktur</xsl:when>
+            <xsl:when test="$scr='fraktur'">fraktur</xsl:when>
+            <xsl:when test="$scr='double-struck'">double-struck</xsl:when>
+            <xsl:when test="$scr='script' and ($sty='b' or $sty='bi')">bold-script</xsl:when>
+            <xsl:when test="$scr='script'">script</xsl:when>
+            <xsl:when test="($scr='roman' or not($scr) or $scr='') and $sty='b'">bold</xsl:when>
+            <xsl:when test="($scr='roman' or not($scr) or $scr='') and $sty='i'">italic</xsl:when>
+            <xsl:when test="($scr='roman' or not($scr) or $scr='') and $sty='p'">normal</xsl:when>
+            <xsl:when test="($scr='roman' or not($scr) or $scr='') and $sty='bi'">bold-italic</xsl:when>
+            <xsl:otherwise />
+          </xsl:choose>
+        </xsl:variable>
+        <xsl:variable name="fontweight">
+          <xsl:choose>
+            <xsl:when test="$sty='b' or $sty='bi'">bold</xsl:when>
+            <xsl:otherwise>normal</xsl:otherwise>
+          </xsl:choose>
+        </xsl:variable>
+        <xsl:variable name="fontstyle">
+          <xsl:choose>
+            <xsl:when test="$sty='p' or $sty='b'">normal</xsl:when>
+            <xsl:otherwise>italic</xsl:otherwise>
+          </xsl:choose>
+        </xsl:variable>
+
+        <!-- Writing of attributes begins here -->
+        <xsl:choose>
+          <!-- Don't write mathvariant for operators unless they want to be normal -->
+          <xsl:when test="$sTokenType='mo' and $mathvariant!='normal'" />
+
+          <!-- A single character within an mi is already italics, don't write -->
+          <xsl:when test="$sTokenType='mi' and $nCharToPrint=1 and ($mathvariant='' or $mathvariant='italic')" />
+
+          <xsl:when test="$sTokenType='mi' and $nCharToPrint &gt; 1 and ($mathvariant='' or $mathvariant='italic')">
+            <xsl:attribute name="mathvariant">
+              <xsl:value-of select="'italic'" />
+            </xsl:attribute>
+          </xsl:when>
+          <xsl:when test="$mathvariant!='italic' and $mathvariant!=''">
+            <xsl:attribute name="mathvariant">
+              <xsl:value-of select="$mathvariant" />
+            </xsl:attribute>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:if test="not($sTokenType='mi' and $nCharToPrint=1) and $fontstyle='italic'">
+              <xsl:attribute name="fontstyle">italic</xsl:attribute>
+            </xsl:if>
+            <xsl:if test="$fontweight='bold'">
+              <xsl:attribute name="fontweight">bold</xsl:attribute>
+            </xsl:if>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="m:eqArr">
+    <mml:mtable>
+      <xsl:for-each select="m:e">
+        <mml:mtr>
+          <mml:mtd>
+            <xsl:choose>
+              <xsl:when test="m:argPr[last()]/m:scrLvl/@m:val!='0' or 
+					            not(m:argPr[last()]/m:scrLvl/@m:val)  or 
+					            m:argPr[last()]/m:scrLvl/@m:val=''">
+                <mml:mrow>
+                  <mml:maligngroup />
+                  <xsl:call-template name="CreateEqArrRow">
+                    <xsl:with-param name="align" select="1" />
+                    <xsl:with-param name="ndCur" select="*[1]" />
+                  </xsl:call-template>
+                </mml:mrow>
+              </xsl:when>
+              <xsl:otherwise>
+                <mml:mstyle>
+                  <xsl:attribute name="scriptlevel">
+                    <xsl:value-of select="m:argPr[last()]/m:scrLvl/@m:val" />
+                  </xsl:attribute>
+                  <mml:maligngroup />
+                  <xsl:call-template name="CreateEqArrRow">
+                    <xsl:with-param name="align" select="1" />
+                    <xsl:with-param name="ndCur" select="*[1]" />
+                  </xsl:call-template>
+                </mml:mstyle>
+              </xsl:otherwise>
+            </xsl:choose>
+          </mml:mtd>
+        </mml:mtr>
+      </xsl:for-each>
+    </mml:mtable>
+  </xsl:template>
+
+  <xsl:template name="CreateEqArrRow">
+    <xsl:param name="align" />
+    <xsl:param name="ndCur" />
+    <xsl:variable name="sAllMt">
+      <xsl:for-each select="$ndCur/m:t">
+        <xsl:value-of select="." />
+      </xsl:for-each>
+    </xsl:variable>
+    <xsl:choose>
+      <xsl:when test="$ndCur/self::m:r">
+        <xsl:call-template name="ParseEqArrMr">
+          <xsl:with-param name="sToParse" select="$sAllMt" />
+          <xsl:with-param name="scr" select="../m:rPr[last()]/m:scr/@m:val" />
+          <xsl:with-param name="sty" select="../m:rPr[last()]/m:sty/@m:val" />
+          <xsl:with-param name="nor">
+            <xsl:choose>
+              <xsl:when test="count($ndCur/m:rPr[last()]/m:nor) = 0">0</xsl:when>
+              <xsl:otherwise>
+                <xsl:call-template name="ForceFalseStrVal">
+                  <xsl:with-param name="str" select="translate($ndCur/m:rPr[last()]/m:nor/@m:val, 
+                                                                     'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
+		                                                                 'abcdefghijklmnopqrstuvwxyz')" />
+                </xsl:call-template>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:with-param>
+          <xsl:with-param name="align" select="$align" />
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates select="$ndCur" />
+      </xsl:otherwise>
+    </xsl:choose>
+    <xsl:if test="count($ndCur/following-sibling::*) &gt; 0">
+      <xsl:variable name="cAmp">
+        <xsl:call-template name="CountAmp">
+          <xsl:with-param name="sAllMt" select="$sAllMt" />
+          <xsl:with-param name="cAmp" select="0" />
+        </xsl:call-template>
+      </xsl:variable>
+      <xsl:call-template name="CreateEqArrRow">
+        <xsl:with-param name="align" select="($align+($cAmp mod 2)) mod 2" />
+        <xsl:with-param name="ndCur" select="$ndCur/following-sibling::*[1]" />
+      </xsl:call-template>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template name="CountAmp">
+    <xsl:param name="sAllMt" />
+    <xsl:param name="cAmp" />
+    <xsl:choose>
+      <xsl:when test="string-length(substring-after($sAllMt, '&amp;')) &gt; 0 or 
+			                substring($sAllMt, string-length($sAllMt))='&#x0026;'">
+        <xsl:call-template name="CountAmp">
+          <xsl:with-param name="sAllMt" select="substring-after($sAllMt, '&#x0026;')" />
+          <xsl:with-param name="cAmp" select="$cAmp+1" />
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$cAmp" />
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!-- %%Template: ParseEqArrMr
+			
+			Similar to ParseMt, but this one has to do more for an equation array. 
+      In equation arrays &amp; is a special character which denotes alignment.
+      
+      The &amp; in an equation works by alternating between meaning insert alignment spacing
+      and insert alignment mark.  For each equation in the equation array
+      there is an implied align space at the beginning of the equation.  Within each equation,
+      the first &amp; means alignmark, the second, align space, the third, alignmark, etc.
+      
+      For this reason when parsing m:r's in equation arrays it is important to keep track of what
+      the next ampersand will mean.
+      
+      $align=0 => Omml's align space, which is similar to MathML's maligngroup.
+      $align=1 => Omml's alignment mark, which is similar to MathML's malignmark.
+	-->
+  <xsl:template name="ParseEqArrMr">
+    <xsl:param name="sToParse" />
+    <xsl:param name="sty" />
+    <xsl:param name="scr" />
+    <xsl:param name="nor" />
+    <xsl:param name="align" />
+
+    <xsl:if test="string-length($sToParse) &gt; 0">
+      <xsl:choose>
+        <xsl:when test="substring($sToParse,1,1) = '&amp;'">
+          <xsl:choose>
+            <xsl:when test="$align='0'">
+              <mml:maligngroup />
+            </xsl:when>
+            <xsl:when test="$align='1'">
+              <mml:malignmark />
+            </xsl:when>
+          </xsl:choose>
+          <xsl:call-template name="ParseEqArrMr">
+            <xsl:with-param name="sToParse" select="substring($sToParse,2)" />
+            <xsl:with-param name="scr" select="$scr" />
+            <xsl:with-param name="sty" select="$sty" />
+            <xsl:with-param name="nor" select="$nor" />
+            <xsl:with-param name="align">
+              <xsl:choose>
+                <xsl:when test="$align='1'">0</xsl:when>
+                <xsl:otherwise>1</xsl:otherwise>
+              </xsl:choose>
+            </xsl:with-param>
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:variable name="sRepNumWith0">
+            <xsl:call-template name="SReplaceNumWithZero">
+              <xsl:with-param name="sToParse" select="$sToParse" />
+            </xsl:call-template>
+          </xsl:variable>
+          <xsl:variable name="sRepOperWith-">
+            <xsl:call-template name="SReplaceOperWithMinus">
+              <xsl:with-param name="sToParse" select="$sRepNumWith0" />
+            </xsl:call-template>
+          </xsl:variable>
+
+          <xsl:variable name="iFirstOper" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '-'))" />
+          <xsl:variable name="iFirstNum" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '0'))" />
+          <xsl:variable name="iFirstAmp" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '&#x0026;'))" />
+          <xsl:variable name="fNumAtPos1">
+            <xsl:choose>
+              <xsl:when test="substring($sRepOperWith-,1,1)='0'">1</xsl:when>
+              <xsl:otherwise>0</xsl:otherwise>
+            </xsl:choose>
+          </xsl:variable>
+          <xsl:variable name="fOperAtPos1">
+            <xsl:choose>
+              <xsl:when test="substring($sRepOperWith-,1,1)='-'">1</xsl:when>
+              <xsl:otherwise>0</xsl:otherwise>
+            </xsl:choose>
+          </xsl:variable>
+          <xsl:choose>
+
+            <!-- Case I: The string begins with neither a number, nor an operator -->
+            <xsl:when test="$fNumAtPos1='0' and $fOperAtPos1='0'">
+              <xsl:choose>
+                <xsl:when test="$nor = 0">
+                  <mml:mi>
+                    <xsl:call-template name="CreateTokenAttributes">
+                      <xsl:with-param name="scr" select="$scr" />
+                      <xsl:with-param name="sty" select="$sty" />
+                      <xsl:with-param name="nor" select="$nor" />
+                      <xsl:with-param name="nCharToPrint" select="1" />
+                      <xsl:with-param name="sTokenType" select="'mi'" />
+                    </xsl:call-template>
+                    <xsl:variable name="sOutput" select="translate(substring($sToParse, 1, 1), ' ', '&#xa0;')" />
+                    <xsl:value-of select="$sOutput" />
+                  </mml:mi>
+                </xsl:when>
+                <xsl:otherwise>
+                  <mml:mtext>
+                    <xsl:variable name="sOutput" select="translate(substring($sToParse, 1, 1), ' ', '&#xa0;')" />
+                    <xsl:value-of select="$sOutput" />
+                  </mml:mtext>
+                </xsl:otherwise>
+              </xsl:choose>
+              <xsl:call-template name="ParseEqArrMr">
+                <xsl:with-param name="sToParse" select="substring($sToParse, 2)" />
+                <xsl:with-param name="scr" select="$scr" />
+                <xsl:with-param name="sty" select="$sty" />
+                <xsl:with-param name="nor" select="$nor" />
+                <xsl:with-param name="align" select="$align" />
+              </xsl:call-template>
+            </xsl:when>
+
+            <!-- Case II: There is an operator at position 1 -->
+            <xsl:when test="$fOperAtPos1='1'">
+              <xsl:choose>
+                <xsl:when test="$nor = 0">
+                  <mml:mo>
+                    <xsl:call-template name="CreateTokenAttributes">
+                      <xsl:with-param name="scr" />
+                      <xsl:with-param name="sty" />
+                      <xsl:with-param name="nor" select="$nor" />
+                      <xsl:with-param name="sTokenType" select="'mo'" />
+                    </xsl:call-template>
+                    <xsl:value-of select="substring($sToParse,1,1)" />
+                  </mml:mo>
+                </xsl:when>
+                <xsl:otherwise>
+                  <mml:mtext>
+                    <xsl:value-of select="substring($sToParse,1,1)" />
+                  </mml:mtext>                  
+                </xsl:otherwise>
+              </xsl:choose>
+              <xsl:call-template name="ParseEqArrMr">
+                <xsl:with-param name="sToParse" select="substring($sToParse, 2)" />
+                <xsl:with-param name="scr" select="$scr" />
+                <xsl:with-param name="sty" select="$sty" />
+                <xsl:with-param name="nor" select="$nor" />
+                <xsl:with-param name="align" select="$align" />
+              </xsl:call-template>
+            </xsl:when>
+
+            <!-- Case III: There is a number at position 1 -->
+            <xsl:otherwise>
+              <xsl:variable name="sConsecNum">
+                <xsl:call-template name="SNumStart">
+                  <xsl:with-param name="sToParse" select="$sToParse" />
+                  <xsl:with-param name="sPattern" select="$sRepNumWith0" />
+                </xsl:call-template>
+              </xsl:variable>
+              <xsl:choose>
+                <xsl:when test="$nor = 0">
+                  <mml:mn>
+                    <xsl:call-template name="CreateTokenAttributes">
+                      <xsl:with-param name="scr" />
+                      <xsl:with-param name="sty" select="'p'"/>
+                      <xsl:with-param name="nor" select="$nor" />
+                      <xsl:with-param name="sTokenType" select="'mn'" />
+                    </xsl:call-template>
+                    <xsl:value-of select="$sConsecNum" />
+                  </mml:mn>
+                </xsl:when>
+                <xsl:otherwise>
+                  <mml:mtext>
+                    <xsl:value-of select="$sConsecNum" />
+                  </mml:mtext>
+                </xsl:otherwise>
+              </xsl:choose>
+              <xsl:call-template name="ParseEqArrMr">
+                <xsl:with-param name="sToParse" select="substring-after($sToParse, $sConsecNum)" />
+                <xsl:with-param name="scr" select="$scr" />
+                <xsl:with-param name="sty" select="$sty" />
+                <xsl:with-param name="nor" select="$nor" />
+                <xsl:with-param name="align" select="$align" />
+              </xsl:call-template>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+  </xsl:template>
+
+  <!-- %%Template: ParseMt
+
+			Produce a run of text. Technically, OMML makes no distinction 
+			between numbers, operators, and other characters in a run. For 
+			MathML we need to break these into mi, mn, or mo elements. 
+			
+			See also ParseEqArrMr
+	-->
+  <xsl:template name="ParseMt">
+    <xsl:param name="sToParse" />
+    <xsl:param name="sty" />
+    <xsl:param name="scr" />
+    <xsl:param name="nor" />
+    <xsl:if test="string-length($sToParse) &gt; 0">
+      <xsl:variable name="sRepNumWith0">
+        <xsl:call-template name="SReplaceNumWithZero">
+          <xsl:with-param name="sToParse" select="$sToParse" />
+        </xsl:call-template>
+      </xsl:variable>
+      <xsl:variable name="sRepOperWith-">
+        <xsl:call-template name="SReplaceOperWithMinus">
+          <xsl:with-param name="sToParse" select="$sRepNumWith0" />
+        </xsl:call-template>
+      </xsl:variable>
+
+      <xsl:variable name="iFirstOper" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '-'))" />
+      <xsl:variable name="iFirstNum" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '0'))" />
+      <xsl:variable name="fNumAtPos1">
+        <xsl:choose>
+          <xsl:when test="substring($sRepOperWith-,1,1)='0'">1</xsl:when>
+          <xsl:otherwise>0</xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="fOperAtPos1">
+        <xsl:choose>
+          <xsl:when test="substring($sRepOperWith-,1,1)='-'">1</xsl:when>
+          <xsl:otherwise>0</xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+
+      <xsl:choose>
+
+        <!-- Case I: The string begins with neither a number, nor an operator -->
+        <xsl:when test="$fOperAtPos1='0' and $fNumAtPos1='0'">
+          <xsl:variable name="nCharToPrint">
+            <xsl:choose>
+              <xsl:when test="ancestor::m:fName">
+                <xsl:choose>
+                  <xsl:when test="($iFirstOper=$iFirstNum) and 
+											($iFirstOper=string-length($sToParse)) and
+							                (substring($sRepOperWith-, string-length($sRepOperWith-))!='0') and 
+							                (substring($sRepOperWith-, string-length($sRepOperWith-))!='-')">
+                    <xsl:value-of select="string-length($sToParse)" />
+                  </xsl:when>
+                  <xsl:when test="$iFirstOper &lt; $iFirstNum">
+                    <xsl:value-of select="$iFirstOper - 1" />
+                  </xsl:when>
+                  <xsl:otherwise>
+                    <xsl:value-of select="$iFirstNum - 1" />
+                  </xsl:otherwise>
+                </xsl:choose>
+              </xsl:when>
+              <xsl:otherwise>1</xsl:otherwise>
+            </xsl:choose>
+          </xsl:variable>
+
+          <mml:mi>
+            <xsl:call-template name="CreateTokenAttributes">
+              <xsl:with-param name="scr" select="$scr" />
+              <xsl:with-param name="sty" select="$sty" />
+              <xsl:with-param name="nor" select="$nor" />
+              <xsl:with-param name="nCharToPrint" select="$nCharToPrint" />
+              <xsl:with-param name="sTokenType" select="'mi'" />
+            </xsl:call-template>
+            <xsl:variable name="sWrite" select="translate(substring($sToParse, 1, $nCharToPrint), ' ', '&#xa0;')" />
+            <xsl:value-of select="$sWrite" />
+          </mml:mi>
+          <xsl:call-template name="ParseMt">
+            <xsl:with-param name="sToParse" select="substring($sToParse, $nCharToPrint+1)" />
+            <xsl:with-param name="scr" select="$scr" />
+            <xsl:with-param name="sty" select="$sty" />
+            <xsl:with-param name="nor" select="$nor" />
+          </xsl:call-template>
+        </xsl:when>
+
+        <!-- Case II: There is an operator at position 1 -->
+        <xsl:when test="$fOperAtPos1='1'">
+          <mml:mo>
+            <xsl:call-template name="CreateTokenAttributes">
+              <xsl:with-param name="scr" />
+              <xsl:with-param name="sty" />
+              <xsl:with-param name="nor" select="$nor" />
+              <xsl:with-param name="sTokenType" select="'mo'" />
+            </xsl:call-template>
+            <xsl:value-of select="substring($sToParse,1,1)" />
+          </mml:mo>
+          <xsl:call-template name="ParseMt">
+            <xsl:with-param name="sToParse" select="substring($sToParse, 2)" />
+            <xsl:with-param name="scr" select="$scr" />
+            <xsl:with-param name="sty" select="$sty" />
+            <xsl:with-param name="nor" select="$nor" />
+          </xsl:call-template>
+        </xsl:when>
+
+        <!-- Case III: There is a number at position 1 -->
+        <xsl:otherwise>
+          <xsl:variable name="sConsecNum">
+            <xsl:call-template name="SNumStart">
+              <xsl:with-param name="sToParse" select="$sToParse" />
+              <xsl:with-param name="sPattern" select="$sRepNumWith0" />
+            </xsl:call-template>
+          </xsl:variable>
+          <mml:mn>
+            <xsl:call-template name="CreateTokenAttributes">
+              <xsl:with-param name="scr" select="$scr" />
+              <xsl:with-param name="sty" select="'p'" />
+              <xsl:with-param name="nor" select="$nor" />
+              <xsl:with-param name="sTokenType" select="'mn'" />
+            </xsl:call-template>
+            <xsl:value-of select="$sConsecNum" />
+          </mml:mn>
+          <xsl:call-template name="ParseMt">
+            <xsl:with-param name="sToParse" select="substring-after($sToParse, $sConsecNum)" />
+            <xsl:with-param name="scr" select="$scr" />
+            <xsl:with-param name="sty" select="$sty" />
+            <xsl:with-param name="nor" select="$nor" />
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+  </xsl:template>
+
+  <!-- %%Template: SNumStart 
+	
+		Return the longest substring of sToParse starting from the 
+		start of sToParse that is a number. In addition, it takes the
+		pattern string, which is sToParse with all of its numbers 
+		replaced with a 0. sPattern should be the same length 
+		as sToParse		
+	-->
+  <xsl:template name="SNumStart">
+    <xsl:param name="sToParse" select="''" />
+    <!-- if we don't get anything, take the string itself -->
+    <xsl:param name="sPattern" select="'$sToParse'" />
+
+
+    <xsl:choose>
+      <!-- the pattern says this is a number, recurse with the rest -->
+      <xsl:when test="substring($sPattern, 1, 1) = '0'">
+        <xsl:call-template name="SNumStart">
+          <xsl:with-param name="sToParse" select="$sToParse" />
+          <xsl:with-param name="sPattern" select="substring($sPattern, 2)" />
+        </xsl:call-template>
+      </xsl:when>
+
+      <!-- the pattern says we've run out of numbers. Take as many
+				characters from sToParse as we shaved off sPattern -->
+      <xsl:otherwise>
+        <xsl:value-of select="substring($sToParse, 1, string-length($sToParse) - string-length($sPattern))" />
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!-- %%Template SRepeatCharAcc
+	
+			The core of SRepeatChar with an accumulator. The current
+			string is in param $acc, and we will double and recurse,
+			if we're less than half of the required length or else just 
+			add the right amount of characters to the accumulator and
+			return
+	-->
+  <xsl:template name="SRepeatCharAcc">
+    <xsl:param name="cchRequired" select="1" />
+    <xsl:param name="ch" select="'-'" />
+    <xsl:param name="acc" select="$ch" />
+
+    <xsl:variable name="cchAcc" select="string-length($acc)" />
+    <xsl:choose>
+      <xsl:when test="(2 * $cchAcc) &lt; $cchRequired">
+        <xsl:call-template name="SRepeatCharAcc">
+          <xsl:with-param name="cchRequired" select="$cchRequired" />
+          <xsl:with-param name="ch" select="$ch" />
+          <xsl:with-param name="acc" select="concat($acc, $acc)" />
+        </xsl:call-template>
+      </xsl:when>
+
+      <xsl:otherwise>
+        <xsl:value-of select="concat($acc, substring($acc, 1, $cchRequired - $cchAcc))" />
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+
+  <!-- %%Template SRepeatChar
+	
+			Generates a string nchRequired long by repeating the given character ch
+	-->
+  <xsl:template name="SRepeatChar">
+    <xsl:param name="cchRequired" select="1" />
+    <xsl:param name="ch" select="'-'" />
+
+    <xsl:call-template name="SRepeatCharAcc">
+      <xsl:with-param name="cchRequired" select="$cchRequired" />
+      <xsl:with-param name="ch" select="$ch" />
+      <xsl:with-param name="acc" select="$ch" />
+    </xsl:call-template>
+  </xsl:template>
+
+  <!-- %%Template SReplaceOperWithMinus
+	
+		Go through the given string and replace every instance
+		of an operator with a minus '-'. This helps quickly identify
+		the first instance of an operator.  
+	-->
+  <xsl:template name="SReplaceOperWithMinus">
+    <xsl:param name="sToParse" select="''" />
+
+    <xsl:value-of select="translate($sToParse, $sOperators, $sMinuses)" />
+  </xsl:template>
+
+  <!-- %%Template SReplaceNumWithZero
+	
+		Go through the given string and replace every instance
+		of an number with a zero '0'. This helps quickly identify
+		the first occurence of a number. 
+		
+		Considers the '.' and ',' part of a number iff they are sandwiched 
+		between two other numbers. 0.3 will be recognized as a number,
+		x.3 will not be. Since these characters can also be an operator, this 
+		should be called before SReplaceOperWithMinus.
+	-->
+  <xsl:template name="SReplaceNumWithZero">
+    <xsl:param name="sToParse" select="''" />
+
+    <!-- First do a simple replace. Numbers will all be come 0's.
+			After this point, the pattern involving the . or , that 
+			we are looking for will become 0.0 or 0,0 -->
+    <xsl:variable name="sSimpleReplace" select="translate($sToParse, $sNumbers, $sZeros)" />
+
+    <!-- And then, replace 0.0 with just 000. This means that the . will 
+			become part of the number -->
+    <xsl:variable name="sReplacePeriod">
+      <xsl:call-template name="SReplace">
+        <xsl:with-param name="sInput" select="$sSimpleReplace" />
+        <xsl:with-param name="sOrig" select="'0.0'" />
+        <xsl:with-param name="sReplacement" select="'000'" />
+      </xsl:call-template>
+    </xsl:variable>
+
+    <!-- And then, replace 0,0 with just 000. This means that the , will 
+			become part of the number -->
+    <xsl:call-template name="SReplace">
+      <xsl:with-param name="sInput" select="$sReplacePeriod" />
+      <xsl:with-param name="sOrig" select="'0,0'" />
+      <xsl:with-param name="sReplacement" select="'000'" />
+    </xsl:call-template>
+  </xsl:template>
+
+  <!-- Template to translate Word's borderBox properties into the menclose notation attribute
+       The initial call to this SHOULD NOT pass an sAttribute.  Subsequent calls to 
+       CreateMencloseNotationAttrFromBorderBoxAttr by CreateMencloseNotationAttrFromBorderBoxAttr will
+       update the sAttribute as appropriate.
+       
+       CreateMencloseNotationAttrFromBorderBoxAttr looks at each attribute (fHideTop, fHideBot, etc.) one at a time
+       in the order they are listed and passes a modified sAttribute to CreateMencloseNotationAttrFromBorderBoxAttr.
+       Each successive call to CreateMencloseNotationAttrFromBorderBoxAttr knows which attribute to look at because 
+       the previous call should have omitted passing the attribute it just analyzed.  This is why as you read lower 
+       and lower in the template that each call to CreateMencloseNotationAttrFromBorderBoxAttr has fewer and fewer attributes.
+       -->
+  <xsl:template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+    <xsl:param name="fHideTop" />
+    <xsl:param name="fHideBot" />
+    <xsl:param name="fHideLeft" />
+    <xsl:param name="fHideRight" />
+    <xsl:param name="fStrikeH" />
+    <xsl:param name="fStrikeV" />
+    <xsl:param name="fStrikeBLTR" />
+    <xsl:param name="fStrikeTLBR" />
+    <xsl:param name="sAttribute" />
+
+    <xsl:choose>
+      <xsl:when test="string-length($sAttribute) = 0">
+        <xsl:choose>
+          <xsl:when test="string-length($fHideTop) &gt; 0
+                      and string-length($fHideBot) &gt; 0 
+                      and string-length($fHideLeft) &gt; 0
+                      and string-length($fHideRight) &gt; 0">
+
+            <xsl:choose>
+              <xsl:when test="$fHideTop = 0 
+                              and $fHideBot = 0
+                              and $fHideLeft = 0 
+                              and $fHideRight = 0">
+                <!-- We can use 'box' instead of top, bot, left, and right.  Therefore,
+                  replace sAttribute with 'box' and begin analyzing params fStrikeH
+                  and below. -->
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fStrikeH" select="$fStrikeH" />
+                  <xsl:with-param name="fStrikeV" select="$fStrikeV" />
+                  <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute">
+                    <xsl:text>box</xsl:text>
+                  </xsl:with-param>
+                </xsl:call-template>
+              </xsl:when>
+              <xsl:otherwise>
+                <!-- Can't use 'box', theremore, must analyze all attributes -->
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fHideTop" select="$fHideTop" />
+                  <xsl:with-param name="fHideBot" select="$fHideBot" />
+                  <xsl:with-param name="fHideLeft" select="$fHideLeft" />
+                  <xsl:with-param name="fHideRight" select="$fHideRight" />
+                  <xsl:with-param name="fStrikeH" select="$fStrikeH" />
+                  <xsl:with-param name="fStrikeV" select="$fStrikeV" />
+                  <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute">
+                    <!-- Assume using all four (left right top bottom).  Subsequent calls
+                         will remove the sides which aren't to be includes. -->
+                    <xsl:text>left right top bottom</xsl:text>
+                  </xsl:with-param>
+                </xsl:call-template>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+        </xsl:choose>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:choose>
+          <xsl:when test="string-length($fHideTop) &gt; 0">
+            <xsl:choose>
+              <xsl:when test="$fHideTop=1">
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fHideBot" select="$fHideBot" />
+                  <xsl:with-param name="fHideLeft" select="$fHideLeft" />
+                  <xsl:with-param name="fHideRight" select="$fHideRight" />
+                  <xsl:with-param name="fStrikeH" select="$fStrikeH" />
+                  <xsl:with-param name="fStrikeV" select="$fStrikeV" />
+                  <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute">
+                    <xsl:call-template name="SReplace">
+                      <xsl:with-param name="sInput" select="$sAttribute" />
+                      <xsl:with-param name="sOrig" select="'top'" />
+                      <xsl:with-param name="sReplacement" select="''" />
+                    </xsl:call-template>
+                  </xsl:with-param>
+                </xsl:call-template>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fHideBot" select="$fHideBot" />
+                  <xsl:with-param name="fHideLeft" select="$fHideLeft" />
+                  <xsl:with-param name="fHideRight" select="$fHideRight" />
+                  <xsl:with-param name="fStrikeH" select="$fStrikeH" />
+                  <xsl:with-param name="fStrikeV" select="$fStrikeV" />
+                  <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute" select="$sAttribute" />
+                </xsl:call-template>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+          <xsl:when test="string-length($fHideBot) &gt; 0">
+            <xsl:choose>
+              <xsl:when test="$fHideBot=1">
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fHideLeft" select="$fHideLeft" />
+                  <xsl:with-param name="fHideRight" select="$fHideRight" />
+                  <xsl:with-param name="fStrikeH" select="$fStrikeH" />
+                  <xsl:with-param name="fStrikeV" select="$fStrikeV" />
+                  <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute">
+                    <xsl:call-template name="SReplace">
+                      <xsl:with-param name="sInput" select="$sAttribute" />
+                      <xsl:with-param name="sOrig" select="'bottom'" />
+                      <xsl:with-param name="sReplacement" select="''" />
+                    </xsl:call-template>
+                  </xsl:with-param>
+                </xsl:call-template>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fHideLeft" select="$fHideLeft" />
+                  <xsl:with-param name="fHideRight" select="$fHideRight" />
+                  <xsl:with-param name="fStrikeH" select="$fStrikeH" />
+                  <xsl:with-param name="fStrikeV" select="$fStrikeV" />
+                  <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute" select="$sAttribute" />
+                </xsl:call-template>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+          <xsl:when test="string-length($fHideLeft) &gt; 0">
+            <xsl:choose>
+              <xsl:when test="$fHideLeft=1">
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fHideRight" select="$fHideRight" />
+                  <xsl:with-param name="fStrikeH" select="$fStrikeH" />
+                  <xsl:with-param name="fStrikeV" select="$fStrikeV" />
+                  <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute">
+                    <xsl:call-template name="SReplace">
+                      <xsl:with-param name="sInput" select="$sAttribute" />
+                      <xsl:with-param name="sOrig" select="'left'" />
+                      <xsl:with-param name="sReplacement" select="''" />
+                    </xsl:call-template>
+                  </xsl:with-param>
+                </xsl:call-template>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fHideRight" select="$fHideRight" />
+                  <xsl:with-param name="fStrikeH" select="$fStrikeH" />
+                  <xsl:with-param name="fStrikeV" select="$fStrikeV" />
+                  <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute" select="$sAttribute" />
+                </xsl:call-template>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+          <xsl:when test="string-length($fHideRight) &gt; 0">
+            <xsl:choose>
+              <xsl:when test="$fHideRight=1">
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fStrikeH" select="$fStrikeH" />
+                  <xsl:with-param name="fStrikeV" select="$fStrikeV" />
+                  <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute">
+                    <xsl:call-template name="SReplace">
+                      <xsl:with-param name="sInput" select="$sAttribute" />
+                      <xsl:with-param name="sOrig" select="'right'" />
+                      <xsl:with-param name="sReplacement" select="''" />
+                    </xsl:call-template>
+                  </xsl:with-param>
+                </xsl:call-template>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fStrikeH" select="$fStrikeH" />
+                  <xsl:with-param name="fStrikeV" select="$fStrikeV" />
+                  <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute" select="$sAttribute" />
+                </xsl:call-template>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+          <xsl:when test="string-length($fStrikeH) &gt; 0">
+            <xsl:choose>
+              <xsl:when test="$fStrikeH=1">
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fStrikeV" select="$fStrikeV" />
+                  <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute" select="concat($sAttribute, ' horizontalstrike')" />
+                </xsl:call-template>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fStrikeV" select="$fStrikeV" />
+                  <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute" select="$sAttribute" />
+                </xsl:call-template>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+          <xsl:when test="string-length($fStrikeV) &gt; 0">
+            <xsl:choose>
+              <xsl:when test="$fStrikeV=1">
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute" select="concat($sAttribute, ' verticalstrike')" />
+                </xsl:call-template>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute" select="$sAttribute" />
+                </xsl:call-template>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+          <xsl:when test="string-length($fStrikeBLTR) &gt; 0">
+            <xsl:choose>
+              <xsl:when test="$fStrikeBLTR=1">
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute" select="concat($sAttribute, ' updiagonalstrike')" />
+                </xsl:call-template>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
+                  <xsl:with-param name="sAttribute" select="$sAttribute" />
+                </xsl:call-template>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+          <xsl:when test="string-length($fStrikeTLBR) &gt; 0">
+            <xsl:choose>
+              <xsl:when test="$fStrikeTLBR=1">
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="sAttribute" select="concat($sAttribute, ' downdiagonalstrike')" />
+                </xsl:call-template>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
+                  <xsl:with-param name="sAttribute" select="$sAttribute" />
+                </xsl:call-template>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:attribute name="notation">
+              <xsl:value-of select="normalize-space($sAttribute)" />
+            </xsl:attribute>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!-- Tristate (true, false, neither) from string value -->
+  <xsl:template name="TFromStrVal">
+    <xsl:param name="str" />
+    <xsl:choose>
+      <xsl:when test="$str = 'on' or $str = '1' or $str = 'true'">1</xsl:when>
+      <xsl:when test="$str = 'off' or $str = '0' or $str = 'false'">0</xsl:when>
+      <xsl:otherwise>-1</xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!-- Return 0 iff $str is explicitly set to a false value.  
+       Return true otherwise -->
+  <xsl:template name="ForceFalseStrVal">
+    <xsl:param name="str" />
+    <xsl:variable name="tValue">
+      <xsl:call-template name="TFromStrVal">
+        <xsl:with-param name="str" select="$str"/>
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:choose>
+      <xsl:when test="$tValue = '0'">0</xsl:when>
+      <xsl:otherwise>1</xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!-- Return 1 iff $str is explicitly set to a true value.  
+       Return false otherwise -->
+  <xsl:template name="ForceTrueStrVal">
+    <xsl:param name="str" />
+    <xsl:variable name="tValue">
+      <xsl:call-template name="TFromStrVal">
+        <xsl:with-param name="str" select="$str"/>
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:choose>
+      <xsl:when test="$tValue = '1'">1</xsl:when>
+      <xsl:otherwise>0</xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+</xsl:stylesheet>

+ 10 - 2
README.md

@@ -1,3 +1,11 @@
-# diagnosis
+# 爻象测评
+
+---
+爻象测评致力于为中小学生进行全方面的学习测评
+
+
+###开发小组成员
+    @HZH
+    @DaiFengWen
+    @Feick
 
-爻象诊断

+ 2 - 0
a.html

@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<html><head><meta charset="utf-8"><style>p{margin-top:0pt;margin-bottom:1pt;}p.a{text-align:justified;}span.a{font-family:'Times New Roman';}p.a3{text-align:left;}span.Char{font-family:'Times New Roman';}span.a4{font-size:10.0pt;}span.a5{font-size:9.0pt;}span.Char0{font-family:'Times New Roman';font-size:9.0pt;}</style></head><body><div style="width:595.3pt;margin-bottom:72.0pt;margin-top:72.0pt;margin-left:90.0pt;margin-right:90.0pt;"><p>【题干】</p><p>如图所示的程序框图运行的结果 <span id="_GoBack"/><img src="\image1.jpeg" style="width:415.3pt;height:259.59497pt;"/>为()</p><p><br/></p><p>A、1</p><p>B、2</p><p>C、3</p><p>D、4</p><p>【答案】</p><p>B</p><p>【分析】</p><p>集合的交集是取两者共有的数</p><p>【解答】</p><p>2个集合中都有2</p><p>【点评】</p><p>这道题考的是集合的基础知识</p><p/></div></body></html>

BIN
image/image1.jpeg


+ 0 - 0
log/history/logback-error-2019-03-31.log


+ 54 - 0
log/history/logback-info-2019-03-31.log

@@ -0,0 +1,54 @@
+2019-03-31 16:14:53.808 logback [main] INFO  edu.math.diagnosis.BootApplication - Starting BootApplication on DESKTOP-MLVKRVT with PID 17328 (E:\workspace\IdeaProject\yaoxiang\target\classes started by Trace in E:\workspace\IdeaProject\yaoxiang)
+2019-03-31 16:14:53.822 logback [main] INFO  edu.math.diagnosis.BootApplication - The following profiles are active: dev
+2019-03-31 16:14:56.040 logback [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data repositories in DEFAULT mode.
+2019-03-31 16:14:56.212 logback [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 149ms. Found 8 repository interfaces.
+2019-03-31 16:14:56.764 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$550afda3] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-03-31 16:14:56.818 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration' of type [org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration$$EnhancerBySpringCGLIB$$edb8c5dd] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-03-31 16:14:56.822 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'objectPostProcessor' of type [org.springframework.security.config.annotation.configuration.AutowireBeanFactoryObjectPostProcessor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-03-31 16:14:56.824 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler@22752544' of type [org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-03-31 16:14:56.828 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration' of type [org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration$$EnhancerBySpringCGLIB$$128d688f] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-03-31 16:14:56.832 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'methodSecurityMetadataSource' of type [org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-03-31 16:14:57.396 logback [main] INFO  o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8085 (http)
+2019-03-31 16:14:57.410 logback [main] INFO  o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8085"]
+2019-03-31 16:14:57.418 logback [main] INFO  o.a.catalina.core.StandardService - Starting service [Tomcat]
+2019-03-31 16:14:57.418 logback [main] INFO  o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.16]
+2019-03-31 16:14:57.430 logback [main] INFO  o.a.c.core.AprLifecycleListener - The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [D:\java\jdk1.8.0_144\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\TortoiseSVN\bin;C:\Users\Trace\AppData\Local\Microsoft\WindowsApps;C:\Users\Trace\AppData\Local\Programs\Fiddler;C:\Program Files\JetBrains\IntelliJ IDEA 2018.3.5\bin;;D:\Git\bin\;;.]
+2019-03-31 16:14:57.574 logback [main] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
+2019-03-31 16:14:57.574 logback [main] INFO  o.s.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 3679 ms
+2019-03-31 16:14:58.324 logback [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
+2019-03-31 16:15:08.836 logback [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
+2019-03-31 16:15:09.023 logback [main] INFO  o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [
+	name: default
+	...]
+2019-03-31 16:15:09.194 logback [main] INFO  org.hibernate.Version - HHH000412: Hibernate Core {5.3.7.Final}
+2019-03-31 16:15:09.196 logback [main] INFO  org.hibernate.cfg.Environment - HHH000206: hibernate.properties not found
+2019-03-31 16:15:09.541 logback [main] INFO  o.h.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
+2019-03-31 16:15:09.930 logback [main] INFO  org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
+2019-03-31 16:15:11.208 logback [main] INFO  o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
+2019-03-31 16:15:13.604 logback [main] INFO  o.s.b.a.e.web.EndpointLinksResolver - Exposing 2 endpoint(s) beneath base path '/actuator'
+2019-03-31 16:15:13.746 logback [main] INFO  s.d.s.w.PropertySourcedRequestMappingHandlerMapping - Mapped URL path [/v2/api-docs] onto method [public org.springframework.http.ResponseEntity<springfox.documentation.spring.web.json.Json> springfox.documentation.swagger2.web.Swagger2Controller.getDocumentation(java.lang.String,javax.servlet.http.HttpServletRequest)]
+2019-03-31 16:15:13.948 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/resources/**'], []
+2019-03-31 16:15:13.948 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/static/**'], []
+2019-03-31 16:15:13.948 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**.js'], []
+2019-03-31 16:15:13.948 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.js'], []
+2019-03-31 16:15:13.948 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/lang/*.json'], []
+2019-03-31 16:15:13.948 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.css'], []
+2019-03-31 16:15:13.948 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.map'], []
+2019-03-31 16:15:13.949 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.png'], []
+2019-03-31 16:15:13.949 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.jpg'], []
+2019-03-31 16:15:13.949 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/user/**'], []
+2019-03-31 16:15:14.001 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@1b06dc57, org.springframework.security.web.context.SecurityContextPersistenceFilter@50d4775b, org.springframework.security.web.header.HeaderWriterFilter@3d12f065, org.springframework.security.web.authentication.logout.LogoutFilter@28b68067, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@556a6320, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@62e586a6, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@345540f9, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@272c5abd, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5af641d3, org.springframework.security.web.session.SessionManagementFilter@33a7331, org.springframework.security.web.access.ExceptionTranslationFilter@6636448b, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@6f69e2d8]
+2019-03-31 16:15:14.165 logback [main] INFO  o.s.s.c.ThreadPoolTaskExecutor - Initializing ExecutorService 'applicationTaskExecutor'
+2019-03-31 16:15:14.335 logback [main] INFO  o.s.b.a.w.s.WelcomePageHandlerMapping - Adding welcome page: class path resource [static/index.html]
+2019-03-31 16:15:14.715 logback [main] INFO  s.d.s.w.p.DocumentationPluginsBootstrapper - Context refreshed
+2019-03-31 16:15:14.752 logback [main] INFO  s.d.s.w.p.DocumentationPluginsBootstrapper - Found 1 custom documentation plugin(s)
+2019-03-31 16:15:14.782 logback [main] INFO  s.d.s.w.s.ApiListingReferenceScanner - Scanning for api listing references
+2019-03-31 16:15:14.954 logback [main] INFO  s.d.s.w.r.o.CachingOperationNameGenerator - Generating unique operation named: deleteUsingGET_1
+2019-03-31 16:15:15.019 logback [main] INFO  s.d.s.w.r.o.CachingOperationNameGenerator - Generating unique operation named: testUsingGET_1
+2019-03-31 16:15:15.054 logback [main] INFO  o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8085"]
+2019-03-31 16:15:15.097 logback [main] INFO  o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8085 (http) with context path ''
+2019-03-31 16:15:15.099 logback [main] INFO  edu.math.diagnosis.BootApplication - Started BootApplication in 22.303 seconds (JVM running for 24.316)
+2019-03-31 16:15:15.190 logback [main] INFO  o.h.h.i.QueryTranslatorFactoryInitiator - HHH000397: Using ASTQueryTranslatorFactory
+2019-03-31 16:15:15.874 logback [RMI TCP Connection(1)-192.168.50.188] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
+2019-03-31 16:15:15.874 logback [RMI TCP Connection(1)-192.168.50.188] INFO  o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
+2019-03-31 16:15:15.886 logback [RMI TCP Connection(1)-192.168.50.188] INFO  o.s.web.servlet.DispatcherServlet - Completed initialization in 12 ms

+ 70 - 0
log/history/logback-info-2019-04-30.log

@@ -0,0 +1,70 @@
+2019-04-30 09:33:02.947 logback [main] INFO  edu.math.diagnosis.BootApplication - Starting BootApplication on DESKTOP-MLVKRVT with PID 20448 (E:\workspace\IdeaProject\yaoxiang\target\classes started by Trace in E:\workspace\IdeaProject\yaoxiang)
+2019-04-30 09:33:02.947 logback [main] INFO  edu.math.diagnosis.BootApplication - The following profiles are active: dev
+2019-04-30 09:33:05.613 logback [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode!
+2019-04-30 09:33:05.613 logback [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data repositories in DEFAULT mode.
+2019-04-30 09:33:05.801 logback [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 156ms. Found 9 repository interfaces.
+2019-04-30 09:33:06.535 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$f39c88ef] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-04-30 09:33:06.582 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration' of type [org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration$$EnhancerBySpringCGLIB$$8c4a5129] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-04-30 09:33:06.582 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'objectPostProcessor' of type [org.springframework.security.config.annotation.configuration.AutowireBeanFactoryObjectPostProcessor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-04-30 09:33:06.582 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler@56382bc9' of type [org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-04-30 09:33:06.582 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration' of type [org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration$$EnhancerBySpringCGLIB$$b11ef3db] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-04-30 09:33:06.582 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'methodSecurityMetadataSource' of type [org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-04-30 09:33:06.644 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'spring.redis-org.springframework.boot.autoconfigure.data.redis.RedisProperties' of type [org.springframework.boot.autoconfigure.data.redis.RedisProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-04-30 09:33:06.644 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration' of type [org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration$$EnhancerBySpringCGLIB$$8b64739] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-04-30 09:33:06.847 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'lettuceClientResources' of type [io.lettuce.core.resource.DefaultClientResources] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-04-30 09:33:07.083 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'redisConnectionFactory' of type [org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-04-30 09:33:07.083 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'redisConfig' of type [edu.math.diagnosis.config.RedisConfig$$EnhancerBySpringCGLIB$$62b736b0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-04-30 09:33:07.567 logback [main] INFO  io.undertow.servlet - Initializing Spring embedded WebApplicationContext
+2019-04-30 09:33:07.567 logback [main] INFO  o.s.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 4557 ms
+2019-04-30 09:33:08.441 logback [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
+2019-04-30 09:33:09.687 logback [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
+2019-04-30 09:33:09.828 logback [main] INFO  o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [
+	name: default
+	...]
+2019-04-30 09:33:10.006 logback [main] INFO  org.hibernate.Version - HHH000412: Hibernate Core {5.3.7.Final}
+2019-04-30 09:33:10.006 logback [main] INFO  org.hibernate.cfg.Environment - HHH000206: hibernate.properties not found
+2019-04-30 09:33:10.350 logback [main] INFO  o.h.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
+2019-04-30 09:33:10.725 logback [main] INFO  org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQL57Dialect
+2019-04-30 09:33:11.979 logback [main] INFO  o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
+2019-04-30 09:33:12.065 logback [main] INFO  e.m.diagnosis.config.DiagnosisConfig - file d:\diagnosis\uploadTempuploadTemp,mkdir true,create false
+2019-04-30 09:33:12.065 logback [main] INFO  e.m.diagnosis.config.DiagnosisConfig - file d:\diagnosis\upload\docdoc,mkdir true,create false
+2019-04-30 09:33:12.087 logback [main] INFO  e.m.diagnosis.config.DiagnosisConfig - file d:\diagnosis\upload\otherother,mkdir true,create false
+2019-04-30 09:33:12.088 logback [main] INFO  e.m.diagnosis.config.DiagnosisConfig - file d:\diagnosis\upload\imageimage,mkdir true,create false
+2019-04-30 09:33:12.089 logback [main] INFO  e.m.diagnosis.config.DiagnosisConfig - file d:\diagnosis\upload\excelexcel,mkdir true,create false
+2019-04-30 09:33:13.178 logback [main] INFO  edu.math.diagnosis.util.ExcelUtils - docpath: /E:/workspace/IdeaProject/yaoxiang/target/classes/doc/ 
+2019-04-30 09:33:14.566 logback [main] INFO  o.s.b.a.e.web.EndpointLinksResolver - Exposing 17 endpoint(s) beneath base path '/actuator'
+2019-04-30 09:33:14.901 logback [main] INFO  io.lettuce.core.EpollProvider - Starting without optional epoll library
+2019-04-30 09:33:14.901 logback [main] INFO  io.lettuce.core.KqueueProvider - Starting without optional kqueue library
+2019-04-30 09:33:15.797 logback [main] INFO  s.d.s.w.PropertySourcedRequestMappingHandlerMapping - Mapped URL path [/v2/api-docs] onto method [public org.springframework.http.ResponseEntity<springfox.documentation.spring.web.json.Json> springfox.documentation.swagger2.web.Swagger2Controller.getDocumentation(java.lang.String,javax.servlet.http.HttpServletRequest)]
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/resources/**'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/static/**'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**.js'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/upload/**'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.js'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/lang/*.json'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.css'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.map'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.png'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.jpg'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/user/**'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/v2/api-docs'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/swagger-resources/configuration/ui'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/swagger-resources'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/swagger-resources/configuration/security'], []
+2019-04-30 09:33:15.981 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/swagger-ui.html'], []
+2019-04-30 09:33:16.060 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@520eb9f8, org.springframework.security.web.context.SecurityContextPersistenceFilter@106ac5f4, org.springframework.security.web.header.HeaderWriterFilter@58038583, org.springframework.security.web.authentication.logout.LogoutFilter@7b55fc83, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@128d397c, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@55849272, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@4552e288, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@141c66db, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@3ecc9baa, org.springframework.security.web.session.SessionManagementFilter@42fb2be9, org.springframework.security.web.access.ExceptionTranslationFilter@2cdd156b, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@2df24f19]
+2019-04-30 09:33:16.443 logback [main] INFO  o.s.b.a.w.s.WelcomePageHandlerMapping - Adding welcome page: class path resource [static/index.html]
+2019-04-30 09:33:16.971 logback [main] INFO  s.d.s.w.p.DocumentationPluginsBootstrapper - Context refreshed
+2019-04-30 09:33:17.018 logback [main] INFO  s.d.s.w.p.DocumentationPluginsBootstrapper - Found 1 custom documentation plugin(s)
+2019-04-30 09:33:17.050 logback [main] INFO  s.d.s.w.s.ApiListingReferenceScanner - Scanning for api listing references
+2019-04-30 09:33:17.222 logback [main] INFO  s.d.s.w.r.o.CachingOperationNameGenerator - Generating unique operation named: deleteUsingGET_1
+2019-04-30 09:33:17.300 logback [main] INFO  s.d.s.w.r.o.CachingOperationNameGenerator - Generating unique operation named: testUsingGET_1
+2019-04-30 09:33:17.877 logback [main] INFO  o.s.s.a.ScheduledAnnotationBeanPostProcessor - No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
+2019-04-30 09:33:17.915 logback [main] INFO  org.xnio - XNIO version 3.3.8.Final
+2019-04-30 09:33:17.915 logback [main] INFO  org.xnio.nio - XNIO NIO Implementation Version 3.3.8.Final
+2019-04-30 09:33:17.947 logback [main] INFO  o.s.b.w.e.u.UndertowServletWebServer - Undertow started on port(s) 8085 (http) with context path ''
+2019-04-30 09:33:17.947 logback [main] INFO  edu.math.diagnosis.BootApplication - Started BootApplication in 16.266 seconds (JVM running for 18.622)
+2019-04-30 09:33:18.062 logback [main] INFO  o.h.h.i.QueryTranslatorFactoryInitiator - HHH000397: Using ASTQueryTranslatorFactory
+2019-04-30 09:33:18.687 logback [RMI TCP Connection(4)-192.168.50.188] INFO  io.undertow.servlet - Initializing Spring DispatcherServlet 'dispatcherServlet'
+2019-04-30 09:33:18.687 logback [RMI TCP Connection(4)-192.168.50.188] INFO  o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
+2019-04-30 09:33:18.687 logback [RMI TCP Connection(4)-192.168.50.188] INFO  o.s.web.servlet.DispatcherServlet - Completed initialization in 0 ms

+ 3 - 0
log/history/logback-warn-2019-03-31.log

@@ -0,0 +1,3 @@
+2019-03-31 16:14:58.325 logback [main] WARN  c.z.hikari.util.DriverDataSource - Registered driver with driverClassName=com.mysql.jdbc.Driver was not found, trying direct instantiation.
+2019-03-31 16:15:13.422 logback [main] WARN  o.s.b.a.o.j.JpaBaseConfiguration$JpaWebConfiguration$JpaWebMvcConfiguration - spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
+2019-03-31 16:15:14.299 logback [main] WARN  o.t.templatemode.TemplateMode - [THYMELEAF][main] Template Mode 'LEGACYHTML5' is deprecated. Using Template Mode 'HTML' instead.

+ 2 - 0
log/history/logback-warn-2019-04-30.log

@@ -0,0 +1,2 @@
+2019-04-30 09:33:07.536 logback [main] WARN  io.undertow.websockets.jsr - UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used
+2019-04-30 09:33:14.363 logback [main] WARN  o.s.b.a.o.j.JpaBaseConfiguration$JpaWebConfiguration$JpaWebMvcConfiguration - spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning

+ 0 - 0
log/logback-debug-%d{yyyy-MM-dd}.log


+ 339 - 0
log/logback-error-%d{yyyy-MM-dd}.log

@@ -0,0 +1,339 @@
+2019-08-29 20:28:57.781 logback [main] ERROR o.s.boot.SpringApplication - Application run failed
+org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is java.lang.RuntimeException: java.nio.file.InvalidPathException: Illegal char <:> at index 2: /d:/diagnosis/uploadTemp/
+	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:157)
+	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
+	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
+	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
+	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
+	at edu.math.diagnosis.BootApplication.main(BootApplication.java:16)
+Caused by: java.lang.RuntimeException: java.nio.file.InvalidPathException: Illegal char <:> at index 2: /d:/diagnosis/uploadTemp/
+	at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:252)
+	at org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory.createDeploymentManager(UndertowServletWebServerFactory.java:284)
+	at org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory.getWebServer(UndertowServletWebServerFactory.java:208)
+	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:181)
+	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:154)
+	... 8 common frames omitted
+Caused by: java.nio.file.InvalidPathException: Illegal char <:> at index 2: /d:/diagnosis/uploadTemp/
+	at sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
+	at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
+	at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
+	at sun.nio.fs.WindowsPath.parse(WindowsPath.java:94)
+	at sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:255)
+	at java.nio.file.Paths.get(Paths.java:84)
+	at io.undertow.servlet.core.ManagedServlet.setupMultipart(ManagedServlet.java:103)
+	at io.undertow.servlet.spec.ServletRegistrationImpl.setMultipartConfig(ServletRegistrationImpl.java:117)
+	at org.springframework.boot.web.servlet.ServletRegistrationBean.configure(ServletRegistrationBean.java:201)
+	at org.springframework.boot.web.servlet.ServletRegistrationBean.configure(ServletRegistrationBean.java:51)
+	at org.springframework.boot.web.servlet.DynamicRegistrationBean.register(DynamicRegistrationBean.java:115)
+	at org.springframework.boot.web.servlet.RegistrationBean.onStartup(RegistrationBean.java:54)
+	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:235)
+	at org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory$Initializer.onStartup(UndertowServletWebServerFactory.java:616)
+	at io.undertow.servlet.core.DeploymentManagerImpl$1.call(DeploymentManagerImpl.java:203)
+	at io.undertow.servlet.core.DeploymentManagerImpl$1.call(DeploymentManagerImpl.java:185)
+	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:42)
+	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
+	at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:250)
+	... 12 common frames omitted
+2019-08-29 20:29:49.604 logback [XNIO-1 task-1] ERROR io.undertow.request - UT005023: Exception handling request to /login
+org.springframework.security.authentication.BadCredentialsException: user admin with type admin,login from null
+	at edu.math.diagnosis.config.LoginSuccessHandler.onAuthenticationSuccess(LoginSuccessHandler.java:54)
+	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.successfulAuthentication(AbstractAuthenticationProcessingFilter.java:326)
+	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:240)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
+	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
+	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
+	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:151)
+	at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:81)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:117)
+	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:106)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
+	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
+	at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
+	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
+	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
+	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
+	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
+	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
+	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
+	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
+	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
+	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
+	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
+	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
+	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
+	at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
+	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
+	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
+	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
+	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
+	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
+	at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
+	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
+	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:364)
+	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
+	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
+	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
+	at java.lang.Thread.run(Thread.java:748)
+2019-08-29 20:30:05.715 logback [XNIO-1 task-3] ERROR io.undertow.request - UT005023: Exception handling request to /login
+org.springframework.security.authentication.BadCredentialsException: user admin with type admin,login from student
+	at edu.math.diagnosis.config.LoginSuccessHandler.onAuthenticationSuccess(LoginSuccessHandler.java:54)
+	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.successfulAuthentication(AbstractAuthenticationProcessingFilter.java:326)
+	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:240)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
+	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
+	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
+	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:151)
+	at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:81)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:117)
+	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:106)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
+	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
+	at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
+	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
+	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
+	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
+	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
+	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
+	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
+	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
+	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
+	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
+	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
+	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
+	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
+	at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
+	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
+	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
+	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
+	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
+	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
+	at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
+	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
+	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:364)
+	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
+	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
+	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
+	at java.lang.Thread.run(Thread.java:748)
+2019-08-29 20:30:18.080 logback [XNIO-1 task-5] ERROR io.undertow.request - UT005023: Exception handling request to /login
+org.springframework.security.authentication.BadCredentialsException: user admin with type admin,login from student
+	at edu.math.diagnosis.config.LoginSuccessHandler.onAuthenticationSuccess(LoginSuccessHandler.java:54)
+	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.successfulAuthentication(AbstractAuthenticationProcessingFilter.java:326)
+	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:240)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
+	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
+	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
+	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:151)
+	at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:81)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:117)
+	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:106)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
+	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
+	at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
+	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
+	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
+	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
+	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
+	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
+	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
+	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
+	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
+	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
+	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
+	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
+	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
+	at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
+	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
+	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
+	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
+	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
+	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
+	at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
+	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
+	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:364)
+	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
+	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
+	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
+	at java.lang.Thread.run(Thread.java:748)
+2019-08-29 20:34:11.880 logback [XNIO-1 task-9] ERROR io.undertow.request - UT005023: Exception handling request to /login
+org.springframework.security.authentication.BadCredentialsException: user admin with type admin,login from student
+	at edu.math.diagnosis.config.LoginSuccessHandler.onAuthenticationSuccess(LoginSuccessHandler.java:54)
+	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.successfulAuthentication(AbstractAuthenticationProcessingFilter.java:326)
+	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:240)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
+	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
+	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
+	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
+	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:151)
+	at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:81)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:117)
+	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:106)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
+	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
+	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
+	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
+	at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
+	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
+	at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
+	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
+	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
+	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
+	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
+	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
+	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
+	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
+	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
+	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
+	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
+	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
+	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
+	at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
+	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
+	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
+	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
+	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
+	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
+	at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
+	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
+	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:364)
+	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
+	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
+	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
+	at java.lang.Thread.run(Thread.java:748)

+ 93 - 0
log/logback-info-%d{yyyy-MM-dd}.log

@@ -0,0 +1,93 @@
+2019-08-29 20:28:54.596 logback [main] INFO  edu.math.diagnosis.BootApplication - Starting BootApplication on DESKTOP-MLVKRVT with PID 485728 (E:\workspace\IdeaProject\yaoxiang\target\classes started by Trace in E:\workspace\IdeaProject\yaoxiang)
+2019-08-29 20:28:54.602 logback [main] INFO  edu.math.diagnosis.BootApplication - The following profiles are active: dev
+2019-08-29 20:28:56.043 logback [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode!
+2019-08-29 20:28:56.043 logback [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data repositories in DEFAULT mode.
+2019-08-29 20:28:56.174 logback [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 120ms. Found 13 repository interfaces.
+2019-08-29 20:28:56.594 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$c490e24a] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:28:56.630 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration' of type [org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration$$EnhancerBySpringCGLIB$$5d3eaa84] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:28:56.635 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'objectPostProcessor' of type [org.springframework.security.config.annotation.configuration.AutowireBeanFactoryObjectPostProcessor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:28:56.638 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler@286090c' of type [org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:28:56.639 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration' of type [org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration$$EnhancerBySpringCGLIB$$82134d36] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:28:56.643 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'methodSecurityMetadataSource' of type [org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:28:56.678 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'spring.redis-org.springframework.boot.autoconfigure.data.redis.RedisProperties' of type [org.springframework.boot.autoconfigure.data.redis.RedisProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:28:56.685 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration' of type [org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration$$EnhancerBySpringCGLIB$$d9aaa094] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:28:56.770 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'lettuceClientResources' of type [io.lettuce.core.resource.DefaultClientResources] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:28:56.837 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'redisConnectionFactory' of type [org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:28:56.842 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'redisConfig' of type [edu.math.diagnosis.config.RedisConfig$$EnhancerBySpringCGLIB$$33ab900b] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:28:57.181 logback [main] INFO  io.undertow.servlet - Initializing Spring embedded WebApplicationContext
+2019-08-29 20:28:57.182 logback [main] INFO  o.s.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 2533 ms
+2019-08-29 20:28:57.771 logback [main] INFO  o.s.b.a.l.ConditionEvaluationReportLoggingListener - 
+
+Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
+2019-08-29 20:29:23.656 logback [main] INFO  edu.math.diagnosis.BootApplication - Starting BootApplication on DESKTOP-MLVKRVT with PID 487196 (E:\workspace\IdeaProject\yaoxiang\target\classes started by Trace in E:\workspace\IdeaProject\yaoxiang)
+2019-08-29 20:29:23.658 logback [main] INFO  edu.math.diagnosis.BootApplication - The following profiles are active: dev
+2019-08-29 20:29:24.957 logback [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode!
+2019-08-29 20:29:24.958 logback [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data repositories in DEFAULT mode.
+2019-08-29 20:29:25.088 logback [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 122ms. Found 13 repository interfaces.
+2019-08-29 20:29:25.619 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$5ceb791f] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:29:25.663 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration' of type [org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration$$EnhancerBySpringCGLIB$$f5994159] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:29:25.669 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'objectPostProcessor' of type [org.springframework.security.config.annotation.configuration.AutowireBeanFactoryObjectPostProcessor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:29:25.671 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler@3811510' of type [org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:29:25.675 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration' of type [org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration$$EnhancerBySpringCGLIB$$1a6de40b] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:29:25.680 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'methodSecurityMetadataSource' of type [org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:29:25.754 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'spring.redis-org.springframework.boot.autoconfigure.data.redis.RedisProperties' of type [org.springframework.boot.autoconfigure.data.redis.RedisProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:29:25.764 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration' of type [org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration$$EnhancerBySpringCGLIB$$72053769] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:29:25.895 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'lettuceClientResources' of type [io.lettuce.core.resource.DefaultClientResources] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:29:25.967 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'redisConnectionFactory' of type [org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:29:25.971 logback [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'redisConfig' of type [edu.math.diagnosis.config.RedisConfig$$EnhancerBySpringCGLIB$$cc0626e0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2019-08-29 20:29:26.315 logback [main] INFO  io.undertow.servlet - Initializing Spring embedded WebApplicationContext
+2019-08-29 20:29:26.315 logback [main] INFO  o.s.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 2625 ms
+2019-08-29 20:29:26.978 logback [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
+2019-08-29 20:29:28.324 logback [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
+2019-08-29 20:29:28.393 logback [main] INFO  o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [
+	name: default
+	...]
+2019-08-29 20:29:28.468 logback [main] INFO  org.hibernate.Version - HHH000412: Hibernate Core {5.3.7.Final}
+2019-08-29 20:29:28.470 logback [main] INFO  org.hibernate.cfg.Environment - HHH000206: hibernate.properties not found
+2019-08-29 20:29:28.650 logback [main] INFO  o.h.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
+2019-08-29 20:29:28.943 logback [main] INFO  org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQL57Dialect
+2019-08-29 20:29:29.948 logback [main] INFO  o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
+2019-08-29 20:29:30.748 logback [main] INFO  e.math.diagnosis.util.FormulaService - loading OMML2MML.XSL
+2019-08-29 20:29:31.159 logback [main] INFO  e.math.diagnosis.util.FormulaService - load OMML2MML.XSL finish
+2019-08-29 20:29:31.240 logback [main] INFO  edu.math.diagnosis.util.ExcelUtils - docpath: /E:/workspace/IdeaProject/yaoxiang/target/classes/doc/ 
+2019-08-29 20:29:32.199 logback [main] INFO  o.s.b.a.e.web.EndpointLinksResolver - Exposing 17 endpoint(s) beneath base path '/actuator'
+2019-08-29 20:29:32.450 logback [main] INFO  io.lettuce.core.EpollProvider - Starting without optional epoll library
+2019-08-29 20:29:32.451 logback [main] INFO  io.lettuce.core.KqueueProvider - Starting without optional kqueue library
+2019-08-29 20:29:34.024 logback [main] INFO  s.d.s.w.PropertySourcedRequestMappingHandlerMapping - Mapped URL path [/v2/api-docs] onto method [public org.springframework.http.ResponseEntity<springfox.documentation.spring.web.json.Json> springfox.documentation.swagger2.web.Swagger2Controller.getDocumentation(java.lang.String,javax.servlet.http.HttpServletRequest)]
+2019-08-29 20:29:34.196 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/resources/**'], []
+2019-08-29 20:29:34.196 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/static/**'], []
+2019-08-29 20:29:34.196 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**.js'], []
+2019-08-29 20:29:34.196 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/upload/**'], []
+2019-08-29 20:29:34.197 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.js'], []
+2019-08-29 20:29:34.197 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/lang/*.json'], []
+2019-08-29 20:29:34.197 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.css'], []
+2019-08-29 20:29:34.197 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.map'], []
+2019-08-29 20:29:34.197 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.png'], []
+2019-08-29 20:29:34.197 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/**/*.jpg'], []
+2019-08-29 20:29:34.197 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/user/**'], []
+2019-08-29 20:29:34.197 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/v2/api-docs'], []
+2019-08-29 20:29:34.197 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/swagger-resources/configuration/ui'], []
+2019-08-29 20:29:34.197 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/swagger-resources'], []
+2019-08-29 20:29:34.197 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/swagger-resources/configuration/security'], []
+2019-08-29 20:29:34.197 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/swagger-ui.html'], []
+2019-08-29 20:29:34.247 logback [main] INFO  o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@513cd96f, org.springframework.security.web.context.SecurityContextPersistenceFilter@68312b85, org.springframework.security.web.header.HeaderWriterFilter@20a533b, org.springframework.security.web.authentication.logout.LogoutFilter@4ac1544f, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@71eb4ea4, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@6d43c881, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5c6ee543, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5f67ff3e, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@12e04531, org.springframework.security.web.session.SessionManagementFilter@3db48e6, org.springframework.security.web.access.ExceptionTranslationFilter@45b37003, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@26401eda]
+2019-08-29 20:29:34.513 logback [main] INFO  o.s.b.a.w.s.WelcomePageHandlerMapping - Adding welcome page: class path resource [static/index.html]
+2019-08-29 20:29:34.856 logback [main] INFO  s.d.s.w.p.DocumentationPluginsBootstrapper - Context refreshed
+2019-08-29 20:29:34.881 logback [main] INFO  s.d.s.w.p.DocumentationPluginsBootstrapper - Found 1 custom documentation plugin(s)
+2019-08-29 20:29:34.925 logback [main] INFO  s.d.s.w.s.ApiListingReferenceScanner - Scanning for api listing references
+2019-08-29 20:29:35.104 logback [main] INFO  s.d.s.w.r.o.CachingOperationNameGenerator - Generating unique operation named: deleteUsingGET_1
+2019-08-29 20:29:35.181 logback [main] INFO  s.d.s.w.r.o.CachingOperationNameGenerator - Generating unique operation named: testUsingGET_1
+2019-08-29 20:29:35.792 logback [main] INFO  o.s.s.a.ScheduledAnnotationBeanPostProcessor - No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
+2019-08-29 20:29:35.813 logback [main] INFO  org.xnio - XNIO version 3.3.8.Final
+2019-08-29 20:29:35.821 logback [main] INFO  org.xnio.nio - XNIO NIO Implementation Version 3.3.8.Final
+2019-08-29 20:29:35.868 logback [main] INFO  o.s.b.w.e.u.UndertowServletWebServer - Undertow started on port(s) 8085 (http) with context path ''
+2019-08-29 20:29:35.869 logback [main] INFO  edu.math.diagnosis.BootApplication - Started BootApplication in 12.798 seconds (JVM running for 14.377)
+2019-08-29 20:29:35.933 logback [main] INFO  o.h.h.i.QueryTranslatorFactoryInitiator - HHH000397: Using ASTQueryTranslatorFactory
+2019-08-29 20:29:38.567 logback [RMI TCP Connection(2)-172.18.53.225] INFO  io.undertow.servlet - Initializing Spring DispatcherServlet 'dispatcherServlet'
+2019-08-29 20:29:38.567 logback [RMI TCP Connection(2)-172.18.53.225] INFO  o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
+2019-08-29 20:29:38.580 logback [RMI TCP Connection(2)-172.18.53.225] INFO  o.s.web.servlet.DispatcherServlet - Completed initialization in 13 ms
+2019-08-29 20:29:49.474 logback [XNIO-1 task-1] INFO  e.m.d.config.LoginSuccessHandler - user admin with type admin,login from null
+2019-08-29 20:30:05.606 logback [XNIO-1 task-3] INFO  e.m.d.config.LoginSuccessHandler - user admin with type admin,login from student
+2019-08-29 20:30:17.979 logback [XNIO-1 task-5] INFO  e.m.d.config.LoginSuccessHandler - user admin with type admin,login from student
+2019-08-29 20:30:44.832 logback [XNIO-1 task-7] INFO  e.m.d.config.LoginSuccessHandler - user admin with type admin,login from admin
+2019-08-29 20:34:11.686 logback [XNIO-1 task-9] INFO  e.m.d.config.LoginSuccessHandler - user admin with type admin,login from student

+ 4 - 0
log/logback-warn-%d{yyyy-MM-dd}.log

@@ -0,0 +1,4 @@
+2019-08-29 20:28:57.155 logback [main] WARN  io.undertow.websockets.jsr - UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used
+2019-08-29 20:28:57.748 logback [main] WARN  o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is java.lang.RuntimeException: java.nio.file.InvalidPathException: Illegal char <:> at index 2: /d:/diagnosis/uploadTemp/
+2019-08-29 20:29:26.290 logback [main] WARN  io.undertow.websockets.jsr - UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used
+2019-08-29 20:29:32.046 logback [main] WARN  o.s.b.a.o.j.JpaBaseConfiguration$JpaWebConfiguration$JpaWebMvcConfiguration - spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning

+ 191 - 0
pom.xml

@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         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>edu.math</groupId>
+    <artifactId>diagnosis</artifactId>
+    <version>1.0</version>
+    <packaging>jar</packaging>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>1.8</java.version>
+        <docker.plugin.version>1.0.0</docker.plugin.version>
+        <docker.host>http://www.yaoxiangedu.com:23750</docker.host>
+    </properties>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.1.3.RELEASE</version>
+        <relativePath/>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-tomcat</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-undertow</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-thymeleaf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.session</groupId>
+            <artifactId>spring-session-data-redis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>2.8.3</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>net.sourceforge.nekohtml</groupId>
+            <artifactId>nekohtml</artifactId>
+            <version>1.9.15</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>2.8.0</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>2.8.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.8.5</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.7</version>
+        </dependency>
+        <dependency>
+            <groupId>com.deepoove</groupId>
+            <artifactId>poi-tl</artifactId>
+            <version>1.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>3.17</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>3.17</version>
+        </dependency>
+        <dependency>
+            <groupId>fr.opensagres.xdocreport</groupId>
+            <artifactId>xdocreport</artifactId>
+            <version>2.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>ooxml-schemas</artifactId>
+            <version>1.3</version>
+        </dependency>
+        <dependency>
+            <groupId>net.sourceforge.jeuclid</groupId>
+            <artifactId>jeuclid-core</artifactId>
+            <version>3.1.9</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.6</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
+    </dependencies>
+
+    <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-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>docker-maven-plugin</artifactId>
+                <version>${docker.plugin.version}</version>
+                <executions>
+                    <!--执行 mvn package 时 自动 执行 mvn docker:build-->
+                    <!--<execution>-->
+                    <!--<id>build-image</id>-->
+                    <!--<phase>package</phase>-->
+                    <!--<goals>-->
+                    <!--<goal>build</goal>-->
+                    <!--</goals>-->
+                    <!--</execution>-->
+                </executions>
+                <configuration>
+                    <imageName>${project.artifactId}</imageName>
+                    <imageTags>${project.version}</imageTags>
+                    <dockerHost>${docker.host}</dockerHost>
+                    <dockerDirectory>src/main/docker</dockerDirectory>
+                    <resources>
+                        <resource>
+                            <targetPath>/</targetPath>
+                            <directory>${project.build.directory}</directory>
+                            <include>${project.build.finalName}.jar</include>
+                        </resource>
+                    </resources>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 73 - 0
result.html

@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8"/>
+    <script type="text/javascript" async
+            src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=MML_CHTML"></script>
+</head>
+<body><p>Following formulas was found in Word document: </p>
+<p>Formula1:</p>
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+    <msup>
+        <mrow>
+            <mfenced separators="|">
+                <mrow>
+                    <mi>x</mi>
+                    <mo>+</mo>
+                    <mi>a</mi>
+                </mrow>
+            </mfenced>
+        </mrow>
+        <mrow>
+            <mi>n</mi>
+        </mrow>
+    </msup>
+    <mo>=</mo>
+    <mrow>
+        <msubsup>
+            <mo stretchy="true"></mo>
+            <mrow>
+                <mi>k</mi>
+                <mo>=</mo>
+                <mn>0</mn>
+            </mrow>
+            <mrow>
+                <mi>n</mi>
+            </mrow>
+        </msubsup>
+        <mrow>
+            <mfenced separators="|">
+                <mrow>
+                    <mfrac linethickness="0pt">
+                        <mrow>
+                            <mi>n</mi>
+                        </mrow>
+                        <mrow>
+                            <mi>k</mi>
+                        </mrow>
+                    </mfrac>
+                </mrow>
+            </mfenced>
+            <msup>
+                <mrow>
+                    <mi>x</mi>
+                </mrow>
+                <mrow>
+                    <mi>k</mi>
+                </mrow>
+            </msup>
+            <msup>
+                <mrow>
+                    <mi>a</mi>
+                </mrow>
+                <mrow>
+                    <mi>n</mi>
+                    <mo>-</mo>
+                    <mi>k</mi>
+                </mrow>
+            </msup>
+        </mrow>
+    </mrow>
+</math>
+<p/></body>
+</html>

+ 6 - 0
src/main/docker/Dockerfile

@@ -0,0 +1,6 @@
+FROM frolvlad/alpine-java
+VOLUME /tmp
+ADD diagnosis.jar app.jar
+ENV PARAMS=""
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar","--spring.profiles.active=docker","${PARAMS}"]
+EXPOSE 8080

+ 1 - 0
src/main/frontend/README.md

@@ -0,0 +1 @@
+# 前端代码

+ 18 - 0
src/main/java/edu/math/diagnosis/BootApplication.java

@@ -0,0 +1,18 @@
+package edu.math.diagnosis;
+
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/6/29 17:01
+ * @DESCRIPTION:
+ */
+@SpringBootApplication
+public class BootApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(BootApplication.class, args);
+    }
+}

+ 45 - 0
src/main/java/edu/math/diagnosis/cache/DbCache.java

@@ -0,0 +1,45 @@
+package edu.math.diagnosis.cache;
+
+
+import java.util.Date;
+
+public abstract class DbCache {
+
+    //优先级,数字越大,越先加载 默认值50
+    protected volatile int order;
+
+    //标识,默认 default
+    protected volatile String tag = this.getClass().getSimpleName();
+
+    //缓存上一次的刷新时间
+    private volatile Date lastUpdateTime = new Date();
+
+    //缓存刷新状态,有时候刷缓存很费时间,
+    private volatile boolean processing;
+
+    public String tag() {
+        return tag;
+    }
+
+    public abstract void flushData();
+
+    public int order() {
+        return 50;
+    }
+
+    public final void flush() {
+        try {
+//	   		LogService.info(String.format("%s flush start!", name()));
+            flushData();
+            lastUpdateTime = new Date();
+//	   		LogService.info(String.format("%s flush finish!", name()));
+        } catch (Throwable e) {
+//			LogService.info(String.format("%s flush fail!", name()));
+//			LogService.error(e.getMessage(), e);
+        }
+    }
+
+    public Date getLastUpdateTime() {
+        return lastUpdateTime;
+    }
+}

+ 74 - 0
src/main/java/edu/math/diagnosis/cache/DbCacheFactory.java

@@ -0,0 +1,74 @@
+package edu.math.diagnosis.cache;
+
+
+import edu.math.diagnosis.util.ReflectorUtils;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+public enum DbCacheFactory {
+    /**
+     *
+     */
+    INSTACE;
+    private final ConcurrentMap<String, DbCache> dataLoaderMap = new ConcurrentHashMap<String, DbCache>();
+
+    DbCacheFactory() {
+        System.out.println(DbCacheFactory.class.getSimpleName() + " init!");
+        String pack = "edu.math.diagnosis.cache.instance";
+        Set<Class<?>> set = ReflectorUtils.getClasses(pack);
+        for (Class<?> claes : set) {
+            try {
+                if (claes.getName().contains("$")) {
+                    continue;
+                }
+                if (DbCache.class.isAssignableFrom(claes)) {
+                    register((DbCache) claes.newInstance());
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+    public <T extends DbCache> DbCache getDataLoader(final Class<T> requiredClass) {
+        return dataLoaderMap.get(requiredClass.getName());
+    }
+
+
+    public <T extends DbCache> void register(DbCache dbCache) {
+        dataLoaderMap.putIfAbsent(dbCache.getClass().getName(), dbCache);
+    }
+
+    public Collection<DbCache> getAllCache() {
+        return dataLoaderMap.values();
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T getCache(Class<T> claes) {
+        if (claes == null) {
+            return null;
+        }
+        DbCache cache = dataLoaderMap.get(claes.getName());
+        if (cache != null) {
+            return (T) cache;
+        } else {
+            System.out.println(String.format("Get cache fail,class:%s", claes.getName()));
+            return null;
+        }
+    }
+
+    public void flushAll() {
+        long t1 = System.currentTimeMillis();
+        System.out.println("DbCacheFactory.flushAll start flush cache...");
+        List<DbCache> caches = new LinkedList<DbCache>(dataLoaderMap.values());
+        Collections.sort(caches, Comparator.comparingInt(DbCache::order));
+        for (DbCache dbCache : caches) {
+            dbCache.flush();
+        }
+        long t2 = System.currentTimeMillis();
+        System.out.println("DbCacheFactory.flushAll flush cache finish.cost time:" + (t2 - t1));
+    }
+}

+ 16 - 0
src/main/java/edu/math/diagnosis/cache/instance/DbCacheDemo.java

@@ -0,0 +1,16 @@
+package edu.math.diagnosis.cache.instance;
+
+import edu.math.diagnosis.cache.DbCache;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/8/24 16:01
+ * @DESCRIPTION:
+ */
+public class DbCacheDemo extends DbCache {
+
+    @Override
+    public void flushData() {
+        System.out.println("DbCacheDemo flushData");
+    }
+}

+ 43 - 0
src/main/java/edu/math/diagnosis/cache/instance/OptionCache.java

@@ -0,0 +1,43 @@
+package edu.math.diagnosis.cache.instance;
+
+import edu.math.diagnosis.cache.DbCache;
+import edu.math.diagnosis.config.StartUpWork;
+import edu.math.diagnosis.dao.OptionRepo;
+import edu.math.diagnosis.entity.QuestionOption;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author daifengwen
+ */
+public class OptionCache extends DbCache {
+
+    private Map<Long, QuestionOption> optionMap = new HashMap<>();
+    private Map<Long, List<QuestionOption>> questionOptionMap = new HashMap<>();
+
+    @Override
+    public void flushData() {
+        OptionRepo optionRepo = StartUpWork.context.getBean("optionRepo", OptionRepo.class);
+        List<QuestionOption> options = optionRepo.findAll();
+        Map<Long, QuestionOption> temp1 = new HashMap<>(2 * options.size());
+        Map<Long, List<QuestionOption>> temp2 = new HashMap<>();
+        options.forEach((option) -> {
+            temp1.put(option.getId(), option);
+            temp2.putIfAbsent(option.getQid(), new ArrayList<>());
+            temp2.get(option.getQid()).add(option);
+        });
+        optionMap = temp1;
+        questionOptionMap = temp2;
+    }
+
+    public QuestionOption getById(long qid) {
+        return optionMap.get(qid);
+    }
+
+    public List<QuestionOption> getByQid(long qid) {
+        return questionOptionMap.get(qid);
+    }
+}

+ 31 - 0
src/main/java/edu/math/diagnosis/cache/instance/PaperCache.java

@@ -0,0 +1,31 @@
+package edu.math.diagnosis.cache.instance;
+
+import edu.math.diagnosis.cache.DbCache;
+import edu.math.diagnosis.config.StartUpWork;
+import edu.math.diagnosis.dao.PaperRepo;
+import edu.math.diagnosis.entity.Paper;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author daifengwen
+ */
+public class PaperCache extends DbCache {
+
+    private Map<Long, Paper> paperMap = new HashMap<>();
+
+    @Override
+    public void flushData() {
+        PaperRepo paperRepo = StartUpWork.context.getBean("paperRepo", PaperRepo.class);
+        List<Paper> papers = paperRepo.findAll();
+        Map<Long, Paper> temp = new HashMap<>();
+        papers.forEach((paper) -> temp.put(paper.getId(), paper));
+        paperMap = temp;
+    }
+
+    public Paper getById(long pid) {
+        return paperMap.get(pid);
+    }
+}

+ 43 - 0
src/main/java/edu/math/diagnosis/cache/instance/QuestionCache.java

@@ -0,0 +1,43 @@
+package edu.math.diagnosis.cache.instance;
+
+import edu.math.diagnosis.cache.DbCache;
+import edu.math.diagnosis.config.StartUpWork;
+import edu.math.diagnosis.dao.QuestionRepo;
+import edu.math.diagnosis.entity.Question;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author daifengwen
+ */
+public class QuestionCache extends DbCache {
+    private Map<Long, Question> questionMap = new HashMap<>();
+    private Map<Long, List<Question>> paperQuestionMap = new HashMap<>();
+
+    @Override
+    public void flushData() {
+
+        QuestionRepo questionRepo = StartUpWork.context.getBean("questionRepo", QuestionRepo.class);
+        List<Question> questions = questionRepo.findAll();
+        Map<Long, Question> temp1 = new HashMap<>(2 * questions.size());
+        Map<Long, List<Question>> temp2 = new HashMap<>();
+        questions.forEach((question) -> {
+            temp1.put(question.getId(), question);
+            temp2.putIfAbsent(question.getPid(), new ArrayList<>());
+            temp2.get(question.getPid()).add(question);
+        });
+        questionMap = temp1;
+        paperQuestionMap = temp2;
+    }
+
+    public Question getById(long qid) {
+        return questionMap.get(qid);
+    }
+
+    public List<Question> getByPid(long pid) {
+        return paperQuestionMap.get(pid);
+    }
+}

+ 19 - 0
src/main/java/edu/math/diagnosis/config/AjaxAuthenticationEntryPoint.java

@@ -0,0 +1,19 @@
+package edu.math.diagnosis.config;
+
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class AjaxAuthenticationEntryPoint implements AuthenticationEntryPoint {
+
+    @Override
+    public void commence(HttpServletRequest request, HttpServletResponse response,
+                         AuthenticationException authException) throws IOException, ServletException {
+        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+    }
+
+}

+ 14 - 0
src/main/java/edu/math/diagnosis/config/AjaxRequestMatcher.java

@@ -0,0 +1,14 @@
+package edu.math.diagnosis.config;
+
+import org.springframework.security.web.util.matcher.RequestMatcher;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class AjaxRequestMatcher implements RequestMatcher {
+    @Override
+    public boolean matches(HttpServletRequest request) {
+        return "XMLHttpRequest".equals(request.getHeader("X-Requested-With")) ||
+                request.getHeader("Accept") != null &&
+                        request.getHeader("Accept").contains("application/json");
+    }
+}

+ 28 - 0
src/main/java/edu/math/diagnosis/config/ConfigConstants.java

@@ -0,0 +1,28 @@
+package edu.math.diagnosis.config;
+
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class ConfigConstants {
+    public final static String ENTER_EXAM_AUTHORITY = "ENTER_EXAM";
+    public final static String REG_EXAM_AUTHORITY = "REG_EXAM";
+    public final static String HIS_RESULT_AUTHORITY = "HIS_RESULT";
+    public final static String USER_INFO_AUTHORITY = "USER_INFO";
+    public final static String IMPROVE_SCORE_AUTHORITY = "IMPROVE_SCORE";
+    public final static String PAPER_EDIT_AUTHORITY = "PAPER_EDIT";
+    public final static String REPORT_VIEW_AUTHORITY = "REPORT_VIEW";
+
+    public final static List<String> USER_AUTHORITY = Arrays.asList(ENTER_EXAM_AUTHORITY, REG_EXAM_AUTHORITY,
+            HIS_RESULT_AUTHORITY, USER_INFO_AUTHORITY, IMPROVE_SCORE_AUTHORITY);
+    public final static List<String> ADMIN_AUTHORITY = Arrays.asList(ENTER_EXAM_AUTHORITY, REG_EXAM_AUTHORITY,
+            HIS_RESULT_AUTHORITY, USER_INFO_AUTHORITY, IMPROVE_SCORE_AUTHORITY, PAPER_EDIT_AUTHORITY, REPORT_VIEW_AUTHORITY);
+
+    public final static SimpleGrantedAuthority ROLE_ADMIN = new SimpleGrantedAuthority("ROLE_ADMIN");
+    public final static SimpleGrantedAuthority ROLE_USER = new SimpleGrantedAuthority("ROLE_USER");
+    public final static SimpleGrantedAuthority ROLE_GUEST = new SimpleGrantedAuthority("ROLE_GUEST");
+
+    public final static String ROLE_ADMIN_STRING = "ROLE_ADMIN";
+    public final static String ROLE_USER_STRING = "ROLE_USER";
+}

+ 15 - 0
src/main/java/edu/math/diagnosis/config/Constants.java

@@ -0,0 +1,15 @@
+package edu.math.diagnosis.config;
+
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+
+public class Constants {
+    public static final String USER_TYPE_ADMIN = "admin";
+    public static final String USER_TYPE_STUDENT = "student";
+    public static final String USER_TYPE_TEACHER = "teacher";
+    public static final String USER_TYPE_GUEST = "guest";
+
+    public static final SimpleGrantedAuthority USER_ADMIN = new SimpleGrantedAuthority(USER_TYPE_ADMIN);
+    public static final SimpleGrantedAuthority USER_TEACHER = new SimpleGrantedAuthority(USER_TYPE_TEACHER);
+    public static final SimpleGrantedAuthority USER_STUDENT = new SimpleGrantedAuthority(USER_TYPE_STUDENT);
+    public static final SimpleGrantedAuthority USER_GUEST = new SimpleGrantedAuthority(USER_TYPE_GUEST);
+}

+ 31 - 0
src/main/java/edu/math/diagnosis/config/CsrfHeaderFilter.java

@@ -0,0 +1,31 @@
+package edu.math.diagnosis.config;
+
+import org.springframework.security.web.csrf.CsrfToken;
+import org.springframework.web.filter.OncePerRequestFilter;
+import org.springframework.web.util.WebUtils;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class CsrfHeaderFilter extends OncePerRequestFilter {
+    @Override
+    protected void doFilterInternal(HttpServletRequest request,
+                                    HttpServletResponse response, FilterChain filterChain)
+            throws ServletException, IOException {
+        CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
+        if (csrf != null) {
+            Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
+            String token = csrf.getToken();
+            if (cookie == null || token != null && !token.equals(cookie.getValue())) {
+                cookie = new Cookie("XSRF-TOKEN", token);
+                cookie.setPath("/");
+                response.addCookie(cookie);
+            }
+        }
+        filterChain.doFilter(request, response);
+    }
+}

+ 64 - 0
src/main/java/edu/math/diagnosis/config/DiagnosisConfig.java

@@ -0,0 +1,64 @@
+package edu.math.diagnosis.config;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Configuration
+public class DiagnosisConfig {
+
+    @Value("${spring.servlet.multipart.location:d:/tomcat/uploadTemp/}")
+    private String tempLocation;
+    @Value("${uploadLocation:d:/tomcat/upload/}")
+    private String uploadLocation;
+    @Value("${uploadPattern:/upload/**}")
+    private String uploadPattern;
+
+    private static final Logger logger = LoggerFactory.getLogger(DiagnosisConfig.class);
+
+    @Bean
+    public UploadProperties uploadProperties() {
+        String[] dirs = {tempLocation, uploadLocation + UploadProperties.DOC_PATH, uploadLocation + UploadProperties.OTHER_PATH,
+                uploadLocation + UploadProperties.IMAGE_PATH, uploadLocation + UploadProperties.EXCEL_PATH};
+        Arrays.asList(dirs).forEach(dir -> createFile(new File(dir)));
+        UploadProperties properties = new UploadProperties();
+        properties.setTempLocation(tempLocation);
+        properties.setUploadLocation(uploadLocation);
+        properties.setUploadPattern(uploadPattern);
+        return properties;
+    }
+
+    private void createFile(File file) {
+        try {
+            if (!file.exists()) {
+                boolean make = file.mkdirs();
+                boolean create = file.createNewFile();
+                logger.info("file {},mkdir {},create {}", file.getPath() + file.getName(), make, create);
+            }
+        } catch (Exception e) {
+            logger.error("项目环境文件夹无法创建", e);
+        }
+    }
+
+    @Bean
+    public ObjectMapper objectMapper() {
+        return new ObjectMapper()
+                .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
+                .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+    }
+
+    @Bean
+    ExecutorService executorService() {
+        return Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
+    }
+}

+ 53 - 0
src/main/java/edu/math/diagnosis/config/LogOperator.java

@@ -0,0 +1,53 @@
+package edu.math.diagnosis.config;
+
+
+import edu.math.diagnosis.util.SecurityUtil;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
+
+@Component
+@Aspect
+public class LogOperator {
+
+    private final static Logger logger = LoggerFactory.getLogger(LogOperator.class);
+
+    //    @Pointcut("execution(* edu.math.diagnosis.controller..*.*(..))")
+    public void pointCut() {
+    }
+
+    //   @Before("pointCut()")
+    public void doBefore(JoinPoint joinPoint) {
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+        String method = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
+        String username = SecurityUtil.getCurrentUser().getUsername();
+        logger.info(username + " invoke " + method + " at " + new Date());
+    }
+
+  /*  @After("pointCut()")
+    public void doAfter(JoinPoint joinPoint){
+        System.out.println("AOP After Advice...");
+    }
+
+    @Around("pointCut()")
+    public Object around(ProceedingJoinPoint pjp){
+        System.out.println("AOP Aronud before...");
+        try {
+           return pjp.proceed();
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }finally {
+            System.out.println("AOP Aronud after...");
+        }
+        return null;
+    }*/
+
+}

+ 58 - 0
src/main/java/edu/math/diagnosis/config/LoginSuccessHandler.java

@@ -0,0 +1,58 @@
+package edu.math.diagnosis.config;
+
+import edu.math.diagnosis.model.AuthUser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Collection;
+
+/**
+ * Created by Feick on 2018/08/29.
+ */
+public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
+
+    @Value("${web.loginFrom:admin}")
+    private String loginFrom;
+
+    private static final Logger logger = LoggerFactory.getLogger(LoginSuccessHandler.class);
+
+    @Override
+    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
+
+        String loginFrom = request.getParameter("loginFrom");
+
+        AuthUser user = (AuthUser) authentication.getPrincipal();
+        String username = user.getUsername();
+
+        String userType = Constants.USER_TYPE_GUEST;
+        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
+        GrantedAuthority authority = authorities.stream().findFirst().orElse(null);
+        if (authority != null) {
+            userType = authority.getAuthority();
+        }
+
+        String msg = String.format("user %s with type %s,login from %s", username, userType, loginFrom);
+
+        logger.info(msg);
+
+        response.setCharacterEncoding("UTF-8");
+        response.setContentType("application/json");
+
+        if (userType.equals(loginFrom)) {
+            System.out.println("登录通过");
+            response.getWriter().println("{\"ok\":\"1\",\"msg\":\"登录成功\"}");
+        } else {
+            throw new BadCredentialsException(msg);
+        }
+    }
+
+}

+ 21 - 0
src/main/java/edu/math/diagnosis/config/LogoutHandler.java

@@ -0,0 +1,21 @@
+package edu.math.diagnosis.config;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class LogoutHandler implements LogoutSuccessHandler {
+
+    @Override
+    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
+            throws IOException, ServletException {
+        // TODO Auto-generated method stub
+        response.setCharacterEncoding("UTF-8");
+        response.setContentType("application/json");
+        response.getWriter().println("{\"ok\":\"1\",\"msg\":\"注销成功\"}");
+    }
+}

+ 18 - 0
src/main/java/edu/math/diagnosis/config/Md5PasswordEncoder.java

@@ -0,0 +1,18 @@
+package edu.math.diagnosis.config;
+
+import edu.math.diagnosis.util.MD5;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+public class Md5PasswordEncoder implements PasswordEncoder {
+
+    @Override
+    public String encode(CharSequence rawPassword) {
+        return MD5.INSTANCE.md5((String) rawPassword);
+    }
+
+    @Override
+    public boolean matches(CharSequence rawPassword, String encodedPassword) {
+        return encodedPassword.equals(MD5.INSTANCE.md5((String) rawPassword));
+    }
+
+}

+ 36 - 0
src/main/java/edu/math/diagnosis/config/MvcConfig.java

@@ -0,0 +1,36 @@
+package edu.math.diagnosis.config;
+
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import javax.annotation.Resource;
+
+@Configuration
+public class MvcConfig {
+
+    @Resource
+    private UploadProperties uploadProperties;
+
+    @Bean
+    WebMvcConfigurer webMvcConfigurer() {
+        return new WebMvcConfigurer() {
+            @Override
+            public void addViewControllers(ViewControllerRegistry registry) {
+                registry.addViewController("/").setViewName("index");
+                registry.addViewController("/app").setViewName("app");
+                registry.addViewController("/login").setViewName("login");
+                registry.addViewController("/hello").setViewName("hello");
+            }
+
+            public void addResourceHandlers(ResourceHandlerRegistry registry) {
+                registry.addResourceHandler(uploadProperties.getUploadPattern())
+                        .addResourceLocations("file:" + uploadProperties.getUploadLocation());
+            }
+        };
+    }
+
+}

+ 76 - 0
src/main/java/edu/math/diagnosis/config/RedisConfig.java

@@ -0,0 +1,76 @@
+package edu.math.diagnosis.config;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.interceptor.KeyGenerator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.cache.RedisCacheWriter;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializationContext;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+
+import javax.annotation.Resource;
+import java.time.Duration;
+
+/**
+ * Created by 千里明月 on 2018/11/27.
+ */
+@EnableCaching
+@Configuration
+@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 36000)
+public class RedisConfig extends CachingConfigurerSupport {
+
+    @Resource
+    private RedisConnectionFactory redisConnectionFactory;
+
+    //    自定义缓存key生成策略
+    @Bean
+    public KeyGenerator keyGenerator() {
+        return (target, method, params) -> {
+            StringBuilder sb = new StringBuilder();
+            sb.append(target.getClass().getName());
+            sb.append(method.getName());
+            for (Object obj : params) {
+                sb.append(obj.toString());
+            }
+            return sb.toString();
+        };
+    }
+
+    @Bean
+    public RedisTemplate<String, Object> redisTemplate() {
+        RedisTemplate<String, Object> template = new RedisTemplate<>();
+        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class);
+        ObjectMapper om = new ObjectMapper();
+        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
+        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+        serializer.setObjectMapper(om);
+        template.setValueSerializer(serializer);
+        template.setKeySerializer(RedisSerializer.string());
+        template.setDefaultSerializer(serializer);
+        template.setConnectionFactory(redisConnectionFactory);
+        return template;
+    }
+
+    //缓存管理器
+    @Bean
+    public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
+        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
+                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()))
+                .entryTtl(Duration.ofHours(1)); // 设置缓存有效期一小时
+        return RedisCacheManager
+                .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
+                .cacheDefaults(redisCacheConfiguration).build();
+    }
+
+}

+ 36 - 0
src/main/java/edu/math/diagnosis/config/StartUpWork.java

@@ -0,0 +1,36 @@
+package edu.math.diagnosis.config;
+
+import edu.math.diagnosis.cache.DbCacheFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/8/24 16:41
+ * @DESCRIPTION:
+ */
+@Component
+public class StartUpWork implements ApplicationRunner, ApplicationContextAware {
+    public static ApplicationContext context;
+
+    @Override
+    public void run(ApplicationArguments applicationArguments) throws Exception {
+        DbCacheFactory.INSTACE.flushAll();
+        ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1, new CustomizableThreadFactory("sche"));
+        scheduledExecutorService.scheduleAtFixedRate(DbCacheFactory.INSTACE::flushAll, 1, 1, TimeUnit.HOURS);
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        context = applicationContext;
+    }
+}

+ 45 - 0
src/main/java/edu/math/diagnosis/config/Swagger2Config.java

@@ -0,0 +1,45 @@
+package edu.math.diagnosis.config;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+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.EnableSwagger2;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/7/5 20:31
+ * @DESCRIPTION:
+ */
+@Configuration
+@EnableSwagger2
+@Profile("dev")
+@ConditionalOnExpression("${swagger.enabled: true}")
+public class Swagger2Config {
+
+    @Bean
+    public Docket createRestApi() {
+        return new Docket(DocumentationType.SWAGGER_2)
+                .apiInfo(apiInfo())
+                .select()
+                //选择controller包
+                .apis(RequestHandlerSelectors.basePackage("edu.math.diagnosis.controller"))
+                .paths(PathSelectors.any())
+                .build();
+    }
+
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+                //自定义信息可按需求填写
+                .title("Spring Boot中使用Swagger构建RESTful APIs")
+                .description("对接")
+                .version("1.0")
+                .build();
+    }
+}

+ 39 - 0
src/main/java/edu/math/diagnosis/config/UploadProperties.java

@@ -0,0 +1,39 @@
+package edu.math.diagnosis.config;
+
+public class UploadProperties {
+
+    private String uploadPattern;
+    private String tempLocation;
+    private String uploadLocation;
+    public static final String IMAGE_PATH = "image/";
+
+    public static final String DOC_PATH = "doc/";
+
+    public static final String EXCEL_PATH = "excel/";
+
+    public static final String OTHER_PATH = "other/";
+
+    public String getUploadPattern() {
+        return uploadPattern;
+    }
+
+    public void setUploadPattern(String uploadPattern) {
+        this.uploadPattern = uploadPattern;
+    }
+
+    public String getTempLocation() {
+        return tempLocation;
+    }
+
+    public void setTempLocation(String tempLocation) {
+        this.tempLocation = tempLocation;
+    }
+
+    public String getUploadLocation() {
+        return uploadLocation;
+    }
+
+    public void setUploadLocation(String uploadLocation) {
+        this.uploadLocation = uploadLocation;
+    }
+}

+ 17 - 0
src/main/java/edu/math/diagnosis/config/WebAuthenticationProvider.java

@@ -0,0 +1,17 @@
+package edu.math.diagnosis.config;
+
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+public class WebAuthenticationProvider extends DaoAuthenticationProvider {
+
+    public WebAuthenticationProvider() {
+        super();
+    }
+
+    public WebAuthenticationProvider(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
+        setUserDetailsService(userDetailsService);
+        setPasswordEncoder(passwordEncoder);
+    }
+}

+ 143 - 0
src/main/java/edu/math/diagnosis/config/WebSecurityConfig.java

@@ -0,0 +1,143 @@
+package edu.math.diagnosis.config;
+
+import edu.math.diagnosis.entity.UserInfo;
+import edu.math.diagnosis.model.AuthUser;
+import edu.math.diagnosis.service.UserService;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+
+import javax.annotation.Resource;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/8/25 17:34
+ * @DESCRIPTION:
+ */
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Resource
+    private UserService userService;
+    @Resource
+    private UploadProperties uploadProperties;
+
+    @Value("${web.loginPage:/login}")
+    private String loginPage;
+    @Value("${web.logoutUrl:/logout}")
+    private String logoutUrl;
+
+    @Override
+    @Bean
+    public UserDetailsService userDetailsService() { //覆盖写userDetailsService方法 (1)
+        return s -> {
+            UserInfo user = userService.findByUsername(s);
+            if (user == null) {
+                throw new UsernameNotFoundException(s + " not found");
+            }
+            return new AuthUser(user);
+        };
+    }
+
+    @Bean
+    LoginSuccessHandler loginSuccessHandler() {
+        return new LoginSuccessHandler();
+    }
+
+//    @Bean
+//    LoginFailHandle loginFailHandle() {
+//        return new LoginFailHandle();
+//    }
+
+    @Bean
+    LogoutHandler logoutHandler() {
+        return new LogoutHandler();
+    }
+
+    @Bean
+    AjaxAuthenticationEntryPoint ajaxAuthenticationEntryPoint() {
+        return new AjaxAuthenticationEntryPoint();
+    }
+
+    @Bean
+    PasswordEncoder passwordEncoder() {
+        return new Md5PasswordEncoder();
+    }
+
+//    @Bean
+//    WebAuthenticationProvider webAuthenticationProvider() {
+//        return new WebAuthenticationProvider(userDetailsService(), passwordEncoder());
+//    }
+
+    @Bean
+    WebAuthenticationDetailsSource webAuthenticationDetailsSource() {
+        return new WebAuthenticationDetailsSource();
+    }
+
+
+    /**
+     * If subclassed this will potentially override subclass configure(HttpSecurity)
+     *
+     * @param http
+     * @throws Exception
+     */
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.csrf().disable();
+        http.headers().cacheControl().disable();
+        http.headers().frameOptions().sameOrigin();
+
+        http.authorizeRequests().antMatchers("/").permitAll();
+        http.authorizeRequests().anyRequest().authenticated();
+//        http.formLogin().loginPage("/login").defaultSuccessUrl("/app", true).permitAll();
+
+        http.formLogin().loginPage(loginPage).successHandler(loginSuccessHandler())
+//                .failureHandler(loginFailHandle())
+                .authenticationDetailsSource(webAuthenticationDetailsSource());
+//        http.logout().logoutUrl("/logout").permitAll();
+        http.logout()
+                // .logoutSuccessHandler(erebusLogoutSuccessHandler)
+                .logoutUrl(logoutUrl).logoutRequestMatcher(new AntPathRequestMatcher(logoutUrl)).deleteCookies("JSESSIONID")
+                .logoutSuccessHandler(logoutHandler());
+        http.sessionManagement().invalidSessionUrl(loginPage);
+
+//        http.authenticationProvider(new WebAuthenticationProvider());
+
+//        http.userDetailsService(userDetailsService());
+
+        http.exceptionHandling().defaultAuthenticationEntryPointFor(ajaxAuthenticationEntryPoint(), new AjaxRequestMatcher());
+        super.configure(http);
+    }
+
+    @Override
+    public void configure(WebSecurity web) throws Exception {
+        web.ignoring().antMatchers("/resources/**", "/static/**", "/**.js");
+        web.ignoring().antMatchers(uploadProperties.getUploadPattern());
+        web.ignoring().antMatchers("/**/*.js", "/lang/*.json", "/**/*.css", "/**/*.map", "/**/*.png", "/**/*.jpg");
+        web.ignoring().antMatchers("/user/**");
+        web.ignoring().antMatchers("/v2/api-docs",//swagger api json
+                "/swagger-resources/configuration/ui",//用来获取支持的动作
+                "/swagger-resources",//用来获取api-docs的URI
+                "/swagger-resources/configuration/security",//安全选项
+                "/swagger-ui.html");
+    }
+
+    @Override
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+        auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
+    }
+
+}

+ 467 - 0
src/main/java/edu/math/diagnosis/controller/CommitController.java

@@ -0,0 +1,467 @@
+package edu.math.diagnosis.controller;
+
+import edu.math.diagnosis.cache.DbCacheFactory;
+import edu.math.diagnosis.cache.instance.OptionCache;
+import edu.math.diagnosis.cache.instance.QuestionCache;
+import edu.math.diagnosis.dao.CommitRepo;
+import edu.math.diagnosis.dao.UserRepo;
+import edu.math.diagnosis.entity.*;
+import edu.math.diagnosis.model.AuthUser;
+import edu.math.diagnosis.model.ResponseMessage;
+import edu.math.diagnosis.util.NumberUtil;
+import edu.math.diagnosis.util.ObjectUtils;
+import edu.math.diagnosis.util.SecurityUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/7/6 17:55
+ * @DESCRIPTION:
+ */
+@RestController
+@RequestMapping("/commit")
+public class CommitController {
+    @Resource
+    CommitRepo commitRepo;
+    @Resource
+    UserRepo userRepo;
+
+    private final OptionCache OptionCache = DbCacheFactory.INSTACE.getCache(OptionCache.class);
+    private final QuestionCache QuestionCache = DbCacheFactory.INSTACE.getCache(QuestionCache.class);
+
+    @RequestMapping(value = "/paper", method = RequestMethod.POST)
+    public ResponseMessage commitPaper(@RequestBody Paper paper) {
+        AuthUser authUser = SecurityUtil.getCurrentUser();
+        Commit commit = new Commit();
+        paper.getQuestions().forEach((question -> {
+            question.setOptions(null);
+            question.setUpdatetime(null);
+            question.setCreatetime(null);
+            question.setContent(null);
+            question.setWrongDesc(null);
+        }));
+        paper.setCreatetime(null);
+        paper.setUpdatetime(null);
+        String data = ObjectUtils.Object2Json(paper);
+        commit.setData(data);
+        long uid = authUser.getUser().getId();
+        long pid = paper.getId();
+        commit.setUid(uid);
+        commit.setPid(pid);
+        double point = calculatePoint(paper);
+        commit.setScore(point);
+        commit.setCreatetime(new Date());
+        commitRepo.saveAndFlush(commit);
+        return ResponseMessage.getInstance(200, NumberUtil.formatDouble(point));
+    }
+
+    private double calculatePoint(Paper paper) {
+        double result = 0.0;
+        List<Question> questions = paper.getQuestions();
+        double total = 0;
+        for (Question question : questions) {
+            double score = (question.getCalculation() + question.getConversion() + question.getInduction() + question.getLanguage() + question.getLogic() + question.getSpace());
+            total += score;
+            if (judgeQuestion(question)) {
+                result += score;
+            }
+        }
+        if (total == 0) {
+            return 0;
+        } else {
+            return (result / total) * 100;
+        }
+    }
+
+    private boolean judgeQuestion(Question question) {
+        String ans = question.getAns();
+        if (StringUtils.isEmpty(ans)) {
+            return false;
+        }
+        String[] options = StringUtils.splitByWholeSeparatorPreserveAllTokens(ans, ",");
+        if (options.length == question.getCorrectNum()) {
+            for (String option : options) {
+                long o = Long.parseLong(option);
+                QuestionOption questionOption = OptionCache.getById(o);
+                if (questionOption == null || !questionOption.isCorrect()) {
+                    return false;
+                }
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @RequestMapping(value = "/check", method = RequestMethod.GET)
+    public boolean checkPaper(@RequestParam long pid) {
+        AuthUser authUser = SecurityUtil.getCurrentUser();
+        long uid = authUser.getUser().getId();
+        int cnt = commitRepo.countByUidAndPid(uid, pid);
+        return cnt < 1;
+    }
+
+    public PaperReport generateReport(Paper paper, long uid) {
+        UserInfo userInfo = userRepo.getOne(uid);
+        PaperReport paperReport = new PaperReport();
+        paperReport.setName(userInfo.getName());
+        paperReport.setUid(uid);
+        paperReport.setPid(paper.getId());
+        paperReport.setPaperName(paper.getName());
+        paperReport.setGenerateTime(new Date());
+        Map<Integer, SectionReport> sectionReportMap = new HashMap<>(4);
+        sectionReportMap.put(1, new SectionReport(1));
+        sectionReportMap.put(2, new SectionReport(2));
+        sectionReportMap.put(3, new SectionReport(3));
+        paperReport.setSectionReportMap(sectionReportMap);
+        List<Question> questions = paper.getQuestions();
+        double total = 0;
+        double result = 0.0;
+        for (Question question : questions) {
+            int section = Math.abs(question.getSection());
+            SectionReport sectionReport = sectionReportMap.get(section);
+            double score = (question.getCalculation() + question.getConversion() + question.getInduction() + question.getLanguage() + question.getLogic() + question.getSpace());
+            fillReportTotalScore(question, paperReport);
+            fillReportTotalScore(question, sectionReport);
+            total += score;
+            double sectionTotalScore = sectionReport.getTotalScore();
+            sectionReport.setTotalScore(sectionTotalScore + score);
+            QuestionCommit questionCommit = new QuestionCommit();
+            questionCommit.setAns(question.getAns());
+            questionCommit.setQid(question.getId());
+            questionCommit.setUsetime(question.getUsetime());
+            questionCommit.setCorrect(false);
+            sectionReport.getMap().put(question.getId(), questionCommit);
+            if (judgeQuestion(question)) {
+                questionCommit.setCorrect(true);
+                result += score;
+                double setionScore = sectionReport.getScore();
+                sectionReport.setScore(setionScore + score);
+                fillReportScore(question, paperReport);
+                fillReportScore(question, sectionReport);
+            }
+        }
+        paperReport.setTotalScore(total);
+        paperReport.setScore(result);
+        return paperReport;
+    }
+
+    private double getDoubleValue(Double d) {
+        if (d == null) {
+            return 0;
+        } else {
+            return d;
+        }
+    }
+
+    private void fillReportTotalScore(Question question, BaseReport report) {
+        double totalCalculationScore = getDoubleValue(report.getTotalCalculationScore());
+        report.setTotalCalculationScore(totalCalculationScore + question.getCalculation());
+
+        double totalConversionScore = getDoubleValue(report.getTotalConversionScore());
+        report.setTotalConversionScore(totalConversionScore + question.getConversion());
+
+        double totalInductionScore = getDoubleValue(report.getTotalInductionScore());
+        report.setTotalInductionScore(totalInductionScore + question.getInduction());
+
+        double totalLanguageScore = getDoubleValue(report.getTotalLanguageScore());
+        report.setTotalLanguageScore(totalLanguageScore + question.getLanguage());
+
+        double totalLogicScore = getDoubleValue(report.getTotalLogicScore());
+        report.setTotalLogicScore(totalLogicScore + question.getLogic());
+
+        double totalSpaceScore = getDoubleValue(report.getTotalSpaceScore());
+        report.setTotalSpaceScore(totalSpaceScore + question.getSpace());
+    }
+
+    private void fillReportScore(Question question, BaseReport report) {
+        double calculationScore = getDoubleValue(report.getCalculationScore());
+        report.setCalculationScore(calculationScore + question.getCalculation());
+
+        double conversionScore = getDoubleValue(report.getConversionScore());
+        report.setConversionScore(conversionScore + question.getConversion());
+
+        double inductionScore = getDoubleValue(report.getInductionScore());
+        report.setInductionScore(inductionScore + question.getInduction());
+
+        double languageScore = getDoubleValue(report.getLanguageScore());
+        report.setLanguageScore(languageScore + question.getLanguage());
+
+        double logicScore = getDoubleValue(report.getLogicScore());
+        report.setLogicScore(logicScore + question.getLogic());
+
+        double spaceScore = getDoubleValue(report.getSpaceScore());
+        report.setSpaceScore(spaceScore + question.getSpace());
+    }
+}
+
+class BaseReport {
+    private Double totalScore = new Double(0);
+    private Double score = new Double(0);
+    private Double totalCalculationScore = new Double(0);
+    private Double calculationScore = new Double(0);
+    private Double totalInductionScore = new Double(0);
+    private Double inductionScore = new Double(0);
+    private Double totalLogicScore = new Double(0);
+    private Double logicScore = new Double(0);
+    private Double totalSpaceScore = new Double(0);
+    private Double spaceScore = new Double(0);
+    private Double totalLanguageScore = new Double(0);
+    private Double languageScore = new Double(0);
+    private Double totalConversionScore = new Double(0);
+    private Double conversionScore = new Double(0);
+
+    public Double getTotalScore() {
+        return totalScore;
+    }
+
+    public void setTotalScore(Double totalScore) {
+        this.totalScore = totalScore;
+    }
+
+    public Double getScore() {
+        return score;
+    }
+
+    public void setScore(Double score) {
+        this.score = score;
+    }
+
+    public Double getTotalCalculationScore() {
+        return totalCalculationScore;
+    }
+
+    public void setTotalCalculationScore(Double totalCalculationScore) {
+        this.totalCalculationScore = totalCalculationScore;
+    }
+
+    public Double getCalculationScore() {
+        return calculationScore;
+    }
+
+    public void setCalculationScore(Double calculationScore) {
+        this.calculationScore = calculationScore;
+    }
+
+    public Double getTotalInductionScore() {
+        return totalInductionScore;
+    }
+
+    public void setTotalInductionScore(Double totalInductionScore) {
+        this.totalInductionScore = totalInductionScore;
+    }
+
+    public Double getInductionScore() {
+        return inductionScore;
+    }
+
+    public void setInductionScore(Double inductionScore) {
+        this.inductionScore = inductionScore;
+    }
+
+    public Double getTotalLogicScore() {
+        return totalLogicScore;
+    }
+
+    public void setTotalLogicScore(Double totalLogicScore) {
+        this.totalLogicScore = totalLogicScore;
+    }
+
+    public Double getLogicScore() {
+        return logicScore;
+    }
+
+    public void setLogicScore(Double logicScore) {
+        this.logicScore = logicScore;
+    }
+
+    public Double getTotalSpaceScore() {
+        return totalSpaceScore;
+    }
+
+    public void setTotalSpaceScore(Double totalSpaceScore) {
+        this.totalSpaceScore = totalSpaceScore;
+    }
+
+    public Double getSpaceScore() {
+        return spaceScore;
+    }
+
+    public void setSpaceScore(Double spaceScore) {
+        this.spaceScore = spaceScore;
+    }
+
+    public Double getTotalLanguageScore() {
+        return totalLanguageScore;
+    }
+
+    public void setTotalLanguageScore(Double totalLanguageScore) {
+        this.totalLanguageScore = totalLanguageScore;
+    }
+
+    public Double getLanguageScore() {
+        return languageScore;
+    }
+
+    public void setLanguageScore(Double languageScore) {
+        this.languageScore = languageScore;
+    }
+
+    public Double getTotalConversionScore() {
+        return totalConversionScore;
+    }
+
+    public void setTotalConversionScore(Double totalConversionScore) {
+        this.totalConversionScore = totalConversionScore;
+    }
+
+    public Double getConversionScore() {
+        return conversionScore;
+    }
+
+    public void setConversionScore(Double conversionScore) {
+        this.conversionScore = conversionScore;
+    }
+}
+
+class PaperReport extends BaseReport {
+    private String name;
+    private Long uid;
+    private Long pid;
+    private String paperName;
+    private Date generateTime;
+    private Map<Integer, SectionReport> sectionReportMap;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Long getUid() {
+        return uid;
+    }
+
+    public void setUid(Long uid) {
+        this.uid = uid;
+    }
+
+    public Long getPid() {
+        return pid;
+    }
+
+    public void setPid(Long pid) {
+        this.pid = pid;
+    }
+
+    public String getPaperName() {
+        return paperName;
+    }
+
+    public void setPaperName(String paperName) {
+        this.paperName = paperName;
+    }
+
+    public Date getGenerateTime() {
+        return generateTime;
+    }
+
+    public void setGenerateTime(Date generateTime) {
+        this.generateTime = generateTime;
+    }
+
+    public Map<Integer, SectionReport> getSectionReportMap() {
+        return sectionReportMap;
+    }
+
+    public void setSectionReportMap(Map<Integer, SectionReport> sectionReportMap) {
+        this.sectionReportMap = sectionReportMap;
+    }
+}
+
+class SectionReport extends BaseReport {
+    private int section;
+
+    private Map<Long, QuestionCommit> map;
+
+    public SectionReport(int section) {
+        this.section = section;
+        map = new HashMap<>();
+    }
+
+    public SectionReport() {
+    }
+
+    public int getSection() {
+        return section;
+    }
+
+    public void setSection(int section) {
+        this.section = section;
+    }
+
+    public Map<Long, QuestionCommit> getMap() {
+        return map;
+    }
+
+    public void setMap(Map<Long, QuestionCommit> map) {
+        this.map = map;
+    }
+}
+
+class QuestionCommit {
+    private long qid;
+    private String ans;
+    private int usetime;
+    private String correctAns;
+    private boolean correct;
+
+    public long getQid() {
+        return qid;
+    }
+
+    public void setQid(long qid) {
+        this.qid = qid;
+    }
+
+    public String getAns() {
+        return ans;
+    }
+
+    public void setAns(String ans) {
+        this.ans = ans;
+    }
+
+    public int getUsetime() {
+        return usetime;
+    }
+
+    public void setUsetime(int usetime) {
+        this.usetime = usetime;
+    }
+
+    public String getCorrectAns() {
+        return correctAns;
+    }
+
+    public void setCorrectAns(String correctAns) {
+        this.correctAns = correctAns;
+    }
+
+    public boolean isCorrect() {
+        return correct;
+    }
+
+    public void setCorrect(boolean correct) {
+        this.correct = correct;
+    }
+}

+ 64 - 0
src/main/java/edu/math/diagnosis/controller/FileController.java

@@ -0,0 +1,64 @@
+package edu.math.diagnosis.controller;
+
+import edu.math.diagnosis.model.ResponseMessage;
+import edu.math.diagnosis.service.FileService;
+import edu.math.diagnosis.util.aliyun.OSSUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/7/5 21:52
+ * @DESCRIPTION:
+ */
+@RestController
+@RequestMapping("/file")
+@Api(tags = "文件管理")
+@PreAuthorize("hasRole('ROLE_ADMIN')")
+public class FileController {
+
+    @Resource
+    private FileService fileService;
+
+    @RequestMapping(value = "/img", method = RequestMethod.PUT)
+    public ResponseMessage uploadImg(@RequestParam MultipartFile file) {
+        String file_name = null;
+        try {
+            int suffixIndex = file.getOriginalFilename().lastIndexOf(".");
+            String suffix = file.getOriginalFilename().substring(suffixIndex);
+            file_name = OSSUtil.INSTANCE.putFile(file.getInputStream(), suffix);
+            return ResponseMessage.getInstance(200, file_name);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return ResponseMessage.getInstance(500, "error");
+    }
+
+    @ApiOperation(value = "上传文件")
+    @PostMapping(value = "/upload", consumes = "multipart/*", headers = "content-type=multipart/form-data")
+    public ResponseMessage uploadFile(@ApiParam(value = "文件") @RequestParam MultipartFile file) {
+        try {
+            int suffixIndex = file.getOriginalFilename().lastIndexOf(".");
+            String suffix = file.getOriginalFilename().substring(suffixIndex);
+            return ResponseMessage.getInstance(200, OSSUtil.INSTANCE.putFile(file.getInputStream(), suffix));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return ResponseMessage.getInstance(500, "error");
+    }
+
+    @GetMapping("download/{path}/{filename}")
+    @ApiOperation("使用方式 curl localhost:8085/file/download/doc/xx.docx")
+    public ResponseEntity<byte[]> download(@PathVariable String path, @PathVariable String filename) throws Exception {
+        return fileService.download(path + "/" + filename);
+    }
+
+}

+ 42 - 0
src/main/java/edu/math/diagnosis/controller/OptionController.java

@@ -0,0 +1,42 @@
+package edu.math.diagnosis.controller;
+
+import edu.math.diagnosis.entity.Question;
+import edu.math.diagnosis.entity.QuestionOption;
+import edu.math.diagnosis.service.OptionService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+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 javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * Created by 千里明月 on 2018/7/15.
+ */
+@RestController
+@RequestMapping("/option")
+@Api(tags = "选项管理")
+@PreAuthorize("hasRole('ROLE_ADMIN')")
+public class OptionController {
+    @Resource
+    private OptionService optionService;
+
+    @ApiOperation(value = "查询所有选项")
+    @RequestMapping(value = "/listOptions", method = RequestMethod.GET)
+    public List<QuestionOption> listOptions(@RequestParam Long qid) {
+        Question question = new Question();
+        question.setId(qid);
+        return optionService.listOptionByQuestion(question);
+    }
+
+    @ApiOperation(value = "删除选项")
+    @RequestMapping(value = "/delete", method = RequestMethod.GET)
+    public boolean delete(@RequestParam Long id) {
+        return optionService.delete(id);
+    }
+
+}

+ 99 - 0
src/main/java/edu/math/diagnosis/controller/PaperController.java

@@ -0,0 +1,99 @@
+package edu.math.diagnosis.controller;
+
+import edu.math.diagnosis.entity.Paper;
+import edu.math.diagnosis.model.PaperVo;
+import edu.math.diagnosis.model.Result;
+import edu.math.diagnosis.service.LocalFileService;
+import edu.math.diagnosis.service.PaperService;
+import edu.math.diagnosis.util.CommonUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.util.FileCopyUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/7/5 20:26
+ * @DESCRIPTION:
+ */
+@RestController
+@RequestMapping("/paper")
+@Api(tags = "试卷管理")
+
+public class PaperController {
+
+    @Resource
+    PaperService paperService;
+    //    @Resource
+//    private FileService fileService;
+    @Resource
+    private LocalFileService localFileService;
+
+    //   @PreAuthorize("hasRole('ROLE_ADMIN')")
+    @ApiOperation(value = "查询所有试卷")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "status", value = "已完成:aleady  未完成:notaleady;  不填则代表全部", paramType = "query"),
+    })
+    @RequestMapping(value = "/listPapers", method = RequestMethod.GET)
+    public List<Paper> listPapers(String status) {
+        return paperService.listPapers(status);
+    }
+
+    @ApiOperation(value = "查询单个试卷  ")
+    @RequestMapping(value = "/getOnePaper/{id}", method = RequestMethod.GET)
+    public Paper getOnePaper(@PathVariable Long id) {
+        return paperService.getOnePaper(id);
+    }
+
+    @PreAuthorize("hasRole('ROLE_ADMIN')")
+    @ApiOperation(value = "新增试卷")
+    @RequestMapping(value = "/add", method = RequestMethod.POST)
+    public Result add(@RequestBody Paper paper) {
+        return paperService.add(paper);
+    }
+
+    @PreAuthorize("hasRole('ROLE_ADMIN')")
+    @ApiOperation(value = "编辑试卷")
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public Result update(@RequestBody Paper paper) {
+        return paperService.update(paper);
+    }
+
+    @PreAuthorize("hasRole('ROLE_ADMIN')")
+    @ApiOperation(value = "删除试卷")
+    @RequestMapping(value = "/delete", method = RequestMethod.GET)
+    public void delete(@RequestParam Long id) {
+        paperService.delete(id);
+    }
+
+    @PreAuthorize("hasRole('ROLE_ADMIN')")
+    @ApiOperation(value = "上传试卷")
+    @PostMapping("uploadPaper")
+    @ApiImplicitParam(name = "templateId", value = "试卷模板Id 默认1")
+    public Result uploadPaper(PaperVo paperVo, @RequestParam(defaultValue = "1") Long templateId,
+                              @RequestBody MultipartFile file) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        FileCopyUtils.copy(file.getInputStream(), baos);
+        int suffixIndex = file.getOriginalFilename().lastIndexOf(".");
+        String suffix = file.getOriginalFilename().substring(suffixIndex);
+        String saveName = CommonUtil.randomUUID() + suffix;
+        byte[] data = baos.toByteArray();
+//        byte[] clone = data.clone();
+//        String url = fileService.upload(data, UploadProperties.DOC_PATH, saveName);
+        String url = localFileService.upload(data, saveName);
+        if (StringUtils.isEmpty(url)) {
+            return Result.fail("文件上传失败,请重试");
+        }
+        return paperService.uploadPaper(paperVo, templateId, url, data);
+    }
+}

+ 84 - 0
src/main/java/edu/math/diagnosis/controller/QuestionController.java

@@ -0,0 +1,84 @@
+package edu.math.diagnosis.controller;
+
+import edu.math.diagnosis.config.UploadProperties;
+import edu.math.diagnosis.entity.Question;
+import edu.math.diagnosis.model.Result;
+import edu.math.diagnosis.service.QuestionService;
+import edu.math.diagnosis.util.DateUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.annotation.Secured;
+import org.springframework.util.FileCopyUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Created by 千里明月 on 2018/7/15.
+ */
+@RestController
+@RequestMapping("/question")
+@Api(tags = "题目管理")
+@Secured("ROLE_ADMIN")
+public class QuestionController {
+    @Resource
+    private QuestionService questionService;
+    @Resource
+    private UploadProperties properties;
+    @Resource
+    private ExecutorService executorService;
+
+    @ApiOperation(value = "增加 试题")
+    @RequestMapping(value = "/addQuestionForPaper", method = RequestMethod.POST)
+    public Result addQuestionForPaper(@RequestBody Question question) {
+        return questionService.addQuestion(question);
+    }
+
+    @ApiOperation(value = "修改 试题")
+    @RequestMapping(value = "/updateQuestionForPaper", method = RequestMethod.POST)
+    public Result updateQuestionForPaper(@RequestBody Question question) {
+        return questionService.updateQuestion(question);
+    }
+
+    @ApiOperation(value = "查询 试题  ")
+    @RequestMapping(value = "/getQuestion", method = RequestMethod.GET)
+    public Question getQuestion(@RequestParam Long id) {
+        return questionService.getQuestion(id);
+    }
+
+    @ApiOperation(value = "删除 试题  ")
+    @RequestMapping(value = "/deleteQuestion", method = RequestMethod.GET)
+    public void deleteQuestion(@RequestParam Long id) {
+        questionService.deleteQuestion(id);
+    }
+
+    @PostMapping("uploadQuestion")
+    @ApiOperation("试卷上传测试")
+    @ApiImplicitParams({@ApiImplicitParam(name = "pid", value = "试卷Id", paramType = "query"),
+            @ApiImplicitParam(name = "section", value = "模块编号", paramType = "query"),
+            @ApiImplicitParam(name = "number", value = "题目编号 可无,默认最大编号", paramType = "query")
+    })
+    public Result uploadQuestion(Long pid, Integer section, @RequestParam(required = false) Integer number,
+                                 @RequestBody MultipartFile file) throws Exception {
+        String date = DateUtil.format(new Date(), "yyMMdd_HHmmss_");
+        //暂时缓存到本地
+        String saveName = properties.getUploadLocation() + date + file.getOriginalFilename();
+        byte[] data = file.getBytes();
+        byte[] clone = data.clone();
+        executorService.submit(() -> {
+            try {
+                FileCopyUtils.copy(clone, new File(saveName));
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        });
+        return questionService.parseQuestion(pid, section, number, data);
+    }
+}

+ 61 - 0
src/main/java/edu/math/diagnosis/controller/TempController.java

@@ -0,0 +1,61 @@
+package edu.math.diagnosis.controller;
+
+import edu.math.diagnosis.model.GeneralInfo;
+import edu.math.diagnosis.model.Report;
+import edu.math.diagnosis.util.ExcelUtils;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/getTempPapers")
+@PreAuthorize("hasRole('ROLE_ADMIN')")
+public class TempController {
+
+    @Resource
+    private ExcelUtils excelUtils;
+
+    @RequestMapping(value = "/getGeneralInfo", method = RequestMethod.GET)
+    public GeneralInfo getCorrectInfo() {
+        GeneralInfo info = new GeneralInfo();
+        info.setCorrectOptions(excelUtils.getCorrectAns());
+        info.setRates(excelUtils.getCorrectRate());
+        info.setAbilityAveScore(excelUtils.getAbilityAveScore());
+        info.setCurveGraph(excelUtils.getCurveGraph());
+
+        return info;
+    }
+
+    @RequestMapping(value = "/getReportData", method = RequestMethod.GET)
+    public List<Report> getPaperData() {
+        List<Report> reports = new ArrayList<>(81);
+        List<String> names = excelUtils.getNames();
+        Map<String, List<String>> optionMap = excelUtils.getOptions();
+        Map<String, List<Integer>> optionRwMap = excelUtils.getOptionRw();
+        Map<String, List<String>> optionCommentMap = excelUtils.getOptionCommentMap(optionRwMap);
+        Map<String, List<Integer>> abilityLevelMap = excelUtils.getAbilityLevel();
+        Map<String, List<Double>> abilityScoreMap = excelUtils.getAbilityScore();
+        Map<String, List<String>> abilityCommentMap = excelUtils.getAbilityWords(abilityLevelMap, abilityScoreMap);
+        Map<String, Integer> scoreMap = excelUtils.getTotalScore();
+        for (String name : names) {
+            Report report = new Report();
+            report.setName(name);
+            report.setOptions(optionMap.get(name));
+            report.setAbilityComments(abilityCommentMap.get(name));
+            report.setAbilityLevel(abilityLevelMap.get(name));
+            report.setRw(optionRwMap.get(name));
+            report.setComments(optionCommentMap.get(name));
+            report.setAbilityScore(abilityScoreMap.get(name));
+            report.setTotalScore(scoreMap.get(name));
+            reports.add(report);
+        }
+
+        return reports;
+    }
+}

+ 109 - 0
src/main/java/edu/math/diagnosis/controller/TestController.java

@@ -0,0 +1,109 @@
+package edu.math.diagnosis.controller;
+
+import edu.math.diagnosis.dao.CommitRepo;
+import edu.math.diagnosis.dao.OptionRepo;
+import edu.math.diagnosis.dao.QuestionRepo;
+import edu.math.diagnosis.entity.Commit;
+import edu.math.diagnosis.entity.Paper;
+import edu.math.diagnosis.entity.Question;
+import edu.math.diagnosis.model.AuthUser;
+import edu.math.diagnosis.util.ObjectUtils;
+import edu.math.diagnosis.util.SecurityUtil;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/6/29 17:18
+ * @DESCRIPTION:
+ */
+@RestController
+public class TestController {
+    @Resource
+    OptionRepo optionRepo;
+    @Resource
+    QuestionRepo questionRepo;
+
+    @Resource
+    CommitRepo commitRepo;
+
+    @Resource
+    CommitController commitController;
+
+    private AtomicLong visitCount = new AtomicLong();
+
+    @PreAuthorize("hasRole('ROLE_USER')")
+    @RequestMapping(value = "/test", method = RequestMethod.GET)
+    public String test() {
+        long cnt = visitCount.incrementAndGet();
+        String name = SecurityUtil.getCurrentUser().getUser().getName();
+        return name + " , Now is " + new Date() + "  and visit times : " + cnt;
+    }
+
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER')")
+    @RequestMapping(value = "/test2", method = RequestMethod.GET)
+    public String test2() {
+        long cnt = visitCount.incrementAndGet();
+        String name = SecurityUtil.getCurrentUser().getUser().getName();
+        return name + " , Now is " + new Date() + "  and visit times : " + cnt;
+    }
+
+    @GetMapping("/info")
+    public AuthUser auth() {
+        AuthUser user = SecurityUtil.getCurrentUser();
+        return user;
+    }
+
+    @PreAuthorize("hasRole('ROLE_ADMIN')")
+    @GetMapping("/temp")
+    public List<PaperReport> temp() {
+        List<PaperReport> result = new ArrayList<>();
+        List<Commit> commitList = commitRepo.findAll();
+        for (Commit commit : commitList) {
+            Paper paper = ObjectUtils.Json2Object(commit.getData(), Paper.class);
+            PaperReport paperReport = commitController.generateReport(paper, commit.getUid());
+            result.add(paperReport);
+            //		System.out.println(ObjectUtils.Object2Json(paperReport));
+        }
+        return result;
+    }
+
+    @PreAuthorize("hasRole('ROLE_ADMIN')")
+    @GetMapping("/temp1")
+    public void temp1() {
+        List<Question> questions = questionRepo.findByPid(7);
+        questions.sort((q1, q2) -> {
+            int s1 = Math.abs(q1.getSection());
+            int s2 = Math.abs(q2.getSection());
+            if (s2 > s1) {
+                return -1;
+            } else if (s2 == s1) {
+                if (q1.getSection() > q2.getSection()) {
+                    return 1;
+                } else if (q1.getSection() < q2.getSection()) {
+                    return -1;
+                } else {
+                    return 0;
+                }
+
+            } else {
+                return 1;
+            }
+        });
+        Integer num = 1;
+        for (Question question : questions) {
+            question.setNumber(num++);
+            questionRepo.save(question);
+        }
+    }
+
+}

+ 45 - 0
src/main/java/edu/math/diagnosis/controller/UserInfoController.java

@@ -0,0 +1,45 @@
+package edu.math.diagnosis.controller;
+
+import edu.math.diagnosis.config.ConfigConstants;
+import edu.math.diagnosis.entity.UserInfo;
+import edu.math.diagnosis.model.AuthUser;
+import edu.math.diagnosis.util.SecurityUtil;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping("/self")
+public class UserInfoController {
+
+
+    /**
+     * 获取当前用户有权限使用的功能模块
+     *
+     * @return
+     */
+    @GetMapping("/authority")
+    public List<String> getAuthorities() {
+        AuthUser user = SecurityUtil.getCurrentUser();
+//        if (user.getAuthorities().contains(ConfigConstants.ROLE_ADMIN)) {
+//            return ConfigConstants.ADMIN_AUTHORITY;
+//        } else if (user.getAuthorities().contains(ConfigConstants.ROLE_USER)) {
+//            return ConfigConstants.USER_AUTHORITY;
+//        }
+        return new ArrayList<>();
+    }
+
+    /**
+     * 获取当前用户的信息
+     *
+     * @return
+     */
+    @GetMapping("/info")
+    public UserInfo getInfo() {
+        AuthUser user = SecurityUtil.getCurrentUser();
+        return user.getUser();
+    }
+}

+ 43 - 0
src/main/java/edu/math/diagnosis/controller/UserManagerController.java

@@ -0,0 +1,43 @@
+package edu.math.diagnosis.controller;
+
+import edu.math.diagnosis.entity.UserInfo;
+import edu.math.diagnosis.service.UserService;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.Date;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/8/25 17:53
+ * @DESCRIPTION:
+ */
+@RestController
+@RequestMapping("/user")
+public class UserManagerController {
+    @Resource
+    UserService userService;
+
+    @PostMapping(value = "/add")
+    public Long addUser(@RequestBody UserInfo user) {
+        return userService.addUser(user);
+    }
+
+    @GetMapping(value = "/test")
+    public String test() {
+        return new Date() + "";
+    }
+
+    @ApiOperation(value = "校验手机号码是否可用(已被注册)", notes = "true : 可用 false : 不可用")
+    @GetMapping(value = "/checkPhone")
+    public boolean checkPhone(@RequestParam String phone) {
+        return userService.checkPhone(phone);
+    }
+
+    @ApiOperation(value = "校验用户名是否可用(已被注册)", notes = "true : 可用 false : 不可用")
+    @GetMapping(value = "/checkUsername")
+    public boolean checkUsername(@RequestParam String username) {
+        return userService.checkUsername(username);
+    }
+}

+ 7 - 0
src/main/java/edu/math/diagnosis/dao/AuthorityRepo.java

@@ -0,0 +1,7 @@
+package edu.math.diagnosis.dao;
+
+import edu.math.diagnosis.entity.Authority;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AuthorityRepo extends JpaRepository<Authority, Long> {
+}

+ 8 - 0
src/main/java/edu/math/diagnosis/dao/CommitRepo.java

@@ -0,0 +1,8 @@
+package edu.math.diagnosis.dao;
+
+import edu.math.diagnosis.entity.Commit;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface CommitRepo extends JpaRepository<Commit, Long> {
+    int countByUidAndPid(long uid, long pid);
+}

+ 20 - 0
src/main/java/edu/math/diagnosis/dao/OptionRepo.java

@@ -0,0 +1,20 @@
+package edu.math.diagnosis.dao;
+
+import edu.math.diagnosis.entity.QuestionOption;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/7/3 10:12
+ * @DESCRIPTION:
+ */
+@Repository
+public interface OptionRepo extends JpaRepository<QuestionOption, Long> {
+    List<QuestionOption> findByQid(long qid);
+
+    List<QuestionOption> findByIdIn(List<Long> ids);
+
+}

+ 12 - 0
src/main/java/edu/math/diagnosis/dao/PaperCommitRepo.java

@@ -0,0 +1,12 @@
+package edu.math.diagnosis.dao;
+
+import edu.math.diagnosis.entity.PaperCommit;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/7/7 11:54
+ * @DESCRIPTION:
+ */
+public interface PaperCommitRepo extends JpaRepository<PaperCommit, Long> {
+}

+ 14 - 0
src/main/java/edu/math/diagnosis/dao/PaperRepo.java

@@ -0,0 +1,14 @@
+package edu.math.diagnosis.dao;
+
+import edu.math.diagnosis.entity.Paper;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/7/3 10:12
+ * @DESCRIPTION:
+ */
+@Repository
+public interface PaperRepo extends JpaRepository<Paper, Long> {
+}

+ 14 - 0
src/main/java/edu/math/diagnosis/dao/PaperResultRepo.java

@@ -0,0 +1,14 @@
+package edu.math.diagnosis.dao;
+
+import edu.math.diagnosis.entity.PaperResult;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/7/3 10:13
+ * @DESCRIPTION:
+ */
+@Repository
+public interface PaperResultRepo extends JpaRepository<PaperResult, Long> {
+}

+ 11 - 0
src/main/java/edu/math/diagnosis/dao/PaperTemplateRepo.java

@@ -0,0 +1,11 @@
+package edu.math.diagnosis.dao;
+
+import edu.math.diagnosis.entity.PaperTemplate;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface PaperTemplateRepo extends JpaRepository<PaperTemplate, Long> {
+    //    @Modifying
+//    @Query("update ShopCoupon sc set sc.deleted = true where sc.id in :ids")
+}

+ 19 - 0
src/main/java/edu/math/diagnosis/dao/QuestionRepo.java

@@ -0,0 +1,19 @@
+package edu.math.diagnosis.dao;
+
+import edu.math.diagnosis.entity.Question;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/7/3 10:10
+ * @DESCRIPTION:
+ */
+@Repository
+public interface QuestionRepo extends JpaRepository<Question, Long> {
+    List<Question> findByPidOrderBySectionAscNumberAsc(long pid);
+
+    List<Question> findByPid(long pid);
+}

+ 12 - 0
src/main/java/edu/math/diagnosis/dao/ReportRepo.java

@@ -0,0 +1,12 @@
+package edu.math.diagnosis.dao;
+
+import edu.math.diagnosis.entity.DiagnosisReport;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/7/7 12:14
+ * @DESCRIPTION:
+ */
+public interface ReportRepo extends JpaRepository<DiagnosisReport, Long> {
+}

+ 11 - 0
src/main/java/edu/math/diagnosis/dao/RoleRepo.java

@@ -0,0 +1,11 @@
+package edu.math.diagnosis.dao;
+
+import edu.math.diagnosis.entity.Commit;
+import edu.math.diagnosis.entity.Role;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface RoleRepo extends JpaRepository<Role, Long> {
+
+}

+ 11 - 0
src/main/java/edu/math/diagnosis/dao/SectionRepo.java

@@ -0,0 +1,11 @@
+package edu.math.diagnosis.dao;
+
+import edu.math.diagnosis.entity.Section;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface SectionRepo extends JpaRepository<Section, Long> {
+
+    List<Section> findByPidOrderByNumber(Long pid);
+}

+ 11 - 0
src/main/java/edu/math/diagnosis/dao/SubjectRepo.java

@@ -0,0 +1,11 @@
+package edu.math.diagnosis.dao;
+
+import edu.math.diagnosis.entity.Subject;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface SubjectRepo extends JpaRepository<Subject, Long> {
+
+    Subject findByName(String name);
+}

+ 19 - 0
src/main/java/edu/math/diagnosis/dao/UserRepo.java

@@ -0,0 +1,19 @@
+package edu.math.diagnosis.dao;
+
+import edu.math.diagnosis.entity.UserInfo;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/8/24 18:26
+ * @DESCRIPTION:
+ */
+public interface UserRepo extends JpaRepository<UserInfo, Long> {
+    UserInfo findByUsername(String username);
+
+    UserInfo findByPhone(String phone);
+
+    int countByPhone(String phone);
+
+    int countByUsername(String username);
+}

+ 94 - 0
src/main/java/edu/math/diagnosis/entity/AbilityScore.java

@@ -0,0 +1,94 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@ApiModel("科目能力分数")
+public class AbilityScore {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @ApiModelProperty("能力Id")
+    private String abilityId;
+
+    @ApiModelProperty("能力")
+    private String ability;
+
+    @Column(nullable = false)
+    @ApiModelProperty("关联类型 commit paper question")
+    private String relatedType;
+
+    @Column(nullable = false)
+    @ApiModelProperty("关联")
+    private Long relatedId;
+
+    @Column(nullable = false, columnDefinition = "double(10,2) default 0")
+    @ApiModelProperty("能力分数")
+    private Double score;
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getAbilityId() {
+        return abilityId;
+    }
+
+    public void setAbilityId(String abilityId) {
+        this.abilityId = abilityId;
+    }
+
+    public String getAbility() {
+        return ability;
+    }
+
+    public void setAbility(String ability) {
+        this.ability = ability;
+    }
+
+    public String getRelatedType() {
+        return relatedType;
+    }
+
+    public void setRelatedType(String relatedType) {
+        this.relatedType = relatedType;
+    }
+
+    public Long getRelatedId() {
+        return relatedId;
+    }
+
+    public void setRelatedId(Long relatedId) {
+        this.relatedId = relatedId;
+    }
+
+    public Double getScore() {
+        return score;
+    }
+
+    public void setScore(Double score) {
+        this.score = score;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+}

+ 39 - 0
src/main/java/edu/math/diagnosis/entity/Authority.java

@@ -0,0 +1,39 @@
+package edu.math.diagnosis.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class Authority {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    private String name;
+    private String des;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDes() {
+        return des;
+    }
+
+    public void setDes(String des) {
+        this.des = des;
+    }
+}

+ 41 - 0
src/main/java/edu/math/diagnosis/entity/BaseMatter.java

@@ -0,0 +1,41 @@
+package edu.math.diagnosis.entity;
+
+
+import io.swagger.annotations.ApiModel;
+
+import javax.persistence.*;
+
+@Entity
+@ApiModel("学业/情绪问题")
+public class BaseMatter {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    @Column(nullable = false)
+    private Long name;
+    private Long code;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getName() {
+        return name;
+    }
+
+    public void setName(Long name) {
+        this.name = name;
+    }
+
+    public Long getCode() {
+        return code;
+    }
+
+    public void setCode(Long code) {
+        this.code = code;
+    }
+}

+ 68 - 0
src/main/java/edu/math/diagnosis/entity/CommentAfterExam.java

@@ -0,0 +1,68 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import org.hibernate.annotations.CreationTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@ApiModel("用户试卷评价")
+public class CommentAfterExam {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column(nullable = false)
+    private Long pid;
+
+    @Column(nullable = false)
+    private Long uid;
+
+    @Lob
+    @Column(nullable = false)
+    private String comment;
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getPid() {
+        return pid;
+    }
+
+    public void setPid(Long pid) {
+        this.pid = pid;
+    }
+
+    public Long getUid() {
+        return uid;
+    }
+
+    public void setUid(Long uid) {
+        this.uid = uid;
+    }
+
+    public String getComment() {
+        return comment;
+    }
+
+    public void setComment(String comment) {
+        this.comment = comment;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+}

+ 87 - 0
src/main/java/edu/math/diagnosis/entity/Commit.java

@@ -0,0 +1,87 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import org.hibernate.annotations.CreationTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@ApiModel("答案提交")
+@Table(name = "commit", indexes = @Index(name = "IDX_UID_PID", columnList = "uid,pid"))
+public class Commit {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    @Column(nullable = false)
+    private Long uid;
+    @Column(nullable = false)
+    private Long pid;
+
+    @Lob
+    @Column(nullable = false)
+    private String data;
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+    @Column(nullable = false, columnDefinition = "double(10,2) default 0")
+    private Double score;
+    @Transient
+    private Paper paper;
+
+    public long getPid() {
+        return pid;
+    }
+
+    public void setPid(long pid) {
+        this.pid = pid;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public long getUid() {
+        return uid;
+    }
+
+    public void setUid(long uid) {
+        this.uid = uid;
+    }
+
+    public String getData() {
+        return data;
+    }
+
+    public void setData(String data) {
+        this.data = data;
+    }
+
+    public Paper getPaper() {
+        return paper;
+    }
+
+    public void setPaper(Paper paper) {
+        this.paper = paper;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public double getScore() {
+        return score;
+    }
+
+    public void setScore(double score) {
+        this.score = score;
+    }
+}

+ 60 - 0
src/main/java/edu/math/diagnosis/entity/CommonMatter.java

@@ -0,0 +1,60 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+
+import javax.persistence.*;
+
+@Entity
+@ApiModel("通用问题")
+public class CommonMatter {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    @Column(nullable = false)
+    private String name;
+    private String code;
+    @Column(nullable = false)
+    private String mistakeMatter;
+    @Column(nullable = false)
+    private String baseMatter;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMistakeMatter() {
+        return mistakeMatter;
+    }
+
+    public void setMistakeMatter(String mistakeMatter) {
+        this.mistakeMatter = mistakeMatter;
+    }
+
+    public String getBaseMatter() {
+        return baseMatter;
+    }
+
+    public void setBaseMatter(String baseMatter) {
+        this.baseMatter = baseMatter;
+    }
+}

+ 96 - 0
src/main/java/edu/math/diagnosis/entity/DiagnosisReport.java

@@ -0,0 +1,96 @@
+package edu.math.diagnosis.entity;
+
+import edu.math.diagnosis.model.QuestionDetail;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/7/6 17:58
+ * @DESCRIPTION: 诊断报告
+ */
+@Entity
+@ApiModel("测试报告")
+public class DiagnosisReport {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    @Column(nullable = false)
+    @ApiModelProperty("试卷答案Id")
+    private Long prid;
+    @Column(nullable = false)
+    private String name;
+
+    @Lob
+    @Column(nullable = false)
+    @ApiModelProperty("结论")
+    private String conclusion;
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+    @Transient
+    private PaperResult pr;
+    @Transient
+    private List<QuestionDetail> details;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getPrid() {
+        return prid;
+    }
+
+    public void setPrid(Long prid) {
+        this.prid = prid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getConclusion() {
+        return conclusion;
+    }
+
+    public void setConclusion(String conclusion) {
+        this.conclusion = conclusion;
+    }
+
+    public PaperResult getPr() {
+        return pr;
+    }
+
+    public void setPr(PaperResult pr) {
+        this.pr = pr;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public List<QuestionDetail> getDetails() {
+        return details;
+    }
+
+    public void setDetails(List<QuestionDetail> details) {
+        this.details = details;
+    }
+}

+ 114 - 0
src/main/java/edu/math/diagnosis/entity/KnowledgeMatter.java

@@ -0,0 +1,114 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@ApiModel("知识点问题")
+public class KnowledgeMatter {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    private String name;
+    private String code;
+    @ApiModelProperty("年级 1-12 X-Y 1X表示1年级上")
+    private String grade;
+
+    private Long subjectId;
+
+    private String commonMatter;
+    private String mistakeMatter;
+    private String baseMatter;
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+    @UpdateTimestamp
+    @Column(nullable = false)
+    private Date updatetime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getGrade() {
+        return grade;
+    }
+
+    public void setGrade(String grade) {
+        this.grade = grade;
+    }
+
+    public Long getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(Long subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public String getCommonMatter() {
+        return commonMatter;
+    }
+
+    public void setCommonMatter(String commonMatter) {
+        this.commonMatter = commonMatter;
+    }
+
+    public String getMistakeMatter() {
+        return mistakeMatter;
+    }
+
+    public void setMistakeMatter(String mistakeMatter) {
+        this.mistakeMatter = mistakeMatter;
+    }
+
+    public String getBaseMatter() {
+        return baseMatter;
+    }
+
+    public void setBaseMatter(String baseMatter) {
+        this.baseMatter = baseMatter;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+}

+ 50 - 0
src/main/java/edu/math/diagnosis/entity/MistakeMatter.java

@@ -0,0 +1,50 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+
+import javax.persistence.*;
+
+@Entity
+@ApiModel("家长误认为的问题")
+public class MistakeMatter {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    @Column(nullable = false)
+    private String name;
+    private String code;
+    @Column(nullable = false)
+    private String baseMatter;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getBaseMatter() {
+        return baseMatter;
+    }
+
+    public void setBaseMatter(String baseMatter) {
+        this.baseMatter = baseMatter;
+    }
+}

+ 277 - 0
src/main/java/edu/math/diagnosis/entity/Paper.java

@@ -0,0 +1,277 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/6/25 18:00
+ * @DESCRIPTION: 试卷
+ */
+@Entity
+@ApiModel("试卷")
+public class Paper {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column(nullable = false)
+    @ApiModelProperty("试卷名称")
+    private String name;
+
+    @Column(nullable = false)
+    @ApiModelProperty("题目数量")
+    private Integer questionNum;
+
+    @Lob
+    @Column
+    @ApiModelProperty("题目说明")
+    private String remark;
+
+    @Column(nullable = false)
+    @ApiModelProperty("年级 1-12 X-Y 1X表示1年级上")
+    private String grade;//1 2 3 4 5 6 7 8 9 10 11 12 年级 1-12
+
+    @Column
+    @ApiModelProperty("试卷编号,编号格式为年级-上/下-顺序/模拟,均两位编码,如8年级上(一) 表示为080101")
+    private String code;
+
+    @Column
+    @ApiModelProperty("总分")
+    private Integer totalScore;
+
+    @ApiModelProperty("试卷时长,单位为分钟")
+    @Column(nullable = false, columnDefinition = " int(11) default 60")
+    private Integer duration;//试卷时长,该考试多久结束,单位分钟
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+    @UpdateTimestamp
+    @Column(nullable = false)
+    private Date updatetime;
+
+    @Column(nullable = false, columnDefinition = " varchar(255) default '20,20,20'")
+    @ApiModelProperty("各模块题目数量,以','隔开,单位为分钟 50,10,10")
+    private String sectionNums;
+
+    @Column(nullable = false, columnDefinition = " varchar(255) default '20,20,20'")
+    @ApiModelProperty("各模块完成时间,以','隔开,单位为分钟 30,30,30")
+    private String sectionDurations;
+
+    @Column(nullable = false, columnDefinition = " varchar(255) default '2,2,2'")
+    @ApiModelProperty("各模块休息时间,以','隔开,单位为分钟 2,2,2")
+    private String sectionRests;
+
+    @Column(nullable = false, columnDefinition = " int(11) default 1")
+    @ApiModelProperty("试卷是否有效,是否已完成编辑,0无效,1有效")
+    private Integer status;//0:无效  1:有效
+
+    @Column
+    @ApiModelProperty("上传文档的位置,可无")
+    private String docxUrl;
+
+    @Column(nullable = false, columnDefinition = "  varchar(255) default '1'")
+    @ApiModelProperty("试卷类型Id")
+    private Long typeId;
+
+    @Column(nullable = false, columnDefinition = "  varchar(255) default '2'")
+    @ApiModelProperty("科目类别Id")
+    private Long subjectId;
+
+    @Lob
+    @Column
+    @ApiModelProperty("试卷分数 可无")
+    private String jsonScore;
+
+    @Transient
+    private List<Section> sections;
+
+    @Transient
+    private List<Question> questions;
+
+    @Transient
+    private List<AbilityScore> scores;
+
+    public Paper(Long id) {
+        this.id = id;
+    }
+
+    public Paper() {
+
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getQuestionNum() {
+        return questionNum;
+    }
+
+    public void setQuestionNum(Integer questionNum) {
+        this.questionNum = questionNum;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public String getGrade() {
+        return grade;
+    }
+
+    public void setGrade(String grade) {
+        this.grade = grade;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public Integer getTotalScore() {
+        return totalScore;
+    }
+
+    public void setTotalScore(Integer totalScore) {
+        this.totalScore = totalScore;
+    }
+
+    public Integer getDuration() {
+        return duration;
+    }
+
+    public void setDuration(Integer duration) {
+        this.duration = duration;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+
+    public String getSectionNums() {
+        return sectionNums;
+    }
+
+    public void setSectionNums(String sectionNums) {
+        this.sectionNums = sectionNums;
+    }
+
+    public String getSectionDurations() {
+        return sectionDurations;
+    }
+
+    public void setSectionDurations(String sectionDurations) {
+        this.sectionDurations = sectionDurations;
+    }
+
+    public String getSectionRests() {
+        return sectionRests;
+    }
+
+    public void setSectionRests(String sectionRests) {
+        this.sectionRests = sectionRests;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public String getDocxUrl() {
+        return docxUrl;
+    }
+
+    public void setDocxUrl(String docxUrl) {
+        this.docxUrl = docxUrl;
+    }
+
+    public Long getTypeId() {
+        return typeId;
+    }
+
+    public void setTypeId(Long typeId) {
+        this.typeId = typeId;
+    }
+
+    public Long getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(Long subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public String getJsonScore() {
+        return jsonScore;
+    }
+
+    public void setJsonScore(String jsonScore) {
+        this.jsonScore = jsonScore;
+    }
+
+    public List<Section> getSections() {
+        return sections;
+    }
+
+    public void setSections(List<Section> sections) {
+        this.sections = sections;
+    }
+
+    public List<Question> getQuestions() {
+        return questions;
+    }
+
+    public void setQuestions(List<Question> questions) {
+        this.questions = questions;
+    }
+
+    public List<AbilityScore> getScores() {
+        return scores;
+    }
+
+    public void setScores(List<AbilityScore> scores) {
+        this.scores = scores;
+    }
+}

+ 144 - 0
src/main/java/edu/math/diagnosis/entity/PaperCommit.java

@@ -0,0 +1,144 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/7/6 17:53
+ * @DESCRIPTION:
+ */
+@Entity
+@ApiModel("试卷提交")
+public class PaperCommit {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    @Column(nullable = false)
+    private Long pid;
+
+    @Column(nullable = false)
+    private Long uid;
+
+    @Column(nullable = false)
+    @ApiModelProperty("用户姓名")
+    private String name;
+
+    @Lob
+    @Column(nullable = false)
+    @ApiModelProperty("答案json化")
+    private String jsonAns;
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+
+    @Column(nullable = false)
+    @ApiModelProperty("是否已生成报告")
+    private boolean generateReport;
+
+    @Column(nullable = false)
+    @ApiModelProperty("用时,单位秒")
+    private int useTime;
+
+    @Column(nullable = false)
+    private Date beginTime;
+    @Column(nullable = false)
+    private Date endTime;
+    @Transient
+    private Map<Long, List<Long>> ans;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getPid() {
+        return pid;
+    }
+
+    public void setPid(Long pid) {
+        this.pid = pid;
+    }
+
+    public Long getUid() {
+        return uid;
+    }
+
+    public void setUid(Long uid) {
+        this.uid = uid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getJsonAns() {
+        return jsonAns;
+    }
+
+    public void setJsonAns(String jsonAns) {
+        this.jsonAns = jsonAns;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public boolean isGenerateReport() {
+        return generateReport;
+    }
+
+    public void setGenerateReport(boolean generateReport) {
+        this.generateReport = generateReport;
+    }
+
+    public Map<Long, List<Long>> getAns() {
+        return ans;
+    }
+
+    public void setAns(Map<Long, List<Long>> ans) {
+        this.ans = ans;
+    }
+
+    public int getUseTime() {
+        return useTime;
+    }
+
+    public void setUseTime(int useTime) {
+        this.useTime = useTime;
+    }
+
+    public Date getBeginTime() {
+        return beginTime;
+    }
+
+    public void setBeginTime(Date beginTime) {
+        this.beginTime = beginTime;
+    }
+
+    public Date getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Date endTime) {
+        this.endTime = endTime;
+    }
+}

+ 162 - 0
src/main/java/edu/math/diagnosis/entity/PaperResult.java

@@ -0,0 +1,162 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/6/25 18:02
+ * @DESCRIPTION: 对应一份试卷的成绩
+ */
+@Entity
+public class PaperResult {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    @Column(nullable = false, columnDefinition = "double(10,2) default 0")
+    private Double score;
+    private String name;//考生姓名
+    @Column(nullable = false)
+    private String uid;
+    @Column(nullable = false)
+    private Long pid;
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+    @Column(nullable = false, columnDefinition = "double(10,2) default 0")
+    private Double score1;
+    @Column(nullable = false, columnDefinition = "double(10,2) default 0")
+    private Double score2;
+    @Column(nullable = false, columnDefinition = "double(10,2) default 0")
+    private Double score3;
+    @Column(nullable = false, columnDefinition = "double(10,2) default 0")
+    private Double score4;
+    @Column(nullable = false, columnDefinition = "double(10,2) default 0")
+    private Double score5;
+    @Column(nullable = false, columnDefinition = "double(10,2) default 0")
+    private Double score6;
+
+    @Lob
+    @Column(nullable = false)
+    @ApiModelProperty("试卷分数")
+    private String jsonScore;
+
+    @Transient
+    private List<AbilityScore> scores;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Double getScore() {
+        return score;
+    }
+
+    public void setScore(Double score) {
+        this.score = score;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getUid() {
+        return uid;
+    }
+
+    public void setUid(String uid) {
+        this.uid = uid;
+    }
+
+    public Long getPid() {
+        return pid;
+    }
+
+    public void setPid(Long pid) {
+        this.pid = pid;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Double getScore1() {
+        return score1;
+    }
+
+    public void setScore1(Double score1) {
+        this.score1 = score1;
+    }
+
+    public Double getScore2() {
+        return score2;
+    }
+
+    public void setScore2(Double score2) {
+        this.score2 = score2;
+    }
+
+    public Double getScore3() {
+        return score3;
+    }
+
+    public void setScore3(Double score3) {
+        this.score3 = score3;
+    }
+
+    public Double getScore4() {
+        return score4;
+    }
+
+    public void setScore4(Double score4) {
+        this.score4 = score4;
+    }
+
+    public Double getScore5() {
+        return score5;
+    }
+
+    public void setScore5(Double score5) {
+        this.score5 = score5;
+    }
+
+    public Double getScore6() {
+        return score6;
+    }
+
+    public void setScore6(Double score6) {
+        this.score6 = score6;
+    }
+
+    public String getJsonScore() {
+        return jsonScore;
+    }
+
+    public void setJsonScore(String jsonScore) {
+        this.jsonScore = jsonScore;
+    }
+
+    public List<AbilityScore> getScores() {
+        return scores;
+    }
+
+    public void setScores(List<AbilityScore> scores) {
+        this.scores = scores;
+    }
+}

+ 194 - 0
src/main/java/edu/math/diagnosis/entity/PaperTemplate.java

@@ -0,0 +1,194 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * Created by Feick on 4/10/2019.
+ */
+@Entity
+@ApiModel("题目模板")
+public class PaperTemplate {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column(nullable = false, length = 128, unique = true)
+    @ApiModelProperty("模板名称")
+    private String name;
+
+    @Column(nullable = false)
+    @ApiModelProperty("前缀 #")
+    private String prefix;
+
+    @ApiModelProperty("后缀 可无 #")
+    private String suffix;
+
+    @ApiModelProperty("模式匹配字符 {}")
+    private String pattern;
+
+    @ApiModelProperty("试卷编码")
+    private String code;
+
+    @Column(nullable = false)
+    @ApiModelProperty("模块 #Section {}#")
+    private String section;
+
+    @Column(nullable = false)
+    @ApiModelProperty("问题 #Q{}#")
+    private String question;
+
+    @Column(nullable = false, columnDefinition = " varchar(255) default '^[A-Z]\\.'")
+    @ApiModelProperty("选项正则匹配 默认为 ^[A-Z]\\.(.*) 匹配A. B. 直到 Z.")
+    private String optionPattern;
+
+    @Column(nullable = false)
+    @ApiModelProperty("答案 #Ans#")
+    private String answer;
+
+    @Column(nullable = false)
+    @ApiModelProperty("标签 #Tag#")
+    private String tag;
+
+    @Column(nullable = false)
+    @ApiModelProperty("能力 #Abt#")
+    private String ability;
+
+    @Column(nullable = false, columnDefinition = " varchar(255) default '1' ")
+    @ApiModelProperty("题目类型")
+    private String type;
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+
+    @UpdateTimestamp
+    @Column(nullable = false)
+    private Date updatetime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPrefix() {
+        return prefix;
+    }
+
+    public void setPrefix(String prefix) {
+        this.prefix = prefix;
+    }
+
+    public String getSuffix() {
+        return suffix;
+    }
+
+    public void setSuffix(String suffix) {
+        this.suffix = suffix;
+    }
+
+    public String getPattern() {
+        return pattern;
+    }
+
+    public void setPattern(String pattern) {
+        this.pattern = pattern;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getSection() {
+        return section;
+    }
+
+    public void setSection(String section) {
+        this.section = section;
+    }
+
+    public String getQuestion() {
+        return question;
+    }
+
+    public void setQuestion(String question) {
+        this.question = question;
+    }
+
+    public String getOptionPattern() {
+        return optionPattern;
+    }
+
+    public void setOptionPattern(String optionPattern) {
+        this.optionPattern = optionPattern;
+    }
+
+    public String getAnswer() {
+        return answer;
+    }
+
+    public void setAnswer(String answer) {
+        this.answer = answer;
+    }
+
+    public String getTag() {
+        return tag;
+    }
+
+    public void setTag(String tag) {
+        this.tag = tag;
+    }
+
+    public String getAbility() {
+        return ability;
+    }
+
+    public void setAbility(String ability) {
+        this.ability = ability;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+}

+ 76 - 0
src/main/java/edu/math/diagnosis/entity/PaperType.java

@@ -0,0 +1,76 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * Created by Feick on 4/10/2019.
+ */
+@Entity
+@ApiModel("试卷类型 真题/模拟..")
+public class PaperType {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column(nullable = false, unique = true)
+    @ApiModelProperty("试卷类型名称")
+    private String name;
+
+    @Column(nullable = false, unique = true)
+    @ApiModelProperty("试卷类型编号")
+    private String code;
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+    @UpdateTimestamp
+    @Column(nullable = false)
+    private Date updatetime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+}

+ 289 - 0
src/main/java/edu/math/diagnosis/entity/Question.java

@@ -0,0 +1,289 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/6/25 17:55
+ * @DESCRIPTION: 题目
+ */
+@Entity
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+@ApiModel("题目")
+public class Question {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column(nullable = false)
+    @ApiModelProperty("所属试卷Id")
+    private long pid;//所属试卷id
+
+    @Column(nullable = false, columnDefinition = " int default 1")
+    @ApiModelProperty("题目编号")
+    private int number;//题目显式编号1,2,3
+
+    @Lob
+    @Column(nullable = false)
+    @ApiModelProperty("题目内容")
+    private String content;
+
+    @Column(nullable = false)
+    private int correctNum;//该题的正确选项个数,单选题为1  多选题>1
+
+    @Column(nullable = false, columnDefinition = " int default 1")
+    @ApiModelProperty("题目所属模块 1 2 3")
+    private int section;
+
+    @Column(nullable = false, columnDefinition = " int default 60")
+    @ApiModelProperty("题目时间")
+    private int duration;
+
+    @Column(nullable = false, columnDefinition = " double(10,2) default 0")
+    @ApiModelProperty("计算能力分数")
+    private Double calculation;
+
+    @Column(nullable = false, columnDefinition = " double(10,2) default 0")
+    @ApiModelProperty("归纳类比分数")
+    private Double induction;
+
+    @Column(nullable = false, columnDefinition = " double(10,2) default 0")
+    @ApiModelProperty("逻辑推理")
+    private Double logic;
+
+    @Column(nullable = false, columnDefinition = " double(10,2) default 0")
+    @ApiModelProperty("空间想象")
+    private Double space;
+
+    @Column(nullable = false, columnDefinition = " double(10,2) default 0")
+    @ApiModelProperty("语言能力")
+    private Double language;
+
+    @Column(nullable = false, columnDefinition = " double(10,2) default 0")
+    @ApiModelProperty("转化能力")
+    private Double conversion;
+
+    @Column(nullable = false, columnDefinition = "double(10,2) default 0")
+    @ApiModelProperty("单题得分")
+    private Double score;//单题得分
+
+    @Lob
+    @Column
+    @ApiModelProperty("正确评语")
+    private String correctDesc;
+
+    @Lob
+    @Column
+    @ApiModelProperty("错误评语")
+    private String wrongDesc;
+
+    @Column
+    @ApiModelProperty("标签")
+    private String tag;
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+    @UpdateTimestamp
+    @Column(nullable = false)
+    private Date updatetime;
+    @Transient
+    private List<QuestionOption> options;
+    @Transient
+    private List<AbilityScore> scores;
+    @Transient
+    private String ans;
+    @Transient
+    private Integer usetime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public long getPid() {
+        return pid;
+    }
+
+    public void setPid(long pid) {
+        this.pid = pid;
+    }
+
+    public int getNumber() {
+        return number;
+    }
+
+    public void setNumber(int number) {
+        this.number = number;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public int getCorrectNum() {
+        return correctNum;
+    }
+
+    public void setCorrectNum(int correctNum) {
+        this.correctNum = correctNum;
+    }
+
+    public int getSection() {
+        return section;
+    }
+
+    public void setSection(int section) {
+        this.section = section;
+    }
+
+    public int getDuration() {
+        return duration;
+    }
+
+    public void setDuration(int duration) {
+        this.duration = duration;
+    }
+
+    public Double getCalculation() {
+        return calculation;
+    }
+
+    public void setCalculation(Double calculation) {
+        this.calculation = calculation;
+    }
+
+    public Double getInduction() {
+        return induction;
+    }
+
+    public void setInduction(Double induction) {
+        this.induction = induction;
+    }
+
+    public Double getLogic() {
+        return logic;
+    }
+
+    public void setLogic(Double logic) {
+        this.logic = logic;
+    }
+
+    public Double getSpace() {
+        return space;
+    }
+
+    public void setSpace(Double space) {
+        this.space = space;
+    }
+
+    public Double getLanguage() {
+        return language;
+    }
+
+    public void setLanguage(Double language) {
+        this.language = language;
+    }
+
+    public Double getConversion() {
+        return conversion;
+    }
+
+    public void setConversion(Double conversion) {
+        this.conversion = conversion;
+    }
+
+    public Double getScore() {
+        return score;
+    }
+
+    public void setScore(Double score) {
+        this.score = score;
+    }
+
+    public String getCorrectDesc() {
+        return correctDesc;
+    }
+
+    public void setCorrectDesc(String correctDesc) {
+        this.correctDesc = correctDesc;
+    }
+
+    public String getWrongDesc() {
+        return wrongDesc;
+    }
+
+    public void setWrongDesc(String wrongDesc) {
+        this.wrongDesc = wrongDesc;
+    }
+
+    public String getTag() {
+        return tag;
+    }
+
+    public void setTag(String tag) {
+        this.tag = tag;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+
+    public List<QuestionOption> getOptions() {
+        return options;
+    }
+
+    public void setOptions(List<QuestionOption> options) {
+        this.options = options;
+    }
+
+    public List<AbilityScore> getScores() {
+        return scores;
+    }
+
+    public void setScores(List<AbilityScore> scores) {
+        this.scores = scores;
+    }
+
+    public String getAns() {
+        return ans;
+    }
+
+    public void setAns(String ans) {
+        this.ans = ans;
+    }
+
+    public Integer getUsetime() {
+        return usetime;
+    }
+
+    public void setUsetime(Integer usetime) {
+        this.usetime = usetime;
+    }
+}

+ 106 - 0
src/main/java/edu/math/diagnosis/entity/QuestionOption.java

@@ -0,0 +1,106 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/6/25 18:11
+ * @DESCRIPTION: 选项,属于某一题
+ */
+@Entity
+@ApiModel("题目选项")
+public class QuestionOption {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column(nullable = false)
+    @ApiModelProperty("所属题目Id")
+    private Long qid;
+
+    /**
+     * option index(1:A  2:B 3:C ...)
+     */
+    @Column(nullable = false)
+    @ApiModelProperty("选项编号 1:A 2:B 3:C")
+    private Integer oindex;
+
+    @Lob
+    @Column(nullable = false)
+    @ApiModelProperty("选项内容")
+    private String content;
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+
+    @UpdateTimestamp
+    @Column(nullable = false)
+    private Date updatetime;
+
+    @Column(nullable = false)
+    @ApiModelProperty("是否正确")
+    private Boolean correct;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getQid() {
+        return qid;
+    }
+
+    public void setQid(Long qid) {
+        this.qid = qid;
+    }
+
+    public Integer getOindex() {
+        return oindex;
+    }
+
+    public void setOindex(Integer oindex) {
+        this.oindex = oindex;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+
+    public Boolean isCorrect() {
+        return correct;
+    }
+
+    public void setCorrect(Boolean correct) {
+        this.correct = correct;
+    }
+}

+ 76 - 0
src/main/java/edu/math/diagnosis/entity/QuestionType.java

@@ -0,0 +1,76 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * Created by Feick on 4/10/2019.
+ */
+@Entity
+@ApiModel("题目类型 单选/多选...")
+public class QuestionType {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column(nullable = false, length = 128, unique = true)
+    @ApiModelProperty("题目类型名称")
+    private String name;
+
+    @Column(nullable = false, length = 128, unique = true)
+    @ApiModelProperty("题目类型编号")
+    private String code;
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+    @UpdateTimestamp
+    @Column(nullable = false)
+    private Date updatetime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+}

+ 79 - 0
src/main/java/edu/math/diagnosis/entity/RemarkTemplate.java

@@ -0,0 +1,79 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@ApiModel("试卷说明模板")
+public class RemarkTemplate {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    @Column(nullable = false, unique = true)
+    private String name;
+    @Lob
+    @Column
+    private String remark;
+    @Column(nullable = false)
+    private Long subjectId;
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+    @UpdateTimestamp
+    @Column(nullable = false)
+    private Date updatetime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public Long getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(Long subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+}

+ 76 - 0
src/main/java/edu/math/diagnosis/entity/Role.java

@@ -0,0 +1,76 @@
+package edu.math.diagnosis.entity;
+
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+public class Role {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    @Column(unique = true,nullable = false)
+    private String name;
+    //预留
+    private String type;
+
+    private String authorityIds;
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+    @UpdateTimestamp
+    @Column(nullable = false)
+    private Date updatetime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getAuthorityIds() {
+        return authorityIds;
+    }
+
+    public void setAuthorityIds(String authorityIds) {
+        this.authorityIds = authorityIds;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+}

+ 4 - 0
src/main/java/edu/math/diagnosis/entity/ScoreSegment.java

@@ -0,0 +1,4 @@
+package edu.math.diagnosis.entity;
+
+public class ScoreSegment {
+}

+ 129 - 0
src/main/java/edu/math/diagnosis/entity/Section.java

@@ -0,0 +1,129 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/11/11 16:33
+ * @DESCRIPTION:
+ */
+@Entity
+@ApiModel("模块")
+public class Section {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    @Column(nullable = false)
+    private Long pid;
+    @Column(nullable = false)
+    @ApiModelProperty("模块编号 1、2、3")
+    private Integer number;
+    @Column(nullable = false, columnDefinition = " int default 20")
+    @ApiModelProperty("模块时间,默认20分钟")
+    private Integer duration;
+    @Lob
+    @Column
+    @ApiModelProperty("背景材料")
+    private String material;
+    @Column(nullable = false, columnDefinition = " int default 2")
+    @ApiModelProperty("休息间隔时间,默认2分钟")
+    private Integer rest;
+    @Column(nullable = false, columnDefinition = " int default 0")
+    @ApiModelProperty("模块题目数量")
+    private Integer nums;
+    @Column(nullable = false, columnDefinition = " int default 1")
+    @ApiModelProperty("模块开始题号")
+    private Integer startNumber;
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+    @UpdateTimestamp
+    @Column(nullable = false)
+    private Date updatetime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getPid() {
+        return pid;
+    }
+
+    public void setPid(Long pid) {
+        this.pid = pid;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public Integer getDuration() {
+        return duration;
+    }
+
+    public void setDuration(Integer duration) {
+        this.duration = duration;
+    }
+
+    public String getMaterial() {
+        return material;
+    }
+
+    public void setMaterial(String material) {
+        this.material = material;
+    }
+
+    public Integer getRest() {
+        return rest;
+    }
+
+    public void setRest(Integer rest) {
+        this.rest = rest;
+    }
+
+    public Integer getNums() {
+        return nums;
+    }
+
+    public void setNums(Integer nums) {
+        this.nums = nums;
+    }
+
+    public Integer getStartNumber() {
+        return startNumber;
+    }
+
+    public void setStartNumber(Integer startNumber) {
+        this.startNumber = startNumber;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+}

+ 76 - 0
src/main/java/edu/math/diagnosis/entity/Subject.java

@@ -0,0 +1,76 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * Created by Feick on 4/10/2019.
+ */
+@Entity
+@ApiModel("科目 语文/数学..")
+public class Subject {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column(nullable = false, unique = true)
+    @ApiModelProperty("科目名称")
+    private String name;
+
+    @Column(nullable = false, unique = true)
+    @ApiModelProperty("科目编号")
+    private String code;
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+    @UpdateTimestamp
+    @Column(nullable = false)
+    private Date updatetime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+}

+ 95 - 0
src/main/java/edu/math/diagnosis/entity/SubjectAbility.java

@@ -0,0 +1,95 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@ApiModel("科目能力")
+public class SubjectAbility {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column(nullable = false)
+    @ApiModelProperty("所属科目Id")
+    private String subjectId;
+
+    @Column(nullable = false, length = 128, unique = true)
+    @ApiModelProperty("科目能力名称")
+    private String name;
+
+    @Column(nullable = false, length = 128, unique = true)
+    @ApiModelProperty("科目能力编号")
+    private String code;
+
+    private String des;
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+    @UpdateTimestamp
+    @Column(nullable = false)
+    private Date updatetime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(String subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getDes() {
+        return des;
+    }
+
+    public void setDes(String des) {
+        this.des = des;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+}

+ 4 - 0
src/main/java/edu/math/diagnosis/entity/SubjectKnowledge.java

@@ -0,0 +1,4 @@
+package edu.math.diagnosis.entity;
+
+public class SubjectKnowledge {
+}

+ 96 - 0
src/main/java/edu/math/diagnosis/entity/SubjectLabel.java

@@ -0,0 +1,96 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@ApiModel("科目标签")
+public class SubjectLabel {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column(nullable = false)
+    @ApiModelProperty("所属科目Id")
+    private String subjectId;
+
+    @Column(nullable = false, length = 128, unique = true)
+    @ApiModelProperty("标签名称")
+    private String name;
+
+    @Column(nullable = false, length = 128, unique = true)
+    @ApiModelProperty("标签编号")
+    private String code;
+
+    private String des;
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+
+    @UpdateTimestamp
+    @Column(nullable = false)
+    private Date updatetime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(String subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getDes() {
+        return des;
+    }
+
+    public void setDes(String des) {
+        this.des = des;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+}

+ 196 - 0
src/main/java/edu/math/diagnosis/entity/UserInfo.java

@@ -0,0 +1,196 @@
+package edu.math.diagnosis.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/8/24 18:23
+ * @DESCRIPTION:
+ */
+@Entity
+public class UserInfo implements Serializable {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column
+    private String name;
+    @Column(nullable = false, length = 128, unique = true)
+    @ApiModelProperty("用户名,唯一")
+    private String username;
+    @Column(nullable = false)
+    private String password;
+    private String email;
+    private String phone;
+    private String salt;
+    private String address;
+    @ApiModelProperty("校区")
+    private String region;//校区
+    private Integer level;
+    private Boolean disabled;
+    private Boolean locked;
+    private Date lastLoginTime;
+
+    @CreationTimestamp
+    @Column(nullable = false)
+    private Date createtime;
+    @UpdateTimestamp
+    @Column(nullable = false)
+    private Date updatetime;
+    private String userType;
+    private String roleIds;
+
+    @Transient
+    private List<String> authorities;
+
+    public String getRegion() {
+        return region;
+    }
+
+    public void setRegion(String region) {
+        this.region = region;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getSalt() {
+        return salt;
+    }
+
+    public void setSalt(String salt) {
+        this.salt = salt;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public Integer getLevel() {
+        return level;
+    }
+
+    public void setLevel(Integer level) {
+        this.level = level;
+    }
+
+    public Date getLastLoginTime() {
+        return lastLoginTime;
+    }
+
+    public void setLastLoginTime(Date lastLoginTime) {
+        this.lastLoginTime = lastLoginTime;
+    }
+
+    public Date getCreatetime() {
+        return createtime;
+    }
+
+    public void setCreatetime(Date createtime) {
+        this.createtime = createtime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+
+    public String getUserType() {
+        return userType;
+    }
+
+    public void setUserType(String userType) {
+        this.userType = userType;
+    }
+
+    public String getRoleIds() {
+        return roleIds;
+    }
+
+    public void setRoleIds(String roleIds) {
+        this.roleIds = roleIds;
+    }
+
+    public List<String> getAuthorities() {
+        return authorities;
+    }
+
+    public void setAuthorities(List<String> authorities) {
+        this.authorities = authorities;
+    }
+
+    public Boolean getDisabled() {
+        return disabled;
+    }
+
+    public void setDisabled(Boolean disabled) {
+        this.disabled = disabled;
+    }
+
+    public Boolean getLocked() {
+        return locked;
+    }
+
+    public void setLocked(Boolean locked) {
+        this.locked = locked;
+    }
+}

+ 88 - 0
src/main/java/edu/math/diagnosis/model/AuthUser.java

@@ -0,0 +1,88 @@
+package edu.math.diagnosis.model;
+
+import edu.math.diagnosis.config.Constants;
+import edu.math.diagnosis.entity.UserInfo;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class AuthUser implements UserDetails {
+    private UserInfo user;
+
+    public AuthUser(UserInfo user) {
+        this.user = user;
+    }
+
+    public UserInfo getUser() {
+        return user;
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        List<GrantedAuthority> authorities = new ArrayList<>();
+        String userType = user.getUserType();
+        if (StringUtils.isBlank(userType)) {
+            authorities.add(Constants.USER_GUEST);
+            return authorities;
+        }
+        String[] type = userType.split(",");
+        for (String t : type) {
+            switch (t) {
+                case Constants.USER_TYPE_ADMIN:
+                    authorities.add(Constants.USER_ADMIN);
+                    break;
+                case Constants.USER_TYPE_TEACHER:
+                    authorities.add(Constants.USER_TEACHER);
+                    break;
+                case Constants.USER_TYPE_STUDENT:
+                    authorities.add(Constants.USER_STUDENT);
+                    break;
+                default:
+                    //如果出现其他角色,则返回guest
+                    return new ArrayList<GrantedAuthority>() {{
+                        add(Constants.USER_GUEST);
+                    }};
+            }
+        }
+        return authorities;
+    }
+
+    @Override
+    public String getPassword() {
+        return user.getPassword();
+//        return null;
+    }
+
+    @Override
+    public String getUsername() {
+        return user.getUsername();
+    }
+
+    @Override
+    public boolean isAccountNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return user.getLocked() == null || !user.getLocked();
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return user.getDisabled() == null || !user.getDisabled();
+    }
+
+    public boolean checkUserType(String userType) {
+        return user.getUserType().contains(userType);
+    }
+}

+ 42 - 0
src/main/java/edu/math/diagnosis/model/GeneralInfo.java

@@ -0,0 +1,42 @@
+package edu.math.diagnosis.model;
+
+import java.util.List;
+
+public class GeneralInfo {
+    private List<String> correctOptions;
+    private List<Double> rates;//每一题的正确率
+    private List<Double> abilityAveScore;
+    private List<Double> curveGraph;
+
+    public List<Double> getCurveGraph() {
+        return curveGraph;
+    }
+
+    public void setCurveGraph(List<Double> curveGraph) {
+        this.curveGraph = curveGraph;
+    }
+
+    public List<String> getCorrectOptions() {
+        return correctOptions;
+    }
+
+    public void setCorrectOptions(List<String> correctOptions) {
+        this.correctOptions = correctOptions;
+    }
+
+    public List<Double> getRates() {
+        return rates;
+    }
+
+    public void setRates(List<Double> rates) {
+        this.rates = rates;
+    }
+
+    public List<Double> getAbilityAveScore() {
+        return abilityAveScore;
+    }
+
+    public void setAbilityAveScore(List<Double> abilityAveScore) {
+        this.abilityAveScore = abilityAveScore;
+    }
+}

+ 86 - 0
src/main/java/edu/math/diagnosis/model/PaperVo.java

@@ -0,0 +1,86 @@
+package edu.math.diagnosis.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel
+public class PaperVo {
+    private String name;
+    @ApiModelProperty("年级 1-12")
+    private Integer grade;
+    @ApiModelProperty("各模块题目数量,以','隔开,单位为分钟 20,20,20")
+    private String sectionNums;
+    @ApiModelProperty("各模块完成时间,以','隔开,单位为分钟 20,20,20")
+    private String sectionDurations;
+    @ApiModelProperty("各模块休息时间,以','隔开,单位为分钟 2,2,2")
+    private String sectionRests;
+    private String remark;
+    @ApiModelProperty("试卷类型Id 1")
+    private Long typeId;
+    @ApiModelProperty("科目类别Id 2")
+    private Long subjectId;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getGrade() {
+        return grade;
+    }
+
+    public void setGrade(Integer grade) {
+        this.grade = grade;
+    }
+
+    public String getSectionNums() {
+        return sectionNums;
+    }
+
+    public void setSectionNums(String sectionNums) {
+        this.sectionNums = sectionNums;
+    }
+
+    public String getSectionDurations() {
+        return sectionDurations;
+    }
+
+    public void setSectionDurations(String sectionDurations) {
+        this.sectionDurations = sectionDurations;
+    }
+
+    public String getSectionRests() {
+        return sectionRests;
+    }
+
+    public void setSectionRests(String sectionRests) {
+        this.sectionRests = sectionRests;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public Long getTypeId() {
+        return typeId;
+    }
+
+    public void setTypeId(Long typeId) {
+        this.typeId = typeId;
+    }
+
+    public Long getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(Long subjectId) {
+        this.subjectId = subjectId;
+    }
+}

+ 65 - 0
src/main/java/edu/math/diagnosis/model/QuestionDetail.java

@@ -0,0 +1,65 @@
+package edu.math.diagnosis.model;
+
+import java.util.List;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/7/6 18:03
+ * @DESCRIPTION: 一题的作答情况
+ */
+public class QuestionDetail {
+    private Long id;
+    private Long qid;
+    private Long drid;
+    private String choices;
+    private boolean correct;
+    private List<Long> choice;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getQid() {
+        return qid;
+    }
+
+    public void setQid(Long qid) {
+        this.qid = qid;
+    }
+
+    public Long getDrid() {
+        return drid;
+    }
+
+    public void setDrid(Long drid) {
+        this.drid = drid;
+    }
+
+    public String getChoices() {
+        return choices;
+    }
+
+    public void setChoices(String choices) {
+        this.choices = choices;
+    }
+
+    public boolean isCorrect() {
+        return correct;
+    }
+
+    public void setCorrect(boolean correct) {
+        this.correct = correct;
+    }
+
+    public List<Long> getChoice() {
+        return choice;
+    }
+
+    public void setChoice(List<Long> choice) {
+        this.choice = choice;
+    }
+}

+ 87 - 0
src/main/java/edu/math/diagnosis/model/Report.java

@@ -0,0 +1,87 @@
+package edu.math.diagnosis.model;
+
+import java.util.List;
+
+public class Report {
+    private String name;
+    private String grade;
+    private Integer totalScore;
+    private List<Double> abilityScore;
+    private List<Integer> abilityLevel;
+    private List<String> abilityComments;//各项能力的评语
+    private List<Integer> rw;//每一题的对错
+    private List<String> comments;//每一题的评语
+    private List<String> options;//每一题学生所选的选项
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getGrade() {
+        return grade;
+    }
+
+    public void setGrade(String grade) {
+        this.grade = grade;
+    }
+
+    public Integer getTotalScore() {
+        return totalScore;
+    }
+
+    public void setTotalScore(Integer totalScore) {
+        this.totalScore = totalScore;
+    }
+
+    public List<Double> getAbilityScore() {
+        return abilityScore;
+    }
+
+    public void setAbilityScore(List<Double> abilityScore) {
+        this.abilityScore = abilityScore;
+    }
+
+    public List<Integer> getAbilityLevel() {
+        return abilityLevel;
+    }
+
+    public void setAbilityLevel(List<Integer> abilityLevel) {
+        this.abilityLevel = abilityLevel;
+    }
+
+    public List<String> getAbilityComments() {
+        return abilityComments;
+    }
+
+    public void setAbilityComments(List<String> abilityComments) {
+        this.abilityComments = abilityComments;
+    }
+
+    public List<Integer> getRw() {
+        return rw;
+    }
+
+    public void setRw(List<Integer> rw) {
+        this.rw = rw;
+    }
+
+    public List<String> getComments() {
+        return comments;
+    }
+
+    public void setComments(List<String> comments) {
+        this.comments = comments;
+    }
+
+    public List<String> getOptions() {
+        return options;
+    }
+
+    public void setOptions(List<String> options) {
+        this.options = options;
+    }
+}

+ 30 - 0
src/main/java/edu/math/diagnosis/model/ResponseMessage.java

@@ -0,0 +1,30 @@
+package edu.math.diagnosis.model;
+
+/**
+ * @AUTHOR: DaiFengWen
+ * @DATE: Create in 2018/5/10 14:15
+ * @DESCRIPTION:
+ */
+public class ResponseMessage {
+    private final String message;
+    private final int code;
+
+    private ResponseMessage(int code, String message) {
+        this.message = message;
+        this.code = code;
+    }
+
+    public static ResponseMessage getInstance(int code, String message) {
+        return new ResponseMessage(code, message);
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+
+    public int getCode() {
+        return code;
+    }
+
+}

+ 82 - 0
src/main/java/edu/math/diagnosis/model/Result.java

@@ -0,0 +1,82 @@
+package edu.math.diagnosis.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * Created by 千里明月 on 2018/7/12.
+ */
+@ApiModel(value = "返回结果")
+public class Result<T> {
+    @ApiModelProperty(value = "泛型,根据返回的对象而定")
+    public T t;
+    @ApiModelProperty(value = "是否成功,成功为true,失败为false")
+    private Boolean result;
+    @ApiModelProperty(value = "返回的消息")
+    private String message;
+
+    public Result() {
+        this.result = true;
+    }
+
+    public Result(Boolean result) {
+        this.result = result;
+    }
+
+    public Result(Boolean result, String message) {
+        this.result = result;
+        this.message = message;
+    }
+
+    public Result(Boolean result, String message, T t) {
+        this.result = result;
+        this.message = message;
+        this.t = t;
+    }
+
+    public Result(Boolean result, T t) {
+        this.result = result;
+        this.t = t;
+    }
+
+    public static Result ok() {
+        return new Result();
+    }
+
+    public static <T> Result ok(T t) {
+        return new Result<>(true, t);
+    }
+
+    public static Result fail() {
+        return new Result(false);
+    }
+
+    public static Result fail(String message) {
+        return new Result(false, message);
+    }
+
+    public T getT() {
+        return t;
+    }
+
+    public void setT(T t) {
+        this.t = t;
+    }
+
+    public Boolean getResult() {
+        return result;
+    }
+
+    public void setResult(Boolean result) {
+        this.result = result;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+}
+

+ 138 - 0
src/main/java/edu/math/diagnosis/model/UserVo.java

@@ -0,0 +1,138 @@
+package edu.math.diagnosis.model;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+public class UserVo implements Serializable {
+
+    private Long id;
+    private String name;
+    private String username;
+    private String email;
+    private String phone;
+    private String salt;
+    private String address;
+    private String region;//校区
+    private Integer level;
+    private Date lastLoginTime;
+
+    private Date updatetime;
+    private String userType;
+    private String roleIds;
+
+    private List<String> authorities;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getSalt() {
+        return salt;
+    }
+
+    public void setSalt(String salt) {
+        this.salt = salt;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public String getRegion() {
+        return region;
+    }
+
+    public void setRegion(String region) {
+        this.region = region;
+    }
+
+    public Integer getLevel() {
+        return level;
+    }
+
+    public void setLevel(Integer level) {
+        this.level = level;
+    }
+
+    public Date getLastLoginTime() {
+        return lastLoginTime;
+    }
+
+    public void setLastLoginTime(Date lastLoginTime) {
+        this.lastLoginTime = lastLoginTime;
+    }
+
+    public Date getUpdatetime() {
+        return updatetime;
+    }
+
+    public void setUpdatetime(Date updatetime) {
+        this.updatetime = updatetime;
+    }
+
+    public String getUserType() {
+        return userType;
+    }
+
+    public void setUserType(String userType) {
+        this.userType = userType;
+    }
+
+    public String getRoleIds() {
+        return roleIds;
+    }
+
+    public void setRoleIds(String roleIds) {
+        this.roleIds = roleIds;
+    }
+
+    public List<String> getAuthorities() {
+        return authorities;
+    }
+
+    public void setAuthorities(List<String> authorities) {
+        this.authorities = authorities;
+    }
+}

Some files were not shown because too many files changed in this diff