371 lines
9.5 KiB
Vue
371 lines
9.5 KiB
Vue
<!--
|
||
任教信息编辑弹窗
|
||
@author pangu
|
||
-->
|
||
<template>
|
||
<el-dialog
|
||
v-model="visible"
|
||
:title="isEdit ? '编辑任教信息' : '添加任教信息'"
|
||
width="550px"
|
||
:close-on-click-modal="false"
|
||
destroy-on-close
|
||
>
|
||
<el-form
|
||
ref="formRef"
|
||
:model="form"
|
||
:rules="rules"
|
||
label-width="80px"
|
||
>
|
||
<el-form-item label="区域" prop="regionId">
|
||
<el-cascader
|
||
v-model="regionIds"
|
||
:options="regionTree"
|
||
:props="{ value: 'regionId', label: 'regionName', checkStrictly: true }"
|
||
placeholder="请选择区域"
|
||
clearable
|
||
style="width: 100%"
|
||
@change="handleRegionChange"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="学校" prop="schoolId">
|
||
<el-select v-model="form.schoolId" placeholder="请选择学校" clearable style="width: 100%" @change="handleSchoolChange">
|
||
<el-option v-for="item in schoolList" :key="item.schoolId" :label="item.schoolName" :value="item.schoolId" />
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="年级" prop="schoolGradeId">
|
||
<el-select v-model="form.schoolGradeId" placeholder="请选择年级" clearable style="width: 100%" @change="handleGradeChange">
|
||
<el-option v-for="item in gradeList" :key="item.id" :label="item.gradeName" :value="item.id" />
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="班级" prop="schoolClassId">
|
||
<el-select v-model="form.schoolClassId" placeholder="请选择班级" clearable style="width: 100%">
|
||
<el-option v-for="item in classList" :key="item.id" :label="item.className" :value="item.id" />
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="学科" prop="subjectId">
|
||
<el-select v-model="form.subjectId" placeholder="请选择学科(可选)" clearable style="width: 100%">
|
||
<el-option v-for="item in subjectList" :key="item.subjectId" :label="item.subjectName" :value="item.subjectId" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<template #footer>
|
||
<el-button @click="visible = false">取消</el-button>
|
||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
</template>
|
||
|
||
<script setup>
|
||
import request from '@/utils/request'
|
||
import { ElMessage } from 'element-plus'
|
||
import { reactive, ref, watch } from 'vue'
|
||
import useBaseDataStore from '@/store/modules/baseData'
|
||
|
||
const baseDataStore = useBaseDataStore()
|
||
|
||
const props = defineProps({
|
||
// 默认区域路径(用于新增时预填)
|
||
defaultRegionPath: {
|
||
type: Array,
|
||
default: () => []
|
||
}
|
||
})
|
||
|
||
const emit = defineEmits(['success', 'add', 'update'])
|
||
|
||
const visible = ref(false)
|
||
const isEdit = ref(false)
|
||
const formRef = ref(null)
|
||
const submitLoading = ref(false)
|
||
|
||
// 会员ID和任教信息ID(memberId 为 null 表示本地模式)
|
||
const memberId = ref(null)
|
||
const educationId = ref(null)
|
||
// 本地模式下的临时索引
|
||
const localIndex = ref(null)
|
||
|
||
// 区域ID数组(用于级联选择器)
|
||
const regionIds = ref([])
|
||
|
||
// 表单数据
|
||
const form = reactive({
|
||
regionId: null,
|
||
schoolId: null,
|
||
schoolGradeId: null,
|
||
schoolClassId: null,
|
||
subjectId: null
|
||
})
|
||
|
||
// 表单验证规则
|
||
const rules = {
|
||
schoolId: [{ required: true, message: '请选择学校', trigger: 'change' }],
|
||
schoolGradeId: [{ required: true, message: '请选择年级', trigger: 'change' }],
|
||
schoolClassId: [{ required: true, message: '请选择班级', trigger: 'change' }]
|
||
}
|
||
|
||
// 下拉选项数据
|
||
const regionTree = ref([])
|
||
const schoolList = ref([])
|
||
const gradeList = ref([])
|
||
const classList = ref([])
|
||
const subjectList = ref([])
|
||
|
||
/**
|
||
* 打开弹窗
|
||
* @param {Long} mId 会员ID(null 表示本地模式)
|
||
* @param {Object} row 编辑时传入任教信息数据
|
||
* @param {Number} index 本地模式下的数组索引
|
||
*/
|
||
const open = async (mId, row, index) => {
|
||
resetForm()
|
||
memberId.value = mId
|
||
isEdit.value = !!row
|
||
localIndex.value = index ?? null
|
||
visible.value = true
|
||
|
||
// 加载基础数据
|
||
await Promise.all([loadRegionTree(), loadSubjectList()])
|
||
|
||
// 编辑模式
|
||
if (row) {
|
||
educationId.value = row.educationId
|
||
form.schoolId = row.schoolId
|
||
form.schoolGradeId = row.schoolGradeId
|
||
form.schoolClassId = row.schoolClassId
|
||
form.subjectId = row.subjectId
|
||
|
||
// 加载关联数据
|
||
if (row.regionId) {
|
||
// 本地模式下 regionIds 可能已有值
|
||
if (row.regionIds) {
|
||
regionIds.value = row.regionIds
|
||
} else {
|
||
regionIds.value = await getRegionPath(row.regionId)
|
||
}
|
||
form.regionId = row.regionId
|
||
await loadSchoolList(row.regionId)
|
||
}
|
||
if (row.schoolId) {
|
||
await loadGradeList(row.schoolId)
|
||
}
|
||
if (row.schoolGradeId) {
|
||
await loadClassList(row.schoolGradeId)
|
||
}
|
||
} else {
|
||
// 新增模式:如果有默认区域路径,使用它
|
||
applyDefaultRegion()
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 应用默认区域路径
|
||
*/
|
||
const applyDefaultRegion = async () => {
|
||
if (props.defaultRegionPath && props.defaultRegionPath.length > 0 && regionIds.value.length === 0) {
|
||
regionIds.value = [...props.defaultRegionPath]
|
||
form.regionId = props.defaultRegionPath[props.defaultRegionPath.length - 1]
|
||
await loadSchoolList(form.regionId)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 重置表单
|
||
*/
|
||
const resetForm = () => {
|
||
educationId.value = null
|
||
regionIds.value = []
|
||
form.regionId = null
|
||
form.schoolId = null
|
||
form.schoolGradeId = null
|
||
form.schoolClassId = null
|
||
form.subjectId = null
|
||
schoolList.value = []
|
||
gradeList.value = []
|
||
classList.value = []
|
||
}
|
||
|
||
/**
|
||
* 加载区域树(使用 Store 缓存)
|
||
*/
|
||
const loadRegionTree = async () => {
|
||
try {
|
||
regionTree.value = await baseDataStore.fetchRegionTree()
|
||
} catch (e) {
|
||
regionTree.value = []
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 加载学科列表(使用 Store 缓存)
|
||
*/
|
||
const loadSubjectList = async () => {
|
||
try {
|
||
subjectList.value = await baseDataStore.fetchSubjects()
|
||
} catch (e) {
|
||
subjectList.value = []
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 加载学校列表
|
||
*/
|
||
const loadSchoolList = async (regionId) => {
|
||
try {
|
||
const res = await request.get('/business/school/listAll', { params: { regionId } })
|
||
schoolList.value = res.data || []
|
||
} catch (e) {
|
||
schoolList.value = []
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 加载年级列表
|
||
*/
|
||
const loadGradeList = async (schoolId) => {
|
||
try {
|
||
const res = await request.get(`/business/school/${schoolId}/grades`)
|
||
gradeList.value = res.data || []
|
||
} catch (e) {
|
||
gradeList.value = []
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 加载班级列表
|
||
*/
|
||
const loadClassList = async (schoolGradeId) => {
|
||
try {
|
||
const res = await request.get(`/business/school/grade/${schoolGradeId}/classes`)
|
||
classList.value = res.data || []
|
||
} catch (e) {
|
||
classList.value = []
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取区域路径(用于回显)
|
||
*/
|
||
const getRegionPath = async (regionId) => {
|
||
try {
|
||
const res = await request.get(`/business/region/${regionId}/path`)
|
||
return res.data || []
|
||
} catch (e) {
|
||
return []
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 区域变更
|
||
*/
|
||
const handleRegionChange = (val) => {
|
||
form.regionId = val && val.length ? val[val.length - 1] : null
|
||
form.schoolId = null
|
||
form.schoolGradeId = null
|
||
form.schoolClassId = null
|
||
schoolList.value = []
|
||
gradeList.value = []
|
||
classList.value = []
|
||
if (form.regionId) {
|
||
loadSchoolList(form.regionId)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 学校变更
|
||
*/
|
||
const handleSchoolChange = () => {
|
||
form.schoolGradeId = null
|
||
form.schoolClassId = null
|
||
gradeList.value = []
|
||
classList.value = []
|
||
if (form.schoolId) {
|
||
loadGradeList(form.schoolId)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 年级变更
|
||
*/
|
||
const handleGradeChange = () => {
|
||
form.schoolClassId = null
|
||
classList.value = []
|
||
if (form.schoolGradeId) {
|
||
loadClassList(form.schoolGradeId)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 提交表单
|
||
*/
|
||
const handleSubmit = async () => {
|
||
try {
|
||
await formRef.value?.validate()
|
||
} catch (e) {
|
||
return
|
||
}
|
||
|
||
// 构建数据(包含名称用于本地展示)
|
||
const data = {
|
||
regionId: form.regionId,
|
||
regionIds: [...regionIds.value],
|
||
schoolId: form.schoolId,
|
||
schoolGradeId: form.schoolGradeId,
|
||
schoolClassId: form.schoolClassId,
|
||
subjectId: form.subjectId,
|
||
// 添加名称用于列表展示
|
||
schoolName: schoolList.value.find(s => s.schoolId === form.schoolId)?.schoolName || '',
|
||
gradeName: gradeList.value.find(g => g.id === form.schoolGradeId)?.gradeName || '',
|
||
className: classList.value.find(c => c.id === form.schoolClassId)?.className || '',
|
||
subjectName: subjectList.value.find(s => s.subjectId === form.subjectId)?.subjectName || ''
|
||
}
|
||
|
||
// 本地模式:返回数据给父组件
|
||
if (!memberId.value) {
|
||
visible.value = false
|
||
if (isEdit.value) {
|
||
emit('update', data, localIndex.value)
|
||
} else {
|
||
emit('add', data)
|
||
}
|
||
return
|
||
}
|
||
|
||
// 远程模式:调用 API
|
||
submitLoading.value = true
|
||
try {
|
||
const apiData = {
|
||
regionId: form.regionId,
|
||
schoolId: form.schoolId,
|
||
schoolGradeId: form.schoolGradeId,
|
||
schoolClassId: form.schoolClassId,
|
||
subjectId: form.subjectId
|
||
}
|
||
|
||
if (isEdit.value) {
|
||
const res = await request.put(`/business/member/${memberId.value}/educations/${educationId.value}`, apiData)
|
||
if (res.code === 200) {
|
||
ElMessage.success('修改成功')
|
||
visible.value = false
|
||
emit('success')
|
||
}
|
||
} else {
|
||
const res = await request.post(`/business/member/${memberId.value}/educations`, apiData)
|
||
if (res.code === 200) {
|
||
ElMessage.success('添加成功')
|
||
visible.value = false
|
||
emit('success')
|
||
}
|
||
}
|
||
} finally {
|
||
submitLoading.value = false
|
||
}
|
||
}
|
||
|
||
defineExpose({ open })
|
||
</script>
|