<template>
  <div class="system-auth-group">
    <div class="category-list">
      <div class="btns" style="display: flex; justify-content: space-between; margin-bottom: 20px">
        <el-button size="small" style="width: 125px" type="primary" icon="el-icon-edit" @click="showType = true"> 编辑分类 </el-button>
        <el-button size="small" style="width: 125px" type="success" icon="el-icon-plus" @click="onEditType(null)"> 添加分类 </el-button>
      </div>
      <el-menu :default-active="nowTypeId" @select="onSelectType">
        <el-menu-item :index="0">
          <div class="name" style="flex: 1">全部分类</div>
        </el-menu-item>
        <template v-for="type in typeList">
          <el-menu-item :key="type.id" :index="type.id">
            <div class="name" style="flex: 1">{{ type.typeName }}</div>
          </el-menu-item>
        </template>
      </el-menu>
    </div>
    <div class="right-wrapper">
      <div class="my-menu">
        <el-input v-model="searchName" size="mini" placeholder="输入名称查询" style="width: 200px" clearable></el-input>
        <el-button size="mini" type="primary" icon="el-icon-search" style="margin: 0 0 0 10px" @click="getData"> 查询 </el-button>
        <div style="flex: 1"></div>
        <el-button size="mini" plain type="success" icon="el-icon-plus" @click="onEdit(null)">添加权限组</el-button>
      </div>
      <div class="main">
        <div class="item" v-for="group of groupList" :key="group.id" :class="{ selected: selected == group.id }">
          <div class="name">
            <div>{{ group.permName }}</div>
            <div style="flex: 1"></div>
            <el-button size="mini" type="primary" plain icon="el-icon-setting" v-show="!isSelect && group.id" @click="goSetting(group)"> 权限设置 </el-button>
            <el-button size="mini" type="success" icon="el-icon-thumb" v-show="isSelect" @click="onSelect(group)"> 选择 </el-button>
            <el-button size="mini" type="primary" plain icon="el-icon-edit" @click="onEdit(group)"></el-button>
            <el-button v-show="group.id" size="mini" type="danger" plain icon="el-icon-delete" @click="onDel(group)"></el-button>
          </div>
          <div class="selected">
            <div class="tag" v-for="item of group.dpList" :key="item.id"><i class="el-icon-s-flag" style="color: #67c23a; margin-right: 5px"></i>{{ item.name }}</div>
            <div class="tag" v-for="item of group.roleList" :key="item.id"><i class="el-icon-user-solid" style="color: #e6a23c; margin-right: 5px"></i>{{ item.name }}</div>
            <div class="tag" v-for="item of group.userList" :key="item.id"><i class="el-icon-user" style="color: #909399; margin-right: 5px"></i>{{ item.name }}</div>
            <div class="tag" v-for="item of group.blackUserList" :key="item.id">
              <i class="el-icon-error" style="color: #909399; margin-right: 5px"></i>
              <span style="color: #f56c6c; text-decoration: line-through">{{ item.name }}</span>
            </div>
          </div>
        </div>
      </div>
      <el-pagination
        class="my-paging"
        @size-change="sizeChange"
        @current-change="getData"
        :current-page.sync="page.current"
        :page-sizes="[10, 20, 50, 100]"
        :page-size="page.size"
        background
        :total="page.total"
        layout="total, sizes, prev, pager, next, jumper"
      ></el-pagination>
    </div>
    <el-dialog title="分类管理" :visible.sync="showType" append-to-body width="600px">
      <el-table :data="typeList" border size="mini">
        <el-table-column label="分类名" prop="typeName"></el-table-column>
        <el-table-column label="排序号" prop="sortNum"></el-table-column>
        <el-table-column label="操作" width="180px" align="center">
          <template v-slot="{ row }">
            <el-button size="mini" type="primary" plain @click="onEditType(row)">编辑</el-button>
            <el-button size="mini" type="danger" plain @click="onDelType(row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>
    <el-dialog title="编辑分类" append-to-body :visible.sync="showTypeEdit" width="600px">
      <el-form size="mini" label-width="80px">
        <el-form-item label="分类名">
          <el-input v-model="typeForm.typeName"></el-input>
        </el-form-item>
        <el-form-item label="排序值">
          <el-input v-model="typeForm.sortNum" type="number"></el-input>
        </el-form-item>
      </el-form>
      <div class="btns" style="margin-top: 30px; display: flex; justify-content: space-evenly">
        <el-button size="mini" style="width: 100px">取消</el-button>
        <el-button size="mini" style="width: 100px" type="primary" @click="onEditTypeConfirm">确定</el-button>
      </div>
    </el-dialog>
    <el-dialog title="编辑权限组" append-to-body :visible.sync="show" width="800px" custom-class="auth-group-dialog">
      <el-form size="mini" label-width="85px">
        <el-form-item label="名称">
          <el-input v-model="form.permName"></el-input>
        </el-form-item>
        <el-form-item label="分类">
          <el-select v-model="form.typeId">
            <el-option v-for="item of typeList" :key="item.id" :label="item.typeName" :value="item.id"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="已选择项">
          <div class="selected">
            <div class="tag" v-for="(item, i) of form.dpList" :key="item.id">
              <i class="el-icon-s-flag" style="color: #67c23a; margin-right: 5px"></i>
              {{ item.name }}
              <i class="el-icon-close" @click="onQuickDel('dpList', item, i)"></i>
            </div>
            <div class="tag" v-for="(item, i) of form.roleList" :key="item.id">
              <i class="el-icon-user-solid" style="color: #e6a23c; margin-right: 5px"></i>
              {{ item.name }}
              <i class="el-icon-close" @click="onQuickDel('roleList', item, i)"></i>
            </div>
            <div class="tag" v-for="(item, i) of form.userList" :key="item.id">
              <i class="el-icon-user" style="color: #909399; margin-right: 5px"></i>
              {{ item.name }}
              <i class="el-icon-close" @click="onQuickDel('userList', item, i)"></i>
            </div>
            <div class="tag" v-for="(item, i) of form.blackUserList" :key="item.id">
              <i class="el-icon-error" style="color: #909399; margin-right: 5px"></i>
              <span style="color: #f56c6c; text-decoration: line-through">{{ item.name }}</span>
              <i class="el-icon-close" @click="onQuickDel('blackUserList', item, i)"></i>
            </div>
          </div>
        </el-form-item>
      </el-form>
      <el-tabs type="card" v-model="activeType" @tab-click="onSelectTab">
        <el-tab-pane name="dept">
          <span slot="label"><i class="el-icon-s-flag" style="color: #67c23a; margin-right: 5px"></i>部门</span>
          <div class="left">
            <el-tree
              ref="dept"
              :data="deptList"
              node-key="id"
              :props="{ label: 'title' }"
              default-expand-all
              show-checkbox
              check-strictly
              check-on-click-node
              :expand-on-click-node="false"
              @check-change="onDeptChange"
            ></el-tree>
          </div>
        </el-tab-pane>
        <el-tab-pane name="role">
          <span slot="label"><i class="el-icon-user-solid" style="color: #e6a23c; margin-right: 5px"></i>角色</span>
          <div class="left">
            <el-tree
              ref="role"
              :data="roleList"
              node-key="id"
              :props="{ label: 'title' }"
              default-expand-all
              show-checkbox
              check-strictly
              check-on-click-node
              :expand-on-click-node="false"
              @check-change="onRoleChange"
            ></el-tree>
          </div>
        </el-tab-pane>
        <el-tab-pane name="user">
          <span slot="label"><i class="el-icon-user" style="color: #909399; margin-right: 5px"></i>用户</span>
          <div class="left">
            <el-tree ref="user" :data="deptList" node-key="id" default-expand-all check-on-click-node :expand-on-click-node="false" @node-click="onUserChange"></el-tree>
          </div>
          <div class="right" style="padding: 10px">
            <el-checkbox v-for="(item, i) of userChecks" :key="i" v-model="item.select" @change="onSelectUser($event, item)">
              {{ item.label }}
            </el-checkbox>
          </div>
        </el-tab-pane>
        <el-tab-pane name="black">
          <span slot="label"><i class="el-icon-error" style="color: #909399; margin-right: 5px"></i>黑名单</span>
          <div class="left">
            <el-tree ref="black" :data="deptList" node-key="id" default-expand-all check-on-click-node :expand-on-click-node="false" @node-click="onBlackChange"></el-tree>
          </div>
          <div class="right" style="padding: 10px">
            <el-checkbox v-for="(item, i) of userChecks" :key="i" v-model="item.select" @change="onSelectBlackUser($event, item)">
              {{ item.label }}
            </el-checkbox>
          </div>
        </el-tab-pane>
        <el-tab-pane name="search">
          <div slot="label" style="display: flex; align-items: center">
            <el-input size="mini" v-model="searchKey" clearable @input="onSearch"></el-input>
            <el-button size="mini" type="primary">搜索</el-button>
          </div>
          <div class="left">
            <div class="name" @click="deptFold = !deptFold">
              <i class="el-icon-s-flag" style="color: #67c23a; margin-right: 5px"></i>部门
              <i class="el-icon-arrow-right" v-if="deptFold"></i>
              <i class="el-icon-arrow-down" v-else></i>
            </div>
            <div class="items" v-show="!deptFold">
              <el-checkbox v-for="(item, i) of deptSearched" :key="i" v-model="item.select" @change="onSelectDeptOrRole($event, item, 'dept')">
                {{ item.label }}
              </el-checkbox>
            </div>
            <div class="name" @click="roleFold = !roleFold">
              <i class="el-icon-user-solid" style="color: #e6a23c; margin-right: 5px"></i>角色
              <i class="el-icon-arrow-right" v-if="roleFold"></i>
              <i class="el-icon-arrow-down" v-else></i>
            </div>
            <div class="items" v-show="!roleFold">
              <el-checkbox v-for="(item, i) of roleSearched" :key="i" v-model="item.select" @change="onSelectDeptOrRole($event, item, 'role')">
                {{ item.label }}
              </el-checkbox>
            </div>
            <div class="name" @click="userFold = !userFold">
              <i class="el-icon-user" style="color: #909399; margin-right: 5px"></i>用户
              <i class="el-icon-arrow-right" v-if="userFold"></i>
              <i class="el-icon-arrow-down" v-else></i>
            </div>
            <div class="items" v-show="!userFold">
              <el-checkbox v-for="(item, i) of userSearched" :key="i" v-model="item.select" @change="onSelectUser($event, item)">
                {{ item.label }}
              </el-checkbox>
            </div>
            <div class="name" @click="blackFold = !blackFold">
              <i class="el-icon-error" style="color: #909399; margin-right: 5px"></i>黑名单
              <i class="el-icon-arrow-right" v-if="blackFold"></i>
              <i class="el-icon-arrow-down" v-else></i>
            </div>
            <div class="items" v-show="!blackFold">
              <el-checkbox v-for="(item, i) of blackSearched" :key="i" v-model="item.select" @change="onSelectBlackUser($event, item)">
                {{ item.label }}
              </el-checkbox>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
      <div class="btns">
        <el-button size="small" @click="show = false">取消</el-button>
        <el-button size="small" plain type="primary" @click="onSubmit">提交</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { getDeptTree } from '@/api/system/dept'
import { roleTree } from '@/api/newbi/app'
import { getList } from '@/api/system/user'
import { save, groupPage, groupDel, typeList, typeDel, typeSave } from '@/api/system/authGroup'
export default {
  props: ['selected', 'isSelect'],
  data() {
    return {
      groupList: [],
      deptList: [],
      roleList: [],
      userChecks: [],
      form: {},
      show: false,
      activeType: 'dept',
      searchName: '',
      showType: false,
      typeList: [],
      typeForm: {},
      showTypeEdit: false,
      nowTypeId: 0,
      page: { size: 10, current: 1, total: 0 },
      searchKey: '',
      deptSearched: [],
      roleSearched: [],
      userSearched: [],
      blackSearched: [],
      deptFold: false,
      roleFold: false,
      userFold: false,
      blackFold: false,
      roleListPlat: [],
      deptListPlat: [],
      userListPlat: []
    }
  },
  created() {
    this.getType()
    getDeptTree().then((res) => {
      getList(1, 10000).then((userRes) => {
        let users = userRes.data.data.records
        this.userListPlat = users.map((i) => ({ id: i.id, label: i.name }))
        users.forEach((item) => (item.depts = item.deptId.split(',')))
        let userListPlat = []
        let userList = res.data.data
        this.getPlat(userList, userListPlat)
        userListPlat.forEach((item) => {
          let id = item.id
          item.label = item.title
          item.list = users.filter((i) => i.depts.includes(id)).map((i) => ({ id: i.id, label: i.name, select: false }))
        })
        this.deptList = userList
        this.deptListPlat = userListPlat.map((i) => ({ id: i.id, label: i.title }))
      })
    })
    roleTree().then((res) => {
      let data = res.data.data
      let roleListPlat = []
      this.getPlat(data, roleListPlat)
      this.roleList = data
      this.roleListPlat = roleListPlat.map((i) => ({ id: i.id, label: i.title }))
    })
  },
  methods: {
    onQuickDel(type, item, index) {
      this.form[type].splice(index, 1)
      if (type == 'dpList') {
        this.$refs.dept.setCheckedKeys(this.form.dpList.map((i) => i.id))
        this.deptSearched.forEach((i) => i.id == item.id && (i.select = false))
      } else if (type == 'roleList') {
        this.$refs.role.setCheckedKeys(this.form.roleList.map((i) => i.id))
        this.roleSearched.forEach((i) => i.id == item.id && (i.select = false))
      } else if (type == 'userList') {
        this.userChecks.forEach((i) => i.id == item.id && (i.select = false))
        this.onSearch()
      } else if (type == 'blackUserList') {
        this.userChecks.forEach((i) => i.id == item.id && (i.select = false))
        this.onSearch()
      }
    },
    // 结果中选择部门或角色时
    onSelectDeptOrRole(status, item, type) {
      if (type == 'dept') {
        if (status) {
          this.form.dpList.push({ id: item.id, name: item.label })
        } else {
          let index = this.form.dpList.findIndex((i) => i.id == item.id)
          this.form.dpList.splice(index, 1)
        }
      } else if (type == 'role') {
        if (status) {
          this.form.roleList.push({ id: item.id, name: item.label })
        } else {
          let index = this.form.roleList.findIndex((i) => i.id == item.id)
          this.form.roleList.splice(index, 1)
        }
      }
    },
    // 搜索所有类型数据时
    onSearch() {
      let key = this.searchKey
      let { dpList, roleList, userList, blackUserList } = this.form
      let deptSearched = this.deptListPlat.filter((i) => i.label.includes(key))
      deptSearched.forEach((i) => (i.select = !!dpList.find((j) => j.id == i.id)))
      this.deptSearched = deptSearched
      let roleSearched = this.roleListPlat.filter((i) => i.label.includes(key))
      roleSearched.forEach((i) => (i.select = !!roleList.find((j) => j.id == i.id)))
      this.roleSearched = roleSearched
      let userSearched = this.userListPlat.filter((i) => i.label.includes(key))
      userSearched.forEach((i) => (i.select = !!userList.find((j) => j.id == i.id)))
      this.userSearched = userSearched
      let other = JSON.parse(JSON.stringify(this.userListPlat))
      let blackSearched = other.filter((i) => i.label.includes(key))
      blackSearched.forEach((i) => (i.select = !!blackUserList.find((j) => j.id == i.id)))
      this.blackSearched = blackSearched
    },
    goSetting(group) {
      this.$router.push(`/system/authGroupSetting?id=${group.id}&name=${group.permName}`)
    },
    sizeChange(size) {
      this.page.size = size
      this.getData()
    },
    onSelectType(index) {
      this.nowTypeId = index
      this.page.current = 1
      this.getData()
    },
    onDelType(type) {
      this.$confirm('是否删除此分类', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          typeDel({ id: type.id }).then((res) => {
            this.$message({ type: 'success', message: '已删除' })
            this.getType()
          })
        })
        .catch(() => {})
    },
    onEditTypeConfirm() {
      if (!this.typeForm.typeName) {
        return this.$message({ message: '请输入分类名', type: 'warning' })
      }
      typeSave(this.typeForm).then((res) => {
        this.$message({ message: '已保存', type: 'success' })
        this.getType()
        this.showTypeEdit = false
      })
    },
    onEditType(type) {
      if (type) {
        this.typeForm = { ...type }
      } else {
        this.typeForm = { typeName: '', sortNum: 0 }
      }
      this.showTypeEdit = true
    },
    getType() {
      typeList().then((res) => {
        this.typeList = res.data.data.sort((a, b) => (a.sortNum > b.sortNum ? 1 : -1))
        this.nowTypeId = 0
        this.getData()
      })
    },
    onSelect(group) {
      if (this.isSelect) {
        this.$emit('select', group.id, group.permName)
      }
    },
    onDel(group) {
      this.$confirm('是否删除此权限组', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          groupDel({ permId: group.id }).then((res) => {
            this.$message({ type: 'success', message: '已删除' })
            this.getData()
          })
        })
        .catch(() => {})
    },
    // 选择面板时
    onSelectTab({ name }) {
      if (name == 'user') {
        let node = this.$refs.user.getCurrentNode()
        if (node) {
          this.onUserChange(node)
        } else {
          this.userChecks = []
        }
      } else if (name == 'black') {
        let node = this.$refs.black.getCurrentNode()
        if (node) {
          this.onBlackChange(node)
        } else {
          this.userChecks = []
        }
      } else if (name == 'search') {
        this.onSearch()
      }
    },
    // 用户选择用户时
    onSelectUser(status, item) {
      if (status) {
        this.form.userList.push({ id: item.id, name: item.label })
      } else {
        let index = this.form.userList.findIndex((i) => i.id == item.id)
        this.form.userList.splice(index, 1)
      }
    },
    // 黑名单选择用户时
    onSelectBlackUser(status, item) {
      if (status) {
        this.form.blackUserList.push({ id: item.id, name: item.label })
      } else {
        let index = this.form.blackUserList.findIndex((i) => i.id == item.id)
        this.form.blackUserList.splice(index, 1)
      }
    },
    // 选择用户部门时
    onUserChange({ list }) {
      list.forEach((i) => {
        i.select = !!this.form.userList.find((j) => j.id == i.id)
      })
      this.userChecks = list
    },
    // 选择黑名单部门时
    onBlackChange({ list }) {
      list.forEach((i) => {
        i.select = !!this.form.blackUserList.find((j) => j.id == i.id)
      })
      this.userChecks = list
    },
    // 选择部门时
    onDeptChange() {
      this.$nextTick(() => {
        let nodes = this.$refs.dept.getCheckedNodes()
        this.form.dpList = nodes.map((i) => ({ id: i.id, name: i.title }))
      })
    },
    // 选择角色时
    onRoleChange() {
      this.$nextTick(() => {
        let nodes = this.$refs.role.getCheckedNodes()
        this.form.roleList = nodes.map((i) => ({ id: i.id, name: i.title }))
      })
    },
    getData() {
      let { size, current } = this.page
      let data = { current, size, permName: this.searchName }
      if (this.nowTypeId) {
        data.typeId = this.nowTypeId
      }
      groupPage(data).then((res) => {
        let { records, total } = res.data.data
        this.page.total = total
        this.groupList = records.map((i) => {
          let { dpList, roleList, userList, blackUserList } = JSON.parse(i.permJson)
          blackUserList = blackUserList || []
          return { ...i, dpList, roleList, userList, blackUserList }
        })
      })
    },
    onSubmit() {
      let { permName, dpList, roleList, userList, typeId, blackUserList } = this.form
      if (!permName || !typeId) {
        return this.$message({ type: 'warning', message: '请填写完整' })
      }
      let data = { permName, typeId, permJson: JSON.stringify({ dpList, roleList, userList, blackUserList }) }
      if (this.form.id || this.form.id === 0) {
        data.id = this.form.id
      }
      save(data).then((res) => {
        this.$message({ type: 'success', message: '已保存' })
        this.show = false
        this.getData()
      })
    },
    getPlat(source, target) {
      source.forEach((i) => {
        target.push(i)
        if (i.children && i.children.length) {
          this.getPlat(i.children, target)
        }
      })
    },
    onEdit(item) {
      if (item) {
        this.form = item
      } else {
        this.form = {
          permName: '',
          dpList: [],
          roleList: [],
          userList: [],
          blackUserList: [],
          typeId: this.nowTypeId || ''
        }
      }
      this.show = true
      this.$nextTick(() => {
        this.$refs.dept.setCheckedKeys(item ? item.dpList.map((i) => i.id) : [])
        this.$refs.role.setCheckedKeys(item ? item.roleList.map((i) => i.id) : [])
        this.$refs.user.setCheckedKeys(item ? item.userList.map((i) => i.id) : [])
        this.$refs.black.setCheckedKeys(item ? item.blackUserList.map((i) => i.id) : [])
      })
    }
  }
}
</script>
<style lang="scss">
.system-auth-group {
  height: 100%;
  overflow: hidden;
  display: flex;
  .category-list {
    flex: 0 0 260px;
    padding-top: 10px;
    padding-right: 10px;
    border-right: 1px solid #ccc;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    .el-menu {
      flex: 1;
      overflow-y: auto;
      .el-menu-item {
        padding: 0 5px 0 10px;
        display: flex;
        align-items: center;
        height: 50px;
        line-height: 50px;
        .name {
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
        }
      }
    }
  }
  .right-wrapper {
    flex: 1;
    padding: 10px 10px 0;
    display: flex;
    flex-direction: column;
    .my-menu {
      flex: 0 0 40px;
      display: flex;
      justify-content: space-between;
    }
    .main {
      flex: 1;
      overflow-y: auto;
    }
    .item {
      margin: 10px;
      border: 1px solid #dcdfe6;
      transition: all 0.2s;
      &:hover {
        border: 1px solid #409eff;
      }
      &.selected {
        border: 1px solid #409eff;
        .name {
          color: #409eff;
        }
      }
      .name {
        display: flex;
        align-items: center;
        padding: 0 20px;
        line-height: 40px;
        font-weight: 600;
        color: #666;
        font-size: 16px;
      }
      .selected {
        max-height: 100px;
        overflow-y: auto;
        padding: 5px;
        .tag {
          display: inline-block;
          margin: 5px;
          font-size: 14px;
          line-height: 16px;
        }
      }
    }
    .my-paging {
      padding: 10px;
      flex: 0 0 50px;
    }
  }
}
.auth-group-dialog {
  .selected {
    height: 100px;
    overflow-y: auto;
    border: 1px solid #dcdfe6;
    padding: 5px;
    .tag {
      display: inline-block;
      margin: 5px 10px;
      font-size: 14px;
      line-height: 16px;
      .el-icon-close {
        vertical-align: top;
        font-size: 10px;
        color: red;
        cursor: pointer;
      }
    }
  }
  .el-tab-pane {
    height: 300px;
    display: flex;
    .left,
    .right {
      flex: 1;
      overflow-y: auto;
      .name {
        line-height: 30px;
        font-size: 16px;
        cursor: pointer;
      }
      .el-checkbox {
        margin: 3px 15px;
        display: flex;
      }
    }
  }
  .btns {
    display: flex;
    justify-content: space-evenly;
    margin-top: 30px;
    .el-button {
      width: 80px;
    }
  }
}
</style>
