| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630 | <template>  <layout-page>    <!-- 基本信息 -->    <view class="progress-box">      <view>简历完成度</view>      <progress        :percent="Number.isInteger(completeNum/7*100) ? (completeNum/7*100) : (completeNum/7*100).toFixed(2)"        show-info        border-radius="50"        activeColor="#00897B"        stroke-width="8"      />    </view>    <!-- <view class="topTip">      使用简历附件生成在线简历:      <text class="resumeAnalysisBtn" @tap="handleToResumeAnalysis">立即生成</text>    </view> -->    <view class="baseInfo borderLine" @tap="handleTo('baseInfoEdit')">      <view>        <view class="baseInfo-name">          <text class="name title">{{ baseInfo.name }}</text>          <uni-icons            type="icon-Edit"            color="#333"            custom-prefix="iconfont"            size="20"          ></uni-icons>        </view>        <view class="baseInfo-desc">{{ baseInfo.jobStatusText }}</view>        <view class="baseInfo-desc">{{ baseInfo.expTypeText ? baseInfo.expTypeText + ' - ' : '' }}{{ baseInfo.age ? baseInfo.age + '岁' : '' }}{{ baseInfo.eduTypeText ? ' - ' + baseInfo.eduTypeText : '' }}</view>        <view class="baseInfo-phone">          <uni-icons            type="icon-Phone"            color="#999"            custom-prefix="iconfont"            size="14"          ></uni-icons>          <text class="number">{{ baseInfo.phone }}</text>        </view>      </view>      <view class="head">        <image          :src="getUserAvatar(baseInfo?.avatar, baseInfo?.sex)"          mode="scaleToFill"        />      </view>    </view>    <!-- 个人画像 -->    <view class="characteristic borderLine">      <view class="titleBox">        <text class="title">个人画像</text>        <uni-icons          type="icon-Edit"          color="#666"          custom-prefix="iconfont"          size="18"          @tap="handleTo('portrait')"        ></uni-icons>      </view>      <view class="tags">        <view          v-for="tag in baseInfo.tagList"          :key="tag"          class="tag"        >          {{ tag }}        </view>      </view>    </view>    <!-- 个人优势 -->    <view class="advantage borderLine">      <view class="titleBox">        <text class="title">个人优势</text>        <uni-icons          type="icon-Edit"          color="#666"          custom-prefix="iconfont"          size="18"          @tap="handleTo('advantage')"        ></uni-icons>      </view>      <view class="ellipsis-2 text px-20">{{ baseInfo.advantage ? baseInfo.advantage : '请填写您的个人优势...' }}</view>    </view>    <!-- 求职意向 -->    <view class="intention borderLine">      <view class="titleBox">        <text class="title">求职意向</text>        <uni-icons          type="icon-add"          color="#666"          custom-prefix="iconfont"          size="18"          @tap="handleTo('jobIntention')"        ></uni-icons>      </view>      <view class="content">        <view class="text" v-if="!intention.length">请填写您的求职意向...</view>        <uni-list :border="false">          <uni-list-item            v-for="int in intention"            :key="int.id"            :border="false"            :clickable="true"            showArrow            @click="handleTo('jobIntention', int.id)"          >            <template v-slot:body>              <view class="item">                <view class="item-title">{{ int.jobTypeName}}</view>                <view>                  <text class="mr-20">{{ int.position}}</text>                  <text>{{ int.payFrom }} {{ int.payFrom  && int.payTo ? '-' : ''}} {{ int.payTo}}</text>                </view>                <view>{{ int.interestedArea && int.interestedArea.length ? int.workArea + ',' + int.interestedArea.map(e => e.name).join(',') : int.workArea }}</view>                <view class="item-tags">                  <view v-for="industry in int.industry" :key="industry.id" class="tag">{{ industry.nameCn }}</view>                </view>              </view>            </template>          </uni-list-item>        </uni-list>      </view>    </view>    <!-- 教育经历 -->    <view class="educationExp borderLine">      <view class="titleBox">        <text class="title">教育经历</text>        <uni-icons          type="icon-add"          color="#666"          custom-prefix="iconfont"          size="18"          @tap="handleTo('educationExp')"        ></uni-icons>      </view>      <view class="content">        <view class="text" v-if="!educationExp.length">请填写您的教育经历...</view>        <uni-list :border="false">          <uni-list-item            v-for="education in educationExp"            :key="education.id"            showArrow            :border="false"            :clickable="true"            :title="education.schoolName"            :note="`${education.major} ${education.educationTypeText}`"            :rightText="education.time"            @click="handleTo('educationExp', education.id)"          />        </uni-list>      </view>    </view>    <!-- 工作经历 -->    <view class="workExp borderLine">      <view class="titleBox">        <text class="title">工作经历</text>        <uni-icons          type="icon-add"          color="#666"          custom-prefix="iconfont"          size="18"          @tap="handleTo('workExperience')"        ></uni-icons>      </view>      <view class="content">        <view          v-for="work in workExp"          :key="work.id"          class="content-item"          @tap="handleTo('workExperience', work.id)"        >          <view class="content-title">            <view class="name">{{ work.enterpriseName }}</view>            <view class="time">              {{ work.time }}              <uni-icons                class="icon"                type="right"                color="#aaa"                size="16"              />            </view>          </view>          <view class="content-subTitle">{{ work.positionName }}</view>          <view class="content-main ellipsis-2">内容:{{ work.content }}</view>        </view>      </view>    </view>    <!-- 培训经历 -->    <view class="workExp trainExp borderLine">      <view class="titleBox">        <text class="title">培训经历</text>        <uni-icons          type="icon-add"          color="#666"          custom-prefix="iconfont"          size="18"          @tap.stop="handleTo('trainingExperience')"        ></uni-icons>      </view>      <view class="content">        <view          v-for="train in trainExp"          :key="train.id"          class="content-item"          @tap.stop="handleTo('trainingExperience', train.id)"        >          <view class="content-title">            <view class="name">{{ train.orgName }}</view>            <view class="time">              {{ train.time }}              <uni-icons                class="icon"                type="right"                color="#aaa"                size="16"              />            </view>          </view>          <view class="content-subTitle">课程:{{ train.course }}</view>          <view class="content-main ellipsis-2">描述:{{ train.content }}</view>        </view>      </view>    </view>    <!-- 职业技能 -->    <view class="characteristic">      <view class="titleBox">        <text class="title">职业技能</text>        <uni-icons          type="icon-Edit"          color="#666"          custom-prefix="iconfont"          size="18"          @tap.stop="handleTo('vocationalSkills')"        ></uni-icons>      </view>      <view class="tags">        <view          v-for="skill in skillExp"          :key="skill.title"          class="tag"        >          {{ skill.title }}        </view>      </view>    </view>  </layout-page></template><script setup>import { ref } from 'vue'import { getAgeByBirthdayTimestamp, timesTampChange } from '@/utils/date'import {  getResumeJobInterested,  getResumeEduExp,  getResumeWorkExp,  getResumeTrainExp,  getResumePersonSkill} from '@/api/resume'import { getText } from '@/utils/getText'import { getDict } from '@/hooks/useDictionaries'import { userStore } from '@/store/user'import { dealJobData } from './dict'import layoutPage from '@/layout'import { onShow } from '@dcloudio/uni-app'import { getUserAvatar } from '@/utils/avatar'const useUserStore = userStore()const baseInfo = ref({})const intention = ref([])const educationExp = ref([])const workExp = ref([])const trainExp = ref([])const skillExp = ref([])// 简历完成度const completeNum = ref(0)function handleTo (str, id) {  uni.navigateTo({ url: id ? `/pagesA/resumeOnline/${str}?id=${id}` : `/pagesA/resumeOnline/${str}` })}function handleToResumeAnalysis () {  uni.navigateTo({ url: '/pagesA/resumeAnalysis/index' })}// 获取基础信息function getBaseInfo () {  const { name, phone, ...obj } = useUserStore.baseInfo  baseInfo.value = {    ...obj,    name: name ? name : useUserStore.userInfo.phone,    phone: phone ? phone : useUserStore.userInfo.phone,    age: obj.birthday ? getAgeByBirthdayTimestamp(obj.birthday) : 0  }  if (useUserStore.userInfo && Object.keys(useUserStore.userInfo).length) completeNum.value++  if (baseInfo.value?.advantage ) completeNum.value++}// 获取求职意向async function getJobInterested () {  const { data } = await getResumeJobInterested()  if (!data || !data.length) {    return  }  completeNum.value++ // 完成度展示  intention.value = dealJobData(data)}// 获取教育经历async function getEduExp () {  const { data: dict } = await getDict('menduner_education_type')  if (dict.code !== 0) {    return  }  const { data } = await getResumeEduExp()  if (!data || !data.length) {    return  }  completeNum.value++ // 完成度展示  educationExp.value = data.map(e => {    const item = dict.data.find(_e => _e.value === e.educationType)    return {      ...e,      educationTypeText: item?.label ?? '',      time: `${timesTampChange(e.startTime ,'Y-M')}-${timesTampChange(e.endTime ,'Y-M')} `    }  })}// 获取工作经验async function getWorkExp () {  const { data } = await getResumeWorkExp()  if (!data || !data.length) {    return  }  completeNum.value++ // 完成度展示  workExp.value = data.map(e => {    return {      ...e,      time: `${timesTampChange(e.startTime ,'Y-M')}-${e.endTime ? timesTampChange(e.endTime ,'Y-M') : '至今'} `    }  })}// 培训经历async function getTrainExpData () {  const { data } = await getResumeTrainExp()  if (!data || !data.length) {    return  }  completeNum.value++ // 完成度展示  trainExp.value = data.map(e => {    return {      ...e,      time: `${timesTampChange(e.startTime ,'Y-M')}-${e.endTime ? timesTampChange(e.endTime ,'Y-M') : '至今'} `    }  })}// 职业技能async function getSkillExpData () {  const { data: _skillList} = await getDict('skillList', {}, 'skillList')  const skillList = _skillList?.data  if (!skillList || !skillList.length) {    return  }  completeNum.value++ // 完成度展示  const { data: _skillLevelArr } = await getDict('menduner_skill_level')  const skillLevelArr = _skillLevelArr?.data  if (!skillLevelArr || !skillLevelArr.length) {    return  }  const { data } = await getResumePersonSkill()  if (!data || !data.length) {    return  }  skillExp.value = data.map(e => {    return {      ...e,      title: `${getText(e.skillId, skillList, 'nameCn', 'id')} / ${getText(e.level, skillLevelArr)}`    }  })}onShow(() => {  completeNum.value = 0  // 获取基础信息  getBaseInfo()  // 获取求职意向  getJobInterested()  // 获取教育经历  getEduExp()  // 获取工作经验  getWorkExp()  // 培训经历  getTrainExpData()  // 职业技能  getSkillExpData()})</script><style lang="scss" scoped>$px: 30rpx;.borderLine {  border-bottom: 2rpx solid #f5f5f5;}.progress-box {  padding: 20rpx $px;}.title {  font-size: 40rpx;  font-weight: 600;}.flex-1 {  flex: 1;}.soloHeight {  height: 80rpx;  line-height: 80rpx;}.px-20 {  padding-left: 20rpx;  padding-right: 20rpx;  box-sizing: border-box;}.mr-20 {  margin-right: 20rpx;}.ellipsis-2 {  overflow: hidden;  display: -webkit-box;  text-overflow: ellipsis; //属性规定当文本溢出包含元素时发生的事情  text-overflow: clip|ellipsis|string; (修剪/省略号/指定字符串)  -webkit-line-clamp: 2;  -webkit-box-orient: vertical; //属性规定框的子元素应该被水平或垂直排列}.titleBox {  margin-bottom: 10rpx;  display: flex;  justify-content: space-between;}.text {  font-size: 28rpx;  color: #666;}.baseInfo {  padding: 20rpx $px;  display: flex;  justify-content: space-between;  align-items: center;  &-name {    margin-bottom: 10rpx;    .name {      margin-right: 10rpx;    }  }  &-desc {    font-size: 28rpx;    color: #666;    margin-bottom: 10rpx;  }  &-phone {    font-size: 28rpx;    color: #666;    .number {      margin-left: 10rpx;    }  }  .head {    image {      width: 150rpx;      height: 150rpx;      border: 2rpx solid #ccc;      border-radius: 50%;    }  }}.advantage {  padding: $px;}.characteristic {  padding: $px;  .tags {    padding-top: $px;    display: flex;    flex-wrap: wrap;    .tag {      margin: 0 10rpx 10rpx 0;      border: 2rpx solid #008978;      color: #008978;      white-space: nowrap;      padding: 4rpx 10rpx;      border-radius: 10rpx;      font-size: 24rpx;    }  }}.intention,.educationExp,.workExp,.projectExp {  padding: $px;}.workExp {  .content {    &-item {      padding: $px 20rpx;    }    &-title {      display: flex;      justify-content: space-between;      .name {        // font-weight: 600;        font-size: 30rpx;        color: #333;      }      .time {        color: #999;        font-size: 24rpx;        display: flex;        align-items: center;        .icon {          margin-left: 20rpx;        }      }    }    &-subTitle {      font-size: 24rpx;      margin-top: 6rpx;      color: #999;    }    &-main {      margin-top: 20rpx;      font-size: 24rpx;      color: #999;    }  }}.intention {  .content {    .item {      font-size: 28rpx;      color: #666;      &-title {        color: #000;        font-weight: 600;      }      &-tags {        display: flex;        .tag {          border: 2rpx solid #008978;          color: #008978;          padding: 4rpx 16rpx;          font-size: 24rpx;          margin: 10rpx 10rpx 0 0;          border-radius: 10rpx;        }      }    }  }}.popup {  padding: $px;  padding-bottom: 100rpx;  &-title {    width: 100%;    display: flex;    justify-content: space-between;    margin-bottom: $px;    font-size: 24rpx;    .title {      font-size: 36rpx;    }  }  &-content {    .box {      display: flex;      justify-content: space-between;      border-bottom: 2rpx solid #eee;      padding: $px 0;      font-size: 30rpx;      font-weight: 500;      color: #000;      &:last-of-type {        border-bottom: none;      }      &.active {        color: #008978;        font-weight: 600;      }    }  }}.popupBox {  height: 90vh;  .handleBtnBox {    // padding: 0 $px;    display: flex;    justify-content: space-between;    view {      padding: calc($px / 2);      margin-right: calc($px / 2);    }    .save {      color: #008978;    }    .close {      color: gray;    }  }  .popupContent {    padding: $px;    padding-bottom: 100rpx;  }}.topTip {  background-color: #f7f8fa;  color: #2f3640;  padding: 12px 20px;  margin: 20px 20rpx;  font-size: 14px;}.resumeAnalysisBtn {  text-decoration: underline;  color: #008978;}</style>
 |