Xiao_123 преди 1 седмица
родител
ревизия
22af62375b

+ 1 - 0
package.json

@@ -55,6 +55,7 @@
     "js-base64": "^3.7.7",
     "jsencrypt": "^3.3.2",
     "lodash-es": "^4.17.21",
+    "marked": "^16.0.0",
     "min-dash": "^4.1.1",
     "mitt": "^3.0.1",
     "nprogress": "^0.2.0",

+ 10 - 0
pnpm-lock.yaml

@@ -95,6 +95,9 @@ importers:
       lodash-es:
         specifier: ^4.17.21
         version: 4.17.21
+      marked:
+        specifier: ^16.0.0
+        version: 16.0.0
       min-dash:
         specifier: ^4.1.1
         version: 4.2.1
@@ -3834,6 +3837,11 @@ packages:
     resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==}
     engines: {node: '>=0.10.0'}
 
+  marked@16.0.0:
+    resolution: {integrity: sha512-MUKMXDjsD/eptB7GPzxo4xcnLS6oo7/RHimUMHEDRhUooPwmN9BEpMl7AEOJv3bmso169wHI2wUF9VQgL7zfmA==}
+    engines: {node: '>= 20'}
+    hasBin: true
+
   matches-selector@1.2.0:
     resolution: {integrity: sha512-c4vLwYWyl+Ji+U43eU/G5FwxWd4ZH0ePUsFs5y0uwD9HUEFBXUQ1zUUan+78IpRD+y4pUfG0nAzNM292K7ItvA==}
 
@@ -9324,6 +9332,8 @@ snapshots:
     dependencies:
       object-visit: 1.0.1
 
+  marked@16.0.0: {}
+
   matches-selector@1.2.0: {}
 
   mathml-tag-names@2.1.3: {}

+ 8 - 0
src/api/menduner/system/talentMap/labeling.ts

@@ -43,6 +43,14 @@ export const talentLabelingApi = {
 		})
 	},
 
+	// 获取网页解析原始markdown
+	getTalentMarkdown: async (image_path: string) => {
+		return await request.downloadMarkdown({ 
+			url: `/api/parse/business-cards/image/${image_path}`,
+			baseURL: import.meta.env.VITE_BASE_URL 
+		})
+	},
+
   // 非结构化数据源 名片解析
 	businessCardParse: async (data: any) => {
 		return await request.upload({ 

+ 5 - 0
src/config/axios/index.ts

@@ -52,5 +52,10 @@ export default {
     option.headersType = 'multipart/form-data'
     const res = await request({ method: 'POST', ...option })
     return res as unknown as Promise<T>
+  },
+  downloadMarkdown: async <T = any>(option: any) => {
+    option.headersType = 'text/markdown'
+    const res = await request({ method: 'GET', ...option })
+    return res as unknown as Promise<T>
   }
 }

+ 51 - 85
src/views/menduner/system/talentMap/maintenance/gather/components/webAnalysis.vue

@@ -1,70 +1,53 @@
 <template>
-  <!-- <div v-if="!markdown_data || !Object.keys(markdown_data)?.length"> -->
-    <ContentWrap>
-      <el-form
-        class="-mb-15px"
-        :model="queryParams"
-        ref="queryFormRef"
-        :inline="true"
-        label-width="110px"
-      >
-        <el-form-item label="微信公众号链接" prop="urls" class="!w-100%">
-          <el-input
-            v-model="queryParams.urls"
-            class="!w-75%"
-            type="textarea"
-            :rows="2"
-            placeholder="请输入需要解析的微信公众号链接"
-          />
-          <el-button
-						type="primary"
-						class="ml-10px"
-						plain
-						@click="handleAnalysis"
-					>解析</el-button>
-        </el-form-item>
-      </el-form>
-    </ContentWrap>
-
-    <el-row v-if="contents.length" :gutter="20">
-      <el-col v-for="(content, index) in contents" :key="index" :span="24">
-        <el-card class="!h-600px" v-loading="!content.data">
-          <template #header>
-            <div class="flex items-center justify-between">
-              <el-text class="flex-1" truncated>{{ content.url }}</el-text>
-              <el-button
-                type="primary"
-                plain
-                class="mt-10px"
-                @click="handleSubmit(content, index)"
-              >信息提取</el-button>
-            </div>
-          </template>
-          <iframe
-            :id="content.id"
-            class="!w-100% !h-[calc(100vh-90px)]"
-            src=""
-            frameborder="0"
-          ></iframe>
-        </el-card>
-      </el-col>
-    </el-row>
-  <!-- </div> -->
-  <!-- <div v-else class="!h-100%">
-    <div class="text-right">
-      <el-button type="primary" plain @click="handleReturn">返回查看解析内容</el-button>
-    </div>
-    <el-card class="!h-100% mt-10px">
-      <div class="!w-192px !h-250px m-auto">
-				<el-image referrerpolicy="no-referrer" :src="markdown_data.pic_url" class="!w-192px !h-250px" />
-			</div>
-			<pre>{{ markdown_data.name_zh }}</pre>
-			<pre>{{ markdown_data.name_en }}</pre>
-			<pre>{{ markdown_data.hotel_zh }}</pre>
-			<pre>{{ markdown_data.title_zh }}</pre>
-			<pre>{{ markdown_data.detailIntroduction }}</pre>
-    </el-card>
-  </div> -->
+  <ContentWrap>
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="110px"
+    >
+      <el-form-item label="微信公众号链接" prop="urls" class="!w-100%">
+        <el-input
+          v-model="queryParams.urls"
+          class="!w-75%"
+          type="textarea"
+          :rows="2"
+          placeholder="请输入需要解析的微信公众号链接"
+        />
+        <el-button
+					type="primary"
+					class="ml-10px"
+					plain
+					@click="handleAnalysis"
+				>解析</el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <el-row v-if="contents.length" :gutter="20">
+    <el-col v-for="(content, index) in contents" :key="index" :span="24">
+      <el-card class="!h-600px" v-loading="!content.data">
+        <template #header>
+          <div class="flex items-center justify-between">
+            <el-text class="flex-1" truncated>{{ content.url }}</el-text>
+            <el-button
+              type="primary"
+              plain
+              class="mt-10px"
+              @click="handleSubmit(content, index)"
+            >信息提取</el-button>
+          </div>
+        </template>
+        <iframe
+          :id="content.id"
+          class="!w-100% !h-[calc(100vh-90px)]"
+          src=""
+          frameborder="0"
+        ></iframe>
+      </el-card>
+    </el-col>
+  </el-row>
 </template>
 
 <script setup>
@@ -77,19 +60,11 @@ import { generateUUID } from '@/utils'
 import { ElLoading } from 'element-plus'
 
 const emit = defineEmits(['analysis', 'reset'])
-// const props = defineProps({
-// 	markDownData: Object
-// })
 const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
 
-// const markdown_data = ref({})
-// watch(() => props.markDownData, val => {
-// 	markdown_data.value = val
-// }, { deep: true })
-
 const queryParams = reactive({
-	// urls: 'https://mp.weixin.qq.com/s/JZ5qxaj9vXsEsswxxD1djA'
+	// urls: 'https://mp.weixin.qq.com/s/JZ5qxaj9vXsEsswxxD1djA' // https://mp.weixin.qq.com/s/R1aJpn9z-Jf0dk9ttoYYeg
 	// urls: 'https://mp.weixin.qq.com/s/vQLWlSB6DzqSewtBLkk_kQ'
   urls: ''
 })
@@ -121,7 +96,7 @@ const wechatHtmlToMarkdown = (html) => {
   const doc = parser.parseFromString(html, 'text/html')
 
   // 提取正文内容 - 微信公众号文章通常在id="js_content"的div中
-  const content = doc.querySelector('#js_content') || doc.body
+  const content = doc.querySelector('#img_content') || doc.body
 
   // 移除不需要的元素
   const elementsToRemove = [
@@ -278,10 +253,7 @@ const handleAnalysis = async () => {
 }
 
 // 信息提取
-// const extractIndex = ref(0)
 const handleSubmit = async (content, index) => {
-	// extractIndex.value = index
-	// if (loading.value) return message.warning('正在解析中,请稍后再试')
 	if (!content.markdown_text) return
 
   const loading = ElLoading.service({
@@ -304,12 +276,6 @@ const handleSubmit = async (content, index) => {
     loading.close()
 	}
 }
-
-// 返回查看解析内容
-// const handleReturn = () => {
-// 	markdown_data.value =  {}
-// 	showPage(contents.value[extractIndex.value])
-// }
 </script>
 
 <style scoped>

+ 1 - 12
src/views/menduner/system/talentMap/maintenance/gather/index.vue

@@ -215,7 +215,6 @@
           </template>
           <!-- 网页解析 -->
           <template v-if="radioValue === 'web'">
-            <!-- :markDownData="markDownData" -->
             <webAnalysis
               v-if="showWebAnalysis"
               @analysis="handleWebAnalysis"
@@ -298,7 +297,7 @@ const getList = async () => {
   try {
     list.value = []
     const data = await talentLabelingApi.getCardList()
-    list.value = data ? data.reverse() : []
+    list.value = data ?? []
   } finally {
     loading.value = false
   }
@@ -335,20 +334,11 @@ const handleDelete = async (id) => {
 }
 
 // 网页解析-人才标签点击
-// const markDownData = ref({})
 const handleTagClick = (index) => {
   if (!webOriginList.value?.[index]) return
   tagCurrentIndex.value = index
   const obj = webOriginList.value[index]
   formData.value = obj ?? {}
-  // markDownData.value = {
-  //   name_zh: obj.name_zh,
-  //   name_en: obj.name_en,
-  //   hotel_zh: obj.hotel_zh,
-  //   title_zh: obj.title_zh,
-  //   pic_url: obj.pic_url,
-  //   detailIntroduction: ''
-  // }
   if (!showFormPage.value) showFormPage.value = true
 }
 
@@ -370,7 +360,6 @@ const handleWebAnalysis = (list, md) => {
 const handleWebClear = () => {
   tagCurrentIndex.value = null
   originMarkdown.value = null
-  // markDownData.value = {}
   tagList.value = []
   webOriginList.value = []
 }

+ 38 - 2
src/views/menduner/system/talentMap/maintenance/labeling/LabelingForm.vue

@@ -3,10 +3,16 @@
 		<el-row :gutter="20">
 			<el-col :span="9">
 				<el-card>
-					<p :style="{'color': previewUrl ? '#2d8cf0' : ''}">名片</p>
-					<el-image v-if="previewUrl" width="100%" :preview-src-list="[previewUrl]" class="cursor-pointer" :src="previewUrl" />
+					<div>
+						<p :style="{'color': previewUrl ? '#2d8cf0' : ''}">名片</p>
+						<el-image v-if="previewUrl" width="100%" :preview-src-list="[previewUrl]" class="cursor-pointer" :src="previewUrl" />
+					</div>
 					<p class="mb-3" :class="{'mt-3': !previewUrl}">门墩儿新任命</p>
 					<p>门墩儿用户简历</p>
+					<div>
+						<p :style="{'color': markdown_text ? '#2d8cf0' : ''}">网页</p>
+						<div v-if="markdown_text" v-html="markdown_text" class="markdownContent"></div>
+					</div>
 				</el-card>
 			</el-col>
 			<el-col :span="15">
@@ -74,6 +80,7 @@ import { getDict } from '@/hooks/web/useDictionaries'
 import { cloneDeep } from 'lodash-es'
 import { TalentMap } from '@/api/menduner/system/talentMap'
 import FormPage from '@/views/menduner/system/talentMap/components/FormPage.vue'
+import { marked } from 'marked'
 
 const message = useMessage() // 消息弹窗
 const loading = ref(false)
@@ -125,6 +132,7 @@ const getTalentTagById = async() => {
 }
 
 /** 打开弹窗 */
+const markdown_text = ref(null)
 const open = async (data) => {
 	previewUrl.value = null
   dialogVisible.value = true
@@ -139,6 +147,15 @@ const open = async (data) => {
 		previewUrl.value = URL.createObjectURL(res)
 	}
 
+	// 网页解析原始markdown内容
+	if (data.origin_source) {
+		if (!data.origin_source?.minio_path) return
+		const result = await talentLabelingApi.getTalentMarkdown(data.origin_source.minio_path)
+		if (result) {
+			markdown_text.value = marked(result)
+		}
+	}
+
 	// 获取人才标签
 	await getTalentTagById()
 }
@@ -184,6 +201,10 @@ const handleSave = async () => {
 	saveLoading.value = true
 	const params = baseInfoRef.value.formQuery
 	if (!params || !Object.keys(params).length) return saveLoading.value = true
+	// 数组转为字符串保存
+  if (Array.isArray(params?.mobile)) {
+    params.mobile = params.mobile.filter(i => Boolean(i)).map(j => String(j).replace(/,|,/g, '')).join(',');
+  }
 	try {
 		await talentLabelingApi.updateBusinessCard({...params, origin_source: talentItem.value?.origin_source}, talentItem.value.id)
 		dialogVisible.value = false
@@ -209,5 +230,20 @@ const handleSave = async () => {
 	.el-descriptions__body {
 		background-color: #f7f8fa;
 	}
+	.markdownContent {
+		width: 100%;
+		max-width: 100%;
+		height: 600px;
+		overflow-y: auto;
+		p {
+			width: 100%;
+			img {
+				width: 100%;
+			}
+		}
+		img {
+			width: 100%;
+		}
+	}
 }
 </style>

+ 1 - 1
src/views/menduner/system/talentMap/maintenance/labeling/index.vue

@@ -91,7 +91,7 @@ const getList = async () => {
   loading.value = true
   try {
     const data = await talentLabelingApi.getCardList()
-    list.value = data ? data.reverse() : []
+    list.value = data ?? []
   } finally {
     loading.value = false
   }