<template>
  <div class="v-page role_page">
    <SearchTreeMenu
      ref="treeMenuRef"
      title="角色分类列表"
      :tree-data="role_list"
      @current-change="toChangeRole"
      @onCreate="toCreateRole"
      @onDelete="toDeleteRole"
    />
    <div class="v-ctx" v-if="active_role">
      <h2 class="v-title">角色信息管理</h2>
      <FormLayout
        ref="formLayoutRef"
        :items="formItems"
        :model="active_role"
        :rules="rules"
        label-width="110px"
        label-position="right"
        inline
      >
        <template v-slot:people>
          <el-button type="text" icon="el-icon-user-solid" @click="show_role_mumber_dialog=true">{{pageInfo.total}}人</el-button>
        </template>
      </FormLayout>

      <h2 class="v-title">功能权限</h2>

      <div v-if="!isSystemRole" style="margin-top:16px">
        在
        <el-radio-group v-model="active_role.base" size="mini" @change="changeBaseRole">
          <el-radio-button
            v-for="v in role_list[0].children"
            :label="v.id"
            :key="v.id"
          >
            {{ v.name }}
          </el-radio-button>
        </el-radio-group>
        的基础上编辑权限
      </div>

      <template v-if="active_role.base">
        <div v-for="v in feature_data" :key="v.name" class="feature_layout">
          <div class="feature_title">
            <el-checkbox
              class="feature"
              :value="(v.children.length?v.isCheckAll = hasCheckAll(v):hasChecked(v, v))"
              :label="v.label"
              @change="(v.children.length?checkAllFeature(v) : checkFeature(v))"
            />
          </div>
          <div class="feature_children">
            <el-checkbox
              v-for="feature in v.children"
              :key="feature.name"
              :value="hasChecked(v, feature)"
              :label="feature.label"
              @change="checkFeature(feature)"
              class="feature"
            />
          </div>
        </div>
      </template>

      <ActionBar
        v-if="active_role.base"
        center
        @onConfirm="onConfirm"
        @onCancel="onCancel"
      />
    </div>

    <DialogLayout
      title="角色人员列表"
      width="60vw"
      :shadowBar="false"
      :visible="show_role_mumber_dialog"
      :actionBarOption="{noCencel:true,noConfirm:true}"
      @onCancel="show_role_mumber_dialog=false">
      <TableLayout
        ref="tableRef"
        height="50vh"
        :column="column"
        :data="role_mumber"
        :pageInfo="pageInfo"
        @page-info-change="findRoleMember"
      >
        <template v-slot:sex="{row}">{{String(row.sex)?['女','男'][row.sex]:''}}</template>
        <template v-slot:birthday="{row}">{{row.birthday?new Date(row.birthday).format('yyyy-MM-dd'):''}}</template>
        <template v-slot:photo="{row}">
          <img v-if="row.photoResource" :src="row.photoResource.diskname.fileLinkTransfer()" width="50" height="50">
        </template>
      </TableLayout>
    </DialogLayout>
  </div>
</template>

<script>
import { SearchTreeMenu, FormLayout, ActionBar, DialogLayout, TableLayout } from '@/components/layout'

import { createRoleApi, deleteRoleApi, findAllRoleApi, updateRoleApi } from '@/api/system/role'
import { findAllFeature } from '@/router/feature'
import { findAllUserApi } from '@/api/system/user'

export default {
  components: { SearchTreeMenu, FormLayout, ActionBar, DialogLayout, TableLayout },

  data: () => ({
    search: '',
    role_list: [],
    feature_data: [],
    active_role: null,
    role_mumber: [],
    show_role_mumber_dialog: false,
    pageInfo: { current: 1, size: 10, total: 0 }
  }),

  computed: {
    isSystemRole () {
      return this.active_role && this.active_role.creator === 'SYSTEM'
    }
  },

  watch: { active_role: 'findRoleMember' },

  created () {
    this.formItems = [
      { prop: 'name', width: '30%', label: '角色名称', model: { tag: 'el-input' } },
      {
        prop: 'desc',
        label: '角色描述',
        model: { tag: 'el-input', type: 'textarea' }
      },
      { prop: 'people', label: '角色人员' }
    ]

    this.rules = {
      name: { required: true, message: '请输入角色名称', trigger: 'blur' }
    }

    this.column = [
      { prop: 'username', label: '用户名' },
      { prop: 'name', label: '姓名' },
      { prop: 'photo', label: '照片' },
      { prop: 'sex', label: '性别' },
      { prop: 'birthday', width: '90px', label: '出生年月' },
      { prop: 'idcard', label: '身份证号' },
      { prop: 'identity', label: '职位' },
      { prop: 'phone', label: '电话' },
      { prop: 'email', label: '邮箱' }
    ]

    this.findAllRole()
  },

  methods: {
    async findAllRole () {
      const { data } = await findAllRoleApi()
      const list = [
        { id: 'system', name: '系统默认', disabled: true, children: [] },
        { id: 'custom', name: '自定义角色', disabled: true, children: [] }
      ]
      this.systemRoleMap = {}
      for (const v of data) {
        v.features = v.features.map((v) => v.name)
        if (v.creator === 'SYSTEM') {
          list[0].children.push(v)
          this.systemRoleMap[v.id] = v
        } else {
          list[1].children.push(v)
        }
      }
      this.role_list = list
      this.feature_data = findAllFeature()
    },

    async findRoleMember () {
      let role = this.active_role
      if (!role.id) return (this.role_mumber = [])

      const { data: { list, total } } = await findAllUserApi({
        role: role.id,
        ...this.pageInfo
      })
      this.role_mumber = list
      this.pageInfo.total = total
    },

    changeBaseRole (baseRole) {
      this.active_role.features = [...this.systemRoleMap[baseRole].features]
    },

    toChangeRole (role) {
      if (role.disabled) return this.onCancel()

      this.active_role = JSON.parse(JSON.stringify(role))
    },

    hasCheckAll (featureRoot) {
      if (!this.active_role) return false
      let hasSize = 0
      for (const v of featureRoot.children) {
        if (this.active_role.features.includes(v.name)) {
          hasSize++
        }
      }
      const isCheckAll = featureRoot.children.length === hasSize
      const i = this.active_role.features.indexOf(featureRoot.name)
      if (hasSize) {
        if (i === -1) this.active_role.features.push(featureRoot.name)
      } else {
        if (i !== -1) this.active_role.features.splice(i, 1)
      }
      return isCheckAll
    },

    hasChecked (featureRoot, feature) {
      if (!this.active_role) return false

      return this.active_role.features.includes(feature.name)
    },

    checkAllFeature (featureRoot) {
      for (const v of featureRoot.children) {
        const index = this.active_role.features.indexOf(v.name)
        if (featureRoot.isCheckAll) {
          if (index !== -1) this.active_role.features.splice(index, 1)
        } else {
          if (index === -1) this.active_role.features.push(v.name)
        }
      }
    },

    checkFeature (feature) {
      const index = this.active_role.features.indexOf(feature.name)
      if (index === -1) {
        this.active_role.features.push(feature.name)
      } else {
        this.active_role.features.splice(index, 1)
      }
    },

    toCreateRole () {
      this.$refs.treeMenuRef.setCurrentKey()
      this.active_role = { name: '', desc: '', base: null, features: [] }
    },

    async toDeleteRole (role) {
      if (this.isSystemRole) return this.$message.error('系统默认角色不可以删除')
      await this.$confirm('将删除一个角色，是否继续？', '操作提示', { type: 'warning' })

      await deleteRoleApi(role.id)
      this.onCancel()
      this.findAllRole()
    },

    async onConfirm () {
      if (!this.active_role.features.length) return this.$message.error('功能权限不能为空')

      await this.$refs.formLayoutRef.validate()
      await (!this.active_role.id ? createRoleApi : updateRoleApi)({
        ...this.active_role,
        features: this.active_role.features.map((name) => ({ name, type: 1 }))
      })
      this.onCancel()
      this.findAllRole()
    },

    onCancel () {
      this.active_role = null
      this.$refs.treeMenuRef.setCurrentKey()
    }
  }
}
</script>

<style lang="scss">
.role_page {
  .form_layout {
    margin-top: 16px;
  }

  .feature_layout {
    margin-top: 20px;
    padding: 12px;
    display: flex;
    align-items: center;
    border-left: 3px solid $--color-primary;
    background-color: #f5f5f5;

    .el-checkbox__label {
      padding-left: 4px;
      color: #666;
    }

    .feature_title {
      min-width: 110px;
      text-align: center;

      .el-checkbox__label {
        color: #333;
        font-weight: bold;
      }
    }

    .feature_children {
      display: flex;
      flex-wrap: wrap;
      border-left: 1px solid #eee;

      .feature {
        padding: 12px;
      }

      .el-checkbox__input.is-checked + .el-checkbox__label {
        color: #666;
      }
    }
  }

  .action_bar {
    margin-top: 30px;
  }
}
</style>
