From 44e387310f750293bf54d65eac32bc49ba7297b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E8=82=A5=E7=BE=8A?= <1048382248@qq.com> Date: Mon, 18 Aug 2025 18:00:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=20=E8=80=83=E8=AF=95?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 2 +- src/api/exam.ts | 24 ++++++ src/api/userCenter.ts | 6 +- src/components/hTable/hTable.ts | 135 +++++++++++++++++--------------- src/components/hTable/index.vue | 3 +- src/views/exam/classDetails.vue | 10 ++- src/views/exam/index.vue | 40 +++++++++- src/views/exam/userDetails.vue | 127 +++++++++++++++++------------- src/views/teacher/index.vue | 8 +- 9 files changed, 223 insertions(+), 132 deletions(-) create mode 100644 src/api/exam.ts diff --git a/.env.development b/.env.development index 93c993a..f8f8e9a 100644 --- a/.env.development +++ b/.env.development @@ -9,4 +9,4 @@ VITE_ROUTER_HISTORY = "hash" # 接口地址 VITE_API_BASEURL = "http://localhost:5199/api" #数据中心后台地址 -VITE_API_USERCENTER_URL = "https://dca.w.23544.com:8843/api/" +VITE_API_USERCENTER_URL = "https://dca.w.23544.com:8843/api" diff --git a/src/api/exam.ts b/src/api/exam.ts new file mode 100644 index 0000000..5668245 --- /dev/null +++ b/src/api/exam.ts @@ -0,0 +1,24 @@ +import { http } from "@/utils/http"; +import type { Res } from "@/utils/http/types"; + +/** + * @description 导入表单 + * @return {object} + */ +export function ImportExamInfo(id: number, file: File) { + let formData = new FormData(); + formData.append("eId", id.toString()); + formData.append("file", file); + return http.request( + "post", + `ExamClassInfo/Import`, + { + data: formData + }, + { + headers: { + "Content-Type": "application/x-www-form-urlencoded" + } + } + ); +} diff --git a/src/api/userCenter.ts b/src/api/userCenter.ts index 3a454ef..5ddc5b0 100644 --- a/src/api/userCenter.ts +++ b/src/api/userCenter.ts @@ -1,3 +1,4 @@ +import { ComboModel } from "@/components/hTable/hTable"; import { http } from "@/utils/http"; import type { Res, ResPage } from "@/utils/http/types"; /** @@ -28,7 +29,10 @@ export function EditSchool(data: any) { * @return {void} */ export function getSchoolData() { - return http.request>("get", `userCenter/public/getschooldata`); + return http.request>( + "get", + `userCenter/public/getschooldata` + ); } /** * @description 获取职位列表 diff --git a/src/components/hTable/hTable.ts b/src/components/hTable/hTable.ts index b97653f..f000c78 100644 --- a/src/components/hTable/hTable.ts +++ b/src/components/hTable/hTable.ts @@ -1,66 +1,73 @@ export interface Dialog { - /* 对话框是否可见 */ + /** 对话框是否可见 */ visible: boolean; - /* 是否显示关闭按钮 */ + /** 是否显示关闭按钮 */ close: boolean; - /* 对话框标题 */ + /** 对话框标题 */ title: string; - /* 对话框宽度 */ + /** 对话框宽度 */ width: string; /**自定义弹窗数据 */ custom: { - /* 自定义对话框高度 */ + /** 自定义对话框高度 */ height: string; - /* 自定义对话框数据 */ + /** 自定义对话框数据 */ data: any[]; - /* 自定义组件路径 */ + /** 自定义组件路径 */ src?: string; - /* 自定义配置项 */ + /** 自定义配置项 */ custom: Record; - /* 自定义对话框是否可见 */ + /** 自定义对话框是否可见 */ visible: boolean; - /* 异步加载组件 */ + /** 异步加载组件 */ component: any; }; edit: { - /* 编辑项ID */ + /** 编辑项ID */ id: number; - /* 编辑对话框标题 */ + /** 编辑对话框标题 */ title: string; - /* 编辑对话框是否可见 */ + /** 编辑对话框是否可见 */ visible: boolean; row?: any; tagData?: any; }; } -/* 按钮自定义配置 */ +/** 按钮自定义配置 */ export interface ButtonCustomConfig { - /* 弹出框标题 */ + /** 弹出框标题 */ title: string; - /* 组件路径 */ + /** 组件路径 */ src: string; - /* 弹框宽度 */ + /** 弹框宽度 */ width: string; - /* 弹框高度 */ + /** 弹框高度 */ height: string; } -/* 操作按钮配置 */ +/** 操作按钮配置 */ export interface OperationButton { - /* 是否为头部按钮 */ + /** 是否为头部按钮 */ topBtn: boolean; /** 按钮权限码 */ perms?: string; - /* 是否显示 */ + /** 是否显示 */ show?: boolean; - /* 按钮文本 */ + /** 按钮文本 */ label: string; - /* 按钮类型 */ - btnType: "add" | "edit" | "del" | "custom"; - /* 按钮样式 */ + /** 按钮点击事件 + * @tips btnType 为空时触发 + * @param obj 当前按钮配置对象 + * @param row 当前行数据 + * @param handleReloadPaged 父表单刷新函数 + */ + click?: (obj, row, handleReloadPaged: (reload: boolean) => void) => void; + /** 按钮类型 */ + btnType?: "add" | "edit" | "del" | "custom"; + /** 按钮样式 */ btnStyle?: "success" | "info" | "primary" | "danger" | "warning"; - /* 自定义按钮配置 */ + /** 自定义按钮配置 */ custom?: ButtonCustomConfig; } @@ -85,7 +92,7 @@ export enum ConditionalType { Range } -/* 字段设置项 */ +/** 字段设置项 */ export interface FieldSetting { /**map 时Value的取值的属性 */ mapValue?: string; @@ -100,30 +107,30 @@ export interface FieldSetting { * @returns 预期返回有效图片地址url */ imgUrl?: (value: any, row: any) => string; - /* 数据源 */ + /** 数据源 */ datasource?: ComboModel[]; } -///* 表格列配置 */ +///** 表格列配置 */ //export interface TableEditColumn {} export interface ComboModel { value: any; text: string; } -/* 表格列配置 */ +/** 表格列配置 */ export interface TableColumn { - /* 显示标签 */ + /** 显示标签 */ label: string; - /* 是否可搜索 */ + /** 是否可搜索 */ search: boolean; - /* 搜索类型 */ + /** 搜索类型 */ searchType?: ConditionalType; - /* 是否允许添加 */ - add: boolean; - /* 是否允许修改 */ + /** 是否允许添加 [false]*/ + add?: boolean; + /** 是否允许修改 [false]*/ edit?: boolean; - /* 列宽度 */ + /** 列宽度 [auto]*/ width?: string; - /* 字段类型 */ + /** 字段类型 */ type?: "string" | "dropdown" | "switch" | "img" | "datetime" | "textarea"; /** 是否多选 */ multiple?: boolean; @@ -133,11 +140,11 @@ export interface TableColumn { rules?: any | Array; /** 显示列 */ show?: boolean; - /* 字段设置 */ + /** 字段设置 */ setting?: FieldSetting; - /* 修改时的编辑值 */ + /** 修改时的编辑值 */ valueE?: Array | string | number | boolean | Date; - /* 查询值 */ + /** 查询值 */ value?: Array | string | number | boolean | Date; /** textarea编辑时的行数 */ editRows?: number; @@ -147,13 +154,13 @@ export interface TableColumn { custom?: (row: any) => string; } -/* 分页数据 */ +/** 分页数据 */ export interface PageData { - /* 总条数 */ + /** 总条数 */ total: number; } -/* 分页数据 */ +/** 分页数据 */ export interface ConditionalModel { /** 字段名称 */ FieldName: string; @@ -165,49 +172,49 @@ export interface ConditionalModel { CSharpTypeName?: string; } -/* 搜索条件 */ +/** 搜索条件 */ export interface SearchConditions { - /* 是否显示搜索 */ + /** 是否显示搜索 */ show: boolean; - /* 当前页码 */ + /** 当前页码 */ PageIndex: number; - /* 每页大小 */ + /** 每页大小 */ PageSize: number; - /* 排序字段 */ + /** 排序字段 */ OrderBy: string; - /* 默认查询条件 */ + /** 默认查询条件 */ defaultConditions: ConditionalModel[]; - /* 查询条件 */ + /** 查询条件 */ Conditions: any[]; } -/* 表格配置 */ +/** 表格配置 */ export interface TableConfig { - /* 搜索回调函数 */ + /** 搜索回调函数 */ searchCallback?: (s: SearchConditions) => void; - /* 新增/修改回调函数 */ + /** 新增/修改回调函数 */ editCallback?: (from: any) => void; - /* API地址 */ + /** API地址 */ apiUrl: string; - /* 是否显示选择列 */ + /** 是否显示选择列 */ selectColumn: boolean; - /* 搜索配置 */ + /** 搜索配置 */ search: SearchConditions; - /* 是否显示操作列 */ + /** 是否显示操作列 */ operationColumn: boolean; - /* 操作按钮配置 */ + /** 操作按钮配置 */ operationColumnData: OperationButton[]; - /* 列配置 */ + /** 列配置 */ column: Record; - /* 表格数据 */ + /** 表格数据 */ data: any[]; /**显示头部操作按钮 */ operationTop?: boolean; - /* 分页数据 */ + /** 分页数据 */ pageData: PageData; - /* 选中行 */ + /** 选中行 */ selectRows: any[]; - /* 是否显示边框 */ + /** 是否显示边框 */ border: boolean; /**是否显示 */ show?: boolean; diff --git a/src/components/hTable/index.vue b/src/components/hTable/index.vue index 29e27c2..3ebbba5 100644 --- a/src/components/hTable/index.vue +++ b/src/components/hTable/index.vue @@ -108,7 +108,8 @@ function intdata() { // 处理 column 的属性 for (const key in table.value.column) { const element = table.value.column[key]; - + if (element.add === undefined) element.add = false; + if (element.edit === undefined) element.edit = false; // Vue 3 中直接赋值即可,不需要 $set if (element.valueE === undefined) element.valueE = element.multiple ? [] : ""; diff --git a/src/views/exam/classDetails.vue b/src/views/exam/classDetails.vue index d91c0a4..1304807 100644 --- a/src/views/exam/classDetails.vue +++ b/src/views/exam/classDetails.vue @@ -66,7 +66,13 @@ const tableData: TableConfig = { show: true, label: "学生成绩详情", btnType: "custom", - btnStyle: "primary" // topBtn: true才生效 success danger + btnStyle: "primary", + custom: { + title: "考试班级详情", // 弹出框title + src: "exam/userDetails", // 组件路径 + width: "1600px", // 弹框宽度 + height: "800px" // 弹框高度 + } } ], column: { @@ -102,7 +108,7 @@ const tableData: TableConfig = { add: false, // 字段允许添加 edit: false // 字段允许修改 }, - etryPerson: { + entryPerson: { label: "录入人", width: "200px", search: true, diff --git a/src/views/exam/index.vue b/src/views/exam/index.vue index 3089926..5cd7edd 100644 --- a/src/views/exam/index.vue +++ b/src/views/exam/index.vue @@ -6,6 +6,8 @@ import { fa } from "element-plus/es/locales.mjs"; import { hTableAPI } from "@/api/hTable"; import { getenum } from "@/api/enum"; import { ruleRequired, ruleRequiredNumber } from "@/utils/rules"; +import { ImportExamInfo } from "@/api/exam"; +import { ElMessage } from "element-plus"; const ControllerName = "Exam"; defineOptions({ @@ -60,15 +62,15 @@ const tableData: TableConfig = { custom: { title: "考试班级详情", // 弹出框title src: "exam/classDetails", // 组件路径 - width: "1600px", // 弹框宽度 - height: "520px" // 弹框高度 + width: "1300px", // 弹框宽度 + height: "800px" // 弹框高度 } }, { topBtn: false, // 头部按钮 show: true, label: "录入成绩", - btnType: "custom", // 按钮类型 add edit del 不设置则 自定义按钮 + click: entryExam, btnStyle: "primary" // topBtn: true才生效 success danger } ], @@ -154,7 +156,39 @@ const tableData: TableConfig = { }, selectRows: [] }; +function entryExam(obj, row, callBack) { + let fileE = document.createElement("input"); + fileE.type = "file"; + var formData = new window.FormData(); + fileE.onchange = async function () { + formData.append("File", fileE.files[0]); + let res = await ImportExamInfo(row[0].id, fileE.files[0]); + if (res.code != undefined) { + if (res.code !== 200) return ElMessage.error(res.message); + else return ElMessage.success("所有数据录入成功"); + } else if (res.type === "application/json") { + let json = await res.text(); + if (json !== undefined && json.Code !== 200) { + return ElMessage.error(json.Message); + } else { + return ElMessage.success("操所有数据录入成功作成功"); + } + } else if (res === undefined || res.size === 0) + return ElMessage.success("所有数据录入成功"); + const url = res && window.URL.createObjectURL(res); + const link = document.createElement("a"); + link.href = url; + link.setAttribute("download", "未成功导入的考试信息数据" + ".xlsx"); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + ElMessage.success("操作成功,已导出重复数据"); + }; + try { + fileE.click(); + } catch (error) {} +} const showTable = ref(false); onMounted(async () => { //初始化数据原 diff --git a/src/views/exam/userDetails.vue b/src/views/exam/userDetails.vue index 5030e01..2e0fd78 100644 --- a/src/views/exam/userDetails.vue +++ b/src/views/exam/userDetails.vue @@ -38,78 +38,93 @@ const tableData: TableConfig = { { // 操作按钮 topBtn: true, // 是头部按钮 - label: "添加", - btnStyle: "success", - btnType: "custom" + label: "成绩升序", + btnStyle: "primary" + }, + { + // 操作按钮 + topBtn: true, // 是头部按钮 + label: "成绩降序", + btnStyle: "primary" }, { topBtn: false, // 头部按钮 - show: true, - label: "删除", - btnType: "del", // 按钮类型 add edit del 不设置则 自定义按钮 - btnStyle: "danger" // topBtn: true才生效 success danger - }, - { - topBtn: false, // 头部按钮 - show: true, - label: "重新录入", - btnType: "custom", // 按钮类型 add edit del 不设置则 自定义按钮 - btnStyle: "primary" // topBtn: true才生效 success danger - }, - { - topBtn: false, // 头部按钮 - show: true, - label: "学生成绩详情", + label: "个人详情", btnType: "custom", btnStyle: "primary" // topBtn: true才生效 success danger } ], column: { // 行数据 - schoolName: { - label: "学校", + userName: { + label: "姓名", search: true, searchType: ConditionalType.Like, // 搜索类型 - add: false, // 字段允许添加 - edit: false, // 字段允许修改 width: "180px" }, - grade: { - label: "年级", - width: "100px", - custom: s => `${s.gradeYear}${s.gradeLevel}`, - search: true, - add: false, // 字段允许添加 - edit: false // 字段允许修改 - }, - className: { - label: "班级", - width: "150px", - search: true, - searchType: ConditionalType.Like, // 搜索类型 - add: false, // 字段允许添加 - edit: false // 字段允许修改 - }, - peopleCount: { - label: "参考人数", - width: "100px", + 语文: { + label: "语文", search: false, - add: false, // 字段允许添加 - edit: false // 字段允许修改 + width: "100px", + custom: row => row.subjectDic.语文 }, - etryPerson: { - label: "录入人", - width: "200px", - search: true, - add: false, // 字段允许添加 - edit: false // 字段允许修改 + 数学: { + label: "数学", + search: false, + width: "100px", + custom: row => row.subjectDic.数学 }, - createTime: { - label: "录入时间", - width: "200px", - search: true, - add: false, // 字段允许添加 - edit: false // 字段允许修改 + 英语: { + label: "英语", + search: false, + width: "100px", + custom: row => row.subjectDic.英语 + }, + 物理: { + label: "物理", + search: false, + width: "100px", + custom: row => row.subjectDic.物理 + }, + 化学: { + label: "化学", + search: false, + width: "100px", + custom: row => row.subjectDic.化学 + }, + 生物: { + label: "生物", + search: false, + width: "100px", + custom: row => row.subjectDic.生物 + }, + 政治: { + label: "政治", + search: false, + width: "100px", + custom: row => row.subjectDic.政治 + }, + 历史: { + label: "历史", + search: false, + width: "100px", + custom: row => row.subjectDic.历史 + }, + 地理: { + label: "地理", + search: false, + width: "100px", + custom: row => row.subjectDic.地理 ?? "--" + }, + assignScore: { + label: "赋分总分", + search: false, + width: "180px" + }, + assignRanking: { + label: "赋分后的排名", + search: false, + width: "200px" } }, data: [], diff --git a/src/views/teacher/index.vue b/src/views/teacher/index.vue index 5892bd7..9f81387 100644 --- a/src/views/teacher/index.vue +++ b/src/views/teacher/index.vue @@ -364,10 +364,10 @@ const props = defineProps({ } }); -const baseUrl = import.meta.env.VITE_APP_BASE_API; -const excelImportUsersUrl = `${baseUrl}api/back/users/downloadimportusersexceltemplate`; -const excelImportMeetingUrl = `${baseUrl}api/back/users/downloadimportmeetingexceltemplate`; -const excelImportOrdersUrl = `${baseUrl}api/back/users/downloadimportordersexceltemplate`; +const baseUrl = import.meta.env.VITE_API_USERCENTER_URL; +const excelImportUsersUrl = `${baseUrl}/back/users/downloadimportusersexceltemplate`; +const excelImportMeetingUrl = `${baseUrl}/back/users/downloadimportmeetingexceltemplate`; +const excelImportOrdersUrl = `${baseUrl}/back/users/downloadimportordersexceltemplate`; const editId = ref(0); const showAllPosition = ref([]);