addExamPage.vue 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148
  1. <!--新增考试-->
  2. <template>
  3. <div class="addExamPage">
  4. <p class="title-p">组卷信息</p>
  5. <el-form ref="form" :model="form" label-width="100px" :rules="rules">
  6. <el-form-item label="适用范围" prop="scopeType" label-width="100px" style="margin-top:10px;">
  7. <template>
  8. <el-radio v-model="form.scopeType" label="1">安全准入考试</el-radio>
  9. <el-radio v-model="form.scopeType" label="2">负面清单考试</el-radio>
  10. <el-radio v-model="form.scopeType" label="3">黑名单考试</el-radio>
  11. <el-radio v-model="form.scopeType" label="4">模拟考试</el-radio>
  12. </template>
  13. </el-form-item>
  14. <el-form-item label="组题方式" prop="joinType" label-width="100px">
  15. <template>
  16. <el-radio-group v-model="form.joinType" @change="joinTypeClick">
  17. <el-radio :label="1">自动组题</el-radio>
  18. <el-radio :label="2">手动组题</el-radio>
  19. </el-radio-group>
  20. </template>
  21. </el-form-item>
  22. <!--自动组题-->
  23. <div class="info-box" v-if="form.joinType == 1">
  24. <div class="info-left-box">
  25. <div v-for="(bigItem,index) in form.repoList"
  26. style="margin-bottom:88px;">
  27. <el-form-item label="题目分类" :prop="'repoList.'+ index +'.classifyId'" :rules="rules.classifyId" label-width="100px" style="width: 420px;">
  28. <el-select
  29. v-model="bigItem.classifyId"
  30. placeholder="请选择分类"
  31. :rules="bigItem.rules">
  32. <el-option
  33. v-for="item in repoOption"
  34. :key="item.id"
  35. :label="item.title"
  36. :value="item.id">
  37. </el-option>
  38. </el-select>
  39. </el-form-item>
  40. </div>
  41. </div>
  42. <div class="info-right-box">
  43. <div class="info-right-max-box"
  44. style="position: relative;"
  45. v-for="(item,index) in form.repoList">
  46. <i v-if="index!=0" class="el-icon-close del-o" @click="delRepo(index)"></i>
  47. <div class="info-right-top-box">
  48. <div>
  49. <el-form-item label="单选题数量" :prop="'repoList.'+ index +'.radioCount'" :rules="rules.radioCount">
  50. <el-input
  51. v-model="item.radioCount"
  52. placeholder="请输入单选题数量"
  53. clearable
  54. style="width:160px;"
  55. maxLength="5"
  56. onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"
  57. @input="changeInput"
  58. />
  59. </el-form-item>
  60. </div>
  61. <div>
  62. <el-form-item label="多选题数量" :prop="'repoList.'+ index +'.multiCount'" :rules="rules.multiCount">
  63. <el-input
  64. v-model="item.multiCount"
  65. placeholder="请输入多选题数量"
  66. clearable
  67. style="width:160px;"
  68. maxLength="5"
  69. onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"
  70. @input="changeInput"
  71. />
  72. </el-form-item>
  73. </div>
  74. <div>
  75. <el-form-item label="判断题数量" :prop="'repoList.'+ index +'.judgeCount'" :rules="rules.judgeCount">
  76. <el-input
  77. v-model="item.judgeCount"
  78. placeholder="请输入判断题数量"
  79. clearable
  80. style="width:160px;"
  81. maxLength="5"
  82. onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"
  83. @input="changeInput"
  84. />
  85. </el-form-item>
  86. </div>
  87. </div>
  88. <div class="info-right-bottom-box">
  89. <div>
  90. <el-form-item label="单选题分值" :prop="'repoList.'+ index +'.radioScore'" :rules="rules.radioScore">
  91. <el-input
  92. v-model="item.radioScore"
  93. placeholder="请输入单选题分值"
  94. clearable
  95. style="width:160px;"
  96. maxLength="5"
  97. onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"
  98. @input="changeInput"
  99. />
  100. </el-form-item>
  101. </div>
  102. <div>
  103. <el-form-item label="多选题分值" :prop="'repoList.'+ index +'.multiScore'" :rules="rules.multiScore">
  104. <el-input
  105. v-model="item.multiScore"
  106. placeholder="请输入多选题分值"
  107. clearable
  108. style="width:160px;"
  109. maxLength="5"
  110. onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"
  111. @input="changeInput"
  112. />
  113. </el-form-item>
  114. </div>
  115. <div>
  116. <el-form-item label="判断题分值" :prop="'repoList.'+ index +'.judgeScore'" :rules="rules.judgeScore">
  117. <el-input
  118. v-model="item.judgeScore"
  119. placeholder="请输入判断题分值"
  120. clearable
  121. style="width:160px;"
  122. maxLength="5"
  123. onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"
  124. @input="changeInput"
  125. />
  126. </el-form-item>
  127. </div>
  128. </div>
  129. </div>
  130. </div>
  131. </div>
  132. <p class="add-button" @click="addObj" v-if="form.joinType == 1">添加分类</p>
  133. <!--手动组题-->
  134. <div class="info-box-manual" v-if="form.joinType == 2">
  135. <div class="info-box-manual-for-max-box" v-for="(item,index) in form.manualList">
  136. <div class="info-box-manual-for-max-title">
  137. <p class="name-p">分类名称:{{item.classifyName}}</p>
  138. <p class="num-p">题目总数:{{item.quIds.length}}</p>
  139. <p class="info-box-manual-for-right-p-one" @click="addManual(index)">编辑</p>
  140. <p class="info-box-manual-for-right-p-two" @click="delManual(index)">删除</p>
  141. </div>
  142. <div class="info-box-manual-for-left-box">
  143. <div class="input-box">
  144. <el-form-item label="单选题数量" :prop="'manualList.'+ index +'.radioCount'" label-width="120px">
  145. <el-input
  146. v-model="item.radioCount"
  147. placeholder=""
  148. clearable
  149. :disabled="true"
  150. size="small"
  151. />
  152. </el-form-item>
  153. <el-form-item label="单选题分值" :prop="'manualList.'+ index +'.radioScore'" :rules="rules.radioScore" label-width="120px">
  154. <el-input
  155. v-model="item.radioScore"
  156. placeholder="请输入单选题分值"
  157. clearable
  158. size="small"
  159. maxLength="2"
  160. onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"
  161. @input="changeInputTwo"
  162. />
  163. </el-form-item>
  164. </div>
  165. <div class="input-box">
  166. <el-form-item label="多选题数量" :prop="'manualList.'+ index +'.multiCount'" label-width="120px">
  167. <el-input
  168. v-model="item.multiCount"
  169. placeholder=""
  170. clearable
  171. :disabled="true"
  172. size="small"
  173. />
  174. </el-form-item>
  175. <el-form-item label="多选题分值" :prop="'manualList.'+ index +'.multiScore'" :rules="rules.multiScore" label-width="120px">
  176. <el-input
  177. v-model="item.multiScore"
  178. placeholder="请输入单选题分值"
  179. clearable
  180. size="small"
  181. maxLength="2"
  182. onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"
  183. @input="changeInputTwo"
  184. />
  185. </el-form-item>
  186. </div>
  187. <div class="input-box">
  188. <el-form-item label="判断题数量" :prop="'manualList.'+ index +'.judgeCount'" label-width="120px">
  189. <el-input
  190. v-model="item.judgeCount"
  191. placeholder=""
  192. clearable
  193. :disabled="true"
  194. size="small"
  195. />
  196. </el-form-item>
  197. <el-form-item label="判断题分值" :prop="'manualList.'+ index +'.judgeScore'" :rules="rules.judgeScore" label-width="120px">
  198. <el-input
  199. v-model="item.judgeScore"
  200. placeholder="请输入单选题分值"
  201. clearable
  202. size="small"
  203. maxLength="2"
  204. onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"
  205. @input="changeInputTwo"
  206. />
  207. </el-form-item>
  208. </div>
  209. </div>
  210. </div>
  211. </div>
  212. <p class="add-button" @click="addManual" v-if="form.joinType == 2">添加分类</p>
  213. <p class="title-p">考试配置</p>
  214. <div class="configuration-box">
  215. <div class="configuration-top-box">
  216. <div>
  217. <el-form-item label="考试名称" prop="title">
  218. <el-input
  219. v-model="form.title"
  220. placeholder="请输入考试名称"
  221. clearable
  222. maxlength="50"
  223. size="small"
  224. />
  225. </el-form-item>
  226. </div>
  227. <div style="margin-left:20px;">
  228. <el-form-item label="考试描述" prop="content">
  229. <el-input
  230. v-model="form.content"
  231. placeholder="请输入考试描述"
  232. clearable
  233. size="small"
  234. maxlength="50"
  235. />
  236. </el-form-item>
  237. </div>
  238. </div>
  239. <!-- <div class="configuration-center-box">
  240. <el-form-item label="积分换算值" prop="conversion" style="margin-left:14px;">
  241. <el-input
  242. v-model="form.conversion"
  243. placeholder="请输入积分换算值"
  244. clearable
  245. type="number"
  246. size="small"
  247. >
  248. <template slot="prepend">1积分等于</template>
  249. </el-input>
  250. </el-form-item>
  251. </div>-->
  252. <div class="configuration-bottom-box">
  253. <div class="one">
  254. <el-form-item label="总分数" prop="totalScore" >
  255. <el-input-number disabled v-model="form.totalScore" @change="handleChange" label="总分数"></el-input-number>
  256. </el-form-item>
  257. </div>
  258. <div>
  259. <el-form-item label="及格分数" prop="qualifyScore">
  260. <el-input-number v-model="form.qualifyScore" @change="handleChange" :min="1" :max="form.totalScore" label="请输入及格分数"></el-input-number>
  261. </el-form-item>
  262. </div>
  263. <div class="two">
  264. <el-form-item label="考试时长分钟" prop="totalTime">
  265. <el-input-number v-model="form.totalTime" @change="handleChange" :min="1" :max="1000" label="请输入考试时常分钟数"></el-input-number>
  266. </el-form-item>
  267. </div>
  268. </div>
  269. <el-form-item label="考前是否人脸验证" prop="preFaceVerify" label-width="155px">
  270. <template>
  271. <el-radio v-model="form.preFaceVerify" :label="0">否</el-radio>
  272. <el-radio v-model="form.preFaceVerify" :label="1">是</el-radio>
  273. </template>
  274. </el-form-item>
  275. <el-form-item label="考后是否人脸验证" prop="endFaceVerify" label-width="155px">
  276. <template>
  277. <el-radio v-model="form.endFaceVerify" :label="0">否</el-radio>
  278. <el-radio v-model="form.endFaceVerify" :label="1">是</el-radio>
  279. </template>
  280. </el-form-item>
  281. </div>
  282. <p class="title-p">考试范围</p>
  283. <el-form-item label="适用学院" prop="deptIds" class="faculty-box">
  284. <!-- 此处需要多选 -->
  285. <treeselect v-model="form.deptIds" :options="deptOptions" :multiple="true" :show-count="true" placeholder="请选择适用学院" />
  286. </el-form-item>
  287. </el-form>
  288. <div class="bottom-button-box">
  289. <el-button @click="backPage">取 消</el-button>
  290. <el-button type="primary" @click="submitForm">确 定</el-button>
  291. </div>
  292. <!--手动添加分类弹窗-->
  293. <el-dialog class="add-manual-dialog" :title="manualTitle" :visible.sync="addManualType" v-if="addManualType" width="1200px" append-to-body>
  294. <el-form :model="manualQueryParams" ref="manualQueryForm" :inline="true" label-width="80px">
  295. <el-form-item label="题目分类" prop="cIds">
  296. <el-select
  297. v-model="manualQueryParams.cIds"
  298. ref="manualRef"
  299. :disabled="manualClassType"
  300. placeholder="请选择分类">
  301. <el-option
  302. v-for="item in repoOption"
  303. :key="item.classifyId"
  304. :label="item.title"
  305. :value="item.classifyId">
  306. </el-option>
  307. </el-select>
  308. </el-form-item>
  309. <el-form-item label="题目名称" prop="content">
  310. <el-input
  311. v-model="manualQueryParams.content"
  312. placeholder="请输入题目名称"
  313. clearable
  314. size="small"
  315. />
  316. </el-form-item>
  317. <el-form-item label="题目类型" prop="quType">
  318. <el-select
  319. v-model="manualQueryParams.quType"
  320. placeholder="请选择题目类型"
  321. clearable
  322. size="small">
  323. <el-option
  324. v-for="dict in quTypes"
  325. :key="dict.type"
  326. :label="dict.value"
  327. :value="dict.type">
  328. </el-option>
  329. </el-select>
  330. </el-form-item>
  331. <el-form-item>
  332. <p class="inquire-button-one" @click="manualQueryHandleQuery">查询</p>
  333. <p class="reset-button-one" @click="manualQueryResetQuery">重置</p>
  334. </el-form-item>
  335. </el-form>
  336. <div class="add-manual-dialog-list-box">
  337. <div class="add-manual-dialog-list-box-left">
  338. <p class="add-manual-dialog-list-box-title">已添加</p>
  339. <div class="add-manual-dialog-list-for-max-box scrollbar-box">
  340. <div class="add-manual-dialog-list-for-box" v-for="(item,index) in manualData.quIds" :key="item.id">
  341. <p>{{item.name}}</p>
  342. <i class="el-icon-circle-close" @click="manualDialogButtonDel(index)"></i>
  343. </div>
  344. <p class="add-manual-dialog-list-for-null" v-if="!manualData.quIds[0]">请再右侧添加题目</p>
  345. </div>
  346. </div>
  347. <div class="add-manual-dialog-list-box-right">
  348. <el-table :data="manualQueryList" border>
  349. <el-table-column label="题目名称" align="left" prop="content" :show-overflow-tooltip="true"/>
  350. <el-table-column label="题目类型" align="left" prop="quType" width="120">
  351. <template slot-scope="scope">
  352. <span v-for="(item, index) in quTypes"
  353. :key="index"
  354. v-if="scope.row.quType == item.type"
  355. >{{ item.value }}</span>
  356. </template>
  357. </el-table-column>
  358. <el-table-column label="操作" align="left" class-name="small-padding fixed-width" width="120">
  359. <template slot-scope="scope">
  360. <div class="button-box">
  361. <p class="table-min-button"
  362. @click="manualDialogButtonAdd(scope.row)"
  363. ><i class="el-icon-circle-plus-outline"></i>添加</p>
  364. </div>
  365. </template>
  366. </el-table-column>
  367. </el-table>
  368. <pagination :page-sizes="[20, 30, 40, 50]"
  369. v-show="manualQuerytotal>0"
  370. :total="manualQuerytotal"
  371. layout="total, prev, pager, next, sizes, jumper"
  372. :page.sync="manualQueryParams.pageNum"
  373. :limit.sync="manualQueryParams.pageSize"
  374. @pagination="getList"
  375. />
  376. </div>
  377. </div>
  378. <div slot="footer" class="dialog-footer">
  379. <el-button @click="offManualBox">取 消</el-button>
  380. <el-button type="primary" @click="addManualObj">确 定</el-button>
  381. </div>
  382. </el-dialog>
  383. </div>
  384. </template>
  385. <script>
  386. import { Message } from 'element-ui'
  387. import { optionRepo,addExam,getRepoInfo,upExam } from "@/api/exam/repo";
  388. import { treeselect } from "@/api/system/dept";
  389. import { list_option } from "@/api/exam/el_classify";
  390. import Treeselect from "@riophae/vue-treeselect";
  391. import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  392. import { listQu } from "@/api/exam/qu";
  393. export default {
  394. props:{
  395. repoId:{},
  396. },
  397. name: 'addExamPage',
  398. components: { Treeselect },
  399. data() {
  400. return {
  401. form:{
  402. code:null,
  403. faculty:null,
  404. title: null,
  405. content: null,
  406. level: null,
  407. scopeType: null,
  408. state: null,
  409. conversion: null,
  410. totalScore: null,
  411. totalTime: null,
  412. qualifyScore: null,
  413. preFaceVerify: null,
  414. endFaceVerify: null,
  415. // 分类列表
  416. repoList: [
  417. {
  418. classifyId:"",//分类ID
  419. radioCount:"0",//单选数量
  420. radioScore:"0",//单选分数
  421. multiCount:"0",//多选数量
  422. multiScore:"0",//多选分数
  423. judgeCount:"0",//判断数量
  424. judgeScore:"0",//判断分数
  425. }
  426. ],
  427. //手动分类
  428. manualList:[],
  429. // 部门
  430. deptIds: [],
  431. },
  432. // 表单校验
  433. rules: {
  434. joinType: [
  435. { required: true, message: "请选择组题方式", trigger: "blur" }
  436. ],
  437. level: [
  438. { required: true, message: "请选择考试难度", trigger: "blur" }
  439. ],
  440. classifyId: [
  441. { required: true, message: "请选择分类", trigger: "blur" }
  442. ],
  443. scopeType: [
  444. { required: true, message: "请选择适用范围", trigger: "blur" }
  445. ],
  446. radioCount: [
  447. { required: true, message: "请输入单选题数量", trigger: "blur" },,
  448. { required: true, message: "请输入单选题数量", validator: this.spaceJudgment, trigger: "blur" }
  449. ],
  450. multiCount: [
  451. { required: true, message: "请输入多选题数量", trigger: "blur" },
  452. { required: true, message: "请输入多选题数量", validator: this.spaceJudgment, trigger: "blur" }
  453. ],
  454. judgeCount: [
  455. { required: true, message: "请输入判断题数量", trigger: "blur" },
  456. { required: true, message: "请输入判断题数量", validator: this.spaceJudgment, trigger: "blur" }
  457. ],
  458. radioScore: [
  459. { required: true, message: "请输入单选题分值", trigger: "blur" },
  460. { required: true, message: "请输入单选题分值", validator: this.spaceJudgment, trigger: "blur" }
  461. ],
  462. multiScore: [
  463. { required: true, message: "请输入多选题分值", trigger: "blur" },
  464. { required: true, message: "请输入多选题分值", validator: this.spaceJudgment, trigger: "blur" }
  465. ],
  466. judgeScore: [
  467. { required: true, message: "请输入判断题分值", trigger: "blur" },
  468. { required: true, message: "请输入判断题分值", validator: this.spaceJudgment, trigger: "blur" }
  469. ],
  470. title: [
  471. { required: true, message: "请输入考试名称", trigger: "blur" },
  472. { required: true, message: "请输入考试名称", validator: this.spaceJudgment, trigger: "blur" }
  473. ],
  474. content: [
  475. { required: true, message: "请输入考试描述", trigger: "blur" },
  476. { required: true, message: "请输入考试描述", validator: this.spaceJudgment, trigger: "blur" }
  477. ],
  478. // conversion: [
  479. // { required: true, message: "请输入积分换算值", trigger: "blur" }
  480. // ],
  481. qualifyScore: [
  482. { required: true, message: "请输入及格分数", trigger: "blur" },
  483. { required: true, message: "请输入及格分数", validator: this.spaceJudgment, trigger: "blur" }
  484. ],
  485. totalTime: [
  486. { required: true, message: "请输入考试时常分钟数", trigger: "blur" },
  487. { required: true, message: "请输入考试时常分钟数", validator: this.spaceJudgment, trigger: "blur" }
  488. ],
  489. deptIds: [
  490. { required: true, message: "请选择适用学院", trigger: "blur" }
  491. ],
  492. preFaceVerify: [
  493. { required: true, message: "请选择考前是否人脸验证", trigger: "blur" }
  494. ],
  495. endFaceVerify: [
  496. { required: true, message: "请选择考后是否人脸验证", trigger: "blur" }
  497. ],
  498. },
  499. // 部门树选项
  500. deptOptions: [],
  501. // 归属分类
  502. repoOption: [],
  503. // 学科字典
  504. subClassOptions: [],
  505. levels: [
  506. {
  507. type: 1,
  508. value: "中等",
  509. },
  510. {
  511. type: 2,
  512. value: "较难",
  513. },
  514. {
  515. type: 3,
  516. value: "难",
  517. },
  518. ],
  519. /***************手动添加分类开始***************/
  520. manualTitle:"",
  521. //弹窗状态
  522. addManualType:false,
  523. //搜索数据
  524. manualQueryParams:{
  525. pageNum: 1,
  526. pageSize:20,
  527. classifyId:"",
  528. title:"",
  529. },
  530. //搜索数据列表
  531. manualQueryList:[],
  532. manualQuerytotal:0,
  533. //题目类型
  534. quTypes: [{type: 1, value: "单选题",}, {type: 2, value: "多选题",}, {type: 3, value: "判断题",},
  535. ],
  536. //当前选中分类
  537. manualIndex:0,
  538. //分类锁死状态
  539. manualClassType:false,
  540. //临时数据
  541. manualData:{
  542. classifyId:"",
  543. classifyName:"",
  544. quIds:[],
  545. },
  546. /***************手动添加分类结束***************/
  547. }
  548. },
  549. created() {
  550. this.getTreeselect();
  551. this.getClassifys();
  552. this.getDicts("subject_class").then((response) => {
  553. this.subClassOptions = response.data;
  554. });
  555. if(this.repoId){
  556. this.getRepoInfo();
  557. }
  558. },
  559. methods: {
  560. /***************手动添加分类开始***************/
  561. //添加/编辑分类
  562. addManual(index){
  563. let self = this;
  564. if(this.form.manualList[0]){
  565. if (index >= 0){
  566. this.manualIndex = index;
  567. } else{
  568. this.manualIndex = this.form.manualList.length;
  569. }
  570. }else{
  571. this.manualIndex = 0;
  572. }
  573. this.manualQueryList = [];
  574. this.manualQuerytotal = 0;
  575. if(index >= 0){
  576. this.manualTitle = "编辑分类";
  577. let newObj = JSON.parse(JSON.stringify(this.form.manualList[index]));
  578. this.manualQueryParams.classifyId = newObj.classifyId;
  579. this.manualClassType = true;
  580. this.manualData = {
  581. classifyId:newObj.classifyId,
  582. classifyName:"",
  583. quIds:newObj.quIds,
  584. };
  585. for(let i=0;i<self.repoOption.length;i++){
  586. if(newObj.classifyId == self.repoOption[i].id){
  587. self.manualData.classifyName = newObj.classifyName;
  588. }
  589. }
  590. this.getList();
  591. }else{
  592. this.manualTitle = "添加分类";
  593. this.manualQueryParams.classifyId = "";
  594. this.manualClassType = false;
  595. this.manualData = {
  596. classifyId:"",
  597. classifyName:"",
  598. quIds:[],
  599. };
  600. }
  601. this.addManualType = true;
  602. },
  603. //删除已有分类
  604. delManual(index){
  605. this.form.manualList.splice(index,1);
  606. this.$forceUpdate();
  607. },
  608. //组题方式改变
  609. joinTypeClick(e){
  610. if(e == 1){
  611. if(!this.form.repoList){
  612. let list = [];
  613. let obj = {
  614. classifyId:"",//分类ID
  615. radioCount:"0",//单选数量
  616. radioScore:"0",//单选分数
  617. multiCount:"0",//多选数量
  618. multiScore:"0",//多选分数
  619. judgeCount:"0",//判断数量
  620. judgeScore:"0",//判断分数
  621. };
  622. list.push(obj);
  623. this.$set(this.form,'repoList',list);
  624. // this.form.repoList = list;
  625. }
  626. }else if(e == 2){
  627. if(!this.form.manualList){
  628. this.$set(this.form,'manualList',[]);
  629. }
  630. }
  631. this.$forceUpdate();
  632. console.log("e",e)
  633. },
  634. //关闭窗口
  635. offManualBox(){
  636. this.addManualType = false;
  637. },
  638. //弹窗确认保存
  639. addManualObj(){
  640. let self = this;
  641. if(!this.manualData.quIds[0]){
  642. this.msgError("请先添加题目")
  643. return
  644. }
  645. //单选题数量
  646. let radioCount = 0;
  647. //多选题数量
  648. let multiCount = 0;
  649. //判断题数量
  650. let judgeCount = 0;
  651. let newObj = JSON.parse(JSON.stringify(this.manualData))
  652. for(let i=0;i<newObj.quIds.length;i++){
  653. if(newObj.quIds[i].quType == 1){
  654. radioCount++
  655. }else if(newObj.quIds[i].quType == 2){
  656. multiCount++
  657. }else if(newObj.quIds[i].quType == 3){
  658. judgeCount++
  659. }
  660. }
  661. let obj = {
  662. classifyId:newObj.classifyId,//分类ID
  663. classifyName:newObj.classifyName,//分类ID
  664. radioCount:radioCount,//单选数量
  665. radioScore:0,//单选分数
  666. multiCount:multiCount,//多选数量
  667. multiScore:0,//多选分数
  668. judgeCount:judgeCount,//判断数量
  669. judgeScore:0,//判断分数
  670. quIds:newObj.quIds,
  671. };
  672. if(this.form.manualList[this.manualIndex]){
  673. this.form.manualList[this.manualIndex] = JSON.parse(JSON.stringify(obj));
  674. }else{
  675. this.form.manualList.push(obj);
  676. }
  677. this.changeInputTwo();
  678. this.offManualBox();
  679. },
  680. //弹窗列表添加按钮
  681. manualDialogButtonAdd(row){
  682. let self = this;
  683. for(let i=0;i<self.manualData.quIds.length;i++){
  684. if(row.id == self.manualData.quIds[i].id){
  685. this.msgError("该题已添加");
  686. return
  687. }
  688. }
  689. let obj = {
  690. id:row.id,
  691. name:row.content,
  692. quType:row.quType,
  693. }
  694. self.manualData.quIds.push(obj);
  695. self.$forceUpdate();
  696. },
  697. //弹窗列表删除按钮
  698. manualDialogButtonDel(index){
  699. this.manualData.quIds.splice(index,1);
  700. this.$forceUpdate();
  701. },
  702. //列表查询
  703. manualQueryHandleQuery(){
  704. let self = this;
  705. if(!this.manualQueryParams.cIds){
  706. this.msgError("请先选择分类");
  707. return
  708. }
  709. this.manualClassType = true;
  710. if(!self.manualData.classifyId){
  711. this.manualData.classifyId = this.manualQueryParams.cIds;
  712. for(let i=0;i<self.repoOption.length;i++){
  713. if(self.manualQueryParams.cIds == self.repoOption[i].id){
  714. self.manualData.classifyName = self.repoOption[i].title;
  715. }
  716. }
  717. }
  718. this.manualQueryParams.pageNum = 1;
  719. this.getList();
  720. },
  721. //列表重置
  722. manualQueryResetQuery(){
  723. this.resetForm("manualQueryForm");
  724. this.manualQueryParams.cIds = "";
  725. this.manualQueryParams.classifyId = "";
  726. this.manualQueryList = [];
  727. this.manualData.classifyId = "";
  728. this.manualData.classifyName = "";
  729. this.manualData.quIds = [];
  730. this.manualClassType = false;
  731. this.$forceUpdate();
  732. },
  733. /** 查询分类列表 */
  734. getList() {
  735. listQu(this.manualQueryParams).then((response) => {
  736. this.manualQueryList = response.rows;
  737. this.manualQuerytotal = response.total;
  738. });
  739. },
  740. /***************手动添加分类结束***************/
  741. getRepoInfo(){
  742. let self = this;
  743. getRepoInfo(this.repoId).then(response => {
  744. console.log(response)
  745. if(response.data.joinType == 1){
  746. this.form = response.data;
  747. this.form.code = this.form.code+"";
  748. this.form.scopeType = this.form.scopeType+"";
  749. }else if(response.data.joinType == 2){
  750. let newData = JSON.parse(JSON.stringify(response.data));
  751. let newList = JSON.parse(JSON.stringify(newData.repoList));
  752. delete newData.repoList
  753. for(let i=0;i<newList.length;i++){
  754. let newQuList = JSON.parse(JSON.stringify(newList[i].examQuList));
  755. delete newList[i].examQuList;
  756. let list = [];
  757. for(let o=0;o<newQuList.length;o++){
  758. let obj = {
  759. id:newQuList[o].quId,
  760. name:newQuList[o].content,
  761. quType:newQuList[o].quType,
  762. }
  763. list.push(obj);
  764. }
  765. newList[i].quIds = list;
  766. }
  767. newData.manualList = newList;
  768. this.form = newData;
  769. this.form.code = this.form.code+"";
  770. this.form.scopeType = this.form.scopeType+"";
  771. this.changeInputTwo();
  772. }
  773. });
  774. },
  775. /** 查询题目分类 */
  776. getClassifys(){
  777. list_option({}).then(response => {
  778. for(let i=0;i<response.data.length;i++){
  779. response.data[i].classifyId = response.data[i].id;
  780. }
  781. this.repoOption = response.data;
  782. });
  783. },
  784. //删除分类
  785. delRepo(index){
  786. this.form.repoList.splice(index,1)
  787. },
  788. //提交
  789. submitForm(){
  790. let self = this;
  791. this.$refs["form"].validate(valid => {
  792. if (valid) {
  793. if(this.form.joinType == 1){
  794. for(let i=0;i<self.form.repoList.length;i++){
  795. let num = 0;
  796. if(self.form.repoList[i].radioCount&&self.form.repoList[i].radioScore){
  797. if(self.accMul(self.form.repoList[i].radioCount,self.form.repoList[i].radioScore)!=0){
  798. num++
  799. }
  800. }
  801. if(self.form.repoList[i].multiCount&&self.form.repoList[i].multiScore){
  802. if(self.accMul(self.form.repoList[i].multiCount,self.form.repoList[i].multiScore)!=0){
  803. num++
  804. }
  805. }
  806. if(self.form.repoList[i].judgeCount&&self.form.repoList[i].judgeScore){
  807. if(self.accMul(self.form.repoList[i].judgeCount,self.form.repoList[i].judgeScore)!=0){
  808. num++
  809. }
  810. }
  811. if(num == 0){
  812. Message({
  813. message: "每个分类至少选择一种题型填,并填写数量与分值",
  814. type: 'warning'
  815. });
  816. return
  817. }
  818. }
  819. }else if(this.form.joinType == 2){
  820. if(!self.form.manualList[0]){
  821. Message({
  822. message: "请至少添加一个分类",
  823. type: 'warning'
  824. });
  825. return
  826. }
  827. for(let i=0;i<self.form.manualList.length;i++){
  828. let num = 0;
  829. if(self.form.manualList[i].radioCount&&self.form.manualList[i].radioScore){
  830. if(self.accMul(self.form.manualList[i].radioCount,self.form.manualList[i].radioScore)!=0){
  831. num++
  832. }
  833. }
  834. if(self.form.manualList[i].multiCount&&self.form.manualList[i].multiScore){
  835. if(self.accMul(self.form.manualList[i].multiCount,self.form.manualList[i].multiScore)!=0){
  836. num++
  837. }
  838. }
  839. if(self.form.manualList[i].judgeCount&&self.form.manualList[i].judgeScore){
  840. if(self.accMul(self.form.manualList[i].judgeCount,self.form.manualList[i].judgeScore)!=0){
  841. num++
  842. }
  843. }
  844. if(num == 0){
  845. Message({
  846. message: "每个分类至少选择一种题型填,并填写数量与分值",
  847. type: 'warning'
  848. });
  849. return
  850. }
  851. }
  852. }
  853. let newRepoList = [];
  854. let newManualList = [];
  855. if(this.form.joinType == 1){
  856. newRepoList = JSON.parse(JSON.stringify(this.form.repoList));
  857. }else if(this.form.joinType == 2){
  858. newManualList = JSON.parse(JSON.stringify(this.form.manualList));
  859. }
  860. let newObj = JSON.parse(JSON.stringify(this.form));
  861. delete newObj.repoList;
  862. delete newObj.manualList;
  863. if(this.form.joinType == 1){
  864. //自动组题
  865. newObj.repoList = newRepoList;
  866. }else if(this.form.joinType == 2){
  867. //手动组题
  868. let list = [];
  869. for(let i=0;i<newManualList.length;i++){
  870. let obj = {
  871. classifyId:newManualList[i].classifyId,
  872. judgeCount:newManualList[i].judgeCount,
  873. judgeScore:newManualList[i].judgeScore,
  874. multiCount:newManualList[i].multiCount,
  875. multiScore:newManualList[i].multiScore,
  876. radioCount:newManualList[i].radioCount,
  877. radioScore:newManualList[i].radioScore,
  878. quIds:[],
  879. }
  880. for(let o=0;o<newManualList[i].quIds.length;o++){
  881. obj.quIds.push(newManualList[i].quIds[o].id)
  882. }
  883. list.push(obj);
  884. }
  885. newObj.repoList = list;
  886. }
  887. // 提交接口
  888. if(this.repoId){
  889. newObj.id = this.repoId;
  890. // this.form.id = this.repoId;
  891. //处理
  892. upExam(newObj).then(response => {
  893. if(response.code==200){
  894. Message({
  895. message: "操作成功",
  896. type: 'success'
  897. });
  898. this.backPage();
  899. }
  900. });
  901. }else{
  902. addExam(newObj).then(response => {
  903. if(response.code==200){
  904. Message({
  905. message: "操作成功",
  906. type: 'success'
  907. });
  908. this.backPage();
  909. }
  910. });
  911. }
  912. }
  913. });
  914. },
  915. //计算总分
  916. changeInput(){
  917. let self = this;
  918. let num = 0;
  919. for(let i=0;i<self.form.repoList.length;i++){
  920. let radio = self.accMul(self.form.repoList[i].radioCount,self.form.repoList[i].radioScore);
  921. let multi = self.accMul(self.form.repoList[i].multiCount,self.form.repoList[i].multiScore);
  922. let judge = self.accMul(self.form.repoList[i].judgeCount,self.form.repoList[i].judgeScore);
  923. num = self.accAdd(num,radio);
  924. num = self.accAdd(num,multi);
  925. num = self.accAdd(num,judge);
  926. }
  927. this.form.totalScore = num;
  928. this.$forceUpdate();
  929. console.log("num",num);
  930. },
  931. //手抖组题计算分数
  932. changeInputTwo(){
  933. let self = this;
  934. let num = 0;
  935. for(let i=0;i<self.form.manualList.length;i++){
  936. let radio = self.accMul(self.form.manualList[i].radioCount,self.form.manualList[i].radioScore);
  937. let multi = self.accMul(self.form.manualList[i].multiCount,self.form.manualList[i].multiScore);
  938. let judge = self.accMul(self.form.manualList[i].judgeCount,self.form.manualList[i].judgeScore);
  939. num = self.accAdd(num,radio);
  940. num = self.accAdd(num,multi);
  941. num = self.accAdd(num,judge);
  942. }
  943. this.form.totalScore = num;
  944. this.$forceUpdate();
  945. console.log("num",num);
  946. },
  947. //添加分类
  948. addObj(){
  949. let obj = {
  950. classifyId:"",//分类ID
  951. radioCount:"0",//单选数量
  952. radioScore:"0",//单选分数
  953. multiCount:"0",//多选数量
  954. multiScore:"0",//多选分数
  955. judgeCount:"0",//判断数量
  956. judgeScore:"0",//判断分数
  957. };
  958. this.form.repoList.push(obj);
  959. },
  960. /** 查询部门下拉树结构 */
  961. getTreeselect() {
  962. treeselect().then(response => {
  963. this.deptOptions = response.data;
  964. });
  965. },
  966. backPage(){
  967. this.$parent.pageOff();
  968. },
  969. handleQuery(){},
  970. handleChange(){},
  971. //乘法
  972. accMul(arg1,arg2){
  973. var m=0,s1=arg1.toString(),s2=arg2.toString();
  974. try{m+=s1.split(".")[1].length}catch(e){}
  975. try{m+=s2.split(".")[1].length}catch(e){}
  976. return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)
  977. },
  978. //加法
  979. accAdd(arg1,arg2){
  980. var r1,r2,m;
  981. try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
  982. try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
  983. m=Math.pow(10,Math.max(r1,r2))
  984. return ((arg1*m+arg2*m)/m).toFixed(0);
  985. },
  986. }
  987. }
  988. </script>
  989. <style lang="scss" scoped>
  990. .addExamPage{
  991. margin-top:-20px;
  992. .title-p{
  993. margin:0;
  994. line-height:80px;
  995. font-size:18px;
  996. color:#0045AF;
  997. border-bottom:2px solid #E0E0E0;
  998. }
  999. .add-button{
  1000. border:1px solid #999;
  1001. font-size:14px;
  1002. line-height:30px;
  1003. width:80px;
  1004. text-align: center;
  1005. color:#999;
  1006. border-radius:4px;
  1007. margin:0 auto;
  1008. cursor:pointer;
  1009. }
  1010. .info-box{
  1011. display: flex;
  1012. .info-left-box{
  1013. width:540px;
  1014. }
  1015. .info-right-box{
  1016. .info-right-max-box{
  1017. .info-right-top-box{
  1018. display:flex;
  1019. }
  1020. .info-right-bottom-box{
  1021. display: flex;
  1022. }
  1023. .del-o{
  1024. position:absolute;
  1025. width:30px;
  1026. height:30px;
  1027. line-height: 30px;
  1028. text-align: center;
  1029. border-radius:50%;
  1030. top:38px;
  1031. right:-30px;
  1032. font-size:25px;
  1033. cursor:pointer;
  1034. color:#999;
  1035. }
  1036. .del-o:hover{
  1037. background: #999;
  1038. color:#fff;
  1039. }
  1040. }
  1041. }
  1042. }
  1043. .info-box-manual{
  1044. overflow: hidden;
  1045. margin-bottom:20px;
  1046. .info-box-manual-for-max-box{
  1047. width:1100px;
  1048. border:1px solid #dedede;
  1049. margin:20px 0 0 20px;
  1050. .info-box-manual-for-max-title{
  1051. padding:0 20px;
  1052. display: flex;
  1053. border-bottom:1px solid #dedede;
  1054. p{
  1055. margin:0;
  1056. line-height:40px;
  1057. font-size:14px;
  1058. }
  1059. .name-p{
  1060. flex:2;
  1061. }
  1062. .num-p{
  1063. flex:1;
  1064. }
  1065. .info-box-manual-for-right-p-one{
  1066. font-size:14px;
  1067. color: #004d8c;
  1068. text-align: center;
  1069. cursor:pointer;
  1070. margin-right:10px;
  1071. }
  1072. .info-box-manual-for-right-p-one:hover{
  1073. color: #0E9EED;
  1074. }
  1075. .info-box-manual-for-right-p-two{
  1076. font-size:14px;
  1077. color: #004d8c;
  1078. text-align: center;
  1079. cursor:pointer;
  1080. }
  1081. .info-box-manual-for-right-p-two:hover{
  1082. color:#E65D6E;
  1083. }
  1084. }
  1085. .info-box-manual-for-left-box{
  1086. display: flex;
  1087. flex:1;
  1088. padding:0 20px;
  1089. .input-box{
  1090. padding-top:22px;
  1091. p:nth-child(1){
  1092. margin-left:20px;
  1093. }
  1094. }
  1095. }
  1096. }
  1097. }
  1098. .configuration-box{
  1099. .configuration-top-box{
  1100. display: flex;
  1101. margin-top:30px;
  1102. }
  1103. .configuration-bottom-box{
  1104. margin-top:24px;
  1105. display: flex;
  1106. div{
  1107. margin-right:10px;
  1108. }
  1109. }
  1110. }
  1111. .faculty-box{
  1112. margin:30px 0 40px;
  1113. }
  1114. .bottom-button-box{
  1115. width:220px;
  1116. margin:0 auto;
  1117. height:40px;
  1118. display: flex;
  1119. p{
  1120. width:100px;
  1121. height:40px;
  1122. line-height:40px;
  1123. margin:0;
  1124. text-align: center;
  1125. font-size:14px;
  1126. border-radius:6px;
  1127. cursor:pointer
  1128. }
  1129. p:nth-child(1){
  1130. margin-right:20px;
  1131. background: #E0E0E0;
  1132. color:#333333;
  1133. }
  1134. p:nth-child(2){
  1135. background: #0045AF;
  1136. color:#ffffff;
  1137. }
  1138. }
  1139. }
  1140. </style>