設計模式(實際項目)-狀態機模式

需求背景:存在狀態流轉的預約單

一.數據庫設計

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.pswp.cn/diannao/36727.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/36727.shtml
英文地址,請注明出處:http://en.pswp.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…