增加量表权限发布一次可作答一次

This commit is contained in:
xiao12feng8 2025-12-22 13:50:50 +08:00
parent b08a3a2ee2
commit b549cacc04
13 changed files with 353 additions and 64 deletions

View File

@ -36,6 +36,7 @@ import com.ddnai.system.domain.psychology.vo.UserAssessmentSummaryVO;
import com.ddnai.system.service.psychology.IPsyAssessmentService; import com.ddnai.system.service.psychology.IPsyAssessmentService;
import com.ddnai.system.service.psychology.IPsyAssessmentAnswerService; import com.ddnai.system.service.psychology.IPsyAssessmentAnswerService;
import com.ddnai.system.service.psychology.IPsyScaleItemService; import com.ddnai.system.service.psychology.IPsyScaleItemService;
import com.ddnai.system.service.psychology.IPsyScalePermissionService;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
@ -59,6 +60,9 @@ public class PsyAssessmentController extends BaseController
@Autowired @Autowired
private com.ddnai.system.service.psychology.IPsyAssessmentReportService reportService; private com.ddnai.system.service.psychology.IPsyAssessmentReportService reportService;
@Autowired
private IPsyScalePermissionService permissionService;
/** /**
* 获取测评列表 * 获取测评列表
*/ */
@ -209,11 +213,24 @@ public class PsyAssessmentController extends BaseController
// 检查是否已存在该用户对该量表的测评记录 // 检查是否已存在该用户对该量表的测评记录
if (assessmentUserId != null && startVO.getScaleId() != null) if (assessmentUserId != null && startVO.getScaleId() != null)
{ {
Integer currentPublishNo = null;
try {
currentPublishNo = permissionService.selectCurrentPublishNoForUserScale(assessmentUserId, startVO.getScaleId());
} catch (Exception ignored) {}
if (currentPublishNo == null) {
currentPublishNo = 1;
}
// 使用不过滤的查询方法获取所有测评记录 // 使用不过滤的查询方法获取所有测评记录
List<PsyAssessment> existingList = assessmentService.selectAssessmentByUserAndScale(assessmentUserId, startVO.getScaleId()); List<PsyAssessment> existingList = assessmentService.selectAssessmentByUserAndScale(assessmentUserId, startVO.getScaleId());
for (PsyAssessment existing : existingList) for (PsyAssessment existing : existingList)
{ {
Integer existingPublishNo = existing.getPublishNo() != null ? existing.getPublishNo() : 1;
if (!existingPublishNo.equals(currentPublishNo)) {
continue;
}
// 检查是否已完成状态为1如果已完成则不允许再次测评 // 检查是否已完成状态为1如果已完成则不允许再次测评
if ("1".equals(existing.getStatus())) if ("1".equals(existing.getStatus()))
{ {
@ -239,6 +256,13 @@ public class PsyAssessmentController extends BaseController
// 初始状态为"已暂停"等用户真正进入答题页面后再改为"进行中" // 初始状态为"已暂停"等用户真正进入答题页面后再改为"进行中"
PsyAssessment assessment = new PsyAssessment(); PsyAssessment assessment = new PsyAssessment();
assessment.setScaleId(startVO.getScaleId()); assessment.setScaleId(startVO.getScaleId());
Integer publishNo = null;
try {
if (assessmentUserId != null && startVO.getScaleId() != null) {
publishNo = permissionService.selectCurrentPublishNoForUserScale(assessmentUserId, startVO.getScaleId());
}
} catch (Exception ignored) {}
assessment.setPublishNo(publishNo != null ? publishNo : 1);
assessment.setAssesseeName(startVO.getAssesseeName()); assessment.setAssesseeName(startVO.getAssesseeName());
assessment.setAssesseeGender(startVO.getAssesseeGender()); assessment.setAssesseeGender(startVO.getAssesseeGender());
assessment.setAssesseeAge(startVO.getAssesseeAge()); assessment.setAssesseeAge(startVO.getAssesseeAge());

View File

@ -824,7 +824,20 @@ public class PsyAssessmentReportController extends BaseController
ReportExportVO exportVO = new ReportExportVO(); ReportExportVO exportVO = new ReportExportVO();
exportVO.setReportId(r.getReportId()); exportVO.setReportId(r.getReportId());
exportVO.setAssessmentId(r.getAssessmentId()); exportVO.setAssessmentId(r.getAssessmentId());
exportVO.setReportTitle(r.getReportTitle()); String title = r.getReportTitle();
Integer attemptNo = null;
try {
attemptNo = calcAttemptNoByAssessmentId(r.getAssessmentId());
} catch (Exception ignored) {}
if (attemptNo != null && attemptNo > 0)
{
if (title == null)
{
title = "";
}
title = title + "(次数" + attemptNo + ")";
}
exportVO.setReportTitle(title);
exportVO.setReportType(r.getReportType()); exportVO.setReportType(r.getReportType());
exportVO.setSummary(r.getSummary()); exportVO.setSummary(r.getSummary());
exportVO.setIsGenerated(r.getIsGenerated()); exportVO.setIsGenerated(r.getIsGenerated());
@ -864,6 +877,53 @@ public class PsyAssessmentReportController extends BaseController
exportReportListAsPdf(exportList, response, fileName); exportReportListAsPdf(exportList, response, fileName);
} }
private Integer calcAttemptNoByAssessmentId(Long assessmentId)
{
if (assessmentId == null)
{
return null;
}
PsyAssessment assessment = assessmentService.selectAssessmentById(assessmentId);
if (assessment == null || assessment.getUserId() == null || assessment.getScaleId() == null)
{
return null;
}
List<PsyAssessment> list = assessmentService.selectAssessmentByUserAndScale(assessment.getUserId(), assessment.getScaleId());
if (list == null || list.isEmpty())
{
return null;
}
java.util.List<PsyAssessment> completed = new java.util.ArrayList<>();
for (PsyAssessment a : list)
{
if (a != null && "1".equals(a.getStatus()))
{
completed.add(a);
}
}
if (completed.isEmpty())
{
return null;
}
completed.sort((a, b) -> {
if (a.getSubmitTime() == null && b.getSubmitTime() == null) return 0;
if (a.getSubmitTime() == null) return 1;
if (b.getSubmitTime() == null) return -1;
return a.getSubmitTime().compareTo(b.getSubmitTime());
});
int idx = 1;
for (PsyAssessment a : completed)
{
if (a.getAssessmentId() != null && a.getAssessmentId().equals(assessmentId))
{
return idx;
}
idx++;
}
return completed.size();
}
/** /**
* 使用 PDFBox 将报告导出为简单的文本 PDF * 使用 PDFBox 将报告导出为简单的文本 PDF
*/ */

View File

@ -33,6 +33,7 @@ import com.ddnai.system.domain.psychology.PsyQuestionnaireAnswerDetail;
import com.ddnai.system.service.psychology.IPsyQuestionnaireService; import com.ddnai.system.service.psychology.IPsyQuestionnaireService;
import com.ddnai.system.service.psychology.IPsyQuestionnaireItemService; import com.ddnai.system.service.psychology.IPsyQuestionnaireItemService;
import com.ddnai.system.service.psychology.IPsyQuestionnaireAnswerService; import com.ddnai.system.service.psychology.IPsyQuestionnaireAnswerService;
import com.ddnai.system.service.psychology.IPsyScalePermissionService;
import com.ddnai.system.service.ISysUserService; import com.ddnai.system.service.ISysUserService;
/** /**
@ -59,6 +60,9 @@ public class PsyQuestionnaireAnswerController extends BaseController
@Autowired @Autowired
private ISysUserService userService; private ISysUserService userService;
@Autowired
private IPsyScalePermissionService permissionService;
/** /**
* 获取问卷答题列表 * 获取问卷答题列表
*/ */
@ -97,9 +101,18 @@ public class PsyQuestionnaireAnswerController extends BaseController
System.out.println("questionnaireId: " + questionnaireId + ", userId: " + userId); System.out.println("questionnaireId: " + questionnaireId + ", userId: " + userId);
System.out.println("========================================"); System.out.println("========================================");
Integer currentPublishNo = null;
try {
currentPublishNo = permissionService.selectCurrentPublishNoForUserScale(userId, -questionnaireId);
} catch (Exception ignored) {}
if (currentPublishNo == null) {
currentPublishNo = 1;
}
// 检查用户是否已完成该问卷 // 检查用户是否已完成该问卷
PsyQuestionnaireAnswer query = new PsyQuestionnaireAnswer(); PsyQuestionnaireAnswer query = new PsyQuestionnaireAnswer();
query.setQuestionnaireId(questionnaireId); query.setQuestionnaireId(questionnaireId);
query.setPublishNo(currentPublishNo);
query.setUserId(userId); query.setUserId(userId);
List<PsyQuestionnaireAnswer> existingList = answerService.selectAnswerList(query); List<PsyQuestionnaireAnswer> existingList = answerService.selectAnswerList(query);
@ -120,6 +133,7 @@ public class PsyQuestionnaireAnswerController extends BaseController
// 没有已完成或进行中的记录创建新的答题记录 // 没有已完成或进行中的记录创建新的答题记录
PsyQuestionnaireAnswer answer = new PsyQuestionnaireAnswer(); PsyQuestionnaireAnswer answer = new PsyQuestionnaireAnswer();
answer.setQuestionnaireId(questionnaireId); answer.setQuestionnaireId(questionnaireId);
answer.setPublishNo(currentPublishNo);
answer.setUserId(userId); answer.setUserId(userId);
answer.setRespondentName(respondentName); answer.setRespondentName(respondentName);
answer.setStatus("0"); // 进行中 answer.setStatus("0"); // 进行中

View File

@ -21,6 +21,8 @@ public class PsyAssessment extends BaseEntity
/** 量表ID */ /** 量表ID */
private Long scaleId; private Long scaleId;
private Integer publishNo;
/** 量表名称(关联查询字段,不存储在表中) */ /** 量表名称(关联查询字段,不存储在表中) */
private String scaleName; private String scaleName;
@ -102,6 +104,16 @@ public class PsyAssessment extends BaseEntity
this.scaleId = scaleId; this.scaleId = scaleId;
} }
public Integer getPublishNo()
{
return publishNo;
}
public void setPublishNo(Integer publishNo)
{
this.publishNo = publishNo;
}
public String getScaleName() public String getScaleName()
{ {
return scaleName; return scaleName;
@ -297,6 +309,7 @@ public class PsyAssessment extends BaseEntity
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("assessmentId", getAssessmentId()) .append("assessmentId", getAssessmentId())
.append("scaleId", getScaleId()) .append("scaleId", getScaleId())
.append("publishNo", getPublishNo())
.append("userId", getUserId()) .append("userId", getUserId())
.append("assesseeName", getAssesseeName()) .append("assesseeName", getAssesseeName())
.append("assesseeGender", getAssesseeGender()) .append("assesseeGender", getAssesseeGender())

View File

@ -21,6 +21,8 @@ public class PsyQuestionnaireAnswer extends BaseEntity
/** 问卷ID */ /** 问卷ID */
private Long questionnaireId; private Long questionnaireId;
private Integer publishNo;
/** 用户ID */ /** 用户ID */
private Long userId; private Long userId;
@ -67,6 +69,16 @@ public class PsyQuestionnaireAnswer extends BaseEntity
this.questionnaireId = questionnaireId; this.questionnaireId = questionnaireId;
} }
public Integer getPublishNo()
{
return publishNo;
}
public void setPublishNo(Integer publishNo)
{
this.publishNo = publishNo;
}
public Long getUserId() public Long getUserId()
{ {
return userId; return userId;
@ -152,6 +164,7 @@ public class PsyQuestionnaireAnswer extends BaseEntity
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("answerId", getAnswerId()) .append("answerId", getAnswerId())
.append("questionnaireId", getQuestionnaireId()) .append("questionnaireId", getQuestionnaireId())
.append("publishNo", getPublishNo())
.append("userId", getUserId()) .append("userId", getUserId())
.append("respondentName", getRespondentName()) .append("respondentName", getRespondentName())
.append("startTime", getStartTime()) .append("startTime", getStartTime())

View File

@ -40,6 +40,8 @@ public class PsyScalePermission extends BaseEntity
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private java.util.Date endTime; private java.util.Date endTime;
private Integer publishNo;
/** 状态0有效 1无效 */ /** 状态0有效 1无效 */
private String status; private String status;
@ -138,6 +140,16 @@ public class PsyScalePermission extends BaseEntity
this.endTime = endTime; this.endTime = endTime;
} }
public Integer getPublishNo()
{
return publishNo;
}
public void setPublishNo(Integer publishNo)
{
this.publishNo = publishNo;
}
public String getStatus() public String getStatus()
{ {
return status; return status;
@ -209,6 +221,7 @@ public class PsyScalePermission extends BaseEntity
.append("className", getClassName()) .append("className", getClassName())
.append("startTime", getStartTime()) .append("startTime", getStartTime())
.append("endTime", getEndTime()) .append("endTime", getEndTime())
.append("publishNo", getPublishNo())
.append("status", getStatus()) .append("status", getStatus())
.append("createBy", getCreateBy()) .append("createBy", getCreateBy())
.append("createTime", getCreateTime()) .append("createTime", getCreateTime())
@ -220,4 +233,3 @@ public class PsyScalePermission extends BaseEntity
.toString(); .toString();
} }
} }

View File

@ -92,6 +92,12 @@ public interface PsyScalePermissionMapper
*/ */
public int deletePermissionByScaleId(Long scaleId); public int deletePermissionByScaleId(Long scaleId);
public Integer selectMaxPublishNo(PsyScalePermission permission);
public int invalidatePermissionByScope(PsyScalePermission permission);
public Integer selectCurrentPublishNoForUserScale(@Param("userId") Long userId, @Param("scaleId") Long scaleId);
/** /**
* 查询所有已配置权限的量表ID * 查询所有已配置权限的量表ID
* *

View File

@ -88,6 +88,12 @@ public class PsyScalePermissionServiceImpl implements IPsyScalePermissionService
return count > 0; return count > 0;
} }
@Override
public Integer selectCurrentPublishNoForUserScale(Long userId, Long scaleId)
{
return permissionMapper.selectCurrentPublishNoForUserScale(userId, scaleId);
}
/** /**
* 新增量表权限 * 新增量表权限
* *
@ -104,37 +110,11 @@ public class PsyScalePermissionServiceImpl implements IPsyScalePermissionService
permission.setStatus("0"); permission.setStatus("0");
} }
// 检查是否已存在相同的权限记录避免重复 Integer maxPublishNo = permissionMapper.selectMaxPublishNo(permission);
PsyScalePermission query = new PsyScalePermission(); int nextPublishNo = (maxPublishNo == null ? 0 : maxPublishNo) + 1;
query.setScaleId(permission.getScaleId()); permission.setPublishNo(nextPublishNo);
query.setUserId(permission.getUserId());
query.setRoleId(permission.getRoleId());
query.setDeptId(permission.getDeptId());
query.setClassName(permission.getClassName());
query.setStatus("0"); // 只检查有效状态的权限
List<PsyScalePermission> existing = permissionMapper.selectPermissionList(query);
if (existing != null && !existing.isEmpty())
{
// 检查是否有完全相同的权限记录除了时间范围
boolean hasDuplicate = existing.stream().anyMatch(p -> {
boolean sameUser = (p.getUserId() == null && permission.getUserId() == null)
|| (p.getUserId() != null && p.getUserId().equals(permission.getUserId()));
boolean sameRole = (p.getRoleId() == null && permission.getRoleId() == null)
|| (p.getRoleId() != null && p.getRoleId().equals(permission.getRoleId()));
boolean sameDept = (p.getDeptId() == null && permission.getDeptId() == null)
|| (p.getDeptId() != null && p.getDeptId().equals(permission.getDeptId()));
boolean sameClass = (p.getClassName() == null && permission.getClassName() == null)
|| (p.getClassName() != null && p.getClassName().equals(permission.getClassName()));
return sameUser && sameRole && sameDept && sameClass;
});
if (hasDuplicate)
{
throw new RuntimeException("该权限已存在,请勿重复添加");
}
}
permissionMapper.invalidatePermissionByScope(permission);
return permissionMapper.insertPermission(permission); return permissionMapper.insertPermission(permission);
} }
@ -203,23 +183,41 @@ public class PsyScalePermissionServiceImpl implements IPsyScalePermissionService
throw new IllegalArgumentException("用户ID不能为空"); throw new IllegalArgumentException("用户ID不能为空");
} }
// 先删除该用户的所有现有权限 String username = SecurityUtils.getUsername();
try { if (username == null || username.isEmpty()) {
permissionMapper.deletePermissionByUserId(userId); username = "system";
} catch (Exception e) { }
log.error("删除用户现有权限失败userId: {}", userId, e);
throw new RuntimeException("删除用户现有权限失败: " + (e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName()), e); java.util.Set<Long> newScaleSet = new java.util.HashSet<>();
if (scaleIds != null) {
for (Long scaleId : scaleIds) {
if (scaleId != null) {
newScaleSet.add(scaleId);
}
}
}
PsyScalePermission activeQuery = new PsyScalePermission();
activeQuery.setUserId(userId);
activeQuery.setStatus("0");
List<PsyScalePermission> activeList = permissionMapper.selectPermissionList(activeQuery);
if (activeList != null) {
for (PsyScalePermission p : activeList) {
if (p != null && p.getScaleId() != null && !newScaleSet.contains(p.getScaleId())) {
p.setStatus("1");
p.setUpdateBy(username);
try {
permissionMapper.updatePermission(p);
} catch (Exception e) {
log.warn("作废权限失败permissionId: {}", p.getPermissionId());
}
}
}
} }
// 批量插入新权限
int count = 0; int count = 0;
if (scaleIds != null && scaleIds.length > 0) if (scaleIds != null && scaleIds.length > 0)
{ {
String username = SecurityUtils.getUsername();
if (username == null || username.isEmpty()) {
username = "system"; // 如果获取不到用户名使用默认值
}
for (Long scaleId : scaleIds) for (Long scaleId : scaleIds)
{ {
if (scaleId == null) { if (scaleId == null) {
@ -240,7 +238,7 @@ public class PsyScalePermissionServiceImpl implements IPsyScalePermissionService
permission.setStatus("0"); permission.setStatus("0");
permission.setCreateBy(username); permission.setCreateBy(username);
int insertResult = permissionMapper.insertPermission(permission); int insertResult = insertPermission(permission);
if (insertResult > 0) { if (insertResult > 0) {
count++; count++;
} else { } else {
@ -248,7 +246,6 @@ public class PsyScalePermissionServiceImpl implements IPsyScalePermissionService
} }
} catch (Exception e) { } catch (Exception e) {
log.error("处理量表权限失败userId: {}, scaleId: {}", userId, scaleId, e); log.error("处理量表权限失败userId: {}, scaleId: {}", userId, scaleId, e);
// 继续处理下一个不中断整个流程
} }
} }
} }

View File

@ -43,6 +43,8 @@ public interface IPsyScalePermissionService
*/ */
public boolean checkUserScalePermission(Long userId, Long scaleId); public boolean checkUserScalePermission(Long userId, Long scaleId);
public Integer selectCurrentPublishNoForUserScale(Long userId, Long scaleId);
/** /**
* 新增量表权限 * 新增量表权限
* *

View File

@ -7,6 +7,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="com.ddnai.system.domain.psychology.PsyAssessment" id="PsyAssessmentResult"> <resultMap type="com.ddnai.system.domain.psychology.PsyAssessment" id="PsyAssessmentResult">
<result property="assessmentId" column="assessment_id" /> <result property="assessmentId" column="assessment_id" />
<result property="scaleId" column="scale_id" /> <result property="scaleId" column="scale_id" />
<result property="publishNo" column="publish_no" />
<result property="scaleName" column="scale_name" /> <result property="scaleName" column="scale_name" />
<result property="userId" column="user_id" /> <result property="userId" column="user_id" />
<result property="assesseeName" column="assessee_name" /> <result property="assesseeName" column="assessee_name" />
@ -34,7 +35,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap> </resultMap>
<sql id="selectAssessmentVo"> <sql id="selectAssessmentVo">
select a.assessment_id, a.scale_id, s.scale_name, a.user_id, select a.assessment_id, a.scale_id, a.publish_no, s.scale_name, a.user_id,
COALESCE(u.nick_name, a.assessee_name) as assessee_name, COALESCE(u.nick_name, a.assessee_name) as assessee_name,
a.assessee_gender, a.assessee_age, a.assessee_gender, a.assessee_age,
a.assessee_id_card, a.assessee_phone, a.assessee_email, a.start_time, a.pause_time, a.assessee_id_card, a.assessee_phone, a.assessee_email, a.start_time, a.pause_time,
@ -112,6 +113,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<insert id="insertAssessment" parameterType="com.ddnai.system.domain.psychology.PsyAssessment" useGeneratedKeys="true" keyProperty="assessmentId"> <insert id="insertAssessment" parameterType="com.ddnai.system.domain.psychology.PsyAssessment" useGeneratedKeys="true" keyProperty="assessmentId">
insert into psy_assessment ( insert into psy_assessment (
<if test="scaleId != null">scale_id, </if> <if test="scaleId != null">scale_id, </if>
<if test="publishNo != null">publish_no, </if>
<if test="userId != null">user_id, </if> <if test="userId != null">user_id, </if>
<if test="assesseeName != null and assesseeName != ''">assessee_name, </if> <if test="assesseeName != null and assesseeName != ''">assessee_name, </if>
<if test="assesseeGender != null">assessee_gender, </if> <if test="assesseeGender != null">assessee_gender, </if>
@ -128,6 +130,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
create_time create_time
)values( )values(
<if test="scaleId != null">#{scaleId}, </if> <if test="scaleId != null">#{scaleId}, </if>
<if test="publishNo != null">#{publishNo}, </if>
<if test="userId != null">#{userId}, </if> <if test="userId != null">#{userId}, </if>
<if test="assesseeName != null and assesseeName != ''">#{assesseeName}, </if> <if test="assesseeName != null and assesseeName != ''">#{assesseeName}, </if>
<if test="assesseeGender != null">#{assesseeGender}, </if> <if test="assesseeGender != null">#{assesseeGender}, </if>
@ -380,10 +383,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<!-- 查询用户已完成的量表ID列表 --> <!-- 查询用户已完成的量表ID列表 -->
<select id="selectCompletedScaleIdsByUserId" parameterType="Long" resultType="java.lang.Long"> <select id="selectCompletedScaleIdsByUserId" parameterType="Long" resultType="java.lang.Long">
select distinct scale_id select distinct a.scale_id
from psy_assessment from psy_assessment a
where user_id = #{userId} where a.user_id = #{userId}
and status = '1' and a.status = '1'
and ifnull(a.publish_no, 1) = (
select ifnull(max(coalesce(p.publish_no, 1)), 1)
from psy_scale_permission p
where p.scale_id = a.scale_id
and p.status = '0'
and (
(p.user_id = #{userId})
or (p.role_id is not null and p.role_id in (
select role_id from sys_user_role where user_id = #{userId}
))
or (p.dept_id is not null and p.dept_id in (
select dept_id from sys_user where user_id = #{userId}
))
or (p.user_id is null and p.role_id is null and p.dept_id is null)
)
and (p.start_time is null or p.start_time &lt;= now())
and (p.end_time is null or p.end_time &gt;= now())
)
</select> </select>
</mapper> </mapper>

View File

@ -7,6 +7,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="com.ddnai.system.domain.psychology.PsyQuestionnaireAnswer" id="PsyQuestionnaireAnswerResult"> <resultMap type="com.ddnai.system.domain.psychology.PsyQuestionnaireAnswer" id="PsyQuestionnaireAnswerResult">
<result property="answerId" column="answer_id" /> <result property="answerId" column="answer_id" />
<result property="questionnaireId" column="questionnaire_id" /> <result property="questionnaireId" column="questionnaire_id" />
<result property="publishNo" column="publish_no" />
<result property="userId" column="user_id" /> <result property="userId" column="user_id" />
<result property="respondentName" column="respondent_name" /> <result property="respondentName" column="respondent_name" />
<result property="startTime" column="start_time" /> <result property="startTime" column="start_time" />
@ -22,7 +23,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap> </resultMap>
<sql id="selectAnswerVo"> <sql id="selectAnswerVo">
select answer_id, questionnaire_id, user_id, respondent_name, start_time, submit_time, select answer_id, questionnaire_id, publish_no, user_id, respondent_name, start_time, submit_time,
total_score, is_pass, `rank`, `status`, create_by, create_time, update_by, update_time total_score, is_pass, `rank`, `status`, create_by, create_time, update_by, update_time
from psy_questionnaire_answer from psy_questionnaire_answer
</sql> </sql>
@ -36,6 +37,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectAnswerVo"/> <include refid="selectAnswerVo"/>
<where> <where>
<if test="questionnaireId != null"> and questionnaire_id = #{questionnaireId}</if> <if test="questionnaireId != null"> and questionnaire_id = #{questionnaireId}</if>
<if test="publishNo != null"> and publish_no = #{publishNo}</if>
<if test="userId != null"> and user_id = #{userId}</if> <if test="userId != null"> and user_id = #{userId}</if>
<if test="status != null and status != ''"> and `status` = #{status}</if> <if test="status != null and status != ''"> and `status` = #{status}</if>
</where> </where>
@ -45,6 +47,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<insert id="insertAnswer" parameterType="com.ddnai.system.domain.psychology.PsyQuestionnaireAnswer" useGeneratedKeys="true" keyProperty="answerId"> <insert id="insertAnswer" parameterType="com.ddnai.system.domain.psychology.PsyQuestionnaireAnswer" useGeneratedKeys="true" keyProperty="answerId">
insert into psy_questionnaire_answer ( insert into psy_questionnaire_answer (
<if test="questionnaireId != null">questionnaire_id, </if> <if test="questionnaireId != null">questionnaire_id, </if>
<if test="publishNo != null">publish_no, </if>
<if test="userId != null">user_id, </if> <if test="userId != null">user_id, </if>
<if test="respondentName != null and respondentName != ''">respondent_name, </if> <if test="respondentName != null and respondentName != ''">respondent_name, </if>
<if test="startTime != null">start_time, </if> <if test="startTime != null">start_time, </if>
@ -53,6 +56,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
create_time create_time
)values( )values(
<if test="questionnaireId != null">#{questionnaireId}, </if> <if test="questionnaireId != null">#{questionnaireId}, </if>
<if test="publishNo != null">#{publishNo}, </if>
<if test="userId != null">#{userId}, </if> <if test="userId != null">#{userId}, </if>
<if test="respondentName != null and respondentName != ''">#{respondentName}, </if> <if test="respondentName != null and respondentName != ''">#{respondentName}, </if>
<if test="startTime != null">#{startTime}, </if> <if test="startTime != null">#{startTime}, </if>
@ -85,10 +89,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<!-- 查询用户已完成的问卷ID列表 --> <!-- 查询用户已完成的问卷ID列表 -->
<select id="selectCompletedQuestionnaireIdsByUserId" parameterType="Long" resultType="java.lang.Long"> <select id="selectCompletedQuestionnaireIdsByUserId" parameterType="Long" resultType="java.lang.Long">
select distinct questionnaire_id select distinct a.questionnaire_id
from psy_questionnaire_answer from psy_questionnaire_answer a
where user_id = #{userId} where a.user_id = #{userId}
and status = '1' and a.status = '1'
and ifnull(a.publish_no, 1) = (
select ifnull(max(coalesce(p.publish_no, 1)), 1)
from psy_scale_permission p
where p.scale_id = -a.questionnaire_id
and p.status = '0'
and (
(p.user_id = #{userId})
or (p.role_id is not null and p.role_id in (
select role_id from sys_user_role where user_id = #{userId}
))
or (p.dept_id is not null and p.dept_id in (
select dept_id from sys_user where user_id = #{userId}
))
or (p.user_id is null and p.role_id is null and p.dept_id is null)
)
and (p.start_time is null or p.start_time &lt;= now())
and (p.end_time is null or p.end_time &gt;= now())
)
</select> </select>
</mapper> </mapper>

View File

@ -13,6 +13,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="className" column="class_name" /> <result property="className" column="class_name" />
<result property="startTime" column="start_time" /> <result property="startTime" column="start_time" />
<result property="endTime" column="end_time" /> <result property="endTime" column="end_time" />
<result property="publishNo" column="publish_no" />
<result property="status" column="status" /> <result property="status" column="status" />
<result property="createBy" column="create_by" /> <result property="createBy" column="create_by" />
<result property="createTime" column="create_time" /> <result property="createTime" column="create_time" />
@ -28,7 +29,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<sql id="selectPermissionVo"> <sql id="selectPermissionVo">
select p.permission_id, p.scale_id, p.dept_id, p.role_id, p.user_id, p.class_name, select p.permission_id, p.scale_id, p.dept_id, p.role_id, p.user_id, p.class_name,
p.start_time, p.end_time, p.status, p.create_by, p.create_time, p.update_by, p.update_time, p.remark, p.start_time, p.end_time, p.publish_no, p.status, p.create_by, p.create_time, p.update_by, p.update_time, p.remark,
case when p.scale_id &lt; 0 then q.questionnaire_name else s.scale_name end as scale_name, case when p.scale_id &lt; 0 then q.questionnaire_name else s.scale_name end as scale_name,
case when p.scale_id &lt; 0 then 'questionnaire' else 'scale' end as source_type, case when p.scale_id &lt; 0 then 'questionnaire' else 'scale' end as source_type,
d.dept_name, r.role_name, u.user_name d.dept_name, r.role_name, u.user_name
@ -123,6 +124,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="className != null and className != ''">class_name, </if> <if test="className != null and className != ''">class_name, </if>
<if test="startTime != null">start_time, </if> <if test="startTime != null">start_time, </if>
<if test="endTime != null">end_time, </if> <if test="endTime != null">end_time, </if>
<if test="publishNo != null">publish_no, </if>
<if test="status != null and status != ''">status, </if> <if test="status != null and status != ''">status, </if>
<if test="remark != null">remark,</if> <if test="remark != null">remark,</if>
<if test="createBy != null and createBy != ''">create_by,</if> <if test="createBy != null and createBy != ''">create_by,</if>
@ -135,6 +137,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="className != null and className != ''">#{className}, </if> <if test="className != null and className != ''">#{className}, </if>
<if test="startTime != null">#{startTime}, </if> <if test="startTime != null">#{startTime}, </if>
<if test="endTime != null">#{endTime}, </if> <if test="endTime != null">#{endTime}, </if>
<if test="publishNo != null">#{publishNo}, </if>
<if test="status != null and status != ''">#{status}, </if> <if test="status != null and status != ''">#{status}, </if>
<if test="remark != null">#{remark},</if> <if test="remark != null">#{remark},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if> <if test="createBy != null and createBy != ''">#{createBy},</if>
@ -152,6 +155,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="className != null and className != ''">class_name = #{className}, </if> <if test="className != null and className != ''">class_name = #{className}, </if>
<if test="startTime != null">start_time = #{startTime}, </if> <if test="startTime != null">start_time = #{startTime}, </if>
<if test="endTime != null">end_time = #{endTime}, </if> <if test="endTime != null">end_time = #{endTime}, </if>
<if test="publishNo != null">publish_no = #{publishNo}, </if>
<if test="status != null and status != ''">status = #{status}, </if> <if test="status != null and status != ''">status = #{status}, </if>
<if test="remark != null">remark = #{remark}, </if> <if test="remark != null">remark = #{remark}, </if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
@ -160,6 +164,76 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where permission_id = #{permissionId} where permission_id = #{permissionId}
</update> </update>
<select id="selectMaxPublishNo" parameterType="com.ddnai.system.domain.psychology.PsyScalePermission" resultType="java.lang.Integer">
select ifnull(max(coalesce(publish_no, 1)), 0)
from psy_scale_permission
<where>
<if test="scaleId != null"> and scale_id = #{scaleId}</if>
<choose>
<when test="deptId != null"> and dept_id = #{deptId}</when>
<otherwise> and dept_id is null</otherwise>
</choose>
<choose>
<when test="roleId != null"> and role_id = #{roleId}</when>
<otherwise> and role_id is null</otherwise>
</choose>
<choose>
<when test="userId != null"> and user_id = #{userId}</when>
<otherwise> and user_id is null</otherwise>
</choose>
<choose>
<when test="className != null and className != ''"> and class_name = #{className}</when>
<otherwise> and (class_name is null or class_name = '')</otherwise>
</choose>
</where>
</select>
<update id="invalidatePermissionByScope" parameterType="com.ddnai.system.domain.psychology.PsyScalePermission">
update psy_scale_permission
set status = '1',
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
update_time = sysdate()
<where>
status = '0'
<if test="scaleId != null"> and scale_id = #{scaleId}</if>
<choose>
<when test="deptId != null"> and dept_id = #{deptId}</when>
<otherwise> and dept_id is null</otherwise>
</choose>
<choose>
<when test="roleId != null"> and role_id = #{roleId}</when>
<otherwise> and role_id is null</otherwise>
</choose>
<choose>
<when test="userId != null"> and user_id = #{userId}</when>
<otherwise> and user_id is null</otherwise>
</choose>
<choose>
<when test="className != null and className != ''"> and class_name = #{className}</when>
<otherwise> and (class_name is null or class_name = '')</otherwise>
</choose>
</where>
</update>
<select id="selectCurrentPublishNoForUserScale" resultType="java.lang.Integer">
select ifnull(max(coalesce(p.publish_no, 1)), 1)
from psy_scale_permission p
where p.scale_id = #{scaleId}
and p.status = '0'
and (
(p.user_id = #{userId})
or (p.role_id is not null and p.role_id in (
select role_id from sys_user_role where user_id = #{userId}
))
or (p.dept_id is not null and p.dept_id in (
select dept_id from sys_user where user_id = #{userId}
))
or (p.user_id is null and p.role_id is null and p.dept_id is null)
)
and (p.start_time is null or p.start_time &lt;= now())
and (p.end_time is null or p.end_time &gt;= now())
</select>
<delete id="deletePermissionById" parameterType="Long"> <delete id="deletePermissionById" parameterType="Long">
delete from psy_scale_permission where permission_id = #{permissionId} delete from psy_scale_permission where permission_id = #{permissionId}
</delete> </delete>

View File

@ -0,0 +1,31 @@
-- 2025-12-22 add publish_no for per-release attempts
ALTER TABLE psy_scale_permission
ADD COLUMN publish_no INT NULL;
UPDATE psy_scale_permission
SET publish_no = 1
WHERE publish_no IS NULL;
ALTER TABLE psy_assessment
ADD COLUMN publish_no INT NULL;
UPDATE psy_assessment
SET publish_no = 1
WHERE publish_no IS NULL;
ALTER TABLE psy_questionnaire_answer
ADD COLUMN publish_no INT NULL;
UPDATE psy_questionnaire_answer
SET publish_no = 1
WHERE publish_no IS NULL;
CREATE INDEX idx_psy_scale_permission_scope_publish
ON psy_scale_permission (scale_id, user_id, role_id, dept_id, status, publish_no);
CREATE INDEX idx_psy_assessment_user_scale_publish
ON psy_assessment (user_id, scale_id, publish_no, status);
CREATE INDEX idx_psy_questionnaire_answer_user_q_publish
ON psy_questionnaire_answer (user_id, questionnaire_id, publish_no, status);