Browse Source

Merge branch 'master' of https://git.proginn.com/zaixianjiaoyu/sourcecode

KaysonCui 5 years ago
parent
commit
65577429e2
39 changed files with 728 additions and 131 deletions
  1. 273 1
      front/project/admin/routes/subject/exercise/page.js
  2. 1 1
      front/project/admin/routes/subject/question/index.js
  3. 17 4
      front/project/admin/routes/system/manager/list/page.js
  4. 12 0
      front/project/admin/stores/exercise.js
  5. 2 1
      front/project/admin/stores/index.js
  6. 12 0
      front/project/admin/stores/question.js
  7. 8 0
      front/project/admin/stores/sentence.js
  8. 21 0
      front/project/admin/stores/slient.js
  9. 38 4
      front/src/layouts/FilterLayout/index.js
  10. 1 1
      server/build.gradle
  11. 1 0
      server/data/src/main/java/com/qxgmat/data/constants/enums/SettingKey.java
  12. 36 1
      server/data/src/main/java/com/qxgmat/data/dao/entity/ExercisePaperQuestion.java
  13. 105 0
      server/data/src/main/java/com/qxgmat/data/dao/entity/SentencePaper.java
  14. 1 1
      server/data/src/main/java/com/qxgmat/data/dao/entity/UserCollectQuestion.java
  15. 0 10
      server/data/src/main/java/com/qxgmat/data/dao/mapping/ExaminationMapper.xml
  16. 0 10
      server/data/src/main/java/com/qxgmat/data/dao/mapping/ExerciseMapper.xml
  17. 2 1
      server/data/src/main/java/com/qxgmat/data/dao/mapping/ExercisePaperQuestionMapper.xml
  18. 4 1
      server/data/src/main/java/com/qxgmat/data/dao/mapping/SentencePaperMapper.xml
  19. 14 15
      server/data/src/main/java/com/qxgmat/data/relation/mapping/ExerciseQuestionRelationMapper.xml
  20. 4 4
      server/data/src/main/java/com/qxgmat/data/relation/mapping/QuestionNoRelationMapper.xml
  21. 3 3
      server/data/src/main/java/com/qxgmat/data/relation/mapping/QuestionRelationMapper.xml
  22. 6 6
      server/data/src/main/java/com/qxgmat/data/relation/mapping/UserAskRelationMapper.xml
  23. 7 7
      server/data/src/main/java/com/qxgmat/data/relation/mapping/UserCollectQuestionRelationMapper.xml
  24. 11 12
      server/data/src/main/java/com/qxgmat/data/relation/mapping/UserPaperRelationMapper.xml
  25. 5 5
      server/data/src/main/java/com/qxgmat/data/relation/mapping/UserReportRelationMapper.xml
  26. 1 1
      server/data/src/main/resources/application-data.yml
  27. 4 0
      server/data/src/main/resources/mybatis-generator.xml
  28. 13 2
      server/gateway-api/src/main/java/com/qxgmat/controller/admin/ExerciseController.java
  29. 11 0
      server/gateway-api/src/main/java/com/qxgmat/controller/admin/QuestionController.java
  30. 38 4
      server/gateway-api/src/main/java/com/qxgmat/controller/admin/SentenceController.java
  31. 18 18
      server/gateway-api/src/main/java/com/qxgmat/controller/admin/SettingController.java
  32. 8 8
      server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java
  33. 2 2
      server/gateway-api/src/main/java/com/qxgmat/controller/api/QuestionController.java
  34. 2 2
      server/gateway-api/src/main/java/com/qxgmat/controller/api/SentenceController.java
  35. 13 2
      server/gateway-api/src/main/java/com/qxgmat/service/ExercisePaperService.java
  36. 19 1
      server/gateway-api/src/main/java/com/qxgmat/service/inline/ExerciseQuestionService.java
  37. 3 0
      server/gateway-api/src/main/java/com/qxgmat/service/inline/StatDayService.java
  38. 10 2
      server/gateway-api/src/main/java/com/qxgmat/task/AsyncTask.java
  39. 2 1
      server/gateway-api/src/main/java/com/qxgmat/task/ScheduledTask.java

+ 273 - 1
front/project/admin/routes/subject/exercise/page.js

@@ -1,10 +1,282 @@
 import React from 'react';
+import { Button } from 'antd';
+import { Link } from 'react-router-dom';
 import './index.less';
 import Page from '@src/containers/Page';
 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 { QuestionType, QuestionDifficult } from '@src/services/Constant';
+import { getMap, formatTreeData, bindSearch, formatDate } from '@src/services/Tools';
+import { asyncSMessage, asyncDelConfirm } from '@src/services/AsyncTools';
+import { Exercise } from '../../../stores/exercise';
+import { System } from '../../../stores/system';
+import { Question } from '../../../stores/question';
+import { Slient } from '../../../stores/slient';
 
+const QuestionTypeMap = getMap(QuestionType, 'value', 'label');
+
+const filterForm = [
+  {
+    key: 'type',
+    type: 'select',
+    allowClear: true,
+    name: '题型',
+    select: QuestionType,
+    placeholder: '请选择',
+    number: true,
+  },
+  {
+    key: 'struct_id',
+    type: 'tree',
+    allowClear: true,
+    name: '分册',
+    select: [],
+    placeholder: '请选择',
+    number: true,
+  },
+  {
+    key: 'paper_id',
+    type: 'select',
+    allowClear: true,
+    name: '练习册',
+    select: [],
+    placeholder: '请选择',
+    number: true,
+  },
+  {
+    key: 'place',
+    type: 'select',
+    allowClear: true,
+    name: '考点',
+    select: [],
+    placeholder: '请选择',
+    number: true,
+  },
+  {
+    key: 'difficult',
+    type: 'select',
+    allowClear: true,
+    name: '难度',
+    select: QuestionDifficult,
+    placeholder: '请选择',
+    number: true,
+  },
+  {
+    key: 'time',
+    type: 'daterange',
+    name: '修改时间',
+  },
+  {
+    key: 'question_no_id',
+    type: 'select',
+    name: '题目ID',
+    select: [],
+    number: true,
+    placeholder: '请输入',
+  },
+];
 export default class extends Page {
+  constructor(props) {
+    super(props);
+    this.actionList = [{
+      key: 'add',
+      name: '新建',
+      render: (item) => {
+        return <Button onClick={() => {
+          linkTo('/subject/question');
+        }}>{item.name}</Button>;
+      },
+    }, {
+      key: 'auto',
+      name: '重新组卷',
+    }, {
+      key: 'delete',
+      name: '批量删除',
+      needSelect: 1,
+    }];
+    this.categoryMap = {};
+    this.columns = [{
+      title: '学科',
+      dataIndex: 'first',
+      render: (text, record) => {
+        return this.categoryMap[record.questionNo.moduleStruct[0]] || text;
+      },
+    }, {
+      title: '题型',
+      dataIndex: 'type',
+      render: (text, record) => {
+        return QuestionTypeMap[record.question.type] || text;
+      },
+    }, {
+      title: '练习册',
+      dataIndex: 'paper',
+      render: (text) => {
+        return text.title;
+      },
+    }, {
+      title: '考点',
+      dataIndex: 'place',
+      render: (text, record) => {
+        return record.question.place;
+      },
+    }, {
+      title: '难度',
+      dataIndex: 'difficlut',
+      render: (text, record) => {
+        return record.question.difficult;
+      },
+    }, {
+      title: '易错度',
+      dataIndex: 'correct',
+      render: (text, record) => {
+        return `${record.questionNo.totalCorrect * 100 / record.questionNo.totalNumber}%`;
+      },
+    }, {
+      title: '平均时间',
+      dataIndex: 'time',
+      render: (text, record) => {
+        return `${record.questionNo.totalTime / record.questionNo.totalNumber}s`;
+      },
+    }, {
+      title: '序号',
+      dataIndex: 'no',
+      render: (text, record) => {
+        const { search } = this.state;
+        if (search.paper_id) {
+          return record.paper.no;
+        }
+        return '--';
+      },
+    }, {
+      title: '修改时间',
+      dataIndex: 'updateTime',
+      render: (text, record) => {
+        return formatDate(record.question.updateTime);
+      },
+    }, {
+      title: '操作',
+      dataIndex: 'handler',
+      render: (text, record) => {
+        return <div className="table-button">
+          {(
+            <Link to={`/subject/question/${record.question_id}`}>编辑</Link>
+          )}
+        </div>;
+      },
+    }];
+  }
+
+  initAuto() {
+    this.outPage();
+    this.interval = setInterval(() => {
+      Slient.exerciseAuto().then((result) => {
+        if (result.process == null || result.process === 100) {
+          this.actionList[1].disabled = false;
+          result.process = 100;
+        } else {
+          this.actionList[1].disabled = true;
+        }
+        this.setState({ process: result.process });
+      });
+    }, 30000);
+  }
+
+  outPage() {
+    if (this.interval) {
+      clearInterval(this.interval);
+    }
+  }
+
+  init() {
+    Exercise.allStruct().then(result => {
+      const list = result.filter(row => row.level > 2).map(row => { row.title = `${row.titleZh}/${row.titleEn}`; row.value = row.id; return row; });
+      filterForm[1].tree = formatTreeData(list, 'id', 'title', 'parentId');
+      this.categoryMap = getMap(result.map(row => { row.title = `${row.titleZh}/${row.titleEn}`; row.value = row.id; return row; }), 'id', 'title');
+      this.setState({ exercise: result });
+    });
+    System.getPlace().then(result => {
+      filterForm[3].select = [].concat(...Object.keys(result).map(key => result[key]));
+      this.setState({ place: result });
+    });
+    bindSearch(filterForm, 'paper_id', this, (search) => {
+      return Exercise.listPaper(search);
+    }, (row) => {
+      return {
+        title: row.title,
+        value: row.id,
+      };
+    }, [], null);
+    bindSearch(filterForm, 'question_no_id', this, (search) => {
+      return Question.searchNo(search);
+    }, (row) => {
+      return {
+        title: row.no,
+        value: row.id,
+      };
+    }, [], null);
+    this.initAuto();
+  }
+
+  initData() {
+    const { search } = this.state;
+    const data = Object.assign({}, search);
+    if (data.time) {
+      data.startTime = data.time[0] || '';
+      data.endTime = data.time[1] || '';
+    }
+    Exercise.listQuestion(data).then(result => {
+      this.setTableData(result.list, result.total);
+    });
+  }
+
+  autoAction() {
+    asyncDelConfirm('组卷确认', '是否重新组卷?', () => {
+      return Exercise.auto();
+    }).then(() => {
+      asyncSMessage('开始组卷!');
+      this.refresh();
+    });
+  }
+
+  deleteAction() {
+    const { selectedRows } = this.state;
+    asyncDelConfirm('删除确认', '是否删除选中题目?', () => {
+      return Promise.all(selectedRows.map(row => Question.del({ id: row.question_id })));
+    }).then(() => {
+      asyncSMessage('删除成功!');
+      this.refresh();
+    });
+  }
+
   renderView() {
-    return <Block flex />;
+    return <Block flex>
+      <FilterLayout
+        show
+        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
+        itemList={this.actionList}
+        selectedKeys={this.state.selectedKeys}
+        onAction={key => this.onAction(key)}
+      />
+      <TableLayout
+        select
+        columns={this.columns}
+        list={this.state.list}
+        pagination={this.state.page}
+        loading={this.props.core.loading}
+        onChange={(pagination, filters, sorter) => this.tableChange(pagination, filters, sorter)}
+        onSelect={(keys, rows) => this.tableSelect(keys, rows)}
+        selectedKeys={this.state.selectedKeys}
+      />
+    </Block>;
   }
 }

+ 1 - 1
front/project/admin/routes/subject/question/index.js

@@ -2,7 +2,7 @@ import module from '../../module';
 import group from '../group';
 
 export default {
-  path: '/subject/question',
+  path: '/subject/question/:id',
   key: 'subject-question',
   title: '题目录入',
   needLogin: true,

+ 17 - 4
front/project/admin/routes/system/manager/list/page.js

@@ -1,4 +1,5 @@
 import React from 'react';
+import { Button } from 'antd';
 import './index.less';
 import Page from '@src/containers/Page';
 import TableLayout from '@src/layouts/TableLayout';
@@ -42,6 +43,19 @@ export default class extends Page {
         title: '用户名',
         dataIndex: 'username',
       },
+      {
+        title: '操作',
+        dataIndex: 'handler',
+        render: (text, record) => {
+          return <div className="table-button">
+            {(
+              <Button type='link' onClick={() => {
+                this.editAction(record);
+              }} >编辑</Button>
+            )}
+          </div>;
+        },
+      },
     ];
   }
 
@@ -60,9 +74,8 @@ export default class extends Page {
     });
   }
 
-  editAction() {
-    const { selectedRows } = this.state;
-    asyncForm('编辑', itemList, selectedRows[0], data => {
+  editAction(row) {
+    asyncForm('编辑', itemList, row, data => {
       return System.putManager(data).then(() => {
         asyncSMessage('编辑成功!');
         this.refresh();
@@ -89,7 +102,7 @@ export default class extends Page {
           onAction={key => this.onAction(key)}
         />
         <TableLayout
-          select
+          // select
           columns={this.columns}
           list={this.state.list}
           pagination={this.state.page}

+ 12 - 0
front/project/admin/stores/exercise.js

@@ -16,6 +16,18 @@ export default class ExerciseStore extends BaseStore {
   delStruct(params) {
     return this.apiDel('/exercise/struct/delete', params);
   }
+
+  listPaper(params) {
+    return this.apiGet('/exercise/paper/list', params);
+  }
+
+  listQuestion(params) {
+    return this.apiGet('/exercise/question/list', params);
+  }
+
+  auto() {
+    return this.apiPost('/exercise/paper/auto');
+  }
 }
 
 export const Exercise = new ExerciseStore({ key: 'exercise' });

+ 2 - 1
front/project/admin/stores/index.js

@@ -5,5 +5,6 @@ import { Preview } from './preview';
 import { User } from './user';
 import { Sentence } from './sentence';
 import { Question } from './question';
+import { Slient } from './slient';
 
-export default [System, Examination, Exercise, Preview, User, Sentence, Question];
+export default [System, Examination, Exercise, Preview, User, Sentence, Question, Slient];

+ 12 - 0
front/project/admin/stores/question.js

@@ -12,6 +12,18 @@ export default class QuestionStore extends BaseStore {
   listNo(params) {
     return this.apiPost('/question/list/no', params);
   }
+
+  add(params) {
+    return this.apiPost('/question/add', params);
+  }
+
+  edit(params) {
+    return this.apiPut('/question/edit', params);
+  }
+
+  del(params) {
+    return this.apiDel('/question/delete', params);
+  }
 }
 
 export const Question = new QuestionStore({ key: 'question' });

+ 8 - 0
front/project/admin/stores/sentence.js

@@ -48,6 +48,14 @@ export default class SentenceStore extends BaseStore {
   delQuestion(params) {
     return this.apiDel('/sentence/question/delete', params);
   }
+
+  auto() {
+    return this.apiPost('/sentence/paper/auto');
+  }
+
+  autoStatus() {
+    return this.apiGet('/sentence/paper/auto');
+  }
 }
 
 export const Sentence = new SentenceStore({ key: 'sentence' });

+ 21 - 0
front/project/admin/stores/slient.js

@@ -0,0 +1,21 @@
+import BaseStore from '@src/stores/base';
+
+export default class SlientStore extends BaseStore {
+  exerciseAuto() {
+    return this.apiGet('/exercise/paper/auto');
+  }
+
+  sentenceAuto() {
+    return this.apiGet('/sentence/paper/auto');
+  }
+
+  requestBeforeHook() {
+    // this.loading();
+  }
+
+  requestAfterHook() {
+    // this.loaded();
+  }
+}
+
+export const Slient = new SlientStore({ key: 'slient' });

+ 38 - 4
front/src/layouts/FilterLayout/index.js

@@ -4,6 +4,7 @@ import { Form, Button, Switch, DatePicker, Input, InputNumber, Cascader } from '
 import Select from '../../components/Select';
 import Radio from '../../components/Radio';
 import Multiple from '../../components/Multiple';
+import TreeSelect from '../../components/TreeSelect';
 import './index.less';
 
 class FilterLayout extends Component {
@@ -15,13 +16,33 @@ class FilterLayout extends Component {
     const data = {};
     const { itemList = [] } = this.props;
     itemList.forEach(item => {
-      data[item.key] = '';
+      if (item.type === 'daterange') {
+        data[item.key] = [];
+        this.props.form.setFieldsValue({ [item.key]: [] });
+      } else {
+        data[item.key] = '';
+      }
     });
     if (this.props.onChange) this.props.onChange(data);
   }
 
   getFilterItem(item) {
     switch (item.type) {
+      case 'tree':
+        return (
+          <TreeSelect
+            {...item}
+            className={item.class}
+            disabled={!!item.disabled}
+            placeholder={item.placeholder}
+            isNode={item.isNode}
+            treeDefaultExpandAll
+            treeData={item.tree}
+            loadData={item.loadData}
+            initData={item.initData}
+            ignore={item.ignore}
+          />
+        );
       case 'radio':
         return <Radio className={item.class} select={item.select} />;
       case 'select':
@@ -29,6 +50,7 @@ class FilterLayout extends Component {
       case 'multiple':
         return (
           <Multiple
+            {...item}
             className={item.class}
             select={item.select}
             placeholder={item.placeholder}
@@ -36,14 +58,15 @@ class FilterLayout extends Component {
           />
         );
       case 'cascader':
-        return <Cascader className={item.class} options={item.select} placeholder={item.placeholder} />;
+        return <Cascader {...item} className={item.class} options={item.select} placeholder={item.placeholder} />;
       case 'textarea':
         return (
-          <Input.TextArea autosize className={item.class} placeholder={item.placeholder} disabled={!!item.disabled} />
+          <Input.TextArea {...item} autosize className={item.class} placeholder={item.placeholder} disabled={!!item.disabled} />
         );
       case 'input':
         return (
           <Input
+            {...item}
             className={item.class}
             placeholder={item.placeholder}
             readOnly={!!item.readOnly}
@@ -53,6 +76,7 @@ class FilterLayout extends Component {
       case 'number':
         return (
           <InputNumber
+            {...item}
             className={item.class}
             placeholder={item.placeholder}
             readOnly={!!item.readOnly}
@@ -62,7 +86,9 @@ class FilterLayout extends Component {
       case 'switch':
         return <Switch className={item.class} />;
       case 'date':
-        return <DatePicker className={item.class} placeholder={item.placeholder} allowClear={false} />;
+        return <DatePicker {...item} className={item.class} placeholder={item.placeholder} />;
+      case 'daterange':
+        return <DatePicker.RangePicker {...item} className={item.class} />;
       default:
         return <div />;
     }
@@ -72,6 +98,8 @@ class FilterLayout extends Component {
     switch (item.type) {
       case 'date':
         return moment(data[item.key]);
+      case 'daterange':
+        return [moment(data[item.key][0]), moment(data[item.key][1])];
       default:
         return data[item.key];
     }
@@ -96,6 +124,12 @@ class FilterLayout extends Component {
                 } else {
                   option.initialValue = moment(option.initialValue);
                 }
+              } else if (item.type === 'daterange') {
+                if (option.initialValue.length > 0) {
+                  option.initialValue = [moment(option.initialValue[0]), moment(option.initialValue[1])];
+                } else {
+                  option.initialValue = [];
+                }
               }
             }
             if (item.type === 'hidden') {

+ 1 - 1
server/build.gradle

@@ -67,7 +67,7 @@ subprojects {
     sourceSets {
         main {
             resources {
-                srcDirs = ["src/main/resources", "src/main/profile/$env"]
+                srcDirs = ["src/main/resources", "src/main/profile/$env", "src/main/java"]
             }
         }
     }

+ 1 - 0
server/data/src/main/java/com/qxgmat/data/constants/enums/SettingKey.java

@@ -6,6 +6,7 @@ package com.qxgmat.data.constants.enums;
 public enum SettingKey {
     INDEX("index"), // 首页设置
     SENTENCE("sentence"), // 长难句目录
+    SENTENCE_PAPER_STATUS("sentence_paper_status"), // 长难句自动组卷状态:process进度,finish时间
     PLACE("place"), // 难点设置
     EXERCISE_TIME("exercise_time"), // 练习题目时间
     EXAMINATION_TIME("examination_time"), // 考试时间

+ 36 - 1
server/data/src/main/java/com/qxgmat/data/dao/entity/ExercisePaperQuestion.java

@@ -3,7 +3,7 @@ package com.qxgmat.data.dao.entity;
 import java.io.Serializable;
 import javax.persistence.*;
 
-@Table(name = "exercise_question")
+@Table(name = "exercise_paper_question")
 public class ExercisePaperQuestion implements Serializable {
     @Id
     @Column(name = "`id`")
@@ -28,6 +28,12 @@ public class ExercisePaperQuestion implements Serializable {
     @Column(name = "`question_no_id`")
     private Integer questionNoId;
 
+    /**
+     * 序号
+     */
+    @Column(name = "`no`")
+    private Integer no;
+
     private static final long serialVersionUID = 1L;
 
     /**
@@ -98,6 +104,24 @@ public class ExercisePaperQuestion implements Serializable {
         this.questionNoId = questionNoId;
     }
 
+    /**
+     * 获取序号
+     *
+     * @return no - 序号
+     */
+    public Integer getNo() {
+        return no;
+    }
+
+    /**
+     * 设置序号
+     *
+     * @param no 序号
+     */
+    public void setNo(Integer no) {
+        this.no = no;
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
@@ -108,6 +132,7 @@ public class ExercisePaperQuestion implements Serializable {
         sb.append(", paperId=").append(paperId);
         sb.append(", questionId=").append(questionId);
         sb.append(", questionNoId=").append(questionNoId);
+        sb.append(", no=").append(no);
         sb.append("]");
         return sb.toString();
     }
@@ -161,6 +186,16 @@ public class ExercisePaperQuestion implements Serializable {
             return this;
         }
 
+        /**
+         * 设置序号
+         *
+         * @param no 序号
+         */
+        public Builder no(Integer no) {
+            obj.setNo(no);
+            return this;
+        }
+
         public ExercisePaperQuestion build() {
             return this.obj;
         }

+ 105 - 0
server/data/src/main/java/com/qxgmat/data/dao/entity/SentencePaper.java

@@ -16,6 +16,24 @@ public class SentencePaper implements Serializable {
     @Column(name = "`title`")
     private String title;
 
+    /**
+     * 题目数量
+     */
+    @Column(name = "`question_number`")
+    private Integer questionNumber;
+
+    /**
+     * 题目编号ids:json
+     */
+    @Column(name = "`question_no_ids`")
+    private Integer[] questionNoIds;
+
+    /**
+     * 开放状态:0关闭,1开启
+     */
+    @Column(name = "`status`")
+    private Integer status;
+
     private static final long serialVersionUID = 1L;
 
     /**
@@ -50,6 +68,60 @@ public class SentencePaper implements Serializable {
         this.title = title;
     }
 
+    /**
+     * 获取题目数量
+     *
+     * @return question_number - 题目数量
+     */
+    public Integer getQuestionNumber() {
+        return questionNumber;
+    }
+
+    /**
+     * 设置题目数量
+     *
+     * @param questionNumber 题目数量
+     */
+    public void setQuestionNumber(Integer questionNumber) {
+        this.questionNumber = questionNumber;
+    }
+
+    /**
+     * 获取题目编号ids:json
+     *
+     * @return question_no_ids - 题目编号ids:json
+     */
+    public Integer[] getQuestionNoIds() {
+        return questionNoIds;
+    }
+
+    /**
+     * 设置题目编号ids:json
+     *
+     * @param questionNoIds 题目编号ids:json
+     */
+    public void setQuestionNoIds(Integer[] questionNoIds) {
+        this.questionNoIds = questionNoIds;
+    }
+
+    /**
+     * 获取开放状态:0关闭,1开启
+     *
+     * @return status - 开放状态:0关闭,1开启
+     */
+    public Integer getStatus() {
+        return status;
+    }
+
+    /**
+     * 设置开放状态:0关闭,1开启
+     *
+     * @param status 开放状态:0关闭,1开启
+     */
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
@@ -58,6 +130,9 @@ public class SentencePaper implements Serializable {
         sb.append("Hash = ").append(hashCode());
         sb.append(", id=").append(id);
         sb.append(", title=").append(title);
+        sb.append(", questionNumber=").append(questionNumber);
+        sb.append(", questionNoIds=").append(questionNoIds);
+        sb.append(", status=").append(status);
         sb.append("]");
         return sb.toString();
     }
@@ -91,6 +166,36 @@ public class SentencePaper implements Serializable {
             return this;
         }
 
+        /**
+         * 设置题目数量
+         *
+         * @param questionNumber 题目数量
+         */
+        public Builder questionNumber(Integer questionNumber) {
+            obj.setQuestionNumber(questionNumber);
+            return this;
+        }
+
+        /**
+         * 设置题目编号ids:json
+         *
+         * @param questionNoIds 题目编号ids:json
+         */
+        public Builder questionNoIds(Integer[] questionNoIds) {
+            obj.setQuestionNoIds(questionNoIds);
+            return this;
+        }
+
+        /**
+         * 设置开放状态:0关闭,1开启
+         *
+         * @param status 开放状态:0关闭,1开启
+         */
+        public Builder status(Integer status) {
+            obj.setStatus(status);
+            return this;
+        }
+
         public SentencePaper build() {
             return this.obj;
         }

+ 1 - 1
server/data/src/main/java/com/qxgmat/data/dao/entity/UserCollectQuestion.java

@@ -4,7 +4,7 @@ import java.io.Serializable;
 import java.util.Date;
 import javax.persistence.*;
 
-@Table(name = "user_collect")
+@Table(name = "user_collect_question")
 public class UserCollectQuestion implements Serializable {
     @Id
     @Column(name = "`id`")

+ 0 - 10
server/data/src/main/java/com/qxgmat/data/dao/mapping/ExaminationMapper.xml

@@ -1,10 +0,0 @@
-<?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.dao.ExaminationMapper">
-  <resultMap id="BaseResultMap" type="com.qxgmat.data.dao.entity.Examination">
-    <!--
-      WARNING - @mbg.generated
-    -->
-    <id column="id" jdbcType="INTEGER" property="id" />
-  </resultMap>
-</mapper>

+ 0 - 10
server/data/src/main/java/com/qxgmat/data/dao/mapping/ExerciseMapper.xml

@@ -1,10 +0,0 @@
-<?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.dao.ExerciseMapper">
-  <resultMap id="BaseResultMap" type="com.qxgmat.data.dao.entity.Exercise">
-    <!--
-      WARNING - @mbg.generated
-    -->
-    <id column="id" jdbcType="INTEGER" property="id" />
-  </resultMap>
-</mapper>

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

@@ -9,11 +9,12 @@
     <result column="paper_id" jdbcType="INTEGER" property="paperId" />
     <result column="question_id" jdbcType="INTEGER" property="questionId" />
     <result column="question_no_id" jdbcType="INTEGER" property="questionNoId" />
+    <result column="no" jdbcType="INTEGER" property="no" />
   </resultMap>
   <sql id="Base_Column_List">
     <!--
       WARNING - @mbg.generated
     -->
-    `id`, `paper_id`, `question_id`, `question_no_id`
+    `id`, `paper_id`, `question_id`, `question_no_id`, `no`
   </sql>
 </mapper>

+ 4 - 1
server/data/src/main/java/com/qxgmat/data/dao/mapping/SentencePaperMapper.xml

@@ -7,11 +7,14 @@
     -->
     <id column="id" jdbcType="INTEGER" property="id" />
     <result column="title" jdbcType="VARCHAR" property="title" />
+    <result column="question_number" jdbcType="INTEGER" property="questionNumber" />
+    <result column="question_no_ids" jdbcType="VARCHAR" property="questionNoIds" typeHandler="com.nuliji.tools.mybatis.handler.IntegerArrayWithJsonHandler" />
+    <result column="status" jdbcType="INTEGER" property="status" />
   </resultMap>
   <sql id="Base_Column_List">
     <!--
       WARNING - @mbg.generated
     -->
-    `id`, `title`
+    `id`, `title`, `question_number`, `question_no_ids`, `status`
   </sql>
 </mapper>

+ 14 - 15
server/data/src/main/java/com/qxgmat/data/relation/mapping/ExerciseQuestionRelationMapper.xml

@@ -1,36 +1,35 @@
 <?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.ExerciseQuestionRelationMapper">
-  <resultMap id="BaseResultMap" type="com.qxgmat.data.dao.entity.ExercisePaperQuestion">
+  <resultMap id="IdMap" type="com.qxgmat.data.dao.entity.ExercisePaperQuestion">
     <!--
       WARNING - @mbg.generated
     -->
-    <id column="id" jdbcType="INT" property="id" />
+    <id column="id" jdbcType="INTEGER" property="id" />
   </resultMap>
-  <sql id="Base_Column_List">
+  <sql id="Id_Column_List">
     <!--
       WARNING - @mbg.generated
     -->
-    q.`id`
+    epq.`id`
   </sql>
 
-  <!--练习题目列表列表-->
-  <select id="listAdmin" resultMap="BaseResultMap">
+  <select id="listAdmin" resultMap="IdMap">
     select
-    <include refid="Base_Column_List" />
-    from `question_no` qn
-    left join `question` q on q.`id` = qn.`question_id`
-    <if test="paperId != null">
-    left join `exercise_paper_question` epq on qn.`id` = epg.`question_no_id`
+    <include refid="Id_Column_List" />
+    from `exercise_paper_question` epq
+    left join `question` q on q.`id` = epq.`question_id`
+    left join `question_no` qn on qn.`id` = epq.`question_no_id`
+    <if test="structId != null">
     left join `exercise_paper` ep on ep.`id` = epg.`paper_id`
         and ep.`id` = #{paperId,jdbcType=VARCHAR}
     </if>
-    where q.`module` = "exercise"
+    where qn.`module` = "exercise"
     <if test="paperId != null">
-      and ep.`id` != null
+      and epq.`paper_id` != null
     </if>
     <if test="structId != null">
-      and find_in_set(#{structId,jdbcType=VARCHAR}, q.`module_struct`)
+      and find_in_set(#{structId,jdbcType=VARCHAR}, qn.`module_struct`)
     </if>
     <if test="questionNoId != null">
       and qn.`id` =#{questionNoId,jdbcType=VARCHAR}
@@ -47,6 +46,6 @@
     <if test="endTime != null">
       and hp.`update_time` &lt; #{endTime,jdbcType=VARCHAR}
     </if>
-    order by q.${order} ${direction}
+    order by ${order} ${direction}
   </select>
 </mapper>

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

@@ -1,13 +1,13 @@
 <?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.QuestionRelationMapper">
-  <resultMap id="BaseResultMap" type="com.qxgmat.data.dao.entity.QuestionNo">
+<mapper namespace="com.qxgmat.data.relation.QuestionNoRelationMapper">
+  <resultMap id="IdMap" type="com.qxgmat.data.dao.entity.QuestionNo">
     <!--
       WARNING - @mbg.generated
     -->
-    <id column="id" jdbcType="INT" property="id" />
+    <id column="id" jdbcType="INTEGER" property="id" />
   </resultMap>
-  <sql id="Base_Column_List">
+  <sql id="Id_Column_List">
     <!--
       WARNING - @mbg.generated
     -->

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

@@ -1,13 +1,13 @@
 <?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.QuestionRelationMapper">
-  <resultMap id="BaseResultMap" type="com.qxgmat.data.dao.entity.Question">
+  <resultMap id="IdMap" type="com.qxgmat.data.dao.entity.Question">
     <!--
       WARNING - @mbg.generated
     -->
-    <id column="id" jdbcType="INT" property="id" />
+    <id column="id" jdbcType="INTEGER" property="id" />
   </resultMap>
-  <sql id="Base_Column_List">
+  <sql id="Id_Column_List">
     <!--
       WARNING - @mbg.generated
     -->

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

@@ -1,13 +1,13 @@
 <?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.UserAskRelationMapper">
-  <resultMap id="BaseResultMap" type="com.qxgmat.data.dao.entity.UserAsk">
+  <resultMap id="IdMap" type="com.qxgmat.data.dao.entity.UserAsk">
     <!--
       WARNING - @mbg.generated
     -->
-    <id column="id" jdbcType="INT" property="id" />
+    <id column="id" jdbcType="INTEGER" property="id" />
   </resultMap>
-  <sql id="Base_Column_List">
+  <sql id="Id_Column_List">
     <!--
       WARNING - @mbg.generated
     -->
@@ -24,9 +24,9 @@
   </update>
 
   <!--用户提问列表-->
-  <select id="listWithUser" resultMap="BaseResultMap">
+  <select id="listWithUser" resultMap="IdMap">
     select
-    <include refid="Base_Column_List" />
+    <include refid="Id_Column_List" />
     from `user_aks` ua
     left join `user` u on u.`id` = ua.`user_id`
       <if test="userId != null">
@@ -52,6 +52,6 @@
     <if test="showStatus != null">
       and ua.`show_status` = #{showStatus,jdbcType=INT}
     </if>
-    order by ua.${order} ${direction}
+    order by ${order} ${direction}
   </select>
 </mapper>

+ 7 - 7
server/data/src/main/java/com/qxgmat/data/relation/mapping/UserCollectQuestionRelationMapper.xml

@@ -1,13 +1,13 @@
 <?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.UserPaperRelationMapper">
-  <resultMap id="BaseResultMap" type="com.qxgmat.data.dao.entity.UserCollectQuestion">
+<mapper namespace="com.qxgmat.data.relation.UserCollectQuestionRelationMapper">
+  <resultMap id="IdMap" type="com.qxgmat.data.dao.entity.UserCollectQuestion">
     <!--
       WARNING - @mbg.generated
     -->
-    <id column="id" jdbcType="INT" property="id" />
+    <id column="id" jdbcType="INTEGER" property="id" />
   </resultMap>
-  <sql id="Base_Column_List">
+  <sql id="Id_Column_List">
     <!--
       WARNING - @mbg.generated
     -->
@@ -17,9 +17,9 @@
   <!--
     用户收藏题目列表
   -->
-  <select id="list" resultMap="BaseResultMap">
+  <select id="list" resultMap="IdMap">
     select
-    <include refid="Base_Column_List" />
+    <include refid="Id_Column_List" />
     from `user_collect_question` ucq
     left join `question_no` qn on qn.`id` = ucq.`question_no_id`
       <if test="module != null">
@@ -42,7 +42,7 @@
       and ucq.`createTime` &lt; #{endTime,jdbcType=VARCHAR}
     </if>
 
-    order by ucq.${order} ${direction}
+    order by ${order} ${direction}
   </select>
 
 </mapper>

+ 11 - 12
server/data/src/main/java/com/qxgmat/data/relation/mapping/UserPaperRelationMapper.xml

@@ -1,13 +1,13 @@
 <?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.UserPaperRelationMapper">
-  <resultMap id="BaseResultMap" type="com.qxgmat.data.dao.entity.UserPaper">
+  <resultMap id="IdMap" type="com.qxgmat.data.dao.entity.UserPaper">
     <!--
       WARNING - @mbg.generated
     -->
-    <id column="id" jdbcType="INT" property="id" />
+    <id column="id" jdbcType="INTEGER" property="id" />
   </resultMap>
-  <sql id="Base_Column_List">
+  <sql id="Id_Column_List">
     <!--
       WARNING - @mbg.generated
     -->
@@ -18,9 +18,9 @@
     用户预习作业列表: 后台
     https://blog.csdn.net/t_1007/article/details/52369261
   -->
-  <select id="listHomeworkPreviewAdmin" resultMap="BaseResultMap">
+  <select id="listHomeworkPreviewAdmin" resultMap="IdMap">
     select
-    <include refid="Base_Column_List" />
+    <include refid="Id_Column_List" />
     from `user_paper` up
     left join `homework_preview` hp on hp.`id` = up.`module_id`
       and up.`module` = "homework_preview"
@@ -46,9 +46,9 @@
   <!--
     用户预习作业列表: 用户端
   -->
-  <select id="listHomeworkPreview" resultMap="BaseResultMap">
+  <select id="listHomeworkPreview" resultMap="IdMap">
     select
-    <include refid="Base_Column_List" />
+    <include refid="Id_Column_List" />
     from `user_paper` up
     left join `homework_preview` hp on hp.`id` = up.`module_id`
       and up.`module` = "homework_preview"
@@ -76,9 +76,9 @@
   <!--
     用户预习作业Top列表: 用户端
   -->
-  <select id="listHomeworkPreviewGroupTop" resultMap="BaseResultMap">
+  <select id="listHomeworkPreviewGroupTop" resultMap="IdMap">
     select
-    <include refid="Base_Column_List" />
+    <include refid="Id_Column_List" />
     from `user_paper` up
     where
     hp.`id` != null
@@ -86,12 +86,11 @@
     <if test="userId != null">
       and up.`user_id` = #{userId,jdbcType=VARCHAR}
     </if>
-    and ( select count(distinct(up1.id))
+    and ( select count(up1.id)
         from `user_paper` up1
         where
         up.`module_id` = up1.`module_id`
         and up.`module` = "homework_preview"
-        and up1.number &lt; up.salary) &lt; ${top}
-    order by
+        and up1.create_time &gt; up.create_time) &lt; ${top}
   </select>
 </mapper>

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

@@ -1,13 +1,13 @@
 <?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.UserReportRelationMapper">
-  <resultMap id="BaseResultMap" type="com.qxgmat.data.dao.entity.UserReport">
+  <resultMap id="IdMap" type="com.qxgmat.data.dao.entity.UserReport">
     <!--
       WARNING - @mbg.generated
     -->
-    <id column="id" jdbcType="INT" property="id" />
+    <id column="id" jdbcType="INTEGER" property="id" />
   </resultMap>
-  <sql id="Base_Column_List">
+  <sql id="Id_Column_List">
     <!--
       WARNING - @mbg.generated
     -->
@@ -18,7 +18,7 @@
     用户完成度最高的最后一次
     https://blog.csdn.net/t_1007/article/details/52369261
   -->
-  <select id="listFinishLast" resultMap="BaseResultMap">
+  <select id="listFinishLast" resultMap="IdMap">
     select
       SUBSTRING_INDEX(GROUP_CONCAT(ur.`id` ORDER BY ur.`user_number` desc, ur.`create_time` desc),',',1)
     from `user_report` ur
@@ -41,7 +41,7 @@
     用户最后一次
     https://blog.csdn.net/t_1007/article/details/52369261
   -->
-  <select id="listLast" resultMap="BaseResultMap">
+  <select id="listLast" resultMap="IdMap">
     select
     SUBSTRING_INDEX(GROUP_CONCAT(ur.`id` ORDER BY ur.`create_time` desc),',',1)
     from `user_report` ur

+ 1 - 1
server/data/src/main/resources/application-data.yml

@@ -3,7 +3,7 @@ mybatis:
   # type-aliases扫描路径
   type-aliases-package: tk.mybatis.springboot.model
   # mapper xml实现扫描路径
-  mapper-locations: classpath:com/qxgmat/data/dao/**/*.xml
+  mapper-locations: classpath:com/qxgmat/data/dao/**/*.xml,classpath:com/qxgmat/data/relation/**/*.xml
   property:
     order: BEFORE
 

+ 4 - 0
server/data/src/main/resources/mybatis-generator.xml

@@ -107,6 +107,10 @@
             <generatedKey column="id" sqlStatement="Mysql" identity="true"/>
             <columnOverride column="question_no_ids" javaType="Integer[]" jdbcType="VARCHAR" typeHandler="com.nuliji.tools.mybatis.handler.IntegerArrayWithJsonHandler"/>
         </table>
+        <table schema="qianxing" tableName="sentence_paper" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" delimitAllColumns="true">
+            <generatedKey column="id" sqlStatement="Mysql" identity="true"/>
+            <columnOverride column="question_no_ids" javaType="Integer[]" jdbcType="VARCHAR" typeHandler="com.nuliji.tools.mybatis.handler.IntegerArrayWithJsonHandler"/>
+        </table>
         <table schema="qianxing" tableName="textbook_paper" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" delimitAllColumns="true">
             <generatedKey column="id" sqlStatement="Mysql" identity="true"/>
             <columnOverride column="question_no_ids" javaType="Integer[]" jdbcType="VARCHAR" typeHandler="com.nuliji.tools.mybatis.handler.IntegerArrayWithJsonHandler"/>

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

@@ -99,8 +99,9 @@ public class ExerciseController {
     public Response<PageMessage<ExercisePaperListDto>> listPaper(
             @RequestParam(required = false, defaultValue = "1") int page,
             @RequestParam(required = false, defaultValue = "100") int size,
+            @RequestParam(required = false, defaultValue = "") String keyword,
             HttpSession session) {
-        Page<ExercisePaper> p = exercisePaperService.select(page, size);
+        Page<ExercisePaper> p = exercisePaperService.select(page, size, keyword);
         List<ExercisePaperListDto> pr = Transform.convert(p, ExercisePaperListDto.class);
 
         return ResponseHelp.success(pr, page, size, p.getTotal());
@@ -144,7 +145,7 @@ public class ExerciseController {
 
     @RequestMapping(value = "/paper/auto", method = RequestMethod.POST)
     @ApiOperation(value = "自动组卷", httpMethod = "POST")
-    public Response<Boolean> paperAuto(@RequestBody @Validated ExerciseStructDto dto, HttpServletRequest request) {
+    public Response<Boolean> autoPaper(@RequestBody @Validated ExerciseStructDto dto, HttpServletRequest request) {
         // 判断当前组卷状态
         Setting setting = settingService.getByKey(SettingKey.EXERCISE_PAPER_STATUS);
         JSONObject status = setting.getValue();
@@ -155,4 +156,14 @@ public class ExerciseController {
 
         return ResponseHelp.success(true);
     }
+
+    @RequestMapping(value = "/paper/auto", method = RequestMethod.GET)
+    @ApiOperation(value = "自动组卷状态", httpMethod = "GET")
+    public Response<JSONObject> autoPaperStatus(HttpServletRequest request) {
+        // 判断当前组卷状态
+        Setting setting = settingService.getByKey(SettingKey.EXERCISE_PAPER_STATUS);
+        JSONObject status = setting.getValue();
+
+        return ResponseHelp.success(status);
+    }
 }

+ 11 - 0
server/gateway-api/src/main/java/com/qxgmat/controller/admin/QuestionController.java

@@ -62,6 +62,17 @@ public class QuestionController {
         return ResponseHelp.success(true);
     }
 
+    @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
+    @ApiOperation(value = "删除题目", httpMethod = "DELETE")
+    public Response<Boolean> delete(int id, HttpServletRequest request) {
+//        Question entity = Transform.dtoToEntity(dto);
+        // 添加
+//        entity.setModule(QuestionModule.EXERCISE.key);
+//        entity = exercisePaperService.editQuestion(entity);
+        managerLogService.log(request);
+        return ResponseHelp.success(true);
+    }
+
     @RequestMapping(value = "/list/no", method = RequestMethod.POST)
     @ApiOperation(value = "题目编号列表:通过编号", httpMethod = "POST")
     public Response<List<QuestionNoExtendDto>> listNo(@RequestBody @Validated QuestionNoSearchDto dto, HttpServletRequest request) {

+ 38 - 4
server/gateway-api/src/main/java/com/qxgmat/controller/admin/SentenceController.java

@@ -1,21 +1,24 @@
 package com.qxgmat.controller.admin;
 
+import com.alibaba.fastjson.JSONObject;
 import com.github.pagehelper.Page;
 import com.nuliji.tools.PageMessage;
 import com.nuliji.tools.Response;
 import com.nuliji.tools.ResponseHelp;
 import com.nuliji.tools.Transform;
+import com.nuliji.tools.exception.ParameterException;
+import com.qxgmat.data.constants.enums.SettingKey;
 import com.qxgmat.data.dao.entity.Question;
 import com.qxgmat.data.dao.entity.SentenceArticle;
 import com.qxgmat.data.dao.entity.SentenceQuestion;
+import com.qxgmat.data.dao.entity.Setting;
 import com.qxgmat.data.relation.entity.SentenceQuestionRelation;
+import com.qxgmat.dto.admin.request.ExerciseStructDto;
 import com.qxgmat.dto.admin.request.ManagerDto;
 import com.qxgmat.dto.admin.response.SentenceQuestionListDto;
 import com.qxgmat.service.SentencePaperService;
-import com.qxgmat.service.inline.ManagerLogService;
-import com.qxgmat.service.inline.QuestionService;
-import com.qxgmat.service.inline.SentenceArticleService;
-import com.qxgmat.service.inline.SentenceQuestionService;
+import com.qxgmat.service.inline.*;
+import com.qxgmat.task.AsyncTask;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -44,6 +47,12 @@ public class SentenceController {
     @Autowired
     private QuestionService questionService;
 
+    @Autowired
+    private SettingService settingService;
+
+    @Autowired
+    private AsyncTask asyncTask;
+
     @RequestMapping(value = "/article/add", method = RequestMethod.POST)
     @ApiOperation(value = "添加长难句文章", httpMethod = "POST")
     public Response<SentenceArticle> addArticle(@RequestBody @Validated SentenceArticle dto, HttpServletRequest request) {
@@ -118,6 +127,7 @@ public class SentenceController {
         SentenceQuestionRelation relation = sentenceQuestionService.relation(entity);
         return ResponseHelp.success(relation);
     }
+
     @RequestMapping(value = "/question/list", method = RequestMethod.GET)
     @ApiOperation(value = "长难句题目列表", httpMethod = "GET")
     public Response<PageMessage<SentenceQuestionListDto>> listQuestion(
@@ -129,4 +139,28 @@ public class SentenceController {
 
         return ResponseHelp.success(pr, page, size, p.getTotal());
     }
+
+    @RequestMapping(value = "/paper/auto", method = RequestMethod.POST)
+    @ApiOperation(value = "自动组卷", httpMethod = "POST")
+    public Response<Boolean> autoPaper(@RequestBody @Validated ExerciseStructDto dto, HttpServletRequest request) {
+        // 判断当前组卷状态
+        Setting setting = settingService.getByKey(SettingKey.SENTENCE_PAPER_STATUS);
+        JSONObject status = setting.getValue();
+        if (status.getInteger("process")<100){
+            throw new ParameterException("组卷进行中,请稍后再试");
+        }
+        asyncTask.autoSentencePaper();
+
+        return ResponseHelp.success(true);
+    }
+
+    @RequestMapping(value = "/paper/auto", method = RequestMethod.GET)
+    @ApiOperation(value = "自动组卷状态", httpMethod = "GET")
+    public Response<JSONObject> autoPaperStatus(HttpServletRequest request) {
+        // 判断当前组卷状态
+        Setting setting = settingService.getByKey(SettingKey.SENTENCE_PAPER_STATUS);
+        JSONObject status = setting.getValue();
+
+        return ResponseHelp.success(status);
+    }
 }

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

@@ -36,7 +36,7 @@ public class SettingController {
 
     @RequestMapping(value = "/index", method = RequestMethod.PUT)
     @ApiOperation(value = "修改首页配置", httpMethod = "PUT")
-    private Response<Boolean> indexEdit(@RequestBody @Validated JSONObject dto){
+    private Response<Boolean> editIndex(@RequestBody @Validated JSONObject dto){
         Setting entity = settingService.getByKey(SettingKey.INDEX);
         entity.setValue(dto);
         settingService.edit(entity);
@@ -45,7 +45,7 @@ public class SettingController {
 
     @RequestMapping(value = "/index", method = RequestMethod.GET)
     @ApiOperation(value = "获取首页配置", httpMethod = "GET")
-    private Response<JSONObject> indexGet(){
+    private Response<JSONObject> getIndex(){
         Setting entity = settingService.getByKey(SettingKey.INDEX);
         logger.debug("{}", entity);
         return ResponseHelp.success(entity.getValue());
@@ -53,7 +53,7 @@ public class SettingController {
 
     @RequestMapping(value = "/place", method = RequestMethod.PUT)
     @ApiOperation(value = "修改考点设置", httpMethod = "PUT")
-    private Response<Boolean> placeEdit(@RequestBody @Validated JSONObject dto){
+    private Response<Boolean> editPlace(@RequestBody @Validated JSONObject dto){
         Setting entity = settingService.getByKey(SettingKey.PLACE);
         entity.setValue(dto);
         settingService.edit(entity);
@@ -62,7 +62,7 @@ public class SettingController {
 
     @RequestMapping(value = "/place", method = RequestMethod.GET)
     @ApiOperation(value = "获取考点配置", httpMethod = "GET")
-    private Response<JSONObject> placeGet(){
+    private Response<JSONObject> getPlace(){
         Setting entity = settingService.getByKey(SettingKey.PLACE);
 
         return ResponseHelp.success(entity.getValue());
@@ -71,7 +71,7 @@ public class SettingController {
 
     @RequestMapping(value = "/sentence", method = RequestMethod.PUT)
     @ApiOperation(value = "修改长难句设置", httpMethod = "PUT")
-    private Response<Boolean> sentenceEdit(@RequestBody @Validated JSONObject dto){
+    private Response<Boolean> editSentence(@RequestBody @Validated JSONObject dto){
         Setting entity = settingService.getByKey(SettingKey.SENTENCE);
         entity.setValue(dto);
         settingService.edit(entity);
@@ -80,7 +80,7 @@ public class SettingController {
 
     @RequestMapping(value = "/sentence", method = RequestMethod.GET)
     @ApiOperation(value = "获取长难句配置", httpMethod = "GET")
-    private Response<JSONObject> sentenceGet(){
+    private Response<JSONObject> getSentence(){
         Setting entity = settingService.getByKey(SettingKey.SENTENCE);
 
         return ResponseHelp.success(entity.getValue());
@@ -89,7 +89,7 @@ public class SettingController {
 
     @RequestMapping(value = "/exercise_time", method = RequestMethod.PUT)
     @ApiOperation(value = "修改做题时间设置", httpMethod = "PUT")
-    private Response<Boolean> exerciseTimeEdit(@RequestBody @Validated JSONObject dto){
+    private Response<Boolean> editExerciseTime(@RequestBody @Validated JSONObject dto){
         Setting entity = settingService.getByKey(SettingKey.EXERCISE_TIME);
         entity.setValue(dto);
         settingService.edit(entity);
@@ -98,14 +98,14 @@ public class SettingController {
 
     @RequestMapping(value = "/exercise_time", method = RequestMethod.GET)
     @ApiOperation(value = "获取做题时间配置", httpMethod = "GET")
-    private Response<JSONObject> exerciseTimeGet(){
+    private Response<JSONObject> getExerciseTime(){
         Setting entity = settingService.getByKey(SettingKey.EXERCISE_TIME);
 
         return ResponseHelp.success(entity.getValue());
     }
     @RequestMapping(value = "/examination_time", method = RequestMethod.PUT)
     @ApiOperation(value = "修改做题时间设置", httpMethod = "PUT")
-    private Response<Boolean> examinationTimeEdit(@RequestBody @Validated JSONObject dto){
+    private Response<Boolean> editExaminationTime(@RequestBody @Validated JSONObject dto){
         Setting entity = settingService.getByKey(SettingKey.EXAMINATION_TIME);
         entity.setValue(dto);
         settingService.edit(entity);
@@ -114,7 +114,7 @@ public class SettingController {
 
     @RequestMapping(value = "/examination_time", method = RequestMethod.GET)
     @ApiOperation(value = "获取做题时间配置", httpMethod = "GET")
-    private Response<JSONObject> examinationTimeGet(){
+    private Response<JSONObject> getExaminationTime(){
         Setting entity = settingService.getByKey(SettingKey.EXAMINATION_TIME);
 
         return ResponseHelp.success(entity.getValue());
@@ -122,7 +122,7 @@ public class SettingController {
 
     @RequestMapping(value = "/filter_time", method = RequestMethod.PUT)
     @ApiOperation(value = "修改剔除时间设置", httpMethod = "PUT")
-    private Response<Boolean> filterTimeEdit(@RequestBody @Validated JSONObject dto){
+    private Response<Boolean> editFilterTime(@RequestBody @Validated JSONObject dto){
         Setting entity = settingService.getByKey(SettingKey.FILTER_TIME);
         entity.setValue(dto);
         settingService.edit(entity);
@@ -131,7 +131,7 @@ public class SettingController {
 
     @RequestMapping(value = "/filter_time", method = RequestMethod.GET)
     @ApiOperation(value = "获取做题时间配置", httpMethod = "GET")
-    private Response<JSONObject> filterTimeGet(){
+    private Response<JSONObject> getFilterTime(){
         Setting entity = settingService.getByKey(SettingKey.FILTER_TIME);
 
         return ResponseHelp.success(entity.getValue());
@@ -139,7 +139,7 @@ public class SettingController {
 
     @RequestMapping(value = "/tips", method = RequestMethod.PUT)
     @ApiOperation(value = "修改结构说明", httpMethod = "PUT")
-    private Response<Boolean> tipsEdit(@RequestBody @Validated JSONObject dto){
+    private Response<Boolean> editTips(@RequestBody @Validated JSONObject dto){
         Setting entity = settingService.getByKey(SettingKey.TIPS);
         entity.setValue(dto);
         settingService.edit(entity);
@@ -148,7 +148,7 @@ public class SettingController {
 
     @RequestMapping(value = "/tips", method = RequestMethod.GET)
     @ApiOperation(value = "获取结构说明", httpMethod = "GET")
-    private Response<JSONObject> tipsGet(){
+    private Response<JSONObject> getTips(){
         Setting entity = settingService.getByKey(SettingKey.TIPS);
 
         return ResponseHelp.success(entity.getValue());
@@ -156,7 +156,7 @@ public class SettingController {
 
     @RequestMapping(value = "/rank/add", method = RequestMethod.POST)
     @ApiOperation(value = "添加排行", httpMethod = "POST")
-    private Response<Boolean> rankAdd(@RequestBody @Validated RankDto dto){
+    private Response<Boolean> addRank(@RequestBody @Validated RankDto dto){
         Rank entity = Transform.dtoToEntity(dto);
         rankService.add(entity);
         return ResponseHelp.success(true);
@@ -164,7 +164,7 @@ public class SettingController {
 
     @RequestMapping(value = "/rank/edit", method = RequestMethod.PUT)
     @ApiOperation(value = "修改排行", httpMethod = "PUT")
-    private Response<Boolean> rankEdit(@RequestBody @Validated RankDto dto){
+    private Response<Boolean> editRank(@RequestBody @Validated RankDto dto){
         Rank entity = Transform.dtoToEntity(dto);
         rankService.edit(entity);
         return ResponseHelp.success(true);
@@ -172,14 +172,14 @@ public class SettingController {
 
     @RequestMapping(value = "/rank/delete", method = RequestMethod.DELETE)
     @ApiOperation(value = "删除排行", httpMethod = "DELETE")
-    private Response<Boolean> rankDelete(@RequestParam int id){
+    private Response<Boolean> deleteRank(@RequestParam int id){
         rankService.delete(id);
         return ResponseHelp.success(true);
     }
 
     @RequestMapping(value = "/rank/list", method = RequestMethod.GET)
     @ApiOperation(value = "获取排行设置", httpMethod = "GET")
-    private Response<List<Rank>> rankGet(){
+    private Response<List<Rank>> getRank(){
         List<Rank> rankList = rankService.all();
         return ResponseHelp.success(rankList);
     }

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

@@ -174,7 +174,7 @@ public class MyController {
 
     @RequestMapping(value = "/prepare", method = RequestMethod.PUT)
     @ApiOperation(value = "修改备考信息", notes = "修改用户备考信息", httpMethod = "PUT")
-    public Response<Boolean> prepareEdit(@RequestBody @Validated UserPrepareDto dto)  {
+    public Response<Boolean> editPrepare(@RequestBody @Validated UserPrepareDto dto)  {
         User entity = Transform.dtoToEntity(dto);
         User user = (User) shiroHelp.getLoginUser();
         userMessageService.clear(user.getId());
@@ -184,7 +184,7 @@ public class MyController {
 
     @RequestMapping(value = "/prepare", method = RequestMethod.GET)
     @ApiOperation(value = "获取备考信息", notes = "获取备考信息及分布", httpMethod = "GET")
-    public Response<UserPrepareDetailDto> prepareGet()  {
+    public Response<UserPrepareDetailDto> getPrepare()  {
         User user = (User) shiroHelp.getLoginUser();
         User entity = usersService.get(user.getId());
         UserPrepareDetailDto dto = Transform.convert(entity, UserPrepareDetailDto.class);
@@ -213,7 +213,7 @@ public class MyController {
 
     @RequestMapping(value = "/collect", method = RequestMethod.PUT)
     @ApiOperation(value = "添加收藏", notes = "添加收藏", httpMethod = "PUT")
-    public Response<Boolean> collectAdd(@RequestBody @Validated UserCollectDto dto)  {
+    public Response<Boolean> addCollect(@RequestBody @Validated UserCollectDto dto)  {
         UserCollectQuestion entity = Transform.dtoToEntity(dto);
         User user = (User) shiroHelp.getLoginUser();
         userCollectQuestionService.addQuestion(user.getId(), entity.getQuestionNoId());
@@ -223,7 +223,7 @@ public class MyController {
 
     @RequestMapping(value = "/collect", method = RequestMethod.DELETE)
     @ApiOperation(value = "移除收藏", notes = "移除收藏", httpMethod = "DELETE")
-    public Response<Boolean> collectDelete(int id)  {
+    public Response<Boolean> deleteCollect(int id)  {
         User user = (User) shiroHelp.getLoginUser();
         Boolean result = userCollectQuestionService.deleteQuestion(user.getId(), id);
 
@@ -232,7 +232,7 @@ public class MyController {
 
     @RequestMapping(value = "/collect/question", method = RequestMethod.GET)
     @ApiOperation(value = "获取收藏题目列表", notes = "获取收藏题目列表", httpMethod = "GET")
-    public Response<PageMessage<UserCollectQuestionDto>> collectList(
+    public Response<PageMessage<UserCollectQuestionDto>> listCollect(
             @RequestParam(required = false, defaultValue = "1") int page,
             @RequestParam(required = false, defaultValue = "100") int size,
             @RequestParam(required = true) String module,
@@ -255,7 +255,7 @@ public class MyController {
 
     @RequestMapping(value = "/error/list", method = RequestMethod.GET)
     @ApiOperation(value = "获取错题列表", notes = "获取错题列表", httpMethod = "GET")
-    public Response<PageMessage<UserQuestionListDto>> errorList(
+    public Response<PageMessage<UserQuestionListDto>> listError(
             @RequestParam(required = false, defaultValue = "1") int page,
             @RequestParam(required = false, defaultValue = "100") int size,
             @RequestParam(required = true) String module,
@@ -271,7 +271,7 @@ public class MyController {
 
     @RequestMapping(value = "/note", method = RequestMethod.PUT)
     @ApiOperation(value = "更新笔记", notes = "更新笔记", httpMethod = "PUT")
-    public Response<Boolean> noteUpdate(@RequestBody @Validated UserNoteDto dto)  {
+    public Response<Boolean> updateNote(@RequestBody @Validated UserNoteDto dto)  {
         UserNote entity = Transform.dtoToEntity(dto);
         User user = (User) shiroHelp.getLoginUser();
         entity.setUserId(user.getId());
@@ -282,7 +282,7 @@ public class MyController {
 
     @RequestMapping(value = "/note/list", method = RequestMethod.GET)
     @ApiOperation(value = "获取笔记列表", notes = "获取笔记列表", httpMethod = "GET")
-    public Response<PageMessage<UserHomeworkPreviewExtendDto>> noteList(
+    public Response<PageMessage<UserHomeworkPreviewExtendDto>> listNote(
             @RequestParam(required = false, defaultValue = "1") int page,
             @RequestParam(required = false, defaultValue = "100") int size,
             @RequestParam(required = true) String module,

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

@@ -68,7 +68,7 @@ public class QuestionController {
 
     @RequestMapping(value = "/preview/list", method = RequestMethod.GET)
     @ApiOperation(value = "获取预习作业列表", notes = "获取预习作业列表", httpMethod = "GET")
-    public Response<PageMessage<UserHomeworkPreviewExtendDto>> previewList(
+    public Response<PageMessage<UserHomeworkPreviewExtendDto>> listPreview(
             @RequestParam(required = false, defaultValue = "1") int page,
             @RequestParam(required = false, defaultValue = "100") int size,
             @RequestParam(required = false) Number category,
@@ -96,7 +96,7 @@ public class QuestionController {
 
     @RequestMapping(value = "/exercise/paper", method = RequestMethod.GET)
     @ApiOperation(value = "练习组卷列表", httpMethod = "GET")
-    public Response<PageMessage<ExercisePaper>> exercisePaperList(
+    public Response<PageMessage<ExercisePaper>> listExercisePaper(
             @RequestParam(required = false, defaultValue = "1") int page,
             @RequestParam(required = false, defaultValue = "100") int size,
             HttpSession session) {

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

@@ -97,7 +97,7 @@ public class SentenceController
 
     @RequestMapping(value = "/article/list", method = RequestMethod.GET)
     @ApiOperation(value = "长难句文章列表", httpMethod = "GET")
-    public Response<List<UserSentenceArticleDto>> articleList(
+    public Response<List<UserSentenceArticleDto>> listArticle(
             @RequestParam(required = true) Integer chapter,
             HttpSession session) {
         User user = (User) shiroHelp.getLoginUser();
@@ -136,7 +136,7 @@ public class SentenceController
 
     @RequestMapping(value = "/paper/list", method = RequestMethod.GET)
     @ApiOperation(value = "长难句组卷列表", httpMethod = "GET")
-    public Response<List<UserSentenceArticleDto>> paperList(
+    public Response<List<UserSentenceArticleDto>> listPaper(
             HttpSession session) {
         User user = (User) shiroHelp.getLoginUser();
         // 查询用户code

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

@@ -4,6 +4,7 @@ import com.github.pagehelper.Page;
 import com.nuliji.tools.AbstractService;
 import com.nuliji.tools.exception.ParameterException;
 import com.nuliji.tools.exception.SystemException;
+import com.nuliji.tools.mybatis.Example;
 import com.qxgmat.data.dao.ExercisePaperMapper;
 import com.qxgmat.data.dao.entity.ExercisePaper;
 import com.qxgmat.data.dao.entity.Question;
@@ -82,8 +83,18 @@ public class ExercisePaperService extends AbstractService {
         return in;
     }
 
-    public Page<ExercisePaper> select(int page, int pageSize){
-        return select(exercisePaperMapper, page, pageSize);
+    public Page<ExercisePaper> select(int page, int pageSize, String keyword){
+        Example example = new Example(ExercisePaper.class);
+        example.and(
+                example.createCriteria()
+                        .andEqualTo("status", 1)
+        );
+        if (keyword != null)
+            example.and(
+                    example.createCriteria()
+                            .andLike("title", keyword)
+            );
+        return select(exercisePaperMapper, example, page, pageSize);
     }
 
     public List<ExercisePaper> select(Collection ids){

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

@@ -2,12 +2,16 @@ package com.qxgmat.service.inline;
 
 import com.github.pagehelper.Page;
 import com.nuliji.tools.AbstractService;
+import com.nuliji.tools.PageResult;
+import com.nuliji.tools.Transform;
 import com.nuliji.tools.exception.ParameterException;
 import com.nuliji.tools.exception.SystemException;
 import com.qxgmat.data.constants.enums.status.DirectionStatus;
 import com.qxgmat.data.dao.ExercisePaperQuestionMapper;
 import com.qxgmat.data.dao.entity.ExercisePaperQuestion;
+import com.qxgmat.data.dao.entity.QuestionNo;
 import com.qxgmat.data.relation.ExerciseQuestionRelationMapper;
+import com.qxgmat.data.relation.QuestionNoRelationMapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -26,6 +30,12 @@ public class ExerciseQuestionService extends AbstractService {
     @Resource
     private ExerciseQuestionRelationMapper exerciseQuestionRelationMapper;
 
+    @Resource
+    private QuestionNoRelationMapper questionNoRelationMapper;
+
+    @Resource
+    private QuestionNoService questionNoService;
+
 
     public Page<ExercisePaperQuestion> listAdmin(int page, int pageSize, Number structId, Number questionNo, Number paperId, String place, String difficult, String startTime, String endTime, String order, DirectionStatus direction){
         if(order.isEmpty()) order = "id";
@@ -35,9 +45,17 @@ public class ExerciseQuestionService extends AbstractService {
         String finalOrder = order;
         DirectionStatus finalDirection = direction;
 
-        return page(() -> {
+        Page<ExercisePaperQuestion> p = page(() -> {
             exerciseQuestionRelationMapper.listAdmin(structId, questionNo, paperId, place, difficult, startTime, endTime, finalOrder, finalDirection.key);
         }, page, pageSize);
+
+        Collection ids = Transform.getIds(p, ExercisePaperQuestion.class, "id");
+
+        // 获取详细数据
+        List<ExercisePaperQuestion> list = select(ids);
+        Transform.replace(p, list, ExercisePaperQuestion.class, "id");
+
+        return p;
     }
 
     public ExercisePaperQuestion add(ExercisePaperQuestion question){

+ 3 - 0
server/gateway-api/src/main/java/com/qxgmat/service/inline/StatDayService.java

@@ -9,13 +9,16 @@ import com.qxgmat.data.dao.StatDayMapper;
 import com.qxgmat.data.dao.entity.StatDay;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.util.Collection;
 import java.util.List;
 
+@Service
 public class StatDayService extends AbstractService {
     private static final Logger logger = LoggerFactory.getLogger(SettingService.class);
+
     @Resource
     private StatDayMapper statDayMapper;
 

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

@@ -11,7 +11,7 @@ public class AsyncTask {
 
     @Async("autoExercisePaper")
     public void autoExercisePaper() {
-        logger.info("自动组卷");
+        logger.info("自动练习组卷");
         long start = System.currentTimeMillis();
         long end = System.currentTimeMillis();
         logger.info("完成任务一,耗时:" + (end - start) + "毫秒");
@@ -19,7 +19,15 @@ public class AsyncTask {
 
     @Async("autoExercisePaperError")
     public void autoExercisePaperError() {
-        logger.info("开始做任务一");
+        logger.info("自动练习难易度组卷");
+        long start = System.currentTimeMillis();
+        long end = System.currentTimeMillis();
+        logger.info("完成任务一,耗时:" + (end - start) + "毫秒");
+    }
+
+    @Async("autoSentencePaper")
+    public void autoSentencePaper() {
+        logger.info("自动长难句");
         long start = System.currentTimeMillis();
         long end = System.currentTimeMillis();
         logger.info("完成任务一,耗时:" + (end - start) + "毫秒");

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

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.qxgmat.data.constants.enums.SettingKey;
 import com.qxgmat.data.dao.entity.Setting;
 import com.qxgmat.data.dao.entity.UserService;
+import com.qxgmat.service.UsersService;
 import com.qxgmat.service.inline.SettingService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,7 +31,7 @@ public class ScheduledTask {
     private SettingService settingService;
 
     @Autowired
-    private UserService userService;
+    private UsersService usersService;
 
     /**
      * cron表达式:* * * * * *(共6位,使用空格隔开,具体如下)