zhou zhou
4 小时以前 6877c9caa25162e570a3e2a99a5b2ce3ef88368b
rsf-design/src/views/system/user/index.vue
@@ -14,6 +14,18 @@
        <template #left>
          <ElSpace wrap>
            <ElButton v-auth="'add'" @click="showDialog('add')" v-ripple>新增用户</ElButton>
            <ElButton
              v-auth="'delete'"
              type="danger"
              :disabled="selectedRows.length === 0"
              @click="handleBatchDelete"
              v-ripple
            >
              批量删除
            </ElButton>
            <ElButton v-auth="'query'" :loading="exportLoading" @click="handleExport" v-ripple
              >导出</ElButton
            >
          </ElSpace>
        </template>
      </ArtTableHeader>
@@ -23,6 +35,7 @@
        :data="data"
        :columns="columns"
        :pagination="pagination"
        @selection-change="handleSelectionChange"
        @pagination:size-change="handleSizeChange"
        @pagination:current-change="handleCurrentChange"
      />
@@ -48,8 +61,10 @@
<script setup>
  import request from '@/utils/http'
  import { guardRequestWithMessage } from '@/utils/sys/requestGuard'
  import { useUserStore } from '@/store/modules/user'
  import {
    fetchDeleteUser,
    fetchExportUserReport,
    fetchGetDeptTree,
    fetchGetRoleOptions,
    fetchGetUserDetail,
@@ -89,10 +104,13 @@
  const detailDrawerVisible = ref(false)
  const detailLoading = ref(false)
  const detailUserData = ref({})
  const selectedRows = ref([])
  const roleOptions = ref([])
  const deptTreeOptions = ref([])
  const exportLoading = ref(false)
  const RESET_PASSWORD = '123456'
  const { hasAuth } = useAuth()
  const userStore = useUserStore()
  const fetchUserPage = (params = {}) => {
    return request.post({
@@ -122,6 +140,12 @@
      apiParams: buildUserPageQueryParams(searchForm.value),
      paginationKey: getUserPaginationKey(),
      columnsFactory: () => [
        {
          type: 'selection',
          width: 52,
          fixed: 'left',
          align: 'center'
        },
        {
          prop: 'username',
          label: '用户名',
@@ -277,6 +301,10 @@
    getData()
  }
  const handleSelectionChange = (rows) => {
    selectedRows.value = Array.isArray(rows) ? rows : []
  }
  const handleReset = () => {
    Object.assign(searchForm.value, createUserSearchState())
    resetSearchParams()
@@ -342,17 +370,46 @@
  const handleDelete = async (row) => {
    try {
      await ElMessageBox.confirm(`确定要删除用户「${row.username || row.nickname || row.id}」吗?`, '删除确认', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
      await ElMessageBox.confirm(
        `确定要删除用户「${row.username || row.nickname || row.id}」吗?`,
        '删除确认',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
      )
      await fetchDeleteUser(row.id)
      ElMessage.success('删除成功')
      await refreshRemove()
    } catch (error) {
      if (error !== 'cancel') {
        ElMessage.error(error?.message || '删除失败')
      }
    }
  }
  const handleBatchDelete = async () => {
    if (!selectedRows.value.length) return
    const ids = selectedRows.value
      .map((item) => item?.id)
      .filter((id) => id !== void 0 && id !== null)
    if (!ids.length) return
    try {
      await ElMessageBox.confirm(`确定要批量删除选中的 ${ids.length} 个用户吗?`, '批量删除确认', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
      await fetchDeleteUser(ids.join(','))
      ElMessage.success('批量删除成功')
      selectedRows.value = []
      await refreshRemove()
    } catch (error) {
      if (error !== 'cancel') {
        ElMessage.error(error?.message || '批量删除失败')
      }
    }
  }
@@ -404,4 +461,41 @@
      row._statusLoading = false
    }
  }
  const handleExport = async () => {
    exportLoading.value = true
    try {
      const response = await guardRequestWithMessage(
        fetchExportUserReport(buildUserSearchParams(searchForm.value), {
          headers: {
            Authorization: userStore.accessToken || ''
          }
        }),
        null,
        {
          timeoutMessage: '用户导出超时,已停止等待'
        }
      )
      if (!response) {
        return
      }
      if (!response.ok) {
        throw new Error(`导出失败,状态码:${response.status}`)
      }
      const blob = await response.blob()
      const downloadUrl = window.URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = downloadUrl
      link.download = 'user.xlsx'
      document.body.appendChild(link)
      link.click()
      link.remove()
      window.URL.revokeObjectURL(downloadUrl)
      ElMessage.success('导出成功')
    } catch (error) {
      ElMessage.error(error?.message || '导出失败')
    } finally {
      exportLoading.value = false
    }
  }
</script>