<template>
  <div class="app-container">
    <div class="filter-container">
      <el-form>
        <el-form-item>
          <el-input
            v-model="filterText"
            placeholder="输入部门关键字进行过滤"
            style="width: 200px"
          />
          <el-input
            v-model="query.nickname"
            placeholder="昵称"
            style="width: 200px"
            clearable
            @keyup.enter.native="crud.toQuery"
          />
          <el-input
            v-model="query.username"
            placeholder="用户名"
            style="width: 100px"
            clearable
            @keyup.enter.native="crud.toQuery"
          />
          <el-button type="primary" icon="el-icon-search" @click="crud.toQuery">
            查询
          </el-button>
          <el-button
            v-if="hasPerm('user:add')"
            type="primary"
            icon="el-icon-edit"
            @click="showCreate"
          >
            添加
          </el-button>
          <el-button
            icon="el-icon-document"
            type="primary"
            @click="handleDownload"
          >
            导出Excel
          </el-button>
        </el-form-item>
      </el-form>
    </div>

    <el-row>
      <el-col :span="4">
        <el-tree
          ref="tree"
          :data="treeData"
          :filter-node-method="filterNode"
          :props="defaultProps"
          node-key="id"
          :default-expanded-keys="[1]"
          @node-click="handleNodeClick"
        />
      </el-col>
      <el-col :span="20">
        <!--表格内容-->
        <CustomTable ref="customTable" :col-configs="colConfigs" :columns="columns" :crud="crud">
          <el-table-column slot="operation" align="center" width="100" label="操作">
            <template slot-scope="scope">
              <Edit :data="scope.row" :disabled-edit="false" />
              <Delete :data="scope.row" style="margin-left: 5px" />
            </template>
          </el-table-column>
        </CustomTable>
        <pagination />
      </el-col>
    </el-row>

    <el-dialog :title="textMap[dialogStatus]" :visible="crud.status.editor > 0">
      <el-form
        ref="tempUser"
        :model="tempUser"
        :rules="rules"
        class="small-space"
        label-position="left"
        label-width="120px"
        style="width: 300px; margin-left: 50px"
      >
        <el-form-item
          v-if="dialogStatus === 'create'"
          label="用户名"
          prop="username"
          required
        >
          <el-input v-model="tempUser.username" type="text" />
        </el-form-item>
        <el-form-item
          v-if="dialogStatus === 'create'"
          label="昵称"
          prop="nickname"
          required
        >
          <el-input v-model="tempUser.nickname" type="text" />
        </el-form-item>
        <el-form-item
          v-if="dialogStatus === 'create'"
          label="密码"
          prop="password"
          required
        >
          <el-input v-model="tempUser.password" type="password" />
        </el-form-item>
        <el-form-item v-else label="新密码">
          <el-input
            v-model="tempUser.password"
            type="password"
            placeholder="不填则表示不修改"
          />
        </el-form-item>
        <el-form-item
          v-if="dialogStatus === 'update'"
          label="新签名密码"
          prop="signPassword"
        >
          <el-input
            v-model="tempUser.signPassword"
            type="password"
            placeholder="不填则表示不修改"
          />
        </el-form-item>
        <el-form-item label="角色" prop="roleIds">
          <el-select
            v-model="roleIds"
            multiple
            placeholder="请选择"
            style="width: 180px"
          >
            <el-option
              v-for="item in roles"
              :key="item.id"
              :label="item.roleName"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-upload
          v-if="dialogStatus === 'update'"
          :before-upload="beforeUpload"
          :on-remove="handleRemove"
          :file-list="fileList"
          :limit="1"
          action="123"
          list-type="picture"
        >
          <el-button size="small" type="primary">
            点击上传签名图片
          </el-button>
          <div slot="tip" class="el-upload__tip">
            只能上传jpg/png文件，且不超过500kb
          </div>
        </el-upload>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="crud.cancelCU">
          取 消
        </el-button>
        <el-button
          v-if="dialogStatus === 'create'"
          type="success"
          @click="createUser"
        >
          创 建
        </el-button>
        <el-button v-else type="primary" @click="updateUser">
          修 改
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import CRUD, { form, header, presenter } from '@/components/Crud/crud'
// import Crud from '@/components/Crud'
// import Query from '@/components/Crud/Query'
import Edit from '@/components/Crud/Edit'
import Delete from '@/components/Crud/Delete'
import CustomTable from '@/components/Crud/Table'
import Pagination from '@/components/Crud/Pagination'
import CrudRole from '@/api/role'
import { mapGetters } from 'vuex'
import { parseTime } from '../../utils'
// import Pagination from '@/components/Pagination'
// crud交由presenter持有
const defaultCrud = presenter(CRUD({
  title: '用户',
  url: '/user/list',
  orderBy: ['id asc'],
  param: {},
  crudMethod: { ...CrudRole }
}))

// 设置初始form
const defaultForm = form({
  id: null,
  roleName: '',
  roleCode: '',
  menuOptionIds: {}
})
export default {
  name: 'UserList',
  components: { Pagination, CustomTable, Edit, Delete },
  mixins: [defaultCrud, defaultForm, header()],
  data() {
    return {
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      colConfigs: [
        { prop: 'nickname', label: '昵称', align: 'center' },
        { prop: 'username', label: '用户名', align: 'center' },
        { prop: 'departmentId', label: '所属部门', align: 'center' },
        { prop: 'createTime', label: '创建时间', align: 'center' },
        { prop: 'updateTime', label: '最近修改时间', align: 'center' },
        { slot: 'operation' }
      ],
      treeData: [],
      filterText: '',
      totalCount: 0, // 分页组件--数据总条数
      list: [], // 表格的数据
      listQuery: {
        pageNum: 1,
        // 页码
        pageSize: 20, // 每页条数
        orderBy: 'id asc'
      },
      roles: [], // 角色列表
      dialogStatus: 'create',
      dialogFormVisible: false,
      textMap: {
        update: '编辑',
        create: '新建用户'
      },
      tempUser: {},
      rules: {
        username: [
          { required: true, message: '请填写用户名', trigger: 'blur' }
        ],
        password: [{ required: true, message: '请填写密码', trigger: 'blur' }],
        nickname: [{ required: true, message: '请填写昵称', trigger: 'blur' }]
      },
      fileList: [],
      depts: [],
      roleIds: []
    }
  },
  computed: {
    ...mapGetters(['userId'])
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val)
    }
  },
  created() {
    // this.getList()
    this.getDepartment()
    this.getAllDepartment()
    if (this.hasPerm('user:add') || this.hasPerm('user:update')) {
      this.getAllRoles()
    }
    console.log(this.crud, this.query, '啊哈哈哈')
  },
  methods: {
    getAllRoles() {
      this.api({
        url: '/role/all',
        method: 'get'
      }).then((data) => {
        this.roles = data
      })
    },
    // 查询检验科室
    getDepartment() {
      this.api({
        url: '/department/all',
        method: 'get'
      }).then((data) => {
        this.depts = data
      })
    },
    getAllDepartment() {
      this.api({
        url: '/department/tree',
        method: 'get'
      }).then((data) => {
        this.treeData = data
      })
    },
    getList() {
      // 查询列表
      this.api({
        url: '/user/list',
        method: 'get',
        params: this.listQuery
      }).then((data) => {
        this.list = data.list
        this.totalCount = data.total
      })
    },
    handleNodeClick(data) {
      if (data.id === 1) {
        this.departmentId = 0
        this.query.departmentId = null
      } else {
        this.departmentId = data.id
        this.query.departmentId = data.id
      }
      this.crud.toQuery()
    },
    filterNode(value, data) {
      console.log(value, data)
      if (!value) return true
      return data.name.indexOf(value) !== -1
    },
    handleFilter() {
      // 查询事件
      this.query.pageNum = 1
      this.getList()
    },
    handleRemove(file, fileList) {
      this.fileList = []
      this.tempUser.signImg = ''
    },
    beforeUpload(file) {
      const isJPG = file.type === 'image/jpeg' || file.type === 'image/png'
      if (!isJPG) {
        this.$message.error('只能上传jpg/png格式的图片')
        return false
      }
      const fd = new FormData()
      fd.append('file', file)
      fd.append('userId', this.tempUser.id)
      this.preview({
        url: '/upload/uploadSignImg',
        method: 'post',
        data: fd
      }).then((data) => {
        this.tempUser.signImg = data
        this.fileList = JSON.parse(data)
        this.fileList[0].url =
          process.env.VUE_APP_IMG_URL + 'signImage/' + this.fileList[0].name
      })
      return true
    },
    showCreate() {
      // 显示新增对话框
      this.tempUser = {}
      this.dialogStatus = 'create'
      console.log(this.crud.status.editor, '哈哈哈')
      this.dialogFormVisible = true
      this.roleIds.length = 0
    },
    showUpdate($index) {
      const user = this.list[$index]
      this.tempUser = user
      this.roleIds.length = 0
      if (user.roleIds !== null && user.roleIds !== undefined) {
        if (user.roleIds.indexOf(',') !== -1) {
          user.roleIds
            .split(',')
            .forEach((roleId) => this.roleIds.push(Number(roleId)))
        }
      }
      if (user.signImg !== null && user.signImg !== '') {
        this.tempUser.signImg = user.signImg
        this.fileList = JSON.parse(user.signImg)
        if (this.fileList.length > 0) {
          this.fileList[0].url =
            process.env.VUE_APP_IMG_URL + 'signImage/' + this.fileList[0].name
        }
      } else {
        this.fileList = []
      }
      this.dialogStatus = 'update'
      this.dialogFormVisible = true
    },
    createUser() {
      // 添加新用户
      this.$refs['tempUser'].validate((valid) => {
        if (valid) {
          if (this.tempUser.password.length < 8) {
            this.$message.warning('密码长度不能低于8位')
            return false
          }
          this.tempUser.deleteStatus = 1
          this.api({
            url: '/user/addUser',
            method: 'post',
            data: {
              user: this.tempUser,
              roleIds: this.roleIds
            }
          }).then(() => {
            this.$message.success('添加成功。')
            this.getList()
            this.crud.cancelCU()
          })
        } else {
          return false
        }
      })
    },
    updateUser() {
      // 修改用户信息
      this.$refs['tempUser'].validate((valid) => {
        if (valid) {
          if (this.tempUser.password && this.tempUser.password.length < 8) {
            this.$message.warning('密码长度不能低于8位')
            return false
          }
          const _vue = this
          this.api({
            url: '/user/updateUser',
            method: 'post',
            data: {
              user: this.tempUser,
              roleIds: this.roleIds
            }
          }).then(() => {
            let msg = '修改成功'
            this.dialogFormVisible = false
            if (this.userId === this.tempUser.userId) {
              msg = '修改成功,部分信息重新登录后生效'
            }
            this.$message({
              message: msg,
              type: 'success',
              duration: 1000,
              onClose: () => {
                _vue.getList()
              }
            })
          })
        } else {
          return false
        }
      })
    },
    removeUser($index) {
      const _vue = this
      this.$confirm('确定删除此用户?', '提示', {
        confirmButtonText: '确定',
        showCancelButton: false,
        type: 'warning'
      }).then(() => {
        const user = _vue.list[$index]
        user.deleteStatus = '0'
        _vue
          .api({
            url: '/user/updateUser',
            method: 'post',
            data: { user: user }
          })
          .then(() => {
            _vue.$message.success('删除成功')
            _vue.getList()
          })
          .catch(() => {
            _vue.$message.error('删除失败')
          })
      })
    },
    handleDownload() {
      import('@/vendor/Export2Excel').then((excel) => {
        const tHeader = [
          'Id',
          '昵称',
          '用户名',
          '角色',
          '创建时间',
          '最近修改时间'
        ]
        const filterVal = [
          'id',
          'nickname',
          'username',
          'roleId',
          'createTime',
          'updateTime'
        ]
        const list = this.list
        const data = this.formatJson(filterVal, list)
        excel.export_json_to_excel({
          header: tHeader,
          data,
          filename: this.filename,
          autoWidth: this.autoWidth
        })
      })
    },
    formatJson(filterVal, jsonData) {
      return jsonData.map((v) =>
        filterVal.map((j) => {
          if (j === 'timestamp') {
            return parseTime(v[j])
          } else {
            return v[j]
          }
        })
      )
    },
    formatterRoleId(row, column, cellValue) {
      if (cellValue) {
        const roleName = []
        cellValue.split(',').forEach((roleId) => {
          const role = this.roles.filter(
            (role) => role.id === Number(roleId)
          )[0]
          if (role) {
            roleName.push(role.roleName)
          }
        })
        return roleName.join(',')
      } else {
        return null
      }
    },
    formatterDepartmentName(row, column, cellValue) {
      if (cellValue !== null) {
        let departmentName
        this.depts.forEach((dep) => {
          if (dep.id === cellValue) {
            departmentName = dep.name
            return false
          } else {
            return true
          }
        })
        return departmentName
      } else {
        return null
      }
    }
  }
}
</script>
