<template>
  <div class="newAuth scroll-y pd24">
    <div class="newAuth-content flex-wrap">
      <div class="newAuth-content-left box-public-shadow-mini">
        <div class="newAuth-content-left-head flex">
          <div class="title">权限树列表</div>
          <el-button @click="handleAdd" size="small">新增</el-button>
        </div>
        <div class="newAuth-content-left-search">
          <el-input size="small" placeholder="请输入内容" clearable prefix-icon="el-icon-search" :filter-node-method="filterNode" v-model="filterText">
          </el-input>
        </div>
        <div class="newAuth-content-left-tree">
          <el-scrollbar ref="scroll" style="height: 100%">
            <el-tree ref="tree" :data="treeData" :props="defaultProps" :default-expanded-keys="expandedKeys" highlight-current :filter-node-method="filterNode" node-key="auth_id" @node-click="handleNodeClick" :expand-on-click-node="false">
              <span class="custom-tree-node" slot-scope="{ node, data }">
                <span class="customTxt">{{ node.label }}</span>
                <div>
                  <span v-show="treeCheckId == data.auth_id" class="customBtn">
                    <template v-if="data.auth_type == 1 || data.auth_type == 2">
                      <el-button @click.stop="handleUp(node,data)" type="text">上移</el-button>
                      <el-button @click.stop="handleDown(node,data)" type="text">下移</el-button>
                    </template>
                    <el-button type="text" class="remBtn" v-if="data.auth_id != 0" @click.stop="handleRemove(node, data)">删除</el-button>
                  </span>
                </div>
              </span>
            </el-tree>
          </el-scrollbar>
        </div>
      </div>
      <div :style="componentName == 'Table' ? 'height:350px':''" class="newAuth-content-right box-public-shadow-mini flex1">
        <div class="newAuth-content-right-head flex">
          <div class="title">权限信息维护</div>
          <el-button type="primary" @click="handleSave" size="small">保存</el-button>
        </div>
        <div class="newAuth-content-right-content">
          <el-form ref="form" :model="form" :rules="rules" label-width="100px">
            <div class="flex-wrap fr-list">
              <el-form-item class="flex1" prop="auth_name" label="权限项名称">
                <el-input size="small" clearable placeholder="请输入权限项名称" v-model="form.auth_name"></el-input>
              </el-form-item>
              <el-form-item class="flex1" label="上级权限项">
                <el-select @change="authChange" filterable size="small" clearable v-model="form.up_auth_id" placeholder="请选择上级权限项">
                  <el-option v-for="(item,index) in authDataArr" :key="index" :label="item.auth_name" :value="item.auth_id"></el-option>
                </el-select>
              </el-form-item>
              <el-form-item class="flex1" prop="auth_type" label="权限类型">
                <el-select size="small" filterable @change="typeChange" clearable v-model="form.auth_type" placeholder="请选择权限类型">
                  <el-option label="目录" :value="1"></el-option>
                  <el-option label="菜单" :value="2"></el-option>
                  <el-option label="按钮" :value="3"></el-option>
                  <el-option label="表格" :value="4"></el-option>
                  <el-option label="表格(文字)" :value="5"></el-option>
                </el-select>
              </el-form-item>
            </div>
            <div class="flex-wrap fr-list">
              <el-form-item class="flex1" label="所属应用">
                <el-select size="small" style="width: 265px;" filterable clearable v-model="form.app_id" placeholder="请选择所属应用">
                  <el-option v-for="(item,index) in apps" :key="index" :label="item.app_name" :value="item.app_id"></el-option>
                </el-select>
              </el-form-item>
            </div>
          </el-form>
          <keep-alive>
            <component ref="dataChild" :icons="icons" :authType="dataType" :authNum="authNum" :authObj="authObj" :is="componentName"></component>
          </keep-alive>
        </div>
      </div>
    </div>
    <Dialog :flag="rmFlag">
      <div class="airportInfoDialog">
        <div class="title del-title">删除</div>
        <div class="content del-content">
          <span class="el-icon-error error r10"></span>您是否确认删除<span class="error l10">{{ rmTitle }}</span>
          ？
        </div>
        <div class="foot right Delfoot">
          <el-button size="medium" class="r24" @click="tableRemove" type="danger">删除</el-button>
          <el-button size="medium" @click="rmFlag = false">取消</el-button>
        </div>
      </div>
    </Dialog>
  </div>
</template>

<script>
import pb from '@/layout/mixin/getPublicData'
import pf from '@/layout/mixin/publicFunc'
import { setTree, listToTree } from '@/utils/validate'
import allIcons from '@/layout/mixin/publicIcons'
import Dialog from "@/layout/components/Dialog/index.vue";
import Menu from './components/menu.vue'
import Catalogue from './components/catalogue.vue'
import Button from './components/button.vue'
import Table from './components/table.vue'
import { getToken } from '@/utils/auth'
export default {
  name: 'NewAuth',
  mixins: [pb, pf],
  components: { Dialog, Menu, Catalogue, Button, Table },
  data () {
    return {
      filterText: '',
      treeData: [
        {
          auth_name: '所有权限',
          auth_id: 0,
          children: [],
          up_auth_id: -1
        }
      ],
      defaultProps: {
        children: 'children',
        label: 'auth_name'
      },
      form: {
        auth_name: null,
        auth_type: null,
        up_auth_id: null,
        app_id: null
      },
      rules: {
        auth_name: [{ required: true, message: '请输入权限名称', trigger: 'blur' }],
        auth_type: [{ required: true, message: '请选择权限类型', trigger: 'change' }],
        up_auth_id: [{ required: true, message: '请选择上级权限项', trigger: 'change' }],
      },
      treeCheckId: null,
      icons: allIcons,
      rmTitle: '',
      rmFlag: false,
      componentName: 'Catalogue',
      authData: [],
      authObj: {},
      rmObj: {},
      dataType: 'add',
      authNum: null,
      authDataArr: [],
      authTable: false,
      treeDatas: [],
      expandedKeys: [],
      apps: []
    }
  },
  watch: {
    filterText (val) {
      this.$refs.tree.filter(val);
    }
  },
  mounted () {
    this.setTreeData()
    this.getApp()
  },
  methods: {
    filterNode (value, data) {
      if (!value) return true;
      return data.auth_name.indexOf(value) !== -1;
    },
    //清空表单
    clearForm () {
      const data = this.form
      for (const key in data) {
        if (Object.hasOwnProperty.call(data, key)) {
          data[key] = null
        }
      }
      this.$refs['form'].resetFields()
      this.$refs['dataChild'].clearForm()
    },
    //获取tree数据
    async setTreeData () {
      const keys = []
      const { code, returnData
      } = await this.getQueryList(SERVICE_ID.sysAuthId, { user_id: getToken('userid') })
      if (code == 0 && returnData && returnData.length) {
        const treeMenu = listToTree(returnData, 'up_auth_id', 'auth_id')
        const newTreeMenu = treeMenu && treeMenu.length ? treeMenu.sort((a, b) => a.show_index - b.show_index) : treeMenu
        newTreeMenu.forEach(item => {
          keys.push(item.auth_id)
          item.children = item.children && item.children.length ? item.children.sort((a, b) => a.show_index - b.show_index) : item.children
        })
        this.expandedKeys = keys
        this.treeDatas = _.cloneDeep(newTreeMenu)
        this.authDataArr = returnData.filter(item => item.auth_type != 3)
        this.treeData[0].children = newTreeMenu
        this.$store.dispatch("auth/changeAuthArrs", returnData);
      }
    },
    //获取应用数据
    async getApp () {
      const { code, returnData } = await this.getQueryList(SERVICE_ID.getAppId)
      if (code == 0) {
        this.apps = returnData
      }
    },
    //新增
    handleAdd () {
      this.dataType = 'add'
      this.clearForm()
    },
    //树点击
    handleNodeClick (data) {
      if (data.auth_id == 0 && data.up_auth_id == -1) {
        return
      }
      this.dataType = 'edit'
      const newObj = _.cloneDeep(data)
      this.treeCheckId = data.auth_id
      this.form.auth_name = data.auth_name
      this.form.up_auth_id = data.up_auth_id
      this.form.auth_type = data.auth_type
      this.form.app_id = data.app_id
      this.rmTitle = data.auth_name
      if (newObj.children) {
        delete newObj.children
      }
      // console.log(data)
      this.authObj = newObj
      this.typeChange(data.auth_type)
    },
    //树删除
    handleRemove (node, data) {
      this.rmFlag = true
      this.rmObj = data
    },
    //树上移
    async handleUp (node, data) {
      const { auth_type, auth_id, up_auth_id } = data
      const mulu = this.treeDatas
      if (auth_type == 1) {
        const nums = []
        const numsObj = { min: null, max: null }
        if (mulu && mulu.length) {
          mulu.forEach((item, index) => {
            item.show_index = index
            nums.push(index)
          })
        }
        numsObj.min = Math.min(...nums)
        numsObj.max = Math.max(...nums)
        const list = mulu.filter(item => item.auth_id == auth_id)
        const listObj = list[0]
        const listIndex = listObj.show_index
        if (listIndex == numsObj.min) {
          this.$message.error('当前已是最上级，无法移动')
        } else {
          const lastObj = mulu[listIndex - 1] //上一级数据
          mulu[listIndex - 1] = listObj
          mulu[listIndex - 1].show_index = listIndex - 1
          mulu[listIndex] = lastObj
          mulu[listIndex].show_index = listIndex
          const delArr = []
          mulu.forEach(item => {
            if (item.children) {
              delete item.children
            }
            delArr.push({
              auth_id: item.auth_id
            })
          })
          const { code } = await this.getChangeList(this.queryId, mulu, 2, delArr)
          if (code == 0) {
            this.$message.success('操作成功')
            this.setTreeData()
          } else {
            this.$message.success('操作失败')
          }
        }
      } else {
        const caidan = mulu.filter(item => item.auth_id == up_auth_id)
        const caidanArr = caidan[0].children
        const caidanNums = []
        if (caidanArr && caidanArr.length) {
          caidanArr.forEach((item, index) => {
            item.show_index = index
            caidanNums.push(index)
          })
        }
        const min = Math.min(...caidanNums)
        const list = caidanArr.filter(item => item.auth_id == auth_id)
        const listObj = list[0]
        const listIndex = listObj.show_index
        if (listIndex == min) {
          this.$message.error('当前已是最上级，无法移动')
        } else {
          const lastObj = caidanArr[listIndex - 1] //上一级数据
          caidanArr[listIndex - 1] = listObj
          caidanArr[listIndex - 1].show_index = listIndex - 1
          caidanArr[listIndex] = lastObj
          caidanArr[listIndex].show_index = listIndex
          const delArr = []
          caidanArr.forEach(item => {
            if (item.children) {
              delete item.children
            }
            delArr.push({
              auth_id: item.auth_id
            })
          })
          const { code } = await this.getChangeList(this.queryId, caidanArr, 2, delArr)
          if (code == 0) {
            this.$message.success('操作成功')
            this.setTreeData()
          } else {
            this.$message.success('操作失败')
          }
        }
      }
    },
    //树下移
    async handleDown (node, data) {
      const { auth_type, auth_id, up_auth_id } = data
      const mulu = this.treeDatas
      if (auth_type == 1) {
        const nums = []
        const numsObj = { min: null, max: null }
        if (mulu && mulu.length) {
          mulu.forEach((item, index) => {
            item.show_index = index
            nums.push(index)
          })
        }
        numsObj.min = Math.min(...nums)
        numsObj.max = Math.max(...nums)
        const list = mulu.filter(item => item.auth_id == auth_id)
        const listObj = list[0]
        const listIndex = listObj.show_index
        if (listIndex == numsObj.max) {
          this.$message.error('当前已是最下级，无法移动')
        } else {
          const lastObj = mulu[listIndex + 1] //上一级数据
          mulu[listIndex + 1] = listObj
          mulu[listIndex + 1].show_index = listIndex + 1
          mulu[listIndex] = lastObj
          mulu[listIndex].show_index = listIndex
          const delArr = []
          mulu.forEach(item => {
            if (item.children) {
              delete item.children
            }
            delArr.push({
              auth_id: item.auth_id
            })
          })
          const { code } = await this.getChangeList(this.queryId, mulu, 2, delArr)
          if (code == 0) {
            this.$message.success('操作成功')
            this.setTreeData()
          } else {
            this.$message.success('操作失败')
          }
        }
      } else {
        const caidan = mulu.filter(item => item.auth_id == up_auth_id)
        const caidanArr = caidan[0].children
        const caidanNums = []
        if (caidanArr && caidanArr.length) {
          caidanArr.forEach((item, index) => {
            item.show_index = index
            caidanNums.push(index)
          })
        }
        const max = Math.max(...caidanNums)
        const list = caidanArr.filter(item => item.auth_id == auth_id)
        const listObj = list[0]
        const listIndex = listObj.show_index
        if (listIndex == max) {
          this.$message.error('当前已是最下级，无法移动')
        } else {
          const lastObj = caidanArr[listIndex + 1] //上一级数据
          caidanArr[listIndex + 1] = listObj
          caidanArr[listIndex + 1].show_index = listIndex + 1
          caidanArr[listIndex] = lastObj
          caidanArr[listIndex].show_index = listIndex
          const delArr = []
          caidanArr.forEach(item => {
            if (item.children) {
              delete item.children
            }
            delArr.push({
              auth_id: item.auth_id
            })
          })
          const { code } = await this.getChangeList(this.queryId, caidanArr, 2, delArr)
          if (code == 0) {
            this.$message.success('操作成功')
            this.setTreeData()
          } else {
            this.$message.success('操作失败')
          }
        }
      }
    },
    //树删除-确定
    async tableRemove () {
      const { code } = await this.getChangeList(this.queryId, this.rmObj, 3)
      if (code == 0) {
        this.$message.success('操作成功')
        this.setTreeData()
        this.rmObj = {}
        this.authObj = {}
        this.clearForm()
      }
      this.rmFlag = false
    },
    //保存
    handleSave () {
      this.$refs['form'].validate(async (valid) => {
        if (valid) {
          const child = this.$refs['dataChild'].form
          // console.log(child)
          const data = _.merge(child, this.form)
          if (Array.isArray(data.pass_parameters)) {
            data.pass_parameters = data.pass_parameters.join(',')
          } else {
            data.pass_parameters = null
          }
          for (const key in data) {
            if (Object.hasOwnProperty.call(data, key)) {
              if (!data[key]) {
                data[key] = null
              }
            }
          }
          if (this.dataType == 'add') {
            const { code } = await this.getChangeList(this.queryId, data, 1)
            if (code == 0) {
              this.$message.success('操作成功')
              this.setTreeData()
            } else {
              this.$message.error('操作失败')
            }
          } else {
            const { code } = await this.getChangeList(this.queryId, data, 2, 'auth_id')
            if (code == 0) {
              this.$message.success('操作成功')
              this.setTreeData()
            } else {
              this.$message.error('操作失败')
            }
          }
          this.authObj = {}
          this.clearForm()
        } else {
          return false
        }
      });
    },
    typeChange (val) {
      switch (val) {
        case 1:
          this.componentName = 'Catalogue'
          break;
        case 2:
          this.componentName = 'Menu'
          break;
        case 3:
          this.componentName = 'Button'
          break;
        case 4:
          this.componentName = 'Table'
          break;
        case 5:
          this.componentName = 'Table'
          break;
        default:
          break;
      }
    },
    authChange (val) {
      this.authNum = val
    }
  }
}
</script>

<style lang="scss" scoped>
.newAuth {
  &-content {
    height: 100%;
    position: relative;
    &-left {
      width: 360px;
      margin-right: 16px;
      height: 100%;
      &-head {
        line-height: 32px;
      }
      &-search {
        margin-top: 18px;
      }
      &-tree {
        margin-top: 30px;
        height: calc(100% - 108px);
        .custom-tree-node {
          flex: 1;
          display: flex;
          align-items: center;
          justify-content: space-between;
          font-size: 14px;
          padding-right: 8px;
          .customBtn {
            color: #dd3838;
            .remBtn {
              color: #dd3838;
            }
          }
        }
      }
    }
    &-right {
      &-head {
        line-height: 32px;
      }
      &-content {
        margin-top: 24px;
        .fr-list {
          .el-form-item {
            margin-right: 105px;
            &:last-child {
              margin-right: 0;
            }
          }
        }
        .el-select {
          width: 100%;
        }
      }
    }
  }
}
</style>