Merge branch 'master' of https://gitee.com/xiao12feng/xinli
This commit is contained in:
commit
e3cda00ff2
|
|
@ -83,6 +83,9 @@ public class PsyAssessmentReportController extends BaseController
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISasReportService sasReportService;
|
private ISasReportService sasReportService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private com.ddnai.system.service.psychology.IPsyUserProfileService profileService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取报告列表(包含测评报告和问卷报告)
|
* 获取报告列表(包含测评报告和问卷报告)
|
||||||
*/
|
*/
|
||||||
|
|
@ -125,6 +128,17 @@ public class PsyAssessmentReportController extends BaseController
|
||||||
vo.setIsGenerated(ar.getIsGenerated());
|
vo.setIsGenerated(ar.getIsGenerated());
|
||||||
vo.setGenerateTime(ar.getGenerateTime());
|
vo.setGenerateTime(ar.getGenerateTime());
|
||||||
vo.setCreateTime(ar.getCreateTime());
|
vo.setCreateTime(ar.getCreateTime());
|
||||||
|
|
||||||
|
// 获取用户信息
|
||||||
|
PsyAssessment assessment = assessmentService.selectAssessmentById(ar.getAssessmentId());
|
||||||
|
if (assessment != null) {
|
||||||
|
vo.setUserId(assessment.getUserId());
|
||||||
|
// 获取用户档案信息编号
|
||||||
|
com.ddnai.system.domain.psychology.PsyUserProfile profile = profileService.selectProfileByUserId(assessment.getUserId());
|
||||||
|
if (profile != null) {
|
||||||
|
vo.setInfoNumber(profile.getInfoNumber());
|
||||||
|
}
|
||||||
|
}
|
||||||
allReports.add(vo);
|
allReports.add(vo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,6 +155,17 @@ public class PsyAssessmentReportController extends BaseController
|
||||||
vo.setIsGenerated(qr.getIsGenerated());
|
vo.setIsGenerated(qr.getIsGenerated());
|
||||||
vo.setGenerateTime(qr.getGenerateTime());
|
vo.setGenerateTime(qr.getGenerateTime());
|
||||||
vo.setCreateTime(qr.getCreateTime());
|
vo.setCreateTime(qr.getCreateTime());
|
||||||
|
|
||||||
|
// 获取用户信息
|
||||||
|
com.ddnai.system.domain.psychology.PsyQuestionnaireAnswer answer = questionnaireAnswerService.selectAnswerById(qr.getAnswerId());
|
||||||
|
if (answer != null) {
|
||||||
|
vo.setUserId(answer.getUserId());
|
||||||
|
// 获取用户档案信息编号
|
||||||
|
com.ddnai.system.domain.psychology.PsyUserProfile profile = profileService.selectProfileByUserId(answer.getUserId());
|
||||||
|
if (profile != null) {
|
||||||
|
vo.setInfoNumber(profile.getInfoNumber());
|
||||||
|
}
|
||||||
|
}
|
||||||
allReports.add(vo);
|
allReports.add(vo);
|
||||||
System.out.println("添加问卷报告: reportId=" + qr.getReportId() + ", answerId=" + qr.getAnswerId() + ", title=" + qr.getReportTitle());
|
System.out.println("添加问卷报告: reportId=" + qr.getReportId() + ", answerId=" + qr.getAnswerId() + ", title=" + qr.getReportTitle());
|
||||||
}
|
}
|
||||||
|
|
@ -184,6 +209,8 @@ public class PsyAssessmentReportController extends BaseController
|
||||||
private Long reportId;
|
private Long reportId;
|
||||||
private String sourceType; // "assessment" 或 "questionnaire"
|
private String sourceType; // "assessment" 或 "questionnaire"
|
||||||
private Long sourceId; // assessmentId 或 answerId
|
private Long sourceId; // assessmentId 或 answerId
|
||||||
|
private Long userId; // 用户ID
|
||||||
|
private String infoNumber; // 信息编号
|
||||||
private String reportTitle;
|
private String reportTitle;
|
||||||
private String reportType;
|
private String reportType;
|
||||||
private String reportContent;
|
private String reportContent;
|
||||||
|
|
@ -199,6 +226,10 @@ public class PsyAssessmentReportController extends BaseController
|
||||||
public void setSourceType(String sourceType) { this.sourceType = sourceType; }
|
public void setSourceType(String sourceType) { this.sourceType = sourceType; }
|
||||||
public Long getSourceId() { return sourceId; }
|
public Long getSourceId() { return sourceId; }
|
||||||
public void setSourceId(Long sourceId) { this.sourceId = sourceId; }
|
public void setSourceId(Long sourceId) { this.sourceId = sourceId; }
|
||||||
|
public Long getUserId() { return userId; }
|
||||||
|
public void setUserId(Long userId) { this.userId = userId; }
|
||||||
|
public String getInfoNumber() { return infoNumber; }
|
||||||
|
public void setInfoNumber(String infoNumber) { this.infoNumber = infoNumber; }
|
||||||
public String getReportTitle() { return reportTitle; }
|
public String getReportTitle() { return reportTitle; }
|
||||||
public void setReportTitle(String reportTitle) { this.reportTitle = reportTitle; }
|
public void setReportTitle(String reportTitle) { this.reportTitle = reportTitle; }
|
||||||
public String getReportType() { return reportType; }
|
public String getReportType() { return reportType; }
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ public class PsyQuestionnaireAnswerController extends BaseController
|
||||||
/**
|
/**
|
||||||
* 获取问卷答题列表
|
* 获取问卷答题列表
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('psychology:questionnaire:list')")
|
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo list(PsyQuestionnaireAnswer answer)
|
public TableDataInfo list(PsyQuestionnaireAnswer answer)
|
||||||
{
|
{
|
||||||
|
|
@ -88,9 +87,12 @@ public class PsyQuestionnaireAnswerController extends BaseController
|
||||||
Long questionnaireId = Long.valueOf(params.get("questionnaireId").toString());
|
Long questionnaireId = Long.valueOf(params.get("questionnaireId").toString());
|
||||||
String respondentName = params.get("respondentName") != null ? params.get("respondentName").toString() : null;
|
String respondentName = params.get("respondentName") != null ? params.get("respondentName").toString() : null;
|
||||||
|
|
||||||
|
// 获取被测试用户ID:如果前端传递了userId(管理员代测),则使用传递的userId;否则使用当前登录用户ID
|
||||||
|
Long userId = params.get("userId") != null ? Long.valueOf(params.get("userId").toString()) : SecurityUtils.getUserId();
|
||||||
|
|
||||||
PsyQuestionnaireAnswer answer = new PsyQuestionnaireAnswer();
|
PsyQuestionnaireAnswer answer = new PsyQuestionnaireAnswer();
|
||||||
answer.setQuestionnaireId(questionnaireId);
|
answer.setQuestionnaireId(questionnaireId);
|
||||||
answer.setUserId(SecurityUtils.getUserId());
|
answer.setUserId(userId); // 使用被测试用户ID
|
||||||
answer.setRespondentName(respondentName);
|
answer.setRespondentName(respondentName);
|
||||||
answer.setStatus("0"); // 进行中
|
answer.setStatus("0"); // 进行中
|
||||||
answer.setStartTime(new Date());
|
answer.setStartTime(new Date());
|
||||||
|
|
@ -164,28 +166,39 @@ public class PsyQuestionnaireAnswerController extends BaseController
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
System.out.println("开始提交问卷,answerId: " + answerId + ", 用户: " + SecurityUtils.getUsername());
|
||||||
|
|
||||||
PsyQuestionnaireAnswer answer = answerService.selectAnswerById(answerId);
|
PsyQuestionnaireAnswer answer = answerService.selectAnswerById(answerId);
|
||||||
if (answer == null)
|
if (answer == null)
|
||||||
{
|
{
|
||||||
|
System.err.println("答题记录不存在,answerId: " + answerId);
|
||||||
return error("答题记录不存在");
|
return error("答题记录不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!"0".equals(answer.getStatus()))
|
if (!"0".equals(answer.getStatus()))
|
||||||
{
|
{
|
||||||
|
System.err.println("问卷状态异常,answerId: " + answerId + ", status: " + answer.getStatus());
|
||||||
return error("问卷已完成或已作废");
|
return error("问卷已完成或已作废");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自动评分并提交
|
// 自动评分并提交
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
int result = answerService.submitAnswer(answerId);
|
int result = answerService.submitAnswer(answerId);
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
System.out.println("问卷提交完成,answerId: " + answerId + ", 耗时: " + (endTime - startTime) + "ms, 结果: " + result);
|
||||||
|
|
||||||
if (result > 0)
|
if (result > 0)
|
||||||
{
|
{
|
||||||
return success("提交成功");
|
return success("提交成功");
|
||||||
}
|
}
|
||||||
|
System.err.println("提交失败,answerId: " + answerId + ", result: " + result);
|
||||||
return error("提交失败");
|
return error("提交失败");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
System.err.println("提交问卷异常,answerId: " + answerId + ", 错误: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
return error("提交失败:" + e.getMessage());
|
return error("提交失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -290,9 +303,8 @@ public class PsyQuestionnaireAnswerController extends BaseController
|
||||||
{
|
{
|
||||||
Long detailId = Long.valueOf(params.get("detailId").toString());
|
Long detailId = Long.valueOf(params.get("detailId").toString());
|
||||||
java.math.BigDecimal score = new java.math.BigDecimal(params.get("score").toString());
|
java.math.BigDecimal score = new java.math.BigDecimal(params.get("score").toString());
|
||||||
String comment = params.get("comment") != null ? params.get("comment").toString() : null;
|
|
||||||
|
|
||||||
int result = answerService.submitScoring(detailId, score, comment);
|
int result = answerService.submitScoring(detailId, score, null);
|
||||||
if (result > 0)
|
if (result > 0)
|
||||||
{
|
{
|
||||||
return success("评分成功");
|
return success("评分成功");
|
||||||
|
|
@ -317,9 +329,8 @@ public class PsyQuestionnaireAnswerController extends BaseController
|
||||||
{
|
{
|
||||||
Long detailId = Long.valueOf(params.get("detailId").toString());
|
Long detailId = Long.valueOf(params.get("detailId").toString());
|
||||||
java.math.BigDecimal score = new java.math.BigDecimal(params.get("score").toString());
|
java.math.BigDecimal score = new java.math.BigDecimal(params.get("score").toString());
|
||||||
String comment = params.get("comment") != null ? params.get("comment").toString() : null;
|
|
||||||
|
|
||||||
int result = answerService.submitScoring(detailId, score, comment);
|
int result = answerService.submitScoring(detailId, score, null);
|
||||||
if (result > 0)
|
if (result > 0)
|
||||||
{
|
{
|
||||||
successCount++;
|
successCount++;
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,8 @@ public class PsyQuestionnaireController extends BaseController
|
||||||
private IPsyQuestionnaireService questionnaireService;
|
private IPsyQuestionnaireService questionnaireService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取问卷列表
|
* 获取问卷列表(答题用户可访问)
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('psychology:questionnaire:list')")
|
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo list(PsyQuestionnaire questionnaire)
|
public TableDataInfo list(PsyQuestionnaire questionnaire)
|
||||||
{
|
{
|
||||||
|
|
@ -46,9 +45,8 @@ public class PsyQuestionnaireController extends BaseController
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据问卷ID获取详细信息
|
* 根据问卷ID获取详细信息(答题用户可访问)
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('psychology:questionnaire:query')")
|
|
||||||
@GetMapping(value = "/{questionnaireId}")
|
@GetMapping(value = "/{questionnaireId}")
|
||||||
public AjaxResult getInfo(@PathVariable Long questionnaireId)
|
public AjaxResult getInfo(@PathVariable Long questionnaireId)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,17 +17,17 @@ spring:
|
||||||
username:
|
username:
|
||||||
password:
|
password:
|
||||||
# 初始连接数
|
# 初始连接数
|
||||||
initialSize: 5
|
initialSize: 10
|
||||||
# 最小连接池数量
|
# 最小连接池数量
|
||||||
minIdle: 10
|
minIdle: 20
|
||||||
# 最大连接池数量
|
# 最大连接池数量
|
||||||
maxActive: 20
|
maxActive: 100
|
||||||
# 配置获取连接等待超时的时间
|
# 配置获取连接等待超时的时间(减少到20秒,快速失败)
|
||||||
maxWait: 60000
|
maxWait: 20000
|
||||||
# 配置连接超时时间
|
# 配置连接超时时间
|
||||||
connectTimeout: 30000
|
connectTimeout: 10000
|
||||||
# 配置网络超时时间
|
# 配置网络超时时间
|
||||||
socketTimeout: 60000
|
socketTimeout: 30000
|
||||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||||
timeBetweenEvictionRunsMillis: 60000
|
timeBetweenEvictionRunsMillis: 60000
|
||||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
|
||||||
|
|
@ -48,28 +48,48 @@ public class PsyUserProfile extends BaseEntity
|
||||||
@Excel(name = "生日", width = 30, dateFormat = "yyyy-MM-dd")
|
@Excel(name = "生日", width = 30, dateFormat = "yyyy-MM-dd")
|
||||||
private java.util.Date birthday;
|
private java.util.Date birthday;
|
||||||
|
|
||||||
/** 学历 */
|
/** 监狱 */
|
||||||
@Excel(name = "学历")
|
@Excel(name = "监狱")
|
||||||
private String education;
|
private String prison;
|
||||||
|
|
||||||
/** 职业 */
|
/** 监区 */
|
||||||
@Excel(name = "职业")
|
@Excel(name = "监区")
|
||||||
private String occupation;
|
private String prisonArea;
|
||||||
|
|
||||||
/** 地址 */
|
/** 性别 */
|
||||||
@Excel(name = "地址")
|
@Excel(name = "性别", readConverterExp = "0=男,1=女,2=未知")
|
||||||
private String address;
|
private String gender;
|
||||||
|
|
||||||
/** 紧急联系人 */
|
/** 民族 */
|
||||||
@Excel(name = "紧急联系人")
|
@Excel(name = "民族")
|
||||||
private String emergencyContact;
|
private String nation;
|
||||||
|
|
||||||
/** 紧急联系电话 */
|
/** 文化程度 */
|
||||||
@Excel(name = "紧急联系电话")
|
@Excel(name = "文化程度")
|
||||||
private String emergencyPhone;
|
private String educationLevel;
|
||||||
|
|
||||||
/** 病史 */
|
/** 罪名 */
|
||||||
private String medicalHistory;
|
@Excel(name = "罪名")
|
||||||
|
private String crimeName;
|
||||||
|
|
||||||
|
/** 刑期 */
|
||||||
|
@Excel(name = "刑期")
|
||||||
|
private String sentenceTerm;
|
||||||
|
|
||||||
|
/** 刑期起日 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Excel(name = "刑期起日", width = 30, dateFormat = "yyyy-MM-dd")
|
||||||
|
private java.util.Date sentenceStartDate;
|
||||||
|
|
||||||
|
/** 刑期止日 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Excel(name = "刑期止日", width = 30, dateFormat = "yyyy-MM-dd")
|
||||||
|
private java.util.Date sentenceEndDate;
|
||||||
|
|
||||||
|
/** 入监时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Excel(name = "入监时间", width = 30, dateFormat = "yyyy-MM-dd")
|
||||||
|
private java.util.Date entryDate;
|
||||||
|
|
||||||
/** 用户状态(0正常 1停用) */
|
/** 用户状态(0正常 1停用) */
|
||||||
private String status;
|
private String status;
|
||||||
|
|
@ -154,64 +174,104 @@ public class PsyUserProfile extends BaseEntity
|
||||||
this.birthday = birthday;
|
this.birthday = birthday;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEducation()
|
public String getPrison()
|
||||||
{
|
{
|
||||||
return education;
|
return prison;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEducation(String education)
|
public void setPrison(String prison)
|
||||||
{
|
{
|
||||||
this.education = education;
|
this.prison = prison;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOccupation()
|
public String getPrisonArea()
|
||||||
{
|
{
|
||||||
return occupation;
|
return prisonArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOccupation(String occupation)
|
public void setPrisonArea(String prisonArea)
|
||||||
{
|
{
|
||||||
this.occupation = occupation;
|
this.prisonArea = prisonArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAddress()
|
public String getGender()
|
||||||
{
|
{
|
||||||
return address;
|
return gender;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAddress(String address)
|
public void setGender(String gender)
|
||||||
{
|
{
|
||||||
this.address = address;
|
this.gender = gender;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEmergencyContact()
|
public String getNation()
|
||||||
{
|
{
|
||||||
return emergencyContact;
|
return nation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEmergencyContact(String emergencyContact)
|
public void setNation(String nation)
|
||||||
{
|
{
|
||||||
this.emergencyContact = emergencyContact;
|
this.nation = nation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEmergencyPhone()
|
public String getEducationLevel()
|
||||||
{
|
{
|
||||||
return emergencyPhone;
|
return educationLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEmergencyPhone(String emergencyPhone)
|
public void setEducationLevel(String educationLevel)
|
||||||
{
|
{
|
||||||
this.emergencyPhone = emergencyPhone;
|
this.educationLevel = educationLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMedicalHistory()
|
public String getCrimeName()
|
||||||
{
|
{
|
||||||
return medicalHistory;
|
return crimeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMedicalHistory(String medicalHistory)
|
public void setCrimeName(String crimeName)
|
||||||
{
|
{
|
||||||
this.medicalHistory = medicalHistory;
|
this.crimeName = crimeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSentenceTerm()
|
||||||
|
{
|
||||||
|
return sentenceTerm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSentenceTerm(String sentenceTerm)
|
||||||
|
{
|
||||||
|
this.sentenceTerm = sentenceTerm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public java.util.Date getSentenceStartDate()
|
||||||
|
{
|
||||||
|
return sentenceStartDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSentenceStartDate(java.util.Date sentenceStartDate)
|
||||||
|
{
|
||||||
|
this.sentenceStartDate = sentenceStartDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public java.util.Date getSentenceEndDate()
|
||||||
|
{
|
||||||
|
return sentenceEndDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSentenceEndDate(java.util.Date sentenceEndDate)
|
||||||
|
{
|
||||||
|
this.sentenceEndDate = sentenceEndDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public java.util.Date getEntryDate()
|
||||||
|
{
|
||||||
|
return entryDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntryDate(java.util.Date entryDate)
|
||||||
|
{
|
||||||
|
this.entryDate = entryDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUserName()
|
public String getUserName()
|
||||||
|
|
@ -274,74 +334,6 @@ public class PsyUserProfile extends BaseEntity
|
||||||
this.infoNumber = infoNumber;
|
this.infoNumber = infoNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 以下方法用于兼容现有代码,这些字段可能存储在 profileData JSON 中
|
|
||||||
// 如果需要,可以从 profileData 中解析这些字段
|
|
||||||
|
|
||||||
public String getPrisonerName()
|
|
||||||
{
|
|
||||||
// 可以从 profileData JSON 中解析,暂时返回 null
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPrisonName()
|
|
||||||
{
|
|
||||||
// 可以从 profileData JSON 中解析,暂时返回 null
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPrisonAreaName()
|
|
||||||
{
|
|
||||||
// 可以从 profileData JSON 中解析,暂时返回 null
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCustodyStatus()
|
|
||||||
{
|
|
||||||
// 可以从 profileData JSON 中解析,暂时返回 null
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNation()
|
|
||||||
{
|
|
||||||
// 可以从 profileData JSON 中解析,暂时返回 null
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEducationLevel()
|
|
||||||
{
|
|
||||||
// 可以从 profileData JSON 中解析,暂时返回 null
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCrimeName()
|
|
||||||
{
|
|
||||||
// 可以从 profileData JSON 中解析,暂时返回 null
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSentenceTerm()
|
|
||||||
{
|
|
||||||
// 可以从 profileData JSON 中解析,暂时返回 null
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSentenceStartDate()
|
|
||||||
{
|
|
||||||
// 可以从 profileData JSON 中解析,暂时返回 null
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSentenceEndDate()
|
|
||||||
{
|
|
||||||
// 可以从 profileData JSON 中解析,暂时返回 null
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEntryDate()
|
|
||||||
{
|
|
||||||
// 可以从 profileData JSON 中解析,暂时返回 null
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
@ -354,11 +346,16 @@ public class PsyUserProfile extends BaseEntity
|
||||||
.append("userName", getUserName())
|
.append("userName", getUserName())
|
||||||
.append("phone", getPhone())
|
.append("phone", getPhone())
|
||||||
.append("birthday", getBirthday())
|
.append("birthday", getBirthday())
|
||||||
.append("education", getEducation())
|
.append("prison", getPrison())
|
||||||
.append("occupation", getOccupation())
|
.append("prisonArea", getPrisonArea())
|
||||||
.append("address", getAddress())
|
.append("gender", getGender())
|
||||||
.append("emergencyContact", getEmergencyContact())
|
.append("nation", getNation())
|
||||||
.append("emergencyPhone", getEmergencyPhone())
|
.append("educationLevel", getEducationLevel())
|
||||||
|
.append("crimeName", getCrimeName())
|
||||||
|
.append("sentenceTerm", getSentenceTerm())
|
||||||
|
.append("sentenceStartDate", getSentenceStartDate())
|
||||||
|
.append("sentenceEndDate", getSentenceEndDate())
|
||||||
|
.append("entryDate", getEntryDate())
|
||||||
.append("infoNumber", getInfoNumber())
|
.append("infoNumber", getInfoNumber())
|
||||||
.append("createBy", getCreateBy())
|
.append("createBy", getCreateBy())
|
||||||
.append("createTime", getCreateTime())
|
.append("createTime", getCreateTime())
|
||||||
|
|
|
||||||
|
|
@ -156,22 +156,30 @@ public class PsyAssessmentServiceImpl implements IPsyAssessmentService
|
||||||
PsyUserProfile profile = userProfileService.selectProfileByUserId(userId);
|
PsyUserProfile profile = userProfileService.selectProfileByUserId(userId);
|
||||||
if (profile != null)
|
if (profile != null)
|
||||||
{
|
{
|
||||||
if (StringUtils.isNotEmpty(profile.getPrisonerName()))
|
if (StringUtils.isNotEmpty(profile.getUserName()))
|
||||||
{
|
{
|
||||||
summaryVO.setUserName(profile.getPrisonerName());
|
summaryVO.setUserName(profile.getUserName());
|
||||||
summaryVO.setNickName(profile.getPrisonerName());
|
summaryVO.setNickName(profile.getUserName());
|
||||||
}
|
}
|
||||||
summaryVO.setInfoNumber(profile.getInfoNumber());
|
summaryVO.setInfoNumber(profile.getInfoNumber());
|
||||||
summaryVO.setPrisonName(profile.getPrisonName());
|
summaryVO.setPrisonName(profile.getPrison());
|
||||||
summaryVO.setPrisonAreaName(profile.getPrisonAreaName());
|
summaryVO.setPrisonAreaName(profile.getPrisonArea());
|
||||||
summaryVO.setCustodyStatus(profile.getCustodyStatus());
|
// 监管状态字段已删除,可以根据需要设置默认值或删除此行
|
||||||
|
// summaryVO.setCustodyStatus(profile.getCustodyStatus());
|
||||||
summaryVO.setNation(profile.getNation());
|
summaryVO.setNation(profile.getNation());
|
||||||
summaryVO.setEducationLevel(profile.getEducationLevel());
|
summaryVO.setEducationLevel(profile.getEducationLevel());
|
||||||
summaryVO.setCrimeName(profile.getCrimeName());
|
summaryVO.setCrimeName(profile.getCrimeName());
|
||||||
summaryVO.setSentenceTerm(profile.getSentenceTerm());
|
summaryVO.setSentenceTerm(profile.getSentenceTerm());
|
||||||
summaryVO.setSentenceStartDate(profile.getSentenceStartDate());
|
// 日期字段需要转换为字符串格式
|
||||||
summaryVO.setSentenceEndDate(profile.getSentenceEndDate());
|
if (profile.getSentenceStartDate() != null) {
|
||||||
summaryVO.setEntryDate(profile.getEntryDate());
|
summaryVO.setSentenceStartDate(new java.text.SimpleDateFormat("yyyy-MM-dd").format(profile.getSentenceStartDate()));
|
||||||
|
}
|
||||||
|
if (profile.getSentenceEndDate() != null) {
|
||||||
|
summaryVO.setSentenceEndDate(new java.text.SimpleDateFormat("yyyy-MM-dd").format(profile.getSentenceEndDate()));
|
||||||
|
}
|
||||||
|
if (profile.getEntryDate() != null) {
|
||||||
|
summaryVO.setEntryDate(new java.text.SimpleDateFormat("yyyy-MM-dd").format(profile.getEntryDate()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<PsyAssessment> assessments = assessmentMapper.selectAssessmentListByUserId(userId);
|
List<PsyAssessment> assessments = assessmentMapper.selectAssessmentListByUserId(userId);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.ddnai.system.service.impl.psychology;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
@ -217,25 +218,37 @@ public class PsyQuestionnaireAnswerServiceImpl implements IPsyQuestionnaireAnswe
|
||||||
// 判断是否及格(需要从问卷表获取及格分数)
|
// 判断是否及格(需要从问卷表获取及格分数)
|
||||||
// 这里暂时不判断,后续可以完善
|
// 这里暂时不判断,后续可以完善
|
||||||
|
|
||||||
// 更新排名(需要重新计算所有答题记录的排名)
|
|
||||||
updateRank(answer.getQuestionnaireId());
|
|
||||||
|
|
||||||
int result = answerMapper.updateAnswer(answer);
|
int result = answerMapper.updateAnswer(answer);
|
||||||
|
|
||||||
// 生成问卷报告
|
// 异步更新排名(避免阻塞提交流程)
|
||||||
if (result > 0) {
|
final Long questionnaireIdForRank = answer.getQuestionnaireId();
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
try {
|
try {
|
||||||
generateQuestionnaireReport(answerId);
|
// 延迟50ms确保事务提交完成
|
||||||
System.out.println("问卷报告生成完成,answerId: " + answerId);
|
Thread.sleep(50);
|
||||||
|
updateRank(questionnaireIdForRank);
|
||||||
|
System.out.println("异步排名更新完成,questionnaireId: " + questionnaireIdForRank);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// 报告生成失败不影响提交,但记录详细错误
|
System.err.println("异步更新排名失败,questionnaireId: " + questionnaireIdForRank);
|
||||||
System.err.println("生成问卷报告失败,answerId: " + answerId);
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 异步生成问卷报告(避免阻塞提交流程)
|
||||||
|
if (result > 0) {
|
||||||
|
// 使用异步任务生成报告,不阻塞当前事务
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
try {
|
||||||
|
// 延迟100ms确保事务提交完成
|
||||||
|
Thread.sleep(100);
|
||||||
|
generateQuestionnaireReport(answerId);
|
||||||
|
System.out.println("异步问卷报告生成完成,answerId: " + answerId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("异步生成问卷报告失败,answerId: " + answerId);
|
||||||
System.err.println("错误信息: " + e.getMessage());
|
System.err.println("错误信息: " + e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
// 不抛出异常,让提交流程继续
|
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
System.err.println("更新答题记录失败,无法生成报告,answerId: " + answerId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -379,10 +392,35 @@ public class PsyQuestionnaireAnswerServiceImpl implements IPsyQuestionnaireAnswe
|
||||||
reportContent.append("</tbody></table>");
|
reportContent.append("</tbody></table>");
|
||||||
reportContent.append("</div>");
|
reportContent.append("</div>");
|
||||||
|
|
||||||
|
// 检查是否有未评分的主观题
|
||||||
|
boolean hasUnscoredSubjective = false;
|
||||||
|
int unscoredCount = 0;
|
||||||
|
for (PsyQuestionnaireAnswerDetail detail : details) {
|
||||||
|
PsyQuestionnaireItem item = itemMapper.selectItemById(detail.getItemId());
|
||||||
|
if (item != null) {
|
||||||
|
boolean isSubjective = isSubjectiveType(item.getItemType());
|
||||||
|
String isScored = detail.getIsScored();
|
||||||
|
|
||||||
|
// 如果是主观题且未评分
|
||||||
|
if (isSubjective && !"1".equals(isScored)) {
|
||||||
|
hasUnscoredSubjective = true;
|
||||||
|
unscoredCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("评分检查结果 - 总题目数: " + details.size() +
|
||||||
|
", 未评分主观题数: " + unscoredCount +
|
||||||
|
", 是否有未评分主观题: " + hasUnscoredSubjective);
|
||||||
|
|
||||||
// 生成报告摘要
|
// 生成报告摘要
|
||||||
String summary = String.format("本次答题共完成%d道题目,总得分%.2f分",
|
String summary = String.format("本次答题共完成%d道题目,总得分%.2f分%s",
|
||||||
details.size(),
|
details.size(),
|
||||||
answer.getTotalScore() != null ? answer.getTotalScore().doubleValue() : 0.0);
|
answer.getTotalScore() != null ? answer.getTotalScore().doubleValue() : 0.0,
|
||||||
|
hasUnscoredSubjective ? "(有" + unscoredCount + "道主观题待评分)" : "");
|
||||||
|
|
||||||
|
// 根据是否有未评分的主观题决定报告状态
|
||||||
|
String isGenerated = hasUnscoredSubjective ? "0" : "1";
|
||||||
|
|
||||||
// 保存报告到数据库
|
// 保存报告到数据库
|
||||||
PsyQuestionnaireReport existingReport = reportMapper.selectReportByAnswerId(answerId);
|
PsyQuestionnaireReport existingReport = reportMapper.selectReportByAnswerId(answerId);
|
||||||
|
|
@ -394,13 +432,13 @@ public class PsyQuestionnaireAnswerServiceImpl implements IPsyQuestionnaireAnswe
|
||||||
|
|
||||||
if (existingReport != null) {
|
if (existingReport != null) {
|
||||||
// 更新现有报告
|
// 更新现有报告
|
||||||
System.out.println("更新已存在的报告,reportId: " + existingReport.getReportId());
|
System.out.println("更新已存在的报告,reportId: " + existingReport.getReportId() + ", 报告状态: " + isGenerated);
|
||||||
report = existingReport;
|
report = existingReport;
|
||||||
report.setReportType("standard");
|
report.setReportType("standard");
|
||||||
report.setReportTitle(reportTitle);
|
report.setReportTitle(reportTitle);
|
||||||
report.setReportContent(reportContent.toString());
|
report.setReportContent(reportContent.toString());
|
||||||
report.setSummary(summary);
|
report.setSummary(summary);
|
||||||
report.setIsGenerated("1");
|
report.setIsGenerated(isGenerated); // 根据评分状态设置
|
||||||
report.setGenerateTime(DateUtils.getNowDate());
|
report.setGenerateTime(DateUtils.getNowDate());
|
||||||
report.setUpdateBy(SecurityUtils.getUsername());
|
report.setUpdateBy(SecurityUtils.getUsername());
|
||||||
report.setUpdateTime(DateUtils.getNowDate());
|
report.setUpdateTime(DateUtils.getNowDate());
|
||||||
|
|
@ -414,12 +452,12 @@ public class PsyQuestionnaireAnswerServiceImpl implements IPsyQuestionnaireAnswe
|
||||||
report.setReportTitle(reportTitle);
|
report.setReportTitle(reportTitle);
|
||||||
report.setReportContent(reportContent.toString());
|
report.setReportContent(reportContent.toString());
|
||||||
report.setSummary(summary);
|
report.setSummary(summary);
|
||||||
report.setIsGenerated("1");
|
report.setIsGenerated(isGenerated); // 根据评分状态设置
|
||||||
report.setGenerateTime(DateUtils.getNowDate());
|
report.setGenerateTime(DateUtils.getNowDate());
|
||||||
report.setCreateBy(SecurityUtils.getUsername());
|
report.setCreateBy(SecurityUtils.getUsername());
|
||||||
report.setCreateTime(DateUtils.getNowDate());
|
report.setCreateTime(DateUtils.getNowDate());
|
||||||
int insertResult = reportMapper.insertReport(report);
|
int insertResult = reportMapper.insertReport(report);
|
||||||
System.out.println("创建新报告结果: " + insertResult + ", reportId: " + report.getReportId());
|
System.out.println("创建新报告结果: " + insertResult + ", reportId: " + report.getReportId() + ", 报告状态: " + isGenerated);
|
||||||
if (insertResult <= 0) {
|
if (insertResult <= 0) {
|
||||||
System.err.println("警告:报告插入失败,insertResult: " + insertResult);
|
System.err.println("警告:报告插入失败,insertResult: " + insertResult);
|
||||||
}
|
}
|
||||||
|
|
@ -1008,8 +1046,18 @@ public class PsyQuestionnaireAnswerServiceImpl implements IPsyQuestionnaireAnswe
|
||||||
answer.setUpdateBy(SecurityUtils.getUsername());
|
answer.setUpdateBy(SecurityUtils.getUsername());
|
||||||
answerMapper.updateAnswer(answer);
|
answerMapper.updateAnswer(answer);
|
||||||
|
|
||||||
// 重新计算排名
|
// 异步重新计算排名
|
||||||
updateRank(answer.getQuestionnaireId());
|
final Long questionnaireIdForRank = answer.getQuestionnaireId();
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
try {
|
||||||
|
Thread.sleep(50);
|
||||||
|
updateRank(questionnaireIdForRank);
|
||||||
|
System.out.println("评分后异步排名更新完成,questionnaireId: " + questionnaireIdForRank);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("评分后异步更新排名失败,questionnaireId: " + questionnaireIdForRank);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 重新生成报告,以反映最新的评分
|
// 重新生成报告,以反映最新的评分
|
||||||
// 注意:由于在同一个事务中,MyBatis一级缓存可能返回旧数据
|
// 注意:由于在同一个事务中,MyBatis一级缓存可能返回旧数据
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,8 @@ public class SasReportServiceImpl implements ISasReportService
|
||||||
info.setUnitName(firstNonBlank(summary.getPrisonName(), summary.getDeptName(), resolveDefaultUnitName()));
|
info.setUnitName(firstNonBlank(summary.getPrisonName(), summary.getDeptName(), resolveDefaultUnitName()));
|
||||||
info.setPrisonAreaName(summary.getPrisonAreaName());
|
info.setPrisonAreaName(summary.getPrisonAreaName());
|
||||||
info.setDeptName(summary.getDeptName());
|
info.setDeptName(summary.getDeptName());
|
||||||
info.setCustodyStatus(summary.getCustodyStatus());
|
// 监管状态字段已删除,可以根据需要设置默认值或删除此行
|
||||||
|
// info.setCustodyStatus(summary.getCustodyStatus());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -181,10 +182,11 @@ public class SasReportServiceImpl implements ISasReportService
|
||||||
}
|
}
|
||||||
if (data.getUserInfo() != null)
|
if (data.getUserInfo() != null)
|
||||||
{
|
{
|
||||||
if (StringUtils.isNotBlank(data.getUserInfo().getCustodyStatus()))
|
// 监管状态字段已删除
|
||||||
{
|
// if (StringUtils.isNotBlank(data.getUserInfo().getCustodyStatus()))
|
||||||
keywords.add(data.getUserInfo().getCustodyStatus());
|
// {
|
||||||
}
|
// keywords.add(data.getUserInfo().getCustodyStatus());
|
||||||
|
// }
|
||||||
if (StringUtils.isNotBlank(data.getUserInfo().getPrisonAreaName()))
|
if (StringUtils.isNotBlank(data.getUserInfo().getPrisonAreaName()))
|
||||||
{
|
{
|
||||||
keywords.add(data.getUserInfo().getPrisonAreaName());
|
keywords.add(data.getUserInfo().getPrisonAreaName());
|
||||||
|
|
|
||||||
|
|
@ -25,31 +25,35 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectQuestionnaireVo">
|
<sql id="selectQuestionnaireVo">
|
||||||
select questionnaire_id, questionnaire_code, questionnaire_name, questionnaire_type, paper_type,
|
select q.questionnaire_id, q.questionnaire_code, q.questionnaire_name, q.questionnaire_type, q.paper_type,
|
||||||
item_count, total_score, pass_score, estimated_time, description, status, sort_order,
|
COALESCE(COUNT(i.item_id), 0) as item_count, q.total_score, q.pass_score, q.estimated_time, q.description, q.status, q.sort_order,
|
||||||
create_by, create_time, update_by, update_time, remark
|
q.create_by, q.create_time, q.update_by, q.update_time, q.remark
|
||||||
from psy_questionnaire
|
from psy_questionnaire q
|
||||||
|
left join psy_questionnaire_item i on q.questionnaire_id = i.questionnaire_id
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectQuestionnaireById" parameterType="Long" resultMap="PsyQuestionnaireResult">
|
<select id="selectQuestionnaireById" parameterType="Long" resultMap="PsyQuestionnaireResult">
|
||||||
<include refid="selectQuestionnaireVo"/>
|
<include refid="selectQuestionnaireVo"/>
|
||||||
where questionnaire_id = #{questionnaireId}
|
where q.questionnaire_id = #{questionnaireId}
|
||||||
|
group by q.questionnaire_id
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectQuestionnaireByCode" parameterType="String" resultMap="PsyQuestionnaireResult">
|
<select id="selectQuestionnaireByCode" parameterType="String" resultMap="PsyQuestionnaireResult">
|
||||||
<include refid="selectQuestionnaireVo"/>
|
<include refid="selectQuestionnaireVo"/>
|
||||||
where questionnaire_code = #{questionnaireCode}
|
where q.questionnaire_code = #{questionnaireCode}
|
||||||
|
group by q.questionnaire_id
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectQuestionnaireList" parameterType="com.ddnai.system.domain.psychology.PsyQuestionnaire" resultMap="PsyQuestionnaireResult">
|
<select id="selectQuestionnaireList" parameterType="com.ddnai.system.domain.psychology.PsyQuestionnaire" resultMap="PsyQuestionnaireResult">
|
||||||
<include refid="selectQuestionnaireVo"/>
|
<include refid="selectQuestionnaireVo"/>
|
||||||
<where>
|
<where>
|
||||||
<if test="questionnaireCode != null and questionnaireCode != ''"> and questionnaire_code = #{questionnaireCode}</if>
|
<if test="questionnaireCode != null and questionnaireCode != ''"> and q.questionnaire_code = #{questionnaireCode}</if>
|
||||||
<if test="questionnaireName != null and questionnaireName != ''"> and questionnaire_name like concat('%', #{questionnaireName}, '%')</if>
|
<if test="questionnaireName != null and questionnaireName != ''"> and q.questionnaire_name like concat('%', #{questionnaireName}, '%')</if>
|
||||||
<if test="questionnaireType != null and questionnaireType != ''"> and questionnaire_type = #{questionnaireType}</if>
|
<if test="questionnaireType != null and questionnaireType != ''"> and q.questionnaire_type = #{questionnaireType}</if>
|
||||||
<if test="status != null and status != ''"> and status = #{status}</if>
|
<if test="status != null and status != ''"> and q.status = #{status}</if>
|
||||||
</where>
|
</where>
|
||||||
order by sort_order, create_time desc
|
group by q.questionnaire_id
|
||||||
|
order by q.sort_order, q.create_time desc
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<insert id="insertQuestionnaire" parameterType="com.ddnai.system.domain.psychology.PsyQuestionnaire" useGeneratedKeys="true" keyProperty="questionnaireId">
|
<insert id="insertQuestionnaire" parameterType="com.ddnai.system.domain.psychology.PsyQuestionnaire" useGeneratedKeys="true" keyProperty="questionnaireId">
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<result property="userName" column="user_name" />
|
<result property="userName" column="user_name" />
|
||||||
<result property="phone" column="phone" />
|
<result property="phone" column="phone" />
|
||||||
<result property="birthday" column="birthday" />
|
<result property="birthday" column="birthday" />
|
||||||
<result property="education" column="education" />
|
<result property="prison" column="prison" />
|
||||||
<result property="occupation" column="occupation" />
|
<result property="prisonArea" column="prison_area" />
|
||||||
<result property="address" column="address" />
|
<result property="gender" column="gender" />
|
||||||
<result property="emergencyContact" column="emergency_contact" />
|
<result property="nation" column="nation" />
|
||||||
<result property="emergencyPhone" column="emergency_phone" />
|
<result property="educationLevel" column="education_level" />
|
||||||
<result property="medicalHistory" column="medical_history" />
|
<result property="crimeName" column="crime_name" />
|
||||||
|
<result property="sentenceTerm" column="sentence_term" />
|
||||||
|
<result property="sentenceStartDate" column="sentence_start_date" />
|
||||||
|
<result property="sentenceEndDate" column="sentence_end_date" />
|
||||||
|
<result property="entryDate" column="entry_date" />
|
||||||
<result property="status" column="status" />
|
<result property="status" column="status" />
|
||||||
<result property="deptId" column="dept_id" />
|
<result property="deptId" column="dept_id" />
|
||||||
<result property="deptName" column="dept_name" />
|
<result property="deptName" column="dept_name" />
|
||||||
|
|
@ -33,8 +37,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
|
||||||
<sql id="selectProfileVo">
|
<sql id="selectProfileVo">
|
||||||
select p.profile_id, p.user_id, p.profile_type, p.profile_data, p.avatar, p.id_card, p.birthday,
|
select p.profile_id, p.user_id, p.profile_type, p.profile_data, p.avatar, p.id_card, p.birthday,
|
||||||
p.education, p.occupation, p.address, p.emergency_contact, p.emergency_phone,
|
p.prison, p.prison_area, p.gender, p.nation, p.education_level, p.crime_name,
|
||||||
p.medical_history, p.info_number, p.create_by, p.create_time, p.update_by, p.update_time, p.remark,
|
p.sentence_term, p.sentence_start_date, p.sentence_end_date, p.entry_date,
|
||||||
|
p.info_number, p.create_by, p.create_time, p.update_by, p.update_time, p.remark,
|
||||||
u.user_name, u.phonenumber as phone, u.nick_name, u.email, u.sex, u.status, u.dept_id, u.create_time as user_create_time
|
u.user_name, u.phonenumber as phone, u.nick_name, u.email, u.sex, u.status, u.dept_id, u.create_time as user_create_time
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
|
|
@ -64,8 +69,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar as user_avatar, u.phonenumber as phone, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by as user_create_by, u.create_time as user_create_time, u.remark as user_remark,
|
select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar as user_avatar, u.phonenumber as phone, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by as user_create_by, u.create_time as user_create_time, u.remark as user_remark,
|
||||||
d.dept_name, d.leader,
|
d.dept_name, d.leader,
|
||||||
p.profile_id, p.profile_type, p.profile_data, p.avatar, p.id_card, p.birthday,
|
p.profile_id, p.profile_type, p.profile_data, p.avatar, p.id_card, p.birthday,
|
||||||
p.education, p.occupation, p.address, p.emergency_contact, p.emergency_phone,
|
p.prison, p.prison_area, p.gender, p.nation, p.education_level, p.crime_name,
|
||||||
p.medical_history, p.info_number, p.create_by, p.create_time, p.update_by, p.update_time, p.remark
|
p.sentence_term, p.sentence_start_date, p.sentence_end_date, p.entry_date,
|
||||||
|
p.info_number, p.create_by, p.create_time, p.update_by, p.update_time, p.remark
|
||||||
from sys_user u
|
from sys_user u
|
||||||
left join sys_dept d on u.dept_id = d.dept_id
|
left join sys_dept d on u.dept_id = d.dept_id
|
||||||
left join psy_user_profile p on u.user_id = p.user_id
|
left join psy_user_profile p on u.user_id = p.user_id
|
||||||
|
|
@ -113,12 +119,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="avatar != null">avatar, </if>
|
<if test="avatar != null">avatar, </if>
|
||||||
<if test="idCard != null">id_card, </if>
|
<if test="idCard != null">id_card, </if>
|
||||||
<if test="birthday != null">birthday, </if>
|
<if test="birthday != null">birthday, </if>
|
||||||
<if test="education != null">education, </if>
|
<if test="prison != null">prison, </if>
|
||||||
<if test="occupation != null">occupation, </if>
|
<if test="prisonArea != null">prison_area, </if>
|
||||||
<if test="address != null">address, </if>
|
<if test="gender != null">gender, </if>
|
||||||
<if test="emergencyContact != null">emergency_contact, </if>
|
<if test="nation != null">nation, </if>
|
||||||
<if test="emergencyPhone != null">emergency_phone, </if>
|
<if test="educationLevel != null">education_level, </if>
|
||||||
<if test="medicalHistory != null">medical_history, </if>
|
<if test="crimeName != null">crime_name, </if>
|
||||||
|
<if test="sentenceTerm != null">sentence_term, </if>
|
||||||
|
<if test="sentenceStartDate != null">sentence_start_date, </if>
|
||||||
|
<if test="sentenceEndDate != null">sentence_end_date, </if>
|
||||||
|
<if test="entryDate != null">entry_date, </if>
|
||||||
<if test="infoNumber != null">info_number, </if>
|
<if test="infoNumber != null">info_number, </if>
|
||||||
<if test="createBy != null">create_by, </if>
|
<if test="createBy != null">create_by, </if>
|
||||||
<if test="remark != null">remark, </if>
|
<if test="remark != null">remark, </if>
|
||||||
|
|
@ -130,12 +140,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="avatar != null">#{avatar}, </if>
|
<if test="avatar != null">#{avatar}, </if>
|
||||||
<if test="idCard != null">#{idCard}, </if>
|
<if test="idCard != null">#{idCard}, </if>
|
||||||
<if test="birthday != null">#{birthday}, </if>
|
<if test="birthday != null">#{birthday}, </if>
|
||||||
<if test="education != null">#{education}, </if>
|
<if test="prison != null">#{prison}, </if>
|
||||||
<if test="occupation != null">#{occupation}, </if>
|
<if test="prisonArea != null">#{prisonArea}, </if>
|
||||||
<if test="address != null">#{address}, </if>
|
<if test="gender != null">#{gender}, </if>
|
||||||
<if test="emergencyContact != null">#{emergencyContact}, </if>
|
<if test="nation != null">#{nation}, </if>
|
||||||
<if test="emergencyPhone != null">#{emergencyPhone}, </if>
|
<if test="educationLevel != null">#{educationLevel}, </if>
|
||||||
<if test="medicalHistory != null">#{medicalHistory}, </if>
|
<if test="crimeName != null">#{crimeName}, </if>
|
||||||
|
<if test="sentenceTerm != null">#{sentenceTerm}, </if>
|
||||||
|
<if test="sentenceStartDate != null">#{sentenceStartDate}, </if>
|
||||||
|
<if test="sentenceEndDate != null">#{sentenceEndDate}, </if>
|
||||||
|
<if test="entryDate != null">#{entryDate}, </if>
|
||||||
<if test="infoNumber != null">#{infoNumber}, </if>
|
<if test="infoNumber != null">#{infoNumber}, </if>
|
||||||
<if test="createBy != null">#{createBy}, </if>
|
<if test="createBy != null">#{createBy}, </if>
|
||||||
<if test="remark != null">#{remark}, </if>
|
<if test="remark != null">#{remark}, </if>
|
||||||
|
|
@ -151,12 +165,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="avatar != null">avatar = #{avatar}, </if>
|
<if test="avatar != null">avatar = #{avatar}, </if>
|
||||||
<if test="idCard != null">id_card = #{idCard}, </if>
|
<if test="idCard != null">id_card = #{idCard}, </if>
|
||||||
<if test="birthday != null">birthday = #{birthday}, </if>
|
<if test="birthday != null">birthday = #{birthday}, </if>
|
||||||
<if test="education != null">education = #{education}, </if>
|
<if test="prison != null">prison = #{prison}, </if>
|
||||||
<if test="occupation != null">occupation = #{occupation}, </if>
|
<if test="prisonArea != null">prison_area = #{prisonArea}, </if>
|
||||||
<if test="address != null">address = #{address}, </if>
|
<if test="gender != null">gender = #{gender}, </if>
|
||||||
<if test="emergencyContact != null">emergency_contact = #{emergencyContact}, </if>
|
<if test="nation != null">nation = #{nation}, </if>
|
||||||
<if test="emergencyPhone != null">emergency_phone = #{emergencyPhone}, </if>
|
<if test="educationLevel != null">education_level = #{educationLevel}, </if>
|
||||||
<if test="medicalHistory != null">medical_history = #{medicalHistory}, </if>
|
<if test="crimeName != null">crime_name = #{crimeName}, </if>
|
||||||
|
<if test="sentenceTerm != null">sentence_term = #{sentenceTerm}, </if>
|
||||||
|
<if test="sentenceStartDate != null">sentence_start_date = #{sentenceStartDate}, </if>
|
||||||
|
<if test="sentenceEndDate != null">sentence_end_date = #{sentenceEndDate}, </if>
|
||||||
|
<if test="entryDate != null">entry_date = #{entryDate}, </if>
|
||||||
<if test="infoNumber != null">info_number = #{infoNumber}, </if>
|
<if test="infoNumber != null">info_number = #{infoNumber}, </if>
|
||||||
<if test="updateBy != null">update_by = #{updateBy}, </if>
|
<if test="updateBy != null">update_by = #{updateBy}, </if>
|
||||||
<if test="remark != null">remark = #{remark}, </if>
|
<if test="remark != null">remark = #{remark}, </if>
|
||||||
|
|
|
||||||
|
|
@ -45,39 +45,97 @@ function buildKeywordAnalysis(reportData, severityMeta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildChartOption(reportData) {
|
export function buildChartOption(reportData) {
|
||||||
|
try {
|
||||||
const chartData = reportData.chartData || {}
|
const chartData = reportData.chartData || {}
|
||||||
const score = safeScore(reportData.calculatedResults?.rawScore)
|
const score = safeScore(reportData.calculatedResults?.rawScore)
|
||||||
const xAxis = chartData.xAxis || [reportData.testRecord?.projectDate || '当前']
|
const rawScoreValue = reportData.calculatedResults?.rawScore || 0
|
||||||
const seriesData = chartData.series || [{ name: '总分', value: reportData.calculatedResults?.rawScore || 0 }]
|
|
||||||
|
// 构建X轴数据
|
||||||
|
let xAxis = []
|
||||||
|
if (chartData.xAxis && Array.isArray(chartData.xAxis) && chartData.xAxis.length > 0) {
|
||||||
|
xAxis = chartData.xAxis
|
||||||
|
} else if (reportData.testRecord?.projectDate) {
|
||||||
|
xAxis = [formatDateLabel(reportData.testRecord.projectDate)]
|
||||||
|
} else {
|
||||||
|
xAxis = ['当前']
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建系列数据
|
||||||
|
let seriesDataValues = []
|
||||||
|
if (chartData.series && Array.isArray(chartData.series) && chartData.series.length > 0) {
|
||||||
|
seriesDataValues = chartData.series.map(item => {
|
||||||
|
const val = item.value !== undefined ? item.value : rawScoreValue
|
||||||
|
return typeof val === 'number' ? val : parseFloat(val) || 0
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
seriesDataValues = [typeof rawScoreValue === 'number' ? rawScoreValue : parseFloat(rawScoreValue) || 0]
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: {
|
title: {
|
||||||
text: chartData.title || 'SAS总分趋势',
|
text: chartData.title || '测评分数趋势',
|
||||||
left: 'center'
|
left: 'center',
|
||||||
|
top: 10,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: 'normal'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
formatter: '{b}: {c}分'
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '10%',
|
||||||
|
right: '10%',
|
||||||
|
bottom: '15%',
|
||||||
|
top: '20%',
|
||||||
|
containLabel: true
|
||||||
},
|
},
|
||||||
tooltip: { trigger: 'axis' },
|
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
data: xAxis
|
data: xAxis,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: { color: '#999' }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
name: '分数',
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: { color: '#999' }
|
||||||
|
}
|
||||||
},
|
},
|
||||||
yAxis: { type: 'value' },
|
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: '总分',
|
name: '总分',
|
||||||
type: 'line',
|
type: 'line',
|
||||||
smooth: true,
|
smooth: true,
|
||||||
areaStyle: { opacity: 0.15 },
|
symbol: 'circle',
|
||||||
data: seriesData.map(item => item.value)
|
symbolSize: 8,
|
||||||
}
|
itemStyle: {
|
||||||
],
|
color: '#409EFF'
|
||||||
graphic: {
|
},
|
||||||
type: 'text',
|
lineStyle: {
|
||||||
left: 'center',
|
width: 2,
|
||||||
top: '10%',
|
color: '#409EFF'
|
||||||
style: {
|
},
|
||||||
text: `当前得分:${score}`,
|
areaStyle: {
|
||||||
fontSize: 14
|
opacity: 0.2,
|
||||||
|
color: '#409EFF'
|
||||||
|
},
|
||||||
|
data: seriesDataValues,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'top',
|
||||||
|
formatter: '{c}分'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('构建图表配置失败:', error)
|
||||||
|
throw new Error('图表配置构建失败: ' + error.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,8 @@ import { buildChartOption, formatDateLabel } from './DynamicContentService'
|
||||||
|
|
||||||
class SASReportGenerator {
|
class SASReportGenerator {
|
||||||
async buildHtml(reportData, includeChart = true) {
|
async buildHtml(reportData, includeChart = true) {
|
||||||
|
// 不再使用图表功能
|
||||||
let chartImage = ''
|
let chartImage = ''
|
||||||
if (includeChart) {
|
|
||||||
chartImage = await this.renderChartImage(buildChartOption(reportData))
|
|
||||||
}
|
|
||||||
const recommendations = (reportData.calculatedResults.recommendations || []).map(item => `<li>${item}</li>`).join('')
|
const recommendations = (reportData.calculatedResults.recommendations || []).map(item => `<li>${item}</li>`).join('')
|
||||||
const keywords = (reportData.keywordAnalysis || reportData.keywords || []).map(item => `<span class="tag">${item}</span>`).join('')
|
const keywords = (reportData.keywordAnalysis || reportData.keywords || []).map(item => `<span class="tag">${item}</span>`).join('')
|
||||||
const printScopes = (reportData.printScopes || []).map(scope => `
|
const printScopes = (reportData.printScopes || []).map(scope => `
|
||||||
|
|
@ -43,7 +41,7 @@ class SASReportGenerator {
|
||||||
<div class="section-title">基本信息</div>
|
<div class="section-title">基本信息</div>
|
||||||
<table>
|
<table>
|
||||||
<tr><th>编码</th><td>${reportData.userInfo.infoNumber || reportData.testRecord.assessmentId || '-'}</td>
|
<tr><th>编码</th><td>${reportData.userInfo.infoNumber || reportData.testRecord.assessmentId || '-'}</td>
|
||||||
<th>样本</th><td>${reportData.userInfo.name || '-'}</td></tr>
|
<th>姓名</th><td>${reportData.userInfo.name || '-'}</td></tr>
|
||||||
<tr><th>测试单位</th><td>${reportData.userInfo.unitName || '-'}</td>
|
<tr><th>测试单位</th><td>${reportData.userInfo.unitName || '-'}</td>
|
||||||
<th>性别</th><td>${reportData.userInfo.gender || '-'}</td></tr>
|
<th>性别</th><td>${reportData.userInfo.gender || '-'}</td></tr>
|
||||||
<tr><th>所属科室/监区</th><td>${reportData.userInfo.prisonAreaName || reportData.userInfo.deptName || '-'}</td>
|
<tr><th>所属科室/监区</th><td>${reportData.userInfo.prisonAreaName || reportData.userInfo.deptName || '-'}</td>
|
||||||
|
|
@ -58,7 +56,6 @@ class SASReportGenerator {
|
||||||
<tr><th>原始分数</th><td class="highlight">${reportData.calculatedResults.rawScore}</td></tr>
|
<tr><th>原始分数</th><td class="highlight">${reportData.calculatedResults.rawScore}</td></tr>
|
||||||
<tr><th>功能评级</th><td>${reportData.calculatedResults.functionalRating}</td></tr>
|
<tr><th>功能评级</th><td>${reportData.calculatedResults.functionalRating}</td></tr>
|
||||||
</table>
|
</table>
|
||||||
${chartImage ? `<div class="chart"><img src="${chartImage}" alt="chart" style="max-width: 600px" /></div>` : ''}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
|
|
@ -106,18 +103,58 @@ class SASReportGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
async renderChartImage(option) {
|
async renderChartImage(option) {
|
||||||
const container = document.createElement('div')
|
let container = null
|
||||||
|
let chart = null
|
||||||
|
try {
|
||||||
|
console.log('开始渲染图表,配置:', option)
|
||||||
|
|
||||||
|
// 创建容器
|
||||||
|
container = document.createElement('div')
|
||||||
container.style.width = '640px'
|
container.style.width = '640px'
|
||||||
container.style.height = '320px'
|
container.style.height = '320px'
|
||||||
container.style.position = 'fixed'
|
container.style.position = 'fixed'
|
||||||
container.style.left = '-9999px'
|
container.style.left = '-9999px'
|
||||||
|
container.style.top = '0'
|
||||||
document.body.appendChild(container)
|
document.body.appendChild(container)
|
||||||
const chart = echarts.init(container)
|
|
||||||
|
// 初始化echarts
|
||||||
|
chart = echarts.init(container)
|
||||||
|
if (!chart) {
|
||||||
|
throw new Error('echarts初始化失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置图表选项
|
||||||
chart.setOption(option)
|
chart.setOption(option)
|
||||||
const dataUrl = chart.getDataURL({ pixelRatio: 2, backgroundColor: '#fff' })
|
|
||||||
chart.dispose()
|
// 等待渲染完成
|
||||||
document.body.removeChild(container)
|
await new Promise(resolve => setTimeout(resolve, 100))
|
||||||
|
|
||||||
|
// 获取图表图像
|
||||||
|
const dataUrl = chart.getDataURL({
|
||||||
|
type: 'png',
|
||||||
|
pixelRatio: 2,
|
||||||
|
backgroundColor: '#fff'
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('图表渲染成功,图像长度:', dataUrl?.length || 0)
|
||||||
return dataUrl
|
return dataUrl
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('图表渲染失败:', error)
|
||||||
|
throw error
|
||||||
|
} finally {
|
||||||
|
// 清理资源
|
||||||
|
try {
|
||||||
|
if (chart) {
|
||||||
|
chart.dispose()
|
||||||
|
}
|
||||||
|
if (container && container.parentNode) {
|
||||||
|
document.body.removeChild(container)
|
||||||
|
}
|
||||||
|
} catch (cleanupError) {
|
||||||
|
console.warn('清理图表资源时出错:', cleanupError)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveReportTitle(reportData) {
|
resolveReportTitle(reportData) {
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
|
||||||
const service = axios.create({
|
const service = axios.create({
|
||||||
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||||
baseURL: process.env.VUE_APP_BASE_API,
|
baseURL: process.env.VUE_APP_BASE_API,
|
||||||
// 超时
|
// 超时(增加到30秒以支持连续测评操作)
|
||||||
timeout: 10000
|
timeout: 30000
|
||||||
})
|
})
|
||||||
|
|
||||||
// request拦截器
|
// request拦截器
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ export default {
|
||||||
scaleList: [],
|
scaleList: [],
|
||||||
profileList: [],
|
profileList: [],
|
||||||
pausedList: [],
|
pausedList: [],
|
||||||
|
targetUserId: null, // 目标用户ID(从URL参数获取)
|
||||||
form: {
|
form: {
|
||||||
scaleId: undefined,
|
scaleId: undefined,
|
||||||
profileId: undefined
|
profileId: undefined
|
||||||
|
|
@ -110,11 +111,23 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// 检查URL参数中是否有scaleId
|
// 检查URL参数中是否有scaleId和profileId/userId
|
||||||
const scaleId = this.$route.query.scaleId;
|
const scaleId = this.$route.query.scaleId;
|
||||||
|
const profileId = this.$route.query.profileId;
|
||||||
|
const userId = this.$route.query.userId;
|
||||||
|
|
||||||
if (scaleId) {
|
if (scaleId) {
|
||||||
this.form.scaleId = parseInt(scaleId);
|
this.form.scaleId = parseInt(scaleId);
|
||||||
}
|
}
|
||||||
|
if (profileId) {
|
||||||
|
this.form.profileId = parseInt(profileId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存userId(如果有)用于后续跳转
|
||||||
|
if (userId) {
|
||||||
|
this.targetUserId = parseInt(userId);
|
||||||
|
}
|
||||||
|
|
||||||
this.loadScales();
|
this.loadScales();
|
||||||
this.loadProfiles();
|
this.loadProfiles();
|
||||||
this.loadPaused();
|
this.loadPaused();
|
||||||
|
|
@ -140,9 +153,17 @@ export default {
|
||||||
if (selectedScale && selectedScale.sourceType === 'questionnaire') {
|
if (selectedScale && selectedScale.sourceType === 'questionnaire') {
|
||||||
// 如果是问卷,直接跳转到问卷开始页面
|
// 如果是问卷,直接跳转到问卷开始页面
|
||||||
const questionnaireId = selectedScale.originalId || Math.abs(selectedScale.scaleId);
|
const questionnaireId = selectedScale.originalId || Math.abs(selectedScale.scaleId);
|
||||||
|
const queryParams = { questionnaireId: questionnaireId };
|
||||||
|
|
||||||
|
// 检查URL中是否有userId参数(管理员代测)
|
||||||
|
const urlUserId = this.$route.query.userId;
|
||||||
|
if (urlUserId) {
|
||||||
|
queryParams.userId = urlUserId;
|
||||||
|
}
|
||||||
|
|
||||||
this.$router.replace({
|
this.$router.replace({
|
||||||
path: '/psychology/questionnaire/start',
|
path: '/psychology/questionnaire/start',
|
||||||
query: { questionnaireId: questionnaireId }
|
query: queryParams
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -164,9 +185,17 @@ export default {
|
||||||
if (selectedScale && selectedScale.sourceType === 'questionnaire') {
|
if (selectedScale && selectedScale.sourceType === 'questionnaire') {
|
||||||
// 如果是问卷,直接跳转到问卷开始页面
|
// 如果是问卷,直接跳转到问卷开始页面
|
||||||
const questionnaireId = selectedScale.originalId || Math.abs(selectedScale.scaleId);
|
const questionnaireId = selectedScale.originalId || Math.abs(selectedScale.scaleId);
|
||||||
|
const queryParams = { questionnaireId: questionnaireId };
|
||||||
|
|
||||||
|
// 检查URL中是否有userId参数(管理员代测)
|
||||||
|
const urlUserId = this.$route.query.userId;
|
||||||
|
if (urlUserId) {
|
||||||
|
queryParams.userId = urlUserId;
|
||||||
|
}
|
||||||
|
|
||||||
this.$router.replace({
|
this.$router.replace({
|
||||||
path: '/psychology/questionnaire/start',
|
path: '/psychology/questionnaire/start',
|
||||||
query: { questionnaireId: questionnaireId }
|
query: queryParams
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -197,9 +226,17 @@ export default {
|
||||||
if (selectedScale && selectedScale.sourceType === 'questionnaire') {
|
if (selectedScale && selectedScale.sourceType === 'questionnaire') {
|
||||||
// 如果是问卷,直接跳转到问卷开始页面
|
// 如果是问卷,直接跳转到问卷开始页面
|
||||||
const questionnaireId = selectedScale.originalId || Math.abs(selectedScale.scaleId);
|
const questionnaireId = selectedScale.originalId || Math.abs(selectedScale.scaleId);
|
||||||
|
const queryParams = { questionnaireId: questionnaireId };
|
||||||
|
|
||||||
|
// 检查URL中是否有userId参数(管理员代测)
|
||||||
|
const urlUserId = this.$route.query.userId;
|
||||||
|
if (urlUserId) {
|
||||||
|
queryParams.userId = urlUserId;
|
||||||
|
}
|
||||||
|
|
||||||
this.$router.replace({
|
this.$router.replace({
|
||||||
path: '/psychology/questionnaire/start',
|
path: '/psychology/questionnaire/start',
|
||||||
query: { questionnaireId: questionnaireId }
|
query: queryParams
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -269,13 +306,29 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果是问卷,直接跳转到问卷答题页面(不需要用户档案)
|
// 如果是问卷,直接跳转到问卷答题页面
|
||||||
if (selectedScale.sourceType === 'questionnaire') {
|
if (selectedScale.sourceType === 'questionnaire') {
|
||||||
const questionnaireId = selectedScale.originalId || Math.abs(selectedScale.scaleId);
|
const questionnaireId = selectedScale.originalId || Math.abs(selectedScale.scaleId);
|
||||||
// 问卷不需要用户档案,直接跳转到问卷开始页面
|
|
||||||
|
// 构建查询参数
|
||||||
|
const queryParams = { questionnaireId: questionnaireId };
|
||||||
|
|
||||||
|
// 优先使用targetUserId(从URL获取),其次使用选择的用户档案
|
||||||
|
if (this.targetUserId) {
|
||||||
|
queryParams.userId = this.targetUserId;
|
||||||
|
console.log('使用URL参数的userId:', this.targetUserId);
|
||||||
|
} else if (this.form.profileId) {
|
||||||
|
const selectedProfile = this.profileList.find(p => p.profileId === this.form.profileId);
|
||||||
|
if (selectedProfile && selectedProfile.userId) {
|
||||||
|
queryParams.userId = selectedProfile.userId;
|
||||||
|
console.log('管理员代测,传递userId:', selectedProfile.userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转到问卷开始页面
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: '/psychology/questionnaire/start',
|
path: '/psychology/questionnaire/start',
|
||||||
query: { questionnaireId: questionnaireId }
|
query: queryParams
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,10 +122,25 @@
|
||||||
<span>{{ parseTime(scope.row.birthday, '{y}-{m}-{d}') }}</span>
|
<span>{{ parseTime(scope.row.birthday, '{y}-{m}-{d}') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="学历" align="center" prop="education" width="100" />
|
<el-table-column label="监狱" align="center" prop="prison" width="120" />
|
||||||
<el-table-column label="职业" align="center" prop="occupation" width="120" />
|
<el-table-column label="监区" align="center" prop="prisonArea" width="100" />
|
||||||
<el-table-column label="紧急联系人" align="center" prop="emergencyContact" width="120" />
|
<el-table-column label="性别" align="center" prop="gender" width="80">
|
||||||
<el-table-column label="紧急电话" align="center" prop="emergencyPhone" width="130" />
|
<template slot-scope="scope">
|
||||||
|
<span v-if="scope.row.gender === '0'">男</span>
|
||||||
|
<span v-else-if="scope.row.gender === '1'">女</span>
|
||||||
|
<span v-else-if="scope.row.gender === '2'">未知</span>
|
||||||
|
<span v-else>{{ scope.row.gender }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="民族" align="center" prop="nation" width="80" />
|
||||||
|
<el-table-column label="文化程度" align="center" prop="educationLevel" width="100" />
|
||||||
|
<el-table-column label="罪名" align="center" prop="crimeName" width="120" />
|
||||||
|
<el-table-column label="刑期" align="center" prop="sentenceTerm" width="100" />
|
||||||
|
<el-table-column label="入监时间" align="center" prop="entryDate" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.entryDate, '{y}-{m}-{d}') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||||
|
|
@ -226,34 +241,99 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="学历" prop="education">
|
<el-form-item label="监狱" prop="prison">
|
||||||
<el-input v-model="form.education" placeholder="请输入学历" />
|
<el-input v-model="form.prison" placeholder="请输入监狱名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="职业" prop="occupation">
|
<el-form-item label="监区" prop="prisonArea">
|
||||||
<el-input v-model="form.occupation" placeholder="请输入职业" />
|
<el-input v-model="form.prisonArea" placeholder="请输入监区" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="性别" prop="gender">
|
||||||
|
<el-select v-model="form.gender" placeholder="请选择性别">
|
||||||
|
<el-option label="男" value="0" />
|
||||||
|
<el-option label="女" value="1" />
|
||||||
|
<el-option label="未知" value="2" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="民族" prop="nation">
|
||||||
|
<el-input v-model="form.nation" placeholder="请输入民族" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="文化程度" prop="educationLevel">
|
||||||
|
<el-select v-model="form.educationLevel" placeholder="请选择文化程度">
|
||||||
|
<el-option label="小学" value="小学" />
|
||||||
|
<el-option label="初中" value="初中" />
|
||||||
|
<el-option label="高中" value="高中" />
|
||||||
|
<el-option label="中专" value="中专" />
|
||||||
|
<el-option label="大专" value="大专" />
|
||||||
|
<el-option label="本科" value="本科" />
|
||||||
|
<el-option label="硕士" value="硕士" />
|
||||||
|
<el-option label="博士" value="博士" />
|
||||||
|
<el-option label="其他" value="其他" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="罪名" prop="crimeName">
|
||||||
|
<el-input v-model="form.crimeName" placeholder="请输入罪名" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="刑期" prop="sentenceTerm">
|
||||||
|
<el-input v-model="form.sentenceTerm" placeholder="请输入刑期(如:3年6个月)" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="刑期起日" prop="sentenceStartDate">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.sentenceStartDate"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择刑期起日"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="刑期止日" prop="sentenceEndDate">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.sentenceEndDate"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择刑期止日"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="入监时间" prop="entryDate">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.entryDate"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择入监时间"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-form-item label="头像">
|
<el-form-item label="头像">
|
||||||
<el-input v-model="form.avatar" placeholder="请输入头像URL" />
|
<el-input v-model="form.avatar" placeholder="请输入头像URL" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="地址" prop="address">
|
|
||||||
<el-input v-model="form.address" type="textarea" :rows="2" placeholder="请输入地址" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="紧急联系人" prop="emergencyContact">
|
|
||||||
<el-input v-model="form.emergencyContact" placeholder="请输入紧急联系人" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="紧急联系电话" prop="emergencyPhone">
|
|
||||||
<el-input v-model="form.emergencyPhone" placeholder="请输入紧急联系电话" maxlength="11" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-form-item label="备注">
|
<el-form-item label="备注">
|
||||||
<el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" />
|
<el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -542,11 +622,16 @@ export default {
|
||||||
userName: undefined,
|
userName: undefined,
|
||||||
phone: undefined,
|
phone: undefined,
|
||||||
birthday: undefined,
|
birthday: undefined,
|
||||||
education: undefined,
|
prison: undefined,
|
||||||
occupation: undefined,
|
prisonArea: undefined,
|
||||||
address: undefined,
|
gender: undefined,
|
||||||
emergencyContact: undefined,
|
nation: undefined,
|
||||||
emergencyPhone: undefined,
|
educationLevel: undefined,
|
||||||
|
crimeName: undefined,
|
||||||
|
sentenceTerm: undefined,
|
||||||
|
sentenceStartDate: undefined,
|
||||||
|
sentenceEndDate: undefined,
|
||||||
|
entryDate: undefined,
|
||||||
remark: undefined
|
remark: undefined
|
||||||
}
|
}
|
||||||
this.resetForm("form")
|
this.resetForm("form")
|
||||||
|
|
|
||||||
|
|
@ -128,14 +128,6 @@
|
||||||
满分:{{ scoreForm.itemScore || 0 }} 分
|
满分:{{ scoreForm.itemScore || 0 }} 分
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="评语">
|
|
||||||
<el-input
|
|
||||||
v-model="scoreForm.comment"
|
|
||||||
type="textarea"
|
|
||||||
:rows="4"
|
|
||||||
placeholder="请输入评语(可选)"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button type="primary" @click="submitScoreForm">确 定</el-button>
|
<el-button type="primary" @click="submitScoreForm">确 定</el-button>
|
||||||
|
|
@ -164,17 +156,6 @@
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="评语" min-width="200">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-input
|
|
||||||
v-model="scope.row.comment"
|
|
||||||
type="textarea"
|
|
||||||
:rows="2"
|
|
||||||
placeholder="评语(可选)"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
</el-table>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button type="primary" @click="submitBatchScore">确 定</el-button>
|
<el-button type="primary" @click="submitBatchScore">确 定</el-button>
|
||||||
|
|
@ -273,8 +254,7 @@ export default {
|
||||||
itemContent: row.itemContent,
|
itemContent: row.itemContent,
|
||||||
itemScore: row.itemScore || 0,
|
itemScore: row.itemScore || 0,
|
||||||
answerText: row.answerText || '',
|
answerText: row.answerText || '',
|
||||||
score: row.answerScore || 0,
|
score: row.answerScore || 0
|
||||||
comment: ''
|
|
||||||
};
|
};
|
||||||
this.scoreOpen = true;
|
this.scoreOpen = true;
|
||||||
},
|
},
|
||||||
|
|
@ -284,8 +264,7 @@ export default {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
const data = {
|
const data = {
|
||||||
detailId: this.scoreForm.detailId,
|
detailId: this.scoreForm.detailId,
|
||||||
score: this.scoreForm.score,
|
score: this.scoreForm.score
|
||||||
comment: this.scoreForm.comment
|
|
||||||
};
|
};
|
||||||
|
|
||||||
submitScoring(data).then(response => {
|
submitScoring(data).then(response => {
|
||||||
|
|
@ -315,8 +294,7 @@ export default {
|
||||||
itemContent: '',
|
itemContent: '',
|
||||||
itemScore: 0,
|
itemScore: 0,
|
||||||
answerText: '',
|
answerText: '',
|
||||||
score: 0,
|
score: 0
|
||||||
comment: ''
|
|
||||||
};
|
};
|
||||||
if (this.$refs["scoreForm"]) {
|
if (this.$refs["scoreForm"]) {
|
||||||
this.$refs["scoreForm"].resetFields();
|
this.$refs["scoreForm"].resetFields();
|
||||||
|
|
@ -329,11 +307,10 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 为每行添加score和comment字段
|
// 为每行添加score字段
|
||||||
this.selectedRows = this.selectedRows.map(row => ({
|
this.selectedRows = this.selectedRows.map(row => ({
|
||||||
...row,
|
...row,
|
||||||
score: row.answerScore || 0,
|
score: row.answerScore || 0
|
||||||
comment: ''
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.batchScoreOpen = true;
|
this.batchScoreOpen = true;
|
||||||
|
|
@ -342,8 +319,7 @@ export default {
|
||||||
submitBatchScore() {
|
submitBatchScore() {
|
||||||
const scoringList = this.selectedRows.map(row => ({
|
const scoringList = this.selectedRows.map(row => ({
|
||||||
detailId: row.detailId,
|
detailId: row.detailId,
|
||||||
score: row.score || 0,
|
score: row.score || 0
|
||||||
comment: row.comment || ''
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
batchSubmitScoring(scoringList).then(response => {
|
batchSubmitScoring(scoringList).then(response => {
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ export default {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
questionnaireList: [],
|
questionnaireList: [],
|
||||||
|
selectedUserId: null, // 管理员选择的被测试用户ID
|
||||||
form: {
|
form: {
|
||||||
questionnaireId: undefined,
|
questionnaireId: undefined,
|
||||||
respondentName: undefined
|
respondentName: undefined
|
||||||
|
|
@ -55,10 +56,16 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// 检查URL参数中是否有questionnaireId
|
// 检查URL参数中是否有questionnaireId和userId
|
||||||
const questionnaireId = this.$route.query.questionnaireId;
|
const questionnaireId = this.$route.query.questionnaireId;
|
||||||
|
const userId = this.$route.query.userId;
|
||||||
|
|
||||||
if (questionnaireId) {
|
if (questionnaireId) {
|
||||||
this.form.questionnaireId = parseInt(questionnaireId);
|
this.form.questionnaireId = parseInt(questionnaireId);
|
||||||
|
// 如果管理员选择了用户(有userId参数),保存起来
|
||||||
|
if (userId) {
|
||||||
|
this.selectedUserId = parseInt(userId);
|
||||||
|
}
|
||||||
// 如果已经选择了问卷,直接开始答题(不需要填写姓名)
|
// 如果已经选择了问卷,直接开始答题(不需要填写姓名)
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.startAnswerDirectly();
|
this.startAnswerDirectly();
|
||||||
|
|
@ -87,6 +94,11 @@ export default {
|
||||||
respondentName: this.form.respondentName || null
|
respondentName: this.form.respondentName || null
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 如果管理员选择了用户,传递userId
|
||||||
|
if (this.selectedUserId) {
|
||||||
|
data.userId = this.selectedUserId;
|
||||||
|
}
|
||||||
|
|
||||||
startQuestionnaireAnswer(data).then(response => {
|
startQuestionnaireAnswer(data).then(response => {
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
this.$modal.msgSuccess("答题已开始");
|
this.$modal.msgSuccess("答题已开始");
|
||||||
|
|
@ -119,6 +131,11 @@ export default {
|
||||||
respondentName: null // 不填写姓名
|
respondentName: null // 不填写姓名
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 如果管理员选择了用户,传递userId
|
||||||
|
if (this.selectedUserId) {
|
||||||
|
data.userId = this.selectedUserId;
|
||||||
|
}
|
||||||
|
|
||||||
startQuestionnaireAnswer(data).then(response => {
|
startQuestionnaireAnswer(data).then(response => {
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
this.$modal.msgSuccess("答题已开始");
|
this.$modal.msgSuccess("答题已开始");
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,8 @@
|
||||||
plain
|
plain
|
||||||
icon="el-icon-printer"
|
icon="el-icon-printer"
|
||||||
size="mini"
|
size="mini"
|
||||||
:disabled="!isAssessmentSelection"
|
:disabled="multiple"
|
||||||
@click="openSasDialog"
|
@click="openExportDialog"
|
||||||
v-hasPermi="['psychology:report:export']"
|
v-hasPermi="['psychology:report:export']"
|
||||||
>导出报告</el-button>
|
>导出报告</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
@ -72,7 +72,11 @@
|
||||||
<el-tag v-else type="primary">量表</el-tag>
|
<el-tag v-else type="primary">量表</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="来源ID" align="center" prop="sourceId" width="100" />
|
<el-table-column label="信息编号" align="center" prop="infoNumber" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ scope.row.infoNumber || '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="报告标题" align="center" prop="reportTitle" :show-overflow-tooltip="true" />
|
<el-table-column label="报告标题" align="center" prop="reportTitle" :show-overflow-tooltip="true" />
|
||||||
<el-table-column label="报告类型" align="center" prop="reportType" width="120">
|
<el-table-column label="报告类型" align="center" prop="reportType" width="120">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
|
|
@ -160,7 +164,7 @@
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- SAS 报告导出设置 -->
|
<!-- SAS 报告导出设置 -->
|
||||||
<el-dialog title="SAS报告导出" :visible.sync="sasExportDialog" width="420px" append-to-body @close="resetSasDialog">
|
<el-dialog title="报告导出" :visible.sync="sasExportDialog" width="420px" append-to-body @close="resetSasDialog">
|
||||||
<el-form :model="sasExportForm" label-width="90px">
|
<el-form :model="sasExportForm" label-width="90px">
|
||||||
<el-form-item label="导出格式">
|
<el-form-item label="导出格式">
|
||||||
<el-radio-group v-model="sasExportForm.format">
|
<el-radio-group v-model="sasExportForm.format">
|
||||||
|
|
@ -168,9 +172,6 @@
|
||||||
<el-radio label="print">打印/PDF</el-radio>
|
<el-radio label="print">打印/PDF</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="包含图表">
|
|
||||||
<el-switch v-model="sasExportForm.includeChart"></el-switch>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="sasExportDialog = false">取 消</el-button>
|
<el-button @click="sasExportDialog = false">取 消</el-button>
|
||||||
|
|
@ -229,20 +230,13 @@ export default {
|
||||||
},
|
},
|
||||||
sasExportDialog: false,
|
sasExportDialog: false,
|
||||||
sasExportForm: {
|
sasExportForm: {
|
||||||
format: "word",
|
format: "word"
|
||||||
includeChart: true
|
|
||||||
},
|
},
|
||||||
sasExportLoading: false,
|
sasExportLoading: false,
|
||||||
sasTarget: null
|
sasTarget: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isAssessmentSelection() {
|
|
||||||
const row = this.getActiveRow();
|
|
||||||
if (!row) return false;
|
|
||||||
if (!row.sourceType) return true;
|
|
||||||
return row.sourceType === 'assessment';
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getList();
|
this.getList();
|
||||||
|
|
@ -403,20 +397,36 @@ export default {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
async openSasDialog(row) {
|
async openExportDialog() {
|
||||||
const target = row || this.getActiveRow();
|
// 获取选中的报告(从选中行或当前行)
|
||||||
|
const target = this.getActiveRow();
|
||||||
if (!target) {
|
if (!target) {
|
||||||
this.$message.warning("请先选择一条量表报告");
|
this.$message.warning("请先选择一条报告");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (target.sourceType && target.sourceType !== 'assessment') {
|
|
||||||
this.$message.warning("仅支持量表测评报告生成模板");
|
console.log('选中的报告对象:', target);
|
||||||
|
console.log('报告类型:', target.sourceType);
|
||||||
|
|
||||||
|
// 确保有sourceType信息
|
||||||
|
if (!target.sourceType) {
|
||||||
|
this.$modal.msgError("报告缺少类型信息,请刷新页面后重试");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果是问卷报告,打开问卷导出对话框
|
||||||
|
if (target.sourceType === 'questionnaire') {
|
||||||
|
this.sasTarget = { ...target, sourceType: 'questionnaire' };
|
||||||
|
this.sasExportForm = { format: "word" };
|
||||||
|
this.sasExportDialog = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 量表报告使用SAS模板
|
||||||
try {
|
try {
|
||||||
const resolved = await this.ensureAssessmentInfo(target);
|
const resolved = await this.ensureAssessmentInfo(target);
|
||||||
this.sasTarget = resolved;
|
this.sasTarget = { ...resolved, sourceType: 'assessment' };
|
||||||
this.sasExportForm = { format: "word", includeChart: true };
|
this.sasExportForm = { format: "word" };
|
||||||
this.sasExportDialog = true;
|
this.sasExportDialog = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$modal.msgError(error.message || "无法定位测评ID");
|
this.$modal.msgError(error.message || "无法定位测评ID");
|
||||||
|
|
@ -445,35 +455,97 @@ export default {
|
||||||
this.sasExportDialog = false;
|
this.sasExportDialog = false;
|
||||||
this.sasExportLoading = false;
|
this.sasExportLoading = false;
|
||||||
this.sasTarget = null;
|
this.sasTarget = null;
|
||||||
this.sasExportForm = { format: "word", includeChart: true };
|
this.sasExportForm = { format: "word" };
|
||||||
},
|
},
|
||||||
async confirmSasExport() {
|
async confirmSasExport() {
|
||||||
if (!this.sasTarget) {
|
if (!this.sasTarget) {
|
||||||
this.$message.warning("未选择报告");
|
this.$message.warning("未选择报告");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const assessmentId = this.sasTarget.sourceId || this.sasTarget.assessmentId;
|
|
||||||
if (!assessmentId) {
|
|
||||||
this.$modal.msgError("无法定位测评ID");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.sasExportLoading = true;
|
this.sasExportLoading = true;
|
||||||
try {
|
try {
|
||||||
const reportData = await loadSasReportData(assessmentId);
|
// 判断是问卷还是量表
|
||||||
if (this.sasExportForm.format === 'word') {
|
if (this.sasTarget.sourceType === 'questionnaire') {
|
||||||
await SASReportGenerator.exportWord(reportData, this.sasExportForm.includeChart);
|
// 问卷报告导出
|
||||||
|
await this.exportQuestionnaireReport();
|
||||||
} else {
|
} else {
|
||||||
await SASReportGenerator.print(reportData, this.sasExportForm.includeChart);
|
// 量表报告导出
|
||||||
|
await this.exportAssessmentReport();
|
||||||
}
|
}
|
||||||
this.$modal.msgSuccess("SAS报告已生成");
|
this.$modal.msgSuccess("报告已生成");
|
||||||
this.resetSasDialog();
|
this.resetSasDialog();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("生成SAS报告失败:", error);
|
console.error("生成报告失败:", error);
|
||||||
this.$modal.msgError("生成失败:" + (error.message || "未知错误"));
|
this.$modal.msgError("生成失败:" + (error.message || "未知错误"));
|
||||||
} finally {
|
} finally {
|
||||||
this.sasExportLoading = false;
|
this.sasExportLoading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async exportAssessmentReport() {
|
||||||
|
const assessmentId = this.sasTarget.sourceId || this.sasTarget.assessmentId;
|
||||||
|
if (!assessmentId) {
|
||||||
|
throw new Error("无法定位测评ID");
|
||||||
|
}
|
||||||
|
const reportData = await loadSasReportData(assessmentId);
|
||||||
|
if (this.sasExportForm.format === 'word') {
|
||||||
|
await SASReportGenerator.exportWord(reportData, false);
|
||||||
|
} else {
|
||||||
|
await SASReportGenerator.print(reportData, false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async exportQuestionnaireReport() {
|
||||||
|
// 获取问卷报告数据(后端已生成完整的HTML,包含评语)
|
||||||
|
const response = await getReport(this.sasTarget.reportId, 'questionnaire');
|
||||||
|
if (!response || !response.data) {
|
||||||
|
throw new Error("获取报告内容失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
const report = response.data;
|
||||||
|
console.log('问卷报告数据:', report);
|
||||||
|
|
||||||
|
// 直接使用后端生成的报告内容(已包含评语)
|
||||||
|
const reportHtml = `
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>${report.reportTitle || '问卷报告'}</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: 'Microsoft Yahei', sans-serif; padding: 32px; color: #303133; }
|
||||||
|
h1, h2 { text-align: center; margin: 16px 0; }
|
||||||
|
.section { margin-top: 24px; }
|
||||||
|
.report-info { margin: 5px 0; color: #606266; }
|
||||||
|
table.score-table { width: 100%; border-collapse: collapse; margin: 20px 0; }
|
||||||
|
table.score-table td, table.score-table th { border: 1px solid #ddd; padding: 10px; font-size: 14px; }
|
||||||
|
table.score-table th { background-color: #f5f7fa; font-weight: bold; }
|
||||||
|
.content { margin-top: 24px; line-height: 1.8; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
${report.reportContent || '暂无报告内容'}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
|
||||||
|
if (this.sasExportForm.format === 'word') {
|
||||||
|
// 导出为Word
|
||||||
|
const blob = new Blob(['\ufeff', reportHtml], { type: 'application/msword' });
|
||||||
|
const filename = `${report.reportTitle || '问卷报告'}_${Date.now()}.doc`;
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = window.URL.createObjectURL(blob);
|
||||||
|
link.download = filename;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
} else {
|
||||||
|
// 打印
|
||||||
|
const printWindow = window.open('', '_blank');
|
||||||
|
printWindow.document.write(reportHtml);
|
||||||
|
printWindow.document.close();
|
||||||
|
printWindow.focus();
|
||||||
|
printWindow.print();
|
||||||
|
}
|
||||||
|
},
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
handleDelete(row) {
|
handleDelete(row) {
|
||||||
let reportIds;
|
let reportIds;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user