diff --git a/seller/src/views/goods/goods-seller/goodsOperationSec.vue b/seller/src/views/goods/goods-seller/goodsOperationSec.vue
index a76178f2..bd1fc728 100644
--- a/seller/src/views/goods/goods-seller/goodsOperationSec.vue
+++ b/seller/src/views/goods/goods-seller/goodsOperationSec.vue
@@ -1452,6 +1452,22 @@ export default {
/** 查询商品参数 */
this.GET_GoodsParams();
+
+ this.$nextTick(() => {
+ this.$refs.editor?.setContent?.(this.baseInfoForm.intro);
+ this.$refs.introEditor?.setContent?.(this.baseInfoForm.mobileIntro);
+ });
+ },
+ /** TinyMCE 的 v-model 可能滞后,提交前从编辑器实例取最新 HTML */
+ syncIntroFromEditors() {
+ const pcEditor = this.$refs.editor;
+ const mobileEditor = this.$refs.introEditor;
+ if (pcEditor?.getContent) {
+ this.baseInfoForm.intro = pcEditor.getContent() ?? "";
+ }
+ if (mobileEditor?.getContent) {
+ this.baseInfoForm.mobileIntro = mobileEditor.getContent() ?? "";
+ }
},
// 渲染sku数据
renderGoodsDetailSku(skuList) {
@@ -1522,8 +1538,8 @@ export default {
},
// 将pc商品描述同步给移动端
promiseIntroEditor() {
- const pcContent = this.$refs.editor?.getContent?.() ?? this.baseInfoForm.intro ?? "";
- this.baseInfoForm.intro = pcContent;
+ this.syncIntroFromEditors();
+ const pcContent = this.baseInfoForm.intro ?? "";
this.baseInfoForm.mobileIntro = pcContent;
this.$nextTick(() => {
this.$refs.introEditor?.setContent?.(pcContent);
@@ -2360,6 +2376,7 @@ export default {
if (!this.$route.query.copyId) {
this.baseInfoForm.goodsId = this.goodsId;
}
+ this.syncIntroFromEditors();
let submit = JSON.parse(JSON.stringify(this.baseInfoForm));
if (
submit.goodsGalleryFiles &&
diff --git a/seller/src/views/lili-components/editor/index.vue b/seller/src/views/lili-components/editor/index.vue
index 8210bca3..2cd87e62 100644
--- a/seller/src/views/lili-components/editor/index.vue
+++ b/seller/src/views/lili-components/editor/index.vue
@@ -36,6 +36,7 @@ export default {
initEditor,
hasChange: false, // 标记内容是否有更改
hasInit: false, // 标记编辑器是否已初始化
+ pendingContent: null, // 编辑器未就绪时暂存待回填内容
tinymceId:
"tinymce-" + +new Date() + ((Math.random() * 1000).toFixed(0) + ""), // 生成唯一的编辑器 ID
fullscreen: false, // 标记编辑器是否处于全屏模式
@@ -43,9 +44,6 @@ export default {
content: "", // 编辑器内容
};
},
- created() {
- this.init();
- },
computed: {
bindValue() {
return this.modelValue ?? this.value ?? "";
@@ -54,40 +52,55 @@ export default {
watch: {
bindValue: {
handler(val) {
- if (!this.hasChange && this.hasInit) {
- const editor = window.tinymce.get(this.tinymceId);
- if (editor) {
- this.$nextTick(() => editor.setContent(val || ""));
- }
+ if (!this.hasChange) {
+ this.setContent(val || "");
}
},
- deep: true,
},
},
methods: {
+ emitContent(content) {
+ this.$emit("update:modelValue", content);
+ this.$emit("input", content);
+ },
+ getEditor() {
+ return window.tinymce?.get(this.tinymceId);
+ },
+ isEditorReady() {
+ const editor = this.getEditor();
+ return !!(editor && editor.initialized && editor.dom);
+ },
// 数据返回并给富文本框插入图片
insertImage(arr){
- arr.forEach(v => window.tinymce.get(this.tinymceId).insertContent(`
`))
+ const editor = this.getEditor();
+ if (!editor || !this.isEditorReady()) {
+ return;
+ }
+ arr.forEach(v => editor.insertContent(`
`))
},
init() {
// 初始化编辑器
this.initTinymce();
},
initTinymce() {
+ if (this.getEditor()) {
+ return;
+ }
const _this = this;
window.tinymce.init({
selector: `#${this.tinymceId}`,
convert_urls: false,
init_instance_callback: (editor) => {
- if (_this.bindValue) {
- _this.$nextTick(() => editor.setContent(_this.bindValue));
- }
_this.hasInit = true;
- editor.on("NodeChange Change KeyUp SetContent", () => {
+ const initial = _this.pendingContent ?? _this.bindValue;
+ _this.pendingContent = null;
+ if (initial) {
+ _this.applyContent(editor, initial);
+ }
+ // 不监听 NodeChange/SetContent:初始化或回填时会把空内容写回 v-model,覆盖已加载的商品描述
+ editor.on("input change undo redo KeyUp", () => {
_this.hasChange = true;
- const content = editor.getContent();
- _this.$emit("update:modelValue", content);
- _this.$emit("input", content);
+ _this.emitContent(editor.getContent());
});
},
setup(editor) {
@@ -101,23 +114,38 @@ export default {
height:this.height
});
},
- setContent(value) {
- const editor = window.tinymce.get(this.tinymceId);
- if (!editor) {
- return;
+ applyContent(editor, content) {
+ if (!editor || !editor.initialized || !editor.dom) {
+ return false;
}
+ try {
+ editor.setContent(content);
+ return true;
+ } catch (e) {
+ console.warn("tinymce setContent failed", e);
+ return false;
+ }
+ },
+ setContent(value) {
const content = value || "";
this.hasChange = false;
- editor.setContent(content);
- this.$emit("update:modelValue", content);
- this.$emit("input", content);
+ if (!this.isEditorReady()) {
+ this.pendingContent = content;
+ return;
+ }
+ this.pendingContent = null;
+ this.applyContent(this.getEditor(), content);
+ this.emitContent(content);
},
getContent() {
- // 获取编辑器的内容
- return window.tinymce.get(this.tinymceId).getContent();
+ const editor = this.getEditor();
+ if (!editor || !editor.initialized) {
+ return this.pendingContent ?? this.bindValue ?? "";
+ }
+ return editor.getContent();
},
destroyTinymce() {
- const tinymce = window.tinymce.get(this.tinymceId);
+ const tinymce = this.getEditor();
if (tinymce) {
// 销毁编辑器实例