<template>
  <div class="app-container">
    <div class="filter-container">
      <sticky style="margin-bottom: 10px;">
        <div class="sub-navbar">
          <el-button type="primary" icon="el-icon-edit" @click="showCreate">
            添加
          </el-button>
        </div>
      </sticky>
      <el-form size="mini">
        <el-form-item>
          <el-input v-model="listQuery.title" placeholder="请输入要查询的菜单名称" clearable style="width: 230px" @keyup.enter.native="handleFilter" />
          <el-button type="primary" icon="el-icon-search" @click="handleFilter">
            查询
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    <el-table
      ref="list"
      :data="list"
      border
      fit
      size="mini"
      highlight-current-row
      row-key="id"
      :default-sort="{prop: 'sort'}"
      :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
      @row-click="onRowClick"
      @selection-change="handleSelectionChange"
    >
      <el-table-column label="菜单名称" prop="title" />
      <el-table-column align="center" label="菜单代码" prop="name" width="100px" />
      <el-table-column align="center" prop="icon" label="图标" width="100px">
        <template slot-scope="scope">
          <svg-icon v-if="scope.row.icon" :icon-class="scope.row.icon" />
        </template>
      </el-table-column>
      <el-table-column align="center" prop="menu" label="权限标识" width="100px" />
      <el-table-column align="center" prop="path" label="路由地址" />
      <el-table-column align="center" prop="sort" label="排序" width="80px" />
      <el-table-column align="center" prop="component" label="组件路径" />
      <el-table-column align="center" prop="cache" label="缓存" width="80px">
        <template slot-scope="scope">
          <span v-if="scope.row.cache">是</span>
          <span v-else>否</span>
        </template>
      </el-table-column>
      <el-table-column align="center" prop="hidden" label="可见" width="80px">
        <template slot-scope="scope">
          <span v-if="scope.row.hidden">否</span>
          <span v-else>是</span>
        </template>
      </el-table-column>
      <el-table-column align="center" prop="iframe" label="外链" width="80px">
        <template slot-scope="scope">
          <span v-if="scope.row.iframe">是</span>
          <span v-else>否</span>
        </template>
      </el-table-column>
      <el-table-column align="center" prop="createTime" label="创建日期" width="160px" />
      <el-table-column align="center" label="操作" width="180" fixed="right">
        <template slot-scope="scope">
          <el-button type="primary" icon="el-icon-edit" size="mini" title="编辑" @click="showUpdate(scope.row)" />
          <el-popover
            :ref="scope.row.id"
            placement="top"
            width="200"
          >
            <p>确定删除吗,如果存在下级节点则一并删除，此操作不能撤销！</p>
            <div style="text-align: right; margin: 0">
              <el-button type="text" size="mini" @click="$refs[scope.row.id].doClose()">
                取消
              </el-button>
              <el-button type="primary" size="mini" @click="deletePermission(scope.row.id)">
                确定
              </el-button>
            </div>
            <el-button slot="reference" size="mini" type="danger" icon="el-icon-delete" />
          </el-popover>
          <el-button type="primary" size="mini" title="复制" @click="copyMenu(scope.$index, scope.row)">
            <svg-icon icon-class="clipboard" />
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
      <el-form
        ref="tempPermission"
        :model="tempPermission"
        :rules="rules"
        class="small-space"
        label-width="100px"
        style="margin-left:50px;height: 450px;"
        size="mini"
      >
        <el-row :gutter="10">
          <el-col :span="11">
            <el-form-item label="菜单标题" prop="title">
              <el-input v-model="tempPermission.title" placeholder="填写菜单标题" :min="0" :max="100" type="text" />
            </el-form-item>
          </el-col>
          <el-col :span="11">
            <el-form-item label="菜单代码" prop="name">
              <el-input v-model="tempPermission.name" placeholder="如base、BaseList" :min="0" :max="100" type="text" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="11">
            <el-form-item label="菜单图标" prop="icon">
              <el-popover
                placement="bottom-start"
                width="450"
                trigger="click"
                @show="$refs['iconSelect'].reset()"
              >
                <IconSelect ref="iconSelect" @selected="selected" />
                <el-input slot="reference" v-model="icon" placeholder="点击选择图标" readonly>
                  <svg-icon v-if="icon" :icon-class="icon" class="el-input__icon" style="height: 32px;width: 16px;" />
                  <i v-else slot="prefix" class="el-icon-search el-input__icon" />
                </el-input>
              </el-popover>
            </el-form-item>
          </el-col>
          <el-col :span="11">
            <el-form-item label="权限标识" prop="menu">
              <el-input v-model="tempPermission.menu" placeholder="如base" :min="0" :max="50" type="text" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="11">
            <el-form-item label="路由地址" prop="path">
              <el-input v-model="tempPermission.path" placeholder="如base、base-list" :min="0" :max="200" type="text" />
            </el-form-item>
          </el-col>
          <el-col :span="11">
            <el-form-item label="菜单排序" prop="sort">
              <el-input-number v-model.number="tempPermission.sort" placeholder="菜单序号" :min="0" :max="999" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="11">
            <el-form-item label="组件路径" prop="component">
              <el-input v-model="tempPermission.component" placeholder="如Layout" :min="0" :max="50" type="text" />
            </el-form-item>
          </el-col>
          <el-col :span="11">
            <el-form-item label="上级类目" prop="pid">
              <el-cascader
                v-model="pid"
                :options="menus"
                :props="{ value: 'id', label: 'title', checkStrictly: true }"
                clearable
                placeholder="选择上级类目"
                size="mini"
                style="width: 100%;"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="11">
            <el-form-item label="菜单缓存" prop="cache">
              <el-radio-group v-model="tempPermission.cache">
                <el-radio-button label="true">
                  是
                </el-radio-button>
                <el-radio-button label="false">
                  否
                </el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="11">
            <el-form-item label="外链菜单" prop="iframe">
              <el-radio-group v-model="tempPermission.iframe">
                <el-radio-button label="true">
                  是
                </el-radio-button>
                <el-radio-button label="false">
                  否
                </el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="11">
            <el-form-item label="菜单可见" prop="hidden">
              <el-radio-group v-model="tempPermission.hidden">
                <el-radio-button label="false">
                  是
                </el-radio-button>
                <el-radio-button label="true">
                  否
                </el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="所含资源" prop="useless">
          <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">
            全选
          </el-checkbox>
          <!--          <span style="margin-left: 20px;color: red;">列表选项默认必选！</span>-->
          <el-checkbox-group v-model="checkedPermissions" @change="handleCheckedCitiesChange">
            <el-checkbox v-for="permission in permissionTypeList" :key="permission.code" :label="permission.code">
              {{ permission.name }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="mini" @click="dialogFormVisible = false">
          取 消
        </el-button>
        <el-button v-if="dialogStatus==='create'" size="mini" type="success" @click="createPermission">
          创 建
        </el-button>
        <el-button v-else size="mini" type="primary" @click="updatePermission">
          修 改
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import Sticky from '@/components/Sticky'
import IconSelect from '@/components/IconSelect'
export default {
  name: 'PermissionList',
  components: { Sticky, IconSelect },
  data() {
    return {
      list: [], // 表格的数据
      menus: [], // 上级菜单列表
      pid: [],
      listQuery: {},
      textMap: {
        update: '编辑菜单',
        create: '新建菜单'
      },
      tempPermission: {},
      dialogStatus: 'create',
      dialogFormVisible: false,
      icon: '',
      rules: {
        name: [
          { required: true, message: '请填写菜单代码', trigger: 'blur' }
        ],
        title: [
          { required: true, message: '请填写菜单名称', trigger: 'blur' }
        ],
        path: [
          { required: true, message: '请填写路由地址', trigger: 'blur' }
        ],
        // menu: [
        //   { required: true, message: '请填写权限标识', trigger: 'change' }
        // ],
        component: [
          { required: true, message: '请填写组件路径', trigger: 'blur' }
        ]
      },
      permissionTypeList: [],
      multipleSelection: [],
      checkAll: false,
      checkAllPermission: [],
      checkedPermissions: [],
      isIndeterminate: false
    }
  },
  created() {
    this.getList()
    this.getPermissionTypeList()
  },
  methods: {
    handleCheckAllChange(val) {
      if (val) {
        this.permissionTypeList.forEach(ad => {
          this.checkedPermissions.push(ad.code)
        })
      } else {
        this.checkedPermissions = []
      }
      this.isIndeterminate = false
    },
    handleCheckedCitiesChange(value) {
      const checkedCount = value.length
      this.checkAll = checkedCount === this.permissionTypeList.length
      this.isIndeterminate = checkedCount > 0 && checkedCount < this.permissionTypeList.length
    },
    getList() {
      // 查询列表
      this.api({
        url: '/permission/list',
        method: 'get',
        params: this.listQuery
      }).then(data => {
        this.list = data
        // 获取菜单类目
        if (!this.listQuery.title) {
          this.menus = []
          const menu = { id: 0, title: '顶级类目', children: [] }
          menu.children = data
          this.menus.push(menu)
        }
      })
    },
    getPermissionTypeList: function() {
      this.api({
        url: '/dicData/getDicDataByTypeCode',
        method: 'get',
        params: {
          typeCode: 'PERMISSION_TYPE',
          parentId: null
        }
      }).then(data => {
        if (data != null) {
          this.permissionTypeList = data.filter(a => a.code !== 'list')
        }
      })
    },
    handleFilter() {
      // 查询事件
      this.getList()
    },
    onRowClick(row) {
      this.$refs.list.toggleRowSelection(row)
    },
    handleSelectionChange: function(val) {
      this.multipleSelection = val
    },
    selected(name) {
      this.icon = name
    },
    showCreate() {
      this.api({
        url: '/permission/getPermissionMaxSort',
        method: 'get'
      }).then(data => {
        this.tempPermission = {
          sort: data + 1,
          iframe: false,
          cache: true,
          hidden: false
        }
      })
      this.pid = []
      this.checkedPermissions = []
      this.isIndeterminate = false
      this.checkAll = false
      this.icon = ''
      this.dialogStatus = 'create'
      this.showTempPermissionForm(true)
    },
    copyMenu($index, row) {
      const data = row.pid ? this.list.filter(tempRow => tempRow.id === row.pid)[0].children.filter(tempRow => tempRow.id === row.id)[0] : this.list[$index]
      this.loadFromData(data)
      this.dialogStatus = 'create'
      this.showTempPermissionForm(false)
    },
    showUpdate(data) {
      this.loadFromData(data)
      this.dialogStatus = 'update'
      this.showTempPermissionForm(false)
    },
    loadFromData(data) {
      this.$set(this, 'tempPermission', data)
      this.icon = this.tempPermission.icon
      this.pid = this.getPermissionPid(this.menus, this.tempPermission.id)
      this.pid.splice(this.pid.length - 1, 1)
      this.checkedPermissions = []
      this.getPermissionTypesById(this.tempPermission.id)
    },
    showTempPermissionForm(bol) {
      this.dialogFormVisible = true
      if (bol) {
        this.$nextTick(() => {
          this.$refs.tempPermission.resetFields()
        })
      }
    },
    getPermissionPid(data, pid) {
      const temp = []
      // eslint-disable-next-line no-unused-vars
      const forFn = function(arr, pid) {
        for (let i = 0; i < arr.length; i++) {
          const item = arr[i]
          if (item.id === pid) {
            temp.push(item.id)
            if (item.id !== 0) {
              forFn(data, item.pid)
            }
          } else {
            if (item.children) {
              forFn(item.children, pid)
            }
          }
        }
      }
      forFn(data, pid)
      return temp.reverse()
    },
    createPermission() {
      this.$refs['tempPermission'].validate((valid) => {
        if (valid) {
          const pid = this.iconUpdate()
          if (pid) {
            this.api({
              url: '/permission',
              method: 'post',
              data: this.tempPermission
            }).then(() => {
              this.$message.success('添加成功。')
              this.getList()
              this.dialogFormVisible = false
            })
          }
        } else {
          return false
        }
      })
    },
    updatePermission() {
      this.$refs['tempPermission'].validate((valid) => {
        if (valid) {
          const pid = this.iconUpdate()
          if (pid) {
            this.api({
              url: '/permission',
              method: 'put',
              data: this.tempPermission
            }).then(() => {
              this.$message.success('更新成功。')
              this.getList()
              this.dialogFormVisible = false
            })
          }
        } else {
          return false
        }
      })
    },
    iconUpdate() {
      this.tempPermission.pid = this.pid[this.pid.length - 1]
      if (this.tempPermission.pid == null) {
        this.$message.error('请选择上级目录！')
        return false
      }
      this.tempPermission.icon = this.icon
      if (this.checkedPermissions.indexOf('list') < 0) {
        this.checkedPermissions.push('list')
      }
      this.tempPermission.permissionTypes = this.checkedPermissions
      return true
    },
    deletePermission(id) {
      this.$confirm('删除此资源会影响到角色的权限，确定要删除吗？', '提示', {
        confirmButtonText: '确定',
        showCancelButton: '取消',
        type: 'warning'
      }).then(() => {
        this.api({
          url: '/permission/deletePermission',
          method: 'delete',
          params: {
            id: id
          }
        }).then(() => {
          this.$message.success('删除成功。')
          this.getList()
        })
      })
    },
    getPermissionTypesById(id) {
      this.api({
        url: '/permission/getPermissionTypesById',
        method: 'get',
        params: {
          permissionId: id
        }
      }).then(data => {
        if (data !== null && data.length > 0) {
          data.filter(d => d.permissionType !== 'list').forEach(d => {
            this.checkedPermissions.push(d.permissionType)
          })
          this.checkAll = this.checkedPermissions.length === this.permissionTypeList.length
          this.isIndeterminate = this.checkedPermissions.length > 0 && this.checkedPermissions.length < this.permissionTypeList.length
        }
      })
    }
  }
}
</script>
