index.vue 6.1 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/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 handleDelete = (row: FileVO) => {
  72. delList(row.id, false)
  73. }
  74. // 详情操作
  75. const handleDetail = (row: FileVO) => {
  76. // 设置数据
  77. detailRef.value = row
  78. dialogTitle.value = t('action.detail')
  79. dialogVisible.value = true
  80. }
  81. // ========== 初始化 ==========
  82. getList()
  83. </script>
  84. <template>
  85. <!-- 搜索工作区 -->
  86. <ContentWrap>
  87. <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
  88. </ContentWrap>
  89. <ContentWrap>
  90. <el-button type="primary" @click="uploadDialogVisible = true">
  91. <Icon icon="ep:upload" class="mr-5px" /> 上传文件
  92. </el-button>
  93. <!-- 列表 -->
  94. <Table
  95. :columns="allSchemas.tableColumns"
  96. :selection="false"
  97. :data="tableObject.tableList"
  98. :loading="tableObject.loading"
  99. :pagination="{
  100. total: tableObject.total
  101. }"
  102. v-model:pageSize="tableObject.pageSize"
  103. v-model:currentPage="tableObject.currentPage"
  104. @register="register"
  105. >
  106. <template #url="{ row }">
  107. <el-image
  108. v-if="row.type === 'jpg' || 'png' || 'gif'"
  109. style="width: 80px; height: 50px"
  110. :src="row.url"
  111. :key="row.url"
  112. fit="contain"
  113. lazy
  114. />
  115. <span v-else>{{ row.url }}</span>
  116. </template>
  117. <template #createTime="{ row }">
  118. <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
  119. </template>
  120. <template #action="{ row }">
  121. <el-button link type="primary" @click="handleDetail(row)">
  122. <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}
  123. </el-button>
  124. <el-button
  125. link
  126. type="primary"
  127. v-hasPermi="['infra:file:delete']"
  128. @click="handleDelete(row)"
  129. >
  130. <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
  131. </el-button>
  132. </template>
  133. </Table>
  134. </ContentWrap>
  135. <Dialog v-model="dialogVisible" :title="dialogTitle">
  136. <!-- 对话框(详情) -->
  137. <Descriptions :schema="allSchemas.detailSchema" :data="detailRef">
  138. <template #url="{ row }">
  139. <el-image
  140. v-if="row.type === 'jpg' || 'png' || 'gif'"
  141. style="width: 100px; height: 100px"
  142. :src="row.url"
  143. :key="row.url"
  144. lazy
  145. />
  146. <span>{{ row.url }}</span>
  147. </template>
  148. <template #createTime="{ row }">
  149. <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
  150. </template>
  151. </Descriptions>
  152. <!-- 操作按钮 -->
  153. <template #footer>
  154. <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
  155. </template>
  156. </Dialog>
  157. <Dialog v-model="uploadDialogVisible" :title="uploadDialogTitle" :destroy-on-close="true">
  158. <el-upload
  159. ref="uploadRef"
  160. :action="updateUrl + '?updateSupport=' + updateSupport"
  161. :headers="uploadHeaders"
  162. :drag="true"
  163. :limit="1"
  164. :multiple="true"
  165. :show-file-list="true"
  166. :disabled="uploadDisabled"
  167. :before-upload="beforeUpload"
  168. :on-exceed="handleExceed"
  169. :on-success="handleFileSuccess"
  170. :on-error="excelUploadError"
  171. :auto-upload="false"
  172. accept=".jpg, .png, .gif"
  173. >
  174. <Icon icon="ep:upload-filled" />
  175. <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  176. <template #tip>
  177. <div class="el-upload__tip">请上传 .jpg, .png, .gif 标准格式文件</div>
  178. </template>
  179. </el-upload>
  180. <template #footer>
  181. <el-button type="primary" @click="submitFileForm">
  182. <Icon icon="ep:upload-filled" />
  183. {{ t('action.save') }}
  184. </el-button>
  185. <el-button @click="uploadDialogVisible = false">{{ t('dialog.close') }}</el-button>
  186. </template>
  187. </Dialog>
  188. </template>