index.vue 6.2 KB

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