Files
server-core/app/api/routers/rbac_public.py
T
Pine 416ade4842 feat: 统一权限聚合端点 + 事件名同步昵称 + IM/企业路由补强
- 新增 rbac_permissions 统一权限/组织归属聚合端点
- sync_event_name_to_nickname 脚本:事件名同步用户昵称
- im router/client、rbac_enterprise/opc/org/public 增强
- compute_catalog、nginx 配置、env.example 更新
2026-09-11 21:15:36 +08:00

88 lines
3.0 KiB
Python

# -*- coding: utf-8 -*-
"""公共配置端点:无需登录或特殊角色即可读取的站点级配置。
只暴露 ``site.`` 前缀的配置(如 Header 广告词),避免泄露短信密钥等敏感配置。
写入仍走 ``/admin/config/{key}``(要求 operator + config.manage 权限)。
"""
from __future__ import annotations
from fastapi import APIRouter, Depends
from ..dependencies import get_db
from ...infrastructure.repositories import Database
router = APIRouter(tags=["public"])
@router.get("/site/config", summary="公共站点配置列表(所有用户可读)")
async def list_site_config(
db: Database = Depends(get_db),
):
"""返回所有 ``site.`` 前缀的配置项,供桌面端 / 小程序 / web 端读取。
不要求登录或 operator 角色;敏感配置(短信密钥等)不会出现在这里。
"""
all_config = await db.config.all()
return [item for item in all_config if str(item.get("key", "")).startswith("site.")]
@router.get("/startup-resources", summary="启动页轮播资源列表(开放接口,无需权限)")
async def get_startup_resources(
db: Database = Depends(get_db),
):
"""返回启动页全屏轮播图的资源列表和配置。
资源列表从配置表 ``site.startup_resources`` 读取;如果未配置,返回兜底默认资源。
支持图片和视频,轮播时间、顺序、效果等由接口一次性返回。
返回格式:
{
"resources": [
{
"url": "https://.../image.jpg",
"type": "image", // image 或 video
"duration": 5000, // 该资源展示时长(毫秒)
"effect": "fade", // 轮播效果:fade/slide/3d/ink/zoom/blur
"order": 1 // 播放顺序
}
],
"settings": {
"loop": true, // 是否循环播放
"shuffle": false, // 是否随机顺序
"transition_duration": 1200 // 过渡动画时长(毫秒)
}
}
"""
# 尝试从配置表读取自定义资源列表
try:
config_item = await db.config.get("site.startup_resources")
if config_item and config_item.get("value"):
import json
value = config_item["value"]
if isinstance(value, str):
parsed = json.loads(value)
else:
parsed = value
if isinstance(parsed, dict) and "resources" in parsed:
return parsed
except Exception:
pass
# 兜底默认资源:本地 bg.mp4 视频循环播放
return {
"resources": [
{
"url": "/bg.mp4",
"type": "video",
"duration": 0, # 视频播放完自动切换,0 表示不限制
"effect": "fade",
"order": 1,
}
],
"settings": {
"loop": True,
"shuffle": False,
"transition_duration": 1500,
},
}