课程类型支持下拉选择,增加课程资源id关联
This commit is contained in:
1 parent
abb042ff1a
commit
b78765c7ff
4 files changed
+140
-15
No files matched your search
@@ -43,6 +43,10 @@ public class TrainCourse extends BaseEntity
|
||||
@Excel(name = "课程内容")
|
||||
private String courseContent;
|
||||
|
||||
/** 课程资源ID,多个资源以英文逗号分隔,对应 train_resource.resource_id */
|
||||
@Excel(name = "课程资源ID")
|
||||
private String resourceId;
|
||||
|
||||
/** 课程状态 (1:正常, 0:停用) */
|
||||
@Excel(name = "课程状态", readConverterExp = "1=正常,0=停用")
|
||||
private Integer status;
|
||||
@@ -180,6 +184,16 @@ public class TrainCourse extends BaseEntity
|
||||
return courseContent;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId)
|
||||
{
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public String getResourceId()
|
||||
{
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status)
|
||||
{
|
||||
this.status = status;
|
||||
@@ -210,6 +224,7 @@ public class TrainCourse extends BaseEntity
|
||||
.append("cDuration", getcDuration())
|
||||
.append("teachingObjective", getTeachingObjective())
|
||||
.append("courseContent", getCourseContent())
|
||||
.append("resourceId", getResourceId())
|
||||
.append("status", getStatus())
|
||||
.append("delFlag", getDelFlag())
|
||||
.append("createBy", getCreateBy())
|
||||
|
||||
@@ -60,6 +60,8 @@ public class CourseDetailVO implements Serializable
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
|
||||
private String resourceId;
|
||||
|
||||
/**
|
||||
* 已关联的教学资源列表
|
||||
* 注:当前 ISSUE-01-03 未实现真实 Course<->Resource 查询;
|
||||
@@ -91,6 +93,7 @@ public class CourseDetailVO implements Serializable
|
||||
vo.setCreateTime(course.getCreateTime());
|
||||
vo.setUpdateBy(course.getUpdateBy());
|
||||
vo.setUpdateTime(course.getUpdateTime());
|
||||
vo.setResourceId(course.getResourceId());
|
||||
// 资源绑定/解绑能力属于 P1,当前返回空列表保持响应结构稳定
|
||||
vo.setResources(Collections.emptyList());
|
||||
return vo;
|
||||
@@ -286,6 +289,14 @@ public class CourseDetailVO implements Serializable
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public List<Object> getResources()
|
||||
{
|
||||
return resources;
|
||||
|
||||
@@ -12,6 +12,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="cDuration" column="c_duration" />
|
||||
<result property="teachingObjective" column="teaching_objective" />
|
||||
<result property="courseContent" column="course_content" />
|
||||
<result property="resourceId" column="resource_id" />
|
||||
<result property="status" column="status" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
<result property="createBy" column="create_by" />
|
||||
@@ -22,7 +23,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectTrainCourseVo">
|
||||
select c_id, c_code, c_name, c_type, c_duration, teaching_objective, course_content, status, del_flag, create_by, create_time, update_by, update_time, remark from train_course
|
||||
select c_id, c_code, c_name, c_type, c_duration, teaching_objective, course_content, resource_id, status, del_flag, create_by, create_time, update_by, update_time, remark from train_course
|
||||
</sql>
|
||||
|
||||
<select id="selectTrainCourseList" parameterType="TrainCourse" resultMap="TrainCourseResult">
|
||||
@@ -63,6 +64,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="cDuration != null">c_duration,</if>
|
||||
<if test="teachingObjective != null and teachingObjective != ''">teaching_objective,</if>
|
||||
<if test="courseContent != null and courseContent != ''">course_content,</if>
|
||||
<if test="resourceId != null and resourceId != ''">resource_id,</if>
|
||||
<if test="status != null">status,</if>
|
||||
<if test="delFlag != null and delFlag != ''">del_flag,</if>
|
||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||
@@ -79,6 +81,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="cDuration != null">#{cDuration},</if>
|
||||
<if test="teachingObjective != null and teachingObjective != ''">#{teachingObjective},</if>
|
||||
<if test="courseContent != null and courseContent != ''">#{courseContent},</if>
|
||||
<if test="resourceId != null and resourceId != ''">#{resourceId},</if>
|
||||
<if test="status != null">#{status},</if>
|
||||
<if test="delFlag != null and delFlag != ''">#{delFlag},</if>
|
||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||
@@ -98,6 +101,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="cDuration != null">c_duration = #{cDuration},</if>
|
||||
<if test="teachingObjective != null">teaching_objective = #{teachingObjective},</if>
|
||||
<if test="courseContent != null">course_content = #{courseContent},</if>
|
||||
<if test="resourceId != null">resource_id = #{resourceId},</if>
|
||||
<if test="status != null">status = #{status},</if>
|
||||
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
|
||||
@@ -18,12 +18,19 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="课程类型" prop="cType">
|
||||
<el-input
|
||||
<el-select
|
||||
v-model="queryParams.cType"
|
||||
placeholder="请输入课程类型"
|
||||
placeholder="请选择课程类型"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in dict.type.train_course_type"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="课程状态" clearable>
|
||||
@@ -66,10 +73,14 @@
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="课程编码" align="center" prop="cCode" min-width="120" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="课程名称" align="center" prop="cName" min-width="140" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="课程类型" align="center" prop="cType" width="120" />
|
||||
<el-table-column label="课程类型" align="center" prop="cType" width="120">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.train_course_type" :value="scope.row.cType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="学时" align="center" prop="cDuration" width="80" />
|
||||
<el-table-column label="教学目标" align="center" prop="teachingObjective" min-width="150" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="课程内容" align="center" prop="courseContent" min-width="160" :show-overflow-tooltip="true" />
|
||||
<!-- <el-table-column label="教学目标" align="center" prop="teachingObjective" min-width="150" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="课程内容" align="center" prop="courseContent" min-width="160" :show-overflow-tooltip="true" />-->
|
||||
<el-table-column label="状态" align="center" prop="status" width="90">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.status === 1 ? 'success' : 'info'">
|
||||
@@ -77,8 +88,8 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" prop="remark" min-width="120" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="160" />
|
||||
<!-- <el-table-column label="备注" align="center" prop="remark" min-width="120" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="160" />-->
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
@@ -136,7 +147,14 @@
|
||||
<el-input v-model="form.cName" placeholder="请输入课程名称" maxlength="100" />
|
||||
</el-form-item>
|
||||
<el-form-item label="课程类型" prop="cType">
|
||||
<el-input v-model="form.cType" placeholder="请输入课程类型 (如 理论课/实操课)" maxlength="30" />
|
||||
<el-select v-model="form.cType" placeholder="请选择课程类型" clearable style="width: 100%">
|
||||
<el-option
|
||||
v-for="dict in dict.type.train_course_type"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="课程学时" prop="cDuration">
|
||||
<el-input-number v-model="form.cDuration" :min="1" :max="9999" placeholder="请输入课程学时" style="width: 100%;" />
|
||||
@@ -147,6 +165,23 @@
|
||||
<el-form-item label="课程内容" prop="courseContent">
|
||||
<el-input v-model="form.courseContent" type="textarea" :rows="4" placeholder="请输入课程内容/摘要" />
|
||||
</el-form-item>
|
||||
<el-form-item label="课程资源" prop="resourceId">
|
||||
<el-select
|
||||
v-model="resourceIdList"
|
||||
multiple
|
||||
filterable
|
||||
collapse-tags
|
||||
placeholder="请选择课程资源 (可多选)"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in resourceOptions"
|
||||
:key="item.resourceId"
|
||||
:label="item.resourceName"
|
||||
:value="String(item.resourceId)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio :label="1">正常</el-radio>
|
||||
@@ -167,9 +202,11 @@
|
||||
|
||||
<script>
|
||||
import { listCourse, getCourse, addCourse, updateCourse, delCourse } from '@/api/train/course'
|
||||
import { listResource, getResource } from '@/api/train/resource'
|
||||
|
||||
export default {
|
||||
name: 'Course',
|
||||
dicts: ['train_course_type'],
|
||||
data() {
|
||||
const validateDuration = (rule, value, callback) => {
|
||||
if (value !== undefined && value !== null && value !== '') {
|
||||
@@ -200,6 +237,10 @@ export default {
|
||||
title: '',
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 课程资源下拉备选项
|
||||
resourceOptions: [],
|
||||
// 已选课程资源ID集合 (对应 form.resourceId 逗号分隔字符串)
|
||||
resourceIdList: [],
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
@@ -229,13 +270,52 @@ export default {
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
this.getResourceOptions()
|
||||
},
|
||||
methods: {
|
||||
/** 查询课程资源下拉备选项 (不做状态过滤,保证已选的停用资源也能正常回显) */
|
||||
getResourceOptions() {
|
||||
return listResource({ pageNum: 1, pageSize: 1000 }).then(response => {
|
||||
this.resourceOptions = response.rows || []
|
||||
return this.resourceOptions
|
||||
}).catch(() => {
|
||||
this.resourceOptions = this.resourceOptions || []
|
||||
return this.resourceOptions
|
||||
})
|
||||
},
|
||||
/** 课程资源ID字符串 -> 多选数组 (统一转成字符串,避免类型不一致导致无法勾选) */
|
||||
parseResourceIds(value) {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return []
|
||||
}
|
||||
return String(value).split(',').map(item => String(item).trim()).filter(item => item !== '')
|
||||
},
|
||||
/** 保证已选资源在下拉选项中存在;element-ui 多选值若无对应 option 会不显示,故必须补齐后再回显 */
|
||||
ensureResourceOptions(ids) {
|
||||
const existingIds = this.resourceOptions.map(item => String(item.resourceId).trim())
|
||||
const missingIds = ids.filter(id => existingIds.indexOf(id) === -1)
|
||||
if (missingIds.length === 0) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
return Promise.all(missingIds.map(id => {
|
||||
return getResource(id).then(response => {
|
||||
if (response.data) {
|
||||
this.resourceOptions.push(response.data)
|
||||
}
|
||||
}).catch(() => {})
|
||||
}))
|
||||
},
|
||||
/** 备选项就绪后再回显已选资源 */
|
||||
prepareResourceOptions(ids) {
|
||||
const load = this.resourceOptions.length > 0 ? Promise.resolve() : this.getResourceOptions()
|
||||
return Promise.resolve(load).then(() => this.ensureResourceOptions(ids))
|
||||
},
|
||||
/** 查询课程信息列表 */
|
||||
getList() {
|
||||
this.loading = true
|
||||
listCourse(this.queryParams).then(response => {
|
||||
this.courseList = response.rows
|
||||
//console.log(response.rows);
|
||||
this.total = response.total
|
||||
this.loading = false
|
||||
})
|
||||
@@ -255,9 +335,11 @@ export default {
|
||||
cDuration: null,
|
||||
teachingObjective: null,
|
||||
courseContent: null,
|
||||
resourceId: null,
|
||||
status: 1,
|
||||
remark: null
|
||||
}
|
||||
this.resourceIdList = []
|
||||
this.resetForm('form')
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
@@ -278,24 +360,37 @@ export default {
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset()
|
||||
this.open = true
|
||||
this.title = '添加课程'
|
||||
this.prepareResourceOptions([]).then(() => {
|
||||
this.open = true
|
||||
this.title = '添加课程'
|
||||
})
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset()
|
||||
const cId = row.cId || this.ids
|
||||
getCourse(cId).then(response => {
|
||||
//console.log(response.data);
|
||||
this.form = response.data
|
||||
if (this.form.status === undefined || this.form.status === null) {
|
||||
this.form.status = 1
|
||||
}
|
||||
this.open = true
|
||||
this.title = '修改课程'
|
||||
})
|
||||
const selectedIds = this.parseResourceIds(this.form.resourceId)
|
||||
// 必须先保证这些ID在下拉备选项中存在,否则多选不会被勾选/显示
|
||||
return this.prepareResourceOptions(selectedIds).then(() => {
|
||||
//this.resourceIdList = selectedIds
|
||||
//console.log("selectedIds===============");
|
||||
//console.log(selectedIds);
|
||||
this.$set(this,"resourceIdList",selectedIds);
|
||||
this.open = true
|
||||
this.title = '修改课程'
|
||||
})
|
||||
}).catch(() => {})
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
// 多选资源ID以逗号分隔写入 resource_id 字段
|
||||
this.form.resourceId = this.resourceIdList.length > 0 ? this.resourceIdList.join(',') : null
|
||||
this.$refs['form'].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.cId != null) {
|
||||
|
||||
Reference in new issue
Block a user