SynthesisPaper.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. <template>
  2. <div
  3. v-loading="fullscreenLoading"
  4. class="synthesis-paper gen-paper-detail"
  5. element-loading-text="正在组卷中..."
  6. >
  7. <div class="part-box">
  8. <div class="part-box-header">
  9. <h1 class="part-box-title">综合组卷</h1>
  10. <div>
  11. <el-button
  12. type="primary"
  13. icon="icon icon-save-white"
  14. :loading="fullscreenLoading"
  15. @click="confirmGenPaper"
  16. >确定</el-button
  17. >
  18. <el-button type="danger" plain @click="goback">返回</el-button>
  19. </div>
  20. </div>
  21. <el-form
  22. ref="modalFormComp"
  23. class="part-filter-form"
  24. :model="modalForm"
  25. :rules="rules"
  26. inline
  27. >
  28. <el-form-item prop="courseName" label="业务课名称" style="width: 300px">
  29. <el-input
  30. v-model="modalForm.courseName"
  31. placeholder="业务课名称"
  32. ></el-input>
  33. </el-form-item>
  34. <el-form-item prop="courseCode" label="业务课代码" style="width: 300px">
  35. <el-input
  36. v-model="modalForm.courseCode"
  37. placeholder="业务课代码"
  38. ></el-input>
  39. </el-form-item>
  40. <el-form-item prop="name" label="试卷标题" style="width: 300px">
  41. <el-input v-model="modalForm.name" placeholder="试卷名称"></el-input>
  42. </el-form-item>
  43. <span class="tips-info margin-left-10"
  44. >会作为试卷标题展示在试卷卷头部分</span
  45. >
  46. </el-form>
  47. </div>
  48. <!-- 试题来源 -->
  49. <div class="part-box">
  50. <div class="gen-step-title">
  51. <h3>题源选择</h3>
  52. </div>
  53. <div class="gen-step-body">
  54. <el-form class="part-filter-form" :inline="true">
  55. <el-form-item label="课程" style="width: 280px">
  56. <el-select
  57. v-model="filter.courseId"
  58. :remote-method="getCoursesList"
  59. :loading="courseLoading"
  60. remote
  61. filterable
  62. clearable
  63. multiple
  64. placeholder="请选择"
  65. @clear="getCoursesList('')"
  66. >
  67. <el-option
  68. v-for="item in courseList"
  69. :key="item.id"
  70. :label="item.name + ' - ' + item.code"
  71. :value="item.id"
  72. ></el-option>
  73. </el-select>
  74. </el-form-item>
  75. <el-form-item label="创建时间" style="width: 460px">
  76. <el-date-picker
  77. v-model="createTime"
  78. type="datetimerange"
  79. :picker-options="pickerOptions"
  80. range-separator="-"
  81. start-placeholder="创建开始时间"
  82. end-placeholder="创建结束时间"
  83. value-format="timestamp"
  84. align="right"
  85. unlink-panels
  86. >
  87. </el-date-picker>
  88. </el-form-item>
  89. <el-form-item>
  90. <el-button type="primary" :loading="loading" @click="toPage(1)"
  91. >查询</el-button
  92. >
  93. </el-form-item>
  94. </el-form>
  95. <el-table v-loading="loading" class="part-box-border" :data="paperList">
  96. <el-table-column width="50" align="center">
  97. <template slot-scope="scope">
  98. <el-checkbox
  99. v-model="scope.row.selected"
  100. @change="paperSelectChange(scope.row)"
  101. ></el-checkbox>
  102. </template>
  103. </el-table-column>
  104. <el-table-column prop="courseName" label="课程名称">
  105. </el-table-column>
  106. <el-table-column prop="courseCode" label="课程代码">
  107. </el-table-column>
  108. <el-table-column prop="paperName" label="试卷名称"> </el-table-column>
  109. <el-table-column prop="totalScore" label="总分" width="100">
  110. </el-table-column>
  111. <el-table-column prop="unitCount" label="小题数量" width="200">
  112. </el-table-column>
  113. </el-table>
  114. <div class="part-page">
  115. <el-pagination
  116. :current-page="current"
  117. :page-size="size"
  118. :page-sizes="[10, 20, 50, 100, 200, 300]"
  119. layout="total, sizes, prev, pager, next, jumper"
  120. :total="total"
  121. @current-change="toPage"
  122. @size-change="pageSizeChange"
  123. >
  124. </el-pagination>
  125. </div>
  126. </div>
  127. </div>
  128. <!-- 已选试卷 -->
  129. <div class="part-box">
  130. <div class="gen-step-title">
  131. <h3>选中试卷列表</h3>
  132. </div>
  133. <div class="gen-step-body">
  134. <el-table class="part-box-border" :data="selectPapers">
  135. <el-table-column prop="courseName" label="课程名称">
  136. </el-table-column>
  137. <el-table-column prop="courseCode" label="课程代码">
  138. </el-table-column>
  139. <el-table-column prop="aliasName" label="试卷名称">
  140. <template slot-scope="scope">
  141. <el-input
  142. v-model="scope.row.aliasName"
  143. placeholder="请输入试卷名称"
  144. ></el-input>
  145. </template>
  146. </el-table-column>
  147. <el-table-column label="操作" width="220">
  148. <template slot-scope="scope">
  149. <el-button
  150. size="mini"
  151. type="danger"
  152. plain
  153. @click="toRemovePaper(scope.row)"
  154. >移除</el-button
  155. >
  156. <el-button
  157. v-if="scope.$index"
  158. size="mini"
  159. type="primary"
  160. plain
  161. @click="toMoveupPaper(scope.row)"
  162. >上移</el-button
  163. >
  164. <el-button
  165. v-if="scope.$index !== dataListLastInd"
  166. size="mini"
  167. type="primary"
  168. plain
  169. @click="toMovedownPaper(scope.row)"
  170. >下移</el-button
  171. >
  172. </template>
  173. </el-table-column>
  174. </el-table>
  175. </div>
  176. </div>
  177. </div>
  178. </template>
  179. <script>
  180. import {
  181. paperPageListApi,
  182. courseQueryApi,
  183. synthesisBuildPaperApi,
  184. } from "../api";
  185. import pickerOptions from "@/constants/datePickerOptions";
  186. export default {
  187. data() {
  188. return {
  189. modalForm: {
  190. courseName: "",
  191. courseCode: "",
  192. name: "",
  193. },
  194. rules: {
  195. courseName: [
  196. {
  197. required: true,
  198. message: "请输入业务课名称",
  199. trigger: "change",
  200. },
  201. {
  202. max: 100,
  203. message: "业务课名称不可超过100字符",
  204. },
  205. ],
  206. courseCode: [
  207. {
  208. required: true,
  209. message: "请输入业务课代码",
  210. trigger: "change",
  211. },
  212. {
  213. max: 100,
  214. message: "业务课代码不可超过100字符",
  215. },
  216. ],
  217. name: [
  218. {
  219. required: true,
  220. message: "请输入试卷名称",
  221. trigger: "change",
  222. },
  223. {
  224. max: 100,
  225. message: "试卷名称不可超过100字符",
  226. },
  227. ],
  228. },
  229. filter: {
  230. courseId: [],
  231. createStartTime: "",
  232. createEndTime: "",
  233. },
  234. current: 1,
  235. size: 10,
  236. total: 0,
  237. loading: false,
  238. paperList: [],
  239. selectPapers: [],
  240. courseList: [],
  241. courseLoading: false,
  242. fullscreenLoading: false,
  243. // date-picker
  244. createTime: [],
  245. pickerOptions,
  246. };
  247. },
  248. computed: {
  249. dataListLastInd() {
  250. return this.selectPapers.length - 1;
  251. },
  252. },
  253. mounted() {
  254. this.getCoursesList();
  255. },
  256. methods: {
  257. async getCoursesList(query) {
  258. this.courseLoading = true;
  259. query = query && query.trim();
  260. const res = await courseQueryApi(query, "true");
  261. this.courseList = res.data || [];
  262. this.courseLoading = false;
  263. },
  264. async getList() {
  265. const datas = {
  266. ...this.filter,
  267. pageNumber: this.current,
  268. pageSize: this.size,
  269. };
  270. datas.courseId = datas.courseId.join();
  271. if (this.createTime && this.createTime.length) {
  272. datas.createStartTime = this.createTime[0];
  273. datas.createEndTime = this.createTime[1];
  274. }
  275. const selectedPaperIds = this.selectPapers.map((item) => item.id);
  276. datas.selectedPaperIds = selectedPaperIds;
  277. const res = await paperPageListApi(datas);
  278. this.paperList = res.data.content.map((item) => {
  279. let nitem = {
  280. ...item,
  281. id: item.paperId,
  282. selected: selectedPaperIds.includes(item.id),
  283. };
  284. return nitem;
  285. });
  286. this.total = res.data.totalElements;
  287. },
  288. toPage(page) {
  289. this.current = page;
  290. this.getList();
  291. },
  292. pageSizeChange(size) {
  293. this.size = size;
  294. this.toPage(1);
  295. },
  296. paperSelectChange(row) {
  297. if (row.selected) {
  298. const paper = this.paperList.find((item) => item.id === row.id);
  299. this.selectPapers.push({ ...paper, aliasName: paper.paperName });
  300. } else {
  301. this.toRemovePaper(row);
  302. }
  303. },
  304. toRemovePaper(row) {
  305. this.selectPapers = this.selectPapers.filter(
  306. (item) => item.id !== row.id
  307. );
  308. },
  309. toMoveupPaper(row) {
  310. const pos = this.selectPapers.findIndex((item) => item.id === row.id);
  311. if (!pos) return;
  312. const curPaper = this.selectPapers.splice(pos, 1)[0];
  313. this.selectPapers.splice(pos - 1, 0, curPaper);
  314. },
  315. toMovedownPaper(row) {
  316. const pos = this.selectPapers.findIndex((item) => item.id === row.id);
  317. if (pos === this.selectPapers.length - 1) return;
  318. const curPaper = this.selectPapers.splice(pos, 1)[0];
  319. this.selectPapers.splice(pos + 1, 0, curPaper);
  320. },
  321. async confirmGenPaper() {
  322. const valid = await this.$refs.modalFormComp.validate().catch(() => {});
  323. if (!valid) return;
  324. if (!this.selectPapers.length) {
  325. this.$message.error("请选择试卷");
  326. return;
  327. }
  328. if (this.fullscreenLoading) return;
  329. this.fullscreenLoading = true;
  330. let datas = { ...this.modalForm };
  331. datas.papers = this.selectPapers.map((item) => {
  332. return {
  333. paperId: item.id,
  334. paperName: item.aliasName,
  335. };
  336. });
  337. const res = await synthesisBuildPaperApi(datas).catch(() => {});
  338. this.fullscreenLoading = false;
  339. if (!res) return;
  340. this.$message.success("组卷成功!");
  341. this.goback();
  342. },
  343. },
  344. };
  345. </script>