CharacterPreview.vue 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977
  1. <!-- eslint-disable vue/no-v-html -->
  2. <template>
  3. <div class="character-preview" :style="[getAreaStyle(), getComponentStyle()]">
  4. <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
  5. <div class="main">
  6. <template v-if="data.property.model === 'write'">
  7. <div
  8. v-for="(item, index) in data.option_list"
  9. :key="index"
  10. class="item-box"
  11. :class="[!item.is_margin ? 'item-box-write' : '']"
  12. >
  13. <div
  14. class="number-box"
  15. :class="['number-box-' + data.property.frame_size]"
  16. :style="{
  17. marginTop: isEnable(data.property.view_pinyin) ? '30px' : '',
  18. }"
  19. >
  20. <span
  21. class="number"
  22. :style="{
  23. background:
  24. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '',
  25. }"
  26. >{{ index + 1 }}</span
  27. >
  28. </div>
  29. <div class="pinyin-en" :class="[item.is_example ? 'item-example' : '']">
  30. <div
  31. v-if="isEnable(data.property.view_pinyin) && item.is_common_pinyin"
  32. class="pinyin"
  33. :style="{
  34. fontSize: data.unified_attrib && data.unified_attrib.pinyin_size ? data.unified_attrib.pinyin_size : '',
  35. }"
  36. >
  37. {{ item.pinyin }}
  38. </div>
  39. <div class="items-flex">
  40. <div v-for="(items, indexs) in item.content_list" :key="indexs" class="items">
  41. <div
  42. v-if="isEnable(data.property.view_pinyin) && !item.is_common_pinyin"
  43. class="pinyin"
  44. :style="{
  45. fontSize:
  46. data.unified_attrib && data.unified_attrib.pinyin_size ? data.unified_attrib.pinyin_size : '',
  47. }"
  48. >
  49. {{ items.pinyin }}
  50. </div>
  51. <div class="items-content">
  52. <template v-if="items && items.type === 'img'">
  53. <el-image
  54. v-if="items.file_list[0]"
  55. class="items-image"
  56. :class="['frame-size-' + data.property.frame_size]"
  57. :src="items.file_list[0].file_url"
  58. fit="contain"
  59. :style="{
  60. borderColor:
  61. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '',
  62. }"
  63. />
  64. </template>
  65. <template v-else-if="items && items.type === 'lian'">
  66. <span
  67. class="items-lian"
  68. :class="['items-lian-' + data.property.frame_size]"
  69. :style="{
  70. color:
  71. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '',
  72. }"
  73. >{{ items.con }}</span
  74. >
  75. </template>
  76. <Strockplayredline
  77. v-if="items && items.type === 'hanzi'"
  78. :Book_text="items.con"
  79. :play-storkes="isEnable(data.property.is_enable_play_structure)"
  80. :cur-item="
  81. isEnable(data.property.is_enable_high_strokes)
  82. ? data.property.model === 'input'
  83. ? items.high_strokes
  84. : userAnswer[index].item[indexs]
  85. : null
  86. "
  87. :type="data.property.model === 'input' ? 'newWord-template-input' : data.type"
  88. :target-div="'newWordTemplate-character' + items.con + index + indexs + randomId"
  89. :hz_json="items.hz_info[0].hzDetail.hz_json"
  90. :bg-type="data.property.frame_type"
  91. class="hanzi-storck"
  92. :class="[
  93. !item.is_margin && item.content_list.length > 1 && indexs == 0 ? 'leftBorderRadius' : '',
  94. !item.is_margin && item.content_list.length > 1 && indexs == item.content_list.length - 1
  95. ? 'rightBorderRadius'
  96. : '',
  97. !item.is_margin &&
  98. item.content_list.length > 1 &&
  99. indexs != item.content_list.length - 1 &&
  100. indexs != 0
  101. ? 'NoborderRadius'
  102. : '',
  103. !item.is_margin &&
  104. item.content_list.length > 1 &&
  105. indexs != item.content_list.length - 1 &&
  106. item.content_list[indexs + 1].type !== 'lian'
  107. ? 'NoborderRight'
  108. : '',
  109. 'frame-size-' + data.property.frame_size,
  110. ]"
  111. :play-color="
  112. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
  113. "
  114. :style="{
  115. borderColor:
  116. data.unified_attrib && data.unified_attrib.topic_color
  117. ? data.unified_attrib.topic_color
  118. : '#346cda',
  119. }"
  120. />
  121. <div
  122. v-if="items && items.type === 'write'"
  123. :class="[
  124. 'strockplay-newWord',
  125. !item.is_margin && item.content_list.length > 1 && indexs == 0 ? 'leftBorderRadius' : '',
  126. !item.is_margin && item.content_list.length > 1 && indexs == item.content_list.length - 1
  127. ? 'rightBorderRadius'
  128. : '',
  129. !item.is_margin &&
  130. item.content_list.length > 1 &&
  131. indexs != item.content_list.length - 1 &&
  132. indexs != 0
  133. ? 'NoborderRadius'
  134. : '',
  135. !item.is_margin &&
  136. item.content_list.length > 1 &&
  137. indexs != item.content_list.length - 1 &&
  138. item.content_list[indexs + 1].type !== 'lian'
  139. ? 'NoborderRight'
  140. : '',
  141. 'frame-size-' + data.property.frame_size,
  142. ]"
  143. :style="{
  144. borderColor:
  145. data.unified_attrib && data.unified_attrib.topic_color
  146. ? data.unified_attrib.topic_color
  147. : '#346cda',
  148. }"
  149. @click="
  150. freeWrite(
  151. userAnswer[index][indexs].imgArr ? userAnswer[index][indexs].imgArr : null,
  152. index,
  153. indexs,
  154. )
  155. "
  156. >
  157. <SvgIcon
  158. v-if="data.property.frame_type === 'tian'"
  159. icon-class="hanzi-writer-bg"
  160. class="character-target-bg"
  161. />
  162. <SvgIcon
  163. v-else-if="data.property.frame_type === 'mi'"
  164. icon-class="mi"
  165. class="character-target-bg"
  166. />
  167. <img
  168. v-if="
  169. !play_status &&
  170. userAnswer[index][indexs].imgArr &&
  171. userAnswer[index][indexs].imgArr.strokes_image
  172. "
  173. class="hanzi-writer-img"
  174. :src="userAnswer[index][indexs].imgArr.strokes_image"
  175. alt=""
  176. />
  177. </div>
  178. </div>
  179. </div>
  180. </div>
  181. <div class="en-common">{{ convertText(item.shiyi) }}</div>
  182. </div>
  183. </div>
  184. </template>
  185. <template v-else>
  186. <div :class="['words-box']">
  187. <div v-for="(item, index) in data.option_list" :key="index" :class="['words-item']">
  188. <div class="words-top">
  189. <div class="words-left" :style="{}">
  190. <AudioPlay
  191. v-if="isEnable(data.property.is_enable_voice)"
  192. :file-id="
  193. item.audio_file_id
  194. ? item.audio_file_id.file_url
  195. ? item.audio_file_id.file_url
  196. : item.audio_file_id
  197. : ''
  198. "
  199. :theme-color="
  200. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
  201. "
  202. />
  203. <span
  204. v-if="isEnable(data.property.view_pinyin) && item.is_common_pinyin"
  205. class="pinyin"
  206. :style="{
  207. fontSize:
  208. data.unified_attrib && data.unified_attrib.pinyin_size ? data.unified_attrib.pinyin_size : '',
  209. }"
  210. >{{ item.pinyin }}</span
  211. >
  212. </div>
  213. </div>
  214. <div class="card-box">
  215. <!-- 描红 -->
  216. <template v-for="(items, indexs) in item.content_list">
  217. <div v-if="item.is_show_ben" :key="'miao' + indexs">
  218. <!-- <div v-if="isEnable(data.property.view_pinyin) && !item.is_common_pinyin" class="pinyin">
  219. {{ items.pinyin }}
  220. </div> -->
  221. <Strockplayredline
  222. :Book_text="items.con"
  223. :play-storkes="isEnable(data.property.is_enable_stroke)"
  224. :cur-item="null"
  225. :target-div="'newWordTemplate-character-answer' + items.con + index + indexs + randomId"
  226. :hz_json="
  227. items.hz_info && items.hz_info[0].hzDetail.hz_json ? items.hz_info[0].hzDetail.hz_json : []
  228. "
  229. class="hanzi-storck"
  230. :class="['strock-chinese', 'border-right-none', 'frame-size-' + data.property.frame_size]"
  231. :bg-type="data.property.frame_type"
  232. :play-color="
  233. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
  234. "
  235. :style="{
  236. borderColor:
  237. data.unified_attrib && data.unified_attrib.topic_color
  238. ? data.unified_attrib.topic_color
  239. : '#346cda',
  240. }"
  241. />
  242. </div>
  243. </template>
  244. <div
  245. v-for="(itemI, indexI) in item.miao_arr"
  246. :key="indexI + index"
  247. style="display: flex"
  248. :style="{
  249. borderColor:
  250. data.unified_attrib && data.unified_attrib.topic_color
  251. ? data.unified_attrib.topic_color
  252. : '#346cda',
  253. }"
  254. @click="miaoStorkes(index, indexI, item.mark, item.content, itemI.strokes)"
  255. >
  256. <Strockplayredlines
  257. v-if="
  258. userAnswer[index].strokes_content_list[indexI] &&
  259. userAnswer[index].strokes_content_list[indexI].flag === 'true'
  260. "
  261. :play-storkes="false"
  262. :book-text="item.content"
  263. :target-div="'write-praT-1' + indexI + index + randomId"
  264. :book-strokes="itemI.strokes"
  265. :class="['strock-chinese', 'frame-size-' + data.property.frame_size]"
  266. :bg-type="data.property.frame_type"
  267. :play-color="
  268. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
  269. "
  270. :style="{
  271. borderColor:
  272. data.unified_attrib && data.unified_attrib.topic_color
  273. ? data.unified_attrib.topic_color
  274. : '#346cda',
  275. }"
  276. />
  277. <Strockplayredlines
  278. v-else
  279. :play-storkes="false"
  280. :book-text="item.content"
  281. :target-div="'write-praT-2' + indexI + index + randomId"
  282. :book-strokes="itemI.strokes"
  283. :stroke-color="'#ddd'"
  284. :class="['strock-chinese', 'frame-size-' + data.property.frame_size]"
  285. :bg-type="data.property.frame_type"
  286. :play-color="
  287. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
  288. "
  289. :style="{
  290. borderColor:
  291. data.unified_attrib && data.unified_attrib.topic_color
  292. ? data.unified_attrib.topic_color
  293. : '#346cda',
  294. }"
  295. />
  296. </div>
  297. <!-- 书写 -->
  298. <div v-for="(items, indexs) in item.imgArr" :key="'write' + indexs" class="con-box">
  299. <div
  300. :class="['strockplay-newWord', 'frame-size-' + data.property.frame_size]"
  301. :style="{
  302. borderColor:
  303. data.unified_attrib && data.unified_attrib.topic_color
  304. ? data.unified_attrib.topic_color
  305. : '#346cda',
  306. }"
  307. @click="
  308. freeWrite(
  309. userAnswer[index].strokes_content_list[indexs].imgArr
  310. ? userAnswer[index].strokes_content_list[indexs].imgArr
  311. : null,
  312. index,
  313. indexs,
  314. )
  315. "
  316. >
  317. <SvgIcon
  318. v-if="data.property.frame_type === 'tian'"
  319. icon-class="hanzi-writer-bg"
  320. class="character-target-bg"
  321. />
  322. <SvgIcon v-else-if="data.property.frame_type === 'mi'" icon-class="mi" class="character-target-bg" />
  323. <img
  324. v-if="
  325. !play_status &&
  326. items &&
  327. userAnswer[index].strokes_content_list[indexs].imgArr &&
  328. userAnswer[index].strokes_content_list[indexs].imgArr.strokes_image
  329. "
  330. class="hanzi-writer-img"
  331. :src="userAnswer[index].strokes_content_list[indexs].imgArr.strokes_image"
  332. alt=""
  333. />
  334. </div>
  335. </div>
  336. </div>
  337. <div v-if="item.shiyi && isEnable(data.property.is_enable_shiyi)" class="words-bottom">
  338. {{ convertText(item.shiyi) }}
  339. </div>
  340. </div>
  341. </div>
  342. </template>
  343. <div v-if="if_free_show" class="practiceBox practice-box-strock">
  344. <FreewriteLettle
  345. ref="freePaint"
  346. :current-tree-i-d="'1234456'"
  347. :current-hz="current_hz"
  348. :curren-hz-data="current_hz_data"
  349. :row-index="active_index"
  350. :col-index="active_col_index"
  351. :disabled="disabled"
  352. :show-play="isEnable(data.property.is_enable_play_back)"
  353. :bg-type="data.property.frame_type"
  354. :attrib="data.unified_attrib"
  355. @closeIfFreeShow="closeIfFreeShow"
  356. @changePraShow="changePraShow"
  357. @changeCurQue="changeCurQue"
  358. @deleteWriteRecord="deleteWriteRecord"
  359. />
  360. </div>
  361. <div v-if="if_miao_show" class="practiceBox practice-box-strock">
  362. <div class="miao-box">
  363. <i class="el-icon-close close-icon" @click="if_miao_show = false"></i>
  364. <Strockplayredlines
  365. v-if="
  366. (userAnswer[active_index].strokes_content_list[active_col_index].flag &&
  367. userAnswer[active_index].strokes_content_list[active_col_index].flag === 'true') ||
  368. disabled
  369. "
  370. :play-storkes="false"
  371. :book-text="current_hz"
  372. :target-div="'write-praT-3' + current_hz + active_col_index + active_index + randomId"
  373. :book-strokes="current_hz_data"
  374. :stroke-color="
  375. disabled &&
  376. (!userAnswer[active_index].strokes_content_list[active_col_index].flag ||
  377. (userAnswer[active_index].strokes_content_list[active_col_index].flag &&
  378. userAnswer[active_index].strokes_content_list[active_col_index].flag === 'false'))
  379. ? '#ddd'
  380. : ''
  381. "
  382. :bg-type="data.property.frame_type"
  383. :play-color="data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''"
  384. />
  385. <Strockred
  386. ref="strockRed"
  387. :class="[
  388. 'strock-red',
  389. userAnswer[active_index].strokes_content_list[active_col_index].flag &&
  390. userAnswer[active_index].strokes_content_list[active_col_index].flag === 'true'
  391. ? 'strock-red-zindex'
  392. : '',
  393. ]"
  394. :book-text="current_hz"
  395. :hanzi-color="hanzi_color"
  396. :target-div="'write-praT' + current_hz + active_col_index + active_index + randomId"
  397. :book-strokes="current_hz_data"
  398. :is-answer.sync="userAnswer[active_index].strokes_content_list[active_col_index].flag"
  399. :show-error-tip="isEnable(data.property.is_enable_error)"
  400. :bg-type="data.property.frame_type"
  401. />
  402. <div v-if="!disabled" :class="['reset-box']" @click="resetHanzi">
  403. <SvgIcon icon-class="reset" class="reset-btn" />
  404. </div>
  405. </div>
  406. </div>
  407. <SoundRecord
  408. v-if="isEnable(data.property.is_enable_voice_answer)"
  409. ref="record"
  410. type="normal"
  411. class="record-box"
  412. :attrib="data.unified_attrib"
  413. :answer-record-list="data.record_list"
  414. :task-model="isJudgingRightWrong ? 'ANSWER' : ''"
  415. @handleWav="handleWav"
  416. />
  417. <PreviewOperation
  418. v-if="data.property.model === 'miao'"
  419. @showAnswerAnalysis="showAnswerAnalysis"
  420. @retry="retry"
  421. :isShowAnswer="isShowAnswers"
  422. />
  423. <AnswerCorrect
  424. :answer-correct="data?.answer_correct"
  425. :visible.sync="visibleAnswerCorrect"
  426. @closeAnswerCorrect="closeAnswerCorrect"
  427. />
  428. <AnswerAnalysis
  429. :visible.sync="visibleAnswerAnalysis"
  430. :answer-list="data.answer_list"
  431. :analysis-list="data.analysis_list"
  432. @closeAnswerAnalysis="closeAnswerAnalysis"
  433. />
  434. </div>
  435. </div>
  436. </template>
  437. <script>
  438. import { getCharacterData } from '@/views/book/courseware/data/character';
  439. import PreviewMixin from '../common/PreviewMixin';
  440. import AudioPlay from '../character_base/components/AudioPlay.vue';
  441. import Strockplayredline from '../newWord_template/components/Strockplayredline.vue';
  442. import Strockplayredlines from '../character_base/components/Strockplayredline.vue';
  443. import Strockred from '../character_base/components/Strockred.vue';
  444. import FreewriteLettle from '../character_base/components/FreewriteLettle.vue';
  445. import SoundRecord from '../../common/SoundRecord.vue';
  446. export default {
  447. name: 'CharacterPreview',
  448. components: {
  449. AudioPlay,
  450. Strockplayredline,
  451. Strockred,
  452. FreewriteLettle,
  453. Strockplayredlines,
  454. SoundRecord,
  455. },
  456. mixins: [PreviewMixin],
  457. data() {
  458. return {
  459. data: getCharacterData(),
  460. userAnswer: [],
  461. hanzi_color: '#404040', // 描红汉字底色
  462. writer_number_yuan: 15,
  463. writer_number: null, // 书写个数
  464. miao_number: null, // 描红个数
  465. if_free_show: false,
  466. free_img: [],
  467. active_index: null,
  468. active_col_index: null,
  469. current_hz: '', // 当前汉字
  470. current_hz_data: null, // 当前汉字数据
  471. play_status: false, // 播放状态
  472. active_mark: '',
  473. option_list: [],
  474. show_preview: false,
  475. miao_arr: [],
  476. if_miao_show: false, // 描红模块
  477. randomId: Math.random().toString(36).substring(2, 12),
  478. isShowAnswers: false,
  479. };
  480. },
  481. computed: {},
  482. watch: {
  483. 'data.option_list': {
  484. handler(val) {
  485. if (val) {
  486. this.handleData();
  487. }
  488. },
  489. deep: true,
  490. immediate: true,
  491. },
  492. isJudgingRightWrong(val) {
  493. if (!val) return;
  494. this.handleWav(this.answer.record_list);
  495. },
  496. 'data.record_list'(val) {
  497. this.answer.record_list = val;
  498. },
  499. },
  500. created() {
  501. if (
  502. (this.data.answer_list && this.data.answer_list.length > 0) ||
  503. (this.data.analysis_list && this.data.analysis_list.length > 0)
  504. ) {
  505. this.isShowAnswers = true;
  506. } else {
  507. this.isShowAnswers = false;
  508. }
  509. },
  510. methods: {
  511. handleWav(data) {
  512. this.data.record_list = data;
  513. },
  514. handleData() {
  515. let answer_list = [];
  516. this.data.option_list.forEach((item, index) => {
  517. if (this.data.property.model === 'write') {
  518. let arr = [];
  519. item.content_list.forEach((items) => {
  520. let obj = null;
  521. if (items.type === 'write') {
  522. obj = {
  523. imgArr: null,
  524. };
  525. }
  526. arr.push(obj);
  527. });
  528. answer_list.push(arr);
  529. } else {
  530. let miao_arr = [];
  531. let arr = [];
  532. if (item.content.trim()) {
  533. for (let i = 0; i < this.data.property.write_number; i++) {
  534. item.content_list.forEach((items) => {
  535. arr.push({ imgArr: null, flag: null });
  536. });
  537. }
  538. for (let i = 0; i < this.data.property.miao_number; i++) {
  539. item.content_list.forEach((items) => {
  540. miao_arr.push({
  541. strokes: items && items.hz_info && items.hz_info[0] ? items.hz_info[0].hzDetail.hz_json : null,
  542. length: item.content_list.length,
  543. });
  544. });
  545. }
  546. item.imgArr = arr;
  547. item.miao_arr = miao_arr;
  548. // if (this.isJudgingRightWrong) {
  549. // item.imgArr = this.userAnswer.find(
  550. // (items) => items.mark === item.mark,
  551. // )?.strokes_content_list;
  552. // }
  553. }
  554. let obj = {
  555. // mark: item.mark,
  556. strokes_content_list: arr,
  557. miao_arr,
  558. };
  559. // if (!this.isJudgingRightWrong) {
  560. // this.userAnswer.push(obj);
  561. // }
  562. answer_list.push(obj);
  563. }
  564. });
  565. this.userAnswer = answer_list;
  566. },
  567. changePraShow() {
  568. this.if_free_show = false;
  569. },
  570. closeIfFreeShow(data, rowIndex, colIndex, mark) {
  571. // this.option_list[rowIndex].imgArr[colIndex] = JSON.stringify(data);
  572. this.if_free_show = false;
  573. this.freeWrite(data, rowIndex, colIndex);
  574. this.$forceUpdate();
  575. },
  576. freeWrite(imgUrl, index, indexs) {
  577. this.if_free_show = true;
  578. this.active_index = index;
  579. this.active_col_index = indexs;
  580. this.current_hz =
  581. this.data.option_list[index] &&
  582. this.data.option_list[index].content_list[indexs] &&
  583. this.data.option_list[index].content_list[indexs].con
  584. ? this.data.option_list[index].content_list[indexs].con
  585. : '';
  586. this.current_hz_data = imgUrl;
  587. },
  588. // 删除记录
  589. deleteWriteRecord(rowIndex, colIndex) {
  590. this.$set(this.option_list[rowIndex].imgArr, colIndex, JSON.stringify({}));
  591. this.changeCurQue(null, rowIndex, colIndex);
  592. this.current_hz_data = null;
  593. this.active_mark = '';
  594. this.$forceUpdate();
  595. },
  596. changeCurQue(answer, rowIndex, colIndex) {
  597. if (answer) {
  598. if (this.data.property.model === 'write') {
  599. this.userAnswer[rowIndex][colIndex].imgArr = answer;
  600. } else {
  601. this.userAnswer[rowIndex].strokes_content_list[colIndex].imgArr = answer;
  602. }
  603. this.$forceUpdate();
  604. }
  605. },
  606. // 点击描红模块
  607. miaoStorkes(index, indexs, mark, content, storkes) {
  608. this.if_miao_show = true;
  609. this.active_index = index;
  610. this.active_col_index = indexs;
  611. this.current_hz = content;
  612. this.current_hz_data = storkes;
  613. },
  614. // 保存描红
  615. saveComplete(flag) {
  616. this.answer.answer_list[this.active_index].strokes_content_list[this.active_col_index] = flag;
  617. },
  618. resetHanzi() {
  619. this.$refs.strockRed.resetHanzi();
  620. },
  621. updateColor(color) {
  622. this.writer.updateColor('strokeColor', color);
  623. this.writer.updateColor('drawingColor', color);
  624. },
  625. // 重做
  626. retry() {
  627. this.handleData();
  628. this.handleWav([]);
  629. this.$refs.record.handleReset();
  630. },
  631. },
  632. };
  633. </script>
  634. <style lang="scss" scoped>
  635. @use '@/styles/mixin.scss' as *;
  636. .character-preview {
  637. @include preview-base;
  638. display: block;
  639. .main {
  640. display: flex;
  641. flex-wrap: wrap;
  642. column-gap: 16px;
  643. justify-content: start;
  644. }
  645. .content-box {
  646. width: max-content;
  647. }
  648. .audio-wrapper-nobg {
  649. height: 24px;
  650. :deep .audio-play {
  651. width: 24px;
  652. height: 24px;
  653. // color: #000;
  654. background-color: initial;
  655. }
  656. :deep .audio-play.not-url {
  657. color: #a1a1a1;
  658. }
  659. :deep .voice-play {
  660. width: 16px;
  661. height: 16px;
  662. }
  663. }
  664. .main-top {
  665. display: flex;
  666. column-gap: 4px;
  667. align-items: center;
  668. justify-content: center;
  669. }
  670. .pinyin {
  671. font-family: 'League';
  672. font-size: 12px;
  673. font-weight: 500;
  674. color: #000;
  675. }
  676. .strock-chinese-box {
  677. display: flex;
  678. flex-wrap: wrap;
  679. margin: 8px 0;
  680. }
  681. .strockplay-newWord {
  682. position: relative;
  683. box-sizing: border-box;
  684. flex-shrink: 0;
  685. width: 80px;
  686. height: 80px;
  687. border: 2px solid #346cda;
  688. border-radius: 4px;
  689. .character-target-bg,
  690. .hanzi-writer-img {
  691. position: absolute;
  692. top: 0;
  693. left: 0;
  694. width: 100%;
  695. height: 100%;
  696. color: #dedede;
  697. }
  698. .hanzi-writer-img {
  699. z-index: 1;
  700. }
  701. }
  702. .border-right-none {
  703. border-right: none;
  704. }
  705. .item-box {
  706. display: flex;
  707. gap: 5px;
  708. }
  709. .number-box {
  710. display: flex;
  711. align-items: center;
  712. height: 80px;
  713. margin-right: 16px;
  714. &-middle {
  715. height: 70px;
  716. }
  717. &-small {
  718. height: 60px;
  719. }
  720. .number {
  721. display: block;
  722. width: 24px;
  723. height: 24px;
  724. font-family: 'arial';
  725. font-size: 14px;
  726. font-weight: bold;
  727. line-height: 24px;
  728. color: #fff;
  729. text-align: center;
  730. background: #346cda;
  731. border-radius: 100%;
  732. }
  733. }
  734. .items {
  735. font-size: 0;
  736. }
  737. .pinyin {
  738. height: 30px;
  739. min-height: 16px;
  740. font-family: 'League';
  741. font-size: 20px;
  742. font-weight: 400;
  743. line-height: 30px;
  744. color: rgba(0, 0, 0, 50%);
  745. text-align: center;
  746. }
  747. .items-image,
  748. .hanzi-storck {
  749. width: 80px;
  750. height: 80px;
  751. overflow: hidden;
  752. border: 2px solid #346cda;
  753. border-radius: 4px;
  754. }
  755. .frame-size-middle {
  756. width: 70px !important;
  757. height: 70px !important;
  758. }
  759. .frame-size-small {
  760. width: 60px !important;
  761. height: 60px !important;
  762. }
  763. .items-lian {
  764. display: block;
  765. height: 80px;
  766. padding: 0 10px;
  767. font-size: 34px;
  768. line-height: 80px;
  769. color: #346cda;
  770. &-middle {
  771. height: 70px;
  772. line-height: 70px;
  773. }
  774. &-small {
  775. height: 60px;
  776. line-height: 60px;
  777. }
  778. }
  779. .items-flex {
  780. display: flex;
  781. gap: 5px;
  782. }
  783. .item-box-write {
  784. .items-flex {
  785. gap: 0;
  786. }
  787. .NoborderRadius {
  788. border-radius: 0;
  789. }
  790. .rightBorderRadius {
  791. border-radius: 0;
  792. border-top-right-radius: 4px;
  793. border-bottom-right-radius: 4px;
  794. }
  795. .leftBorderRadius {
  796. border-radius: 0;
  797. border-top-left-radius: 4px;
  798. border-bottom-left-radius: 4px;
  799. }
  800. .NoborderRight {
  801. border-right: none;
  802. }
  803. }
  804. .pinyin-common {
  805. margin-bottom: 5px;
  806. :deep .edit-div {
  807. font-family: 'League';
  808. }
  809. }
  810. .en-common {
  811. margin-top: 8px;
  812. // text-align: center;
  813. word-break: break-word;
  814. }
  815. .practiceBox {
  816. position: fixed;
  817. top: 0;
  818. left: 0;
  819. z-index: 101;
  820. box-sizing: border-box;
  821. width: 100%;
  822. height: 100vh;
  823. overflow: hidden;
  824. overflow-y: auto;
  825. background: rgba(0, 0, 0, 19%);
  826. &.practice-box-strock {
  827. display: flex;
  828. align-items: center;
  829. justify-content: center;
  830. padding-top: 0;
  831. }
  832. .miao-box {
  833. position: relative;
  834. width: 332px;
  835. height: 360px;
  836. padding: 30px 16px;
  837. margin: 0 auto;
  838. background: #f3f3f3;
  839. border-radius: 8px;
  840. box-shadow: 0 4px 16px rgba(0, 0, 0, 15%);
  841. .close-icon {
  842. position: absolute;
  843. top: 0;
  844. right: 8px;
  845. z-index: 2;
  846. width: 32px;
  847. height: 32px;
  848. padding: 8px;
  849. cursor: pointer;
  850. }
  851. .strockredBox,
  852. .strockplay-redInner {
  853. width: 300px;
  854. height: 300px;
  855. margin: 0 auto;
  856. }
  857. .strock-red {
  858. position: absolute;
  859. top: 30px;
  860. left: 16px;
  861. &-zindex {
  862. z-index: -1;
  863. }
  864. }
  865. .reset-box {
  866. position: absolute;
  867. right: 22px;
  868. bottom: 22px;
  869. z-index: 100;
  870. display: flex;
  871. align-items: center;
  872. justify-content: center;
  873. width: 11px;
  874. height: 11px;
  875. color: $text-color;
  876. cursor: pointer;
  877. &:hover {
  878. color: #000;
  879. }
  880. }
  881. }
  882. }
  883. .card-box {
  884. display: flex;
  885. flex-flow: wrap;
  886. gap: 5px;
  887. }
  888. .words-left {
  889. display: flex;
  890. gap: 10px;
  891. align-items: center;
  892. margin-bottom: 5px;
  893. }
  894. :deep .strockplay-redInner {
  895. width: 80px;
  896. height: 80px;
  897. border-width: 2px !important;
  898. border-radius: 4px;
  899. }
  900. .words-item {
  901. margin-bottom: 10px;
  902. }
  903. .words-bottom {
  904. margin-top: 3px;
  905. word-break: break-word;
  906. }
  907. .operation {
  908. width: 100%;
  909. }
  910. }
  911. </style>