avatar.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. <!-- -->
  2. <template>
  3. <div class="avatarsBox" @mouseover="showIcon = true" @mouseleave="showIcon = false">
  4. <div style="width: 130px; height: 130px;">
  5. <v-img :src="getUserAvatar(avatarResult, '1')" width="130" height="130" style="border-radius: 6px;"></v-img>
  6. <div v-show="showIcon" @click="openFileInput" class="mdi mdi-camera-outline camera">
  7. <input
  8. type="file"
  9. ref="fileInput"
  10. accept="image/png, image/jpg, image/jpeg"
  11. style="display: none;"
  12. @change="handleUploadFile"
  13. />
  14. </div>
  15. </div>
  16. </div>
  17. <!-- <Loading :visible="overlay"></Loading> -->
  18. <!-- 图片裁剪 -->
  19. <ImgCropper :visible="isShowCopper" :image="selectPic" :cropBoxResizable="true" @submit="handleHideCopper" :aspectRatio="1 / 1" @close="isShowCopper = false, selectPic = ''"></ImgCropper>
  20. </template>
  21. <script setup>
  22. defineOptions({ name: 'resumeAnalysis-avatar'})
  23. import { getUserAvatar } from '@/utils/avatar'
  24. // import { blobToJson } from '@/utils'
  25. import { ref } from 'vue'
  26. const props = defineProps({
  27. id: {
  28. type: String,
  29. default: ''
  30. },
  31. data: {
  32. type: String,
  33. default: ''
  34. }
  35. })
  36. const showIcon = ref(false)
  37. // 选择文件
  38. const fileInput = ref()
  39. const clicked = ref(false)
  40. const openFileInput = () => {
  41. if (clicked.value) return
  42. clicked.value = true
  43. fileInput.value.click()
  44. clicked.value = false
  45. }
  46. // 上传头像
  47. const selectPic = ref('')
  48. const isShowCopper = ref(false)
  49. const accept = ['jpg', 'png', 'jpeg']
  50. const handleUploadFile = async (e) => {
  51. const file = e.target.files[0]
  52. const fileType = file.name.split('.')[1]
  53. if (!accept.includes(fileType)) return Snackbar.warning('请上传图片格式')
  54. const reader = new FileReader()
  55. reader.readAsDataURL(file)
  56. reader.onload = () => {
  57. selectPic.value = String(reader.result)
  58. isShowCopper.value = true
  59. }
  60. }
  61. const avatarResult = ref(props.data)
  62. // 图片裁剪
  63. const handleHideCopper = async (res) => {
  64. isShowCopper.value = false
  65. avatarResult.value = res?.result.dataURL || ''
  66. // avatarResult.value = res?.result ? Reflect.get(res.result, 'dataURL') : ''
  67. }
  68. const submit = async () => {
  69. return { id: props.id, data: avatarResult.value}
  70. }
  71. defineExpose({
  72. id: props.id,
  73. submit
  74. })
  75. </script>
  76. <style lang="scss" scoped>
  77. .avatarsBox {
  78. height: 150px;
  79. width: 120px;
  80. position: relative;
  81. cursor: pointer;
  82. margin: 0 32px;
  83. .camera {
  84. color: #fff;
  85. font-size: 42px;
  86. position: absolute;
  87. top: 50%;
  88. left: 50%;
  89. transform: translate(-50%, -50%);
  90. }
  91. }
  92. </style>