PinyinBasePreview.vue 27 KB

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