Browse Source

feat: 求职人员查看个人简历

zhangying 11 months ago
parent
commit
478dfb2571

+ 6 - 0
src/main/java/com/hz/employmentsite/vo/jobUserManager/JobUserVo.java

@@ -29,6 +29,8 @@ public class JobUserVo {
 
     private Integer politicsStatusID;
 
+    private String politicsStatusName;
+
     private String birthPlace;
 
     private Date birthDay;
@@ -37,10 +39,14 @@ public class JobUserVo {
 
     private Integer familyNatureID;
 
+    private String familyNatureName;
+
     private Integer cultureRank;
 
     private Integer healthID;
 
+    private String healthName;
+
     private Integer bloodTypeID;
 
     private String height;

+ 21 - 8
src/main/resources/mapping/cquery/JobUserCQuery.xml

@@ -2,16 +2,29 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="com.hz.employmentsite.mapper.cquery.JobUserCQuery">
     <select id="selectJobUserList" resultType="com.hz.employmentsite.vo.jobUserManager.JobUserVo">
-        select  jobuser.* ,gender.name as GenderName,culture.name as CultureName,site.SiteName,jobstatus.name as JobStatusName,keytype.name as KeyTypeName,
-        (select count(*) from pc_recommend recommend where jobuser.JobUserID = recommend.JobuserID and isRead = 1)as RecommendedCount
-        ,case when jobuser.IdentityNumber is not null and jobuser.IdentityNumber <![CDATA[ <> ]]>'' then TIMESTAMPDIFF(YEAR,STR_TO_DATE(SUBSTRING(jobuser.IdentityNumber, 7, 8),'%Y%m%d'),CURRENT_DATE())
-         else null end as age
+        select jobuser.* ,gender.name as GenderName,culture.name as CultureName,site.SiteName,jobstatus.name as
+        JobStatusName,keytype.name as KeyTypeName,sys_politics.name as politicsStatusName,sys_health.name as healthName,
+        sys_family.name as familyNatureName,
+        (select count(*) from pc_recommend recommend where jobuser.JobUserID = recommend.JobuserID and isRead = 1)as
+        RecommendedCount
+        ,case when jobuser.IdentityNumber is not null and jobuser.IdentityNumber <![CDATA[ <> ]]>'' then
+        TIMESTAMPDIFF(YEAR,STR_TO_DATE(SUBSTRING(jobuser.IdentityNumber, 7, 8),'%Y%m%d'),CURRENT_DATE())
+        else null end as age
         from pc_jobuser jobuser
         left join pc_site site on site.SiteID = jobuser.SiteID
-        left join sys_dictionary_item culture on jobuser.CultureRank = culture.value and culture.DictionaryCode='CultureLevel'
-        left join sys_dictionary_item gender  on jobuser.Sex = gender.value and gender.DictionaryCode='Gender'
-        left join sys_dictionary_item jobstatus on jobuser.JobStatusID = jobstatus.value and jobstatus.DictionaryCode='JobStatus'
-        left join sys_dictionary_item keytype on jobuser.KeyPersonTypeID = keytype.value and keytype.DictionaryCode='KeyPersonType'
+        left join sys_dictionary_item culture on jobuser.CultureRank = culture.value and
+        culture.DictionaryCode='CultureLevel'
+        left join sys_dictionary_item gender on jobuser.Sex = gender.value and gender.DictionaryCode='Gender'
+        left join sys_dictionary_item jobstatus on jobuser.JobStatusID = jobstatus.value and
+        jobstatus.DictionaryCode='JobStatus'
+        left join sys_dictionary_item keytype on jobuser.KeyPersonTypeID = keytype.value and
+        keytype.DictionaryCode='KeyPersonType'
+        left join (select * from sys_dictionary_item where DictionaryCode ='PoliticsStatus') sys_politics on
+        jobuser.PoliticsStatusID = sys_politics.Value
+        left join (select * from sys_dictionary_item where DictionaryCode ='Health') sys_health on
+        jobuser.healthID = sys_health.Value
+        left join (select * from sys_dictionary_item where DictionaryCode ='FamilyNature') sys_family on
+        jobuser.familyNatureID = sys_family.Value
         where 1=1
         <if test="jobUserIDList != '' and jobUserIDList != null">
             and jobuser.jobuserID in (${jobUserIDList})

BIN
vue/src/assets/images/jl-avt.png


+ 4 - 2
vue/src/plugins/antd.ts

@@ -19,7 +19,8 @@ import {
   Switch,
   Space, Cascader,
   Tree,
-  Transfer,Image,Progress,List,Avatar,Badge,Spin,Pagination
+  Transfer, Image, Progress, List, Avatar, Badge, Spin, Pagination,
+  Timeline
 } from 'ant-design-vue';
 import type { App } from 'vue';
 //导入组件库
@@ -68,5 +69,6 @@ export function setupAntd(app: App<Element>) {
     .use(Transfer)
     .use(Cascader)
     .use(Image)
-    .use(Tree).use(Progress).use(List).use(Avatar).use(Badge).use(Spin).use(Pagination);
+    .use(Tree).use(Progress).use(List).use(Avatar).use(Badge).use(Spin).use(Pagination)
+    .use(Timeline);
 }

+ 1 - 0
vue/src/router/asyncModules/jobUserManager.ts

@@ -2,6 +2,7 @@ export default {
   'views/jobusermgr/jobseeker/index': () => import('@/views/jobUserManager/jobuser/index.vue'),
   'views/jobusermgr/jobseeker/add': () => import('@/views/jobUserManager/jobuser/edit.vue'),
   'views/jobusermgr/jobseeker/edit': () => import('@/views/jobUserManager/jobuser/edit.vue'),
+  'views/jobusermgr/jobseeker/vitae': () => import('@/views/jobUserManager/jobuser/vitae.vue'),
   'views/jobusermgr/jobhunt/index': () => import('@/views/jobUserManager/jobhunt/index.vue'),
   'views/jobusermgr/jobhunt/add': () => import('@/views/jobUserManager/jobhunt/edit.vue'),
   'views/jobusermgr/jobhunt/edit': () => import('@/views/jobUserManager/jobhunt/edit.vue'),

+ 10 - 5
vue/src/views/jobUserManager/jobuser/index.vue

@@ -123,6 +123,7 @@
         <template #bodyCell="{ column, text, record }">
           <template v-if="column.key === 'operation'">
             <div class="table-operation">
+              <a-button type="link" size="small" functioncode="T01030106" @click='onVitae(record)'>个人简历</a-button>
               <a-button type="link" size="small" functioncode="T01030103" @click='onEdit(record)'>编辑</a-button>
               <a-button type="link" size="small" functioncode="T01030104" @click="onDel(record)">删除</a-button>
             </div>
@@ -134,13 +135,13 @@
 </template>
 
 <script lang="ts">
-import {reactive, ref, computed, defineComponent, createVNode} from 'vue';
-import type {FormInstance, TableColumnsType, TableProps, SelectProps} from 'ant-design-vue';
-import {getList, del} from '@/api/jobUserManager/jobuser';
+import {computed, createVNode, defineComponent, reactive, ref} from 'vue';
+import type {FormInstance, SelectProps, TableColumnsType, TableProps} from 'ant-design-vue';
+import {message, Modal} from "ant-design-vue";
+import {del, getList} from '@/api/jobUserManager/jobuser';
 import {getSysDictionaryList} from '@/api/system/dictionary';
 import {getPaginationTotalTitle} from '@/utils/common';
 import {useTabsViewStore} from "@/store/modules/tabsView";
-import {message, Modal} from "ant-design-vue";
 import {DownOutlined, ExclamationCircleOutlined, UpOutlined} from "@ant-design/icons-vue";
 import BExportExcel from "@/components/basic/excel/exportExcel/exportExcel.vue";
 import BImportExcel from "@/components/basic/excel/importExcel/importExcel.vue";
@@ -193,7 +194,7 @@ export default defineComponent({
       {title: '地址', dataIndex: 'address', key: 'address',align: "center"},
       {title: '就业状态', dataIndex: 'jobStatusName', key: 'jobStatusName',align: "center"},
       {title: '重点人员类别', dataIndex: 'keyTypeName', key: 'keyTypeName',align: "center"},
-      {title: '操作', key: 'operation', width: 100, align: 'center'},
+      {title: '操作', key: 'operation', width: 170, align: 'center'},
     ];
     const pagination = computed(() => ({
       total: formState.total,
@@ -293,6 +294,9 @@ export default defineComponent({
     const onEdit = (item: any) => {
       tabsViewStore.addTabByPath('/jobusermgr/jobseeker/edit', {id: item.jobUserID});
     };
+    const onVitae = (item: any) => {
+      tabsViewStore.addTabByPath('/jobusermgr/jobseeker/vitae', {id: item.jobUserID});
+    };
 
     const onDel = (item: any) => {
       if (item) {
@@ -347,6 +351,7 @@ export default defineComponent({
       getEducationList,
       getEmphasisTypeList,
       calculateAge,
+      onVitae,
       expand
     };
   },

+ 276 - 0
vue/src/views/jobUserManager/jobuser/vitae.vue

@@ -0,0 +1,276 @@
+<template>
+  <div class="card-search">
+    <div class="jl-content">
+      <!-- 头像等信息 -->
+      <div class="avt-content">
+        <!--头像 -->
+        <div class="avt-image">
+          <a-avatar :size="72" :src="avtImg"></a-avatar>
+        </div>
+        <!-- 姓名 -->
+        <h1>{{ jobUserInfo.name }}</h1>
+        <!-- 性别,年龄,民族 -->
+        <div class="age-info">
+          <span>
+            <man-outlined v-if="jobUserInfo.genderName === '男'"/>
+            <woman-outlined v-if="jobUserInfo.genderName === '女'"/>
+            {{ jobUserInfo.genderName }}
+          </span>
+          <span>
+            {{ jobUserInfo.age }}岁
+          </span>
+          <span>
+            {{ jobUserInfo.nation }}
+          </span>
+        </div>
+        <!-- 政治面貌,学历,手机 -->
+        <div class="politics-info">
+          <span class="label-span">
+            政治面貌:
+          </span>
+          <span>
+            {{ jobUserInfo.politicsStatusName }}
+          </span>
+          <span class="label-span">
+            学历:
+          </span>
+          <span>
+            {{ jobUserInfo.cultureName }}
+          </span>
+          <span class="label-span">
+            手机:
+          </span>
+          <span>
+            {{ jobUserInfo.userMobile }}
+          </span>
+        </div>
+      </div>
+      <!-- 基本信息与学历,工作经历 -->
+      <div class="info-content">
+        <a-divider orientation="left">基本信息</a-divider>
+        <a-descriptions :column="2" bordered style="margin-left: 25px;">
+          <a-descriptions-item label="出生地">{{ jobUserInfo.birthPlace }}</a-descriptions-item>
+          <a-descriptions-item label="身份证号">{{ jobUserInfo.identityNumber }}</a-descriptions-item>
+          <a-descriptions-item label="重点人员类别">{{ jobUserInfo.keyTypeName }}</a-descriptions-item>
+          <a-descriptions-item label="健康状况">{{ jobUserInfo.healthName }}</a-descriptions-item>
+          <a-descriptions-item label="就业状态">{{ jobUserInfo.jobStatusName }}</a-descriptions-item>
+          <a-descriptions-item label="户口性质">{{ jobUserInfo.familyNatureName }}</a-descriptions-item>
+          <a-descriptions-item :span="2" label="住址">{{ jobUserInfo.familyAddress }}</a-descriptions-item>
+          <a-descriptions-item :span="2" label="兴趣爱好">{{ jobUserInfo.hobby }}</a-descriptions-item>
+          <a-descriptions-item :span="2" label="专业技术特长">{{ jobUserInfo.personalSkills }}</a-descriptions-item>
+        </a-descriptions>
+        <a-divider orientation="left">教育经历</a-divider>
+        <a-table :columns="educationColumns" :data-source="educationData" :pagination="false" bordered
+                 style="margin-left: 11px;">
+          <template #bodyCell="{ column, index, record}">
+            <template v-if="column.key === 'schoolTime'">
+              <div>
+                {{
+                  dayjs(record.schoolTime).format('YYYY-MM-DD')
+                }}
+              </div>
+            </template>
+            <template v-if="column.key === 'overTime'">
+              <div>
+                {{
+                  dayjs(record.overTime).format('YYYY-MM-DD')
+                }}
+              </div>
+            </template>
+          </template>
+        </a-table>
+        <a-divider orientation="left">工作经历</a-divider>
+        <a-timeline style="margin-left: 25px;">
+          <a-timeline-item v-for="(item, key) in experienceData" :key="key" position="left">
+            <p>{{ dayjs(item.startTime).format('YYYY-MM-DD') }}至{{ dayjs(item.endTime).format('YYYY-MM-DD') }}</p>
+            <h1>{{ item.workAddress }}</h1>
+            <h1>{{ item.duties }}</h1>
+          </a-timeline-item>
+        </a-timeline>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import {onMounted, reactive, ref} from "vue";
+import {getDataById, getEducationList, getExperienceList} from "@/api/jobUserManager/jobuser";
+import avtImg from "@/assets/images/jl-avt.png"
+import {ManOutlined, WomanOutlined} from '@ant-design/icons-vue';
+import type {TableColumnsType} from "ant-design-vue";
+import dayjs from "dayjs";
+
+// 求职人员信息
+const jobUserInfo = reactive({
+  name: "",
+  genderName: "",
+  age: null,
+  nation: "",
+  politicsStatusName: "",
+  cultureName: "",
+  userMobile: "",
+  birthPlace: "",
+  identityNumber: "",
+  keyTypeName: "",
+  healthName: "",
+  jobStatusName: "",
+  familyNatureName: "",
+  familyAddress: "",
+  hobby: "",
+  personalSkills: ""
+})
+// 受教育经历
+const educationData = ref<Array<any>>([]);
+// 受教育经历表格定义
+const educationColumns: TableColumnsType = [
+  {
+    title: '序号',
+    align: "center",
+    key: 'educationID',
+    width: 120,
+    customRender: item => `${searchParams.pageSize * (searchParams.pageIndex - 1) + item.index + 1}`
+  },
+  {
+    title: '学校名',
+    dataIndex: 'schoolName',
+    key: 'schoolName',
+    align: "center",
+    width: 120
+  },
+  {
+    title: '文化程度',
+    dataIndex: 'cultureRank',
+    key: 'cultureRank',
+    align: "center",
+    width: 120
+  },
+  {
+    title: '就读时间',
+    dataIndex: 'schoolTime',
+    key: 'schoolTime',
+    align: "center",
+    width: 120
+  },
+  {
+    title: '毕业时间',
+    dataIndex: 'overTime',
+    key: 'overTime',
+    align: "center",
+    width: 120
+  },
+  {
+    title: '专业',
+    dataIndex: 'major',
+    key: 'major',
+    align: "center",
+    width: 120
+  },
+];
+const searchParams = reactive({
+  pageIndex: 1,
+  pageSize: 99
+});
+// 工作经验数据
+const experienceData = ref<Array<any>>([]);
+
+
+// 加载求职人员数据
+const loadData = (id: any) => {
+  getDataById(id).then(data => {
+    Object.keys(jobUserInfo).forEach(key => {
+      jobUserInfo[key] = data[key];
+    })
+  });
+};
+
+// 加载教育经历
+const loadEducation = (id: any) => {
+  getEducationList(id).then(data => {
+    if (data) {
+      educationData.value = data;
+    }
+  });
+}
+
+// 加载工作经历
+const loadExperienceData = (id: any) => {
+  getExperienceList(id).then(data => {
+    if (data) {
+      data.sort((a, b) => {
+        // 将 startTime 字段转换为日期对象进行比较
+        const startTimeA = new Date(a.startTime);
+        const startTimeB = new Date(b.startTime);
+
+        return startTimeB - startTimeA;
+      })
+      experienceData.value = data;
+    }
+  })
+}
+
+// 页面初始化
+onMounted(() => {
+  const id = history.state.params?.id;
+  loadData(id);
+  loadEducation(id);
+  loadExperienceData(id)
+})
+</script>
+
+<style lang="less" scoped>
+.card-search {
+
+  .jl-content {
+    min-height: calc(100vh - 240px);
+    width: 100%;
+    display: flex;
+
+    .avt-content {
+      width: 20%;
+      background-color: #e7e7e7;
+      padding: 10px;
+
+      .avt-image {
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: center;
+      }
+
+      .age-info {
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+        margin-top: 15px;
+        padding: 0 20%;
+      }
+
+      .politics-info {
+        margin-top: 25px;
+        display: grid;
+        row-gap: 22px;
+        grid-template-columns: repeat(2, minmax(0, 1fr));
+
+        .label-span {
+          text-align: right;
+        }
+      }
+
+      h1 {
+        margin-top: 1rem;
+        text-align: center;
+        font-size: 20px;
+        font-weight: 700;
+      }
+
+    }
+
+    .info-content {
+      width: 80%;
+      height: 100%;
+      margin-left: 10px;
+    }
+  }
+}
+
+
+</style>