| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657 |
- <template>
- <div class="page_item step_2_content page_search">
- <div class="container_left">
- <FormSearchGroup :searchList="searchList" @searchChange="HandleSearchChange"></FormSearchGroup>
-
- <Table
- :hidePagination="true"
- class="teacher_table"
- :tableColumns="teacherTableColumns"
- :tableData="teacherList"
- :tableRowClassName="tableRowClassName"
- @rowClick="HandleSelectTeacher"
- ></Table>
- </div>
- <div class="container_right">
- <div class="search_content">
- <!-- 年级切换 -->
- <div class="content_left">
- <TabSearch
- class="grade_tab"
- tabType="box"
- :tabList="gradeList"
- :defaultTabKey="searchParmams.gradeId"
- @tabChange="(val)=>HandleTabChange(val,'grade')">
- </TabSearch>
- </div>
- <div class="content_right">
- <el-button class="delete_button_border_no_bg" @click="ClearTeachingRelationship">清空授课</el-button>
- <el-button class="button_refresh">批量导出</el-button>
- <el-button class="button_refresh">批量导入</el-button>
- <el-button class="button_background" @click="FinishTeachingRelationship">完成</el-button>
- </div>
- </div>
- <div class="page_jg_20"></div>
- <div class="search_content">
- <div class="content_left">
- <TabSearch
- tabType="line"
- :tabList="tabList"
- :defaultTabKey="searchParmams.classType"
- @tabChange="(val)=>HandleTabChange(val,'classType')"> </TabSearch>
- </div>
- <div class="content_right">
- <span v-if="isConfigMode" class="config_switch_desc">
- {{ selectedTeacher?.teacherId ? `当前选中的教师:${selectedTeacher.teacherName} ${selectedTeacher.userAccount}` : '暂无选中的教师' }}
- </span>
- <el-switch v-model="isConfigMode"
- style="--el-switch-on-color: #2E64FA"
- active-text="选中教师配置任课关系" />
- </div>
- </div>
- <div class="page_solid_line"></div>
- <div class="page_jg_20"></div>
- <div class="end_item">
- <!-- 行政班渲染表数据 -->
- <Table v-if="searchParmams.classType === 'xingzeng'"
- :tableColumns="filterAdministrativeClassTableColumns"
- :tableData="administrativeClassTableData"
- :hidePagination="true">
- <template #className="{row}">
- {{ row.className.className }}
- </template>
- <template v-for="column in filterAdministrativeClassTableColumns.slice(1)" :key="column.name" v-slot:[column.name]="{row}">
-
- <div class="cell_container" @click="HandleAddTeacher(row, column.name,'administrative')">
- <template v-if="row?.[column.name] && row?.[column.name]?.length > 0">
- <div v-for="(teacher, idx) in row?.[column.name]" :key="teacher.teacherId">
- <el-tooltip
- effect="dark"
- :content="`${teacher.teacherName} ${teacher.userAccount}`"
- placement="top-start"
- >
- <div v-if="isConfigMode" class="teacher_tag">
- <span :title="teacher.teacherName">{{ teacher.teacherName }}</span>
- <el-icon class="delete_icon" @click.stop="HandleRemoveTeacher(row, column.name, idx,'administrative')"><Close /></el-icon>
- </div>
- <div v-else class="disabled_teacher">
- <span :title="teacher.teacherName">{{ teacher.teacherName }}</span>
- </div>
- </el-tooltip>
- </div>
- </template>
- <template v-else>
- <span v-if="isConfigMode" class="placeholder_text" >请选择教师</span>
- <span v-else>-</span>
- </template>
- </div>
- </template>
- </Table>
- <!-- 教学班渲染表数据 -->
- <Table v-else-if="searchParmams.classType === 'teach'"
- :tableColumns="filterTeachingClassTableColumns"
- :tableData="teachingClassTableData"
- :hidePagination="true">
- <template v-for="column in filterTeachingClassTableColumns" :key="column.name" v-slot:[column.name]="{row}">
- <div class="cell_container teaching_cell_container" @click="HandleAddTeacher(row, column.name,'teach')">
- <div class="class_name">
- {{ row?.[column.name]?.className.className }}
- </div>
- <div class="teaching_teacher_list" v-if="row?.[column.name]?.className?.className && row?.[column.name]?.teacherList?.length > 0">
- <div v-for="(teacher, idx) in row?.[column.name]?.teacherList" :key="teacher.teacherId">
- <el-tooltip
- effect="dark"
- :content="`${teacher.teacherName} ${teacher.userAccount}`"
- placement="top-start"
- >
- <div v-if="isConfigMode" class="teacher_tag">
- <span :title="teacher.teacherName">{{ teacher.teacherName }}</span>
- <el-icon class="delete_icon" @click.stop="HandleRemoveTeacher(row, column.name, idx,'teach')"><Close /></el-icon>
- </div>
- <div v-else class="disabled_teacher">
- <span :title="teacher.teacherName">{{ teacher.teacherName }}</span>
- </div>
- </el-tooltip>
- </div>
- </div>
- <template v-else-if="row?.[column.name]?.className?.className">
- <span v-if="isConfigMode" class="placeholder_text" >请选择教师</span>
- <span v-else>-</span>
- </template>
- </div>
- </template>
- </Table>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { ref, reactive, onMounted } from 'vue';
- import { useRoute } from 'vue-router';
- import { useStore } from 'vuex';
- import { Close } from '@element-plus/icons-vue';
- import FormSearchGroup from '@/baseComponents/FormSearchGroup.vue';
- import Table from '@/baseComponents/Table.vue';
- import TabSearch from '@/baseComponents/TabSearch.vue';
- import {
- getTeachingRelationshipTableDataApi, getTeacherListDataApi,
- saveTeachingRelationshipApi, deleteTeachingRelationshipApi,
- finishTeachingRelationshipApi,clearTeachingRelationshipApi
- } from '@/api/teachingRelationshipComponent'
- import {getEvaluationDataDetailApi} from '@/api/evaluationDataComponent'
- import {administrativeClassTableColumns,teacherTableColumns,teachingClassTableColumns} from './table'
- import { ElMessage } from 'element-plus';
- import router from '@/router';
- const route = useRoute()
- const store = useStore()
- // 配置模式开关
- const isConfigMode = ref(true);
- // 1. 查询参数 列表 配置
- const tabList = ref([
- {
- label:'行政班',
- key:'xingzeng',
- },
- {
- label:'教学班',
- key:'teach',
- },
- ]);
- // 搜索列表配置
- const searchList = ref([
- {
- key: 'searchKey',
- type: 'input',
- placeholder: '教师姓名、账号',
- }
- ]);
- // 查询参数
- const searchParmams = ref({
- gradeId:'',
- classType:'teach',
- searchKey:''
- })
- // 年级列表
- interface GradeItm {
- label:string,
- key:string
- }
- const gradeList = ref<GradeItm[]>([])
- interface GradeClassType {
- gradeId:string,
- administrativeClassStatus: number|string, // 0关闭 1开启
- teachingClassStatus: number|string // 0关闭 1开启
- }
- const gradeClassTypeStatus = ref<GradeClassType[]>([]) //存储 不同年级的班级类型状态
- // 获取年级列表信息
- const GetGradeList = async()=>{
- let id = route.query.id
- let res = await getEvaluationDataDetailApi(id)
- if(res?.code == 200){
- gradeList.value = res?.data.map((item,index)=>{
- gradeClassTypeStatus.value[index] = {
- gradeId:item.id,
- administrativeClassStatus: item.administrativeClassStatus,
- teachingClassStatus: item.teachingClassStatus
- }
- return {
- label:item.gradeName,
- key:item.id
- }
- }) || []
- searchParmams.value.gradeId = gradeList.value[0].key
- }
- }
- // 2. 教师列表数据
- interface TeacherItm {
- id: null | string
- teacherId: string
- teacherName: string
- userAccount: string
- }
- const teacherList = ref<TeacherItm[]>([]);
- // 选中的教师ID
- const selectedTeacher = ref()
- // 获取教师列表数据
- const GetTeacherTableData = async ()=>{
- let params = {
- evaluationId: route.query.id,
- evaluationGradeId: searchParmams.value.gradeId,
- teacherName: searchParmams.value.searchKey
- }
- let res = await getTeacherListDataApi(params)
- if(res?.code == 200){
- teacherList.value = res.data || []
- }
- }
- // 行选中 选择教师
- const HandleSelectTeacher = (teacher) => {
- selectedTeacher.value = {
- teacherId:teacher.teacherId,
- teacherName:teacher.teacherName,
- userAccount:teacher.userAccount,
- };
- };
- // 设置表行选中 样式
- const tableRowClassName = ({row,rowIndex})=>{
- if(row.teacherId == selectedTeacher.value?.teacherId){
- return 'active_row'
- }
- }
- // 搜索变化处理
- const HandleSearchChange = async (params) => {
- console.log('搜索参数', params);
- searchParmams.value.searchKey = params.searchKey
- // 重查教师账号信息
- await GetTeacherTableData()
- };
- // 3. 授课关系数据
- // 行政班 表头
- const filterAdministrativeClassTableColumns = ref([...administrativeClassTableColumns.value])
- // 教学班 表头
- const filterTeachingClassTableColumns = ref([...teachingClassTableColumns.value])
- const administrativeClassTableData = ref([]); // 行政班授课关系数据
- const teachingClassTableData = ref([]) //教学班授课关系数据
- // 获取表格授课关系配置数据
- const GetTeachingRelationshipData = async ()=>{
- teachingClassTableData.value = []
- administrativeClassTableData.value = []
- let res = await getTeachingRelationshipTableDataApi(searchParmams.value.gradeId)
- if(res?.code == 200){
- // 行政班数据 行政班科目 教学班数据 教学班科目
- const {administrativeClassData,administrativeSubjectLists,
- teachingClassData, teachingSubjectLists,
- } = res.data
-
- // 行政班数据渲染
- let administrativeHeaderColumn = administrativeSubjectLists.map(item=>{
- return {
- name: item.subjectId,
- label: item.name,
- width: '140',
- custom: true,
- fixed:'',
- hidden: false,
- align:'center',
- }
- })
- filterAdministrativeClassTableColumns.value = [...administrativeClassTableColumns.value,...administrativeHeaderColumn]
- administrativeClassTableData.value = administrativeClassData.map(item=>{
- let subjectOpt = {}
- item.subjectData.map(subject=>{
- subjectOpt[subject.subjectId] = subject.teacherData
- })
- return {
- className:{
- className:item.className,
- evaluationClassId:item.evaluationClassId
- },
- ...subjectOpt
- }
- })
- // 教学班数据渲染
- let teachingHeaderColumn = teachingSubjectLists.map(item=>{
- return {
- name: item.subjectId,
- label: item.name,
- width: '140',
- custom: true,
- fixed:'',
- hidden: false,
- align:'center',
- }
- })
- filterTeachingClassTableColumns.value = [...teachingClassTableColumns.value,...teachingHeaderColumn];
- teachingClassData.map((subjectItm:any)=>{
- let subjectId = subjectItm.subjectId
- subjectItm?.classData.map((classItm,idx)=>{
- let subjectOpt = {
- className:{
- className:classItm.className,
- evaluationClassId:classItm.evaluationClassId
- },
- teacherList:classItm.teacherData
- }
- if(typeof teachingClassTableData.value[Number(idx)] === 'object'){
- teachingClassTableData.value[Number(idx)][subjectId] = subjectOpt
- }else{
- teachingClassTableData.value[Number(idx)] = {}
- teachingClassTableData.value[Number(idx)][subjectId] = subjectOpt
- }
- });
- })
- }
- }
- // 添加教师
- const HandleAddTeacher = async (row, cell,type) => {
- if (!isConfigMode.value) return;
- if (!selectedTeacher.value) return;
- let teacherMsg = {
- teacherId: selectedTeacher.value?.teacherId,
- teacherName: selectedTeacher.value?.teacherName,
- userAccount:selectedTeacher.value?.userAccount
- }
- switch(type){
- case 'administrative':{
- // 行政班
- if (!row[cell]) {
- row[cell] = [];
- }
- let res = await saveTeachingRelationshipApi({
- ...teacherMsg,
- evaluationId:route.query.id,
- evaluationGradeId:searchParmams.value.gradeId,
- evaluationSubjectId:cell,
- evaluationClassId:row.className.evaluationClassId,
- classType:searchParmams.value.classType == 'teach' ? 1 : 0 //班级类型,0-行政班,1-教学班
- })
- if(res?.code == 200){
- ElMessage.success(res?.msg)
- row[cell].push({...teacherMsg,id:res?.data});
- }
- break
- }
- case 'teach':{
- if (row?.[cell]?.className?.className && !row?.[cell]?.teacherList) {
- row[cell] = {
- name:row?.[cell]?.className,
- teacherList:[]
- }
- }
-
- let res = await saveTeachingRelationshipApi({
- ...teacherMsg,
- evaluationId:route.query.id,
- evaluationGradeId:searchParmams.value.gradeId,
- evaluationSubjectId:cell,
- evaluationClassId:row[cell].className.evaluationClassId,
- classType:searchParmams.value.classType == 'teach' ? 1 : 0 //班级类型,0-行政班,1-教学班
- })
- if(res?.code == 200){
- ElMessage.success(res?.msg)
- row[cell].teacherList.push({...teacherMsg,id:res?.data});
- }
- break
- }
- }
- };
- // 移除教师
- const HandleRemoveTeacher = async (row, cell, index,type) => {
- if (!isConfigMode.value) return;
- let id = null
- let res = undefined
- switch(type){
- case 'teach':{
- id = row[cell].teacherList[index].id
- res = await deleteTeachingRelationshipApi(id)
- if(res?.code == 200){
- ElMessage.success(res?.msg)
- row[cell].teacherList.splice(index, 1);
- }
- break
- }
- case 'administrative':{
- id = row[cell][index].id
- res = await deleteTeachingRelationshipApi(id)
- if(res?.code == 200){
- ElMessage.success(res?.msg)
- row[cell].splice(index, 1);
- }
- break
- }
- }
- };
- // 4 综合.
- // 标签切换处理 年级/班级类型
- const HandleTabChange = async (val,type) => {
- console.log('当前选中的tab',val,type)
- switch(type){
- case 'grade':{
- let aimClassTypeStatus = gradeClassTypeStatus.value.find(item=>{
- return item.gradeId == val
- })
- tabList.value = []
- if(aimClassTypeStatus.administrativeClassStatus === 1){
- searchParmams.value.classType = 'xingzeng'
- tabList.value.push(
- {
- label:'行政班',
- key:'xingzeng',
- },
- )
- }
- if(aimClassTypeStatus.teachingClassStatus === 1){
- if(aimClassTypeStatus.administrativeClassStatus !== 1){
- searchParmams.value.classType = 'teach'
- }
- tabList.value.push(
- {
- label:'教学班',
- key:'teach',
- },
- )
- }
- searchParmams.value.gradeId = val
- await reloadData()
- break
- }
- case 'classType':{
- searchParmams.value.classType = val
- break
- }
- }
- };
- // 5. 完成授课关系
- const FinishTeachingRelationship = async ()=>{
- let params = gradeList.value.map(grade=>{
- return grade.key
- })
- let res = await finishTeachingRelationshipApi(params)
- if(res?.code == 200){
- // 更新全局状态 并 跳转到下一步
- await store.dispatch('updateEvaluationManageStepData',route.query.id)
- // 线上匿名 线下答卷
- // store.state.evaluationManageStepData.evaluationType // 评价方式 0-线上匿名,1-线下答卷,2-线上导入,3-线上实名
- if(store.state.evaluationManageStepData.evaluationType === 0){
- store.commit('updateEvaluationManageStepData',{currentActiveStepName:'questionnaireTemplate'}) //更新全局活跃路由
- router.push(`questionnaireTemplate?id=${route.query.id}`)
-
- }else if(store.state.evaluationManageStepData.evaluationType === 1){
- store.commit('updateEvaluationManageStepData',{currentActiveStepName:'numberMapping'}) //更新全局活跃路由
- router.push(`numberMapping?id=${route.query.id}`)
- }
- }
- }
- // 6. 清空授课关系
- const ClearTeachingRelationship = async ()=>{
- let id = searchParmams.value.gradeId
- let classType = searchParmams.value.classType == 'teach' ? 1 : 0 //班级类型,0-行政班,1-教学班
- let res = await clearTeachingRelationshipApi(id,classType)
- if(res?.code == 200){
- ElMessage.success(res?.msg)
- // 重查页面
- await GetTeachingRelationshipData()
- }
- }
- // 重新加载页面数据
- const reloadData =async ()=>{
- await GetTeacherTableData()
- await GetTeachingRelationshipData()
- }
- onMounted( async ()=>{
- await GetGradeList()
- HandleTabChange(searchParmams.value.gradeId,'grade')
- })
- </script>
- <style lang="scss" scoped>
- .step_2_content {
- height: calc(100%);
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- align-items: stretch;
- gap:20px;
- overflow: auto;
- .container_left {
- flex-shrink: 0;
- display: flex;
- flex-direction: column;
- overflow: auto;
-
- width: 200px;
- height: 100%;
- .teacher_table{
- margin-top: 16px;
- :deep(.el-table__body){
- tr.active_row td
- {
- background-color: rgba(46, 100, 250,0.1) !important;
- border:none;
- color: #2e64fa;
- }
- }
- }
- }
- .container_right {
- height: 100%;
- display: flex;
- flex-direction: column;
- overflow: auto;
- .config_switch_desc{
- font-size: 14px;
- }
- .end_item{
- overflow-y: auto;
- }
- .grade_tab{
- gap:10px;
- :deep(> span){
- border: 1px solid #dcdfe6 !important;
- border-radius: 6px;
- }
- }
- }
- }
- /* 单元格内部组件样式 */
- .cell_container {
- text-align: center;
- display: flex;
- justify-content: flex-start;
- flex-wrap: wrap;
- align-items: center;
- padding: 8px;
- gap: 8px;
- &.teaching_cell_container{
- flex-wrap: nowrap;
- .class_name{
- word-break: keep-all;
- }
- }
- .teaching_teacher_list{
- display: flex;
- justify-content: flex-start;
- flex-wrap: wrap;
- align-items: center;
- gap: 8px;
- }
- .disabled_teacher,
- .placeholder_text {
- width: 90px;
- height: 36px;
- font-weight: 400;
- font-size: 14px;
- color: #CCCCCC;
- text-align: center;
- line-height: 36px;
- background-color: #f3f3f3;
- border-radius: 4px;
- cursor: pointer;
- }
- .disabled_teacher{
- color:#666666;
- }
- .teacher_tag {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 0 8px;
- min-width: 90px;
- height: 36px;
- font-weight: 400;
- font-size: 14px;
- color: #2E64FA;
- text-align: center;
- line-height: 36px;
- background: rgba(46, 100, 250, 0.1);
- border-radius: 4px;
- .delete_icon {
- cursor: pointer;
- font-size: 12px;
- }
- }
- }
- </style>
|