EditPaperPendingTrial.vue 87 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802
  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 v-if="audioFileName" class="tips-info">文件: {{ audioFileName }}</p>
  1085. <div v-if="checkResult" style="margin-top: 20px">
  1086. <span>检查结果:</span><br /><br />
  1087. <span v-show="message == 'OK!'" style="color: #13ce66">OK!</span>
  1088. <span v-show="message != 'OK!'" style="color: #ff4949">{{
  1089. message
  1090. }}</span>
  1091. </div>
  1092. </el-dialog>
  1093. <!-- 上传答案文件 -->
  1094. <el-dialog
  1095. title="上传答案文件"
  1096. :visible.sync="dialogAnswerFile"
  1097. :before-close="closeAnswerDialog"
  1098. :modal="false"
  1099. width="520px"
  1100. append-to-body
  1101. custom-class="side-dialog"
  1102. >
  1103. <div>
  1104. <div tabindex="0" class="el-upload el-upload--text">
  1105. <el-button
  1106. type="primary"
  1107. icon="icon icon-search-white"
  1108. @click="selectAnswerFile"
  1109. >选择文件</el-button
  1110. >
  1111. <input
  1112. id="answerFile"
  1113. class="el-upload__input"
  1114. name="answerFiles"
  1115. type="file"
  1116. value="上传答案文件"
  1117. accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
  1118. @change="answerFileChange"
  1119. />
  1120. </div>
  1121. <el-button type="primary" @click="downAnswerTemplate">
  1122. <span>下载模板</span>
  1123. </el-button>
  1124. <el-button
  1125. type="primary"
  1126. :loading="uploadAnswerLoading"
  1127. :disabled="uploadAnswerLoading"
  1128. @click="uploadAnswerFile"
  1129. >
  1130. <span v-show="!uploadAnswerLoading">开始上传</span>
  1131. <span v-show="uploadAnswerLoading">正在上传中...</span>
  1132. </el-button>
  1133. </div>
  1134. <p v-if="answerFileName" class="tips-info">文件: {{ answerFileName }}</p>
  1135. <div style="margin-top: 20px">
  1136. <span v-show="answerMessage != ''" style="color: #ff4949">{{
  1137. answerMessage
  1138. }}</span>
  1139. </div>
  1140. </el-dialog>
  1141. <!-- 基础构成 -->
  1142. <el-dialog
  1143. title="基础构成"
  1144. width="100%"
  1145. :visible.sync="basicDialog"
  1146. :modal="false"
  1147. append-to-body
  1148. custom-class="side-dialog"
  1149. >
  1150. <PaperBasicComposition
  1151. v-if="basicDialog"
  1152. :paper-id="paperId"
  1153. ></PaperBasicComposition>
  1154. </el-dialog>
  1155. <!-- 题型分布 -->
  1156. <el-dialog
  1157. title="题型分布"
  1158. width="100%"
  1159. :visible.sync="typeDialog"
  1160. :modal="false"
  1161. append-to-body
  1162. custom-class="side-dialog"
  1163. >
  1164. <PaperQuestionType
  1165. v-if="typeDialog"
  1166. :paper-id="paperId"
  1167. ></PaperQuestionType>
  1168. </el-dialog>
  1169. <!-- 蓝图分布 -->
  1170. <el-dialog
  1171. title="蓝图分布"
  1172. width="100%"
  1173. :visible.sync="blueDialog"
  1174. :modal="false"
  1175. append-to-body
  1176. custom-class="side-dialog"
  1177. >
  1178. <PaperBlue
  1179. v-if="blueDialog"
  1180. :paper-id="paperId"
  1181. :course-id="paper.course.id"
  1182. ></PaperBlue>
  1183. </el-dialog>
  1184. <!-- 审核记录 -->
  1185. <el-dialog
  1186. title="审核记录"
  1187. width="700px"
  1188. :visible.sync="auditInfoDialog"
  1189. :modal="false"
  1190. append-to-body
  1191. custom-class="side-dialog"
  1192. >
  1193. <AuditInfo v-if="auditInfoDialog" :paper-id="paperId"></AuditInfo>
  1194. </el-dialog>
  1195. <!-- 审核试卷 -->
  1196. <el-dialog
  1197. title="审核试卷"
  1198. width="700px"
  1199. :visible.sync="auditPaperDialog"
  1200. :modal="false"
  1201. append-to-body
  1202. custom-class="side-dialog"
  1203. >
  1204. <AuditPaper
  1205. v-if="auditPaperDialog"
  1206. :paper-ids="selectedPaperIds"
  1207. :audit-result="auditResult"
  1208. @afterAudit="afterAudit"
  1209. ></AuditPaper>
  1210. </el-dialog>
  1211. </div>
  1212. </template>
  1213. <script>
  1214. import { QUESTION_API } from "@/constants/constants";
  1215. import { isEmptyStr, QUESTION_TYPES } from "../constants/constants";
  1216. import { mapState } from "vuex";
  1217. import PaperBasicComposition from "./PaperBasicComposition.vue";
  1218. import PaperQuestionType from "./PaperQuestionType.vue";
  1219. import PaperBlue from "./PaperBlue.vue";
  1220. import AuditInfo from "./AuditInfo.vue";
  1221. import AuditPaper from "./AuditPaper.vue";
  1222. export default {
  1223. name: "EditPaperApp",
  1224. components: {
  1225. PaperBasicComposition,
  1226. PaperQuestionType,
  1227. PaperBlue,
  1228. AuditInfo,
  1229. AuditPaper,
  1230. },
  1231. data() {
  1232. return {
  1233. coursePropertyLoading: false,
  1234. showCheckDuplicateBtn: false,
  1235. selectedPaperIds: [],
  1236. auditPaperDialog: false,
  1237. auditResult: "",
  1238. auditInfoDialog: false,
  1239. blueDialog: false,
  1240. typeDialog: false,
  1241. basicDialog: false,
  1242. quesAnswerShow: true,
  1243. quesTagShow: true,
  1244. hValue: "100px",
  1245. wValue: "500px",
  1246. display: "block",
  1247. uploadAction: "",
  1248. fileList: [],
  1249. answerFileList: [],
  1250. paperId: "",
  1251. paperDetailId: "",
  1252. editPaperDetailUnit: "",
  1253. quesDialog: false,
  1254. paperDatailDialog: false,
  1255. paperRemarkDialog: false,
  1256. parentView: "",
  1257. paper: {
  1258. course: {
  1259. id: "",
  1260. code: "",
  1261. name: "",
  1262. },
  1263. examRemark: "",
  1264. },
  1265. loading: false,
  1266. dialogLoading: false,
  1267. detailLoading: false,
  1268. uploadAudioLoading: false,
  1269. uploadAnswerLoading: false,
  1270. questionTypes: QUESTION_TYPES,
  1271. questionType: "",
  1272. quesModel: { quesProperties: [] },
  1273. quesAnswer: null,
  1274. prevAnswerPointCount: 0,
  1275. editpaperDetail: {},
  1276. reduplicateQuestions: [],
  1277. reduplicateGroup: [],
  1278. reduplicateQuesColor: [],
  1279. singleRightAnswer: "", //接收单选答案
  1280. multipleRightAnswer: [], //接收多选答案
  1281. options: [
  1282. {
  1283. value: 0,
  1284. label: "错误",
  1285. },
  1286. {
  1287. value: 1,
  1288. label: "正确",
  1289. },
  1290. ],
  1291. duplicateLoading: false,
  1292. dialogRadioFile: false,
  1293. dialogAnswerFile: false,
  1294. isUpload: true,
  1295. isUploadAnswer: true,
  1296. message: "",
  1297. answerMessage: "",
  1298. checkResult: false,
  1299. checkResultAnswer: false,
  1300. fileNameList: [],
  1301. defaultColor: [
  1302. "Red",
  1303. "Blue",
  1304. "LimeGreen",
  1305. "GoldenRod",
  1306. "Black",
  1307. "BlueViolet",
  1308. "Chocolate",
  1309. "DarkCyan",
  1310. "HotPink",
  1311. "Orange",
  1312. "IndianRed",
  1313. "Indigo",
  1314. "Green",
  1315. "Aqua",
  1316. "CadetBlue",
  1317. "SkyBlue",
  1318. "SlateBlue",
  1319. "SlateGray",
  1320. "Tomato",
  1321. "VioletRed",
  1322. ],
  1323. difficultyDegreeList: [
  1324. { label: 0.1, value: 0.1 },
  1325. { label: 0.2, value: 0.2 },
  1326. { label: 0.3, value: 0.3 },
  1327. { label: 0.4, value: 0.4 },
  1328. { label: 0.5, value: 0.5 },
  1329. { label: 0.6, value: 0.6 },
  1330. { label: 0.7, value: 0.7 },
  1331. { label: 0.8, value: 0.8 },
  1332. { label: 0.9, value: 0.9 },
  1333. { label: 1.0, value: 1.0 },
  1334. ],
  1335. publicityList: [
  1336. { label: "公开", value: true },
  1337. { label: "非公开", value: false },
  1338. ],
  1339. answerTypes: [
  1340. { label: "文本", value: "DIVERSIFIED_TEXT" },
  1341. { label: "音频", value: "SINGLE_AUDIO" },
  1342. ],
  1343. matchingTypes: [
  1344. { label: "填词", value: 1 },
  1345. { label: "段落", value: 2 },
  1346. ],
  1347. matchingModes: [
  1348. { label: "单用", value: 1 },
  1349. { label: "复用", value: 2 },
  1350. ],
  1351. coursePropertyList: [],
  1352. coursePropertyId: "", //课程属性名
  1353. firstPropertyList: [], //一级属性集合
  1354. firstPropertyId: "", //一级属性id
  1355. secondPropertyList: [], //二级属性集合
  1356. secondPropertyId: "", //二级属性id
  1357. examRemark: "",
  1358. showQuestions: [],
  1359. showButtons: [],
  1360. showSubQuestions: {},
  1361. showSubButtons: {},
  1362. answerFileName: "",
  1363. audioFileName: "",
  1364. };
  1365. },
  1366. computed: {
  1367. ...mapState({
  1368. user: (state) => state.user,
  1369. }),
  1370. updatePorperty() {
  1371. return false;
  1372. },
  1373. answer() {
  1374. if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
  1375. return this.singleRightAnswer;
  1376. } else if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
  1377. var obj = this.multipleRightAnswer;
  1378. return obj.sort().toString();
  1379. }
  1380. return this.quesModel.quesAnswer;
  1381. },
  1382. enableAnswerPoint() {
  1383. return (
  1384. this.quesModel.questionType == "FILL_BLANK_QUESTION" ||
  1385. this.quesModel.questionType == "CLOZE" ||
  1386. this.quesModel.questionType == "BANKED_CLOZE"
  1387. );
  1388. },
  1389. },
  1390. created() {
  1391. let qt = sessionStorage.getItem("quesTagShow");
  1392. if (qt) {
  1393. this.quesTagShow = qt == "true";
  1394. }
  1395. let qa = sessionStorage.getItem("quesAnswerShow");
  1396. if (qa) {
  1397. this.quesAnswerShow = qa == "true";
  1398. }
  1399. document.getElementsByTagName("body")[0].style = "";
  1400. this.paperId = this.$route.params.id;
  1401. this.parentView = this.$route.params.parentView;
  1402. this.initPaper();
  1403. this.uploadAction = QUESTION_API + "/uploadRadio/" + this.paperId;
  1404. this.uploadHeaders = {
  1405. key: this.user.key,
  1406. token: this.user.token,
  1407. };
  1408. },
  1409. methods: {
  1410. getQuesPropertyKey(quesProp) {
  1411. if (!quesProp) {
  1412. return "";
  1413. } else if (quesProp.secondProperty.id) {
  1414. return (
  1415. quesProp.courseProperty.id +
  1416. "-" +
  1417. quesProp.firstProperty.id +
  1418. "-" +
  1419. quesProp.secondProperty.id
  1420. );
  1421. } else {
  1422. return quesProp.courseProperty.id + "-" + quesProp.firstProperty.id;
  1423. }
  1424. },
  1425. getCoursesProperty(name) {
  1426. this.coursePropertyLoading = true;
  1427. this.$httpWithMsg
  1428. .get(
  1429. QUESTION_API +
  1430. "/courseProperty/enable?courseId=" +
  1431. this.paper.course.id +
  1432. "&name=" +
  1433. name
  1434. )
  1435. .then((response) => {
  1436. this.coursePropertyList = response.data;
  1437. this.coursePropertyLoading = false;
  1438. });
  1439. },
  1440. showCheckDuplicate() {
  1441. if (this.paper.checkDuplicateStatus == "DISPOSED") {
  1442. this.showCheckDuplicateBtn = false;
  1443. } else if (this.paper.paperDetails) {
  1444. for (let paperDetilData of this.paper.paperDetails) {
  1445. if (paperDetilData.paperDetailUnits) {
  1446. for (let unit of paperDetilData.paperDetailUnits) {
  1447. if (unit.question.checkDuplicateStatus == "TO_BE_DISPOSE") {
  1448. this.showCheckDuplicateBtn = true;
  1449. return;
  1450. }
  1451. }
  1452. }
  1453. }
  1454. this.showCheckDuplicateBtn = false;
  1455. }
  1456. },
  1457. checkDuplicate() {
  1458. this.$router.push({
  1459. name: "check_duplicate_info",
  1460. query: {
  1461. basePaperId: this.paper.id,
  1462. from: "paper",
  1463. },
  1464. });
  1465. },
  1466. checkDuplicateQuestion(questionId) {
  1467. this.$router.push({
  1468. name: "check_duplicate_info",
  1469. query: {
  1470. quesId: questionId,
  1471. basePaperId: this.paper.id,
  1472. from: "paper",
  1473. },
  1474. });
  1475. },
  1476. isShowEditBtn() {
  1477. if (
  1478. this.paper.creationBy == this.user.userId &&
  1479. (this.paper.auditStatus == "WITHDRAW" ||
  1480. this.paper.auditStatus == "NOT_PASS")
  1481. ) {
  1482. return true;
  1483. } else {
  1484. return false;
  1485. }
  1486. },
  1487. afterAudit() {
  1488. this.auditPaperDialog = false;
  1489. this.back();
  1490. },
  1491. auditPaper(pass) {
  1492. this.auditResult = pass;
  1493. this.selectedPaperIds = [];
  1494. this.selectedPaperIds.push(this.paperId);
  1495. this.auditPaperDialog = true;
  1496. },
  1497. isShowAuditBtn() {
  1498. if (
  1499. this.paper.auditStatus != "WITHDRAW" &&
  1500. this.paper.auditStatus != "NOT_PASS" &&
  1501. this.isMyAudit()
  1502. ) {
  1503. return true;
  1504. } else {
  1505. return false;
  1506. }
  1507. },
  1508. isMyAudit() {
  1509. if (
  1510. this.paper.auditStatus == "FIRST_PENDING_TRIAL" &&
  1511. this.user.auditAuthority == "FIRST"
  1512. ) {
  1513. return true;
  1514. }
  1515. if (
  1516. this.paper.auditStatus == "SECOND_PENDING_TRIAL" &&
  1517. this.user.auditAuthority == "SECOND"
  1518. ) {
  1519. return true;
  1520. }
  1521. if (
  1522. this.paper.auditStatus == "THIRD_PENDING_TRIAL" &&
  1523. this.user.auditAuthority == "THIRD"
  1524. ) {
  1525. return true;
  1526. }
  1527. return false;
  1528. },
  1529. showAuditDialog() {
  1530. this.auditInfoDialog = true;
  1531. },
  1532. showBlueDialog() {
  1533. this.blueDialog = true;
  1534. },
  1535. showTypeDialog() {
  1536. this.typeDialog = true;
  1537. },
  1538. showBasicDialog() {
  1539. this.basicDialog = true;
  1540. },
  1541. quesAnswerShowHide() {
  1542. this.quesAnswerShow = !this.quesAnswerShow;
  1543. sessionStorage.setItem("quesAnswerShow", this.quesAnswerShow);
  1544. },
  1545. quesTagShowHide() {
  1546. this.quesTagShow = !this.quesTagShow;
  1547. sessionStorage.setItem("quesTagShow", this.quesTagShow);
  1548. },
  1549. isMatchingQuestion(questionType) {
  1550. if (
  1551. questionType == "PARAGRAPH_MATCHING" ||
  1552. questionType == "BANKED_CLOZE"
  1553. ) {
  1554. return true;
  1555. } else {
  1556. return false;
  1557. }
  1558. },
  1559. isNested(questionType) {
  1560. if (
  1561. questionType == "PARAGRAPH_MATCHING" ||
  1562. questionType == "BANKED_CLOZE" ||
  1563. questionType == "CLOZE" ||
  1564. questionType == "READING_COMPREHENSION" ||
  1565. questionType == "LISTENING_QUESTION"
  1566. ) {
  1567. return true;
  1568. } else {
  1569. return false;
  1570. }
  1571. },
  1572. otherSelect(optIndex, quesModel) {
  1573. return "该选项被第" + quesModel.optionsSelected[optIndex + 1] + "题选用";
  1574. },
  1575. isInOtherSelect(optIndex, quesModel) {
  1576. if (quesModel.parentQuesParam.matchingMode != 1) {
  1577. return false;
  1578. }
  1579. if (!quesModel.optionsSelected) {
  1580. return false;
  1581. }
  1582. if (!quesModel.optionsSelected[optIndex + 1]) {
  1583. return false;
  1584. }
  1585. if (
  1586. quesModel.optionsSelected[optIndex + 1].includes(quesModel.subNumber)
  1587. ) {
  1588. return false;
  1589. }
  1590. return true;
  1591. },
  1592. movePaperDetailUnitSub(unitid, subid, vector) {
  1593. let vectorStr = vector == "up" ? "上移" : "下移";
  1594. this.$alert("您确定" + vectorStr + "吗?", "提示", {
  1595. confirmButtonText: "确定",
  1596. callback: (action) => {
  1597. if (action == "confirm") {
  1598. this.loading = true;
  1599. this.$http
  1600. .put(
  1601. QUESTION_API +
  1602. "/paperDetailUnit/sub/" +
  1603. unitid +
  1604. "/" +
  1605. subid +
  1606. "/" +
  1607. vector
  1608. )
  1609. .then(() => {
  1610. this.initPaper();
  1611. this.loading = true;
  1612. this.$notify({
  1613. message: vectorStr + "成功",
  1614. type: "success",
  1615. });
  1616. this.loading = false;
  1617. });
  1618. }
  1619. },
  1620. });
  1621. },
  1622. showUnitSubDown(unit, subid) {
  1623. if (unit.question.subQuestions.length <= 1) {
  1624. return false;
  1625. }
  1626. if (
  1627. subid !=
  1628. unit.question.subQuestions[unit.question.subQuestions.length - 1].id
  1629. ) {
  1630. return true;
  1631. } else {
  1632. return false;
  1633. }
  1634. },
  1635. showUnitSubUp(unit, subid) {
  1636. if (unit.question.subQuestions.length <= 1) {
  1637. return false;
  1638. }
  1639. if (subid != unit.question.subQuestions[0].id) {
  1640. return true;
  1641. } else {
  1642. return false;
  1643. }
  1644. },
  1645. movePaperDetailUnit(detailId, unitid, vector) {
  1646. let vectorStr = vector == "up" ? "上移" : "下移";
  1647. this.$alert("您确定" + vectorStr + "吗?", "提示", {
  1648. confirmButtonText: "确定",
  1649. callback: (action) => {
  1650. if (action == "confirm") {
  1651. this.loading = true;
  1652. this.$http
  1653. .put(
  1654. QUESTION_API +
  1655. "/paperDetailUnit/" +
  1656. detailId +
  1657. "/" +
  1658. unitid +
  1659. "/" +
  1660. vector
  1661. )
  1662. .then(() => {
  1663. this.initPaper();
  1664. this.loading = true;
  1665. this.$notify({
  1666. message: vectorStr + "成功",
  1667. type: "success",
  1668. });
  1669. this.loading = false;
  1670. });
  1671. }
  1672. },
  1673. });
  1674. },
  1675. showUnitDown(detail, unitid) {
  1676. if (detail.paperDetailUnits.length <= 1) {
  1677. return false;
  1678. }
  1679. if (
  1680. unitid != detail.paperDetailUnits[detail.paperDetailUnits.length - 1].id
  1681. ) {
  1682. return true;
  1683. } else {
  1684. return false;
  1685. }
  1686. },
  1687. showUnitUp(detail, unitid) {
  1688. if (detail.paperDetailUnits.length <= 1) {
  1689. return false;
  1690. }
  1691. if (unitid != detail.paperDetailUnits[0].id) {
  1692. return true;
  1693. } else {
  1694. return false;
  1695. }
  1696. },
  1697. movePaperDetail(detail, vector) {
  1698. let vectorStr = vector == "up" ? "上移" : "下移";
  1699. this.$alert("您确定" + vectorStr + "吗?", "提示", {
  1700. confirmButtonText: "确定",
  1701. callback: (action) => {
  1702. if (action == "confirm") {
  1703. this.loading = true;
  1704. this.$http
  1705. .put(
  1706. QUESTION_API +
  1707. "/paperDetail/" +
  1708. this.paperId +
  1709. "/" +
  1710. detail.id +
  1711. "/" +
  1712. vector
  1713. )
  1714. .then(() => {
  1715. this.initPaper();
  1716. this.loading = true;
  1717. this.$notify({
  1718. message: vectorStr + "成功",
  1719. type: "success",
  1720. });
  1721. this.loading = false;
  1722. });
  1723. }
  1724. },
  1725. });
  1726. },
  1727. showUp(detail) {
  1728. if (this.paper.paperDetails.length <= 1) {
  1729. return false;
  1730. }
  1731. if (detail.id != this.paper.paperDetails[0].id) {
  1732. return true;
  1733. } else {
  1734. return false;
  1735. }
  1736. },
  1737. showDown(detail) {
  1738. if (this.paper.paperDetails.length <= 1) {
  1739. return false;
  1740. }
  1741. if (
  1742. detail.id !=
  1743. this.paper.paperDetails[this.paper.paperDetails.length - 1].id
  1744. ) {
  1745. return true;
  1746. } else {
  1747. return false;
  1748. }
  1749. },
  1750. downAnswerTemplate() {
  1751. var key = this.user.key;
  1752. var token = this.user.token;
  1753. window.open(
  1754. QUESTION_API + "/paper/answer/template?$key=" + key + "&$token=" + token
  1755. );
  1756. },
  1757. openAnswerDialog() {
  1758. this.checkResultAnswer = false;
  1759. this.isUploadAnswer = true;
  1760. if (document.getElementById("answerFile")) {
  1761. document.getElementById("answerFile").value = "";
  1762. }
  1763. this.answerFileName = "";
  1764. this.dialogAnswerFile = true;
  1765. this.answerFileList = [];
  1766. },
  1767. closeAnswerDialog() {
  1768. this.answerMessage = "";
  1769. this.dialogAnswerFile = this.uploadAnswerLoading;
  1770. },
  1771. selectAnswerFile() {
  1772. document.getElementById("answerFile").click();
  1773. },
  1774. answerFileChange() {
  1775. let fileList = document.getElementById("answerFile").files;
  1776. if (fileList.length == 0) {
  1777. this.answerFileName = "";
  1778. } else {
  1779. this.answerFileName = fileList[0].name;
  1780. }
  1781. },
  1782. uploadAnswerFile() {
  1783. this.answerMessage = "";
  1784. var fileList = document.getElementById("answerFile").files;
  1785. if (fileList.length == 0) {
  1786. this.answerMessage = "请选择文件!";
  1787. return;
  1788. }
  1789. let param = new FormData();
  1790. //循环添加到formData中
  1791. for (var i = 0; i < fileList.length; i++) {
  1792. var file = fileList[i];
  1793. param.append("dataFile", file, file.name);
  1794. }
  1795. let config = {
  1796. headers: { "Content-Type": "multipart/form-data" },
  1797. };
  1798. this.uploadAnswerLoading = true;
  1799. this.$http
  1800. .post(
  1801. QUESTION_API + "/paper/answer/import/" + this.paperId,
  1802. param,
  1803. config
  1804. )
  1805. .then(() => {
  1806. this.dialogAnswerFile = false;
  1807. this.uploadAnswerLoading = false;
  1808. this.checkResultAnswer = false;
  1809. this.isUploadAnswer = true;
  1810. document.getElementById("answerFile").value = "";
  1811. this.initPaper();
  1812. })
  1813. .catch((error) => {
  1814. this.answerMessage = error.response.data.desc;
  1815. document.getElementById("answerFile").value = "";
  1816. this.uploadAnswerLoading = false;
  1817. });
  1818. },
  1819. //隐藏大题下的所有小题
  1820. hideContent(index) {
  1821. this.showQuestions[index].is_show = false;
  1822. this.showButtons[index].up = false;
  1823. },
  1824. //展开大题下所有小题
  1825. showContent(index) {
  1826. this.showQuestions[index].is_show = true;
  1827. this.showButtons[index].up = true;
  1828. },
  1829. //隐藏大题下的所有小题
  1830. hideSubContent(index) {
  1831. this.showSubQuestions[index] = false;
  1832. this.showSubButtons[index] = false;
  1833. this.$forceUpdate();
  1834. },
  1835. //展开大题下所有小题
  1836. showSubContent(index) {
  1837. this.showSubQuestions[index] = true;
  1838. this.showSubButtons[index] = true;
  1839. this.$forceUpdate();
  1840. },
  1841. quesMouseOver(index) {
  1842. document.getElementById(index).style.visibility = "visible";
  1843. },
  1844. quesMouseOut(index) {
  1845. document.getElementById(index).style.visibility = "hidden";
  1846. },
  1847. selectQues(id) {
  1848. this.paperDetailId = id;
  1849. var courseId = this.paper.course.id;
  1850. this.$router.push({
  1851. path:
  1852. "/select_question/" +
  1853. this.paper.id +
  1854. "/" +
  1855. courseId +
  1856. "/" +
  1857. this.paperDetailId +
  1858. "/" +
  1859. this.parentView,
  1860. });
  1861. },
  1862. //打开编辑大题题目弹窗
  1863. openEditPaperDetail(paperDetail) {
  1864. this.paperDatailDialog = true;
  1865. this.editpaperDetail = Object.assign({}, paperDetail); //浅拷贝
  1866. },
  1867. //关闭编辑大题题目弹窗
  1868. closePaperDatailDialog() {
  1869. this.paperDatailDialog = false;
  1870. this.editpaperDetail = {};
  1871. },
  1872. //保存大题题目信息
  1873. savePaperDatail(editpaperDetail) {
  1874. this.detailLoading = true;
  1875. var paperId = this.paper.id;
  1876. this.$http
  1877. .post(QUESTION_API + "/updatePaperDetail/" + paperId, editpaperDetail)
  1878. .then(() => {
  1879. this.$notify({
  1880. message: "保存成功",
  1881. type: "success",
  1882. });
  1883. this.detailLoading = false;
  1884. this.closePaperDatailDialog();
  1885. this.initPaper();
  1886. });
  1887. },
  1888. //初始化试卷
  1889. initPaper() {
  1890. const scrollPosition =
  1891. document.documentElement.scrollTop || document.body.scrollTop;
  1892. this.loading = true;
  1893. this.paper = {
  1894. course: {
  1895. id: "",
  1896. code: "",
  1897. name: "",
  1898. },
  1899. };
  1900. this.$http
  1901. .get(QUESTION_API + "/paper/" + this.paperId)
  1902. .then((response) => {
  1903. this.paper = response.data;
  1904. //查询所有课程属性名
  1905. this.getCoursesProperty("");
  1906. //将所有小题分为公开和非公开
  1907. if (this.paper.paperDetails && this.paper.paperDetails.length > 0) {
  1908. let dindx = 0;
  1909. for (let paperDetil of this.paper.paperDetails) {
  1910. this.showQuestions.push({ is_show: true });
  1911. this.showButtons.push({ up: true });
  1912. paperDetil.pubCount = 0;
  1913. paperDetil.noPubCount = 0;
  1914. if (
  1915. paperDetil.paperDetailUnits &&
  1916. paperDetil.paperDetailUnits.length > 0
  1917. ) {
  1918. let uindx = 0;
  1919. for (let paperDetilUt of paperDetil.paperDetailUnits) {
  1920. this.showSubQuestions[dindx + "-" + uindx] = true;
  1921. this.showSubButtons[dindx + "-" + uindx] = true;
  1922. if (!this.isNested(paperDetilUt.question.questionType)) {
  1923. //非套题
  1924. if (paperDetilUt.question.publicity) {
  1925. paperDetil.pubCount = paperDetil.pubCount + 1;
  1926. } else {
  1927. paperDetil.noPubCount = paperDetil.noPubCount + 1;
  1928. }
  1929. } else {
  1930. //循环所有子题
  1931. for (let ques of paperDetilUt.question.subQuestions) {
  1932. if (ques.publicity) {
  1933. paperDetil.pubCount = paperDetil.pubCount + 1;
  1934. } else {
  1935. paperDetil.noPubCount = paperDetil.noPubCount + 1;
  1936. }
  1937. }
  1938. }
  1939. uindx++;
  1940. }
  1941. }
  1942. dindx++;
  1943. }
  1944. }
  1945. this.showCheckDuplicate();
  1946. setTimeout(() => {
  1947. document.documentElement.scrollTop = document.body.scrollTop =
  1948. scrollPosition;
  1949. console.log(scrollPosition);
  1950. }, 1000);
  1951. this.loading = false;
  1952. });
  1953. },
  1954. //删除大题
  1955. deletePaperDetail(paperDetailsId) {
  1956. //先判断大题下面是否还有小题
  1957. var count = 0;
  1958. for (var i = 0, imax = this.paper.paperDetails.length; i < imax; i++) {
  1959. if (paperDetailsId == this.paper.paperDetails[i].id) {
  1960. if (this.paper.paperDetails[i].paperDetailUnits) {
  1961. count += this.paper.paperDetails[i].paperDetailUnits.length;
  1962. break;
  1963. }
  1964. }
  1965. }
  1966. if (count == 0) {
  1967. this.$alert("您确定删除吗?", "提示", {
  1968. confirmButtonText: "确定",
  1969. callback: (action) => {
  1970. if (action == "confirm") {
  1971. this.loading = true;
  1972. this.$http
  1973. .delete(
  1974. QUESTION_API +
  1975. "/paperDetail/" +
  1976. this.paperId +
  1977. "/" +
  1978. paperDetailsId
  1979. )
  1980. .then(() => {
  1981. this.initPaper();
  1982. this.loading = true;
  1983. this.$notify({
  1984. message: "删除成功",
  1985. type: "success",
  1986. });
  1987. this.loading = false;
  1988. });
  1989. }
  1990. },
  1991. });
  1992. } else {
  1993. this.$alert("大题下还有小题,不可删除!", "提示", {
  1994. confirmButtonText: "确定",
  1995. callback: () => {},
  1996. });
  1997. }
  1998. },
  1999. quesShow(id) {
  2000. if (this.reduplicateGroup.length < 1) {
  2001. return true;
  2002. }
  2003. for (var i = 0, imax = this.reduplicateGroup.length; i < imax; i++) {
  2004. if (id == this.reduplicateGroup[i]) {
  2005. return true;
  2006. }
  2007. }
  2008. return false;
  2009. },
  2010. //编辑题目
  2011. editQues(paperDetailUnit, question) {
  2012. console.log("question:", question);
  2013. this.coursePropertyId = "";
  2014. this.firstPropertyId = "";
  2015. this.secondPropertyId = "";
  2016. this.editPaperDetailUnit = paperDetailUnit;
  2017. this.quesModel = JSON.parse(JSON.stringify(question)); //深拷贝
  2018. if (!this.quesModel.control) {
  2019. this.quesModel.control = {};
  2020. }
  2021. this.quesModel.score = paperDetailUnit.score;
  2022. //如果是套题下面的小题编辑 ( paperDetailUnit的类型是套题,question的类型不是套题)
  2023. if (
  2024. this.isNested(paperDetailUnit.questionType) &&
  2025. question.questionType != paperDetailUnit.questionType
  2026. ) {
  2027. for (var i = 0; i < paperDetailUnit.question.subQuestions.length; i++) {
  2028. if (
  2029. paperDetailUnit.question.subQuestions[i].id == this.quesModel.id
  2030. ) {
  2031. this.quesModel.score = paperDetailUnit.subScoreList[i];
  2032. this.quesModel.parentType = paperDetailUnit.questionType;
  2033. this.quesModel.optionsSelected = paperDetailUnit.optionsSelected;
  2034. this.quesModel.parentQuesParam = paperDetailUnit.question.quesParam;
  2035. break;
  2036. }
  2037. }
  2038. }
  2039. if (isEmptyStr(this.quesModel.answerType)) {
  2040. this.quesModel.answerType = "DIVERSIFIED_TEXT";
  2041. }
  2042. if (this.quesModel.questionType === "BOOL_ANSWER_QUESTION") {
  2043. this.quesAnswer = this.quesModel.quesAnswer === "true" ? 1 : 0;
  2044. } else if (this.quesModel.questionType === "TEXT_ANSWER_QUESTION") {
  2045. const answer = JSON.parse(this.quesModel.quesAnswer);
  2046. this.quesAnswer = answer[0];
  2047. } else if (this.quesModel.questionType == "FILL_BLANK_QUESTION") {
  2048. const answer = JSON.parse(this.quesModel.quesAnswer);
  2049. this.quesAnswer = answer;
  2050. } else {
  2051. this.quesAnswer = null;
  2052. }
  2053. this.prevAnswerPointCount = this.getAnswerPointCount(
  2054. this.quesModel.quesBody
  2055. );
  2056. this.assignAnswers(); //给singleRightAnswer或multipleRightAnswer赋值
  2057. this.openQuesDialog();
  2058. },
  2059. //给singleRightAnswer和multipleRightAnswer赋值
  2060. assignAnswers() {
  2061. if (this.quesModel.quesOptions && this.quesModel.quesOptions.length > 0) {
  2062. this.singleRightAnswer = "";
  2063. this.multipleRightAnswer = [];
  2064. for (let i = 0; i < this.quesModel.quesOptions.length; i++) {
  2065. let option = this.quesModel.quesOptions[i];
  2066. if (
  2067. this.quesModel.questionType == "SINGLE_ANSWER_QUESTION" &&
  2068. option.isCorrect == 1
  2069. ) {
  2070. this.singleRightAnswer = String.fromCharCode(65 + i);
  2071. }
  2072. if (
  2073. this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION" &&
  2074. option.isCorrect == 1
  2075. ) {
  2076. this.multipleRightAnswer.push(String.fromCharCode(65 + i));
  2077. }
  2078. }
  2079. }
  2080. },
  2081. boolAnswerChange(val) {
  2082. this.quesModel.quesAnswer = val ? "true" : "false";
  2083. },
  2084. textAnswerChange(val) {
  2085. this.quesModel.quesAnswer = JSON.stringify([val]);
  2086. },
  2087. resetNumberAndSaveAnswerPoints(answer) {
  2088. this.quesAnswer = answer.map((element, index) => {
  2089. element.index = index + 1;
  2090. return element;
  2091. });
  2092. this.quesModel.quesAnswer = JSON.stringify(this.quesAnswer);
  2093. },
  2094. updateAnswerPoint(index, value) {
  2095. // console.log(index, this.question.answer[index]);
  2096. this.quesAnswer[index] = { ...value };
  2097. this.resetNumberAndSaveAnswerPoints(this.quesAnswer);
  2098. },
  2099. getAnswerPointCount(bodyJson) {
  2100. let count = 0;
  2101. bodyJson.sections.forEach((section) => {
  2102. section.blocks.forEach((block) => {
  2103. if (block.type === "cloze") count++;
  2104. });
  2105. });
  2106. return count;
  2107. },
  2108. quesBodyChange(quesBodyJson) {
  2109. this.quesModel.quesBody = quesBodyJson;
  2110. if (this.quesModel.questionType == "FILL_BLANK_QUESTION") {
  2111. let curPonitCount = this.getAnswerPointCount(quesBodyJson);
  2112. if (curPonitCount === this.prevAnswerPointCount) return;
  2113. this.prevAnswerPointCount = curPonitCount;
  2114. let newAnswer = [];
  2115. for (let i = 0; i < curPonitCount; i++) {
  2116. newAnswer.push(
  2117. (this.quesAnswer && this.quesAnswer[i]) || { sections: [] }
  2118. );
  2119. }
  2120. this.resetNumberAndSaveAnswerPoints(newAnswer);
  2121. }
  2122. },
  2123. //打开修改试题编辑框
  2124. openQuesDialog() {
  2125. this.quesDialog = true;
  2126. },
  2127. //关闭试题编辑框
  2128. closeQuesDialog() {
  2129. this.quesDialog = false;
  2130. this.quesModel = {};
  2131. },
  2132. //删除属性
  2133. handleClose(tag) {
  2134. this.quesModel.quesProperties.splice(
  2135. this.quesModel.quesProperties.indexOf(tag),
  2136. 1
  2137. );
  2138. },
  2139. //查询一级属性
  2140. searchFirst() {
  2141. this.firstPropertyId = "";
  2142. this.secondPropertyId = "";
  2143. this.secondPropertyList = [];
  2144. if (this.coursePropertyId) {
  2145. for (let courseProperty of this.coursePropertyList) {
  2146. if (courseProperty.id == this.coursePropertyId) {
  2147. this.$http
  2148. .get(QUESTION_API + "/property/first/" + courseProperty.id)
  2149. .then((response) => {
  2150. this.firstPropertyList = response.data;
  2151. });
  2152. }
  2153. }
  2154. }
  2155. },
  2156. //查询二级属性
  2157. searchSecond() {
  2158. this.secondPropertyId = "";
  2159. if (this.firstPropertyId) {
  2160. this.$http
  2161. .get(QUESTION_API + "/property/second/" + this.firstPropertyId)
  2162. .then((response) => {
  2163. this.secondPropertyList = response.data;
  2164. });
  2165. }
  2166. },
  2167. //新增属性
  2168. insertProperty() {
  2169. if (!this.checkInsertPro()) {
  2170. return false;
  2171. }
  2172. var quesProperty = {
  2173. key: "",
  2174. courseProperty: {},
  2175. firstProperty: {},
  2176. secondProperty: {},
  2177. };
  2178. if (
  2179. this.quesModel.quesProperties == null ||
  2180. this.quesModel.quesProperties.length == 0
  2181. ) {
  2182. this.quesModel.quesProperties = [];
  2183. }
  2184. let quesPropertyKey =
  2185. this.coursePropertyId +
  2186. "-" +
  2187. this.firstPropertyId +
  2188. "-" +
  2189. this.secondPropertyId;
  2190. for (let quesPro of this.quesModel.quesProperties) {
  2191. if (quesPro.key == quesPropertyKey) {
  2192. this.$notify({
  2193. message: "该属性已存在,请重新选择",
  2194. type: "error",
  2195. });
  2196. return false;
  2197. }
  2198. }
  2199. for (let property of this.coursePropertyList) {
  2200. if (property.id == this.coursePropertyId) {
  2201. quesProperty.courseProperty = property;
  2202. }
  2203. }
  2204. //取到一级属性对象
  2205. for (let property of this.firstPropertyList) {
  2206. if (property.id == this.firstPropertyId) {
  2207. quesProperty.firstProperty = property;
  2208. }
  2209. }
  2210. //判断是否有二级属性
  2211. if (
  2212. this.secondPropertyList != undefined &&
  2213. this.secondPropertyList.length > 0
  2214. ) {
  2215. if (!this.secondPropertyId) {
  2216. this.$notify({
  2217. message: "请选择二级属性",
  2218. type: "error",
  2219. });
  2220. return false;
  2221. }
  2222. }
  2223. //取到二级属性对象
  2224. for (let property of this.secondPropertyList) {
  2225. if (property.id == this.secondPropertyId) {
  2226. quesProperty.secondProperty = property;
  2227. }
  2228. }
  2229. quesProperty.key = this.getQuesPropertyKey(quesProperty);
  2230. this.quesModel.quesProperties.push(quesProperty);
  2231. this.quesModel = Object.assign({}, this.quesModel);
  2232. //清空下拉框
  2233. this.coursePropertyId = "";
  2234. this.firstPropertyId = "";
  2235. this.secondPropertyId = "";
  2236. this.firstPropertyList = [];
  2237. this.secondPropertyList = [];
  2238. },
  2239. //新增属性验证
  2240. checkInsertPro() {
  2241. if (!this.coursePropertyId) {
  2242. this.$notify({
  2243. message: "请选择属性",
  2244. type: "error",
  2245. });
  2246. return false;
  2247. }
  2248. if (!this.firstPropertyId) {
  2249. this.$notify({
  2250. message: "请选择一级属性",
  2251. type: "error",
  2252. });
  2253. return false;
  2254. }
  2255. return true;
  2256. },
  2257. //删除选项
  2258. removeQuesOption(option) {
  2259. if (this.quesModel.quesOptions.length == 1) {
  2260. this.$notify({
  2261. message: "不能删除最后一个选项",
  2262. type: "error",
  2263. });
  2264. return;
  2265. }
  2266. this.singleRightAnswer = "";
  2267. this.multipleRightAnswer = [];
  2268. let index = this.quesModel.quesOptions.indexOf(option);
  2269. if (index !== -1) {
  2270. this.quesModel.quesOptions.splice(index, 1);
  2271. }
  2272. if (this.quesModel.quesOptions.length > 0) {
  2273. for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
  2274. var quesOption = this.quesModel.quesOptions[i];
  2275. quesOption["number"] = i + 1;
  2276. if (quesOption.isCorrect == 1) {
  2277. var answerOrderNum = String.fromCharCode(65 + i);
  2278. if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
  2279. this.singleRightAnswer = answerOrderNum;
  2280. }
  2281. if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
  2282. this.multipleRightAnswer.push(answerOrderNum);
  2283. }
  2284. }
  2285. }
  2286. }
  2287. },
  2288. //新增选项
  2289. addQuesOption() {
  2290. this.quesModel.quesOptions.push({
  2291. number: "",
  2292. optionBody: "",
  2293. isCorrect: "",
  2294. });
  2295. for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
  2296. this.quesModel.quesOptions[i]["number"] = i + 1;
  2297. }
  2298. },
  2299. savePaperDetailUnit() {
  2300. //跟新难度值
  2301. if (this.quesModel.difficultyDegree < 0.4) {
  2302. this.quesModel.difficulty = "难";
  2303. } else if (
  2304. this.quesModel.difficultyDegree > 0.3 &&
  2305. this.quesModel.difficultyDegree < 0.8
  2306. ) {
  2307. this.quesModel.difficulty = "中";
  2308. } else {
  2309. this.quesModel.difficulty = "易";
  2310. }
  2311. this.setRightAnswer();
  2312. if (/^\d+(?=\.{0,1}\d+$|$)/.test(this.quesModel.score)) {
  2313. console.log("正确");
  2314. } else {
  2315. this.$notify({
  2316. message: "分数只能为正数",
  2317. type: "error",
  2318. });
  2319. return;
  2320. }
  2321. if (this.enableAnswerPoint) {
  2322. const pointCount = this.getAnswerPointCount(this.quesModel.quesBody);
  2323. if (!pointCount) {
  2324. this.$notify({
  2325. message: "请插入答题点",
  2326. type: "error",
  2327. });
  2328. return;
  2329. }
  2330. }
  2331. if (this.paper.paperType == "GENERATE") {
  2332. this.$confirm(
  2333. "试题内容修改,会影响所有关联试卷,是否确定进行?",
  2334. "提示",
  2335. {
  2336. confirmButtonText: "确定",
  2337. cancelButtonText: "取消",
  2338. type: "warning",
  2339. }
  2340. ).then(() => {
  2341. this.submitPaperDetailUnit();
  2342. });
  2343. } else {
  2344. this.submitPaperDetailUnit();
  2345. }
  2346. },
  2347. submitPaperDetailUnit() {
  2348. let paperDetailUnitExp = {
  2349. id: this.editPaperDetailUnit.id,
  2350. question: this.quesModel,
  2351. score: this.quesModel.score,
  2352. };
  2353. if (
  2354. this.quesModel.quesOptions &&
  2355. this.quesModel.quesOptions.length == 0
  2356. ) {
  2357. this.$confirm("无选项将删除该试题, 是否继续?", "提示", {
  2358. confirmButtonText: "确定",
  2359. cancelButtonText: "取消",
  2360. type: "warning",
  2361. }).then(() => {
  2362. this.dialogLoading = true;
  2363. this.$http
  2364. .delete(
  2365. QUESTION_API +
  2366. "/paper/deleteQuestion/" +
  2367. this.editPaperDetailUnit.id +
  2368. "/" +
  2369. this.quesModel.id
  2370. )
  2371. .then((response) => {
  2372. if (response.data.length > 0) {
  2373. var deleteInfo =
  2374. "该试题被试卷:" +
  2375. response.data.join(" , ") +
  2376. "使用,不能删除";
  2377. this.$notify({
  2378. message: deleteInfo,
  2379. type: "error",
  2380. });
  2381. } else {
  2382. this.$notify({
  2383. message: "保存成功",
  2384. type: "success",
  2385. });
  2386. }
  2387. this.dialogLoading = false;
  2388. });
  2389. });
  2390. } else {
  2391. this.dialogLoading = true;
  2392. //校验音频重复
  2393. let audiomap = new Map();
  2394. let regex = new RegExp(
  2395. '<a id="[^<>]+" name="([^<>]+\\.mp3)"></a>',
  2396. "ig"
  2397. );
  2398. let ret = "";
  2399. let quesBodyStr = paperDetailUnitExp.question.quesBody;
  2400. if (quesBodyStr) {
  2401. while ((ret = regex.exec(quesBodyStr))) {
  2402. if (audiomap.get(ret[1])) {
  2403. this.dialogLoading = false;
  2404. this.$notify({
  2405. type: "error",
  2406. message: "题干中存在相同的音频文件",
  2407. });
  2408. return;
  2409. } else {
  2410. audiomap.set(ret[1], ret[1]);
  2411. }
  2412. }
  2413. }
  2414. let quesAnswerStr = paperDetailUnitExp.question.quesAnswer;
  2415. if (quesAnswerStr) {
  2416. while ((ret = regex.exec(quesAnswerStr))) {
  2417. if (audiomap.get(ret[1])) {
  2418. this.dialogLoading = false;
  2419. this.$notify({
  2420. type: "error",
  2421. message: "答案中存在相同的音频文件",
  2422. });
  2423. return;
  2424. } else {
  2425. audiomap.set(ret[1], ret[1]);
  2426. }
  2427. }
  2428. }
  2429. let quesOptions = paperDetailUnitExp.question.quesOptions;
  2430. if (quesOptions) {
  2431. for (let i = 0; i < quesOptions.length; i++) {
  2432. let quesOptionStr = quesOptions[i].optionBody;
  2433. while ((ret = regex.exec(quesOptionStr))) {
  2434. if (audiomap.get(ret[1])) {
  2435. this.dialogLoading = false;
  2436. this.$notify({
  2437. type: "error",
  2438. message: "选项中存在相同的音频文件",
  2439. });
  2440. return;
  2441. } else {
  2442. audiomap.set(ret[1], ret[1]);
  2443. }
  2444. }
  2445. }
  2446. }
  2447. // paperDetailUnitExp.question.quesAnswer = this.answer;
  2448. this.$http
  2449. .put(QUESTION_API + "/paperDetailUnit", paperDetailUnitExp)
  2450. .then(() => {
  2451. this.$notify({
  2452. message: "保存成功",
  2453. type: "success",
  2454. });
  2455. this.dialogLoading = false;
  2456. this.closeQuesDialog();
  2457. this.initPaper();
  2458. })
  2459. .catch((err) => {
  2460. this.dialogLoading = false;
  2461. this.$notify({
  2462. type: "error",
  2463. message: err.response.data.desc,
  2464. });
  2465. });
  2466. }
  2467. },
  2468. //在正确的option上设置isCorrect=1
  2469. setRightAnswer() {
  2470. if (
  2471. !this.quesModel.quesOptions ||
  2472. this.quesModel.quesOptions.length == 0
  2473. ) {
  2474. return false;
  2475. }
  2476. let quesAnswer = [];
  2477. for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
  2478. var option = this.quesModel.quesOptions[i];
  2479. var answerOrderNum = String.fromCharCode(65 + i);
  2480. if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
  2481. option["isCorrect"] =
  2482. answerOrderNum == this.singleRightAnswer ? 1 : 0;
  2483. }
  2484. if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
  2485. option["isCorrect"] =
  2486. this.multipleRightAnswer.indexOf(answerOrderNum) > -1 ? 1 : 0;
  2487. }
  2488. if (option["isCorrect"]) quesAnswer.push(i + 1);
  2489. }
  2490. this.quesModel.quesAnswer = JSON.stringify(quesAnswer);
  2491. },
  2492. //删除试题
  2493. deleteQues(paperDetailUnit) {
  2494. let paperDetailUnitId = paperDetailUnit.id;
  2495. if (this.paper.paperType == "GENERATE") {
  2496. this.deleteQues01(paperDetailUnitId);
  2497. } else {
  2498. let questionId = paperDetailUnit.question.id;
  2499. this.deleteQues02(questionId, paperDetailUnitId);
  2500. }
  2501. },
  2502. deleteQues01(paperDetailUnitId) {
  2503. this.$alert("您确定删除吗?", "提示", {
  2504. confirmButtonText: "确定",
  2505. callback: (action) => {
  2506. if (action == "confirm") {
  2507. this.loading = true;
  2508. this.$http
  2509. .delete(QUESTION_API + "/paperDetailUnit/" + paperDetailUnitId)
  2510. .then(() => {
  2511. this.initPaper();
  2512. this.reduplicateGroup = [];
  2513. this.loading = true;
  2514. this.$notify({
  2515. message: "删除成功",
  2516. type: "success",
  2517. });
  2518. this.loading = false;
  2519. });
  2520. }
  2521. },
  2522. });
  2523. },
  2524. deleteQues02(questionId, paperDetailUnitId) {
  2525. this.$alert("您确定删除吗?", "提示", {
  2526. confirmButtonText: "确定",
  2527. callback: (action) => {
  2528. if (action == "confirm") {
  2529. this.loading = true;
  2530. this.$http
  2531. .delete(
  2532. QUESTION_API +
  2533. "/paper/deleteQuestion/" +
  2534. paperDetailUnitId +
  2535. "/" +
  2536. questionId
  2537. )
  2538. .then((response) => {
  2539. if (response.data.length > 0) {
  2540. var deleteInfo =
  2541. "该试题被试卷:" +
  2542. response.data.join(" , ") +
  2543. "使用,不能删除";
  2544. this.$notify({
  2545. message: deleteInfo,
  2546. type: "error",
  2547. });
  2548. } else {
  2549. this.initPaper();
  2550. this.reduplicateGroup = [];
  2551. this.loading = true;
  2552. this.$notify({
  2553. message: "保存成功",
  2554. type: "success",
  2555. });
  2556. }
  2557. this.loading = false;
  2558. });
  2559. }
  2560. },
  2561. });
  2562. },
  2563. exportPaperAnswer() {
  2564. var key = this.user.key;
  2565. var token = this.user.token;
  2566. window.open(
  2567. QUESTION_API +
  2568. "/paper/answer/export/" +
  2569. this.paperId +
  2570. "?$key=" +
  2571. key +
  2572. "&$token=" +
  2573. token
  2574. );
  2575. },
  2576. getSubQuesEditId(paperDetailUnit, subQuestion) {
  2577. return paperDetailUnit.question.id + "_" + subQuestion.subNumber;
  2578. },
  2579. //打开考试说明编辑框
  2580. openEditExamPaperRemark() {
  2581. if (this.paper.examRemark) {
  2582. this.examRemark = this.paper.examRemark;
  2583. } else {
  2584. this.examRemark = "";
  2585. }
  2586. this.paperRemarkDialog = true;
  2587. },
  2588. //保存考试说明
  2589. savePaperRemark() {
  2590. this.paper.examRemark = this.examRemark;
  2591. this.savePaper();
  2592. this.paperRemarkDialog = false;
  2593. },
  2594. //关闭考试说明编辑框
  2595. closPaperRemark() {
  2596. this.examRemark = "";
  2597. this.paperRemarkDialog = false;
  2598. },
  2599. //保存试卷
  2600. savePaper() {
  2601. this.loading = true;
  2602. this.$http
  2603. .put(QUESTION_API + "/paper", this.paper)
  2604. .then(() => {
  2605. this.$notify({
  2606. message: "保存成功",
  2607. type: "success",
  2608. });
  2609. this.loading = false;
  2610. this.initPaper();
  2611. })
  2612. .catch((error) => {
  2613. this.loading = false;
  2614. this.$notify({
  2615. type: "error",
  2616. message: error.response.data.desc,
  2617. });
  2618. });
  2619. },
  2620. //删除试卷
  2621. deletePaper() {
  2622. this.$confirm("确认删除试卷吗?", "提示", {
  2623. type: "warning",
  2624. }).then(() => {
  2625. this.loading = true;
  2626. this.selectedPaperIds = [];
  2627. this.selectedPaperIds.push(this.paper.id);
  2628. this.$http
  2629. .post(
  2630. QUESTION_API + "/paper/audit/delete",
  2631. new URLSearchParams({ paperIds: this.selectedPaperIds })
  2632. )
  2633. .then(
  2634. () => {
  2635. this.$notify({
  2636. message: "删除成功",
  2637. type: "success",
  2638. });
  2639. this.back();
  2640. },
  2641. (error) => {
  2642. this.$notify({
  2643. message: error.response.data.desc,
  2644. type: "error",
  2645. });
  2646. this.loading = false;
  2647. }
  2648. );
  2649. });
  2650. },
  2651. //打开上传音频弹框
  2652. openDialog() {
  2653. this.checkResult = false;
  2654. this.isUpload = true;
  2655. if (document.getElementById("radioFile")) {
  2656. document.getElementById("radioFile").value = "";
  2657. }
  2658. this.audioFileName = "";
  2659. this.dialogRadioFile = true;
  2660. this.fileList = [];
  2661. },
  2662. //关闭音频弹框
  2663. closeAudioDialog() {
  2664. this.dialogRadioFile = this.uploadAudioLoading;
  2665. },
  2666. //返回
  2667. back() {
  2668. if (sessionStorage.getItem("question_back") == "true") {
  2669. this.$router.push({
  2670. path: "/questions/" + this.parentView + "/0",
  2671. });
  2672. } else {
  2673. this.$router.push({
  2674. path: "/questions/" + this.parentView + "/1",
  2675. });
  2676. }
  2677. },
  2678. paperDetailShow(paperDetail) {
  2679. if (this.reduplicateGroup.length == 0) {
  2680. return true;
  2681. }
  2682. let paperDetailUnits = paperDetail.paperDetailUnits;
  2683. for (let i = 0, imax = paperDetailUnits.length; i < imax; i++) {
  2684. for (var j = 0, jmax = this.reduplicateGroup.length; j < jmax; j++) {
  2685. if (paperDetailUnits[i].id == this.reduplicateGroup[j]) {
  2686. return true;
  2687. }
  2688. }
  2689. }
  2690. return false;
  2691. },
  2692. //上传文件检查
  2693. checkFile() {
  2694. this.fileNameList = [];
  2695. //读取选取的文件夹里面的文件
  2696. this.checkResult = true;
  2697. var files = document.getElementById("radioFile").files;
  2698. if (files.length == 0) {
  2699. this.message = "请选择音频文件夹!";
  2700. return;
  2701. }
  2702. var size = 0;
  2703. var isGo = false;
  2704. //取到所有文件的文件名
  2705. for (var i = 0; i < files.length; i++) {
  2706. this.fileNameList.push(files[i].name);
  2707. if (files[i].size > 5 * 1024 * 1024) {
  2708. isGo = true;
  2709. break;
  2710. }
  2711. size = files[i].size + size;
  2712. }
  2713. if (isGo) {
  2714. this.message = "上传单个文件不能超过5M";
  2715. this.isUpload = true;
  2716. }
  2717. if (size > 50 * 1024 * 1024) {
  2718. this.message = "上传文件总和不能超过50M";
  2719. this.isUpload = true;
  2720. return;
  2721. }
  2722. this.$http
  2723. .post(
  2724. QUESTION_API + "/checkRadioFile/" + this.paperId,
  2725. this.fileNameList
  2726. )
  2727. .then((response) => {
  2728. console.log("response:", response);
  2729. this.message = response.data.errorMsg;
  2730. if (this.message == "OK") {
  2731. this.message = "OK!";
  2732. this.isUpload = false;
  2733. } else {
  2734. this.isUpload = true;
  2735. }
  2736. })
  2737. .catch((error) => {
  2738. console.log(error);
  2739. });
  2740. },
  2741. // 音频文件
  2742. selectAudioFile() {
  2743. document.getElementById("radioFile").click();
  2744. },
  2745. audioFileChange() {
  2746. let fileList = document.getElementById("radioFile").files;
  2747. if (fileList.length == 0) {
  2748. this.audioFileName = "";
  2749. } else {
  2750. let names = [];
  2751. for (var i = 0; i < fileList.length; i++) {
  2752. var file = fileList[i];
  2753. names.push(file.name);
  2754. }
  2755. this.audioFileName = names.join();
  2756. }
  2757. },
  2758. uploadAudioFile() {
  2759. let param = new FormData();
  2760. var fileList = document.getElementById("radioFile").files;
  2761. //循环添加到formData中
  2762. for (var i = 0; i < fileList.length; i++) {
  2763. var file = fileList[i];
  2764. param.append("files", file, file.name);
  2765. }
  2766. let config = {
  2767. headers: { "Content-Type": "multipart/form-data" },
  2768. };
  2769. this.$http
  2770. .post(QUESTION_API + "/uploadRadio/" + this.paperId, param, config)
  2771. .then(() => {
  2772. this.dialogRadioFile = false;
  2773. this.uploadAudioLoading = false;
  2774. this.checkResult = false;
  2775. this.isUpload = true;
  2776. document.getElementById("radioFile").value = "";
  2777. this.initPaper();
  2778. })
  2779. .catch((error) => {
  2780. this.message = error.response.data.desc;
  2781. this.uploadAudioLoading = false;
  2782. });
  2783. },
  2784. },
  2785. };
  2786. </script>