Merge branch '0418_小程序开发' of http://182.92.166.109:3000/zhuangyuanke/PostDischargePatientManage into 0418_小程序开发

This commit is contained in:
haown 2024-07-04 09:06:40 +08:00
commit 5cc50e6d48
29 changed files with 902 additions and 73 deletions

View File

@ -9,7 +9,7 @@ xinelu:
# 实例演示开关 # 实例演示开关
demoEnabled: true demoEnabled: true
# 文件路径 示例( Windows配置D:/postdischarge/uploadPathLinux配置 /home/postdischarge/uploadPath # 文件路径 示例( Windows配置D:/postdischarge/uploadPathLinux配置 /home/postdischarge/uploadPath
profile: D:/postdischarge/uploadPath profile: E:/postdischarge/uploadPath
# 签约知情书上传 # 签约知情书上传
sign-informed-file-url: /signInformed sign-informed-file-url: /signInformed
# 素材库封面上传 # 素材库封面上传
@ -202,7 +202,7 @@ wechat-applet-chat-config:
# 微信小程序事件回调令牌 # 微信小程序事件回调令牌
token: uI1NGHesp7ylIYVYQvp0TlcDmUTKCHj2 token: uI1NGHesp7ylIYVYQvp0TlcDmUTKCHj2
# 微信小程序事件回调消息加密密钥 # 微信小程序事件回调消息加密密钥
encoding-aes-key: 5rbyhMBpdnxTEVT54zeHMNcXi3ccilQZ209QqGi89EW encoding-aes-key: 5rbyhMBpdnxTEVT54zeHMNcXi3ccilQZ209QqGi8E10
# 随访模板id # 随访模板id
follow-template-id: p__w9HO65a8aqgy6OuNG9t_v9_j1dcT81CEA_cdMhaw follow-template-id: p__w9HO65a8aqgy6OuNG9t_v9_j1dcT81CEA_cdMhaw
# 健康宣教模板id # 健康宣教模板id
@ -219,4 +219,24 @@ wechat-official-account-config:
# 微信公众号事件回调消息加密密钥 # 微信公众号事件回调消息加密密钥
official-account-encoding-aes-key: Awcn7nvDU4bcfBwAZmiRbB3lFgXAm2RIg45utdb5Zt3 official-account-encoding-aes-key: Awcn7nvDU4bcfBwAZmiRbB3lFgXAm2RIg45utdb5Zt3
# 测试模板id # 测试模板id
test-template-id: WUCYtSbH-QFRV_fMcfmn86QLsz1zo881QW7fQNTWOjc test-template-id: WUCYtSbH-QFRV_fMcfmn86QLsz1zo881QW7fQNTWOjc
# 阿里云参数配置
aliyun-sms:
# AccessKey ID
accessKeyId: LTAIo6vpMk2441nc
# AccessKey Secret
accessKeySecret: JxPKD3Vx404QsZ3SvYSai1wuOlyRtR
# 产品名称:云通信短信API产品,开发者无需替换
product: Dysmsapi
# 产品域名,开发者无需替换
domain: dysmsapi.aliyuncs.com
# 地域ID
regionId: cn-qingdao
# 阿里云登录确认验证模板-短信签名
signName: 新医路
# 阿里云登录确认验证模板-模板CODE
templateCode: SMS_152466667
# 阿里云登录确认验证模板-模板内容
templateContent: 验证码${code},您正在登录,若非本人操作,请勿泄露。

View File

@ -0,0 +1,53 @@
package com.xinelu.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @program: PostDischargePatientManage
* @description: 阿里云参数配置
* @author: yxl
* @create: 2024-07-02 20:48
**/
@Data
@Component
@ConfigurationProperties(prefix = "aliyun-sms")
public class AliYunSmsConfig {
/**
* AccessKey ID
*/
private String accessKeyId;
/**
* AccessKey Secret
*/
private String accessKeySecret;
/**
* 产品名称:云通信短信API产品,开发者无需替换
*/
private String product;
/**
* 产品域名,开发者无需替换
*/
private String domain;
/**
* 地域ID
*/
private String regionId;
/**
* 阿里云登录确认验证模板-模板签名
*/
private String signName;
/**
* 阿里云登录确认验证模板-模板CODE
*/
private String templateCode;
}

View File

@ -368,4 +368,22 @@ public class Constants {
* 常用术语最小层数 * 常用术语最小层数
*/ */
public static final Long TERM_MIN_LEVEL = 1L; public static final Long TERM_MIN_LEVEL = 1L;
/**
* 登录发送短信验证冷却键前缀
*/
public static final String SMS_COOL_DOWN ="SMS_COOL_DOWN_";
/**
* 登录发送短信验证冷却键对应的值
*/
public static final String SMS_COOL_DOWN_VALUE ="COOL_DOWN";
/**
* 登录发送短信验证前缀
*/
public static final String SMS_CODE ="SMS_CODE_";
} }

View File

@ -0,0 +1,236 @@
package com.xinelu.common.enums;
import lombok.Getter;
/**
* 短信发送失败错误码枚举
*/
@Getter
public enum SmsErrorCodeEnum {
/**
* RAM权限不足
*/
RAM_PERMISSION_DENY("isp.RAM_PERMISSION_DENY", "RAM权限不足"),
/**
* 业务停机
*/
OUT_OF_SERVICE("isv.OUT_OF_SERVICE", "业务停机"),
/**
* 未开通云通信产品的阿里云客户
*/
PRODUCT_UN_SUBSCRIPT("isv.PRODUCT_UN_SUBSCRIPT", "未开通云通信产品的阿里云客户"),
/**
* 产品未开通
*/
PRODUCT_UNSUBSCRIBE("isv.PRODUCT_UNSUBSCRIBE", "产品未开通"),
/**
* 账户不存在
*/
ACCOUNT_NOT_EXISTS("isv.ACCOUNT_NOT_EXISTS", "账户不存在"),
/**
* 账户异常
*/
ACCOUNT_ABNORMAL("isv.ACCOUNT_ABNORMAL", "账户异常"),
/**
* 该账号下找不到对应模板
*/
SMS_TEMPLATE_ILLEGAL("isv.SMS_TEMPLATE_ILLEGAL", "该账号下找不到对应模板"),
/**
* 测试模板和签名限制
*/
SMS_TEST_SIGN_TEMPLATE_LIMIT("isv.SMS_TEST_SIGN_TEMPLATE_LIMIT", "测试模板和签名限制"),
/**
* 签名和模板类型不一致
*/
SMS_SIGNATURE_SCENE_ILLEGAL("isv.SMS_SIGNATURE_SCENE_ILLEGAL", "签名和模板类型不一致"),
/**
* 签名禁止使用
*/
SMS_SIGN_ILLEGAL("isv.SMS_SIGN_ILLEGAL", "签名禁止使用"),
/**
* 该账号下找不到对应签名
*/
SMS_SIGNATURE_ILLEGAL("isv.SMS_SIGNATURE_ILLEGAL", "该账号下找不到对应签名"),
/**
* 系统出现错误请重新调用
*/
SYSTEM_ERROR("isp.SYSTEM_ERROR", "系统出现错误,请重新调用"),
/**
* 手机号码格式错误
*/
MOBILE_NUMBER_ILLEGAL("isv.MOBILE_NUMBER_ILLEGAL", "手机号码格式错误"),
/**
* 手机号码数量超过限制最多支持1000条
*/
MOBILE_COUNT_OVER_LIMIT("isv.MOBILE_COUNT_OVER_LIMIT", "手机号码数量超过限制最多支持1000条"),
/**
* 模板变量中存在未赋值变量
*/
TEMPLATE_MISSING_PARAMETERS("isv.TEMPLATE_MISSING_PARAMETERS", "模板变量中存在未赋值变量"),
/**
* 传入的变量内容和实际申请模板时变量所选择的属性类型不配
*/
TEMPLATE_PARAMS_ILLEGAL("isv.TEMPLATE_PARAMS_ILLEGAL", "传入的变量内容和实际申请模板时变量所选择的属性类型不配"),
/**
* 超过单自然日模板申请数量上限
*/
TEMPLATE_COUNT_OVER_LIMIT("isv.TEMPLATE_COUNT_OVER_LIMIT", "超过单自然日模板申请数量上限"),
/**
* 模板字符数量超过限制
*/
TEMPLATE_OVER_LIMIT("isv.TEMPLATE_OVER_LIMIT", "模板字符数量超过限制"),
/**
* 触发云通信流控限制
*/
BUSINESS_LIMIT_CONTROL("isv.BUSINESS_LIMIT_CONTROL", "触发云通信流控限制"),
/**
* 参数格式错误请修改为字符串值
*/
INVALID_JSON_PARAM("isv.INVALID_JSON_PARAM", "参数格式错误,请修改为字符串值"),
/**
* 参数格式不正确
*/
INVALID_PARAMETERS("isv.INVALID_PARAMETERS", "参数格式不正确"),
/**
* 变量中传入疑似违规信息
*/
BLACK_KEY_CONTROL_LIMIT("isv.BLACK_KEY_CONTROL_LIMIT", "变量中传入疑似违规信息"),
/**
* 参数超过长度限制
*/
PARAM_LENGTH_LIMIT("isv.PARAM_LENGTH_LIMIT", "参数超过长度限制"),
/**
* 变量不支持传入URL
*/
PARAM_NOT_SUPPORT_URL("isv.PARAM_NOT_SUPPORT_URL", "变量不支持传入URL"),
/**
* 账户余额不足
*/
AMOUNT_NOT_ENOUGH("isv.AMOUNT_NOT_ENOUGH", "账户余额不足"),
/**
* 关键字拦截
*/
FILTER("FILTER", "关键字拦截"),
/**
* 重复过滤
*/
VALVE_MC("VALVE:M_MC", "重复过滤"),
/**
* 单个号码日或月发送上限流控超限频繁发送超限
*/
MOBILE_SEND_LIMIT("MOBILE_SEND_LIMIT", "单个号码日或月发送上限,流控超限,频繁发送超限"),
/**
* 手机号在黑名单平台或运营商
*/
MOBILE_IN_BLACK("MOBILE_IN_BLACK", "手机号在黑名单(平台或运营商)"),
/**
* 手机终端问题内存满SIM卡满非法设备等
*/
MOBILE_TERMINAL_ERROR("MOBILE_TERMINAL_ERROR", "手机终端问题、内存满、SIM卡满、非法设备等"),
/**
* 未开通国际短信
*/
SP_NOT_BY_INTER_SMS("SP_NOT_BY_INTER_SMS", "未开通国际短信"),
/**
* 用户手机退订此业务产品未开通
*/
USER_REJECT("USER_REJECT", "用户手机退订此业务、产品未开通"),
/**
* 运营商未知错误
*/
SP_UNKNOWN_ERROR("SP_UNKNOWN_ERROR", "运营商未知错误"),
/**
* 用户账户异常携号转网欠费等
*/
MOBILE_ACCOUNT_ABNORMAL("MOBILE_ACCOUNT_ABNORMAL", "用户账户异常、携号转网、欠费等"),
/**
* 消息发送成功
*/
DELIVERED("DELIVERED", "消息发送成功"),
/**
* 内容关键字拦截
*/
CONTENT_KEYWORD("CONTENT_KEYWORD", "内容关键字拦截"),
/**
* 签名黑名单
*/
SIGNATURE_BLACKLIST("SIGNATURE_BLACKLIST", "签名黑名单"),
/**
* 号码不合法
*/
INVALID_NUMBER("INVALID_NUMBER", "号码不合法"),
/**
* 无路由器
*/
NO_ROUTE("NO_ROUTE", "无路由器"),
/**
* 模板内容无退订
*/
CONTENT_ERROR("CONTENT_ERROR", "模板内容无退订"),
/**
* 未知错误
*/
UNKNOWN_ERROR("UNKNOWN_ERROR", "未知错误");
private final String code;
private final String message;
SmsErrorCodeEnum(String code, String message) {
this.code = code;
this.message = message;
}
public String getMessage() {
return message;
}
public static SmsErrorCodeEnum getMsgByCode(String code) {
for (SmsErrorCodeEnum errorCode : SmsErrorCodeEnum.values()) {
if (errorCode.code.equals(code)) {
return errorCode;
}
}
return UNKNOWN_ERROR;
}
}

View File

@ -1,5 +1,7 @@
package com.xinelu.common.utils.uuid; package com.xinelu.common.utils.uuid;
import java.security.SecureRandom;
/** /**
* ID生成器工具类 * ID生成器工具类
* *
@ -41,4 +43,14 @@ public class IdUtils {
public static String fastSimpleUUID() { public static String fastSimpleUUID() {
return UUID.fastUUID().toString(true); return UUID.fastUUID().toString(true);
} }
/**
* SecureRandom生成六位随机数
* @return 六位随机数
*/
public static int generateSixDigitNumber() {
SecureRandom random = new SecureRandom();
// // 100000 (inclusive) to 999999 (inclusive)
return 100000 + random.nextInt(900000);
}
} }

View File

@ -10,7 +10,6 @@ import com.xinelu.manage.domain.labelfieldinfo.LabelFieldInfo;
import com.xinelu.manage.dto.labelfieldinfo.LabelFieldInfoAddDTO; import com.xinelu.manage.dto.labelfieldinfo.LabelFieldInfoAddDTO;
import com.xinelu.manage.service.labelfieldinfo.ILabelFieldInfoService; import com.xinelu.manage.service.labelfieldinfo.ILabelFieldInfoService;
import com.xinelu.manage.vo.labelfieldinfo.LabelFieldTreeVO; import com.xinelu.manage.vo.labelfieldinfo.LabelFieldTreeVO;
import com.xinelu.manage.vo.labelfieldinfo.LabelFieldVO;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@ -116,4 +115,9 @@ public class LabelFieldInfoController extends BaseController {
public AjaxResult remove(@PathVariable Long[] ids) { public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(labelFieldInfoService.deleteLabelFieldInfoByIds(ids)); return toAjax(labelFieldInfoService.deleteLabelFieldInfoByIds(ids));
} }
@GetMapping("/taskTypeGrouping")
public AjaxResult taskTypeGrouping() {
return labelFieldInfoService.taskTypeGrouping();
}
} }

View File

@ -69,4 +69,7 @@ public interface ResidentInfoMapper {
* @return 被护理人基本信息 * @return 被护理人基本信息
*/ */
ResidentInfo getResidentInfoByPhoneAndOpenId(@Param("phone") String phone, @Param("openId") String openId); ResidentInfo getResidentInfoByPhoneAndOpenId(@Param("phone") String phone, @Param("openId") String openId);
List<ResidentInfo> getResidentInfoByPhoneAndName(@Param("phone") String phone, @Param("patientName") String patientName);
} }

View File

@ -1,6 +1,7 @@
package com.xinelu.manage.mapper.taskpartitiondict; package com.xinelu.manage.mapper.taskpartitiondict;
import com.xinelu.manage.domain.taskpartitiondict.TaskPartitionDict; import com.xinelu.manage.domain.taskpartitiondict.TaskPartitionDict;
import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
@ -59,4 +60,6 @@ public interface TaskPartitionDictMapper {
* @return 结果 * @return 结果
*/ */
int deleteTaskPartitionDictByIds(Long[] ids); int deleteTaskPartitionDictByIds(Long[] ids);
List<TaskPartitionDict> selectTaskPartitionList( List<Long> ids);
} }

View File

@ -1,6 +1,7 @@
package com.xinelu.manage.mapper.tasktypedict; package com.xinelu.manage.mapper.tasktypedict;
import com.xinelu.manage.domain.tasktypedict.TaskTypeDict; import com.xinelu.manage.domain.tasktypedict.TaskTypeDict;
import com.xinelu.manage.vo.tasktypedict.TaskTypeDictVO;
import java.util.List; import java.util.List;
@ -59,4 +60,11 @@ public interface TaskTypeDictMapper {
* @return 结果 * @return 结果
*/ */
public int deleteTaskTypeDictByIds(Long[] ids); public int deleteTaskTypeDictByIds(Long[] ids);
/**
* 查询任务类型字典列表
*
* @return 任务类型字典集合
*/
List<TaskTypeDictVO> selectTaskTypeDicts();
} }

View File

@ -204,6 +204,7 @@ public class LabelFieldContentServiceImpl implements ILabelFieldContentService {
} }
PatientTaskDto patientTaskDto = new PatientTaskDto(); PatientTaskDto patientTaskDto = new PatientTaskDto();
patientTaskDto.setPatientId(patientId); patientTaskDto.setPatientId(patientId);
//暂时不用
List<SignPatientManageRouteNode> nodeList = signPatientManageRouteNodeMapper.getNodeList(patientTaskDto); List<SignPatientManageRouteNode> nodeList = signPatientManageRouteNodeMapper.getNodeList(patientTaskDto);
List<String> nodeContentList = nodeList.stream().filter(Objects::nonNull).map(SignPatientManageRouteNode::getNodeContent).filter(Objects::nonNull).collect(Collectors.toList()); List<String> nodeContentList = nodeList.stream().filter(Objects::nonNull).map(SignPatientManageRouteNode::getNodeContent).filter(Objects::nonNull).collect(Collectors.toList());
String nodeContentListJoin = String.join(",", nodeContentList); String nodeContentListJoin = String.join(",", nodeContentList);
@ -233,20 +234,26 @@ public class LabelFieldContentServiceImpl implements ILabelFieldContentService {
for (int i = 0; i < declaredFields.length; i++) { for (int i = 0; i < declaredFields.length; i++) {
strings[i] = declaredFields[i].getName().toUpperCase(); strings[i] = declaredFields[i].getName().toUpperCase();
} }
List<PortraitSnVO> PortraitSnVOS = new ArrayList<>();
List<String> asListStrings = Arrays.asList(strings); List<String> asListStrings = Arrays.asList(strings);
for (GroupingValue groupingValue : labelFieldContentList) { for (GroupingValue groupingValue : labelFieldContentList) {
PortraitSnVO portraitSnVO = new PortraitSnVO();
groupingValue.setPatientId(patientId); groupingValue.setPatientId(patientId);
String s = asListStrings.stream().filter(Objects::nonNull).filter(item -> item.equals(groupingValue.getFieldCode())).findFirst().orElse(new String()); String s = asListStrings.stream().filter(Objects::nonNull).filter(item -> item.equals(groupingValue.getFieldCode())).findFirst().orElse(new String());
groupingValue.setFieldValue(paramsValue.getOrDefault(s, "").toString()); groupingValue.setFieldValue(paramsValue.getOrDefault(s, "").toString());
portraitSnVO.setPortraitSn(groupingValue.getPortraitSn());
PortraitSnVOS.add(portraitSnVO);
} }
List<Long> collect = labelFieldContentList.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getTaskPartitionDictId())).map(LabelFieldInfo::getTaskPartitionDictId).distinct().collect(Collectors.toList());
List<LabelFieldAndPartitionDict> labelFieldAndPartitionDictList = new ArrayList<>(); List<LabelFieldAndPartitionDict> labelFieldAndPartitionDictList = new ArrayList<>();
LabelFieldAndPartitionDict labelFieldAndPartitionDict = new LabelFieldAndPartitionDict(); for (Long aLong : collect) {
labelFieldAndPartitionDict.setPortraitSnVOList(PortraitSnVOS); List<PortraitSnVO> PortraitSnVOS = new ArrayList<>();
labelFieldAndPartitionDictList.add(labelFieldAndPartitionDict); LabelFieldAndPartitionDict labelFieldAndPartitionDict = new LabelFieldAndPartitionDict();
PortraitSnVO portraitSnVO = new PortraitSnVO();
List<GroupingValue> collect1 = labelFieldContentList.stream().filter(Objects::nonNull).filter(item -> aLong.equals(item.getTaskPartitionDictId())).collect(Collectors.toList());
portraitSnVO.setGroupingValues(collect1);
PortraitSnVOS.add(portraitSnVO);
labelFieldAndPartitionDict.setTaskPartitionDictId(aLong);
labelFieldAndPartitionDict.setTaskPartitionDictName(collect1.get(0).getTaskPartitionDictName());
labelFieldAndPartitionDict.setPortraitSnVOList(PortraitSnVOS);
labelFieldAndPartitionDictList.add(labelFieldAndPartitionDict);
}
return labelFieldAndPartitionDictList; return labelFieldAndPartitionDictList;
} }

View File

@ -4,7 +4,6 @@ import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.manage.domain.labelfieldinfo.LabelFieldInfo; import com.xinelu.manage.domain.labelfieldinfo.LabelFieldInfo;
import com.xinelu.manage.dto.labelfieldinfo.LabelFieldInfoAddDTO; import com.xinelu.manage.dto.labelfieldinfo.LabelFieldInfoAddDTO;
import com.xinelu.manage.vo.labelfieldinfo.LabelFieldTreeVO; import com.xinelu.manage.vo.labelfieldinfo.LabelFieldTreeVO;
import com.xinelu.manage.vo.labelfieldinfo.LabelFieldVO;
import java.util.List; import java.util.List;
@ -75,4 +74,11 @@ public interface ILabelFieldInfoService {
* 批量新增标签字段信息 * 批量新增标签字段信息
*/ */
int insertLabelFieldInfoList(LabelFieldInfoAddDTO labelFieldInfoAddDTO); int insertLabelFieldInfoList(LabelFieldInfoAddDTO labelFieldInfoAddDTO);
/**
* 查询任务类型
*
* @return AjaxResult
*/
AjaxResult taskTypeGrouping();
} }

View File

@ -1,14 +1,18 @@
package com.xinelu.manage.service.labelfieldinfo.impl; package com.xinelu.manage.service.labelfieldinfo.impl;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.exception.ServiceException; import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.SecurityUtils; import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.manage.domain.labelfieldinfo.LabelFieldInfo; import com.xinelu.manage.domain.labelfieldinfo.LabelFieldInfo;
import com.xinelu.manage.domain.taskpartitiondict.TaskPartitionDict;
import com.xinelu.manage.dto.labelfieldinfo.LabelFieldInfoAddDTO; import com.xinelu.manage.dto.labelfieldinfo.LabelFieldInfoAddDTO;
import com.xinelu.manage.mapper.labelfieldcontent.LabelFieldContentMapper;
import com.xinelu.manage.mapper.labelfieldinfo.LabelFieldInfoMapper; import com.xinelu.manage.mapper.labelfieldinfo.LabelFieldInfoMapper;
import com.xinelu.manage.mapper.taskpartitiondict.TaskPartitionDictMapper;
import com.xinelu.manage.mapper.tasktypedict.TaskTypeDictMapper;
import com.xinelu.manage.service.labelfieldinfo.ILabelFieldInfoService; import com.xinelu.manage.service.labelfieldinfo.ILabelFieldInfoService;
import com.xinelu.manage.vo.labelfieldinfo.LabelFieldTreeVO; import com.xinelu.manage.vo.labelfieldinfo.LabelFieldTreeVO;
import com.xinelu.manage.vo.labelfieldinfo.LabelFieldVO; import com.xinelu.manage.vo.labelfieldinfo.LabelFieldVO;
import com.xinelu.manage.vo.tasktypedict.TaskTypeDictVO;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -32,9 +36,10 @@ import java.util.stream.Collectors;
public class LabelFieldInfoServiceImpl implements ILabelFieldInfoService { public class LabelFieldInfoServiceImpl implements ILabelFieldInfoService {
@Resource @Resource
private LabelFieldInfoMapper labelFieldInfoMapper; private LabelFieldInfoMapper labelFieldInfoMapper;
@Resource @Resource
private LabelFieldContentMapper labelFieldContentMapper; private TaskTypeDictMapper taskTypeDictMapper;
@Resource
private TaskPartitionDictMapper taskPartitionDictMapper;
/** /**
* 查询标签字段信息 * 查询标签字段信息
@ -172,4 +177,21 @@ public class LabelFieldInfoServiceImpl implements ILabelFieldInfoService {
} }
return 1; return 1;
} }
@Override
public AjaxResult taskTypeGrouping() {
List<TaskTypeDictVO> taskTypeDictList = taskTypeDictMapper.selectTaskTypeDicts();
List<Long> ids = taskTypeDictList.stream().filter(Objects::nonNull).map(TaskTypeDictVO::getTaskTypeId).filter(Objects::nonNull).collect(Collectors.toList());
List<TaskPartitionDict> taskPartitionDicts = taskPartitionDictMapper.selectTaskPartitionList(ids);
if (CollectionUtils.isEmpty(taskPartitionDicts)) {
return AjaxResult.success(taskPartitionDicts);
}
for (TaskTypeDictVO taskTypeDictVO : taskTypeDictList) {
List<TaskPartitionDict> collect = taskPartitionDicts.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getTaskTypeId()) && taskTypeDictVO.getTaskTypeId().equals(item.getTaskTypeId())).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(collect)) {
taskTypeDictVO.setTaskPartitionDictList(collect);
}
}
return AjaxResult.success(taskTypeDictList);
}
} }

View File

@ -4,7 +4,6 @@ import com.alibaba.fastjson2.JSONObject;
import com.xinelu.common.core.domain.AjaxResult; import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.enums.PatientSexEnum; import com.xinelu.common.enums.PatientSexEnum;
import com.xinelu.common.enums.ReleaseStatusEnum; import com.xinelu.common.enums.ReleaseStatusEnum;
import com.xinelu.common.enums.TemplateTypeEnum;
import com.xinelu.common.exception.ServiceException; import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.BaseUtil; import com.xinelu.common.utils.BaseUtil;
import com.xinelu.common.utils.SecurityUtils; import com.xinelu.common.utils.SecurityUtils;
@ -55,8 +54,8 @@ public class SpecialDiseaseNodeServiceImpl implements ISpecialDiseaseNodeService
private PatientNodeParamsCurrentMapper patientNodeParamsCurrentMapper; private PatientNodeParamsCurrentMapper patientNodeParamsCurrentMapper;
@Resource @Resource
private PatientInfoMapper patientInfoMapper; private PatientInfoMapper patientInfoMapper;
@Resource @Resource
private IPatientAllInfoViewService patientAllInfoViewService; private IPatientAllInfoViewService patientAllInfoViewService;
/** /**
@ -123,16 +122,16 @@ public class SpecialDiseaseNodeServiceImpl implements ISpecialDiseaseNodeService
if (Objects.nonNull(specialDiseaseNode) && Objects.nonNull(specialDiseaseNode.getSpecialDiseaseRouteId())) { if (Objects.nonNull(specialDiseaseNode) && Objects.nonNull(specialDiseaseNode.getSpecialDiseaseRouteId())) {
SpecialDiseaseRoute specialDiseaseRoute = specialDiseaseRouteMapper.selectSpecialDiseaseRouteById(specialDiseaseNode.getSpecialDiseaseRouteId()); SpecialDiseaseRoute specialDiseaseRoute = specialDiseaseRouteMapper.selectSpecialDiseaseRouteById(specialDiseaseNode.getSpecialDiseaseRouteId());
if (specialDiseaseRoute.getParentRouteId() == null || specialDiseaseRoute.getParentRouteId() == 0) { if (specialDiseaseRoute.getParentRouteId() == null || specialDiseaseRoute.getParentRouteId() == 0) {
if (Objects.nonNull(specialDiseaseRoute) && StringUtils.isNotBlank(specialDiseaseRoute.getReleaseStatus()) && !ReleaseStatusEnum.UNPUBLISHED.getInfo().equals(specialDiseaseRoute.getReleaseStatus())) { if (Objects.nonNull(specialDiseaseRoute) && StringUtils.isNotBlank(specialDiseaseRoute.getReleaseStatus()) && !ReleaseStatusEnum.UNPUBLISHED.getInfo().equals(specialDiseaseRoute.getReleaseStatus())) {
return AjaxResult.error("已发布过的专病路径不能修改!"); return AjaxResult.error("已发布过的专病路径不能修改!");
} }
} else { } else {
// 判断主路径的发布状态 // 判断主路径的发布状态
SpecialDiseaseRoute parentRoute = specialDiseaseRouteMapper.selectSpecialDiseaseRouteById(specialDiseaseRoute.getParentRouteId()); SpecialDiseaseRoute parentRoute = specialDiseaseRouteMapper.selectSpecialDiseaseRouteById(specialDiseaseRoute.getParentRouteId());
if (Objects.nonNull(parentRoute) && StringUtils.isNotBlank(parentRoute.getReleaseStatus()) && !StringUtils.equals(ReleaseStatusEnum.UNPUBLISHED.getInfo(), specialDiseaseRoute.getReleaseStatus())) { if (Objects.nonNull(parentRoute) && StringUtils.isNotBlank(parentRoute.getReleaseStatus()) && !StringUtils.equals(ReleaseStatusEnum.UNPUBLISHED.getInfo(), specialDiseaseRoute.getReleaseStatus())) {
return AjaxResult.error("已发布过的专病路径不能修改!"); return AjaxResult.error("已发布过的专病路径不能修改!");
} }
} }
} }
List<Long> longs = specialDiseaseNodeMapper.selectSpecialDiseaseRouteIds(specialDiseaseNode.getSpecialDiseaseRouteId()); List<Long> longs = specialDiseaseNodeMapper.selectSpecialDiseaseRouteIds(specialDiseaseNode.getSpecialDiseaseRouteId());
SpecialDiseaseRoute specialDiseaseRoute = new SpecialDiseaseRoute(); SpecialDiseaseRoute specialDiseaseRoute = new SpecialDiseaseRoute();
@ -156,20 +155,18 @@ public class SpecialDiseaseNodeServiceImpl implements ISpecialDiseaseNodeService
List<SpecialDiseaseNodeVO> specialDiseaseNodeVOS = new ArrayList<>(); List<SpecialDiseaseNodeVO> specialDiseaseNodeVOS = new ArrayList<>();
int i = 0; int i = 0;
for (SpecialDiseaseNodeVO diseaseNode : specialDiseaseNode.getSpecialDiseaseNodeList()) { for (SpecialDiseaseNodeVO diseaseNode : specialDiseaseNode.getSpecialDiseaseNodeList()) {
if(StringUtils.isBlank(diseaseNode.getRouteNodeName())) { if (StringUtils.isBlank(diseaseNode.getRouteNodeName())) {
throw new ServiceException("请输入节点名称"); throw new ServiceException("请输入节点名称");
} }
if (diseaseNode.getRouteNodeDay() == null) { if (diseaseNode.getRouteNodeDay() == null) {
throw new ServiceException("请输入节点时间"); throw new ServiceException("请输入节点时间");
} }
if (StringUtils.isBlank(diseaseNode.getTaskType()) || StringUtils.isBlank(diseaseNode.getTaskSubdivision()) || StringUtils.isBlank(diseaseNode.getTaskStatus())) { if (StringUtils.isBlank(diseaseNode.getTaskType()) || StringUtils.isBlank(diseaseNode.getTaskSubdivision()) || StringUtils.isBlank(diseaseNode.getTaskStatus())) {
throw new ServiceException("任务类型、任务细分、任务状态不能为空"); throw new ServiceException("任务类型、任务细分、任务状态不能为空");
} }
diseaseNode.setRouteId(specialDiseaseRoute.getId()); diseaseNode.setRouteId(specialDiseaseRoute.getId());
diseaseNode.setRouteName(specialDiseaseNode.getRouteName()); diseaseNode.setRouteName(specialDiseaseNode.getRouteName());
diseaseNode.setTemplateType(null); if (Objects.isNull(diseaseNode.getPhonePushSign()) || diseaseNode.getPhonePushSign() == 0) {
if (StringUtils.isNotBlank(diseaseNode.getTaskSubdivisiontemplateType())
&& (TemplateTypeEnum.QUESTIONNAIRE.getInfo().equals(diseaseNode.getTaskSubdivisiontemplateType()) || TemplateTypeEnum.PROPAGANDA.getInfo().equals(diseaseNode.getTaskSubdivisiontemplateType()) || TemplateTypeEnum.SCRIPT.getInfo().equals(diseaseNode.getTaskSubdivisiontemplateType()))) {
diseaseNode.setTemplateType(diseaseNode.getTaskSubdivisiontemplateType()); diseaseNode.setTemplateType(diseaseNode.getTaskSubdivisiontemplateType());
} }
diseaseNode.setUpdateTime(LocalDateTime.now()); diseaseNode.setUpdateTime(LocalDateTime.now());
@ -281,26 +278,27 @@ public class SpecialDiseaseNodeServiceImpl implements ISpecialDiseaseNodeService
return retList; return retList;
} }
@Override public List<RouteTaskAuditVo> getByParentRouteId(Long parentRouteId) { @Override
return specialDiseaseNodeMapper.getByParentRouteId(parentRouteId); public List<RouteTaskAuditVo> getByParentRouteId(Long parentRouteId) {
} return specialDiseaseNodeMapper.getByParentRouteId(parentRouteId);
}
/** /**
* 根据任务细分类型获取患者的真实信息 * 根据任务细分类型获取患者的真实信息
* *
* @param patientId 患者主键 * @param patientId 患者主键
* @return 实际信息 * @return 实际信息
*/ */
private JSONObject getParamsValue(Long patientId) { private JSONObject getParamsValue(Long patientId) {
JSONObject retObj = new JSONObject(); JSONObject retObj = new JSONObject();
PatientAllInfoView patientAllInfoView = patientAllInfoViewService.selectPatientAllInfoViewByPatientId(patientId); PatientAllInfoView patientAllInfoView = patientAllInfoViewService.selectPatientAllInfoViewByPatientId(patientId);
if (ObjectUtils.isEmpty(patientAllInfoView)) { if (ObjectUtils.isEmpty(patientAllInfoView)) {
throw new ServiceException("患者信息获取错误,请联系管理员!"); throw new ServiceException("患者信息获取错误,请联系管理员!");
} }
retObj = JSONObject.parseObject(JSONObject.toJSONString(patientAllInfoView)); retObj = JSONObject.parseObject(JSONObject.toJSONString(patientAllInfoView));
// 性别转换成中文计算年龄 // 性别转换成中文计算年龄
retObj.fluentPut("sex", PatientSexEnum.getInfoByCode(patientAllInfoView.getSex()).getInfo()) retObj.fluentPut("sex", PatientSexEnum.getInfoByCode(patientAllInfoView.getSex()).getInfo())
.fluentPut("age", BaseUtil.getAge(patientAllInfoView.getBirthDate())); .fluentPut("age", BaseUtil.getAge(patientAllInfoView.getBirthDate()));
return retObj; return retObj;
} }
} }

View File

@ -27,4 +27,6 @@ public class SpecialDiseaseNodeVO extends SpecialDiseaseNode {
private String taskStatusName; private String taskStatusName;
private String taskSubdivisiontemplateType; private String taskSubdivisiontemplateType;
private String flowScheme;
} }

View File

@ -0,0 +1,30 @@
package com.xinelu.manage.vo.tasktypedict;
import com.xinelu.manage.domain.taskpartitiondict.TaskPartitionDict;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* 任务类型字典对象 task_type_dict
*
* @author xinelu
* @date 2024-03-11
*/
@Data
public class TaskTypeDictVO {
/**
* 主键id
*/
private Long taskTypeId;
/**
* 任务类型名称
*/
@ApiModelProperty(value = "任务类型名称")
private String taskTypeName;
private List<TaskPartitionDict> taskPartitionDictList;
}

View File

@ -360,7 +360,7 @@
<if test="portraitStatus != null"> <if test="portraitStatus != null">
and lfc.portrait_status = #{portraitStatus} and lfc.portrait_status = #{portraitStatus}
</if> </if>
Order by tpd.task_partition_sort,lfc.portrait_sn,lfc.content_sort Order by tpd.task_partition_sort,lfc.portrait_sn,lfi.field_sort
</select> </select>
<insert id="insertLabelFieldContentList"> <insert id="insertLabelFieldContentList">

View File

@ -232,17 +232,19 @@
<select id="selectLabelFieldInfoByTaskPartitionDictId" <select id="selectLabelFieldInfoByTaskPartitionDictId"
resultType="com.xinelu.manage.vo.labelfieldcontent.GroupingValue"> resultType="com.xinelu.manage.vo.labelfieldcontent.GroupingValue">
select id labelFieldInfoId, select lfi.id labelFieldInfoId,
field_name, lfi.field_name,
field_code, lfi.field_code,
field_type, lfi.field_type,
field_sort, lfi.field_sort,
field_remark, lfi.field_remark,
task_partition_dict_id, lfi.task_partition_dict_id,
task_partition_dict_name, lfi.task_partition_dict_name,
task_type_id, lfi.task_type_id,
task_type_name lfi.task_type_name
from label_field_info from label_field_info lfi
LEFT JOIN task_partition_dict tpd on tpd.id = lfi.task_partition_dict_id
LEFT JOIN task_type_dict ttd on ttd.id = tpd.task_type_id
<where> <where>
<if test="taskPartitionDictId != null and taskPartitionDictId != 0"> <if test="taskPartitionDictId != null and taskPartitionDictId != 0">
and task_partition_dict_id = #{taskPartitionDictId} and task_partition_dict_id = #{taskPartitionDictId}
@ -251,6 +253,7 @@
and task_partition_dict_id is null and task_partition_dict_id is null
</if> </if>
</where> </where>
Order by ttd.task_type_sort,tpd.task_partition_sort,lfi.field_sort
</select> </select>
<select id="selectLabelFieldNameByTaskPartitionDictIds" <select id="selectLabelFieldNameByTaskPartitionDictIds"

View File

@ -197,4 +197,17 @@
</if> </if>
</where> </where>
</select> </select>
<select id="getResidentInfoByPhoneAndName" resultType="com.xinelu.manage.domain.residentinfo.ResidentInfo">
<include refid="selectResidentInfoVo" />
<where>
del_flag = 0
<if test="phone != null and phone != ''">
and patient_phone = #{phone}
</if>
<if test="patientName != null and patientName != ''">
and patient_name = #{patientName}
</if>
</where>
</select>
</mapper> </mapper>

View File

@ -125,6 +125,7 @@
<result property="taskSubdivisionName" column="taskSubdivisionName"/> <result property="taskSubdivisionName" column="taskSubdivisionName"/>
<result property="taskStatusName" column="taskStatusName"/> <result property="taskStatusName" column="taskStatusName"/>
<result property="nodeContent" column="node_content"/> <result property="nodeContent" column="node_content"/>
<result property="flowScheme" column="flowScheme"/>
</resultMap> </resultMap>
<sql id="selectSpecialDiseaseNodeVo"> <sql id="selectSpecialDiseaseNodeVo">
@ -807,7 +808,7 @@
<select id="selectSpecialDiseaseByRouteId" <select id="selectSpecialDiseaseByRouteId"
resultType="com.xinelu.manage.vo.specialdiseaseroute.SpecialDiseaseRouteVO" resultType="com.xinelu.manage.vo.specialdiseaseroute.SpecialDiseaseRouteVO"
resultMap="SpecialDiseaseRouteResult"> resultMap="SpecialDiseaseRouteResult">
select sdr.id specialDiseaseRouteId, select sdr.id specialDiseaseRouteId,
sdr.department_id, sdr.department_id,
sdr.department_name, sdr.department_name,
sdr.disease_type_id, sdr.disease_type_id,
@ -818,7 +819,7 @@
sdr.route_classify, sdr.route_classify,
sdr.release_status, sdr.release_status,
sdr.suit_range, sdr.suit_range,
sdn.id as specialDiseaseNodeId, sdn.id as specialDiseaseNodeId,
sdn.route_id, sdn.route_id,
sdn.route_name, sdn.route_name,
sdn.route_node_name, sdn.route_node_name,
@ -865,16 +866,17 @@
sdn.route_check_remark, sdn.route_check_remark,
sdn.node_content, sdn.node_content,
sdn.phone_dial_method, sdn.phone_dial_method,
(select flow_scheme from script_info where id = sdn.phone_template_id) flowScheme,
(select COUNT(1) (select COUNT(1)
from special_disease_node from special_disease_node
where route_id = specialDiseaseRouteId) totalNumber, where route_id = specialDiseaseRouteId) totalNumber,
(select COUNT(1) (select COUNT(1)
from special_disease_node from special_disease_node
where route_id = specialDiseaseRouteId where route_id = specialDiseaseRouteId
and route_check_status = 'AGREE') agreeNumber, and route_check_status = 'AGREE') agreeNumber,
ttd.task_type_name taskTypeName, ttd.task_type_name taskTypeName,
tpd.task_partition_name taskSubdivisionName, tpd.task_partition_name taskSubdivisionName,
tsd.task_status_name taskStatusName tsd.task_status_name taskStatusName
from special_disease_route sdr from special_disease_route sdr
left join special_disease_node sdn ON sdn.route_id = sdr.id left join special_disease_node sdn ON sdn.route_id = sdr.id
left join task_type_dict ttd ON ttd.task_type_code = sdn.task_type left join task_type_dict ttd ON ttd.task_type_code = sdn.task_type

View File

@ -206,4 +206,16 @@
#{id} #{id}
</foreach> </foreach>
</delete> </delete>
<select id="selectTaskPartitionList"
resultType="com.xinelu.manage.domain.taskpartitiondict.TaskPartitionDict">
select * from task_partition_dict
<where>
task_type_id in
<foreach item="ids" collection="list" open="(" separator="," close=")">
#{ids}
</foreach>
</where>
order by task_partition_sort
</select>
</mapper> </mapper>

View File

@ -137,4 +137,11 @@
#{id} #{id}
</foreach> </foreach>
</delete> </delete>
<select id="selectTaskTypeDicts" resultType="com.xinelu.manage.vo.tasktypedict.TaskTypeDictVO">
select id taskTypeId,
task_type_name
from task_type_dict
order by task_type_sort
</select>
</mapper> </mapper>

View File

@ -39,5 +39,12 @@
<groupId>org.simpleframework</groupId> <groupId>org.simpleframework</groupId>
<artifactId>simple-xml</artifactId> <artifactId>simple-xml</artifactId>
</dependency> </dependency>
<!--阿里云发送短信-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alicloud-sms</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,5 +1,12 @@
package com.xinelu.mobile.controller; package com.xinelu.mobile.controller;
import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.xinelu.common.config.AliYunSmsConfig;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.utils.uuid.IdUtils;
import com.xinelu.mobile.dto.smssend.SmsInfoDTO;
import com.xinelu.mobile.utils.SmsSendUtils;
import com.xinelu.mobile.utils.WeChatAppletUtils; import com.xinelu.mobile.utils.WeChatAppletUtils;
import com.xinelu.mobile.utils.WeChatOfficialAccountUtils; import com.xinelu.mobile.utils.WeChatOfficialAccountUtils;
import com.xinelu.mobile.vo.wechatofficialaccountcallback.PatientVO; import com.xinelu.mobile.vo.wechatofficialaccountcallback.PatientVO;
@ -22,6 +29,10 @@ public class MobileTestController {
private WeChatAppletUtils weChatAppletUtils; private WeChatAppletUtils weChatAppletUtils;
@Resource @Resource
private WeChatOfficialAccountUtils weChatOfficialAccountUtils; private WeChatOfficialAccountUtils weChatOfficialAccountUtils;
@Resource
private SmsSendUtils smsSendUtils;
@Resource
private AliYunSmsConfig aliYunSmsConfig;
/** /**
* 测试获取微信小程序accessToken * 测试获取微信小程序accessToken
@ -54,4 +65,25 @@ public class MobileTestController {
public void sendAppletTemplate(PatientVO patientVO) { public void sendAppletTemplate(PatientVO patientVO) {
weChatOfficialAccountUtils.sendAppletTemplateMessage(patientVO); weChatOfficialAccountUtils.sendAppletTemplateMessage(patientVO);
} }
/**
*发送短信验证
*/
@GetMapping("/sendSms")
public AjaxResult sendAppletTemplate(String phoneNum) throws ClientException {
SmsInfoDTO smsInfoDTO = new SmsInfoDTO();
smsInfoDTO.setPhoneNumbers(phoneNum);
smsInfoDTO.setSignName(aliYunSmsConfig.getSignName());
smsInfoDTO.setTemplateCode(aliYunSmsConfig.getTemplateCode());
// 生成六位数验证码
String code = String.valueOf(IdUtils.generateSixDigitNumber());
JSONObject obj = new JSONObject();
obj.put("code", code);
smsInfoDTO.setTemplateParam(obj);
Boolean b = smsSendUtils.sendSms(smsInfoDTO);
if (!b) {
return AjaxResult.error("短信发送失败");
}
return AjaxResult.success("短信发送成功");
}
} }

View File

@ -4,12 +4,11 @@ import com.xinelu.common.core.controller.BaseController;
import com.xinelu.common.core.domain.AjaxResult; import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.page.TableDataInfo; import com.xinelu.common.core.page.TableDataInfo;
import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordDTO; import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordDTO;
import com.xinelu.mobile.dto.verifysmscode.VerifySmsCodeDTO;
import com.xinelu.mobile.service.appletpersoncenter.AppletPersonCenterService; import com.xinelu.mobile.service.appletpersoncenter.AppletPersonCenterService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.List;
@ -80,4 +79,40 @@ public class AppletPersonCenterController extends BaseController {
return AjaxResult.success(appletPersonCenterService.getHealthRecordInfoById(id)); return AjaxResult.success(appletPersonCenterService.getHealthRecordInfoById(id));
} }
@ApiOperation("院后微信小程序登录接口")
@GetMapping("/appletLoginV1")
public AjaxResult appletLoginV1(@RequestParam("loginCode") String loginCode) {
if (StringUtils.isBlank(loginCode)) {
return AjaxResult.error("登录凭证编码不能为空!");
}
return appletPersonCenterService.appletLoginV1(loginCode);
}
@ApiOperation("小程序登录发送短信验证码")
@GetMapping("/sendSms")
public AjaxResult sendSms(String phoneNum) {
if (StringUtils.isBlank(phoneNum)) {
return AjaxResult.error("手机号码不能为空!");
}
return appletPersonCenterService.sendSms(phoneNum);
}
@ApiOperation("小程序登录验证短信验证码")
@PostMapping("/verifySmsCode")
public AjaxResult verifySmsCode(@RequestBody VerifySmsCodeDTO verifySmsCodeDTO) {
if (StringUtils.isBlank(verifySmsCodeDTO.getOpenId())) {
return AjaxResult.error("微信小程序openid不能为空!");
}
if (StringUtils.isBlank(verifySmsCodeDTO.getPhoneNum())) {
return AjaxResult.error("手机号不能为空!");
}
if (StringUtils.isBlank(verifySmsCodeDTO.getPatientName())) {
return AjaxResult.error("姓名不能为空");
}
if (StringUtils.isBlank(verifySmsCodeDTO.getSmsCode())) {
return AjaxResult.error("短信验证码不能为空!");
}
return appletPersonCenterService.verifySmsCode(verifySmsCodeDTO);
}
} }

View File

@ -0,0 +1,34 @@
package com.xinelu.mobile.dto.smssend;
import com.alibaba.fastjson2.JSONObject;
import lombok.Data;
/**
* @program: PostDischargePatientManage
* @description: 短信发送参数DTO
* @author: yxl
* @create: 2024-07-02 21:05
**/
@Data
public class SmsInfoDTO {
/**
* :短信签名
*/
private String signName;
/**
* 待发送手机号多个用逗号隔开
*/
private String phoneNumbers;
/**
* 短信模板Code
*/
private String templateCode;
/**
* 模板中的变量替换JSON串
*/
private JSONObject templateParam;
}

View File

@ -0,0 +1,27 @@
package com.xinelu.mobile.dto.verifysmscode;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @program: PostDischargePatientManage
* @description: 验证短信验证码DTO
* @author: yxl
* @create: 2024-07-03 14:58
**/
@Data
public class VerifySmsCodeDTO {
@ApiModelProperty(value = "微信小程序openid")
private String openId;
@ApiModelProperty(value = "手机号")
private String phoneNum;
@ApiModelProperty(value = "姓名")
private String patientName;
@ApiModelProperty(value = "短信验证码")
private String smsCode;
}

View File

@ -3,6 +3,7 @@ package com.xinelu.mobile.service.appletpersoncenter;
import com.xinelu.common.core.domain.AjaxResult; import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordDTO; import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordDTO;
import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordInfoDTO; import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordInfoDTO;
import com.xinelu.mobile.dto.verifysmscode.VerifySmsCodeDTO;
import java.util.List; import java.util.List;
@ -48,4 +49,25 @@ public interface AppletPersonCenterService {
*/ */
HealthRecordInfoDTO getHealthRecordInfoById(Long id); HealthRecordInfoDTO getHealthRecordInfoById(Long id);
/**
* 院后微信小程序登录接口
* @param loginCode 登录凭证
* @return 微信小程序用户登录信息
*/
AjaxResult appletLoginV1(String loginCode);
/**
* 小程序登录发送验证码
* @param phoneNum 手机号码
* @return 发送短信验证码信息
*/
AjaxResult sendSms(String phoneNum);
/**
* 小程序登录验证短信验证码
* @param verifySmsCodeDTO 验证短信验证码DTO
* @return 验证短信验证码信息
*/
AjaxResult verifySmsCode(VerifySmsCodeDTO verifySmsCodeDTO);
} }

View File

@ -1,26 +1,36 @@
package com.xinelu.mobile.service.appletpersoncenter.Impl; package com.xinelu.mobile.service.appletpersoncenter.Impl;
import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.xinelu.common.config.AliYunSmsConfig;
import com.xinelu.common.config.WeChatAppletChatConfig; import com.xinelu.common.config.WeChatAppletChatConfig;
import com.xinelu.common.constant.Constants; import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult; import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.utils.uuid.IdUtils;
import com.xinelu.manage.domain.residentinfo.ResidentInfo; import com.xinelu.manage.domain.residentinfo.ResidentInfo;
import com.xinelu.manage.mapper.residentinfo.ResidentInfoMapper; import com.xinelu.manage.mapper.residentinfo.ResidentInfoMapper;
import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordDTO; import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordDTO;
import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordInfoDTO; import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordInfoDTO;
import com.xinelu.mobile.dto.smssend.SmsInfoDTO;
import com.xinelu.mobile.dto.verifysmscode.VerifySmsCodeDTO;
import com.xinelu.mobile.mapper.appletpersoncenter.AppletPersonCenterMapper; import com.xinelu.mobile.mapper.appletpersoncenter.AppletPersonCenterMapper;
import com.xinelu.mobile.service.appletpersoncenter.AppletPersonCenterService; import com.xinelu.mobile.service.appletpersoncenter.AppletPersonCenterService;
import com.xinelu.mobile.utils.SmsSendUtils;
import com.xinelu.mobile.utils.WeChatAppletUtils; import com.xinelu.mobile.utils.WeChatAppletUtils;
import com.xinelu.mobile.vo.appletpersoncenter.PostDischargeAppletPhoneVO; import com.xinelu.mobile.vo.appletpersoncenter.PostDischargeAppletPhoneVO;
import com.xinelu.mobile.vo.appletpersoncenter.PostDischargeAppletVO; import com.xinelu.mobile.vo.appletpersoncenter.PostDischargeAppletVO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.TimeUnit;
/** /**
* @Description 院后小程序个人中心业务层实现类 * @Description 院后小程序个人中心业务层实现类
@ -37,12 +47,17 @@ public class AppletPersonCenterServiceImpl implements AppletPersonCenterService
@Resource @Resource
private WeChatAppletChatConfig weChatAppletChatConfig; private WeChatAppletChatConfig weChatAppletChatConfig;
@Resource @Resource
private RedisTemplate<String, Object> redisTemplate; private RedisTemplate<String, String> redisTemplate;
@Resource @Resource
private ResidentInfoMapper residentInfoMapper; private ResidentInfoMapper residentInfoMapper;
@Resource @Resource
private AppletPersonCenterMapper appletPersonCenterMapper; private AppletPersonCenterMapper appletPersonCenterMapper;
@Resource
private SmsSendUtils smsSendUtils;
@Resource
private AliYunSmsConfig aliYunSmsConfig;
/** /**
* 院后微信小程序一键登录接口 * 院后微信小程序一键登录接口
* *
@ -156,4 +171,116 @@ public class AppletPersonCenterServiceImpl implements AppletPersonCenterService
} }
return healthRecordInfoDTO; return healthRecordInfoDTO;
} }
/**
* 院后微信小程序登录接口
*
* @param loginCode 登录凭证
* @return 微信小程序用户登录信息
*/
@Override
public AjaxResult appletLoginV1(String loginCode) {
//根据code获取用户的微信unionId以及openId等信息
PostDischargeAppletVO appletLoginInfo = weChatAppletUtils.getPostDischargeAppletLogin(weChatAppletChatConfig.getAppletId(), weChatAppletChatConfig.getSecret(), loginCode, weChatAppletChatConfig.getGrantType());
if (Objects.isNull(appletLoginInfo)) {
return AjaxResult.error("获取院后微信小程序用户信息失败");
}
if (Objects.nonNull(appletLoginInfo.getErrcode()) && appletLoginInfo.getErrcode() != Constants.SUCCESS_CODE) {
return AjaxResult.error("获取院后微信小程序用户信息失败,失败信息为:" + appletLoginInfo.getErrmsg());
}
String openId = StringUtils.isBlank(appletLoginInfo.getOpenid()) ? "" : appletLoginInfo.getOpenid();
ResidentInfo residentInfo = residentInfoMapper.getResidentInfoByPhoneAndOpenId(null, openId);
if (ObjectUtils.isEmpty(residentInfo)) {
return AjaxResult.success("未注册", openId);
}
return AjaxResult.success("已注册", residentInfo);
}
/**
* 小程序登录发送验证码
*
* @param phoneNum 手机号码
* @return 发送短信验证码信息
*/
@Override
public AjaxResult sendSms(String phoneNum) {
try {
String coolDownKey = Constants.SMS_COOL_DOWN + phoneNum;
String cacheKey = Constants.SMS_CODE + phoneNum;
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
// 检查是否处于冷却期
if (valueOperations.get(coolDownKey) != null) {
return AjaxResult.error("请等待60秒后再尝试发送验证码");
}
// 生成并发送新的验证码
SmsInfoDTO smsInfoDTO = new SmsInfoDTO();
smsInfoDTO.setPhoneNumbers(phoneNum);
smsInfoDTO.setSignName(aliYunSmsConfig.getSignName());
smsInfoDTO.setTemplateCode(aliYunSmsConfig.getTemplateCode());
String code = String.valueOf(IdUtils.generateSixDigitNumber());
JSONObject obj = new JSONObject();
obj.put("code", code);
smsInfoDTO.setTemplateParam(obj);
Boolean b = smsSendUtils.sendSms(smsInfoDTO);
if (!b) {
log.error("短信发送失败,手机号:{}", phoneNum);
return AjaxResult.error("短信发送失败");
}
// 更新验证码和冷却键
valueOperations.set(cacheKey, code, 5, TimeUnit.MINUTES);
valueOperations.set(coolDownKey, Constants.SMS_COOL_DOWN_VALUE, 60, TimeUnit.SECONDS);
log.info("手机号为{}的验证码已经生成", phoneNum);
return AjaxResult.success("短信发送成功");
} catch (ClientException e) {
log.error("短信发送失败,手机号:{},错误原因:{}", phoneNum, e.getMessage(), e);
return AjaxResult.error("短信发送失败");
}
}
/**
* 小程序登录验证短信验证码
*
* @param verifySmsCodeDTO 验证短信验证码DTO
* @return 验证短信验证码信息
*/
@Override
public AjaxResult verifySmsCode(VerifySmsCodeDTO verifySmsCodeDTO) {
try {
String openId = verifySmsCodeDTO.getOpenId();
String smsCode = verifySmsCodeDTO.getSmsCode();
String cacheKey = Constants.SMS_CODE + verifySmsCodeDTO.getPhoneNum();
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
String storedCode = valueOperations.get(cacheKey);
if (storedCode == null) {
log.info("验证码已过期,手机号:{}", verifySmsCodeDTO.getPhoneNum());
return AjaxResult.error("验证码已过期,请重新获取!");
}
if (!storedCode.equals(smsCode)) {
log.info("验证码验证失败,手机号:{},输入的验证码:{},获取的验证码:{}", verifySmsCodeDTO.getPhoneNum(), smsCode, storedCode);
return AjaxResult.error("验证码错误,请重新输入!");
}
log.info("验证码验证成功,手机号:{}", verifySmsCodeDTO.getPhoneNum());
List<ResidentInfo> residentInfos = residentInfoMapper.getResidentInfoByPhoneAndName(verifySmsCodeDTO.getPhoneNum(), verifySmsCodeDTO.getPatientName());
if (residentInfos == null || residentInfos.isEmpty()) {
return AjaxResult.error("您的用户信息尚未录入系统,无法执行注册操作!");
} else if (residentInfos.size() > 1) {
// 存在姓名和手机号重复的情况
return AjaxResult.error("您的信息存在重复记录,请联系管理员进行操作!");
}
ResidentInfo residentInfo = residentInfos.get(0);
residentInfo.setOpenId(openId);
residentInfoMapper.updateResidentInfo(residentInfo);
return AjaxResult.success("注册成功!", residentInfo);
} catch (Exception e) {
log.error("验证验证码时发生异常,手机号:{},异常信息:{}", verifySmsCodeDTO.getPhoneNum(), e.getMessage(), e);
return AjaxResult.error("短信验证码验证失败!");
}
}
} }

View File

@ -0,0 +1,86 @@
package com.xinelu.mobile.utils;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.xinelu.common.config.AliYunSmsConfig;
import com.xinelu.common.enums.SmsErrorCodeEnum;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.mobile.dto.smssend.SmsInfoDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @program: PostDischargePatientManage
* @description: 短信发送工具类
* @author: yxl
* @create: 2024-07-02 20:50
**/
@Component
@Slf4j
public class SmsSendUtils {
private static final String SUCCESS = "OK";
@Resource
private AliYunSmsConfig aliyunSmsConfig;
/**
* 发送短信
*/
public Boolean sendSms(SmsInfoDTO smsInfoDTO) throws ClientException, ServiceException {
try {
// 短信发送参数非空性判断
if (ObjectUtils.isEmpty(smsInfoDTO)) {
throw new ServiceException("短信发送参数不能为空!");
}
if (StringUtils.isBlank(smsInfoDTO.getPhoneNumbers())) {
throw new ServiceException("待发送手机号不能为空!");
}
if (StringUtils.isBlank(smsInfoDTO.getSignName())) {
throw new ServiceException("短信签名不能为空!");
}
if (StringUtils.isBlank(smsInfoDTO.getTemplateCode())) {
throw new ServiceException("短信模板Code不能为空!");
}
// 设置系统的默认连接超时时间和读取超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
// 初始化acsClient暂不支持region化
IClientProfile profile = DefaultProfile.getProfile(aliyunSmsConfig.getRegionId(), aliyunSmsConfig.getAccessKeyId(), aliyunSmsConfig.getAccessKeySecret());
DefaultProfile.addEndpoint(aliyunSmsConfig.getRegionId(), aliyunSmsConfig.getProduct(), aliyunSmsConfig.getDomain());
IAcsClient acsClient = new DefaultAcsClient(profile);
// 组装请求对象
SendSmsRequest request = new SendSmsRequest();
request.setPhoneNumbers(smsInfoDTO.getPhoneNumbers());
request.setSignName(smsInfoDTO.getSignName());
request.setTemplateCode(smsInfoDTO.getTemplateCode());
request.setTemplateParam(smsInfoDTO.getTemplateParam().toJSONString());
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
// 判断响应的结果
if (!SUCCESS.equals(sendSmsResponse.getCode())) {
SmsErrorCodeEnum errorCode = SmsErrorCodeEnum.getMsgByCode(sendSmsResponse.getCode());
log.error("短信发送失败,错误码:{},错误信息:{}", sendSmsResponse.getCode(), errorCode.getMessage());
return false;
}
log.info("短信发送成功code{}", sendSmsResponse.getCode());
return true;
} catch (ClientException e) {
log.error("发送短信出现异常,异常信息:{}", e.getMessage());
throw e;
}
}
}