CoverSelect.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <template>
  2. <div>
  3. <p>封面:</p>
  4. <div class="thumb-div">
  5. <el-image
  6. v-if="newsItem.thumbUrl"
  7. style="width: 300px; max-height: 300px"
  8. :src="newsItem.thumbUrl"
  9. fit="contain"
  10. />
  11. <Icon
  12. v-else
  13. icon="ep:plus"
  14. class="avatar-uploader-icon"
  15. :class="isFirst ? 'avatar' : 'avatar1'"
  16. />
  17. <div class="thumb-but">
  18. <el-upload
  19. :action="UPLOAD_URL"
  20. :headers="HEADERS"
  21. multiple
  22. :limit="1"
  23. :file-list="fileList"
  24. :data="uploadData"
  25. :before-upload="onBeforeUpload"
  26. :on-error="onUploadError"
  27. :on-success="onUploadSuccess"
  28. >
  29. <template #trigger>
  30. <el-button size="small" type="primary" :loading="isUploading" disabled="isUploading">
  31. {{ isUploading ? '正在上传' : '本地上传' }}
  32. </el-button>
  33. </template>
  34. <el-button
  35. size="small"
  36. type="primary"
  37. @click="showImageDialog = true"
  38. style="margin-left: 5px"
  39. >
  40. 素材库选择
  41. </el-button>
  42. <template #tip>
  43. <div class="el-upload__tip">支持 bmp/png/jpeg/jpg/gif 格式,大小不超过 2M</div>
  44. </template>
  45. </el-upload>
  46. </div>
  47. <el-dialog
  48. title="选择图片"
  49. v-model="showImageDialog"
  50. width="80%"
  51. append-to-body
  52. destroy-on-close
  53. >
  54. <WxMaterialSelect
  55. :objData="{ type: 'image', accountId: accountId }"
  56. @select-material="onMaterialSelected"
  57. />
  58. </el-dialog>
  59. </div>
  60. </div>
  61. </template>
  62. <script setup lang="ts">
  63. import WxMaterialSelect from '@/views/mp/components/wx-material-select/main.vue'
  64. import { getAccessToken } from '@/utils/auth'
  65. import type { UploadFiles, UploadProps, UploadRawFile } from 'element-plus'
  66. import { NewsItem } from './types'
  67. const message = useMessage()
  68. // const UPLOAD_URL = 'http://localhost:8000/upload/' // 上传永久素材的地址
  69. const UPLOAD_URL = import.meta.env.VITE_BASE_URL + '/admin-api/mp/material/upload-permanent' // 上传永久素材的地址
  70. const HEADERS = { Authorization: 'Bearer ' + getAccessToken() } // 设置上传的请求头部
  71. const props = defineProps<{
  72. modelValue: NewsItem
  73. isFirst: boolean
  74. }>()
  75. const emit = defineEmits<{
  76. (e: 'update:modelValue', v: NewsItem)
  77. }>()
  78. const newsItem = computed<NewsItem>({
  79. get() {
  80. return props.modelValue
  81. },
  82. set(val) {
  83. emit('update:modelValue', val)
  84. }
  85. })
  86. const accountId = inject<number>('accountId')
  87. const showImageDialog = ref(false)
  88. const fileList = ref<UploadFiles>([])
  89. interface UploadData {
  90. type: 'image' | 'video' | 'audio'
  91. accountId?: number
  92. }
  93. const uploadData: UploadData = reactive({
  94. type: 'image',
  95. accountId: accountId
  96. })
  97. const isUploading = ref(false)
  98. /** 素材选择完成事件*/
  99. const onMaterialSelected = (item: any) => {
  100. showImageDialog.value = false
  101. newsItem.value.thumbMediaId = item.mediaId
  102. newsItem.value.thumbUrl = item.url
  103. }
  104. const onBeforeUpload: UploadProps['beforeUpload'] = (rawFile: UploadRawFile) => {
  105. const isType = ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/jpg'].includes(
  106. rawFile.type
  107. )
  108. if (!isType) {
  109. message.error('上传图片格式不对!')
  110. return false
  111. }
  112. if (rawFile.size / 1024 / 1024 > 2) {
  113. message.error('上传图片大小不能超过 2M!')
  114. return false
  115. }
  116. // 校验通过
  117. return true
  118. }
  119. const onUploadSuccess: UploadProps['onSuccess'] = (res: any) => {
  120. if (res.code !== 0) {
  121. message.error('上传出错:' + res.msg)
  122. return false
  123. }
  124. // 重置上传文件的表单
  125. fileList.value = []
  126. // 设置草稿的封面字段
  127. newsItem.value.thumbMediaId = res.data.mediaId
  128. newsItem.value.thumbUrl = res.data.url
  129. }
  130. const onUploadError = (err: Error) => {
  131. message.error('上传失败: ' + err.message)
  132. }
  133. </script>
  134. <style lang="scss" scoped>
  135. .el-upload__tip {
  136. margin-left: 5px;
  137. }
  138. .thumb-div {
  139. display: inline-block;
  140. width: 100%;
  141. text-align: center;
  142. .avatar-uploader-icon {
  143. width: 120px;
  144. height: 120px;
  145. font-size: 28px;
  146. line-height: 120px;
  147. color: #8c939d;
  148. text-align: center;
  149. border: 1px solid #d9d9d9;
  150. }
  151. .avatar {
  152. width: 230px;
  153. height: 120px;
  154. }
  155. .avatar1 {
  156. width: 120px;
  157. height: 120px;
  158. }
  159. .thumb-but {
  160. margin: 5px;
  161. }
  162. }
  163. </style>