HeaderBanner.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <template>
  2. <div style="height: calc(100vw * 0.59)" class="w-full">
  3. <div
  4. v-if="!bannerUrl"
  5. class="flex h-full w-full items-center justify-center bg-[url('~/assets/img/note-create/note_create_banner_bg.png')]"
  6. >
  7. <div
  8. @click="handleSelectImage"
  9. class="flex h-40 w-150 active:bg-[#000]/[0.1] bg-[#FFFFFF]/[0.2] items-center justify-center space-x-10 rounded-full border-2 border-white"
  10. >
  11. <div class="w-16 h-16">
  12. <van-image width="100%" height="100%" :src="icon_image_fill" />
  13. </div>
  14. <span class="text-sm font-normal pt-4 text-[#FF9300]">设置游记头图</span>
  15. </div>
  16. </div>
  17. <div v-else class="relative h-full w-full">
  18. <img :src="bannerUrl" class="h-full w-full" alt="" />
  19. <div
  20. @click="open"
  21. class="absolute rounded-full bottom-10 right-10 flex cursor-pointer items-center space-x-8 bg-[#00000080] px-15 py-8 hover:opacity-90"
  22. >
  23. <div class="w-16 h-16">
  24. <van-image width="100%" height="100%" :src="image" />
  25. </div>
  26. <span class="text-base text-white">重新上传头图</span>
  27. </div>
  28. </div>
  29. <!-- <van-dialog title="图片剪裁" v-model:show="cropperDialogVisible" width="375"> -->
  30. <!-- <div class="h-full w-full"> -->
  31. <!-- <img ref="cropperRef" :src="cropperImageBase64" alt="" /> -->
  32. <!-- <vueCropper
  33. ref="cropperRef"
  34. :img="cropperImageBase64"
  35. autoCrop
  36. :outputSize="1"
  37. centerBox
  38. fixed
  39. fixedBox
  40. original
  41. :full="true"
  42. :fixedNumber="[3.2, 1]"
  43. ></vueCropper> -->
  44. <!-- </div> -->
  45. <!-- <template #footer>
  46. <div class="flex items-center justify-center space-x-20 pt-10 pb-10">
  47. <van-button
  48. round
  49. plain
  50. color="#FF9300"
  51. type="primary"
  52. @click="cropperDialogVisible = false"
  53. >
  54. 取消
  55. </van-button>
  56. <van-button
  57. round
  58. type="primary"
  59. @click="handleCropperOk"
  60. :loading="loading"
  61. color="#FF9300"
  62. >
  63. 确认
  64. </van-button>
  65. </div>
  66. </template> -->
  67. <!-- </van-dialog> -->
  68. </div>
  69. </template>
  70. <script setup>
  71. import { useFileDialog } from '@vueuse/core'
  72. import icon_image_fill from '~/assets/img/note-create/icon-image-fill.png'
  73. import image from '~/assets/img/note-create/image.svg'
  74. // import { VueCropper } from 'vue-cropper'
  75. // import 'vue-cropper/dist/index.css'
  76. const bannerUrl = defineModel('bannerUrl')
  77. const { open, onChange } = useFileDialog({
  78. accept: '.png,.png,.jpeg,.JPG,Png '
  79. })
  80. // const cropperImageBase64 = ref('')
  81. function handleSelectImage() {
  82. open()
  83. }
  84. onChange(async (files) => {
  85. if (!files.length) return
  86. const reader = new FileReader()
  87. reader.readAsDataURL(files[0])
  88. reader.onload = () => {
  89. bannerUrl.value = reader.result
  90. handleCropperOk(files[0])
  91. }
  92. })
  93. // const cropperRef = ref(null)
  94. // const cropperDialogVisible = ref(false)
  95. const loading = ref(false)
  96. async function handleCropperOk(data) {
  97. try {
  98. loading.value = true
  99. // 此处需上传图片,保存URL
  100. const formData = new FormData()
  101. formData.append('uploadFile', data)
  102. formData.append('asImage', true)
  103. formData.append('fieldName', 'travelNotesBanner')
  104. const res = await request('/admin/app/tourismProjectTravelNotesWrite/upload', {
  105. method: 'post',
  106. body: formData
  107. })
  108. const url = res.data.fileUrl
  109. loading.value = true
  110. bannerUrl.value = url
  111. } finally {
  112. loading.value = false
  113. }
  114. }
  115. </script>
  116. <style lang="scss" scoped></style>