优化更新
This commit is contained in:
@@ -178,6 +178,23 @@ export default {
|
||||
return await request.post('roles/batch-copy', params)
|
||||
},
|
||||
},
|
||||
export: {
|
||||
post: async function (params) {
|
||||
return await request.post('roles/export', params, { responseType: 'blob' })
|
||||
},
|
||||
},
|
||||
import: {
|
||||
post: async function (formData) {
|
||||
return await request.post('roles/import', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' }
|
||||
})
|
||||
},
|
||||
},
|
||||
downloadTemplate: {
|
||||
get: async function () {
|
||||
return await request.get('roles/download-template', { responseType: 'blob' })
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// 权限管理
|
||||
@@ -227,6 +244,23 @@ export default {
|
||||
return await request.post('permissions/batch-status', params)
|
||||
},
|
||||
},
|
||||
export: {
|
||||
post: async function (params) {
|
||||
return await request.post('permissions/export', params, { responseType: 'blob' })
|
||||
},
|
||||
},
|
||||
import: {
|
||||
post: async function (formData) {
|
||||
return await request.post('permissions/import', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' }
|
||||
})
|
||||
},
|
||||
},
|
||||
downloadTemplate: {
|
||||
get: async function () {
|
||||
return await request.get('permissions/download-template', { responseType: 'blob' })
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// 部门管理
|
||||
|
||||
@@ -104,34 +104,22 @@
|
||||
<!-- 新增/编辑/查看部门弹窗 -->
|
||||
<save-dialog v-if="dialog.save" ref="saveDialogRef" @success="handleSaveSuccess" @closed="dialog.save = false" />
|
||||
|
||||
<!-- 导入弹窗 -->
|
||||
<a-modal v-model:open="dialog.import" title="导入部门" :width="500" :footer="null">
|
||||
<a-space direction="vertical" style="width: 100%">
|
||||
<a-alert message="导入说明" description="请先下载模板,按照模板格式填写数据后上传。如果部门名称已存在则跳过。" type="info" show-icon />
|
||||
<a-button @click="handleDownloadTemplate" style="width: 100%">
|
||||
<template #icon><download-outlined /></template>
|
||||
下载导入模板
|
||||
</a-button>
|
||||
<a-upload
|
||||
:file-list="importFileList"
|
||||
:before-upload="handleImportUpload"
|
||||
@remove="() => importFileList = []"
|
||||
accept=".xlsx,.xls"
|
||||
:max-count="1"
|
||||
>
|
||||
<a-button>
|
||||
<template #icon><upload-outlined /></template>
|
||||
选择文件
|
||||
</a-button>
|
||||
</a-upload>
|
||||
</a-space>
|
||||
</a-modal>
|
||||
<!-- 导入部门弹窗 -->
|
||||
<sc-import v-model:open="dialog.import" title="导入部门" :api="authApi.departments.import.post"
|
||||
:template-api="authApi.departments.downloadTemplate.get" filename="部门" @success="handleImportSuccess" />
|
||||
|
||||
<!-- 导出部门弹窗 -->
|
||||
<sc-export v-model:open="dialog.export" title="导出部门" :api="handleExportApi"
|
||||
:default-filename="`部门列表_${Date.now()}`" :show-options="false" tip="导出当前选中或所有部门数据"
|
||||
@success="handleExportSuccess" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { message, Modal } from 'ant-design-vue'
|
||||
import scTable from '@/components/scTable/index.vue'
|
||||
import scImport from '@/components/scImport/index.vue'
|
||||
import scExport from '@/components/scExport/index.vue'
|
||||
import saveDialog from './components/SaveDialog.vue'
|
||||
import authApi from '@/api/auth'
|
||||
import { useTable } from '@/hooks/useTable'
|
||||
@@ -168,15 +156,13 @@ const {
|
||||
// 对话框状态
|
||||
const dialog = reactive({
|
||||
save: false,
|
||||
import: false
|
||||
import: false,
|
||||
export: false
|
||||
})
|
||||
|
||||
// 弹窗引用
|
||||
const saveDialogRef = ref(null)
|
||||
|
||||
// 导入文件列表
|
||||
const importFileList = ref([])
|
||||
|
||||
// 行key
|
||||
const rowKey = 'id'
|
||||
|
||||
@@ -304,82 +290,47 @@ const handleBatchStatus = (status) => {
|
||||
}
|
||||
|
||||
// 导出部门
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
let ids = []
|
||||
if (selectedRows.value.length > 0) {
|
||||
ids = selectedRows.value.map(item => item.id)
|
||||
}
|
||||
const res = await authApi.departments.export.post({ ids }, { responseType: 'blob' })
|
||||
const handleExport = () => {
|
||||
dialog.export = true
|
||||
}
|
||||
|
||||
// 创建下载链接
|
||||
const url = window.URL.createObjectURL(new Blob([res]))
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.setAttribute('download', `部门列表_${new Date().getTime()}.xlsx`)
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
window.URL.revokeObjectURL(url)
|
||||
// 导出API封装
|
||||
const handleExportApi = async () => {
|
||||
const ids = selectedRows.value.map(item => item.id)
|
||||
return await authApi.departments.export.post({ ids: ids.length > 0 ? ids : undefined })
|
||||
}
|
||||
|
||||
message.success('导出成功')
|
||||
selectedRows.value = []
|
||||
} catch (error) {
|
||||
console.error('导出失败:', error)
|
||||
message.error('导出失败')
|
||||
}
|
||||
// 导出成功回调
|
||||
const handleExportSuccess = () => {
|
||||
selectedRows.value = []
|
||||
}
|
||||
|
||||
// 导入部门
|
||||
const handleImport = () => {
|
||||
importFileList.value = []
|
||||
dialog.import = true
|
||||
}
|
||||
|
||||
// 上传导入文件
|
||||
const handleImportUpload = async (file) => {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
|
||||
try {
|
||||
importFileList.value = [{ uid: file.uid, name: file.name, status: 'uploading' }]
|
||||
const res = await authApi.departments.import.post(formData)
|
||||
|
||||
importFileList.value = []
|
||||
dialog.import = false
|
||||
|
||||
if (res.code === 200) {
|
||||
message.success(res.message || '导入成功')
|
||||
refreshTable()
|
||||
} else {
|
||||
message.error(res.message || '导入失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('导入失败:', error)
|
||||
importFileList.value = []
|
||||
message.error(error.response?.data?.message || '导入失败')
|
||||
}
|
||||
|
||||
return false // 阻止自动上传
|
||||
// 导入成功回调
|
||||
const handleImportSuccess = () => {
|
||||
refreshTable()
|
||||
}
|
||||
|
||||
// 下载导入模板
|
||||
// 下载模板
|
||||
const handleDownloadTemplate = async () => {
|
||||
try {
|
||||
const res = await authApi.departments.downloadTemplate.get({ responseType: 'blob' })
|
||||
|
||||
// 创建下载链接
|
||||
const url = window.URL.createObjectURL(new Blob([res]))
|
||||
const blob = await authApi.departments.downloadTemplate.get()
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.setAttribute('download', '部门导入模板.xlsx')
|
||||
link.download = '部门导入模板.xlsx'
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
window.URL.revokeObjectURL(url)
|
||||
message.success('下载成功')
|
||||
} catch (error) {
|
||||
console.error('下载模板失败:', error)
|
||||
message.error('下载模板失败')
|
||||
message.error('下载失败')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,14 +12,12 @@
|
||||
</div>
|
||||
<div class="actions">
|
||||
<a-space size="small">
|
||||
<a-tooltip title="展开全部">
|
||||
<a-button type="text" size="small" @click="handleExpandAll">
|
||||
<template #icon><UnorderedListOutlined /></template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip title="折叠全部">
|
||||
<a-button type="text" size="small" @click="handleCollapseAll">
|
||||
<template #icon><OrderedListOutlined /></template>
|
||||
<a-tooltip :title="isAllExpanded ? '折叠全部' : '展开全部'">
|
||||
<a-button type="text" size="small" @click="handleToggleExpand">
|
||||
<template #icon>
|
||||
<UnorderedListOutlined v-if="!isAllExpanded" />
|
||||
<OrderedListOutlined v-else />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip title="添加根权限">
|
||||
@@ -43,7 +41,6 @@
|
||||
checkable
|
||||
:check-strictly="false"
|
||||
:expand-on-click-node="false"
|
||||
block-node
|
||||
@select="onMenuSelect"
|
||||
@check="onMenuCheck">
|
||||
<template #icon="{ dataRef }">
|
||||
@@ -81,6 +78,25 @@
|
||||
<template #icon><DeleteOutlined /></template>
|
||||
批量删除 ({{ checkedMenuKeys.length }})
|
||||
</a-button>
|
||||
<a-dropdown>
|
||||
<a-button type="link" size="small">
|
||||
<template #icon><MoreOutlined /></template>
|
||||
更多
|
||||
</a-button>
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item @click="handleImport">
|
||||
<ImportOutlined />导入权限
|
||||
</a-menu-item>
|
||||
<a-menu-item @click="handleExport">
|
||||
<ExportOutlined />导出权限
|
||||
</a-menu-item>
|
||||
<a-menu-item @click="handleDownloadTemplate">
|
||||
<DownloadOutlined />下载模板
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
<a-button type="link" size="small" @click="handleRefresh">
|
||||
<template #icon><ReloadOutlined /></template>
|
||||
刷新
|
||||
@@ -96,6 +112,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导入权限弹窗 -->
|
||||
<sc-import v-model:open="dialog.import" title="导入权限" :api="authApi.permissions.import.post"
|
||||
:template-api="authApi.permissions.downloadTemplate.get" filename="权限" @success="handleImportSuccess" />
|
||||
|
||||
<!-- 导出权限弹窗 -->
|
||||
<sc-export v-model:open="dialog.export" title="导出权限" :api="handleExportApi"
|
||||
:default-filename="`权限列表_${Date.now()}`" :show-options="false" tip="导出当前选中或所有权限数据"
|
||||
@success="handleExportSuccess" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -112,9 +137,16 @@ import {
|
||||
UnorderedListOutlined,
|
||||
OrderedListOutlined,
|
||||
DeleteOutlined,
|
||||
StopOutlined
|
||||
StopOutlined,
|
||||
ImportOutlined,
|
||||
ExportOutlined,
|
||||
DownloadOutlined,
|
||||
MoreOutlined
|
||||
} from '@ant-design/icons-vue'
|
||||
import { computed } from 'vue'
|
||||
import saveForm from './components/SaveForm.vue'
|
||||
import scImport from '@/components/scImport/index.vue'
|
||||
import scExport from '@/components/scExport/index.vue'
|
||||
import authApi from '@/api/auth'
|
||||
|
||||
defineOptions({
|
||||
@@ -137,9 +169,30 @@ const parentId = ref(null)
|
||||
const loading = ref(false)
|
||||
const detailLoading = ref(false)
|
||||
|
||||
// 对话框状态
|
||||
const dialog = ref({
|
||||
import: false,
|
||||
export: false
|
||||
})
|
||||
|
||||
// 树引用
|
||||
const treeRef = ref()
|
||||
|
||||
// 是否全部展开
|
||||
const isAllExpanded = computed(() => {
|
||||
const allKeys = getAllKeys(filteredMenuTree.value)
|
||||
return allKeys.length > 0 && expandedKeys.value.length === allKeys.length
|
||||
})
|
||||
|
||||
// 切换展开/折叠
|
||||
const handleToggleExpand = () => {
|
||||
if (isAllExpanded.value) {
|
||||
handleCollapseAll()
|
||||
} else {
|
||||
handleExpandAll()
|
||||
}
|
||||
}
|
||||
|
||||
// 加载权限树
|
||||
const loadMenuTree = async () => {
|
||||
try {
|
||||
@@ -363,6 +416,52 @@ const handleSaveSuccess = async () => {
|
||||
message.success('保存成功')
|
||||
}
|
||||
|
||||
// 导出权限
|
||||
const handleExport = () => {
|
||||
dialog.value.export = true
|
||||
}
|
||||
|
||||
// 导出API封装
|
||||
const handleExportApi = async () => {
|
||||
return await authApi.permissions.export.post({
|
||||
ids: checkedMenuKeys.value.length > 0 ? checkedMenuKeys.value : undefined
|
||||
})
|
||||
}
|
||||
|
||||
// 导出成功回调
|
||||
const handleExportSuccess = () => {
|
||||
checkedMenuKeys.value = []
|
||||
}
|
||||
|
||||
// 导入权限
|
||||
const handleImport = () => {
|
||||
dialog.value.import = true
|
||||
}
|
||||
|
||||
// 导入成功回调
|
||||
const handleImportSuccess = () => {
|
||||
loadMenuTree()
|
||||
}
|
||||
|
||||
// 下载模板
|
||||
const handleDownloadTemplate = async () => {
|
||||
try {
|
||||
const blob = await authApi.permissions.downloadTemplate.get()
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = '权限导入模板.xlsx'
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
window.URL.revokeObjectURL(url)
|
||||
message.success('下载成功')
|
||||
} catch (error) {
|
||||
console.error('下载模板失败:', error)
|
||||
message.error('下载失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
loadMenuTree()
|
||||
@@ -401,8 +500,11 @@ defineExpose({
|
||||
background: transparent;
|
||||
|
||||
.ant-tree-node-content-wrapper {
|
||||
padding: 4px 0;
|
||||
padding: 2px 4px;
|
||||
transition: background-color 0.2s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 28px;
|
||||
|
||||
&:hover {
|
||||
background-color: #f5f5f5;
|
||||
@@ -411,22 +513,37 @@ defineExpose({
|
||||
|
||||
.ant-tree-switcher {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 20px;
|
||||
}
|
||||
|
||||
.ant-tree-iconEle {
|
||||
margin-right: 6px;
|
||||
margin-right: 4px;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ant-tree-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tree-node-content {
|
||||
display: inline-flex;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
max-width: 100%;
|
||||
|
||||
.tree-node-title {
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
color: #262626;
|
||||
flex-shrink: 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.tree-node-code {
|
||||
@@ -434,14 +551,17 @@ defineExpose({
|
||||
font-size: 11px;
|
||||
background: #f0f0f0;
|
||||
border: none;
|
||||
padding: 1px 6px;
|
||||
padding: 0 4px;
|
||||
border-radius: 2px;
|
||||
color: #595959;
|
||||
flex-shrink: 0;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.tree-node-disabled {
|
||||
color: #ff4d4f;
|
||||
margin-left: 4px;
|
||||
font-size: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,25 @@
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
<a-dropdown>
|
||||
<a-button>
|
||||
更多
|
||||
<DownOutlined />
|
||||
</a-button>
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item @click="handleImport">
|
||||
<ImportOutlined />导入角色
|
||||
</a-menu-item>
|
||||
<a-menu-item @click="handleExport">
|
||||
<ExportOutlined />导出角色
|
||||
</a-menu-item>
|
||||
<a-menu-item @click="handleDownloadTemplate">
|
||||
<DownloadOutlined />下载模板
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
<a-button type="primary" @click="handleAdd">
|
||||
<template #icon><PlusOutlined /></template>
|
||||
新增
|
||||
@@ -72,6 +91,15 @@
|
||||
<!-- 权限设置弹窗 -->
|
||||
<permission-dialog v-if="dialog.permission" ref="permissionDialogRef" @success="permissionSuccess"
|
||||
@closed="dialog.permission = false" />
|
||||
|
||||
<!-- 导入角色弹窗 -->
|
||||
<sc-import v-model:open="dialog.import" title="导入角色" :api="authApi.roles.import.post"
|
||||
:template-api="authApi.roles.downloadTemplate.get" filename="角色" @success="handleImportSuccess" />
|
||||
|
||||
<!-- 导出角色弹窗 -->
|
||||
<sc-export v-model:open="dialog.export" title="导出角色" :api="handleExportApi"
|
||||
:default-filename="`角色列表_${Date.now()}`" :show-options="false" tip="导出当前选中或所有角色数据"
|
||||
@success="handleExportSuccess" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -84,9 +112,14 @@ import {
|
||||
DownOutlined,
|
||||
CheckCircleOutlined,
|
||||
CopyOutlined,
|
||||
DeleteOutlined
|
||||
DeleteOutlined,
|
||||
ImportOutlined,
|
||||
ExportOutlined,
|
||||
DownloadOutlined
|
||||
} from '@ant-design/icons-vue'
|
||||
import scTable from '@/components/scTable/index.vue'
|
||||
import scImport from '@/components/scImport/index.vue'
|
||||
import scExport from '@/components/scExport/index.vue'
|
||||
import saveDialog from './components/SaveDialog.vue'
|
||||
import permissionDialog from './components/PermissionDialog.vue'
|
||||
import authApi from '@/api/auth'
|
||||
@@ -125,7 +158,9 @@ const {
|
||||
// 对话框状态
|
||||
const dialog = reactive({
|
||||
save: false,
|
||||
permission: false
|
||||
permission: false,
|
||||
import: false,
|
||||
export: false
|
||||
})
|
||||
|
||||
// 弹窗引用
|
||||
@@ -296,4 +331,49 @@ const handleSaveSuccess = () => {
|
||||
const permissionSuccess = () => {
|
||||
refreshTable()
|
||||
}
|
||||
|
||||
// 导出角色
|
||||
const handleExport = async () => {
|
||||
dialog.export = true
|
||||
}
|
||||
|
||||
// 导出API封装
|
||||
const handleExportApi = async () => {
|
||||
const ids = selectedRows.value.map(item => item.id)
|
||||
return await authApi.roles.export.post({ ids: ids.length > 0 ? ids : undefined })
|
||||
}
|
||||
|
||||
// 导出成功回调
|
||||
const handleExportSuccess = () => {
|
||||
selectedRows.value = []
|
||||
}
|
||||
|
||||
// 导入角色
|
||||
const handleImport = () => {
|
||||
dialog.import = true
|
||||
}
|
||||
|
||||
// 导入成功回调
|
||||
const handleImportSuccess = () => {
|
||||
refreshTable()
|
||||
}
|
||||
|
||||
// 下载模板
|
||||
const handleDownloadTemplate = async () => {
|
||||
try {
|
||||
const blob = await authApi.roles.downloadTemplate.get()
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = '角色导入模板.xlsx'
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
window.URL.revokeObjectURL(url)
|
||||
message.success('下载成功')
|
||||
} catch (error) {
|
||||
console.error('下载模板失败:', error)
|
||||
message.error('下载失败')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -126,6 +126,15 @@
|
||||
|
||||
<!-- 角色设置弹窗 -->
|
||||
<role-dialog v-if="dialog.role" ref="roleDialogRef" @success="handleRoleSuccess" @closed="dialog.role = false" />
|
||||
|
||||
<!-- 导入用户弹窗 -->
|
||||
<sc-import v-model:open="dialog.import" title="导入用户" :api="authApi.users.import.post"
|
||||
:template-api="authApi.users.downloadTemplate.get" filename="用户" @success="handleImportSuccess" />
|
||||
|
||||
<!-- 导出用户弹窗 -->
|
||||
<sc-export v-model:open="dialog.export" title="导出用户" :api="handleExportApi"
|
||||
:default-filename="`用户列表_${Date.now()}`" :show-options="false" tip="导出当前选中或所有用户数据"
|
||||
@success="handleExportSuccess" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -146,6 +155,8 @@ import {
|
||||
UserOutlined
|
||||
} from '@ant-design/icons-vue'
|
||||
import scTable from '@/components/scTable/index.vue'
|
||||
import scImport from '@/components/scImport/index.vue'
|
||||
import scExport from '@/components/scExport/index.vue'
|
||||
import saveDialog from './components/SaveDialog.vue'
|
||||
import roleDialog from './components/RoleDialog.vue'
|
||||
import authApi from '@/api/auth'
|
||||
@@ -188,7 +199,9 @@ const {
|
||||
// 对话框状态
|
||||
const dialog = reactive({
|
||||
save: false,
|
||||
role: false
|
||||
role: false,
|
||||
import: false,
|
||||
export: false
|
||||
})
|
||||
|
||||
// 弹窗引用
|
||||
@@ -368,53 +381,50 @@ const handleBatchRoles = () => {
|
||||
}
|
||||
|
||||
// 导出数据
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
const ids = selectedRows.value.map(item => item.id)
|
||||
const res = await authApi.users.export.post({ ids: ids.length > 0 ? ids : undefined })
|
||||
if (res) {
|
||||
// 创建下载链接
|
||||
const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = `users_${Date.now()}.xlsx`
|
||||
link.click()
|
||||
window.URL.revokeObjectURL(url)
|
||||
message.success('导出成功')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('导出失败:', error)
|
||||
message.error('导出失败')
|
||||
}
|
||||
const handleExport = () => {
|
||||
dialog.export = true
|
||||
}
|
||||
|
||||
// 导出API封装
|
||||
const handleExportApi = async () => {
|
||||
const ids = selectedRows.value.map(item => item.id)
|
||||
return await authApi.users.export.post({ ids: ids.length > 0 ? ids : undefined })
|
||||
}
|
||||
|
||||
// 导出成功回调
|
||||
const handleExportSuccess = () => {
|
||||
selectedRows.value = []
|
||||
}
|
||||
|
||||
// 导入用户
|
||||
const handleImport = () => {
|
||||
dialog.import = true
|
||||
}
|
||||
|
||||
// 导入成功回调
|
||||
const handleImportSuccess = () => {
|
||||
refreshTable()
|
||||
}
|
||||
|
||||
// 下载模板
|
||||
const handleDownloadTemplate = async () => {
|
||||
try {
|
||||
const res = await authApi.users.downloadTemplate.get()
|
||||
if (res) {
|
||||
const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = 'user_template.xlsx'
|
||||
link.click()
|
||||
window.URL.revokeObjectURL(url)
|
||||
message.success('下载成功')
|
||||
}
|
||||
const blob = await authApi.users.downloadTemplate.get()
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = '用户导入模板.xlsx'
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
window.URL.revokeObjectURL(url)
|
||||
message.success('下载成功')
|
||||
} catch (error) {
|
||||
console.error('下载模板失败:', error)
|
||||
message.error('下载失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 导入用户
|
||||
const handleImport = () => {
|
||||
// TODO: 实现导入弹窗
|
||||
message.info('导入功能开发中...')
|
||||
}
|
||||
|
||||
// 重置密码
|
||||
const handleResetPassword = (record) => {
|
||||
Modal.confirm({
|
||||
|
||||
Reference in New Issue
Block a user