|
|
@@ -1,62 +1,244 @@
|
|
|
<template>
|
|
|
- <!-- 成绩查询 成绩单 -->
|
|
|
- <ReportModule :showTitle="false" :showDescribe="false" tableOrChart="table">
|
|
|
+ <!-- 成绩查询 - 成绩单 -->
|
|
|
+ <ReportModule
|
|
|
+ :showTitle="false"
|
|
|
+ :showDescribe="false"
|
|
|
+ :showPrintBtn="false"
|
|
|
+ tableOrChart="table"
|
|
|
+ :currentPage="state.pageInfo.pageNum"
|
|
|
+ :pageSize="state.pageInfo.pageSize"
|
|
|
+ :pageSizes="[50, 100]"
|
|
|
+ :total="state.pageInfo.total"
|
|
|
+ @update:pageSize="handleSizeChange"
|
|
|
+ @update:currentPage="handleCurrentChange"
|
|
|
+ >
|
|
|
<template #title_left>
|
|
|
- <el-input v-model="state.keyWord" style="width: 200px" placeholder="请输入学号或姓名" class="input_with">
|
|
|
+ <el-input
|
|
|
+ v-model="state.keyWord"
|
|
|
+ clearable
|
|
|
+ style="width: 200px"
|
|
|
+ placeholder="请输入学号或姓名"
|
|
|
+ class="input_with"
|
|
|
+ @input="handleSearch"
|
|
|
+ >
|
|
|
<template #append>
|
|
|
- <el-button :icon="Search" />
|
|
|
+ <el-button :icon="Search" @click="handleSearch" />
|
|
|
</template>
|
|
|
</el-input>
|
|
|
- <span class="count_item">应考:293人</span>
|
|
|
- <span class="count_item">实考:280人</span>
|
|
|
- <span class="count_item orange">缺考:13人</span>
|
|
|
- </template>
|
|
|
- <template #title_right>
|
|
|
- <el-checkbox-group class="checkbox_group" v-model="state.checkList">
|
|
|
- <el-checkbox label="显示分组" value="group" />
|
|
|
- <el-checkbox label="显示小题" value="question" />
|
|
|
- </el-checkbox-group>
|
|
|
+
|
|
|
+ <span class="count_item"
|
|
|
+ >应考:{{ state.tableCount.examStudentCount }}人</span
|
|
|
+ >
|
|
|
+ <span class="count_item">实考:{{ state.tableCount.normalCount }}人</span>
|
|
|
+ <span class="count_item orange"
|
|
|
+ >缺考:{{ state.tableCount.missExamCount }}人</span
|
|
|
+ >
|
|
|
</template>
|
|
|
<template #module_table_chart>
|
|
|
- <el-table :data="tableData" border style="width: 100%">
|
|
|
- <el-table-column prop="date" label="Date" width="180" />
|
|
|
- <el-table-column prop="name" label="Name" width="180" />
|
|
|
- <el-table-column prop="address" label="Address" />
|
|
|
+ <el-table
|
|
|
+ :data="state.tableData"
|
|
|
+ border
|
|
|
+ height="500"
|
|
|
+ v-loading="state.tableLoading"
|
|
|
+ :element-loading-text="state.loadingText"
|
|
|
+ element-loading-spinner="el-icon-loading"
|
|
|
+ element-loading-background="#ffffff"
|
|
|
+ >
|
|
|
+ <el-table-column
|
|
|
+ type="index"
|
|
|
+ :index="GetIndexNumber"
|
|
|
+ align="center"
|
|
|
+ width="70"
|
|
|
+ label="序号"
|
|
|
+ fixed="left"
|
|
|
+ ></el-table-column>
|
|
|
+ <template v-for="item in state.staticHeaderData">
|
|
|
+ <el-table-column
|
|
|
+ v-if="item.display"
|
|
|
+ :key="item.prop"
|
|
|
+ :prop="item.prop"
|
|
|
+ :label="item.label"
|
|
|
+ min-width="100"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <el-table-column
|
|
|
+ v-for="(item, index) in state.answerDataTitle"
|
|
|
+ :key="item.prop"
|
|
|
+ :prop="item.prop"
|
|
|
+ :label="item.label"
|
|
|
+ min-width="100"
|
|
|
+ >
|
|
|
+ <template #default="scope">{{
|
|
|
+ scope.row?.dynamicsData?.answerData?.[index] || "-"
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
</el-table>
|
|
|
</template>
|
|
|
</ReportModule>
|
|
|
</template>
|
|
|
+
|
|
|
<script lang="ts" setup>
|
|
|
-import ReportModule from '@/components/ReportModule.vue';
|
|
|
-import { Search } from '@element-plus/icons-vue'
|
|
|
-import { onMounted, reactive, ref } from "vue";
|
|
|
-const tableData = [
|
|
|
- {
|
|
|
- date: '2016-05-03',
|
|
|
- name: 'Tom',
|
|
|
- address: 'No. 189, Grove St, Los Angeles',
|
|
|
- },
|
|
|
- {
|
|
|
- date: '2016-05-02',
|
|
|
- name: 'Tom',
|
|
|
- address: 'No. 189, Grove St, Los Angeles',
|
|
|
+import ReportModule from "@/components/ReportModule.vue";
|
|
|
+import {
|
|
|
+ studentTranscriptTitle,
|
|
|
+ queryJointStudentStatistics,
|
|
|
+ studentTranscript,
|
|
|
+} from "@/api/analysis";
|
|
|
+import { useAnalysisStore } from "@/store/analysis";
|
|
|
+import { Search } from "@element-plus/icons-vue";
|
|
|
+import { onMounted, reactive, watch } from "vue";
|
|
|
+
|
|
|
+interface TableColumn {
|
|
|
+ prop: string;
|
|
|
+ label: string;
|
|
|
+ display?: boolean;
|
|
|
+ [key: string]: any;
|
|
|
+}
|
|
|
+
|
|
|
+interface TableCount {
|
|
|
+ examStudentCount: number | string;
|
|
|
+ normalCount: number | string;
|
|
|
+ missExamCount: number | string;
|
|
|
+}
|
|
|
+
|
|
|
+interface PageInfo {
|
|
|
+ pageSize: number;
|
|
|
+ pageNum: number;
|
|
|
+ total: number;
|
|
|
+}
|
|
|
+
|
|
|
+interface State {
|
|
|
+ keyWord: string;
|
|
|
+ tableData: any[];
|
|
|
+ staticHeaderData: TableColumn[];
|
|
|
+ answerDataTitle: TableColumn[];
|
|
|
+ tableCount: TableCount;
|
|
|
+ pageInfo: PageInfo;
|
|
|
+ tableLoading: Boolean;
|
|
|
+ loadingText: String;
|
|
|
+}
|
|
|
+
|
|
|
+const analysisStore = useAnalysisStore();
|
|
|
+
|
|
|
+const state = reactive<State>({
|
|
|
+ keyWord: "",
|
|
|
+ tableData: [],
|
|
|
+ staticHeaderData: [],
|
|
|
+ answerDataTitle: [],
|
|
|
+ tableCount: {
|
|
|
+ examStudentCount: 0,
|
|
|
+ normalCount: 0,
|
|
|
+ missExamCount: 0,
|
|
|
},
|
|
|
- {
|
|
|
- date: '2016-05-04',
|
|
|
- name: 'Tom',
|
|
|
- address: 'No. 189, Grove St, Los Angeles',
|
|
|
+ pageInfo: {
|
|
|
+ pageSize: 50,
|
|
|
+ pageNum: 1,
|
|
|
+ total: 0,
|
|
|
},
|
|
|
- {
|
|
|
- date: '2016-05-01',
|
|
|
- name: 'Tom',
|
|
|
- address: 'No. 189, Grove St, Los Angeles',
|
|
|
+ tableLoading: true,
|
|
|
+ loadingText: "加载中……",
|
|
|
+});
|
|
|
+
|
|
|
+/** 获取表头 */
|
|
|
+const getStudentTranscriptTitle = async () => {
|
|
|
+ if (!analysisStore.filterObject) return;
|
|
|
+ try {
|
|
|
+ const res = await studentTranscriptTitle({
|
|
|
+ ...analysisStore.filterObject,
|
|
|
+ topicControl: 0,
|
|
|
+ });
|
|
|
+ if (res.code === 200) {
|
|
|
+ state.staticHeaderData = res.data?.title?.staticHeaderData || [];
|
|
|
+ state.answerDataTitle =
|
|
|
+ res.data?.title?.dynamicsHeaderData?.answerDataTitle || [];
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ console.error("获取表头失败:", err);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/** 获取顶部统计 */
|
|
|
+const getTableCount = async () => {
|
|
|
+ if (!analysisStore.filterObject) return;
|
|
|
+ try {
|
|
|
+ const res = await queryJointStudentStatistics({
|
|
|
+ ...analysisStore.filterObject,
|
|
|
+ topicControl: 0,
|
|
|
+ queryStr: state.keyWord,
|
|
|
+ });
|
|
|
+ if (res.code === 200) {
|
|
|
+ state.tableCount = res.data || {};
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ console.error("获取统计数据失败:", err);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/** 获取表格数据 */
|
|
|
+const getTableData = async () => {
|
|
|
+ if (!analysisStore.filterObject) return;
|
|
|
+ try {
|
|
|
+ state.tableLoading = true;
|
|
|
+ const res = await studentTranscript({
|
|
|
+ ...analysisStore.filterObject,
|
|
|
+ topicControl: 0,
|
|
|
+ queryStr: state.keyWord,
|
|
|
+ pageParam: {
|
|
|
+ pageNum: state.pageInfo.pageNum,
|
|
|
+ pageSize: state.pageInfo.pageSize,
|
|
|
+ },
|
|
|
+ });
|
|
|
+ if (res.code === 200) {
|
|
|
+ state.tableData = res.data?.listData || [];
|
|
|
+ state.pageInfo.total = Number(res.data?.total || 0);
|
|
|
+ }
|
|
|
+ state.tableLoading = false;
|
|
|
+ } catch (err) {
|
|
|
+ console.error("获取表格数据失败:", err);
|
|
|
+ }
|
|
|
+};
|
|
|
+//获取序号
|
|
|
+const GetIndexNumber = (index: number) => {
|
|
|
+ let indexCount =
|
|
|
+ (state.pageInfo.pageNum - 1) * state.pageInfo.pageSize + index + 1;
|
|
|
+ return indexCount;
|
|
|
+};
|
|
|
+// 分页 & 搜索
|
|
|
+const handleCurrentChange = (val: number) => {
|
|
|
+ state.pageInfo.pageNum = val;
|
|
|
+ getTableData();
|
|
|
+};
|
|
|
+
|
|
|
+const handleSizeChange = (val: number) => {
|
|
|
+ state.pageInfo.pageSize = val;
|
|
|
+ state.pageInfo.pageNum = 1;
|
|
|
+ getTableData();
|
|
|
+};
|
|
|
+
|
|
|
+const handleSearch = () => {
|
|
|
+ state.pageInfo.pageNum = 1;
|
|
|
+ getTableData();
|
|
|
+};
|
|
|
+
|
|
|
+// 初始化
|
|
|
+const pageInit = () => {
|
|
|
+ getStudentTranscriptTitle();
|
|
|
+ getTableCount();
|
|
|
+ getTableData();
|
|
|
+};
|
|
|
+
|
|
|
+// 监听筛选条件
|
|
|
+watch(
|
|
|
+ () => analysisStore.filterObject,
|
|
|
+ async () => {
|
|
|
+ pageInit();
|
|
|
},
|
|
|
-]
|
|
|
-const state = reactive({
|
|
|
- keyWord: '',
|
|
|
- checkList: ['group']
|
|
|
+ { deep: true },
|
|
|
+);
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ pageInit();
|
|
|
});
|
|
|
-onMounted(() => { });
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
@@ -65,14 +247,14 @@ onMounted(() => { });
|
|
|
}
|
|
|
|
|
|
.count_item {
|
|
|
- font-weight: 400;
|
|
|
font-size: 16px;
|
|
|
- color: #333333;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #333;
|
|
|
line-height: 24px;
|
|
|
margin-left: 10px;
|
|
|
|
|
|
&.orange {
|
|
|
- color: #FB9F34;
|
|
|
+ color: #fb9f34;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -80,7 +262,7 @@ onMounted(() => { });
|
|
|
:deep(.el-checkbox) {
|
|
|
margin-right: 10px;
|
|
|
|
|
|
- &:nth-child(1) {
|
|
|
+ &:first-child {
|
|
|
margin-right: 20px;
|
|
|
}
|
|
|
}
|