SNAPSHOT W7 已部署稳定态 — 凯迪ERP+OA一体化平台 (MET 73.3%)
恢复点(restore point)。别人改崩后可 git reset --hard 回到此提交。 == 此快照内容 == - 后端 oa-backend: 734 控制器 / 711 实体 (Spring Boot 3.2.5 + SQLite, 端口8091) - 前端 modern-ui/app: Vue3+Vite, 约700页 (构建产物已在 oa-backend/src/main/resources/static) - 数据库 oa-backend/data/oa.db: 含全部演示数据 (强制入库, 6.6MB) - 交接文档 go.md + go-code-reference/endpoints/entities/database.md - 多代理建设脚本 .claude/wf-*.js == 状态 == - 对 凯迪科技ERP_20260507.xlsx 合规 MET ~73.3% (PARTIAL 75: 34可建+6种子/bug+35外部硬天花板) - 安全: 5轮红队+5轮复检, default-deny分级鉴权, 连续零可利用 - W3~W7 累计补完436缺口; W8末轮(40缺口)为半成品(源码树可编译但未集成) - 运行: cd oa-backend; java -jar build/libs/oa-backend-0.1.0.jar --server.port=8091; admin/123456 == 排除(gitignore, 可再生) == node_modules / oa-backend/build / .jdks / *.log / Backup-ERP-* / 弃用的OFBiz核心(只保留modern-ui) 完整文件夹备份见同目录 Backup-ERP-20260615-191517/ (含上述全部, 仅缺 node_modules) 时间戳: 20260615-191517 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
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.SewageShiftHandover;
|
||||
import com.kaidi.oa.repository.SewageShiftHandoverRepository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 城镇污水运营·值班交接班(补深审计 MISSING 生产计划与调度·值班管理缺口)。
|
||||
*
|
||||
* 区别于 HandoverController(人事岗位移交),本控制器专为水厂班次交接建模:
|
||||
* - 当班人员填写交接班记录(运行状态 / 设备情况 / 待办事项);
|
||||
* - 接班人在线签名确认:/{id}/accept,记录 acceptedAt(模拟移动端签名时间);
|
||||
* - 待接班列表:GET /pending — 返回 status=待接班 的记录;
|
||||
* - 今日交接记录:GET /today — 返回当日所有交接记录,支持按 plant 过滤。
|
||||
*
|
||||
* 写口默认受 AuthInterceptor default-deny(ADMIN/APPROVER) 保护。
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/oa/sewage-shift-handovers")
|
||||
public class SewageShiftHandoverController {
|
||||
|
||||
private final SewageShiftHandoverRepository handoverRepo;
|
||||
|
||||
public SewageShiftHandoverController(SewageShiftHandoverRepository handoverRepo) {
|
||||
this.handoverRepo = handoverRepo;
|
||||
}
|
||||
|
||||
// ---------- 基础 CRUD ----------
|
||||
|
||||
@GetMapping
|
||||
public ApiResp<List<SewageShiftHandover>> list(
|
||||
@RequestParam(required = false) String status,
|
||||
@RequestParam(required = false) String plant,
|
||||
@RequestParam(required = false) String handoverDate) {
|
||||
if (status != null && !status.isBlank()) {
|
||||
return ApiResp.ok(handoverRepo.findByStatus(status));
|
||||
}
|
||||
if (plant != null && !plant.isBlank()) {
|
||||
return ApiResp.ok(handoverRepo.findByPlant(plant));
|
||||
}
|
||||
if (handoverDate != null && !handoverDate.isBlank()) {
|
||||
return ApiResp.ok(handoverRepo.findByHandoverDate(handoverDate));
|
||||
}
|
||||
return ApiResp.ok(handoverRepo.findAll());
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ApiResp<SewageShiftHandover> get(@PathVariable Long id) {
|
||||
return ApiResp.ok(handoverRepo.findById(id)
|
||||
.orElseThrow(() -> new NotFoundException("交接班记录不存在: " + id)));
|
||||
}
|
||||
|
||||
public record HandoverRequest(
|
||||
String handoverDate, String shift, String plant,
|
||||
String outgoingStaff, String incomingStaff,
|
||||
Double treatedWater, Double codIn, Double codOut, Double ammoniaOut,
|
||||
String processStatus, String equipmentStatus, String faultRecord,
|
||||
String completedWorkOrders, String pendingItems, String safetyNotes,
|
||||
String chemicalNotes, String remark) {
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ApiResp<SewageShiftHandover> create(@RequestBody HandoverRequest req) {
|
||||
if (req.handoverDate() == null || req.handoverDate().isBlank()) {
|
||||
throw new ApiException(400, "交接日期(handoverDate) 不能为空");
|
||||
}
|
||||
if (req.outgoingStaff() == null || req.outgoingStaff().isBlank()) {
|
||||
throw new ApiException(400, "交班人(outgoingStaff) 不能为空");
|
||||
}
|
||||
SewageShiftHandover h = new SewageShiftHandover();
|
||||
h.setCode("SHO-" + (handoverRepo.count() + 1));
|
||||
h.setHandoverDate(req.handoverDate());
|
||||
h.setShift(req.shift());
|
||||
h.setPlant(req.plant());
|
||||
h.setOutgoingStaff(req.outgoingStaff());
|
||||
h.setIncomingStaff(req.incomingStaff());
|
||||
h.setTreatedWater(req.treatedWater());
|
||||
h.setCodIn(req.codIn());
|
||||
h.setCodOut(req.codOut());
|
||||
h.setAmmoniaOut(req.ammoniaOut());
|
||||
h.setProcessStatus(req.processStatus());
|
||||
h.setEquipmentStatus(req.equipmentStatus());
|
||||
h.setFaultRecord(req.faultRecord());
|
||||
h.setCompletedWorkOrders(req.completedWorkOrders());
|
||||
h.setPendingItems(req.pendingItems());
|
||||
h.setSafetyNotes(req.safetyNotes());
|
||||
h.setChemicalNotes(req.chemicalNotes());
|
||||
h.setRemark(req.remark());
|
||||
h.setStatus("待接班");
|
||||
h.setCreatedAt(Instant.now());
|
||||
return ApiResp.ok(handoverRepo.save(h));
|
||||
}
|
||||
|
||||
@PatchMapping("/{id}")
|
||||
@Transactional
|
||||
public ApiResp<SewageShiftHandover> update(@PathVariable Long id, @RequestBody HandoverRequest req) {
|
||||
SewageShiftHandover h = handoverRepo.findById(id)
|
||||
.orElseThrow(() -> new NotFoundException("交接班记录不存在: " + id));
|
||||
if ("已接班".equals(h.getStatus())) {
|
||||
throw new ApiException(409, "已接班的记录不允许修改");
|
||||
}
|
||||
if (req.handoverDate() != null && !req.handoverDate().isBlank()) h.setHandoverDate(req.handoverDate());
|
||||
if (req.shift() != null) h.setShift(req.shift());
|
||||
if (req.plant() != null) h.setPlant(req.plant());
|
||||
if (req.outgoingStaff() != null && !req.outgoingStaff().isBlank()) h.setOutgoingStaff(req.outgoingStaff());
|
||||
if (req.incomingStaff() != null) h.setIncomingStaff(req.incomingStaff());
|
||||
if (req.treatedWater() != null) h.setTreatedWater(req.treatedWater());
|
||||
if (req.codIn() != null) h.setCodIn(req.codIn());
|
||||
if (req.codOut() != null) h.setCodOut(req.codOut());
|
||||
if (req.ammoniaOut() != null) h.setAmmoniaOut(req.ammoniaOut());
|
||||
if (req.processStatus() != null) h.setProcessStatus(req.processStatus());
|
||||
if (req.equipmentStatus() != null) h.setEquipmentStatus(req.equipmentStatus());
|
||||
if (req.faultRecord() != null) h.setFaultRecord(req.faultRecord());
|
||||
if (req.completedWorkOrders() != null) h.setCompletedWorkOrders(req.completedWorkOrders());
|
||||
if (req.pendingItems() != null) h.setPendingItems(req.pendingItems());
|
||||
if (req.safetyNotes() != null) h.setSafetyNotes(req.safetyNotes());
|
||||
if (req.chemicalNotes() != null) h.setChemicalNotes(req.chemicalNotes());
|
||||
if (req.remark() != null) h.setRemark(req.remark());
|
||||
return ApiResp.ok(handoverRepo.save(h));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@Transactional
|
||||
public ApiResp<Void> delete(@PathVariable Long id) {
|
||||
handoverRepo.findById(id).orElseThrow(() -> new NotFoundException("交接班记录不存在: " + id));
|
||||
handoverRepo.deleteById(id);
|
||||
return ApiResp.ok(null);
|
||||
}
|
||||
|
||||
// ---------- 接班签名确认(移动端)----------
|
||||
|
||||
public record AcceptRequest(String incomingStaff, String remark) {
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/accept")
|
||||
@Transactional
|
||||
public ApiResp<SewageShiftHandover> accept(@PathVariable Long id, @RequestBody AcceptRequest req) {
|
||||
SewageShiftHandover h = handoverRepo.findById(id)
|
||||
.orElseThrow(() -> new NotFoundException("交接班记录不存在: " + id));
|
||||
if ("已接班".equals(h.getStatus())) {
|
||||
throw new ApiException(409, "该交接班记录已签收,不可重复操作");
|
||||
}
|
||||
if (req.incomingStaff() != null && !req.incomingStaff().isBlank()) {
|
||||
h.setIncomingStaff(req.incomingStaff());
|
||||
}
|
||||
if (h.getIncomingStaff() == null || h.getIncomingStaff().isBlank()) {
|
||||
throw new ApiException(400, "接班人(incomingStaff) 不能为空");
|
||||
}
|
||||
h.setAcceptedAt(Instant.now());
|
||||
h.setStatus("已接班");
|
||||
if (req.remark() != null) {
|
||||
String prev = h.getRemark() != null ? h.getRemark() : "";
|
||||
h.setRemark(prev.isEmpty() ? req.remark() : prev + "; " + req.remark());
|
||||
}
|
||||
return ApiResp.ok(handoverRepo.save(h));
|
||||
}
|
||||
|
||||
// ---------- 待接班列表 ----------
|
||||
|
||||
@GetMapping("/pending")
|
||||
public ApiResp<List<SewageShiftHandover>> pending() {
|
||||
return ApiResp.ok(handoverRepo.findByStatus("待接班"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user