123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 |
- <script setup lang="ts">
- import {AreaChartParams, SchoolParams} from "@/api/areaboard/types";
- import {GradeList} from "@/api/grade/types";
- import {getGradeSelect} from "@/api/grade";
- import {getAreaSchool} from "@/api/areaboard";
- import {SchoolList} from "@/api/school/types";
- import ComboCharts from "@/views/admin/components/ComboCharts.vue";
- import {trimInput} from "@/utils";
- import {StudentItem, StudentParams} from "@/api/student/types";
- import {getStudentLists} from "@/api/student";
- import {useRouter} from "vue-router";
- import SvgIcon from "@/components/SvgIcon/index.vue";
- const router = useRouter();
- defineOptions({
- name: "DashboardSchool",
- inheritAttrs: false,
- });
- /**
- * 筛选条件
- */
- const dataParams: SchoolParams = reactive({
- school_id: 0,
- grade_id: 0,
- start_time: Math.ceil(Date.parse("2023/1/1 00:00") / 1000),
- end_time: Math.ceil(Date.now() / 1000),
- });
- const datePicker = ref<number[]>([Date.parse("2023/1/1 00:00"), Date.now()]);
- const schoolData = ref<SchoolList[]>();
- const gradeData = ref<GradeList[]>();
- /**
- * 获取学校
- */
- async function getSchoolData() {
- getAreaSchool(0, 0)
- .then(({data}) => {
- schoolData.value = data;
- schoolData.value?.unshift({num: "", school_id: 0, name: "全部学校"});
- gradeData.value = [{id: 0, name: "全部班级"}];
- })
- .catch((error) => {
- schoolData.value = [{num: "", school_id: 0, name: "全部学校"}];
- gradeData.value = [{id: 0, name: "全部班级"}];
- console.log(error.message);
- });
- }
- /**
- * 班级数据
- */
- async function getGradeData(schoolId: number) {
- getGradeSelect(schoolId)
- .then(({data}) => {
- dataParams.grade_id = 0;
- gradeData.value = data;
- gradeData.value?.unshift({id: 0, name: "全部班级"});
- })
- .catch((error) => {
- dataParams.grade_id = 0;
- gradeData.value = [{id: 0, name: "全部班级"}];
- console.log(error.message);
- });
- }
- // 改变时间
- function changeDate() {
- dataParams.start_time = Math.ceil(datePicker.value[0] / 1000);
- dataParams.end_time = Math.ceil(datePicker.value[1] / 1000);
- }
- // 获取图表数据条件
- const chartStatus = ref(false);
- const chartParams: AreaChartParams = reactive({});
- /**
- * 获取页面数据
- */
- function getSchoolPageData() {
- // 图表参数
- chartParams.school_id = dataParams.school_id;
- chartParams.grade_id = dataParams.grade_id;
- chartParams.start_time = dataParams.start_time;
- chartParams.end_time = dataParams.end_time;
- chartStatus.value = true;
- if (dataParams.school_id > 0) {
- // 学生参数
- studentParams.school_id = dataParams.school_id;
- studentParams.grade_id = dataParams.grade_id;
- getStudentData();
- } else {
- dataMessage.value = "你还未选择具体学校,请选择学校后查看。";
- }
- }
- /**
- * 学生数据
- */
- const studentParams: StudentParams = reactive({
- school_id: 0,
- grade_id: 0,
- search: "",
- page: 1,
- page_size: 10,
- });
- const dataMessage = ref("加载中...");
- const studentCount = ref(0);
- const studentData = ref<StudentItem[]>();
- // 重置学生参数
- function initStudentParams() {
- studentParams.school_id = dataParams.school_id;
- studentParams.grade_id = dataParams.grade_id;
- studentParams.search = "";
- studentParams.page = 1;
- studentParams.page_size = 10;
- getStudentData();
- }
- async function getStudentData() {
- getStudentLists(studentParams)
- .then(({data}) => {
- const {count, lists} = data;
- studentCount.value = count;
- studentData.value = lists;
- if (!(count && count > 0 && lists.length > 0)) {
- dataMessage.value = "没有符合搜索条件的记录!";
- if (studentParams.grade_id == 0 && studentParams.search == "") {
- dataMessage.value = "暂时还没有任何学生绑定学校!";
- }
- }
- })
- .catch((error) => {
- dataMessage.value = error.message;
- console.log(error.message);
- });
- }
- function alertTrainingError() {
- ElMessage.error("该学生训练数据还不足以进行训练效果分析,请至少完成16次专注力训练后再来查看。");
- }
- function alertEvaluationError() {
- ElMessage.error("该学生还未进行过测评,暂无测评数据。");
- }
- function getSchoolSearch() {
- getStudentData();
- }
- function pathTo(url: String) {
- // 记录搜索条件
- sessionStorage.setItem("schoolChartParams", JSON.stringify(dataParams));
- sessionStorage.setItem("schoolStudentParams", JSON.stringify(studentParams));
- // 路由跳转
- router.push(url);
- }
- onMounted(() => {
- // 获取学校
- getSchoolData();
- gradeData.value = [{id: 0, name: "全部班级"}];
- // 获取记录的搜索条件
- let params1 = sessionStorage.getItem("schoolChartParams");
- if (params1 && params1 != "null") {
- const parse1: SchoolParams = JSON.parse(params1);
- if (parse1.school_id && parse1.school_id > 0) {
- dataParams.school_id = parse1.school_id;
- }
- if (parse1.grade_id && parse1.grade_id > 0) {
- dataParams.grade_id = parse1.grade_id;
- }
- if (parse1.start_time && parse1.start_time > 0) {
- dataParams.start_time = parse1.start_time;
- }
- if (parse1.end_time && parse1.end_time > 0) {
- dataParams.end_time = parse1.end_time;
- }
- }
- let params2 = sessionStorage.getItem("schoolStudentParams");
- if (params2 && params2 != "null") {
- const parse2: StudentParams = JSON.parse(params2);
- if (parse2.page && parse2.page > 0) {
- studentParams.page = parse2.page;
- }
- if (parse2.page_size && parse2.page_size > 0) {
- studentParams.page_size = parse2.page_size;
- }
- if (parse2.search) {
- studentParams.search = parse2.search;
- }
- }
- sessionStorage.removeItem("schoolChartParams");
- sessionStorage.removeItem("schoolStudentParams");
- // 获取页面数据
- getSchoolPageData();
- });
- </script>
- <template>
- <div class="area-container">
- <div class="search-box s2">
- <el-select
- v-model="dataParams.school_id"
- filterable
- placeholder="全部学校"
- size="large"
- @change="getGradeData(dataParams.school_id)">
- <el-option v-for="item in schoolData" :key="item.school_id" :label="item.name" :value="item.school_id" />
- </el-select>
- <el-select v-model="dataParams.grade_id" placeholder="全部班级" size="large">
- <el-option v-for="item in gradeData" :key="item.id" :label="item.name" :value="item.id" />
- </el-select>
- <div>
- <el-date-picker
- v-model="datePicker"
- type="daterange"
- size="large"
- start-placeholder="开始日期"
- end-placeholder="结束日期"
- format="YYYY-MM-DD"
- value-format="x"
- @change="changeDate()" />
- </div>
- <el-button color="#4284f2" size="large" @click="getSchoolPageData()">查找</el-button>
- </div>
- <!-- Echarts 图表 -->
- <ComboCharts
- v-if="chartStatus"
- :key="chartParams?.toString()"
- :schoolId="chartParams.school_id"
- :gradeId="chartParams.grade_id"
- :startTime="chartParams.start_time"
- :endTime="chartParams.end_time" />
- <!-- 学生查找 -->
- <div v-if="dataParams.school_id > 0" class="search-box s2">
- <el-input
- v-model="studentParams.search"
- placeholder="请输入学生名称或手机号码"
- size="large"
- @input="(value:string) => (studentParams.search = trimInput(value))" />
- <el-button size="large" type="primary" @click="getSchoolSearch()">查找</el-button>
- <el-button size="large" type="primary" @click="initStudentParams()">重置</el-button>
- <a
- class="download-btn"
- href="javascript:void(0);"
- @click="pathTo('/download/student/excel?school=' + studentParams.school_id)">
- <svg-icon icon-class="download" size="3rem" />
- <span>报告原始数据下载</span>
- </a>
- </div>
- <!-- 学生列表-->
- <div class="student-container">
- <!-- 学生数据 -->
- <div class="list-table">
- <el-table :data="studentData" style="width: 100%">
- <el-table-column align="center" label="序号" max-width="120" type="index" />
- <el-table-column prop="name" label="学生名称" align="center" />
- <el-table-column prop="grade_name" label="所在班级" align="center" />
- <el-table-column prop="phone" label="手机号码" align="center" />
- <el-table-column prop="create_time" label="注册时间" align="center" />
- <el-table-column prop="count" label="训练次数" align="center" />
- <el-table-column label="操作" align="center" min-width="160">
- <template #default="scope">
- <button
- class="table-btn"
- @click="pathTo('/schoolBoard/training?id=' + scope.row.id + '&grade=' + scope.row.grade_id)">
- 训练报告
- </button>
- <button
- v-if="scope.row.count > 16"
- class="table-btn"
- @click="pathTo('/schoolBoard/result?id=' + scope.row.id + '&school=' + studentParams.school_id)">
- 训练效果分析
- </button>
- <button v-else class="table-btn disabled" @click="alertTrainingError()">训练效果分析</button>
- <button
- v-if="scope.row.count_report > 0"
- class="table-btn"
- @click="pathTo('/schoolBoard/evaluation?id=' + scope.row.id)">
- 训练效果分析
- </button>
- <button v-else class="table-btn disabled" @click="alertEvaluationError()">测评数据对比</button>
- </template>
- </el-table-column>
- <!-- 无数据插槽 -->
- <template #empty>
- <div class="empty">
- <img src="../../../assets/empty.png" alt="数据为空" />
- <p>{{ dataMessage }}</p>
- </div>
- </template>
- </el-table>
- <pagination
- v-if="studentCount > 0"
- v-model:total="studentCount"
- v-model:page="studentParams.page"
- v-model:limit="studentParams.page_size"
- @pagination="getSchoolSearch()" />
- </div>
- </div>
- </div>
- </template>
- <style lang="scss" scoped>
- .area-top {
- background: #fff;
- }
- .card-box {
- padding: 0 30px 20px;
- }
- .search-box {
- position: relative;
- display: flex;
- padding: 20px 55px;
- line-height: 40px;
- background: #fff;
- .el-select {
- width: 140px;
- margin-right: 10px;
- }
- .el-button {
- padding: 0 26px;
- margin: 0 0 0 20px;
- font-size: 16px;
- background: #4284f2;
- border-radius: 10px;
- }
- .el-input {
- width: 250px;
- margin: 0;
- border: 1px solid #ddd;
- border-radius: 10px;
- }
- :deep(.el-input__inner) {
- font-size: 16px;
- }
- .download-btn {
- position: absolute;
- right: 180px;
- color: #4284f2;
- }
- .download-btn * {
- margin-right: 12px;
- vertical-align: middle;
- }
- }
- :deep(.el-select) {
- --el-select-input-focus-border-color: none !important;
- }
- :deep(.search-box .el-date-editor) {
- width: 300px;
- margin: 0;
- overflow: hidden;
- border: 1px solid #ddd;
- border-radius: 10px;
- }
- :deep(.search-box.s2 .el-select) {
- border: 1px solid #ddd;
- border-radius: 10px;
- }
- :deep(.el-date-editor) {
- --el-select-input-focus-border-color: none !important;
- }
- :deep(.el-input__wrapper) {
- background: #fff;
- border-radius: 12px;
- box-shadow: none !important;
- }
- :deep(.el-input__wrapper.is-focus) {
- box-shadow: none !important;
- }
- :deep(.el-select:hover:not(.el-select--disabled) .el-input__wrapper) {
- box-shadow: none !important;
- }
- :deep(.el-select .el-input__wrapper.is-focus) {
- box-shadow: none !important;
- }
- :deep(.el-table .el-table__header .el-table__cell .cell) {
- overflow: visible;
- white-space: nowrap;
- }
- :deep(.el-table th.el-table__cell) {
- background: #e9ebee;
- }
- .mobile .el-col {
- margin-bottom: 10px;
- }
- .student-container {
- position: relative;
- padding: 20px 30px;
- }
- .list-table {
- overflow: hidden;
- background: #fff;
- border-radius: 25px;
- .table-btn {
- display: inline-block;
- height: 38px;
- padding: 0 15px;
- margin-right: 10px;
- line-height: 38px;
- color: #fff;
- background: #4284f2;
- border-radius: 6px;
- &.disabled {
- background: #bfbfbf;
- }
- }
- }
- .empty {
- padding: 200px 0;
- }
- </style>
|