<template>
  <el-dialog :visible.sync="visible" :before-close="cancelDialog">
    <el-divider />
    <label slot="title" style="float: left;">{{ dialogTitle }}</label>

    <el-row>
      <el-form ref="form" :model="form" :rules="formRules" label-suffix="：" label-width="100px">
        <el-form-item label="角色名称" prop="name">
          <el-input v-model.trim="form.name" placeholder="请输入角色名称" clearable />
        </el-form-item>
        <el-form-item label="数据权限" prop="deptIds">
          <el-cascader
            ref="dTree"
            v-model="deptIds"
            :options="options"
            :props="{ expandTrigger: 'hover',multiple: true }"
            :show-all-levels="false"
            clearable
          />
        </el-form-item>
        <el-form-item label="备注" prop="remarks">
          <el-input v-model.trim="form.remarks" placeholder="请输入备注" clearable />
        </el-form-item>
      </el-form>
    </el-row>

    <div slot="footer" class="dialog-footer">
      <el-divider />
      <el-button @click="cancelDialog">取 消</el-button>
      <el-button type="primary" @click="handleSave">确 定</el-button>
    </div>
  </el-dialog>
</template>

<script>
import roleApi from '@/api/platform/roleApi'
import deptApi from '@/api/platform/deptApi'

export default {
  name: 'EditRoleDialog',
  props: {
    dialogTitle: {
      type: String,
      default: () => {
        return ''
      }
    },
    visible: {
      type: Boolean,
      default: false
    },
    form: {
      type: Object,
      default: () => {
        return {
          id: '',
          name: '',
          deptIds: [],
          remarks: ''
        }
      }
    }
  },
  data() {
    return {
      formRules: {
        name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }]
      },
      options: [],
      deptIds: [], // 数据权限部门
      nodeIds: [] // 叶子节点
    }
  },
  watch: {
    visible(val) {
      if (val === true) {
        this.form.deptIds.forEach(item => {
          this.nodeIds = []
          this.getLeafes(this.options, item)
          this.nodeIds.forEach(item => {
            this.deptIds.push(this.getNodePathArray(this.options, item, []))
          })
        })
      }
    }
  },
  mounted() {
    deptApi.nodes().then(data => {
      this.options = data
    })
  },
  methods: {
    /**
     * 查找某个节点的所有子节点
     * data：需要查找的节点树，id：节点的id ;从该节点开始查找其子节点中的所有叶子节点
     */
    getLeafes(data, id) {
      for (let i = 0; i < data.length; i++) {
        const element = data[i]
        // 命中节点id
        if (element.value === id) {
          // 判断是否存在子节点，又则继续查找其子节点的叶子节点
          if (element.children && typeof (element.children) === 'object') {
            // 查找叶子节点
            this.parseTreeJson(element.children)
          } else { // 不存在子节点则该节点为叶子节点
            this.nodeIds.push(element.value)
            return
          }
        } else {
          // 如果存在子节点，则继续查找其子节点的所有子节点
          if (element.children && typeof (element.children) === 'object') {
            // 继续遍历子节点查找当前节点
            this.getLeafes(element.children, id)
          }
        }
      }
    },
    /**
     * 查找nodes节点的所有叶子节点
     */
    parseTreeJson(nodes) {
      for (let i = 0; i < nodes.length; i++) {
        const element = nodes[i]
        // 判断是否存在子节点，则继续查找其子节点的叶子节点
        if (element.children && typeof (element.children) === 'object') {
          this.parseTreeJson(element.children)
        } else {
          // 把叶子节点放入数组中
          this.nodeIds.push(element.value)
        }
      }
    },
    /**
     * 根据节点树（data）,节点id，查找节点节点路径，以数组返回。如节点路径为1-2，则返回['1','2']
     * indexArray在使用时传入空数组即可
     */
    getNodePathArray(data, id, indexArray) {
      const arr = Array.from(indexArray)
      for (let i = 0, len = data.length; i < len; i++) {
        arr.push(data[i].value)
        if (data[i].value === id) {
          return arr
        }
        const children = data[i].children
        if (children && children.length) {
          const result = this.getNodePathArray(children, id, arr)
          if (result) {
            return result
          }
        }
        arr.pop()
      }
      return false
    },
    getCheckedDept() {
      // 获取选中的节点（不包括半选中的节点）
      let c = this.$refs.dTree.getCheckedNodes()
      // 实现效果：如果子节点的父节点被选中（父节点的子节点元素被全选），则获取父节点消息，如果没有全部选中，则获取子节点
      // 实现原理：如果节点有父节点且父节点被选中了，那么这个父节点就是为全选的状态的，使用数组过滤，可得出结果
      c = Array.from(c).filter(item => !(item.parent && item.parent.checked))
      return c
    },
    cancelDialog() {
      this.form = {
        id: '',
        name: '',
        deptIds: [],
        remarks: ''
      }
      this.$refs['form'].resetFields()
      this.deptIds = []
      this.nodeIds = []
      this.$emit('cancelDialog', false)
    },
    handleSave() {
      this.$refs['form'].validate((valid) => {
        if (!valid) {
          return
        }
        const nodes = this.getCheckedDept()
        const mForm = {
          id: this.form.id,
          name: this.form.name,
          deptIds: [],
          remarks: this.form.remarks
        }
        Array.from(nodes).forEach(node => {
          mForm.deptIds.push(node.data.value)
        })
        roleApi.saveOrUpdate(mForm).then(data => {
          this.$refs['form'].resetFields()
          this.deptIds = []
          this.nodeIds = []
          this.$emit('cancelDialog', false)
          this.$emit('refresh')
        })
      })
    }
  }
}

</script>
<style>
</style>
