Xiao_123 7 mesi fa
parent
commit
96870f8ef3
33 ha cambiato i file con 369 aggiunte e 282 eliminazioni
  1. 1 1
      src/components/Enterprise/hotPromoted.vue
  2. 5 1
      src/components/personalRecharge/index.vue
  3. 1 1
      src/layout/company/navBar.vue
  4. 0 1
      src/layout/enterprise.vue
  5. 2 7
      src/layout/personal/navBar.vue
  6. 1 1
      src/layout/personal/slider.vue
  7. 0 19
      src/router/modules/components/recruit/enterprise.js
  8. 98 32
      src/router/modules/components/recruit/personCenter.js
  9. 0 65
      src/router/modules/components/recruit/personal.js
  10. 5 1
      src/views/mall/purchasePackage/index.vue
  11. 0 1
      src/views/publicRecruitment/components/table.vue
  12. 12 3
      src/views/publicRecruitment/index.vue
  13. 1 1
      src/views/publicRecruitment/myRecommendation.vue
  14. 0 13
      src/views/recruit/enterprise/purchasePackage/index.vue
  15. 14 0
      src/views/recruit/personal/PersonalCenter/bountyRewards/index.vue
  16. 9 4
      src/views/recruit/personal/PersonalCenter/index.vue
  17. 2 2
      src/views/recruit/personal/PersonalCenter/memberBenefits/membershipPackage/index.vue
  18. 0 0
      src/views/recruit/personal/PersonalCenter/memberBenefits/taskCenter/components/daily.vue
  19. 0 0
      src/views/recruit/personal/PersonalCenter/memberBenefits/taskCenter/components/signIn.vue
  20. 0 0
      src/views/recruit/personal/PersonalCenter/memberBenefits/taskCenter/components/suggest.vue
  21. 1 2
      src/views/recruit/personal/PersonalCenter/memberBenefits/taskCenter/index.vue
  22. 100 0
      src/views/recruit/personal/PersonalCenter/resume/attachment/index.vue
  23. 1 1
      src/views/recruit/personal/PersonalCenter/resume/online/components/basicInfo.vue
  24. 0 0
      src/views/recruit/personal/PersonalCenter/resume/online/components/dict.js
  25. 0 0
      src/views/recruit/personal/PersonalCenter/resume/online/components/educationExp.vue
  26. 0 0
      src/views/recruit/personal/PersonalCenter/resume/online/components/jobIntention.vue
  27. 0 0
      src/views/recruit/personal/PersonalCenter/resume/online/components/projectExperience.vue
  28. 0 0
      src/views/recruit/personal/PersonalCenter/resume/online/components/selfEvaluation.vue
  29. 0 0
      src/views/recruit/personal/PersonalCenter/resume/online/components/trainingExperience.vue
  30. 0 0
      src/views/recruit/personal/PersonalCenter/resume/online/components/vocationalSkills.vue
  31. 0 0
      src/views/recruit/personal/PersonalCenter/resume/online/components/workExperience.vue
  32. 116 0
      src/views/recruit/personal/PersonalCenter/resume/online/index.vue
  33. 0 126
      src/views/recruit/personal/remuse/index.vue

+ 1 - 1
src/components/Enterprise/hotPromoted.vue

@@ -18,7 +18,7 @@
             </p>
           </div>
         </div>
-        <div class="px-5 py-1 ellipsis" :style="{'height': '33px', 'border-bottom': item.enterprise.welfareList && item.enterprise.welfareList.length ? '1px solid #EBEBEB;' : 'none'}">
+        <div class="px-5 py-1 ellipsis" :style="{'height': '33px', 'border-bottom': item.enterprise.welfareList && item.enterprise.welfareList.length ? '1px solid #EBEBEB' : 'none'}">
           <span class="welfareTag mr-5" v-for="(k, i) in item.enterprise.welfareList" :key="i">{{ k }}</span>
         </div>
         <!-- 职位列表 -->

+ 5 - 1
src/components/personalRecharge/index.vue

@@ -1,5 +1,9 @@
 <template>
   <div class="resume-box" :class="{'fullShow': fullShow}">
+    <div class="color-primary mb-5 text-decoration-underline cursor-pointer" @click="router.go(-1)">
+      <v-icon>mdi-chevron-triple-left</v-icon>
+      回到我的钱包
+    </div>
     <div class="resume-header" v-if="showTitle">
       <div class="resume-title">
         余额充值
@@ -68,7 +72,7 @@ defineProps({
   }
 })
 
-import { useRoute } from 'vue-router'; const route = useRoute()
+import { useRoute, useRouter } from 'vue-router'; const route = useRoute(); const router = useRouter()
 const fullShow = ref(route.path === '/personalRecharge' ? true : false)
 
 const current = ref(0)

+ 1 - 1
src/layout/company/navBar.vue

@@ -130,7 +130,7 @@ const enterpriseList = ref([])
 
 const menuList = ref([
   // { title: t('enterprise.account.myAccount'), icon: 'mdi-account', change: () => router.push({ path: '/recruit/enterprise/memberCenter/myAccount' }) },
-  // { title: t('vipPackage.purchasePackage'), icon: 'mdi-gift-outline', change: () => window.open('/recruit/enterprise/purchasePackage') },
+  // { title: t('vipPackage.purchasePackage'), icon: 'mdi-gift-outline', change: () => window.open('/recruit/enterprise/memberCenter/myMembers') },
   // { title: t('enterprise.personalInformationSettings'), icon: 'mdi-account-cog', change: () => router.push({ path: '/recruit/enterprise/informationSettings' }) },
   // { title: t('setting.switchToOtherCompany'), icon: 'mdi-home-switch', hidden: enterpriseList.value?.length < 2, change: () => handleSwitchToAnotherEnterprise },
   // { title: t('enterprise.registeringNewEnterprise'), icon: 'mdi-home-plus-outline', change: () => handleRegisteringNewEnterprise },

+ 0 - 1
src/layout/enterprise.vue

@@ -44,7 +44,6 @@ const key = computed(() => {
 
 const whiteList = [
   '/recruit/enterprise/resumeManagement/talentPool/details/details',
-  '/recruit/enterprise/purchasePackage',
   '/recruit/enterprise/systemManagement/groupAccount/invite/0',
   '/recruit/enterprise/systemManagement/groupAccount/invite/1'
 ]

+ 2 - 7
src/layout/personal/navBar.vue

@@ -243,18 +243,13 @@ const handleToPersonalCenter = () => {
 // 退出登录
 const handleLogout = async () => {
   await userStore.userLogout(1)
+  showBall.value = false
   if (route.path === '/recruitHome') location.reload()
   else router.push({ path: '/recruitHome' })
 }
 
 const items = ref([
-  // { title: t('vipPackage.purchasePackage'), icon: 'mdi-gift-outline', change: () => router.push({ path: '/recruit/personal/purchasePackage' }) },
-  // { title: t('resume.onlineResume'), icon: 'mdi-list-box-outline', change: () => router.push({ path: '/recruit/personal/resume' }) },
-  // { title: t('setting.accountSettings'), icon: 'mdi-cog-outline', change: () => router.push({ path: '/recruit/personal/accountSettings/accountBinding' }) },
-  // { title: t('setting.switchToRecruit'), icon: 'mdi-swap-horizontal', change: handleSwitch },
-  { title: t('publicRecruitment.bountyRewards'), icon: 'mdi-google-circles-extended', change: () => router.push({ path: '/publicRecruitment' }) },
-  // { title: t('points.wallet'), icon: ' mdi-database-outline', change: () => router.push({ path: '/recruit/personal/myWallet' }) },
-  // { title: t('taskCenter.taskCenter'), icon: 'mdi-calendar-check-outline', change: () => router.push({ path: '/recruit/personal/TaskCenter' }) },
+  { title: t('setting.accountSettings'), icon: 'mdi-cog-outline', change: () => router.push({ path: '/recruit/personal/personalCenter/accountSettings' }) },
   { title: t('setting.logOut'), icon: 'mdi-logout', change: handleLogout }
 ])
 

+ 1 - 1
src/layout/personal/slider.vue

@@ -24,7 +24,7 @@ const list = [
   { mdi: 'mdi-arrow-up-bold', tips: '返回顶部' },
   { mdi: 'mdi-qrcode', tips: '微信公众号', showImg: 'https://minio.citupro.com/dev/static/mendunerCode.jpg' },
   { mdi: 'mdi-bell-outline', tips: '消息', path: '/recruit/personal/message' },
-  { mdi: 'mdi-list-box-outline', tips: '在线简历', path: '/recruit/personal/resume' }
+  { mdi: 'mdi-list-box-outline', tips: '在线简历', path: '/recruit/personal/personalCenter/resume/online' }
 ]
 
 const handleClick = (item, index) => {

+ 0 - 19
src/router/modules/components/recruit/enterprise.js

@@ -339,25 +339,6 @@ const enterprise = [
         component: () => import('@/views/recruit/enterprise/memberCenter/invoice/header.vue')
       }
     ]
-  },
-  {
-    path: '/recruit/enterprise/purchasePackage',
-    component: Layout,
-    name: 'enterprisePurchasePackage',
-    show: true,
-    meta: {
-      title: '购买套餐',
-    },
-    children: [
-      {
-        path: '/recruit/enterprise/purchasePackage',
-        component: () => import('@/views/recruit/enterprise/purchasePackage/index'),
-        meta: {
-          title: '购买套餐',
-          hideSide: true
-        },
-      }
-    ]
   }
 ]
 export default enterprise

+ 98 - 32
src/router/modules/components/recruit/personCenter.js

@@ -15,6 +15,7 @@ const personCenter = [
         redirect: '/recruit/personal/personalCenter/jobFeedback',
         component: () => import('@/views/recruit/personal/PersonalCenter/index'),
         children: [
+          // 求职反馈
           {
             path: '/recruit/personal/personalCenter/jobFeedback',
             name: 'Job Feedback',
@@ -25,26 +26,87 @@ const personCenter = [
               icon: 'mdi-account-sync-outline'
             }
           },
+          // 简历管理
+          {
+            path: '/recruit/personal/personalCenter/resume',
+            redirect: '/recruit/personal/personalCenter/resume/online',
+            name: 'Resume Management',
+            meta: {
+              title: '简历管理',
+              enName: 'Resume Management',
+              icon: 'mdi-list-box-outline'
+            },
+            children: [
+              {
+                path: '/recruit/personal/personalCenter/resume/online',
+                component: () => import('@/views/recruit/personal/PersonalCenter/resume/online/index.vue'),
+                meta: {
+                  enName: 'Online Resume',
+                  title: '在线简历'
+                }
+              },
+              {
+                path: '/recruit/personal/personalCenter/resume/attachment',
+                component: () => import('@/views/recruit/personal/PersonalCenter/resume/attachment/index.vue'),
+                meta: {
+                  enName: 'Attachment Resume',
+                  title: '附件简历'
+                }
+              }
+            ]
+          },
+          // 赏金奖励
+          {
+            path: '/recruit/personal/personalCenter/bountyRewards',
+            name: 'bountyRewards',
+            component: () => import('@/views/recruit/personal/PersonalCenter/bountyRewards/index.vue'),
+            meta: {
+              title: '赏金奖励',
+              enName: 'Bounty Rewards',
+              icon: 'mdi-octagram-outline'
+            }
+          },
+          // 我的钱包
           {
             path: '/recruit/personal/personalCenter/wallet',
             name: 'My Wallet',
-            component: () => import('@/views/recruit/personal/PersonalCenter/wallet/index.vue'),
             meta: {
               title: '我的钱包',
               enName: 'My Wallet',
               icon: 'mdi-wallet-outline'
-            }
+            },
+            component: () => import('@/views/recruit/personal/PersonalCenter/wallet/index.vue'),
           },
+          // 会员福利
           {
-            path: '/recruit/personal/personalCenter/taskCenter',
-            name: 'Task Center',
-            component: () => import('@/views/recruit/personal/PersonalCenter/taskCenter/index.vue'),
+            path: '/recruit/personal/personalCenter/memberBenefits',
+            redirect: '/recruit/personal/personalCenter/memberBenefits/taskCenter',
+            name: 'Member Benefits',
             meta: {
-              title: '任务中心',
-              enName: 'Task Center',
-              icon: 'mdi-movie-star-outline'
-            }
+              title: '会员福利',
+              enName: 'Member Benefits',
+              icon: 'mdi-gamepad-circle-outline'
+            },
+            children: [
+              {
+                path: '/recruit/personal/personalCenter/memberBenefits/taskCenter',
+                component: () => import('@/views/recruit/personal/PersonalCenter/memberBenefits/taskCenter/index.vue'),
+                meta: {
+                  enName: 'Task Center',
+                  title: '任务中心'
+                }
+              },
+              {
+                path: '/recruit/personal/personalCenter/memberBenefits/membershipPackage',
+                component: () => import('@/views/recruit/personal/PersonalCenter/memberBenefits/membershipPackage/index.vue'),
+                meta: {
+                  enName: 'Membership Package',
+                  title: '会员套餐'
+                }
+              }
+            ]
           },
+          // 账号设置
           {
             path: '/recruit/personal/personalCenter/accountSettings',
             redirect: '/recruit/personal/personalCenter/accountSettings/editPassword',
@@ -59,36 +121,40 @@ const personCenter = [
                 path: '/recruit/personal/personalCenter/accountSettings/editPassword',
                 component: () => import('@/views/recruit/personal/PersonalCenter/accountSettings/editPassword'),
                 meta: {
-                  title: '修改密码'
+                  title: '修改密码',
+                  enName: 'Edit Password'
                 }
               },
-              // {
-              //   path: '/recruit/personal/personalCenter/accountSettings/accountBinding',
-              //   component: () => import('@/views/recruit/personal/PersonalCenter/accountSettings/accountBinding'),
-              //   meta: {
-              //     title: '账号绑定'
-              //   }
-              // },
-              // {
-              //   path: '/recruit/personal/personalCenter/accountSettings/realAuthentication',
-              //   component: () => import('@/views/recruit/personal/PersonalCenter/accountSettings/realAuthentication'),
-              //   meta: {
-              //     title: '实名认证'
-              //   }
-              // },
-              // {
-              //   path: '/recruit/personal/personalCenter/accountSettings/privacySettings',
-              //   component: () => import('@/views/recruit/personal/PersonalCenter/accountSettings/privacySettings'),
-              //   meta: {
-              //     title: '隐私设置'
-              //   }
-              // }
+              {
+                path: '/recruit/personal/personalCenter/accountSettings/accountBinding',
+                component: () => import('@/views/recruit/personal/PersonalCenter/accountSettings/accountBinding'),
+                meta: {
+                  title: '账号绑定',
+                  enName: 'Account binding'
+                }
+              },
+              {
+                path: '/recruit/personal/personalCenter/accountSettings/realAuthentication',
+                component: () => import('@/views/recruit/personal/PersonalCenter/accountSettings/realAuthentication'),
+                meta: {
+                  title: '实名认证',
+                  enName: 'Real name authentication'
+                }
+              },
+              {
+                path: '/recruit/personal/personalCenter/accountSettings/privacySettings',
+                component: () => import('@/views/recruit/personal/PersonalCenter/accountSettings/privacySettings'),
+                meta: {
+                  title: '隐私设置',
+                  enName: 'Privacy settings'
+                }
+              }
             ]
           }
         ]
       }
     ]
-  },
+  }
 ]
 
 export default personCenter

+ 0 - 65
src/router/modules/components/recruit/personal.js

@@ -4,20 +4,6 @@ import Layout from '@/layout'
 import personCenter from './personCenter'
 
 const personal = [
-  {
-    path: '/recruit/personal/resume',
-    component: Layout,
-    name: 'resume',
-    meta: {
-      title: '在线简历'
-    },
-    children: [
-      {
-        path: '/recruit/personal/resume',
-        component: () => import('@/views/recruit/personal/remuse/index.vue')
-      }
-    ]
-  },
   // {
   //   path: '/recruit/personal/personalCenter',
   //   component: Layout,
@@ -39,23 +25,6 @@ const personal = [
   //     }
   //   ]
   // },
-  {
-    path: '/publicRecruitment',
-    component: Layout,
-    name: 'myPublicRecruitment',
-    meta: {
-      title: '赏金奖励'
-    },
-    children: [
-      {
-        path: '/publicRecruitment',
-        component: () => import('@/views/publicRecruitment/index'),
-        meta: {
-          title: '赏金奖励'
-        },
-      }
-    ]
-  },
   {
     path: '/recruit/personal/myWallet',
     component: Layout,
@@ -94,40 +63,6 @@ const personal = [
       },
     ]
   },
-  {
-    path: '/recruit/personal/TaskCenter',
-    component: Layout,
-    name: 'personalTaskCenter',
-    meta: {
-      title: '任务中心'
-    },
-    children: [
-      {
-        path: '/recruit/personal/TaskCenter',
-        component: () => import('@/views/recruit/personal/taskCenter/index'),
-        meta: {
-          title: '任务中心'
-        },
-      }
-    ]
-  },
-  {
-    path: '/recruit/personal/purchasePackage',
-    component: Layout,
-    name: 'personalPurchasePackage',
-    meta: {
-      title: '购买套餐'
-    },
-    children: [
-      {
-        path: '/recruit/personal/purchasePackage',
-        component: () => import('@/views/recruit/personal/purchasePackage'),
-        meta: {
-          title: '购买套餐'
-        }
-      }
-    ]
-  },
   {
     path: '/integral/personalIntegralRules',
     component: Layout,

+ 5 - 1
src/views/mall/purchasePackage/index.vue

@@ -1,6 +1,6 @@
 <!-- 购买套餐 -->
 <template>
-  <div class="default-width py-3">
+  <div class="py-3" :class="customClass">
     <div class="white-bgc resume-box">
       <div class="resume-header" v-if="showTitle">
         <div class="resume-title">购买会员</div>
@@ -51,6 +51,10 @@ defineProps({
   showTitle: {
     type: Boolean,
     default: true
+  },
+  customClass: {
+    type: String,
+    default: 'default-width'
   }
 })
 

+ 0 - 1
src/views/publicRecruitment/components/table.vue

@@ -5,7 +5,6 @@
     :items="items"
     :headers="headers"
     hover
-    height="60vh"
     item-value="id"
   >
     <template #bottom></template>

+ 12 - 3
src/views/publicRecruitment/index.vue

@@ -1,6 +1,6 @@
 <!-- 赏金与积分 -->
 <template>
-  <div class="default-width py-3">
+  <div class="py-3" :class="customClass">
     <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#fff" @update:model-value="getPositionList">
       <v-tab :value="1">{{ $t('publicRecruitment.myRecommendation') }}</v-tab>
       <!-- <v-tab :value="2">{{ $t('publicRecruitment.withdrawalRecords') }}</v-tab> -->
@@ -17,12 +17,21 @@
 </template>
 
 <script setup>
+defineOptions({name: 'personal-myPublicRecruitment-index'})
+import { ref } from 'vue'
 import myRecommendation from './myRecommendation.vue'
 // import myRegistration from './myRegistration.vue'
+
+defineProps({
+  customClass: {
+    type: String,
+    default: 'default-width'
+  }
+})
+
 import { useRoute } from 'vue-router'; const route = useRoute()
 import { useRouter } from 'vue-router'; const router = useRouter()
-import { ref } from 'vue'
-defineOptions({name: 'personal-myPublicRecruitment-index'})
+
 const tab = ref(+route.query?.tab || 1)
 const getPositionList = () => {
   if (route.query) router.replace({ path: route.path }) // 不留记录的清除跳转带过来的参数

+ 1 - 1
src/views/publicRecruitment/myRecommendation.vue

@@ -23,7 +23,7 @@
       </div>
     </div>
     <!-- 滚动区域 -->
-    <div class="pa-3 white-bgc" style="height: 300px; border-radius: 5px; width: 360px;">
+    <div class="pa-3 white-bgc" style="height: 300px; border-radius: 5px; width: 260px;">
       <bountyDisplay></bountyDisplay>
     </div>
   </div>

+ 0 - 13
src/views/recruit/enterprise/purchasePackage/index.vue

@@ -1,13 +0,0 @@
-<!-- 购买套餐 -->
-<template>
-  <PurchasePackage :type="1"></PurchasePackage>
-</template>
-
-<script setup>
-defineOptions({name: 'enterprise-purchasePackage'})
-import PurchasePackage from '@/views/mall/purchasePackage'
-
-</script>
-
-<style lang="scss" scoped>
-</style>

+ 14 - 0
src/views/recruit/personal/PersonalCenter/bountyRewards/index.vue

@@ -0,0 +1,14 @@
+<template>
+  <div>
+    <BountyRewardsPage customClass=""></BountyRewardsPage>
+  </div>
+</template>
+
+<script setup>
+defineOptions({ name: 'bountyRewards'})
+import BountyRewardsPage from '@/views/publicRecruitment/index'
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 9 - 4
src/views/recruit/personal/PersonalCenter/index.vue

@@ -1,8 +1,9 @@
 <template>
-  <div class="pt-3 default-width d-flex parent">
+  <div class="pt-3 d-flex parent">
     <v-card class="left">
       <v-list class="side-box" color="primary">
         <v-list-subheader class="title mb-3">个人中心</v-list-subheader>
+        <v-divider></v-divider>
         <template v-for="(item, index) in list">
           <template v-if="!item.children.length">
             <v-list-item
@@ -88,7 +89,11 @@ updateAccountInfo()
 
 <style scoped lang="scss">
 .parent {
-  height: calc(100vh - 150px);
+  width: 1300px;
+  max-width: 1300px;
+  min-width: 1300px;
+  margin: 0 auto;
+  height: calc(100vh - 100px);
   overflow-y: auto;
 }
 .page {
@@ -99,8 +104,8 @@ updateAccountInfo()
 }
 .left {
   position: sticky;
-  width: 250px;
-  height: calc(100vh - 173px);
+  width: 220px;
+  height: calc(100vh - 113px);
 }
 .title {
   color: var(--color-333);

+ 2 - 2
src/views/recruit/personal/purchasePackage/index.vue → src/views/recruit/personal/PersonalCenter/memberBenefits/membershipPackage/index.vue

@@ -1,9 +1,9 @@
 <template>
-  <PurchasePackage></PurchasePackage>
+  <PurchasePackage customClass=""></PurchasePackage>
 </template>
 
 <script setup>
-defineOptions({ name: 'personal-purchasePackage'})
+defineOptions({ name: 'person-center-purchasePackage'})
 import PurchasePackage from '@/views/mall/purchasePackage'
 
 </script>

+ 0 - 0
src/views/recruit/personal/taskCenter/components/daily.vue → src/views/recruit/personal/PersonalCenter/memberBenefits/taskCenter/components/daily.vue


+ 0 - 0
src/views/recruit/personal/taskCenter/components/signIn.vue → src/views/recruit/personal/PersonalCenter/memberBenefits/taskCenter/components/signIn.vue


+ 0 - 0
src/views/recruit/personal/taskCenter/components/suggest.vue → src/views/recruit/personal/PersonalCenter/memberBenefits/taskCenter/components/suggest.vue


+ 1 - 2
src/views/recruit/personal/taskCenter/index.vue → src/views/recruit/personal/PersonalCenter/memberBenefits/taskCenter/index.vue

@@ -1,13 +1,12 @@
 <!-- 任务中心 -->
 <template>
-  <div class="default-width py-3">
+  <div class="py-3">
     <!-- 签到 -->
     <signIn class="white-bgc borderRadius5 mb-3 pa-3"></signIn>
     <!-- 推荐任务 -->
     <suggest class="white-bgc borderRadius5 mb-3 pa-3"></suggest>
     <!-- 每日任务 -->
     <daily class="white-bgc borderRadius5 mb-3 pa-3"></daily>
-    <!-- <div class="white-bgc borderRadius5 mt-3 pa-3"></div> -->
   </div>
 </template>
 

+ 100 - 0
src/views/recruit/personal/PersonalCenter/resume/attachment/index.vue

@@ -0,0 +1,100 @@
+<template>
+  <div class="resume-box">
+    <div class="resume-header mb-3">
+      <div class="resume-title">附件简历</div>
+      <v-btn variant="text" color="primary" prepend-icon="mdi-plus-box" @click="openFileInput">
+        上传
+        <File ref="uploadFile" @success="handleUploadResume"></File>
+      </v-btn>
+    </div>
+    <div v-if="attachmentList.length">
+      <div
+        :class="['position-item', 'mx-n2', 'px-2']" 
+        v-for="(k, i) in attachmentList" 
+        :key="i" 
+        @mouseenter="k.active = true" 
+        @mouseleave="k.active = false"
+      >
+        <div>{{ k.title }}</div>
+        <div class="float-right" v-if="k.active">
+          <v-btn variant="text" color="primary" prepend-icon="mdi-eye-outline" @click="previewFile(k.url)">预览</v-btn>
+          <v-btn variant="text" color="primary" prepend-icon="mdi-square-edit-outline" @click="handleDownload(k)">下载</v-btn>
+          <v-btn variant="text" color="primary" prepend-icon="mdi-trash-can-outline" @click="handleDelete(k)">{{ $t('common.delete') }}</v-btn>
+        </div>
+      </div>
+    </div>
+    <div v-else class="resumeNoDataText">请上传您的附件简历</div>
+  </div>
+</template>
+
+<script setup>
+defineOptions({ name: 'person-center-resume-annex'})
+import { ref } from 'vue'
+import Snackbar from '@/plugins/snackbar'
+import Confirm from '@/plugins/confirm'
+import { useI18n } from '@/hooks/web/useI18n'
+import { getPersonResumeCv, savePersonResumeCv, deletePersonResumeCv } from '@/api/recruit/personal/resume'
+import { getBlob, saveAs } from '@/utils'
+import { previewFile } from '@/utils'
+
+const { t } = useI18n()
+
+// 获取附件
+const attachmentList = ref([])
+const getList = async () => {
+  const data = await getPersonResumeCv()
+  attachmentList.value = data
+}
+getList()
+
+// 选择文件
+const uploadFile = ref()
+const openFileInput = () => {
+  if (attachmentList.value.length >= 5) return Snackbar.warning(t('resume.uploadFiveCopies'))
+  uploadFile.value.trigger()
+}
+
+// 上传附件
+const handleUploadResume = async (url, title) => {
+  if (!url || !title) return
+  Snackbar.success(t('common.uploadSucMsg'))
+  await savePersonResumeCv({ title, url })
+  getList()
+}
+
+// 删除
+const handleDelete = ({ id }) => {
+  Confirm(t('common.confirmTitle'), t('resume.deleteAttachment')).then(async () => {
+    await deletePersonResumeCv(id)
+    Snackbar.success(t('common.delMsg'))
+    getList()
+  })
+}
+
+// 下载附件
+const handleDownload = (k) => {
+  getBlob(k.url).then(blob => {
+    saveAs(blob, k.title)
+  })
+}
+</script>
+
+<style scoped lang="scss">
+.position-item {
+  display: flex;
+  justify-content: space-between;
+  cursor: pointer;
+  border-radius: 6px;
+  line-height: 40px;
+  font-size: 15px;
+  &:hover {
+    background-color: var(--color-f8);
+  }
+  span {
+    font-size: 15px;
+  }
+  .grey-text {
+    color: var(--color-999);
+  }
+}
+</style>

+ 1 - 1
src/views/recruit/personal/remuse/components/basicInfo.vue → src/views/recruit/personal/PersonalCenter/resume/online/components/basicInfo.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="resume-box mb-3">
+  <div class="resume-box mb-3 elevation-2">
     <div class="resume-header">
       <div class="resume-title">{{ $t('resume.basicInfo') }}</div>
       <v-btn v-if="!isEdit" variant="text" color="primary" prepend-icon="mdi-square-edit-outline" @click="isEdit = true">{{ $t('common.edit') }}</v-btn>

+ 0 - 0
src/views/recruit/personal/remuse/components/dict.js → src/views/recruit/personal/PersonalCenter/resume/online/components/dict.js


+ 0 - 0
src/views/recruit/personal/remuse/components/educationExp.vue → src/views/recruit/personal/PersonalCenter/resume/online/components/educationExp.vue


+ 0 - 0
src/views/recruit/personal/remuse/components/jobIntention.vue → src/views/recruit/personal/PersonalCenter/resume/online/components/jobIntention.vue


+ 0 - 0
src/views/recruit/personal/remuse/components/projectExperience.vue → src/views/recruit/personal/PersonalCenter/resume/online/components/projectExperience.vue


+ 0 - 0
src/views/recruit/personal/remuse/components/selfEvaluation.vue → src/views/recruit/personal/PersonalCenter/resume/online/components/selfEvaluation.vue


+ 0 - 0
src/views/recruit/personal/remuse/components/trainingExperience.vue → src/views/recruit/personal/PersonalCenter/resume/online/components/trainingExperience.vue


+ 0 - 0
src/views/recruit/personal/remuse/components/vocationalSkills.vue → src/views/recruit/personal/PersonalCenter/resume/online/components/vocationalSkills.vue


+ 0 - 0
src/views/recruit/personal/remuse/components/workExperience.vue → src/views/recruit/personal/PersonalCenter/resume/online/components/workExperience.vue


+ 116 - 0
src/views/recruit/personal/PersonalCenter/resume/online/index.vue

@@ -0,0 +1,116 @@
+<template>
+  <div>
+    <div class="tabHeader">
+      <ProgressBar :num="completeNum" :total="items?.length"></ProgressBar>
+      <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#f7f8fa">
+        <v-tab v-for="k in items" :key="k.path" :value="k.value" @click="handleClick(k)">
+          {{ k.text }}
+          <template v-slot:append>
+            <template v-if="k.status === false">
+              <v-icon color="orange">mdi-information-outline</v-icon>
+              <v-tooltip activator="parent" location="top">请完善{{ k.text }}</v-tooltip>
+            </template>
+          </template>
+        </v-tab>
+      </v-tabs>
+    </div>
+    <div class="pt-3 contentBox px-1" id="contentBox" ref="scrollBox">
+      <component
+        v-for="val in items"
+        :key="val.id"
+        class="mb-3 elevation-2"
+        :is="val.path"
+        :id="val.id"
+        @complete="complete"
+      />
+    </div>
+  </div>
+</template>
+
+<script setup>
+defineOptions({ name: 'person-center-resume-online'})
+import { ref, onMounted, shallowRef } from 'vue'
+import { useI18n } from '@/hooks/web/useI18n'
+import basicInfo from './components/basicInfo.vue'
+import selfEvaluation from './components/selfEvaluation.vue'
+import jobIntention from './components/jobIntention.vue'
+import trainingExperience from './components/trainingExperience.vue'
+import educationExp from './components/educationExp.vue'
+import workExperience from './components/workExperience.vue'
+import projectExperience from './components/projectExperience.vue'
+import vocationalSkills from './components/vocationalSkills.vue'
+
+const { t } = useI18n()
+const scrollBox = ref()
+const tab = ref(0)
+const items = shallowRef([
+  { text: t('resume.basicInfo'), id: 'basicInfo', status: true, path: basicInfo },
+  { text: t('resume.personalAdvantages'), id: 'selfEvaluation', status: false, path: selfEvaluation },
+  { text: t('resume.jobIntention'), id: 'jobIntention', status: true, path: jobIntention },
+  { text: t('resume.educationExp'), id: 'educationExp', status: true, path: educationExp },
+  { text: t('resume.workExperience'), id: 'workExperience', status: false, path: workExperience },
+  { text: t('resume.projectExperience'), id: 'projectExperience', status: true, path: projectExperience },
+  { text: t('resume.trainingExperience'), id: 'trainingExperience', status: false, path: trainingExperience },
+  { text: t('resume.vocationalSkills'), id: 'vocationalSkills', status: true, path: vocationalSkills }
+])
+
+onMounted(() => {
+  const selector = document.getElementById('contentBox')
+  if (!selector) return
+  selector.style.top = `${scrollBox.value.offsetTop + 12}px`
+})
+
+const handleClick = (item) => {
+  if (item.id) {
+    const selector = document.getElementById(item.id)
+    if (!selector) {
+      scrollBox.value.scrollTo({
+        top: 0,
+        behavior: 'smooth'
+      })
+      return
+    }
+    scrollBox.value.scrollTo({
+      top: selector.offsetTop - scrollBox.value.offsetTop - 12,
+      behavior: 'smooth'
+    })
+  }
+}
+
+// 简历完成度
+const completeNum = ref(0)
+const complete = (val) => {
+  if (!val?.id) return
+  completeNum.value = 0
+  items.value.forEach(e => {
+    if (e.id === val.id) {
+      e.status = val.status || false
+    }
+    if (e.status) {
+      completeNum.value++
+    }
+  })
+}
+</script>
+
+<style scoped lang="scss">
+.tabHeader {
+  position: sticky;
+}
+.contentBox {
+  height: calc(100vh - 251px);
+  overflow: auto;
+}
+::-webkit-scrollbar {
+  width: 0;
+  height: 0;
+}
+::-webkit-scrollbar-thumb, .temporaryAdd ::-webkit-scrollbar-thumb, .details_edit ::-webkit-scrollbar-thumb {
+  // 滚动条-颜色
+  background: #c3c3c379;
+}
+::-webkit-scrollbar-track, .temporaryAdd ::-webkit-scrollbar-track, .details_edit ::-webkit-scrollbar-track {
+  // 滚动条-底色
+  background: #e5e5e58f;
+}
+</style>

+ 0 - 126
src/views/recruit/personal/remuse/index.vue

@@ -1,126 +0,0 @@
-<template>
-  <div class="default-width d-flex" ref="scrollBox">
-    <div class="mr-3 pt-3">
-      <v-card id="leftCadId" width="240" max-width="240" height="540" class="positionSticky">
-        <v-list>
-          <v-list-subheader class="title">简历目录</v-list-subheader>
-          <v-list-item v-for="(item, i) in items" :key="i" :value="item" :disabled="!item.id" color="primary" @click="handleClick(item)">
-            <template v-slot:prepend>
-              <v-icon :icon="item.icon"></v-icon>
-            </template>
-            <v-list-item-title>{{ item.text }}</v-list-item-title>
-            <template v-slot:append>
-              <!-- <v-icon v-if="!item.status">mdi-information-outline</v-icon> -->
-              <v-icon v-if="item.status" color="primary">mdi-check</v-icon>
-              <template v-else>
-                <v-icon color="orange">mdi-information-outline</v-icon>
-                <v-tooltip activator="parent" location="top">请完善{{ item.text }}</v-tooltip>
-              </template>
-            </template>
-          </v-list-item>
-        </v-list>
-        <v-divider></v-divider>
-        <ProgressBar
-          class="mt-2"
-          :num="completeNum"
-          :total="items?.length"
-        ></ProgressBar>
-      </v-card>
-    </div>
-    <div class=" pt-3">
-      <component
-        v-for="item in comList"
-        :key="item.id"
-        ref="component"
-        class="mb-3"
-        :is="item.path"
-        :id="item.domId"
-        @complete="complete"
-      />
-    </div>
-  </div>
-</template>
-
-<script setup>
-defineOptions({ name: 'resume-index' })
-import basicInfo from './components/basicInfo.vue'
-import selfEvaluation from './components/selfEvaluation.vue'
-import jobIntention from './components/jobIntention.vue'
-import trainingExperience from './components/trainingExperience.vue'
-import educationExp from './components/educationExp.vue'
-import workExperience from './components/workExperience.vue'
-import projectExperience from './components/projectExperience.vue'
-import vocationalSkills from './components/vocationalSkills.vue'
-import { useI18n } from '@/hooks/web/useI18n'
-import ProgressBar from '@/components/ProgressBar'
-const { t } = useI18n()
-import { ref } from 'vue'
-import { onMounted } from 'vue';
-const scrollBox = ref()
-
-const comList = [
-  // { path: vocationalSkills, id: 'resumeVocationalSkills', domId: 'vocationalSkills' },
-  { path: basicInfo, id: 'resumeBasicInfo', domId: 'basicInfo' }, // domId与items中的id保持一致
-  { path: selfEvaluation, id: 'resumeSelfEvaluation', domId: 'selfEvaluation' },
-  { path: jobIntention, id: 'resumeJobIntention', domId: 'jobIntention' },
-  { path: educationExp, id: 'resumeEducationExp', domId: 'educationExp' },
-  { path: workExperience, id: 'resumeProjectExperience', domId: 'workExperience' },
-  { path: projectExperience, id: 'resumeProjectExperience', domId: 'projectExperience' },
-  { path: trainingExperience, id: 'resumeTrainingExperience', domId: 'trainingExperience' },
-  { path: vocationalSkills, id: 'resumeVocationalSkills', domId: 'vocationalSkills' },
-]
-
-const items = ref([
-  { text: t('resume.basicInfo'), icon: 'mdi-account-outline', id: 'basicInfo' },
-  { text: t('resume.personalAdvantages'), icon: 'mdi-account-star-outline', id: 'selfEvaluation' },
-  { text: t('resume.jobIntention'), icon: 'mdi-briefcase-variant-outline', id: 'jobIntention' },
-  { text: t('resume.educationExp'), icon: 'mdi-school-outline', id: 'educationExp' },
-  { text: t('resume.workExperience'), icon: 'mdi-ballot-outline', id: 'workExperience' },
-  { text: t('resume.projectExperience'), icon: 'mdi-card-text-outline', id: 'projectExperience' },
-  { text: t('resume.trainingExperience'), icon: 'mdi-flag-outline', id: 'trainingExperience' },
-  { text: t('resume.vocationalSkills'), icon: 'mdi-star-check-outline', id: 'vocationalSkills' }
-])
-
-onMounted(() => {
-  const selector = document.getElementById('leftCadId')
-  if (!selector) return
-  selector.style.top = `${scrollBox.value.offsetTop + 12}px`
-})
-
-const handleClick = (item) => {
-  if (item.id) {
-    const selector = document.getElementById(item.id)
-    if (!selector) return
-    window.scrollTo({
-      top: selector.offsetTop - scrollBox.value.offsetTop - 12,
-      behavior: 'smooth'
-    })
-  }
-}
-
-const completeNum = ref(0)
-const complete = (val) => {
-  if (!val?.id) return
-  completeNum.value = 0
-  items.value.forEach(e => {
-    if (e.id === val.id) {
-      e.status = val.status || false
-    }
-    if (e.status) {
-      completeNum.value++
-    }
-  })
-}
-</script>
-
-<style lang="scss" scoped>
-.positionSticky {
-  position: sticky;
-  // top: 62px;
-}
-.title {
-  color: var(--color-333);
-  font-weight: 600;
-  font-size: 20px;
-}
-</style>