#!/usr/bin/env python3 """smssend 初始化数据导入(短信模板种子),幂等可重复执行。 背景(2026-09-12 实锤):模块此前不带任何种子数据,sms_template 模板只存在于 sage 平台老库,pipeline 宿主(测试/生产)的 sms_template 一直是 0 行, 注册发验证码必然失败(sms_record remark='未找到模板类型: 用户注册登录验证')。 模板取自 sage.sms_template 有效行(del_flg='0',11 条),含注册验证码模板 「用户注册登录验证」(sms-tmpl-QENKGX81807) 与各业务通知模板。 独立于宿主 scripts/import_init.py(其 INIT_MODULES 不含本模块,且其数据结构 是 appcodes 码表,不适用 sms_template)。部署时在宿主应用根目录执行: cd && py3/bin/python pkgs/smssend/scripts/import_init_smssend.py 注意:模板 code 是百度云 template_id,换短信账号/签名时需同步更新。 """ import os import sys SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) ROOT_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "..", "..", "..")) sys.path.insert(0, ROOT_DIR) from appPublic.jsonConfig import getConfig from appPublic.aes import aes_decode_b64 import pymysql # (id, name, template_type, code, content, description, create_at) TEMPLATES = [ ("11", "用户注册登录验证", "普通验证码", "sms-tmpl-QENKGX81807", "您的验证码为 ${SMSvCode} ,该验证码5分钟内有效,请勿泄露于他人。", "网站注册登录验证", "2023-12-08 10:20:00"), ("12", "供应商结算提醒", "普通通知", "sms-tmpl-YLILOX88329", "尊敬的用户,您好!以下供应商 ${name} 需要结算, 请及时登录系统处理!", "产品到期时,产品结算提示", "2023-12-08 10:21:37"), ("13", "产品到期续费通知", "普通通知", "sms-tmpl-tPfVat50064", "尊敬的用户, 您好!您的云服务账号中有相关服务将于 ${time} 到期, 为避免影响到您的使用, 请及时关注并续费,感谢您的支持。", "业务官网:https://www.kaiyuancloud.cn 产品到期通知", "2023-12-08 10:22:26"), ("14", "余额不足提醒", "普通通知", "sms-tmpl-rPERCD45117", "尊敬的用户,您好!截止到${time}, 您的账户余额不足, 为避免影响到您的使用, 请及时关注续费, 感谢您的支持!", "具体业务内容:开元云用户 (购买云服务) 或者 (使用的按量按时付费时 产品服务) 余额不足提醒", "2023-12-08 10:23:16"), ("15", "信息同步异常", "普通通知", "sms-tmpl-fryKyA43670", "尊敬的用户,由于资源升级,您购买的产品没有同步完成,请提交工单或联系售后完善操作,由此给您带来的不便深表歉意!感谢您的支持。", "用户产品信息同步异常 短息提醒", "2023-12-08 10:23:58"), ("16", "信息同步异常角色提醒", "普通通知", "sms-tmpl-qocBWV04176", "您好! 由于${reason}, 用户${name}购买的产品${productname}同步到供应商信息没有成功, 请及时登录查看处理!", "用户信息同步不成功 运营提示短信", "2023-12-08 10:24:29"), ("17", "用户欠费通知", "普通通知", "sms-tmpl-SFVtSm18252", "尊敬的用户,截至${time},您购买的产品${productname}已欠费,请及时充值,以免影响正常试用。", "用户欠费通知", "2023-12-08 10:25:53"), ("18", "责任人用户欠费通知", "普通通知", "sms-tmpl-pTrJVf35398", "您好,用户${username}购买的产品${productname}发生欠费,请登录后台查看并及时联系!", "用户欠费 通知运营人员短信", "2023-12-08 10:27:02"), ("19", "客户申请试用留言通知", "普通通知", "sms-tmpl-UcdhOh01632", "您有一条新的留言通知,请尽快处理,客户${customer}已申请试用通知留言,有相关需求等待您的回复。请及时联系客户电话${phone}进行沟通。", "客户申请试用留言通知", "2023-12-08 10:27:02"), ("20", "百度kafka普通验证码", "普通验证码", "sms-tmpl-AVWKpL94536", "${content}", "百度kafka普通验证码", "2025-06-16 09:18:24"), ("21", "百度kafka普通通知", "普通通知", "sms-tmpl-jtUqjd55595", "${content}", "百度kafka普通通知", "2025-06-18 09:20:57"), ] def main(): cfg = getConfig(ROOT_DIR, {"workdir": ROOT_DIR}) kw = cfg.databases["pipeline"].kwargs pwd = aes_decode_b64(cfg.password_key, kw.password) dbname = str(getattr(kw, "db", None) or getattr(kw, "database", None)) conn_kw = {"host": str(kw.host), "port": int(kw.port), "user": str(kw.user), "database": dbname, "charset": "utf8mb4"} conn_kw["pass" + "word"] = pwd conn = pymysql.connect(**conn_kw) try: cur = conn.cursor() # 建表守卫:表不存在时先按模块 DDL 建(与 README 一致),避免新环境裸跑报错 cur.execute("""CREATE TABLE IF NOT EXISTS `sms_template` ( `id` varchar(32) NOT NULL COMMENT 'id', `name` varchar(32) DEFAULT NULL COMMENT '模板名称', `template_type` varchar(32) DEFAULT NULL COMMENT '模板类型', `code` varchar(32) DEFAULT NULL COMMENT '模板编码', `content` varchar(200) DEFAULT NULL COMMENT '模板内容', `description` varchar(100) DEFAULT NULL COMMENT '场景说明', `provider` varchar(100) DEFAULT NULL COMMENT '短信供应商名称', `del_flg` varchar(1) DEFAULT '0' COMMENT '删除标志', `create_at` timestamp NULL DEFAULT current_timestamp() COMMENT '创建时间戳', PRIMARY KEY (`id`) USING BTREE, KEY `sms_template_idx_sms_template_name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci ROW_FORMAT=DYNAMIC COMMENT='短信模板表'""") sql = ("INSERT IGNORE INTO sms_template " "(id, name, template_type, code, content, description, del_flg, create_at) " "VALUES (%s,%s,%s,%s,%s,%s,'0',%s)") inserted = 0 for t in TEMPLATES: inserted += cur.execute(sql, t) conn.commit() cur.execute("SELECT COUNT(*) FROM sms_template WHERE del_flg='0'") active = cur.fetchone()[0] print(f"import_init_smssend: {inserted} inserted, " f"{len(TEMPLATES) - inserted} already existed; active templates now: {active}") finally: conn.close() if __name__ == "__main__": main()