Преглед на файлове

人才定位:详情改为弹窗展示

Xiao_123 преди 2 месеца
родител
ревизия
a198adfea4
променени са 1 файла, в които са добавени 156 реда и са изтрити 37 реда
  1. 156 37
      src/views/menduner/system/talentMap/search/index.vue

+ 156 - 37
src/views/menduner/system/talentMap/search/index.vue

@@ -39,24 +39,56 @@
     </el-table>
   </ContentWrap>
 
-	<el-drawer
-		v-model="drawer"
-		class="!w-50vw"
-		:with-header="false"
-	>
-		<div v-loading="detailsLoading">
-			<div v-if="detail && Object.keys(detail).length > 0">
-				<div class="mb-30px" v-if="previewUrl">
-					<div class="el-descriptions__header el-descriptions__title">名片</div>
-					<div class="text-center w-100% cursor-pointer">
-						<el-image :src="previewUrl" class="w-300px h-500px" :preview-src-list="[previewUrl]" />
-					</div>
-				</div>
+	<Dialog
+    title="人才详情"
+    v-model="dialogVisible"
+    :modalClose="false"
+    width="90%"
+    @close="dialogVisible = false"
+  >
+		<el-row :gutter="20">
+			<el-col :span="9">
+				<div v-if="sourceList && sourceList.length > 0" class="!h-80vh overflow-y-auto">
+					<el-card v-for="val in sourceList" :key="val.id" class="mb-10px">
+						<template #header>
+							<CardTitle :title="typeObj[val.task_type] + val.source_date" />
+						</template>
+						<el-image 
+							v-if="['名片', '杂项'].includes(val.task_type)"
+							width="100%"
+							:preview-src-list="[val.minio_path]"
+							class="cursor-pointer"
+							:src="val.minio_path"
+						/>
+
+						<p v-if="val.task_type === '招聘'">人才ID:{{ val.minio_path }}</p>
+
+						<template v-if="val.task_type === '简历'">
+							<IFrame :src="val.minio_path" />
+						</template>
 
-				<el-descriptions title="基本信息" :column="1" border>
-					<el-descriptions-item label="人才标签">
+						<template v-if="val.task_type === '新任命'">
+							<iframe
+								:id="val.id"
+								class="markdownContent"
+								src=""
+								frameborder="0"
+							></iframe>
+						</template>
+					</el-card>
+				</div>
+				<el-card v-else>
+					<el-empty description="暂无来源" />
+				</el-card>
+			</el-col>
+			<el-col :span="15">
+				<el-descriptions title="人才标签" :column="1" border>
+					<el-descriptions-item label="标签">
 						<el-tag v-for="k in talentTags" :key="k.talent" type="success" class="mr-10px my-10px">{{ k.tag }}</el-tag>
 					</el-descriptions-item>
+				</el-descriptions>
+
+				<el-descriptions class="my-30px" title="基本信息" :column="2" border>
 					<el-descriptions-item 
 						v-for="val in keyArr" 
 						:key="val.value" 
@@ -71,50 +103,56 @@
 					</el-descriptions-item>
 				</el-descriptions>
 
-				<div class="mt-30px career">
+				<div class="career">
 					<div class="el-descriptions__header el-descriptions__title">职业轨迹</div>
 					<el-table :data="detail.career_path" border>
-						<el-table-column prop="company_name" label="酒店名称">
-							<template #default="{ row }">{{ row.company_name ?? '-'}}</template>
+						<el-table-column prop="hotel_zh" label="酒店名称">
+							<template #default="{ row }">{{ row.hotel_zh ?? '-'}}</template>
 						</el-table-column>
-						<el-table-column prop="position" label="职位名称">
-							<template #default="{ row }">{{ row.position ?? '-'}}</template>
+						<el-table-column prop="title_zh" label="职位名称">
+							<template #default="{ row }">{{ row.title_zh ?? '-'}}</template>
 						</el-table-column>
-						<el-table-column prop="current_date" label="日期">
-							<template #default="{ row }">{{ row.current_date ?? '-'}}</template>
+						<el-table-column prop="date" label="日期">
+							<template #default="{ row }">{{ row.date ?? '-'}}</template>
 						</el-table-column>
 					</el-table>
 				</div>
-			</div>
-			<el-empty v-else description="暂无详细信息,去查看其他人的信息吧~" />
-		</div>
-	</el-drawer>
-
+			</el-col>
+		</el-row>
+    <template #footer>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
 </template>
 
 <script setup>
 import { ref, computed } from 'vue'
 import { Search } from '@element-plus/icons-vue'
+import { generateUUID } from '@/utils'
 import { talentSearchApi } from '@/api/menduner/system/talentMap/search'
 import { talentLabelingApi } from '@/api/menduner/system/talentMap/labeling'
 
 const message = useMessage() // 消息弹窗
-const searchValue = ref(null)
+const searchValue = ref('酒店运营')
 const formRef = ref()
 const loading = ref(false)
 const list = ref([])
 const abortController = ref(null)
 
-const drawer = ref(false)
+const dialogVisible = ref(false)
 const detailsLoading = ref(false)
 const detail = ref({})
 const talentTags = ref([])
-const previewUrl = ref(null)
 const keyArr = [
   { label: '中文名', value: 'name_zh' },
   { label: '英文名', value: 'name_en' },
   { label: '职位/头衔(中)', value: 'title_zh' },
   { label: '职位/头衔(英)', value: 'title_en' },
+  { label: '生日', value: 'birthday' },
+  { label: '年龄', value: 'age' },
+  { label: '籍贯', value: 'native_place' },
+  { label: '工作地', value: 'residence' },
+  { label: '固定电话', value: 'phone' },
   { label: '手机号码', value: 'mobile' },
   { label: '电子邮箱', value: 'email' },
   { label: '酒店/公司名称(中)', value: 'hotel_zh' },
@@ -128,29 +166,110 @@ const keyArr = [
   { label: '隶属关系(中)', value: 'affiliation_zh' },
   { label: '隶属关系(英)', value: 'affiliation_en' },
   { label: '品牌组合', value: 'brand_group' },
-  { label: '固定电话', value: 'phone' },
+  { label: '人才信息', value: 'talent_profile' },
   { label: '创建时间', value: 'created_at' },
   { label: '更新时间', value: 'updated_at' }
 ]
+const typeObj = {
+	'招聘': '门墩儿招聘',
+	'新任命': '门墩儿新任命',
+	'名片': '名片',
+	'简历': '简历',
+	'杂项': '杂项'
+}
+
+// markdown回显
+const showPage = (id, html) => {
+   // 将 data-src 转化为 src
+  html = html.replace(/data-src/g, 'src')
+    .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/g, '')
+    .replace(/https/g, 'http')
+
+  nextTick(() => {
+    const iframe = document.getElementById(id)
+    if (!iframe) return
+    const doc = iframe.contentDocument || iframe.document
+    // 设置 iframe 中请求不发送 referrer,以绕过图片防盗链
+    const htmlArr = html.split('</head>')
+    const html_src_add = htmlArr[0] + '<meta name="referrer" content="never"></head>' + htmlArr[1]
+    doc.open()
+    doc.write(html_src_add)
+    doc.close()
 
+    // 设置图片宽高
+    let iwindow = iframe.contentWindow;
+    iframe.addEventListener('load',function () {
+      let idoc = iwindow.document;
+      let imgs = idoc.getElementsByTagName('img')
+      for (let i = 0; i < imgs.length; i++) {
+        const img = imgs[i]
+        if (img) {
+          if (img.width >= img.height) {
+            img.width = iframe.clientWidth / 2
+          } else {
+            img.height = iframe.clientHeight / 2
+            let left = (iframe.clientWidth - img.width) / 2
+            img.style.marginLeft = left + "px"
+          }
+        }
+      }
+    })
+  })
+}
+
+const handleShowPage = async (id, url) => {
+	await nextTick()
+	const response = await fetch(url)
+	const text = await response.text()
+	const doc = `
+		<!DOCTYPE html>
+		<html class="">
+			<head></head>
+			<body>
+				${marked(text)}
+			</body>
+		</html>
+	`
+	showPage(id, doc)
+}
+
+const resetData = () => {
+	sourceList.value = []
+	talentTags.value = []
+	detail.value = {}
+}
+
+const sourceList = ref([])
 const handleDetails = async (id) => {
 	if (!id) return
 
-	drawer.value = true
+	resetData()
+
 	detailsLoading.value = true
 	try {
     const result = await talentSearchApi.getBusinessCardDetails(id)
     detail.value = result || {}
 
-    // 获取名片预览
-    if (result?.image_path) {
-      const data = await talentLabelingApi.getTalentCardByImagePath(result.image_path)
-      previewUrl.value = URL.createObjectURL(data)
-    }
+		if (result?.origin_source) {
+			const list = JSON.parse(result.origin_source)
+			// 时间排序
+			const sortedList = list.sort((a, b) => new Date(b.source_date) - new Date(a.source_date))
+			sourceList.value = sortedList.map(e => {
+				const item = { ...e, id: generateUUID() }
+
+				if (e.task_type === '新任命') {
+					handleShowPage(item.id, item.minio_path)
+				}
+				
+				return item
+			})
+		}
 
 		// 获取人才标签
 		const tagData = await talentLabelingApi.getTalentTagById(id)
 		talentTags.value = tagData ?? []
+
+		dialogVisible.value = true
   } finally {
 		detailsLoading.value = false
 	}