# 老系统设备迁移快照导出脚本

这个工具只负责从老系统 `legacy_mysql` 导出设备迁移所需的业务快照，不写入新系统数据库，也不生成新系统导入 SQL。

## 导出范围

- 设备号/IMEI：从你提供的输入 CSV 读取；不提供 ICCID 时，脚本会按老库 `tbl_card.vcode`/`tbl_card.imei` 反查主卡，并通过 `tbl_card_relate` 展开关联副卡。
- 卡当前快照：从 `tbl_card` 读取当前卡状态、老套餐字段、当前已用量等。
- 套餐快照：从 `tbl_card_life` 和 `tbl_next_month_card_life` 读取当前/次月套餐事实。
- 卡钱包快照：从 `tbl_card_wallet` 读取余额和自动续费字段。
- 佣金账户快照：按卡所属老代理，从 `tbl_agent_commission_account` 读取账户累计金额。
- 日流量记录：不导出，只保留当前已用量和剩余量建议值。

## 输入 CSV

脚本会自动识别常见表头。最省事的输入只需要设备号/IMEI，不需要提供 SN 和 ICCID。SN 只是随导出结果透传，可不填。

支持的常见表头：

```csv
imei
862639076004532
```

如果业务给的是设备号字段，也可以写成：

```csv
device_virtual_no
862639076004532
```

如果业务后续能直接给 ICCID，脚本也仍然支持单卡或多卡槽 ICCID 输入。

可识别字段包括：

- 设备号：`device_virtual_no`、`device_no`、`virtual_no`、`mchno`、`设备号`、`设备虚拟号`、`机器码`
- IMEI：`imei`、`device_imei`、`mchno`、`设备imei`、`机器码`
- SN：`sn`、`设备sn`
- 单卡：`iccid`、`卡号`、`主卡`、`main_iccid`
- 多卡槽：`iccid1`、`iccid_1`、`slot1_iccid`、`card1`、`sim1`、`卡1`，最多识别到 4 个卡槽

## 使用方式

```bash
export LEGACY_MYSQL_DSN='user:password@tcp(host:3306)/kyhl'

go run ./scripts/legacy_device_export \
  -input ./devices.csv \
  -out ./legacy_device_export_output
```

也可以通过参数指定库名：

```bash
go run ./scripts/legacy_device_export \
  -dsn 'user:password@tcp(host:3306)/kyhl' \
  -schema kyhl \
  -input ./devices.csv \
  -out ./legacy_device_export_output
```

默认不会导出佣金明细。如需按输入 ICCID 额外导出 `tbl_agent_commission_detail` 明细，可加：

```bash
-include-commission-details
```

## 输出文件

- `input_assets.csv`：标准化后的输入设备/卡关系。
- `unresolved_inputs.csv`：无法通过输入 ICCID 或设备号/IMEI 解析出老库 ICCID 的行。
- `card_snapshot.csv`：老卡本体快照和当前已用量，并给出 `tb_iot_card.data_usage_mb`、`current_month_usage_mb`、`last_gateway_reading_mb` 的导入建议值；状态/类型/运营商分类会同时输出中文 `*_name` 列，也会保留老卡 `expire_time`。
- `package_usage_snapshot.csv`：老套餐快照，以及按当前已用量分摊出来的 `allocated_used_mb`、`remaining_mb` 建议值；老套餐状态、新系统建议状态会同时输出中文 `*_name` 列。时间字段同时输出老库原始 `start_at`/`expires_at` 和迁移参考 `effective_start_at`/`effective_expires_at`，具体来源看 `date_source_note`。
- `wallet_snapshot.csv`：老卡钱包余额和自动续费信息，自动续费状态会同时输出中文 `*_name` 列。
- `commission_account_snapshot.csv`：老代理佣金账户快照，预留 `suggested_new_shop_id` 供后续导入时映射新系统店铺。
- `missing_cards.csv`：输入 ICCID 在老库 `tbl_card` 中未命中的清单。
- `summary.txt`：本次导出摘要。
- `field_dictionary.csv`：所有输出字段的中文说明。
- `enum_dictionary.csv`：状态码、类型码、来源表等枚举值说明。
- `README_zh.md`：随本次导出生成的阅读入口和口径提醒。
- `commission_detail_snapshot.csv`：仅在传入 `-include-commission-details` 时生成。

## 注意事项

- `package_usage_snapshot.csv` 的已用量分摊是迁移建议值，后续生成新系统导入 SQL 前仍需要结合新系统套餐系列、套餐和供应商映射复核。
- 输入 CSV 可以不提供 SN 和 ICCID；不提供 ICCID 时会先按老库 `tbl_card.vcode`，再兼容 `tbl_card.imei` 反查 ICCID，并通过 `tbl_card_relate` 展开关联卡。
- CSV 表头保留英文是为了后续脚本稳定读取；人工查看时优先看同表的 `*_name` 中文列、`field_dictionary.csv` 和 `enum_dictionary.csv`。
- 老库部分 `tbl_card_life.start_date` 为空，但 `expire_date` 和 `create_time` 有值；脚本会保留原始空值，并在 `effective_start_at` 用 `create_time` 兜底，避免误以为没有导出。
- 新系统轮询流量会根据网关当前读数和 `last_gateway_reading_mb` 计算增量，后续导入脚本应优先使用 `card_snapshot.csv` 中的 `suggested_tb_iot_card_last_gateway_reading_mb` 避免首轮重复扣量。
- 这个脚本不会修改老系统或新系统数据。
