
<template>
  <div class="editor">
    <div id="editorContent"></div>
    <!-- <button type="button" class="btn" @click="getEditorData">获取当前内容</button> -->
    <!-- <h3>内容预览</h3> -->
    <!-- <textarea name="" id="" cols="170" rows="20" readonly v-model="editorData"></textarea> -->
  </div>
</template>

<script>
// 引入 wangEditor
import wangEditor from 'wangeditor'
import axios from 'axios'
import qs from 'qs'
import load from '@/utils/loading'
import {
  getToken
} from '@/utils/auth'
export default {
  data() {
    return {
      editor: null,
      editorData: ''
    }
  },
  props: {
    value: { // 组件状态
    	type: String
    },
  },
  mounted() {
    const editor = new wangEditor(`#editorContent`)
    // 默认情况下，显示所有菜单
    editor.config.menus = [
        'head',
        'bold',
        'fontSize',
        'fontName',
        'italic',
        'underline',
        'strikeThrough',
        'indent',
        'lineHeight',
        'foreColor',
        'backColor',
        // 'link',
        'list',
        'justify',
        'quote',
        // 'emoticon',
        'image',
        // 'video',
        'table',
        // 'code',
        'splitLine',
        'undo',
        'redo',
    ]
    // 最大上传图片数
    editor.config.uploadImgMaxLength = 1
    editor.config.zIndex = 500
    // 限制图片大小
    // editor.config.uploadImgMaxSize = 2 * 1024 * 1024
    // 配置 onchange 回调函数，将数据同步到 vue 中
    editor.config.onchange = (newHtml) => {
       this.editorData = newHtml
       this.$emit('input', newHtml)
    }
    // console.log(editor.txt.eventHooks)
    // editor.txt.eventHooks.clickEvents.push(() => {
    //   return false
    // })
    // editor.txt.eventHooks.imgClickEvents.push(() => {

    // })
    // editor.config.uploadImgServer = '/api-web/uploadFile'
    editor.config.customUploadImg = async (resultFiles, insertImgFn) => {
        // resultFiles 是 input 中选中的文件列表
        // insertImgFn 是获取图片 url 后，插入到编辑器的方法
        console.log(insertImgFn)
        const file = resultFiles[0]
        const imageType = {
          "image/png": true,
          "image/jpeg": true
        };
        const isImage = imageType[file.type];
        const isLt2M = file.size / 1024 / 1024 < 2;
        if (!isImage) {
          this.$message.error("只能上传图片格式!");
        }
        if (!isLt2M) {
          this.$message.error("上传图片大小不能超过 2M!");
        }
        if(isImage && isLt2M) {
          load.startLoading()
          let form = new FormData()
          form.append('file', file)
          await axios({
            method: 'post',
            headers: {
                Authorization: getToken()
            },
            data: form,
            url: '/api-web/uploadFile',
          }).then(res => {
            const result = res.data
            if(result.code == 200) {
              // 上传图片，返回结果，将图片插入到编辑器中
              insertImgFn(result.data.url)
            }
          })
          load.endLoading()
        }
    }

    // 创建编辑器
    editor.create()
    this.editor = editor
  },
  methods: {
    getEditorData() {
      // 通过代码获取编辑器内容
      let data = this.editor.txt.html()
      this.$emit('getEditorData', data)
      // alert(data)
    }
  },
  watch: {
    value(newValue) {
      console.log(newValue)
      this.editor.txt.html(newValue)
    }
  },
  beforeDestroy() {
    // 调用销毁 API 对当前编辑器实例进行销毁
    this.editor.destroy()
  }
}

</script>

<style lang="scss">
  .home {
    margin: auto;
    position: relative;
    .btn {
      position: absolute;
      right: 0;
      top: 0;
      padding: 5px 10px;
      cursor: pointer;
    }
    h3 {
      margin: 30px 0 15px;
    }
  }
</style>
<!-- <template>
  <div class="editor">
    <quill-editor class="ql-editor" v-model="content" ref="myQuillEditor" :options="editorOption" @change="onEditorChange($event)"></quill-editor>

    <el-upload class="ivu-upload" :show-upload-list="false" :headers="headers" :on-success="handleSuccess" accept=".jpg, .jpeg, .png"
      :max-size="2048" multiple action="/api-web/uploadFile">
      <Button icon="ios-cloud-upload-outline"></Button>
    </el-upload>

    <el-dialog title="插入视频" width="500px" :visible.sync="dialogFormVisible">
      <el-form :model="dialogForm" ref="diologForm" :rules="dialogFormRules">
        <el-form-item label="封面图地址" label-width="90px">
          <el-upload class="avatar-uploader" style="line-height: 0;display: inline-block" action="/api-web/uploadFile"
            :headers="headers" :show-file-list="false" v-loading="uploadImgLoading" accept=".jpg, .jpeg, .png"
            :on-success="handleImgSuccess" :on-error="handleUploadImgError" :before-upload="beforeImgUpload">
            <img v-if="dialogForm.poster" :src="dialogForm.poster" class="avatar" />
            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
          </el-upload>
        </el-form-item>
        <el-form-item label="视频类型" label-width="90px">
          <el-radio-group v-model="formRadio">
            <el-radio :label="1">外部链接</el-radio>
            <el-radio :label="2">上传</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item v-if="formRadio == 1" label="视频地址" label-width="90px" prop="url">
          <el-input v-model="dialogForm.url" style="width: 100%;" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item v-if="formRadio == 2" label="上传视频" label-width="90px" prop="videoUrl">
          <el-upload class="upload-demo" style="display: inline-block" v-loading="uploadLoading" action="/api-web/uploadFile"
            :before-upload="beforeUpload" :on-success="handleUploadSuccess" :on-error="handleUploadError"
            :show-file-list="false" accept=".mp4" :file-list="fileList" :on-exceed="handleExceed">
            <video style="width: 120px; height: 120px" v-if="dialogForm.videoUrl" type="video/mp4" preload="auto" :src="dialogForm.videoUrl"></video>
            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
          </el-upload>
          <p class="imageSize">只能上传mp4文件, 且不超过100M</p>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="onVideoComfirm('diologForm')">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
  import {
    getToken
  } from "@/utils/auth";
  import "quill/dist/quill.core.css";
  import "quill/dist/quill.snow.css";
  import "quill/dist/quill.bubble.css";
  import Quill from "quill";
  import {
    quillEditor
  } from "vue-quill-editor";
  // 工具栏配置
  const toolbarOptions = [
    ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
    ["blockquote", "code-block"], // 引用  代码块
    [{ header: 1 }, { header: 2 }], // 1、2 级标题
    [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表
    [{ script: "sub" }, { script: "super" }], // 上标/下标
    [{ indent: "-1" }, { indent: "+1" }], // 缩进
    // [{'direction': 'rtl'}],                         // 文本方向
    [{ size: ["small", false, "large", "huge"] }], // 字体大小
    [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
    [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
    [{ font: [] }], // 字体种类
    [{ align: [] }], // 对齐方式
    ["clean"], // 清除文本格式
    ["image", "video"] // 链接、图片、视频
    // ["link", "image", "video"] // 链接、图片、视频
  ];
  // 标题
  const titleConfig = {
    "ql-bold": "加粗",
    "ql-color": "颜色",
    "ql-font": "字体",
    "ql-code": "插入代码",
    "ql-italic": "斜体",
    // 'ql-link': '添加链接',
    "ql-background": "背景颜色",
    "ql-size": "字体大小",
    "ql-strike": "删除线",
    "ql-script": "上标/下标",
    "ql-underline": "下划线",
    "ql-blockquote": "引用",
    "ql-header": "标题",
    "ql-indent": "缩进",
    "ql-list": "列表",
    "ql-align": "文本对齐",
    "ql-direction": "文本方向",
    "ql-code-block": "代码块",
    "ql-formula": "公式",
    "ql-image": "图片",
    "ql-video": "视频",
    "ql-clean": "清除字体样式",
    "ql-upload": "文件"
  };

  // 这里引入修改过的video模块并注册
  import Video from "@/views/quill/video.js";
  import dayjs from 'dayjs'
  Quill.register(Video, true);
  export default {
    name: 'editor',
    components: { quillEditor },
    data() {
      return {
        content: null,
        headers: {
          Authorization: getToken()
        },
        dialogFormVisible: false,
        dialogForm: {
          poster: null,
          url: null,
          videoUrl: null
        },
        uploadLoading: false,
        uploadImgLoading: false,
        fileList: [],
        dialogFormRules: {
          url: [{ required: true, message: "请输入视频地址", trigger: "blur" }],
          videoUrl: [{ required: true, message: "请上传视频", trigger: 'blur' }]
        },
        formRadio: 1,
        editorOption: {
          placeholder: "请输入内容",
          modules: {
            toolbar: {
              container: toolbarOptions,
              handlers: {
                image: function(value) {
                  if (value) {
                    // 调用iview图片上传
                    document.querySelector(".ivu-upload .el-upload").click();
                  } else {
                    this.quill.format("image", false);
                  }
                },
                video: function(value) {
                  if (value) {
                    that.dialogFormVisible = true;
                    let editor = that.$refs.myQuillEditor.quill;
                    // 光标所在位置
                    that.editorIndex = editor.getSelection().index;
                  } else {
                    this.quill.format("image", false);
                  }
                }
              }
            }
          }
        },
      }
    },
    methods: {
      onEditorChange({
        quill,
        html,
        text
      }) {
        this.form.content = html;
      },
      onVideoComfirm (formName) {
        this.$refs[formName].validate(valid => {
          if (valid) {
            let dialogForm = this.dialogForm;
            // 获取富文本组件实例
            let quill = this.editor;
            // 插入图片，res为服务器返回的图片链接地址
            const params = {
              poster: dialogForm.poster,
              url: this.formRadio == 1 ? dialogForm.url : dialogForm.videoUrl,
            }
            quill.insertEmbed(this.editorIndex, "video", params);
            // 调整光标到最后
            quill.setSelection(this.editorIndex + 1, { preload: false });

            this.dialogFormVisible = false;
            this.dialogForm = {
              poster: null,
              url: null,
              videoUrl: null
            };
          } else {
            return false;
          }
        });
      },
      handleSuccess (res) {
        // 获取富文本组件实例
        let quill = this.editor;
        // 如果上传成功
        if (res.code) {
          // 获取光标所在位置
          let length = quill.getSelection().index;
          // 插入图片，res为服务器返回的图片链接地址
          quill.insertEmbed(length, "image", res.data.url);
          // 调整光标到最后
          quill.setSelection(length + 1);
        } else {
          // 提示信息，需引入Message
          this.$message.error("图片插入失败");
        }
      },
      addQuillTitle () {
        const oToolBar = document.querySelector(".ql-toolbar"),
          aButton = oToolBar.querySelectorAll("button"),
          aSelect = oToolBar.querySelectorAll("select");
        aButton.forEach(function (item) {
          if (item.className === "ql-script") {
            item.value === "sub" ? (item.title = "下标") : (item.title = "上标");
          } else if (item.className === "ql-indent") {
            item.value === "+1"
              ? (item.title = "向右缩进")
              : (item.title = "向左缩进");
          } else {
            item.title = titleConfig[item.classList[0]];
          }
        });
        aSelect.forEach(function (item) {
          item.parentNode.title = titleConfig[item.classList[0]];
        });
      },
      handleUploadImgError(file) {
        this.uploadImgLoading = false
        this.$message.error('上传失败')
      },
      handleImgSuccess(res, file) {
        this.uploadImgLoading = false
        this.dialogForm.poster = res.data.url
      },
      beforeImgUpload(file) {
        const imageType = {
          "image/png": true,
          "image/jpeg": true
        };
        const isImage = imageType[file.type];
        const isLt2M = file.size / 1024 / 1024 < 2;
        console.log(isImage, isLt2M)
        if (!isImage) {
          this.$message.error("只能上传图片格式!");
        }
        if (!isLt2M) {
          this.$message.error("上传图片大小不能超过 2MB!");
        }
        if (isImage && isLt2M) {
          this.uploadImgLoading = true
        }
        return isImage && isLt2M;
      },
      handleAvatarSuccess(res, file) {
        this.form.coverImage = res.data.url;
      },
      beforeAvatarUpload(file) {
        const imageType = {
          "image/png": true,
          "image/jpeg": true
        };
        const isImage = imageType[file.type];
        const isLt2M = file.size / 1024 / 1024 < 2;

        if (!isImage) {
          this.$message.error("只能上传图片格式!");
        }
        if (!isLt2M) {
          this.$message.error("上传图片大小不能超过 2M!");
        }
        return isImage && isLt2M;
      },
      beforeUpload(file) {
        // const isJPG = file.type === 'image/jpeg';
        const isLt2M = file.size / 1024 / 1024 < 100;

        //   if (!isJPG) {
        //     this.$message.error('上传头像图片只能是 JPG 格式!');
        //   }
        if (!isLt2M) {
          this.$message.error('上传视频大小不能超过 100MB!');
        }
        this.uploadLoading = true
        return isLt2M;
      },
      handleUploadError(file) {
        this.uploadLoading = false
        this.$message.error('上传视频失败')
      },
      handleUploadSuccess(file, fileList) {
        this.uploadLoading = false
        this.$message.success('上传视频成功')
        this.dialogForm.videoUrl = file.data.url;
      },
      handleExceed(files, fileList) {
        this.$message.error('您已上传过视频')
      }
    },
    computed: {
      editor() {
        return this.$refs.myQuillEditor.quill;
      }
    }
  }
</script>

<style>
  /deep/.ql-editor {
    min-height: 300px;
    padding: 0;
  }

  /deep/.ql-container .ql-editor {
    max-height: 500px;
  }

  .el-button--primary {
    background: #14928a;
    border-color: #14928a;
    color: #fff;

    &:hover,
    &:active,
    &:focus {
      background: #14928a;
      border-color: #14928a;
      color: #fff;
    }
  }
</style>
 -->
