prepare_platform_data.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import asyncio
  2. import json
  3. import secrets
  4. from pathlib import Path
  5. from uuid import UUID
  6. from sqlalchemy.ext.asyncio import async_sessionmaker
  7. from zhifu.core.config import Settings
  8. from zhifu.core.database import create_engine
  9. from zhifu.modules.identity.auth import now, password_hasher
  10. from zhifu.modules.identity.models import Tenant
  11. from zhifu.modules.platform.models import PlatformAccount, TenantRegistration
  12. async def main():
  13. settings = Settings()
  14. if settings.environment == "production":
  15. raise ValueError("开发平台账户仅允许在 development 或 test 环境创建")
  16. target = Path(".work/platform-accounts.json")
  17. existing = (
  18. json.loads(await asyncio.to_thread(target.read_text, encoding="utf-8"))
  19. if await asyncio.to_thread(target.exists) else None
  20. )
  21. password = existing["password"] if existing else secrets.token_urlsafe(24)
  22. actor_id = UUID("ac700000-2026-4000-8000-000000000050")
  23. tenant_id = UUID("ac700000-2026-4000-8000-000000000001")
  24. engine = create_engine(settings)
  25. try:
  26. sessions = async_sessionmaker(engine, expire_on_commit=False)
  27. async with sessions.begin() as session:
  28. account = await session.get(PlatformAccount, actor_id.bytes)
  29. if account is None:
  30. session.add(PlatformAccount(
  31. id=actor_id.bytes, username="platform-admin",
  32. password_hash=password_hasher.hash(password),
  33. status="ACTIVE", permissions=["platform:manage"], created_at=now(),
  34. ))
  35. elif existing is None:
  36. raise ValueError("平台账户已存在,本地账户凭据文件缺失")
  37. tenant = await session.get(Tenant, tenant_id.bytes)
  38. if tenant is None:
  39. raise ValueError("请先准备前端开发商家账户")
  40. registration = await session.get(TenantRegistration, tenant_id.bytes)
  41. if registration is None:
  42. session.add(TenantRegistration(
  43. tenant_id=tenant_id.bytes, contact="开发环境接入管理员",
  44. status="COMPLETE", created_at=now(),
  45. ))
  46. tenant_name = tenant.name
  47. target.parent.mkdir(exist_ok=True)
  48. await asyncio.to_thread(target.write_text, json.dumps({
  49. "username": "platform-admin", "password": password, "actor_id": str(actor_id),
  50. "tenant_id": str(tenant_id), "tenant_name": tenant_name,
  51. }, ensure_ascii=False, indent=2), encoding="utf-8")
  52. print("平台开发账户已准备,凭据保存在 .work/platform-accounts.json,未输出密码。")
  53. finally:
  54. await engine.dispose()
  55. if __name__ == "__main__":
  56. asyncio.run(main())