105 lines
4.3 KiB
Python
105 lines
4.3 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""短信生态配置写入脚本(迁移自 PineSoundServer .env)。
|
||
|
||
把阿里云凭据/签名/区域与 PineSound 短信模板(仅本项目需要的 T1 登录)写入
|
||
system_configs 表:
|
||
|
||
- sms.provider -> aliyun
|
||
- sms.aliyun -> 凭据/签名/区域(与 PineSoundServer .env 完全一致:
|
||
ACCESS_KEY_ID / ACCESS_KEY_SECRET / REGION_ID=cn-qingdao /
|
||
SIGN_NAME=派音人工智能)
|
||
- sms.template.login -> SMS_510980133(PineSound T1 登录验证码,变量 code)
|
||
- sms.template.register -> SMS_510980133(本项目注册=手机号登录一体,复用 T1)
|
||
|
||
PineSound 其余模板(修改密码/绑定手机/找回密码/注销/充值/内测)本项目当前业务
|
||
未使用,不迁移;notification / order_status / appointment 场景 PineSound 无匹配
|
||
模板,保持留空(stub 打印,不阻断业务)。
|
||
|
||
用法:
|
||
python scripts/db/set_sms_config.py # 实际执行
|
||
python scripts/db/set_sms_config.py --dry-run # 只预览不写库
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import argparse
|
||
import asyncio
|
||
from pathlib import Path
|
||
|
||
from dotenv import load_dotenv
|
||
|
||
load_dotenv(Path(__file__).resolve().parent.parent.parent / ".env")
|
||
|
||
from sqlalchemy import text # noqa: E402
|
||
|
||
from app.infrastructure.db import AsyncSessionLocal # noqa: E402
|
||
from app.infrastructure.repositories import utcnow_iso # noqa: E402
|
||
|
||
# 与 PineSoundServer .env 完全一致的阿里云短信配置
|
||
ALIYUN_CONFIG = {
|
||
"access_key_id": "LTAI5t6ZU2Nf8qbGpEpn7bzN",
|
||
"access_key_secret": "lnNkxiXvNVsCPdc7hVZSXz6goOz8YJ",
|
||
"sign_name": "派音人工智能",
|
||
"region_id": "cn-qingdao",
|
||
"endpoint": "dysmsapi.aliyuncs.com",
|
||
}
|
||
|
||
# key -> (value, description);幂等覆盖:已存在的键也更新为 PineSound 配置。
|
||
SMS_CONFIGS: list[tuple[str, str, str]] = [
|
||
("sms.provider", "aliyun", "短信 provider(stub|aliyun)"),
|
||
("sms.aliyun",
|
||
__import__("json").dumps(ALIYUN_CONFIG, ensure_ascii=False),
|
||
"阿里云短信总配置(与 PineSoundServer .env 一致)"),
|
||
("sms.template.login",
|
||
'{"template_id":"SMS_510980133","variables":["code"]}',
|
||
"登录验证码模板(PineSound T1:验证码 code,5分钟有效,请勿泄露)"),
|
||
("sms.template.register",
|
||
'{"template_id":"SMS_510980133","variables":["code"]}',
|
||
"注册验证码模板(本项目注册=手机号登录一体,复用 T1)"),
|
||
("sms.template.notification",
|
||
'{"template_id":"","variables":[]}',
|
||
"通知提醒模板(PineSound 无匹配模板,暂留空)"),
|
||
("sms.template.order_status",
|
||
'{"template_id":"","variables":["order_no","status"]}',
|
||
"订单状态变动模板(PineSound 无匹配模板,暂留空)"),
|
||
("sms.template.appointment",
|
||
'{"template_id":"","variables":["service_name","schedule_at","contact"]}',
|
||
"服务预约模板(PineSound 无匹配模板,暂留空)"),
|
||
]
|
||
|
||
|
||
async def main(dry_run: bool) -> int:
|
||
now = utcnow_iso()
|
||
async with AsyncSessionLocal() as session:
|
||
for key, value, description in SMS_CONFIGS:
|
||
exists = (
|
||
await session.execute(
|
||
text("SELECT `key` FROM system_configs WHERE `key` = :k"),
|
||
{"k": key},
|
||
)
|
||
).scalar_one_or_none()
|
||
if exists:
|
||
sql = text(
|
||
"UPDATE system_configs SET `value` = :v, description = :d, "
|
||
"updated_at = :now WHERE `key` = :k"
|
||
)
|
||
else:
|
||
sql = text(
|
||
"INSERT INTO system_configs (`key`, `value`, `description`, "
|
||
"updated_at) VALUES (:k, :v, :d, :now)"
|
||
)
|
||
if dry_run:
|
||
print(f"[dry-run] {'UPDATE' if exists else 'INSERT'} {key} = {value}")
|
||
continue
|
||
await session.execute(sql, {"k": key, "v": value, "d": description, "now": now})
|
||
if not dry_run:
|
||
await session.commit()
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
parser = argparse.ArgumentParser(description="写入短信生态配置(PineSound 迁移)")
|
||
parser.add_argument("--dry-run", action="store_true", help="只预览不写库")
|
||
args = parser.parse_args()
|
||
raise SystemExit(asyncio.run(main(args.dry_run)))
|