浏览代码

fix(server): 修复变更

Go 5 年之前
父节点
当前提交
b521f9797f
共有 94 个文件被更改,包括 850 次插入286 次删除
  1. 28 5
      front/.eslintrc
  2. 5 0
      front/config/index.js
  3. 15 3
      front/config/local.json
  4. 4 4
      front/project/Constant.js
  5. 2 2
      front/project/admin/routes/course/data/page.js
  6. 0 1
      front/project/admin/routes/course/experience/page.js
  7. 2 0
      front/project/admin/routes/course/invoice/page.js
  8. 2 2
      front/project/admin/routes/interaction/askQuestion/index.js
  9. 13 14
      front/project/admin/routes/interaction/askQuestion/page.js
  10. 3 3
      front/project/admin/routes/interaction/askQuestionDetail/index.js
  11. 16 13
      front/project/admin/routes/interaction/askQuestionDetail/page.js
  12. 1 1
      front/project/admin/routes/interaction/comment/index.js
  13. 2 1
      front/project/admin/routes/interaction/comment/page.js
  14. 18 3
      front/project/admin/routes/student/askCourse/page.js
  15. 15 12
      front/project/admin/routes/student/askCourseDetail/page.js
  16. 15 3
      front/project/admin/routes/student/askQuestion/page.js
  17. 15 12
      front/project/admin/routes/student/askQuestionDetail/page.js
  18. 3 3
      front/project/admin/routes/student/studyDetail/page.js
  19. 1 3
      front/project/admin/routes/subject/examination/page.js
  20. 4 2
      front/project/admin/routes/subject/exercise/page.js
  21. 2 2
      front/project/admin/routes/subject/question/page.js
  22. 4 8
      front/project/admin/routes/subject/textbook/page.js
  23. 8 2
      front/project/admin/routes/user/abnormal/page.js
  24. 5 5
      front/project/admin/routes/user/detail/page.js
  25. 2 0
      front/project/admin/routes/user/list/page.js
  26. 3 2
      front/project/admin/routes/user/order/page.js
  27. 9 1
      front/project/admin/routes/user/recordAll/page.js
  28. 2 2
      front/project/h5/routes/page/home/page.js
  29. 2 2
      front/project/h5/routes/product/courseDetail/page.js
  30. 1 1
      front/project/h5/routes/product/courseVs/page.js
  31. 3 3
      front/project/www/components/Login/index.js
  32. 2 2
      front/src/containers/Async.js
  33. 24 19
      front/src/services/AsyncTools.js
  34. 35 0
      server/data/src/main/java/com/qxgmat/data/dao/entity/UserAskCourse.java
  35. 35 0
      server/data/src/main/java/com/qxgmat/data/dao/entity/UserAskQuestion.java
  36. 3 2
      server/data/src/main/java/com/qxgmat/data/dao/mapping/UserAskCourseMapper.xml
  37. 3 2
      server/data/src/main/java/com/qxgmat/data/dao/mapping/UserAskQuestionMapper.xml
  38. 14 0
      server/data/src/main/java/com/qxgmat/data/relation/MessageTemplateRelationMapper.java
  39. 2 1
      server/data/src/main/java/com/qxgmat/data/relation/TextbookQuestionRelationMapper.java
  40. 2 0
      server/data/src/main/java/com/qxgmat/data/relation/UserAbnormalRelationMapper.java
  41. 3 1
      server/data/src/main/java/com/qxgmat/data/relation/UserAskCourseRelationMapper.java
  42. 3 1
      server/data/src/main/java/com/qxgmat/data/relation/UserAskQuestionRelationMapper.java
  43. 26 0
      server/data/src/main/java/com/qxgmat/data/relation/mapping/MessageTemplateRelationMapper.xml
  44. 3 0
      server/data/src/main/java/com/qxgmat/data/relation/mapping/QuestionNoRelationMapper.xml
  45. 6 0
      server/data/src/main/java/com/qxgmat/data/relation/mapping/UserAbnormalRelationMapper.xml
  46. 11 5
      server/data/src/main/java/com/qxgmat/data/relation/mapping/UserAskCourseRelationMapper.xml
  47. 10 4
      server/data/src/main/java/com/qxgmat/data/relation/mapping/UserAskQuestionRelationMapper.xml
  48. 3 1
      server/gateway-api/src/main/java/com/qxgmat/controller/admin/CourseController.java
  49. 3 1
      server/gateway-api/src/main/java/com/qxgmat/controller/admin/QuestionController.java
  50. 0 1
      server/gateway-api/src/main/java/com/qxgmat/controller/admin/SettingController.java
  51. 2 2
      server/gateway-api/src/main/java/com/qxgmat/controller/admin/TextbookController.java
  52. 9 7
      server/gateway-api/src/main/java/com/qxgmat/controller/admin/UserController.java
  53. 0 1
      server/gateway-api/src/main/java/com/qxgmat/controller/api/BaseController.java
  54. 43 2
      server/gateway-api/src/main/java/com/qxgmat/controller/api/CourseController.java
  55. 5 0
      server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java
  56. 23 9
      server/gateway-api/src/main/java/com/qxgmat/dto/admin/extend/QuestionExtendDto.java
  57. 10 0
      server/gateway-api/src/main/java/com/qxgmat/dto/admin/extend/UserOrderRecordExtendDto.java
  58. 17 0
      server/gateway-api/src/main/java/com/qxgmat/dto/admin/request/UserFrozenDto.java
  59. 11 0
      server/gateway-api/src/main/java/com/qxgmat/dto/admin/response/TextbookQuestionListDto.java
  60. 10 0
      server/gateway-api/src/main/java/com/qxgmat/dto/admin/response/UserAskCourseListDto.java
  61. 10 0
      server/gateway-api/src/main/java/com/qxgmat/dto/admin/response/UserAskQuestionListDto.java
  62. 13 0
      server/gateway-api/src/main/java/com/qxgmat/dto/request/CourseTrailViewDto.java
  63. 13 0
      server/gateway-api/src/main/java/com/qxgmat/dto/request/ExperienceViewDto.java
  64. 18 0
      server/gateway-api/src/main/java/com/qxgmat/dto/response/CourseExperienceDetailDto.java
  65. 150 0
      server/gateway-api/src/main/java/com/qxgmat/dto/response/CourseExperienceListDto.java
  66. 2 2
      server/gateway-api/src/main/java/com/qxgmat/service/UserQuestionService.java
  67. 2 3
      server/gateway-api/src/main/java/com/qxgmat/service/UsersService.java
  68. 4 4
      server/gateway-api/src/main/java/com/qxgmat/service/extend/CourseExtendService.java
  69. 3 3
      server/gateway-api/src/main/java/com/qxgmat/service/extend/ExaminationService.java
  70. 4 3
      server/gateway-api/src/main/java/com/qxgmat/service/extend/ExerciseService.java
  71. 1 0
      server/gateway-api/src/main/java/com/qxgmat/service/extend/MessageExtendService.java
  72. 30 18
      server/gateway-api/src/main/java/com/qxgmat/service/extend/OrderFlowService.java
  73. 4 4
      server/gateway-api/src/main/java/com/qxgmat/service/extend/QuestionFlowService.java
  74. 4 4
      server/gateway-api/src/main/java/com/qxgmat/service/extend/SentenceService.java
  75. 1 1
      server/gateway-api/src/main/java/com/qxgmat/service/extend/TextbookService.java
  76. 2 3
      server/gateway-api/src/main/java/com/qxgmat/service/inline/CommentService.java
  77. 2 3
      server/gateway-api/src/main/java/com/qxgmat/service/inline/CourseExperienceService.java
  78. 2 3
      server/gateway-api/src/main/java/com/qxgmat/service/inline/FaqService.java
  79. 12 0
      server/gateway-api/src/main/java/com/qxgmat/service/inline/MessageTemplateService.java
  80. 2 3
      server/gateway-api/src/main/java/com/qxgmat/service/inline/PreviewPaperService.java
  81. 2 2
      server/gateway-api/src/main/java/com/qxgmat/service/inline/TextbookPaperService.java
  82. 7 8
      server/gateway-api/src/main/java/com/qxgmat/service/inline/TextbookQuestionService.java
  83. 4 5
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserAbnormalService.java
  84. 4 9
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserAskCourseService.java
  85. 4 6
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserAskQuestionService.java
  86. 2 2
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserCourseRecordService.java
  87. 2 3
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserFeedbackErrorService.java
  88. 8 11
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserOrderRecordService.java
  89. 2 3
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserOrderService.java
  90. 2 2
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserSentenceRecordService.java
  91. 2 3
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserTextbookFeedbackService.java
  92. 1 1
      server/gateway-api/src/main/java/com/qxgmat/task/AsyncTask.java
  93. 1 1
      server/gateway-api/src/main/java/com/qxgmat/task/ScheduledTask.java
  94. 7 0
      server/tools/src/main/java/com/nuliji/tools/Tools.java

+ 28 - 5
front/.eslintrc

@@ -1,11 +1,30 @@
 {
   "parser": "babel-eslint",
-  "extends": ["standard-react", "airbnb-base"],
-  "plugins": ["react", "import"],
+  "extends": [
+    "standard-react",
+    "airbnb-base"
+  ],
+  "plugins": [
+    "react",
+    "import"
+  ],
   "settings": {
     "import/resolver": {
       "alias": {
-        "map": [["@src", "./src"], ["@project", "./project/admin"], ["@components", "./components"]]
+        "map": [
+          [
+            "@src",
+            "./src"
+          ],
+          [
+            "@project",
+            "./project/admin"
+          ],
+          [
+            "@components",
+            "./components"
+          ]
+        ]
       }
     }
   },
@@ -34,7 +53,11 @@
     "sha1": false,
     "wx": false,
     "CKEDITOR": false,
-    "Masonry": false
+    "Masonry": false,
+    "__PcUrl__": false,
+    "__H5Url__": false,
+    "__WechatPcAppId__": false,
+    "__WechatH5AppId__": false
   },
   "rules": {
     "camelcase": "off",
@@ -61,4 +84,4 @@
     "import/no-named-as-default": "off",
     "operator-linebreak": "off"
   }
-}
+}

+ 5 - 0
front/config/index.js

@@ -52,6 +52,11 @@ config.globals = {
   __DEBUG__: config.env === 'development' || config.env === 'test',
   __API_PATH__: `\'${config.api_path}\'`,
   __BASE_NAME__: `\'${config.basename}\'`,
+
+  __PcUrl__: `\'config.PcUrl}\'`,
+  __WechatPcAppId__: `\'config.WechatPcAppId}\'`,
+  __H5Url__: `\'config.H5Url}\'`,
+  __WechatH5AppId__: `\'config.WechatH5AppId}\'`,
 };
 
 debug(`Looking for environment overrides for NODE_ENV '${config.env}'.`);

+ 15 - 3
front/config/local.json

@@ -14,7 +14,11 @@
         "from": "/",
         "to": "/"
       }
-    ]
+    ],
+    "PcUrl": "http://www.baidu.com",
+    "WechatPcAppId": "wx324965bb6800f9b9",
+    "H5Url": "http://127.0.0.1:3000",
+    "WechatH5AppId": "wxbee75af2ece94ed7"
   },
   "test": {
     "serverHost": "127.0.0.1",
@@ -24,7 +28,11 @@
     "keyword": "",
     "scripts": [],
     "publicPath": "/",
-    "basename": "/"
+    "basename": "/",
+    "PcUrl": "http://www.baidu.com",
+    "WechatPcAppId": "wx324965bb6800f9b9",
+    "H5Url": "http://127.0.0.1:3000",
+    "WechatH5AppId": "wxbee75af2ece94ed7"
   },
   "production": {
     "serverHost": "127.0.0.1",
@@ -34,6 +42,10 @@
     "keyword": "",
     "scripts": [],
     "publicPath": "/",
-    "basename": "/"
+    "basename": "/",
+    "PcUrl": "http://www.baidu.com",
+    "WechatPcAppId": "wx324965bb6800f9b9",
+    "H5Url": "http://127.0.0.1:3000",
+    "WechatH5AppId": "wxbee75af2ece94ed7"
   }
 }

+ 4 - 4
front/project/Constant.js

@@ -1,10 +1,10 @@
-export const UserUrl = 'http://www.baidu.com';
+export const PcUrl = __PcUrl__;
 
-export const WechatUserAppId = 'wx324965bb6800f9b9';
+export const WechatPcAppId = __WechatPcAppId__;
 
-export const H5Url = 'http://127.0.0.1:3000';
+export const H5Url = __H5Url__;
 
-export const WechatH5AppId = 'wxbee75af2ece94ed7';
+export const WechatH5AppId = __WechatH5AppId__;
 
 export const QuestionDifficult = [{ label: 'Easy', value: 'easy', sort: 2 }, { label: 'Medium', value: 'medium', sort: 1 }, { label: 'Hard', value: 'hard', sort: 0 }];
 

+ 2 - 2
front/project/admin/routes/course/data/page.js

@@ -78,12 +78,12 @@ export default class extends Page {
     }, {
       title: '查看人数',
       sorter: true,
-      sortDirections: ['ascend'],
+      // sortDirections: ['ascend'],
       dataIndex: 'viewNumber',
     }, {
       title: '购买人数',
       sorter: true,
-      sortDirections: ['descend'],
+      // sortDirections: ['descend'],
       dataIndex: 'saleNumber',
     }, {
       title: '更新时间',

+ 0 - 1
front/project/admin/routes/course/experience/page.js

@@ -189,7 +189,6 @@ export default class extends Page {
         onAction={key => this.onAction(key)}
       />
       <TableLayout
-        select
         columns={this.tableSort(this.columns)}
         list={this.state.list}
         pagination={this.state.page}

+ 2 - 0
front/project/admin/routes/course/invoice/page.js

@@ -41,9 +41,11 @@ export default class extends Page {
     this.actionList = [{
       key: 'download',
       name: '下载',
+      needSelect: 1,
     }, {
       key: 'finish',
       name: '批量开票',
+      needSelect: 1,
     }];
     this.columns = [{
       title: '申请时间',

+ 2 - 2
front/project/admin/routes/interaction/askQuestion/index.js

@@ -2,8 +2,8 @@ import module from '../../module';
 import group from '../group';
 
 export default {
-  path: '/innteraction/ask/question',
-  key: 'innteraction-ask-question',
+  path: '/interaction/ask/question',
+  key: 'interaction-ask-question',
   title: '非学员提问',
   needLogin: true,
   module,

+ 13 - 14
front/project/admin/routes/interaction/askQuestion/page.js

@@ -6,7 +6,7 @@ import Block from '@src/components/Block';
 import FilterLayout from '@src/layouts/FilterLayout';
 import ActionLayout from '@src/layouts/ActionLayout';
 import TableLayout from '@src/layouts/TableLayout';
-import { getMap, bindSearch, formatDate, formatSeconds } from '@src/services/Tools';
+import { getMap, bindSearch, formatDate } from '@src/services/Tools';
 import { asyncSMessage, asyncDelConfirm } from '@src/services/AsyncTools';
 import { QuestionType, AskStatus, MoneyRange, SwitchSelect, AskTarget, AskModule } from '../../../../Constant';
 import { User } from '../../../stores/user';
@@ -81,6 +81,10 @@ export default class extends Page {
       select: [],
       number: true,
       placeholder: '请输入',
+    }, {
+      key: 'time',
+      type: 'daterange',
+      name: '提问时间',
     }];
     this.columns = [{
       title: '板块',
@@ -110,22 +114,11 @@ export default class extends Page {
         return formatDate(text);
       },
     }, {
-      title: '倒计时',
-      dataIndex: 'askTime',
-      render: (text, record) => {
-        const end = new Date(record.answerTime) || new Date();
-        const cost = (end.getTime() - new Date(record.createTime).getTime()) / 1000;
-        if (text) {
-          if (text - cost > 0) return `${formatSeconds(text - cost)}/${formatSeconds(text)}`;
-          return `0/${formatSeconds(text)}`;
-        }
-        return '-';
-      },
-    }, {
       title: '回答者',
       dataIndex: 'manager.username',
     }, {
       title: '回答时间',
+      sorter: true,
       dataIndex: 'answerTime',
       render: (text) => {
         return text ? formatDate(text) : '';
@@ -172,7 +165,13 @@ export default class extends Page {
   }
 
   initData() {
-    Question.listAsk(Object.assign({ hasRecord: false }, this.state.search)).then(result => {
+    const { search } = this.state;
+    const data = Object.assign({ hasRecord: false }, search);
+    if (data.time) {
+      data.startTime = data.time[0] || '';
+      data.endTime = data.time[1] || '';
+    }
+    Question.listAsk(data).then(result => {
       this.setTableData(result.list, result.total);
     });
   }

+ 3 - 3
front/project/admin/routes/interaction/askQuestionDetail/index.js

@@ -2,13 +2,13 @@ import module from '../../module';
 import group from '../group';
 
 export default {
-  path: '/innteraction/ask/question/detail/:id?',
-  key: 'innteraction-ask-question-detail',
+  path: '/interaction/ask/question/detail/:id?',
+  key: 'interaction-ask-question-detail',
   title: '提问详情',
   needLogin: true,
   module,
   group,
-  showKey: 'innteraction-ask-question',
+  showKey: 'interaction-ask-question',
   component() {
     return import('./page');
   },

+ 16 - 13
front/project/admin/routes/interaction/askQuestionDetail/page.js

@@ -8,7 +8,7 @@ import DragList from '@src/components/DragList';
 // import FileUpload from '@src/components/FileUpload';
 import { formatFormError, formatDate, getMap } from '@src/services/Tools';
 import { asyncSMessage } from '@src/services/AsyncTools';
-import { UserUrl, AskTarget, QuestionType, AskModule } from '../../../../Constant';
+import { PcUrl, AskTarget, QuestionType, AskModule } from '../../../../Constant';
 // import { User } from '../../../stores/user';
 import { Question } from '../../../stores/question';
 
@@ -75,7 +75,6 @@ export default class extends Page {
       if (!err) {
         const data = form.getFieldsValue();
         data.showStatus = data.showStatus ? 1 : 0;
-        data.ignoreStatus = data.ignoreStatus ? 1 : 0;
         data.other = this.state.data.others.map(row => row.id);
         Question.editAsk(data).then(() => {
           asyncSMessage('保存成功');
@@ -86,6 +85,14 @@ export default class extends Page {
     });
   }
 
+  ignore() {
+    const { data } = this.state;
+    Question.editAsk({ id: data.id, ignoreStatus: 1 }).then(() => {
+      asyncSMessage('操作成功');
+      goBack();
+    });
+  }
+
   renderBase() {
     const { data } = this.state;
     const { question = {}, questionNo = {} } = data;
@@ -96,7 +103,7 @@ export default class extends Page {
           {AskModuleMap[data.askModule]}
         </Form.Item>
         <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='题型'>
-          {QuestionTypeMap[question.type]}
+          {QuestionTypeMap[question.questionType]}
         </Form.Item>
         <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='题目id'>
           <a href='' target='_blank'>{questionNo.no}</a>
@@ -150,7 +157,7 @@ export default class extends Page {
           this.orderQuestion(oldIndex, newIndex);
         }}
         renderItem={(item) => (
-          <List.Item actions={[<Icon type='bars' className='icon' />, <Typography.Text copyable={{ text: `${UserUrl}/paper/question/${this.state.data.userQuestionId}?askId=${item.id}` }} />]}>
+          <List.Item actions={[<Icon type='bars' className='icon' />, <Typography.Text copyable={{ text: `${PcUrl}/paper/question/${this.state.data.userQuestionId}?askId=${item.id}` }} />]}>
             <Row style={{ width: '100%' }}>
               <Col span={11}>问题:<span dangerouslySetInnerHTML={{ __html: item.content }} /></Col>
               <Col span={11} offset={1}>答复:<span dangerouslySetInnerHTML={{ __html: item.answer }} /></Col>
@@ -187,15 +194,6 @@ export default class extends Page {
               )}
             </Form.Item>
           </Col>
-          <Col span={12}>
-            <Form.Item labelCol={{ span: 12 }} wrapperCol={{ span: 10 }} label='是否忽略'>
-              {getFieldDecorator('ignoreStatus', {
-                valuePropName: 'checked',
-              })(
-                <Switch checkedChildren='on' unCheckedChildren='off' />,
-              )}
-            </Form.Item>
-          </Col>
         </Row>
       </Form>
     </Block>;
@@ -210,6 +208,11 @@ export default class extends Page {
 
       <Row type="flex" justify="center">
         <Col>
+          <Button type="drange" onClick={() => {
+            this.ignore();
+          }}>忽略问题</Button>
+        </Col>
+        <Col>
           <Button type="primary" onClick={() => {
             this.submit();
           }}>保存</Button>

+ 1 - 1
front/project/admin/routes/interaction/comment/index.js

@@ -3,7 +3,7 @@ import group from '../group';
 
 export default {
   path: '/interaction/comment',
-  key: 'innteraction-comment',
+  key: 'interaction-comment',
   title: '评价',
   needLogin: true,
   module,

+ 2 - 1
front/project/admin/routes/interaction/comment/page.js

@@ -91,7 +91,8 @@ export default class extends Page {
         return `${text.nickname || record.nickname}${extend ? `(${extend})` : ''}`;
       },
     }, {
-      title: '时间',
+      title: '评价时间',
+      sorter: true,
       dataIndex: 'createTime',
       render: (text) => {
         return formatDate(text);

+ 18 - 3
front/project/admin/routes/student/askCourse/page.js

@@ -68,6 +68,10 @@ export default class extends Page {
       name: '消费金额',
       select: MoneyRange,
       number: true,
+    }, {
+      key: 'time',
+      type: 'daterange',
+      name: '提问时间',
     }];
     this.columns = [{
       title: '学科',
@@ -101,12 +105,13 @@ export default class extends Page {
       },
     }, {
       title: '倒计时',
-      dataIndex: 'askTime',
+      sorter: true,
+      dataIndex: 'expireTime',
       render: (text, record) => {
         const end = new Date(record.answerTime) || new Date();
         const cost = (end.getTime() - new Date(record.createTime).getTime()) / 1000;
         if (text) {
-          if (text - cost > 0) return `${formatSeconds(text - cost)}/${formatSeconds(text)}`;
+          if (record.askTime - cost > 0) return `${formatSeconds(text - cost)}/${formatSeconds(text)}`;
           return `0/${formatSeconds(text)}`;
         }
         return '-';
@@ -116,6 +121,7 @@ export default class extends Page {
       dataIndex: 'manager.username',
     }, {
       title: '回答时间',
+      sorter: true,
       dataIndex: 'answerTime',
       render: (text) => {
         return text ? formatDate(text) : '';
@@ -172,7 +178,13 @@ export default class extends Page {
   }
 
   initData() {
-    Course.listAsk(this.state.search).then(result => {
+    const { search } = this.state;
+    const data = Object.assign({ hasRecord: true }, search);
+    if (data.time) {
+      data.startTime = data.time[0] || '';
+      data.endTime = data.time[1] || '';
+    }
+    Course.listAsk(data).then(result => {
       this.setTableData(result.list, result.total);
     });
   }
@@ -195,6 +207,9 @@ export default class extends Page {
         itemList={this.filterForm}
         data={this.state.search}
         onChange={data => {
+          if (data.time.length > 0) {
+            data.time = [data.time[0].format('YYYY-MM-DD HH:mm:ss'), data.time[1].format('YYYY-MM-DD HH:mm:ss')];
+          }
           this.search(data);
         }} />}
       {/* <ActionLayout

+ 15 - 12
front/project/admin/routes/student/askCourseDetail/page.js

@@ -8,7 +8,7 @@ import DragList from '@src/components/DragList';
 // import FileUpload from '@src/components/FileUpload';
 import { formatFormError, formatDate, formatTreeData, getMap } from '@src/services/Tools';
 import { asyncSMessage } from '@src/services/AsyncTools';
-import { UserUrl } from '../../../../Constant';
+import { PcUrl } from '../../../../Constant';
 import { Exercise } from '../../../stores/exercise';
 import { Course } from '../../../stores/course';
 
@@ -79,7 +79,6 @@ export default class extends Page {
       if (!err) {
         const data = form.getFieldsValue();
         data.showStatus = data.showStatus ? 1 : 0;
-        data.ignoreStatus = data.ignoreStatus ? 1 : 0;
         data.other = this.state.data.others.map(row => row.id);
         Course.editAsk(data).then(() => {
           asyncSMessage('保存成功');
@@ -90,6 +89,14 @@ export default class extends Page {
     });
   }
 
+  ignore() {
+    const { data } = this.state;
+    Course.editAsk({ id: data.id, ignoreStatus: 1 }).then(() => {
+      asyncSMessage('操作成功');
+      goBack();
+    });
+  }
+
   renderBase() {
     const { data } = this.state;
     const { course = {} } = data;
@@ -151,7 +158,7 @@ export default class extends Page {
           this.orderQuestion(oldIndex, newIndex);
         }}
         renderItem={(item) => (
-          <List.Item actions={[<Icon type='bars' className='icon' />, <Typography.Text copyable={{ text: `${UserUrl}/course/ask?askId=${item.id}` }} />]}>
+          <List.Item actions={[<Icon type='bars' className='icon' />, <Typography.Text copyable={{ text: `${PcUrl}/course/ask?askId=${item.id}` }} />]}>
             <Row style={{ width: '100%' }}>
               <Col span={11}>问题:<span dangerouslySetInnerHTML={{ __html: item.content }} /></Col>
               <Col span={11} offset={1}>答复:<span dangerouslySetInnerHTML={{ __html: item.answer }} /></Col>
@@ -188,15 +195,6 @@ export default class extends Page {
               )}
             </Form.Item>
           </Col>
-          <Col span={12}>
-            <Form.Item labelCol={{ span: 12 }} wrapperCol={{ span: 10 }} label='是否忽略'>
-              {getFieldDecorator('ignoreStatus', {
-                valuePropName: 'checked',
-              })(
-                <Switch checkedChildren='on' unCheckedChildren='off' />,
-              )}
-            </Form.Item>
-          </Col>
         </Row>
       </Form>
     </Block>;
@@ -211,6 +209,11 @@ export default class extends Page {
 
       <Row type="flex" justify="center">
         <Col>
+          <Button type="drange" onClick={() => {
+            this.ignore();
+          }}>忽略问题</Button>
+        </Col>
+        <Col>
           <Button type="primary" onClick={() => {
             this.submit();
           }}>保存</Button>

+ 15 - 3
front/project/admin/routes/student/askQuestion/page.js

@@ -81,6 +81,10 @@ export default class extends Page {
       select: [],
       number: true,
       placeholder: '请输入',
+    }, {
+      key: 'time',
+      type: 'daterange',
+      name: '提问时间',
     }];
     this.columns = [{
       title: '板块',
@@ -111,12 +115,13 @@ export default class extends Page {
       },
     }, {
       title: '倒计时',
-      dataIndex: 'askTime',
+      sorter: true,
+      dataIndex: 'expireTime',
       render: (text, record) => {
         const end = new Date(record.answerTime) || new Date();
         const cost = (end.getTime() - new Date(record.createTime).getTime()) / 1000;
         if (text) {
-          if (text - cost > 0) return `${formatSeconds(text - cost)}/${formatSeconds(text)}`;
+          if (record.askTime - cost > 0) return `${formatSeconds(text - cost)}/${formatSeconds(text)}`;
           return `0/${formatSeconds(text)}`;
         }
         return '-';
@@ -126,6 +131,7 @@ export default class extends Page {
       dataIndex: 'manager.username',
     }, {
       title: '回答时间',
+      sorter: true,
       dataIndex: 'answerTime',
       render: (text) => {
         return text ? formatDate(text) : '';
@@ -172,7 +178,13 @@ export default class extends Page {
   }
 
   initData() {
-    Question.listAsk(Object.assign({ hasRecord: true }, this.state.search)).then(result => {
+    const { search } = this.state;
+    const data = Object.assign({ hasRecord: true }, search);
+    if (data.time) {
+      data.startTime = data.time[0] || '';
+      data.endTime = data.time[1] || '';
+    }
+    Question.listAsk(data).then(result => {
       this.setTableData(result.list, result.total);
     });
   }

+ 15 - 12
front/project/admin/routes/student/askQuestionDetail/page.js

@@ -8,7 +8,7 @@ import DragList from '@src/components/DragList';
 // import FileUpload from '@src/components/FileUpload';
 import { formatFormError, formatDate, getMap } from '@src/services/Tools';
 import { asyncSMessage } from '@src/services/AsyncTools';
-import { UserUrl, AskTarget, QuestionType, AskModule } from '../../../../Constant';
+import { PcUrl, AskTarget, QuestionType, AskModule } from '../../../../Constant';
 // import { User } from '../../../stores/user';
 import { Question } from '../../../stores/question';
 
@@ -72,7 +72,6 @@ export default class extends Page {
       if (!err) {
         const data = form.getFieldsValue();
         data.showStatus = data.showStatus ? 1 : 0;
-        data.ignoreStatus = data.ignoreStatus ? 1 : 0;
         data.other = this.state.data.others.map(row => row.id);
         Question.editAsk(data).then(() => {
           asyncSMessage('保存成功');
@@ -83,6 +82,14 @@ export default class extends Page {
     });
   }
 
+  ignore() {
+    const { data } = this.state;
+    Question.editAsk({ id: data.id, ignoreStatus: 1 }).then(() => {
+      asyncSMessage('操作成功');
+      goBack();
+    });
+  }
+
   renderBase() {
     const { data } = this.state;
     const { question = {}, questionNo = {} } = data;
@@ -147,7 +154,7 @@ export default class extends Page {
           this.orderQuestion(oldIndex, newIndex);
         }}
         renderItem={(item) => (
-          <List.Item actions={[<Icon type='bars' className='icon' />, <Typography.Text copyable={{ text: `${UserUrl}/paper/question/${this.state.data.userQuestionId}?askId=${item.id}` }} />]}>
+          <List.Item actions={[<Icon type='bars' className='icon' />, <Typography.Text copyable={{ text: `${PcUrl}/paper/question/${this.state.data.userQuestionId}?askId=${item.id}` }} />]}>
             <Row style={{ width: '100%' }}>
               <Col span={11}>问题:<span dangerouslySetInnerHTML={{ __html: item.content }} /></Col>
               <Col span={11} offset={1}>答复:<span dangerouslySetInnerHTML={{ __html: item.answer }} /></Col>
@@ -184,15 +191,6 @@ export default class extends Page {
               )}
             </Form.Item>
           </Col>
-          <Col span={12}>
-            <Form.Item labelCol={{ span: 12 }} wrapperCol={{ span: 10 }} label='是否忽略'>
-              {getFieldDecorator('ignoreStatus', {
-                valuePropName: 'checked',
-              })(
-                <Switch checkedChildren='on' unCheckedChildren='off' />,
-              )}
-            </Form.Item>
-          </Col>
         </Row>
       </Form>
     </Block>;
@@ -207,6 +205,11 @@ export default class extends Page {
 
       <Row type="flex" justify="center">
         <Col>
+          <Button type="drange" onClick={() => {
+            this.ignore();
+          }}>忽略问题</Button>
+        </Col>
+        <Col>
           <Button type="primary" onClick={() => {
             this.submit();
           }}>保存</Button>

+ 3 - 3
front/project/admin/routes/student/studyDetail/page.js

@@ -9,7 +9,7 @@ import ActionLayout from '@src/layouts/ActionLayout';
 import TableLayout from '@src/layouts/TableLayout';
 import { formatDate, formatSecond, formatPercent } from '@src/services/Tools';
 import { asyncSMessage, asyncForm } from '@src/services/AsyncTools';
-import { UserUrl } from '../../../../Constant';
+import { PcUrl } from '../../../../Constant';
 import { Course } from '../../../stores/course';
 import { User } from '../../../stores/user';
 import { System } from '../../../stores/system';
@@ -43,7 +43,7 @@ export default class extends Page {
       render: (text, record) => {
         return <div className="table-button">
           {<a onClick={() => {
-            User.locationUser(record.userId, `${UserUrl}/my/report`);
+            User.locationUser(record.userId, `${PcUrl}/my/report`);
           }}>查看</a>}
         </div>;
       },
@@ -104,7 +104,7 @@ export default class extends Page {
       dataIndex: 'userPaper',
       render: (text, record) => {
         return text ? <a onClick={() => {
-          User.locationUser(record.userId, `${UserUrl}/paper/report/${record.reportId}`);
+          User.locationUser(record.userId, `${PcUrl}/paper/report/${record.reportId}`);
         }}>查看{text.times > 0 ? '(已完成)' : ''}</a> : '';
       },
     }, {

+ 1 - 3
front/project/admin/routes/subject/examination/page.js

@@ -117,6 +117,7 @@ export default class extends Page {
       },
     }, {
       title: '修改时间',
+      sorter: true,
       dataIndex: 'updateTime',
       render: (text, record) => {
         return formatDate(record.question.updateTime);
@@ -185,9 +186,6 @@ export default class extends Page {
         itemList={filterForm}
         data={this.state.search}
         onChange={data => {
-          // if (data.time.length > 0) {
-          //   data.time = [data.time[0].format('YYYY-MM-DD HH:mm:ss'), data.time[1].format('YYYY-MM-DD HH:mm:ss')];
-          // }
           this.search(data);
         }} />}
       <ActionLayout

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

@@ -141,16 +141,18 @@ export default class extends Page {
       },
     }, {
       title: '序号',
+      sorter: this.state.search.paperId,
       dataIndex: 'no',
       render: (text, record) => {
         const { search } = this.state;
-        if (search.paper_id) {
-          return record.paper.no;
+        if (search.paperId) {
+          return record.no;
         }
         return '--';
       },
     }, {
       title: '修改时间',
+      sorter: true,
       dataIndex: 'updateTime',
       render: (text, record) => {
         return formatDate(record.question.updateTime);

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

@@ -340,7 +340,7 @@ export default class extends Page {
 
   searchStem() {
     const { form } = this.props;
-    const content = form.getFieldValue('stem').replace(/<[^>]+>/g, '');
+    const content = (form.getFieldValue('stem') || '').replace(/<[^>]+>/g, '');
     Question.searchStem({ content })
       .then(result => {
         if (result.list.length > 0) {
@@ -352,7 +352,7 @@ export default class extends Page {
               return Promise.resolve();
             });
         } else {
-          asyncSMessage('无可匹配题目');
+          asyncSMessage('无可匹配题目', 'warn');
         }
       });
   }

+ 4 - 8
front/project/admin/routes/subject/textbook/page.js

@@ -18,7 +18,7 @@ const TextbookTypeMap = getMap(TextbookType, 'value', 'label');
 
 const filterForm = [
   {
-    key: 'type',
+    key: 'questionType',
     type: 'select',
     allowClear: true,
     name: '题型',
@@ -60,16 +60,13 @@ export default class extends Page {
     this.categoryMap = {};
     this.columns = [{
       title: '题型',
-      dataIndex: 'type',
+      dataIndex: 'questionType',
       render: (text, record) => {
-        return TextbookTypeMap[record.question.type] || text;
+        return TextbookTypeMap[record.question.questionType] || text;
       },
     }, {
       title: '练习册',
-      dataIndex: 'paper',
-      render: (text) => {
-        return (text || {}).text.title;
-      },
+      dataIndex: 'paper.title',
     }, {
       title: '题目ID',
       dataIndex: 'title',
@@ -134,7 +131,6 @@ export default class extends Page {
         onAction={key => this.onAction(key)}
       />
       <TableLayout
-        select
         columns={this.tableSort(this.columns)}
         list={this.state.list}
         pagination={this.state.page}

+ 8 - 2
front/project/admin/routes/user/abnormal/page.js

@@ -24,7 +24,7 @@ export default class extends Page {
       key: 'totalAlert',
       type: 'number',
       allowClear: true,
-      name: '实名认证',
+      name: '警告次数',
       number: true,
     }, {
       key: 'time',
@@ -108,7 +108,13 @@ export default class extends Page {
   }
 
   initData() {
-    User.listAbnormal(this.state.search).then(result => {
+    const { search } = this.state;
+    const data = Object.assign({}, search);
+    if (data.time) {
+      data.startTime = data.time[0] || '';
+      data.endTime = data.time[1] || '';
+    }
+    User.listAbnormal(data).then(result => {
       this.setTableData(result.list, result.total);
     });
   }

+ 5 - 5
front/project/admin/routes/user/detail/page.js

@@ -6,7 +6,7 @@ import Block from '@src/components/Block';
 import TableLayout from '@src/layouts/TableLayout';
 import { formatDate, getMap, formatMoney, formatSeconds } from '@src/services/Tools';
 import { asyncSMessage, asyncForm, asyncDelConfirm } from '@src/services/AsyncTools';
-import { UserUrl, PrepareStatus, PrepareExaminationTime, ServiceKey } from '../../../../Constant';
+import { PcUrl, PrepareStatus, PrepareExaminationTime, ServiceKey } from '../../../../Constant';
 import { User } from '../../../stores/user';
 import { System } from '../../../stores/system';
 import { Exercise } from '../../../stores/exercise';
@@ -97,7 +97,7 @@ export default class extends Page {
 
   noFrozenAction() {
     asyncDelConfirm('操作确认', '是否要取消封禁账户?取消后账户可以使用网站', () => {
-      return User.frozen({ id: this.state.data.id })
+      return User.noFrozen({ id: this.state.data.id })
         .then(() => {
           asyncSMessage('操作成功!');
           this.refresh();
@@ -158,7 +158,7 @@ export default class extends Page {
             </Col>
             <Col span={12}>
               <Form.Item labelCol={{ span: 5 }} wrapperCol={{ span: 16 }} label='注册时间'>
-                {formatDate(data.createTime)}
+                {data.createTime && formatDate(data.createTime)}
               </Form.Item>
             </Col>
             <Col span={12}>
@@ -233,7 +233,7 @@ export default class extends Page {
       <h1>服务开通</h1>
       <div className="group">
         <h2>累计消费金额</h2>
-        <span>{data.totalMoney}</span>
+        <p>{data.totalMoney}</p>
         <Button onClick={() => {
           this.addMoneyAction();
         }}>增加线下金额</Button>
@@ -268,7 +268,7 @@ export default class extends Page {
       <div className="group">
         <h2>学习数据</h2>
         <Button onClick={() => {
-          User.locationUser(this.params.id, `${UserUrl}/my/data`);
+          User.locationUser(this.params.id, `${PcUrl}/my/data`);
         }}>查看</Button>
       </div>
     </Block>;

+ 2 - 0
front/project/admin/routes/user/list/page.js

@@ -43,6 +43,7 @@ export default class extends Page {
       required: true,
       option: {
         normalize: (value) => {
+          if (!value) return value;
           if (this.mobile === value) return value;
           if (this.timeout) {
             clearTimeout(this.timeout);
@@ -112,6 +113,7 @@ export default class extends Page {
       dataIndex: 'nickname',
     }, {
       title: '注册时间',
+      sorter: true,
       dataIndex: 'createTime',
       render: (text) => {
         return formatDate(text, 'YYYY-MM-DD');

+ 3 - 2
front/project/admin/routes/user/order/page.js

@@ -21,7 +21,8 @@ export default class extends Page {
     }, {
       key: 'transactionNo',
       type: 'input',
-      name: '请输入支付流水号',
+      required: true,
+      name: '支付流水号',
     }];
     this.filterF = null;
     this.filterForm = [{
@@ -94,7 +95,7 @@ export default class extends Page {
           <Link to={`/user/order/detail/${record.id}`}>查看</Link>
           {record.payStatus === 0 && (
             <a onClick={() => {
-              this.finishActionn(record);
+              this.finishAction(record);
             }}>确认收款</a>
           )}
         </div>;

+ 9 - 1
front/project/admin/routes/user/recordAll/page.js

@@ -43,13 +43,16 @@ export default class extends Page {
       type: 'select',
       name: '国际码',
       select: MobileArea,
+      required: true,
     }, {
       key: 'mobile',
       type: 'input',
       name: '手机号',
       placeholder: '请输入',
+      required: true,
       option: {
         normalize: (value) => {
+          if (!value) return value;
           if (this.mobile === value) return value;
           if (this.timeout) {
             clearTimeout(this.timeout);
@@ -71,6 +74,7 @@ export default class extends Page {
       name: '开通服务',
       select: ServiceKey,
       placeholder: '请选择',
+      required: true,
       onChange: (value) => {
         this.serviceList[4].select = ServiceParamList[value] || [];
         this.serviceList[4].disabled = !this.serviceList[4].select.length;
@@ -90,13 +94,16 @@ export default class extends Page {
       type: 'select',
       name: '国际码',
       select: MobileArea,
+      required: true,
     }, {
       key: 'mobile',
       type: 'input',
       name: '手机号',
       placeholder: '请输入',
+      required: true,
       option: {
         normalize: (value) => {
+          if (!value) return value;
           if (this.mobile === value) return value;
           if (this.timeout) {
             clearTimeout(this.timeout);
@@ -116,6 +123,7 @@ export default class extends Page {
       key: 'dataId',
       type: 'select',
       name: '开通资料',
+      required: true,
       select: [],
       placeholder: '请选择',
     }];
@@ -212,7 +220,7 @@ export default class extends Page {
       dataIndex: 'handler',
       render: (text, record) => {
         return <div className="table-button">
-          {record.isUsed > 0 && !record.isStop && (
+          {!record.isStop && (
             <a onClick={() => {
               this.stopAction(record.id);
             }}>停用</a>

+ 2 - 2
front/project/h5/routes/page/home/page.js

@@ -2,7 +2,7 @@ import React from 'react';
 import './index.less';
 import Page from '@src/containers/Page';
 import Assets from '@src/components/Assets';
-import { UserUrl } from '../../../../Constant';
+import { PcUrl } from '../../../../Constant';
 import { Main } from '../../../stores/main';
 
 export default class extends Page {
@@ -24,7 +24,7 @@ export default class extends Page {
           <div className="copy-title">复制下方地址至浏览器打开</div>
           <div className="input">
             <div className="prefix">http://</div>
-            <div className="value">{UserUrl.replace('http://', '')}/id/{info.inviteCode}</div>
+            <div className="value">{PcUrl.replace('http://', '')}/id/{info.inviteCode}</div>
             <Assets name="copy" />
           </div>
         </div>

+ 2 - 2
front/project/h5/routes/product/courseDetail/page.js

@@ -6,7 +6,7 @@ import Money from '../../../components/Money';
 import Button from '../../../components/Button';
 import { Course } from '../../../stores/course';
 import { Order } from '../../../stores/order';
-import { UserUrl } from '../../../../Constant';
+import { PcUrl } from '../../../../Constant';
 
 export default class extends Page {
   initState() {
@@ -31,7 +31,7 @@ export default class extends Page {
         <div className="b-g" style={{ backgroundImage: `url(${data.cover})` }}>
           <div className="title">{data.title}</div>
         </div>
-        <div className="tip">访问{UserUrl}/course/detail/{data.id},试听该课程</div>
+        <div className="tip">访问{PcUrl}/course/detail/{data.id},试听该课程</div>
         <div className="detail">
           <Tabs
             page={tab}

+ 1 - 1
front/project/h5/routes/product/courseVs/page.js

@@ -30,7 +30,7 @@ export default class extends Page {
         <div className="b-g" style={{ backgroundImage: `url(${data.cover})` }}>
           <div className="title">{data.title}</div>
         </div>
-        {/* <div className="tip">访问{UserUrl}/course/detail/{data.id},试听该课程</div> */}
+        {/* <div className="tip">访问{PcUrl}/course/detail/{data.id},试听该课程</div> */}
         <div className="detail">
           <Tabs
             page={tab}

+ 3 - 3
front/project/www/components/Login/index.js

@@ -7,7 +7,7 @@ import { Icon as GIcon } from '../Icon';
 import { Button as GButton } from '../Button';
 import { User } from '../../stores/user';
 import { Common } from '../../stores/common';
-import { MobileArea, WechatUserAppId } from '../../../Constant';
+import { MobileArea, WechatPcAppId } from '../../../Constant';
 
 const LOGIN_PHONE = 'LOGIN_PHONE';
 const LOGIN_WX = 'LOGIN_WX';
@@ -256,7 +256,7 @@ export default class Login extends Component {
       <div className="body">
         <div className="title">微信扫码登录</div>
         <div className="qr-code">
-          <iframe frameBorder="0" src={`/login.html?appid=${WechatUserAppId}&redirectUri=${encodeURIComponent('http://www.duoshaojiaoyu.com')}`} width="300" height="300" />
+          <iframe frameBorder="0" src={`/login.html?appid=${WechatPcAppId}&redirectUri=${encodeURIComponent('http://www.duoshaojiaoyu.com')}`} width="300" height="300" />
           <div className="text">请使用微信扫描二维码登录</div>
         </div>
         <Tooltip overlayClassName="gray" placement="left" title="手机号登录">
@@ -340,7 +340,7 @@ export default class Login extends Component {
           手机号注册成功!为更好的使用服务,建议您绑定微信号。
         </div>
         <div className="qr-code">
-          <iframe frameBorder="0" src={`/login.html?appid=${WechatUserAppId}&redirectUri=${encodeURIComponent('http://www.duoshaojiaoyu.com')}`} width="300" height="300" />
+          <iframe frameBorder="0" src={`/login.html?appid=${WechatPcAppId}&redirectUri=${encodeURIComponent('http://www.duoshaojiaoyu.com')}`} width="300" height="300" />
           <div className="text">请使用微信扫描二维码登录</div>
           <div
             className="jump"

+ 2 - 2
front/src/containers/Async.js

@@ -1,5 +1,5 @@
 import React, { Component } from 'react';
-import { createForm } from 'rc-form';
+import { Form } from 'antd';
 
 export default class extends Component {
   constructor(props) {
@@ -12,7 +12,7 @@ export default class extends Component {
       this.props
         .component()
         .then(({ default: component }) => {
-          this.setState({ C: this.props.isForm ? createForm()(component) : component });
+          this.setState({ C: this.props.isForm ? Form.create()(component) : component });
         })
         .catch(err => {
           console.log('async error: ', err);

+ 24 - 19
front/src/services/AsyncTools.js

@@ -37,10 +37,33 @@ function getAsyncAntd() {
   return import('../components/AsyncAntd');
 }
 
+export function asyncSMessage(title, type = 'success') {
+  return getAsyncAntd().then(({ Message }) => {
+    switch (type) {
+      case 'warn':
+      case 'warning':
+        Message.warning(title);
+        break;
+      case 'error':
+        Message.error(title);
+        break;
+      case 'success':
+      default:
+        Message.success(title);
+        break;
+    }
+  });
+}
+
 export function asyncModalConfirm(props, cb) {
   const params = {
     onOk: () => {
-      cb();
+      const result = cb();
+      if (result) {
+        result.catch((err) => {
+          asyncSMessage(err.message, 'error');
+        });
+      }
     },
     destroyOnClose: true,
   };
@@ -56,21 +79,3 @@ export function asyncConfirm(title, content, cb) {
 export function asyncDelConfirm(title, content, cb) {
   return asyncModalConfirm({ title, content, okType: 'danger', maskClosable: true }, cb);
 }
-
-export function asyncSMessage(title, type = 'success') {
-  return getAsyncAntd().then(({ Message }) => {
-    switch (type) {
-      case 'warn':
-      case 'warning':
-        Message.warning(title);
-        break;
-      case 'error':
-        Message.error(title);
-        break;
-      case 'success':
-      default:
-        Message.success(title);
-        break;
-    }
-  });
-}

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

@@ -48,6 +48,12 @@ public class UserAskCourse implements Serializable {
     private Integer askTime;
 
     /**
+     * 过期时间
+     */
+    @Column(name = "`expire_time`")
+    private Date expireTime;
+
+    /**
      * 回答状态: 0未回答,1回答,2忽略
      */
     @Column(name = "`answer_status`")
@@ -220,6 +226,24 @@ public class UserAskCourse implements Serializable {
     }
 
     /**
+     * 获取过期时间
+     *
+     * @return expire_time - 过期时间
+     */
+    public Date getExpireTime() {
+        return expireTime;
+    }
+
+    /**
+     * 设置过期时间
+     *
+     * @param expireTime 过期时间
+     */
+    public void setExpireTime(Date expireTime) {
+        this.expireTime = expireTime;
+    }
+
+    /**
      * 获取回答状态: 0未回答,1回答,2忽略
      *
      * @return answer_status - 回答状态: 0未回答,1回答,2忽略
@@ -386,6 +410,7 @@ public class UserAskCourse implements Serializable {
         sb.append(", recordId=").append(recordId);
         sb.append(", position=").append(position);
         sb.append(", askTime=").append(askTime);
+        sb.append(", expireTime=").append(expireTime);
         sb.append(", answerStatus=").append(answerStatus);
         sb.append(", managerId=").append(managerId);
         sb.append(", showStatus=").append(showStatus);
@@ -479,6 +504,16 @@ public class UserAskCourse implements Serializable {
         }
 
         /**
+         * 设置过期时间
+         *
+         * @param expireTime 过期时间
+         */
+        public Builder expireTime(Date expireTime) {
+            obj.setExpireTime(expireTime);
+            return this;
+        }
+
+        /**
          * 设置回答
          *
          * @param answer 回答

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

@@ -66,6 +66,12 @@ public class UserAskQuestion implements Serializable {
     private Integer askTime;
 
     /**
+     * 过期时间
+     */
+    @Column(name = "`expire_time`")
+    private Date expireTime;
+
+    /**
      * 回答状态: 0未回答,1回答,2忽略
      */
     @Column(name = "`answer_status`")
@@ -298,6 +304,24 @@ public class UserAskQuestion implements Serializable {
     }
 
     /**
+     * 获取过期时间
+     *
+     * @return expire_time - 过期时间
+     */
+    public Date getExpireTime() {
+        return expireTime;
+    }
+
+    /**
+     * 设置过期时间
+     *
+     * @param expireTime 过期时间
+     */
+    public void setExpireTime(Date expireTime) {
+        this.expireTime = expireTime;
+    }
+
+    /**
      * 获取回答状态: 0未回答,1回答,2忽略
      *
      * @return answer_status - 回答状态: 0未回答,1回答,2忽略
@@ -485,6 +509,7 @@ public class UserAskQuestion implements Serializable {
         sb.append(", recordId=").append(recordId);
         sb.append(", target=").append(target);
         sb.append(", askTime=").append(askTime);
+        sb.append(", expireTime=").append(expireTime);
         sb.append(", answerStatus=").append(answerStatus);
         sb.append(", managerId=").append(managerId);
         sb.append(", showStatus=").append(showStatus);
@@ -609,6 +634,16 @@ public class UserAskQuestion implements Serializable {
         }
 
         /**
+         * 设置过期时间
+         *
+         * @param expireTime 过期时间
+         */
+        public Builder expireTime(Date expireTime) {
+            obj.setExpireTime(expireTime);
+            return this;
+        }
+
+        /**
          * 设置回答
          *
          * @param answer 回答

+ 3 - 2
server/data/src/main/java/com/qxgmat/data/dao/mapping/UserAskCourseMapper.xml

@@ -12,6 +12,7 @@
     <result column="record_id" jdbcType="INTEGER" property="recordId" />
     <result column="position" jdbcType="VARCHAR" property="position" />
     <result column="ask_time" jdbcType="INTEGER" property="askTime" />
+    <result column="expire_time" jdbcType="TIMESTAMP" property="expireTime" />
     <result column="answer_status" jdbcType="INTEGER" property="answerStatus" />
     <result column="manager_id" jdbcType="INTEGER" property="managerId" />
     <result column="show_status" jdbcType="INTEGER" property="showStatus" />
@@ -32,8 +33,8 @@
       WARNING - @mbg.generated
     -->
     `id`, `user_id`, `course_id`, `course_no_id`, `record_id`, `position`, `ask_time`, 
-    `answer_status`, `manager_id`, `show_status`, `answer_time`, `order`, `create_time`, 
-    `update_time`
+    `expire_time`, `answer_status`, `manager_id`, `show_status`, `answer_time`, `order`, 
+    `create_time`, `update_time`
   </sql>
   <sql id="Blob_Column_List">
     <!--

+ 3 - 2
server/data/src/main/java/com/qxgmat/data/dao/mapping/UserAskQuestionMapper.xml

@@ -15,6 +15,7 @@
     <result column="record_id" jdbcType="INTEGER" property="recordId" />
     <result column="target" jdbcType="VARCHAR" property="target" />
     <result column="ask_time" jdbcType="INTEGER" property="askTime" />
+    <result column="expire_time" jdbcType="TIMESTAMP" property="expireTime" />
     <result column="answer_status" jdbcType="INTEGER" property="answerStatus" />
     <result column="manager_id" jdbcType="INTEGER" property="managerId" />
     <result column="show_status" jdbcType="INTEGER" property="showStatus" />
@@ -36,8 +37,8 @@
       WARNING - @mbg.generated
     -->
     `id`, `user_id`, `user_question_id`, `ask_module`, `question_module`, `question_id`, 
-    `question_no_id`, `record_id`, `target`, `ask_time`, `answer_status`, `manager_id`, 
-    `show_status`, `answer_time`, `order`, `create_time`, `update_time`
+    `question_no_id`, `record_id`, `target`, `ask_time`, `expire_time`, `answer_status`, 
+    `manager_id`, `show_status`, `answer_time`, `order`, `create_time`, `update_time`
   </sql>
   <sql id="Blob_Column_List">
     <!--

+ 14 - 0
server/data/src/main/java/com/qxgmat/data/relation/MessageTemplateRelationMapper.java

@@ -0,0 +1,14 @@
+package com.qxgmat.data.relation;
+
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * Created by gaojie on 2017/11/9.
+ */
+public interface MessageTemplateRelationMapper {
+
+    void accumulation(
+            @Param("id") Number templateId,
+            @Param("number") Integer number
+    );
+}

+ 2 - 1
server/data/src/main/java/com/qxgmat/data/relation/TextbookQuestionRelationMapper.java

@@ -1,6 +1,7 @@
 package com.qxgmat.data.relation;
 
 import com.qxgmat.data.dao.entity.TextbookQuestion;
+import com.qxgmat.data.relation.entity.TextbookQuestionRelation;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
@@ -17,7 +18,7 @@ public interface TextbookQuestionRelationMapper {
             @Param("correct") Integer correct
     );
 
-    List<TextbookQuestion> listAdmin(
+    List<TextbookQuestionRelation> listAdmin(
             @Param("questionType") String questionType,
             @Param("paperId") Number paperId,
             @Param("questionNoId") Number questionNoId,

+ 2 - 0
server/data/src/main/java/com/qxgmat/data/relation/UserAbnormalRelationMapper.java

@@ -15,6 +15,8 @@ public interface UserAbnormalRelationMapper {
     List<UserAbnormal> listAdmin(
             @Param("userId") Integer userId,
             @Param("totalAlert") Integer totalAlert,
+            @Param("startTime") String startTime,
+            @Param("endTime") String endTime,
             String order,
             String direction
     );

+ 3 - 1
server/data/src/main/java/com/qxgmat/data/relation/UserAskCourseRelationMapper.java

@@ -10,7 +10,7 @@ import java.util.List;
  * Created by gaojie on 2017/11/9.
  */
 public interface UserAskCourseRelationMapper {
-    List<UserAskCourse> listWithCourse(
+    List<UserAskCourse> listAdmin(
             @Param("structId") Integer structId,
             @Param("courseId") Number courseId,
             @Param("answerStatus") Integer answerStatus,
@@ -18,6 +18,8 @@ public interface UserAskCourseRelationMapper {
             @Param("userId") Integer userId,
             @Param("min") Integer min,
             @Param("max") Integer max,
+            @Param("startTime") String startTime,
+            @Param("endTime") String endTime,
             String order,
             String direction
     );

+ 3 - 1
server/data/src/main/java/com/qxgmat/data/relation/UserAskQuestionRelationMapper.java

@@ -32,7 +32,7 @@ public interface UserAskQuestionRelationMapper {
             String order
     );
 
-    List<UserAskQuestion> listWithUser(
+    List<UserAskQuestion> listAdmin(
             @Param("askModule") String askModule,
             @Param("questionType") String questionType,
             @Param("questionModule") String questionModule,
@@ -44,6 +44,8 @@ public interface UserAskQuestionRelationMapper {
             @Param("min") Integer min,
             @Param("max") Integer max,
             @Param("hasRecord") Boolean hasRecord,
+            @Param("startTime") String startTime,
+            @Param("endTime") String endTime,
             String order,
             String direction
     );

+ 26 - 0
server/data/src/main/java/com/qxgmat/data/relation/mapping/MessageTemplateRelationMapper.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qxgmat.data.relation.MessageTemplateRelationMapper">
+  <resultMap id="IdMap" type="com.qxgmat.data.dao.entity.MessageTemplate">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="id" jdbcType="INTEGER" property="id" />
+  </resultMap>
+  <sql id="Id_Column_List">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    mt.`id`
+  </sql>
+
+  <!--累加做题记录-->
+  <update id="accumulation">
+    UPDATE `message_template`
+    <trim prefix="set" suffixOverrides=",">
+      `send_number`=`send_number`+#{number, jdbcType=INTEGER},
+    </trim>
+    WHERE `id` = #{id, jdbcType=VARCHAR}
+  </update>
+
+</mapper>

+ 3 - 0
server/data/src/main/java/com/qxgmat/data/relation/mapping/QuestionNoRelationMapper.xml

@@ -102,6 +102,9 @@
   <select id="listExerciseAdmin" resultMap="IdMap">
     select
     <include refid="Id_Column_List" />
+    <if test="paperId != null">
+      , find_in_set(qn.`id`, trim(TRAILING ']' from trim(LEADING '[' from eq.`question_no_ids`))) as ep.`no`
+    </if>
     from `question_no` qn
     left join `question` q on q.`id` = qn.`question_id`
     <if test="paperId != null">

+ 6 - 0
server/data/src/main/java/com/qxgmat/data/relation/mapping/UserAbnormalRelationMapper.xml

@@ -28,6 +28,12 @@
     <if test="totalAlert != null">
       and u.`total_alert` = #{totalAlert,jdbcType=VARCHAR}
     </if>
+    <if test="startTime != null">
+      and u.`create_time` &gt; #{startTime,jdbcType=VARCHAR}
+    </if>
+    <if test="endTime != null">
+      and u.`create_time` &lt; #{endTime,jdbcType=VARCHAR}
+    </if>
     where
     u.`id` &gt; 0
     order by ${order} ${direction}

+ 11 - 5
server/data/src/main/java/com/qxgmat/data/relation/mapping/UserAskCourseRelationMapper.xml

@@ -28,9 +28,9 @@
     select
     <include refid="Id_Column_List" />
     from `user_ask_course` uac
-    left join `user` u on u.`id` = ua.`user_id`
+    left join `user` u on u.`id` = uac.`user_id`
       <if test="userId != null">
-        and ua.`user_id` = #{userId,jdbcType=VARCHAR}
+        and uac.`user_id` = #{userId,jdbcType=VARCHAR}
       </if>
       <if test="max != null">
         and u.`total_money` &lt; ${max}
@@ -38,7 +38,7 @@
       <if test="min != null">
         and u.`total_money` &gt; ${min}
       </if>
-    left join `course` c on c.`id` = ua.`course_id`
+    left join `course` c on c.`id` = uac.`course_id`
       <if test="courseId != null">
         and c.`id` = #{courseId,jdbcType=VARCHAR}
       </if>
@@ -49,10 +49,16 @@
     c.`id` &gt; 0
     and u.`id` &gt; 0
     <if test="answerStatus != null">
-      and ua.`answer_status` = #{answerStatus,jdbcType=INTEGER}
+      and uac.`answer_status` = #{answerStatus,jdbcType=INTEGER}
     </if>
     <if test="showStatus != null">
-      and ua.`show_status` = #{showStatus,jdbcType=INTEGER}
+      and uac.`show_status` = #{showStatus,jdbcType=INTEGER}
+    </if>
+    <if test="startTime != null">
+      and uac.`create_time` &gt; #{startTime,jdbcType=VARCHAR}
+    </if>
+    <if test="endTime != null">
+      and uac.`create_time` &lt; #{endTime,jdbcType=VARCHAR}
     </if>
     order by ${order} ${direction}
   </select>

+ 10 - 4
server/data/src/main/java/com/qxgmat/data/relation/mapping/UserAskQuestionRelationMapper.xml

@@ -139,12 +139,12 @@
     </if>
   </select>
 
-  <!--用户提问列表-->
-  <select id="listWithUser" resultMap="IdMap">
+  <!--后台提问列表-->
+  <select id="listAdmin" resultMap="IdMap">
     select
     <include refid="Id_Column_List" />
     from `user_ask_question` uaq
-    left join `user` u on u.`id` = ua.`user_id`
+    left join `user` u on u.`id` = uaq.`user_id`
       <if test="userId != null">
         and uaq.`user_id` = #{userId,jdbcType=VARCHAR}
       </if>
@@ -154,7 +154,7 @@
       <if test="min != null">
         and u.`total_money` &gt; ${min}
       </if>
-    left join `question` q on q.`id` = ua.`question_id`
+    left join `question` q on q.`id` = uaq.`question_id`
     where
     u.`id` &gt; 0
     <if test="questionNoId != null">
@@ -178,6 +178,12 @@
     <if test="questionType != null">
       and q.`question_type` =#{questionType,jdbcType=VARCHAR}
     </if>
+    <if test="startTime != null">
+      and uaq.`create_time` &gt; #{startTime,jdbcType=VARCHAR}
+    </if>
+    <if test="endTime != null">
+      and uaq.`create_time` &lt; #{endTime,jdbcType=VARCHAR}
+    </if>
     <if test="hasRecord != null">
       <if test="hasRecord">
         and uaq.`record_id` &gt; 0

+ 3 - 1
server/gateway-api/src/main/java/com/qxgmat/controller/admin/CourseController.java

@@ -799,10 +799,12 @@ public class CourseController {
             @RequestParam(required = false) Integer showStatus,
             @RequestParam(required = false) Integer userId,
             @RequestParam(required = false) Integer moneyRang,
+            @RequestParam(required = false) String startTime,
+            @RequestParam(required = false) String endTime,
             @RequestParam(required = false, defaultValue = "id") String order,
             @RequestParam(required = false, defaultValue = "desc") String direction,
             HttpSession session) {
-        Page<UserAskCourse> p = userAskCourseService.listAdmin(page, size, structId, courseId, AskStatus.ValueOf(answerStatus), showStatus, userId, MoneyRange.ValueOf(moneyRang), order, DirectionStatus.ValueOf(direction));
+        Page<UserAskCourse> p = userAskCourseService.listAdmin(page, size, structId, courseId, AskStatus.ValueOf(answerStatus), showStatus, userId, MoneyRange.ValueOf(moneyRang), startTime, endTime, order, DirectionStatus.ValueOf(direction));
         List<UserAskCourseListDto> pr = Transform.convert(p, UserAskCourseListDto.class);
 
         // 绑定用户

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

@@ -242,10 +242,12 @@ public class QuestionController {
             @RequestParam(required = false) Integer showStatus,
             @RequestParam(required = false) Integer moneyRang,
             @RequestParam(required = false) Boolean hasRecord,
+            @RequestParam(required = false) String startTime,
+            @RequestParam(required = false) String endTime,
             @RequestParam(required = false, defaultValue = "id") String order,
             @RequestParam(required = false, defaultValue = "desc") String direction,
             HttpSession session) {
-        Page<UserAskQuestion> p = userAskQuestionService.listAdmin(page, size, askModule, questionType, questionModule, userId, questionNoId, AskTarget.ValueOf(target), AskStatus.ValueOf(answerStatus), showStatus, MoneyRange.ValueOf(moneyRang), hasRecord, order, DirectionStatus.ValueOf(direction));
+        Page<UserAskQuestion> p = userAskQuestionService.listAdmin(page, size, askModule, questionType, questionModule, userId, questionNoId, AskTarget.ValueOf(target), AskStatus.ValueOf(answerStatus), showStatus, MoneyRange.ValueOf(moneyRang), hasRecord, startTime, endTime, order, DirectionStatus.ValueOf(direction));
         List<UserAskQuestionListDto> pr = Transform.convert(p, UserAskQuestionListDto.class);
 
         // 绑定题目

+ 0 - 1
server/gateway-api/src/main/java/com/qxgmat/controller/admin/SettingController.java

@@ -21,7 +21,6 @@ import com.qxgmat.help.ShiroHelp;
 import com.qxgmat.service.UsersService;
 import com.qxgmat.service.extend.MessageExtendService;
 import com.qxgmat.service.inline.*;
-import com.sun.org.apache.xpath.internal.operations.Bool;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.apache.poi.hssf.usermodel.HSSFCell;

+ 2 - 2
server/gateway-api/src/main/java/com/qxgmat/controller/admin/TextbookController.java

@@ -140,13 +140,13 @@ public class TextbookController {
     public Response<PageMessage<TextbookQuestionListDto>> listQuestion(
             @RequestParam(required = false, defaultValue = "1") int page,
             @RequestParam(required = false, defaultValue = "100") int size,
-            @RequestParam(required = false) String type,
+            @RequestParam(required = false) String questionType,
             @RequestParam(required = false) Integer paperId,
             @RequestParam(required = false) Integer questionNoId,
             @RequestParam(required = false, defaultValue = "id") String order,
             @RequestParam(required = false, defaultValue = "desc") String direction,
             HttpSession session) {
-        Page<TextbookQuestion> p = textbookQuestionService.listAdmin(page, size, type, paperId, questionNoId, order, DirectionStatus.ValueOf(direction));
+        Page<TextbookQuestionRelation> p = textbookQuestionService.listAdmin(page, size, questionType, paperId, questionNoId, order, DirectionStatus.ValueOf(direction));
         List<TextbookQuestionListDto> pr = Transform.convert(p, TextbookQuestionListDto.class);
 
         return ResponseHelp.success(pr, page, size, p.getTotal());

+ 9 - 7
server/gateway-api/src/main/java/com/qxgmat/controller/admin/UserController.java

@@ -220,13 +220,13 @@ public class UserController {
 
     @RequestMapping(value = "/frozen", method = RequestMethod.POST)
     @ApiOperation(value = "冻结用户", httpMethod = "POST")
-    public Response<Boolean> frozen(@RequestParam int id, HttpSession session) {
-        User entity = usersService.get(id);
+    public Response<Boolean> frozen(@RequestBody @Validated UserFrozenDto dto, HttpSession session) {
+        User entity = usersService.get(dto.getId());
         if (entity.getIsFrozen() > 0){
             throw new ParameterException("用户已冻结");
         }
         usersService.edit(User.builder()
-                .id(id)
+                .id(dto.getId())
                 .isFrozen(1)
                 .build());
         return ResponseHelp.success(true);
@@ -234,13 +234,13 @@ public class UserController {
 
     @RequestMapping(value = "/nofrozen", method = RequestMethod.POST)
     @ApiOperation(value = "取消冻结用户", httpMethod = "POST")
-    public Response<Boolean> noFrozen(@RequestParam int id, HttpSession session) {
-        User entity = usersService.get(id);
+    public Response<Boolean> noFrozen(@RequestBody @Validated UserFrozenDto dto, HttpSession session) {
+        User entity = usersService.get(dto.getId());
         if (entity.getIsFrozen() == 0){
             throw new ParameterException("用户未冻结");
         }
         usersService.edit(User.builder()
-                .id(id)
+                .id(dto.getId())
                 .isFrozen(0)
                 .build());
         return ResponseHelp.success(true);
@@ -897,10 +897,12 @@ public class UserController {
             @RequestParam(required = false, defaultValue = "100") int size,
             @RequestParam(required = false) Integer userId,
             @RequestParam(required = false) Integer totalAlert,
+            @RequestParam(required = false) String startTime,
+            @RequestParam(required = false) String endTime,
             @RequestParam(required = false, defaultValue = "id") String order,
             @RequestParam(required = false, defaultValue = "desc") String direction,
             HttpSession session) {
-        Page<UserAbnormal> p = userAbnormalService.listAdmin(page, size, userId, totalAlert, order, DirectionStatus.ValueOf(direction));
+        Page<UserAbnormal> p = userAbnormalService.listAdmin(page, size, userId, totalAlert, startTime, endTime, order, DirectionStatus.ValueOf(direction));
         List<UserAbnormalInfoDto> pr = Transform.convert(p, UserAbnormalInfoDto.class);
 
         // 绑定用户

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

@@ -17,7 +17,6 @@ import com.qxgmat.dto.response.CommentDto;
 import com.qxgmat.dto.response.FaqDto;
 import com.qxgmat.service.UsersService;
 import com.qxgmat.service.inline.*;
-import com.sun.org.apache.xpath.internal.operations.Bool;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;

+ 43 - 2
server/gateway-api/src/main/java/com/qxgmat/controller/api/CourseController.java

@@ -13,13 +13,17 @@ import com.qxgmat.data.constants.enums.user.DataType;
 import com.qxgmat.data.dao.entity.*;
 import com.qxgmat.data.relation.entity.UserPreviewPaperRelation;
 import com.qxgmat.dto.extend.*;
+import com.qxgmat.dto.request.CourseTrailViewDto;
+import com.qxgmat.dto.request.ExperienceViewDto;
 import com.qxgmat.dto.response.*;
 import com.qxgmat.help.ShiroHelp;
+import com.qxgmat.service.UsersService;
 import com.qxgmat.service.extend.PreviewService;
 import com.qxgmat.service.inline.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpSession;
@@ -76,6 +80,9 @@ public class CourseController {
     @Autowired
     private UserOrderRecordService userOrderRecordService;
 
+    @Autowired
+    private UsersService usersService;
+
 
     @RequestMapping(value = "/vs", method = RequestMethod.GET)
     @ApiOperation(value = "获取1v1课程信息", notes = "获取1v1课程信息", httpMethod = "GET")
@@ -137,6 +144,13 @@ public class CourseController {
         return ResponseHelp.success(course);
     }
 
+    @RequestMapping(value = "/trail/view", method = RequestMethod.POST)
+    @ApiOperation(value = "课程试用", httpMethod = "POST")
+    public Response<Boolean> viewTrail(@RequestBody @Validated CourseTrailViewDto dto, HttpSession session) {
+        courseService.accumulation(dto.getId(), 1, 0, 0);
+        return ResponseHelp.success(true);
+    }
+
     @RequestMapping(value = "/package/list", method = RequestMethod.GET)
     @ApiOperation(value = "套餐列表", httpMethod = "GET")
     public Response<PageMessage<CoursePackageListDto>> listPackage(
@@ -263,7 +277,7 @@ public class CourseController {
 
     @RequestMapping(value = "/experience/list", method = RequestMethod.GET)
     @ApiOperation(value = "心经列表", httpMethod = "GET")
-    public Response<PageMessage<CourseExperience>> listExperience(
+    public Response<PageMessage<CourseExperienceListDto>> listExperience(
             @RequestParam(required = false, defaultValue = "1") int page,
             @RequestParam(required = false, defaultValue = "100") int size,
             @RequestParam(required = false) String prepareStatus,
@@ -276,7 +290,34 @@ public class CourseController {
 
         Page<CourseExperience> p = courseExperienceService.list(page, size, prepareStatus, ExperienceScoreRange.ValueOf(experienceScore), ExperienceDayRange.ValueOf(experienceDay), experiencePercent, order, DirectionStatus.ValueOf(direction));
 
-        return ResponseHelp.success(p, page, size, p.getTotal());
+        List<CourseExperienceListDto> pr = Transform.convert(p, CourseExperienceListDto.class);
+
+        // 绑定用户
+        Collection userIds = Transform.getIds(pr, CourseExperienceListDto.class, "userId");
+        List<User> userList = usersService.select(userIds);
+        Transform.combine(pr, userList, CourseExperienceListDto.class, "userId", "user", User.class, "id", UserExtendDto.class);
+
+        return ResponseHelp.success(pr, page, size, p.getTotal());
+    }
+
+    @RequestMapping(value = "/experience/detail", method = RequestMethod.GET)
+    @ApiOperation(value = "心经查看", httpMethod = "GET")
+    public Response<CourseExperience> detailExperience(int id, HttpSession session) {
+
+        CourseExperience entity = courseExperienceService.get(id);
+        if(entity.getUserId() > 0){
+            CourseExperienceDetailDto dto = Transform.convert(entity, CourseExperienceDetailDto.class);
+            User user = usersService.get(dto.getUserId());
+            dto.setUser(Transform.convert(user, UserExtendDto.class));
+        }
+        return ResponseHelp.success(entity);
+    }
+
+    @RequestMapping(value = "/experience/view", method = RequestMethod.POST)
+    @ApiOperation(value = "心经阅读", httpMethod = "POST")
+    public Response<Boolean> viewExperience(@RequestBody @Validated ExperienceViewDto dto, HttpSession session) {
+        courseExperienceService.accumulation(dto.getId(), 1, 0);
+        return ResponseHelp.success(true);
     }
 
     @RequestMapping(value = "/record", method = RequestMethod.GET)

+ 5 - 0
server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java

@@ -43,6 +43,7 @@ import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
+import javax.tools.Tool;
 import javax.validation.Validator;
 import java.io.File;
 import java.io.IOException;
@@ -1229,6 +1230,8 @@ public class MyController {
             entity.setRecordId(recordId);
             UserOrderRecord record = userOrderRecordService.get(recordId);
             entity.setAskTime(record.getAskTime());
+            Date now = new Date();
+            entity.setExpireTime(Tools.addHour(now, record.getAskTime() / 3600));
         }else{
             // todo 判断题目是否有提问权限
         }
@@ -1328,6 +1331,8 @@ public class MyController {
             entity.setRecordId(userCourse.getRecordId());
             UserOrderRecord record = userOrderRecordService.get(userCourse.getRecordId());
             entity.setAskTime(record.getAskTime());
+            Date now = new Date();
+            entity.setExpireTime(Tools.addHour(now, record.getAskTime() / 3600));
         }else{
             throw new ParameterException("课程需开通后才能提问");
         }

+ 23 - 9
server/gateway-api/src/main/java/com/qxgmat/dto/admin/extend/QuestionExtendDto.java

@@ -3,6 +3,8 @@ package com.qxgmat.dto.admin.extend;
 import com.nuliji.tools.annotation.Dto;
 import com.qxgmat.data.dao.entity.Question;
 
+import java.util.Date;
+
 @Dto(entity = Question.class)
 public class QuestionExtendDto {
 
@@ -10,12 +12,16 @@ public class QuestionExtendDto {
 
     private String description;
 
-    private String type;
+    private String questionType;
+
     private String difficult;
+
     private String place;
 
     private Integer[] associationContent;
 
+    private Date updateTime;
+
     public Integer getId() {
         return id;
     }
@@ -24,14 +30,6 @@ public class QuestionExtendDto {
         this.id = id;
     }
 
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
     public String getDifficult() {
         return difficult;
     }
@@ -63,4 +61,20 @@ public class QuestionExtendDto {
     public void setDescription(String description) {
         this.description = description;
     }
+
+    public String getQuestionType() {
+        return questionType;
+    }
+
+    public void setQuestionType(String questionType) {
+        this.questionType = questionType;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
 }

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

@@ -16,6 +16,8 @@ public class UserOrderRecordExtendDto {
 
     private String money;
 
+    private String source;
+
     public String getProductType() {
         return productType;
     }
@@ -71,4 +73,12 @@ public class UserOrderRecordExtendDto {
     public void setMoney(String money) {
         this.money = money;
     }
+
+    public String getSource() {
+        return source;
+    }
+
+    public void setSource(String source) {
+        this.source = source;
+    }
 }

+ 17 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/admin/request/UserFrozenDto.java

@@ -0,0 +1,17 @@
+package com.qxgmat.dto.admin.request;
+
+import com.nuliji.tools.annotation.Dto;
+import com.qxgmat.data.dao.entity.User;
+
+@Dto(entity = User.class)
+public class UserFrozenDto {
+    private Integer id;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+}

+ 11 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/admin/response/TextbookQuestionListDto.java

@@ -2,6 +2,7 @@ package com.qxgmat.dto.admin.response;
 
 import com.nuliji.tools.annotation.Dto;
 import com.qxgmat.data.dao.entity.TextbookQuestion;
+import com.qxgmat.dto.admin.extend.QuestionExtendDto;
 
 
 @Dto(entity = TextbookQuestion.class)
@@ -13,6 +14,8 @@ public class TextbookQuestionListDto {
 
     private String title;
 
+    private QuestionExtendDto question;
+
     public Integer getId() {
         return id;
     }
@@ -36,4 +39,12 @@ public class TextbookQuestionListDto {
     public void setTitle(String title) {
         this.title = title;
     }
+
+    public QuestionExtendDto getQuestion() {
+        return question;
+    }
+
+    public void setQuestion(QuestionExtendDto question) {
+        this.question = question;
+    }
 }

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

@@ -30,6 +30,8 @@ public class UserAskCourseListDto {
 
     private Integer askTime;
 
+    private Date expireTime;
+
     private Integer answerStatus;
 
     private Integer showStatus;
@@ -131,4 +133,12 @@ public class UserAskCourseListDto {
     public void setAskTime(Integer askTime) {
         this.askTime = askTime;
     }
+
+    public Date getExpireTime() {
+        return expireTime;
+    }
+
+    public void setExpireTime(Date expireTime) {
+        this.expireTime = expireTime;
+    }
 }

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

@@ -33,6 +33,8 @@ public class UserAskQuestionListDto {
 
     private Integer askTime;
 
+    private Date expireTime;
+
     private Integer answerStatus;
 
     private Integer showStatus;
@@ -150,4 +152,12 @@ public class UserAskQuestionListDto {
     public void setPaperModule(String paperModule) {
         this.paperModule = paperModule;
     }
+
+    public Date getExpireTime() {
+        return expireTime;
+    }
+
+    public void setExpireTime(Date expireTime) {
+        this.expireTime = expireTime;
+    }
 }

+ 13 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/request/CourseTrailViewDto.java

@@ -0,0 +1,13 @@
+package com.qxgmat.dto.request;
+
+public class CourseTrailViewDto {
+    private Integer id;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+}

+ 13 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/request/ExperienceViewDto.java

@@ -0,0 +1,13 @@
+package com.qxgmat.dto.request;
+
+public class ExperienceViewDto {
+    private Integer id;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+}

+ 18 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/response/CourseExperienceDetailDto.java

@@ -0,0 +1,18 @@
+package com.qxgmat.dto.response;
+
+import com.nuliji.tools.annotation.Dto;
+import com.qxgmat.data.dao.entity.CourseExperience;
+import com.qxgmat.dto.extend.UserExtendDto;
+
+@Dto(entity = CourseExperience.class)
+public class CourseExperienceDetailDto extends  CourseExperience {
+    private UserExtendDto user;
+
+    public UserExtendDto getUser() {
+        return user;
+    }
+
+    public void setUser(UserExtendDto user) {
+        this.user = user;
+    }
+}

+ 150 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/response/CourseExperienceListDto.java

@@ -0,0 +1,150 @@
+package com.qxgmat.dto.response;
+
+import com.nuliji.tools.annotation.Dto;
+import com.qxgmat.data.dao.entity.CourseExperience;
+import com.qxgmat.dto.extend.UserExtendDto;
+
+import java.util.Date;
+
+@Dto(entity = CourseExperience.class)
+public class CourseExperienceListDto {
+    private Integer id;
+
+    private Integer userId;
+
+    private UserExtendDto user;
+
+    private String nickname;
+
+    private String title;
+
+    private String link;
+
+    private String prepareStatus;
+
+    private Integer experienceDay;
+
+    private Integer experienceScore;
+
+    private String experiencePercent;
+
+    private Integer viewNumber;
+
+    private Integer collectNumber;
+
+    private Date createTime;
+
+    private Date updateTime;
+
+    public UserExtendDto getUser() {
+        return user;
+    }
+
+    public void setUser(UserExtendDto user) {
+        this.user = user;
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public String getNickname() {
+        return nickname;
+    }
+
+    public void setNickname(String nickname) {
+        this.nickname = nickname;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getLink() {
+        return link;
+    }
+
+    public void setLink(String link) {
+        this.link = link;
+    }
+
+    public String getPrepareStatus() {
+        return prepareStatus;
+    }
+
+    public void setPrepareStatus(String prepareStatus) {
+        this.prepareStatus = prepareStatus;
+    }
+
+    public Integer getExperienceDay() {
+        return experienceDay;
+    }
+
+    public void setExperienceDay(Integer experienceDay) {
+        this.experienceDay = experienceDay;
+    }
+
+    public Integer getExperienceScore() {
+        return experienceScore;
+    }
+
+    public void setExperienceScore(Integer experienceScore) {
+        this.experienceScore = experienceScore;
+    }
+
+    public String getExperiencePercent() {
+        return experiencePercent;
+    }
+
+    public void setExperiencePercent(String experiencePercent) {
+        this.experiencePercent = experiencePercent;
+    }
+
+    public Integer getViewNumber() {
+        return viewNumber;
+    }
+
+    public void setViewNumber(Integer viewNumber) {
+        this.viewNumber = viewNumber;
+    }
+
+    public Integer getCollectNumber() {
+        return collectNumber;
+    }
+
+    public void setCollectNumber(Integer collectNumber) {
+        this.collectNumber = collectNumber;
+    }
+
+    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;
+    }
+}

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

@@ -313,7 +313,7 @@ public class UserQuestionService extends AbstractService {
     public UserRecordStatRelation stat(Integer userId, String startTime, String endTime){
         List<UserRecordStatRelation> list = userQuestionRelationMapper.stat(userId, startTime, endTime);
         if (list!=null && list.size() > 0){
-            return list.get(1);
+            return list.get(0);
         }
         return null;
     }
@@ -327,7 +327,7 @@ public class UserQuestionService extends AbstractService {
     public UserRecordStatRelation statAvg(String startTime, String endTime){
         List<UserRecordStatRelation> list = userQuestionRelationMapper.statAvg(startTime, endTime);
         if (list!=null && list.size() > 0){
-            return list.get(1);
+            return list.get(0);
         }
         return null;
     }

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

@@ -463,11 +463,10 @@ public class UsersService extends AbstractService {
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;

+ 4 - 4
server/gateway-api/src/main/java/com/qxgmat/service/extend/CourseExtendService.java

@@ -106,8 +106,8 @@ public class CourseExtendService {
      * @return
      */
     public Integer studyTime(Integer userId, Date startTime, Date endTime){
-        UserRecordStatRelation record = userCourseRecordService.stat(userId, startTime.toString(), endTime.toString());
-        return record == null ? record.getUserTime() : 0;
+        UserRecordStatRelation record = userCourseRecordService.stat(userId, startTime != null? startTime.toString():null, endTime != null ? endTime.toString(): null);
+        return record != null ? record.getUserTime() : 0;
     }
 
     /**
@@ -115,8 +115,8 @@ public class CourseExtendService {
      * @return
      */
     public Integer studyAvgTime(Date startTime, Date endTime){
-        UserRecordStatRelation record = userCourseRecordService.statAvg(startTime.toString(), endTime.toString());
-        return record == null ? record.getUserTime() : 0;
+        UserRecordStatRelation record = userCourseRecordService.statAvg(startTime != null? startTime.toString():null, endTime != null ? endTime.toString(): null);
+        return record != null ? record.getUserTime() : 0;
     }
 
     public UserCourse userCourse(Integer userId, Integer courseId){

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

@@ -150,6 +150,7 @@ public class ExaminationService extends AbstractService {
     }
 
     private Map<String, String> adminMap = new HashMap<String, String>(){{
+        put("updateTime", "q");
         put("", "qn");
     }};
 
@@ -171,11 +172,10 @@ public class ExaminationService extends AbstractService {
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;

+ 4 - 3
server/gateway-api/src/main/java/com/qxgmat/service/extend/ExerciseService.java

@@ -66,6 +66,8 @@ public class ExerciseService extends AbstractService {
     private UserReportService userReportService;
 
     private Map<String, String> adminMap = new HashMap<String, String>(){{
+        put("updateTime", "q");
+        put("no", "ep");
         put("", "qn");
     }};
     /**
@@ -88,11 +90,10 @@ public class ExerciseService extends AbstractService {
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;

+ 1 - 0
server/gateway-api/src/main/java/com/qxgmat/service/extend/MessageExtendService.java

@@ -57,6 +57,7 @@ public class MessageExtendService {
                 default:
                     throw new ParameterException("消息发送方式错误");
             }
+            messageTemplateService.accumulation(template.getId(), 1);
         }
     }
 

+ 30 - 18
server/gateway-api/src/main/java/com/qxgmat/service/extend/OrderFlowService.java

@@ -391,6 +391,10 @@ public class OrderFlowService {
 
         initRecordCallback.put(ProductType.COURSE, ((order, record) -> {
             Course course = courseService.get(record.getProductId());
+
+            // 记录销售数量
+            courseService.accumulation(course.getId(), 0, record.getParentId() ==0 ? 1:0, record.getParentId() != 0 ? 1:0);
+
             CourseModule courseModule = CourseModule.ValueOf(course.getCourseModule());
             // 小班课程不会存在记录,在线视频和1v1授课都有有效期
             Date startTime = new Date();
@@ -414,6 +418,9 @@ public class OrderFlowService {
             // 处理套餐赠送
             CoursePackage coursePackage = coursePackageService.get(record.getProductId());
 
+            // 记录销售数量
+            coursePackageService.accumulation(coursePackage.getId(), 1);
+
             InitRecord callback = initRecordCallback.get(ProductType.SERVICE);
             JSONObject gift = coursePackage.getGift();
             Integer qxCat = gift.getInteger(ServiceKey.QX_CAT.key);
@@ -464,6 +471,9 @@ public class OrderFlowService {
             record.setIsUsed(1);
             Date time = new Date();
             record.setUseTime(time);
+
+            // 记录销售数量
+            courseDataService.accumulation(record.getProductId(), 1, 0);
             return record;
         }));
         initRecordCallback.put(ProductType.SERVICE, ((order, record)->{
@@ -747,24 +757,26 @@ public class OrderFlowService {
         }
 
         JSONArray gift = userOrder.getGift();
-        for(Object infoO : gift){
-            JSONObject info = (JSONObject)infoO;
-            if(info.get("key").equals("vs")){
-                // 添加赠送课时
-                Integer courseId = info.getInteger("courseId");
-                if(courseId != null){
-                    UserOrderRecord record = UserOrderRecord.builder()
-                            .orderId(userOrder.getId())
-                            .userId(userOrder.getUserId())
-                            .productType(ProductType.COURSE.key)
-                            .productId(courseId)
-                            .number(info.getIntValue("number"))
-                            .source(RecordSource.GIFT_COURSE.key)
-                            .build();
-
-                    InitRecord callback = initRecordCallback.get(ProductType.ValueOf(record.getProductType()));
-                    callback.callback(userOrder, record);
-                    userOrderRecordService.add(record);
+        if (gift != null){
+            for(Object infoO : gift){
+                JSONObject info = (JSONObject)infoO;
+                if(info.get("key").equals("vs")){
+                    // 添加赠送课时
+                    Integer courseId = info.getInteger("courseId");
+                    if(courseId != null){
+                        UserOrderRecord record = UserOrderRecord.builder()
+                                .orderId(userOrder.getId())
+                                .userId(userOrder.getUserId())
+                                .productType(ProductType.COURSE.key)
+                                .productId(courseId)
+                                .number(info.getIntValue("number"))
+                                .source(RecordSource.GIFT_COURSE.key)
+                                .build();
+
+                        InitRecord callback = initRecordCallback.get(ProductType.ValueOf(record.getProductType()));
+                        callback.callback(userOrder, record);
+                        userOrderRecordService.add(record);
+                    }
                 }
             }
         }

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

@@ -743,8 +743,8 @@ public class QuestionFlowService {
      * @return
      */
     public Integer studyTime(Integer userId, Date startTime, Date endTime){
-        UserRecordStatRelation record = userQuestionService.stat(userId, startTime.toString(), endTime.toString());
-        return record == null ? record.getUserTime() : 0;
+        UserRecordStatRelation record = userQuestionService.stat(userId, startTime != null? startTime.toString():null, endTime != null ? endTime.toString(): null);
+        return record != null ? record.getUserTime() : 0;
     }
 
     /**
@@ -752,8 +752,8 @@ public class QuestionFlowService {
      * @return
      */
     public Integer studyAvgTime(Date startTime, Date endTime){
-        UserRecordStatRelation record = userQuestionService.statAvg(startTime.toString(), endTime.toString());
-        return record == null ? record.getUserTime() : 0;
+        UserRecordStatRelation record = userQuestionService.statAvg(startTime != null? startTime.toString():null, endTime != null ? endTime.toString(): null);
+        return record != null ? record.getUserTime() : 0;
     }
 
     /**

+ 4 - 4
server/gateway-api/src/main/java/com/qxgmat/service/extend/SentenceService.java

@@ -185,8 +185,8 @@ public class SentenceService {
      * @return
      */
     public Integer studyTime(Integer userId, Date startTime, Date endTime){
-        UserRecordStatRelation record = userSentenceRecordService.stat(userId, startTime.toString(), endTime.toString());
-        return record == null ? record.getUserTime() : 0;
+        UserRecordStatRelation record = userSentenceRecordService.stat(userId, startTime != null? startTime.toString():null, endTime != null ? endTime.toString(): null);
+        return record != null ? record.getUserTime() : 0;
     }
 
     /**
@@ -194,8 +194,8 @@ public class SentenceService {
      * @return
      */
     public Integer studyAvgTime(Date startTime, Date endTime){
-        UserRecordStatRelation record = userSentenceRecordService.statAvg(startTime.toString(), endTime.toString());
-        return record == null ? record.getUserTime() : 0;
+        UserRecordStatRelation record = userSentenceRecordService.statAvg(startTime != null? startTime.toString():null, endTime != null ? endTime.toString(): null);
+        return record != null ? record.getUserTime() : 0;
     }
 
     /**

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

@@ -123,7 +123,7 @@ public class TextbookService {
     private void addQuestionToPaper(TextbookLibrary library, TextbookQuestion question, TextbookLogic logic){
         String prefixTitle = generatePrefixTitle(library);
         // 获取最后一个paper
-        TextbookPaper paper = textbookPaperService.getLastBySet(logic, question.getLibraryId());
+        TextbookPaper paper = textbookPaperService.getLastByLibrary(logic, question.getLibraryId());
         Integer no = 0;
         if (paper == null || paper.getQuestionNumber().equals(paperLength)){
             if (paper != null){

+ 2 - 3
server/gateway-api/src/main/java/com/qxgmat/service/inline/CommentService.java

@@ -41,11 +41,10 @@ public class CommentService extends AbstractService {
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;

+ 2 - 3
server/gateway-api/src/main/java/com/qxgmat/service/inline/CourseExperienceService.java

@@ -44,11 +44,10 @@ public class CourseExperienceService extends AbstractService {
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;

+ 2 - 3
server/gateway-api/src/main/java/com/qxgmat/service/inline/FaqService.java

@@ -41,11 +41,10 @@ public class FaqService extends AbstractService {
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;

+ 12 - 0
server/gateway-api/src/main/java/com/qxgmat/service/inline/MessageTemplateService.java

@@ -11,6 +11,7 @@ import com.qxgmat.data.constants.enums.MessageType;
 import com.qxgmat.data.constants.enums.status.DirectionStatus;
 import com.qxgmat.data.dao.MessageTemplateMapper;
 import com.qxgmat.data.dao.entity.MessageTemplate;
+import com.qxgmat.data.relation.MessageTemplateRelationMapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -27,6 +28,9 @@ public class MessageTemplateService extends AbstractService {
     @Resource
     private MessageTemplateMapper messageTemplateMapper;
 
+    @Resource
+    private MessageTemplateRelationMapper messageTemplateRelationMapper;
+
     public Page<MessageTemplate> listAdmin(int page, int pageSize, MessageCategory messageCategory, MessageMethod messageMethod, Boolean needCustom, String order, DirectionStatus direction){
         Example example = new Example(MessageTemplate.class);
         if(messageCategory != null)
@@ -89,6 +93,14 @@ public class MessageTemplateService extends AbstractService {
         return select(messageTemplateMapper, example);
     }
 
+    /**
+     * 累加做题记录到questionNo
+     * @param id
+     */
+    public void accumulation(int id, int number){
+        messageTemplateRelationMapper.accumulation(id, number);
+    }
+
     public MessageTemplate add(MessageTemplate message){
         int result = insert(messageTemplateMapper, message);
         message = one(messageTemplateMapper, message.getId());

+ 2 - 3
server/gateway-api/src/main/java/com/qxgmat/service/inline/PreviewPaperService.java

@@ -52,11 +52,10 @@ public class PreviewPaperService extends AbstractService {
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;

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

@@ -105,12 +105,12 @@ public class TextbookPaperService extends AbstractService {
         return select(textbookPaperMapper, example);
     }
 
-    public TextbookPaper getLastBySet(TextbookLogic logic, Integer setId){
+    public TextbookPaper getLastByLibrary(TextbookLogic logic, Integer libraryId){
         Example example = new Example(TextbookPaper.class);
         example.and(
                 example.createCriteria()
                         .andEqualTo("logic", logic.key)
-                        .andEqualTo("setId", setId)
+                        .andEqualTo("libraryId", libraryId)
         );
         example.orderBy("createTime").desc();
         return one(textbookPaperMapper, example);

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

@@ -55,15 +55,14 @@ public class TextbookQuestionService extends AbstractService {
      * @param direction
      * @return
      */
-    public Page<TextbookQuestion> listAdmin(int page, int pageSize, String questionType, Number paperId, Integer questionNoId, String order, DirectionStatus direction){
+    public Page<TextbookQuestionRelation> listAdmin(int page, int pageSize, String questionType, Number paperId, Integer questionNoId, String order, DirectionStatus direction){
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;
@@ -71,15 +70,15 @@ public class TextbookQuestionService extends AbstractService {
         String finalOrder = order;
         DirectionStatus finalDirection = direction;
 
-        Page<TextbookQuestion> p = page(() -> {
+        Page<TextbookQuestionRelation> p = page(() -> {
             textbookQuestionRelationMapper.listAdmin(questionType, paperId, questionNoId, finalOrder, finalDirection.key);
         }, page, pageSize);
 
-        Collection ids = Transform.getIds(p, TextbookQuestion.class, "id");
+        Collection ids = Transform.getIds(p, TextbookQuestionRelation.class, "id");
 
         // 获取详细数据
-        List<TextbookQuestion> list = select(ids);
-        Transform.replace(p, list, TextbookQuestion.class, "id");
+        List<TextbookQuestionRelation> list = relation(select(ids));
+        Transform.replace(p, list, TextbookQuestionRelation.class, "id");
 
         return p;
     }

+ 4 - 5
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserAbnormalService.java

@@ -39,15 +39,14 @@ public class UserAbnormalService extends AbstractService {
         put("", "ua");
     }};
 
-    public Page<UserAbnormal> listAdmin(int page, int size, Integer userId, Integer totalAlert, String order, DirectionStatus direction){
+    public Page<UserAbnormal> listAdmin(int page, int size, Integer userId, Integer totalAlert, String startTime, String endTime, String order, DirectionStatus direction){
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;
@@ -55,7 +54,7 @@ public class UserAbnormalService extends AbstractService {
         String finalOrder = order;
         DirectionStatus finalDirection = direction;
         Page<UserAbnormal> p = page(
-                ()-> userAbnormalRelationMapper.listAdmin(userId, totalAlert, finalOrder, finalDirection.key)
+                ()-> userAbnormalRelationMapper.listAdmin(userId, totalAlert, startTime, endTime, finalOrder, finalDirection.key)
                 , page, size);
 
         Collection ids = Transform.getIds(p, UserAbnormal.class, "id");

+ 4 - 9
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserAskCourseService.java

@@ -9,14 +9,10 @@ import com.nuliji.tools.exception.SystemException;
 import com.nuliji.tools.mybatis.Example;
 import com.qxgmat.data.constants.enums.status.AskStatus;
 import com.qxgmat.data.constants.enums.status.DirectionStatus;
-import com.qxgmat.data.constants.enums.user.AskTarget;
 import com.qxgmat.data.constants.enums.user.MoneyRange;
 import com.qxgmat.data.dao.UserAskCourseMapper;
-import com.qxgmat.data.dao.UserAskQuestionMapper;
 import com.qxgmat.data.dao.entity.UserAskCourse;
-import com.qxgmat.data.dao.entity.UserAskQuestion;
 import com.qxgmat.data.relation.UserAskCourseRelationMapper;
-import com.qxgmat.data.relation.UserAskQuestionRelationMapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -42,18 +38,17 @@ public class UserAskCourseService extends AbstractService {
         put("", "uac");
     }};
 
-    public Page<UserAskCourse> listAdmin(int page, int size, Integer structId, Number courseId, AskStatus status, Integer showStatus, Integer userId, MoneyRange moneyRange, String order, DirectionStatus direction){
+    public Page<UserAskCourse> listAdmin(int page, int size, Integer structId, Number courseId, AskStatus status, Integer showStatus, Integer userId, MoneyRange moneyRange, String startTime, String endTime, String order, DirectionStatus direction){
         Integer statusIndex = status != null ? status.index : null;
         Integer max = moneyRange != null ? moneyRange.max == Integer.MAX_VALUE ? null : moneyRange.max : null;
         Integer min = moneyRange != null ? moneyRange.min : null;
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;
@@ -61,7 +56,7 @@ public class UserAskCourseService extends AbstractService {
         String finalOrder = order;
         DirectionStatus finalDirection = direction;
         Page<UserAskCourse> p = page(
-                ()-> userAskCourseRelationMapper.listWithCourse(structId, courseId, statusIndex, showStatus, userId, min, max, finalOrder, finalDirection.key)
+                ()-> userAskCourseRelationMapper.listAdmin(structId, courseId, statusIndex, showStatus, userId, min, max, startTime, endTime, finalOrder, finalDirection.key)
         , page, size);
 
         Collection ids = Transform.getIds(p, UserAskCourse.class, "id");

+ 4 - 6
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserAskQuestionService.java

@@ -12,7 +12,6 @@ import com.qxgmat.data.constants.enums.status.DirectionStatus;
 import com.qxgmat.data.constants.enums.user.AskTarget;
 import com.qxgmat.data.constants.enums.user.MoneyRange;
 import com.qxgmat.data.dao.UserAskQuestionMapper;
-import com.qxgmat.data.dao.entity.QuestionNo;
 import com.qxgmat.data.dao.entity.UserAskQuestion;
 import com.qxgmat.data.relation.UserAskQuestionRelationMapper;
 import org.slf4j.Logger;
@@ -60,7 +59,7 @@ public class UserAskQuestionService extends AbstractService {
         put("", "uaq");
     }};
 
-    public Page<UserAskQuestion> listAdmin(int page, int size, String askModule, String questionType, String questionModule, Number userId, Number questionNoId, AskTarget target, AskStatus status, Integer showStatus, MoneyRange moneyRange, Boolean hasRecord, String order, DirectionStatus direction){
+    public Page<UserAskQuestion> listAdmin(int page, int size, String askModule, String questionType, String questionModule, Number userId, Number questionNoId, AskTarget target, AskStatus status, Integer showStatus, MoneyRange moneyRange, Boolean hasRecord, String startTime, String endTime, String order, DirectionStatus direction){
         String tk = target != null ? target.key : "";
         Integer statusIndex = status != null ? status.index : null;
         Integer max = moneyRange != null ? moneyRange.max == Integer.MAX_VALUE ? null : moneyRange.max : null;
@@ -68,11 +67,10 @@ public class UserAskQuestionService extends AbstractService {
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;
@@ -80,7 +78,7 @@ public class UserAskQuestionService extends AbstractService {
         String finalOrder = order;
         DirectionStatus finalDirection = direction;
         Page<UserAskQuestion> p = page(
-                ()-> userAskQuestionRelationMapper.listWithUser(askModule, questionType, questionModule, userId, questionNoId, tk, statusIndex, showStatus, min, max, hasRecord, finalOrder, finalDirection.key)
+                ()-> userAskQuestionRelationMapper.listAdmin(askModule, questionType, questionModule, userId, questionNoId, tk, statusIndex, showStatus, min, max, hasRecord, startTime, endTime, finalOrder, finalDirection.key)
         , page, size);
 
         Collection ids = Transform.getIds(p, UserAskQuestion.class, "id");

+ 2 - 2
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserCourseRecordService.java

@@ -95,7 +95,7 @@ public class UserCourseRecordService extends AbstractService {
     public UserRecordStatRelation stat(Integer userId, String startTime, String endTime){
         List<UserRecordStatRelation> list = userCourseRecordRelationMapper.stat(userId, startTime, endTime);
         if (list!=null && list.size() > 0){
-            return list.get(1);
+            return list.get(0);
         }
         return null;
     }
@@ -109,7 +109,7 @@ public class UserCourseRecordService extends AbstractService {
     public UserRecordStatRelation statAvg(String startTime, String endTime){
         List<UserRecordStatRelation> list = userCourseRecordRelationMapper.statAvg(startTime, endTime);
         if (list!=null && list.size() > 0){
-            return list.get(1);
+            return list.get(0);
         }
         return null;
     }

+ 2 - 3
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserFeedbackErrorService.java

@@ -46,11 +46,10 @@ public class UserFeedbackErrorService extends AbstractService {
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;

+ 8 - 11
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserOrderRecordService.java

@@ -165,9 +165,9 @@ public class UserOrderRecordService extends AbstractService {
             example.and(
                     needMoney ?
                     example.createCriteria()
-                            .andGreaterThan("money", 0) :
+                            .andGreaterThan("orderId", 0) :
                     example.createCriteria()
-                            .andEqualTo("money", 0)
+                            .andEqualTo("orderId", 0)
             );
         }
         if(productType != null){
@@ -367,11 +367,10 @@ public class UserOrderRecordService extends AbstractService {
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;
@@ -400,11 +399,10 @@ public class UserOrderRecordService extends AbstractService {
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;
@@ -432,11 +430,10 @@ public class UserOrderRecordService extends AbstractService {
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;

+ 2 - 3
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserOrderService.java

@@ -40,11 +40,10 @@ public class UserOrderService extends AbstractService {
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;

+ 2 - 2
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserSentenceRecordService.java

@@ -38,7 +38,7 @@ public class UserSentenceRecordService extends AbstractService {
     public UserRecordStatRelation stat(Integer userId, String startTime, String endTime){
         List<UserRecordStatRelation> list = userSentenceRecordRelationMapper.stat(userId, startTime, endTime);
         if (list!=null && list.size() > 0){
-            return list.get(1);
+            return list.get(0);
         }
         return null;
     }
@@ -52,7 +52,7 @@ public class UserSentenceRecordService extends AbstractService {
     public UserRecordStatRelation statAvg(String startTime, String endTime){
         List<UserRecordStatRelation> list = userSentenceRecordRelationMapper.statAvg(startTime, endTime);
         if (list!=null && list.size() > 0){
-            return list.get(1);
+            return list.get(0);
         }
         return null;
     }

+ 2 - 3
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserTextbookFeedbackService.java

@@ -40,11 +40,10 @@ public class UserTextbookFeedbackService extends AbstractService {
         if(order == null || order.isEmpty()){
             order = "id";
         }
-        order = Tools.underscoreName(order);
         if(adminMap.containsKey(order)){
-            order = adminMap.get(order)+".`"+order+"`";
+            order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
         }else{
-            order = adminMap.get("")+".`"+order+"`";
+            order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
         }
         if (direction == null){
             direction = DirectionStatus.DESC;

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

@@ -231,7 +231,7 @@ public class AsyncTask {
     public void postTextbookToEmail(){
         logger.info("发布机经:发送到订阅用户邮箱");
         long start = System.currentTimeMillis();
-        // 获取订阅用户及其邮箱
+        // todo 获取订阅用户及其邮箱
 
         long end = System.currentTimeMillis();
         logger.info("发布机经,耗时:" + (end - start) + "毫秒");

+ 1 - 1
server/gateway-api/src/main/java/com/qxgmat/task/ScheduledTask.java

@@ -144,7 +144,7 @@ public class ScheduledTask {
                     .sendStatus(MessageStatus.SENDING.index)
                     .build());
             int number = 0;
-
+            // todo
             messageTemplateService.edit(MessageTemplate.builder()
                     .id(message.getId())
                     .sendNumber(number)

+ 7 - 0
server/tools/src/main/java/com/nuliji/tools/Tools.java

@@ -271,6 +271,13 @@ public class Tools {
         return calendar.get(Calendar.YEAR);
     }
 
+    public static Date addHour(Date date, int hour){
+        Calendar c = Calendar.getInstance();
+        c.setTime(date);
+        c.add(Calendar.HOUR, hour);
+        return c.getTime();
+    }
+
     public static Date addDate(Date date, int day){
         Calendar c = Calendar.getInstance();
         c.setTime(date);