Xiao_123 hace 5 meses
padre
commit
de1b1f299b

+ 5 - 45
src/api/menduner/system/talentMap/index.ts

@@ -1,49 +1,9 @@
 import request from '@/config/axios'
 
-// 猎寻服务 VO
-export interface HuntVO {
-  id: number // id
-  name: string // 姓名
-  enterpriseName: string // 企业名称
-  phone: string // 联系方式
-  status: string // 状态(0待处理|1已联系)
-  remark: string // 备注
-}
-
-// 猎寻服务 API
-export const HuntApi = {
-  // 查询猎寻服务分页
-  getHuntPage: async (params: any) => {
-    return await request.get({ url: `/menduner/system/hunt/page`, params })
-  },
-
-  // 查询猎寻服务详情
-  getHunt: async (id: number) => {
-    return await request.get({ url: `/menduner/system/hunt/get?id=` + id })
-  },
-
-  // 新增猎寻服务
-  createHunt: async (data: HuntVO) => {
-    return await request.post({ url: `/menduner/system/hunt/create`, data })
-  },
-
-  // 修改猎寻服务
-  updateHunt: async (data: HuntVO) => {
-    return await request.put({ url: `/menduner/system/hunt/update`, data })
-  },
-
-  // 处理猎寻服务
-  dealHunt: async (data: HuntVO) => {
-    return await request.put({ url: '/menduner/system/hunt/processed', data })
-  },
-
-  // 删除猎寻服务
-  deleteHunt: async (id: number) => {
-    return await request.delete({ url: `/menduner/system/hunt/delete?id=` + id })
-  },
-
-  // 导出猎寻服务 Excel
-  exportHunt: async (params) => {
-    return await request.download({ url: `/menduner/system/hunt/export-excel`, params })
+// 人才地图 API
+export const TalentMap = {
+  // 简历解析
+  resumeParse: async (params) => {
+    return await request.get({ url: `/menduner/system/online/resume/parser`, params })
   }
 }

+ 69 - 61
src/views/menduner/system/talentMap/details/components/edu.vue

@@ -1,74 +1,82 @@
 <template>
-  <el-table v-loading="loading" :data="tableData" :stripe="true" class="m-t-20px">
-    <el-table-column label="学校名称" align="center" prop="schoolName" />
-    <el-table-column label="专业名称" align="center" prop="major" />
-    <el-table-column label="学历" align="center" prop="educationType">
-      <template #default="scope">
-        <dict-tag v-if="scope.row.educationTyp" :type="DICT_TYPE.MENDUNER_EDUCATION_TYPE" :value="scope.row.educationType" />
-        <span v-else>未知</span>
-      </template>
-    </el-table-column>
-    <el-table-column label="学制类型" align="center" prop="educationSystemType">
-      <template #default="scope">
-        <dict-tag :type="DICT_TYPE.MENDUNER_EDUCATION_SYSTEM_TYPE" :value="scope.row.educationSystemType" />
-      </template>
-    </el-table-column>
-    <el-table-column label="在校开始日期" align="center" prop="startTime" :formatter="dateFormatter2" width="180px" />
-    <el-table-column label="在校结束日期" align="center" prop="endTime" :formatter="dateFormatter2" width="180px" />
-    <el-table-column label="在校经历" align="center" prop="content" :show-overflow-tooltip="true" />
-  </el-table>
+  <el-card shadow="never" class="m-t-10px">
+    <template #header>
+      <CardTitle title="教育经历" />
+    </template>
+    <el-table :data="list" :stripe="true">
+      <el-table-column label="学校名称" align="center" prop="eduCollege" />
+      <el-table-column label="专业名称" align="center" prop="eduMajor" />
+      <el-table-column label="在校日期" align="center" prop="startDate">
+        <template #default="{ row }">{{ row.startDate }} - {{ row.endDate }}</template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" prop="actions">
+        <template #default="{ row, $index }">
+          <el-button link type="primary" @click="handleEdit(row, $index)">编辑</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </el-card>
 
-  <Pagination
-    :total="total"
-    v-model:page="queryParams.pageNo"
-    v-model:limit="queryParams.pageSize"
-    @pagination="getList"
-  />
+  <Dialog title="教育经历编辑" v-model="dialogVisible">
+    <el-form
+      ref="formRef"
+      :model="formData"
+      :rules="formRules"
+      label-width="80px"
+    >
+      <el-form-item label="学校名称" prop="eduCollege" required>
+        <el-input v-model="formData.eduCollege" />
+      </el-form-item>
+      <el-form-item label="专业名称" prop="eduMajor" required>
+        <el-input v-model="formData.eduMajor" />
+      </el-form-item>
+      <el-form-item label="开始时间" prop="startDate" required>
+        <el-input v-model="formData.startDate" placeholder="请填写开始时间" />
+      </el-form-item>
+      <el-form-item label="结束时间" prop="endDate" required>
+        <el-input v-model="formData.endDate" placeholder="请填写结束时间" />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <el-button @click="submitForm" type="primary">确 定</el-button>
+      <el-button @click="dialogVisible = false; formData = {}">取 消</el-button>
+    </template>
+  </Dialog>
 </template>
 
 <script setup>
-defineOptions({ name: 'PersonEduList'})
-import { PersonInfoApi } from '@/api/menduner/system/person'
-import { DICT_TYPE } from '@/utils/dict'
-import { dateFormatter2 } from '@/utils/formatTime'
+defineOptions({ name: 'TalentMapEdu'})
+import { cloneDeep } from 'lodash-es'
 
 const props = defineProps({
-  userId: String
+  data: Array
 })
+const list = ref([])
+list.value = cloneDeep(props.data)
 
-const loading = ref(false)
-const tableData = ref([
-  {
-    id: 21563, 
-    userId: "804044393148452864", 
-    schoolId: null, 
-    schoolName: "广州旅游商务职业学校", 
-    educationType: "2", 
-    educationSystemType: null, 
-    majorId: null, 
-    major: "烹饪", 
-    startTime: 1325347200000, 
-    endTime: 1388505600000, 
-    content: null, 
-    createTime: 1728362217408
-  }
-])
-const total = ref(0)
-const queryParams = reactive({
-  pageNo: 1,
-  pageSize: 10,
-  userId: props.userId
+const editIndex = ref(0)
+const formRef = ref()
+const dialogVisible = ref(false)
+const formData = ref({})
+const formRules = reactive({
+  eduCollege: [{ required: true, message: '学校名称不能为空', trigger: 'blur' }],
+  eduMajor: [{ required: true, message: '专业名称不能为空', trigger: 'blur' }],
+  startDate: [{ required: true, message: '开始时间不能为空', trigger: 'blur' }],
+  endDate: [{ required: true, message: '结束时间不能为空', trigger: 'blur' }]
 })
 
-const getList = async () => {
-  loading.value = true
-  try {
-    const data = await PersonInfoApi.getPersonEduPage(queryParams)
-    tableData.value = data.list
-    total.value = data.total
-  } finally {
-    loading.value = false
-  }
+const handleEdit = (row, index) => {
+  editIndex.value = index
+  formData.value = cloneDeep(row)
+  dialogVisible.value = true
+}
+
+const submitForm = async () => {
+  await formRef.value.validate()
+  list.value[editIndex.value] = formData.value
+  formData.value = {}
+  editIndex.value = 0
+  dialogVisible.value = false
+  console.log(list.value, 'submit')
 }
-// getList()
 </script>

+ 20 - 0
src/views/menduner/system/talentMap/details/components/evaluation.vue

@@ -0,0 +1,20 @@
+<template>
+  <div>
+    <el-card shadow="never">
+      <template #header>
+        <CardTitle title="个人优势" />
+      </template>
+      <el-input v-model="evaluation" :rows="8" type="textarea" placeholder="请输入您的个人优势" />
+    </el-card>
+  </div>
+</template>
+
+<script setup>
+defineOptions({ name: 'TalentMapEvaluation'})
+
+const props = defineProps({
+  data: Object
+})
+
+const evaluation = computed(() => props.data.contMyDesc)
+</script>

+ 75 - 135
src/views/menduner/system/talentMap/details/components/exp.vue

@@ -1,148 +1,88 @@
 <template>
-  <el-table v-loading="loading" :data="tableData" :stripe="true" class="m-t-20px">
-    <el-table-column label="企业名称" align="center" prop="enterpriseName" />
-    <el-table-column label="职位名称" align="center" prop="positionName" />
-    <el-table-column label="在职时间范围" align="center" prop="startTime">
-      <template #default="{ row }">
-        {{ timesTampChange(row.startTime, 'Y-M') + ' 到 ' + (row.endTime ? timesTampChange(row.endTime, 'Y-M') : '至今') }}
-      </template>
-    </el-table-column>
-    <el-table-column label="工作内容" align="center" prop="content" :show-overflow-tooltip="true" />
-  </el-table>
+  <el-card shadow="never" class="m-t-10px">
+    <template #header>
+      <CardTitle title="工作经历" />
+    </template>
+    <el-table :data="list" :stripe="true">
+      <el-table-column label="任职企业" align="center" prop="jobCpy" />
+      <el-table-column label="职位名称" align="center" prop="jobPosition" />
+      <el-table-column label="在职时间" align="center" prop="startTime">
+        <template #default="{ row }">
+          {{ row.startDate }} - {{ row.endDate }}
+        </template>
+      </el-table-column>
+      <!-- <el-table-column label="工作内容" align="center" prop="jobContent" :show-overflow-tooltip="true" /> -->
+      <el-table-column label="操作" align="center" prop="actions">
+        <template #default="{ row, $index }">
+          <el-button link type="primary" @click="handleEdit(row, $index)">编辑</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </el-card>
 
-  <Pagination
-    :total="total"
-    v-model:page="queryParams.pageNo"
-    v-model:limit="queryParams.pageSize"
-    @pagination="getList"
-  />
+  <Dialog title="工作经历编辑" v-model="dialogVisible">
+    <el-form
+      ref="formRef"
+      :model="formData"
+      :rules="formRules"
+      label-width="80px"
+    >
+      <el-form-item label="任职企业" prop="jobCpy" required>
+        <el-input v-model="formData.jobCpy" />
+      </el-form-item>
+      <el-form-item label="职位名称" prop="jobPosition" required>
+        <el-input v-model="formData.jobPosition" />
+      </el-form-item>
+      <el-form-item label="开始时间" prop="startDate" required>
+        <el-input v-model="formData.startDate" placeholder="请填写开始时间" />
+      </el-form-item>
+      <el-form-item label="结束时间" prop="endDate" required>
+        <el-input v-model="formData.endDate" placeholder="请填写结束时间" />
+      </el-form-item>
+      <el-form-item label="工作内容" prop="jobContent">
+        <el-input v-model="formData.jobContent" :rows="8" type="textarea" />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <el-button @click="submitForm" type="primary">确 定</el-button>
+      <el-button @click="dialogVisible = false; formData = {}">取 消</el-button>
+    </template>
+  </Dialog>
 </template>
 
 <script setup>
-defineOptions({ name: 'PersonExpList'})
-import { PersonInfoApi } from '@/api/menduner/system/person'
-import { DICT_TYPE } from '@/utils/dict'
-import { dateFormatter2 } from '@/utils/formatTime'
-import { timesTampChange } from '@/utils/transform/date'
+defineOptions({ name: 'TalentMapExp'})
+import { cloneDeep } from 'lodash-es'
 
 const props = defineProps({
-  userId: String
+  data: Array
 })
+const list = ref([])
+list.value = cloneDeep(props.data)
 
-const loading = ref(false)
-const tableData = ref([
-  {
-    id: 90086, 
-    userId: "804044393148452864", 
-    enterpriseId: null, 
-    enterpriseName: "广州美居酒店", 
-    industryId: null, 
-    deptName: null, 
-    positionId: null, 
-    positionName: "行政总厨 Executive Chef  /  餐饮总监 F .B Director", 
-    startTime: 1709222400000, 
-    endTime: null, 
-    content: null, 
-    achievement: null, 
-    pay: 12000, 
-    payUnit: "2", 
-    currencyType: null, 
-    skillList: null, 
-    createTime: 1728367561460
-  }, 
-  {
-    id: 90085, 
-    userId: "804044393148452864", 
-    enterpriseId: null, 
-    enterpriseName: "广州增城万达嘉华酒店", 
-    industryId: null, 
-    deptName: null, 
-    positionId: null, 
-    positionName: "资深副厨师长", 
-    startTime: 1551369600000, 
-    endTime: 1709222400000, 
-    content: null, 
-    achievement: null, 
-    pay: 9500, 
-    payUnit: "2", 
-    currencyType: null, 
-    skillList: null, 
-    createTime: 1728367455706
-  }, 
-  {
-    id: 90084, 
-    userId: "804044393148452864", 
-    enterpriseId: null, 
-    enterpriseName: "上海绿地铂骊酒店", 
-    industryId: null, 
-    deptName: null, 
-    positionId: null, 
-    positionName: "全日制餐厅副厨师长", 
-    startTime: 1485878400000, 
-    endTime: 1548950400000, 
-    content: null, 
-    achievement: null, 
-    pay: 8500, 
-    payUnit: "2", 
-    currencyType: null, 
-    skillList: null, 
-    createTime: 1728364267421
-  }, 
-  {
-    id: 90083, 
-    userId: "804044393148452864", 
-    enterpriseId: null, 
-    enterpriseName: "广州花都皇冠假日酒店", 
-    industryId: null, 
-    deptName: null, 
-    positionId: null, 
-    positionName: "西厨主管", 
-    startTime: 1391184000000, 
-    endTime: 1483200000000, 
-    content: null, 
-    achievement: null, 
-    pay: 4500, 
-    payUnit: "2", 
-    currencyType: null, 
-    skillList: null, 
-    createTime: 1728367575841
-  }, 
-  {
-    id: 90082, 
-    userId: "804044393148452864", 
-    enterpriseId: null, 
-    enterpriseName: "广州 W 酒店", 
-    industryId: null, 
-    deptName: null, 
-    positionId: null, 
-    positionName: "一级厨师", 
-    startTime: 1356969600000, 
-    endTime: 1388505600000, 
-    content: null, 
-    achievement: null, 
-    pay: 3000, 
-    payUnit: "2", 
-    currencyType: null, 
-    skillList: null, 
-    createTime: 1728367376573
-  }
-])
-const total = ref(0)
-const queryParams = reactive({
-  pageNo: 1,
-  pageSize: 10,
-  userId: props.userId
+const editIndex = ref(0)
+const formRef = ref()
+const dialogVisible = ref(false)
+const formData = ref({})
+const formRules = reactive({
+  jobCpy: [{ required: true, message: '任职企业不能为空', trigger: 'blur' }],
+  jobPosition: [{ required: true, message: '职位名称不能为空', trigger: 'blur' }],
+  startDate: [{ required: true, message: '开始时间不能为空', trigger: 'blur' }],
+  endDate: [{ required: true, message: '结束时间不能为空', trigger: 'blur' }]
 })
 
-const getList = async () => {
-  loading.value = true
-  try {
-    const data = await PersonInfoApi.getPersonExpPage(queryParams)
-    tableData.value = data.list
-    total.value = data.total
-  } finally {
-    loading.value = false
-  }
+const handleEdit = (row, index) => {
+  editIndex.value = index
+  formData.value = cloneDeep(row)
+  dialogVisible.value = true
+}
+
+const submitForm = async () => {
+  await formRef.value.validate()
+  list.value[editIndex.value] = formData.value
+  formData.value = {}
+  editIndex.value = 0
+  dialogVisible.value = false
+  console.log(list.value, 'submit')
 }
-// getList()
 </script>

+ 88 - 106
src/views/menduner/system/talentMap/details/components/info.vue

@@ -1,126 +1,108 @@
 <template>
-  <div v-if="info && Object.keys(info)">
-    <!-- <div style="margin-bottom: 12px; text-align: end;">
-      <div v-if="isEdit">
-        <el-button @click="isEdit = false">取消</el-button>
-        <el-button type="primary" @click="isEdit = false">保存</el-button>
-      </div>
-      <el-button v-else type="primary" @click="isEdit = true">修改</el-button>
-    </div> -->
-    <el-descriptions class="margin-top" :column="2" border>
-      <el-descriptions-item label="用户头像">
-        <el-image v-if="info.avatar" class="h-100px w-100px" :src="info.avatar" fit="contain" hide-on-click-modal :preview-src-list="[info.avatar]"/>
-      </el-descriptions-item>
-      <el-descriptions-item label="性别">
-        <dict-tag v-if="info.sex !== '0'" :type="DICT_TYPE.MENDUNER_SEX" :value="info.sex" />
-      </el-descriptions-item>
-      <el-descriptions-item label="用户名">{{ info.name }}</el-descriptions-item>
-      <el-descriptions-item label="英文名">{{ info.foreignName }}</el-descriptions-item>
-      <el-descriptions-item label="联系电话">{{ info.phone || user.phone }}</el-descriptions-item>
-      <el-descriptions-item label="邮箱">{{ info.email }}</el-descriptions-item>
-      <el-descriptions-item label="出生日期">{{ formatDate(info.birthday, 'YYYY-MM-DD') }}</el-descriptions-item>
-      <el-descriptions-item label="首次工作时间">{{ formatDate(info.firstWorkTime, 'YYYY-MM-DD') }}</el-descriptions-item>
-      <el-descriptions-item label="婚姻状况">
-        <dict-tag :type="DICT_TYPE.MENDUNER_MARITAL_STATUS" :value="info.maritalStatus" />
-      </el-descriptions-item>
-      <el-descriptions-item label="学历">
-        <dict-tag :type="DICT_TYPE.MENDUNER_EDUCATION_TYPE" :value="info.eduType" />
-      </el-descriptions-item>
-      <el-descriptions-item label="	工作经验">
-        <dict-tag :type="DICT_TYPE.MENDUNER_EXP_TYPE" :value="info.expType" />
-      </el-descriptions-item>
-      <el-descriptions-item label="求职类型">
-        <dict-tag :type="DICT_TYPE.MENDUNER_JOB_TYPE" :value="info.jobType" />
-      </el-descriptions-item>
-      <el-descriptions-item label="求职状态">
-        <dict-tag :type="DICT_TYPE.MENDUNER_JOB_SEEK_STATUS" :value="info.jobStatus" />
-      </el-descriptions-item>
-      <!-- <el-descriptions-item label="账号状态">
-        <dict-tag :type="DICT_TYPE.MENDUNER_STATUS" :value="user.status" />
-      </el-descriptions-item> -->
-      <!-- <el-descriptions-item label="会员套餐">
-        {{ user.vipFlag ? packageList.find(e => e.id === Number(user.vipFlag))?.name : '' }}
-      </el-descriptions-item> -->
-      <!-- <el-descriptions-item label="会员到期时间">
-        {{ formatDate(user.vipExpireDate, 'YYYY-MM-DD HH:mm:ss') }}
-      </el-descriptions-item> -->
-    </el-descriptions>
+  <div>
+    <el-card shadow="never">
+      <template #header>
+        <CardTitle title="基本信息" />
+      </template>
+      <!-- <div style="margin-bottom: 12px; text-align: end;">
+        <div v-if="isEdit">
+          <el-button @click="isEdit = false">取消</el-button>
+          <el-button type="primary" @click="isEdit = false">保存</el-button>
+        </div>
+        <el-button v-else type="primary" @click="isEdit = true">修改</el-button>
+      </div> -->
+      <el-descriptions class="margin-top" :column="2" border>
+        <el-descriptions-item label="用户头像">
+          <el-image v-if="data.avatarData" class="h-100px w-100px" :src="data.avatarData" fit="contain" hide-on-click-modal :preview-src-list="[data.avatarData]"/>
+        </el-descriptions-item>
+        <el-descriptions-item label="性别">{{ data.genderInf }}</el-descriptions-item>
+        <el-descriptions-item label="用户名">{{ data.name }}</el-descriptions-item>
+        <el-descriptions-item label="联系电话">{{ data.phone }}</el-descriptions-item>
+        <el-descriptions-item label="工作年限">{{ data.workYear }}年</el-descriptions-item>
+        <el-descriptions-item label="出生日期">{{ data.birthday }}</el-descriptions-item>
+        <el-descriptions-item label="婚姻状况">{{ data.marital_status }}</el-descriptions-item>
+        <el-descriptions-item label="学历">{{ data.degree }}</el-descriptions-item>
+        <el-descriptions-item label="邮箱">{{ data.email }}</el-descriptions-item>
+        <el-descriptions-item label="现居">{{ data.city }}</el-descriptions-item>
+      </el-descriptions>
+    </el-card>
   </div>
 </template>
 
 <script setup>
 defineOptions({ name: 'EnterpriseDetailsInfo'})
-import { DICT_TYPE } from '@/utils/dict'
-import { formatDate } from '@/utils/formatTime'
-import { PersonInfoApi } from '@/api/menduner/system/person'
+// import { DICT_TYPE } from '@/utils/dict'
+// import { formatDate } from '@/utils/formatTime'
+// import { PersonInfoApi } from '@/api/menduner/system/person'
 
 const props = defineProps({
-  id: String,
-  userId: String
+  // id: String,
+  // userId: String,
+  data: Object
 })
 
 // const isEdit = ref(false)
 
 // 获取人才详情
-const info = ref({
-  id: "1843909447483768834", 
-  userId: "804044393148452864", 
-  foreignName: "Oscar", 
-  name: "沈和威", 
-  sex: "0", 
-  avatar: "https://www.mendunerhr.com/images/1726804566749_804044393148452864_mini.jpg", 
-  phone: null, 
-  email: "812320386@qq.com", 
-  wxCode: null, 
-  birthday: 828547200000, 
-  maritalStatus: null, 
-  areaId: null, 
-  regId: null, 
-  jobType: "0", 
-  jobStatus: "2", 
-  firstWorkTime: 1356969600000, 
-  advantage: null, 
-  expType: "7", 
-  eduType: "3", 
-  tagList: null, 
-  createTime: 1728457245120, 
-  updateTime: 1732688920332
-})
-const getInfo = async () => {
-  const data = await PersonInfoApi.getPersonDetails(props.id)
-  info.value = data
-}
+// const info = ref({
+//   id: "1843909447483768834", 
+//   userId: "804044393148452864", 
+//   foreignName: "Oscar", 
+//   name: "沈和威", 
+//   sex: "0", 
+//   avatar: "https://www.mendunerhr.com/images/1726804566749_804044393148452864_mini.jpg", 
+//   phone: null, 
+//   email: "812320386@qq.com", 
+//   wxCode: null, 
+//   birthday: 828547200000, 
+//   maritalStatus: null, 
+//   areaId: null, 
+//   regId: null, 
+//   jobType: "0", 
+//   jobStatus: "2", 
+//   firstWorkTime: 1356969600000, 
+//   advantage: null, 
+//   expType: "7", 
+//   eduType: "3", 
+//   tagList: null, 
+//   createTime: 1728457245120, 
+//   updateTime: 1732688920332
+// })
+// const getInfo = async () => {
+//   const data = await PersonInfoApi.getPersonDetails(props.id)
+//   info.value = data
+// }
 // if (props.id) getInfo()
 
 // 会员套餐列表
-const packageList = ref([])
-const getPackageList = async () => {
-  const data = await PersonInfoApi.getPersonPackageList()
-  packageList.value = data
-}
-getPackageList()
+// const packageList = ref([])
+// const getPackageList = async () => {
+//   const data = await PersonInfoApi.getPersonPackageList()
+//   packageList.value = data
+// }
+// getPackageList()
 
 // 获取用户详情
-const user = ref({
-  id: "804044393148452864", 
-  username: "13539831035", 
-  password: "$2a$04$3QZFv24b5l8OxwHijZZQY.GDxXZZbdYvl8Y8cJXtBxQ2UDsCPnSBe", 
-  email: "812320386@qq.com", 
-  phone: "13539831035", 
-  avatar: "https://www.mendunerhr.com/images/1726804566749_804044393148452864_mini.jpg", 
-  status: "0", 
-  registerIp: null, 
-  registerTerminal: null, 
-  vipFlag: null, 
-  vipExpireDate: null, 
-  inviteCode: null, 
-  loginIp: "", 
-  loginDate: null, 
-  createTime: 1728291312047
-})
-const getUserDetails = async () => {
-  const data = await PersonInfoApi.getUserDetails(props.userId)
-  user.value = data
-}
+// const user = ref({
+//   id: "804044393148452864", 
+//   username: "13539831035", 
+//   password: "$2a$04$3QZFv24b5l8OxwHijZZQY.GDxXZZbdYvl8Y8cJXtBxQ2UDsCPnSBe", 
+//   email: "812320386@qq.com", 
+//   phone: "13539831035", 
+//   avatar: "https://www.mendunerhr.com/images/1726804566749_804044393148452864_mini.jpg", 
+//   status: "0", 
+//   registerIp: null, 
+//   registerTerminal: null, 
+//   vipFlag: null, 
+//   vipExpireDate: null, 
+//   inviteCode: null, 
+//   loginIp: "", 
+//   loginDate: null, 
+//   createTime: 1728291312047
+// })
+// const getUserDetails = async () => {
+//   const data = await PersonInfoApi.getUserDetails(props.userId)
+//   user.value = data
+// }
 // getUserDetails()
 </script>

+ 41 - 60
src/views/menduner/system/talentMap/details/index.vue

@@ -3,70 +3,49 @@
     <el-row :gutter="10">
       <el-col :span="14">
         <el-card shadow="never">
+          <IFrame :src="fileUrl" />
+        </el-card>
+      </el-col>
+      <el-col :span="10">
+        <div>
           <el-tabs type="border-card">
-            <el-tab-pane label="附件简历">
-              <Attachment :user-id="userId" />
+            <el-tab-pane v-if="Object.keys(result).length" label="简历解析内容">
+              <Info :data="result"/>
+              <Evaluation :data="result" class="m-t-10px" />
+              <Edu :data="result.educationObjs"  />
+              <Exp :data="result.jobExpObjs" />
             </el-tab-pane>
-            <el-tab-pane label="在线简历">
-              <el-card shadow="never" class="m-b-12px">
-                <template #header>
-                  <div class="flex items-center justify-between">
-                    <CardTitle title="基本信息" />
-                    <!-- <el-button size="small" type="primary" @click="null; newTagText = ''"> 修改 </el-button> -->
-                  </div>
-                </template>
-                <Info :id="id" :user-id="userId" />
-              </el-card>
-              <el-card shadow="never" class="m-b-12px">
+            <el-tab-pane label="标签">
+              <el-card shadow="never">
                 <template #header>
                   <div class="flex items-center justify-between">
-                    <CardTitle title="工作经历" />
+                    <CardTitle title="已有标签" />
+                    <el-button size="small" type="primary" @click="addNewTag = true; newTagText = ''">
+                      添加新标签
+                    </el-button>
                   </div>
                 </template>
-                <Exp :id="id" :user-id="userId" />
+                <div style="display: flex;" class="m-b-12px" v-if="addNewTag">
+                  <el-input
+                    v-model="newTagText"
+                    placeholder="请输入标签,按回车键确认!"
+                    clearable
+                    style="max-width: 300px;"
+                    @keyup.enter="saveTags"
+                  />
+                  <el-button type="primary" class="m-l-12px" @click="saveTags">保存</el-button>
+                  <el-button @click="addNewTag = false">关闭</el-button>
+                </div>
+                <Tags :id="id" />
               </el-card>
-              <el-card shadow="never" class="m-b-12px">
+              <el-card shadow="never" class="m-t-10px">
                 <template #header>
-                  <div class="flex items-center justify-between">
-                    <CardTitle title="教育经历" />
-                  </div>
+                  <CardTitle title="推荐标签" />
                 </template>
-                <Edu :id="id" :user-id="userId" />
+                <TagsRecommend :id="id" />
               </el-card>
             </el-tab-pane>
           </el-tabs>
-        </el-card>
-      </el-col>
-      <el-col :span="10">
-        <div>
-          <el-card shadow="never">
-            <template #header>
-              <div class="flex items-center justify-between">
-                <CardTitle title="已有标签" />
-                <el-button size="small" type="primary" @click="addNewTag = true; newTagText = ''">
-                  添加新标签
-                </el-button>
-              </div>
-            </template>
-            <div style="display: flex;" class="m-b-12px" v-if="addNewTag">
-              <el-input
-                v-model="newTagText"
-                placeholder="请输入标签,按回车键确认!"
-                clearable
-                style="max-width: 300px;"
-                @keyup.enter="saveTags"
-              />
-              <el-button type="primary" class="m-l-12px" @click="saveTags">保存</el-button>
-              <el-button @click="addNewTag = false">关闭</el-button>
-            </div>
-            <Tags :id="id" :user-id="userId" />
-          </el-card>
-          <el-card shadow="never" class="m-t-10px">
-            <template #header>
-              <CardTitle title="推荐标签" />
-            </template>
-            <TagsRecommend :id="id" :user-id="userId" />
-          </el-card>
         </div>
       </el-col>
     </el-row>
@@ -82,8 +61,10 @@ import Edu from './components/edu.vue'
 import Exp from './components/exp.vue'
 import Attachment from './components/attachment.vue'
 import DeliveryJob from './components/deliveryJob.vue'
+import Evaluation from './components/evaluation.vue'
 import Tags from './components/tags.vue'
 import TagsRecommend from './components/tagsRecommend.vue'
+import { TalentMap } from '@/api/menduner/system/talentMap'
 
 const addNewTag = ref(false)
 const newTagText = ref('')
@@ -91,16 +72,16 @@ const saveTags = () => {
   addNewTag.value = false
 }
 
+const result = ref({})
+const fileUrl = ref('')
+
 /** 初始化 */
 const { currentRoute } = useRouter() // 路由
-const { delView } = useTagsViewStore() // 视图操作
 const route = useRoute()
-const { id, userId } = route.query
-onMounted(() => {
-  if (!userId) {
-    ElMessage.warning('参数错误,用户编号不能为空!')
-    delView(unref(currentRoute))
-    return
-  }
+const { id } = route.params
+onMounted(async () => {
+  const parserData = localStorage.getItem('resumeParserData') ? JSON.parse(localStorage.getItem('resumeParserData')) : {}
+  fileUrl.value = parserData.url
+  result.value = parserData.data
 })
 </script>

+ 94 - 97
src/views/menduner/system/talentMap/index.vue

@@ -9,79 +9,27 @@
       label-width="68px"
     >
       <el-form-item label="姓名" prop="name">
-        <el-input
-          v-model="queryParams.name"
-          placeholder="请输入姓名"
-          clearable
-          @keyup.enter="handleQuery"
-          class="!w-240px"
-        />
+        <el-input v-model="queryParams.name" placeholder="请输入姓名" clearable @keyup.enter="handleQuery" class="!w-240px" />
       </el-form-item>
       <el-form-item>
         <el-button @click="handleQuery"><Icon icon="ep:search" /> 搜索</el-button>
         <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
-        <!-- <el-button
-          type="primary"
-          plain
-          @click="openForm"
-        >
-          <Icon icon="ep:plus" class="mr-5px" /> 新增
-        </el-button> -->
-        <el-button
-          type="warning"
-          plain
-          @click="handleImportAttachment"
-        >
-          简历解析
-          <File ref="uploadFile" @success="handleUploadResume"/>
+        <el-button type="primary" plain @click="handleAdd">
+          <Icon icon="ep:plus" class="mr-5px" /> 新增人才
         </el-button>
-        <!-- <UploadFile
-          v-model="fileUrl"
-          :limit="1"
-          txt="简历解析"
-          :plain="true"
-          :is-show-tip="false"
-          butType="warning"
-          accept=".pdf, .doc"
-          class="ml-10px mt-10px"
-        /> -->
-        <!-- <el-button
-          type="success"
-          plain
-          @click="handleExport"
-          :loading="exportLoading"
-        >
-          <Icon icon="ep:download" class="mr-5px" /> 导出
-        </el-button> -->
       </el-form-item>
     </el-form>
-    <div>
-      
-    </div>
   </ContentWrap>
 
   <!-- 列表 -->
   <ContentWrap>
     <el-table v-loading="loading" :data="list" :stripe="true">
-      <!-- <el-table-column label="id" align="center" prop="id" :show-overflow-tooltip="true" /> -->
       <el-table-column label="姓名" align="center" prop="name" />
       <el-table-column label="标签个数" align="center" prop="num" />
       <el-table-column label="操作" align="center">
         <template #default="scope">
-          <el-button
-            link
-            type="primary"
-            @click="openDetail(scope.row)"
-          >
-            查看
-          </el-button>
-          <el-button
-            link
-            type="danger"
-            @click="handleDelete(scope.row.id)"
-          >
-            删除
-          </el-button>
+          <el-button link type="primary" @click="openDetail(scope.row)">查看</el-button>
+          <el-button link type="danger" @click="handleDelete(scope.row.id)">删除</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -95,16 +43,46 @@
   </ContentWrap>
 
   <!-- 表单弹窗:添加/修改 -->
-  <!-- <TalentForm ref="formRef" @success="getList" /> -->
+  <TalentForm ref="formRef" @success="getList" />
+
+  <Dialog v-model="dialogVisible" title="新增人才" style="width: 47%;">
+    <div style="display: flex;">
+      <el-upload
+        ref="uploadRef"
+        v-model:file-list="fileList"
+        :action="uploadUrl"
+        :auto-upload="false"
+        :data="data"
+        :limit="1"
+        :on-change="handleChange"
+        :on-error="submitFormError"
+        :on-exceed="handleExceed"
+        :on-success="submitFormSuccess"
+        :http-request="httpRequest"
+        accept=".pdf"
+        drag
+        style="flex: 1;"
+      >
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">上传附件, 将文件拖到此处,或 <em>点击上传</em></div>
+        <template #tip>
+          <div class="el-upload__tip" style="color: red">
+            提示:仅允许导入 pdf 格式文件!
+          </div>
+        </template>
+      </el-upload>
+      <div class="m-l-10px info" @click="dialogVisible = false; formRef.open()">
+        点击填写基本信息
+      </div>
+    </div>
+  </Dialog>
 </template>
 
 <script setup>
-// import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
 import download from '@/utils/download'
-// import { HuntApi, HuntVO } from '@/api/menduner/system/hunt'
-// import TalentForm from './talentForm.vue'
 import { commonApi } from '@/api/menduner/common'
 import File from '@/components/Upload/file.vue'
+import { useUpload } from '@/components/UploadFile/src/useUpload'
 
 /** 猎寻服务 列表 */
 defineOptions({ name: 'TalentMap' })
@@ -120,12 +98,42 @@ const queryParams = reactive({
   pageSize: 10,
   name: undefined,
 })
+const formRef = ref()
 const queryFormRef = ref() // 搜索的表单
 const exportLoading = ref(false) // 导出的加载中
 
+const uploadRef = ref()
+const dialogVisible = ref(false)
+const data = ref({ path: '' })
+const fileList = ref([]) // 文件列表
+const { uploadUrl, httpRequest } = useUpload()
+
+/** 上传错误提示 */
+const submitFormError = () => {
+  message.error('上传失败,请您重新上传!')
+}
+
+/** 文件数超出提示 */
+const handleExceed = () => {
+  message.error('最多只能上传一个文件!')
+}
+
+const submitFormSuccess = () => {
+  // 清理
+  dialogVisible.value = false
+  unref(uploadRef)?.clearFiles()
+}
+
+// 文件上传
+const handleChange = (file) => {
+  data.value.path = file.name
+  unref(uploadRef)?.submit()
+  if (fileList.value.length) handleUploadResume(fileList.value[0].response.data, fileList.value[0].name)
+}
+
 /** 查询列表 */
 const getList = async () => {
-  list.value = [{id: '1843909421273563137', userId: '800018973600124928', name: '测试', num: '23'}]
+  // list.value = [{id: '1843909421273563137', userId: '800018973600124928', name: '测试', num: '23'}]
   loading.value = false
   
   // loading.value = true
@@ -139,13 +147,6 @@ const getList = async () => {
   // }
 }
 
-
-/** 添加操作 */
-// const formRef = ref()
-// const openForm = () => {
-//   formRef.value.open()
-// }
-
 /** 搜索按钮操作 */
 const handleQuery = () => {
   queryParams.pageNo = 1
@@ -177,49 +178,45 @@ const handleDelete = async (id) => {
   } catch {}
 }
 
-/** 导出按钮操作 */
-// const handleExport = async () => {
-//   try {
-//     // 导出的二次确认
-//     await message.exportConfirm()
-//     // 发起导出
-//     exportLoading.value = true
-//     // const data = await HuntApi.exportHunt(queryParams)
-//     // download.excel(data, '猎寻服务.xls')
-//   } catch {
-//   } finally {
-//     exportLoading.value = false
-//   }
-// }
-
-// 导入附件简历
-const uploadFile = ref()
-const handleImportAttachment = () => {
-  uploadFile.value.trigger()
+const handleAdd = () => {
+  dialogVisible.value = true
 }
 
 // 上传附件
-// const fileUrl = ref('')
-// const resumeParserData = ref({})
-const handleUploadResume = async (url, title, filename) => {
+const handleUploadResume = async (url, filename) => {
   if (url) {
     const res = await commonApi.resumeParser({ fileUrl: url })
-    if (res?.data?.status?.code === 200) {
+    if (res?.status?.code === 200) {
       localStorage.setItem('resumeParserData', JSON.stringify({
-        data: res.data,
+        data: res.result,
         url: url,
         filename: filename,
-        id: Date.now() + 'resumeParserData'
+        id: Date.now()
       }))
       // 路由跳转
-      // talentMap/talentMap/detail
       push({ name: 'TalentMapDetail' })
     }
   }
 }
-
 /** 初始化 **/
 onMounted(() => {
   getList()
 })
-</script>
+</script>
+
+<style lang="scss">
+.info {
+  display: flex;
+  width: 50%;
+  height: 99px;
+  cursor: pointer; 
+  border: 1px dashed #ccc; 
+  border-radius: 6px; 
+  align-items: center; 
+  justify-content: center;
+
+  &:hover {
+    border: 1px dashed #409eff;
+  }
+}
+</style>

+ 8 - 16
src/views/menduner/system/talentMap/talentForm.vue

@@ -1,5 +1,5 @@
 <template>
-  <Dialog :title="dialogTitle" v-model="dialogVisible">
+  <Dialog title="基本信息填写" v-model="dialogVisible">
     <el-form
       ref="formRef"
       :model="formData"
@@ -8,19 +8,19 @@
       v-loading="formLoading"
     >
       <el-form-item label="姓名" prop="name">
-        <el-input :disabled="formType === 'handle'" v-model="formData.name" placeholder="请输入姓名" />
+        <el-input v-model="formData.name" placeholder="请输入姓名" />
       </el-form-item>
       <el-form-item label="联系方式" prop="phone">
-        <el-input :disabled="formType === 'handle'" v-model="formData.phone" placeholder="请输入联系方式" />
+        <el-input v-model="formData.phone" placeholder="请输入联系方式" />
       </el-form-item>
       <el-form-item label="任职企业名称" prop="enterpriseName">
-        <el-input :disabled="formType === 'handle'" v-model="formData.enterpriseName" placeholder="请输入企业名称" />
+        <el-input v-model="formData.enterpriseName" placeholder="请输入企业名称" />
       </el-form-item>
       <el-form-item label="任职职位名称" prop="enterpriseName">
-        <el-input :disabled="formType === 'handle'" v-model="formData.positionName" placeholder="请输入企业名称" />
+        <el-input v-model="formData.positionName" placeholder="请输入企业名称" />
       </el-form-item>
       <el-form-item label="求职状态" prop="jobStatus">
-        <el-select :disabled="formType === 'handle'" v-model="formData.status" placeholder="请选择状态">
+        <el-select v-model="formData.status" placeholder="请选择状态">
           <el-option
             v-for="(dict, index) in getStrDictOptions(DICT_TYPE.MENDUNER_JOB_SEEK_STATUS)"
             :key="'status'+index"
@@ -29,9 +29,6 @@
           />
         </el-select>
       </el-form-item>
-      <!-- <el-form-item label="备注" prop="remark">
-        <el-input v-model="formData.remark" type="textarea" rows="6" placeholder="请输入备注" />
-      </el-form-item> -->
     </el-form>
     <template #footer>
       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
@@ -39,9 +36,9 @@
     </template>
   </Dialog>
 </template>
+
 <script setup lang="ts">
 import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
-// import { HuntApi, HuntVO } from '@/api/menduner/system/talentMap'
 
 /** 猎寻服务 表单 */
 defineOptions({ name: 'TalentForm' })
@@ -50,9 +47,7 @@ defineOptions({ name: 'TalentForm' })
 // const message = useMessage() // 消息弹窗
 
 const dialogVisible = ref(false) // 弹窗的是否展示
-const dialogTitle = ref('新增人才') // 弹窗的标题
 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
-const formType = ref('') // 表单的类型:create - 新增;update - 修改
 const formData = ref({
   id: undefined,
   name: undefined,
@@ -64,13 +59,12 @@ const formData = ref({
 
 /** 重置表单 */
 const resetForm = () => {
-  // formData.value = {}
   Object.keys(formData.value).forEach(key => formData.value[key] = undefined)
   formData.value
   formRef.value?.resetFields()
 }
 const formRules = reactive({
-  name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
+  // name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
   // enterpriseName: [{ required: true, message: '企业名称不能为空', trigger: 'blur' }],
   // phone: [{ required: true, message: '联系方式不能为空', trigger: 'blur' }],
 })
@@ -79,8 +73,6 @@ const formRef = ref() // 表单 Ref
 /** 打开弹窗 */
 const open = async () => {
   dialogVisible.value = true
-  // dialogTitle.value = t('action.' + type)
-  // formType.value = type
   resetForm()
   // // 修改时,设置数据
   // if (id) {