Bladeren bron

人才地图管理

lifanagju_citu 5 maanden geleden
bovenliggende
commit
bc8f0918de

+ 1 - 1
src/router/modules/remaining.ts

@@ -506,7 +506,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
   {
     path: '/talentMap',
     component: Layout,
-    name: 'talentMap',
+    name: 'talentMapCenter',
     meta: { hidden: true },
     children: [
       {

+ 40 - 0
src/views/menduner/system/talentMap/details/components/attachment.vue

@@ -0,0 +1,40 @@
+<template>
+  <el-table v-loading="loading" :data="tableData" :stripe="true">
+    <el-table-column label="附件名称" align="center" prop="title" />
+    <el-table-column label="操作" align="center">
+      <template #default="scope">
+        <el-link type="primary" download :href="scope.row.url" :underline="false" target="_blank">下载</el-link>
+      </template>
+    </el-table-column>
+  </el-table>
+</template>
+
+<script setup>
+defineOptions({ name: 'PersonAttachment' })
+import { PersonInfoApi } from '@/api/menduner/system/person'
+
+const props = defineProps({
+  userId: String
+})
+
+const loading = ref(false)
+const tableData = ref([])
+const total = ref(0)
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 5,
+  userId: props.userId
+})
+
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await PersonInfoApi.getPersonAttachmentList(queryParams)
+    tableData.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+getList()
+</script>

+ 30 - 0
src/views/menduner/system/talentMap/details/components/collect.vue

@@ -0,0 +1,30 @@
+<template>
+  <div>
+    <el-descriptions class="margin-top" :column="1" border>
+      <el-descriptions-item label="职位收藏数量">{{ info.position || 0 }}</el-descriptions-item>
+      <el-descriptions-item label="企业收藏数量">{{ info.enterprise || 0 }}</el-descriptions-item>
+    </el-descriptions>
+  </div>
+</template>
+
+<script setup>
+/* 职位、企业收藏数量 */
+defineOptions({ name: 'PersonAccount'})
+import { PersonInfoApi } from '@/api/menduner/system/person'
+import { formatDate } from '@/utils/formatTime'
+import { DICT_TYPE } from '@/utils/dict'
+
+const props = defineProps({
+  userId: String
+})
+
+const info = ref({
+  position: 0,
+  enterprise: 0
+})
+const getInfo = async () => {
+  info.value.position = await PersonInfoApi.getPersonJobFavoriteCount(props.userId)
+  info.value.enterprise = await PersonInfoApi.getPersonEnterpriseSubscribeCount(props.userId)
+}
+getInfo()
+</script>

+ 134 - 0
src/views/menduner/system/talentMap/details/components/deliveryJob.vue

@@ -0,0 +1,134 @@
+<template>
+  <el-table v-loading="loading" :data="tableData" :stripe="true" class="m-t-20px">
+    <el-table-column label="职位名称" align="center" prop="job.name" />
+    <el-table-column label="发布企业" align="center" prop="enterprise.anotherName">
+      <template #default="scope">{{ scope.row.enterprise.anotherName || scope.row.enterprise.name}}</template>
+    </el-table-column>
+    <el-table-column label="地区" align="center" prop="job.areaName">
+      <template #default="scope">{{ !scope.row.job.areaId ? '全国' : scope.row.job.areaName }}</template>
+    </el-table-column>
+    <el-table-column label="薪资" align="center" prop="job.payFrom">
+      <template #default="scope">
+        <span v-if="scope.row.job.payFrom && scope.row.job.payTo">
+          {{ scope.row.job.payFrom }} - {{ scope.row.job.payTo }}/{{ payUnit.find(e => e.value === Number(scope.row.job.payUnit))?.label }}
+        </span>
+        <span v-else>面议</span>
+      </template>
+    </el-table-column>
+    <el-table-column label="投递附件名称" align="center" prop="cvRel.title" />
+    <el-table-column label="投递时间" align="center" prop="cvRel.createTime" :formatter="dateFormatter" width="180px" />
+    <el-table-column label="投递状态" align="center">
+      <template #default="scope">
+        {{ scope.row.cvRel.status === '0' ? '未查看' : '已查看'}}
+      </template>
+    </el-table-column>
+    <el-table-column label="操作" align="center">
+      <template #default="scope">
+        <el-button link type="primary" @click="openDetail(scope.row)" class="m-r-10px">详情</el-button>
+        <el-link type="primary" download :href="scope.row.cvRel.url" :underline="false" target="_blank">附件下载</el-link>
+      </template>
+    </el-table-column>
+  </el-table>
+
+  <Pagination
+    :total="total"
+    v-model:page="queryParams.pageNo"
+    v-model:limit="queryParams.pageSize"
+    @pagination="getList"
+  />
+
+  <Dialog title="职位详情" v-model="dialogVisible">
+    <el-descriptions :column="1" border>
+      <el-descriptions-item label="职位名称">{{ itemData.name }}</el-descriptions-item>
+      <el-descriptions-item label="发布企业">{{ itemData.enterpriseName }}</el-descriptions-item>
+      <el-descriptions-item label="职位类型">{{ itemData.positionName }}</el-descriptions-item>
+      <el-descriptions-item label="工作城市">{{ !itemData.areaId ? '全国' : itemData.areaName }}</el-descriptions-item>
+      <el-descriptions-item label="详细地址">{{ itemData.address }}</el-descriptions-item>
+      <el-descriptions-item label="薪资">
+        <span v-if="itemData.payFrom && itemData.payTo">
+          {{ itemData.payFrom }} - {{ itemData.payTo }}/{{ payUnit.find(e => e.value === Number(itemData.payUnit))?.label }}
+        </span>
+        <span v-else>面议</span>
+      </el-descriptions-item>
+      <el-descriptions-item label="投递附件名称">
+        <el-link type="primary" download :href="itemData.title" :underline="false" target="_blank">{{ itemData.title }}</el-link>
+      </el-descriptions-item>
+      <el-descriptions-item label="投递时间">
+        {{ itemData.time ? timesTampChange(itemData.time, 'Y-M-D h:m:s') : '' }}
+      </el-descriptions-item>
+      <el-descriptions-item label="投递状态">
+        {{ itemData.cvStatus === '0' ? '未查看' : '已查看' }}
+      </el-descriptions-item>
+      <el-descriptions-item label="学历要求">
+        <dict-tag :type="DICT_TYPE.MENDUNER_EDUCATION_TYPE" :value="itemData.eduType" />
+      </el-descriptions-item>
+      <el-descriptions-item label="工作经验">
+        <dict-tag :type="DICT_TYPE.MENDUNER_EXP_TYPE" :value="itemData.expType" />
+      </el-descriptions-item>
+      <el-descriptions-item label="刷新时间">{{ timesTampChange(itemData.updateTime, 'Y-M-D h:m') }}</el-descriptions-item>
+      <el-descriptions-item label="到期时间">
+        {{ itemData.expireTime ? timesTampChange(itemData.expireTime, 'Y-M-D') : '长期有效' }}
+      </el-descriptions-item>
+      <el-descriptions-item label="职位关键字">
+        <el-tag type="primary" v-for="k in itemData.tagList" :key="k" class="m-r-5px m-b-5px">{{ k }}</el-tag>
+      </el-descriptions-item>
+    </el-descriptions>
+    <template #footer>
+      <el-button @click="dialogVisible = false; itemData = {}">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+
+<script setup>
+defineOptions({ name: 'PersonEduList'})
+import { PersonInfoApi } from '@/api/menduner/system/person'
+import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
+import { dateFormatter } from '@/utils/formatTime'
+import { timesTampChange } from '@/utils/transform/date'
+import { dealDictObjData } from '@/utils/transform/position'
+
+const props = defineProps({
+  userId: String
+})
+
+const loading = ref(false)
+const tableData = ref([])
+const total = ref(0)
+const payUnit = getIntDictOptions(DICT_TYPE.MENDUNER_PAY_UNIT)
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  userId: props.userId
+})
+
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await PersonInfoApi.getPersonJobDeliveryList(queryParams)
+    tableData.value = data.list.map(e => {
+      e.job = dealDictObjData({}, e.job)
+      return e
+    })
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+getList()
+
+// 职位详情
+const itemData = ref({})
+const dialogVisible = ref(false)
+const openDetail = (item) => {
+  itemData.value = { 
+    ...item.job, 
+    enterpriseName: item.enterprise.anotherName || item.enterprise.name, 
+    url: item.cvRel.url, 
+    title: item.cvRel.title, 
+    time: item.cvRel.createTime,
+    cvStatus: item.cvRel.status
+  }
+  console.log(itemData.value, '===========')
+  dialogVisible.value = true
+}
+</script>

+ 58 - 0
src/views/menduner/system/talentMap/details/components/edu.vue

@@ -0,0 +1,58 @@
+<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 :type="DICT_TYPE.MENDUNER_EDUCATION_TYPE" :value="scope.row.educationType" />
+      </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>
+
+  <Pagination
+    :total="total"
+    v-model:page="queryParams.pageNo"
+    v-model:limit="queryParams.pageSize"
+    @pagination="getList"
+  />
+</template>
+
+<script setup>
+defineOptions({ name: 'PersonEduList'})
+import { PersonInfoApi } from '@/api/menduner/system/person'
+import { DICT_TYPE } from '@/utils/dict'
+import { dateFormatter2 } from '@/utils/formatTime'
+
+const props = defineProps({
+  userId: String
+})
+
+const loading = ref(false)
+const tableData = ref([])
+const total = ref(0)
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  userId: props.userId
+})
+
+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
+  }
+}
+getList()
+</script>

+ 52 - 0
src/views/menduner/system/talentMap/details/components/exp.vue

@@ -0,0 +1,52 @@
+<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>
+
+  <Pagination
+    :total="total"
+    v-model:page="queryParams.pageNo"
+    v-model:limit="queryParams.pageSize"
+    @pagination="getList"
+  />
+</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'
+
+const props = defineProps({
+  userId: String
+})
+
+const loading = ref(false)
+const tableData = ref([])
+const total = ref(0)
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  userId: props.userId
+})
+
+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
+  }
+}
+getList()
+</script>

+ 9 - 0
src/views/menduner/system/talentMap/details/components/info.vue

@@ -1,5 +1,12 @@
 <template>
   <div>
+    <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]"/>
@@ -52,6 +59,8 @@ const props = defineProps({
   userId: String
 })
 
+const isEdit = ref(false)
+
 // 获取人才详情
 const info = ref({})
 const getInfo = async () => {

+ 70 - 0
src/views/menduner/system/talentMap/details/components/interviewInvite.vue

@@ -0,0 +1,70 @@
+<template>
+  <ContentWrap>
+    <el-table v-loading="loading" :data="list" :stripe="true">
+      <el-table-column label="投递岗位" align="center" prop="job.name" />
+      <el-table-column label="岗位薪资" align="center" prop="job.payFrom">
+        <template #default="{ row }">
+          {{ !row.job.payFrom && !row.job.payTo ? '面议' : `${row.job.payFrom}-${row.job.payTo}/${payUnit.find(e => e.value === Number(row.job.payUnit))?.label}` }}
+        </template>
+      </el-table-column>
+      <el-table-column label="发布企业" align="center" prop="enterprise.name">
+        <template #default="{ row }">{{ row.enterprise.anotherName || row.enterprise.name }}</template>
+      </el-table-column>
+      <el-table-column label="面试时间" align="center" prop="time">
+        <template #default="{ row }">{{ timesTampChange(row.time, 'Y-M-D h:m') }}</template>
+      </el-table-column>
+      <el-table-column label="面试地点" align="center" prop="address" />
+      <el-table-column label="联系人" align="center" prop="contact.name" />
+      <el-table-column label="联系电话" align="center" prop="phone" />
+      <el-table-column label="状态" align="center" prop="status">
+        <template #default="{ row }">
+          <dict-tag :type="DICT_TYPE.MENDUNER_INTERVIEW_INVITE_STATUS" :value="row.status" />
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </ContentWrap>
+</template>
+
+<script lang="ts" setup>
+import { timesTampChange } from '@/utils/transform/date'
+import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
+import { PersonInfoApi } from '@/api/menduner/system/person'
+defineOptions({ name: 'PersonInterviewInvite' })
+
+const props = defineProps({
+  userId: String
+})
+
+const loading = ref(true) // 列表的加载中
+const total = ref(0) // 列表的总页数
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  userId: props.userId
+})
+
+const payUnit = getIntDictOptions(DICT_TYPE.MENDUNER_PAY_UNIT)
+const list = ref([]) // 列表的数据
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await PersonInfoApi.getInterviewInvitePage(queryParams)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 初始化 **/
+onMounted(() => {
+  getList()
+})
+</script>

+ 69 - 0
src/views/menduner/system/talentMap/details/components/jobIntention.vue

@@ -0,0 +1,69 @@
+<template>
+  <el-table v-loading="loading" :data="tableData" :stripe="true" class="m-t-20px">
+    <el-table-column label="期望职位" align="center" prop="positionName" />
+    <el-table-column label="期望行业" align="center" prop="industryNameList">
+      <template #default="scope">
+        {{  scope.row.industryNameList && scope.row.industryNameList.length ? scope.row.industryNameList.join(',') : '' }}
+      </template>
+    </el-table-column>
+    <el-table-column label="薪酬最低要求" align="center" prop="payFrom" />
+    <el-table-column label="薪酬最高要求" align="center" prop="payTo" />
+    <el-table-column label="求职类型" align="center" prop="jobType">
+      <template #default="scope">
+        <dict-tag :type="DICT_TYPE.MENDUNER_JOB_TYPE" :value="scope.row.jobType" />
+      </template>
+    </el-table-column>
+    <el-table-column label="工作城市" align="center" prop="workAreaName" />
+    <el-table-column label="其它感兴趣城市" align="center" prop="interestedAreaNameList">
+      <template #default="scope">
+        {{  scope.row.interestedAreaNameList && scope.row.interestedAreaNameList.length ? scope.row.interestedAreaNameList.join(',') : '' }}
+      </template>
+    </el-table-column>
+    <el-table-column
+      label="创建时间"
+      align="center"
+      prop="createTime"
+      :formatter="dateFormatter"
+      width="180px"
+    />
+  </el-table>
+
+  <Pagination
+    :total="total"
+    v-model:page="queryParams.pageNo"
+    v-model:limit="queryParams.pageSize"
+    @pagination="getList"
+  />
+</template>
+
+<script setup>
+defineOptions({ name: 'PersonJobIntentionList'})
+import { PersonInfoApi } from '@/api/menduner/system/person'
+import { DICT_TYPE } from '@/utils/dict'
+import { dateFormatter } from '@/utils/formatTime'
+
+const props = defineProps({
+  userId: String
+})
+
+const loading = ref(false)
+const tableData = ref([])
+const total = ref(0)
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  userId: props.userId
+})
+
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await PersonInfoApi.getPersonJobIntentionPage(queryParams)
+    tableData.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+getList()
+</script>

+ 242 - 0
src/views/menduner/system/talentMap/details/components/tags.vue

@@ -0,0 +1,242 @@
+<!--  -->
+<template>
+  <div>
+    <div v-if="tagList?.length">
+      <el-tag
+        v-for="item of tagList"
+        :key="item.id"
+        closable
+        size="large"
+        class="m-r-10px m-b-10px"
+      >{{ item.nameCn }}</el-tag>
+    </div>
+  </div>
+</template>
+
+<script setup>
+defineOptions({name: 'Tags'})
+const tagList = ref([
+  {
+    id: "1838837550391787522", 
+    nameCn: "效率", 
+    nameEn: "efficiency", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838837550391787522", 
+    children: [ ]
+  }, 
+  {
+    id: "1838837666309767170", 
+    nameCn: "质量", 
+    nameEn: "quality", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838837666309767170", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853020339752962", 
+    nameCn: "逻辑思维能力", 
+    nameEn: "logical thinking", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853020339752962", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853209356136450", 
+    nameCn: "编码习惯", 
+    nameEn: "Coding habits", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853209356136450", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853291161841666", 
+    nameCn: "高并发", 
+    nameEn: "High concurrency", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853291161841666", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853394492641282", 
+    nameCn: "分布式事务", 
+    nameEn: "distributed transaction", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853394492641282", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853661942435842", 
+    nameCn: "分析问题", 
+    nameEn: "analyze the problem", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853661942435842", 
+    children: [ ]
+  }, 
+  {
+    id: "1838837550391787522", 
+    nameCn: "效率", 
+    nameEn: "efficiency", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838837550391787522", 
+    children: [ ]
+  }, 
+  {
+    id: "1838837666309767170", 
+    nameCn: "质量", 
+    nameEn: "quality", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838837666309767170", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853020339752962", 
+    nameCn: "逻辑思维能力", 
+    nameEn: "logical thinking", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853020339752962", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853209356136450", 
+    nameCn: "编码习惯", 
+    nameEn: "Coding habits", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853209356136450", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853291161841666", 
+    nameCn: "高并发", 
+    nameEn: "High concurrency", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853291161841666", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853394492641282", 
+    nameCn: "分布式事务", 
+    nameEn: "distributed transaction", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853394492641282", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853661942435842", 
+    nameCn: "分析问题", 
+    nameEn: "analyze the problem", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853661942435842", 
+    children: [ ]
+  }, 
+  {
+    id: "1838837550391787522", 
+    nameCn: "效率", 
+    nameEn: "efficiency", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838837550391787522", 
+    children: [ ]
+  }, 
+  {
+    id: "1838837666309767170", 
+    nameCn: "质量", 
+    nameEn: "quality", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838837666309767170", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853020339752962", 
+    nameCn: "逻辑思维能力", 
+    nameEn: "logical thinking", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853020339752962", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853209356136450", 
+    nameCn: "编码习惯", 
+    nameEn: "Coding habits", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853209356136450", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853291161841666", 
+    nameCn: "高并发", 
+    nameEn: "High concurrency", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853291161841666", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853394492641282", 
+    nameCn: "分布式事务", 
+    nameEn: "distributed transaction", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853394492641282", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853661942435842", 
+    nameCn: "分析问题", 
+    nameEn: "analyze the problem", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853661942435842", 
+    children: [ ]
+  }, 
+  {
+    id: "1838853734973657089", 
+    nameCn: "沟通能力", 
+    nameEn: "communication skills", 
+    type: "0", 
+    parentId: "1838826266250338305", 
+    level: 1, 
+    path: "1838826266250338305,1838853734973657089", 
+    children: [ ]
+  }
+])
+</script>
+<style lang="scss" scoped>
+</style>

+ 355 - 0
src/views/menduner/system/talentMap/details/components/tagsRecommend.vue

@@ -0,0 +1,355 @@
+<!--  -->
+<template>
+  <div>
+    <div>
+      <span style="font-size: 14px;">标签分类:</span>
+      <el-select
+        v-model="tagType"
+        placeholder="请选择标签分类"
+        clearable
+        class="!w-180px"
+      >
+        <el-option
+          v-for="tag in tagList"
+          :key="tag.id"
+          :label="tag.name"
+          :value="tag.id"
+        />
+      </el-select>
+    </div>
+    <div>
+      <div v-for="val in tagList" :key="val.id" class="m-t-15px">
+        <span style="font-size: 14px;">{{ val?.nameCn || '--' }}</span>
+        <div v-if="val?.children?.length">
+          <el-tag size="large" class="m-r-10px m-t-10px" v-for="item of val.children" :key="item.id">{{ item.nameCn }}</el-tag>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+defineOptions({name: 'TagsRecommend'})
+
+const tagType = ref(null)
+const tagTypeList = ref([{name: '团队', id: '团队'},{name: '进取精神', id: '进取精神'}, {name: '工作质量', id: '工作质量'}, {name: '承受能力', id: '承受能力'}])
+const tagList = ref([
+  {
+    id: "1838825944446558210", 
+    nameCn: "团队", 
+    nameEn: "team", 
+    type: "0", 
+    parentId: 0, 
+    level: 0, 
+    path: "1838825944446558210", 
+    children: [
+      {
+        id: "1838826793411436545", 
+        nameCn: "合作精神", 
+        nameEn: "Spirit of cooperation", 
+        type: "0", 
+        parentId: "1838825944446558210", 
+        level: 1, 
+        path: "1838825944446558210,1838826793411436545", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853885473746946", 
+        nameCn: "协调能力", 
+        nameEn: "Coordination ability", 
+        type: "0", 
+        parentId: "1838825944446558210", 
+        level: 1, 
+        path: "1838825944446558210,1838853885473746946", 
+        children: [ ]
+      }
+    ]
+  }, 
+  {
+    id: "1838826023743946754", 
+    nameCn: "进取精神", 
+    nameEn: "spirit of enterprising", 
+    type: "0", 
+    parentId: 0, 
+    level: 0, 
+    path: "1838826023743946754", 
+    children: [
+      {
+        id: "1838837082798317569", 
+        nameCn: "细心", 
+        nameEn: "careful", 
+        type: "0", 
+        parentId: "1838826023743946754", 
+        level: 1, 
+        path: "1838826023743946754,1838837082798317569", 
+        children: [ ]
+      }, 
+      {
+        id: "1838837135919054849", 
+        nameCn: "乐观", 
+        nameEn: "optimistic", 
+        type: "0", 
+        parentId: "1838826023743946754", 
+        level: 1, 
+        path: "1838826023743946754,1838837135919054849", 
+        children: [ ]
+      }
+    ]
+  }, 
+  {
+    id: "1838826266250338305", 
+    nameCn: "工作质量", 
+    nameEn: "Work quality", 
+    type: "0", 
+    parentId: 0, 
+    level: 0, 
+    path: "1838826266250338305", 
+    children: [
+      {
+        id: "1838837550391787522", 
+        nameCn: "效率", 
+        nameEn: "efficiency", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838837550391787522", 
+        children: [ ]
+      }, 
+      {
+        id: "1838837666309767170", 
+        nameCn: "质量", 
+        nameEn: "quality", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838837666309767170", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853020339752962", 
+        nameCn: "逻辑思维能力", 
+        nameEn: "logical thinking", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853020339752962", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853209356136450", 
+        nameCn: "编码习惯", 
+        nameEn: "Coding habits", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853209356136450", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853291161841666", 
+        nameCn: "高并发", 
+        nameEn: "High concurrency", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853291161841666", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853394492641282", 
+        nameCn: "分布式事务", 
+        nameEn: "distributed transaction", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853394492641282", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853661942435842", 
+        nameCn: "分析问题", 
+        nameEn: "analyze the problem", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853661942435842", 
+        children: [ ]
+      }, 
+      {
+        id: "1838837550391787522", 
+        nameCn: "效率", 
+        nameEn: "efficiency", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838837550391787522", 
+        children: [ ]
+      }, 
+      {
+        id: "1838837666309767170", 
+        nameCn: "质量", 
+        nameEn: "quality", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838837666309767170", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853020339752962", 
+        nameCn: "逻辑思维能力", 
+        nameEn: "logical thinking", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853020339752962", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853209356136450", 
+        nameCn: "编码习惯", 
+        nameEn: "Coding habits", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853209356136450", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853291161841666", 
+        nameCn: "高并发", 
+        nameEn: "High concurrency", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853291161841666", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853394492641282", 
+        nameCn: "分布式事务", 
+        nameEn: "distributed transaction", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853394492641282", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853661942435842", 
+        nameCn: "分析问题", 
+        nameEn: "analyze the problem", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853661942435842", 
+        children: [ ]
+      }, 
+      {
+        id: "1838837550391787522", 
+        nameCn: "效率", 
+        nameEn: "efficiency", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838837550391787522", 
+        children: [ ]
+      }, 
+      {
+        id: "1838837666309767170", 
+        nameCn: "质量", 
+        nameEn: "quality", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838837666309767170", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853020339752962", 
+        nameCn: "逻辑思维能力", 
+        nameEn: "logical thinking", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853020339752962", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853209356136450", 
+        nameCn: "编码习惯", 
+        nameEn: "Coding habits", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853209356136450", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853291161841666", 
+        nameCn: "高并发", 
+        nameEn: "High concurrency", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853291161841666", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853394492641282", 
+        nameCn: "分布式事务", 
+        nameEn: "distributed transaction", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853394492641282", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853661942435842", 
+        nameCn: "分析问题", 
+        nameEn: "analyze the problem", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853661942435842", 
+        children: [ ]
+      }, 
+      {
+        id: "1838853734973657089", 
+        nameCn: "沟通能力", 
+        nameEn: "communication skills", 
+        type: "0", 
+        parentId: "1838826266250338305", 
+        level: 1, 
+        path: "1838826266250338305,1838853734973657089", 
+        children: [ ]
+      }
+    ]
+  }, 
+  {
+    id: "1838826464175349762", 
+    nameCn: "承受能力", 
+    nameEn: "Affordability", 
+    type: "0", 
+    parentId: 0, 
+    level: 0, 
+    path: "1838826464175349762", 
+    children: [
+      {
+        id: "1838837393176690689", 
+        nameCn: "抗压", 
+        nameEn: "Compression resistance", 
+        type: "0", 
+        parentId: "1838826464175349762", 
+        level: 1, 
+        path: "1838826464175349762,1838837393176690689", 
+        children: [ ]
+      }
+    ]
+  }
+])
+
+</script>
+<style lang="scss" scoped>
+</style>

+ 99 - 13
src/views/menduner/system/talentMap/details/index.vue

@@ -1,21 +1,107 @@
 <template>
-  <div> 123</div>
+  <div>
+    <el-row :gutter="10">
+      <el-col :span="14">
+        <el-card shadow="never">
+          <!-- <template #header>
+            <CardTitle title="人才详情" />
+          </template> -->
+          <el-tabs>
+            <el-tab-pane label="基本信息">
+              <Info :id="id" :user-id="userId" />
+            </el-tab-pane>
+            <el-tab-pane label="教育经历">
+              <Edu :user-id="userId" />
+            </el-tab-pane>
+            <el-tab-pane label="工作经历">
+              <Exp :user-id="userId" />
+            </el-tab-pane>
+            <el-tab-pane label="求职意向">
+              <JobIntention :user-id="userId" />
+            </el-tab-pane>
+            <!-- <el-tab-pane label="面试邀约记录">
+              <InterviewInvite :user-id="userId" />
+            </el-tab-pane> -->
+            <el-tab-pane label="职位投递记录">
+              <DeliveryJob :user-id="userId" />
+            </el-tab-pane>
+            <!-- <el-tab-pane label="职位收藏、企业收藏数">
+              <Collect :user-id="userId" />
+            </el-tab-pane> -->
+            <el-tab-pane label="附件简历">
+              <Attachment :user-id="userId" />
+            </el-tab-pane>
+          </el-tabs>
+        </el-card>
+      </el-col>
+      <el-col :span="10">
+        <div>
+          <el-card shadow="never">
+            <template #header>
+              <!-- <CardTitle title="已有标签" /> -->
+              <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>
+  </div>
 </template>
 
 <script setup>
 defineOptions({ name: 'TalentMapDetail'})
-// import Info from './components/info.vue'
+import { useTagsViewStore } from '@/store/modules/tagsView'
+import { ElMessage } from 'element-plus'
+import Info from './components/info.vue'
+import Edu from './components/edu.vue'
+import Exp from './components/exp.vue'
+import JobIntention from './components/jobIntention.vue'
+// import Collect from './components/collect.vue'
+import Attachment from './components/attachment.vue'
+import DeliveryJob from './components/deliveryJob.vue'
+// import InterviewInvite from './components/interviewInvite.vue'
+import Tags from './components/tags.vue'
+import TagsRecommend from './components/tagsRecommend.vue'
+
+const addNewTag = ref(false)
+const newTagText = ref('')
+const saveTags = () => {
+  addNewTag.value = false
+}
 
 /** 初始化 */
-// const { currentRoute } = useRouter() // 路由
-// const { delView } = useTagsViewStore() // 视图操作
-// const route = useRoute()
-// const { id, userId } = route.query
-// onMounted(() => {
-//   if (!userId) {
-//     ElMessage.warning('参数错误,用户编号不能为空!')
-//     delView(unref(currentRoute))
-//     return
-//   }
-// })
+const { currentRoute } = useRouter() // 路由
+const { delView } = useTagsViewStore() // 视图操作
+const route = useRoute()
+const { id, userId } = route.query
+onMounted(() => {
+  if (!userId) {
+    ElMessage.warning('参数错误,用户编号不能为空!')
+    delView(unref(currentRoute))
+    return
+  }
+})
 </script>