244 lines
6.9 KiB
Vue
244 lines
6.9 KiB
Vue
<!--
|
|
- Copyright (c) 2018-2025, cyweb All rights reserved.
|
|
-
|
|
- Redistribution and use in source and binary forms, with or without
|
|
- modification, are permitted provided that the following conditions are met:
|
|
-
|
|
- Redistributions of source code must retain the above copyright notice,
|
|
- this list of conditions and the following disclaimer.
|
|
- Redistributions in binary form must reproduce the above copyright
|
|
- notice, this list of conditions and the following disclaimer in the
|
|
- documentation and/or other materials provided with the distribution.
|
|
- Neither the name of the pig4cloud.com developer nor the names of its
|
|
- contributors may be used to endorse or promote products derived from
|
|
- this software without specific prior written permission.
|
|
-
|
|
-->
|
|
|
|
<template>
|
|
<div class="layout-padding">
|
|
<div class="layout-padding-auto layout-padding-view">
|
|
<el-form :model="queryForm" inline class="mb-4" ref="searchFormRef">
|
|
<el-form-item label="入学年份" prop="grade">
|
|
<el-select v-model="queryForm.grade" filterable clearable placeholder="请选择入学年份">
|
|
<el-option v-for="item in gradeList" :key="item.year" :label="item.year" :value="item.year" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="学院" prop="deptCode">
|
|
<el-select v-model="queryForm.deptCode" filterable clearable placeholder="请选择学院">
|
|
<el-option v-for="item in deptList" :key="item.deptCode" :label="item.deptName" :value="item.deptCode" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="班级" prop="classCode">
|
|
<el-select v-model="queryForm.classCode" filterable clearable placeholder="请选择班级">
|
|
<el-option v-for="item in classData" :key="item.classCode" :label="item.classNo" :value="item.classCode" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button type="primary" icon="Search" @click="searchData">查询</el-button>
|
|
<el-button type="primary" plain icon="Refresh" class="ml10" @click="resetQuery">重置</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
|
|
<div class="mb15">
|
|
<el-button
|
|
v-if="hasAuth('recruit_newstucheckin_statistics_output')"
|
|
type="warning"
|
|
plain
|
|
icon="Download"
|
|
:loading="exportLoading"
|
|
@click="handleExportOut"
|
|
>
|
|
导出
|
|
</el-button>
|
|
</div>
|
|
|
|
<el-table
|
|
:data="tableData"
|
|
height="650"
|
|
show-summary
|
|
:summary-method="getSummaries"
|
|
stripe
|
|
border
|
|
v-loading="tableLoading"
|
|
:header-cell-style="{ 'text-align': 'center' }"
|
|
:cell-style="{ 'text-align': 'center' }"
|
|
class="el_table_job_fair_stu"
|
|
>
|
|
<el-table-column type="index" width="50" fixed label="序号" />
|
|
<el-table-column prop="deptName" label="学院" />
|
|
<el-table-column prop="classNo" label="班级" />
|
|
<el-table-column prop="classNum" label="预计报到人数" />
|
|
<el-table-column prop="checkInOk" label="已经报到" />
|
|
<el-table-column prop="postpone" label="推迟报到" />
|
|
<el-table-column prop="abandon" label="放弃报到" />
|
|
<el-table-column prop="missing" label="无法联系" />
|
|
<el-table-column prop="contact" label="未联系" />
|
|
<el-table-column prop="checkInRate" label="报到率" />
|
|
</el-table>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts" name="backSchoolCheckin-statistics">
|
|
import { ref, reactive, computed, onMounted } from 'vue';
|
|
import { useAuth } from '/@/hooks/auth';
|
|
import { useMessage } from '/@/hooks/message';
|
|
import { getDataStatistics } from '/@/api/recruit/newstucheckin';
|
|
import { getList } from '/@/api/recruit/recruitstudentplangroup';
|
|
import { getDeptList } from '/@/api/basic/basicclass';
|
|
import { queryAllClass } from '/@/api/basic/basicclass';
|
|
import axios from 'axios';
|
|
|
|
const { hasAuth } = useAuth();
|
|
|
|
// 消息提示 hooks
|
|
const message = useMessage();
|
|
|
|
// 引用
|
|
const searchFormRef = ref();
|
|
|
|
// 状态
|
|
const tableData = ref<any[]>([]);
|
|
const tableLoading = ref(false);
|
|
const exportLoading = ref(false);
|
|
const gradeList = ref<any[]>([]);
|
|
const deptList = ref<any[]>([]);
|
|
const classData = ref<any[]>([]);
|
|
|
|
// 查询表单
|
|
const queryForm = reactive({
|
|
grade: '',
|
|
deptCode: '',
|
|
classCode: '',
|
|
});
|
|
|
|
// 初始化
|
|
const init = async () => {
|
|
await Promise.all([getGradeData(), getDeptData(), getClassData()]);
|
|
getList();
|
|
};
|
|
|
|
// 查看所有入学年份
|
|
const getGradeData = async () => {
|
|
try {
|
|
const data = await getList();
|
|
gradeList.value = data.data || [];
|
|
} catch (error) {
|
|
console.error('获取入学年份失败', error);
|
|
}
|
|
};
|
|
|
|
// 查找所有二级学院
|
|
const getDeptData = async () => {
|
|
try {
|
|
const data = await getDeptList();
|
|
deptList.value = data.data || [];
|
|
} catch (error) {
|
|
console.error('获取学院列表失败', error);
|
|
}
|
|
};
|
|
|
|
// 查找所有班级
|
|
const getClassData = async () => {
|
|
try {
|
|
const data = await queryAllClass();
|
|
classData.value = data.data || [];
|
|
} catch (error) {
|
|
console.error('获取班级列表失败', error);
|
|
}
|
|
};
|
|
|
|
// 获取数据列表
|
|
const getList = async () => {
|
|
try {
|
|
tableLoading.value = true;
|
|
const response = await getDataStatistics(queryForm);
|
|
tableData.value = response.data || [];
|
|
} catch (error) {
|
|
console.error('获取数据失败', error);
|
|
} finally {
|
|
tableLoading.value = false;
|
|
}
|
|
};
|
|
|
|
// 查询
|
|
const searchData = () => {
|
|
getList();
|
|
};
|
|
|
|
// 重置查询
|
|
const resetQuery = () => {
|
|
searchFormRef.value?.resetFields();
|
|
queryForm.grade = '';
|
|
queryForm.deptCode = '';
|
|
queryForm.classCode = '';
|
|
getList();
|
|
};
|
|
|
|
// 导出
|
|
const handleExportOut = async () => {
|
|
try {
|
|
exportLoading.value = true;
|
|
const res = await axios({
|
|
method: 'post',
|
|
url: '/recruit/newstucheckin/exportDataStatistics',
|
|
data: queryForm,
|
|
responseType: 'blob',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
});
|
|
const blob = new Blob([res.data]);
|
|
const fileName = '新生报到统计.xls';
|
|
const elink = document.createElement('a');
|
|
elink.download = fileName;
|
|
elink.style.display = 'none';
|
|
elink.href = URL.createObjectURL(blob);
|
|
document.body.appendChild(elink);
|
|
elink.click();
|
|
URL.revokeObjectURL(elink.href);
|
|
document.body.removeChild(elink);
|
|
} catch (error: any) {
|
|
message.error(error.msg || '导出失败');
|
|
} finally {
|
|
exportLoading.value = false;
|
|
}
|
|
};
|
|
|
|
// 合计方法
|
|
const getSummaries = (param: any) => {
|
|
const { columns, data } = param;
|
|
const sums: any[] = [];
|
|
columns.forEach((column: any, index: number) => {
|
|
if (index === 0) {
|
|
sums[index] = '合计';
|
|
return;
|
|
}
|
|
if (index === 1 || index === 2) {
|
|
sums[index] = '';
|
|
return;
|
|
}
|
|
const values = data.map((item: any) => Number(item[column.property]));
|
|
if (!values.every((value: any) => isNaN(value))) {
|
|
sums[index] = values.reduce((prev: number, curr: any) => {
|
|
const value = Number(curr);
|
|
if (!isNaN(value)) {
|
|
return prev + curr;
|
|
} else {
|
|
return prev;
|
|
}
|
|
}, 0);
|
|
sums[index] += '';
|
|
}
|
|
});
|
|
return sums;
|
|
};
|
|
|
|
onMounted(() => {
|
|
init();
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped></style>
|