generating.vue 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384
  1. <template>
  2. <div class="generating_container">
  3. <el-card>
  4. <div class="header_top">
  5. <div :class="tabActive == 0 ? 'active' : ''" @click="switchTab(0)">
  6. 手动组卷
  7. </div>
  8. <div :class="tabActive == 1 ? 'active' : ''" @click="switchTab(1)">
  9. 智能组卷
  10. </div>
  11. <div :class="tabActive == 2 ? 'active' : ''" @click="switchTab(2)">
  12. 组卷记录
  13. </div>
  14. </div>
  15. <div class="radio_contianer">
  16. <div v-if="tabActive != 2">
  17. <span>选题</span>
  18. <el-radio-group v-model="selectQueId" size="mini" @change="toggleSelect">
  19. <el-radio-button :label="index" v-for="(item, index) in selectQue" :key="index">{{ item }}</el-radio-button>
  20. </el-radio-group>
  21. </div>
  22. <div v-show="tabActive == 2">
  23. <span>科目</span>
  24. <el-radio-group v-model="zujuanSubjectId" size="mini" @change="toggleZujuanSubject">
  25. <el-radio-button :label="null"> 所有 </el-radio-button>
  26. <el-radio-button :label="item.subjectid" v-for="(item, index) in subjectList" :key="index">
  27. {{ item.subjectname }}
  28. </el-radio-button>
  29. </el-radio-group>
  30. </div>
  31. <div v-show="tabActive != 2">
  32. <span>科目</span>
  33. <el-radio-group v-model="form.subjectId" size="mini" @change="toggleSub">
  34. <el-radio-button :label="item.subjectid" v-for="(item, index) in subjectList" :key="index">
  35. {{ item.subjectname }}
  36. </el-radio-button>
  37. </el-radio-group>
  38. </div>
  39. <div v-show="selectQueId == 0 && tabActive != 2">
  40. <span>版本</span>
  41. <el-radio-group v-model="form.editionId" size="mini" @change="toggleEdi">>
  42. <el-radio-button :label="key" v-for="(value, key) in editionList" :key="key">
  43. {{ value }}
  44. </el-radio-button>
  45. </el-radio-group>
  46. </div>
  47. <div v-show="selectQueId == 0 && tabActive != 2">
  48. <span>学册</span>
  49. <el-radio-group v-model="form.gradeId" size="mini" @change="toggleGrade">>
  50. <el-radio-button :label="item.gradeid" v-for="item in gradeList" :key="item.gradeid">
  51. {{ item.gradename }}
  52. </el-radio-button>
  53. </el-radio-group>
  54. </div>
  55. <div v-show="tabActive == 0 && tabActive != 2">
  56. <span>题型</span>
  57. <el-radio-group v-model="form.queTypeName" size="mini" @change="toggleType">
  58. <el-radio-button :label="item" v-for="(item, index) in queTypeList" :key="index">{{ item }}
  59. </el-radio-button>
  60. </el-radio-group>
  61. </div>
  62. </div>
  63. </el-card>
  64. <!-- 主体 -->
  65. <el-container v-show="tabActive != 2">
  66. <el-aside width="284px" style="
  67. padding-bottom: 104px;
  68. background: #fff;
  69. margin-right: 24px;
  70. height: 600px;
  71. overflow: scroll;
  72. overflow-x: hidden;
  73. ">
  74. <div class="aside_header">
  75. <span>CONTACT</span>
  76. <span>{{selectQueId == 0?'章节目录':'知识点目录'}}</span>
  77. </div>
  78. <div class="aside_content" v-show="selectQueId == 0">
  79. <el-tree highlight-current :expand-on-click-node="false" :data="treeList" :props="defaultProps" node-key="$treeNodeId" @node-click="clickChapterNode" ref="chapterTree"></el-tree>
  80. </div>
  81. <div class="aside_content" v-show="selectQueId == 1">
  82. <el-tree highlight-current :expand-on-click-node="false" :data="knowledgeTree" :props="knowledgeProps" node-key="$treeNodeId" @node-click="clickKonwNode" ref="knowTree"></el-tree>
  83. </div>
  84. </el-aside>
  85. <!-- 手动组卷 -->
  86. <el-main style="background: #fff" v-show="tabActive == 0">
  87. <!-- 头部 -->
  88. <div class="main_header">
  89. <div class="left">
  90. <div class="main_tit">{{ title }}</div>
  91. <!-- 暂不支持 -->
  92. <div class="filter" style="display: flex; align-items: center" v-if="false">
  93. <input type="checkbox" /><span>过滤已做题</span>
  94. </div>
  95. </div>
  96. <div class="search_box">
  97. <input v-model="searchText" placeholder="请输入内容" />
  98. <img src="@/assets/images/icon_search2.png" alt="" @click="toggleType(form.queTypeName)" />
  99. </div>
  100. </div>
  101. <!-- 主题内容 -->
  102. <div class="main_con">
  103. <!-- 题目 -->
  104. <div class="paper_questions" id="question_list">
  105. <div class="que_item" v-for="(item, index) in queList" :key="item.id">
  106. <div class="que_content">
  107. <div class="que-content-title">
  108. <div class="index">{{ (pageSize*(pageNum-1)+index+1) }}.</div>
  109. <div v-html="item.title"></div>
  110. </div>
  111. <div class="que-option">
  112. <div v-if="item.optionA">
  113. <span>A</span>
  114. <span v-html="item.optionA"></span>
  115. </div>
  116. <div v-if="item.optionB">
  117. <span>B</span>
  118. <span v-html="item.optionB"></span>
  119. </div>
  120. <div v-if="item.optionC">
  121. <span>C</span>
  122. <span v-html="item.optionC"></span>
  123. </div>
  124. <div v-if="item.optionD">
  125. <span>D</span>
  126. <span v-html="item.optionD"></span>
  127. </div>
  128. </div>
  129. </div>
  130. <div class="que_footer">
  131. <div class="spans">
  132. <span class="id">ID: {{ item.id }}</span>
  133. <span>题型: {{ item.qtpye }}</span>
  134. <span>难度: 一般</span>
  135. </div>
  136. <div class="operation">
  137. <div class="shoucan">
  138. <div v-show="item.collect" @click="toCancelCollectQue(item)" style="display: flex; align-items: center">
  139. <img src="@/assets/images/icon_shoucang_s.png" alt="" style="margin-right: 8px" />
  140. <span>已收藏</span>
  141. </div>
  142. <div v-show="!item.collect" @click="toCollectQue(item)" style="display: flex; align-items: center">
  143. <img src="@/assets/images/icon_shoucang_n.png" style="margin-right: 8px" alt="" />
  144. <span>收藏</span>
  145. </div>
  146. </div>
  147. <div class="jiucuo" @click="$refs.correct.open(item.id)">
  148. <img src="@/assets/images/icon_jiucuo.png" alt="" />
  149. <span>纠错</span>
  150. </div>
  151. <div class="detail" @click="viewDetail(index)">
  152. <img src="@/assets/images/icon_chakan.png" alt="" />
  153. <span>查看详情>></span>
  154. </div>
  155. <div class="addQue">
  156. <el-button @click="addQueCard(item)" icon="el-icon-shopping-cart-2" type="success" plain :disabled="
  157. queCardForm.queList.some((q) => q.id == item.id)
  158. ">加入选题</el-button>
  159. </div>
  160. </div>
  161. </div>
  162. <div class="parse" v-show="item.createTime" v-html="item.answer2"></div>
  163. </div>
  164. <div v-if="queList.length == 0" class="empty-text">
  165. 暂时没有内容
  166. </div>
  167. </div>
  168. </div>
  169. <pagination v-if="total > 0" :total="total" :page.sync="pageNum" :limit.sync="pageSize" @pagination="handleSizeChange" />
  170. </el-main>
  171. <!-- 智能组卷 -->
  172. <el-main v-show="tabActive == 1" style="background: #fff">
  173. <div class="knowPoints">
  174. <div class="tit">
  175. <span>已选知识点({{ tags.length }})</span>
  176. <div class="clear">
  177. <img src="@/assets/images/icon_qingkong.png" alt="" />
  178. <span>清空</span>
  179. </div>
  180. </div>
  181. <el-divider></el-divider>
  182. <!-- tags -->
  183. <div class="tags">
  184. <el-tag v-for="tag in tags" :key="tag.id" closable style="margin-right: 24px; margin-bottom: 24px" @close="handleClose(tag)">
  185. {{ tag.name }}
  186. </el-tag>
  187. </div>
  188. </div>
  189. <div class="que">
  190. <div class="tit">
  191. <span>题型/题量</span>
  192. <div class="clear">
  193. <img src="@/assets/images/icon_qingkong.png" alt="" />
  194. <span>清空</span>
  195. </div>
  196. </div>
  197. <el-divider></el-divider>
  198. <!-- 计数器 -->
  199. <div class="computer">
  200. <div class="computer_item" v-for="(item, index) in queCount" :key="index">
  201. <span class="tit">{{ item.name }}</span>
  202. <el-input-number controls-position="right" @change="handleChange" v-model="item.count" :min="0" :max="item.num" style="margin: 0 8px"></el-input-number>
  203. <span class="select">可选{{ item.num }}道</span>
  204. </div>
  205. </div>
  206. </div>
  207. <!-- 生成试卷 -->
  208. <div style="
  209. display: flex;
  210. justify-content: center;
  211. margin-top: 90px;
  212. margin-bottom: 90px;
  213. ">
  214. <span class="generateExam" @click="getQuestionsByQTypeAndNum">生成试卷</span>
  215. </div>
  216. </el-main>
  217. </el-container>
  218. <!-- 组卷记录 -->
  219. <el-container style="background: #fff; min-height: 500px; display: block" v-show="tabActive == 2">
  220. <el-table :data="examRecord" style="width: 100%" v-loading="tableLoading">
  221. <el-table-column type="index" label="序号" width="50px">
  222. </el-table-column>
  223. <el-table-column prop="subjectName" label="科目"> </el-table-column>
  224. <el-table-column prop="name" label="试卷标题">
  225. <template slot-scope="scope">
  226. <el-link @click="clickEditPaperName(scope.row)"><i class="el-icon-edit"></i>{{ scope.row.name }}</el-link>
  227. </template>
  228. </el-table-column>
  229. <el-table-column prop="remark" label="试卷概要"> </el-table-column>
  230. <el-table-column prop="status" label="状态"> </el-table-column>
  231. <el-table-column prop="createdTime" label="组卷时间"> </el-table-column>
  232. <el-table-column label="操作">
  233. <template slot-scope="scope">
  234. <div>
  235. <span style="color: #47c6a2; margin-right: 16px; cursor: pointer" @click="clickEditPaper(scope.row)">编辑</span>
  236. <span style="color: #ff4e00; margin-right: 16px; cursor: pointer" @click="clickDownloadPaper(scope.row.paperId)">下载</span>
  237. <i class="el-icon-delete table-delete-icon" @click="clickDeletePopup(scope.$index, examRecord)"></i>
  238. </div>
  239. <div v-hasPermi="['front:generatingPaperCenter:saveToPersonResources']" style="color: #608edf; margin-right: 16px; cursor: pointer" @click="clickSendToResource(scope.row.paperId)">
  240. 发送至个人资源库
  241. </div>
  242. </template>
  243. </el-table-column>
  244. <template slot="empty">
  245. <img src="@/assets/images/icon_data.png" />
  246. <span>没有信息</span>
  247. </template>
  248. </el-table>
  249. <el-pagination :page-sizes="[100, 200, 300, 400]" :page-size="100" layout="prev,pager,next,jumper,total,sizes" :total="examRecordTotal">
  250. </el-pagination>
  251. </el-container>
  252. <!-- 试题篮 -->
  253. <div class="queBoxer" v-show="tabActive == 0">
  254. <div class="left">
  255. <div class="tit">
  256. <i class="el-icon-shopping-cart-2" style="margin-bottom: 10px"></i>
  257. <div style="width: 17px; margin-bottom: 10px">试题篮</div>
  258. <span class="count" style="background: #ff4e00; padding: 2px 5px; margin-bottom: 15px">{{ queCardForm.queList.length }}</span>
  259. </div>
  260. <div style="cursor: pointer" @click="show = !show">
  261. <i :class="show ? 'el-icon-arrow-right' : 'el-icon-arrow-left'"></i>
  262. </div>
  263. </div>
  264. <div class="main">
  265. <el-collapse-transition>
  266. <div v-show="show">
  267. <div style="margin-bottom: 30px">
  268. <div style="margin-bottom: 10px">
  269. 共({{ queCardForm.queList.length }})道题
  270. </div>
  271. <div v-for="(value, key) in groupedCardQueList" :key="key + value.length" style="margin-top: 3px; color: #666666">
  272. <span>{{ key }}</span><span> {{ value.length }} </span>道
  273. </div>
  274. </div>
  275. <div>
  276. <p style="
  277. color: #ff4e00;
  278. text-align: right;
  279. border-bottom: 1px solid #dedede;
  280. ">
  281. <span @click="clearQueCard" style="cursor: pointer"> 清空</span>
  282. </p>
  283. </div>
  284. <div class="btn" @click="createdPaper">生成试卷</div>
  285. </div>
  286. </el-collapse-transition>
  287. </div>
  288. </div>
  289. <!-- 弹出警告 -->
  290. <el-dialog title="警告" :visible.sync="dialogVisible" width="30%">
  291. <span>科目不一致,请清空试题篮或选择同一科目</span>
  292. <span slot="footer" class="dialog-footer">
  293. <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
  294. </span>
  295. </el-dialog>
  296. <el-dialog title="修改试卷标题" :visible.sync="dialogPaperNameVisible" width="400px">
  297. <el-input v-model="dialogPaperName" placeholder="请输入试卷标题"></el-input>
  298. <span slot="footer" class="dialog-footer">
  299. <el-button type="primary" @click="savePaperName">确 定</el-button>
  300. </span>
  301. </el-dialog>
  302. <correct-question ref="correct"></correct-question>
  303. </div>
  304. </template>
  305. <script>
  306. import {
  307. smartSubjectList,
  308. smartGradeList,
  309. editionList,
  310. qtBySubject,
  311. treeList,
  312. listByChapter,
  313. knowledgeTree,
  314. listByKnowledge,
  315. countByChapter,
  316. queCollect,
  317. queCancelCollect,
  318. countByKnowledge,
  319. paperRecords,
  320. getQuestionCardList,
  321. deleteQuestionCard,
  322. addToQuestionCard,
  323. listBottoms,
  324. savePaperInfo,
  325. knowByChapter,
  326. deletePaper,
  327. getQuestionsByQTypeAndNum,
  328. getQuestionsByIds,
  329. download,
  330. listCustomerPaperQeustions,
  331. saveToPersonResources,
  332. updateNameById,
  333. } from "@/api/webApi/webQue.js";
  334. import { mapGetters } from "vuex"
  335. import correctQuestion from '../../components/MxPaper/plus/correct-question-dialog.vue';
  336. export default {
  337. components: { correctQuestion },
  338. data() {
  339. return {
  340. dialogVisible: false,
  341. tableLoading: false,
  342. examRecord: [],
  343. tabActive: 0,
  344. searchText: '',
  345. form: {
  346. subjectId: 0,
  347. editionId: 0,
  348. gradeId: 0,
  349. queTypeName: "",
  350. chapterId: 0,
  351. knowledgeId: 0,
  352. knowledgeIds: [],
  353. listBottoms: [],
  354. },
  355. show: false,
  356. // 知识点标签
  357. tags: [],
  358. // 题型/选题数据
  359. queCount: [],
  360. knowledgeProps: {
  361. label: "name",
  362. children: "children",
  363. },
  364. defaultProps: {
  365. label: "name",
  366. children: "children",
  367. },
  368. selectQueId: 0,
  369. selectQue: ["按章节选题", "按知识点选题"],
  370. subjectList: [],
  371. gradeList: [],
  372. editionList: [],
  373. queTypeList: [],
  374. allQueType: "所有",
  375. treeList: [],
  376. queList: [],
  377. title: "",
  378. knowledgeTree: [],
  379. queCardForm: {
  380. queList: [],
  381. },
  382. total: 0,
  383. pageNum: 0,
  384. pageSize: 10,
  385. examRecordTotal: 0,
  386. // 在选题栏里面的题目id集合
  387. topicblueIds: [],
  388. // 修改试卷标题
  389. dialogPaperNameVisible: false,
  390. dialogPager: {},
  391. dialogPaperName: "",
  392. zujuanSubjectId: null,
  393. };
  394. },
  395. computed: {
  396. formQueTypeName() {
  397. return this.form.queTypeName == this.allQueType
  398. ? ""
  399. : this.form.queTypeName;
  400. },
  401. groupedCardQueList() {
  402. let groupedCard = {};
  403. this.queCardForm.queList.forEach((que) => {
  404. if (!groupedCard[que.qtpye]) groupedCard[que.qtpye] = [];
  405. let groupedQueByType = groupedCard[que.qtpye];
  406. groupedQueByType.push(que);
  407. });
  408. return groupedCard;
  409. },
  410. ...mapGetters(["period"])
  411. },
  412. created() {
  413. let query = this.$route.query;
  414. if (query.hasOwnProperty("tabActive")) {
  415. this.switchTab(query.tabActive);
  416. }
  417. this.getSubjectList();
  418. getQuestionCardList().then((res) => {
  419. this.queCardForm.queList = res.data;
  420. this.topicblueIds = res.data.map((item) => {
  421. return item.id;
  422. });
  423. });
  424. },
  425. methods: {
  426. getQuestionsByQTypeAndNum() {
  427. // 智能组卷的生成试卷
  428. if (this.tabActive == 1) {
  429. let queCount = this.queCount;
  430. let req = [];
  431. let allQue = 0;
  432. queCount.forEach((item) => {
  433. if (item.count > 0) {
  434. allQue = allQue + item.count;
  435. req.push({
  436. subjectid: this.form.subjectId,
  437. qtpye: item.name,
  438. diff: 1,
  439. number: item.count,
  440. chapterid: this.form.chapterId,
  441. gradeid: this.form.gradeId,
  442. editionid: this.form.editionId,
  443. knowledgeIds: this.form.knowledgeIds,
  444. });
  445. }
  446. });
  447. if (allQue > 100) {
  448. this.msgError("选题上限是100题哦");
  449. return;
  450. } else if (allQue == 0) {
  451. this.msgError("你还未选择题目");
  452. return;
  453. }
  454. getQuestionsByQTypeAndNum(req).then((res) => {
  455. console.log(res);
  456. localStorage.setItem(
  457. "paperData",
  458. JSON.stringify({
  459. paperTitle: null,
  460. subjectId: this.form.subjectId,
  461. })
  462. );
  463. localStorage.setItem("questionList", JSON.stringify(res.data));
  464. this.$router.push({
  465. path: "/question-center/generatingPaperCenter/paper",
  466. });
  467. });
  468. } else if (this.tabActive == 0) {
  469. localStorage.setItem(
  470. "paperData",
  471. JSON.stringify({
  472. paperTitle: null,
  473. subjectId: this.form.subjectId,
  474. })
  475. );
  476. localStorage.setItem(
  477. "questionList",
  478. JSON.stringify(this.queCardForm.queList)
  479. );
  480. this.$router.push({
  481. path: "/question-center/generatingPaperCenter/paper",
  482. });
  483. }
  484. },
  485. createdPaper() {
  486. if (this.queCardForm.queList && this.queCardForm.queList.length > 0) {
  487. localStorage.setItem(
  488. "paperData",
  489. JSON.stringify({
  490. paperTitle: null,
  491. subjectId: this.form.subjectId,
  492. })
  493. );
  494. localStorage.setItem(
  495. "questionList",
  496. JSON.stringify(this.queCardForm.queList)
  497. );
  498. this.$router.push({
  499. path: "/question-center/generatingPaperCenter/paper",
  500. });
  501. }
  502. },
  503. toSavePaperInfo() {
  504. let req = [
  505. {
  506. subjectid: 1,
  507. qtpye: "选择题",
  508. diff: 1,
  509. number: 1,
  510. chapterid: 1,
  511. knowledgeIds: [1, 2, 3],
  512. },
  513. ];
  514. savePaperInfo(req).then((res) => {
  515. console.log(res);
  516. });
  517. },
  518. switchTab(index) {
  519. this.tabActive = index;
  520. if (this.tabActive == 2) {
  521. this.getPaperRecords();
  522. }
  523. },
  524. clearQueCard() {
  525. if (this.queCardForm.queList.length > 0) {
  526. deleteQuestionCard().then((res) => {
  527. console.log(res);
  528. this.queCardForm.queList = [];
  529. this.msgSuccess("清空成功");
  530. });
  531. }
  532. },
  533. // 查询组卷记录
  534. getPaperRecords() {
  535. paperRecords({
  536. subjectId: this.zujuanSubjectId,
  537. }).then((res) => {
  538. this.examRecordTotal = res.total;
  539. this.examRecord = res.rows;
  540. });
  541. },
  542. /**
  543. * 删除试卷
  544. */
  545. httpDeletePaper(id) {
  546. deletePaper({
  547. paperId: id,
  548. }).then((res) => {
  549. this.getPaperRecords();
  550. this.$message({
  551. type: "success",
  552. message: "删除成功!",
  553. });
  554. });
  555. },
  556. clickDeletePopup(index, data) {
  557. let self = this;
  558. if (data[index] && data[index]["paperId"]) {
  559. this.$confirm("是否删除该试卷?", "提示", {
  560. confirmButtonText: "确定",
  561. cancelButtonText: "取消",
  562. type: "warning",
  563. }).then(() => {
  564. self.httpDeletePaper(data[index]["paperId"]);
  565. });
  566. }
  567. },
  568. clickEditPaper(paper) {
  569. listCustomerPaperQeustions(paper.paperId).then((res) => {
  570. localStorage.setItem(
  571. "paperData",
  572. JSON.stringify({
  573. paperId: paper.paperId,
  574. paperTitle: paper.name,
  575. subjectId: paper.subjectid,
  576. })
  577. );
  578. localStorage.setItem("questionList", JSON.stringify(res.rows));
  579. this.$router.push({
  580. path: "/question-center/generatingPaperCenter/paper",
  581. });
  582. });
  583. },
  584. clickDownloadPaper(paperId) {
  585. download(paperId, this.period);
  586. },
  587. clickSendToResource(paperId) {
  588. this.tableLoading = true;
  589. saveToPersonResources(paperId).then((res) => {
  590. this.tableLoading = false;
  591. this.msgSuccess("发送成功");
  592. });
  593. },
  594. clickEditPaperName(paper) {
  595. this.dialogPager = paper;
  596. this.dialogPaperName = paper.name;
  597. this.dialogPaperNameVisible = true;
  598. },
  599. savePaperName() {
  600. const paperName = this.dialogPaperName?.trim();
  601. if (!paperName) {
  602. this.msgError("试卷标题不能为空");
  603. return;
  604. }
  605. updateNameById(this.dialogPager.paperId, paperName).then((res) => {
  606. this.dialogPager.name = paperName;
  607. this.dialogPaperNameVisible = false;
  608. this.msgSuccess("修改成功");
  609. });
  610. },
  611. // 添加试题
  612. addQueCard(item) {
  613. if (this.queCardForm.queList.length == 0) {
  614. console.log("直接添加");
  615. // 为0直接添加
  616. addToQuestionCard({
  617. questionId: item.id,
  618. }).then((res) => {
  619. this.queCardForm.queList.push(item);
  620. console.log(res);
  621. });
  622. } else {
  623. console.log(this.queCardForm.queList[0]);
  624. // 判断是否是同一个科目下的题目
  625. if (item.subjectid == this.queCardForm.queList[0].subjectid) {
  626. // 是,则添加
  627. addToQuestionCard({
  628. questionId: item.id,
  629. }).then((res) => {
  630. this.queCardForm.queList.push(item);
  631. console.log(res);
  632. console.log("this.queCardForm.queList", this.queCardForm.queList);
  633. });
  634. } else {
  635. // 不是,弹出警告
  636. this.dialogVisible = true;
  637. }
  638. }
  639. },
  640. clickChapterNode(item) {
  641. console.log(item);
  642. this.form.chapterId = item.id;
  643. if (this.tabActive == 0) {
  644. this.title = item.name;
  645. this.getQueBychapter();
  646. } else if (this.tabActive == 1) {
  647. this.getKnowByChapter();
  648. /* this.getCountByChapter(); */
  649. }
  650. },
  651. clickKonwNode(item) {
  652. console.log(item);
  653. this.form.knowledgeId = item.id;
  654. if (this.tabActive == 0) {
  655. this.title = item.name;
  656. this.getQueByKnowleged();
  657. } else if (this.tabActive == 1) {
  658. this.getListBottoms();
  659. }
  660. },
  661. handleClose(tag) {
  662. this.tags.splice(this.tags.indexOf(tag), 1);
  663. console.log(tag);
  664. if (this.selectQueId == 0) {
  665. let index = this.form.knowledgeIds.findIndex((item) => item == tag.id);
  666. this.form.knowledgeIds.splice(index, 1);
  667. this.getCountByChapter();
  668. } else if (this.selectQueId == 1) {
  669. console.log(1111);
  670. let index = this.form.listBottoms.findIndex((item) => item == tag.id);
  671. this.form.listBottoms.splice(index, 1);
  672. this.getCountByKnowledged();
  673. }
  674. },
  675. handleChange(e) { },
  676. // 课程
  677. getSubjectList() {
  678. smartSubjectList().then((res) => {
  679. this.form.subjectId = res.rows[0].subjectid;
  680. this.subjectList = res.rows;
  681. this.getEidtion();
  682. });
  683. },
  684. getQueType() {
  685. qtBySubject({
  686. subjectId: this.form.subjectId,
  687. gradeId: this.form.gradeId,
  688. editionId: this.form.editionId,
  689. }).then((res) => {
  690. const qTypes = [this.allQueType, ...res.data];
  691. this.form.queTypeName = qTypes[0];
  692. this.queTypeList = qTypes;
  693. console.log(res);
  694. });
  695. },
  696. // 获取所有版本
  697. getEidtion() {
  698. editionList({
  699. subjectId: this.form.subjectId,
  700. }).then((res) => {
  701. this.form.editionId = Object.keys(res.data)[0];
  702. this.editionList = res.data;
  703. this.getGrade();
  704. });
  705. },
  706. // 获取所有的学册
  707. getGrade() {
  708. smartGradeList({
  709. subjectId: this.form.subjectId,
  710. editionId: this.form.editionId,
  711. }).then((res) => {
  712. console.log(res);
  713. if (res.data.length > 0) {
  714. this.form.gradeId = res.data[0].gradeid;
  715. }
  716. this.gradeList = res.data;
  717. this.getTree();
  718. this.getQueType();
  719. });
  720. },
  721. // 获取章节树
  722. getTree() {
  723. treeList({
  724. ...this.form,
  725. }).then((res) => {
  726. console.log(res);
  727. this.treeList = res.data;
  728. this.clickChapterNode(this.treeList[0]);
  729. this.$nextTick(() => {
  730. if (!this.$refs.chapterTree) {
  731. return;
  732. }
  733. this.$refs.chapterTree.$el.children[0].classList.add("is_current");
  734. this.$refs.chapterTree.setCurrentKey(this.treeList[0].$treeNodeId);
  735. let d = this.$refs.chapterTree.getCheckedNodes();
  736. });
  737. });
  738. },
  739. // 根据知识点获取题库列表
  740. getQueByKnowleged() {
  741. listByKnowledge({
  742. pageNum: this.pageNum,
  743. pageSize: this.pageSize,
  744. qtpye: this.formQueTypeName,
  745. knowledgeId: this.form.knowledgeId,
  746. subjectId: this.form.subjectId,
  747. searchTerm: this.searchText
  748. }).then((res) => {
  749. console.log(res);
  750. this.total = res.total;
  751. this.queList = res.rows;
  752. this.$nextTick((_) => this.mxGlobal.MathQueue("question_list"));
  753. });
  754. },
  755. handleSizeChange(data) {
  756. this.pageNum = data.page || 1;
  757. this.pageSize = data.limit || 10;
  758. this.getQueBychapter();
  759. },
  760. // 根据章节获取题库列表
  761. getQueBychapter() {
  762. listByChapter({
  763. pageNum: this.pageNum,
  764. pageSize: this.pageSize,
  765. qtpye: this.formQueTypeName,
  766. chapterId: this.form.chapterId,
  767. subjectId: this.form.subjectId,
  768. searchTerm: this.searchText
  769. }).then((res) => {
  770. console.log(res);
  771. this.total = res.total;
  772. this.queList = res.rows;
  773. this.$nextTick((_) => this.mxGlobal.MathQueue("question_list"));
  774. console.log(this.queList);
  775. });
  776. },
  777. // 根据章节获取题库类型和数量
  778. getCountByChapter() {
  779. countByChapter({
  780. chapterId: this.form.chapterId,
  781. subjectId: this.form.subjectId,
  782. editionId: this.form.editionId,
  783. gradeId: this.form.gradeId,
  784. knowledgeIds: this.form.knowledgeIds.join(","),
  785. }).then((res) => {
  786. console.log(res);
  787. this.queCount = res.data;
  788. });
  789. },
  790. // 根据知识点获取题库类型和数量
  791. getCountByKnowledged() {
  792. console.log(this.form.listBottoms);
  793. countByKnowledge({
  794. knowledgeIds: this.form.listBottoms.join(","),
  795. subjectId: this.form.subjectId,
  796. }).then((res) => {
  797. console.log(res);
  798. this.queCount = res.data;
  799. });
  800. },
  801. toggleZujuanSubject(e) {
  802. this.zujuanSubjectId = e;
  803. if (this.tabActive == 2) {
  804. this.getPaperRecords();
  805. return;
  806. }
  807. },
  808. toggleSub(e) {
  809. this.form.subjectId = e;
  810. if (this.selectQueId == 1) {
  811. this.getKnowledges();
  812. return;
  813. }
  814. this.getEidtion();
  815. },
  816. toggleEdi(e) {
  817. this.form.editionId = e;
  818. this.getGrade();
  819. },
  820. toggleGrade(e) {
  821. this.form.gradeId = e;
  822. this.getTree();
  823. this.getQueType();
  824. },
  825. viewDetail(index) {
  826. if (this.queList[index].createTime) {
  827. this.queList[index].createTime = false;
  828. } else {
  829. this.queList[index].createTime = true;
  830. }
  831. },
  832. getKnowledges() {
  833. knowledgeTree({
  834. subjectId: this.form.subjectId,
  835. pharseId: 3,
  836. }).then((res) => {
  837. this.knowledgeTree = res.data;
  838. this.clickKonwNode(res.data[0]);
  839. });
  840. },
  841. toggleSelect(e) {
  842. this.selectQueId = e;
  843. if (e == 1) {
  844. this.getKnowledges();
  845. }
  846. },
  847. toggleType(e) {
  848. this.form.queTypeName = e;
  849. this.pageNum = 1
  850. if (this.selectQueId == 0) {
  851. if (this.tabActive == 0) {
  852. this.getQueBychapter();
  853. } else {
  854. this.getCountByChapter();
  855. }
  856. } else if (this.selectQueId == 1) {
  857. if (this.tabActive == 0) {
  858. this.getQueByKnowleged();
  859. } else {
  860. this.getCountByKnowledged();
  861. }
  862. }
  863. },
  864. // 获取底层知识
  865. getListBottoms() {
  866. listBottoms({
  867. knowledgeId: this.form.knowledgeId,
  868. }).then((res) => {
  869. this.form.listBottoms = res.data.map((item) => {
  870. return item.id;
  871. });
  872. this.tags = res.data;
  873. this.getCountByKnowledged();
  874. });
  875. },
  876. // 根据章节查找知识点
  877. getKnowByChapter() {
  878. knowByChapter({
  879. chapterId: this.form.chapterId,
  880. gradeId: this.form.gradeId,
  881. subjectId: this.form.subjectId,
  882. }).then((res) => {
  883. let arr = [];
  884. for (let item of res.data) {
  885. arr.push(item.id);
  886. }
  887. this.form.knowledgeIds = arr;
  888. this.tags = res.data;
  889. this.getCountByChapter();
  890. });
  891. },
  892. toCollectQue(item) {
  893. queCollect({
  894. questionId: item.id,
  895. }).then((res) => {
  896. item.collect = !item.collect;
  897. this.msgSuccess("收藏成功");
  898. console.log(res);
  899. });
  900. },
  901. toCancelCollectQue(item) {
  902. queCancelCollect({
  903. questionId: item.id,
  904. }).then((res) => {
  905. item.collect = !item.collect;
  906. this.msgSuccess("取消收藏成功");
  907. console.log(res);
  908. });
  909. },
  910. },
  911. };
  912. </script>
  913. <style scoped>
  914. .generating_container {
  915. padding: 20px;
  916. background: #f7f7f7;
  917. }
  918. .active {
  919. color: #47c6a2;
  920. }
  921. .active::after {
  922. content: "";
  923. width: 100%;
  924. height: 4px;
  925. position: absolute;
  926. background: #47c6a2;
  927. left: 0;
  928. transform: translateY(50%);
  929. bottom: 0;
  930. }
  931. .header_top {
  932. display: flex;
  933. border-bottom: 1px solid #b7b7b7;
  934. margin-bottom: 20px;
  935. }
  936. .header_top > div {
  937. position: relative;
  938. flex: 1;
  939. text-align: center;
  940. padding: 30px 0;
  941. }
  942. .header_top > div:hover {
  943. color: #47c6a2;
  944. }
  945. .header_top > div:hover::after {
  946. content: "";
  947. width: 100%;
  948. height: 4px;
  949. position: absolute;
  950. background: #47c6a2;
  951. left: 0;
  952. transform: translateY(50%);
  953. bottom: 0;
  954. }
  955. .radio_contianer .el-radio-button {
  956. margin-right: 8px;
  957. }
  958. .radio_contianer > div {
  959. margin-bottom: 16px;
  960. display: flex;
  961. justify-content: flex-start;
  962. align-items: center;
  963. }
  964. .radio_contianer > div > span {
  965. flex-shrink: 0;
  966. font-size: 14px;
  967. font-family: PingFangSC-Regular, PingFang SC;
  968. font-weight: 400;
  969. color: #232323;
  970. line-height: 20px;
  971. height: 20px;
  972. width: 50px;
  973. }
  974. .el-card {
  975. margin-bottom: 20px;
  976. }
  977. .el-aside {
  978. margin-bottom: 0;
  979. padding: 24px 0 0 16px;
  980. }
  981. .aside_header {
  982. display: flex;
  983. flex-direction: column;
  984. justify-content: left;
  985. }
  986. .aside_header > span:first-child {
  987. width: 173px;
  988. height: 27px;
  989. background: -webkit-gradient(
  990. linear,
  991. left top,
  992. left bottom,
  993. from(#ffffff),
  994. to(#47c6a2)
  995. );
  996. background: linear-gradient(180deg, #ffffff 0%, #47c6a2 100%);
  997. opacity: 0.5;
  998. }
  999. .aside_header > span:last-child {
  1000. margin-bottom: 20px;
  1001. }
  1002. .aside_header > span {
  1003. margin-top: 5px;
  1004. width: 84px;
  1005. height: 22px;
  1006. font-size: 16px;
  1007. font-family: PingFangSC-Medium, PingFang SC;
  1008. font-weight: 500;
  1009. color: #343434;
  1010. line-height: 22px;
  1011. }
  1012. .el-main {
  1013. padding: 37px 28px 0 28px;
  1014. }
  1015. .main_header {
  1016. display: flex;
  1017. align-items: center;
  1018. justify-content: space-between;
  1019. margin-bottom: 20px;
  1020. }
  1021. .main_header .main_tit {
  1022. font-size: 16px;
  1023. font-weight: 500;
  1024. color: #47c6a2;
  1025. line-height: 22px;
  1026. margin-right: 64px;
  1027. }
  1028. .main_header .filter {
  1029. font-weight: 400;
  1030. color: #4c4c4c;
  1031. line-height: 20px;
  1032. }
  1033. .main_header .left {
  1034. display: flex;
  1035. }
  1036. .search_box {
  1037. display: flex;
  1038. flex-direction: row;
  1039. align-items: center;
  1040. justify-content: flex-end;
  1041. position: relative;
  1042. margin-right: 20px;
  1043. }
  1044. .search_box img {
  1045. position: absolute;
  1046. right: 20px;
  1047. cursor: pointer;
  1048. top: 6px;
  1049. }
  1050. .search_box input {
  1051. background: #f7f7ff;
  1052. border-radius: 20px;
  1053. border: 1px solid #c6cbf5;
  1054. outline: none;
  1055. width: 340px;
  1056. height: 32px;
  1057. padding-left: 24px;
  1058. }
  1059. .que_item {
  1060. border-radius: 1px;
  1061. border: 1px solid #dedede;
  1062. margin-bottom: 8px;
  1063. }
  1064. .que_content {
  1065. padding: 12px 24px 0 33px;
  1066. font-size: 14px;
  1067. font-family: PingFangSC-Medium, PingFang SC;
  1068. font-weight: 500;
  1069. color: #4c4c4c;
  1070. line-height: 27px;
  1071. margin-bottom: 40px;
  1072. }
  1073. .que-content-title {
  1074. font-size: 14px;
  1075. display: flex;
  1076. }
  1077. .que-option {
  1078. line-height: 40px;
  1079. }
  1080. .que-option span {
  1081. margin-right: 5px;
  1082. }
  1083. .que_footer {
  1084. border-top: 1px solid #dedede;
  1085. padding-left: 33px;
  1086. overflow: hidden;
  1087. padding-bottom: 23px;
  1088. padding-top: 21px;
  1089. }
  1090. .que_footer .spans {
  1091. float: left;
  1092. font-size: 12px;
  1093. font-family: PingFangSC-Regular, PingFang SC;
  1094. font-weight: 400;
  1095. color: #979797;
  1096. line-height: 20px;
  1097. }
  1098. .que_footer .spans > span {
  1099. margin-right: 20px;
  1100. }
  1101. .operation {
  1102. display: flex;
  1103. align-items: center;
  1104. font-size: 14px;
  1105. font-family: PingFangSC-Regular, PingFang SC;
  1106. font-weight: 400;
  1107. color: #47c6a2;
  1108. line-height: 20px;
  1109. float: right;
  1110. }
  1111. .operation > div {
  1112. display: flex;
  1113. align-items: center;
  1114. cursor: pointer;
  1115. }
  1116. .operation .shoucan {
  1117. margin-right: 46px;
  1118. }
  1119. .operation .jiucuo {
  1120. color: #ff4e00;
  1121. margin-right: 32px;
  1122. }
  1123. .operation .detail span {
  1124. border-radius: 1px;
  1125. border-bottom: 1px solid #47c6a2;
  1126. }
  1127. .operation .detail {
  1128. margin-right: 32px;
  1129. }
  1130. .operation > div > img {
  1131. margin-right: 10px;
  1132. }
  1133. .knowPoints .tags {
  1134. margin-top: 24px;
  1135. margin-bottom: 72px;
  1136. }
  1137. .knowPoints .tit {
  1138. margin-bottom: 16px;
  1139. overflow: hidden;
  1140. color: #47c6a2;
  1141. }
  1142. .knowPoints .clear {
  1143. float: right;
  1144. margin-right: 40px;
  1145. }
  1146. .knowPoints .clear img {
  1147. margin-right: 16px;
  1148. }
  1149. .que .tit {
  1150. margin-bottom: 16px;
  1151. overflow: hidden;
  1152. color: #47c6a2;
  1153. }
  1154. .que .clear {
  1155. float: right;
  1156. margin-right: 40px;
  1157. }
  1158. .que .clear img {
  1159. margin-right: 16px;
  1160. }
  1161. .el-divider {
  1162. margin: 0;
  1163. background: #47c6a2;
  1164. }
  1165. .computer {
  1166. margin-top: 24px;
  1167. display: flex;
  1168. justify-content: flex-start;
  1169. flex-wrap: wrap;
  1170. }
  1171. .computer .computer_item {
  1172. flex: 33% 0 0;
  1173. margin-bottom: 32px;
  1174. }
  1175. .computer .computer_item .tit {
  1176. height: 20px;
  1177. font-size: 14px;
  1178. font-family: PingFangSC-Regular, PingFang SC;
  1179. font-weight: 400;
  1180. color: #343434;
  1181. line-height: 20px;
  1182. }
  1183. .computer .computer_item .select {
  1184. width: 58px;
  1185. height: 17px;
  1186. font-size: 12px;
  1187. font-family: PingFangSC-Regular, PingFang SC;
  1188. font-weight: 400;
  1189. color: #969696;
  1190. line-height: 17px;
  1191. }
  1192. .parse {
  1193. padding: 20px;
  1194. }
  1195. ::-webkit-scrollbar {
  1196. width: 4px;
  1197. }
  1198. ::-webkit-scrollbar-thumb {
  1199. -webkit-box-shadow: inset 0 0 1px rgba(136, 136, 136, 0.3);
  1200. background-color: rgb(238, 241, 245);
  1201. }
  1202. .queBoxer {
  1203. display: flex;
  1204. position: fixed;
  1205. right: 0;
  1206. top: 50%;
  1207. transform: translateY(-50%);
  1208. }
  1209. .queBoxer .main {
  1210. border-top: 2px solid #47c6a2;
  1211. padding: 10px 0;
  1212. border-bottom: 2px solid #47c6a2;
  1213. background: #fff;
  1214. }
  1215. .queBoxer > div > div {
  1216. padding: 0 10px;
  1217. }
  1218. .queBoxer .left {
  1219. padding: 10px;
  1220. background: #47c6a2;
  1221. color: white;
  1222. display: flex;
  1223. flex-direction: column;
  1224. justify-content: space-between;
  1225. align-items: center;
  1226. }
  1227. .queBoxer .main .btn {
  1228. background: #47c6a2;
  1229. color: white;
  1230. border-radius: 4px;
  1231. padding: 4px;
  1232. cursor: pointer;
  1233. margin: 5px 10px;
  1234. text-align: center;
  1235. }
  1236. .queBoxer .left .tit {
  1237. display: flex;
  1238. writing-mode: lr-tb;
  1239. align-items: center;
  1240. flex-direction: column;
  1241. justify-content: space-between;
  1242. }
  1243. .generateExam {
  1244. padding: 14px 29px;
  1245. background: #47c6a2;
  1246. border-radius: 4px;
  1247. cursor: pointer;
  1248. color: white;
  1249. }
  1250. /deep/.el-button--success.is-plain.is-disabled {
  1251. background-color: #ffffff;
  1252. border-color: #e6ebf5;
  1253. color: #c0c4cc;
  1254. }
  1255. /deep/ .el-tree-node__content {
  1256. padding-top: 6px;
  1257. padding-bottom: 6px;
  1258. height: 32px;
  1259. font-size: 14px;
  1260. font-family: PingFangSC-Medium, PingFang SC;
  1261. font-weight: 500;
  1262. color: #343434;
  1263. line-height: 20px;
  1264. }
  1265. .generating_container >>> .el-radio-button__inner {
  1266. border-left: 1px solid #dcdfe6;
  1267. }
  1268. .generating_container >>> .radio_contianer .el-radio-button .el-radio-button__inner {
  1269. border-radius: 16px;
  1270. border-bottom: 5px;
  1271. }
  1272. .generating_container >>> .split_page .el-pager > li {
  1273. border-radius: 50%;
  1274. }
  1275. .generating_container >>> .el-tree-node {
  1276. padding-left: 16px;
  1277. }
  1278. .generating_container >>> .el-tree-node__expand-icon.expanded {
  1279. content: "";
  1280. }
  1281. .generating_container >>> .el-tree-node__content > .el-tree-node__expand-icon {
  1282. padding: 6px;
  1283. /* position: absolute; */
  1284. right: 16px;
  1285. }
  1286. .generating_container >>> .radio_contianer .is-active .el-radio-button__inner{
  1287. border-left: none;
  1288. }
  1289. .empty-text {
  1290. margin-top: 150px;
  1291. text-align: center;
  1292. color: #ccc;
  1293. }
  1294. .generating_container >>>.el-input-number.is-controls-right .el-input-number__decrease {
  1295. width: 16px;
  1296. }
  1297. .generating_container >>>.el-input-number.is-controls-right[class*="medium"] [class*="increase"],
  1298. .generating_container >>>.el-input-number.is-controls-right[class*="medium"] [class*="decrease"] {
  1299. width: 16px;
  1300. }
  1301. .generating_container >>>.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
  1302. color: #47c6a2;
  1303. background: #ffffff;
  1304. }
  1305. .generating_container >>>.table-delete-icon {
  1306. cursor: pointer;
  1307. }
  1308. </style>