From 2655be7e39ce0f49ab4e76ad517f49ac5fc79f5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=AA=E5=AF=92?= <2533659732@qq.com> Date: Tue, 19 Mar 2024 10:48:11 +0800 Subject: [PATCH 01/21] =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E8=AE=A2=E9=98=85=E9=80=9A=E7=9F=A5=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xinelu/common/enums/MessageTypeEnum.java | 43 ++++ .../common/enums/SubscribeStatusEnum.java | 28 +++ .../com/xinelu/generator/util/GenUtils.java | 2 +- .../xinelu/generator/util/VelocityUtils.java | 2 +- .../src/main/resources/vm/java/mapper.java.vm | 2 +- .../main/resources/vm/java/service.java.vm | 2 +- .../SubscribeMessageRecord.java | 12 +- .../SubscribeMessageRecordMapper.java | 61 ++++++ .../ISubscribeMessageRecordService.java | 61 ++++++ .../SubscribeMessageRecordServiceImpl.java | 90 ++++++++ .../SubscribeMessageRecordMapper.xml | 196 ++++++++++++++++++ 11 files changed, 489 insertions(+), 10 deletions(-) create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/enums/MessageTypeEnum.java create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/enums/SubscribeStatusEnum.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagerecord/SubscribeMessageRecordMapper.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagerecord/ISubscribeMessageRecordService.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagerecord/impl/SubscribeMessageRecordServiceImpl.java create mode 100644 postdischarge-manage/src/main/resources/mapper/manage/subscribemessagerecord/SubscribeMessageRecordMapper.xml diff --git a/postdischarge-common/src/main/java/com/xinelu/common/enums/MessageTypeEnum.java b/postdischarge-common/src/main/java/com/xinelu/common/enums/MessageTypeEnum.java new file mode 100644 index 00000000..a68bd7d2 --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/enums/MessageTypeEnum.java @@ -0,0 +1,43 @@ +package com.xinelu.common.enums; + +import lombok.Getter; + +/** + * @Description 消息推送枚举 + * @Author 纪寒 + * @Date 2024-03-19 10:12:39 + * @Version 1.0 + */ +@Getter +public enum MessageTypeEnum { + /** + * 电话外呼 + */ + PHONE_OUTBOUND("PHONE_OUTBOUND"), + + /** + * 问卷量表 + */ + QUESTIONNAIRE_SCALE("QUESTIONNAIRE_SCALE"), + + /** + * 宣教文章 + */ + PROPAGANDA_ARTICLE("QUESTIONNAIRE_SCALE"), + + /** + * 文字提醒 + */ + TEXT_REMIND("TEXT_REMIND"), + + /** + * 人工随访 + */ + ARTIFICIAL_FOLLOW_UP("ARTIFICIAL_FOLLOW_UP"), + ; + final private String value; + + MessageTypeEnum(String value) { + this.value = value; + } +} diff --git a/postdischarge-common/src/main/java/com/xinelu/common/enums/SubscribeStatusEnum.java b/postdischarge-common/src/main/java/com/xinelu/common/enums/SubscribeStatusEnum.java new file mode 100644 index 00000000..43a1c468 --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/enums/SubscribeStatusEnum.java @@ -0,0 +1,28 @@ +package com.xinelu.common.enums; + +import lombok.Getter; + +/** + * @Description 订阅状态枚举 + * @Author 纪寒 + * @Date 2024-03-19 10:20:05 + * @Version 1.0 + */ +@Getter +public enum SubscribeStatusEnum { + /** + * 接受 + */ + ACCEPT("ACCEPT"), + + /** + * 拒绝 + */ + REJECT("REJECT"); + final private String value; + + SubscribeStatusEnum(String value) { + this.value = value; + } + +} diff --git a/postdischarge-generator/src/main/java/com/xinelu/generator/util/GenUtils.java b/postdischarge-generator/src/main/java/com/xinelu/generator/util/GenUtils.java index e52a12d9..26650a2a 100644 --- a/postdischarge-generator/src/main/java/com/xinelu/generator/util/GenUtils.java +++ b/postdischarge-generator/src/main/java/com/xinelu/generator/util/GenUtils.java @@ -167,7 +167,7 @@ public class GenUtils { * * @param replacementm 替换值 * @param searchList 替换列表 - * @return + * @return 文本结果 */ public static String replaceFirst(String replacementm, String[] searchList) { String text = replacementm; diff --git a/postdischarge-generator/src/main/java/com/xinelu/generator/util/VelocityUtils.java b/postdischarge-generator/src/main/java/com/xinelu/generator/util/VelocityUtils.java index 93f1527e..a09327e0 100644 --- a/postdischarge-generator/src/main/java/com/xinelu/generator/util/VelocityUtils.java +++ b/postdischarge-generator/src/main/java/com/xinelu/generator/util/VelocityUtils.java @@ -125,7 +125,7 @@ public class VelocityUtils { * @return 模板列表 */ public static List getTemplateList(String tplCategory) { - List templates = new ArrayList(); + List templates = new ArrayList<>(); templates.add("vm/java/domain.java.vm"); templates.add("vm/java/mapper.java.vm"); templates.add("vm/java/service.java.vm"); diff --git a/postdischarge-generator/src/main/resources/vm/java/mapper.java.vm b/postdischarge-generator/src/main/resources/vm/java/mapper.java.vm index 53dad760..d34bdf4e 100644 --- a/postdischarge-generator/src/main/resources/vm/java/mapper.java.vm +++ b/postdischarge-generator/src/main/resources/vm/java/mapper.java.vm @@ -20,7 +20,7 @@ public interface ${ClassName}Mapper { * @param ${pkColumn.javaField} ${functionName}主键 * @return ${functionName} */ - public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); /** * 查询${functionName}列表 diff --git a/postdischarge-generator/src/main/resources/vm/java/service.java.vm b/postdischarge-generator/src/main/resources/vm/java/service.java.vm index 3c78d9eb..a01b640c 100644 --- a/postdischarge-generator/src/main/resources/vm/java/service.java.vm +++ b/postdischarge-generator/src/main/resources/vm/java/service.java.vm @@ -17,7 +17,7 @@ public interface I${ClassName}Service { * @param ${pkColumn.javaField} ${functionName}主键 * @return ${functionName} */ - public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); /** * 查询${functionName}列表 diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagerecord/SubscribeMessageRecord.java b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagerecord/SubscribeMessageRecord.java index 5eff7800..f0f00142 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagerecord/SubscribeMessageRecord.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagerecord/SubscribeMessageRecord.java @@ -12,7 +12,7 @@ import lombok.NoArgsConstructor; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; -import java.util.Date; +import java.time.LocalDateTime; /** * 微信小程序订阅消息记录对象 subscribe_message_record @@ -93,15 +93,15 @@ public class SubscribeMessageRecord extends BaseEntity { * 订阅时间 */ @ApiModelProperty(value = "订阅时间") - @JsonFormat(pattern = "yyyy-MM-dd") - @Excel(name = "订阅时间", width = 30, dateFormat = "yyyy-MM-dd") - private Date subscribeTime; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "订阅时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime subscribeTime; /** * 订阅状态,accept:接受,reject:拒绝 */ - @ApiModelProperty(value = "订阅状态,accept:接受,reject:拒绝") - @Excel(name = "订阅状态,accept:接受,reject:拒绝") + @ApiModelProperty(value = "订阅状态,ACCEPT:接受,REJECT:拒绝") + @Excel(name = "订阅状态,ACCEPT:接受,REJECT:拒绝") private String subscribeStatus; diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagerecord/SubscribeMessageRecordMapper.java b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagerecord/SubscribeMessageRecordMapper.java new file mode 100644 index 00000000..ae155e63 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagerecord/SubscribeMessageRecordMapper.java @@ -0,0 +1,61 @@ +package com.xinelu.manage.mapper.subscribemessagerecord; + +import com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord; + +import java.util.List; + +/** + * 微信小程序订阅消息记录Mapper接口 + * + * @author xinelu + * @date 2024-03-19 + */ +public interface SubscribeMessageRecordMapper { + /** + * 查询微信小程序订阅消息记录 + * + * @param id 微信小程序订阅消息记录主键 + * @return 微信小程序订阅消息记录 + */ + SubscribeMessageRecord selectSubscribeMessageRecordById(Long id); + + /** + * 查询微信小程序订阅消息记录列表 + * + * @param subscribeMessageRecord 微信小程序订阅消息记录 + * @return 微信小程序订阅消息记录集合 + */ + List selectSubscribeMessageRecordList(SubscribeMessageRecord subscribeMessageRecord); + + /** + * 新增微信小程序订阅消息记录 + * + * @param subscribeMessageRecord 微信小程序订阅消息记录 + * @return 结果 + */ + int insertSubscribeMessageRecord(SubscribeMessageRecord subscribeMessageRecord); + + /** + * 修改微信小程序订阅消息记录 + * + * @param subscribeMessageRecord 微信小程序订阅消息记录 + * @return 结果 + */ + int updateSubscribeMessageRecord(SubscribeMessageRecord subscribeMessageRecord); + + /** + * 删除微信小程序订阅消息记录 + * + * @param id 微信小程序订阅消息记录主键 + * @return 结果 + */ + int deleteSubscribeMessageRecordById(Long id); + + /** + * 批量删除微信小程序订阅消息记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteSubscribeMessageRecordByIds(Long[] ids); +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagerecord/ISubscribeMessageRecordService.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagerecord/ISubscribeMessageRecordService.java new file mode 100644 index 00000000..ac244ec0 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagerecord/ISubscribeMessageRecordService.java @@ -0,0 +1,61 @@ +package com.xinelu.manage.service.subscribemessagerecord; + +import com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord; + +import java.util.List; + +/** + * 微信小程序订阅消息记录Service接口 + * + * @author xinelu + * @date 2024-03-19 + */ +public interface ISubscribeMessageRecordService { + /** + * 查询微信小程序订阅消息记录 + * + * @param id 微信小程序订阅消息记录主键 + * @return 微信小程序订阅消息记录 + */ + SubscribeMessageRecord selectSubscribeMessageRecordById(Long id); + + /** + * 查询微信小程序订阅消息记录列表 + * + * @param subscribeMessageRecord 微信小程序订阅消息记录 + * @return 微信小程序订阅消息记录集合 + */ + List selectSubscribeMessageRecordList(SubscribeMessageRecord subscribeMessageRecord); + + /** + * 新增微信小程序订阅消息记录 + * + * @param subscribeMessageRecord 微信小程序订阅消息记录 + * @return 结果 + */ + int insertSubscribeMessageRecord(SubscribeMessageRecord subscribeMessageRecord); + + /** + * 修改微信小程序订阅消息记录 + * + * @param subscribeMessageRecord 微信小程序订阅消息记录 + * @return 结果 + */ + int updateSubscribeMessageRecord(SubscribeMessageRecord subscribeMessageRecord); + + /** + * 批量删除微信小程序订阅消息记录 + * + * @param ids 需要删除的微信小程序订阅消息记录主键集合 + * @return 结果 + */ + int deleteSubscribeMessageRecordByIds(Long[] ids); + + /** + * 删除微信小程序订阅消息记录信息 + * + * @param id 微信小程序订阅消息记录主键 + * @return 结果 + */ + int deleteSubscribeMessageRecordById(Long id); +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagerecord/impl/SubscribeMessageRecordServiceImpl.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagerecord/impl/SubscribeMessageRecordServiceImpl.java new file mode 100644 index 00000000..7319f48b --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagerecord/impl/SubscribeMessageRecordServiceImpl.java @@ -0,0 +1,90 @@ +package com.xinelu.manage.service.subscribemessagerecord.impl; + +import com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord; +import com.xinelu.manage.mapper.subscribemessagerecord.SubscribeMessageRecordMapper; +import com.xinelu.manage.service.subscribemessagerecord.ISubscribeMessageRecordService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 微信小程序订阅消息记录Service业务层处理 + * + * @author xinelu + * @date 2024-03-19 + */ +@Service +public class SubscribeMessageRecordServiceImpl implements ISubscribeMessageRecordService { + @Resource + private SubscribeMessageRecordMapper subscribeMessageRecordMapper; + + /** + * 查询微信小程序订阅消息记录 + * + * @param id 微信小程序订阅消息记录主键 + * @return 微信小程序订阅消息记录 + */ + @Override + public SubscribeMessageRecord selectSubscribeMessageRecordById(Long id) { + return subscribeMessageRecordMapper.selectSubscribeMessageRecordById(id); + } + + /** + * 查询微信小程序订阅消息记录列表 + * + * @param subscribeMessageRecord 微信小程序订阅消息记录 + * @return 微信小程序订阅消息记录 + */ + @Override + public List selectSubscribeMessageRecordList(SubscribeMessageRecord subscribeMessageRecord) { + return subscribeMessageRecordMapper.selectSubscribeMessageRecordList(subscribeMessageRecord); + } + + /** + * 新增微信小程序订阅消息记录 + * + * @param subscribeMessageRecord 微信小程序订阅消息记录 + * @return 结果 + */ + @Override + public int insertSubscribeMessageRecord(SubscribeMessageRecord subscribeMessageRecord) { + subscribeMessageRecord.setCreateTime(LocalDateTime.now()); + return subscribeMessageRecordMapper.insertSubscribeMessageRecord(subscribeMessageRecord); + } + + /** + * 修改微信小程序订阅消息记录 + * + * @param subscribeMessageRecord 微信小程序订阅消息记录 + * @return 结果 + */ + @Override + public int updateSubscribeMessageRecord(SubscribeMessageRecord subscribeMessageRecord) { + subscribeMessageRecord.setUpdateTime(LocalDateTime.now()); + return subscribeMessageRecordMapper.updateSubscribeMessageRecord(subscribeMessageRecord); + } + + /** + * 批量删除微信小程序订阅消息记录 + * + * @param ids 需要删除的微信小程序订阅消息记录主键 + * @return 结果 + */ + @Override + public int deleteSubscribeMessageRecordByIds(Long[] ids) { + return subscribeMessageRecordMapper.deleteSubscribeMessageRecordByIds(ids); + } + + /** + * 删除微信小程序订阅消息记录信息 + * + * @param id 微信小程序订阅消息记录主键 + * @return 结果 + */ + @Override + public int deleteSubscribeMessageRecordById(Long id) { + return subscribeMessageRecordMapper.deleteSubscribeMessageRecordById(id); + } +} diff --git a/postdischarge-manage/src/main/resources/mapper/manage/subscribemessagerecord/SubscribeMessageRecordMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/subscribemessagerecord/SubscribeMessageRecordMapper.xml new file mode 100644 index 00000000..8072f8ea --- /dev/null +++ b/postdischarge-manage/src/main/resources/mapper/manage/subscribemessagerecord/SubscribeMessageRecordMapper.xml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + select id, patient_id, manage_route_node_id, unionid, openid, applet_id, template_id, message_type, subscribe_count, subscribe_time, subscribe_status, create_by, create_time, update_by, update_time from subscribe_message_record + + + + + + + + insert into subscribe_message_record + + patient_id, + + manage_route_node_id, + + unionid, + + openid, + + applet_id, + + template_id, + + message_type, + + subscribe_count, + + subscribe_time, + + subscribe_status, + + create_by, + + create_time, + + update_by, + + update_time, + + + + #{patientId}, + + #{manageRouteNodeId}, + + #{unionid}, + + #{openid}, + + #{appletId}, + + #{templateId}, + + #{messageType}, + + #{subscribeCount}, + + #{subscribeTime}, + + #{subscribeStatus}, + + #{createBy}, + + #{createTime}, + + #{updateBy}, + + #{updateTime}, + + + + + + update subscribe_message_record + + patient_id = + #{patientId}, + + manage_route_node_id = + #{manageRouteNodeId}, + + unionid = + #{unionid}, + + openid = + #{openid}, + + applet_id = + #{appletId}, + + template_id = + #{templateId}, + + message_type = + #{messageType}, + + subscribe_count = + #{subscribeCount}, + + subscribe_time = + #{subscribeTime}, + + subscribe_status = + #{subscribeStatus}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + + where id = #{id} + + + + delete from subscribe_message_record where id = #{id} + + + + delete from subscribe_message_record where id in + + #{id} + + + \ No newline at end of file From 0c1c45088f88f06b2a4966a28d7f2ca1c78cfa64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=AA=E5=AF=92?= <2533659732@qq.com> Date: Tue, 19 Mar 2024 11:14:22 +0800 Subject: [PATCH 02/21] =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E8=AE=A2=E9=98=85=E9=80=9A=E7=9F=A5=E7=BB=93=E6=9E=9C?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xinelu/common/enums/ErrorStatusEnum.java | 27 +++ .../common/enums/SubscribeStatusEnum.java | 4 +- .../main/resources/vm/java/controller.java.vm | 12 +- .../src/main/resources/vm/java/domain.java.vm | 8 +- .../resources/vm/java/serviceImpl.java.vm | 4 +- .../main/resources/vm/java/sub-domain.java.vm | 2 +- .../SubscribeMessageRecordController.java | 91 ++++++++ .../SubscribeMessageSendRecordController.java | 91 ++++++++ .../SubscribeMessageSendRecord.java | 136 ++++++++++++ .../SubscribeMessageSendRecordMapper.java | 61 ++++++ .../ISubscribeMessageSendRecordService.java | 61 ++++++ ...SubscribeMessageSendRecordServiceImpl.java | 90 ++++++++ .../SubscribeMessageSendRecordMapper.xml | 207 ++++++++++++++++++ 13 files changed, 779 insertions(+), 15 deletions(-) create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/enums/ErrorStatusEnum.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/controller/subscribemessagerecord/SubscribeMessageRecordController.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/controller/subscribemessagesendrecord/SubscribeMessageSendRecordController.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagesendrecord/SubscribeMessageSendRecord.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagesendrecord/ISubscribeMessageSendRecordService.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagesendrecord/impl/SubscribeMessageSendRecordServiceImpl.java create mode 100644 postdischarge-manage/src/main/resources/mapper/manage/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.xml diff --git a/postdischarge-common/src/main/java/com/xinelu/common/enums/ErrorStatusEnum.java b/postdischarge-common/src/main/java/com/xinelu/common/enums/ErrorStatusEnum.java new file mode 100644 index 00000000..7f0e5084 --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/enums/ErrorStatusEnum.java @@ -0,0 +1,27 @@ +package com.xinelu.common.enums; + +import lombok.Getter; + +/** + * @Description 小程序消息推送结果状态枚举 + * @Author 纪寒 + * @Date 2024-03-19 10:57:43 + * @Version 1.0 + */ +@Getter +public enum ErrorStatusEnum { + /** + * 成功 + */ + success("success"), + + /** + * 失败 + */ + fail("fail"); + final private String value; + + ErrorStatusEnum(String value) { + this.value = value; + } +} diff --git a/postdischarge-common/src/main/java/com/xinelu/common/enums/SubscribeStatusEnum.java b/postdischarge-common/src/main/java/com/xinelu/common/enums/SubscribeStatusEnum.java index 43a1c468..02a508d5 100644 --- a/postdischarge-common/src/main/java/com/xinelu/common/enums/SubscribeStatusEnum.java +++ b/postdischarge-common/src/main/java/com/xinelu/common/enums/SubscribeStatusEnum.java @@ -13,12 +13,12 @@ public enum SubscribeStatusEnum { /** * 接受 */ - ACCEPT("ACCEPT"), + accept("accept"), /** * 拒绝 */ - REJECT("REJECT"); + rejet("rejet"); final private String value; SubscribeStatusEnum(String value) { diff --git a/postdischarge-generator/src/main/resources/vm/java/controller.java.vm b/postdischarge-generator/src/main/resources/vm/java/controller.java.vm index 61e42e16..0d083087 100644 --- a/postdischarge-generator/src/main/resources/vm/java/controller.java.vm +++ b/postdischarge-generator/src/main/resources/vm/java/controller.java.vm @@ -13,15 +13,15 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.xinyilu.common.annotation.Log; -import com.xinyilu.common.core.controller.BaseController; -import com.xinyilu.common.core.domain.AjaxResult; -import com.xinyilu.common.enums.BusinessType; +import com.xinelu.common.annotation.Log; +import com.xinelu.common.core.controller.BaseController; +import com.xinelu.common.core.domain.AjaxResult; +import com.xinelu.common.enums.BusinessType; import ${packageName}.domain.${ClassName}; import ${packageName}.service.I${ClassName}Service; -import com.xinyilu.common.utils.poi.ExcelUtil; +import com.xinelu.common.utils.poi.ExcelUtil; #if($table.crud || $table.sub) -import com.xinyilu.common.core.page.TableDataInfo; +import com.xinelu.common.core.page.TableDataInfo; #elseif($table.tree) #end diff --git a/postdischarge-generator/src/main/resources/vm/java/domain.java.vm b/postdischarge-generator/src/main/resources/vm/java/domain.java.vm index ea4fe7cb..07624d51 100644 --- a/postdischarge-generator/src/main/resources/vm/java/domain.java.vm +++ b/postdischarge-generator/src/main/resources/vm/java/domain.java.vm @@ -13,11 +13,11 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; -import com.xinyilu.common.annotation.Excel; +import com.xinelu.common.annotation.Excel; #if($table.crud) -import com.xinyilu.common.core.domain.BaseEntity; +import com.xinelu.common.core.domain.BaseEntity; #elseif($table.tree) -import com.xinyilu.common.core.domain.TreeEntity; +import com.xinelu.common.core.domain.TreeEntity; #end /** @@ -32,7 +32,7 @@ import com.xinyilu.common.core.domain.TreeEntity; @EqualsAndHashCode(callSuper = true) @ApiModel(value = "${functionName}对象", description = "${tableName}") #if($table.crud) - #set($Entity="BaseDomain") + #set($Entity="BaseEntity") #elseif($table.tree) #set($Entity="TreeEntity") #end diff --git a/postdischarge-generator/src/main/resources/vm/java/serviceImpl.java.vm b/postdischarge-generator/src/main/resources/vm/java/serviceImpl.java.vm index d3c6ef7c..8b32f9ff 100644 --- a/postdischarge-generator/src/main/resources/vm/java/serviceImpl.java.vm +++ b/postdischarge-generator/src/main/resources/vm/java/serviceImpl.java.vm @@ -4,7 +4,7 @@ import java.time.LocalDateTime; import java.util.List; #foreach ($column in $columns) #if($column.javaField == 'createTime' || $column.javaField == 'updateTime') - import com.xinyilu.common.utils.DateUtils; + import com.xinelu.common.utils.DateUtils; #break #end #end @@ -13,7 +13,7 @@ import org.springframework.stereotype.Service; #if($table.sub) import java.util.ArrayList; - import com.xinyilu.common.utils.StringUtils; + import com.xinelu.common.utils.StringUtils; import org.springframework.transaction.annotation.Transactional; import ${packageName}.domain.${subClassName}; #end diff --git a/postdischarge-generator/src/main/resources/vm/java/sub-domain.java.vm b/postdischarge-generator/src/main/resources/vm/java/sub-domain.java.vm index f69d2548..c753cf0d 100644 --- a/postdischarge-generator/src/main/resources/vm/java/sub-domain.java.vm +++ b/postdischarge-generator/src/main/resources/vm/java/sub-domain.java.vm @@ -3,7 +3,7 @@ package ${packageName}.domain; #foreach ($import in $subImportList) import ${import}; #end -import com.xinyilu.common.annotation.Excel; +import com.xinelu.common.annotation.Excel; /** * ${subTable.functionName}对象 ${subTableName} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/controller/subscribemessagerecord/SubscribeMessageRecordController.java b/postdischarge-manage/src/main/java/com/xinelu/manage/controller/subscribemessagerecord/SubscribeMessageRecordController.java new file mode 100644 index 00000000..f20e9719 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/controller/subscribemessagerecord/SubscribeMessageRecordController.java @@ -0,0 +1,91 @@ +package com.xinelu.manage.controller.subscribemessagerecord; + +import com.xinelu.common.annotation.Log; +import com.xinelu.common.core.controller.BaseController; +import com.xinelu.common.core.domain.AjaxResult; +import com.xinelu.common.core.page.TableDataInfo; +import com.xinelu.common.enums.BusinessType; +import com.xinelu.common.utils.poi.ExcelUtil; +import com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord; +import com.xinelu.manage.service.subscribemessagerecord.ISubscribeMessageRecordService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 微信小程序订阅消息记录Controller + * + * @author xinelu + * @date 2024-03-19 + */ +@RestController +@RequestMapping("/manage/sendRecord") +public class SubscribeMessageRecordController extends BaseController { + @Resource + private ISubscribeMessageRecordService subscribeMessageRecordService; + + /** + * 查询微信小程序订阅消息记录列表 + */ + @PreAuthorize("@ss.hasPermi('manage:sendRecord:list')") + @GetMapping("/list") + public TableDataInfo list(SubscribeMessageRecord subscribeMessageRecord) { + startPage(); + List list = subscribeMessageRecordService.selectSubscribeMessageRecordList(subscribeMessageRecord); + return getDataTable(list); + } + + /** + * 导出微信小程序订阅消息记录列表 + */ + @PreAuthorize("@ss.hasPermi('manage:sendRecord:export')") + @Log(title = "微信小程序订阅消息记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SubscribeMessageRecord subscribeMessageRecord) { + List list = subscribeMessageRecordService.selectSubscribeMessageRecordList(subscribeMessageRecord); + ExcelUtil util = new ExcelUtil<>(SubscribeMessageRecord.class); + util.exportExcel(response, list, "微信小程序订阅消息记录数据"); + } + + /** + * 获取微信小程序订阅消息记录详细信息 + */ + @PreAuthorize("@ss.hasPermi('manage:sendRecord:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) { + return AjaxResult.success(subscribeMessageRecordService.selectSubscribeMessageRecordById(id)); + } + + /** + * 新增微信小程序订阅消息记录 + */ + @PreAuthorize("@ss.hasPermi('manage:sendRecord:add')") + @Log(title = "微信小程序订阅消息记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SubscribeMessageRecord subscribeMessageRecord) { + return toAjax(subscribeMessageRecordService.insertSubscribeMessageRecord(subscribeMessageRecord)); + } + + /** + * 修改微信小程序订阅消息记录 + */ + @PreAuthorize("@ss.hasPermi('manage:sendRecord:edit')") + @Log(title = "微信小程序订阅消息记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SubscribeMessageRecord subscribeMessageRecord) { + return toAjax(subscribeMessageRecordService.updateSubscribeMessageRecord(subscribeMessageRecord)); + } + + /** + * 删除微信小程序订阅消息记录 + */ + @PreAuthorize("@ss.hasPermi('manage:sendRecord:remove')") + @Log(title = "微信小程序订阅消息记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) { + return toAjax(subscribeMessageRecordService.deleteSubscribeMessageRecordByIds(ids)); + } +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/controller/subscribemessagesendrecord/SubscribeMessageSendRecordController.java b/postdischarge-manage/src/main/java/com/xinelu/manage/controller/subscribemessagesendrecord/SubscribeMessageSendRecordController.java new file mode 100644 index 00000000..bcc6a418 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/controller/subscribemessagesendrecord/SubscribeMessageSendRecordController.java @@ -0,0 +1,91 @@ +package com.xinelu.manage.controller.subscribemessagesendrecord; + +import com.xinelu.common.annotation.Log; +import com.xinelu.common.core.controller.BaseController; +import com.xinelu.common.core.domain.AjaxResult; +import com.xinelu.common.core.page.TableDataInfo; +import com.xinelu.common.enums.BusinessType; +import com.xinelu.common.utils.poi.ExcelUtil; +import com.xinelu.manage.domain.subscribemessagesendrecord.SubscribeMessageSendRecord; +import com.xinelu.manage.service.subscribemessagesendrecord.ISubscribeMessageSendRecordService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 微信小程序订阅消息发送结果记录Controller + * + * @author xinelu + * @date 2024-03-19 + */ +@RestController +@RequestMapping("/manage/sendResult") +public class SubscribeMessageSendRecordController extends BaseController { + @Resource + private ISubscribeMessageSendRecordService subscribeMessageSendRecordService; + + /** + * 查询微信小程序订阅消息发送结果记录列表 + */ + @PreAuthorize("@ss.hasPermi('manage:sendResult:list')") + @GetMapping("/list") + public TableDataInfo list(SubscribeMessageSendRecord subscribeMessageSendRecord) { + startPage(); + List list = subscribeMessageSendRecordService.selectSubscribeMessageSendRecordList(subscribeMessageSendRecord); + return getDataTable(list); + } + + /** + * 导出微信小程序订阅消息发送结果记录列表 + */ + @PreAuthorize("@ss.hasPermi('manage:sendResult:export')") + @Log(title = "微信小程序订阅消息发送结果记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SubscribeMessageSendRecord subscribeMessageSendRecord) { + List list = subscribeMessageSendRecordService.selectSubscribeMessageSendRecordList(subscribeMessageSendRecord); + ExcelUtil util = new ExcelUtil<>(SubscribeMessageSendRecord.class); + util.exportExcel(response, list, "微信小程序订阅消息发送结果记录数据"); + } + + /** + * 获取微信小程序订阅消息发送结果记录详细信息 + */ + @PreAuthorize("@ss.hasPermi('manage:sendResult:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) { + return AjaxResult.success(subscribeMessageSendRecordService.selectSubscribeMessageSendRecordById(id)); + } + + /** + * 新增微信小程序订阅消息发送结果记录 + */ + @PreAuthorize("@ss.hasPermi('manage:sendResult:add')") + @Log(title = "微信小程序订阅消息发送结果记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SubscribeMessageSendRecord subscribeMessageSendRecord) { + return toAjax(subscribeMessageSendRecordService.insertSubscribeMessageSendRecord(subscribeMessageSendRecord)); + } + + /** + * 修改微信小程序订阅消息发送结果记录 + */ + @PreAuthorize("@ss.hasPermi('manage:sendResult:edit')") + @Log(title = "微信小程序订阅消息发送结果记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SubscribeMessageSendRecord subscribeMessageSendRecord) { + return toAjax(subscribeMessageSendRecordService.updateSubscribeMessageSendRecord(subscribeMessageSendRecord)); + } + + /** + * 删除微信小程序订阅消息发送结果记录 + */ + @PreAuthorize("@ss.hasPermi('manage:sendResult:remove')") + @Log(title = "微信小程序订阅消息发送结果记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) { + return toAjax(subscribeMessageSendRecordService.deleteSubscribeMessageSendRecordByIds(ids)); + } +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagesendrecord/SubscribeMessageSendRecord.java b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagesendrecord/SubscribeMessageSendRecord.java new file mode 100644 index 00000000..45aef908 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagesendrecord/SubscribeMessageSendRecord.java @@ -0,0 +1,136 @@ +package com.xinelu.manage.domain.subscribemessagesendrecord; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.xinelu.common.annotation.Excel; +import com.xinelu.common.core.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.time.LocalDateTime; + +/** + * 微信小程序订阅消息发送结果记录对象 subscribe_message_send_record + * + * @author xinelu + * @date 2024-03-19 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +@ApiModel(value = "微信小程序订阅消息发送结果记录对象", description = "subscribe_message_send_record") +public class SubscribeMessageSendRecord extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + private Long id; + + /** + * 患者id + */ + @ApiModelProperty(value = "患者id") + @Excel(name = "患者id") + private Long patientId; + + /** + * 签约患者管理任务节点表id + */ + @ApiModelProperty(value = "签约患者管理任务节点表id") + @Excel(name = "签约患者管理任务节点表id") + private Long manageRouteNodeId; + + /** + * 微信unionid + */ + @ApiModelProperty(value = "微信unionid") + @Excel(name = "微信unionid") + private String unionid; + + /** + * 微信openid + */ + @ApiModelProperty(value = "微信openid") + @Excel(name = "微信openid") + private String openid; + + /** + * 微信小程序id + */ + @ApiModelProperty(value = "微信小程序id") + @Excel(name = "微信小程序id") + private String appletId; + + /** + * 订阅消息发送时间 + */ + @ApiModelProperty(value = "订阅消息发送时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "订阅消息发送时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime subscribeTime; + + /** + * 消息模板id + */ + @ApiModelProperty(value = "消息模板id") + @Excel(name = "消息模板id") + private String templateId; + + /** + * 消息id + */ + @ApiModelProperty(value = "消息id") + @Excel(name = "消息id") + private String msgId; + + /** + * 订阅任务消息类型,电话外呼:PHONE_OUTBOUND,问卷量表:QUESTIONNAIRE_SCALE,宣教文章:PROPAGANDA_ARTICLE,文字提醒:TEXT_REMIND,人工随访:ARTIFICIAL_FOLLOW_UP + */ + @ApiModelProperty(value = "订阅任务消息类型,电话外呼:PHONE_OUTBOUND,问卷量表:QUESTIONNAIRE_SCALE,宣教文章:PROPAGANDA_ARTICLE,文字提醒:TEXT_REMIND,人工随访:ARTIFICIAL_FOLLOW_UP") + @Excel(name = "订阅任务消息类型,电话外呼:PHONE_OUTBOUND,问卷量表:QUESTIONNAIRE_SCALE,宣教文章:PROPAGANDA_ARTICLE,文字提醒:TEXT_REMIND,人工随访:ARTIFICIAL_FOLLOW_UP") + private String messageType; + + /** + * 推送结果状态码(0表示成功) + */ + @ApiModelProperty(value = "推送结果状态码") + @Excel(name = "推送结果状态码", readConverterExp = "0=表示成功") + private Long errorCode; + + /** + * 推送结果状态码,success:成功 + */ + @ApiModelProperty(value = "推送结果状态码,success:成功,fail:失败") + @Excel(name = "推送结果状态码,success:成功, fail:失败") + private String errorStatus; + + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("patientId", getPatientId()) + .append("manageRouteNodeId", getManageRouteNodeId()) + .append("unionid", getUnionid()) + .append("openid", getOpenid()) + .append("appletId", getAppletId()) + .append("subscribeTime", getSubscribeTime()) + .append("templateId", getTemplateId()) + .append("msgId", getMsgId()) + .append("messageType", getMessageType()) + .append("errorCode", getErrorCode()) + .append("errorStatus", getErrorStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.java b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.java new file mode 100644 index 00000000..3784205d --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.java @@ -0,0 +1,61 @@ +package com.xinelu.manage.mapper.subscribemessagesendrecord; + +import com.xinelu.manage.domain.subscribemessagesendrecord.SubscribeMessageSendRecord; + +import java.util.List; + +/** + * 微信小程序订阅消息发送结果记录Mapper接口 + * + * @author xinelu + * @date 2024-03-19 + */ +public interface SubscribeMessageSendRecordMapper { + /** + * 查询微信小程序订阅消息发送结果记录 + * + * @param id 微信小程序订阅消息发送结果记录主键 + * @return 微信小程序订阅消息发送结果记录 + */ + SubscribeMessageSendRecord selectSubscribeMessageSendRecordById(Long id); + + /** + * 查询微信小程序订阅消息发送结果记录列表 + * + * @param subscribeMessageSendRecord 微信小程序订阅消息发送结果记录 + * @return 微信小程序订阅消息发送结果记录集合 + */ + List selectSubscribeMessageSendRecordList(SubscribeMessageSendRecord subscribeMessageSendRecord); + + /** + * 新增微信小程序订阅消息发送结果记录 + * + * @param subscribeMessageSendRecord 微信小程序订阅消息发送结果记录 + * @return 结果 + */ + int insertSubscribeMessageSendRecord(SubscribeMessageSendRecord subscribeMessageSendRecord); + + /** + * 修改微信小程序订阅消息发送结果记录 + * + * @param subscribeMessageSendRecord 微信小程序订阅消息发送结果记录 + * @return 结果 + */ + int updateSubscribeMessageSendRecord(SubscribeMessageSendRecord subscribeMessageSendRecord); + + /** + * 删除微信小程序订阅消息发送结果记录 + * + * @param id 微信小程序订阅消息发送结果记录主键 + * @return 结果 + */ + int deleteSubscribeMessageSendRecordById(Long id); + + /** + * 批量删除微信小程序订阅消息发送结果记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteSubscribeMessageSendRecordByIds(Long[] ids); +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagesendrecord/ISubscribeMessageSendRecordService.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagesendrecord/ISubscribeMessageSendRecordService.java new file mode 100644 index 00000000..1676e22f --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagesendrecord/ISubscribeMessageSendRecordService.java @@ -0,0 +1,61 @@ +package com.xinelu.manage.service.subscribemessagesendrecord; + +import com.xinelu.manage.domain.subscribemessagesendrecord.SubscribeMessageSendRecord; + +import java.util.List; + +/** + * 微信小程序订阅消息发送结果记录Service接口 + * + * @author xinelu + * @date 2024-03-19 + */ +public interface ISubscribeMessageSendRecordService { + /** + * 查询微信小程序订阅消息发送结果记录 + * + * @param id 微信小程序订阅消息发送结果记录主键 + * @return 微信小程序订阅消息发送结果记录 + */ + SubscribeMessageSendRecord selectSubscribeMessageSendRecordById(Long id); + + /** + * 查询微信小程序订阅消息发送结果记录列表 + * + * @param subscribeMessageSendRecord 微信小程序订阅消息发送结果记录 + * @return 微信小程序订阅消息发送结果记录集合 + */ + List selectSubscribeMessageSendRecordList(SubscribeMessageSendRecord subscribeMessageSendRecord); + + /** + * 新增微信小程序订阅消息发送结果记录 + * + * @param subscribeMessageSendRecord 微信小程序订阅消息发送结果记录 + * @return 结果 + */ + int insertSubscribeMessageSendRecord(SubscribeMessageSendRecord subscribeMessageSendRecord); + + /** + * 修改微信小程序订阅消息发送结果记录 + * + * @param subscribeMessageSendRecord 微信小程序订阅消息发送结果记录 + * @return 结果 + */ + int updateSubscribeMessageSendRecord(SubscribeMessageSendRecord subscribeMessageSendRecord); + + /** + * 批量删除微信小程序订阅消息发送结果记录 + * + * @param ids 需要删除的微信小程序订阅消息发送结果记录主键集合 + * @return 结果 + */ + int deleteSubscribeMessageSendRecordByIds(Long[] ids); + + /** + * 删除微信小程序订阅消息发送结果记录信息 + * + * @param id 微信小程序订阅消息发送结果记录主键 + * @return 结果 + */ + int deleteSubscribeMessageSendRecordById(Long id); +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagesendrecord/impl/SubscribeMessageSendRecordServiceImpl.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagesendrecord/impl/SubscribeMessageSendRecordServiceImpl.java new file mode 100644 index 00000000..f6bed21a --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/subscribemessagesendrecord/impl/SubscribeMessageSendRecordServiceImpl.java @@ -0,0 +1,90 @@ +package com.xinelu.manage.service.subscribemessagesendrecord.impl; + +import com.xinelu.manage.domain.subscribemessagesendrecord.SubscribeMessageSendRecord; +import com.xinelu.manage.mapper.subscribemessagesendrecord.SubscribeMessageSendRecordMapper; +import com.xinelu.manage.service.subscribemessagesendrecord.ISubscribeMessageSendRecordService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 微信小程序订阅消息发送结果记录Service业务层处理 + * + * @author xinelu + * @date 2024-03-19 + */ +@Service +public class SubscribeMessageSendRecordServiceImpl implements ISubscribeMessageSendRecordService { + @Resource + private SubscribeMessageSendRecordMapper subscribeMessageSendRecordMapper; + + /** + * 查询微信小程序订阅消息发送结果记录 + * + * @param id 微信小程序订阅消息发送结果记录主键 + * @return 微信小程序订阅消息发送结果记录 + */ + @Override + public SubscribeMessageSendRecord selectSubscribeMessageSendRecordById(Long id) { + return subscribeMessageSendRecordMapper.selectSubscribeMessageSendRecordById(id); + } + + /** + * 查询微信小程序订阅消息发送结果记录列表 + * + * @param subscribeMessageSendRecord 微信小程序订阅消息发送结果记录 + * @return 微信小程序订阅消息发送结果记录 + */ + @Override + public List selectSubscribeMessageSendRecordList(SubscribeMessageSendRecord subscribeMessageSendRecord) { + return subscribeMessageSendRecordMapper.selectSubscribeMessageSendRecordList(subscribeMessageSendRecord); + } + + /** + * 新增微信小程序订阅消息发送结果记录 + * + * @param subscribeMessageSendRecord 微信小程序订阅消息发送结果记录 + * @return 结果 + */ + @Override + public int insertSubscribeMessageSendRecord(SubscribeMessageSendRecord subscribeMessageSendRecord) { + subscribeMessageSendRecord.setCreateTime(LocalDateTime.now()); + return subscribeMessageSendRecordMapper.insertSubscribeMessageSendRecord(subscribeMessageSendRecord); + } + + /** + * 修改微信小程序订阅消息发送结果记录 + * + * @param subscribeMessageSendRecord 微信小程序订阅消息发送结果记录 + * @return 结果 + */ + @Override + public int updateSubscribeMessageSendRecord(SubscribeMessageSendRecord subscribeMessageSendRecord) { + subscribeMessageSendRecord.setUpdateTime(LocalDateTime.now()); + return subscribeMessageSendRecordMapper.updateSubscribeMessageSendRecord(subscribeMessageSendRecord); + } + + /** + * 批量删除微信小程序订阅消息发送结果记录 + * + * @param ids 需要删除的微信小程序订阅消息发送结果记录主键 + * @return 结果 + */ + @Override + public int deleteSubscribeMessageSendRecordByIds(Long[] ids) { + return subscribeMessageSendRecordMapper.deleteSubscribeMessageSendRecordByIds(ids); + } + + /** + * 删除微信小程序订阅消息发送结果记录信息 + * + * @param id 微信小程序订阅消息发送结果记录主键 + * @return 结果 + */ + @Override + public int deleteSubscribeMessageSendRecordById(Long id) { + return subscribeMessageSendRecordMapper.deleteSubscribeMessageSendRecordById(id); + } +} diff --git a/postdischarge-manage/src/main/resources/mapper/manage/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.xml new file mode 100644 index 00000000..e7633f1e --- /dev/null +++ b/postdischarge-manage/src/main/resources/mapper/manage/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.xml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select id, patient_id, manage_route_node_id, unionid, openid, applet_id, subscribe_time, template_id, msg_id, message_type, error_code, error_status, create_by, create_time, update_by, update_time from subscribe_message_send_record + + + + + + + + insert into subscribe_message_send_record + + patient_id, + + manage_route_node_id, + + unionid, + + openid, + + applet_id, + + subscribe_time, + + template_id, + + msg_id, + + message_type, + + error_code, + + error_status, + + create_by, + + create_time, + + update_by, + + update_time, + + + + #{patientId}, + + #{manageRouteNodeId}, + + #{unionid}, + + #{openid}, + + #{appletId}, + + #{subscribeTime}, + + #{templateId}, + + #{msgId}, + + #{messageType}, + + #{errorCode}, + + #{errorStatus}, + + #{createBy}, + + #{createTime}, + + #{updateBy}, + + #{updateTime}, + + + + + + update subscribe_message_send_record + + patient_id = + #{patientId}, + + manage_route_node_id = + #{manageRouteNodeId}, + + unionid = + #{unionid}, + + openid = + #{openid}, + + applet_id = + #{appletId}, + + subscribe_time = + #{subscribeTime}, + + template_id = + #{templateId}, + + msg_id = + #{msgId}, + + message_type = + #{messageType}, + + error_code = + #{errorCode}, + + error_status = + #{errorStatus}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + + where id = #{id} + + + + delete from subscribe_message_send_record where id = #{id} + + + + delete from subscribe_message_send_record where id in + + #{id} + + + \ No newline at end of file From 317e38e594bce1e60bd4be9ca61cc729a42dce40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=AA=E5=AF=92?= <2533659732@qq.com> Date: Tue, 19 Mar 2024 17:19:49 +0800 Subject: [PATCH 03/21] =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E8=AE=A2=E9=98=85=E5=BE=AE=E4=BF=A1=E5=AF=B9=E6=8E=A5?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=BC=80=E5=8F=91=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 + .../src/main/resources/application.yml | 23 ++ .../common/config/AppletChatConfig.java | 67 +++++ .../enums/SubscribeMessageTypeEnum.java | 40 +++ .../com/xinelu/common/utils/DateUtils.java | 17 +- .../SubscribeMessageRecord.java | 2 +- .../SubscribeMessageSendRecord.java | 2 +- .../mapper/patientinfo/PatientInfoMapper.java | 8 + .../SubscribeMessageRecordMapper.java | 20 ++ .../SubscribeMessageSendRecordMapper.java | 8 + .../manage/patientinfo/PatientInfoMapper.xml | 29 ++ .../SubscribeMessageRecordMapper.xml | 41 +++ .../SubscribeMessageSendRecordMapper.xml | 27 ++ postdischarge-mobile/pom.xml | 5 + .../{ => mobiletest}/MobileTestMapper.java | 2 +- .../WeChatAppletCallBackService.java | 19 ++ .../impl/WeChatAppletCallBackServiceImpl.java | 278 ++++++++++++++++++ .../SubscribeMsgChangeEventVO.java | 25 ++ .../SubscribeMsgPopupEventListVO.java | 36 +++ .../SubscribeMsgPopupEventVO.java | 25 ++ .../SubscribeMsgSentEventListVO.java | 42 +++ .../SubscribeMsgSentEventVO.java | 25 ++ .../WeChatMessagePushVO.java | 66 +++++ .../mobile}/mobiletest/MobileTestMapper | 2 +- 24 files changed, 809 insertions(+), 7 deletions(-) create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/config/AppletChatConfig.java create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/enums/SubscribeMessageTypeEnum.java rename postdischarge-mobile/src/main/java/com/xinelu/mobile/mapper/{ => mobiletest}/MobileTestMapper.java (75%) create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatappletcallback/WeChatAppletCallBackService.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatappletcallback/impl/WeChatAppletCallBackServiceImpl.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgChangeEventVO.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventListVO.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventVO.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventListVO.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventVO.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/WeChatMessagePushVO.java rename postdischarge-mobile/src/main/resources/{mapper.mobile => mapper/mobile}/mobiletest/MobileTestMapper (70%) diff --git a/pom.xml b/pom.xml index 57102d84..d16eedee 100644 --- a/pom.xml +++ b/pom.xml @@ -34,6 +34,7 @@ 0.9.1 1.18.4 3.0.3 + 2.7.1 @@ -184,6 +185,12 @@ postdischarge-mobile ${xinelu.version} + + + org.simpleframework + simple-xml + ${simple-xml.version} + diff --git a/postdischarge-admin/src/main/resources/application.yml b/postdischarge-admin/src/main/resources/application.yml index ad357f09..02e18e5d 100644 --- a/postdischarge-admin/src/main/resources/application.yml +++ b/postdischarge-admin/src/main/resources/application.yml @@ -182,3 +182,26 @@ xss: excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* + +# 微信小程序参数配置信息 +applet-chat-config: + # 微信小程序id,wxdec3416aa3d60cab + applet-id: wxdc32268eca6b78f9 + # 微信小程序密钥,f58e19be0380c2ebc6e9e9684c0dacce + secret: 0d0e41432908750460aef2bf0aa871ae + # 微信小程序返回国家语言 + lang: zh_CN + # 微信小程序授权类型 + grant-type: authorization_code + # 微信小程序事件回调令牌 + token: uI1NGHesp7ylIYVYQvp0TlcDmUTKCHj2 + # 微信小程序事件回调消息加密密钥 + encoding-aes-key: 5rbyhMBpdnxTEVT54zeHMNcXi3ccilQZ209QqGi89EW + # 优惠券领取模板id + coupon-receive-template-id: e1JRZaw1OfTz2b6X9DTqqaJtV4rXEt7uhwXoZLDb_eA + # 商品订单支付成功通知模板id + goods-order-template-id: -IxZeEkkXFhoSwGtBHbipKQ6kjEmkdTkswKeOypSsNQ + # 预约服务订单通知模板id + appoint-order-template-id: nUB9HRbqQXOVuTpkKBIHMgzWlNq6touzxf5QYBiMkbU + # 签到成功通知模板id + sign-template-id: S_c9bR4znSWpXg-6ACIMn7AkaR11dzo113XM8w4CKz0 diff --git a/postdischarge-common/src/main/java/com/xinelu/common/config/AppletChatConfig.java b/postdischarge-common/src/main/java/com/xinelu/common/config/AppletChatConfig.java new file mode 100644 index 00000000..b2cd5dec --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/config/AppletChatConfig.java @@ -0,0 +1,67 @@ +package com.xinelu.common.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @Description 微信小程序参数配置类 + * @Author 纪寒 + * @Date 2024-03-19 15:52:38 + * @Version 1.0 + */ +@Data +@Component +@ConfigurationProperties(prefix = "applet-chat-config") +public class AppletChatConfig { + + /** + * 小程序id + */ + private String appletId; + + /** + * 小程序secret + */ + private String secret; + + /** + * 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语 + */ + private String lang; + + /** + * 授权类型 + */ + private String grantType; + + /** + * 微信小程序事件回调令牌 + */ + private String token; + + /** + * 微信小程序事件回调消息加密密钥 + */ + private String encodingAesKey; + + /** + * 优惠券领取模板id + */ + private String couponReceiveTemplateId; + + /** + * 商品订单支付成功通知模板id + */ + private String goodsOrderTemplateId; + + /** + * 预约服务订单通知模板id + */ + private String appointOrderTemplateId; + + /** + * 签到通知模板 + */ + private String signTemplateId; +} diff --git a/postdischarge-common/src/main/java/com/xinelu/common/enums/SubscribeMessageTypeEnum.java b/postdischarge-common/src/main/java/com/xinelu/common/enums/SubscribeMessageTypeEnum.java new file mode 100644 index 00000000..a2ce93f0 --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/enums/SubscribeMessageTypeEnum.java @@ -0,0 +1,40 @@ +package com.xinelu.common.enums; + +import lombok.Getter; + +/** + * @Description 微信小程序订阅消息记录表 订阅消息类型枚举, + * @Date 2024-03-19 17:16:06 + * @Author 纪寒 + * @Version 1.0 + */ +@Getter +public enum SubscribeMessageTypeEnum { + + /** + * 预约服务付款通知提醒 + */ + APPOINT_ORDER_MESSAGE_PUSH("APPOINT_ORDER_MESSAGE_PUSH"), + + /** + * 优惠券领取提醒 + */ + COUPON_RECEIVE_MESSAGE_PUSH("COUPON_RECEIVE_MESSAGE_PUSH"), + + /** + * 商品订单支付成功提醒 + */ + GOODS_ORDER_MESSAGE_PUSH("GOODS_ORDER_MESSAGE_PUSH"), + + /** + * 签到积分通知提醒 + */ + SIGN_MESSAGE_PUSH("SIGN_MESSAGE_PUSH"), + ; + + final private String info; + + SubscribeMessageTypeEnum(String info) { + this.info = info; + } +} diff --git a/postdischarge-common/src/main/java/com/xinelu/common/utils/DateUtils.java b/postdischarge-common/src/main/java/com/xinelu/common/utils/DateUtils.java index 7e8b39de..141a0bec 100644 --- a/postdischarge-common/src/main/java/com/xinelu/common/utils/DateUtils.java +++ b/postdischarge-common/src/main/java/com/xinelu/common/utils/DateUtils.java @@ -167,7 +167,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils { * @param date LocalDate * @param pattern 解析格式 * @return 日期字符串 - * @Author jihan + * @Author 纪寒 */ public static String formatDateToString(LocalDate date, String pattern) { if (Objects.isNull(date)) { @@ -181,7 +181,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils { * * @param date 指定日期,如果为null,默认为当天 * @return 结束日期 - * @author jihan + * @author 纪寒 */ public static LocalDateTime end(LocalDate date) { return LocalDateTime.of(null == date ? LocalDate.now() : date, LocalTime.MAX); @@ -193,7 +193,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils { * @param beginTime 开始时间 * @param endTime 结束时间可以为null, 如果为null则表示now * @return 分钟差值 - * @author jihan + * @author 纪寒 */ public static long differenceMinutes(LocalDateTime beginTime, LocalDateTime endTime) { if (null == beginTime) { @@ -201,4 +201,15 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils { } return ChronoUnit.MINUTES.between(beginTime, null == endTime ? LocalDateTime.now() : endTime); } + + /** + * 时间戳转LocalDateTime + * + * @param timestamp 时间戳 + * @return java.time.LocalDateTime + * @author 纪寒 + */ + public static LocalDateTime timestampToLocalDateTime(long timestamp) { + return LocalDateTime.ofEpochSecond(timestamp / 1000, 0, ZoneOffset.ofHours(8)); + } } diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagerecord/SubscribeMessageRecord.java b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagerecord/SubscribeMessageRecord.java index f0f00142..434714bc 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagerecord/SubscribeMessageRecord.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagerecord/SubscribeMessageRecord.java @@ -87,7 +87,7 @@ public class SubscribeMessageRecord extends BaseEntity { */ @ApiModelProperty(value = "用于订阅消息次数") @Excel(name = "用于订阅消息次数") - private Long subscribeCount; + private Integer subscribeCount; /** * 订阅时间 diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagesendrecord/SubscribeMessageSendRecord.java b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagesendrecord/SubscribeMessageSendRecord.java index 45aef908..074a0550 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagesendrecord/SubscribeMessageSendRecord.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/subscribemessagesendrecord/SubscribeMessageSendRecord.java @@ -102,7 +102,7 @@ public class SubscribeMessageSendRecord extends BaseEntity { */ @ApiModelProperty(value = "推送结果状态码") @Excel(name = "推送结果状态码", readConverterExp = "0=表示成功") - private Long errorCode; + private Integer errorCode; /** * 推送结果状态码,success:成功 diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/patientinfo/PatientInfoMapper.java b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/patientinfo/PatientInfoMapper.java index c9bcb296..9b1a290a 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/patientinfo/PatientInfoMapper.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/patientinfo/PatientInfoMapper.java @@ -58,4 +58,12 @@ public interface PatientInfoMapper { * @return 结果 */ public int deletePatientInfoByIds(Long[] ids); + + /** + * 根据openid查询被护理人信息 + * + * @param openId 微信openId + * @return 被护理人基本信息 + */ + PatientInfo getPatientInfoByOpenId(String openId); } diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagerecord/SubscribeMessageRecordMapper.java b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagerecord/SubscribeMessageRecordMapper.java index ae155e63..3d6b0bcf 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagerecord/SubscribeMessageRecordMapper.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagerecord/SubscribeMessageRecordMapper.java @@ -1,6 +1,7 @@ package com.xinelu.manage.mapper.subscribemessagerecord; import com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord; +import org.apache.ibatis.annotations.Param; import java.util.List; @@ -58,4 +59,23 @@ public interface SubscribeMessageRecordMapper { * @return 结果 */ int deleteSubscribeMessageRecordByIds(Long[] ids); + + /** + * 批量新增微信小程序订阅消息记录 + * + * @param subscribeMessageRecordList 新增微信小程序订阅消息记录 + * @return int + **/ + int insertSubscribeMessageRecordList(List subscribeMessageRecordList); + + /** + * 根据会员openid与templateId修改微信小程序订阅消息记录 + * + * @param openId 微信openid + * @param templateId 模板id + * @param subscribeStatus 订阅状态 + * @param patientId 患者id + * @return int + **/ + int updateSubscribeMessageTemplateId(@Param("openId") String openId, @Param("templateId") String templateId, @Param("subscribeStatus") String subscribeStatus, @Param("patientId") Long patientId); } diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.java b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.java index 3784205d..7ceb8caa 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.java @@ -58,4 +58,12 @@ public interface SubscribeMessageSendRecordMapper { * @return 结果 */ int deleteSubscribeMessageSendRecordByIds(Long[] ids); + + /** + * 批量新增微信小程序订阅消息发送记录 + * + * @param subscribeMessageSendRecordList 微信小程序订阅发送消息记录 + * @return int + **/ + int insertSubscribeMessageSendRecordList(List subscribeMessageSendRecordList); } diff --git a/postdischarge-manage/src/main/resources/mapper/manage/patientinfo/PatientInfoMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/patientinfo/PatientInfoMapper.xml index 44a50ec8..f7481789 100644 --- a/postdischarge-manage/src/main/resources/mapper/manage/patientinfo/PatientInfoMapper.xml +++ b/postdischarge-manage/src/main/resources/mapper/manage/patientinfo/PatientInfoMapper.xml @@ -519,4 +519,33 @@ #{id} + + \ No newline at end of file diff --git a/postdischarge-manage/src/main/resources/mapper/manage/subscribemessagerecord/SubscribeMessageRecordMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/subscribemessagerecord/SubscribeMessageRecordMapper.xml index 8072f8ea..c6ad81c4 100644 --- a/postdischarge-manage/src/main/resources/mapper/manage/subscribemessagerecord/SubscribeMessageRecordMapper.xml +++ b/postdischarge-manage/src/main/resources/mapper/manage/subscribemessagerecord/SubscribeMessageRecordMapper.xml @@ -193,4 +193,45 @@ #{id} + + + insert into subscribe_message_record( + patient_id, + unionid, + openid, + template_id, + message_type, + subscribe_count, + subscribe_time, + applet_id, + subscribe_status, + create_by, + create_time, + update_by, + update_time + ) values + + ( + #{subscribeMessageRecordList.patientId}, + #{subscribeMessageRecordList.unionid}, + #{subscribeMessageRecordList.openid}, + #{subscribeMessageRecordList.templateId}, + #{subscribeMessageRecordList.messageType}, + #{subscribeMessageRecordList.subscribeCount}, + #{subscribeMessageRecordList.subscribeTime}, + #{subscribeMessageRecordList.appletId}, + #{subscribeMessageRecordList.subscribeStatus}, + #{subscribeMessageRecordList.createBy}, + #{subscribeMessageRecordList.createTime}, + #{subscribeMessageRecordList.updateBy}, + #{subscribeMessageRecordList.updateTime} + ) + + + + + update subscribe_message_record + set patient_id = #{patientId}, subscribe_status = #{subscribeStatus}, update_time = now() + where openid = #{openId} and template_id = #{templateId} + \ No newline at end of file diff --git a/postdischarge-manage/src/main/resources/mapper/manage/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.xml index e7633f1e..cf4ac9e2 100644 --- a/postdischarge-manage/src/main/resources/mapper/manage/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.xml +++ b/postdischarge-manage/src/main/resources/mapper/manage/subscribemessagesendrecord/SubscribeMessageSendRecordMapper.xml @@ -204,4 +204,31 @@ #{id} + + + insert into subscribe_message_send_record( + openid, + applet_id, + subscribe_time, + template_id, + msg_id, + message_type, + error_code, + error_status, + create_time + ) values + + ( + #{sendRecord.openid}, + #{sendRecord.appletId}, + #{sendRecord.subscribeTime}, + #{sendRecord.templateId}, + #{sendRecord.msgId}, + #{sendRecord.messageType}, + #{sendRecord.errorCode}, + #{sendRecord.errorStatus}, + #{sendRecord.createTime} + ) + + \ No newline at end of file diff --git a/postdischarge-mobile/pom.xml b/postdischarge-mobile/pom.xml index 8ede5002..0ac748c5 100644 --- a/postdischarge-mobile/pom.xml +++ b/postdischarge-mobile/pom.xml @@ -34,5 +34,10 @@ com.xinelu postdischarge-manage + + + org.simpleframework + simple-xml + \ No newline at end of file diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/mapper/MobileTestMapper.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/mapper/mobiletest/MobileTestMapper.java similarity index 75% rename from postdischarge-mobile/src/main/java/com/xinelu/mobile/mapper/MobileTestMapper.java rename to postdischarge-mobile/src/main/java/com/xinelu/mobile/mapper/mobiletest/MobileTestMapper.java index af0ed197..5307ed69 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/mapper/MobileTestMapper.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/mapper/mobiletest/MobileTestMapper.java @@ -1,4 +1,4 @@ -package com.xinelu.mobile.mapper; +package com.xinelu.mobile.mapper.mobiletest; /** * @Description 测试 Mapper diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatappletcallback/WeChatAppletCallBackService.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatappletcallback/WeChatAppletCallBackService.java new file mode 100644 index 00000000..f9f6b0cc --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatappletcallback/WeChatAppletCallBackService.java @@ -0,0 +1,19 @@ +package com.xinelu.mobile.service.wechatappletcallback; + +import com.xinelu.mobile.vo.wechatappletcallback.WeChatMessagePushVO; + +/** + * @Description 微信小程序事件回调业务层 + * @Author 纪寒 + * @Date 2024-03-15 15:45:50 + * @Version 1.0 + */ +public interface WeChatAppletCallBackService { + + /** + * 微信小程序消息推送事件回调POST处理 + * + * @param weChatMessagePushVO 请求参数 + */ + void handleWeChatAppletCallBack(WeChatMessagePushVO weChatMessagePushVO); +} diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatappletcallback/impl/WeChatAppletCallBackServiceImpl.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatappletcallback/impl/WeChatAppletCallBackServiceImpl.java new file mode 100644 index 00000000..8823f23a --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatappletcallback/impl/WeChatAppletCallBackServiceImpl.java @@ -0,0 +1,278 @@ +package com.xinelu.mobile.service.wechatappletcallback.impl; + +import com.xinelu.common.config.AppletChatConfig; +import com.xinelu.common.enums.SubscribeMessageTypeEnum; +import com.xinelu.common.exception.ServiceException; +import com.xinelu.common.utils.DateUtils; +import com.xinelu.manage.domain.patientinfo.PatientInfo; +import com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord; +import com.xinelu.manage.domain.subscribemessagesendrecord.SubscribeMessageSendRecord; +import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper; +import com.xinelu.manage.mapper.subscribemessagerecord.SubscribeMessageRecordMapper; +import com.xinelu.manage.mapper.subscribemessagesendrecord.SubscribeMessageSendRecordMapper; +import com.xinelu.mobile.service.wechatappletcallback.WeChatAppletCallBackService; +import com.xinelu.mobile.vo.wechatappletcallback.WeChatMessagePushVO; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.compress.utils.Lists; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @Description 微信小程序事件回调业务层实现类 + * @Author 纪寒 + * @Date 2024-03-19 17:13:06 + * @Version 1.0 + */ +@Service +@Slf4j +public class WeChatAppletCallBackServiceImpl implements WeChatAppletCallBackService { + + @Resource + private SubscribeMessageRecordMapper subscribeMessageRecordMapper; + @Resource + private AppletChatConfig appletChatConfig; + @Resource + private PatientInfoMapper patientInfoMapper; + @Resource + private SubscribeMessageSendRecordMapper subscribeMessageSendRecordMapper; + /** + * 微信消息推送变更事件标识 + */ + private static final String SUBSCRIBE_MSG_CHANGE_EVENT = "subscribe_msg_change_event"; + + /** + * 微信消息推送订阅事件标识 + */ + private static final String SUBSCRIBE_MSG_POPUP_EVENT = "subscribe_msg_popup_event"; + + /** + * 微信消息推送发送结果事件标识 + */ + private static final String SUBSCRIBE_MSG__SENT_EVENT = "subscribe_msg_sent_event"; + + /** + * 微信小程序消息推送事件回调POST处理 + * + * @param weChatMessagePushVO 请求参数 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public void handleWeChatAppletCallBack(WeChatMessagePushVO weChatMessagePushVO) { + if (weChatMessagePushVO.getEvent().equals(SUBSCRIBE_MSG_POPUP_EVENT)) { + //处理用户订阅授权事件 + this.handleSubscribeMsgPopupEvent(weChatMessagePushVO); + } + if (weChatMessagePushVO.getEvent().equals(SUBSCRIBE_MSG_CHANGE_EVENT)) { + //处理订阅消息变更事件 + this.handleSubscribeMsgChangeEvent(weChatMessagePushVO); + } + if (weChatMessagePushVO.getEvent().equals(SUBSCRIBE_MSG__SENT_EVENT)) { + //处理订阅消息发送结果事件 + this.handleSubscribeMsgSentEvent(weChatMessagePushVO); + } + } + + /** + * 处理用户订阅授权事件 + * + * @param weChatMessagePushVO 参数信息 + */ + private void handleSubscribeMsgPopupEvent(WeChatMessagePushVO weChatMessagePushVO) { + //处理订阅消息授权事件 + if (Objects.isNull(weChatMessagePushVO.getSubscribeMsgPopupEvent()) || CollectionUtils.isEmpty(weChatMessagePushVO.getSubscribeMsgPopupEvent().getSubscribeMsgPopupEventList())) { + return; + } + //查询用户信息表 + PatientInfo patientInfo = patientInfoMapper.getPatientInfoByOpenId(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName()); + //组装数据 + List subscribeMessageRecordList = createSubscribeMessageRecordList(patientInfo, weChatMessagePushVO, SUBSCRIBE_MSG_POPUP_EVENT); + if (CollectionUtils.isEmpty(subscribeMessageRecordList)) { + return; + } + //根据openid查询数据库原有的订阅消息记录 + SubscribeMessageRecord subscribeMessageRecord = new SubscribeMessageRecord(); + subscribeMessageRecord.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName()); + List existMessageRecordList = subscribeMessageRecordMapper.selectSubscribeMessageRecordList(subscribeMessageRecord); + List subtractSubscribeList = new ArrayList<>(CollectionUtils.subtract(subscribeMessageRecordList, existMessageRecordList)); + if (CollectionUtils.isNotEmpty(subtractSubscribeList)) { + //新增订阅记录信息 + int insertCount = subscribeMessageRecordMapper.insertSubscribeMessageRecordList(subtractSubscribeList); + if (insertCount <= 0) { + log.error("微信订阅消息回调,新增用户订阅消息记录失败,记录信息为:[{}]", subtractSubscribeList); + throw new ServiceException("微信订阅消息回调,新增用户订阅消息记录失败!"); + } + } + List intersectionSubscribeList = new ArrayList<>(CollectionUtils.intersection(subscribeMessageRecordList, existMessageRecordList)); + if (CollectionUtils.isNotEmpty(intersectionSubscribeList)) { + //修改订阅信息状态 + for (SubscribeMessageRecord messageRecord : intersectionSubscribeList) { + Long patientId = null; + if (Objects.nonNull(patientInfo) && Objects.nonNull(patientInfo.getId())) { + patientId = patientInfo.getId(); + } + String openId = StringUtils.isBlank(messageRecord.getOpenid()) ? "" : messageRecord.getOpenid(); + String templateId = StringUtils.isBlank(messageRecord.getTemplateId()) ? "" : messageRecord.getTemplateId(); + String subscribeStatus = StringUtils.isBlank(messageRecord.getSubscribeStatus()) ? "" : messageRecord.getSubscribeStatus(); + subscribeMessageRecordMapper.updateSubscribeMessageTemplateId(openId, templateId, subscribeStatus, patientId); + } + } + } + + /** + * 处理订阅消息变更事件 + * + * @param weChatMessagePushVO 信息 + */ + private void handleSubscribeMsgChangeEvent(WeChatMessagePushVO weChatMessagePushVO) { + if (Objects.isNull(weChatMessagePushVO.getSubscribeMsgChangeEvent()) || CollectionUtils.isEmpty(weChatMessagePushVO.getSubscribeMsgChangeEvent().getSubscribeMsgPopupEventList())) { + return; + } + //查询用户信息表 + PatientInfo patientInfo = patientInfoMapper.getPatientInfoByOpenId(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName()); + //组装数据 + List subscribeMessageRecordList = createSubscribeMessageRecordList(patientInfo, weChatMessagePushVO, SUBSCRIBE_MSG_CHANGE_EVENT); + if (CollectionUtils.isEmpty(subscribeMessageRecordList)) { + return; + } + //根据openid查询数据库原有的订阅消息记录 + SubscribeMessageRecord subscribeMessageRecord = new SubscribeMessageRecord(); + subscribeMessageRecord.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName()); + List existMessageRecordList = subscribeMessageRecordMapper.selectSubscribeMessageRecordList(subscribeMessageRecord); + List intersectionSubscribeList = new ArrayList<>(CollectionUtils.intersection(subscribeMessageRecordList, existMessageRecordList)); + if (CollectionUtils.isNotEmpty(intersectionSubscribeList)) { + //修改订阅信息状态 + for (SubscribeMessageRecord messageRecord : intersectionSubscribeList) { + Long patientId = null; + if (Objects.nonNull(patientInfo) && Objects.nonNull(patientInfo.getId())) { + patientId = patientInfo.getId(); + } + String openId = StringUtils.isBlank(messageRecord.getOpenid()) ? "" : messageRecord.getOpenid(); + String templateId = StringUtils.isBlank(messageRecord.getTemplateId()) ? "" : messageRecord.getTemplateId(); + String subscribeStatus = StringUtils.isBlank(messageRecord.getSubscribeStatus()) ? "" : messageRecord.getSubscribeStatus(); + subscribeMessageRecordMapper.updateSubscribeMessageTemplateId(openId, templateId, subscribeStatus, patientId); + } + } + } + + /** + * 处理订阅消息发送结果事件 + * + * @param weChatMessagePushVO 信息 + */ + private void handleSubscribeMsgSentEvent(WeChatMessagePushVO weChatMessagePushVO) { + if (Objects.isNull(weChatMessagePushVO.getSubscribeMsgSentEvent()) || CollectionUtils.isEmpty(weChatMessagePushVO.getSubscribeMsgSentEvent().getSubscribeMsgSentEventList())) { + return; + } + //组装数据 + List subscribeMessageSendRecordList = createSubscribeMessageSendRecordList(weChatMessagePushVO); + if (CollectionUtils.isNotEmpty(subscribeMessageSendRecordList)) { + int insertCount = subscribeMessageSendRecordMapper.insertSubscribeMessageSendRecordList(subscribeMessageSendRecordList); + if (insertCount <= 0) { + log.error("微信订阅消息回调,新增用户订阅消息发送记录失败,记录信息为:[{}]", subscribeMessageSendRecordList); + throw new ServiceException("微信订阅消息回调,新增用户订阅消息发送记录失败!"); + } + } + } + + /** + * 组装订阅消息数据 + * + * @param patientInfo 会员用户信息 + * @param weChatMessagePushVO 微信请求参数信息 + * @param eventType 事件类型 + * @return List + */ + private List createSubscribeMessageRecordList(PatientInfo patientInfo, WeChatMessagePushVO weChatMessagePushVO, String eventType) { + List subscribeMessageRecordList = Lists.newArrayList(); + if (SUBSCRIBE_MSG_POPUP_EVENT.equals(eventType)) { + subscribeMessageRecordList = weChatMessagePushVO.getSubscribeMsgPopupEvent().getSubscribeMsgPopupEventList().stream().filter(Objects::nonNull).map(item -> { + SubscribeMessageRecord subscribe = new SubscribeMessageRecord(); + if (Objects.nonNull(patientInfo) && Objects.nonNull(patientInfo.getId())) { + subscribe.setPatientId(patientInfo.getId()); + } + //此处模板通知需要根据实际情况进行修改 + subscribe.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName()); + subscribe.setAppletId(StringUtils.isBlank(weChatMessagePushVO.getToUserName()) ? "" : weChatMessagePushVO.getToUserName()); + subscribe.setTemplateId(StringUtils.isBlank(item.getTemplateId()) ? "" : item.getTemplateId()); + if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getCouponReceiveTemplateId().equals(item.getTemplateId())) { + subscribe.setMessageType(SubscribeMessageTypeEnum.COUPON_RECEIVE_MESSAGE_PUSH.getInfo()); + } + if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getAppointOrderTemplateId().equals(item.getTemplateId())) { + subscribe.setMessageType(SubscribeMessageTypeEnum.APPOINT_ORDER_MESSAGE_PUSH.getInfo()); + } + if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getGoodsOrderTemplateId().equals(item.getTemplateId())) { + subscribe.setMessageType(SubscribeMessageTypeEnum.GOODS_ORDER_MESSAGE_PUSH.getInfo()); + } + if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getSignTemplateId().equals(item.getTemplateId())) { + subscribe.setMessageType(SubscribeMessageTypeEnum.SIGN_MESSAGE_PUSH.getInfo()); + } + subscribe.setSubscribeCount(1); + subscribe.setSubscribeTime(StringUtils.isBlank(weChatMessagePushVO.getCreateTime()) ? null : DateUtils.timestampToLocalDateTime(Long.parseLong(weChatMessagePushVO.getCreateTime()) * 1000L)); + subscribe.setCreateTime(LocalDateTime.now()); + subscribe.setSubscribeStatus(StringUtils.isBlank(item.getSubscribeStatusString()) ? "" : item.getSubscribeStatusString()); + return subscribe; + }).collect(Collectors.toList()); + } + if (SUBSCRIBE_MSG_CHANGE_EVENT.equals(eventType)) { + subscribeMessageRecordList = weChatMessagePushVO.getSubscribeMsgChangeEvent().getSubscribeMsgPopupEventList().stream().filter(Objects::nonNull).map(item -> { + SubscribeMessageRecord subscribe = new SubscribeMessageRecord(); + if (Objects.nonNull(patientInfo) && Objects.nonNull(patientInfo.getId())) { + subscribe.setPatientId(patientInfo.getId()); + } + //此处模板通知需要根据实际情况进行修改 + subscribe.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName()); + subscribe.setAppletId(StringUtils.isBlank(weChatMessagePushVO.getToUserName()) ? "" : weChatMessagePushVO.getToUserName()); + subscribe.setTemplateId(StringUtils.isBlank(item.getTemplateId()) ? "" : item.getTemplateId()); + if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getCouponReceiveTemplateId().equals(item.getTemplateId())) { + subscribe.setMessageType(SubscribeMessageTypeEnum.COUPON_RECEIVE_MESSAGE_PUSH.getInfo()); + } + if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getAppointOrderTemplateId().equals(item.getTemplateId())) { + subscribe.setMessageType(SubscribeMessageTypeEnum.APPOINT_ORDER_MESSAGE_PUSH.getInfo()); + } + if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getGoodsOrderTemplateId().equals(item.getTemplateId())) { + subscribe.setMessageType(SubscribeMessageTypeEnum.GOODS_ORDER_MESSAGE_PUSH.getInfo()); + } + if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getSignTemplateId().equals(item.getTemplateId())) { + subscribe.setMessageType(SubscribeMessageTypeEnum.SIGN_MESSAGE_PUSH.getInfo()); + } + subscribe.setSubscribeCount(1); + subscribe.setSubscribeTime(StringUtils.isBlank(weChatMessagePushVO.getCreateTime()) ? null : DateUtils.timestampToLocalDateTime(Long.parseLong(weChatMessagePushVO.getCreateTime()) * 1000L)); + subscribe.setCreateTime(LocalDateTime.now()); + subscribe.setSubscribeStatus(StringUtils.isBlank(item.getSubscribeStatusString()) ? "" : item.getSubscribeStatusString()); + return subscribe; + }).collect(Collectors.toList()); + } + return subscribeMessageRecordList; + } + + /** + * 组装订阅消息发送结果数据 + * + * @param weChatMessagePushVO 微信请求参数信息 + * @return List + */ + private List createSubscribeMessageSendRecordList(WeChatMessagePushVO weChatMessagePushVO) { + return weChatMessagePushVO.getSubscribeMsgSentEvent().getSubscribeMsgSentEventList().stream().map(item -> { + SubscribeMessageSendRecord sendRecord = new SubscribeMessageSendRecord(); + sendRecord.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName()); + sendRecord.setAppletId(StringUtils.isBlank(weChatMessagePushVO.getToUserName()) ? "" : weChatMessagePushVO.getToUserName()); + sendRecord.setTemplateId(StringUtils.isBlank(item.getTemplateId()) ? "" : item.getTemplateId()); + sendRecord.setMessageType(StringUtils.isBlank(weChatMessagePushVO.getMsgType()) ? "" : weChatMessagePushVO.getMsgType()); + sendRecord.setMsgId(StringUtils.isBlank(item.getMsgId()) ? "" : item.getMsgId()); + sendRecord.setSubscribeTime(StringUtils.isBlank(weChatMessagePushVO.getCreateTime()) ? null : DateUtils.timestampToLocalDateTime(Long.parseLong(weChatMessagePushVO.getCreateTime()) * 1000L)); + sendRecord.setCreateTime(LocalDateTime.now()); + sendRecord.setErrorStatus(StringUtils.isBlank(item.getErrorStatus()) ? "" : item.getErrorStatus()); + sendRecord.setErrorCode(StringUtils.isBlank(item.getErrorCode()) ? null : Integer.parseInt(item.getErrorCode())); + return sendRecord; + }).collect(Collectors.toList()); + } +} diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgChangeEventVO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgChangeEventVO.java new file mode 100644 index 00000000..9da66f77 --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgChangeEventVO.java @@ -0,0 +1,25 @@ +package com.xinelu.mobile.vo.wechatappletcallback; + +import lombok.Data; +import org.simpleframework.xml.ElementList; +import org.simpleframework.xml.Root; + +import java.io.Serializable; +import java.util.List; + +/** + * @Description 当用户在手机端服务通知里消息卡片右上角“...”管理消息实体类 + * @Author 纪寒 + * @Date 2024-03-19 16:12:17 + * @Version 1.0 + */ +@Root(name = "SubscribeMsgChangeEvent", strict = false) +@Data +public class SubscribeMsgChangeEventVO implements Serializable { + private static final long serialVersionUID = -6682105837610124794L; + /** + * 信息集合 + */ + @ElementList(inline = true, required = false) + private List subscribeMsgPopupEventList; +} diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventListVO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventListVO.java new file mode 100644 index 00000000..0316246a --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventListVO.java @@ -0,0 +1,36 @@ +package com.xinelu.mobile.vo.wechatappletcallback; + +import lombok.Data; +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +import java.io.Serializable; + +/** + * @Description 模板信息集合 + * @Author 纪寒 + * @Date 2024-03-19 16:10:28 + * @Version 1.0 + */ +@Root(name = "List", strict = false) +@Data +public class SubscribeMsgPopupEventListVO implements Serializable { + private static final long serialVersionUID = 548605591615555467L; + /** + * 模板id + */ + @Element(name = "TemplateId", required = false) + private String templateId; + + /** + * 订阅结果(accept接收;reject拒收) + */ + @Element(name = "SubscribeStatusString", required = false) + private String subscribeStatusString; + + /** + * 弹框场景,0代表在小程序页面内 + */ + @Element(name = "PopupScene", required = false) + private String popupScene; +} diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventVO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventVO.java new file mode 100644 index 00000000..9f552c5c --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventVO.java @@ -0,0 +1,25 @@ +package com.xinelu.mobile.vo.wechatappletcallback; + +import lombok.Data; +import org.simpleframework.xml.ElementList; +import org.simpleframework.xml.Root; + +import java.io.Serializable; +import java.util.List; + +/** + * @Description 当用户触发订阅消息弹框后信息实体类 + * @Author 纪寒 + * @Date 2024-03-19 16:09:23 + * @Version 1.0 + */ +@Root(name = "SubscribeMsgPopupEvent", strict = false) +@Data +public class SubscribeMsgPopupEventVO implements Serializable { + private static final long serialVersionUID = -6682105837610124794L; + /** + * 信息集合 + */ + @ElementList(inline = true, required = false) + private List subscribeMsgPopupEventList; +} diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventListVO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventListVO.java new file mode 100644 index 00000000..e85a4c28 --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventListVO.java @@ -0,0 +1,42 @@ +package com.xinelu.mobile.vo.wechatappletcallback; + +import lombok.Data; +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +import java.io.Serializable; + +/** + * @Description 调用订阅消息接口发送消息给用户的最终结果信息集合实体类 + * @Author 纪寒 + * @Date 2024-03-19 16:13:39 + * @Version 1.0 + */ +@Root(name = "List", strict = false) +@Data +public class SubscribeMsgSentEventListVO implements Serializable { + private static final long serialVersionUID = 3771741965224817805L; + /** + * 模板id + */ + @Element(name = "TemplateId", required = false) + private String templateId; + + /** + * 消息id(调用接口时也会返回) + */ + @Element(name = "MsgID", required = false) + private String msgId; + + /** + * 推送结果状态码(0表示成功) + */ + @Element(name = "ErrorCode", required = false) + private String errorCode; + + /** + * 推送结果状态码对应的含义 + */ + @Element(name = "ErrorStatus", required = false) + private String errorStatus; +} diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventVO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventVO.java new file mode 100644 index 00000000..6fcc1f42 --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventVO.java @@ -0,0 +1,25 @@ +package com.xinelu.mobile.vo.wechatappletcallback; + +import lombok.Data; +import org.simpleframework.xml.ElementList; +import org.simpleframework.xml.Root; + +import java.io.Serializable; +import java.util.List; + +/** + * @Description 调用订阅消息接口发送消息给用户的最终结果实体类 + * @Author 纪寒 + * @Date 2024-03-19 16:13:23 + * @Version 1.0 + */ +@Root(name = "SubscribeMsgSentEvent", strict = false) +@Data +public class SubscribeMsgSentEventVO implements Serializable { + private static final long serialVersionUID = -6682105837610124794L; + /** + * 信息集合 + */ + @ElementList(inline = true, required = false) + private List subscribeMsgSentEventList; +} diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/WeChatMessagePushVO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/WeChatMessagePushVO.java new file mode 100644 index 00000000..df50dd6b --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/WeChatMessagePushVO.java @@ -0,0 +1,66 @@ +package com.xinelu.mobile.vo.wechatappletcallback; + +import lombok.Data; +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +import java.io.Serializable; + +/** + * @Description 微信小程序消息推送回调实体类 + * @Author 纪寒 + * @Date 2024-03-19 16:06:17 + * @Version 1.0 + */ +@Root(name = "xml", strict = false) +@Data +public class WeChatMessagePushVO implements Serializable { + private static final long serialVersionUID = 6233209958847696141L; + /** + * 小程序账号 + */ + @Element(name = "ToUserName", required = false) + private String toUserName; + + /** + * 用户openid + */ + @Element(name = "FromUserName", required = false) + private String fromUserName; + + /** + * 时间戳 + */ + @Element(name = "CreateTime", required = false) + private String createTime; + + /** + * 消息类型 + */ + @Element(name = "MsgType", required = false) + private String msgType; + + /** + * 事件类型 + */ + @Element(name = "Event", required = false) + private String event; + + /** + * 当用户触发订阅消息弹框后触发时间集合 + */ + @Element(name = "SubscribeMsgPopupEvent", required = false) + private SubscribeMsgPopupEventVO subscribeMsgPopupEvent; + + /** + * 当用户在手机端服务通知里消息卡片右上角“...”管理消息时 + */ + @Element(name = "SubscribeMsgChangeEvent", required = false) + private SubscribeMsgChangeEventVO subscribeMsgChangeEvent; + + /** + * 当用户在手机端服务通知里消息卡片右上角“...”管理消息时 + */ + @Element(name = "SubscribeMsgSentEvent", required = false) + private SubscribeMsgSentEventVO subscribeMsgSentEvent; +} diff --git a/postdischarge-mobile/src/main/resources/mapper.mobile/mobiletest/MobileTestMapper b/postdischarge-mobile/src/main/resources/mapper/mobile/mobiletest/MobileTestMapper similarity index 70% rename from postdischarge-mobile/src/main/resources/mapper.mobile/mobiletest/MobileTestMapper rename to postdischarge-mobile/src/main/resources/mapper/mobile/mobiletest/MobileTestMapper index ceb12892..3b8ea21e 100644 --- a/postdischarge-mobile/src/main/resources/mapper.mobile/mobiletest/MobileTestMapper +++ b/postdischarge-mobile/src/main/resources/mapper/mobile/mobiletest/MobileTestMapper @@ -2,5 +2,5 @@ - + \ No newline at end of file From 6341f71a257795e9fbd51114481086291cbf15df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=AA=E5=AF=92?= <2533659732@qq.com> Date: Thu, 21 Mar 2024 10:36:07 +0800 Subject: [PATCH 04/21] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=B0=8F=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=E6=B6=88=E6=81=AF=E6=8E=A8=E9=80=81=E4=BB=A3=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E5=BE=AE=E4=BF=A1=E5=8A=9F=E8=83=BD=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application.yml | 2 + .../xinelu/common/utils/aes/AesException.java | 55 ++++ .../xinelu/common/utils/aes/ByteGroup.java | 31 +++ .../xinelu/common/utils/aes/PKCS7Encoder.java | 62 +++++ .../com/xinelu/common/utils/aes/SHA1.java | 94 +++++++ .../common/utils/aes/WXBizMsgCrypt.java | 234 ++++++++++++++++++ .../com/xinelu/common/utils/aes/XMLParse.java | 68 +++++ .../framework/config/SecurityConfig.java | 8 + .../WeChatAppletCallBackController.java | 74 ++++++ .../wechatappletcallback/MessageSignDTO.java | 40 +++ .../java/com/xinelu/mobile/utils/XmlUtil.java | 29 +++ .../SubscribeMsgChangeEventVO.java | 2 +- .../SubscribeMsgPopupEventListVO.java | 2 +- .../SubscribeMsgPopupEventVO.java | 2 +- .../SubscribeMsgSentEventListVO.java | 2 +- .../SubscribeMsgSentEventVO.java | 2 +- .../WeChatMessagePushVO.java | 2 +- 17 files changed, 703 insertions(+), 6 deletions(-) create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/utils/aes/AesException.java create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/utils/aes/ByteGroup.java create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/utils/aes/PKCS7Encoder.java create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/utils/aes/SHA1.java create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/utils/aes/WXBizMsgCrypt.java create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/utils/aes/XMLParse.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatappletcallback/WeChatAppletCallBackController.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/dto/wechatappletcallback/MessageSignDTO.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/XmlUtil.java diff --git a/postdischarge-admin/src/main/resources/application.yml b/postdischarge-admin/src/main/resources/application.yml index 02e18e5d..8550115d 100644 --- a/postdischarge-admin/src/main/resources/application.yml +++ b/postdischarge-admin/src/main/resources/application.yml @@ -100,6 +100,8 @@ token: secret: DIweGcEWJTbvo48dnvOMR8GsDW # 令牌有效期(默认30分钟) expireTime: 30 + # 请求拦截白名单 + ant-matchers: /postDischarge/** ## MyBatis-Plus配置 mybatis-plus: diff --git a/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/AesException.java b/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/AesException.java new file mode 100644 index 00000000..fc191dfc --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/AesException.java @@ -0,0 +1,55 @@ +package com.xinelu.common.utils.aes; + +/** + * @Description 微信AES解密异常信息类 + * @Author WeChat + * @Date 2024-03-21 10:17:50 + */ +@SuppressWarnings("serial") +public class AesException extends Exception { + + public final static int OK = 0; + public final static int VALIDATE_SIGNATURE_ERROR = -40001; + public final static int PARSE_XML_ERROR = -40002; + public final static int COMPUTE_SIGNATURE_ERROR = -40003; + public final static int ILLEGAL_AES_KEY = -40004; + public final static int VALIDATE_APP_ID_ERROR = -40005; + public final static int ENCRYPT_AES_ERROR = -40006; + public final static int DECRYPT_AES_ERROR = -40007; + public final static int ILLEGAL_BUFFER = -40008; + + private final int code; + + private static String getMessage(int code) { + switch (code) { + case VALIDATE_SIGNATURE_ERROR: + return "签名验证错误"; + case PARSE_XML_ERROR: + return "xml解析失败"; + case COMPUTE_SIGNATURE_ERROR: + return "sha加密生成签名失败"; + case ILLEGAL_AES_KEY: + return "SymmetricKey非法"; + case VALIDATE_APP_ID_ERROR: + return "appid校验失败"; + case ENCRYPT_AES_ERROR: + return "aes加密失败"; + case DECRYPT_AES_ERROR: + return "aes解密失败"; + case ILLEGAL_BUFFER: + return "解密后得到的buffer非法"; + default: + return null; + } + } + + public int getCode() { + return code; + } + + AesException(int code) { + super(getMessage(code)); + this.code = code; + } + +} diff --git a/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/ByteGroup.java b/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/ByteGroup.java new file mode 100644 index 00000000..f90e822c --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/ByteGroup.java @@ -0,0 +1,31 @@ +package com.xinelu.common.utils.aes; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Description 字节数组 + * @Author WeChat + * @Date 2024-03-21 10:17:56 + */ +class ByteGroup { + List byteContainer = new ArrayList<>(); + + public byte[] toBytes() { + byte[] bytes = new byte[byteContainer.size()]; + for (int i = 0; i < byteContainer.size(); i++) { + bytes[i] = byteContainer.get(i); + } + return bytes; + } + + public void addBytes(byte[] bytes) { + for (byte b : bytes) { + byteContainer.add(b); + } + } + + public int size() { + return byteContainer.size(); + } +} diff --git a/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/PKCS7Encoder.java b/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/PKCS7Encoder.java new file mode 100644 index 00000000..0686ff9e --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/PKCS7Encoder.java @@ -0,0 +1,62 @@ +package com.xinelu.common.utils.aes; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +/** + * @Description 提供基于PKCS7算法的加解密接口 + * @Author WeChat + * @Date 2024-03-21 10:18:21 + */ +class PKCS7Encoder { + static Charset CHARSET = StandardCharsets.UTF_8; + static int BLOCK_SIZE = 32; + + /** + * 获得对明文进行补位填充的字节. + * + * @param count 需要进行填充补位操作的明文字节个数 + * @return 补齐用的字节数组 + */ + static byte[] encode(int count) { + // 计算需要填充的位数 + int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE); + if (amountToPad == 0) { + amountToPad = BLOCK_SIZE; + } + // 获得补位所用的字符 + char padChr = chr(amountToPad); + StringBuilder tmp = new StringBuilder(); + for (int index = 0; index < amountToPad; index++) { + tmp.append(padChr); + } + return tmp.toString().getBytes(CHARSET); + } + + /** + * 删除解密后明文的补位字符 + * + * @param decrypted 解密后的明文 + * @return 删除补位字符后的明文 + */ + static byte[] decode(byte[] decrypted) { + int pad = decrypted[decrypted.length - 1]; + if (pad < 1 || pad > 32) { + pad = 0; + } + return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); + } + + /** + * 将数字转化成ASCII码对应的字符,用于对明文进行补码 + * + * @param a 需要转化的数字 + * @return 转化得到的字符 + */ + static char chr(int a) { + byte target = (byte) (a & 0xFF); + return (char) target; + } + +} diff --git a/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/SHA1.java b/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/SHA1.java new file mode 100644 index 00000000..8fae4ca1 --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/SHA1.java @@ -0,0 +1,94 @@ +package com.xinelu.common.utils.aes; + +import org.apache.commons.lang3.BooleanUtils; + +import java.security.MessageDigest; +import java.util.Arrays; + + +/** + * SHA1 class + *

+ * + * @Description 计算公众平台的消息签名接口 + * @Author WeChat + * @Date 2024-03-21 10:19:50 + */ +class SHA1 { + + /** + * 用SHA1算法生成安全签名 + * + * @param token 票据 + * @param timestamp 时间戳 + * @param nonce 随机字符串 + * @param encrypt 密文 + * @return 安全签名 + * @throws AesException 异常信息 + */ + public static String getShaOne(String token, String timestamp, String nonce, String encrypt) throws AesException { + return signatureByShaOne(token, timestamp, nonce, encrypt, true); + } + + /** + * 用SHA1算法生成安全签名,小程序回调设置验证URL时计算签名使用 + * + * @param token 票据 + * @param timestamp 时间戳 + * @param nonce 随机字符串 + * @return 安全签名 + * @throws AesException 异常信息 + */ + public static String getShaTwo(String token, String timestamp, String nonce) throws AesException { + return signatureByShaOne(token, timestamp, nonce, "", false); + } + + /** + * 使用SHA-1计算签名公共方法 + * + * @param token 令牌 + * @param timestamp 时间粗 + * @param nonce 随机字符串 + * @param encrypt 密文 + * @param encryptFlag 密文传入标识 + * @return String 明文 + * @throws AesException 异常信息 + */ + private static String signatureByShaOne(String token, String timestamp, String nonce, String encrypt, boolean encryptFlag) throws AesException { + try { + String[] array; + int size; + if (BooleanUtils.isTrue(encryptFlag)) { + array = new String[]{token, timestamp, nonce, encrypt}; + size = 4; + } else { + array = new String[]{token, timestamp, nonce}; + size = 3; + } + StringBuilder sb = new StringBuilder(); + // 字符串排序 + Arrays.sort(array); + for (int i = 0; i < size; i++) { + sb.append(array[i]); + } + String str = sb.toString(); + // SHA1签名生成 + MessageDigest md = MessageDigest.getInstance("SHA-1"); + md.update(str.getBytes()); + byte[] digest = md.digest(); + StringBuilder hexStr = new StringBuilder(); + String shaHex; + for (byte b : digest) { + shaHex = Integer.toHexString(b & 0xFF); + if (shaHex.length() < 2) { + hexStr.append(0); + } + hexStr.append(shaHex); + } + return hexStr.toString(); + } catch (Exception e) { + e.printStackTrace(); + throw new AesException(AesException.COMPUTE_SIGNATURE_ERROR); + } + } +} diff --git a/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/WXBizMsgCrypt.java b/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/WXBizMsgCrypt.java new file mode 100644 index 00000000..859836c9 --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/WXBizMsgCrypt.java @@ -0,0 +1,234 @@ +package com.xinelu.common.utils.aes; + +import org.apache.commons.codec.binary.Base64; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Random; + +/** + * @Description 提供接收和推送给公众平台消息的加解密接口(UTF8编码的字符串). + * @Author WeChat + * @Date 2024-03-21 10:18:26 + */ +public class WXBizMsgCrypt { + static Charset CHARSET = StandardCharsets.UTF_8; + Base64 base64 = new Base64(); + byte[] aesKey; + String token; + String appId; + + /** + * 构造函数 + * + * @param token 公众平台上,开发者设置的token + * @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey + * @param appId 公众平台appid + * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息 + */ + public WXBizMsgCrypt(String token, String encodingAesKey, String appId) throws AesException { + int length = 43; + if (encodingAesKey.length() != length) { + throw new AesException(AesException.ILLEGAL_AES_KEY); + } + this.token = token; + this.appId = appId; + aesKey = Base64.decodeBase64(encodingAesKey + "="); + } + + /** + * 生成4个字节的网络字节序 + * + * @param sourceNumber 数值 + * @return 字节数组 + */ + byte[] getNetworkBytesOrder(int sourceNumber) { + byte[] orderBytes = new byte[4]; + orderBytes[3] = (byte) (sourceNumber & 0xFF); + orderBytes[2] = (byte) (sourceNumber >> 8 & 0xFF); + orderBytes[1] = (byte) (sourceNumber >> 16 & 0xFF); + orderBytes[0] = (byte) (sourceNumber >> 24 & 0xFF); + return orderBytes; + } + + /** + * 还原4个字节的网络字节序 + * + * @param orderBytes 字节数组 + * @return 数值 + */ + int recoverNetworkBytesOrder(byte[] orderBytes) { + int sourceNumber = 0; + for (int i = 0; i < 4; i++) { + sourceNumber <<= 8; + sourceNumber |= orderBytes[i] & 0xff; + } + return sourceNumber; + } + + /** + * 随机生成16位字符串 + * + * @return 随机字符串 + */ + String getRandomStr() { + String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + Random random = new Random(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 16; i++) { + int number = random.nextInt(base.length()); + sb.append(base.charAt(number)); + } + return sb.toString(); + } + + /** + * 对明文进行加密. + * + * @param text 需要加密的明文 + * @return 加密后base64编码的字符串 + * @throws AesException aes加密失败 + */ + String encrypt(String randomStr, String text) throws AesException { + ByteGroup byteCollector = new ByteGroup(); + byte[] randomStrBytes = randomStr.getBytes(CHARSET); + byte[] textBytes = text.getBytes(CHARSET); + byte[] networkBytesOrder = getNetworkBytesOrder(textBytes.length); + byte[] appidBytes = appId.getBytes(CHARSET); + // randomStr + networkBytesOrder + text + appid + byteCollector.addBytes(randomStrBytes); + byteCollector.addBytes(networkBytesOrder); + byteCollector.addBytes(textBytes); + byteCollector.addBytes(appidBytes); + // ... + pad: 使用自定义的填充方式对明文进行补位填充 + byte[] padBytes = PKCS7Encoder.encode(byteCollector.size()); + byteCollector.addBytes(padBytes); + // 获得最终的字节流, 未加密 + byte[] unencrypted = byteCollector.toBytes(); + try { + // 设置加密模式为AES的CBC模式 + Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES"); + IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16); + cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv); + // 加密 + byte[] encrypted = cipher.doFinal(unencrypted); + // 使用BASE64对加密后的字符串进行编码 + return base64.encodeToString(encrypted); + } catch (Exception e) { + e.printStackTrace(); + throw new AesException(AesException.ENCRYPT_AES_ERROR); + } + } + + /** + * 对密文进行解密. + * + * @param text 需要解密的密文 + * @return 解密得到的明文 + * @throws AesException aes解密失败 + */ + String decrypt(String text) throws AesException { + byte[] original; + try { + // 设置解密模式为AES的CBC模式 + Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES"); + IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16)); + cipher.init(Cipher.DECRYPT_MODE, keySpec, iv); + // 使用BASE64对密文进行解码 + byte[] encrypted = Base64.decodeBase64(text); + // 解密 + original = cipher.doFinal(encrypted); + } catch (Exception e) { + e.printStackTrace(); + throw new AesException(AesException.DECRYPT_AES_ERROR); + } + String xmlContent, fromAppid; + try { + // 去除补位字符 + byte[] bytes = PKCS7Encoder.decode(original); + // 分离16位随机字符串,网络字节序和AppId + byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20); + int xmlLength = recoverNetworkBytesOrder(networkOrder); + xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET); + fromAppid = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length), + CHARSET); + } catch (Exception e) { + e.printStackTrace(); + throw new AesException(AesException.ILLEGAL_BUFFER); + } + // appid不相同的情况 + if (!fromAppid.equals(appId)) { + throw new AesException(AesException.VALIDATE_APP_ID_ERROR); + } + return xmlContent; + } + + /** + * @param replyMsg 公众平台待回复用户的消息,xml格式的字符串 + * @param timeStamp 时间戳,可以自己生成,也可以用URL参数的timestamp + * @param nonce 随机串,可以自己生成,也可以用URL参数的nonce + * @return 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串 + * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息 + * @Description 将公众平台回复用户的消息加密打包. + */ + public String encryptMsg(String replyMsg, String timeStamp, String nonce) throws AesException { + // 加密 + String encrypt = encrypt(getRandomStr(), replyMsg); + // 生成安全签名 + if ("".equals(timeStamp)) { + timeStamp = Long.toString(System.currentTimeMillis()); + } + String signature = SHA1.getShaOne(token, timeStamp, nonce, encrypt); + // 生成发送的xml + return XMLParse.generate(encrypt, signature, timeStamp, nonce); + } + + /** + * @param msgSignature 签名串,对应URL参数的msg_signature + * @param timeStamp 时间戳,对应URL参数的timestamp + * @param nonce 随机串,对应URL参数的nonce + * @param postData 密文,对应POST请求的数据 + * @return 解密后的原文 + * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息 + * @Description 检验消息的真实性,并且获取解密后的明文. + */ + public String decryptMsg(String msgSignature, String timeStamp, String nonce, String postData) + throws AesException { + // 密钥,公众账号的app secret + // 提取密文 + Object[] encrypt = XMLParse.extract(postData); + // 验证安全签名 + String signature = SHA1.getShaTwo(token, timeStamp, nonce); + // 和URL中的签名比较是否相等 + if (!signature.equals(msgSignature)) { + throw new AesException(AesException.VALIDATE_SIGNATURE_ERROR); + } + // 解密 + return decrypt(encrypt[1].toString()); + } + + /** + * 验证URL + * + * @param msgSignature 签名串,对应URL参数的msg_signature + * @param timeStamp 时间戳,对应URL参数的timestamp + * @param nonce 随机串,对应URL参数的nonce + * @param echoStr 随机串,对应URL参数的echostr + * @return 原始的随机串echostr + * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息 + */ + public String verifyUrl(String msgSignature, String timeStamp, String nonce, String echoStr) throws AesException { + String signature = SHA1.getShaTwo(token, timeStamp, nonce); + if (!signature.equals(msgSignature)) { + throw new AesException(AesException.VALIDATE_SIGNATURE_ERROR); + } + return echoStr; + } + +} \ No newline at end of file diff --git a/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/XMLParse.java b/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/XMLParse.java new file mode 100644 index 00000000..b07ec1cf --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/utils/aes/XMLParse.java @@ -0,0 +1,68 @@ +package com.xinelu.common.utils.aes; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.StringReader; + +/** + * @Description 提供提取消息格式中的密文及生成回复消息格式的接口. + * @Author WeChat + * @Date 2024-03-21 10:18:57 + */ +class XMLParse { + + /** + * 提取出xml数据包中的加密消息 + * + * @param xmltext 待提取的xml字符串 + * @return 提取出的加密消息字符串 + * @throws AesException 异常信息 + */ + public static Object[] extract(String xmltext) throws AesException { + Object[] result = new Object[3]; + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); + dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + dbf.setXIncludeAware(false); + dbf.setExpandEntityReferences(false); + DocumentBuilder db = dbf.newDocumentBuilder(); + StringReader sr = new StringReader(xmltext); + InputSource is = new InputSource(sr); + Document document = db.parse(is); + Element root = document.getDocumentElement(); + NodeList nodelist1 = root.getElementsByTagName("Encrypt"); + NodeList nodelist2 = root.getElementsByTagName("ToUserName"); + result[0] = 0; + result[1] = nodelist1.item(0).getTextContent(); + result[2] = nodelist2.item(0).getTextContent(); + return result; + } catch (Exception e) { + e.printStackTrace(); + throw new AesException(AesException.PARSE_XML_ERROR); + } + } + + /** + * 生成xml消息 + * + * @param encrypt 加密后的消息密文 + * @param signature 安全签名 + * @param timestamp 时间戳 + * @param nonce 随机字符串 + * @return 生成的xml字符串 + */ + public static String generate(String encrypt, String signature, String timestamp, String nonce) { + String format = "\n" + "\n" + + "\n" + + "%3$s\n" + "\n" + ""; + return String.format(format, encrypt, signature, timestamp, nonce); + } +} diff --git a/postdischarge-framework/src/main/java/com/xinelu/framework/config/SecurityConfig.java b/postdischarge-framework/src/main/java/com/xinelu/framework/config/SecurityConfig.java index 281ed2c8..0fb107d7 100644 --- a/postdischarge-framework/src/main/java/com/xinelu/framework/config/SecurityConfig.java +++ b/postdischarge-framework/src/main/java/com/xinelu/framework/config/SecurityConfig.java @@ -4,6 +4,7 @@ import com.xinelu.framework.config.properties.PermitAllUrlProperties; import com.xinelu.framework.security.filter.JwtAuthenticationTokenFilter; import com.xinelu.framework.security.handle.AuthenticationEntryPointImpl; import com.xinelu.framework.security.handle.LogoutSuccessHandlerImpl; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; @@ -64,6 +65,12 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Resource private PermitAllUrlProperties permitAllUrl; + /** + * 请求拦截白名单 + */ + @Value("${token.ant-matchers}") + private String antMatchers; + /** * 解决 无法直接注入 AuthenticationManager * @@ -111,6 +118,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { // 静态资源,可匿名访问 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() + .antMatchers(antMatchers.split(",")).permitAll() // 除上面外的所有请求全部需要鉴权认证 .anyRequest().authenticated() .and() diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatappletcallback/WeChatAppletCallBackController.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatappletcallback/WeChatAppletCallBackController.java new file mode 100644 index 00000000..6d7006fa --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatappletcallback/WeChatAppletCallBackController.java @@ -0,0 +1,74 @@ +package com.xinelu.mobile.controller.wechatappletcallback; + +import com.xinelu.common.config.AppletChatConfig; +import com.xinelu.common.utils.aes.AesException; +import com.xinelu.common.utils.aes.WXBizMsgCrypt; +import com.xinelu.mobile.dto.wechatappletcallback.MessageSignDTO; +import com.xinelu.mobile.service.wechatappletcallback.WeChatAppletCallBackService; +import com.xinelu.mobile.utils.XmlUtil; +import com.xinelu.mobile.vo.wechatappletcallback.WeChatMessagePushVO; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.Objects; + +/** + * @Description 院后微信小程序事件回调控制器 + * @Author 纪寒 + * @Date 2024-03-21 10:20:32 + * @Version 1.0 + */ +@Slf4j +@RestController +@RequestMapping("/postDischarge/weChatAppletCallBack") +public class WeChatAppletCallBackController { + + @Resource + private AppletChatConfig appletChatConfig; + @Resource + private WeChatAppletCallBackService weChatAppletCallBackService; + + /** + * 微信小程序回调验证方法 + * + * @param messageSignDTO 微信输入参数 + * @return 解密后的字符串 + * @throws AesException 异常信息 + */ + @GetMapping + public String getWeChatAppletCallBack(MessageSignDTO messageSignDTO) throws AesException { + WXBizMsgCrypt wxCpt = new WXBizMsgCrypt(appletChatConfig.getToken(), appletChatConfig.getEncodingAesKey(), appletChatConfig.getAppletId()); + String verifyMessage = wxCpt.verifyUrl(messageSignDTO.getSignature(), messageSignDTO.getTimestamp(), messageSignDTO.getNonce(), messageSignDTO.getEchostr()); + log.info("院后微信小程序回调设置验证URL成功,验证信息:verifyMessage = [{}]", verifyMessage); + return verifyMessage; + } + + /** + * 微信小程序消息推送事件回调POST处理 + * + * @param signature 签名 + * @param timestamp 时间戳 + * @param nonce 随机字符串 + * @param postData 消息体,xml格式 + */ + @PostMapping + public void handleWeChatAppletCallBack(@RequestParam("signature") String signature, + @RequestParam("timestamp") String timestamp, + @RequestParam("nonce") String nonce, + @RequestBody String postData) throws AesException { + WXBizMsgCrypt wxCpt = new WXBizMsgCrypt(appletChatConfig.getToken(), appletChatConfig.getEncodingAesKey(), appletChatConfig.getAppletId()); + String decryptMsg = wxCpt.decryptMsg(signature, timestamp, nonce, postData); + WeChatMessagePushVO weChatMessagePushVO = (WeChatMessagePushVO) XmlUtil.fromXml(decryptMsg, WeChatMessagePushVO.class); + if (Objects.isNull(weChatMessagePushVO)) { + log.error("院后微信小程序xml数据转换失败,请求信息为: [{}]", decryptMsg); + return; + } + if (StringUtils.isBlank(weChatMessagePushVO.getEvent()) || StringUtils.isBlank(weChatMessagePushVO.getMsgType())) { + return; + } + log.info("院后微信小程序消息推送回调执行,消息数据为: [{}]", weChatMessagePushVO); + weChatAppletCallBackService.handleWeChatAppletCallBack(weChatMessagePushVO); + } +} diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/dto/wechatappletcallback/MessageSignDTO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/dto/wechatappletcallback/MessageSignDTO.java new file mode 100644 index 00000000..4a85d61e --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/dto/wechatappletcallback/MessageSignDTO.java @@ -0,0 +1,40 @@ +package com.xinelu.mobile.dto.wechatappletcallback; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @Description 消息验证实体类 + * @Author 纪寒 + * @Date 2024-03-21 10:09:01 + * @Version 1.0 + */ +@Data +public class MessageSignDTO implements Serializable { + private static final long serialVersionUID = 357274374767303359L; + /** + * 微信小程序签名 + */ + private String signature; + + /** + * 时间戳 + */ + private String timestamp; + + /** + * 随机字符串 + */ + private String nonce; + + /** + * 加密的字符串 + */ + private String echostr; + + /** + * 回调数据包,xml格式 + */ + private String postData; +} diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/XmlUtil.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/XmlUtil.java new file mode 100644 index 00000000..608efbde --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/XmlUtil.java @@ -0,0 +1,29 @@ +package com.xinelu.mobile.utils; + +import org.simpleframework.xml.Serializer; +import org.simpleframework.xml.core.Persister; + +/** + * @Description Xml格式数据工具类 + * @Author 纪寒 + * @Date 2024-03-21 10:22:34 + * @Version 1.0 + */ +public class XmlUtil { + /** + * Xml数据转换 + * + * @param xml 数据格式 + * @param objClass 要转换的类 + * @return 返回结果 + */ + public static Object fromXml(String xml, Class objClass) { + Serializer serializer = new Persister(); + try { + return serializer.read(objClass, xml); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgChangeEventVO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgChangeEventVO.java index 9da66f77..c907a099 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgChangeEventVO.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgChangeEventVO.java @@ -16,7 +16,7 @@ import java.util.List; @Root(name = "SubscribeMsgChangeEvent", strict = false) @Data public class SubscribeMsgChangeEventVO implements Serializable { - private static final long serialVersionUID = -6682105837610124794L; + private static final long serialVersionUID = 1500711025576966938L; /** * 信息集合 */ diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventListVO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventListVO.java index 0316246a..f86f4ae2 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventListVO.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventListVO.java @@ -15,7 +15,7 @@ import java.io.Serializable; @Root(name = "List", strict = false) @Data public class SubscribeMsgPopupEventListVO implements Serializable { - private static final long serialVersionUID = 548605591615555467L; + private static final long serialVersionUID = -4591923245411784629L; /** * 模板id */ diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventVO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventVO.java index 9f552c5c..ac4458b1 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventVO.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgPopupEventVO.java @@ -16,7 +16,7 @@ import java.util.List; @Root(name = "SubscribeMsgPopupEvent", strict = false) @Data public class SubscribeMsgPopupEventVO implements Serializable { - private static final long serialVersionUID = -6682105837610124794L; + private static final long serialVersionUID = -2068512537328225075L; /** * 信息集合 */ diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventListVO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventListVO.java index e85a4c28..1363b589 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventListVO.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventListVO.java @@ -15,7 +15,7 @@ import java.io.Serializable; @Root(name = "List", strict = false) @Data public class SubscribeMsgSentEventListVO implements Serializable { - private static final long serialVersionUID = 3771741965224817805L; + private static final long serialVersionUID = -2104837918391487594L; /** * 模板id */ diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventVO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventVO.java index 6fcc1f42..67fc2f89 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventVO.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/SubscribeMsgSentEventVO.java @@ -16,7 +16,7 @@ import java.util.List; @Root(name = "SubscribeMsgSentEvent", strict = false) @Data public class SubscribeMsgSentEventVO implements Serializable { - private static final long serialVersionUID = -6682105837610124794L; + private static final long serialVersionUID = -8280763002307815282L; /** * 信息集合 */ diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/WeChatMessagePushVO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/WeChatMessagePushVO.java index df50dd6b..1c61798a 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/WeChatMessagePushVO.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatappletcallback/WeChatMessagePushVO.java @@ -15,7 +15,7 @@ import java.io.Serializable; @Root(name = "xml", strict = false) @Data public class WeChatMessagePushVO implements Serializable { - private static final long serialVersionUID = 6233209958847696141L; + private static final long serialVersionUID = 7102691058196437738L; /** * 小程序账号 */ From ddf01f2f49282a11d815599e3bb68b601e0818c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=AA=E5=AF=92?= <2533659732@qq.com> Date: Thu, 21 Mar 2024 14:36:06 +0800 Subject: [PATCH 05/21] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E6=A8=A1=E6=9D=BF=E6=B6=88=E6=81=AF=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=AF=B9=E6=8E=A5=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application.yml | 15 +++- ...onfig.java => WeChatAppletChatConfig.java} | 6 +- .../config/WeChatOfficialAccountConfig.java | 36 ++++++++++ .../com/xinelu/common/constant/Constants.java | 47 +++++++----- .../com/xinelu/common/entity/AccessToken.java | 44 ++++++++++++ .../controller/MobileTestController.java | 22 ++++++ .../WeChatAppletCallBackController.java | 4 +- ...ChatOfficialAccountCallbackController.java | 42 +++++++++++ .../impl/WeChatAppletCallBackServiceImpl.java | 4 +- .../mobile/utils/WeChatAppletUtils.java | 71 +++++++++++++++++++ .../utils/WeChatOfficialAccountUtils.java | 71 +++++++++++++++++++ 11 files changed, 337 insertions(+), 25 deletions(-) rename postdischarge-common/src/main/java/com/xinelu/common/config/{AppletChatConfig.java => WeChatAppletChatConfig.java} (87%) create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/config/WeChatOfficialAccountConfig.java create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/entity/AccessToken.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatofficialaccountcallback/WeChatOfficialAccountCallbackController.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatAppletUtils.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatOfficialAccountUtils.java diff --git a/postdischarge-admin/src/main/resources/application.yml b/postdischarge-admin/src/main/resources/application.yml index 8550115d..257ced72 100644 --- a/postdischarge-admin/src/main/resources/application.yml +++ b/postdischarge-admin/src/main/resources/application.yml @@ -185,8 +185,8 @@ xss: # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* -# 微信小程序参数配置信息 -applet-chat-config: +# 院后微信小程序参数配置信息 +wechat-applet-chat-config: # 微信小程序id,wxdec3416aa3d60cab applet-id: wxdc32268eca6b78f9 # 微信小程序密钥,f58e19be0380c2ebc6e9e9684c0dacce @@ -207,3 +207,14 @@ applet-chat-config: appoint-order-template-id: nUB9HRbqQXOVuTpkKBIHMgzWlNq6touzxf5QYBiMkbU # 签到成功通知模板id sign-template-id: S_c9bR4znSWpXg-6ACIMn7AkaR11dzo113XM8w4CKz0 + +# 院后微信公众号参数配置 +wechat-official-account-config: + # 微信公众号id + official-account-app-id: wx9d87c7c73ef1ebde + # 微信公众号secret + official-account-app-secret: 20ab2c266b1da75d71e9932e7d28326e + # 微信公众号事件回调令牌 + official-account-token: Token + # 微信公众号事件回调消息加密密钥 + official-account-encoding-aes-key: xinyilu \ No newline at end of file diff --git a/postdischarge-common/src/main/java/com/xinelu/common/config/AppletChatConfig.java b/postdischarge-common/src/main/java/com/xinelu/common/config/WeChatAppletChatConfig.java similarity index 87% rename from postdischarge-common/src/main/java/com/xinelu/common/config/AppletChatConfig.java rename to postdischarge-common/src/main/java/com/xinelu/common/config/WeChatAppletChatConfig.java index b2cd5dec..d2db2da6 100644 --- a/postdischarge-common/src/main/java/com/xinelu/common/config/AppletChatConfig.java +++ b/postdischarge-common/src/main/java/com/xinelu/common/config/WeChatAppletChatConfig.java @@ -5,15 +5,15 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** - * @Description 微信小程序参数配置类 + * @Description 新医路院后微信小程序参数配置类 * @Author 纪寒 * @Date 2024-03-19 15:52:38 * @Version 1.0 */ @Data @Component -@ConfigurationProperties(prefix = "applet-chat-config") -public class AppletChatConfig { +@ConfigurationProperties(prefix = "wechat-applet-chat-config") +public class WeChatAppletChatConfig { /** * 小程序id diff --git a/postdischarge-common/src/main/java/com/xinelu/common/config/WeChatOfficialAccountConfig.java b/postdischarge-common/src/main/java/com/xinelu/common/config/WeChatOfficialAccountConfig.java new file mode 100644 index 00000000..fad78d8e --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/config/WeChatOfficialAccountConfig.java @@ -0,0 +1,36 @@ +package com.xinelu.common.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @Description 新医路院后微信公众号参数配置类 + * @Author 纪寒 + * @Date 2024-03-21 11:12:04 + * @Version 1.0 + */ +@Data +@Component +@ConfigurationProperties(prefix = "wechat-official-account-config") +public class WeChatOfficialAccountConfig { + /** + * 微信公众号id + */ + private String officialAccountAppId; + + /** + * 微信公众号secret + */ + private String officialAccountAppSecret; + + /** + * 微信公众号事件回调令牌 + */ + private String officialAccountToken; + + /** + * 微信公众号事件回调消息加密密钥 + */ + private String officialAccountEncodingAesKey; +} diff --git a/postdischarge-common/src/main/java/com/xinelu/common/constant/Constants.java b/postdischarge-common/src/main/java/com/xinelu/common/constant/Constants.java index d41889f7..0023f012 100644 --- a/postdischarge-common/src/main/java/com/xinelu/common/constant/Constants.java +++ b/postdischarge-common/src/main/java/com/xinelu/common/constant/Constants.java @@ -189,23 +189,38 @@ public class Constants { */ public static final String TASK_PARTITION_CODE = "TPC"; - /** - * 门诊患者 - */ - public static final String OUTPATIENT = "outpatient"; + /** + * 门诊患者 + */ + public static final String OUTPATIENT = "outpatient"; - /** - * 预住院 - */ - public static final String PRE_HOSPITALIZED = "prehospitalized"; + /** + * 预住院 + */ + public static final String PRE_HOSPITALIZED = "prehospitalized"; - /** - * 在院 - */ - public static final String IN_HOSPITAL = "inhospital"; + /** + * 在院 + */ + public static final String IN_HOSPITAL = "inhospital"; - /** - * 出院 - */ - public static final String DISCHARGED = "discharged"; + /** + * 出院 + */ + public static final String DISCHARGED = "discharged"; + + /** + * 院后微信小程序accessToken的redis的键前缀 + */ + public static final String WE_CHAT_APPLET_ACCESS_TOKEN = "WE_CHAT_APPLET_ACCESS_TOKEN_"; + + /** + * 院后微信公众号accessToken的redis的键前缀 + */ + public static final String WE_CHAT_OFFICIAL_ACCOUNT_ACCESS_TOKEN = "WE_CHAT_OFFICIAL_ACCOUNT_ACCESS_TOKEN_"; + + /** + * 获取微信小程序和微信公众号accessToken的url地址 + */ + public static final String WE_CHAT_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential"; } diff --git a/postdischarge-common/src/main/java/com/xinelu/common/entity/AccessToken.java b/postdischarge-common/src/main/java/com/xinelu/common/entity/AccessToken.java new file mode 100644 index 00000000..652a145a --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/entity/AccessToken.java @@ -0,0 +1,44 @@ +package com.xinelu.common.entity; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.io.Serializable; + +/** + * @Description 微信小程序和微信公众号accessToken信息实体类 + * @Author 纪寒 + * @Date 2024-03-21 14:00:10 + * @Version 1.0 + */ +@Data +public class AccessToken implements Serializable { + private static final long serialVersionUID = -7751995012730354177L; + /** + * accessToken值 + */ + @JSONField(name = "access_token") + private String accessToken; + + /** + * access_token有效时间,有效时间为7200秒 + */ + @JSONField(name = "expires_in") + private String expiresIn; + + /** + * 错误状态码 + * 40001:AppSecret 错误或者 AppSecret 不属于这个小程序,请开发者确认 AppSecret 的正确性 + * 40002:请确保 grant_type 字段值为 client_credential + * 40013:不合法的 AppID,请开发者检查 AppID 的正确性,避免异常字符,注意大小写 + */ + private Integer errcode; + + /** + * 错误状态值 + * 40001:AppSecret 错误或者 AppSecret 不属于这个小程序,请开发者确认 AppSecret 的正确性 + * 40002:请确保 grant_type 字段值为 client_credential + * 40013:不合法的 AppID,请开发者检查 AppID 的正确性,避免异常字符,注意大小写 + */ + private String errmsg; +} diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/MobileTestController.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/MobileTestController.java index 8ca6acc9..ba977a84 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/MobileTestController.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/MobileTestController.java @@ -1,8 +1,12 @@ package com.xinelu.mobile.controller; +import com.xinelu.mobile.utils.WeChatAppletUtils; +import com.xinelu.mobile.utils.WeChatOfficialAccountUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import javax.annotation.Resource; + /** * @Description 测试controller * @Author 纪寒 @@ -12,5 +16,23 @@ import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/testMobile") public class MobileTestController { + @Resource + private WeChatAppletUtils weChatAppletUtils; + @Resource + private WeChatOfficialAccountUtils weChatOfficialAccountUtils; + /** + * 测试获取微信小程序accessToken + */ + @RequestMapping("/getAppletAcccessToken") + public void getAppletAccessToken() { + weChatAppletUtils.getWeChatAppletAccessToken(); + } + /** + * 测试获取微信公众号accessToken + */ + @RequestMapping("/getOfficialAccountAccessToken") + public void getOfficialAccountAccessToken() { + weChatOfficialAccountUtils.getWeChatOfficialAccountAccessToken(); + } } diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatappletcallback/WeChatAppletCallBackController.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatappletcallback/WeChatAppletCallBackController.java index 6d7006fa..d5b17c56 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatappletcallback/WeChatAppletCallBackController.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatappletcallback/WeChatAppletCallBackController.java @@ -1,6 +1,6 @@ package com.xinelu.mobile.controller.wechatappletcallback; -import com.xinelu.common.config.AppletChatConfig; +import com.xinelu.common.config.WeChatAppletChatConfig; import com.xinelu.common.utils.aes.AesException; import com.xinelu.common.utils.aes.WXBizMsgCrypt; import com.xinelu.mobile.dto.wechatappletcallback.MessageSignDTO; @@ -26,7 +26,7 @@ import java.util.Objects; public class WeChatAppletCallBackController { @Resource - private AppletChatConfig appletChatConfig; + private WeChatAppletChatConfig appletChatConfig; @Resource private WeChatAppletCallBackService weChatAppletCallBackService; diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatofficialaccountcallback/WeChatOfficialAccountCallbackController.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatofficialaccountcallback/WeChatOfficialAccountCallbackController.java new file mode 100644 index 00000000..c48451dc --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatofficialaccountcallback/WeChatOfficialAccountCallbackController.java @@ -0,0 +1,42 @@ +package com.xinelu.mobile.controller.wechatofficialaccountcallback; + +import com.xinelu.common.config.WeChatOfficialAccountConfig; +import com.xinelu.common.utils.aes.AesException; +import com.xinelu.common.utils.aes.WXBizMsgCrypt; +import com.xinelu.mobile.dto.wechatappletcallback.MessageSignDTO; +import lombok.extern.slf4j.Slf4j; +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; + +/** + * @Description 院后微信公众号事件回调控制器 + * @Author 纪寒 + * @Date 2024-03-21 14:26:56 + * @Version 1.0 + */ +@Slf4j +@RestController +@RequestMapping("/postDischarge/officialAccountCallback") +public class WeChatOfficialAccountCallbackController { + @Resource + private WeChatOfficialAccountConfig weChatOfficialAccountConfig; + + /** + * 院后微信公众号回调验证方法 + * + * @param messageSignDTO 微信输入参数 + * @return 解密后的字符串 + * @throws AesException 异常信息 + */ + @GetMapping + public String getWeChatOfficialAccountCallBack(MessageSignDTO messageSignDTO) throws AesException { + WXBizMsgCrypt wxCpt = new WXBizMsgCrypt(weChatOfficialAccountConfig.getOfficialAccountToken(), weChatOfficialAccountConfig.getOfficialAccountEncodingAesKey(), weChatOfficialAccountConfig.getOfficialAccountAppId()); + String verifyMessage = wxCpt.verifyUrl(messageSignDTO.getSignature(), messageSignDTO.getTimestamp(), messageSignDTO.getNonce(), messageSignDTO.getEchostr()); + log.info("院后微信公众号回调设置验证URL成功,验证信息:verifyMessage = [{}]", verifyMessage); + return verifyMessage; + } +} + diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatappletcallback/impl/WeChatAppletCallBackServiceImpl.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatappletcallback/impl/WeChatAppletCallBackServiceImpl.java index 8823f23a..56c427dd 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatappletcallback/impl/WeChatAppletCallBackServiceImpl.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatappletcallback/impl/WeChatAppletCallBackServiceImpl.java @@ -1,6 +1,6 @@ package com.xinelu.mobile.service.wechatappletcallback.impl; -import com.xinelu.common.config.AppletChatConfig; +import com.xinelu.common.config.WeChatAppletChatConfig; import com.xinelu.common.enums.SubscribeMessageTypeEnum; import com.xinelu.common.exception.ServiceException; import com.xinelu.common.utils.DateUtils; @@ -39,7 +39,7 @@ public class WeChatAppletCallBackServiceImpl implements WeChatAppletCallBackServ @Resource private SubscribeMessageRecordMapper subscribeMessageRecordMapper; @Resource - private AppletChatConfig appletChatConfig; + private WeChatAppletChatConfig appletChatConfig; @Resource private PatientInfoMapper patientInfoMapper; @Resource diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatAppletUtils.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatAppletUtils.java new file mode 100644 index 00000000..62b2cba8 --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatAppletUtils.java @@ -0,0 +1,71 @@ +package com.xinelu.mobile.utils; + +import com.alibaba.fastjson2.JSON; +import com.xinelu.common.config.WeChatAppletChatConfig; +import com.xinelu.common.constant.Constants; +import com.xinelu.common.entity.AccessToken; +import com.xinelu.common.exception.ServiceException; +import com.xinelu.common.utils.http.HttpUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +/** + * @Description 院后微信小程序公共方法工具类 + * @Author 纪寒 + * @Date 2024-03-21 13:41:08 + * @Version 1.0 + */ +@Component +public class WeChatAppletUtils { + + @Resource + private RedisTemplate redisTemplate; + @Resource + private WeChatAppletChatConfig weChatAppletChatConfig; + /** + * 返回成功状态码 + */ + private static final int SUCCESS_CODE = 0; + + /** + * 获取微信小程序的accessToken值 + * + * @return 小程序accessToken值 + */ + public String getWeChatAppletAccessToken() { + String accessToken; + String accessTokenRedisKey = Constants.WE_CHAT_APPLET_ACCESS_TOKEN + "accessToken"; + //从Redis中取出accessToken + Object object = redisTemplate.opsForValue().get(accessTokenRedisKey); + if (Objects.isNull(object)) { + //没有,获取accessToken + String accessTokenUrl = Constants.WE_CHAT_ACCESS_TOKEN_URL + "&appid=" + weChatAppletChatConfig.getAppletId() + "&secret=" + weChatAppletChatConfig.getSecret(); + //发送请求 + String result = HttpUtils.sendGet(accessTokenUrl); + if (StringUtils.isBlank(result)) { + throw new ServiceException("获取微信小程序accessToken信息失败", 201); + } + AccessToken weAppletAccessToken = JSON.parseObject(result, AccessToken.class); + if (Objects.isNull(weAppletAccessToken)) { + throw new ServiceException("获取微信小程序accessToken信息失败"); + } + if (Objects.nonNull(weAppletAccessToken.getErrcode()) && weAppletAccessToken.getErrcode() != SUCCESS_CODE) { + throw new ServiceException("获取微信小程序accessToken信息失败,失败信息为:" + weAppletAccessToken.getErrmsg(), 201); + } + if (StringUtils.isBlank(weAppletAccessToken.getAccessToken())) { + throw new ServiceException("微信小程序accessToken信息为空"); + } + accessToken = weAppletAccessToken.getAccessToken(); + //存入Redis中 + redisTemplate.opsForValue().set(accessTokenRedisKey, accessToken, 3600, TimeUnit.SECONDS); + } else { + accessToken = (String) object; + } + return accessToken; + } +} diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatOfficialAccountUtils.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatOfficialAccountUtils.java new file mode 100644 index 00000000..ccfc4b0a --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatOfficialAccountUtils.java @@ -0,0 +1,71 @@ +package com.xinelu.mobile.utils; + +import com.alibaba.fastjson2.JSON; +import com.xinelu.common.config.WeChatOfficialAccountConfig; +import com.xinelu.common.constant.Constants; +import com.xinelu.common.entity.AccessToken; +import com.xinelu.common.exception.ServiceException; +import com.xinelu.common.utils.http.HttpUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +/** + * @Description 院后公众号公众方法工具类 + * @Author 纪寒 + * @Date 2024-03-21 13:42:31 + * @Version 1.0 + */ +@Component +public class WeChatOfficialAccountUtils { + + @Resource + private RedisTemplate redisTemplate; + @Resource + private WeChatOfficialAccountConfig weChatOfficialAccountConfig; + /** + * 返回成功状态码 + */ + private static final int SUCCESS_CODE = 0; + + /** + * 获取院后微信公众号accessToken + * + * @return 微信公众号的accessToken + */ + public String getWeChatOfficialAccountAccessToken() { + String accessToken; + String accessTokenRedisKey = Constants.WE_CHAT_OFFICIAL_ACCOUNT_ACCESS_TOKEN + "accessToken"; + //从Redis中取出accessToken + Object object = redisTemplate.opsForValue().get(accessTokenRedisKey); + if (Objects.isNull(object)) { + //没有,获取accessToken + String accessTokenUrl = Constants.WE_CHAT_ACCESS_TOKEN_URL + "&appid=" + weChatOfficialAccountConfig.getOfficialAccountAppId() + "&secret=" + weChatOfficialAccountConfig.getOfficialAccountAppSecret(); + //发送请求 + String result = HttpUtils.sendGet(accessTokenUrl); + if (StringUtils.isBlank(result)) { + throw new ServiceException("获取微信公众号accessToken信息失败", 201); + } + AccessToken officialAccountAccessToken = JSON.parseObject(result, AccessToken.class); + if (Objects.isNull(officialAccountAccessToken)) { + throw new ServiceException("获取微信公众号accessToken信息失败"); + } + if (Objects.nonNull(officialAccountAccessToken.getErrcode()) && officialAccountAccessToken.getErrcode() != SUCCESS_CODE) { + throw new ServiceException("获取微信公众号accessToken信息失败,失败信息为:" + officialAccountAccessToken.getErrmsg(), 201); + } + if (StringUtils.isBlank(officialAccountAccessToken.getAccessToken())) { + throw new ServiceException("微信公众号accessToken信息为空"); + } + accessToken = officialAccountAccessToken.getAccessToken(); + //存入Redis中 + redisTemplate.opsForValue().set(accessTokenRedisKey, accessToken, 3600, TimeUnit.SECONDS); + } else { + accessToken = (String) object; + } + return accessToken; + } +} From 4cd5348e7d540e94d25cc9b81bd742c6d7067abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=AA=E5=AF=92?= <2533659732@qq.com> Date: Thu, 21 Mar 2024 15:29:46 +0800 Subject: [PATCH 06/21] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E6=A8=A1=E6=9D=BF=E6=B6=88=E6=81=AF=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=A1=E6=81=AF=E5=8F=82=E6=95=B0=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- postdischarge-admin/src/main/resources/application.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/postdischarge-admin/src/main/resources/application.yml b/postdischarge-admin/src/main/resources/application.yml index 257ced72..1d53c9c5 100644 --- a/postdischarge-admin/src/main/resources/application.yml +++ b/postdischarge-admin/src/main/resources/application.yml @@ -215,6 +215,6 @@ wechat-official-account-config: # 微信公众号secret official-account-app-secret: 20ab2c266b1da75d71e9932e7d28326e # 微信公众号事件回调令牌 - official-account-token: Token + official-account-token: xinyilu # 微信公众号事件回调消息加密密钥 - official-account-encoding-aes-key: xinyilu \ No newline at end of file + official-account-encoding-aes-key: Awcn7nvDU4bcfBwAZmiRbB3lFgXAm2RIg45utdb5Zt3 \ No newline at end of file From e0f8e8072aaa052dc8cdb24b2df57465b5f2f707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=AA=E5=AF=92?= <2533659732@qq.com> Date: Thu, 21 Mar 2024 17:36:40 +0800 Subject: [PATCH 07/21] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E6=A8=A1=E6=9D=BF=E6=B6=88=E6=81=AF=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=A1=E6=81=AF=E5=8F=82=E6=95=B0=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application.yml | 2 +- .../mobile/controller/MobileTestController.java | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/postdischarge-admin/src/main/resources/application.yml b/postdischarge-admin/src/main/resources/application.yml index 1d53c9c5..0b21fe40 100644 --- a/postdischarge-admin/src/main/resources/application.yml +++ b/postdischarge-admin/src/main/resources/application.yml @@ -101,7 +101,7 @@ token: # 令牌有效期(默认30分钟) expireTime: 30 # 请求拦截白名单 - ant-matchers: /postDischarge/** + ant-matchers: /postDischarge/**,/testMobile/** ## MyBatis-Plus配置 mybatis-plus: diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/MobileTestController.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/MobileTestController.java index ba977a84..aae18f01 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/MobileTestController.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/MobileTestController.java @@ -2,6 +2,7 @@ package com.xinelu.mobile.controller; import com.xinelu.mobile.utils.WeChatAppletUtils; import com.xinelu.mobile.utils.WeChatOfficialAccountUtils; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -20,19 +21,20 @@ public class MobileTestController { private WeChatAppletUtils weChatAppletUtils; @Resource private WeChatOfficialAccountUtils weChatOfficialAccountUtils; + /** * 测试获取微信小程序accessToken */ - @RequestMapping("/getAppletAcccessToken") - public void getAppletAccessToken() { - weChatAppletUtils.getWeChatAppletAccessToken(); + @GetMapping("/getAppletAcccessToken") + public String getAppletAccessToken() { + return weChatAppletUtils.getWeChatAppletAccessToken(); } /** * 测试获取微信公众号accessToken */ - @RequestMapping("/getOfficialAccountAccessToken") - public void getOfficialAccountAccessToken() { - weChatOfficialAccountUtils.getWeChatOfficialAccountAccessToken(); + @GetMapping("/getOfficialAccountAccessToken") + public String getOfficialAccountAccessToken() { + return weChatOfficialAccountUtils.getWeChatOfficialAccountAccessToken(); } } From 35d9a6199ce8d30b7d4fe6d3b33c50f2852bc2fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=AA=E5=AF=92?= <2533659732@qq.com> Date: Mon, 25 Mar 2024 17:46:41 +0800 Subject: [PATCH 08/21] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E6=A8=A1=E6=9D=BF=E6=B6=88=E6=81=AF=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=A1=E6=81=AF=E5=8F=82=E6=95=B0=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application.yml | 4 +- postdischarge-common/pom.xml | 6 + .../com/xinelu/common/constant/Constants.java | 40 ++++ .../enums/TemplateEventSendStatusEnum.java | 34 ++++ .../xinelu/common/utils/http/HttpUtils.java | 46 +++++ .../OfficialAccountTemplateEvent.java | 119 +++++++++++ .../OfficialAccountTemplateEventMapper.java | 61 ++++++ .../IOfficialAccountTemplateEventService.java | 61 ++++++ ...ficialAccountTemplateEventServiceImpl.java | 90 +++++++++ .../OfficialAccountTemplateEventMapper.xml | 185 ++++++++++++++++++ .../controller/MobileTestController.java | 8 + ...ChatOfficialAccountCallbackController.java | 41 +++- .../WeChatOfficialAccountCallbackService.java | 18 ++ ...hatOfficialAccountCallbackServiceImpl.java | 65 ++++++ .../utils/WeChatOfficialAccountUtils.java | 62 ++++++ .../WeChatOfficialAccountEventPushVO.java | 60 ++++++ 16 files changed, 896 insertions(+), 4 deletions(-) create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/enums/TemplateEventSendStatusEnum.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/domain/officialaccounttemplateevent/OfficialAccountTemplateEvent.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/mapper/officialaccounttemplateevent/OfficialAccountTemplateEventMapper.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccounttemplateevent/IOfficialAccountTemplateEventService.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccounttemplateevent/impl/OfficialAccountTemplateEventServiceImpl.java create mode 100644 postdischarge-manage/src/main/resources/mapper/manage/officialaccounttemplateevent/OfficialAccountTemplateEventMapper.xml create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/WeChatOfficialAccountCallbackService.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/impl/WeChatOfficialAccountCallbackServiceImpl.java create mode 100644 postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatofficialaccountcallback/WeChatOfficialAccountEventPushVO.java diff --git a/postdischarge-admin/src/main/resources/application.yml b/postdischarge-admin/src/main/resources/application.yml index 0b21fe40..89a7ce9f 100644 --- a/postdischarge-admin/src/main/resources/application.yml +++ b/postdischarge-admin/src/main/resources/application.yml @@ -217,4 +217,6 @@ wechat-official-account-config: # 微信公众号事件回调令牌 official-account-token: xinyilu # 微信公众号事件回调消息加密密钥 - official-account-encoding-aes-key: Awcn7nvDU4bcfBwAZmiRbB3lFgXAm2RIg45utdb5Zt3 \ No newline at end of file + official-account-encoding-aes-key: Awcn7nvDU4bcfBwAZmiRbB3lFgXAm2RIg45utdb5Zt3 + # 测试模板id + test-template-id: WUCYtSbH-QFRV_fMcfmn86QLsz1zo881QW7fQNTWOjc \ No newline at end of file diff --git a/postdischarge-common/pom.xml b/postdischarge-common/pom.xml index f64df95d..73f446fc 100644 --- a/postdischarge-common/pom.xml +++ b/postdischarge-common/pom.xml @@ -111,6 +111,12 @@ org.projectlombok lombok + + + org.apache.httpcomponents + httpclient + 4.5.13 + \ No newline at end of file diff --git a/postdischarge-common/src/main/java/com/xinelu/common/constant/Constants.java b/postdischarge-common/src/main/java/com/xinelu/common/constant/Constants.java index 0023f012..fef06939 100644 --- a/postdischarge-common/src/main/java/com/xinelu/common/constant/Constants.java +++ b/postdischarge-common/src/main/java/com/xinelu/common/constant/Constants.java @@ -223,4 +223,44 @@ public class Constants { * 获取微信小程序和微信公众号accessToken的url地址 */ public static final String WE_CHAT_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential"; + + /** + * 微信公众号模板消息推送发送接口地址 + */ + public static final String OFFICIAL_ACCOUNT_TEMPLATE_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="; + + /** + * 获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口 + */ + public static final int INVALID_CREDENTIAL_ACCESS_TOKEN_ISINVALID_OR_NOT_LATEST = 40001; + + /** + * 不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID + */ + public static final int INVALID_OPENID = 40003; + + /** + * 不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口 + */ + public static final int INVALID_ACCESS_TOKEN = 40014; + + /** + * 不合法的 template_id + */ + public static final int INVALID_TEMPLATE_ID = 40037; + + /** + * 用户拒接订阅 + */ + public static final int DENY_SUBSCRIPTION = 43101; + + /** + * 参数无效 + */ + public static final int ARGUMENT_INVALID = 47003; + + /** + * 成功 + */ + public static final int SUCCESS_ERROR_CODE = 0; } diff --git a/postdischarge-common/src/main/java/com/xinelu/common/enums/TemplateEventSendStatusEnum.java b/postdischarge-common/src/main/java/com/xinelu/common/enums/TemplateEventSendStatusEnum.java new file mode 100644 index 00000000..8d45922a --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/enums/TemplateEventSendStatusEnum.java @@ -0,0 +1,34 @@ +package com.xinelu.common.enums; + +import lombok.Getter; + +/** + * @Description 微信公众号模板事件消息发送状态枚举 + * @Author 纪寒 + * @Date 2024-03-25 14:38:27 + * @Version 1.0 + */ +@Getter +public enum TemplateEventSendStatusEnum { + /** + * 成功 + */ + SUCCESS("success"), + + /** + * 用户拒绝接收 + */ + REJECT("failed:user block"), + + /** + * 发送失败 + */ + FAILED("failed:system failed"), + ; + + final private String info; + + TemplateEventSendStatusEnum(String info) { + this.info = info; + } +} diff --git a/postdischarge-common/src/main/java/com/xinelu/common/utils/http/HttpUtils.java b/postdischarge-common/src/main/java/com/xinelu/common/utils/http/HttpUtils.java index 9159bb3b..1d5c3109 100644 --- a/postdischarge-common/src/main/java/com/xinelu/common/utils/http/HttpUtils.java +++ b/postdischarge-common/src/main/java/com/xinelu/common/utils/http/HttpUtils.java @@ -2,6 +2,16 @@ package com.xinelu.common.utils.http; import com.xinelu.common.constant.Constants; import com.xinelu.common.utils.StringUtils; +import org.apache.http.Consts; +import org.apache.http.HttpEntity; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.HttpClientUtils; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -207,4 +217,40 @@ public class HttpUtils { return true; } } + + /** + * 发送json格式的POST类型的http请求 + * + * @param url 请求地址 + * @param param json格式的请求参数 + * @return String 返回值信息 + */ + public static String sendPostJson(String url, String param) { + String result = null; + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + try { + httpClient = HttpClients.createDefault(); + // 字符串编码 + StringEntity entity = new StringEntity(param, Consts.UTF_8); + // 设置content-type + entity.setContentType("application/json"); + HttpPost httpPost = new HttpPost(url); + httpPost.setConfig(RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).build()); + // 防止被当成攻击添加的 + httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/54.0.2840.87 Safari/537.36"); + // 接收参数设置 + httpPost.setHeader("Accept", "application/json"); + httpPost.setEntity(entity); + response = httpClient.execute(httpPost); + HttpEntity httpEntity = response.getEntity(); + result = EntityUtils.toString(httpEntity); + } catch (Exception e) { + log.warn("post请求发送失败,请求路径:[{}],请求参数:[{}],异常信息:[{}]", url, param, e); + } finally { + HttpClientUtils.closeQuietly(response); + HttpClientUtils.closeQuietly(httpClient); + } + return result; + } } \ No newline at end of file diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/officialaccounttemplateevent/OfficialAccountTemplateEvent.java b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/officialaccounttemplateevent/OfficialAccountTemplateEvent.java new file mode 100644 index 00000000..0b1d7bd6 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/officialaccounttemplateevent/OfficialAccountTemplateEvent.java @@ -0,0 +1,119 @@ +package com.xinelu.manage.domain.officialaccounttemplateevent; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.xinelu.common.annotation.Excel; +import com.xinelu.common.core.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.time.LocalDateTime; + +/** + * 微信公众号模板信息事件推送对象 official_account_template_event + * + * @author xinelu + * @date 2024-03-25 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +@ApiModel(value = "微信公众号模板信息事件推送对象", description = "official_account_template_event") +public class OfficialAccountTemplateEvent extends BaseEntity { + private static final long serialVersionUID = -8437491233815143821L; + /** + * 主键id + */ + private Long id; + + /** + * 患者信息表id + */ + @ApiModelProperty(value = "患者信息表id") + @Excel(name = "患者信息表id") + private Long patientId; + + /** + * 患者姓名 + */ + @ApiModelProperty(value = "患者姓名") + @Excel(name = "患者姓名") + private String patientName; + + /** + * 微信用户openid + */ + @ApiModelProperty(value = "微信用户openid") + @Excel(name = "微信用户openid") + private String openid; + + /** + * 微信公众号id + */ + @ApiModelProperty(value = "微信公众号id") + @Excel(name = "微信公众号id") + private String officialAccountAppId; + + /** + * 发送时间,即:事件创建时间,yyyy-MM-dd HH:mm:ss + */ + @ApiModelProperty(value = "发送时间,即:事件创建时间,yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "发送时间,即:事件创建时间,yyyy-MM-dd HH:mm:ss", width = 30, dateFormat = "yyyy-MM-dd") + private LocalDateTime sendTime; + + /** + * 消息类型是事件,固定取值为:event + */ + @ApiModelProperty(value = "消息类型是事件,固定取值为:event") + @Excel(name = "消息类型是事件,固定取值为:event") + private String msgType; + + /** + * 事件为模板消息发送结束,固定取值为:TEMPLATESENDJOBFINISH + */ + @ApiModelProperty(value = "事件为模板消息发送结束,固定取值为:TEMPLATESENDJOBFINISH") + @Excel(name = "事件为模板消息发送结束,固定取值为:TEMPLATESENDJOBFINISH") + private String eventType; + + /** + * 消息id + */ + @ApiModelProperty(value = "消息id") + @Excel(name = "消息id") + private String msgId; + + /** + * 发送状态,成功:success,用户拒绝接收:failed:user block,发送失败(非用户拒绝):failed:system failed + */ + @ApiModelProperty(value = "发送状态,成功:success,用户拒绝接收:failed:user block,发送失败") + @Excel(name = "发送状态,成功:success,用户拒绝接收:failed:user block,发送失败", readConverterExp = "非=用户拒绝") + private String status; + + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("patientId", getPatientId()) + .append("patientName", getPatientName()) + .append("openid", getOpenid()) + .append("officialAccountAppId", getOfficialAccountAppId()) + .append("sendTime", getSendTime()) + .append("msgType", getMsgType()) + .append("eventType", getEventType()) + .append("msgId", getMsgId()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/officialaccounttemplateevent/OfficialAccountTemplateEventMapper.java b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/officialaccounttemplateevent/OfficialAccountTemplateEventMapper.java new file mode 100644 index 00000000..ef4d97f4 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/officialaccounttemplateevent/OfficialAccountTemplateEventMapper.java @@ -0,0 +1,61 @@ +package com.xinelu.manage.mapper.officialaccounttemplateevent; + +import com.xinelu.manage.domain.officialaccounttemplateevent.OfficialAccountTemplateEvent; + +import java.util.List; + +/** + * 微信公众号模板信息事件推送Mapper接口 + * + * @author xinelu + * @date 2024-03-25 + */ +public interface OfficialAccountTemplateEventMapper { + /** + * 查询微信公众号模板信息事件推送 + * + * @param id 微信公众号模板信息事件推送主键 + * @return 微信公众号模板信息事件推送 + */ + OfficialAccountTemplateEvent selectOfficialAccountTemplateEventById(Long id); + + /** + * 查询微信公众号模板信息事件推送列表 + * + * @param officialAccountTemplateEvent 微信公众号模板信息事件推送 + * @return 微信公众号模板信息事件推送集合 + */ + List selectOfficialAccountTemplateEventList(OfficialAccountTemplateEvent officialAccountTemplateEvent); + + /** + * 新增微信公众号模板信息事件推送 + * + * @param officialAccountTemplateEvent 微信公众号模板信息事件推送 + * @return 结果 + */ + int insertOfficialAccountTemplateEvent(OfficialAccountTemplateEvent officialAccountTemplateEvent); + + /** + * 修改微信公众号模板信息事件推送 + * + * @param officialAccountTemplateEvent 微信公众号模板信息事件推送 + * @return 结果 + */ + int updateOfficialAccountTemplateEvent(OfficialAccountTemplateEvent officialAccountTemplateEvent); + + /** + * 删除微信公众号模板信息事件推送 + * + * @param id 微信公众号模板信息事件推送主键 + * @return 结果 + */ + int deleteOfficialAccountTemplateEventById(Long id); + + /** + * 批量删除微信公众号模板信息事件推送 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteOfficialAccountTemplateEventByIds(Long[] ids); +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccounttemplateevent/IOfficialAccountTemplateEventService.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccounttemplateevent/IOfficialAccountTemplateEventService.java new file mode 100644 index 00000000..27d77114 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccounttemplateevent/IOfficialAccountTemplateEventService.java @@ -0,0 +1,61 @@ +package com.xinelu.manage.service.officialaccounttemplateevent; + +import com.xinelu.manage.domain.officialaccounttemplateevent.OfficialAccountTemplateEvent; + +import java.util.List; + +/** + * 微信公众号模板信息事件推送Service接口 + * + * @author xinelu + * @date 2024-03-25 + */ +public interface IOfficialAccountTemplateEventService { + /** + * 查询微信公众号模板信息事件推送 + * + * @param id 微信公众号模板信息事件推送主键 + * @return 微信公众号模板信息事件推送 + */ + OfficialAccountTemplateEvent selectOfficialAccountTemplateEventById(Long id); + + /** + * 查询微信公众号模板信息事件推送列表 + * + * @param officialAccountTemplateEvent 微信公众号模板信息事件推送 + * @return 微信公众号模板信息事件推送集合 + */ + List selectOfficialAccountTemplateEventList(OfficialAccountTemplateEvent officialAccountTemplateEvent); + + /** + * 新增微信公众号模板信息事件推送 + * + * @param officialAccountTemplateEvent 微信公众号模板信息事件推送 + * @return 结果 + */ + int insertOfficialAccountTemplateEvent(OfficialAccountTemplateEvent officialAccountTemplateEvent); + + /** + * 修改微信公众号模板信息事件推送 + * + * @param officialAccountTemplateEvent 微信公众号模板信息事件推送 + * @return 结果 + */ + int updateOfficialAccountTemplateEvent(OfficialAccountTemplateEvent officialAccountTemplateEvent); + + /** + * 批量删除微信公众号模板信息事件推送 + * + * @param ids 需要删除的微信公众号模板信息事件推送主键集合 + * @return 结果 + */ + int deleteOfficialAccountTemplateEventByIds(Long[] ids); + + /** + * 删除微信公众号模板信息事件推送信息 + * + * @param id 微信公众号模板信息事件推送主键 + * @return 结果 + */ + int deleteOfficialAccountTemplateEventById(Long id); +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccounttemplateevent/impl/OfficialAccountTemplateEventServiceImpl.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccounttemplateevent/impl/OfficialAccountTemplateEventServiceImpl.java new file mode 100644 index 00000000..f9546e1b --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccounttemplateevent/impl/OfficialAccountTemplateEventServiceImpl.java @@ -0,0 +1,90 @@ +package com.xinelu.manage.service.officialaccounttemplateevent.impl; + +import com.xinelu.manage.domain.officialaccounttemplateevent.OfficialAccountTemplateEvent; +import com.xinelu.manage.mapper.officialaccounttemplateevent.OfficialAccountTemplateEventMapper; +import com.xinelu.manage.service.officialaccounttemplateevent.IOfficialAccountTemplateEventService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 微信公众号模板信息事件推送Service业务层处理 + * + * @author xinelu + * @date 2024-03-25 + */ +@Service +public class OfficialAccountTemplateEventServiceImpl implements IOfficialAccountTemplateEventService { + @Resource + private OfficialAccountTemplateEventMapper officialAccountTemplateEventMapper; + + /** + * 查询微信公众号模板信息事件推送 + * + * @param id 微信公众号模板信息事件推送主键 + * @return 微信公众号模板信息事件推送 + */ + @Override + public OfficialAccountTemplateEvent selectOfficialAccountTemplateEventById(Long id) { + return officialAccountTemplateEventMapper.selectOfficialAccountTemplateEventById(id); + } + + /** + * 查询微信公众号模板信息事件推送列表 + * + * @param officialAccountTemplateEvent 微信公众号模板信息事件推送 + * @return 微信公众号模板信息事件推送 + */ + @Override + public List selectOfficialAccountTemplateEventList(OfficialAccountTemplateEvent officialAccountTemplateEvent) { + return officialAccountTemplateEventMapper.selectOfficialAccountTemplateEventList(officialAccountTemplateEvent); + } + + /** + * 新增微信公众号模板信息事件推送 + * + * @param officialAccountTemplateEvent 微信公众号模板信息事件推送 + * @return 结果 + */ + @Override + public int insertOfficialAccountTemplateEvent(OfficialAccountTemplateEvent officialAccountTemplateEvent) { + officialAccountTemplateEvent.setCreateTime(LocalDateTime.now()); + return officialAccountTemplateEventMapper.insertOfficialAccountTemplateEvent(officialAccountTemplateEvent); + } + + /** + * 修改微信公众号模板信息事件推送 + * + * @param officialAccountTemplateEvent 微信公众号模板信息事件推送 + * @return 结果 + */ + @Override + public int updateOfficialAccountTemplateEvent(OfficialAccountTemplateEvent officialAccountTemplateEvent) { + officialAccountTemplateEvent.setUpdateTime(LocalDateTime.now()); + return officialAccountTemplateEventMapper.updateOfficialAccountTemplateEvent(officialAccountTemplateEvent); + } + + /** + * 批量删除微信公众号模板信息事件推送 + * + * @param ids 需要删除的微信公众号模板信息事件推送主键 + * @return 结果 + */ + @Override + public int deleteOfficialAccountTemplateEventByIds(Long[] ids) { + return officialAccountTemplateEventMapper.deleteOfficialAccountTemplateEventByIds(ids); + } + + /** + * 删除微信公众号模板信息事件推送信息 + * + * @param id 微信公众号模板信息事件推送主键 + * @return 结果 + */ + @Override + public int deleteOfficialAccountTemplateEventById(Long id) { + return officialAccountTemplateEventMapper.deleteOfficialAccountTemplateEventById(id); + } +} diff --git a/postdischarge-manage/src/main/resources/mapper/manage/officialaccounttemplateevent/OfficialAccountTemplateEventMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/officialaccounttemplateevent/OfficialAccountTemplateEventMapper.xml new file mode 100644 index 00000000..eeade5db --- /dev/null +++ b/postdischarge-manage/src/main/resources/mapper/manage/officialaccounttemplateevent/OfficialAccountTemplateEventMapper.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + select id, patient_id, patient_name, openid, official_account_app_id, send_time, msg_type, event_type, msg_id, status, create_by, create_time, update_by, update_time from official_account_template_event + + + + + + + + insert into official_account_template_event + + patient_id, + + patient_name, + + openid, + + official_account_app_id, + + send_time, + + msg_type, + + event_type, + + msg_id, + + status, + + create_by, + + create_time, + + update_by, + + update_time, + + + + #{patientId}, + + #{patientName}, + + #{openid}, + + #{officialAccountAppId}, + + #{sendTime}, + + #{msgType}, + + #{eventType}, + + #{msgId}, + + #{status}, + + #{createBy}, + + #{createTime}, + + #{updateBy}, + + #{updateTime}, + + + + + + update official_account_template_event + + patient_id = + #{patientId}, + + patient_name = + #{patientName}, + + openid = + #{openid}, + + official_account_app_id = + #{officialAccountAppId}, + + send_time = + #{sendTime}, + + msg_type = + #{msgType}, + + event_type = + #{eventType}, + + msg_id = + #{msgId}, + + status = + #{status}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + + where id = #{id} + + + + delete from official_account_template_event where id = #{id} + + + + delete from official_account_template_event where id in + + #{id} + + + \ No newline at end of file diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/MobileTestController.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/MobileTestController.java index aae18f01..ad840f07 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/MobileTestController.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/MobileTestController.java @@ -37,4 +37,12 @@ public class MobileTestController { public String getOfficialAccountAccessToken() { return weChatOfficialAccountUtils.getWeChatOfficialAccountAccessToken(); } + + /** + * 测试微信公众号模板消息发送 + */ + @GetMapping("/sendOfficialAccountTemplate") + public void sendOfficialAccountTemplateMessage() { + weChatOfficialAccountUtils.sendOfficialAccountTemplateMessage(); + } } diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatofficialaccountcallback/WeChatOfficialAccountCallbackController.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatofficialaccountcallback/WeChatOfficialAccountCallbackController.java index c48451dc..225dfdf6 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatofficialaccountcallback/WeChatOfficialAccountCallbackController.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatofficialaccountcallback/WeChatOfficialAccountCallbackController.java @@ -4,12 +4,15 @@ import com.xinelu.common.config.WeChatOfficialAccountConfig; import com.xinelu.common.utils.aes.AesException; import com.xinelu.common.utils.aes.WXBizMsgCrypt; import com.xinelu.mobile.dto.wechatappletcallback.MessageSignDTO; +import com.xinelu.mobile.service.wechatofficialaccountcallback.WeChatOfficialAccountCallbackService; +import com.xinelu.mobile.utils.XmlUtil; +import com.xinelu.mobile.vo.wechatofficialaccountcallback.WeChatOfficialAccountEventPushVO; import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import java.util.Objects; /** * @Description 院后微信公众号事件回调控制器 @@ -23,6 +26,8 @@ import javax.annotation.Resource; public class WeChatOfficialAccountCallbackController { @Resource private WeChatOfficialAccountConfig weChatOfficialAccountConfig; + @Resource + private WeChatOfficialAccountCallbackService weChatOfficialAccountCallbackService; /** * 院后微信公众号回调验证方法 @@ -33,10 +38,40 @@ public class WeChatOfficialAccountCallbackController { */ @GetMapping public String getWeChatOfficialAccountCallBack(MessageSignDTO messageSignDTO) throws AesException { + //解密微信报文信息并验证微信公众号与服务器之间是否正常通信 WXBizMsgCrypt wxCpt = new WXBizMsgCrypt(weChatOfficialAccountConfig.getOfficialAccountToken(), weChatOfficialAccountConfig.getOfficialAccountEncodingAesKey(), weChatOfficialAccountConfig.getOfficialAccountAppId()); String verifyMessage = wxCpt.verifyUrl(messageSignDTO.getSignature(), messageSignDTO.getTimestamp(), messageSignDTO.getNonce(), messageSignDTO.getEchostr()); log.info("院后微信公众号回调设置验证URL成功,验证信息:verifyMessage = [{}]", verifyMessage); return verifyMessage; } + + /** + * 院后微信公众号模板消息事件回调处理 + * + * @param signature 签名 + * @param timestamp 时间戳 + * @param nonce 随机字符串 + * @param postData 事件报文内容 + * @throws AesException 异常信息 + */ + @PostMapping + public void handleWeChatOfficialAccountCallBack(@RequestParam("signature") String signature, + @RequestParam("timestamp") String timestamp, + @RequestParam("nonce") String nonce, + @RequestBody String postData) throws AesException { + //解密微信报文信息并验证微信公众号与服务器之间是否正常通信 + WXBizMsgCrypt wxCpt = new WXBizMsgCrypt(weChatOfficialAccountConfig.getOfficialAccountToken(), weChatOfficialAccountConfig.getOfficialAccountEncodingAesKey(), weChatOfficialAccountConfig.getOfficialAccountAppId()); + String verifyMessage = wxCpt.verifyUrl(signature, timestamp, nonce, postData); + WeChatOfficialAccountEventPushVO eventPush = (WeChatOfficialAccountEventPushVO) XmlUtil.fromXml(verifyMessage, WeChatOfficialAccountEventPushVO.class); + if (Objects.isNull(eventPush)) { + log.info("院后微信公众号模板消息事件xml数据转换失败,请求信息为: [{}]", verifyMessage); + return; + } + if (StringUtils.isBlank(eventPush.getToUserName()) || StringUtils.isBlank(eventPush.getEvent()) || StringUtils.isBlank(eventPush.getMsgType())) { + log.info("院后微信公众号模板消息事件解析事件数据为空!"); + return; + } + weChatOfficialAccountCallbackService.handleOfficialAccountTemplateEvent(eventPush); + } } diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/WeChatOfficialAccountCallbackService.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/WeChatOfficialAccountCallbackService.java new file mode 100644 index 00000000..27e4c650 --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/WeChatOfficialAccountCallbackService.java @@ -0,0 +1,18 @@ +package com.xinelu.mobile.service.wechatofficialaccountcallback; + +import com.xinelu.mobile.vo.wechatofficialaccountcallback.WeChatOfficialAccountEventPushVO; + +/** + * @Description 院后微信公众号事件回调service + * @Author 纪寒 + * @Date 2024-03-25 14:52:03 + * @Version 1.0 + */ +public interface WeChatOfficialAccountCallbackService { + /** + * 院后微信公众号模板消息事件回调处理 + * + * @param eventPushVO 模板消息事件回调数据 + */ + void handleOfficialAccountTemplateEvent(WeChatOfficialAccountEventPushVO eventPushVO); +} diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/impl/WeChatOfficialAccountCallbackServiceImpl.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/impl/WeChatOfficialAccountCallbackServiceImpl.java new file mode 100644 index 00000000..0f68d8af --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/impl/WeChatOfficialAccountCallbackServiceImpl.java @@ -0,0 +1,65 @@ +package com.xinelu.mobile.service.wechatofficialaccountcallback.impl; + +import com.xinelu.common.exception.ServiceException; +import com.xinelu.common.utils.DateUtils; +import com.xinelu.manage.domain.officialaccounttemplateevent.OfficialAccountTemplateEvent; +import com.xinelu.manage.domain.patientinfo.PatientInfo; +import com.xinelu.manage.mapper.officialaccounttemplateevent.OfficialAccountTemplateEventMapper; +import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper; +import com.xinelu.mobile.service.wechatofficialaccountcallback.WeChatOfficialAccountCallbackService; +import com.xinelu.mobile.vo.wechatofficialaccountcallback.WeChatOfficialAccountEventPushVO; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.Objects; + +/** + * @Description 院后微信公众号事件回调service实现 + * @Author 纪寒 + * @Date 2024-03-25 14:55:53 + * @Version 1.0 + */ +@Service +@Slf4j +public class WeChatOfficialAccountCallbackServiceImpl implements WeChatOfficialAccountCallbackService { + + @Resource + private PatientInfoMapper patientInfoMapper; + @Resource + private OfficialAccountTemplateEventMapper officialAccountTemplateEventMapper; + + /** + * 院后微信公众号模板消息事件回调处理 + * + * @param eventPushVO 模板消息事件回调数据 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public void handleOfficialAccountTemplateEvent(WeChatOfficialAccountEventPushVO eventPushVO) { + //查询患者信息 + PatientInfo patientInfo = patientInfoMapper.getPatientInfoByOpenId(eventPushVO.getFromUserName()); + if (Objects.isNull(patientInfo)) { + log.info("当前患者信息不存在,微信用户openid为:{}", eventPushVO.getFromUserName()); + return; + } + OfficialAccountTemplateEvent templateEvent = new OfficialAccountTemplateEvent(); + templateEvent.setPatientId(Objects.isNull(patientInfo.getId()) ? null : patientInfo.getId()); + templateEvent.setPatientName(StringUtils.isBlank(patientInfo.getPatientName()) ? "" : patientInfo.getPatientName()); + templateEvent.setOpenid(eventPushVO.getFromUserName()); + templateEvent.setOfficialAccountAppId(StringUtils.isBlank(eventPushVO.getToUserName()) ? "" : eventPushVO.getToUserName()); + templateEvent.setSendTime(StringUtils.isBlank(eventPushVO.getCreateTime()) ? null : DateUtils.timestampToLocalDateTime(Long.parseLong(eventPushVO.getCreateTime()) * 1000L)); + templateEvent.setMsgType(StringUtils.isBlank(eventPushVO.getMsgType()) ? "" : eventPushVO.getMsgType()); + templateEvent.setEventType(StringUtils.isBlank(eventPushVO.getEvent()) ? "" : eventPushVO.getEvent()); + templateEvent.setMsgId(StringUtils.isBlank(eventPushVO.getMsgId()) ? "" : eventPushVO.getMsgId()); + templateEvent.setStatus(StringUtils.isBlank(eventPushVO.getStatus()) ? "" : eventPushVO.getStatus()); + int insertTemplateEventCount = officialAccountTemplateEventMapper.insertOfficialAccountTemplateEvent(templateEvent); + if (insertTemplateEventCount < 0) { + log.error("院后微信公众号模板事件推送,新增模板事件消息信息失败,信息为:[{}]", templateEvent); + throw new ServiceException("院后微信公众号模板事件推送记录信息失败!"); + } + log.info("院后微信公众号模板事件推送处理成功!"); + } +} diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatOfficialAccountUtils.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatOfficialAccountUtils.java index ccfc4b0a..6c3a3f93 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatOfficialAccountUtils.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatOfficialAccountUtils.java @@ -6,11 +6,14 @@ import com.xinelu.common.constant.Constants; import com.xinelu.common.entity.AccessToken; import com.xinelu.common.exception.ServiceException; import com.xinelu.common.utils.http.HttpUtils; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import javax.annotation.Resource; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.Objects; import java.util.concurrent.TimeUnit; @@ -20,6 +23,7 @@ import java.util.concurrent.TimeUnit; * @Date 2024-03-21 13:42:31 * @Version 1.0 */ +@Slf4j @Component public class WeChatOfficialAccountUtils { @@ -68,4 +72,62 @@ public class WeChatOfficialAccountUtils { } return accessToken; } + + /** + * 微信公众号模板消息发送 + */ + public void sendOfficialAccountTemplateMessage() { + //获取微信公众号的accessToken + String accessToken = this.getWeChatOfficialAccountAccessToken(); + //定义模板内容,公众模板内容 + Map paramsMap = new LinkedHashMap<>(); + paramsMap.put("touser", "oHBuH5T90TghJdYKfBlxE4fhayBc"); + paramsMap.put("template_id", "WUCYtSbH-QFRV_fMcfmn86QLsz1zo881QW7fQNTWOjc"); + //微信小程序跳转内容 + Map miniprogramMap = new LinkedHashMap<>(); + miniprogramMap.put("appid", "wxdc32268eca6b78f9"); + miniprogramMap.put("pagepath", "pages/startup/startup"); + //微信小程序模板data内容 + Map dataMap = new LinkedHashMap<>(); + dataMap.put("phrase7", "泉医陪护服务"); + dataMap.put("character_string3", "000026315412331612100"); + dataMap.put("time6", "2024-03-25 16:21:32"); + dataMap.put("time10", "2024-03-27 10:00:00"); + dataMap.put("thing11", "济南市槐荫区首诺城市之光东座22楼E10"); + paramsMap.put("miniprogram", miniprogramMap); + paramsMap.put("data", dataMap); + //拼接请求地址并发送 + String messageUrl = Constants.OFFICIAL_ACCOUNT_TEMPLATE_SEND_URL + accessToken; + String param = JSON.toJSONString(paramsMap); + String result = HttpUtils.sendPostJson(messageUrl, param); + //返回参数映射 + AccessToken errCode = JSON.parseObject(result, AccessToken.class); + if (Objects.nonNull(errCode) && Objects.nonNull(errCode.getErrcode())) { + switch (errCode.getErrcode()) { + case Constants.SUCCESS_ERROR_CODE: + log.info("发送消息成功!"); + break; + case Constants.INVALID_CREDENTIAL_ACCESS_TOKEN_ISINVALID_OR_NOT_LATEST: + log.error("取 access_token 时 AppSecret 错误,或者 access_token 无效!"); + break; + case Constants.INVALID_OPENID: + log.error("不合法的 OpenId!"); + break; + case Constants.INVALID_ACCESS_TOKEN: + log.error("合法的 access_token!"); + break; + case Constants.INVALID_TEMPLATE_ID: + log.error("不合法的 template_id!"); + break; + case Constants.ARGUMENT_INVALID: + log.error("参数无效!"); + break; + case Constants.DENY_SUBSCRIPTION: + log.error("用户拒接订阅!"); + break; + default: + break; + } + } + } } diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatofficialaccountcallback/WeChatOfficialAccountEventPushVO.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatofficialaccountcallback/WeChatOfficialAccountEventPushVO.java new file mode 100644 index 00000000..b5930da6 --- /dev/null +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/vo/wechatofficialaccountcallback/WeChatOfficialAccountEventPushVO.java @@ -0,0 +1,60 @@ +package com.xinelu.mobile.vo.wechatofficialaccountcallback; + +import lombok.Data; +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +import java.io.Serializable; + +/** + * @Description 微信公众号模板消息事件推送实体类 + * @Author 纪寒 + * @Date 2024-03-25 13:36:17 + * @Version 1.0 + */ +@Root(name = "xml", strict = false) +@Data +public class WeChatOfficialAccountEventPushVO implements Serializable { + private static final long serialVersionUID = 4329284826265109369L; + /** + * 公众号微信号 + */ + @Element(name = "ToUserName", required = false) + private String toUserName; + + /** + * 接收模板消息的用户的openid + */ + @Element(name = "FromUserName", required = false) + private String fromUserName; + + /** + * 创建时间 + */ + @Element(name = "CreateTime", required = false) + private String createTime; + + /** + * 消息类型是事件 + */ + @Element(name = "MsgType", required = false) + private String msgType; + + /** + * 事件为模板消息发送结束 + */ + @Element(name = "Event", required = false) + private String event; + + /** + * 消息id + */ + @Element(name = "MsgID", required = false) + private String msgId; + + /** + * 发送状态为,成功:success,用户拒绝接收:failed:user block,发送失败(非用户拒绝):failed:system failed + */ + @Element(name = "Status", required = false) + private String status; +} From 0db3aeb14c4fef6a06b11b1789c6b33dcef2b6ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=AA=E5=AF=92?= <2533659732@qq.com> Date: Tue, 26 Mar 2024 14:18:34 +0800 Subject: [PATCH 09/21] =?UTF-8?q?=E6=82=A3=E8=80=85=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E8=A1=A8=E6=96=B0=E5=A2=9E=E5=85=AC=E4=BC=97=E5=8F=B7openid?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/patientinfo/PatientInfo.java | 202 +++- .../manage/patientinfo/PatientInfoMapper.xml | 1045 +++++++++-------- 2 files changed, 672 insertions(+), 575 deletions(-) diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/patientinfo/PatientInfo.java b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/patientinfo/PatientInfo.java index 163a4b43..c7873400 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/patientinfo/PatientInfo.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/patientinfo/PatientInfo.java @@ -5,14 +5,14 @@ import com.xinelu.common.annotation.Excel; import com.xinelu.common.core.domain.BaseEntity; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; - -import java.time.LocalDateTime; -import java.util.Date; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import java.time.LocalDateTime; +import java.util.Date; + /** * 患者信息对象 patient_info * @@ -26,199 +26,285 @@ import lombok.NoArgsConstructor; @ApiModel(value = "患者信息对象", description = "patient_info") public class PatientInfo extends BaseEntity { - private static final long serialVersionUID=1L; + private static final long serialVersionUID = 1L; - /** 主键id */ + /** + * 主键id + */ private Long id; - /** 患者姓名 */ + /** + * 患者姓名 + */ @ApiModelProperty(value = "患者姓名") @Excel(name = "患者姓名") private String patientName; - /** 患者电话 */ + /** + * 患者电话 + */ @ApiModelProperty(value = "患者电话") @Excel(name = "患者电话") private String patientPhone; - /** 家属电话 */ + /** + * 家属电话 + */ @ApiModelProperty(value = "家属电话") private String familyMemberPhone; - /** 出生日期,格式:yyyy-MM-dd */ + /** + * 出生日期,格式:yyyy-MM-dd + */ @ApiModelProperty(value = "出生日期,格式:yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd") private Date birthDate; - /** 身份证号 */ + /** + * 身份证号 + */ @ApiModelProperty(value = "身份证号") private String cardNo; - /** 性别,男:MALE,女:FEMALE */ + /** + * 性别,男:MALE,女:FEMALE + */ @ApiModelProperty(value = "性别,男:MALE,女:FEMALE") @Excel(name = "性别,男:MALE,女:FEMALE") private String sex; - /** 住址 */ + /** + * 住址 + */ @ApiModelProperty(value = "住址") @Excel(name = "住址") private String address; - /** 患者类型,预住院患者:PRE_HOSPITALIZED_PATIENT,在院患者:IN_HOSPITAL_PATIENT,门诊患者:OUTPATIENT,出院患者:DISCHARGED_PATIENT, -签约患者:CONTRACTED_PATIENT */ + /** + * 患者类型,预住院患者:PRE_HOSPITALIZED_PATIENT,在院患者:IN_HOSPITAL_PATIENT,门诊患者:OUTPATIENT,出院患者:DISCHARGED_PATIENT, + * 签约患者:CONTRACTED_PATIENT + */ @ApiModelProperty(value = "患者类型,预住院患者:PRE_HOSPITALIZED_PATIENT,在院患者:IN_HOSPITAL_PATIENT,门诊患者:OUTPATIENT,出院患者:DISCHARGED_PATIENT,签约患者:CONTRACTED_PATIENT") private String patientType; - /** - * 签约状态,未签约:UN_SIGN,在签:IN_SIGN,解约:SEPARATE_SIGN, 服务到期:EXPIRE_SIGN - */ - @ApiModelProperty(value = "签约状态,未签约:UN_SIGN,在签:IN_SIGN,解约:SEPARATE_SIGN, 过期:EXPIRE_SIGN") - private String signStatus; + /** + * 签约状态,未签约:UN_SIGN,在签:IN_SIGN,解约:SEPARATE_SIGN, 服务到期:EXPIRE_SIGN + */ + @ApiModelProperty(value = "签约状态,未签约:UN_SIGN,在签:IN_SIGN,解约:SEPARATE_SIGN, 过期:EXPIRE_SIGN") + private String signStatus; - @ApiModelProperty(value = "签约记录表id") - private Long signPatientRecordId; + @ApiModelProperty(value = "签约记录表id") + private Long signPatientRecordId; - /** - * 服务状态,意向签约:INTENTIONAL_SIGNING,服务中:SERVICE_CENTER,服务结束:SERVICE_END - */ - @ApiModelProperty(value = "服务状态,意向签约:INTENTIONAL_SIGNING,服务中:SERVICE_CENTER,服务结束:SERVICE_END") - private String serviceStatus; + /** + * 服务状态,意向签约:INTENTIONAL_SIGNING,服务中:SERVICE_CENTER,服务结束:SERVICE_END + */ + @ApiModelProperty(value = "服务状态,意向签约:INTENTIONAL_SIGNING,服务中:SERVICE_CENTER,服务结束:SERVICE_END") + private String serviceStatus; - /** 签约时间,格式:yyyy-MM-dd HH:mm:ss */ + /** + * 签约时间,格式:yyyy-MM-dd HH:mm:ss + */ @ApiModelProperty(value = "签约时间,格式:yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "签约时间,格式:yyyy-MM-dd HH:mm:ss", width = 30, dateFormat = "yyyy-MM-dd") private LocalDateTime signTime; - /** 开证医生(预住院患者) */ + /** + * 开证医生(预住院患者) + */ @ApiModelProperty(value = "开证医生") @Excel(name = "开证医生", readConverterExp = "预住院患者") private String certificateIssuingDoctor; - /** 就诊方式,门诊:OUTPATIENT_SERVICE,住院:BE_IN_HOSPITAL */ + /** + * 就诊方式,门诊:OUTPATIENT_SERVICE,住院:BE_IN_HOSPITAL + */ @ApiModelProperty(value = "就诊方式,门诊:OUTPATIENT_SERVICE,住院:BE_IN_HOSPITAL") @Excel(name = "就诊方式,门诊:OUTPATIENT_SERVICE,住院:BE_IN_HOSPITAL") private String visitMethod; - /** 主要诊断 */ + /** + * 主要诊断 + */ @ApiModelProperty(value = "主要诊断") private String mainDiagnosis; - /** 主治医生 */ + /** + * 主治医生 + */ @ApiModelProperty(value = "主治医生") @Excel(name = "主治医生") private String attendingPhysician; - /** 所属医院id */ + /** + * 所属医院id + */ @ApiModelProperty(value = "所属医院id") private Long hospitalAgencyId; - /** 所属医院名称 */ + /** + * 所属医院名称 + */ @ApiModelProperty(value = "所属医院名称") @Excel(name = "所属医院名称") private String hospitalAgencyName; - /** 所属院区id */ + /** + * 所属院区id + */ @ApiModelProperty(value = "所属院区id") private Long campusAgencyId; - /** 所属院区名称 */ + /** + * 所属院区名称 + */ @ApiModelProperty(value = "所属院区名称") @Excel(name = "所属院区名称") private String campusAgencyName; - /** 所属科室id */ + /** + * 所属科室id + */ @ApiModelProperty(value = "所属科室id") private Long departmentId; - /** 所属科室名称 */ + /** + * 所属科室名称 + */ @ApiModelProperty(value = "所属科室名称") @Excel(name = "所属科室名称") private String departmentName; - /** 所属病区id */ + /** + * 所属病区id + */ @ApiModelProperty(value = "所属病区id") private Long wardId; - /** 所属病区名称 */ + /** + * 所属病区名称 + */ @ApiModelProperty(value = "所属病区名称") @Excel(name = "所属病区名称") private String wardName; - /** 住院号 */ + /** + * 住院号 + */ @ApiModelProperty(value = "住院号") @Excel(name = "住院号") private String admissionNumber; - /** 责任护士 */ + /** + * 责任护士 + */ @ApiModelProperty(value = "责任护士") private String responsibleNurse; - /** 就诊流水号 */ + /** + * 就诊流水号 + */ @ApiModelProperty(value = "就诊流水号") private String visitSerialNumber; - /** 手术名称 */ + /** + * 手术名称 + */ @ApiModelProperty(value = "手术名称") private String surgicalName; - /** 入院时间,时间格式:yyyy-MM-dd */ + /** + * 入院时间,时间格式:yyyy-MM-dd + */ @ApiModelProperty(value = "入院时间") private Date admissionDate; - /** 出院时间(出院患者),时间格式:yyyy-MM-dd */ + /** + * 出院时间(出院患者),时间格式:yyyy-MM-dd + */ @ApiModelProperty(value = "出院时间(出院患者)") private Date dischargeDate; - /** 病历内容 */ + /** + * 病历内容 + */ @ApiModelProperty(value = "病历内容") private String medicalRecordContent; - /** 预约治疗组(取值以及枚举未知?) */ + /** + * 预约治疗组(取值以及枚举未知?) + */ @ApiModelProperty(value = "预约治疗组(取值以及枚举未知?)") private String appointmentTreatmentGroup; - /** 登记号(预住院患者) */ + /** + * 登记号(预住院患者) + */ @ApiModelProperty(value = "登记号(预住院患者)") private String registrationNo; - /** 登记日期(预住院患者),时间格式:yyyy-MM-dd */ + /** + * 登记日期(预住院患者),时间格式:yyyy-MM-dd + */ @ApiModelProperty(value = "登记日期(预住院患者),时间格式:yyyy-MM-dd") private Date registrationDate; - /** 预约时间(预住院患者),时间格式:yyyy-MM-dd */ + /** + * 预约时间(预住院患者),时间格式:yyyy-MM-dd + */ @ApiModelProperty(value = "预约时间(预住院患者),时间格式:yyyy-MM-dd") private Date appointmentDate; - /** 门诊号(门诊患者) */ + /** + * 门诊号(门诊患者) + */ @ApiModelProperty(value = "门诊号") @Excel(name = "门诊号", readConverterExp = "门=诊患者") private String outpatientNumber; - /** 就诊时间(门诊患者),时间格式:yyyy-MM-dd */ + /** + * 就诊时间(门诊患者),时间格式:yyyy-MM-dd + */ @ApiModelProperty(value = "就诊时间") @Excel(name = "就诊时间", readConverterExp = "门=诊患者") private Date visitTime; - /** 出院方式(出院患者) */ + /** + * 出院方式(出院患者) + */ @ApiModelProperty(value = "出院方式") @Excel(name = "出院方式", readConverterExp = "出=院患者") private String dischargeMethod; - /** 微信openid,微信小程序唯一标识 */ - @ApiModelProperty(value = "微信openid,微信小程序唯一标识") + /** + * 微信小程序openid,微信小程序唯一标识 + */ + @ApiModelProperty(value = "微信小程序openid,微信小程序唯一标识") private String openId; - /** 微信unionid,微信小程序和微信公众号统一标识 */ + /** + * 微信unionid,微信小程序和微信公众号统一标识 + */ @ApiModelProperty(value = "微信unionid,微信小程序和微信公众号统一标识 ") private String unionId; - /** 患者来源,微信小程序:WE_CHAT_APPLET,微信公众号:WE_CHAT_OFFICIAL_ACCOUNT,管理端:MANAGE_END */ + /** + * 微信公众号openid,微信众号唯一标识 + */ + @ApiModelProperty(value = "微信公众号openid,微信众号唯一标识 ") + private String officialAccountOpenId; + + /** + * 患者来源,微信小程序:WE_CHAT_APPLET,微信公众号:WE_CHAT_OFFICIAL_ACCOUNT,管理端:MANAGE_END + */ @ApiModelProperty(value = "患者来源,微信小程序:WE_CHAT_APPLET,微信公众号:WE_CHAT_OFFICIAL_ACCOUNT,管理端:MANAGE_END") @Excel(name = "患者来源,微信小程序:WE_CHAT_APPLET,微信公众号:WE_CHAT_OFFICIAL_ACCOUNT,管理端:MANAGE_END") private String patientSource; - /** 删除标识,0:未删除,1:已删除 */ + /** + * 删除标识,0:未删除,1:已删除 + */ private Integer delFlag; } diff --git a/postdischarge-manage/src/main/resources/mapper/manage/patientinfo/PatientInfoMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/patientinfo/PatientInfoMapper.xml index f7481789..dbce726c 100644 --- a/postdischarge-manage/src/main/resources/mapper/manage/patientinfo/PatientInfoMapper.xml +++ b/postdischarge-manage/src/main/resources/mapper/manage/patientinfo/PatientInfoMapper.xml @@ -1,59 +1,60 @@ + PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + select id, patient_name, patient_phone, @@ -70,482 +71,492 @@ admission_number, responsible_nurse, visit_serial_number, surgical_name, admission_date, discharge_date, medical_record_content, appointment_treatment_group, registration_no, registration_date, appointment_date, outpatient_number, visit_time, discharge_method, - open_id, union_id, patient_source, del_flag, create_by, create_time, update_by, update_time + open_id, union_id, official_account_openid, patient_source, del_flag, create_by, create_time, update_by, update_time from patient_info - + + + del_flag = 0 + + and patient_name = #{patientName} + + + and patient_phone like concat('%', #{patientPhone}, '%') + + + and card_no = #{cardNo} + + + + + and (patient_type = 'OUTPATIENT' or patient_type = 'DISCHARGED_PATIENT') + + + and patient_type = #{patientType} + + + + + and main_diagnosis like concat('%', #{mainDiagnosis}, '%') + + + and hospital_agency_id = #{hospitalAgencyId} + + + and campus_agency_id = #{campusAgencyId} + + + and department_id = #{departmentId} + + + and ward_id = #{wardId} + + + and attending_physician = #{attendingPhysician} + + + and visit_method = #{visitMethod} + - - and surgical_name like concat('%', #{surgicalName}, '%') - - - and visit_time >= #{visitTimeStart} - - - and visit_time <= #{visitTimeEnd} - - - and admission_date >= #{admissionDateStart} - - - and admission_date <= #{admissionDateEnd} - - - and appointment_date >= #{appointmentDateStart} - - - and appointment_date <= #{appointmentDateEnd} - - - and appointment_treatment_group = #{appointmentTreatmentGroup} - - - and certificate_issuing_doctor = #{certificateIssuingDoctor} - - - and registration_no = #{registrationNo} - - - and visit_serial_number = #{visitSerialNumber} - - - and responsible_nurse = #{responsibleNurse} - - - and patient_source = #{patientSource} - - - + + and surgical_name like concat('%', #{surgicalName}, '%') + + + and visit_time >= #{visitTimeStart} + + + and visit_time <= #{visitTimeEnd} + + + and admission_date >= #{admissionDateStart} + + + and admission_date <= #{admissionDateEnd} + + + and appointment_date >= #{appointmentDateStart} + + + and appointment_date <= #{appointmentDateEnd} + + + and appointment_treatment_group = #{appointmentTreatmentGroup} + + + and certificate_issuing_doctor = #{certificateIssuingDoctor} + + + and registration_no = #{registrationNo} + + + and visit_serial_number = #{visitSerialNumber} + + + and responsible_nurse = #{responsibleNurse} + + + and patient_source = #{patientSource} + + + - + - - insert into patient_info - - - patient_name, - - patient_phone, - - family_member_phone, - - birth_date, - - card_no, - - sex, - - address, - - patient_type, - - sign_status, - - sign_patient_record_id, - - service_status, - - sign_time, - - certificate_issuing_doctor, - - visit_method, - - main_diagnosis, - - attending_physician, - - hospital_agency_id, - - hospital_agency_name, - - campus_agency_id, - - campus_agency_name, - - department_id, - - department_name, - - ward_id, - - ward_name, - - - admission_number, - - - responsible_nurse, - - - visit_serial_number, - - - surgical_name, - - - admission_date, - - - discharge_date, - - medical_record_content, - - appointment_treatment_group, - - registration_no, - - registration_date, - - appointment_date, - - outpatient_number, - - visit_time, - - discharge_method, - - open_id, - - union_id, - - patient_source, - - del_flag, - - create_by, - - create_time, - - update_by, - - update_time, - - - - #{patientName}, - - #{patientPhone}, - - #{familyMemberPhone}, - - #{birthDate}, - - #{cardNo}, - - #{sex}, - - #{address}, - - #{patientType}, - - #{signStatus}, - - #{signPatientRecordId}, - - #{serviceStatus}, - - #{signTime}, - - #{certificateIssuingDoctor}, - - #{visitMethod}, - - #{mainDiagnosis}, - - #{attendingPhysician}, - - #{hospitalAgencyId}, - - #{hospitalAgencyName}, - - #{campusAgencyId}, - - #{campusAgencyName}, - - #{departmentId}, - - #{departmentName}, - - #{wardId}, - - #{wardName}, - - #{admissionNumber}, - - #{responsibleNurse}, - - #{visitSerialNumber}, - - #{surgicalName}, - - #{admissionDate}, - - #{dischargeDate}, - - #{medicalRecordContent}, - - #{appointmentTreatmentGroup}, - - #{registrationNo}, - - #{registrationDate}, - - #{appointmentDate}, - - #{outpatientNumber}, - - #{visitTime}, - - #{dischargeMethod}, - - #{openId}, - - #{unionId}, - - #{patientSource}, - - #{delFlag}, - - #{createBy}, - - #{createTime}, - - #{updateBy}, - - #{updateTime}, - - - + + insert into patient_info + + + patient_name, + + patient_phone, + + family_member_phone, + + birth_date, + + card_no, + + sex, + + address, + + patient_type, + + sign_status, + + sign_patient_record_id, + + service_status, + + sign_time, + + certificate_issuing_doctor, + + visit_method, + + main_diagnosis, + + attending_physician, + + hospital_agency_id, + + hospital_agency_name, + + campus_agency_id, + + campus_agency_name, + + department_id, + + department_name, + + ward_id, + + ward_name, + + + admission_number, + + + responsible_nurse, + + + visit_serial_number, + + + surgical_name, + + + admission_date, + + + discharge_date, + + medical_record_content, + + appointment_treatment_group, + + registration_no, + + registration_date, + + appointment_date, + + outpatient_number, + + visit_time, + + discharge_method, + + open_id, + + union_id, + + official_account_openid, + + patient_source, + + del_flag, + + create_by, + + create_time, + + update_by, + + update_time, + + + + #{patientName}, + + #{patientPhone}, + + #{familyMemberPhone}, + + #{birthDate}, + + #{cardNo}, + + #{sex}, + + #{address}, + + #{patientType}, + + #{signStatus}, + + #{signPatientRecordId}, + + #{serviceStatus}, + + #{signTime}, + + #{certificateIssuingDoctor}, + + #{visitMethod}, + + #{mainDiagnosis}, + + #{attendingPhysician}, + + #{hospitalAgencyId}, + + #{hospitalAgencyName}, + + #{campusAgencyId}, + + #{campusAgencyName}, + + #{departmentId}, + + #{departmentName}, + + #{wardId}, + + #{wardName}, + + #{admissionNumber}, + + #{responsibleNurse}, + + #{visitSerialNumber}, + + #{surgicalName}, + + #{admissionDate}, + + #{dischargeDate}, + + #{medicalRecordContent}, + + #{appointmentTreatmentGroup}, + + #{registrationNo}, + + #{registrationDate}, + + #{appointmentDate}, + + #{outpatientNumber}, + + #{visitTime}, + + #{dischargeMethod}, + + #{openId}, + + #{unionId}, + + #{officialAccountOpenId}, + + #{patientSource}, + + #{delFlag}, + + #{createBy}, + + #{createTime}, + + #{updateBy}, + + #{updateTime}, + + + - - update patient_info - - - patient_name = #{patientName}, - - - patient_phone = #{patientPhone}, - - - family_member_phone = #{familyMemberPhone}, - - - birth_date = #{birthDate}, - - - card_no = #{cardNo}, - - - sex = #{sex}, - - - address = #{address}, - - - patient_type = #{patientType}, - - sign_status = - #{signStatus}, - - sign_patient_record_id = #{signPatientRecordId}, - - service_status = #{serviceStatus}, - - sign_time = - #{signTime}, - - certificate_issuing_doctor = - #{certificateIssuingDoctor}, - - visit_method = - #{visitMethod}, - - main_diagnosis = - #{mainDiagnosis}, - - attending_physician = - #{attendingPhysician}, - - hospital_agency_id = - #{hospitalAgencyId}, - - hospital_agency_name = - #{hospitalAgencyName}, - - campus_agency_id = - #{campusAgencyId}, - - campus_agency_name = - #{campusAgencyName}, - - department_id = - #{departmentId}, - - department_name = - #{departmentName}, - - ward_id = - #{wardId}, - - ward_name = - #{wardName}, - - admission_number = - #{admissionNumber}, - - responsible_nurse = - #{responsibleNurse}, - - visit_serial_number = - #{visitSerialNumber}, - - surgical_name = - #{surgicalName}, - - - admission_date = #{admissionDate}, - - - discharge_date = #{dischargeDate}, - - medical_record_content = - #{medicalRecordContent}, - - appointment_treatment_group = - #{appointmentTreatmentGroup}, - - registration_no = - #{registrationNo}, - - registration_date = - #{registrationDate}, - - appointment_date = - #{appointmentDate}, - - outpatient_number = - #{outpatientNumber}, - - visit_time = - #{visitTime}, - - discharge_method = - #{dischargeMethod}, - - open_id = - #{openId}, - - union_id = - #{unionId}, - - patient_source = - #{patientSource}, - - del_flag = - #{delFlag}, - - create_by = - #{createBy}, - - create_time = - #{createTime}, - - update_by = - #{updateBy}, - - update_time = - #{updateTime}, - - - where id = #{id} - + + update patient_info + + + patient_name = #{patientName}, + + + patient_phone = #{patientPhone}, + + + family_member_phone = #{familyMemberPhone}, + + + birth_date = #{birthDate}, + + + card_no = #{cardNo}, + + + sex = #{sex}, + + + address = #{address}, + + + patient_type = #{patientType}, + + sign_status = + #{signStatus}, + + sign_patient_record_id = #{signPatientRecordId}, + + service_status = #{serviceStatus}, + + sign_time = + #{signTime}, + + certificate_issuing_doctor = + #{certificateIssuingDoctor}, + + visit_method = + #{visitMethod}, + + main_diagnosis = + #{mainDiagnosis}, + + attending_physician = + #{attendingPhysician}, + + hospital_agency_id = + #{hospitalAgencyId}, + + hospital_agency_name = + #{hospitalAgencyName}, + + campus_agency_id = + #{campusAgencyId}, + + campus_agency_name = + #{campusAgencyName}, + + department_id = + #{departmentId}, + + department_name = + #{departmentName}, + + ward_id = + #{wardId}, + + ward_name = + #{wardName}, + + admission_number = + #{admissionNumber}, + + responsible_nurse = + #{responsibleNurse}, + + visit_serial_number = + #{visitSerialNumber}, + + surgical_name = + #{surgicalName}, + + + admission_date = #{admissionDate}, + + + discharge_date = #{dischargeDate}, + + medical_record_content = + #{medicalRecordContent}, + + appointment_treatment_group = + #{appointmentTreatmentGroup}, + + registration_no = + #{registrationNo}, + + registration_date = + #{registrationDate}, + + appointment_date = + #{appointmentDate}, + + outpatient_number = + #{outpatientNumber}, + + visit_time = + #{visitTime}, + + discharge_method = + #{dischargeMethod}, + + open_id = + #{openId}, + + union_id = + #{unionId}, + + official_account_openid = + #{officialAccountOpenId}, + + patient_source = + #{patientSource}, + + del_flag = + #{delFlag}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + + where id = #{id} + - + update patient_info set del_flag = 1 where id = #{id} - - update patient_info set del_flag = 1 where id in - - #{id} - - + + update patient_info set del_flag = 1 where id in + + #{id} + + - + \ No newline at end of file From b5b09e26778acac158a9c179aa3e5ced443407ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=AA=E5=AF=92?= <2533659732@qq.com> Date: Tue, 26 Mar 2024 17:20:43 +0800 Subject: [PATCH 10/21] =?UTF-8?q?=E5=85=AC=E4=BC=97=E5=8F=B7=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E6=B6=88=E6=81=AF=E5=BC=80=E5=8F=91=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/entity/MessageValueEntity.java | 21 ++ .../enums/OfficialAccountEventEnum.java | 34 ++++ .../enums/TemplateEventSendStatusEnum.java | 34 ---- .../OfficialAccountSubscribeEvent.java | 94 +++++++++ .../OfficialAccountTemplateEvent.java | 2 +- .../OfficialAccountSubscribeEventMapper.java | 77 +++++++ ...IOfficialAccountSubscribeEventService.java | 61 ++++++ ...icialAccountSubscribeEventServiceImpl.java | 91 +++++++++ .../OfficialAccountSubscribeEventMapper.xml | 191 ++++++++++++++++++ ...ChatOfficialAccountCallbackController.java | 11 +- .../WeChatOfficialAccountCallbackService.java | 7 + ...hatOfficialAccountCallbackServiceImpl.java | 68 +++++++ .../utils/WeChatOfficialAccountUtils.java | 13 +- 13 files changed, 662 insertions(+), 42 deletions(-) create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/entity/MessageValueEntity.java create mode 100644 postdischarge-common/src/main/java/com/xinelu/common/enums/OfficialAccountEventEnum.java delete mode 100644 postdischarge-common/src/main/java/com/xinelu/common/enums/TemplateEventSendStatusEnum.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/domain/officialaccountsubscribeevent/OfficialAccountSubscribeEvent.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/mapper/officialaccountsubscribeevent/OfficialAccountSubscribeEventMapper.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccountsubscribeevent/IOfficialAccountSubscribeEventService.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccountsubscribeevent/impl/OfficialAccountSubscribeEventServiceImpl.java create mode 100644 postdischarge-manage/src/main/resources/mapper/manage/officialaccountsubscribeevent/OfficialAccountSubscribeEventMapper.xml diff --git a/postdischarge-common/src/main/java/com/xinelu/common/entity/MessageValueEntity.java b/postdischarge-common/src/main/java/com/xinelu/common/entity/MessageValueEntity.java new file mode 100644 index 00000000..6f3d8f24 --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/entity/MessageValueEntity.java @@ -0,0 +1,21 @@ +package com.xinelu.common.entity; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @Description 消息推送信息实体类 + * @Author 纪寒 + * @Date 2024-03-26 17:09:50 + */ +@Data +public class MessageValueEntity implements Serializable { + private static final long serialVersionUID = -1257378392221120423L; + + private String value; + + public MessageValueEntity(String value) { + this.value = value; + } +} diff --git a/postdischarge-common/src/main/java/com/xinelu/common/enums/OfficialAccountEventEnum.java b/postdischarge-common/src/main/java/com/xinelu/common/enums/OfficialAccountEventEnum.java new file mode 100644 index 00000000..88c827dd --- /dev/null +++ b/postdischarge-common/src/main/java/com/xinelu/common/enums/OfficialAccountEventEnum.java @@ -0,0 +1,34 @@ +package com.xinelu.common.enums; + +import lombok.Getter; + +/** + * @Description 微信公众号事件枚举 + * @Author 纪寒 + * @Date 2024-03-25 14:38:27 + * @Version 1.0 + */ +@Getter +public enum OfficialAccountEventEnum { + /** + * 模板消息推送事件 + */ + TEMPLATESENDJOBFINISH("TEMPLATESENDJOBFINISH"), + + /** + * 关系公众号事件 + */ + SUBSCRIBE("subscribe"), + + /** + * 取关公众号事件 + */ + UNSUBSCRIBE("unsubscribe"), + ; + + final private String info; + + OfficialAccountEventEnum(String info) { + this.info = info; + } +} diff --git a/postdischarge-common/src/main/java/com/xinelu/common/enums/TemplateEventSendStatusEnum.java b/postdischarge-common/src/main/java/com/xinelu/common/enums/TemplateEventSendStatusEnum.java deleted file mode 100644 index 8d45922a..00000000 --- a/postdischarge-common/src/main/java/com/xinelu/common/enums/TemplateEventSendStatusEnum.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.xinelu.common.enums; - -import lombok.Getter; - -/** - * @Description 微信公众号模板事件消息发送状态枚举 - * @Author 纪寒 - * @Date 2024-03-25 14:38:27 - * @Version 1.0 - */ -@Getter -public enum TemplateEventSendStatusEnum { - /** - * 成功 - */ - SUCCESS("success"), - - /** - * 用户拒绝接收 - */ - REJECT("failed:user block"), - - /** - * 发送失败 - */ - FAILED("failed:system failed"), - ; - - final private String info; - - TemplateEventSendStatusEnum(String info) { - this.info = info; - } -} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/officialaccountsubscribeevent/OfficialAccountSubscribeEvent.java b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/officialaccountsubscribeevent/OfficialAccountSubscribeEvent.java new file mode 100644 index 00000000..7096dbf2 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/officialaccountsubscribeevent/OfficialAccountSubscribeEvent.java @@ -0,0 +1,94 @@ +package com.xinelu.manage.domain.officialaccountsubscribeevent; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.xinelu.common.annotation.Excel; +import com.xinelu.common.core.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.time.LocalDateTime; + +/** + * 微信公众号关注和取消事件信息对象 official_account_subscribe_event + * + * @author xinelu + * @date 2024-03-26 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +@ApiModel(value = "微信公众号关注和取消事件信息对象", description = "official_account_subscribe_event") +public class OfficialAccountSubscribeEvent extends BaseEntity { + private static final long serialVersionUID = 4235213866159646854L; + /** + * 主键id + */ + private Long id; + + /** + * 微信公众号openid + */ + @ApiModelProperty(value = "微信公众号openid") + @Excel(name = "微信公众号openid") + private String openid; + + /** + * 微信公众号id + */ + @ApiModelProperty(value = "微信公众号id") + @Excel(name = "微信公众号id") + private String officialAccountAppId; + + /** + * 消息创建时间 ,yyyy-MM-dd HH:mm:ss + */ + @ApiModelProperty(value = "消息创建时间 ,yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "消息创建时间 ,yyyy-MM-dd HH:mm:ss", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime sendTime; + + /** + * 消息类型是事件,固定取值为:event + */ + @ApiModelProperty(value = "消息类型是事件,固定取值为:event") + @Excel(name = "消息类型是事件,固定取值为:event") + private String msgType; + + /** + * 事件类型,订阅:subscribe,取消订阅:unsubscribe + */ + @ApiModelProperty(value = "事件类型,订阅:subscribe,取消订阅:unsubscribe") + @Excel(name = "事件类型,订阅:subscribe,取消订阅:unsubscribe") + private String eventType; + + /** + * 订阅状态,关注:FOCUS,取消:CANCEL + */ + @ApiModelProperty(value = "订阅状态,关注:FOCUS,取消:CANCEL") + @Excel(name = "订阅状态,关注:FOCUS,取消:CANCEL") + private String subscribeStatus; + + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("openid", getOpenid()) + .append("officialAccountAppId", getOfficialAccountAppId()) + .append("sendTime", getSendTime()) + .append("msgType", getMsgType()) + .append("eventType", getEventType()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/officialaccounttemplateevent/OfficialAccountTemplateEvent.java b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/officialaccounttemplateevent/OfficialAccountTemplateEvent.java index 0b1d7bd6..44d8c73f 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/officialaccounttemplateevent/OfficialAccountTemplateEvent.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/officialaccounttemplateevent/OfficialAccountTemplateEvent.java @@ -47,7 +47,7 @@ public class OfficialAccountTemplateEvent extends BaseEntity { private String patientName; /** - * 微信用户openid + * 微信公众号openid */ @ApiModelProperty(value = "微信用户openid") @Excel(name = "微信用户openid") diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/officialaccountsubscribeevent/OfficialAccountSubscribeEventMapper.java b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/officialaccountsubscribeevent/OfficialAccountSubscribeEventMapper.java new file mode 100644 index 00000000..ede879d7 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/officialaccountsubscribeevent/OfficialAccountSubscribeEventMapper.java @@ -0,0 +1,77 @@ +package com.xinelu.manage.mapper.officialaccountsubscribeevent; + +import com.xinelu.manage.domain.officialaccountsubscribeevent.OfficialAccountSubscribeEvent; + +import java.util.List; + +/** + * 微信公众号关注和取消事件信息Mapper接口 + * + * @author xinelu + * @date 2024-03-26 + */ +public interface OfficialAccountSubscribeEventMapper { + /** + * 查询微信公众号关注和取消事件信息 + * + * @param id 微信公众号关注和取消事件信息主键 + * @return 微信公众号关注和取消事件信息 + */ + OfficialAccountSubscribeEvent selectOfficialAccountSubscribeEventById(Long id); + + /** + * 查询微信公众号关注和取消事件信息列表 + * + * @param officialAccountSubscribeEvent 微信公众号关注和取消事件信息 + * @return 微信公众号关注和取消事件信息集合 + */ + List selectOfficialAccountSubscribeEventList(OfficialAccountSubscribeEvent officialAccountSubscribeEvent); + + /** + * 新增微信公众号关注和取消事件信息 + * + * @param officialAccountSubscribeEvent 微信公众号关注和取消事件信息 + * @return 结果 + */ + int insertOfficialAccountSubscribeEvent(OfficialAccountSubscribeEvent officialAccountSubscribeEvent); + + /** + * 修改微信公众号关注和取消事件信息 + * + * @param officialAccountSubscribeEvent 微信公众号关注和取消事件信息 + * @return 结果 + */ + int updateOfficialAccountSubscribeEvent(OfficialAccountSubscribeEvent officialAccountSubscribeEvent); + + /** + * 删除微信公众号关注和取消事件信息 + * + * @param id 微信公众号关注和取消事件信息主键 + * @return 结果 + */ + int deleteOfficialAccountSubscribeEventById(Long id); + + /** + * 批量删除微信公众号关注和取消事件信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteOfficialAccountSubscribeEventByIds(Long[] ids); + + /** + * 根据openid查询用户是否订阅公众号 + * + * @param openId 公众号openID + * @return 结果 + */ + int getSubscribeEventInfo(String openId); + + /** + * 根据openid修改订阅信息 + * + * @param officialAccountSubscribeEvent 微信公众号关注和取消事件信息 + * @return 结果 + */ + int updateSubscribeEventInfo(OfficialAccountSubscribeEvent officialAccountSubscribeEvent); +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccountsubscribeevent/IOfficialAccountSubscribeEventService.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccountsubscribeevent/IOfficialAccountSubscribeEventService.java new file mode 100644 index 00000000..2e855f12 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccountsubscribeevent/IOfficialAccountSubscribeEventService.java @@ -0,0 +1,61 @@ +package com.xinelu.manage.service.officialaccountsubscribeevent; + +import com.xinelu.manage.domain.officialaccountsubscribeevent.OfficialAccountSubscribeEvent; + +import java.util.List; + +/** + * 微信公众号关注和取消事件信息Service接口 + * + * @author xinelu + * @date 2024-03-26 + */ +public interface IOfficialAccountSubscribeEventService { + /** + * 查询微信公众号关注和取消事件信息 + * + * @param id 微信公众号关注和取消事件信息主键 + * @return 微信公众号关注和取消事件信息 + */ + OfficialAccountSubscribeEvent selectOfficialAccountSubscribeEventById(Long id); + + /** + * 查询微信公众号关注和取消事件信息列表 + * + * @param officialAccountSubscribeEvent 微信公众号关注和取消事件信息 + * @return 微信公众号关注和取消事件信息集合 + */ + List selectOfficialAccountSubscribeEventList(OfficialAccountSubscribeEvent officialAccountSubscribeEvent); + + /** + * 新增微信公众号关注和取消事件信息 + * + * @param officialAccountSubscribeEvent 微信公众号关注和取消事件信息 + * @return 结果 + */ + int insertOfficialAccountSubscribeEvent(OfficialAccountSubscribeEvent officialAccountSubscribeEvent); + + /** + * 修改微信公众号关注和取消事件信息 + * + * @param officialAccountSubscribeEvent 微信公众号关注和取消事件信息 + * @return 结果 + */ + int updateOfficialAccountSubscribeEvent(OfficialAccountSubscribeEvent officialAccountSubscribeEvent); + + /** + * 批量删除微信公众号关注和取消事件信息 + * + * @param ids 需要删除的微信公众号关注和取消事件信息主键集合 + * @return 结果 + */ + int deleteOfficialAccountSubscribeEventByIds(Long[] ids); + + /** + * 删除微信公众号关注和取消事件信息信息 + * + * @param id 微信公众号关注和取消事件信息主键 + * @return 结果 + */ + int deleteOfficialAccountSubscribeEventById(Long id); +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccountsubscribeevent/impl/OfficialAccountSubscribeEventServiceImpl.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccountsubscribeevent/impl/OfficialAccountSubscribeEventServiceImpl.java new file mode 100644 index 00000000..ec306baf --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/officialaccountsubscribeevent/impl/OfficialAccountSubscribeEventServiceImpl.java @@ -0,0 +1,91 @@ +package com.xinelu.manage.service.officialaccountsubscribeevent.impl; + + +import com.xinelu.manage.domain.officialaccountsubscribeevent.OfficialAccountSubscribeEvent; +import com.xinelu.manage.mapper.officialaccountsubscribeevent.OfficialAccountSubscribeEventMapper; +import com.xinelu.manage.service.officialaccountsubscribeevent.IOfficialAccountSubscribeEventService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 微信公众号关注和取消事件信息Service业务层处理 + * + * @author xinelu + * @date 2024-03-26 + */ +@Service +public class OfficialAccountSubscribeEventServiceImpl implements IOfficialAccountSubscribeEventService { + @Resource + private OfficialAccountSubscribeEventMapper officialAccountSubscribeEventMapper; + + /** + * 查询微信公众号关注和取消事件信息 + * + * @param id 微信公众号关注和取消事件信息主键 + * @return 微信公众号关注和取消事件信息 + */ + @Override + public OfficialAccountSubscribeEvent selectOfficialAccountSubscribeEventById(Long id) { + return officialAccountSubscribeEventMapper.selectOfficialAccountSubscribeEventById(id); + } + + /** + * 查询微信公众号关注和取消事件信息列表 + * + * @param officialAccountSubscribeEvent 微信公众号关注和取消事件信息 + * @return 微信公众号关注和取消事件信息 + */ + @Override + public List selectOfficialAccountSubscribeEventList(OfficialAccountSubscribeEvent officialAccountSubscribeEvent) { + return officialAccountSubscribeEventMapper.selectOfficialAccountSubscribeEventList(officialAccountSubscribeEvent); + } + + /** + * 新增微信公众号关注和取消事件信息 + * + * @param officialAccountSubscribeEvent 微信公众号关注和取消事件信息 + * @return 结果 + */ + @Override + public int insertOfficialAccountSubscribeEvent(OfficialAccountSubscribeEvent officialAccountSubscribeEvent) { + officialAccountSubscribeEvent.setCreateTime(LocalDateTime.now()); + return officialAccountSubscribeEventMapper.insertOfficialAccountSubscribeEvent(officialAccountSubscribeEvent); + } + + /** + * 修改微信公众号关注和取消事件信息 + * + * @param officialAccountSubscribeEvent 微信公众号关注和取消事件信息 + * @return 结果 + */ + @Override + public int updateOfficialAccountSubscribeEvent(OfficialAccountSubscribeEvent officialAccountSubscribeEvent) { + officialAccountSubscribeEvent.setUpdateTime(LocalDateTime.now()); + return officialAccountSubscribeEventMapper.updateOfficialAccountSubscribeEvent(officialAccountSubscribeEvent); + } + + /** + * 批量删除微信公众号关注和取消事件信息 + * + * @param ids 需要删除的微信公众号关注和取消事件信息主键 + * @return 结果 + */ + @Override + public int deleteOfficialAccountSubscribeEventByIds(Long[] ids) { + return officialAccountSubscribeEventMapper.deleteOfficialAccountSubscribeEventByIds(ids); + } + + /** + * 删除微信公众号关注和取消事件信息信息 + * + * @param id 微信公众号关注和取消事件信息主键 + * @return 结果 + */ + @Override + public int deleteOfficialAccountSubscribeEventById(Long id) { + return officialAccountSubscribeEventMapper.deleteOfficialAccountSubscribeEventById(id); + } +} diff --git a/postdischarge-manage/src/main/resources/mapper/manage/officialaccountsubscribeevent/OfficialAccountSubscribeEventMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/officialaccountsubscribeevent/OfficialAccountSubscribeEventMapper.xml new file mode 100644 index 00000000..f4628ed3 --- /dev/null +++ b/postdischarge-manage/src/main/resources/mapper/manage/officialaccountsubscribeevent/OfficialAccountSubscribeEventMapper.xml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + select id, openid, official_account_app_id, send_time, msg_type, event_type, subscribe_status, create_by, create_time, update_by, update_time from official_account_subscribe_event + + + + + + + + insert into official_account_subscribe_event + + openid, + + official_account_app_id, + + send_time, + + msg_type, + + event_type, + + subscribe_status, + + create_by, + + create_time, + + update_by, + + update_time, + + + + #{openid}, + + #{officialAccountAppId}, + + #{sendTime}, + + #{msgType}, + + #{eventType}, + + #{subscribeStatus}, + + #{createBy}, + + #{createTime}, + + #{updateBy}, + + #{updateTime}, + + + + + + update official_account_subscribe_event + + openid = + #{openid}, + + official_account_app_id = + #{officialAccountAppId}, + + send_time = + #{sendTime}, + + msg_type = + #{msgType}, + + event_type = + #{eventType}, + + subscribe_status = + #{subscribeStatus}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + + where id = #{id} + + + + delete from official_account_subscribe_event where id = #{id} + + + + delete from official_account_subscribe_event where id in + + #{id} + + + + + + + update official_account_subscribe_event + + openid = + #{openid}, + + official_account_app_id = + #{officialAccountAppId}, + + send_time = + #{sendTime}, + + msg_type = + #{msgType}, + + event_type = + #{eventType}, + + subscribe_status = + #{subscribeStatus}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + + where openid = #{openid} + + \ No newline at end of file diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatofficialaccountcallback/WeChatOfficialAccountCallbackController.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatofficialaccountcallback/WeChatOfficialAccountCallbackController.java index 225dfdf6..18ad196a 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatofficialaccountcallback/WeChatOfficialAccountCallbackController.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/controller/wechatofficialaccountcallback/WeChatOfficialAccountCallbackController.java @@ -1,6 +1,7 @@ package com.xinelu.mobile.controller.wechatofficialaccountcallback; import com.xinelu.common.config.WeChatOfficialAccountConfig; +import com.xinelu.common.enums.OfficialAccountEventEnum; import com.xinelu.common.utils.aes.AesException; import com.xinelu.common.utils.aes.WXBizMsgCrypt; import com.xinelu.mobile.dto.wechatappletcallback.MessageSignDTO; @@ -71,7 +72,15 @@ public class WeChatOfficialAccountCallbackController { log.info("院后微信公众号模板消息事件解析事件数据为空!"); return; } - weChatOfficialAccountCallbackService.handleOfficialAccountTemplateEvent(eventPush); + //微信模板公众号消息事件 + if (OfficialAccountEventEnum.TEMPLATESENDJOBFINISH.getInfo().equals(eventPush.getEvent())) { + weChatOfficialAccountCallbackService.handleOfficialAccountTemplateEvent(eventPush); + } + //微信公众号关注和取消事件 + if (OfficialAccountEventEnum.SUBSCRIBE.getInfo().equals(eventPush.getEvent()) || + OfficialAccountEventEnum.UNSUBSCRIBE.getInfo().equals(eventPush.getEvent())) { + weChatOfficialAccountCallbackService.handleOfficialAccountSubscribeEvent(eventPush); + } } } diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/WeChatOfficialAccountCallbackService.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/WeChatOfficialAccountCallbackService.java index 27e4c650..72ced160 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/WeChatOfficialAccountCallbackService.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/WeChatOfficialAccountCallbackService.java @@ -15,4 +15,11 @@ public interface WeChatOfficialAccountCallbackService { * @param eventPushVO 模板消息事件回调数据 */ void handleOfficialAccountTemplateEvent(WeChatOfficialAccountEventPushVO eventPushVO); + + /** + * 院后微信公众号取消和关注事件回调处理 + * + * @param eventPushVO 公众号取消和关注事件回调数据 + */ + void handleOfficialAccountSubscribeEvent(WeChatOfficialAccountEventPushVO eventPushVO); } diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/impl/WeChatOfficialAccountCallbackServiceImpl.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/impl/WeChatOfficialAccountCallbackServiceImpl.java index 0f68d8af..454c8b63 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/impl/WeChatOfficialAccountCallbackServiceImpl.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/service/wechatofficialaccountcallback/impl/WeChatOfficialAccountCallbackServiceImpl.java @@ -1,9 +1,13 @@ package com.xinelu.mobile.service.wechatofficialaccountcallback.impl; +import com.xinelu.common.enums.OfficialAccountEventEnum; +import com.xinelu.common.enums.SubscribeStatusEnum; import com.xinelu.common.exception.ServiceException; import com.xinelu.common.utils.DateUtils; +import com.xinelu.manage.domain.officialaccountsubscribeevent.OfficialAccountSubscribeEvent; import com.xinelu.manage.domain.officialaccounttemplateevent.OfficialAccountTemplateEvent; import com.xinelu.manage.domain.patientinfo.PatientInfo; +import com.xinelu.manage.mapper.officialaccountsubscribeevent.OfficialAccountSubscribeEventMapper; import com.xinelu.manage.mapper.officialaccounttemplateevent.OfficialAccountTemplateEventMapper; import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper; import com.xinelu.mobile.service.wechatofficialaccountcallback.WeChatOfficialAccountCallbackService; @@ -14,6 +18,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; +import java.time.LocalDateTime; import java.util.Objects; /** @@ -30,6 +35,8 @@ public class WeChatOfficialAccountCallbackServiceImpl implements WeChatOfficialA private PatientInfoMapper patientInfoMapper; @Resource private OfficialAccountTemplateEventMapper officialAccountTemplateEventMapper; + @Resource + private OfficialAccountSubscribeEventMapper officialAccountSubscribeEventMapper; /** * 院后微信公众号模板消息事件回调处理 @@ -55,6 +62,8 @@ public class WeChatOfficialAccountCallbackServiceImpl implements WeChatOfficialA templateEvent.setEventType(StringUtils.isBlank(eventPushVO.getEvent()) ? "" : eventPushVO.getEvent()); templateEvent.setMsgId(StringUtils.isBlank(eventPushVO.getMsgId()) ? "" : eventPushVO.getMsgId()); templateEvent.setStatus(StringUtils.isBlank(eventPushVO.getStatus()) ? "" : eventPushVO.getStatus()); + templateEvent.setCreateTime(LocalDateTime.now()); + templateEvent.setCreateBy("xinyilu"); int insertTemplateEventCount = officialAccountTemplateEventMapper.insertOfficialAccountTemplateEvent(templateEvent); if (insertTemplateEventCount < 0) { log.error("院后微信公众号模板事件推送,新增模板事件消息信息失败,信息为:[{}]", templateEvent); @@ -62,4 +71,63 @@ public class WeChatOfficialAccountCallbackServiceImpl implements WeChatOfficialA } log.info("院后微信公众号模板事件推送处理成功!"); } + + /** + * 院后微信公众号取消和关注事件回调处理 + * + * @param eventPushVO 公众号取消和关注事件回调数据 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public void handleOfficialAccountSubscribeEvent(WeChatOfficialAccountEventPushVO eventPushVO) { + //关注公众号事件 + if (OfficialAccountEventEnum.SUBSCRIBE.getInfo().equals(eventPushVO.getEvent())) { + handleSubscribeEventInfo(eventPushVO, SubscribeStatusEnum.accept.getValue()); + } + //取消关注公众号事件 + if (OfficialAccountEventEnum.UNSUBSCRIBE.getInfo().equals(eventPushVO.getEvent())) { + handleSubscribeEventInfo(eventPushVO, SubscribeStatusEnum.rejet.getValue()); + } + } + + /** + * 处理公众号订阅信息 + * + * @param eventPushVO 公众号取消和关注事件回调数据 + * @param subscribeStatus 订阅状态 + */ + private void handleSubscribeEventInfo(WeChatOfficialAccountEventPushVO eventPushVO, String subscribeStatus) { + int subscribeEventCount = officialAccountSubscribeEventMapper.getSubscribeEventInfo(eventPushVO.getFromUserName()); + if (subscribeEventCount == 0) { + //没有订阅过,直接新增 + OfficialAccountSubscribeEvent subscribeEvent = new OfficialAccountSubscribeEvent(); + subscribeEvent.setOpenid(eventPushVO.getFromUserName()); + subscribeEvent.setOfficialAccountAppId(StringUtils.isBlank(eventPushVO.getToUserName()) ? "" : eventPushVO.getToUserName()); + subscribeEvent.setSendTime(StringUtils.isBlank(eventPushVO.getCreateTime()) ? null : DateUtils.timestampToLocalDateTime(Long.parseLong(eventPushVO.getCreateTime()) * 1000L)); + subscribeEvent.setMsgType(StringUtils.isBlank(eventPushVO.getMsgType()) ? "" : eventPushVO.getMsgType()); + subscribeEvent.setEventType(StringUtils.isBlank(eventPushVO.getEvent()) ? "" : eventPushVO.getEvent()); + subscribeEvent.setSubscribeStatus(subscribeStatus); + subscribeEvent.setCreateTime(LocalDateTime.now()); + subscribeEvent.setCreateBy("xinyilu"); + int insertSubscribeEvent = officialAccountSubscribeEventMapper.insertOfficialAccountSubscribeEvent(subscribeEvent); + if (insertSubscribeEvent < 0) { + log.error("院后微信公众号关注和取消事件,新增信息失败,信息为:[{}]", subscribeEvent); + throw new ServiceException("新增院后微信公众号关注和取消事件信息失败!"); + } + } else { + //订阅过,修改 + OfficialAccountSubscribeEvent subscribeEvent = new OfficialAccountSubscribeEvent(); + subscribeEvent.setOpenid(eventPushVO.getFromUserName()); + subscribeEvent.setSendTime(StringUtils.isBlank(eventPushVO.getCreateTime()) ? null : DateUtils.timestampToLocalDateTime(Long.parseLong(eventPushVO.getCreateTime()) * 1000L)); + subscribeEvent.setEventType(StringUtils.isBlank(eventPushVO.getEvent()) ? "" : eventPushVO.getEvent()); + subscribeEvent.setSubscribeStatus(subscribeStatus); + subscribeEvent.setUpdateTime(LocalDateTime.now()); + subscribeEvent.setUpdateBy("xinyilu"); + int updateSubscribeEvent = officialAccountSubscribeEventMapper.updateSubscribeEventInfo(subscribeEvent); + if (updateSubscribeEvent < 0) { + log.error("院后微信公众号关注和取消事件,修改信息失败,信息为:[{}]", subscribeEvent); + throw new ServiceException("修改院后微信公众号关注和取消事件信息失败!"); + } + } + } } diff --git a/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatOfficialAccountUtils.java b/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatOfficialAccountUtils.java index 6c3a3f93..37d6bdb3 100644 --- a/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatOfficialAccountUtils.java +++ b/postdischarge-mobile/src/main/java/com/xinelu/mobile/utils/WeChatOfficialAccountUtils.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSON; import com.xinelu.common.config.WeChatOfficialAccountConfig; import com.xinelu.common.constant.Constants; import com.xinelu.common.entity.AccessToken; +import com.xinelu.common.entity.MessageValueEntity; import com.xinelu.common.exception.ServiceException; import com.xinelu.common.utils.http.HttpUtils; import lombok.extern.slf4j.Slf4j; @@ -81,7 +82,7 @@ public class WeChatOfficialAccountUtils { String accessToken = this.getWeChatOfficialAccountAccessToken(); //定义模板内容,公众模板内容 Map paramsMap = new LinkedHashMap<>(); - paramsMap.put("touser", "oHBuH5T90TghJdYKfBlxE4fhayBc"); + paramsMap.put("touser", "oSwvX5qknp3DrAXfBgFjoMvG6WCI"); paramsMap.put("template_id", "WUCYtSbH-QFRV_fMcfmn86QLsz1zo881QW7fQNTWOjc"); //微信小程序跳转内容 Map miniprogramMap = new LinkedHashMap<>(); @@ -89,11 +90,11 @@ public class WeChatOfficialAccountUtils { miniprogramMap.put("pagepath", "pages/startup/startup"); //微信小程序模板data内容 Map dataMap = new LinkedHashMap<>(); - dataMap.put("phrase7", "泉医陪护服务"); - dataMap.put("character_string3", "000026315412331612100"); - dataMap.put("time6", "2024-03-25 16:21:32"); - dataMap.put("time10", "2024-03-27 10:00:00"); - dataMap.put("thing11", "济南市槐荫区首诺城市之光东座22楼E10"); + dataMap.put("phrase7", new MessageValueEntity("泉医陪护")); + dataMap.put("character_string3", new MessageValueEntity("000026315412331612100")); + dataMap.put("time6", new MessageValueEntity("2024-03-25 16:21:32")); + dataMap.put("time10", new MessageValueEntity("2024-03-27 10:00:00")); + dataMap.put("thing11", new MessageValueEntity("济南市槐荫区首诺城市之光东座22楼E10")); paramsMap.put("miniprogram", miniprogramMap); paramsMap.put("data", dataMap); //拼接请求地址并发送 From 765cfe6d7cd7cacfe021d6abd6b6242c822b19b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=AA=E5=AF=92?= <2533659732@qq.com> Date: Mon, 1 Apr 2024 11:06:14 +0800 Subject: [PATCH 11/21] =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=86=B2=E7=AA=81?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/patientinfo/PatientInfo.java | 36 +- .../mapper/patientinfo/PatientInfoMapper.java | 8 +- .../manage/patientinfo/PatientInfoMapper.xml | 501 ------------------ 3 files changed, 10 insertions(+), 535 deletions(-) diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/patientinfo/PatientInfo.java b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/patientinfo/PatientInfo.java index e6cf4157..463e18dc 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/patientinfo/PatientInfo.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/patientinfo/PatientInfo.java @@ -10,8 +10,8 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import java.time.LocalDateTime; import java.time.LocalDate; +import java.time.LocalDateTime; /** * 患者信息对象 patient_info @@ -33,9 +33,6 @@ public class PatientInfo extends BaseEntity { */ private Long id; - /** - * 患者姓名 - */ /** * 居民信息表id */ @@ -119,9 +116,6 @@ public class PatientInfo extends BaseEntity { @Excel(name = "签约时间,格式:yyyy-MM-dd HH:mm:ss", width = 30, dateFormat = "yyyy-MM-dd") private LocalDateTime signTime; - /** - * 就诊方式,门诊:OUTPATIENT_SERVICE,住院:BE_IN_HOSPITAL - */ /** * 开证医生(预住院患者) */ @@ -150,9 +144,6 @@ public class PatientInfo extends BaseEntity { @Excel(name = "主治医生姓名") private String attendingPhysicianName; - /** - * 主要诊断 - */ /** * 主要诊断 */ @@ -166,9 +157,6 @@ public class PatientInfo extends BaseEntity { @Excel(name = "主治医生") private String attendingPhysician; - /** - * 所属医院id - */ /** * 所属医院id */ @@ -221,9 +209,6 @@ public class PatientInfo extends BaseEntity { @Excel(name = "所属病区名称") private String wardName; - /** - * 责任护士 - */ /** * 住院号 */ @@ -243,9 +228,6 @@ public class PatientInfo extends BaseEntity { @ApiModelProperty(value = "最新一条就诊记录id") private Long patientVisitRecordId; - /** - * 就诊流水号 - */ /** * 就诊流水号 */ @@ -258,9 +240,6 @@ public class PatientInfo extends BaseEntity { @ApiModelProperty(value = "手术名称") private String surgicalName; - /** - * 入院时间,时间格式:yyyy-MM-dd - */ /** * 入院时间,时间格式:yyyy-MM-dd */ @@ -273,9 +252,6 @@ public class PatientInfo extends BaseEntity { @ApiModelProperty(value = "出院时间(出院患者)") private LocalDateTime dischargeTime; - /** - * 预约治疗组(取值以及枚举未知?) - */ /** * 病历内容 */ @@ -312,6 +288,7 @@ public class PatientInfo extends BaseEntity { @ApiModelProperty(value = "门诊/住院号 ") @Excel(name = "门诊/住院号 ", readConverterExp = "门诊/住院号 ") private String inHospitalNumber; + /** * 门诊号(门诊患者) */ @@ -323,13 +300,15 @@ public class PatientInfo extends BaseEntity { * 就诊时间,格式:yyyy-MM-dd HH:mm:ss */ @ApiModelProperty(value = "就诊时间,格式:yyyy-MM-dd HH:mm:ss") - @JsonFormat(pattern = "yyyy-MM-dd") - @Excel(name = "就诊时间,格式:yyyy-MM-dd HH:mm:ss", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "就诊时间,格式:yyyy-MM-dd HH:mm:ss", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") private LocalDateTime visitDate; + /** * 就诊时间(门诊患者),时间格式:yyyy-MM-dd */ @ApiModelProperty(value = "就诊时间") + @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "就诊时间", readConverterExp = "门=诊患者") private LocalDate visitTime; @@ -340,9 +319,6 @@ public class PatientInfo extends BaseEntity { @Excel(name = "出院方式", readConverterExp = "出=院患者") private String dischargeMethod; - /** - * 患者来源,微信小程序:WE_CHAT_APPLET,微信公众号:WE_CHAT_OFFICIAL_ACCOUNT,管理端:MANAGE_END - */ /** * 微信小程序openid,微信小程序唯一标识 */ diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/patientinfo/PatientInfoMapper.java b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/patientinfo/PatientInfoMapper.java index 632f27e0..5fc4e354 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/patientinfo/PatientInfoMapper.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/patientinfo/PatientInfoMapper.java @@ -19,7 +19,7 @@ public interface PatientInfoMapper { * @param id 患者信息主键 * @return 患者信息 */ - public PatientInfo selectPatientInfoById(Long id); + PatientInfo selectPatientInfoById(Long id); /** * 查询患者信息 @@ -27,7 +27,7 @@ public interface PatientInfoMapper { * @param id 主键id * @return 患者信息 */ - public PatientBaseInfoVo getPatientBaseInfo(Long id); + PatientBaseInfoVo getPatientBaseInfo(Long id); /** * 查询患者信息列表 @@ -59,7 +59,7 @@ public interface PatientInfoMapper { * @param id 患者信息主键 * @return 结果 */ - public int deletePatientInfoById(Long id); + int deletePatientInfoById(Long id); /** * 批量删除患者信息 @@ -67,7 +67,7 @@ public interface PatientInfoMapper { * @param ids 需要删除的数据主键集合 * @return 结果 */ - public int deletePatientInfoByIds(Long[] ids); + int deletePatientInfoByIds(Long[] ids); /** * 根据openid查询被护理人信息 diff --git a/postdischarge-manage/src/main/resources/mapper/manage/patientinfo/PatientInfoMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/patientinfo/PatientInfoMapper.xml index ac12a2c5..3aff95f4 100644 --- a/postdischarge-manage/src/main/resources/mapper/manage/patientinfo/PatientInfoMapper.xml +++ b/postdischarge-manage/src/main/resources/mapper/manage/patientinfo/PatientInfoMapper.xml @@ -49,61 +49,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - select id,resident_id, - - select id, patient_name, patient_phone, family_member_phone, @@ -120,10 +68,6 @@ admission_time, discharge_time, appointment_treatment_group, registration_no, registration_date, appointment_date, in_hospital_number, visit_date, discharge_method, patient_source, del_flag, create_by, create_time, update_by, update_time - admission_number, responsible_nurse, visit_serial_number, surgical_name, - admission_date, discharge_date, medical_record_content, appointment_treatment_group, - registration_no, registration_date, appointment_date, outpatient_number, visit_time, discharge_method, - open_id, union_id, official_account_openid, patient_source, del_flag, create_by, create_time, update_by, update_time from patient_info @@ -207,93 +151,6 @@ - - - - insert into patient_info - - - patient_name, - - patient_phone, - - family_member_phone, - - birth_date, - - card_no, - - sex, - - address, - - patient_type, - - sign_status, - - sign_patient_record_id, - - service_status, - - sign_time, - - certificate_issuing_doctor, - - visit_method, - - main_diagnosis, - - attending_physician, - - hospital_agency_id, - - hospital_agency_name, - - campus_agency_id, - - campus_agency_name, - - department_id, - - department_name, - - ward_id, - - ward_name, - - - admission_number, - - - responsible_nurse, - - - visit_serial_number, - - - surgical_name, - - - admission_date, - - - discharge_date, - - medical_record_content, - - appointment_treatment_group, - - registration_no, - - registration_date, - - appointment_date, - - outpatient_number, - - visit_time, - - discharge_method, - - open_id, - - union_id, - - official_account_openid, - - patient_source, - - del_flag, - - create_by, - - create_time, - - update_by, - - update_time, - - - - #{patientName}, - - #{patientPhone}, - - #{familyMemberPhone}, - - #{birthDate}, - - #{cardNo}, - - #{sex}, - - #{address}, - - #{patientType}, - - #{signStatus}, - - #{signPatientRecordId}, - - #{serviceStatus}, - - #{signTime}, - - #{certificateIssuingDoctor}, - - #{visitMethod}, - - #{mainDiagnosis}, - - #{attendingPhysician}, - - #{hospitalAgencyId}, - - #{hospitalAgencyName}, - - #{campusAgencyId}, - - #{campusAgencyName}, - - #{departmentId}, - - #{departmentName}, - - #{wardId}, - - #{wardName}, - - #{admissionNumber}, - - #{responsibleNurse}, - - #{visitSerialNumber}, - - #{surgicalName}, - - #{admissionDate}, - - #{dischargeDate}, - - #{medicalRecordContent}, - - #{appointmentTreatmentGroup}, - - #{registrationNo}, - - #{registrationDate}, - - #{appointmentDate}, - - #{outpatientNumber}, - - #{visitTime}, - - #{dischargeMethod}, - - #{openId}, - - #{unionId}, - - #{officialAccountOpenId}, - - #{patientSource}, - - #{delFlag}, - - #{createBy}, - - #{createTime}, - - #{updateBy}, - - #{updateTime}, - - - insert into patient_info @@ -703,151 +353,6 @@ - - update patient_info - - - patient_name = #{patientName}, - - - patient_phone = #{patientPhone}, - - - family_member_phone = #{familyMemberPhone}, - - - birth_date = #{birthDate}, - - - card_no = #{cardNo}, - - - sex = #{sex}, - - - address = #{address}, - - - patient_type = #{patientType}, - - sign_status = - #{signStatus}, - - sign_patient_record_id = #{signPatientRecordId}, - - service_status = #{serviceStatus}, - - sign_time = - #{signTime}, - - certificate_issuing_doctor = - #{certificateIssuingDoctor}, - - visit_method = - #{visitMethod}, - - main_diagnosis = - #{mainDiagnosis}, - - attending_physician = - #{attendingPhysician}, - - hospital_agency_id = - #{hospitalAgencyId}, - - hospital_agency_name = - #{hospitalAgencyName}, - - campus_agency_id = - #{campusAgencyId}, - - campus_agency_name = - #{campusAgencyName}, - - department_id = - #{departmentId}, - - department_name = - #{departmentName}, - - ward_id = - #{wardId}, - - ward_name = - #{wardName}, - - admission_number = - #{admissionNumber}, - - responsible_nurse = - #{responsibleNurse}, - - visit_serial_number = - #{visitSerialNumber}, - - surgical_name = - #{surgicalName}, - - - admission_date = #{admissionDate}, - - - discharge_date = #{dischargeDate}, - - medical_record_content = - #{medicalRecordContent}, - - appointment_treatment_group = - #{appointmentTreatmentGroup}, - - registration_no = - #{registrationNo}, - - registration_date = - #{registrationDate}, - - appointment_date = - #{appointmentDate}, - - outpatient_number = - #{outpatientNumber}, - - visit_time = - #{visitTime}, - - discharge_method = - #{dischargeMethod}, - - open_id = - #{openId}, - - union_id = - #{unionId}, - - official_account_openid = - #{officialAccountOpenId}, - - patient_source = - #{patientSource}, - - del_flag = - #{delFlag}, - - create_by = - #{createBy}, - - create_time = - #{createTime}, - - update_by = - #{updateBy}, - - update_time = - #{updateTime}, - - - where id = #{id} - update patient_info @@ -993,12 +498,6 @@ #{id} - - update patient_info set del_flag = 1 where id in - - #{id} - - diff --git a/postdischarge-manage/src/main/resources/mapper/manage/specialdiseasenode/SpecialDiseaseNodeMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/specialdiseasenode/SpecialDiseaseNodeMapper.xml index f698c374..372c8286 100644 --- a/postdischarge-manage/src/main/resources/mapper/manage/specialdiseasenode/SpecialDiseaseNodeMapper.xml +++ b/postdischarge-manage/src/main/resources/mapper/manage/specialdiseasenode/SpecialDiseaseNodeMapper.xml @@ -20,8 +20,6 @@ - @@ -72,19 +70,6 @@ - - - - - - - - - - - - - select id, route_id, @@ -716,7 +701,7 @@ - - - - - - \ No newline at end of file From 3514b0a62a8cecc0af4f55fda2c2f510ccc876b9 Mon Sep 17 00:00:00 2001 From: youxilong Date: Mon, 8 Apr 2024 11:16:50 +0800 Subject: [PATCH 13/21] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=BA=E5=B7=A5?= =?UTF-8?q?=E9=9A=8F=E8=AE=BF=E4=BB=A3=E5=8A=9E=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SignPatientManageRouteServiceImpl.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/signpatientmanageroute/impl/SignPatientManageRouteServiceImpl.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/signpatientmanageroute/impl/SignPatientManageRouteServiceImpl.java index 2d807e04..3d6a964f 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/service/signpatientmanageroute/impl/SignPatientManageRouteServiceImpl.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/signpatientmanageroute/impl/SignPatientManageRouteServiceImpl.java @@ -208,11 +208,16 @@ public class SignPatientManageRouteServiceImpl implements ISignPatientManageRout // 新增患者管理任务执行记录 insertPatientTaskExecuteRecord(dto, routeHandlePerson, time); } else { - // 如果任务类型不是电话外呼(人工随访,问卷量表),新增问卷提交结果表(题目,选项表),更新节点任务表,新增患者管理任务执行记录 + // 如果任务类型不是电话外呼,更新节点任务表,新增患者管理任务执行记录,新增问卷提交结果表、题目表、选项表 + // 更新节点任务表 + updateSignPatientManageRouteNode(dto, routeHandlePerson, time); + // 新增患者管理任务执行记录 + Long taskExecuteRecordId = insertPatientTaskExecuteRecord(dto, routeHandlePerson, time); PatientQuestionSubmitResult patientQuestionSubmitResult = new PatientQuestionSubmitResult(); BeanUtils.copyBeanProp(patientQuestionSubmitResult, dto); patientQuestionSubmitResult.setCreateBy(routeHandlePerson); patientQuestionSubmitResult.setCreateTime(time); + patientQuestionSubmitResult.setTaskExecuteRecordId(taskExecuteRecordId); // 新增患者问卷提交结果 if (patientQuestionSubmitResultMapper.insertPatientQuestionSubmitResult(patientQuestionSubmitResult) <= 0) { throw new ServiceException("新增患者问卷提交结果失败"); @@ -255,11 +260,6 @@ public class SignPatientManageRouteServiceImpl implements ISignPatientManageRout if (patientQuestionOptionResultMapper.saveQuestionOptionList(saveQuestionSubjectOptions) <= 0) { throw new ServiceException("新增患者问卷题目选项提交结果失败"); } - // 更新节点任务表 - updateSignPatientManageRouteNode(dto, routeHandlePerson, time); - // 新增患者管理任务执行记录 - insertPatientTaskExecuteRecord(dto, routeHandlePerson, time); - } return AjaxResult.success(); } @@ -267,7 +267,7 @@ public class SignPatientManageRouteServiceImpl implements ISignPatientManageRout /** * 新增患者管理任务执行记录 */ - private void insertPatientTaskExecuteRecord(PatientQuestionSubmitResultDTO dto, String routeHandlePerson, LocalDateTime time) { + private Long insertPatientTaskExecuteRecord(PatientQuestionSubmitResultDTO dto, String routeHandlePerson, LocalDateTime time) { PatientTaskExecuteRecord patientTaskExecuteRecord = new PatientTaskExecuteRecord(); BeanUtils.copyProperties(dto, patientTaskExecuteRecord); patientTaskExecuteRecord.setTaskContent(dto.getTaskType()); @@ -276,11 +276,12 @@ public class SignPatientManageRouteServiceImpl implements ISignPatientManageRout patientTaskExecuteRecord.setExecuteType(TaskCreateTypeConstant.MANUAL_CREATE); patientTaskExecuteRecord.setCreateBy(routeHandlePerson); patientTaskExecuteRecord.setCreateTime(time); - if (patientTaskExecuteRecordMapper.insertPatientTaskExecuteRecord(patientTaskExecuteRecord) <= 0) { + if (patientTaskExecuteRecordMapper.insertPatientTaskExecuteRecord(patientTaskExecuteRecord) > 0) { + return patientTaskExecuteRecord.getId(); + } else { throw new ServiceException("新增患者管理任务记录失败"); } } - /** * 更新节点任务表 */ From 6f4a37bfa51a8c80f0d69896ecac8f8287ca0c07 Mon Sep 17 00:00:00 2001 From: youxilong Date: Mon, 8 Apr 2024 11:30:52 +0800 Subject: [PATCH 14/21] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/xinelu/manage/domain/patientinfo/PatientInfo.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/patientinfo/PatientInfo.java b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/patientinfo/PatientInfo.java index edc82985..42975e88 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/patientinfo/PatientInfo.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/patientinfo/PatientInfo.java @@ -233,12 +233,6 @@ public class PatientInfo extends BaseEntity { @ApiModelProperty(value = "就诊流水号") private String visitSerialNumber; - /** - * 手术名称 - */ - @ApiModelProperty(value = "手术名称") - private String surgicalName; - /** * 入院时间,时间格式:yyyy-MM-dd */ From 57a73624f24018b827207fc2d02fb9a8b4dc06fc Mon Sep 17 00:00:00 2001 From: zhangheng <3226558941@qq.com> Date: Mon, 8 Apr 2024 15:15:24 +0800 Subject: [PATCH 15/21] =?UTF-8?q?=E4=B8=93=E7=97=85=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/enums/RouteCheckStatusEnum.java | 25 ++++--- .../SpecialDiseaseNodeController.java | 11 +++ .../ISpecialDiseaseNodeService.java | 8 +++ .../impl/SpecialDiseaseNodeServiceImpl.java | 19 +++-- .../SpecialDiseaseNodeVO.java | 7 +- .../SpecialDiseaseNodeMapper.xml | 71 +++++++++++++++++-- 6 files changed, 121 insertions(+), 20 deletions(-) diff --git a/postdischarge-common/src/main/java/com/xinelu/common/enums/RouteCheckStatusEnum.java b/postdischarge-common/src/main/java/com/xinelu/common/enums/RouteCheckStatusEnum.java index f706c9c1..a3151660 100644 --- a/postdischarge-common/src/main/java/com/xinelu/common/enums/RouteCheckStatusEnum.java +++ b/postdischarge-common/src/main/java/com/xinelu/common/enums/RouteCheckStatusEnum.java @@ -1,19 +1,28 @@ package com.xinelu.common.enums; +import lombok.Getter; + /** * 节点审核状态枚举类 * * @author haown * @date 2024-04-01 */ +@Getter public enum RouteCheckStatusEnum { - /** - * 同意 - */ - AGREE, + /** + * 同意 + */ + AGREE("AGREE"), - /** - * 不同意 - */ - DISAGREE + /** + * 不同意 + */ + DISAGREE("DISAGREE"), + ; + final private String info; + + RouteCheckStatusEnum(String info) { + this.info = info; + } } diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/controller/specialdiseasenode/SpecialDiseaseNodeController.java b/postdischarge-manage/src/main/java/com/xinelu/manage/controller/specialdiseasenode/SpecialDiseaseNodeController.java index 818a91bf..33ff1255 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/controller/specialdiseasenode/SpecialDiseaseNodeController.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/controller/specialdiseasenode/SpecialDiseaseNodeController.java @@ -101,4 +101,15 @@ public class SpecialDiseaseNodeController extends BaseController { } return specialDiseaseNodeService.selectSpecialDisease(specialDiseaseRouteId); } + + /** + * 修改节点信息状态 + */ + @PostMapping("/updateRouteCheckStatus") + public AjaxResult updateRouteCheckStatus(@RequestBody SpecialDiseaseNode specialDiseaseNode) { + if (Objects.isNull(specialDiseaseNode)) { + return AjaxResult.error("请选择需要修改的节点信息!"); + } + return specialDiseaseNodeService.updateRouteCheckStatus(specialDiseaseNode); + } } diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseasenode/ISpecialDiseaseNodeService.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseasenode/ISpecialDiseaseNodeService.java index da781192..b4f06545 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseasenode/ISpecialDiseaseNodeService.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseasenode/ISpecialDiseaseNodeService.java @@ -68,4 +68,12 @@ public interface ISpecialDiseaseNodeService { * @return AjaxResult */ AjaxResult selectSpecialDisease(Long specialDiseaseRouteId); + + /** + * 修改节点信息状态 + * + * @param specialDiseaseNode 节点信息 + * @return AjaxResult + */ + AjaxResult updateRouteCheckStatus(SpecialDiseaseNode specialDiseaseNode); } diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseasenode/impl/SpecialDiseaseNodeServiceImpl.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseasenode/impl/SpecialDiseaseNodeServiceImpl.java index 832ca6df..73876c1e 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseasenode/impl/SpecialDiseaseNodeServiceImpl.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseasenode/impl/SpecialDiseaseNodeServiceImpl.java @@ -1,6 +1,7 @@ package com.xinelu.manage.service.specialdiseasenode.impl; import com.xinelu.common.core.domain.AjaxResult; +import com.xinelu.common.enums.RouteCheckStatusEnum; import com.xinelu.common.exception.ServiceException; import com.xinelu.common.utils.SecurityUtils; import com.xinelu.common.utils.bean.BeanUtils; @@ -8,8 +9,8 @@ import com.xinelu.manage.domain.specialdiseasenode.SpecialDiseaseNode; import com.xinelu.manage.domain.specialdiseaseroute.SpecialDiseaseRoute; import com.xinelu.manage.mapper.specialdiseasenode.SpecialDiseaseNodeMapper; import com.xinelu.manage.mapper.specialdiseaseroute.SpecialDiseaseRouteMapper; -import com.xinelu.manage.mapper.specialdiseasetriggercondition.SpecialDiseaseTriggerConditionMapper; import com.xinelu.manage.service.specialdiseasenode.ISpecialDiseaseNodeService; +import com.xinelu.manage.vo.specialdiseasenode.SpecialDiseaseNodeVO; import com.xinelu.manage.vo.specialdiseaseroute.SpecialDiseaseRouteVO; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -32,8 +33,6 @@ public class SpecialDiseaseNodeServiceImpl implements ISpecialDiseaseNodeService private SpecialDiseaseNodeMapper specialDiseaseNodeMapper; @Resource private SpecialDiseaseRouteMapper specialDiseaseRouteMapper; - @Resource - private SpecialDiseaseTriggerConditionMapper triggerConditionMapper; /** @@ -111,11 +110,12 @@ public class SpecialDiseaseNodeServiceImpl implements ISpecialDiseaseNodeService log.info("删除管理节点信息失败"); throw new ServiceException("修改专病路径管理节点信息失败"); } - for (SpecialDiseaseNode diseaseNode : specialDiseaseNode.getSpecialDiseaseNodeList()) { + for (SpecialDiseaseNodeVO diseaseNode : specialDiseaseNode.getSpecialDiseaseNodeList()) { diseaseNode.setRouteId(specialDiseaseRoute.getId()); diseaseNode.setRouteName(specialDiseaseNode.getRouteName()); diseaseNode.setUpdateTime(LocalDateTime.now()); diseaseNode.setUpdateBy(SecurityUtils.getUsername()); + diseaseNode.setRouteCheckStatus(RouteCheckStatusEnum.DISAGREE.getInfo()); } int insertNodeCount = specialDiseaseNodeMapper.insertSpecialDiseaseNodeList(specialDiseaseNode.getSpecialDiseaseNodeList()); if (insertNodeCount < 0) { @@ -157,4 +157,15 @@ public class SpecialDiseaseNodeServiceImpl implements ISpecialDiseaseNodeService public AjaxResult selectSpecialDisease(Long specialDiseaseRouteId) { return AjaxResult.success(specialDiseaseNodeMapper.selectSpecialDiseaseByRouteId(specialDiseaseRouteId)); } + + /** + * 修改节点信息状态 + * + * @param specialDiseaseNode 节点信息 + * @return AjaxResult + */ + @Override + public AjaxResult updateRouteCheckStatus(SpecialDiseaseNode specialDiseaseNode) { + return AjaxResult.success(specialDiseaseNodeMapper.updateSpecialDiseaseNode(specialDiseaseNode)); + } } diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/vo/specialdiseasenode/SpecialDiseaseNodeVO.java b/postdischarge-manage/src/main/java/com/xinelu/manage/vo/specialdiseasenode/SpecialDiseaseNodeVO.java index 932c2956..65cc8bff 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/vo/specialdiseasenode/SpecialDiseaseNodeVO.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/vo/specialdiseasenode/SpecialDiseaseNodeVO.java @@ -15,6 +15,9 @@ import lombok.EqualsAndHashCode; @Data public class SpecialDiseaseNodeVO extends SpecialDiseaseNode { - @ApiModelProperty(value = "专病路径表id") - private Long SpecialDiseaseNodeId; + private Long specialDiseaseNodeId; + + private String taskTypeName; + + private String taskSubdivisionName; } diff --git a/postdischarge-manage/src/main/resources/mapper/manage/specialdiseasenode/SpecialDiseaseNodeMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/specialdiseasenode/SpecialDiseaseNodeMapper.xml index 372c8286..2516a64a 100644 --- a/postdischarge-manage/src/main/resources/mapper/manage/specialdiseasenode/SpecialDiseaseNodeMapper.xml +++ b/postdischarge-manage/src/main/resources/mapper/manage/specialdiseasenode/SpecialDiseaseNodeMapper.xml @@ -18,8 +18,10 @@ + + + resultMap="SpecialDiseaseNodeVOResult"/> @@ -64,12 +66,60 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, route_id, @@ -701,9 +751,9 @@ + + \ No newline at end of file From cb102a265127a2fcc91f10ca3b7a15116612d76a Mon Sep 17 00:00:00 2001 From: youxilong Date: Mon, 8 Apr 2024 17:53:20 +0800 Subject: [PATCH 17/21] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=BA=E5=B7=A5?= =?UTF-8?q?=E9=9A=8F=E8=AE=BF=E4=BB=A3=E5=8A=9E=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/manualfollowup/ManualFollowUpDTO.java | 4 +-- .../SignPatientManageRouteServiceImpl.java | 4 +-- .../vo/manualfollowup/ManualFollowUpVO.java | 4 +-- .../SignPatientManageRouteMapper.xml | 27 +++++++++++++++---- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/dto/manualfollowup/ManualFollowUpDTO.java b/postdischarge-manage/src/main/java/com/xinelu/manage/dto/manualfollowup/ManualFollowUpDTO.java index 9cc18b43..d000e5cb 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/dto/manualfollowup/ManualFollowUpDTO.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/dto/manualfollowup/ManualFollowUpDTO.java @@ -44,8 +44,8 @@ public class ManualFollowUpDTO { @ApiModelProperty(value = "所属病区id") private Long wardId; - @ApiModelProperty(value = "患者类型,在院患者:IN_HOSPITAL_PATIENT,门诊患者:OUTPATIENT,出院患者:DISCHARGED_PATIENT") - private String patientType; + @ApiModelProperty(value = "适用范围,在院:IN_THE_HOSPITAL,出院:DISCHARGE,门诊:OUTPATIENT_SERVICE") + private String suitRange; @ApiModelProperty(value = "就诊流水号") private String visitSerialNumber; diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/signpatientmanageroute/impl/SignPatientManageRouteServiceImpl.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/signpatientmanageroute/impl/SignPatientManageRouteServiceImpl.java index 3d6a964f..1669c300 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/service/signpatientmanageroute/impl/SignPatientManageRouteServiceImpl.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/signpatientmanageroute/impl/SignPatientManageRouteServiceImpl.java @@ -291,8 +291,8 @@ public class SignPatientManageRouteServiceImpl implements ISignPatientManageRout signPatientManageRouteNode.setRouteHandleRemark(dto.getRouteHandleRemark()); signPatientManageRouteNode.setRouteHandleId(dto.getRouteHandleId()); signPatientManageRouteNode.setRouteHandlePerson(routeHandlePerson); - signPatientManageRouteNode.setCreateBy(routeHandlePerson); - signPatientManageRouteNode.setCreateTime(time); + signPatientManageRouteNode.setUpdateBy(routeHandlePerson); + signPatientManageRouteNode.setUpdateTime(time); // 更新节点任务表 if (signPatientManageRouteNodeMapper.updateSignPatientManageRouteNode(signPatientManageRouteNode) <= 0) { throw new ServiceException("更新节点任务表失败"); diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/vo/manualfollowup/ManualFollowUpVO.java b/postdischarge-manage/src/main/java/com/xinelu/manage/vo/manualfollowup/ManualFollowUpVO.java index d5dc1fed..7852b9a4 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/vo/manualfollowup/ManualFollowUpVO.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/vo/manualfollowup/ManualFollowUpVO.java @@ -90,8 +90,8 @@ public class ManualFollowUpVO { @ApiModelProperty(value = "主治医生姓名") private String attendingPhysicianName; - @ApiModelProperty(value = "患者类型,在院患者:IN_HOSPITAL_PATIENT,门诊患者:OUTPATIENT,出院患者:DISCHARGED_PATIENT") - private String patientType; + @ApiModelProperty(value = "在院:IN_THE_HOSPITAL,出院:DISCHARGE,门诊:OUTPATIENT_SERVICE") + private String suitRange; @ApiModelProperty(value = "入院时间") @JsonFormat(pattern = "yyyy-MM-dd") diff --git a/postdischarge-manage/src/main/resources/mapper/manage/signpatientmanageroute/SignPatientManageRouteMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/signpatientmanageroute/SignPatientManageRouteMapper.xml index 45e9fd8e..4cfc4e5a 100644 --- a/postdischarge-manage/src/main/resources/mapper/manage/signpatientmanageroute/SignPatientManageRouteMapper.xml +++ b/postdischarge-manage/src/main/resources/mapper/manage/signpatientmanageroute/SignPatientManageRouteMapper.xml @@ -115,9 +115,17 @@ pvr.surgical_name, pi.attending_physician_id, pi.attending_physician_name, - pi.patient_type, - IF(pi.visit_method = 'OUTPATIENT_SERVICE',NULL,pi.admission_time) AS 'admissionTime', - IF(pi.visit_method = 'OUTPATIENT_SERVICE',pi.visit_date,pi.discharge_time) AS 'visitOrDischargeTime', + IF(spmr.suit_range = 'IN_THE_HOSPITAL', pi.admission_time, NULL) AS 'admissionTime', + CASE + WHEN spmr.suit_range = 'OUTPATIENT_SERVICE' THEN pi.visit_date + WHEN spmr.suit_range = 'DISCHARGE' THEN pi.discharge_time + WHEN spmr.suit_range = 'OUTPATIENT_SERVICE_DISCHARGE' THEN COALESCE(pi.visit_date, pi.discharge_time) + END AS 'visitOrDischargeTime', + CASE + WHEN spmr.suit_range IN ('IN_THE_HOSPITAL', 'DISCHARGE', 'OUTPATIENT_SERVICE') THEN spmr.suit_range + WHEN spmr.suit_range = 'OUTPATIENT_SERVICE_DISCHARGE' AND pi.visit_date IS NOT NULL THEN 'OUTPATIENT_SERVICE' + WHEN spmr.suit_range = 'OUTPATIENT_SERVICE_DISCHARGE' AND pi.discharge_time IS NOT NULL THEN 'DISCHARGE' + END AS 'suitRange', pter.execute_time AS 'executeTime', spmr.id AS 'manageRouteId', spmrn.id AS 'manageRouteNodeId', @@ -162,8 +170,17 @@ AND pi.ward_id = #{wardId} - - AND pi.patient_type = #{patientType} + + + + + AND (spmr.suit_range = #{suitRange} OR spmr.suit_range = 'OUTPATIENT_SERVICE_DISCHARGE') + + + + AND spmr.suit_range = #{suitRange} + + AND pi.visit_serial_number LIKE concat('%', #{visitSerialNumber}, '%') From f539d7628eeebf22eaa0df4adc25f836a902f665 Mon Sep 17 00:00:00 2001 From: zhangheng <3226558941@qq.com> Date: Tue, 9 Apr 2024 13:24:39 +0800 Subject: [PATCH 18/21] =?UTF-8?q?=E4=B8=93=E7=97=85=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SpecialDiseaseRouteController.java | 8 +- .../SpecialDiseaseRoutePackageController.java | 91 ++++++++++ .../SpecialDiseaseRoutePackage.java | 76 ++++++++ .../SpecialDiseaseRoutePackageMapper.java | 73 ++++++++ .../impl/QuestionInfoServiceImpl.java | 4 +- .../ISpecialDiseaseRouteService.java | 4 +- .../impl/SpecialDiseaseRouteServiceImpl.java | 67 ++++++- .../ISpecialDiseaseRoutePackageService.java | 61 +++++++ ...SpecialDiseaseRoutePackageServiceImpl.java | 90 ++++++++++ .../SpecialDiseaseRouteVO.java | 3 + .../SpecialDiseaseRoutePackageVO.java | 18 ++ .../SpecialDiseaseRouteMapper.xml | 16 ++ .../SpecialDiseaseRoutePackageMapper.xml | 168 ++++++++++++++++++ 13 files changed, 665 insertions(+), 14 deletions(-) create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/controller/specialdiseaseroutepackage/SpecialDiseaseRoutePackageController.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/domain/specialdiseaseroutepackage/SpecialDiseaseRoutePackage.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/mapper/specialdiseaseroutepackage/SpecialDiseaseRoutePackageMapper.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroutepackage/ISpecialDiseaseRoutePackageService.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroutepackage/impl/SpecialDiseaseRoutePackageServiceImpl.java create mode 100644 postdischarge-manage/src/main/java/com/xinelu/manage/vo/specialdiseaseroutepackage/SpecialDiseaseRoutePackageVO.java create mode 100644 postdischarge-manage/src/main/resources/mapper/manage/specialdiseaseroutepackage/SpecialDiseaseRoutePackageMapper.xml diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/controller/specialdiseaseroute/SpecialDiseaseRouteController.java b/postdischarge-manage/src/main/java/com/xinelu/manage/controller/specialdiseaseroute/SpecialDiseaseRouteController.java index ef503523..981bf2df 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/controller/specialdiseaseroute/SpecialDiseaseRouteController.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/controller/specialdiseaseroute/SpecialDiseaseRouteController.java @@ -52,8 +52,8 @@ public class SpecialDiseaseRouteController extends BaseController { @PreAuthorize("@ss.hasPermi('system:specialDiseaseRoute:add')") @Log(title = "专病路径信息", businessType = BusinessType.INSERT) @PostMapping("/add") - public AjaxResult add(@RequestBody SpecialDiseaseRoute specialDiseaseRoute) { - return toAjax(specialDiseaseRouteService.insertSpecialDiseaseRoute(specialDiseaseRoute)); + public AjaxResult add(@RequestBody SpecialDiseaseRouteVO specialDiseaseRoute) { + return specialDiseaseRouteService.insertSpecialDiseaseRoute(specialDiseaseRoute); } /** @@ -62,8 +62,8 @@ public class SpecialDiseaseRouteController extends BaseController { @PreAuthorize("@ss.hasPermi('system:specialDiseaseRoute:edit')") @Log(title = "专病路径信息", businessType = BusinessType.UPDATE) @PutMapping("/edit") - public AjaxResult edit(@RequestBody SpecialDiseaseRoute specialDiseaseRoute) { - return toAjax(specialDiseaseRouteService.updateSpecialDiseaseRoute(specialDiseaseRoute)); + public AjaxResult edit(@RequestBody SpecialDiseaseRouteVO specialDiseaseRoute) { + return specialDiseaseRouteService.updateSpecialDiseaseRoute(specialDiseaseRoute); } /** diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/controller/specialdiseaseroutepackage/SpecialDiseaseRoutePackageController.java b/postdischarge-manage/src/main/java/com/xinelu/manage/controller/specialdiseaseroutepackage/SpecialDiseaseRoutePackageController.java new file mode 100644 index 00000000..7713e752 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/controller/specialdiseaseroutepackage/SpecialDiseaseRoutePackageController.java @@ -0,0 +1,91 @@ +package com.xinelu.manage.controller.specialdiseaseroutepackage; + +import com.xinelu.common.annotation.Log; +import com.xinelu.common.core.controller.BaseController; +import com.xinelu.common.core.domain.AjaxResult; +import com.xinelu.common.core.page.TableDataInfo; +import com.xinelu.common.enums.BusinessType; +import com.xinelu.common.utils.poi.ExcelUtil; +import com.xinelu.manage.domain.specialdiseaseroutepackage.SpecialDiseaseRoutePackage; +import com.xinelu.manage.service.specialdiseaseroutepackage.ISpecialDiseaseRoutePackageService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 专病路径-服务包关系(多对多关系)Controller + * + * @author xinelu + * @date 2024-04-09 + */ +@RestController +@RequestMapping("/system/routePackage") +public class SpecialDiseaseRoutePackageController extends BaseController { + @Resource + private ISpecialDiseaseRoutePackageService specialDiseaseRoutePackageService; + + /** + * 查询专病路径-服务包关系(多对多关系)列表 + */ + @PreAuthorize("@ss.hasPermi('system:routePackage:list')") + @GetMapping("/list") + public TableDataInfo list(SpecialDiseaseRoutePackage specialDiseaseRoutePackage) { + startPage(); + List list = specialDiseaseRoutePackageService.selectSpecialDiseaseRoutePackageList(specialDiseaseRoutePackage); + return getDataTable(list); + } + + /** + * 导出专病路径-服务包关系(多对多关系)列表 + */ + @PreAuthorize("@ss.hasPermi('system:routePackage:export')") + @Log(title = "专病路径-服务包关系(多对多关系)", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SpecialDiseaseRoutePackage specialDiseaseRoutePackage) { + List list = specialDiseaseRoutePackageService.selectSpecialDiseaseRoutePackageList(specialDiseaseRoutePackage); + ExcelUtil util = new ExcelUtil<>(SpecialDiseaseRoutePackage.class); + util.exportExcel(response, list, "专病路径-服务包关系(多对多关系)数据"); + } + + /** + * 获取专病路径-服务包关系(多对多关系)详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:routePackage:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) { + return AjaxResult.success(specialDiseaseRoutePackageService.selectSpecialDiseaseRoutePackageById(id)); + } + + /** + * 新增专病路径-服务包关系(多对多关系) + */ + @PreAuthorize("@ss.hasPermi('system:routePackage:add')") + @Log(title = "专病路径-服务包关系(多对多关系)", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SpecialDiseaseRoutePackage specialDiseaseRoutePackage) { + return toAjax(specialDiseaseRoutePackageService.insertSpecialDiseaseRoutePackage(specialDiseaseRoutePackage)); + } + + /** + * 修改专病路径-服务包关系(多对多关系) + */ + @PreAuthorize("@ss.hasPermi('system:routePackage:edit')") + @Log(title = "专病路径-服务包关系(多对多关系)", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SpecialDiseaseRoutePackage specialDiseaseRoutePackage) { + return toAjax(specialDiseaseRoutePackageService.updateSpecialDiseaseRoutePackage(specialDiseaseRoutePackage)); + } + + /** + * 删除专病路径-服务包关系(多对多关系) + */ + @PreAuthorize("@ss.hasPermi('system:routePackage:remove')") + @Log(title = "专病路径-服务包关系(多对多关系)", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) { + return toAjax(specialDiseaseRoutePackageService.deleteSpecialDiseaseRoutePackageByIds(ids)); + } +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/domain/specialdiseaseroutepackage/SpecialDiseaseRoutePackage.java b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/specialdiseaseroutepackage/SpecialDiseaseRoutePackage.java new file mode 100644 index 00000000..3b226ba7 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/domain/specialdiseaseroutepackage/SpecialDiseaseRoutePackage.java @@ -0,0 +1,76 @@ +package com.xinelu.manage.domain.specialdiseaseroutepackage; + +import com.xinelu.common.annotation.Excel; +import com.xinelu.common.core.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 专病路径-服务包关系(多对多关系)对象 special_disease_route_package + * + * @author xinelu + * @date 2024-04-09 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +@ApiModel(value = "专病路径-服务包关系(多对多关系)对象", description = "special_disease_route_package") +public class SpecialDiseaseRoutePackage extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + private Long id; + + /** + * 专病路径表id + */ + @ApiModelProperty(value = "专病路径表id") + @Excel(name = "专病路径表id") + private Long routeId; + + /** + * 服务包表id + */ + @ApiModelProperty(value = "服务包表id") + @Excel(name = "服务包表id") + private Long servicePackageId; + + /** + * 路径名称 + */ + @ApiModelProperty(value = "路径名称") + @Excel(name = "路径名称") + private String routeName; + + /** + * 服务包名称 + */ + @ApiModelProperty(value = "服务包名称") + @Excel(name = "服务包名称") + private String packageName; + + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("routeId", getRouteId()) + .append("servicePackageId", getServicePackageId()) + .append("routeName", getRouteName()) + .append("packageName", getPackageName()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/specialdiseaseroutepackage/SpecialDiseaseRoutePackageMapper.java b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/specialdiseaseroutepackage/SpecialDiseaseRoutePackageMapper.java new file mode 100644 index 00000000..03c1d924 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/specialdiseaseroutepackage/SpecialDiseaseRoutePackageMapper.java @@ -0,0 +1,73 @@ +package com.xinelu.manage.mapper.specialdiseaseroutepackage; + +import com.xinelu.manage.domain.specialdiseaseroutepackage.SpecialDiseaseRoutePackage; + +import java.util.List; + +/** + * 专病路径-服务包关系(多对多关系)Mapper接口 + * + * @author xinelu + * @date 2024-04-09 + */ +public interface SpecialDiseaseRoutePackageMapper { + /** + * 查询专病路径-服务包关系(多对多关系) + * + * @param id 专病路径-服务包关系(多对多关系)主键 + * @return 专病路径-服务包关系(多对多关系) + */ + SpecialDiseaseRoutePackage selectSpecialDiseaseRoutePackageById(Long id); + + /** + * 查询专病路径-服务包关系(多对多关系)列表 + * + * @param specialDiseaseRoutePackage 专病路径-服务包关系(多对多关系) + * @return 专病路径-服务包关系(多对多关系)集合 + */ + List selectSpecialDiseaseRoutePackageList(SpecialDiseaseRoutePackage specialDiseaseRoutePackage); + + /** + * 新增专病路径-服务包关系(多对多关系) + * + * @param specialDiseaseRoutePackage 专病路径-服务包关系(多对多关系) + * @return 结果 + */ + int insertSpecialDiseaseRoutePackage(SpecialDiseaseRoutePackage specialDiseaseRoutePackage); + + /** + * 修改专病路径-服务包关系(多对多关系) + * + * @param specialDiseaseRoutePackage 专病路径-服务包关系(多对多关系) + * @return 结果 + */ + int updateSpecialDiseaseRoutePackage(SpecialDiseaseRoutePackage specialDiseaseRoutePackage); + + /** + * 删除专病路径-服务包关系(多对多关系) + * + * @param id 专病路径-服务包关系(多对多关系)主键 + * @return 结果 + */ + int deleteSpecialDiseaseRoutePackageById(Long id); + + /** + * 批量删除专病路径-服务包关系(多对多关系) + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteSpecialDiseaseRoutePackageByIds(Long[] ids); + + + int insertSpecialDiseaseRoutePackageList(List specialDiseaseRoutePackageList); + + + /** + * 删除专病路径-服务包关系(多对多关系) + * + * @param routeId 专病路径-服务包关系(多对多关系)主键 + * @return 结果 + */ + int deleteSpecialDiseaseRoutePackageByRouteId(Long routeId); +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/questioninfo/impl/QuestionInfoServiceImpl.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/questioninfo/impl/QuestionInfoServiceImpl.java index 968a6871..89f57d13 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/service/questioninfo/impl/QuestionInfoServiceImpl.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/questioninfo/impl/QuestionInfoServiceImpl.java @@ -181,7 +181,9 @@ public class QuestionInfoServiceImpl implements IQuestionInfoService { saveQuestionSubject.setCreateTime(LocalDateTime.now()); saveQuestionSubject.setCreateBy(SecurityUtils.getUsername()); questionSubjects.add(saveQuestionSubject); - questionSubjectOptions.addAll(questionSubject.getQuestionSubjectOptionList()); + if (CollectionUtils.isNotEmpty(questionSubject.getQuestionSubjectOptionList())) { + questionSubjectOptions.addAll(questionSubject.getQuestionSubjectOptionList()); + } } int questionSubjectCount = questionSubjectMapper.insertQuestionSubjectList(questionSubjects); if (questionSubjectCount <= 0) { diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroute/ISpecialDiseaseRouteService.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroute/ISpecialDiseaseRouteService.java index f6d70fb5..c9cc8deb 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroute/ISpecialDiseaseRouteService.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroute/ISpecialDiseaseRouteService.java @@ -35,7 +35,7 @@ public interface ISpecialDiseaseRouteService { * @param specialDiseaseRoute 专病路径信息 * @return 结果 */ - int insertSpecialDiseaseRoute(SpecialDiseaseRoute specialDiseaseRoute); + AjaxResult insertSpecialDiseaseRoute(SpecialDiseaseRouteVO specialDiseaseRoute); /** * 修改专病路径信息 @@ -43,7 +43,7 @@ public interface ISpecialDiseaseRouteService { * @param specialDiseaseRoute 专病路径信息 * @return 结果 */ - int updateSpecialDiseaseRoute(SpecialDiseaseRoute specialDiseaseRoute); + AjaxResult updateSpecialDiseaseRoute(SpecialDiseaseRouteVO specialDiseaseRoute); /** * 批量删除专病路径信息 diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroute/impl/SpecialDiseaseRouteServiceImpl.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroute/impl/SpecialDiseaseRouteServiceImpl.java index bfa30904..1fb7affa 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroute/impl/SpecialDiseaseRouteServiceImpl.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroute/impl/SpecialDiseaseRouteServiceImpl.java @@ -6,14 +6,18 @@ import com.xinelu.common.enums.ReleaseStatusEnum; import com.xinelu.common.enums.RouteCheckStatusEnum; import com.xinelu.common.exception.ServiceException; import com.xinelu.common.utils.SecurityUtils; +import com.xinelu.common.utils.bean.BeanUtils; import com.xinelu.common.utils.codes.GenerateSystemCodeUtil; import com.xinelu.manage.domain.specialdiseaseroute.SpecialDiseaseRoute; +import com.xinelu.manage.domain.specialdiseaseroutepackage.SpecialDiseaseRoutePackage; import com.xinelu.manage.mapper.specialdiseasenode.SpecialDiseaseNodeMapper; import com.xinelu.manage.mapper.specialdiseaseroute.SpecialDiseaseRouteMapper; +import com.xinelu.manage.mapper.specialdiseaseroutepackage.SpecialDiseaseRoutePackageMapper; import com.xinelu.manage.mapper.specialdiseasetriggercondition.SpecialDiseaseTriggerConditionMapper; import com.xinelu.manage.service.specialdiseaseroute.ISpecialDiseaseRouteService; import com.xinelu.manage.vo.department.DepartmentVO; import com.xinelu.manage.vo.specialdiseaseroute.SpecialDiseaseRouteVO; +import com.xinelu.manage.vo.specialdiseaseroutepackage.SpecialDiseaseRoutePackageVO; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; @@ -41,6 +45,8 @@ public class SpecialDiseaseRouteServiceImpl implements ISpecialDiseaseRouteServi private SpecialDiseaseTriggerConditionMapper triggerConditionMapper; @Resource private GenerateSystemCodeUtil generateSystemCodeUtil; + @Resource + private SpecialDiseaseRoutePackageMapper specialDiseaseRoutePackageMapper; /** @@ -72,11 +78,31 @@ public class SpecialDiseaseRouteServiceImpl implements ISpecialDiseaseRouteServi * @return 结果 */ @Override - public int insertSpecialDiseaseRoute(SpecialDiseaseRoute specialDiseaseRoute) { + public AjaxResult insertSpecialDiseaseRoute(SpecialDiseaseRouteVO specialDiseaseRoute) { specialDiseaseRoute.setCreateTime(LocalDateTime.now()); specialDiseaseRoute.setCreateBy(SecurityUtils.getUsername()); specialDiseaseRoute.setRouteCode(Constants.ROUTE_CODE + generateSystemCodeUtil.generateSystemCode(Constants.ROUTE_CODE)); - return specialDiseaseRouteMapper.insertSpecialDiseaseRoute(specialDiseaseRoute); + int insertRouteCount = specialDiseaseRouteMapper.insertSpecialDiseaseRoute(specialDiseaseRoute); + if (insertRouteCount < 0) { + return AjaxResult.error("新增专病路径信息失败,请联系管理员!"); + } + List specialDiseaseRoutePackages = new ArrayList<>(); + SpecialDiseaseRoutePackage routePackage = new SpecialDiseaseRoutePackage(); + if (CollectionUtils.isNotEmpty(specialDiseaseRoute.getRoutePackageList())) { + for (SpecialDiseaseRoutePackage specialDiseaseRoutePackage : specialDiseaseRoute.getRoutePackageList()) { + specialDiseaseRoutePackage.setRouteId(specialDiseaseRoute.getId()); + specialDiseaseRoutePackage.setRouteName(specialDiseaseRoute.getRouteName()); + specialDiseaseRoutePackage.setCreateTime(LocalDateTime.now()); + specialDiseaseRoutePackage.setCreateBy(SecurityUtils.getUsername()); + BeanUtils.copyBeanProp(routePackage, specialDiseaseRoutePackage); + specialDiseaseRoutePackages.add(routePackage); + } + int insertRoutePackageCount = specialDiseaseRoutePackageMapper.insertSpecialDiseaseRoutePackageList(specialDiseaseRoutePackages); + if (insertRoutePackageCount < 0) { + return AjaxResult.error("新增专病路径信息失败,请联系管理员!"); + } + } + return AjaxResult.success(); } /** @@ -86,10 +112,33 @@ public class SpecialDiseaseRouteServiceImpl implements ISpecialDiseaseRouteServi * @return 结果 */ @Override - public int updateSpecialDiseaseRoute(SpecialDiseaseRoute specialDiseaseRoute) { + public AjaxResult updateSpecialDiseaseRoute(SpecialDiseaseRouteVO specialDiseaseRoute) { specialDiseaseRoute.setUpdateTime(LocalDateTime.now()); specialDiseaseRoute.setUpdateBy(SecurityUtils.getUsername()); - return specialDiseaseRouteMapper.updateSpecialDiseaseRoute(specialDiseaseRoute); + specialDiseaseRoute.setId(specialDiseaseRoute.getSpecialDiseaseRouteId()); + int updateRouteCount = specialDiseaseRouteMapper.updateSpecialDiseaseRoute(specialDiseaseRoute); + if (updateRouteCount < 0) { + return AjaxResult.error("修改专病路径信息失败,请联系管理员!"); + } + List specialDiseaseRoutePackages = new ArrayList<>(); + SpecialDiseaseRoutePackage routePackage = new SpecialDiseaseRoutePackage(); + if (CollectionUtils.isNotEmpty(specialDiseaseRoute.getRoutePackageList())) { + for (SpecialDiseaseRoutePackageVO specialDiseaseRoutePackage : specialDiseaseRoute.getRoutePackageList()) { + specialDiseaseRoutePackage.setUpdateTime(LocalDateTime.now()); + specialDiseaseRoutePackage.setUpdateBy(SecurityUtils.getUsername()); + BeanUtils.copyBeanProp(routePackage, specialDiseaseRoutePackage); + specialDiseaseRoutePackages.add(routePackage); + } + int insertRoutePackageCount = specialDiseaseRoutePackageMapper.insertSpecialDiseaseRoutePackageList(specialDiseaseRoutePackages); + if (insertRoutePackageCount < 0) { + return AjaxResult.error("修改专病路径信息失败,请联系管理员!"); + } + } + int deleteRoutePackageCount = specialDiseaseRoutePackageMapper.deleteSpecialDiseaseRoutePackageByRouteId(specialDiseaseRoute.getSpecialDiseaseRouteId()); + if (deleteRoutePackageCount < 0) { + return AjaxResult.error("修改专病路径信息失败,请联系管理员!"); + } + return AjaxResult.success(); } /** @@ -114,15 +163,19 @@ public class SpecialDiseaseRouteServiceImpl implements ISpecialDiseaseRouteServi public AjaxResult deleteSpecialDiseaseRouteById(Long id) { int deleteRouteCount = specialDiseaseRouteMapper.deleteSpecialDiseaseRouteById(id); if (deleteRouteCount < 0) { - throw new ServiceException("删除专病路径管理信息失败"); + throw new ServiceException("删除专病路径管理信息失败,请联系管理员!"); } int deleteNodeCount = specialDiseaseNodeMapper.deleteSpecialDiseaseNodeByRouteId(id); if (deleteNodeCount < 0) { - throw new ServiceException("删除专病路径管理信息失败"); + throw new ServiceException("删除专病路径管理信息失败,请联系管理员!"); } int deleteTriggerConditionCount = triggerConditionMapper.deleteSpecialDiseaseTriggerConditionByRouteId(id); if (deleteTriggerConditionCount < 0) { - throw new ServiceException("删除专病路径管理信息失败"); + throw new ServiceException("删除专病路径管理信息失败,请联系管理员!"); + } + int deleteRoutePackageCount = specialDiseaseRoutePackageMapper.deleteSpecialDiseaseRoutePackageByRouteId(id); + if (deleteRoutePackageCount < 0) { + return AjaxResult.error("删除专病路径管理信息失败,请联系管理员!"); } return AjaxResult.success(); } diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroutepackage/ISpecialDiseaseRoutePackageService.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroutepackage/ISpecialDiseaseRoutePackageService.java new file mode 100644 index 00000000..21700d11 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroutepackage/ISpecialDiseaseRoutePackageService.java @@ -0,0 +1,61 @@ +package com.xinelu.manage.service.specialdiseaseroutepackage; + +import com.xinelu.manage.domain.specialdiseaseroutepackage.SpecialDiseaseRoutePackage; + +import java.util.List; + +/** + * 专病路径-服务包关系(多对多关系)Service接口 + * + * @author xinelu + * @date 2024-04-09 + */ +public interface ISpecialDiseaseRoutePackageService { + /** + * 查询专病路径-服务包关系(多对多关系) + * + * @param id 专病路径-服务包关系(多对多关系)主键 + * @return 专病路径-服务包关系(多对多关系) + */ + SpecialDiseaseRoutePackage selectSpecialDiseaseRoutePackageById(Long id); + + /** + * 查询专病路径-服务包关系(多对多关系)列表 + * + * @param specialDiseaseRoutePackage 专病路径-服务包关系(多对多关系) + * @return 专病路径-服务包关系(多对多关系)集合 + */ + List selectSpecialDiseaseRoutePackageList(SpecialDiseaseRoutePackage specialDiseaseRoutePackage); + + /** + * 新增专病路径-服务包关系(多对多关系) + * + * @param specialDiseaseRoutePackage 专病路径-服务包关系(多对多关系) + * @return 结果 + */ + int insertSpecialDiseaseRoutePackage(SpecialDiseaseRoutePackage specialDiseaseRoutePackage); + + /** + * 修改专病路径-服务包关系(多对多关系) + * + * @param specialDiseaseRoutePackage 专病路径-服务包关系(多对多关系) + * @return 结果 + */ + int updateSpecialDiseaseRoutePackage(SpecialDiseaseRoutePackage specialDiseaseRoutePackage); + + /** + * 批量删除专病路径-服务包关系(多对多关系) + * + * @param ids 需要删除的专病路径-服务包关系(多对多关系)主键集合 + * @return 结果 + */ + int deleteSpecialDiseaseRoutePackageByIds(Long[] ids); + + /** + * 删除专病路径-服务包关系(多对多关系)信息 + * + * @param id 专病路径-服务包关系(多对多关系)主键 + * @return 结果 + */ + int deleteSpecialDiseaseRoutePackageById(Long id); +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroutepackage/impl/SpecialDiseaseRoutePackageServiceImpl.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroutepackage/impl/SpecialDiseaseRoutePackageServiceImpl.java new file mode 100644 index 00000000..371082a5 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroutepackage/impl/SpecialDiseaseRoutePackageServiceImpl.java @@ -0,0 +1,90 @@ +package com.xinelu.manage.service.specialdiseaseroutepackage.impl; + +import com.xinelu.manage.domain.specialdiseaseroutepackage.SpecialDiseaseRoutePackage; +import com.xinelu.manage.mapper.specialdiseaseroutepackage.SpecialDiseaseRoutePackageMapper; +import com.xinelu.manage.service.specialdiseaseroutepackage.ISpecialDiseaseRoutePackageService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 专病路径-服务包关系(多对多关系)Service业务层处理 + * + * @author xinelu + * @date 2024-04-09 + */ +@Service +public class SpecialDiseaseRoutePackageServiceImpl implements ISpecialDiseaseRoutePackageService { + @Resource + private SpecialDiseaseRoutePackageMapper specialDiseaseRoutePackageMapper; + + /** + * 查询专病路径-服务包关系(多对多关系) + * + * @param id 专病路径-服务包关系(多对多关系)主键 + * @return 专病路径-服务包关系(多对多关系) + */ + @Override + public SpecialDiseaseRoutePackage selectSpecialDiseaseRoutePackageById(Long id) { + return specialDiseaseRoutePackageMapper.selectSpecialDiseaseRoutePackageById(id); + } + + /** + * 查询专病路径-服务包关系(多对多关系)列表 + * + * @param specialDiseaseRoutePackage 专病路径-服务包关系(多对多关系) + * @return 专病路径-服务包关系(多对多关系) + */ + @Override + public List selectSpecialDiseaseRoutePackageList(SpecialDiseaseRoutePackage specialDiseaseRoutePackage) { + return specialDiseaseRoutePackageMapper.selectSpecialDiseaseRoutePackageList(specialDiseaseRoutePackage); + } + + /** + * 新增专病路径-服务包关系(多对多关系) + * + * @param specialDiseaseRoutePackage 专病路径-服务包关系(多对多关系) + * @return 结果 + */ + @Override + public int insertSpecialDiseaseRoutePackage(SpecialDiseaseRoutePackage specialDiseaseRoutePackage) { + specialDiseaseRoutePackage.setCreateTime(LocalDateTime.now()); + return specialDiseaseRoutePackageMapper.insertSpecialDiseaseRoutePackage(specialDiseaseRoutePackage); + } + + /** + * 修改专病路径-服务包关系(多对多关系) + * + * @param specialDiseaseRoutePackage 专病路径-服务包关系(多对多关系) + * @return 结果 + */ + @Override + public int updateSpecialDiseaseRoutePackage(SpecialDiseaseRoutePackage specialDiseaseRoutePackage) { + specialDiseaseRoutePackage.setUpdateTime(LocalDateTime.now()); + return specialDiseaseRoutePackageMapper.updateSpecialDiseaseRoutePackage(specialDiseaseRoutePackage); + } + + /** + * 批量删除专病路径-服务包关系(多对多关系) + * + * @param ids 需要删除的专病路径-服务包关系(多对多关系)主键 + * @return 结果 + */ + @Override + public int deleteSpecialDiseaseRoutePackageByIds(Long[] ids) { + return specialDiseaseRoutePackageMapper.deleteSpecialDiseaseRoutePackageByIds(ids); + } + + /** + * 删除专病路径-服务包关系(多对多关系)信息 + * + * @param id 专病路径-服务包关系(多对多关系)主键 + * @return 结果 + */ + @Override + public int deleteSpecialDiseaseRoutePackageById(Long id) { + return specialDiseaseRoutePackageMapper.deleteSpecialDiseaseRoutePackageById(id); + } +} diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/vo/specialdiseaseroute/SpecialDiseaseRouteVO.java b/postdischarge-manage/src/main/java/com/xinelu/manage/vo/specialdiseaseroute/SpecialDiseaseRouteVO.java index 2dffbb03..0b4408b6 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/vo/specialdiseaseroute/SpecialDiseaseRouteVO.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/vo/specialdiseaseroute/SpecialDiseaseRouteVO.java @@ -2,6 +2,7 @@ package com.xinelu.manage.vo.specialdiseaseroute; import com.xinelu.manage.domain.specialdiseaseroute.SpecialDiseaseRoute; import com.xinelu.manage.vo.specialdiseasenode.SpecialDiseaseNodeVO; +import com.xinelu.manage.vo.specialdiseaseroutepackage.SpecialDiseaseRoutePackageVO; import com.xinelu.manage.vo.specialdiseasetriggercondition.TriggerConditionVO; import lombok.Data; import lombok.EqualsAndHashCode; @@ -42,4 +43,6 @@ public class SpecialDiseaseRouteVO extends SpecialDiseaseRoute { * 触发条件信息 */ List triggerConditionList; + + List routePackageList; } \ No newline at end of file diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/vo/specialdiseaseroutepackage/SpecialDiseaseRoutePackageVO.java b/postdischarge-manage/src/main/java/com/xinelu/manage/vo/specialdiseaseroutepackage/SpecialDiseaseRoutePackageVO.java new file mode 100644 index 00000000..f56c93f3 --- /dev/null +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/vo/specialdiseaseroutepackage/SpecialDiseaseRoutePackageVO.java @@ -0,0 +1,18 @@ +package com.xinelu.manage.vo.specialdiseaseroutepackage; + +import com.xinelu.manage.domain.specialdiseaseroutepackage.SpecialDiseaseRoutePackage; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 专病路径-服务包关系(多对多关系)对象 special_disease_route_package + * + * @author xinelu + * @date 2024-04-09 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class SpecialDiseaseRoutePackageVO extends SpecialDiseaseRoutePackage { + + private Long specialDiseaseRoutePackageId; +} \ No newline at end of file diff --git a/postdischarge-manage/src/main/resources/mapper/manage/specialdiseaseroute/SpecialDiseaseRouteMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/specialdiseaseroute/SpecialDiseaseRouteMapper.xml index 3c6e1351..ccdef691 100644 --- a/postdischarge-manage/src/main/resources/mapper/manage/specialdiseaseroute/SpecialDiseaseRouteMapper.xml +++ b/postdischarge-manage/src/main/resources/mapper/manage/specialdiseaseroute/SpecialDiseaseRouteMapper.xml @@ -42,6 +42,8 @@ + @@ -56,6 +58,14 @@ + + + + + + + + select id, department_id, @@ -373,6 +383,11 @@ sdtc.trigger_condition_value, sdtc.trigger_condition_sort, sdtc.trigger_condition_remark, + sdrp.id specialDiseaseRoutePackageId, + sdrp.route_id, + sdrp.service_package_id, + sdrp.route_name, + sdrp.package_name, (select COUNT(1) from special_disease_node where route_id = specialDiseaseRouteId) totalNumber, @@ -383,6 +398,7 @@ from special_disease_route sdr LEFT JOIN special_disease_node sdn ON sdn.route_id = sdr.id LEFT JOIN special_disease_trigger_condition sdtc ON sdr.id = sdtc.route_id + LEFT JOIN special_disease_route_package sdrp ON sdr.id = sdrp.route_id where sdr.id = #{id} diff --git a/postdischarge-manage/src/main/resources/mapper/manage/specialdiseaseroutepackage/SpecialDiseaseRoutePackageMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/specialdiseaseroutepackage/SpecialDiseaseRoutePackageMapper.xml new file mode 100644 index 00000000..1181e795 --- /dev/null +++ b/postdischarge-manage/src/main/resources/mapper/manage/specialdiseaseroutepackage/SpecialDiseaseRoutePackageMapper.xml @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + select id, + route_id, + service_package_id, + route_name, + package_name, + create_by, + create_time, + update_by, + update_time + from special_disease_route_package + + + + + + + + insert into special_disease_route_package + + route_id, + + service_package_id, + + route_name, + + package_name, + + create_by, + + create_time, + + update_by, + + update_time, + + + + #{routeId}, + + #{servicePackageId}, + + #{routeName}, + + #{packageName}, + + #{createBy}, + + #{createTime}, + + #{updateBy}, + + #{updateTime}, + + + + + + update special_disease_route_package + + route_id = + #{routeId}, + + service_package_id = + #{servicePackageId}, + + route_name = + #{routeName}, + + package_name = + #{packageName}, + + create_by = + #{createBy}, + + create_time = + #{createTime}, + + update_by = + #{updateBy}, + + update_time = + #{updateTime}, + + + where id = #{id} + + + + delete + from special_disease_route_package + where id = #{id} + + + + delete from special_disease_route_package where id in + + #{id} + + + + + insert into special_disease_route_package( + route_id, + service_package_id, + route_name, + package_name, + create_by, + create_time + ) values + + ( + #{specialDiseaseRoutePackageList.routeId}, + #{specialDiseaseRoutePackageList.servicePackageId}, + #{specialDiseaseRoutePackageList.routeName}, + #{specialDiseaseRoutePackageList.packageName}, + #{specialDiseaseRoutePackageList.createBy}, + #{specialDiseaseRoutePackageList.createTime} + ) + + + + + delete + from special_disease_route_package + where route_id = #{routeId} + + \ No newline at end of file From ecc349d2135da0c9d669eee550572d99f1b7db61 Mon Sep 17 00:00:00 2001 From: zhangheng <3226558941@qq.com> Date: Tue, 9 Apr 2024 14:06:55 +0800 Subject: [PATCH 19/21] =?UTF-8?q?=E6=9C=BA=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agencycategory/AgencyCategoryMapper.java | 8 ++++++++ .../impl/AgencyCategoryServiceImpl.java | 7 +++---- .../impl/SpecialDiseaseRouteServiceImpl.java | 15 ++++++++------- .../agencycategory/AgencyCategoryMapper.xml | 6 ++++++ 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/agencycategory/AgencyCategoryMapper.java b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/agencycategory/AgencyCategoryMapper.java index 567d57af..c978e0d8 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/agencycategory/AgencyCategoryMapper.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/agencycategory/AgencyCategoryMapper.java @@ -21,6 +21,14 @@ public interface AgencyCategoryMapper { */ AgencyCategory selectAgencyCategoryById(Long id); + /** + * 查询机构类别 + * + * @param parentCategoryId 机构类别主键 + * @return 机构类别 + */ + AgencyCategory selectAgencyCategoryByParentCategoryId(Long parentCategoryId); + /** * 查询机构类别列表 * diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/agencycategory/impl/AgencyCategoryServiceImpl.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/agencycategory/impl/AgencyCategoryServiceImpl.java index e3ba6fa7..ee31a807 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/service/agencycategory/impl/AgencyCategoryServiceImpl.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/agencycategory/impl/AgencyCategoryServiceImpl.java @@ -1,9 +1,7 @@ package com.xinelu.manage.service.agencycategory.impl; -import com.xinelu.common.utils.DateUtils; import com.xinelu.common.utils.SecurityUtils; import com.xinelu.common.utils.StringUtils; -import com.xinelu.common.utils.codes.GenerateSystemCodeUtil; import com.xinelu.manage.domain.agencycategory.AgencyCategory; import com.xinelu.manage.mapper.agencycategory.AgencyCategoryMapper; import com.xinelu.manage.service.agencycategory.IAgencyCategoryService; @@ -61,8 +59,9 @@ public class AgencyCategoryServiceImpl implements IAgencyCategoryService { */ @Override public int insertAgencyCategory(AgencyCategory agencyCategory) { - if (Objects.isNull(agencyCategory.getCategoryLevel()) || agencyCategory.getCategoryLevel().equals(1)) { - agencyCategory.setParentCategoryId(null); + if (Objects.nonNull(agencyCategory.getParentCategoryId())) { + AgencyCategory parentAgencyCategory = agencyCategoryMapper.selectAgencyCategoryByParentCategoryId(agencyCategory.getParentCategoryId()); + agencyCategory.setCategoryLevel((parentAgencyCategory.getCategoryLevel() == null ? 0 : parentAgencyCategory.getCategoryLevel()) + 1); } agencyCategory.setCreateTime(LocalDateTime.now()); agencyCategory.setCreateBy(SecurityUtils.getUsername()); diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroute/impl/SpecialDiseaseRouteServiceImpl.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroute/impl/SpecialDiseaseRouteServiceImpl.java index 1fb7affa..44c2a65a 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroute/impl/SpecialDiseaseRouteServiceImpl.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/specialdiseaseroute/impl/SpecialDiseaseRouteServiceImpl.java @@ -87,9 +87,9 @@ public class SpecialDiseaseRouteServiceImpl implements ISpecialDiseaseRouteServi return AjaxResult.error("新增专病路径信息失败,请联系管理员!"); } List specialDiseaseRoutePackages = new ArrayList<>(); - SpecialDiseaseRoutePackage routePackage = new SpecialDiseaseRoutePackage(); if (CollectionUtils.isNotEmpty(specialDiseaseRoute.getRoutePackageList())) { for (SpecialDiseaseRoutePackage specialDiseaseRoutePackage : specialDiseaseRoute.getRoutePackageList()) { + SpecialDiseaseRoutePackage routePackage = new SpecialDiseaseRoutePackage(); specialDiseaseRoutePackage.setRouteId(specialDiseaseRoute.getId()); specialDiseaseRoutePackage.setRouteName(specialDiseaseRoute.getRouteName()); specialDiseaseRoutePackage.setCreateTime(LocalDateTime.now()); @@ -113,17 +113,22 @@ public class SpecialDiseaseRouteServiceImpl implements ISpecialDiseaseRouteServi */ @Override public AjaxResult updateSpecialDiseaseRoute(SpecialDiseaseRouteVO specialDiseaseRoute) { + int deleteRoutePackageCount = specialDiseaseRoutePackageMapper.deleteSpecialDiseaseRoutePackageByRouteId(specialDiseaseRoute.getId()); + if (deleteRoutePackageCount < 0) { + return AjaxResult.error("修改专病路径信息失败,请联系管理员!"); + } specialDiseaseRoute.setUpdateTime(LocalDateTime.now()); specialDiseaseRoute.setUpdateBy(SecurityUtils.getUsername()); - specialDiseaseRoute.setId(specialDiseaseRoute.getSpecialDiseaseRouteId()); int updateRouteCount = specialDiseaseRouteMapper.updateSpecialDiseaseRoute(specialDiseaseRoute); if (updateRouteCount < 0) { return AjaxResult.error("修改专病路径信息失败,请联系管理员!"); } List specialDiseaseRoutePackages = new ArrayList<>(); - SpecialDiseaseRoutePackage routePackage = new SpecialDiseaseRoutePackage(); if (CollectionUtils.isNotEmpty(specialDiseaseRoute.getRoutePackageList())) { for (SpecialDiseaseRoutePackageVO specialDiseaseRoutePackage : specialDiseaseRoute.getRoutePackageList()) { + SpecialDiseaseRoutePackage routePackage = new SpecialDiseaseRoutePackage(); + specialDiseaseRoutePackage.setRouteId(specialDiseaseRoute.getId()); + specialDiseaseRoutePackage.setRouteName(specialDiseaseRoute.getRouteName()); specialDiseaseRoutePackage.setUpdateTime(LocalDateTime.now()); specialDiseaseRoutePackage.setUpdateBy(SecurityUtils.getUsername()); BeanUtils.copyBeanProp(routePackage, specialDiseaseRoutePackage); @@ -134,10 +139,6 @@ public class SpecialDiseaseRouteServiceImpl implements ISpecialDiseaseRouteServi return AjaxResult.error("修改专病路径信息失败,请联系管理员!"); } } - int deleteRoutePackageCount = specialDiseaseRoutePackageMapper.deleteSpecialDiseaseRoutePackageByRouteId(specialDiseaseRoute.getSpecialDiseaseRouteId()); - if (deleteRoutePackageCount < 0) { - return AjaxResult.error("修改专病路径信息失败,请联系管理员!"); - } return AjaxResult.success(); } diff --git a/postdischarge-manage/src/main/resources/mapper/manage/agencycategory/AgencyCategoryMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/agencycategory/AgencyCategoryMapper.xml index 1c3e5876..cd00f2d9 100644 --- a/postdischarge-manage/src/main/resources/mapper/manage/agencycategory/AgencyCategoryMapper.xml +++ b/postdischarge-manage/src/main/resources/mapper/manage/agencycategory/AgencyCategoryMapper.xml @@ -67,6 +67,12 @@ where id = #{id} + + insert into agency_category From 263279e66dc896fb00c9ad221784fc46f3126233 Mon Sep 17 00:00:00 2001 From: zhangheng <3226558941@qq.com> Date: Tue, 9 Apr 2024 14:09:53 +0800 Subject: [PATCH 20/21] =?UTF-8?q?=E6=9C=BA=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/manage/agencycategory/AgencyCategoryMapper.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postdischarge-manage/src/main/resources/mapper/manage/agencycategory/AgencyCategoryMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/agencycategory/AgencyCategoryMapper.xml index cd00f2d9..062ff81d 100644 --- a/postdischarge-manage/src/main/resources/mapper/manage/agencycategory/AgencyCategoryMapper.xml +++ b/postdischarge-manage/src/main/resources/mapper/manage/agencycategory/AgencyCategoryMapper.xml @@ -70,7 +70,7 @@ Date: Tue, 9 Apr 2024 14:10:48 +0800 Subject: [PATCH 21/21] =?UTF-8?q?=E6=9C=BA=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/agencycategory/AgencyCategoryMapper.java | 8 -------- .../agencycategory/impl/AgencyCategoryServiceImpl.java | 2 +- .../mapper/manage/agencycategory/AgencyCategoryMapper.xml | 6 ------ 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/agencycategory/AgencyCategoryMapper.java b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/agencycategory/AgencyCategoryMapper.java index c978e0d8..567d57af 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/agencycategory/AgencyCategoryMapper.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/mapper/agencycategory/AgencyCategoryMapper.java @@ -21,14 +21,6 @@ public interface AgencyCategoryMapper { */ AgencyCategory selectAgencyCategoryById(Long id); - /** - * 查询机构类别 - * - * @param parentCategoryId 机构类别主键 - * @return 机构类别 - */ - AgencyCategory selectAgencyCategoryByParentCategoryId(Long parentCategoryId); - /** * 查询机构类别列表 * diff --git a/postdischarge-manage/src/main/java/com/xinelu/manage/service/agencycategory/impl/AgencyCategoryServiceImpl.java b/postdischarge-manage/src/main/java/com/xinelu/manage/service/agencycategory/impl/AgencyCategoryServiceImpl.java index ee31a807..c9fd7370 100644 --- a/postdischarge-manage/src/main/java/com/xinelu/manage/service/agencycategory/impl/AgencyCategoryServiceImpl.java +++ b/postdischarge-manage/src/main/java/com/xinelu/manage/service/agencycategory/impl/AgencyCategoryServiceImpl.java @@ -60,7 +60,7 @@ public class AgencyCategoryServiceImpl implements IAgencyCategoryService { @Override public int insertAgencyCategory(AgencyCategory agencyCategory) { if (Objects.nonNull(agencyCategory.getParentCategoryId())) { - AgencyCategory parentAgencyCategory = agencyCategoryMapper.selectAgencyCategoryByParentCategoryId(agencyCategory.getParentCategoryId()); + AgencyCategory parentAgencyCategory = agencyCategoryMapper.selectAgencyCategoryById(agencyCategory.getParentCategoryId()); agencyCategory.setCategoryLevel((parentAgencyCategory.getCategoryLevel() == null ? 0 : parentAgencyCategory.getCategoryLevel()) + 1); } agencyCategory.setCreateTime(LocalDateTime.now()); diff --git a/postdischarge-manage/src/main/resources/mapper/manage/agencycategory/AgencyCategoryMapper.xml b/postdischarge-manage/src/main/resources/mapper/manage/agencycategory/AgencyCategoryMapper.xml index 062ff81d..1c3e5876 100644 --- a/postdischarge-manage/src/main/resources/mapper/manage/agencycategory/AgencyCategoryMapper.xml +++ b/postdischarge-manage/src/main/resources/mapper/manage/agencycategory/AgencyCategoryMapper.xml @@ -67,12 +67,6 @@ where id = #{id} - - insert into agency_category