<template>
  <el-drawer title="数据权限" :visible="show" size="90%" :destroy-on-close="true" @close="close">
    <el-form ref="permission" :model="permission" label-width="100px">
      <el-form-item label="角色名称">
        {{ permission.roleName }}
      </el-form-item>
      <el-form-item label="角色代码">
        {{ permission.roleCode }}
      </el-form-item>
      <el-form-item label="权限范围">
        <el-select v-model="permission.dataScope">
          <el-option v-for="(item, index) in dataScopes" :key="index" :label="item" :value="index" />
        </el-select>
      </el-form-item>
      <el-form-item v-if="permission.dataScope === 1" label="数据权限">
        <el-table
          ref="departments"
          :data="departments"
          border
          fit
          height="650"
          highlight-current-row
          row-key="id"
          :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
          style="width: 99%;"
        >
          <el-table-column label="部门名称">
            <template slot-scope="scope">
              <el-checkbox v-model="scope.row.checked" :indeterminate="scope.row.indeterminate" @change="handleCheckAllChange(scope.row, $event)">
                {{ scope.row.name }}
              </el-checkbox>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
    </el-form>
    <el-row :gutter="20">
      <el-col :span="4" :offset="2">
        <el-select v-if="permission.dataScope === 1" v-model="showMode" @change="changeShowMode">
          <el-option
            v-for="(item, index) in showModes"
            :key="index"
            :label="item"
            :value="index"
          />
        </el-select>
      </el-col>
      <el-col :span="4" :offset="14">
        <el-button type="primary" @click="update">
          确 认
        </el-button>
        <el-button @click="close">
          取 消
        </el-button>
      </el-col>
    </el-row>
  </el-drawer>
</template>

<script>
import CrudRole from '@/api/role'
import { getAll } from '@/api/data_scope_department'

export default {
  name: 'DataPermission',
  data() {
    return {
      show: false,
      permission: {},
      dataScopes: ['全部数据权限', '自定义数据权限', '本部门数据权限', '本部门及下级数据权限', '仅本人数据权限'],
      departments: [],
      showMode: 0,
      showModes: ['合并所有', '展开所有', '全部勾选', '取消勾选'],
      checkedIds: new Set()
    }
  },
  mounted() {
    const that = this
    this.common.$on('openDataPermission', function(data) {
      that.open(data)
    })
  },
  created() {
    const that = this
    this.common.$on('openDataPermission', function(data) {
      that.open(data)
    })
    this.getDepartmentList()
  },
  methods: {
    open(data) {
      this.permission = data
      this.getAllDataScopeDepartment()
      this.show = true
    },
    close() {
      this.show = false
    },
    getAllDataScopeDepartment() {
      getAll({
        roleId: this.permission.id
      }).then(data => {
        data = data.map(row => row.departmentId)
        this.departments.forEach(permission => {
          if (permission.children.length > 0) {
            this.echoChildren(permission.children, data)
          } else {
            this.settingChecked(permission, data)
          }
        })
      })
    },
    getDepartmentList() {
      // 查询列表
      this.api({
        url: '/department/tree',
        method: 'get'
      }).then(data => {
        this.departments = data
      })
    },
    /**
     * 改变展示方式
     */
    changeShowMode(val) {
      switch (val) {
        case 0:
          this.departments.forEach(row => this.$refs.departments.toggleRowExpansion(row, false))
          break
        case 1:
          this.departments.forEach(row => this.$refs.departments.toggleRowExpansion(row, true))
          break
        case 2:
          this.departments.forEach(row => {
            row.checked = true
            row.indeterminate = false
            this.handleCheckAllChange(row, true)
          })
          break
        case 3:
          this.departments.forEach(row => {
            row.checked = false
            row.indeterminate = false
            this.handleCheckAllChange(row, false)
          })
          break
        default:
          break
      }
    },
    update() {
      console.log(this.checkedIds)
      console.log(Array.from(this.checkedIds))
      this.permission.dataScopeDepartmentIds = Array.from(this.checkedIds)
      console.log(this.permission)
      CrudRole.edit(this.permission).then(() => this.$notify.success('操作成功'))
    },
    handleCheckAllChange(val, checked) {
      if (checked) {
        this.checkedIds.add(val.id)
      } else {
        this.checkedIds.delete(val.id)
      }
      // 有下级去处理下级
      if (val.children.length > 0) {
        this.findChildren(val.children, checked)
      }
      // 处理上级
      if (val.parentId !== 0) {
        this.findParent(this.departments, val.parentId)
      }
      val.indeterminate = false
    },
    findChildren(list, checked) {
      list.forEach(children => {
        children.checked = checked
        children.indeterminate = false
        if (children.children.length > 0) {
          this.findChildren(children.children, checked)
        }
      })
    },
    findParent(list, parentId) {
      list.forEach(result => {
        let parentCheckedLength = 0
        let parentIndeterminateLength = 0
        // 对当前层级的上级操作
        if (result.id === parentId) {
          // 判断下级的状态，用来为父级的状态做判断
          result.children.forEach(children => {
            if (children.indeterminate) {
              parentIndeterminateLength++
            } else if (children.checked) {
              parentCheckedLength++
            }
          })
          result.checked = parentCheckedLength === result.children.length
          result.indeterminate = (parentIndeterminateLength > 0 || parentCheckedLength > 0) && parentCheckedLength < result.children.length

          if (result.checked) {
            this.checkedIds.add(result.id)
          } else {
            this.checkedIds.delete(result.id)
          }
          // 如果还有上级，继续操作
          if (result.parentId !== 0) {
            this.findParent(this.departments, result.parentId)
          }
        } else if (result.children.length > 0) {
          this.findParent(result.children, parentId)
        }
      })
    },
    echoChildren(list, optionsIds) {
      list.forEach(result => {
        if (result.children.length === 0) {
          this.settingChecked(result, optionsIds)
        } else {
          this.echoChildren(result.children, optionsIds)
        }
      })
    },
    settingChecked(result, optionsIds) {
      let matching = false
      optionsIds.forEach(optionsId => {
        if (result.id === optionsId) {
          result.checked = true
          matching = true
        }
      })
      if (matching) {
        this.handleCheckChange(result)
      }
    },
    handleCheckChange(val) {
      // 处理上级
      if (val.parentId !== 0) {
        this.findParent(this.departments, val.parentId)
      }
    }
  }
}
</script>

<style scoped>

</style>
