feat: 一键部署——配置内置默认值,去掉示例复制与环境变量

目标:git clone 后 docker compose up -d 直接可用,无需任何手工准备。

变更:
- config.example/ → config/,config.example.yaml → config.yaml
  不再需要 cp -r 与逐份修改
- 删除 .env / .env.example,值全部内置到 docker-compose.yml
  (GoFrame 不展开配置文件中的 ${VAR},环境变量方案在 Go 侧不可用)
- 配置文件里的 ${VAR} 全部替换为字面默认值
- schema/04-users.sh 与 05-reset-passwords.sh 改为脚本内字面口令,
  不再读取环境变量
- 新增 schema/13-seed-flow-package.sql 占位文件,说明套餐表为空的原因与补齐方式
- .gitignore 不再排除 config/ 与 .env(已无 .env)
- README 改为「一键启动」+「上线前必改」两张表

已验证:docker compose config 通过;compose 口令、各配置文件 DSN、
初始化脚本三处口令哈希一致;库名与 schema 中一致。
This commit is contained in:
MiFaZhan
2026-10-29 09:17:26 +08:00
parent 0bfc0ebe80
commit 5ddad0c5e5
18 changed files with 252 additions and 299 deletions
+16 -14
View File
@@ -3,31 +3,33 @@
# 业务数据库账号与附加库
# 由 MySQL 容器 docker-entrypoint-initdb.d 在首次启动时执行。
#
# 为什么用 .sh 而不是 .sql:
# MySQL 官方镜像的 initdb 脚本无法在 SQL 里读环境变量,
# 而账号口令必须从 .env 注入,不能写死在仓库里。
# 口令直接写在本文件(不使用环境变量)。
# 改口令时必须同时修改以下三处,否则服务连不上库:
# 1. docker-compose.yml 的 MYSQL_APP_PASSWORD
# 2. config/*/config.yaml 里 database link 的口令
# 3. 本文件下方的 APP_PASSWORD
# ============================================================
set -euo pipefail
if [ -z "${MYSQL_APP_PASSWORD:-}" ]; then
echo "[initdb] 错误:未设置 MYSQL_APP_PASSWORD" >&2
exit 1
fi
# 与 docker-compose.yml 保持一致
APP_USER='iotlcm_app'
APP_PASSWORD='Iotlcm2026Default'
ROOT_PASSWORD='Iotlcm2026Default'
DB_NAME='db_iotlcm'
mysql --protocol=socket -uroot -p"${MYSQL_ROOT_PASSWORD}" <<SQL
mysql --protocol=socket -uroot -p"${ROOT_PASSWORD}" <<SQL
SET NAMES utf8mb4;
-- 应用账号(对应各 config 文件里的数据库用户名 u_iotlcm)
CREATE USER IF NOT EXISTS 'u_iotlcm'@'%'
IDENTIFIED WITH mysql_native_password BY '${MYSQL_APP_PASSWORD}';
GRANT ALL PRIVILEGES ON \`db_iotlcm\`.* TO 'u_iotlcm'@'%';
CREATE USER IF NOT EXISTS '${APP_USER}'@'%'
IDENTIFIED WITH mysql_native_password BY '${APP_PASSWORD}';
GRANT ALL PRIVILEGES ON \`${DB_NAME}\`.* TO '${APP_USER}'@'%';
-- legacyCard 附加库(可选,不需要时删掉这三行)
CREATE DATABASE IF NOT EXISTS \`iotdb\`
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT ALL PRIVILEGES ON \`iotdb\`.* TO 'u_iotlcm'@'%';
GRANT ALL PRIVILEGES ON \`iotdb\`.* TO '${APP_USER}'@'%';
FLUSH PRIVILEGES;
SQL
echo "[initdb] 应用账号 u_iotlcm 已创建"
echo "[initdb] 应用账号 ${APP_USER} 已创建"
+13 -10
View File
@@ -2,26 +2,29 @@
# ============================================================
# 重置种子账号口令(由 MySQL 容器 initdb 自动执行)
#
# 01-schema.sql 里的密码哈希源自旧库,不能用于开源分发。
# 这里按 MYSQL_ADMIN_PASSWORD 统一重算,登录后请逐个修改。
# 01-schema.sql 里的密码哈希源自旧库,不能用于分发。
# 这里统一重算,登录后请逐个修改。
#
# 哈希算法(见 iotlcm-admin-svr server/internal/library/utils/utils.go):
# md5( hex(md5(明文)) + md5(salt) )
# salt 取自每行 sys_user.salt 列。
#
# 口令直接写在本文件(不使用环境变量)。
# 改口令时必须同时修改以下两处:
# 1. docker-compose.yml 的 MYSQL_ADMIN_PASSWORD
# 2. 本文件下方的 ADMIN_PASSWORD
# ============================================================
set -euo pipefail
if [ -z "${MYSQL_ADMIN_PASSWORD:-}" ]; then
echo "[initdb] 错误:未设置 MYSQL_ADMIN_PASSWORD" >&2
exit 1
fi
ADMIN_PASSWORD='Iotlcm2026Default'
ROOT_PASSWORD='Iotlcm2026Default'
DB_NAME='db_iotlcm'
PWD_MD5=$(printf '%s' "$MYSQL_ADMIN_PASSWORD" | md5sum | awk '{print $1}')
PWD_MD5=$(printf '%s' "$ADMIN_PASSWORD" | md5sum | awk '{print $1}')
# 逐个账号按其自身 salt 计算哈希(salt 每行不同)
mysql --protocol=socket -uroot -p"${MYSQL_ROOT_PASSWORD}" <<SQL
mysql --protocol=socket -uroot -p"${ROOT_PASSWORD}" <<SQL
SET NAMES utf8mb4;
USE \`db_iotlcm\`;
USE \`${DB_NAME}\`;
DROP PROCEDURE IF EXISTS sp_reset_all_passwords;
DELIMITER \$\$
+35
View File
@@ -0,0 +1,35 @@
-- ============================================================
-- 流量套餐种子数据(占位文件)
--
-- 本文件目前为空,属预期状态。
--
-- 原因:套餐(t_sim_flow_package_info)与具体运营商、渠道、
-- 资费政策强相关,不适合随代码分发固定数据。
--
-- 影响:表为空时,业务受理中的「办理套餐 / 续费 / 变更套餐」
-- 无套餐可选,其余功能(查卡、状态同步、通道管理)不受影响。
--
-- 补齐方式(二选一):
--
-- 方式一:登录管理端 →「套餐定价」创建套餐(推荐)
-- 创建后即可在业务受理中选择。
--
-- 方式二:按下列结构自行插入 SQL。
-- 字段含义以 `SHOW CREATE TABLE t_sim_flow_package_info`
-- 与厂商 API 文档为准。
--
-- 示例(字段不完整,仅示意,按实际情况补全):
-- INSERT INTO `t_sim_flow_package_info`
-- (`package_name`, `package_type`, `flow_size`, `price`, `status`, ...)
-- VALUES
-- ('示例套餐-1GB/月', 1, 1024, 10.00, 0, ...);
--
-- 执行方式:
-- docker compose exec -T mysql sh -c \
-- 'exec mysql -uroot -p"<root口令>" db_iotlcm' < schema/13-seed-flow-package.sql
-- ============================================================
SET NAMES utf8mb4;
USE `db_iotlcm`;
-- 留空,由使用者按上述方式补齐
+23 -27
View File
@@ -14,22 +14,32 @@ docker compose up -d mysql
## 执行顺序
按「结构 → 账号 → 种子数据」三阶段编号,文件名顺序即执行顺序。除 01 外全部幂等,可重复执行。
| 序号 | 文件 | 内容 |
| --- | --- | --- |
| 01 | `01-schema.sql` | 建 `db_iotlcm` 库 + 全部表结构 + 基础数据(菜单、字典、角色、租户、演示账号)。自包含:`DROP DATABASE` → `CREATE` → `USE` |
| 01 | `01-schema.sql` | 建库 + 全部表结构 + 基础数据(菜单、字典、角色、租户、演示账号)。自包含:`DROP DATABASE` → `CREATE` → `USE` |
| 02 | `02-schema-fix-preview1.sql` | 补 `card_channel_assoc` 表 + 27 列。用存储过程按 `information_schema` 判断,规避 MySQL 8 无 `ADD COLUMN IF NOT EXISTS` |
| 03 | `03-schema-align-prod.sql` | 补 `t_sms_template_config` 表 + 修正 `batch_no` 默认值 |
| 04 | `04-users.sh` | 建应用账号 `u_iotlcm`(口令取自 `MYSQL_APP_PASSWORD`)+ 可选库 `iotdb` |
| 05 | `05-reset-passwords.sh` | 把所有种子账号口令重置为 `MYSQL_ADMIN_PASSWORD`(按各账号自身 salt 重算哈希) |
| 04 | `04-users.sh` | 建应用账号 `iotlcm_app` + 可选库 `iotdb` |
| 05 | `05-reset-passwords.sh` | 把所有种子账号口令重置为脚本内设定的口令(按各账号自身 salt 重算哈希) |
| 06 | `06-seed-channel-templates.sql` | 通道模板 23 条(上游密钥已置空) |
| 07 | `07-seed-dict.sql` | 数据字典:`sys_dict_type` 86 类 + `sys_dict_data` 435 条 |
| 08 | `08-seed-mock-channel.sql` | **Mock 通道 `channel_yd_mock`**。演示卡全部挂在该通道上,缺则卡片管理的通道列、筛选、开停复机均不可用 |
| 09 | `09-seed-role-chain.sql` | 代理下发模板参数 + 角色下发标记 |
| 10 | `10-seed-jobs.sql` | 定时任务 19 条,**默认全部停用**(避免自动全量同步压满机器) |
| 11 | `11-seed-menu-align-prod.sql` | 菜单增量 27 条(含达量断网按钮权限、全量同步页) |
| 12 | `12-repair-dept-ancestors.sql` | `sys_dept.ancestors` 尾逗号归一化。全新库为空操作,仅用于修复既有库脏数据 |
| 12 | `12-repair-dept-ancestors.sql` | `sys_dept.ancestors` 尾逗号归一化。全新库为空操作 |
| 13 | `13-seed-flow-package.sql` | **占位文件**,流量套餐为空。需在管理端「套餐定价」中创建 |
## 口令说明
`04-users.sh` 与 `05-reset-passwords.sh` 里的口令是**字面值**(不使用环境变量),必须与以下位置保持一致:
| 口令 | 需同步的位置 |
| --- | --- |
| 应用账号 `iotlcm_app` | `docker-compose.yml` 的 `MYSQL_ROOT_PASSWORD`(root)与 `config/*/config.yaml` 里 database link 的口令 |
| 种子账号 | `docker-compose.yml` 里 admin 的初始化口令说明、`05-reset-passwords.sh` 的 `ADMIN_PASSWORD` |
改口令时三处一起改,漏改会导致服务连不上库或登录失败。
## 种子数据说明
@@ -50,44 +60,30 @@ docker compose up -d mysql
| --- | --- |
| 账号昵称 | `示例用户01` ~ `示例用户18` |
| 邮箱 | `user01@example.com` ~ `user18@example.com` |
| 手机号 | 合法 11 位编造号(`1380000` + 4 位序号,保持互异) |
| 手机号 | 合法 11 位编造号(保持互异) |
| 登录 IP | 清空 |
| 头像地址 | 清空 |
| 公司名 / 组织名 | `示例企业` / `示例代理` |
| 密码哈希 | 初始化时按 `MYSQL_ADMIN_PASSWORD` 重算 |
| 通道密钥 | 置空 |
### 空表(正常)
以下表在种子库中为空,属预期状态:
| 表 | 说明 |
| --- | --- |
| `t_sim_flow_package_info` | 流量套餐。为空时无法办理套餐/续费/改套餐,需自行在后台「套餐定价」中创建 |
| `t_sim_card` | 卡数据。可通过挡板服务的造卡接口生成测试卡 |
| `t_sim_channels` | 业务通道。Mock 通道由 `08` 脚本插入 |
| 其余 `t_*` 业务表 | 均为空,随业务操作产生数据 |
## 首次登录
| 项 | 值 |
| --- | --- |
| 地址 | `http://<宿主机IP><:ADMIN_UI_PORT>` |
| 账号 | `admin` |
| 口令 | `.env` 里的 `MYSQL_ADMIN_PASSWORD` |
其余演示账号的登录名见 `sys_user.user_name`,口令同为 `MYSQL_ADMIN_PASSWORD`。**所有账号登录后请立即修改口令。**
| `t_sim_flow_package_info` | 流量套餐,见 `13-seed-flow-package.sql` 说明 |
| `t_sim_card` | 卡数据,可通过挡板服务造卡或自行入库 |
| 其余 `t_*` 业务表 | 随业务操作产生数据 |
## 手动执行
容器已启动后需要单独执行某个脚本:
容器已启动后单独执行某个脚本:
```bash
docker compose exec -T mysql sh -c \
'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" db_iotlcm' < schema/07-seed-dict.sql
'exec mysql -uroot -p"<root口令>" db_iotlcm' < schema/07-seed-dict.sql
```
`.sh` 脚本需要环境变量,在容器内执行:
`.sh` 脚本:
```bash
docker compose exec mysql bash /docker-entrypoint-initdb.d/04-users.sh