Compare commits
No commits in common. "fd2fcc2c1bbd1f37b8863c2360a88fc91329856a" and "823a8defc811936bcd397cdcedba6e675a10bc68" have entirely different histories.
fd2fcc2c1b
...
823a8defc8
|
|
@ -1,5 +1,4 @@
|
||||||
import { http } from "@/utils/http";
|
import { http } from "@/utils/http";
|
||||||
import { Res } from "@/utils/http/types";
|
|
||||||
// import type { Res } from "@/utils/http/types";
|
// import type { Res } from "@/utils/http/types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -30,31 +29,7 @@ export function ImportExamInfo(id: number, file: File) {
|
||||||
* @return {object}
|
* @return {object}
|
||||||
*/
|
*/
|
||||||
export function DeleteExamInfo(data: { classId: number; examId: number }) {
|
export function DeleteExamInfo(data: { classId: number; examId: number }) {
|
||||||
return http.request<Res<any>>("post", `ExamClassInfo/DeleteExamInfo`, {
|
return http.request<any>("post", `ExamClassInfo/DeleteExamInfo`, {
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 重算考试排名
|
|
||||||
* @return {object}
|
|
||||||
*/
|
|
||||||
export function RecalculateExamRankings(examId: Number) {
|
|
||||||
return http.request<Res<any>>(
|
|
||||||
"get",
|
|
||||||
`ExamClassInfo/RecalculateExamRankings`,
|
|
||||||
{
|
|
||||||
params: { examId }
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 获取班级考试分段排名
|
|
||||||
* @return {object}
|
|
||||||
*/
|
|
||||||
export function ClassRanking(examId: Number,classId: Number) {
|
|
||||||
return http.request<Res<any>>("get", `ExamClassInfo/ClassRanking`, {
|
|
||||||
params: { examId, classId }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -22,7 +22,7 @@ export class hTableAPI {
|
||||||
delete(data) {
|
delete(data) {
|
||||||
return http.request<Res<any>>("post", `${this.url}/Del`, { data });
|
return http.request<Res<any>>("post", `${this.url}/Del`, { data });
|
||||||
}
|
}
|
||||||
querycombo(data = {}) {
|
querycombo(data) {
|
||||||
return http.request<Res<ComboModel[]>>("post", `${this.url}/QueryCombo`, {
|
return http.request<Res<ComboModel[]>>("post", `${this.url}/QueryCombo`, {
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -198,18 +198,18 @@ export class TableColumnSearch {
|
||||||
|
|
||||||
/** 表格列配置 */
|
/** 表格列配置 */
|
||||||
export class TableColumn {
|
export class TableColumn {
|
||||||
constructor() {
|
constructor(
|
||||||
|
) {
|
||||||
|
|
||||||
this.type = "string";
|
this.type = "string";
|
||||||
this.show = true;
|
this.show = true;
|
||||||
this.search = new TableColumnSearch();
|
this.search = new TableColumnSearch();
|
||||||
this.edit = new TableColumnEdit();
|
this.edit = new TableColumnEdit();
|
||||||
this.fixed = false;
|
|
||||||
this.setting = {};
|
this.setting = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 显示标签 */
|
/** 显示标签 */
|
||||||
label: string;
|
label: string;
|
||||||
fixed?: 'left' | 'right'| boolean;
|
|
||||||
/** 查询配置 */
|
/** 查询配置 */
|
||||||
search?: TableColumnSearch;
|
search?: TableColumnSearch;
|
||||||
/** 编辑配置 */
|
/** 编辑配置 */
|
||||||
|
|
@ -327,8 +327,6 @@ export interface TableConfig {
|
||||||
searchCallback?: (s: SearchConditions) => void;
|
searchCallback?: (s: SearchConditions) => void;
|
||||||
/** 新增/修改回调函数 */
|
/** 新增/修改回调函数 */
|
||||||
editCallback?: (from: any) => void;
|
editCallback?: (from: any) => void;
|
||||||
/** 展开行的回调 */
|
|
||||||
expandChange?: (row: any, expandedRows: any[]) => void;
|
|
||||||
/** API地址 */
|
/** API地址 */
|
||||||
apiUrl: string;
|
apiUrl: string;
|
||||||
/** 是否显示选择列 */
|
/** 是否显示选择列 */
|
||||||
|
|
@ -337,10 +335,6 @@ export interface TableConfig {
|
||||||
search: SearchConditions;
|
search: SearchConditions;
|
||||||
/** 是否显示操作列 */
|
/** 是否显示操作列 */
|
||||||
operationColumn: boolean;
|
operationColumn: boolean;
|
||||||
/** 操作列是否固定列 */
|
|
||||||
operationColumnFixed?: "left" | "right" | boolean;
|
|
||||||
/** 是否允许展开列 */
|
|
||||||
expandColumn?: boolean;
|
|
||||||
/** 操作按钮配置 */
|
/** 操作按钮配置 */
|
||||||
operationColumnData: OperationButton[];
|
operationColumnData: OperationButton[];
|
||||||
/** 列配置 */
|
/** 列配置 */
|
||||||
|
|
@ -363,8 +357,6 @@ export function intTableData(tValue: TableConfig): TableConfig {
|
||||||
if (!tValue.data) tValue.data = [];
|
if (!tValue.data) tValue.data = [];
|
||||||
if (!tValue.selectRows) tValue.selectRows = [];
|
if (!tValue.selectRows) tValue.selectRows = [];
|
||||||
if (tValue.border == null) tValue.border = true;
|
if (tValue.border == null) tValue.border = true;
|
||||||
if (tValue.operationColumnFixed == null) tValue.operationColumnFixed = false;
|
|
||||||
if (tValue.expandColumn == null) tValue.expandColumn = false;
|
|
||||||
if (!tValue.pageData) tValue.pageData = { total: 0 };
|
if (!tValue.pageData) tValue.pageData = { total: 0 };
|
||||||
if (tValue.operationTop === undefined) tValue.operationTop = true;
|
if (tValue.operationTop === undefined) tValue.operationTop = true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -117,8 +117,8 @@ function handleResetForm() {
|
||||||
function fetchInitData() {}
|
function fetchInitData() {}
|
||||||
function fetchFormData() {
|
function fetchFormData() {
|
||||||
editData.value.loading = false;
|
editData.value.loading = false;
|
||||||
handleResetForm();
|
|
||||||
if (editData.value.isedit) {
|
if (editData.value.isedit) {
|
||||||
|
handleResetForm();
|
||||||
Api.Info(props.id).then((res) => {
|
Api.Info(props.id).then((res) => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
editData.value.frorm = res.data;
|
editData.value.frorm = res.data;
|
||||||
|
|
|
||||||
|
|
@ -207,20 +207,16 @@ function handleDelete(obj, row) {
|
||||||
row.forEach((it) => {
|
row.forEach((it) => {
|
||||||
ids.push(it.id);
|
ids.push(it.id);
|
||||||
});
|
});
|
||||||
ElMessageBox.confirm("此操作将永久删除勾选记录, 是否继续?")
|
ElMessageBox.confirm("此操作将永久删除勾选记录, 是否继续?").then(() => {
|
||||||
.then(() => {
|
Api.delete(ids).then((res) => {
|
||||||
Api.delete(ids).then((res) => {
|
if (res.code === 200) {
|
||||||
if (res.code === 200) {
|
handleReloadPaged();
|
||||||
handleReloadPaged();
|
ElMessage.success("删除成功");
|
||||||
ElMessage.success("删除成功");
|
} else {
|
||||||
} else {
|
ElMessage.error(res.message);
|
||||||
ElMessage.error(res.message);
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
ElMessage.info("取消删除");
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// 页面完成回调
|
// 页面完成回调
|
||||||
function handleAddCallback() {
|
function handleAddCallback() {
|
||||||
|
|
@ -458,7 +454,6 @@ function fetchPagedData() {
|
||||||
:row-key="rowKeyFun"
|
:row-key="rowKeyFun"
|
||||||
@selection-change="handleSelectionChange"
|
@selection-change="handleSelectionChange"
|
||||||
@sort-change="sortChange"
|
@sort-change="sortChange"
|
||||||
@expand-change="table.expandChange"
|
|
||||||
>
|
>
|
||||||
<el-table-column v-if="table.selectColumn" type="selection" width="40" />
|
<el-table-column v-if="table.selectColumn" type="selection" width="40" />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
|
@ -466,7 +461,6 @@ function fetchPagedData() {
|
||||||
table.operationColumn &&
|
table.operationColumn &&
|
||||||
table.operationColumnData.filter((s) => !s.topBtn).length > 0
|
table.operationColumnData.filter((s) => !s.topBtn).length > 0
|
||||||
"
|
"
|
||||||
:fixed="table.operationColumnFixed"
|
|
||||||
label="操作"
|
label="操作"
|
||||||
:width="getOperationColumnWidth()"
|
:width="getOperationColumnWidth()"
|
||||||
>
|
>
|
||||||
|
|
@ -489,21 +483,12 @@ function fetchPagedData() {
|
||||||
<!-- 行内按钮组 -->
|
<!-- 行内按钮组 -->
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<!-- 拓展列 -->
|
|
||||||
<el-table-column v-if="table.expandColumn" type="expand">
|
|
||||||
<template #default="props">
|
|
||||||
<slot name="expandSlot" :props="props"></slot>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
v-for="(item, name, i) of tableShowColumn"
|
v-for="(item, name, i) of tableShowColumn"
|
||||||
:key="i"
|
:key="i"
|
||||||
:prop="name"
|
:prop="name"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:width="item.width"
|
:width="item.width"
|
||||||
:fixed="item.fixed"
|
|
||||||
:sortable="item.search.sort ? `custom` : false"
|
:sortable="item.search.sort ? `custom` : false"
|
||||||
>
|
>
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ const convertKeysToCamelCase = <T>(data: any): T => {
|
||||||
const defaultConfig: AxiosRequestConfig = {
|
const defaultConfig: AxiosRequestConfig = {
|
||||||
baseURL: import.meta.env.VITE_API_BASEURL,
|
baseURL: import.meta.env.VITE_API_BASEURL,
|
||||||
// 请求超时时间
|
// 请求超时时间
|
||||||
timeout: 30 * 1000,
|
timeout: 20 * 1000,
|
||||||
headers: {
|
headers: {
|
||||||
Accept: "application/json, text/plain, */*",
|
Accept: "application/json, text/plain, */*",
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,6 @@ import { fa } from "element-plus/es/locales.mjs";
|
||||||
import { hTableAPI } from "@/api/hTable";
|
import { hTableAPI } from "@/api/hTable";
|
||||||
import { getenum } from "@/api/enum";
|
import { getenum } from "@/api/enum";
|
||||||
import { ruleRequired, ruleRequiredNumber } from "@/utils/rules";
|
import { ruleRequired, ruleRequiredNumber } from "@/utils/rules";
|
||||||
import { ClassRanking } from "@/api/exam";
|
|
||||||
import { ElMessage } from "element-plus";
|
|
||||||
const ControllerName = "ExamClassInfo";
|
const ControllerName = "ExamClassInfo";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
|
|
@ -27,11 +25,9 @@ function searchCallback(data) {}
|
||||||
const table = ref<{ initTable: (config: TableConfig) => void }>();
|
const table = ref<{ initTable: (config: TableConfig) => void }>();
|
||||||
const tableData: TableConfig = intTableData({
|
const tableData: TableConfig = intTableData({
|
||||||
apiUrl: ControllerName,
|
apiUrl: ControllerName,
|
||||||
expandColumn: true,
|
|
||||||
selectColumn: false, // 列表选择
|
selectColumn: false, // 列表选择
|
||||||
border: false, // 是否显示表格边框
|
border: false, // 是否显示表格边框
|
||||||
searchCallback: searchCallback,
|
searchCallback: searchCallback,
|
||||||
expandChange: expandChange,
|
|
||||||
search: {
|
search: {
|
||||||
// 查询条件
|
// 查询条件
|
||||||
show: true,
|
show: true,
|
||||||
|
|
@ -77,6 +73,19 @@ const tableData: TableConfig = intTableData({
|
||||||
},
|
},
|
||||||
peopleCount: {
|
peopleCount: {
|
||||||
label: "参考人数",
|
label: "参考人数",
|
||||||
|
width: "100px",
|
||||||
|
},
|
||||||
|
onLineCount: {
|
||||||
|
label: "重本人数",
|
||||||
|
width: "100px",
|
||||||
|
},
|
||||||
|
onLineRate: {
|
||||||
|
label: "重本率",
|
||||||
|
width: "100px",
|
||||||
|
custom: (row) => `${row.onLineRate * 100}%`,
|
||||||
|
},
|
||||||
|
onLineRanking: {
|
||||||
|
label: "重本率排名",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: [],
|
data: [],
|
||||||
|
|
@ -92,275 +101,8 @@ onMounted(async () => {
|
||||||
|
|
||||||
showTable.value = true;
|
showTable.value = true;
|
||||||
});
|
});
|
||||||
// types/exam.ts 或直接在组件中定义
|
|
||||||
export interface ExamClassTag {
|
|
||||||
Name: string; // 标签名称
|
|
||||||
SubjectStr?: string; // 学科枚举,可空(总分则为 null)
|
|
||||||
OnLineRanking: number; // 上线考试排名
|
|
||||||
OnLineRate: number; // 上线率(注意:C#中是 decimal,TS里用 number)
|
|
||||||
OnLineCount: number; // 上线人数
|
|
||||||
}
|
|
||||||
|
|
||||||
async function expandChange(row: any, expandedRows: any[]) {
|
|
||||||
if (row.rankingList != null) return;
|
|
||||||
let res = await ClassRanking(row.examId, row.classId);
|
|
||||||
if (res.code != 200) return ElMessage.error(res.message || "获取数据失败");
|
|
||||||
row.rankingList = res.data;
|
|
||||||
}
|
|
||||||
// 根据学科获取CSS类名
|
|
||||||
const getSubjectClass = (subjectStr) => {
|
|
||||||
if (!subjectStr) return "";
|
|
||||||
|
|
||||||
const subjectMap = {
|
|
||||||
总分: "total",
|
|
||||||
数学: "math",
|
|
||||||
英语: "english",
|
|
||||||
物理: "physics",
|
|
||||||
化学: "chemistry",
|
|
||||||
生物: "biology",
|
|
||||||
};
|
|
||||||
|
|
||||||
return subjectMap[subjectStr] || "";
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div><ahTable v-if="showTable" ref="table" :tableConfig="tableData" /></div>
|
||||||
<ahTable v-if="showTable" ref="table" :tableConfig="tableData">
|
|
||||||
<template #expandSlot="{ props }">
|
|
||||||
<!-- 拓展内容 -->
|
|
||||||
<div class="expanded-content expandSlot">
|
|
||||||
<div
|
|
||||||
v-if="props.row.rankingList && props.row.rankingList.length > 0"
|
|
||||||
class="ranking-list"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-for="(tag, tagIndex) in props.row.rankingList"
|
|
||||||
:key="tagIndex"
|
|
||||||
class="tag-card"
|
|
||||||
:class="getSubjectClass(tag.subjectStr)"
|
|
||||||
>
|
|
||||||
<div class="tag-name">
|
|
||||||
<span>{{ tag.name }}</span>
|
|
||||||
<span class="subject-badge">{{ tag.subjectStr || "总分" }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="tag-details">
|
|
||||||
<div class="detail-item">
|
|
||||||
<span class="detail-label">上线排名:</span>
|
|
||||||
<span class="detail-value">第 {{ tag.onLineRanking }} 名</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="detail-item">
|
|
||||||
<span class="detail-label">上线人数:</span>
|
|
||||||
<span class="detail-value">{{ tag.onLineCount }} 人</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="detail-item">
|
|
||||||
<span class="detail-label">上线率:</span>
|
|
||||||
<span class="detail-value"
|
|
||||||
>{{ (tag.onLineRate * 100).toFixed(0) }}%</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="progress-container">
|
|
||||||
<div
|
|
||||||
class="progress-bar"
|
|
||||||
:style="{ width: tag.onLineRate * 100 + '%' }"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-else class="empty-state">
|
|
||||||
<i class="fas fa-inbox" style="font-size: 3rem; margin-bottom: 15px"></i>
|
|
||||||
<p>暂无标签数据</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</ahTable>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<style>
|
|
||||||
.expandSlot {
|
|
||||||
padding: 10px 20px;
|
|
||||||
background: #f5f7fa;
|
|
||||||
}
|
|
||||||
.container {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 1200px;
|
|
||||||
background: white;
|
|
||||||
border-radius: 12px;
|
|
||||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
background: linear-gradient(90deg, #3498db, #2c3e50);
|
|
||||||
color: white;
|
|
||||||
padding: 20px 30px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header h1 {
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 1.8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header .subtitle {
|
|
||||||
opacity: 0.9;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-container {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-table th {
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
padding: 15px;
|
|
||||||
text-align: left;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #2c3e50;
|
|
||||||
border-bottom: 2px solid #e9ecef;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-table td {
|
|
||||||
padding: 15px;
|
|
||||||
border-bottom: 1px solid #e9ecef;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-table tr:hover {
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.expand-btn {
|
|
||||||
background: #3498db;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
padding: 6px 12px;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
transition: all 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.expand-btn:hover {
|
|
||||||
background: #2980b9;
|
|
||||||
transform: translateY(-2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ranking-list {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
|
||||||
gap: 15px;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-card {
|
|
||||||
background: white;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 15px;
|
|
||||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05);
|
|
||||||
border-left: 4px solid #3498db;
|
|
||||||
transition: transform 0.3s, box-shadow 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-card:hover {
|
|
||||||
transform: translateY(-5px);
|
|
||||||
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-card.total {
|
|
||||||
border-left-color: #777f8a;
|
|
||||||
}
|
|
||||||
.tag-card.math {
|
|
||||||
border-left-color: #e74c3c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-card.english {
|
|
||||||
border-left-color: #f39c12;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-card.physics {
|
|
||||||
border-left-color: #9b59b6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-card.chemistry {
|
|
||||||
border-left-color: #1abc9c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-card.biology {
|
|
||||||
border-left-color: #2ecc71;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-name {
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
color: #2c3e50;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subject-badge {
|
|
||||||
padding: 3px 8px;
|
|
||||||
border-radius: 12px;
|
|
||||||
font-size: 0.75rem;
|
|
||||||
font-weight: 600;
|
|
||||||
background: #ecf0f1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-details {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-item {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 0px;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-label {
|
|
||||||
color: #7f8c8d;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-value {
|
|
||||||
font-weight: 500;
|
|
||||||
color: #2c3e50;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-container {
|
|
||||||
height: 8px;
|
|
||||||
background: #ecf0f1;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-top: 5px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-bar {
|
|
||||||
height: 100%;
|
|
||||||
background: linear-gradient(90deg, #3498db, #2ecc71);
|
|
||||||
border-radius: 4px;
|
|
||||||
transition: width 0.5s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.empty-state {
|
|
||||||
text-align: center;
|
|
||||||
padding: 30px;
|
|
||||||
color: #7f8c8d;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -90,19 +90,19 @@ const tableData: TableConfig = intTableData({
|
||||||
search: new TableColumnSearch(true),
|
search: new TableColumnSearch(true),
|
||||||
},
|
},
|
||||||
|
|
||||||
// onLineCount: {
|
onLineCount: {
|
||||||
// label: "重本人数",
|
label: "重本人数",
|
||||||
// width: "80px",
|
width: "80px",
|
||||||
// },
|
},
|
||||||
// onLineRate: {
|
onLineRate: {
|
||||||
// label: "重本率",
|
label: "重本率",
|
||||||
// custom: (row) => `${Math.round(row.onLineRate * 100)}%`,
|
custom: (row) => `${Math.round(row.onLineRate * 100)}%`,
|
||||||
// width: "80px",
|
width: "80px",
|
||||||
// },
|
},
|
||||||
// onLineRanking: {
|
onLineRanking: {
|
||||||
// label: "重本率排名",
|
label: "重本率排名",
|
||||||
// width: "100px",
|
width: "100px",
|
||||||
// },
|
},
|
||||||
maxScore: {
|
maxScore: {
|
||||||
label: "最高分[赋分]",
|
label: "最高分[赋分]",
|
||||||
width: "130px",
|
width: "130px",
|
||||||
|
|
@ -122,10 +122,10 @@ const tableData: TableConfig = intTableData({
|
||||||
},
|
},
|
||||||
averageRank: {
|
averageRank: {
|
||||||
label: "总平均分排名",
|
label: "总平均分排名",
|
||||||
width: "110px",
|
|
||||||
},
|
},
|
||||||
rank: {
|
rank: {
|
||||||
label: "远端平均/资源校平均",
|
label: "远端平均/资源校平均",
|
||||||
|
width: "95px",
|
||||||
custom: (row) =>
|
custom: (row) =>
|
||||||
`${
|
`${
|
||||||
row.baseSchoolScore == 0
|
row.baseSchoolScore == 0
|
||||||
|
|
|
||||||
|
|
@ -1,188 +0,0 @@
|
||||||
<script setup lang="ts">
|
|
||||||
import ahTable from "@/components/hTable/index.vue";
|
|
||||||
import {
|
|
||||||
ConditionalType,
|
|
||||||
intTableData,
|
|
||||||
TableColumnSearch,
|
|
||||||
TableConfig,
|
|
||||||
} from "@/components/hTable/hTable";
|
|
||||||
import { onMounted, ref } from "vue";
|
|
||||||
import { fa } from "element-plus/es/locales.mjs";
|
|
||||||
import { hTableAPI } from "@/api/hTable";
|
|
||||||
import { getenum } from "@/api/enum";
|
|
||||||
import {
|
|
||||||
ruleNumber,
|
|
||||||
ruleRequired,
|
|
||||||
ruleRequiredGrade,
|
|
||||||
ruleRequiredI,
|
|
||||||
ruleRequiredNumber,
|
|
||||||
} from "@/utils/rules";
|
|
||||||
import { ImportExamInfo, RecalculateExamRankings } from "@/api/exam";
|
|
||||||
import { ElMessage, ElMessageBox } from "element-plus";
|
|
||||||
import { entryExamInfo } from "./examFun";
|
|
||||||
const ControllerName = "ExamTags";
|
|
||||||
|
|
||||||
defineOptions({
|
|
||||||
name: ControllerName,
|
|
||||||
});
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
data: any;
|
|
||||||
}>();
|
|
||||||
function searchCallback(data) {}
|
|
||||||
|
|
||||||
const table = ref<{ initTable: (config: TableConfig) => void }>();
|
|
||||||
const tableData: TableConfig = intTableData({
|
|
||||||
apiUrl: ControllerName,
|
|
||||||
selectColumn: false, // 列表选择
|
|
||||||
border: false, // 是否显示表格边框
|
|
||||||
searchCallback: searchCallback,
|
|
||||||
editCallback: async (from) => {
|
|
||||||
if (from.subjectId == -1) from.subjectId = null;
|
|
||||||
from.examId = props.data[0].id;
|
|
||||||
},
|
|
||||||
search: {
|
|
||||||
// 查询条件
|
|
||||||
show: false,
|
|
||||||
showPage: false,
|
|
||||||
PageIndex: 0,
|
|
||||||
PageSize: 1000,
|
|
||||||
OrderBy: "Id", // 排序
|
|
||||||
defaultConditions: [
|
|
||||||
{
|
|
||||||
FieldName: "ExamId",
|
|
||||||
FieldValue: props.data[0].id + "",
|
|
||||||
ConditionalType: ConditionalType.Equal,
|
|
||||||
},
|
|
||||||
], // 默认查询条件
|
|
||||||
Conditions: [],
|
|
||||||
},
|
|
||||||
operationColumn: true, // 显示操作按钮
|
|
||||||
operationColumnData: [
|
|
||||||
// {
|
|
||||||
// // 操作按钮
|
|
||||||
// topBtn: false, // 是头部按钮
|
|
||||||
// label: "修改",
|
|
||||||
// btnType: "edit", // 按钮类型 add edit del custom
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
// 操作按钮
|
|
||||||
topBtn: true, // 是头部按钮
|
|
||||||
label: "添加",
|
|
||||||
btnStyle: "success",
|
|
||||||
btnType: "add", // 按钮类型 add edit del custom
|
|
||||||
},
|
|
||||||
{
|
|
||||||
topBtn: false,
|
|
||||||
label: "删除",
|
|
||||||
btnType: "del",
|
|
||||||
btnStyle: "danger",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
topBtn: true,
|
|
||||||
label: "重新计算考试上线数据",
|
|
||||||
click: RExamRankings,
|
|
||||||
btnStyle: "info",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
column: {
|
|
||||||
examId: {
|
|
||||||
label: "考试",
|
|
||||||
width: "180px",
|
|
||||||
search: new TableColumnSearch(true, ConditionalType.Equal), // 搜索
|
|
||||||
type: "dropdown",
|
|
||||||
},
|
|
||||||
tagName: {
|
|
||||||
label: "分段名称",
|
|
||||||
width: "180px",
|
|
||||||
edit: {
|
|
||||||
add: true,
|
|
||||||
rules: ruleRequiredI(20, 1),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
subjectId: {
|
|
||||||
label: "学科",
|
|
||||||
width: "100px",
|
|
||||||
search: new TableColumnSearch(true),
|
|
||||||
type: "dropdown",
|
|
||||||
custom: (row) =>
|
|
||||||
row.subjectId
|
|
||||||
? tableData.column.subjectId.setting.datasource.find(
|
|
||||||
(s) => s.value == row.subjectId
|
|
||||||
)?.text ?? "--"
|
|
||||||
: "总分",
|
|
||||||
edit: {
|
|
||||||
add: true,
|
|
||||||
rules: ruleRequired,
|
|
||||||
editDefault: -1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
maxScore: {
|
|
||||||
label: "最大分数",
|
|
||||||
width: "120px",
|
|
||||||
edit: {
|
|
||||||
add: true,
|
|
||||||
rules: ruleRequiredNumber,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
minScore: {
|
|
||||||
label: "最小分数",
|
|
||||||
width: "120px",
|
|
||||||
edit: {
|
|
||||||
add: true,
|
|
||||||
rules: ruleRequiredNumber,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
createTime: {
|
|
||||||
label: "创建时间",
|
|
||||||
type: "datetime",
|
|
||||||
custom: (row) => row.createTime?.replace("T", " ").substring(0, 10) ?? "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data: [],
|
|
||||||
pageData: {
|
|
||||||
total: 0,
|
|
||||||
},
|
|
||||||
selectRows: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
const Api = new hTableAPI(`Exam`);
|
|
||||||
const showTable = ref(false);
|
|
||||||
onMounted(async () => {
|
|
||||||
//初始化数据原
|
|
||||||
|
|
||||||
tableData.column.examId.setting.datasource = (await Api.querycombo()).data;
|
|
||||||
tableData.column.subjectId.setting.datasource = [
|
|
||||||
{ text: "总分", value: -1 },
|
|
||||||
...(await getenum("SubjectEnum")).data,
|
|
||||||
];
|
|
||||||
|
|
||||||
showTable.value = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
async function RExamRankings() {
|
|
||||||
try {
|
|
||||||
await ElMessageBox.confirm(
|
|
||||||
`重新计算考试上线数据,可能需要较长时间,是否继续?`,
|
|
||||||
"确认",
|
|
||||||
{
|
|
||||||
confirmButtonText: "继续",
|
|
||||||
cancelButtonText: "取消",
|
|
||||||
type: "warning",
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const res = await RecalculateExamRankings(props.data[0].id);
|
|
||||||
if (res.code == 200) {
|
|
||||||
ElMessage.success("操作成功");
|
|
||||||
} else {
|
|
||||||
ElMessage.error(res.message || "操作失败");
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
ElMessage.info("取消操作");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div><ahTable v-if="showTable" ref="table" :tableConfig="tableData" /></div>
|
|
||||||
</template>
|
|
||||||
|
|
@ -78,19 +78,6 @@ const tableData: TableConfig = intTableData({
|
||||||
height: "800px", // 弹框高度
|
height: "800px", // 弹框高度
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
topBtn: false, // 头部按钮
|
|
||||||
show: true,
|
|
||||||
label: "分段",
|
|
||||||
btnType: "custom", // 按钮类型 add edit del 不设置则 自定义按钮
|
|
||||||
btnStyle: "info",
|
|
||||||
custom: {
|
|
||||||
title: "考试分段", // 弹出框title
|
|
||||||
src: "exam/examTags", // 组件路径
|
|
||||||
width: "1200px", // 弹框宽度
|
|
||||||
height: "800px", // 弹框高度
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
topBtn: false, // 头部按钮
|
topBtn: false, // 头部按钮
|
||||||
show: true,
|
show: true,
|
||||||
|
|
@ -120,7 +107,7 @@ const tableData: TableConfig = intTableData({
|
||||||
edit: {
|
edit: {
|
||||||
add: true,
|
add: true,
|
||||||
edit: true,
|
edit: true,
|
||||||
rules: ruleRequiredI(20, 2),
|
rules: ruleRequired,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
gradeLevel: {
|
gradeLevel: {
|
||||||
|
|
@ -223,11 +210,8 @@ const showTable = ref(false);
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
//初始化数据原
|
//初始化数据原
|
||||||
|
|
||||||
tableData.column.gradeLevel.setting.datasource = (
|
tableData.column.gradeLevel.setting.datasource =
|
||||||
await getenum("GradeLevelEnum")
|
(await getenum("GradeLevelEnum")).data.map(s=>{return {value : s.text,text:s.text}});
|
||||||
).data.map((s) => {
|
|
||||||
return { value: s.text, text: s.text };
|
|
||||||
});
|
|
||||||
|
|
||||||
tableData.column.testPaperType.setting.datasource = (
|
tableData.column.testPaperType.setting.datasource = (
|
||||||
await getenum("TestPaperTypeEnum")
|
await getenum("TestPaperTypeEnum")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue