bce8cd9923
一、RBAC 权限管理(角色 → 可见页面) - 新增 admin_role 表 + 权限目录 permissions.py:角色持有一组页面 key,登录后左侧只展示这些页 - 内建角色 管理员(super_admin 全权锁定)/运营/财务/技术,页集对齐原型;key 承重(require_role 用),另加中文 label 展示 - 角色 CRUD 端点(仅 super_admin)+ 目录端点;登录/me 下发当前角色有效可见页 - admins 加删除、角色存在性校验;可复看已确定登录密码:UI 建的账号留存明文 plain_password,脚本建的超管不留存 二、系统配置下发修复 - 首页数据「保存即生效」:显式保存(apply_now)对 real/manual 直接落配置目标值、绕过只增不减护栏(修「改了 app 端不变」),护栏仍管自动 tick - 首页轮播新增数据源三选一:mixed(真实优先+种子)/real(只真实)/seed(只种子),get_feed 分支 + /marquee-seeds/mode 端点 - 福利页 Tab 隐藏 任务/里程碑,及看广告的单次金币/每轮次数/信息流开关:CONFIG_DEFS 加 hidden + list_config 过滤,业务读取默认值不受影响 三、比价记录店/商品搜索 - comparison_record 加 product_names 派生列(从下单 items 拼商品名),迁移建列并回填历史行 - admin 比价记录列表店/商品分列可搜:走 product_names 普通列 LIKE,规避 SQLite JSON 中文 ensure_ascii 转义搜不到的坑 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
82 lines
2.6 KiB
Python
82 lines
2.6 KiB
Python
"""admin_role 表 CRUD + 「角色 → 有效可见页」解析。"""
|
|
from __future__ import annotations
|
|
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.admin.permissions import (
|
|
ALL_PAGE_KEYS,
|
|
BUILTIN_ROLES,
|
|
SUPER_ADMIN_ROLE,
|
|
sanitize_pages,
|
|
)
|
|
from app.models.admin_role import AdminRole
|
|
|
|
|
|
def ensure_builtin_roles(db: Session) -> None:
|
|
"""空表时播种内建角色(管理员/运营/财务/技术)。幂等:表非空即 no-op。
|
|
给 create_all 环境(测试 / 未跑迁移的全新库)兜底,迁移已播种则不重复。
|
|
仅 super_admin 为 is_builtin(锁定不可改删);运营/财务/技术可编辑页/删除。"""
|
|
if db.execute(select(AdminRole.id).limit(1)).first() is not None:
|
|
return
|
|
db.add_all([
|
|
AdminRole(
|
|
name=r["name"], label=r["label"], pages=list(r["pages"]),
|
|
is_builtin=(r["name"] == SUPER_ADMIN_ROLE),
|
|
)
|
|
for r in BUILTIN_ROLES
|
|
])
|
|
db.commit()
|
|
|
|
|
|
def list_roles(db: Session) -> list[AdminRole]:
|
|
ensure_builtin_roles(db)
|
|
# super_admin(内建)恒排最前,其余按创建序
|
|
return list(
|
|
db.execute(
|
|
select(AdminRole).order_by(AdminRole.is_builtin.desc(), AdminRole.id)
|
|
).scalars().all()
|
|
)
|
|
|
|
|
|
def get_role(db: Session, name: str) -> AdminRole | None:
|
|
return db.execute(
|
|
select(AdminRole).where(AdminRole.name == name)
|
|
).scalar_one_or_none()
|
|
|
|
|
|
def create_role(db: Session, *, name: str, label: str, pages: list[str]) -> AdminRole:
|
|
# 自定义角色:name(key)= label = 用户输入的名称
|
|
role = AdminRole(name=name, label=label, pages=sanitize_pages(pages), is_builtin=False)
|
|
db.add(role)
|
|
db.commit()
|
|
db.refresh(role)
|
|
return role
|
|
|
|
|
|
def update_role(
|
|
db: Session, role: AdminRole, *, label: str | None = None, pages: list[str] | None = None
|
|
) -> AdminRole:
|
|
# 只改展示名 label + 可见页;name(key)不可变(admin_user.role / require_role 承重)
|
|
if label is not None:
|
|
role.label = label
|
|
if pages is not None:
|
|
role.pages = sanitize_pages(pages)
|
|
db.commit()
|
|
db.refresh(role)
|
|
return role
|
|
|
|
|
|
def delete_role(db: Session, role: AdminRole) -> None:
|
|
db.delete(role)
|
|
db.commit()
|
|
|
|
|
|
def effective_pages_of(db: Session, role_name: str) -> list[str]:
|
|
"""某角色名的有效可见页:super_admin → 全部;其余 → 查表 pages 与目录取交。"""
|
|
if role_name == SUPER_ADMIN_ROLE:
|
|
return list(ALL_PAGE_KEYS)
|
|
ensure_builtin_roles(db)
|
|
role = get_role(db, role_name)
|
|
return sanitize_pages(role.pages if role else None)
|