Browse Source

fix(front): 修复bug

Go 5 years ago
parent
commit
977c83309b
31 changed files with 152 additions and 62 deletions
  1. 6 2
      front/project/www/components/OtherModal/index.less
  2. 4 0
      front/project/www/components/Panel/index.js
  3. 1 1
      front/project/www/components/ProgressButton/index.js
  4. 6 0
      front/project/www/components/ProgressButton/index.less
  5. 1 1
      front/project/www/components/UserTable/index.less
  6. 1 1
      front/project/www/routes/examination/list/page.js
  7. 1 1
      front/project/www/routes/exercise/list/page.js
  8. 1 1
      front/project/www/routes/exercise/main/page.js
  9. 25 11
      front/project/www/routes/my/collect/page.js
  10. 24 6
      front/project/www/routes/my/error/page.js
  11. 14 8
      front/project/www/routes/my/main/page.js
  12. 6 0
      front/project/www/routes/my/note/index.less
  13. 1 0
      front/project/www/routes/my/note/page.js
  14. 1 1
      front/project/www/routes/my/report/page.js
  15. 1 1
      front/project/www/routes/page/export/page.js
  16. 4 4
      front/project/www/routes/paper/question/detail/index.js
  17. 1 1
      front/project/www/routes/preview/list/page.js
  18. 1 1
      front/project/www/routes/textbook/list/page.js
  19. 1 0
      front/src/components/PieChart/index.js
  20. 2 2
      server/data/src/main/java/com/qxgmat/data/relation/mapping/UserQuestionRelationMapper.xml
  21. 13 10
      server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java
  22. 1 1
      server/gateway-api/src/main/java/com/qxgmat/controller/api/QuestionController.java
  23. 12 1
      server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserExerciseExtendDto.java
  24. 10 0
      server/gateway-api/src/main/java/com/qxgmat/dto/response/UserQuestionDetailDto.java
  25. 1 1
      server/gateway-api/src/main/java/com/qxgmat/service/UsersService.java
  26. 6 0
      server/gateway-api/src/main/java/com/qxgmat/service/extend/QuestionFlowService.java
  27. 2 2
      server/gateway-api/src/main/java/com/qxgmat/service/extend/TextbookService.java
  28. 1 1
      server/gateway-api/src/main/java/com/qxgmat/service/inline/SentencePaperService.java
  29. 1 1
      server/gateway-api/src/main/java/com/qxgmat/service/inline/TextbookPaperService.java
  30. 1 1
      server/gateway-api/src/main/java/com/qxgmat/service/inline/TextbookQuestionService.java
  31. 2 2
      server/gateway-api/src/main/java/com/qxgmat/task/AsyncTask.java

+ 6 - 2
front/project/www/components/OtherModal/index.less

@@ -164,6 +164,7 @@
     width: 630px;
     color: #686872;
     padding: 20px 30px;
+
     .modal-content {
       margin: 0 auto;
     }
@@ -281,11 +282,14 @@
           }
         }
 
-        .tab.active,
-        .tab:hover {
+        .tab.active {
           color: #fff;
           background: #4299FF;
         }
+
+        .tab:hover {
+          color: #4299FF;
+        }
       }
 
       .input {

+ 4 - 0
front/project/www/components/Panel/index.js

@@ -18,6 +18,9 @@ function makePie(value, text, subtext) {
       top: '28%',
       left: '48%',
     },
+    tooltip: {
+      show: false,
+    },
     // value < 50 ? '#f19057' :
     color: ['#6966fb', '#f7f7f7'],
     series: [
@@ -28,6 +31,7 @@ function makePie(value, text, subtext) {
           show: false,
         },
         data: [value, 100 - value],
+        silent: true,
       },
     ],
   };

+ 1 - 1
front/project/www/components/ProgressButton/index.js

@@ -12,7 +12,7 @@ function ProgressButton(props) {
       }}
     >
       <div className="progress" style={{ width: `${progress}%` }} />
-      {children}
+      <div className="progress-content">{children}</div>
     </div>
   );
 }

+ 6 - 0
front/project/www/components/ProgressButton/index.less

@@ -20,6 +20,12 @@
     top: 0;
     bottom: 0;
     left: 0;
+    z-index: 0;
+  }
+
+  .progress-content {
+    position: relative;
+    z-index: 1;
   }
 }
 

+ 1 - 1
front/project/www/components/UserTable/index.less

@@ -39,7 +39,7 @@
     }
 
     td {
-      padding: 20px;
+      padding: 15px;
     }
   }
 

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

@@ -586,7 +586,7 @@ export default class extends Page {
   }
 
   restart(item) {
-    asyncConfirm('提示', '是否重置', () => {
+    asyncConfirm('提示', '你打算重做本套练习,过往做题记录可至「个人中心-报告」查看。', () => {
       Question.restart(item.paper.id).then(() => {
         this.refresh();
       });

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

@@ -238,7 +238,7 @@ export default class extends Page {
   }
 
   restart(item) {
-    asyncConfirm('提示', '是否重置', () => {
+    asyncConfirm('提示', '你打算重做本套练习,过往做题记录可至「个人中心-报告」查看。', () => {
       Question.restart(item.paper.id).then(() => {
         this.refresh();
       });

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

@@ -610,7 +610,7 @@ export default class extends Page {
   }
 
   restart(item) {
-    asyncConfirm('提示', '是否重置', () => {
+    asyncConfirm('提示', '你打算重做本套练习,过往做题记录可至「个人中心-报告」查看。', () => {
       Question.restart(item.paper.id).then(() => {
         this.refresh();
       });

+ 25 - 11
front/project/www/routes/my/collect/page.js

@@ -1,4 +1,5 @@
 import React, { Component } from 'react';
+import { Link } from 'react-router-dom';
 import './index.less';
 import { Icon, Checkbox } from 'antd';
 import Page from '@src/containers/Page';
@@ -57,6 +58,7 @@ export default class extends Page {
       {
         key: 'question_type',
         title: '题型',
+        width: 115,
         render: (text, record) => {
           return QuestionTypeMap[record.questionType];
         },
@@ -65,39 +67,50 @@ export default class extends Page {
       {
         key: 'title',
         title: '题目ID',
+        width: 100,
         fixSort: true,
+        render: (text, record) => {
+          return <Link to={`/question/detail/${record.questionNoId}`}>{text}</Link>;
+        },
       },
       {
         key: 'description',
         title: '内容',
+        width: 220,
+        render: (text) => {
+          return <div style={{ maxHeight: '80px', overflow: 'hidden' }}>{text}</div>;
+        },
       },
       {
         key: 'time',
         title: '耗时',
+        width: 80,
         sort: true,
         render: (text, record) => {
-          const user = record.stat.userTime / record.stat.userNumber;
-          const all = record.questionNo.totalTime / record.questionNo.totalNumber;
+          const user = record.stat ? record.stat.userTime / record.stat.userNumber : 0;
+          const all = record.questionNo.totalNumber ? record.questionNo.totalTime / record.questionNo.totalNumber : 0;
           return <div className="sub">
-            <div className="t-2 t-s-12">{formatSeconds(user)}<Assets height={10} width={10} name={user > all ? 'up' : 'down'} /></div>
-            <div className="t-6 t-s-12">全站{formatSeconds(all)}</div>
+            <div className="t-2 t-s-12">{user > 0 ? formatSeconds(user) : '-'}{user > 0 && <Assets height={10} width={10} name={user > all ? 'up' : 'down'} />}</div>
+            <div className="t-6 t-s-12">全站{all > 0 ? formatSeconds(all) : '-'}</div>
           </div>;
         },
       },
       {
         key: 'correct',
         title: '错误率',
+        width: 95,
         sort: true,
         render: (text, record) => {
           return <div className="sub">
-            <div className="t-2 t-s-12">{formatPercent(record.stat.userNumber - record.stat.userCorrect, record.stat.userNumber, false)}</div>
-            <div className="t-6 t-s-12">{record.stat.userNumber - record.stat.userCorrect}/{record.stat.userNumber}</div>
+            <div className="t-2 t-s-12">{record.stat ? formatPercent(record.stat.userNumber - record.stat.userCorrect, record.stat.userNumber, false) : '-'}</div>
+            <div className="t-6 t-s-12">{record.stat ? `${record.stat.userNumber - record.stat.userCorrect}/${record.stat.userNumber}` : '-'}</div>
           </div>;
         },
       },
       {
         key: 'latest_time',
         title: '最近做题',
+        width: 95,
         render: (text) => {
           return <div className="sub">
             <div className="t-2 t-s-12">{text.split(' ')[0]}</div>
@@ -157,11 +170,12 @@ export default class extends Page {
         ),
       ).then(result => {
         result.list = result.list.map(row => {
+          row.questionNo = row.questionNo || {};
           row.key = row.questionNoId;
           row.questionType = row.question.questionType;
           row.title = row.questionNo.title;
           row.description = row.question.description;
-          row.latest_time = formatDate(row.latestTime, 'YYYY-MM-DD HH:mm:ss');
+          row.latest_time = row.latestTime ? formatDate(row.latestTime, 'YYYY-MM-DD HH:mm:ss') : '';
           return row;
         });
         this.setState({ list: result.list, total: result.total });
@@ -256,10 +270,10 @@ export default class extends Page {
           this.setState({ showVip: true });
           return;
         }
-        // if (selectList.length < 10) {
-        //   this.setState({ showWarn: true, warn: { title: '组卷练习', content: '不可小于10题,请重新选择' } });
-        //   return;
-        // }
+        if (selectList.length < 10) {
+          this.setState({ showWarn: true, warn: { title: '组卷练习', content: '不可小于10题,请重新选择' } });
+          return;
+        }
         if (selectList.length > 50) {
           this.setState({ showWarn: true, warn: { title: '组卷练习', content: '不可多余50题,请重新选择' } });
           return;

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

@@ -1,4 +1,5 @@
 import React from 'react';
+import { Link } from 'react-router-dom';
 import './index.less';
 import { Icon, Checkbox } from 'antd';
 import Page from '@src/containers/Page';
@@ -54,6 +55,7 @@ export default class extends Page {
       {
         key: 'question_type',
         title: '题型',
+        width: 115,
         render: (text, record) => {
           return QuestionTypeMap[record.questionType];
         },
@@ -62,39 +64,50 @@ export default class extends Page {
       {
         key: 'title',
         title: '题目ID',
+        width: 100,
         fixSort: true,
+        render: (text, record) => {
+          return <Link to={`/paper/question/${record.id}`}>{text}</Link>;
+        },
       },
       {
         key: 'description',
         title: '内容',
+        width: 220,
+        render: (text) => {
+          return <div style={{ maxHeight: '80px', overflow: 'hidden' }}>{text}</div>;
+        },
       },
       {
         key: 'time',
         title: '耗时',
+        width: 80,
         sort: true,
         render: (text, record) => {
-          const user = record.stat.userTime / record.stat.userNumber;
-          const all = record.questionNo.totalTime / record.questionNo.totalNumber;
+          const user = record.stat ? record.stat.userTime / record.stat.userNumber : 0;
+          const all = record.questionNo.totalNumber ? record.questionNo.totalTime / record.questionNo.totalNumber : 0;
           return <div className="sub">
-            <div className="t-2 t-s-12">{formatSeconds(user)}<Assets height={10} width={10} name={user > all ? 'up' : 'down'} /></div>
-            <div className="t-6 t-s-12">全站{formatSeconds(all)}</div>
+            <div className="t-2 t-s-12">{user > 0 ? formatSeconds(user) : '-'}{user > 0 && <Assets height={10} width={10} name={user > all ? 'up' : 'down'} />}</div>
+            <div className="t-6 t-s-12">全站{all > 0 ? formatSeconds(all) : '-'}</div>
           </div>;
         },
       },
       {
         key: 'correct',
         title: '错误率',
+        width: 95,
         sort: true,
         render: (text, record) => {
           return <div className="sub">
-            <div className="t-2 t-s-12">{formatPercent(record.stat.userNumber - record.stat.userCorrect, record.stat.userNumber, false)}</div>
-            <div className="t-6 t-s-12">{record.stat.userNumber - record.stat.userCorrect}/{record.stat.userNumber}</div>
+            <div className="t-2 t-s-12">{record.stat ? formatPercent(record.stat.userNumber - record.stat.userCorrect, record.stat.userNumber, false) : '-'}</div>
+            <div className="t-6 t-s-12">{record.stat ? `${record.stat.userNumber - record.stat.userCorrect}/${record.stat.userNumber}` : '-'}</div>
           </div>;
         },
       },
       {
         key: 'latest_time',
         title: '最近做题',
+        width: 95,
         render: (text) => {
           return <div className="sub">
             <div className="t-2 t-s-12">{text.split(' ')[0]}</div>
@@ -154,7 +167,12 @@ export default class extends Page {
           ),
         ).then(result => {
           result.list = result.list.map(row => {
+            row.questionNo = row.questionNo || {};
             row.key = row.questionNoId;
+            row.questionType = row.question.questionType;
+            row.title = row.questionNo.title;
+            row.description = row.question.description;
+            row.latest_time = row.latestTime ? formatDate(row.latestTime, 'YYYY-MM-DD HH:mm:ss') : '';
             return row;
           });
           this.setState({ list: result.list, total: result.total });

+ 14 - 8
front/project/www/routes/my/main/page.js

@@ -233,16 +233,21 @@ export default class extends Page {
     Main.getAd('my-self').then(result => {
       this.setState({ ads: result });
     });
+    this.refreshDay(this.state.day);
+    this.refreshMessage();
+  }
+
+  refreshMessage() {
     // 获取未读消息
     My.message({ page: 1, size: 2, read: 0 }).then(result => {
       this.setState({ messages: result.list });
     });
-    this.refreshDay(this.state.day);
   }
 
   readAllMessage() {
     My.readAllMessage().then(() => {
       User.refreshToken();
+      this.refreshMessage();
       asyncSMessage('操作成功');
     });
   }
@@ -271,7 +276,7 @@ export default class extends Page {
       const study = [];
       const exerciseMap = {};
       result.exerciseList.forEach(row => {
-        exerciseMap[row.title] = row;
+        exerciseMap[row.key] = row;
       });
       study.push({
         type: 'exercise',
@@ -297,15 +302,15 @@ export default class extends Page {
           },
           {
             title: '平均正确率',
-            sc: exerciseMap.sc ? formatPercent(exerciseMap.sc.correct, exerciseMap.sc.number) : '-%',
-            cr: exerciseMap.cr ? formatPercent(exerciseMap.cr.correct, exerciseMap.cr.number) : '-%',
-            rc: exerciseMap.rc ? formatPercent(exerciseMap.rc.correct, exerciseMap.rc.number) : '-%',
+            sc: exerciseMap.sc ? formatPercent(exerciseMap.sc.correct, exerciseMap.sc.number, false) : '-%',
+            cr: exerciseMap.cr ? formatPercent(exerciseMap.cr.correct, exerciseMap.cr.number, false) : '-%',
+            rc: exerciseMap.rc ? formatPercent(exerciseMap.rc.correct, exerciseMap.rc.number, false) : '-%',
           },
           {
             title: '平均用时',
-            sc: exerciseMap.sc ? exerciseMap.sc.time / exerciseMap.sc.number : '-',
-            cr: exerciseMap.cr ? exerciseMap.cr.time / exerciseMap.cr.number : '-',
-            rc: exerciseMap.rc ? exerciseMap.rc.time / exerciseMap.rc.number : '-',
+            sc: exerciseMap.sc ? formatSeconds(exerciseMap.sc.time / exerciseMap.sc.number) : '-',
+            cr: exerciseMap.cr ? formatSeconds(exerciseMap.cr.time / exerciseMap.cr.number) : '-',
+            rc: exerciseMap.rc ? formatSeconds(exerciseMap.rc.time / exerciseMap.rc.number) : '-',
           },
         ],
       });
@@ -457,6 +462,7 @@ export default class extends Page {
                 disabledDate={date => date.unix() <= moment.unix()}
                 onChange={date => {
                   this.refreshDay(date);
+                  this.setState({ showCal: false });
                 }}
               />
             )}

+ 6 - 0
front/project/www/routes/my/note/index.less

@@ -48,6 +48,12 @@
 
         .group {
           display: inline-block;
+
+          &.text-hidden {
+            white-space: nowrap;
+            text-overflow: ellipsis;
+            overflow: hidden;
+          }
         }
 
         .sub {

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

@@ -131,6 +131,7 @@ export default class extends Page {
           ),
         ).then(result => {
           result.list = result.list.map(row => {
+            row.questionNo = row.questionNo || {};
             row.key = row.questionNoId;
             row.group = true;
             row.questionType = row.question.questionType;

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

@@ -122,7 +122,7 @@ export default class extends Page {
           const time = formatDate(report.updateTime, 'YYYY-MM-DD HH:mm:ss');
           return <div className="">
             <div className="t-2 t-s-12">{time.split(' ')[0]}
-              {childIndex === -1 && reports.length > 1 && (
+              {childIndex === -1 && reports && reports.length > 1 && (
                 <Popover
                   trigger="click"
                   content={

+ 1 - 1
front/project/www/routes/page/export/page.js

@@ -182,7 +182,7 @@ class BaseDetail extends Component {
     return [
       <div className="detail-item-block">
         <div className="t-1 t-s-16 m-b-2" dangerouslySetInnerHTML={{ __html: question.stem }} />
-        {this.renderSelect(question.content.question[0].select)}
+        {this.renderSelect(question.content.questions[0].select)}
       </div>,
       this.renderAnswer(),
     ];

+ 4 - 4
front/project/www/routes/paper/question/detail/index.js

@@ -420,7 +420,7 @@ export default class extends Component {
                       this.setState({ showAnswer: value });
                     }}
                   >
-                    {showAnswer ? '显示答案' : '关闭答案'}
+                    {showAnswer ? '显示答案' : '显示答案'}
                   </Switch>
                 )}
                 {this.renderAnswer()}
@@ -471,7 +471,7 @@ export default class extends Component {
                     this.setState({ showAnswer: value });
                   }}
                 >
-                  {showAnswer ? '显示答案' : '关闭答案'}
+                  {showAnswer ? '显示答案' : '显示答案'}
                 </Switch>
                 }
                 {this.renderAnswer()}
@@ -582,7 +582,7 @@ export default class extends Component {
               this.setState({ showAnswer: value });
             }}
           >
-            {showAnswer ? '显示答案' : '关闭答案'}
+            {showAnswer ? '显示答案' : '显示答案'}
           </Switch>
         )}
         {question.questionType === 'awa' && <h2>Analytical Writing Assessment</h2>}
@@ -614,7 +614,7 @@ export default class extends Component {
             this.setState({ showAnswer: value });
           }}
         >
-          {showAnswer ? '显示答案' : '关闭答案'}
+          {showAnswer ? '显示答案' : '显示答案'}
         </Switch>
         <div className="body">
           <h2>Your Response</h2>

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

@@ -242,7 +242,7 @@ export default class extends Page {
   }
 
   restart(item) {
-    asyncConfirm('提示', '是否重置', () => {
+    asyncConfirm('提示', '你打算重做本套练习,过往做题记录可至「个人中心-报告」查看。', () => {
       Question.restart(item.paper.id).then(() => {
         this.refresh();
       });

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

@@ -157,7 +157,7 @@ export default class extends Page {
   }
 
   restart(item) {
-    asyncConfirm('提示', '是否重置', () => {
+    asyncConfirm('提示', '你打算重做本套练习,过往做题记录可至「个人中心-报告」查看。', () => {
       Question.restart(item.paper.id).then(() => {
         this.refresh();
       });

+ 1 - 0
front/src/components/PieChart/index.js

@@ -14,6 +14,7 @@ function PieChart(props) {
       {
         data: [],
         type: 'pie',
+        silent: true,
       },
     ],
     xAxis: {

+ 2 - 2
server/data/src/main/java/com/qxgmat/data/relation/mapping/UserQuestionRelationMapper.xml

@@ -56,7 +56,7 @@
       and upq.`question_module` = uq.`question_module`
       and upq.`question_origin` = 'remove_error'
     where
-    q.`id` > 0 and upq.`id` = null and uq.`user_id` = #{userId,jdbcType=VARCHAR}
+    q.`id` > 0 and qn.`id` > 0 and upq.`id` is null and uq.`user_id` = #{userId,jdbcType=VARCHAR}
     <if test="keyword != null">
       and (q.`stem` like #{keywordLike,jdbcType=VARCHAR}
       or qn.`title` like #{keywordLike,jdbcType=VARCHAR}
@@ -122,7 +122,7 @@
       and upq.`question_module` = uq.`question_module`
       and upq.`question_origin` = 'remove_error'
     where
-    q.`id` > 0 and upq.`id` = null and uq.`user_id` = #{userId,jdbcType=VARCHAR}
+    q.`id` > 0 and qn.`id` > 0 and upq.`id` = null and uq.`user_id` = #{userId,jdbcType=VARCHAR}
     <if test="keyword != null">
       and (q.`stem` like #{keywordLike,jdbcType=VARCHAR}
       or qn.`title` like #{keywordLike,jdbcType=VARCHAR}

+ 13 - 10
server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java

@@ -487,15 +487,18 @@ public class MyController {
     @RequestMapping(value = "/prepare", method = RequestMethod.PUT)
     @ApiOperation(value = "修改备考信息", notes = "修改用户备考信息", httpMethod = "PUT")
     public Response<Boolean> editPrepare(@RequestBody @Validated UserPrepareDto dto)  {
-        User entity = Transform.dtoToEntity(dto);
         User user = (User) shiroHelp.getLoginUser();
-        entity.setId(user.getId());
-        if (user.getPrepareTime() == null){
-            // 邀请奖励
+        User entity = usersService.get(user.getId());
+
+        User prepareUser = Transform.dtoToEntity(dto);
+        prepareUser.setId(user.getId());
+        prepareUser.setPrepareTime(new Date());
+        usersService.edit(prepareUser);
+
+        if (entity.getPrepareTime() == null){
+            // 备考奖励
             orderFlowService.givePrepare(user);
         }
-        entity.setPrepareTime(new Date());
-        usersService.edit(entity);
 
         return ResponseHelp.success(true);
     }
@@ -552,7 +555,7 @@ public class MyController {
         for(UserStudyStatRelation type:typeList){
             exerciseTime += type.getUserTime();
             exerciseQuestion += type.getUserNumber();
-            exerciseList.add(new UserExerciseExtendDto(m.get(type.getModule()), type.getUserNumber(), type.getUserTime(), type.getUserCorrect()));
+            exerciseList.add(new UserExerciseExtendDto(type.getModule(), m.get(type.getModule()), type.getUserNumber(), type.getUserTime(), type.getUserCorrect()));
         }
         // todo 练习统计排行
         UserRankStatRelation exerciseRank = userReportService.rankExerciseByTime(user.getId(), start, end);
@@ -1017,7 +1020,7 @@ public class MyController {
 
         // 最近做题
         List<UserQuestion> lastList = userQuestionService.listWithLast(user.getId(), questionIds);
-        Map lastMap = Transform.getMap(lastList, UserQuestion.class, "id", "createTime");
+        Map lastMap = Transform.getMap(lastList, UserQuestion.class, "questionId", "createTime");
         Transform.combine(pr, lastMap, UserCollectQuestionInfoDto.class, "questionId", "latestTime");
 
         // 收藏、笔记
@@ -1076,7 +1079,7 @@ public class MyController {
         List<Question> questionList = questionService.select(questionIds);
         Transform.combine(pr, questionList, UserQuestionErrorInfoDto.class, "questionId", "question", Question.class, "id", QuestionExtendDto.class);
 
-        Collection questionNoIds = Transform.getIds(pr, UserQuestionErrorInfoDto.class, "questionId");
+        Collection questionNoIds = Transform.getIds(pr, UserQuestionErrorInfoDto.class, "questionNoId");
         List<QuestionNo> questionNoList = questionNoService.select(questionNoIds);
         Transform.combine(pr, questionNoList, UserQuestionErrorInfoDto.class, "questionNoId", "questionNo", QuestionNo.class, "id", QuestionNoExtendDto.class);
 
@@ -1087,7 +1090,7 @@ public class MyController {
 
         // 最近做题
         List<UserQuestion> lastList = userQuestionService.listWithLast(user.getId(), questionIds);
-        Map lastMap = Transform.getMap(lastList, UserQuestion.class, "id", "createTime");
+        Map lastMap = Transform.getMap(lastList, UserQuestion.class, "questionId", "createTime");
         Transform.combine(pr, lastMap, UserQuestionErrorInfoDto.class, "questionId", "latestTime");
 
         // 收藏、笔记

+ 1 - 1
server/gateway-api/src/main/java/com/qxgmat/controller/api/QuestionController.java

@@ -337,7 +337,7 @@ public class QuestionController {
                     extendDto.setId(child.getId());
                     extendDto.setTitleEn(child.getTitleEn());
                     extendDto.setTitleZh(child.getTitleZh());
-                    List<QuestionNo> childQuestionList = list.stream().filter((q)-> Collections.singletonList(q.getModuleStruct()).contains(child.getId().intValue())).collect(Collectors.toList());
+                    List<QuestionNo> childQuestionList = list.stream().filter((q)-> Arrays.stream(q.getModuleStruct()).filter((r)->r==child.getId()).count()>0).collect(Collectors.toList());
                     extendDto.setQuestionNumber(childQuestionList.size());
                     if (user != null){
                         int minTimes = 0;

+ 12 - 1
server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserExerciseExtendDto.java

@@ -1,6 +1,8 @@
 package com.qxgmat.dto.extend;
 
 public class UserExerciseExtendDto {
+    private String key;
+
     private String title;
 
     private Integer number;
@@ -9,7 +11,8 @@ public class UserExerciseExtendDto {
 
     private Integer correct;
 
-    public UserExerciseExtendDto(String title, Integer number, Integer time, Integer correct) {
+    public UserExerciseExtendDto(String key, String title, Integer number, Integer time, Integer correct) {
+        this.key = key;
         this.title = title;
         this.number = number;
         this.time = time;
@@ -47,4 +50,12 @@ public class UserExerciseExtendDto {
     public void setCorrect(Integer correct) {
         this.correct = correct;
     }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
 }

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

@@ -35,6 +35,8 @@ public class UserQuestionDetailDto {
 
     private JSONObject detail;
 
+    private Integer userTime;
+
     private QuestionDetailExtendDto question;
 
     private QuestionNoExtendDto questionNo;
@@ -208,4 +210,12 @@ public class UserQuestionDetailDto {
     public void setSetting(JSONObject setting) {
         this.setting = setting;
     }
+
+    public Integer getUserTime() {
+        return userTime;
+    }
+
+    public void setUserTime(Integer userTime) {
+        this.userTime = userTime;
+    }
 }

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

@@ -71,7 +71,7 @@ public class UsersService extends AbstractService {
     public String getTokenByUser(User user){
         UserToken ut = new UserToken();
         ut.setId(user.getId());
-        Date expire = new Date(new Date().getTime() + 86400);
+        Date expire = new Date(new Date().getTime() + 86400000);
         ut.setExpire(expire);
         String info = tokenHandler.toJson(ut);
         return CipherHelp.encrypt(info, CipherHelp.DES, secret);

+ 6 - 0
server/gateway-api/src/main/java/com/qxgmat/service/extend/QuestionFlowService.java

@@ -788,6 +788,12 @@ public class QuestionFlowService {
         userReport.setIsStat(1);
         userReportService.edit(userReport);
 
+        FinishAfterReport finishAfterReportCallback = finishAfterCallback.get(PaperOrigin.ValueOf(userReport.getPaperOrigin()));
+        if(finishAfterReportCallback != null){
+            finishAfterReportCallback.callback(userReport);
+        }
+        // 统计: 更新对应paper记录
+        userPaperService.accumulation(userReport);
         return userPaperService.reset(userPaperId, userId);
     }
 

+ 2 - 2
server/gateway-api/src/main/java/com/qxgmat/service/extend/TextbookService.java

@@ -24,7 +24,7 @@ import java.util.stream.Collectors;
 @Service
 public class TextbookService {
     SimpleDateFormat stringToDate = new SimpleDateFormat("yyyy-MM-dd");
-    SimpleDateFormat dateToString = new SimpleDateFormat("yyyy年MM月dd日");
+    SimpleDateFormat dateToString = new SimpleDateFormat("MM月dd日");
     SimpleDateFormat dateToDay = new SimpleDateFormat("dd日");
 
     @Value("${paper.textbookLength}")
@@ -337,7 +337,7 @@ public class TextbookService {
         String endDate;
         if (library.getEndDate()==null){
             // 至今
-            endDate = "now";
+            endDate = "Now";
         }else if(library.getStartDate().equals(library.getEndDate())){
             // 同月
             endDate = dateToString.format(library.getEndDate());

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

@@ -79,7 +79,7 @@ public class SentencePaperService extends AbstractService {
      * @return
      */
     public String generateTitle(String prefixTitle, Integer length, Integer no, Integer questionNumber){
-        return String.format("%s#%d~%d", prefixTitle, (no - 1) * length + 1, (no - 1) * length + questionNumber);
+        return String.format("%s(%d-%d)", prefixTitle, (no - 1) * length + 1, (no - 1) * length + questionNumber);
     }
 
     public SentencePaper getLast(SentenceLogic logic){

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

@@ -76,7 +76,7 @@ public class TextbookPaperService extends AbstractService {
      * @return
      */
     public String generateTitle(String prefixTitle, Integer length, Integer no, Integer questionNumber){
-        return String.format("%s#%d~%d", prefixTitle, (no - 1) * length + 1, (no - 1) * length + questionNumber);
+        return String.format("%s-(%d-%d)", prefixTitle, (no - 1) * length + 1, (no - 1) * length + questionNumber);
     }
 
     /**

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

@@ -105,7 +105,7 @@ public class TextbookQuestionService extends AbstractService {
      * @return
      */
     public String generateTitle(String prefixTitle, Integer no) {
-        return String.format("%s#%d", prefixTitle, no);
+        return String.format("%s-%d", prefixTitle, no);
     }
 
     /**

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

@@ -139,7 +139,7 @@ public class AsyncTask {
                 Integer yScore = y.getTotalNumber() > 0 ? y.getTotalCorrect() * 100/ y.getTotalNumber(): 0;
                 return yScore.compareTo(xScore);
             });
-            List<ExercisePaper> errorPapers = exerciseService.createPaper(prefixTitle, questionType, struct.getParentId(), struct.getId(), exerciseService.getPaperLength(), ExerciseLogic.ERROR, null, list);
+            List<ExercisePaper> errorPapers = exerciseService.createPaper("易错题", questionType, struct.getParentId(), struct.getId(), exerciseService.getPaperLength(), ExerciseLogic.ERROR, null, list);
             Collection errorIds = Transform.getIds(errorPapers, ExercisePaper.class, "id");
             exerciseService.switchPaper(struct.getParentId(), struct.getId(), ExerciseLogic.ERROR, errorIds);
         }
@@ -205,7 +205,7 @@ public class AsyncTask {
                 Integer yScore = y.getTotalNumber() > 0 ? y.getTotalCorrect() * 100/ y.getTotalNumber(): 0;
                 return yScore.compareTo(xScore);
             });
-            List<ExercisePaper> errorPapers = exerciseService.createPaper(prefixTitle, questionType, struct.getParentId(), struct.getId(), exerciseService.getPaperLength(), ExerciseLogic.ERROR, null, list);
+            List<ExercisePaper> errorPapers = exerciseService.createPaper("易错题", questionType, struct.getParentId(), struct.getId(), exerciseService.getPaperLength(), ExerciseLogic.ERROR, null, list);
             Collection errorIds = Transform.getIds(errorPapers, SentencePaper.class, "id");
             exerciseService.switchPaper(struct.getParentId(), struct.getId(), ExerciseLogic.ERROR, errorIds);
         }