// 组件混入 import Vue from 'vue'; import ModuleBase from './ModuleBase.vue'; import RichText from '@/components/RichText.vue'; import MultilingualFill from '@/views/book/components/MultilingualFill.vue'; import { displayList, viewMethodList, isEnable } from '@/views/book/courseware/data/common'; import { ContentSaveCoursewareComponentContent, ContentGetCoursewareComponentContent, CrateParsedTextInfo_Pinyin, } from '@/api/book'; const mixin = { data() { return { displayList, viewMethodList, typeList: ['interaction'], isEnable, property: { isGetContent: false, // 是否已获取内容 }, borderColorObj: Vue.observable({ value: this.borderColor }), // 边框颜色 multilingualVisible: false, // 多语言弹窗 }; }, props: { id: { type: String, required: true, }, componentMove: { type: Function, required: true, }, borderColor: { type: String, required: true, }, content: { type: String, default: '{}', }, type: { type: String, default: '', }, }, components: { ModuleBase, RichText, MultilingualFill, }, provide() { return { showSetting: this.showSetting, id: this.id, deleteComponent: this.deleteComponent, handleComponentMove: this.handleComponentMove, property: this.property, borderColor: this.borderColorObj, }; }, watch: { borderColor(newVal) { this.borderColorObj.value = newVal; }, content: { handler(newVal) { if (this.type !== 'interaction') return; if (newVal) this.data = JSON.parse(newVal); }, immediate: true, }, }, inject: ['courseware_id', 'project_id', 'getBookUnifiedAttr'], created() { if (this.type !== 'interaction') { this.GetCoursewareComponentContent(); } // 初始化 mind_map.node_list[0].id if (!this.data?.mind_map?.node_list?.[0]?.id) { this.data.mind_map = this.data.mind_map ?? {}; this.data.mind_map.node_list = this.data.mind_map.node_list ?? [{}]; if (this.data.mind_map.node_list.length > 0) { this.data.mind_map.node_list[0].id = this.id; } } }, methods: { GetCoursewareComponentContent() { ContentGetCoursewareComponentContent({ courseware_id: this.courseware_id, component_id: this.id }).then( ({ content }) => { if (content) { this.data = JSON.parse(content); } else if ('view_pinyin' in this.data.property) { // 初始化时,如果有 view_pinyin 则根据全文设置配置设 view_pinyin 和 pinyin_position const bookUnifiedAttr = this.getBookUnifiedAttr(); this.data.property.view_pinyin = bookUnifiedAttr?.view_pinyin ?? 'false'; this.data.property.pinyin_position = bookUnifiedAttr?.pinyin_position ?? 'top'; } this.property.isGetContent = true; this.$watch( 'data', () => { this.$emit('changeData'); }, { deep: true }, ); }, ); }, /** * @description 显示设置 */ showSetting() { this.$emit('showSetting', this.data.property, this.data.type, this.id); }, /** * @description 删除组件 */ deleteComponent() { this.$emit('deleteComponent', this.id); }, /** * @description 更新property属性 * @param {String} type 类型 * @param {Object} attr 属性 */ updateProperty(type, attr) { this.$set(this.data.property, type, attr); }, /** * 批量设置富文本样式 * @param {Object} type 类型 * @param {Object} attr 属性 */ updateRichTextProperty(type, attr) { let richTextRefs = this.$refs.richText; if (!richTextRefs) return; if (!Array.isArray(richTextRefs)) { richTextRefs = [richTextRefs]; } richTextRefs?.forEach((richText) => { richText.setRichFormat(type, attr); }); }, setUnifiedAttr(data) { if (!data) return; this.data.unified_attrib = data; }, handleComponentMove(data) { this.componentMove({ ...data, id: this.id }); }, /** * 保存课节组件内容 * @returns {Promise} 返回 Promise,便于父组件 await */ saveCoursewareComponentContent() { return ContentSaveCoursewareComponentContent({ courseware_id: this.courseware_id, component_id: this.id, component_type: this.data.type, content: JSON.stringify(this.data), }); }, findComponentWithRefAndMethod(children, refName, methodName) { for (const child of children) { // 检查当前组件是否符合条件 if (child.$refs[refName] && typeof child[methodName] === 'function') { return child; } // 递归检查子组件 if (child.$children?.length) { const found = this.findComponentWithRefAndMethod(child.$children, refName, methodName); if (found) return found; } } return null; }, openMultilingual() { this.multilingualVisible = true; }, /** * @description 提交多语言翻译 * @param {Array} multilingual */ handleMultilingualTranslation(multilingual) { this.data.multilingual = multilingual; }, /** * 获取并设置拼音解析文本 * @param {String} text 文本 * @param {Number} i 行索引 * @param {Number} j 列索引 * @param {String} attr 属性名 */ createParsedTextInfoPinyin(text, i = -1, j = -1, attr = 'option_list') { let data = null; if (i === -1) { data = this.data; } else if (i >= 0 && j === -1) { data = this.data[attr][i]; } else if (i >= 0 && j >= 0) { data = this.data[attr][i][j]; } if (text === '') { data.pinyin_proofread_word_list = []; return; } data.paragraph_list_parameter.text = text; CrateParsedTextInfo_Pinyin({ ...data.paragraph_list_parameter, is_first_sentence_first_hz_pinyin_first_char_upper_case: this.data.property.is_first_sentence_first_hz_pinyin_first_char_upper_case, }).then(({ parsed_text }) => { if (parsed_text) { // 合并 activeTextStyle const mergedData = parsed_text.paragraph_list.map((outerArr, i) => outerArr.map((innerArr, j) => innerArr.map((newItem, k) => ({ ...newItem, // 如果 originalItem 有 activeTextStyle,就合并到 newItem ...(data.paragraph_list?.[i]?.[j]?.[k]?.activeTextStyle && { activeTextStyle: data.paragraph_list[i][j][k].activeTextStyle, }), })), ), ); data.paragraph_list = mergedData; } }); }, /** * 填充校对后的拼音 * @param {Object} param0 拼音参数 * @param {Number} col 列索引 * @param {Number} row 行索引 * @param {String} attr 属性名 */ fillCorrectPinyin( { selectContent: { text, pinyin, activeTextStyle }, i, j, k }, row = -1, col = -1, attr = 'option_list', ) { let data = null; if (row === -1) { data = this.data.paragraph_list_parameter; } else if (row >= 0 && col === -1) { data = this.data[attr][row].paragraph_list_parameter; } else if (row >= 0 && col >= 0) { data = this.data[attr][row][col].paragraph_list_parameter; } if (!Array.isArray(data.pinyin_proofread_word_list)) { data.pinyin_proofread_word_list = []; } data.pinyin_proofread_word_list.push({ paragraph_index: i, sentence_index: j, word_index: k, word: text, pinyin, }); let listItem = null; if (row === -1) { listItem = this.data.paragraph_list?.[i]?.[j]?.[k]; } else if (row >= 0 && col === -1) { listItem = this.data[attr]?.[row]?.paragraph_list?.[i]?.[j]?.[k]; } else if (row >= 0 && col >= 0) { listItem = this.data[attr]?.[row]?.[col]?.paragraph_list?.[i]?.[j]?.[k]; } if (listItem) { if (pinyin) listItem.pinyin = pinyin; if (activeTextStyle) listItem.activeTextStyle = activeTextStyle; } }, }, }; export default mixin;