提交 72c8ad47 authored 作者: 王鹏飞's avatar 王鹏飞

feat: 学生管理增加筛选条件

上级 c2b5eab4
...@@ -25,7 +25,7 @@ const props = withDefaults( ...@@ -25,7 +25,7 @@ const props = withDefaults(
limit: 10, limit: 10,
data() { data() {
return [] return []
} },
} }
) )
...@@ -38,7 +38,7 @@ const page = reactive({ total: 0, size: props.limit, currentPage: 1 }) ...@@ -38,7 +38,7 @@ const page = reactive({ total: 0, size: props.limit, currentPage: 1 })
const params = reactive({ ...props.remote?.params }) const params = reactive({ ...props.remote?.params })
watch( watch(
() => props.data, () => props.data,
list => { (list) => {
dataList.value = list || [] dataList.value = list || []
}, },
{ immediate: true } { immediate: true }
...@@ -147,8 +147,7 @@ defineExpose({ refetch, tableRef, params, loading }) ...@@ -147,8 +147,7 @@ defineExpose({ refetch, tableRef, params, loading })
clearable clearable
@change="search" @change="search"
style="width: 200px" style="width: 200px"
v-if="item.type === 'input'" v-if="item.type === 'input'" />
/>
<!-- select --> <!-- select -->
<el-select <el-select
v-model="params[item.prop]" v-model="params[item.prop]"
...@@ -156,14 +155,12 @@ defineExpose({ refetch, tableRef, params, loading }) ...@@ -156,14 +155,12 @@ defineExpose({ refetch, tableRef, params, loading })
clearable clearable
@change="search" @change="search"
v-if="item.type === 'select'" v-if="item.type === 'select'"
style="width: 200px" style="width: 200px">
>
<el-option <el-option
:label="option[item.labelKey] || option.label" :label="option[item.labelKey] || option.label"
:value="option[item.valueKey] || option.value" :value="option[item.valueKey] || option.value"
v-for="(option, index) in item.options" v-for="(option, index) in item.options"
:key="index" :key="index" />
/>
</el-select> </el-select>
</template> </template>
</el-form-item> </el-form-item>
...@@ -186,8 +183,7 @@ defineExpose({ refetch, tableRef, params, loading }) ...@@ -186,8 +183,7 @@ defineExpose({ refetch, tableRef, params, loading })
v-bind="$attrs" v-bind="$attrs"
style="height: 100%" style="height: 100%"
ref="tableRef" ref="tableRef"
:header-cell-style="{ background: '#EFEFEF' }" :header-cell-style="{ background: '#EFEFEF' }">
>
<el-table-column v-bind="item || {}" v-for="item in columns" :key="item.prop"> <el-table-column v-bind="item || {}" v-for="item in columns" :key="item.prop">
<template #default="scope" v-if="item.slots || item.computed"> <template #default="scope" v-if="item.slots || item.computed">
<slot :name="item.slots" v-bind="scope" v-if="item.slots"></slot> <slot :name="item.slots" v-bind="scope" v-if="item.slots"></slot>
...@@ -206,15 +202,14 @@ defineExpose({ refetch, tableRef, params, loading }) ...@@ -206,15 +202,14 @@ defineExpose({ refetch, tableRef, params, loading })
class="table-list-pagination" class="table-list-pagination"
background background
layout="total, sizes, prev, pager, next, jumper" layout="total, sizes, prev, pager, next, jumper"
:page-sizes="[10, 20, 30, 50, 100]" :page-sizes="[10, 20, 30, 50]"
:page-size="page.size" :page-size="page.size"
:total="page.total" :total="page.total"
v-model:currentPage="page.currentPage" v-model:currentPage="page.currentPage"
@size-change="pageSizeChange" @size-change="pageSizeChange"
@current-change="fetchList()" @current-change="fetchList()"
:hide-on-single-page="true" :hide-on-single-page="true"
v-if="hasPagination" v-if="hasPagination">
>
</el-pagination> </el-pagination>
</div> </div>
</div> </div>
......
...@@ -7,7 +7,7 @@ export function getStudentList(params?: { name?: string; organ_id?: string; page ...@@ -7,7 +7,7 @@ export function getStudentList(params?: { name?: string; organ_id?: string; page
// // 导入学生 // // 导入学生
export function importStudent(data: { file: any }) { export function importStudent(data: { file: any }) {
return httpRequest.post('/api/resource/v1/learning/student/import', data, { return httpRequest.post('/api/resource/v1/learning/student/import', data, {
headers: { 'Content-Type': 'multipart/form-data' } headers: { 'Content-Type': 'multipart/form-data' },
}) })
} }
// 导出学生 // 导出学生
...@@ -50,10 +50,20 @@ export function getStuDetail(params?: { id: string }) { ...@@ -50,10 +50,20 @@ export function getStuDetail(params?: { id: string }) {
return httpRequest.get('/api/resource/v1/learning/student/view', { params }) return httpRequest.get('/api/resource/v1/learning/student/view', { params })
} }
// 班级搜索 // 班级搜索
export function getClassList(params?: { specialty_id: string; organ_id: string; page?: string; 'per-page'?: string }) { export function searchClass(params?: { specialty_id: string; organ_id: string; page?: string; 'per-page'?: string }) {
return httpRequest.get('/api/resource/v1/learning/student/search-class', { params }) return httpRequest.get('/api/resource/v1/learning/student/search-class', { params })
} }
// 获取专业列表 // 获取专业列表
export function getProList(params?: { name?: string; page?: string; 'per-page'?: string }) { export function getProList(params?: { name?: string; page?: string; 'per-page'?: string; sort?: string }) {
return httpRequest.get('/api/resource/v1/backend/specialty/list', { params }) return httpRequest.get('/api/resource/v1/backend/specialty/list', { params })
} }
// 获取班级列表
export function getClassList(params?: {
specialty_id: string
organ_id: string
page?: string
'per-page'?: string
sort?: string
}) {
return httpRequest.get('/api/resource/v1/learning/class/list', { params })
}
...@@ -4,7 +4,7 @@ import { ElMessage } from 'element-plus' ...@@ -4,7 +4,7 @@ import { ElMessage } from 'element-plus'
import { useProjectList } from '@/composables/useGetProjectList' import { useProjectList } from '@/composables/useGetProjectList'
import { useMapStore } from '@/stores/map' import { useMapStore } from '@/stores/map'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { addStudent, updateStudent, getStuDetail, getClassList, getProList } from '../api' import { addStudent, updateStudent, getStuDetail, searchClass, getProList } from '../api'
const store = useMapStore() const store = useMapStore()
const userStore = useUserStore() const userStore = useUserStore()
...@@ -112,7 +112,7 @@ if (userStore.roles[0].name !== '超级管理员') { ...@@ -112,7 +112,7 @@ if (userStore.roles[0].name !== '超级管理员') {
} }
// 获取班级列表 // 获取班级列表
const handleClassList = () => { const handleClassList = () => {
getClassList({ searchClass({
specialty_id: form.specialty_id, specialty_id: form.specialty_id,
organ_id: form.organ_id || userStore.organization?.id, organ_id: form.organ_id || userStore.organization?.id,
'per-page': '100' 'per-page': '100'
......
import { getClassList, getProList } from '../api'
// 专业列表
export function useSpecialtyList() {
const items = ref([])
const params = reactive({ name: '' })
const fetchList = async () => {
const { data } = await getProList({ ...params, 'per-page': '100', sort: 'name' })
items.value = data.list
}
onMounted(fetchList)
return { items, params, fetchList }
}
// 班级列表
export function useClassList() {
const items = ref([])
const params = reactive({ organ_id: '', specialty_id: '' })
const fetchList = async () => {
const { data } = await getClassList({ ...params, 'per-page': '100', sort: 'name' })
items.value = data.list
}
watch(params, fetchList)
onMounted(fetchList)
return { items, params, fetchList }
}
...@@ -7,44 +7,86 @@ import ImportStudent from '../components/ImportStudent.vue' ...@@ -7,44 +7,86 @@ import ImportStudent from '../components/ImportStudent.vue'
import { getStudentList, exportStudent, updateStudent } from '../api' import { getStudentList, exportStudent, updateStudent } from '../api'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useClassList, useSpecialtyList } from '../composables/useData'
// 判断当前用户是不是超级管理员 // 判断当前用户是不是超级管理员
const user = useUserStore().roles const user = useUserStore().roles
const isAdmin = !!user.find((item: any) => item.name === '超级管理员') const isAdmin = !!user.find((item: any) => item.name === '超级管理员')
const departmentList: any = useProjectList('', '79806610719731712').departmentList const { departmentList } = useProjectList('', '79806610719731712')
const appList = ref() const appList = ref()
const id = ref('') const id = ref('')
const title = ref('') const title = ref('')
const isEdit = ref('') const isEdit = ref('')
const isShowAddDialog = ref(false) const isShowAddDialog = ref(false)
const isShowImportDialog = ref(false) const isShowImportDialog = ref(false)
// 专业
const { items: specialtyList } = useSpecialtyList()
// 班级
let { items: classList, params } = useClassList()
// const isShowAnalysisDialog = ref(false) // const isShowAnalysisDialog = ref(false)
const listOptions = { const listOptions = computed(() => {
remote: { httpRequest: getStudentList, params: { name: '', organ_id: '' } }, return {
filters: [ remote: {
{ type: 'input', prop: 'name', label: '学生姓名:', placeholder: '学生姓名' }, httpRequest: getStudentList,
{ type: 'select', prop: 'organ_id', slots: 'filter-department' } params: { name: '', organ_id: '', mobile: '', specialty_id: '', class_id: '' },
], beforeRequest: (requestPrams: any) => {
columns: [ params.organ_id = requestPrams.organ_id
{ type: 'selection' }, params.specialty_id = requestPrams.specialty_id
{ label: '序号', type: 'index', align: 'center' }, return requestPrams
{ label: '学号', prop: 'sno_number', align: 'center', minWidth: '200' }, },
{ label: '姓名', prop: 'name', align: 'center', minWidth: '100' }, },
{ label: '性别', prop: 'gender_name', align: 'center' }, filters: [
{ label: '出生年月', prop: 'birthday', align: 'center', minWidth: '200' }, {
{ label: '省', prop: 'province_name', align: 'center' }, type: 'select',
{ label: '市', prop: 'city_name', align: 'center' }, prop: 'organ_id',
{ label: '县', prop: 'county_name', align: 'center' }, label: '所属部门/学校:',
{ label: '联系电话', prop: 'mobile', align: 'center', minWidth: '200' }, options: departmentList.value,
{ label: '部门/学校', prop: 'organ_id_name', align: 'center', minWidth: '200' }, labelKey: 'name',
{ label: '专业', prop: 'specialty_id_name', align: 'center', minWidth: '200' }, valueKey: 'id',
{ label: '班级', prop: 'class_id_name', align: 'center', minWidth: '200' }, },
{ label: '身份证号', prop: 'id_number', align: 'center', minWidth: '200' }, {
{ label: '生效状态', slots: 'status', align: 'center' }, type: 'select',
{ label: '更新时间', prop: 'updated_time', align: 'center', minWidth: '200' }, prop: 'specialty_id',
{ label: '操作', slots: 'table-operate', align: 'center', minWidth: '200', fixed: 'right' } label: '所属专业:',
] options: specialtyList.value,
} labelKey: 'name',
valueKey: 'id',
},
{
type: 'select',
prop: 'class_id',
label: '所属班级:',
options: classList.value,
labelKey: 'name',
valueKey: 'id',
},
{ type: 'input', prop: 'name', label: '学生姓名:', placeholder: '学生姓名' },
{ type: 'input', prop: 'mobile', label: '学生电话:', placeholder: '学生电话' },
],
columns: [
{ type: 'selection' },
{ label: '序号', type: 'index', align: 'center' },
{ label: '学号', prop: 'sno_number', align: 'center', minWidth: '200' },
{ label: '姓名', prop: 'name', align: 'center', minWidth: '100' },
{ label: '性别', prop: 'gender_name', align: 'center' },
{ label: '联系电话', prop: 'mobile', align: 'center', minWidth: '200' },
{ label: '部门/学校', prop: 'organ_id_name', align: 'center', minWidth: '200' },
{ label: '专业', prop: 'specialty_id_name', align: 'center', minWidth: '200' },
{ label: '班级', prop: 'class_id_name', align: 'center', minWidth: '200' },
{ label: '身份证号', prop: 'id_number', align: 'center', minWidth: '200' },
{ label: '出生年月', prop: 'birthday', align: 'center', minWidth: '200' },
{ label: '省', prop: 'province_name', align: 'center' },
{ label: '市', prop: 'city_name', align: 'center' },
{ label: '县', prop: 'county_name', align: 'center' },
{ label: '生效状态', slots: 'status', align: 'center' },
{ label: '更新时间', prop: 'updated_time', align: 'center', minWidth: '200' },
{ label: '操作', slots: 'table-operate', align: 'center', minWidth: '200', fixed: 'right' },
],
}
})
// 刷新页面 // 刷新页面
const handleRefresh = () => { const handleRefresh = () => {
...@@ -115,17 +157,23 @@ const handleAnalysis = () => { ...@@ -115,17 +157,23 @@ const handleAnalysis = () => {
<template> <template>
<AppCard title="学生管理"> <AppCard title="学生管理">
<AppList v-bind="listOptions" ref="appList" @selection-change="handleSelectionChange" border stripe style="margin-top: 30px"> <AppList
<el-button type="primary" round @click="handleAddStudent" v-permission="'v1-learning-student-create'">新增学生</el-button> v-bind="listOptions"
<el-button type="primary" round @click="handleImport" v-permission="'v1-learning-student-import'">批量导入</el-button> ref="appList"
<el-button type="primary" round @click="handleExport" v-permission="'v1-learning-student-download'">导出</el-button> @selection-change="handleSelectionChange"
border
stripe
style="margin-top: 30px">
<el-button type="primary" round @click="handleAddStudent" v-permission="'v1-learning-student-create'"
>新增学生</el-button
>
<el-button type="primary" round @click="handleImport" v-permission="'v1-learning-student-import'"
>批量导入</el-button
>
<el-button type="primary" round @click="handleExport" v-permission="'v1-learning-student-download'"
>导出</el-button
>
<el-button type="primary" round @click="handleAnalysis">生源地分析</el-button> <el-button type="primary" round @click="handleAnalysis">生源地分析</el-button>
<template v-if="isAdmin" #filter-department="{ params }">
<div class="name" style="font-size: 14px; color: #606266; padding-right: 12px">所属部门/学校:</div>
<el-select @change="handleRefresh" clearable v-model="params.organ_id" placeholder="请选择所属部门/学校">
<el-option v-for="item in departmentList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</template>
<template #status="{ row }"> <template #status="{ row }">
<el-switch <el-switch
size="large" size="large"
...@@ -139,14 +187,24 @@ const handleAnalysis = () => { ...@@ -139,14 +187,24 @@ const handleAnalysis = () => {
</template> </template>
<template #table-operate="{ row }"> <template #table-operate="{ row }">
<el-space> <el-space>
<el-link type="primary" plain @click="handleDetail(row)" v-permission="'v1-learning-student-view'">查看</el-link> <el-link type="primary" plain @click="handleDetail(row)" v-permission="'v1-learning-student-view'"
<el-link type="primary" plain @click="handleEdit(row)" v-permission="'v1-learning-student-update'">编辑</el-link> >查看</el-link
>
<el-link type="primary" plain @click="handleEdit(row)" v-permission="'v1-learning-student-update'"
>编辑</el-link
>
</el-space> </el-space>
</template> </template>
</AppList> </AppList>
</AppCard> </AppCard>
<!-- 新增学生 --> <!-- 新增学生 -->
<AddStudent v-if="isShowAddDialog === true" v-model:isShowAddDialog="isShowAddDialog" :id="id" :title="title" :isEdit="isEdit" @create="handleRefresh" /> <AddStudent
v-if="isShowAddDialog === true"
v-model:isShowAddDialog="isShowAddDialog"
:id="id"
:title="title"
:isEdit="isEdit"
@create="handleRefresh" />
<!-- 导入学生 --> <!-- 导入学生 -->
<ImportStudent v-if="isShowImportDialog" v-model:isShowImportDialog="isShowImportDialog" @create="handleRefresh" /> <ImportStudent v-if="isShowImportDialog" v-model:isShowImportDialog="isShowImportDialog" @create="handleRefresh" />
<!-- 生源地分析 --> <!-- 生源地分析 -->
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论