|
@@ -6,7 +6,7 @@
|
|
<div v-for="(val, index) in statistics" :key="index" class="statistics-card pa-5">
|
|
<div v-for="(val, index) in statistics" :key="index" class="statistics-card pa-5">
|
|
<div class="color-666">{{ val.label }}</div>
|
|
<div class="color-666">{{ val.label }}</div>
|
|
<div class="">
|
|
<div class="">
|
|
- <span class="value font-weight-bold color-primary">{{ val.value }}</span>
|
|
|
|
|
|
+ <span class="value font-weight-bold color-primary">{{ val.number }}</span>
|
|
<span class="color-999 font-size-14">人</span>
|
|
<span class="color-999 font-size-14">人</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@@ -32,14 +32,14 @@
|
|
<span class="ml-3 color-primary cursor-pointer" @click="handleEnterprise(item.id)">{{ formatName(item.anotherName || item.name) }}</span>
|
|
<span class="ml-3 color-primary cursor-pointer" @click="handleEnterprise(item.id)">{{ formatName(item.anotherName || item.name) }}</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
- <template #internshipNumber="{ item }">
|
|
|
|
- <span class="color-primary cursor-pointer" @click="handleDetail(item, '实习中')">{{ item.internshipNumber || 0 }}人</span>
|
|
|
|
|
|
+ <template #inProgressNum="{ item }">
|
|
|
|
+ <span class="color-primary cursor-pointer" @click="handleDetail(item, '实习中', '1', item.inProgressNum)">{{ item.inProgressNum || 0 }}人</span>
|
|
</template>
|
|
</template>
|
|
- <template #waitInternshipNumber="{ item }">
|
|
|
|
- <span class="color-primary cursor-pointer" @click="handleDetail(item, '等待实习')">{{ item.waitInternshipNumber || 0 }}人</span>
|
|
|
|
|
|
+ <template #waitingNum="{ item }">
|
|
|
|
+ <span class="color-primary cursor-pointer" @click="handleDetail(item, '等待实习', '0', item.waitingNum)">{{ item.waitingNum || 0 }}人</span>
|
|
</template>
|
|
</template>
|
|
- <template #internshipSuccessNumber="{ item }">
|
|
|
|
- <span class="color-primary cursor-pointer" @click="handleDetail(item, '结束实习')">{{ item.internshipSuccessNumber || 0 }}人</span>
|
|
|
|
|
|
+ <template #endNum="{ item }">
|
|
|
|
+ <span class="color-primary cursor-pointer" @click="handleDetail(item, '结束实习', '2', item.endNum)">{{ item.endNum || 0 }}人</span>
|
|
</template>
|
|
</template>
|
|
<template #actions="{ item }">
|
|
<template #actions="{ item }">
|
|
<v-btn v-if="!item?.recommendationLetter" color="primary" variant="text" @click="handleUploadLetter(item.id)">上传推荐信</v-btn>
|
|
<v-btn v-if="!item?.recommendationLetter" color="primary" variant="text" @click="handleUploadLetter(item.id)">上传推荐信</v-btn>
|
|
@@ -61,79 +61,65 @@
|
|
itemKey="id"
|
|
itemKey="id"
|
|
@pageHandleChange="handleChangeDrillPage"
|
|
@pageHandleChange="handleChangeDrillPage"
|
|
>
|
|
>
|
|
|
|
+ <template #enterpriseName="{ item }">
|
|
|
|
+ {{ formatName(item.enterprise.anotherName || item.enterprise.name) }}
|
|
|
|
+ </template>
|
|
|
|
+ <template #jobName="{ item }">
|
|
|
|
+ {{ formatName(item.job.name) }}
|
|
|
|
+ </template>
|
|
<template #studentName="{ item }">
|
|
<template #studentName="{ item }">
|
|
<div class="d-flex align-center">
|
|
<div class="d-flex align-center">
|
|
- <v-avatar size="40" :image="getUserAvatar(item.headImg, item.teacherSex)"></v-avatar>
|
|
|
|
- <span class="ml-3 color-primary cursor-pointer" @click="handleToStudentDetail(item.studentId)">{{ item.studentName || item.phone }}</span>
|
|
|
|
|
|
+ <v-avatar size="40" :image="getUserAvatar(item.person.avatar, item.person.sex)"></v-avatar>
|
|
|
|
+ <span class="ml-3 color-primary cursor-pointer" @click="handleToStudentDetail(item.studentId)">{{ item.person?.name || item.person?.phone }}</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
</CtTable>
|
|
</CtTable>
|
|
</CtDialog>
|
|
</CtDialog>
|
|
-
|
|
|
|
- <v-navigation-drawer v-model="showDetail" absolute location="right" rounded temporary width="700" class="pa-5">
|
|
|
|
- 111
|
|
|
|
- </v-navigation-drawer>
|
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
defineOptions({name: 'studentList-internship-situation'})
|
|
defineOptions({name: 'studentList-internship-situation'})
|
|
import { ref, onMounted } from 'vue'
|
|
import { ref, onMounted } from 'vue'
|
|
import { getUserAvatar } from '@/utils/avatar'
|
|
import { getUserAvatar } from '@/utils/avatar'
|
|
-import { getStudentPage } from '@/api/recruit/enterprise/student'
|
|
|
|
-import { dealDictObjData } from '@/utils/position'
|
|
|
|
|
|
+import { dealDictArrayData } from '@/utils/position'
|
|
import { formatName } from '@/utils/getText'
|
|
import { formatName } from '@/utils/getText'
|
|
import Snackbar from '@/plugins/snackbar'
|
|
import Snackbar from '@/plugins/snackbar'
|
|
-import { studentPracticeStatistics } from '@/api/school'
|
|
|
|
|
|
+import { getDict } from '@/hooks/web/useDictionaries'
|
|
|
|
+import { timesTampChange } from '@/utils/date'
|
|
|
|
+import { studentPracticeRecordCount, studentPracticePage, studentPracticeRecordPage } from '@/api/school'
|
|
|
|
|
|
-const statistics = ref([
|
|
|
|
- { label: '等待实习', value: 0, key: 'waitInternshipNumber' },
|
|
|
|
- { label: '实习中', value: 1, key: 'internshipNumber' },
|
|
|
|
- { label: '实习结束', value: 0, key: 'internshipSuccessNumber' }
|
|
|
|
-])
|
|
|
|
|
|
+const statistics = ref([])
|
|
|
|
|
|
const loading = ref(false)
|
|
const loading = ref(false)
|
|
const total = ref(0)
|
|
const total = ref(0)
|
|
|
|
+const schoolInfo = ref(localStorage.getItem('schoolInfo') ? JSON.parse(localStorage.getItem('schoolInfo')) : {})
|
|
const query = ref({
|
|
const query = ref({
|
|
pageNo: 1,
|
|
pageNo: 1,
|
|
pageSize: 10,
|
|
pageSize: 10,
|
|
- startTime: null
|
|
|
|
|
|
+ schoolId: schoolInfo.value.schoolId
|
|
})
|
|
})
|
|
-const tableData = ref([
|
|
|
|
- {
|
|
|
|
- "id": 1,
|
|
|
|
- "name": "门墩儿信息科技有限公司",
|
|
|
|
- "anotherName": "门墩儿",
|
|
|
|
- "industryId": "1829087620475494402",
|
|
|
|
- "industryName": '互联网',
|
|
|
|
- "scale": "0",
|
|
|
|
- "scaleName": '0-20人',
|
|
|
|
- "logoUrl": "https://minio.menduner.com/dev/1e6893918ef378ca280360078dfe74ade10b27101c89865261824b46de7d34a6.png",
|
|
|
|
- internshipNumber: 2,
|
|
|
|
- internshipSuccessNumber: 0,
|
|
|
|
- waitInternshipNumber: 0
|
|
|
|
- }
|
|
|
|
-])
|
|
|
|
-const schoolInfo = ref(localStorage.getItem('schoolInfo') ? JSON.parse(localStorage.getItem('schoolInfo')) : {})
|
|
|
|
|
|
+const tableData = ref([])
|
|
|
|
|
|
const headers = [
|
|
const headers = [
|
|
{ title: '实习企业', key: 'enterpriseName', sortable: false },
|
|
{ title: '实习企业', key: 'enterpriseName', sortable: false },
|
|
{ title: '所在行业', key: 'industryName', sortable: false },
|
|
{ title: '所在行业', key: 'industryName', sortable: false },
|
|
{ title: '企业规模', key: 'scaleName', sortable: false },
|
|
{ title: '企业规模', key: 'scaleName', sortable: false },
|
|
- { title: '实习中', key: 'internshipNumber', sortable: false },
|
|
|
|
- { title: '实习结束', key: 'internshipSuccessNumber', sortable: false },
|
|
|
|
- { title: '等待实习', key: 'waitInternshipNumber', sortable: false },
|
|
|
|
|
|
+ { title: '等待实习', key: 'waitingNum', sortable: false },
|
|
|
|
+ { title: '实习中', key: 'inProgressNum', sortable: false },
|
|
|
|
+ { title: '实习结束', key: 'endNum', sortable: false },
|
|
]
|
|
]
|
|
|
|
|
|
// 学生列表
|
|
// 学生列表
|
|
const getList = async () => {
|
|
const getList = async () => {
|
|
loading.value = true
|
|
loading.value = true
|
|
try {
|
|
try {
|
|
- const result = await getStudentPage(query.value)
|
|
|
|
- tableData.value = result?.list.map(e => {
|
|
|
|
- e.enterprise = dealDictObjData({}, e.enterprise)
|
|
|
|
- e.job = dealDictObjData({}, e.job)
|
|
|
|
- return e
|
|
|
|
- })
|
|
|
|
|
|
+ const result = await studentPracticePage(query.value)
|
|
|
|
+ if (!result?.list || result?.list.length === 0) {
|
|
|
|
+ tableData.value = []
|
|
|
|
+ total.value = 0
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ tableData.value = dealDictArrayData([], result.list)
|
|
total.value = result?.total || 0
|
|
total.value = result?.total || 0
|
|
} finally {
|
|
} finally {
|
|
loading.value = false
|
|
loading.value = false
|
|
@@ -143,20 +129,19 @@ const getList = async () => {
|
|
// 数值统计
|
|
// 数值统计
|
|
const getStatistics = async () => {
|
|
const getStatistics = async () => {
|
|
try {
|
|
try {
|
|
- const data = await studentPracticeStatistics({ schoolId: schoolInfo.value?.school?.schoolId })
|
|
|
|
- console.log(data, 'data')
|
|
|
|
- // statistics.value.forEach(e => {
|
|
|
|
- // const obj = data.find(val => val.key === e.value)
|
|
|
|
- // e.count = obj ? obj.value : 0
|
|
|
|
- // })
|
|
|
|
|
|
+ const data = await studentPracticeRecordCount({ schoolId: schoolInfo.value?.schoolId })
|
|
|
|
+ statistics.value.forEach(e => {
|
|
|
|
+ const obj = data.find(val => val.key === e.value)
|
|
|
|
+ e.number = obj.value
|
|
|
|
+ })
|
|
} catch {}
|
|
} catch {}
|
|
}
|
|
}
|
|
|
|
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
- // const { data } = await getDict('student_practice_status')
|
|
|
|
- // statistics.value = data
|
|
|
|
- // getStatistics()
|
|
|
|
- // getList()
|
|
|
|
|
|
+ const { data } = await getDict('student_practice_status')
|
|
|
|
+ statistics.value = data
|
|
|
|
+ getStatistics()
|
|
|
|
+ getList()
|
|
})
|
|
})
|
|
|
|
|
|
const handleChangePage = (val) => {
|
|
const handleChangePage = (val) => {
|
|
@@ -174,51 +159,55 @@ const handleEnterprise = (id) => {
|
|
const drill = ref({
|
|
const drill = ref({
|
|
total: 0,
|
|
total: 0,
|
|
query: {
|
|
query: {
|
|
- size: 10,
|
|
|
|
- current: 1
|
|
|
|
|
|
+ pageSize: 10,
|
|
|
|
+ pageNo: 1,
|
|
|
|
+ schoolId: schoolInfo.value.schoolId
|
|
},
|
|
},
|
|
title: '学生列表',
|
|
title: '学生列表',
|
|
show: false,
|
|
show: false,
|
|
- list: [{
|
|
|
|
- studentName: '张三',
|
|
|
|
- enterpriseName: '北京字节跳动科技有限公司',
|
|
|
|
- phone: '12345678901',
|
|
|
|
- schoolDepartmentName: '计算机科学与技术',
|
|
|
|
- majorName: '计算机科学与技术',
|
|
|
|
- schoolClassName: '2019级',
|
|
|
|
- studentNo: '2019111111',
|
|
|
|
- studentId: 1,
|
|
|
|
- teacherSex: '1',
|
|
|
|
- headImg: '',
|
|
|
|
- phone: '12345678901',
|
|
|
|
- studentPracticeStatus: '实习中'
|
|
|
|
- }],
|
|
|
|
|
|
+ list: [],
|
|
headers: [
|
|
headers: [
|
|
- { title: '状态', key: 'studentPracticeStatus', sortable: false },
|
|
|
|
{ title: '学生姓名', key: 'studentName', sortable: false },
|
|
{ title: '学生姓名', key: 'studentName', sortable: false },
|
|
{ title: '实习企业', key: 'enterpriseName', sortable: false },
|
|
{ title: '实习企业', key: 'enterpriseName', sortable: false },
|
|
- { title: '联系电话', key: 'phone', sortable: false },
|
|
|
|
- { title: '所属院系', key: 'schoolDepartmentName', sortable: false },
|
|
|
|
- { title: '所属专业', key: 'majorName', sortable: false },
|
|
|
|
- { title: '所在班级', key: 'schoolClassName', sortable: false },
|
|
|
|
- { title: '学号', key: 'studentNo', sortable: false },
|
|
|
|
|
|
+ { title: '实习职位', key: 'jobName', sortable: false },
|
|
|
|
+ { title: '开始时间', key: 'startTime', sortable: false, value: item => timesTampChange(item.startTime, 'Y-M-D') },
|
|
|
|
+ { title: '结束时间', key: 'endTime', sortable: false, value: item => timesTampChange(item.endTime, 'Y-M-D') },
|
|
|
|
+ { title: '学生联系电话', key: 'person.phone', sortable: false },
|
|
]
|
|
]
|
|
})
|
|
})
|
|
-// 学生列表
|
|
|
|
-const handleDetail = (item, label) => {
|
|
|
|
|
|
+
|
|
|
|
+const getDrillData = async () => {
|
|
|
|
+ try {
|
|
|
|
+ const data = await studentPracticeRecordPage(drill.value.query)
|
|
|
|
+ drill.value.list = data.list
|
|
|
|
+ drill.value.total = data.total
|
|
|
|
+ drill.value.show = true
|
|
|
|
+ } catch {}
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 钻取-学生列表
|
|
|
|
+const handleDetail = (item, label, status, value) => {
|
|
|
|
+ if (!value) return Snackbar.warning('暂无数据')
|
|
drill.value.title = `${item.anotherName} - 状态[${label}] - 学生列表`
|
|
drill.value.title = `${item.anotherName} - 状态[${label}] - 学生列表`
|
|
- drill.value.query.current = 1
|
|
|
|
- drill.value.show = true
|
|
|
|
|
|
+ drill.value.query.pageNo = 1
|
|
|
|
+ drill.value.query.status = status
|
|
|
|
+ drill.value.query.enterpriseId = item.id
|
|
|
|
+
|
|
|
|
+ getDrillData()
|
|
}
|
|
}
|
|
-const handleChangeDrillPage = (page) => {}
|
|
|
|
|
|
+const handleChangeDrillPage = (page) => {
|
|
|
|
+ drill.value.query.pageNo = page
|
|
|
|
+ getDrillData()
|
|
|
|
+}
|
|
|
|
+
|
|
const handleClose = () => {
|
|
const handleClose = () => {
|
|
drill.value.show = false
|
|
drill.value.show = false
|
|
- // drill.value.list = []
|
|
|
|
|
|
+ drill.value.list = []
|
|
}
|
|
}
|
|
|
|
|
|
-const showDetail = ref(false)
|
|
|
|
|
|
+// 学生详情
|
|
const handleToStudentDetail = (id) => {
|
|
const handleToStudentDetail = (id) => {
|
|
- showDetail.value = true
|
|
|
|
|
|
+ if (id) window.open(`/recruit/teacher/studentList/detail/${id}`)
|
|
}
|
|
}
|
|
</script>
|
|
</script>
|
|
|
|
|