|
|
@@ -0,0 +1,514 @@
|
|
|
+<template>
|
|
|
+
|
|
|
+ <div class="page_item page_search number_mapping_content">
|
|
|
+ <div class="search_content">
|
|
|
+ <!-- 班级类型切换 -->
|
|
|
+ <div class="content_left">
|
|
|
+ <TabSearch
|
|
|
+ class="grade_tab"
|
|
|
+ tabType="box"
|
|
|
+ :tabList="gradeList"
|
|
|
+ :defaultTabKey="defaultTabkey"
|
|
|
+ @tabChange="(val)=>HandleTabChange(val)">
|
|
|
+ </TabSearch>
|
|
|
+ </div>
|
|
|
+ <div class="content_right">
|
|
|
+ <el-button class="button_background" @click="FinishNumberMapping">完成</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="page_jg_20"></div>
|
|
|
+
|
|
|
+ <div class="main_content">
|
|
|
+ <div class="container_left">
|
|
|
+ <div class="search_content">
|
|
|
+ <div class="content_left">
|
|
|
+ <div class="grade_title">可选班级</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="page_jg_20"></div>
|
|
|
+
|
|
|
+
|
|
|
+ <Table
|
|
|
+ :hidePagination="true"
|
|
|
+ class="teacher_table"
|
|
|
+ :currentPage="1" :totalNum="0"
|
|
|
+ :pageSize="200" :tableColumns="classTableColumns"
|
|
|
+ :tableData="classList"
|
|
|
+ :tableRowClassName="tableRowClassName"
|
|
|
+ @rowClick="HandleSelectRowClass"
|
|
|
+ ></Table>
|
|
|
+ </div>
|
|
|
+ <div class="container_right">
|
|
|
+
|
|
|
+ <div class="search_content">
|
|
|
+ <div class="content_left">
|
|
|
+ <div class="grade_title">班级编号对应表</div>
|
|
|
+ </div>
|
|
|
+ <div class="content_right">
|
|
|
+ <span v-if="isConfigMode" class="config_switch_desc">
|
|
|
+ {{ selectedClassItm?.id ? `当前选中的班级:${selectedClassItm.gradeName } ${selectedClassItm.className}` : '暂无选中的班级' }}
|
|
|
+ </span>
|
|
|
+ <el-switch v-model="isConfigMode"
|
|
|
+ style="--el-switch-on-color: #2E64FA"
|
|
|
+ active-text="选中班级配置编号关系" />
|
|
|
+ <el-button class="button_border" @click="AddOneRowClassCode">新增班级编号</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="page_jg_20"></div>
|
|
|
+
|
|
|
+ <div class="end_item">
|
|
|
+ <Table :currentPage="1" :pageSize="2"
|
|
|
+ :tableColumns="filterNumberMappingTableColumns"
|
|
|
+ :tableData="administrativeClassTableData"
|
|
|
+ :hidePagination="true"
|
|
|
+ :totalNum="0">
|
|
|
+
|
|
|
+ <template v-for="column in filterNumberMappingTableColumns.slice(1,-1)" :key="column.name" v-slot:[column.name]="{row}">
|
|
|
+ <div class="cell_container" @click="HandleAddClassBindCode(row, column.name)">
|
|
|
+ <template v-if="row?.[column.name] && row?.[column.name]?.length > 0">
|
|
|
+ <div v-for="(classItm, idx) in row?.[column.name]" :key="classItm.id">
|
|
|
+ <el-tooltip
|
|
|
+ effect="dark"
|
|
|
+ :content="`${classItm.gradeName} ${classItm.className}`"
|
|
|
+ placement="top-start"
|
|
|
+ >
|
|
|
+ <div v-if="isConfigMode" class="teacher_tag">
|
|
|
+ <span :title="classItm.className">{{ classItm.className }}</span>
|
|
|
+ <el-icon class="delete_icon" @click.stop="HandleRemoveCodeMappinClass(row, column.name, idx)"><Close /></el-icon>
|
|
|
+ </div>
|
|
|
+ <div v-else class="disabled_teacher">
|
|
|
+ <span :title="classItm.className">{{ classItm.className }}</span>
|
|
|
+ </div>
|
|
|
+ </el-tooltip>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <span v-if="isConfigMode" class="placeholder_text" >请选择班级</span>
|
|
|
+ <span v-else>-</span>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template #operation="{row,currentIndex}">
|
|
|
+ <div class="table_row_option">
|
|
|
+ <span
|
|
|
+ :class="[administrativeClassTableData?.length === currentIndex ? 'el_button_delete' : 'editor_disable']"
|
|
|
+ @click="administrativeClassTableData?.length === currentIndex ? HandleDeleteRowClassCode(row) : ''">删除</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </Table>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import { ref, onMounted, computed } from 'vue';
|
|
|
+import { useRoute } from 'vue-router';
|
|
|
+import { useStore } from 'vuex';
|
|
|
+
|
|
|
+import { Close } from '@element-plus/icons-vue';
|
|
|
+import Table from '@/baseComponents/Table.vue';
|
|
|
+import TabSearch from '@/baseComponents/TabSearch.vue';
|
|
|
+import {
|
|
|
+ getAlternativeClassDataApi,
|
|
|
+ getClassNumberMappingDataApi,
|
|
|
+ setClassNumberMappingDataApi,
|
|
|
+ deleteRowClassNumberMappingDataApi,
|
|
|
+ addRowClassNumberMappingDataApi,
|
|
|
+ finishNumberMappingDataApi,
|
|
|
+ deleteCodeMappinClassApi,
|
|
|
+} from '@/api/numberMappingComponent'
|
|
|
+
|
|
|
+import {numberMappingTableColumns,classTableColumns,} from './table'
|
|
|
+import { ElMessage } from 'element-plus';
|
|
|
+import router from '@/router';
|
|
|
+
|
|
|
+const route = useRoute()
|
|
|
+const store = useStore()
|
|
|
+
|
|
|
+// 配置模式开关
|
|
|
+const isConfigMode = ref(true);
|
|
|
+
|
|
|
+
|
|
|
+// 查询参数
|
|
|
+const searchParmams = ref({
|
|
|
+ subjectId: '0', //科目ID
|
|
|
+ // "classCode": 0,
|
|
|
+ type: 0 //类型,0-行政班,1-教学班
|
|
|
+})
|
|
|
+
|
|
|
+const defaultTabkey = computed(()=>{
|
|
|
+ return JSON.stringify({
|
|
|
+ subjectId: searchParmams.value.subjectId, // 科目id
|
|
|
+ type:searchParmams.value.type // 类型,0-行政班,1-教学班
|
|
|
+ })
|
|
|
+})
|
|
|
+// 年级列表
|
|
|
+interface GradeItm {
|
|
|
+ label:string,
|
|
|
+ key:string
|
|
|
+}
|
|
|
+const gradeList = ref<GradeItm[]>([])
|
|
|
+
|
|
|
+
|
|
|
+// 获取班级类型列表信息
|
|
|
+const GetClassTypeList = async(subjectData)=>{
|
|
|
+ if(subjectData?.length >0){
|
|
|
+ gradeList.value = subjectData.map((item,index)=>{
|
|
|
+ return {
|
|
|
+ label:item.name,
|
|
|
+ key:JSON.stringify({
|
|
|
+ subjectId: item.subjectId, // 科目id
|
|
|
+ type:item.type // 类型,0-行政班,1-教学班
|
|
|
+ }),
|
|
|
+ }
|
|
|
+ }) || []
|
|
|
+
|
|
|
+ // 待确认——————
|
|
|
+ searchParmams.value.type = JSON.parse(gradeList.value[0].key).type
|
|
|
+ searchParmams.value.subjectId = JSON.parse(gradeList.value[0].key).subjectId
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// 2. 班级列表数据
|
|
|
+interface ClassItm {
|
|
|
+ id: string
|
|
|
+ className: string
|
|
|
+ gradeName: string
|
|
|
+}
|
|
|
+const classList = ref<ClassItm[]>([]);
|
|
|
+// 选中的班级ID
|
|
|
+const selectedClassItm = ref()
|
|
|
+// 获取可选班级列表数据
|
|
|
+const GetClassTableData = async ()=>{
|
|
|
+ let params = {
|
|
|
+ evaluationId: route.query.id,
|
|
|
+ subjectId:searchParmams.value.subjectId,
|
|
|
+ type:searchParmams.value.type
|
|
|
+ }
|
|
|
+
|
|
|
+ let res = await getAlternativeClassDataApi(params)
|
|
|
+ if(res?.code == 200){
|
|
|
+ classList.value = res.data || []
|
|
|
+ }
|
|
|
+}
|
|
|
+// 行选中 选择班级
|
|
|
+const HandleSelectRowClass = (classItm) => {
|
|
|
+ selectedClassItm.value = {
|
|
|
+ id:classItm.id,
|
|
|
+ className:classItm.className,
|
|
|
+ gradeName:classItm.gradeName,
|
|
|
+ };
|
|
|
+};
|
|
|
+// 设置表行选中 样式
|
|
|
+const tableRowClassName = ({row,rowIndex})=>{
|
|
|
+ if(row.id == selectedClassItm.value?.id){
|
|
|
+ return 'active_row'
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// 3. 班级编号对应 关系数据
|
|
|
+const filterNumberMappingTableColumns = ref([...numberMappingTableColumns.value]) //表头
|
|
|
+const administrativeClassTableData = ref([]); // 行政班 班级编号对应 关系数据
|
|
|
+// 获取表格授课关系配置数据
|
|
|
+const GetTeachingRelationshipData = async ()=>{
|
|
|
+ administrativeClassTableData.value = []
|
|
|
+
|
|
|
+ let params = {
|
|
|
+ evaluationId: route.query.id,
|
|
|
+ subjectId:searchParmams.value.subjectId,
|
|
|
+ type:searchParmams.value.type
|
|
|
+ }
|
|
|
+
|
|
|
+ let res = await getClassNumberMappingDataApi(params)
|
|
|
+ if(res?.code == 200){
|
|
|
+ const {
|
|
|
+ gradeData,subjectData,tableData
|
|
|
+ } = res.data
|
|
|
+
|
|
|
+
|
|
|
+ GetClassTypeList(subjectData)
|
|
|
+
|
|
|
+ // 班级编号对应表 数据渲染
|
|
|
+ let dynamicGradeHeaderColumn = gradeData.map(item=>{
|
|
|
+ return {
|
|
|
+ name: item.id,
|
|
|
+ label: item.gradeName,
|
|
|
+ width: '140',
|
|
|
+ custom: true,
|
|
|
+ fixed:'',
|
|
|
+ hidden: false,
|
|
|
+ align:'center',
|
|
|
+ }
|
|
|
+ })
|
|
|
+ filterNumberMappingTableColumns.value = [numberMappingTableColumns.value[0],...dynamicGradeHeaderColumn,numberMappingTableColumns.value[1]]
|
|
|
+
|
|
|
+
|
|
|
+ administrativeClassTableData.value = tableData.map(item=>{
|
|
|
+ let classOpt = {}
|
|
|
+ item.gradeData.map(grade=>{
|
|
|
+ classOpt[grade.evaluationGradeId] = grade.classData
|
|
|
+ })
|
|
|
+ return {
|
|
|
+ classCode:item.classCode,
|
|
|
+ ...classOpt
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 添加班级绑定编号
|
|
|
+const HandleAddClassBindCode = async (row, cell) => {
|
|
|
+ if (!isConfigMode.value) return;
|
|
|
+ if (!selectedClassItm.value) return;
|
|
|
+
|
|
|
+ let teacherMsg = {
|
|
|
+ id: selectedClassItm.value?.id,
|
|
|
+ className: selectedClassItm.value?.className,
|
|
|
+ gradeName:selectedClassItm.value?.gradeName
|
|
|
+ }
|
|
|
+
|
|
|
+ // 行政班
|
|
|
+ if (!row[cell]) {
|
|
|
+ row[cell] = [];
|
|
|
+ }
|
|
|
+
|
|
|
+ let params = {
|
|
|
+ id: selectedClassItm.value?.id, //班级id
|
|
|
+ classCode: row.classCode,
|
|
|
+ evaluationGradeId: cell,
|
|
|
+ subjectId:searchParmams.value.subjectId,
|
|
|
+ type:searchParmams.value.type
|
|
|
+ }
|
|
|
+
|
|
|
+ let res = await setClassNumberMappingDataApi(params)
|
|
|
+ if(res?.code == 200){
|
|
|
+ ElMessage.success(res?.msg)
|
|
|
+ row[cell].push({...teacherMsg,id:res?.data});
|
|
|
+ await GetClassTableData()
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 删除编号对应关系中的某个班级
|
|
|
+const HandleRemoveCodeMappinClass = async (row, cell, index) => {
|
|
|
+ if (!isConfigMode.value) return;
|
|
|
+ let id = null
|
|
|
+ let res = undefined
|
|
|
+ id = row[cell][index].id
|
|
|
+ res = await deleteCodeMappinClassApi(id)
|
|
|
+ if(res?.code == 200){
|
|
|
+ ElMessage.success(res?.msg)
|
|
|
+ row[cell].splice(index, 1);
|
|
|
+ await GetClassTableData()
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 删除一行班级编号 及对应数据
|
|
|
+const HandleDeleteRowClassCode =async (row)=>{
|
|
|
+ let params = {
|
|
|
+ subjectId:searchParmams.value.subjectId,
|
|
|
+ evaluationId: route.query.id,
|
|
|
+ classCode: row.classCode,
|
|
|
+ type:searchParmams.value.type
|
|
|
+ }
|
|
|
+
|
|
|
+ let res = await deleteRowClassNumberMappingDataApi(params)
|
|
|
+ if(res?.code == 200){
|
|
|
+ ElMessage.success(res?.msg)
|
|
|
+ await reloadData()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 新增班级编号
|
|
|
+const AddOneRowClassCode = async ()=>{
|
|
|
+ let params = {
|
|
|
+ subjectId:searchParmams.value.subjectId,
|
|
|
+ evaluationId: route.query.id,
|
|
|
+ type:searchParmams.value.type
|
|
|
+ }
|
|
|
+ let res = await addRowClassNumberMappingDataApi(params)
|
|
|
+ if(res?.code == 200){
|
|
|
+ await GetTeachingRelationshipData()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 4 综合.
|
|
|
+// 标签切换处理 年级/班级类型
|
|
|
+const HandleTabChange = async (val) => {
|
|
|
+ console.log('当前选中的tab',val)
|
|
|
+ searchParmams.value.subjectId = JSON.parse(val).subjectId
|
|
|
+ searchParmams.value.type = JSON.parse(val).type
|
|
|
+ await reloadData()
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+// 5. 完成编号对应关系
|
|
|
+const FinishNumberMapping = async ()=>{
|
|
|
+ let res = await finishNumberMappingDataApi(route.query.id)
|
|
|
+ if(res?.code == 200){
|
|
|
+ // 更新全局状态
|
|
|
+ store.dispatch('updateEvaluationManageStepData',route.query.id)
|
|
|
+ //更新全局活跃路由
|
|
|
+ store.commit('updateEvaluationManageStepData',{currentActiveStepName:'templateSetting'})
|
|
|
+ //跳转到下一步
|
|
|
+ router.push(`templateSetting?id=${route.query.id}`)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// 重新加载页面数据
|
|
|
+const reloadData =async ()=>{
|
|
|
+ // 查询可选班级数据
|
|
|
+ await GetClassTableData()
|
|
|
+ // 查询 现有的 班级编号对应关系
|
|
|
+ await GetTeachingRelationshipData()
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+onMounted( async ()=>{
|
|
|
+ // await GetClassTableData()
|
|
|
+ // await GetTeachingRelationshipData()
|
|
|
+ HandleTabChange(defaultTabkey.value)
|
|
|
+})
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+
|
|
|
+.number_mapping_content{
|
|
|
+ height: 100%;
|
|
|
+ overflow: auto;
|
|
|
+
|
|
|
+ .grade_tab{
|
|
|
+ gap:10px;
|
|
|
+ :deep(> span){
|
|
|
+ border: 1px solid #dcdfe6 !important;
|
|
|
+ border-radius: 6px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+.main_content {
|
|
|
+ overflow: auto;
|
|
|
+ height: calc(100% - 56px);
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: flex-start;
|
|
|
+ gap:20px;
|
|
|
+
|
|
|
+ .container_left {
|
|
|
+ height: 100%;
|
|
|
+ flex-shrink: 0;
|
|
|
+ width: 200px;
|
|
|
+ overflow-y: auto;
|
|
|
+ .search_content{
|
|
|
+ height: 36px;
|
|
|
+ }
|
|
|
+ .teacher_table{
|
|
|
+ :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: hidden;
|
|
|
+
|
|
|
+ .config_switch_desc{
|
|
|
+ font-size: 14px;
|
|
|
+
|
|
|
+ }
|
|
|
+ .end_item{
|
|
|
+ overflow-y: auto;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 单元格内部组件样式 */
|
|
|
+.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>
|
|
|
+
|