diff --git a/RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/TrainResourceController.java b/RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/TrainResourceController.java new file mode 100644 index 000000000..9ae9ee110 --- /dev/null +++ b/RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/TrainResourceController.java @@ -0,0 +1,93 @@ +package com.ruoyi.web.controller.train; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.train.domain.TrainResource; +import com.ruoyi.train.service.ITrainResourceService; + +/** + * 教学资源Controller + * + * @author ruoyi + */ +@RestController +@RequestMapping("/train/resource") +public class TrainResourceController extends BaseController +{ + @Autowired + private ITrainResourceService trainResourceService; + + /** + * 查询教学资源列表 + */ + @PreAuthorize("@ss.hasPermi('train:resource:list')") + @GetMapping("/list") + public TableDataInfo list(TrainResource trainResource) + { + startPage(); + List list = trainResourceService.selectTrainResourceList(trainResource); + return getDataTable(list); + } + + /** + * 获取教学资源详细信息 + */ + @PreAuthorize("@ss.hasPermi('train:resource:list')") + @GetMapping(value = "/{resourceId}") + public AjaxResult getInfo(@PathVariable("resourceId") String resourceId) + { + return success(trainResourceService.selectTrainResourceByResourceId(resourceId)); + } + + /** + * 新增教学资源 + */ + @PreAuthorize("@ss.hasPermi('train:resource:edit')") + @Log(title = "教学资源", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody TrainResource trainResource) + { + trainResource.setCreateBy(SecurityUtils.getUsername()); + return toAjax(trainResourceService.insertTrainResource(trainResource)); + } + + /** + * 删除教学资源 (RESTful DELETE /train/resource/{resourceIds}) + */ + @PreAuthorize("@ss.hasPermi('train:resource:edit')") + @Log(title = "教学资源", businessType = BusinessType.DELETE) + @DeleteMapping("/{resourceIds}") + public AjaxResult remove(@PathVariable String[] resourceIds) + { + return toAjax(trainResourceService.deleteTrainResourceByResourceIds(resourceIds)); + } + + /** + * 修改教学资源 (RESTful PUT /train/resource/{resourceId}) + */ + @PreAuthorize("@ss.hasPermi('train:resource:edit')") + @Log(title = "教学资源", businessType = BusinessType.UPDATE) + @PutMapping("/{resourceId}") + public AjaxResult edit(@PathVariable("resourceId") String resourceId, @Validated @RequestBody TrainResource trainResource) + { + trainResource.setResourceId(resourceId); + trainResource.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(trainResourceService.updateTrainResource(trainResource)); + } +} diff --git a/RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/TrainStudentController.java b/RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/TrainStudentController.java index f6646b8f9..8996242dd 100644 --- a/RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/TrainStudentController.java +++ b/RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/TrainStudentController.java @@ -1,15 +1,12 @@ package com.ruoyi.web.controller.train; import java.util.List; +import java.util.regex.Pattern; import javax.validation.Valid; + +import com.ruoyi.common.utils.StringUtils; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import com.github.pagehelper.PageInfo; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.constant.HttpStatus; @@ -18,6 +15,7 @@ import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.train.domain.dto.StudentCreateDTO; +import com.ruoyi.train.domain.dto.StudentUpdateDTO; import com.ruoyi.train.domain.query.StudentQuery; import com.ruoyi.train.domain.vo.StudentAdminVO; import com.ruoyi.train.domain.vo.StudentDetailVO; @@ -30,6 +28,8 @@ import com.ruoyi.web.service.train.TrainAccountBindingAdminService; @RequestMapping({"/train/student", "/train/students"}) public class TrainStudentController extends BaseController { + private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$"); + private final ITrainStudentService trainStudentService; private final TrainAccountBindingAdminService bindingAdminService; @@ -76,6 +76,27 @@ public class TrainStudentController extends BaseController return success(trainStudentService.createStudent(dto)); } + /** + * 修改学员信息 (PUT /train/student/{sId}) + */ + @PreAuthorize("@ss.hasPermi('train:student:edit')") + @Log(title = "学员主档", businessType = BusinessType.UPDATE, + isSaveRequestData = false, isSaveResponseData = true) + @PutMapping(value = "/{sId}") + public AjaxResult edit(@PathVariable("sId") String sId, @Valid @RequestBody StudentUpdateDTO dto) + { + dto.setsId(sId); + if (StringUtils.isNotEmpty(dto.getsName()) && dto.getsName().trim().length() > 50) + { + return AjaxResult.error("学员姓名长度不能超过50个字符"); + } + if (StringUtils.isNotEmpty(dto.getsPhone()) && !isValidPhone(dto.getsPhone())) + { + return AjaxResult.error("学员手机号码格式不正确"); + } + return success(trainStudentService.updateTrainStudent(dto)); + } + @PreAuthorize("@ss.hasPermi('train:student:remove')") @Log(title = "学员主档", businessType = BusinessType.DELETE) @DeleteMapping("/{sId}") @@ -83,4 +104,9 @@ public class TrainStudentController extends BaseController { return toAjax(trainStudentService.deleteTrainStudentBySId(sId)); } + + private boolean isValidPhone(String phone) + { + return PHONE_PATTERN.matcher(phone).matches(); + } } diff --git a/RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/TrainTrainingSiteController.java b/RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/TrainTrainingSiteController.java index a88fe16cd..8b71d8c75 100644 --- a/RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/TrainTrainingSiteController.java +++ b/RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/TrainTrainingSiteController.java @@ -4,6 +4,7 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -67,6 +68,17 @@ public class TrainTrainingSiteController extends BaseController return toAjax(trainTrainingSiteService.insertTrainTrainingSite(trainTrainingSite)); } + /** + * 删除实训场地 (RESTful DELETE /train/training-site/{siteIds}) + */ + @PreAuthorize("@ss.hasPermi('train:site:edit')") + @Log(title = "实训场地", businessType = BusinessType.DELETE) + @DeleteMapping("/{siteIds}") + public AjaxResult remove(@PathVariable String[] siteIds) + { + return toAjax(trainTrainingSiteService.deleteTrainTrainingSiteBySiteIds(siteIds)); + } + /** * 修改实训场地 (RESTful PUT /train/training-site/{siteId}) */ diff --git a/RuoYi-Vue/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/RuoYi-Vue/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index c02381a9f..aed7f86a3 100644 --- a/RuoYi-Vue/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/RuoYi-Vue/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -63,7 +63,7 @@ public class SysLoginService public String login(String username, String password, String code, String uuid) { // 验证码校验 - //validateCaptcha(username, code, uuid); + validateCaptcha(username, code, uuid); // 登录前置校验 loginPreCheck(username, password); // 用户验证 diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainClassroomInfo.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainClassroomInfo.java index 1733539bc..3405afa9e 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainClassroomInfo.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainClassroomInfo.java @@ -46,6 +46,12 @@ public class TrainClassroomInfo extends BaseEntity /** 删除标志 (0代表存在 2代表删除) */ private String delFlag; + private Integer multimedia; + + private Integer projector; + + private String seatArrange; + public void setClassRoomId(String classRoomId) { this.classRoomId = classRoomId; @@ -106,6 +112,30 @@ public class TrainClassroomInfo extends BaseEntity return delFlag; } + public Integer getMultimedia() { + return multimedia; + } + + public void setMultimedia(Integer multimedia) { + this.multimedia = multimedia; + } + + public Integer getProjector() { + return projector; + } + + public void setProjector(Integer projector) { + this.projector = projector; + } + + public String getSeatArrange() { + return seatArrange; + } + + public void setSeatArrange(String seatArrange) { + this.seatArrange = seatArrange; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -120,6 +150,9 @@ public class TrainClassroomInfo extends BaseEntity .append("updateBy", getUpdateBy()) .append("updateTime", getUpdateTime()) .append("remark", getRemark()) + .append("multimedia", getMultimedia()) + .append("projector", getProjector()) + .append("seatArrange", getSeatArrange()) .toString(); } } diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainCourse.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainCourse.java index e2d379227..d0d6533c8 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainCourse.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainCourse.java @@ -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()) diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainResource.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainResource.java new file mode 100644 index 000000000..31b6104a8 --- /dev/null +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainResource.java @@ -0,0 +1,149 @@ +package com.ruoyi.train.domain; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 教学资源对象 train_resource + * + *

统一教学资源:文档、视频、3D模型、VR资源、外部教学链接、其他。 + * 该表被 train_course_resource、train_study_duration 外键引用,删除一律走逻辑删除。

+ * + * @author ruoyi + */ +public class TrainResource extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 资源唯一ID */ + private String resourceId; + + /** 资源名称 */ + @NotBlank(message = "资源名称不能为空") + @Size(max = 150, message = "资源名称长度不能超过150个字符") + @Excel(name = "资源名称") + private String resourceName; + + /** 资源类型 (1:文档, 2:视频, 3:3D模型, 4:VR资源, 5:外部教学链接, 6:其他) */ + @NotNull(message = "资源类型不能为空") + @Min(value = 1, message = "资源类型取值必须为1-6") + @Max(value = 6, message = "资源类型取值必须为1-6") + @Excel(name = "资源类型", readConverterExp = "1=文档,2=视频,3=3D模型,4=VR资源,5=外部教学链接,6=其他") + private Integer resourceType; + + /** 资源存储地址/在线链接 */ + @NotBlank(message = "资源地址不能为空") + @Size(max = 500, message = "资源地址长度不能超过500个字符") + @Excel(name = "资源地址") + private String resourceUrl; + + /** 资源描述/使用说明 */ + @Size(max = 500, message = "资源描述长度不能超过500个字符") + @Excel(name = "资源描述") + private String description; + + /** 状态 (1:正常, 0:停用) */ + @Min(value = 0, message = "状态取值必须为0或1") + @Max(value = 1, message = "状态取值必须为0或1") + @Excel(name = "状态", readConverterExp = "0=停用,1=正常") + private Integer status; + + /** 删除标志 (0代表存在 2代表删除) */ + private String delFlag; + + public void setResourceId(String resourceId) + { + this.resourceId = resourceId; + } + + public String getResourceId() + { + return resourceId; + } + + public void setResourceName(String resourceName) + { + this.resourceName = resourceName; + } + + public String getResourceName() + { + return resourceName; + } + + public void setResourceType(Integer resourceType) + { + this.resourceType = resourceType; + } + + public Integer getResourceType() + { + return resourceType; + } + + public void setResourceUrl(String resourceUrl) + { + this.resourceUrl = resourceUrl; + } + + public String getResourceUrl() + { + return resourceUrl; + } + + public void setDescription(String description) + { + this.description = description; + } + + public String getDescription() + { + return description; + } + + public void setStatus(Integer status) + { + this.status = status; + } + + public Integer getStatus() + { + return status; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() + { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("resourceId", getResourceId()) + .append("resourceName", getResourceName()) + .append("resourceType", getResourceType()) + .append("resourceUrl", getResourceUrl()) + .append("description", getDescription()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainStudent.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainStudent.java index f955ccbce..4df2cd266 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainStudent.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainStudent.java @@ -42,6 +42,10 @@ public class TrainStudent extends BaseEntity private Integer status; private String delFlag; + private String avatar; + + private Integer dutyLevel; + public String getsId() { return sId; @@ -194,6 +198,22 @@ public class TrainStudent extends BaseEntity this.delFlag = delFlag; } + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public Integer getDutyLevel() { + return dutyLevel; + } + + public void setDutyLevel(Integer dutyLevel) { + this.dutyLevel = dutyLevel; + } + /** * 安全日志表示:刻意不包含身份证密文、查重值或任何完整身份证信息。 */ @@ -219,6 +239,8 @@ public class TrainStudent extends BaseEntity .append("updateBy", getUpdateBy()) .append("updateTime", getUpdateTime()) .append("remark", getRemark()) + .append("dutyLevel", getDutyLevel()) + .append("avatar", getAvatar()) .toString(); } } diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainTeacher.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainTeacher.java index ceafd6f4f..4df270495 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainTeacher.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainTeacher.java @@ -60,6 +60,15 @@ public class TrainTeacher extends BaseEntity /** 删除标志 (0:存在, 2:删除) */ private String delFlag; + private String avatar; + + private String major; + + private String courses; + + private Date startTeaching; + + public void settId(String tId) { this.tId = tId; @@ -180,6 +189,38 @@ public class TrainTeacher extends BaseEntity return delFlag; } + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getMajor() { + return major; + } + + public void setMajor(String major) { + this.major = major; + } + + public String getCourses() { + return courses; + } + + public void setCourses(String courses) { + this.courses = courses; + } + + public Date getStartTeaching() { + return startTeaching; + } + + public void setStartTeaching(Date startTeaching) { + this.startTeaching = startTeaching; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -199,6 +240,10 @@ public class TrainTeacher extends BaseEntity .append("updateBy", getUpdateBy()) .append("updateTime", getUpdateTime()) .append("remark", getRemark()) + .append("avatar", getAvatar()) + .append("major", getMajor()) + .append("courses", getCourses()) + .append("startTeaching", getStartTeaching()) .toString(); } } diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainTrainingSite.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainTrainingSite.java index fd705060f..801073da4 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainTrainingSite.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/TrainTrainingSite.java @@ -50,6 +50,10 @@ public class TrainTrainingSite extends BaseEntity /** 删除标志 (0代表存在 2代表删除) */ private String delFlag; + private String major; + + private String seatArrange; + public void setSiteId(String siteId) { this.siteId = siteId; @@ -120,6 +124,22 @@ public class TrainTrainingSite extends BaseEntity return delFlag; } + public String getMajor() { + return major; + } + + public void setMajor(String major) { + this.major = major; + } + + public String getSeatArrange() { + return seatArrange; + } + + public void setSeatArrange(String seatArrange) { + this.seatArrange = seatArrange; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -135,6 +155,8 @@ public class TrainTrainingSite extends BaseEntity .append("updateBy", getUpdateBy()) .append("updateTime", getUpdateTime()) .append("remark", getRemark()) + .append("major", getMajor()) + .append("seatArrange", getSeatArrange()) .toString(); } } diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/ClassroomCreateDTO.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/ClassroomCreateDTO.java index 8e1758ed7..77f9938ae 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/ClassroomCreateDTO.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/ClassroomCreateDTO.java @@ -32,6 +32,12 @@ public class ClassroomCreateDTO implements Serializable /** 教室状态 (0: 正在使用, 1: 可用空闲, 2: 维护中) */ private Integer roomStatus; + private Integer multimedia; + + private Integer projector; + + private String seatArrange; + /** 备注 */ @Size(max = 500, message = "备注长度不能超过500个字符") private String remark; @@ -85,4 +91,28 @@ public class ClassroomCreateDTO implements Serializable { this.remark = remark; } + + public Integer getMultimedia() { + return multimedia; + } + + public void setMultimedia(Integer multimedia) { + this.multimedia = multimedia; + } + + public Integer getProjector() { + return projector; + } + + public void setProjector(Integer projector) { + this.projector = projector; + } + + public String getSeatArrange() { + return seatArrange; + } + + public void setSeatArrange(String seatArrange) { + this.seatArrange = seatArrange; + } } diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/SiteCreateDTO.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/SiteCreateDTO.java index 6744760d5..a2791e807 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/SiteCreateDTO.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/SiteCreateDTO.java @@ -39,6 +39,10 @@ public class SiteCreateDTO implements Serializable @Size(max = 500, message = "备注长度不能超过500个字符") private String remark; + private String seatArrange; + + private String major; + public String getSiteName() { return siteName; @@ -98,4 +102,20 @@ public class SiteCreateDTO implements Serializable { this.remark = remark; } + + public String getSeatArrange() { + return seatArrange; + } + + public void setSeatArrange(String seatArrange) { + this.seatArrange = seatArrange; + } + + public String getMajor() { + return major; + } + + public void setMajor(String major) { + this.major = major; + } } diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/StudentCreateDTO.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/StudentCreateDTO.java index a8d100e51..e892ca896 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/StudentCreateDTO.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/StudentCreateDTO.java @@ -46,6 +46,9 @@ public class StudentCreateDTO implements Serializable @Size(max = 500, message = "备注长度不能超过500个字符") private String remark; + private Integer dutyLevel; + private String avatar; + public String getsName() { return sName; } public void setsName(String sName) { this.sName = sName; } public String getsGender() { return sGender; } @@ -65,6 +68,22 @@ public class StudentCreateDTO implements Serializable public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } + public Integer getDutyLevel() { + return dutyLevel; + } + + public void setDutyLevel(Integer dutyLevel) { + this.dutyLevel = dutyLevel; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + @Override public String toString() { diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/StudentUpdateDTO.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/StudentUpdateDTO.java new file mode 100644 index 000000000..b0bfb97ca --- /dev/null +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/dto/StudentUpdateDTO.java @@ -0,0 +1,36 @@ +package com.ruoyi.train.domain.dto; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +/** + * 学员手工修改请求。 + * + *

复用 {@link StudentCreateDTO} 的可编辑字段与校验规则,额外要求携带学员主键 sId。 + * 身份证号沿用「只写不读」策略:未提交时保留库内既有密文,不做清空。

+ */ +public class StudentUpdateDTO extends StudentCreateDTO +{ + private static final long serialVersionUID = 1L; + + @NotBlank(message = "学员ID不能为空") + @Size(max = 64, message = "学员ID长度不能超过64个字符") + private String sId; + + public String getsId() + { + return sId; + } + + public void setsId(String sId) + { + this.sId = sId; + } + + @Override + public String toString() + { + return "StudentUpdateDTO{sId='" + sId + "', sName='" + getsName() + + "', idCardProvided=" + (getIdCard() != null) + "}"; + } +} diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/ClassroomDetailVO.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/ClassroomDetailVO.java index 32e35ce66..d389575c1 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/ClassroomDetailVO.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/ClassroomDetailVO.java @@ -40,6 +40,12 @@ public class ClassroomDetailVO implements Serializable @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; + private String seatArrange; + + private Integer multimedia; + + private Integer projector; + public String getClassRoomId() { return classRoomId; @@ -119,4 +125,28 @@ public class ClassroomDetailVO implements Serializable { this.createTime = createTime; } + + public String getSeatArrange() { + return seatArrange; + } + + public void setSeatArrange(String seatArrange) { + this.seatArrange = seatArrange; + } + + public Integer getMultimedia() { + return multimedia; + } + + public void setMultimedia(Integer multimedia) { + this.multimedia = multimedia; + } + + public Integer getProjector() { + return projector; + } + + public void setProjector(Integer projector) { + this.projector = projector; + } } diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/CourseDetailVO.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/CourseDetailVO.java index c6c04d6bf..be46a95e6 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/CourseDetailVO.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/CourseDetailVO.java @@ -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 getResources() { return resources; diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/SiteDetailVO.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/SiteDetailVO.java index 082eb7b49..bfe3b6111 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/SiteDetailVO.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/SiteDetailVO.java @@ -38,6 +38,10 @@ public class SiteDetailVO implements Serializable @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; + private String seatArrange; + + private String major; + public String getSiteId() { return siteId; @@ -117,4 +121,20 @@ public class SiteDetailVO implements Serializable { this.createTime = createTime; } + + public String getSeatArrange() { + return seatArrange; + } + + public void setSeatArrange(String seatArrange) { + this.seatArrange = seatArrange; + } + + public String getMajor() { + return major; + } + + public void setMajor(String major) { + this.major = major; + } } diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/StudentDetailVO.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/StudentDetailVO.java index f2b390858..ad36e7334 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/StudentDetailVO.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/StudentDetailVO.java @@ -14,6 +14,10 @@ public class StudentDetailVO extends StudentItemVO @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; + private Integer dutyLevel; + + private String avatar; + public String getFaceRef() { return faceRef; } public void setFaceRef(String faceRef) { this.faceRef = faceRef; } public String getRemark() { return remark; } @@ -22,4 +26,20 @@ public class StudentDetailVO extends StudentItemVO public void setCreateBy(String createBy) { this.createBy = createBy; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } + + public Integer getDutyLevel() { + return dutyLevel; + } + + public void setDutyLevel(Integer dutyLevel) { + this.dutyLevel = dutyLevel; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } } diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/StudentItemVO.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/StudentItemVO.java index afe69246e..62ed8fee2 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/StudentItemVO.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/vo/StudentItemVO.java @@ -22,6 +22,10 @@ public class StudentItemVO implements Serializable private Integer sourceType; private Integer status; + private String avatar; + + private Integer dutyLevel; + public String getsId() { return sId; } public void setsId(String sId) { this.sId = sId; } public String getsName() { return sName; } @@ -44,4 +48,20 @@ public class StudentItemVO implements Serializable public void setSourceType(Integer sourceType) { this.sourceType = sourceType; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public Integer getDutyLevel() { + return dutyLevel; + } + + public void setDutyLevel(Integer dutyLevel) { + this.dutyLevel = dutyLevel; + } } diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/mapper/TrainResourceMapper.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/mapper/TrainResourceMapper.java new file mode 100644 index 000000000..ba97c2ab8 --- /dev/null +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/mapper/TrainResourceMapper.java @@ -0,0 +1,60 @@ +package com.ruoyi.train.mapper; + +import java.util.List; +import com.ruoyi.train.domain.TrainResource; + +/** + * 教学资源Mapper接口 + * + * @author ruoyi + */ +public interface TrainResourceMapper +{ + /** + * 查询教学资源 + * + * @param resourceId 教学资源主键 + * @return 教学资源 + */ + public TrainResource selectTrainResourceByResourceId(String resourceId); + + /** + * 查询教学资源列表 + * + * @param trainResource 教学资源查询条件 + * @return 教学资源集合 + */ + public List selectTrainResourceList(TrainResource trainResource); + + /** + * 新增教学资源 + * + * @param trainResource 教学资源 + * @return 结果 + */ + public int insertTrainResource(TrainResource trainResource); + + /** + * 修改教学资源 + * + * @param trainResource 教学资源 + * @return 结果 + */ + public int updateTrainResource(TrainResource trainResource); + + /** + * 删除教学资源(逻辑删除) + * + * @param resourceId 教学资源主键 + * @return 结果 + */ + public int deleteTrainResourceByResourceId(String resourceId); + + /** + * 批量删除教学资源(逻辑删除) + * + * @param resourceIds 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteTrainResourceByResourceIds(String[] resourceIds); +} diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/mapper/TrainStudentMapper.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/mapper/TrainStudentMapper.java index 6112ae3f7..9e0476ef3 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/mapper/TrainStudentMapper.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/mapper/TrainStudentMapper.java @@ -18,6 +18,14 @@ public interface TrainStudentMapper int insertTrainStudent(TrainStudent trainStudent); + /** + * 修改学员主档(仅更新非空字段,身份信息随身份证变更同步刷新) + * + * @param trainStudent 学员信息(必须携带 sId) + * @return 影响行数 + */ + int updateTrainStudent(TrainStudent trainStudent); + /** * 根据系统用户ID查询学员信息 (del_flag = '0') * diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/ITrainResourceService.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/ITrainResourceService.java new file mode 100644 index 000000000..b7f0e43e5 --- /dev/null +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/ITrainResourceService.java @@ -0,0 +1,60 @@ +package com.ruoyi.train.service; + +import java.util.List; +import com.ruoyi.train.domain.TrainResource; + +/** + * 教学资源Service接口 + * + * @author ruoyi + */ +public interface ITrainResourceService +{ + /** + * 查询教学资源 + * + * @param resourceId 教学资源主键 + * @return 教学资源 + */ + public TrainResource selectTrainResourceByResourceId(String resourceId); + + /** + * 查询教学资源列表 + * + * @param trainResource 教学资源查询条件 + * @return 教学资源集合 + */ + public List selectTrainResourceList(TrainResource trainResource); + + /** + * 新增教学资源 + * + * @param trainResource 教学资源 + * @return 结果 + */ + public int insertTrainResource(TrainResource trainResource); + + /** + * 修改教学资源 + * + * @param trainResource 教学资源 + * @return 结果 + */ + public int updateTrainResource(TrainResource trainResource); + + /** + * 批量删除教学资源 + * + * @param resourceIds 需要删除的教学资源主键集合 + * @return 结果 + */ + public int deleteTrainResourceByResourceIds(String[] resourceIds); + + /** + * 删除教学资源信息 + * + * @param resourceId 教学资源主键 + * @return 结果 + */ + public int deleteTrainResourceByResourceId(String resourceId); +} diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/ITrainStudentService.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/ITrainStudentService.java index a3eb6fdff..e4ebb9b55 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/ITrainStudentService.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/ITrainStudentService.java @@ -2,6 +2,7 @@ package com.ruoyi.train.service; import java.util.List; import com.ruoyi.train.domain.dto.StudentCreateDTO; +import com.ruoyi.train.domain.dto.StudentUpdateDTO; import com.ruoyi.train.domain.query.StudentQuery; import com.ruoyi.train.domain.vo.StudentDetailVO; import com.ruoyi.train.domain.vo.StudentItemVO; @@ -15,6 +16,14 @@ public interface ITrainStudentService String createStudent(StudentCreateDTO dto); + /** + * 修改学员主档 + * + * @param dto 学员修改请求(携带 sId) + * @return 学员主档ID + */ + String updateTrainStudent(StudentUpdateDTO dto); + /** * 安全删除学员档案(ZERO-REFERENCE SAFE DELETE) * diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainClassroomInfoServiceImpl.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainClassroomInfoServiceImpl.java index 468ef08ef..0c6357bd1 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainClassroomInfoServiceImpl.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainClassroomInfoServiceImpl.java @@ -57,6 +57,9 @@ public class TrainClassroomInfoServiceImpl implements ITrainClassroomInfoService vo.setRoomStatus(classroom.getRoomStatus()); vo.setRemark(classroom.getRemark()); vo.setCreateTime(classroom.getCreateTime()); + vo.setSeatArrange(classroom.getSeatArrange()); + vo.setMultimedia(classroom.getMultimedia()); + vo.setProjector(classroom.getProjector()); // 按 bind_classroom_id 查询绑定的电子班牌(0..N),映射为轻量摘要 VO,无绑定时返回空列表 [] TrainElectronicBoard boardQuery = new TrainElectronicBoard(); diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainResourceServiceImpl.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainResourceServiceImpl.java new file mode 100644 index 000000000..7d4a2816d --- /dev/null +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainResourceServiceImpl.java @@ -0,0 +1,159 @@ +package com.ruoyi.train.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.uuid.IdUtils; +import com.ruoyi.train.domain.TrainResource; +import com.ruoyi.train.mapper.TrainResourceMapper; +import com.ruoyi.train.service.ITrainResourceService; + +/** + * 教学资源Service业务层处理 + * + *

资源表被 train_course_resource、train_study_duration 外键引用, + * 因此删除统一使用逻辑删除(del_flag = '2'),禁止物理删除。

+ * + * @author ruoyi + */ +@Service +public class TrainResourceServiceImpl implements ITrainResourceService +{ + @Autowired + private TrainResourceMapper trainResourceMapper; + + /** + * 查询教学资源 + * + * @param resourceId 教学资源主键 + * @return 教学资源 + */ + @Override + public TrainResource selectTrainResourceByResourceId(String resourceId) + { + return trainResourceMapper.selectTrainResourceByResourceId(resourceId); + } + + /** + * 查询教学资源列表 + * + * @param trainResource 教学资源查询条件 + * @return 教学资源集合 + */ + @Override + public List selectTrainResourceList(TrainResource trainResource) + { + return trainResourceMapper.selectTrainResourceList(trainResource); + } + + /** + * 新增教学资源 + * + * @param trainResource 教学资源 + * @return 结果 + */ + @Override + public int insertTrainResource(TrainResource trainResource) + { + validateResourceType(trainResource.getResourceType()); + validateStatus(trainResource.getStatus()); + // 未指定主键时自动生成32位UUID,与 resource_id VARCHAR(32) 对齐 + if (StringUtils.isEmpty(trainResource.getResourceId())) + { + trainResource.setResourceId(IdUtils.fastSimpleUUID()); + } + if (trainResource.getStatus() == null) + { + trainResource.setStatus(1); // 默认正常 + } + trainResource.setDelFlag("0"); + trainResource.setCreateTime(DateUtils.getNowDate()); + return trainResourceMapper.insertTrainResource(trainResource); + } + + /** + * 修改教学资源 + * + * @param trainResource 教学资源(必须携带 resourceId) + * @return 结果 + */ + @Override + public int updateTrainResource(TrainResource trainResource) + { + if (StringUtils.isEmpty(trainResource.getResourceId())) + { + throw new ServiceException("资源ID不能为空"); + } + if (trainResource.getResourceType() != null) + { + validateResourceType(trainResource.getResourceType()); + } + if (trainResource.getStatus() != null) + { + validateStatus(trainResource.getStatus()); + } + trainResource.setUpdateTime(DateUtils.getNowDate()); + return trainResourceMapper.updateTrainResource(trainResource); + } + + /** + * 批量删除教学资源 + * + * @param resourceIds 需要删除的教学资源主键集合 + * @return 结果 + */ + @Override + public int deleteTrainResourceByResourceIds(String[] resourceIds) + { + if (resourceIds == null || resourceIds.length == 0) + { + throw new ServiceException("请选择要删除的资源"); + } + return trainResourceMapper.deleteTrainResourceByResourceIds(resourceIds); + } + + /** + * 删除教学资源信息 + * + * @param resourceId 教学资源主键 + * @return 结果 + */ + @Override + public int deleteTrainResourceByResourceId(String resourceId) + { + if (StringUtils.isEmpty(resourceId)) + { + throw new ServiceException("资源ID不能为空"); + } + return trainResourceMapper.deleteTrainResourceByResourceId(resourceId); + } + + /** + * 校验资源类型取值:1文档 2视频 33D模型 4VR资源 5外部教学链接 6其他 + */ + private void validateResourceType(Integer resourceType) + { + if (resourceType == null) + { + throw new ServiceException("资源类型不能为空"); + } + if (resourceType < 1 || resourceType > 6) + { + throw new ServiceException("资源类型取值必须为1-6"); + } + } + + /** + * 校验状态取值:0停用 1正常 + */ + private void validateStatus(Integer status) + { + if (status != null && status != 0 && status != 1) + { + throw new ServiceException("资源状态取值必须为0或1"); + } + } +} diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainStudentServiceImpl.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainStudentServiceImpl.java index 385c1fcda..b7f6bb278 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainStudentServiceImpl.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainStudentServiceImpl.java @@ -13,6 +13,7 @@ import com.ruoyi.common.utils.uuid.IdUtils; import com.ruoyi.train.constant.StudentErrorCode; import com.ruoyi.train.domain.TrainStudent; import com.ruoyi.train.domain.dto.StudentCreateDTO; +import com.ruoyi.train.domain.dto.StudentUpdateDTO; import com.ruoyi.train.domain.query.StudentQuery; import com.ruoyi.train.domain.vo.StudentDetailVO; import com.ruoyi.train.domain.vo.StudentItemVO; @@ -99,6 +100,8 @@ public class TrainStudentServiceImpl implements ITrainStudentService student.setOrgName(trimToNull(dto.getOrgName())); student.setsPhone(trimToNull(dto.getsPhone())); student.setsEmail(trimToNull(dto.getsEmail())); + student.setAvatar(trimToNull(dto.getAvatar())); + student.setDutyLevel(dto.getDutyLevel()); if (normalizedIdCard != null) { @@ -144,6 +147,93 @@ public class TrainStudentServiceImpl implements ITrainStudentService return student.getsId(); } + /** + * 修改学员主档信息。 + * + *

与 createStudent 保持完全一致的安全语义:姓名必填、身份证格式校验、 + * 身份证以可逆密文 + 冻结查重哈希落库、末四位仅用于脱敏展示。差异点:

+ *
    + *
  • 身份证未提供时保留库内既有密文,避免误清空已归档的身份信息;
  • + *
  • 身份证变更时才做全局查重,哈希未变化视为本人,不做重复判定;
  • + *
  • userId / sourceType / status / delFlag 不属于编辑范围,一律不覆盖。
  • + *
+ * + * @param dto 学员修改请求(携带 sId) + * @return 学员主档ID + */ + @Override + @Transactional(rollbackFor = Exception.class) + public String updateTrainStudent(StudentUpdateDTO dto) + { + if (dto == null || StringUtils.isEmpty(dto.getsId())) + { + throw new ServiceException("学员ID不能为空"); + } + validate(dto); + + TrainStudent existing = trainStudentMapper.selectTrainStudentBySId(dto.getsId()); + if (existing == null) + { + throw new ServiceException(StudentErrorCode.STUDENT_NOT_FOUND_MESSAGE, + StudentErrorCode.STUDENT_NOT_FOUND); + } + + TrainStudent student = new TrainStudent(); + student.setsId(existing.getsId()); + student.setsName(dto.getsName().trim()); + student.setsGender(trimToNull(dto.getsGender())); + student.setsBirth(dto.getsBirth()); + student.setOrgName(trimToNull(dto.getOrgName())); + student.setsPhone(trimToNull(dto.getsPhone())); + student.setsEmail(trimToNull(dto.getsEmail())); + student.setAvatar(trimToNull(dto.getAvatar())); + student.setFaceRef(trimToNull(dto.getFaceRef())); + student.setDutyLevel(dto.getDutyLevel()); + student.setRemark(trimToNull(dto.getRemark())); + + String normalizedIdCard = normalizeIdCard(dto.getIdCard()); + if (normalizedIdCard != null) + { + String hash = identityProtection.deterministicHash(normalizedIdCard); + // 哈希未变化说明仍是同一人,只有真正变更身份证时才需要全局查重 + if (!hash.equals(existing.getIdCardHash()) + && trainStudentMapper.selectOneByIdCardHash(hash) != null) + { + throw duplicateIdentity(); + } + student.setIdCardCiphertext(identityProtection.encrypt(normalizedIdCard)); + student.setIdCardHash(hash); + student.setIdCardLast4(normalizedIdCard.substring(normalizedIdCard.length() - 4)); + } + else + { + student.setIdCardCiphertext(existing.getIdCardCiphertext()); + student.setIdCardHash(existing.getIdCardHash()); + student.setIdCardLast4(existing.getIdCardLast4()); + } + + student.setUpdateTime(DateUtils.getNowDate()); + try + { + student.setUpdateBy(SecurityUtils.getUsername()); + } + catch (Exception ignored) + { + // 非 Web 单元测试无登录上下文;不使用任何请求数据作为审计用户兜底。 + } + + try + { + trainStudentMapper.updateTrainStudent(student); + } + catch (DuplicateKeyException e) + { + // 应用层预检之外,数据库唯一约束继续封堵并发重复身份证。 + throw duplicateIdentity(); + } + return student.getsId(); + } + private StudentItemVO toItemVO(TrainStudent student) { StudentItemVO item = new StudentItemVO(); @@ -164,6 +254,8 @@ public class TrainStudentServiceImpl implements ITrainStudentService target.setIdCardMasked(maskStoredIdentity(student)); target.setSourceType(student.getSourceType()); target.setStatus(student.getStatus()); + target.setAvatar(student.getAvatar()); + target.setDutyLevel(student.getDutyLevel()); } private String maskStoredIdentity(TrainStudent student) diff --git a/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainClassroomInfoMapper.xml b/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainClassroomInfoMapper.xml index 4dcfe990f..bb9d540fa 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainClassroomInfoMapper.xml +++ b/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainClassroomInfoMapper.xml @@ -16,19 +16,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + - select class_room_id, room_name, room_location, capacity, room_status, del_flag, create_by, create_time, update_by, update_time, remark from train_classroom_info + select class_room_id, room_name, room_location, capacity, room_status, del_flag, create_by, create_time, update_by, update_time, remark, seat_arrange, multimedia, projector from train_classroom_info @@ -61,6 +66,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update_by, update_time, remark, + seat_arrange, + multimedia, + projector, #{classRoomId}, @@ -74,6 +82,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{updateBy}, #{updateTime}, #{remark}, + #{seatArrange}, + #{multimedia}, + #{projector}, @@ -88,6 +99,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update_by = #{updateBy}, update_time = #{updateTime}, remark = #{remark}, + seat_arrange = #{seatArrange}, + multimedia = #{multimedia}, + projector = #{projector}, where class_room_id = #{classRoomId} diff --git a/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainCourseMapper.xml b/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainCourseMapper.xml index 5a0db4dce..51d6b1f5a 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainCourseMapper.xml +++ b/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainCourseMapper.xml @@ -12,6 +12,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -22,7 +23,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - 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 + + where del_flag = '0' + and resource_name like concat('%', #{resourceName}, '%') + and resource_type = #{resourceType} + and resource_url like concat('%', #{resourceUrl}, '%') + and description like concat('%', #{description}, '%') + and status = #{status} + and create_by = #{createBy} + and create_time >= #{params.beginTime} + and create_time <= #{params.endTime} + order by create_time desc + + + + + + insert into train_resource + + resource_id, + resource_name, + resource_type, + resource_url, + description, + status, + del_flag, + create_by, + create_time, + update_by, + update_time, + remark, + + + #{resourceId}, + #{resourceName}, + #{resourceType}, + #{resourceUrl}, + #{description}, + #{status}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{remark}, + + + + + update train_resource + + resource_name = #{resourceName}, + resource_type = #{resourceType}, + resource_url = #{resourceUrl}, + description = #{description}, + status = #{status}, + del_flag = #{delFlag}, + update_by = #{updateBy}, + update_time = #{updateTime}, + remark = #{remark}, + + where resource_id = #{resourceId} and del_flag = '0' + + + + update train_resource set del_flag = '2' where resource_id = #{resourceId} + + + + update train_resource set del_flag = '2' where resource_id in + + #{resourceId} + + + diff --git a/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainStudentMapper.xml b/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainStudentMapper.xml index 825a4d715..459cdcae9 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainStudentMapper.xml +++ b/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainStudentMapper.xml @@ -25,12 +25,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + select s_id, s_name, s_gender, s_birth, user_id, org_name, s_phone, s_email, id_card_ciphertext, id_card_hash, id_card_last4, face_ref, source_type, - status, create_by, create_time, update_by, update_time, remark, del_flag + status, create_by, create_time, update_by, update_time, remark, del_flag, + avatar, duty_level from train_student @@ -77,14 +80,39 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" insert into train_student ( s_id, s_name, s_gender, s_birth, user_id, org_name, s_phone, s_email, id_card_ciphertext, id_card_hash, id_card_last4, face_ref, source_type, - status, create_by, create_time, update_by, update_time, remark, del_flag + status, create_by, create_time, update_by, update_time, remark, del_flag, + avatar, duty_level ) values ( #{sId}, #{sName}, #{sGender}, #{sBirth}, #{userId}, #{orgName}, #{sPhone}, #{sEmail}, #{idCardCiphertext}, #{idCardHash}, #{idCardLast4}, #{faceRef}, #{sourceType}, - #{status}, #{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{remark}, #{delFlag} + #{status}, #{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{remark}, #{delFlag}, + #{avatar}, #{dutyLevel} ) + + + update train_student + + s_name = #{sName}, + s_gender = #{sGender}, + s_birth = #{sBirth}, + org_name = #{orgName}, + s_phone = #{sPhone}, + s_email = #{sEmail}, + id_card_ciphertext = #{idCardCiphertext}, + id_card_hash = #{idCardHash}, + id_card_last4 = #{idCardLast4}, + face_ref = #{faceRef}, + avatar = #{avatar}, + duty_level = #{dutyLevel}, + remark = #{remark}, + update_time = #{updateTime}, + update_by = #{updateBy} + + where s_id = #{sId} and del_flag = '0' + + @@ -39,6 +43,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and t_phone like concat('%', #{tPhone}, '%') and t_email = #{tEmail} and status = #{status} + and major like concat('%', #{major}, '%') + and courses like concat('%', #{courses}, '%') order by create_time desc @@ -72,6 +78,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update_by, update_time, remark, + avatar, + major, + courses, + start_teaching, #{tId}, @@ -90,6 +100,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{updateBy}, #{updateTime}, #{remark}, + #{avatar}, + #{major}, + #{courses}, + #{startTeaching}, @@ -108,6 +122,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update_by = #{updateBy}, update_time = #{updateTime}, remark = #{remark}, + avatar = #{avatar}, + major = #{major}, + courses = #{courses}, + start_teaching = #{startTeaching}, where t_id = #{tId} and del_flag = '0' diff --git a/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainTrainingSiteMapper.xml b/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainTrainingSiteMapper.xml index 12a52116c..4646c43f9 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainTrainingSiteMapper.xml +++ b/RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/TrainTrainingSiteMapper.xml @@ -17,20 +17,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + - select site_id, site_name, site_location, capacity, site_device, site_status, del_flag, create_by, create_time, update_by, update_time, remark from train_training_site + select site_id, site_name, site_location, capacity, site_device, site_status, del_flag, create_by, create_time, update_by, update_time, remark, major, seat_arrange from train_training_site @@ -64,6 +67,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update_by, update_time, remark, + major, + seat_arrange, #{siteId}, @@ -78,6 +83,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{updateBy}, #{updateTime}, #{remark}, + #{major}, + #{seatArrange}, @@ -93,6 +100,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update_by = #{updateBy}, update_time = #{updateTime}, remark = #{remark}, + major = #{major}, + seat_arrange = #{seatArrange}, where site_id = #{siteId} diff --git a/build_ui/src/api/system/user.js b/build_ui/src/api/system/user.js index f2f76ef9f..7a3d5e763 100644 --- a/build_ui/src/api/system/user.js +++ b/build_ui/src/api/system/user.js @@ -96,7 +96,7 @@ export function updateUserPwd(oldPassword, newPassword) { return request({ url: '/system/user/profile/updatePwd', method: 'put', - params: data + data: data }) } diff --git a/build_ui/src/api/train/resource.js b/build_ui/src/api/train/resource.js new file mode 100644 index 000000000..7bc49879d --- /dev/null +++ b/build_ui/src/api/train/resource.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询教学资源列表 +export function listResource(query) { + return request({ + url: '/train/resource/list', + method: 'get', + params: query + }) +} + +// 查询教学资源详细 +export function getResource(resourceId) { + return request({ + url: '/train/resource/' + resourceId, + method: 'get' + }) +} + +// 新增教学资源 +export function addResource(data) { + return request({ + url: '/train/resource', + method: 'post', + data: data + }) +} + +// 修改教学资源 +export function updateResource(data) { + return request({ + url: '/train/resource/' + data.resourceId, + method: 'put', + data: data + }) +} + +// 删除教学资源 +export function delResource(resourceId) { + return request({ + url: '/train/resource/' + resourceId, + method: 'delete' + }) +} diff --git a/build_ui/src/api/train/site.js b/build_ui/src/api/train/site.js index e2e38964e..7f3dbfeb5 100644 --- a/build_ui/src/api/train/site.js +++ b/build_ui/src/api/train/site.js @@ -26,6 +26,14 @@ export function addSite(data) { }) } +// 删除实训场地 +export function delSite(ids) { + return request({ + url: '/train/training-site/' + ids, + method: 'delete' + }) +} + // 修改实训场地 export function updateSite(data) { return request({ diff --git a/build_ui/src/api/train/student.js b/build_ui/src/api/train/student.js index ceb9d9fda..3a643c16e 100644 --- a/build_ui/src/api/train/student.js +++ b/build_ui/src/api/train/student.js @@ -26,6 +26,15 @@ export function addStudent(data) { }) } +// 修改教师信息 +export function updateStudent(data) { + return request({ + url: '/train/student/' + (data.sId || ''), + method: 'put', + data: data + }) +} + // 查询可关联学员的系统用户候选列表 export function getStudentBindableUsers(keyword) { return request({ diff --git a/build_ui/src/views/train/classroom/index.vue b/build_ui/src/views/train/classroom/index.vue index 86f3b04e1..a764dc366 100644 --- a/build_ui/src/views/train/classroom/index.vue +++ b/build_ui/src/views/train/classroom/index.vue @@ -1,6 +1,6 @@ - + + + + + + + - diff --git a/build_ui/src/views/train/student/studentAvatar.vue b/build_ui/src/views/train/student/studentAvatar.vue new file mode 100644 index 000000000..8c803f6e1 --- /dev/null +++ b/build_ui/src/views/train/student/studentAvatar.vue @@ -0,0 +1,233 @@ + + + + diff --git a/build_ui/src/views/train/teacher/index.vue b/build_ui/src/views/train/teacher/index.vue index 19a2395cc..978694e2c 100644 --- a/build_ui/src/views/train/teacher/index.vue +++ b/build_ui/src/views/train/teacher/index.vue @@ -10,12 +10,13 @@ /> - + />--> + - + + + + + + + @@ -72,21 +89,37 @@ + + + - + - - + + + - +