EditPaperPendingTrial.vue 87 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809
  1. <template>
  2. <div
  3. v-loading="loading"
  4. class="edit-paper"
  5. element-loading-text="拼命加载中。。。"
  6. >
  7. <div class="edit-header">
  8. <div class="edit-header-top box-justify">
  9. <div class="header-info">
  10. <div class="header-info-item">
  11. <span>课程代码:</span>
  12. <span>{{ paper.course.code }}</span>
  13. </div>
  14. <div class="header-info-item">
  15. <span>课程名称:</span>
  16. <span>{{ paper.course.name }}</span>
  17. </div>
  18. <div class="header-info-item">
  19. <span>试卷名称:</span>
  20. <span>
  21. <el-tooltip class="item" effect="dark" placement="top-start">
  22. <div slot="content">{{ paper.name }}</div>
  23. <el-input
  24. v-model="paper.name"
  25. size="mini"
  26. class="header-info-input"
  27. placeholder="试卷名称"
  28. ></el-input>
  29. </el-tooltip>
  30. </span>
  31. </div>
  32. <div class="header-info-item">
  33. <span>试卷总分:</span>
  34. <span>{{ paper.totalScore }}</span>
  35. </div>
  36. </div>
  37. <div class="header-btns">
  38. <el-dropdown v-show="isShowAuditBtn()">
  39. <el-button type="primary" size="small">
  40. 审核<i class="el-icon-arrow-down el-icon--right"></i>
  41. </el-button>
  42. <el-dropdown-menu slot="dropdown">
  43. <el-dropdown-item>
  44. <el-button
  45. size="mini"
  46. type="success"
  47. @click="auditPaper('PASS')"
  48. >
  49. <i class="el-icon-success"></i>通过
  50. </el-button>
  51. </el-dropdown-item>
  52. <el-dropdown-item>
  53. <el-button
  54. size="mini"
  55. type="danger"
  56. @click="auditPaper('NOT_PASS')"
  57. >
  58. <i class="el-icon-error"></i>不通过
  59. </el-button>
  60. </el-dropdown-item>
  61. </el-dropdown-menu>
  62. </el-dropdown>
  63. <el-button
  64. v-show="isShowEditBtn()"
  65. type="primary"
  66. size="small"
  67. @click="savePaper"
  68. >保存
  69. </el-button>
  70. <el-button
  71. v-show="isShowEditBtn()"
  72. type="danger"
  73. plain
  74. size="small"
  75. @click="deletePaper(paper.id)"
  76. >删除
  77. </el-button>
  78. <el-button
  79. v-if="showCheckDuplicateBtn"
  80. type="primary"
  81. size="small"
  82. plain
  83. @click="checkDuplicate"
  84. >
  85. 进入查重
  86. </el-button>
  87. <el-dropdown v-show="isShowEditBtn()">
  88. <el-button type="primary" size="small" plain>
  89. 更多 <i class="el-icon-more el-icon--right"></i>
  90. </el-button>
  91. <el-dropdown-menu slot="dropdown" class="action-dropdown">
  92. <el-dropdown-item>
  93. <el-button type="primary" plain size="small" @click="openDialog"
  94. >上传音频
  95. </el-button>
  96. </el-dropdown-item>
  97. <el-dropdown-item>
  98. <el-button
  99. size="small"
  100. type="primary"
  101. plain
  102. @click="exportPaperAnswer()"
  103. >导出答案</el-button
  104. >
  105. </el-dropdown-item>
  106. <el-dropdown-item>
  107. <el-button
  108. type="primary"
  109. size="small"
  110. plain
  111. @click="openAnswerDialog"
  112. >导入答案
  113. </el-button>
  114. </el-dropdown-item>
  115. </el-dropdown-menu>
  116. </el-dropdown>
  117. <el-button
  118. size="small"
  119. type="danger"
  120. plain
  121. icon="icon icon-back"
  122. @click="back"
  123. >返回</el-button
  124. >
  125. </div>
  126. </div>
  127. <div class="edit-header-bottom box-justify">
  128. <div>
  129. <el-button type="info" size="small" @click="showBasicDialog">
  130. 基础构成
  131. </el-button>
  132. <el-button type="info" size="small" @click="showTypeDialog">
  133. 题型分布
  134. </el-button>
  135. <el-button type="info" size="small" @click="showBlueDialog">
  136. 蓝图分布
  137. </el-button>
  138. <el-button type="info" size="small" @click="showAuditDialog">
  139. 审核记录
  140. </el-button>
  141. </div>
  142. <div>
  143. <span class="tips-info margin-right-10"
  144. >当前状态:{{ paper.auditStatus | paperAuditStatusFilter }}</span
  145. >
  146. <el-button type="primary" size="small" plain @click="quesTagShowHide">
  147. {{ quesTagShow ? "隐藏" : "显示" }}属性
  148. </el-button>
  149. <el-button
  150. type="primary"
  151. size="small"
  152. plain
  153. @click="quesAnswerShowHide"
  154. >
  155. {{ quesAnswerShow ? "隐藏" : "显示" }}答案
  156. </el-button>
  157. </div>
  158. </div>
  159. </div>
  160. <div class="edit-body">
  161. <div class="edit-part-list">
  162. <div class="edit-part">
  163. <div class="edit-cont">
  164. <div class="edit-cont-title">
  165. <h3>考试说明</h3>
  166. </div>
  167. <div class="edit-cont-action">
  168. <el-button
  169. v-show="isShowEditBtn()"
  170. type="primary"
  171. plain
  172. size="small"
  173. @click="openEditExamPaperRemark"
  174. >编辑</el-button
  175. >
  176. </div>
  177. <div class="edit-cont-body">
  178. <div v-html="paper.examRemark"></div>
  179. </div>
  180. </div>
  181. </div>
  182. </div>
  183. <!-- 循环大题 -->
  184. <div
  185. v-for="(paperDetail, detailIndex) in paper.paperDetails"
  186. v-show="paperDetailShow(paperDetail)"
  187. :key="detailIndex"
  188. class="edit-part-list"
  189. >
  190. <div class="edit-part">
  191. <div
  192. class="edit-cont"
  193. @mouseover="quesMouseOver(paperDetail.id)"
  194. @mouseout="quesMouseOut(paperDetail.id)"
  195. >
  196. <div class="edit-cont-title">
  197. <h3>
  198. <span>{{ paperDetail.cnNum }}</span> <span>.</span>
  199. <span>{{ paperDetail.name }}</span>
  200. <span>
  201. ({{
  202. !paperDetail.title ? "本大题" : paperDetail.title + ","
  203. }}共{{ paperDetail.unitCount }}小题,满分{{
  204. paperDetail.score
  205. }}分)
  206. </span>
  207. </h3>
  208. </div>
  209. <div
  210. :id="paperDetail.id"
  211. class="edit-cont-action"
  212. style="visibility: hidden"
  213. >
  214. <el-button
  215. v-show="
  216. parentView == 'exam_paper_pending_trial' && isShowEditBtn()
  217. "
  218. size="small"
  219. type="primary"
  220. plain
  221. @click="selectQues(paperDetail.id)"
  222. >选题
  223. </el-button>
  224. <el-button
  225. v-show="isShowEditBtn()"
  226. size="small"
  227. type="primary"
  228. plain
  229. @click="openEditPaperDetail(paperDetail)"
  230. >编辑
  231. </el-button>
  232. <el-button
  233. v-if="showUp(paperDetail)"
  234. v-show="isShowEditBtn()"
  235. size="small"
  236. type="primary"
  237. plain
  238. @click="movePaperDetail(paperDetail, 'up')"
  239. >上移
  240. </el-button>
  241. <el-button
  242. v-if="showDown(paperDetail)"
  243. v-show="isShowEditBtn()"
  244. size="small"
  245. type="primary"
  246. plain
  247. @click="movePaperDetail(paperDetail, 'down')"
  248. >下移
  249. </el-button>
  250. <el-button
  251. v-show="isShowEditBtn()"
  252. size="small"
  253. type="danger"
  254. @click="deletePaperDetail(paperDetail.id)"
  255. >删除
  256. </el-button>
  257. <el-button
  258. v-show="showButtons[detailIndex].up"
  259. size="small"
  260. type="primary"
  261. plain
  262. icon="el-icon-arrow-up"
  263. @click.stop="hideContent(detailIndex)"
  264. ></el-button>
  265. <el-button
  266. v-show="!showButtons[detailIndex].up"
  267. size="small"
  268. icon="el-icon-arrow-down"
  269. type="primary"
  270. plain
  271. @click.stop="showContent(detailIndex)"
  272. ></el-button>
  273. </div>
  274. <rich-text
  275. class="edit-cont-body"
  276. :text-json="paperDetail.description"
  277. ></rich-text>
  278. </div>
  279. <div v-show="quesTagShow" class="edit-property">
  280. <div class="edit-property-box">
  281. <div
  282. v-for="(paperDetailTag, tagIndex) in paperDetail.tags"
  283. :key="tagIndex"
  284. class="edit-property-item"
  285. >
  286. <div class="edit-property-body edit-property-danger">
  287. <div class="edit-property-title">
  288. {{ paperDetailTag.tag }}
  289. </div>
  290. <div class="edit-property-content">
  291. {{ paperDetailTag.content }}
  292. </div>
  293. </div>
  294. </div>
  295. </div>
  296. </div>
  297. </div>
  298. <!-- 循环小题 -->
  299. <div
  300. v-show="showQuestions[detailIndex].is_show"
  301. class="edit-paper-questions"
  302. >
  303. <template
  304. v-for="(paperDetailUnit, unitIndex) in paperDetail.paperDetailUnits"
  305. >
  306. <div
  307. v-show="quesShow(paperDetailUnit.id)"
  308. :key="`question-${unitIndex}`"
  309. :class="[
  310. 'edit-part',
  311. {
  312. 'question-duplicate':
  313. paperDetailUnit.question.checkDuplicateStatus ==
  314. 'TO_BE_DISPOSE',
  315. },
  316. ]"
  317. >
  318. <div
  319. class="edit-cont"
  320. @mouseover="quesMouseOver(paperDetailUnit.id)"
  321. @mouseout="quesMouseOut(paperDetailUnit.id)"
  322. >
  323. <div class="edit-cont-title">
  324. <span>{{ paperDetailUnit.number }}.</span>
  325. <rich-text
  326. :text-json="paperDetailUnit.question.quesBody"
  327. ></rich-text>
  328. <span> ({{ paperDetailUnit.score }}分) </span>
  329. </div>
  330. <div
  331. :id="paperDetailUnit.id"
  332. class="edit-cont-action"
  333. style="visibility: hidden"
  334. >
  335. <span class="tips-info">
  336. {{ paperDetailUnit.question.bodyLengthText }}
  337. </span>
  338. <el-button
  339. v-if="
  340. paperDetailUnit.question.checkDuplicateStatus ==
  341. 'TO_BE_DISPOSE'
  342. "
  343. size="small"
  344. type="primary"
  345. plain
  346. @click="checkDuplicateQuestion(paperDetailUnit.question.id)"
  347. >进入查重
  348. </el-button>
  349. <el-button
  350. v-show="isShowEditBtn()"
  351. size="small"
  352. type="primary"
  353. plain
  354. @click="editQues(paperDetailUnit, paperDetailUnit.question)"
  355. >编辑
  356. </el-button>
  357. <el-button
  358. v-if="showUnitUp(paperDetail, paperDetailUnit.id)"
  359. v-show="isShowEditBtn()"
  360. size="small"
  361. type="primary"
  362. plain
  363. @click="
  364. movePaperDetailUnit(
  365. paperDetail.id,
  366. paperDetailUnit.id,
  367. 'up'
  368. )
  369. "
  370. >上移
  371. </el-button>
  372. <el-button
  373. v-if="showUnitDown(paperDetail, paperDetailUnit.id)"
  374. v-show="isShowEditBtn()"
  375. size="small"
  376. type="primary"
  377. plain
  378. @click="
  379. movePaperDetailUnit(
  380. paperDetail.id,
  381. paperDetailUnit.id,
  382. 'down'
  383. )
  384. "
  385. >下移
  386. </el-button>
  387. <el-button
  388. v-show="isShowEditBtn()"
  389. type="danger"
  390. size="small"
  391. @click="deleteQues(paperDetailUnit)"
  392. >删除
  393. </el-button>
  394. <el-button
  395. v-show="
  396. isNested(paperDetailUnit.questionType) &&
  397. showSubButtons[detailIndex + '-' + unitIndex]
  398. "
  399. size="small"
  400. icon="el-icon-arrow-up"
  401. @click.stop="hideSubContent(detailIndex + '-' + unitIndex)"
  402. ></el-button>
  403. <el-button
  404. v-show="
  405. isNested(paperDetailUnit.questionType) &&
  406. !showSubButtons[detailIndex + '-' + unitIndex]
  407. "
  408. size="small"
  409. type="primary"
  410. plain
  411. icon="el-icon-arrow-down"
  412. @click.stop="showSubContent(detailIndex + '-' + unitIndex)"
  413. ></el-button>
  414. </div>
  415. <div class="edit-cont-body">
  416. <div
  417. v-for="(quesOption, optionIndex) in paperDetailUnit.question
  418. .quesOptions"
  419. :key="optionIndex"
  420. class="paper-option"
  421. >
  422. <span>{{ optionIndex | optionOrderWordFilter }}. </span>
  423. <rich-text :text-json="quesOption.optionBody"></rich-text>
  424. </div>
  425. <div v-if="!isNested(paperDetailUnit.questionType)">
  426. <div v-show="quesAnswerShow" class="paper-answer">
  427. <span>答案:</span>
  428. <question-answer
  429. :data="paperDetailUnit.question"
  430. ></question-answer>
  431. </div>
  432. </div>
  433. </div>
  434. </div>
  435. <div v-show="quesTagShow" class="edit-property">
  436. <div class="edit-property-box">
  437. <div
  438. v-for="(questionTag, tagIndex) in paperDetailUnit.question
  439. .tags"
  440. :key="tagIndex"
  441. class="edit-property-item"
  442. >
  443. <div class="edit-property-body">
  444. <div class="edit-property-title">
  445. {{ questionTag.tag }}
  446. </div>
  447. <div class="edit-property-content">
  448. {{ questionTag.content }}
  449. </div>
  450. </div>
  451. </div>
  452. </div>
  453. </div>
  454. </div>
  455. <!-- 子题 -->
  456. <div
  457. v-show="showSubQuestions[detailIndex + '-' + unitIndex]"
  458. :key="`question-sub-${unitIndex}`"
  459. class="edit-paper-question-subs"
  460. >
  461. <div
  462. v-for="(subQuestion, subIndex) in paperDetailUnit.question
  463. .subQuestions"
  464. v-show="quesShow(subQuestion.id)"
  465. :key="subIndex"
  466. class="edit-part"
  467. >
  468. <div
  469. class="edit-cont"
  470. @mouseover="
  471. quesMouseOver(
  472. getSubQuesEditId(paperDetailUnit, subQuestion)
  473. )
  474. "
  475. @mouseout="
  476. quesMouseOut(getSubQuesEditId(paperDetailUnit, subQuestion))
  477. "
  478. >
  479. <div
  480. v-show="isShowEditBtn()"
  481. :id="getSubQuesEditId(paperDetailUnit, subQuestion)"
  482. class="edit-cont-action"
  483. style="visibility: hidden"
  484. >
  485. <el-button
  486. size="small"
  487. type="primary"
  488. plain
  489. @click="editQues(paperDetailUnit, subQuestion)"
  490. >编辑
  491. </el-button>
  492. <el-button
  493. v-if="showUnitSubUp(paperDetailUnit, subQuestion.id)"
  494. size="small"
  495. type="primary"
  496. plain
  497. @click="
  498. movePaperDetailUnitSub(
  499. paperDetailUnit.id,
  500. subQuestion.id,
  501. 'up'
  502. )
  503. "
  504. >上移
  505. </el-button>
  506. <el-button
  507. v-if="showUnitSubDown(paperDetailUnit, subQuestion.id)"
  508. size="small"
  509. type="primary"
  510. plain
  511. @click="
  512. movePaperDetailUnitSub(
  513. paperDetailUnit.id,
  514. subQuestion.id,
  515. 'down'
  516. )
  517. "
  518. >下移
  519. </el-button>
  520. </div>
  521. <div class="edit-cont-title">
  522. <span>{{ subQuestion.subNumber }}. </span>
  523. <rich-text :text-json="subQuestion.quesBody"></rich-text>
  524. <span
  525. >({{ paperDetailUnit.subScoreList[subIndex] }}分)</span
  526. >
  527. </div>
  528. <div
  529. v-if="!isMatchingQuestion(paperDetailUnit.questionType)"
  530. class="edit-cont-body"
  531. >
  532. <div
  533. v-for="(
  534. subQuesOption, subOptIndex
  535. ) in subQuestion.quesOptions"
  536. :key="subOptIndex"
  537. class="paper-option"
  538. >
  539. <span>{{ subOptIndex | optionOrderWordFilter }}. </span>
  540. <rich-text
  541. :text-json="subQuesOption.optionBody"
  542. ></rich-text>
  543. </div>
  544. </div>
  545. <div v-show="quesAnswerShow" class="paper-answer">
  546. <span>答案:</span>
  547. <question-answer :data="subQuestion"></question-answer>
  548. </div>
  549. </div>
  550. <div v-show="quesTagShow" class="edit-property">
  551. <div class="edit-property-box">
  552. <div
  553. v-for="(subQuestionTag, tagIndex) in subQuestion.tags"
  554. :key="tagIndex"
  555. class="edit-property-item"
  556. >
  557. <div class="edit-property-body">
  558. <div class="edit-property-title">
  559. {{ subQuestionTag.tag }}
  560. </div>
  561. <div class="edit-property-content">
  562. {{ subQuestionTag.content }}
  563. </div>
  564. </div>
  565. </div>
  566. </div>
  567. </div>
  568. </div>
  569. </div>
  570. </template>
  571. </div>
  572. </div>
  573. </div>
  574. <!-- 编辑大题弹框 -->
  575. <el-dialog
  576. v-loading.body="detailLoading"
  577. width="600px"
  578. title="大题名称编辑"
  579. element-loading-text="保存中。。。"
  580. :visible.sync="paperDatailDialog"
  581. :modal="false"
  582. append-to-body
  583. custom-class="side-dialog"
  584. @close="closeQuesDialog"
  585. >
  586. <el-form :model="editpaperDetail" label-width="80px">
  587. <el-form-item label="大题名称">
  588. <el-input
  589. v-model="editpaperDetail.name"
  590. placeholder="请输入大题名称"
  591. ></el-input>
  592. </el-form-item>
  593. <el-form-item label="大题描述">
  594. <v-editor
  595. v-model="editpaperDetail.description"
  596. :enable-formula="false"
  597. ></v-editor>
  598. </el-form-item>
  599. </el-form>
  600. <div slot="footer">
  601. <el-button type="primary" @click="savePaperDatail(editpaperDetail)"
  602. >保存</el-button
  603. >
  604. <el-button type="danger" plain @click="closePaperDatailDialog()"
  605. >取消</el-button
  606. >
  607. </div>
  608. </el-dialog>
  609. <!-- 编辑试题弹框 -->
  610. <el-dialog
  611. v-loading.body="dialogLoading"
  612. title="试题编辑"
  613. element-loading-text="保存中。。。"
  614. :visible.sync="quesDialog"
  615. :modal="false"
  616. append-to-body
  617. custom-class="side-dialog"
  618. @close="closeQuesDialog"
  619. >
  620. <el-form :model="quesModel" label-position="right" label-width="80px">
  621. <el-row :gutter="10">
  622. <el-col :span="12">
  623. <el-form-item label="题型">
  624. <el-select
  625. v-model="quesModel.questionType"
  626. :disabled="true"
  627. placeholder="请输入题型"
  628. >
  629. <el-option
  630. v-for="item in questionTypes"
  631. :key="item.value"
  632. :label="item.label"
  633. :value="item.value"
  634. >
  635. </el-option>
  636. </el-select>
  637. </el-form-item>
  638. </el-col>
  639. <el-col :span="12">
  640. <el-form-item label="分值">
  641. <el-input-number
  642. v-model="quesModel.score"
  643. placeholder="分值"
  644. :precision="1"
  645. :min="0"
  646. :disabled="isNested(quesModel.questionType)"
  647. ></el-input-number>
  648. </el-form-item>
  649. </el-col>
  650. <el-col :span="12">
  651. <el-form-item label="难度">
  652. <el-select
  653. v-model="quesModel.difficultyDegree"
  654. placeholder="请输入难度"
  655. :disabled="
  656. isNested(quesModel.questionType) ? true : updatePorperty
  657. "
  658. >
  659. <el-option
  660. v-for="item in difficultyDegreeList"
  661. :key="item.value"
  662. :label="item.label"
  663. :value="item.value"
  664. >
  665. </el-option>
  666. </el-select>
  667. </el-form-item>
  668. </el-col>
  669. <el-col :span="12">
  670. <el-form-item label="公开度">
  671. <el-select
  672. v-model="quesModel.publicity"
  673. placeholder="请输入公开度"
  674. :disabled="updatePorperty"
  675. >
  676. <el-option
  677. v-for="item in publicityList"
  678. :key="item.value"
  679. :label="item.label"
  680. :value="item.value"
  681. >
  682. </el-option>
  683. </el-select>
  684. </el-form-item>
  685. </el-col>
  686. <el-col
  687. v-if="quesModel.questionType == 'TEXT_ANSWER_QUESTION'"
  688. :span="12"
  689. >
  690. <el-form-item label="作答类型">
  691. <el-select
  692. v-model="quesModel.answerType"
  693. :disabled="updatePorperty"
  694. >
  695. <el-option
  696. v-for="item in answerTypes"
  697. :key="item.value"
  698. :label="item.label"
  699. :value="item.value"
  700. >
  701. </el-option>
  702. </el-select>
  703. </el-form-item>
  704. </el-col>
  705. <el-col
  706. v-if="quesModel.questionType && !isNested(quesModel.questionType)"
  707. :span="12"
  708. >
  709. <el-form-item label="时长">
  710. <el-input-number
  711. v-model="quesModel.control.maxAnswerTime"
  712. size="small"
  713. :precision="0"
  714. :min="1"
  715. :disabled="updatePorperty"
  716. ></el-input-number>
  717. </el-form-item>
  718. </el-col>
  719. <el-col v-if="isMatchingQuestion(quesModel.questionType)" :span="12">
  720. <el-form-item label="答题模式">
  721. <el-select
  722. v-model="quesModel.quesParam.matchingMode"
  723. :disabled="updatePorperty"
  724. >
  725. <el-option
  726. v-for="item in matchingModes"
  727. :key="item.value"
  728. :label="item.label"
  729. :value="item.value"
  730. >
  731. </el-option>
  732. </el-select>
  733. </el-form-item>
  734. </el-col>
  735. </el-row>
  736. <el-form-item label="属性列表">
  737. <el-tooltip
  738. v-for="(content, propIndex) in quesModel.quesProperties"
  739. :key="propIndex"
  740. placement="top"
  741. >
  742. <div slot="content">
  743. <span v-if="content.firstProperty != null"
  744. >一级属性:{{ content.firstProperty.name }}({{
  745. content.firstProperty.code
  746. }})</span
  747. ><br />
  748. <span v-if="content.secondProperty != null"
  749. >二级属性:{{ content.secondProperty.name }}({{
  750. content.secondProperty.code
  751. }})</span
  752. >
  753. </div>
  754. <span>
  755. <el-tag
  756. :key="content.id"
  757. style="margin-right: 5px"
  758. :closable="!updatePorperty"
  759. type="primary"
  760. effect="dark"
  761. @close="handleClose(content)"
  762. >
  763. {{ content.courseProperty.name }}
  764. </el-tag>
  765. </span>
  766. </el-tooltip>
  767. </el-form-item>
  768. <el-row :gutter="10">
  769. <el-col :span="8">
  770. <el-form-item label="属性名" label-width="80px">
  771. <el-select
  772. v-model="coursePropertyId"
  773. :remote-method="getCoursesProperty"
  774. :loading="coursePropertyLoading"
  775. remote
  776. filterable
  777. clearable
  778. placeholder="属性名"
  779. class="property_with"
  780. :disabled="updatePorperty"
  781. @change="searchFirst"
  782. >
  783. <el-option label="请选择" value=""></el-option>
  784. <el-option
  785. v-for="item in coursePropertyList"
  786. :key="item.id"
  787. :label="item.name"
  788. :value="item.id"
  789. >
  790. </el-option>
  791. </el-select>
  792. </el-form-item>
  793. </el-col>
  794. <el-col :span="6">
  795. <el-form-item label="一级" label-width="48px">
  796. <el-select
  797. v-model="firstPropertyId"
  798. placeholder="一级"
  799. class="property_with"
  800. :disabled="updatePorperty"
  801. @change="searchSecond"
  802. >
  803. <el-option label="请选择" value=""></el-option>
  804. <el-option
  805. v-for="item in firstPropertyList"
  806. :key="item.id"
  807. :label="item.name + '(' + item.code + ')'"
  808. :value="item.id"
  809. >
  810. </el-option>
  811. </el-select>
  812. </el-form-item>
  813. </el-col>
  814. <el-col :span="6">
  815. <el-form-item label="二级" label-width="48px">
  816. <el-select
  817. v-model="secondPropertyId"
  818. placeholder="二级"
  819. class="property_with"
  820. :disabled="updatePorperty"
  821. >
  822. <el-option label="请选择" value=""></el-option>
  823. <el-option
  824. v-for="item in secondPropertyList"
  825. :key="item.id"
  826. :label="item.name + '(' + item.code + ')'"
  827. :value="item.id"
  828. >
  829. </el-option>
  830. </el-select>
  831. </el-form-item>
  832. </el-col>
  833. <el-col :span="4">
  834. <el-form-item label-width="0px">
  835. <el-button
  836. type="primary"
  837. :disabled="updatePorperty"
  838. @click="insertProperty"
  839. ><i class="el-icon-plus"></i>新增属性
  840. </el-button>
  841. </el-form-item>
  842. </el-col>
  843. </el-row>
  844. <!-- end by weiwenhai -->
  845. <el-form-item label="题目">
  846. <v-editor
  847. v-model="quesModel.quesBody"
  848. :enable-answer-point="enableAnswerPoint"
  849. @change="quesBodyChange"
  850. ></v-editor>
  851. </el-form-item>
  852. <el-form-item
  853. v-for="(quesOption, optIndex) in quesModel.quesOptions"
  854. :key="optIndex"
  855. >
  856. <div class="question-edit-option">
  857. <div class="option-check">
  858. <div
  859. v-if="
  860. !quesModel.parentType ||
  861. !isMatchingQuestion(quesModel.parentType) ||
  862. !isInOtherSelect(optIndex, quesModel)
  863. "
  864. >
  865. <el-radio
  866. v-if="quesModel.questionType === 'SINGLE_ANSWER_QUESTION'"
  867. v-model="singleRightAnswer"
  868. :label="optIndex | optionOrderWordFilter"
  869. ></el-radio>
  870. <el-checkbox
  871. v-if="quesModel.questionType === 'MULTIPLE_ANSWER_QUESTION'"
  872. v-model="multipleRightAnswer"
  873. :label="optIndex | optionOrderWordFilter"
  874. ></el-checkbox>
  875. <span v-if="isMatchingQuestion(quesModel.questionType)">{{
  876. optIndex | optionOrderWordFilter
  877. }}</span>
  878. </div>
  879. <div
  880. v-if="
  881. quesModel.parentType &&
  882. isMatchingQuestion(quesModel.parentType) &&
  883. isInOtherSelect(optIndex, quesModel)
  884. "
  885. >
  886. <el-tooltip
  887. class="item"
  888. effect="dark"
  889. :content="otherSelect(optIndex, quesModel)"
  890. placement="top-start"
  891. >
  892. <el-radio
  893. v-if="quesModel.questionType === 'SINGLE_ANSWER_QUESTION'"
  894. v-model="singleRightAnswer"
  895. :disabled="true"
  896. :label="optIndex | optionOrderWordFilter"
  897. ></el-radio>
  898. <el-checkbox
  899. v-if="quesModel.questionType === 'MULTIPLE_ANSWER_QUESTION'"
  900. v-model="multipleRightAnswer"
  901. :disabled="true"
  902. :label="optIndex | optionOrderWordFilter"
  903. ></el-checkbox>
  904. <span v-if="isMatchingQuestion(quesModel.questionType)">{{
  905. optIndex | optionOrderWordFilter
  906. }}</span>
  907. </el-tooltip>
  908. </div>
  909. </div>
  910. <div
  911. v-if="
  912. !quesModel.parentType ||
  913. !isMatchingQuestion(quesModel.parentType)
  914. "
  915. class="option-body"
  916. >
  917. <v-editor v-model="quesOption.optionBody"></v-editor>
  918. </div>
  919. <div
  920. v-if="
  921. quesModel.parentType && isMatchingQuestion(quesModel.parentType)
  922. "
  923. class="option-body"
  924. >
  925. <rich-text :text-json="quesOption.optionBody"></rich-text>
  926. </div>
  927. <div
  928. v-if="
  929. !quesModel.parentType ||
  930. !isMatchingQuestion(quesModel.parentType)
  931. "
  932. class="option-delete"
  933. >
  934. <el-button
  935. size="mini"
  936. circle
  937. type="danger"
  938. icon="el-icon-delete"
  939. title="删除"
  940. @click.prevent="removeQuesOption(quesOption)"
  941. ></el-button>
  942. </div>
  943. </div>
  944. </el-form-item>
  945. <el-form-item>
  946. <el-button
  947. v-if="
  948. (quesModel.questionType == 'SINGLE_ANSWER_QUESTION' ||
  949. quesModel.questionType == 'MULTIPLE_ANSWER_QUESTION' ||
  950. isMatchingQuestion(quesModel.questionType)) &&
  951. !isMatchingQuestion(quesModel.parentType)
  952. "
  953. type="primary"
  954. @click="addQuesOption"
  955. ><i class="el-icon-plus"></i> 新增选项
  956. </el-button>
  957. </el-form-item>
  958. <!-- 答案 -->
  959. <!-- 填空 -->
  960. <div v-if="quesModel.questionType == 'FILL_BLANK_QUESTION'">
  961. <el-form-item label="答案" prop="quesAnswer">
  962. <div v-if="quesAnswer" class="option-list">
  963. <div
  964. v-for="(opt, index) of quesAnswer"
  965. :key="index"
  966. class="option-item"
  967. >
  968. <div class="option-item-info">
  969. <span>({{ index + 1 }})</span>
  970. </div>
  971. <v-editor
  972. :value="opt"
  973. class="option-item-body"
  974. @change="(val) => updateAnswerPoint(index, val)"
  975. />
  976. </div>
  977. </div>
  978. </el-form-item>
  979. </div>
  980. <!-- 简答 -->
  981. <div v-if="quesModel.questionType === 'TEXT_ANSWER_QUESTION'">
  982. <el-form-item label="答案" prop="quesAnswer">
  983. <v-editor
  984. v-model="quesAnswer"
  985. @change="textAnswerChange"
  986. ></v-editor>
  987. </el-form-item>
  988. </div>
  989. <!-- 单选或多选 -->
  990. <div
  991. v-if="
  992. quesModel.questionType == 'SINGLE_ANSWER_QUESTION' ||
  993. quesModel.questionType == 'MULTIPLE_ANSWER_QUESTION'
  994. "
  995. >
  996. <el-form-item label="答案">
  997. <span v-html="answer"></span>
  998. </el-form-item>
  999. </div>
  1000. <!-- 判断 -->
  1001. <div v-if="quesModel.questionType == 'BOOL_ANSWER_QUESTION'">
  1002. <el-form-item label="答案">
  1003. <el-select
  1004. v-model="quesAnswer"
  1005. placeholder="请选择"
  1006. @change="boolAnswerChange"
  1007. >
  1008. <el-option
  1009. v-for="op in options"
  1010. :key="op.value"
  1011. :label="op.label"
  1012. :value="op.value"
  1013. >
  1014. </el-option>
  1015. </el-select>
  1016. </el-form-item>
  1017. </div>
  1018. </el-form>
  1019. <div slot="footer">
  1020. <el-button type="primary" @click="savePaperDetailUnit()"
  1021. >保存</el-button
  1022. >
  1023. <el-button type="danger" plain @click="closeQuesDialog">取消</el-button>
  1024. </div>
  1025. </el-dialog>
  1026. <!-- 考试说明弹框 -->
  1027. <el-dialog
  1028. title="考试说明编辑"
  1029. :visible.sync="paperRemarkDialog"
  1030. width="600px"
  1031. :modal="false"
  1032. append-to-body
  1033. custom-class="side-dialog"
  1034. >
  1035. <el-form label-position="top">
  1036. <el-form-item label="考试说明:">
  1037. <v-editor v-model="examRemark" :enable-formula="false"></v-editor>
  1038. </el-form-item>
  1039. </el-form>
  1040. <div slot="footer">
  1041. <el-button type="primary" @click="savePaperRemark">保存</el-button>
  1042. <el-button type="danger" plain @click="closPaperRemark">取消</el-button>
  1043. </div>
  1044. </el-dialog>
  1045. <!-- 上传音频弹框 -->
  1046. <el-dialog
  1047. title="上传音频文件"
  1048. :visible.sync="dialogRadioFile"
  1049. :before-close="closeAudioDialog"
  1050. :modal="false"
  1051. width="520px"
  1052. append-to-body
  1053. custom-class="side-dialog"
  1054. >
  1055. <div>
  1056. <div tabindex="0" class="el-upload el-upload--text">
  1057. <el-button
  1058. type="primary"
  1059. icon="icon icon-search-white"
  1060. @click="selectAudioFile"
  1061. >选择文件</el-button
  1062. >
  1063. <input
  1064. id="radioFile"
  1065. class="el-upload__input"
  1066. name="files"
  1067. type="file"
  1068. value="上传音频文件"
  1069. webkitdirectory
  1070. @change="audioFileChange"
  1071. />
  1072. </div>
  1073. <el-button type="warning" @click="checkFile">检查文件名</el-button>
  1074. <el-button
  1075. type="info"
  1076. :loading="uploadAudioLoading"
  1077. :disabled="isUpload || uploadAudioLoading"
  1078. @click="uploadAudioFile"
  1079. >
  1080. <span v-show="!uploadAudioLoading">开始上传</span>
  1081. <span v-show="uploadAudioLoading">正在上传中...</span>
  1082. </el-button>
  1083. </div>
  1084. <p class="tips-info"><i class="el-icon-info"></i>只能上传MP3文件</p>
  1085. <p v-if="audioFileName" class="tips-info">文件: {{ audioFileName }}</p>
  1086. <div v-if="checkResult" style="margin-top: 20px">
  1087. <span>检查结果:</span><br /><br />
  1088. <span v-show="message == 'OK!'" style="color: #13ce66">OK!</span>
  1089. <span v-show="message != 'OK!'" style="color: #ff4949">{{
  1090. message
  1091. }}</span>
  1092. </div>
  1093. </el-dialog>
  1094. <!-- 上传答案文件 -->
  1095. <el-dialog
  1096. title="上传答案文件"
  1097. :visible.sync="dialogAnswerFile"
  1098. :before-close="closeAnswerDialog"
  1099. :modal="false"
  1100. width="520px"
  1101. append-to-body
  1102. custom-class="side-dialog"
  1103. >
  1104. <div>
  1105. <div tabindex="0" class="el-upload el-upload--text">
  1106. <el-button
  1107. type="primary"
  1108. icon="icon icon-search-white"
  1109. @click="selectAnswerFile"
  1110. >选择文件</el-button
  1111. >
  1112. <input
  1113. id="answerFile"
  1114. class="el-upload__input"
  1115. name="answerFiles"
  1116. type="file"
  1117. value="上传答案文件"
  1118. accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
  1119. @change="answerFileChange"
  1120. />
  1121. </div>
  1122. <el-button type="primary" @click="downAnswerTemplate">
  1123. <span>下载模板</span>
  1124. </el-button>
  1125. <el-button
  1126. type="primary"
  1127. :loading="uploadAnswerLoading"
  1128. :disabled="uploadAnswerLoading"
  1129. @click="uploadAnswerFile"
  1130. >
  1131. <span v-show="!uploadAnswerLoading">开始上传</span>
  1132. <span v-show="uploadAnswerLoading">正在上传中...</span>
  1133. </el-button>
  1134. </div>
  1135. <p v-if="answerFileName" class="tips-info">文件: {{ answerFileName }}</p>
  1136. <div style="margin-top: 20px">
  1137. <span v-show="answerMessage != ''" style="color: #ff4949">{{
  1138. answerMessage
  1139. }}</span>
  1140. </div>
  1141. </el-dialog>
  1142. <!-- 基础构成 -->
  1143. <el-dialog
  1144. title="基础构成"
  1145. width="100%"
  1146. :visible.sync="basicDialog"
  1147. :modal="false"
  1148. append-to-body
  1149. custom-class="side-dialog"
  1150. >
  1151. <PaperBasicComposition
  1152. v-if="basicDialog"
  1153. :paper-id="paperId"
  1154. ></PaperBasicComposition>
  1155. </el-dialog>
  1156. <!-- 题型分布 -->
  1157. <el-dialog
  1158. title="题型分布"
  1159. width="100%"
  1160. :visible.sync="typeDialog"
  1161. :modal="false"
  1162. append-to-body
  1163. custom-class="side-dialog"
  1164. >
  1165. <PaperQuestionType
  1166. v-if="typeDialog"
  1167. :paper-id="paperId"
  1168. ></PaperQuestionType>
  1169. </el-dialog>
  1170. <!-- 蓝图分布 -->
  1171. <el-dialog
  1172. title="蓝图分布"
  1173. width="100%"
  1174. :visible.sync="blueDialog"
  1175. :modal="false"
  1176. append-to-body
  1177. custom-class="side-dialog"
  1178. >
  1179. <PaperBlue
  1180. v-if="blueDialog"
  1181. :paper-id="paperId"
  1182. :course-id="paper.course.id"
  1183. ></PaperBlue>
  1184. </el-dialog>
  1185. <!-- 审核记录 -->
  1186. <el-dialog
  1187. title="审核记录"
  1188. width="700px"
  1189. :visible.sync="auditInfoDialog"
  1190. :modal="false"
  1191. append-to-body
  1192. custom-class="side-dialog"
  1193. >
  1194. <AuditInfo v-if="auditInfoDialog" :paper-id="paperId"></AuditInfo>
  1195. </el-dialog>
  1196. <!-- 审核试卷 -->
  1197. <el-dialog
  1198. title="审核试卷"
  1199. width="700px"
  1200. :visible.sync="auditPaperDialog"
  1201. :modal="false"
  1202. append-to-body
  1203. custom-class="side-dialog"
  1204. >
  1205. <AuditPaper
  1206. v-if="auditPaperDialog"
  1207. :paper-ids="selectedPaperIds"
  1208. :audit-result="auditResult"
  1209. @afterAudit="afterAudit"
  1210. ></AuditPaper>
  1211. </el-dialog>
  1212. </div>
  1213. </template>
  1214. <script>
  1215. import { QUESTION_API } from "@/constants/constants";
  1216. import { isEmptyStr, QUESTION_TYPES } from "../constants/constants";
  1217. import { mapState } from "vuex";
  1218. import PaperBasicComposition from "./PaperBasicComposition.vue";
  1219. import PaperQuestionType from "./PaperQuestionType.vue";
  1220. import PaperBlue from "./PaperBlue.vue";
  1221. import AuditInfo from "./AuditInfo.vue";
  1222. import AuditPaper from "./AuditPaper.vue";
  1223. export default {
  1224. name: "EditPaperApp",
  1225. components: {
  1226. PaperBasicComposition,
  1227. PaperQuestionType,
  1228. PaperBlue,
  1229. AuditInfo,
  1230. AuditPaper,
  1231. },
  1232. data() {
  1233. return {
  1234. coursePropertyLoading: false,
  1235. showCheckDuplicateBtn: false,
  1236. selectedPaperIds: [],
  1237. auditPaperDialog: false,
  1238. auditResult: "",
  1239. auditInfoDialog: false,
  1240. blueDialog: false,
  1241. typeDialog: false,
  1242. basicDialog: false,
  1243. quesAnswerShow: true,
  1244. quesTagShow: true,
  1245. hValue: "100px",
  1246. wValue: "500px",
  1247. display: "block",
  1248. uploadAction: "",
  1249. fileList: [],
  1250. answerFileList: [],
  1251. paperId: "",
  1252. paperDetailId: "",
  1253. editPaperDetailUnit: "",
  1254. quesDialog: false,
  1255. paperDatailDialog: false,
  1256. paperRemarkDialog: false,
  1257. parentView: "",
  1258. paper: {
  1259. course: {
  1260. id: "",
  1261. code: "",
  1262. name: "",
  1263. },
  1264. examRemark: "",
  1265. },
  1266. loading: false,
  1267. dialogLoading: false,
  1268. detailLoading: false,
  1269. uploadAudioLoading: false,
  1270. uploadAnswerLoading: false,
  1271. questionTypes: QUESTION_TYPES,
  1272. questionType: "",
  1273. quesModel: { quesProperties: [] },
  1274. quesAnswer: null,
  1275. prevAnswerPointCount: 0,
  1276. editpaperDetail: {},
  1277. reduplicateQuestions: [],
  1278. reduplicateGroup: [],
  1279. reduplicateQuesColor: [],
  1280. singleRightAnswer: "", //接收单选答案
  1281. multipleRightAnswer: [], //接收多选答案
  1282. options: [
  1283. {
  1284. value: 0,
  1285. label: "错误",
  1286. },
  1287. {
  1288. value: 1,
  1289. label: "正确",
  1290. },
  1291. ],
  1292. duplicateLoading: false,
  1293. dialogRadioFile: false,
  1294. dialogAnswerFile: false,
  1295. isUpload: true,
  1296. isUploadAnswer: true,
  1297. message: "",
  1298. answerMessage: "",
  1299. checkResult: false,
  1300. checkResultAnswer: false,
  1301. fileNameList: [],
  1302. defaultColor: [
  1303. "Red",
  1304. "Blue",
  1305. "LimeGreen",
  1306. "GoldenRod",
  1307. "Black",
  1308. "BlueViolet",
  1309. "Chocolate",
  1310. "DarkCyan",
  1311. "HotPink",
  1312. "Orange",
  1313. "IndianRed",
  1314. "Indigo",
  1315. "Green",
  1316. "Aqua",
  1317. "CadetBlue",
  1318. "SkyBlue",
  1319. "SlateBlue",
  1320. "SlateGray",
  1321. "Tomato",
  1322. "VioletRed",
  1323. ],
  1324. difficultyDegreeList: [
  1325. { label: 0.1, value: 0.1 },
  1326. { label: 0.2, value: 0.2 },
  1327. { label: 0.3, value: 0.3 },
  1328. { label: 0.4, value: 0.4 },
  1329. { label: 0.5, value: 0.5 },
  1330. { label: 0.6, value: 0.6 },
  1331. { label: 0.7, value: 0.7 },
  1332. { label: 0.8, value: 0.8 },
  1333. { label: 0.9, value: 0.9 },
  1334. { label: 1.0, value: 1.0 },
  1335. ],
  1336. publicityList: [
  1337. { label: "公开", value: true },
  1338. { label: "非公开", value: false },
  1339. ],
  1340. answerTypes: [
  1341. { label: "文本", value: "DIVERSIFIED_TEXT" },
  1342. { label: "音频", value: "SINGLE_AUDIO" },
  1343. ],
  1344. matchingTypes: [
  1345. { label: "填词", value: 1 },
  1346. { label: "段落", value: 2 },
  1347. ],
  1348. matchingModes: [
  1349. { label: "单用", value: 1 },
  1350. { label: "复用", value: 2 },
  1351. ],
  1352. coursePropertyList: [],
  1353. coursePropertyId: "", //课程属性名
  1354. firstPropertyList: [], //一级属性集合
  1355. firstPropertyId: "", //一级属性id
  1356. secondPropertyList: [], //二级属性集合
  1357. secondPropertyId: "", //二级属性id
  1358. examRemark: "",
  1359. showQuestions: [],
  1360. showButtons: [],
  1361. showSubQuestions: {},
  1362. showSubButtons: {},
  1363. answerFileName: "",
  1364. audioFileName: "",
  1365. };
  1366. },
  1367. computed: {
  1368. ...mapState({
  1369. user: (state) => state.user,
  1370. }),
  1371. updatePorperty() {
  1372. return false;
  1373. },
  1374. answer() {
  1375. if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
  1376. return this.singleRightAnswer;
  1377. } else if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
  1378. var obj = this.multipleRightAnswer;
  1379. return obj.sort().toString();
  1380. }
  1381. return this.quesModel.quesAnswer;
  1382. },
  1383. enableAnswerPoint() {
  1384. return (
  1385. this.quesModel.questionType == "FILL_BLANK_QUESTION" ||
  1386. this.quesModel.questionType == "CLOZE" ||
  1387. this.quesModel.questionType == "BANKED_CLOZE"
  1388. );
  1389. },
  1390. },
  1391. created() {
  1392. let qt = sessionStorage.getItem("quesTagShow");
  1393. if (qt) {
  1394. this.quesTagShow = qt == "true";
  1395. }
  1396. let qa = sessionStorage.getItem("quesAnswerShow");
  1397. if (qa) {
  1398. this.quesAnswerShow = qa == "true";
  1399. }
  1400. document.getElementsByTagName("body")[0].style = "";
  1401. this.paperId = this.$route.params.id;
  1402. this.parentView = this.$route.params.parentView;
  1403. this.initPaper();
  1404. this.uploadAction = QUESTION_API + "/uploadRadio/" + this.paperId;
  1405. this.uploadHeaders = {
  1406. key: this.user.key,
  1407. token: this.user.token,
  1408. };
  1409. },
  1410. methods: {
  1411. getQuesPropertyKey(quesProp) {
  1412. if (!quesProp) {
  1413. return "";
  1414. } else if (quesProp.secondProperty.id) {
  1415. return (
  1416. quesProp.courseProperty.id +
  1417. "-" +
  1418. quesProp.firstProperty.id +
  1419. "-" +
  1420. quesProp.secondProperty.id
  1421. );
  1422. } else {
  1423. return quesProp.courseProperty.id + "-" + quesProp.firstProperty.id;
  1424. }
  1425. },
  1426. getCoursesProperty(name) {
  1427. this.coursePropertyLoading = true;
  1428. this.$httpWithMsg
  1429. .get(
  1430. QUESTION_API +
  1431. "/courseProperty/enable?courseId=" +
  1432. this.paper.course.id +
  1433. "&name=" +
  1434. name
  1435. )
  1436. .then((response) => {
  1437. this.coursePropertyList = response.data;
  1438. this.coursePropertyLoading = false;
  1439. });
  1440. },
  1441. showCheckDuplicate() {
  1442. if (this.paper.checkDuplicateStatus == "DISPOSED") {
  1443. this.showCheckDuplicateBtn = false;
  1444. } else if (this.paper.paperDetails) {
  1445. for (let paperDetilData of this.paper.paperDetails) {
  1446. if (paperDetilData.paperDetailUnits) {
  1447. for (let unit of paperDetilData.paperDetailUnits) {
  1448. if (unit.question.checkDuplicateStatus == "TO_BE_DISPOSE") {
  1449. this.showCheckDuplicateBtn = true;
  1450. return;
  1451. }
  1452. }
  1453. }
  1454. }
  1455. this.showCheckDuplicateBtn = false;
  1456. }
  1457. },
  1458. checkDuplicate() {
  1459. this.$router.push({
  1460. name: "check_duplicate_info",
  1461. query: {
  1462. basePaperId: this.paper.id,
  1463. from: "paper",
  1464. },
  1465. });
  1466. },
  1467. checkDuplicateQuestion(questionId) {
  1468. this.$router.push({
  1469. name: "check_duplicate_info",
  1470. query: {
  1471. quesId: questionId,
  1472. basePaperId: this.paper.id,
  1473. from: "paper",
  1474. },
  1475. });
  1476. },
  1477. isShowEditBtn() {
  1478. if (
  1479. this.paper.creationBy == this.user.userId &&
  1480. (this.paper.auditStatus == "WITHDRAW" ||
  1481. this.paper.auditStatus == "NOT_PASS")
  1482. ) {
  1483. return true;
  1484. } else {
  1485. return false;
  1486. }
  1487. },
  1488. afterAudit() {
  1489. this.auditPaperDialog = false;
  1490. this.back();
  1491. },
  1492. auditPaper(pass) {
  1493. this.auditResult = pass;
  1494. this.selectedPaperIds = [];
  1495. this.selectedPaperIds.push(this.paperId);
  1496. this.auditPaperDialog = true;
  1497. },
  1498. isShowAuditBtn() {
  1499. if (
  1500. this.paper.auditStatus != "WITHDRAW" &&
  1501. this.paper.auditStatus != "NOT_PASS" &&
  1502. this.isMyAudit()
  1503. ) {
  1504. return true;
  1505. } else {
  1506. return false;
  1507. }
  1508. },
  1509. isMyAudit() {
  1510. if (
  1511. this.paper.auditStatus == "FIRST_PENDING_TRIAL" &&
  1512. this.user.auditAuthority == "FIRST"
  1513. ) {
  1514. return true;
  1515. }
  1516. if (
  1517. this.paper.auditStatus == "SECOND_PENDING_TRIAL" &&
  1518. this.user.auditAuthority == "SECOND"
  1519. ) {
  1520. return true;
  1521. }
  1522. if (
  1523. this.paper.auditStatus == "THIRD_PENDING_TRIAL" &&
  1524. this.user.auditAuthority == "THIRD"
  1525. ) {
  1526. return true;
  1527. }
  1528. return false;
  1529. },
  1530. showAuditDialog() {
  1531. this.auditInfoDialog = true;
  1532. },
  1533. showBlueDialog() {
  1534. this.blueDialog = true;
  1535. },
  1536. showTypeDialog() {
  1537. this.typeDialog = true;
  1538. },
  1539. showBasicDialog() {
  1540. this.basicDialog = true;
  1541. },
  1542. quesAnswerShowHide() {
  1543. this.quesAnswerShow = !this.quesAnswerShow;
  1544. sessionStorage.setItem("quesAnswerShow", this.quesAnswerShow);
  1545. },
  1546. quesTagShowHide() {
  1547. this.quesTagShow = !this.quesTagShow;
  1548. sessionStorage.setItem("quesTagShow", this.quesTagShow);
  1549. },
  1550. isMatchingQuestion(questionType) {
  1551. if (
  1552. questionType == "PARAGRAPH_MATCHING" ||
  1553. questionType == "BANKED_CLOZE"
  1554. ) {
  1555. return true;
  1556. } else {
  1557. return false;
  1558. }
  1559. },
  1560. isNested(questionType) {
  1561. if (
  1562. questionType == "PARAGRAPH_MATCHING" ||
  1563. questionType == "BANKED_CLOZE" ||
  1564. questionType == "CLOZE" ||
  1565. questionType == "READING_COMPREHENSION" ||
  1566. questionType == "LISTENING_QUESTION"
  1567. ) {
  1568. return true;
  1569. } else {
  1570. return false;
  1571. }
  1572. },
  1573. otherSelect(optIndex, quesModel) {
  1574. return "该选项被第" + quesModel.optionsSelected[optIndex + 1] + "题选用";
  1575. },
  1576. isInOtherSelect(optIndex, quesModel) {
  1577. if (quesModel.parentQuesParam.matchingMode != 1) {
  1578. return false;
  1579. }
  1580. if (!quesModel.optionsSelected) {
  1581. return false;
  1582. }
  1583. if (!quesModel.optionsSelected[optIndex + 1]) {
  1584. return false;
  1585. }
  1586. if (
  1587. quesModel.optionsSelected[optIndex + 1].includes(quesModel.subNumber)
  1588. ) {
  1589. return false;
  1590. }
  1591. return true;
  1592. },
  1593. movePaperDetailUnitSub(unitid, subid, vector) {
  1594. let vectorStr = vector == "up" ? "上移" : "下移";
  1595. this.$alert("您确定" + vectorStr + "吗?", "提示", {
  1596. confirmButtonText: "确定",
  1597. callback: (action) => {
  1598. if (action == "confirm") {
  1599. this.loading = true;
  1600. this.$http
  1601. .put(
  1602. QUESTION_API +
  1603. "/paperDetailUnit/sub/" +
  1604. unitid +
  1605. "/" +
  1606. subid +
  1607. "/" +
  1608. vector
  1609. )
  1610. .then(() => {
  1611. this.initPaper();
  1612. this.loading = true;
  1613. this.$notify({
  1614. message: vectorStr + "成功",
  1615. type: "success",
  1616. });
  1617. this.loading = false;
  1618. });
  1619. }
  1620. },
  1621. });
  1622. },
  1623. showUnitSubDown(unit, subid) {
  1624. if (unit.question.subQuestions.length <= 1) {
  1625. return false;
  1626. }
  1627. if (
  1628. subid !=
  1629. unit.question.subQuestions[unit.question.subQuestions.length - 1].id
  1630. ) {
  1631. return true;
  1632. } else {
  1633. return false;
  1634. }
  1635. },
  1636. showUnitSubUp(unit, subid) {
  1637. if (unit.question.subQuestions.length <= 1) {
  1638. return false;
  1639. }
  1640. if (subid != unit.question.subQuestions[0].id) {
  1641. return true;
  1642. } else {
  1643. return false;
  1644. }
  1645. },
  1646. movePaperDetailUnit(detailId, unitid, vector) {
  1647. let vectorStr = vector == "up" ? "上移" : "下移";
  1648. this.$alert("您确定" + vectorStr + "吗?", "提示", {
  1649. confirmButtonText: "确定",
  1650. callback: (action) => {
  1651. if (action == "confirm") {
  1652. this.loading = true;
  1653. this.$http
  1654. .put(
  1655. QUESTION_API +
  1656. "/paperDetailUnit/" +
  1657. detailId +
  1658. "/" +
  1659. unitid +
  1660. "/" +
  1661. vector
  1662. )
  1663. .then(() => {
  1664. this.initPaper();
  1665. this.loading = true;
  1666. this.$notify({
  1667. message: vectorStr + "成功",
  1668. type: "success",
  1669. });
  1670. this.loading = false;
  1671. });
  1672. }
  1673. },
  1674. });
  1675. },
  1676. showUnitDown(detail, unitid) {
  1677. if (detail.paperDetailUnits.length <= 1) {
  1678. return false;
  1679. }
  1680. if (
  1681. unitid != detail.paperDetailUnits[detail.paperDetailUnits.length - 1].id
  1682. ) {
  1683. return true;
  1684. } else {
  1685. return false;
  1686. }
  1687. },
  1688. showUnitUp(detail, unitid) {
  1689. if (detail.paperDetailUnits.length <= 1) {
  1690. return false;
  1691. }
  1692. if (unitid != detail.paperDetailUnits[0].id) {
  1693. return true;
  1694. } else {
  1695. return false;
  1696. }
  1697. },
  1698. movePaperDetail(detail, vector) {
  1699. let vectorStr = vector == "up" ? "上移" : "下移";
  1700. this.$alert("您确定" + vectorStr + "吗?", "提示", {
  1701. confirmButtonText: "确定",
  1702. callback: (action) => {
  1703. if (action == "confirm") {
  1704. this.loading = true;
  1705. this.$http
  1706. .put(
  1707. QUESTION_API +
  1708. "/paperDetail/" +
  1709. this.paperId +
  1710. "/" +
  1711. detail.id +
  1712. "/" +
  1713. vector
  1714. )
  1715. .then(() => {
  1716. this.initPaper();
  1717. this.loading = true;
  1718. this.$notify({
  1719. message: vectorStr + "成功",
  1720. type: "success",
  1721. });
  1722. this.loading = false;
  1723. });
  1724. }
  1725. },
  1726. });
  1727. },
  1728. showUp(detail) {
  1729. if (this.paper.paperDetails.length <= 1) {
  1730. return false;
  1731. }
  1732. if (detail.id != this.paper.paperDetails[0].id) {
  1733. return true;
  1734. } else {
  1735. return false;
  1736. }
  1737. },
  1738. showDown(detail) {
  1739. if (this.paper.paperDetails.length <= 1) {
  1740. return false;
  1741. }
  1742. if (
  1743. detail.id !=
  1744. this.paper.paperDetails[this.paper.paperDetails.length - 1].id
  1745. ) {
  1746. return true;
  1747. } else {
  1748. return false;
  1749. }
  1750. },
  1751. downAnswerTemplate() {
  1752. var key = this.user.key;
  1753. var token = this.user.token;
  1754. window.open(
  1755. QUESTION_API + "/paper/answer/template?$key=" + key + "&$token=" + token
  1756. );
  1757. },
  1758. openAnswerDialog() {
  1759. this.checkResultAnswer = false;
  1760. this.isUploadAnswer = true;
  1761. if (document.getElementById("answerFile")) {
  1762. document.getElementById("answerFile").value = "";
  1763. }
  1764. this.answerFileName = "";
  1765. this.dialogAnswerFile = true;
  1766. this.answerFileList = [];
  1767. },
  1768. closeAnswerDialog() {
  1769. this.answerMessage = "";
  1770. this.dialogAnswerFile = this.uploadAnswerLoading;
  1771. },
  1772. selectAnswerFile() {
  1773. document.getElementById("answerFile").click();
  1774. },
  1775. answerFileChange() {
  1776. let fileList = document.getElementById("answerFile").files;
  1777. if (fileList.length == 0) {
  1778. this.answerFileName = "";
  1779. } else {
  1780. this.answerFileName = fileList[0].name;
  1781. }
  1782. },
  1783. uploadAnswerFile() {
  1784. this.answerMessage = "";
  1785. var fileList = document.getElementById("answerFile").files;
  1786. if (fileList.length == 0) {
  1787. this.answerMessage = "请选择文件!";
  1788. return;
  1789. }
  1790. let param = new FormData();
  1791. //循环添加到formData中
  1792. for (var i = 0; i < fileList.length; i++) {
  1793. var file = fileList[i];
  1794. param.append("dataFile", file, file.name);
  1795. }
  1796. let config = {
  1797. headers: { "Content-Type": "multipart/form-data" },
  1798. };
  1799. this.uploadAnswerLoading = true;
  1800. this.$http
  1801. .post(
  1802. QUESTION_API + "/paper/answer/import/" + this.paperId,
  1803. param,
  1804. config
  1805. )
  1806. .then(() => {
  1807. this.dialogAnswerFile = false;
  1808. this.uploadAnswerLoading = false;
  1809. this.checkResultAnswer = false;
  1810. this.isUploadAnswer = true;
  1811. document.getElementById("answerFile").value = "";
  1812. this.initPaper();
  1813. })
  1814. .catch((error) => {
  1815. this.answerMessage = error.response.data.desc;
  1816. document.getElementById("answerFile").value = "";
  1817. this.uploadAnswerLoading = false;
  1818. });
  1819. },
  1820. //隐藏大题下的所有小题
  1821. hideContent(index) {
  1822. this.showQuestions[index].is_show = false;
  1823. this.showButtons[index].up = false;
  1824. },
  1825. //展开大题下所有小题
  1826. showContent(index) {
  1827. this.showQuestions[index].is_show = true;
  1828. this.showButtons[index].up = true;
  1829. },
  1830. //隐藏大题下的所有小题
  1831. hideSubContent(index) {
  1832. this.showSubQuestions[index] = false;
  1833. this.showSubButtons[index] = false;
  1834. this.$forceUpdate();
  1835. },
  1836. //展开大题下所有小题
  1837. showSubContent(index) {
  1838. this.showSubQuestions[index] = true;
  1839. this.showSubButtons[index] = true;
  1840. this.$forceUpdate();
  1841. },
  1842. quesMouseOver(index) {
  1843. document.getElementById(index).style.visibility = "visible";
  1844. },
  1845. quesMouseOut(index) {
  1846. document.getElementById(index).style.visibility = "hidden";
  1847. },
  1848. selectQues(id) {
  1849. this.paperDetailId = id;
  1850. var courseId = this.paper.course.id;
  1851. this.$router.push({
  1852. path:
  1853. "/select_question/" +
  1854. this.paper.id +
  1855. "/" +
  1856. courseId +
  1857. "/" +
  1858. this.paperDetailId +
  1859. "/" +
  1860. this.parentView,
  1861. });
  1862. },
  1863. //打开编辑大题题目弹窗
  1864. openEditPaperDetail(paperDetail) {
  1865. this.paperDatailDialog = true;
  1866. this.editpaperDetail = Object.assign({}, paperDetail); //浅拷贝
  1867. },
  1868. //关闭编辑大题题目弹窗
  1869. closePaperDatailDialog() {
  1870. this.paperDatailDialog = false;
  1871. this.editpaperDetail = {};
  1872. },
  1873. //保存大题题目信息
  1874. savePaperDatail(editpaperDetail) {
  1875. this.detailLoading = true;
  1876. var paperId = this.paper.id;
  1877. this.$http
  1878. .post(QUESTION_API + "/updatePaperDetail/" + paperId, editpaperDetail)
  1879. .then(() => {
  1880. this.$notify({
  1881. message: "保存成功",
  1882. type: "success",
  1883. });
  1884. this.detailLoading = false;
  1885. this.closePaperDatailDialog();
  1886. this.initPaper();
  1887. });
  1888. },
  1889. //初始化试卷
  1890. initPaper() {
  1891. const scrollPosition =
  1892. document.documentElement.scrollTop || document.body.scrollTop;
  1893. this.loading = true;
  1894. this.paper = {
  1895. course: {
  1896. id: "",
  1897. code: "",
  1898. name: "",
  1899. },
  1900. };
  1901. this.$http
  1902. .get(QUESTION_API + "/paper/" + this.paperId)
  1903. .then((response) => {
  1904. this.paper = response.data;
  1905. //查询所有课程属性名
  1906. this.getCoursesProperty("");
  1907. //将所有小题分为公开和非公开
  1908. if (this.paper.paperDetails && this.paper.paperDetails.length > 0) {
  1909. let dindx = 0;
  1910. for (let paperDetil of this.paper.paperDetails) {
  1911. this.showQuestions.push({ is_show: true });
  1912. this.showButtons.push({ up: true });
  1913. paperDetil.pubCount = 0;
  1914. paperDetil.noPubCount = 0;
  1915. if (
  1916. paperDetil.paperDetailUnits &&
  1917. paperDetil.paperDetailUnits.length > 0
  1918. ) {
  1919. let uindx = 0;
  1920. for (let paperDetilUt of paperDetil.paperDetailUnits) {
  1921. this.showSubQuestions[dindx + "-" + uindx] = true;
  1922. this.showSubButtons[dindx + "-" + uindx] = true;
  1923. if (!this.isNested(paperDetilUt.question.questionType)) {
  1924. //非套题
  1925. if (paperDetilUt.question.publicity) {
  1926. paperDetil.pubCount = paperDetil.pubCount + 1;
  1927. } else {
  1928. paperDetil.noPubCount = paperDetil.noPubCount + 1;
  1929. }
  1930. } else {
  1931. //循环所有子题
  1932. for (let ques of paperDetilUt.question.subQuestions) {
  1933. if (ques.publicity) {
  1934. paperDetil.pubCount = paperDetil.pubCount + 1;
  1935. } else {
  1936. paperDetil.noPubCount = paperDetil.noPubCount + 1;
  1937. }
  1938. }
  1939. }
  1940. uindx++;
  1941. }
  1942. }
  1943. dindx++;
  1944. }
  1945. }
  1946. this.showCheckDuplicate();
  1947. setTimeout(() => {
  1948. document.documentElement.scrollTop = document.body.scrollTop =
  1949. scrollPosition;
  1950. console.log(scrollPosition);
  1951. }, 1000);
  1952. this.loading = false;
  1953. });
  1954. },
  1955. //删除大题
  1956. deletePaperDetail(paperDetailsId) {
  1957. //先判断大题下面是否还有小题
  1958. var count = 0;
  1959. for (var i = 0, imax = this.paper.paperDetails.length; i < imax; i++) {
  1960. if (paperDetailsId == this.paper.paperDetails[i].id) {
  1961. if (this.paper.paperDetails[i].paperDetailUnits) {
  1962. count += this.paper.paperDetails[i].paperDetailUnits.length;
  1963. break;
  1964. }
  1965. }
  1966. }
  1967. if (count == 0) {
  1968. this.$alert("您确定删除吗?", "提示", {
  1969. confirmButtonText: "确定",
  1970. callback: (action) => {
  1971. if (action == "confirm") {
  1972. this.loading = true;
  1973. this.$http
  1974. .delete(
  1975. QUESTION_API +
  1976. "/paperDetail/" +
  1977. this.paperId +
  1978. "/" +
  1979. paperDetailsId
  1980. )
  1981. .then(() => {
  1982. this.initPaper();
  1983. this.loading = true;
  1984. this.$notify({
  1985. message: "删除成功",
  1986. type: "success",
  1987. });
  1988. this.loading = false;
  1989. });
  1990. }
  1991. },
  1992. });
  1993. } else {
  1994. this.$alert("大题下还有小题,不可删除!", "提示", {
  1995. confirmButtonText: "确定",
  1996. callback: () => {},
  1997. });
  1998. }
  1999. },
  2000. quesShow(id) {
  2001. if (this.reduplicateGroup.length < 1) {
  2002. return true;
  2003. }
  2004. for (var i = 0, imax = this.reduplicateGroup.length; i < imax; i++) {
  2005. if (id == this.reduplicateGroup[i]) {
  2006. return true;
  2007. }
  2008. }
  2009. return false;
  2010. },
  2011. //编辑题目
  2012. editQues(paperDetailUnit, question) {
  2013. console.log("question:", question);
  2014. this.coursePropertyId = "";
  2015. this.firstPropertyId = "";
  2016. this.secondPropertyId = "";
  2017. this.editPaperDetailUnit = paperDetailUnit;
  2018. this.quesModel = JSON.parse(JSON.stringify(question)); //深拷贝
  2019. if (!this.quesModel.control) {
  2020. this.quesModel.control = {};
  2021. }
  2022. this.quesModel.score = paperDetailUnit.score;
  2023. //如果是套题下面的小题编辑 ( paperDetailUnit的类型是套题,question的类型不是套题)
  2024. if (
  2025. this.isNested(paperDetailUnit.questionType) &&
  2026. question.questionType != paperDetailUnit.questionType
  2027. ) {
  2028. for (var i = 0; i < paperDetailUnit.question.subQuestions.length; i++) {
  2029. if (
  2030. paperDetailUnit.question.subQuestions[i].id == this.quesModel.id
  2031. ) {
  2032. this.quesModel.score = paperDetailUnit.subScoreList[i];
  2033. this.quesModel.parentType = paperDetailUnit.questionType;
  2034. this.quesModel.optionsSelected = paperDetailUnit.optionsSelected;
  2035. this.quesModel.parentQuesParam = paperDetailUnit.question.quesParam;
  2036. break;
  2037. }
  2038. }
  2039. }
  2040. if (isEmptyStr(this.quesModel.answerType)) {
  2041. this.quesModel.answerType = "DIVERSIFIED_TEXT";
  2042. }
  2043. if (this.quesModel.questionType === "BOOL_ANSWER_QUESTION") {
  2044. this.quesAnswer = this.quesModel.quesAnswer === "true" ? 1 : 0;
  2045. } else if (this.quesModel.questionType === "TEXT_ANSWER_QUESTION") {
  2046. const answer = JSON.parse(this.quesModel.quesAnswer);
  2047. this.quesAnswer = answer[0];
  2048. } else if (this.quesModel.questionType == "FILL_BLANK_QUESTION") {
  2049. const answer = JSON.parse(this.quesModel.quesAnswer);
  2050. this.quesAnswer = answer;
  2051. } else {
  2052. this.quesAnswer = null;
  2053. }
  2054. this.prevAnswerPointCount = this.getAnswerPointCount(
  2055. this.quesModel.quesBody
  2056. );
  2057. this.assignAnswers(); //给singleRightAnswer或multipleRightAnswer赋值
  2058. this.openQuesDialog();
  2059. },
  2060. //给singleRightAnswer和multipleRightAnswer赋值
  2061. assignAnswers() {
  2062. if (this.quesModel.quesOptions && this.quesModel.quesOptions.length > 0) {
  2063. this.singleRightAnswer = "";
  2064. this.multipleRightAnswer = [];
  2065. for (let i = 0; i < this.quesModel.quesOptions.length; i++) {
  2066. let option = this.quesModel.quesOptions[i];
  2067. if (
  2068. this.quesModel.questionType == "SINGLE_ANSWER_QUESTION" &&
  2069. option.isCorrect == 1
  2070. ) {
  2071. this.singleRightAnswer = String.fromCharCode(65 + i);
  2072. }
  2073. if (
  2074. this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION" &&
  2075. option.isCorrect == 1
  2076. ) {
  2077. this.multipleRightAnswer.push(String.fromCharCode(65 + i));
  2078. }
  2079. }
  2080. }
  2081. },
  2082. boolAnswerChange(val) {
  2083. this.quesModel.quesAnswer = val ? "true" : "false";
  2084. },
  2085. textAnswerChange(val) {
  2086. this.quesModel.quesAnswer = JSON.stringify([val]);
  2087. },
  2088. resetNumberAndSaveAnswerPoints(answer) {
  2089. this.quesAnswer = answer.map((element, index) => {
  2090. element.index = index + 1;
  2091. return element;
  2092. });
  2093. this.quesModel.quesAnswer = JSON.stringify(this.quesAnswer);
  2094. },
  2095. updateAnswerPoint(index, value) {
  2096. // console.log(index, this.question.answer[index]);
  2097. this.quesAnswer[index] = { ...value };
  2098. this.resetNumberAndSaveAnswerPoints(this.quesAnswer);
  2099. },
  2100. getAnswerPointCount(bodyJson) {
  2101. let count = 0;
  2102. bodyJson.sections.forEach((section) => {
  2103. section.blocks.forEach((block) => {
  2104. if (block.type === "cloze") count++;
  2105. });
  2106. });
  2107. return count;
  2108. },
  2109. quesBodyChange(quesBodyJson) {
  2110. this.quesModel.quesBody = quesBodyJson;
  2111. if (this.quesModel.questionType == "FILL_BLANK_QUESTION") {
  2112. let curPonitCount = this.getAnswerPointCount(quesBodyJson);
  2113. if (curPonitCount === this.prevAnswerPointCount) return;
  2114. this.prevAnswerPointCount = curPonitCount;
  2115. let newAnswer = [];
  2116. for (let i = 0; i < curPonitCount; i++) {
  2117. newAnswer.push(
  2118. (this.quesAnswer && this.quesAnswer[i]) || { sections: [] }
  2119. );
  2120. }
  2121. this.resetNumberAndSaveAnswerPoints(newAnswer);
  2122. }
  2123. },
  2124. //打开修改试题编辑框
  2125. openQuesDialog() {
  2126. this.quesDialog = true;
  2127. },
  2128. //关闭试题编辑框
  2129. closeQuesDialog() {
  2130. this.quesDialog = false;
  2131. this.quesModel = {};
  2132. },
  2133. //删除属性
  2134. handleClose(tag) {
  2135. this.quesModel.quesProperties.splice(
  2136. this.quesModel.quesProperties.indexOf(tag),
  2137. 1
  2138. );
  2139. },
  2140. //查询一级属性
  2141. searchFirst() {
  2142. this.firstPropertyId = "";
  2143. this.secondPropertyId = "";
  2144. this.secondPropertyList = [];
  2145. if (this.coursePropertyId) {
  2146. for (let courseProperty of this.coursePropertyList) {
  2147. if (courseProperty.id == this.coursePropertyId) {
  2148. this.$http
  2149. .get(QUESTION_API + "/property/first/" + courseProperty.id)
  2150. .then((response) => {
  2151. this.firstPropertyList = response.data;
  2152. });
  2153. }
  2154. }
  2155. }
  2156. },
  2157. //查询二级属性
  2158. searchSecond() {
  2159. this.secondPropertyId = "";
  2160. if (this.firstPropertyId) {
  2161. this.$http
  2162. .get(QUESTION_API + "/property/second/" + this.firstPropertyId)
  2163. .then((response) => {
  2164. this.secondPropertyList = response.data;
  2165. });
  2166. }
  2167. },
  2168. //新增属性
  2169. insertProperty() {
  2170. if (!this.checkInsertPro()) {
  2171. return false;
  2172. }
  2173. var quesProperty = {
  2174. key: "",
  2175. courseProperty: {},
  2176. firstProperty: {},
  2177. secondProperty: {},
  2178. };
  2179. if (
  2180. this.quesModel.quesProperties == null ||
  2181. this.quesModel.quesProperties.length == 0
  2182. ) {
  2183. this.quesModel.quesProperties = [];
  2184. }
  2185. let quesPropertyKey =
  2186. this.coursePropertyId +
  2187. "-" +
  2188. this.firstPropertyId +
  2189. "-" +
  2190. this.secondPropertyId;
  2191. for (let quesPro of this.quesModel.quesProperties) {
  2192. if (quesPro.key == quesPropertyKey) {
  2193. this.$notify({
  2194. message: "该属性已存在,请重新选择",
  2195. type: "error",
  2196. });
  2197. return false;
  2198. }
  2199. }
  2200. for (let property of this.coursePropertyList) {
  2201. if (property.id == this.coursePropertyId) {
  2202. quesProperty.courseProperty = property;
  2203. }
  2204. }
  2205. //取到一级属性对象
  2206. for (let property of this.firstPropertyList) {
  2207. if (property.id == this.firstPropertyId) {
  2208. quesProperty.firstProperty = property;
  2209. }
  2210. }
  2211. //判断是否有二级属性
  2212. if (
  2213. this.secondPropertyList != undefined &&
  2214. this.secondPropertyList.length > 0
  2215. ) {
  2216. if (!this.secondPropertyId) {
  2217. this.$notify({
  2218. message: "请选择二级属性",
  2219. type: "error",
  2220. });
  2221. return false;
  2222. }
  2223. }
  2224. //取到二级属性对象
  2225. for (let property of this.secondPropertyList) {
  2226. if (property.id == this.secondPropertyId) {
  2227. quesProperty.secondProperty = property;
  2228. }
  2229. }
  2230. quesProperty.key = this.getQuesPropertyKey(quesProperty);
  2231. this.quesModel.quesProperties.push(quesProperty);
  2232. this.quesModel = Object.assign({}, this.quesModel);
  2233. //清空下拉框
  2234. this.coursePropertyId = "";
  2235. this.firstPropertyId = "";
  2236. this.secondPropertyId = "";
  2237. this.firstPropertyList = [];
  2238. this.secondPropertyList = [];
  2239. },
  2240. //新增属性验证
  2241. checkInsertPro() {
  2242. if (!this.coursePropertyId) {
  2243. this.$notify({
  2244. message: "请选择属性",
  2245. type: "error",
  2246. });
  2247. return false;
  2248. }
  2249. if (!this.firstPropertyId) {
  2250. this.$notify({
  2251. message: "请选择一级属性",
  2252. type: "error",
  2253. });
  2254. return false;
  2255. }
  2256. return true;
  2257. },
  2258. //删除选项
  2259. removeQuesOption(option) {
  2260. if (this.quesModel.quesOptions.length == 1) {
  2261. this.$notify({
  2262. message: "不能删除最后一个选项",
  2263. type: "error",
  2264. });
  2265. return;
  2266. }
  2267. this.singleRightAnswer = "";
  2268. this.multipleRightAnswer = [];
  2269. let index = this.quesModel.quesOptions.indexOf(option);
  2270. if (index !== -1) {
  2271. this.quesModel.quesOptions.splice(index, 1);
  2272. }
  2273. if (this.quesModel.quesOptions.length > 0) {
  2274. for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
  2275. var quesOption = this.quesModel.quesOptions[i];
  2276. quesOption["number"] = i + 1;
  2277. if (quesOption.isCorrect == 1) {
  2278. var answerOrderNum = String.fromCharCode(65 + i);
  2279. if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
  2280. this.singleRightAnswer = answerOrderNum;
  2281. }
  2282. if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
  2283. this.multipleRightAnswer.push(answerOrderNum);
  2284. }
  2285. }
  2286. }
  2287. }
  2288. },
  2289. //新增选项
  2290. addQuesOption() {
  2291. this.quesModel.quesOptions.push({
  2292. number: "",
  2293. optionBody: "",
  2294. isCorrect: "",
  2295. });
  2296. for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
  2297. this.quesModel.quesOptions[i]["number"] = i + 1;
  2298. }
  2299. },
  2300. savePaperDetailUnit() {
  2301. //跟新难度值
  2302. if (this.quesModel.difficultyDegree < 0.4) {
  2303. this.quesModel.difficulty = "难";
  2304. } else if (
  2305. this.quesModel.difficultyDegree > 0.3 &&
  2306. this.quesModel.difficultyDegree < 0.8
  2307. ) {
  2308. this.quesModel.difficulty = "中";
  2309. } else {
  2310. this.quesModel.difficulty = "易";
  2311. }
  2312. this.setRightAnswer();
  2313. if (/^\d+(?=\.{0,1}\d+$|$)/.test(this.quesModel.score)) {
  2314. console.log("正确");
  2315. } else {
  2316. this.$notify({
  2317. message: "分数只能为正数",
  2318. type: "error",
  2319. });
  2320. return;
  2321. }
  2322. if (this.enableAnswerPoint) {
  2323. const pointCount = this.getAnswerPointCount(this.quesModel.quesBody);
  2324. if (!pointCount) {
  2325. this.$notify({
  2326. message: "请插入答题点",
  2327. type: "error",
  2328. });
  2329. return;
  2330. }
  2331. }
  2332. if (this.paper.paperType == "GENERATE") {
  2333. this.$confirm(
  2334. "试题内容修改,会影响所有关联试卷,是否确定进行?",
  2335. "提示",
  2336. {
  2337. confirmButtonText: "确定",
  2338. cancelButtonText: "取消",
  2339. type: "warning",
  2340. }
  2341. ).then(() => {
  2342. this.submitPaperDetailUnit();
  2343. });
  2344. } else {
  2345. this.submitPaperDetailUnit();
  2346. }
  2347. },
  2348. submitPaperDetailUnit() {
  2349. let paperDetailUnitExp = {
  2350. id: this.editPaperDetailUnit.id,
  2351. question: this.quesModel,
  2352. score: this.quesModel.score,
  2353. };
  2354. if (
  2355. this.quesModel.quesOptions &&
  2356. this.quesModel.quesOptions.length == 0
  2357. ) {
  2358. this.$confirm("无选项将删除该试题, 是否继续?", "提示", {
  2359. confirmButtonText: "确定",
  2360. cancelButtonText: "取消",
  2361. type: "warning",
  2362. }).then(() => {
  2363. this.dialogLoading = true;
  2364. this.$http
  2365. .delete(
  2366. QUESTION_API +
  2367. "/paper/deleteQuestion/" +
  2368. this.editPaperDetailUnit.id +
  2369. "/" +
  2370. this.quesModel.id
  2371. )
  2372. .then((response) => {
  2373. if (response.data.length > 0) {
  2374. var deleteInfo =
  2375. "该试题被试卷:" +
  2376. response.data.join(" , ") +
  2377. "使用,不能删除";
  2378. this.$notify({
  2379. message: deleteInfo,
  2380. type: "error",
  2381. });
  2382. } else {
  2383. this.$notify({
  2384. message: "保存成功",
  2385. type: "success",
  2386. });
  2387. }
  2388. this.dialogLoading = false;
  2389. });
  2390. });
  2391. } else {
  2392. this.dialogLoading = true;
  2393. //校验音频重复
  2394. let audiomap = new Map();
  2395. let regex = new RegExp(
  2396. '<a id="[^<>]+" name="([^<>]+\\.mp3)"></a>',
  2397. "ig"
  2398. );
  2399. let ret = "";
  2400. let quesBodyStr = paperDetailUnitExp.question.quesBody;
  2401. if (quesBodyStr) {
  2402. while ((ret = regex.exec(quesBodyStr))) {
  2403. if (audiomap.get(ret[1])) {
  2404. this.dialogLoading = false;
  2405. this.$notify({
  2406. type: "error",
  2407. message: "题干中存在相同的音频文件",
  2408. });
  2409. return;
  2410. } else {
  2411. audiomap.set(ret[1], ret[1]);
  2412. }
  2413. }
  2414. }
  2415. let quesAnswerStr = paperDetailUnitExp.question.quesAnswer;
  2416. if (quesAnswerStr) {
  2417. while ((ret = regex.exec(quesAnswerStr))) {
  2418. if (audiomap.get(ret[1])) {
  2419. this.dialogLoading = false;
  2420. this.$notify({
  2421. type: "error",
  2422. message: "答案中存在相同的音频文件",
  2423. });
  2424. return;
  2425. } else {
  2426. audiomap.set(ret[1], ret[1]);
  2427. }
  2428. }
  2429. }
  2430. let quesOptions = paperDetailUnitExp.question.quesOptions;
  2431. if (quesOptions) {
  2432. for (let i = 0; i < quesOptions.length; i++) {
  2433. let quesOptionStr = quesOptions[i].optionBody;
  2434. while ((ret = regex.exec(quesOptionStr))) {
  2435. if (audiomap.get(ret[1])) {
  2436. this.dialogLoading = false;
  2437. this.$notify({
  2438. type: "error",
  2439. message: "选项中存在相同的音频文件",
  2440. });
  2441. return;
  2442. } else {
  2443. audiomap.set(ret[1], ret[1]);
  2444. }
  2445. }
  2446. }
  2447. }
  2448. // paperDetailUnitExp.question.quesAnswer = this.answer;
  2449. this.$http
  2450. .put(QUESTION_API + "/paperDetailUnit", paperDetailUnitExp)
  2451. .then(() => {
  2452. this.$notify({
  2453. message: "保存成功",
  2454. type: "success",
  2455. });
  2456. this.dialogLoading = false;
  2457. this.closeQuesDialog();
  2458. this.initPaper();
  2459. })
  2460. .catch((err) => {
  2461. this.dialogLoading = false;
  2462. this.$notify({
  2463. type: "error",
  2464. message: err.response.data.desc,
  2465. });
  2466. });
  2467. }
  2468. },
  2469. //在正确的option上设置isCorrect=1
  2470. setRightAnswer() {
  2471. if (
  2472. !this.quesModel.quesOptions ||
  2473. this.quesModel.quesOptions.length == 0
  2474. ) {
  2475. return false;
  2476. }
  2477. let quesAnswer = [];
  2478. for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
  2479. var option = this.quesModel.quesOptions[i];
  2480. var answerOrderNum = String.fromCharCode(65 + i);
  2481. if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
  2482. option["isCorrect"] =
  2483. answerOrderNum == this.singleRightAnswer ? 1 : 0;
  2484. }
  2485. if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
  2486. option["isCorrect"] =
  2487. this.multipleRightAnswer.indexOf(answerOrderNum) > -1 ? 1 : 0;
  2488. }
  2489. if (option["isCorrect"]) quesAnswer.push(i + 1);
  2490. }
  2491. this.quesModel.quesAnswer = JSON.stringify(quesAnswer);
  2492. },
  2493. //删除试题
  2494. deleteQues(paperDetailUnit) {
  2495. let paperDetailUnitId = paperDetailUnit.id;
  2496. if (this.paper.paperType == "GENERATE") {
  2497. this.deleteQues01(paperDetailUnitId);
  2498. } else {
  2499. let questionId = paperDetailUnit.question.id;
  2500. this.deleteQues02(questionId, paperDetailUnitId);
  2501. }
  2502. },
  2503. deleteQues01(paperDetailUnitId) {
  2504. this.$alert("您确定删除吗?", "提示", {
  2505. confirmButtonText: "确定",
  2506. callback: (action) => {
  2507. if (action == "confirm") {
  2508. this.loading = true;
  2509. this.$http
  2510. .delete(QUESTION_API + "/paperDetailUnit/" + paperDetailUnitId)
  2511. .then(() => {
  2512. this.initPaper();
  2513. this.reduplicateGroup = [];
  2514. this.loading = true;
  2515. this.$notify({
  2516. message: "删除成功",
  2517. type: "success",
  2518. });
  2519. this.loading = false;
  2520. });
  2521. }
  2522. },
  2523. });
  2524. },
  2525. deleteQues02(questionId, paperDetailUnitId) {
  2526. this.$alert("您确定删除吗?", "提示", {
  2527. confirmButtonText: "确定",
  2528. callback: (action) => {
  2529. if (action == "confirm") {
  2530. this.loading = true;
  2531. this.$http
  2532. .delete(
  2533. QUESTION_API +
  2534. "/paper/deleteQuestion/" +
  2535. paperDetailUnitId +
  2536. "/" +
  2537. questionId
  2538. )
  2539. .then((response) => {
  2540. if (response.data.length > 0) {
  2541. var deleteInfo =
  2542. "该试题被试卷:" +
  2543. response.data.join(" , ") +
  2544. "使用,不能删除";
  2545. this.$notify({
  2546. message: deleteInfo,
  2547. type: "error",
  2548. });
  2549. } else {
  2550. this.initPaper();
  2551. this.reduplicateGroup = [];
  2552. this.loading = true;
  2553. this.$notify({
  2554. message: "保存成功",
  2555. type: "success",
  2556. });
  2557. }
  2558. this.loading = false;
  2559. });
  2560. }
  2561. },
  2562. });
  2563. },
  2564. exportPaperAnswer() {
  2565. var key = this.user.key;
  2566. var token = this.user.token;
  2567. window.open(
  2568. QUESTION_API +
  2569. "/paper/answer/export/" +
  2570. this.paperId +
  2571. "?$key=" +
  2572. key +
  2573. "&$token=" +
  2574. token
  2575. );
  2576. },
  2577. getSubQuesEditId(paperDetailUnit, subQuestion) {
  2578. return paperDetailUnit.question.id + "_" + subQuestion.subNumber;
  2579. },
  2580. //打开考试说明编辑框
  2581. openEditExamPaperRemark() {
  2582. if (this.paper.examRemark) {
  2583. this.examRemark = this.paper.examRemark;
  2584. } else {
  2585. this.examRemark = "";
  2586. }
  2587. this.paperRemarkDialog = true;
  2588. },
  2589. //保存考试说明
  2590. savePaperRemark() {
  2591. this.paper.examRemark = this.examRemark;
  2592. this.savePaper();
  2593. this.paperRemarkDialog = false;
  2594. },
  2595. //关闭考试说明编辑框
  2596. closPaperRemark() {
  2597. this.examRemark = "";
  2598. this.paperRemarkDialog = false;
  2599. },
  2600. //保存试卷
  2601. savePaper() {
  2602. this.loading = true;
  2603. this.$http
  2604. .put(QUESTION_API + "/paper", this.paper)
  2605. .then(() => {
  2606. this.$notify({
  2607. message: "保存成功",
  2608. type: "success",
  2609. });
  2610. this.loading = false;
  2611. this.initPaper();
  2612. })
  2613. .catch((error) => {
  2614. this.loading = false;
  2615. this.$notify({
  2616. type: "error",
  2617. message: error.response.data.desc,
  2618. });
  2619. });
  2620. },
  2621. //删除试卷
  2622. deletePaper() {
  2623. this.$confirm("确认删除试卷吗?", "提示", {
  2624. type: "warning",
  2625. }).then(() => {
  2626. this.loading = true;
  2627. this.selectedPaperIds = [];
  2628. this.selectedPaperIds.push(this.paper.id);
  2629. this.$http
  2630. .post(
  2631. QUESTION_API + "/paper/audit/delete",
  2632. new URLSearchParams({ paperIds: this.selectedPaperIds })
  2633. )
  2634. .then(
  2635. () => {
  2636. this.$notify({
  2637. message: "删除成功",
  2638. type: "success",
  2639. });
  2640. this.back();
  2641. },
  2642. (error) => {
  2643. this.$notify({
  2644. message: error.response.data.desc,
  2645. type: "error",
  2646. });
  2647. this.loading = false;
  2648. }
  2649. );
  2650. });
  2651. },
  2652. //打开上传音频弹框
  2653. openDialog() {
  2654. this.checkResult = false;
  2655. this.isUpload = true;
  2656. if (document.getElementById("radioFile")) {
  2657. document.getElementById("radioFile").value = "";
  2658. }
  2659. this.audioFileName = "";
  2660. this.dialogRadioFile = true;
  2661. this.fileList = [];
  2662. },
  2663. //关闭音频弹框
  2664. closeAudioDialog() {
  2665. this.dialogRadioFile = this.uploadAudioLoading;
  2666. },
  2667. //返回
  2668. back() {
  2669. if (sessionStorage.getItem("question_back") == "true") {
  2670. this.$router.push({
  2671. path: "/questions/" + this.parentView + "/0",
  2672. });
  2673. } else {
  2674. this.$router.push({
  2675. path: "/questions/" + this.parentView + "/1",
  2676. });
  2677. }
  2678. },
  2679. paperDetailShow(paperDetail) {
  2680. if (this.reduplicateGroup.length == 0) {
  2681. return true;
  2682. }
  2683. let paperDetailUnits = paperDetail.paperDetailUnits;
  2684. for (let i = 0, imax = paperDetailUnits.length; i < imax; i++) {
  2685. for (var j = 0, jmax = this.reduplicateGroup.length; j < jmax; j++) {
  2686. if (paperDetailUnits[i].id == this.reduplicateGroup[j]) {
  2687. return true;
  2688. }
  2689. }
  2690. }
  2691. return false;
  2692. },
  2693. //上传文件检查
  2694. checkFile() {
  2695. this.fileNameList = [];
  2696. //读取选取的文件夹里面的文件
  2697. this.checkResult = true;
  2698. var files = document.getElementById("radioFile").files;
  2699. if (files.length == 0) {
  2700. this.message = "请选择音频文件夹!";
  2701. return;
  2702. }
  2703. var size = 0;
  2704. var isGo = false;
  2705. //取到所有文件的文件名
  2706. for (var i = 0; i < files.length; i++) {
  2707. if (this.checkAudioFormat(files[i].name)) {
  2708. this.fileNameList.push(files[i].name);
  2709. if (files[i].size > 5 * 1024 * 1024) {
  2710. isGo = true;
  2711. break;
  2712. }
  2713. size = files[i].size + size;
  2714. }
  2715. }
  2716. if (isGo) {
  2717. this.message = "上传单个文件不能超过5M";
  2718. this.isUpload = true;
  2719. }
  2720. if (size > 50 * 1024 * 1024) {
  2721. this.message = "上传文件总和不能超过50M";
  2722. this.isUpload = true;
  2723. return;
  2724. }
  2725. this.$http
  2726. .post(
  2727. QUESTION_API + "/checkRadioFile/" + this.paperId,
  2728. this.fileNameList
  2729. )
  2730. .then((response) => {
  2731. console.log("response:", response);
  2732. this.message = response.data.errorMsg;
  2733. if (this.message == "OK") {
  2734. this.message = "OK!";
  2735. this.isUpload = false;
  2736. } else {
  2737. this.isUpload = true;
  2738. }
  2739. })
  2740. .catch((error) => {
  2741. console.log(error);
  2742. });
  2743. },
  2744. checkAudioFormat(name) {
  2745. return name.endsWith(".mp3");
  2746. },
  2747. // 音频文件
  2748. selectAudioFile() {
  2749. document.getElementById("radioFile").click();
  2750. },
  2751. audioFileChange() {
  2752. let fileList = document.getElementById("radioFile").files;
  2753. if (fileList.length == 0) {
  2754. this.audioFileName = "";
  2755. } else {
  2756. let names = [];
  2757. for (var i = 0; i < fileList.length; i++) {
  2758. var file = fileList[i];
  2759. if (this.checkAudioFormat(file.name)) names.push(file.name);
  2760. }
  2761. this.audioFileName = names.join();
  2762. }
  2763. },
  2764. uploadAudioFile() {
  2765. let param = new FormData();
  2766. var fileList = document.getElementById("radioFile").files;
  2767. //循环添加到formData中
  2768. for (var i = 0; i < fileList.length; i++) {
  2769. var file = fileList[i];
  2770. if (this.checkAudioFormat(file.name))
  2771. param.append("files", file, file.name);
  2772. }
  2773. let config = {
  2774. headers: { "Content-Type": "multipart/form-data" },
  2775. };
  2776. this.$http
  2777. .post(QUESTION_API + "/uploadRadio/" + this.paperId, param, config)
  2778. .then(() => {
  2779. this.dialogRadioFile = false;
  2780. this.uploadAudioLoading = false;
  2781. this.checkResult = false;
  2782. this.isUpload = true;
  2783. document.getElementById("radioFile").value = "";
  2784. this.initPaper();
  2785. })
  2786. .catch((error) => {
  2787. this.message = error.response.data.desc;
  2788. this.uploadAudioLoading = false;
  2789. });
  2790. },
  2791. },
  2792. };
  2793. </script>