Table.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. <template>
  2. <ModuleBase ref="base" :type="data.type">
  3. <template #content>
  4. <!-- <div class="fun-type">
  5. <a
  6. v-for="{ value, label } in tableTypeList"
  7. :key="value"
  8. :class="[data.mode === value ? 'active' : '']"
  9. @click="data.mode = value"
  10. >{{ label }}</a
  11. >
  12. </div> -->
  13. <div class="table-rich-toolbar">
  14. <el-select
  15. v-model="data.styles.fontFamily"
  16. placeholder="请选择"
  17. style="width: 130px"
  18. @change="BatchSetFormat('fontFamily', data.styles.fontFamily)"
  19. >
  20. <el-option v-for="{ value, label } in fontFamilyList" :key="value" :label="label" :value="value" />
  21. </el-select>
  22. <el-select
  23. v-model="data.styles.fontSize"
  24. placeholder="请选择"
  25. style="width: 130px"
  26. @change="BatchSetFormat('fontSize', data.styles.fontSize)"
  27. >
  28. <el-option
  29. v-for="(value, index) in 16"
  30. :key="index"
  31. :label="6 + value * 2 + 'pt'"
  32. :value="6 + value * 2 + 'pt'"
  33. />
  34. </el-select>
  35. <el-form :model="property" inline>
  36. <el-form-item label="文字颜色">
  37. <el-color-picker v-model="data.styles.fontColor" @change="BatchSetFormat('color', data.styles.fontColor)" />
  38. </el-form-item>
  39. <el-form-item label="背景色">
  40. <el-color-picker v-model="data.styles.bgColor" />
  41. </el-form-item>
  42. </el-form>
  43. <span
  44. :class="[data.styles.isUnderline ? 'active' : '']"
  45. @click="
  46. data.styles.isUnderline = !data.styles.isUnderline;
  47. BatchSetFormat('underline');
  48. "
  49. >
  50. <SvgIcon icon-class="underline" size="20" />
  51. </span>
  52. <span
  53. :class="[data.styles.isBold ? 'active' : '']"
  54. @click="
  55. data.styles.isBold = !data.styles.isBold;
  56. BatchSetFormat('bold');
  57. "
  58. >
  59. <SvgIcon icon-class="font-bold" size="20" />
  60. </span>
  61. <span
  62. :class="[data.styles.isItalic ? 'active' : '']"
  63. @click="
  64. data.styles.isItalic = !data.styles.isItalic;
  65. BatchSetFormat('italic');
  66. "
  67. >
  68. <SvgIcon icon-class="font-italic" size="20" />
  69. </span>
  70. <span
  71. :class="[data.styles.isStrikethrough ? 'active' : '']"
  72. @click="
  73. data.styles.isStrikethrough = !data.styles.isStrikethrough;
  74. BatchSetFormat('strikethrough');
  75. "
  76. >
  77. <SvgIcon icon-class="strikethrough" size="20" />
  78. </span>
  79. <span
  80. :class="[data.styles.textAlign === 'LEFT' ? 'active' : '']"
  81. @click="
  82. data.styles.textAlign = 'LEFT';
  83. BatchSetFormat('align', 'LEFT');
  84. "
  85. >
  86. <SvgIcon icon-class="align-left" size="20" />
  87. </span>
  88. <span
  89. :class="[data.styles.textAlign === 'MIDDLE' ? 'active' : '']"
  90. @click="
  91. data.styles.textAlign = 'MIDDLE';
  92. BatchSetFormat('align', 'MIDDLE');
  93. "
  94. >
  95. <SvgIcon icon-class="align-center" size="20" />
  96. </span>
  97. <span
  98. :class="[data.styles.textAlign === 'RIGHT' ? 'active' : '']"
  99. @click="
  100. data.styles.textAlign = 'RIGHT';
  101. BatchSetFormat('align', 'RIGHT');
  102. "
  103. >
  104. <SvgIcon icon-class="align-right" size="20" />
  105. </span>
  106. </div>
  107. <div class="option-list">
  108. <div v-for="(item, i) in data.option_list" :key="i" class="table-node">
  109. <el-color-picker v-model="data.rows_bg_list[i]" />
  110. <div v-for="(li, j) in item" :key="li.mark" class="table-item">
  111. <!-- eslint-disable max-len -->
  112. <RichText
  113. v-if="property.isGetContent"
  114. ref="richText"
  115. v-model="li.content"
  116. :font-size="data?.unified_attrib?.font_size"
  117. :font-family="data?.unified_attrib?.font"
  118. :font-color="data?.unified_attrib?.text_color"
  119. :inline="true"
  120. :item-index="i + '#' + j"
  121. toolbar="fontselect fontsizeselect forecolor backcolor | underline | bold italic strikethrough alignleft aligncenter alignright image media link"
  122. @handleRichTextBlur="handleBlurCon"
  123. />
  124. <el-input v-else v-model="li.content" @blur="handleBlurCon" />
  125. <el-button size="mini" @click="editCell(li.cell)">配置</el-button>
  126. </div>
  127. </div>
  128. <div class="table-node">
  129. <div style="width: 32px"></div>
  130. <div v-for="(value, index) in data.col_width" :key="index" class="table-item table-items">
  131. <el-color-picker v-model="data.cols_bg_list[index]" />
  132. <el-input v-model="value.value">
  133. <template slot="prepend">列宽:</template><template slot="append">%</template></el-input
  134. >
  135. </div>
  136. </div>
  137. </div>
  138. <el-input
  139. v-if="data.property.fill_type === fillTypeList[1].value"
  140. v-model="data.vocabulary"
  141. type="textarea"
  142. :autosize="{ minRows: 2, maxRows: 4 }"
  143. resize="none"
  144. placeholder="请输入词汇,用于选词填空"
  145. />
  146. <p class="tips">在需要作答的单元格内输入三个以上下划线“___”</p>
  147. <el-button @click="identifyText()">识别</el-button>
  148. <el-button @click="handleMultilingual">多语言</el-button>
  149. <template v-if="isEnable(data.has_identify)">
  150. <p class="tips">在需要作答的单元格内录入标准答案,多个填空答案用换行录入,同一个填空有多个答案用斜线“/”隔开</p>
  151. <div class="option-list">
  152. <div v-for="(item, i) in data.answer_lists" :key="i" class="table-node">
  153. <div v-for="(li, j) in item" :key="i + 'col' + j" class="table-item">
  154. <el-input v-model="li.answer" type="textarea" :readonly="!data.option_list[i][j].hasInput" />
  155. <span
  156. v-if="data.option_list[i][j].cell.isCross"
  157. style="display: flex; align-items: center; font-size: 14px"
  158. >勾叉答案<i
  159. :class="[
  160. { 'el-icon-check': li.crossAnswer === statusList[1] },
  161. { 'el-icon-close': li.crossAnswer === statusList[2] },
  162. ]"
  163. style="display: block; width: 14px; height: 14px; border: 1px solid #000"
  164. @click="toggle(li)"
  165. ></i
  166. ></span>
  167. </div>
  168. </div>
  169. </div>
  170. </template>
  171. <AnswerAnalysisList
  172. v-if="data.answer_list?.length > 0 || data.analysis_list?.length > 0"
  173. :answer-list="data.answer_list"
  174. :analysis-list="data.analysis_list"
  175. :unified-attrib="data.unified_attrib"
  176. @updateAnswerAnalysisFileList="updateAnswerAnalysisFileList"
  177. @deleteAnswerAnalysis="deleteAnswerAnalysis"
  178. />
  179. <MultilingualFill
  180. :visible.sync="multilingualVisible"
  181. :text="multilingualText"
  182. :translations="data.multilingual"
  183. @SubmitTranslation="handleMultilingualTranslation"
  184. />
  185. <el-divider v-if="isEnable(data.property.view_pinyin)" content-position="left">
  186. 拼音效果
  187. <el-button
  188. v-show="isEnable(data.property.view_pinyin)"
  189. type="text"
  190. icon="el-icon-refresh"
  191. title="刷新"
  192. class="refresh-pinyin-btn"
  193. @click.native="identifyText()"
  194. /></el-divider>
  195. <template v-if="isEnable(data.property.view_pinyin)">
  196. <template v-for="(item, index) in data.option_list">
  197. <PinyinText
  198. v-for="(items, indexs) in item"
  199. :id="'table_pinyin_text_' + index + '_' + indexs"
  200. :key="index + '_' + indexs"
  201. ref="PinyinText"
  202. :rich-text-list="items.rich_text_list"
  203. :pinyin-position="data.property.pinyin_position"
  204. :pinyin-size="data?.unified_attrib?.pinyin_size"
  205. :font-size="data?.unified_attrib?.font_size"
  206. :font-family="data?.unified_attrib?.font"
  207. @fillCorrectPinyin="fillCorrectPinyin"
  208. />
  209. </template>
  210. </template>
  211. <el-dialog
  212. v-if="editCellFlag"
  213. title="配置单元格"
  214. :visible="editCellFlag"
  215. width="460px"
  216. :close-on-click-modal="false"
  217. @close="editCellFlag = false"
  218. >
  219. <el-form :model="activeCell" :inline="true">
  220. <el-form-item label="背景色">
  221. <el-color-picker v-model="activeCell.bgColor" />
  222. </el-form-item>
  223. <el-form-item label="勾叉">
  224. <el-switch v-model="activeCell.isCross" />
  225. </el-form-item>
  226. <el-form-item label="合并行">
  227. <el-input v-model="activeCell.rowspan" class="rowspan" type="number" />
  228. </el-form-item>
  229. <el-form-item label="合并列">
  230. <el-input v-model="activeCell.colspan" class="colspan" type="number" />
  231. </el-form-item>
  232. </el-form>
  233. <div slot="footer">
  234. <el-button @click="editCellFlag = false">取消</el-button>
  235. <el-button type="primary" @click="editCellFlag = false">确定</el-button>
  236. </div>
  237. </el-dialog>
  238. </template>
  239. </ModuleBase>
  240. </template>
  241. <script>
  242. import { isEnable } from '@/views/book/courseware/data/common';
  243. import ModuleMixin from '../../common/ModuleMixin';
  244. import { PinyinBuild_OldFormat } from '@/api/book';
  245. import { getRandomNumber } from '@/utils';
  246. import PinyinText from '@/components/PinyinText.vue';
  247. import {
  248. getTableData,
  249. getOption,
  250. tableTypeList,
  251. fontFamilyList,
  252. getAnswerOption,
  253. fillTypeList,
  254. } from '@/views/book/courseware/data/table';
  255. export default {
  256. name: 'TablePage',
  257. components: {
  258. PinyinText,
  259. },
  260. mixins: [ModuleMixin],
  261. data() {
  262. return {
  263. isEnable,
  264. data: getTableData(),
  265. tableTypeList,
  266. fontFamilyList,
  267. multilingualText: '',
  268. isViewExplanatoryNoteDialog: false,
  269. oldRichData: {},
  270. fillTypeList,
  271. activeCell: null,
  272. editCellFlag: false,
  273. statusList: ['normal', 'tick', 'cross'],
  274. editContentIndex: '', // 编辑内容的单元格索引
  275. };
  276. },
  277. watch: {
  278. 'data.property.row_count': {
  279. handler(val) {
  280. if (val < this.data.option_list.length) {
  281. this.data.option_list = this.data.option_list.slice(0, val);
  282. this.data.answer_lists = this.data.answer_lists.slice(0, val);
  283. this.data.rows_bg_list = this.data.rows_bg_list.slice(0, val);
  284. } else {
  285. const diff = val - this.data.option_list.length;
  286. for (let i = 0; i < diff; i++) {
  287. this.data.option_list.push(Array.from({ length: this.data.property.column_count }, getOption));
  288. this.data.answer_lists.push(Array.from({ length: this.data.property.column_count }, getAnswerOption));
  289. this.data.rows_bg_list.push('');
  290. }
  291. }
  292. },
  293. },
  294. 'data.property.column_count': {
  295. handler(val) {
  296. const diff = val - this.data.option_list[0].length;
  297. for (let i = 0; i < diff; i++) {
  298. this.data.col_width.push({
  299. value: '',
  300. });
  301. this.data.cols_bg_list.push('');
  302. }
  303. this.data.cols_bg_list = this.data.cols_bg_list.slice(0, val);
  304. this.data.option_list = this.data.option_list.map((row) => {
  305. if (val < row.length) {
  306. this.data.col_width = this.data.col_width.slice(0, val);
  307. return row.slice(0, val);
  308. }
  309. const diff = val - row.length;
  310. return row.concat(Array.from({ length: diff }, getOption));
  311. });
  312. this.data.answer_lists = this.data.answer_lists?.map((row) => {
  313. if (val < row.length) {
  314. return row.slice(0, val);
  315. }
  316. const diff = val - row.length;
  317. return row.concat(Array.from({ length: diff }, getAnswerOption));
  318. });
  319. },
  320. },
  321. 'data.property.view_pinyin': {
  322. handler(val) {
  323. let text = '';
  324. this.data.option_list.forEach((item) => {
  325. item.forEach((items) => {
  326. text += `${items.content.replace(/<[^>]+>/g, '')}\n`;
  327. });
  328. });
  329. if (!isEnable(val)) {
  330. this.data.paragraph_list = [];
  331. return;
  332. }
  333. if (isEnable(val) && text && this.data.paragraph_list.length <= 0) {
  334. this.data.paragraph_list_parameter.text = text;
  335. this.data.paragraph_list_parameter.is_first_sentence_first_hz_pinyin_first_char_upper_case =
  336. this.data.property.is_first_sentence_first_hz_pinyin_first_char_upper_case;
  337. this.data.option_list.forEach((item, index) => {
  338. item.forEach((items, indexs) => {
  339. this.createParsedTextInfoPinyin(items.content, `${index}#${indexs}`);
  340. });
  341. });
  342. }
  343. },
  344. deep: true,
  345. },
  346. 'data.property.is_first_sentence_first_hz_pinyin_first_char_upper_case': {
  347. handler(val, oldVal) {
  348. if (val === oldVal) return;
  349. let text = '';
  350. this.data.option_list.forEach((item) => {
  351. item.forEach((items) => {
  352. text += `${items.content.replace(/<[^>]+>/g, '')}\n`;
  353. });
  354. });
  355. if (!isEnable(this.data.property.view_pinyin)) {
  356. this.data.paragraph_list = [];
  357. return;
  358. }
  359. if (text && isEnable(this.data.property.view_pinyin)) {
  360. this.data.paragraph_list_parameter.text = text;
  361. this.data.paragraph_list_parameter.is_first_sentence_first_hz_pinyin_first_char_upper_case = val;
  362. this.data.option_list.forEach((item, index) => {
  363. item.forEach((items, indexs) => {
  364. this.createParsedTextInfoPinyin(items.content, `${index}#${indexs}`);
  365. });
  366. });
  367. }
  368. },
  369. deep: true,
  370. },
  371. 'data.vocabulary': {
  372. handler(val) {
  373. if (!val) return;
  374. this.data.word_list = val
  375. .split(/[\n\r]+/)
  376. .map((item) => item.split(' ').filter((s) => s))
  377. .flat()
  378. .map((content) => {
  379. return {
  380. content,
  381. mark: getRandomNumber(),
  382. };
  383. });
  384. },
  385. },
  386. 'data.unified_attrib': {
  387. handler(val) {
  388. if (val) {
  389. this.data.styles.fontFamily = this.data?.unified_attrib?.font || '楷体,微软雅黑';
  390. this.data.styles.fontSize = this.data?.unified_attrib?.font_size || '12pt';
  391. this.data.styles.fontColor = this.data?.unified_attrib?.text_color || '#1d2129';
  392. this.data.styles.textAlign = this.data?.unified_attrib?.align || 'LEFT';
  393. }
  394. },
  395. deep: true,
  396. immediate: true,
  397. },
  398. },
  399. methods: {
  400. toggle(status) {
  401. const index = this.statusList.findIndex((item) => status.crossAnswer === item);
  402. status.crossAnswer = index === this.statusList.length - 1 ? this.statusList[0] : this.statusList[index + 1];
  403. },
  404. editCell(cell) {
  405. this.activeCell = cell;
  406. this.editCellFlag = true;
  407. },
  408. // 设置样式
  409. BatchSetFormat(type, val = '') {
  410. this.$refs.richText.forEach((richText) => {
  411. richText.setRichFormat(type, val);
  412. });
  413. },
  414. // 识别文本
  415. identifyText(editIndex) {
  416. let text = '';
  417. this.data.has_identify = 'true';
  418. this.data.option_list.forEach((item, index) => {
  419. item.forEach((items, indexs) => {
  420. items.model_essay = [];
  421. // this.data.answer_list[index][indexs].answer_list = [];
  422. if (items.content) {
  423. let inputIndex = 0;
  424. items.content
  425. .split(/<(p|div)[^>]*>(.*?)<\/(p|div)>/g)
  426. .filter((s) => s && !s.match(/^(p|div)$/))
  427. .forEach((itemss) => {
  428. if (itemss.charCodeAt() === 10) return;
  429. let strArr = itemss.split(/_{3,}/g);
  430. strArr.forEach((itemS, index) => {
  431. items.model_essay.push({
  432. value: itemS,
  433. type: 'text',
  434. });
  435. if (index !== strArr.length - 1) {
  436. items.model_essay.push({
  437. value: '',
  438. type: 'input',
  439. mark: getRandomNumber(),
  440. inputIndex,
  441. write_base64: '',
  442. audio_answer_list: [],
  443. });
  444. inputIndex += 1;
  445. items.hasInput = true;
  446. }
  447. });
  448. // // 去除所有的 font-size 样式
  449. // .replace(/font-size:\s*\d+(\.\d+)?px;/gi, '')
  450. // // 匹配 class 名为 rich-fill 的 span 标签和三个以上的_,并将它们组成数组
  451. // .replace(/<span class="rich-fill".*?>(.*?)<\/span>|([_]{3,})/gi, '###$1$2###');
  452. });
  453. }
  454. items.crossAnswer = 'normal';
  455. // text += `${items.content.replace(/<[^>]+>/g, '')}\n`;
  456. text += `${items.content}\n`;
  457. });
  458. });
  459. if (isEnable(this.data.property.view_pinyin)) {
  460. if (editIndex) {
  461. let arr = editIndex.split('#');
  462. text = this.data.option_list[arr[0]][arr[1]].content;
  463. this.createParsedTextInfoPinyin(text, editIndex);
  464. } else {
  465. this.data.option_list.forEach((item, index) => {
  466. item.forEach((items, indexs) => {
  467. this.createParsedTextInfoPinyin(items.content, `${index}#${indexs}`);
  468. });
  469. });
  470. }
  471. }
  472. },
  473. // 获取拼音解析文本
  474. createParsedTextInfoPinyin(text, editIndex) {
  475. if (text === '') {
  476. this.data.paragraph_list_parameter.pinyin_proofread_word_list = [];
  477. return;
  478. }
  479. // .replace(/<[^>]+>/g, '')
  480. this.data.paragraph_list_parameter.text = text;
  481. this.data.paragraph_list_parameter.is_first_sentence_first_hz_pinyin_first_char_upper_case =
  482. this.data.property.is_first_sentence_first_hz_pinyin_first_char_upper_case;
  483. this.data.paragraph_list_parameter.is_rich_text = 'true';
  484. PinyinBuild_OldFormat(this.data.paragraph_list_parameter).then((res) => {
  485. if (res.parsed_text) {
  486. const mergedData = res.parsed_text.paragraph_list.map((outerArr, i) =>
  487. outerArr.map((innerArr, j) =>
  488. innerArr.map((newItem, k) => {
  489. // 从 originalData 中找到对应的项
  490. const originalItem = this.data.paragraph_list[i]?.[j]?.[k];
  491. // 如果 originalItem 有 activeTextStyle,就合并到 newItem
  492. if (originalItem?.activeTextStyle) {
  493. return {
  494. ...newItem,
  495. activeTextStyle: originalItem.activeTextStyle,
  496. };
  497. }
  498. // 否则直接返回 newItem
  499. return newItem;
  500. }),
  501. ),
  502. );
  503. this.data.paragraph_list = mergedData;
  504. if (editIndex) {
  505. let arr = editIndex.split('#');
  506. let list = res.rich_text.text_list;
  507. list.forEach((item) => {
  508. let inputIndex = 0;
  509. if (item.word_list) {
  510. item.word_list.forEach((items, index) => {
  511. let isUnderline = /^_{3,}$/.test(items.text);
  512. if (isUnderline) {
  513. let obj = {
  514. value: '',
  515. type: 'input',
  516. mark: getRandomNumber(),
  517. inputIndex,
  518. write_base64: '',
  519. audio_answer_list: [],
  520. };
  521. inputIndex++;
  522. item.word_list[index] = { ...items, ...obj };
  523. } else {
  524. items.type = 'text';
  525. }
  526. });
  527. } else {
  528. item.type = 'text';
  529. }
  530. });
  531. this.$set(this.data.option_list[arr[0]][arr[1]], 'rich_text_list', list);
  532. } else {
  533. this.$set(this.data, 'rich_text_list', res.rich_text.text_list);
  534. }
  535. let pinyin_index = 0;
  536. this.data.option_list.forEach((item, index) => {
  537. item.forEach((items, indexs) => {
  538. items.model_pinyin = [];
  539. let inputIndex = 0;
  540. if (items.content && mergedData[pinyin_index] && mergedData[pinyin_index][0]) {
  541. mergedData[pinyin_index][0].forEach((itemP) => {
  542. let isUnderline = /^_{3,}$/.test(itemP.text);
  543. if (isUnderline) {
  544. items.model_pinyin.push({
  545. value: '',
  546. type: 'input',
  547. mark: getRandomNumber(),
  548. inputIndex,
  549. });
  550. inputIndex++;
  551. } else {
  552. items.model_pinyin.push(itemP);
  553. }
  554. });
  555. pinyin_index++;
  556. }
  557. });
  558. });
  559. if (this.editContentIndex) {
  560. this.editContentIndex = '';
  561. }
  562. }
  563. });
  564. console.log(this.data);
  565. },
  566. // 填充校对后的拼音
  567. fillCorrectPinyin({ selectContent: { text, pinyin, activeTextStyle }, i, j, k }) {
  568. this.data.paragraph_list_parameter.pinyin_proofread_word_list.push({
  569. paragraph_index: i,
  570. sentence_index: j,
  571. word_index: k,
  572. word: text,
  573. pinyin,
  574. });
  575. if (pinyin) this.data.paragraph_list[i][j][k].pinyin = pinyin;
  576. if (activeTextStyle) this.data.paragraph_list[i][j][k].activeTextStyle = activeTextStyle;
  577. },
  578. // 思维导图数据
  579. handleMindMap() {
  580. let node_list = [];
  581. this.data.option_list.forEach((item) => {
  582. item.forEach((items) => {
  583. node_list.push({
  584. name: items.content.replace(/<[^>]*>?/gm, ''),
  585. id: Math.random().toString(36).substring(2, 12),
  586. });
  587. });
  588. });
  589. this.data.mind_map.node_list = node_list;
  590. },
  591. handleBlurCon(index) {
  592. this.editContentIndex = index;
  593. this.identifyText(index);
  594. this.handleMindMap();
  595. },
  596. handleMultilingual() {
  597. this.multilingualText = '';
  598. this.data.option_list.forEach((item) => {
  599. item.forEach((items) => {
  600. this.multilingualText += items.content ? `<p>${items.content}</p>` : '<p>&nbsp;</p>';
  601. });
  602. });
  603. this.multilingualVisible = true;
  604. },
  605. },
  606. };
  607. </script>
  608. <style lang="scss" scoped>
  609. .option-list {
  610. margin-bottom: 12px;
  611. .table-node {
  612. display: flex;
  613. row-gap: 16px;
  614. .table-item {
  615. flex: 1;
  616. min-width: 75px;
  617. padding: 8px;
  618. border: 1px solid $border-color;
  619. &:not(:last-child) {
  620. border-right: 0;
  621. }
  622. :deep p {
  623. margin: 0;
  624. }
  625. :deep .el-input-group__append,
  626. :deep .el-input-group__prepend {
  627. padding: 0 5px;
  628. }
  629. &.table-items {
  630. display: flex;
  631. align-items: center;
  632. }
  633. }
  634. }
  635. }
  636. .fun-type {
  637. display: flex;
  638. gap: 5px;
  639. width: 100%;
  640. padding-bottom: 10px;
  641. border-bottom: 1px solid #e5e6eb;
  642. a {
  643. padding: 5px 10px;
  644. font-weight: normal;
  645. color: #1d2129;
  646. cursor: pointer;
  647. background: #f2f3f5;
  648. border: 1px solid #f2f3f5;
  649. border-radius: 2px;
  650. &.active {
  651. color: #165dff;
  652. background: #e7eeff;
  653. border-color: #165dff;
  654. }
  655. }
  656. }
  657. .table-rich-toolbar {
  658. display: flex;
  659. gap: 5px;
  660. padding: 5px 0;
  661. /* align-items: center; */
  662. :deep .el-form-item--small.el-form-item {
  663. margin: 0 5px 0 0;
  664. }
  665. :deep .el-form-item__label {
  666. padding-right: 3px;
  667. }
  668. > span {
  669. height: 30px;
  670. padding: 5px 6px;
  671. color: #222f3e;
  672. cursor: pointer;
  673. border-radius: 5px;
  674. &:hover {
  675. background: #cce2fa;
  676. }
  677. &.active {
  678. background: #a6ccf7;
  679. }
  680. }
  681. }
  682. .tips {
  683. font-size: 12px;
  684. color: #999;
  685. }
  686. </style>