drawerItem.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. <!-- 固定选题 Drawer 内容 -->
  2. <template>
  3. <div class="drawerItem-container">
  4. <div class="left-max-big-box">
  5. <div class="left-title-p">{{titleName}}</div>
  6. <div class="page-form-title-box">
  7. <el-form :model="leftQueryParams" class="form-box" ref="queryForm"
  8. :inline="true" style="width:100%;">
  9. <el-form-item label="" prop="deptId">
  10. <el-cascader
  11. style="width: 180px"
  12. v-model="leftQueryParams.deptId"
  13. :options="optionListA"
  14. :props="{
  15. emitPath:false,
  16. checkStrictly: true,
  17. value: 'deptId',
  18. label: 'deptName',
  19. children: 'child',
  20. }"
  21. :show-all-levels="false"
  22. filterable
  23. placeholder="来源"
  24. ></el-cascader>
  25. </el-form-item>
  26. <el-form-item label="" prop="questionType">
  27. <el-select v-model="leftQueryParams.questionType" placeholder="题型" style="width: 140px">
  28. <el-option
  29. v-for="dict in optionListB"
  30. :key="dict.value"
  31. :label="dict.label"
  32. :value="dict.value"
  33. />
  34. </el-select>
  35. </el-form-item>
  36. <el-form-item label="" prop="difficulty">
  37. <el-select v-model="leftQueryParams.difficulty" placeholder="难度" style="width: 140px">
  38. <el-option
  39. v-for="dict in optionListC"
  40. :key="dict.value"
  41. :label="dict.label"
  42. :value="dict.value"
  43. />
  44. </el-select>
  45. </el-form-item>
  46. <el-form-item label="" prop="questionContent">
  47. <el-input
  48. maxLength="30"
  49. v-model="leftQueryParams.questionContent"
  50. placeholder="搜索试题"
  51. style="width: 140px"
  52. />
  53. </el-form-item>
  54. <p class="page-inquire-common-style-button" @click="leftHandleQuery">查询</p>
  55. <p class="page-reset-common-style-button" @click="leftResetQuery">重置</p>
  56. </el-form>
  57. </div>
  58. <div class="page-content-box">
  59. <el-table class="table-box" border :data="leftDataList"
  60. ref="leftMultipleTable" :row-key="leftGetRowKey" @selection-change="leftHandleSelectionChange">
  61. <el-table-column type="selection" width="55" :reserve-selection="true"></el-table-column>
  62. <el-table-column label="题干" prop="questionContent" show-overflow-tooltip>
  63. <template slot-scope="scope">
  64. <span style="color:#0183fa;cursor: pointer;" @click="tableButton(2,scope.row)">{{ cleanRichText(scope.row.questionContent) }}</span>
  65. </template>
  66. </el-table-column>
  67. <el-table-column label="题型" prop="questionType" width="140" show-overflow-tooltip>
  68. <template slot-scope="scope">
  69. <span>{{ scope.row.questionType == 1?'单选题':(scope.row.questionType == 2?'多选题':(scope.row.questionType == 3?'判断题':'')) }}</span>
  70. </template>
  71. </el-table-column>
  72. <el-table-column label="难度" prop="content" width="140" show-overflow-tooltip>
  73. <template slot-scope="scope">
  74. <span>{{ scope.row.difficulty == 1?'简单':(scope.row.difficulty == 2?'一般':(scope.row.difficulty == 3?'较难':(scope.row.difficulty == 4?'极难':''))) }}</span>
  75. </template>
  76. </el-table-column>
  77. </el-table>
  78. <pagination :page-sizes="[20, 30, 40, 50]"
  79. v-show="leftTotal>0"
  80. :total="leftTotal"
  81. :page.sync="leftQueryParams.page"
  82. :limit.sync="leftQueryParams.pageSize"
  83. @pagination="leftGetList"
  84. />
  85. </div>
  86. </div>
  87. <div class="center-max-big-box">
  88. <p></p>
  89. <p class="el-icon-arrow-right" @click="addButton()"></p>
  90. <p class="el-icon-arrow-left" @click="delButton()"></p>
  91. <p></p>
  92. </div>
  93. <div class="right-max-big-box">
  94. <div class="right-title-box">
  95. <p>总题目数:{{maxNum}}</p>
  96. <p>总分:{{maxScore}}</p>
  97. <!--<p>还需设置 {{gapScore}} 分的题目</p>-->
  98. </div>
  99. <div class="page-form-title-box">
  100. <el-form :model="rightQueryParams" class="form-box" ref="queryForm"
  101. :inline="true" style="width:100%;">
  102. <el-form-item label="" prop="deptId">
  103. <el-cascader
  104. style="width: 180px"
  105. v-model="rightQueryParams.deptId"
  106. :options="optionListA"
  107. :props="{
  108. emitPath:false,
  109. checkStrictly: true,
  110. value: 'deptId',
  111. label: 'deptName',
  112. children: 'child',
  113. }"
  114. :show-all-levels="false"
  115. filterable
  116. placeholder="来源"
  117. ></el-cascader>
  118. </el-form-item>
  119. <el-form-item label="" prop="questionType">
  120. <el-select v-model="rightQueryParams.questionType" placeholder="题型" style="width: 140px">
  121. <el-option
  122. v-for="dict in optionListB"
  123. :key="dict.value"
  124. :label="dict.label"
  125. :value="dict.value"
  126. />
  127. </el-select>
  128. </el-form-item>
  129. <el-form-item label="" prop="difficulty">
  130. <el-select v-model="rightQueryParams.difficulty" placeholder="难度" style="width: 140px">
  131. <el-option
  132. v-for="dict in optionListC"
  133. :key="dict.value"
  134. :label="dict.label"
  135. :value="dict.value"
  136. />
  137. </el-select>
  138. </el-form-item>
  139. <el-form-item label="" prop="questionContent">
  140. <el-input
  141. maxLength="30"
  142. v-model="rightQueryParams.questionContent"
  143. placeholder="搜索试题"
  144. style="width: 140px"
  145. />
  146. </el-form-item>
  147. <p class="page-inquire-common-style-button" @click="rightHandleQuery">查询</p>
  148. <p class="page-reset-common-style-button" @click="rightResetQuery">重置</p>
  149. </el-form>
  150. </div>
  151. <div class="page-content-box">
  152. <el-table class="table-box" border :data="rightDataList"
  153. ref="rightMultipleTable" :row-key="rightGetRowKey" @selection-change="rightHandleSelectionChange">
  154. <el-table-column type="selection" width="55" :reserve-selection="true"></el-table-column>
  155. <el-table-column label="题干" prop="questionContent" show-overflow-tooltip>
  156. <template slot-scope="scope">
  157. <span style="color:#0183fa;cursor: pointer;" @click="tableButton(2,scope.row)">{{ cleanRichText(scope.row.questionContent) }}</span>
  158. </template>
  159. </el-table-column>
  160. <el-table-column label="题型" prop="questionType" width="140" show-overflow-tooltip>
  161. <template slot-scope="scope">
  162. <span>{{ scope.row.questionType == 1?'单选题':(scope.row.questionType == 2?'多选题':(scope.row.questionType == 3?'判断题':'')) }}</span>
  163. </template>
  164. </el-table-column>
  165. <el-table-column label="难度" prop="content" width="140" show-overflow-tooltip>
  166. <template slot-scope="scope">
  167. <span>{{ scope.row.difficulty == 1?'简单':(scope.row.difficulty == 2?'一般':(scope.row.difficulty == 3?'较难':(scope.row.difficulty == 4?'极难':''))) }}</span>
  168. </template>
  169. </el-table-column>
  170. </el-table>
  171. <pagination :page-sizes="[20, 30, 40, 50]"
  172. v-show="rightTotal>0"
  173. :total="rightTotal"
  174. :page.sync="rightQueryParams.page"
  175. :limit.sync="rightQueryParams.pageSize"
  176. @pagination="rightGetList"
  177. />
  178. </div>
  179. </div>
  180. <div class="button-position-box">
  181. <p class="button-1" @click="outButton()">返回</p>
  182. <p class="button-2" @click="resetButton()">重置</p>
  183. <p class="button-3" @click="saveButton()">保存</p>
  184. </div>
  185. </div>
  186. </template>
  187. <script>
  188. import {
  189. systemDeptCurrentDept,examElQuestionBankList,
  190. } from "@/api/safetyEducationExaminationNew/index";
  191. export default {
  192. name: 'drawerItem',
  193. props: {
  194. drawerPropsData:{},
  195. },
  196. data() {
  197. return {
  198. titleName:'',
  199. knowledgePointId:'',
  200. maxNum:0,
  201. maxScore:0,
  202. questionScore:0,
  203. checkIndex:null,
  204. // gapScore:0,
  205. optionListA:[],
  206. optionListB:[{value:1,label:'单选'},{value:2,label:'多选'},{value:3,label:'判断'}],
  207. optionListC:[{value:1,label:'简单'},{value:2,label:'一般'},{value:3,label:'较难'},{value:4,label:'极难'}],
  208. leftQueryParams:{
  209. page:1,
  210. pageSize:20,
  211. questionContent:'',
  212. difficulty:null,
  213. questionType:null,
  214. deptId:null,
  215. },
  216. leftDataList:[],
  217. leftTotal:0,
  218. rightQueryParams:{
  219. page:1,
  220. pageSize:20,
  221. questionContent:'',
  222. difficulty:null,
  223. questionType:null,
  224. deptId:null,
  225. },
  226. rightDataList:[],
  227. rightTotal:0,
  228. //过滤/显示的题目ids
  229. questionIds:[],
  230. leftMultipleSelection:[],
  231. rightMultipleSelection:[],
  232. }
  233. },
  234. mounted() {
  235. this.$set(this,'titleName',this.drawerPropsData.name);
  236. this.$set(this,'knowledgePointId',this.drawerPropsData.knowledgePointId);
  237. this.$set(this,'questionScore',this.drawerPropsData.questionScore);
  238. this.$set(this,'checkIndex',this.drawerPropsData.index);
  239. this.$set(this,'questionIds',this.drawerPropsData.questionIds?this.drawerPropsData.questionIds:[]);
  240. this.$set(this,'maxScore',this.accMul(this.drawerPropsData.questionScore,this.drawerPropsData.questionIds.length));
  241. this.leftGetList()
  242. this.rightGetList()
  243. this.systemDeptCurrentDept()
  244. },
  245. methods: {
  246. addButton(){
  247. let self = this;
  248. if(!self.leftMultipleSelection[0]){
  249. this.msgError('请勾选左侧题目')
  250. return
  251. }
  252. if(self.leftMultipleSelection.length + this.questionIds.length > 1000){
  253. this.msgError('最多添加1000道题目')
  254. return
  255. }
  256. let list = [];
  257. for(let i=0;i<self.leftMultipleSelection.length;i++){
  258. list.push(self.leftMultipleSelection[i].id)
  259. }
  260. this.$set(this,'questionIds',JSON.parse(JSON.stringify([...this.questionIds,...list])));
  261. this.$set(this,'leftMultipleSelection',[]);
  262. this.$set(this,'rightMultipleSelection',[]);
  263. this.$refs.leftMultipleTable.clearSelection();
  264. this.$refs.rightMultipleTable.clearSelection();
  265. this.leftHandleQuery();
  266. this.rightHandleQuery();
  267. },
  268. delButton(){
  269. let self = this;
  270. if(!self.rightMultipleSelection[0]){
  271. this.msgError('请勾选右侧题目')
  272. return
  273. }
  274. let list = [];
  275. for(let i=0;i<self.rightMultipleSelection.length;i++){
  276. list.push(self.rightMultipleSelection[i].id)
  277. }
  278. this.$set(this,'questionIds',JSON.parse(JSON.stringify(this.questionIds.filter(item => !list.includes(item)))));
  279. this.$set(this,'leftMultipleSelection',[]);
  280. this.$set(this,'rightMultipleSelection',[]);
  281. this.$refs.leftMultipleTable.clearSelection();
  282. this.$refs.rightMultipleTable.clearSelection();
  283. this.leftHandleQuery();
  284. this.rightHandleQuery();
  285. },
  286. //查询按钮
  287. leftHandleQuery(){
  288. this.$set(this.leftQueryParams,'page',1);
  289. this.leftGetList();
  290. },
  291. //重置按钮
  292. leftResetQuery(){
  293. this.$set(this,'leftQueryParams',{
  294. page:1,
  295. pageSize:20,
  296. questionContent:'',
  297. difficulty:null,
  298. questionType:null,
  299. deptId:null,
  300. });
  301. this.leftGetList();
  302. },
  303. leftGetList(){
  304. let obj = JSON.parse(JSON.stringify(this.leftQueryParams))
  305. obj.knowledgePointId = this.knowledgePointId;
  306. obj.excludeQuestionIds = this.questionIds;
  307. examElQuestionBankList(obj).then(response => {
  308. this.$set(this,'leftDataList',response.data.records);
  309. this.$set(this,'leftTotal',response.data.total);
  310. });
  311. },
  312. leftGetRowKey(row) {
  313. return row.id;
  314. },
  315. leftHandleSelectionChange(val) {
  316. this.leftMultipleSelection = val;
  317. },
  318. //查询按钮
  319. rightHandleQuery(){
  320. this.$set(this.rightQueryParams,'page',1);
  321. this.rightGetList();
  322. },
  323. //重置按钮
  324. rightResetQuery(){
  325. this.$set(this,'rightQueryParams',{
  326. page:1,
  327. pageSize:20,
  328. questionContent:'',
  329. difficulty:null,
  330. questionType:null,
  331. deptId:null,
  332. });
  333. this.rightGetList();
  334. },
  335. rightGetList(){
  336. if(!this.questionIds[0]){
  337. this.$set(this,'rightDataList',[]);
  338. this.$set(this,'rightTotal',0);
  339. this.$set(this,'maxScore',0);
  340. return
  341. }
  342. let obj = JSON.parse(JSON.stringify(this.rightQueryParams))
  343. obj.knowledgePointId = this.knowledgePointId;
  344. obj.includeQuestionIds = this.questionIds;
  345. examElQuestionBankList(obj).then(response => {
  346. this.$set(this,'rightDataList',response.data.records);
  347. this.$set(this,'rightTotal',response.data.total);
  348. this.$set(this,'maxNum',response.data.total);
  349. console.log('this.drawerPropsData.questionScore',this.drawerPropsData.questionScore)
  350. console.log('response.data.total',response.data.total)
  351. this.$set(this,'maxScore',this.accMul(this.drawerPropsData.questionScore,response.data.total));
  352. });
  353. },
  354. rightGetRowKey(row) {
  355. return row.id;
  356. },
  357. rightHandleSelectionChange(val) {
  358. this.rightMultipleSelection = val;
  359. },
  360. //学院列表
  361. systemDeptCurrentDept(){
  362. systemDeptCurrentDept({}).then(response => {
  363. const list = response.data || [];
  364. this.formatTreeData(list);
  365. this.$set(this,'optionListA',list);
  366. });
  367. },
  368. //清洗富文本
  369. cleanRichText(htmlStr, maxLength = 50) {
  370. if (!htmlStr) return '';
  371. const tempDiv = document.createElement('div');
  372. tempDiv.innerHTML = htmlStr;
  373. let text = tempDiv.textContent || tempDiv.innerText || '';
  374. text = text.replace(/\s+/g, ' ').trim();
  375. if (maxLength && text.length > maxLength) {
  376. return text.substring(0, maxLength) + '...';
  377. }
  378. return text;
  379. },
  380. //返回
  381. outButton(){
  382. this.$parent.$parent.drawerReturnButton();
  383. },
  384. //重置
  385. resetButton(){
  386. },
  387. //保存
  388. saveButton(){
  389. if(!this.questionIds[0]){
  390. this.msgError('请选择题目')
  391. return
  392. }
  393. let obj = {
  394. index:this.checkIndex,
  395. questionIds:this.questionIds
  396. }
  397. this.$parent.$parent.drawerConfirmButton(JSON.parse(JSON.stringify(obj)))
  398. },
  399. //乘法
  400. accMul(arg1,arg2){
  401. var m=0,s1=arg1.toString(),s2=arg2.toString();
  402. try{m+=s1.split(".")[1].length}catch(e){}
  403. try{m+=s2.split(".")[1].length}catch(e){}
  404. return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)
  405. },
  406. },
  407. }
  408. </script>
  409. <style scoped lang="scss">
  410. .drawerItem-container {
  411. flex:1;
  412. display: flex;
  413. overflow: hidden;
  414. .left-max-big-box{
  415. flex:1;
  416. display: flex;
  417. flex-direction: column;
  418. overflow: hidden;
  419. border-right:1px solid #dedede;
  420. .left-title-p{
  421. height:50px;
  422. border-bottom:1px solid #dedede;
  423. line-height:50px;
  424. padding: 0 20px;
  425. color:#0183fa;
  426. font-size:16px;
  427. }
  428. }
  429. .center-max-big-box{
  430. width:60px;
  431. display: flex;
  432. flex-direction: column;
  433. overflow: hidden;
  434. p:nth-child(1){
  435. flex: 1;
  436. }
  437. p:nth-child(2){
  438. width:40px;
  439. height:40px;
  440. line-height:40px;
  441. text-align: center;
  442. background-color: #0183fa;
  443. color:#fff;
  444. border-radius:50%;
  445. margin:0 0 0 10px;
  446. cursor: pointer;
  447. }
  448. p:nth-child(3){
  449. width:40px;
  450. height:40px;
  451. line-height:40px;
  452. text-align: center;
  453. background-color: #0183fa;
  454. color:#fff;
  455. border-radius:50%;
  456. margin:40px 0 0 10px;
  457. cursor: pointer;
  458. }
  459. p:nth-child(4){
  460. flex: 1;
  461. }
  462. }
  463. .right-max-big-box{
  464. flex:1;
  465. display: flex;
  466. flex-direction: column;
  467. overflow: hidden;
  468. border-left:1px solid #dedede;
  469. .right-title-box{
  470. display: flex;
  471. height:50px;
  472. border-bottom:1px solid #dedede;
  473. line-height:50px;
  474. padding: 0 20px;
  475. p{
  476. margin-right:40px;
  477. color:#0183fa;
  478. font-size:14px;
  479. font-weight:700;
  480. }
  481. }
  482. }
  483. .button-position-box{
  484. position: absolute;
  485. top:0;
  486. right:10px;
  487. display: flex;
  488. .button-1{
  489. border:1px solid #999;
  490. color:#999;
  491. font-size:14px;
  492. text-align: center;
  493. line-height:40px;
  494. height:40px;
  495. width:80px;
  496. border-radius:4px;
  497. margin:10px 10px 0 0;
  498. cursor: pointer;
  499. }
  500. .button-2{
  501. border:1px solid #999;
  502. background-color: #999;
  503. color:#fff;
  504. font-size:14px;
  505. text-align: center;
  506. line-height:40px;
  507. height:40px;
  508. width:80px;
  509. border-radius:4px;
  510. margin:10px 10px 0 0;
  511. cursor: pointer;
  512. }
  513. .button-3{
  514. border:1px solid #0183fa;
  515. background-color: #0183fa;
  516. color:#fff;
  517. font-size:14px;
  518. text-align: center;
  519. line-height:40px;
  520. height:40px;
  521. width:80px;
  522. border-radius:4px;
  523. margin:10px 0 0 0;
  524. cursor: pointer;
  525. }
  526. }
  527. }
  528. </style>