Compare commits

...

48 Commits

Author SHA1 Message Date
宇宙皮皮娃 50c750f684 顺德删除修改 5 months ago
wyb eeb022da85 fix:顺德人医,hip1122推送召回功能修改 5 months ago
宇宙皮皮娃 9381ec0d0e 顺德死亡修改 6 months ago
宇宙皮皮娃 41817cbfbf 顺德死亡修改 7 months ago
wyb 34480ad8d5 fix: 顺德人医用户不删除,修改状态冻结和不可用 7 months ago
wyb b2888557cb fix: 顺德人医用户不删除,修改状态冻结和不可用 7 months ago
wyb a9cb442250 feat: 顺德人医,HIP1112 检查/检验报告召回推送 7 months ago
宇宙皮皮娃 7ec1634b80 Merge remote-tracking branch 'origin/master' 8 months ago
宇宙皮皮娃 4d063d76c2 修改 8 months ago
wyb a5e43d82a5 feat: 顺德人医,检查报告,病理来源报告,唯一值不需要分隔下划线 10 months ago
宇宙皮皮娃 e1abd3bdbe Merge remote-tracking branch 'origin/master' 1 year ago
宇宙皮皮娃 d34b8d64a8 修复 1 year ago
wyb 8c505bbad9 feat:顺德人医量表采集 1 year ago
宇宙皮皮娃 9c0b5f8a46 新增增加离院方式 1 year ago
wyb 8c7a98a025 feat:顺德人医lungFunction-001 肺功能暂时走pacs,但是下划线不是合并 1 year ago
宇宙皮皮娃 67fd6d57e8 新增增加离院方式 1 year ago
宇宙皮皮娃 941eb07ba1 sql修改 1 year ago
wyb 90f76c7d3f feat:顺德人医移动护理采集报错日志打印 1 year ago
wyb 3a6801300b feat: 用户更新,添加管辖科室的修改,方法注释 1 year ago
wyb 757c0df053 feat: 用户更新,添加管辖科室的修改 1 year ago
宇宙皮皮娃 ce38d65c96 sql修改 1 year ago
宇宙皮皮娃 09995ef181 拆分取消住院 1 year ago
宇宙皮皮娃 11fce9d130 Merge remote-tracking branch 'origin/master' 1 year ago
宇宙皮皮娃 77cb3b3029 管床医生修改 1 year ago
wyb 16dc209139 feat: 新增延迟消息表,护理不再通过redis过期key进行处理 2 years ago
宇宙皮皮娃 d644c4a187 科室名称修改 2 years ago
wyb ca48bd9dd5 feat: 新增检查报告推送手工单,没有住院次数,使用出入院时间范围(出院+3天)或者符合条件在院的。 2 years ago
wyb e0c6936c1c feat: 新增检查报告推送手工单,没有住院次数,使用检查报告时间匹配 2 years ago
宇宙皮皮娃 552b705e76 解档推送 2 years ago
wyb 89a45ea24e fix:修复判断质控失败 2 years ago
wyb 23da7cf02e 更新采集任务的信息 2 years ago
wyb 10a4f72937 检查报告,上报合并文件标题 2 years ago
wyb 119e2bbfdd 检查报告 文件唯一号修改 2 years ago
wyb 145705e82f sql 修复 2 years ago
wyb 8c2160da27 任务创建时间不为空 2 years ago
wyb 664510dab3 lis 时间匹配确认 2 years ago
wyb 9f7e53a050 婴儿的护理任务,不校验完整性,文件传给母亲,来源加_B后缀 2 years ago
wyb b8a0f08d38 母婴关系查询问题修复,新增患者基础数据索引去除m和z 2 years ago
wyb 4ac0f2ff4d 修复1009没存储xml文件 2 years ago
宇宙皮皮娃 48eeb5be29 Merge remote-tracking branch 'origin/master' 2 years ago
宇宙皮皮娃 635a1cee5f 出院时间修改 2 years ago
wyb ba29c4a1fc 文件标题修改 2 years ago
wyb 973a15a526 报告单号存储 2 years ago
wyb af9c1504f5 接口补偿 2 years ago
wyb 9b5ddbb727 mapper修复 2 years ago
wyb f1e4a8298a pacs 补偿job,和信息添加 2 years ago
wyb 451f04c002 修正获取信息节点 2 years ago
wyb 5404536caa 检查报告查询pacs base64日志存储,检查base64获取的配置 2 years ago

@ -1,4 +1,15 @@
{
"blocking": ["xdxt","yx","jc"],
"notHandled":["lis","bl","nh"]
"blocking": [
"xdxt",
"yx",
"jc"
],
"notHandled": [
"lis",
"bl",
"nh"
],
"fetchBase64": [
"cta"
]
}

@ -129,6 +129,18 @@
<artifactId>docus-shiro-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.axis</groupId>
<artifactId>axis</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.apache.axis</groupId>
<artifactId>axis-jaxrpc</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>com.docus</groupId>
<artifactId>docus-base-starter</artifactId>

@ -7,6 +7,8 @@ import com.docus.infrastructure.web.api.CommonResult;
import com.docus.server.api.HospitalSubmitNodeServiceApi;
import com.docus.server.api.dto.HospitalSubmitNodeLogAddDTO;
import com.docus.server.api.enums.HospitalSubmitNodeEnum;
import com.docus.server.common.entity.SdryPacsPrintExcept;
import com.docus.server.common.service.SdryPacsPrintExceptService;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
@ -29,7 +31,9 @@ public class AppRunBootstrap {
System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
SpringApplication.run(AppRunBootstrap.class, args);
}
private static void test1(){
SpringUtils.getBean(SdryPacsPrintExceptService.class).insert(new SdryPacsPrintExcept());
}
private static void test(){
HospitalSubmitNodeServiceApi hospitalSubmitNodeServiceApi = SpringUtils.getBean(HospitalSubmitNodeServiceApi.class);
HospitalSubmitNodeLogAddDTO dto = new HospitalSubmitNodeLogAddDTO();

@ -13,4 +13,6 @@ import org.springframework.stereotype.Component;
public class UserSyncConfig {
@Value("${docus.user.defpwd:}")
private String password;
@Value("docus.user.powerdeptroles:")
private String powerDeptRoles;
}

@ -0,0 +1,63 @@
package com.docus.server.collection.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @BelongsProject: docus_medicalrecord_starter
* @BelongsPackage: com.docus.services.clinicqualitycontrol.dto
* @Author: jiashi1
* @CreateTime: 2023-02-14 14:56
* @Description: TODO
* @Version: 1.0
*/
@Data
@ApiModel("质控和退回推送dto")
public class BacklPushDto {
@ApiModelProperty(value = "病案主键")
private String patientId;
@ApiModelProperty(value = "住院号(病案号)")
private String inpatientNo;
@ApiModelProperty(value = "住院次数")
private Integer admissTimes;
@ApiModelProperty(value = "住院就诊流水号(记账号)")
private String jzh;
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "出院科室代码")
private String disDept;
@ApiModelProperty(value = "出院科室")
private String disDeptName;
@ApiModelProperty(value = "申请人工号")
private String applyUserName;
@ApiModelProperty(value = "申请人")
private String applyName;
@ApiModelProperty(value = "操作人工号")
private String controlUserName;
@ApiModelProperty(value = "操作人")
private String controlName;
@ApiModelProperty(value = "解档时间(召回审批时间开始)")
private String auditTime;
@ApiModelProperty(value = "解档天数(召回天数默认7天)")
private String day;
@ApiModelProperty(value = "解档\\归档状态( 未归档状态\\归档状态) ")
private Integer isArchive;
@ApiModelProperty(value = "解档\\归档文书类型( 召回修改分类对应的采集器id逗号隔开的字符串)")
private String collectIds;
}

@ -0,0 +1,26 @@
package com.docus.server.collection.dto;
import lombok.Data;
@Data
public class BedDoctorDto {
private String serialId;
private String receive;
private String send;
/**
*
*/
private String inpatientNo;
/**
*
*/
private Integer admissTimes;
/**
*
*/
private String bedDoctor;
/**
*
*/
private String bedDoctorName;
}

@ -40,5 +40,6 @@ public class TBasicDto {
//入院状态 1更新 2删除
private String statu;
private Integer isOther;
private String leaveMethod;
}

@ -53,4 +53,8 @@ public class UserModifyParam {
*
*/
private String telephone;
/**
*
*/
private String powerDept;
}

@ -0,0 +1,67 @@
package com.docus.server.collection.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
*
* </p>
*
* @author jiashi
* @since 2023-02-14
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="CqcPushConfig对象", description="推送配置表")
public class CqcPushConfig implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID")
@TableId(value = "id", type = IdType.ID_WORKER_STR)
private Long id;
@ApiModelProperty(value = "业务类型1退回医生2退回护理3退回手麻4退回重症5召回推送6归档推送7病案室纸质签收推送8电子病例解档9护理解档10电子病历归档11护理归档")
private String businessType;
@ApiModelProperty(value = "协议类型1webservice,2http")
private String protocolType;
@ApiModelProperty(value = "命名空间")
private String namespace;
@ApiModelProperty(value = "接口地址")
private String url;
@ApiModelProperty(value = "方法名")
private String method;
@ApiModelProperty(value = "是否启用0否1是")
private Integer effective;
@ApiModelProperty(value = "标题")
private String title;
@ApiModelProperty(value = "创建人")
private String createUser;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "修改人")
private String updateUser;
@ApiModelProperty(value = "修改时间")
private Date updateTime;
@ApiModelProperty(value = "参数json")
private String parameterList;
}

@ -39,4 +39,7 @@ public class TBasicExtend implements Serializable {
@ApiModelProperty(value = "责任护士 对应护士节点")
private String dutyNurse;
@ApiModelProperty(value = "离院方式")
private Integer leaveMethod;
}

@ -0,0 +1,17 @@
package com.docus.server.collection.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.docus.server.collection.entity.CqcPushConfig;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface CqcPushConfigMapper extends BaseMapper<CqcPushConfig> {
/**
* @description
*/
List<CqcPushConfig> getCqcPushConfigByBusinessTypes(@Param("ids") List<Long> ids);
}

@ -41,4 +41,12 @@ public interface PowerUserMapper {
* @return
*/
int delUserByUserName(@Param("userName") String userName);
/**
*
*
* @param userName
* @return
*/
int cancelUserByUserName(@Param("userName") String userName);
}

@ -3,6 +3,7 @@ package com.docus.server.collection.mapper;
import com.docus.server.collection.entity.TBasic;
import com.docus.server.collection.entity.TBasicExtend;
import com.docus.server.report.entity.MaternalInfantRelationship;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -15,44 +16,53 @@ import java.util.List;
* @author jiashi
* @since 2021-04-14
*/
public interface TBasicMapper{
public interface TBasicMapper {
/**
*
*
* @param inpatientNo
* @param admissTimes
* @return
*/
String getPatientIdByInpatientNoAndAdminssTimes(@Param("inpatientNo") String inpatientNo,@Param("adminssTimes") Integer admissTimes);
String getPatientIdByInpatientNoAndAdminssTimes(@Param("inpatientNo") String inpatientNo, @Param("adminssTimes") Integer admissTimes);
Integer selectOne(@Param("jzh") String jzh);
String getPatientId(@Param("jzh") String jzh);
List<String> getPatientIds(@Param("inpatientNo") String inpatientNo,@Param("admissTimes") Integer admissTimes);
Integer setBedDoctor(@Param("patientIds") List<String> patientIds,@Param("bedDoctor") String bedDoctor,@Param("bedDoctorName") String bedDoctorName);
Integer insert(@Param("tBasic") TBasic tBasic);
Integer insertExtend(@Param("tBasicExtend") TBasicExtend tBasicExtend);
Integer update(@Param("tBasic") TBasic tBasic);
Integer cancelHospital(@Param("tBasic") TBasic tBasic);
Integer updateExtend(@Param("tBasicExtend") TBasicExtend tBasicExtend);
List<TBasic> selectBasicListByAdmissDate(@Param("admissStartDate")String admissStartDate,@Param("admissEndDate") String admissEndDate,@Param("offset") int offset,@Param("size") int size);
List<TBasic> selectBasicListByAdmissDate(@Param("admissStartDate") String admissStartDate, @Param("admissEndDate") String admissEndDate, @Param("offset") int offset, @Param("size") int size);
/**
*
* @param patientId
*
* @param patientId
* @return
*/
String getSdRyIndexByPatientId(@Param("patientId")String patientId);
String getSdRyIndexByPatientId(@Param("patientId") String patientId);
List<TBasic> selectBasicListByCreateOrUpdateTime(@Param("startDate")String queryBasicStartDate, @Param("endDate")String queryBasicEndDate, @Param("offset") int offset,@Param("size") int size);
List<TBasic> selectBasicListByCreateOrUpdateTime(@Param("startDate") String queryBasicStartDate, @Param("endDate") String queryBasicEndDate, @Param("offset") int offset, @Param("size") int size);
List<TBasic> selectBasicListByPatientIds(@Param("patientIds") List<String> patientIds);
Integer getNurseFileCount(@Param("patientId")String patientId);
Integer getNurseFileCount(@Param("patientId") String patientId);
/**
*
*
* @param patientId
* @return
*/
@ -60,35 +70,41 @@ public interface TBasicMapper{
/**
*
* @param patientId
*
* @param patientId
* @param removeCount
* @return db
*/
Integer saveNisRemoveFilesCount(@Param("patientId") String patientId,@Param("count") int removeCount);
Integer saveNisRemoveFilesCount(@Param("patientId") String patientId, @Param("count") int removeCount);
/**
*
*
* @param patientId
* @return
*/
String getSdRyIndex(@Param("patientId") String patientId);
/**
*
*
*
* @param babyIndex
* @return
* @return
*/
String getParentSdRyIndex(@Param("babyIndex")String babyIndex);
MaternalInfantRelationship getMaternalInfantRelationship(@Param("babyIndex") String babyIndex);
/**
*
* @param sdRyIndex
*
* @param sdRyIndex
* @param admissTimes
* @return
*/
String getPatientIdBySdRyIndex(@Param("sdRyIndex")String sdRyIndex);
String getPatientIdBySdRyIndexAndAdmissTimes(@Param("sdRyIndex") String sdRyIndex, @Param("admissTimes") String admissTimes);
/**
*
*
* @param patientId
* @return
*/
@ -98,14 +114,16 @@ public interface TBasicMapper{
/**
*
*
* @param patientId
* @param state 0 1
* @param state 0 1
* @return
*/
int updateNursCollectState(@Param("patientId") String patientId, @Param("state") int state);
/**
*
*
* @param patientId
* @return
*/
@ -113,8 +131,33 @@ public interface TBasicMapper{
/**
*
*
* @param userName
* @return
*/
String getNameByUserName(@Param("userName")String userName);
String getNameByUserName(@Param("userName") String userName);
/**
*
*
* @param inpatientNo
* @param reportTime yyyy-MM-dd HH:mm:ss
* @return
* @date 2024/1/9 14:46
* @author YongBin Wen
*/
List<Integer> getAdmissTimesByInpNoAndReportTime(@Param("inpatientNo") String inpatientNo, @Param("reportTime") String reportTime);
/**
*
*
* @param inpNo
* @return java.util.List<com.docus.server.collection.entity.TBasic>
* @date 2024/1/10 8:39
* @author YongBin Wen
*/
List<TBasic> selectBasicListByInpNo(@Param("inpNo") String inpNo);
int deleteExtend(@Param("patientId") String patientId);
}

@ -21,4 +21,12 @@ public interface IPowerUserService {
* @return
*/
boolean delUserByUserName(String userName);
/**
*
*
* @param userName
* @return
*/
boolean cancelUserByUserName(String userName);
}

@ -1,16 +1,23 @@
package com.docus.server.collection.service;
import com.docus.server.collection.dto.BedDoctorDto;
import com.docus.server.collection.dto.TBasicDto;
import com.docus.server.collection.entity.TBasic;
import java.util.Date;
public interface ITBasicService {
public void setTBasic(TBasicDto dto) throws Exception;
public void updateTBasic(TBasicDto dto) throws Exception;
public void cancelHospital(TBasicDto dto) throws Exception;
public void updateAdmissTBasic(TBasicDto dto) throws Exception;
public void setBedDoctor(BedDoctorDto dto) throws Exception;
/**
*
* @param babyPatientId
@ -25,4 +32,15 @@ public interface ITBasicService {
* @return
*/
boolean getIsBabyBasic(String patientId);
/**
*
* @date 2024/1/10 8:33
* @author YongBin Wen
* @param inpatientNo
* @param reportDate
* @param timeRangeAddedHour
* @return java.lang.Integer
*/
Integer matchingAdmissTimesByInpNoAndReportTime(String inpatientNo, Date reportDate, long timeRangeAddedHour);
}

@ -11,6 +11,7 @@ import com.docus.server.collection.service.IPowerUserService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
/**
*
@ -19,6 +20,7 @@ import javax.annotation.Resource;
*/
@Service
public class PowerUserServiceImpl implements IPowerUserService {
@Resource
private PowerUserMapper powerUserMapper;
@Resource
@ -30,6 +32,7 @@ public class PowerUserServiceImpl implements IPowerUserService {
public boolean register(UserDto userDto) {
PowerUser powerUser = powerUserMapper.getUserByUserName(userDto.getUserName());
UserModifyParam userModifyParam = userDto.transUserAddParam();
if (Func.isEmpty(powerUser)) {
long userId = idService.getDateSeq();
userModifyParam.setUserId(userId);
@ -37,11 +40,15 @@ public class PowerUserServiceImpl implements IPowerUserService {
powerUserMapper.addUser(userModifyParam);
return true;
}
String powerDept = getUpdatePowerDept(powerUser, userDto);
userModifyParam.setPowerDept(powerDept);
userModifyParam.setUserId(powerUser.getUserId());
powerUserMapper.updateUser(userModifyParam);
return true;
}
@Override
public boolean delUserByUserName(String userName) {
PowerUser powerUser = powerUserMapper.getUserByUserName(userName);
@ -51,4 +58,41 @@ public class PowerUserServiceImpl implements IPowerUserService {
powerUserMapper.delUserByUserName(userName);
return true;
}
@Override
public boolean cancelUserByUserName(String userName) {
PowerUser powerUser = powerUserMapper.getUserByUserName(userName);
if (Func.isEmpty(powerUser)) {
return true;
}
powerUserMapper.cancelUserByUserName(userName);
return true;
}
/**
*
*
* @param powerUser db
* @param userDto
* @return
*/
private String getUpdatePowerDept(PowerUser powerUser, UserDto userDto) {
// 需要添加管辖科室的角色集合
String powerDeptRoles = syncConfig.getPowerDeptRoles();
List<String> powerDeptRoleList = Objects.isNull(powerDeptRoles) ? new ArrayList<>() : Arrays.asList(powerDeptRoles.split(","));
Long roleId = powerUser.getRoleId();
String powerDept = powerUser.getPowerDept();
// 添加的角色特殊处理添加
if (powerDeptRoleList.contains(String.valueOf(roleId))) {
Set<String> powerDeptList = new HashSet<>();
if (!Objects.isNull(powerUser.getPowerDept())) {
String[] origPowerDepts = powerUser.getPowerDept().split(",");
Collections.addAll(powerDeptList, origPowerDepts);
}
powerDeptList.add(userDto.getDeptId());
powerDept = String.join(",", powerDeptList);
}
return powerDept;
}
}

@ -5,19 +5,27 @@ import cn.hutool.core.util.ObjectUtil;
import com.docus.core.util.DateUtil;
import com.docus.core.util.Func;
import com.docus.infrastructure.core.exception.BaseException;
import com.docus.infrastructure.core.utils.SpringUtil;
import com.docus.infrastructure.redis.service.IdService;
import com.docus.server.collection.dto.BedDoctorDto;
import com.docus.server.collection.dto.TBasicDto;
import com.docus.server.collection.entity.TBasic;
import com.docus.server.collection.entity.TBasicExtend;
import com.docus.server.collection.mapper.TBasicMapper;
import com.docus.server.collection.service.ITBasicService;
import com.docus.server.collection.util.BackPushEventEntity;
import com.docus.server.report.entity.MaternalInfantRelationship;
import com.docus.server.rpc.SdRyHospitalRpc;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@ -45,56 +53,64 @@ public class TBasicServiceImpl implements ITBasicService {
@Resource
private ThreadPoolExecutor threadPoolExecutor;
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@Override
@Transactional
public void setTBasic(TBasicDto tBasicDto) throws Exception {
//判断jzh是否重复
Integer num = tBasicMapper.selectOne(tBasicDto.getJzh());
if (num>0) {
if (num > 0) {
updateTBasic(tBasicDto);
return;
}
Long patientId = idService.getDateSeq();
//数据类型转化,格式处理
Date admissDate=null;
if(Func.isNotEmpty(tBasicDto.getAdmissDate())){
Date admissDate = null;
if (Func.isNotEmpty(tBasicDto.getAdmissDate())) {
admissDate = Func.parseDate(tBasicDto.getAdmissDate(), DateUtil.PATTERN_DATETIME_MINI);
}
Date disDate=null;
if(Func.isNotEmpty(tBasicDto.getDisDate())){
Date disDate = null;
if (Func.isNotEmpty(tBasicDto.getDisDate())) {
disDate = Func.parseDate(tBasicDto.getDisDate(), DateUtil.PATTERN_DATETIME_MINI);
}
String admissTimesStr = tBasicDto.getAdmissTimes();
Integer admissTimes=null;
if(NumberUtil.isInteger(admissTimesStr)){
admissTimes=Integer.parseInt(admissTimesStr);
Integer admissTimes = null;
if (NumberUtil.isInteger(admissTimesStr)) {
admissTimes = Integer.parseInt(admissTimesStr);
}
String ageStr = tBasicDto.getAge();
if(Func.isNotEmpty(ageStr)){
ageStr =ageStr.substring(0,ageStr.length()-1);
if (Func.isNotEmpty(ageStr)) {
ageStr = ageStr.substring(0, ageStr.length() - 1);
}
Integer age=null;
if(NumberUtil.isInteger(ageStr)){
age=Integer.parseInt(ageStr);
Integer age = null;
if (NumberUtil.isInteger(ageStr)) {
age = Integer.parseInt(ageStr);
}
String sexName=tBasicDto.getSexName();
if(Func.isNotEmpty(sexName)&&sexName.length()>1){
sexName=sexName.substring(0,1);
String sexName = tBasicDto.getSexName();
if (Func.isNotEmpty(sexName) && sexName.length() > 1) {
sexName = sexName.substring(0, 1);
}
String admissDaysStr = tBasicDto.getAdmissDays();
Integer admissDays=null;
if(NumberUtil.isInteger(admissDaysStr)){
admissDays=Integer.parseInt(admissDaysStr);
Integer admissDays = null;
if (NumberUtil.isInteger(admissDaysStr)) {
admissDays = Integer.parseInt(admissDaysStr);
}
String isDeadStr = tBasicDto.getIsDead();
Integer isDead=0;
if("死亡".equals(isDeadStr)){
isDead=1;
Integer isDead = 0;
if ("告死亡".equals(isDeadStr)) {
isDead = 1;
}
String leaveMethodStr = tBasicDto.getLeaveMethod();
Integer leaveMethod = null;
if (ObjectUtil.isNotEmpty(leaveMethodStr)&&NumberUtil.isInteger(leaveMethodStr)) {
leaveMethod=Integer.parseInt(leaveMethodStr);
}
//组装数据
TBasic tBasic=new TBasic();
TBasic tBasic = new TBasic();
tBasic.setPatientId(patientId.toString());
tBasic.setJzh(tBasicDto.getJzh());
tBasic.setInpatientNo(tBasicDto.getInpatientNo());
@ -120,22 +136,23 @@ public class TBasicServiceImpl implements ITBasicService {
//设置是否婴儿
String inpatientNo = tBasicDto.getInpatientNo();
if(inpatientNo.contains("B")||inpatientNo.contains("b")){
if (inpatientNo.contains("B") || inpatientNo.contains("b")) {
tBasic.setIsOther(1);
}else{
} else {
tBasic.setIsOther(0);
}
TBasicExtend tBasicExtend=new TBasicExtend();
String sdryIndex = tBasicDto.getSdryIndex();
TBasicExtend tBasicExtend = new TBasicExtend();
tBasicExtend.setPatientId(patientId.toString());
tBasicExtend.setWardCode(tBasicDto.getWardCode());
tBasicExtend.setWardName(tBasicDto.getWardName());
tBasicExtend.setSdryIndex(tBasicDto.getSdryIndex());
tBasicExtend.setSdryIndex(sdryIndex == null ? null : sdryIndex.replace("z", "").replace("m", ""));
tBasicExtend.setLeaveMethod(leaveMethod);
//持久化
tBasicMapper.insert(tBasic);
tBasicMapper.insertExtend(tBasicExtend);
confirmAndUpdIcuRecordState(tBasic.getInpatientNo(),tBasic.getAdmissTimes());
confirmAndUpdIcuRecordState(tBasic.getInpatientNo(), tBasic.getAdmissTimes());
}
@ -149,44 +166,48 @@ public class TBasicServiceImpl implements ITBasicService {
return;
}
//数据类型转化,格式处理
Date admissDate=null;
if(Func.isNotEmpty(tBasicDto.getAdmissDate())){
Date admissDate = null;
if (Func.isNotEmpty(tBasicDto.getAdmissDate())) {
admissDate = Func.parseDate(tBasicDto.getAdmissDate(), DateUtil.PATTERN_DATETIME_MINI);
}
Date disDate=null;
if(Func.isNotEmpty(tBasicDto.getDisDate())){
Date disDate = null;
if (Func.isNotEmpty(tBasicDto.getDisDate())) {
disDate = Func.parseDate(tBasicDto.getDisDate(), DateUtil.PATTERN_DATETIME_MINI);
}
String admissTimesStr = tBasicDto.getAdmissTimes();
Integer admissTimes=null;
if(NumberUtil.isInteger(admissTimesStr)){
admissTimes=Integer.parseInt(admissTimesStr);
Integer admissTimes = null;
if (NumberUtil.isInteger(admissTimesStr)) {
admissTimes = Integer.parseInt(admissTimesStr);
}
String ageStr = tBasicDto.getAge();
if(Func.isNotEmpty(ageStr)){
ageStr =ageStr.substring(0,ageStr.length()-1);
if (Func.isNotEmpty(ageStr)) {
ageStr = ageStr.substring(0, ageStr.length() - 1);
}
Integer age=null;
if(NumberUtil.isInteger(ageStr)){
age=Integer.parseInt(ageStr);
Integer age = null;
if (NumberUtil.isInteger(ageStr)) {
age = Integer.parseInt(ageStr);
}
String sexName=tBasicDto.getSexName();
if(Func.isNotEmpty(sexName)&&sexName.length()>1){
sexName=sexName.substring(0,1);
String sexName = tBasicDto.getSexName();
if (Func.isNotEmpty(sexName) && sexName.length() > 1) {
sexName = sexName.substring(0, 1);
}
String admissDaysStr = tBasicDto.getAdmissDays();
Integer admissDays=null;
if(NumberUtil.isInteger(admissDaysStr)){
admissDays=Integer.parseInt(admissDaysStr);
Integer admissDays = null;
if (NumberUtil.isInteger(admissDaysStr)) {
admissDays = Integer.parseInt(admissDaysStr);
}
String isDeadStr = tBasicDto.getIsDead();
Integer isDead=0;
if("死亡".equals(isDeadStr)){
isDead=1;
Integer isDead = 0;
if ("死亡".equals(isDeadStr)||"告死亡".equals(isDeadStr)) {
isDead = 1;
}
String leaveMethodStr = tBasicDto.getLeaveMethod();
Integer leaveMethod = null;
if (ObjectUtil.isNotEmpty(leaveMethodStr)&&NumberUtil.isInteger(leaveMethodStr)) {
leaveMethod=Integer.parseInt(leaveMethodStr);
}
//组装数据
TBasic tBasic=new TBasic();
TBasic tBasic = new TBasic();
tBasic.setJzh(tBasicDto.getJzh());
tBasic.setPatientId(patientId);
@ -213,23 +234,113 @@ public class TBasicServiceImpl implements ITBasicService {
tBasic.setIsOther(tBasicDto.getIsOther());
//设置是否婴儿
String inpatientNo = tBasicDto.getInpatientNo();
if(tBasic.getIsOther()==0&&(inpatientNo.contains("B")||inpatientNo.contains("b"))){
if (tBasic.getIsOther() == 0 && (inpatientNo.contains("B") || inpatientNo.contains("b"))) {
tBasic.setIsOther(1);
}else if(tBasic.getIsOther()==0){
} else if (tBasic.getIsOther() == 0) {
tBasic.setIsOther(0);
}
String sdryIndex = tBasicDto.getSdryIndex();
TBasicExtend tBasicExtend = new TBasicExtend();
tBasicExtend.setPatientId(patientId);
tBasicExtend.setWardCode(tBasicDto.getWardCode());
tBasicExtend.setWardName(tBasicDto.getWardName());
tBasicExtend.setSdryIndex(sdryIndex == null ? null : sdryIndex.replace("z", "").replace("m",""));
tBasicExtend.setSdryIndex(sdryIndex == null ? null : sdryIndex.replace("z", "").replace("m", ""));
tBasicExtend.setLeaveMethod(leaveMethod);
//持久化
tBasicMapper.update(tBasic);
tBasicMapper.updateExtend(tBasicExtend);
confirmAndUpdIcuRecordState(tBasic.getInpatientNo(),tBasic.getAdmissTimes());
confirmAndUpdIcuRecordState(tBasic.getInpatientNo(), tBasic.getAdmissTimes());
}
@Override
public void cancelHospital(TBasicDto tBasicDto) throws Exception {
//判断jzh是否存在
String patientId = tBasicMapper.getPatientId(tBasicDto.getJzh());
if (Func.isEmpty(patientId)) {
throw new BaseException("取消住院出错 jzh:"+tBasicDto.getJzh()+"不存在记录");
}
//数据类型转化,格式处理
//数据类型转化,格式处理
Date admissDate = null;
if (Func.isNotEmpty(tBasicDto.getAdmissDate())) {
admissDate = Func.parseDate(tBasicDto.getAdmissDate(), DateUtil.PATTERN_DATETIME_MINI);
}
Date disDate = null;
if (Func.isNotEmpty(tBasicDto.getDisDate())) {
disDate = Func.parseDate(tBasicDto.getDisDate(), DateUtil.PATTERN_DATETIME_MINI);
}
String admissTimesStr = tBasicDto.getAdmissTimes();
Integer admissTimes = null;
if (NumberUtil.isInteger(admissTimesStr)) {
admissTimes = Integer.parseInt(admissTimesStr);
}
String ageStr = tBasicDto.getAge();
if (Func.isNotEmpty(ageStr)) {
ageStr = ageStr.substring(0, ageStr.length() - 1);
}
Integer age = null;
if (NumberUtil.isInteger(ageStr)) {
age = Integer.parseInt(ageStr);
}
String sexName = tBasicDto.getSexName();
if (Func.isNotEmpty(sexName) && sexName.length() > 1) {
sexName = sexName.substring(0, 1);
}
String admissDaysStr = tBasicDto.getAdmissDays();
Integer admissDays = null;
if (NumberUtil.isInteger(admissDaysStr)) {
admissDays = Integer.parseInt(admissDaysStr);
}
String isDeadStr = tBasicDto.getIsDead();
Integer isDead = 0;
if ("死亡".equals(isDeadStr)) {
isDead = 1;
}
//组装数据
TBasic tBasic = new TBasic();
tBasic.setJzh(tBasicDto.getJzh());
tBasic.setPatientId(patientId);
tBasic.setInpatientNo(tBasicDto.getInpatientNo());
tBasic.setAdmissTimes(admissTimes);
tBasic.setName(tBasicDto.getName());
tBasic.setAdmissDate(admissDate);
tBasic.setDisDate(disDate);
tBasic.setAdmissDept(tBasicDto.getAdmissDept());
tBasic.setAdmissDeptName(tBasicDto.getAdmissDeptName());
tBasic.setDisDeptName(tBasicDto.getDisDeptName());
tBasic.setAttending(tBasicDto.getAttending());
tBasic.setAttendingName(tBasicDto.getAttendingName());
tBasic.setAge(age);
tBasic.setSex(tBasicDto.getSex());
tBasic.setIdCard(tBasicDto.getIdCard());
tBasic.setDisDept(tBasicDto.getDisDept());
tBasic.setSexName(sexName);
tBasic.setBedNum(tBasicDto.getBedNum());
tBasic.setAdmissDays(admissDays);
tBasic.setIsDead(isDead);
tBasic.setWardCode(tBasicDto.getWardCode());
tBasic.setWardName(tBasicDto.getWardName());
tBasic.setIsOther(tBasicDto.getIsOther());
//设置是否婴儿
String inpatientNo = tBasicDto.getInpatientNo();
if (tBasic.getIsOther() == 0 && (inpatientNo.contains("B") || inpatientNo.contains("b"))) {
tBasic.setIsOther(1);
} else if (tBasic.getIsOther() == 0) {
tBasic.setIsOther(0);
}
//是否取消住院
if ("2".equals(tBasicDto.getStatu())) {
applicationEventPublisher.publishEvent(new BackPushEventEntity(this, tBasic));
tBasic.setDisDate(null);
//持久化
tBasicMapper.cancelHospital(tBasic);
return;
}
throw new BaseException("未取消住院,状态 statusCode"+tBasicDto.getStatu());
}
@Override
@ -240,50 +351,51 @@ public class TBasicServiceImpl implements ITBasicService {
if (Func.isEmpty(patientId)) {
throw new BaseException("数据不存在,更新失败");
}
if("2".equals(tBasicDto.getStatu())){
if ("2".equals(tBasicDto.getStatu())) {
tBasicMapper.deleteByPatientId(patientId);
log.info("入院信息删除jzh:{},patientId:{},statusCode:{}",tBasicDto.getJzh(),patientId,tBasicDto.getStatu());
tBasicMapper.deleteExtend(patientId);
log.info("入院信息删除jzh:{},patientId:{},statusCode:{}", tBasicDto.getJzh(), patientId, tBasicDto.getStatu());
return;
}
//数据类型转化,格式处理
Date admissDate=null;
if(Func.isNotEmpty(tBasicDto.getAdmissDate())){
Date admissDate = null;
if (Func.isNotEmpty(tBasicDto.getAdmissDate())) {
admissDate = Func.parseDate(tBasicDto.getAdmissDate(), DateUtil.PATTERN_DATETIME_MINI);
}
Date disDate=null;
if(Func.isNotEmpty(tBasicDto.getDisDate())){
Date disDate = null;
if (Func.isNotEmpty(tBasicDto.getDisDate())) {
disDate = Func.parseDate(tBasicDto.getDisDate(), DateUtil.PATTERN_DATETIME_MINI);
}
String admissTimesStr = tBasicDto.getAdmissTimes();
Integer admissTimes=null;
if(NumberUtil.isInteger(admissTimesStr)){
admissTimes=Integer.parseInt(admissTimesStr);
Integer admissTimes = null;
if (NumberUtil.isInteger(admissTimesStr)) {
admissTimes = Integer.parseInt(admissTimesStr);
}
String ageStr = tBasicDto.getAge();
if(Func.isNotEmpty(ageStr)){
ageStr =ageStr.substring(0,ageStr.length()-1);
if (Func.isNotEmpty(ageStr)) {
ageStr = ageStr.substring(0, ageStr.length() - 1);
}
Integer age=null;
if(NumberUtil.isInteger(ageStr)){
age=Integer.parseInt(ageStr);
Integer age = null;
if (NumberUtil.isInteger(ageStr)) {
age = Integer.parseInt(ageStr);
}
String sexName=tBasicDto.getSexName();
if(Func.isNotEmpty(sexName)&&sexName.length()>1){
sexName=sexName.substring(0,1);
String sexName = tBasicDto.getSexName();
if (Func.isNotEmpty(sexName) && sexName.length() > 1) {
sexName = sexName.substring(0, 1);
}
String admissDaysStr = tBasicDto.getAdmissDays();
Integer admissDays=null;
if(NumberUtil.isInteger(admissDaysStr)){
admissDays=Integer.parseInt(admissDaysStr);
Integer admissDays = null;
if (NumberUtil.isInteger(admissDaysStr)) {
admissDays = Integer.parseInt(admissDaysStr);
}
String isDeadStr = tBasicDto.getIsDead();
Integer isDead=0;
if("死亡".equals(isDeadStr)){
isDead=1;
Integer isDead = 0;
if ("死亡".equals(isDeadStr)) {
isDead = 1;
}
//组装数据
TBasic tBasic=new TBasic();
TBasic tBasic = new TBasic();
tBasic.setJzh(tBasicDto.getJzh());
tBasic.setPatientId(patientId);
@ -310,40 +422,69 @@ public class TBasicServiceImpl implements ITBasicService {
tBasic.setIsOther(tBasicDto.getIsOther());
//设置是否婴儿
String inpatientNo = tBasicDto.getInpatientNo();
if(tBasic.getIsOther()==0&&(inpatientNo.contains("B")||inpatientNo.contains("b"))){
if (tBasic.getIsOther() == 0 && (inpatientNo.contains("B") || inpatientNo.contains("b"))) {
tBasic.setIsOther(1);
}else if(tBasic.getIsOther()==0){
} else if (tBasic.getIsOther() == 0) {
tBasic.setIsOther(0);
}
String sdryIndex = tBasicDto.getSdryIndex();
TBasicExtend tBasicExtend=new TBasicExtend();
TBasicExtend tBasicExtend = new TBasicExtend();
tBasicExtend.setPatientId(patientId);
tBasicExtend.setWardCode(tBasicDto.getWardCode());
tBasicExtend.setWardName(tBasicDto.getWardName());
tBasicExtend.setSdryIndex(sdryIndex==null?null:sdryIndex.replace("z","").replace("m",""));
tBasicExtend.setSdryIndex(sdryIndex == null ? null : sdryIndex.replace("z", "").replace("m", ""));
//持久化
tBasicMapper.update(tBasic);
tBasicMapper.updateExtend(tBasicExtend);
confirmAndUpdIcuRecordState(tBasic.getInpatientNo(),tBasic.getAdmissTimes());
confirmAndUpdIcuRecordState(tBasic.getInpatientNo(), tBasic.getAdmissTimes());
}
@Override
public void setBedDoctor(BedDoctorDto dto) throws Exception {
String inpatientNo = dto.getInpatientNo();
Integer admissTimes = dto.getAdmissTimes();
String bedDoctor = dto.getBedDoctor();
String bedDoctorName = dto.getBedDoctorName();
if(Func.isEmpty(inpatientNo)){
throw new BaseException("病案号为空,更新失败");
}
if(Func.isEmpty(admissTimes)){
throw new BaseException("住院次数为空,更新失败");
}
if(Func.isEmpty(bedDoctor)){
throw new BaseException("管床医生工号为空,更新失败");
}
if(Func.isEmpty(bedDoctorName)){
throw new BaseException("管床医生姓名为空,更新失败");
}
//判断病案是否存在
List<String> patientIds = tBasicMapper.getPatientIds(inpatientNo,admissTimes);
if (Func.isEmpty(patientIds)) {
throw new BaseException("数据不存在,更新失败");
}
tBasicMapper.setBedDoctor(patientIds,bedDoctor,bedDoctorName);
log.info("主键{}管床医生更新成功",patientIds.toString());
}
@Override
public TBasic getSdRyParentPatientInfo(String babyPatientId) {
// 宝宝索引
String babyIndex=tBasicMapper.getSdRyIndex(babyPatientId);
if (Func.isBlank(babyIndex)){
String babyIndex = tBasicMapper.getSdRyIndex(babyPatientId);
if (Func.isBlank(babyIndex)) {
return null;
}
// 宝宝索引查妈妈索引
String parentSdRyIndex= tBasicMapper.getParentSdRyIndex(babyIndex);
if(Func.isBlank(parentSdRyIndex)){
// 宝宝索引查妈妈索引 和住院次数
MaternalInfantRelationship infantRelationship = tBasicMapper.getMaternalInfantRelationship(babyIndex);
if (Objects.isNull(infantRelationship) || Func.isBlank(infantRelationship.getMomId())) {
return null;
}
// 通过索引查病案主键
String parentPatientId=tBasicMapper.getPatientIdBySdRyIndex(parentSdRyIndex);
if(Func.isBlank(parentPatientId)){
String parentSdRyIndex = infantRelationship.getMomId();
// 通过索引和住院次数查病案主键
String parentPatientId = tBasicMapper.getPatientIdBySdRyIndexAndAdmissTimes(parentSdRyIndex, infantRelationship.getParentTimes());
if (Func.isBlank(parentPatientId)) {
return null;
}
// 通过病案主键查基础信息
@ -352,20 +493,53 @@ public class TBasicServiceImpl implements ITBasicService {
@Override
public boolean getIsBabyBasic(String patientId) {
TBasic tBasic= tBasicMapper.getByPatientId(patientId);
TBasic tBasic = tBasicMapper.getByPatientId(patientId);
return Func.isNotEmpty(tBasic) && Func.isNotBlank(tBasic.getInpatientNo()) && tBasic.getInpatientNo().toUpperCase().contains("B");
}
@Override
public Integer matchingAdmissTimesByInpNoAndReportTime(String inpatientNo, Date reportDate, long timeRangeAddedHour) {
List<TBasic> basicList = tBasicMapper.selectBasicListByInpNo(inpatientNo);
if (Func.isEmpty(basicList)) {
log.warn("住院号:{} 未查询到患者基础数据!", inpatientNo);
return null;
}
// 转换毫秒范围进行比较运算
long timeRangeAddedMillis = timeRangeAddedHour * 60 * 60 * 1000;
long reportDateTimeMillis = reportDate.getTime();
for (TBasic basic : basicList) {
Date admissDate = basic.getAdmissDate();
Date disDate = basic.getDisDate();
if (Objects.isNull(admissDate)) {
log.warn("住院号:{} 有入院时间为空的基础数据!", inpatientNo);
continue;
}
// 入院时间大于报告时间,不匹配
if (admissDate.getTime() > reportDateTimeMillis) {
continue;
}
// 报告时间大于等于入院时间,出院时间为空或者 报告时间小于等于出院时间+时间范围差,则匹配该条数据
if (Objects.isNull(disDate) || reportDateTimeMillis <= (disDate.getTime() + timeRangeAddedMillis)) {
if (Objects.isNull(basic.getAdmissTimes())) {
log.warn("住院号:{} ,报告时间:{},范围添加 {} 小时匹配患者数据patientId为{},但是住院次数为空!", inpatientNo, Func.formatDateTime(reportDate), timeRangeAddedHour, basic.getPatientId());
}
return basic.getAdmissTimes();
}
}
log.warn("住院号:{},报告时间:{},范围添加 {} 小时,未匹配到患者基础数据具体住院次数!", inpatientNo, Func.formatDateTime(reportDate), timeRangeAddedHour);
return null;
}
public void confirmAndUpdIcuRecordState(String inpatientNo,Integer admissTimes){
threadPoolExecutor.execute(()->{
public void confirmAndUpdIcuRecordState(String inpatientNo, Integer admissTimes) {
threadPoolExecutor.execute(() -> {
// 此处异步,睡眠一秒保证事务提交
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
sdRyHospitalRpc.confirmAndUpdIcuRecordState(inpatientNo,admissTimes);
sdRyHospitalRpc.confirmAndUpdIcuRecordState(inpatientNo, admissTimes);
});
}
}

@ -0,0 +1,28 @@
package com.docus.server.collection.util;
import com.docus.server.collection.entity.TBasic;
import org.springframework.context.ApplicationEvent;
/**
* @description 退event
* @author chierhao
* @date 2023-02-14 15:12
*/
public class BackPushEventEntity extends ApplicationEvent{
private static final long serialVersionUID = 1L;
private TBasic tBasic ;
public BackPushEventEntity(Object source, TBasic tBasic ) {
super(source);
this.tBasic = tBasic;
}
public TBasic getTBasic() {
return tBasic;
}
public void setTBasic( TBasic tBasic ) {
this.tBasic = tBasic;
}
}

@ -0,0 +1,99 @@
package com.docus.server.collection.util;
import com.docus.core.util.DateUtil;
import com.docus.server.collection.dto.BacklPushDto;
import java.util.Date;
import java.util.UUID;
/**
* @BelongsProject: docus_medicalrecord_starter
* @BelongsPackage: com.docus.services.statistical.util
* @Author: jiashi
* @CreateTime: 2022-12-27 15:33
* @Description: TODO
* @Version: 1.0
*/
public class BackPushUtil {
/**
* @description xml
* @author jiashi
* @date 2023-07-12 14:14
* @param dto
* @return: java.lang.String
*/
public static String getXml(BacklPushDto dto) {
String result=
"<PRPA_HIP1265 xmlns=\"urn:hl7-org:v3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ITSVersion=\"XML_1.0\" xsi:schemaLocation=\"urn:hl7-org:v3\">\n" +
"\t<!--id-消息流水号 UUID -->\n" +
"\t<id extension=\""+ UUID.randomUUID()+"\"/>\n" +
"\t<!--creationTime-消息创建时间 -->\n" +
"\t<creationTime value=\""+ DateUtil.format(new Date(),DateUtil.PATTERN_DATETIME_MINI)+"\"/>\n" +
"\t<!--interactionId-消息的服务标识 -->\n" +
"\t<interactionId root=\"2.16.840.1.113883.1.6\" extension=\"PRPA_HIP1265\"/>\n" +
"\t<!--processingCode-处理代码。标识此消息是否是产品、训练、调试系统的一部分。D调试P产品T训练 -->\n" +
"\t<processingCode code=\"P\"/>\n" +
"\t<!-- processingModeCode-处理模型代码。定义此消息是一个文档处理还是一个初始装载的一部分。A 存档I初始装载R从存档中恢复T当前处理间隔传递。 -->\n" +
"\t<processingModeCode/>\n" +
"\t<!-- acceptAckCode-接收确认类型 AL总是确认NE从不确认ER仅在错误/或拒绝时确认SU 仅在成功完成时确认。 -->\n" +
"\t<acceptAckCode code=\"AL\"/>\n" +
"\t<receiver typeCode=\"RCV\">\n" +
"\t\t<device classCode=\"DEV\" determinerCode=\"INSTANCE\">\n" +
"\t\t\t<id>\n" +
"\t\t\t\t<!-- 接收方编号请向集成平台提供商获取 -->\n" +
"\t\t\t\t<item extension=\"Orion-001\"/>\n" +
"\t\t\t</id>\n" +
"\t\t</device>\n" +
"\t</receiver>\n" +
"\t<sender typeCode=\"SND\">\n" +
"\t\t<device classCode=\"DEV\" determinerCode=\"INSTANCE\">\n" +
"\t\t\t<id>\n" +
"\t\t\t\t<!-- 发送方编号请向集成平台提供商获取 -->\n" +
"\t\t\t\t<item extension=\"PaperlessManagementMRIS-001\"/>\n" +
"\t\t\t</id>\n" +
"\t\t</device>\n" +
"\t</sender>\n" +
"\t<controlActProcess classCode=\"STC\" moodCode=\"EVN\">\n" +
"\t\t<code code=\"InpatientEncounterStarted\">\n" +
"\t\t\t<displayName value=\"归档解档服务\"/>\n" +
"\t\t</code>\n" +
"\t\t<!--\t归档/解档ID\t-->\n" +
"\t\t<archiveId value=\""+UUID.randomUUID()+"\"/>\n" +
"\t\t<!--\t住院号\t-->\n" +
"\t\t<inHospIndexNo value=\""+dto.getInpatientNo()+"\"/>\n" +
"\t\t<!--\t住院次数\t-->\n" +
"\t\t<visitNo value=\""+dto.getAdmissTimes()+"\"/>\n" +
"\t\t<!--\t住院就诊流水号\t-->\n" +
"\t\t<inHospNo value=\""+dto.getJzh()+"\"/>\n" +
"\t\t<!--\t姓名\t-->\n" +
"\t\t<patientName value=\""+dto.getName()+"\"/>\n" +
"\t\t<!--\t出院科室代码\t-->\n" +
"\t\t<dischargeDeptCode value=\""+dto.getDisDept()+"\"/>\n" +
"\t\t<!--\t出院科室\t-->\n" +
"\t\t<dischargeDeptName value=\""+dto.getDisDeptName()+"\"/>\n" +
"\t\t<!--\t申请人工号\t-->\n" +
"\t\t<applicantCode value=\""+dto.getApplyUserName()+"\"/>\n" +
"\t\t<!--\t申请人\t-->\n" +
"\t\t<applicantName value=\""+dto.getApplyName()+"\"/>\n" +
"\t\t<!--\t操作人工号\t-->\n" +
"\t\t<operatorCode value=\""+dto.getControlUserName()+"\"/>\n" +
"\t\t<!--\t操作人\t-->\n" +
"\t\t<operatorName value=\""+dto.getControlName()+"\"/>\n" +
"\t\t<!--\t解档时间根据天数从当前时间后推\t-->\n" +
"\t\t<unarchiveTime value=\""+dto.getAuditTime()+"\"/>\n" +
"\t\t<!--\t解档天数\t-->\n" +
"\t\t<unarchiveDays value=\""+dto.getDay()+"\"/>\n" +
"\t\t<!--\t解档\\归档状态 0:解档 1:归档\t-->\n" +
"\t\t<archiveState value=\""+dto.getIsArchive()+"\"/>\n" +
"\t\t<!--\t解档\\归档文书类型 0:电子病历1:护理\t-->\n" +
"\t\t<archiveType value=\""+dto.getCollectIds()+"\"/>\n" +
"\t\t<!--\t医院信息 code是医院代码 value是医院名称\t-->\n" +
"\t\t<hospInfo code=\"4560886379\" value=\"南方医科大学顺德医院\"/>\n" +
"\t</controlActProcess>\n" +
"</PRPA_HIP1265>";
return result;
}
}

@ -0,0 +1,216 @@
package com.docus.server.collection.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.docus.core.util.DateUtil;
import com.docus.core.util.Func;
import com.docus.infrastructure.core.exception.BaseException;
import com.docus.server.collection.dto.BacklPushDto;
import com.docus.server.collection.entity.CqcPushConfig;
import com.docus.server.collection.entity.TBasic;
import com.docus.server.collection.mapper.CqcPushConfigMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.axis.encoding.XMLType;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import java.util.*;
import java.util.stream.Collectors;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
/**
* @author chierhao
* @description 退
* @date 2023-02-14 14:38
*/
@Component
@Slf4j
@Async
public class CqcPushListenerUtil {
@Autowired
private CqcPushConfigMapper cqcPushConfigMapper;
@Value("${docus.basic.pushconfig:}")
private String pushConfigId;
@Value("${docus.basic.pushusername:}")
private String userName;
@Value("${docus.basic.pushname:}")
private String name;
@Value("${docus.basic.day:}")
private String day;
/*
* @description 退
* @author jiashi
* @date 2023-07-13 15:20
* @param event
*/
@Async
@EventListener
public void backPushListener(BackPushEventEntity event) {
TBasic tBasic= event.getTBasic();
String[] split = pushConfigId.split(",");
List<Long> ids=new ArrayList<>();
for(String str:split){
long l = Long.parseLong(str);
ids.add(l);
}
if(Func.isEmpty(ids)){
log.info("推送配置id为空");
return;
}
List<CqcPushConfig> configs = cqcPushConfigMapper.getCqcPushConfigByBusinessTypes(ids);
if(Func.isEmpty(configs)){
log.info("推送配置查询为空");
return;
}
for(CqcPushConfig config:configs){
//顺德人医解档推送
liberationMethod(tBasic,config);
}
}
/**
* @description webservice
* @author jiashi
* @date 2023-07-12 10:51
* @param cqcPushConfig
*/
public void liberationMethod(TBasic tBasic, CqcPushConfig cqcPushConfig) {
//解档推送消息
if (Func.isNotEmpty(tBasic)) {
String archiveType = "";
if (cqcPushConfig.getBusinessType().equals("8")) {
archiveType = "0";
}
if (cqcPushConfig.getBusinessType().equals("9")) {
archiveType = "1";
}
if (cqcPushConfig.getBusinessType().equals("12")) {
archiveType = "2";
}
//组装参数
BacklPushDto dto = new BacklPushDto();
dto.setPatientId(tBasic.getPatientId());
dto.setInpatientNo(tBasic.getInpatientNo());
dto.setAdmissTimes(tBasic.getAdmissTimes());
dto.setJzh(tBasic.getInpatientNo() + "_" + tBasic.getAdmissTimes());
dto.setName(tBasic.getName());
dto.setDisDept(tBasic.getDisDept());
dto.setDisDeptName(tBasic.getDisDeptName());
dto.setApplyUserName(userName);
dto.setApplyName(name);
dto.setControlUserName(userName);
dto.setControlName(name);
dto.setAuditTime(DateUtil.format(new Date(), DateUtil.PATTERN_DATETIME));
dto.setDay(day);
dto.setIsArchive(0);
dto.setCollectIds(archiveType);
String wsParam = BackPushUtil.getXml(dto);
//发送消息
//请求地址
String wsUrl = cqcPushConfig.getUrl();
//命名空间
String namespance = cqcPushConfig.getNamespace();
// 推送方法名
String wsMethod = cqcPushConfig.getMethod();
//参数
String parameterListStr = cqcPushConfig.getParameterList();
parameterListStr = String.format(parameterListStr, JSON.toJSONString(wsParam));
List<Map<String, Object>> parameterList = new ArrayList<>();
parameterList = JSON.parseObject(parameterListStr, new TypeReference<List<Map<String, Object>>>() {
});
List<Object> parameters = parameterList.stream().map(e -> e.get("parameter")).collect(Collectors.toList());
log.info("推送入参: parameterList:{}", JSON.toJSONString(parameterList));
//回调值
String result = "";
for (int i = 0; i < 3; i++) {
try {
Thread.sleep(i * 5 * 100);
} catch (InterruptedException e) {
log.error(e.getMessage(), e);
}
if (wsUrl.contains("?wsdl")) {
result = requestFunctionWebServiceCXF(wsUrl, namespance, wsMethod, parameters);
} else {
result = requestFunctionWebService(wsUrl, namespance, wsMethod, parameterList);
}
log.info("得到的结果:" + result);
if (result.contains("成功") || result.contains("success")) {
break;
}
}
} else {
throw new BaseException("病案基础信息为空,推送消息失败");
}
}
/**
* @param url wsdl
* @param namespace
* @param method
*/
public String requestFunctionWebService(String url, String namespace, String method, List<Map<String,Object>> parameterList) {
String result = null;
try {
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(url);
call.setOperationName(new QName(namespace, method));
for (Map<String,Object> paramMap:parameterList){
call.addParameter((String) paramMap.get("parameterName"), XMLType.XSD_STRING, ParameterMode.IN);
}
List<Object> parameter = parameterList.stream().map(e -> e.get("parameter")).collect(Collectors.toList());
Object[] opAddEntryArgs = parameter.toArray();
call.setReturnType(XMLType.XSD_STRING);//设置返回类型
result = (String) call.invoke(opAddEntryArgs);
} catch (Exception e) {
log.error(e.getMessage(),e);
result = e.getMessage();
}
return result;
}
public String requestFunctionWebServiceCXF(String url, String namespace, String method, List<Object> params) {
String result;
try {
//创建动态客户端工厂 创建客户端
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient(url);
//命名空间和方法
QName name = new QName(namespace, method);
//调用,省中医ChasMessageServer方法特殊处理
Object[] opAddEntryArgs;
opAddEntryArgs = params.toArray();
Object[] objects = client.invoke(name, opAddEntryArgs);
result = objects[0].toString();
} catch (Exception e) {
log.error(e.getMessage(),e);
result = e.getMessage();
}
return result;
}
}

@ -23,4 +23,15 @@ public interface BasicService {
* @description
*/
public String updateAdmissTBasic(String message);
/**
* @description
*/
public String setBedDoctor(String message);
/**
* @description
*/
public String cancelHospital(String message);
}

@ -31,6 +31,12 @@ public interface ReceiveServer {
*/
public String updateAdmissTBasic(String message);
/**
* @description
*/
public String setBedDoctor(String message);
/**
*
*
@ -114,4 +120,18 @@ public interface ReceiveServer {
* @return
*/
String pushMaternalInfantRelationship(String maternalInfantRelationshipMessage);
/**
*
* /
* @param recallInspectionReportMessage /
* @return
*/
String pushRecallInspectionReport(String recallInspectionReportMessage);
/**
* @description
*/
String cancelHospital(String message);
}

@ -1,7 +1,9 @@
package com.docus.server.collection.webservice.impl;
import cn.hutool.core.util.NumberUtil;
import com.docus.core.util.Func;
import com.docus.core.util.ObjectUtil;
import com.docus.server.collection.dto.BedDoctorDto;
import com.docus.server.collection.dto.TBasicDto;
import com.docus.server.collection.service.ITBasicService;
import com.docus.server.collection.util.Result;
@ -71,6 +73,28 @@ public class BasicServiceImpl implements BasicService {
}
@Override
public String cancelHospital(String body) {
log.info("取消住院基础数据:{}", body);
if (Func.isEmpty(body)) {
return Result.failed(null,"参数为空",null,null);
}
//解析xml
TBasicDto tBasicDto = null;
try {
tBasicDto=getCancelHospitalDto(body);
//持久化
tBasicService.cancelHospital(tBasicDto);
}catch (Exception e){
e.printStackTrace();
log.error(e.getMessage(), e);
return Result.failed(tBasicDto.getSerialId(),e.getMessage(),tBasicDto.getReceive(),tBasicDto.getSend());
}
return Result.success(tBasicDto.getSerialId(),tBasicDto.getReceive(),tBasicDto.getSend());
}
@Override
public String setAdmissTBasic(String message) {
log.info("新增入院基础数据:{}", message);
@ -111,7 +135,26 @@ public class BasicServiceImpl implements BasicService {
return Result.failed(tBasicDto.getSerialId(),e.getMessage(),tBasicDto.getReceive(),tBasicDto.getSend());
}
return Result.success(tBasicDto.getSerialId(),tBasicDto.getReceive(),tBasicDto.getSend());
}
@Override
public String setBedDoctor(String message) {
log.info("设置管床医生数据:{}", message);
if (Func.isEmpty(message)) {
return Result.failed(null,"参数为空",null,null);
}
//解析xml
BedDoctorDto bedDoctorDto = null;
try {
bedDoctorDto=getBedDoctorDto(message);
//持久化
tBasicService.setBedDoctor(bedDoctorDto);
}catch (Exception e){
e.printStackTrace();
log.error(e.getMessage(), e);
return Result.failed(bedDoctorDto.getSerialId(),e.getMessage(),bedDoctorDto.getReceive(),bedDoctorDto.getSend());
}
return Result.success(bedDoctorDto.getSerialId(),bedDoctorDto.getReceive(),bedDoctorDto.getSend());
}
public TBasicDto getNewTBasicDto(String str) {
@ -178,7 +221,7 @@ public class BasicServiceImpl implements BasicService {
}
//出院诊断科室名称[]
String disDeptName=null;
Node disDeptNameNode = xml.getNode("/PRPA_HIP0032/controlActProcess/subject/encounterEvent/component[@displayName='出院诊断']/section/entry[@displayName='出院诊断-西医条目']/observation/performer/assignedEntity/representedOrganization/name");
Node disDeptNameNode = xml.getNode("/PRPA_HIP0032/controlActProcess/subject/encounterEvent/componentOf/encompassingEncounter/location/healthCareFacility/serviceProviderOrganization/asOrganizationPartOf/wholeOrganization/asOrganizationPartOf/wholeOrganization/asOrganizationPartOf/wholeOrganization/name");
if(Func.isNotEmpty(disDeptNameNode)){
disDeptName=disDeptNameNode.getTextContent();
}
@ -238,7 +281,7 @@ public class BasicServiceImpl implements BasicService {
}
//是否死亡[]
String isDead=null;
Node isDeadNode = xml.getNode("/PRPA_HIP0032/controlActProcess/subject/encounterEvent/component[@displayName='出院诊断']/section/entry[@displayName='出院情况']/observation/value");
Node isDeadNode = xml.getNode("/PRPA_HIP0032/controlActProcess/subject/encounterEvent/component[@displayName='出院诊断']/section/entry[@displayName='出院医嘱']/observation/value");
if(Func.isNotEmpty(isDeadNode)){
isDead=isDeadNode.getTextContent();
}
@ -260,6 +303,12 @@ public class BasicServiceImpl implements BasicService {
if(Func.isNotEmpty(sdryIndexNode)){
sdryIndex=sdryIndexNode.getNodeValue();
}
//顺德人医第三方索引
String leaveMethod=null;
Node leaveMethodNode = xml.getNode("/PRPA_HIP0032/controlActProcess/subject/encounterEvent/component[@displayName='出院诊断']/section/lhWay/@code");
if(Func.isNotEmpty(leaveMethodNode)){
leaveMethod=leaveMethodNode.getNodeValue();
}
//设置dto
TBasicDto dto=new TBasicDto();
@ -288,6 +337,7 @@ public class BasicServiceImpl implements BasicService {
dto.setWardName(wardName);
dto.setSdryIndex(sdryIndex);
dto.setIsOther(0);
dto.setLeaveMethod(leaveMethod);
return dto;
}
@ -438,6 +488,13 @@ public class BasicServiceImpl implements BasicService {
sdryIndex=sdryIndexNode.getNodeValue();
}
//出院状态
String statusCode=null;
Node statusCodeNode = xml.getNode("/PRPA_HIP0033/controlActProcess/subject/encounterEvent/statusCode/@code");
if(Func.isNotEmpty(statusCodeNode)){
statusCode=statusCodeNode.getNodeValue();
}
//设置dto
TBasicDto dto=new TBasicDto();
dto.setSerialId(serialId);
@ -465,9 +522,196 @@ public class BasicServiceImpl implements BasicService {
dto.setWardName(wardName);
dto.setSdryIndex(sdryIndex);
dto.setIsOther(0);
dto.setStatu(statusCode);
return dto;
}
public TBasicDto getCancelHospitalDto(String str) {
XmlUtil xml=XmlUtil.of(str);
//id-消息流水号
String serialId=null;
Node serialIdNode = xml.getNode("/PRPA_HIP1235/id/@extension");
if(Func.isNotEmpty(serialIdNode)){
serialId=serialIdNode.getNodeValue();
}
//接受方
String receive=null;
Node receiveNode = xml.getNode("/PRPA_HIP1235/receiver/device/id/item/@extension");
if(Func.isNotEmpty(receiveNode)){
receive=receiveNode.getNodeValue();
}
//发送方
String send=null;
Node sendNode = xml.getNode("/PRPA_HIP1235/sender/device/id/item/@extension");
if(Func.isNotEmpty(sendNode)){
send=sendNode.getNodeValue();
}
//住院流水号
String jzh=null;
Node jzhNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/item/@extension");
if(Func.isNotEmpty(jzhNode)){
jzh=jzhNode.getNodeValue();
}
//住院号标识
String inpatientNo=null;
Node inpatientNoNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/id/item/@extension");
if(Func.isNotEmpty(inpatientNoNode)){
inpatientNo=inpatientNoNode.getNodeValue();
}
//住院次数[]
String admissTimes=null;
Node admissTimesNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/lengthOfStayQuantity[@unit='次']/@value");
if(Func.isNotEmpty(admissTimesNode)){
admissTimes=admissTimesNode.getNodeValue();
}
//姓名
String name=null;
Node nameNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/subject/patient/patientPerson/name/item/part/@value");
if(Func.isNotEmpty(nameNode)){
name=nameNode.getNodeValue();
}
//入院日期时间
String admissDate=null;
Node admissDateNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/effectiveTime/low/@value");
if(Func.isNotEmpty(admissDateNode)){
admissDate=admissDateNode.getNodeValue();
}
//出院日期时间
String disDate=null;
Node disDateNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/effectiveTime/high/@value");
if(Func.isNotEmpty(disDateNode)){
disDate=disDateNode.getNodeValue();
}
//入院诊断科室名称[]
String admissDeptName=null;
Node admissDeptNameNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/component[@displayName='入院诊断']/section/entry[@displayName='入院诊断-西医条目']/observation/performer/assignedEntity/representedOrganization/name");
if(Func.isNotEmpty(admissDeptNameNode)){
admissDeptNameNode.getTextContent();
}
//出院诊断科室名称[]
String disDeptName=null;
Node disDeptNameNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/component[@displayName='出院诊断']/section/entry[@displayName='出院诊断-西医条目']/observation/performer/assignedEntity/representedOrganization/name");
if(Func.isNotEmpty(disDeptNameNode)){
disDeptName=disDeptNameNode.getTextContent();
}
//主治医师[]
String attending=null;
Node attendingNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/authenticator[@displayName='住院医师']/assignedEntity/id/@extension");
if(Func.isNotEmpty(attendingNode)){
attending=attendingNode.getTextContent();
}
//主治医师[]
String attendingName=null;
Node attendingNameNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/authenticator[@displayName='住院医师']/assignedEntity/assignedPerson/name");
if(Func.isNotEmpty(attendingNameNode)){
attendingName=attendingNameNode.getTextContent();
}
//年龄
String age=null;
Node ageNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/subject/patient/patientPerson/age[@unit='岁']/@value");
if(Func.isNotEmpty(ageNode)){
age=ageNode.getNodeValue();
}
//性别
String sex=null;
Node sexNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/subject/patient/patientPerson/administrativeGenderCode/@code");
if(Func.isNotEmpty(sexNode)){
sex=sexNode.getNodeValue();
}
//身份证号
String idCard=null;
Node idCardNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/subject/patient/patientPerson/id/item/@extension");
if(Func.isNotEmpty(idCardNode)){
idCard=idCardNode.getNodeValue();
}
//出院科室
String disDept=null;
Node disDeptCardNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/componentOf/encompassingEncounter/location/healthCareFacility/serviceProviderOrganization/asOrganizationPartOf/wholeOrganization/asOrganizationPartOf/wholeOrganization/asOrganizationPartOf/wholeOrganization/id/@extension");
if(Func.isNotEmpty(disDeptCardNode)){
disDept=disDeptCardNode.getNodeValue();
}
//性别名称
String sexName=null;
Node sexNameNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/subject/patient/patientPerson/administrativeGenderCode/@displayName");
if(Func.isNotEmpty(sexNameNode)){
sexName=sexNameNode.getNodeValue();
}
//床位号
String bedNum=null;
Node bedNumNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/componentOf/encompassingEncounter/location/healthCareFacility/serviceProviderOrganization/asOrganizationPartOf/wholeOrganization/id/@extension");
if(Func.isNotEmpty(bedNumNode)){
bedNum=bedNumNode.getNodeValue();
}
//住院天数数[]
String admissDays=null;
Node admissDaysNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/lengthOfStayQuantity[@unit='天']/@value");
if(Func.isNotEmpty(admissDaysNode)){
admissDays=admissDaysNode.getNodeValue();
}
//是否死亡[]
String isDead=null;
Node isDeadNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/component[@displayName='出院诊断']/section/entry[@displayName='出院情况']/observation/value");
if(Func.isNotEmpty(isDeadNode)){
isDead=isDeadNode.getTextContent();
}
//病区编号
String wardCode=null;
Node wardCodeNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/componentOf/encompassingEncounter/location/healthCareFacility/serviceProviderOrganization/asOrganizationPartOf/wholeOrganization/asOrganizationPartOf/wholeOrganization/asOrganizationPartOf/wholeOrganization/asOrganizationPartOf/wholeOrganization/id/@extension");
if(Func.isNotEmpty(wardCodeNode)){
wardCode=wardCodeNode.getNodeValue();
}
//病区名称
String wardName=null;
Node wardNameNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/componentOf/encompassingEncounter/location/healthCareFacility/serviceProviderOrganization/asOrganizationPartOf/wholeOrganization/asOrganizationPartOf/wholeOrganization/asOrganizationPartOf/wholeOrganization/asOrganizationPartOf/wholeOrganization/name");
if(Func.isNotEmpty(wardNameNode)){
wardName=wardNameNode.getTextContent();
}
//顺德人医第三方索引
String sdryIndex=null;
Node sdryIndexNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/subject/patient/id/item/@extension");
if(Func.isNotEmpty(sdryIndexNode)){
sdryIndex=sdryIndexNode.getNodeValue();
}
//出院状态
String statusCode=null;
Node statusCodeNode = xml.getNode("/PRPA_HIP1235/controlActProcess/subject/encounterEvent/statusCode/@code");
if(Func.isNotEmpty(statusCodeNode)){
statusCode=statusCodeNode.getNodeValue();
}
//设置dto
TBasicDto dto=new TBasicDto();
dto.setSerialId(serialId);
dto.setSend(send);
dto.setReceive(receive);
dto.setInpatientNo(inpatientNo);
dto.setName(name);
dto.setJzh(jzh);
dto.setAdmissDeptName(admissDeptName);
dto.setDisDeptName(disDeptName);
dto.setAdmissDate(admissDate);
dto.setDisDate(disDate);
dto.setAdmissTimes(admissTimes);
dto.setAttending(attending);
dto.setAttendingName(attendingName);
dto.setAge(age);
dto.setSex(sex);
dto.setIdCard(idCard);
dto.setDisDept(disDept);
dto.setSexName(sexName);
dto.setBedNum(bedNum);
dto.setIsDead(isDead);
dto.setAdmissDays(admissDays);
dto.setWardCode(wardCode);
dto.setWardName(wardName);
dto.setSdryIndex(sdryIndex);
dto.setIsOther(0);
dto.setStatu(statusCode);
return dto;
}
public TBasicDto getAdmissTBasicDto(String message) {
XmlUtil xml=XmlUtil.of(message);
//id-消息流水号
@ -514,7 +758,7 @@ public class BasicServiceImpl implements BasicService {
}
//入院日期时间
String admissDate=null;
Node admissDateNode = xml.getNode("/PRPA_HIP1070/controlActProcess/encounterEvent/effectiveTime/low/@value");
Node admissDateNode = xml.getNode("/PRPA_HIP1070/controlActProcess/subject/component[@displayName='入科章节']/location1/time/low/@value");
if(Func.isNotEmpty(admissDateNode)){
admissDate=admissDateNode.getNodeValue();
}
@ -765,6 +1009,64 @@ public class BasicServiceImpl implements BasicService {
}
return dto;
}
public BedDoctorDto getBedDoctorDto(String str) {
XmlUtil xml=XmlUtil.of(str);
//id-消息流水号
String serialId=null;
Node serialIdNode = xml.getNode("/PRPA_HIP1233/id/@extension");
if(Func.isNotEmpty(serialIdNode)){
serialId=serialIdNode.getNodeValue();
}
//接受方
String receive=null;
Node receiveNode = xml.getNode("/PRPA_HIP1233/receiver/device/id/item/@extension");
if(Func.isNotEmpty(receiveNode)){
receive=receiveNode.getNodeValue();
}
//发送方
String send=null;
Node sendNode = xml.getNode("/PRPA_HIP1233/sender/device/id/item/@extension");
if(Func.isNotEmpty(sendNode)){
send=sendNode.getNodeValue();
}
//病案号
String inpatientNo=null;
Node inpatientNoNode = xml.getNode("/PRPA_HIP1233/controlActProcess/ihNum/@value");
if(Func.isNotEmpty(inpatientNoNode)){
inpatientNo=inpatientNoNode.getNodeValue();
}
//住院次数
Integer admissTimes=null;
Node admissTimesNode = xml.getNode("/PRPA_HIP1233/controlActProcess/ihTimes/@value");
if(Func.isNotEmpty(admissTimesNode)){
String nodeValue = admissTimesNode.getNodeValue();
if(ObjectUtil.isNotEmpty(nodeValue)&&NumberUtil.isInteger(nodeValue)){
admissTimes=Integer.parseInt(nodeValue);
}
}
//管床医生工号
String bedDoctor=null;
Node bedDoctorNode = xml.getNode("/PRPA_HIP1233/controlActProcess/referPhysician/@code");
if(Func.isNotEmpty(bedDoctorNode)){
bedDoctor=bedDoctorNode.getNodeValue();
}
//管床医生姓名
String bedDoctorName=null;
Node bedDoctorNameNode = xml.getNode("/PRPA_HIP1233/controlActProcess/referPhysician/@value");
if(Func.isNotEmpty(bedDoctorNameNode)){
bedDoctorName=bedDoctorNameNode.getNodeValue();
}
//设置dto
BedDoctorDto dto=new BedDoctorDto();
dto.setSerialId(serialId);
dto.setSend(send);
dto.setReceive(receive);
dto.setInpatientNo(inpatientNo);
dto.setAdmissTimes(admissTimes);
dto.setBedDoctor(bedDoctor);
dto.setBedDoctorName(bedDoctorName);
return dto;
}
}

@ -56,6 +56,11 @@ public class ReceiveServerImpl implements ReceiveServer {
return basicService.updateAdmissTBasic(message) ;
}
@Override
public String setBedDoctor(String message) {
return basicService.setBedDoctor(message);
}
@Override
public String userModify(String receiveUser) {
return userServer.userModify(receiveUser);
@ -102,6 +107,15 @@ public class ReceiveServerImpl implements ReceiveServer {
public String pushMaternalInfantRelationship(String maternalInfantRelationshipMessage) {
return reportServer.pushMaternalInfantRelationship(maternalInfantRelationshipMessage);
}
@Override
public String pushRecallInspectionReport(String recallInspectionReportMessage) {
return reportServer.pushRecallInspectionReport(recallInspectionReportMessage);
}
@Override
public String cancelHospital(String message) {
return basicService.cancelHospital(message);
}
@Override
public String querySdJxIndexTest(String xml) {

@ -41,7 +41,7 @@ public class UserServerImpl implements IUserServer {
// 判断操作类型 是否是删除,或者 删除标记的
boolean isDel = (Func.isNotEmpty(operateType) && operateType.contains(delType)) || userDto.isDelFlag();
if (isDel) {
iPowerUserService.delUserByUserName(userDto.getUserName());
iPowerUserService.cancelUserByUserName(userDto.getUserName());
} else {
iPowerUserService.register(userDto);
}

@ -0,0 +1,84 @@
package com.docus.server.common.entity;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
*
*
* @author wyb
* @date 2023-10-13
*/
@Data
public class RemoteCallResult implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
/**
*
*/
private String keyword;
/**
*
*/
private String url;
/**
*
*/
private String header;
/**
*
*/
private String request;
/**
*
*/
private String response;
/**
*
*/
private String remark;
/**
*
*/
private String description;
/**
* 01
*/
private Integer requestStorageType;
/**
* 01
*/
private Integer responseStorageType;
/**
* 123
*/
private Integer callStatus;
/**
*
*/
private Date callStartTime;
/**
*
*/
private Date callEndTime;
public RemoteCallResult() {
}
}

@ -0,0 +1,63 @@
package com.docus.server.common.entity;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* pacsbase64
* @author wyb
* @date 2023-10-17
*/
@Data
public class SdryPacsPrintExcept implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
/**
*
*/
private String inpatientNo;
/**
*
*/
private Integer admissTimes;
/**
* /
*/
private String jzh;
/**
*
*/
private String reportMessagePath;
/**
* 1
*/
private Integer state;
/**
*
*/
private Date createTime;
/**
*
*/
private String examReportSn;
/**
* 10081009
*/
private String serviceFlag;
public SdryPacsPrintExcept() {}
}

@ -0,0 +1,18 @@
package com.docus.server.common.mapper;
import com.docus.server.common.entity.RemoteCallResult;
import org.apache.ibatis.annotations.Param;
/**
*
* @author wyb
*
*/
public interface RemoteCallResultMapper {
/**
*
* @param remoteCallResult
* @return
*/
int save(@Param("result") RemoteCallResult remoteCallResult);
}

@ -0,0 +1,20 @@
package com.docus.server.common.mapper;
import com.docus.server.common.entity.SdryPacsPrintExcept;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* pacsbase64 mapper
* @author wyb
*/
public interface SdryPacsPrintExceptMapper {
int saveExcept(@Param("except") SdryPacsPrintExcept pacsPrintExcept);
SdryPacsPrintExcept getById(@Param("id") Long id);
int compensateSuccuss(@Param("id") Long id);
List<Long> getCompensateIds(@Param("beginDateTime") String beginDateTime);
}

@ -0,0 +1,16 @@
package com.docus.server.common.service;
import com.docus.server.common.entity.RemoteCallResult;
/**
*
* @author WYBDEV
*/
public interface RemoteCallResultService {
/**
*
* @param remoteCallResult
*/
void save(RemoteCallResult remoteCallResult);
}

@ -0,0 +1,21 @@
package com.docus.server.common.service;
import com.docus.server.common.entity.SdryPacsPrintExcept;
import java.util.List;
/**
* pacs
* @author WYBDEV
*/
public interface SdryPacsPrintExceptService {
int insert(SdryPacsPrintExcept pacsPrintExcept);
SdryPacsPrintExcept getById(Long id);
int compensateSuccuss(Long id);
List<Long> getCompensateIds(String beginDateTime);
}

@ -0,0 +1,53 @@
package com.docus.server.common.service.impl;
import com.docus.core.util.Func;
import com.docus.infrastructure.redis.service.IdService;
import com.docus.server.common.entity.RemoteCallResult;
import com.docus.server.common.mapper.RemoteCallResultMapper;
import com.docus.server.common.service.RemoteCallResultService;
import com.docus.server.common.util.FileUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.File;
/**
*
*
* @author wyb
*/
@Service
public class RemoteCallResultServiceImpl implements RemoteCallResultService {
@Resource
private IdService idService;
@Resource
private RemoteCallResultMapper remoteCallResultMapper;
private final static int SAVE_DISK_DATA_LENGTH = 1024;
private final static String REMOTE_CALL_SAVE_PATH = FileUtil.currentPath() + File.separator + "remote-call";
@Override
public void save(RemoteCallResult remoteCallResult) {
remoteCallResult.setRequestStorageType(0);
remoteCallResult.setResponseStorageType(0);
Long id = remoteCallResult.getId() == null ? idService.getDateSeq() : remoteCallResult.getId();
remoteCallResult.setId(id);
String request = remoteCallResult.getRequest();
String response = remoteCallResult.getResponse();
if (Func.isNotBlank(request) && request.length() > SAVE_DISK_DATA_LENGTH) {
String saveReqPath = REMOTE_CALL_SAVE_PATH + File.separator + id + "_request";
FileUtil.saveStrData(response, new File(saveReqPath));
remoteCallResult.setRequestStorageType(1);
remoteCallResult.setRequest(saveReqPath);
}
if (Func.isNotBlank(response) && response.length() > SAVE_DISK_DATA_LENGTH) {
String saveRespPath = REMOTE_CALL_SAVE_PATH + File.separator + id + "_response";
FileUtil.saveStrData(response, new File(saveRespPath));
remoteCallResult.setResponseStorageType(1);
remoteCallResult.setResponse(saveRespPath);
}
remoteCallResultMapper.save(remoteCallResult);
}
}

@ -0,0 +1,52 @@
package com.docus.server.common.service.impl;
import com.docus.infrastructure.redis.service.IdService;
import com.docus.server.common.entity.SdryPacsPrintExcept;
import com.docus.server.common.mapper.SdryPacsPrintExceptMapper;
import com.docus.server.common.service.SdryPacsPrintExceptService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
*
*
* @author wyb
*/
@Service
public class SdryPacsPrintExceptServiceImpl implements SdryPacsPrintExceptService {
@Resource
private IdService idService;
@Resource
private SdryPacsPrintExceptMapper sdryPacsPrintExceptMapper;
@Override
public int insert(SdryPacsPrintExcept pacsPrintExcept) {
Long id = pacsPrintExcept.getId();
id = id == null ? idService.getDateSeq() : id;
pacsPrintExcept.setId(id);
return sdryPacsPrintExceptMapper.saveExcept(pacsPrintExcept);
}
@Override
public SdryPacsPrintExcept getById(Long id) {
return sdryPacsPrintExceptMapper.getById(id);
}
@Override
public int compensateSuccuss(Long id) {
return sdryPacsPrintExceptMapper.compensateSuccuss(id);
}
@Override
public List<Long> getCompensateIds(String beginDateTime) {
List<Long> ids= sdryPacsPrintExceptMapper.getCompensateIds(beginDateTime);
if(Objects.isNull(ids)){
return new ArrayList<>();
}
return ids;
}
}

@ -0,0 +1,95 @@
package com.docus.server.common.util;
import com.docus.core.util.Func;
import java.io.*;
/**
*
*
* @author WYBDEV
*/
public class FileUtil {
/**
* @return jar
*/
public static String currentPath() {
try {
File dir = new File(".");
return dir.getCanonicalPath();
} catch (Exception e) {
return "";
}
}
/**
*
*
* @param file
* @return
*/
public static boolean mkFileDirs(File file) {
if (!file.getParentFile().exists()) {
return file.getParentFile().mkdirs();
}
return true;
}
/**
*
*
* @param data
* @param file
*/
public static void saveStrData(String data, File file) {
mkFileDirs(file);
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(file);
fileWriter.write(data);
fileWriter.flush();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (fileWriter != null) {
try {
fileWriter.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
public static void main(String[] args) throws Exception {
String path = currentPath() + File.separator + "remotecall" + File.separator + Func.randomUUID() + ".txt";
File file = new File(path);
saveStrData("随便写一点东西", file);
String where = readStr(file);
System.out.println(where);
}
public static String readStr(File file) {
BufferedReader bufferedReader = null;
try {
StringBuilder sb = new StringBuilder();
bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
return sb.toString();
} catch (Exception ex){
ex.printStackTrace();
return null;
}finally {
if(bufferedReader!=null){
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

@ -3,6 +3,7 @@ package com.docus.server.report.api;
import com.docus.infrastructure.web.api.CommonResult;
import com.docus.server.report.api.dto.*;
import com.docus.server.report.api.vo.SdRyBloodReportVO;
import com.docus.server.report.api.vo.SdRyLiangBiaoReportVO;
import java.util.List;
@ -78,7 +79,14 @@ public interface ShunDePeopleService {
* @return
*/
CommonResult<List<SdRyBloodReportVO>> getBloodView(String inpatientNo, Integer admissTimes);
/**
*
* @param inpatientNo
* @param beginDate
* @param endDate +7
*/
List<SdRyLiangBiaoReportVO> getLinagBiaoReport(String inpatientNo, String beginDate, String endDate);
}

@ -84,6 +84,13 @@ public class ReportDto {
*/
private String reportSn;
/**
*
*/
private boolean mergeFileTitle;
public ReportDto() {
}

@ -6,13 +6,18 @@ import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.docus.core.util.DateUtil;
import com.docus.core.util.ExceptionUtils;
import com.docus.core.util.Func;
import com.docus.infrastructure.web.api.CommonResult;
import com.docus.server.common.entity.RemoteCallResult;
import com.docus.server.common.service.RemoteCallResultService;
import com.docus.server.report.api.ShunDePeopleService;
import com.docus.server.report.api.dto.*;
import com.docus.server.report.api.vo.SdRyBloodReportVO;
import com.docus.server.report.api.vo.SdRyLiangBiaoReportVO;
import com.docus.server.report.client.JaxWsDynamicClient;
import com.docus.server.report.config.SdRyReportQueryConfig;
import com.docus.server.report.job.ReportJob;
import com.docus.server.report.util.IdUtil;
import com.docus.server.report.util.TableJsonRead;
import com.docus.server.report.util.XmlUtil;
@ -22,10 +27,7 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@ -47,6 +49,10 @@ public class ShunDePeopleServiceImpl implements ShunDePeopleService {
@Resource
private SdRyReportQueryConfig sdRyReportQueryConfig;
@Resource
private ReportJob reportJob;
@Resource
private RemoteCallResultService remoteCallResultService;
@Override
@ -141,26 +147,54 @@ public class ShunDePeopleServiceImpl implements ShunDePeopleService {
// 参数3FunctionType传空暂未启用
// 参数4Caller服务调用者名称由PACS提供验证令牌时
String[] param = {functionName, inputString, functionType, caller};
RemoteCallResult remoteCallResult = new RemoteCallResult();
remoteCallResult.setUrl(url + " | " + namespaceUri + " | " + operationName);
remoteCallResult.setRequest(Arrays.toString(param));
remoteCallResult.setDescription("根据检查流水和报告序列号指定要获取的报告PACS将生成PDF格式的报告并将PDF文件的BASE64编码串返回。");
remoteCallResult.setKeyword(examNo + "_" + reportNo);
remoteCallResult.setCallStartTime(new Date());
PACS_PDF_LOCK.lock();
try {
String result = JaxWsDynamicClient.send(url, namespaceUri, operationName, param);
if (interval > 0) {
TimeUnit.MILLISECONDS.sleep(interval);
}
remoteCallResult.setCallStatus(1);
String base64 = reportJob.parsePacsGetBase64(result);
if (Func.isBlank(base64)) {
remoteCallResult.setRemark("查询base64结果为空!");
remoteCallResult.setCallStatus(3);
}
remoteCallResult.setResponse(result);
remoteCallResult.setCallEndTime(new Date());
try {
remoteCallResultService.save(remoteCallResult);
} catch (Exception e) {
e.printStackTrace();
}
return result;
} catch (Exception ex) {
log.error(ex.getMessage(), ex);
String exceptionMessage = ExceptionUtils.getExceptionMessage(ex);
remoteCallResult.setRemark(ex.getMessage());
remoteCallResult.setCallStatus(2);
remoteCallResult.setResponse(exceptionMessage);
remoteCallResult.setCallEndTime(new Date());
try {
remoteCallResultService.save(remoteCallResult);
} catch (Exception e) {
e.printStackTrace();
}
return null;
} finally {
PACS_PDF_LOCK.unlock();
}
}
public static void main(String[] args) {
SdNurseInsertSugarRequest request = new SdNurseInsertSugarRequest("10086", "1", "nur");
String requestParam = Func.toJson(request);
System.out.println(requestParam);
}
@Override
public SdNurseInsertSugarResponse getNurseInsertSugarReport(SdNurseInsertSugarRequest request) {
@ -217,6 +251,61 @@ public class ShunDePeopleServiceImpl implements ShunDePeopleService {
}
}
@Override
public List<SdRyLiangBiaoReportVO> getLinagBiaoReport(String inpatientNo, String beginDate, String endDate) {
String randomUuid = Func.randomUUID();
String param = "<Root>\n" +
"\t\t <FunCode>lbGetReport</FunCode>\n" +
"\t\t <patientid>" + inpatientNo + "</patientid>\n" +
"\t\t <begin_date>" + beginDate + "</begin_date>\n" +
"\t\t <end_date>" + endDate + "</end_date>\n" +
"\t </Root>";
Object[] params = {param};
String url = sdRyReportQueryConfig.getLiangbiaoUrl();
String operationName = "GetHisData";
try {
log.info("[" + randomUuid + "] " + "获取量表报告地址:" + url + "参数:" + param);
String result = JaxWsDynamicClient.send(url, null, operationName, params);
log.info("[" + randomUuid + "] " + "获取量表报告结果:" + result);
return parseLiangBiaoResult(result);
} catch (Exception ex) {
log.error("[" + randomUuid + "] " + "获取量表报告出错了," + ex.getMessage(), ex);
return new ArrayList<>();
}
}
private static List<SdRyLiangBiaoReportVO> parseLiangBiaoResult(String result) {
XmlUtil xmlUtil = XmlUtil.of(result);
Node node = xmlUtil.getNode("/Root/error_code");
String errorCode = node.getTextContent();
boolean success = "0".equals(errorCode);
if (!success) {
return new ArrayList<>();
}
NodeList reportNodeList = xmlUtil.getNodeList("/Root/ResultData/Row");
int length = reportNodeList.getLength();
if (length <= 0) {
return new ArrayList<>();
}
List<SdRyLiangBiaoReportVO> list = new ArrayList<>();
for (int i = 0; i < length; i++) {
SdRyLiangBiaoReportVO vo = new SdRyLiangBiaoReportVO();
Node item = reportNodeList.item(i);
NodeList childNodes = item.getChildNodes();
int childNodesLength = childNodes.getLength();
for (int j = 0; j < childNodesLength; j++) {
Node childNode = childNodes.item(j);
if ("PDFUrl".equals(childNode.getNodeName())) {
String pdfUrl = childNode.getTextContent();
vo.setFileUrl(pdfUrl);
}
}
list.add(vo);
}
return list;
}
private String organizationQuerySdRyInspectReportUrl(String reportQueryLisUrl) {
return reportQueryLisUrl + "/query?uuid=" + IdUtil.standardUUID() +
"&action=" + sdRyReportQueryConfig.getReportQueryInspectAction() +

@ -46,9 +46,10 @@ public class TaskDistributeServiceImpl implements TaskDistributeService {
}
public static void main(String[] args) {
String path="111.jpg";
String fh=".jpg";
System.out.println(path.endsWith(fh));
String result="{\"createTime\":\"2024-01-30 08:41:32\",\"hospitals\":[{\"admissTimes\":3,\"disDate\":\"2024-02-01 00:00:00\",\"disDeptName\":\"\",\"patientId\":\"2024013008413200003\",\"wardCode\":\"B060201\",\"wardName\":\"6号楼2楼病区\"}],\"jzh\":\"311618\",\"outPatientNoList\":[\"000997515200\",\"000870572900\",\"000870360700\",\"001041083100\"],\"patient\":{\"inpatientNo\":\"10073479\",\"name\":\"张玖昌\",\"patientId\":\"2024013008413200003\"},\"patientId\":\"2024013008413200003\",\"recordType\":\"1\",\"tasks\":[{\"collectorId\":\"22\",\"patientId\":\"2024013008413200003\",\"taskId\":913954351203971072}]}";
ReportDownTwoDto reportDownTwoDtoCommonResult = Func.readJson(result, new TypeReference<ReportDownTwoDto>() {
});
System.out.println(reportDownTwoDtoCommonResult);
}
@Override
public CommonResult<String> cancel(Long taskId) {

@ -0,0 +1,16 @@
package com.docus.server.report.api.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author YongBin Wen
* @date 2024/6/25 14:18
*/
@Data
@ApiModel("顺德人医量表报告单查询结果")
public class SdRyLiangBiaoReportVO {
@ApiModelProperty("文件下载地址")
private String fileUrl;
}

@ -0,0 +1,60 @@
package com.docus.server.report.config;
import com.docus.server.report.listener.NisReportDownloadWaitHandler;
import com.docus.server.report.mapper.DelayedMessagesMapper;
import com.docus.server.report.scheduler.JobScheduler;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* jobservicedaomapper
*
* @author YongBin Wen
* @date 2024/1/23 14:13
*/
@Component
public class JobAdminConfig implements InitializingBean, DisposableBean {
private static JobAdminConfig jobAdminConfig = null;
public static JobAdminConfig getJobAdminConfig() {
return jobAdminConfig;
}
// ---------------------- JobScheduler ----------------------
private JobScheduler xxlJobScheduler;
@Override
public void afterPropertiesSet() throws Exception {
jobAdminConfig = this;
xxlJobScheduler = new JobScheduler();
xxlJobScheduler.init();
}
@Override
public void destroy() throws Exception {
xxlJobScheduler.destroy();
}
// dao service
@Resource
private NisReportDownloadWaitHandler nisReportDownloadWaitHandler;
@Resource
private DelayedMessagesMapper delayedMessagesMapper;
public NisReportDownloadWaitHandler getNisReportDownloadWaitHandler() {
return nisReportDownloadWaitHandler;
}
public DelayedMessagesMapper getDelayedMessagesMapper() {
return delayedMessagesMapper;
}
}

@ -8,49 +8,73 @@ import java.util.List;
/**
*
*
* @author wyb
*/
public class SdRyReportHandledConfig {
private final SdRyReportSystem sdRyReportSystem;
private final static TableJsonRead JSON_READ = new TableJsonRead();
@Data
private static class SdRyReportSystem{
private static class SdRyReportSystem {
/**
*
* ,
*/
private List<String> blocking = new ArrayList<>();
private List<String> blocking = new ArrayList<>();
/**
*
* job
*/
private List<String> notHandled = new ArrayList<>();
/**
* base64job
*/
private List<String> fetchBase64 = new ArrayList<>();
}
public SdRyReportHandledConfig(){
TableJsonRead jsonRead = new TableJsonRead();
this.sdRyReportSystem= jsonRead.Read("data-config", "sdry-report-system.json", SdRyReportSystem.class);
public SdRyReportHandledConfig() {
}
public boolean isBlocking(String systemName){
if(this.sdRyReportSystem!=null){
List<String> blocking = this.sdRyReportSystem.getBlocking();
public SdRyReportSystem getSdRyReportSystem() {
return JSON_READ.Read("data-config", "sdry-report-system.json", SdRyReportSystem.class);
}
public boolean isBlocking(String systemName) {
SdRyReportSystem sdRyReportSystem = getSdRyReportSystem();
if (sdRyReportSystem != null) {
List<String> blocking = sdRyReportSystem.getBlocking();
return blocking.contains(systemName);
}
return false;
}
public boolean isNotHandled(String systemName){
if(this.sdRyReportSystem!=null){
List<String> notHandled = this.sdRyReportSystem.getNotHandled();
public boolean isNotHandled(String systemName) {
SdRyReportSystem sdRyReportSystem = getSdRyReportSystem();
if (sdRyReportSystem != null) {
List<String> notHandled = sdRyReportSystem.getNotHandled();
return notHandled.contains(systemName);
}
return false;
}
public boolean isFetchBase64(String systemName) {
SdRyReportSystem sdRyReportSystem = getSdRyReportSystem();
if (sdRyReportSystem != null) {
List<String> getBase64System = sdRyReportSystem.getFetchBase64();
return getBase64System.contains(systemName);
}
return false;
}
public static void main(String[] args) {
SdRyReportHandledConfig sdRyReportHandledConfig = new SdRyReportHandledConfig();
System.out.println(sdRyReportHandledConfig.sdRyReportSystem);
System.out.println(sdRyReportHandledConfig.getSdRyReportSystem());
System.out.println(sdRyReportHandledConfig.isNotHandled("lis"));
System.out.println(sdRyReportHandledConfig.isNotHandled("yx"));
System.out.println(sdRyReportHandledConfig.isBlocking("yx"));
System.out.println(sdRyReportHandledConfig.isBlocking("lis"));
System.out.println(sdRyReportHandledConfig.isFetchBase64("cta"));
}
}

@ -14,6 +14,12 @@ import org.springframework.stereotype.Component;
@Getter
@Setter
public class SdRyReportQueryConfig {
/**
*
*/
public static String BABY_COLLECTOR_ID_SUFFIX = "_B";
@Value("${sdry.report-index-query.wsdl-addr:}")
private String queryReportIndexWsdlAddr;
@Value("${sdry.report-index-query.namespace-uri:}")
@ -59,6 +65,8 @@ public class SdRyReportQueryConfig {
private int reportQueryNurseInsertSugarInterval;
@Value("${sdry.report-query-url.nurseInsertSugar.collectorId}")
private String reportQueryNurseInsertSugarCollectorId;
@Value("${sdry.report-query-url.nurseInsertSugar.defaultAssortType:other}")
private String reportQueryNurseInsertSugarDefaultAssortType;
@Value("${sdry.report-query-url.nurseInsertSugar.pushErr.url:}")
@ -67,8 +75,6 @@ public class SdRyReportQueryConfig {
private int reportQueryNurseInsertSugarErrPushInterval;
@Value("${sdry.report-query-url.blood.collectorId}")
private String bloodCollectorId;
@Value("${sdry.report-query-url.blood.url}")
@ -76,5 +82,10 @@ public class SdRyReportQueryConfig {
@Value("${sdry.report-query-url.blood.defaultAssortType}")
private String bloodDefaultAssortType;
@Value("${sdry.report-query-url.liangbiao.collectorId}")
private String liangbiaoCollectorId;
@Value("${sdry.report-query-url.liangbiao.url}")
private String liangbiaoUrl;
@Value("${sdry.report-query-url.liangbiao.defaultAssortType}")
private String liangbiaoDefaultAssortType;
}

@ -12,4 +12,9 @@ public interface ReportDownloadWait {
* redisKey,docus:collect:report:download:wait:{id}:{}
*/
String REPORT_DOWNLOAD_WAIT_KEY = "docus:collect:report:download:wait:%s:%s";
/**
*
*/
String NIS_REPORT_DOWNLOAD_WAIT_DELAY_MSG_TYPE = "docus:collect:report:download:wait:nis";
}

@ -0,0 +1,35 @@
package com.docus.server.report.controller;
import com.docus.infrastructure.web.api.CommonResult;
import com.docus.server.report.job.FetchPacsBase64Job;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
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;
@Slf4j
@Api(tags = "pacs获取base64异常相关接口")
@RestController
@RequestMapping("/api/fetchPacsBase64Except")
public class FetchPacsBase64ExceptController {
@Resource
private FetchPacsBase64Job fetchPacsBase64Job;
@ApiOperation(value = "根据异常数据表的id补偿")
@GetMapping("/compenstateById")
public CommonResult<Object> compenstateById(@Param("id") Long exceptId) {
fetchPacsBase64Job.compensateFetchBase64Report(exceptId);
return CommonResult.success("完成");
}
}

@ -76,4 +76,7 @@ public class AfCollectTask implements Serializable {
@ApiModelProperty(value = "c9")
private String C9;
@ApiModelProperty(value = "任务创建时间")
private Date createTime;
}

@ -0,0 +1,58 @@
package com.docus.server.report.entity;
import lombok.Data;
import java.util.Date;
/**
*
* @author wyb
*/
@Data
public class DelayedMessages {
/**
* ID
*/
private Long id;
/**
*
*/
private String messageType;
/**
*
*/
private String keyword;
/**
*
*/
private String message;
/**
*
*/
private Date nextExecutionTime;
/**
*
*/
private Integer delaySeconds;
/**
*
*/
private Date createTime;
/**
*
*/
private Integer retries;
/**
*
*/
private String errorMessage;
}

@ -0,0 +1,167 @@
package com.docus.server.report.job;
import com.docus.core.util.Func;
import com.docus.infrastructure.redis.service.IdService;
import com.docus.infrastructure.redis.service.RedisOps;
import com.docus.server.common.entity.SdryPacsPrintExcept;
import com.docus.server.common.service.SdryPacsPrintExceptService;
import com.docus.server.common.util.FileUtil;
import com.docus.server.report.api.dto.ReportDto;
import com.docus.server.report.service.ReportService;
import com.docus.server.report.util.XmlUtil;
import com.docus.server.report.webservice.WebserviceMessageType;
import com.docus.server.report.webservice.impl.HIP1008InspectionReportAdditionHandler;
import com.docus.server.report.webservice.impl.HIP1009InspectionReportUpdatesHandler;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.File;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* pacsbase64xxl-Job
*
* @author jiashi
*/
@Component
@Slf4j
public class FetchPacsBase64Job {
/**
* pacspdfbase64使job
*/
public final static String FETCH_PACS_BASE64_QUEUE_HIP1008 = "docus:sdry:pacsbase64:" + WebserviceMessageType.HIP1008;
public final static String FETCH_PACS_BASE64_QUEUE_HIP1009 = "docus:sdry:pacsbase64:" + WebserviceMessageType.HIP1009;
@Resource
private ReportService reportService;
@Resource
private RedisOps redisOps;
@Resource
private HIP1008InspectionReportAdditionHandler hip1008;
@Resource
private HIP1009InspectionReportUpdatesHandler hip1009;
@Resource
private SdryPacsPrintExceptService sdryPacsPrintExceptService;
@Resource
private IdService idService;
public static void main(String[] args) {
LocalDate localDate = LocalDate.now().plusMonths(-3);
String beginDateTime = localDate.toString() + " 00:00:00";
System.out.println(beginDateTime);
}
@XxlJob("compensateFetchBase64ReportJob")
public void compensateFetchBase64ReportJob() {
LocalDate localDate = LocalDate.now().plusMonths(-3);
String beginDateTime = localDate.toString() + " 00:00:00";
List<Long> compensateIds = sdryPacsPrintExceptService.getCompensateIds(beginDateTime);
log.info("补偿失败的pacs获取base64文件数据JOB开始本次补偿 {} 条数据!", compensateIds.size());
if (Func.isNotEmpty(compensateIds)) {
for (Long id : compensateIds) {
try {
compensateFetchBase64Report(id);
} catch (Exception ex) {
log.error("补偿失败的pacs补偿id" + id + " 补偿失败了。", ex);
}
}
}
log.info("补偿失败的pacs获取base64文件数据JOB结束");
}
/**
* 1008base64job
*/
@XxlJob("fetchBase64ReportHip1008Job")
public void fetchBase64ReportHip1008Job() {
String xml = redisOps.rPop(FETCH_PACS_BASE64_QUEUE_HIP1008);
ReportDto reportDto = parse(WebserviceMessageType.HIP1008, xml);
if (reportDto != null) {
reportService.report(reportDto);
return;
}
String filePath = FileUtil.currentPath() + File.separator + "fetch-base64-xml"
+ File.separator + WebserviceMessageType.HIP1008
+ File.separator + Func.formatDate(LocalDate.now())
+ File.separator + idService.getDateSeq();
FileUtil.saveStrData(xml, new File(filePath));
ReportDto reportDto2 = hip1008.getReportDtoByInspectionInsert(XmlUtil.of(xml));
SdryPacsPrintExcept pacsPrintExcept = new SdryPacsPrintExcept();
pacsPrintExcept.setInpatientNo(reportDto2.getInpatientNo());
pacsPrintExcept.setAdmissTimes(reportDto2.getAdmisstimes());
pacsPrintExcept.setJzh(reportDto2.getJzh());
pacsPrintExcept.setReportMessagePath(filePath);
pacsPrintExcept.setServiceFlag(WebserviceMessageType.HIP1008);
pacsPrintExcept.setState(0);
pacsPrintExcept.setCreateTime(new Date());
pacsPrintExcept.setExamReportSn(reportDto2.getReportSn());
sdryPacsPrintExceptService.insert(pacsPrintExcept);
}
/**
* 1009base64job
*/
@XxlJob("fetchBase64ReportHip1009Job")
public void fetchBase64ReportHip1009Job() {
String xml = redisOps.rPop(FETCH_PACS_BASE64_QUEUE_HIP1009);
ReportDto reportDto = parse(WebserviceMessageType.HIP1009, xml);
if (reportDto != null) {
reportService.report(reportDto);
return;
}
String filePath = FileUtil.currentPath() + File.separator + "fetch-base64-xml"
+ File.separator + WebserviceMessageType.HIP1009
+ File.separator + Func.formatDate(LocalDate.now())
+ File.separator + idService.getDateSeq();
FileUtil.saveStrData(xml, new File(filePath));
ReportDto reportDto2 = hip1009.getReportDtoByInspectionUpdate(XmlUtil.of(xml));
SdryPacsPrintExcept pacsPrintExcept = new SdryPacsPrintExcept();
pacsPrintExcept.setInpatientNo(reportDto2.getInpatientNo());
pacsPrintExcept.setAdmissTimes(reportDto2.getAdmisstimes());
pacsPrintExcept.setJzh(reportDto2.getJzh());
pacsPrintExcept.setReportMessagePath(filePath);
pacsPrintExcept.setServiceFlag(WebserviceMessageType.HIP1009);
pacsPrintExcept.setState(0);
pacsPrintExcept.setExamReportSn(reportDto2.getReportSn());
pacsPrintExcept.setCreateTime(new Date());
sdryPacsPrintExceptService.insert(pacsPrintExcept);
}
public void compensateFetchBase64Report(Long id) {
// base64的和job的检查报告统一处理逻辑不然会出现重复
SdryPacsPrintExcept except = sdryPacsPrintExceptService.getById(id);
if(Objects.isNull(except)){
log.error("未找到id为{} 的获取pacs异常的数据",id);
return;
}
String messagePath = except.getReportMessagePath();
String xml = FileUtil.readStr(new File(messagePath));
if (Objects.isNull(xml)) {
log.error("文件:{},获取xml内容为空", messagePath);
return;
}
ReportDto reportDto = parse(except.getServiceFlag(), xml);
if (reportDto != null) {
reportService.report(reportDto);
sdryPacsPrintExceptService.compensateSuccuss(id);
}
}
private ReportDto parse(String serviceFlag, String xml) {
XmlUtil xmlUtil = XmlUtil.of(xml);
if (serviceFlag.equals(WebserviceMessageType.HIP1008)) {
return hip1008.fetchBase64Parse(xmlUtil);
}
if (serviceFlag.equals(WebserviceMessageType.HIP1009)) {
return hip1009.fetchBase64Parse(xmlUtil);
}
return null;
}
}

@ -1,6 +1,7 @@
package com.docus.server.report.job;
import com.alibaba.fastjson.JSONObject;
import com.docus.core.util.DateUtil;
import com.docus.core.util.Func;
import com.docus.infrastructure.core.exception.BaseException;
import com.docus.infrastructure.redis.service.IdService;
@ -13,6 +14,7 @@ import com.docus.server.report.api.ShunDePeopleService;
import com.docus.server.report.api.TaskDistributeService;
import com.docus.server.report.api.dto.*;
import com.docus.server.report.api.vo.SdRyBloodReportVO;
import com.docus.server.report.api.vo.SdRyLiangBiaoReportVO;
import com.docus.server.report.config.SdRyCollectNurseInsertSugarConfig;
import com.docus.server.report.config.SdRyReportQueryConfig;
import com.docus.server.report.config.TaskValidateConfig;
@ -20,8 +22,10 @@ import com.docus.server.report.config.ZdAssortConfig;
import com.docus.server.report.consts.ReportDownloadWait;
import com.docus.server.report.entity.AfJobTime;
import com.docus.server.report.entity.AfReportRecord;
import com.docus.server.report.entity.DelayedMessages;
import com.docus.server.report.mapper.AfJobTimeMapper;
import com.docus.server.report.mapper.AfReportRecordMapper;
import com.docus.server.report.mapper.DelayedMessagesMapper;
import com.docus.server.report.service.ReportService;
import com.docus.server.report.service.ShunDePeopleBusinessService;
import com.docus.server.report.util.TableJsonRead;
@ -73,6 +77,8 @@ public class ReportJob {
private ShunDePeopleBusinessService shunDePeopleBusinessService;
@Resource
RedisOps redisOps;
@Resource
private DelayedMessagesMapper delayedMessagesMapper;
@Value("${docus.report.waittime}")
private int waittime;
@ -114,6 +120,59 @@ public class ReportJob {
log.info("病案号:{},住院次数:{},输血报告单采集:{} 份", inpatientNo, admissTimes, Func.isEmpty(sdRyBloodReportVOList) ? 0 : sdRyBloodReportVOList.size());
}
/**
*
*/
@XxlJob("SdRyLiangbiaoCollectJob")
public void sdRyLiangbiaoCollectJob() {
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>量表采集JOB开始");
String liangbiaoCollectorId = sdRyReportQueryConfig.getLiangbiaoCollectorId();
String liangbiaoDefaultAssortType = sdRyReportQueryConfig.getLiangbiaoDefaultAssortType();
ReportDownTwoDto reportDownTwoDto = taskDistributeService.getNoViewTaskByCollectorId(liangbiaoCollectorId);
if (reportDownTwoDto == null) {
return;
}
Long taskId = reportDownTwoDto.getTasks().get(0).getTaskId();
String patientId = reportDownTwoDto.getPatient().getPatientId();
String inpatientNo = reportDownTwoDto.getPatient().getInpatientNo();
ReportHospitalTwoDto hospitalTwoDto = reportDownTwoDto.getHospitals().get(0);
String admissDateStr = hospitalTwoDto.getAdmissDate();
String disDateStr = hospitalTwoDto.getDisDate();
Integer admissTimes = hospitalTwoDto.getAdmissTimes();
LocalDate admissDate = Func.parseDateTime(admissDateStr).toLocalDate();
LocalDate disDate = Func.parseDateTime(disDateStr).toLocalDate();
String beginDate = admissDate.toString();
String endDate = disDate.plusDays(7).toString();
List<SdRyLiangBiaoReportVO> liangBiaoReports = shunDePeopleService.getLinagBiaoReport(inpatientNo, beginDate, endDate);
int size = 0;
if (Func.isNotEmpty(liangBiaoReports)) {
// 查出多个记录可能指的是同一个已经合并的文件只是描述了项目而已所以根据pdf路径去重唯一值和命名取文件名
List<String> fileUrls = liangBiaoReports.stream().map(SdRyLiangBiaoReportVO::getFileUrl).distinct().collect(Collectors.toList());
ReportDto reportDto;
for (String fileUrl : fileUrls) {
String fileTitle = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
String serialnum = fileTitle;
reportDto = new ReportDto();
reportDto.setSysFlag(liangbiaoCollectorId);
reportDto.setTaskId(taskId);
reportDto.setDownUrl(fileUrl);
reportDto.setFileTitle(fileTitle);
reportDto.setSerialnum(serialnum);
reportDto.setAssortId(ZdAssortConfig.getZdAssortId(liangbiaoDefaultAssortType));
reportDto.setAdmisstimes(admissTimes);
reportDto.setInpatientNo(inpatientNo);
reportDto.setPatientId(patientId);
reportDto.setDowntype(1);
reportDto.setFileSource("1");
reportDto.setFilestoragetype("1");
reportService.report(reportDto);
}
size = fileUrls.size();
}
log.info("病案号:{},住院次数:{},量表报告单采集:{} 份", inpatientNo, admissTimes, Func.isEmpty(liangBiaoReports) ? 0 : size);
}
@XxlJob("SdRyLisCollectJob")
public void sdRyLisCollectJob() {
String reportQueryLisCollectorId = sdRyReportQueryConfig.getReportQueryLisCollectorId();
@ -205,77 +264,126 @@ public class ReportJob {
*/
@XxlJob("SdRyNurseInsertSugarCollectJob")
public void sdRyNurseInsertSugarCollectJob() {
String reportQueryNurseInsertSugarCollectorId = sdRyReportQueryConfig.getReportQueryNurseInsertSugarCollectorId();
ReportDownTwoDto reportDownTwoDto = taskDistributeService.getNoViewTaskByCollectorId(reportQueryNurseInsertSugarCollectorId);
if (reportDownTwoDto == null) {
return;
}
if (isCancelTask(reportDownTwoDto, reportQueryNurseInsertSugarCollectorId)) {
log.warn("作废任务,{}", reportDownTwoDto);
taskDistributeService.cancel(reportDownTwoDto.getTasks().get(0).getTaskId());
return;
}
String patientId = reportDownTwoDto.getPatient().getPatientId();
String inpatientNo = reportDownTwoDto.getPatient().getInpatientNo();
Integer admissTimes = reportDownTwoDto.getHospitals().get(0).getAdmissTimes();
final String traceCode = "nurse_print_doc";
SdNurseInsertSugarRequest sdNurseInsertSugarRequest = new SdNurseInsertSugarRequest(inpatientNo, admissTimes.toString(), traceCode);
SdNurseInsertSugarResponse sdNurseInsertSugarResponse = shunDePeopleService.getNurseInsertSugarReport(sdNurseInsertSugarRequest);
List<SdNurseInsertSugarResponse.NisData> nurseInsertSugarReportList = sdNurseInsertSugarResponse.getData();
if (Func.isNotEmpty(nurseInsertSugarReportList)) {
Integer filesNumber = nurseInsertSugarReportList.get(0).getFILES_NUMBER();
Integer nurseFileCount = tBasicMapper.getNurseFileCount(patientId);
if (filesNumber == null) {
log.warn("{} ,{},接口未返回文件数量!", inpatientNo, admissTimes);
return;
}
if (nurseFileCount == null) {
log.warn("{} , {},未获取到护理提交的文件数量!", inpatientNo, admissTimes);
shunDePeopleBusinessService.nurseFileCountError(inpatientNo, admissTimes, "未获取到护理提交的文件数量!");
try {
String reportQueryNurseInsertSugarCollectorId = sdRyReportQueryConfig.getReportQueryNurseInsertSugarCollectorId();
ReportDownTwoDto reportDownTwoDto = taskDistributeService.getNoViewTaskByCollectorId(reportQueryNurseInsertSugarCollectorId);
if (reportDownTwoDto == null) {
return;
}
if (!filesNumber.equals(nurseFileCount)) {
log.warn("{} , {},护理提交的文件数量与接口返回的文件数量不匹配!", inpatientNo, admissTimes);
shunDePeopleBusinessService.nurseFileCountError(inpatientNo, admissTimes, "护理提交的文件数量与接口返回的文件数量不匹配");
if (isCancelTask(reportDownTwoDto, reportQueryNurseInsertSugarCollectorId)) {
log.warn("作废任务,{}", reportDownTwoDto);
taskDistributeService.cancel(reportDownTwoDto.getTasks().get(0).getTaskId());
return;
}
// 从配置获取需要过滤的文件名称
SdRyCollectNurseInsertSugarConfig config = SdRyCollectNurseInsertSugarConfig.getConfig();
List<String> fileRemoveByFormName = config.getFileRemoveByFormName();
List<SdNurseInsertSugarResponse.NisData> removeFiles = nurseInsertSugarReportList.stream()
.filter(item -> isCharacterContains(item.getForm_name(), fileRemoveByFormName))
.collect(Collectors.toList());
log.info("住院号:{},住院次数{},护理采集过滤文件: {} 共 {} 条", inpatientNo, admissTimes, fileRemoveByFormName, removeFiles.size());
tBasicMapper.saveNisRemoveFilesCount(patientId, removeFiles.size());
ReportDto reportDto;
int collectFileCount = 0;
for (SdNurseInsertSugarResponse.NisData nisReport : nurseInsertSugarReportList) {
// 从过滤配置中匹配,如果匹配则跳过本次循环
if (isCharacterContains(nisReport.getForm_name(), fileRemoveByFormName)) {
continue;
boolean babyTask = isBabyTask(reportDownTwoDto);
String patientId = reportDownTwoDto.getPatient().getPatientId();
String inpatientNo = reportDownTwoDto.getPatient().getInpatientNo();
Integer admissTimes = reportDownTwoDto.getHospitals().get(0).getAdmissTimes();
final String traceCode = "nurse_print_doc";
SdNurseInsertSugarRequest sdNurseInsertSugarRequest = new SdNurseInsertSugarRequest(inpatientNo, admissTimes.toString(), traceCode);
SdNurseInsertSugarResponse sdNurseInsertSugarResponse = shunDePeopleService.getNurseInsertSugarReport(sdNurseInsertSugarRequest);
List<SdNurseInsertSugarResponse.NisData> nurseInsertSugarReportList = sdNurseInsertSugarResponse.getData();
if (Func.isNotEmpty(nurseInsertSugarReportList)) {
Integer filesNumber = nurseInsertSugarReportList.get(0).getFILES_NUMBER();
Integer nurseFileCount = tBasicMapper.getNurseFileCount(patientId);
if (filesNumber == null) {
log.warn("{} ,{},接口未返回文件数量!", inpatientNo, admissTimes);
return;
}
reportDto = new ReportDto();
reportDto.setSysFlag(reportQueryNurseInsertSugarCollectorId);
reportDto.setTaskId(reportDownTwoDto.getTasks().get(0).getTaskId());
reportDto.setDownUrl(nisReport.getUrl());
reportDto.setFileTitle(nisReport.getForm_name());
reportDto.setSerialnum(nisReport.getForm_id());
reportDto.setAssortId(ZdAssortConfig.getZdAssortId(nisReport.getForm_name(), sdRyReportQueryConfig.getReportQueryNurseInsertSugarDefaultAssortType()));
reportDto.setAdmisstimes(admissTimes);
reportDto.setInpatientNo(inpatientNo);
reportDto.setPatientId(patientId);
reportDto.setDowntype(1);
reportDto.setFileSource("1");
reportDto.setFilestoragetype("1");
reportService.report(reportDto);
collectFileCount++;
if (nurseFileCount == null) {
log.warn("{} , {},未获取到护理提交的文件数量!", inpatientNo, admissTimes);
shunDePeopleBusinessService.nurseFileCountError(inpatientNo, admissTimes, "未获取到护理提交的文件数量!");
return;
}
if (!filesNumber.equals(nurseFileCount)) {
log.warn("{} , {},护理提交的文件数量与接口返回的文件数量不匹配!", inpatientNo, admissTimes);
shunDePeopleBusinessService.nurseFileCountError(inpatientNo, admissTimes, "护理提交的文件数量与接口返回的文件数量不匹配");
return;
}
// 从配置获取需要过滤的文件名称
SdRyCollectNurseInsertSugarConfig config = SdRyCollectNurseInsertSugarConfig.getConfig();
List<String> fileRemoveByFormName = config.getFileRemoveByFormName();
List<SdNurseInsertSugarResponse.NisData> removeFiles = nurseInsertSugarReportList.stream()
.filter(item -> isCharacterContains(item.getForm_name(), fileRemoveByFormName))
.collect(Collectors.toList());
log.info("住院号:{},住院次数{},护理采集过滤文件: {} 共 {} 条", inpatientNo, admissTimes, fileRemoveByFormName, removeFiles.size());
tBasicMapper.saveNisRemoveFilesCount(patientId, removeFiles.size());
ReportDto reportDto;
int collectFileCount = 0;
for (SdNurseInsertSugarResponse.NisData nisReport : nurseInsertSugarReportList) {
// 从过滤配置中匹配,如果匹配则跳过本次循环
if (isCharacterContains(nisReport.getForm_name(), fileRemoveByFormName)) {
continue;
}
reportDto = new ReportDto();
reportDto.setSysFlag(reportQueryNurseInsertSugarCollectorId);
reportDto.setTaskId(reportDownTwoDto.getTasks().get(0).getTaskId());
reportDto.setDownUrl(nisReport.getUrl());
reportDto.setFileTitle(nisReport.getForm_name());
reportDto.setSerialnum(nisReport.getForm_id());
reportDto.setAssortId(ZdAssortConfig.getZdAssortId(nisReport.getForm_name(), sdRyReportQueryConfig.getReportQueryNurseInsertSugarDefaultAssortType()));
reportDto.setAdmisstimes(admissTimes);
reportDto.setInpatientNo(inpatientNo);
reportDto.setPatientId(patientId);
reportDto.setDowntype(1);
reportDto.setFileSource("1");
reportDto.setFilestoragetype("1");
if (babyTask) {
// 婴儿任务,文件传到母亲病案,来源加后缀
PatientInfoDTO parent = reportDownTwoDto.getParent();
reportDto.setAdmisstimes(parent.getAdmissTimes());
reportDto.setInpatientNo(parent.getInpatientNo());
reportDto.setPatientId(parent.getPatientId());
reportDto.setSysFlag(reportQueryNurseInsertSugarCollectorId + SdRyReportQueryConfig.BABY_COLLECTOR_ID_SUFFIX);
}
reportService.report(reportDto);
collectFileCount++;
}
log.info("住院号:{},住院次数{},护理采集文件: {} 条", inpatientNo, admissTimes, collectFileCount);
if (babyTask) {
return;
}
sendNisDelayVerifyMessage(patientId);
}
log.info("住院号:{},住院次数{},护理采集文件: {} 条", inpatientNo, admissTimes, collectFileCount);
// 设置一个redisKey,过期被监听处理
String redisKey = String.format(ReportDownloadWait.REPORT_DOWNLOAD_WAIT_KEY, reportQueryNurseInsertSugarCollectorId, patientId);
redisOps.setEx(redisKey, "0", waittime*60);
} catch (Exception ex) {
log.error("移动护理采集出错了!" + ex.getMessage(), ex);
}
}
/**
*
*/
public void sendNisDelayVerifyMessage(String patientId) {
int delaySeconds = waittime * 60;
String msgType = ReportDownloadWait.NIS_REPORT_DOWNLOAD_WAIT_DELAY_MSG_TYPE;
DelayedMessages condition = new DelayedMessages();
condition.setMessageType(msgType);
condition.setKeyword(patientId);
DelayedMessages message = delayedMessagesMapper.findMessage(condition);
LocalDateTime nextExecuteDateTime = LocalDateTime.now().plusSeconds(delaySeconds);
String formatNextExecuteDateTime = Func.formatDateTime(nextExecuteDateTime);
Date nextExecuteDate = Func.parseDate(formatNextExecuteDateTime, DateUtil.PATTERN_DATETIME);
if (Objects.isNull(message)) {
message = new DelayedMessages();
message.setId(idService.getDateSeq());
message.setMessageType(msgType);
message.setKeyword(patientId);
message.setMessage(patientId);
message.setDelaySeconds(delaySeconds);
message.setNextExecutionTime(nextExecuteDate);
message.setCreateTime(new Date());
message.setRetries(0);
message.setErrorMessage("");
delayedMessagesMapper.insert(message);
} else {
message.setDelaySeconds(delaySeconds);
message.setNextExecutionTime(nextExecuteDate);
delayedMessagesMapper.updateById(message);
}
}
@ -623,8 +731,7 @@ public class ReportJob {
ReportDto reportDto = new ReportDto();
reportDto.setAdmisstimes(tBasic.getAdmissTimes());
reportDto.setInpatientNo(tBasic.getInpatientNo());
// 确定报告唯一 报告单号+申请单号
reportDto.setSerialnum(examReportSn + requestSn);
reportDto.setFileTitle(reportName);
reportDto.setVisitSn(visitSn);
reportDto.setPatientSn(patientSn);
@ -637,6 +744,8 @@ public class ReportJob {
if (Func.isBlank(base64)) {
continue;
}
// 确定报告唯一 报告单号+申请单号
reportDto.setSerialnum(split[0]);
String url = saveBase64(base64);
reportDto.setDownUrl(url);
reportDto.setDowntype(5);
@ -645,6 +754,7 @@ public class ReportJob {
reportDto.setSysFlag(updateBy);
reportDto.setFileSource("1");
reportDto.setFilestoragetype("1");
reportDto.setMergeFileTitle(true);
reportDtoList.add(reportDto);
}
}
@ -657,7 +767,7 @@ public class ReportJob {
}
private String saveBase64(String base64) {
public String saveBase64(String base64) {
String dir = createBase64SaveDir();
String base64File = dir + File.separator + idService.getDateSeq() + ".txt";
try (FileWriter fileWriter = new FileWriter(base64File);
@ -691,7 +801,7 @@ public class ReportJob {
}
}
private static String parsePacsGetBase64(String xml) {
public String parsePacsGetBase64(String xml) {
try {
XmlUtil xmlUtil = XmlUtil.of(xml);
Node codeNode = xmlUtil.getNode("/Result/Code");
@ -756,11 +866,11 @@ public class ReportJob {
Instant adminssDateInstant = admissDate.toInstant();
Instant disDateInstant = disDate.toInstant();
// 开始时间去入院前三天
LocalDate admissLocalDate = adminssDateInstant.atZone(zoneId).toLocalDate();
LocalDate startTimeLocalDate = admissLocalDate.plusDays(-3);
LocalDate disLocalDate = disDateInstant.atZone(zoneId).toLocalDate();
String startTime = startTimeLocalDate.toString() + " 00:00:00";
String endTime = disLocalDate.toString() + " 23:59:59";
LocalDateTime admissLocalDateTime = adminssDateInstant.atZone(zoneId).toLocalDateTime();
LocalDateTime startTimeLocalDateTime = admissLocalDateTime.plusDays(-3);
LocalDateTime disLocalDateTime = disDateInstant.atZone(zoneId).toLocalDateTime();
String startTime = Func.formatDateTime(startTimeLocalDateTime);
String endTime = Func.formatDateTime(disLocalDateTime);
SdJxReportDto sdJxReportDto = new SdJxReportDto();
sdJxReportDto.setPage(true);
@ -811,11 +921,11 @@ public class ReportJob {
Instant adminssDateInstant = admissDate.toInstant();
Instant disDateInstant = disDate.toInstant();
// 开始时间去入院前三天
LocalDate admissLocalDate = adminssDateInstant.atZone(zoneId).toLocalDate();
LocalDate startTimeLocalDate = admissLocalDate.plusDays(-3);
LocalDate disLocalDate = disDateInstant.atZone(zoneId).toLocalDate();
String startTime = startTimeLocalDate.toString() + " 00:00:00";
String endTime = disLocalDate.toString() + " 23:59:59";
LocalDateTime admissLocalDateTime = adminssDateInstant.atZone(zoneId).toLocalDateTime();
LocalDateTime startTimeLocalDateTime = admissLocalDateTime.plusDays(-3);
LocalDateTime disLocalDateTime = disDateInstant.atZone(zoneId).toLocalDateTime();
String startTime = Func.formatDateTime(startTimeLocalDateTime);
String endTime = Func.formatDateTime(disLocalDateTime);
SdJxReportDto sdJxReportDto = new SdJxReportDto();
sdJxReportDto.setPage(true);
@ -871,6 +981,16 @@ public class ReportJob {
String resultJsonStr = Func.toJson(result);
List<JSONObject> reportObjectList = Func.parseJsonArray(resultJsonStr, JSONObject.class);
if (Func.isNotEmpty(reportObjectList)) {
// 开始时间去入院前三天
ZoneId zoneId = ZoneId.systemDefault();
Instant adminssDateInstant = tBasic.getAdmissDate().toInstant();
Instant disDateInstant = tBasic.getDisDate().toInstant();
// 开始时间去入院前三天
LocalDateTime admissLocalDateTime = adminssDateInstant.atZone(zoneId).toLocalDateTime();
LocalDateTime startTimeLocalDateTime = admissLocalDateTime.plusDays(-3);
LocalDateTime disLocalDateTime = disDateInstant.atZone(zoneId).toLocalDateTime();
for (JSONObject reportObject : reportObjectList) {
// 检验报告号
String labReportSn = String.valueOf(reportObject.get("LAB_REPORT_SN"));
@ -882,6 +1002,13 @@ public class ReportJob {
String reportTypeName = String.valueOf(reportObject.get("REPORT_TYPE_NAME"));
// 系统修改
String updateBy = String.valueOf(reportObject.get("UPDATEBY"));
// 申请时间
Date requestTime = reportObject.getDate("REQUEST_TIME");
LocalDateTime requestTime2LocalDateTime = requestTime.toInstant().atZone(zoneId).toLocalDateTime();
if (requestTime2LocalDateTime.isBefore(startTimeLocalDateTime) || requestTime2LocalDateTime.isAfter(disLocalDateTime)) {
log.warn("解析LIS报告病案号{},住院次数:{}该报告RequestTime不在入院时间-3天与出院时间范围内不下载此病案信息{}", tBasic.getInpatientNo(), tBasic.getAdmissTimes(), reportObject);
continue;
}
ReportDto reportDto = new ReportDto();
reportDto.setAdmisstimes(tBasic.getAdmissTimes());

@ -10,7 +10,6 @@ import com.docus.server.collection.entity.TBasic;
import com.docus.server.collection.entity.TBasicExtend;
import com.docus.server.collection.mapper.TBasicMapper;
import com.docus.server.common.util.RedisKeyExpirationHandler;
import com.docus.server.common.util.RedisKeyExpirationListener;
import com.docus.server.report.api.MedicalRecordService;
import com.docus.server.report.api.request.CqcAuditRequest;
import com.docus.server.report.config.SdRyReportQueryConfig;
@ -22,7 +21,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@ -34,8 +32,6 @@ import java.util.Objects;
@Component
@Slf4j
public class NisReportDownloadWaitHandler extends RedisKeyExpirationHandler {
@Autowired
private RedisKeyExpirationListener redisKeyExpirationListener;
@Autowired
private RedisOps redisOps;
@Autowired
@ -49,10 +45,9 @@ public class NisReportDownloadWaitHandler extends RedisKeyExpirationHandler {
@Resource
private MedicalRecordService medicalRecordService;
@PostConstruct
public void registerRedisKeyExpireListener() {
redisKeyExpirationListener.register(this);
}
public static void main(String[] args) {
String collectId = "3";
@ -71,10 +66,14 @@ public class NisReportDownloadWaitHandler extends RedisKeyExpirationHandler {
return;
}
String patientId = getPatientId(expireRedisKey);
verify(patientId);
}
public void verify(String patientId) {
log.info("病案主键:{} 护理采集数量校对开始!", patientId);
boolean verifyNisFileCountResult = verifyNisFileCountAndPushErr(patientId);
if (verifyNisFileCountResult) {
tBasicMapper.updateNursCollectState(patientId,1);
tBasicMapper.updateNursCollectState(patientId, 1);
nisQualityControl(patientId);
}
}
@ -128,7 +127,8 @@ public class NisReportDownloadWaitHandler extends RedisKeyExpirationHandler {
CommonResult<String> result = medicalRecordService.cqcAudit(request);
log.info("{} 护理质控结果:{}", patientId, result);
if (!ResultCode.SUCCESS.getCode().equals(result.getCode())) {
// 就算是返回失败的code如果包含了 ‘当前节点不包含’,也算质控通过
if (!ResultCode.SUCCESS.getCode().equals(result.getCode()) && !result.getMsg().contains("当前节点不包含")) {
throw new BaseException(result.getMsg());
}
}
@ -165,4 +165,5 @@ public class NisReportDownloadWaitHandler extends RedisKeyExpirationHandler {
return expireRedisKey.replace(nisKeyPrefix, "");
}
}

@ -24,4 +24,15 @@ public interface AfCollectTaskMapper {
* @return
*/
AfCollectTask getTaskById(@Param("id") Long taskId);
/**
*
* @param id id
* @param fileName
* @param serialnum
* @return
*/
int updateNewSubmit(@Param("id") Long id,@Param("c2") String fileName,@Param("c1") String serialnum);
int cancelFile(@Param("patientId")String patientId, @Param("sysFlag")String sysFlag,@Param("serialnum") String serialnum);
}

@ -0,0 +1,23 @@
package com.docus.server.report.mapper;
import com.docus.server.report.entity.DelayedMessages;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* mapper
* @author wyb
*/
public interface DelayedMessagesMapper {
int delById(@Param("id") Long id);
int updateById(@Param("message") DelayedMessages message);
int insert(@Param("message") DelayedMessages message);
List<DelayedMessages> findExecutableMessages(@Param("condition") DelayedMessages condition,@Param("currentDateTime") String formatCurrentDateTime);
DelayedMessages findMessage(@Param("condition") DelayedMessages condition);
}

@ -0,0 +1,26 @@
package com.docus.server.report.scheduler;
import com.docus.server.report.thread.VerifyNisReportHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author YongBin Wen
* @date 2024/1/23 14:04
*/
public class JobScheduler {
private static final Logger logger = LoggerFactory.getLogger(JobScheduler.class);
public void init() throws Exception {
VerifyNisReportHelper.getInstance().start();
logger.info(">>>>>>>>> init job admin success.");
}
public void destroy() throws Exception {
VerifyNisReportHelper.getInstance().toStop();
}
}

@ -28,4 +28,5 @@ public interface ReportService {
*/
void makeupThreePartyPushReportByTaskIds(List<Long> taskIds) throws Exception;
void cancel(String patientId, String sysFlag, String serialnum);
}

@ -17,7 +17,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@ -77,7 +77,7 @@ public class ReportServiceImpl implements ReportService {
}
String bufferDownUrl = bufferInfo.getDownUrl();
String serialnum = bufferInfo.getSerialnum();
// 设置地址或者文件信息
// 设置地址或者文件信息
if (isSaveOrUpdateDownloadUrl) {
bufferInfo.setFileUrl(reportDto);
} else {
@ -89,6 +89,7 @@ public class ReportServiceImpl implements ReportService {
if (canReport) {
afReportRecordMapper.cancelBlocking(bufferInfo.getId());
ReportDto dto = new ReportDto(bufferInfo);
dto.setMergeFileTitle(true);
report(dto);
}
} finally {
@ -113,7 +114,7 @@ public class ReportServiceImpl implements ReportService {
// 如果出现多条出错的情况,还是得保存收到的信息,人工干预处理
patientId = tBasicMapper.getPatientIdByInpatientNoAndAdminssTimes(reportDto.getInpatientNo(), reportDto.getAdmisstimes());
} catch (Exception ex) {
log.error("查询病案主键出错了,病案号:"+reportDto.getInpatientNo()+" ,住院次数:"+reportDto.getAdmisstimes(), ex);
log.error("查询病案主键出错了,病案号:" + reportDto.getInpatientNo() + " ,住院次数:" + reportDto.getAdmisstimes(), ex);
}
// 不验证数据,始终保存收到的信息
AfReportRecord afReportRecord = afReportRecordMapper.getRecordBySerialnumAndInpatientNoAndSysFlag(reportDto.getSerialnum(), reportDto.getInpatientNo(), reportDto.getAdmisstimes(), reportDto.getSysFlag());
@ -124,10 +125,21 @@ public class ReportServiceImpl implements ReportService {
afReportRecord.setPatientId(patientId);
afReportRecordMapper.saveRecord(afReportRecord);
} else {
// 如果要合并文件标题
String fileTitle = reportDto.getFileTitle();
if (reportDto.isMergeFileTitle()) {
String lastFileName = afReportRecord.getFileName();
String[] fileTitles = lastFileName.split("\\|");
HashSet<String> fileTitleSet = new LinkedHashSet<>();
Collections.addAll(fileTitleSet, fileTitles);
fileTitleSet.add(fileTitle);
fileTitle = String.join("|", fileTitleSet);
}
// 更新 主要更新 url
afReportRecord.setDownUrl(reportDto.getDownUrl());
afReportRecord.setDownType(reportDto.getDowntype());
afReportRecord.setFileName(reportDto.getFileTitle());
afReportRecord.setFileName(fileTitle);
afReportRecord.setPatientId(patientId);
afReportRecord.setZdAssortId(reportDto.getAssortId());
afReportRecordMapper.updateRecordByTaskId(afReportRecord);
@ -151,7 +163,10 @@ public class ReportServiceImpl implements ReportService {
afCollectTask.setSysflag(reportDto.getSysFlag());
afCollectTask.setState("0");
afCollectTask.setPatientId(patientId);
afCollectTask.setCreateTime(new Date());
collectTaskMapper.saveTask(afCollectTask);
}else{
collectTaskMapper.updateNewSubmit(afCollectTask.getId(),afReportRecord.getFileName(),reportDto.getSerialnum());
}
// 都成功后发布下载事件
applicationContext.publishEvent(new ThreePartyPushReportDownEvent(this, afReportRecord.getTaskId()));
@ -194,4 +209,9 @@ public class ReportServiceImpl implements ReportService {
// 当截取长度小于集合长度,可以进行下次循环截取
} while (loop);
}
@Override
public void cancel(String patientId, String sysFlag, String serialnum) {
collectTaskMapper.cancelFile(patientId,sysFlag,serialnum);
}
}

@ -0,0 +1,95 @@
package com.docus.server.report.thread;
import com.docus.core.util.DateUtil;
import com.docus.core.util.Func;
import com.docus.server.report.config.JobAdminConfig;
import com.docus.server.report.consts.ReportDownloadWait;
import com.docus.server.report.entity.DelayedMessages;
import com.docus.server.report.listener.NisReportDownloadWaitHandler;
import com.docus.server.report.mapper.DelayedMessagesMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author YongBin Wen
* @date 2024/1/23 10:59
*/
public class VerifyNisReportHelper {
private static Logger logger = LoggerFactory.getLogger(VerifyNisReportHelper.class);
private static VerifyNisReportHelper instance = new VerifyNisReportHelper();
public static VerifyNisReportHelper getInstance() {
return instance;
}
private Thread nisVerifyThread;
private volatile boolean toStop = false;
public void start() {
nisVerifyThread = new Thread(() -> {
final String messageType = ReportDownloadWait.NIS_REPORT_DOWNLOAD_WAIT_DELAY_MSG_TYPE;
DelayedMessages condition = new DelayedMessages();
condition.setMessageType(messageType);
DelayedMessagesMapper delayedMessagesMapper = JobAdminConfig.getJobAdminConfig().getDelayedMessagesMapper();
NisReportDownloadWaitHandler handler = JobAdminConfig.getJobAdminConfig().getNisReportDownloadWaitHandler();
while (!toStop) {
try {
LocalDateTime currentDateTime = LocalDateTime.now();
String formatCurrentDateTime = Func.formatDateTime(currentDateTime);
// 数据量暂时不大,使用
List<DelayedMessages> delayedMessages = delayedMessagesMapper.findExecutableMessages(condition, formatCurrentDateTime);
if (Func.isNotEmpty(delayedMessages)) {
for (DelayedMessages message : delayedMessages) {
try {
String patientId = message.getMessage();
handler.verify(patientId);
delayedMessagesMapper.delById(message.getId());
} catch (Exception ex) {
if (!toStop) {
logger.error(">>>>>>>>>>> verify nis report thread error:" + ex.getMessage() + " ,delayMessage:" + Func.toJson(message), ex);
int retries = message.getRetries() + 1;
Integer delaySeconds = message.getDelaySeconds();
LocalDateTime nexExecuteLocalDateTime = LocalDateTime.now().plusSeconds(delaySeconds);
String dateTime = Func.formatDateTime(nexExecuteLocalDateTime);
Date nexExecuteTime = Func.parseDate(dateTime, DateUtil.PATTERN_DATETIME);
message.setRetries(retries);
message.setErrorMessage(ex.getMessage());
message.setNextExecutionTime(nexExecuteTime);
delayedMessagesMapper.updateById(message);
}
}
}
}
TimeUnit.SECONDS.sleep(10);
} catch (Exception ex) {
if (!toStop) {
logger.error(">>>>>>>>>>> verify nis report thread error:" + ex.getMessage(), ex);
}
}
}
logger.info(">>>>>>>>>>> verify nis report thread stop");
});
nisVerifyThread.setDaemon(true);
nisVerifyThread.setName("verifyNisReportHelper");
nisVerifyThread.start();
}
public void toStop() {
toStop = false;
nisVerifyThread.interrupt();
try {
nisVerifyThread.join();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}

@ -18,6 +18,7 @@ package com.docus.server.report.util;
import com.docus.core.util.Exceptions;
import com.docus.core.util.IoUtil;
import com.docus.core.util.StringUtil;
import org.springframework.lang.Nullable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@ -93,6 +94,7 @@ public class XmlUtil {
* @return XmlUtil
*/
public static XmlUtil of(String xmlStr) {
xmlStr = StringUtil.replace(xmlStr, "\u00A0", " ");
StringReader sr = new StringReader(xmlStr.trim());
InputSource inputSource = new InputSource(sr);
XmlUtil xmlUtil = create(inputSource);

@ -75,4 +75,12 @@ public interface IReportServer {
* @return
*/
String pushMaternalInfantRelationship(String maternalInfantRelationshipMessage);
/**
*
* /
* @param recallInspectionReportMessage /
* @return
*/
String pushRecallInspectionReport(String recallInspectionReportMessage);
}

@ -9,6 +9,7 @@ public interface WebserviceMessageType {
String HIP1009="HIP1009";
String HIP1010="HIP1010";
String HIP1011="HIP1011";
String HIP1112="HIP1112";
String HIP1166="HIP1166";
String HIP1264="HIP1264";
String ICU="ICU";

@ -3,9 +3,14 @@ package com.docus.server.report.webservice.impl;
import com.docus.core.util.DateUtil;
import com.docus.core.util.Func;
import com.docus.infrastructure.core.exception.BaseException;
import com.docus.infrastructure.redis.service.RedisOps;
import com.docus.server.collection.service.ITBasicService;
import com.docus.server.report.api.ShunDePeopleService;
import com.docus.server.report.api.dto.ReportDto;
import com.docus.server.report.config.SdRyReportHandledConfig;
import com.docus.server.report.config.ZdAssortConfig;
import com.docus.server.report.job.FetchPacsBase64Job;
import com.docus.server.report.job.ReportJob;
import com.docus.server.report.service.ReportService;
import com.docus.server.report.util.IdUtil;
import com.docus.server.report.util.XmlUtil;
@ -16,10 +21,13 @@ import org.springframework.stereotype.Service;
import org.w3c.dom.Node;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* HIP1008-
*
* @author jiahsi
*/
@Service(WebserviceMessageType.HIP1008)
@ -27,6 +35,15 @@ import java.util.Date;
public class HIP1008InspectionReportAdditionHandler implements WebserviceReceiveServerHandler {
@Resource
private ReportService reportService;
@Resource
private ShunDePeopleService shunDePeopleService;
@Resource
private ReportJob reportJob;
@Resource
private RedisOps redisOps;
@Resource
private ITBasicService tBasicService;
@Override
public String handle(String receiveMessage) {
@ -40,17 +57,23 @@ public class HIP1008InspectionReportAdditionHandler implements WebserviceReceive
sender = xmlUtil.getNode("/POOR_HIP1008/sender/device/id/item/@extension").getNodeValue();
receiver = xmlUtil.getNode("/POOR_HIP1008/receiver/device/id/item/@extension").getNodeValue();
SdRyReportHandledConfig sdRyReportHandledConfig = new SdRyReportHandledConfig();
// 如果是获取base64的为什么这里要解析因为这里可以提前解析知道问题base64另外抽出来的方法会响应超时为了做异步
ReportDto reportDto = getReportDtoByInspectionInsert(xmlUtil);
verifyFileInfo(reportDto);
String sysFlag = reportDto.getSysFlag();
if (sdRyReportHandledConfig.isNotHandled(sysFlag)) {
return insertSuccess(msgId, sender, receiver);
}
if(sdRyReportHandledConfig.isBlocking(sysFlag)){
if (sdRyReportHandledConfig.isBlocking(sysFlag)) {
reportDto.setDownUrl(null);
reportService.reportBuffer(reportDto);
return insertSuccess(msgId, sender, receiver);
}
if (sdRyReportHandledConfig.isFetchBase64(sender)) {
// 过程很长保存队列job慢慢消费
redisOps.lPush(FetchPacsBase64Job.FETCH_PACS_BASE64_QUEUE_HIP1008, receiveMessage);
return insertSuccess(msgId, sender, receiver);
}
reportService.report(reportDto);
return insertSuccess(msgId, sender, receiver);
} catch (BaseException baseException) {
@ -61,19 +84,118 @@ public class HIP1008InspectionReportAdditionHandler implements WebserviceReceive
return insertFailed(msgId, sender, receiver, "系统错误!");
}
}
public ReportDto fetchBase64Parse(XmlUtil inspectionInsertXmlUtil) {
Node senderNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/sender/device/id/item/@extension");
String updateBy = senderNode.getNodeValue();
Node inpatientNoNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.12']/@extension");
String inpatientNo = inpatientNoNode.getNodeValue();
Node admissTimesNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/recordTarget/patientRole/item[@root='1.2.156.112635.1.2.1.7']/@extension");
Integer admissTimes;
try {
admissTimes = Integer.valueOf(admissTimesNode.getNodeValue());
} catch (Exception ex) {
log.error(ex.getMessage(), ex);
admissTimes = null;
}
// 患者本次就诊唯一键患者id【12位】+就诊次数
Node visitSnNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.11']/@extension");
String visitSn = visitSnNode.getNodeValue();
// 患者id
Node patientSnNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/recordTarget/patientRole/item[@root='2.16.156.10011.0.2.2']/@extension");
String patientSn = patientSnNode.getNodeValue();
// 检查报告单号标识
Node reportFlagNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.32']/@extension");
String examReportSn = reportFlagNode.getNodeValue();
//电子申请单编号
Node eafNoNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.24']/@extension");
String requestSn = eafNoNode.getNodeValue();
Node fileTitleNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/component/structuredBody/component[@displayName='检查结果明细']/section/entry[@displayName='检查项目']/organizer/component[@displayName='检查项目']/observation/value");
String reportName = fileTitleNode.getTextContent();
if (admissTimes == null && isManualDocuments(requestSn)) {
admissTimes = getAdmissTimes(inpatientNo, inspectionInsertXmlUtil);
}
ReportDto reportDto = new ReportDto();
reportDto.setAdmisstimes(admissTimes);
reportDto.setInpatientNo(inpatientNo);
// 确定报告唯一 报告单号+申请单号,如果报告单号带下划线是合并报告,取报告单号下划线前的
String serialnum = examReportSn + requestSn;
reportDto.setFileTitle(reportName);
reportDto.setVisitSn(visitSn);
reportDto.setPatientSn(patientSn);
// 检查报告需要从Pacs接口获取base64
String[] split = examReportSn.split("_");
String fromPacs = shunDePeopleService.getBase64PdfFromPacs(split[0], split[1]);
// 从pacs打印出来
String base64 = reportJob.parsePacsGetBase64(fromPacs);
if (Func.isBlank(base64)) {
return null;
}
// 如果报告单号带下划线是合并报告,取报告单号下划线前的
if (examReportSn.contains("_")) {
serialnum = split[0];
}
reportDto.setSerialnum(serialnum);
String url = reportJob.saveBase64(base64);
reportDto.setDownUrl(url);
reportDto.setDowntype(5);
// 根据系统来分类
reportDto.setAssortId(ZdAssortConfig.getZdAssortId(updateBy));
reportDto.setSysFlag(updateBy);
reportDto.setFileSource("1");
reportDto.setFilestoragetype("1");
reportDto.setMergeFileTitle(true);
return reportDto;
}
private Integer getAdmissTimes(String inpatientNo, XmlUtil inspectionInsertXmlUtil) {
try {
//检查报告日期 yyyyMMddHHmmss
String pattern = "yyyyMMddHHmmss";
Node reportTimeNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/author/time/@value");
String reportTime = reportTimeNode.getNodeValue();
Date reportDate = Func.parseDate(reportTime, pattern);
// 出院时间+3天匹配
int timeRangeAddedHour = 3 * 24;
return tBasicService.matchingAdmissTimesByInpNoAndReportTime(inpatientNo, reportDate, timeRangeAddedHour);
} catch (Exception ex) {
throw new BaseException("解析检查报告时间出错了!");
}
}
public ReportDto getReportDtoByInspectionInsert(XmlUtil inspectionInsertXmlUtil) {
Node senderNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/sender/device/id/item/@extension");
String sender = senderNode.getNodeValue();
String zdAssortId = ZdAssortConfig.getZdAssortId(sender);
if(Func.isBlank(zdAssortId)){
zdAssortId=ZdAssortConfig.getOtherAssortId();
if (Func.isBlank(zdAssortId)) {
zdAssortId = ZdAssortConfig.getOtherAssortId();
}
Node inpatientNoNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.12']/@extension");
String inpatientNo = inpatientNoNode.getNodeValue();
Node admissTimesNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/recordTarget/patientRole/item[@root='1.2.156.112635.1.2.1.7']/@extension");
Integer admissTimes = Integer.valueOf(admissTimesNode.getNodeValue());
Integer admissTimes;
try {
admissTimes = Integer.valueOf(admissTimesNode.getNodeValue());
} catch (Exception ex) {
log.error(ex.getMessage(), ex);
admissTimes = null;
}
// 检查报告单号标识
Node reportFlagNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.32']/@extension");
@ -82,6 +204,18 @@ public class HIP1008InspectionReportAdditionHandler implements WebserviceReceive
Node eafNoNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.24']/@extension");
String eafNo = eafNoNode.getNodeValue();
String serialnum = reportFlag + "@" + eafNo;
// 如果报告单号带下划线是合并报告,取报告单号下划线前的,可能有个别来源不需要
List<String> ignoreUnderlineSenders= Arrays.asList("lungFunction-001","BL-001");
if (reportFlag.contains("_") && !ignoreUnderlineSenders.contains(sender)) {
String[] split = reportFlag.split("_");
serialnum = split[0];
}
// 如果是手工单,住院次数可能为空,则需要根据检查报告时间与出入院区间获取住院次数
// todo 实施手工单需求确认
if (admissTimes == null && isManualDocuments(eafNo)) {
getAdmissTimes(inpatientNo, inspectionInsertXmlUtil);
}
// Node assortIdNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告']/section/entry[@displayName='检查类型']/observation/code/@displayName");
// String assortId = assortIdNode.getNodeValue();
@ -89,8 +223,8 @@ public class HIP1008InspectionReportAdditionHandler implements WebserviceReceive
// Node sysFlagNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告']/section/entry[@displayName='检查类型']/observation/code/@displayName");
// String sysFlag = sysFlagNode.getNodeValue();
Node fileTitleNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告']/section/entry[@displayName='检查报告类型']/observation/code/@displayName");
String fileTitle = fileTitleNode.getNodeValue();
Node fileTitleNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/component/structuredBody/component[@displayName='检查结果明细']/section/entry[@displayName='检查项目']/organizer/component[@displayName='检查项目']/observation/value");
String fileTitle = fileTitleNode.getTextContent();
Node downUrlNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告图像']/report/entry[@displayName='检查报告图像URL地址']/observation/value");
String downUrl = downUrlNode.getTextContent();
@ -106,9 +240,23 @@ public class HIP1008InspectionReportAdditionHandler implements WebserviceReceive
reportDto.setSysFlag(sender);
reportDto.setFileSource("1");
reportDto.setFilestoragetype("1");
reportDto.setMergeFileTitle(true);
return reportDto;
}
/**
*
*
* @param eafNo
* @return boolean
* @date 2024/1/9 14:38
* @author YongBin Wen
*/
private boolean isManualDocuments(String eafNo) {
return Func.isBlank(eafNo);
}
/**
*
*
@ -120,8 +268,8 @@ public class HIP1008InspectionReportAdditionHandler implements WebserviceReceive
public String insertSuccess(String msgId, String sender, String receiver) {
String createTime = Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI);
return "<MCCI_IN000002UV01 xmlns=\"urn:hl7-org:v3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ITSVersion=\"XML_1.0\" xsi:schemaLocation=\"urn:hl7-org:v3 file:///E:/hl7/HL7/v3ballot_fullsite_2011MAY/v3ballot/html/processable/multicacheschemas/MCCI _IN000002UV01.xsd\">" +
"<id extension=\""+ IdUtil.standardUUID()+"\"/>" +
"<creationTime value=\""+createTime+"\"/>" +
"<id extension=\"" + IdUtil.standardUUID() + "\"/>" +
"<creationTime value=\"" + createTime + "\"/>" +
"<interactionId root=\"2.16.840.1.113883.1.6\" extension=\"MCCI_IN000002UV01\"/>" +
"<processingCode code=\"P\"/>" +
"<processingModeCode/>" +
@ -142,7 +290,7 @@ public class HIP1008InspectionReportAdditionHandler implements WebserviceReceive
"</sender>" +
"<acknowledgement typeCode=\"AA\">" +
"<targetMessage>" +
"<id extension=\""+msgId+"\"/>" +
"<id extension=\"" + msgId + "\"/>" +
"</targetMessage>" +
"<acknowledgementDetail>" +
"<text value=\"成功\"/>" +
@ -193,8 +341,8 @@ public class HIP1008InspectionReportAdditionHandler implements WebserviceReceive
String createTime = Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI);
return "<MCCI_IN000002UV01 xmlns=\"urn:hl7-org:v3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ITSVersion=\"XML_1.0\" xsi:schemaLocation=\"urn:hl7-org:v3 file:///E:/hl7/HL7/v3ballot_fullsite_2011MAY/v3ballot/html/processable/multicacheschemas/MCCI _IN000002UV01.xsd\">" +
"<id extension=\""+IdUtil.standardUUID()+"\"/>" +
"<creationTime value=\""+createTime+"\"/>" +
"<id extension=\"" + IdUtil.standardUUID() + "\"/>" +
"<creationTime value=\"" + createTime + "\"/>" +
"<interactionId root=\"2.16.840.1.113883.1.6\" extension=\"MCCI_IN000002UV01\"/>" +
"<processingCode code=\"P\"/>" +
"<processingModeCode/>" +
@ -215,10 +363,10 @@ public class HIP1008InspectionReportAdditionHandler implements WebserviceReceive
"</sender>" +
"<acknowledgement typeCode=\"AE\">" +
"<targetMessage>" +
"<id extension=\""+msgId+"\"/>" +
"<id extension=\"" + msgId + "\"/>" +
"</targetMessage>" +
"<acknowledgementDetail>" +
"<text value=\""+failedMessage+"\"/>" +
"<text value=\"" + failedMessage + "\"/>" +
"</acknowledgementDetail>" +
"</acknowledgement>" +
"</MCCI_IN000002UV01>";

@ -3,9 +3,14 @@ package com.docus.server.report.webservice.impl;
import com.docus.core.util.DateUtil;
import com.docus.core.util.Func;
import com.docus.infrastructure.core.exception.BaseException;
import com.docus.infrastructure.redis.service.RedisOps;
import com.docus.server.collection.service.ITBasicService;
import com.docus.server.report.api.ShunDePeopleService;
import com.docus.server.report.api.dto.ReportDto;
import com.docus.server.report.config.SdRyReportHandledConfig;
import com.docus.server.report.config.ZdAssortConfig;
import com.docus.server.report.job.FetchPacsBase64Job;
import com.docus.server.report.job.ReportJob;
import com.docus.server.report.service.ReportService;
import com.docus.server.report.util.IdUtil;
import com.docus.server.report.util.XmlUtil;
@ -16,10 +21,13 @@ import org.springframework.stereotype.Service;
import org.w3c.dom.Node;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* HIP1009-
*
* @author jiahsi
*/
@Service(WebserviceMessageType.HIP1009)
@ -27,6 +35,15 @@ import java.util.Date;
public class HIP1009InspectionReportUpdatesHandler implements WebserviceReceiveServerHandler {
@Resource
private ReportService reportService;
@Resource
private ShunDePeopleService shunDePeopleService;
@Resource
private ReportJob reportJob;
@Resource
private RedisOps redisOps;
@Resource
private ITBasicService tBasicService;
@Override
public String handle(String receiveMessage) {
@ -40,17 +57,23 @@ public class HIP1009InspectionReportUpdatesHandler implements WebserviceReceiveS
sender = xmlUtil.getNode("/POOR_HIP1009/sender/device/id/item/@extension").getNodeValue();
receiver = xmlUtil.getNode("/POOR_HIP1009/receiver/device/id/item/@extension").getNodeValue();
SdRyReportHandledConfig sdRyReportHandledConfig = new SdRyReportHandledConfig();
// 如果是获取base64的为什么这里要解析因为这里可以提前解析知道问题base64另外抽出来的方法会响应超时为了做异步
ReportDto reportDto = getReportDtoByInspectionUpdate(xmlUtil);
verifyFileInfo(reportDto);
String sysFlag = reportDto.getSysFlag();
if (sdRyReportHandledConfig.isNotHandled(sysFlag)) {
return updateSuccess(msgId, sender, receiver);
}
if(sdRyReportHandledConfig.isBlocking(sysFlag)){
if (sdRyReportHandledConfig.isBlocking(sysFlag)) {
reportDto.setDownUrl(null);
reportService.reportBuffer(reportDto);
return updateSuccess(msgId, sender, receiver);
}
if (sdRyReportHandledConfig.isFetchBase64(sender)) {
// 过程很长保存队列job慢慢消费
redisOps.lPush(FetchPacsBase64Job.FETCH_PACS_BASE64_QUEUE_HIP1009, receiveMessage);
return updateSuccess(msgId, sender, receiver);
}
reportService.report(reportDto);
return updateSuccess(msgId, sender, receiver);
} catch (BaseException baseException) {
@ -63,20 +86,100 @@ public class HIP1009InspectionReportUpdatesHandler implements WebserviceReceiveS
}
public ReportDto fetchBase64Parse(XmlUtil inspectionInsertXmlUtil) {
Node senderNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1009/sender/device/id/item/@extension");
String updateBy = senderNode.getNodeValue();
Node inpatientNoNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.12']/@extension");
String inpatientNo = inpatientNoNode.getNodeValue();
Node admissTimesNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/recordTarget/patientRole/item[@root='1.2.156.112635.1.2.1.7']/@extension");
Integer admissTimes;
try {
admissTimes = Integer.valueOf(admissTimesNode.getNodeValue());
} catch (Exception ex) {
log.error(ex.getMessage(), ex);
admissTimes = null;
}
// 患者本次就诊唯一键患者id【12位】+就诊次数
Node visitSnNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.11']/@extension");
String visitSn = visitSnNode.getNodeValue();
// 患者id
Node patientSnNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/recordTarget/patientRole/item[@root='2.16.156.10011.0.2.2']/@extension");
String patientSn = patientSnNode.getNodeValue();
// 检查报告单号标识
Node reportFlagNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.32']/@extension");
String examReportSn = reportFlagNode.getNodeValue();
//电子申请单编号
Node eafNoNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.24']/@extension");
String requestSn = eafNoNode.getNodeValue();
Node fileTitleNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/component/structuredBody/component[@displayName='检查结果明细']/section/entry[@displayName='检查项目']/organizer/component[@displayName='检查项目']/observation/value");
String reportName = fileTitleNode.getTextContent();
if (admissTimes == null && isManualDocuments(requestSn)) {
admissTimes = getAdmissTimes(inpatientNo, inspectionInsertXmlUtil);
}
ReportDto reportDto = new ReportDto();
reportDto.setAdmisstimes(admissTimes);
reportDto.setInpatientNo(inpatientNo);
// 确定报告唯一 报告单号+申请单号,如果报告单号带下划线是合并报告,取报告单号下划线前的
String serialnum = examReportSn + requestSn;
reportDto.setFileTitle(reportName);
reportDto.setVisitSn(visitSn);
reportDto.setPatientSn(patientSn);
// 检查报告需要从Pacs接口获取base64
String[] split = examReportSn.split("_");
String fromPacs = shunDePeopleService.getBase64PdfFromPacs(split[0], split[1]);
// 从pacs打印出来
String base64 = reportJob.parsePacsGetBase64(fromPacs);
if (Func.isBlank(base64)) {
return null;
}
if (examReportSn.contains("_")) {
serialnum = split[0];
}
reportDto.setSerialnum(serialnum);
String url = reportJob.saveBase64(base64);
reportDto.setDownUrl(url);
reportDto.setDowntype(5);
// 根据系统来分类
reportDto.setAssortId(ZdAssortConfig.getZdAssortId(updateBy));
reportDto.setSysFlag(updateBy);
reportDto.setFileSource("1");
reportDto.setFilestoragetype("1");
reportDto.setMergeFileTitle(true);
return reportDto;
}
public ReportDto getReportDtoByInspectionUpdate(XmlUtil inspectionUpdateXmlUtil) {
Node senderNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/sender/device/id/item/@extension");
String sender = senderNode.getNodeValue();
String zdAssortId = ZdAssortConfig.getZdAssortId(sender);
if(Func.isBlank(zdAssortId)){
zdAssortId=ZdAssortConfig.getOtherAssortId();
if (Func.isBlank(zdAssortId)) {
zdAssortId = ZdAssortConfig.getOtherAssortId();
}
Node inpatientNoNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.12']/@extension");
String inpatientNo = inpatientNoNode.getNodeValue();
Node admissTimesNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/recordTarget/patientRole/item[@root='1.2.156.112635.1.2.1.7']/@extension");
Integer admissTimes = Integer.valueOf(admissTimesNode.getNodeValue());
Integer admissTimes;
try {
admissTimes = Integer.valueOf(admissTimesNode.getNodeValue());
} catch (Exception ex) {
log.error(ex.getMessage(), ex);
admissTimes = null;
}
// 检查报告单号标识
Node reportFlagNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.32']/@extension");
@ -85,6 +188,12 @@ public class HIP1009InspectionReportUpdatesHandler implements WebserviceReceiveS
Node eafNoNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.24']/@extension");
String eafNo = eafNoNode.getNodeValue();
String serialnum = reportFlag + "@" + eafNo;
// 如果报告单号带下划线是合并报告,取报告单号下划线前的,可能有个别来源不需要
List<String> ignoreUnderlineSenders= Arrays.asList("lungFunction-001","BL-001");
if (reportFlag.contains("_") && !ignoreUnderlineSenders.contains(sender)) {
String[] split = reportFlag.split("_");
serialnum = split[0];
}
// Node assortIdNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告']/section/entry[@displayName='检查类型']/observation/code/@displayName");
// String assortId = assortIdNode.getNodeValue();
@ -92,12 +201,17 @@ public class HIP1009InspectionReportUpdatesHandler implements WebserviceReceiveS
// Node sysFlagNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告']/section/entry[@displayName='检查类型']/observation/code/@displayName");
// String sysFlag = sysFlagNode.getNodeValue();
Node fileTitleNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告']/section/entry[@displayName='检查报告类型']/observation/code/@displayName");
String fileTitle = fileTitleNode.getNodeValue();
Node fileTitleNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/component/structuredBody/component[@displayName='检查结果明细']/section/entry[@displayName='检查项目']/organizer/component[@displayName='检查项目']/observation/value");
String fileTitle = fileTitleNode.getTextContent();
Node downUrlNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告图像']/report/entry[@displayName='检查报告图像URL地址']/observation/value");
String downUrl = downUrlNode.getTextContent();
if (admissTimes == null && isManualDocuments(eafNo)) {
admissTimes = getAdmissTimes(inpatientNo, inspectionUpdateXmlUtil);
}
ReportDto reportDto = new ReportDto();
reportDto.setReportSn(reportFlag);
@ -110,9 +224,36 @@ public class HIP1009InspectionReportUpdatesHandler implements WebserviceReceiveS
reportDto.setSysFlag(sender);
reportDto.setFileSource("1");
reportDto.setFilestoragetype("1");
reportDto.setMergeFileTitle(true);
return reportDto;
}
/**
*
*
* @param eafNo
* @return boolean
* @date 2024/1/9 14:38
* @author YongBin Wen
*/
private boolean isManualDocuments(String eafNo) {
return Func.isBlank(eafNo);
}
private Integer getAdmissTimes(String inpatientNo, XmlUtil inspectionInsertXmlUtil) {
try {
//检查报告日期 yyyyMMddHHmmss
String pattern = "yyyyMMddHHmmss";
Node reportTimeNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/author/time/@value");
String reportTime = reportTimeNode.getNodeValue();
Date reportDate = Func.parseDate(reportTime, pattern);
// 出院时间+3天匹配
int timeRangeAddedHour = 3 * 24;
return tBasicService.matchingAdmissTimesByInpNoAndReportTime(inpatientNo, reportDate, timeRangeAddedHour);
} catch (Exception ex) {
throw new BaseException("解析检查报告时间出错了!");
}
}
/**
*
@ -126,8 +267,8 @@ public class HIP1009InspectionReportUpdatesHandler implements WebserviceReceiveS
String createTime = Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI);
return "<MCCI_IN000002UV01 xmlns=\"urn:hl7-org:v3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ITSVersion=\"XML_1.0\" xsi:schemaLocation=\"urn:hl7-org:v3 file:///E:/hl7/HL7/v3ballot_fullsite_2011MAY/v3ballot/html/processable/multicacheschemas/MCCI _IN000002UV01.xsd\">" +
"<id extension=\""+ IdUtil.standardUUID()+"\"/>" +
"<creationTime value=\""+createTime+"\"/>" +
"<id extension=\"" + IdUtil.standardUUID() + "\"/>" +
"<creationTime value=\"" + createTime + "\"/>" +
"<interactionId root=\"2.16.840.1.113883.1.6\" extension=\"MCCI_IN000002UV01\"/>" +
"<processingCode code=\"P\"/>" +
"<processingModeCode/>" +
@ -148,7 +289,7 @@ public class HIP1009InspectionReportUpdatesHandler implements WebserviceReceiveS
"</sender>" +
"<acknowledgement typeCode=\"AA\">" +
"<targetMessage>" +
"<id extension=\""+msgId+"\"/>" +
"<id extension=\"" + msgId + "\"/>" +
"</targetMessage>" +
"<acknowledgementDetail>" +
"<text value=\"成功\"/>" +
@ -200,8 +341,8 @@ public class HIP1009InspectionReportUpdatesHandler implements WebserviceReceiveS
public String updateFailed(String msgId, String sender, String receiver, String failedMessage) {
String createTime = Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI);
return "<MCCI_IN000002UV01 xmlns=\"urn:hl7-org:v3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ITSVersion=\"XML_1.0\" xsi:schemaLocation=\"urn:hl7-org:v3 file:///E:/hl7/HL7/v3ballot_fullsite_2011MAY/v3ballot/html/processable/multicacheschemas/MCCI _IN000002UV01.xsd\">" +
"<id extension=\""+IdUtil.standardUUID()+"\"/>" +
"<creationTime value=\""+createTime+"\"/>" +
"<id extension=\"" + IdUtil.standardUUID() + "\"/>" +
"<creationTime value=\"" + createTime + "\"/>" +
"<interactionId root=\"2.16.840.1.113883.1.6\" extension=\"MCCI_IN000002UV01\"/>" +
"<processingCode code=\"P\"/>" +
"<processingModeCode/>" +
@ -222,10 +363,10 @@ public class HIP1009InspectionReportUpdatesHandler implements WebserviceReceiveS
"</sender>" +
"<acknowledgement typeCode=\"AE\">" +
"<targetMessage>" +
"<id extension=\""+msgId+"\"/>" +
"<id extension=\"" + msgId + "\"/>" +
"</targetMessage>" +
"<acknowledgementDetail>" +
"<text value=\""+failedMessage+"\"/>" +
"<text value=\"" + failedMessage + "\"/>" +
"</acknowledgementDetail>" +
"</acknowledgement>" +
"</MCCI_IN000002UV01>";

@ -0,0 +1,545 @@
package com.docus.server.report.webservice.impl;
import com.docus.core.util.DateUtil;
import com.docus.core.util.Func;
import com.docus.infrastructure.core.exception.BaseException;
import com.docus.server.collection.mapper.TBasicMapper;
import com.docus.server.report.config.SdRyReportQueryConfig;
import com.docus.server.report.service.ReportService;
import com.docus.server.report.util.IdUtil;
import com.docus.server.report.util.XmlUtil;
import com.docus.server.report.webservice.WebserviceMessageType;
import com.docus.server.report.webservice.WebserviceReceiveServerHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* HIP1008-
*
* @author jiahsi
*/
@Service(WebserviceMessageType.HIP1112)
@Slf4j
public class HIP1112RecallInspectionReportHandler implements WebserviceReceiveServerHandler {
@Resource
private ReportService reportService;
@Resource
private TBasicMapper tBasicMapper;
@Resource
private SdRyReportQueryConfig sdRyReportQueryConfig;
public static void main(String[] args) {
String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"\n" +
"<POOR_HIP1112 xmlns=\"urn:hl7-org:v3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ITSVersion=\"XML_1.0\" xsi:schemaLocation=\"urn:hl7-org:v3 ../multicacheschemas/POOR_IN200901UV.xsd\"> \n" +
" <!-- 消息ID --> \n" +
" <id extension=\"80ABD4579CC14D979BEFF422B58972F3\"/> \n" +
" <!-- 消息创建时间 --> \n" +
" <creationTime value=\"202502181107\"/> \n" +
" <!-- 交互ID --> \n" +
" <interactionId extension=\"POOR_IN200901UV23\"/> \n" +
" <!--消息用途: P(Production); D(Debugging); T(Training) --> \n" +
" <processingCode code=\"P\"/> \n" +
" <!-- 消息处理模式: A(Archive); I(Initial load); R(Restore from archive); T(Current\n" +
" processing) --> \n" +
" <processingModeCode code=\"R\"/> \n" +
" <!-- 消息应答: AL(Always); ER(Error/reject only); NE(Never) --> \n" +
" <acceptAckCode code=\"NE\"/> \n" +
" <!-- 接受者 --> \n" +
" <receiver typeCode=\"RCV\"> \n" +
" <device classCode=\"DEV\" determinerCode=\"INSTANCE\"> \n" +
" <!-- 接受者ID --> \n" +
" <id> \n" +
" <item root=\"\" extension=\"Orion-001\"/> \n" +
" </id> \n" +
" </device> \n" +
" </receiver> \n" +
" <!-- 发送者 --> \n" +
" <sender typeCode=\"SND\"> \n" +
" <device classCode=\"DEV\" determinerCode=\"INSTANCE\"> \n" +
" <!-- 发送者ID --> \n" +
" <id> \n" +
" <item root=\"\" extension=\"LIS\"/> \n" +
" </id> \n" +
" </device> \n" +
" </sender> \n" +
" <!-- 封装的消息内容(按Excel填写) --> \n" +
" <controlActProcess classCode=\"CACT\" moodCode=\"EVN\"> \n" +
" <!-- 消息交互类型 @code: 新增 :new 修改:update --> \n" +
" <code code=\"new\"/> \n" +
" <subject typeCode=\"SUBJ\" xsi:nil=\"false\"> \n" +
" <placerGroup> \n" +
" <!-- 1代表新增2代表更新--> \n" +
" <code/> \n" +
" <!-- 召回状态 必须项未使用 --> \n" +
" <statusCode code=\"1\"/> \n" +
" <!-- 患者信息 --> \n" +
" <subject typeCode=\"SBJ\"> \n" +
" <patient classCode=\"PAT\"> \n" +
" <id> \n" +
" <!--域ID --> \n" +
" <item root=\"1.2.156.10011.1.2.1.2\" extension=\"002120608400\"/> \n" +
" <!-- 患者ID --> \n" +
" <item root=\"2.16.156.10011.0.2.2\" extension=\"10143462\"/> \n" +
" <!--住院号标识--> \n" +
" <item root=\"2.16.156.10011.1.12\" extension=\"\"/> \n" +
" <!--门急诊号--> \n" +
" <item root=\"2.16.156.10011.1.11\" extension=\"10143462\"/> \n" +
" </id> \n" +
" <providerOrganization classCode=\"ORG\" determinerCode=\"INSTANCE\"> \n" +
" <!--报告科室编码--> \n" +
" <id> \n" +
" <item extension=\"\" root=\"1.2.156.10011.1.1.1\"/> \n" +
" </id> \n" +
" <!--报告科室名称 --> \n" +
" <name xsi:type=\"BAG_EN\"> \n" +
" <item> \n" +
" <part value=\"检验科\"/> \n" +
" </item> \n" +
" </name> \n" +
" <asOrganizationPartOf classCode=\"PART\"> \n" +
" <wholeOrganization determinerCode=\"INSTANCE\" classCode=\"ORG\"> \n" +
" <!--医疗机构代码 --> \n" +
" <id> \n" +
" <item extension=\"45608863-7\"/> \n" +
" </id> \n" +
" <!--医疗机构名称 --> \n" +
" <name xsi:type=\"BAG_EN\"> \n" +
" <item>\n" +
" <part value=\"南方医科大学顺德医院\"/>\n" +
" </item> \n" +
" </name> \n" +
" </wholeOrganization> \n" +
" </asOrganizationPartOf> \n" +
" </providerOrganization> \n" +
" </patient> \n" +
" </subject> \n" +
" <!--召回章节 如果多份报告召回,此处可循环--> \n" +
" <component> \n" +
" <!--召回报告号 检验/检查报告单号--> \n" +
" <id root=\"2.16.156.10011.1.32\" extension=\"20250214G0112502141040\"/> \n" +
" <!--召回关联申请单号--> \n" +
" <inFulfillmentOf> \n" +
" <order> \n" +
" <!-- 关联申请单号(可多个) --> \n" +
" <id extension=\"1\"/> \n" +
" <id extension=\"2\"/> \n" +
" <id extension=\"3\"/> \n" +
" <!--可多个,当还有需要关联的医嘱号时参照上述格式添加--> \n" +
" </order> \n" +
" </inFulfillmentOf> \n" +
" <!--报告属性 1代表检验、2代表PACS、3 内镜、4 静态心电、5 动态心电、6 病理、7 体检、8 Petct 9超声--> \n" +
" <reportAttribute extension=\"1\" displayName=\"报告属性\"/> \n" +
" <!--报告类型 013 微生物系统报告 007 检验系统报告--> \n" +
" <code code=\"007\" codeSystem=\"1.2.156.112672.1.1.27\"> \n" +
" <displayName value=\"检验系统报告\"/> \n" +
" </code> \n" +
" <!-- 报告召回信息 --> \n" +
" <performer typeCode=\"PRF\"> \n" +
" <time> \n" +
" <!-- 报告召回时间 --> \n" +
" <any value=\"\"/> \n" +
" </time> \n" +
" <assignedEntity classCode=\"ASSIGNED\"> \n" +
" <!-- 报告召回操作人编码 --> \n" +
" <id> \n" +
" <item extension=\"\" root=\"1.2.156.10011.1.1.2\"/> \n" +
" </id> \n" +
" <assignedPerson determinerCode=\"INSTANCE\" classCode=\"PSN\"> \n" +
" <!-- 报告召回操作人姓名 必须项已使用 --> \n" +
" <name xsi:type=\"BAG_EN\"> \n" +
" <item> \n" +
" <part value=\"\"/> \n" +
" </item> \n" +
" </name> \n" +
" </assignedPerson> \n" +
" </assignedEntity> \n" +
" </performer> \n" +
" <!--召回操作科室 --> \n" +
" <location typeCode=\"LOC\" xsi:nil=\"false\"> \n" +
" <!--必须项未使用 --> \n" +
" <time/> \n" +
" <!--就诊机构/科室 --> \n" +
" <serviceDeliveryLocation classCode=\"SDLOC\"> \n" +
" <serviceProviderOrganization determinerCode=\"INSTANCE\" classCode=\"ORG\"> \n" +
" <!--操作科室编码 --> \n" +
" <id> \n" +
" <item extension=\"30\" root=\"1.2.156.10011.1.1.1\"/> \n" +
" </id> \n" +
" <!--操作科室名称 --> \n" +
" <name xsi:type=\"BAG_EN\"> \n" +
" <item> \n" +
" <part value=\"检验室\"/> \n" +
" </item> \n" +
" </name> \n" +
" </serviceProviderOrganization> \n" +
" </serviceDeliveryLocation> \n" +
" </location> \n" +
" <!--召回原因--> \n" +
" <reason contextConductionInd=\"true\"> \n" +
" <observation moodCode=\"EVN\" classCode=\"OBS\"> \n" +
" <!-- 必须项 未使用--> \n" +
" <code/> \n" +
" <value xsi:type=\"ST\" value=\"报告状态修改\"/> \n" +
" </observation> \n" +
" </reason> \n" +
" </component> \n" +
" <!--就诊 --> \n" +
" <componentOf1 contextConductionInd=\"false\" xsi:nil=\"false\" typeCode=\"COMP\"> \n" +
" <!--就诊 --> \n" +
" <encounter classCode=\"ENC\" moodCode=\"EVN\"> \n" +
" <id> \n" +
" <!-- 就诊次数 必须项已使用 --> \n" +
" <item extension=\"6\" root=\"1.2.156.10011.1.2.1.7\"/> \n" +
" <!-- 就诊流水号 --> \n" +
" <item extension=\"10143462\" root=\"1.2.156.10011.1.2.1.6\"/> \n" +
" </id> \n" +
" <!--就诊类别编码 1:门诊2:急诊3:住院4:体检9:其他;--> \n" +
" <code codeSystem=\"1.2.156.10011.1.1.80\" code=\"3\"> \n" +
" <!-- 就诊类别名称 --> \n" +
" <displayName value=\"住院\"/> \n" +
" </code> \n" +
" <!--必须项未使用 --> \n" +
" <statusCode code=\"Active\"/> \n" +
" <!--病人(必须项未使用) --> \n" +
" <subject typeCode=\"SBJ\"> \n" +
" <patient classCode=\"PAT\"/> \n" +
" </subject> \n" +
" </encounter> \n" +
" </componentOf1> \n" +
" </placerGroup> \n" +
" </subject> \n" +
" </controlActProcess> \n" +
"</POOR_HIP1112>\n";
new HIP1112RecallInspectionReportHandler().handle(xml);
}
@Override
public String handle(String receiveMessage) {
log.info("检查/检验召回推送:{}", receiveMessage);
String msgId = "";
String sender = "";
String receiver = "";
try {
XmlUtil xmlUtil = XmlUtil.of(receiveMessage);
msgId = xmlUtil.getNode("/POOR_HIP1112/id/@extension").getNodeValue();
sender = xmlUtil.getNode("/POOR_HIP1112/sender/device/id/item/@extension").getNodeValue();
receiver = xmlUtil.getNode("/POOR_HIP1112/receiver/device/id/item/@extension").getNodeValue();
String mzFlag = "1";
String zyFlag = "3";
String flag = xmlUtil.getNode("/POOR_HIP1112/controlActProcess/subject/placerGroup/componentOf1/encounter/code/@code").getNodeValue();
if (zyFlag.equals(flag)) {
handleZy(xmlUtil, sender);
} else if (mzFlag.equals(flag)) {
handleMz(xmlUtil, sender);
}
return success(msgId, sender, receiver);
} catch (BaseException baseException) {
log.error(baseException.getMessage(), baseException);
return failed(msgId, sender, receiver, baseException.getMessage());
} catch (Exception ex) {
log.error(ex.getMessage(), ex);
return failed(msgId, sender, receiver, "系统错误!");
}
}
private void handleMz(XmlUtil xmlUtil, String sender) {
String reportQueryMzInspectCollectorId = sdRyReportQueryConfig.getReportQueryMzInspectCollectorId();
String reportQueryLisCollectorId = sdRyReportQueryConfig.getReportQueryLisCollectorId();
// 处理门诊的
String sdryIndex;
int admissTimes;
String patientId;
Node sdryIndexNode = xmlUtil.getNode("/POOR_HIP1112/controlActProcess/subject/placerGroup/subject/patient/id/item[@root='1.2.156.10011.1.2.1.2']/@extension");
if (Objects.isNull(sdryIndexNode)) {
throw new BaseException("未找到域id节点");
}
sdryIndex = sdryIndexNode.getNodeValue();
if (Func.isBlank(sdryIndex)) {
throw new BaseException("域ID解析为空");
}
Node admissTimesNode = xmlUtil.getNode("/POOR_HIP1112/controlActProcess/subject/placerGroup/componentOf1/encounter/id/item[@root='1.2.156.10011.1.2.1.7']/@extension");
if (Objects.isNull(admissTimesNode)) {
throw new BaseException("未找到就诊次数节点!");
}
try {
admissTimes = Integer.parseInt(admissTimesNode.getNodeValue());
} catch (Exception ex) {
throw new BaseException("无法解析就诊次数!");
}
if (admissTimes <= 0) {
throw new BaseException("就诊次数解析不正常应该为大于0的数字");
}
try {
// patientId = tBasicMapper.getPatientIdByInpatientNoAndAdminssTimes(inpatientNo, admissTimes);
patientId = tBasicMapper.getPatientIdBySdRyIndexAndAdmissTimes(sdryIndex, admissTimes + "");
} catch (Exception ex) {
// log.error("门诊检查/检验召回,根据门急诊号:" + mzjNo + ",和就诊次数:" + admissTimes + ",无法匹配正确的患者!" + ex.getMessage(), ex);
log.error("门诊检查/检验召回根据域id" + sdryIndex + "无法匹配正确的患者!" + ex.getMessage(), ex);
return;
}
if (Func.isBlank(patientId)) {
log.error("门诊检查/检验召回根据域id" + sdryIndex + "无法匹配正确的患者!");
return;
}
String jy = "1";
String jc = "2";
String reportAttribute = xmlUtil.getNode("/POOR_HIP1112/controlActProcess/subject/placerGroup/component/reportAttribute/@extension").getNodeValue();
Node reportFlagNode = xmlUtil.getNode("/POOR_HIP1112/controlActProcess/subject/placerGroup/component/id[@root='2.16.156.10011.1.32']/@extension");
String reportFlag = reportFlagNode.getNodeValue();
if (Func.isBlank(reportFlag)) {
throw new BaseException("报告单号为空!");
}
NodeList requestNoNodes = xmlUtil.getNodeList("/POOR_HIP1112/controlActProcess/subject/placerGroup/component/inFulfillmentOf/order/id/@extension");
int length = requestNoNodes.getLength();
if (length > 0) {
for (int i = 0; i < length; i++) {
Node item = requestNoNodes.item(i);
String requestNo = item.getNodeValue();
if (jc.equals(reportAttribute)) {
String jianChaFileSerialnum = getJcFileSerialnum(reportFlag, requestNo, sender);
reportService.cancel(patientId, reportQueryMzInspectCollectorId, jianChaFileSerialnum);
}
if (jy.equals(reportAttribute)) {
String jianYanFileSerialnum = getMzJyFileSerialnum(reportFlag, requestNo);
if (Func.isNotBlank(jianYanFileSerialnum)) {
reportService.cancel(patientId, reportQueryLisCollectorId, jianYanFileSerialnum);
}
}
}
} else {
if (jc.equals(reportAttribute)) {
String jianChaFileSerialnum = getJcFileSerialnum(reportFlag, null, sender);
if (Func.isNotBlank(jianChaFileSerialnum)) {
reportService.cancel(patientId, reportQueryMzInspectCollectorId, jianChaFileSerialnum);
}
}
}
}
private void handleZy(XmlUtil xmlUtil, String sender) {
// 处理住院
String sdryIndex;
int admissTimes;
String patientId;
String sysFlag = sender;
Node sdryIndexNode = xmlUtil.getNode("/POOR_HIP1112/controlActProcess/subject/placerGroup/subject/patient/id/item[@root='1.2.156.10011.1.2.1.2']/@extension");
if (Objects.isNull(sdryIndexNode)) {
throw new BaseException("未找到域id节点");
}
sdryIndex = sdryIndexNode.getNodeValue();
if (Func.isBlank(sdryIndex)) {
throw new BaseException("域ID解析为空");
}
Node admissTimesNode = xmlUtil.getNode("/POOR_HIP1112/controlActProcess/subject/placerGroup/componentOf1/encounter/id/item[@root='1.2.156.10011.1.2.1.7']/@extension");
if (Objects.isNull(admissTimesNode)) {
throw new BaseException("未找到住院次数节点!");
}
try {
admissTimes = Integer.parseInt(admissTimesNode.getNodeValue());
} catch (Exception ex) {
throw new BaseException("无法解析住院次数!");
}
if (admissTimes <= 0) {
throw new BaseException("住院次数解析不正常应该为大于0的数字");
}
try {
patientId = tBasicMapper.getPatientIdBySdRyIndexAndAdmissTimes(sdryIndex, admissTimes + "");
} catch (Exception ex) {
log.error("住院检查/检验召回根据域ID" + sdryIndex + ",和住院次数:" + admissTimes + ",无法匹配正确的患者!" + ex.getMessage(), ex);
return;
}
if (Func.isBlank(patientId)) {
log.error("住院检查/检验召回根据域ID" + sdryIndex + ",和住院次数:" + admissTimes + ",无法匹配正确的患者!");
return;
}
String jy = "1";
String jc = "2";
String reportAttribute = xmlUtil.getNode("/POOR_HIP1112/controlActProcess/subject/placerGroup/component/reportAttribute/@extension").getNodeValue();
Node reportFlagNode = xmlUtil.getNode("/POOR_HIP1112/controlActProcess/subject/placerGroup/component/id[@root='2.16.156.10011.1.32']/@extension");
String reportFlag = reportFlagNode.getNodeValue();
if (Func.isBlank(reportFlag)) {
throw new BaseException("报告单号为空!");
}
NodeList requestNoNodes = xmlUtil.getNodeList("/POOR_HIP1112/controlActProcess/subject/placerGroup/component/inFulfillmentOf/order/id/@extension");
int length = requestNoNodes.getLength();
if (length > 0) {
for (int i = 0; i < length; i++) {
Node item = requestNoNodes.item(i);
String requestNo = item.getNodeValue();
if (jc.equals(reportAttribute)) {
String jianChaFileSerialnum = getJcFileSerialnum(reportFlag, requestNo, sender);
reportService.cancel(patientId, sysFlag, jianChaFileSerialnum);
}
if (jy.equals(reportAttribute)) {
String jianYanFileSerialnum = getZyJyFileSerialnum(reportFlag, requestNo);
reportService.cancel(patientId, sysFlag, jianYanFileSerialnum);
}
}
} else {
if (jc.equals(reportAttribute)) {
String jianChaFileSerialnum = getJcFileSerialnum(reportFlag, null, sender);
if (Func.isNotBlank(jianChaFileSerialnum)) {
reportService.cancel(patientId, sysFlag, jianChaFileSerialnum);
}
}
}
}
/**
* @param reportFlag
* @param requestNo
* @param sender
* @return id
*/
private String getJcFileSerialnum(String reportFlag, String requestNo, String sender) {
// 如果报告单号带下划线是合并报告,取报告单号下划线前的,可能有个别来源不需要
List<String> ignoreUnderlineSenders = Arrays.asList("lungFunction-001", "BL-001");
boolean splitCondition = reportFlag.contains("_") && !ignoreUnderlineSenders.contains(sender);
if (splitCondition) {
String[] split = reportFlag.split("_");
return split[0];
}
if (Objects.isNull(requestNo)) {
return null;
}
return reportFlag + "@" + requestNo;
}
/**
* @param reportFlag
* @param requestNo
* @return id
*/
private String getZyJyFileSerialnum(String reportFlag, String requestNo) {
return reportFlag + "@" + requestNo;
}
/**
* @param reportFlag
* @param requestNo
* @return id
*/
private String getMzJyFileSerialnum(String reportFlag, String requestNo) {
if (Objects.isNull(requestNo)) {
return null;
}
return reportFlag + requestNo;
}
/**
*
*
* @param msgId id
* @param sender
* @param receiver
* @return
*/
public String success(String msgId, String sender, String receiver) {
String createTime = Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI);
return "<MCCI_IN000002UV01 xmlns=\"urn:hl7-org:v3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ITSVersion=\"XML_1.0\" xsi:schemaLocation=\"urn:hl7-org:v3 file:///E:/hl7/HL7/v3ballot_fullsite_2011MAY/v3ballot/html/processable/multicacheschemas/MCCI _IN000002UV01.xsd\">" +
"<id extension=\"" + IdUtil.standardUUID() + "\"/>" +
"<creationTime value=\"" + createTime + "\"/>" +
"<interactionId root=\"2.16.840.1.113883.1.6\" extension=\"MCCI_IN000002UV01\"/>" +
"<processingCode code=\"P\"/>" +
"<processingModeCode/>" +
"<acceptAckCode code=\"AL\"/>" +
"<receiver typeCode=\"RCV\">" +
"<device classCode=\"DEV\" determinerCode=\"INSTANCE\">" +
"<id>" +
"<item extension=\"Orion-001\"/>" +
"</id>" +
"</device>" +
"</receiver>" +
"<sender typeCode=\"SND\">" +
"<device classCode=\"DEV\" determinerCode=\"INSTANCE\">" +
"<id>" +
"<item extension=\"PaperlessManagementMRIS-001\"/>" +
"</id>" +
"</device>" +
"</sender>" +
"<acknowledgement typeCode=\"AA\">" +
"<targetMessage>" +
"<id extension=\"" + msgId + "\"/>" +
"</targetMessage>" +
"<acknowledgementDetail>" +
"<text value=\"成功\"/>" +
"</acknowledgementDetail>" +
"</acknowledgement>" +
"</MCCI_IN000002UV01>";
}
/**
*
*
* @param msgId id
* @param sender
* @param receiver
* @return
*/
public String failed(String msgId, String sender, String receiver, String failedMessage) {
String createTime = Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI);
return "<MCCI_IN000002UV01 xmlns=\"urn:hl7-org:v3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ITSVersion=\"XML_1.0\" xsi:schemaLocation=\"urn:hl7-org:v3 file:///E:/hl7/HL7/v3ballot_fullsite_2011MAY/v3ballot/html/processable/multicacheschemas/MCCI _IN000002UV01.xsd\">" +
"<id extension=\"" + IdUtil.standardUUID() + "\"/>" +
"<creationTime value=\"" + createTime + "\"/>" +
"<interactionId root=\"2.16.840.1.113883.1.6\" extension=\"MCCI_IN000002UV01\"/>" +
"<processingCode code=\"P\"/>" +
"<processingModeCode/>" +
"<acceptAckCode code=\"AL\"/>" +
"<receiver typeCode=\"RCV\">" +
"<device classCode=\"DEV\" determinerCode=\"INSTANCE\">" +
"<id>" +
"<item extension=\"Orion-001\"/>" +
"</id>" +
"</device>" +
"</receiver>" +
"<sender typeCode=\"SND\">" +
"<device classCode=\"DEV\" determinerCode=\"INSTANCE\">" +
"<id>" +
"<item extension=\"PaperlessManagementMRIS-001\"/>" +
"</id>" +
"</device>" +
"</sender>" +
"<acknowledgement typeCode=\"AE\">" +
"<targetMessage>" +
"<id extension=\"" + msgId + "\"/>" +
"</targetMessage>" +
"<acknowledgementDetail>" +
"<text value=\"" + failedMessage + "\"/>" +
"</acknowledgementDetail>" +
"</acknowledgement>" +
"</MCCI_IN000002UV01>";
}
}

@ -66,4 +66,9 @@ public class SdryReportServerImpl implements IReportServer {
public String pushMaternalInfantRelationship(String maternalInfantRelationshipMessage) {
return webserviceReceiveServerHandler.get(WebserviceMessageType.HIP1264).handle(maternalInfantRelationshipMessage);
}
@Override
public String pushRecallInspectionReport(String recallInspectionReportMessage) {
return webserviceReceiveServerHandler.get(WebserviceMessageType.HIP1112).handle(recallInspectionReportMessage);
}
}

@ -41,7 +41,7 @@ spring:
shared-configs:
- comm.${spring.cloud.nacos.config.file-extension}
profiles:
active: dev
active: test
sdry:
# 顺德人医查询检查、检验报告之前查患者交叉索引的wsdl配置
@ -90,7 +90,14 @@ sdry:
url: http://127.0.0.1:9314/hospital/sdRy/getBloodView
# js-table-type 中配置的文件分段
defaultAssortType: blood
# 量表
liangbiao:
# 量表报告采集器队列
collectorId: 1008611
# 量表的
url: http://192.168.8.251:8080/hiswscom/wsdl/IgetHisData?wsdl
# js-table-type 中配置的文件分段
defaultAssortType: liangbiao
docus:
@ -100,6 +107,7 @@ docus:
user:
# 用户默认密码
defpwd: fd29cd53ec12616e5f36b77d4afffbff
powerdeptroles:
report:
downurl: http://localhost:9291/api/downplatform/report
# 质控时间,分钟
@ -112,6 +120,13 @@ docus:
nisApproveUrl: http://192.168.16.85:9102/qc/tBasicCqc/cqcAudit?hp=token1
# 确认重症状态并更新
confirmAndUpdIcuRecordStateUrl: http://127.0.0.1:9314/hospital/sdRy/confirmAndupdIcuRecordState
# 电子病例护理重症护理解档配置id
pushconfig: 8,9,12
#推送操作人工号,姓名
pushusername: 05908
pushname: 可信病案归档
#解档天数
day: 90
mybatis-plus:
configuration:
map-underscore-to-camel-case: true

@ -26,26 +26,6 @@
<MaxHistory>30</MaxHistory>
</rollingPolicy>
</appender>
<appender name="external-interface" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<!-- 指定日志输出格式 -->
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%X{traceId}] [%L] [%-5p] %m%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 指定收集策略:滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--指定生成日志保存地址 -->
<fileNamePattern>${log.path}external%d.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>500MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
</appender>
<logger name="com.docus.services.system.service.ClientGetBasicServiceImpl" level="DEBUG" additivity="false">
<appender-ref ref="external-interface" />
</logger>
<springProfile name="dev">

@ -5,9 +5,24 @@
<mapper namespace="com.docus.server.report.mapper.AfCollectTaskMapper">
<insert id="saveTask">
INSERT INTO `docus_archivefile`.`af_collect_task`(`id`, `patient_id`, `sysflag`,
`state`, `C1`,`C2`, `C3`)
VALUES (#{task.id}, #{task.patientId}, #{task.sysflag}, '0', #{task.C1}, #{task.C2}, #{task.C3});
`state`, `C1`,`C2`, `C3`,`create_time`)
VALUES (#{task.id}, #{task.patientId}, #{task.sysflag}, '0', #{task.C1}, #{task.C2}, #{task.C3},#{task.createTime});
</insert>
<update id="updateNewSubmit">
update `docus_archivefile`.`af_collect_task`
set c1=#{c1},
c2=#{c2},
state=0,
recollect_time=now()
where `id` = #{id}
</update>
<delete id="cancelFile">
update `docus_archivefile`.`t_scan_assort`
set is_del=1
where `patient_id` = #{patientId}
and source= #{sysFlag}
and file_column_1= #{serialnum}
</delete>
<select id="getTaskById" resultType="com.docus.server.report.entity.AfCollectTask">
select *

@ -0,0 +1,30 @@
<?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="com.docus.server.collection.mapper.CqcPushConfigMapper">
<select id="getCqcPushConfigByBusinessTypes" resultType="com.docus.server.collection.entity.CqcPushConfig">
SELECT
id,
business_type,
protocol_type,
namespace,
url,
method,
effective,
title,
create_user,
create_time,
update_user,
update_time,
parameter_list
FROM
cqc_push_config
WHERE id in
<foreach collection="ids" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
AND effective=1
</select>
</mapper>

@ -0,0 +1,56 @@
<?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="com.docus.server.report.mapper.DelayedMessagesMapper">
<insert id="insert">
INSERT INTO
`docus_medicalrecord`.`delayed_messages` (`id`, `message_type`, `keyword`, `message`, `next_execution_time`, `delay_seconds`, `create_time`, `retries`, `error_message`)
VALUES (#{message.id}, #{message.messageType}, #{message.keyword}, #{message.message}, #{message.nextExecutionTime}, #{message.delaySeconds}, #{message.createTime}, 0, #{message.errorMessage})
</insert>
<update id="updateById">
UPDATE `docus_medicalrecord`.`delayed_messages`
SET
`message_type` = #{message.messageType},
`keyword` = #{message.keyword},
`message` = #{message.message},
`next_execution_time` = #{message.nextExecutionTime},
`delay_seconds` = #{message.delaySeconds},
`create_time` = #{message.createTime},
`retries` = #{message.retries},
`error_message` = #{message.errorMessage}
WHERE `id` = #{message.id}
</update>
<delete id="delById">
DELETE FROM `docus_medicalrecord`.`delayed_messages` WHERE `id`=#{id}
</delete>
<select id="findExecutableMessages" resultType="com.docus.server.report.entity.DelayedMessages">
select
*
from
`docus_medicalrecord`.`delayed_messages`
where
`next_execution_time` <![CDATA[<=]]> #{currentDateTime}
<if test="condition.keyword != null and condition.keyword != '' ">
and `keyword` = #{condition.keyword}
</if>
<if test="condition.messageType != null and condition.messageType != '' ">
and `message_type` = #{condition.messageType}
</if>
</select>
<select id="findMessage" resultType="com.docus.server.report.entity.DelayedMessages">
select
*
from
`docus_medicalrecord`.`delayed_messages`
where
1=1
<if test="condition.keyword != null and condition.keyword != '' ">
and `keyword` = #{condition.keyword}
</if>
<if test="condition.messageType != null and condition.messageType != '' ">
and `message_type` = #{condition.messageType}
</if>
</select>
</mapper>

@ -26,6 +26,7 @@
`user_position`=#{user.position},
`user_tel`=#{user.telephone},
`name`=#{user.name},
`power_dept`=#{user.powerDept},
`update_date`=now()
where `user_id`=#{user.userId}
</update>
@ -33,8 +34,16 @@
delete from `docus_system`.`power_user` where `user_name` = #{userName}
</delete>
<update id="cancelUserByUserName">
update `docus_system`.`power_user`
set `account_state`=2,
`enabled`=0,
`effective`=0
where `user_name` = #{userName}
</update>
<select id="getUserByUserName" resultType="com.docus.server.collection.entity.PowerUser">
SELECT `user_id`,`user_name`,`user_pwd` FROM `docus_system`.`power_user`
SELECT `user_id`,`user_name`,`user_pwd`,`power_dept`,`role_id` FROM `docus_system`.`power_user`
WHERE `user_name` = #{userName} LIMIT 1
</select>
</mapper>

@ -0,0 +1,11 @@
<?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="com.docus.server.common.mapper.RemoteCallResultMapper">
<insert id="save">
INSERT INTO `docus_archivefile`.`remote_call_result`(`id`, `keyword`, `url`, `header`, `request`, `response`, `remark`, `description`, `request_storage_type`, `response_storage_type`, `call_status`, `call_start_time`, `call_end_time`)
VALUES (#{result.id}, #{result.keyword}, #{result.url}, #{result.header}, #{result.request}, #{result.response}, #{result.remark}, #{result.description}, #{result.requestStorageType}, #{result.responseStorageType}, #{result.callStatus}, #{result.callStartTime}, #{result.callEndTime})
</insert>
</mapper>

@ -0,0 +1,38 @@
<?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="com.docus.server.common.mapper.SdryPacsPrintExceptMapper">
<insert id="saveExcept">
INSERT INTO `docus_archivefile`.`sdry_pacs_print_except`(`id`, `inpatient_no`, `admiss_times`, `jzh`, `report_message_path`, `state`, `create_time`, `service_flag`,`exam_report_sn`)
VALUES (#{except.id}, #{except.inpatientNo}, #{except.admissTimes}, #{except.jzh}, #{except.reportMessagePath}, 0, #{except.createTime}, #{except.serviceFlag},#{except.examReportSn})
</insert>
<update id="compensateSuccuss">
update
`docus_archivefile`.`sdry_pacs_print_except`
set `state`=1
where id=#{id}
</update>
<select id="getById" resultType="com.docus.server.common.entity.SdryPacsPrintExcept">
select
`id`,
`inpatient_no`,
`admiss_times`,
`jzh`,
`report_message_path`,
`state`,
`create_time`,
`service_flag`
from `docus_archivefile`.`sdry_pacs_print_except`
where id=#{id}
</select>
<select id="getCompensateIds" resultType="java.lang.Long">
select
`id`
from
`docus_archivefile`.`sdry_pacs_print_except`
where `state`=0 and `create_time` > #{beginDateTime}
</select>
</mapper>

@ -7,6 +7,75 @@
delete from `docus_medicalrecord`.`t_basic`
where `patient_id`=#{patientId};
</delete>
<update id="cancelHospital">
UPDATE `docus_medicalrecord`.`t_basic`
<set>
<if test="tBasic.admissDays !=null ">
`admiss_days`=#{tBasic.admissDays},
</if>
<if test="tBasic.isDead !=null ">
`is_dead`=#{tBasic.isDead},
</if>
<if test="tBasic.sexName !=null ">
`sex_name`=#{tBasic.sexName},
</if>
<if test="tBasic.bedNum !=null ">
`bed_num`=#{tBasic.bedNum},
</if>
<if test="tBasic.age !=null ">
`age`=#{tBasic.age},
</if>
<if test="tBasic.sex !=null ">
`sex`=#{tBasic.sex},
</if>
<if test="tBasic.idCard !=null ">
`id_card`=#{tBasic.idCard},
</if>
<if test="tBasic.disDept !=null ">
`dis_dept`=#{tBasic.disDept},
</if>
<if test="tBasic.admissTimes !=null ">
`admiss_times`=#{tBasic.admissTimes},
</if>
<if test="tBasic.inpatientNo !=null ">
`inpatient_no`=#{tBasic.inpatientNo},
</if>
<if test="tBasic.name !=null ">
`name`=#{tBasic.name},
</if>
<if test="tBasic.admissDate !=null ">
`admiss_date`=#{tBasic.admissDate},
</if>
<if test="tBasic.admissDeptName !=null ">
`admiss_dept`=#{tBasic.admissDept},
</if>
<if test="tBasic.admissDeptName !=null ">
`admiss_dept_name`=#{tBasic.admissDeptName},
</if>
<if test="tBasic.disDeptName !=null ">
`dis_dept_name`=#{tBasic.disDeptName},
</if>
<if test="tBasic.attending !=null ">
`attending`=#{tBasic.attending},
</if>
<if test="tBasic.attendingName !=null ">
`attending_name`=#{tBasic.attendingName},
</if>
<if test="tBasic.wardCode !=null ">
`ward_code`=#{tBasic.wardCode},
</if>
<if test="tBasic.wardName !=null ">
`ward_name`=#{tBasic.wardName},
</if>
<if test="tBasic.isOther !=null ">
`is_other`=#{tBasic.isOther},
</if>
b_column5=CONCAT(inpatient_no,'_',admiss_times),
`dis_date`=#{tBasic.disDate},
`update_time`=now()
</set>
WHERE `patient_id`=#{tBasic.patientId,jdbcType=VARCHAR};
</update>
<select id="getPatientIdByInpatientNoAndAdminssTimes" resultType="java.lang.String">
select `patient_id`
@ -28,9 +97,9 @@
</insert>
<insert id="insertExtend">
INSERT INTO `docus_medicalrecord`.`t_basic_extend`
(`patient_id`,`ward_code`,`ward_name`,`sdry_index`)
(`patient_id`,`ward_code`,`ward_name`,`sdry_index`,`leave_method`)
VALUES
(#{tBasicExtend.patientId},#{tBasicExtend.wardCode},#{tBasicExtend.wardName},#{tBasicExtend.sdryIndex})
(#{tBasicExtend.patientId},#{tBasicExtend.wardCode},#{tBasicExtend.wardName},#{tBasicExtend.sdryIndex},#{tBasicExtend.leaveMethod})
</insert>
<insert id="saveNisRemoveFilesCount">
INSERT INTO `docus_medicalrecord`.`t_basic_extend`
@ -85,9 +154,6 @@
<if test="tBasic.admissDeptName !=null ">
`admiss_dept_name`=#{tBasic.admissDeptName},
</if>
<if test="tBasic.disDate !=null ">
`dis_date`=#{tBasic.disDate},
</if>
<if test="tBasic.disDeptName !=null ">
`dis_dept_name`=#{tBasic.disDeptName},
</if>
@ -107,6 +173,9 @@
`is_other`=#{tBasic.isOther},
</if>
b_column5=CONCAT(inpatient_no,'_',admiss_times),
<if test="tBasic.disDate !=null ">
`dis_date`=#{tBasic.disDate},
</if>
`update_time`=now()
</set>
WHERE `patient_id`=#{tBasic.patientId,jdbcType=VARCHAR};
@ -114,18 +183,29 @@
<update id="updateExtend">
INSERT INTO `docus_medicalrecord`.`t_basic_extend`
(`patient_id`,`ward_code`,`ward_name`,`sdry_index`)
(`patient_id`,`ward_code`,`ward_name`,`sdry_index`,leave_method)
VALUES
(#{tBasicExtend.patientId},#{tBasicExtend.wardCode},#{tBasicExtend.wardName},#{tBasicExtend.sdryIndex})
(#{tBasicExtend.patientId},#{tBasicExtend.wardCode},#{tBasicExtend.wardName},#{tBasicExtend.sdryIndex},#{tBasicExtend.leaveMethod})
on DUPLICATE KEY UPDATE
`ward_code`=#{tBasicExtend.wardCode},
`ward_name`=#{tBasicExtend.wardName},
<if test="tBasicExtend.leaveMethod != null and tBasicExtend.leaveMethod != ''">
leave_method=#{tBasicExtend.leaveMethod},
</if>
`sdry_index`=#{tBasicExtend.sdryIndex}
</update>
<update id="updateNursCollectState">
UPDATE `docus_medicalrecord`.`t_basic` set nurs_collect = #{state}
where patient_id=#{patientId}
</update>
<update id="setBedDoctor">
UPDATE `docus_medicalrecord`.`t_basic` set bed_doctor = #{bedDoctor},
bed_doctor_name = #{bedDoctorName}
where patient_id in
<foreach collection="patientIds" open="(" close=")" separator="," item="val">
#{val}
</foreach>
</update>
<select id="selectOne" resultType="java.lang.Integer">
select count(patient_id) from t_basic where jzh=#{jzh}
@ -206,15 +286,17 @@
from `docus_medicalrecord`.`t_basic_extend`
WHERE patient_id=#{patientId}
</select>
<select id="getParentSdRyIndex" resultType="java.lang.String">
SELECT mom_id
<select id="getMaternalInfantRelationship" resultType="com.docus.server.report.entity.MaternalInfantRelationship">
SELECT *
FROM `docus_medicalrecord`.`t_maternal_infant_relationship`
where baby_id=#{babyIndex}
</select>
<select id="getPatientIdBySdRyIndex" resultType="java.lang.String">
select patient_id
<select id="getPatientIdBySdRyIndexAndAdmissTimes" resultType="java.lang.String">
select t_basic_extend.patient_id
from `docus_medicalrecord`.`t_basic_extend`
WHERE sdry_index=#{sdRyIndex}
INNER JOIN docus_medicalrecord.t_basic ON t_basic_extend.patient_id = t_basic.patient_id
WHERE t_basic_extend.sdry_index = #{sdRyIndex}
and t_basic.admiss_times = #{admissTimes}
</select>
<select id="getByPatientId" resultType="com.docus.server.collection.entity.TBasic">
select *
@ -229,5 +311,28 @@
<select id="getNameByUserName" resultType="java.lang.String">
select `name` from docus_system.power_user where user_name=#{userName}
</select>
<select id="getAdmissTimesByInpNoAndReportTime" resultType="java.lang.Integer">
select admiss_times
from `docus_medicalrecord`.`t_basic`
where inpatient_no=#{inpatientNo}
and #{reportTime} BETWEEN admiss_date and dis_date
</select>
<select id="selectBasicListByInpNo" resultType="com.docus.server.collection.entity.TBasic">
select
*
from
`docus_medicalrecord`.`t_basic`
where inpatient_no=#{inpNo}
</select>
<select id="getPatientIds" resultType="java.lang.String">
select patient_id from t_basic
where inpatient_no=#{inpatientNo}
and admiss_times=#{admissTimes}
</select>
<delete id="deleteExtend">
delete from `docus_medicalrecord`.`t_basic_extend`
where `patient_id`=#{patientId};
</delete>
</mapper>

Loading…
Cancel
Save