feat:增加 user 用户的导入功能
							parent
							
								
									cf434f0ed1
								
							
						
					
					
						commit
						49f13bf301
					
				|  | @ -56,6 +56,14 @@ export function importUserTemplate() { | ||||||
|   return requestClient.download('/system/user/get-import-template'); |   return requestClient.download('/system/user/get-import-template'); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /** 导入用户 */ | ||||||
|  | export function importUser(file: File, updateSupport: boolean) { | ||||||
|  |   return requestClient.upload('/system/user/import', { | ||||||
|  |     file, | ||||||
|  |     updateSupport | ||||||
|  |   }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /** 用户密码重置 */ | /** 用户密码重置 */ | ||||||
| export function resetUserPassword(id: number, password: string) { | export function resetUserPassword(id: number, password: string) { | ||||||
|   return requestClient.put('/system/user/update-password', { id, password }); |   return requestClient.put('/system/user/update-password', { id, password }); | ||||||
|  |  | ||||||
|  | @ -220,6 +220,31 @@ export function useAssignRoleFormSchema(): VbenFormSchema[] { | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /** 用户导入的表单 */ | ||||||
|  | export function useImportFormSchema(): VbenFormSchema[] { | ||||||
|  |   return [ | ||||||
|  |     { | ||||||
|  |       fieldName: 'file', | ||||||
|  |       label: '用户数据', | ||||||
|  |       component: 'Upload', | ||||||
|  |       rules: 'required', | ||||||
|  |       help: '仅允许导入 xls、xlsx 格式文件', | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       fieldName: 'updateSupport', | ||||||
|  |       label: '是否覆盖', | ||||||
|  |       component: 'Switch', | ||||||
|  |       componentProps: { | ||||||
|  |         checkedChildren: '是', | ||||||
|  |         unCheckedChildren: '否', | ||||||
|  |       }, | ||||||
|  |       rules: z.boolean().default(false), | ||||||
|  |       help: '是否更新已经存在的用户数据', | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /** 列表的搜索表单 */ | /** 列表的搜索表单 */ | ||||||
| export function useGridFormSchema(): VbenFormSchema[] { | export function useGridFormSchema(): VbenFormSchema[] { | ||||||
|   return [ |   return [ | ||||||
|  | @ -317,7 +342,7 @@ export function useGridColumns<T = SystemUserApi.SystemUser>( | ||||||
|           onClick: onActionClick, |           onClick: onActionClick, | ||||||
|         }, |         }, | ||||||
|         name: 'CellOperation', |         name: 'CellOperation', | ||||||
|         // TODO @芋艿:后续把 delete、assign-role、reset-password 搞成“更多”
 |         // TODO @芋艿:后续把 delete、assign-role、reset-password 搞成"更多"
 | ||||||
|         options: [ |         options: [ | ||||||
|           'edit', // 默认的编辑按钮
 |           'edit', // 默认的编辑按钮
 | ||||||
|           'delete', // 默认的删除按钮
 |           'delete', // 默认的删除按钮
 | ||||||
|  |  | ||||||
|  | @ -4,11 +4,12 @@ import type { SystemUserApi } from '#/api/system/user'; | ||||||
| import type { SystemDeptApi } from '#/api/system/dept'; | import type { SystemDeptApi } from '#/api/system/dept'; | ||||||
| 
 | 
 | ||||||
| import { Page, useVbenModal } from '@vben/common-ui'; | import { Page, useVbenModal } from '@vben/common-ui'; | ||||||
| import { Button, message, Modal, Row, Col } from 'ant-design-vue'; | import { Button, message, Modal } from 'ant-design-vue'; | ||||||
| import { Plus, Download } from '@vben/icons'; | import { Plus, Download, Upload } from '@vben/icons'; | ||||||
| import Form from './modules/form.vue'; | import Form from './modules/form.vue'; | ||||||
| import ResetPasswordForm from './modules/reset-password-form.vue'; | import ResetPasswordForm from './modules/reset-password-form.vue'; | ||||||
| import AssignRoleForm from './modules/assign-role-form.vue'; | import AssignRoleForm from './modules/assign-role-form.vue'; | ||||||
|  | import ImportForm from './modules/import-form.vue'; | ||||||
| import DeptTree from './modules/dept-tree.vue'; | import DeptTree from './modules/dept-tree.vue'; | ||||||
| 
 | 
 | ||||||
| import { $t } from '#/locales'; | import { $t } from '#/locales'; | ||||||
|  | @ -35,6 +36,11 @@ const [AssignRoleModal, assignRoleModalApi] = useVbenModal({ | ||||||
|   destroyOnClose: true, |   destroyOnClose: true, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | const [ImportModal, importModalApi] = useVbenModal({ | ||||||
|  |   connectedComponent: ImportForm, | ||||||
|  |   destroyOnClose: true, | ||||||
|  | }); | ||||||
|  | 
 | ||||||
| /** 刷新表格 */ | /** 刷新表格 */ | ||||||
| function onRefresh() { | function onRefresh() { | ||||||
|   gridApi.query(); |   gridApi.query(); | ||||||
|  | @ -58,6 +64,11 @@ function onCreate() { | ||||||
|   formModalApi.setData(null).open(); |   formModalApi.setData(null).open(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /** 导入用户 */ | ||||||
|  | function onImport() { | ||||||
|  |   importModalApi.open(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /** 编辑用户 */ | /** 编辑用户 */ | ||||||
| function onEdit(row: SystemUserApi.SystemUser) { | function onEdit(row: SystemUserApi.SystemUser) { | ||||||
|   formModalApi.setData(row).open(); |   formModalApi.setData(row).open(); | ||||||
|  | @ -180,6 +191,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ | ||||||
|     <FormModal @success="onRefresh" /> |     <FormModal @success="onRefresh" /> | ||||||
|     <ResetPasswordModal @success="onRefresh" /> |     <ResetPasswordModal @success="onRefresh" /> | ||||||
|     <AssignRoleModal @success="onRefresh" /> |     <AssignRoleModal @success="onRefresh" /> | ||||||
|  |     <ImportModal @success="onRefresh" /> | ||||||
| 
 | 
 | ||||||
|     <div class="flex h-full"> |     <div class="flex h-full"> | ||||||
|       <!-- 左侧部门树 --> |       <!-- 左侧部门树 --> | ||||||
|  | @ -198,6 +210,10 @@ const [Grid, gridApi] = useVbenVxeGrid({ | ||||||
|               <Download class="size-5" /> |               <Download class="size-5" /> | ||||||
|               {{ $t('ui.actionTitle.export') }} |               {{ $t('ui.actionTitle.export') }} | ||||||
|             </Button> |             </Button> | ||||||
|  |             <Button type="primary" class="ml-2" @click="onImport"> | ||||||
|  |               <Upload class="size-5" /> | ||||||
|  |               {{ $t('ui.actionTitle.import', ['用户']) }} | ||||||
|  |             </Button> | ||||||
|           </template> |           </template> | ||||||
|         </Grid> |         </Grid> | ||||||
|       </div> |       </div> | ||||||
|  |  | ||||||
|  | @ -0,0 +1,77 @@ | ||||||
|  | <script lang="ts" setup> | ||||||
|  | import type { FileType } from 'ant-design-vue/es/upload/interface'; | ||||||
|  | 
 | ||||||
|  | import { useVbenModal } from '@vben/common-ui'; | ||||||
|  | import { message} from 'ant-design-vue'; | ||||||
|  | import { Button, Upload } from 'ant-design-vue'; | ||||||
|  | 
 | ||||||
|  | import { $t } from '#/locales'; | ||||||
|  | import { useVbenForm } from '#/adapter/form'; | ||||||
|  | import { importUser, importUserTemplate } from '#/api/system/user'; | ||||||
|  | import { downloadByData } from '#/utils/download'; | ||||||
|  | 
 | ||||||
|  | import { useImportFormSchema } from '../data'; | ||||||
|  | 
 | ||||||
|  | const emit = defineEmits(['success']); | ||||||
|  | 
 | ||||||
|  | const [Form, formApi] = useVbenForm({ | ||||||
|  |   layout: 'horizontal', | ||||||
|  |   schema: useImportFormSchema(), | ||||||
|  |   showDefaultActions: false, | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const [Modal, modalApi] = useVbenModal({ | ||||||
|  |   async onConfirm() { | ||||||
|  |     const { valid } = await formApi.validate(); | ||||||
|  |     if (!valid) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     modalApi.lock(); | ||||||
|  |     // 提交表单 | ||||||
|  |     const data = await formApi.getValues(); | ||||||
|  |     try { | ||||||
|  |       await importUser(data.file, data.updateSupport); | ||||||
|  |       // 关闭并提示 | ||||||
|  |       await modalApi.close(); | ||||||
|  |       emit('success'); | ||||||
|  |       message.success({ | ||||||
|  |         content: $t('ui.actionMessage.operationSuccess'), | ||||||
|  |         key: 'action_process_msg', | ||||||
|  |       }); | ||||||
|  |     } finally { | ||||||
|  |       modalApi.lock(false); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | /** 上传前 */ | ||||||
|  | function beforeUpload(file: FileType) { | ||||||
|  |   formApi.setFieldValue('file', file); | ||||||
|  |   return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** 下载模版 */ | ||||||
|  | async function onDownload() { | ||||||
|  |   const data = await importUserTemplate(); | ||||||
|  |   downloadByData(data, '用户导入模板.xlsx'); | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <Modal title="导入用户"> | ||||||
|  |     <Form class="mx-4"> | ||||||
|  |       <template #file> | ||||||
|  |         <div class="w-full"> | ||||||
|  |           <Upload :max-count="1" accept=".xls,.xlsx" :beforeUpload="beforeUpload"> | ||||||
|  |             <Button type="primary"> 选择 Excel 文件 </Button> | ||||||
|  |           </Upload> | ||||||
|  |         </div> | ||||||
|  |       </template> | ||||||
|  |     </Form> | ||||||
|  |     <template #prepend-footer> | ||||||
|  |       <div class="flex flex-auto items-center"> | ||||||
|  |         <Button @click="onDownload"> 下载导入模板 </Button> | ||||||
|  |       </div> | ||||||
|  |     </template> | ||||||
|  |   </Modal> | ||||||
|  | </template> | ||||||
|  | @ -66,4 +66,5 @@ export { | ||||||
|   UserRoundPen, |   UserRoundPen, | ||||||
|   X, |   X, | ||||||
|   Download, |   Download, | ||||||
|  |   Upload, | ||||||
| } from 'lucide-vue-next'; | } from 'lucide-vue-next'; | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ | ||||||
|     "create": "Create {0}", |     "create": "Create {0}", | ||||||
|     "delete": "Delete {0}", |     "delete": "Delete {0}", | ||||||
|     "view": "View {0}", |     "view": "View {0}", | ||||||
|  |     "import": "Import", | ||||||
|     "export": "Export" |     "export": "Export" | ||||||
|   }, |   }, | ||||||
|   "actionMessage": { |   "actionMessage": { | ||||||
|  | @ -21,7 +22,10 @@ | ||||||
|     "deleting": "Deleting {0} ...", |     "deleting": "Deleting {0} ...", | ||||||
|     "deleteSuccess": "{0} deleted successfully", |     "deleteSuccess": "{0} deleted successfully", | ||||||
|     "operationSuccess": "Operation succeeded", |     "operationSuccess": "Operation succeeded", | ||||||
|     "operationFailed": "Operation failed" |     "operationFailed": "Operation failed", | ||||||
|  |     "importSuccess": "Import succeeded", | ||||||
|  |     "importFail": "Import failed", | ||||||
|  |     "downloadTemplateFail": "Download template failed" | ||||||
|   }, |   }, | ||||||
|   "placeholder": { |   "placeholder": { | ||||||
|     "input": "Please enter", |     "input": "Please enter", | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ | ||||||
|     "create": "新增{0}", |     "create": "新增{0}", | ||||||
|     "delete": "删除{0}", |     "delete": "删除{0}", | ||||||
|     "view": "查看{0}", |     "view": "查看{0}", | ||||||
|  |     "import": "导入", | ||||||
|     "export": "导出" |     "export": "导出" | ||||||
|   }, |   }, | ||||||
|   "actionMessage": { |   "actionMessage": { | ||||||
|  | @ -21,7 +22,10 @@ | ||||||
|     "deleting": "正在删除 {0} ...", |     "deleting": "正在删除 {0} ...", | ||||||
|     "deleteSuccess": "{0} 删除成功", |     "deleteSuccess": "{0} 删除成功", | ||||||
|     "operationSuccess": "操作成功", |     "operationSuccess": "操作成功", | ||||||
|     "operationFailed": "操作失败" |     "operationFailed": "操作失败", | ||||||
|  |     "importSuccess": "导入成功", | ||||||
|  |     "importFail": "导入失败", | ||||||
|  |     "downloadTemplateFail": "下载模板失败" | ||||||
|   }, |   }, | ||||||
|   "placeholder": { |   "placeholder": { | ||||||
|     "input": "请输入", |     "input": "请输入", | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 YunaiV
						YunaiV