<template>
  <div class="rich-editor">
    <Toolbar
      v-if="withToolbar"
      :editor="instance"
      :defaultConfig="toolbarConfig"
      :mode="mode"
    />
    <Editor
      :style="{ height }"
      :modelValue="modelValue"
      :defaultConfig="computedEditorConfig"
      :mode="mode"
      @onChange="$emit('update:modelValue', $event.getHtml())"
      @onCreated="handleCreated"
    />
  </div>
</template>

<script>
import { Toolbar, Editor } from '@wangeditor/editor-for-vue'
import request from '@/core/utils/request'
export default {
  name: 'RichEditor',
  components: {
    Toolbar,
    Editor
  },
  props: {
    // 值
    modelValue: {
      type: String,
      required: true
    },
    // 编辑器高度
    height: {
      default: null
    },
    // 输入提示文案
    placeholder: {
      default: '请输入'
    },
    // 编辑器模式
    mode: {
      default: 'simple'
    },
    // 是否展示工具栏
    withToolbar: {
      default: true
    },
    // 工具栏配置，详见https://www.wangeditor.com/v5/toolbar-config.html#toolbarkeys
    toolbarConfig: {
      type: Object,
      default () {
        return {}
      }
    },
    // 编辑器配置
    editorConfig: {
      type: Object,
      default () {
        return {}
      }
    }
  },
  data () {
    return {
      instance: null,
    }
  },
  computed: {
    // 计算编辑器配置
    computedEditorConfig () {
      return {
        placeholder: this.placeholder,
        scroll: false,
        ...this.editorConfig
      }
    }
  },
  methods: {
    // 编辑器创建完成
    handleCreated (editor) {
      this.instance = Object.seal(editor)
      this.$emit('created', editor)
    },
    // 获取文本内容
    getText () {
      return this.instance.getText()
    },
    // 获取文章摘要
    getDigest (length = 200) {
      let digest = this.getText().substring(0, length).trim()
      // 去掉空行
      digest = digest
        .split('\n')
        .map(line => line.trim())
        .join('')
      // 防止断义
      // - 如果存在句号，则截取到句号
      if (digest.indexOf('。') > -1) {
        digest = digest.substring(0, digest.lastIndexOf('。') + 1)
      }
      return digest
    },
    /**
     * 启用图片上传，详见https://www.wangeditor.com/v5/menu-config.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8A%9F%E8%83%BD
     *
     * @param url 上传地址
     * @param maxFileSize 最大上传文件大小，单位：M
     * @param allowedFileTypes 允许上传的文件类型
     * @returns this
     */
    enableImageUpload ({
      url = '/resource/oss/upload/image',
      maxFileSize = 2,
      allowedFileTypes = ['image/*']
    }) {
      this.getConfig().MENU_CONF.uploadImage = {
        // 允许选择的文件类型
        allowedFileTypes: allowedFileTypes,
        // 自定义上传
        customUpload: async (file, insertFn) => {
          // 验证图片大小
          if (file.size > maxFileSize * 1024 * 1024) {
            this.$tip.warning('图片大小不能超过' + maxFileSize + 'M')
            return
          }
          // 执行文件上传
          const formData = new FormData()
          formData.append('file', file)
          request.post(url, formData, {
            headers: {
              'Content-Type': 'multipart/form-data;charset=UTF-8'
            }
          })
            .then(data => {
              // 插入文章
              insertFn(this.$getImageURL(data.fileKey), data.originalFilename || '', this.$getImageURL(data.fileKey))
            })
            .catch(e => {
              this.$tip.apiFailed(e)
            })
        }
      }
      return this
    },
    // 获取图片集
    getImages () {
      return [...this.$el.querySelectorAll('img')].map(node => node.getAttribute('src'))
    },
    // 获取配置
    getConfig () {
      return this.instance.getConfig()
    }
  },
  // 组件销毁时，销毁编辑器
  beforeUnmount () {
    if (this.instance == null) {
      return
    }
    this.instance.destroy()
  }
}
</script>

<style src="@wangeditor/editor/dist/css/style.css"></style>
<style lang="scss">
.rich-editor {
  width: 100%;
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  font-size: 16px;
  & > div {
    // 工具栏
    &:first-of-type {
      flex-shrink: 0;
      border-bottom: 1px solid #e0e0e0;
    }
    // 编辑器
    &:last-of-type {
      flex-grow: 1;
      overflow-y: auto;
    }
  }
}
</style>
