PinyinBasePreview.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. <!-- eslint-disable vue/no-v-html -->
  2. <template>
  3. <div class="pinyin-preview" :style="[getAreaStyle(), getComponentStyle()]">
  4. <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
  5. <div class="main">
  6. <div
  7. class="content-box"
  8. :class="[data.property.arrange_type === 'horizontal' ? 'content-box-flex' : 'content-box-vertical']"
  9. >
  10. <div class="first-con">
  11. <AudioPlay
  12. v-if="data.audio_file_id && data.property.audio_position === 'front'"
  13. :file-id="data.audio_file_url"
  14. :theme-color="data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''"
  15. />
  16. <div
  17. class="option-content"
  18. :class="[
  19. isJudgingRightWrong && data.property.fun_type === 'mark'
  20. ? con_preview[0].all_right
  21. ? 'all-right'
  22. : 'has-error'
  23. : '',
  24. ]"
  25. :style="{
  26. fontSize: data.unified_attrib && data.unified_attrib.font_size ? data.unified_attrib.font_size : '',
  27. }"
  28. >
  29. <span v-if="data.content_hz" class="items-hz">{{ convertText(data.content_hz) }}</span>
  30. <!-- 拼音输入 -->
  31. <template v-if="data.property.fun_type === 'input'">
  32. <span
  33. v-for="(itemc, indexc) in con_preview"
  34. :key="indexc"
  35. :class="['item-con', isJudgingRightWrong && itemc.type === 'input' ? itemc.is_right : '']"
  36. >
  37. <el-input
  38. v-if="itemc.type === 'input'"
  39. v-model="itemc.con"
  40. :disabled="disabled"
  41. :style="[{ width: Math.max(20, itemc.con.length * 10) + 'px' }]"
  42. class="item-input"
  43. @blur="onInputChange(itemc)"
  44. />
  45. <span v-else>{{ convertText(itemc.con) }}</span>
  46. </span>
  47. </template>
  48. <template v-else-if="data.property.answer_mode === 'select'">
  49. <template v-if="data.property.fun_type === 'show'">
  50. <span v-for="(itemc, indexc) in data.matically_pinyin_str[data.mark]" :key="indexc" class="items-box">
  51. <span v-for="(itemi, indexi) in itemc" :key="indexi" :class="['items-con']">{{ itemi }}</span>
  52. </span>
  53. </template>
  54. <template v-else>
  55. <span
  56. v-for="(itemc, indexc) in con_preview[0].item_con"
  57. :key="indexc"
  58. :class="[
  59. 'item-con',
  60. active_index_str === 0 + '-' + indexc ? 'active' : '',
  61. isJudgingRightWrong && !con_preview[0].user_answer[indexc].is_right ? 'error' : '',
  62. data.property.fun_type === 'show' ? 'item-con-in' : '',
  63. ]"
  64. @click="
  65. if (data.property.fun_type === 'show') return;
  66. con_preview[0].item_active_index = indexc;
  67. active_index_str = 0 + '-' + indexc;
  68. "
  69. >
  70. {{ itemc }}
  71. </span>
  72. </template>
  73. </template>
  74. <template v-else>
  75. <span v-for="(itemc, indexc) in con_preview[0].item_con" :key="indexc" class="items-box">
  76. <span
  77. v-for="(itemi, indexi) in itemc"
  78. :key="indexi"
  79. :class="[
  80. 'items-con',
  81. active_index_str === 0 + '-' + indexc + '-' + indexi ? 'active' : '',
  82. isJudgingRightWrong &&
  83. !con_preview[0].user_answer[indexc].is_right &&
  84. con_preview[0].user_answer[indexc].select_index_submit === indexi
  85. ? 'error'
  86. : '',
  87. isJudgingRightWrong &&
  88. !con_preview[0].user_answer[indexc].is_right &&
  89. con_preview[0].user_answer[indexc].right_index === indexi
  90. ? 'right'
  91. : '',
  92. ]"
  93. @click="handleSelectItemTone(0, indexc, indexi, con_preview[0].item_con_yuan[indexc][indexi])"
  94. >{{ itemi }}</span
  95. >
  96. </span>
  97. </template>
  98. </div>
  99. <AudioPlay
  100. v-if="data.audio_file_id && data.property.audio_position === 'back'"
  101. :file-id="data.audio_file_url"
  102. />
  103. </div>
  104. <div v-if="data.property.fun_type === 'mark'" class="tone-box">
  105. <span
  106. v-for="({ img, value }, j) in toneList"
  107. :key="j"
  108. :class="[
  109. 'tone',
  110. data.property.answer_mode === 'select' &&
  111. con_preview[0].user_answer[con_preview[0].item_active_index] &&
  112. con_preview[0].user_answer[con_preview[0].item_active_index].select_tone === value
  113. ? 'active'
  114. : data.property.answer_mode === 'label' &&
  115. con_preview[0].user_answer[con_preview[0].item_active_index] &&
  116. con_preview[0].user_answer[con_preview[0].item_active_index].select_tone === value &&
  117. con_preview[0].user_answer[con_preview[0].item_active_index].select_letter === active_letter &&
  118. select_item_index === 0
  119. ? 'active'
  120. : '',
  121. (isJudgingRightWrong &&
  122. con_preview[0].user_answer[con_preview[0].item_active_index].right_answer === value &&
  123. con_preview[0].user_answer[con_preview[0].item_active_index].select_index_submit !==
  124. con_preview[0].user_answer[con_preview[0].item_active_index].right_answer &&
  125. data.property.answer_mode === 'select') ||
  126. (isJudgingRightWrong &&
  127. data.property.answer_mode === 'label' &&
  128. con_preview[0].user_answer[con_preview[0].item_active_index].right_answer === value &&
  129. con_preview[0].user_answer[con_preview[0].item_active_index].right_index ===
  130. con_preview[0].user_answer[con_preview[0].item_active_index].select_index &&
  131. select_item_index === 0)
  132. ? 'right'
  133. : '',
  134. ]"
  135. @click="chooseTone(con_preview[0], value)"
  136. >
  137. <SvgIcon :icon-class="img" />
  138. </span>
  139. </div>
  140. <template v-else-if="data.property.fun_type !== 'mark' && isEnable(data.property.is_enable_voice_answer)">
  141. <SoundRecord
  142. ref="record"
  143. type="normal"
  144. class="record-box"
  145. :answer-record-list="answer.answer_list[0].record_list"
  146. :task-model="isJudgingRightWrong ? 'ANSWER' : ''"
  147. :attrib="data.unified_attrib"
  148. @handleWav="handleWav"
  149. />
  150. </template>
  151. </div>
  152. <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" @retry="retry" />
  153. <AnswerCorrect
  154. :answer-correct="data?.answer_correct"
  155. :visible.sync="visibleAnswerCorrect"
  156. @closeAnswerCorrect="closeAnswerCorrect"
  157. />
  158. <AnswerAnalysis
  159. :visible.sync="visibleAnswerAnalysis"
  160. :answer-list="data.answer_list"
  161. :analysis-list="data.analysis_list"
  162. @closeAnswerAnalysis="closeAnswerAnalysis"
  163. >
  164. <div v-if="data.property.fun_type === 'input'" slot="right-answer" class="right-answer">
  165. <div
  166. class="content-box"
  167. :class="[data.property.arrange_type === 'horizontal' ? 'content-box-flex' : 'content-box-vertical']"
  168. >
  169. <div class="first-con">
  170. <AudioPlay
  171. v-if="data.audio_file_id && data.property.audio_position === 'front'"
  172. :file-id="data.audio_file_url"
  173. :theme-color="
  174. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
  175. "
  176. />
  177. <div
  178. class="option-content"
  179. :style="{
  180. fontSize: data.unified_attrib && data.unified_attrib.font_size ? data.unified_attrib.font_size : '',
  181. }"
  182. >
  183. <span v-if="data.content_hz" class="items-hz">{{ convertText(data.content_hz) }}</span>
  184. <!-- 拼音输入 -->
  185. <template v-if="data.property.fun_type === 'input'">
  186. <span
  187. v-for="(itemc, indexc) in con_preview"
  188. :key="indexc"
  189. :class="['item-con', itemc.type === 'input' ? 'right' : '']"
  190. >
  191. <el-input
  192. v-if="itemc.type === 'input'"
  193. v-model="itemc.answer"
  194. :disabled="true"
  195. :style="[{ width: Math.max(20, itemc.con.length * 10) + 'px' }]"
  196. class="item-input"
  197. />
  198. <span v-else>{{ itemc.con }}</span>
  199. </span>
  200. </template>
  201. </div>
  202. <AudioPlay
  203. v-if="data.audio_file_id && data.property.audio_position === 'back'"
  204. :file-id="data.audio_file_url"
  205. />
  206. </div>
  207. </div>
  208. </div>
  209. </AnswerAnalysis>
  210. </div>
  211. </div>
  212. </template>
  213. <script>
  214. import { getPinyinBaseData, arrangeTypeList, audioPositionList } from '@/views/book/courseware/data/pinyinBase';
  215. import PreviewMixin from '../common/PreviewMixin';
  216. import AudioPlay from '../character_base/components/AudioPlay.vue';
  217. import SoundRecord from '../../common/SoundRecord.vue';
  218. import { addTone, handleToneValue } from '@/utils/common';
  219. export default {
  220. name: 'PinyinBasePreview',
  221. components: {
  222. AudioPlay,
  223. SoundRecord,
  224. },
  225. mixins: [PreviewMixin],
  226. data() {
  227. return {
  228. data: getPinyinBaseData(),
  229. arrangeTypeList,
  230. audioPositionList,
  231. toneList: [
  232. { value: '1', label: '一声', img: 'first-tone' },
  233. { value: '2', label: '二声', img: 'second-tone' },
  234. { value: '3', label: '三声', img: 'third-tone' },
  235. { value: '4', label: '四声', img: 'fourth-tone' },
  236. // { value: '0', label: '轻声', img: 'neutral-tone' },
  237. ],
  238. con_preview: [],
  239. tone_data: [
  240. ['ā', 'á', 'ǎ', 'à', 'a'],
  241. ['ō', 'ó', 'ǒ', 'ò', 'o'],
  242. ['ē', 'é', 'ě', 'è', 'e'],
  243. ['ī', 'í', 'ǐ', 'ì', 'i'],
  244. ['ū', 'ú', 'ǔ', 'ù', 'u'],
  245. ['ǖ', 'ǘ', 'ǚ', 'ǜ', 'ü'],
  246. ['ǖ', 'ǘ', 'ǚ', 'ǜ', 'ü'],
  247. ['Ā', 'Á', 'Â', 'À', 'A'],
  248. ['Ō', 'Ó', 'Ô', 'Ò', 'O'],
  249. ['Ē', 'É', 'Ê', 'È', 'E'],
  250. ['Ī', 'Í', 'Î', 'Ì', 'I'],
  251. ['Ū', 'Ú', 'Û', 'Ù', 'U'],
  252. ['n', 'ń', 'ň', 'ǹ', 'n'],
  253. ['m̄', 'ḿ', 'm', 'm̀', 'm'],
  254. ],
  255. final_con: '',
  256. active_index_str: '', // 高亮索引的字符串
  257. active_letter: '', // 选中字母的值
  258. active_letter_index: 0, // 选择字母索引
  259. select_item_index: 0, // 小题索引
  260. };
  261. },
  262. watch: {
  263. data: {
  264. handler(val) {
  265. // if (!val || this.data.type !== 'choose_tone') return;
  266. this.handleData();
  267. },
  268. deep: true,
  269. immediate: true,
  270. },
  271. isJudgingRightWrong: {
  272. handler(val) {
  273. if (!val) return;
  274. this.judgeRight();
  275. this.$forceUpdate();
  276. },
  277. immediate: true,
  278. },
  279. 'answer.answer_list'(val) {
  280. this.answer.answer_list = val;
  281. },
  282. },
  283. created() {
  284. // console.log(this.data);
  285. },
  286. methods: {
  287. chooseTone(item, value) {
  288. if (this.disabled) return;
  289. if (!this.active_letter && this.data.property.answer_mode === 'label') return;
  290. if (
  291. item.user_answer[item.item_active_index].select_tone &&
  292. item.user_answer[item.item_active_index].select_tone === value &&
  293. this.data.property.answer_mode === 'label' &&
  294. item.user_answer[item.item_active_index].select_letter === this.active_letter
  295. ) {
  296. item.user_answer[item.item_active_index].select_tone = '';
  297. this.handleReplaceTone(this.active_letter + 0);
  298. setTimeout(() => {
  299. let new_con = item.item_con_yuan[item.item_active_index].split(this.active_letter);
  300. item.item_con[item.item_active_index] = new_con[0] + this.final_con + new_con[1];
  301. this.$forceUpdate();
  302. this.answer.answer_list[0].value[item.item_active_index] = new_con[0] + this.active_letter + new_con[1];
  303. }, 100);
  304. } else if (
  305. item.user_answer[item.item_active_index].select_tone &&
  306. item.user_answer[item.item_active_index].select_tone === value &&
  307. this.data.property.answer_mode === 'select'
  308. ) {
  309. item.user_answer[item.item_active_index].select_tone = '';
  310. this.handleReplaceTone(item.item_con_yuan[item.item_active_index] + 0);
  311. setTimeout(() => {
  312. item.item_con[item.item_active_index] = this.final_con;
  313. this.$forceUpdate();
  314. }, 100);
  315. this.answer.answer_list[0].value[item.item_active_index] = '';
  316. } else {
  317. item.user_answer[item.item_active_index].select_tone = value;
  318. if (this.data.property.answer_mode === 'label') {
  319. item.user_answer[item.item_active_index].select_letter = this.active_letter;
  320. this.active_index_str = `${0}-${item.item_active_index}-${this.active_letter_index}`;
  321. this.handleReplaceTone(this.active_letter + value);
  322. setTimeout(() => {
  323. let new_con = item.item_con_yuan[item.item_active_index].split(this.active_letter);
  324. item.item_con[item.item_active_index] = new_con[0] + this.final_con + new_con[1];
  325. this.$forceUpdate();
  326. this.answer.answer_list[0].value[item.item_active_index] =
  327. new_con[0] + this.active_letter + value + new_con[1];
  328. }, 100);
  329. } else {
  330. this.active_index_str = `${0}-${item.item_active_index}`;
  331. this.handleReplaceTone(item.item_con_yuan[item.item_active_index] + value);
  332. setTimeout(() => {
  333. item.item_con[item.item_active_index] = this.final_con;
  334. this.$forceUpdate();
  335. }, 100);
  336. this.answer.answer_list[0].value[item.item_active_index] = value;
  337. }
  338. }
  339. },
  340. // 处理数据
  341. handleData() {
  342. this.con_preview = [];
  343. this.show_preview = false;
  344. if (!this.isJudgingRightWrong) {
  345. this.answer.answer_list = [];
  346. }
  347. if (this.data.property.fun_type === 'input') {
  348. let arr = this.data.matically_pinyin_str[this.data.mark].split(/_{3,}/g);
  349. let inputIndex = 0;
  350. arr.forEach((item, index) => {
  351. let obj = {
  352. con: item,
  353. type: 'text',
  354. };
  355. this.con_preview.push(obj);
  356. if (index !== arr.length - 1) {
  357. let objs = {
  358. con: '',
  359. type: 'input',
  360. inputIndex,
  361. answer: this.data.answer.answer_list[inputIndex] ? this.data.answer.answer_list[inputIndex].con : '',
  362. };
  363. this.con_preview.push(JSON.parse(JSON.stringify(objs)));
  364. inputIndex++;
  365. }
  366. });
  367. if (!this.isJudgingRightWrong) {
  368. let obj = {
  369. mark: this.data.mark,
  370. value: this.con_preview,
  371. record_list: [],
  372. };
  373. this.answer.answer_list.push(obj);
  374. }
  375. } else {
  376. // this.data.option_list.forEach((item) => {
  377. let con_arr = JSON.parse(JSON.stringify(this.data.content_view));
  378. let user_answer = [];
  379. let user_submit = []; // 用户提交答案
  380. con_arr.forEach((items) => {
  381. user_answer.push({
  382. select_tone: null,
  383. select_letter: '',
  384. select_index: '',
  385. });
  386. user_submit.push(this.data.property.answer_mode === 'label' ? items : '');
  387. });
  388. let obj = {
  389. item_con: con_arr,
  390. item_con_yuan: JSON.parse(JSON.stringify(con_arr)),
  391. mark: this.data.mark,
  392. user_answer,
  393. item_active_index: 0,
  394. active_letter: '',
  395. };
  396. if (!this.isJudgingRightWrong) {
  397. let obj = {
  398. mark: this.data.mark,
  399. value: user_submit,
  400. record_list: [],
  401. };
  402. this.answer.answer_list.push(obj);
  403. }
  404. this.con_preview.push(obj);
  405. // });
  406. }
  407. this.show_preview = true;
  408. },
  409. handleReplaceTone(e, arr, index, resArr) {
  410. this.$nextTick(() => {
  411. let value = e;
  412. this.resArr = [];
  413. if (value) {
  414. let reg = /\s+/g;
  415. let valueArr = value.split(reg);
  416. valueArr.forEach((item) => {
  417. this.handleValue(item, resArr);
  418. });
  419. let str = '';
  420. setTimeout(() => {
  421. if (resArr) {
  422. resArr.forEach((item) => {
  423. str += ' ';
  424. item.forEach((sItem) => {
  425. if (sItem.number && sItem.con) {
  426. let number = Number(sItem.number);
  427. let con = sItem.con;
  428. let word = this.addTone(number, con);
  429. str += word;
  430. } else if (sItem.number) {
  431. str += sItem.number;
  432. } else if (sItem.con) {
  433. str += ` ${sItem.con} `;
  434. }
  435. });
  436. });
  437. if (this.data.property.answer_mode === 'label') {
  438. let number_index = e.search(/0|1|2|3|4/) + 1;
  439. arr[index] = str.trim() + (number_index === 0 ? '' : e.substring(number_index));
  440. } else {
  441. arr[index] = str.trim();
  442. }
  443. } else {
  444. this.resArr.forEach((item) => {
  445. str += ' ';
  446. item.forEach((sItem) => {
  447. if (sItem.number && sItem.con) {
  448. let number = Number(sItem.number);
  449. let con = sItem.con;
  450. let word = this.addTone(number, con);
  451. str += word;
  452. } else if (sItem.number) {
  453. str += sItem.number;
  454. } else if (sItem.con) {
  455. str += ` ${sItem.con} `;
  456. }
  457. });
  458. });
  459. this.final_con = str.trim();
  460. }
  461. }, 10);
  462. }
  463. });
  464. },
  465. handleValue(valItem, resArr) {
  466. let reg = /\d/;
  467. let reg2 = /[A-Za-zü]+\d/g;
  468. let numList = [];
  469. let valArr = valItem.split('');
  470. if (reg2.test(valItem)) {
  471. for (let i = 0; i < valArr.length; i++) {
  472. let item = valItem[i];
  473. if (reg.test(item)) {
  474. let numIndex = numList.length === 0 ? 0 : numList[numList.length - 1].index;
  475. let con = valItem.substring(numIndex, i);
  476. con = con.replace(/\d/g, '');
  477. let obj = {
  478. index: i,
  479. number: item,
  480. con,
  481. isTran: true,
  482. };
  483. numList.push(obj);
  484. }
  485. }
  486. } else {
  487. numList = [];
  488. }
  489. if (resArr) {
  490. if (numList.length === 0) {
  491. resArr.push([{ con: valItem }]);
  492. } else {
  493. resArr.push(numList);
  494. }
  495. } else if (numList.length === 0) {
  496. this.resArr.push([{ con: valItem }]);
  497. } else {
  498. this.resArr.push(numList);
  499. }
  500. },
  501. addTone(number, con) {
  502. let zmList = ['a', 'o', 'e', 'i', 'u', 'v', 'ü', 'A', 'O', 'E', 'I', 'U', 'n', 'm'];
  503. let cons = con;
  504. if (number) {
  505. for (let i = 0; i < zmList.length; i++) {
  506. let zm = zmList[i];
  507. if (con.indexOf(zm) > -1) {
  508. let zm2 = this.tone_data[i][number - 1];
  509. if (con.indexOf('iu') > -1) {
  510. zm2 = this.tone_data[4][number - 1];
  511. cons = con.replace('u', zm2);
  512. } else if (con.indexOf('ui') > -1) {
  513. zm2 = this.tone_data[3][number - 1];
  514. cons = con.replace('i', zm2);
  515. } else if (
  516. con.indexOf('yv') > -1 ||
  517. con.indexOf('jv') > -1 ||
  518. con.indexOf('qv') > -1 ||
  519. con.indexOf('xv') > -1
  520. ) {
  521. zm2 = this.tone_data[4][number - 1];
  522. cons = con.replace('v', zm2);
  523. } else {
  524. cons = con.replace(zm, zm2);
  525. }
  526. break;
  527. }
  528. }
  529. }
  530. return cons;
  531. },
  532. handleSelectItemTone(i, indexc, indexi, itemi) {
  533. if (this.data.property.fun_type === 'show') {
  534. return;
  535. }
  536. this.con_preview[0].item_active_index = indexc;
  537. this.con_preview[0].user_answer[indexc].select_index = indexi;
  538. this.active_index_str = `${i}-${indexc}-${indexi}`;
  539. this.active_letter = itemi;
  540. this.active_letter_index = indexi;
  541. this.select_item_index = i;
  542. },
  543. // 判断对错
  544. judgeRight() {
  545. this.show_preview = false;
  546. let answer_list_item = this.answer.answer_list.filter((items) => this.data.mark === items.mark);
  547. if (this.data.property.fun_type === 'input') {
  548. this.con_preview.forEach((items, indexs) => {
  549. if (items.type === 'input') {
  550. let is_right = items.answer
  551. ? answer_list_item[0].value[indexs].con === items.answer
  552. ? 'right'
  553. : 'error'
  554. : '';
  555. this.$set(items, 'is_right', is_right);
  556. }
  557. });
  558. } else {
  559. this.con_preview = [];
  560. let con_arr = JSON.parse(JSON.stringify(this.data.content_view));
  561. let user_answer = [];
  562. let user_select = [];
  563. let user_res_arr = [];
  564. con_arr.forEach((items, indexs) => {
  565. user_answer.push({
  566. select_tone: answer_list_item[0].value[indexs],
  567. select_letter: '',
  568. select_index: '',
  569. is_right:
  570. this.data.answer.answer_list[0] &&
  571. this.data.answer.answer_list[0].value &&
  572. this.data.answer.answer_list[0].value[indexs] &&
  573. answer_list_item[0].value[indexs] === this.data.answer.answer_list[0].value[indexs],
  574. right_answer:
  575. this.data.answer.answer_list[0] &&
  576. this.data.answer.answer_list[0].value &&
  577. this.data.answer.answer_list[0].value[indexs]
  578. ? this.data.answer.answer_list[0].value[indexs]
  579. : null,
  580. });
  581. user_res_arr.push([]);
  582. user_select.push('');
  583. if (this.data.property.fun_type === 'mark') {
  584. if (this.data.property.answer_mode === 'label') {
  585. this.handleReplaceTone(answer_list_item[0].value[indexs], user_select, indexs, user_res_arr[indexs]);
  586. if (
  587. answer_list_item[0].value[indexs].match(/\d+/g) &&
  588. answer_list_item[0].value[indexs].match(/\d+/g).length > 0
  589. ) {
  590. user_answer[indexs].select_tone = answer_list_item[0].value[indexs].match(/\d+/g)[0];
  591. let letter_number = answer_list_item[0].value[indexs].match(/\d+/g)[0];
  592. let letter_index = answer_list_item[0].value[indexs].indexOf(letter_number) - 1;
  593. user_answer[indexs].select_letter = answer_list_item[0].value[indexs].substring(
  594. letter_index,
  595. letter_index + 1,
  596. );
  597. user_answer[indexs].select_index_submit = letter_index;
  598. } else {
  599. user_select[indexs] = items;
  600. }
  601. user_answer[indexs].right_answer = this.data.answer.answer_list[0].value[indexs].match(/0|1|2|3|4/)
  602. ? this.data.answer.answer_list[0].value[indexs].match(/0|1|2|3|4/)[0]
  603. : '';
  604. user_answer[indexs].right_index = this.data.answer.answer_list[0].value[indexs].search(/0|1|2|3|4/) - 1;
  605. } else {
  606. this.handleReplaceTone(
  607. items + answer_list_item[0].value[indexs],
  608. user_select,
  609. indexs,
  610. user_res_arr[indexs],
  611. );
  612. user_select[indexs] = items;
  613. }
  614. } else if (this.data.property.fun_type === 'input') {
  615. }
  616. });
  617. let obj = {
  618. item_con: user_select,
  619. item_con_yuan: JSON.parse(JSON.stringify(con_arr)),
  620. mark: this.data.mark,
  621. user_answer,
  622. item_active_index: 0,
  623. active_letter: '',
  624. user_res_arr,
  625. all_right:
  626. JSON.stringify(answer_list_item[0].value) === JSON.stringify(this.data.answer.answer_list[0].value),
  627. };
  628. this.con_preview.push(obj);
  629. }
  630. setTimeout(() => {
  631. this.show_preview = true;
  632. }, 100);
  633. },
  634. handleWav(data) {
  635. this.answer.answer_list[0].record_list = data;
  636. },
  637. onInputChange(item) {
  638. let answer = item.con;
  639. answer = answer
  640. .trim()
  641. .split(/\s+/)
  642. .map((item) => {
  643. return handleToneValue(item);
  644. })
  645. .map((item) =>
  646. item.map(({ number, con }) => (number && con ? addTone(Number(number), con) : number || con || '')),
  647. )
  648. .filter((item) => item.length > 0)
  649. .join(' ');
  650. item.con = answer;
  651. },
  652. // 重做
  653. retry() {
  654. this.handleData();
  655. if (this.data.property.fun_type !== 'mark' && this.isEnable(this.data.property.is_enable_voice_answer)) {
  656. this.$refs.record.handleReset();
  657. }
  658. },
  659. },
  660. };
  661. </script>
  662. <style lang="scss" scoped>
  663. @use '@/styles/mixin.scss' as *;
  664. .pinyin-preview {
  665. @include preview-base;
  666. .content-box {
  667. &-flex {
  668. display: flex;
  669. flex-wrap: wrap;
  670. column-gap: 8px;
  671. align-items: center;
  672. }
  673. &-vertical {
  674. .tone-box,
  675. .record-box {
  676. margin-top: 8px;
  677. }
  678. }
  679. }
  680. .first-con {
  681. display: flex;
  682. column-gap: 8px;
  683. align-items: center;
  684. }
  685. .option-content {
  686. padding: 5px 15px;
  687. color: #706f78;
  688. background-color: $content-color;
  689. border: 1px solid $content-color;
  690. border-radius: 4px;
  691. &.all-right {
  692. background-color: $right-bc-color;
  693. border-color: $right-bc-color;
  694. }
  695. &.has-error {
  696. border-color: $error-color;
  697. }
  698. }
  699. .items-hz {
  700. margin-right: 4px;
  701. font-size: 16px;
  702. // font-weight: 500;
  703. line-height: 24px;
  704. color: #000;
  705. }
  706. .item-con,
  707. .items-con {
  708. font-family: 'League';
  709. // font-weight: 500;
  710. color: #000;
  711. cursor: pointer;
  712. &.right {
  713. color: $right-color;
  714. :deep .el-input__inner {
  715. color: $right-color;
  716. border-bottom-color: $right-color;
  717. }
  718. }
  719. &.error {
  720. color: $error-color;
  721. :deep .el-input__inner {
  722. color: $error-color;
  723. border-bottom-color: $error-color;
  724. }
  725. }
  726. &.active {
  727. color: #2f6fec;
  728. }
  729. }
  730. .item-con-in {
  731. cursor: initial;
  732. }
  733. .tone-box {
  734. display: flex;
  735. column-gap: 8px;
  736. }
  737. .tone {
  738. width: 32px;
  739. height: 32px;
  740. padding: 8px;
  741. font-size: 0;
  742. color: #9f9f9f;
  743. text-align: center;
  744. cursor: pointer;
  745. &.right {
  746. color: $right-color;
  747. background-color: $right-bc-color;
  748. border-radius: 16px;
  749. }
  750. &.active {
  751. color: #2f6fec;
  752. background: #dfe9fd;
  753. border-radius: 16px;
  754. }
  755. }
  756. .record-box {
  757. padding: 7px 12px;
  758. background: #f2f3f5;
  759. border-radius: 2px;
  760. }
  761. .item-input {
  762. :deep .el-input__inner {
  763. padding: 0;
  764. font-family: 'League';
  765. font-size: 16px;
  766. color: #1d2129;
  767. text-align: center;
  768. background-color: transparent;
  769. border-width: 0;
  770. border-bottom: 1px solid #1d2129;
  771. border-radius: 0;
  772. }
  773. }
  774. }
  775. </style>