Browse Source

fix(front): 调整样式

Go 4 years ago
parent
commit
de91a1d78f
52 changed files with 403 additions and 158 deletions
  1. 6 2
      front/.babelrc
  2. 27 19
      front/package-lock.json
  3. 3 0
      front/package.json
  4. 5 4
      front/project/admin/routes/setting/rank/page.js
  5. 2 2
      front/project/admin/routes/subject/question/page.js
  6. 3 2
      front/project/admin/routes/subject/sentenceQuestion/page.js
  7. 2 2
      front/project/admin/routes/subject/textbookQuestion/page.js
  8. 2 2
      front/project/www/components/Date/index.js
  9. 4 8
      front/project/www/layouts/User/index.js
  10. 4 4
      front/project/www/routes/course/detail/page.js
  11. 1 1
      front/project/www/routes/examination/list/page.js
  12. 1 1
      front/project/www/routes/examination/main/page.js
  13. 1 1
      front/project/www/routes/exercise/list/page.js
  14. 4 4
      front/project/www/routes/exercise/main/page.js
  15. 1 1
      front/project/www/routes/my/answer/page.js
  16. 3 3
      front/project/www/routes/my/course/page.js
  17. 2 2
      front/project/www/routes/my/data/page.js
  18. 1 1
      front/project/www/routes/my/error/page.js
  19. 8 10
      front/project/www/routes/my/index.js
  20. 5 1
      front/project/www/routes/my/main/page.js
  21. 1 1
      front/project/www/routes/my/note/page.js
  22. 6 4
      front/project/www/routes/my/report/page.js
  23. 6 6
      front/project/www/routes/paper/process/base/index.js
  24. 9 3
      front/project/www/routes/paper/process/page.js
  25. 25 22
      front/project/www/routes/paper/report/page.js
  26. 8 9
      front/project/www/routes/question/index.js
  27. 1 1
      front/project/www/routes/question/search/page.js
  28. 1 1
      front/project/www/routes/textbook/list/page.js
  29. 1 1
      front/src/components/Assets/index.js
  30. 44 0
      front/src/components/Editor/index.js
  31. 12 0
      front/src/components/Editor/index.less
  32. 3 12
      server/data/src/main/java/com/qxgmat/data/dao/entity/ExercisePaper.java
  33. 3 12
      server/data/src/main/java/com/qxgmat/data/dao/entity/Question.java
  34. 35 0
      server/data/src/main/java/com/qxgmat/data/dao/entity/UserPaper.java
  35. 35 0
      server/data/src/main/java/com/qxgmat/data/dao/entity/UserReport.java
  36. 4 3
      server/data/src/main/java/com/qxgmat/data/dao/mapping/UserPaperMapper.xml
  37. 2 1
      server/data/src/main/java/com/qxgmat/data/dao/mapping/UserReportMapper.xml
  38. 1 0
      server/data/src/main/java/com/qxgmat/data/relation/UserPaperRelationMapper.java
  39. 4 3
      server/data/src/main/java/com/qxgmat/data/relation/mapping/UserPaperRelationMapper.xml
  40. 3 0
      server/data/src/main/resources/db/migration/V8__update_report.sql
  41. 16 4
      server/gateway-api/src/main/java/com/qxgmat/controller/admin/SettingController.java
  42. 10 0
      server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserPaperBaseExtendDto.java
  43. 10 0
      server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserPaperDetailExtendDto.java
  44. 10 0
      server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserReportExtendDto.java
  45. 9 0
      server/gateway-api/src/main/java/com/qxgmat/dto/response/PaperBaseDto.java
  46. 10 0
      server/gateway-api/src/main/java/com/qxgmat/dto/response/UserReportBaseDto.java
  47. 10 0
      server/gateway-api/src/main/java/com/qxgmat/dto/response/UserReportDetailDto.java
  48. 1 1
      server/gateway-api/src/main/java/com/qxgmat/service/UserPaperService.java
  49. 7 3
      server/gateway-api/src/main/java/com/qxgmat/service/extend/QuestionFlowService.java
  50. 12 0
      server/gateway-api/src/main/java/com/qxgmat/task/AsyncTask.java
  51. 1 1
      server/tools/src/main/java/com/nuliji/tools/shiro/RoleFilter.java
  52. 18 0
      uploaded.sh

+ 6 - 2
front/.babelrc

@@ -23,5 +23,9 @@
       ]
     ]
   ],
-  "presets": ["es2015", "stage-3", "react"]
-}
+  "presets": [
+    "es2015",
+    "stage-3",
+    "react"
+  ]
+}

+ 27 - 19
front/package-lock.json

@@ -270,7 +270,7 @@
     },
     "@types/quill": {
       "version": "1.3.10",
-      "resolved": "http://registry.npm.taobao.org/@types/quill/download/@types/quill-1.3.10.tgz",
+      "resolved": "https://registry.npm.taobao.org/@types/quill/download/@types/quill-1.3.10.tgz",
       "integrity": "sha1-3B97ZYf37pS99SkbySKJ9vBJdhM=",
       "requires": {
         "parchment": "^1.1.2"
@@ -4928,9 +4928,9 @@
       "dev": true
     },
     "fast-diff": {
-      "version": "1.1.2",
-      "resolved": "http://registry.npm.taobao.org/fast-diff/download/fast-diff-1.1.2.tgz",
-      "integrity": "sha1-S2LEK44D3j+EhGC2OQeZIGldAVQ="
+      "version": "1.2.0",
+      "resolved": "http://registry.npm.taobao.org/fast-diff/download/fast-diff-1.2.0.tgz",
+      "integrity": "sha1-c+4RmC2Gyq95WYKNUZz+kn+sXwM="
     },
     "fast-json-stable-stringify": {
       "version": "2.0.0",
@@ -8640,14 +8640,14 @@
       "dev": true
     },
     "quill": {
-      "version": "1.3.6",
-      "resolved": "http://registry.npm.taobao.org/quill/download/quill-1.3.6.tgz",
-      "integrity": "sha1-mfTeH+6FkloNfUFjttgyjyMxek0=",
+      "version": "1.3.7",
+      "resolved": "https://registry.npm.taobao.org/quill/download/quill-1.3.7.tgz",
+      "integrity": "sha1-2lsvOixHDpMjQM2/NmjJ8h+Shug=",
       "requires": {
         "clone": "^2.1.1",
         "deep-equal": "^1.0.1",
         "eventemitter3": "^2.0.3",
-        "extend": "^3.0.1",
+        "extend": "^3.0.2",
         "parchment": "^1.1.4",
         "quill-delta": "^3.6.2"
       },
@@ -8661,24 +8661,32 @@
           "version": "2.0.3",
           "resolved": "http://registry.npm.taobao.org/eventemitter3/download/eventemitter3-2.0.3.tgz",
           "integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo="
+        },
+        "fast-diff": {
+          "version": "1.1.2",
+          "resolved": "http://registry.npm.taobao.org/fast-diff/download/fast-diff-1.1.2.tgz",
+          "integrity": "sha1-S2LEK44D3j+EhGC2OQeZIGldAVQ="
+        },
+        "quill-delta": {
+          "version": "3.6.3",
+          "resolved": "https://registry.npm.taobao.org/quill-delta/download/quill-delta-3.6.3.tgz",
+          "integrity": "sha1-sZ/SuJQSMBxg4f8hPY2GDqwPEDI=",
+          "requires": {
+            "deep-equal": "^1.0.1",
+            "extend": "^3.0.2",
+            "fast-diff": "1.1.2"
+          }
         }
       }
     },
     "quill-delta": {
-      "version": "3.6.3",
-      "resolved": "http://registry.npm.taobao.org/quill-delta/download/quill-delta-3.6.3.tgz",
-      "integrity": "sha1-sZ/SuJQSMBxg4f8hPY2GDqwPEDI=",
+      "version": "4.2.1",
+      "resolved": "https://registry.npm.taobao.org/quill-delta/download/quill-delta-4.2.1.tgz",
+      "integrity": "sha1-rU8ZHN875QecXcOZG5YDpcwNtpo=",
       "requires": {
         "deep-equal": "^1.0.1",
         "extend": "^3.0.2",
-        "fast-diff": "1.1.2"
-      },
-      "dependencies": {
-        "extend": {
-          "version": "3.0.2",
-          "resolved": "http://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz",
-          "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo="
-        }
+        "fast-diff": "1.2.0"
       }
     },
     "raf": {

+ 3 - 0
front/package.json

@@ -78,7 +78,10 @@
     "history": "^4.7.2",
     "js-sha1": "^0.6.0",
     "moment": "^2.22.2",
+    "parchment": "^1.1.4",
     "promise": "^7.1.1",
+    "quill": "^1.3.7",
+    "quill-delta": "^4.2.1",
     "react": "^16.6.3",
     "react-addons-css-transition-group": "^15.6.2",
     "react-contextmenu": "^2.10",

+ 5 - 4
front/project/admin/routes/setting/rank/page.js

@@ -81,7 +81,7 @@ export default class extends Page {
         return <Upload
           showUploadList={false}
           beforeUpload={(file) => System.importRank({ file }).then((result) => {
-            asyncSMessage(`导入成功: ${result}条数据`);
+            asyncSMessage(`导入: ${result}条数据,数据正在更新中,请勿重新提交`);
             this.refresh();
             return Promise.reject();
           }).catch(e => {
@@ -101,8 +101,8 @@ export default class extends Page {
   }
 
   initData() {
-    System.listRank().then(result => {
-      this.setState({ list: result });
+    System.listRank(this.state.search).then(result => {
+      this.setTableData(result.list, result.total);
     });
   }
 
@@ -144,8 +144,9 @@ export default class extends Page {
       <TableLayout
         columns={this.tableSort(this.columns)}
         list={this.state.list}
-        pagination={false}
+        pagination={this.state.page}
         loading={this.props.core.loading}
+        onChange={(pagination, filters, sorter) => this.tableChange(pagination, filters, sorter)}
       />
     </Block>;
   }

+ 2 - 2
front/project/admin/routes/subject/question/page.js

@@ -918,7 +918,7 @@ export default class extends Page {
         <Form.Item label='官方解析'>
           {getFieldDecorator('officialContent', {
           })(
-            <Editor placeholder='输入内容' />,
+            <Editor placeholder='输入内容' onUpload={(file) => System.uploadImage(file)} />,
           )}
         </Form.Item>
       </Form>
@@ -932,7 +932,7 @@ export default class extends Page {
         <Form.Item label='千行解析'>
           {getFieldDecorator('qxContent', {
           })(
-            <Editor placeholder='输入内容' />,
+            <Editor placeholder='输入内容' onUpload={(file) => System.uploadImage(file)} />,
           )}
         </Form.Item>
       </Form>

+ 3 - 2
front/project/admin/routes/subject/sentenceQuestion/page.js

@@ -13,6 +13,7 @@ import { SentenceOption } from '../../../../Constant';
 // import { Preview } from '../../../stores/preview';
 import { Exercise } from '../../../stores/exercise';
 import { Sentence } from '../../../stores/sentence';
+import { System } from '../../../stores/system';
 import config from './index';
 
 const stopWords = [',', '.', ':', '!', ';', '?', '\\', '/', '`', '\'', '', '。', ',', '?', '!', '“', '”'];
@@ -454,7 +455,7 @@ export default class extends Page {
         <Form.Item label='千行解析'>
           {getFieldDecorator('question.qxContent', {
           })(
-            <Editor placeholder='输入内容' />,
+            <Editor placeholder='输入内容' onUpload={(file) => System.uploadImage(file)} />,
           )}
         </Form.Item>
       </Form>
@@ -468,7 +469,7 @@ export default class extends Page {
         <Form.Item label='中文解析'>
           {getFieldDecorator('question.chineseContent', {
           })(
-            <Editor placeholder='输入内容' />,
+            <Editor placeholder='输入内容' onUpload={(file) => System.uploadImage(file)} />,
           )}
         </Form.Item>
       </Form>

+ 2 - 2
front/project/admin/routes/subject/textbookQuestion/page.js

@@ -284,7 +284,7 @@ export default class extends Page {
             <Form.Item>
               {getFieldDecorator(`question.content.questions[${index}].description`, {
               })(
-                <Editor placeholder='选项问题说明' />,
+                <Editor placeholder='选项问题说明' onUpload={(file) => System.uploadImage(file)} />,
               )}
             </Form.Item>
           )}
@@ -361,7 +361,7 @@ export default class extends Page {
         <Form.Item label='千行解析'>
           {getFieldDecorator('question.qxContent', {
           })(
-            <Editor placeholder='输入内容' />,
+            <Editor placeholder='输入内容' onUpload={(file) => System.uploadImage(file)} />,
           )}
         </Form.Item>
       </Form>

+ 2 - 2
front/project/www/components/Date/index.js

@@ -61,7 +61,7 @@ export class TwoDate extends Component {
     const today = moment();
     this.state = {
       key: 0,
-      value: today,
+      value: null,
       leftValue: today.clone().subtract(1, 'month'),
       rightValue: today,
     };
@@ -90,7 +90,7 @@ export class TwoDate extends Component {
     const { getType } = this.props;
     return (
       <div
-        className={`ant-fullcalendar-date ${getType ? getType(date) : ''} ${value.diff(date) === 0 ? 'selected' : ''}`}
+        className={`ant-fullcalendar-date ${getType ? getType(date) : ''} ${value && value.diff(date) === 0 ? 'selected' : ''}`}
       >
         <div className="ant-fullcalendar-value">{date.get('date')}</div>
       </div>

+ 4 - 8
front/project/www/layouts/User/index.js

@@ -3,10 +3,10 @@ import { Link } from 'react-router-dom';
 import './index.less';
 
 function UserLayout(props) {
-  const { menu = [], active, right, center, ads = [] } = props;
+  const { menu = [], active, right, center, ads = [], onClick } = props;
 
   return (
-    <div className={`user-layout content ${right ? 'right' : ''}`}>
+    <div className={`user-layout content ${right ? 'right' : ''}`} onClick={(e) => onClick && onClick(e)}>
       <div className="left-layout">
         <div className="block-layout">
           {menu.map(item => {
@@ -25,9 +25,7 @@ function UserLayout(props) {
               if (!item) return null;
               return <div className="block-layout">{item}</div>;
             })
-          ) : (
-            <div className="block-layout">{center}</div>
-          )}
+          ) : (<div className="block-layout">{center}</div>)}
         </div>
       )}
       {right && (
@@ -37,9 +35,7 @@ function UserLayout(props) {
               if (!item) return null;
               return <div className="block-layout">{item}</div>;
             })
-          ) : (
-            <div className="block-layout">{right}</div>
-          )}
+          ) : (<div className="block-layout">{right}</div>)}
           {ads.length > 0 && ads.map(item => {
             return <div className="block-layout">{item}</div>;
           })}

+ 4 - 4
front/project/www/routes/course/detail/page.js

@@ -42,7 +42,7 @@ export default class extends Page {
         render: text => {
           text = text || {};
           const progress = text.report ? formatPercent(text.report.userNumber, text.report.questionNumber) : 0;
-          const times = text.paper ? text.paper.times : 0;
+          const times = text.paper ? text.paper.finishTimes : 0;
           return (
             <div>
               <div className="v-a-m d-i-b">
@@ -105,7 +105,7 @@ export default class extends Page {
         key: 'progress',
         render: (text, record) => {
           const { paper = {} } = record;
-          return `${paper.paper && paper.paper.times > 0 ? `${paper.paper.times}次+` : ''}${
+          return `${paper.paper && paper.paper.finishTimes > 0 ? `${paper.paper.finishTimes}次+` : ''}${
             paper.report ? formatPercent(paper.report.userNumber, paper.report.questionNumber, false) : '0%'}`;
         },
       },
@@ -448,7 +448,7 @@ export default class extends Page {
           <div className="t-2 m-b-1">授课老师:{data.teacher}</div>
           <div className={'detail'}>
             <div className="left">
-              {data.have && <div hidden={(item.paper && item.paper.times > 0)} className="left-top">
+              {data.have && <div hidden={(item.paper && item.paper.finishTimes > 0)} className="left-top">
                 <span className="d-i-b m-r-1">预习作业</span>
                 <span className="d-i-b m-r-2">
                   <ProgressText width={480} size="small" progress={item.report ? formatPercent(item.report.userNumber, item.report.questionNumber) : 0} />
@@ -501,7 +501,7 @@ export default class extends Page {
                 </Video>}
               </div>
             </div>
-            <div className={`detail-right ${data.have && !(item.paper && item.paper.times > 0) ? 'have' : ''}  tab-warpper`}>
+            <div className={`detail-right ${data.have && !(item.paper && item.paper.finishTimes > 0) ? 'have' : ''}  tab-warpper`}>
               <Tabs
                 type="division"
                 theme="gray"

+ 1 - 1
front/project/www/routes/examination/list/page.js

@@ -402,7 +402,7 @@ export default class extends Page {
             <div className="table-row">
               <div className="night f-s-16">{record.title}</div>
               <div>
-                <ProgressText progress={progress} times={record.paper ? record.paper.times : 0} size="small" />
+                <ProgressText progress={progress} times={record.paper ? record.paper.finishTimes : 0} size="small" />
               </div>
             </div>
           );

+ 1 - 1
front/project/www/routes/examination/main/page.js

@@ -136,7 +136,7 @@ export default class extends Page {
     Question.getExaminationProgress(subject.id).then(result => {
       // const exerciseProgress = getMap(r, 'id');
       result = result.map(row => {
-        row.title = `${row.titleZh}${row.titleEn}`;
+        row.title = `${row.titleZh}`;
         row.info = [
           {
             title: '已做',

+ 1 - 1
front/project/www/routes/exercise/list/page.js

@@ -33,7 +33,7 @@ export default class extends Page {
           <div className="table-row">
             <div className="night f-s-16">{record.title}</div>
             <div>
-              <ProgressText progress={progress} times={record.paper ? record.paper.times : 0} size="small" />
+              <ProgressText progress={progress} times={record.paper ? record.paper.finishTimes : 0} size="small" />
             </div>
           </div>
         );

+ 4 - 4
front/project/www/routes/exercise/main/page.js

@@ -51,7 +51,7 @@ const exerciseColumns = [{
       <div className="table-row">
         <div className="night f-s-16">{record.title}</div>
         <div>
-          <ProgressText progress={progress} times={record.paper ? record.paper.times : 0} size="small" />
+          <ProgressText progress={progress} times={record.paper ? record.paper.finishTimes : 0} size="small" />
         </div>
       </div>
     );
@@ -147,7 +147,7 @@ export default class extends Page {
           <div className="table-row">
             <div className="night f-s-16">{record.title}</div>
             <div>
-              <ProgressText progress={progress} times={record.paper ? record.paper.times : 0} size="small" />
+              <ProgressText progress={progress} times={record.paper ? record.paper.finishTimes : 0} size="small" />
             </div>
           </div>
         );
@@ -508,7 +508,7 @@ export default class extends Page {
     Question.getExerciseProgress(type.id).then(result => {
       // const exerciseProgress = getMap(r, 'id');
       result = result.map(row => {
-        row.title = `${row.titleZh}${row.titleEn}`;
+        row.title = `${row.titleZh}`;
         row.info = [
           {
             title: '已做',
@@ -657,7 +657,7 @@ export default class extends Page {
     const { paperChecked, paperList } = this.state;
     value = paperChecked === value ? null : value;
     const list = paperList.filter(row => {
-      const finish = row.paper ? row.paper.times > 0 : false;
+      const finish = row.paper ? row.paper.finishTimes > 0 : false;
       if (value === 0) {
         return !finish;
       } if (value === 1) {

+ 1 - 1
front/project/www/routes/my/answer/page.js

@@ -98,7 +98,7 @@ export default class extends Page {
       needSentence: false,
       allSubject: true,
     }).then(({ questionTypes }) => {
-      return refreshStruct(this, data.tab, data.one, data.two, {
+      return refreshStruct(this, questionTypes, data.tab, data.one, data.two, {
         all: true,
         needPreview: false,
         needTextbook: true,

+ 3 - 3
front/project/www/routes/my/course/page.js

@@ -624,7 +624,7 @@ class CourseOnline extends Component {
         render: text => {
           text = text || {};
           const progress = text.report ? formatPercent(text.report.userNumber, text.report.questionNumber) : 0;
-          const times = text.paper ? text.paper.times : 0;
+          const times = text.paper ? text.paper.finishTimes : 0;
           return (
             <div>
               <div className="v-a-m d-i-b">
@@ -687,7 +687,7 @@ class CourseOnline extends Component {
         key: 'progress',
         render: (text, record) => {
           const { paper = {} } = record;
-          return `${paper.paper && paper.paper.times > 0 ? `${paper.paper.times}次+` : ''}${
+          return `${paper.paper && paper.paper.finishTimes > 0 ? `${paper.paper.finishTimes}次+` : ''}${
             paper.report ? formatPercent(paper.report.userNumber, paper.report.questionNumber, false) : '0%'}`;
         },
       },
@@ -1065,7 +1065,7 @@ class CourseVs extends Component {
           render: text => {
             text = text || {};
             const progress = text.report ? formatPercent(text.report.userNumber, text.report.questionNumber) : 0;
-            const times = text.paper ? text.paper.times : 0;
+            const times = text.paper ? text.paper.finishTimes : 0;
             return (
               <div>
                 <div className="v-a-m d-i-b">

+ 2 - 2
front/project/www/routes/my/data/page.js

@@ -326,8 +326,8 @@ export default class extends Page {
     }
     const [startTime, endTime] = timeRange(data.timerange);
     refreshQuestionType(this, data.subject, data.questionType, { needSentence: false, allSubject: false })
-      .then(() => {
-        return refreshStruct(this, data.tab, data.one, data.two, {
+      .then(({ questionTypes }) => {
+        return refreshStruct(this, questionTypes, data.tab, data.one, data.two, {
           all: true, needPreview: false, needTextbook: false,
         });
       })

+ 1 - 1
front/project/www/routes/my/error/page.js

@@ -147,7 +147,7 @@ export default class extends Page {
       needSentence: true,
       allSubject: true,
     }).then(({ questionTypes }) => {
-      return refreshStruct(this, data.tab, data.one, data.two, {
+      return refreshStruct(this, questionTypes, data.tab, data.one, data.two, {
         all: true,
         needPreview: false,
         needTextbook: true,

+ 8 - 10
front/project/www/routes/my/index.js

@@ -49,7 +49,7 @@ export function refreshQuestionType(compontent, subject, questionType, { all, ne
   });
 }
 
-export function refreshStruct(compontent, module, one, two, { all, needTextbook, needPreview }) {
+export function refreshStruct(compontent, questionTypes, module, one, two, { all, needTextbook, needPreview }) {
   switch (module) {
     case 'exercise':
       return Main.getExerciseAll().then(result => {
@@ -67,20 +67,19 @@ export function refreshStruct(compontent, module, one, two, { all, needTextbook,
               key: row.key,
               structIds: [],
               parentId: row.level > 3 ? idsMap[row.parentId] : null,
-              subject: [],
-              questionType: [],
+              questionTypes: [],
             };
           }
           const item = map[row.key];
           item.structIds.push(row.id);
-          if (item.subject.indexOf(row.subject) < 0) {
-            item.subject.push(row.subject);
-          }
-          if (item.questionType.indexOf(row.questionType) < 0) {
-            item.questionType.push(row.questionType);
+          if (item.questionTypes.indexOf(row.extend) < 0) {
+            item.questionTypes.push(row.extend);
           }
         });
-        const list = Object.values(map);
+        let list = Object.values(map);
+        if (questionTypes && questionTypes.length > 0) {
+          list = list.filter(row => row.questionTypes.filter((v) => questionTypes.indexOf(v) >= 0).length);
+        }
         if (needPreview) {
           list.push({
             title: '预习作业',
@@ -111,7 +110,6 @@ export function refreshStruct(compontent, module, one, two, { all, needTextbook,
             structIds = resultMap[two];
           }
         }
-
         const tree = formatTreeData(list, 'key', 'title', 'parentId');
         const oneSelect = tree;
         const twoSelectMap = getMap(tree, 'key', 'children');

+ 5 - 1
front/project/www/routes/my/main/page.js

@@ -382,6 +382,9 @@ export default class extends Page {
             </a>
           );
         })}
+        onClick={() => {
+          if (this.state.showCal) this.setState({ showCal: false });
+        }}
       />
     );
   }
@@ -449,7 +452,8 @@ export default class extends Page {
             {day === 'other' && <span>{formatDate(time, 'YYYY-MM-DD')}</span>}
             <Assets
               name="calendar"
-              onClick={() => {
+              onClick={(e) => {
+                e.stopPropagation();
                 this.setState({ showCal: true });
               }}
             />

+ 1 - 1
front/project/www/routes/my/note/page.js

@@ -112,7 +112,7 @@ export default class extends Page {
       needSentence: false,
       allSubject: true,
     }).then(({ questionTypes }) => {
-      return refreshStruct(this, data.tab, data.one, data.two, {
+      return refreshStruct(this, questionTypes, data.tab, data.one, data.two, {
         all: true,
         needPreview: false,
         needTextbook: false,

+ 6 - 4
front/project/www/routes/my/report/page.js

@@ -468,6 +468,8 @@ export default class extends Page {
     data.filterMap = this.state.search;
     if (data.order) {
       data.sortMap = { [data.order]: data.direction };
+    } else {
+      data.sortMap = { latest_time: 'desc' };
     }
     if (data.timerange) {
       data.filterMap.timerange = data.timerange;
@@ -501,15 +503,15 @@ export default class extends Page {
           all: true,
           needSentence: true,
           allSubject: true,
-        }).then(({ questionTypes, courseModules }) => {
-          return refreshStruct(this, data.tab, data.one, data.two, {
+        }).then(({ questionTypes }) => {
+          return refreshStruct(this, questionTypes, data.tab, data.one, data.two, {
             all: true,
             needPreview: true,
             needTextbook: false,
-          }).then(({ structIds, latest, year }) => {
+          }).then(({ structIds, courseModules }) => {
             My.listReport(
               Object.assign(
-                { module: data.tab, questionTypes, structIds, latest, year, courseModules, startTime, endTime },
+                { module: data.tab, questionTypes, structIds, courseModules, startTime, endTime },
                 this.state.search,
                 {
                   order: Object.keys(data.sortMap)

+ 6 - 6
front/project/www/routes/paper/process/base/index.js

@@ -333,12 +333,12 @@ export default class extends Component {
               <div className="desc-info">{formatSeconds(paper.time)}</div>
             </div>
           </div>
-          {paper.times > 0 && <div className="tip">
+          {paper.finishTimes > 0 && <div className="tip">
             <Checkbox className="m-r-1" checked={!disorder} onChange={() => flow.setSetting({ disorder: !!disorder })} />
             题目选项乱序显示
           </div>}
           <div className="submit">
-            <Button size="lager" radius onClick={() => flow.start({ disorder: paper.times > 0 ? !disorder : false })}>
+            <Button size="lager" radius onClick={() => flow.start({ disorder: paper.finishTimes > 0 ? !disorder : false })}>
               开始练习
             </Button>
           </div>
@@ -381,12 +381,12 @@ export default class extends Component {
           })}
         </div>
         <div className="bottom">
-          {paper.times > 0 && <div className="text">
+          {paper.finishTimes > 0 && <div className="text">
             <Checkbox checked={!disorder} onChange={() => flow.setSetting({ disorder: !!disorder })} /> 题目选项乱序显示
           </div>}
           <div className="text">
             Click{' '}
-            <div className="next" onClick={() => flow.start({ disorder: paper.times > 0 ? !disorder : false, order })}>
+            <div className="next" onClick={() => flow.start({ disorder: paper.finishTimes > 0 ? !disorder : false, order })}>
               Next
               <Assets name="next_icon" />
             </div>{' '}
@@ -429,12 +429,12 @@ export default class extends Component {
           })}
         </div>
         <div className="bottom">
-          {paper.times > 0 && <div className="text">
+          {paper.finishTimes > 0 && <div className="text">
             <Checkbox checked={!disorder} onChange={() => flow.setSetting({ disorder: !!disorder })} /> 题目选项乱序显示
           </div>}
           <div className="text">
             Click{' '}
-            <div className="next" onClick={() => flow.start({ disorder: paper.times > 0 ? !disorder : false, order: order.filter(row => row) })}>
+            <div className="next" onClick={() => flow.start({ disorder: paper.finishTimes > 0 ? !disorder : false, order: order.filter(row => row) })}>
               Next
               <Assets name="next_icon" />
             </div>{' '}

+ 9 - 3
front/project/www/routes/paper/process/page.js

@@ -25,6 +25,9 @@ export default class extends Page {
 
     this.startInterval = null;
     this.startTime = 0;
+
+    this.baseRef = null;
+    this.sentenceRef = null;
   }
 
   initState() {
@@ -193,7 +196,9 @@ export default class extends Page {
     const { report } = this.state;
     return Question.stage(report.id)
       .then(() => {
-        return this.relaxStage();
+        this.baseRef.expireTime(() => {
+          this.relaxStage();
+        });
       });
   }
 
@@ -234,6 +239,7 @@ export default class extends Page {
       this.stageInterval = setInterval(() => {
         this.stageTime += 1;
         if (this.stageTime >= this.stageProcess.time) {
+          this.stageQuestionTime(0, true);
           const { scene } = this.state;
           if (scene === 'relax') {
             // 进入下一阶段,获取下一题
@@ -332,9 +338,9 @@ export default class extends Page {
     if (!paper.id || !scene) return null;
     switch (paper.paperModule) {
       case 'sentence':
-        return <Sentence key={userQuestion.id} {...this.state} flow={this} mode='process' />;
+        return <Sentence ref={(ref) => { this.sentenceRef = ref; }} key={userQuestion.id} {...this.state} flow={this} mode='process' />;
       default:
-        return <Base key={userQuestion.id} {...this.state} flow={this} mode='process' />;
+        return <Base ref={(ref) => { this.baseRef = ref; }} key={userQuestion.id} {...this.state} flow={this} mode='process' />;
     }
   }
 }

+ 25 - 22
front/project/www/routes/paper/report/page.js

@@ -176,6 +176,9 @@ function lineOption1(title, data, legend, color) {
       formatter: (params) => {
         return formatSeconds(params.value[params.seriesIndex + 1]);
       },
+      position: (point) => {
+        return [point[0] + 5, point[1] + 5];
+      },
     },
     legend: {
       show: legend.length > 1,
@@ -238,12 +241,12 @@ function barOption1(title, value, allValue, avgCorrect, avgIncorrent) {
       ],
     },
   ];
-  const xAxis2 = {
-    type: 'category',
-    axisTick: { show: false },
-    axisLine: { lineStyle: { color: '#D1D6DF' } },
-    splitLine: { show: false },
-  };
+  // const xAxis2 = {
+  //   type: 'category',
+  //   axisTick: { show: false },
+  //   axisLine: { lineStyle: { color: '#D1D6DF' } },
+  //   splitLine: { show: false },
+  // };
   const yAxis1 = [
     {
       gridIndex: 0,
@@ -264,14 +267,14 @@ function barOption1(title, value, allValue, avgCorrect, avgIncorrent) {
       splitLine: { show: false },
     },
   ];
-  const yAxis2 = {
-    show: false,
-    min: 0,
-    max: 100,
-    axisTick: { show: false },
-    axisLine: { show: false },
-    splitLine: { show: false },
-  };
+  // const yAxis2 = {
+  //   show: false,
+  //   min: 0,
+  //   max: 100,
+  //   axisTick: { show: false },
+  //   axisLine: { show: false },
+  //   splitLine: { show: false },
+  // };
   const data1 = {
     type: 'bar',
     barWidth: 50,
@@ -343,13 +346,13 @@ function barOption1(title, value, allValue, avgCorrect, avgIncorrent) {
         textVerticalAlign: 'middle',
         textStyle: { color: '#686872', fontWeight: '500', fontSize: 14, lineHeight: 20 },
         bottom: '2%',
-        left: '26%',
+        left: '28%',
       },
     ],
-    xAxis: avgCorrect ? xAxis1 : xAxis2,
-    yAxis: avgCorrect ? yAxis1 : yAxis2,
-    grid: avgCorrect ? [{ width: 200, x: 72 }, { width: 350, x: 272 }] : { width: 200, left: '30%' },
-    series: avgCorrect ? [data1, data2] : [data1],
+    xAxis: xAxis1, // : xAxis2,
+    yAxis: yAxis1, // : yAxis2,
+    grid: [{ width: 200, x: 72 }, { width: 350, x: 272 }], // : { width: 200, left: '30%' },
+    series: [data1, data2], // : [data1],
   };
 }
 
@@ -713,7 +716,7 @@ export default class extends Page {
             </div>
             <div className="right">
               <div className="text">{user.info.nickname}</div>
-              <div className="desc">练习次数{paper.times + 1}</div>
+              <div className="desc">练习次数{report.times}</div>
               <div className="desc">{formatDate(report.updateTime, 'YYYY-MM-DD HH:mm:ss')}</div>
             </div>
           </div>
@@ -750,7 +753,7 @@ export default class extends Page {
             </div>
             <div className="right">
               <div className="text">{user.info.nickname}</div>
-              <div className="desc">练习次数{paper.times + 1}</div>
+              <div className="desc">练习次数{report.times}</div>
               <div className="desc">{formatDate(report.updateTime, 'YYYY-MM-DD HH:mm:ss')}</div>
             </div>
           </div>
@@ -783,7 +786,7 @@ export default class extends Page {
             </div>
             <div className="right">
               <div className="text">{user.info.nickname}</div>
-              <div className="desc">练习次数{paper.times + 1}</div>
+              <div className="desc">练习次数{report.times}</div>
               <div className="desc">{formatDate(report.updateTime, 'YYYY-MM-DD HH:mm:ss')}</div>
             </div>
           </div>

+ 8 - 9
front/project/www/routes/question/index.js

@@ -40,7 +40,7 @@ export function refreshQuestionType(compontent, subject, questionType, { all, ne
   });
 }
 
-export function refreshStruct(compontent, module, one, two, { all }) {
+export function refreshStruct(compontent, questionTypes, module, one, two, { all }) {
   switch (module) {
     case 'exercise':
       return Main.getExerciseAll().then(result => {
@@ -58,20 +58,19 @@ export function refreshStruct(compontent, module, one, two, { all }) {
               key: row.key,
               structIds: [],
               parentId: row.level > 3 ? idsMap[row.parentId] : null,
-              subject: [],
-              questionType: [],
+              questionTypes: [],
             };
           }
           const item = map[row.key];
           item.structIds.push(row.id);
-          if (item.subject.indexOf(row.subject) < 0) {
-            item.subject.push(row.subject);
-          }
-          if (item.questionType.indexOf(row.questionType) < 0) {
-            item.questionType.push(row.questionType);
+          if (item.questionTypes.indexOf(row.extend) < 0) {
+            item.questionTypes.push(row.extend);
           }
         });
-        const list = Object.values(map);
+        let list = Object.values(map);
+        if (questionTypes && questionTypes.length > 0) {
+          list = list.filter(row => row.questionTypes.filter((v) => questionTypes.indexOf(v) >= 0).length);
+        }
         let courseModules = null;
         let structIds = null;
         if (one === 'preview') {

+ 1 - 1
front/project/www/routes/question/search/page.js

@@ -55,7 +55,7 @@ export default class extends Page {
       allSubject: true,
       excludeAwa: true,
     }).then(({ questionTypes }) => {
-      return refreshStruct(this, 'exercise', data.one, data.two, {
+      return refreshStruct(this, questionTypes, 'exercise', data.one, data.two, {
         all: true,
       }).then(({ structIds }) => {
         let handler = null;

+ 1 - 1
front/project/www/routes/textbook/list/page.js

@@ -29,7 +29,7 @@ export default class extends Page {
           <div className="table-row">
             <div className="night f-s-16">{record.title}</div>
             <div>
-              <ProgressText progress={progress} times={record.paper ? record.paper.times : 0} size="small" />
+              <ProgressText progress={progress} times={record.paper ? record.paper.finishTimes : 0} size="small" />
             </div>
           </div>
         );

+ 1 - 1
front/src/components/Assets/index.js

@@ -9,7 +9,7 @@ function Assets(props) {
       style={{ width, height }}
       className={`assets ${className} ${!(!name && !src) || 'hide'}`}
       src={src || `/assets/${name}.${svg ? 'svg' : 'png'}`}
-      onClick={() => onClick && onClick()}
+      onClick={(e) => onClick && onClick(e)}
     />
   );
 }

+ 44 - 0
front/src/components/Editor/index.js

@@ -1,8 +1,13 @@
 import React from 'react';
+import Quill from 'quill';
 import ReactQuill from 'react-quill';
 import 'react-quill/dist/quill.snow.css';
+import './index.less';
 import { generateUUID } from '../../services/Tools';
 
+const Delta = Quill.imports.delta;
+const Parchment = Quill.imports.parchment;
+
 const defaultContainer = [
   [{ header: '1' }, { header: '2' }],
   ['bold', 'underline', 'blockquote'],
@@ -30,6 +35,31 @@ const formats = [
   'image',
   // 'video',
 ];
+class ListAttributor extends Parchment.Attributor.Style {
+  value(node) {
+    // console.log(node);
+    const style = node.style || {};
+    return style.listStyleType;
+    // return super.value(node);
+  }
+
+  add(node, value) {
+    // console.log(node, value);
+    node.style.listStyleType = value;
+    return true;
+  }
+}
+
+const ListClass = new Parchment.Attributor.Class('list-style-customer', 'ql-list', {
+  scope: Parchment.Scope.BLOCK_BLOT,
+});
+const ListStyleType = new ListAttributor('list-style', 'list-style-type', {
+  scope: Parchment.Scope.BLOCK_BLOT,
+});
+// console.log(ListStyleType);
+Quill.register(ListStyleType, true);
+Quill.register(ListClass, true);
+
 class Editor extends React.Component {
   constructor(props) {
     super(props);
@@ -45,6 +75,20 @@ class Editor extends React.Component {
       clipboard: {
         // toggle to add extra line breaks when pasting HTML:
         matchVisual: true,
+        matchers: [
+          ['ol', (node, delta) => {
+            const style = node.style || {};
+            if (style.listStyleType) {
+              delta = delta.reduce((d, op) => {
+                // if (op.attributes && op.attributes['list-style']) {
+                //   return d.push(op);
+                // }
+                return d.insert(op.insert, Object.assign({}, op.attributes, { 'list-style': ListStyleType.value(node), 'list-style-customer': 'customer' }));
+              }, new Delta());
+            }
+            return delta;
+          }],
+        ],
       },
     };
     this.modules = Object.assign(this.modules, props.modules);

+ 12 - 0
front/src/components/Editor/index.less

@@ -0,0 +1,12 @@
+@charset "utf-8";
+
+.ql-editor ol li.ql-list-customer,
+.ql-editor ul li.ql-list-customer {
+  padding-left: 0;
+}
+
+.ql-editor li.ql-list-customer:before {}
+
+.ql-editor ol li.ql-list-customer:before {
+  content: "";
+}

+ 3 - 12
server/data/src/main/java/com/qxgmat/data/dao/entity/ExercisePaper.java

@@ -16,9 +16,6 @@ public class ExercisePaper implements Serializable {
     @Column(name = "`question_type`")
     private String questionType;
 
-    /**
-     * 组卷名称
-     */
     @Column(name = "`title`")
     private String title;
 
@@ -105,18 +102,14 @@ public class ExercisePaper implements Serializable {
     }
 
     /**
-     * 获取组卷名称
-     *
-     * @return title - 组卷名称
+     * @return title
      */
     public String getTitle() {
         return title;
     }
 
     /**
-     * 设置组卷名称
-     *
-     * @param title 组卷名称
+     * @param title
      */
     public void setTitle(String title) {
         this.title = title;
@@ -317,9 +310,7 @@ public class ExercisePaper implements Serializable {
         }
 
         /**
-         * 设置组卷名称
-         *
-         * @param title 组卷名称
+         * @param title
          */
         public Builder title(String title) {
             obj.setTitle(title);

+ 3 - 12
server/data/src/main/java/com/qxgmat/data/dao/entity/Question.java

@@ -27,9 +27,6 @@ public class Question implements Serializable {
     @Column(name = "`question_type`")
     private String questionType;
 
-    /**
-     * 考点: 读取setting
-     */
     @Column(name = "`place`")
     private String place;
 
@@ -199,18 +196,14 @@ public class Question implements Serializable {
     }
 
     /**
-     * 获取考点: 读取setting
-     *
-     * @return place - 考点: 读取setting
+     * @return place
      */
     public String getPlace() {
         return place;
     }
 
     /**
-     * 设置考点: 读取setting
-     *
-     * @param place 考点: 读取setting
+     * @param place
      */
     public void setPlace(String place) {
         this.place = place;
@@ -642,9 +635,7 @@ public class Question implements Serializable {
         }
 
         /**
-         * 设置考点: 读取setting
-         *
-         * @param place 考点: 读取setting
+         * @param place
          */
         public Builder place(String place) {
             obj.setPlace(place);

+ 35 - 0
server/data/src/main/java/com/qxgmat/data/dao/entity/UserPaper.java

@@ -84,6 +84,12 @@ public class UserPaper implements Serializable {
     private Integer times;
 
     /**
+     * 完成次数
+     */
+    @Column(name = "`finish_times`")
+    private Integer finishTimes;
+
+    /**
      * 单次时间:系统时间
      */
     @Column(name = "`time`")
@@ -364,6 +370,24 @@ public class UserPaper implements Serializable {
     }
 
     /**
+     * 获取完成次数
+     *
+     * @return finish_times - 完成次数
+     */
+    public Integer getFinishTimes() {
+        return finishTimes;
+    }
+
+    /**
+     * 设置完成次数
+     *
+     * @param finishTimes 完成次数
+     */
+    public void setFinishTimes(Integer finishTimes) {
+        this.finishTimes = finishTimes;
+    }
+
+    /**
      * 获取单次时间:系统时间
      *
      * @return time - 单次时间:系统时间
@@ -526,6 +550,7 @@ public class UserPaper implements Serializable {
         sb.append(", questionNoIds=").append(questionNoIds);
         sb.append(", questionNumber=").append(questionNumber);
         sb.append(", times=").append(times);
+        sb.append(", finishTimes=").append(finishTimes);
         sb.append(", time=").append(time);
         sb.append(", latestTime=").append(latestTime);
         sb.append(", latestReportId=").append(latestReportId);
@@ -688,6 +713,16 @@ public class UserPaper implements Serializable {
         }
 
         /**
+         * 设置完成次数
+         *
+         * @param finishTimes 完成次数
+         */
+        public Builder finishTimes(Integer finishTimes) {
+            obj.setFinishTimes(finishTimes);
+            return this;
+        }
+
+        /**
          * 设置最近一次做题时间
          *
          * @param latestTime 最近一次做题时间

+ 35 - 0
server/data/src/main/java/com/qxgmat/data/dao/entity/UserReport.java

@@ -111,6 +111,12 @@ public class UserReport implements Serializable {
     @Column(name = "`is_stat`")
     private Integer isStat;
 
+    /**
+     * 第几次
+     */
+    @Column(name = "`times`")
+    private Integer times;
+
     @Column(name = "`create_time`")
     private Date createTime;
 
@@ -436,6 +442,24 @@ public class UserReport implements Serializable {
     }
 
     /**
+     * 获取第几次
+     *
+     * @return times - 第几次
+     */
+    public Integer getTimes() {
+        return times;
+    }
+
+    /**
+     * 设置第几次
+     *
+     * @param times 第几次
+     */
+    public void setTimes(Integer times) {
+        this.times = times;
+    }
+
+    /**
      * @return create_time
      */
     public Date getCreateTime() {
@@ -487,6 +511,7 @@ public class UserReport implements Serializable {
         sb.append(", detail=").append(detail);
         sb.append(", isFinish=").append(isFinish);
         sb.append(", isStat=").append(isStat);
+        sb.append(", times=").append(times);
         sb.append(", createTime=").append(createTime);
         sb.append(", updateTime=").append(updateTime);
         sb.append("]");
@@ -591,6 +616,16 @@ public class UserReport implements Serializable {
         }
 
         /**
+         * 设置第几次
+         *
+         * @param times 第几次
+         */
+        public Builder times(Integer times) {
+            obj.setTimes(times);
+            return this;
+        }
+
+        /**
          * 设置已做题目数
          *
          * @param userNumber 已做题目数

+ 4 - 3
server/data/src/main/java/com/qxgmat/data/dao/mapping/UserPaperMapper.xml

@@ -18,8 +18,9 @@
     <result column="question_no_ids" jdbcType="VARCHAR" property="questionNoIds" typeHandler="com.nuliji.tools.mybatis.handler.IntegerArrayWithJsonHandler" />
     <result column="question_number" jdbcType="INTEGER" property="questionNumber" />
     <result column="times" jdbcType="INTEGER" property="times" />
+    <result column="finish_times" jdbcType="INTEGER" property="finishTimes" />
     <result column="time" jdbcType="INTEGER" property="time" />
-    <result column="latest_time" jdbcType="DATE" property="latestTime" />
+    <result column="latest_time" jdbcType="TIMESTAMP" property="latestTime" />
     <result column="latest_report_id" jdbcType="INTEGER" property="latestReportId" />
     <result column="total_time" jdbcType="INTEGER" property="totalTime" />
     <result column="total_number" jdbcType="INTEGER" property="totalNumber" />
@@ -33,7 +34,7 @@
     -->
     `id`, `user_id`, `title`, `paper_module`, `paper_origin`, `is_adapt`, `origin_id`, 
     `record_id`, `paper_no`, `qx_cat`, `question_no_ids`, `question_number`, `times`, 
-    `time`, `latest_time`, `latest_report_id`, `total_time`, `total_number`, `total_correct`, 
-    `delete_time`, `is_reset`
+    `finish_times`, `time`, `latest_time`, `latest_report_id`, `total_time`, `total_number`, 
+    `total_correct`, `delete_time`, `is_reset`
   </sql>
 </mapper>

+ 2 - 1
server/data/src/main/java/com/qxgmat/data/dao/mapping/UserReportMapper.xml

@@ -23,6 +23,7 @@
     <result column="detail" jdbcType="VARCHAR" property="detail" typeHandler="com.nuliji.tools.mybatis.handler.JsonObjectHandler" />
     <result column="is_finish" jdbcType="INTEGER" property="isFinish" />
     <result column="is_stat" jdbcType="INTEGER" property="isStat" />
+    <result column="times" jdbcType="INTEGER" property="times" />
     <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
     <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
   </resultMap>
@@ -32,6 +33,6 @@
     -->
     `id`, `user_id`, `paper_id`, `paper_module`, `paper_origin`, `origin_id`, `question_no_ids`, 
     `question_number`, `time`, `user_number`, `user_time`, `user_correct`, `finish_time`, 
-    `setting`, `score`, `detail`, `is_finish`, `is_stat`, `create_time`, `update_time`
+    `setting`, `score`, `detail`, `is_finish`, `is_stat`, `times`, `create_time`, `update_time`
   </sql>
 </mapper>

+ 1 - 0
server/data/src/main/java/com/qxgmat/data/relation/UserPaperRelationMapper.java

@@ -19,6 +19,7 @@ public interface UserPaperRelationMapper {
             @Param("time") Integer time,
             @Param("correct") Integer correct,
             @Param("times") Integer times,
+            @Param("finish") Integer finish,
             @Param("latestTime") Date latestTime,
             @Param("latestReportId") Integer latestReportId
     );

+ 4 - 3
server/data/src/main/java/com/qxgmat/data/relation/mapping/UserPaperRelationMapper.xml

@@ -22,6 +22,7 @@
       `total_time`=`total_time`+#{time, jdbcType=INTEGER},
       `total_correct`=`total_correct`+#{correct, jdbcType=INTEGER},
       `times` = `times`+#{times, jdbcType=INTEGER},
+      `finish_times` = `finish_times`+#{finish, jdbcType=INTEGER},
       `latest_time` = #{latestTime, jdbcType=DATE},
       `latest_report_id` = #{latestReportId, jdbcType=INTEGER},
     </trim>
@@ -101,13 +102,13 @@
         #{item}
       </foreach>
     </if>
+    left join `preview_paper` pp on pa.`paper_id` = pp.`id`
     <if test="questionTypes != null">
       and
       <foreach collection="questionTypes" item="item" index="index" open="(" close=")" separator=" or ">
-        pa.`question_type` = #{item}
+        pp.`question_type` = #{item}
       </foreach>
     </if>
-    left join `preview_paper` pp on pa.`paper_id` = pp.`id`
     where up.`user_id` = #{userId,jdbcType=VARCHAR} and ur.`id` is not null
     <if test="keyword != null">
       and (ep.`title` like #{keywordLike,jdbcType=VARCHAR}
@@ -118,7 +119,7 @@
       and ep.`id` > 0
     </if>
     <if test="structIds == null">
-      and (ep.`id` > 0 or sp.`id` > 0 or pa.`id` > 0)
+      and (ep.`id` > 0 or sp.`id` > 0 or pp.`id` > 0)
     </if>
     <if test="courseModules != null">
       and (pa.`id` > 0)

+ 3 - 0
server/data/src/main/resources/db/migration/V8__update_report.sql

@@ -0,0 +1,3 @@
+ALTER TABLE user_report add column times int(11) unsigned NOT NULL DEFAULT '0' COMMENT '第几次' AFTER is_stat;
+
+ALTER TABLE user_paper add column finish_times int(11) unsigned NOT NULL DEFAULT '0' COMMENT '完成次数' AFTER times;

+ 16 - 4
server/gateway-api/src/main/java/com/qxgmat/controller/admin/SettingController.java

@@ -21,6 +21,7 @@ import com.qxgmat.service.UsersService;
 import com.qxgmat.service.extend.MessageExtendService;
 import com.qxgmat.service.extend.OrderFlowService;
 import com.qxgmat.service.inline.*;
+import com.qxgmat.task.AsyncTask;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@@ -94,6 +95,9 @@ public class SettingController {
     @Autowired
     private OrderFlowService orderFlowService;
 
+    @Autowired
+    private AsyncTask asyncTask;
+
     @RequestMapping(value = "/index", method = RequestMethod.PUT)
     @ApiOperation(value = "修改首页配置", httpMethod = "PUT")
     private Response<Boolean> editIndex(@RequestBody @Validated JSONObject dto){
@@ -793,9 +797,12 @@ public class SettingController {
 
     @RequestMapping(value = "/rank/list", method = RequestMethod.GET)
     @ApiOperation(value = "获取排行设置", httpMethod = "GET")
-    private Response<List<Rank>> getRank(){
-        List<Rank> rankList = rankService.all();
-        return ResponseHelp.success(rankList);
+    private Response<PageMessage<Rank>> getRank(
+            @RequestParam(required = false, defaultValue = "1") int page,
+            @RequestParam(required = false, defaultValue = "100") int size
+    ){
+        Page<Rank> p = rankService.select(page, size);
+        return ResponseHelp.success(p, page, size, p.getTotal());
     }
 
     @RequestMapping(value = "/rank/import", method = RequestMethod.POST)
@@ -831,6 +838,11 @@ public class SettingController {
         for(int i=1;i<=lastRowNum;i++){
             row = sheet.getRow(i);
             rank = new Rank();
+
+            cell = row.getCell(0);
+            if (cell==null){
+                break;
+            }
             for(int j=0;j<totalColumns;j++){
                 cell = row.getCell(j);
                 if(cell!=null){
@@ -866,7 +878,7 @@ public class SettingController {
             }
             rankList.add(rank);
         }
-        rankService.replaceAll(rankList);
+        asyncTask.refreshRank(rankList);
         return ResponseHelp.success(rankList.size());
     }
 }

+ 10 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserPaperBaseExtendDto.java

@@ -13,6 +13,8 @@ public class UserPaperBaseExtendDto {
 
     private Integer times;
 
+    private Integer finishTimes;
+
     private String title;
 
     private Integer paperNo;
@@ -98,4 +100,12 @@ public class UserPaperBaseExtendDto {
     public void setPaperOrigin(String paperOrigin) {
         this.paperOrigin = paperOrigin;
     }
+
+    public Integer getFinishTimes() {
+        return finishTimes;
+    }
+
+    public void setFinishTimes(Integer finishTimes) {
+        this.finishTimes = finishTimes;
+    }
 }

+ 10 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserPaperDetailExtendDto.java

@@ -12,6 +12,8 @@ public class UserPaperDetailExtendDto {
 
     private Integer times;
 
+    private Integer finishTimes;
+
     private String title;
 
     private String paperModule;
@@ -77,4 +79,12 @@ public class UserPaperDetailExtendDto {
     public void setPaperOrigin(String paperOrigin) {
         this.paperOrigin = paperOrigin;
     }
+
+    public Integer getFinishTimes() {
+        return finishTimes;
+    }
+
+    public void setFinishTimes(Integer finishTimes) {
+        this.finishTimes = finishTimes;
+    }
 }

+ 10 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserReportExtendDto.java

@@ -36,6 +36,8 @@ public class UserReportExtendDto {
 
     private JSONObject score;
 
+    private Integer times;
+
     public Integer getId() {
         return id;
     }
@@ -139,4 +141,12 @@ public class UserReportExtendDto {
     public void setPaperOrigin(String paperOrigin) {
         this.paperOrigin = paperOrigin;
     }
+
+    public Integer getTimes() {
+        return times;
+    }
+
+    public void setTimes(Integer times) {
+        this.times = times;
+    }
 }

+ 9 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/response/PaperBaseDto.java

@@ -12,6 +12,7 @@ public class PaperBaseDto {
     private Integer time;
     private Integer questionNumber;
     private Integer times;
+    private Integer finishTimes;
     private Integer isAdapt;
 
     public Integer getQuestionNumber() {
@@ -77,4 +78,12 @@ public class PaperBaseDto {
     public void setTimes(Integer times) {
         this.times = times;
     }
+
+    public Integer getFinishTimes() {
+        return finishTimes;
+    }
+
+    public void setFinishTimes(Integer finishTimes) {
+        this.finishTimes = finishTimes;
+    }
 }

+ 10 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/response/UserReportBaseDto.java

@@ -33,6 +33,8 @@ public class UserReportBaseDto {
 
     private JSONObject setting;
 
+    private Integer times;
+
     private Date updateTime;
 
     public Integer getId() {
@@ -138,4 +140,12 @@ public class UserReportBaseDto {
     public void setOriginId(Integer originId) {
         this.originId = originId;
     }
+
+    public Integer getTimes() {
+        return times;
+    }
+
+    public void setTimes(Integer times) {
+        this.times = times;
+    }
 }

+ 10 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/response/UserReportDetailDto.java

@@ -46,6 +46,8 @@ public class UserReportDetailDto {
 
     private Integer isFinish;
 
+    private Integer times;
+
     public Integer getId() {
         return id;
     }
@@ -181,4 +183,12 @@ public class UserReportDetailDto {
     public void setUser(UserExtendDto user) {
         this.user = user;
     }
+
+    public Integer getTimes() {
+        return times;
+    }
+
+    public void setTimes(Integer times) {
+        this.times = times;
+    }
 }

+ 1 - 1
server/gateway-api/src/main/java/com/qxgmat/service/UserPaperService.java

@@ -289,7 +289,7 @@ public class UserPaperService extends AbstractService {
      * @param report
      */
     public void accumulation(UserReport report){
-        userPaperRelationMapper.accumulation(report.getPaperId(), report.getUserNumber(), report.getUserTime(), report.getUserCorrect(), report.getIsFinish(), report.getFinishTime(), report.getId());
+        userPaperRelationMapper.accumulation(report.getPaperId(), report.getUserNumber(), report.getUserTime(), report.getUserCorrect(), 1, report.getIsFinish(), report.getFinishTime(), report.getId());
     }
 
     public int countByUser(Integer userId, PaperOrigin origin){

+ 7 - 3
server/gateway-api/src/main/java/com/qxgmat/service/extend/QuestionFlowService.java

@@ -759,7 +759,6 @@ public class QuestionFlowService {
         StatReport statReportCallback = finishCallback.get(PaperModule.ValueOf(userReport.getPaperModule()));
         statReportCallback.callback(userReport, userQuestionList);
         userReport.setIsStat(1);
-        userReportService.edit(userReport);
 
         FinishAfterReport finishAfterReportCallback = finishAfterCallback.get(PaperOrigin.ValueOf(userReport.getPaperOrigin()));
         if(finishAfterReportCallback != null){
@@ -767,11 +766,14 @@ public class QuestionFlowService {
         }
         // 统计: 更新对应paper记录
         userPaperService.accumulation(userReport);
+        UserPaper userPaper = userPaperService.get(userReport.getPaperId());
+        userReport.setTimes(userPaper.getTimes());
+        userReportService.edit(userReport);
         return true;
     }
 
     /**
-     * 重新开始一份试卷:设定试卷reset=1,列表不绑定最后一次考试记录
+     * 重新开始一份试卷:设定试卷reset=1
      * @param userPaperId
      * @param userId
      * @return
@@ -789,7 +791,6 @@ public class QuestionFlowService {
         StatReport callback = finishCallback.get(PaperModule.ValueOf(userReport.getPaperModule()));
         callback.callback(userReport, userQuestionList);
         userReport.setIsStat(1);
-        userReportService.edit(userReport);
 
         FinishAfterReport finishAfterReportCallback = finishAfterCallback.get(PaperOrigin.ValueOf(userReport.getPaperOrigin()));
         if(finishAfterReportCallback != null){
@@ -797,6 +798,9 @@ public class QuestionFlowService {
         }
         // 统计: 更新对应paper记录
         userPaperService.accumulation(userReport);
+        UserPaper userPaper = userPaperService.get(userReport.getPaperId());
+        userReport.setTimes(userPaper.getTimes());
+        userReportService.edit(userReport);
         return userPaperService.reset(userPaperId, userId);
     }
 

+ 12 - 0
server/gateway-api/src/main/java/com/qxgmat/task/AsyncTask.java

@@ -61,6 +61,9 @@ public class AsyncTask {
     private MessageExtendService messageExtendService;
 
     @Autowired
+    private RankService rankService;
+
+    @Autowired
     private UserServiceService userServiceService;
 
     @Autowired
@@ -321,4 +324,13 @@ public class AsyncTask {
         long end = System.currentTimeMillis();
         logger.info("资料更新,耗时:" + (end - start) + "毫秒");
     }
+
+    @Async
+    public void refreshRank(List<Rank> rankList){
+        logger.info("资料更新");
+        long start = System.currentTimeMillis();
+        rankService.replaceAll(rankList);
+        long end = System.currentTimeMillis();
+        logger.info("资料更新,耗时:" + (end - start) + "毫秒");
+    }
 }

+ 1 - 1
server/tools/src/main/java/com/nuliji/tools/shiro/RoleFilter.java

@@ -24,7 +24,7 @@ public class RoleFilter extends RolesAuthorizationFilter {
     @Override
     public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
         Subject subject = getSubject(request, response);
-        if(!subject.isAuthenticated()){
+        if(!subject.isAuthenticated() && !subject.isRemembered()){
             logger.debug("not login");
             return false;
         }

+ 18 - 0
uploaded.sh

@@ -0,0 +1,18 @@
+#!/bin/bash
+CURRENT_PATH=$(pwd);
+ROOT_PATH=$(cd `dirname $0`/; pwd);
+RUN_PATH=${ROOT_PATH}
+
+echo $1
+TARGET=$1
+
+cd ${RUN_PATH}
+pwd
+
+if [[ $TARGET = "gateway" ]]
+then
+  npx pm2 start --hp ${RUN_PATH} ${RUN_PATH}/pm2.json
+elif [[ $TARGET = "gateway-all" ]]
+then
+  npx pm2 start --hp ${RUN_PATH} ${RUN_PATH}/pm2.json
+fi