package com.kaidi.oa.web; import com.kaidi.oa.common.ApiException; import com.kaidi.oa.common.ApiResp; import com.kaidi.oa.common.NotFoundException; import com.kaidi.oa.domain.SupervisionInspection; import com.kaidi.oa.domain.SupervisionProject; import com.kaidi.oa.repository.SupervisionInspectionRepository; import com.kaidi.oa.repository.SupervisionProjectRepository; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.time.Instant; import java.util.List; /** * 工程监理部·监理记录(施工过程质量控制留痕)。一条记录按 inspectType 区分 * 旁站 / 巡视 / 平行检验 / 监理通知,含部位、依据图纸版本、结论、问题与整改闭环状态。 * * 提供 CRUD + 整改闭环动作({@code /{id}/close})。按 supervisionProjectId 归属, * 资源路径 /api/oa/supervision-inspections。 */ @RestController @RequestMapping("/api/oa/supervision-inspections") public class SupervisionInspectionController { private final SupervisionInspectionRepository inspectionRepo; private final SupervisionProjectRepository projectRepo; public SupervisionInspectionController(SupervisionInspectionRepository inspectionRepo, SupervisionProjectRepository projectRepo) { this.inspectionRepo = inspectionRepo; this.projectRepo = projectRepo; } @GetMapping public ApiResp> list( @RequestParam(required = false) Long projectId, @RequestParam(required = false) String inspectType, @RequestParam(required = false) String rectifyStatus) { if (projectId != null) { return ApiResp.ok(inspectionRepo.findBySupervisionProjectIdOrderByIdDesc(projectId)); } if (inspectType != null && !inspectType.isBlank()) { return ApiResp.ok(inspectionRepo.findByInspectType(inspectType)); } if (rectifyStatus != null && !rectifyStatus.isBlank()) { return ApiResp.ok(inspectionRepo.findByRectifyStatus(rectifyStatus)); } return ApiResp.ok(inspectionRepo.findAll()); } @GetMapping("/{id}") public ApiResp get(@PathVariable Long id) { return ApiResp.ok(inspectionRepo.findById(id) .orElseThrow(() -> new NotFoundException("supervision inspection not found: " + id))); } public record InspectionRequest( Long supervisionProjectId, String code, String inspectType, String part, String inspectDate, Long designDocId, String content, String conclusion, String problem, String rectifyStatus, String rectifyDueDate, String rectifyResult, String inspector) { } @PostMapping public ApiResp create(@RequestBody InspectionRequest req) { if (req.supervisionProjectId() == null) { throw new ApiException(400, "所属监理项目(supervisionProjectId) 不能为空"); } SupervisionProject parent = projectRepo.findById(req.supervisionProjectId()) .orElseThrow(() -> new NotFoundException("supervision project not found: " + req.supervisionProjectId())); if (req.inspectType() == null || req.inspectType().isBlank()) { throw new ApiException(400, "记录类型(inspectType) 不能为空(旁站/巡视/平行检验/监理通知)"); } SupervisionInspection r = new SupervisionInspection(); r.setSupervisionProjectId(parent.getId()); r.setSupervisionProjectCode(parent.getCode()); r.setCode(req.code() == null || req.code().isBlank() ? "JLJL-" + (inspectionRepo.count() + 1) : req.code()); r.setInspectType(req.inspectType()); r.setPart(req.part()); r.setInspectDate(req.inspectDate()); r.setDesignDocId(req.designDocId()); r.setContent(req.content()); r.setConclusion(req.conclusion() == null || req.conclusion().isBlank() ? "合格" : req.conclusion()); r.setProblem(req.problem()); r.setRectifyStatus(req.rectifyStatus() == null || req.rectifyStatus().isBlank() ? defaultRectify(r.getConclusion()) : req.rectifyStatus()); r.setRectifyDueDate(req.rectifyDueDate()); r.setRectifyResult(req.rectifyResult()); r.setInspector(req.inspector()); r.setCreatedAt(Instant.now()); return ApiResp.ok(inspectionRepo.save(r)); } @PatchMapping("/{id}") public ApiResp update(@PathVariable Long id, @RequestBody InspectionRequest req) { SupervisionInspection r = inspectionRepo.findById(id) .orElseThrow(() -> new NotFoundException("supervision inspection not found: " + id)); if (req.inspectType() != null && !req.inspectType().isBlank()) r.setInspectType(req.inspectType()); if (req.part() != null) r.setPart(req.part()); if (req.inspectDate() != null) r.setInspectDate(req.inspectDate()); if (req.designDocId() != null) r.setDesignDocId(req.designDocId()); if (req.content() != null) r.setContent(req.content()); if (req.conclusion() != null && !req.conclusion().isBlank()) r.setConclusion(req.conclusion()); if (req.problem() != null) r.setProblem(req.problem()); if (req.rectifyStatus() != null && !req.rectifyStatus().isBlank()) r.setRectifyStatus(req.rectifyStatus()); if (req.rectifyDueDate() != null) r.setRectifyDueDate(req.rectifyDueDate()); if (req.rectifyResult() != null) r.setRectifyResult(req.rectifyResult()); if (req.inspector() != null) r.setInspector(req.inspector()); return ApiResp.ok(inspectionRepo.save(r)); } @DeleteMapping("/{id}") public ApiResp delete(@PathVariable Long id) { if (!inspectionRepo.existsById(id)) { throw new NotFoundException("supervision inspection not found: " + id); } inspectionRepo.deleteById(id); return ApiResp.ok(null); } public record CloseRequest(String rectifyResult) { } /** * 整改闭环:施工方整改回传后,监理复核确认,把整改状态置「已复核闭环」并记录复核结果。 * 已闭环再次提交拒绝,避免覆盖闭环记录。 */ @PostMapping("/{id}/close") public ApiResp close(@PathVariable Long id, @RequestBody(required = false) CloseRequest req) { SupervisionInspection r = inspectionRepo.findById(id) .orElseThrow(() -> new NotFoundException("supervision inspection not found: " + id)); if ("已复核闭环".equals(r.getRectifyStatus())) { throw new ApiException(409, "该问题已复核闭环,请勿重复"); } if ("无需整改".equals(r.getRectifyStatus())) { throw new ApiException(400, "该记录无需整改,无法闭环"); } if (req != null && req.rectifyResult() != null && !req.rectifyResult().isBlank()) { r.setRectifyResult(req.rectifyResult()); } r.setRectifyStatus("已复核闭环"); return ApiResp.ok(inspectionRepo.save(r)); } /** 结论决定整改默认态:合格→无需整改;整改/不合格/停工→待整改。 */ private static String defaultRectify(String conclusion) { if ("整改".equals(conclusion) || "不合格".equals(conclusion) || "停工".equals(conclusion)) { return "待整改"; } return "无需整改"; } }