1、选修课选择教室、教员等用下拉选择,
2、绑定教材落库
This commit is contained in:
+3
@@ -35,6 +35,9 @@ public class ElectiveCourseSaveDTO {
|
||||
/** 教室编号 */
|
||||
private String jsbh;
|
||||
|
||||
/** 教材名称(按名称匹配教材信息,写入课程教材关联) */
|
||||
private String jcmc;
|
||||
|
||||
/** 计划人数 */
|
||||
private Integer rs;
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.roomroot.jwgl.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.roomroot.jwgl.entity.KCJC;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 课程教材 Mapper
|
||||
*/
|
||||
@Mapper
|
||||
public interface KCJCMapper extends BaseMapper<KCJC> {
|
||||
}
|
||||
+43
@@ -10,9 +10,11 @@ import com.roomroot.common.utils.poi.ExcelUtil;
|
||||
import com.roomroot.jwgl.dto.jys.ElectiveCourseImportDTO;
|
||||
import com.roomroot.jwgl.dto.jys.ElectiveCourseQuery;
|
||||
import com.roomroot.jwgl.dto.jys.ElectiveCourseSaveDTO;
|
||||
import com.roomroot.jwgl.entity.JCXX;
|
||||
import com.roomroot.jwgl.entity.JSB;
|
||||
import com.roomroot.jwgl.entity.JYB;
|
||||
import com.roomroot.jwgl.entity.KB;
|
||||
import com.roomroot.jwgl.entity.KCJC;
|
||||
import com.roomroot.jwgl.entity.XYDB;
|
||||
import com.roomroot.jwgl.entity.XYDNDXQJBXXB;
|
||||
import com.roomroot.jwgl.entity.XYDQB;
|
||||
@@ -23,7 +25,9 @@ import com.roomroot.jwgl.mapper.ClassSemesterMapper;
|
||||
import com.roomroot.jwgl.mapper.ElectiveCourseMapper;
|
||||
import com.roomroot.jwgl.mapper.JYBMapper;
|
||||
import com.roomroot.jwgl.mapper.KBMapper;
|
||||
import com.roomroot.jwgl.mapper.KCJCMapper;
|
||||
import com.roomroot.jwgl.mapper.StudentTeamTaskMapper;
|
||||
import com.roomroot.jwgl.mapper.TeachingMaterialMapper;
|
||||
import com.roomroot.jwgl.mapper.XYDBMapper;
|
||||
import com.roomroot.jwgl.mapper.XYDQBMapper;
|
||||
import com.roomroot.jwgl.mapper.ZYBMapper;
|
||||
@@ -93,6 +97,10 @@ public class ElectiveCourseServiceImpl implements ElectiveCourseService {
|
||||
private ZYBMapper zybMapper;
|
||||
@Resource
|
||||
private ClassSemesterMapper classSemesterMapper;
|
||||
@Resource
|
||||
private KCJCMapper kcjcMapper;
|
||||
@Resource
|
||||
private TeachingMaterialMapper teachingMaterialMapper;
|
||||
|
||||
@Resource
|
||||
private TeamCodeUtil teamCodeUtil;
|
||||
@@ -115,6 +123,8 @@ public class ElectiveCourseServiceImpl implements ElectiveCourseService {
|
||||
throw new ServiceException("选修课信息不能为空", BAD_REQUEST);
|
||||
}
|
||||
KB course = requireCourse(dto.getKbh());
|
||||
// 先校验教材存在性,避免先建班/学期后失败回滚留下副作用
|
||||
linkCourseTextbook(course.getKbh(), dto.getJcmc());
|
||||
String xydbh = resolveTeamId(dto.getXydbh(), dto.getXxbmc(), dto.getNj(), true, dto.getRs());
|
||||
XYDRWB task = new XYDRWB();
|
||||
task.setBh(UuidUtil.getOriginalUUID());
|
||||
@@ -259,6 +269,11 @@ public class ElectiveCourseServiceImpl implements ElectiveCourseService {
|
||||
}
|
||||
jsbh = room.getJsbh();
|
||||
}
|
||||
try {
|
||||
linkCourseTextbook(course.getKbh(), row.getJcmc());
|
||||
} catch (ServiceException e) {
|
||||
throw new ServiceException("第" + line + "行" + e.getMessage(), BAD_REQUEST);
|
||||
}
|
||||
String xydbh = resolveTeamId(null, row.getXxbmc().trim(), row.getKxbcnj(), true, row.getJhrs());
|
||||
XYDRWB task = new XYDRWB();
|
||||
task.setBh(UuidUtil.getOriginalUUID());
|
||||
@@ -656,6 +671,34 @@ public class ElectiveCourseServiceImpl implements ElectiveCourseService {
|
||||
return course;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按教材名称把教材挂到课程(课程教材表)。教材按「名称」精确匹配,
|
||||
* 同一课程同一教材的关联已存在则跳过,不覆盖课程已有教材。
|
||||
*/
|
||||
private void linkCourseTextbook(String kbh, String jcmc) {
|
||||
if (StringUtils.isEmpty(jcmc) || StringUtils.isEmpty(kbh)) {
|
||||
return;
|
||||
}
|
||||
JCXX material = teachingMaterialMapper.selectOne(new LambdaQueryWrapper<JCXX>()
|
||||
.eq(JCXX::getMc, jcmc.trim())
|
||||
.last("LIMIT 1"));
|
||||
if (material == null) {
|
||||
throw new ServiceException("教材不存在:" + jcmc, NOT_FOUND);
|
||||
}
|
||||
Long exists = kcjcMapper.selectCount(new LambdaQueryWrapper<KCJC>()
|
||||
.eq(KCJC::getKbh, kbh)
|
||||
.eq(KCJC::getJcbh, material.getBh()));
|
||||
if (exists != null && exists > 0) {
|
||||
return;
|
||||
}
|
||||
KCJC link = new KCJC();
|
||||
link.setBh(UuidUtil.getOriginalUUID());
|
||||
link.setKbh(kbh);
|
||||
link.setJcbh(material.getBh());
|
||||
link.setTy(0);
|
||||
kcjcMapper.insert(link);
|
||||
}
|
||||
|
||||
private void updateTeamDates(String xydbh, LocalDateTime start, LocalDateTime end) {
|
||||
if (start == null && end == null) {
|
||||
return;
|
||||
|
||||
@@ -149,13 +149,57 @@
|
||||
<el-input v-model="form.kcmc" placeholder="请输入课程名称,提交时按名称查找课编号" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="实施教员" prop="js">
|
||||
<el-input v-model="form.js" placeholder="请输入实施教员,提交时按名称查找教员编号" clearable />
|
||||
<el-select
|
||||
v-model="form.js"
|
||||
placeholder="请选择实施教员"
|
||||
clearable
|
||||
filterable
|
||||
:loading="teacherLoading"
|
||||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
v-for="t in teacherOptions"
|
||||
:key="t.jybh"
|
||||
:label="(t.jyxm || '-') + '(' + t.jybh + ')'"
|
||||
:value="t.jybh"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="教材">
|
||||
<el-input v-model="form.jc" placeholder="请输入教材" clearable />
|
||||
<el-select
|
||||
v-model="form.jc"
|
||||
placeholder="请选择教材"
|
||||
clearable
|
||||
filterable
|
||||
allow-create
|
||||
default-first-option
|
||||
:loading="materialLoading"
|
||||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
v-for="m in materialOptions"
|
||||
:key="m.bh || m.id"
|
||||
:label="m.mc"
|
||||
:value="m.mc"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="教学场地">
|
||||
<el-input v-model="form.jxcd" placeholder="请输入教学场地,提交时按名称查找教室编号" clearable />
|
||||
<el-select
|
||||
v-model="form.jxcd"
|
||||
placeholder="请选择教学场地"
|
||||
clearable
|
||||
filterable
|
||||
:loading="classroomLoading"
|
||||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
v-for="r in classroomOptions"
|
||||
:key="r.jsbh"
|
||||
:label="r.jsmc ? r.jsbh + ' · ' + r.jsmc : r.jsbh"
|
||||
:value="r.jsbh"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="计划学时">
|
||||
<el-input-number v-model="form.jhsxs" :min="0" :precision="0" class="w-full" />
|
||||
@@ -191,7 +235,8 @@ import {
|
||||
} from '@/api/teachOffice/elective'
|
||||
import { listKb } from '@/api/teachOffice/kb'
|
||||
import { listTeacher } from '@/api/teachOffice/teacher'
|
||||
import { listClassroom } from '@/api/teachBusiness/classroom'
|
||||
import { listAllClassroom } from '@/api/teachBusiness/classroom'
|
||||
import { listTeachingMaterial } from '@/api/textbook/teachingMaterial'
|
||||
import { saveAs } from 'file-saver'
|
||||
|
||||
export default {
|
||||
@@ -235,10 +280,18 @@ export default {
|
||||
xf: 0,
|
||||
jh: 0
|
||||
},
|
||||
// ==================== 新建弹窗下拉选项 ====================
|
||||
teacherOptions: [],
|
||||
teacherLoading: false,
|
||||
classroomOptions: [],
|
||||
classroomLoading: false,
|
||||
materialOptions: [],
|
||||
materialLoading: false,
|
||||
|
||||
rules: {
|
||||
xxbmc: [{ required: true, message: '请输入选修班名称', trigger: 'blur' }],
|
||||
kcmc: [{ required: true, message: '请输入课程名称', trigger: 'blur' }],
|
||||
js: [{ required: true, message: '请输入实施教员', trigger: 'blur' }]
|
||||
js: [{ required: true, message: '请选择实施教员', trigger: 'change' }]
|
||||
},
|
||||
|
||||
// ==================== 分页 ====================
|
||||
@@ -401,10 +454,50 @@ export default {
|
||||
jh: 0
|
||||
}
|
||||
this.dialogVisible = true
|
||||
this.loadTeacherOptions()
|
||||
this.loadClassroomOptions()
|
||||
this.loadMaterialOptions()
|
||||
this.$nextTick(() => {
|
||||
this.$refs.formRef && this.$refs.formRef.clearValidate()
|
||||
})
|
||||
},
|
||||
loadTeacherOptions() {
|
||||
if (this.teacherOptions.length || this.teacherLoading) return
|
||||
this.teacherLoading = true
|
||||
listTeacher({ pageNum: 1, pageSize: 500 }).then(res => {
|
||||
const records = (res && res.data && res.data.records) || []
|
||||
this.teacherOptions = records.filter(t => t.jybh && !t.lzzt)
|
||||
}).catch(() => {
|
||||
this.teacherOptions = []
|
||||
}).finally(() => {
|
||||
this.teacherLoading = false
|
||||
})
|
||||
},
|
||||
loadClassroomOptions() {
|
||||
if (this.classroomOptions.length || this.classroomLoading) return
|
||||
this.classroomLoading = true
|
||||
listAllClassroom().then(res => {
|
||||
this.classroomOptions = (res && res.data ? res.data : [])
|
||||
.filter(r => r.jsbh && !(r.ty === true || r.ty === 1 || r.ty === '1' || r.ty === 'true'))
|
||||
.sort((a, b) => String(a.jsbh).localeCompare(String(b.jsbh), 'zh-CN'))
|
||||
}).catch(() => {
|
||||
this.classroomOptions = []
|
||||
}).finally(() => {
|
||||
this.classroomLoading = false
|
||||
})
|
||||
},
|
||||
loadMaterialOptions() {
|
||||
if (this.materialOptions.length || this.materialLoading) return
|
||||
this.materialLoading = true
|
||||
listTeachingMaterial({ pageNum: 1, pageSize: 500 }).then(res => {
|
||||
const records = (res && res.data && res.data.records) || []
|
||||
this.materialOptions = records.filter(m => m.mc && !(m.ty === true || m.ty === 1 || m.ty === '1' || m.ty === 'true'))
|
||||
}).catch(() => {
|
||||
this.materialOptions = []
|
||||
}).finally(() => {
|
||||
this.materialLoading = false
|
||||
})
|
||||
},
|
||||
handleNewConfirm() {
|
||||
if (!this.$refs.formRef) return
|
||||
this.$refs.formRef.validate((valid) => {
|
||||
@@ -413,16 +506,9 @@ export default {
|
||||
})
|
||||
},
|
||||
submitNewElective() {
|
||||
const emptyPage = { data: { records: [] } }
|
||||
Promise.all([
|
||||
listKb({ pageNum: 1, pageSize: 1, kmc: this.form.kcmc }),
|
||||
listTeacher({ pageNum: 1, pageSize: 1, jyxm: this.form.js }),
|
||||
this.form.jxcd ? listClassroom({ pageNum: 1, pageSize: 1, jsmc: this.form.jxcd }) : Promise.resolve(emptyPage)
|
||||
])
|
||||
.then(([kbRes, teacherRes, roomRes]) => {
|
||||
listKb({ pageNum: 1, pageSize: 1, kmc: this.form.kcmc })
|
||||
.then(kbRes => {
|
||||
const kbh = kbRes?.data?.records?.[0]?.kbh
|
||||
const jybh = teacherRes?.data?.records?.[0]?.jybh
|
||||
const jsbh = roomRes?.data?.records?.[0]?.jsbh
|
||||
if (!kbh) {
|
||||
this.$message.warning(`未找到课程科目:${this.form.kcmc}`)
|
||||
return
|
||||
@@ -431,8 +517,9 @@ export default {
|
||||
kbh: kbh,
|
||||
xxbmc: this.form.xxbmc,
|
||||
nj: this.form.nj || undefined,
|
||||
jybh: jybh || undefined,
|
||||
jsbh: jsbh || undefined,
|
||||
jybh: this.form.js || undefined,
|
||||
jsbh: this.form.jxcd || undefined,
|
||||
jcmc: this.form.jc || undefined,
|
||||
rs: this.form.jh || undefined,
|
||||
xs: this.form.jhsxs || undefined,
|
||||
xf: this.form.xf || undefined
|
||||
@@ -486,6 +573,10 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// ==================== 6. 数据表格区域 ====================
|
||||
.table-card {
|
||||
.list-header {
|
||||
|
||||
Reference in New Issue
Block a user