From b60695b0e5693a6e88203d146176745bcee91a8a Mon Sep 17 00:00:00 2001 From: MiFaZhan Date: Thu, 29 Oct 2026 18:07:50 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A1=A5=E9=BD=90=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E5=8A=9E=E7=90=86=E6=81=A2=E5=A4=8D=E8=A1=A8=E5=B9=B6=E6=A0=A1?= =?UTF-8?q?=E6=AD=A3=E5=88=9D=E5=A7=8B=E5=8C=96=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +++ schema/README.md | 5 ++-- schema/init.sql | 76 ++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 81 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0cb0539..f2469b1 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,8 @@ docker compose --profile with-nginx up -d # 自带反向代理 多个 profile 可组合:`--profile with-mock --profile with-nginx up -d` +`with-bot` 需要先在 `config/bot/config.yaml` 填入有效的飞书应用 `appId` / `appSecret`;开源默认配置未提供企业凭据,不配置时 bot 无法启动。默认启动不包含 bot。 + ## 镜像版本 当前部署编排固定使用业务镜像 `v1.0.4`;`iotlcm-app-server` 与 `iotlcm-app-web` 固定为 `v1.0.2`。升级时请在 `docker-compose.yml` 中同步更新对应 tag,不要改用 `latest`。 @@ -69,6 +71,8 @@ iotlcm-deploy/ └── data/ # 运行数据(首次启动自动创建,不入版本库) ``` +全新初始化生成 95 张业务表(原有 91 张 + worker 异步恢复所需 4 张);已部署旧库不会自动执行新增迁移,见 `schema/README.md`。 + ## 上线前必改 默认口令仅用于快速试用。**正式部署前必须修改以下内容**,具体位置见[部署手册](https://git.5iot.com/iotlcm-public/iotlcm-docs): diff --git a/schema/README.md b/schema/README.md index 34008c0..1882826 100644 --- a/schema/README.md +++ b/schema/README.md @@ -1,6 +1,6 @@ # 数据库初始化 -`init.sql` 是**单文件**初始化脚本,MySQL 容器首次以空数据卷启动时由 `docker-entrypoint-initdb.d` 自动执行。 +`init.sql` 是**单文件**初始化脚本,MySQL 容器首次以空数据卷启动时由 `docker-entrypoint-initdb.d` 自动执行。已有数据目录不会自动执行新增 DDL,升级时需先核对四张表状态,再按上游迁移规范处理,不能删除数据卷。 ## 内容组成 @@ -18,12 +18,13 @@ | 定时任务 | 20 条,**默认全部停用**(避免自动全量同步打满机器) | | 菜单增量 | 达量断网按钮权限、全量同步页 | | v1.0.4 前置 | 导出中心表 `t_export_task`、通知已读表 `sys_notice_user`、`card_channel_assoc.channel_id` 扩宽、菜单权限 | +| APN 异步恢复 | `data_operation_parent`、`data_operation_sub_batch`、`data_operation_sub_detail`、`data_operation_card_claim` 四表;须先建表后启动 worker | | 数据修复 | `sys_dept.ancestors` 尾逗号归一化(全新库为空操作) | | 业务账号与口令 | 建 `u_iotlcm` 账号、可选库 `iotdb`、种子账号口令统一重置 | ## 来源 -内容取自**演示环境正在使用的种子库**,以生产 89 表基线为基础并补齐 v1.0.4 的 2 张表,初始化后为 **91 表**。脱敏及部署适配包括: +内容取自**演示环境正在使用的种子库**,以生产 89 表基线为基础,补齐 v1.0.4 的 2 张表及 worker 异步恢复所需的 4 张表,初始化后为 **95 表**。四张恢复表直接采用内部数据库仓 `feat/data-operation-reconcile-20261015` 的 `SQL/20261015_data_operation_sub_batch.sql`(提交 `bf5f7fd`);原有 91 表统计不含这四张表。脱敏及部署适配包括: - 演示账号昵称、邮箱、手机号、登录 IP、头像 → 占位或编造值 - 公司名、组织名 → 「示例企业」等通用名 diff --git a/schema/init.sql b/schema/init.sql index ba5c3b1..adaa386 100644 --- a/schema/init.sql +++ b/schema/init.sql @@ -5388,8 +5388,7 @@ SELECT `dept_id`, `dept_name`, `parent_id`, `ancestors` -- 口令为字面值(不使用环境变量)。改口令须同步修改: -- docker-compose.yml 的 MYSQL_ROOT_PASSWORD -- config/*/config.yaml 各服务 database link 的口令 --- config/*/config.yaml 各服务 database link 的口令 --- 口令算法:md5( hex(md5(明文)) + md5(salt) ),见 iotlcm-admin-svr utils.go +-- 口令算法:MD5(CONCAT(MD5(明文), salt));前端先 MD5 明文,后端再将该值与原始 salt 拼接后 MD5。 CREATE USER IF NOT EXISTS 'u_iotlcm'@'%' IDENTIFIED WITH mysql_native_password BY 'Iotlcm2026Default'; @@ -5404,3 +5403,76 @@ FLUSH PRIVILEGES; -- 种子账号口令统一重置为部署口令(登录后请逐个修改) UPDATE `sys_user` SET `password` = MD5(CONCAT(MD5('Iotlcm2026Default'), `salt`)); + + +-- ============================================================ +-- worker-svr v1.0.4 的 APN 异步办理恢复表(来源:iotlcm-database +-- feat/data-operation-reconcile-20261015:SQL/20261015_data_operation_sub_batch.sql,bf5f7fd) +-- 新库初始化阶段先建表,后启动 worker;旧库单独执行原迁移,不覆盖已有记录。 +-- ============================================================ +-- APN异步任务:先执行迁移,再部署配套chan/proxy/worker;禁止混版直接发送办理请求。 +-- apnAsyncProtocolVersion=0仅阻断网络办理请求,worker恢复器仍会访问本脚本创建的四张表;故必须先迁移。 +-- 升级前排空旧路由与在途请求、逐批核实旧同步processing批次:可能已送上游却无operationId者不得自动重投。 +-- 所有chan/proxy/worker实例均升级且旧实例退出后才显式开启门禁;能力probe成功不证明下一次办理必达同一实例。 +-- 本脚本只创建全新四表,不负责升级此前未部署的试验版表结构;若已存在同名表须先核对列与排序规则。 +-- 仅适用于首次创建四表;CREATE IF NOT EXISTS不升级未部署的旧试验结构。 +-- 若发现同名旧表,须停止启用并单独核验冻结请求/明细/active归属,禁止清空或重置jobId和补查次数。 +-- worker数据库连接须保持写入与读取一致的loc/parseTime约定(与现有生产配置一致)。 +CREATE TABLE IF NOT EXISTS `data_operation_parent` ( + `batch_no` varchar(64) NOT NULL, + `ready` tinyint NOT NULL DEFAULT 0, + `finalize_token` varchar(64) DEFAULT NULL, + `finalize_until` datetime(3) DEFAULT NULL, + `recovery_attempt_at` datetime(3) DEFAULT NULL, + `last_reason` varchar(1024) DEFAULT NULL, + `updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), + PRIMARY KEY (`batch_no`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='APN父批准备屏障及可恢复汇总租约'; + +CREATE TABLE IF NOT EXISTS `data_operation_sub_batch` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `batch_no` varchar(64) NOT NULL, + `batch_type` int NOT NULL, + `chan_key` varchar(128) NOT NULL, + `operation_id` varchar(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, + `detail_ids` json NOT NULL, + `request_data` json NOT NULL COMMENT '首发前冻结请求,恢复不能重新构建', + `job_id` varchar(128) DEFAULT NULL, + `status` varchar(24) NOT NULL DEFAULT 'prepared' COMMENT 'prepared/submitting/accepted/uncertain/review/done', + `poll_count` tinyint unsigned NOT NULL DEFAULT 0, + `next_check_at` datetime(3) DEFAULT NULL, + `submitted_at` datetime(3) DEFAULT NULL, + `lease_token` varchar(64) DEFAULT NULL, + `lease_until` datetime(3) DEFAULT NULL, + `last_reason` varchar(1024) DEFAULT NULL, + `created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), + PRIMARY KEY (`id`), + UNIQUE KEY `uk_data_operation_id` (`operation_id`), + KEY `idx_data_sub_due` (`status`,`next_check_at`,`lease_until`), + KEY `idx_data_sub_batch` (`batch_no`,`status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='APN异步子批及恢复状态'; + +CREATE TABLE IF NOT EXISTS `data_operation_sub_detail` ( + `detail_id` bigint NOT NULL, + `operation_id` varchar(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, + `batch_no` varchar(64) NOT NULL, + `iccid` varchar(64) NOT NULL, + PRIMARY KEY (`detail_id`), + UNIQUE KEY `uk_data_sub_batch_card` (`batch_no`,`iccid`), + KEY `idx_data_sub_detail_operation` (`operation_id`), + KEY `idx_data_sub_detail_batch` (`batch_no`), + KEY `idx_data_sub_detail_card` (`iccid`,`batch_no`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='明细唯一提交意图映射'; + +-- queued与active分离:新准备意图不抢已提交请求的owner,未知active不能自动释放。 +CREATE TABLE IF NOT EXISTS `data_operation_card_claim` ( + `tenant_id` varchar(64) NOT NULL, + `iccid` varchar(64) NOT NULL, + `batch_id` bigint NOT NULL DEFAULT 0 COMMENT '最新queued批次序', + `operation_id` varchar(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL DEFAULT '' COMMENT '最新queued意图', + `active_batch_id` bigint NOT NULL DEFAULT 0, + `active_operation_id` varchar(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL DEFAULT '', + `updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), + PRIMARY KEY (`tenant_id`,`iccid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='APN卡持久化提交顺序屏障';