Merge branch '0418_小程序开发' of http://182.92.166.109:3000/zhuangyuanke/PostDischargePatientManage into 0418_小程序开发
Conflicts: postdischarge-manage/src/main/java/com/xinelu/manage/mapper/signpatientmanageroutenode/SignPatientManageRouteNodeMapper.java postdischarge-manage/src/main/resources/mapper/manage/patientinfo/PatientInfoMapper.xml postdischarge-manage/src/main/resources/mapper/manage/signpatientmanageroutenode/SignPatientManageRouteNodeMapper.xml postdischarge-mobile/src/main/java/com/xinelu/mobile/service/homepage/Impl/HomePageServiceImpl.java
This commit is contained in:
commit
6d944b7aa8
@ -0,0 +1,45 @@
|
|||||||
|
package com.xinelu.manage.controller.homepage;
|
||||||
|
|
||||||
|
import com.xinelu.common.core.controller.BaseController;
|
||||||
|
import com.xinelu.common.core.domain.AjaxResult;
|
||||||
|
import com.xinelu.manage.service.homepage.SystemHomePageService;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 首页信息Controller
|
||||||
|
*
|
||||||
|
* @author zh
|
||||||
|
* @date 2024-08-13
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/system/homePage")
|
||||||
|
public class SystemHomePageController extends BaseController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SystemHomePageService systemHomePageService;
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("topStatistics")
|
||||||
|
public AjaxResult topStatistics() {
|
||||||
|
return AjaxResult.success(systemHomePageService.topStatistics());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("signPatientCount")
|
||||||
|
public AjaxResult signPatientCount() {
|
||||||
|
return AjaxResult.success(systemHomePageService.signPatientCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("serviceModeStatistics")
|
||||||
|
public AjaxResult serviceModeStatistics() {
|
||||||
|
return AjaxResult.success(systemHomePageService.serviceModeStatistics());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("taskSituation")
|
||||||
|
public AjaxResult taskSituation(){
|
||||||
|
return AjaxResult.success(systemHomePageService.taskSituation());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,6 +6,9 @@ import com.xinelu.manage.dto.patientinfo.PatientInfoDto;
|
|||||||
import com.xinelu.manage.vo.patientinfo.PatientBaseInfoVo;
|
import com.xinelu.manage.vo.patientinfo.PatientBaseInfoVo;
|
||||||
import com.xinelu.manage.vo.patientinfo.PatientInfoVo;
|
import com.xinelu.manage.vo.patientinfo.PatientInfoVo;
|
||||||
import com.xinelu.manage.vo.patientinfo.PatientNextTaskVo;
|
import com.xinelu.manage.vo.patientinfo.PatientNextTaskVo;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,4 +107,19 @@ public interface PatientInfoMapper {
|
|||||||
* @return 被护理人基本信息
|
* @return 被护理人基本信息
|
||||||
*/
|
*/
|
||||||
ResidentInfo getPatientInfoByOpenId(String openId);
|
ResidentInfo getPatientInfoByOpenId(String openId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据创建时间查询患者数量
|
||||||
|
*
|
||||||
|
* @param firstDay 本月第一天
|
||||||
|
* @param now 当前时间
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int getPatientInfoCountByCreateTime(@Param("firstDay") LocalDate firstDay, @Param("now") LocalDate now);
|
||||||
|
|
||||||
|
int selectPatientInfoCountBySignTime(@Param("firstDay") LocalDate firstDay, @Param("now") LocalDate now);
|
||||||
|
|
||||||
|
int selectPatientSignTotalCount();
|
||||||
|
|
||||||
|
int selectPatientSignServiceCount();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,8 @@ package com.xinelu.manage.mapper.patientprehospitalization;
|
|||||||
|
|
||||||
import com.xinelu.manage.domain.patientprehospitalization.PatientPreHospitalization;
|
import com.xinelu.manage.domain.patientprehospitalization.PatientPreHospitalization;
|
||||||
import com.xinelu.manage.dto.patientinfo.PatientInfoDto;
|
import com.xinelu.manage.dto.patientinfo.PatientInfoDto;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
@ -39,4 +41,12 @@ public interface PatientPreHospitalizationMapper {
|
|||||||
*/
|
*/
|
||||||
public int deleteByIds(Long[] ids);
|
public int deleteByIds(Long[] ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据创建时间查询预住院患者数量
|
||||||
|
*
|
||||||
|
* @param firstDay 本月第一天
|
||||||
|
* @param now 当前时间
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int getPatientPreHospitalizationCountByCreateTime(@Param("firstDay") LocalDate firstDay, @Param("now") LocalDate now);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,15 +3,15 @@ package com.xinelu.manage.mapper.signpatientmanageroutenode;
|
|||||||
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
|
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
|
||||||
import com.xinelu.manage.dto.signpatientmanageroutenode.PatientTaskDto;
|
import com.xinelu.manage.dto.signpatientmanageroutenode.PatientTaskDto;
|
||||||
import com.xinelu.manage.dto.signpatientmanageroutenode.SignPatientManageRouteNodeDto;
|
import com.xinelu.manage.dto.signpatientmanageroutenode.SignPatientManageRouteNodeDto;
|
||||||
import com.xinelu.manage.vo.signpatientmanageroutenode.PatientManageNodeListVo;
|
import com.xinelu.manage.vo.homepage.PatientAndNode;
|
||||||
import com.xinelu.manage.vo.signpatientmanageroutenode.PatientTaskVo;
|
import com.xinelu.manage.vo.signpatientmanageroutenode.*;
|
||||||
import com.xinelu.manage.vo.signpatientmanageroutenode.SignPatientManageNodeAuditVo;
|
|
||||||
import com.xinelu.manage.vo.signpatientmanageroutenode.SignPatientTaskVo;
|
|
||||||
import com.xinelu.manage.vo.signpatientmanageroutenode.TextMessage;
|
|
||||||
import com.xinelu.manage.vo.specialdiseasenode.SpecialDiseaseNodeAuditVo;
|
import com.xinelu.manage.vo.specialdiseasenode.SpecialDiseaseNodeAuditVo;
|
||||||
import java.util.List;
|
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 签约患者管理任务路径节点Mapper接口
|
* 签约患者管理任务路径节点Mapper接口
|
||||||
*
|
*
|
||||||
@ -162,4 +162,10 @@ public interface SignPatientManageRouteNodeMapper {
|
|||||||
*/
|
*/
|
||||||
int getPatientExecutedTaskNum(Long signPatientRecordId);
|
int getPatientExecutedTaskNum(Long signPatientRecordId);
|
||||||
|
|
||||||
|
|
||||||
|
int selectNodeCountByCreateTime(@Param("firstDay") LocalDate firstDay, @Param("now") LocalDate now);
|
||||||
|
|
||||||
|
BigDecimal selectNodeCount(@Param("phoneDialMethod") String phoneDialMethod, @Param("messagePushSign") Long messagePushSign, @Param("appletPushSign") Long appletPushSign);
|
||||||
|
|
||||||
|
List<PatientAndNode> selectNodeExecuteStatus();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,10 @@ import com.xinelu.manage.domain.signpatientrecord.SignPatientRecord;
|
|||||||
import com.xinelu.manage.dto.signpatientrecord.SignPatientListDto;
|
import com.xinelu.manage.dto.signpatientrecord.SignPatientListDto;
|
||||||
import com.xinelu.manage.vo.signpatientrecord.IntentionalSignVo;
|
import com.xinelu.manage.vo.signpatientrecord.IntentionalSignVo;
|
||||||
import com.xinelu.manage.vo.signpatientrecord.SignPatientInfoVo;
|
import com.xinelu.manage.vo.signpatientrecord.SignPatientInfoVo;
|
||||||
import com.xinelu.manage.vo.signpatientrecord.SignPatientRecordVo;
|
|
||||||
import com.xinelu.manage.vo.signpatientrecord.SignPatientListVo;
|
import com.xinelu.manage.vo.signpatientrecord.SignPatientListVo;
|
||||||
|
import com.xinelu.manage.vo.signpatientrecord.SignPatientRecordVo;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,4 +44,6 @@ public interface SignPatientRecordMapper {
|
|||||||
* @Date 2024-08-08 11:00
|
* @Date 2024-08-08 11:00
|
||||||
*/
|
*/
|
||||||
IntentionalSignVo getIntentionalSign(Long id);
|
IntentionalSignVo getIntentionalSign(Long id);
|
||||||
|
|
||||||
|
int selectCheckStatus(@Param("routeCheckStatus") String routeCheckStatus, @Param("serviceStatus") String serviceStatus);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,26 @@
|
|||||||
|
package com.xinelu.manage.service.homepage;
|
||||||
|
|
||||||
|
import com.xinelu.common.core.domain.AjaxResult;
|
||||||
|
import com.xinelu.manage.vo.homepage.ServiceModeStatistics;
|
||||||
|
import com.xinelu.manage.vo.homepage.SignPatientCount;
|
||||||
|
import com.xinelu.manage.vo.homepage.TaskSituation;
|
||||||
|
import com.xinelu.manage.vo.homepage.TopStatisticsVO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 首页信息Service接口
|
||||||
|
*
|
||||||
|
* @author ZH
|
||||||
|
* @date 2024-08-13
|
||||||
|
*/
|
||||||
|
public interface SystemHomePageService {
|
||||||
|
|
||||||
|
TopStatisticsVO topStatistics();
|
||||||
|
|
||||||
|
List<SignPatientCount> signPatientCount();
|
||||||
|
|
||||||
|
List<ServiceModeStatistics> serviceModeStatistics();
|
||||||
|
|
||||||
|
List<TaskSituation> taskSituation();
|
||||||
|
}
|
||||||
@ -0,0 +1,130 @@
|
|||||||
|
package com.xinelu.manage.service.homepage.impl;
|
||||||
|
|
||||||
|
import com.xinelu.common.enums.NodeExecuteStatusEnum;
|
||||||
|
import com.xinelu.common.enums.PhoneDialMethodEnum;
|
||||||
|
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
|
||||||
|
import com.xinelu.manage.mapper.patientprehospitalization.PatientPreHospitalizationMapper;
|
||||||
|
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
|
||||||
|
import com.xinelu.manage.mapper.signpatientrecord.SignPatientRecordMapper;
|
||||||
|
import com.xinelu.manage.service.homepage.SystemHomePageService;
|
||||||
|
import com.xinelu.manage.vo.homepage.*;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.temporal.TemporalAdjusters;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 首页信息Service业务层处理
|
||||||
|
*
|
||||||
|
* @author ZH
|
||||||
|
* @date 2024-08-13
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class SystemHomePageServiceImpl implements SystemHomePageService {
|
||||||
|
@Resource
|
||||||
|
private PatientInfoMapper patientInfoMapper;
|
||||||
|
@Resource
|
||||||
|
private PatientPreHospitalizationMapper patientPreHospitalizationMapper;
|
||||||
|
@Resource
|
||||||
|
private SignPatientManageRouteNodeMapper signPatientManageRouteNodeMapper;
|
||||||
|
@Resource
|
||||||
|
private SignPatientRecordMapper signPatientRecordMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TopStatisticsVO topStatistics() {
|
||||||
|
LocalDate now = LocalDate.now();
|
||||||
|
TopStatisticsVO topStatisticsVO = new TopStatisticsVO();
|
||||||
|
LocalDate firstDay = now.with(TemporalAdjusters.firstDayOfMonth());
|
||||||
|
int createPatientCount = patientInfoMapper.getPatientInfoCountByCreateTime(firstDay, now);
|
||||||
|
int patientPreHospitalizationCount = patientPreHospitalizationMapper.getPatientPreHospitalizationCountByCreateTime(firstDay, now);
|
||||||
|
topStatisticsVO.setThisMonthPatient(createPatientCount + patientPreHospitalizationCount);
|
||||||
|
topStatisticsVO.setSignPatientCount(patientInfoMapper.selectPatientInfoCountBySignTime(firstDay, now));
|
||||||
|
topStatisticsVO.setNodeCount(signPatientManageRouteNodeMapper.selectNodeCountByCreateTime(firstDay, now));
|
||||||
|
topStatisticsVO.setPatientSignCount(patientInfoMapper.selectPatientSignTotalCount());
|
||||||
|
topStatisticsVO.setPatientSignServiceCount(patientInfoMapper.selectPatientSignServiceCount());
|
||||||
|
return topStatisticsVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SignPatientCount> signPatientCount() {
|
||||||
|
List<LocalDate> localDates = new ArrayList<>();
|
||||||
|
List<SignPatientCount> signPatientCounts = new ArrayList<>();
|
||||||
|
LocalDate now = LocalDate.now();
|
||||||
|
for (int i = 5; i >= 0; i--) {
|
||||||
|
LocalDate localDate = now.minusMonths(i);
|
||||||
|
localDates.add(localDate);
|
||||||
|
}
|
||||||
|
for (LocalDate localDate : localDates) {
|
||||||
|
SignPatientCount signPatientCount = new SignPatientCount();
|
||||||
|
LocalDate firstDay = localDate.with(TemporalAdjusters.firstDayOfMonth());
|
||||||
|
LocalDate lastDay = localDate.with(TemporalAdjusters.lastDayOfMonth());
|
||||||
|
int createPatientCount = patientInfoMapper.getPatientInfoCountByCreateTime(firstDay, lastDay);
|
||||||
|
int i = patientInfoMapper.selectPatientInfoCountBySignTime(firstDay, lastDay);
|
||||||
|
signPatientCount.setTime(localDate);
|
||||||
|
signPatientCount.setSignPatientCount(createPatientCount);
|
||||||
|
signPatientCount.setProportion(new BigDecimal(i).divide(new BigDecimal(createPatientCount), 2, RoundingMode.HALF_UP));
|
||||||
|
signPatientCounts.add(signPatientCount);
|
||||||
|
}
|
||||||
|
return signPatientCounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ServiceModeStatistics> serviceModeStatistics() {
|
||||||
|
ArrayList<ServiceModeStatistics> serviceModeStatisticsList = new ArrayList<>();
|
||||||
|
BigDecimal common = signPatientManageRouteNodeMapper.selectNodeCount(PhoneDialMethodEnum.COMMON.getInfo(), null, null);
|
||||||
|
BigDecimal AI = signPatientManageRouteNodeMapper.selectNodeCount(PhoneDialMethodEnum.AI.getInfo(), null, null);
|
||||||
|
BigDecimal messagePushSign = signPatientManageRouteNodeMapper.selectNodeCount(null, 0L, null);
|
||||||
|
BigDecimal appletPushSign = signPatientManageRouteNodeMapper.selectNodeCount(null, null, 0L);
|
||||||
|
BigDecimal all = common.add(AI).add(messagePushSign).add(appletPushSign);
|
||||||
|
serviceModeStatisticsList.add(new ServiceModeStatistics("AI", AI.divide(all, 2, RoundingMode.HALF_UP), AI));
|
||||||
|
serviceModeStatisticsList.add(new ServiceModeStatistics("短信", messagePushSign.divide(all, 2, RoundingMode.HALF_UP), messagePushSign));
|
||||||
|
serviceModeStatisticsList.add(new ServiceModeStatistics("微信", appletPushSign.divide(all, 2, RoundingMode.HALF_UP), appletPushSign));
|
||||||
|
serviceModeStatisticsList.add(new ServiceModeStatistics("人工随访", common.divide(all, 2, RoundingMode.HALF_UP), common));
|
||||||
|
return serviceModeStatisticsList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TaskSituation> taskSituation() {
|
||||||
|
LocalDate now = LocalDate.now();
|
||||||
|
List<TaskSituation> taskSituations = new ArrayList<>();
|
||||||
|
//未审核
|
||||||
|
int checkStatusCount = signPatientRecordMapper.selectCheckStatus("UNAUDITED", "SERVICE_CENTER");
|
||||||
|
//全部
|
||||||
|
int signTimeCount = signPatientRecordMapper.selectCheckStatus(null, "SERVICE_CENTER");
|
||||||
|
//任务
|
||||||
|
List<PatientAndNode> patientAndNodes = signPatientManageRouteNodeMapper.selectNodeExecuteStatus();
|
||||||
|
int unExecutedCount = 0;
|
||||||
|
int allCount = 0;
|
||||||
|
if (CollectionUtils.isNotEmpty(patientAndNodes)) {
|
||||||
|
allCount = patientAndNodes.size();
|
||||||
|
for (PatientAndNode patientAndNode : patientAndNodes) {
|
||||||
|
LocalDate localDate = null;
|
||||||
|
if (Objects.nonNull(patientAndNode.getDischargeTime())) {
|
||||||
|
localDate = patientAndNode.getDischargeTime().plusDays(patientAndNode.getRouteNodeDay());
|
||||||
|
}
|
||||||
|
if (Objects.isNull(patientAndNode.getDischargeTime()) && Objects.nonNull(patientAndNode.getVisitDate())) {
|
||||||
|
localDate = patientAndNode.getVisitDate().plusDays(patientAndNode.getRouteNodeDay());
|
||||||
|
}
|
||||||
|
if (Objects.isNull(localDate)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
boolean before = localDate.isBefore(LocalDate.now()) || localDate.isEqual(LocalDate.now());
|
||||||
|
if (before) {
|
||||||
|
if (!NodeExecuteStatusEnum.EXECUTED.getInfo().equals(patientAndNode.getNodeExecuteStatus())) {
|
||||||
|
unExecutedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskSituations.add(new TaskSituation("人工审核", checkStatusCount, signTimeCount));
|
||||||
|
taskSituations.add(new TaskSituation("人工随访", unExecutedCount, allCount));
|
||||||
|
return taskSituations;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package com.xinelu.manage.vo.homepage;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PatientAndNode {
|
||||||
|
|
||||||
|
private Long signPatientManageRouteNodeIds;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "出院时间(出院患者)")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private LocalDate dischargeTime;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "就诊时间,格式:yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private LocalDate visitDate;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "管理路径节点时间,时间单位为:天")
|
||||||
|
private Integer routeNodeDay;
|
||||||
|
|
||||||
|
private String nodeExecuteStatus;
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package com.xinelu.manage.vo.homepage;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ServiceModeStatistics {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 比例
|
||||||
|
*/
|
||||||
|
private BigDecimal proportion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数量
|
||||||
|
*/
|
||||||
|
private BigDecimal count;
|
||||||
|
|
||||||
|
public ServiceModeStatistics(String name, BigDecimal proportion, BigDecimal count) {
|
||||||
|
super();
|
||||||
|
this.name = name;
|
||||||
|
this.proportion = proportion;
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.xinelu.manage.vo.homepage;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class SignPatientCount {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间
|
||||||
|
*/
|
||||||
|
private LocalDate time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数量
|
||||||
|
*/
|
||||||
|
private Integer SignPatientCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 百分比
|
||||||
|
*/
|
||||||
|
private BigDecimal proportion;
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package com.xinelu.manage.vo.homepage;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class TaskSituation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分子
|
||||||
|
*/
|
||||||
|
private Integer count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分母
|
||||||
|
*/
|
||||||
|
private Integer allCount;
|
||||||
|
|
||||||
|
public TaskSituation(String name, Integer count, Integer allCount) {
|
||||||
|
super();
|
||||||
|
this.name = name;
|
||||||
|
this.count = count;
|
||||||
|
this.allCount = allCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.xinelu.manage.vo.homepage;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class TopStatisticsVO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本月新增患者数
|
||||||
|
*/
|
||||||
|
private Integer thisMonthPatient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本月签约患者数
|
||||||
|
*/
|
||||||
|
private Integer signPatientCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本月随访人次
|
||||||
|
*/
|
||||||
|
private Integer nodeCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务总人数
|
||||||
|
*/
|
||||||
|
private Integer patientSignCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务中患者数
|
||||||
|
*/
|
||||||
|
private Integer patientSignServiceCount;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -391,4 +391,14 @@
|
|||||||
#{item.updateTime,jdbcType=TIMESTAMP})
|
#{item.updateTime,jdbcType=TIMESTAMP})
|
||||||
</foreach>
|
</foreach>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
|
<select id="getPatientPreHospitalizationCountByCreateTime" resultType="java.lang.Integer">
|
||||||
|
select
|
||||||
|
count(1)
|
||||||
|
from patient_pre_hospitalization
|
||||||
|
where
|
||||||
|
del_flag = 0
|
||||||
|
and create_time >= #{firstDay}
|
||||||
|
and create_time <= #{now}
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@ -345,9 +345,9 @@
|
|||||||
LEFT JOIN patient_visit_record pvr ON pi.patient_visit_record_id = pvr.id
|
LEFT JOIN patient_visit_record pvr ON pi.patient_visit_record_id = pvr.id
|
||||||
<where>
|
<where>
|
||||||
pi.del_flag = 0
|
pi.del_flag = 0
|
||||||
|
and spmrn.phone_push_sign = 1
|
||||||
AND spmrn.route_check_status = 'AGREE'
|
AND spmrn.route_check_status = 'AGREE'
|
||||||
AND spmrn.task_node_type in ('PHONE_OUTBOUND','QUESTIONNAIRE_SCALE')
|
AND spmrn.task_node_type in ('PHONE_OUTBOUND','QUESTIONNAIRE_SCALE')
|
||||||
AND spmrn.phone_dial_method = 'COMMON'
|
|
||||||
<if test="patientName != null and patientName != ''">
|
<if test="patientName != null and patientName != ''">
|
||||||
AND pi.patient_name LIKE concat('%', #{patientName}, '%')
|
AND pi.patient_name LIKE concat('%', #{patientName}, '%')
|
||||||
</if>
|
</if>
|
||||||
|
|||||||
@ -946,4 +946,44 @@
|
|||||||
where spmr.patient_id = #{patientId} and spmrn.del_flag = 0 and spmrn.node_execute_status = 'EXECUTED'
|
where spmr.patient_id = #{patientId} and spmrn.del_flag = 0 and spmrn.node_execute_status = 'EXECUTED'
|
||||||
GROUP BY spmr.patient_id, spmr.sign_patient_record_id
|
GROUP BY spmr.patient_id, spmr.sign_patient_record_id
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectNodeCountByCreateTime" resultType="java.lang.Integer">
|
||||||
|
select count(1)
|
||||||
|
from sign_patient_manage_route_node
|
||||||
|
where del_flag = 0
|
||||||
|
and phone_push_sign = 1
|
||||||
|
and create_time >= #{firstDay}
|
||||||
|
and create_time <= #{now}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectNodeCount" resultType="java.math.BigDecimal">
|
||||||
|
select count(1)
|
||||||
|
from sign_patient_manage_route_node
|
||||||
|
where del_flag = 0
|
||||||
|
<if test="phoneDialMethod != null and phoneDialMethod != ''">
|
||||||
|
and phone_dial_method =#{phoneDialMethod}
|
||||||
|
</if>
|
||||||
|
<if test="messagePushSign != null and messagePushSign != ''">
|
||||||
|
and message_push_sign =#{messagePushSign}
|
||||||
|
</if>
|
||||||
|
<if test="appletPushSign != null and appletPushSign != ''">
|
||||||
|
and (applet_push_sign =#{appletPushSign}
|
||||||
|
OR official_push_sign =#{appletPushSign})
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectNodeExecuteStatus" resultType="com.xinelu.manage.vo.homepage.PatientAndNode">
|
||||||
|
SELECT spmrn.id signPatientManageRouteNodeIds,
|
||||||
|
spmrn.node_execute_status,
|
||||||
|
pi.discharge_time,
|
||||||
|
pi.visit_date,
|
||||||
|
spmrn.route_node_day
|
||||||
|
from sign_patient_manage_route_node spmrn
|
||||||
|
LEFT JOIN sign_patient_manage_route spmr on spmr.id = spmrn.manage_route_id
|
||||||
|
LEFT JOIN patient_info pi ON pi.id = spmr.patient_id
|
||||||
|
where pi.del_flag = 0
|
||||||
|
and spmrn.phone_push_sign = 1
|
||||||
|
AND spmrn.route_check_status = 'AGREE'
|
||||||
|
AND spmrn.task_node_type in ('PHONE_OUTBOUND','QUESTIONNAIRE_SCALE')
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
@ -523,4 +523,29 @@
|
|||||||
select id, patient_id, intentional_source ,intentional_time, billing_doctor_id, billing_doctor_name
|
select id, patient_id, intentional_source ,intentional_time, billing_doctor_id, billing_doctor_name
|
||||||
from sign_patient_record where id = #{id}
|
from sign_patient_record where id = #{id}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectCheckStatus" resultType="java.lang.Integer">
|
||||||
|
SELECT COUNT(1)
|
||||||
|
from sign_patient_record spr
|
||||||
|
left join patient_info pi on pi.sign_patient_record_id = spr.id
|
||||||
|
<where>
|
||||||
|
spr.del_flag = 0 and pi.del_flag = 0
|
||||||
|
<if test="serviceStatus != null">
|
||||||
|
and pi.service_status = #{serviceStatus}
|
||||||
|
</if>
|
||||||
|
<choose>
|
||||||
|
<when test="routeCheckStatus != null and routeCheckStatus == 'UNAUDITED'.toString()">
|
||||||
|
and (spr.route_check_status is null or spr.portait_check_status is null)
|
||||||
|
</when>
|
||||||
|
<when test="routeCheckStatus != null and routeCheckStatus == 'AGREE'.toString()">
|
||||||
|
and spr.route_check_status = #{routeCheckStatus} and spr.portait_check_status =
|
||||||
|
#{routeCheckStatus}
|
||||||
|
</when>
|
||||||
|
<when test="routeCheckStatus != null and routeCheckStatus == 'DISAGREE'.toString()">
|
||||||
|
and (spr.route_check_status = #{routeCheckStatus} or spr.portait_check_status =
|
||||||
|
#{routeCheckStatus})
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@ -3,10 +3,10 @@ package com.xinelu.mobile.controller.homepage;
|
|||||||
import com.xinelu.common.core.controller.BaseController;
|
import com.xinelu.common.core.controller.BaseController;
|
||||||
import com.xinelu.common.core.domain.AjaxResult;
|
import com.xinelu.common.core.domain.AjaxResult;
|
||||||
import com.xinelu.common.core.page.TableDataInfo;
|
import com.xinelu.common.core.page.TableDataInfo;
|
||||||
import com.xinelu.manage.domain.patienttaskexecuterecord.PatientTaskExecuteRecord;
|
|
||||||
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
|
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
|
||||||
import com.xinelu.manage.dto.patientquestionsubmitresult.PatientQuestionSubmitResultDTO;
|
import com.xinelu.manage.dto.patientquestionsubmitresult.PatientQuestionSubmitResultDTO;
|
||||||
import com.xinelu.mobile.service.homepage.HomePageService;
|
import com.xinelu.mobile.service.homepage.HomePageService;
|
||||||
|
import com.xinelu.mobile.vo.homepage.HealthLog;
|
||||||
import com.xinelu.mobile.vo.myfollowup.MyFollowUpVO;
|
import com.xinelu.mobile.vo.myfollowup.MyFollowUpVO;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ public class HomePageController extends BaseController {
|
|||||||
@GetMapping("/selectTaskExecuteRecord")
|
@GetMapping("/selectTaskExecuteRecord")
|
||||||
public TableDataInfo selectPatientTaskExecuteRecord(Long residentId) {
|
public TableDataInfo selectPatientTaskExecuteRecord(Long residentId) {
|
||||||
startPage();
|
startPage();
|
||||||
List<PatientTaskExecuteRecord> list = homePageService.selectPatientTaskExecuteRecord(residentId);
|
List<HealthLog> list = homePageService.selectPatientTaskExecuteRecord(residentId);
|
||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/mobile/info")
|
@RequestMapping("/postDischarge")
|
||||||
public class MobileInfoController extends BaseController {
|
public class MobileInfoController extends BaseController {
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package com.xinelu.mobile.mapper.homepage;
|
|||||||
|
|
||||||
import com.xinelu.manage.domain.patienttaskexecuterecord.PatientTaskExecuteRecord;
|
import com.xinelu.manage.domain.patienttaskexecuterecord.PatientTaskExecuteRecord;
|
||||||
import com.xinelu.manage.vo.signpatientmanageroute.PhonePush;
|
import com.xinelu.manage.vo.signpatientmanageroute.PhonePush;
|
||||||
|
import com.xinelu.mobile.vo.homepage.HealthLog;
|
||||||
import com.xinelu.mobile.vo.homepage.MessageTabulationVO;
|
import com.xinelu.mobile.vo.homepage.MessageTabulationVO;
|
||||||
import com.xinelu.mobile.vo.homepage.NodeExecuteStatus;
|
import com.xinelu.mobile.vo.homepage.NodeExecuteStatus;
|
||||||
import com.xinelu.mobile.vo.myfollowup.MyFollowUpVO;
|
import com.xinelu.mobile.vo.myfollowup.MyFollowUpVO;
|
||||||
@ -33,7 +34,7 @@ public interface HomePageMapper {
|
|||||||
* @param nodeExecuteStatus 节点状态
|
* @param nodeExecuteStatus 节点状态
|
||||||
* @return PatientTaskExecuteRecord
|
* @return PatientTaskExecuteRecord
|
||||||
*/
|
*/
|
||||||
List<PatientTaskExecuteRecord> selectTaskExecuteRecordByResidentId(@Param("residentId") Long residentId, @Param("nodeExecuteStatus") String nodeExecuteStatus);
|
List<HealthLog> selectTaskExecuteRecordByResidentId(@Param("residentId") Long residentId, @Param("nodeExecuteStatus") String nodeExecuteStatus);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据居民查询满意度问卷
|
* 根据居民查询满意度问卷
|
||||||
|
|||||||
@ -2,10 +2,10 @@ package com.xinelu.mobile.service.homepage;
|
|||||||
|
|
||||||
import com.xinelu.common.core.domain.AjaxResult;
|
import com.xinelu.common.core.domain.AjaxResult;
|
||||||
import com.xinelu.common.core.page.TableDataInfo;
|
import com.xinelu.common.core.page.TableDataInfo;
|
||||||
import com.xinelu.manage.domain.patienttaskexecuterecord.PatientTaskExecuteRecord;
|
|
||||||
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
|
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
|
||||||
import com.xinelu.manage.dto.patientquestionsubmitresult.PatientQuestionSubmitResultDTO;
|
import com.xinelu.manage.dto.patientquestionsubmitresult.PatientQuestionSubmitResultDTO;
|
||||||
import com.xinelu.manage.vo.signpatientmanageroute.PhonePush;
|
import com.xinelu.manage.vo.signpatientmanageroute.PhonePush;
|
||||||
|
import com.xinelu.mobile.vo.homepage.HealthLog;
|
||||||
import com.xinelu.mobile.vo.myfollowup.MyFollowUpVO;
|
import com.xinelu.mobile.vo.myfollowup.MyFollowUpVO;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -64,7 +64,7 @@ public interface HomePageService {
|
|||||||
* @param residentId 用户id
|
* @param residentId 用户id
|
||||||
* @return AjaxResult
|
* @return AjaxResult
|
||||||
*/
|
*/
|
||||||
List<PatientTaskExecuteRecord> selectPatientTaskExecuteRecord(Long residentId);
|
List<HealthLog> selectPatientTaskExecuteRecord(Long residentId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 满意度问卷
|
* 满意度问卷
|
||||||
|
|||||||
@ -39,11 +39,20 @@ import com.xinelu.manage.vo.questionsubjectoption.QuestionSubjectOptionVO;
|
|||||||
import com.xinelu.manage.vo.signpatientmanageroute.PhonePush;
|
import com.xinelu.manage.vo.signpatientmanageroute.PhonePush;
|
||||||
import com.xinelu.mobile.mapper.homepage.HomePageMapper;
|
import com.xinelu.mobile.mapper.homepage.HomePageMapper;
|
||||||
import com.xinelu.mobile.service.homepage.HomePageService;
|
import com.xinelu.mobile.service.homepage.HomePageService;
|
||||||
|
import com.xinelu.mobile.vo.homepage.HealthLog;
|
||||||
import com.xinelu.mobile.vo.homepage.MessageContentVO;
|
import com.xinelu.mobile.vo.homepage.MessageContentVO;
|
||||||
import com.xinelu.mobile.vo.homepage.MessageTabulationVO;
|
import com.xinelu.mobile.vo.homepage.MessageTabulationVO;
|
||||||
import com.xinelu.mobile.vo.homepage.NodeExecuteStatus;
|
import com.xinelu.mobile.vo.homepage.NodeExecuteStatus;
|
||||||
import com.xinelu.mobile.vo.myfollowup.MyFollowUpVO;
|
import com.xinelu.mobile.vo.myfollowup.MyFollowUpVO;
|
||||||
import com.xinelu.mobile.vo.satisfactionquestionnaire.SatisfactionQuestionnaire;
|
import com.xinelu.mobile.vo.satisfactionquestionnaire.SatisfactionQuestionnaire;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@ -279,8 +288,24 @@ public class HomePageServiceImpl implements HomePageService {
|
|||||||
* @return AjaxResult
|
* @return AjaxResult
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<PatientTaskExecuteRecord> selectPatientTaskExecuteRecord(Long residentId) {
|
public List<HealthLog> selectPatientTaskExecuteRecord(Long residentId) {
|
||||||
return homePageMapper.selectTaskExecuteRecordByResidentId(residentId, null);
|
List<HealthLog> patientTaskExecuteRecords = homePageMapper.selectTaskExecuteRecordByResidentId(residentId, null);
|
||||||
|
if (CollectionUtils.isNotEmpty(patientTaskExecuteRecords)) {
|
||||||
|
for (HealthLog patientTaskExecuteRecord : patientTaskExecuteRecords) {
|
||||||
|
LocalDate localDate = null;
|
||||||
|
if (Objects.nonNull(patientTaskExecuteRecord.getDischargeTime())) {
|
||||||
|
localDate = patientTaskExecuteRecord.getDischargeTime().plusDays(patientTaskExecuteRecord.getRouteNodeDay());
|
||||||
|
}
|
||||||
|
if (Objects.isNull(patientTaskExecuteRecord.getDischargeTime()) && Objects.nonNull(patientTaskExecuteRecord.getVisitDate())) {
|
||||||
|
localDate = patientTaskExecuteRecord.getVisitDate().plusDays(patientTaskExecuteRecord.getRouteNodeDay());
|
||||||
|
}
|
||||||
|
if (Objects.isNull(localDate)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
patientTaskExecuteRecord.setExecuteTime(localDate.atTime(0, 0, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return patientTaskExecuteRecords;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
package com.xinelu.mobile.vo.homepage;
|
||||||
|
|
||||||
|
import com.xinelu.manage.domain.patienttaskexecuterecord.PatientTaskExecuteRecord;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class HealthLog extends PatientTaskExecuteRecord {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "出院时间")
|
||||||
|
private LocalDate dischargeTime;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "就诊时间")
|
||||||
|
private LocalDate visitDate;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "管理路径节点时间,时间单位为:天")
|
||||||
|
private Integer routeNodeDay;
|
||||||
|
}
|
||||||
@ -42,15 +42,18 @@
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectTaskExecuteRecordByResidentId"
|
<select id="selectTaskExecuteRecordByResidentId"
|
||||||
resultType="com.xinelu.manage.domain.patienttaskexecuterecord.PatientTaskExecuteRecord">
|
resultType="com.xinelu.mobile.vo.homepage.HealthLog">
|
||||||
select
|
select
|
||||||
CASE
|
CASE
|
||||||
WHEN spmrn.task_node_type = 'PHONE_OUTBOUND' THEN spmrn.phone_template_name
|
WHEN spmrn.task_node_type = 'PHONE_OUTBOUND' THEN spmrn.phone_template_name
|
||||||
WHEN spmrn.task_node_type = 'QUESTIONNAIRE_SCALE' THEN spmrn.questionnaire_name
|
WHEN spmrn.task_node_type = 'QUESTIONNAIRE_SCALE' THEN spmrn.questionnaire_name
|
||||||
WHEN spmrn.task_node_type = 'PROPAGANDA_ARTICLE' THEN spmrn.propaganda_title
|
WHEN spmrn.task_node_type = 'PROPAGANDA_ARTICLE' THEN spmrn.propaganda_title
|
||||||
WHEN spmrn.task_node_type = 'TEXT_REMIND' THEN '文字提醒'
|
WHEN spmrn.task_node_type = 'TEXT_REMIND' THEN '消息通知'
|
||||||
END AS manageRouteNodeName,
|
END AS manageRouteNodeName,
|
||||||
pter.execute_time
|
pter.execute_time,
|
||||||
|
pi.discharge_time,
|
||||||
|
pi.visit_date,
|
||||||
|
spmrn.route_node_day
|
||||||
from sign_patient_manage_route_node spmrn
|
from sign_patient_manage_route_node spmrn
|
||||||
LEFT JOIN sign_patient_manage_route spmr ON spmr.id = spmrn.manage_route_id
|
LEFT JOIN sign_patient_manage_route spmr ON spmr.id = spmrn.manage_route_id
|
||||||
LEFT JOIN patient_info pi ON pi.id = spmr.patient_id
|
LEFT JOIN patient_info pi ON pi.id = spmr.patient_id
|
||||||
@ -163,7 +166,7 @@
|
|||||||
CASE
|
CASE
|
||||||
WHEN spmrn.task_node_type = 'QUESTIONNAIRE_SCALE' THEN spmrn.questionnaire_name
|
WHEN spmrn.task_node_type = 'QUESTIONNAIRE_SCALE' THEN spmrn.questionnaire_name
|
||||||
WHEN spmrn.task_node_type = 'PROPAGANDA_ARTICLE' THEN spmrn.propaganda_title
|
WHEN spmrn.task_node_type = 'PROPAGANDA_ARTICLE' THEN spmrn.propaganda_title
|
||||||
WHEN spmrn.task_node_type = 'TEXT_REMIND' THEN '文字提醒'
|
WHEN spmrn.task_node_type = 'TEXT_REMIND' THEN '消息通知'
|
||||||
END AS manageRouteNodeName
|
END AS manageRouteNodeName
|
||||||
from sign_patient_manage_route_node spmrn
|
from sign_patient_manage_route_node spmrn
|
||||||
LEFT JOIN sign_patient_manage_route spmr ON spmr.id = spmrn.manage_route_id
|
LEFT JOIN sign_patient_manage_route spmr ON spmr.id = spmrn.manage_route_id
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user