All checks were successful
技能自动化发布 / release (push) Successful in 8s
Data-management add/edit now use short forms with enums; copy clones a platform account into a new empty profile. Co-authored-by: Cursor <cursoragent@cursor.com>
54 lines
1.9 KiB
Python
54 lines
1.9 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""账号名称副本编号、登录标识类型推断。"""
|
||
from __future__ import annotations
|
||
|
||
import re
|
||
from typing import Iterable, Optional
|
||
|
||
_COPY_SUFFIX_RE = re.compile(r"^(.*?)(?: 副本(?: (\d+))?)?$")
|
||
_EMAIL_RE = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$")
|
||
_CN_MOBILE_RE = re.compile(r"^1\d{10}$")
|
||
_PHONE_RE = re.compile(r"^\+?\d{8,15}$")
|
||
_PHONE_STRIP_RE = re.compile(r"[\s\-()]")
|
||
|
||
KNOWN_LOGIN_ID_TYPES = frozenset(
|
||
{"email", "username", "phone", "customer_code", "api_account", "unknown"}
|
||
)
|
||
KNOWN_ACCOUNT_STATUSES = frozenset({"active", "disabled", "needs_review"})
|
||
|
||
|
||
def infer_login_id_type(login_id: Optional[str]) -> str:
|
||
"""从登录标识猜类型;空则 unknown。"""
|
||
text = (login_id or "").strip()
|
||
if not text:
|
||
return "unknown"
|
||
if _EMAIL_RE.match(text):
|
||
return "email"
|
||
compact = _PHONE_STRIP_RE.sub("", text)
|
||
if _CN_MOBILE_RE.match(compact) or _PHONE_RE.match(compact):
|
||
return "phone"
|
||
return "username"
|
||
|
||
|
||
def resolve_login_id_type(explicit: Optional[str], login_id: Optional[str]) -> str:
|
||
"""有明确类型(且不是 unknown)时用明确值,否则按 login_id 推断。"""
|
||
typed = (explicit or "").strip()
|
||
if typed and typed != "unknown":
|
||
return typed
|
||
return infer_login_id_type(login_id)
|
||
|
||
|
||
def next_copy_label(source_label: str, existing_labels: Iterable[str]) -> str:
|
||
"""在已有名称中生成「原名 副本」/「原名 副本 2」…,避免叠「副本 副本」。"""
|
||
raw = (source_label or "").strip() or "账号"
|
||
existing = {item.strip().lower() for item in existing_labels if (item or "").strip()}
|
||
match = _COPY_SUFFIX_RE.match(raw)
|
||
stem = (match.group(1).strip() if match else raw) or raw
|
||
n = 1
|
||
while n <= 9999:
|
||
candidate = f"{stem} 副本" if n == 1 else f"{stem} 副本 {n}"
|
||
if candidate.lower() not in existing:
|
||
return candidate
|
||
n += 1
|
||
return f"{stem} 副本 {n}"
|