database.modal.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <script setup lang="ts">
  2. import type { UploadChangeParam } from 'ant-design-vue';
  3. import { shallowRef, triggerRef } from 'vue';
  4. import { useVbenModal } from '@vben/common-ui';
  5. import { FilePlus } from '@vben/icons';
  6. import { $t } from '@vben/locales';
  7. import { message, UploadDragger } from 'ant-design-vue';
  8. export interface ImportDatabaseProps<U = { count: number; message: string }> {
  9. accept?: string;
  10. upload?: (file: File) => Promise<U>;
  11. }
  12. defineOptions({
  13. name: 'ImportDatabaseModal',
  14. });
  15. const emit = defineEmits(['success']);
  16. const props = shallowRef<ImportDatabaseProps>({
  17. accept: '*/*',
  18. });
  19. const [Modal, modalApi] = useVbenModal({
  20. showConfirmButton: false,
  21. async onConfirm() {},
  22. onOpenChange(isOpen) {
  23. if (isOpen) {
  24. const data = modalApi.getData<ImportDatabaseProps>();
  25. Object.assign(props.value, data);
  26. triggerRef(props);
  27. }
  28. },
  29. });
  30. const onAcceptError = (_files: File[]) => {
  31. message.warn(`请上传正确格式的文件`);
  32. };
  33. async function onChangeHandle(info: UploadChangeParam<File>) {
  34. const accept = props.value.accept ?? '*/*';
  35. if (info.file.type && accept !== '*/*' && !accept.includes(info.file.type))
  36. return onAcceptError(info.fileList);
  37. modalApi.lock();
  38. try {
  39. const data = await props.value.upload?.(info.file);
  40. if (data?.count) {
  41. message.success(data.message);
  42. await modalApi.close();
  43. emit('success');
  44. }
  45. } catch (error: any) {
  46. message.error(error.message);
  47. } finally {
  48. modalApi.lock(false);
  49. }
  50. }
  51. </script>
  52. <template>
  53. <Modal
  54. class="import-database-modal-wrapper"
  55. :draggable="true"
  56. :fullscreen-button="false"
  57. :confirm-text="$t('ui.actionTitle.import')"
  58. >
  59. <UploadDragger
  60. class="size-full"
  61. name="file"
  62. :show-upload-list="false"
  63. :accept="props.accept"
  64. :before-upload="() => false"
  65. @change="onChangeHandle"
  66. @reject="onAcceptError"
  67. >
  68. <p class="ant-upload-drag-icon text-center">
  69. <FilePlus class="text-primary inline size-24" />
  70. </p>
  71. <span class="ant-upload-text">单击或将文件拖到此区域进行上传</span>
  72. </UploadDragger>
  73. <template v-if="$slots['prepend-footer']" #prepend-footer>
  74. <slot name="prepend-footer"></slot>
  75. </template>
  76. </Modal>
  77. </template>
  78. <style scoped lang="scss">
  79. :deep(.ant-upload-btn) {
  80. display: flex !important;
  81. flex-direction: column;
  82. justify-content: center;
  83. padding: 0 !important;
  84. }
  85. :global(.import-database-modal-wrapper) {
  86. height: 520px;
  87. }
  88. </style>