<template>
  <div>
    <!-- 
      模块type: introduce | form | forms | column | columns | history
     -->
    <el-dialog title="模块管理" :visible.sync="visible" :width="dialogWidth" custom-class="module"
      :close-on-click-modal="false" :before-close="close">
      <template v-if="data.type === 'introduce'">
        <el-table class="module-table" :data="data.list" header-align="center" row-key="id">
          <el-table-column type="index" width="60" label="序号" align="center"></el-table-column>

          <el-table-column v-for="(item, i) in data.forms" :key="i" :prop="item.prop" :label="item.label"
            min-width="130" align="center">
            <template slot-scope="scope">
              <div v-if="item.type === 'link' && scope.row.link" class="link-wrap">
                <span>{{ scope.row.link.linkName }}</span>
              </div>

              <template v-else-if="item.type === 'upload'">
                <img v-if="scope.row.pic" :src="scope.row.pic" class="upload-pic">
                <div class="upload-none" v-else>
                  <i class="el-icon-picture-outline"></i>
                </div>
              </template>
              <p v-else>{{ scope.row[item.prop] }}</p>
            </template>
          </el-table-column>

          <el-table-column label="操作" :width="data.sort ? 150 : 100" align="center">
            <template slot-scope="scope">
              <div class="flex a-center">
                <el-switch v-model="scope.row.isEnable" :active-value="1" :inactive-value="0">
                </el-switch>
                <i class="el-icon-edit-outline del" @click="editIntro(scope.row, scope.$index)"></i>
                <template v-if="data.sort">
                  <i v-if="scope.$index != data.list.length - 1" class="el-icon-bottom del"
                    @click="sort(1, scope.$index)"></i>
                  <i v-if="scope.$index" class="el-icon-top del" @click="sort(0, scope.$index)"></i>
                </template>
                <i class="el-icon-delete del" @click="delRow(data.list, scope.$index)"></i>
              </div>
            </template>
          </el-table-column>
        </el-table>
        <div class="plus">
          <i class="el-icon-circle-plus-outline" @click="addRow"></i>
        </div>
      </template>
      <el-form v-else-if="data.type === 'form' || data.type === 'forms'" ref="form" :model="data.form" :rules="rules"
        label-width="70px">
        <el-form-item v-for="(item, i) in data.forms" :key="i" :prop="item.prop" :label="item.label">
          <el-input v-if="item.type === 'input'" v-model="data.form[item.prop]" placeholder="请输入"
            maxlength="100"></el-input>
          <el-input v-if="item.type === 'textarea'" v-model="data.form[item.prop]" type="textarea" placeholder="请输入"
            maxlength="300"></el-input>
          <div v-if="item.type === 'upload' || item.type === 'video' || item.type === 'media'" class="uploader-wrap">
            <el-upload v-if="item.type === 'upload'" class="uploader" accept=".jpg,.png,.jpeg,.gif"
              :on-change="res => changeFile(res, data.form)" :show-file-list="false" :headers="headers"
              :action="api.upload">
              <img v-if="data.form.pic && !isVideo(data.form.mediaType)" :src="data.form.pic" class="avatar">
              <div class="uploader-default" v-else>
                <i class="el-icon-plus"></i>
                <p>上传图片</p>
              </div>
              <div slot="tip" class="el-upload__tip">
                <p>只支持.jpg,.png格式</p>
              </div>
            </el-upload>
            <el-upload v-if="item.type === 'video'" accept=".mp4,.mov,.avi"
              :on-success="res => uploadSuccess(res, data.form, item)" :before-remove="beforeRemove"
              :on-remove="(file, fileList) => handleRemove(file, fileList, data.form, item.prop)" :file-list="fileList"
              :headers="headers" :action="api.upload">

              <el-button>上传视频</el-button>
              <div slot="tip" class="el-upload__tip">
                <p>请上传大小1G以内的视频</p>
              </div>
            </el-upload>
            <!-- 图片视频都可上传 -->
            <el-upload v-if="item.type === 'media'" :on-success="res => uploadSuccess(res, data.form, item)"
              :before-remove="beforeRemove"
              :on-remove="(file, fileList) => handleRemove(file, fileList, data.form, item.prop)" :file-list="fileList"
              :headers="headers" :action="api.upload">
              <el-button>上传资源</el-button>
            </el-upload>
            <i v-if="!item.required" class="el-icon-delete del" @click="data.form[item.prop] = ''"></i>
          </div>
          <div v-if="item.type === 'link'" class="flex">
            <el-input class="m-r-10" v-model="data.form.link.linkName"></el-input>
            <el-button @click="toLink(data.form)">设置链接</el-button>
          </div>
          <Editor v-if="item.type === 'editor'" api-key='rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda'
            v-model="data.form[item.prop]" :init="editorConfig" />
        </el-form-item>
      </el-form>
      <el-form v-else-if="data.type === 'column' || data.type === 'columns'" ref="form" :model="data.form"
        :rules="columnRules" label-width="100px">
        <el-form-item prop="site" label="站点选择">
          <el-select v-model="data.form.site" @change="siteChange">
            <el-option v-for="item in $refs.link.sites" :key="item.id" :label="item.siteName" :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item prop="column" label="关联栏目">
          <el-cascader ref="links" v-model="data.form.column" :options="columns" :props="columnProps" clearable
            @change="columnChange"></el-cascader>
        </el-form-item>
        <el-form-item label="文章展示数量">
          <el-select v-model="data.form.articleNum">
            <el-option v-for="item in articleNums" :key="item.id" :label="item.name" :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="栏目标题">
          <el-radio v-model="data.form.columnTitle" :label="1" @change="columnTitleChange">默认读取关联栏目</el-radio>
          <div class="radio-wrap">
            <el-radio v-model="data.form.columnTitle" :label="2" @change="columnTitleChange"></el-radio>
            <el-input v-model="data.form.columnTitleCustom" :disabled="data.form.columnTitle == 1" size="small"
              maxlength="100"></el-input>
          </div>
        </el-form-item>
      </el-form>
      <template v-else-if="data.type === 'history'">
        <el-table class="module-table" :data="data.list" header-align="center" row-key="id">
          <el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
          <el-table-column prop="title" label="标题" min-width="140" align="center">
            <template slot-scope="scope">
              <el-input v-model="scope.row.title" placeholder="请输入" maxlength="100"></el-input>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="100" align="center">
            <template slot-scope="scope">
              <div class="flex a-center">
                <el-switch v-model="scope.row.isEnable" :active-value="1" :inactive-value="0">
                </el-switch>
                <i class="el-icon-edit-outline del" @click="editHistory(scope.row, scope.$index)"></i>
                <i class="el-icon-delete del" @click="delRow(data.list, scope.$index)"></i>
              </div>
            </template>
          </el-table-column>
        </el-table>
        <div class="plus">
          <i class="el-icon-circle-plus-outline" @click="addRow"></i>
        </div>
      </template>
      <span slot="footer" class="dialog-footer">
        <el-button @click="$emit('update:visible', false)">取消</el-button>
        <el-button type="primary" @click="moduleSubmit">确定</el-button>
      </span>
    </el-dialog>
    <Link ref="link" :data.sync="linkForm" :visible.sync="linkVisible" @linkSubmit="linkSubmit" />
    <Content :data.sync="data" :visible.sync="contentVisible" @contentSubmit="contentSubmit" />
    <History :data.sync="data" :list.sync="historyData" :form.sync="data.form" :visible.sync="historyVisible"
      @historySubmit="historySubmit" />

    <!-- 剪裁组件弹窗 -->
    <el-dialog title="图片裁剪" append-to-body :visible.sync="cropperModel" width="1100px" :close-on-click-modal="false">
      <Cropper ref="cropper" :img-file.sync="file" :is-upload="isUpload" :fixed="fixed" :fixedNumber.sync="fixedNumber"
        :autoCropWidth="autoCropWidth" :autoCropHeight="autoCropHeight" :dataType="data.type" @upload="customUpload" />
    </el-dialog>
  </div>
</template>

<script>
import Link from '@/components/modules/link'
import Content from '@/components/modules/content'
import History from '@/components/modules/history'
import Editor from '@tinymce/tinymce-vue'
import Setting from '@/setting'
import Util from '@/libs/util'
import 'tinymce-paragraphspacing'
import editorConfig from '@/components/editor'
import Cropper from '@/components/img-upload/Cropper'
import Axios from 'axios'
import { mapActions } from 'vuex'
export default {
  name: 'module',
  props: ['data', 'visible'],
  components: {
    Link,
    Content,
    Editor,
    History,
    Cropper
  },
  data () {
    return {
      site: this.$store.state.content.site,
      headers: {
        token: Util.local.get(Setting.tokenKey)
      },
      isVideo: Util.isVideo,
      dialogWidth: '800px',
      rules: {},
      linkVisible: false,
      linkForm: {},
      curIndex: 0,
      editorConfig,

      columnRules: {
        site: [
          { required: true, message: '请选择站点', trigger: 'change' }
        ],
        column: [
          { required: true, message: '请选择关联栏目', trigger: 'change' }
        ],
      },
      columns: [],
      articleNums: [
        {
          id: '',
          name: '默认'
        },
        {
          id: 4,
          name: '4'
        },
        {
          id: 3,
          name: '3'
        },
        {
          id: 2,
          name: '2'
        },
      ],
      fileList: [],
      columnProps: {
        checkStrictly: true,
        value: 'id',
        label: 'columnName'
      },

      contentVisible: false,
      curModule: 0,
      curData: {},

      historyVisible: false,
      historyData: [],

      cropperModel: false,
      isUpload: false,
      file: {}, // 当前被选择的图片文件
      fixed: false,
      fixedNumber: [0.88, 1],
      autoCropWidth: 480,
      autoCropHeight: 124,
    };
  },
  watch: {
    visible (open) {
      // 每次打开的时候处理参数
      open && this.handleForm()
    }
  },
  mounted () {
    this.handleForm()
  },
  methods: {
    ...mapActions("user", [
      'logout'
    ]),
    // 处理form表单参数
    handleForm () {
      const { type, forms, form, dialogWidth } = this.data
      this.fixed = false
      if (type === 'form' || type === 'forms') {
        forms.map(e => {
          if (e.type === 'video' || e.type === 'media') {
            this.fileList = [
              {
                name: form.fileName,
                url: form.video || e.pic
              }
            ]
          }
          if (e.type === 'upload' && e.width) {
            this.autoCropWidth = e.width
            this.autoCropHeight = e.height
            this.fixed = true
            this.fixedNumber = [e.width / e.height, 1]
          }
          // 加必填
          if (e.required) {
            this.rules[e.prop] = [
              {
                required: true,
                message: `请${e.type === 'input' ? '输入' : '选择'}${e.label}`,
                trigger: e.type === 'input' ? 'blur' : 'change'
              }
            ]
          }
        })
      }
      if (type === 'column' && form.articleNumOpt) {
        const nums = [
          {
            id: '',
            name: '默认'
          }
        ]
        for (let i = form.articleNumOpt; i > 1; i--) {
          nums.push({
            id: i,
            name: i
          })
        }
        this.articleNums = nums
      }
      form && form.site && this.siteChange(form.site)
      this.dialogWidth = dialogWidth || '800px'
    },
    // 站点切换回调
    siteChange (siteId) {
      this.$post(this.api.listWithTree, Util.rsa({
        siteId,
        columnName: '',
        templateId: '',
        typeId: '',
        isSort: 1
      })).then(({ data }) => {
        this.data.type === 'columns' || this.handleColumn(data)
        this.columns = data
      }).catch(err => { })
    },
    // 递归处理栏目
    handleColumn (data) {
      data.map(e => {
        // if (e.typeId === 2 || e.typeId === 3) e.disabled = true
        e.children.length ? this.handleColumn(e.children) : (delete e.children)
      })
    },
    // 栏目切换回调
    columnChange (val) {
      this.data.form.columnName = this.$refs.links.getCheckedNodes()[0].label
    },
    // 栏目标题切换回调
    columnTitleChange (val) {
      const { form } = this.data
      const checked = this.$refs.links.getCheckedNodes()
      form.columnName = val === 2 ? form.columnTitleCustom : (checked.length ? checked[0].label : '')
    },
    // 添加行
    addRow () {
      const { type } = this.data
      if (type === 'history') {
        this.data.list.push(JSON.parse(JSON.stringify(this.data.historyForm)))
      } else {
        this.editIntro(this.data.originForm, -1)
      }
    },
    close () {
      this.$emit('update:visible', false)
    },
    // 图片裁剪上传事件
    customUpload (data) {
      const formData = new FormData()
      formData.append('file', data, this.file.name)
      this.imgUpload(formData)
    },
    // 图片上传到服务器
    imgUpload (formData) {
      this.isUpload = true
      Axios({
        method: 'post',
        url: this.api.upload,
        data: formData,
        headers: {
          'Content-Type': 'multipart/form-data',
          token: Util.local.get(Setting.tokenKey)
        },
      }).then(({ data }) => {
        if (data.code === 401) {
          Util.errorMsg("登录过期，请重新登录");
          setTimeout(() => {
            this.$store.dispatch('user/logout')
          }, 1000);
          return false
        }
        this.$set(this.curForm, 'pic', data.url)
      }).catch(res => { })
      this.$refs.cropper.isDisabled = false
      this.isUpload = false
      this.cropperModel = false
    },
    // 图片改变钩子
    changeFile (file, form) {
      const { size, name } = file
      const ext = name.substring(name.lastIndexOf('.') + 1)
      if (!Util.isImg(ext)) {
        this.$message.error('请上传图片！')
        return false
      }
      if (size / 1024 / 1024 > 100) {
        this.$message.error('请上传100M以内的图片！')
        return false
      }
      this.file = file
      this.curForm = form
      this.cropperModel = true
      this.$nextTick(() => {
        this.$refs.cropper.updateImg({
          url: window.URL.createObjectURL(file.raw),
          size: file.size
        })
      })
    },
    // 上传成功
    uploadSuccess (res, row, item = {}) {
      if (res.code === 401) {
        Util.errorMsg("登录过期，请重新登录");
        setTimeout(() => {
          this.logout()
        }, 1000)
      } else {
        this.$set(row, item.type === 'video' ? 'video' : 'pic', res.url)
        this.$set(row, 'mediaType', res.original.substr(res.original.lastIndexOf('.') + 1))
        this.$set(row, 'fileName', res.original)
      }
    },
    beforeRemove (file, fileList) {
      return this.$confirm(`确定移除 ${file.name}？`);
    },
    handleRemove (file, fileList, form, prop) {
      form[prop] = ''
      form.fileName = ''
    },
    // 排序
    sort (type, i) {
      const item = this.data.list.splice(i, 1)[0]
      this.data.list.splice(i + (type ? 1 : -1), 0, item)
    },
    // 删除行（通用）
    delRow (list, i) {
      this.$confirm('确定要删除吗？', '提示', {
        type: 'warning'
      }).then(() => {
        list.splice(i, 1)
      }).catch(() => { })
    },
    // 展示链接设置
    toLink (row, i = 0) {
      if (!row.link.linkName) {
        row.link = {
          linkName: '无',
          connectionType: 1,
          columnId: [],
          articleId: '',
          linkAddress: '',
          site: this.site.id,
          otherColumnId: [],
          otherArticleId: '',
          isOpen: 1
        }
      }
      this.curIndex = i
      this.linkForm = row.link
      this.linkVisible = true
    },
    // 编辑内容
    editIntro (row, i = 0) {
      this.data.form = JSON.parse(JSON.stringify(row))
      if (!this.data.labelWidth) this.data.labelWidth = '60px'
      this.curModule = i
      this.contentVisible = true
    },
    // content设置提交
    contentSubmit () {
      this.contentVisible = false
      const { form } = this.data
      if (this.curModule === -1) {
        this.data.list.push(JSON.parse(JSON.stringify(this.data.form)))
      } else {
        const list = this.data.list[this.curModule]
        for (const i in form) {
          this.$set(list, i, form[i])
        }
      }
      this.data.form = JSON.parse(JSON.stringify(this.data.originForm))
    },
    // 链接设置提交
    linkSubmit () {
      const el = this.$refs.link
      const data = this.data.form ? this.data.form.link : this.data.list[this.curIndex].link
      let name
      // 站内链接
      if (data.connectionType === 1) {
        if (!data.columnId.length) return Util.errorMsg('请选择站内链接')
        // 如果选择了文章，则取文章标题作为链接名称，否则取栏目标题
        if (data.articleId) {
          const item = el.articles.find(e => e.id == data.articleId)
          name = item ? item.title : ''
        } else {
          name = el.$refs.column.getCheckedNodes()[0].pathLabels.join('/')
        }
      } else if (data.connectionType === 3) { // 其他站点链接
        if (!data.otherColumnId.length) return Util.errorMsg('请选择栏目')
        // 如果选择了文章，则取文章标题作为链接名称，否则取栏目标题
        if (data.otherArticleId) {
          const item = el.articles.find(e => e.id == data.otherArticleId)
          name = item ? item.title : ''
        } else {
          name = el.$refs.otherColumn.getCheckedNodes()[0].pathLabels.join('/')
        }
      } else { // 站外链接
        if (!data.linkAddress) return Util.errorMsg('请输入站外链接')
        name = data.linkAddress
      }
      data.linkName = name
      this.linkVisible = false
    },
    // 编辑history
    editHistory (row, i = 0) {
      this.historyData = row.list
      this.curModule = i
      this.historyVisible = true
    },
    // history设置提交
    historySubmit () {
      this.historyVisible = false
    },
    // 模块设置提交
    moduleSubmit () {
      this.$emit('moduleSubmit')
    },
  }
};
</script>
<style lang="scss" scoped>
.radio-wrap {
  display: flex;
  align-items: center;

  .el-input {
    width: 200px;
    margin-left: -40px;
  }
}
</style>