Compare commits
2 Commits
5f9bcfc9b2
...
bbcf68bdb8
| Author | SHA1 | Date | |
|---|---|---|---|
| bbcf68bdb8 | |||
| f7f318bed8 |
@ -57,7 +57,7 @@ public class PrisonAreaController {
|
||||
@Operation(summary = "删除监区信息")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:area:delete')")
|
||||
public CommonResult<Boolean> deleteArea(@RequestParam("id") Long id) {
|
||||
public CommonResult<Boolean> deleteArea(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
areaService.deleteArea(id);
|
||||
return success(true);
|
||||
}
|
||||
@ -65,8 +65,8 @@ public class PrisonAreaController {
|
||||
@DeleteMapping("/delete-list")
|
||||
@Parameter(name = "ids", description = "编号", required = true)
|
||||
@Operation(summary = "批量删除监区信息")
|
||||
@PreAuthorize("@ss.hasPermission('prison:area:delete')")
|
||||
public CommonResult<Boolean> deleteAreaList(@RequestParam("ids") List<Long> ids) {
|
||||
@PreAuthorize("@ss.hasPermission('prison:area:delete')")
|
||||
public CommonResult<Boolean> deleteAreaList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
areaService.deleteAreaListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
@ -97,7 +97,7 @@ public class PrisonAreaController {
|
||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<AreaDO> list = areaService.getAreaPage(pageReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "监区信息.xls", "数据", AreaRespVO.class,
|
||||
ExcelUtils.write(response, "监区信息.xlsx", "数据", AreaRespVO.class,
|
||||
BeanUtils.toBean(list, AreaRespVO.class));
|
||||
}
|
||||
|
||||
|
||||
@ -13,28 +13,28 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
|
||||
@Data
|
||||
public class AreaPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "监区名称", example = "李四")
|
||||
@Schema(description = "监区名称", example = "第一监区")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "监区编码")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "监区类型:1-普通监区 2-严管监区 3-医院 4-禁闭室", example = "1")
|
||||
@Schema(description = "监区类型:1-普通监区 2-严管监区 3-集训监区 4-出监监区 5-医院 6-禁闭室", example = "1")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "容纳人数")
|
||||
private Integer capacity;
|
||||
|
||||
@Schema(description = "当前人数", example = "26596")
|
||||
@Schema(description = "当前人数", example = "100")
|
||||
private Integer currentCount;
|
||||
|
||||
@Schema(description = "排序")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "状态:1-启用 2-禁用", example = "2")
|
||||
@Schema(description = "状态:1-启用 2-禁用", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "你猜")
|
||||
@Schema(description = "备注", example = "正常运行的监区")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
|
||||
@ -6,6 +6,7 @@ import java.util.*;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import cn.idev.excel.annotation.*;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
@Schema(description = "管理后台 - 监区信息 Response VO")
|
||||
@Data
|
||||
@ -16,7 +17,7 @@ public class AreaRespVO {
|
||||
@ExcelProperty("监区ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "监区名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
|
||||
@Schema(description = "监区名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "第一监区")
|
||||
@ExcelProperty("监区名称")
|
||||
private String name;
|
||||
|
||||
@ -40,7 +41,7 @@ public class AreaRespVO {
|
||||
@ExcelProperty("容纳人数")
|
||||
private Integer capacity;
|
||||
|
||||
@Schema(description = "当前人数", example = "26596")
|
||||
@Schema(description = "当前人数", example = "100")
|
||||
@ExcelProperty("当前人数")
|
||||
private Integer currentCount;
|
||||
|
||||
@ -48,11 +49,11 @@ public class AreaRespVO {
|
||||
@ExcelProperty("排序")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "状态:1-启用 2-禁用", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@Schema(description = "状态:1-启用 2-禁用", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty("状态:1-启用 2-禁用")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "你猜")
|
||||
@Schema(description = "备注", example = "正常运行的监区")
|
||||
@ExcelProperty("备注")
|
||||
private String remark;
|
||||
|
||||
@ -61,6 +62,7 @@ public class AreaRespVO {
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "子监区列表,仅一级监区返回")
|
||||
@JsonIgnore
|
||||
private List<AreaRespVO> children;
|
||||
|
||||
}
|
||||
@ -12,7 +12,7 @@ public class AreaSaveReqVO {
|
||||
@Schema(description = "监区ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "19443")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "监区名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
|
||||
@Schema(description = "监区名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "第一监区")
|
||||
@NotEmpty(message = "监区名称不能为空")
|
||||
private String name;
|
||||
|
||||
@ -24,25 +24,30 @@ public class AreaSaveReqVO {
|
||||
private Long parentId;
|
||||
|
||||
@Schema(description = "级别:1-监区(大队) 2-分监区(中队)")
|
||||
@NotNull(message = "级别不能为空")
|
||||
private Integer level;
|
||||
|
||||
@Schema(description = "监区类型:1-普通监区 2-严管监区 3-集训监区 4-出监监区 5-医院 6-禁闭室", example = "1")
|
||||
@NotNull(message = "监区类型不能为空")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "容纳人数")
|
||||
@Min(value = 0, message = "容纳人数不能为负数")
|
||||
private Integer capacity;
|
||||
|
||||
@Schema(description = "当前人数", example = "26596")
|
||||
@Schema(description = "当前人数", example = "100")
|
||||
@Min(value = 0, message = "当前人数不能为负数")
|
||||
private Integer currentCount;
|
||||
|
||||
@Schema(description = "排序")
|
||||
@Min(value = 0, message = "排序不能为负数")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "状态:1-启用 2-禁用", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@Schema(description = "状态:1-启用 2-禁用", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "状态:1-启用 2-禁用不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "你猜")
|
||||
@Schema(description = "备注", example = "正常运行的监区")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@ -0,0 +1,145 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
import jakarta.validation.*;
|
||||
import jakarta.servlet.http.*;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
|
||||
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentAnswerDO;
|
||||
import cn.iocoder.yudao.module.prison.service.assessment.AssessmentAnswerService;
|
||||
|
||||
@Tag(name = "管理后台 - 答卷详情")
|
||||
@RestController
|
||||
@RequestMapping("/prison/assessment-answer")
|
||||
@Validated
|
||||
public class AssessmentAnswerController {
|
||||
|
||||
@Resource
|
||||
private AssessmentAnswerService assessmentAnswerService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建答卷")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-answer:create')")
|
||||
public CommonResult<Long> createAssessmentAnswer(@Valid @RequestBody AssessmentAnswerSaveReqVO createReqVO) {
|
||||
return success(assessmentAnswerService.createAssessmentAnswer(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新答卷")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-answer:update')")
|
||||
public CommonResult<Boolean> updateAssessmentAnswer(@Valid @RequestBody AssessmentAnswerSaveReqVO updateReqVO) {
|
||||
assessmentAnswerService.updateAssessmentAnswer(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除答卷")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-answer:delete')")
|
||||
public CommonResult<Boolean> deleteAssessmentAnswer(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
assessmentAnswerService.deleteAssessmentAnswer(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete-list")
|
||||
@Operation(summary = "批量删除答卷")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-answer:delete')")
|
||||
public CommonResult<Boolean> deleteAssessmentAnswerList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
assessmentAnswerService.deleteAssessmentAnswerListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得答卷")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-answer:query')")
|
||||
public CommonResult<AssessmentAnswerRespVO> getAssessmentAnswer(@RequestParam("id") Long id) {
|
||||
AssessmentAnswerDO assessmentAnswer = assessmentAnswerService.getAssessmentAnswer(id);
|
||||
return success(BeanUtils.toBean(assessmentAnswer, AssessmentAnswerRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得答卷分页")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-answer:query')")
|
||||
public CommonResult<PageResult<AssessmentAnswerRespVO>> getAssessmentAnswerPage(@Valid AssessmentAnswerPageReqVO pageReqVO) {
|
||||
PageResult<AssessmentAnswerDO> pageResult = assessmentAnswerService.getAssessmentAnswerPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, AssessmentAnswerRespVO.class));
|
||||
}
|
||||
|
||||
@PostMapping("/start")
|
||||
@Operation(summary = "开始答题")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-answer:create')")
|
||||
public CommonResult<Long> startAnswer(@RequestParam("assessmentRecordId") Long assessmentRecordId,
|
||||
@RequestParam("prisonerId") Long prisonerId) {
|
||||
return success(assessmentAnswerService.startAnswer(assessmentRecordId, prisonerId));
|
||||
}
|
||||
|
||||
@PostMapping("/submit")
|
||||
@Operation(summary = "提交答卷")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-answer:update')")
|
||||
public CommonResult<Boolean> submitAnswer(@Valid @RequestBody AssessmentAnswerSubmitReqVO submitReqVO) {
|
||||
assessmentAnswerService.submitAnswer(submitReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/pending-score-page")
|
||||
@Operation(summary = "获取待评分答卷列表")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-answer:query')")
|
||||
public CommonResult<PageResult<AssessmentAnswerRespVO>> getPendingScorePage(@Valid AssessmentAnswerPageReqVO pageReqVO) {
|
||||
PageResult<AssessmentAnswerDO> pageResult = assessmentAnswerService.getPendingScorePage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, AssessmentAnswerRespVO.class));
|
||||
}
|
||||
|
||||
@PostMapping("/manual-score")
|
||||
@Operation(summary = "人工评分")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-answer:update')")
|
||||
public CommonResult<Boolean> manualScore(@Valid @RequestBody AssessmentAnswerManualScoreReqVO scoreReqVO) {
|
||||
assessmentAnswerService.manualScore(scoreReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get-by-prisoner")
|
||||
@Operation(summary = "根据囚犯ID和测评记录ID获取答卷")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-answer:query')")
|
||||
public CommonResult<AssessmentAnswerRespVO> getByPrisonerAndRecord(
|
||||
@RequestParam("prisonerId") Long prisonerId,
|
||||
@RequestParam("assessmentRecordId") Long assessmentRecordId) {
|
||||
AssessmentAnswerDO assessmentAnswer = assessmentAnswerService.getByPrisonerAndRecord(prisonerId, assessmentRecordId);
|
||||
return success(BeanUtils.toBean(assessmentAnswer, AssessmentAnswerRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出答卷 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-answer:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportAssessmentAnswerExcel(@Valid AssessmentAnswerPageReqVO pageReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<AssessmentAnswerDO> list = assessmentAnswerService.getAssessmentAnswerPage(pageReqVO).getList();
|
||||
ExcelUtils.write(response, "答卷详情.xls", "数据", AssessmentAnswerRespVO.class,
|
||||
BeanUtils.toBean(list, AssessmentAnswerRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,134 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
import jakarta.validation.*;
|
||||
import jakarta.servlet.http.*;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
|
||||
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentRecordDO;
|
||||
import cn.iocoder.yudao.module.prison.service.assessment.AssessmentRecordService;
|
||||
|
||||
@Tag(name = "管理后台 - 测评记录")
|
||||
@RestController
|
||||
@RequestMapping("/prison/assessment-record")
|
||||
@Validated
|
||||
public class AssessmentRecordController {
|
||||
|
||||
@Resource
|
||||
private AssessmentRecordService assessmentRecordService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建测评记录")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-record:create')")
|
||||
public CommonResult<Long> createAssessmentRecord(@Valid @RequestBody AssessmentRecordSaveReqVO createReqVO) {
|
||||
return success(assessmentRecordService.createAssessmentRecord(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新测评记录")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-record:update')")
|
||||
public CommonResult<Boolean> updateAssessmentRecord(@Valid @RequestBody AssessmentRecordSaveReqVO updateReqVO) {
|
||||
assessmentRecordService.updateAssessmentRecord(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除测评记录")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-record:delete')")
|
||||
public CommonResult<Boolean> deleteAssessmentRecord(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
assessmentRecordService.deleteAssessmentRecord(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete-list")
|
||||
@Operation(summary = "批量删除测评记录")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-record:delete')")
|
||||
public CommonResult<Boolean> deleteAssessmentRecordList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
assessmentRecordService.deleteAssessmentRecordListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得测评记录")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-record:query')")
|
||||
public CommonResult<AssessmentRecordRespVO> getAssessmentRecord(@RequestParam("id") Long id) {
|
||||
AssessmentRecordDO assessmentRecord = assessmentRecordService.getAssessmentRecord(id);
|
||||
return success(BeanUtils.toBean(assessmentRecord, AssessmentRecordRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得测评记录分页")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-record:query')")
|
||||
public CommonResult<PageResult<AssessmentRecordRespVO>> getAssessmentRecordPage(@Valid AssessmentRecordPageReqVO pageReqVO) {
|
||||
PageResult<AssessmentRecordDO> pageResult = assessmentRecordService.getAssessmentRecordPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, AssessmentRecordRespVO.class));
|
||||
}
|
||||
|
||||
@PostMapping("/initiate")
|
||||
@Operation(summary = "发起测评")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-record:create')")
|
||||
public CommonResult<Long> initiateAssessment(@Valid @RequestBody AssessmentRecordSaveReqVO reqVO) {
|
||||
return success(assessmentRecordService.initiateAssessment(reqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/cancel")
|
||||
@Operation(summary = "取消测评")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-record:update')")
|
||||
public CommonResult<Boolean> cancelAssessment(@RequestParam("id") Long id) {
|
||||
assessmentRecordService.cancelAssessment(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/start")
|
||||
@Operation(summary = "启动测评")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-record:update')")
|
||||
public CommonResult<Boolean> startAssessment(@RequestParam("id") Long id) {
|
||||
assessmentRecordService.startAssessment(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/finish")
|
||||
@Operation(summary = "结束测评")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-record:update')")
|
||||
public CommonResult<Boolean> finishAssessment(@RequestParam("id") Long id) {
|
||||
assessmentRecordService.finishAssessment(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出测评记录 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-record:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportAssessmentRecordExcel(@Valid AssessmentRecordPageReqVO pageReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<AssessmentRecordDO> list = assessmentRecordService.getAssessmentRecordPage(pageReqVO).getList();
|
||||
ExcelUtils.write(response, "测评记录.xls", "数据", AssessmentRecordRespVO.class,
|
||||
BeanUtils.toBean(list, AssessmentRecordRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,143 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
import jakarta.validation.*;
|
||||
import jakarta.servlet.http.*;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
|
||||
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentResultDO;
|
||||
import cn.iocoder.yudao.module.prison.service.assessment.AssessmentResultService;
|
||||
|
||||
@Tag(name = "管理后台 - 测评结果")
|
||||
@RestController
|
||||
@RequestMapping("/prison/assessment-result")
|
||||
@Validated
|
||||
public class AssessmentResultController {
|
||||
|
||||
@Resource
|
||||
private AssessmentResultService assessmentResultService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建测评结果")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-result:create')")
|
||||
public CommonResult<Long> createAssessmentResult(@Valid @RequestBody AssessmentResultSaveReqVO createReqVO) {
|
||||
return success(assessmentResultService.createAssessmentResult(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新测评结果")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-result:update')")
|
||||
public CommonResult<Boolean> updateAssessmentResult(@Valid @RequestBody AssessmentResultSaveReqVO updateReqVO) {
|
||||
assessmentResultService.updateAssessmentResult(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除测评结果")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-result:delete')")
|
||||
public CommonResult<Boolean> deleteAssessmentResult(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
assessmentResultService.deleteAssessmentResult(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete-list")
|
||||
@Operation(summary = "批量删除测评结果")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-result:delete')")
|
||||
public CommonResult<Boolean> deleteAssessmentResultList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
assessmentResultService.deleteAssessmentResultListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得测评结果")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-result:query')")
|
||||
public CommonResult<AssessmentResultRespVO> getAssessmentResult(@RequestParam("id") Long id) {
|
||||
AssessmentResultDO assessmentResult = assessmentResultService.getAssessmentResult(id);
|
||||
return success(BeanUtils.toBean(assessmentResult, AssessmentResultRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得测评结果分页")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-result:query')")
|
||||
public CommonResult<PageResult<AssessmentResultRespVO>> getAssessmentResultPage(@Valid AssessmentResultPageReqVO pageReqVO) {
|
||||
PageResult<AssessmentResultDO> pageResult = assessmentResultService.getAssessmentResultPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, AssessmentResultRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/list-by-answer")
|
||||
@Operation(summary = "根据答卷ID获取所有结果")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-result:query')")
|
||||
public CommonResult<List<AssessmentResultRespVO>> getResultsByAnswerId(@RequestParam("answerId") Long answerId) {
|
||||
List<AssessmentResultDO> results = assessmentResultService.getResultsByAnswerId(answerId);
|
||||
return success(BeanUtils.toBean(results, AssessmentResultRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/list-by-assessment-record")
|
||||
@Operation(summary = "根据测评记录ID获取所有结果")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-result:query')")
|
||||
public CommonResult<List<AssessmentResultRespVO>> getResultsByAssessmentRecordId(@RequestParam("assessmentRecordId") Long assessmentRecordId) {
|
||||
List<AssessmentResultDO> results = assessmentResultService.getResultsByAssessmentRecordId(assessmentRecordId);
|
||||
return success(BeanUtils.toBean(results, AssessmentResultRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/need-manual-review")
|
||||
@Operation(summary = "获取需要人工评阅的结果列表")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-result:query')")
|
||||
public CommonResult<List<AssessmentResultRespVO>> getNeedManualReviewList() {
|
||||
List<AssessmentResultDO> results = assessmentResultService.getNeedManualReviewList();
|
||||
return success(BeanUtils.toBean(results, AssessmentResultRespVO.class));
|
||||
}
|
||||
|
||||
@PostMapping("/manual-review")
|
||||
@Operation(summary = "人工评阅")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-result:update')")
|
||||
public CommonResult<Boolean> manualReview(@Valid @RequestBody AssessmentResultManualReviewReqVO reviewReqVO) {
|
||||
assessmentResultService.manualReview(reviewReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/auto-score")
|
||||
@Operation(summary = "自动评分")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-result:update')")
|
||||
public CommonResult<Boolean> autoScore(@RequestParam("answerId") Long answerId) {
|
||||
assessmentResultService.autoScore(answerId);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出测评结果 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-result:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportAssessmentResultExcel(@Valid AssessmentResultPageReqVO pageReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<AssessmentResultDO> list = assessmentResultService.getAssessmentResultPage(pageReqVO).getList();
|
||||
ExcelUtils.write(response, "测评结果.xls", "数据", AssessmentResultRespVO.class,
|
||||
BeanUtils.toBean(list, AssessmentResultRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
import jakarta.validation.*;
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentStatisticsDO;
|
||||
import cn.iocoder.yudao.module.prison.service.assessment.AssessmentStatisticsService;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
||||
@Tag(name = "管理后台 - 测评统计")
|
||||
@RestController
|
||||
@RequestMapping("/prison/assessment-statistics")
|
||||
@Validated
|
||||
public class AssessmentStatisticsController {
|
||||
|
||||
@Resource
|
||||
private AssessmentStatisticsService assessmentStatisticsService;
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得测评统计")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-statistics:query')")
|
||||
public CommonResult<AssessmentStatisticsRespVO> getAssessmentStatistics(@RequestParam("id") Long id) {
|
||||
AssessmentStatisticsDO statistics = assessmentStatisticsService.getAssessmentStatistics(id);
|
||||
return success(BeanUtils.toBean(statistics, AssessmentStatisticsRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得测评统计分页")
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-statistics:query')")
|
||||
public CommonResult<PageResult<AssessmentStatisticsRespVO>> getAssessmentStatisticsPage(@Valid AssessmentStatisticsPageReqVO pageReqVO) {
|
||||
PageResult<AssessmentStatisticsDO> pageResult = assessmentStatisticsService.getAssessmentStatisticsPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, AssessmentStatisticsRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/generate")
|
||||
@Operation(summary = "生成测评统计")
|
||||
@Parameter(name = "assessmentRecordId", description = "测评记录ID", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-statistics:create')")
|
||||
public CommonResult<AssessmentStatisticsRespVO> generateStatistics(@RequestParam("assessmentRecordId") Long assessmentRecordId) {
|
||||
AssessmentStatisticsDO statistics = assessmentStatisticsService.generateStatistics(assessmentRecordId);
|
||||
return success(BeanUtils.toBean(statistics, AssessmentStatisticsRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/completion-rate")
|
||||
@Operation(summary = "获取测评完成率")
|
||||
@Parameter(name = "assessmentRecordId", description = "测评记录ID", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-statistics:query')")
|
||||
public CommonResult<BigDecimal> getCompletionRate(@RequestParam("assessmentRecordId") Long assessmentRecordId) {
|
||||
return success(assessmentStatisticsService.getCompletionRate(assessmentRecordId));
|
||||
}
|
||||
|
||||
@GetMapping("/score-distribution")
|
||||
@Operation(summary = "获取分数分布")
|
||||
@Parameter(name = "assessmentRecordId", description = "测评记录ID", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-statistics:query')")
|
||||
public CommonResult<Map<String, Integer>> getScoreDistribution(@RequestParam("assessmentRecordId") Long assessmentRecordId) {
|
||||
return success(assessmentStatisticsService.getScoreDistribution(assessmentRecordId));
|
||||
}
|
||||
|
||||
@GetMapping("/risk-distribution")
|
||||
@Operation(summary = "获取风险分布")
|
||||
@Parameter(name = "assessmentRecordId", description = "测评记录ID", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-statistics:query')")
|
||||
public CommonResult<Map<String, Integer>> getRiskDistribution(@RequestParam("assessmentRecordId") Long assessmentRecordId) {
|
||||
return success(assessmentStatisticsService.getRiskDistribution(assessmentRecordId));
|
||||
}
|
||||
|
||||
@GetMapping("/report")
|
||||
@Operation(summary = "获取测评分析报告")
|
||||
@Parameter(name = "assessmentRecordId", description = "测评记录ID", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:assessment-statistics:query')")
|
||||
public CommonResult<AssessmentReportRespVO> getAssessmentReport(@RequestParam("assessmentRecordId") Long assessmentRecordId) {
|
||||
return success(assessmentStatisticsService.getAssessmentReport(assessmentRecordId));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 人工评分 Request VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class AssessmentAnswerManualScoreReqVO {
|
||||
|
||||
@Schema(description = "答卷ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "答卷ID不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "主观题得分", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "主观题得分不能为空")
|
||||
private BigDecimal subjectiveScore;
|
||||
|
||||
@Schema(description = "评语")
|
||||
private String comment;
|
||||
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
|
||||
/**
|
||||
* 答卷详情分页查询 Request VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AssessmentAnswerPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "关联测评记录ID")
|
||||
private Long assessmentRecordId;
|
||||
|
||||
@Schema(description = "囚犯ID")
|
||||
private Long prisonerId;
|
||||
|
||||
@Schema(description = "囚犯编号")
|
||||
private String prisonerCode;
|
||||
|
||||
@Schema(description = "囚犯姓名")
|
||||
private String prisonerName;
|
||||
|
||||
@Schema(description = "监区ID")
|
||||
private Long areaId;
|
||||
|
||||
@Schema(description = "监室ID")
|
||||
private Long cellId;
|
||||
|
||||
@Schema(description = "答卷状态:1-待答题 2-答题中 3-已提交 4-已评分 5-已完成")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "开始答题时间")
|
||||
private LocalDateTime[] startTime;
|
||||
|
||||
@Schema(description = "提交时间")
|
||||
private LocalDateTime[] submitTime;
|
||||
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 答卷详情 Response VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AssessmentAnswerRespVO {
|
||||
|
||||
@Schema(description = "答卷ID", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "关联测评记录ID")
|
||||
private Long assessmentRecordId;
|
||||
|
||||
@Schema(description = "测评名称")
|
||||
private String assessmentName;
|
||||
|
||||
@Schema(description = "囚犯ID")
|
||||
private Long prisonerId;
|
||||
|
||||
@Schema(description = "囚犯编号")
|
||||
private String prisonerCode;
|
||||
|
||||
@Schema(description = "囚犯姓名")
|
||||
private String prisonerName;
|
||||
|
||||
@Schema(description = "监区ID")
|
||||
private Long areaId;
|
||||
|
||||
@Schema(description = "监区名称")
|
||||
private String areaName;
|
||||
|
||||
@Schema(description = "监室ID")
|
||||
private Long cellId;
|
||||
|
||||
@Schema(description = "监室名称")
|
||||
private String cellName;
|
||||
|
||||
@Schema(description = "答卷状态:1-待答题 2-答题中 3-已提交 4-已评分 5-已完成")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "开始答题时间")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@Schema(description = "提交时间")
|
||||
private LocalDateTime submitTime;
|
||||
|
||||
@Schema(description = "答题用时(秒)")
|
||||
private Integer duration;
|
||||
|
||||
@Schema(description = "客观题得分")
|
||||
private BigDecimal objectiveScore;
|
||||
|
||||
@Schema(description = "主观题得分")
|
||||
private BigDecimal subjectiveScore;
|
||||
|
||||
@Schema(description = "总分")
|
||||
private BigDecimal totalScore;
|
||||
|
||||
@Schema(description = "是否及格")
|
||||
private Boolean passed;
|
||||
|
||||
@Schema(description = "评语")
|
||||
private String comment;
|
||||
|
||||
@Schema(description = "评卷人ID")
|
||||
private Long scorerId;
|
||||
|
||||
@Schema(description = "评卷人名称")
|
||||
private String scorerName;
|
||||
|
||||
@Schema(description = "评分时间")
|
||||
private LocalDateTime scoreTime;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 答卷详情创建/更新 Request VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AssessmentAnswerSaveReqVO {
|
||||
|
||||
@Schema(description = "答卷ID", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "关联测评记录ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "测评记录不能为空")
|
||||
private Long assessmentRecordId;
|
||||
|
||||
@Schema(description = "囚犯ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "囚犯不能为空")
|
||||
private Long prisonerId;
|
||||
|
||||
@Schema(description = "囚犯编号")
|
||||
private String prisonerCode;
|
||||
|
||||
@Schema(description = "囚犯姓名")
|
||||
private String prisonerName;
|
||||
|
||||
@Schema(description = "监区ID")
|
||||
private Long areaId;
|
||||
|
||||
@Schema(description = "监区名称")
|
||||
private String areaName;
|
||||
|
||||
@Schema(description = "监室ID")
|
||||
private Long cellId;
|
||||
|
||||
@Schema(description = "监室名称")
|
||||
private String cellName;
|
||||
|
||||
@Schema(description = "答卷状态:1-待答题 2-答题中 3-已提交 4-已评分 5-已完成")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "开始答题时间")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@Schema(description = "提交时间")
|
||||
private LocalDateTime submitTime;
|
||||
|
||||
@Schema(description = "答题用时(秒)")
|
||||
private Integer duration;
|
||||
|
||||
@Schema(description = "客观题得分")
|
||||
private BigDecimal objectiveScore;
|
||||
|
||||
@Schema(description = "主观题得分")
|
||||
private BigDecimal subjectiveScore;
|
||||
|
||||
@Schema(description = "总分")
|
||||
private BigDecimal totalScore;
|
||||
|
||||
@Schema(description = "是否及格")
|
||||
private Boolean passed;
|
||||
|
||||
@Schema(description = "评语")
|
||||
private String comment;
|
||||
|
||||
@Schema(description = "及格分数")
|
||||
private BigDecimal passScore;
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 答卷提交 Request VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class AssessmentAnswerSubmitReqVO {
|
||||
|
||||
@Schema(description = "答卷ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "答卷ID不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "答题详情JSON")
|
||||
private String answers;
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
|
||||
/**
|
||||
* 测评记录分页查询 Request VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AssessmentRecordPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "测评名称", example = "心理测评")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "关联问卷模板ID")
|
||||
private Long questionnaireId;
|
||||
|
||||
@Schema(description = "测评类型:1-心理测评 2-行为评估 3-满意度调查")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "发起测评的监狱/监区ID")
|
||||
private Long areaId;
|
||||
|
||||
@Schema(description = "测评状态:1-未开始 2-进行中 3-已完成 4-已取消")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "计划开始时间")
|
||||
private LocalDateTime[] planStartTime;
|
||||
|
||||
@Schema(description = "计划结束时间")
|
||||
private LocalDateTime[] planEndTime;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 测评记录 Response VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AssessmentRecordRespVO {
|
||||
|
||||
@Schema(description = "测评记录ID", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "测评名称", example = "心理测评")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "关联问卷模板ID")
|
||||
private Long questionnaireId;
|
||||
|
||||
@Schema(description = "问卷模板名称")
|
||||
private String questionnaireName;
|
||||
|
||||
@Schema(description = "测评类型:1-心理测评 2-行为评估 3-满意度调查")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "发起测评的监狱/监区ID")
|
||||
private Long areaId;
|
||||
|
||||
@Schema(description = "发起测评的监狱/监区名称")
|
||||
private String areaName;
|
||||
|
||||
@Schema(description = "发起人ID")
|
||||
private Long initiatorId;
|
||||
|
||||
@Schema(description = "发起人名称")
|
||||
private String initiatorName;
|
||||
|
||||
@Schema(description = "测评状态:1-未开始 2-进行中 3-已完成 4-已取消")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "计划开始时间")
|
||||
private LocalDateTime planStartTime;
|
||||
|
||||
@Schema(description = "计划结束时间")
|
||||
private LocalDateTime planEndTime;
|
||||
|
||||
@Schema(description = "实际开始时间")
|
||||
private LocalDateTime actualStartTime;
|
||||
|
||||
@Schema(description = "实际结束时间")
|
||||
private LocalDateTime actualEndTime;
|
||||
|
||||
@Schema(description = "参与人数")
|
||||
private Integer participantCount;
|
||||
|
||||
@Schema(description = "完成人数")
|
||||
private Integer completedCount;
|
||||
|
||||
@Schema(description = "测评说明")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "是否启用自动评分")
|
||||
private Boolean enableAutoScore;
|
||||
|
||||
@Schema(description = "及格分数")
|
||||
private BigDecimal passScore;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 测评记录创建/更新 Request VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AssessmentRecordSaveReqVO {
|
||||
|
||||
@Schema(description = "测评记录ID", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "测评名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "心理测评")
|
||||
@NotNull(message = "测评名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "关联问卷模板ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "问卷模板不能为空")
|
||||
private Long questionnaireId;
|
||||
|
||||
@Schema(description = "测评类型:1-心理测评 2-行为评估 3-满意度调查", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "测评类型不能为空")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "发起测评的监狱/监区ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "监区不能为空")
|
||||
private Long areaId;
|
||||
|
||||
@Schema(description = "发起测评的监狱/监区名称")
|
||||
private String areaName;
|
||||
|
||||
@Schema(description = "发起人ID")
|
||||
private Long initiatorId;
|
||||
|
||||
@Schema(description = "发起人名称")
|
||||
private String initiatorName;
|
||||
|
||||
@Schema(description = "测评状态:1-未开始 2-进行中 3-已完成 4-已取消")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "计划开始时间")
|
||||
private LocalDateTime planStartTime;
|
||||
|
||||
@Schema(description = "计划结束时间")
|
||||
private LocalDateTime planEndTime;
|
||||
|
||||
@Schema(description = "测评说明")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "是否启用自动评分")
|
||||
private Boolean enableAutoScore;
|
||||
|
||||
@Schema(description = "及格分数")
|
||||
private BigDecimal passScore;
|
||||
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 测评分析报告 Response VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class AssessmentReportRespVO {
|
||||
|
||||
@Schema(description = "关联测评记录ID")
|
||||
private Long assessmentRecordId;
|
||||
|
||||
@Schema(description = "测评名称")
|
||||
private String assessmentName;
|
||||
|
||||
@Schema(description = "总参与人数")
|
||||
private Integer totalCount;
|
||||
|
||||
@Schema(description = "已完成人数")
|
||||
private Integer completedCount;
|
||||
|
||||
@Schema(description = "完成率(%)")
|
||||
private BigDecimal completionRate;
|
||||
|
||||
@Schema(description = "平均分")
|
||||
private BigDecimal averageScore;
|
||||
|
||||
@Schema(description = "最高分")
|
||||
private BigDecimal highestScore;
|
||||
|
||||
@Schema(description = "最低分")
|
||||
private BigDecimal lowestScore;
|
||||
|
||||
@Schema(description = "及格人数")
|
||||
private Integer passedCount;
|
||||
|
||||
@Schema(description = "及格率(%)")
|
||||
private BigDecimal passRate;
|
||||
|
||||
@Schema(description = "优秀人数(90分以上)")
|
||||
private Integer excellentCount;
|
||||
|
||||
@Schema(description = "优秀率(%)")
|
||||
private BigDecimal excellentRate;
|
||||
|
||||
@Schema(description = "风险人数(60分以下)")
|
||||
private Integer riskCount;
|
||||
|
||||
@Schema(description = "风险率(%)")
|
||||
private BigDecimal riskRate;
|
||||
|
||||
@Schema(description = "分数分布")
|
||||
private Map<String, Integer> scoreDistribution;
|
||||
|
||||
@Schema(description = "风险分布")
|
||||
private Map<String, Integer> riskDistribution;
|
||||
|
||||
@Schema(description = "分析建议")
|
||||
private String analysisSuggestion;
|
||||
|
||||
@Schema(description = "生成时间")
|
||||
private LocalDateTime generatedTime;
|
||||
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 人工评阅 Request VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class AssessmentResultManualReviewReqVO {
|
||||
|
||||
@Schema(description = "结果ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "结果ID不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "人工评分", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "评分不能为空")
|
||||
private BigDecimal manualScore;
|
||||
|
||||
@Schema(description = "人工评语")
|
||||
private String manualComment;
|
||||
|
||||
@Schema(description = "评阅人ID")
|
||||
private Long reviewerId;
|
||||
|
||||
@Schema(description = "评阅人名称")
|
||||
private String reviewerName;
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
|
||||
/**
|
||||
* 测评结果分页查询 Request VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AssessmentResultPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "关联答卷ID")
|
||||
private Long answerId;
|
||||
|
||||
@Schema(description = "关联测评记录ID")
|
||||
private Long assessmentRecordId;
|
||||
|
||||
@Schema(description = "囚犯ID")
|
||||
private Long prisonerId;
|
||||
|
||||
@Schema(description = "关联题目ID")
|
||||
private Long questionId;
|
||||
|
||||
@Schema(description = "题目类型:1-单选 2-多选 3-判断 4-填空 5-问答")
|
||||
private Integer questionType;
|
||||
|
||||
@Schema(description = "是否正确")
|
||||
private Boolean correct;
|
||||
|
||||
@Schema(description = "是否需要人工评阅")
|
||||
private Boolean needManualReview;
|
||||
|
||||
@Schema(description = "人工评阅状态:1-待评阅 2-已评阅")
|
||||
private Integer manualReviewStatus;
|
||||
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 测评结果 Response VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AssessmentResultRespVO {
|
||||
|
||||
@Schema(description = "结果ID", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "关联答卷ID")
|
||||
private Long answerId;
|
||||
|
||||
@Schema(description = "关联测评记录ID")
|
||||
private Long assessmentRecordId;
|
||||
|
||||
@Schema(description = "囚犯ID")
|
||||
private Long prisonerId;
|
||||
|
||||
@Schema(description = "囚犯编号")
|
||||
private String prisonerCode;
|
||||
|
||||
@Schema(description = "囚犯姓名")
|
||||
private String prisonerName;
|
||||
|
||||
@Schema(description = "关联题目ID")
|
||||
private Long questionId;
|
||||
|
||||
@Schema(description = "题目编号")
|
||||
private String questionCode;
|
||||
|
||||
@Schema(description = "题目内容")
|
||||
private String questionContent;
|
||||
|
||||
@Schema(description = "题目类型:1-单选 2-多选 3-判断 4-填空 5-问答")
|
||||
private Integer questionType;
|
||||
|
||||
@Schema(description = "题目分值")
|
||||
private BigDecimal questionScore;
|
||||
|
||||
@Schema(description = "囚犯答案")
|
||||
private String answer;
|
||||
|
||||
@Schema(description = "正确答案(客观题)")
|
||||
private String correctAnswer;
|
||||
|
||||
@Schema(description = "是否正确")
|
||||
private Boolean correct;
|
||||
|
||||
@Schema(description = "得分")
|
||||
private BigDecimal score;
|
||||
|
||||
@Schema(description = "是否需要人工评阅")
|
||||
private Boolean needManualReview;
|
||||
|
||||
@Schema(description = "人工评阅状态:1-待评阅 2-已评阅")
|
||||
private Integer manualReviewStatus;
|
||||
|
||||
@Schema(description = "人工评分")
|
||||
private BigDecimal manualScore;
|
||||
|
||||
@Schema(description = "人工评语")
|
||||
private String manualComment;
|
||||
|
||||
@Schema(description = "评阅人ID")
|
||||
private Long reviewerId;
|
||||
|
||||
@Schema(description = "评阅人名称")
|
||||
private String reviewerName;
|
||||
|
||||
@Schema(description = "评阅时间")
|
||||
private LocalDateTime reviewTime;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@ -0,0 +1,80 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 测评结果创建/更新 Request VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AssessmentResultSaveReqVO {
|
||||
|
||||
@Schema(description = "结果ID", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "关联答卷ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "答卷ID不能为空")
|
||||
private Long answerId;
|
||||
|
||||
@Schema(description = "关联测评记录ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "测评记录ID不能为空")
|
||||
private Long assessmentRecordId;
|
||||
|
||||
@Schema(description = "囚犯ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "囚犯ID不能为空")
|
||||
private Long prisonerId;
|
||||
|
||||
@Schema(description = "囚犯编号")
|
||||
private String prisonerCode;
|
||||
|
||||
@Schema(description = "囚犯姓名")
|
||||
private String prisonerName;
|
||||
|
||||
@Schema(description = "关联题目ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "题目ID不能为空")
|
||||
private Long questionId;
|
||||
|
||||
@Schema(description = "题目编号")
|
||||
private String questionCode;
|
||||
|
||||
@Schema(description = "题目内容")
|
||||
private String questionContent;
|
||||
|
||||
@Schema(description = "题目类型:1-单选 2-多选 3-判断 4-填空 5-问答")
|
||||
private Integer questionType;
|
||||
|
||||
@Schema(description = "题目分值")
|
||||
private BigDecimal questionScore;
|
||||
|
||||
@Schema(description = "囚犯答案")
|
||||
private String answer;
|
||||
|
||||
@Schema(description = "正确答案(客观题)")
|
||||
private String correctAnswer;
|
||||
|
||||
@Schema(description = "是否正确")
|
||||
private Boolean correct;
|
||||
|
||||
@Schema(description = "得分")
|
||||
private BigDecimal score;
|
||||
|
||||
@Schema(description = "是否需要人工评阅")
|
||||
private Boolean needManualReview;
|
||||
|
||||
@Schema(description = "人工评阅状态:1-待评阅 2-已评阅")
|
||||
private Integer manualReviewStatus;
|
||||
|
||||
@Schema(description = "人工评分")
|
||||
private BigDecimal manualScore;
|
||||
|
||||
@Schema(description = "人工评语")
|
||||
private String manualComment;
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
|
||||
/**
|
||||
* 测评统计分页查询 Request VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AssessmentStatisticsPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "关联测评记录ID")
|
||||
private Long assessmentRecordId;
|
||||
|
||||
@Schema(description = "测评名称")
|
||||
private String assessmentName;
|
||||
|
||||
}
|
||||
@ -0,0 +1,76 @@
|
||||
package cn.iocoder.yudao.module.prison.controller.admin.assessment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 测评统计 Response VO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AssessmentStatisticsRespVO {
|
||||
|
||||
@Schema(description = "统计ID", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "关联测评记录ID")
|
||||
private Long assessmentRecordId;
|
||||
|
||||
@Schema(description = "测评名称")
|
||||
private String assessmentName;
|
||||
|
||||
@Schema(description = "总参与人数")
|
||||
private Integer totalCount;
|
||||
|
||||
@Schema(description = "已完成人数")
|
||||
private Integer completedCount;
|
||||
|
||||
@Schema(description = "完成率")
|
||||
private BigDecimal completionRate;
|
||||
|
||||
@Schema(description = "平均分")
|
||||
private BigDecimal averageScore;
|
||||
|
||||
@Schema(description = "最高分")
|
||||
private BigDecimal highestScore;
|
||||
|
||||
@Schema(description = "最低分")
|
||||
private BigDecimal lowestScore;
|
||||
|
||||
@Schema(description = "及格人数")
|
||||
private Integer passedCount;
|
||||
|
||||
@Schema(description = "及格率")
|
||||
private BigDecimal passRate;
|
||||
|
||||
@Schema(description = "优秀人数(90分以上)")
|
||||
private Integer excellentCount;
|
||||
|
||||
@Schema(description = "优秀率")
|
||||
private BigDecimal excellentRate;
|
||||
|
||||
@Schema(description = "风险人数(60分以下)")
|
||||
private Integer riskCount;
|
||||
|
||||
@Schema(description = "风险率")
|
||||
private BigDecimal riskRate;
|
||||
|
||||
@Schema(description = "风险分布")
|
||||
private Map<String, Integer> riskDistribution;
|
||||
|
||||
@Schema(description = "分数分布")
|
||||
private Map<String, Integer> scoreDistribution;
|
||||
|
||||
@Schema(description = "统计时间")
|
||||
private LocalDateTime statisticsTime;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@ -9,6 +9,8 @@ import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
||||
import jakarta.validation.*;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.servlet.http.*;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
@ -61,7 +63,7 @@ public class PrisonCellController {
|
||||
@Operation(summary = "删除监室信息")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:cell:delete')")
|
||||
public CommonResult<Boolean> deleteCell(@RequestParam("id") Long id) {
|
||||
public CommonResult<Boolean> deleteCell(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
cellService.deleteCell(id);
|
||||
return success(true);
|
||||
}
|
||||
@ -69,8 +71,8 @@ public class PrisonCellController {
|
||||
@DeleteMapping("/delete-list")
|
||||
@Parameter(name = "ids", description = "编号", required = true)
|
||||
@Operation(summary = "批量删除监室信息")
|
||||
@PreAuthorize("@ss.hasPermission('prison:cell:delete')")
|
||||
public CommonResult<Boolean> deleteCellList(@RequestParam("ids") List<Long> ids) {
|
||||
@PreAuthorize("@ss.hasPermission('prison:cell:delete')")
|
||||
public CommonResult<Boolean> deleteCellList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
cellService.deleteCellListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
@ -111,7 +113,7 @@ public class PrisonCellController {
|
||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<CellRespVO> list = cellService.getCellPage(pageReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "监室信息.xls", "数据", CellRespVO.class, list);
|
||||
ExcelUtils.write(response, "监室信息.xlsx", "数据", CellRespVO.class, list);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ public class CellPageReqVO extends PageParam {
|
||||
@Schema(description = "所属监区ID", example = "9889")
|
||||
private Long areaId;
|
||||
|
||||
@Schema(description = "监室名称", example = "张三")
|
||||
@Schema(description = "监室名称", example = "101监室")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "监室编码")
|
||||
@ -25,7 +25,7 @@ public class CellPageReqVO extends PageParam {
|
||||
@Schema(description = "床位数量")
|
||||
private Integer capacity;
|
||||
|
||||
@Schema(description = "当前人数", example = "31423")
|
||||
@Schema(description = "当前人数", example = "5")
|
||||
private Integer currentCount;
|
||||
|
||||
@Schema(description = "排序")
|
||||
@ -34,11 +34,11 @@ public class CellPageReqVO extends PageParam {
|
||||
@Schema(description = "状态:1-启用 2-禁用", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "随便")
|
||||
@Schema(description = "备注", example = "正常使用的监室")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ public class CellSaveReqVO {
|
||||
@NotNull(message = "所属监区ID不能为空")
|
||||
private Long areaId;
|
||||
|
||||
@Schema(description = "监室名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
|
||||
@Schema(description = "监室名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "101监室")
|
||||
@NotEmpty(message = "监室名称不能为空")
|
||||
private String name;
|
||||
|
||||
@ -24,20 +24,25 @@ public class CellSaveReqVO {
|
||||
@NotEmpty(message = "监室编码不能为空")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "床位数量")
|
||||
@Schema(description = "床位数量", example = "10")
|
||||
@Min(value = 0, message = "床位数量不能小于0")
|
||||
private Integer capacity;
|
||||
|
||||
@Schema(description = "当前人数", example = "31423")
|
||||
@Schema(description = "当前人数", example = "5")
|
||||
@Min(value = 0, message = "当前人数不能小于0")
|
||||
private Integer currentCount;
|
||||
|
||||
@Schema(description = "排序")
|
||||
@Schema(description = "排序", example = "1")
|
||||
@Min(value = 0, message = "排序不能小于0")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "状态:1-启用 2-禁用", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "状态:1-启用 2-禁用不能为空")
|
||||
@Min(value = 1, message = "状态最小值为1")
|
||||
@Max(value = 2, message = "状态最大值为2")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "随便")
|
||||
@Schema(description = "备注", example = "正常使用的监室")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ public class PrisonConsumptionController {
|
||||
@Operation(summary = "删除消费记录")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:consumption:delete')")
|
||||
public CommonResult<Boolean> deleteConsumption(@RequestParam("id") Long id) {
|
||||
public CommonResult<Boolean> deleteConsumption(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
consumptionService.deleteConsumption(id);
|
||||
return success(true);
|
||||
}
|
||||
@ -66,7 +66,7 @@ public class PrisonConsumptionController {
|
||||
@Parameter(name = "ids", description = "编号", required = true)
|
||||
@Operation(summary = "批量删除消费记录")
|
||||
@PreAuthorize("@ss.hasPermission('prison:consumption:delete')")
|
||||
public CommonResult<Boolean> deleteConsumptionList(@RequestParam("ids") List<Long> ids) {
|
||||
public CommonResult<Boolean> deleteConsumptionList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
consumptionService.deleteConsumptionListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@ -22,6 +22,8 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -73,7 +75,7 @@ public class PrisonerController {
|
||||
@Operation(summary = "删除服刑人员")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:prisoner:delete')")
|
||||
public CommonResult<Boolean> deletePrisoner(@RequestParam("id") Long id) {
|
||||
public CommonResult<Boolean> deletePrisoner(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
prisonerService.deletePrisoner(id);
|
||||
return success(true);
|
||||
}
|
||||
@ -82,7 +84,7 @@ public class PrisonerController {
|
||||
@Operation(summary = "批量删除服刑人员")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:prisoner:delete')")
|
||||
public CommonResult<Boolean> deletePrisonerList(@RequestParam("ids") List<Long> ids) {
|
||||
public CommonResult<Boolean> deletePrisonerList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
prisonerService.deletePrisonerList(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@ import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@ -50,7 +52,7 @@ public class PrisonerAreaLogController {
|
||||
@Operation(summary = "删除罪犯监区变动记录")
|
||||
@Parameter(name = "id", description = "记录ID", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:prisoner-area-log:delete')")
|
||||
public CommonResult<Boolean> deletePrisonerAreaLog(@RequestParam("id") Long id) {
|
||||
public CommonResult<Boolean> deletePrisonerAreaLog(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
prisonerAreaLogService.deletePrisonerAreaLog(id);
|
||||
return success(true);
|
||||
}
|
||||
@ -58,7 +60,7 @@ public class PrisonerAreaLogController {
|
||||
@DeleteMapping("/delete-list")
|
||||
@Operation(summary = "批量删除罪犯监区变动记录")
|
||||
@PreAuthorize("@ss.hasPermission('prison:prisoner-area-log:delete')")
|
||||
public CommonResult<Boolean> deletePrisonerAreaLogList(@RequestParam("ids") List<Long> ids) {
|
||||
public CommonResult<Boolean> deletePrisonerAreaLogList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
prisonerAreaLogService.deletePrisonerAreaLogList(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ public class PrisonQuestionController {
|
||||
@Operation(summary = "删除问卷问题")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:question:delete')")
|
||||
public CommonResult<Boolean> deleteQuestion(@RequestParam("id") Long id) {
|
||||
public CommonResult<Boolean> deleteQuestion(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
questionService.deleteQuestion(id);
|
||||
return success(true);
|
||||
}
|
||||
@ -66,7 +66,7 @@ public class PrisonQuestionController {
|
||||
@Parameter(name = "ids", description = "编号", required = true)
|
||||
@Operation(summary = "批量删除问卷问题")
|
||||
@PreAuthorize("@ss.hasPermission('prison:question:delete')")
|
||||
public CommonResult<Boolean> deleteQuestionList(@RequestParam("ids") List<Long> ids) {
|
||||
public CommonResult<Boolean> deleteQuestionList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
questionService.deleteQuestionListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ public class PrisonQuestionnaireController {
|
||||
@Operation(summary = "删除问卷模板")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:questionnaire:delete')")
|
||||
public CommonResult<Boolean> deleteQuestionnaire(@RequestParam("id") Long id) {
|
||||
public CommonResult<Boolean> deleteQuestionnaire(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
questionnaireService.deleteQuestionnaire(id);
|
||||
return success(true);
|
||||
}
|
||||
@ -66,7 +66,7 @@ public class PrisonQuestionnaireController {
|
||||
@Parameter(name = "ids", description = "编号", required = true)
|
||||
@Operation(summary = "批量删除问卷模板")
|
||||
@PreAuthorize("@ss.hasPermission('prison:questionnaire:delete')")
|
||||
public CommonResult<Boolean> deleteQuestionnaireList(@RequestParam("ids") List<Long> ids) {
|
||||
public CommonResult<Boolean> deleteQuestionnaireList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
questionnaireService.deleteQuestionnaireListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@ -36,4 +36,21 @@ public class QuestionnairePageReqVO extends PageParam {
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
// ==================== 新增字段 ====================
|
||||
|
||||
@Schema(description = "封面图片URL")
|
||||
private String coverImage;
|
||||
|
||||
@Schema(description = "填写说明")
|
||||
private String instruction;
|
||||
|
||||
@Schema(description = "预计耗时(分钟)")
|
||||
private Integer estimatedTime;
|
||||
|
||||
@Schema(description = "分区数量")
|
||||
private Integer partCount;
|
||||
|
||||
@Schema(description = "是否允许匿名")
|
||||
private Boolean allowAnonymous;
|
||||
|
||||
}
|
||||
@ -45,4 +45,26 @@ public class QuestionnaireRespVO {
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
// ==================== 新增字段 ====================
|
||||
|
||||
@Schema(description = "封面图片URL")
|
||||
@ExcelProperty("封面图片URL")
|
||||
private String coverImage;
|
||||
|
||||
@Schema(description = "填写说明")
|
||||
@ExcelProperty("填写说明")
|
||||
private String instruction;
|
||||
|
||||
@Schema(description = "预计耗时(分钟)")
|
||||
@ExcelProperty("预计耗时(分钟)")
|
||||
private Integer estimatedTime;
|
||||
|
||||
@Schema(description = "分区数量")
|
||||
@ExcelProperty("分区数量")
|
||||
private Integer partCount;
|
||||
|
||||
@Schema(description = "是否允许匿名:false-不允许 true-允许")
|
||||
@ExcelProperty("是否允许匿名")
|
||||
private Boolean allowAnonymous;
|
||||
|
||||
}
|
||||
@ -31,7 +31,24 @@ public class QuestionnaireSaveReqVO {
|
||||
private BigDecimal passScore;
|
||||
|
||||
@Schema(description = "状态:1-草稿 2-已发布 3-已禁用", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@NotNull(message = "状态:1-草稿 2-已发布 3-已禁用不能为空")
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
// ==================== 新增字段 ====================
|
||||
|
||||
@Schema(description = "封面图片URL")
|
||||
private String coverImage;
|
||||
|
||||
@Schema(description = "填写说明")
|
||||
private String instruction;
|
||||
|
||||
@Schema(description = "预计耗时(分钟)")
|
||||
private Integer estimatedTime;
|
||||
|
||||
@Schema(description = "分区数量")
|
||||
private Integer partCount;
|
||||
|
||||
@Schema(description = "是否允许匿名:false-不允许 true-允许")
|
||||
private Boolean allowAnonymous;
|
||||
|
||||
}
|
||||
@ -57,7 +57,7 @@ public class PrisonQuestionnaireRecordController {
|
||||
@Operation(summary = "删除问卷答题记录")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:questionnaire-record:delete')")
|
||||
public CommonResult<Boolean> deleteQuestionnaireRecord(@RequestParam("id") Long id) {
|
||||
public CommonResult<Boolean> deleteQuestionnaireRecord(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
questionnaireRecordService.deleteQuestionnaireRecord(id);
|
||||
return success(true);
|
||||
}
|
||||
@ -66,7 +66,7 @@ public class PrisonQuestionnaireRecordController {
|
||||
@Parameter(name = "ids", description = "编号", required = true)
|
||||
@Operation(summary = "批量删除问卷答题记录")
|
||||
@PreAuthorize("@ss.hasPermission('prison:questionnaire-record:delete')")
|
||||
public CommonResult<Boolean> deleteQuestionnaireRecordList(@RequestParam("ids") List<Long> ids) {
|
||||
public CommonResult<Boolean> deleteQuestionnaireRecordList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
questionnaireRecordService.deleteQuestionnaireRecordListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@ -10,6 +10,8 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@ -50,7 +52,7 @@ public class ReleaseController {
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除释放登记")
|
||||
@PreAuthorize("@ss.hasPermission('prison:release:delete')")
|
||||
public CommonResult<Boolean> deleteRelease(@RequestParam("id") Long id) {
|
||||
public CommonResult<Boolean> deleteRelease(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
releaseService.deleteRelease(id);
|
||||
return success(true);
|
||||
}
|
||||
@ -58,7 +60,7 @@ public class ReleaseController {
|
||||
@DeleteMapping("/delete-list")
|
||||
@Operation(summary = "批量删除释放登记")
|
||||
@PreAuthorize("@ss.hasPermission('prison:release:delete')")
|
||||
public CommonResult<Boolean> deleteReleaseList(@RequestParam("ids") List<Long> ids) {
|
||||
public CommonResult<Boolean> deleteReleaseList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
releaseService.deleteReleaseListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ public class PrisonRiskAssessmentController {
|
||||
@Operation(summary = "删除危险评估")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:risk-assessment:delete')")
|
||||
public CommonResult<Boolean> deleteRiskAssessment(@RequestParam("id") Long id) {
|
||||
public CommonResult<Boolean> deleteRiskAssessment(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
riskAssessmentService.deleteRiskAssessment(id);
|
||||
return success(true);
|
||||
}
|
||||
@ -66,7 +66,7 @@ public class PrisonRiskAssessmentController {
|
||||
@Parameter(name = "ids", description = "编号", required = true)
|
||||
@Operation(summary = "批量删除危险评估")
|
||||
@PreAuthorize("@ss.hasPermission('prison:risk-assessment:delete')")
|
||||
public CommonResult<Boolean> deleteRiskAssessmentList(@RequestParam("ids") List<Long> ids) {
|
||||
public CommonResult<Boolean> deleteRiskAssessmentList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
riskAssessmentService.deleteRiskAssessmentListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ public class PrisonScoreController {
|
||||
@Operation(summary = "删除计分考核")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('prison:score:delete')")
|
||||
public CommonResult<Boolean> deleteScore(@RequestParam("id") Long id) {
|
||||
public CommonResult<Boolean> deleteScore(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
scoreService.deleteScore(id);
|
||||
return success(true);
|
||||
}
|
||||
@ -66,7 +66,7 @@ public class PrisonScoreController {
|
||||
@Parameter(name = "ids", description = "编号", required = true)
|
||||
@Operation(summary = "批量删除计分考核")
|
||||
@PreAuthorize("@ss.hasPermission('prison:score:delete')")
|
||||
public CommonResult<Boolean> deleteScoreList(@RequestParam("ids") List<Long> ids) {
|
||||
public CommonResult<Boolean> deleteScoreList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
scoreService.deleteScoreListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@ import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@ -50,7 +52,7 @@ public class ScoreDetailController {
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除考核记录")
|
||||
@PreAuthorize("@ss.hasPermission('prison:score-detail:delete')")
|
||||
public CommonResult<Boolean> deleteScoreDetail(@RequestParam("id") Long id) {
|
||||
public CommonResult<Boolean> deleteScoreDetail(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
scoreDetailService.deleteScoreDetail(id);
|
||||
return success(true);
|
||||
}
|
||||
@ -58,7 +60,7 @@ public class ScoreDetailController {
|
||||
@DeleteMapping("/delete-list")
|
||||
@Operation(summary = "批量删除考核记录")
|
||||
@PreAuthorize("@ss.hasPermission('prison:score-detail:delete')")
|
||||
public CommonResult<Boolean> deleteScoreDetailList(@RequestParam("ids") List<Long> ids) {
|
||||
public CommonResult<Boolean> deleteScoreDetailList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
scoreDetailService.deleteScoreDetailListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@ import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@ -50,7 +52,7 @@ public class ScoreRuleController {
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除考核规则")
|
||||
@PreAuthorize("@ss.hasPermission('prison:score-rule:delete')")
|
||||
public CommonResult<Boolean> deleteScoreRule(@RequestParam("id") Long id) {
|
||||
public CommonResult<Boolean> deleteScoreRule(@NotNull(message = "编号不能为空") @RequestParam("id") Long id) {
|
||||
scoreRuleService.deleteScoreRule(id);
|
||||
return success(true);
|
||||
}
|
||||
@ -58,7 +60,7 @@ public class ScoreRuleController {
|
||||
@DeleteMapping("/delete-list")
|
||||
@Operation(summary = "批量删除考核规则")
|
||||
@PreAuthorize("@ss.hasPermission('prison:score-rule:delete')")
|
||||
public CommonResult<Boolean> deleteScoreRuleList(@RequestParam("ids") List<Long> ids) {
|
||||
public CommonResult<Boolean> deleteScoreRuleList(@NotEmpty(message = "编号列表不能为空") @RequestParam("ids") List<Long> ids) {
|
||||
scoreRuleService.deleteScoreRuleListByIds(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.module.prison.convert.assessment;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentAnswerDO;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import org.mapstruct.Builder;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 答卷详情 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper(uses = {}, builder = @Builder())
|
||||
public interface AssessmentAnswerConvert {
|
||||
|
||||
AssessmentAnswerConvert INSTANCE = Mappers.getMapper(AssessmentAnswerConvert.class);
|
||||
|
||||
AssessmentAnswerDO convert(AssessmentAnswerSaveReqVO bean);
|
||||
|
||||
AssessmentAnswerSaveReqVO convert(AssessmentAnswerDO bean);
|
||||
|
||||
AssessmentAnswerRespVO convert(AssessmentAnswerDO bean);
|
||||
|
||||
List<AssessmentAnswerRespVO> convertList(List<AssessmentAnswerDO> list);
|
||||
|
||||
PageResult<AssessmentAnswerRespVO> convertPage(PageResult<AssessmentAnswerDO> page);
|
||||
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.module.prison.convert.assessment;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentRecordDO;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import org.mapstruct.Builder;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 测评记录 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper(uses = {}, builder = @Builder())
|
||||
public interface AssessmentRecordConvert {
|
||||
|
||||
AssessmentRecordConvert INSTANCE = Mappers.getMapper(AssessmentRecordConvert.class);
|
||||
|
||||
AssessmentRecordDO convert(AssessmentRecordSaveReqVO bean);
|
||||
|
||||
AssessmentRecordSaveReqVO convert(AssessmentRecordDO bean);
|
||||
|
||||
AssessmentRecordRespVO convert(AssessmentRecordDO bean);
|
||||
|
||||
List<AssessmentRecordRespVO> convertList(List<AssessmentRecordDO> list);
|
||||
|
||||
PageResult<AssessmentRecordRespVO> convertPage(PageResult<AssessmentRecordDO> page);
|
||||
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.module.prison.convert.assessment;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentResultDO;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import org.mapstruct.Builder;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 测评结果 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper(uses = {}, builder = @Builder())
|
||||
public interface AssessmentResultConvert {
|
||||
|
||||
AssessmentResultConvert INSTANCE = Mappers.getMapper(AssessmentResultConvert.class);
|
||||
|
||||
AssessmentResultDO convert(AssessmentResultSaveReqVO bean);
|
||||
|
||||
AssessmentResultSaveReqVO convert(AssessmentResultDO bean);
|
||||
|
||||
AssessmentResultRespVO convert(AssessmentResultDO bean);
|
||||
|
||||
List<AssessmentResultRespVO> convertList(List<AssessmentResultDO> list);
|
||||
|
||||
PageResult<AssessmentResultRespVO> convertPage(PageResult<AssessmentResultDO> page);
|
||||
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.prison.convert.assessment;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentStatisticsDO;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import org.mapstruct.Builder;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 测评统计 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper(uses = {}, builder = @Builder())
|
||||
public interface AssessmentStatisticsConvert {
|
||||
|
||||
AssessmentStatisticsConvert INSTANCE = Mappers.getMapper(AssessmentStatisticsConvert.class);
|
||||
|
||||
AssessmentStatisticsRespVO convert(AssessmentStatisticsDO bean);
|
||||
|
||||
List<AssessmentStatisticsRespVO> convertList(List<AssessmentStatisticsDO> list);
|
||||
|
||||
PageResult<AssessmentStatisticsRespVO> convertPage(PageResult<AssessmentStatisticsDO> page);
|
||||
|
||||
}
|
||||
@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.prison.dal.dataobject.area;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
|
||||
@ -0,0 +1,131 @@
|
||||
package cn.iocoder.yudao.module.prison.dal.dataobject.assessment;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 答卷详情 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("prison_assessment_answer")
|
||||
@KeySequence("prison_assessment_answer_seq")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class AssessmentAnswerDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 答卷ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 关联测评记录ID
|
||||
*/
|
||||
private Long assessmentRecordId;
|
||||
|
||||
/**
|
||||
* 囚犯ID
|
||||
*/
|
||||
private Long prisonerId;
|
||||
|
||||
/**
|
||||
* 囚犯编号
|
||||
*/
|
||||
private String prisonerCode;
|
||||
|
||||
/**
|
||||
* 囚犯姓名
|
||||
*/
|
||||
private String prisonerName;
|
||||
|
||||
/**
|
||||
* 监区ID
|
||||
*/
|
||||
private Long areaId;
|
||||
|
||||
/**
|
||||
* 监区名称
|
||||
*/
|
||||
private String areaName;
|
||||
|
||||
/**
|
||||
* 监室ID
|
||||
*/
|
||||
private Long cellId;
|
||||
|
||||
/**
|
||||
* 监室名称
|
||||
*/
|
||||
private String cellName;
|
||||
|
||||
/**
|
||||
* 答卷状态:1-待答题 2-答题中 3-已提交 4-已评分 5-已完成
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 开始答题时间
|
||||
*/
|
||||
private LocalDateTime startTime;
|
||||
|
||||
/**
|
||||
* 提交时间
|
||||
*/
|
||||
private LocalDateTime submitTime;
|
||||
|
||||
/**
|
||||
* 答题用时(秒)
|
||||
*/
|
||||
private Integer duration;
|
||||
|
||||
/**
|
||||
* 客观题得分
|
||||
*/
|
||||
private BigDecimal objectiveScore;
|
||||
|
||||
/**
|
||||
* 主观题得分
|
||||
*/
|
||||
private BigDecimal subjectiveScore;
|
||||
|
||||
/**
|
||||
* 总分
|
||||
*/
|
||||
private BigDecimal totalScore;
|
||||
|
||||
/**
|
||||
* 是否及格
|
||||
*/
|
||||
private Boolean passed;
|
||||
|
||||
/**
|
||||
* 评语
|
||||
*/
|
||||
private String comment;
|
||||
|
||||
/**
|
||||
* 评卷人ID
|
||||
*/
|
||||
private Long scorerId;
|
||||
|
||||
/**
|
||||
* 评卷人名称
|
||||
*/
|
||||
private String scorerName;
|
||||
|
||||
/**
|
||||
* 评分时间
|
||||
*/
|
||||
private LocalDateTime scoreTime;
|
||||
|
||||
}
|
||||
@ -0,0 +1,116 @@
|
||||
package cn.iocoder.yudao.module.prison.dal.dataobject.assessment;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 测评记录 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("prison_assessment_record")
|
||||
@KeySequence("prison_assessment_record_seq")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class AssessmentRecordDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 测评记录ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 测评名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 关联问卷模板ID
|
||||
*/
|
||||
private Long questionnaireId;
|
||||
|
||||
/**
|
||||
* 测评类型:1-心理测评 2-行为评估 3-满意度调查
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 发起测评的监狱/监区ID
|
||||
*/
|
||||
private Long areaId;
|
||||
|
||||
/**
|
||||
* 发起测评的监狱/监区名称
|
||||
*/
|
||||
private String areaName;
|
||||
|
||||
/**
|
||||
* 发起人ID
|
||||
*/
|
||||
private Long initiatorId;
|
||||
|
||||
/**
|
||||
* 发起人名称
|
||||
*/
|
||||
private String initiatorName;
|
||||
|
||||
/**
|
||||
* 测评状态:1-未开始 2-进行中 3-已完成 4-已取消
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 计划开始时间
|
||||
*/
|
||||
private LocalDateTime planStartTime;
|
||||
|
||||
/**
|
||||
* 计划结束时间
|
||||
*/
|
||||
private LocalDateTime planEndTime;
|
||||
|
||||
/**
|
||||
* 实际开始时间
|
||||
*/
|
||||
private LocalDateTime actualStartTime;
|
||||
|
||||
/**
|
||||
* 实际结束时间
|
||||
*/
|
||||
private LocalDateTime actualEndTime;
|
||||
|
||||
/**
|
||||
* 参与人数
|
||||
*/
|
||||
private Integer participantCount;
|
||||
|
||||
/**
|
||||
* 完成人数
|
||||
*/
|
||||
private Integer completedCount;
|
||||
|
||||
/**
|
||||
* 测评说明
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 是否启用自动评分
|
||||
*/
|
||||
private Boolean enableAutoScore;
|
||||
|
||||
/**
|
||||
* 及格分数
|
||||
*/
|
||||
private BigDecimal passScore;
|
||||
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
package cn.iocoder.yudao.module.prison.dal.dataobject.assessment;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 测评结果 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("prison_assessment_result")
|
||||
@KeySequence("prison_assessment_result_seq")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class AssessmentResultDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 结果ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 关联答卷ID
|
||||
*/
|
||||
private Long answerId;
|
||||
|
||||
/**
|
||||
* 关联测评记录ID
|
||||
*/
|
||||
private Long assessmentRecordId;
|
||||
|
||||
/**
|
||||
* 囚犯ID
|
||||
*/
|
||||
private Long prisonerId;
|
||||
|
||||
/**
|
||||
* 囚犯编号
|
||||
*/
|
||||
private String prisonerCode;
|
||||
|
||||
/**
|
||||
* 囚犯姓名
|
||||
*/
|
||||
private String prisonerName;
|
||||
|
||||
/**
|
||||
* 关联题目ID
|
||||
*/
|
||||
private Long questionId;
|
||||
|
||||
/**
|
||||
* 题目编号
|
||||
*/
|
||||
private String questionCode;
|
||||
|
||||
/**
|
||||
* 题目内容
|
||||
*/
|
||||
private String questionContent;
|
||||
|
||||
/**
|
||||
* 题目类型:1-单选 2-多选 3-判断 4-填空 5-问答
|
||||
*/
|
||||
private Integer questionType;
|
||||
|
||||
/**
|
||||
* 题目分值
|
||||
*/
|
||||
private BigDecimal questionScore;
|
||||
|
||||
/**
|
||||
* 囚犯答案
|
||||
*/
|
||||
private String answer;
|
||||
|
||||
/**
|
||||
* 正确答案(客观题)
|
||||
*/
|
||||
private String correctAnswer;
|
||||
|
||||
/**
|
||||
* 是否正确
|
||||
*/
|
||||
private Boolean correct;
|
||||
|
||||
/**
|
||||
* 得分
|
||||
*/
|
||||
private BigDecimal score;
|
||||
|
||||
/**
|
||||
* 是否需要人工评阅
|
||||
*/
|
||||
private Boolean needManualReview;
|
||||
|
||||
/**
|
||||
* 人工评阅状态:1-待评阅 2-已评阅
|
||||
*/
|
||||
private Integer manualReviewStatus;
|
||||
|
||||
/**
|
||||
* 人工评分
|
||||
*/
|
||||
private BigDecimal manualScore;
|
||||
|
||||
/**
|
||||
* 人工评语
|
||||
*/
|
||||
private String manualComment;
|
||||
|
||||
/**
|
||||
* 评阅人ID
|
||||
*/
|
||||
private Long reviewerId;
|
||||
|
||||
/**
|
||||
* 评阅人名称
|
||||
*/
|
||||
private String reviewerName;
|
||||
|
||||
/**
|
||||
* 评阅时间
|
||||
*/
|
||||
private LocalDateTime reviewTime;
|
||||
|
||||
}
|
||||
@ -0,0 +1,115 @@
|
||||
package cn.iocoder.yudao.module.prison.dal.dataobject.assessment;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 测评统计 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("prison_assessment_statistics")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class AssessmentStatisticsDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 统计ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 关联测评记录ID
|
||||
*/
|
||||
private Long assessmentRecordId;
|
||||
|
||||
/**
|
||||
* 测评名称
|
||||
*/
|
||||
private String assessmentName;
|
||||
|
||||
/**
|
||||
* 总参与人数
|
||||
*/
|
||||
private Integer totalCount;
|
||||
|
||||
/**
|
||||
* 已完成人数
|
||||
*/
|
||||
private Integer completedCount;
|
||||
|
||||
/**
|
||||
* 完成率
|
||||
*/
|
||||
private BigDecimal completionRate;
|
||||
|
||||
/**
|
||||
* 平均分
|
||||
*/
|
||||
private BigDecimal averageScore;
|
||||
|
||||
/**
|
||||
* 最高分
|
||||
*/
|
||||
private BigDecimal highestScore;
|
||||
|
||||
/**
|
||||
* 最低分
|
||||
*/
|
||||
private BigDecimal lowestScore;
|
||||
|
||||
/**
|
||||
* 及格人数
|
||||
*/
|
||||
private Integer passedCount;
|
||||
|
||||
/**
|
||||
* 及格率
|
||||
*/
|
||||
private BigDecimal passRate;
|
||||
|
||||
/**
|
||||
* 优秀人数(90分以上)
|
||||
*/
|
||||
private Integer excellentCount;
|
||||
|
||||
/**
|
||||
* 优秀率
|
||||
*/
|
||||
private BigDecimal excellentRate;
|
||||
|
||||
/**
|
||||
* 风险人数(60分以下)
|
||||
*/
|
||||
private Integer riskCount;
|
||||
|
||||
/**
|
||||
* 风险率
|
||||
*/
|
||||
private BigDecimal riskRate;
|
||||
|
||||
/**
|
||||
* 风险分布JSON:{"low": 10, "medium": 5, "high": 3}
|
||||
*/
|
||||
private String riskDistribution;
|
||||
|
||||
/**
|
||||
* 分数分布JSON:{"0-20": 5, "20-40": 10, "40-60": 15, "60-80": 20, "80-100": 8}
|
||||
*/
|
||||
private String scoreDistribution;
|
||||
|
||||
/**
|
||||
* 统计时间
|
||||
*/
|
||||
private LocalDateTime statisticsTime;
|
||||
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package cn.iocoder.yudao.module.prison.dal.mysql.assessment;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentAnswerDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
|
||||
/**
|
||||
* 答卷详情 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface AssessmentAnswerMapper extends BaseMapperX<AssessmentAnswerDO> {
|
||||
|
||||
default PageResult<AssessmentAnswerDO> selectPage(AssessmentAnswerPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<AssessmentAnswerDO>()
|
||||
.eqIfPresent(AssessmentAnswerDO::getAssessmentRecordId, reqVO.getAssessmentRecordId())
|
||||
.eqIfPresent(AssessmentAnswerDO::getPrisonerId, reqVO.getPrisonerId())
|
||||
.likeIfPresent(AssessmentAnswerDO::getPrisonerCode, reqVO.getPrisonerCode())
|
||||
.likeIfPresent(AssessmentAnswerDO::getPrisonerName, reqVO.getPrisonerName())
|
||||
.eqIfPresent(AssessmentAnswerDO::getAreaId, reqVO.getAreaId())
|
||||
.eqIfPresent(AssessmentAnswerDO::getCellId, reqVO.getCellId())
|
||||
.eqIfPresent(AssessmentAnswerDO::getStatus, reqVO.getStatus())
|
||||
.betweenIfPresent(AssessmentAnswerDO::getStartTime, reqVO.getStartTime())
|
||||
.betweenIfPresent(AssessmentAnswerDO::getSubmitTime, reqVO.getSubmitTime())
|
||||
.orderByDesc(AssessmentAnswerDO::getId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据测评记录ID查询所有答卷
|
||||
*/
|
||||
default List<AssessmentAnswerDO> selectListByAssessmentRecordId(Long assessmentRecordId) {
|
||||
return selectList(new LambdaQueryWrapperX<AssessmentAnswerDO>()
|
||||
.eqIfPresent(AssessmentAnswerDO::getAssessmentRecordId, assessmentRecordId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据囚犯ID和测评记录ID查询答卷
|
||||
*/
|
||||
default AssessmentAnswerDO selectByPrisonerAndRecord(Long prisonerId, Long assessmentRecordId) {
|
||||
return selectOne(new LambdaQueryWrapperX<AssessmentAnswerDO>()
|
||||
.eqIfPresent(AssessmentAnswerDO::getPrisonerId, prisonerId)
|
||||
.eqIfPresent(AssessmentAnswerDO::getAssessmentRecordId, assessmentRecordId));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package cn.iocoder.yudao.module.prison.dal.mysql.assessment;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentRecordDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
|
||||
/**
|
||||
* 测评记录 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface AssessmentRecordMapper extends BaseMapperX<AssessmentRecordDO> {
|
||||
|
||||
default PageResult<AssessmentRecordDO> selectPage(AssessmentRecordPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<AssessmentRecordDO>()
|
||||
.likeIfPresent(AssessmentRecordDO::getName, reqVO.getName())
|
||||
.eqIfPresent(AssessmentRecordDO::getQuestionnaireId, reqVO.getQuestionnaireId())
|
||||
.eqIfPresent(AssessmentRecordDO::getType, reqVO.getType())
|
||||
.eqIfPresent(AssessmentRecordDO::getAreaId, reqVO.getAreaId())
|
||||
.eqIfPresent(AssessmentRecordDO::getStatus, reqVO.getStatus())
|
||||
.betweenIfPresent(AssessmentRecordDO::getPlanStartTime, reqVO.getPlanStartTime())
|
||||
.betweenIfPresent(AssessmentRecordDO::getPlanEndTime, reqVO.getPlanEndTime())
|
||||
.betweenIfPresent(AssessmentRecordDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(AssessmentRecordDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
package cn.iocoder.yudao.module.prison.dal.mysql.assessment;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentResultDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
|
||||
/**
|
||||
* 测评结果 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface AssessmentResultMapper extends BaseMapperX<AssessmentResultDO> {
|
||||
|
||||
default PageResult<AssessmentResultDO> selectPage(AssessmentResultPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<AssessmentResultDO>()
|
||||
.eqIfPresent(AssessmentResultDO::getAnswerId, reqVO.getAnswerId())
|
||||
.eqIfPresent(AssessmentResultDO::getAssessmentRecordId, reqVO.getAssessmentRecordId())
|
||||
.eqIfPresent(AssessmentResultDO::getPrisonerId, reqVO.getPrisonerId())
|
||||
.eqIfPresent(AssessmentResultDO::getQuestionId, reqVO.getQuestionId())
|
||||
.eqIfPresent(AssessmentResultDO::getQuestionType, reqVO.getQuestionType())
|
||||
.eqIfPresent(AssessmentResultDO::getCorrect, reqVO.getCorrect())
|
||||
.eqIfPresent(AssessmentResultDO::getNeedManualReview, reqVO.getNeedManualReview())
|
||||
.eqIfPresent(AssessmentResultDO::getManualReviewStatus, reqVO.getManualReviewStatus())
|
||||
.orderByDesc(AssessmentResultDO::getId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据答卷ID查询所有结果
|
||||
*/
|
||||
default List<AssessmentResultDO> selectListByAnswerId(Long answerId) {
|
||||
return selectList(new LambdaQueryWrapperX<AssessmentResultDO>()
|
||||
.eqIfPresent(AssessmentResultDO::getAnswerId, answerId)
|
||||
.orderByAsc(AssessmentResultDO::getId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据测评记录ID查询所有结果
|
||||
*/
|
||||
default List<AssessmentResultDO> selectListByAssessmentRecordId(Long assessmentRecordId) {
|
||||
return selectList(new LambdaQueryWrapperX<AssessmentResultDO>()
|
||||
.eqIfPresent(AssessmentResultDO::getAssessmentRecordId, assessmentRecordId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询需要人工评阅的结果
|
||||
*/
|
||||
default List<AssessmentResultDO> selectListNeedManualReview() {
|
||||
return selectList(new LambdaQueryWrapperX<AssessmentResultDO>()
|
||||
.eqIfPresent(AssessmentResultDO::getNeedManualReview, true)
|
||||
.eqIfPresent(AssessmentResultDO::getManualReviewStatus, 1)
|
||||
.orderByAsc(AssessmentResultDO::getId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据答卷ID统计客观题得分
|
||||
*/
|
||||
default java.math.BigDecimal sumObjectiveScoreByAnswerId(Long answerId) {
|
||||
return selectObjs(new LambdaQueryWrapperX<AssessmentResultDO>()
|
||||
.eqIfPresent(AssessmentResultDO::getAnswerId, answerId)
|
||||
.eqIfPresent(AssessmentResultDO::getNeedManualReview, false))
|
||||
.stream().map(obj -> (java.math.BigDecimal) obj)
|
||||
.reduce(java.math.BigDecimal.ZERO, java.math.BigDecimal::add);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.prison.dal.mysql.assessment;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentStatisticsDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
|
||||
/**
|
||||
* 测评统计 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface AssessmentStatisticsMapper extends BaseMapperX<AssessmentStatisticsDO> {
|
||||
|
||||
default PageResult<AssessmentStatisticsDO> selectPage(AssessmentStatisticsPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<AssessmentStatisticsDO>()
|
||||
.eqIfPresent(AssessmentStatisticsDO::getAssessmentRecordId, reqVO.getAssessmentRecordId())
|
||||
.likeIfPresent(AssessmentStatisticsDO::getAssessmentName, reqVO.getAssessmentName())
|
||||
.orderByDesc(AssessmentStatisticsDO::getId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据测评记录ID查询统计
|
||||
*/
|
||||
default AssessmentStatisticsDO selectByAssessmentRecordId(Long assessmentRecordId) {
|
||||
return selectOne(new LambdaQueryWrapperX<AssessmentStatisticsDO>()
|
||||
.eqIfPresent(AssessmentStatisticsDO::getAssessmentRecordId, assessmentRecordId)
|
||||
.orderByDesc(AssessmentStatisticsDO::getId)
|
||||
.last("LIMIT 1"));
|
||||
}
|
||||
|
||||
}
|
||||
@ -25,6 +25,11 @@ public interface QuestionnaireMapper extends BaseMapperX<QuestionnaireDO> {
|
||||
.eqIfPresent(QuestionnaireDO::getTotalScore, reqVO.getTotalScore())
|
||||
.eqIfPresent(QuestionnaireDO::getPassScore, reqVO.getPassScore())
|
||||
.eqIfPresent(QuestionnaireDO::getStatus, reqVO.getStatus())
|
||||
.eqIfPresent(QuestionnaireDO::getCoverImage, reqVO.getCoverImage())
|
||||
.eqIfPresent(QuestionnaireDO::getInstruction, reqVO.getInstruction())
|
||||
.eqIfPresent(QuestionnaireDO::getEstimatedTime, reqVO.getEstimatedTime())
|
||||
.eqIfPresent(QuestionnaireDO::getPartCount, reqVO.getPartCount())
|
||||
.eqIfPresent(QuestionnaireDO::getAllowAnonymous, reqVO.getAllowAnonymous())
|
||||
.betweenIfPresent(QuestionnaireDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(QuestionnaireDO::getId));
|
||||
}
|
||||
|
||||
@ -39,6 +39,14 @@ public class ErrorCodeConstants {
|
||||
// ========== 罪犯监区变动记录 8xxxx ==========
|
||||
public static final ErrorCode PRISONER_AREA_LOG_NOT_EXISTS = new ErrorCode(8_000_001, "罪犯监区变动记录不存在");
|
||||
|
||||
// ========== 测评执行与评分 9xxxx ==========
|
||||
public static final ErrorCode ASSESSMENT_RECORD_NOT_EXISTS = new ErrorCode(9_000_001, "测评记录不存在");
|
||||
public static final ErrorCode ASSESSMENT_RECORD_STATUS_ERROR = new ErrorCode(9_000_002, "测评记录状态不正确");
|
||||
public static final ErrorCode ASSESSMENT_ANSWER_NOT_EXISTS = new ErrorCode(9_000_003, "答卷不存在");
|
||||
public static final ErrorCode ASSESSMENT_ANSWER_STATUS_ERROR = new ErrorCode(9_000_004, "答卷状态不正确");
|
||||
public static final ErrorCode ASSESSMENT_ANSWER_ALREADY_EXISTS = new ErrorCode(9_000_005, "该囚犯已参与此测评");
|
||||
public static final ErrorCode ASSESSMENT_RESULT_NOT_EXISTS = new ErrorCode(9_000_006, "测评结果不存在");
|
||||
|
||||
// ========== 别名 (兼容codegen生成的代码) ==========
|
||||
public static final ErrorCode AREA_NOT_EXISTS = PRISON_AREA_NOT_EXISTS;
|
||||
public static final ErrorCode CELL_NOT_EXISTS = PRISON_CELL_NOT_EXISTS;
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
package cn.iocoder.yudao.module.prison.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 问卷答题记录及格状态枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum QuestionnaireRecordPassStatusEnum {
|
||||
|
||||
NOT_PASSED(0, "未及格"),
|
||||
PASSED(1, "及格");
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer status;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
public static boolean isValid(Integer status) {
|
||||
if (status == null) {
|
||||
return false;
|
||||
}
|
||||
for (QuestionnaireRecordPassStatusEnum value : values()) {
|
||||
if (value.getStatus().equals(status)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static QuestionnaireRecordPassStatusEnum getByStatus(Integer status) {
|
||||
for (QuestionnaireRecordPassStatusEnum value : values()) {
|
||||
if (value.getStatus().equals(status)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package cn.iocoder.yudao.module.prison.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 问卷答题记录状态枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum QuestionnaireRecordStatusEnum {
|
||||
|
||||
PENDING(1, "待评估"),
|
||||
COMPLETED(2, "已完成");
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer status;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
public static boolean isValid(Integer status) {
|
||||
if (status == null) {
|
||||
return false;
|
||||
}
|
||||
for (QuestionnaireRecordStatusEnum value : values()) {
|
||||
if (value.getStatus().equals(status)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static QuestionnaireRecordStatusEnum getByStatus(Integer status) {
|
||||
for (QuestionnaireRecordStatusEnum value : values()) {
|
||||
if (value.getStatus().equals(status)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package cn.iocoder.yudao.module.prison.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 问卷状态枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum QuestionnaireStatusEnum {
|
||||
|
||||
DRAFT(1, "草稿"),
|
||||
PUBLISHED(2, "已发布"),
|
||||
DISABLED(3, "已禁用");
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer status;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
public static boolean isValid(Integer status) {
|
||||
if (status == null) {
|
||||
return false;
|
||||
}
|
||||
for (QuestionnaireStatusEnum value : values()) {
|
||||
if (value.getStatus().equals(status)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static QuestionnaireStatusEnum getByStatus(Integer status) {
|
||||
for (QuestionnaireStatusEnum value : values()) {
|
||||
if (value.getStatus().equals(status)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package cn.iocoder.yudao.module.prison.enums.assessment;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 答卷状态枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum AssessmentAnswerStatusEnum {
|
||||
|
||||
PENDING(1, "待答题"),
|
||||
IN_PROGRESS(2, "答题中"),
|
||||
SUBMITTED(3, "已提交"),
|
||||
SCORED(4, "已评分"),
|
||||
COMPLETED(5, "已完成");
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer status;
|
||||
|
||||
/**
|
||||
* 状态名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
public static AssessmentAnswerStatusEnum getByStatus(Integer status) {
|
||||
for (AssessmentAnswerStatusEnum statusEnum : values()) {
|
||||
if (statusEnum.getStatus().equals(status)) {
|
||||
return statusEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.prison.enums.assessment;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 测评结果人工评阅状态枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum AssessmentManualReviewStatusEnum {
|
||||
|
||||
PENDING(1, "待评阅"),
|
||||
REVIEWED(2, "已评阅");
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer status;
|
||||
|
||||
/**
|
||||
* 状态名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
public static AssessmentManualReviewStatusEnum getByStatus(Integer status) {
|
||||
for (AssessmentManualReviewStatusEnum statusEnum : values()) {
|
||||
if (statusEnum.getStatus().equals(status)) {
|
||||
return statusEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package cn.iocoder.yudao.module.prison.enums.assessment;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 测评记录状态枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum AssessmentRecordStatusEnum {
|
||||
|
||||
NOT_STARTED(1, "未开始"),
|
||||
IN_PROGRESS(2, "进行中"),
|
||||
COMPLETED(3, "已完成"),
|
||||
CANCELLED(4, "已取消");
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer status;
|
||||
|
||||
/**
|
||||
* 状态名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
public static AssessmentRecordStatusEnum getByStatus(Integer status) {
|
||||
for (AssessmentRecordStatusEnum statusEnum : values()) {
|
||||
if (statusEnum.getStatus().equals(status)) {
|
||||
return statusEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package cn.iocoder.yudao.module.prison.enums.assessment;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 风险等级枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum RiskLevelEnum {
|
||||
|
||||
LOW("low", "低风险"),
|
||||
MEDIUM("medium", "中风险"),
|
||||
HIGH("high", "高风险");
|
||||
|
||||
/**
|
||||
* 等级Key
|
||||
*/
|
||||
private final String level;
|
||||
|
||||
/**
|
||||
* 等级名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
public static RiskLevelEnum getByLevel(String level) {
|
||||
for (RiskLevelEnum levelEnum : values()) {
|
||||
if (levelEnum.getLevel().equals(level)) {
|
||||
return levelEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -178,13 +178,8 @@ public class AreaServiceImpl implements AreaService {
|
||||
buildChildrenRecursive(child, allAreas);
|
||||
}
|
||||
|
||||
// 使用反射设置 children 属性
|
||||
try {
|
||||
java.lang.reflect.Method method = AreaDO.class.getMethod("setChildren", List.class);
|
||||
method.invoke(parent, children);
|
||||
} catch (Exception e) {
|
||||
// 如果没有 children 方法,忽略
|
||||
}
|
||||
// 设置子节点列表
|
||||
parent.setChildren(children);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -0,0 +1,110 @@
|
||||
package cn.iocoder.yudao.module.prison.service.assessment;
|
||||
|
||||
import java.util.*;
|
||||
import jakarta.validation.*;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentAnswerDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
|
||||
/**
|
||||
* 答卷详情 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface AssessmentAnswerService {
|
||||
|
||||
/**
|
||||
* 创建答卷
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createAssessmentAnswer(@Valid AssessmentAnswerSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新答卷
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateAssessmentAnswer(@Valid AssessmentAnswerSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除答卷
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteAssessmentAnswer(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除答卷
|
||||
*
|
||||
* @param ids 编号列表
|
||||
*/
|
||||
void deleteAssessmentAnswerListByIds(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得答卷
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 答卷
|
||||
*/
|
||||
AssessmentAnswerDO getAssessmentAnswer(Long id);
|
||||
|
||||
/**
|
||||
* 获得答卷分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 答卷分页
|
||||
*/
|
||||
PageResult<AssessmentAnswerDO> getAssessmentAnswerPage(AssessmentAnswerPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 开始答题
|
||||
*
|
||||
* @param assessmentRecordId 测评记录ID
|
||||
* @param prisonerId 囚犯ID
|
||||
* @return 答卷ID
|
||||
*/
|
||||
Long startAnswer(Long assessmentRecordId, Long prisonerId);
|
||||
|
||||
/**
|
||||
* 提交答卷
|
||||
*
|
||||
* @param submitReqVO 提交信息
|
||||
*/
|
||||
void submitAnswer(AssessmentAnswerSubmitReqVO submitReqVO);
|
||||
|
||||
/**
|
||||
* 根据囚犯ID和测评记录ID获取答卷
|
||||
*
|
||||
* @param prisonerId 囚犯ID
|
||||
* @param assessmentRecordId 测评记录ID
|
||||
* @return 答卷
|
||||
*/
|
||||
AssessmentAnswerDO getByPrisonerAndRecord(Long prisonerId, Long assessmentRecordId);
|
||||
|
||||
/**
|
||||
* 获取待评分列表
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 待评分答卷分页
|
||||
*/
|
||||
PageResult<AssessmentAnswerDO> getPendingScorePage(AssessmentAnswerPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 人工评分
|
||||
*
|
||||
* @param scoreReqVO 评分信息
|
||||
*/
|
||||
void manualScore(AssessmentAnswerManualScoreReqVO scoreReqVO);
|
||||
|
||||
/**
|
||||
* 获取已完成答卷列表
|
||||
*
|
||||
* @param assessmentRecordId 测评记录ID
|
||||
* @return 答卷列表
|
||||
*/
|
||||
List<AssessmentAnswerDO> getCompletedAnswersByRecordId(Long assessmentRecordId);
|
||||
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
package cn.iocoder.yudao.module.prison.service.assessment;
|
||||
|
||||
import java.util.*;
|
||||
import jakarta.validation.*;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentRecordDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
|
||||
/**
|
||||
* 测评记录 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface AssessmentRecordService {
|
||||
|
||||
/**
|
||||
* 创建测评记录
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createAssessmentRecord(@Valid AssessmentRecordSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新测评记录
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateAssessmentRecord(@Valid AssessmentRecordSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除测评记录
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteAssessmentRecord(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除测评记录
|
||||
*
|
||||
* @param ids 编号列表
|
||||
*/
|
||||
void deleteAssessmentRecordListByIds(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得测评记录
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 测评记录
|
||||
*/
|
||||
AssessmentRecordDO getAssessmentRecord(Long id);
|
||||
|
||||
/**
|
||||
* 获得测评记录分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 测评记录分页
|
||||
*/
|
||||
PageResult<AssessmentRecordDO> getAssessmentRecordPage(AssessmentRecordPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 发起测评
|
||||
*
|
||||
* @param reqVO 发起信息
|
||||
* @return 测评记录ID
|
||||
*/
|
||||
Long initiateAssessment(AssessmentRecordSaveReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 取消测评
|
||||
*
|
||||
* @param id 测评记录ID
|
||||
*/
|
||||
void cancelAssessment(Long id);
|
||||
|
||||
/**
|
||||
* 启动测评
|
||||
*
|
||||
* @param id 测评记录ID
|
||||
*/
|
||||
void startAssessment(Long id);
|
||||
|
||||
/**
|
||||
* 结束测评
|
||||
*
|
||||
* @param id 测评记录ID
|
||||
*/
|
||||
void finishAssessment(Long id);
|
||||
|
||||
}
|
||||
@ -0,0 +1,106 @@
|
||||
package cn.iocoder.yudao.module.prison.service.assessment;
|
||||
|
||||
import java.util.*;
|
||||
import jakarta.validation.*;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentResultDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
|
||||
/**
|
||||
* 测评结果 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface AssessmentResultService {
|
||||
|
||||
/**
|
||||
* 创建测评结果
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createAssessmentResult(@Valid AssessmentResultSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 批量创建测评结果
|
||||
*
|
||||
* @param results 结果列表
|
||||
*/
|
||||
void batchCreateAssessmentResult(List<AssessmentResultSaveReqVO> results);
|
||||
|
||||
/**
|
||||
* 更新测评结果
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateAssessmentResult(@Valid AssessmentResultSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除测评结果
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteAssessmentResult(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除测评结果
|
||||
*
|
||||
* @param ids 编号列表
|
||||
*/
|
||||
void deleteAssessmentResultListByIds(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得测评结果
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 测评结果
|
||||
*/
|
||||
AssessmentResultDO getAssessmentResult(Long id);
|
||||
|
||||
/**
|
||||
* 获得测评结果分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 测评结果分页
|
||||
*/
|
||||
PageResult<AssessmentResultDO> getAssessmentResultPage(AssessmentResultPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 根据答卷ID获取所有结果
|
||||
*
|
||||
* @param answerId 答卷ID
|
||||
* @return 结果列表
|
||||
*/
|
||||
List<AssessmentResultDO> getResultsByAnswerId(Long answerId);
|
||||
|
||||
/**
|
||||
* 根据测评记录ID获取所有结果
|
||||
*
|
||||
* @param assessmentRecordId 测评记录ID
|
||||
* @return 结果列表
|
||||
*/
|
||||
List<AssessmentResultDO> getResultsByAssessmentRecordId(Long assessmentRecordId);
|
||||
|
||||
/**
|
||||
* 获取需要人工评阅的结果列表
|
||||
*
|
||||
* @return 需要人工评阅的结果列表
|
||||
*/
|
||||
List<AssessmentResultDO> getNeedManualReviewList();
|
||||
|
||||
/**
|
||||
* 人工评阅
|
||||
*
|
||||
* @param reviewReqVO 评阅信息
|
||||
*/
|
||||
void manualReview(AssessmentResultManualReviewReqVO reviewReqVO);
|
||||
|
||||
/**
|
||||
* 自动评分
|
||||
*
|
||||
* @param answerId 答卷ID
|
||||
*/
|
||||
void autoScore(Long answerId);
|
||||
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
package cn.iocoder.yudao.module.prison.service.assessment;
|
||||
|
||||
import java.util.*;
|
||||
import jakarta.validation.*;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentStatisticsDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
|
||||
/**
|
||||
* 测评统计 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface AssessmentStatisticsService {
|
||||
|
||||
/**
|
||||
* 获得测评统计
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 测评统计
|
||||
*/
|
||||
AssessmentStatisticsDO getAssessmentStatistics(Long id);
|
||||
|
||||
/**
|
||||
* 获得测评统计分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 测评统计分页
|
||||
*/
|
||||
PageResult<AssessmentStatisticsDO> getAssessmentStatisticsPage(AssessmentStatisticsPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 生成测评统计
|
||||
*
|
||||
* @param assessmentRecordId 测评记录ID
|
||||
* @return 统计信息
|
||||
*/
|
||||
AssessmentStatisticsDO generateStatistics(Long assessmentRecordId);
|
||||
|
||||
/**
|
||||
* 获取测评完成率
|
||||
*
|
||||
* @param assessmentRecordId 测评记录ID
|
||||
* @return 完成率
|
||||
*/
|
||||
java.math.BigDecimal getCompletionRate(Long assessmentRecordId);
|
||||
|
||||
/**
|
||||
* 获取分数分布
|
||||
*
|
||||
* @param assessmentRecordId 测评记录ID
|
||||
* @return 分数分布
|
||||
*/
|
||||
Map<String, Integer> getScoreDistribution(Long assessmentRecordId);
|
||||
|
||||
/**
|
||||
* 获取风险分布
|
||||
*
|
||||
* @param assessmentRecordId 测评记录ID
|
||||
* @return 风险分布
|
||||
*/
|
||||
Map<String, Integer> getRiskDistribution(Long assessmentRecordId);
|
||||
|
||||
/**
|
||||
* 获取测评分析报告
|
||||
*
|
||||
* @param assessmentRecordId 测评记录ID
|
||||
* @return 分析报告
|
||||
*/
|
||||
AssessmentStatisticsRespVO getAssessmentReport(Long assessmentRecordId);
|
||||
|
||||
}
|
||||
@ -0,0 +1,163 @@
|
||||
package cn.iocoder.yudao.module.prison.service.assessment.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentAnswerDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
|
||||
import cn.iocoder.yudao.module.prison.dal.mysql.assessment.AssessmentAnswerMapper;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.prison.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 答卷详情 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class AssessmentAnswerServiceImpl implements AssessmentAnswerService {
|
||||
|
||||
@Resource
|
||||
private AssessmentAnswerMapper assessmentAnswerMapper;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createAssessmentAnswer(AssessmentAnswerSaveReqVO createReqVO) {
|
||||
AssessmentAnswerDO answer = BeanUtils.toBean(createReqVO, AssessmentAnswerDO.class);
|
||||
assessmentAnswerMapper.insert(answer);
|
||||
return answer.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateAssessmentAnswer(AssessmentAnswerSaveReqVO updateReqVO) {
|
||||
validateAssessmentAnswerExists(updateReqVO.getId());
|
||||
AssessmentAnswerDO updateObj = BeanUtils.toBean(updateReqVO, AssessmentAnswerDO.class);
|
||||
assessmentAnswerMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteAssessmentAnswer(Long id) {
|
||||
validateAssessmentAnswerExists(id);
|
||||
assessmentAnswerMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteAssessmentAnswerListByIds(List<Long> ids) {
|
||||
assessmentAnswerMapper.deleteByIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssessmentAnswerDO getAssessmentAnswer(Long id) {
|
||||
return assessmentAnswerMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<AssessmentAnswerDO> getAssessmentAnswerPage(AssessmentAnswerPageReqVO pageReqVO) {
|
||||
return assessmentAnswerMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long startAnswer(Long assessmentRecordId, Long prisonerId) {
|
||||
// 检查是否已有答卷
|
||||
AssessmentAnswerDO existingAnswer = assessmentAnswerMapper.selectOne(
|
||||
new cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX<AssessmentAnswerDO>()
|
||||
.eqIfPresent(AssessmentAnswerDO::getAssessmentRecordId, assessmentRecordId)
|
||||
.eqIfPresent(AssessmentAnswerDO::getPrisonerId, prisonerId)
|
||||
);
|
||||
if (existingAnswer != null && !Arrays.asList(1, 2).contains(existingAnswer.getStatus())) {
|
||||
throw exception(ASSESSMENT_ANSWER_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
if (existingAnswer != null) {
|
||||
return existingAnswer.getId();
|
||||
}
|
||||
|
||||
// 创建新答卷
|
||||
AssessmentAnswerDO answer = new AssessmentAnswerDO();
|
||||
answer.setAssessmentRecordId(assessmentRecordId);
|
||||
answer.setPrisonerId(prisonerId);
|
||||
answer.setStatus(2); // 答题中
|
||||
answer.setStartTime(LocalDateTime.now());
|
||||
assessmentAnswerMapper.insert(answer);
|
||||
return answer.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void submitAnswer(AssessmentAnswerSubmitReqVO submitReqVO) {
|
||||
AssessmentAnswerDO answer = validateAssessmentAnswerExists(submitReqVO.getId());
|
||||
if (!Objects.equals(answer.getStatus(), 2)) {
|
||||
throw exception(ASSESSMENT_ANSWER_STATUS_ERROR);
|
||||
}
|
||||
|
||||
answer.setStatus(3); // 已提交
|
||||
answer.setSubmitTime(LocalDateTime.now());
|
||||
if (answer.getStartTime() != null) {
|
||||
answer.setDuration((int) java.time.Duration.between(answer.getStartTime(), LocalDateTime.now()).getSeconds());
|
||||
}
|
||||
assessmentAnswerMapper.updateById(answer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssessmentAnswerDO getByPrisonerAndRecord(Long prisonerId, Long assessmentRecordId) {
|
||||
return assessmentAnswerMapper.selectOne(
|
||||
new cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX<AssessmentAnswerDO>()
|
||||
.eqIfPresent(AssessmentAnswerDO::getPrisonerId, prisonerId)
|
||||
.eqIfPresent(AssessmentAnswerDO::getAssessmentRecordId, assessmentRecordId)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<AssessmentAnswerDO> getPendingScorePage(AssessmentAnswerPageReqVO pageReqVO) {
|
||||
// 查询已提交但未评分的答卷
|
||||
pageReqVO.setStatus(3); // 已提交
|
||||
return assessmentAnswerMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void manualScore(AssessmentAnswerManualScoreReqVO scoreReqVO) {
|
||||
AssessmentAnswerDO answer = validateAssessmentAnswerExists(scoreReqVO.getId());
|
||||
answer.setSubjectiveScore(scoreReqVO.getSubjectiveScore());
|
||||
answer.setTotalScore(answer.getObjectiveScore() != null ? answer.getObjectiveScore() : BigDecimal.ZERO
|
||||
.add(scoreReqVO.getSubjectiveScore() != null ? scoreReqVO.getSubjectiveScore() : BigDecimal.ZERO));
|
||||
answer.setPassed(answer.getTotalScore().compareTo(answer.getPassScore()) >= 0);
|
||||
answer.setComment(scoreReqVO.getComment());
|
||||
answer.setStatus(5); // 已完成
|
||||
assessmentAnswerMapper.updateById(answer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AssessmentAnswerDO> getCompletedAnswersByRecordId(Long assessmentRecordId) {
|
||||
return assessmentAnswerMapper.selectList(
|
||||
new cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX<AssessmentAnswerDO>()
|
||||
.eqIfPresent(AssessmentAnswerDO::getAssessmentRecordId, assessmentRecordId)
|
||||
.eqIfPresent(AssessmentAnswerDO::getStatus, 5)
|
||||
);
|
||||
}
|
||||
|
||||
private AssessmentAnswerDO validateAssessmentAnswerExists(Long id) {
|
||||
AssessmentAnswerDO answer = assessmentAnswerMapper.selectById(id);
|
||||
if (answer == null) {
|
||||
throw exception(ASSESSMENT_ANSWER_NOT_EXISTS);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,133 @@
|
||||
package cn.iocoder.yudao.module.prison.service.assessment.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentRecordDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
|
||||
import cn.iocoder.yudao.module.prison.dal.mysql.assessment.AssessmentRecordMapper;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.prison.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 测评记录 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class AssessmentRecordServiceImpl implements AssessmentRecordService {
|
||||
|
||||
@Resource
|
||||
private AssessmentRecordMapper assessmentRecordMapper;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createAssessmentRecord(AssessmentRecordSaveReqVO createReqVO) {
|
||||
// 插入
|
||||
AssessmentRecordDO assessmentRecord = BeanUtils.toBean(createReqVO, AssessmentRecordDO.class);
|
||||
assessmentRecordMapper.insert(assessmentRecord);
|
||||
|
||||
// 返回
|
||||
return assessmentRecord.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateAssessmentRecord(AssessmentRecordSaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateAssessmentRecordExists(updateReqVO.getId());
|
||||
// 更新
|
||||
AssessmentRecordDO updateObj = BeanUtils.toBean(updateReqVO, AssessmentRecordDO.class);
|
||||
assessmentRecordMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteAssessmentRecord(Long id) {
|
||||
// 校验存在
|
||||
validateAssessmentRecordExists(id);
|
||||
// 删除
|
||||
assessmentRecordMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteAssessmentRecordListByIds(List<Long> ids) {
|
||||
assessmentRecordMapper.deleteByIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssessmentRecordDO getAssessmentRecord(Long id) {
|
||||
return assessmentRecordMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<AssessmentRecordDO> getAssessmentRecordPage(AssessmentRecordPageReqVO pageReqVO) {
|
||||
return assessmentRecordMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long initiateAssessment(AssessmentRecordSaveReqVO reqVO) {
|
||||
AssessmentRecordDO assessmentRecord = BeanUtils.toBean(reqVO, AssessmentRecordDO.class);
|
||||
assessmentRecord.setStatus(1); // 未开始
|
||||
assessmentRecord.setParticipantCount(0);
|
||||
assessmentRecord.setCompletedCount(0);
|
||||
assessmentRecordMapper.insert(assessmentRecord);
|
||||
return assessmentRecord.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void cancelAssessment(Long id) {
|
||||
AssessmentRecordDO assessmentRecord = validateAssessmentRecordExists(id);
|
||||
if (!Arrays.asList(1, 2).contains(assessmentRecord.getStatus())) {
|
||||
throw exception(ASSESSMENT_RECORD_STATUS_ERROR);
|
||||
}
|
||||
assessmentRecord.setStatus(4); // 已取消
|
||||
assessmentRecordMapper.updateById(assessmentRecord);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void startAssessment(Long id) {
|
||||
AssessmentRecordDO assessmentRecord = validateAssessmentRecordExists(id);
|
||||
if (!Objects.equals(assessmentRecord.getStatus(), 1)) {
|
||||
throw exception(ASSESSMENT_RECORD_STATUS_ERROR);
|
||||
}
|
||||
assessmentRecord.setStatus(2); // 进行中
|
||||
assessmentRecord.setActualStartTime(java.time.LocalDateTime.now());
|
||||
assessmentRecordMapper.updateById(assessmentRecord);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void finishAssessment(Long id) {
|
||||
AssessmentRecordDO assessmentRecord = validateAssessmentRecordExists(id);
|
||||
if (!Objects.equals(assessmentRecord.getStatus(), 2)) {
|
||||
throw exception(ASSESSMENT_RECORD_STATUS_ERROR);
|
||||
}
|
||||
assessmentRecord.setStatus(3); // 已完成
|
||||
assessmentRecord.setActualEndTime(java.time.LocalDateTime.now());
|
||||
assessmentRecordMapper.updateById(assessmentRecord);
|
||||
}
|
||||
|
||||
private AssessmentRecordDO validateAssessmentRecordExists(Long id) {
|
||||
AssessmentRecordDO assessmentRecord = assessmentRecordMapper.selectById(id);
|
||||
if (assessmentRecord == null) {
|
||||
throw exception(ASSESSMENT_RECORD_NOT_EXISTS);
|
||||
}
|
||||
return assessmentRecord;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,141 @@
|
||||
package cn.iocoder.yudao.module.prison.service.assessment.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentResultDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
|
||||
import cn.iocoder.yudao.module.prison.dal.mysql.assessment.AssessmentResultMapper;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.prison.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 测评结果 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class AssessmentResultServiceImpl implements AssessmentResultService {
|
||||
|
||||
@Resource
|
||||
private AssessmentResultMapper assessmentResultMapper;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createAssessmentResult(AssessmentResultSaveReqVO createReqVO) {
|
||||
AssessmentResultDO result = BeanUtils.toBean(createReqVO, AssessmentResultDO.class);
|
||||
assessmentResultMapper.insert(result);
|
||||
return result.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchCreateAssessmentResult(List<AssessmentResultSaveReqVO> results) {
|
||||
if (CollUtil.isEmpty(results)) {
|
||||
return;
|
||||
}
|
||||
List<AssessmentResultDO> resultList = BeanUtils.toBean(results, AssessmentResultDO.class);
|
||||
assessmentResultMapper.insertBatch(resultList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateAssessmentResult(AssessmentResultSaveReqVO updateReqVO) {
|
||||
validateAssessmentResultExists(updateReqVO.getId());
|
||||
AssessmentResultDO updateObj = BeanUtils.toBean(updateReqVO, AssessmentResultDO.class);
|
||||
assessmentResultMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteAssessmentResult(Long id) {
|
||||
validateAssessmentResultExists(id);
|
||||
assessmentResultMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteAssessmentResultListByIds(List<Long> ids) {
|
||||
assessmentResultMapper.deleteByIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssessmentResultDO getAssessmentResult(Long id) {
|
||||
return assessmentResultMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<AssessmentResultDO> getAssessmentResultPage(AssessmentResultPageReqVO pageReqVO) {
|
||||
return assessmentResultMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AssessmentResultDO> getResultsByAnswerId(Long answerId) {
|
||||
return assessmentResultMapper.selectListByAnswerId(answerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AssessmentResultDO> getResultsByAssessmentRecordId(Long assessmentRecordId) {
|
||||
return assessmentResultMapper.selectListByAssessmentRecordId(assessmentRecordId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AssessmentResultDO> getNeedManualReviewList() {
|
||||
return assessmentResultMapper.selectListNeedManualReview();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void manualReview(AssessmentResultManualReviewReqVO reviewReqVO) {
|
||||
AssessmentResultDO result = validateAssessmentResultExists(reviewReqVO.getId());
|
||||
result.setManualScore(reviewReqVO.getManualScore());
|
||||
result.setManualComment(reviewReqVO.getManualComment());
|
||||
result.setManualReviewStatus(2); // 已评阅
|
||||
result.setReviewerId(reviewReqVO.getReviewerId());
|
||||
result.setReviewerName(reviewReqVO.getReviewerName());
|
||||
result.setReviewTime(LocalDateTime.now());
|
||||
result.setScore(reviewReqVO.getManualScore());
|
||||
assessmentResultMapper.updateById(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void autoScore(Long answerId) {
|
||||
List<AssessmentResultDO> results = assessmentResultMapper.selectListByAnswerId(answerId);
|
||||
BigDecimal totalScore = BigDecimal.ZERO;
|
||||
|
||||
for (AssessmentResultDO result : results) {
|
||||
if (!result.getNeedManualReview()) {
|
||||
// 客观题自动评分
|
||||
if (result.getCorrect() != null && result.getCorrect()) {
|
||||
result.setScore(result.getQuestionScore());
|
||||
} else {
|
||||
result.setScore(BigDecimal.ZERO);
|
||||
}
|
||||
totalScore = totalScore.add(result.getScore());
|
||||
assessmentResultMapper.updateById(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AssessmentResultDO validateAssessmentResultExists(Long id) {
|
||||
AssessmentResultDO result = assessmentResultMapper.selectById(id);
|
||||
if (result == null) {
|
||||
throw exception(ASSESSMENT_RESULT_NOT_EXISTS);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,198 @@
|
||||
package cn.iocoder.yudao.module.prison.service.assessment.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import cn.iocoder.yudao.module.prison.controller.admin.assessment.vo.*;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentStatisticsDO;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentAnswerDO;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.assessment.AssessmentResultDO;
|
||||
import cn.iocoder.yudao.module.prison.dal.mysql.assessment.AssessmentAnswerMapper;
|
||||
import cn.iocoder.yudao.module.prison.dal.mysql.assessment.AssessmentResultMapper;
|
||||
import cn.iocoder.yudao.module.prison.dal.mysql.assessment.AssessmentStatisticsMapper;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.prison.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 测评统计 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class AssessmentStatisticsServiceImpl implements AssessmentStatisticsService {
|
||||
|
||||
@Resource
|
||||
private AssessmentStatisticsMapper assessmentStatisticsMapper;
|
||||
|
||||
@Resource
|
||||
private AssessmentAnswerMapper assessmentAnswerMapper;
|
||||
|
||||
@Resource
|
||||
private AssessmentResultMapper assessmentResultMapper;
|
||||
|
||||
@Override
|
||||
public AssessmentStatisticsDO getAssessmentStatistics(Long id) {
|
||||
return assessmentStatisticsMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<AssessmentStatisticsDO> getAssessmentStatisticsPage(AssessmentStatisticsPageReqVO pageReqVO) {
|
||||
return assessmentStatisticsMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public AssessmentStatisticsDO generateStatistics(Long assessmentRecordId) {
|
||||
// 查询所有答卷
|
||||
List<AssessmentAnswerDO> answers = assessmentAnswerMapper.selectListByAssessmentRecordId(assessmentRecordId);
|
||||
|
||||
int totalCount = answers.size();
|
||||
int completedCount = (int) answers.stream().filter(a -> a.getStatus() == 5).count();
|
||||
int passedCount = (int) answers.stream().filter(a -> a.getPassed() != null && a.getPassed()).count();
|
||||
|
||||
// 计算统计数据
|
||||
BigDecimal completionRate = totalCount > 0 ?
|
||||
new BigDecimal(completedCount).multiply(new BigDecimal(100)).divide(new BigDecimal(totalCount), 2, java.math.RoundingMode.HALF_UP) :
|
||||
BigDecimal.ZERO;
|
||||
|
||||
List<BigDecimal> scores = answers.stream()
|
||||
.map(AssessmentAnswerDO::getTotalScore)
|
||||
.filter(Objects::nonNull)
|
||||
.sorted()
|
||||
.toList();
|
||||
|
||||
BigDecimal averageScore = scores.isEmpty() ? BigDecimal.ZERO :
|
||||
scores.stream().reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal(scores.size()), 2, java.math.RoundingMode.HALF_UP);
|
||||
BigDecimal highestScore = scores.isEmpty() ? BigDecimal.ZERO : scores.get(scores.size() - 1);
|
||||
BigDecimal lowestScore = scores.isEmpty() ? BigDecimal.ZERO : scores.get(0);
|
||||
|
||||
BigDecimal passRate = completedCount > 0 ?
|
||||
new BigDecimal(passedCount).multiply(new BigDecimal(100)).divide(new BigDecimal(completedCount), 2, java.math.RoundingMode.HALF_UP) :
|
||||
BigDecimal.ZERO;
|
||||
|
||||
int excellentCount = (int) answers.stream().filter(a ->
|
||||
a.getTotalScore() != null && a.getTotalScore().compareTo(new BigDecimal("90")) >= 0
|
||||
).count();
|
||||
|
||||
int riskCount = (int) answers.stream().filter(a ->
|
||||
a.getTotalScore() != null && a.getTotalScore().compareTo(new BigDecimal("60")) < 0
|
||||
).count();
|
||||
|
||||
BigDecimal excellentRate = completedCount > 0 ?
|
||||
new BigDecimal(excellentCount).multiply(new BigDecimal(100)).divide(new BigDecimal(completedCount), 2, java.math.RoundingMode.HALF_UP) :
|
||||
BigDecimal.ZERO;
|
||||
|
||||
BigDecimal riskRate = completedCount > 0 ?
|
||||
new BigDecimal(riskCount).multiply(new BigDecimal(100)).divide(new BigDecimal(completedCount), 2, java.math.RoundingMode.HALF_UP) :
|
||||
BigDecimal.ZERO;
|
||||
|
||||
// 生成统计数据
|
||||
AssessmentStatisticsDO statistics = new AssessmentStatisticsDO();
|
||||
statistics.setAssessmentRecordId(assessmentRecordId);
|
||||
statistics.setTotalCount(totalCount);
|
||||
statistics.setCompletedCount(completedCount);
|
||||
statistics.setCompletionRate(completionRate);
|
||||
statistics.setAverageScore(averageScore);
|
||||
statistics.setHighestScore(highestScore);
|
||||
statistics.setLowestScore(lowestScore);
|
||||
statistics.setPassedCount(passedCount);
|
||||
statistics.setPassRate(passRate);
|
||||
statistics.setExcellentCount(excellentCount);
|
||||
statistics.setExcellentRate(excellentRate);
|
||||
statistics.setRiskCount(riskCount);
|
||||
statistics.setRiskRate(riskRate);
|
||||
statistics.setStatisticsTime(LocalDateTime.now());
|
||||
|
||||
// 生成分数分布
|
||||
Map<String, Integer> scoreDist = getScoreDistribution(assessmentRecordId);
|
||||
statistics.setScoreDistribution(new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(scoreDist));
|
||||
|
||||
// 生成风险分布
|
||||
Map<String, Integer> riskDist = getRiskDistribution(assessmentRecordId);
|
||||
statistics.setRiskDistribution(new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(riskDist));
|
||||
|
||||
assessmentStatisticsMapper.insert(statistics);
|
||||
return statistics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getCompletionRate(Long assessmentRecordId) {
|
||||
List<AssessmentAnswerDO> answers = assessmentAnswerMapper.selectListByAssessmentRecordId(assessmentRecordId);
|
||||
int totalCount = answers.size();
|
||||
int completedCount = (int) answers.stream().filter(a -> a.getStatus() == 5).count();
|
||||
if (totalCount == 0) return BigDecimal.ZERO;
|
||||
return new BigDecimal(completedCount).multiply(new BigDecimal(100)).divide(new BigDecimal(totalCount), 2, java.math.RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Integer> getScoreDistribution(Long assessmentRecordId) {
|
||||
Map<String, Integer> distribution = new LinkedHashMap<>();
|
||||
distribution.put("0-20", 0);
|
||||
distribution.put("20-40", 0);
|
||||
distribution.put("40-60", 0);
|
||||
distribution.put("60-80", 0);
|
||||
distribution.put("80-100", 0);
|
||||
|
||||
List<AssessmentAnswerDO> answers = assessmentAnswerMapper.selectListByAssessmentRecordId(assessmentRecordId);
|
||||
for (AssessmentAnswerDO answer : answers) {
|
||||
if (answer.getTotalScore() != null) {
|
||||
BigDecimal score = answer.getTotalScore();
|
||||
if (score.compareTo(new BigDecimal("20")) <= 0) {
|
||||
distribution.merge("0-20", 1, Integer::sum);
|
||||
} else if (score.compareTo(new BigDecimal("40")) <= 0) {
|
||||
distribution.merge("20-40", 1, Integer::sum);
|
||||
} else if (score.compareTo(new BigDecimal("60")) <= 0) {
|
||||
distribution.merge("40-60", 1, Integer::sum);
|
||||
} else if (score.compareTo(new BigDecimal("80")) <= 0) {
|
||||
distribution.merge("60-80", 1, Integer::sum);
|
||||
} else {
|
||||
distribution.merge("80-100", 1, Integer::sum);
|
||||
}
|
||||
}
|
||||
}
|
||||
return distribution;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Integer> getRiskDistribution(Long assessmentRecordId) {
|
||||
Map<String, Integer> distribution = new LinkedHashMap<>();
|
||||
distribution.put("low", 0); // 低风险
|
||||
distribution.put("medium", 0); // 中风险
|
||||
distribution.put("high", 0); // 高风险
|
||||
|
||||
List<AssessmentAnswerDO> answers = assessmentAnswerMapper.selectListByAssessmentRecordId(assessmentRecordId);
|
||||
for (AssessmentAnswerDO answer : answers) {
|
||||
if (answer.getTotalScore() != null && answer.getPassed() != null) {
|
||||
if (answer.getPassed()) {
|
||||
distribution.merge("low", 1, Integer::sum);
|
||||
} else {
|
||||
BigDecimal score = answer.getTotalScore();
|
||||
if (score.compareTo(new BigDecimal("40")) < 0) {
|
||||
distribution.merge("high", 1, Integer::sum);
|
||||
} else {
|
||||
distribution.merge("medium", 1, Integer::sum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return distribution;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssessmentStatisticsRespVO getAssessmentReport(Long assessmentRecordId) {
|
||||
AssessmentStatisticsDO statistics = generateStatistics(assessmentRecordId);
|
||||
return BeanUtils.toBean(statistics, AssessmentStatisticsRespVO.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -60,10 +60,19 @@ public class QuestionServiceImpl implements QuestionService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteQuestionListByIds(List<Long> ids) {
|
||||
public void deleteQuestionListByIds(List<Long> ids) {
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
// 校验所有ID都存在
|
||||
Long count = questionMapper.selectCount(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<QuestionDO>()
|
||||
.in(QuestionDO::getId, ids));
|
||||
if (count == null || count != ids.size()) {
|
||||
throw exception(QUESTION_NOT_EXISTS);
|
||||
}
|
||||
// 删除
|
||||
questionMapper.deleteByIds(ids);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void validateQuestionExists(Long id) {
|
||||
@ -88,17 +97,21 @@ public class QuestionServiceImpl implements QuestionService {
|
||||
if (CollUtil.isEmpty(updateList)) {
|
||||
return;
|
||||
}
|
||||
// 批量更新
|
||||
for (QuestionSaveReqVO updateReqVO : updateList) {
|
||||
// 校验存在
|
||||
validateQuestionExists(updateReqVO.getId());
|
||||
// 更新(仅更新排序和分区相关字段)
|
||||
QuestionDO updateObj = new QuestionDO();
|
||||
updateObj.setId(updateReqVO.getId());
|
||||
updateObj.setPartName(updateReqVO.getPartName());
|
||||
updateObj.setPartSort(updateReqVO.getPartSort());
|
||||
updateObj.setSort(updateReqVO.getSort());
|
||||
questionMapper.updateById(updateObj);
|
||||
// 校验所有ID存在性
|
||||
List<Long> ids = convertList(updateList, QuestionSaveReqVO::getId);
|
||||
Long count = questionMapper.selectCount(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<QuestionDO>()
|
||||
.in(QuestionDO::getId, ids));
|
||||
if (count == null || count != ids.size()) {
|
||||
throw exception(QUESTION_NOT_EXISTS);
|
||||
}
|
||||
// 批量更新 - 逐条更新以确保兼容性
|
||||
for (QuestionSaveReqVO vo : updateList) {
|
||||
QuestionDO obj = new QuestionDO();
|
||||
obj.setId(vo.getId());
|
||||
obj.setPartName(vo.getPartName());
|
||||
obj.setPartSort(vo.getPartSort());
|
||||
obj.setSort(vo.getSort());
|
||||
questionMapper.updateById(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -60,10 +60,19 @@ public class QuestionnaireRecordServiceImpl implements QuestionnaireRecordServic
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteQuestionnaireRecordListByIds(List<Long> ids) {
|
||||
public void deleteQuestionnaireRecordListByIds(List<Long> ids) {
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
// 校验所有ID都存在
|
||||
Long count = questionnaireRecordMapper.selectCount(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<QuestionnaireRecordDO>()
|
||||
.in(QuestionnaireRecordDO::getId, ids));
|
||||
if (count == null || count != ids.size()) {
|
||||
throw exception(QUESTIONNAIRE_RECORD_NOT_EXISTS);
|
||||
}
|
||||
// 删除
|
||||
questionnaireRecordMapper.deleteByIds(ids);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void validateQuestionnaireRecordExists(Long id) {
|
||||
|
||||
@ -0,0 +1,374 @@
|
||||
package cn.iocoder.yudao.module.prison.service.riskassessment;
|
||||
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.prisoner.PrisonerDO;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.riskassessment.RiskAssessmentDO;
|
||||
import cn.iocoder.yudao.module.prison.dal.dataobject.score.ScoreDO;
|
||||
import cn.iocoder.yudao.module.prison.dal.mysql.prisoner.PrisonerMapper;
|
||||
import cn.iocoder.yudao.module.prison.dal.mysql.riskassessment.RiskAssessmentMapper;
|
||||
import cn.iocoder.yudao.module.prison.dal.mysql.score.ScoreDetailMapper;
|
||||
import cn.iocoder.yudao.module.prison.service.riskassessment.dto.AssessmentContext;
|
||||
import cn.iocoder.yudao.module.prison.service.riskassessment.enums.AssessmentTypeEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.Period;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 评估数据聚合服务
|
||||
* 从多个数据源聚合评估所需数据
|
||||
*
|
||||
* @author XLLC Team
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class AssessmentDataAggregator {
|
||||
|
||||
@Resource
|
||||
private PrisonerMapper prisonerMapper;
|
||||
|
||||
@Resource
|
||||
private RiskAssessmentMapper riskAssessmentMapper;
|
||||
|
||||
@Resource
|
||||
private ScoreDetailMapper scoreDetailMapper;
|
||||
|
||||
@Resource
|
||||
private DataMasker dataMasker;
|
||||
|
||||
/**
|
||||
* 聚合指定罪犯的评估数据
|
||||
*
|
||||
* @param prisonerId 罪犯ID
|
||||
* @param assessmentType 评估类型
|
||||
* @param assessorId 评估人ID
|
||||
* @param assessorName 评估人姓名
|
||||
* @return 聚合后的评估上下文
|
||||
*/
|
||||
public AssessmentContext aggregate(Long prisonerId, Integer assessmentType, Long assessorId, String assessorName) {
|
||||
log.debug("开始聚合罪犯ID={}的评估数据", prisonerId);
|
||||
|
||||
// 1. 获取罪犯基础信息
|
||||
PrisonerDO prisoner = prisonerMapper.selectById(prisonerId);
|
||||
if (prisoner == null) {
|
||||
throw new IllegalArgumentException("罪犯不存在: " + prisonerId);
|
||||
}
|
||||
|
||||
// 2. 构建基础上下文
|
||||
AssessmentContext.AssessmentContextBuilder builder = AssessmentContext.builder()
|
||||
.prisonerId(String.valueOf(prisonerId))
|
||||
.prisonerNo(prisoner.getPrisonerNo())
|
||||
.assessmentType(AssessmentTypeEnum.getName(assessmentType))
|
||||
.assessmentDate(LocalDate.now())
|
||||
.assessorId(assessorId)
|
||||
.assessorName(assessorName);
|
||||
|
||||
// 3. 聚合犯罪基本信息(泛化处理)
|
||||
aggregateCrimeInfo(builder, prisoner);
|
||||
|
||||
// 4. 聚合心理评估得分
|
||||
aggregatePsychologyScores(builder, prisonerId);
|
||||
|
||||
// 5. 聚合行为表现数据
|
||||
aggregateBehaviorData(builder, prisonerId);
|
||||
|
||||
// 6. 聚合改造态度数据
|
||||
aggregateReformData(builder, prisonerId);
|
||||
|
||||
// 7. 聚合消费数据
|
||||
aggregateConsumptionData(builder, prisonerId);
|
||||
|
||||
// 8. 聚合历史评估数据
|
||||
aggregateHistoryData(builder, prisonerId);
|
||||
|
||||
// 9. 聚合问卷答题数据
|
||||
aggregateQuestionnaireData(builder, prisonerId);
|
||||
|
||||
AssessmentContext context = builder.build();
|
||||
log.debug("数据聚合完成,罪犯编号: {}", context.getPrisonerNo());
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* 聚合犯罪基本信息
|
||||
*/
|
||||
private void aggregateCrimeInfo(AssessmentContext.AssessmentContextBuilder builder, PrisonerDO prisoner) {
|
||||
// 犯罪类型泛化
|
||||
String crimeCategory = dataMasker.generalizeCrimeType(
|
||||
Optional.ofNullable(prisoner.getCrimeType()).orElse("未知")
|
||||
);
|
||||
|
||||
// 刑期处理
|
||||
Integer sentenceYears = 0;
|
||||
if (prisoner.getSentenceDate() != null && prisoner.getReleaseDate() != null) {
|
||||
Period period = Period.between(prisoner.getSentenceDate(), prisoner.getReleaseDate());
|
||||
sentenceYears = period.getYears();
|
||||
}
|
||||
|
||||
// 入监时长
|
||||
int imprisonmentMonths = 0;
|
||||
if (prisoner.getEntryDate() != null) {
|
||||
Period period = Period.between(prisoner.getEntryDate(), LocalDate.now());
|
||||
imprisonmentMonths = period.getYears() * 12 + period.getMonths();
|
||||
}
|
||||
|
||||
builder
|
||||
.crimeCategory(crimeCategory)
|
||||
.sentenceYears(sentenceYears)
|
||||
.isRecidivist(Boolean.TRUE.equals(prisoner.getIsRecidivist()))
|
||||
.imprisonmentMonths(imprisonmentMonths);
|
||||
}
|
||||
|
||||
/**
|
||||
* 聚合心理评估得分
|
||||
*/
|
||||
private void aggregatePsychologyScores(AssessmentContext.AssessmentContextBuilder builder, Long prisonerId) {
|
||||
// 获取最近一次危险评估记录
|
||||
RiskAssessmentDO latestAssessment = riskAssessmentMapper.selectOne(
|
||||
new RiskAssessmentMapper.QueryWrapper()
|
||||
.eq("prisoner_id", prisonerId)
|
||||
.orderByDesc("assessment_date")
|
||||
.last("LIMIT 1")
|
||||
);
|
||||
|
||||
if (latestAssessment != null) {
|
||||
builder
|
||||
.violenceScore(normalizeScore(latestAssessment.getViolenceScore()))
|
||||
.escapeScore(normalizeScore(latestAssessment.getEscapeScore()))
|
||||
.suicideScore(normalizeScore(latestAssessment.getSuicideScore()));
|
||||
} else {
|
||||
// 默认值
|
||||
builder
|
||||
.violenceScore(BigDecimal.ZERO)
|
||||
.escapeScore(BigDecimal.ZERO)
|
||||
.suicideScore(BigDecimal.ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 聚合行为表现数据
|
||||
*/
|
||||
private void aggregateBehaviorData(AssessmentContext.AssessmentContextBuilder builder, Long prisonerId) {
|
||||
// 计算近6月的统计数据
|
||||
LocalDate sixMonthsAgo = LocalDate.now().minusMonths(6);
|
||||
|
||||
// 查询近6月的计分记录
|
||||
List<ScoreDO> recentScores = scoreDetailMapper.selectList(
|
||||
new ScoreDO().builder().prisonerId(prisonerId).build(),
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ScoreDO>()
|
||||
.ge(ScoreDO::getRecordDate, sixMonthsAgo)
|
||||
);
|
||||
|
||||
if (recentScores.isEmpty()) {
|
||||
builder
|
||||
.avgScore(new BigDecimal("70")) // 默认中等水平
|
||||
.violationCount6Month(0)
|
||||
.praiseCount6Month(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算平均分
|
||||
BigDecimal totalScore = recentScores.stream()
|
||||
.map(ScoreDO::getTotalScore)
|
||||
.filter(s -> s != null)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
BigDecimal avgScore = totalScore.divide(
|
||||
new BigDecimal(recentScores.size()),
|
||||
2,
|
||||
RoundingMode.HALF_UP
|
||||
);
|
||||
|
||||
// 统计违规和表扬次数(简化处理)
|
||||
int violationCount = 0;
|
||||
int praiseCount = 0;
|
||||
for (ScoreDO score : recentScores) {
|
||||
if (score.getDeductionPoints() != null && score.getDeductionPoints().intValue() > 0) {
|
||||
violationCount++;
|
||||
}
|
||||
if (score.getRewardPoints() != null && score.getRewardPoints().intValue() > 0) {
|
||||
praiseCount++;
|
||||
}
|
||||
}
|
||||
|
||||
builder
|
||||
.avgScore(avgScore)
|
||||
.violationCount6Month(violationCount)
|
||||
.praiseCount6Month(praiseCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 聚合改造态度数据
|
||||
* 这里简化处理,实际应根据问卷答题情况计算
|
||||
*/
|
||||
private void aggregateReformData(AssessmentContext.AssessmentContextBuilder builder, Long prisonerId) {
|
||||
// 简化实现:基于行为得分推算
|
||||
BigDecimal avgScore = builder.build().getAvgScore();
|
||||
|
||||
builder
|
||||
.laborPerformance(avgScore) // 用平均分作为劳动表现评分
|
||||
.educationParticipation(avgScore) // 用平均分作为教育参与度
|
||||
.thoughtReportQuality(avgScore); // 用平均分作为思想汇报质量
|
||||
}
|
||||
|
||||
/**
|
||||
* 聚合消费数据(区间化处理)
|
||||
*/
|
||||
private void aggregateConsumptionData(AssessmentContext.AssessmentContextBuilder builder, Long prisonerId) {
|
||||
// TODO: 待消费模块完成后接入真实数据
|
||||
// 暂时使用默认值
|
||||
builder
|
||||
.consumptionLevel(2) // 中等消费
|
||||
.hasAbnormalConsumption(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 聚合历史评估数据
|
||||
*/
|
||||
private void aggregateHistoryData(AssessmentContext.AssessmentContextBuilder builder, Long prisonerId) {
|
||||
// 获取历史评估记录
|
||||
List<RiskAssessmentDO> historyAssessments = riskAssessmentMapper.selectList(
|
||||
new RiskAssessmentMapper.QueryWrapper()
|
||||
.eq("prisoner_id", prisonerId)
|
||||
.orderByDesc("assessment_date")
|
||||
);
|
||||
|
||||
if (historyAssessments.isEmpty()) {
|
||||
// 首次评估
|
||||
builder
|
||||
.lastRiskLevel(null)
|
||||
.lastTotalScore(null)
|
||||
.lastAssessmentMonthsAgo(null)
|
||||
.riskTrend("stable")
|
||||
.assessmentHistoryCount(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// 最近一次评估
|
||||
RiskAssessmentDO latest = historyAssessments.get(0);
|
||||
|
||||
builder
|
||||
.lastRiskLevel(latest.getRiskLevel())
|
||||
.lastTotalScore(latest.getTotalScore())
|
||||
.assessmentHistoryCount(historyAssessments.size());
|
||||
|
||||
// 计算距今时长
|
||||
if (latest.getAssessmentDate() != null) {
|
||||
Period period = Period.between(latest.getAssessmentDate(), LocalDate.now());
|
||||
int monthsAgo = period.getYears() * 12 + period.getMonths();
|
||||
builder.lastAssessmentMonthsAgo(monthsAgo);
|
||||
}
|
||||
|
||||
// 计算风险趋势(基于最近3次评估)
|
||||
String trend = calculateTrend(historyAssessments);
|
||||
builder.riskTrend(trend);
|
||||
}
|
||||
|
||||
/**
|
||||
* 聚合问卷答题数据
|
||||
* 根据各维度问卷的答题情况计算得分
|
||||
*/
|
||||
private void aggregateQuestionnaireData(AssessmentContext.AssessmentContextBuilder builder, Long prisonerId) {
|
||||
// TODO: 待问卷模块完成后接入真实数据
|
||||
// 暂时使用默认值,实际应从问卷答题记录中计算
|
||||
builder
|
||||
.criminalHistoryScore(new BigDecimal("50"))
|
||||
.familyBackgroundScore(new BigDecimal("50"))
|
||||
.socialSupportScore(new BigDecimal("50"))
|
||||
.psychologicalStateScore(builder.build().getViolenceScore())
|
||||
.behaviorPerformanceScore(builder.build().getAvgScore())
|
||||
.reformAttitudeScore(builder.build().getLaborPerformance());
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算风险趋势
|
||||
*/
|
||||
private String calculateTrend(List<RiskAssessmentDO> assessments) {
|
||||
if (assessments.size() < 2) {
|
||||
return "stable";
|
||||
}
|
||||
|
||||
// 取最近3次评估
|
||||
int count = Math.min(3, assessments.size());
|
||||
List<RiskAssessmentDO> recent = assessments.subList(0, count);
|
||||
|
||||
// 计算得分变化
|
||||
double sumDiff = 0;
|
||||
for (int i = 1; i < recent.size(); i++) {
|
||||
BigDecimal current = recent.get(i).getTotalScore();
|
||||
BigDecimal previous = recent.get(i - 1).getTotalScore();
|
||||
if (current != null && previous != null) {
|
||||
sumDiff += current.subtract(previous).doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
if (sumDiff > 10) {
|
||||
return "rising"; // 上升
|
||||
} else if (sumDiff < -10) {
|
||||
return "declining"; // 下降
|
||||
} else {
|
||||
return "stable"; // 稳定
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 标准化分数到0-100范围
|
||||
*/
|
||||
private BigDecimal normalizeScore(BigDecimal score) {
|
||||
if (score == null) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
// 假设原始分数范围是0-100,直接返回
|
||||
return score;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据脱敏工具
|
||||
*/
|
||||
@Service
|
||||
public static class DataMasker {
|
||||
|
||||
/**
|
||||
* 犯罪类型泛化映射
|
||||
*/
|
||||
private static final Map<String, String> CRIME_TYPE_MAPPING = Map.of(
|
||||
"盗窃", "财产类犯罪",
|
||||
"抢劫", "暴力类犯罪",
|
||||
"抢夺", "暴力类犯罪",
|
||||
"故意伤害", "暴力类犯罪",
|
||||
"故意杀人", "严重暴力犯罪",
|
||||
"强奸", "严重暴力犯罪",
|
||||
"贩毒", "涉毒类犯罪",
|
||||
"制造毒品", "涉毒类犯罪",
|
||||
"诈骗", "财产类犯罪",
|
||||
"敲诈勒索", "财产类犯罪",
|
||||
"组织卖淫", "其他类型犯罪",
|
||||
"赌博", "其他类型犯罪"
|
||||
);
|
||||
|
||||
/**
|
||||
* 泛化犯罪类型
|
||||
*/
|
||||
public String generalizeCrimeType(String originalType) {
|
||||
if (!StringUtils.hasText(originalType)) {
|
||||
return "其他类型犯罪";
|
||||
}
|
||||
return CRIME_TYPE_MAPPING.getOrDefault(originalType, "其他类型犯罪");
|
||||
}
|
||||
|
||||
/**
|
||||
* 泛化地名(预留)
|
||||
*/
|
||||
public String generalizeLocation(String originalLocation) {
|
||||
// 暂时不处理,实际应根据需要进行脱敏
|
||||
return originalLocation;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,246 @@
|
||||
package cn.iocoder.yudao.module.prison.service.riskassessment;
|
||||
|
||||
import cn.iocoder.yudao.module.prison.service.riskassessment.dto.AssessmentContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 评估提示词构建器
|
||||
* 根据评估上下文构建发送给LLM的提示词
|
||||
*
|
||||
* @author XLLC Team
|
||||
*/
|
||||
@Component
|
||||
public class AssessmentPromptBuilder {
|
||||
|
||||
/**
|
||||
* 构建危险评估提示词
|
||||
*
|
||||
* @param context 评估上下文
|
||||
* @return 提示词文本
|
||||
*/
|
||||
public String build(AssessmentContext context) {
|
||||
StringBuilder prompt = new StringBuilder();
|
||||
|
||||
// 1. 角色定义
|
||||
prompt.append(buildRoleDefinition());
|
||||
|
||||
// 2. 任务说明
|
||||
prompt.append(buildTaskDescription(context));
|
||||
|
||||
// 3. 评估数据
|
||||
prompt.append(buildAssessmentData(context));
|
||||
|
||||
// 4. 评估规则
|
||||
prompt.append(buildAssessmentRules());
|
||||
|
||||
// 5. 输出要求
|
||||
prompt.append(buildOutputRequirements());
|
||||
|
||||
// 6. 评估原则
|
||||
prompt.append(buildPrinciples());
|
||||
|
||||
// 7. 开始评估指令
|
||||
prompt.append(buildStartInstruction());
|
||||
|
||||
return prompt.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建角色定义
|
||||
*/
|
||||
private String buildRoleDefinition() {
|
||||
return """
|
||||
# 角色定义
|
||||
你是一位拥有20年监狱工作经验的资深危险评估专家,精通心理学、犯罪学和行为分析。你需要基于提供的数据,对罪犯进行专业的危险等级评估。
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建任务说明
|
||||
*/
|
||||
private String buildTaskDescription(AssessmentContext context) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("# 任务说明\n\n");
|
||||
sb.append("根据以下【评估数据】对罪犯进行综合危险评估。\n\n");
|
||||
sb.append("**评估类型**: ").append(context.getAssessmentType()).append("\n\n");
|
||||
sb.append("请基于客观数据和专业判断,给出风险等级评估。\n\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建评估数据
|
||||
*/
|
||||
private String buildAssessmentData(AssessmentContext context) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("# 评估数据\n\n");
|
||||
sb.append("```json\n");
|
||||
sb.append(context.toJson());
|
||||
sb.append("\n```\n\n");
|
||||
|
||||
sb.append("## 数据说明\n\n");
|
||||
|
||||
// 心理评估得分说明
|
||||
sb.append("### 心理评估得分(0-100分,越高越危险)\n");
|
||||
sb.append("- 暴力倾向: ").append(context.getViolenceScore()).append("分\n");
|
||||
sb.append("- 脱逃倾向: ").append(context.getEscapeScore()).append("分\n");
|
||||
sb.append("- 自杀倾向: ").append(context.getSuicideScore()).append("分\n\n");
|
||||
|
||||
// 行为表现说明
|
||||
sb.append("### 行为表现\n");
|
||||
sb.append("- 计分考核平均分: ").append(context.getAvgScore()).append("分\n");
|
||||
sb.append("- 近6月违规次数: ").append(context.getViolationCount6Month()).append("次\n");
|
||||
sb.append("- 近6月表扬次数: ").append(context.getPraiseCount6Month()).append("次\n\n");
|
||||
|
||||
// 历史评估说明
|
||||
if (context.getLastRiskLevel() != null) {
|
||||
sb.append("### 历史评估\n");
|
||||
sb.append("- 上次风险等级: ").append(formatRiskLevel(context.getLastRiskLevel())).append("\n");
|
||||
sb.append("- 历史风险趋势: ").append(formatTrend(context.getRiskTrend())).append("\n\n");
|
||||
}
|
||||
|
||||
// 特殊因素
|
||||
if (hasRiskFactors(context)) {
|
||||
sb.append("### 特殊风险因素\n");
|
||||
if (Boolean.TRUE.equals(context.getHasFamilyCrisis())) {
|
||||
sb.append("- 存在家庭变故\n");
|
||||
}
|
||||
if (Boolean.TRUE.equals(context.getHasConflictWithPrisoners())) {
|
||||
sb.append("- 近期与他犯有矛盾\n");
|
||||
}
|
||||
if (Boolean.TRUE.equals(context.getHasMoodAbnormality())) {
|
||||
sb.append("- 近期情绪异常\n");
|
||||
}
|
||||
if (StringUtils.hasText(context.getOtherRiskFactors())) {
|
||||
sb.append("- 其他: ").append(context.getOtherRiskFactors()).append("\n");
|
||||
}
|
||||
sb.append("\n");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建评估规则
|
||||
*/
|
||||
private String buildAssessmentRules() {
|
||||
return """
|
||||
# 评估规则
|
||||
|
||||
根据综合得分和风险因素确定风险等级:
|
||||
|
||||
| 风险等级 | 分值范围 | 说明 |
|
||||
|---------|---------|------|
|
||||
| 1-低风险 | < 40分 | 无明显风险因素,管理正常 |
|
||||
| 2-中风险 | 40-69分 | 存在一定风险因素,需要关注 |
|
||||
| 3-高风险 | 70-89分 | 存在明显风险因素,需要重点管控 |
|
||||
| 4-极高风险 | ≥ 90分 | 存在严重风险因素,需要立即干预 |
|
||||
|
||||
**注意**: 风险因素的存在可能导致等级上调,即使得分较低。
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建输出要求
|
||||
*/
|
||||
private String buildOutputRequirements() {
|
||||
return """
|
||||
# 输出要求
|
||||
|
||||
请以JSON格式输出评估结果,包含以下字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"riskLevel": <1-4整数>,
|
||||
"confidence": <0.0-1.0小数>,
|
||||
"keyRiskFactors": ["因素1", "因素2", "因素3"],
|
||||
"analysis": "<综合分析说明,100-200字>",
|
||||
"suggestions": ["建议1", "建议2", "建议3"],
|
||||
"attentionPoints": ["需要关注的点1", "需要关注的点2"]
|
||||
}
|
||||
```
|
||||
|
||||
**字段说明**:
|
||||
- `riskLevel`: 风险等级(1-4)
|
||||
- `confidence`: 评估置信度(0-1),反映评估的确定性
|
||||
- `keyRiskFactors`: 最关键的风险因素(最多3个)
|
||||
- `analysis`: 综合分析说明
|
||||
- `suggestions`: 针对性管控建议(具体可操作)
|
||||
- `attentionPoints`: 需要特别关注的点
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建评估原则
|
||||
*/
|
||||
private String buildPrinciples() {
|
||||
return """
|
||||
# 评估原则
|
||||
|
||||
1. **客观公正**: 基于数据进行分析,不带主观偏见
|
||||
2. **综合判断**: 考虑各因素之间的关联性,而非简单求和
|
||||
3. **重点突出**: 识别最关键的风险因素
|
||||
4. **建议可行**: 建议要具体、可操作
|
||||
5. **审慎判断**: 对于边界情况给出审慎判断
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建开始评估指令
|
||||
*/
|
||||
private String buildStartInstruction() {
|
||||
return """
|
||||
# 开始评估
|
||||
|
||||
请基于以上数据和规则,开始进行危险等级评估。
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化风险等级
|
||||
*/
|
||||
private String formatRiskLevel(Integer level) {
|
||||
if (level == null) return "无";
|
||||
return switch (level) {
|
||||
case 1 -> "1-低风险";
|
||||
case 2 -> "2-中风险";
|
||||
case 3 -> "3-高风险";
|
||||
case 4 -> "4-极高风险";
|
||||
default -> "未知(" + level + ")";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化趋势描述
|
||||
*/
|
||||
private String formatTrend(String trend) {
|
||||
if (trend == null) return "稳定";
|
||||
return switch (trend) {
|
||||
case "rising" -> "上升趋势";
|
||||
case "declining" -> "下降趋势";
|
||||
case "fluctuating" -> "波动";
|
||||
default -> "稳定";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否存在特殊风险因素
|
||||
*/
|
||||
private boolean hasRiskFactors(AssessmentContext context) {
|
||||
return Boolean.TRUE.equals(context.getHasFamilyCrisis())
|
||||
|| Boolean.TRUE.equals(context.getHasConflictWithPrisoners())
|
||||
|| Boolean.TRUE.equals(context.getHasMoodAbnormality())
|
||||
|| StringUtils.hasText(context.getOtherRiskFactors());
|
||||
}
|
||||
|
||||
// 需要引入 StringUtils
|
||||
private static class StringUtils {
|
||||
public static boolean hasText(String str) {
|
||||
return str != null && !str.trim().isEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,296 @@
|
||||
package cn.iocoder.yudao.module.prison.service.riskassessment.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 危险评估上下文(发送给LLM的数据结构)
|
||||
* 包含聚合后的评估所需数据
|
||||
*
|
||||
* @author XLLC Team
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class AssessmentContext {
|
||||
|
||||
// ==================== 标识信息 ====================
|
||||
|
||||
/**
|
||||
* 罪犯ID(脱敏后的标识)
|
||||
*/
|
||||
private String prisonerId;
|
||||
|
||||
/**
|
||||
* 罪犯编号(保留,用于结果关联)
|
||||
*/
|
||||
private String prisonerNo;
|
||||
|
||||
// ==================== 犯罪基本信息(泛化后) ====================
|
||||
|
||||
/**
|
||||
* 犯罪类型(泛化类别)
|
||||
* 如:暴力类犯罪、财产类犯罪、涉毒类犯罪等
|
||||
*/
|
||||
private String crimeCategory;
|
||||
|
||||
/**
|
||||
* 刑期(保留时长,去掉具体日期)
|
||||
*/
|
||||
private Integer sentenceYears;
|
||||
|
||||
/**
|
||||
* 是否累犯
|
||||
*/
|
||||
private Boolean isRecidivist;
|
||||
|
||||
/**
|
||||
* 入监时长(月)
|
||||
*/
|
||||
private Integer imprisonmentMonths;
|
||||
|
||||
// ==================== 心理评估得分(0-100) ====================
|
||||
|
||||
/**
|
||||
* 暴力倾向得分(0-100,越高越危险)
|
||||
*/
|
||||
private BigDecimal violenceScore;
|
||||
|
||||
/**
|
||||
* 脱逃倾向得分(0-100,越高越危险)
|
||||
*/
|
||||
private BigDecimal escapeScore;
|
||||
|
||||
/**
|
||||
* 自杀倾向得分(0-100,越高越危险)
|
||||
*/
|
||||
private BigDecimal suicideScore;
|
||||
|
||||
// ==================== 行为表现数据 ====================
|
||||
|
||||
/**
|
||||
* 计分考核月均分
|
||||
*/
|
||||
private BigDecimal avgScore;
|
||||
|
||||
/**
|
||||
* 近6月违规次数
|
||||
*/
|
||||
private Integer violationCount6Month;
|
||||
|
||||
/**
|
||||
* 近6月表扬次数
|
||||
*/
|
||||
private Integer praiseCount6Month;
|
||||
|
||||
/**
|
||||
* 近6月扣分次数
|
||||
*/
|
||||
private Integer deductionCount6Month;
|
||||
|
||||
// ==================== 改造态度数据 ====================
|
||||
|
||||
/**
|
||||
* 劳动表现评分(0-100)
|
||||
*/
|
||||
private BigDecimal laborPerformance;
|
||||
|
||||
/**
|
||||
* 学习教育参与度(0-100)
|
||||
*/
|
||||
private BigDecimal educationParticipation;
|
||||
|
||||
/**
|
||||
* 思想汇报质量(0-100)
|
||||
*/
|
||||
private BigDecimal thoughtReportQuality;
|
||||
|
||||
// ==================== 消费数据(统计脱敏) ====================
|
||||
|
||||
/**
|
||||
* 月均消费金额(区间化)
|
||||
* 0: 低消费, 1: 中低消费, 2: 中等消费, 3: 中高消费, 4: 高消费
|
||||
*/
|
||||
private Integer consumptionLevel;
|
||||
|
||||
/**
|
||||
* 是否有异常大额消费
|
||||
*/
|
||||
private Boolean hasAbnormalConsumption;
|
||||
|
||||
// ==================== 历史评估数据 ====================
|
||||
|
||||
/**
|
||||
* 上次评估风险等级(1-4)
|
||||
*/
|
||||
private Integer lastRiskLevel;
|
||||
|
||||
/**
|
||||
* 上次评估综合得分
|
||||
*/
|
||||
private BigDecimal lastTotalScore;
|
||||
|
||||
/**
|
||||
* 评估时间(距今月数)
|
||||
*/
|
||||
private Integer lastAssessmentMonthsAgo;
|
||||
|
||||
/**
|
||||
* 历史风险趋势
|
||||
* stable: 稳定, rising: 上升, declining: 下降, fluctuating: 波动
|
||||
*/
|
||||
private String riskTrend;
|
||||
|
||||
/**
|
||||
* 历史评估记录数
|
||||
*/
|
||||
private Integer assessmentHistoryCount;
|
||||
|
||||
// ==================== 问卷答题数据(维度得分) ====================
|
||||
|
||||
/**
|
||||
* 犯罪史评估得分(0-100)
|
||||
*/
|
||||
private BigDecimal criminalHistoryScore;
|
||||
|
||||
/**
|
||||
* 家庭背景评估得分(0-100)
|
||||
*/
|
||||
private BigDecimal familyBackgroundScore;
|
||||
|
||||
/**
|
||||
* 社会支持评估得分(0-100)
|
||||
*/
|
||||
private BigDecimal socialSupportScore;
|
||||
|
||||
/**
|
||||
* 心理状态评估得分(0-100)
|
||||
*/
|
||||
private BigDecimal psychologicalStateScore;
|
||||
|
||||
/**
|
||||
* 行为表现评估得分(0-100)
|
||||
*/
|
||||
private BigDecimal behaviorPerformanceScore;
|
||||
|
||||
/**
|
||||
* 改造态度评估得分(0-100)
|
||||
*/
|
||||
private BigDecimal reformAttitudeScore;
|
||||
|
||||
// ==================== 特殊因素标记 ====================
|
||||
|
||||
/**
|
||||
* 是否存在家庭变故
|
||||
*/
|
||||
private Boolean hasFamilyCrisis;
|
||||
|
||||
/**
|
||||
* 是否近期与他犯有矛盾
|
||||
*/
|
||||
private Boolean hasConflictWithPrisoners;
|
||||
|
||||
/**
|
||||
* 是否近期情绪异常
|
||||
*/
|
||||
private Boolean hasMoodAbnormality;
|
||||
|
||||
/**
|
||||
* 其他风险因素描述(文本)
|
||||
*/
|
||||
private String otherRiskFactors;
|
||||
|
||||
// ==================== 评估元信息 ====================
|
||||
|
||||
/**
|
||||
* 评估类型
|
||||
*/
|
||||
private String assessmentType;
|
||||
|
||||
/**
|
||||
* 评估日期
|
||||
*/
|
||||
private LocalDate assessmentDate;
|
||||
|
||||
/**
|
||||
* 评估人ID
|
||||
*/
|
||||
private Long assessorId;
|
||||
|
||||
/**
|
||||
* 评估人姓名
|
||||
*/
|
||||
private String assessorName;
|
||||
|
||||
/**
|
||||
* 转换为JSON字符串(用于LLM调用)
|
||||
*/
|
||||
public String toJson() {
|
||||
return String.format("""
|
||||
{
|
||||
"prisonerNo": "%s",
|
||||
"crimeCategory": "%s",
|
||||
"sentenceYears": %d,
|
||||
"isRecidivist": %b,
|
||||
"imprisonmentMonths": %d,
|
||||
"violenceScore": %s,
|
||||
"escapeScore": %s,
|
||||
"suicideScore": %s,
|
||||
"avgScore": %s,
|
||||
"violationCount6Month": %d,
|
||||
"praiseCount6Month": %d,
|
||||
"laborPerformance": %s,
|
||||
"educationParticipation": %s,
|
||||
"lastRiskLevel": %d,
|
||||
"lastTotalScore": %s,
|
||||
"riskTrend": "%s",
|
||||
"assessmentHistoryCount": %d,
|
||||
"criminalHistoryScore": %s,
|
||||
"familyBackgroundScore": %s,
|
||||
"socialSupportScore": %s,
|
||||
"psychologicalStateScore": %s,
|
||||
"behaviorPerformanceScore": %s,
|
||||
"reformAttitudeScore": %s,
|
||||
"hasFamilyCrisis": %b,
|
||||
"hasConflictWithPrisoners": %b,
|
||||
"hasMoodAbnormality": %b,
|
||||
"otherRiskFactors": "%s"
|
||||
}
|
||||
""",
|
||||
prisonerNo,
|
||||
crimeCategory,
|
||||
sentenceYears,
|
||||
isRecidivist,
|
||||
imprisonmentMonths,
|
||||
violenceScore,
|
||||
escapeScore,
|
||||
suicideScore,
|
||||
avgScore,
|
||||
violationCount6Month,
|
||||
praiseCount6Month,
|
||||
laborPerformance,
|
||||
educationParticipation,
|
||||
lastRiskLevel,
|
||||
lastTotalScore,
|
||||
riskTrend,
|
||||
assessmentHistoryCount,
|
||||
criminalHistoryScore,
|
||||
familyBackgroundScore,
|
||||
socialSupportScore,
|
||||
psychologicalStateScore,
|
||||
behaviorPerformanceScore,
|
||||
reformAttitudeScore,
|
||||
hasFamilyCrisis,
|
||||
hasConflictWithPrisoners,
|
||||
hasMoodAbnormality,
|
||||
otherRiskFactors != null ? otherRiskFactors : ""
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
package cn.iocoder.yudao.module.prison.service.riskassessment.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* LLM评估结果
|
||||
*
|
||||
* @author XLLC Team
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class LlmAssessmentResult {
|
||||
|
||||
/**
|
||||
* 风险等级(1-4)
|
||||
*/
|
||||
private Integer riskLevel;
|
||||
|
||||
/**
|
||||
* 置信度(0-1)
|
||||
*/
|
||||
private BigDecimal confidence;
|
||||
|
||||
/**
|
||||
* 关键风险因素列表
|
||||
*/
|
||||
private List<String> keyRiskFactors;
|
||||
|
||||
/**
|
||||
* 综合分析说明
|
||||
*/
|
||||
private String analysis;
|
||||
|
||||
/**
|
||||
* 管控建议列表
|
||||
*/
|
||||
private List<String> suggestions;
|
||||
|
||||
/**
|
||||
* 需要关注的点
|
||||
*/
|
||||
private List<String> attentionPoints;
|
||||
|
||||
/**
|
||||
* 原始LLM响应
|
||||
*/
|
||||
private String rawResponse;
|
||||
|
||||
/**
|
||||
* 使用的模型
|
||||
*/
|
||||
private String modelUsed;
|
||||
|
||||
/**
|
||||
* 评估耗时(毫秒)
|
||||
*/
|
||||
private Long evaluationTimeMs;
|
||||
|
||||
/**
|
||||
* 评估时间
|
||||
*/
|
||||
private LocalDateTime evaluatedAt;
|
||||
|
||||
/**
|
||||
* 是否需要人工复核
|
||||
*/
|
||||
public boolean requiresHumanReview() {
|
||||
// 置信度低于0.7或风险等级为4(极高风险)需要人工复核
|
||||
return confidence.compareTo(new BigDecimal("0.7")) < 0 || riskLevel == 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取风险等级描述
|
||||
*/
|
||||
public String getRiskLevelDescription() {
|
||||
if (riskLevel == null) return "未知";
|
||||
return switch (riskLevel) {
|
||||
case 1 -> "低风险";
|
||||
case 2 -> "中风险";
|
||||
case 3 -> "高风险";
|
||||
case 4 -> "极高风险";
|
||||
default -> "未知";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取风险等级颜色标识(前端使用)
|
||||
*/
|
||||
public String getRiskLevelColor() {
|
||||
if (riskLevel == null) return "grey";
|
||||
return switch (riskLevel) {
|
||||
case 1 -> "success"; // 绿色
|
||||
case 2 -> "warning"; // 橙色
|
||||
case 3 -> "danger"; // 红色
|
||||
case 4 -> "danger"; // 深红
|
||||
default -> "info";
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,239 @@
|
||||
package cn.iocoder.yudao.module.prison.service.riskassessment.llm;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.module.prison.service.riskassessment.llm.LlmClient.LlmOptions;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Claude大模型客户端实现
|
||||
*
|
||||
* 基于Anthropic Claude API的客户端实现
|
||||
* API文档: https://docs.anthropic.com/claude/reference/getting-started
|
||||
*
|
||||
* @author XLLC Team
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ClaudeLlmClient implements LlmClient {
|
||||
|
||||
private static final String BASE_URL = "https://api.anthropic.com/v1/messages";
|
||||
private static final String DEFAULT_MODEL = "claude-3-5-sonnet-20241022";
|
||||
|
||||
@Value("${llm.claude.api-key:}")
|
||||
private String apiKey;
|
||||
|
||||
@Value("${llm.claude.timeout-seconds:30}")
|
||||
private int timeoutSeconds;
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
public ClaudeLlmClient() {
|
||||
this.restTemplate = new RestTemplate();
|
||||
// 配置超时
|
||||
this.restTemplate.setRequestFactory(() -> {
|
||||
var requestFactory = new org.springframework.http.client.SimpleClientHttpRequestFactory();
|
||||
requestFactory.setConnectTimeout(Duration.ofSeconds(30));
|
||||
requestFactory.setReadTimeout(Duration.ofSeconds(30));
|
||||
return requestFactory;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String complete(String prompt, LlmOptions options) {
|
||||
try {
|
||||
ClaudeRequest request = buildRequest(prompt, options, false);
|
||||
ClaudeResponse response = execute(request);
|
||||
|
||||
if (response.content != null && !response.content.isEmpty()) {
|
||||
return response.content.get(0).text;
|
||||
}
|
||||
|
||||
log.warn("Claude响应内容为空");
|
||||
return "";
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Claude API调用失败: {}", e.getMessage(), e);
|
||||
throw new LlmException("Claude API调用失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String completeJson(String prompt, LlmOptions options) {
|
||||
try {
|
||||
// 在提示词中明确要求JSON输出
|
||||
String jsonPrompt = prompt + "\n\n请确保输出格式为有效的JSON,不要添加额外的markdown格式。";
|
||||
|
||||
ClaudeRequest request = buildRequest(jsonPrompt, options, true);
|
||||
ClaudeResponse response = execute(request);
|
||||
|
||||
if (response.content != null && !response.content.isEmpty()) {
|
||||
String text = response.content.get(0).text;
|
||||
// 清理可能的markdown包装
|
||||
text = cleanJsonResponse(text);
|
||||
return text;
|
||||
}
|
||||
|
||||
log.warn("Claude JSON响应内容为空");
|
||||
return "";
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Claude JSON API调用失败: {}", e.getMessage(), e);
|
||||
throw new LlmException("Claude JSON API调用失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
if (apiKey == null || apiKey.isEmpty()) {
|
||||
log.warn("Claude API密钥未配置");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// 简单的健康检查
|
||||
String testPrompt = "Hello";
|
||||
ClaudeRequest request = buildRequest(testPrompt,
|
||||
LlmOptions.defaultOptions(), false);
|
||||
execute(request);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.warn("Claude服务不可用: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Claude";
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建请求对象
|
||||
*/
|
||||
private ClaudeRequest buildRequest(String prompt, LlmOptions options, boolean isJsonMode) {
|
||||
// 构建系统提示词(用于JSON模式)
|
||||
String systemPrompt = isJsonMode
|
||||
? "你是一个专业的危险评估助手。请始终以JSON格式输出响应,不要添加任何markdown代码块标记。"
|
||||
: "你是一位专业的危险评估专家。请基于提供的数据进行专业评估。";
|
||||
|
||||
return new ClaudeRequest(
|
||||
options.model() != null ? options.model() : DEFAULT_MODEL,
|
||||
prompt,
|
||||
systemPrompt,
|
||||
options.temperature(),
|
||||
options.maxTokens()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行API调用
|
||||
*/
|
||||
private ClaudeResponse execute(ClaudeRequest request) {
|
||||
// 请求头
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("x-api-key", apiKey);
|
||||
headers.put("anthropic-version", "2023-06-01");
|
||||
headers.put("anthropic-dangerous-direct-browser-access", "true");
|
||||
headers.put("content-type", "application/json");
|
||||
|
||||
// 构建请求体
|
||||
Map<String, Object> body = new HashMap<>();
|
||||
body.put("model", request.model());
|
||||
body.put("messages", new Object[]{
|
||||
Map.of("role", "system", "content", request.systemPrompt())
|
||||
});
|
||||
body.put("max_tokens", request.maxTokens());
|
||||
body.put("temperature", request.temperature());
|
||||
body.put("stream", false);
|
||||
|
||||
// 添加用户消息
|
||||
Object[] messages = new Object[2];
|
||||
messages[0] = Map.of("role", "system", "content", request.systemPrompt());
|
||||
messages[1] = Map.of("role", "user", "content", request.prompt());
|
||||
body.put("messages", messages);
|
||||
|
||||
try {
|
||||
// 注意: 实际使用时需要配置HTTP客户端处理Anthropic的特殊请求头
|
||||
// 这里使用简化实现,实际项目中建议使用官方SDK
|
||||
log.debug("调用Claude API, model: {}, temperature: {}",
|
||||
request.model(), request.temperature());
|
||||
|
||||
// 模拟响应(实际需要接入真实API)
|
||||
// TODO: 接入真实Claude API
|
||||
return buildMockResponse();
|
||||
|
||||
} catch (RestClientException e) {
|
||||
log.error("Claude API请求失败: {}", e.getMessage());
|
||||
throw new LlmException("API请求失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建模拟响应(开发阶段使用)
|
||||
*/
|
||||
private ClaudeResponse buildMockResponse() {
|
||||
// 开发阶段返回模拟数据
|
||||
log.warn("使用Claude API模拟响应,请配置真实API密钥");
|
||||
|
||||
ClaudeResponse.ContentBlock content = new ClaudeResponse.ContentBlock(
|
||||
"text",
|
||||
"{\"riskLevel\": 2, \"confidence\": 0.85, \"keyRiskFactors\": [\"开发阶段模拟数据\"], \"analysis\": \"这是模拟响应,请配置Claude API密钥后使用真实调用\", \"suggestions\": [\"配置API密钥后重启服务\"]}"
|
||||
);
|
||||
|
||||
return new ClaudeResponse(
|
||||
"mock-id",
|
||||
"assistant",
|
||||
new java.util.List.of(content),
|
||||
"stop",
|
||||
"end_turn"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理JSON响应,去除markdown包装
|
||||
*/
|
||||
private String cleanJsonResponse(String text) {
|
||||
if (text == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// 去除 ```json 和 ``` 包装
|
||||
text = text.replaceAll("```json\\s*", "")
|
||||
.replaceAll("```\\s*", "")
|
||||
.trim();
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Claude API请求结构
|
||||
*/
|
||||
private record ClaudeRequest(
|
||||
String model,
|
||||
String prompt,
|
||||
String systemPrompt,
|
||||
double temperature,
|
||||
int maxTokens
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Claude API响应结构
|
||||
*/
|
||||
private record ClaudeResponse(
|
||||
String id,
|
||||
String type,
|
||||
java.util.List<ContentBlock> content,
|
||||
String stop_reason,
|
||||
String role
|
||||
) {
|
||||
record ContentBlock(String type, String text) {}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
package cn.iocoder.yudao.module.prison.service.riskassessment.llm;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* LLM客户端接口
|
||||
*
|
||||
* @author XLLC Team
|
||||
*/
|
||||
public interface LlmClient {
|
||||
|
||||
/**
|
||||
* 调用大模型生成内容
|
||||
*
|
||||
* @param prompt 提示词
|
||||
* @param options 调用选项
|
||||
* @return 模型生成的文本响应
|
||||
*/
|
||||
String complete(String prompt, LlmOptions options);
|
||||
|
||||
/**
|
||||
* 调用大模型生成JSON格式响应
|
||||
*
|
||||
* @param prompt 提示词
|
||||
* @param options 调用选项
|
||||
* @return JSON格式的响应文本
|
||||
*/
|
||||
String completeJson(String prompt, LlmOptions options);
|
||||
|
||||
/**
|
||||
* 检查客户端是否可用
|
||||
*
|
||||
* @return 是否可用
|
||||
*/
|
||||
boolean isAvailable();
|
||||
|
||||
/**
|
||||
* 获取客户端名称
|
||||
*
|
||||
* @return 客户端名称
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* 调用选项
|
||||
*/
|
||||
record LlmOptions(
|
||||
String model, // 模型名称
|
||||
double temperature, // 温度参数 (0.0-1.0)
|
||||
int maxTokens, // 最大Token数
|
||||
Map<String, String> headers // 额外请求头
|
||||
) {
|
||||
/**
|
||||
* 创建默认选项
|
||||
*/
|
||||
public static LlmOptions defaultOptions() {
|
||||
return new LlmOptions(
|
||||
"claude-3-5-sonnet-20241022",
|
||||
0.1, // 低温度,输出更稳定
|
||||
2000,
|
||||
Map.of()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建低温度选项(用于评估场景)
|
||||
*/
|
||||
public static LlmOptions assessmentOptions() {
|
||||
return new LlmOptions(
|
||||
"claude-3-5-sonnet-20241022",
|
||||
0.05, // 极低温度,减少随机性
|
||||
2048,
|
||||
Map.of()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建高温度选项(用于创意场景)
|
||||
*/
|
||||
public static LlmOptions creativeOptions() {
|
||||
return new LlmOptions(
|
||||
"claude-3-5-sonnet-20241022",
|
||||
0.7,
|
||||
4096,
|
||||
Map.of()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,106 @@
|
||||
package cn.iocoder.yudao.module.prison.service.riskassessment.llm;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* LLM客户端工厂
|
||||
* 根据配置选择不同的LLM客户端
|
||||
*
|
||||
* @author XLLC Team
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class LlmClientFactory {
|
||||
|
||||
private final Map<String, LlmClient> clients;
|
||||
|
||||
public LlmClientFactory(List<LlmClient> clientList) {
|
||||
// 初始化客户端映射
|
||||
this.clients = new java.util.HashMap<>();
|
||||
for (LlmClient client : clientList) {
|
||||
clients.put(client.getName().toLowerCase(), client);
|
||||
log.info("注册LLM客户端: {}", client.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定名称的客户端
|
||||
*
|
||||
* @param name 客户端名称
|
||||
* @return LLM客户端
|
||||
*/
|
||||
public LlmClient getClient(String name) {
|
||||
LlmClient client = clients.get(name.toLowerCase());
|
||||
if (client == null) {
|
||||
throw new LlmException("UNKNOWN_CLIENT", "未找到LLM客户端: " + name);
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认客户端
|
||||
*
|
||||
* @return 默认LLM客户端
|
||||
*/
|
||||
public LlmClient getDefaultClient() {
|
||||
// 优先使用Claude
|
||||
if (clients.containsKey("claude")) {
|
||||
return clients.get("claude");
|
||||
}
|
||||
|
||||
// 如果没有Claude,返回第一个可用的客户端
|
||||
return clients.values().stream()
|
||||
.filter(LlmClient::isAvailable)
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new LlmException("NO_AVAILABLE_CLIENT", "没有可用的LLM客户端"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用于评估的客户端
|
||||
* 优先选择Claude(评估能力强)
|
||||
*
|
||||
* @return 评估用的LLM客户端
|
||||
*/
|
||||
public LlmClient getAssessmentClient() {
|
||||
// 优先使用Claude
|
||||
LlmClient claude = clients.get("claude");
|
||||
if (claude != null && claude.isAvailable()) {
|
||||
log.debug("选择Claude作为评估客户端");
|
||||
return claude;
|
||||
}
|
||||
|
||||
// 检查其他可用客户端
|
||||
for (LlmClient client : clients.values()) {
|
||||
if (client.isAvailable()) {
|
||||
log.warn("Claude不可用,使用备用客户端: {}", client.getName());
|
||||
return client;
|
||||
}
|
||||
}
|
||||
|
||||
throw new LlmException("NO_AVAILABLE_CLIENT", "没有可用的LLM客户端进行评估");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查指定客户端是否可用
|
||||
*
|
||||
* @param name 客户端名称
|
||||
* @return 是否可用
|
||||
*/
|
||||
public boolean isAvailable(String name) {
|
||||
LlmClient client = clients.get(name.toLowerCase());
|
||||
return client != null && client.isAvailable();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有已注册的客户端名称
|
||||
*
|
||||
* @return 客户端名称列表
|
||||
*/
|
||||
public List<String> getRegisteredClients() {
|
||||
return clients.keySet().stream().toList();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package cn.iocoder.yudao.module.prison.service.riskassessment.llm;
|
||||
|
||||
/**
|
||||
* LLM调用异常
|
||||
*
|
||||
* @author XLLC Team
|
||||
*/
|
||||
public class LlmException extends RuntimeException {
|
||||
|
||||
private final String errorCode;
|
||||
|
||||
public LlmException(String message) {
|
||||
super(message);
|
||||
this.errorCode = "LLM_ERROR";
|
||||
}
|
||||
|
||||
public LlmException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.errorCode = "LLM_ERROR";
|
||||
}
|
||||
|
||||
public LlmException(String errorCode, String message) {
|
||||
super(message);
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
public LlmException(String errorCode, String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
public String getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
192
yudao-module-prison/src/main/resources/sql/assessment_module.sql
Normal file
192
yudao-module-prison/src/main/resources/sql/assessment_module.sql
Normal file
@ -0,0 +1,192 @@
|
||||
-- =====================================================
|
||||
-- XL监狱综合管理平台 - 测评执行与评分模块数据库脚本
|
||||
-- 生成时间: 2026-01-15
|
||||
-- 模块: assessment (测评执行与评分)
|
||||
-- =====================================================
|
||||
|
||||
-- =====================================================
|
||||
-- 1. 测评记录表 (prison_assessment_record)
|
||||
-- 用于记录测评的执行情况,包括罪犯测评的发起、完成状态等
|
||||
-- =====================================================
|
||||
DROP TABLE IF EXISTS `prison_assessment_record`;
|
||||
CREATE TABLE IF NOT EXISTS `prison_assessment_record` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '记录ID',
|
||||
`prisoner_id` bigint NOT NULL COMMENT '罪犯ID',
|
||||
`prisoner_name` varchar(100) NOT NULL COMMENT '罪犯姓名',
|
||||
`prisoner_no` varchar(50) NOT NULL COMMENT '罪犯编号',
|
||||
`questionnaire_id` bigint NOT NULL COMMENT '问卷模板ID',
|
||||
`questionnaire_name` varchar(200) NOT NULL COMMENT '问卷名称',
|
||||
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:1-待测评 2-测评中 3-已完成 4-已过期',
|
||||
`start_time` datetime DEFAULT NULL COMMENT '开始时间',
|
||||
`end_time` datetime DEFAULT NULL COMMENT '结束时间',
|
||||
`total_score` decimal(10,2) DEFAULT NULL COMMENT '总分',
|
||||
`pass_status` tinyint DEFAULT NULL COMMENT '及格状态:1-及格 2-不及格 3-待评阅',
|
||||
`risk_level` tinyint DEFAULT NULL COMMENT '风险等级:1-高风险 2-中风险 3-低风险',
|
||||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_assessment_record_prisoner_id` (`prisoner_id`),
|
||||
KEY `idx_assessment_record_prisoner_no` (`prisoner_no`),
|
||||
KEY `idx_assessment_record_questionnaire_id` (`questionnaire_id`),
|
||||
KEY `idx_assessment_record_status` (`status`),
|
||||
KEY `idx_assessment_record_create_time` (`create_time`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='测评记录表';
|
||||
|
||||
-- =====================================================
|
||||
-- 2. 答卷详情表 (prison_assessment_answer)
|
||||
-- 用于记录每道题的答题详情,包括客观题自动评分和主观题人工评分
|
||||
-- =====================================================
|
||||
DROP TABLE IF EXISTS `prison_assessment_answer`;
|
||||
CREATE TABLE IF NOT EXISTS `prison_assessment_answer` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '答案ID',
|
||||
`record_id` bigint NOT NULL COMMENT '测评记录ID',
|
||||
`question_id` bigint NOT NULL COMMENT '题目ID',
|
||||
`question_type` tinyint NOT NULL COMMENT '题目类型:1-单选 2-多选 3-判断 4-填空 5-简述',
|
||||
`question_content` varchar(500) NOT NULL COMMENT '题目内容',
|
||||
`answer_content` text COMMENT '答案内容',
|
||||
`score` decimal(10,2) DEFAULT 0.00 COMMENT '得分',
|
||||
`is_correct` bit(1) DEFAULT NULL COMMENT '是否正确',
|
||||
`is_manual_score` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否需要人工评分',
|
||||
`manual_score` decimal(10,2) DEFAULT NULL COMMENT '人工评分分数',
|
||||
`manual_comment` varchar(500) DEFAULT NULL COMMENT '人工评语',
|
||||
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_assessment_answer_record_id` (`record_id`),
|
||||
KEY `idx_assessment_answer_question_id` (`question_id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='答卷详情表';
|
||||
|
||||
-- =====================================================
|
||||
-- 3. 测评结果表 (prison_assessment_result)
|
||||
-- 用于记录测评的最终结果,包括客观题得分、主观题得分、总分及风险评估
|
||||
-- =====================================================
|
||||
DROP TABLE IF EXISTS `prison_assessment_result`;
|
||||
CREATE TABLE IF NOT EXISTS `prison_assessment_result` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '结果ID',
|
||||
`record_id` bigint NOT NULL COMMENT '测评记录ID',
|
||||
`objective_score` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '客观题得分',
|
||||
`subjective_score` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '主观题得分',
|
||||
`total_score` decimal(10,2) NOT NULL COMMENT '总分',
|
||||
`pass_score` decimal(10,2) NOT NULL COMMENT '及格分数线',
|
||||
`pass_status` tinyint NOT NULL COMMENT '及格状态:1-及格 2-不及格 3-待评阅',
|
||||
`risk_level` tinyint DEFAULT NULL COMMENT '风险等级:1-高风险 2-中风险 3-低风险',
|
||||
`evaluation_suggestion` text COMMENT '评估建议',
|
||||
`evaluator_id` bigint DEFAULT NULL COMMENT '评阅人ID',
|
||||
`evaluator_name` varchar(100) DEFAULT NULL COMMENT '评阅人姓名',
|
||||
`evaluate_time` datetime DEFAULT NULL COMMENT '评阅时间',
|
||||
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_assessment_result_record_id` (`record_id`),
|
||||
KEY `idx_assessment_result_evaluator_id` (`evaluator_id`),
|
||||
KEY `idx_assessment_result_evaluate_time` (`evaluate_time`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='测评结果表';
|
||||
|
||||
-- =====================================================
|
||||
-- 4. 测评统计表 (prison_assessment_statistics)
|
||||
-- 用于统计测评的整体情况,包括发起数量、完成率、平均分、风险分布等
|
||||
-- =====================================================
|
||||
DROP TABLE IF EXISTS `prison_assessment_statistics`;
|
||||
CREATE TABLE IF NOT EXISTS `prison_assessment_statistics` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '统计ID',
|
||||
`questionnaire_id` bigint NOT NULL COMMENT '问卷ID',
|
||||
`questionnaire_name` varchar(200) NOT NULL COMMENT '问卷名称',
|
||||
`stat_date` date NOT NULL COMMENT '统计日期',
|
||||
`total_count` int NOT NULL DEFAULT 0 COMMENT '发起总数',
|
||||
`completed_count` int NOT NULL DEFAULT 0 COMMENT '完成数量',
|
||||
`completion_rate` decimal(5,2) DEFAULT 0.00 COMMENT '完成率',
|
||||
`average_score` decimal(10,2) DEFAULT 0.00 COMMENT '平均分',
|
||||
`pass_rate` decimal(5,2) DEFAULT 0.00 COMMENT '及格率',
|
||||
`high_risk_count` int NOT NULL DEFAULT 0 COMMENT '高风险人数',
|
||||
`medium_risk_count` int NOT NULL DEFAULT 0 COMMENT '中风险人数',
|
||||
`low_risk_count` int NOT NULL DEFAULT 0 COMMENT '低风险人数',
|
||||
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_assessment_statistics_questionnaire_id` (`questionnaire_id`),
|
||||
KEY `idx_assessment_statistics_stat_date` (`stat_date`),
|
||||
UNIQUE KEY `uk_questionnaire_date` (`questionnaire_id`, `stat_date`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='测评统计表';
|
||||
|
||||
-- =====================================================
|
||||
-- 菜单权限 SQL
|
||||
-- =====================================================
|
||||
-- 说明: 请将 ${table.parentMenuId} 替换为实际的父菜单ID
|
||||
-- 监狱管理模块的父菜单ID通常为 5047 (系统管理) 或对应的监狱模块菜单ID
|
||||
-- =====================================================
|
||||
|
||||
-- 获取监狱模块父菜单ID (假设为 5047,请根据实际情况调整)
|
||||
-- SELECT @parentId := 5047;
|
||||
|
||||
-- 1. 测评记录管理菜单
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status, component_name)
|
||||
VALUES ('测评记录管理', '', 2, 1, 5047, 'assessment-record', '', 'prison/assessment-record/index', 0, 'AssessmentRecord');
|
||||
SELECT @assessmentRecordParentId := LAST_INSERT_ID();
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('测评记录查询', 'prison:assessment-record:query', 3, 1, @assessmentRecordParentId, '', '', '', 0);
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('测评记录创建', 'prison:assessment-record:create', 3, 2, @assessmentRecordParentId, '', '', '', 0);
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('测评记录更新', 'prison:assessment-record:update', 3, 3, @assessmentRecordParentId, '', '', '', 0);
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('测评记录删除', 'prison:assessment-record:delete', 3, 4, @assessmentRecordParentId, '', '', '', 0);
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('测评记录导出', 'prison:assessment-record:export', 3, 5, @assessmentRecordParentId, '', '', '', 0);
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('发起测评', 'prison:assessment-record:start', 3, 6, @assessmentRecordParentId, '', '', '', 0);
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('提交测评', 'prison:assessment-record:submit', 3, 7, @assessmentRecordParentId, '', '', '', 0);
|
||||
|
||||
-- 2. 答卷详情管理菜单
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status, component_name)
|
||||
VALUES ('答卷详情管理', '', 2, 2, 5047, 'assessment-answer', '', 'prison/assessment-answer/index', 0, 'AssessmentAnswer');
|
||||
SELECT @assessmentAnswerParentId := LAST_INSERT_ID();
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('答卷详情查询', 'prison:assessment-answer:query', 3, 1, @assessmentAnswerParentId, '', '', '', 0);
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('答卷详情更新', 'prison:assessment-answer:update', 3, 2, @assessmentAnswerParentId, '', '', '', 0);
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('人工评分', 'prison:assessment-answer:manual-score', 3, 3, @assessmentAnswerParentId, '', '', '', 0);
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('答卷详情导出', 'prison:assessment-answer:export', 3, 4, @assessmentAnswerParentId, '', '', '', 0);
|
||||
|
||||
-- 3. 测评结果管理菜单
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status, component_name)
|
||||
VALUES ('测评结果管理', '', 2, 3, 5047, 'assessment-result', '', 'prison/assessment-result/index', 0, 'AssessmentResult');
|
||||
SELECT @assessmentResultParentId := LAST_INSERT_ID();
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('测评结果查询', 'prison:assessment-result:query', 3, 1, @assessmentResultParentId, '', '', '', 0);
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('测评结果更新', 'prison:assessment-result:update', 3, 2, @assessmentResultParentId, '', '', '', 0);
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('测评结果导出', 'prison:assessment-result:export', 3, 3, @assessmentResultParentId, '', '', '', 0);
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('风险评估', 'prison:assessment-result:risk-evaluate', 3, 4, @assessmentResultParentId, '', '', '', 0);
|
||||
|
||||
-- 4. 测评统计管理菜单
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status, component_name)
|
||||
VALUES ('测评统计管理', '', 2, 4, 5047, 'assessment-statistics', '', 'prison/assessment-statistics/index', 0, 'AssessmentStatistics');
|
||||
SELECT @assessmentStatisticsParentId := LAST_INSERT_ID();
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('测评统计查询', 'prison:assessment-statistics:query', 3, 1, @assessmentStatisticsParentId, '', '', '', 0);
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('测评统计导出', 'prison:assessment-statistics:export', 3, 2, @assessmentStatisticsParentId, '', '', '', 0);
|
||||
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('生成统计', 'prison:assessment-statistics:generate', 3, 3, @assessmentStatisticsParentId, '', '', '', 0);
|
||||
@ -0,0 +1,18 @@
|
||||
-- 问题表新增字段
|
||||
-- 执行前请确保已备份数据库
|
||||
-- 连接数据库: mysql -h 192.168.10.130 -u xlcp_dev -p xlcp_dev
|
||||
|
||||
ALTER TABLE prison_question
|
||||
ADD COLUMN part_name VARCHAR(100) DEFAULT NULL COMMENT '分区名称' AFTER `sort`,
|
||||
ADD COLUMN part_sort INT DEFAULT NULL COMMENT '分区排序' AFTER `part_name`,
|
||||
ADD COLUMN help_text VARCHAR(500) DEFAULT NULL COMMENT '帮助说明' AFTER `part_sort`,
|
||||
ADD COLUMN placeholder VARCHAR(200) DEFAULT NULL COMMENT '占位提示' AFTER `help_text`,
|
||||
ADD COLUMN default_value VARCHAR(500) DEFAULT NULL COMMENT '默认值' AFTER `placeholder`,
|
||||
ADD COLUMN auto_fill_type VARCHAR(20) DEFAULT NULL COMMENT '自动填充类型:NONE-无 AUTO-自动 MANUAL-手动' AFTER `default_value`,
|
||||
ADD COLUMN auto_fill_source VARCHAR(500) DEFAULT NULL COMMENT '自动填充来源' AFTER `auto_fill_type`,
|
||||
ADD COLUMN display_condition VARCHAR(1000) DEFAULT NULL COMMENT '显示条件JSON' AFTER `auto_fill_source`,
|
||||
ADD COLUMN min_value DECIMAL(10,2) DEFAULT NULL COMMENT '最小值' AFTER `display_condition`,
|
||||
ADD COLUMN max_value DECIMAL(10,2) DEFAULT NULL COMMENT '最大值' AFTER `min_value`;
|
||||
|
||||
-- 验证字段是否添加成功
|
||||
DESCRIBE prison_question;
|
||||
@ -0,0 +1,13 @@
|
||||
-- 问卷模板表新增字段
|
||||
-- 执行前请确保已备份数据库
|
||||
-- 连接数据库: mysql -h 192.168.10.130 -u xlcp_dev -p xlcp_dev
|
||||
|
||||
ALTER TABLE prison_questionnaire
|
||||
ADD COLUMN cover_image VARCHAR(500) DEFAULT NULL COMMENT '封面图片URL' AFTER `status`,
|
||||
ADD COLUMN instruction VARCHAR(500) DEFAULT NULL COMMENT '填写说明' AFTER `cover_image`,
|
||||
ADD COLUMN estimated_time INT DEFAULT NULL COMMENT '预计耗时(分钟)' AFTER `instruction`,
|
||||
ADD COLUMN part_count INT DEFAULT NULL COMMENT '分区数量' AFTER `estimated_time`,
|
||||
ADD COLUMN allow_anonymous TINYINT(1) DEFAULT NULL COMMENT '是否允许匿名:0-否 1-是' AFTER `part_count`;
|
||||
|
||||
-- 验证字段是否添加成功
|
||||
SELECT * FROM prison_questionnaire LIMIT 1;
|
||||
Loading…
x
Reference in New Issue
Block a user