index.vue 97 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820
  1. <template>
  2. <div class="course-exam">
  3. <Header></Header>
  4. <section class="section">
  5. <div class="container">
  6. <div class="section__header">
  7. <!-- <el-breadcrumb separator="/">
  8. <el-breadcrumb-item
  9. v-for="(item, index) in $route.matched"
  10. :key="index"
  11. :to="{ path: item.path }"
  12. >{{ item.name }}</el-breadcrumb-item
  13. >
  14. </el-breadcrumb> -->
  15. </div>
  16. <div class="section__body">
  17. <div class="explain-record">
  18. <div class="explain-record__body">
  19. <div class="left-box">
  20. <Header-tab-box
  21. :num="questionOverNum(true)"
  22. @prevQuestion="prevQuestion"
  23. :allNum="questionList.length"
  24. @nextQuestion="nextQuestion"
  25. ></Header-tab-box>
  26. <div class="left-box__body">
  27. <template v-for="(question, questionIndex) in questionList">
  28. <div
  29. class="question"
  30. v-if="question.type == 1 && current == questionIndex"
  31. :key="questionIndex"
  32. >
  33. <div class="question__title">
  34. {{ questionIndex + 1 }}、单选题
  35. </div>
  36. <div
  37. class="question__desc"
  38. v-html="question.content"
  39. ></div>
  40. <div class="question__content">
  41. <div class="question-list" v-if="!question.ques">
  42. <div
  43. class="radio"
  44. v-for="(item, index) in question.jsonStr"
  45. :key="index"
  46. @click="
  47. radioSelect(
  48. question,
  49. questionIndex,
  50. item.optionsId
  51. )
  52. "
  53. >
  54. <div>
  55. {{ ast[index] }}. {{ item.content }}
  56. <div v-if="item.imgUrl">
  57. <img
  58. style="max-width: 100%"
  59. :src="$tools.splitImgHost(item.imgUrl)"
  60. alt=""
  61. />
  62. </div>
  63. </div>
  64. </div>
  65. </div>
  66. <div class="question-list" v-if="question.ques">
  67. <div
  68. class="radio"
  69. :class="{
  70. right:
  71. bankType == 1 &&
  72. (item.optionsId == question.ques ||
  73. item.optionsId == question.ans),
  74. wrong:
  75. bankType == 1 &&
  76. item.optionsId == question.ques &&
  77. question.ques != question.ans,
  78. user_choose:
  79. bankType == 2 && item.optionsId == question.ques
  80. }"
  81. v-for="(item, index) in question.jsonStr"
  82. :key="index"
  83. @click="
  84. radioSelect(
  85. question,
  86. questionIndex,
  87. item.optionsId
  88. )
  89. "
  90. >
  91. <div>
  92. {{ ast[index] }}. {{ item.content }}
  93. <div v-if="item.imgUrl">
  94. <img
  95. style="max-width: 100%"
  96. :src="$tools.splitImgHost(item.imgUrl)"
  97. alt=""
  98. />
  99. </div>
  100. </div>
  101. </div>
  102. </div>
  103. <div
  104. class="answer-list"
  105. v-if="bankType == 1 && question.ques"
  106. >
  107. <div class="answer-list__left">
  108. 题目答案:{{ ast[question.ans - 1] }}
  109. </div>
  110. <div class="answer-list__left">
  111. 我的答案:{{ ast[question.ques - 1] }}
  112. </div>
  113. </div>
  114. <div
  115. class="explain-list"
  116. v-if="bankType == 1 && question.ques"
  117. >
  118. <div class="explain-list__header">答案解析:</div>
  119. <div
  120. class="explain-list__body"
  121. v-html="question.analysisContent"
  122. ></div>
  123. </div>
  124. </div>
  125. </div>
  126. <div
  127. class="question"
  128. v-if="question.type == 2 && current == questionIndex"
  129. :key="questionIndex"
  130. >
  131. <div class="question__title">
  132. {{ questionIndex + 1 }}、多选题
  133. </div>
  134. <div
  135. class="question__desc"
  136. v-html="question.content"
  137. ></div>
  138. <div class="question__content">
  139. <div class="question-list" v-if="!question.ques">
  140. <el-checkbox
  141. class="checkbox"
  142. v-for="(item, index) in question.jsonStr"
  143. :key="index"
  144. :label="item.optionsId"
  145. v-model="item.checked"
  146. >
  147. <div>
  148. {{ ast[index] }}. {{ item.content }}
  149. <div v-if="item.imgUrl">
  150. <img
  151. style="max-width: 100%"
  152. :src="$tools.splitImgHost(item.imgUrl)"
  153. alt=""
  154. />
  155. </div>
  156. </div>
  157. </el-checkbox>
  158. </div>
  159. <div class="question-list" v-if="question.ques">
  160. <el-checkbox
  161. :disabled="bankType == 2 ? false : true"
  162. class="checkbox"
  163. :class="{
  164. right:
  165. bankType == 1 &&
  166. (question.ques.indexOf(item.optionsId) != -1 ||
  167. question.ans.indexOf(item.optionsId) != -1),
  168. wrong:
  169. bankType == 1 &&
  170. question.ques.indexOf(item.optionsId) != -1 &&
  171. question.ans.indexOf(item.optionsId) == -1,
  172. user_choose:
  173. bankType == 2 &&
  174. question.ques.indexOf(item.optionsId) != -1
  175. }"
  176. v-for="(item, index) in question.jsonStr"
  177. :key="index"
  178. :label="item.optionsId"
  179. v-model="item.checked"
  180. >
  181. <div>
  182. {{ ast[index] }}. {{ item.content }}
  183. <div v-if="item.imgUrl">
  184. <img
  185. style="max-width: 100%"
  186. :src="$tools.splitImgHost(item.imgUrl)"
  187. alt=""
  188. />
  189. </div>
  190. </div>
  191. </el-checkbox>
  192. </div>
  193. <div
  194. class="answer-list"
  195. v-if="bankType == 1 && question.ques"
  196. >
  197. <div class="answer-list__left">
  198. 题目答案:
  199. <template v-for="ansItem in question.ans">{{
  200. ast[ansItem - 1]
  201. }}</template>
  202. </div>
  203. <div class="answer-list__left">
  204. 我的答案:
  205. <template v-for="quesItem in question.ques">{{
  206. ast[quesItem - 1]
  207. }}</template>
  208. </div>
  209. </div>
  210. <div
  211. class="explain-list"
  212. v-if="bankType == 1 && question.ques"
  213. >
  214. <div class="explain-list__header">答案解析:</div>
  215. <div
  216. class="explain-list__body"
  217. v-html="question.analysisContent"
  218. ></div>
  219. </div>
  220. </div>
  221. <div class="question__btns">
  222. <div
  223. v-if="
  224. bankType == 2 || (bankType == 1 && !question.ques)
  225. "
  226. class="submit"
  227. @click="checkboxSubmit(question, questionIndex)"
  228. >
  229. 确认答案
  230. </div>
  231. </div>
  232. </div>
  233. <div
  234. class="question"
  235. v-if="question.type == 3 && current == questionIndex"
  236. :key="questionIndex"
  237. >
  238. <div class="question__title">
  239. {{ questionIndex + 1 }}、判断题
  240. </div>
  241. <div
  242. class="question__desc"
  243. v-html="question.content"
  244. ></div>
  245. <div class="question__content">
  246. <div class="question-list" v-if="!question.ques">
  247. <div
  248. class="radio"
  249. v-for="(item, index) in judge"
  250. :key="index"
  251. @click="judgeSelect(question, questionIndex, index)"
  252. >
  253. <div>
  254. {{ ast[index] }}. {{ item }}
  255. <div v-if="item.imgUrl">
  256. <img
  257. style="max-width: 100%"
  258. :src="$tools.splitImgHost(item.imgUrl)"
  259. alt=""
  260. />
  261. </div>
  262. </div>
  263. </div>
  264. </div>
  265. <div class="question-list" v-if="question.ques">
  266. <div
  267. class="radio"
  268. :class="{
  269. right:
  270. bankType == 1 &&
  271. (index == (question.ques == 1 ? 0 : 1) ||
  272. index != question.ans),
  273. wrong:
  274. bankType == 1 &&
  275. index == (question.ques == 1 ? 0 : 1) &&
  276. question.ques != question.ans,
  277. user_choose:
  278. bankType == 2 &&
  279. index == (question.ques == 1 ? 0 : 1)
  280. }"
  281. v-for="(item, index) in judge"
  282. :key="index"
  283. @click="judgeSelect(question, questionIndex, index)"
  284. >
  285. <div>
  286. {{ ast[index] }}. {{ item }}
  287. <div v-if="item.imgUrl">
  288. <img
  289. style="max-width: 100%"
  290. :src="$tools.splitImgHost(item.imgUrl)"
  291. alt=""
  292. />
  293. </div>
  294. </div>
  295. </div>
  296. </div>
  297. <div
  298. class="answer-list"
  299. v-if="bankType == 1 && question.ques"
  300. >
  301. <div class="answer-list__left">
  302. 题目答案:{{ ast[question.ans == 1 ? 0 : 1] }}
  303. </div>
  304. <div class="answer-list__left">
  305. 我的答案:{{ ast[question.ques == 1 ? 0 : 1] }}
  306. </div>
  307. </div>
  308. <div
  309. class="explain-list"
  310. v-if="bankType == 1 && question.ques"
  311. >
  312. <div class="explain-list__header">答案解析:</div>
  313. <div
  314. class="explain-list__body"
  315. v-html="question.analysisContent"
  316. ></div>
  317. </div>
  318. </div>
  319. </div>
  320. <div
  321. class="question"
  322. v-if="question.type == 4 && current == questionIndex"
  323. :key="questionIndex"
  324. >
  325. <div class="question__title">
  326. {{ questionIndex + 1 }}、案例题
  327. </div>
  328. <div
  329. class="question__desc"
  330. v-html="question.content"
  331. ></div>
  332. <div class="question__content">
  333. <el-tabs v-model="question.tabIndex">
  334. <el-tab-pane
  335. v-for="(json, jsonIndex) in question.jsonStr"
  336. :label="'问题' + (jsonIndex + 1)"
  337. :name="jsonIndex + ''"
  338. :key="jsonIndex"
  339. >
  340. <div
  341. class="question"
  342. v-if="json.type == 1"
  343. :key="questionIndex"
  344. >
  345. <div class="question__title">
  346. {{ jsonIndex + 1 }}、单选题
  347. </div>
  348. <div
  349. class="question__desc"
  350. v-html="json.content"
  351. ></div>
  352. <div class="question__content">
  353. <div
  354. class="question-list"
  355. v-if="!question.ques[jsonIndex]"
  356. >
  357. <div
  358. class="radio"
  359. v-for="(item, index) in json.optionsList"
  360. :key="index"
  361. @click="
  362. radioSelectChild(
  363. questionIndex,
  364. jsonIndex,
  365. item.optionsId
  366. )
  367. "
  368. >
  369. <div>
  370. {{ ast[index] }}. {{ item.content }}
  371. <div v-if="item.imgUrl">
  372. <img
  373. style="max-width: 100%"
  374. :src="
  375. $tools.splitImgHost(item.imgUrl)
  376. "
  377. alt=""
  378. />
  379. </div>
  380. </div>
  381. </div>
  382. </div>
  383. <div
  384. class="question-list"
  385. v-if="question.ques[jsonIndex]"
  386. >
  387. <div
  388. class="radio"
  389. :class="{
  390. right:
  391. bankType == 1 &&
  392. (item.optionsId ==
  393. question.ques[jsonIndex] ||
  394. item.optionsId ==
  395. question.ans[jsonIndex]),
  396. wrong:
  397. bankType == 1 &&
  398. item.optionsId ==
  399. question.ques[jsonIndex] &&
  400. question.ques[jsonIndex] !=
  401. question.ans[jsonIndex],
  402. user_choose:
  403. bankType == 2 &&
  404. item.optionsId ==
  405. question.ques[jsonIndex]
  406. }"
  407. v-for="(item, index) in json.optionsList"
  408. :key="index"
  409. @click="
  410. radioSelectChild(
  411. questionIndex,
  412. jsonIndex,
  413. item.optionsId
  414. )
  415. "
  416. >
  417. <div>
  418. {{ ast[index] }}. {{ item.content }}
  419. <div v-if="item.imgUrl">
  420. <img
  421. style="max-width: 100%"
  422. :src="
  423. $tools.splitImgHost(item.imgUrl)
  424. "
  425. alt=""
  426. />
  427. </div>
  428. </div>
  429. </div>
  430. </div>
  431. <div
  432. class="answer-list"
  433. v-if="
  434. bankType == 1 && question.ques[jsonIndex]
  435. "
  436. >
  437. <div class="answer-list__left">
  438. 题目答案:{{
  439. ast[question.ans[jsonIndex] - 1]
  440. }}
  441. </div>
  442. <div class="answer-list__left">
  443. 我的答案:{{
  444. ast[question.ques[jsonIndex] - 1]
  445. }}
  446. </div>
  447. </div>
  448. <div
  449. class="explain-list"
  450. v-if="
  451. bankType == 1 && question.ques[jsonIndex]
  452. "
  453. >
  454. <div class="explain-list__header">
  455. 答案解析:
  456. </div>
  457. <div
  458. class="explain-list__body"
  459. v-html="json.analysisContent"
  460. ></div>
  461. </div>
  462. </div>
  463. <div class="question__btns"></div>
  464. </div>
  465. <div
  466. class="question"
  467. v-if="json.type == 2"
  468. :key="jsonIndex"
  469. >
  470. <div class="question__title">
  471. {{ jsonIndex + 1 }}、多选题
  472. </div>
  473. <div
  474. class="question__desc"
  475. v-html="json.content"
  476. ></div>
  477. <div class="question__content">
  478. <div
  479. class="question-list"
  480. v-if="!question.ques[jsonIndex]"
  481. >
  482. <el-checkbox
  483. class="checkbox"
  484. v-for="(item, index) in json.optionsList"
  485. :key="index"
  486. :label="item.optionsId"
  487. v-model="item.checked"
  488. >
  489. <div>
  490. {{ ast[index] }}. {{ item.content }}
  491. <div v-if="item.imgUrl">
  492. <img
  493. style="max-width: 100%"
  494. :src="
  495. $tools.splitImgHost(item.imgUrl)
  496. "
  497. alt=""
  498. />
  499. </div>
  500. </div>
  501. </el-checkbox>
  502. </div>
  503. <div
  504. class="question-list"
  505. v-if="question.ques[jsonIndex]"
  506. >
  507. <el-checkbox
  508. :disabled="bankType == 2 ? false : true"
  509. class="checkbox"
  510. :class="{
  511. right:
  512. bankType == 1 &&
  513. (question.ques[jsonIndex].indexOf(
  514. item.optionsId
  515. ) != -1 ||
  516. question.ans[jsonIndex].indexOf(
  517. item.optionsId
  518. ) != -1),
  519. wrong:
  520. bankType == 1 &&
  521. question.ques[jsonIndex].indexOf(
  522. item.optionsId
  523. ) != -1 &&
  524. question.ans[jsonIndex].indexOf(
  525. item.optionsId
  526. ) == -1,
  527. user_choose:
  528. bankType == 2 &&
  529. question.ques[jsonIndex].indexOf(
  530. item.optionsId
  531. ) != -1
  532. }"
  533. v-for="(item, index) in json.optionsList"
  534. :key="index"
  535. :label="item.optionsId"
  536. v-model="item.checked"
  537. >
  538. <div>
  539. {{ ast[index] }}. {{ item.content }}
  540. <div v-if="item.imgUrl">
  541. <img
  542. style="max-width: 100%"
  543. :src="
  544. $tools.splitImgHost(item.imgUrl)
  545. "
  546. alt=""
  547. />
  548. </div>
  549. </div>
  550. </el-checkbox>
  551. </div>
  552. <div
  553. class="answer-list"
  554. v-if="
  555. bankType == 1 && question.ques[jsonIndex]
  556. "
  557. >
  558. <div class="answer-list__left">
  559. 题目答案:
  560. <template
  561. v-for="ansItem in question.ans[jsonIndex]"
  562. >{{ ast[ansItem - 1] }}</template
  563. >
  564. </div>
  565. <div class="answer-list__left">
  566. 我的答案:
  567. <template
  568. v-for="quesItem in question.ques[
  569. jsonIndex
  570. ]"
  571. >{{ ast[quesItem - 1] }}</template
  572. >
  573. </div>
  574. </div>
  575. <div
  576. class="explain-list"
  577. v-if="
  578. bankType == 1 && question.ques[jsonIndex]
  579. "
  580. >
  581. <div class="explain-list__header">
  582. 答案解析:
  583. </div>
  584. <div
  585. class="explain-list__body"
  586. v-html="json.analysisContent"
  587. ></div>
  588. </div>
  589. </div>
  590. <div class="question__btns">
  591. <div
  592. v-if="
  593. bankType == 2 ||
  594. (bankType == 1 &&
  595. !question.ques[jsonIndex])
  596. "
  597. class="submit"
  598. @click="
  599. checkboxSubmitChild(
  600. questionIndex,
  601. jsonIndex
  602. )
  603. "
  604. >
  605. 确认答案
  606. </div>
  607. </div>
  608. </div>
  609. <div
  610. class="question"
  611. v-if="json.type == 3"
  612. :key="jsonIndex"
  613. >
  614. <div class="question__title">
  615. {{ jsonIndex + 1 }}、判断题
  616. </div>
  617. <div
  618. class="question__desc"
  619. v-html="json.content"
  620. ></div>
  621. <div class="question__content">
  622. <div
  623. class="question-list"
  624. v-if="!question.ques[jsonIndex]"
  625. >
  626. <div
  627. class="radio"
  628. v-for="(item, index) in judge"
  629. :key="index"
  630. @click="
  631. judgeSelectChild(
  632. questionIndex,
  633. jsonIndex,
  634. index
  635. )
  636. "
  637. >
  638. <div>
  639. {{ ast[index] }}. {{ item }}
  640. <div v-if="item.imgUrl">
  641. <img
  642. style="max-width: 100%"
  643. :src="
  644. $tools.splitImgHost(item.imgUrl)
  645. "
  646. alt=""
  647. />
  648. </div>
  649. </div>
  650. </div>
  651. </div>
  652. <div
  653. class="question-list"
  654. v-if="question.ques[jsonIndex]"
  655. >
  656. <div
  657. class="radio"
  658. :class="{
  659. right:
  660. bankType == 1 &&
  661. (index ==
  662. (question.ques[jsonIndex] == 1
  663. ? 0
  664. : 1) ||
  665. index != question.ans[jsonIndex]),
  666. wrong:
  667. bankType == 1 &&
  668. index ==
  669. (question.ques[jsonIndex] == 1
  670. ? 0
  671. : 1) &&
  672. question.ques[jsonIndex] !=
  673. question.ans[jsonIndex],
  674. user_choose:
  675. bankType == 2 &&
  676. index ==
  677. (question.ques[jsonIndex] == 1
  678. ? 0
  679. : 1)
  680. }"
  681. v-for="(item, index) in judge"
  682. :key="index"
  683. @click="
  684. judgeSelectChild(
  685. questionIndex,
  686. jsonIndex,
  687. index
  688. )
  689. "
  690. >
  691. <div>
  692. {{ ast[index] }}. {{ item }}
  693. <div v-if="item.imgUrl">
  694. <img
  695. style="max-width: 100%"
  696. :src="
  697. $tools.splitImgHost(item.imgUrl)
  698. "
  699. alt=""
  700. />
  701. </div>
  702. </div>
  703. </div>
  704. </div>
  705. <div
  706. class="answer-list"
  707. v-if="
  708. bankType == 1 && question.ques[jsonIndex]
  709. "
  710. >
  711. <div class="answer-list__left">
  712. 题目答案:{{
  713. ast[question.ans[jsonIndex] == 1 ? 0 : 1]
  714. }}
  715. </div>
  716. <div class="answer-list__left">
  717. 我的答案:{{
  718. ast[question.ques[jsonIndex] == 1 ? 0 : 1]
  719. }}
  720. </div>
  721. </div>
  722. <div
  723. class="explain-list"
  724. v-if="
  725. bankType == 1 && question.ques[jsonIndex]
  726. "
  727. >
  728. <div class="explain-list__header">
  729. 答案解析:
  730. </div>
  731. <div
  732. class="explain-list__body"
  733. v-html="json.analysisContent"
  734. ></div>
  735. </div>
  736. </div>
  737. <div class="question__btns"></div>
  738. </div>
  739. <div
  740. class="question"
  741. v-if="json.type == 5"
  742. :key="jsonIndex"
  743. >
  744. <div class="question__title">
  745. {{ jsonIndex + 1 }}、简答题
  746. </div>
  747. <div
  748. class="question__desc"
  749. v-html="json.content"
  750. ></div>
  751. <div class="question__content">
  752. <div
  753. class="question-list textarea"
  754. v-if="
  755. bankType == 2 ||
  756. (bankType == 1 &&
  757. !(
  758. question.ques[jsonIndex] &&
  759. (question.ques[jsonIndex].imageList
  760. .length ||
  761. question.ques[jsonIndex].text)
  762. ))
  763. "
  764. >
  765. <el-input
  766. type="textarea"
  767. rows="5"
  768. v-model="json.ansText.text"
  769. resize="none"
  770. ></el-input>
  771. <div class="upload clearfix">
  772. <div
  773. class="upload__imgs"
  774. v-for="(img, imgIndex) in json.ansText
  775. .imageList"
  776. :key="imgIndex"
  777. >
  778. <img
  779. style="max-width: 100%"
  780. :src="$tools.splitImgHost(img, true)"
  781. alt=""
  782. />
  783. </div>
  784. <div class="upload__btn">
  785. <i class="el-icon-plus icon"></i>
  786. <p>上传图片</p>
  787. <input
  788. @change="
  789. uploadImgChild(
  790. $event,
  791. questionIndex,
  792. jsonIndex
  793. )
  794. "
  795. type="file"
  796. />
  797. </div>
  798. </div>
  799. </div>
  800. <div
  801. class="explain-list"
  802. v-if="
  803. bankType == 1 &&
  804. question.ques[jsonIndex] &&
  805. (question.ques[jsonIndex].imageList
  806. .length ||
  807. question.ques[jsonIndex].text)
  808. "
  809. >
  810. <div class="explain-list__header">
  811. 我的答案:
  812. </div>
  813. <div class="explain-list__body">
  814. <div>
  815. {{ question.ques[jsonIndex].text }}
  816. </div>
  817. <div class="upload clearfix">
  818. <div
  819. class="upload__imgs"
  820. v-for="(img, imgIndex) in question.ques[
  821. jsonIndex
  822. ].imageList"
  823. :key="imgIndex"
  824. >
  825. <img
  826. style="max-width: 100%"
  827. :src="$tools.splitImgHost(img, true)"
  828. alt=""
  829. />
  830. </div>
  831. </div>
  832. </div>
  833. <div class="explain-list__header">
  834. 答案解析:
  835. </div>
  836. <div
  837. class="explain-list__body"
  838. v-html="json.analysisContent"
  839. ></div>
  840. </div>
  841. </div>
  842. <div class="question__btns">
  843. <div
  844. v-if="
  845. bankType == 2 ||
  846. (bankType == 1 &&
  847. !(
  848. question.ques[jsonIndex] &&
  849. (question.ques[jsonIndex].imageList
  850. .length ||
  851. question.ques[jsonIndex].text)
  852. ))
  853. "
  854. class="submit"
  855. @click="
  856. ansSubmitChild(
  857. question,
  858. questionIndex,
  859. jsonIndex
  860. )
  861. "
  862. >
  863. 确认答案
  864. </div>
  865. </div>
  866. </div>
  867. </el-tab-pane>
  868. </el-tabs>
  869. </div>
  870. </div>
  871. <div
  872. class="question"
  873. v-if="question.type == 5 && current == questionIndex"
  874. :key="questionIndex"
  875. >
  876. <div class="question__title">
  877. {{ questionIndex + 1 }}、简答题
  878. </div>
  879. <div
  880. class="question__desc"
  881. v-html="question.content"
  882. ></div>
  883. <div class="question__content">
  884. <div
  885. class="question-list textarea"
  886. v-if="
  887. bankType == 2 ||
  888. (bankType == 1 &&
  889. !question.ques.imageList.length &&
  890. !question.ques.text)
  891. "
  892. >
  893. <el-input
  894. type="textarea"
  895. rows="5"
  896. v-model="question.ansText.text"
  897. resize="none"
  898. ></el-input>
  899. <div class="upload clearfix">
  900. <div
  901. class="upload__imgs"
  902. v-for="(img, imgIndex) in question.ansText
  903. .imageList"
  904. :key="imgIndex"
  905. >
  906. <img
  907. style="max-width: 100%"
  908. :src="$tools.splitImgHost(img, true)"
  909. alt=""
  910. />
  911. </div>
  912. <div class="upload__btn">
  913. <i class="el-icon-plus icon"></i>
  914. <p>上传图片</p>
  915. <input
  916. @change="
  917. uploadImg($event, question, questionIndex)
  918. "
  919. type="file"
  920. />
  921. </div>
  922. </div>
  923. </div>
  924. <div
  925. class="explain-list"
  926. v-if="
  927. (bankType == 1 && question.ques.imageList.length) ||
  928. question.ques.text
  929. "
  930. >
  931. <div class="explain-list__header">我的答案:</div>
  932. <div class="explain-list__body">
  933. <div>{{ question.ques.text }}</div>
  934. <div class="upload clearfix">
  935. <div
  936. class="upload__imgs"
  937. v-for="(img, imgIndex) in question.ques
  938. .imageList"
  939. :key="imgIndex"
  940. >
  941. <img
  942. style="max-width: 100%"
  943. :src="$tools.splitImgHost(img, true)"
  944. alt=""
  945. />
  946. </div>
  947. </div>
  948. </div>
  949. <div class="explain-list__header">答案解析:</div>
  950. <div
  951. class="explain-list__body"
  952. v-html="question.analysisContent"
  953. ></div>
  954. </div>
  955. </div>
  956. <div class="question__btns">
  957. <div
  958. v-if="
  959. bankType == 2 ||
  960. (bankType == 1 &&
  961. !question.ques.imageList.length &&
  962. !question.ques.text)
  963. "
  964. class="submit"
  965. @click="ansSubmit(question, questionIndex)"
  966. >
  967. 确认答案
  968. </div>
  969. </div>
  970. </div>
  971. </template>
  972. </div>
  973. <Collection-box
  974. :param="param"
  975. @sumit="getCollectInfo(current)"
  976. :showT="!collectList[current]"
  977. ></Collection-box>
  978. </div>
  979. <div class="right-box">
  980. <div class="right-box__header">
  981. <el-button
  982. type="primary"
  983. round
  984. plain
  985. size="small"
  986. class="back-btn"
  987. @click="$router.back(-1)"
  988. >返回</el-button
  989. >
  990. </div>
  991. <div class="right-box__footer">
  992. <div class="submit" @click="submit">交卷</div>
  993. </div>
  994. <div class="right-box__header">
  995. <div class="title">答题卡</div>
  996. <div class="time" v-if="allTimes">
  997. 剩余时间 {{ countdown(lastTime) }}
  998. </div>
  999. </div>
  1000. <div class="right-box__body">
  1001. <div class="card">
  1002. <div class="card__note">
  1003. <div class="item">
  1004. <div class="box green"></div>
  1005. 正确
  1006. </div>
  1007. <div class="item">
  1008. <div class="box red"></div>
  1009. 错误
  1010. </div>
  1011. <div class="item">
  1012. <div class="box blue"></div>
  1013. 已做未评改
  1014. </div>
  1015. <div class="item">
  1016. <div class="box yellow"></div>
  1017. 少选
  1018. </div>
  1019. <div class="item">
  1020. <div class="box white"></div>
  1021. 未做
  1022. </div>
  1023. </div>
  1024. <div class="card__content">
  1025. <ul class="list">
  1026. <li
  1027. class="item white"
  1028. v-for="(item, index) in questionList"
  1029. :key="index"
  1030. :class="{
  1031. green: bankType == 1 && isRight(item, index),
  1032. red: bankType == 1 && isWrong(item, index),
  1033. yellow: bankType == 1 && isPart(item, index),
  1034. blue: bankType == 1 && isOver(item, index),
  1035. check_ans: bankType == 2 && isCheck(item, index)
  1036. }"
  1037. @click="changeIndex(index)"
  1038. >
  1039. {{ index + 1 }}
  1040. </li>
  1041. </ul>
  1042. </div>
  1043. </div>
  1044. </div>
  1045. </div>
  1046. </div>
  1047. </div>
  1048. </div>
  1049. </div>
  1050. </section>
  1051. <ToolBar></ToolBar>
  1052. <Footer></Footer>
  1053. <takePicture
  1054. ref="takePicture"
  1055. @returnParameter="returnParameter"
  1056. ></takePicture>
  1057. </div>
  1058. </template>
  1059. <script>
  1060. import takePicture from "@/components/takePicture/index.vue";
  1061. import myMixins from "@/mixin";
  1062. import Footer from "@/components/footer/index";
  1063. import Header from "@/components/header/index";
  1064. import ToolBar from "@/components/toolbar/index";
  1065. import CollectionBox from "@/components/common/CollectionBox.vue";
  1066. import HeaderTabBox from "../../components/exam/HeaderTabBox.vue";
  1067. import { mapMutations } from "vuex";
  1068. export default {
  1069. name: "BankExplain",
  1070. components: {
  1071. Footer,
  1072. Header,
  1073. ToolBar,
  1074. CollectionBox,
  1075. HeaderTabBox,
  1076. takePicture
  1077. },
  1078. mixins: [myMixins],
  1079. data() {
  1080. return {
  1081. openPhotoStatus: 0,
  1082. recordId: 0,
  1083. tabIndex: "1",
  1084. textarea: "",
  1085. questionIndex: 0,
  1086. checked: false,
  1087. questionList: [],
  1088. judge: ["正确", "错误"],
  1089. ast: [
  1090. "A",
  1091. "B",
  1092. "C",
  1093. "D",
  1094. "E",
  1095. "F",
  1096. "G",
  1097. "H",
  1098. "I",
  1099. "J",
  1100. "K",
  1101. "L",
  1102. "M",
  1103. "N",
  1104. "O",
  1105. "P",
  1106. "Q",
  1107. "R",
  1108. "S",
  1109. "T",
  1110. "U",
  1111. "V",
  1112. "W",
  1113. "X",
  1114. "Y",
  1115. "Z"
  1116. ],
  1117. mustBack: false,
  1118. needPhoto: false,
  1119. lastTime: 0, //剩余考试时长
  1120. allTimes: 0, //总考试时长
  1121. lastCount: 0,
  1122. examId: 0,
  1123. goodsId: 0,
  1124. courseId: 0,
  1125. gradeId: 0,
  1126. moduleId: 0,
  1127. chapterId: 0,
  1128. sectionId: 0,
  1129. orderGoodsId: 0,
  1130. current: 0,
  1131. timer: null,
  1132. type: 0, //type:1章卷,2节卷,3模块卷
  1133. bankType: 0,
  1134. compareFaceData: 0, // 拍照匹配相似度
  1135. collectList: [],
  1136. doMode: 1,
  1137. simulateExamId: ""
  1138. };
  1139. },
  1140. async mounted() {
  1141. this.goodsId = Number(this.$route.params.goodsId);
  1142. this.examId = Number(this.$route.query.examId);
  1143. this.type = Number(this.$route.query.type);
  1144. this.courseId = Number(this.$route.query.courseId);
  1145. this.gradeId = Number(this.$route.query.gradeId);
  1146. this.moduleId = Number(this.$route.query.moduleId);
  1147. this.sectionId = Number(this.$route.query.sectionId);
  1148. this.chapterId = Number(this.$route.query.chapterId);
  1149. this.orderGoodsId = Number(this.$route.query.orderGoodsId);
  1150. if (
  1151. (this.type == 1 && (!this.chapterId || this.chapterId === 0)) ||
  1152. (this.type == 3 && (!this.moduleId || this.moduleId === 0))
  1153. ) {
  1154. this.$alert("数据出现未知异常,请重进或向教务人员反馈", "提示", {
  1155. confirmButtonText: "返回上一页",
  1156. showClose: false,
  1157. callback: action => {
  1158. this.mustBack = true;
  1159. this.$router.go(-1);
  1160. }
  1161. });
  1162. return;
  1163. }
  1164. await this.getGoodsDetail();
  1165. await this.bankExam();
  1166. this.needPhoto && (await this.getExamLearnStatus());
  1167. this.goodsQuestionList();
  1168. },
  1169. beforeDestroy() {
  1170. clearInterval(this.timer);
  1171. try {
  1172. this.$msgbox.close();
  1173. } catch (err) {}
  1174. },
  1175. methods: {
  1176. ...mapMutations(["setExamResult"]),
  1177. toFixed(num) {
  1178. if (num) {
  1179. let str = String(num).indexOf(".");
  1180. if (str != -1) {
  1181. return +num.toFixed(2);
  1182. } else {
  1183. return num;
  1184. }
  1185. } else {
  1186. return 0;
  1187. }
  1188. },
  1189. getGoodsDetail() {
  1190. return new Promise(resolve => {
  1191. this.$request.goodsDetail(this.goodsId).then(res => {
  1192. if (this.type != 2) {
  1193. if (res.data.goodsPhotoExamConfig) {
  1194. let goodsPhotoExamConfig = JSON.parse(
  1195. res.data.goodsPhotoExamConfig
  1196. );
  1197. if (goodsPhotoExamConfig.photograph > 0) {
  1198. this.needPhoto = true;
  1199. }
  1200. }
  1201. if (res.data.erJianErZao) {
  1202. this.needPhoto = true;
  1203. }
  1204. }
  1205. resolve();
  1206. });
  1207. });
  1208. },
  1209. /**
  1210. * @param {Object} current
  1211. * 获取收藏信息
  1212. */
  1213. getCollectInfo(current) {
  1214. this.$request
  1215. .getCollectInfo({
  1216. examId: this.examId,
  1217. questionId: this.questionList[current].questionId,
  1218. goodsId: this.goodsId,
  1219. orderGoodsId: this.orderGoodsId,
  1220. doMode: this.doMode
  1221. })
  1222. .then(res => {
  1223. this.$set(this.collectList, current, res.data);
  1224. })
  1225. .catch(err => {
  1226. this.$set(this.collectList, current, false);
  1227. });
  1228. },
  1229. //提示且允许返回
  1230. mustBackPage(msg, text) {
  1231. this.$alert(msg || "未知异常", "提示", {
  1232. confirmButtonText: text || "返回上一页",
  1233. showClose: false,
  1234. callback: action => {
  1235. this.mustBack = true;
  1236. this.$router.go(-1);
  1237. }
  1238. });
  1239. return;
  1240. },
  1241. /**
  1242. * 请求题目列表
  1243. */
  1244. goodsQuestionList() {
  1245. this.$request[
  1246. this.doMode == 3 ? "goodsRandomQuestionList" : "goodsQuestionList"
  1247. ]({
  1248. examId: this.examId,
  1249. goodsId: this.goodsId,
  1250. orderGoodsId: this.orderGoodsId,
  1251. from: this.doMode == 3 ? 2 : ""
  1252. })
  1253. .then(async ({ data }) => {
  1254. if (this.doMode == 3) {
  1255. this.simulateExamId = data.simulateExamId;
  1256. data = data.questionList;
  1257. }
  1258. if (!data.length) {
  1259. this.mustBackPage("该试卷暂无题目");
  1260. return;
  1261. }
  1262. this.questionList = this.questionOptimizeFormat(data);
  1263. this.lastCount = this.questionList.length;
  1264. this.getCollectInfo(this.current);
  1265. await this.examRecord();
  1266. })
  1267. .catch(err => {
  1268. if (this.doMode == 3) {
  1269. this.mustBackPage("你已做完所有题目", "确定,并且返回上一页");
  1270. } else {
  1271. this.mustBackPage(err.msg);
  1272. }
  1273. });
  1274. },
  1275. //拍照
  1276. openPhoto() {
  1277. this.$refs.takePicture.openPhoto();
  1278. },
  1279. //拍照成功回显 url
  1280. async returnParameter(url) {
  1281. let file = this.$tools.convertBase64UrlToBlob(url);
  1282. const photoUrl = await this.$upload.upload(file, 0, {
  1283. gradeId: this.gradeId,
  1284. orderGoodsId: this.orderGoodsId
  1285. });
  1286. let compareFaceData = await this.faceRecognition(photoUrl);
  1287. if (compareFaceData >= 80) {
  1288. //提交拍照记录
  1289. if (await this.postStudyRecord(0, photoUrl, compareFaceData)) {
  1290. this.needPhoto = false;
  1291. if (this.openPhotoStatus == 1) {
  1292. this.examSubmit();
  1293. return;
  1294. }
  1295. if (this.allTimes) {
  1296. this.BeginTime(); //需要开启计时器
  1297. }
  1298. }
  1299. } else {
  1300. this.$message({
  1301. type: "warning",
  1302. message: "人脸匹配不通过,请重新拍照上传"
  1303. });
  1304. setTimeout(() => {
  1305. this.openPhoto();
  1306. }, 1500);
  1307. }
  1308. },
  1309. //需要开启计时器
  1310. BeginTime() {
  1311. this.timer = setInterval(() => {
  1312. if (this.lastTime <= 0) {
  1313. clearInterval(this.timer);
  1314. this.$confirm("考试时间已到,系统将自动交卷", "提示", {
  1315. showConfirmButton: false,
  1316. closeOnClickModal: false,
  1317. showCancelButton: false,
  1318. closeOnPressEscape: false,
  1319. distinguishCancelAndClose: false,
  1320. showClose: false
  1321. });
  1322. setTimeout(() => {
  1323. this.examSubmit();
  1324. }, 2000);
  1325. return;
  1326. }
  1327. this.lastTime--;
  1328. }, 1000);
  1329. },
  1330. //提交拍照记录
  1331. postStudyRecord(status = 0, imgUrl, compareFaceData) {
  1332. return new Promise(resolve => {
  1333. let data = {
  1334. photo: imgUrl,
  1335. recordId: this.recordId
  1336. };
  1337. if (imgUrl) {
  1338. data.similarity = compareFaceData; // 相似度
  1339. }
  1340. this.$request
  1341. .studyExamPhotoRecord(data)
  1342. .then(res => {
  1343. resolve(true);
  1344. })
  1345. .catch(err => {
  1346. this.$message({
  1347. type: "warning",
  1348. message: err.msg
  1349. });
  1350. });
  1351. });
  1352. },
  1353. //人脸校验
  1354. faceRecognition(url) {
  1355. return new Promise(resolve => {
  1356. this.$request
  1357. .faceCertificationCompareFace({
  1358. urlA: url,
  1359. // imageA: url,
  1360. orderGoodsId: this.orderGoodsId,
  1361. gradeId: this.gradeId
  1362. })
  1363. .then(res => {
  1364. resolve(res.data);
  1365. })
  1366. .catch(err => {
  1367. if (err.toString().indexOf("timeout") != -1) {
  1368. err = {
  1369. msg: "拍照超时,请重新拍照"
  1370. };
  1371. }
  1372. this.$message({
  1373. type: "warning",
  1374. message: err.msg
  1375. });
  1376. setTimeout(() => {
  1377. this.openPhoto();
  1378. }, 1500);
  1379. });
  1380. });
  1381. },
  1382. /**
  1383. * 记录总题数,获取recordId
  1384. */
  1385. examRecord() {
  1386. return new Promise(resolve => {
  1387. let self = this;
  1388. let questionList = 0;
  1389. this.questionList.forEach((item, index) => {
  1390. if (item.type == 1 || item.type == 2 || item.type == 3) {
  1391. questionList++;
  1392. }
  1393. });
  1394. this.$request
  1395. .bankRecord({
  1396. fromPlat: 2, //"来源平台 1小程序 2PC网站 3h5"
  1397. courseId: this.courseId,
  1398. chapterId: this.chapterId || 0,
  1399. moduleId: this.moduleId || 0,
  1400. sectionId: this.sectionId || 0,
  1401. goodsId: this.goodsId,
  1402. examId: this.examId,
  1403. type: this.type,
  1404. gradeId: this.gradeId,
  1405. totalQuestionNum: questionList,
  1406. allQuestionNum: this.questionList.length,
  1407. orderGoodsId: this.orderGoodsId,
  1408. doMode: this.doMode,
  1409. simulateExamId: this.simulateExamId
  1410. })
  1411. .then(res => {
  1412. this.recordId = res.data;
  1413. // 节不需要拍照
  1414. if (self.needPhoto) {
  1415. this.openPhoto();
  1416. } else {
  1417. if (this.lastTime) {
  1418. this.BeginTime(); //需要开启计时器
  1419. }
  1420. resolve();
  1421. }
  1422. })
  1423. .catch(err => {
  1424. if (err.code === 601) {
  1425. this.mustBackPage(err.msg);
  1426. } else {
  1427. this.$message.error(err.msg || "未知错误");
  1428. }
  1429. });
  1430. });
  1431. },
  1432. /**
  1433. * 获取试卷类型:1练习,2考试
  1434. */
  1435. bankExam() {
  1436. return new Promise(resolve => {
  1437. this.$request.bankExam(this.examId).then(res => {
  1438. this.bankType = res.data.doType; //1练习,2考试
  1439. this.allTimes = (res.data.answerTime || 0) * 60;
  1440. this.lastTime = (res.data.answerTime || 0) * 60;
  1441. this.doMode = res.data.simulateStatus ? 3 : 1;
  1442. resolve();
  1443. });
  1444. });
  1445. },
  1446. /**
  1447. * @param {Object}
  1448. * 单选点击确认
  1449. */
  1450. radioSelect(question, questionIndex, optionsId) {
  1451. // if (this.questionList[questionIndex].ques) return;
  1452. if (this.questionList[questionIndex].ques && this.bankType == 1) {
  1453. return;
  1454. }
  1455. this.$set(this.questionList[questionIndex], "ques", optionsId);
  1456. },
  1457. /**
  1458. * @param {Object}
  1459. * 案例单选点击
  1460. */
  1461. radioSelectChild(questionIndex, jsonIndex, optionsId) {
  1462. // if (this.questionList[questionIndex].ques[jsonIndex]) return;
  1463. if (
  1464. this.questionList[questionIndex].ques[jsonIndex] &&
  1465. this.bankType == 1
  1466. ) {
  1467. return;
  1468. }
  1469. this.$set(this.questionList[questionIndex].ques, jsonIndex, optionsId);
  1470. },
  1471. /**
  1472. * 多选点击确认
  1473. */
  1474. checkboxSubmit(question, questionIndex) {
  1475. // if (this.questionList[questionIndex].ques) return;
  1476. if (this.questionList[questionIndex].ques && this.bankType == 1) {
  1477. return;
  1478. }
  1479. let arr = [];
  1480. this.questionList[questionIndex].jsonStr.forEach(item => {
  1481. if (item.checked) {
  1482. arr.push(item.optionsId);
  1483. }
  1484. });
  1485. if (!arr.length) {
  1486. delete this.questionList[questionIndex].ques;
  1487. this.$message({
  1488. type: "warning",
  1489. message: "请选择答案"
  1490. });
  1491. return;
  1492. }
  1493. this.$set(this.questionList[questionIndex], "ques", arr);
  1494. },
  1495. /**
  1496. * @param {Object}
  1497. * 案例多选确认
  1498. */
  1499. checkboxSubmitChild(questionIndex, ansIndex) {
  1500. // if (this.questionList[questionIndex].ques[ansIndex]) return;
  1501. if (
  1502. this.questionList[questionIndex].ques[ansIndex] &&
  1503. this.bankType == 1
  1504. ) {
  1505. return;
  1506. }
  1507. let arr = [];
  1508. this.questionList[questionIndex].jsonStr[ansIndex].optionsList.forEach(
  1509. item => {
  1510. if (item.checked) {
  1511. arr.push(item.optionsId);
  1512. }
  1513. }
  1514. );
  1515. if (!arr.length) {
  1516. delete this.questionList[questionIndex].ques[ansIndex];
  1517. this.$message({
  1518. type: "warning",
  1519. message: "请选择答案"
  1520. });
  1521. return;
  1522. }
  1523. this.$set(this.questionList[questionIndex].ques, ansIndex, arr);
  1524. },
  1525. /**
  1526. * 判断点击确认
  1527. */
  1528. judgeSelect(question, questionIndex, index) {
  1529. // if (question.ques) return;
  1530. if (question.ques && this.bankType == 1) {
  1531. return;
  1532. }
  1533. this.$set(
  1534. this.questionList[questionIndex],
  1535. "ques",
  1536. index == 0 ? "1" : "0"
  1537. );
  1538. },
  1539. judgeSelectChild(questionIndex, jsonIndex, index) {
  1540. // console.log(this.questionList[questionIndex].ques[jsonIndex]);
  1541. // if (this.questionList[questionIndex].ques[jsonIndex]) return;
  1542. if (
  1543. this.questionList[questionIndex].ques[jsonIndex] &&
  1544. this.bankType == 1
  1545. ) {
  1546. return;
  1547. }
  1548. this.$set(
  1549. this.questionList[questionIndex].ques,
  1550. jsonIndex,
  1551. index == 0 ? "1" : "0"
  1552. );
  1553. },
  1554. /**
  1555. * 上传图片
  1556. */
  1557. uploadImg(e, question, questionIndex) {
  1558. var file = e.target.files[0];
  1559. if (file.size > 2 * 1024 * 1024) {
  1560. this.$message.warn("图片不得大于2000kb");
  1561. return;
  1562. }
  1563. var type = e.target.value
  1564. .toLowerCase()
  1565. .split(".")
  1566. .splice(-1);
  1567. if (
  1568. type[0] != "jpg" &&
  1569. type[0] != "png" &&
  1570. type[0] != "jpeg" &&
  1571. type[0] != "gif"
  1572. ) {
  1573. this.$message.error("上传格式需为:.jpg/.png/.jpeg/gif");
  1574. e.target.value = "";
  1575. return;
  1576. }
  1577. this.$upload.upload(file, 0).then(res => {
  1578. question.ansText.imageList.push(res);
  1579. });
  1580. },
  1581. /**
  1582. * 案例上传图片
  1583. */
  1584. uploadImgChild(e, questionIndex, jsonIndex) {
  1585. var file = e.target.files[0];
  1586. if (file.size > 2 * 1024 * 1024) {
  1587. this.$message.warn("图片不得大于2000kb");
  1588. return;
  1589. }
  1590. var type = e.target.value
  1591. .toLowerCase()
  1592. .split(".")
  1593. .splice(-1);
  1594. if (
  1595. type[0] != "jpg" &&
  1596. type[0] != "png" &&
  1597. type[0] != "jpeg" &&
  1598. type[0] != "gif"
  1599. ) {
  1600. this.$message.error("上传格式需为:.jpg/.png/.jpeg/gif");
  1601. e.target.value = "";
  1602. return;
  1603. }
  1604. this.$upload.upload(file, 0).then(res => {
  1605. this.questionList[questionIndex].jsonStr[
  1606. jsonIndex
  1607. ].ansText.imageList.push(res);
  1608. });
  1609. },
  1610. isOver(item, index) {
  1611. if (this.questionList[index].ques) {
  1612. if (item.type == 4) {
  1613. //案例题
  1614. let isOver = item.jsonStr.every((jsonItem, indexs) => {
  1615. if (
  1616. jsonItem.type == 1 ||
  1617. jsonItem.type == 2 ||
  1618. jsonItem.type == 3
  1619. ) {
  1620. if (item.ques[indexs]) {
  1621. return true;
  1622. } else {
  1623. return false;
  1624. }
  1625. } else if (jsonItem.type == 5) {
  1626. if (
  1627. item.ques[indexs] &&
  1628. (item.ques[indexs].text || item.ques[indexs].imageList.length)
  1629. ) {
  1630. return true;
  1631. } else {
  1632. return false;
  1633. }
  1634. }
  1635. });
  1636. if (isOver) {
  1637. return true;
  1638. } else {
  1639. return false;
  1640. }
  1641. } else if (item.type == 5) {
  1642. //简答题
  1643. //每一项都相等
  1644. if (item.ques && (item.ques.imageList.length || item.ques.text)) {
  1645. return true;
  1646. }
  1647. //判断
  1648. } else {
  1649. return false;
  1650. }
  1651. } else {
  1652. return false;
  1653. }
  1654. },
  1655. ansSubmit(question, questionIndex) {
  1656. if (!question.ansText.text && !question.ansText.imageList.length) {
  1657. this.$message({
  1658. type: "warning",
  1659. message: "请输入内容或上传图片"
  1660. });
  1661. return;
  1662. }
  1663. question.ques.imageList = question.ansText.imageList;
  1664. question.ques.text = question.ansText.text;
  1665. },
  1666. ansSubmitChild(question, questionIndex, jsonIndex) {
  1667. if (
  1668. !this.questionList[questionIndex].jsonStr[jsonIndex].ansText.text &&
  1669. !this.questionList[questionIndex].jsonStr[jsonIndex].ansText.imageList
  1670. .length
  1671. ) {
  1672. this.$message({
  1673. type: "warning",
  1674. message: "请输入内容或上传图片"
  1675. });
  1676. return;
  1677. }
  1678. this.$set(this.questionList[questionIndex].ques, jsonIndex, {
  1679. imageList:
  1680. this.questionList[questionIndex].jsonStr[jsonIndex].ansText
  1681. .imageList || [],
  1682. text:
  1683. this.questionList[questionIndex].jsonStr[jsonIndex].ansText.text || ""
  1684. });
  1685. },
  1686. changeIndex(index) {
  1687. this.current = index;
  1688. this.getCollectInfo(this.current);
  1689. },
  1690. nextQuestion() {
  1691. if (this.current >= this.questionList.length - 1) {
  1692. this.$message({
  1693. type: "warning",
  1694. message: "已经是最后一题了!"
  1695. });
  1696. return;
  1697. }
  1698. this.current++;
  1699. this.getCollectInfo(this.current);
  1700. },
  1701. prevQuestion() {
  1702. if (this.current == 0) {
  1703. this.$message({
  1704. type: "warning",
  1705. message: "已经是第一题了!"
  1706. });
  1707. return;
  1708. } else {
  1709. this.current--;
  1710. this.getCollectInfo(this.current);
  1711. }
  1712. },
  1713. isCheck(item, index) {
  1714. if (this.questionList[index].ques) {
  1715. return true;
  1716. }
  1717. },
  1718. isRight(item, index) {
  1719. //单选
  1720. if (this.questionList[index].ques) {
  1721. if (item.type == 1) {
  1722. return this.questionList[index].ques == this.questionList[index].ans;
  1723. //多选
  1724. } else if (item.type == 2) {
  1725. //每一项都相等
  1726. return this.questionList[index].ans.every((item, i) => {
  1727. return item == this.questionList[index].ques[i];
  1728. });
  1729. //判断
  1730. } else if (item.type == 3) {
  1731. return this.questionList[index].ques == this.questionList[index].ans;
  1732. } else {
  1733. return false;
  1734. }
  1735. } else {
  1736. return false;
  1737. }
  1738. },
  1739. isWrong(item, index) {
  1740. if (this.questionList[index].ques) {
  1741. //单选
  1742. if (item.type == 1) {
  1743. return this.questionList[index].ques != this.questionList[index].ans;
  1744. //多选
  1745. } else if (item.type == 2) {
  1746. //每一项都相等
  1747. return this.questionList[index].ques.some((item, i) => {
  1748. return this.questionList[index].ans.indexOf(item) == -1;
  1749. });
  1750. //判断
  1751. } else if (item.type == 3) {
  1752. return this.questionList[index].ques != this.questionList[index].ans;
  1753. } else {
  1754. return false;
  1755. }
  1756. } else {
  1757. return false;
  1758. }
  1759. },
  1760. isPart(item, index) {
  1761. if (this.questionList[index].ques) {
  1762. if (item.type == 2) {
  1763. let isWrong = this.questionList[index].ques.some((item, i) => {
  1764. return this.questionList[index].ans.indexOf(item) == -1;
  1765. });
  1766. let isRight = this.questionList[index].ans.every((item, i) => {
  1767. return item == this.questionList[index].ques[i];
  1768. });
  1769. if (!isRight && !isWrong) {
  1770. return true;
  1771. }
  1772. }
  1773. } else {
  1774. return false;
  1775. }
  1776. },
  1777. right(bankIndex, ansIndex, option) {
  1778. if (
  1779. this.questionList[bankIndex].ques[ansIndex] &&
  1780. this.questionList[bankIndex].ans[ansIndex]
  1781. ) {
  1782. if (
  1783. this.questionList[bankIndex].ques[ansIndex].indexOf(
  1784. option.optionsId
  1785. ) != -1 ||
  1786. this.questionList[bankIndex].ans[ansIndex].indexOf(
  1787. option.optionsId
  1788. ) != -1
  1789. ) {
  1790. return true;
  1791. } else {
  1792. return false;
  1793. }
  1794. } else {
  1795. return false;
  1796. }
  1797. },
  1798. wrong(bankIndex, ansIndex, option) {
  1799. if (
  1800. this.questionList[bankIndex].ques[ansIndex] &&
  1801. this.questionList[bankIndex].ans[ansIndex]
  1802. ) {
  1803. if (
  1804. this.questionList[bankIndex].ques[ansIndex].indexOf(
  1805. option.optionsId
  1806. ) != -1 &&
  1807. this.questionList[bankIndex].ans[ansIndex].indexOf(
  1808. option.optionsId
  1809. ) == -1
  1810. ) {
  1811. return true;
  1812. } else {
  1813. return false;
  1814. }
  1815. } else {
  1816. return false;
  1817. }
  1818. },
  1819. /**
  1820. * 获取已经回答的题目数
  1821. * hasSpecail (是否包含简答和案例)
  1822. */
  1823. questionOverNum(hasSpecail) {
  1824. let count = 0;
  1825. this.questionList.forEach(item => {
  1826. if (item.type == 1 || item.type == 2 || item.type == 3) {
  1827. if (item.ques) {
  1828. count++;
  1829. }
  1830. } else if (item.type == 4) {
  1831. //案例题
  1832. if (hasSpecail) {
  1833. let isOver = item.jsonStr.every((jsonItem, index) => {
  1834. if (
  1835. jsonItem.type == 1 ||
  1836. jsonItem.type == 2 ||
  1837. jsonItem.type == 3
  1838. ) {
  1839. if (item.ques[index]) {
  1840. return true;
  1841. } else {
  1842. return false;
  1843. }
  1844. } else if (jsonItem.type == 5) {
  1845. if (
  1846. item.ques[index] &&
  1847. (item.ques[index].text || item.ques[index].imageList.length)
  1848. ) {
  1849. return true;
  1850. } else {
  1851. return false;
  1852. }
  1853. }
  1854. });
  1855. if (isOver) {
  1856. count++;
  1857. }
  1858. }
  1859. } else if (item.type == 5) {
  1860. //简答题
  1861. if (hasSpecail) {
  1862. if (item.ques && (item.ques.text || item.ques.imageList.length)) {
  1863. count++;
  1864. }
  1865. }
  1866. }
  1867. });
  1868. return count;
  1869. },
  1870. collect(state, index) {
  1871. if (!state) {
  1872. this.$request
  1873. .collectQuestion({
  1874. examId: this.examId,
  1875. questionId: this.questionList[index].questionId,
  1876. goodsId: this.goodsId || "",
  1877. orderGoodsId: this.orderGoodsId,
  1878. doMode: this.doMode
  1879. })
  1880. .then(res => {
  1881. this.$set(this.collectList, index, true);
  1882. this.$message.success("收藏成功");
  1883. this.getCollectInfo(index);
  1884. });
  1885. } else {
  1886. this.$request
  1887. .deleteCollectQuestion(this.collectList[index].collectQuestionId)
  1888. .then(res => {
  1889. this.$set(this.collectList, index, false);
  1890. this.$message.success("取消收藏成功");
  1891. });
  1892. }
  1893. return;
  1894. },
  1895. submit() {
  1896. let ansCount = this.questionOverNum(true); //已答题数
  1897. this.lastCount = this.questionList.length - ansCount; //统计未答完的题数
  1898. //没有答完
  1899. if (this.lastCount !== 0) {
  1900. this.$confirm(
  1901. `您还有${this.lastCount}道题未作答, 现在继续作答,还是下次继续?`,
  1902. "提示",
  1903. {
  1904. confirmButtonText: "立即交卷",
  1905. cancelButtonText: "继续做题",
  1906. closeOnClickModal: false,
  1907. closeOnPressEscape: false,
  1908. distinguishCancelAndClose: false,
  1909. showClose: false
  1910. }
  1911. )
  1912. .then(_ => {
  1913. this.examSubmit();
  1914. })
  1915. .catch(_ => {});
  1916. return;
  1917. }
  1918. if (this.bankType == 2) {
  1919. if (this.lastTime > 0) {
  1920. let lastTime = this.countdown(this.lastTime);
  1921. this.$confirm(`时间还剩余${lastTime},确定交卷吗?`, "提示", {
  1922. confirmButtonText: "交卷",
  1923. cancelButtonText: "继续答题",
  1924. closeOnClickModal: false,
  1925. closeOnPressEscape: false,
  1926. distinguishCancelAndClose: false,
  1927. showClose: false
  1928. })
  1929. .then(_ => {
  1930. this.examSubmit();
  1931. })
  1932. .catch(_ => {});
  1933. return;
  1934. }
  1935. }
  1936. this.examSubmit();
  1937. },
  1938. /**
  1939. * @param {Object} second倒计时过滤器
  1940. */
  1941. countdown(second) {
  1942. if (second) {
  1943. let h = parseInt((second / 60 / 60) % 24); // 计算小时
  1944. let m = parseInt((second / 60) % 60); // 计算分数
  1945. let s = parseInt(second % 60); // 计算当前秒数
  1946. if (h < 10) h = "0" + h;
  1947. if (m < 10) m = "0" + m;
  1948. if (s < 10) s = "0" + s;
  1949. return h + ":" + m + ":" + s;
  1950. } else {
  1951. return "";
  1952. }
  1953. },
  1954. examSubmit() {
  1955. let form = this.calculateScore(this.questionList);
  1956. clearInterval(this.timer);
  1957. //交卷 /bank/record/edit
  1958. this.$request
  1959. .bankRecordEdit({
  1960. moduleId: this.moduleId,
  1961. chapterId: this.chapterId,
  1962. sectionId: this.sectionId,
  1963. gradeId: this.gradeId,
  1964. courseId: this.courseId,
  1965. orderGoodsId: this.orderGoodsId,
  1966. type: this.type, //题卷类型 1章卷 2节卷 3模块卷
  1967. examId: this.examId,
  1968. goodsId: this.goodsId,
  1969. recordId: this.recordId,
  1970. status: 1,
  1971. examTime: parseInt(this.allTimes),
  1972. doTime: parseInt(this.allTimes) - parseInt(this.lastTime),
  1973. ...form
  1974. })
  1975. .then(res => {
  1976. this.mustBack = true;
  1977. clearInterval(this.timer);
  1978. this.$message({
  1979. type: "success",
  1980. message: "交卷成功"
  1981. });
  1982. setTimeout(() => {
  1983. let result = {
  1984. rightQuestionNum: form.rightQuestionNum,
  1985. doWrongQuestionNum: form.questionIds.length,
  1986. score: form.performance,
  1987. totalScore: form.totalScore,
  1988. reportStatus: form.reportStatus,
  1989. lessQuestionNum: form.lessQuestionNum
  1990. };
  1991. this.setExamResult(result);
  1992. this.$router.replace({
  1993. path: "/course-report",
  1994. query: {
  1995. nextStatus: this.$route.query.nextStatus,
  1996. // orderGoodsId: this.orderGoodsId,
  1997. // chapterId: this.chapterId,
  1998. // moduleId: this.moduleId,
  1999. examId: this.examId,
  2000. recordId: this.recordId,
  2001. type: this.type //type:1章卷,2节卷,3模块卷
  2002. }
  2003. });
  2004. }, 1000);
  2005. })
  2006. .catch(err => {
  2007. if (err.code === 559) {
  2008. this.$message.error(err.msg);
  2009. console.log("拍照不够触发");
  2010. this.openPhotoStatus = 1;
  2011. this.needPhoto = true;
  2012. this.openPhoto();
  2013. } else {
  2014. this.$message.error(err.msg);
  2015. }
  2016. console.log(err, "err");
  2017. });
  2018. //错题集id提交(客观题)/exam/wwrong/record
  2019. this.$request
  2020. .examWrongRecord({
  2021. moduleId: this.moduleId || 0,
  2022. chapterId: this.chapterId || 0,
  2023. sectionId: this.sectionId || 0,
  2024. gradeId: this.gradeId,
  2025. courseId: this.courseId,
  2026. orderGoodsId: this.orderGoodsId,
  2027. examId: this.examId,
  2028. goodsId: this.goodsId,
  2029. questionIds: form.questionIds,
  2030. recordId: this.recordId,
  2031. type: 2, // 视频课程的传2
  2032. doMode: this.doMode,
  2033. courseType: 2
  2034. })
  2035. .then(res => {})
  2036. .catch(err => {});
  2037. },
  2038. getExamLearnStatus(section) {
  2039. return new Promise(resolve => {
  2040. this.$request
  2041. .getExamLearnStatus({
  2042. goodsId: this.goodsId,
  2043. gradeId: this.gradeId,
  2044. chapterId: this.chapterId,
  2045. courseId: this.courseId,
  2046. moduleId: this.moduleId,
  2047. type: this.type,
  2048. examId: this.examId,
  2049. orderGoodsId: this.orderGoodsId
  2050. })
  2051. .then(res => {
  2052. if (res.data) {
  2053. //之前是否拍照过,拍过则不需要再拍
  2054. this.needPhoto = false;
  2055. }
  2056. resolve();
  2057. });
  2058. });
  2059. },
  2060. /**
  2061. * 返回统计回答正确题数
  2062. */
  2063. examRecordEdit() {
  2064. if (this.needPhoto) {
  2065. this.$message.error("未拍照");
  2066. return;
  2067. }
  2068. clearInterval(this.postTimer);
  2069. clearInterval(this.timer);
  2070. let form = this.calculateScore(this.questionList);
  2071. this.$request
  2072. .bankRecordEdit({
  2073. examId: this.examId,
  2074. goodsId: this.goodsId,
  2075. gradeId: this.gradeId,
  2076. recordId: this.recordId,
  2077. orderGoodsId: this.orderGoodsId,
  2078. courseId: this.courseId,
  2079. type: this.type,
  2080. moduleId: this.moduleId,
  2081. chapterId: this.chapterId,
  2082. sectionId: this.sectionId,
  2083. status: 0,
  2084. ...form
  2085. })
  2086. .then(res => {});
  2087. }
  2088. },
  2089. computed: {
  2090. param() {
  2091. return {
  2092. examId: this.examId,
  2093. questionId: this.questionList[this.current]
  2094. ? this.questionList[this.current].questionId
  2095. : undefined,
  2096. goodsId: this.goodsId,
  2097. orderGoodsId: this.orderGoodsId,
  2098. collectQuestionId: this.collectList[this.current]
  2099. ? this.collectList[this.current].collectQuestionId
  2100. : undefined
  2101. };
  2102. }
  2103. },
  2104. beforeRouteLeave(to, from, next) {
  2105. if (
  2106. this.mustBack ||
  2107. this.$refs.takePicture.photoBadStatus ||
  2108. (to.path == "/home" && !this.$store.state.userInfo)
  2109. ) {
  2110. next();
  2111. } else {
  2112. next(false);
  2113. //离开
  2114. let ansCount = this.questionOverNum(true); //已答题数
  2115. this.lastCount = this.questionList.length - ansCount; //统计未答完的题数
  2116. if (this.bankType == 1) {
  2117. //所有题目答完
  2118. if (this.lastCount == 0) {
  2119. // this.testOver = true;
  2120. this.$nextTick(() => {
  2121. this.$confirm("您还未交卷,确定结束做题吗?", "温馨提示", {
  2122. confirmButtonText: "结束做题",
  2123. cancelButtonText: "下次继续",
  2124. type: "warning"
  2125. })
  2126. .then(() => {
  2127. this.examSubmit();
  2128. })
  2129. .catch(() => {
  2130. this.examRecordEdit();
  2131. next();
  2132. });
  2133. });
  2134. //未答完
  2135. } else {
  2136. this.$nextTick(() => {
  2137. this.$confirm(
  2138. `您还有${this.lastCount}道题未作答, 现在继续作答,还是下次继续?`,
  2139. "温馨提示",
  2140. {
  2141. confirmButtonText: "继续作答",
  2142. cancelButtonText: "下次继续",
  2143. type: "warning"
  2144. }
  2145. )
  2146. .then(() => {
  2147. // confirmButton回调
  2148. })
  2149. .catch(() => {
  2150. this.examRecordEdit();
  2151. next();
  2152. });
  2153. });
  2154. // this.isLastCount = true;
  2155. }
  2156. } else if (this.bankType == 2) {
  2157. //所有题目答完
  2158. if (this.lastCount == 0) {
  2159. this.$nextTick(() => {
  2160. this.$confirm(`您已完成所有题目,快去交卷吧!`, "温馨提示", {
  2161. confirmButtonText: "立即交卷",
  2162. cancelButtonText: "暂不交卷",
  2163. type: "warning"
  2164. })
  2165. .then(() => {
  2166. // confirmButton回调
  2167. this.examSubmit();
  2168. })
  2169. .catch(() => {});
  2170. });
  2171. //未答完
  2172. } else {
  2173. this.$nextTick(() => {
  2174. this.$confirm(
  2175. `您当前正在测试,还剩${this.lastCount}道题未完成,离开视为交卷`,
  2176. "温馨提示",
  2177. {
  2178. confirmButtonText: "继续离开",
  2179. cancelButtonText: "暂不离开",
  2180. type: "warning"
  2181. }
  2182. )
  2183. .then(() => {
  2184. this.examSubmit();
  2185. })
  2186. .catch(() => {});
  2187. });
  2188. }
  2189. }
  2190. }
  2191. }
  2192. };
  2193. </script>
  2194. <!-- Add "scoped" attribute to limit CSS to this component only -->
  2195. <style scoped lang="scss">
  2196. .course-exam {
  2197. .section {
  2198. overflow: hidden;
  2199. &__header {
  2200. height: 20px;
  2201. margin-top: 20px;
  2202. }
  2203. &__body {
  2204. .explain-record {
  2205. &__body {
  2206. border: 1px solid #eee;
  2207. .left-box {
  2208. position: relative;
  2209. float: left;
  2210. width: 970px;
  2211. min-height: 630px;
  2212. border: 1px solid #eee;
  2213. &__body {
  2214. border-bottom: 1px solid #eee;
  2215. .question {
  2216. padding: 12px 0 0 12px;
  2217. display: flex;
  2218. flex-direction: column;
  2219. height: 100%;
  2220. &__title {
  2221. padding-left: 12px;
  2222. font-size: 16px;
  2223. font-family: Microsoft YaHei;
  2224. font-weight: bold;
  2225. color: #333333;
  2226. line-height: 24px;
  2227. }
  2228. &__desc {
  2229. padding-left: 12px;
  2230. margin-top: 20px;
  2231. font-size: 16px;
  2232. font-family: Microsoft YaHei;
  2233. font-weight: 400;
  2234. color: #666666;
  2235. line-height: 24px;
  2236. text-align: justify;
  2237. /deep/ img {
  2238. max-width: 100% !important;
  2239. }
  2240. }
  2241. &__content {
  2242. /deep/ .el-tabs__item {
  2243. padding: 0 20px !important;
  2244. height: 40px;
  2245. line-height: 40px;
  2246. }
  2247. .question__content {
  2248. height: auto;
  2249. overflow: auto;
  2250. }
  2251. .question-list {
  2252. padding: 24px 0 24px 24px;
  2253. border-bottom: 1px solid #eee;
  2254. .checkbox,
  2255. .radio {
  2256. cursor: pointer;
  2257. margin-right: 24px;
  2258. padding: 0 24px;
  2259. display: flex;
  2260. align-items: center;
  2261. margin-top: 2px;
  2262. min-height: 40px;
  2263. padding-top: 10px;
  2264. padding-bottom: 10px;
  2265. background: #f5f9ff;
  2266. border-radius: 8px;
  2267. box-sizing: border-box;
  2268. &.right {
  2269. background: #37c65b;
  2270. }
  2271. &.wrong {
  2272. background: #ff3a30;
  2273. }
  2274. &.user_choose {
  2275. background: #007aff;
  2276. }
  2277. }
  2278. &.textarea {
  2279. margin-right: 12px;
  2280. .upload {
  2281. margin-top: 10px;
  2282. &__imgs {
  2283. margin-right: 10px;
  2284. width: 80px;
  2285. height: 80px;
  2286. background: #ffffff;
  2287. border: 1px solid #eeeeee;
  2288. border-radius: 4px;
  2289. position: relative;
  2290. display: flex;
  2291. float: left;
  2292. align-items: center;
  2293. justify-content: center;
  2294. img {
  2295. max-width: 100%;
  2296. max-height: 100%;
  2297. }
  2298. }
  2299. &__btn {
  2300. margin-right: 10px;
  2301. width: 80px;
  2302. height: 80px;
  2303. background: #ffffff;
  2304. border: 1px solid #eeeeee;
  2305. border-radius: 4px;
  2306. position: relative;
  2307. display: flex;
  2308. float: left;
  2309. align-items: center;
  2310. justify-content: center;
  2311. flex-direction: column;
  2312. .icon {
  2313. font-size: 20px;
  2314. color: #3f8dfd;
  2315. }
  2316. p {
  2317. font-size: 12px;
  2318. font-family: Microsoft YaHei;
  2319. font-weight: 400;
  2320. color: #999999;
  2321. line-height: 24px;
  2322. }
  2323. input {
  2324. position: absolute;
  2325. left: 0;
  2326. top: 0;
  2327. display: block;
  2328. width: 100%;
  2329. height: 100%;
  2330. opacity: 0;
  2331. }
  2332. }
  2333. }
  2334. }
  2335. /deep/
  2336. .el-checkbox__input.is-checked
  2337. + .el-checkbox__label {
  2338. color: #000 !important;
  2339. }
  2340. /deep/
  2341. .el-checkbox__input.is-disabled
  2342. + span.el-checkbox__label {
  2343. color: #000;
  2344. }
  2345. /deep/ .el-checkbox {
  2346. white-space: normal;
  2347. }
  2348. }
  2349. .answer-list {
  2350. height: 40px;
  2351. // border-top: 1px solid #eee;
  2352. border-bottom: 1px solid #eee;
  2353. // margin-top: 24px;
  2354. display: flex;
  2355. align-items: center;
  2356. justify-content: space-between;
  2357. padding: 0 24px;
  2358. &__left {
  2359. font-size: 16px;
  2360. font-family: Microsoft YaHei;
  2361. font-weight: 400;
  2362. color: #333333;
  2363. line-height: 24px;
  2364. }
  2365. &__right {
  2366. font-size: 16px;
  2367. font-family: Microsoft YaHei;
  2368. font-weight: 400;
  2369. color: #333333;
  2370. line-height: 24px;
  2371. }
  2372. }
  2373. .explain-list {
  2374. padding: 12px 24px;
  2375. &__header {
  2376. font-size: 16px;
  2377. font-family: Microsoft YaHei;
  2378. font-weight: bold;
  2379. color: #666666;
  2380. line-height: 24px;
  2381. }
  2382. &__body {
  2383. margin-top: 12px;
  2384. font-size: 16px;
  2385. font-family: Microsoft YaHei;
  2386. font-weight: 400;
  2387. color: #666666;
  2388. line-height: 24px;
  2389. }
  2390. .upload {
  2391. margin-top: 10px;
  2392. &__imgs {
  2393. margin-right: 10px;
  2394. width: 80px;
  2395. height: 80px;
  2396. background: #ffffff;
  2397. border: 1px solid #eeeeee;
  2398. border-radius: 4px;
  2399. position: relative;
  2400. display: flex;
  2401. float: left;
  2402. align-items: center;
  2403. justify-content: center;
  2404. img {
  2405. max-width: 100%;
  2406. max-height: 100%;
  2407. }
  2408. }
  2409. }
  2410. }
  2411. .question {
  2412. padding-bottom: 58px;
  2413. }
  2414. }
  2415. &__btns {
  2416. position: relative;
  2417. height: 32px;
  2418. .submit {
  2419. cursor: pointer;
  2420. margin: 0 auto;
  2421. width: 140px;
  2422. height: 32px;
  2423. background: #3f8dfd;
  2424. box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.2);
  2425. border-radius: 16px;
  2426. text-align: center;
  2427. line-height: 32px;
  2428. color: #fff;
  2429. font-size: 16px;
  2430. }
  2431. .collect {
  2432. cursor: pointer;
  2433. position: absolute;
  2434. right: 0;
  2435. top: 5px;
  2436. font-size: 12px;
  2437. font-family: Microsoft YaHei;
  2438. font-weight: 400;
  2439. color: #3f8dfd;
  2440. line-height: 24px;
  2441. }
  2442. }
  2443. }
  2444. }
  2445. }
  2446. .right-box {
  2447. float: right;
  2448. width: 299px;
  2449. border-right: 1px solid #eee;
  2450. &__header {
  2451. height: 40px;
  2452. line-height: 40px;
  2453. border-bottom: 1px solid #eeeeee;
  2454. padding: 0 10px;
  2455. .back-btn {
  2456. display: block;
  2457. margin: 0 auto;
  2458. width: 160px;
  2459. }
  2460. .title {
  2461. float: left;
  2462. font-size: 16px;
  2463. font-family: Microsoft YaHei;
  2464. font-weight: bold;
  2465. color: #333333;
  2466. float: left;
  2467. }
  2468. .time {
  2469. font-size: 16px;
  2470. font-family: Microsoft YaHei;
  2471. font-weight: 400;
  2472. color: #666666;
  2473. float: right;
  2474. }
  2475. }
  2476. &__body {
  2477. border-bottom: 1px solid #eee;
  2478. height: 510px;
  2479. .card {
  2480. &__note {
  2481. display: flex;
  2482. height: 64px;
  2483. align-items: center;
  2484. border-bottom: 1px solid #eee;
  2485. flex-wrap: wrap;
  2486. .item {
  2487. display: flex;
  2488. align-items: center;
  2489. margin-left: 10px;
  2490. width: 84px;
  2491. font-size: 12px;
  2492. .box {
  2493. margin-right: 5px;
  2494. width: 16px;
  2495. height: 16px;
  2496. border-radius: 4px;
  2497. &.white {
  2498. background: #ffffff;
  2499. border: 1px solid #eeeeee;
  2500. }
  2501. &.green {
  2502. background: #37c65b;
  2503. }
  2504. &.red {
  2505. background: #ff3a30;
  2506. }
  2507. &.yellow {
  2508. background: #ffc53d;
  2509. }
  2510. &.blue,
  2511. &.check_ans {
  2512. background: #3f8dfd;
  2513. }
  2514. }
  2515. }
  2516. }
  2517. &__content {
  2518. height: 440px;
  2519. overflow-y: scroll;
  2520. &::-webkit-scrollbar {
  2521. width: 6px;
  2522. }
  2523. &::-webkit-scrollbar-track {
  2524. background-color: #fff;
  2525. -webkit-border-radius: 2em;
  2526. -moz-border-radius: 2em;
  2527. border-radius: 2em;
  2528. }
  2529. &::-webkit-scrollbar-thumb {
  2530. background-color: #eeeeee;
  2531. -webkit-border-radius: 2em;
  2532. -moz-border-radius: 2em;
  2533. border-radius: 2em;
  2534. }
  2535. .list {
  2536. display: flex;
  2537. flex-wrap: wrap;
  2538. .item {
  2539. width: 40px;
  2540. height: 40px;
  2541. border-radius: 10px;
  2542. text-align: center;
  2543. line-height: 40px;
  2544. margin-left: 16px;
  2545. margin-top: 16px;
  2546. cursor: pointer;
  2547. &.white {
  2548. line-height: 38px;
  2549. color: #333333;
  2550. background: #ffffff;
  2551. border: 1px solid #eeeeee;
  2552. }
  2553. &.green {
  2554. color: #fff;
  2555. background: #37c65b;
  2556. }
  2557. &.red {
  2558. color: #fff;
  2559. background: #ff3a30;
  2560. }
  2561. &.blue,
  2562. &.check_ans {
  2563. color: #fff;
  2564. background: #3f8dfd;
  2565. }
  2566. &.yellow {
  2567. background: #ffc53d;
  2568. }
  2569. &.disabled {
  2570. cursor: not-allowed;
  2571. line-height: 38px;
  2572. color: #eeeeee;
  2573. background: #ffffff;
  2574. border: 1px solid #eeeeee;
  2575. }
  2576. }
  2577. }
  2578. }
  2579. }
  2580. }
  2581. &__footer {
  2582. border-bottom: 1px solid #eee;
  2583. height: 40px;
  2584. display: flex;
  2585. align-items: center;
  2586. justify-content: center;
  2587. .submit {
  2588. cursor: pointer;
  2589. width: 140px;
  2590. height: 32px;
  2591. background: #3f8dfd;
  2592. box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.2);
  2593. border-radius: 16px;
  2594. line-height: 32px;
  2595. text-align: center;
  2596. color: #fff;
  2597. font-size: 16px;
  2598. }
  2599. }
  2600. }
  2601. }
  2602. }
  2603. }
  2604. }
  2605. .take-photo {
  2606. /deep/ .el-dialog__header {
  2607. display: none;
  2608. }
  2609. /deep/ .el-dialog__body {
  2610. padding: 0;
  2611. overflow: unset;
  2612. }
  2613. &__close {
  2614. cursor: pointer;
  2615. position: absolute;
  2616. right: 0;
  2617. top: -28px;
  2618. width: 24px;
  2619. height: 24px;
  2620. line-height: 24px;
  2621. text-align: center;
  2622. color: #eee;
  2623. border: 1px solid #eee;
  2624. border-radius: 50%;
  2625. }
  2626. &__header {
  2627. height: 40px;
  2628. border-bottom: 1px solid #eee;
  2629. line-height: 40px;
  2630. font-size: 16px;
  2631. font-family: Microsoft YaHei;
  2632. font-weight: bold;
  2633. color: #333333;
  2634. padding-left: 24px;
  2635. }
  2636. &__body {
  2637. // height: 400px;
  2638. padding: 40px 24px;
  2639. .left-box {
  2640. width: 336px;
  2641. float: left;
  2642. .title {
  2643. font-size: 16px;
  2644. font-family: Microsoft YaHei;
  2645. font-weight: bold;
  2646. color: #ff3b30;
  2647. line-height: 24px;
  2648. }
  2649. .content {
  2650. font-size: 14px;
  2651. font-family: Microsoft YaHei;
  2652. font-weight: 400;
  2653. color: #333333;
  2654. line-height: 28px;
  2655. margin-top: 32px;
  2656. }
  2657. }
  2658. .right-box {
  2659. float: right;
  2660. width: 400px;
  2661. height: 400px;
  2662. position: relative;
  2663. overflow: hidden;
  2664. video {
  2665. width: 100%;
  2666. height: 100%;
  2667. }
  2668. .mask {
  2669. width: 55%;
  2670. height: 200px;
  2671. position: absolute;
  2672. top: 0;
  2673. left: 0;
  2674. right: 0;
  2675. bottom: 0;
  2676. margin: 30px auto 0;
  2677. box-shadow: 0 0 0 2000px rgba(0, 0, 0, 0.4);
  2678. }
  2679. }
  2680. }
  2681. &__footer {
  2682. height: 90px;
  2683. border-top: 1px solid #eee;
  2684. text-align: center;
  2685. .take {
  2686. display: inline-block;
  2687. width: 200px;
  2688. height: 40px;
  2689. padding: 0;
  2690. border-radius: 20px;
  2691. text-align: center;
  2692. line-height: 40px;
  2693. margin: 24px auto;
  2694. }
  2695. }
  2696. }
  2697. }
  2698. </style>