Explorar o código

Merge branch 'dev' of https://git.citupro.com/zhengnaiwen_citu/menduner into dev

lifanagju_citu hai 10 meses
pai
achega
2cdc91e51b

+ 1 - 0
components.d.ts

@@ -23,6 +23,7 @@ declare module 'vue' {
     CtTextField: typeof import('./src/components/CtVuetify/CtTextField/index.vue')['default']
     DatePicker: typeof import('./src/components/DatePicker/index.vue')['default']
     Details: typeof import('./src/components/Enterprise/details.vue')['default']
+    Echarts: typeof import('./src/components/Echarts/index.vue')['default']
     Empty: typeof import('./src/components/Empty/index.vue')['default']
     HeadSearch: typeof import('./src/components/headSearch/index.vue')['default']
     HotPromoted: typeof import('./src/components/Enterprise/hotPromoted.vue')['default']

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 602 - 201
package-lock.json


+ 3 - 1
package.json

@@ -12,6 +12,7 @@
     "@mdi/font": "7.0.96",
     "@vuepic/vue-datepicker": "^8.7.0",
     "axios": "^1.6.8",
+    "echarts": "^5.4.3",
     "js-base64": "^3.7.7",
     "js-cookie": "^3.0.5",
     "lodash": "^4.17.21",
@@ -24,7 +25,8 @@
     "vue": "^3.4.0",
     "vue-i18n": "9",
     "vue-router": "^4.3.0",
-    "vuetify": "^3.6.0"
+    "vuetify": "^3.6.0",
+    "wukongimjssdk": "^1.2.10"
   },
   "devDependencies": {
     "@rushstack/eslint-patch": "^1.8.0",

+ 10 - 0
src/api/recruit/personal/personalCenter/index.js

@@ -0,0 +1,10 @@
+import request from '@/config/axios'
+
+
+// 看过我的企业用户列表
+export const getInterestedMePage = async (params) => {
+  return await request.get({
+    url: '/app-api/menduner/system/job-cv-rel/get/job/cv/look/page',
+    params
+  })
+}

+ 3 - 1
src/components/DatePicker/index.vue

@@ -48,5 +48,7 @@ const time = computed(() => {
 </script>
 
 <style scoped lang="scss">
-
+:deep(.dp__input_icon_pad) {
+  font-size: 14px;
+}
 </style>

+ 60 - 0
src/components/Echarts/index.vue

@@ -0,0 +1,60 @@
+<template>
+  <div>
+    <div :id="domId" :style="{'width':'100%','height': height + 'px','padding-top':'15px','margin':'auto'}"></div>
+  </div>
+</template>
+
+<script setup>
+defineOptions({ name: 'low-code'})
+import { ref, watch, nextTick, onMounted } from 'vue'
+import * as echarts from 'echarts'
+import { generateUUID } from "@/utils/index" 
+
+const emit = defineEmits(['click'])
+const props = defineProps({
+  height: {
+    type: [Number, String],
+    default: 485
+  },
+  // 附加数据
+  option: {
+    type: [Object, Array],
+    default: () => {}
+  }
+})
+
+const domId = ref(generateUUID())
+const chart = ref({})
+
+const initMap = () => {
+  chart.value = echarts.init(document.getElementById(domId.value), null, { renderer: 'svg' })
+  chart.value.setOption(props.option)
+  chart.value.on('click', (param) => {
+    emit('click', param)
+  })
+  window.addEventListener('resize',()=>{
+    chart.value.resize()
+  })
+}
+
+onMounted(() => {
+  initMap()
+})
+
+watch(
+  () => props.option,
+  () => {
+    if(Object.keys(chart.value).length) {
+      chart.value.dispose()
+    }
+    nextTick(()=>{
+      initMap()
+    })
+  },
+  { deep: true }
+)
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 4 - 0
src/main.js

@@ -8,11 +8,14 @@
 import { registerPlugins } from '@/plugins'
 import '@/styles/index.scss'
 
+// import * as echarts from 'echarts'
 import App from './App.vue'
 import { createApp } from 'vue'
 
 import { createPinia } from 'pinia'
 
+// import WKSDK from "wukongimjssdk"
+
 import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' // pinia 持久化
 
 // 日期组件
@@ -33,6 +36,7 @@ const app = createApp(App)
 app.use(pinia)
 app.use(router)
 
+// app.config.globalProperties.$echarts = echarts
 registerPlugins(app)
 app.component('VueDatePicker', VueDatePicker)
 

+ 1 - 0
src/styles/index.css

@@ -187,4 +187,5 @@
 .card-box {
   width: 100%;
   height: 100%;
+  min-height: 70vh;
 }

+ 1 - 1
src/styles/index.min.css

@@ -1 +1 @@
-:root{--zIndex-dialog:999;--default-bgc:#f2f4f7;--v-primary-base:#00897B;--v-error-base:#fe574a;--v-primary-lighten1:#26A69A;--v-primary-lighten2:#4DB6AC;--v-primary-lighten3:#80CBC4;--v-primary-lighten4:#B2DFDB;--color-222:#222;--color-333:#333;--color-666:#666;--color-777:#777;--color-999:#999;--color-ccc:#ccc;--color-f3:#f3f3f3;--color-f2f4f742:#f2f4f742;--color-f8:#f8f8f8;--color-f2f4f7:#f2f4f7;--color-d5e6e8:#d5e6e8;--zIndex-breadcrumbs:999}.color-222{color:#222}.color-333{color:#333}.color-666{color:#666}.color-777{color:#777}.color-999{color:#999}.color-ccc{color:#ccc}.color-f3f3f3{color:#f3f3f3}.color-f2f4f742{color:#f2f4f742}.color-f8f8f8{color:#f8f8f8}.color-f2f4f7{color:#f2f4f7}.color-d5e6e8{color:#d5e6e8}.color-error{color:#fe574a}.color-primary{color:#00897B}.font-size-12{font-size:12px}.font-size-13{font-size:13px}.font-size-14{font-size:14px}.font-size-15{font-size:15px}.font-size-16{font-size:16px}.font-size-17{font-size:17px}.font-size-18{font-size:18px}.font-size-19{font-size:19px}.font-size-20{font-size:20px}.buttons{height:36px;width:224px}.half-button{height:36px;width:88px}.default-width{width:1184px;min-width:1184px;max-width:1184px;margin:0 auto}.defaultLink{color:#008978;cursor:pointer}.default-active{color:var(--v-primary-base) !important}.border-bottom-dashed{border-bottom:1px dashed var(--color-ccc)}.white-bgc{background-color:#fff}.ellipsis{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.septal-line{display:inline-block;width:1px;height:10px;vertical-align:middle;background-color:#e0e0e0;margin:0 10px}.resume-box{border-radius:5px;padding:20px 30px;background-color:#fff}.resume-header{display:flex;justify-content:space-between;align-items:center;height:36px}.resume-title{font-weight:700;font-size:18px;border-left:5px solid #00897B;padding-left:12px;line-height:17px}.resumeNoDataText{color:var(--color-666);font-size:14px}.card-box{width:100%;height:100%}
+:root{--zIndex-dialog:999;--default-bgc:#f2f4f7;--v-primary-base:#00897B;--v-error-base:#fe574a;--v-primary-lighten1:#26A69A;--v-primary-lighten2:#4DB6AC;--v-primary-lighten3:#80CBC4;--v-primary-lighten4:#B2DFDB;--color-222:#222;--color-333:#333;--color-666:#666;--color-777:#777;--color-999:#999;--color-ccc:#ccc;--color-f3:#f3f3f3;--color-f2f4f742:#f2f4f742;--color-f8:#f8f8f8;--color-f2f4f7:#f2f4f7;--color-d5e6e8:#d5e6e8;--zIndex-breadcrumbs:999}.color-222{color:#222}.color-333{color:#333}.color-666{color:#666}.color-777{color:#777}.color-999{color:#999}.color-ccc{color:#ccc}.color-f3f3f3{color:#f3f3f3}.color-f2f4f742{color:#f2f4f742}.color-f8f8f8{color:#f8f8f8}.color-f2f4f7{color:#f2f4f7}.color-d5e6e8{color:#d5e6e8}.color-error{color:#fe574a}.color-primary{color:#00897B}.font-size-12{font-size:12px}.font-size-13{font-size:13px}.font-size-14{font-size:14px}.font-size-15{font-size:15px}.font-size-16{font-size:16px}.font-size-17{font-size:17px}.font-size-18{font-size:18px}.font-size-19{font-size:19px}.font-size-20{font-size:20px}.buttons{height:36px;width:224px}.half-button{height:36px;width:88px}.default-width{width:1184px;min-width:1184px;max-width:1184px;margin:0 auto}.defaultLink{color:#008978;cursor:pointer}.default-active{color:var(--v-primary-base) !important}.border-bottom-dashed{border-bottom:1px dashed var(--color-ccc)}.white-bgc{background-color:#fff}.ellipsis{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.septal-line{display:inline-block;width:1px;height:10px;vertical-align:middle;background-color:#e0e0e0;margin:0 10px}.resume-box{border-radius:5px;padding:20px 30px;background-color:#fff}.resume-header{display:flex;justify-content:space-between;align-items:center;height:36px}.resume-title{font-weight:700;font-size:18px;border-left:5px solid #00897B;padding-left:12px;line-height:17px}.resumeNoDataText{color:var(--color-666);font-size:14px}.card-box{width:100%;height:100%;min-height:70vh}

+ 1 - 0
src/styles/index.scss

@@ -131,4 +131,5 @@
 .card-box {
   width: 100%;
   height: 100%;
+  min-height: 70vh;
 }

+ 13 - 0
src/utils/index.js

@@ -42,4 +42,17 @@ import { Base64 } from 'js-base64'
 export const previewFile = (url) => {
   const baseUrl = import.meta.env.VITE_PREVIEW_URL
   window.open(`${baseUrl}/onlinePreview?url=${encodeURIComponent(Base64.encode(url))}`)
+}
+
+export const generateUUID = () => {
+  var d = new Date().getTime()
+  if (window.performance && typeof window.performance.now === "function") {
+    d += performance.now(); //use high-precision timer if available
+  }
+  var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+    var r = (d + Math.random() * 16) % 16 | 0
+    d = Math.floor(d / 16)
+    return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16)
+  })
+  return uuid.replace(/-/g, "")
 }

+ 1 - 1
src/views/recruit/enterprise/informationManagement/informationSettingsComponents/basicInfo.vue

@@ -171,7 +171,7 @@ const getBaseInfo = async () => {
     }
     query.industryId = data.industryId
     if (item.key === 'industryId') {
-      item.value = industryList.value.find(e => e.id === data[item.key]).nameCn
+      item.value = industryList.value.find(e => e.id === data[item.key])?.nameCn
     } else item.value = data[item.key]
   })
 }

+ 53 - 0
src/views/recruit/enterprise/statistics/components/daily.vue

@@ -0,0 +1,53 @@
+<template>
+  <v-data-table
+    :items="items"
+    :headers="headers"
+  > 
+    <template #bottom>
+      <CtPagination
+        :total="total"
+        :page="query.pageNo"
+        :limit="query.pageSize"
+        @handleChange="handleChangePage"
+      ></CtPagination>
+    </template>
+  </v-data-table>
+</template>
+
+<script setup>
+defineOptions({ name: 'daily-page'})
+import { ref } from 'vue'
+
+const total = ref(8)
+const query = ref({
+  pageSize: 10,
+  pageNo: 1
+})
+const headers = [
+  { title: '日期', key: 'date', sortable: false },
+  { title: '有效职位', key: 'effectivePositions', sortable: false },
+  { title: '刷新次数', key: 'refreshTimes', sortable: false },
+  { title: '职位浏览', key: 'jobBrowse', sortable: false },
+  { title: '简历投递', key: 'resumeDelivery', sortable: false},
+  { title: '简历处理', key: 'resumeDeal', sortable: false },
+  { title: '邀请面试', key: 'invite', sortable: false }
+]
+const items = ref([
+  { date: '2024-07-01', effectivePositions: 0, refreshTimes: 0, jobBrowse: 0, resumeDelivery: 0, resumeDeal: 0, invite: 0 },
+  { date: '2024-07-02', effectivePositions: 0, refreshTimes: 0, jobBrowse: 0, resumeDelivery: 0, resumeDeal: 0, invite: 0 },
+  { date: '2024-07-03', effectivePositions: 0, refreshTimes: 0, jobBrowse: 0, resumeDelivery: 0, resumeDeal: 0, invite: 0 },
+  { date: '2024-07-04', effectivePositions: 0, refreshTimes: 0, jobBrowse: 0, resumeDelivery: 0, resumeDeal: 0, invite: 0 },
+  { date: '2024-07-05', effectivePositions: 0, refreshTimes: 0, jobBrowse: 0, resumeDelivery: 0, resumeDeal: 0, invite: 0 },
+  { date: '2024-07-06', effectivePositions: 0, refreshTimes: 0, jobBrowse: 0, resumeDelivery: 0, resumeDeal: 0, invite: 0 },
+  { date: '2024-07-07', effectivePositions: 0, refreshTimes: 0, jobBrowse: 0, resumeDelivery: 0, resumeDeal: 0, invite: 0 },
+  { date: '2024-07-08', effectivePositions: 0, refreshTimes: 0, jobBrowse: 0, resumeDelivery: 0, resumeDeal: 0, invite: 0 }
+])
+
+const handleChangePage = (e) => {
+  query.value.pageNo = e
+}
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 171 - 0
src/views/recruit/enterprise/statistics/components/data.js

@@ -0,0 +1,171 @@
+export const list = [
+  {
+    col: 6,
+    option: {
+      title: {
+        text: '性别比例'
+      },
+      tooltip: {
+        trigger: 'item'
+      },
+      legend: {
+        top: '5%',
+        left: 'center'
+      },
+      series: [
+        {
+          name: 'Access From',
+          type: 'pie',
+          radius: ['40%', '70%'],
+          avoidLabelOverlap: false,
+          itemStyle: {
+            borderRadius: 10,
+            borderColor: '#fff',
+            borderWidth: 2
+          },
+          label: {
+            show: true,
+            formatter: e => {
+              return e.name + ': ' + e.value + '%'
+            }
+          },
+          labelLine: {
+            show: true
+          },
+          data: [
+            { value: 65, name: '男' },
+            { value: 35, name: '女' }
+          ]
+        }
+      ]
+    }
+  },
+  {
+    col: 6,
+    option: {
+      title: {
+        text: '年龄分布'
+      },
+      xAxis: {
+        type: 'category',
+        data: ['18-22岁', '22-30岁', '30-39岁', '40-49岁', '50-59岁']
+      },
+      yAxis: {
+        type: 'value'
+      },
+      grid: {
+        left: '0',
+        top: '50',
+        right: '0',
+        bottom: 0,
+        containLabel: true
+      },
+      series: [
+        {
+          data: [120, 200, 150, 80, 70],
+          type: 'bar',
+          barWidth: 40,
+          label: {
+            show: true
+          }
+        }
+      ]
+    }
+  },
+  {
+    col: 6,
+    option: {
+      title: {
+        text: '工作年限分布'
+      },
+      xAxis: {
+        type: 'category',
+        data: ['应届毕业生', '1年以上', '2年以上', '3年以上', '5年以上', '8年以上', '10年以上']
+      },
+      yAxis: {
+        type: 'value'
+      },
+      grid: {
+        left: '0',
+        top: '50',
+        right: '0',
+        bottom: 0,
+        containLabel: true
+      },
+      series: [
+        {
+          data: [120, 200, 150, 80, 70, 110, 130],
+          type: 'bar',
+          barWidth: 40,
+          label: {
+            show: true
+          }
+        }
+      ]
+    }
+  },
+  {
+    col: 6,
+    option: {
+      title: {
+        text: '学历分布'
+      },
+      xAxis: {
+        type: 'category',
+        data: ['本科以上', '大专', '中专', '中技', '高中', '初中']
+      },
+      yAxis: {
+        type: 'value'
+      },
+      grid: {
+        left: '0',
+        top: '50',
+        right: '0',
+        bottom: 0,
+        containLabel: true
+      },
+      series: [
+        {
+          data: [120, 200, 150, 80, 70, 110],
+          type: 'bar',
+          barWidth: 40,
+          label: {
+            show: true
+          }
+        }
+      ]
+    }
+  },
+  {
+    col: 12,
+    option: {
+      title: {
+        text: '期望月薪'
+      },
+      xAxis: {
+        type: 'category',
+        data: ['3-5k', '5-8k', '8-12k', '12-15k', '15-20k', '20-30k', '面议']
+      },
+      yAxis: {
+        type: 'value'
+      },
+      grid: {
+        left: '0',
+        top: '50',
+        right: '0',
+        bottom: 0,
+        containLabel: true
+      },
+      series: [
+        {
+          data: [120, 200, 150, 80, 70, 110, 130],
+          type: 'bar',
+          barWidth: 40,
+          label: {
+            show: true
+          }
+        }
+      ]
+    }
+  }
+]

+ 152 - 0
src/views/recruit/enterprise/statistics/components/overview.vue

@@ -0,0 +1,152 @@
+<template>
+  <div class="overview my-5">
+    <div class="overview-item pa-5 color-666" v-for="(val, i) in overview" :key="i">
+      <div>{{ val.title }}</div>
+      <div class="overview-item-value my-3">{{ val.value }}</div>
+      <div class="font-size-14">
+        环比
+        <span class="color-error">0% ↑</span>
+      </div>
+    </div>
+  </div>
+  <div id="myChart" style="width: 100%; height: 500px;background-color: #f7f8fa;border-radius: 8px;" class="pa-3"></div>
+</template>
+
+<script setup>
+defineOptions({ name: 'overview-page'})
+import { ref, onMounted } from 'vue'
+import * as echarts from 'echarts'
+
+// 数据概况
+const overview = ref([
+  { title: '我看过', value: 86, desc: '' },
+  { title: '看过我', value: 12, desc: '' },
+  { title: '我打招呼', value: 0, desc: '' },
+  { title: '牛人新招呼', value: 4, desc: '' },
+  { title: '我沟通', value: 0, desc: '' },
+  { title: '收获简历', value: 5, desc: '' },
+  { title: '交换电话微信', value: 2, desc: '' },
+  { title: '接受面试', value: 0, desc: '' }
+])
+
+onMounted(() => {
+  var chartDom = document.getElementById('myChart')
+  var myChart = echarts.init(chartDom)
+  var option
+
+  option = {
+    title: {
+      text: '历史数据走势图'
+    },
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'cross',
+        label: {
+          backgroundColor: '#6a7985'
+        }
+      }
+    },
+    legend: {
+      data: ['职位数', '刷新次数', '职位浏览', '简历投递数', '简历处理']
+    },
+    toolbox: {
+      feature: {
+        saveAsImage: {}
+      }
+    },
+    grid: {
+      left: '3%',
+      right: '4%',
+      bottom: '3%',
+      containLabel: true
+    },
+    xAxis: [
+      {
+        type: 'category',
+        boundaryGap: false,
+        data: ['2024-07-10', '2024-07-11', '2024-07-12']
+      }
+    ],
+    yAxis: [
+      {
+        type: 'value'
+      }
+    ],
+    series: [
+      {
+        name: '职位数',
+        type: 'line',
+        emphasis: {
+          focus: 'series'
+        },
+        data: [120, 132, 101, 134, 90, 230, 210]
+      },
+      {
+        name: '刷新次数',
+        type: 'line',
+        emphasis: {
+          focus: 'series'
+        },
+        data: [220, 182, 191, 234, 290, 330, 310]
+      },
+      {
+        name: '职位浏览',
+        type: 'line',
+        emphasis: {
+          focus: 'series'
+        },
+        data: [150, 232, 201, 154, 190, 330, 410]
+      },
+      {
+        name: '简历投递数',
+        type: 'line',
+        emphasis: {
+          focus: 'series'
+        },
+        data: [320, 332, 301, 334, 390, 330, 320]
+      },
+      {
+        name: '简历处理',
+        type: 'line',
+        label: {
+          show: true,
+          position: 'top'
+        },
+        emphasis: {
+          focus: 'series'
+        },
+        data: [820, 932, 901, 934, 1290, 1330, 1320]
+      }
+    ]
+  }
+  option && myChart.setOption(option)
+})
+</script>
+
+<style scoped lang="scss">
+.overview {
+  display: flex;
+  flex-wrap: wrap;
+  width: 100%;
+}
+.overview-item {
+  width: calc((100% - 84px) / 8);
+  min-width: calc((100% - 84px) / 8);
+  max-width: calc((100% - 84px) / 8);
+  margin: 0 12px 12px 0;
+  height: 175px;
+  border-radius: 12px;
+  overflow: hidden;
+  transition: all .2s linear;
+  background-color: #f7f8fa;
+  &:nth-child(8n) {
+    margin-right: 0;
+  }
+}
+.overview-item-value {
+  color: var(--v-primary-base);
+  font-weight: 700;
+  font-size: 44px;
+}
+</style>

+ 22 - 0
src/views/recruit/enterprise/statistics/components/resume.vue

@@ -0,0 +1,22 @@
+<template>
+  <v-container>
+    <v-row>
+      <v-col class="bgc" v-for="(val, i) in list" :key="i" :md="val.col">
+        <Echarts :height="400" :option="val.option"></Echarts>
+      </v-col>
+    </v-row>
+  </v-container>
+</template>
+
+<script setup>
+defineOptions({ name: 'resume-analysis'})
+import { list } from './data.js'
+
+</script>
+
+<style scoped lang="scss">
+.bgc {
+  background-color: #f7f8fa;
+  border-radius: 8px;
+}
+</style>

+ 66 - 2
src/views/recruit/enterprise/statistics/overallAnalysis.vue

@@ -1,11 +1,75 @@
 <template>
-  <div>整体分析</div>
+  <v-card class="card-box pa-5">
+    <div class="d-flex color-666 font-size-14">
+      <div class="d-flex align-center">
+        <span>选择时间</span>
+        <div class="ml-5 after">
+          <span v-for="(k, i) in list" :key="i" :class="['item', { 'active': current === (i + 1) }]" @click="current = i + 1 ">{{ k }}</span>
+        </div>
+      </div>
+      <div class="d-flex align-center ml-15">
+        <span>自定义日期</span>
+        <div class="ml-5">
+          <date-picker v-model="date" :options="{ range: true, clearable: true, placeholder: '请选择要查看的时间范围' }"></date-picker>
+        </div>
+      </div>
+    </div>
+    <div class="mt-10">
+      <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#f7f8fa">
+        <v-tab :value="1">数据概况</v-tab>
+      </v-tabs>
+      <Overview class="mt-5"></Overview>
+    </div>
+    <div class="my-10">
+      <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#f7f8fa">
+        <v-tab :value="1">应聘简历分析</v-tab>
+      </v-tabs>
+      <ResumeAnalysis class="mt-5"></ResumeAnalysis>
+    </div>
+    <div>
+      <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#f7f8fa">
+        <v-tab :value="1">每日统计</v-tab>
+      </v-tabs>
+      <DailyPage class="mt-5"></DailyPage>
+    </div>
+  </v-card>
 </template>
 
 <script setup>
 defineOptions({ name: 'overallAnalysis'})
+import { ref } from 'vue'
+import Overview from './components/overview.vue'
+import DailyPage from './components/daily.vue'
+import ResumeAnalysis from './components/resume.vue'
+
+const tab = ref(1)
+const date = ref(null)
+const current = ref(1)
+const list = ['最近7天', '上个月', '上季度']
+
 </script>
 
 <style scoped lang="scss">
-
+.after {
+  height: 36px;
+  background-color: #f2f3f5;
+  border-radius: 4px;
+  padding: 1.5px;
+}
+.item {
+  line-height: 31px;
+  padding: 0 12px;
+  margin: 1.5px;
+  cursor: pointer;
+}
+.active {
+  position: relative;
+  color: var(--v-primary-base);
+  background-color: #fff;
+  display: inline-block;
+  margin: 1.5px;
+  height: 30px;
+  border-radius: 4px;
+  transition: all .1s linear;
+}
 </style>

+ 0 - 188
src/views/recruit/personal/PersonalCenter/components/interestedMe.vue

@@ -1,188 +0,0 @@
-<template>
-  <div>
-    <div v-if="list.length">
-      <div class="position-item mb-3 job-closed" v-for="(val, i) in list" :key="i" @mouseenter="handleMouseEnter(val)" @mouseleave="val.active = false">
-        <div class="info-header">
-          <div v-if="val.active" class="header-btn">
-            <v-btn class="half-button" color="primary" size="small">继续沟通</v-btn>
-            <v-btn v-if="props.tab === 4" class="half-button ml-3" color="primary" size="small">取消感兴趣</v-btn>
-          </div>
-          <div class="img-box">
-            <v-avatar :image="val.contact.avatars || 'https://minio.citupro.com/dev/menduner/7.png'" size="x-small"></v-avatar>
-            <span class="name">
-              <span class="mx-3">{{ val.contact.name }}</span>
-              <span class="gray">{{ val.contact.postNameCn }}</span>
-            </span>
-          </div>
-        </div>
-        <div class="info-content">
-          <div class="job-info">
-            <div class="job-name cursor-pointer">
-              <span class="mr-3 info-name">{{ val.name }}</span>
-              <span>[{{ val.areaName }}]</span>
-            </div>
-            <div class="job-other">
-              <span class="salary">{{ val.payFrom }}-{{ val.payTo }}k</span>
-              <v-chip class="mx-3" color="primary" label size="small">{{ val.expName }}</v-chip>
-              <v-chip color="primary" label size="small">{{ val.eduName }}</v-chip>
-            </div>
-          </div>
-          <div v-if="props.tab === 3" class="interview-info">
-            <div>面试时间:2022.03.15 17:00</div>
-            <div class="mt-3">面试地点:先烈中路100号大院203室</div>
-          </div>
-          <div v-else class="company-info">
-            <v-img width="50" height="50" :src="val.contact.avatars || 'https://minio.citupro.com/dev/menduner/7.png'"></v-img>
-            <div class="ml-3">
-              <div class="cursor-pointer info-name">{{ val.enterprise.name }}</div>
-              <div class="mt-3">
-                <v-chip color="primary" label size="small" class="mr-3" v-for="k in desc" :key="k">{{ val.enterprise[k] }}</v-chip>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div v-else>
-      <Empty></Empty>
-    </div>
-  </div>
-</template>
-
-<script setup>
-// 对我感兴趣
-defineOptions({ name: 'position-interested-in-me' })
-import { ref } from 'vue'
-// import { dealDictArrayData, dealDictObjData } from '@/utils/position'
-import Empty from '@/components/Empty'
-
-const props = defineProps({
-  tab: {
-    type: Number,
-    default: 0
-  }
-})
-
-// const items = ref([])
-// const page = ref({
-//   pageNo: 1,
-//   pageSize: 10
-// })
-const list = ref([
-  // {
-  //   contact: {
-  //     name: '肖女士',
-  //     avatars: 'https://cdn.vuetifyjs.com/images/john.jpg',
-  //     postNameCn: '人事经理'
-  //   },
-  //   name: '前端开发工程师',
-  //   areaName: '北京·石景山区·八大处',
-  //   payFrom: 15,
-  //   payTo: 18,
-  //   expName: '3-5年',
-  //   eduName: '本科',
-  //   active: false,
-  //   enterprise: {
-  //     name: '广州辞图科技有限公司',
-  //     industryName: '互联网',
-  //     scaleName: '0-20人',
-  //     financingName: '未融资'
-  //   }
-  // },
-  // {
-  //   contact: {
-  //     name: '肖女士',
-  //     avatars: 'https://cdn.vuetifyjs.com/images/john.jpg',
-  //     postNameCn: '人事经理'
-  //   },
-  //   name: '前端开发工程师',
-  //   areaName: '北京·石景山区·八大处',
-  //   payFrom: 15,
-  //   payTo: 18,
-  //   expName: '3-5年',
-  //   eduName: '本科',
-  //   active: false,
-  //   enterprise: {
-  //     name: '广州辞图科技有限公司',
-  //     industryName: '互联网',
-  //     scaleName: '0-20人',
-  //     financingName: '未融资'
-  //   }
-  // }
-])
-
-const desc = ['industryName', 'financingName', 'scaleName']
-
-const handleMouseEnter = (val) => {
-  if (props.tab !==3 ) val.active = true
-}
-
-</script>
-
-<style scoped lang="scss">
-.position-item {
-  height: 144px;
-  background-color: #fff;
-  border-radius: 12px;
-  &:hover {
-    box-shadow: 0 16px 40px 0 rgba(153, 153, 153, .3);
-  }
-  .info-header {
-    height: 48px;
-    background: linear-gradient(90deg,#f5fcfc,#fcfbfa);
-    .img-box {
-      padding: 12px 24px;
-      .name {
-        color: var(--color-222);
-        font-weight: 400;
-        font-size: 13px;
-        .gray {
-          color: var(--color-666);
-        }
-      }
-    }
-    .header-btn {
-      padding: 10px 10px 0 0;
-      float: right;
-      .v-btn {
-        z-index: 1;
-      }
-    }
-  }
-  .info-content {
-    display: flex;
-    padding: 16px 24px;
-    justify-content: space-between;
-    .job-info {
-      width: 430px;
-      min-width: 430px;
-      max-width: 430px;
-      font-weight: 500;
-      font-size: 16px;
-      .job-name {
-        height: 22px;
-        line-height: 22px;
-        color: var(--color-222);
-        margin-bottom: 12px;
-      }
-      .job-other {
-        color: var(--v-error-base);
-        height: 22px;
-        line-height: 22px;
-      }
-    }
-    .company-info {
-      display: flex;
-      align-items: center
-    }
-    .interview-info {
-      color: var(--color-333);
-      font-size: 15px;
-    }
-  }
-}
-
-.info-name:hover {
-  color: var(--v-primary-base);
-}
-</style>

+ 115 - 152
src/views/recruit/personal/PersonalCenter/components/seenMe.vue

@@ -1,51 +1,41 @@
 <template>
   <div>
-    <div v-if="list.length">
-      <div class="position-item mb-3 job-closed" v-for="(val, i) in list" :key="i" @mouseenter="handleMouseEnter(val)" @mouseleave="val.active = false">
-        <div class="info-header">
-          <div v-if="val.active" class="header-btn">
-            <v-btn class="half-button" color="primary" size="small">继续沟通</v-btn>
-            <v-btn v-if="props.tab === 4" class="half-button ml-3" color="primary" size="small">取消感兴趣</v-btn>
-          </div>
-          <div class="img-box">
-            <v-avatar :image="val.contact.avatars || 'https://minio.citupro.com/dev/menduner/7.png'" size="x-small"></v-avatar>
-            <span class="name">
-              <span class="mx-3">{{ val.contact.name }}</span>
-              <span class="gray">{{ val.contact.postNameCn }}</span>
-            </span>
+    <div v-if="items.length" class="mt-3">
+      <div class="sub-li mb-3" v-for="item in items" :key="item.id" @mouseenter="item.active = true" @mouseleave="item.active = false">
+        <div class="company-info-top" @click="handleClickEnterprise(item, 'briefIntroduction')">
+          <div class="company-info">
+            <div class="float-left mr-5">
+              <v-img :src="item.enterprise.logoUrl || 'https://minio.citupro.com/dev/menduner/company-avatar.png'" :alt="item.enterprise.anotherName" :width="40" style="height: 40px;border-radius: 4px;"/>
+            </div>
+            <h3 :class="{'default-active': item.active }">{{ item.enterprise.anotherName }}</h3>
+            <p>{{ item.enterprise.financingName }}<span class="mx-2">|</span>{{ item.enterprise.industryName }}<span class="mx-2">|</span>{{ item.enterprise.scaleName }}</p>
           </div>
         </div>
-        <div class="info-content">
-          <div class="job-info">
-            <div class="job-name cursor-pointer">
-              <span class="mr-3 info-name">{{ val.name }}</span>
-              <span>[{{ val.areaName }}]</span>
-            </div>
-            <div class="job-other">
-              <span class="salary">{{ val.payFrom }}-{{ val.payTo }}k</span>
-              <v-chip class="mx-3" color="primary" label size="small">{{ val.expName }}</v-chip>
-              <v-chip color="primary" label size="small">{{ val.eduName }}</v-chip>
+        <div class="company-info-bottom">
+          <div class="chipBox">
+            <div class="d-inline-block" v-for="(val, i) in item.enterprise.welfareList" :key="i">
+              <span>{{ val }}</span>
+              <span class="mx-1" v-if="i !== item.enterprise.welfareList.length - 1">|</span>
             </div>
           </div>
-          <div v-if="props.tab === 3" class="interview-info">
-            <div>面试时间:2022.03.15 17:00</div>
-            <div class="mt-3">面试地点:先烈中路100号大院203室</div>
-          </div>
-          <div v-else class="company-info">
-            <v-img width="50" height="50" :src="val.contact.avatars || 'https://minio.citupro.com/dev/menduner/7.png'"></v-img>
-            <div class="ml-3">
-              <div class="cursor-pointer info-name">{{ val.enterprise.name }}</div>
-              <div class="mt-3">
-                <v-chip color="primary" label size="small" class="mr-3" v-for="k in desc" :key="k">{{ val.enterprise[k] }}</v-chip>
-              </div>
-            </div>
+          <div class="footer-right">
+            <v-avatar size="x-small" :image="item.contact.avatar || 'https://minio.citupro.com/dev/menduner/7.png'"></v-avatar>
+            <span class="mx-2 textColor666">
+              {{ item.contact.name }}
+              <span v-if="item?.contact?.name && item?.post?.nameCn">|</span>
+              {{ item?.post?.nameCn }}
+            </span>
           </div>
         </div>
       </div>
+      <CtPagination
+        :total="total"
+        :page="page.pageNo"
+        :limit="page.pageSize"
+        @handleChange="handleChangePage"
+      ></CtPagination>
     </div>
-    <div v-else>
-      <Empty></Empty>
-    </div>
+    <Empty v-else></Empty>
   </div>
 </template>
 
@@ -53,136 +43,109 @@
 // 看过我
 defineOptions({ name: 'position-seen-me' })
 import { ref } from 'vue'
-// import { dealDictArrayData, dealDictObjData } from '@/utils/position'
+import { getInterestedMePage } from '@/api/recruit/personal/personalCenter'
+import { dealDictObjData } from '@/utils/position'
 import Empty from '@/components/Empty'
 
-const props = defineProps({
-  tab: {
-    type: Number,
-    default: 0
-  }
+const total = ref(0)
+const items = ref([])
+const page = ref({
+  pageNo: 1,
+  pageSize: 10
 })
 
-// const items = ref([])
-// const page = ref({
-//   pageNo: 1,
-//   pageSize: 10
-// })
-const list = ref([
-  // {
-  //   contact: {
-  //     name: '肖女士',
-  //     avatars: 'https://cdn.vuetifyjs.com/images/john.jpg',
-  //     postNameCn: '人事经理'
-  //   },
-  //   name: '前端开发工程师',
-  //   areaName: '北京·石景山区·八大处',
-  //   payFrom: 15,
-  //   payTo: 18,
-  //   expName: '3-5年',
-  //   eduName: '本科',
-  //   active: false,
-  //   enterprise: {
-  //     name: '广州辞图科技有限公司',
-  //     industryName: '互联网',
-  //     scaleName: '0-20人',
-  //     financingName: '未融资'
-  //   }
-  // },
-  // {
-  //   contact: {
-  //     name: '肖女士',
-  //     avatars: 'https://cdn.vuetifyjs.com/images/john.jpg',
-  //     postNameCn: '人事经理'
-  //   },
-  //   name: '前端开发工程师',
-  //   areaName: '北京·石景山区·八大处',
-  //   payFrom: 15,
-  //   payTo: 18,
-  //   expName: '3-5年',
-  //   eduName: '本科',
-  //   active: false,
-  //   enterprise: {
-  //     name: '广州辞图科技有限公司',
-  //     industryName: '互联网',
-  //     scaleName: '0-20人',
-  //     financingName: '未融资'
-  //   }
-  // }
-])
-
-const desc = ['industryName', 'financingName', 'scaleName']
+const getData = async () => {
+  const res = await getInterestedMePage(page.value)
+  items.value = res.list.map(e => {
+    e.enterprise = dealDictObjData({}, e.enterprise)
+    e.active = false
+    return e
+  })
+  total.value = res.total
+}
+getData()
 
-const handleMouseEnter = (val) => {
-  if (props.tab !==3 ) val.active = true
+const handleClickEnterprise = (item, key) => {
+  window.open(`/recruit/personal/company/details/${item.enterprise.id}?key=${key}`)
 }
 
 </script>
 
 <style scoped lang="scss">
-.position-item {
-  height: 144px;
-  background-color: #fff;
+.sub-li {
+  position: relative;
+  height: 130px;
   border-radius: 12px;
+  padding: 0;
+  overflow: hidden;
+  transition: all .2s linear;
+  background-color: #fff;
+  cursor: pointer;
+  &:nth-child(4n) {
+    margin-right: 0;
+  }
   &:hover {
     box-shadow: 0 16px 40px 0 rgba(153, 153, 153, .3);
   }
-  .info-header {
-    height: 48px;
-    background: linear-gradient(90deg,#f5fcfc,#fcfbfa);
-    .img-box {
-      padding: 12px 24px;
-      .name {
-        color: var(--color-222);
-        font-weight: 400;
-        font-size: 13px;
-        .gray {
-          color: var(--color-666);
-        }
-      }
-    }
-    .header-btn {
-      padding: 10px 10px 0 0;
-      float: right;
-      .v-btn {
-        z-index: 1;
-      }
-    }
+}
+.textColor666 { 
+  color: var(--color-666);
+  font-size: 14px;
+}
+.company-info {
+  float: left;
+  margin-left: 16px;
+  width: 282px;
+}
+.company-info-top {
+  display: flex;
+  height: 76px;
+  padding: 16px 20px;
+  overflow: hidden;
+  justify-content: space-between;
+}
+.company-info h3 {
+  height: 22px;
+  font-size: 16px;
+  font-weight: 400;
+  color: var(--color-222);
+  line-height: 22px;
+  margin: 0 0 4px 0;
+  padding: 0;
+  max-width: 100%;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+.company-info p {
+  height: 18px;
+  font-size: 13px;
+  font-weight: 400;
+  color: var(--color-999);
+  line-height: 18px;
+}
+.company-info-bottom {
+  display: flex;
+  width: 100%;
+  padding: 16px 20px;
+  justify-content: space-between;
+  background-color: #f8fcfb;
+  .chipBox {
+    width: 70%;
+    min-width: 70%;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    font-size: 13px; 
+    color: var(--color-999);
   }
-  .info-content {
-    display: flex;
-    padding: 16px 24px;
-    justify-content: space-between;
-    .job-info {
-      width: 430px;
-      min-width: 430px;
-      max-width: 430px;
-      font-weight: 500;
-      font-size: 16px;
-      .job-name {
-        height: 22px;
-        line-height: 22px;
-        color: var(--color-222);
-        margin-bottom: 12px;
-      }
-      .job-other {
-        color: var(--v-error-base);
-        height: 22px;
-        line-height: 22px;
-      }
-    }
-    .company-info {
-      display: flex;
-      align-items: center
-    }
-    .interview-info {
-      color: var(--color-333);
-      font-size: 15px;
+  .position {
+    color: var(--color-666);
+    font-size: 14px;
+    cursor: pointer;
+    &:hover {
+      color: var(--v-primary-base);
     }
   }
 }
-
-.info-name:hover {
-  color: var(--v-primary-base);
-}
 </style>

+ 0 - 2
src/views/recruit/personal/PersonalCenter/dynamic/left.vue

@@ -73,7 +73,6 @@ import communication from '../components/communication.vue'
 import delivery from '../components/delivery.vue'
 import interview from '../components/interview/index.vue'
 import interested from '../components/interested.vue'
-import interestedMe from '../components/interestedMe.vue'
 import seenMe from '../components/seenMe.vue'
 
 const { t } = useI18n()
@@ -82,7 +81,6 @@ const list = [
   { title: t('position.delivered'), path: delivery },
   { title: t('position.interview'), path: interview },
   { title: t('position.interested'), path: interested },
-  { title: t('position.interestedInMe'), path: interestedMe },
   { title: t('position.haveSeenMe'), path: seenMe }
 ]
 const tab = ref(1)

+ 1 - 1
src/views/recruit/personal/company/components/companyItem.vue

@@ -7,7 +7,7 @@
         </div>
         <div class="company-info">
           <h3 :class="{'default-active': item.active }">{{ item.anotherName }}</h3>
-          <p>{{ item.financingName }}<span class="mx-2">|</span>{{ item.industryName }}</p>
+          <p>{{ item.financingName }}<span class="mx-2" v-if="item.financingName && item.industryName">|</span>{{ item.industryName }}</p>
         </div>
       </div>
       <div class="company-info-bottom">

+ 3 - 4
src/views/recruit/personal/remuse/components/educationExp.vue

@@ -41,7 +41,7 @@
           <span class="color6 font15">{{ getText(item.educationSystemType, dictItemsObj.educationSystemType) }}</span>
         </div>
         <div class="level3">
-          <span class="color6 font15">在校经历:{{ item.content }}</span>
+          <span class="color6 font15">在校经历:{{ item.content || '暂无描述' }}</span>
         </div>
       </div>
     </div>
@@ -186,9 +186,8 @@ const formItems = ref({
       rows: 5,
       resize: true,
       counter: 1600,
-      label: '在校经历 *',
-      outlined: true,
-      rules: [v => !!v || '请输入在校经历']
+      label: '在校经历',
+      outlined: true
     },
   ]
 })

+ 3 - 3
src/views/recruit/personal/remuse/components/jobIntention.vue

@@ -116,7 +116,7 @@ const items = ref({
     {
       slotName: 'industryIdList',
       key: 'industryIdList',
-      value: '不限',
+      value: '',
       outlined: true,
       label: '期望行业 *',
       col: 6,
@@ -195,7 +195,7 @@ const handleJobClickItem = (list, name) => {
 // 行业类型
 let currentSelect = reactive([])
 const handleIndustry = (list, arr) => {
-  if (!list.length) return setValue('industryIdList', '不限')
+  if (!list.length) return setValue('industryIdList', '')
   query.industryIdList = list
   currentSelect = arr
   const str = arr.map(e => e.nameCn).join('、')
@@ -211,7 +211,7 @@ const handleArea = (list, name) => {
 
 const resetForm = () => {
   items.value.options.forEach(e => {
-    if (e.key === 'industryIdList') e.value = '不限'
+    if (e.key === 'industryIdList') e.value = ''
     else e.value = null
   })
   editId.value = null

+ 2 - 6
src/views/recruit/personal/remuse/components/trainingExperience.vue

@@ -34,7 +34,7 @@
           </div>
           <div>
             <span class="label-title">培训描述:</span>
-            <span class="label-title">{{ k.content }}</span>
+            <span class="label-title">{{ k.content || '暂无描述' }}</span>
           </div>
         </div>
       </div>
@@ -106,15 +106,11 @@ const items = ref({
       type: 'textarea',
       key: 'content',
       value: '',
-      label: '培训描述 *',
+      label: '培训描述',
       rows: 5,
       resize: true,
       counter: 2000,
       rules: [
-        value => {
-          if (value) return true
-          return '请输入培训描述'
-        },
         value => {
           if (value?.length <= 200) return true
           return '请输入2-200个字符'

+ 0 - 1
src/views/recruit/personal/taskCenter/components/signIn.vue

@@ -87,7 +87,6 @@ const handleSignIn = async () => {
     signLoading.value = false
 
     // 更新积分数
-    await integralRef.value.getIntegral()
     await userStore.getUserAccountInfo()
   }, 1000)
 }

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio