<template>
  <com-head :options="headList" showCtrl>
    <el-form label-width="90px" inline="true">
      <el-form-item label="用户姓名：">
        <el-input v-model="search.state.nickName" placeholder="请输入"></el-input>
      </el-form-item>
      <el-form-item label="手机号：">
        <el-input v-model="search.state.userName" placeholder="请输入"></el-input>
      </el-form-item>
      <el-form-item label="所属公司：">
        <com-company v-model="search.state.departmentId" />
      </el-form-item>
      <el-form-item class="searh-btns">
        <el-button @click="search.reset">重置</el-button>
        <el-button type="primary" @click="search.submit">查询</el-button>
      </el-form-item>
    </el-form>
  </com-head>

  <div class="body-layer">
    <div class="body-head">
      <h3>用户列表</h3>
      <div class="table-ctrl-right">
        <el-button
          v-if="auth.add"
          type="primary"
          icon="el-icon-plus"
          @click="oper.readyInsert"
          >创建用户</el-button
        >
      </div>
    </div>

    <el-table
      class="user-table"
      ref="multipleTable"
      :data="dataList.state"
      tooltip-effect="dark"
      style="width: 100%"
      @row-click="selectRow"
    >
      <el-table-column label="姓名" prop="nickName"></el-table-column>
      <el-table-column label="手机号" prop="userName"></el-table-column>
      <el-table-column label="所属架构" prop="departmentName"></el-table-column>
      <el-table-column label="角色" prop="roleName"></el-table-column>
      <el-table-column label="创建時間" prop="createTime"></el-table-column>
      <el-table-column label="操作" v-slot:default="{ row }" v-if="auth.update || auth.updatePwd || auth.delete">
        <span class="oper-span" @click="updateInfo(row)" v-if="auth.update">编辑</span>
        <span class="oper-span tip-spw" @click="updatePwd(row)" @mouseenter="enterHandle" @mouseout="outHandle" v-if="auth.updatePwd">重置密码</span>
        <!-- <el-tooltip content="密码重置为88888888VR，可登录修改" placement="top">
          <span class="oper-span tip-spw" @click="updatePwd(row)" v-if="auth.updatePwd">重置密码</span>
        </el-tooltip> -->
        <span class="oper-span" @click="delUser(row)" v-if="auth.delete && row.roleName !== '超级管理员'" style="color: var(--primaryColor)">删除</span>
      </el-table-column>
    </el-table>
    <com-pagination
      @size-change="pag.sizeChange"
      @current-change="pag.currentChange"
      :current-page="pag.state.currPage"
      :page-size="pag.state.size"
      layout="total, sizes, prev, pager, next, jumper"
      :total="pag.state.total"/>
  </div>
  
  <div class="tip" :style="{left: tip.left, top: tip.top}" v-if="tip.show"></div>

  <com-dialog
    :title="(oper.state.id ? '修改' : '创建') + '用户'"
    :enterText="oper.state.id ? '保 存' : '创 建'"
    v-model:show="oper.state.show"
    @submit="operItem"
  >
    <el-form ref="form" :model="form" label-width="100px" class="user-from">
      <el-form-item label="姓名：" class="mandatory">
        <el-input v-model="oper.state.nickName" placeholder="请输入"></el-input>
      </el-form-item>
      <el-form-item label="手机号：" class="mandatory">
        <el-input v-model="oper.state.userName" placeholder="请输入"></el-input>
      </el-form-item>

      <template v-if="!oper.state.id">
        <div class="stop-psw">
          <input type="text">
          <input type="password" name="" id="">
        </div>

        <el-form-item label="密码：" class="mandatory">
          <el-input v-model="oper.state.password" type="password" placeholder="必须包含数字、字母，长度8-16个"></el-input>
        </el-form-item>
        <el-form-item label="二次确认：" class="mandatory">
          <el-input v-model="oper.state.confirmPwd" type="password" placeholder="必须包含数字、字母，长度8-16个"></el-input>
        </el-form-item>
      </template>

      <el-form-item label="所属架构：" class="mandatory">
        <com-company v-model="oper.state.departmentId" ref="company" @asyncLoad="updateRoleId" style="width: 100%" hideAll />
      </el-form-item>
      
      <el-form-item label="角色：" class="roleName" v-if="showRole">
        <com-role v-model="oper.state.roleId" style="width: 100%" hideAll @asyncLoad="updateRoleId" :notShow="notShowRole" ref="roleCom" />
      </el-form-item>
    </el-form>
  </com-dialog>
</template>


<script>
import { ref } from "vue";
import getTableState from "@/state/tableRef";
import comDialog from "@/components/dialog";
import comHead from "@/components/head";
import comCompany from "@/components/company-select";
import comPagination from "@/components/pagination";
import roleCompany from "@/components/role-select";
import auth from "@/state/viewAuth";
import axios from 'axios'
import {encryption} from '@/util'
import {PSW, PHONE} from '@/constant/REG'

import {
  getUserList,
  insertUser,
  updateUser,
  resetUserPWD,
  deleteUser
} from '@/request/config'


export default {
  name: 'user',
  setup() {
    const state = getTableState({
      updateUrl: updateUser,
      insertUrl: insertUser,
      getUrl: getUserList,
      operAttr: {
        nickName: "",
        userName: "",
        departmentId: "",
        password: '',
        confirmPwd: '',
        roleId: ""
      },
      searchAttr: { nickName: "", userName: '', departmentId: '' },
      pagAttr: {totalNum: 'total'}
    });
    const headList = ref([{ name: "用户管理", value: 2 }]);

    const updateInfo = (row) => {
      state.oper.value.readyUpdate(row)
    }
    
    return { ...state, headList, updateInfo, auth, company: null };
  },
  data() {
    return {
      notShowRole: [],
      showRole: true,
      tip: {
        show: false,
        left: 0,
        top: 0
      }
    }
  },
  watch: {
    'oper.state.departmentId'() {
      this.updateRoleId()
    },
    'oper.state.roleId'() {
      this.updateRoleId()
    }
  },
  methods: {
    async updateRoleId() {
      let notShowRole = this.getNotShowRole()
      if (notShowRole.includes(this.oper.state.roleId)) {
        let item = this.$refs.roleCom.allData.find(({id}) => 
          !notShowRole.includes(id)
        )
        await this.$nextTick()
        await this.$refs.roleCom.$nextTick()
        this.notShowRole = notShowRole
        this.oper.state.roleId = item.id
      } else {
        // await this.$refs.roleCom.$nextTick()
        this.notShowRole = notShowRole
      }

      // this.$refs.roleCom.$forceUpdate()
    },
    getNotShowRole() {
      if (!this.$refs.company || !this.$refs.roleCom || !this.$refs.roleCom.allData) return []
      let coms = this.$refs.company.options
      let cCom 

      if (this.oper.state.departmentId) {
        cCom = coms.find(({id}) => id == this.oper.state.departmentId)
      } 
      if (!cCom) {
        cCom = coms.find(({parentId}) => !parentId)
      }

      if (cCom) {
        let roles = cCom.parentId ?
          this.$refs.roleCom.allData.filter(({roleKey}) => roleKey === 'group') :
          this.$refs.roleCom.allData.filter(({roleKey}) => roleKey !== 'group')

        return roles.map(({id}) => id)
      } else {
        return []
      }
    },
    enterHandle(ev) {
      this.tip.show = true
      this.tip.left = ev.pageX + 'px'
      this.tip.top = ev.pageY + 'px'
    },
    outHandle() {
      this.tip.show = false
    },
    async operItem() {
      const updatePhone = this.oper.state.__oldData ? this.oper.state.__oldData.userName !== this.oper.state.userName : true
      
      if (updatePhone && !PHONE.REG.test(this.oper.state.userName)) {
        return this.$alert(PHONE.tip, '提示')
      }
      if (this.oper.state.password !== this.oper.state.confirmPwd) {
        return this.$alert('两次密码不一致！', '提示')
      }

      if (this.oper.state.id) {
        let updateState = {...this.oper.state, password: void 0, confirmPwd: void 0, updatePwd: void 0}
        if (!updatePhone) {
          delete updateState.userName
        }
        this.oper.update(updateState)
      } else if (this.oper.state.password === this.oper.state.confirmPwd) {
        if (PSW.REG.test(this.oper.state.password)) {
          let cryPsw = encryption(this.oper.state.password)
          this.oper.insert({
            ...this.oper.state,
            password: cryPsw,  
            confirmPwd: cryPsw,  
            updatePwd: void 0
          })
        } else {
          this.$alert(PSW.tip, '提示')
        }
      }
    },
    async updatePwd(row) {
      if (await this.$confirm(`确定要重置${row.nickName}的密码吗？`, '提示')) {
        await axios.get(resetUserPWD + row.id)
      }
    },
    async delUser(row) {
      if (await this.$confirm(`确定要删除${row.nickName}？`, '提示')) {
        await axios.get(deleteUser + row.id)
        this.dataList.refer()
      }
    }
  },
  components: {
    "com-dialog": comDialog,
    "com-head": comHead,
    "com-company": comCompany,
    "com-role": roleCompany,
    "com-pagination": comPagination
  },
};
</script>

<style lang="scss" scoped>
.table-ctrl-right {
  .search-scene {
    margin: 0 20px 0 26px;
  }
  i {
    margin-left: 20px;
    font-size: 1.7rem;
    vertical-align: middle;
    cursor: pointer;

    &.active {
      color: var(--primaryColor);
    }
  }
}

.user-from {
  width: 380px;
  margin: 0 auto;
}

.tip {
  position: fixed;
  left: 50%;
  top: 50%;
  z-index: 999;

  &::before {
    content: '密码重置为88888888，可登录修改';
    position: absolute;
    width: 205px;
    left: 50%;
    transform: translateX(-50%);
    bottom: 100%;
    border-radius: 4px;
    padding: 10px;
    z-index: 2000;
    font-size: 12px;
    line-height: 1.2;
    min-width: 10px;
    word-wrap: break-word;
    background: #303133;
    color: #fff;
    margin-bottom: 6px;
    
  }

  &::after {
    content: '';
    position: absolute;
    display: block;
    width: 0;
    height: 0;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    border-color: transparent;
    border-style: solid;
    border-width: 6px;
    border-top-color: #303133;
    border-bottom-width: 0;
  }
}
</style>

<style>
.user-table.el-table .cell {
  overflow: inherit;
}
</style>
