|
@@ -10,23 +10,53 @@
|
|
|
</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 class="filter_wrapper">
|
|
|
|
|
+ <div class="tag_group" v-if="gradeList.length > 1">
|
|
|
|
|
+ <div class="tag_group_title">年级:</div>
|
|
|
|
|
+ <div class="tag_group_content">
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="tag_item"
|
|
|
|
|
+ v-for="item in gradeList"
|
|
|
|
|
+ :key="item.code"
|
|
|
|
|
+ @click="SelectGrade(item.code)"
|
|
|
|
|
+ :class="item.code === selectedGradeCode ? 'active' : ''"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ item.name }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="tag_group" v-if="subjectList.length > 1">
|
|
|
|
|
+ <div class="tag_group_title">科目:</div>
|
|
|
|
|
+ <div class="tag_group_content">
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="tag_item"
|
|
|
|
|
+ v-for="item in subjectList"
|
|
|
|
|
+ :key="item.code"
|
|
|
|
|
+ @click="SelectSubject(item.code)"
|
|
|
|
|
+ :class="item.code === selectedSubjectCode ? 'active' : ''"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ item.name }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </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>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -56,14 +86,24 @@
|
|
|
{{ row.phone || '-' }}
|
|
{{ row.phone || '-' }}
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column prop="gradeName" label="年级" width="160" align="center">
|
|
|
|
|
|
|
+ <el-table-column prop="gradeNames" label="年级" width="160" align="center">
|
|
|
<template #default="{ row }">
|
|
<template #default="{ row }">
|
|
|
- {{ row.gradeName || '-' }}
|
|
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="multi_line_cell"
|
|
|
|
|
+ :title="GetNameListTitle(row.gradeNames)"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ FormatNameList(row.gradeNames) }}
|
|
|
|
|
+ </div>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column prop="subjectName" label="科目" width="160" align="center">
|
|
|
|
|
|
|
+ <el-table-column prop="subjectNames" label="科目" width="160" align="center">
|
|
|
<template #default="{ row }">
|
|
<template #default="{ row }">
|
|
|
- {{ row.subjectName || '-' }}
|
|
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="multi_line_cell"
|
|
|
|
|
+ :title="GetNameListTitle(row.subjectNames)"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ FormatNameList(row.subjectNames) }}
|
|
|
|
|
+ </div>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column prop="textbookVersions" label="教材版本" width="180" align="center">
|
|
<el-table-column prop="textbookVersions" label="教材版本" width="180" align="center">
|
|
@@ -207,6 +247,16 @@ const currentTab = ref('all')
|
|
|
// 搜索关键字
|
|
// 搜索关键字
|
|
|
const searchKeyword = ref('')
|
|
const searchKeyword = ref('')
|
|
|
|
|
|
|
|
|
|
+interface FilterItem {
|
|
|
|
|
+ code: string | number
|
|
|
|
|
+ name: string
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const gradeList = ref<FilterItem[]>([])
|
|
|
|
|
+const subjectList = ref<FilterItem[]>([])
|
|
|
|
|
+const selectedGradeCode = ref<string | number>('all')
|
|
|
|
|
+const selectedSubjectCode = ref<string | number>('all')
|
|
|
|
|
+
|
|
|
// 表格数据
|
|
// 表格数据
|
|
|
interface Teacher {
|
|
interface Teacher {
|
|
|
userId: number | string
|
|
userId: number | string
|
|
@@ -216,6 +266,10 @@ interface Teacher {
|
|
|
phone: string
|
|
phone: string
|
|
|
status: number
|
|
status: number
|
|
|
binXKW: number
|
|
binXKW: number
|
|
|
|
|
+ gradeCodes?: Array<string | number>
|
|
|
|
|
+ gradeNames?: string[]
|
|
|
|
|
+ subjectCodes?: Array<string | number>
|
|
|
|
|
+ subjectNames?: string[]
|
|
|
textbookVersions?: string
|
|
textbookVersions?: string
|
|
|
textbook?: string
|
|
textbook?: string
|
|
|
[key: string]: any
|
|
[key: string]: any
|
|
@@ -304,10 +358,51 @@ const GetTableIndex = (index: number) => {
|
|
|
return (pageNum.value - 1) * pageSize.value + index + 1
|
|
return (pageNum.value - 1) * pageSize.value + index + 1
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 前端 Tab 筛选 + 分页
|
|
|
|
|
|
|
+const FormatNameList = (names?: string[]) => {
|
|
|
|
|
+ if (!Array.isArray(names) || names.length === 0) return '-'
|
|
|
|
|
+ return names.filter(Boolean).join(',')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const GetNameListTitle = (names?: string[]) => {
|
|
|
|
|
+ if (!Array.isArray(names) || names.length === 0) return ''
|
|
|
|
|
+ return names.filter(Boolean).join(',')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const NormalizeFilterList = (list: FilterItem[]) => {
|
|
|
|
|
+ const normalizedList = (list || []).map(item => ({
|
|
|
|
|
+ code: item.code,
|
|
|
|
|
+ name: item.name,
|
|
|
|
|
+ }))
|
|
|
|
|
+ const hasAll = normalizedList.some(item => item.code === 'all' || item.name === '全部')
|
|
|
|
|
+ if (hasAll) return normalizedList
|
|
|
|
|
+ return [{ code: 'all', name: '全部' }, ...normalizedList]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const MatchCodeFilter = (
|
|
|
|
|
+ codes: Array<string | number> | undefined,
|
|
|
|
|
+ selectedCode: string | number
|
|
|
|
|
+) => {
|
|
|
|
|
+ if (selectedCode === 'all') return true
|
|
|
|
|
+ if (!Array.isArray(codes)) return false
|
|
|
|
|
+ return codes.some(code => String(code) === String(selectedCode))
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 前端 Tab + 年级/科目 筛选 + 分页
|
|
|
const FilterAndPaginate = () => {
|
|
const FilterAndPaginate = () => {
|
|
|
let filteredData = [...allData.value]
|
|
let filteredData = [...allData.value]
|
|
|
|
|
|
|
|
|
|
+ if (selectedGradeCode.value !== 'all') {
|
|
|
|
|
+ filteredData = filteredData.filter(item =>
|
|
|
|
|
+ MatchCodeFilter(item.gradeCodes, selectedGradeCode.value)
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (selectedSubjectCode.value !== 'all') {
|
|
|
|
|
+ filteredData = filteredData.filter(item =>
|
|
|
|
|
+ MatchCodeFilter(item.subjectCodes, selectedSubjectCode.value)
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (currentTab.value === 'bound') {
|
|
if (currentTab.value === 'bound') {
|
|
|
filteredData = filteredData.filter(item => item.binXKW === 1)
|
|
filteredData = filteredData.filter(item => item.binXKW === 1)
|
|
|
} else if (currentTab.value === 'unbound') {
|
|
} else if (currentTab.value === 'unbound') {
|
|
@@ -334,15 +429,21 @@ const GetTeacherList = async () => {
|
|
|
}
|
|
}
|
|
|
const res = await getAllTeacher(params)
|
|
const res = await getAllTeacher(params)
|
|
|
if (res.code === 200 && res.data) {
|
|
if (res.code === 200 && res.data) {
|
|
|
- allData.value = res.data.records || []
|
|
|
|
|
|
|
+ gradeList.value = NormalizeFilterList(res.data.gradeList || [])
|
|
|
|
|
+ subjectList.value = NormalizeFilterList(res.data.subjectList || [])
|
|
|
|
|
+ allData.value = res.data.teacherList || []
|
|
|
FilterAndPaginate()
|
|
FilterAndPaginate()
|
|
|
} else {
|
|
} else {
|
|
|
|
|
+ gradeList.value = []
|
|
|
|
|
+ subjectList.value = []
|
|
|
allData.value = []
|
|
allData.value = []
|
|
|
tableData.value = []
|
|
tableData.value = []
|
|
|
total.value = 0
|
|
total.value = 0
|
|
|
}
|
|
}
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('获取教师列表失败', error)
|
|
console.error('获取教师列表失败', error)
|
|
|
|
|
+ gradeList.value = []
|
|
|
|
|
+ subjectList.value = []
|
|
|
allData.value = []
|
|
allData.value = []
|
|
|
tableData.value = []
|
|
tableData.value = []
|
|
|
total.value = 0
|
|
total.value = 0
|
|
@@ -351,6 +452,18 @@ const GetTeacherList = async () => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+const SelectGrade = (code: string | number) => {
|
|
|
|
|
+ selectedGradeCode.value = code
|
|
|
|
|
+ pageNum.value = 1
|
|
|
|
|
+ FilterAndPaginate()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const SelectSubject = (code: string | number) => {
|
|
|
|
|
+ selectedSubjectCode.value = code
|
|
|
|
|
+ pageNum.value = 1
|
|
|
|
|
+ FilterAndPaginate()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// 切换Tab(前端筛选)
|
|
// 切换Tab(前端筛选)
|
|
|
const ChangeTab = (tab: string) => {
|
|
const ChangeTab = (tab: string) => {
|
|
|
currentTab.value = tab
|
|
currentTab.value = tab
|
|
@@ -408,7 +521,7 @@ const GoEnter = (row: Teacher) => {
|
|
|
const SetTableHeight = () => {
|
|
const SetTableHeight = () => {
|
|
|
const containerHeight = document.documentElement.clientHeight
|
|
const containerHeight = document.documentElement.clientHeight
|
|
|
const headerHeight = 60 // 顶部导航
|
|
const headerHeight = 60 // 顶部导航
|
|
|
- const filterHeight = 100 // 筛选区域
|
|
|
|
|
|
|
+ const filterHeight = 180 // 筛选区域
|
|
|
const paginationHeight = 100 // 分页器
|
|
const paginationHeight = 100 // 分页器
|
|
|
const marginHeight = 40 // 边距
|
|
const marginHeight = 40 // 边距
|
|
|
tableHeight.value = containerHeight - headerHeight - filterHeight - paginationHeight - marginHeight
|
|
tableHeight.value = containerHeight - headerHeight - filterHeight - paginationHeight - marginHeight
|
|
@@ -482,12 +595,60 @@ onUnmounted(() => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 筛选区域
|
|
// 筛选区域
|
|
|
|
|
+.filter_wrapper {
|
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.tag_group {
|
|
|
|
|
+ padding: 8px 0;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: flex-start;
|
|
|
|
|
+
|
|
|
|
|
+ .tag_group_title {
|
|
|
|
|
+ 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;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.filter_area {
|
|
.filter_area {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
gap: 20px;
|
|
gap: 20px;
|
|
|
border-radius: 8px;
|
|
border-radius: 8px;
|
|
|
- margin-bottom: 16px;
|
|
|
|
|
|
|
+ margin-top: 8px;
|
|
|
|
|
|
|
|
.search_area {
|
|
.search_area {
|
|
|
flex: 1;
|
|
flex: 1;
|
|
@@ -507,6 +668,17 @@ onUnmounted(() => {
|
|
|
min-width: 0;
|
|
min-width: 0;
|
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+.multi_line_cell {
|
|
|
|
|
+ display: -webkit-box;
|
|
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
|
|
+ -webkit-line-clamp: 2;
|
|
|
|
|
+ line-clamp: 2;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ word-break: break-all;
|
|
|
|
|
+ line-height: 20px;
|
|
|
|
|
+ max-height: 40px;
|
|
|
|
|
+}
|
|
|
// 表格内自定义样式
|
|
// 表格内自定义样式
|
|
|
.name_text {
|
|
.name_text {
|
|
|
color: #2E64FA;
|
|
color: #2E64FA;
|