package com.kaidi.oa.web; import com.kaidi.oa.common.Money; import com.kaidi.oa.common.ApiException; import com.kaidi.oa.common.ApiResp; import com.kaidi.oa.common.NotFoundException; import com.kaidi.oa.domain.Declaration; import com.kaidi.oa.repository.DeclarationRepository; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; 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; /** * R&D innovation center: government program declarations (政府项目申报). program * is one of 高新技术企业 / 科技型中小企业 / 省重点研发计划 / 专精特新 / 创新平台; * status is one of 准备中 / 已申报 / 已立项 / 已结题 / 未通过. Tail link of business * chain 6: rdProjectId (nullable) references an RdProject. */ @RestController @RequestMapping("/api/oa/declarations") public class DeclarationController { private final DeclarationRepository declarationRepo; public DeclarationController(DeclarationRepository declarationRepo) { this.declarationRepo = declarationRepo; } @GetMapping public ApiResp> list(@RequestParam(required = false) String program, @RequestParam(required = false) String status) { List list; if (program != null && !program.isBlank()) { list = declarationRepo.findByProgram(program); } else if (status != null && !status.isBlank()) { list = declarationRepo.findByStatus(status); } else { list = declarationRepo.findAll(); } return ApiResp.ok(list); } @GetMapping("/{id}") public ApiResp get(@PathVariable Long id) { return ApiResp.ok(declarationRepo.findById(id) .orElseThrow(() -> new NotFoundException("declaration not found: " + id))); } public record CreateDeclarationRequest( String name, String program, String authority, Long rdProjectId, Double amount, String deadline, String status, String owner) { } @PostMapping public ApiResp create(@RequestBody CreateDeclarationRequest req) { if (req.name() == null || req.name().isBlank()) { throw new ApiException(400, "name is required"); } Declaration d = new Declaration(); d.setName(req.name()); d.setProgram(req.program()); d.setAuthority(req.authority()); d.setRdProjectId(req.rdProjectId()); d.setAmount(Money.of(req.amount() == null ? 0 : req.amount())); d.setDeadline(req.deadline()); d.setStatus(req.status() == null || req.status().isBlank() ? "准备中" : req.status()); d.setOwner(req.owner()); d.setCreatedAt(Instant.now()); return ApiResp.ok(declarationRepo.save(d)); } /** PUT /{id} -> 编辑政府项目申报; 只覆盖请求体里给出的字段。 */ @PutMapping("/{id}") public ApiResp update(@PathVariable Long id, @RequestBody CreateDeclarationRequest req) { Declaration d = declarationRepo.findById(id) .orElseThrow(() -> new NotFoundException("declaration not found: " + id)); if (req.name() != null) { if (req.name().isBlank()) { throw new ApiException(400, "name is required"); } d.setName(req.name()); } if (req.program() != null) d.setProgram(req.program()); if (req.authority() != null) d.setAuthority(req.authority()); if (req.rdProjectId() != null) d.setRdProjectId(req.rdProjectId()); if (req.amount() != null) d.setAmount(Money.of(req.amount())); if (req.deadline() != null) d.setDeadline(req.deadline()); if (req.status() != null && !req.status().isBlank()) d.setStatus(req.status()); // 归属仅 create 定调, update 不接收客户端 owner, 不得被篡改。 return ApiResp.ok(declarationRepo.save(d)); } /** DELETE /{id} -> 删除政府项目申报。 */ @DeleteMapping("/{id}") public ApiResp delete(@PathVariable Long id) { if (!declarationRepo.existsById(id)) { throw new NotFoundException("declaration not found: " + id); } declarationRepo.deleteById(id); return ApiResp.ok(null); } }