studentDetails.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <!-- 学生详情 -->
  2. <template>
  3. <div v-if="Object.keys(info).length" class="d-flex justify-center flex-column align-center mb-8">
  4. <v-card class="pa-8">
  5. <!-- 头像院系 -->
  6. <baseInfo class="mt-5" :data="info"></baseInfo>
  7. <!-- 基本信息 -->
  8. <other :data="info"></other>
  9. </v-card>
  10. <!-- 实习情况 -->
  11. <v-card class="my-3 pa-5">
  12. <div class="resume-header">
  13. <div class="resume-title">实习情况</div>
  14. </div>
  15. <CtTable
  16. class="mt-3"
  17. :items="practice"
  18. :headers="headers"
  19. :elevation="0"
  20. :loading="false"
  21. :is-tools="false"
  22. :items-per-page="-1"
  23. :showPage="false"
  24. itemKey="id"
  25. >
  26. <template #enterpriseName="{ item }">
  27. <div class="d-flex align-center defaultLink" @click="handleEnterprise(item.enterpriseId)">
  28. <v-avatar size="40" :image="item.enterprise.logoUrl || 'https://minio.citupro.com/dev/menduner/company-avatar.png'"></v-avatar>
  29. <span class="ml-3">{{ formatName(item.enterprise.anotherName || item.enterprise.name) }}</span>
  30. </div>
  31. </template>
  32. <template #status="{ item }">
  33. {{ statusList.find(e => e.value === item.status)?.label }}
  34. </template>
  35. </CtTable>
  36. </v-card>
  37. </div>
  38. <Loading :visible="loading"></Loading>
  39. </template>
  40. <script setup>
  41. defineOptions({name: 'studentList-student-details'})
  42. import baseInfo from './components/baseInfo.vue'
  43. import other from './components/other.vue'
  44. import { ref, onMounted } from 'vue'
  45. import { getStudentDetailsById, getInternshipById } from '@/api/school'
  46. import Snackbar from '@/plugins/snackbar'
  47. import { useRoute } from 'vue-router';
  48. import { formatName } from '@/utils/getText'
  49. import { timesTampChange } from '@/utils/date'
  50. import { getDict } from '@/hooks/web/useDictionaries'
  51. const route = useRoute()
  52. // 获取人才详情
  53. const info = ref({})
  54. const loading = ref(false)
  55. const { id } = route.params
  56. const headers = [
  57. { title: '实习企业', key: 'enterpriseName', sortable: false },
  58. { title: '投递职位', key: 'jobName', sortable: false, value: item => formatName(item?.job?.name) },
  59. { title: '实习状态', key: 'status', sortable: false },
  60. { title: '开始时间', key: 'startTime', sortable: false, value: item => timesTampChange(item.startTime, 'Y-M-D') },
  61. { title: '结束时间', key: 'endTime', sortable: false, value: item => timesTampChange(item.startTime, 'Y-M-D') },
  62. ]
  63. // 获取学生实习情况
  64. const practice = ref([])
  65. const getPracticeRecord = async (userId) => {
  66. const data = await getInternshipById({ userId })
  67. practice.value = data || []
  68. }
  69. const getCvDetail = async () => {
  70. if (!id) {
  71. Snackbar.warning('缺少学生id')
  72. setTimeout(() => {
  73. window.close()
  74. }, 2000)
  75. return
  76. }
  77. loading.value = true
  78. const data = await getStudentDetailsById({ id })
  79. info.value = data || {}
  80. loading.value = false
  81. // 实习情况
  82. getPracticeRecord(data.userId)
  83. }
  84. const statusList = ref([])
  85. onMounted(async () => {
  86. // 状态字典
  87. const { data } = await getDict('student_practice_status')
  88. statusList.value = data || []
  89. getCvDetail()
  90. })
  91. // 跳转企业详情
  92. const handleEnterprise = (enterpriseId) => {
  93. if (!enterpriseId) return
  94. window.open(`/recruit/personal/company/details/${enterpriseId}?key=briefIntroduction`)
  95. }
  96. </script>
  97. <style lang="scss" scoped>
  98. .v-card {
  99. width: 940px;
  100. }
  101. </style>