小鹅通课程学员批量导入
把格式各异的学员名单,整理成小鹅通后台能直接吃的 .csv。
典型输入:商家甩来一串手机号、聊天里粘的一大段号码、一个 学员名单.xlsx、一张名单截图。
典型输出:一份 .csv,商家拿去后台「课程 → 学员 → 批量导入」上传即可。
核心价值:格式的坑全部由脚本兜住。你只负责把"给谁、多久"问清楚。
一、格式速查(脚本已保证,你不需要手写)
| 项 | 硬要求 |
|---|---|
| 文件 | CSV,UTF-8 带 BOM,LF 换行(Excel 打开不乱码的关键) |
| 第 1 行 | 官方「导入说明(必读)」整段(1 个字段 + 4 个空字段位) |
| 第 2 行 | 表头,5 列,文案与顺序一字不能改 |
| 第 3 行起 | 数据行,恒为 5 个字段,空值留空但逗号不能省 |
| 列 1 | 手机号/用户ID(必填):11 位手机号,或 u_ 开头的用户ID |
| 列 2 | 课程有效期(必填):30天 / 长期有效 / 2027/3/1 23:59:59到期 |
| 列 3 | 姓名(最多64个字)(选填) |
| 列 4 | 备注(最多20个字)(选填) |
| 列 5 | 公司名(最多20个字)(选填) |
标准数据行长这样(注意行尾那串逗号):
13511112222,30天,张三,张三先生,小鹅通
13511112223,长期有效,李四,,
u_60d1599c35cyh_xxxxxxxxxx,2027/3/1 23:59:59到期,,,
官方原文与每条规则的出处见 @references/format-spec.md。
二、工作流
Step 0 · 先问清有效期(唯一必须问的事)
有效期是必填项,且脚本无法替你猜。
- 用户说了("开通一年"/"到明年 6 月"/"长期")→ 直接用,脚本会自动归一化。
- 用户没说 → 问一句:「这批学员的课程有效期给多久?(30天 / 长期有效 / 具体到期日)」
- 用户说"你看着办" → 用
30天,并在交付说明里显眼标注"按 30 天开的,要改告诉我"。
用户明确说"统一 30 天"这种,不要再为其他人逐行追问;表格里自带有效期列的,以表格为准。
Step 1 · 收输入
| 输入形态 | 怎么处理 |
|---|---|
| 一串号码(对话里粘贴) | 直接传给 --text,不用先整理 |
.csv / .tsv / .txt |
直接 --input |
.xlsx / .xlsm |
直接 --input(取第 1 个工作表,符合官方要求) |
.xls 老格式 |
让用户另存为 xlsx 或 csv |
| 名单截图 | 先读图把号码抄出来,抄完必须回读核对一遍,错一位就是给别人开了课 |
Step 2 · 生成
# 对话里粘的一串号码
python3 scripts/build_import.py \
--text "13511112222 135 1111 2223 +8613611112224" \
--validity 30天 \
--out ~/Desktop/学员导入.csv
# 表格文件(自动认表头、自动认有效期列)
python3 scripts/build_import.py \
--input ~/Desktop/学员名单.xlsx \
--out ~/Desktop/学员导入.csv
脚本会打印解析报告:可导入几条、排除了哪些、为什么排除、哪些被截断。
Step 3 · 读报告,别跳过
看到"已排除"就要在交付说明里逐条告诉用户是哪个号码、什么原因。
看到"提醒"(名字超 64 字被截断、3个月按今天换算成具体日期)也要说。
绝不因为某一行有问题就悄悄丢掉整个文件,也绝不编造一个号码凑数。
Step 4 · 校验(硬门槛)
python3 scripts/verify_import.py ~/Desktop/学员导入.csv --expect <数据行数>
必须看到 ✓ 校验通过 才能交付。看到 ✗ 就回去修,别解释、别绕过。
Step 5 · 交付
用 present_files 打开 CSV,并用一段话说明:
- 共几条学员、有效期统一是什么(或分布)
- 排除了几条、分别是什么原因
- 有没有被截断的姓名/备注/公司名
- 上传路径:小鹅通店铺后台 → 课程 → 学员 → 批量导入
- 一句提醒:不要用 Excel 打开后另存(会把手机号变成科学计数法、BOM 也可能丢)
三、铁律
- 不要手写 CSV。 少一个逗号就整列错位,且后台只报"导入异常"不告诉你哪行错。
- 不要用 Excel 另存。 要预览可以打开看,保存一律回到脚本生成的那份文件。
- 不要编造手机号。 号码错一位就是给陌生人开了课,且无法撤回。
- 有效期不能空。 空的会被后台拒,也会让脚本报"缺少课程有效期"。
- 新用户必须用手机号。 从未访问过店铺的人给用户ID 是导不进去的,只有手机号才能自动建号。
- 提醒覆盖规则。 重复导入已有学员时,后台按本次文件更新有效期;但对方现有权益更长或为长期有效时保持不变。所以"续期"这个动作靠这个文件做不到,别向用户承诺。
四、已知踩坑(脚本已处理,但你得知道原理)
| 坑 | 现象 | 本技能怎么绕开 |
|---|---|---|
| 手机号带空格 | 135 1111 2222 被按空格拆成 3 条垃圾数据 |
按 3-4-4 分组模式整体识别,不按空格切 |
| 全角数字 | 13511112222 导入失败 |
先做 NFKC 归一化 |
+86 / 0086 前缀 |
13 位被判为非法 | 自动剥离国家码 |
| 用户ID 里的下划线 | u_60d1..._abc 被当分隔符删掉 |
先认 u_ 前缀,再清洗手机号分隔符 |
| 备注里写半角逗号 | 整行多出一列,后面全错位 | 文本字段的半角逗号自动转全角「,」 |
| 名字太长 | 超 64 字后台导入异常 | 自动截断并在报告里点名 |
| 有效期写"30天后" | 无法识别,导入失败 | 报错并提示标准写法,不瞎猜 |
| 到期日已过 | 后台直接导入失败 | 生成阶段就拦下并列出 |
| Excel 日期单元格 | 被读成 46000 这种序列号 |
自动按 Excel 纪元换算成真实日期 |
五、文件清单(缺一个都会跑不起来)
xiaoe-student-import/
├── SKILL.md # 本文件
├── references/
│ ├── format-spec.md # 官方格式原文 + 字段口径 + 解析规则(权威依据)
│ └── usage-examples.md # 4 个真实场景:输入 → 命令 → 输出
└── scripts/
├── build_import.py # 名单 → 合规 CSV(含清洗、归一化、去重、报告)
├── verify_import.py # 成品逐项校验(独立实现,不共用生成代码)
└── selftest.py # 回归自检,含负向对照,71 项
依赖:Python 3 标准库即可;读 .xlsx 需要 openpyxl(没装会提示另存 CSV)。
装完想确认没坏,跑一句:python3 scripts/selftest.py,应输出 全部通过 ✓。