NotesPreview.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. <!-- eslint-disable vue/no-v-html -->
  2. <template>
  3. <div class="notes-preview" :style="getAreaStyle()">
  4. <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
  5. <div class="main">
  6. <div class="NPC-zhedie">
  7. <div
  8. class="topTitle"
  9. :style="{
  10. backgroundColor:
  11. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '',
  12. }"
  13. >
  14. <div class="NPC-top-left">
  15. <span class="NPC-topTitle-text" v-html="data.title_con"></span>
  16. <span class="NPC-topTitle-text" v-if="showLang">
  17. {{ titleTrans[getLang()] }}
  18. </span>
  19. </div>
  20. <div class="NPC-top-right" @click="handleChangeTab">
  21. <span class="NPC-top-right-text">{{ wordShow ? '收起' : '展开' }}</span>
  22. <img v-if="wordShow" src="@/assets/down.png" alt="" />
  23. <img v-else class="rotate" src="@/assets/down.png" alt="" />
  24. </div>
  25. </div>
  26. <el-collapse-transition>
  27. <div v-show="wordShow" class="NPC-notes-list">
  28. <div v-for="(item, index) in data.option" :key="'NPC-notes' + index" class="NPC-notes">
  29. <div class="NPC-notes-con">
  30. <span
  31. class="NPC-notes-con-number"
  32. v-html="item.number"
  33. :style="{
  34. color:
  35. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '',
  36. }"
  37. ></span>
  38. <div class="NPC-notes-con-box">
  39. <template v-if="isEnable(data.property.view_pinyin)">
  40. <p class="pinyin-text">
  41. <span
  42. v-if="data.property.pinyin_position === 'top'"
  43. class="pinyin"
  44. v-html="item.pinyin"
  45. :style="{
  46. fontSize:
  47. data.unified_attrib && data.unified_attrib.pinyin_size
  48. ? data.unified_attrib.pinyin_size
  49. : '',
  50. }"
  51. >
  52. </span>
  53. <span>
  54. <span
  55. v-if="data.property.pinyin_position === 'front'"
  56. v-html="item.pinyin"
  57. class="pinyin pinyin-front"
  58. :style="{
  59. fontSize:
  60. data.unified_attrib && data.unified_attrib.pinyin_size
  61. ? data.unified_attrib.pinyin_size
  62. : '',
  63. }"
  64. ></span
  65. ><span
  66. class="NPC-notes-con-text"
  67. v-html="item.con"
  68. :style="{
  69. color:
  70. data.unified_attrib && data.unified_attrib.topic_color
  71. ? data.unified_attrib.topic_color
  72. : '',
  73. fontSize:
  74. data.unified_attrib && data.unified_attrib.font_size ? data.unified_attrib.font_size : '',
  75. }"
  76. ></span
  77. ><span
  78. v-if="data.property.pinyin_position === 'back'"
  79. v-html="item.pinyin"
  80. class="pinyin pinyin-back"
  81. :style="{
  82. fontSize:
  83. data.unified_attrib && data.unified_attrib.pinyin_size
  84. ? data.unified_attrib.pinyin_size
  85. : '',
  86. }"
  87. ></span>
  88. </span>
  89. <span
  90. v-if="data.property.pinyin_position === 'bottom'"
  91. class="pinyin"
  92. v-html="item.pinyin"
  93. :style="{
  94. fontSize:
  95. data.unified_attrib && data.unified_attrib.pinyin_size
  96. ? data.unified_attrib.pinyin_size
  97. : '',
  98. }"
  99. ></span>
  100. </p>
  101. </template>
  102. <span
  103. class="NPC-notes-con-text"
  104. v-html="item.con"
  105. v-else
  106. :style="{
  107. color:
  108. data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '',
  109. fontSize:
  110. data.unified_attrib && data.unified_attrib.font_size ? data.unified_attrib.font_size : '',
  111. }"
  112. ></span>
  113. <span class="multilingual" v-if="showLang">
  114. {{
  115. multilingualTextList[getLang()] &&
  116. multilingualTextList[getLang()][index] &&
  117. multilingualTextList[getLang()][index][0]
  118. ? multilingualTextList[getLang()][index][0]
  119. : ''
  120. }}
  121. </span>
  122. </div>
  123. </div>
  124. <div class="NPC-notes-trans" v-html="item.interpret"></div>
  125. <div v-if="item.note" class="NPC-notes-note" v-html="item.note"></div>
  126. <div v-if="item.file_list[0]" class="NPC-notes-note-img">
  127. <el-image :src="item.pic_url" :preview-src-list="[item.pic_url]" fit="contain" />
  128. </div>
  129. <div class="NPC-notes-note" v-if="showLang">
  130. {{
  131. multilingualTextList[getLang()] &&
  132. multilingualTextList[getLang()][index] &&
  133. multilingualTextList[getLang()][index][1]
  134. ? multilingualTextList[getLang()][index][1]
  135. : ''
  136. }}
  137. </div>
  138. </div>
  139. </div>
  140. </el-collapse-transition>
  141. </div>
  142. </div>
  143. </div>
  144. </template>
  145. <script>
  146. import { getNotesData, isEnable } from '@/views/book/courseware/data/notes';
  147. import PreviewMixin from '../common/PreviewMixin';
  148. import { GetFileURLMap } from '@/api/app';
  149. export default {
  150. name: 'NotesPreview',
  151. components: {},
  152. props: ['notesData'],
  153. mixins: [PreviewMixin],
  154. data() {
  155. return {
  156. data: this.notesData ? this.notesData : getNotesData(),
  157. wordShow: true,
  158. multilingualTextList: {}, // 多语言对应的切割后的翻译
  159. titleTrans: {},
  160. };
  161. },
  162. computed: {},
  163. watch: {
  164. 'data.option.length': {
  165. handler(val) {
  166. if (val) {
  167. // this.wordShow = isEnable(this.data.property.is_word_show);
  168. this.handleData();
  169. }
  170. },
  171. deep: true,
  172. immediate: true,
  173. },
  174. },
  175. created() {},
  176. methods: {
  177. handleChangeTab() {
  178. this.wordShow = !this.wordShow;
  179. },
  180. handleData() {
  181. if (this.showLang) {
  182. this.data.multilingual.forEach((item) => {
  183. let trans_arr = item.translation.split('\n');
  184. this.$set(this.titleTrans, item.type, trans_arr[0] ? trans_arr[0] : '');
  185. let chunkSize = 2;
  186. let chunkedArr = trans_arr.splice(1).reduce((acc, curr, index) => {
  187. // 当索引是chunkSize的倍数时,开始一个新的子数组
  188. if (index % chunkSize === 0) {
  189. acc.push([curr]); // 开始新的子数组并添加当前元素
  190. } else {
  191. acc[acc.length - 1].push(curr); // 将当前元素添加到最后一个子数组中
  192. }
  193. return acc;
  194. }, []);
  195. this.$set(this.multilingualTextList, item.type, chunkedArr);
  196. });
  197. }
  198. this.data.option.forEach((item) => {
  199. if (item.file_list && item.file_list[0]) {
  200. GetFileURLMap({ file_id_list: item.file_list }).then(({ url_map }) => {
  201. this.$set(item, 'pic_url', url_map[item.file_list[0]]);
  202. });
  203. }
  204. });
  205. },
  206. },
  207. };
  208. </script>
  209. <style lang="scss" scoped>
  210. @use '@/styles/mixin.scss' as *;
  211. .notes-preview {
  212. @include preview-base;
  213. .NPC-zhedie {
  214. // margin-bottom: 24px;
  215. .topTitle {
  216. display: flex;
  217. justify-content: space-between;
  218. width: 100%;
  219. height: 48px;
  220. padding-right: 16px;
  221. padding-left: 24px;
  222. overflow: hidden;
  223. background: #e35454;
  224. border: 1px solid rgba(0, 0, 0, 10%);
  225. border-radius: 8px 8px 0 0;
  226. :deep p {
  227. margin: 0;
  228. }
  229. .NPC-top-left {
  230. display: flex;
  231. align-items: center;
  232. justify-content: flex-start;
  233. .NPC-topTitle-text {
  234. margin: 0 8px 0 0;
  235. font-family: 'sourceR';
  236. font-size: 16px;
  237. font-weight: bold;
  238. color: #fff;
  239. }
  240. }
  241. .NPC-top-right {
  242. display: flex;
  243. align-items: center;
  244. justify-content: flex-start;
  245. cursor: pointer;
  246. &-text {
  247. font-size: 14px;
  248. font-weight: normal;
  249. line-height: 16px;
  250. color: #fff;
  251. }
  252. img {
  253. width: 16px;
  254. height: 16px;
  255. margin-left: 4px;
  256. }
  257. }
  258. .rotate {
  259. animation-name: firstrotate;
  260. animation-timing-function: linear;
  261. animation-direction: 2s;
  262. animation-fill-mode: both;
  263. }
  264. }
  265. .NPC-notes-list {
  266. padding: 24px 24px 5px;
  267. border: 1px solid rgba(0, 0, 0, 10%);
  268. border-top: none;
  269. border-radius: 0 0 8px 8px;
  270. .NPC-notes {
  271. width: 100%;
  272. margin-bottom: 24px;
  273. :deep p {
  274. margin: 0;
  275. }
  276. .NPC-notes-con {
  277. display: flex;
  278. align-items: center;
  279. justify-content: flex-start;
  280. margin-bottom: 12px;
  281. .NPC-notes-con-box {
  282. flex: 1;
  283. margin-left: 5px;
  284. }
  285. .NPC-notes-con-number {
  286. font-family: 'robot';
  287. font-size: 14px;
  288. font-style: normal;
  289. font-weight: normal;
  290. line-height: 150%;
  291. color: #e35454;
  292. }
  293. .NPC-notes-con-text {
  294. width: max-content;
  295. margin: 0 5px;
  296. // font-size: 14px;
  297. font-style: normal;
  298. font-weight: normal;
  299. line-height: 1;
  300. color: #e35454;
  301. :deep p {
  302. // line-height: 150%;
  303. display: inline;
  304. }
  305. }
  306. }
  307. .pinyin {
  308. font-family: 'League';
  309. font-size: 14px;
  310. &-front,
  311. &-back {
  312. :deep p {
  313. // line-height: 150%;
  314. display: inline;
  315. }
  316. }
  317. }
  318. .NPC-notes-trans {
  319. padding-left: 27px;
  320. margin-bottom: 12px;
  321. font-size: 14px;
  322. font-style: normal;
  323. font-weight: bold;
  324. line-height: 150%;
  325. color: #000;
  326. }
  327. .NPC-notes-note {
  328. font-size: 14px;
  329. font-style: normal;
  330. font-weight: normal;
  331. line-height: 150%;
  332. color: #000;
  333. text-indent: 27px;
  334. word-break: break-word;
  335. }
  336. }
  337. }
  338. .NPC-notes-note-img {
  339. width: 100%;
  340. > div {
  341. max-width: 100%;
  342. > img {
  343. max-width: 100%;
  344. }
  345. }
  346. }
  347. }
  348. @keyframes firstrotate {
  349. 0% {
  350. transform: rotateZ(0deg);
  351. }
  352. 100% {
  353. transform: rotateZ(180deg);
  354. }
  355. }
  356. @keyframes huifuRotate {
  357. 0% {
  358. transform: rotateZ(180deg);
  359. }
  360. 100% {
  361. transform: rotateZ(0deg);
  362. }
  363. }
  364. }
  365. </style>