Procházet zdrojové kódy

样式调整;学校列表筛选区域顶部固定逻辑添加;开通科目不可删除科目条件添加;

zhangguohua před 1 rokem
rodič
revize
f3c7aa9fb1

+ 6 - 3
src/layout/components/AppMain.vue

@@ -1,9 +1,9 @@
 <template>
   <div class="container">
     <SiderBar />
-    <el-main class="main_container">
-      <router-view></router-view>
-    </el-main>
+    <!-- <el-main class="main_container"> -->
+    <router-view></router-view>
+    <!-- </el-main> -->
   </div>
 </template>
 
@@ -26,6 +26,9 @@ export default {
   height: calc(100vh - 65px);
 }
 .main_container {
+  padding: 20px;
   background: #F0F4FB;
+  height: calc(100vh - 65px);
+  overflow-y: auto;
 }
 </style>

+ 16 - 8
src/styles/common.scss

@@ -42,6 +42,7 @@ body {
   overflow: hidden;
   -webkit-font-smoothing: antialiased;//控制字体在 WebKit 浏览器(如 Chrome、Safari)中的抗锯齿方式。antialiased 表示使用“无锯齿”的字体渲染方式,使文字更清晰平滑,尤其适用于浅色或白色背景上的深色字体。
   text-rendering: optimizeLegibility;//告诉浏览器优先考虑文字的可读性而不是渲染速度或几何精度
+  background: #F0F4FB;
 }
 .el-select .el-select__wrapper,
 .el-input .el-input__wrapper,
@@ -113,6 +114,9 @@ body {
   background: #2E64FA;
   border-color: #2E64FA;
 }
+.el-checkbox__inner:hover, .el-radio__inner:hover {
+  border-color: #2E64FA;
+}
 
 .el-radio__input.is-checked .el-radio__inner {
   background: #2E64FA;
@@ -178,7 +182,12 @@ button:focus, button:focus-visible {
   background: #2E64FA;
 }
 
-
+.el-pagination button.is-active, .el-pagination button:hover {
+  color: #2E64FA;
+}
+.el-pagination.is-background .el-pager li.is-active {
+  background: #2E64FA;
+}
 
 // 全局滚动条样式修改
 /* 滚动条轨道区域样式 */
@@ -492,8 +501,7 @@ button:focus, button:focus-visible {
     display: flex;
     align-items: center;
   }
-  .el-input--mini .el-input__inner
-  {
+  .el-input--mini .el-input__inner {
     height: 30px !important;
     line-height: 30 !important;
   }
@@ -521,7 +529,7 @@ button:focus, button:focus-visible {
     min-width: 30px;
   }
 
-  .el-pager li {
+  .el-pagination .el-pager li {
     min-width: 30px;
     height: 30px;
     width: 30px;
@@ -530,13 +538,12 @@ button:focus, button:focus-visible {
     border-radius: 4px 4px 4px 4px;
     padding: 0 !important;
     margin-left: 8px;
-
     font-weight: 400;
     font-size: 14px;
     color: #666;
   }
 
-  .el-pager li.active {
+  .el-pagination .el-pager li.active {
     background: #2f51ff;
     font-weight: 400;
     font-size: 14px;
@@ -607,13 +614,14 @@ button:focus, button:focus-visible {
       width: 120px;
     }
     .el-input {
-      width: 230px;
+      width: 200px;
     }
     .content_left {
       display: flex;
       gap: 10px;
+      flex-wrap: wrap;
       width: auto;
-      height: 36px;
+      // height: 36px;
       line-height: 36px;
       .tab_button {
         width: auto;

+ 1 - 1
src/views/examination/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="page_container">
+  <div class="main_container page_container">
     <div class="page_item">
       <div class="page_left">
         <div class="page_search">

+ 52 - 46
src/views/manager/index.vue

@@ -1,51 +1,54 @@
 <template>
-  <div class="page_item">
-    <div class="page_search">
-      <div class="search_content">
-        <div class="content_left">
-          <el-input v-model="keyWord" placeholder="请输入姓名或账号" @input="GoSearch">
-            <template #append>
-              <el-button :icon="Search" @click="GoSearch" />
-            </template>
-          </el-input>
-        </div>
-        <div class="content_right">
-          <el-button class="button_refresh" @click="Refresh"><img src="@/assets/icon/refresh.svg" alt="" style="margin-right: 5px;">刷新</el-button>
-          <el-button class="button_background" @click="AddManager" v-if="permissions.includes('managerCreate')">新增用户</el-button>
+  <div class="main_container page_container">
+    <div class="page_item">
+      <div class="page_search">
+        <div class="search_content">
+          <div class="content_left">
+            <el-input v-model="keyWord" placeholder="请输入姓名或账号" @input="GoSearch">
+              <template #append>
+                <el-button :icon="Search" @click="GoSearch" />
+              </template>
+            </el-input>
+          </div>
+          <div class="content_right">
+            <el-button class="button_refresh" @click="Refresh"><img src="@/assets/icon/refresh.svg" alt="" style="margin-right: 5px;">刷新</el-button>
+            <el-button class="button_background" @click="AddManager" v-if="permissions.includes('managerCreate')">新增用户</el-button>
+          </div>
         </div>
       </div>
+      <div class="page_jg_20"></div>
+      <div class="page_table">
+        <el-table :data="tableData" stripe :key="tableKey" v-loading="tableLoading" element-loading-text="拼命加载中……"
+          element-loading-spinner="el-icon-loading" element-loading-background="#ffffff" row-key="studentId">
+            <el-table-column type="index" label="序号" align="center" width="50" />
+            <el-table-column prop="username" label="账号" align="center"  show-overflow-tooltip />
+            <el-table-column prop="nickname" label="姓名" align="center"  show-overflow-tooltip />
+            <el-table-column prop="phoneNo" label="手机号" align="center"  show-overflow-tooltip />
+            <el-table-column prop="status" label="状态" align="center"  show-overflow-tooltip>
+              <template #default="scope">
+                <div class="table_row_status">
+                  <!-- 正常 -->
+                  <div class="yes_release_icon" v-if="scope.row.status === 1"></div>
+                  <!-- 封禁 -->
+                  <div class="ready_close_icon" v-else></div>
+                  {{ scope.row.statusLabel }}
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="lastLoginAt" label="最后登录时间" align="center"  show-overflow-tooltip />
+            <el-table-column label="操作" align="center" fixed="right" min-width="120">
+              <template #default="scope">
+                <div class="table_row_option">
+                  <div class="button_editor" @click="EditManager(scope.row)" v-if="permissions.includes('managerUpdate')">编辑</div>
+                  <div class="button_editor" @click="EditPassword(scope.row)" v-if="permissions.includes('managerPassword')">重置密码</div>
+                  <div class="button_delete" @click="DeleteManager(scope.row)" v-if="permissions.includes('managerDelete')">删除</div>
+                </div>
+              </template>
+            </el-table-column>
+        </el-table>
+      </div>
     </div>
-    <div class="page_jg_20"></div>
-    <div class="page_table">
-      <el-table :data="tableData" stripe :key="tableKey" v-loading="tableLoading" element-loading-text="拼命加载中……"
-        element-loading-spinner="el-icon-loading" element-loading-background="#ffffff" row-key="studentId">
-          <el-table-column type="index" label="序号" align="center" width="50" />
-          <el-table-column prop="username" label="账号" align="center"  show-overflow-tooltip />
-          <el-table-column prop="nickname" label="姓名" align="center"  show-overflow-tooltip />
-          <el-table-column prop="phoneNo" label="手机号" align="center"  show-overflow-tooltip />
-          <el-table-column prop="status" label="状态" align="center"  show-overflow-tooltip>
-            <template #default="scope">
-              <div class="table_row_status">
-                <!-- 正常 -->
-                <div class="yes_release_icon" v-if="scope.row.status === 1"></div>
-                <!-- 封禁 -->
-                <div class="ready_close_icon" v-else></div>
-                {{ scope.row.statusLabel }}
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column prop="lastLoginAt" label="最后登录时间" align="center"  show-overflow-tooltip />
-          <el-table-column label="操作" align="center" fixed="right" min-width="120">
-            <template #default="scope">
-              <div class="table_row_option">
-                <div class="button_editor" @click="EditManager(scope.row)" v-if="permissions.includes('managerUpdate')">编辑</div>
-                <div class="button_editor" @click="EditPassword(scope.row)" v-if="permissions.includes('managerPassword')">重置密码</div>
-                <div class="button_delete" @click="DeleteManager(scope.row)" v-if="permissions.includes('managerDelete')">删除</div>
-              </div>
-            </template>
-          </el-table-column>
-      </el-table>
-    </div>
+    
 
     <div class="page_dialog">
       <AddAdmin v-if="dialogData.showDialog" @update="RefTable" />
@@ -158,6 +161,9 @@ const Refresh = () => {
 
 </script>
 
-<style>
-
+<style lang="scss" scoped>
+.page_container {
+  display: flex;
+  height: 100%;
+}
 </style>

+ 10 - 1
src/views/school/SearchMain.vue

@@ -114,9 +114,13 @@ const selectItem = (value: string, str: SearchDataKey, item: any) => {
       arr.splice(0, 0, { cityCode: "", cityName: "全部" })
       cityNode.value = arr
       searchData.value.cityCode = ''
+      districtNode.value = []
+      searchData.value.districtCode = ''
     }else {
       cityNode.value = []
       searchData.value.cityCode = ''
+      districtNode.value = []
+      searchData.value.districtCode = ''
     }
   }
   if(str == 'cityCode') {
@@ -178,8 +182,10 @@ const GetSearchList = () => {
           data[i].splice(0, 0, { provinceCode: "", provinceName: "全部" })
         }else if(i == 'cityNode') {
           data[i].splice(0, 0, { cityCode: "", cityName: "全部" })
+        }else if(i == 'districtNode') {
+          data[i].splice(0, 0, { districtCode: "", districtName: "全部" })
         }else if( i == 'typeNode') {
-           data[i].splice(0, 0, { type: "", typeName: "全部" })
+          data[i].splice(0, 0, { type: "", typeName: "全部" })
         }else if( i == 'userInfo') {
           data[i].splice(0, 0, { userId: "", nickname: "全部" })
         }
@@ -192,6 +198,9 @@ const GetSearchList = () => {
 </script>
 
 <style lang="scss" scoped>
+.page_item {
+  padding: 10px 20px !important;
+}
 .tag_group{
   padding:8px 0;
   display: flex;

+ 303 - 91
src/views/school/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div class="main_container" @scroll="OnScroll" ref="scrollContainer">
     <div class="user_num_content">
       <div class="user_item all">
         <div class="item_left">
@@ -31,20 +31,74 @@
       </div>
     </div>
 
-    <!-- <div class="filter_box" :style="{ display: filterVisible ? 'block' : 'none' }" ref="filterAreaRef">
-      <div>
-        111
-      </div>
-    </div> -->
     <div ref="filterRef" class="filter_area">
-      <SearchMain @FnSearch="FnSearch" />
+      <!-- <SearchMain @FnSearch="FnSearch" /> -->
+      <div class="page_item">
+        <div class="tag_group" v-if="searchList.provinceNode.length > 1">
+          <div class="tag_group_title">省份:</div>
+          <div class="tag_group_content">
+            <div class="tag_item" v-for="item in searchList.provinceNode" :key="item.provinceCode" @click="selectItem(item.provinceCode, 'provinceCode', item)" :class="item.provinceCode === searchData.provinceCode ? 'active' : ''">
+              {{ item.provinceName }}
+            </div>
+          </div>
+        </div>
+        <div class="tag_group" v-if="cityNode.length > 0">
+          <div class="tag_group_title">城市:</div>
+          <div class="tag_group_content">
+            <div class="tag_item" v-for="item in cityNode" :key="item.cityCode" @click="selectItem(item.cityCode, 'cityCode', item)" :class="item.cityCode === searchData.cityCode ? 'active' : ''">
+              {{ item.cityName }}
+            </div>
+          </div>
+        </div>
+        <div class="tag_group" v-if="districtNode.length > 0">
+          <div class="tag_group_title">区/县:</div>
+          <div class="tag_group_content">
+            <div class="tag_item" v-for="item in districtNode" :key="item.districtCode" @click="selectItem(item.districtCode, 'districtCode', item)" :class="item.districtCode === searchData.districtCode ? 'active' : ''">
+              {{ item.districtName }}
+            </div>
+          </div>
+        </div>
+        <div class="tag_group" v-if="searchList.userInfo.length > 1">
+          <div class="tag_group_title">运维:</div>
+          <div class="tag_group_content">
+            <div class="tag_item" v-for="item in searchList.userInfo" :key="item.userId" @click="selectItem(item.userId, 'userId', item)" :class="item.userId === searchData.userId ? 'active' : ''">
+              {{ item.nickname }}
+            </div>
+          </div>
+        </div>
+        <div class="tag_group" v-if="searchList.typeNode.length > 1">
+          <div class="tag_group_title">状态:</div>
+          <div class="tag_group_content">
+            <div class="tag_item" v-for="item in searchList.typeNode" :key="item.type" @click="selectItem(item.type, 'type', item)" :class="item.type === searchData.type ? 'active' : ''">
+              {{ item.typeName }}
+            </div>
+          </div>
+        </div>
+      </div>
     </div>
     <div class="page_jg_20"></div>
     <div class="page_item">
       <div class="page_search">
-        <div class="search_content">
+        <div class="search_content" ref="searchContentRef">
           <div class="content_left">
-            <el-select v-model="schoolTypeSelect" @change="SearchChange" placeholder="">
+            <div class="simple_filter" v-if="isShowSimpleFilter">
+              <el-select v-model="searchData.provinceCode" @change="SearchChange" v-if="searchList.provinceNode && searchList.provinceNode.length > 1">
+                <el-option v-for="item in searchList.provinceNode" :key="item.provinceCode" :value="item.provinceCode" :label="item.provinceName"></el-option>
+              </el-select>
+              <el-select v-model="searchData.cityCode" @change="SearchChange" v-if="cityNode && cityNode.length > 1">
+                <el-option v-for="item in cityNode" :key="item.cityCode" :value="item.cityCode" :label="item.cityName"></el-option>
+              </el-select>
+              <el-select v-model="searchData.districtCode" @change="SearchChange" v-if="districtNode && districtNode.length > 1">
+                <el-option v-for="item in districtNode" :key="item.districtCode" :value="item.districtCode" :label="item.districtName"></el-option>
+              </el-select>
+              <el-select v-model="searchData.userId" @change="SearchChange" v-if="searchList.userInfo && searchList.userInfo.length > 1">
+                <el-option v-for="item in searchList.userInfo" :key="item.userId" :value="item.userId" :label="item.nickname"></el-option>
+              </el-select>
+              <el-select v-model="searchData.type" @change="SearchChange" v-if="searchList.typeNode && searchList.typeNode.length > 1">
+                <el-option v-for="item in searchList.typeNode" :key="item.type" :value="item.type" :label="item.typeName"></el-option>
+              </el-select>
+            </div>
+            <el-select v-model="schoolTypeSelect" @change="SearchChange">
               <el-option label="全部类型" value="all"></el-option>
               <el-option label="单校" :value="0"></el-option>
               <el-option label="联考" :value="1"></el-option>
@@ -56,9 +110,9 @@
             </el-input>
           </div>
           <div class="content_right">
-            <el-button class="button_refresh" @click="Refresh">
+            <!-- <el-button class="button_refresh" @click="Refresh">
               <img src="@/assets/icon/refresh.svg" alt="" style="margin-right: 5px;">刷新
-            </el-button>
+            </el-button> -->
             <el-button class="button_border" @click="OpenSubject" v-if="permissions.includes('schoolOpenSubjects')">开通科目</el-button>
             <el-button class="button_background" @click="addUser" v-if="permissions.includes('schoolCreate')">新增用户</el-button>
           </div>
@@ -66,9 +120,9 @@
       </div>
       <div class="page_jg_20"></div>
       <div class="page_table">
-        <el-table :data="tableData" stripe v-loading="tableLoading" element-loading-text="拼命加载中……" 
+        <el-table :data="tableData" stripe v-loading="tableLoading" element-loading-text="拼命加载中……" :height="tableHeight"
           element-loading-spinner="el-icon-loading" element-loading-background="#ffffff">
-            <el-table-column type="index" label="序号" fixed="left" align="center" />
+            <el-table-column prop="index" label="序号" fixed="left" align="center" />
             <el-table-column prop="tenantCode" label="学校编号" width="80" fixed="left" align="center" show-overflow-tooltip />
             <el-table-column prop="tenantName" label="学校名称" min-width="160" fixed="left" align="center" show-overflow-tooltip>
               <template #default="{row}">
@@ -129,6 +183,10 @@
               </template>
             </el-table-column>
         </el-table>
+        <div class="page_pagination">
+          <el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[20, 50, 100]" background layout="sizes, prev, pager, next" :total="total" 
+            @current-change="HandleCurrentChange" @size-change="HandleSizeChange" />
+        </div>
       </div>
     </div>
 
@@ -150,7 +208,8 @@ import ResetPassword from '@/components/resetPassword.vue'
 import { Search } from '@element-plus/icons-vue'
 import { ElMessageBox, ElMessage } from 'element-plus'
 import { ref, reactive, provide, onMounted, nextTick, onUnmounted } from 'vue'
-import { getSchoolNumber, getSchoolList, changeStatus ,getTicket} from '@/api/school'
+import { getSchoolNumber, getSchoolList, changeStatus ,getTicket, getSearchList} from '@/api/school'
+import { throttle } from 'lodash';
 
 interface UserNumber {
   allUser: number
@@ -164,8 +223,121 @@ const userNumber = ref<UserNumber>({
   experienceUser: 0,
   freezeUser: 0
 })
+
+const searchData = ref({
+  provinceCode: 'all',
+  cityCode: 'all',
+  districtCode: 'all',
+  type: 'all',
+  userId: 'all',
+})
+
+interface Province {
+  provinceCode: string;
+  provinceName: string;
+  children?: City[]; // 如果有子级城市数据的话
+}
+interface City {
+  cityCode:  string
+  cityName:  string
+  children?: District[]; // 如果有子级区县数据的话
+}
+interface District {
+  districtCode:  string
+  districtName:  string
+}
+const cityNode = ref<City[]>([])
+const districtNode = ref<District[]>([])
+
+interface TypeNode {
+  type: string;
+  typeName: string;
+}
+
+interface UserInfo {
+  userId: string;
+  nickname: string;
+}
+
+interface SearchList {
+  examTypes: any[]; 
+  provinceNode: Province[];
+  cityNode: City[];
+  districtNode: District[];
+  typeNode: TypeNode[];
+  userInfo: UserInfo[];
+}
+const searchList = ref<SearchList>({
+  examTypes: [],
+  provinceNode: [],
+  cityNode: [],
+  districtNode: [],
+  typeNode: [],
+  userInfo: []
+})
+// const emit = defineEmits(['FnSearch'])
+
+type SearchDataKey = 'provinceCode' | 'cityCode' | 'districtCode' | 'type' | 'userId'
+const selectItem = (value: string, str: SearchDataKey, item: any) => {
+  searchData.value[str] = value
+  let arr = []
+  if(str == 'provinceCode') {
+    if(value && value != 'all') {
+      arr = [...item.children]
+      arr.splice(0, 0, { cityCode: "all", cityName: "全部" })
+      cityNode.value = arr
+      searchData.value.cityCode = 'all'
+      districtNode.value = []
+      searchData.value.districtCode = 'all'
+    }else {
+      cityNode.value = []
+      searchData.value.cityCode = 'all'
+      districtNode.value = []
+      searchData.value.districtCode = 'all'
+    }
+  }
+  if(str == 'cityCode') {
+    if(value && value != 'all') {
+      arr = [...item.children]
+      arr.splice(0, 0, { districtCode: "all", districtName: "全部" })
+      districtNode.value = arr
+      searchData.value.districtCode = 'all'
+    }else {
+      districtNode.value = []
+      searchData.value.districtCode = 'all'
+    }
+  }
+  FnSearch(searchData)
+
+  // emit('FnSearch', searchData);
+}
+
+const GetSearchList = () => {
+  getSearchList().then((res: any) => {
+    console.log(res)
+    if(res.code == 200) {
+      const { data } = res
+      for(let i in data) {
+        if(i == 'provinceNode') {
+          data[i].splice(0, 0, { provinceCode: "all", provinceName: "全部" })
+        }else if(i == 'cityNode') {
+          data[i].splice(0, 0, { cityCode: "all", cityName: "全部" })
+        }else if(i == 'districtNode') {
+          data[i].splice(0, 0, { districtCode: "all", districtName: "全部" })
+        }else if( i == 'typeNode') {
+          data[i].splice(0, 0, { type: "all", typeName: "全部" })
+        }else if( i == 'userInfo') {
+          data[i].splice(0, 0, { userId: "all", nickname: "全部" })
+        }
+      }
+      searchList.value = data
+      console.log(searchList.value)
+    }
+  })
+}
 // 定义列表数据类型
 interface User {
+  index: number;
   tenantCode: String;
   tenantName: String;
   status: number;
@@ -184,6 +356,9 @@ const tableData = ref<User[]>([])
 
 const schoolTypeSelect = ref<string>("all")
 const schoolNameCode = ref('')
+const pageNum = ref(1)
+const pageSize = ref(20)
+const total = ref(0)
 const tableLoading = ref(false)
 const showDialog = ref(false)
 const dialogData = reactive({
@@ -216,19 +391,18 @@ provide('subjectShowDialog', subjectShowDialog) // 开通科目弹窗数据
 provide('passwordDialog', passwordDialog) // 重置密码弹窗数据
 onMounted(() => {
   permissions.value = JSON.parse(localStorage.getItem('permissions'))
+
+  GetSearchList()
   GetSchoolNumber()
   GetSchoolList()
+  nextTick(() => {
+    SetTableHeight()
+  })
+  window.addEventListener('resize', HandleResize);
 })
 onUnmounted(() => {
-  // if (observer) {
-  //   observer.disconnect();
-  //   observer = null;
-  // }
-  window.addEventListener('scroll', aaa);
+  window.removeEventListener('resize', HandleResize);
 });
-const aaa = () => {
-  console.log('aaa')
-} 
 // 新增用户
 const addUser = () => {
   showDialog.value = true
@@ -243,7 +417,7 @@ const EditUser =  (row: any) => {
   dialogData.tenantName = row.tenantName
 }
 // 设置权限
-const OpenAuth = (row: any) => {
+const OpenAuth = (row: any) => {  
   authData.id = row.id
   authData.schoolName = row.tenantName
   authData.tenantCode = row.tenantCode
@@ -254,20 +428,15 @@ const OpenSubject = () => {
   console.log('OpenSubject')
   subjectShowDialog.value = true
 }
-// 筛选项数据
-const searchData = ref({
-  provinceCode: '', // 省份
-  cityCode: '', // 市
-  type: '', // 状态(正式/体验)
-  userId: '' // 运维人员
-})
 // 筛选项查询
 const FnSearch = (data: any) => {
   searchData.value = data.value
+  pageNum.value = 1
   GetSchoolList()
 }
 // 表格上面筛选查询
 const SearchChange = () => {
+  pageNum.value = 1
   GetSchoolList()
 }
 // 获取用户数量
@@ -281,23 +450,39 @@ const GetSchoolNumber = () => {
 // 获取学校列表
 const GetSchoolList = () => {
   let params = {
-    type: searchData.value.type,
-    userId: searchData.value.userId,
-    cityCode: searchData.value.cityCode,
-    provinceCode: searchData.value.provinceCode,
+    type: searchData.value.type == 'all' ? '' : searchData.value.type,
+    userId: searchData.value.userId == 'all' ? '' : searchData.value.userId,
+    cityCode: searchData.value.cityCode == 'all' ? '' : searchData.value.cityCode,
+    provinceCode: searchData.value.provinceCode == 'all' ? '' : searchData.value.provinceCode,
     schoolType:  schoolTypeSelect.value == 'all' ? '' : schoolTypeSelect.value,
-    queryStr: schoolNameCode.value
+    queryStr: schoolNameCode.value,
+    pageNum: pageNum.value,
+    pageSize: pageSize.value,
   }
   tableLoading.value = true
   getSchoolList(params).then((res: any) => {
     if(res.code == 200 && res.data) {
-      tableData.value = res.data
+      tableData.value = res.data.records
+      total.value = parseInt(res.data.total)
+      tableData.value.map((item, index) => {
+        item.index = (pageNum.value - 1) * pageSize.value + index + 1
+      })
     }
     tableLoading.value = false
   }).catch(() => {
     tableLoading.value = false
   })
 }
+// 切换分页页码
+const HandleCurrentChange = (val) => {
+  pageNum.value = val
+  GetSchoolList()
+}
+const HandleSizeChange = (val) => {
+  pageSize.value = val
+  pageNum.value = 1
+  GetSchoolList()
+}
 // 新增/修改学校信息后刷新列表
 const RefTable = (val: any) => {
   showDialog.value = val
@@ -373,55 +558,54 @@ const Refresh = () => {
   schoolNameCode.value = ""
   GetSchoolList()
 }
-const filterRef = ref(null)
-const isSticky = ref(false)
-let observer = null;
-const HandleScroll = () => {
-  console.log('1111')
-  observer = new IntersectionObserver(
-    (entries) => {
-      entries.forEach(entry => {
-        if (entry.boundingClientRect.top <= 65) {
-          isSticky.value = true;
-        } else {
-          isSticky.value = false;
-        }
-      });
-    },
-    {
-      root: null, // 使用视口作为根元素
-      threshold: 0, // 当元素顶部接触视口顶部时触发
-      rootMargin: `-${65}px 0px 0px 0px` // 相对于视口顶部的偏移
-    }
-  );
-  
-  if (filterRef.value) {
-    observer.observe(filterRef.value);
-  }
-}
 
-
-const filterVisible = ref(false)
-// 获取筛选区域的引用
-const filterAreaRef = ref<HTMLDivElement | null>(null);
+const filterRef = ref<HTMLDivElement | null>(null)
+const scrollContainer = ref<HTMLElement | null>(null);
+const isShowSimpleFilter = ref(false);
 
 // 监听页面滚动
 const OnScroll = () => {
-  console.log('123', window.scrollY)
-  const filterArea = filterAreaRef.value;
-  const scrollPosition = window.scrollY;
-  const contentTop = document.querySelector('.filter_area')?.getBoundingClientRect().top || 0;
-  console.log(contentTop)
-  // 当页面滚动到内容区域中间时显示筛选区域
-  if (scrollPosition >= contentTop - 100) {
-    filterVisible.value = true;
-  } else {
-    filterVisible.value = false;
-  }
+  nextTick(() => {
+    const filterElement = filterRef.value.$el || filterRef.value // 获取 DOM 元素
+    if (!filterElement) return
+
+    const filterElementHeight = filterElement.getBoundingClientRect().height
+    const scrollTop = scrollContainer.value?.scrollTop || window.scrollY
+    // console.log('筛选区域高度', filterElementHeight)
+    // console.log('scrolltop滑动距离', scrollTop)
+    // 判断是否滚动到了筛选区域的底部
+    if (scrollTop > filterElementHeight + 60) {
+      isShowSimpleFilter.value = true
+      SetTableHeight()
+    } else {
+      isShowSimpleFilter.value = false
+    }
+  })
 };
+const tableHeight = ref(0)
+const searchContentRef = ref<HTMLDivElement | null>(null);
+const SetTableHeight = () => {
+  const clientHeight = scrollContainer.value?.clientHeight || document.documentElement.clientHeight;
+  const searchContentHeight = searchContentRef.value?.clientHeight || document.documentElement.clientHeight;
+
+  tableHeight.value = clientHeight - searchContentHeight - 148
+
+}
+// 监听窗口大小变化,重新计算表格高度 使用节流防止频繁改变窗口大小导致计算量过大而页面卡顿
+const HandleResize = throttle(() => {
+  SetTableHeight();
+}, 500) // 节流 500 毫秒内最多执行一次
 </script>
 
 <style lang="scss" scoped>
+.simple_filter {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+}
+.search_content {
+  align-items: flex-start !important;
+}
 .user_num_content {
   width: 100%;
   display: flex;
@@ -499,21 +683,49 @@ const OnScroll = () => {
   color: #ccc; 
   cursor: not-allowed;
 }
-.filter_box {
-  display: none;
-}
-.sticky-top {
-  display: block;
-  width: calc(100% - 190px);
-  position: fixed;
-  top: 65px; /* 与header高度一致 */
-  left: 170px;
-  right: 20px;
-  padding: 20px;
-  background: #F0F4FB;
-  z-index: 20;
 
-  // box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+
+.filter_area .page_item {
+  padding: 10px 20px !important;
+}
+.tag_group{
+  padding:8px 0;
+  display: flex;
+  justify-content: flex-start;
+  .tag_group_title {
+    // width: auto;
+    width: 50px;
+    height: auto;
+    margin-right: 8px;
+    color: #303133;
+    font-size: 14px;
+    text-align: right;
+    line-height: 30px;
+    font-weight: 500;
+    letter-spacing: 0em;
+  }
+  .tag_group_content {
+    width: calc(100% - 80px);
+    display: flex;
+    flex-wrap: wrap;
+    gap: 8px;
+    .tag_item {
+      padding: 0 8px;
+      line-height: 30px;
+      border-radius: 4px;
+      font-size: 14px;
+      background: #fff;
+      color: #999999;
+      cursor: pointer;
+      &.active {
+        background: rgba(71,113,203,0.1);
+        color: #2E64FA;
+      }
+      &:hover {
+        color: #2E64FA;
+      }
+    }
+  }
 }
 
 </style>

+ 11 - 5
src/views/school/subjectList.vue

@@ -1,9 +1,9 @@
 <template>
   <el-dialog v-model="subjectShowDialog" title="科目列表" width="600px">
     <div class="subject_list">
-      <div v-for="tag in subjectList" :key="tag.id" class="list_item">
+      <div v-for="tag in subjectList" :key="tag.id" class="list_item" :class="tag.canDelete == 1 ? 'list_item can_delete' : 'list_item'">
         <span>{{ tag.courseName }}</span>
-        <img src="@/assets/icon/delete.svg" @click="delSubject(tag.id)">
+        <img src="@/assets/icon/delete.svg" v-if="tag.canDelete" @click="delSubject(tag.id)">
       </div>
       <el-input ref="InputRef" v-if="inputVisible" v-model="inputValue" @keyup.enter="handleInputConfirm" @blur="InputBlur" class="input_item">
         <template #append>
@@ -61,7 +61,7 @@ const InputBlur = () => {
 const handleInputConfirm = () => {
   if (inputValue.value) {
     addSubject({ courseName: inputValue.value }).then((res: any) => {
-      if (res.code === 200 && res.data) {
+      if (res.code === 200) {
         ElMessage.success(res.msg)
         GetAllSubject()
         inputVisible.value = false
@@ -111,10 +111,10 @@ const delSubject = (id: number) => {
   flex-wrap: wrap;
   gap:20px ;
   .list_item {
-    background: rgba(46,100,250,0.1);
     border-radius: 4px 4px 4px 4px;
     border: 1px solid #2E64FA;
     width: auto;
+    min-width: 72px;
     height: 36px;
     line-height: 36px;
     padding: 0 10px;
@@ -124,10 +124,16 @@ const delSubject = (id: number) => {
     display: flex;
     justify-content: space-between;
     align-items: center;
+    &.can_delete {
+      background: rgba(46,100,250,0.1);
+    }
     span {
-      margin-right: 8px;
+      width: 100%;
+      text-align: center;
+      // margin-right: 8px;
     }
     img {
+      margin-left: 8px;
       width: 16px;
       height: 16px;
       cursor: pointer;