Browse Source

feat: 异步导入导出

wanggaokun 1 year ago
parent
commit
959fa26d0b

+ 96 - 0
src/api/interface/system/importExport.ts

@@ -0,0 +1,96 @@
+import { PageQuery, BaseEntity } from '@/api/interface/index'
+export interface ImportExportVO extends BaseEntity {
+  /**
+   * 唯一编码
+   */
+  id: string | number
+
+  /**
+   * 文件名称
+   */
+  name: string
+
+  /**
+   * 文件地址
+   */
+  url: string
+
+  /**
+   * 日志信息
+   */
+  logInfo: string
+
+  /**
+   * 状态(1正常  0异常)
+   */
+  status: string
+
+  /**
+   * 文件Id
+   */
+  ossId: number
+}
+
+export interface ImportExportForm {
+  /**
+   * 唯一编码
+   */
+  id?: string | number
+
+  /**
+   * 文件名称
+   */
+  name?: string
+
+  /**
+   * 文件地址
+   */
+  url?: string
+
+  /**
+   * 文件地址
+   */
+  ossId?: number
+
+  /**
+   * 日志信息
+   */
+  logInfo?: string
+
+  /**
+   * 状态(1正常  0异常)
+   */
+  status?: number
+
+  /**
+   * 乐观锁
+   */
+  version?: number
+}
+
+export interface ImportExportQuery extends PageQuery {
+  /**
+   * 文件名称
+   */
+  name?: string
+
+  /**
+   * 文件地址
+   */
+  url?: string
+
+  /**
+   * 日志信息
+   */
+  logInfo?: string
+
+  /**
+   * 状态(1正常  0异常)
+   */
+  status?: number
+
+  /**
+   * 日期范围参数
+   */
+  params?: any
+}

+ 19 - 0
src/api/modules/system/importExport.ts

@@ -0,0 +1,19 @@
+import http from '@/api'
+import { ImportExportVO, ImportExportQuery } from '@/api/interface/system/importExport'
+/**
+ * @name 查询导入导出日志列表
+ * @param query 参数
+ * @returns 返回列表
+ */
+export const listImportExportApi = (query: ImportExportQuery) => {
+  return http.get<ImportExportVO[]>('/system/importExport/list', query, { loading: true })
+}
+
+/**
+ * @name 查询导入导出日志详细
+ * @param id id
+ * @returns returns
+ */
+export const getImportExportApi = (id: string | number) => {
+  return http.get<ImportExportVO>(`/system/importExport/${id}`)
+}

+ 9 - 1
src/api/modules/system/user.ts

@@ -87,12 +87,20 @@ export const importDataApi = (params: FormData) => {
   return http.post('/system/user/importData', params)
 }
 
+/**
+ * @name 导出下载数据
+ * @returns returns
+ */
+export const exportDownApi = (data: any) => {
+  return http.downloadPost('/system/user/export', data, { loading: false })
+}
+
 /**
  * @name 导出数据
  * @returns returns
  */
 export const exportApi = (data: any) => {
-  return http.downloadPost('/system/user/export', data)
+  return http.post('/system/user/export', data)
 }
 
 /**

+ 5 - 6
src/components/ImportExcel/index.vue

@@ -47,12 +47,13 @@
       </span>
     </template>
   </el-dialog>
+  <TaskDialog ref="taskDialogRef" />
 </template>
 
 <script setup lang="ts" name="ImportExcel">
 import { useDownload } from '@/hooks/useDownload'
 import { ElNotification, UploadRequestOptions, UploadRawFile, UploadInstance } from 'element-plus'
-
+import TaskDialog from '@/components/TaskDialog/index.vue'
 export interface ExcelParameterProps {
   title: string // 标题
   fileSize?: number // 上传文件的大小
@@ -149,13 +150,11 @@ const excelUploadError = () => {
   })
 }
 
+const taskDialogRef = ref<InstanceType<typeof TaskDialog> | null>(null)
 // 上传成功提示
 const excelUploadSuccess = () => {
-  ElNotification({
-    title: '温馨提示',
-    message: `批量添加${parameter.value.title}成功!`,
-    type: 'success'
-  })
+  dialogVisible.value = false
+  taskDialogRef.value?.openImportDialog()
 }
 
 defineExpose({

+ 68 - 0
src/components/TaskDialog/index.vue

@@ -0,0 +1,68 @@
+<template>
+  <el-dialog v-model="dialogVisible" :close-on-click-modal="false" :title="parameter.title" :destroy-on-close="true" width="600" top="8vh" draggable>
+    <div style="text-align: center" v-if="parameter.type === 'import'">
+      <h3>数据导入中...</h3>
+      <div class="info-text">关闭弹窗后可在[<el-link type="primary" @click="link">头像-我的导入导出-导入信息</el-link>] 中查看导入记录。</div>
+    </div>
+    <div style="text-align: center" v-else>
+      <h3>文件导出中...</h3>
+      <div class="info-text">关闭弹窗后可在[<el-link type="primary" @click="link">头像-我的导入导出-导出信息</el-link>] 下载查看。</div>
+    </div>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="handleCancel">关闭</el-button>
+      </span>
+    </template>
+  </el-dialog>
+  <IEDrawer ref="drawerRef" />
+</template>
+
+<script setup lang="ts" name="TaskDialog">
+import IEDrawer from '@/views/import-export/index.vue'
+
+export interface DialogProps {
+  title: string // 标题
+  type: 'import' | 'export' // 导入导出类型
+}
+// dialog状态
+const dialogVisible = ref(false)
+// 父组件传过来的参数
+let parameter = ref<DialogProps>({
+  title: '导入信息',
+  type: 'import'
+})
+
+// 取消按钮,重置表单,关闭弹框
+const handleCancel = () => {
+  dialogVisible.value = false
+}
+const drawerRef = ref<InstanceType<typeof IEDrawer> | null>(null)
+const link = () => {
+  drawerRef.value?.acceptParams()
+  dialogVisible.value = false
+}
+// 接收父组件参数
+const openImportDialog = () => {
+  dialogVisible.value = true
+}
+const openExportDialog = () => {
+  dialogVisible.value = true
+  parameter.value = {
+    title: '导出信息',
+    type: 'export'
+  }
+}
+
+defineExpose({
+  openImportDialog,
+  openExportDialog,
+  handleCancel
+})
+</script>
+<style setup lang="scss">
+.info-text {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+</style>

+ 3 - 0
src/stores/interface/index.ts

@@ -36,6 +36,9 @@ export interface UserState {
   token: string | undefined
   name: string
   avatar: string
+  nickname: string
+  userId: string | number
+  tenantId: string
   roles: string[]
   permissions: string[]
 }

+ 8 - 2
src/stores/modules/user.ts

@@ -9,6 +9,9 @@ export const useUserStore = defineStore('admin-user', {
     token: getToken(),
     name: '',
     avatar: '',
+    nickname: '',
+    userId: '',
+    tenantId: '',
     roles: [],
     permissions: []
   }),
@@ -37,7 +40,7 @@ export const useUserStore = defineStore('admin-user', {
             if (res.code === 200) {
               const data = res.data
               const user = data.user
-              const avatar = user.avatar == '' || user.avatar == null ? defAvatar : import.meta.env.VITE_APP_BASE_API + user.avatar
+              const profile = user.url == '' || user.url == null ? defAvatar : user.url
               if (data.roles && data.roles.length > 0) {
                 // 验证返回的roles是否是一个非空数组
                 this.roles = data.roles
@@ -46,7 +49,10 @@ export const useUserStore = defineStore('admin-user', {
                 this.roles = ['ROLE_DEFAULT']
               }
               this.name = user.userName
-              this.avatar = avatar
+              this.avatar = profile
+              this.nickname = user.nickName
+              this.userId = user.userId
+              this.tenantId = user.tenantId
             }
             resolve(res)
           })

+ 1 - 0
src/styles/element.scss

@@ -177,6 +177,7 @@ label {
 }
 
 /* proTable */
+.drawer-table-box,
 .table-box,
 .table-main {
   display: flex;

+ 73 - 34
src/views/import-export/index.vue

@@ -1,9 +1,16 @@
 <template>
   <el-drawer v-model="drawerVisible" :destroy-on-close="true" size="950px" :title="drawerProps.title">
-    <el-tabs v-model="activeName" class="demo-tabs">
+    <el-tabs v-model="activeName">
       <el-tab-pane label="导入日志" name="1">
-        <div class="table-box">
-          <ProTable :columns="iColumns" :tool-button="false" row-key="id" :data="tableData">
+        <div class="drawer-table-box">
+          <ProTable
+            :columns="iColumns"
+            :height="400"
+            :tool-button="false"
+            row-key="id"
+            :init-param="{ type: '0' }"
+            :request-api="listImportExportApi"
+          >
             <template #status="scope">
               <div class="i-text">
                 <span v-show="scope.row.status == 1" style="margin-right: 8px">
@@ -12,22 +19,34 @@
                 <span v-show="scope.row.status == 0" style="margin-right: 8px">
                   <i class="dot-class" style="background-color: #f56c6c"></i>
                 </span>
-                {{ scope.row.status }}
+                <span v-show="scope.row.status == 2" style="margin-right: 8px">
+                  <i class="dot-class" style="background-color: #e6a23c"></i>
+                </span>
+                <span> </span>
               </div>
             </template>
             <!-- 表格操作 -->
-            <template #operation>
-              <el-button type="primary" link> 下载 </el-button>
+            <template #operation="scope">
+              <el-button type="primary" link @click="handleDownload(scope.row)"> 下载 </el-button>
+              <el-button type="primary" link @click="handleLog(scope.row)"> 日志 </el-button>
             </template>
           </ProTable>
         </div>
       </el-tab-pane>
       <el-tab-pane label="导出日志" name="second">
-        <div class="table-box">
-          <ProTable :columns="eColumns" :tool-button="false" row-key="id" :data="tableData">
+        <div class="drawer-table-box">
+          <ProTable
+            :columns="eColumns"
+            :height="400"
+            :tool-button="false"
+            row-key="id"
+            :init-param="{ type: '1' }"
+            :request-api="listImportExportApi"
+          >
             <!-- 表格操作 -->
-            <template #operation>
-              <el-button type="primary" link> 下载 </el-button>
+            <template #operation="scope">
+              <el-button type="primary" link @click="handleDownload(scope.row)"> 下载 </el-button>
+              <el-button type="primary" link @click="handleLog(scope.row)"> 日志 </el-button>
             </template>
           </ProTable>
         </div>
@@ -38,7 +57,12 @@
 
 <script setup lang="ts" name="IEDrawer">
 import { ColumnProps } from '@/components/ProTable/interface'
-
+import { listImportExportApi } from '@/api/modules/system/importExport'
+import useDownload from '@/hooks/useDownload'
+import { ImportExportVO } from '@/api/interface/system/importExport'
+import { ElMessageBox } from 'element-plus'
+const { proxy } = getCurrentInstance() as ComponentInternalInstance
+const { excel_status } = toRefs<any>(proxy?.useDict('excel_status'))
 const activeName = ref('1')
 interface DrawerProps {
   title: string
@@ -49,18 +73,32 @@ const drawerProps = ref<DrawerProps>({
   title: '我的导入导出'
 })
 
-const tableData = [
-  {
-    id: 11,
-    name: 'Tom',
-    status: '1',
-    createBy: 'wanggaokun',
-    updateTime: '2024-06-21 17:25:33'
-  }
-]
+// const tableData = [
+//   {
+//     id: 11,
+//     name: 'Tom',
+//     status: '1',
+//     createBy: 'wanggaokun',
+//     updateTime: '2024-06-21 17:25:33'
+//   }
+// ]
+/** 下载按钮操作 */
+const handleDownload = (row: ImportExportVO) => {
+  useDownload.oss(row.ossId)
+}
+const handleLog = (row: ImportExportVO) => {
+  ElMessageBox.alert(row.logInfo, '日志信息', {
+    dangerouslyUseHTMLString: true
+  })
+}
 
 // 导入信息表格配置项
 const iColumns = reactive<ColumnProps<any>[]>([
+  {
+    type: 'index',
+    label: '序号',
+    width: 60
+  },
   {
     prop: 'name',
     label: '文件名称',
@@ -70,11 +108,12 @@ const iColumns = reactive<ColumnProps<any>[]>([
   },
   {
     prop: 'status',
-    label: '数据导入状态',
+    label: '状态',
+    enum: excel_status,
     search: {
-      el: 'input'
+      el: 'select'
     },
-    width: 220
+    width: 120
   },
   {
     prop: 'createBy',
@@ -82,7 +121,7 @@ const iColumns = reactive<ColumnProps<any>[]>([
     search: {
       el: 'input'
     },
-    width: 120
+    width: 220
   },
   {
     prop: 'updateTime',
@@ -93,10 +132,15 @@ const iColumns = reactive<ColumnProps<any>[]>([
     },
     width: 220
   },
-  { prop: 'operation', label: '操作', width: 100 }
+  { prop: 'operation', label: '操作' }
 ])
 // 导出信息表格配置项
 const eColumns = reactive<ColumnProps<any>[]>([
+  {
+    type: 'index',
+    label: '序号',
+    width: 60
+  },
   {
     prop: 'name',
     label: '文件名称',
@@ -107,29 +151,24 @@ const eColumns = reactive<ColumnProps<any>[]>([
   {
     prop: 'createBy',
     label: '操作人',
-    search: {
-      el: 'input'
-    },
     width: 220
   },
   {
     prop: 'updateTime',
     label: '操作时间',
-    search: {
-      el: 'date-picker',
-      props: { type: 'datetimerange', valueFormat: 'YYYY-MM-DD HH:mm:ss' }
-    },
     width: 220
   },
   {
     prop: 'status',
     label: '状态',
+    tag: true,
+    enum: excel_status,
     search: {
-      el: 'input'
+      el: 'select'
     },
     width: 120
   },
-  { prop: 'operation', label: '操作', width: 100 }
+  { prop: 'operation', label: '操作' }
 ])
 
 // 接收父组件传过来的参数

+ 0 - 1
src/views/system/oss/index.vue

@@ -114,7 +114,6 @@ const batchDelete = async (ids: string[]) => {
 
 /** 下载按钮操作 */
 const handleDownload = (row: OssVO) => {
-  console.log(row)
   if (row.service === 'Local') {
     useDownload.localResource(row.url)
     return

+ 9 - 8
src/views/system/user/index.vue

@@ -37,18 +37,19 @@
       </ProTable>
       <FormDialog ref="formDialogRef" :items-options="itemsOptions" :model="model" />
       <ImportExcel ref="dialogRef" />
+      <TaskDialog ref="taskDialogRef" />
     </div>
   </div>
 </template>
 
 <script setup lang="tsx" name="UserManage">
 import { User } from '@/api/interface'
-import { useDownload } from '@/hooks/useDownload'
 import { useHandleData } from '@/hooks/useHandleData'
 import { ElMessageBox, ElMessage } from 'element-plus'
-
+// import { useDownload } from '@/hooks/useDownload'
 import TreeFilter from '@/components/TreeFilter/index.vue'
 import ImportExcel from '@/components/ImportExcel/index.vue'
+import TaskDialog from '@/components/TaskDialog/index.vue'
 import FormDialog from '@/components/FormDialog/index.vue'
 import { ColumnProps, ProTableInstance } from '@/components/ProTable/interface'
 import {
@@ -59,8 +60,8 @@ import {
   changeUserStatus,
   importTemplateApi,
   importDataApi,
-  exportApi,
   getUserApi,
+  exportDownApi,
   deptTreeSelectApi,
   resetUserPwdApi
 } from '@/api/modules/system/user'
@@ -88,7 +89,6 @@ const getTreeFilter = async () => {
 
 // 树形筛选切换
 const changeTreeFilter = (val: string) => {
-  // ElMessage.success('请注意查看请求参数变化 🤔')
   proTable.value!.pageable.pageNum = 1
   initParam.deptId = val
 }
@@ -130,12 +130,13 @@ function handleResetPwd(row: any) {
       console.log(e)
     })
 }
-
+const taskDialogRef = ref<InstanceType<typeof TaskDialog> | null>(null)
 // 导出用户列表
 const downloadFile = async () => {
-  ElMessageBox.confirm('确认导出用户数据?', '温馨提示', { type: 'warning' }).then(() =>
-    useDownload(exportApi, '用户列表', proTable.value?.searchParam)
-  )
+  ElMessageBox.confirm('确认导出用户数据?', '温馨提示', { type: 'warning' }).then(async () => {
+    exportDownApi(proTable.value?.searchParam)
+    taskDialogRef.value?.openExportDialog()
+  })
 }
 
 // 批量添加用户