import asyncio import threading from datetime import datetime import pytz # 后台操作 def async_new_task(func, *args, **kwargs): threading.Thread(target=func, args=args, kwargs=kwargs, daemon=True).start() async def async_task(func, *args, **kwargs): return await asyncio.to_thread(func, *args, **kwargs) def format_datetime(dt: datetime, tz="Asia/Shanghai"): if dt.tzinfo is None: dt = pytz.UTC.localize(dt) tz_obj = pytz.timezone(tz) dt = dt.astimezone(tz_obj) return dt.strftime("%Y-%m-%d %H:%M:%S") def safe_round(value, ndigits=2, default=None): return round(value, ndigits) if value is not None else default def build_dept_tree(depts): dept_map = {d["id"]: d for d in depts} roots = [] for d in depts: pid = d["pid"] if pid and pid in dept_map: dept_map[pid]["children"].append(d) else: # pid 为 0 或不存在 → 顶层 roots.append(d) return roots def build_menu_tree(items): item_map = {item["id"]: item for item in items} tree = [] for item in items: pid = item["pid"] if pid and pid in item_map: item_map[pid]["children"].append(item) else: tree.append(item) return tree from uuid import UUID def is_valid_uuid(value: str): try: UUID(value) return True except: return False