From 34981c30a78e8bbd7791131059a9210f9928b62c Mon Sep 17 00:00:00 2001
From: 刘光辉 <347230014@qq.com>
Date: 星期四, 17 九月 2026 09:24:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into master

---
 jnpf-lims/jnpf-lims-controller/src/main/java/jnpf/limsController/LimsHuanjingJianceController.java |  378 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 378 insertions(+), 0 deletions(-)

diff --git a/jnpf-lims/jnpf-lims-controller/src/main/java/jnpf/limsController/LimsHuanjingJianceController.java b/jnpf-lims/jnpf-lims-controller/src/main/java/jnpf/limsController/LimsHuanjingJianceController.java
new file mode 100644
index 0000000..3a277aa
--- /dev/null
+++ b/jnpf-lims/jnpf-lims-controller/src/main/java/jnpf/limsController/LimsHuanjingJianceController.java
@@ -0,0 +1,378 @@
+package jnpf.limsController;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jnpf.exception.DataException;
+import jnpf.limsEntity.LimsHuanjingCaiyangdianVo;
+import jnpf.limsEntity.LimsHuanjingJianceActionParam;
+import jnpf.limsEntity.LimsHuanjingJianceKanbanItemVo;
+import jnpf.limsEntity.LimsHuanjingJianceKanbanRowVo;
+import jnpf.limsEntity.LimsHuanjingJianceQushiDataVo;
+import jnpf.limsEntity.LimsHuanjingJianceQushiParam;
+import jnpf.limsEntity.LimsHuanjingJianceQuyangParam;
+import jnpf.limsEntity.LimsHuanjingJianceJiluEntity;
+import jnpf.limsEntity.LimsSignEntity;
+import jnpf.limsEntity.LimsSignUsageTarget;
+import jnpf.limsEntity.SignOpType;
+import jnpf.limsService.LimsHuanjingJianceService;
+import jnpf.limsService.LimsSignService;
+import jnpf.util.R;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+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.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.LocalDate;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+@Slf4j
+@Tag(name = "lims鐜鐩戞祴鎺ュ彛", description = "鐜鐩戞祴閲囨牱鐐� / 璁″垝鎿嶄綔")
+@RestController
+@RequestMapping("/lims/biz/huanjing/jiance")
+public class LimsHuanjingJianceController {
+
+    @Autowired
+    private LimsHuanjingJianceService limsHuanjingJianceService;
+    @Autowired
+    private LimsSignService limsSignService;
+
+    /**
+     * 鏌ヨ閲囨牱鐐广��
+     *
+     * <p>鍓嶇浼犲叆鐨� {@code jiance_quyu_id} 涓� lims_huanjing_quyu.f_id锛�
+     * lims_huanjing_caiyangdian 瀹為檯鐢� jiance_quyu 瀛楁淇濆瓨璇ュ尯鍩熶富閿��
+     */
+    @Operation(summary = "鏌ヨ閲囨牱鐐�")
+    @GetMapping("/caiyangdian/list")
+    public R<List<LimsHuanjingCaiyangdianVo>> listCaiyangdian(
+            @RequestParam("jiance_quyu_id") String jianceQuyuId,
+            @RequestParam(value = "jiejing_jibie", required = false) String jiejingJibie) {
+        if (!StringUtils.hasText(jianceQuyuId)) {
+            return R.error("妫�娴嬪尯鍩烮D涓嶈兘涓虹┖");
+        }
+
+        String jibie = StringUtils.hasText(jiejingJibie) ? jiejingJibie.trim() : null;
+        return R.success(limsHuanjingJianceService.listCaiyangdian(jianceQuyuId.trim(), jibie));
+    }
+
+    /**
+     * 鐜鐩戞祴璁″垝鐪嬫澘琛屻��
+     */
+    @Operation(summary = "鐜鐩戞祴璁″垝鐪嬫澘琛�")
+    @GetMapping("/kanban/rows")
+    public R<List<LimsHuanjingJianceKanbanRowVo>> listKanbanRows(
+            @RequestParam(value = "jiance_quyu", required = false) String jianceQuyu,
+            @RequestParam(value = "weizhi_bianhao", required = false) String weizhiBianhao,
+            @RequestParam(value = "jiejing_jibie", required = false) String jiejingJibie) {
+        return R.success(limsHuanjingJianceService.listKanbanRows(
+                trimToNull(jianceQuyu),
+                trimToNull(weizhiBianhao),
+                trimToNull(jiejingJibie)));
+    }
+
+    /**
+     * 鐜鐩戞祴璁″垝鐪嬫澘鏃ュ巻椤广��
+     */
+    @Operation(summary = "鐜鐩戞祴璁″垝鐪嬫澘鏃ュ巻椤�")
+    @GetMapping("/kanban/items")
+    public R<List<LimsHuanjingJianceKanbanItemVo>> listKanbanItems(
+            @RequestParam("start_date") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
+            @RequestParam("end_date") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate,
+            @RequestParam(value = "jiance_quyu", required = false) String jianceQuyu,
+            @RequestParam(value = "weizhi_bianhao", required = false) String weizhiBianhao,
+            @RequestParam(value = "jiejing_jibie", required = false) String jiejingJibie) {
+        if (startDate == null || endDate == null) {
+            return R.error("鏃ユ湡鑼冨洿涓嶈兘涓虹┖");
+        }
+        if (startDate.isAfter(endDate)) {
+            return R.error("寮�濮嬫棩鏈熶笉鑳藉ぇ浜庣粨鏉熸棩鏈�");
+        }
+
+        ZoneId zoneId = ZoneId.systemDefault();
+        Date start = Date.from(startDate.atStartOfDay(zoneId).toInstant());
+        Date end = Date.from(endDate.atTime(LocalTime.MAX).atZone(zoneId).toInstant());
+        return R.success(limsHuanjingJianceService.listKanbanItems(
+                start,
+                end,
+                trimToNull(jianceQuyu),
+                trimToNull(weizhiBianhao),
+                trimToNull(jiejingJibie)));
+    }
+
+    /**
+     * 鍒犻櫎鐜鐩戞祴璁″垝鐪嬫澘璁板綍瀛愰」銆�
+     */
+    @Operation(summary = "鍒犻櫎鐜鐩戞祴璁″垝鐪嬫澘璁板綍瀛愰」")
+    @DeleteMapping("/kanban/zixiang/{id}")
+    public R<String> deleteKanbanZixiang(@PathVariable("id") String id) {
+        if (!StringUtils.hasText(id)) {
+            return R.error("璁板綍瀛愰」ID涓嶈兘涓虹┖");
+        }
+        try {
+            int affected = limsHuanjingJianceService.deleteKanbanZixiang(id.trim());
+            if (affected <= 0) {
+                return R.error("鐜鐩戞祴璁板綍瀛愰」涓嶅瓨鍦�");
+            }
+            return R.success("鍒犻櫎鎴愬姛");
+        } catch (DataException e) {
+            return R.error(e.getMessage());
+        }
+    }
+
+    /**
+     * 鐜鐩戞祴瓒嬪娍鍒嗘瀽鏁版嵁銆�
+     */
+    @Operation(summary = "鐜鐩戞祴瓒嬪娍鍒嗘瀽鏁版嵁")
+    @PostMapping("/qushi/data")
+    public R<LimsHuanjingJianceQushiDataVo> getQushiData(@RequestBody LimsHuanjingJianceQushiParam param) {
+        if (param == null) {
+            return R.error("璇锋眰鍙傛暟涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(param.getStartDate()) || !StringUtils.hasText(param.getEndDate())) {
+            return R.error("鏃ユ湡鑼冨洿涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(param.getJianceQuyu())) {
+            return R.error("鍖哄煙涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(param.getJiejingJibie())) {
+            return R.error("娲佸噣绾у埆涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(param.getWeizhiBianhao())) {
+            return R.error("鎴块棿缂栧彿涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(param.getJiancePinci())) {
+            return R.error("鐩戞祴棰戞涓嶈兘涓虹┖");
+        }
+        if (param.getJianceXiangmu() == null || param.getJianceXiangmu().isEmpty()) {
+            return R.error("鐩戞祴椤圭洰涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(param.getJianceZhuangtai())) {
+            return R.error("鐩戞祴鐘舵�佷笉鑳戒负绌�");
+        }
+
+        LocalDate startDate;
+        LocalDate endDate;
+        try {
+            startDate = LocalDate.parse(param.getStartDate().trim());
+            endDate = LocalDate.parse(param.getEndDate().trim());
+        } catch (DateTimeParseException e) {
+            return R.error("鏃ユ湡鏍煎紡涓嶆纭�");
+        }
+        if (startDate.isAfter(endDate)) {
+            return R.error("寮�濮嬫棩鏈熶笉鑳藉ぇ浜庣粨鏉熸棩鏈�");
+        }
+
+        List<String> jianceXiangmu = new ArrayList<>();
+        for (String item : param.getJianceXiangmu()) {
+            if (StringUtils.hasText(item)) {
+                jianceXiangmu.add(item.trim());
+            }
+        }
+        if (jianceXiangmu.isEmpty()) {
+            return R.error("鐩戞祴椤圭洰涓嶈兘涓虹┖");
+        }
+
+        ZoneId zoneId = ZoneId.systemDefault();
+        Date start = Date.from(startDate.atStartOfDay(zoneId).toInstant());
+        Date end = Date.from(endDate.atTime(LocalTime.MAX).atZone(zoneId).toInstant());
+        return R.success(limsHuanjingJianceService.listQushiData(
+                start,
+                end,
+                param.getJianceQuyu().trim(),
+                param.getJiejingJibie().trim(),
+                param.getWeizhiBianhao().trim(),
+                param.getJiancePinci().trim(),
+                jianceXiangmu,
+                param.getJianceZhuangtai().trim()));
+    }
+
+    /**
+     * 鐜鐩戞祴璁″垝鎿嶄綔銆�
+     */
+    @Operation(summary = "鐜鐩戞祴璁″垝鎿嶄綔")
+    @PostMapping("/jihua/action")
+    public R<String> jianceJihuaAction(@RequestBody LimsHuanjingJianceActionParam param) {
+        if (param == null) {
+            return R.error("璇锋眰鍙傛暟涓嶈兘涓虹┖");
+        }
+
+        String action = param.getAction();
+        String flowId = param.getFlowId();
+        String taskId = param.getTaskId();
+
+        if (!StringUtils.hasText(action)) {
+            return R.error("缂哄皯 action");
+        }
+        action = action.trim();
+        if (!StringUtils.hasText(flowId)) {
+            return R.error("娴佺▼id(flow_id)涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(taskId)) {
+            return R.error("娴佺▼浠诲姟id(task_id)涓嶈兘涓虹┖");
+        }
+
+        switch (action) {
+            case "accept":
+                int affected = limsHuanjingJianceService.acceptJianceJihua(flowId.trim(), taskId.trim());
+                if (affected <= 0) {
+                    return R.error("鐜鐩戞祴璁″垝鏁版嵁涓嶅瓨鍦�");
+                }
+                return R.success("鍚敤鎴愬姛");
+            case "terminate":
+                int terminated = limsHuanjingJianceService.terminateJianceJihua(flowId.trim(), taskId.trim());
+                if (terminated <= 0) {
+                    return R.error("鐜鐩戞祴璁″垝鏁版嵁涓嶅瓨鍦�");
+                }
+                return R.success("缁堟鎴愬姛");
+            default:
+                return R.error("涓嶆敮鎸佺殑鎿嶄綔: " + action);
+        }
+    }
+
+    /**
+     * 鐜鐩戞祴鎶ュ憡鎿嶄綔銆�
+     */
+    @Operation(summary = "鐜鐩戞祴鎶ュ憡鎿嶄綔")
+    @PostMapping("/baogao/action")
+    public R<String> baogaoAction(@RequestBody LimsHuanjingJianceActionParam param) {
+        if (param == null) {
+            return R.error("璇锋眰鍙傛暟涓嶈兘涓虹┖");
+        }
+
+        String action = param.getAction();
+        String flowId = param.getFlowId();
+        String taskId = param.getTaskId();
+
+        if (!StringUtils.hasText(action)) {
+            return R.error("缂哄皯 action");
+        }
+        action = action.trim();
+        if (!StringUtils.hasText(flowId)) {
+            return R.error("娴佺▼id(flow_id)涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(taskId)) {
+            return R.error("娴佺▼浠诲姟id(task_id)涓嶈兘涓虹┖");
+        }
+        if (!"submit".equals(action) && !"accept".equals(action) && !"reject".equals(action)) {
+            return R.error("涓嶆敮鎸佺殑鎿嶄綔: " + action);
+        }
+
+        int affected = limsHuanjingJianceService.baogaoAction(flowId.trim(), taskId.trim(), action);
+        if (affected <= 0) {
+            return R.error("鐜鐩戞祴鎶ュ憡鏁版嵁涓嶅瓨鍦�");
+        }
+        return R.success("鎿嶄綔鎴愬姛");
+    }
+
+    /**
+     * 鐜鐩戞祴璁板綍鍙栨牱銆�
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Operation(summary = "鐜鐩戞祴璁板綍鍙栨牱")
+    @PostMapping("/jilu/quyang")
+    public R<String> quyangJilu(@RequestBody LimsHuanjingJianceQuyangParam param) {
+        if (param == null) {
+            return R.error("璇锋眰鍙傛暟涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(param.getJiluId())) {
+            return R.error("鐜鐩戞祴璁板綍ID涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(param.getBizSign())) {
+            return R.error("璇锋坊鍔犵數瀛愮鍚�");
+        }
+
+        String jiluId = param.getJiluId().trim();
+        String bizSign = param.getBizSign().trim();
+        LimsHuanjingJianceJiluEntity jilu = limsHuanjingJianceService.findJiluById(jiluId);
+        if (jilu == null) {
+            return R.error("鐜鐩戞祴璁板綍鏁版嵁涓嶅瓨鍦�");
+        }
+        LimsSignEntity sign;
+        try {
+            sign = limsSignService.requireValidSign(
+                    bizSign, SignOpType.HUANJING_QUYANG, jiluId);
+        } catch (DataException e) {
+            return R.error(e.getMessage());
+        }
+        int affected = limsHuanjingJianceService.quyangJilu(jiluId, bizSign);
+        if (affected <= 0) {
+            return R.error("鐜鐩戞祴璁板綍鏁版嵁涓嶅瓨鍦�");
+        }
+        recordHuanjingSignUsage(sign, SignOpType.HUANJING_QUYANG, jilu);
+        return R.success("鍙栨牱鎴愬姛");
+    }
+
+    /**
+     * 鐜鐩戞祴璁板綍缁堟鍙栨牱銆�
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Operation(summary = "鐜鐩戞祴璁板綍缁堟鍙栨牱")
+    @PostMapping("/jilu/quyang/terminate")
+    public R<String> terminateQuyangJilu(@RequestBody LimsHuanjingJianceQuyangParam param) {
+        if (param == null) {
+            return R.error("璇锋眰鍙傛暟涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(param.getJiluId())) {
+            return R.error("鐜鐩戞祴璁板綍ID涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(param.getBizSign())) {
+            return R.error("璇锋坊鍔犵數瀛愮鍚�");
+        }
+
+        String jiluId = param.getJiluId().trim();
+        String bizSign = param.getBizSign().trim();
+        LimsHuanjingJianceJiluEntity jilu = limsHuanjingJianceService.findJiluById(jiluId);
+        if (jilu == null) {
+            return R.error("鐜鐩戞祴璁板綍鏁版嵁涓嶅瓨鍦�");
+        }
+        LimsSignEntity sign;
+        try {
+            sign = limsSignService.requireValidSign(
+                    bizSign, SignOpType.HUANJING_QUYANG_TERMINATE, jiluId);
+        } catch (DataException e) {
+            return R.error(e.getMessage());
+        }
+        int affected = limsHuanjingJianceService.terminateQuyangJilu(jiluId, bizSign);
+        if (affected <= 0) {
+            return R.error("鐜鐩戞祴璁板綍鏁版嵁涓嶅瓨鍦�");
+        }
+        recordHuanjingSignUsage(sign, SignOpType.HUANJING_QUYANG_TERMINATE, jilu);
+        return R.success("缁堟鍙栨牱鎴愬姛");
+    }
+
+    private String trimToNull(String value) {
+        return StringUtils.hasText(value) ? value.trim() : null;
+    }
+
+    private void recordHuanjingSignUsage(LimsSignEntity sign,
+                                         SignOpType opType,
+                                         LimsHuanjingJianceJiluEntity jilu) {
+        String bizCode = StringUtils.hasText(jilu.getJihuaMingcheng())
+                ? jilu.getJihuaMingcheng().trim()
+                : (StringUtils.hasText(jilu.getJihuaId()) ? jilu.getJihuaId().trim() : jilu.getId());
+        LimsSignUsageTarget target = LimsSignUsageTarget.builder()
+                .targetTable("lims_huanjing_jiance_jilu")
+                .targetId(jilu.getId())
+                .bizType("HUANJING_JIANCE")
+                .bizModule("LIMS-鐜鐩戞祴")
+                .bizCode(bizCode)
+                .build();
+        limsSignService.recordSignUsage(sign, opType,
+                Collections.singletonList(jilu.getId()), Collections.singletonList(target));
+    }
+}

--
Gitblit v1.8.0