增加学员修改逻辑
This commit is contained in:
1 parent
9d6689569c
commit
ad533c55fb
5 files changed
+165
-7
No files matched your search
+34
-7
@@ -1,15 +1,13 @@
|
||||
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 com.ruoyi.train.domain.TrainTeacher;
|
||||
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 +16,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 +29,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 +77,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 +105,9 @@ public class TrainStudentController extends BaseController
|
||||
{
|
||||
return toAjax(trainStudentService.deleteTrainStudentBySId(sId));
|
||||
}
|
||||
|
||||
private boolean isValidPhone(String phone)
|
||||
{
|
||||
return PHONE_PATTERN.matcher(phone).matches();
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,14 @@ public interface TrainStudentMapper
|
||||
|
||||
int insertTrainStudent(TrainStudent trainStudent);
|
||||
|
||||
/**
|
||||
* 修改学员主档(仅更新非空字段,身份信息随身份证变更同步刷新)
|
||||
*
|
||||
* @param trainStudent 学员信息(必须携带 sId)
|
||||
* @return 影响行数
|
||||
*/
|
||||
int updateTrainStudent(TrainStudent trainStudent);
|
||||
|
||||
/**
|
||||
* 根据系统用户ID查询学员信息 (del_flag = '0')
|
||||
*
|
||||
|
||||
@@ -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)
|
||||
*
|
||||
|
||||
+91
@@ -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,7 @@ 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()));
|
||||
|
||||
if (normalizedIdCard != null)
|
||||
{
|
||||
@@ -144,6 +146,93 @@ public class TrainStudentServiceImpl implements ITrainStudentService
|
||||
return student.getsId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改学员主档信息。
|
||||
*
|
||||
* <p>与 createStudent 保持完全一致的安全语义:姓名必填、身份证格式校验、
|
||||
* 身份证以可逆密文 + 冻结查重哈希落库、末四位仅用于脱敏展示。差异点:</p>
|
||||
* <ul>
|
||||
* <li>身份证未提供时保留库内既有密文,避免误清空已归档的身份信息;</li>
|
||||
* <li>身份证变更时才做全局查重,哈希未变化视为本人,不做重复判定;</li>
|
||||
* <li>userId / sourceType / status / delFlag 不属于编辑范围,一律不覆盖。</li>
|
||||
* </ul>
|
||||
*
|
||||
* @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 +253,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)
|
||||
|
||||
@@ -90,6 +90,29 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
)
|
||||
</insert>
|
||||
|
||||
<!-- 修改学员主档:仅覆盖传入的非空字段,userId/sourceType/status/delFlag 不在编辑范围 -->
|
||||
<update id="updateTrainStudent" parameterType="TrainStudent">
|
||||
update train_student
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="sName != null">s_name = #{sName},</if>
|
||||
<if test="sGender != null">s_gender = #{sGender},</if>
|
||||
<if test="sBirth != null">s_birth = #{sBirth},</if>
|
||||
<if test="orgName != null">org_name = #{orgName},</if>
|
||||
<if test="sPhone != null">s_phone = #{sPhone},</if>
|
||||
<if test="sEmail != null">s_email = #{sEmail},</if>
|
||||
<if test="idCardCiphertext != null">id_card_ciphertext = #{idCardCiphertext},</if>
|
||||
<if test="idCardHash != null">id_card_hash = #{idCardHash},</if>
|
||||
<if test="idCardLast4 != null">id_card_last4 = #{idCardLast4},</if>
|
||||
<if test="faceRef != null">face_ref = #{faceRef},</if>
|
||||
<if test="avatar != null">avatar = #{avatar},</if>
|
||||
<if test="dutyLevel != null">duty_level = #{dutyLevel},</if>
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
update_time = #{updateTime},
|
||||
update_by = #{updateBy}
|
||||
</trim>
|
||||
where s_id = #{sId} and del_flag = '0'
|
||||
</update>
|
||||
|
||||
<!-- 根据系统用户ID查询学员 (仅限未删除 del_flag = '0') -->
|
||||
<select id="selectTrainStudentByUserId" parameterType="Long" resultMap="TrainStudentResult">
|
||||
<include refid="selectTrainStudentDomain" />
|
||||
|
||||
Reference in new issue
Block a user