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

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

一.數據庫設計

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) {}
}

九.具體行為調用代碼類

@Overridepublic void bindPicpCustomer(AppointClinicBindReq req, UserTokenInfoDTO userTokenInfoDTO) {AppointPO appointPO = Optional.ofNullable(appointRepository.getOnePOById(req.getAppointmentId())).orElseThrow(() ->new BusinessException(ResultEnum.PARAM_ERROR, "預約單數據不存在或已被刪除"));AppointHandleContext handleContext = new AppointHandleContext();handleContext.setStatusHandler(AppointStatusHandlerFactory.getStatusHandler(AppointStatusEnum.getEnum(appointPO.getStatus())));handleContext.bindPicpCustomer(handleContext, AppointContext.builder().appointPO(appointPO).clientEnum(appointSupport.getLoginClientEnum(userTokenInfoDTO)).userTokenInfoDTO(userTokenInfoDTO).picpUsers(req.getPicpUsers()).build());}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/38633.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/38633.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/38633.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

實現膠囊神經網絡,識別手寫MNIST數據集,談談實現及理解。

&#x1f3c6;本文收錄于《CSDN問答解答》專欄&#xff0c;主要記錄項目實戰過程中的Bug之前因后果及提供真實有效的解決方案&#xff0c;希望能夠助你一臂之力&#xff0c;幫你早日登頂實現財富自由&#x1f680;&#xff1b;同時&#xff0c;歡迎大家關注&&收藏&…

稀疏數組Java練習代碼含IO

是在學習尚硅谷的數據結構與算法Java課程&#xff0c;課后自己憑借思路寫的練習代碼 首先定義一個稀疏數組類 import java.io.*; import java.util.Objects;public class SparseArray {int sum;//創建原始數組public int[][] createArray(int column, int row){//根據傳入數據…

雨量氣象站:野外監測的得力助手

在廣闊無垠的大自然中&#xff0c;雨量、風力、風向、溫濕度以及大氣壓力等氣象數據對于各種應用場景都至關重要。特別是在野外、森林防火、山洪監測等無市電供電的場合&#xff0c;一款高效可靠的監測設備更是不可或缺。雨量氣象站正是為了滿足這些需求而誕生的戶外專用監測站…

C++ STL unique_ptr智能指針源碼剖析

由于上一篇博客將shared_ptr,weak_ptr,enable_shared_form_this的源碼實現整理了一遍,想著cpp智能指針還差個unique_ptr故寫下此篇博客,以供學習 源碼剖析 一,模板參數 首先,我們先看unique_ptr的模板參數,第一個參數_TP自是不用說表示對象類型,第二個模板參數定義了unique_p…

FFmpeg視頻處理工具安裝使用

一、前言 FFmpeg是流行的開源視頻處理工具&#xff0c;用于轉碼、合并、編輯等。以下是安裝和使用方法&#xff1a; 二、步驟 1.下載 1.1 ffmpeg下載 官網下載地址 wget https://www.ffmpeg.org/releases/ffmpeg-6.1.1.tar.xz1.2 nasm下載 https://www.nasm.us/pub/nasm/…

Android應用安裝過程

Android 系統源碼源碼-應用安裝過程 Android 中應用安裝的過程就是解析 AndroidManifest.xml 的過程&#xff0c;系統可以從 Manifest 中得到應用程序的相關信息&#xff0c;比如 Activity、Service、Broadcast Receiver 和 ContentProvider 等。這些工作都是由 PackageManage…

drm core

drm core初始化 /*** drm_sysfs_init - initialize sysfs helpers** This is used to create the DRM class, which is the implicit parent of any* other top-level DRM sysfs objects.** You must call drm_sysfs_destroy() to release the allocated resources.** Return: …

Linux通配符及其在文件搜索和管理中的應用

Linux通配符及其在文件搜索和管理中的應用 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 1. 了解Linux通配符 在Linux系統中&#xff0c;通配符是一種用于匹…

家政小程序的開發,帶動市場快速發展,提高家政服務質量

當下生活水平逐漸提高&#xff0c;也增加了年輕人的工作壓力&#xff0c;同時老齡化也在日益增加&#xff0c;使得大眾對家政的需求日益提高&#xff0c;能力、服務質量高的家政人員能夠有效提高大眾的生活幸福指數。 但是&#xff0c;傳統的家政服務模式存在著效率低、用戶與…

慧翰股份毛利率下滑:股權轉讓糾紛引關注,研發費用率遠弱同行還買樓?

《港灣商業觀察》施子夫 6月11日&#xff0c;慧翰微電子股份有限公司&#xff08;以下簡稱&#xff0c;慧翰股份&#xff09;IPO注冊申請獲證監會同意&#xff0c;預計公司將很快登陸深交所創業板&#xff0c;保薦機構為廣發證券。 從業績面來看&#xff0c;過去三年&#xf…

基于X86+FPGA+AI的芯片缺陷檢測方案

應用場景 隨著半導體技術的發展&#xff0c;對芯片的良率要求越來越高。然而集成電路芯片制造工藝復雜&#xff0c;其制造過程中往往產生很多缺陷&#xff0c;因此缺陷檢測是集成電路制造過程中的必備工藝。 客戶需求 小體積&#xff0c;低功耗 2 x USB,1 x LAN Core-i平臺無…

JavaScript——運算符的優先級和結合性

目錄 任務描述 相關知識 運算符的優先級 運算符的結合性 編程要求 任務描述 本關任務&#xff1a;我們將給出函數mainJs()的完整代碼&#xff0c;要求在函數體內第三句以及第五句中添加適當的括號&#xff0c;實現編程要求里面的要求。 要想完成本關任務&#xff0c;必須…

一點連接千家銀行,YonSuite讓“銀企對賬”一鍵確認

在當今數智化浪潮下&#xff0c;成長型企業面臨著前所未有的機遇與挑戰。特別是在與銀行的對接以及銀企對賬等方面&#xff0c;傳統的手動操作模式已難以滿足企業高效、安全的金融管理需求。用友YonSuite作為一款全場景SaaS應用服務&#xff0c;憑借其強大的銀企直聯功能&#…

AI在線免費視頻工具3:聲音生視頻

1、聲音生視頻 Noisee&#xff1a;通過聲音生成對應視頻&#xff0c;可以增加prompt指定生成內容相關視頻 https://noisee.ai/create

【基礎篇】第5章 Elasticsearch 數據聚合與分析

在Elasticsearch的龐大功能體系中&#xff0c;數據聚合與分析扮演著至關重要的角色&#xff0c;它使我們能夠從海量數據中提煉出有價值的信息&#xff0c;為決策提供依據。本章將深入探討Elasticsearch的聚合功能&#xff0c;從基本概念到常見類型的實踐&#xff0c;讓你掌握如…

Elasticsearch 使用誤區之二——頻繁更新文檔

在使用 Elasticsearch 時&#xff0c;頻繁更新文檔是一種常見誤區。這不僅影響性能&#xff0c;還可能導致系統資源的浪費。 理解 Elasticsearch 的文檔更新機制對于優化性能至關重要。 關于 Elasticsearch 更新操作&#xff0c;常見問題如下&#xff1a; ——https://t.zsxq.c…

Spring Cloud實戰:構建分布式系統解決方案

Spring Cloud實戰&#xff1a;構建分布式系統解決方案 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01;今天我們將深入探討如何使用Spring Cloud來構建分布式系統…

剖析DeFi交易產品之UniswapV4:概述篇

本文首發于公眾號&#xff1a;Keegan小鋼 UniswapV4 與 UniswapV3 相比&#xff0c;算法上并沒有什么改變&#xff0c;依然還是采用集中流動性模型&#xff0c;但架構上變化很大&#xff0c;包括功能架構&#xff0c;也包括技術架構。相比之前的版本&#xff0c;UniswapV4 最大…

百元藍牙耳機推薦2024,百元藍牙耳機排行榜盤點

在2024年面對琳瑯滿目的藍牙耳機選項&#xff0c;消費者往往難以抉擇&#xff0c;特別是在預算有限的情況下&#xff0c;如何在眾多產品中挑選出既滿足質量又符合預算的耳機成為了一個不小的挑戰。 為了幫助大家在繁多的選擇中找到真正物有所值的百元藍牙耳機&#xff0c;我們…

UnityUGUI之一:image和Rawimage

image組件的相關屬性 其中SpriteMode&#xff0c;若為單個圖片則為Single&#xff0c;圖片集則為Multiple 圖集的切割 點擊Slice可以進行自動切割 為且每個格子都可以進行單獨的九宮格切割 當圖片被九宮格切割再進行拉伸以后&#xff0c;九宮格的四角不會被拉伸 Tiled&#x…