Xiao_123 9 months ago
parent
commit
aad2a0e410

+ 62 - 46
src/views/recruit/personal/position/components/details.vue

@@ -1,6 +1,6 @@
 <template>
-  <div>
-    <div class="default-width banner px-6">
+  <div style="position: relative;">
+    <div class="default-width banner px-6" id="share">
       <div class="banner-title d-flex justify-space-between">
         <div class="d-flex align-center">
           <h1 class="ellipsis">{{ info.name }}</h1>
@@ -123,14 +123,19 @@
       @close="shareDialog = false"
     >
       <div>
+        <div class="mb-3">方式一:生成图片并下载</div>
+        <v-btn color="primary" @click="generateAndDownloadImage">点击生成图片</v-btn>
+      </div>
+      <div class="mt-10">
+        <div class="mb-3">方式二:手动复制以下链接分享给好友</div>
         <div class="pa-4" style="background-color: #f0f0f0; border-radius: 8px;">{{ shareUrlTxt }}</div>
         <v-btn v-if="!getToken()" class="mt-1" color="warning" variant="text">您还未登录,登录后分享可享受分享有礼活动!</v-btn>
         <!-- <v-btn class="mt-4 ml-3" color="success" @click="copyText">复制分享链接</v-btn>
         <v-btn class="mt-4 ml-3" color="primary" variant="outlined" @click="openShareLink">打开分享链接</v-btn> -->
-        <div class="color-warning mt-5">
+        <!-- <div class="color-warning mt-5">
           <v-icon size="25">mdi-information</v-icon>
           请复制上述链接分享给好友
-        </div>
+        </div> -->
       </div>
       <template #footer>
         <v-divider></v-divider>
@@ -141,12 +146,14 @@
             variant="text"
             @click="shareDialog = false"
           >{{ $t('common.close') }}</v-btn>
-          <!-- <v-btn class="radius button-item float-right ma-2" variant="text" color="indigo" :ripple="false" @click="handleShareClick">下载图片</v-btn> -->
         </div>
       </template>
     </Dialog>
 
     <Loading :visible="loading"></Loading>
+    <div style="position: absolute; left: -9999px; bottom: 0">
+      <PosterPage :jobId="id" ref="share"></PosterPage>
+    </div>
   </div>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
 </template>
 
@@ -168,57 +175,66 @@ import selectResumeDialog from './jobDetails/selectResumeDialog'
 import { getToken } from '@/utils/auth'
 import { prologue, defaultText } from '@/hooks/web/useIM'
 import { getUserAvatar } from '@/utils/avatar'
-// import html2canvas from 'html2canvas'
+import PosterPage from './poster.vue'
+import html2canvas from 'html2canvas'
 
 const { t } = useI18n()
 const router = useRouter()
 const { id } = router.currentRoute.value.params
-// provide('jobId', id)
 const delivery = ref(false) // 是否已投递简历
 const loading = ref(false)
 
-// const DPR = () => {
-//   // 获取设备dpi
-//   if (window.devicePixelRatio && window.devicePixelRatio > 1) {
-//     return window.devicePixelRatio * 2
-//   }
-//   // 直接返回高像素比
-//   return 8
-// }
+const DPR = () => {
+  // 获取设备dpi
+  if (window.devicePixelRatio && window.devicePixelRatio > 1) {
+    return window.devicePixelRatio * 2
+  }
+  // 直接返回高像素比
+  return 8
+}
 
-// const downloadBase64 = (content, fileName) => {
-//   const base64ToBlob = function (code) {
-//     let parts = code.split(';base64,')
-//     let contentType = parts[0].split(':')[1]
-//     let raw = window.atob(parts[1])
-//     let rawLength = raw.length
-//     let uInt8Array = new Uint8Array(rawLength)
-//     for (let i = 0; i < rawLength; ++i) {
-//       uInt8Array[i] = raw.charCodeAt(i)
-//     }
+const downloadBase64 = (content, fileName) => {
+  const base64ToBlob = function (code) {
+    let parts = code.split(';base64,')
+    let contentType = parts[0].split(':')[1]
+    let raw = window.atob(parts[1])
+    let rawLength = raw.length
+    let uInt8Array = new Uint8Array(rawLength)
+    for (let i = 0; i < rawLength; ++i) {
+      uInt8Array[i] = raw.charCodeAt(i)
+    }
 
-//     return new Blob([uInt8Array], {
-//       type: contentType
-//     })
-//   }
-//   let aLink = document.createElement('a')
-//   let blob = base64ToBlob(content)
-//   aLink.download = fileName + '.png'
-//   aLink.href = URL.createObjectURL(blob)
-//   aLink.click()
-//   loading.value = false
-// }
+    return new Blob([uInt8Array], {
+      type: contentType
+    })
+  }
+  let aLink = document.createElement('a')
+  let blob = base64ToBlob(content)
+  aLink.download = fileName + '.png'
+  aLink.href = URL.createObjectURL(blob)
+  aLink.click()
+  loading.value = false
+}
 
-// const handleShareClick = () => {
-//   const dpi = DPR()
-//   html2canvas(document.getElementById('share'), { useCORS: true, scale: dpi }).then(function(canvas) {
-//     shareDialog.value = false
-//     loading.value = true
-//     const base64 = canvas.toDataURL().replace(/^data:image\/(png|jpg);base64,/, '')
-//     const base64img = `data:image/png;base64,${base64}`
-//     downloadBase64(base64img, 'test4')
-//   })
-// }
+const share = ref()
+// 生成图片
+const generateAndDownloadImage = async () => {  
+  if (!share.value) {  
+    return
+  }
+  loading.value = true
+  shareDialog.value = false
+  try {  
+    const canvas = await html2canvas(share.value.$el, { scale: DPR(), useCORS: true })
+    const image = canvas.toDataURL().replace(/^data:image\/(png|jpg);base64,/, '')
+    const base64img = `data:image/png;base64,${image}`
+    const { name, areaName, payFrom, payTo } = info.value
+    downloadBase64(base64img, `${name}_${areaName}_${payFrom}-${payTo}-${positionInfo.value.payName}`)
+  } catch (error) {  
+    console.error('Error generating image:', error)
+    Snackbar.error('图片生成失败')
+  }
+}  
 
 // 相似职位
 const similarList = ref([])

+ 6 - 6
src/views/recruit/personal/position/components/poster.vue

@@ -4,7 +4,6 @@
     <v-card
       class="py-3 px-5"
       style="min-height: calc(100vh - 20px); box-sizing: border-box; margin: 0 auto;"
-      :style="{'width': '750px'}"
     >
       <div v-if="!Object.keys(info).length">加载失败</div>
       <div v-else>
@@ -64,20 +63,22 @@
 <script setup>
 import { commissionCalculation } from '@/utils/position'
 defineOptions({name: 'recruit-personal-shareJob-index'})
-import { ref, inject } from 'vue';
+import { ref } from 'vue';
 import { getPositionDetails } from '@/api/position'
 import { dealDictObjData } from '@/utils/position'
 
 // 职位详情
-const jobId = inject('jobId')
+const props = defineProps({
+  jobId: String
+})
 const info = ref({})
 const positionInfo = ref({})
 const getPositionDetail = async () => {
-  const data = await getPositionDetails({ id: jobId })
+  const data = await getPositionDetails({ id: props.jobId })
   info.value = data
   positionInfo.value = { ...dealDictObjData({}, info.value), ...info.value }
 }
-if (jobId) getPositionDetail()
+if (props.jobId) getPositionDetail()
 
 const desc = [
   { mdi: 'mdi-map-marker-outline', value: 'areaName' },
@@ -102,7 +103,6 @@ const desc = [
   font-size: 28px;
   margin-right: 30px;
   margin-top: 1px;
-  // max-width: 45%;
   vertical-align: middle;
   flex: 1;
 }