edu/admin/src/views/organization/assign/index.vue

222 lines
7.0 KiB
Vue

<template>
<div class="class-divide">
<el-card class="!border-none" shadow="never">
<el-form ref="formRef" class="mb-[-16px]" :model="formData" :inline="true">
<el-form-item label="目标班级" prop="classIds">
<!-- 班级选择按钮 -->
<el-button
type="primary"
plain
class="w-[280px] text-left justify-start"
@click="openClassPopup"
>
{{
formData.classIds.length
? '已选择' + formData.classIds.length + '个班级'
: '请选择需要分配的班级'
}}
</el-button>
<!-- 仅显示已选择班级数量 -->
<div class="selected-count mt-2">
已选择 {{ formData.classIds.length }} 个班级
</div>
</el-form-item>
<el-form-item label="待分班学生" prop="studentIds">
<!-- 学生选择按钮 -->
<el-button
type="primary"
plain
class="w-[280px] text-left justify-start"
@click="openStudentPopup"
>
{{
formData.studentIds.length
? '已选择' + formData.studentIds.length + '名学生'
: '请选择需要分班的学生'
}}
</el-button>
<!-- 仅显示已选择学生数量 -->
<div class="selected-count mt-2">
已选择 {{ formData.studentIds.length }} 名学生
</div>
</el-form-item>
<el-form-item label="分班模式" prop="model">
<el-radio-group v-model="formData.model" class="w-[280px]">
<el-radio :label="1">优先填满模式</el-radio>
<el-radio :label="2">优先比例平均模式</el-radio>
<el-radio :label="3">优先人数平均模式</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleDivide">自动分班</el-button>
<el-button @click="resetForm">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none mt-4" shadow="never">
<div class="flex justify-between items-center">
<h3>分班结果预览</h3>
<el-button v-perms="['class:export']" type="primary" plain @click="handleExport">
<template #icon>
<icon name="el-icon-Download" />
</template>
导出结果
</el-button>
</div>
<el-table class="mt-4" size="large" v-loading="loading" :data="resultList">
<el-table-column label="班级名称" prop="className" min-width="150" />
<el-table-column label="学生姓名" prop="studentName" min-width="150" />
<el-table-column label="分配方式" prop="modelName" min-width="150" />
<el-table-column label="分配时间" prop="assignTime" min-width="180" />
</el-table>
<div class="flex justify-end mt-4" v-if="resultList.length > 0">
<pagination v-model="pager" @change="getResultList" />
</div>
</el-card>
<!-- 班级弹窗 -->
<class-popup
ref="classRef"
:selected-ids="formData.classIds"
@success="handleClassSelect"
@close="showClass = false"
/>
<!-- 学生弹窗 -->
<student-popup
ref="studentRef"
:selected-ids="formData.studentIds"
@success="handleStudentSelect"
@close="showStudent = false"
/>
</div>
</template>
<script lang="ts" setup name="classDivide">
import { reactive, ref, shallowRef } from 'vue'
import { authclass } from '@/api/assign'
import { classLists } from '@/api/class'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import ClassPopup from './class.vue'
import StudentPopup from './student.vue'
// 弹窗控制
const showClass = ref(false)
const showStudent = ref(false)
// 弹窗引用
const classRef = shallowRef<InstanceType<typeof ClassPopup>>()
const studentRef = shallowRef<InstanceType<typeof StudentPopup>>()
// 打开班级弹窗
const openClassPopup = () => {
classRef.value?.open()
showClass.value = true
}
// 打开学生弹窗
const openStudentPopup = () => {
studentRef.value?.open()
showStudent.value = true
}
// 表单数据
const formData = reactive({
classIds: [] as number[],
model: 1,
studentIds: [] as number[]
})
// 列表数据
const resultList = ref<Array<any>>([])
const loading = ref(false)
// 处理班级选择结果
const handleClassSelect = (selectedIds: number[]) => {
formData.classIds = selectedIds
showClass.value = false
}
// 处理学生选择结果
const handleStudentSelect = (selectedIds: number[]) => {
formData.studentIds = selectedIds
showStudent.value = false
}
// 分页配置
const { pager, getLists: getResultList } = usePaging({
fetchFun: classLists, // 替换为实际的分班结果接口
params: reactive({ page: 1, limit: 10 })
})
// 表单引用
const formRef = shallowRef<any>(null)
// 处理自动分班
const handleDivide = async () => {
if (!formData.classIds.length) {
return feedback.msgWarning('请选择目标班级')
}
if (!formData.studentIds.length) {
return feedback.msgWarning('请选择待分班学生')
}
try {
loading.value = true
await authclass(formData)
feedback.msgSuccess('分班成功')
getResultList() // 重新获取分班结果
resetForm() // 重置表单
} catch (err) {
feedback.msgError('分班失败,请重试')
} finally {
loading.value = false
}
}
// 重置表单
const resetForm = () => {
formData.classIds = []
formData.studentIds = []
formData.model = 1
formRef.value?.resetFields()
}
// 导出结果
const handleExport = () => {
feedback.confirm('导出功能开发中')
}
// 初始化加载数据
getResultList()
</script>
<style scoped>
.class-divide {
padding: 20px;
}
.selected-count {
padding: 4px 8px;
background-color: #f0f9ff;
border: 1px solid #cce5ff;
border-radius: 4px;
font-size: 12px;
color: #1890ff;
}
/* 调整表单项样式 */
:deep(.el-form-item__content) {
display: flex;
flex-direction: column;
align-items: flex-start;
}
</style>