index.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <script setup lang="ts">
  2. import { ref } from 'vue'
  3. import dayjs from 'dayjs'
  4. import { ElMessage, ElUpload, UploadInstance, UploadRawFile, ElImage } from 'element-plus'
  5. import { useTable } from '@/hooks/web/useTable'
  6. import { useI18n } from '@/hooks/web/useI18n'
  7. import type { FileVO } from '@/api/infra/fileList/types'
  8. import { allSchemas } from './fileList.data'
  9. import * as FileApi from '@/api/infra/fileList'
  10. import { getAccessToken, getTenantId } from '@/utils/auth'
  11. const { t } = useI18n() // 国际化
  12. // ========== 列表相关 ==========
  13. const { register, tableObject, methods } = useTable<FileVO>({
  14. getListApi: FileApi.getFilePageApi,
  15. delListApi: FileApi.deleteFileApi
  16. })
  17. const { getList, setSearchParams, delList } = methods
  18. // ========== 上传相关 ==========
  19. const uploadDialogVisible = ref(false)
  20. const uploadDialogTitle = ref('上传')
  21. const updateSupport = ref(0)
  22. const uploadDisabled = ref(false)
  23. const uploadRef = ref<UploadInstance>()
  24. let updateUrl = import.meta.env.VITE_UPLOAD_URL
  25. const uploadHeaders = ref()
  26. // 文件上传之前判断
  27. const beforeUpload = (file: UploadRawFile) => {
  28. const isImg = file.type === 'image/jpeg' || 'image/gif' || 'image/png'
  29. const isLt5M = file.size / 1024 / 1024 < 5
  30. if (!isImg) ElMessage.error('上传文件只能是 jpeg / gif / png 格式!')
  31. if (!isLt5M) ElMessage.error('上传文件大小不能超过 5MB!')
  32. return isImg && isLt5M
  33. }
  34. // 处理上传的文件发生变化
  35. // const handleFileChange = (uploadFile: UploadFile): void => {
  36. // uploadRef.value.data.path = uploadFile.name
  37. // }
  38. // 文件上传
  39. const submitFileForm = () => {
  40. uploadHeaders.value = {
  41. Authorization: 'Bearer ' + getAccessToken(),
  42. 'tenant-id': getTenantId()
  43. }
  44. uploadDisabled.value = true
  45. uploadRef.value!.submit()
  46. }
  47. // 文件上传成功
  48. const handleFileSuccess = (response: any): void => {
  49. if (response.code !== 0) {
  50. ElMessage.error(response.msg)
  51. return
  52. }
  53. ElMessage.success('上传成功')
  54. getList()
  55. uploadDialogVisible.value = false
  56. uploadDisabled.value = false
  57. }
  58. // 文件数超出提示
  59. const handleExceed = (): void => {
  60. ElMessage.error('最多只能上传一个文件!')
  61. }
  62. // 上传错误提示
  63. const excelUploadError = (): void => {
  64. ElMessage.error('导入数据失败,请您重新上传!')
  65. }
  66. // ========== 详情相关 ==========
  67. const detailRef = ref() // 详情 Ref
  68. const dialogVisible = ref(false) // 是否显示弹出层
  69. const dialogTitle = ref('') // 弹出层标题
  70. // 详情操作
  71. const handleDetail = (row: FileVO) => {
  72. // 设置数据
  73. detailRef.value = row
  74. dialogTitle.value = t('action.detail')
  75. dialogVisible.value = true
  76. }
  77. // ========== 初始化 ==========
  78. getList()
  79. </script>
  80. <template>
  81. <!-- 搜索工作区 -->
  82. <ContentWrap>
  83. <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
  84. </ContentWrap>
  85. <ContentWrap>
  86. <el-button type="primary" @click="uploadDialogVisible = true">
  87. <Icon icon="ep:upload" class="mr-5px" /> 上传文件
  88. </el-button>
  89. <!-- 列表 -->
  90. <Table
  91. :columns="allSchemas.tableColumns"
  92. :selection="false"
  93. :data="tableObject.tableList"
  94. :loading="tableObject.loading"
  95. :pagination="{
  96. total: tableObject.total
  97. }"
  98. v-model:pageSize="tableObject.pageSize"
  99. v-model:currentPage="tableObject.currentPage"
  100. @register="register"
  101. >
  102. <template #url="{ row }">
  103. <el-image
  104. v-if="row.type === 'jpg' || 'png' || 'gif'"
  105. style="width: 80px; height: 50px"
  106. :src="row.url"
  107. :key="row.url"
  108. fit="contain"
  109. lazy
  110. />
  111. <span v-else>{{ row.url }}</span>
  112. </template>
  113. <template #createTime="{ row }">
  114. <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
  115. </template>
  116. <template #action="{ row }">
  117. <el-button link type="primary" @click="handleDetail(row)">
  118. <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}
  119. </el-button>
  120. <el-button
  121. link
  122. type="primary"
  123. v-hasPermi="['infra:file:delete']"
  124. @click="delList(row.id, false)"
  125. >
  126. <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
  127. </el-button>
  128. </template>
  129. </Table>
  130. </ContentWrap>
  131. <Dialog v-model="dialogVisible" :title="dialogTitle">
  132. <!-- 对话框(详情) -->
  133. <Descriptions :schema="allSchemas.detailSchema" :data="detailRef">
  134. <template #url="{ row }">
  135. <el-image
  136. v-if="row.type === 'jpg' || 'png' || 'gif'"
  137. style="width: 100px; height: 100px"
  138. :src="row.url"
  139. :key="row.url"
  140. lazy
  141. />
  142. <span>{{ row.url }}</span>
  143. </template>
  144. <template #createTime="{ row }">
  145. <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
  146. </template>
  147. </Descriptions>
  148. <!-- 操作按钮 -->
  149. <template #footer>
  150. <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
  151. </template>
  152. </Dialog>
  153. <Dialog v-model="uploadDialogVisible" :title="uploadDialogTitle" :destroy-on-close="true">
  154. <el-upload
  155. ref="uploadRef"
  156. :action="updateUrl + '?updateSupport=' + updateSupport"
  157. :headers="uploadHeaders"
  158. :drag="true"
  159. :limit="1"
  160. :multiple="true"
  161. :show-file-list="true"
  162. :disabled="uploadDisabled"
  163. :before-upload="beforeUpload"
  164. :on-exceed="handleExceed"
  165. :on-success="handleFileSuccess"
  166. :on-error="excelUploadError"
  167. :auto-upload="false"
  168. accept=".jpg, .png, .gif"
  169. >
  170. <Icon icon="ep:upload-filled" />
  171. <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  172. <template #tip>
  173. <div class="el-upload__tip">请上传 .jpg, .png, .gif 标准格式文件</div>
  174. </template>
  175. </el-upload>
  176. <template #footer>
  177. <el-button type="primary" @click="submitFileForm">
  178. <Icon icon="ep:upload-filled" />
  179. {{ t('action.save') }}
  180. </el-button>
  181. <el-button @click="uploadDialogVisible = false">{{ t('dialog.close') }}</el-button>
  182. </template>
  183. </Dialog>
  184. </template>