Kaynağa Gözat

feat(front): 个人中心复选

Go 4 yıl önce
ebeveyn
işleme
5bfd08689d
36 değiştirilmiş dosya ile 413 ekleme ve 202 silme
  1. 3 3
      front/config/local.json
  2. 6 3
      front/project/admin/routes/course/dataHistory/page.js
  3. 2 1
      front/project/admin/routes/course/index.js
  4. 22 4
      front/project/h5/routes/product/courseVs/page.js
  5. 7 0
      front/project/h5/stores/main.js
  6. 2 2
      front/project/h5/stores/order.js
  7. 8 13
      front/project/www/components/UserAction/index.js
  8. 13 3
      front/project/www/routes/my/answer/page.js
  9. 28 17
      front/project/www/routes/my/collect/page.js
  10. 26 15
      front/project/www/routes/my/error/page.js
  11. 54 14
      front/project/www/routes/my/note/page.js
  12. 22 7
      front/project/www/routes/my/report/page.js
  13. 8 0
      front/project/www/routes/my/tools/index.less
  14. 24 16
      front/project/www/routes/my/tools/page.js
  15. 7 0
      front/project/www/stores/main.js
  16. 1 1
      front/project/www/stores/my.js
  17. 2 2
      front/project/www/stores/order.js
  18. 6 2
      front/project/www/stores/textbook.js
  19. 2 1
      front/src/containers/Page.js
  20. 3 3
      server/data/src/main/java/com/qxgmat/data/relation/mapping/CommentRelationMapper.xml
  21. 1 1
      server/data/src/main/java/com/qxgmat/data/relation/mapping/CourseDataHistoryRelationMapper.xml
  22. 3 3
      server/data/src/main/java/com/qxgmat/data/relation/mapping/FaqRelationMapper.xml
  23. 2 2
      server/data/src/main/resources/db/migration/V1__init_table.sql
  24. 8 0
      server/gateway-api/src/main/java/com/qxgmat/controller/api/BaseController.java
  25. 9 4
      server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java
  26. 19 0
      server/gateway-api/src/main/java/com/qxgmat/controller/api/TextbookController.java
  27. 21 19
      server/gateway-api/src/main/java/com/qxgmat/dto/admin/request/CourseDataHistoryDto.java
  28. 1 1
      server/gateway-api/src/main/java/com/qxgmat/service/UserCollectQuestionService.java
  29. 1 0
      server/gateway-api/src/main/java/com/qxgmat/service/extend/OrderFlowService.java
  30. 18 10
      server/gateway-api/src/main/java/com/qxgmat/service/extend/QuestionFlowService.java
  31. 5 5
      server/gateway-api/src/main/java/com/qxgmat/service/extend/ToolsService.java
  32. 29 0
      server/gateway-api/src/main/java/com/qxgmat/service/inline/QuestionNoService.java
  33. 24 24
      server/gateway-api/src/main/java/com/qxgmat/service/inline/SentenceQuestionService.java
  34. 24 24
      server/gateway-api/src/main/java/com/qxgmat/service/inline/TextbookQuestionService.java
  35. 1 1
      server/gateway-api/src/main/profile/dev/application-runtime.yml
  36. 1 1
      server/gateway-api/src/main/profile/test/application-runtime.yml

+ 3 - 3
front/config/local.json

@@ -16,7 +16,7 @@
       }
     ],
     "PcUrl": "http://127.0.0.1:3000",
-    "WechatPcAppId": "wx324965bb6800f9b9",
+    "WechatPcAppId": "wxa6a1620243459e6a",
     "H5Url": "http://127.0.0.1:3000",
     "WechatH5AppId": "wx65c7d378b4184bcc"
   },
@@ -30,7 +30,7 @@
     "publicPath": "/",
     "basename": "/",
     "PcUrl": "http://test.duoshaojiaoyu.com",
-    "WechatPcAppId": "wx324965bb6800f9b9",
+    "WechatPcAppId": "wxa6a1620243459e6a",
     "H5Url": "http://mobiletest.duoshaojiaoyu.com",
     "WechatH5AppId": "wx65c7d378b4184bcc"
   },
@@ -48,4 +48,4 @@
     "H5Url": "http://h5.duoshaojiaoyu.com",
     "WechatH5AppId": "wxbee75af2ece94ed7"
   }
-}
+}

+ 6 - 3
front/project/admin/routes/course/dataHistory/page.js

@@ -33,6 +33,9 @@ export default class extends Page {
       key: 'id',
       type: 'hidden',
     }, {
+      key: 'dataId',
+      type: 'hidden',
+    }, {
       key: 'time',
       type: 'date',
       name: '更新时间',
@@ -118,8 +121,9 @@ export default class extends Page {
     });
   }
 
-  addHistory() {
-    asyncForm('创建', this.itemList, {}, data => {
+  addHistoryAction() {
+    const { id } = this.params;
+    asyncForm('创建', this.itemList, { dataId: id }, data => {
       return Course.addDataHistory(data).then(() => {
         asyncSMessage('添加成功!');
         this.refreshHistory();
@@ -213,7 +217,6 @@ export default class extends Page {
   renderView() {
     const { history } = this.state;
     return <div flex>
-      {this.renderBase()}
       {this.renderFile()}
       {history && this.renderHistory()}
 

+ 2 - 1
front/project/admin/routes/course/index.js

@@ -6,10 +6,11 @@ import previewDetail from './previewDetail';
 import Package from './package';
 import data from './data';
 import dataDetail from './dataDetail';
+import dataHistory from './dataHistory';
 import experience from './experience';
 import experienceDetail from './experienceDetail';
 import invoice from './invoice';
 
 import student from './student';
 
-export default [list, detail, vsDetail, preview, previewDetail, Package, data, dataDetail, experience, experienceDetail, invoice, student];
+export default [list, detail, vsDetail, preview, previewDetail, Package, data, dataDetail, dataHistory, experience, experienceDetail, invoice, student];

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

@@ -6,6 +6,7 @@ import Money from '../../../components/Money';
 import Button from '../../../components/Button';
 import { FAQItem, CommentItem } from '../../../components/Item';
 import { Course } from '../../../stores/course';
+import { Main } from '../../../stores/main';
 import { Order } from '../../../stores/order';
 import Icon from '../../../components/Icon';
 
@@ -16,15 +17,32 @@ export default class extends Page {
 
   initData() {
     const { id } = this.params;
-    Course.get(id).then(result => {
-      this.setState({ data: result });
-      this.changeNumber(1);
+    Main.getPromote().then(result => {
+      this.promote = result.vs_list || [];
+      Course.get(id).then(data => {
+        this.setState({ data });
+        this.changeNumber(1);
+      });
     });
   }
 
   changeNumber(number) {
     const { data } = this.state;
-    const price = data.price * number;
+    let price = data.price * number;
+    let max = 0;
+    let maxIndex = -1;
+    this.promote = [{ number: 2, percent: 90 }];
+    this.promote.forEach((row, i) => {
+      if (row.number <= number) {
+        if (row.number > max) {
+          max = number;
+          maxIndex = i;
+        }
+      }
+    });
+    if (maxIndex >= 0) {
+      price *= this.promote[maxIndex].percent / 100;
+    }
     this.setState({ number, price });
   }
 

+ 7 - 0
front/project/h5/stores/main.js

@@ -28,6 +28,13 @@ export default class MainStore extends BaseStore {
   }
 
   /**
+   * 获取优惠信息
+   */
+  getPromote() {
+    return this.apiGet('/base/promote');
+  }
+
+  /**
    * 获取微信信息
    */
   getWechat() {

+ 2 - 2
front/project/h5/stores/order.js

@@ -58,8 +58,8 @@ export default class OrderStore extends BaseStore {
    * 开通服务、课程等
    * @param {*} id
    */
-  useRecord(id, isSubscribe) {
-    return this.apiPost('/order/record/use', { id, isSubscribe });
+  useRecord(recordId, isSubscribe) {
+    return this.apiPost('/order/record/use', { recordId, isSubscribe });
   }
 }
 

+ 8 - 13
front/project/www/components/UserAction/index.js

@@ -31,7 +31,7 @@ export default class UserAction extends Component {
   }
 
   onSearch(value) {
-    this.setState({ searchText: value });
+    this.setState({ searchText: value, showInput: true });
   }
 
   onFilter(key, value) {
@@ -50,6 +50,7 @@ export default class UserAction extends Component {
     const {
       allCheckbox,
       allChecked,
+      defaultSearch,
       help,
       btnList = [],
       search,
@@ -101,40 +102,34 @@ export default class UserAction extends Component {
                 {item.fixed ? (
                   sortMap[item.key] ? (
                     <GIcon active name="arrow-down" onClick={() => this.onSort(item.key, '')} />
-                  ) : (
-                    <GIcon name="arrow-up" onClick={() => this.onSort(item.key, 'desc')} />
-                  )
+                  ) : (<GIcon name="arrow-up" onClick={() => this.onSort(item.key, 'desc')} />)
                 ) : sortMap[item.key] ? (
                   <Assets
                     name={sortMap[item.key] === 'asc' ? 'seqencing2_up_select' : 'seqencing2_down_select'}
                     onClick={() => this.onSort(item.key, sortMap[item.key] === 'asc' ? 'desc' : '')}
                   />
-                ) : (
-                  <Assets name="seqencing2_normal" onClick={() => this.onSort(item.key, 'asc')} />
-                )}
+                ) : (<Assets name="seqencing2_normal" onClick={() => this.onSort(item.key, 'asc')} />)}
               </div>
             );
           })}
         </div>
         {search && (
           <div className="search">
-            {showInput && (
+            {(showInput || defaultSearch) && (
               <input
                 className="search-input"
                 placeholder="请输入您想搜索的内容"
-                value={searchText}
+                value={!searchText ? (showInput ? '' : defaultSearch) : searchText}
                 onChange={e => this.onSearch(e.target.value)}
                 onKeyUp={e => this.onSearchKey(e)}
               />
             )}
-            {!showInput && <Icon type="search" onClick={() => this.setState({ showInput: true })} />}
+            {(!showInput && !defaultSearch) && <Icon type="search" onClick={() => this.setState({ showInput: true })} />}
           </div>
         )}
         {right && (
           <div
-            className={`right ${
-              btnList.length === 0 && selectList.length === 0 && sortList.length === 0 ? 'only' : ''
-            }`}
+            className={`right ${btnList.length === 0 && selectList.length === 0 && sortList.length === 0 ? 'only' : ''}`}
           >
             {right}
           </div>

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

@@ -115,7 +115,13 @@ export default class extends Page {
   }
 
   onFilter(value) {
-    this.search(value);
+    this.search(value, false);
+    this.initData();
+  }
+
+  onSearch(value) {
+    this.search({ keyword: value }, false);
+    this.initData();
   }
 
   onSort(value) {
@@ -123,11 +129,13 @@ export default class extends Page {
     // this.search({ order: keys.length ? keys.join('|') : null, direction: keys.length ? Object.values(value).join('|') : null });
     const { sortMap } = this.state;
     const index = keys.length > 1 && sortMap[keys[0]] ? 1 : 0;
-    this.search({ order: keys.length ? keys[index] : null, direction: keys.length ? value[keys[index]] : null });
+    this.search({ order: keys.length ? keys[index] : null, direction: keys.length ? value[keys[index]] : null }, false);
+    this.initData();
   }
 
   onChangePage(page) {
-    this.search({ page });
+    this.search({ page }, false);
+    this.initData();
   }
 
   onAction() { }
@@ -175,6 +183,7 @@ export default class extends Page {
         />
         <UserAction
           search
+          defaultSearch={filterMap.keyword}
           selectList={[
             {
               children: [
@@ -215,6 +224,7 @@ export default class extends Page {
           ]}
           filterMap={filterMap}
           onFilter={value => this.onFilter(value)}
+          onSearch={value => this.onSearch(value)}
         />
         <UserAction
           sortList={[

+ 28 - 17
front/project/www/routes/my/collect/page.js

@@ -2,6 +2,7 @@ import React, { Component } from 'react';
 import './index.less';
 import { Icon, Checkbox } from 'antd';
 import Page from '@src/containers/Page';
+import Assets from '@src/components/Assets';
 import { timeRange, getMap, formatPercent, formatMonth, formatDate, formatSeconds } from '@src/services/Tools';
 import UserLayout from '../../../layouts/User';
 import UserTable from '../../../components/UserTable';
@@ -45,10 +46,11 @@ const columns = [
     title: '耗时',
     sort: true,
     render: (text, record) => {
-      // <Assets height={10} width={10} name='up' />
+      const user = record.stat.userTime / record.stat.userNumber;
+      const all = record.questionNo.totalTime / record.questionNo.totalNumber;
       return <div className="sub">
-        <div className="t-2 t-s-12">{formatSeconds(record.stat.userTime / record.stat.userNumber)}</div>
-        <div className="t-6 t-s-12">全站{formatSeconds(record.questionNo.totalTime / record.questionNo.totalNumber)}</div>
+        <div className="t-2 t-s-12">{formatSeconds(user)}<Assets height={10} width={10} name={user > all ? 'up' : 'down'} /></div>
+        <div className="t-6 t-s-12">全站{formatSeconds(all)}</div>
       </div>;
     },
   },
@@ -58,8 +60,8 @@ const columns = [
     sort: true,
     render: (text, record) => {
       return <div className="sub">
-        <div className="t-2 t-s-12">{formatPercent(record.stat.userCorrect, record.stat.userNumber, false)}</div>
-        <div className="t-6 t-s-12">{record.stat.userCorrect}/{record.stat.userNumber}</div>
+        <div className="t-2 t-s-12">{formatPercent(record.stat.userNumber - record.stat.userCorrect, record.stat.userNumber, false)}</div>
+        <div className="t-6 t-s-12">{record.stat.userNumber - record.stat.userCorrect}/{record.stat.userNumber}</div>
       </div>;
     },
   },
@@ -152,12 +154,12 @@ export default class extends Page {
           },
         ),
       ).then(result => {
-        console.log(result);
         result.list = result.list.map(row => {
+          row.key = row.questionNoId;
           row.questionType = row.question.questionType;
           row.title = row.questionNo.title;
           row.description = row.question.description;
-          row.latestTime = formatDate(row.latestTime, 'YYYY-MM-DD HH:mm:ss');
+          row.latest_time = formatDate(row.latestTime, 'YYYY-MM-DD HH:mm:ss');
           return row;
         });
         this.setState({ list: result.list, total: result.total });
@@ -178,7 +180,13 @@ export default class extends Page {
   }
 
   onFilter(value) {
-    this.search(value);
+    this.search(value, false);
+    this.initData();
+  }
+
+  onSearch(value) {
+    this.search({ keyword: value }, false);
+    this.initData();
   }
 
   onSort(value) {
@@ -186,24 +194,25 @@ export default class extends Page {
     // this.search({ order: keys.length ? keys.join('|') : null, direction: keys.length ? Object.values(value).join('|') : null });
     const { sortMap } = this.state;
     const index = keys.length > 1 && sortMap[keys[0]] ? 1 : 0;
-    this.search({ order: keys.length ? keys[index] : null, direction: keys.length ? value[keys[index]] : null });
+    this.search({ order: keys.length ? keys[index] : null, direction: keys.length ? value[keys[index]] : null }, false);
+    this.initData();
   }
 
   onChangePage(page) {
-    this.search({ page });
+    this.search({ page }, false);
+    this.initData();
   }
 
   onAll(checked) {
+    const selectList = [];
     if (checked) {
-      const { data = [] } = this.state;
-      const list = [];
-      data.forEach(item => {
-        list.push(item.key);
+      const { list = [] } = this.state;
+      list.forEach(item => {
+        if (selectList.indexOf(item.key) >= 0) return;
+        selectList.push(item.key);
       });
-      this.setState({ selectList: list, allChecked: true });
-    } else {
-      this.setState({ selectList: [], allChecked: false });
     }
+    this.setState({ selectList, allChecked: checked });
   }
 
   onSelect(selectList) {
@@ -379,6 +388,7 @@ export default class extends Page {
       <div className="tab-1-layout">
         <UserAction
           search
+          defaultSearch={filterMap.keyword}
           selectList={[
             {
               children: [
@@ -408,6 +418,7 @@ export default class extends Page {
           ]}
           filterMap={filterMap}
           onFilter={value => this.onFilter(value)}
+          onSearch={value => this.onSearch(value)}
         />
         <UserAction
           allCheckbox

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

@@ -2,6 +2,7 @@ import React from 'react';
 import './index.less';
 import { Icon, Checkbox } from 'antd';
 import Page from '@src/containers/Page';
+import Assets from '@src/components/Assets';
 import { timeRange, formatDate, getMap, formatSeconds, formatPercent } from '@src/services/Tools';
 import UserLayout from '../../../layouts/User';
 import UserTable from '../../../components/UserTable';
@@ -43,9 +44,11 @@ const columns = [
     title: '耗时',
     sort: true,
     render: (text, record) => {
+      const user = record.stat.userTime / record.stat.userNumber;
+      const all = record.questionNo.totalTime / record.questionNo.totalNumber;
       return <div className="sub">
-        <div className="t-2 t-s-12">{formatSeconds(record.stat.userTime / record.stat.userNumber)}</div>
-        <div className="t-6 t-s-12">全站{formatSeconds(record.questionNo.totalTime / record.questionNo.totalNumber)}</div>
+        <div className="t-2 t-s-12">{formatSeconds(user)}<Assets height={10} width={10} name={user > all ? 'up' : 'down'} /></div>
+        <div className="t-6 t-s-12">全站{formatSeconds(all)}</div>
       </div>;
     },
   },
@@ -55,8 +58,8 @@ const columns = [
     sort: true,
     render: (text, record) => {
       return <div className="sub">
-        <div className="t-2 t-s-12">{formatPercent(record.stat.userCorrect, record.stat.userNumber, false)}</div>
-        <div className="t-6 t-s-12">{record.stat.userCorrect}/{record.stat.userNumber}</div>
+        <div className="t-2 t-s-12">{formatPercent(record.stat.userNumber - record.stat.userCorrect, record.stat.userNumber, false)}</div>
+        <div className="t-6 t-s-12">{record.stat.userNumber - record.stat.userCorrect}/{record.stat.userNumber}</div>
       </div>;
     },
   },
@@ -148,6 +151,10 @@ export default class extends Page {
             },
           ),
         ).then(result => {
+          result.list = result.list.map(row => {
+            row.key = row.questionNoId;
+            return row;
+          });
           this.setState({ list: result.list, total: result.total });
         });
       });
@@ -160,11 +167,13 @@ export default class extends Page {
   }
 
   onFilter(value) {
-    this.search(value);
+    this.search(value, false);
+    this.initData();
   }
 
   onSearch(value) {
-    console.log(value);
+    this.search({ keyword: value }, false);
+    this.initData();
   }
 
   onSort(value) {
@@ -172,24 +181,25 @@ export default class extends Page {
     // this.search({ order: keys.length ? keys.join('|') : null, direction: keys.length ? Object.values(value).join('|') : null });
     const { sortMap } = this.state;
     const index = keys.length > 1 && sortMap[keys[0]] ? 1 : 0;
-    this.search({ order: keys.length ? keys[index] : null, direction: keys.length ? value[keys[index]] : null });
+    this.search({ order: keys.length ? keys[index] : null, direction: keys.length ? value[keys[index]] : null }, false);
+    this.initData();
   }
 
   onChangePage(page) {
-    this.search({ page });
+    this.search({ page }, false);
+    this.initData();
   }
 
   onAll(checked) {
+    const selectList = [];
     if (checked) {
-      const { data = [] } = this.state;
-      const list = [];
-      data.forEach(item => {
-        list.push(item.key);
+      const { list = [] } = this.state;
+      list.forEach(item => {
+        if (selectList.indexOf(item.key) >= 0) return;
+        selectList.push(item.key);
       });
-      this.setState({ selectList: list, allChecked: true });
-    } else {
-      this.setState({ selectList: [], allChecked: false });
     }
+    this.setState({ selectList, allChecked: checked });
   }
 
   onSelect(selectList) {
@@ -336,6 +346,7 @@ export default class extends Page {
         />
         <UserAction
           search
+          defaultSearch={filterMap.keyword}
           selectList={[
             {
               children: [

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

@@ -130,6 +130,7 @@ export default class extends Page {
           ),
         ).then(result => {
           result.list = result.list.map(row => {
+            row.key = row.questionNoId;
             row.group = true;
             row.questionType = row.question.questionType;
             row.title = row.questionNo.title;
@@ -139,6 +140,7 @@ export default class extends Page {
               if (!row[`${r.value}Content`]) return;
               row.list.push({
                 title: r.value,
+                key: `${row.key}|${r.value}`,
                 updateTime: formatDate(row[`${r.value}Time`], 'YYYY-MM-DD HH:mm:ss'),
                 content: row[`${r.value}Content`],
               });
@@ -157,7 +159,13 @@ export default class extends Page {
   }
 
   onFilter(value) {
-    this.search(value);
+    this.search(value, false);
+    this.initData();
+  }
+
+  onSearch(value) {
+    this.search({ keyword: value }, false);
+    this.initData();
   }
 
   onSort(value) {
@@ -165,44 +173,72 @@ export default class extends Page {
     // this.search({ order: keys.length ? keys.join('|') : null, direction: keys.length ? Object.values(value).join('|') : null });
     const { sortMap } = this.state;
     const index = keys.length > 1 && sortMap[keys[0]] ? 1 : 0;
-    this.search({ order: keys.length ? keys[index] : null, direction: keys.length ? value[keys[index]] : null });
+    this.search({ order: keys.length ? keys[index] : null, direction: keys.length ? value[keys[index]] : null }, false);
   }
 
   onChangePage(page) {
-    this.search({ page });
+    this.search({ page }, false);
+    this.initData();
   }
 
   onAll(checked) {
+    const selectList = [];
     if (checked) {
-      const { data = [] } = this.state;
-      const list = [];
-      data.forEach(item => {
-        list.push(item.key);
+      const { list = [] } = this.state;
+      list.forEach(item => {
+        if (selectList.indexOf(item.key) >= 0) return;
+        selectList.push(item.key);
       });
-      this.setState({ selectList: list, allChecked: true });
-    } else {
-      this.setState({ selectList: [], allChecked: false });
     }
+    this.setState({ selectList, allChecked: checked });
   }
 
   onSelect(selectList) {
     this.setState({ selectList });
   }
 
+  onSelectContent(contentSelectList) {
+    this.setState({ contentSelectList });
+  }
+
   onAction(key) {
     const { info } = this.props.user;
-    const { selectList } = this.state;
+    const { selectList, contentSelectList } = this.state;
+    const questionNoMap = {};
+    let questionNoIds;
     switch (key) {
       case 'help':
         this.setState({ showTips: true });
         return;
       case 'clear':
-        if (selectList.length === 0) {
+        if (selectList.length === 0 && contentSelectList === 0) {
           this.setState({ showWarn: true, warn: { title: '移除', content: '不可少于1题,请重新选择' } });
           return;
         }
-        // this.clearNote();
-        this.setState({ showClearConfirm: true, clearInfo: { questionNoIds: selectList } });
+        contentSelectList.forEach(row => {
+          const [questionNoId, target] = row.split('|');
+          if (selectList.indexOf(questionNoId) >= 0) return;
+          if (!questionNoMap[questionNoId]) {
+            questionNoMap[questionNoId] = {};
+          }
+          questionNoMap[questionNoId][target] = '';
+        });
+        questionNoIds = Object.keys(questionNoMap);
+        if (questionNoIds.length > 0) {
+          Promise.all(questionNoIds.map(row => {
+            return My.updateQuestionNote(row, questionNoMap);
+          }))
+            .then(() => {
+              if (selectList.length > 0) {
+                this.clearNote();
+              } else {
+                this.refresh();
+              }
+            });
+        } else {
+          this.clearNote();
+        }
+        // this.setState({ showClearConfirm: true, clearInfo: { questionNoIds: selectList } });
         break;
       case 'export':
         if (!info.vip) {
@@ -267,6 +303,7 @@ export default class extends Page {
         />
         <UserAction
           search
+          defaultSearch={filterMap.keyword}
           selectList={[
             {
               children: [
@@ -307,6 +344,7 @@ export default class extends Page {
           ]}
           filterMap={filterMap}
           onFilter={value => this.onFilter(value)}
+          onSearch={value => this.onSearch(value)}
         />
         <UserAction
           allCheckbox
@@ -333,6 +371,7 @@ export default class extends Page {
                 selectList={selectList}
                 columns={questionColumns}
                 data={[item]}
+                onSelect={l => this.onSelect(l)}
                 header={false}
               />
               <UserTable
@@ -343,6 +382,7 @@ export default class extends Page {
                 selectList={contentSelectList}
                 columns={contentColumns}
                 data={item.list}
+                onSelect={l => this.onSelectContent(l)}
                 header={index === 0}
               />
             </div>

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

@@ -1,6 +1,7 @@
 import React from 'react';
 import './index.less';
 import Page from '@src/containers/Page';
+import Assets from '@src/components/Assets';
 import { timeRange, formatPercent, formatSeconds, formatDate, getMap } from '@src/services/Tools';
 import UserLayout from '../../../layouts/User';
 import UserAction from '../../../components/UserAction';
@@ -74,9 +75,11 @@ export default class extends Page {
         render: (text, record) => {
           const { reports } = record;
           return reports.map(report => {
+            const user = formatPercent(report.userCorrect, report.userNumber);
+            const all = formatPercent(record.stat.totalCorrect, record.stat.totalNumber);
             return <div className="sub">
-              <div className="t-2 t-s-12">{formatPercent(report.userCorrect, report.userNumber, false)}</div>
-              <div className="t-6 t-s-12">全站{formatPercent(record.stat.totalCorrect, record.stat.totalNumber, false)}</div>
+              <div className="t-2 t-s-12">{user}%<Assets height={10} width={10} name={user > all ? 'up' : 'down'} /></div>
+              <div className="t-6 t-s-12">全站{all}%</div>
             </div>;
           });
         },
@@ -88,9 +91,11 @@ export default class extends Page {
         render: (text, record) => {
           const { reports } = record;
           return reports.map(report => {
+            const user = report.userTime / report.userNumber;
+            const all = record.stat.totalTime / record.stat.totalNumber;
             return <div className="sub">
-              <div className="t-2 t-s-12">{formatSeconds(report.userTime / report.userNumber)}</div>
-              <div className="t-6 t-s-12">全站{formatSeconds(record.stat.totalTime / record.stat.totalNumber)}</div>
+              <div className="t-2 t-s-12">{formatSeconds(user)}<Assets height={10} width={10} name={user > all ? 'up' : 'down'} /></div>
+              <div className="t-6 t-s-12">全站{formatSeconds(all)}</div>
             </div>;
           });
         },
@@ -350,7 +355,13 @@ export default class extends Page {
   }
 
   onFilter(value) {
-    this.search(value);
+    this.search(value, false);
+    this.initData();
+  }
+
+  onSearch(value) {
+    this.search({ keyword: value }, false);
+    this.initData();
   }
 
   onSort(value) {
@@ -358,11 +369,13 @@ export default class extends Page {
     // this.search({ order: keys.length ? keys.join('|') : null, direction: keys.length ? Object.values(value).join('|') : null });
     const { sortMap } = this.state;
     const index = keys.length > 1 && sortMap[keys[0]] ? 1 : 0;
-    this.search({ order: keys.length ? keys[index] : null, direction: keys.length ? value[keys[index]] : null });
+    this.search({ order: keys.length ? keys[index] : null, direction: keys.length ? value[keys[index]] : null }, false);
+    this.initData();
   }
 
   onChangePage(page) {
-    this.search({ page });
+    this.search({ page }, false);
+    this.initData();
   }
 
   renderView() {
@@ -423,10 +436,12 @@ export default class extends Page {
         />
         <UserAction
           search
+          defaultSearch={filterMap.keyword}
           selectList={selectList}
           filterMap={filterMap}
           onFilter={value => this.onFilter(value)}
           onChange={key => this.onChangeTab(key)}
+          onSearch={value => this.onSearch(value)}
         />
         <UserTable
           columns={columns}

+ 8 - 0
front/project/www/routes/my/tools/index.less

@@ -202,6 +202,14 @@
       }
     }
 
+    .user-action {
+      .email {
+        span {
+          cursor: pointer;
+        }
+      }
+    }
+
     .data-layout {
       margin: 0 -20px;
       text-align: center;

+ 24 - 16
front/project/www/routes/my/tools/page.js

@@ -38,7 +38,17 @@ const dataHistoryColumns = [
 ];
 
 const textbookHistoryColumns = [
-  { title: '更新时间', key: 'createTime', width: 120 },
+  {
+    title: '更新时间',
+    key: 'createTime',
+    width: 120,
+    render: (text) => {
+      return <div className="sub">
+        <div className="t-2 t-s-12">{text.split(' ')[0]}</div>
+        <div className="t-6 t-s-12">{text.split(' ')[1]}</div>
+      </div>;
+    },
+  },
   { title: '版本', key: 'version', width: 120 },
   { title: '更新内容', key: 'content', width: 330 },
 ];
@@ -102,7 +112,7 @@ export default class extends Page {
       result.day = parseInt((new Date().getTime() - new Date(result.latest.startDate).getTime()) / 86400000, 10);
 
       result.expireDay =
-        result.expireTime && parseInt((new Date().getTime() - new Date(result.expireTime).getTime()) / 86400000, 10);
+        result.expireTime && parseInt((new Date(result.expireTime).getTime() - new Date().getTime()) / 86400000, 10);
 
       const list = [];
 
@@ -114,12 +124,13 @@ export default class extends Page {
   }
 
   textbookHistory({ page, size, subject }) {
-    Textbook.listHistory({ subject }).then(result => {
+    Textbook.allHistory(subject).then(result => {
       this.setState({
+        showUpdate: true,
         updateList: result.map(row => {
           row.version = row[`${subject}Version`];
           row.content = row[`${subject}Content`];
-          row.createTime = formatDate(row.createTime, 'YYYY-MM-DD\nHH:mm:ss');
+          row.createTime = formatDate(row.createTime, 'YYYY-MM-DD HH:mm:ss');
           return row;
         }),
         // 不显示分页
@@ -151,7 +162,8 @@ export default class extends Page {
   recordList({ page, size, service, isUse, isExpire }) {
     Order.listRecord({ page, size, productType: 'service', service, isUse, isExpire }).then(result => {
       this.setState({
-        updateList: result.map(row => {
+        showUpdate: true,
+        updateList: result.list.map(row => {
           row.title = ServiceKeyMap[service];
           row.source = RecordSourceMap[row.source];
           row.handler = (
@@ -166,7 +178,7 @@ export default class extends Page {
           row.endTime = `${formatDate(row.endTime, 'YYYY-MM-DD')} 前`;
           return row;
         }),
-        updateTotal: result.length,
+        updateTotal: result.list.length,
         updatePage: page,
         updateData: { page, size, service, isUse, columns: isUse ? [] : openColumns, type: 'record' },
       });
@@ -230,6 +242,7 @@ export default class extends Page {
         return row;
       });
       this.setState({
+        showUpdate: true,
         // 不显示分页
         updateTotal: 0,
         maxHeight: 730,
@@ -588,7 +601,6 @@ export default class extends Page {
                     if (key === 'comment') {
                       this.setState({ showComment: true, comment: { channel: 'course_data', position: item.id } });
                     } else if (key === 'update') {
-                      this.setState({ showUpdate: true });
                       this.dataHistory({ dataId: item.id, page: 1, size: 10 });
                     } else if (key === 'feedback') {
                       this.setState({ showFeedbackError: true, feedbackError: { dataId: item.id, title: item.title, position: ['', '', ''] } });
@@ -624,13 +636,10 @@ export default class extends Page {
           right={
             !data.hasService &&
             data.unUseRecord && (
-              <div
-                className="email"
-                onClick={() => {
+              <div className="email" >
+                <span onClick={() => {
                   this.recordList({ page: 1, size: 10, service: 'textbook', isUse: false, isExpire: false });
-                }}
-              >
-                待开通
+                }} >待开通</span>
               </div>
             )
           }
@@ -656,7 +665,6 @@ export default class extends Page {
                       if (key === 'comment') {
                         this.setState({ showComment: true, comment: { channel: 'library' } });
                       } else if (key === 'update') {
-                        this.setState({ showUpdate: true });
                         this.textbookHistory({ page: 1, size: 100, subject: item.subject });
                       } else if (key === 'feedback') {
                         this.setState({ showFeedback: true, feedback: { questionSubject: item.subject, target: TextbookFeedbackTarget[0].value } });
@@ -677,12 +685,12 @@ export default class extends Page {
             </Button>
           </div>
         )}
-        {data.hasService && (
+        {/* {data.hasService && (
           <div className="tip-layout">
             <div className="t1">使用中</div>
             <div className="t2">距离到期还有 {data.expireDay} 天</div>
           </div>
-        )}
+        )} */}
         {!data.hasService && data.unUseRecord && (
           <div className="tip-layout">
             <div className="t2">请于{formatDate(data.unUseRecord.endTime, 'YYYY-MM-DD')}前开通</div>

+ 7 - 0
front/project/www/stores/main.js

@@ -24,6 +24,13 @@ export default class MainStore extends BaseStore {
   }
 
   /**
+   * 获取优惠信息
+   */
+  getPromote() {
+    return this.apiGet('/base/promote');
+  }
+
+  /**
    * 获取对应位置的提示tips
    * @param {*} position
    */

+ 1 - 1
front/project/www/stores/my.js

@@ -343,7 +343,7 @@ export default class MyStore extends BaseStore {
    * @param {*} content
    */
   addFeedbackErrorData(dataId, title, position, originContent, content) {
-    return this.apiPost('/my/feedback/error/question', { dataId, title, position, originContent, content });
+    return this.apiPost('/my/feedback/error/data', { dataId, title, position, originContent, content });
   }
 
   /**

+ 2 - 2
front/project/www/stores/order.js

@@ -66,8 +66,8 @@ export default class OrderStore extends BaseStore {
    * 开通服务、课程等
    * @param {*} id
    */
-  useRecord(id, isSubscribe) {
-    return this.apiPost('/order/record/use', { id, isSubscribe });
+  useRecord(recordId, isSubscribe) {
+    return this.apiPost('/order/record/use', { recordId, isSubscribe });
   }
 
   openInvoice({ orderId, invoiceType, title, identity }) {

+ 6 - 2
front/project/www/stores/textbook.js

@@ -26,8 +26,12 @@ export default class TextbookStore extends BaseStore {
     return this.apiGet('/textbook/year', { year });
   }
 
-  listHistory(subject) {
-    return this.apiGet('/textbook/history/list', { subject });
+  allHistory(subject) {
+    return this.apiGet('/textbook/history/all', { subject });
+  }
+
+  noTopic(libraryId, subject, no) {
+    return this.apiGet('/textbook/topic/no', { libraryId, subject, no });
   }
 
   listTopic(page, size, latest, qualitys, isOld, order, direction) {

+ 2 - 1
front/src/containers/Page.js

@@ -65,7 +65,7 @@ export default class extends Component {
     this.outPage();
   }
 
-  init() {}
+  init() { }
 
   initState() {
     return {};
@@ -154,6 +154,7 @@ export default class extends Component {
   }
 
   changeQuery(query) {
+    this.setState({ search: query });
     changeParams(`?${querystring.stringify(query)}`);
   }
 

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

@@ -61,7 +61,7 @@
     select id, `position`
     from
     (
-    select c.id, c.`position`, c.`order`,
+    select c.id, c.`position`, c.`sort`,
     (@num:=if(@group = `position`, @num +1, if(@group := `position`, 1, 1))) row_number
     from comment c
     CROSS JOIN (select @num:=0, @group:=null) b
@@ -73,9 +73,9 @@
         #{item}
       </foreach>
     </if>
-    order by c.`position` desc, c.`order` desc
+    order by c.`position` desc, c.`sort` desc
     ) as x
     where x.row_number &lt; #{top,jdbcType=INTEGER}
-    order by x.`order` desc
+    order by x.`sort` desc
   </select>
 </mapper>

+ 1 - 1
server/data/src/main/java/com/qxgmat/data/relation/mapping/CourseDataHistoryRelationMapper.xml

@@ -32,7 +32,7 @@
     and `uor`.`id` > 0
     </if>
     <if test="dataId != null">
-      and `cdh`.dataId = #{dataId,jdbcType=VARCHAR}
+      and `cdh`.`data_id` = #{dataId,jdbcType=VARCHAR}
     </if>
 
   </select>

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

@@ -64,7 +64,7 @@
     select id, `position`
     from
     (
-    select c.id, c.`position`, c.`order`,
+    select c.id, c.`position`, c.`sort`,
     (@num:=if(@group = `position`, @num +1, if(@group := `position`, 1, 1))) row_number
     from faq c
     CROSS JOIN (select @num:=0, @group:=null) b
@@ -76,9 +76,9 @@
         #{item}
       </foreach>
     </if>
-    order by c.`position` desc, c.`order` desc
+    order by c.`position` desc, c.`sort` desc
     ) as x
     where x.row_number &lt; #{top,jdbcType=INTEGER}
-    order by x.`order` desc
+    order by x.`sort` desc
   </select>
 </mapper>

+ 2 - 2
server/data/src/main/resources/db/migration/V1__init_table.sql

@@ -126,7 +126,7 @@ CREATE TABLE course_data_history (
   data_id int(11) unsigned NOT NULL DEFAULT '0' COMMENT '资料id',
   version varchar(255) NOT NULL DEFAULT '' COMMENT '版本名称',
   time datetime DEFAULT NULL COMMENT '更新时间',
-  position varchar(255) NOT NULL DEFAULT '0' COMMENT '更新位置',
+  position varchar(255) NOT NULL DEFAULT '' COMMENT '更新位置',
   origin_content text COMMENT '原文',
   content text COMMENT '更正',
   create_time datetime DEFAULT NULL,
@@ -1396,7 +1396,7 @@ CREATE TABLE user_sentence_record (
 CREATE TABLE user_service (
   id int(11) unsigned NOT NULL AUTO_INCREMENT,
   user_id int(11) unsigned NOT NULL DEFAULT '0' COMMENT '用户id',
-  service varchar(20) NOT NULL DEFAULT '0' COMMENT '服务: vip, ',
+  service varchar(20) NOT NULL DEFAULT '' COMMENT '服务: vip, ',
   is_subscribe tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '机经是否邮箱订阅',
   is_reset tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '模考是否重置',
   start_time datetime DEFAULT NULL,

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

@@ -95,6 +95,14 @@ public class BaseController {
         return ResponseHelp.success(adList);
     }
 
+    @RequestMapping(value = "/promote", method = RequestMethod.GET)
+    @ApiOperation(value = "获取课程促销", httpMethod = "GET")
+    private Response<JSONObject> getPromote(){
+        Setting entity = settingService.getByKey(SettingKey.PROMOTE);
+
+        return ResponseHelp.success(entity.getValue());
+    }
+
     @RequestMapping(value = "/tips", method = RequestMethod.GET)
     @ApiOperation(value = "获取提示信息", notes = "获取提示信息", httpMethod = "GET")
     public Response<Map<String, String>> tips(@RequestParam(required = true) String[] position)  {

+ 9 - 4
server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java

@@ -1247,13 +1247,18 @@ public class MyController {
         Transform.combine(pr, reportByPaper, UserPaperDto.class, "id", "reports", UserReportExtendDto.class);
 
         // 获取试卷统计信息
-        Map<Integer, Integer[]> baseIdsMap = new HashMap<>();
+        Map<Integer, Integer[]> idsMap = new HashMap<>();
         for(UserPaperDto paper : pr){
             if (paper.getQuestionNoIds() == null) continue;
-            baseIdsMap.put(paper.getId(), paper.getQuestionNoIds());
+            idsMap.put(paper.getId(), paper.getQuestionNoIds());
         }
-        Map baseStatMap = questionNoService.statPaperMap(baseIdsMap);
-        Transform.combine(pr, baseStatMap, UserPaperDto.class, "id", "stat");
+        Map statMap = questionNoService.statPaperMap(idsMap);
+        Transform.combine(pr, statMap, UserPaperDto.class, "id", "stat");
+
+        // 获取试卷题型
+        Map questionTypMap = questionNoService.questionTypeMap(idsMap);
+        Transform.combine(pr, questionTypMap, UserPaperDto.class, "id", "questionTypes");
+
 
         return ResponseHelp.success(pr, page, size, p.getTotal());
     }

+ 19 - 0
server/gateway-api/src/main/java/com/qxgmat/controller/api/TextbookController.java

@@ -274,6 +274,25 @@ public class TextbookController
         return ResponseHelp.success(p);
     }
 
+    @RequestMapping(value = "/topic/no", method = RequestMethod.GET)
+    @ApiOperation(value = "获取机经详情", notes = "根据机经序号获取题目", httpMethod = "GET")
+    public Response<TextbookTopic> topic(
+            @RequestParam(required = true) Integer libraryId,
+            @RequestParam(required = true) String subject,
+            @RequestParam(required = true) Integer no
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        if (user == null) {
+            throw new AuthException("请先登录");
+        }
+        if (no == null || no == 0){
+            no = 1;
+        }
+        TextbookTopic textbookTopic = textbookTopicService.getByNo(libraryId, subject, no);
+
+        return ResponseHelp.success(textbookTopic);
+    }
+
     @RequestMapping(value = "/topic/list", method = RequestMethod.GET)
     @ApiOperation(value = "机经列表", httpMethod = "GET")
     public Response<PageMessage<TextbookTopic>> listTopic(

+ 21 - 19
server/gateway-api/src/main/java/com/qxgmat/dto/admin/request/CourseDataHistoryDto.java

@@ -3,22 +3,24 @@ package com.qxgmat.dto.admin.request;
 import com.nuliji.tools.annotation.Dto;
 import com.qxgmat.data.dao.entity.CourseDataHistory;
 
+import java.util.Date;
+
 @Dto(entity = CourseDataHistory.class)
 public class CourseDataHistoryDto {
     private Integer id;
 
     private Integer dataId;
 
-    private String resource;
+    private String position;
 
     private String version;
 
-    private String changePage;
-
     private String originContent;
 
     private String content;
 
+    private Date time;
+
     public Integer getId() {
         return id;
     }
@@ -35,14 +37,6 @@ public class CourseDataHistoryDto {
         this.dataId = dataId;
     }
 
-    public String getResource() {
-        return resource;
-    }
-
-    public void setResource(String resource) {
-        this.resource = resource;
-    }
-
     public String getVersion() {
         return version;
     }
@@ -51,14 +45,6 @@ public class CourseDataHistoryDto {
         this.version = version;
     }
 
-    public String getChangePage() {
-        return changePage;
-    }
-
-    public void setChangePage(String changePage) {
-        this.changePage = changePage;
-    }
-
     public String getOriginContent() {
         return originContent;
     }
@@ -74,4 +60,20 @@ public class CourseDataHistoryDto {
     public void setContent(String content) {
         this.content = content;
     }
+
+    public Date getTime() {
+        return time;
+    }
+
+    public void setTime(Date time) {
+        this.time = time;
+    }
+
+    public String getPosition() {
+        return position;
+    }
+
+    public void setPosition(String position) {
+        this.position = position;
+    }
 }

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

@@ -145,7 +145,7 @@ public class UserCollectQuestionService extends AbstractService {
         }
         int result = insert(userCollectQuestionMapper, entity);
         questionService.accumulationCollect(entity, 1);
-        questionNoService.accumulationCollect(in, 1);
+        questionNoService.accumulationCollect(entity, 1);
         return entity;
     }
 

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

@@ -600,6 +600,7 @@ public class OrderFlowService {
             if (userService == null){
                 userService = UserService.builder()
                         .userId(record.getUserId())
+                        .service(serviceKey.key)
                         .isSubscribe(record.getIsSubscribe())
                         .isReset(0)
                         .startTime(startTime)

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

@@ -138,14 +138,14 @@ public class QuestionFlowService {
         });
         makePaperCallback.put(QuestionModule.SENTENCE, (userPaper, id)->{
             // 获取考题时间
-            List<SentenceQuestionRelation> relationList = sentenceQuestionService.listWithRelationByIds(userPaper.getQuestionNoIds());
+            List<SentenceQuestionRelation> relationList = sentenceQuestionService.relation(sentenceQuestionService.listByQuestionNo(Arrays.stream(userPaper.getQuestionNoIds()).collect(Collectors.toList())));
             Integer time = toolsService.computerTime(relationList.toArray(new SentenceQuestionRelation[0]));
             userPaper.setTime(time);
             return userPaper;
         });
         makePaperCallback.put(QuestionModule.TEXTBOOK, (userPaper, id)->{
             // 获取考题时间
-            List<TextbookQuestionRelation> relationList = textbookQuestionService.listWithRelationByIds(userPaper.getQuestionNoIds());
+            List<TextbookQuestionRelation> relationList = textbookQuestionService.relation(textbookQuestionService.listByQuestionNo(Arrays.stream(userPaper.getQuestionNoIds()).collect(Collectors.toList())));
             Integer time = toolsService.computerTime(relationList.toArray(new TextbookQuestionRelation[0]));
             userPaper.setTime(time);
             return userPaper;
@@ -194,7 +194,7 @@ public class QuestionFlowService {
             userPaper.setQuestionNoIds(paper.getQuestionNoIds());
             userPaper.setQuestionNumber(paper.getQuestionNumber());
             // 获取考题时间
-            List<SentenceQuestionRelation> relationList = sentenceQuestionService.listWithRelationByIds(userPaper.getQuestionNoIds());
+            List<SentenceQuestionRelation> relationList = sentenceQuestionService.relation(sentenceQuestionService.listByQuestionNo(Arrays.stream(userPaper.getQuestionNoIds()).collect(Collectors.toList())));
             Integer time = toolsService.computerTime(relationList.toArray(new SentenceQuestionRelation[0]));
             userPaper.setTime(time);
             return userPaper;
@@ -205,7 +205,7 @@ public class QuestionFlowService {
             userPaper.setQuestionNoIds(paper.getQuestionNoIds());
             userPaper.setQuestionNumber(paper.getQuestionNumber());
             // 获取考题时间
-            List<TextbookQuestionRelation> relationList = textbookQuestionService.listWithRelationByIds(userPaper.getQuestionNoIds());
+            List<TextbookQuestionRelation> relationList = textbookQuestionService.relation(textbookQuestionService.listByQuestionNo(Arrays.stream(userPaper.getQuestionNoIds()).collect(Collectors.toList())));
             Integer time = toolsService.computerTime(relationList.toArray(new TextbookQuestionRelation[0]));
             userPaper.setTime(time);
             return userPaper;
@@ -295,8 +295,8 @@ public class QuestionFlowService {
         nextCallback.put(PaperModule.SENTENCE, (question, report, lastQuestion)->{
             Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
             if (questionNoId == 0) return false;
-            SentenceQuestionRelation relation = sentenceQuestionService.relation(sentenceQuestionService.get(questionNoId));
-            question.setQuestionNoId(relation.getId());
+            SentenceQuestionRelation relation = sentenceQuestionService.relation(sentenceQuestionService.getByQuestionNo(questionNoId));
+            question.setQuestionNoId(relation.getQuestionNoId());
             question.setQuestionId(relation.getQuestionId());
             question.setQuestionType(relation.getQuestion().getQuestionType());
             Integer time = toolsService.computerTime(relation);
@@ -306,8 +306,8 @@ public class QuestionFlowService {
         nextCallback.put(PaperModule.TEXTBOOK, (question, report, lastQuestion)->{
             Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
             if (questionNoId == 0) return false;
-            TextbookQuestionRelation relation = textbookQuestionService.relation(textbookQuestionService.get(questionNoId));
-            question.setQuestionNoId(relation.getId());
+            TextbookQuestionRelation relation = textbookQuestionService.relation(textbookQuestionService.getByQuestionNo(questionNoId));
+            question.setQuestionNoId(relation.getQuestionNoId());
             question.setQuestionId(relation.getQuestionId());
             question.setQuestionType(relation.getQuestion().getQuestionType());
             Integer time = toolsService.computerTime(relation);
@@ -1411,7 +1411,11 @@ public class QuestionFlowService {
     private JSONObject statTextbookReport(UserReport report, List<UserQuestion> questionList){
         UserPaper paper = userPaperService.get(report.getPaperId());
         Collection questionNoIds = Transform.getIds(questionList, UserQuestion.class, "questionNoId");
-        Map<Number, TextbookQuestionRelation> relationMap = textbookQuestionService.mapWithRelationByIds((Integer[])questionNoIds.toArray());
+        List<TextbookQuestionRelation> relationList = textbookQuestionService.relation(textbookQuestionService.listByQuestionNo(questionNoIds));
+        Map<Number, TextbookQuestionRelation> relationMap = new HashMap<>();
+        for(TextbookQuestionRelation relation : relationList){
+            relationMap.put(relation.getQuestionNoId(), relation);
+        }
 
         // report
         JSONObject detail = new JSONObject();
@@ -1500,7 +1504,11 @@ public class QuestionFlowService {
     private JSONObject statSentenceReport(UserReport report, List<UserQuestion> questionList){
         UserPaper paper = userPaperService.get(report.getPaperId());
         Collection questionNoIds = Transform.getIds(questionList, UserQuestion.class, "questionNoId");
-        Map<Number, SentenceQuestionRelation> relationMap = sentenceQuestionService.mapWithRelationByIds(questionNoIds.toArray());
+        List<SentenceQuestionRelation> relationList = sentenceQuestionService.relation(sentenceQuestionService.listByQuestionNo(questionNoIds));
+        Map<Number, SentenceQuestionRelation> relationMap = new HashMap<>();
+        for(SentenceQuestionRelation relation : relationList){
+            relationMap.put(relation.getQuestionNoId(), relation);
+        }
 
         // report
         JSONObject detail = new JSONObject();

+ 5 - 5
server/gateway-api/src/main/java/com/qxgmat/service/extend/ToolsService.java

@@ -400,7 +400,7 @@ public class ToolsService {
         for(int i = 0; i < settings.size(); i++){
             JSONObject o = settings.getJSONObject(i);
             int number = o.getIntValue("number");
-            if(number < list.size()){
+            if(number <= list.size()){
                 if (number > max){
                     max = number;
                     maxIndex = i;
@@ -430,7 +430,7 @@ public class ToolsService {
         for(int i = 0; i < settings.size(); i++){
             JSONObject o = settings.getJSONObject(i);
             int number = o.getIntValue("number");
-            if(number < checkout.getNumber()){
+            if(number <= checkout.getNumber()){
                 if (number > max){
                     max = number;
                     maxIndex = i;
@@ -481,7 +481,7 @@ public class ToolsService {
         for(int i = 0; i < settings.size(); i++){
             JSONObject o = settings.getJSONObject(i);
             int money = o.getIntValue("money");
-            if(money < totalMoney.intValue()){
+            if(money <= totalMoney.intValue()){
                 if (money > max){
                     max = money;
                     maxIndex = i;
@@ -510,7 +510,7 @@ public class ToolsService {
         for(int i = 0; i < settings.size(); i++){
             JSONObject o = settings.getJSONObject(i);
             int money = o.getIntValue("money");
-            if(money < totalMoney.intValue()){
+            if(money <= totalMoney.intValue()){
                 if (money > max){
                     max = money;
                     maxIndex = i;
@@ -539,7 +539,7 @@ public class ToolsService {
         for(int i = 0; i < settings.size(); i++){
             JSONObject o = settings.getJSONObject(i);
             int number = o.getIntValue("number");
-            if(number < vsNumber){
+            if(number <= vsNumber){
                 if (number > max){
                     max = number;
                     maxIndex = i;

+ 29 - 0
server/gateway-api/src/main/java/com/qxgmat/service/inline/QuestionNoService.java

@@ -427,6 +427,35 @@ public class QuestionNoService extends AbstractService {
         return relationMap;
     }
 
+    /**
+     * 根据试卷分组获取统计信息
+     * @param questionNoIdsMap
+     * @return
+     */
+    public Map<Integer, List<String>> questionTypeMap(Map<Integer, Integer[]> questionNoIdsMap){
+        Map<Integer, List<String>> relationMap = new HashMap<>();
+        List<Integer> ids = new ArrayList<>();
+        for(Integer[] questionNoIds : questionNoIdsMap.values()){
+            ids.addAll(Arrays.stream(questionNoIds).collect(Collectors.toList()));
+        }
+        List<QuestionNo> questionNoList = select(ids);
+        List<QuestionNoRelation> relationList = relation(questionNoList);
+        Map questionNoMap = Transform.getMap(relationList, QuestionNoRelation.class, "id");
+
+        for(Integer k: questionNoIdsMap.keySet()){
+            List<String> l = new ArrayList<>();
+            for (Integer questionNoId : questionNoIdsMap.get(k)){
+                QuestionNoRelation relation = (QuestionNoRelation)questionNoMap.get(questionNoId);
+                if (!l.contains(relation.getQuestion().getQuestionType())){
+                    l.add(relation.getQuestion().getQuestionType());
+                }
+            }
+            relationMap.put(k, l);
+        }
+
+        return relationMap;
+    }
+
     public List<QuestionNoRelation> relation(List<QuestionNo> p){
         List<QuestionNoRelation> relationList = Transform.convert(p, QuestionNoRelation.class);
 

+ 24 - 24
server/gateway-api/src/main/java/com/qxgmat/service/inline/SentenceQuestionService.java

@@ -64,30 +64,30 @@ public class SentenceQuestionService extends AbstractService {
         return page(() -> select(sentenceQuestionMapper, example), page, size);
     }
 
-    /**
-     * 根据题目编号id列表获取关联题目
-     * @param ids
-     * @return
-     */
-    public List<SentenceQuestionRelation> listWithRelationByIds(Number[] ids){
-        List<SentenceQuestion> p = select(sentenceQuestionMapper, ids);
-        return relation(p);
-    }
-
-    /**
-     * 根据题目编号id列表获取关联题目
-     * @param ids
-     * @return
-     */
-    public Map<Number, SentenceQuestionRelation> mapWithRelationByIds(Object[] ids){
-        List<SentenceQuestion> p = select(sentenceQuestionMapper, ids);
-        List<SentenceQuestionRelation> list = relation(p);
-        Map<Number, SentenceQuestionRelation> map = new HashMap<>();
-        for(SentenceQuestionRelation relation : list){
-            map.put(relation.getId(), relation);
-        }
-        return map;
-    }
+//    /**
+//     * 根据题目编号id列表获取关联题目
+//     * @param ids
+//     * @return
+//     */
+//    public List<SentenceQuestionRelation> listWithRelationByIds(Number[] ids){
+//        List<SentenceQuestion> p = select(sentenceQuestionMapper, ids);
+//        return relation(p);
+//    }
+//
+//    /**
+//     * 根据题目编号id列表获取关联题目
+//     * @param ids
+//     * @return
+//     */
+//    public Map<Number, SentenceQuestionRelation> mapWithRelationByIds(Object[] ids){
+//        List<SentenceQuestion> p = select(sentenceQuestionMapper, ids);
+//        List<SentenceQuestionRelation> list = relation(p);
+//        Map<Number, SentenceQuestionRelation> map = new HashMap<>();
+//        for(SentenceQuestionRelation relation : list){
+//            map.put(relation.getId(), relation);
+//        }
+//        return map;
+//    }
 //
 //    /**
 //     * 累加做题记录到sentenceQuestion

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

@@ -189,30 +189,30 @@ public class TextbookQuestionService extends AbstractService {
         return new PageResult<>(relation(p), p.getTotal());
     }
 
-    /**
-     * 根据题目编号id列表获取关联题目
-     * @param ids
-     * @return
-     */
-    public List<TextbookQuestionRelation> listWithRelationByIds(Number[] ids){
-        List<TextbookQuestion> p = select(textbookQuestionMapper, ids);
-        return relation(p);
-    }
-
-    /**
-     * 根据题目编号id列表获取关联题目
-     * @param ids
-     * @return
-     */
-    public Map<Number, TextbookQuestionRelation> mapWithRelationByIds(Number[] ids){
-        List<TextbookQuestion> p = select(textbookQuestionMapper, ids);
-        List<TextbookQuestionRelation> list = relation(p);
-        Map<Number, TextbookQuestionRelation> map = new HashMap<>();
-        for(TextbookQuestionRelation relation : list){
-            map.put(relation.getId(), relation);
-        }
-        return map;
-    }
+//    /**
+//     * 根据题目编号id列表获取关联题目
+//     * @param ids
+//     * @return
+//     */
+//    public List<TextbookQuestionRelation> listWithRelationByIds(Number[] ids){
+//        List<TextbookQuestion> p = select(textbookQuestionMapper, ids);
+//        return relation(p);
+//    }
+//
+//    /**
+//     * 根据题目编号id列表获取关联题目
+//     * @param ids
+//     * @return
+//     */
+//    public Map<Number, TextbookQuestionRelation> mapWithRelationByIds(Number[] ids){
+//        List<TextbookQuestion> p = select(textbookQuestionMapper, ids);
+//        List<TextbookQuestionRelation> list = relation(p);
+//        Map<Number, TextbookQuestionRelation> map = new HashMap<>();
+//        for(TextbookQuestionRelation relation : list){
+//            map.put(relation.getId(), relation);
+//        }
+//        return map;
+//    }
 //
 //    /**
 //     * 累加做题记录到sentenceQuestion

+ 1 - 1
server/gateway-api/src/main/profile/dev/application-runtime.yml

@@ -90,7 +90,7 @@ upload:
 third:
   wechat:
     pc:
-      appId: wx324965bb6800f9b9
+      appId: wxa6a1620243459e6a
       appSecret: 51b8bf5029502d8eccb7a658529b1372
 
     native:

+ 1 - 1
server/gateway-api/src/main/profile/test/application-runtime.yml

@@ -90,7 +90,7 @@ upload:
 third:
   wechat:
     pc:
-      appId: wx324965bb6800f9b9
+      appId: wxa6a1620243459e6a
       appSecret: 51b8bf5029502d8eccb7a658529b1372
 
     native: