Commit 49a85d44 authored by 向怀芳's avatar 向怀芳 🎱

Merge remote-tracking branch 'origin/hpgp' into hpgp

# Conflicts:
#	cloud-common/cloud-common-core/src/main/java/cn/sh/stc/sict/cloud/common/core/constant/RedisCacheConstant.java
parents 02a06796 edc1fe66
......@@ -36,6 +36,10 @@ public class RedisCacheConstant {
/**
* 验证码前缀
*/
public static final String DEFAULT_CODE_KEY = "SICT_DEFAULT_CODE_KEY_";
public static final String DEPT_NUM_SOURCE_RESULT = "dept_num_source_result";
public static final String DEFAULT_CODE_KEY = APP + "SICT_DEFAULT_CODE_KEY_";
public static final String LOGIN_ERROR_TIMES = APP + "login_error_times";
}
......@@ -12,6 +12,7 @@ public class WDUserInfo {
private String token;
private String id;
private String username;
private String name;
private String personcard;
private String mobile;
private Date birth;
......
......@@ -2,17 +2,16 @@ package cn.sh.stc.sict.cloud.upms.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.sh.stc.sict.cloud.common.core.constant.Constant;
import cn.sh.stc.sict.cloud.common.core.constant.UserConstant;
import cn.sh.stc.sict.cloud.common.core.constant.enums.LoginTypeEnum;
import cn.sh.stc.sict.cloud.common.core.dto.WDUserCardInfo;
import cn.sh.stc.sict.cloud.common.core.dto.WDUserInfo;
import cn.sh.stc.sict.cloud.common.core.util.NumberUtil;
import cn.sh.stc.sict.cloud.common.core.util.SsbUtil;
import cn.sh.stc.sict.cloud.upms.dao.SysUserBaseMapper;
import cn.sh.stc.sict.cloud.upms.dto.UserDTO;
import cn.sh.stc.sict.cloud.upms.dto.UserInfo;
import cn.sh.stc.sict.cloud.upms.model.HpUserRole;
import cn.sh.stc.sict.cloud.upms.model.SysUserBase;
import cn.sh.stc.sict.cloud.upms.service.HpUserRoleService;
import cn.sh.stc.sict.cloud.upms.service.SysUserBaseService;
......@@ -28,8 +27,6 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.List;
@Slf4j
@Service("sysUserBaseService")
@AllArgsConstructor
......@@ -74,6 +71,7 @@ public class SysUserBaseServiceImpl extends ServiceImpl<SysUserBaseMapper, SysUs
private UserInfo getBySSBToken(String source, String token) {
WDUserInfo wdUser = SsbUtil.getUserInfo(token);
log.error("ssb.login.wdUser = {}", JSONUtil.toJsonStr(wdUser));
if (ObjectUtil.isNull(wdUser) || StrUtil.isBlank(wdUser.getMobile())) {
return null;
}
......@@ -83,9 +81,9 @@ public class SysUserBaseServiceImpl extends ServiceImpl<SysUserBaseMapper, SysUs
// 未注册用户默认注册
if (user == null) {
user = new SysUserBase();
user.setUserName(wdUser.getMobile());
user.setUserName(wdUser.getUsername());
user.setOpenId(wdUser.getMobile());
user.setName(wdUser.getUsername());
user.setName(wdUser.getName());
user.setIdCard(wdUser.getPersoncard());
user.setSex(wdUser.getGender());
user.setHeadimg(wdUser.getAvatar());
......@@ -94,7 +92,7 @@ public class SysUserBaseServiceImpl extends ServiceImpl<SysUserBaseMapper, SysUs
user.setPasswd(ENCODER.encode(Constant.DEFAULT_PASSWORD));
user.setPhone(wdUser.getMobile());
this.save(user);
List<WDUserCardInfo> cardList = SsbUtil.getUserCardInfoList(token);
// List<WDUserCardInfo> cardList = SsbUtil.getUserCardInfoList(token);
}
UserInfo info = new UserInfo();
......
......@@ -4,13 +4,17 @@ import cn.sh.stc.sict.cloud.common.security.annotation.EnableSictFeignClients;
import cn.sh.stc.sict.cloud.common.security.annotation.EnableSictResourceServer;
import cn.sh.stc.sict.cloud.common.swagger.annotation.EnableSictSwagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @author F_xh
*/
@EnableAsync
@EnableCaching
@EnableScheduling
@EnableSictSwagger2
@SpringCloudApplication
......
package cn.sh.stc.sict.theme.hpgp.controller.mobile;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.sh.stc.sict.cloud.common.security.util.SecurityUtils;
import cn.sh.stc.sict.cloud.upms.dto.CurrentUser;
import cn.sh.stc.sict.theme.hpgp.model.HpgpBusyIdlePrediction;
import cn.sh.stc.sict.theme.hphy.model.HphyPatientBase;
import cn.sh.stc.sict.theme.hphy.service.HphyPatientBaseService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import cn.sh.stc.sict.cloud.common.core.util.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cn.sh.stc.sict.theme.hpgp.model.HpHzjl;
import cn.sh.stc.sict.theme.hpgp.service.HpHzjlService;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javax.annotation.Resource;
import java.io.Serializable;
import java.util.List;
/**
* (HpHzjl)表控制层
*
* @author F_xh
* @since 2022-08-15 14:14:33
*/
@Slf4j
@RestController
@AllArgsConstructor
@Api(tags = "患者就诊记录")
@RequestMapping("/hpHzjl")
public class HpHzjlController {
/**
* 服务对象
*/
private final HpHzjlService hpHzjlService;
private final HphyPatientBaseService hphyPatientBaseService;
@GetMapping("/history/dept/list")
public R historyDeptList(){
CurrentUser current = SecurityUtils.getCurrentUser();
if(ObjectUtil.isEmpty(current)|| StrUtil.isBlank(current.getOpenId())){
log.error("current = {}", JSONUtil.toJsonStr(current));
return new R().error("当前的登录人信息异常");
}
HphyPatientBase patient = hphyPatientBaseService.getByOpenId(current.getOpenId());
if(ObjectUtil.isEmpty(patient)||StrUtil.isBlank(patient.getCertId())){
log.error("patient = {}", JSONUtil.toJsonStr(patient));
return new R().error("患者信息异常!");
}
List<HpgpBusyIdlePrediction> result = hpHzjlService.listByCertId(patient.getCertId());
return new R(result);
}
}
......@@ -32,13 +32,13 @@ public class HpgpDiagnosticExperienceController extends ApiController {
* 分页查询
*
* @param page 分页对象
* @param hpgpDiagnosticExperience 黄浦全科导诊——诊断经验云词
* @param experience 黄浦全科导诊——诊断经验云词
* @return
*/
@ApiOperation("分页查询")
@GetMapping("/page")
public R<?> getHpgpDiagnosticExperiencePage(Page page, HpgpDiagnosticExperience hpgpDiagnosticExperience) {
page = hpgpDiagnosticExperienceService.page(page, Wrappers.query(hpgpDiagnosticExperience));
public R<?> getHpgpDiagnosticExperiencePage(Page page, HpgpDiagnosticExperience experience) {
page = hpgpDiagnosticExperienceService.page(page, Wrappers.query(experience));
return new R<>(page);
}
......
package cn.sh.stc.sict.theme.hpgp.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import cn.sh.stc.sict.theme.hpgp.model.HpHzjl;
/**
* (HpHzjl)表数据库访问层
*
* @author F_xh
* @since 2022-08-15 14:14:33
*/
public interface HpHzjlMapper extends BaseMapper<HpHzjl> {
}
package cn.sh.stc.sict.theme.hpgp.model;
import java.util.Date;
import io.swagger.annotations.ApiModelProperty;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import io.swagger.annotations.Api;
/**
* (HpHzjl)表实体类
*
* @author F_xh
* @since 2022-08-15 14:14:33
*/
@Data
@SuppressWarnings("serial")
@EqualsAndHashCode(callSuper = true)
public class HpHzjl extends Model<HpHzjl> {
private String zjhm;
private String zjlx;
private String xm;
private String yljgdm;
private String jzlx;
private String txbz;
private String jzksbm;
private String jzksmc;
private Date jzksrq;
private String zzysgh;
private String zzysxm;
private String jzzdsm;
}
package cn.sh.stc.sict.theme.hpgp.model;
import java.util.Date;
import cn.sh.stc.sict.cloud.common.core.util.NumberUtil;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
/**
* 黄浦全科导诊——忙闲预测(HpgpBusyIdle_ prediction)表实体类
......@@ -18,22 +20,64 @@ import java.io.Serializable;
@Data
@EqualsAndHashCode(callSuper = true)
public class HpgpBusyIdlePrediction extends Model<HpgpBusyIdlePrediction> {
private Long id;
//医院代码
@ApiModelProperty(hidden = false, value = "医院代码")
@ApiModelProperty( value = "医院代码")
private String hospitalCode;
//医院名称
@ApiModelProperty(hidden = false, value = "医院名称")
@ApiModelProperty(value = "医院名称")
private String hospitalName;
private String oneDeptCode;
//科室代码
@ApiModelProperty(hidden = false, value = "科室代码")
@ApiModelProperty(value = "科室代码")
private String deptCode;
//科室名称
@ApiModelProperty(hidden = false, value = "科室名称")
@ApiModelProperty(value = "科室名称")
private String deptName;
//预测日期
@ApiModelProperty(hidden = false, value = "预测日期")
@ApiModelProperty(value = "预测日期")
private Date predictionDate;
// 总号源数量
private Integer reserveOrderNum;
// 可预约号源数量
private Integer remainNum;
//忙闲评分
@ApiModelProperty(hidden = false, value = "忙闲评分")
@ApiModelProperty(value = "忙闲评分")
private Integer score;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
/**
* 获取主键值
*
* @return 主键值
*/
@Override
protected Serializable pkVal() {
return this.id;
}
// 可用号源 / 号源
// >=0.5 0- 闲 -绿色
// 0.2-0.5 1-忙碌-黄色
// <=0.2 2-非常忙碌-红色
// 无号院 -1 灰色
public void setScoreByNum() {
if (NumberUtil.isNotNullOrZero(this.reserveOrderNum)) {
double roate = this.remainNum * 1.0 / this.reserveOrderNum;
if (roate >= 0.5) {
this.setScore(0);
} else if (roate > 0.2 && roate < 0.5) {
this.setScore(1);
} else {
this.setScore(2);
}
} else {
this.setScore(-1);
}
}
}
......@@ -16,6 +16,7 @@ import java.io.Serializable;
@Data
@EqualsAndHashCode(callSuper = true)
public class HpgpDepartmentRank extends Model<HpgpDepartmentRank> {
private Integer id;
//标准科室
@ApiModelProperty(hidden = false, value = "标准科室")
private String standardDept;
......@@ -25,6 +26,9 @@ public class HpgpDepartmentRank extends Model<HpgpDepartmentRank> {
//医院名称
@ApiModelProperty(hidden = false, value = "医院名称")
private String hospitalName;
@ApiModelProperty(hidden = false, value = "一级科室代码")
private String oneDeptCode;
//科室代码
@ApiModelProperty(hidden = false, value = "科室代码")
private String deptCode;
......@@ -36,4 +40,20 @@ public class HpgpDepartmentRank extends Model<HpgpDepartmentRank> {
private Integer rankScore;
private String tag;
private String resourceOutPatInfo;
private String resourceDoctInfo;
/**
* 获取主键值
*
* @return 主键值
*/
@Override
protected Serializable pkVal() {
return this.id;
}
}
......@@ -22,6 +22,9 @@ public class HpgpDiagnosticExperience extends Model<HpgpDiagnosticExperience> {
//医院名称
@ApiModelProperty(hidden = false, value = "医院名称")
private String hospitalName;
@ApiModelProperty(hidden = false, value = "一级科室代码")
private String oneDeptCode;
//科室代码
@ApiModelProperty(hidden = false, value = "科室代码")
private String deptCode;
......
......@@ -22,6 +22,9 @@ public class HpgpInspectionCheck extends Model<HpgpInspectionCheck> {
//医院名称
@ApiModelProperty(hidden = false, value = "医院名称")
private String hospitalName;
@ApiModelProperty(hidden = false, value = "一级科室代码")
private String oneDeptCode;
//科室代码
@ApiModelProperty(hidden = false, value = "科室代码")
private String deptCode;
......
......@@ -19,6 +19,7 @@ public class HpgpLabExperience extends Model<HpgpLabExperience> {
private Integer id;
private String hospCode;
private String hospName;
private String oneDeptCode;
private String deptCode;
private String deptName;
private String itemName;
......
package cn.sh.stc.sict.theme.hpgp.service;
import cn.sh.stc.sict.theme.hpgp.model.HpgpBusyIdlePrediction;
import com.baomidou.mybatisplus.extension.service.IService;
import cn.sh.stc.sict.theme.hpgp.model.HpHzjl;
import java.util.List;
/**
* (HpHzjl)表服务接口
*
* @author F_xh
* @since 2022-08-15 14:14:33
*/
public interface HpHzjlService extends IService<HpHzjl> {
List<HpgpBusyIdlePrediction> listByCertId(String certId);
}
package cn.sh.stc.sict.theme.hpgp.service;
import cn.hutool.core.date.DateTime;
import cn.sh.stc.sict.theme.hpgp.model.HpgpBusyIdlePrediction;
import cn.sh.stc.sict.theme.hpgp.vo.DeptPredictionVO;
import cn.sh.stc.sict.theme.hpgp.model.HpgpDepartmentRank;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.Date;
import java.util.List;
/**
......@@ -20,5 +22,9 @@ public interface HpgpBusyIdlePredictionService extends IService<HpgpBusyIdlePred
* @param deptName 标准科室名称
* @return 忙闲医院科室
*/
List<DeptPredictionVO> busyIdlePrediction(String deptName);
List<HpgpBusyIdlePrediction> busyIdlePrediction(String deptName);
void statisticResourceInfo(HpgpDepartmentRank dept, Date startDate, Date endDate, Byte flag);
List<HpgpBusyIdlePrediction> listByDeptRank(HpgpDepartmentRank dept, DateTime startTime, DateTime endTime);
}
......@@ -3,6 +3,8 @@ package cn.sh.stc.sict.theme.hpgp.service;
import com.baomidou.mybatisplus.extension.service.IService;
import cn.sh.stc.sict.theme.hpgp.model.HpgpDepartmentRank;
import java.util.List;
/**
* 黄浦全科导诊——科室排名(HpgpDepartmentRank)表服务接口
*
......@@ -11,4 +13,9 @@ import cn.sh.stc.sict.theme.hpgp.model.HpgpDepartmentRank;
*/
public interface HpgpDepartmentRankService extends IService<HpgpDepartmentRank> {
void updateResource();
HpgpDepartmentRank getByCode(String hospCode, String oneDeptCode, String deptCode);
List<HpgpDepartmentRank> listHotDept();
}
package cn.sh.stc.sict.theme.hpgp.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.sh.stc.sict.theme.hpgp.model.HpgpBusyIdlePrediction;
import cn.sh.stc.sict.theme.hpgp.model.HpgpDepartmentRank;
import cn.sh.stc.sict.theme.hpgp.service.HpgpBusyIdlePredictionService;
import cn.sh.stc.sict.theme.hpgp.service.HpgpDepartmentRankService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.sh.stc.sict.theme.hpgp.dao.HpHzjlMapper;
import cn.sh.stc.sict.theme.hpgp.model.HpHzjl;
import cn.sh.stc.sict.theme.hpgp.service.HpHzjlService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* (HpHzjl)表服务实现类
*
* @author F_xh
* @since 2022-08-15 14:14:33
*/
@AllArgsConstructor
@Service("hpHzjlService")
public class HpHzjlServiceImpl extends ServiceImpl<HpHzjlMapper, HpHzjl> implements HpHzjlService {
private final HpgpDepartmentRankService hpgpDepartmentRankService;
private final HpgpBusyIdlePredictionService hpgpBusyIdlePredictionService;
/**
* 根据身份证号查找最后三次不同科室就诊记录,并计算忙闲
* 如果未找到,则推送三个热门科室
*
* @param certId
* @return
*/
@Override
public List<HpgpBusyIdlePrediction> listByCertId(String certId) {
List<HpgpBusyIdlePrediction> result = new ArrayList<>();
DateTime startTime = DateUtil.tomorrow();
DateTime endTime = DateUtil.offsetDay(startTime, 6);
LambdaQueryWrapper<HpHzjl> wrapper = Wrappers.lambdaQuery();
wrapper.eq(HpHzjl::getZjhm, certId)
.groupBy(HpHzjl::getJzksbm)
.orderByDesc(HpHzjl::getJzksrq)
.last("limit 10");
List<HpHzjl> recordList = this.list(wrapper);
if (CollUtil.isNotEmpty(recordList)) {
for (HpHzjl record : recordList) {
if (result.size() >= 20) {
break;
}
// 查找科室
HpgpDepartmentRank dept = hpgpDepartmentRankService.getByCode(record.getYljgdm(), null, record.getJzksbm());
if (ObjectUtil.isEmpty(dept)) {
continue;
}
// 忙闲预测
result.addAll(hpgpBusyIdlePredictionService.listByDeptRank(dept, startTime, endTime));
}
}
if (CollUtil.isEmpty(result)) {
List<HpgpDepartmentRank> rankList = hpgpDepartmentRankService.listHotDept();
rankList.forEach(rank -> {
result.addAll(hpgpBusyIdlePredictionService.listByDeptRank(rank, startTime, endTime));
});
}
return result;
}
}
package cn.sh.stc.sict.theme.hpgp.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.sh.stc.sict.cloud.common.core.constant.Constant;
import cn.sh.stc.sict.theme.hpgp.model.HpgpBusyIdlePrediction;
import cn.sh.stc.sict.theme.hpgp.service.HpgpBusyIdlePredictionService;
import cn.sh.stc.sict.theme.hphy.wd.*;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.sh.stc.sict.theme.hpgp.dao.HpgpDepartmentRankMapper;
import cn.sh.stc.sict.theme.hpgp.model.HpgpDepartmentRank;
import cn.sh.stc.sict.theme.hpgp.service.HpgpDepartmentRankService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 黄浦全科导诊——科室排名(HpgpDepartmentRank)表服务实现类
*
* @author zhangly
* @since 2022-01-14 09:56:47
*/
@Slf4j
@AllArgsConstructor
@Service("hpgpDepartmentRankService")
public class HpgpDepartmentRankServiceImpl extends ServiceImpl<HpgpDepartmentRankMapper, HpgpDepartmentRank> implements HpgpDepartmentRankService {
@Override
public void updateResource() {
List<HpgpDepartmentRank> deptList = this.list();
deptList.forEach(dept -> {
if (dept.getOneDeptCode().equals(dept.getDeptCode())) {
return;
}
this.asyncUpdateRank(dept);
});
}
@Override
public HpgpDepartmentRank getByCode(String hospCode, String oneDeptCode, String deptCode) {
LambdaQueryWrapper<HpgpDepartmentRank> wrapper = Wrappers.lambdaQuery();
wrapper.eq(HpgpDepartmentRank::getHospitalCode, hospCode)
.eq(StrUtil.isNotEmpty(oneDeptCode), HpgpDepartmentRank::getOneDeptCode, oneDeptCode)
.eq(StrUtil.isNotEmpty(deptCode), HpgpDepartmentRank::getDeptCode, deptCode)
.last("limit 1");
return this.getOne(wrapper);
}
@Override
public List<HpgpDepartmentRank> listHotDept() {
LambdaQueryWrapper<HpgpDepartmentRank> wrapper = Wrappers.lambdaQuery();
wrapper.eq(HpgpDepartmentRank::getTag, Constant.STRING_YES);
return this.list(wrapper);
}
@Async
void asyncUpdateRank(HpgpDepartmentRank dept) {
DeptInfo deptInfo = new DeptInfo();
deptInfo.setHosOrgCode(dept.getHospitalCode());
deptInfo.setOneDeptCode(dept.getOneDeptCode());
deptInfo.setDeptCode(dept.getDeptCode());
List<OutPatInfo> resourceOutPatInfo = WanDaHttpUtil.getResourceOutPatInfo(deptInfo);
List<DoctInfo> resourceDoctInfo = WanDaHttpUtil.getResourceDoctInfo(deptInfo);
if (CollUtil.isEmpty(resourceDoctInfo) && CollUtil.isEmpty(resourceOutPatInfo)) {
return;
}
HpgpDepartmentRank update = new HpgpDepartmentRank();
update.setId(dept.getId());
update.setResourceDoctInfo(JSONUtil.toJsonStr(resourceDoctInfo));
update.setResourceOutPatInfo(JSONUtil.toJsonStr(resourceOutPatInfo));
this.updateById(update);
}
}
package cn.sh.stc.sict.theme.hpgp.vo;
import cn.sh.stc.sict.cloud.common.core.util.NumberUtil;
import cn.sh.stc.sict.theme.hpgp.model.HpgpBusyIdlePrediction;
import lombok.Data;
@Data
public class DeptPredictionVO extends HpgpBusyIdlePrediction {
private Integer reserveOrderNum;
private Integer remainNum;
// 可用号源 / 号源
// >=0.5 0- 闲 -绿色
// 0.2-0.5 1-忙碌-黄色
// <=0.2 2-非常忙碌-红色
// 无号院 -1 灰色
public void setScoreByNum() {
if (NumberUtil.isNotNullOrZero(this.reserveOrderNum)) {
double roate = this.remainNum * 1.0 / this.reserveOrderNum;
if (roate >= 0.5) {
this.setScore(0);
} else if (roate > 0.2 && roate < 0.5) {
this.setScore(1);
} else {
this.setScore(2);
}
} else {
this.setScore(-1);
}
}
}
package cn.sh.stc.sict.theme.hphy.controller.mp;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.sh.stc.sict.cloud.common.core.constant.Constant;
import cn.sh.stc.sict.cloud.common.core.util.R;
import cn.sh.stc.sict.theme.hpgp.model.HpgpDepartmentRank;
import cn.sh.stc.sict.theme.hpgp.service.HpgpBusyIdlePredictionService;
import cn.sh.stc.sict.theme.hpgp.service.HpgpDepartmentRankService;
import cn.sh.stc.sict.theme.hphy.model.HpDeptInfo;
import cn.sh.stc.sict.theme.hphy.service.HpDeptInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.api.ApiController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
/**
* (HpDeptInfo)维护接口
......@@ -28,11 +37,56 @@ public class HpDeptInfoController extends ApiController {
* 服务对象
*/
private final HpDeptInfoService hpDeptInfoService;
private final HpgpDepartmentRankService hpgpDepartmentRankService;
private final HpgpBusyIdlePredictionService hpgpBusyIdlePredictionService;
@ApiOperation("科室医生查询接口")
@GetMapping
public R<?> getDeptDoctors(@ApiParam("医院代码") @RequestParam("hospitalCode") String hospitalCode,
@ApiParam("科室代码") @RequestParam("deptCode") String deptCode){
@ApiParam("科室代码") @RequestParam("deptCode") String deptCode) {
return new R<>(hpDeptInfoService.getDeptDoctors(hospitalCode, deptCode));
}
@ApiOperation("更新科室号源信息")
@PostMapping("/wd/resource")
public R updateDeptResource() {
List<HpDeptInfo> deptList = hpDeptInfoService.list();
deptList.forEach(dept -> {
if (StrUtil.isEmpty(dept.getOneDeptCode()) || StrUtil.isEmpty(dept.getDeptCode())) {
return;
}
hpDeptInfoService.asyncUpdate(dept);
});
return new R();
}
@ApiOperation("更新科室排行表号源信息")
@PostMapping("/rank/wd/resource")
public R updateRankDeptResource() {
hpgpDepartmentRankService.updateResource();
return new R();
}
@ApiOperation("定时统计排行科室的号源信息")
@PostMapping("/statistic/rank/wd/resource")
public R statisticRankDeptResourceInfo(@RequestParam(value = "hospCode", required = false) String hospCode,
@RequestParam(value = "oneDeptCode", required = false) String oneDeptCode,
@RequestParam(value = "dept", required = false) String deptCode,
@RequestParam(value = "flag", required = false, defaultValue = Constant.STRING_NO) Byte flag) {
LambdaQueryWrapper<HpgpDepartmentRank> wrapper = Wrappers.lambdaQuery();
wrapper.eq(StrUtil.isNotEmpty(hospCode), HpgpDepartmentRank::getHospitalCode, hospCode)
.eq(StrUtil.isNotEmpty(oneDeptCode), HpgpDepartmentRank::getOneDeptCode, oneDeptCode)
.eq(StrUtil.isNotEmpty(deptCode), HpgpDepartmentRank::getDeptCode, deptCode);
List<HpgpDepartmentRank> deptList = hpgpDepartmentRankService.list(wrapper);
deptList.forEach(dept -> {
if (StrUtil.isEmpty(dept.getOneDeptCode()) || StrUtil.isEmpty(dept.getDeptCode())) {
return;
}
Date startDate = DateUtil.date();
Date endDate = DateUtil.offsetDay(startDate, 10);
hpgpBusyIdlePredictionService.statisticResourceInfo(dept, startDate, endDate, flag);
});
return new R();
}
}
......@@ -3,6 +3,7 @@ package cn.sh.stc.sict.theme.hphy.controller.mp;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.sh.stc.sict.cloud.common.core.constant.Constant;
import cn.sh.stc.sict.cloud.common.core.constant.enums.LoginTypeEnum;
import cn.sh.stc.sict.cloud.common.core.dto.WDUserCardInfo;
......@@ -103,7 +104,9 @@ public class HphyPatientBaseController {
*/
@GetMapping
public R getInfo() {
log.error("获取患者信息1");
CurrentUser current = SecurityUtils.getCurrentUser();
log.error("获取患者信息2, current = {}", JSONUtil.toJsonStr(current));
if (StrUtil.isBlank(current.getOpenId())) {
log.error("openId 为空");
......@@ -115,6 +118,7 @@ public class HphyPatientBaseController {
current.setGender(PatientConstant.getGender(base.getGender()));
SecurityUtils.updateCurrent(current);
}
log.error("获取患者信息2, base = {}", JSONUtil.toJsonStr(base));
return new R(base);
}
......@@ -123,6 +127,7 @@ public class HphyPatientBaseController {
@GetMapping("/third-party")
public R getInfoByToken(@RequestParam("source") String source,
@RequestParam("token") String token) {
log.error("source = {}, token = {}", source, token);
CurrentUser current = SecurityUtils.getCurrentUser();
if (StrUtil.isBlank(current.getOpenId())) {
......@@ -130,9 +135,11 @@ public class HphyPatientBaseController {
}
// 获取患者信息
HphyPatientBase base = hphyPatientBaseService.getByOpenId(current.getOpenId());
log.error("third-party.base1 = {}", JSONUtil.toJsonStr(base));
if (ObjectUtil.isNull(base) || NumberUtil.isNullOrZero(base.getId())) {
if (LoginTypeEnum.SSB.getType().equals(source)) {
WDUserInfo userInfo = SsbUtil.getUserInfo(token);
log.error("wdUser = {}", userInfo);
List<WDUserCardInfo> cardList = SsbUtil.getUserCardInfoList(token);
base = hphyPatientBaseService.saveSSbInfo(current, userInfo, cardList);
hpPatientCardService.save(base, cardList);
......
......@@ -3,6 +3,7 @@ package cn.sh.stc.sict.theme.hphy.controller.mp;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import cn.sh.stc.sict.cloud.common.core.constant.Constant;
import cn.sh.stc.sict.cloud.common.core.util.R;
import cn.sh.stc.sict.cloud.common.core.util.ValidateCodeUtil;
......@@ -21,6 +22,7 @@ import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author F_xh
......@@ -72,7 +74,21 @@ public class WDController {
@GetMapping("/num/info")
public R getOrderNumberInfo(NumSourceInfo numSourceInfo) {
// 医生查询所有号源能查到,查询指定类型号源差不多,20220715处理:查询所有,过滤
String orderNumType = numSourceInfo.getOrderNumType();
if(WanDaConstant.ORDER_TYPE_OUTP.equals(numSourceInfo.getOrderType())){
numSourceInfo.setOrderNumType(null);
}
List<NumSourceInfo> list = WanDaHttpUtil.getOrderNumInfo(numSourceInfo);
if(CollUtil.isEmpty(list)){
return new R();
}
if(WanDaConstant.ORDER_TYPE_OUTP.equals(numSourceInfo.getOrderType())){
List<NumSourceInfo> result = list.stream().filter(i -> orderNumType.equals(i.getOrderNumType())).collect(Collectors.toList());
return new R(result);
}else{
return new R(list);
}
// if (CollUtil.isNotEmpty(list)) {
// return R.builder().code(Constant.BYTE_YES).data(list).bizCode(Constant.INT_NO).build();
......@@ -90,7 +106,7 @@ public class WDController {
//
// return new R(list);
// }
return new R().success(list);
// return new R().success(list);
}
@ApiOperation("获取测压亭列表")
......@@ -98,4 +114,5 @@ public class WDController {
public R getPressureStationList(){
return new R();
}
}
......@@ -23,4 +23,5 @@ public class HpDocInfoController extends ApiController {
* 服务对象
*/
private final HpDocInfoService hpDocInfoService;
}
\ No newline at end of file
......@@ -43,6 +43,10 @@ public class HpDeptInfo extends Model<HpDeptInfo> {
@ApiModelProperty(hidden = false, value = "显示次序")
private String indexNo;
private String resourceOutPatInfo;
private String resourceDoctInfo;
/**
* 获取主键值
......
......@@ -55,6 +55,8 @@ public class HpDocInfo extends Model<HpDocInfo> {
@ApiModelProperty(hidden = false, value = "是否有资源(0有,1无)")
private String isResource;
private Byte hasResource;
/**
* 获取主键值
......
package cn.sh.stc.sict.theme.hphy.schedule;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.sh.stc.sict.cloud.common.core.constant.Constant;
import cn.sh.stc.sict.theme.hpgp.model.HpgpDepartmentRank;
import cn.sh.stc.sict.theme.hpgp.service.HpgpBusyIdlePredictionService;
import cn.sh.stc.sict.theme.hpgp.service.HpgpDepartmentRankService;
import cn.sh.stc.sict.theme.hphy.constant.DataConstant;
import cn.sh.stc.sict.theme.hphy.model.HpDeptInfo;
import cn.sh.stc.sict.theme.hphy.model.HpDocInfo;
......@@ -21,6 +27,7 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
......@@ -38,6 +45,8 @@ public class RefreshJob {
private final HpHosInfoService hpHosInfoService;
private final HpDeptInfoService deptInfoService;
private final HpDocInfoService docInfoService;
private final HpgpDepartmentRankService hpgpDepartmentRankService;
private final HpgpBusyIdlePredictionService hpgpBusyIdlePredictionService;
/**
* 每月一日0点 更新医院信息
......@@ -100,6 +109,23 @@ public class RefreshJob {
}
}
/**
* 每天中午12点,晚上12点,统计号源信息
*/
// @Scheduled(cron = "0 50 12 * * ? ")
@Scheduled(cron = "0 0 0,12 * * ? ")
public void statisticRankDeptResourceInfo() {
List<HpgpDepartmentRank> deptList = hpgpDepartmentRankService.list();
deptList.forEach(dept -> {
if (StrUtil.isEmpty(dept.getOneDeptCode()) || StrUtil.isEmpty(dept.getDeptCode())) {
return;
}
Date startDate = DateUtil.date();
Date endDate = DateUtil.offsetDay(startDate, 10);
hpgpBusyIdlePredictionService.statisticResourceInfo(dept, startDate, endDate, Constant.BYTE_NO);
});
}
private void saveDoctor(String hosOrgCode, MapperFactory factory) {
List<DoctInfo> doctInfos = WanDaHttpUtil.getDoctInfo(new DeptInfo(hosOrgCode));
......
......@@ -19,4 +19,6 @@ public interface HpDeptInfoService extends IService<HpDeptInfo> {
* @return
*/
DeptDoctorsVO getDeptDoctors(String hospitalCode, String deptCode);
void asyncUpdate(HpDeptInfo dept);
}
......@@ -4,6 +4,8 @@ import cn.sh.stc.sict.theme.hphy.model.HpDocInfo;
import cn.sh.stc.sict.theme.hphy.model.HphyGuideRecord;
import cn.sh.stc.sict.theme.hphy.vo.DoctorMatchVO;
import cn.sh.stc.sict.theme.hphy.vo.PythonResult;
import cn.sh.stc.sict.theme.hphy.wd.DeptInfo;
import cn.sh.stc.sict.theme.hphy.wd.NumSourceInfo;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
......@@ -26,4 +28,8 @@ public interface HpDocInfoService extends IService<HpDocInfo> {
List<DoctorMatchVO> getRecommendList(HphyGuideRecord guide, List<PythonResult> pythonList);
void saveDoctor(List<HpDocInfo> docInfos, String hosOrgCode);
List<HpDocInfo> listByDeptInfo(DeptInfo deptInfo);
void updateResource(NumSourceInfo numSourceInfo, Byte hasResource);
}
\ No newline at end of file
package cn.sh.stc.sict.theme.hphy.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.sh.stc.sict.theme.hphy.dao.HpDocInfoMapper;
import cn.sh.stc.sict.theme.hphy.model.HpDocInfo;
import cn.sh.stc.sict.theme.hphy.model.HphyGuideMatch;
......@@ -9,7 +10,11 @@ import cn.sh.stc.sict.theme.hphy.service.HpDocInfoService;
import cn.sh.stc.sict.theme.hphy.service.HphyGuideMatchService;
import cn.sh.stc.sict.theme.hphy.vo.DoctorMatchVO;
import cn.sh.stc.sict.theme.hphy.vo.PythonResult;
import cn.sh.stc.sict.theme.hphy.wd.DeptInfo;
import cn.sh.stc.sict.theme.hphy.wd.HosInfo;
import cn.sh.stc.sict.theme.hphy.wd.NumSourceInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
......@@ -41,7 +46,7 @@ public class HpDocInfoServiceImpl extends ServiceImpl<HpDocInfoMapper, HpDocInfo
@Override
public List<DoctorMatchVO> getRecommendList(HphyGuideRecord guide, List<PythonResult> pythonList) {
List<DoctorMatchVO> result = new ArrayList<>();
if(CollUtil.isNotEmpty(pythonList)){
if (CollUtil.isNotEmpty(pythonList)) {
Map<String, Double> matchMap = pythonList.stream().collect(Collectors.toMap(PythonResult::getDoctorId, PythonResult::getMatchScore));
List<String> doctorIdList = pythonList.stream().map(PythonResult::getDoctorId).collect(Collectors.toList());
LambdaQueryWrapper<HpDocInfo> wrapper = new LambdaQueryWrapper<>();
......@@ -82,4 +87,25 @@ public class HpDocInfoServiceImpl extends ServiceImpl<HpDocInfoMapper, HpDocInfo
this.remove(new LambdaQueryWrapper<HpDocInfo>().eq(HpDocInfo::getHosOrgCode, hosOrgCode));
this.saveBatch(docInfos);
}
@Override
public List<HpDocInfo> listByDeptInfo(DeptInfo deptInfo) {
LambdaQueryWrapper<HpDocInfo> wrapper = Wrappers.lambdaQuery();
wrapper.eq(HpDocInfo::getHosOrgCode, deptInfo.getHosOrgCode())
.eq(HpDocInfo::getOneDeptCode, deptInfo.getOneDeptCode())
.eq(StrUtil.isNotEmpty(deptInfo.getDeptCode()), HpDocInfo::getDeptCode, deptInfo.getDeptCode());
return this.list(wrapper);
}
@Override
public void updateResource(NumSourceInfo num, Byte hasResource) {
LambdaQueryWrapper<HpDocInfo> wrapper = Wrappers.lambdaQuery();
wrapper.eq(HpDocInfo::getHosOrgCode, num.getHosOrgCode())
.eq(HpDocInfo::getOneDeptCode, num.getOneDeptCode())
.eq(StrUtil.isNotEmpty(num.getDeptCode()), HpDocInfo::getDeptCode, num.getDeptCode())
.eq(HpDocInfo::getResourceCode, num.getResourceCode());
HpDocInfo update = new HpDocInfo();
update.setHasResource(hasResource);
this.update(update, wrapper);
}
}
\ No newline at end of file
......@@ -7,14 +7,13 @@ import cn.sh.stc.sict.cloud.common.core.constant.Constant;
import cn.sh.stc.sict.cloud.common.core.dto.WDUserCardInfo;
import cn.sh.stc.sict.cloud.common.core.dto.WDUserInfo;
import cn.sh.stc.sict.cloud.upms.dto.CurrentUser;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import cn.sh.stc.sict.theme.hphy.dao.HphyPatientBaseMapper;
import cn.sh.stc.sict.theme.hphy.model.HphyPatientBase;
import cn.sh.stc.sict.theme.hphy.service.HphyPatientBaseService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
......@@ -40,7 +39,7 @@ public class HphyPatientBaseServiceImpl extends ServiceImpl<HphyPatientBaseMappe
base.setUserId(current.getId());
base.setOpenId(current.getOpenId());
base.setPhone(userInfo.getMobile());
base.setName(userInfo.getUsername());
base.setName(userInfo.getName());
base.setCertId(userInfo.getPersoncard());
base.setAge(String.valueOf(IdcardUtil.getAgeByIdCard(userInfo.getPersoncard())));
base.setGender(Constant.BYTE_YES.equals(userInfo.getGender()) ? "男" : "女");
......@@ -52,6 +51,7 @@ public class HphyPatientBaseServiceImpl extends ServiceImpl<HphyPatientBaseMappe
}
this.save(base);
return base;
}
return null;
}
......
......@@ -5,6 +5,7 @@ public class WanDaConstant {
/**
* 预约类型:1-医生 2-门诊
*/
public static final String ORDER_TYPE_DOCT = "1";
public static final String ORDER_TYPE_OUTP = "1";
public static final String ORDER_TYPE_CLINC = "2";
......
......@@ -116,7 +116,7 @@ public class WanDaHttpUtil {
log.error("获取一级科室信息失败");
return null;
}
log.info("获取一级科室信息:body = {}", body);
// log.info("获取一级科室信息:body = {}", body);
String returnXml = getReturn(body, "GetDeptInfoTopService");
return serialDeptInfos(returnXml);
}
......@@ -139,7 +139,7 @@ public class WanDaHttpUtil {
log.error("获取二级科室信息失败");
return null;
}
log.info("获取二级科室信息:body = {}", body);
// log.info("获取二级科室信息:body = {}", body);
String returnXml = getReturn(body, "GetDeptInfoTwoService");
return serialDeptInfos(returnXml);
}
......@@ -197,28 +197,35 @@ public class WanDaHttpUtil {
*/
public List<NumSourceInfo> getOrderNumInfo(NumSourceInfo numSourceInfo) {
String xml = WanDaUtil.GetOrderNumInfoServiceXML(numSourceInfo);
String body = HttpRequest.post(URL)
.body(xml)
.execute()
.body();
if (StrUtil.isBlank(body)) {
log.error("号源查询 失败");
return null;
}
// log.info("号源查询:body = {}", body);
String returnXml = getReturn(body, "GetOrderNumInfoService");
if (Constant.STRING_NO.equals(getCode(returnXml))) {
Document document = XmlUtil.readXML(returnXml);
NodeList nodeList = document.getElementsByTagName("NumSourceInfo");
List<NumSourceInfo> list = new ArrayList<>();
if (null != nodeList && nodeList.getLength() > 0) {
for (int i = 0; i < nodeList.getLength(); i++) {
list.add(XmlUtil.xmlToBean(nodeList.item(i), NumSourceInfo.class));
String body = "";
try {
body = HttpRequest.post(URL)
.body(xml)
.execute()
.body();
if (StrUtil.isBlank(body)) {
log.error("号源查询 失败");
return null;
}
String returnXml = getReturn(body, "GetOrderNumInfoService");
if (Constant.STRING_NO.equals(getCode(returnXml))) {
Document document = XmlUtil.readXML(returnXml);
NodeList nodeList = document.getElementsByTagName("NumSourceInfo");
List<NumSourceInfo> list = new ArrayList<>();
if (null != nodeList && nodeList.getLength() > 0) {
for (int i = 0; i < nodeList.getLength(); i++) {
list.add(XmlUtil.xmlToBean(nodeList.item(i), NumSourceInfo.class));
}
}
return list;
} else {
return null;
}
return list;
} else {
}catch (Exception e){
log.error("号源查询失败,num = {}", JSONUtil.toJsonStr(numSourceInfo));
log.error("号源查询失败,body = {}", body);
log.error(e.getMessage(), e);
return null;
}
}
......@@ -416,7 +423,7 @@ public class WanDaHttpUtil {
*/
public List<DoctInfo> getResourceDoctInfo(DeptInfo deptInfo) {
String xml = WanDaUtil.GetResourceDoctInfoServiceXML(deptInfo);
//log.error("获取可预约医生信息 xml = {}", xml);
String body = HttpRequest.post(URL)
.body(xml)
.execute()
......@@ -426,7 +433,7 @@ public class WanDaHttpUtil {
log.error("获取可预约医生信息 失败");
return null;
}
log.info("获取可预约医生信息:body = {}", body);
//log.info("获取可预约医生信息:body = {}", body);
String returnXml = getReturn(body, "GetResourceDoctInfoService");
return serialDoctInfo(returnXml);
}
......@@ -439,7 +446,7 @@ public class WanDaHttpUtil {
*/
public List<OutPatInfo> getResourceOutPatInfo(DeptInfo deptInfo) {
String xml = WanDaUtil.GetResourceOutPatInfoServiceXML(deptInfo);
//log.error("获取可预约门诊信息 xml = {}", xml);
String body = HttpRequest.post(URL)
.body(xml)
.execute()
......@@ -449,7 +456,7 @@ public class WanDaHttpUtil {
log.error("查询门诊信息失败");
return null;
}
// log.info("查询门诊信息:body = {}", body);
//log.info("查询门诊信息:body = {}", body);
String returnXml = getReturn(body, "GetResourceOutPatInfoService");
return serialOutPatInfo(returnXml);
}
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.sh.stc.sict.theme.hpgp.dao.HpHzjlMapper">
<resultMap type="cn.sh.stc.sict.theme.hpgp.model.HpHzjl" id="HpHzjlMap">
<result property="zjhm" column="ZJHM"/>
<result property="zjlx" column="ZJLX"/>
<result property="xm" column="XM"/>
<result property="yljgdm" column="YLJGDM"/>
<result property="jzlx" column="JZLX"/>
<result property="txbz" column="TXBZ"/>
<result property="jzksbm" column="JZKSBM"/>
<result property="jzksmc" column="JZKSMC"/>
<result property="jzksrq" column="JZKSRQ"/>
<result property="zzysgh" column="ZZYSGH"/>
<result property="zzysxm" column="ZZYSXM"/>
<result property="jzzdsm" column="JZZDSM"/>
</resultMap>
</mapper>
......@@ -23,7 +23,7 @@
d.one_dept_code oneDeptCode,
d.dept_code subDeptCode
from hpgp_department_rank dr
left join hp_dept_info d on (dr.hospital_code = d.hos_org_code and dr.dept_code = d.dept_code)
join hp_dept_info d on (dr.hospital_code = d.hos_org_code and dr.one_dept_code = d.one_dept_code and dr.dept_code = d.dept_code)
where dr.standard_dept = #{deptName}
order by dr.rank_score asc
limit #{size}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment