DialogueAnswerViewChs.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. <!-- -->
  2. <template>
  3. <div
  4. class="dialogue-answer-view NPC-zhedie dialogue-answer-view-phone"
  5. v-if="isShowTemp"
  6. :style="{ background: themeColorPhone }"
  7. >
  8. <!-- 标题 -->
  9. <template v-if="curQue.title">
  10. <div class="topTitle">
  11. <div class="NPC-top-left">
  12. <span class="NPC-topTitle-text">{{ curQue.title }}</span>
  13. </div>
  14. <div class="NPC-top-right" @click="handleChangeTab">
  15. <span class="NPC-top-right-text">{{
  16. wordShow ? "收起" : "展开"
  17. }}</span>
  18. <img v-if="wordShow" src="../../../../assets/NPC/down.png" alt="" />
  19. <img
  20. v-else
  21. class="rotate"
  22. src="../../../../assets/NPC/down.png"
  23. alt=""
  24. />
  25. </div>
  26. </div>
  27. <el-collapse-transition>
  28. <div :class="['dialogue-answer-content']" v-show="wordShow">
  29. <div
  30. class="guide"
  31. v-if="curQue.guide"
  32. :style="{ fontSize: baseSizePhone - 2 + 'px' }"
  33. >
  34. {{ curQue.guide }}
  35. </div>
  36. <div
  37. :class="[
  38. 'dialogue-answer-inner',
  39. curQue.option &&
  40. curQue.option.length > 0 &&
  41. curQue.option[index] &&
  42. curQue.option[index].detail &&
  43. curQue.option[index].detail.length > 0
  44. ? 'hasoption'
  45. : '',
  46. index == curQue.list.length - 1 ? 'haspadding' : ''
  47. ]"
  48. v-for="(item, index) in curQue.list"
  49. :key="'list' + index"
  50. >
  51. <span
  52. class="number"
  53. v-if="item.number"
  54. :style="{ fontSize: baseSizePhone + 'px' }"
  55. >{{ item.number }}</span
  56. >
  57. <div class="dialogue-item">
  58. <div
  59. class="dialogue-img"
  60. v-if="item.img_list && item.img_list.length > 0"
  61. >
  62. <el-image
  63. :style="{
  64. width: '100px',
  65. height: '100px'
  66. }"
  67. :src="item.img_list[0].id"
  68. fit="scale-down"
  69. @click="imgShow(item.img_list[0].id)"
  70. ></el-image>
  71. </div>
  72. <div class="dialogue-answer-model">
  73. <AnswerModel
  74. :curQue="item"
  75. :Bookanswer="curQue.Bookanswer[index]"
  76. :pyPosition="curQue.pyPosition"
  77. :enPosition="curQue.enPosition"
  78. :colorBox="colorBox"
  79. :TaskModel="TaskModel"
  80. :listIndex="index"
  81. :judgeAnswer="judgeAnswer"
  82. :audioWidth="item.number ? 592 : 620"
  83. :baseSizePhone="baseSizePhone"
  84. />
  85. </div>
  86. <template
  87. v-if="
  88. curQue.option &&
  89. curQue.option.length > 0 &&
  90. curQue.option[index] &&
  91. curQue.option[index].detail &&
  92. curQue.option[index].detail.length > 0
  93. "
  94. >
  95. <OptionModel
  96. :curOption="curQue.option[index]"
  97. :index="index"
  98. :baseSizePhone="baseSizePhone"
  99. />
  100. </template>
  101. </div>
  102. </div>
  103. </div>
  104. </el-collapse-transition>
  105. </template>
  106. <template v-else>
  107. <div class="dialogue-answer-content">
  108. <div
  109. class="guide"
  110. :style="{ fontSize: baseSizePhone - 2 + 'px' }"
  111. v-if="curQue.guide"
  112. >
  113. {{ curQue.guide }}
  114. </div>
  115. <div
  116. class="dialogue-answer-inner"
  117. v-for="(item, index) in curQue.list"
  118. :key="'list' + index"
  119. >
  120. <template v-if="isShowQue(index)">
  121. <span
  122. class="number"
  123. v-if="item.number"
  124. :style="{ fontSize: baseSizePhone + 'px' }"
  125. >{{ item.number }}</span
  126. >
  127. <div class="dialogue-item">
  128. <div
  129. class="dialogue-img"
  130. v-if="item.img_list && item.img_list.length > 0"
  131. >
  132. <el-image
  133. :style="{
  134. width: '100px',
  135. height: '100px'
  136. }"
  137. :src="item.img_list[0].id"
  138. fit="scale-down"
  139. @click="imgShow(item.img_list[0].id)"
  140. ></el-image>
  141. </div>
  142. <div class="dialogue-answer-model">
  143. <AnswerModel
  144. :curQue="item"
  145. :Bookanswer="curQue.Bookanswer[index]"
  146. :pyPosition="curQue.pyPosition"
  147. :enPosition="curQue.enPosition"
  148. :colorBox="colorBox"
  149. :listIndex="index"
  150. :TaskModel="TaskModel"
  151. :judgeAnswer="judgeAnswer"
  152. :audioWidth="item.number ? 592 : 620"
  153. :baseSizePhone="baseSizePhone"
  154. />
  155. </div>
  156. <template
  157. v-if="
  158. curQue.option &&
  159. curQue.option.length > 0 &&
  160. curQue.option[index] &&
  161. curQue.option[index].detail &&
  162. curQue.option[index].detail.length > 0
  163. "
  164. >
  165. <OptionModel
  166. :curOption="curQue.option[index]"
  167. :index="index"
  168. :baseSizePhone="baseSizePhone"
  169. />
  170. </template>
  171. <template
  172. v-if="
  173. curQue.wordcard &&
  174. curQue.wordcard.length > 0 &&
  175. curQue.wordcard[index]
  176. "
  177. >
  178. <WordcardModel
  179. :curWordcard="curQue.wordcard[index]"
  180. :index="index"
  181. :pyPosition="curQue.pyPosition"
  182. />
  183. </template>
  184. </div>
  185. </template>
  186. </div>
  187. </div>
  188. </template>
  189. <img-preview
  190. v-if="imgPreviewDialog"
  191. :imgPreviewSrc="imgPreviewSrc"
  192. @closeImgPreview="closeImgPreview"
  193. ></img-preview>
  194. </div>
  195. </template>
  196. <script>
  197. import AudioLine from "../AudioLine.vue";
  198. import RoleChs from "./RoleChs.vue";
  199. import RemarkChs from "./RemarkChs.vue";
  200. import Soundrecord from "../Soundrecord.vue";
  201. import AnswerModel from "./AnswerModel.vue";
  202. import OptionModel from "./OptionModel.vue";
  203. import WordcardModel from "./WordcardModel.vue";
  204. import ImgPreview from "../components/ImgPreview.vue";
  205. export default {
  206. name: "DialogueAnswerViewChs",
  207. components: {
  208. AudioLine,
  209. RoleChs,
  210. RemarkChs,
  211. Soundrecord,
  212. AnswerModel,
  213. OptionModel,
  214. WordcardModel,
  215. ImgPreview
  216. },
  217. props: [
  218. "curQue",
  219. "colorBox",
  220. "TaskModel",
  221. "judgeAnswer",
  222. "baseSizePhone",
  223. "themeColorPhone"
  224. ],
  225. data() {
  226. return {
  227. wordShow: true,
  228. noFont: ["~", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "/"],
  229. userAnswer: {
  230. recordList: [],
  231. input: [],
  232. judge: []
  233. },
  234. judgeAnswersList: [],
  235. userErrorNumberTotal: 0,
  236. imgPreviewDialog: false,
  237. imgPreviewSrc: ""
  238. };
  239. },
  240. computed: {
  241. isShowTemp() {
  242. let _this = this;
  243. let bool = false;
  244. if (_this.curQue && _this.curQue.Bookanswer) {
  245. if (_this.judgeAnswer == "standardAnswer") {
  246. if (_this.userErrorNumberTotal > 0) {
  247. bool = true;
  248. } else {
  249. bool = false;
  250. }
  251. } else {
  252. bool = true;
  253. }
  254. }
  255. return bool;
  256. },
  257. isShowQue() {
  258. return function(index) {
  259. let _this = this;
  260. let bool = false;
  261. let userErrorNumberTotal = 0;
  262. let Bookanswer = _this.curQue.Bookanswer;
  263. if (Bookanswer && Bookanswer.length > 0) {
  264. userErrorNumberTotal = _this.countUserErrorNumber(Bookanswer[index]);
  265. if (_this.judgeAnswer == "standardAnswer") {
  266. if (userErrorNumberTotal > 0) {
  267. bool = true;
  268. } else {
  269. bool = false;
  270. }
  271. } else {
  272. bool = true;
  273. }
  274. }
  275. return bool;
  276. };
  277. }
  278. },
  279. watch: {},
  280. //方法集合
  281. methods: {
  282. handleChangeTab() {
  283. this.wordShow = !this.wordShow;
  284. },
  285. handleData() {
  286. let list = JSON.parse(JSON.stringify(this.curQue.list));
  287. list.forEach(item => {
  288. let answerArr = [];
  289. if (item.answer) {
  290. answerArr = item.answer.split("\n");
  291. }
  292. item.answerArr = answerArr;
  293. });
  294. this.$set(this.curQue, "list", list);
  295. },
  296. initAnswer() {
  297. let reg = /_{2,}/g;
  298. let BookAnswer = [];
  299. let list = JSON.parse(JSON.stringify(this.curQue.list));
  300. list.forEach((item, index) => {
  301. let answerArr = [];
  302. if (item.answer) {
  303. answerArr = item.answer.split("\n");
  304. }
  305. let arr = item.article.match(reg);
  306. let paraLeg = item.detail.length;
  307. let userAnswer = JSON.parse(JSON.stringify(this.userAnswer));
  308. if (arr) {
  309. arr.forEach((aItem, aIndex) => {
  310. let re = {
  311. value: "",
  312. userAnswerJudge:
  313. answerArr.length > 0 &&
  314. answerArr[aIndex] &&
  315. answerArr[aIndex] != "??" &&
  316. answerArr[aIndex] != "??"
  317. ? "[JUDGE##F##JUDGE]"
  318. : ""
  319. };
  320. userAnswer.input.push(JSON.parse(JSON.stringify(re)));
  321. });
  322. for (let i = 0; i < paraLeg; i++) {
  323. userAnswer.recordList.push(null);
  324. }
  325. } else if (item.checkList && item.checkList.indexOf("record") > -1) {
  326. for (let i = 0; i < paraLeg; i++) {
  327. userAnswer.recordList.push(null);
  328. }
  329. }
  330. if (item.checkList && item.checkList.indexOf("judge") > -1) {
  331. for (let i = 0; i < paraLeg; i++) {
  332. let judge_obj = {
  333. value: "",
  334. userAnswerJudge:
  335. item.judge[i].isJudge && item.judge[i].judge
  336. ? "[JUDGE##F##JUDGE]"
  337. : ""
  338. };
  339. userAnswer.judge.push(JSON.parse(JSON.stringify(judge_obj)));
  340. }
  341. }
  342. BookAnswer.push(userAnswer);
  343. });
  344. this.$set(this.curQue, "Bookanswer", BookAnswer);
  345. },
  346. countUserErrorNumber(data) {
  347. let BookanswerStr = JSON.stringify(data);
  348. let userErrorNumberTotal = 0;
  349. let errReg = /\[JUDGE##F##JUDGE\]/g;
  350. if (errReg.test(BookanswerStr)) {
  351. let errorArr = BookanswerStr.match(/\[JUDGE##F##JUDGE\]/g);
  352. userErrorNumberTotal = errorArr.length;
  353. }
  354. return userErrorNumberTotal;
  355. },
  356. imgShow(id) {
  357. this.imgPreviewDialog = true;
  358. this.imgPreviewSrc = id;
  359. },
  360. closeImgPreview() {
  361. this.imgPreviewDialog = false;
  362. }
  363. },
  364. //生命周期 - 创建完成(可以访问当前this实例)
  365. created() {},
  366. //生命周期 - 挂载完成(可以访问DOM元素)
  367. mounted() {
  368. let _this = this;
  369. _this.userErrorNumberTotal = 0;
  370. if (_this.curQue) {
  371. _this.handleData();
  372. if (!_this.curQue.Bookanswer) {
  373. _this.initAnswer();
  374. } else {
  375. _this.userErrorNumberTotal = _this.countUserErrorNumber(
  376. _this.curQue.Bookanswer
  377. );
  378. }
  379. }
  380. },
  381. beforeCreate() {}, //生命周期 - 创建之前
  382. beforeMount() {}, //生命周期 - 挂载之前
  383. beforeUpdate() {}, //生命周期 - 更新之前
  384. updated() {}, //生命周期 - 更新之后
  385. beforeDestroy() {}, //生命周期 - 销毁之前
  386. destroyed() {}, //生命周期 - 销毁完成
  387. activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
  388. };
  389. </script>
  390. <style lang="scss" scoped>
  391. //@import url(); 引入公共css类
  392. .dialogue-answer-view {
  393. width: 100%;
  394. margin-bottom: 24px;
  395. .guide {
  396. width: 100%;
  397. font-size: 16px;
  398. line-height: 19px;
  399. font-family: "robot";
  400. padding-top: 24px;
  401. }
  402. .dialogue-answer-content {
  403. width: 100%;
  404. box-sizing: border-box;
  405. padding: 0px 24px 0 24px;
  406. &.nooption {
  407. padding-bottom: 40px;
  408. }
  409. }
  410. .dialogue-answer-inner {
  411. display: flex;
  412. justify-content: flex-start;
  413. align-items: flex-start;
  414. padding: 5px 0;
  415. &.hasoption {
  416. border-bottom: 1px solid rgba(0, 0, 0, 0.1);
  417. padding-bottom: 24px;
  418. }
  419. &.haspadding {
  420. padding-bottom: 40px;
  421. }
  422. &:nth-last-child(1) {
  423. border: 0;
  424. }
  425. .number {
  426. width: 32px;
  427. height: 32px;
  428. background: #e35454;
  429. border-radius: 100%;
  430. display: flex;
  431. justify-content: center;
  432. align-items: center;
  433. font-weight: bold;
  434. font-size: 16px;
  435. line-height: 150%;
  436. color: #ffffff;
  437. font-family: "robot";
  438. margin-top: 4px;
  439. flex-shrink: 0;
  440. }
  441. }
  442. .dialogue-answer-model {
  443. flex: 1;
  444. }
  445. .dialogue-answer-article {
  446. width: 100%;
  447. display: flex;
  448. justify-content: flex-start;
  449. align-items: center;
  450. }
  451. .dialogue-img {
  452. width: 228px;
  453. height: 196px;
  454. background: #ffffff;
  455. border: 1px solid rgba(0, 0, 0, 0.1);
  456. box-sizing: border-box;
  457. border-radius: 8px;
  458. padding: 16px;
  459. overflow: hidden;
  460. margin-left: 24px;
  461. margin-top: 8px;
  462. > img {
  463. width: 100%;
  464. }
  465. }
  466. &-phone {
  467. .dialogue-answer-content {
  468. padding: 0;
  469. }
  470. .dialogue-answer-inner {
  471. display: block;
  472. .dialogue-item {
  473. display: flex;
  474. justify-content: flex-start;
  475. align-items: flex-start;
  476. .dialogue-img {
  477. margin-left: 0;
  478. margin-right: 5px;
  479. width: 122px;
  480. height: 122px;
  481. padding: 10px;
  482. flex-shrink: 0;
  483. border: 1px solid rgba(0, 0, 0, 0.1);
  484. border-radius: 8px;
  485. }
  486. }
  487. }
  488. }
  489. }
  490. .NPC-Big-Book-preview-green {
  491. .dialogue-answer-view {
  492. .number {
  493. background: #24b99e !important;
  494. }
  495. }
  496. }
  497. .NPC-Big-Book-preview-brown {
  498. .number {
  499. background: #bd8865 !important;
  500. }
  501. }
  502. </style>
  503. <style lang="scss">
  504. .dialogue-answer-view-phone {
  505. .article-content {
  506. padding: 8px 0 !important;
  507. }
  508. }
  509. </style>