|
|
@@ -0,0 +1,405 @@
|
|
|
+<template>
|
|
|
+ <div class="teacher_list_container">
|
|
|
+ <!-- 顶部导航 -->
|
|
|
+ <div class="header">
|
|
|
+ <el-button class="back_button" @click="GoBack">
|
|
|
+ <i class="iconfont icon_xiangzuo back_icon" ></i>
|
|
|
+ 返回
|
|
|
+ </el-button>
|
|
|
+ <div class="school_name">{{ schoolName }}</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 筛选区域 -->
|
|
|
+ <div class="filter_area">
|
|
|
+ <TabSearch.default
|
|
|
+ :tabList="tabList"
|
|
|
+ tabType="box"
|
|
|
+ :defaultTabKey="currentTab"
|
|
|
+ @tabChange="ChangeTab"
|
|
|
+ />
|
|
|
+ <div class="search_area">
|
|
|
+ <el-input
|
|
|
+ v-model="searchKeyword"
|
|
|
+ placeholder="请输入姓名/账号"
|
|
|
+ @input="HandleSearch"
|
|
|
+ >
|
|
|
+ <template #append>
|
|
|
+ <el-button :icon="Search" @click="HandleSearch" />
|
|
|
+ </template>
|
|
|
+ </el-input>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 表格区域 -->
|
|
|
+ <div class="page_table">
|
|
|
+ <el-table
|
|
|
+ :data="tableData"
|
|
|
+ stripe
|
|
|
+ v-loading="tableLoading"
|
|
|
+ element-loading-text="拼命加载中……"
|
|
|
+ :height="tableHeight"
|
|
|
+ >
|
|
|
+ <el-table-column type="index" label="序号" width="60" align="center" />
|
|
|
+ <el-table-column prop="userAccount" label="账号" min-width="100" align="center" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="userName" label="姓名" min-width="100" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span class="name_text" @click="GoEnter(row)">{{ row.userName }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="wxName" label="微信名" min-width="100" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ {{ row.wxName || '-' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="phone" label="手机号" min-width="120" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ {{ row.phone || '-' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="binXKW" label="是否绑定学科网" width="160" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ {{ row.binXKW === 1 ? '是' : '否' }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="status" label="状态" width="80" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <div class="status_container">
|
|
|
+ <span
|
|
|
+ class="status_dot"
|
|
|
+ :class="row.status === 1 ? 'active' : 'disabled'"
|
|
|
+ ></span>
|
|
|
+ <span :class="row.status === 1 ? 'status_active' : 'status_disabled'">
|
|
|
+ {{ row.status === 1 ? '启用' : '禁用' }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" width="80" align="center" fixed="right">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span class="enter_button" @click="GoEnter(row)">进入</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 分页器 -->
|
|
|
+ <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>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts" setup>
|
|
|
+import { ref, onMounted, onUnmounted, nextTick } from 'vue'
|
|
|
+import { useRoute, useRouter } from 'vue-router'
|
|
|
+import { Search } from '@element-plus/icons-vue'
|
|
|
+import { ElMessage } from 'element-plus'
|
|
|
+import { throttle } from 'lodash'
|
|
|
+import * as TabSearch from '@/baseComponents/TabSearch.vue'
|
|
|
+import { getAllTeacher, getTicket } from '@/api/school'
|
|
|
+
|
|
|
+const route = useRoute()
|
|
|
+const router = useRouter()
|
|
|
+
|
|
|
+// 学校信息
|
|
|
+const schoolName = ref('')
|
|
|
+const schoolId = ref('')
|
|
|
+
|
|
|
+// Tab列表
|
|
|
+interface TabItem {
|
|
|
+ label: string
|
|
|
+ key: string
|
|
|
+ prefix?: string
|
|
|
+ prefixLight?: string
|
|
|
+ suffix?: string | number
|
|
|
+}
|
|
|
+const tabList = ref<TabItem[]>([
|
|
|
+ { label: '全部', key: 'all' },
|
|
|
+ { label: '已绑定学科网', key: 'bound' },
|
|
|
+ { label: '未绑定学科网', key: 'unbound' },
|
|
|
+])
|
|
|
+
|
|
|
+// Tab切换
|
|
|
+const currentTab = ref('all')
|
|
|
+
|
|
|
+// 搜索关键字
|
|
|
+const searchKeyword = ref('')
|
|
|
+
|
|
|
+// 表格数据
|
|
|
+interface Teacher {
|
|
|
+ userId: number | string
|
|
|
+ userAccount: string
|
|
|
+ userName: string
|
|
|
+ wxName: string
|
|
|
+ phone: string
|
|
|
+ status: number
|
|
|
+ binXKW: number
|
|
|
+ [key: string]: any
|
|
|
+}
|
|
|
+
|
|
|
+const tableData = ref<Teacher[]>([])
|
|
|
+const allData = ref<Teacher[]>([])
|
|
|
+const tableLoading = ref(false)
|
|
|
+const pageNum = ref(1)
|
|
|
+const pageSize = ref(20)
|
|
|
+const total = ref(0)
|
|
|
+const tableHeight = ref(0)
|
|
|
+
|
|
|
+// 前端筛选 + 分页
|
|
|
+const FilterAndPaginate = () => {
|
|
|
+ let filteredData = [...allData.value]
|
|
|
+
|
|
|
+ // tab筛选
|
|
|
+ if (currentTab.value === 'bound') {
|
|
|
+ filteredData = filteredData.filter(item => item.binXKW === 1)
|
|
|
+ } else if (currentTab.value === 'unbound') {
|
|
|
+ filteredData = filteredData.filter(item => item.binXKW === 0)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 搜索筛选
|
|
|
+ if (searchKeyword.value) {
|
|
|
+ const keyword = searchKeyword.value.toLowerCase()
|
|
|
+ filteredData = filteredData.filter(item =>
|
|
|
+ (item.userName || '').toLowerCase().includes(keyword) ||
|
|
|
+ (item.userAccount || '').toLowerCase().includes(keyword)
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ total.value = filteredData.length
|
|
|
+ const start = (pageNum.value - 1) * pageSize.value
|
|
|
+ const end = start + pageSize.value
|
|
|
+ tableData.value = filteredData.slice(start, end)
|
|
|
+}
|
|
|
+
|
|
|
+// 获取教师列表(仅初始化时调用)
|
|
|
+const GetTeacherList = async () => {
|
|
|
+ tableLoading.value = true
|
|
|
+ try {
|
|
|
+ const params: Record<string, any> = {
|
|
|
+ schoolId: schoolId.value,
|
|
|
+ }
|
|
|
+ const res = await getAllTeacher(params)
|
|
|
+ allData.value = res.data || []
|
|
|
+ FilterAndPaginate()
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取教师列表失败', error)
|
|
|
+ } finally {
|
|
|
+ tableLoading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 切换Tab(前端筛选)
|
|
|
+const ChangeTab = (tab: string) => {
|
|
|
+ currentTab.value = tab
|
|
|
+ pageNum.value = 1
|
|
|
+ FilterAndPaginate()
|
|
|
+}
|
|
|
+
|
|
|
+// 搜索(前端筛选)
|
|
|
+const HandleSearch = () => {
|
|
|
+ pageNum.value = 1
|
|
|
+ FilterAndPaginate()
|
|
|
+}
|
|
|
+
|
|
|
+// 分页操作(前端分页)
|
|
|
+const HandleCurrentChange = (val: number) => {
|
|
|
+ pageNum.value = val
|
|
|
+ FilterAndPaginate()
|
|
|
+}
|
|
|
+
|
|
|
+const HandleSizeChange = (val: number) => {
|
|
|
+ pageSize.value = val
|
|
|
+ pageNum.value = 1
|
|
|
+ FilterAndPaginate()
|
|
|
+}
|
|
|
+
|
|
|
+// 返回
|
|
|
+const GoBack = () => {
|
|
|
+ router.back()
|
|
|
+}
|
|
|
+
|
|
|
+// 进入
|
|
|
+const GoEnter = (row: Teacher) => {
|
|
|
+ // 禁用状态禁止进入
|
|
|
+ if (row.status === 0) {
|
|
|
+ ElMessage.error('该教师已禁用,无法进入')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const params = {
|
|
|
+ id: schoolId.value,
|
|
|
+ }
|
|
|
+
|
|
|
+ getTicket(params).then((res: any) => {
|
|
|
+ const ticket = res.data
|
|
|
+ let url = `https://www.k12100.com/#/otherLogin?schoolId=${schoolId.value}&ticket=${ticket}`
|
|
|
+
|
|
|
+ if (import.meta.env.VITE_API_BASE_URL === 'https://admin.k12100.com/admin/') {
|
|
|
+ url = `https://www.k12100.com/#/otherLogin?schoolId=${schoolId.value}&ticket=${ticket}`
|
|
|
+ } else {
|
|
|
+ url = `https://index.k12100.net/#/otherLogin?schoolId=${schoolId.value}&ticket=${ticket}`
|
|
|
+ }
|
|
|
+ window.open(url)
|
|
|
+ }).catch(() => {})
|
|
|
+}
|
|
|
+
|
|
|
+// 计算表格高度
|
|
|
+const SetTableHeight = () => {
|
|
|
+ const containerHeight = document.documentElement.clientHeight
|
|
|
+ const headerHeight = 60 // 顶部导航
|
|
|
+ const filterHeight = 100 // 筛选区域
|
|
|
+ const paginationHeight = 100 // 分页器
|
|
|
+ const marginHeight = 40 // 边距
|
|
|
+ tableHeight.value = containerHeight - headerHeight - filterHeight - paginationHeight - marginHeight
|
|
|
+}
|
|
|
+
|
|
|
+// 监听窗口大小变化
|
|
|
+const HandleResize = throttle(() => {
|
|
|
+ SetTableHeight()
|
|
|
+}, 500)
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ // 获取路由参数
|
|
|
+ schoolName.value = route.query.schoolName as string || ''
|
|
|
+ schoolId.value = route.query.schoolId as string || ''
|
|
|
+
|
|
|
+ nextTick(() => {
|
|
|
+ SetTableHeight()
|
|
|
+ GetTeacherList()
|
|
|
+ })
|
|
|
+
|
|
|
+ window.addEventListener('resize', HandleResize)
|
|
|
+})
|
|
|
+
|
|
|
+onUnmounted(() => {
|
|
|
+ window.removeEventListener('resize', HandleResize)
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.teacher_list_container {
|
|
|
+ margin: 20px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ background:#fff;
|
|
|
+ border-radius: 10px;
|
|
|
+ padding:20px;
|
|
|
+ width: 100%;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+// 顶部导航
|
|
|
+.header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 20px;
|
|
|
+ margin-bottom: 20px;
|
|
|
+
|
|
|
+ .back_button {
|
|
|
+ width: 82px;
|
|
|
+ height: 36px;
|
|
|
+ background: #FFFFFF !important;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid #DCDFE6 !important;
|
|
|
+ color: #606266;
|
|
|
+ font-size: 14px;
|
|
|
+ padding: 0;
|
|
|
+ .back_icon {
|
|
|
+ width: 14px;
|
|
|
+ height: 14px;
|
|
|
+ font-size: 14px;
|
|
|
+ vertical-align: middle;
|
|
|
+ color: #333;
|
|
|
+ margin-right: 5px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .school_name {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 550;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 筛选区域
|
|
|
+.filter_area {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 20px;
|
|
|
+ border-radius: 8px;
|
|
|
+ margin-bottom: 16px;
|
|
|
+
|
|
|
+ .search_area {
|
|
|
+ flex: 1;
|
|
|
+ max-width: 217px;
|
|
|
+ }
|
|
|
+
|
|
|
+ // TabSearch 组件样式穿透
|
|
|
+ :deep(.box_tab) {
|
|
|
+ .un_selected {
|
|
|
+ color: #BBBBBB !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.page_table {
|
|
|
+ width: 100%;
|
|
|
+ min-width: 0;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+// 表格内自定义样式
|
|
|
+.name_text {
|
|
|
+ color: #2E64FA;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ text-decoration: underline;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 状态样式
|
|
|
+.status_container {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.status_dot {
|
|
|
+ width: 8px;
|
|
|
+ height: 8px;
|
|
|
+ border-radius: 50%;
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ background: #2BC644;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.disabled {
|
|
|
+ background: #F56C6C;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.status_active {
|
|
|
+ color: #2BC644;
|
|
|
+}
|
|
|
+
|
|
|
+.status_disabled {
|
|
|
+ color: #F56C6C;
|
|
|
+}
|
|
|
+
|
|
|
+.enter_button {
|
|
|
+ color: #2E64FA;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ text-decoration: underline;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|