<template>
  <div>
    <a-row type="flex" :gutter="10">
      <a-col :span="12">
        <a-card :bordered="false" style="min-height:calc(100vh - 125px);">
          <advance-table
            :columns="columns"
            :data-source="list"
            title="角色管理"
            :loading="loading"
            rowKey="id"
            size="middle"
            tableKey="system-role-SysRoleIndex-table"
            @refresh="getList"
            :customRow="onClickRow"
            :format-conditions="true"
            :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
            :pagination="{
              current: queryParam.pageNum,
              pageSize: queryParam.pageSize,
              total: total,
              showSizeChanger: true,
              showLessItems: true,
              showQuickJumper: true,
              showTotal: (total, range) => `第 ${range[0]}-${range[1]} 条，总计 ${total} 条`,
              onChange: changeSize,
              onShowSizeChange: onShowSizeChange,
            }">
            <div class="table-operations" slot="button">
              <a-input-search
                placeholder="请输入编码或名称"
                v-model="queryParam.codeOrName"
                style="width: 150px"
                @search="handleQuery" />
              <a-button type="primary" size="small" @click="addRow()" v-hasPermi="['system:role:add']">
                <a-icon type="plus" />新增
              </a-button>
              <a-button type="" size="small" @click="batchSaveRole()" v-hasPermi="['system:role:add']">
                <a-icon type="save" />保存
              </a-button>
              <a-button type="danger" v-if="!multiple" @click="batchDeleteRow" v-hasPermi="['system:role:remove']">
                <a-icon type="delete" />删除
              </a-button>
              <a-button type="" @click="handleExport" v-hasPermi="['system:role:export']">
                <a-icon type="download" />导出
              </a-button>
            </div>
            <span slot="status" slot-scope="{text,record}">
              <a-tooltip placement="top">
                <template slot="title">
                  <span>点击修改状态</span>
                </template>
                <a-popconfirm
                  ok-text="是"
                  cancel-text="否"
                  @confirm="confirmHandleStatus(record)"
                >
                  <span slot="title">确认<b>{{ record.status === '1' ? '启用' : '停用' }}</b>【{{ record.roleName }}】的角色吗?</span>
                  <a-badge :status="record.status === '0' ? 'processing' : 'error'" :text=" statusFormat(record) " />
                </a-popconfirm>
              </a-tooltip>
            </span>

            <span slot="roleNameSolt" slot-scope="{text,record}">
              <a-tag color="blue" v-if="!record.editable">
                {{ text }}
              </a-tag>
              <a-input placeholder="请输入" v-model="record.roleName" v-if="record.editable" />
            </span>
            <span slot="roleKey" slot-scope="{text,record}">
              <a-tag color="blue" v-if="!record.editable || record.roleKey ==='admin'">
                {{ text }}
              </a-tag>
              <a-input placeholder="请输入" v-model="record.roleKey" v-if="record.editable && record.roleKey !=='admin'" />
            </span>
            <span slot="sort" slot-scope="{text,record}">
              <span v-if="!record.editable">
                {{ text }}
              </span>
              <a-input-number placeholder="请输入"v-model="record.sort" v-if="record.editable" :min="0" style="width: 100%"/>
            </span>
            <span slot="operation" slot-scope="{text, record}">
              <div v-if="record.editable">
                <a @click.stop="cancelEditCell(record)" >
                  取消
                </a>
                <a-divider type="vertical" />
                <a @click="deleteRow(record,'delete')">删除</a>
              </div>
              <div v-else>
                <a @click.stop="updateRow(record)" v-hasPermi="['system:role:edit']">
                  修改
                </a>
                <a-divider type="vertical" v-hasPermi="['system:role:remove']" />
                <a @click.stop="deleteRow(record)" v-hasPermi="['system:role:remove']">
                  删除
                </a>
              </div>
            </span>
          </advance-table>
        </a-card>
      </a-col>
      <a-col :span="12">
        <a-card :bordered="false" style="min-height:calc(100vh - 125px);">
          <select-user selectModel="multi" v-model="selectedUser" v-show="false" ref="selectUserRef" />
          <advance-table
            :columns="roleUserColumns"
            :data-source="subList"
            title="角色用户"
            :loading="subLoading"
            rowKey="id"
            size="middle"
            tableKey="system-roleuser-SysRoleIndex-table"
            @refresh="getRoleUserList"
            :format-conditions="true"
            :row-selection="{ selectedRowKeys: selectedSubRowKeys, onChange: onSelectSubChange}"
            :pagination="{
              current: querySubParam.pageNum,
              pageSize: querySubParam.pageSize,
              total: subTotal,
              showSizeChanger: true,
              showLessItems: true,
              showQuickJumper: true,
              showTotal: (subTotal, range) => `第 ${range[0]}-${range[1]} 条，总计 ${subTotal} 条`,
              onChange: changeSubSize,
              onShowSizeChange: onShowSizeSubChange,
            }">
            <div class="table-operations" slot="button">
              <a-input-search
                placeholder="请输入编码或名称"
                v-model="querySubParam.userNameOrName"
                style="width: 150px"
                @search="handleQueryRoleUser" />
              <a-button
                type="primary"
                v-if="currentSelectRoleId.indexOf('newRow-')<0"
                size="small"
                @click="handleAddUser()"
                v-hasPermi="['system:role:add']">
                <a-icon type="plus" />添加用户
              </a-button>
              <a-button
                type="danger"
                v-if="!subMultiple"
                @click="handleDeleteSub"
                v-hasPermi="['system:role:remove']">
                <a-icon type="delete" />删除
              </a-button>
            </div>

            <span slot="status" slot-scope="{record}">
              <a-badge status="processing" :text=" statusFormat(record) " />
            </span>
            <span slot="roleKey" slot-scope="{text}">
              <a-tag color="blue">
                {{ text }}
              </a-tag>
            </span>
            <span slot="operation" slot-scope="{text, record}">
              <a @click.stop="handleDeleteSub(record)" v-hasPermi="['system:role:remove']">
                删除
              </a>
            </span>
          </advance-table>
        </a-card>
      </a-col>
    </a-row>

  </div>
</template>
<script>
  import {
    listRole,
    exportRole,
    batchSaveRole,
    delRoleUser,
    changeRoleStatus
  } from '@/api/system/role'
  import {
    getRoleUserList,
    saveRoleUser
  } from '@/api/system/user'
  import AdvanceTable from '@/components/pt/table/AdvanceTable'
  import SelectUser from '@/components/pt/selectUser/SelectUser'
  import {
    randomUUID
  } from '@/utils/util'
  export default {
    name: 'Role',
    components: {
      AdvanceTable,
      SelectUser
    },
    data () {
      return {
        list: [],
        // 表格缓存的数据 - 用来点击取消时回显数据
        cacheData: [],
        deleteData: [], // 可编辑表格待删除数据，数据库已存在数据界面假删除，保存到该集合，最终请求数据库删除
        subList: [],
        selectedRowKeys: [],
        selectedSubRowKeys: [],
        selectedRows: [],
        selectedSubRows: [],
        selectedUser: '',
        // 高级搜索 展开/关闭
        advanced: false,
        // 非单个禁用
        single: true,
        // 非多个禁用
        multiple: true,
        subMultiple: true,
        currentSelectRoleId: '',
        selectItem: {},
        ids: [],
        subIds: [], // 子表选择id集合
        loading: false,
        subLoading: false,
        total: 0,
        subTotal: 0,
        // 状态数据字典
        statusOptions: [],
        // 日期范围
        dateRange: [],
        labelCol: {
          span: 6
        },
        wrapperCol: {
          span: 18
        },
        queryParam: {
          pageNum: 1,
          pageSize: 10,
          roleName: undefined,
          roleKey: undefined,
          status: undefined
        },
        querySubParam: {
          pageNum: 1,
          pageSize: 10
        },
        addModalRefName: 'addModal', // 添加弹窗ref名称
        columns: [{
            title: '角色名称',
            dataIndex: 'roleName',
            ellipsis: true,
            scopedSlots: {
              customRender: 'roleNameSolt'
            }
          },
          {
            title: '角色编码',
            dataIndex: 'roleKey',
            width: '150px',
            ellipsis: true,
            scopedSlots: {
              customRender: 'roleKey'
            }
          },
          {
            title: '排序号',
            dataIndex: 'sort',
            align: 'center',
            scopedSlots: {
              customRender: 'sort'
            }
          },
          {
            title: '状态',
            dataIndex: 'status',
            scopedSlots: {
              customRender: 'status'
            },
            align: 'center'
          },
          {
            title: '操作',
            dataIndex: 'operation',
            width: '100px',
            scopedSlots: {
              customRender: 'operation'
            }
          }
        ],
        roleUserColumns: [{
            title: '用户名称',
            dataIndex: 'name',
            ellipsis: true
          },
          {
            title: '登录名',
            dataIndex: 'userName',
            ellipsis: true
          },
          {
            title: '状态',
            dataIndex: 'status',
            scopedSlots: {
              customRender: 'status'
            },
            align: 'center'
          },
          {
            title: '操作',
            dataIndex: 'operation',
            width: '100px',
            scopedSlots: {
              customRender: 'operation'
            }
          }
        ]
      }
    },
    filters: {},
    created () {
      this.getList()
      this.getDicts('sys_normal_disable').then(response => {
        this.statusOptions = response.data
      })
    },
    computed: {},
    watch: {
      selectedUser (val) {
        const saveRoleUserForm = {
          'userId': val.ids,
          'roleId': this.currentSelectRoleId
        }
        saveRoleUser(saveRoleUserForm).then(response => {
          this.$message.success('添加成功', 3)
          this.getRoleUserList()
        })
      },
      selectItem (val) {
        this.renderRowStyle(val)
        this.getRoleUserList(val.id)
      }
    },
    methods: {
      statusFormat (row) {
        return this.selectDictLabel(this.statusOptions, row.status)
      },
      /** 查询定时任务列表 */
      getList () {
        this.showAddModal = false
        this.showEditModal = false
        this.showDataScopeModal = false
        this.loading = true
        listRole(this.addDateRange(this.queryParam, this.dateRange)).then(response => {
          this.list = response.data.list
          this.list.map((item) => {
            item.operation = item.remark
          })
          this.total = response.data.total
          this.loading = false
          if (this.list.length > 0) {
            this.$nextTick(() => (
              this.selectItem = this.list[0]
            ))
           // this.getRoleUserList(this.list[0].id)
          }
        })
      },
      getRoleUserList (roleId) {
        if (typeof (roleId) === 'string') {
          if (roleId === null || roleId === '' || roleId === undefined) {
            roleId = this.currentSelectRoleId
          } else {
            this.currentSelectRoleId = roleId
          }
        } else {
          roleId = this.currentSelectRoleId
        }
        if (roleId.indexOf('newRow-') < 0) {
          // 只有保存的数据才加载字表数据
          this.subLoading = true
          this.querySubParam.roleId = roleId
          getRoleUserList(this.addDateRange(this.querySubParam, this.dateRange)).then(response => {
            this.subList = response.data.list
            this.subList.map((item) => {
              item.operation = item.remark
            })
            this.subTotal = response.data.total
            this.subLoading = false
          })
        } else {
          // 新添加行不需要加载后台，直接清空子表数据
          this.subList = []
          this.subTotal = 0
        }
        this.subIds = []
        this.selectedSubRowKeys = []
        this.subMultiple = true
      },
      onClickRow (record, index) {
        return {
          on: {
            click: (event) => {
              if (event.target !== undefined && event.target.localName === 'td') {
                if (this.validaData()) {
                  this.selectItem = record
                  // this.updateRow(record)
                }
              }
            }
          }
        }
      },
      /** 搜索按钮操作 */
      handleQuery () {
        this.queryParam.pageNum = 1
        this.getList()
      },
      handleQueryRoleUser () {
        this.querySubParam.pageNum = 1
        this.getRoleUserList()
      },
      addRow () {
        const flag = this.validaData()
        if (flag) {
          // 角色添加行方法
          const id = randomUUID()
          const newRow = {
            id: 'newRow-' + id, // newRow 表示该行是新增的，提交成功后 key替换为数据库ID
            handleType: 'add',
            roleName: '',
            roleKey: '',
            status: '0',
            operation: '',
            editable: true
          }
          // 关闭所有已打卡行编辑
          this.closeEditCell(this.list)
          this.list.unshift(newRow)
          this.$nextTick(() => (
            this.selectItem = newRow
          ))
        }
      },
      updateRow (record) {
        // if (record.roleKey === 'admin') {
        //   this.$message.info('管理员不允许修改！')
        // } else {
          // 角色编辑行方法
          const newData = [...this.list]
          this.closeEditCell(newData)
          record.handleType = 'edit'
          record.editable = true
          this.list = newData
          // this.getRoleUserList(record.id)
          this.$nextTick(() => (
            this.selectItem = record
          ))
        // }
      },
      cancelEditCell (record) {
        if (this.validaData()) {
          // 取消行编辑
          const newData = [...this.list]
          record.editable = false
          this.list = newData
        }
      },
      realDeleteRow (record, type) {
        if (record.roleKey === 'admin') {
          this.$message.info('管理员不允许删除！')
        } else {
          const newData = [...this.list]
          const id = record.id
          record.handleType = 'delete'
          if (id.indexOf('newRow-') < 0) {
            // 数据库数据需要保存到待删除集合最终提交数据库删除
            this.deleteData.push(record)
          }
          const target = newData.filter(item => record.id !== item.id)
          if (target) {
            this.list = target
          }
          if (type !== 'batch') {
            this.selectFirstRecord()
          }
        }
      },
      deleteRow (record, type) {
        if (type !== 'batch') {
          const id = record.id
          if (id.indexOf('newRow-') >= 0) {
            // 针对前台添加为保存数据库的数据直接删除，无需询问
           this.realDeleteRow(record, type)
          } else {
            const that = this
            this.$confirm({
              title: '删除角色会删除相关的菜单，用户关系等，确认删除吗?',
              onOk () {
                that.realDeleteRow(record, type)
              },
              onCancel () {}
            })
          }
        } else {
          this.realDeleteRow(record, type)
        }
      },
      batchDeleteRow () {
        const that = this
        this.$confirm({
          title: '删除角色会删除相关的菜单，用户关系等，确认删除吗?',
          // content: '当前选中编号为' + roleIds + '的数据',
          onOk () {
            that.ids.forEach(id => {
              const deleteRowData = that.list.filter(item => id === item.id)[0]
              that.deleteRow(deleteRowData, 'batch')
            })
            that.selectFirstRecord()
          },
          onCancel () {}
        })
      },
      selectFirstRecord () {
        // 定位选中行到第一条数据
        if (this.list.length > 0) {
           this.selectItem = this.list[0]
        } else {
          // 移除子表数据
           this.subList = []
           this.subTotal = 0
        }
      },
      batchSaveRole () {
        // 批量保存角色数据
         let saveList = this.list.filter(item => (item.handleType === 'add' || item.handleType === 'edit'))
         saveList = saveList.concat(this.deleteData)
         if (saveList.length === 0) {
             this.$message.info('没有可保存的数据！')
         } else {
           const flag = this.validaData()
           if (flag) {
              batchSaveRole(saveList).then(response => {
                this.$message.success(
                  '保存成功',
                  3
                )
                this.getList()
              })
             }
         }
      },
      validaData () {
        let flag = true
        this.list.forEach(item => {
          if (item.handleType !== 'undefined' && (item.handleType === 'add' || item.handleType === 'edit')) {
            if (item.roleName === '' || item.roleName === 'undefined' || item.roleName === null) {
              this.$message.info('请先维护角色名称为空的数据！')
              flag = false
            }
            if (flag && (item.roleKey === '' || item.roleKey === 'undefined' || item.roleKey === null)) {
              this.$message.info('请先维护角色编码为空的数据！')
              flag = false
            }
          }
        })
        return flag
      },
      closeEditCell (data) {
        // 关闭所有打开的可编辑行
        const list = data.filter(item => item.editable === true)
        list.forEach(item => {
          item.editable = false
        })
      },
      /* 角色状态修改 */
          confirmHandleStatus (row) {
            const text = row.status === '1' ? '启用' : '停用'
            row.status = row.status === '0' ? '1' : '0'
            changeRoleStatus(row.id, row.status)
            .then(() => {
              this.$message.success(
                text + '成功',
                3
              )
            }).catch(function () {
              this.$message.error(
                text + '异常',
                3
              )
            })
          },
      handleAddUser () {
        this.$nextTick(() => (
          this.$refs.selectUserRef.showSelectUser()
        ))
      },
      onShowSizeChange (current, pageSize) {
        this.queryParam.pageSize = pageSize
        this.getList()
      },
      onShowSizeSubChange (current, pageSize) {
        this.querySubParam.pageSize = pageSize
        this.getRoleUserList()
      },
      onSizeChange (current, size) {
        this.queryParam.pageNum = 1
        this.queryParam.pageSize = size
        this.getList()
      },
      changeSize (current, pageSize) {
        this.queryParam.pageNum = current
        this.queryParam.pageSize = pageSize
        this.getList()
      },
      changeSubSize (current, pageSize) {
        this.querySubParam.pageNum = current
        this.querySubParam.pageSize = pageSize
        this.getRoleUserList()
      },
      onSelectChange (selectedRowKeys, selectedRows) {
        this.selectedRowKeys = selectedRowKeys
        this.selectedRows = selectedRows
        this.ids = this.selectedRows.map(item => item.id)
        this.single = selectedRowKeys.length !== 1
        this.multiple = !selectedRowKeys.length
      },
      onSelectSubChange (selectedSubRowKeys, selectedSubRows) {
        this.selectedSubRowKeys = selectedSubRowKeys
        this.selectedSubRows = selectedSubRows
        this.subIds = this.selectedSubRows.map(item => item.id)
        this.subMultiple = !selectedSubRowKeys.length
      },
      handleDeleteSub (row) {
         var that = this
        const userIds = row.id || this.subIds
        this.$confirm({
          title: '确认删除所选中数据?',
          onOk () {
             return delRoleUser(that.currentSelectRoleId, userIds)
              .then(() => {
                that.onSelectSubChange([], [])
                that.getRoleUserList()
                that.$message.success(
                  '删除成功',
                  3
                )
              })
          },
          onCancel () {}
        })
      },
      /** 导出按钮操作 */
      handleExport () {
        var that = this
        this.$confirm({
          title: '是否确认导出?',
          content: '此操作将导出当前条件下所有数据而非选中数据',
          onOk () {
            return exportRole(that.queryParam)
              .then(response => {
                that.download(response.msg)
                that.$message.success(
                  '导出成功',
                  3
                )
              })
          },
          onCancel () {}
        })
      },
      renderRowStyle (currentRow) { // 增加表格选中行样式
        // 类数组
        const rowEles = document.getElementsByClassName('ant-table-row')
        const rowSelectEles = document.getElementsByClassName('row-selection')
        let rowList
        if (rowSelectEles.length) {
          rowSelectEles[0].classList.remove('row-selection')
        }
        if (rowEles.length) {
          rowList = [...rowEles]
          // 这里不用 === 是因为获取的 rowKey 是 String 类型，而给与的原数据 key 为 Number 类型
          // 若要用 === ，事先进行类型转换再用吧
          rowList.find(row => row.dataset.rowKey === currentRow.id).classList.add('row-selection')
        }
      }
    }
  }
</script>
<style lang="less">
  .ant-table-row.row-selection {
    background-color: #F0F2F5;
  }
</style>
