219 lines
16 KiB
SQL
219 lines
16 KiB
SQL
-- =============================================================
|
||
-- 租户套餐 + 用户数配额(平台端「租户套餐」功能)
|
||
--
|
||
-- 业务说明:
|
||
-- 1. 套餐(yz_system_tenant_package)决定租户能开通哪些功能模块
|
||
-- (模块取自 yz_system_modules,如 erp / oa / crm / cms),
|
||
-- 租户绑定套餐后,租户端菜单按套餐包含的模块过滤(未包含的整块菜单不展示)。
|
||
-- 2. 所有租户都有用户数上限(yz_system_tenant.user_quota,默认 20),
|
||
-- 租户用户数达到上限后不允许再新增账号,需要先增购用户数:
|
||
-- · 单个增购:按套餐的 extra_user_price(如 200 元/人)
|
||
-- · 套餐增购:按 yz_system_tenant_user_quota_package 配置的规格(如 5人/500元)
|
||
-- 每次增购写入 yz_system_tenant_quota_order 记录,并累加到租户的 user_quota。
|
||
--
|
||
-- 本脚本可重复执行:建表用 IF NOT EXISTS,补列/预置数据均做存在性判断。
|
||
-- 运行:mysql --default-character-set=utf8mb4 -h<host> -P<port> -u<user> -p <db> < create_tenant_package.sql
|
||
-- =============================================================
|
||
|
||
-- 1) 租户套餐表
|
||
CREATE TABLE IF NOT EXISTS `yz_system_tenant_package` (
|
||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键ID',
|
||
`name` varchar(64) NOT NULL DEFAULT '' COMMENT '套餐名称,如:ERP套餐',
|
||
`code` varchar(64) NOT NULL DEFAULT '' COMMENT '套餐编码(唯一,程序识别用)',
|
||
`description` varchar(500) NOT NULL DEFAULT '' COMMENT '套餐说明',
|
||
`price` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '套餐售价(元)',
|
||
`user_quota` int(11) NOT NULL DEFAULT 20 COMMENT '套餐包含的用户数(新租户绑定套餐后初始化的用户数上限)',
|
||
`extra_user_price` decimal(10,2) NOT NULL DEFAULT 200.00 COMMENT '单个用户增购价格(元/人)',
|
||
`is_default` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否默认套餐:1是 0否(新建租户未指定套餐时使用)',
|
||
`sort` int(11) NOT NULL DEFAULT 0 COMMENT '排序号,越小越靠前',
|
||
`status` tinyint(4) NOT NULL DEFAULT 1 COMMENT '状态:1启用 0禁用',
|
||
`remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
|
||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||
`delete_time` datetime DEFAULT NULL COMMENT '删除时间(软删除)',
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_code` (`code`, `delete_time`),
|
||
KEY `idx_delete_time` (`delete_time`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='租户套餐表(功能模块 + 用户数配额)';
|
||
|
||
-- 2) 套餐-功能模块关联表(一个套餐勾选多个模块,模块取自 yz_system_modules.code)
|
||
CREATE TABLE IF NOT EXISTS `yz_system_tenant_package_module` (
|
||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键ID',
|
||
`package_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '套餐ID 关联 yz_system_tenant_package(id)',
|
||
`module_code` varchar(64) NOT NULL DEFAULT '' COMMENT '功能模块编码 关联 yz_system_modules(code),如 erp/oa/crm/cms',
|
||
`module_name` varchar(64) NOT NULL DEFAULT '' COMMENT '功能模块名称(冗余,便于展示)',
|
||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_package_id` (`package_id`),
|
||
KEY `idx_module_code` (`module_code`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='租户套餐-功能模块关联表';
|
||
|
||
-- 3) 用户数加购套餐表(平台可维护的「人/元」规格,如 5人 500元)
|
||
CREATE TABLE IF NOT EXISTS `yz_system_tenant_user_quota_package` (
|
||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键ID',
|
||
`name` varchar(64) NOT NULL DEFAULT '' COMMENT '规格名称,如:5人套餐',
|
||
`user_count` int(11) NOT NULL DEFAULT 0 COMMENT '包含用户数',
|
||
`price` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '售价(元)',
|
||
`sort` int(11) NOT NULL DEFAULT 0 COMMENT '排序号,越小越靠前',
|
||
`status` tinyint(4) NOT NULL DEFAULT 1 COMMENT '状态:1启用 0禁用',
|
||
`remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
|
||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||
`delete_time` datetime DEFAULT NULL COMMENT '删除时间(软删除)',
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_delete_time` (`delete_time`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='租户用户数加购套餐表';
|
||
|
||
-- 4) 租户用户数增购记录表
|
||
CREATE TABLE IF NOT EXISTS `yz_system_tenant_quota_order` (
|
||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键ID',
|
||
`tid` bigint(20) NOT NULL DEFAULT 0 COMMENT '租户ID 关联 yz_system_tenant(id)',
|
||
`type` tinyint(4) NOT NULL DEFAULT 1 COMMENT '增购方式:1单个增购 2套餐增购',
|
||
`quota_package_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '加购套餐ID(type=2 时有效)',
|
||
`package_name` varchar(64) NOT NULL DEFAULT '' COMMENT '加购规格名称(冗余)',
|
||
`user_count` int(11) NOT NULL DEFAULT 0 COMMENT '本次增购用户数',
|
||
`unit_price` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '单价(元/人,type=1 时使用)',
|
||
`amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '本次金额(元)',
|
||
`quota_before` int(11) NOT NULL DEFAULT 0 COMMENT '增购前用户数上限',
|
||
`quota_after` int(11) NOT NULL DEFAULT 0 COMMENT '增购后用户数上限',
|
||
`operator` varchar(64) NOT NULL DEFAULT '' COMMENT '操作人(平台账号)',
|
||
`remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
|
||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_tid` (`tid`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='租户用户数增购记录表';
|
||
|
||
-- 5) 租户表补列:套餐ID + 用户数上限
|
||
SET @tbl := (SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'yz_system_tenant');
|
||
SET @col := (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'yz_system_tenant' AND COLUMN_NAME = 'package_id');
|
||
SET @ddl := IF(@tbl > 0 AND @col = 0, 'ALTER TABLE `yz_system_tenant` ADD COLUMN `package_id` bigint(20) NOT NULL DEFAULT 0 COMMENT ''套餐ID 关联 yz_system_tenant_package(id),0-未绑定''', 'DO 0');
|
||
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||
|
||
SET @tbl := (SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'yz_system_tenant');
|
||
SET @col := (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'yz_system_tenant' AND COLUMN_NAME = 'user_quota');
|
||
SET @ddl := IF(@tbl > 0 AND @col = 0, 'ALTER TABLE `yz_system_tenant` ADD COLUMN `user_quota` int(11) NOT NULL DEFAULT 20 COMMENT ''用户数上限(默认20,增购后累加)''', 'DO 0');
|
||
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||
|
||
-- 存量租户兜底:用户数上限为 0 的按默认 20 初始化
|
||
UPDATE `yz_system_tenant` SET `user_quota` = 20 WHERE `user_quota` <= 0;
|
||
|
||
-- 存量租户兜底:用户数上限小于已开用户数时,按已开用户数抬高(避免历史租户立刻被锁死)
|
||
UPDATE `yz_system_tenant` t
|
||
SET t.`user_quota` = (
|
||
SELECT cnt FROM (SELECT COUNT(*) AS cnt FROM `yz_system_tenant_user` u WHERE u.`tid` = t.`id` AND u.`delete_time` IS NULL) c
|
||
)
|
||
WHERE t.`user_quota` < (
|
||
SELECT cnt FROM (SELECT COUNT(*) AS cnt FROM `yz_system_tenant_user` u WHERE u.`tid` = t.`id` AND u.`delete_time` IS NULL) c2
|
||
);
|
||
|
||
-- 6) 预置套餐(幂等:按 code 判断,不存在才插入)
|
||
INSERT INTO `yz_system_tenant_package` (`name`, `code`, `description`, `price`, `user_quota`, `extra_user_price`, `is_default`, `sort`, `status`, `remark`, `create_time`, `update_time`)
|
||
SELECT '基础版', 'basic', '基础功能:系统管理、基础设置、便捷工具', 0.00, 20, 200.00, 1, 1, 1, '默认套餐,新建租户自动绑定', NOW(), NOW()
|
||
WHERE NOT EXISTS (SELECT 1 FROM (SELECT `id` FROM `yz_system_tenant_package` WHERE `code` = 'basic' AND `delete_time` IS NULL) t);
|
||
|
||
INSERT INTO `yz_system_tenant_package` (`name`, `code`, `description`, `price`, `user_quota`, `extra_user_price`, `is_default`, `sort`, `status`, `remark`, `create_time`, `update_time`)
|
||
SELECT 'ERP套餐', 'erp', '基础功能 + 进销存(ERP)', 0.00, 20, 200.00, 0, 2, 1, '', NOW(), NOW()
|
||
WHERE NOT EXISTS (SELECT 1 FROM (SELECT `id` FROM `yz_system_tenant_package` WHERE `code` = 'erp' AND `delete_time` IS NULL) t);
|
||
|
||
INSERT INTO `yz_system_tenant_package` (`name`, `code`, `description`, `price`, `user_quota`, `extra_user_price`, `is_default`, `sort`, `status`, `remark`, `create_time`, `update_time`)
|
||
SELECT 'CRM套餐', 'crm', '基础功能 + 客户关系管理(CRM)', 0.00, 20, 200.00, 0, 3, 1, '', NOW(), NOW()
|
||
WHERE NOT EXISTS (SELECT 1 FROM (SELECT `id` FROM `yz_system_tenant_package` WHERE `code` = 'crm' AND `delete_time` IS NULL) t);
|
||
|
||
INSERT INTO `yz_system_tenant_package` (`name`, `code`, `description`, `price`, `user_quota`, `extra_user_price`, `is_default`, `sort`, `status`, `remark`, `create_time`, `update_time`)
|
||
SELECT '企业全功能版', 'all', '基础功能 + 进销存 + OA + CRM + 网站管理', 0.00, 20, 200.00, 0, 9, 1, '', NOW(), NOW()
|
||
WHERE NOT EXISTS (SELECT 1 FROM (SELECT `id` FROM `yz_system_tenant_package` WHERE `code` = 'all' AND `delete_time` IS NULL) t);
|
||
|
||
-- 7) 预置套餐功能模块(按套餐 code + 模块 code 幂等插入)
|
||
-- 注意:MySQL 的派生表不能引用外层字段,因此这里把「已存在的关联」整表materialize 成 ex,
|
||
-- 再在 WHERE 中与外层套餐/模块做关联,既避免了「不能 SELECT 目标表」,也保证可重复执行。
|
||
-- 基础模块:基础设置(basicSettings)、系统管理(systemManager)、便捷工具(bianjiegongju)
|
||
INSERT INTO `yz_system_tenant_package_module` (`package_id`, `module_code`, `module_name`, `create_time`)
|
||
SELECT p.`id`, m.`code`, m.`name`, NOW()
|
||
FROM `yz_system_tenant_package` p
|
||
JOIN `yz_system_modules` m ON m.`delete_time` IS NULL AND m.`code` IN ('basicSettings', 'systemManager', 'bianjiegongju')
|
||
WHERE p.`code` IN ('basic', 'erp', 'crm', 'all') AND p.`delete_time` IS NULL
|
||
AND NOT EXISTS (
|
||
SELECT 1 FROM (SELECT `package_id`, `module_code` FROM `yz_system_tenant_package_module`) ex
|
||
WHERE ex.`package_id` = p.`id` AND ex.`module_code` = m.`code`
|
||
);
|
||
|
||
-- ERP套餐:附加 erp 模块
|
||
INSERT INTO `yz_system_tenant_package_module` (`package_id`, `module_code`, `module_name`, `create_time`)
|
||
SELECT p.`id`, m.`code`, m.`name`, NOW()
|
||
FROM `yz_system_tenant_package` p
|
||
JOIN `yz_system_modules` m ON m.`delete_time` IS NULL AND m.`code` = 'erp'
|
||
WHERE p.`code` = 'erp' AND p.`delete_time` IS NULL
|
||
AND NOT EXISTS (
|
||
SELECT 1 FROM (SELECT `package_id`, `module_code` FROM `yz_system_tenant_package_module`) ex
|
||
WHERE ex.`package_id` = p.`id` AND ex.`module_code` = m.`code`
|
||
);
|
||
|
||
-- CRM套餐:附加 crm 模块
|
||
INSERT INTO `yz_system_tenant_package_module` (`package_id`, `module_code`, `module_name`, `create_time`)
|
||
SELECT p.`id`, m.`code`, m.`name`, NOW()
|
||
FROM `yz_system_tenant_package` p
|
||
JOIN `yz_system_modules` m ON m.`delete_time` IS NULL AND m.`code` = 'crm'
|
||
WHERE p.`code` = 'crm' AND p.`delete_time` IS NULL
|
||
AND NOT EXISTS (
|
||
SELECT 1 FROM (SELECT `package_id`, `module_code` FROM `yz_system_tenant_package_module`) ex
|
||
WHERE ex.`package_id` = p.`id` AND ex.`module_code` = m.`code`
|
||
);
|
||
|
||
-- 企业全功能版:附加 erp / oa / crm / cms
|
||
INSERT INTO `yz_system_tenant_package_module` (`package_id`, `module_code`, `module_name`, `create_time`)
|
||
SELECT p.`id`, m.`code`, m.`name`, NOW()
|
||
FROM `yz_system_tenant_package` p
|
||
JOIN `yz_system_modules` m ON m.`delete_time` IS NULL AND m.`code` IN ('erp', 'oa', 'crm', 'cms')
|
||
WHERE p.`code` = 'all' AND p.`delete_time` IS NULL
|
||
AND NOT EXISTS (
|
||
SELECT 1 FROM (SELECT `package_id`, `module_code` FROM `yz_system_tenant_package_module`) ex
|
||
WHERE ex.`package_id` = p.`id` AND ex.`module_code` = m.`code`
|
||
);
|
||
|
||
-- 8) 预置用户数加购套餐(5人 500元;可按需在平台端维护更多规格)
|
||
INSERT INTO `yz_system_tenant_user_quota_package` (`name`, `user_count`, `price`, `sort`, `status`, `remark`, `create_time`, `update_time`)
|
||
SELECT '5人套餐', 5, 500.00, 1, 1, '一次性增购 5 个用户数', NOW(), NOW()
|
||
WHERE NOT EXISTS (SELECT 1 FROM (SELECT `id` FROM `yz_system_tenant_user_quota_package` WHERE `name` = '5人套餐' AND `delete_time` IS NULL) t);
|
||
|
||
INSERT INTO `yz_system_tenant_user_quota_package` (`name`, `user_count`, `price`, `sort`, `status`, `remark`, `create_time`, `update_time`)
|
||
SELECT '10人套餐', 10, 900.00, 2, 1, '一次性增购 10 个用户数', NOW(), NOW()
|
||
WHERE NOT EXISTS (SELECT 1 FROM (SELECT `id` FROM `yz_system_tenant_user_quota_package` WHERE `name` = '10人套餐' AND `delete_time` IS NULL) t);
|
||
|
||
-- 9) 存量租户兜底:未绑定套餐的存量租户绑定「企业全功能版」,
|
||
-- 避免上线后老租户因套餐未配置而看不到原有功能菜单;
|
||
-- 之后可在「租户管理 → 编辑 / 套餐与用户数」中按实际购买情况改为 ERP/CRM 等套餐。
|
||
-- (若没有 all 套餐,则退回绑定默认套餐)
|
||
UPDATE `yz_system_tenant` t
|
||
SET t.`package_id` = (SELECT p.`id` FROM (SELECT `id` FROM `yz_system_tenant_package` WHERE `code` = 'all' AND `delete_time` IS NULL ORDER BY `sort`, `id` LIMIT 1) p)
|
||
WHERE (t.`package_id` IS NULL OR t.`package_id` = 0)
|
||
AND EXISTS (SELECT 1 FROM (SELECT `id` FROM `yz_system_tenant_package` WHERE `code` = 'all' AND `delete_time` IS NULL) p2);
|
||
|
||
UPDATE `yz_system_tenant` t
|
||
SET t.`package_id` = (SELECT p.`id` FROM (SELECT `id` FROM `yz_system_tenant_package` WHERE `is_default` = 1 AND `delete_time` IS NULL ORDER BY `sort`, `id` LIMIT 1) p)
|
||
WHERE (t.`package_id` IS NULL OR t.`package_id` = 0)
|
||
AND EXISTS (SELECT 1 FROM (SELECT `id` FROM `yz_system_tenant_package` WHERE `is_default` = 1 AND `delete_time` IS NULL) p2);
|
||
|
||
-- 10) 平台端菜单:基础设置 → 租户套餐(仅平台端可见)
|
||
-- pid=17 为「基础设置」菜单;若环境中 17 不是基础设置,请在平台端「菜单管理」里手工挂载本页面:
|
||
-- 组件路径 /basicSettings/tenantpackage/index.vue,路径 /basicSettings/tenantpackage
|
||
INSERT INTO `yz_system_menu` (`pid`, `title`, `path`, `component_path`, `icon`, `sort`, `status`, `is_visible`, `views`, `type`, `permission`, `creater`, `remark`, `create_time`, `update_time`)
|
||
SELECT 17, '租户套餐', '/basicSettings/tenantpackage', '/basicSettings/tenantpackage/index.vue', 'Box', 4, 1, 1, '[1]', 2, '', 'system', '租户功能套餐与用户数加购规格', NOW(), NOW()
|
||
WHERE NOT EXISTS (SELECT 1 FROM (SELECT `id` FROM `yz_system_menu` WHERE `path` = '/basicSettings/tenantpackage' AND `delete_time` IS NULL) t)
|
||
AND EXISTS (SELECT 1 FROM (SELECT `id` FROM `yz_system_menu` WHERE `id` = 17 AND `delete_time` IS NULL) t2);
|
||
|
||
-- 11) 【按需执行】存量租户套餐调整
|
||
-- 本脚本第 9 步只处理「package_id 为空/0」的租户;若存量租户已被绑定为「基础版」,
|
||
-- 上线菜单按套餐过滤后,这些租户将看不到 进销存/OA/CRM/网站管理 等菜单。
|
||
-- 如需要让老租户保留原有全部功能,按下面的语句把它们改为「企业全功能版」
|
||
-- (或改成各自实际购买的套餐;也可直接在平台端「租户管理 → 编辑」里选择套餐)。
|
||
--
|
||
-- UPDATE `yz_system_tenant`
|
||
-- SET `package_id` = (SELECT p.`id` FROM (SELECT `id` FROM `yz_system_tenant_package` WHERE `code` = 'all' AND `delete_time` IS NULL ORDER BY `sort`, `id` LIMIT 1) p)
|
||
-- WHERE `id` IN (1, 2); -- ← 改成你的租户ID,或去掉 WHERE 批量处理
|
||
|
||
-- 校验:套餐与模块
|
||
-- SELECT p.id, p.name, p.code, p.user_quota, p.extra_user_price, GROUP_CONCAT(pm.module_code) AS modules
|
||
-- FROM yz_system_tenant_package p LEFT JOIN yz_system_tenant_package_module pm ON pm.package_id = p.id
|
||
-- WHERE p.delete_time IS NULL GROUP BY p.id;
|
||
-- SELECT id, tenant_name, package_id, user_quota FROM yz_system_tenant;
|