2026-02-03 16:35:57 +08:00
|
|
|
|
<!--
|
|
|
|
|
|
教育身份编辑弹窗
|
2026-02-03 20:26:45 +08:00
|
|
|
|
@author pangu
|
2026-02-03 16:35:57 +08:00
|
|
|
|
-->
|
|
|
|
|
|
<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 } from 'vue'
|
2026-02-03 17:25:10 +08:00
|
|
|
|
import useBaseDataStore from '@/store/modules/baseData'
|
|
|
|
|
|
|
|
|
|
|
|
const baseDataStore = useBaseDataStore()
|
2026-02-03 16:35:57 +08:00
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 重置表单
|
|
|
|
|
|
*/
|
|
|
|
|
|
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 = []
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-02-03 17:25:10 +08:00
|
|
|
|
* 加载区域树(使用 Store 缓存)
|
2026-02-03 16:35:57 +08:00
|
|
|
|
*/
|
|
|
|
|
|
const loadRegionTree = async () => {
|
|
|
|
|
|
try {
|
2026-02-03 17:25:10 +08:00
|
|
|
|
regionTree.value = await baseDataStore.fetchRegionTree()
|
2026-02-03 16:35:57 +08:00
|
|
|
|
} catch (e) {
|
|
|
|
|
|
regionTree.value = []
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-02-03 17:25:10 +08:00
|
|
|
|
* 加载学科列表(使用 Store 缓存)
|
2026-02-03 16:35:57 +08:00
|
|
|
|
*/
|
|
|
|
|
|
const loadSubjectList = async () => {
|
|
|
|
|
|
try {
|
2026-02-03 17:25:10 +08:00
|
|
|
|
subjectList.value = await baseDataStore.fetchSubjects()
|
2026-02-03 16:35:57 +08:00
|
|
|
|
} 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>
|