<template>
  <div class="app-container">
    <el-button type="primary" @click="handleAddRole" v-if="companyId != ''">新建角色</el-button>

    <el-table :data="rolesList" style="width: 100%;margin-top:30px;" border>
      <el-table-column align="center" label="序号" width="80">
        <template slot-scope="scope">
          {{
            (roleQuery.pageNum - 1) * roleQuery.pageSize + scope.$index + 1
          }}
        </template>
      </el-table-column>
      <el-table-column align="center" label="角色名称" width="220">
        <template slot-scope="scope">
          {{ scope.row.rlName }}
        </template>
      </el-table-column>
      <el-table-column align="header-center" label="角色描述">
        <template slot-scope="scope">
          {{ scope.row.rlDesc }}
        </template>
      </el-table-column>
      <el-table-column align="center" label="操作">
        <template slot-scope="scope">
          <el-button type="primary" size="small" @click="handleEdit(scope)" >编辑角色信息和分配角色路由</el-button>
          <el-button type="danger" size="small" @click="handleDelete(scope)" >删除角色</el-button>
        </template>
      </el-table-column>
    </el-table>

    <div class="footer">
      <el-pagination
        :current-page.sync="roleQuery.pageNum"
        :page-size="roleQuery.pageSize"
        layout="total, prev, pager, next"
        :total="total"
        @current-change="handleCurrentChange"
      />
    </div>

    <el-dialog :visible.sync="dialogVisible" :title="dialogType">
      <el-form :model="role" label-width="80px" label-position="left">
        <el-form-item label="角色名称">
          <el-input v-model="role.rlName" placeholder="角色名称" />
        </el-form-item>
        <el-form-item label="角色描述">
          <el-input
            v-model="role.rlDesc"
            :autosize="{ minRows: 2, maxRows: 4}"
            type="textarea"
            placeholder="角色描述"
          />
        </el-form-item>
        <el-form-item label="路由树">
          <el-tree
            ref="tree"
            :check-strictly="checkStrictly"
            :data="routesData"
            :props="defaultProps"
            @check="checkTree"
            show-checkbox
            default-expand-all
            node-key="id"
            class="permission-tree"
          />
        </el-form-item>
      </el-form>
      <div style="text-align:right;">
        <el-button type="danger" @click="dialogVisible=false">取消</el-button>
        <el-button type="primary" @click="confirmRole">提交</el-button>
      </div>
    </el-dialog>
  </div>
</template>



<script>
import path from 'path'
import { deepClone } from '@/utils'
import { getRoles,addRole,deleteRole, updateRole} from '@/api/role'
import { getRoutes} from '@/api/auth'

const defaultRole = {
  rlId: 0,
  rlName: '',
  rlDesc: '',
  routes: [],
  companyId:'',
}

export default {
  data(){
    return{
      roleQuery: {
        companyId: null,
        pageNum: 1,
        pageSize: 10
      },
      total: 0,
      role: Object.assign({}, defaultRole),
      rolesList:[],
      routes:null,

      dialogType:"新增角色",
      dialogVisible:false,

      checkStrictly: true,// 父子节点 checkbox的选择是否关联
      defaultProps: {                       // 角色树
        children: 'children',
        label: 'title'
      },
      companyId:'',
    }
  },
  created() {
    this.roleQuery.companyId = this.$store.getters.companyId
    this.companyId=this.$store.getters.companyId;
    this.getRoutes()
    this.getRoles()
  },
  computed: {
    routesData() {
      return this.routes
    },
  },
  methods:{
    //handleCurrentChange
    handleCurrentChange(val){
      this.roleQuery.pageNum = val
      this.getRoles()
    },
    //获取角色
    getRoles() {
      getRoles (this.roleQuery).then((res)=>{
        if(res.status == "success"){
          this.rolesList = res.data.list
          this.total = res.data.total
        }else{
          this.$message.error(res.data)
        }
      }).catch((error)=>{
        this.$message.error("查询数据失败")
      })
    },
    //获取路由
    getRoutes() {
      getRoutes().then((res)=>{
        if(res.status == "success"){
          this.serviceRoutes = res.data
          this.routes = this.generateRoutes(res.data)
        }
      })
    },
    //处理路由数据
    generateRoutes(routes, basePath = '/') {
      const res = []
      for (let route of routes) {
        if(route.id != 1){
          const data = {
            path: path.resolve(basePath, route.path),
            title: route.meta && (route.menuExplain ? `${route.meta.title}（${route.menuExplain}）`: route.meta.title),
            id: route.id
          }
          if (route.children.length>0) {
            data.children = this.generateRoutes(route.children, data.path)
          }
          res.push(data)
        }
      }
      return res
    },
    //新增角色
    handleAddRole(){
      this.role = Object.assign({}, defaultRole)
      this.role.companyId = this.$store.getters.companyId
      if (this.$refs.tree) {
        this.$refs.tree.setCheckedNodes([])
      }
      this.dialogType = '添加角色'
      this.dialogVisible = true
    },
    //编辑角色
    handleEdit(scope){
      this.dialogType = '编辑角色'
      this.dialogVisible = true
      console.log(scope)
      this.role = deepClone(scope.row)
      this.$nextTick(() => {
        const selectedKeys = this.generateArr(this.role.routes)
        this.$refs.tree.setCheckedKeys(selectedKeys)
      })
    },
    generateArr(routes) {
      let data = []
      routes.forEach(route => {
        if (route.children) {
          const temp = this.generateArr(route.children)
          if (temp.length > 0) {
            data = [...data, ...temp]
          }
        }else{
          data.push(route.id)
        }
      })
      return data
    },
    //删除角色
    handleDelete({ $index, row }){
      this.$confirm('确定要删除该角色吗?', 'Warning', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          deleteRole(row.rlId).then((res)=>{
            if(res.status == 'success'){
              this.$message.success("删除成功")
              this.rolesList.splice($index, 1)
            }else{
              this.$message.error(res.data)
            }
          }).catch((error)=>{
            this.$message.error("删除失败")
          })
        })
        .catch(err => { console.error(err) })
    },
    //提交
    confirmRole(){

      const isEdit = this.dialogType === '编辑角色'
      // 获取选中权限树id
      const checkedKeys = this.$refs.tree.getCheckedKeys()
      if (checkedKeys){
        let routes = []
        checkedKeys.forEach(key => {
          let obj = {id:key}
          routes.push(obj)
        })
        // 将menu对象数组，赋给要添加的role
        this.role.routes = routes
      }
      if (isEdit) { // 修改角色
        updateRole(this.role).then((res)=>{
          if(res.status=="success"){
            this.$message.success("修改成功")
            this.getRoles()
          }else{
            this.$message.error(res.data)
          }
        }).catch((error)=>{
          this.$message.error("修改失败")
        })

      }else{
        //新增角色
        addRole(this.role).then((res)=>{
          if(res.status=="success"){
            this.$message.success("添加成功")
            this.getRoles()
          }else{
            this.$message.error(res.data)
          }
        }).catch((error)=>{
          this.$message.error("添加失败")
        })
      }
      this.dialogVisible = false
    },



    //点击树
    checkTree(data){
      const node = this.$refs.tree.getNode(data.id);
      this.setNode(node);
    },
    setNode(node) {
      if (node.checked) {
        //如果当前是选中checkbox,则递归设置父节点和父父节点++选中
        this.setParentNode(node);
      } else {
        //当前是取消选中,将所有子节点都取消选中
        this.setChildenNode(node);
      }
    },
    setParentNode(node) {
      if (node.parent) {
        for (const key in node) {
          if (key === "parent") {
            node[key].checked = true;
            this.setParentNode(node[key]);
          }
        }
      }
    },
    setChildenNode(node) {
      let len = node.childNodes.length;
      for (let i = 0; i < len; i++) {
        node.childNodes[i].checked = false;
        this.setChildenNode(node.childNodes[i]);
      }
    },
  }
}
</script>

<style scoped>
.footer {
  text-align: right;
}
</style>