init: IotLCM 开源版部署仓

内容:
- docker-compose.yml:14 个基础/业务服务 + 3 个可选 profile(with-mock 挡板、with-bot、with-nginx)
- .env.example:集中管理镜像仓库、口令、端口;必填项缺失时 compose 直接报错退出
- config.example/:10 份配置模板,全部为占位值与注释说明
- schema/:12 个初始化脚本,按文件名顺序由 MySQL initdb 自动执行

脱敏处理:
- 生产/内网 IP、镜像仓库地址、公司名、真实域名全部清除
- 演示账号保留 18 个(出库与划拨依赖账号与部门树的关联),
  昵称/邮箱/手机号/登录IP/头像改为占位或编造值
- 数据库账号与 admin 口令改为初始化时按 .env 注入计算
- 通道模板与 Mock 通道的上游密钥置空
- Mock 通道地址指向 compose 内 onelink-mock 服务

部署时用 --profile with-mock 启动运营商接口挡板,即可在无真实运营商环境时跑通全链路。
This commit is contained in:
MiFaZhan
2026-10-28 13:40:12 +08:00
commit bc2c7bcc6b
26 changed files with 7264 additions and 0 deletions
+116
View File
@@ -0,0 +1,116 @@
-- ============================================
-- 演示环境种子库结构补齐(2026-10-16)
-- 背景:mysql-init/01-schema.sql 源自 db_iotlcm_init.sql(较旧),
-- 与当前业务镜像期望的 schema 存在差异,导致 app-server 后台任务
-- 报 `Unknown column 'source_channel'` 等错误。
-- 依据:以预演1(内网环境)的 db_iotlcm 为基准逐列比对得出。
-- 差异:缺 1 张表(card_channel_assoc)+ 27 列(分布 8 张表)。
--
-- ⚠️ MySQL 8.0 不支持 `ALTER TABLE ... ADD COLUMN IF NOT EXISTS`(MariaDB 语法),
-- 因此用存储过程按 information_schema 判断后动态执行,保证幂等、可重复运行。
--
-- 执行顺序:01-schema.sql → 本文件(按文件名排序,02-)。
-- ============================================
SET NAMES utf8mb4;
USE `db_iotlcm`;
-- ---------- 1. 缺失的表:card_channel_assoc(卡号段-通道关联)----------
CREATE TABLE IF NOT EXISTS `card_channel_assoc` (
`id` bigint NOT NULL AUTO_INCREMENT,
`channel_id` int NOT NULL COMMENT '通道ID',
`match_type` tinyint NOT NULL COMMENT '匹配类型',
`iccid` varchar(32) DEFAULT NULL COMMENT '单卡ICCID',
`iccid_start` varchar(32) DEFAULT NULL COMMENT '卡号段起始',
`iccid_end` varchar(32) DEFAULT NULL COMMENT '卡号段结束',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_channel_id` (`channel_id`),
KEY `idx_iccid` (`iccid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='卡号段与通道关联';
-- ---------- 2. 幂等补列辅助过程 ----------
DROP PROCEDURE IF EXISTS `sp_add_column_if_missing`;
DELIMITER $$
CREATE PROCEDURE `sp_add_column_if_missing`(
IN p_table VARCHAR(64),
IN p_column VARCHAR(64),
IN p_ddl TEXT
)
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = DATABASE()
AND table_name = p_table
AND column_name = p_column
) THEN
SET @s = CONCAT('ALTER TABLE `', p_table, '` ADD COLUMN ', p_ddl);
PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SELECT CONCAT('added ', p_table, '.', p_column) AS action;
ELSE
SELECT CONCAT('exists ', p_table, '.', p_column) AS action;
END IF;
END$$
DELIMITER ;
-- ---------- 3. batch_main:补 2 列 ----------
CALL sp_add_column_if_missing('batch_main', 'source_channel',
"`source_channel` varchar(24) NOT NULL DEFAULT 'legacy' COMMENT '发起渠道:console/mini_program/api/system/legacy'");
CALL sp_add_column_if_missing('batch_main', 'execution_mode',
"`execution_mode` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '执行模式'");
-- ---------- 4. sys_user:补 1 列 ----------
CALL sp_add_column_if_missing('sys_user', 'is_init_password',
"`is_init_password` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否为初始密码'");
-- ---------- 5. t_sim_card_info:补 4 列 ----------
CALL sp_add_column_if_missing('t_sim_card_info', 'imei_sync_time',
"`imei_sync_time` datetime DEFAULT NULL COMMENT 'IMEI 同步时间'");
CALL sp_add_column_if_missing('t_sim_card_info', 'imei_update_time',
"`imei_update_time` datetime DEFAULT NULL COMMENT 'IMEI 更新时间'");
CALL sp_add_column_if_missing('t_sim_card_info', 'traffic_cutoff_triggered_at',
"`traffic_cutoff_triggered_at` datetime DEFAULT NULL COMMENT '流量停机触发时间'");
CALL sp_add_column_if_missing('t_sim_card_info', 'traffic_cutoff_cross_month_hold',
"`traffic_cutoff_cross_month_hold` tinyint(1) NOT NULL DEFAULT 0 COMMENT '流量停机跨月保持'");
-- ---------- 6. t_sim_channels:补 9 列 ----------
CALL sp_add_column_if_missing('t_sim_channels', 'app_key',
"`app_key` varchar(64) DEFAULT NULL COMMENT '运营商 app_key'");
CALL sp_add_column_if_missing('t_sim_channels', 'app_secret',
"`app_secret` varchar(64) DEFAULT NULL COMMENT '运营商 app_secret'");
CALL sp_add_column_if_missing('t_sim_channels', 'operator',
"`operator` tinyint unsigned DEFAULT NULL COMMENT '运营商'");
CALL sp_add_column_if_missing('t_sim_channels', 'is_normal',
"`is_normal` tinyint(1) DEFAULT NULL COMMENT '是否正常'");
CALL sp_add_column_if_missing('t_sim_channels', 'docking_status',
"`docking_status` tinyint(1) DEFAULT NULL COMMENT '对接状态'");
CALL sp_add_column_if_missing('t_sim_channels', 'sync_enabled',
"`sync_enabled` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否启用全量同步'");
CALL sp_add_column_if_missing('t_sim_channels', 'card_info_count',
"`card_info_count` bigint NOT NULL DEFAULT 0 COMMENT '卡信息数量'");
CALL sp_add_column_if_missing('t_sim_channels', 'stock_card_count',
"`stock_card_count` bigint NOT NULL DEFAULT 0 COMMENT '库存卡数量'");
CALL sp_add_column_if_missing('t_sim_channels', 'cancellation_card_count',
"`cancellation_card_count` bigint NOT NULL DEFAULT 0 COMMENT '销户卡数量'");
-- ---------- 7. 两张套餐绑定表:补 batch_no ----------
CALL sp_add_column_if_missing('t_sim_pool_bind_package', 'batch_no',
"`batch_no` varchar(64) NOT NULL DEFAULT '' COMMENT '批次号'");
CALL sp_add_column_if_missing('t_sim_pool_bind_pkg_logs', 'batch_no',
"`batch_no` varchar(64) NOT NULL DEFAULT '' COMMENT '批次号'");
-- ---------- 8. 清理辅助过程 ----------
DROP PROCEDURE IF EXISTS `sp_add_column_if_missing`;
-- ---------- 9. 校验 ----------
SELECT 'tables' AS check_item, COUNT(*) AS n FROM information_schema.tables
WHERE table_schema='db_iotlcm'
UNION ALL SELECT 'columns', COUNT(*) FROM information_schema.columns
WHERE table_schema='db_iotlcm'
UNION ALL SELECT 'has_source_channel', COUNT(*) FROM information_schema.columns
WHERE table_schema='db_iotlcm' AND table_name='batch_main' AND column_name='source_channel'
UNION ALL SELECT 'has_card_channel_assoc', COUNT(*) FROM information_schema.tables
WHERE table_schema='db_iotlcm' AND table_name='card_channel_assoc';