Pārlūkot izejas kodu

add
研究队列

lifang 2 mēneši atpakaļ
vecāks
revīzija
20c70d09f7
32 mainītis faili ar 1231 papildinājumiem un 74 dzēšanām
  1. 1 1
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/app/controller/ALiYunController.java
  2. 18 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/config/handler/JsonbReasearchPushPointListTypeHandler.java
  3. 51 49
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/config/listener/PatientMonitorListener.java
  4. 3 6
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/BaiLianPluginsController.java
  5. 80 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/BizReasearchQueueClinicController.java
  6. 74 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/BizReasearchQueueController.java
  7. 1 1
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/vo/BizClinicAndAssessmentVO.java
  8. 1 1
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/vo/BizClinicAndDeviceVO.java
  9. 1 1
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/vo/BizClinicAndQuestionVO.java
  10. 1 1
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/vo/BizClinicInfoVO.java
  11. 53 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/vo/BizReasearchQueueVO.java
  12. 50 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/dto/BizReasearchQueueClinicDTO.java
  13. 19 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/dto/BizReasearchQueueClinicQueryDTO.java
  14. 42 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/dto/BizReasearchQueueDTO.java
  15. 30 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/dto/BizReasearchQueueQueryDTO.java
  16. 27 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/entity/BizReasearchPushPointEntity.java
  17. 31 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/enums/ReasearchQueueTimePointType.java
  18. 28 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/mapper/BizReasearchQueueClinicMapper.java
  19. 28 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/mapper/BizReasearchQueueMapper.java
  20. 52 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/po/BizReasearchQueueClinicPO.java
  21. 68 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/po/BizReasearchQueuePO.java
  22. 3 4
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/repository/BizClinicRoomRepository.java
  23. 16 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/repository/BizReasearchQueueClinicRepository.java
  24. 23 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/repository/BizReasearchQueueRepository.java
  25. 3 4
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/service/IBizClinicRoomService.java
  26. 54 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/service/IBizReasearchQueueClinicService.java
  27. 55 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/service/IBizReasearchQueueService.java
  28. 3 3
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/service/impl/BizClinicRoomServiceImpl.java
  29. 92 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/service/impl/BizReasearchQueueClinicServiceImpl.java
  30. 273 0
      tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/service/impl/BizReasearchQueueServiceImpl.java
  31. 3 3
      tr-modules/tr-module-smartFollowUp/src/main/resources/mapper/smart/BizClinicRoomMapper.xml
  32. 47 0
      tr-modules/tr-module-smartFollowUp/src/main/resources/mapper/smart/BizReasearchQueueMapper.xml

+ 1 - 1
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/app/controller/ALiYunController.java

@@ -20,7 +20,7 @@ import java.util.*;
  */
 @RestController
 @RequestMapping("/oauth/aliyun")
-@Api(tags = "识别患者图片信息")
+@Api(tags = "识别患者图片信息",hidden = true)
 public class ALiYunController {
 
     @Autowired

+ 18 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/config/handler/JsonbReasearchPushPointListTypeHandler.java

@@ -0,0 +1,18 @@
+package cn.tr.module.smart.common.config.handler;
+
+import cn.tr.module.smart.common.entity.BizReasearchPushPointEntity;
+import cn.tr.plugin.mybatis.config.handler.JsonbTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+
+import java.util.List;
+
+@MappedJdbcTypes(JdbcType.OTHER)
+@MappedTypes(List.class)
+public class JsonbReasearchPushPointListTypeHandler extends JsonbTypeHandler {
+
+    public JsonbReasearchPushPointListTypeHandler() {
+        super(BizReasearchPushPointEntity.class);
+    }
+}

+ 51 - 49
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/config/listener/PatientMonitorListener.java

@@ -3,6 +3,7 @@ package cn.tr.module.smart.common.config.listener;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.tr.core.annotation.TenantIgnore;
+import cn.tr.core.tenant.TenantContextHolder;
 import cn.tr.core.utils.JsonUtils;
 import cn.tr.module.api.sys.tenant.SysTenantApi;
 import cn.tr.module.api.sys.tenant.SysTenantPojo;
@@ -105,56 +106,57 @@ public class PatientMonitorListener {
         BizDeviceAlarmPO bizDeviceAlarmPO = handleAlarmData(infusionHistory,oldInfusionHistory, deviceHistory);
         if(ObjectUtil.isNotNull(bizDeviceAlarmPO)){
             deviceAlarmRepository.insert(bizDeviceAlarmPO);
+            
         }
-        // 根据住院号查找患者信息
-        log.debug("开始精确查找患者信息,住院号: {}", source.getPatientCode());
-        BizPatientPO patientPO=patientRepository.selectOne(new LambdaQueryWrapper<BizPatientPO>()
-                .eq(BizPatientPO::getPatientCode, source.getPatientCode())
-                .eq(BizPatientPO::getTenantId,tenant.getTenantId())
-                .last("limit 1"));
-
-        // 如果精确查找未找到,则进行模糊查找
-        if(ObjectUtil.isNull(patientPO)){
-            log.debug("精确查找未找到患者,开始模糊查找,住院号: {}", infusionHistory.getPatientCode());
-            patientPO=patientRepository.selectMayBeLinkedPatient(infusionHistory.getPatientCode(),infusionHistory.getTenantId());
-        }
-        // 如果找到相似的住院号
-        if (ObjectUtil.isNotNull(patientPO)) {
-            BizInfusionClinicPO infusionClinic = new BizInfusionClinicPO();
-            infusionClinic.setInfusionId(infusionHistory.getId());
-            infusionClinic.setClinicId(patientPO.getCurrentClinicId());
-            infusionClinic.setType(InfusionBindType.autoBind);
-            //判断有没有被绑定
-            BizInfusionClinicPO infusionClinicPO = infusionClinicRepository.selectOne(new LambdaQueryWrapper<BizInfusionClinicPO>()
-                    .eq(BizInfusionClinicPO::getClinicId, patientPO.getCurrentClinicId())
-                    .last("limit 1"));
-            if(ObjectUtil.isNotNull(infusionClinicPO)&&StrUtil.equals(infusionClinicPO.getInfusionId(),infusionHistory.getId())){
-                //已绑定
-                return;
-            }
-            if (ObjectUtil.isNotNull(infusionClinicPO)) {
-                if(InfusionBindType.autoBind.equals(infusionClinicPO.getType())){
-                    //如果是自动绑的,则判断两个泵头的先后顺序
-                    BizInfusionHistoryPO preInfusionHistory = infusionHistoryRepository.selectById(infusionClinicPO.getInfusionId());
-                    if (ObjectUtil.isNotNull(preInfusionHistory)) {
-                        infusionClinicRepository.deleteById(infusionClinicPO.getId());
-                        infusionClinicRepository.insert(infusionClinic);
-                        log.info("找到匹配的患者信息,患者ID: {}", patientPO.getId());
-                    }else {
-                        if(ObjectUtil.compare(infusionHistory.getInfusionStartTime(),preInfusionHistory.getInfusionStartTime())>0){
-                            infusionClinicRepository.deleteById(infusionClinicPO.getId());
-                            infusionClinicRepository.insert(infusionClinic);
-                            log.info("找到匹配的患者信息,患者ID: {}", patientPO.getId());
-                        }
-                    }
-                }
-            }else {
-                infusionClinicRepository.insert(infusionClinic);
-                log.info("找到匹配的患者信息,患者ID: {}", patientPO.getId());
-            }
-        } else {
-            log.warn("未找到匹配的患者信息,住院号: {}", source.getPatientCode());
-        }
+//        // 根据住院号查找患者信息
+//        log.debug("开始精确查找患者信息,住院号: {}", source.getPatientCode());
+//        BizPatientPO patientPO=patientRepository.selectOne(new LambdaQueryWrapper<BizPatientPO>()
+//                .eq(BizPatientPO::getPatientCode, source.getPatientCode())
+//                .eq(BizPatientPO::getTenantId,tenant.getTenantId())
+//                .last("limit 1"));
+//
+//        // 如果精确查找未找到,则进行模糊查找
+//        if(ObjectUtil.isNull(patientPO)){
+//            log.debug("精确查找未找到患者,开始模糊查找,住院号: {}", infusionHistory.getPatientCode());
+//            patientPO=patientRepository.selectMayBeLinkedPatient(infusionHistory.getPatientCode(),infusionHistory.getTenantId());
+//        }
+//        // 如果找到相似的住院号
+//        if (ObjectUtil.isNotNull(patientPO)) {
+//            BizInfusionClinicPO infusionClinic = new BizInfusionClinicPO();
+//            infusionClinic.setInfusionId(infusionHistory.getId());
+//            infusionClinic.setClinicId(patientPO.getCurrentClinicId());
+//            infusionClinic.setType(InfusionBindType.autoBind);
+//            //判断有没有被绑定
+//            BizInfusionClinicPO infusionClinicPO = infusionClinicRepository.selectOne(new LambdaQueryWrapper<BizInfusionClinicPO>()
+//                    .eq(BizInfusionClinicPO::getClinicId, patientPO.getCurrentClinicId())
+//                    .last("limit 1"));
+//            if(ObjectUtil.isNotNull(infusionClinicPO)&&StrUtil.equals(infusionClinicPO.getInfusionId(),infusionHistory.getId())){
+//                //已绑定
+//                return;
+//            }
+//            if (ObjectUtil.isNotNull(infusionClinicPO)) {
+//                if(InfusionBindType.autoBind.equals(infusionClinicPO.getType())){
+//                    //如果是自动绑的,则判断两个泵头的先后顺序
+//                    BizInfusionHistoryPO preInfusionHistory = infusionHistoryRepository.selectById(infusionClinicPO.getInfusionId());
+//                    if (ObjectUtil.isNotNull(preInfusionHistory)) {
+//                        infusionClinicRepository.deleteById(infusionClinicPO.getId());
+//                        infusionClinicRepository.insert(infusionClinic);
+//                        log.info("找到匹配的患者信息,患者ID: {}", patientPO.getId());
+//                    }else {
+//                        if(ObjectUtil.compare(infusionHistory.getInfusionStartTime(),preInfusionHistory.getInfusionStartTime())>0){
+//                            infusionClinicRepository.deleteById(infusionClinicPO.getId());
+//                            infusionClinicRepository.insert(infusionClinic);
+//                            log.info("找到匹配的患者信息,患者ID: {}", patientPO.getId());
+//                        }
+//                    }
+//                }
+//            }else {
+//                infusionClinicRepository.insert(infusionClinic);
+//                log.info("找到匹配的患者信息,患者ID: {}", patientPO.getId());
+//            }
+//        } else {
+//            log.warn("未找到匹配的患者信息,住院号: {}", source.getPatientCode());
+//        }
 
         log.info("患者监护数据处理完成");
     }

+ 3 - 6
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/BaiLianPluginsController.java

@@ -3,13 +3,10 @@ package cn.tr.module.smart.common.controller;
 import cn.dev33.satoken.annotation.SaIgnore;
 import cn.tr.core.annotation.TenantIgnore;
 import cn.tr.core.pojo.CommonResult;
-import cn.tr.module.smart.app.controller.vo.DoctorClinicRoomVO;
 import cn.tr.module.smart.common.service.IBizClinicRoomService;
-import cn.tr.module.smart.common.vo.BizClinicAndAssessmentVO;
-import cn.tr.module.smart.common.vo.BizClinicAndDeviceVO;
-import cn.tr.module.smart.common.vo.BizClinicAndQuestionVO;
-import cn.tr.plugin.security.bo.UserLoginInfoBO;
-import cn.tr.plugin.security.context.LoginUserContextHolder;
+import cn.tr.module.smart.common.controller.vo.BizClinicAndAssessmentVO;
+import cn.tr.module.smart.common.controller.vo.BizClinicAndDeviceVO;
+import cn.tr.module.smart.common.controller.vo.BizClinicAndQuestionVO;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;

+ 80 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/BizReasearchQueueClinicController.java

@@ -0,0 +1,80 @@
+package cn.tr.module.smart.common.controller;
+
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.tr.core.validation.Insert;
+import cn.tr.core.validation.Update;
+import cn.tr.core.pojo.CommonResult;
+import lombok.AllArgsConstructor;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+import cn.tr.module.smart.common.dto.BizReasearchQueueClinicDTO;
+import cn.tr.module.smart.common.service.IBizReasearchQueueClinicService;
+import cn.tr.module.smart.common.dto.BizReasearchQueueClinicQueryDTO;
+import java.util.*;
+import cn.tr.plugin.mybatis.base.BaseController;
+import org.springframework.web.bind.annotation.*;
+import cn.tr.module.api.sys.log.annotation.OperateLog;
+import cn.tr.core.pojo.TableDataInfo;
+/**
+ * 队列-临床手术关联表控制器
+ *
+ * @author lf
+ * @date  2025/10/15 08:27
+ */
+@Api(tags = "队列-临床手术关联表",hidden = true)
+@RestController
+@RequestMapping("/common/reasearchQueueClinic")
+@AllArgsConstructor
+public class BizReasearchQueueClinicController extends BaseController{
+
+    private final IBizReasearchQueueClinicService bizReasearchQueueClinicService;
+
+    @ApiOperationSupport(author = "lf",order = 1)
+    @ApiOperation(value="根据条件查询队列-临床手术关联表",notes = "权限: 无")
+    @PostMapping("/query/page")
+    public TableDataInfo<BizReasearchQueueClinicDTO> selectList(@RequestBody BizReasearchQueueClinicQueryDTO query) {
+        startPage();
+        return getDataTable(bizReasearchQueueClinicService.selectBizReasearchQueueClinicList(query));
+    }
+
+    @ApiOperationSupport(author = "lf",order = 2)
+    @ApiOperation(value = "根据id查询队列-临床手术关联表",notes = "权限: common:reasearchQueueClinic:query")
+    @GetMapping("/detail/{id}")
+    @SaCheckPermission("common:reasearchQueueClinic:query")
+    public CommonResult<BizReasearchQueueClinicDTO> findById(@PathVariable("id") String id){
+        return CommonResult.success(bizReasearchQueueClinicService.selectBizReasearchQueueClinicById(id));
+    }
+
+    @ApiOperationSupport(author = "lf",order = 3)
+    @ApiOperation(value="添加队列-临床手术关联表",notes = "权限: common:reasearchQueueClinic:add")
+    @PostMapping("/add")
+    @OperateLog
+    @SaCheckPermission("common:reasearchQueueClinic:add")
+    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) BizReasearchQueueClinicDTO source) {
+        return CommonResult.success(bizReasearchQueueClinicService.insertBizReasearchQueueClinic(source));
+    }
+
+    @ApiOperationSupport(author = "lf",order = 4)
+    @ApiOperation(value="通过主键id编辑队列-临床手术关联表",notes = "权限: common:reasearchQueueClinic:edit")
+    @PostMapping("/edit")
+    @OperateLog
+    @SaCheckPermission("common:reasearchQueueClinic:edit")
+    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) BizReasearchQueueClinicDTO source) {
+        return CommonResult.success(bizReasearchQueueClinicService.updateBizReasearchQueueClinicById(source));
+    }
+
+    @ApiOperationSupport(author = "lf",order = 5)
+    @ApiOperation(value="删除队列-临床手术关联表",notes = "权限: common:reasearchQueueClinic:remove")
+    @PostMapping("/removeByIds")
+    @OperateLog
+    @SaCheckPermission("common:reasearchQueueClinic:remove")
+    public CommonResult<Integer> delete(@RequestBody Collection<String> ids) {
+        return CommonResult.success(bizReasearchQueueClinicService.removeBizReasearchQueueClinicByIds(ids));
+    }
+}

+ 74 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/BizReasearchQueueController.java

@@ -0,0 +1,74 @@
+package cn.tr.module.smart.common.controller;
+
+import cn.tr.module.smart.common.controller.vo.BizReasearchQueueVO;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.tr.core.validation.Insert;
+import cn.tr.core.validation.Update;
+import cn.tr.core.pojo.CommonResult;
+import lombok.AllArgsConstructor;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+import cn.tr.module.smart.common.dto.BizReasearchQueueDTO;
+import cn.tr.module.smart.common.service.IBizReasearchQueueService;
+import cn.tr.module.smart.common.dto.BizReasearchQueueQueryDTO;
+import java.util.*;
+import cn.tr.plugin.mybatis.base.BaseController;
+import org.springframework.web.bind.annotation.*;
+import cn.tr.module.api.sys.log.annotation.OperateLog;
+import cn.tr.core.pojo.TableDataInfo;
+/**
+ * 研究队列控制器
+ *
+ * @author lf
+ * @date  2025/10/14 17:18
+ */
+@Api(tags = "研究队列")
+@RestController
+@RequestMapping("/common/reasearchQueue")
+@AllArgsConstructor
+public class BizReasearchQueueController extends BaseController{
+
+    private final IBizReasearchQueueService bizReasearchQueueService;
+
+    @ApiOperationSupport(author = "lf",order = 1)
+    @ApiOperation(value="根据条件查询研究队列",notes = "权限: 无")
+    @PostMapping("/query/page")
+    public TableDataInfo<BizReasearchQueueVO> selectList(@RequestBody BizReasearchQueueQueryDTO query) {
+        startPage();
+        return getDataTable(bizReasearchQueueService.stdSelectBizReasearchQueueList(query));
+    }
+
+    @ApiOperationSupport(author = "lf",order = 2)
+    @ApiOperation(value = "根据id查询研究队列",notes = "权限: 无")
+    @GetMapping("/detail/{id}")
+    public CommonResult<BizReasearchQueueVO> findById(@PathVariable("id") String id){
+        return CommonResult.success(bizReasearchQueueService.selectBizReasearchQueueById(id));
+    }
+
+    @ApiOperationSupport(author = "lf",order = 3)
+    @ApiOperation(value="添加研究队列",notes = "权限: 无")
+    @PostMapping("/add")
+    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) BizReasearchQueueDTO source) {
+        return CommonResult.success(bizReasearchQueueService.insertBizReasearchQueue(source));
+    }
+
+    @ApiOperationSupport(author = "lf",order = 4)
+    @ApiOperation(value="通过主键id编辑研究队列",notes = "权限: 无")
+    @PostMapping("/edit")
+    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) BizReasearchQueueDTO source) {
+        return CommonResult.success(bizReasearchQueueService.updateBizReasearchQueueById(source));
+    }
+
+    @ApiOperationSupport(author = "lf",order = 5)
+    @ApiOperation(value="删除研究队列",notes = "权限: 无")
+    @PostMapping("/removeByIds")
+    public CommonResult<Integer> delete(@RequestBody Collection<String> ids) {
+        return CommonResult.success(bizReasearchQueueService.removeBizReasearchQueueByIds(ids));
+    }
+}

+ 1 - 1
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/vo/BizClinicAndAssessmentVO.java → tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/vo/BizClinicAndAssessmentVO.java

@@ -1,4 +1,4 @@
-package cn.tr.module.smart.common.vo;
+package cn.tr.module.smart.common.controller.vo;
 
 import cn.tr.module.smart.common.config.PainAssessmentJsonbTypeHandler;
 import cn.tr.module.smart.common.entity.BizPainAssessmentContentEntity;

+ 1 - 1
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/vo/BizClinicAndDeviceVO.java → tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/vo/BizClinicAndDeviceVO.java

@@ -1,4 +1,4 @@
-package cn.tr.module.smart.common.vo;
+package cn.tr.module.smart.common.controller.vo;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;

+ 1 - 1
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/vo/BizClinicAndQuestionVO.java → tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/vo/BizClinicAndQuestionVO.java

@@ -1,4 +1,4 @@
-package cn.tr.module.smart.common.vo;
+package cn.tr.module.smart.common.controller.vo;
 
 import cn.tr.module.smart.app.config.ContentListType;
 import cn.tr.module.smart.app.config.QuestionListType;

+ 1 - 1
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/vo/BizClinicInfoVO.java → tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/vo/BizClinicInfoVO.java

@@ -1,4 +1,4 @@
-package cn.tr.module.smart.common.vo;
+package cn.tr.module.smart.common.controller.vo;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;

+ 53 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/controller/vo/BizReasearchQueueVO.java

@@ -0,0 +1,53 @@
+package cn.tr.module.smart.common.controller.vo;
+
+import cn.tr.module.smart.common.config.handler.JsonbReasearchPushPointListTypeHandler;
+import cn.tr.module.smart.common.entity.BizReasearchPushPointEntity;
+import cn.tr.plugin.mybatis.config.handler.JsonbTypeHandler;
+import cn.tr.plugin.mybatis.pojo.TenantPO;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 研究队列实体
+ *
+ * @author lf
+ * @date  2025/10/14 17:18
+ **/
+@Data
+@ToString
+public class BizReasearchQueueVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+    /** id */
+    @ApiModelProperty(value = "id", position = 1)
+    private String id;
+
+    /** 队列名称 */
+    @ApiModelProperty(value = "队列名称", position = 2)
+    private String name;
+
+    @ApiModelProperty(value = "问卷名称",position = 3)
+    private String questionGroupName;
+
+    @ApiModelProperty(value = "推送时间",position = 4)
+    private String timePointsShow;
+
+    /** 队列内手术数量 */
+    @ApiModelProperty(value = "队列人数", position = 5)
+    private Integer clinicCount;
+
+    @ApiModelProperty("创建日期")
+    private Date createTime;
+
+    /** 队列状态 */
+    @ApiModelProperty(value = "当前状态", position = 6)
+    private String status;
+}

+ 50 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/dto/BizReasearchQueueClinicDTO.java

@@ -0,0 +1,50 @@
+package cn.tr.module.smart.common.dto;
+
+import cn.tr.module.smart.common.config.handler.JsonbReasearchPushPointListTypeHandler;
+import cn.tr.module.smart.common.entity.BizReasearchPushPointEntity;
+import cn.tr.plugin.mybatis.pojo.BaseDTO;
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import cn.tr.core.validation.Insert;
+import cn.tr.core.validation.Update;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import javax.validation.constraints.*;
+import java.util.*;
+/**
+ * 队列-临床手术关联表传输对象
+ *
+ * @author lf
+ * @date  2025/10/15 08:27
+ **/
+@Data
+@ApiModel("队列-临床手术关联表传输对象")
+@EqualsAndHashCode(callSuper = true)
+@ToString
+public class BizReasearchQueueClinicDTO extends BaseDTO  {
+    private static final long serialVersionUID = 1L;
+    @ApiModelProperty(value = "id", position = 1)
+     @NotBlank  (message = "主键不能为空",groups = {Update.class})
+    private String id;
+
+    @ApiModelProperty(value = "临床id", position = 2)
+    private String clinicRoomId;
+
+    @ApiModelProperty(value = "队列id", position = 3)
+    private String queueId;
+
+    @ApiModelProperty(value = "上一次推送的时间间隔", position = 4)
+    private Integer lastPushInterval;
+
+    @ApiModelProperty(value = "推送次数", position = 6)
+    private Integer pushCount;
+
+    @ApiModelProperty(value = "上一次的推送时间", position = 7)
+    private Date lastPushTime;
+
+    @ApiModelProperty(value = "回答次数", position = 8)
+    private Integer answerCount;
+
+}

+ 19 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/dto/BizReasearchQueueClinicQueryDTO.java

@@ -0,0 +1,19 @@
+package cn.tr.module.smart.common.dto;
+
+import lombok.ToString;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.util.*;
+/**
+ * 队列-临床手术关联表查询参数
+ *
+ * @author lf
+ * @date  2025/10/15 08:27
+ **/
+@Data
+@ApiModel("队列-临床手术关联表查询参数")
+@ToString
+public class BizReasearchQueueClinicQueryDTO  {
+    private static final long serialVersionUID = 1L;
+}

+ 42 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/dto/BizReasearchQueueDTO.java

@@ -0,0 +1,42 @@
+package cn.tr.module.smart.common.dto;
+
+import cn.tr.module.smart.common.entity.BizReasearchPushPointEntity;
+import cn.tr.plugin.mybatis.pojo.BaseDTO;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import cn.tr.core.validation.Update;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import javax.validation.constraints.*;
+import java.util.*;
+/**
+ * 研究队列传输对象
+ *
+ * @author lf
+ * @date  2025/10/14 17:18
+ **/
+@Data
+@ApiModel("研究队列传输对象")
+@EqualsAndHashCode(callSuper = true)
+@ToString
+public class BizReasearchQueueDTO extends BaseDTO  {
+    private static final long serialVersionUID = 1L;
+    @ApiModelProperty(value = "id", position = 1)
+    @NotBlank  (message = "主键不能为空",groups = {Update.class})
+    private String id;
+
+    @ApiModelProperty(value = "队列名称", position = 3)
+    private String name;
+
+    @ApiModelProperty(value = "队列状态", position = 4)
+    private String status;
+
+    /** 推送时间点 */
+    @ApiModelProperty(value = "推送时间点", position = 5)
+    @NotNull(message = "推送时间点不能为空")
+    private List<BizReasearchPushPointEntity> timePoints;
+
+    @ApiModelProperty(value = "绑定的术后问卷id", position = 8)
+    private String bindQuestionId;
+}

+ 30 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/dto/BizReasearchQueueQueryDTO.java

@@ -0,0 +1,30 @@
+package cn.tr.module.smart.common.dto;
+
+import lombok.ToString;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.util.*;
+/**
+ * 研究队列查询参数
+ *
+ * @author lf
+ * @date  2025/10/14 17:18
+ **/
+@Data
+@ApiModel("研究队列查询参数")
+@ToString
+public class BizReasearchQueueQueryDTO  {
+    private static final long serialVersionUID = 1L;
+    @ApiModelProperty("研究队列名称")
+    private String name;
+
+    @ApiModelProperty("队列状态")
+    private String status;
+
+    @ApiModelProperty("创建时间")
+    private List<Date> createTime;
+
+    @ApiModelProperty(hidden = true)
+    private String currentUser;
+}

+ 27 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/entity/BizReasearchPushPointEntity.java

@@ -0,0 +1,27 @@
+package cn.tr.module.smart.common.entity;
+
+import cn.tr.module.smart.common.enums.ReasearchQueueTimePointType;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+@ApiModel("推送时间点")
+public class BizReasearchPushPointEntity {
+    /**
+     * {@link ReasearchQueueTimePointType}
+     */
+    @ApiModelProperty("术后时间单位 天:day 周:week 月:month 年:year")
+    @NotBlank(message = "术后时间单位不能为空")
+    private String timeUnit;
+
+    @ApiModelProperty("术后时间间隔")
+    @NotBlank(message = "术后时间间隔不能为空")
+    private Integer interval;
+
+    @ApiModelProperty("时间点 格式为:HH:mm")
+    @NotBlank(message = "时间点不能为空")
+    private String timePoint;
+}

+ 31 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/enums/ReasearchQueueTimePointType.java

@@ -0,0 +1,31 @@
+package cn.tr.module.smart.common.enums;
+/**
+ * 研究队列时间点类型接口
+ *
+ * 该接口用于定义研究队列中时间点类型的常量标识
+ *
+ * @author lf
+ * @since 2025/10/14 17:18
+ */
+public interface ReasearchQueueTimePointType {
+
+    /**
+     * 天时间单位
+     */
+    String day = "day";
+
+    /**
+     * 周时间单位
+     */
+    String week = "week";
+
+    /**
+     * 月时间单位
+     */
+    String month = "month";
+
+    /**
+     * 年时间单位
+     */
+    String year = "year";
+}

+ 28 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/mapper/BizReasearchQueueClinicMapper.java

@@ -0,0 +1,28 @@
+package cn.tr.module.smart.common.mapper;
+
+import cn.tr.module.smart.common.po.BizReasearchQueueClinicPO;
+import cn.tr.module.smart.common.dto.BizReasearchQueueClinicDTO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+* 队列-临床手术关联表映射工具
+*
+* @author lf
+* @date  2025/10/15 08:27
+**/
+@Mapper
+public interface BizReasearchQueueClinicMapper {
+    BizReasearchQueueClinicMapper INSTANCE = Mappers.getMapper(BizReasearchQueueClinicMapper.class);
+
+    BizReasearchQueueClinicPO convertPO(BizReasearchQueueClinicDTO source);
+
+    BizReasearchQueueClinicDTO convertDto(BizReasearchQueueClinicPO source);
+
+    List<BizReasearchQueueClinicDTO> convertDtoList(List<BizReasearchQueueClinicPO> source);
+
+    List<BizReasearchQueueClinicPO> convertPOList(List<BizReasearchQueueClinicDTO> source);
+
+}

+ 28 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/mapper/BizReasearchQueueMapper.java

@@ -0,0 +1,28 @@
+package cn.tr.module.smart.common.mapper;
+
+import cn.tr.module.smart.common.po.BizReasearchQueuePO;
+import cn.tr.module.smart.common.dto.BizReasearchQueueDTO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+* 研究队列映射工具
+*
+* @author lf
+* @date  2025/10/14 17:18
+**/
+@Mapper
+public interface BizReasearchQueueMapper {
+    BizReasearchQueueMapper INSTANCE = Mappers.getMapper(BizReasearchQueueMapper.class);
+
+    BizReasearchQueuePO convertPO(BizReasearchQueueDTO source);
+
+    BizReasearchQueueDTO convertDto(BizReasearchQueuePO source);
+
+    List<BizReasearchQueueDTO> convertDtoList(List<BizReasearchQueuePO> source);
+
+    List<BizReasearchQueuePO> convertPOList(List<BizReasearchQueueDTO> source);
+
+}

+ 52 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/po/BizReasearchQueueClinicPO.java

@@ -0,0 +1,52 @@
+package cn.tr.module.smart.common.po;
+
+import cn.tr.plugin.mybatis.pojo.TenantPO;   
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import java.util.*;
+/**
+ * 队列-临床手术关联表实体
+ *
+ * @author lf
+ * @date  2025/10/15 08:27
+ **/
+@Data
+@TableName(value="biz_reasearch_queue_clinic",autoResultMap = true)
+@EqualsAndHashCode(callSuper = true)
+@ToString
+public class BizReasearchQueueClinicPO extends TenantPO {
+
+    /** id */
+    @TableId
+    @ApiModelProperty(value = "id", position = 1)
+    private String id;
+
+    /** 临床id */
+    @ApiModelProperty(value = "临床id", position = 2)
+    private String clinicRoomId;
+
+    /** 队列id */
+    @ApiModelProperty(value = "队列id", position = 3)
+    private String queueId;
+
+    /** 上一次推送的时间间隔 */
+    @ApiModelProperty(value = "上一次推送的时间间隔", position = 4)
+    private Integer lastPushInterval;
+
+    /** 推送次数 */
+    @ApiModelProperty(value = "推送次数", position = 5)
+    private Integer pushCount;
+
+    /** 上一次的推送时间 */
+    @ApiModelProperty(value = "上一次的推送时间", position = 6)
+    private Date lastPushTime;
+
+    /** 回答次数 */
+    @ApiModelProperty(value = "回答次数", position = 7)
+    private Integer answerCount;
+
+}

+ 68 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/po/BizReasearchQueuePO.java

@@ -0,0 +1,68 @@
+package cn.tr.module.smart.common.po;
+
+import cn.tr.module.smart.common.config.handler.JsonbReasearchPushPointListTypeHandler;
+import cn.tr.module.smart.common.entity.BizReasearchPushPointEntity;
+import cn.tr.plugin.mybatis.config.handler.JsonbTypeHandler;
+import cn.tr.plugin.mybatis.pojo.TenantPO;
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.apache.ibatis.type.JdbcType;
+
+import java.util.*;
+/**
+ * 研究队列实体
+ *
+ * @author lf
+ * @date  2025/10/14 17:18
+ **/
+@Data
+@TableName(value="biz_reasearch_queue",autoResultMap = true)
+@EqualsAndHashCode(callSuper = true)
+@ToString
+public class BizReasearchQueuePO extends TenantPO {
+
+    /** id */
+    @TableId
+    @ApiModelProperty(value = "id", position = 1)
+    private String id;
+
+    /** 所属人 */
+    @ApiModelProperty(value = "所属人", position = 2)
+    private String owner;
+
+    /** 队列名称 */
+    @ApiModelProperty(value = "队列名称", position = 3)
+    private String name;
+
+    /** 队列状态 */
+    @ApiModelProperty(value = "队列状态", position = 4)
+    private String status;
+
+    /** 推送时间点 */
+    @ApiModelProperty(value = "推送时间点", position = 5)
+    @TableField(typeHandler = JsonbReasearchPushPointListTypeHandler.class)
+    private List<BizReasearchPushPointEntity> timePoints;
+
+    /** 推送时间点格式化 */
+    @ApiModelProperty(value = "推送时间点格式化", position = 6)
+    @TableField(typeHandler = JsonbTypeHandler.class)
+    private  List<Long> timePointsFormat;
+
+    @ApiModelProperty(value = "将推送时间点转为字符串展示",position = 7)
+    private String timePointsShow;
+
+    /** 队列内手术数量 */
+    @ApiModelProperty(value = "队列内手术数量", position = 8)
+    private Integer clinicCount;
+
+    /** 绑定的术后问卷id */
+    @ApiModelProperty(value = "绑定的术后问卷id", position = 9)
+    private String bindQuestionId;
+
+    @TableField(updateStrategy = FieldStrategy.NEVER,fill = FieldFill.INSERT, jdbcType = JdbcType.VARCHAR)
+    private Integer deleted;
+
+}

+ 3 - 4
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/repository/BizClinicRoomRepository.java

@@ -5,12 +5,11 @@ import cn.tr.module.smart.app.controller.dto.AppDoctorClinicQueryByPatientCodeDT
 import cn.tr.module.smart.app.controller.dto.AppDoctorClinicRoomDTO;
 import cn.tr.module.smart.app.controller.vo.DoctorClinicRoomVO;
 import cn.tr.module.smart.app.controller.vo.WxDoctorClinicRoomThumbnailVO;
-import cn.tr.module.smart.common.dto.BizClinicRoomDTO;
 import cn.tr.module.smart.common.dto.BizClinicRoomQueryDTO;
 import cn.tr.module.smart.common.po.BizClinicRoomPO;
-import cn.tr.module.smart.common.vo.BizClinicAndAssessmentVO;
-import cn.tr.module.smart.common.vo.BizClinicAndDeviceVO;
-import cn.tr.module.smart.common.vo.BizClinicAndQuestionVO;
+import cn.tr.module.smart.common.controller.vo.BizClinicAndAssessmentVO;
+import cn.tr.module.smart.common.controller.vo.BizClinicAndDeviceVO;
+import cn.tr.module.smart.common.controller.vo.BizClinicAndQuestionVO;
 import cn.tr.module.smart.web.dto.BizPatientClinicListDTO;
 import cn.tr.module.smart.web.vo.BizClinicVO;
 import cn.tr.module.smart.wx.controller.vo.BizWxAppletClinicDetailVO;

+ 16 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/repository/BizReasearchQueueClinicRepository.java

@@ -0,0 +1,16 @@
+package cn.tr.module.smart.common.repository;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+import cn.tr.module.smart.common.po.BizReasearchQueueClinicPO;
+/**
+ * 队列-临床手术关联表Mapper接口
+ *
+ * @author lf
+ * @date  2025/10/15 08:27
+ **/
+@Repository
+@Mapper
+public interface BizReasearchQueueClinicRepository extends BaseMapper<BizReasearchQueueClinicPO> {
+}

+ 23 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/repository/BizReasearchQueueRepository.java

@@ -0,0 +1,23 @@
+package cn.tr.module.smart.common.repository;
+
+import cn.tr.module.smart.common.controller.vo.BizReasearchQueueVO;
+import cn.tr.module.smart.common.dto.BizReasearchQueueQueryDTO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+import cn.tr.module.smart.common.po.BizReasearchQueuePO;
+
+import java.util.List;
+
+/**
+ * 研究队列Mapper接口
+ *
+ * @author lf
+ * @date  2025/10/14 17:18
+ **/
+@Repository
+@Mapper
+public interface BizReasearchQueueRepository extends BaseMapper<BizReasearchQueuePO> {
+    List<BizReasearchQueueVO> stdSelectBizReasearchQueueList(@Param("query") BizReasearchQueueQueryDTO query);
+}

+ 3 - 4
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/service/IBizClinicRoomService.java

@@ -8,9 +8,9 @@ import cn.tr.module.smart.app.controller.vo.WxDoctorClinicRoomThumbnailVO;
 import cn.tr.module.smart.common.dto.BizClinicAddOrEditDTO;
 import cn.tr.module.smart.common.dto.BizClinicRoomDTO;
 import cn.tr.module.smart.common.dto.BizClinicRoomQueryDTO;
-import cn.tr.module.smart.common.vo.BizClinicAndAssessmentVO;
-import cn.tr.module.smart.common.vo.BizClinicAndDeviceVO;
-import cn.tr.module.smart.common.vo.BizClinicAndQuestionVO;
+import cn.tr.module.smart.common.controller.vo.BizClinicAndAssessmentVO;
+import cn.tr.module.smart.common.controller.vo.BizClinicAndDeviceVO;
+import cn.tr.module.smart.common.controller.vo.BizClinicAndQuestionVO;
 import cn.tr.module.smart.web.dto.BizClinicShiftDoctorDTO;
 import cn.tr.module.smart.web.dto.BizDeviceBindClinicDTO;
 import cn.tr.module.smart.web.vo.BizClinicVO;
@@ -20,7 +20,6 @@ import cn.tr.module.smart.wx.controller.vo.BizWxDeptQuestionVO;
 import cn.tr.module.smart.wx.dto.*;
 import com.alibaba.dashscope.exception.InputRequiredException;
 import com.alibaba.dashscope.exception.NoApiKeyException;
-import org.springframework.cache.annotation.Cacheable;
 
 import java.io.IOException;
 import java.util.Collection;

+ 54 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/service/IBizReasearchQueueClinicService.java

@@ -0,0 +1,54 @@
+package cn.tr.module.smart.common.service;
+
+import cn.tr.module.smart.common.dto.BizReasearchQueueClinicDTO;
+import cn.tr.module.smart.common.dto.BizReasearchQueueClinicQueryDTO;
+import java.util.*;
+
+/**
+ * 队列-临床手术关联表Service接口
+ *
+ * @author lf
+ * @date  2025/10/15 08:27
+ **/
+public interface IBizReasearchQueueClinicService{
+
+    /**
+     * 根据条件查询队列-临床手术关联表
+     * @param    query 查询参数
+     * @author   lf
+     * @date      2025/10/15 08:27
+     */
+    List<BizReasearchQueueClinicDTO> selectBizReasearchQueueClinicList(BizReasearchQueueClinicQueryDTO query);
+
+    /**
+     * 根据id查询队列-临床手术关联表
+     * @param    id 主键id
+     * @author   lf
+     * @date      2025/10/15 08:27
+     */
+    BizReasearchQueueClinicDTO selectBizReasearchQueueClinicById(String id);
+
+    /**
+     * 编辑队列-临床手术关联表
+     * @param   source 编辑实体类
+     * @author  lf
+     * @date     2025/10/15 08:27
+     */
+    boolean updateBizReasearchQueueClinicById(BizReasearchQueueClinicDTO source);
+
+    /**
+     * 新增队列-临床手术关联表
+     * @param   source 新增实体类
+     * @author lf
+     * @date  2025/10/15 08:27
+     */
+    boolean insertBizReasearchQueueClinic(BizReasearchQueueClinicDTO source);
+
+    /**
+     * 删除队列-临床手术关联表详情
+     * @param  ids 删除主键集合
+     * @author lf
+     * @date    2025/10/15 08:27
+     */
+    int removeBizReasearchQueueClinicByIds(Collection<String> ids);
+}

+ 55 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/service/IBizReasearchQueueService.java

@@ -0,0 +1,55 @@
+package cn.tr.module.smart.common.service;
+
+import cn.tr.module.smart.common.controller.vo.BizReasearchQueueVO;
+import cn.tr.module.smart.common.dto.BizReasearchQueueDTO;
+import cn.tr.module.smart.common.dto.BizReasearchQueueQueryDTO;
+import java.util.*;
+
+/**
+ * 研究队列Service接口
+ *
+ * @author lf
+ * @date  2025/10/14 17:18
+ **/
+public interface IBizReasearchQueueService{
+
+    /**
+     * 根据条件查询研究队列
+     * @param    query 查询参数
+     * @author   lf
+     * @date      2025/10/14 17:18
+     */
+    List<BizReasearchQueueVO> stdSelectBizReasearchQueueList(BizReasearchQueueQueryDTO query);
+
+    /**
+     * 根据id查询研究队列
+     * @param    id 主键id
+     * @author   lf
+     * @date      2025/10/14 17:18
+     */
+    BizReasearchQueueVO selectBizReasearchQueueById(String id);
+
+    /**
+     * 编辑研究队列
+     * @param   source 编辑实体类
+     * @author  lf
+     * @date     2025/10/14 17:18
+     */
+    boolean updateBizReasearchQueueById(BizReasearchQueueDTO source);
+
+    /**
+     * 新增研究队列
+     * @param   source 新增实体类
+     * @author lf
+     * @date  2025/10/14 17:18
+     */
+    boolean insertBizReasearchQueue(BizReasearchQueueDTO source);
+
+    /**
+     * 删除研究队列详情
+     * @param  ids 删除主键集合
+     * @author lf
+     * @date    2025/10/14 17:18
+     */
+    int removeBizReasearchQueueByIds(Collection<String> ids);
+}

+ 3 - 3
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/service/impl/BizClinicRoomServiceImpl.java

@@ -27,9 +27,9 @@ import cn.tr.module.smart.common.po.*;
 import cn.tr.module.smart.common.properties.ALiYunProperties;
 import cn.tr.module.smart.common.repository.*;
 import cn.tr.module.smart.common.service.*;
-import cn.tr.module.smart.common.vo.BizClinicAndAssessmentVO;
-import cn.tr.module.smart.common.vo.BizClinicAndDeviceVO;
-import cn.tr.module.smart.common.vo.BizClinicAndQuestionVO;
+import cn.tr.module.smart.common.controller.vo.BizClinicAndAssessmentVO;
+import cn.tr.module.smart.common.controller.vo.BizClinicAndDeviceVO;
+import cn.tr.module.smart.common.controller.vo.BizClinicAndQuestionVO;
 import cn.tr.module.smart.web.dto.BizClinicShiftDoctorDTO;
 import cn.tr.module.smart.web.dto.BizDeviceBindClinicDTO;
 import cn.tr.module.smart.web.vo.BizClinicVO;

+ 92 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/service/impl/BizReasearchQueueClinicServiceImpl.java

@@ -0,0 +1,92 @@
+package cn.tr.module.smart.common.service.impl;
+
+import cn.tr.core.exception.TRExcCode;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import cn.hutool.core.collection.CollectionUtil;
+import org.springframework.transaction.annotation.Transactional;
+import cn.tr.core.exception.ServiceException;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import cn.tr.module.smart.common.repository.BizReasearchQueueClinicRepository;
+import cn.tr.module.smart.common.po.BizReasearchQueueClinicPO;
+import cn.tr.module.smart.common.dto.BizReasearchQueueClinicDTO;
+import cn.tr.module.smart.common.dto.BizReasearchQueueClinicQueryDTO;
+import java.util.*;
+import cn.tr.module.smart.common.service.IBizReasearchQueueClinicService;
+import cn.tr.module.smart.common.mapper.BizReasearchQueueClinicMapper;
+/**
+ * 队列-临床手术关联表Service接口实现类
+ *
+ * @author lf
+ * @date  2025/10/15 08:27
+ **/
+@Service
+public class BizReasearchQueueClinicServiceImpl implements IBizReasearchQueueClinicService {
+    @Autowired
+    private BizReasearchQueueClinicRepository baseRepository;
+
+
+    /**
+    * 根据条件查询队列-临床手术关联表
+    * @param    query 查询参数
+    * @author   lf
+    * @date      2025/10/15 08:27
+    */
+    @Override
+    public List<BizReasearchQueueClinicDTO> selectBizReasearchQueueClinicList(BizReasearchQueueClinicQueryDTO query){
+        return BizReasearchQueueClinicMapper.INSTANCE.convertDtoList(
+                baseRepository.selectList(new LambdaQueryWrapper<BizReasearchQueueClinicPO>()
+                )
+        );
+    };
+
+    /**
+    * 根据id查询队列-临床手术关联表
+    * @param    id 主键id
+    * @author   lf
+    * @date      2025/10/15 08:27
+    */
+    @Override
+    public BizReasearchQueueClinicDTO selectBizReasearchQueueClinicById(String id){
+        return BizReasearchQueueClinicMapper.INSTANCE.convertDto(baseRepository.selectById(id));
+    };
+
+    /**
+    * 编辑队列-临床手术关联表
+    * @param   source 编辑实体类
+    * @author  lf
+    * @date     2025/10/15 08:27
+    */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean updateBizReasearchQueueClinicById(BizReasearchQueueClinicDTO source){
+            return baseRepository.updateById(BizReasearchQueueClinicMapper.INSTANCE.convertPO(source))!=0;
+    };
+
+    /**
+    * 新增队列-临床手术关联表
+    * @param   source 新增实体类
+    * @author lf
+    * @date  2025/10/15 08:27
+    */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean insertBizReasearchQueueClinic(BizReasearchQueueClinicDTO source){
+        return baseRepository.insert(BizReasearchQueueClinicMapper.INSTANCE.convertPO(source))!=0;
+    };
+
+    /**
+    * 删除队列-临床手术关联表详情
+    * @param  ids 删除主键集合
+    * @author lf
+    * @date    2025/10/15 08:27
+    */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int removeBizReasearchQueueClinicByIds(Collection<String> ids){
+        if(CollectionUtil.isEmpty(ids)){
+            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"请选择要删除的数据");
+        }
+        return baseRepository.deleteBatchIds(ids);
+    };
+}

+ 273 - 0
tr-modules/tr-module-smartFollowUp/src/main/java/cn/tr/module/smart/common/service/impl/BizReasearchQueueServiceImpl.java

@@ -0,0 +1,273 @@
+package cn.tr.module.smart.common.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import cn.tr.core.exception.TRExcCode;
+import cn.tr.core.strategy.LoginUserStrategy;
+import cn.tr.core.utils.ValidationUtils;
+import cn.tr.module.smart.common.controller.vo.BizReasearchQueueVO;
+import cn.tr.module.smart.common.entity.BizReasearchPushPointEntity;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import cn.hutool.core.collection.CollectionUtil;
+import org.springframework.transaction.annotation.Transactional;
+import cn.tr.core.exception.ServiceException;
+import cn.tr.module.smart.common.repository.BizReasearchQueueRepository;
+import cn.tr.module.smart.common.po.BizReasearchQueuePO;
+import cn.tr.module.smart.common.dto.BizReasearchQueueDTO;
+import cn.tr.module.smart.common.dto.BizReasearchQueueQueryDTO;
+import java.util.*;
+import cn.tr.module.smart.common.service.IBizReasearchQueueService;
+import cn.tr.module.smart.common.mapper.BizReasearchQueueMapper;
+/**
+ * 研究队列Service接口实现类
+ *
+ * @author lf
+ * @date  2025/10/14 17:18
+ **/
+@Service
+public class BizReasearchQueueServiceImpl implements IBizReasearchQueueService {
+    @Autowired
+    private BizReasearchQueueRepository baseRepository;
+
+
+    /**
+     * 根据条件查询研究队列
+     * @param    query 查询参数
+     * @author   lf
+     * @date      2025/10/14 17:18
+     */
+    @Override
+    public List<BizReasearchQueueVO> stdSelectBizReasearchQueueList(BizReasearchQueueQueryDTO query){
+        return baseRepository.stdSelectBizReasearchQueueList(query);
+    };
+
+    /**
+     * 根据id查询研究队列
+     * @param    id 主键id
+     * @author   lf
+     * @date      2025/10/14 17:18
+     */
+    @Override
+    public BizReasearchQueueVO selectBizReasearchQueueById(String id){
+        return null;
+    };
+
+    /**
+     * 编辑研究队列
+     * @param   source 编辑实体类
+     * @author  lf
+     * @date     2025/10/14 17:18
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean updateBizReasearchQueueById(BizReasearchQueueDTO source){
+        validateSource(source);
+        BizReasearchQueuePO oldSource = baseRepository.selectById(source.getId());
+        String currentUserId = LoginUserStrategy.tr.getCurrentUserId();
+        if(StrUtil.equals(oldSource.getOwner(),currentUserId)){
+            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"您没有权限修改该数据");
+        }
+        BizReasearchQueuePO updateSource = BizReasearchQueueMapper.INSTANCE.convertPO(source);
+        updateSource.setTimePointsShow(formatTimePoints(updateSource.getTimePoints()));
+        updateSource.setTimePointsFormat(calculateAndSetTimePointsFormat(updateSource.getTimePoints()));
+        return baseRepository.updateById(updateSource)!=0;
+    };
+
+    /**
+     * 新增研究队列
+     * @param   source 新增实体类
+     * @author lf
+     * @date  2025/10/14 17:18
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean insertBizReasearchQueue(BizReasearchQueueDTO source){
+        validateSource(source);
+        BizReasearchQueuePO insertSource = BizReasearchQueueMapper.INSTANCE.convertPO(source);
+        insertSource.setOwner(LoginUserStrategy.tr.getCurrentUserId());
+        insertSource.setClinicCount(0);
+        insertSource.setTimePointsShow(formatTimePoints(insertSource.getTimePoints()));
+        insertSource.setTimePointsFormat(calculateAndSetTimePointsFormat(insertSource.getTimePoints()));
+        return baseRepository.insert(insertSource)!=0;
+    };
+
+    /**
+     * 删除研究队列详情
+     * @param  ids 删除主键集合
+     * @author lf
+     * @date    2025/10/14 17:18
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int removeBizReasearchQueueByIds(Collection<String> ids){
+        if(CollectionUtil.isEmpty(ids)){
+            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"请选择要删除的数据");
+        }
+        String currentUserId = LoginUserStrategy.tr.getCurrentUserId();
+        return baseRepository.delete(new LambdaQueryWrapper<BizReasearchQueuePO>()
+                .in(BizReasearchQueuePO::getId,ids)
+                .eq(BizReasearchQueuePO::getOwner,currentUserId));
+    };
+
+    private void validateSource(BizReasearchQueueDTO source){
+        ValidationUtils.validate(source.getTimePoints());
+        for (BizReasearchPushPointEntity timePoint : source.getTimePoints()) {
+            if (!isValidTimePointFormat(timePoint.getTimePoint())) {
+                throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"时间点格式错误");
+            }
+        }
+    }
+
+    /**
+     * 将推送时间点列表转换为可读的字符串格式
+     * 根据图片中的格式:术后一天、三天、一周、三周、一月
+     *
+     * @param timePoints 推送时间点列表
+     * @return 格式化后的字符串
+     */
+    public String formatTimePoints(List<BizReasearchPushPointEntity> timePoints) {
+        if (timePoints == null || timePoints.isEmpty()) {
+            return "";
+        }
+
+        List<String> formattedPoints = new ArrayList<>();
+
+        for (BizReasearchPushPointEntity point : timePoints) {
+            String timeUnit = point.getTimeUnit();
+            Integer interval = point.getInterval();
+
+            if (interval != null && timeUnit != null) {
+                String formattedPoint = formatSingleTimePoint(interval, timeUnit);
+                formattedPoints.add(formattedPoint);
+            }
+        }
+
+        // 按照时间间隔从小到大排序(先按单位,再按数值)
+        formattedPoints.sort((a, b) -> {
+            // 提取数字和单位
+            String[] aParts = a.split("(?<=\\d)(?=\\D)");
+            String[] bParts = b.split("(?<=\\d)(?=\\D)");
+
+            int aNum = Integer.parseInt(aParts[0].replaceAll("术后", ""));
+            String aUnit = aParts[1];
+
+            int bNum = Integer.parseInt(bParts[0].replaceAll("术后", ""));
+            String bUnit = bParts[1];
+
+            // 先比较单位(day < week < month < year),再比较数值
+            int unitCompare = compareUnits(aUnit, bUnit);
+            if (unitCompare != 0) {
+                return unitCompare;
+            }
+            return Integer.compare(aNum, bNum);
+        });
+
+        // 使用顿号连接所有时间点
+        return String.join("、", formattedPoints);
+    }
+
+    /**
+     * 比较时间单位的顺序
+     * @param unit1 第一个单位
+     * @param unit2 第二个单位
+     * @return 比较结果
+     */
+    private int compareUnits(String unit1, String unit2) {
+        Map<String, Integer> unitOrder = new HashMap<>();
+        unitOrder.put("天", 1);
+        unitOrder.put("周", 2);
+        unitOrder.put("月", 3);
+        unitOrder.put("年", 4);
+
+        return Integer.compare(unitOrder.getOrDefault(unit1, 5), unitOrder.getOrDefault(unit2, 5));
+    }
+
+
+    /**
+     * 格式化单个时间点为可读字符串
+     *
+     * @param interval 时间间隔
+     * @param timeUnit 时间单位
+     * @return 格式化后的字符串
+     */
+    private String formatSingleTimePoint(Integer interval, String timeUnit) {
+        switch (timeUnit) {
+            case "day":
+                return "术后" + interval + "天";
+            case "week":
+                return "术后" + interval + "周";
+            case "month":
+                return "术后" + interval + "月";
+            case "year":
+                return "术后" + interval + "年";
+            default:
+                return "术后" + interval + "天"; // 默认按天计算
+        }
+    }
+
+
+
+    /**
+     * 计算并设置推送时间点间隔(按从小到大排序)
+     * @param timePoints 推送时间点列表
+     */
+    public List<Long> calculateAndSetTimePointsFormat(List<BizReasearchPushPointEntity> timePoints) {
+        List<Long> result=new ArrayList<>();
+        if (timePoints == null || timePoints.isEmpty()) {
+            return result;
+        }
+        List<Long> intervals = new ArrayList<>();
+
+        for (BizReasearchPushPointEntity pushPoint : timePoints) {
+            String timeUnit = pushPoint.getTimeUnit();
+            Integer interval = pushPoint.getInterval();
+
+            if (interval != null) {
+                long milliseconds = convertToMilliseconds(interval, timeUnit);
+                intervals.add(milliseconds);
+            }
+        }
+
+        // 按间隔从小到大排序
+        intervals.sort(Long::compareTo);
+        return intervals;
+    }
+
+    /**
+     * 将时间间隔转换为毫秒数
+     * @param interval 时间间隔
+     * @param timeUnit 时间单位
+     * @return 毫秒数
+     */
+    private long convertToMilliseconds(Integer interval, String timeUnit) {
+        switch (timeUnit) {
+            case "day":
+                return interval * 24L * 60 * 60 * 1000;
+            case "week":
+                return interval * 7L * 24 * 60 * 60 * 1000;
+            case "month":
+                return interval * 30L * 24 * 60 * 60 * 1000; // 近似值
+            case "year":
+                return interval * 365L * 24 * 60 * 60 * 1000; // 近似值
+            default:
+                return interval * 60L * 1000; // 默认按分钟计算
+        }
+    }
+
+    /**
+     * 校验时间点格式是否为HH:mm格式
+     * @param timePoint 时间点字符串
+     * @return 是否符合HH:mm格式
+     */
+    public boolean isValidTimePointFormat(String timePoint) {
+        if (timePoint == null || timePoint.isEmpty()) {
+            return false;
+        }
+
+        // 正则表达式匹配HH:mm格式
+        // 支持00:00到23:59的时间格式
+        String timePattern = "^([01]?[0-9]|2[0-3]):[0-5][0-9]$";
+        return timePoint.matches(timePattern);
+    }
+}

+ 3 - 3
tr-modules/tr-module-smartFollowUp/src/main/resources/mapper/smart/BizClinicRoomMapper.xml

@@ -416,7 +416,7 @@
         bih.device_alarm,bih.infusion_start_time,bih.last_upload_time,bih.device_type,bih.hospital_code,
         bih.warn_will_finished,bih.warn_analgesic_poor,bih.warn_low_battery
     </sql>
-    <resultMap id="ClinicAndDevice" type="cn.tr.module.smart.common.vo.BizClinicAndDeviceVO">
+    <resultMap id="ClinicAndDevice" type="cn.tr.module.smart.common.controller.vo.BizClinicAndDeviceVO">
         <result property="clinicId" column="clinic_id"/>
         <result property="clinicName" column="clinic_name"/>
         <result property="clinicNameDoctor" column="clinic_name_doctor"/>
@@ -490,7 +490,7 @@
     <sql id="ClinicAndQuestionAnswerColumn">
         bqa.id as question_answer_id,bqa.content,bqa.question,bqa.question_group_id,bqa.send_time,bqa.answer_time,bqa.deleted,bqa.question_type
     </sql>
-    <resultMap id="ClinicAndQuestionAnswer" type="cn.tr.module.smart.common.vo.BizClinicAndQuestionVO">
+    <resultMap id="ClinicAndQuestionAnswer" type="cn.tr.module.smart.common.controller.vo.BizClinicAndQuestionVO">
         <result property="clinicId" column="clinic_id"/>
         <result property="clinicName" column="clinic_name"/>
         <result property="clinicNameDoctor" column="clinic_name_doctor"/>
@@ -538,7 +538,7 @@
         bpa.flare_up_duration,bpa.sleep_status,bpa.mental_status,bpa.appetite_status,bpa.nausea_vomiting,
         bpa.itching,bpa.dizziness,bpa.throat_pain,bpa.voice_hoarseness,bpa.satisfaction_rating,bpa.pain_nature
     </sql>
-    <resultMap id="ClinicAndAssessment" type="cn.tr.module.smart.common.vo.BizClinicAndAssessmentVO">
+    <resultMap id="ClinicAndAssessment" type="cn.tr.module.smart.common.controller.vo.BizClinicAndAssessmentVO">
         <result property="clinicId" column="clinic_id"/>
         <result property="clinicName" column="clinic_name"/>
         <result property="clinicNameDoctor" column="clinic_name_doctor"/>

+ 47 - 0
tr-modules/tr-module-smartFollowUp/src/main/resources/mapper/smart/BizReasearchQueueMapper.xml

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.tr.module.smart.common.repository.BizReasearchQueueRepository">
+
+    <resultMap id="stdResult" type="cn.tr.module.smart.common.controller.vo.BizReasearchQueueVO">
+        <result property="id" column="id" />
+        <result property="name" column="name" />
+        <result property="questionGroupName" column="question_group_name" />
+        <result property="timePointsShow" column="time_points_show" />
+        <result property="clinicCount" column="clinic_count" />
+        <result property="createTime" column="create_time" />
+        <result property="status" column="status" />
+    </resultMap>
+
+
+    <select id="stdSelectBizReasearchQueueList" resultMap="stdResult">
+        SELECT
+        brq.id as id,
+        brq.name as  name,
+        brq.question_group_name as question_group_name,
+        brq.time_points_show as time_points_show,
+        brq.clinic_count as clinic_count,
+        brq.create_time as create_time,
+        brq.status as  status
+        FROM
+        biz_reasearch_queue as brq
+        left join biz_question_group as bqg on brq.bind_question_id = bqg.id
+        WHERE
+        1=1
+        <if test="query.name != null and query.name != ''">
+            AND brq.name LIKE CONCAT('%',#{query.name},'%')
+        </if>
+        <if test="query.status != null and query.status != ''">
+            AND brq.status = #{query.status}
+        </if>
+        <if test="query.createTime != null and query.createTime.size() > 0">
+            <if test="query.createTime.size() == 1">
+                AND brq.create_time >= #{query.createTime[0]}
+            </if>
+            <if test="query.createTime.size() == 2">
+                AND brq.create_time BETWEEN #{query.createTime[0]} AND #{query.createTime[1]}
+            </if>
+        </if>
+    </select>
+</mapper>