<template>
  <div class="main-box">
    <TreeFilter title="部门列表" :is-all="false" :data="treeFilterData" :default-value="initParam.deptId" @change="changeTreeFilter" />
    <div class="table-box">
      <ProTable
        ref="proTable"
        row-key="userId"
        :indent="20"
        :columns="columns"
        :request-api="listUserApi"
        :request-auto="false"
        :init-param="initParam"
        :search-col="{ xs: 1, sm: 1, md: 2, lg: 3, xl: 3 }"
      >
        <!-- 表格 header 按钮 -->
        <template #tableHeader="scope">
          <el-button type="primary" v-auth="['system:user:add']" :icon="CirclePlus" @click="openDialog(1, '用户新增')"> 新增 </el-button>
          <el-button type="primary" v-auth="['system:user:import']" :icon="Upload" plain @click="batchAdd">导入</el-button>
          <el-button type="primary" v-auth="['system:user:export']" :icon="Download" plain @click="downloadFile">导出</el-button>
          <el-button
            type="danger"
            v-auth="['system:user:remove']"
            :icon="Delete"
            plain
            :disabled="!scope.isSelected"
            @click="batchDelete(scope.selectedListIds)"
          >
            批量删除
          </el-button>
        </template>
        <!-- 表格操作 -->
        <template #operation="scope">
          <el-button type="primary" link v-if="scope.row.userId !== 1" :icon="EditPen" @click="openDialog(2, '用户编辑', scope.row)">编辑</el-button>
          <el-button type="primary" link v-if="scope.row.userId !== 1" :icon="Delete" @click="deleteAccount(scope.row)">删除</el-button>
          <el-button type="primary" link v-if="scope.row.userId !== 1" :icon="View" @click="handleResetPwd(scope.row)">重置密码</el-button>
        </template>
      </ProTable>
      <FormDialog ref="formDialogRef" />
      <ImportExcel ref="dialogRef" />
    </div>
  </div>
</template>

<script setup lang="tsx" name="UserManage">
import { onMounted, reactive, ref } from 'vue'
import { User } from '@/api/interface'
import { useDownload } from '@/hooks/useDownload'
import { useHandleData } from '@/hooks/useHandleData'
import { ElMessageBox, ElMessage } from 'element-plus'
import ProTable from '@/components/ProTable/index.vue'
import TreeFilter from '@/components/TreeFilter/index.vue'
import ImportExcel from '@/components/ImportExcel/index.vue'
import FormDialog from '@/components/DialogOld/form.vue'
import { CirclePlus, Download, Upload, View, Delete, EditPen } from '@element-plus/icons-vue'
import { ColumnProps, ProTableInstance } from '@/components/ProTable/interface'
import {
  listUserApi,
  delUserApi,
  addUserApi,
  updateUserApi,
  changeUserStatus,
  importTemplateApi,
  importDataApi,
  exportApi,
  getUserApi,
  deptTreeSelectApi,
  resetUserPwdApi
} from '@/api/modules/system/user'
import { getDictsApi } from '@/api/modules/system/dictData'
onMounted(() => {
  getTreeFilter()
})

// ProTable 实例
const proTable = ref<ProTableInstance>()
// 如果表格需要初始化请求参数，直接定义传给 ProTable(之后每次请求都会自动带上该参数，此参数更改之后也会一直带上，改变此参数会自动刷新表格数据)
const initParam = reactive({ deptId: '' })

// 获取 treeFilter 数据
// 当 proTable 的 requestAuto 属性为 false，不会自动请求表格数据，等待 treeFilter 数据回来之后，更改 initParam.departmentId 的值，才会触发请求 proTable 数据
const treeFilterData = ref<any>([])
const getTreeFilter = async () => {
  const { data } = await deptTreeSelectApi()
  treeFilterData.value = data
  initParam.deptId = treeFilterData.value[0].id
}

// 树形筛选切换
const changeTreeFilter = (val: string) => {
  // ElMessage.success('请注意查看请求参数变化 🤔')
  proTable.value!.pageable.pageNum = 1
  initParam.deptId = val
}

// 切换用户状态
const changeStatus = async (row: User.ResUserList) => {
  await useHandleData(changeUserStatus, { userId: row.userId, status: row.status == '1' ? 0 : 1 }, `切换【${row.userName}】用户状态`)
  proTable.value?.getTableList()
}

// 删除用户信息
const deleteAccount = async (params: User.ResUserList) => {
  await useHandleData(delUserApi, params.userId, `删除【${params.userName}】用户`)
  proTable.value?.getTableList()
}

// 批量删除用户信息
const batchDelete = async (ids: string[]) => {
  await useHandleData(delUserApi, ids, '删除所选用户信息')
  proTable.value?.clearSelection()
  proTable.value?.getTableList()
}

function handleResetPwd(row: any) {
  ElMessageBox.prompt('请输入"' + row.userName + '"的新密码', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    closeOnClickModal: false,
    inputPattern: /^.{5,20}$/,
    inputErrorMessage: '用户密码长度必须介于 5 和 20 之间'
  })
    .then(({ value }: any) => {
      resetUserPwdApi({ userId: row.userId, password: value }).then(res => {
        if (res.code == 200) ElMessage.success('修改成功，新密码是：' + value)
        else ElMessage.error(res.msg)
      })
    })
    .catch((e: any) => {
      console.log(e)
    })
}

// 导出用户列表
const downloadFile = async () => {
  ElMessageBox.confirm('确认导出用户数据?', '温馨提示', { type: 'warning' }).then(() =>
    useDownload(exportApi, '用户列表', proTable.value?.searchParam)
  )
}

// 批量添加用户
const dialogRef = ref<InstanceType<typeof ImportExcel> | null>(null)
const batchAdd = () => {
  const params = {
    title: '用户',
    tempApi: importTemplateApi,
    importApi: importDataApi,
    getTableList: proTable.value?.getTableList
  }
  dialogRef.value?.acceptParams(params)
}
const formDialogRef = ref<InstanceType<typeof FormDialog> | null>(null)
const postOptions = ref<any[]>([])
const roleOptions = ref<any[]>([])
// 打开弹框的功能
const openDialog = async (type: number, title: string, row?: any) => {
  let res = await getUserApi(row?.userId || null)

  postOptions.value = res.data.posts
  roleOptions.value = res.data.roles
  // 表单项配置
  const fieldList: Form.FieldItem[] = [
    {
      label: '用户昵称',
      placeholder: '请输入用户昵称',
      span: 12,
      field: 'nickName',
      rules: [{ required: true, message: '用户昵称不能为空' }]
    },
    {
      label: '归属部门',
      span: 12,
      field: 'deptId',
      placeholder: '请选择归属部门',
      enum: () => deptTreeSelectApi(),
      type: 'select-tree',
      options: {
        valueKey: 'id',
        labelKey: 'label',
        children: 'children'
      }
    },
    {
      label: '手机号码',
      placeholder: '请输入手机号码',
      span: 12,
      field: 'phonenumber',
      rules: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur' }]
    },
    {
      label: '邮箱',
      placeholder: '请输入邮箱',
      span: 12,
      field: 'email',
      rules: [{ type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }]
    },
    {
      label: '性别',
      span: 12,
      field: 'sex',
      enum: () => getDictsApi('sys_user_gender'),
      type: 'select',
      options: {
        labelKey: 'dictLabel',
        valueKey: 'dictValue'
      }
    },
    {
      label: '状态',
      span: 12,
      field: 'status',
      type: 'radio',
      enum: () => getDictsApi('sys_normal_disable'),
      options: {
        labelKey: 'dictLabel',
        valueKey: 'dictValue'
      }
    },
    {
      label: '岗位',
      span: 12,
      field: 'postIds',
      enum: postOptions.value,
      type: 'select',
      options: {
        valueKey: 'postId',
        labelKey: 'postName',
        multiple: true
      }
    },
    {
      label: '角色',
      span: 12,
      field: 'roleIds',
      enum: roleOptions.value,
      type: 'select',
      options: {
        valueKey: 'roleId',
        labelKey: 'roleName',
        multiple: true
      }
    },
    {
      label: '备注',
      placeholder: '请输入内容',
      field: 'remark',
      type: 'textarea'
    }
  ]
  if (type == 1) {
    fieldList.splice(
      4,
      0,
      {
        label: '用户名称',
        placeholder: '请输入用户名称',
        field: 'userName',
        span: 12,
        rules: [
          { required: true, message: '用户名称不能为空' },
          { min: 2, max: 20, message: '用户名称长度必须介于 2 和 20 之间', trigger: 'blur' }
        ]
      },
      {
        label: '用户密码',
        placeholder: '请输入密码',
        field: 'password',
        type: 'password',
        showPassword: true,
        span: 12,
        rules: [
          { required: true, message: '密码不能为空' },
          { min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' }
        ]
      }
    )
  }
  if (row?.userId) {
    res.data.user.postIds = res.data.postIds
    res.data.user.roleIds = res.data.roleIds
  }

  const params = {
    title,
    width: 680,
    isEdit: type !== 3,
    fieldList: fieldList,
    model: type == 1 ? {} : res.data.user,
    api: type == 1 ? addUserApi : updateUserApi,
    getTableList: proTable.value?.getTableList
  }

  formDialogRef.value?.openDialog(params)
}
// 表格配置项
const columns = reactive<ColumnProps<User.ResUserList>[]>([
  { type: 'selection', fixed: 'left', width: 70 },
  { prop: 'userId', label: '用户编号' },
  { prop: 'userName', label: '用户名称', search: { el: 'input' }, width: 120 },
  { prop: 'nickName', label: '用户昵称', search: { el: 'input' }, width: 120 },
  { prop: 'dept.deptName', label: '部门', width: 120 },
  { prop: 'phonenumber', label: '手机号码', width: 120 },
  {
    prop: 'status',
    label: '用户状态',
    width: 120,
    enum: () => getDictsApi('sys_normal_disable'),
    search: { el: 'tree-select' },
    fieldNames: { label: 'dictLabel', value: 'dictValue' },
    render: scope => {
      return (
        <el-switch
          model-value={scope.row.status}
          active-text={scope.row.status === '1' ? '禁用' : '启用'}
          active-value={'0'}
          inactive-value={'1'}
          onClick={() => changeStatus(scope.row)}
        />
      )
    }
  },
  {
    prop: 'sex',
    label: '性别',
    width: 120,
    enum: () => getDictsApi('sys_user_gender'),
    fieldNames: {
      label: 'dictLabel',
      value: 'dictValue'
    }
  },
  { prop: 'createTime', label: '创建时间', width: 180 },
  { prop: 'operation', label: '操作', width: 240, fixed: 'right' }
])
</script>
