设计模式(实际项目)-状态机模式

需求背景:存在状态流转的预约单

一.数据库设计

CREATE TABLE `appointment` (`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',`appoint_type` int(11) NOT NULL COMMENT '预约类型(0:线下查房...)',`appoint_user_id` bigint(20) NOT NULL COMMENT '预约人userId',`appoint_store_id` bigint(20) NOT NULL COMMENT '预约门店',`appoint_service_type` int(11) DEFAULT NULL COMMENT '预约服务类型(9:儿科查房 7:产科查房 8:中医查房)',`appoint_doctor_id` bigint(11) DEFAULT NULL COMMENT '预约医生id',`appoint_date` date DEFAULT NULL COMMENT '预约日期(精确到日)',`appoint_time_start` time NOT NULL COMMENT '预约开始时间',`appoint_time_end` time NOT NULL COMMENT '预约结束时间',`status` int(11) NOT NULL COMMENT '状态(-1:已取消 0:待接单 1:待分配(已拒绝) 2:待查房 3:待小结 4:待签名 100:已完成 )',`drive_appointment_id` bigint(20) DEFAULT NULL COMMENT '驱动预约单id(null:代表驱动预约单)',`appointment_setting_id` bigint(20) DEFAULT NULL COMMENT '预约单-配置id',`create_id` bigint(20) DEFAULT NULL COMMENT '创建人id',`gmt_create` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`modify_id` bigint(20) DEFAULT NULL COMMENT '修改人',`gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',`deleted` tinyint(1) DEFAULT '0' COMMENT '删除标记;0-正常 ;1-删除',PRIMARY KEY (`id`),KEY `idx_drive_appointment_id` (`drive_appointment_id`) USING BTREE,KEY `idx_appointment_setting_id` (`appointment_setting_id`) USING BTREE,KEY `idx_appoint_user_id` (`appoint_user_id`) USING BTREE
)  AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4  COMMENT='预约单';-- 预约单-状态流转表CREATE TABLE `stbella-his`.appointment_status_log
( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',appointment_id    bigint(20)						not null COMMENT '预约单id',before_status 	  int(11)							  NOT null COMMENT '前状态',after_status 	    int(11)							  NOT null COMMENT '后状态',handle_type       int(11)								not null COMMENT '操作类型',handle_user_type    int(11)					    not null COMMENT '操作人类型',create_id bigint(20) DEFAULT NULL COMMENT '创建人id',gmt_create datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',modify_id bigint(20) DEFAULT NULL COMMENT '修改人',gmt_modified datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',deleted tinyint(1) DEFAULT '0' COMMENT '删除标记;0-正常 ;1-删除',PRIMARY KEY (`id`),KEY `idx_appointment_id` (`appointment_id`) USING BTREE
)  comment '预约单-状态流转表'; 

二.状态枚举类

@Getter
@AllArgsConstructor
public enum AppointStatusEnum {INIT(-100, "初始化"),CANCEL(-1, "已取消"),WAIT_RECEIVE(0, "待接单"),WAIT_DISTRIBUTE(1, "待分配"),WAIT_CHECK_ROOM(2, "待查房"),WAIT_SUMMARY(3, "待小结"),WAIT_SIGN(4, "待签名"),COMPLETE(100, "已完成");private final int code;private final String name;public static AppointStatusEnum getEnum(int code) {for (AppointStatusEnum statusEnum : AppointStatusEnum.values()) {if (statusEnum.getCode() == code) {return statusEnum;}}return null;}}

三. 上下文参数类:参数传递

@Builder
@Data
public class AppointContext implements Serializable {private static final long serialVersionUID = 3542771730176821092L;private UserTokenInfoDTO userTokenInfoDTO;private ClientEnum clientEnum;private AppointPO appointPO;}

四.状态机流转上下文类:所有要执行的动作都在这里记录

@Data
public class AppointHandleContext implements Serializable {private static final long serialVersionUID = 1658366511210864400L;private IAppointStatusHandler statusHandler = AppointStatusHandlerFactory.getStatusHandler(AppointStatusEnum.INIT);public AppointDetailVO detail(AppointHandleContext handleContext, public Boolean cancel(AppointHandleContext handleContext, AppointContext context) {return statusHandler.cancel(handleContext, context);}public String add(AppointHandleContext handleContext, AppointContext context) {return statusHandler.add(handleContext, context);}public Boolean update(AppointHandleContext handleContext, AppointContext context) {return statusHandler.update(handleContext, context);}}

五.状态处理器工厂类

@Component
public class AppointStatusHandlerFactory implements ApplicationContextAware {private static final Map<AppointStatusEnum, IAppointStatusHandler> MAP = Maps.newHashMapWithExpectedSize(AppointStatusEnum.values().length);@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {Map<String, IAppointStatusHandler> beansOfType = applicationContext.getBeansOfType(IAppointStatusHandler.class);if (CollectionUtil.isEmpty(beansOfType)) {return;}beansOfType.forEach((key, statusHandler) -> MAP.put(statusHandler.getStatus(), statusHandler));}public static IAppointStatusHandler getStatusHandler(AppointStatusEnum appointStatusEnum) {return Optional.ofNullable(MAP.get(appointStatusEnum)).orElseThrow(() -> new BusinessException(ResultEnum.PARAM_ERROR, "预约单状态异常"));}}

六.状态接口类

public interface IAppointStatusHandler {AppointStatusEnum getStatus();AppointDetailVO detail(AppointHandleContext handleContext, AppointContext context);Boolean cancel(AppointHandleContext handleContext, AppointContext context);String add(AppointHandleContext handleContext, AppointContext context);Boolean update(AppointHandleContext handleContext, AppointContext context);」

七.状态抽象实现类

@Slf4j
@Component
public abstract class AbstractAppointStatusHandler implements IAppointStatusHandler {private static final String LOG_PRE = "预约单状态流转异常,method:{},handleContext:{},context:{}";@Overridepublic AppointDetailVO detail(AppointHandleContext handleContext, AppointContext context) {log.error(LOG_PRE, "detail", JSONUtil.toJsonStr(handleContext), JSONUtil.toJsonStr(context));throw new BusinessException(ResultEnum.PARAM_ERROR, "当前状态不允许查询");}@Overridepublic Boolean cancel(AppointHandleContext handleContext, AppointContext context) {log.error(LOG_PRE, "cancel", JSONUtil.toJsonStr(handleContext), JSONUtil.toJsonStr(context));throw new BusinessException(ResultEnum.PARAM_ERROR, "当前状态不允许取消");}@Overridepublic String add(AppointHandleContext handleContext, AppointContext context) {log.error(LOG_PRE, "add", JSONUtil.toJsonStr(handleContext), JSONUtil.toJsonStr(context));throw new BusinessException(ResultEnum.PARAM_ERROR, "当前状态不允许新增");}@Overridepublic Boolean update(AppointHandleContext handleContext, AppointContext context) {log.error(LOG_PRE, "update", JSONUtil.toJsonStr(handleContext), JSONUtil.toJsonStr(context));throw new BusinessException(ResultEnum.PARAM_ERROR, "当前状态不允许修改");}
}

八.每个状态节点实现类

@Slf4j
@Component
public class AppointInitHandler extends AbstractAppointStatusHandler {@Overridepublic AppointStatusEnum getStatus() {return AppointStatusEnum.INIT;}@Overridepublic AppointDetailVO detail(AppointHandleContext handleContext, AppointContext context) {return appointSupport.detail(context);}@Overridepublic String add(AppointHandleContext handleContext, AppointContext context) {}}
@Slf4j
@Component
public class AppointWaitCheckRoomHandler extends AbstractAppointStatusHandler {@Overridepublic AppointStatusEnum getStatus() {return AppointStatusEnum.WAIT_CHECK_ROOM;}@Resourceprivate AppointSupport appointSupport;@Overridepublic AppointDetailVO detail(AppointHandleContext handleContext, AppointContext context) {AppointDetailVO detail = appointSupport.detail(context);ClientEnum clientEnum = context.getClientEnum();AppointPO appointPO = context.getAppointPO();switch (clientEnum) {case HIS_NURSE:this.nurseDetail(detail, appointPO);break;case HIS_DOCTOR:this.doctorDetail(detail, appointPO);break;default:break;}return detail;}@Overridepublic Boolean cancel(AppointHandleContext handleContext, AppointContext context) {return appointSupport.handleOnlyStatus(context, AppointStatusEnum.CANCEL, AppointHandleTypeEnum.CANCEL);}@Overridepublic Boolean startCheckRoom(AppointHandleContext handleContext, AppointContext context) {return appointSupport.handleOnlyStatus(context, AppointStatusEnum.WAIT_SUMMARY, AppointHandleTypeEnum.START_CHECK_ROOM);}
@Slf4j
@Component
public class AppointCompleteHandler extends AbstractAppointStatusHandler {@Overridepublic AppointStatusEnum getStatus() {return AppointStatusEnum.COMPLETE;}@Overridepublic AppointDetailVO detail(AppointHandleContext handleContext, AppointContext context) {AppointDetailVO detail = appointSupport.detail(context);ClientEnum clientEnum = context.getClientEnum();AppointPO appointPO = context.getAppointPO();switch (clientEnum) {case HIS_NURSE:this.nurseDetail(detail, appointPO);break;case HIS_DOCTOR:this.doctorDetail(detail, appointPO);break;default:break;}return detail;}@Overridepublic AppointCheckRoomSignNotifyVO getAppointCheckRoomSignNotifyVO(AppointHandleContext handleContext, AppointContext context) {}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/36727.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

研导智能科技——AI辅助科研产品开发

人工智能&#xff08;AI&#xff09;技术的飞速发展为科研领域带来了革命性的变化。本公司致力于开发基于人工智能的科研辅助产品&#xff0c;旨在通过智能化手段提高科研人员的工作效率和研究质量。目前&#xff0c;我们成功开发了研导学术平台&#xff08;www.zhiyanxueshu.c…

Linux运维:MySQL数据库(1)

1.信息与数据&#xff1a; 数据是信息的载体&#xff0c;信息是数据的内涵。数据库就是存储数据的仓库&#xff0c;并长期存储在计算机磁盘中&#xff0c;可由多个用户和应用程序共享的数据集合&#xff0c;就是数据库。 2.数据库中的数据的特点&#xff1a; 2.1.数据是按照某…

RuleApp1.4.6文章社区客户端 广告联盟支持Docx导入

支持编译为安卓&#xff0c;苹果&#xff0c;小程序&#xff0c;H5网页的社区客户端代码&#xff0c;包括文章模块&#xff0c;用户模块&#xff0c;动态模块&#xff0c;支付模块&#xff0c;聊天模块&#xff0c;广告模块&#xff0c;商城模块等基础功能&#xff0c;包含VIP会…

C++的模板(九):模板的实例化问题

前文子系统中的例子&#xff0c; SubSystem内部用了STL库的map模板: template <class Event, class Response> class SubSystem{ public:map<Event*, Response*> table; public:void bind(Event *e, Response *r);void unbind(Event *e); public:int OnMessage(E…

10位时间戳、13位时间戳、17位时间戳,以及在JavaScript中的格式转换

一、介绍 1、10位时间戳 2、13位时间戳 3、17位时间戳 4、时间戳转换工具 二、13位时间戳的转换 1、转标准日期 2、转格式化日期 三、10位时间戳的转换 1、转标准日期 2、转格式化日期 四、17位时间戳的转换 1、解析思路 2、解析过程 &#xff08;1&#xff09;统…

C++系统编程篇——Linux第一个小程序--进度条

&#xff08;1&#xff09;先引入一个概念&#xff1a;行缓冲区 \r和\n \r表示回车 \n表示回车并换行 ①代码一 #include<stdio.h> #include<unistd.h> int main()…

django学习入门系列之第三点《伪类简单了解》

文章目录 hover&#xff08;伪类&#xff09;after&#xff08;伪类&#xff09;往期回顾 hover&#xff08;伪类&#xff09; 伪类指的是用冒号加的 hover样式指的是&#xff0c;当用户光标移动到设定区域后&#xff0c;所执行的用法 如&#xff1a; <!DOCTYPE html>…

【C语言】函数无参数有返回值、有参数无返回值、有参数有返回值

文章目录 前言C语言函数的分类和使用无参数有返回值的函数有参数无返回值的函数有参数有返回值的函数 总结 前言 在C语言中&#xff0c;函数是一种重要的组织代码的方式。根据函数的参数和返回值&#xff0c;我们可以将函数分为三类&#xff1a;无参数有返回值、有参数无返回值…

清理未使用的镜像和容器

删除未使用的镜像和容器&#xff1a; docker system prune -a清理构建缓存&#xff1a; Docker 会缓存构建过程中使用的中间镜像&#xff0c;可以通过以下命令清理它们&#xff1a; docker builder prune定期清理旧镜像&#xff1a; 定期运行以下命令清理旧镜像&#xff1a; …

通过代理从ARDUINO IDE直接下载开发板包

使用免费代理 实现ARDUINO IDE2.3.2 下载ESP8266/ESP32包 免费代理 列表 测试代理是否可用的 网站 有时&#xff0c;代理是可用的&#xff0c;但依然有可能找不到开发板管理器的资料包。 可以多换几个代理试试。 代理的配置 文件 -> 首选项 -> 网络 进入后做如下配置…

2024百度之星第二场-小度的01串

补题链接&#xff1a; 码蹄集 一道经典线段树板子题。 区间修改01置换&#xff0c;区间查询子串权值。 唯一区别&#xff0c;权值要求的是相邻字符都不同所需修改的最小字符个数。 我们在线段树节点上分别维护当前连续区间&#xff1a; 奇数位是0的个数&#xff08;j0&…

K8S两种安装方式如何选择?

K8S两种安装方式如何选择&#xff1f;\nKubeadm VS kubernetes 二进制\n\n1、kubeadm 方式部署&#xff08;推荐&#xff09;\n推荐理由&#xff1a;\n\n官方推荐&#xff1a;kubeadm 是 Kubernetes 官方提供的工具&#xff0c;用于快速搭建生产级别的 Kubernetes 集群&#xf…

python读取hdf4文件

记录一下使用xarray读取hdf4&#xff08;not hdf5&#xff09;过程中遇到的问题. 目的: 读取hdf4 file的matadata遇到的问题&#xff1a;使用xarray.open_dataset()失败解决方法&#xff1a;使用pyhdf.SD代替 import os from pyhdf.SD import SD, SDC import xarray as xr im…

ios CCNSDate.m

// // CCNSDate.h // CCFC // // Created by xichen on 11-12-17. // Copyright 2011年 ccteam. All rights reserved. //#import <Foundation/Foundation.h>interface NSDate(cc)// 获取系统时间(yyyy-MM-dd HH:mm:ss.SSS格式)(NSString *)getSystemTimeStr;// prin…

记录Spring Boot中的API请求参数读取方式

一、背景 项目开发中经常使用Spring Boot开发API&#xff0c;所以读取请求参数是服务端编码中最基本最常见的操作项&#xff0c;Spring Boot中也提供多种机制来满足不同的API设计要求。接下来就记录一下项目中用过的6种请求参数读取方式。 RequestParam 用来加载请求URL中&q…

2024年6月24日-6月30日(ue5肉鸽视频p16-p25)

试过重点放在独立游戏上&#xff0c;有个indienova独立游戏团队是全职的&#xff0c;由于他们干了几个月&#xff0c;节奏暂时跟不上&#xff0c;紧张焦虑了。五一时也有点自暴自弃了&#xff0c;实在没必要&#xff0c;按照自己的节奏走即可。精力和时间也有限&#xff0c;放在…

Python和tkinter实现的字母记忆配对游戏

Python和tkinter实现的字母记忆配对游戏 因为这个小游戏用到了tkinter&#xff0c;先简要介绍一下它。tkinter是Python的标准GUI(图形用户界面)库&#xff0c;它提供了一种简单而强大的方式来创建图形界面应用程序。它提供了创建基本图形界面所需的所有工具&#xff0c;同时保…

OSI七层模型TCP/IP四层面试高频考点

OSI七层模型&TCP/IP四层&面试高频考点 1 OSI七层模型 1. 物理层&#xff1a;透明地传输比特流 在物理媒介上传输原始比特流&#xff0c;定义了连接主机的硬件设备和传输媒介的规范。它确保比特流能够在网络中准确地传输&#xff0c;例如通过以太网、光纤和无线电波等媒…

什么是有效的电子签名?PDF电子签名怎样具备法律效力?

电子签名逐渐成为商务文书和法律文件中不可或缺的一部分。《电子签名法》自2005年4月1日起施行&#xff0c;这一立法是中国信息化法律的重要里程碑&#xff0c;为电子签名应用奠定了法律基础。电子签名不仅仅是一种技术手段&#xff0c;更是一种法律认可的签名形式。那么究竟什…

js生成UUID确保数据的唯一性

在JavaScript中&#xff0c;生成UUID&#xff08;Universally Unique Identifier&#xff09;通常用于确保数据的唯一性。 以下是一个简单的使用JavaScript生成UUID的示例&#xff0c;它基于RFC 4122版本4&#xff08;随机UUID&#xff09;的算法&#xff1a; function gener…