From 6877c9caa25162e570a3e2a99a5b2ce3ef88368b Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期一, 13 四月 2026 13:48:37 +0800
Subject: [PATCH] #页面优化

---
 rsf-design/src/views/system/user/index.vue |  104 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 99 insertions(+), 5 deletions(-)

diff --git a/rsf-design/src/views/system/user/index.vue b/rsf-design/src/views/system/user/index.vue
index 8800cf1..53fcf15 100644
--- a/rsf-design/src/views/system/user/index.vue
+++ b/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>

--
Gitblit v1.9.1