Files
--/src/view/homeView.vue
汤凯 49d0c43a2a 2
2025-12-08 17:19:41 +08:00

596 lines
16 KiB
Vue

<template>
<div v-loading="loading" class="h-[calc(100vh-144px)] flex px-[40px]">
<div
v-if="!(teacherList.data && teacherList.data.length)"
class="w-full h-full bg-white relative flex justify-center items-center"
>
<div class="no_data"></div>
</div>
<a-menu
v-if="teacherList.data && teacherList.data.length"
id="dddddd"
style="width: 256px"
v-model:selectedKeys="selectedKeys"
mode="inline"
class="h-full overflow-y-scroll mr-[20px]"
>
<a-menu-item
v-for="item in teacherList.data"
:key="item.teacherId"
@titleClick="titleClick"
@click="handleClick(item)"
>
<div class="flex justify-between">
<div>{{ item.name }}</div>
<div
@click="showTeacherDetail"
v-if="
item.teacherId == selectedKeys[0] &&
userStore.userInfo.data &&
userStore.userInfo.data.isLeader
"
class="mr-[20px]"
>
详情
</div>
</div>
</a-menu-item>
</a-menu>
<div
v-if="teacherList.data && teacherList.data.length"
class="w-[calc(100%-280px)] h-full"
>
<a-table
:columns="columns"
:data-source="stuList.data"
:scroll="{ y: 'calc(100vh - 264px)' }"
:pagination="{ pageSize: 50 }"
class="h-[calc(100%-300px)]"
>
<template #action="{ record }">
<span
@click="toStudetail(record)"
class="text-[#1677ff] cursor-pointer"
>
详情
</span>
</template>
</a-table>
</div>
<el-dialog
v-model="stuDetailVisible"
:close-on-click-modal="false"
title="学生详情"
width="800"
class="stu_detail"
>
<div class="w-full text-[16px]">
<div>
<div class="flex mb-[10px]">
<div class="text-[#333]">姓名:</div>
<div class="text-[#666]">{{ stuDetail.data.name || "-" }}</div>
</div>
<div class="flex mb-[10px]">
<div class="text-[#333]">学生号:</div>
<div class="text-[#666]">{{ stuDetail.data.studentId || "-" }}</div>
</div>
<!-- <div class="flex mb-[10px]">
<div class="text-[#333]">性别:</div>
<div class="text-[#666]">{{ stuDetail.data.gender || "-" }}</div>
</div> -->
<div class="flex mb-[10px]">
<div class="text-[#333]">院系:</div>
<div class="text-[#666]">
{{ stuDetail.data.departmentName || "-" }}
</div>
</div>
<div class="flex mb-[10px]">
<div class="text-[#333]">专业:</div>
<div class="text-[#666]">
{{ stuDetail.data.majorName || "-" }}
</div>
</div>
<!-- <div class="flex mb-[10px]">
<div class="text-[#333]">年级:</div>
<div class="text-[#666]">
{{ stuDetail.data.currentGrade || "-" }}
</div>
</div> -->
<div class="flex mb-[10px]">
<div class="text-[#333]">书院:</div>
<div class="text-[#666]">
{{ stuDetail.data.collegeName || "-" }}
</div>
</div>
<!-- <div class="flex mb-[10px]">
<div class="text-[#333]">班级:</div>
<div class="text-[#666]">
{{
(stuDetail.data.collegeClass &&
stuDetail.data.collegeClass.name) ||
"-"
}}
</div>
</div> -->
<div>
<div class="mb-[10px]">学生评估:</div>
<el-input
v-model="stuDetail.data.evaluation"
style="width: 100%"
:rows="12"
type="textarea"
placeholder="评估中"
:disabled="true"
/>
</div>
</div>
</div>
</el-dialog>
<el-dialog
v-model="teacherDetailVisible"
:close-on-click-modal="false"
title="教师详情"
width="800"
class="teacher_detail"
>
<div class="w-full text-[16px]">
<div v-if="teacherDail.data">
<div class="flex mb-[10px]">
<div class="text-[#333]">姓名:</div>
<div class="text-[#666]">
{{ teacherDail.data.name || "-" }}
</div>
</div>
<div class="flex mb-[10px]">
<div class="text-[#333]">职工号:</div>
<div class="text-[#666]">
{{ teacherDail.data.teacherId || "-" }}
</div>
</div>
<div class="flex mb-[10px]">
<div class="text-[#333]">性别:</div>
<div class="text-[#666]">
{{ teacherDail.data.gender || "-" }}
</div>
</div>
<div class="flex mb-[10px]">
<div class="text-[#333]">出生年份:</div>
<div class="text-[#666]">
{{ teacherDail.data.birthYear || "-" }}
</div>
</div>
<div class="flex mb-[10px]">
<div class="text-[#333]">入职时间:</div>
<div class="text-[#666]">
{{ teacherDail.data.hireDate || "-" }}
</div>
</div>
<div class="flex mb-[10px]">
<div class="text-[#333]">职称:</div>
<div class="text-[#666]">
{{ teacherDail.data.title || "-" }}
</div>
</div>
<div class="flex mb-[10px]">
<div class="text-[#333]">学历:</div>
<div class="text-[#666]">
{{ teacherDail.data.education || "-" }}
</div>
</div>
<div class="flex mb-[10px]">
<div class="text-[#333]">毕业院校:</div>
<div class="text-[#666]">
{{ teacherDail.data.graduationSchool || "-" }}
</div>
</div>
<div class="flex mb-[10px]">
<div class="text-[#333]">联系方式:</div>
<div class="text-[#666]">
{{ teacherDail.data.telphone || "-" }}
</div>
</div>
<div class="flex mb-[10px]">
<div class="flex-shrink-0 text-[#333]">著作:</div>
<div
v-if="teacherDail.data.books && teacherDail.data.books.length"
class="text-[#666]"
>
{{
teacherDail.data.books.map((item) => item.bookTitle).join("、")
}}
</div>
<div v-else>-</div>
</div>
<div class="flex mb-[10px]">
<div class="flex-shrink-0 text-[#333]">专利:</div>
<div
v-if="teacherDail.data.patents && teacherDail.data.patents.length"
class="text-[#666]"
>
{{
teacherDail.data.patents
.map((item) => item.patentName)
.join("、")
}}
</div>
<div v-else>-</div>
</div>
<div class="flex mb-[10px]">
<div class="flex-shrink-0 text-[#333]">授课科目:</div>
<div
v-if="
teacherDail.data.subjects && teacherDail.data.subjects.length
"
class="text-[#666]"
>
{{
teacherDail.data.subjects
.map((item) => item.subjectName)
.join("、")
}}
</div>
<div v-else>-</div>
</div>
<div class="flex mb-[10px]">
<div class="flex-shrink-0 text-[#333]">科研项目:</div>
<div
v-if="
teacherDail.data.researchProjects &&
teacherDail.data.researchProjects.length
"
class="text-[#666]"
>
{{
teacherDail.data.researchProjects
.map((item) => item.projectName)
.join("、")
}}
</div>
<div v-else>-</div>
</div>
<div class="flex mb-[10px]">
<div class="flex-shrink-0 text-[#333]">科研奖励:</div>
<div
v-if="
teacherDail.data.teachingAwards &&
teacherDail.data.teachingAwards.length
"
class="text-[#666]"
>
{{
teacherDail.data.teachingAwards
.map((item) => item.projectName)
.join("、")
}}
</div>
<div v-else>-</div>
</div>
<div class="flex mb-[10px]">
<div class="flex-shrink-0 text-[#333]">科研论文:</div>
<div
v-if="
teacherDail.data.researchPapers &&
teacherDail.data.researchPapers.length
"
class="pre_wrap text-[#666]"
>
{{
teacherDail.data.researchPapers
.map((item) => item.paperTitle)
.join(";\n")
}}
</div>
<div v-else>-</div>
</div>
<div>
<div class="mb-[10px]">教师评估:</div>
<el-input
v-model="teacherDail.data.evaluation"
style="width: 100%"
:rows="6"
type="textarea"
placeholder="评估中"
:disabled="true"
/>
</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { fetchEventSource } from "@microsoft/fetch-event-source";
import { useRouter, useRoute } from "vue-router";
import { watch } from "vue";
import {
loginAPI,
getTeacherListApi,
getStuListApi,
getStuInfoApi,
getTeacherInfoApi,
getTeacherDifyApi,
getStuDetailApi,
getStudentDifyApi,
} from "@/request/api";
import { useUserStore } from "@/store/user.ts";
import { ElMessage } from "element-plus";
let loading = ref(false);
let userStore: any = useUserStore();
const stuDetailVisible: any = ref(false);
const stuDetail: any = reactive({ data: {} });
const selectedKeys = ref([]);
// const openKeys = ref(["sub1"]);
const columns = [
{
title: "学生号",
dataIndex: "studentId",
key: "studentId",
},
{
title: "姓名",
dataIndex: "name",
key: "name",
},
{
title: "年级",
dataIndex: "currentGrade",
key: "currentGrade",
},
{
title: "院系",
dataIndex: "departmentName",
key: "departmentName",
},
{
title: "专业",
dataIndex: "majorName",
key: "majorName",
},
{
title: "书院",
dataIndex: "collegeName",
key: "collegeName",
},
{
title: "辅导员",
dataIndex: "counselor",
key: "counselor",
},
{
title: "详情",
key: "action",
slots: { customRender: "action" },
},
];
const teacherList = reactive({
data: [],
});
const teacherDetailVisible: any = ref(false);
const teacherDail = reactive({ data: { evaluation: "" } });
const stuList = reactive({
data: [],
});
const router = useRouter();
const route = useRoute();
const nowSelecTeacher = reactive({ data: {} });
watch(
() => userStore.menuInfo,
(N, O) => {
getTeacherList();
console.log("menuInfo1111111", userStore.menuInfo.key);
}
);
watch(
selectedKeys,
() => {
getStuList();
},
{
immediate: false,
deep: true,
}
);
onMounted(async () => {
getTeacherList();
});
onActivated(async () => {
getTeacherList();
});
let ipAddress = "http://zb89ba6d.natappfree.cc";
// async function getStuDetail() {
// let res = await getStuDetailApi();
// console.log("学生详情", res);
// }
async function getAIDetail(sseUrl: any, query: any) {
const controller = new AbortController();
const { signal } = controller;
fetchEventSource(sseUrl, {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json",
Accept: "text/event-stream",
Authorization: "Bearer " + userStore.userInfo.data.auth,
// credentials: "include",
},
credentials: "include",
// body: mes.replace(/\\/g, '\\\\'),
body: JSON.stringify({ query: JSON.stringify(query), user: "1" }),
signal,
openWhenHidden: true,
onmessage(e) {
console.log("e", e);
let temdata = "";
const chunk = e.data;
if (chunk === "[DONE]") {
return;
}
try {
temdata += chunk;
console.log("temdata", temdata);
} catch (error) {
console.error("Message update failed:", error);
controller.abort();
}
},
onclose() {
console.log("Connection closed");
controller.abort();
},
onerror(error) {
console.error("Error----------------->:", error);
controller.abort();
throw error;
},
});
}
async function toStudetail(data) {
console.log("data", data);
loading.value = true;
let res = await getStuInfoApi(data.id);
loading.value = false;
stuDetailVisible.value = true;
// let res2 = await getTeacherDifyApi(JSON.stringify(res.data));
// getAIDetail(ipAddress + `/mentors/dify`, res.data);
if (res.code == 200) {
// res.data.academicClassName = res.data?.academicClass?.name || "-";
// res.data.evaluation = res2.data;
stuDetail.data = res.data;
console.log("stuDetail.data", stuDetail.data);
console.log("res.data", JSON.stringify(res.data));
}
let res2 = await getStudentDifyApi(JSON.stringify(res.data));
stuDetail.data.evaluation = res2.data;
console.log("res2.data");
console.log("stuDetail.data", stuDetail.data);
// router.push({
// path: "/stu-detail",
// query: {
// id: data.studentId,
// },
// });
}
async function getTeacherList() {
let res = await getTeacherListApi(userStore.menuInfo.key);
console.log("res", res);
if (res?.data) {
teacherList.data.splice(0);
selectedKeys.value[0] = res?.data[0]?.teacherId || null;
nowSelecTeacher.data = res?.data[0] || {};
teacherList.data.push(...res?.data);
}
}
async function getStuList() {
console.log("getStuList", selectedKeys.value);
let res = await getStuListApi({ teacherId: selectedKeys.value[0] });
stuList.data.splice(0);
if (res?.data?.students?.length) {
res?.data?.students.forEach((item) => {
item.collegeName = item?.collegeName || "-";
item.majorName = item?.majorName || "-";
item.departmentName = item?.departmentName || "-";
item.counselor = item?.counselor || "-";
});
stuList.data.push(...res.data.students);
}
}
async function showTeacherDetail() {
loading.value = true;
let res = await getTeacherInfoApi(nowSelecTeacher.data.id);
loading.value = false;
if (res.code == 200) {
if (res.data) {
console.log("res.data", JSON.stringify(res.data));
teacherDail.data = res.data;
}
teacherDetailVisible.value = true;
// console.log("teacherDetailVisible.value", teacherDetailVisible.value);
} else {
ElMessage.error("获取数据失败,请稍后重试!");
}
let resDify = await getTeacherDifyApi(JSON.stringify(res.data));
teacherDail.data.evaluation = resDify.data;
}
function handleClick(data) {
nowSelecTeacher.data = data;
}
const titleClick = (e: Event) => {
console.log("titleClick", e);
};
function toAboutPage() {
router.push({
path: "/about",
query: {
title: "666",
},
});
}
function toTestPage() {
router.push({
path: "/test/" + 888,
});
}
</script>
<style scoped lang="less">
.no_data {
background: url("../assets/web/noData.png");
width: 400px;
height: 400px;
// background-image: url("../assets/web/noData.png");
// background-repeat: no-repeat;
// background-color: #333;
// position: absolute;
// left: 50%;
// top: 50%;
z-index: 100;
background-position: center;
background-size: cover;
}
.pre_wrap {
white-space: pre-wrap;
}
// .ant-table-wrapper {
// height: 100%;
// }
// :deep(.ant-spin-nested-loading) {
// height: 100%;
// }
// :deep(.ant-spin-container) {
// height: 100%;
// }
:deep(.ant-menu-item) {
// padding-left: 0 !important;
padding-right: 0 !important;
padding-top: 0 !important;
padding-bottom: 0 !important;
}
:deep(.stu_detail) {
background: linear-gradient(180deg, #e6fffc 0%, #ffffff 30%);
}
:deep(.teacher_detail) {
background: linear-gradient(180deg, #e6efff 0%, #ffffff 30%);
}
</style>