优化条件筛选
This commit is contained in:
@@ -77,6 +77,16 @@ const references = reactive<Record<string, any[]>>({
|
||||
campuses: [], colleges: [], majors: [], buildings: [], counselors: [],
|
||||
})
|
||||
const form = reactive<Record<string, any>>({})
|
||||
const listFilters = reactive({
|
||||
collegeId: undefined as string | undefined,
|
||||
majorId: undefined as string | undefined,
|
||||
grade: undefined as number | undefined,
|
||||
campusId: undefined as string | undefined,
|
||||
buildingId: undefined as string | undefined,
|
||||
minimumCapacity: undefined as number | undefined,
|
||||
teachingVenueNature: undefined as number | undefined,
|
||||
isEnabled: undefined as boolean | undefined,
|
||||
})
|
||||
|
||||
const title = computed(() => tabs.value.find((x) => x.key === active.value)?.label ?? '')
|
||||
const canManage = computed(() =>
|
||||
@@ -90,6 +100,10 @@ const filteredRows = computed(() => {
|
||||
.filter(Boolean).some((value) => String(value).toLowerCase().includes(q)),
|
||||
)
|
||||
})
|
||||
const filteredMajors = computed(() => references.majors.filter((item: any) =>
|
||||
!listFilters.collegeId || item.collegeId === listFilters.collegeId))
|
||||
const filteredBuildings = computed(() => references.buildings.filter((item: any) =>
|
||||
!listFilters.campusId || item.campusId === listFilters.campusId))
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(20)
|
||||
const total = ref(0)
|
||||
@@ -154,6 +168,18 @@ async function load(resetPage = true) {
|
||||
page: currentPage.value,
|
||||
pageSize: pageSize.value,
|
||||
keyword: keyword.value.trim() || undefined,
|
||||
...(active.value === 'classes' ? {
|
||||
collegeId: listFilters.collegeId,
|
||||
majorId: listFilters.majorId,
|
||||
grade: listFilters.grade,
|
||||
isEnabled: listFilters.isEnabled,
|
||||
} : {
|
||||
campusId: listFilters.campusId,
|
||||
buildingId: listFilters.buildingId,
|
||||
minimumCapacity: listFilters.minimumCapacity,
|
||||
teachingVenueNature: listFilters.teachingVenueNature,
|
||||
isEnabled: listFilters.isEnabled,
|
||||
}),
|
||||
}
|
||||
: undefined,
|
||||
})
|
||||
@@ -187,6 +213,11 @@ async function loadReferences() {
|
||||
|
||||
async function changeTab() {
|
||||
keyword.value = ''
|
||||
Object.assign(listFilters, {
|
||||
collegeId: undefined, majorId: undefined, grade: undefined,
|
||||
campusId: undefined, buildingId: undefined, minimumCapacity: undefined,
|
||||
teachingVenueNature: undefined, isEnabled: undefined,
|
||||
})
|
||||
await load()
|
||||
}
|
||||
|
||||
@@ -388,6 +419,32 @@ watch(
|
||||
|
||||
<div class="table-toolbar">
|
||||
<el-input v-model="keyword" :prefix-icon="Search" clearable placeholder="搜索编码、名称或所属单位" />
|
||||
<template v-if="active === 'classes'">
|
||||
<el-select v-model="listFilters.collegeId" clearable placeholder="全部学院" @change="() => { listFilters.majorId = undefined; load() }">
|
||||
<el-option v-for="item in references.colleges" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
<el-select v-model="listFilters.majorId" clearable filterable placeholder="全部专业" @change="load()">
|
||||
<el-option v-for="item in filteredMajors" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
<el-input-number v-model="listFilters.grade" :min="1900" :max="2200" controls-position="right" placeholder="入学年级" @change="load()" />
|
||||
</template>
|
||||
<template v-else-if="active === 'classrooms'">
|
||||
<el-select v-model="listFilters.campusId" clearable placeholder="全部校区" @change="() => { listFilters.buildingId = undefined; load() }">
|
||||
<el-option v-for="item in references.campuses" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
<el-select v-model="listFilters.buildingId" clearable filterable placeholder="全部教学楼" @change="load()">
|
||||
<el-option v-for="item in filteredBuildings" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
<el-select v-model="listFilters.teachingVenueNature" clearable placeholder="场地性质" @change="load()">
|
||||
<el-option v-for="item in venueNatureOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
<el-input-number v-model="listFilters.minimumCapacity" :min="1" controls-position="right" placeholder="最小容量" @change="load()" />
|
||||
</template>
|
||||
<el-select v-if="serverPaged" v-model="listFilters.isEnabled" clearable placeholder="全部状态" @change="load()">
|
||||
<el-option label="启用" :value="true" />
|
||||
<el-option label="停用" :value="false" />
|
||||
</el-select>
|
||||
<el-button :icon="Search" @click="load()">查询</el-button>
|
||||
<el-button :icon="Refresh" @click="() => load(false)">刷新</el-button>
|
||||
<template v-if="canManage">
|
||||
<el-button :icon="Document" @click="downloadTemplate">下载模板</el-button>
|
||||
|
||||
@@ -39,6 +39,7 @@ interface TeachingClassItem {
|
||||
}
|
||||
|
||||
const terms = ref<any[]>([])
|
||||
const colleges = ref<any[]>([])
|
||||
const auth = useAuthStore()
|
||||
const canManageSchedule = computed(() => auth.user?.roles.some(role => ['SuperAdmin', 'AcademicAdmin'].includes(role)) ?? false)
|
||||
const classes = ref<TeachingClassItem[]>([])
|
||||
@@ -46,6 +47,9 @@ const selected = ref<TeachingClassItem>()
|
||||
const report = ref<any>()
|
||||
const termId = ref<string>()
|
||||
const keyword = ref('')
|
||||
const collegeId = ref<string>()
|
||||
const teacherKeyword = ref('')
|
||||
const riskOnly = ref(false)
|
||||
const page = ref(1)
|
||||
const total = ref(0)
|
||||
const pageSize = 12
|
||||
@@ -109,6 +113,9 @@ async function loadClasses(reset = false) {
|
||||
params: {
|
||||
academicTermId: termId.value,
|
||||
keyword: keyword.value.trim() || undefined,
|
||||
collegeId: collegeId.value,
|
||||
teacherKeyword: teacherKeyword.value.trim() || undefined,
|
||||
riskOnly: riskOnly.value || undefined,
|
||||
page: page.value,
|
||||
pageSize,
|
||||
},
|
||||
@@ -343,7 +350,12 @@ watch(historyMetric, async () => {
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
terms.value = (await http.get('/base-data/terms')).data
|
||||
const [termResponse, collegeResponse] = await Promise.all([
|
||||
http.get('/base-data/terms'),
|
||||
http.get('/base-data/colleges'),
|
||||
])
|
||||
terms.value = termResponse.data
|
||||
colleges.value = collegeResponse.data
|
||||
termId.value = defaultAcademicTermId(terms.value)
|
||||
} catch (error) {
|
||||
ElMessage.error(apiErrorMessage(error))
|
||||
@@ -409,7 +421,12 @@ onBeforeUnmount(() => {
|
||||
<el-select v-model="termId" clearable placeholder="全部学期" style="width: 240px" @change="loadClasses(true)">
|
||||
<el-option v-for="term in terms" :key="term.id" :label="academicTermLabel(term)" :value="term.id" />
|
||||
</el-select>
|
||||
<el-select v-model="collegeId" clearable placeholder="全部开课学院" style="width: 190px" @change="loadClasses(true)">
|
||||
<el-option v-for="college in colleges" :key="college.id" :label="college.name" :value="college.id" />
|
||||
</el-select>
|
||||
<el-input v-model="keyword" clearable placeholder="课程、教学班名称或编号" :prefix-icon="Search" @keyup.enter="loadClasses(true)" />
|
||||
<el-input v-model="teacherKeyword" clearable placeholder="任课教师姓名或工号" :prefix-icon="Search" @keyup.enter="loadClasses(true)" @clear="loadClasses(true)" />
|
||||
<el-checkbox v-model="riskOnly" @change="loadClasses(true)">仅看预警班</el-checkbox>
|
||||
<el-button type="primary" @click="loadClasses(true)">查询</el-button>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -28,6 +28,10 @@ const editingRoles = ref<string[]>([])
|
||||
const editingStaffNumber = ref('')
|
||||
const editingCollegeId = ref<string>()
|
||||
const keyword = ref('')
|
||||
const roleFilter = ref<string>()
|
||||
const collegeFilter = ref<string>()
|
||||
const enabledFilter = ref<boolean>()
|
||||
const loginFilter = ref<boolean>()
|
||||
const page = ref(1)
|
||||
const total = ref(0)
|
||||
const pageSize = 20
|
||||
@@ -69,6 +73,10 @@ async function load(resetPage = false) {
|
||||
page: page.value,
|
||||
pageSize,
|
||||
keyword: keyword.value.trim() || undefined,
|
||||
roleName: roleFilter.value,
|
||||
collegeId: collegeFilter.value,
|
||||
isEnabled: enabledFilter.value,
|
||||
hasLoggedIn: loginFilter.value,
|
||||
},
|
||||
}),
|
||||
http.get('/users/roles'),
|
||||
@@ -231,6 +239,20 @@ onMounted(load)
|
||||
@clear="load(true)"
|
||||
@keyup.enter="load(true)"
|
||||
/>
|
||||
<el-select v-model="roleFilter" clearable placeholder="全部角色" @change="load(true)">
|
||||
<el-option v-for="role in roles" :key="role.name" :label="role.name" :value="role.name" />
|
||||
</el-select>
|
||||
<el-select v-model="collegeFilter" clearable placeholder="全部学院" @change="load(true)">
|
||||
<el-option v-for="college in colleges" :key="college.id" :label="college.name" :value="college.id" />
|
||||
</el-select>
|
||||
<el-select v-model="enabledFilter" clearable placeholder="全部账号状态" @change="load(true)">
|
||||
<el-option label="启用" :value="true" />
|
||||
<el-option label="停用" :value="false" />
|
||||
</el-select>
|
||||
<el-select v-model="loginFilter" clearable placeholder="全部登录情况" @change="load(true)">
|
||||
<el-option label="已登录过" :value="true" />
|
||||
<el-option label="从未登录" :value="false" />
|
||||
</el-select>
|
||||
<el-button :icon="Search" @click="load(true)">查询</el-button>
|
||||
<el-button :icon="Document" @click="downloadTemplate">下载模板</el-button>
|
||||
<el-button :icon="Upload" :loading="importing" @click="chooseImportFile">Excel 导入</el-button>
|
||||
|
||||
Reference in New Issue
Block a user