-- ============================================================================== -- 数据库变更脚本:多药房独立药品与库存隔离方案 -- 适用系统:hospital-applets-api -- 执行说明: -- 1. 本脚本默认表前缀为 `gdxz_`,若数据库未配置表前缀,请全局替换删除 `gdxz_`。 -- 2. 请在业务低峰期执行,按顺序分批执行:第一部分(新建表)-> 第二部分(修改表)-> 第三部分(数据回填初始化)。 -- 3. 脚本具有幂等性设计(IF NOT EXISTS / ON DUPLICATE KEY UPDATE)。 -- ============================================================================== -- ============================================================================== -- 第一部分:新建两张药房核心表 -- ============================================================================== -- 1.1 药房基础信息表(gdxz_pharmacy) CREATE TABLE IF NOT EXISTS `gdxz_pharmacy` ( `pharmacy_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '药房ID(雪花算法ID,0表示系统默认/老数据)', `pharmacy_name` varchar(128) NOT NULL DEFAULT '' COMMENT '药房名称', `pharmacy_code` varchar(64) NOT NULL DEFAULT '' COMMENT '药房编码(对接第三方药房的thirdCode/pharmacyCode)', `postage` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '基础运费/邮费(单位:元)', `free_shipping_threshold` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '满额包邮门槛(单位:元,0表示不免邮)', `is_pickup` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否支持到店自提(0:不支持 1:支持)', `telephone` varchar(32) NOT NULL DEFAULT '' COMMENT '药房联系电话', `province` varchar(64) NOT NULL DEFAULT '' COMMENT '省份名称', `city` varchar(64) NOT NULL DEFAULT '' COMMENT '城市名称', `county` varchar(64) NOT NULL DEFAULT '' COMMENT '区县名称', `address` varchar(255) NOT NULL DEFAULT '' COMMENT '详细地址', `pickup_address` varchar(255) NOT NULL DEFAULT '' COMMENT '自提详细地址', `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0:禁用 1:启用)', `created_at` datetime DEFAULT NULL COMMENT '创建时间', `updated_at` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`pharmacy_id`), UNIQUE KEY `uk_pharmacy_code` (`pharmacy_code`), KEY `idx_status` (`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='药房基础信息表'; -- 1.2 医生-药房关联表(gdxz_doctor_pharmacy) CREATE TABLE IF NOT EXISTS `gdxz_doctor_pharmacy` ( `doctor_pharmacy_id` bigint(20) unsigned NOT NULL COMMENT '关联主键ID(雪花算法ID)', `doctor_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '医生ID', `pharmacy_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '药房ID', `is_default` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否默认药房(0:否 1:是)', `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0:禁用/解绑 1:正常)', `created_at` datetime DEFAULT NULL COMMENT '创建时间', `updated_at` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`doctor_pharmacy_id`), UNIQUE KEY `uk_doctor_pharmacy` (`doctor_id`, `pharmacy_id`), KEY `idx_doctor_default` (`doctor_id`, `is_default`, `status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='医生-药房绑定关联表'; -- ============================================================================== -- 第二部分:现有业务表字段扩展(ALTER TABLE) -- ============================================================================== -- 2.1 处方主表增加药房快照字段(gdxz_order_prescription) ALTER TABLE `gdxz_order_prescription` ADD COLUMN `pharmacy_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '开方药房ID' AFTER `doctor_advice`, ADD COLUMN `pharmacy_code` varchar(64) NOT NULL DEFAULT '' COMMENT '开方药房编码' AFTER `pharmacy_id`, ADD COLUMN `pharmacy_name` varchar(128) NOT NULL DEFAULT '' COMMENT '开方药房名称' AFTER `pharmacy_code`, ADD KEY `idx_pharmacy_code` (`pharmacy_code`); -- 2.2 药品订单表增加药房快照及配送类型字段(gdxz_order_product) ALTER TABLE `gdxz_order_product` ADD COLUMN `pharmacy_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '所属药房ID' AFTER `logistics_fee`, ADD COLUMN `pharmacy_code` varchar(64) NOT NULL DEFAULT '' COMMENT '所属药房编码' AFTER `pharmacy_id`, ADD COLUMN `pharmacy_name` varchar(128) NOT NULL DEFAULT '' COMMENT '所属药房名称' AFTER `pharmacy_code`, ADD COLUMN `delivery_type` tinyint(1) NOT NULL DEFAULT '2' COMMENT '配送方式(1:到店自提 2:快递配送)' AFTER `pharmacy_name`, ADD KEY `idx_pharmacy_code` (`pharmacy_code`), ADD KEY `idx_delivery_type` (`delivery_type`); -- 2.3 药品表增加所属药房隔离字段(gdxz_product) ALTER TABLE `gdxz_product` ADD COLUMN `pharmacy_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '所属药房ID' AFTER `product_platform_id`, ADD COLUMN `pharmacy_code` varchar(64) NOT NULL DEFAULT '' COMMENT '所属药房编码' AFTER `pharmacy_id`, ADD KEY `idx_pharmacy_code` (`pharmacy_code`); -- 2.4 处方平台药品目录表增加第三方药房编码(gdxz_product_platform) ALTER TABLE `gdxz_product_platform` ADD COLUMN `pharmacy_code` varchar(64) NOT NULL DEFAULT '' COMMENT '第三方药房编码' AFTER `product_pharmacy_code`, ADD KEY `idx_pharmacy_code` (`pharmacy_code`); -- ============================================================================== -- 第三部分:历史数据回填与初始化(DML) -- ============================================================================== -- 3.1 初始化系统默认药房记录(pharmacy_id = 0,编码 ZD-10198) INSERT INTO `gdxz_pharmacy` ( `pharmacy_id`, `pharmacy_name`, `pharmacy_code`, `postage`, `free_shipping_threshold`, `is_pickup`, `telephone`, `province`, `city`, `county`, `address`, `pickup_address`, `status`, `created_at`, `updated_at` ) VALUES ( 0, '总院默认药房', 'ZD-10198', 7.00, 0.00, 1, '010-87573022', '北京市', '北京市', '海淀区', '医疗机构总院院内药房', '医疗机构总院门诊楼1层药房自提窗口', 1, NOW(), NOW() ) ON DUPLICATE KEY UPDATE `pharmacy_code` = VALUES(`pharmacy_code`), `pharmacy_name` = VALUES(`pharmacy_name`), `status` = 1; -- 3.2 回填现有药品表(gdxz_product)的药房归属为默认药房 UPDATE `gdxz_product` SET `pharmacy_id` = 0, `pharmacy_code` = 'ZD-10198' WHERE `pharmacy_code` = '' OR `pharmacy_code` IS NULL; -- 3.3 回填处方平台目录表(gdxz_product_platform)的药房编码 UPDATE `gdxz_product_platform` SET `pharmacy_code` = 'ZD-10198' WHERE `pharmacy_code` = '' OR `pharmacy_code` IS NULL; -- 3.4 回填历史处方表(gdxz_order_prescription)快照数据 UPDATE `gdxz_order_prescription` SET `pharmacy_id` = 0, `pharmacy_code` = 'ZD-10198', `pharmacy_name` = '总院默认药房' WHERE `pharmacy_code` = '' OR `pharmacy_code` IS NULL; -- 3.5 回填历史药品订单表(gdxz_order_product)快照与配送方式(历史订单默认为快递=2) UPDATE `gdxz_order_product` SET `pharmacy_id` = 0, `pharmacy_code` = 'ZD-10198', `pharmacy_name` = '总院默认药房', `delivery_type` = 2 WHERE `pharmacy_code` = '' OR `pharmacy_code` IS NULL; -- 3.6 为现有所有正常在职的医生,初始化绑定默认药房(避免上线后老医生无法开方) INSERT IGNORE INTO `gdxz_doctor_pharmacy` ( `doctor_pharmacy_id`, `doctor_id`, `pharmacy_id`, `is_default`, `status`, `created_at`, `updated_at` ) SELECT -- 结合时间戳与医生ID生成唯一大整数ID (UNIX_TIMESTAMP(NOW()) * 1000000 + (d.doctor_id % 1000000)) AS `doctor_pharmacy_id`, d.doctor_id, 0 AS `pharmacy_id`, 1 AS `is_default`, 1 AS `status`, NOW() AS `created_at`, NOW() AS `updated_at` FROM `gdxz_user_doctor` d WHERE d.status = 1 AND NOT EXISTS ( SELECT 1 FROM `gdxz_doctor_pharmacy` dp WHERE dp.doctor_id = d.doctor_id );