mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-10-08 10:39:59 +00:00
refactor: 整合仪表盘功能到监控模块,清理冗余代码
- 移除原监控仪表盘独立模块,将相关功能合并到在线监控模块 - 重构租户配置字段名,统一使用logo_url和name替代tenant_logo/tenant_name - 优化搜索工具函数,移除重复导入 - 调整参数配置模型字段长度限制,移除config_value的max_length约束 - 清理冗余的常量定义和导入语句 - 修复批量状态设置接口的redis依赖注入 - 增强OAuth登录安全性,添加租户默认归属和state一次性消费 - 优化资源目录缓存逻辑,减少重复计算 - 新增API Token模块基础框架 - 完善用户token版本管理,支持主动失效JWT - 调整AI模型配置缓存过期时间 - 修复菜单类型字段索引,提升查询性能 - 简化前端刷新token调用逻辑 - 新增滑块验证完成接口和忘记密码验证码校验 - 调整系统配置默认值,添加操作日志保留天数和接口白名单配置 - 限制Mock支付回调仅在开发环境可用 - 重构websocket认证方式,支持更安全的subprotocol传参
This commit is contained in:
@@ -4,13 +4,15 @@ from fastapi import APIRouter, Body, Depends, Path, Query, Request, Security, st
|
||||
from fastapi.responses import JSONResponse
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.common.enums import RET
|
||||
from app.common.enums import RET, EnvironmentEnum
|
||||
from app.common.response import ErrorResponse, ResponseSchema, SuccessResponse
|
||||
from app.config.setting import settings
|
||||
from app.core.base_schema import AuthSchema, PageResultSchema, PaginationQueryParam
|
||||
from app.core.dependencies import AuthPermission, db_getter
|
||||
from app.core.exceptions import CustomException
|
||||
from app.core.logger import logger
|
||||
from app.core.router_class import OperationLogRoute
|
||||
from app.utils.payment import get_mock_gateway
|
||||
|
||||
from .schema import (
|
||||
OrderCreateSchema,
|
||||
@@ -102,8 +104,8 @@ async def order_pay_create_controller(
|
||||
async def order_pay_status_controller(
|
||||
db: Annotated[AsyncSession, Depends(db_getter)],
|
||||
order_id: Annotated[int, Path(description="订单ID", ge=1)],
|
||||
auth: Annotated[AuthSchema, Security(AuthPermission(["module_platform:order:query"], check_data_scope=False))],
|
||||
) -> JSONResponse:
|
||||
auth = AuthSchema(check_data_scope=False)
|
||||
result = await OrderService.check_payment_status(auth=auth, db=db, order_id=order_id)
|
||||
return SuccessResponse(data=result)
|
||||
|
||||
@@ -124,12 +126,18 @@ async def order_pay_callback_controller(
|
||||
return ErrorResponse(msg=str(e))
|
||||
|
||||
|
||||
@OrderRouter.post("/mock/callback", summary="Mock 支付回调(开发环境触发模拟支付)", response_model=ResponseSchema[dict])
|
||||
@OrderRouter.post("/mock/callback", summary="Mock 支付回调(仅开发/测试环境可用)", response_model=ResponseSchema[dict])
|
||||
async def order_pay_mock_callback_controller(
|
||||
db: Annotated[AsyncSession, Depends(db_getter)],
|
||||
order_id: Annotated[int, Body(description="订单ID", ge=1)],
|
||||
) -> JSONResponse:
|
||||
from app.utils.payment import get_mock_gateway
|
||||
# Mock 回调仅在 DEV 环境暴露;生产环境必须通过真实支付网关的 webhook 触发
|
||||
if settings.ENVIRONMENT != EnvironmentEnum.DEV:
|
||||
raise CustomException(
|
||||
msg="Mock 支付回调仅在开发环境可用",
|
||||
code=RET.FORBIDDEN.code,
|
||||
status_code=403,
|
||||
)
|
||||
|
||||
from .service import OrderService
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"""订单与支付 CRUD"""
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.core.base_crud import CRUDBase
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
import random
|
||||
import secrets
|
||||
import string
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy import func, select
|
||||
from sqlalchemy import update as sa_update
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.api.v1.module_system.dept.model import DeptModel
|
||||
from app.api.v1.module_system.role.model import RoleModel
|
||||
from app.api.v1.module_system.user.model import UserModel
|
||||
from app.core.base_schema import AuthSchema
|
||||
from app.core.database import async_db_session
|
||||
from app.core.event_bus import EventBus
|
||||
from app.core.exceptions import CustomException
|
||||
from app.core.logger import logger
|
||||
from app.utils.payment import create_payment_gateway
|
||||
|
||||
from ..package.model import PackageModel
|
||||
from ..tenant.model import TenantModel
|
||||
from .crud import OrderCRUD
|
||||
from .model import OrderModel
|
||||
from .schema import (
|
||||
@@ -27,16 +35,19 @@ from .schema import (
|
||||
|
||||
|
||||
def _generate_order_no() -> str:
|
||||
"""生成订单号:YYYYMMDD + 6位随机数"""
|
||||
"""生成订单号:YYYYMMDD + 10位加密安全随机数(碰撞概率极低)。
|
||||
|
||||
使用 :func:`secrets.choice` 而非 ``random``,避免伪随机带来的可预测性。
|
||||
"""
|
||||
today = datetime.now().strftime("%Y%m%d")
|
||||
suffix = str(random.randint(100000, 999999))
|
||||
return f"{today}{suffix}"
|
||||
rand = "".join(secrets.choice(string.digits) for _ in range(10))
|
||||
return f"{today}{rand}"
|
||||
|
||||
|
||||
def _generate_refund_no() -> str:
|
||||
"""生成退款单号"""
|
||||
today = datetime.now().strftime("%Y%m%d")
|
||||
suffix = str(random.randint(100000, 999999))
|
||||
suffix = "".join(secrets.choice(string.digits) for _ in range(6))
|
||||
return f"RF{today}{suffix}"
|
||||
|
||||
|
||||
@@ -65,10 +76,10 @@ class OrderService:
|
||||
- OrderOutSchema: 新创建的订单详情
|
||||
"""
|
||||
if amount is None:
|
||||
from app.api.v1.module_platform.package.model import PackageModel
|
||||
|
||||
pkg = await db.get(PackageModel, data.package_id)
|
||||
amount = pkg.price if pkg else 0
|
||||
if not pkg:
|
||||
raise CustomException(msg=f"套餐[{data.package_id}]不存在或已删除")
|
||||
amount = pkg.price
|
||||
|
||||
order = await OrderCRUD(auth, db).create(
|
||||
OrderCreateInternalSchema(
|
||||
@@ -189,10 +200,6 @@ class OrderService:
|
||||
|
||||
@staticmethod
|
||||
async def cancel_expired_orders() -> None:
|
||||
from sqlalchemy import update as sa_update
|
||||
|
||||
from app.core.database import async_db_session
|
||||
|
||||
now = datetime.now()
|
||||
async with async_db_session() as session:
|
||||
async with session.begin():
|
||||
@@ -224,8 +231,6 @@ class PaymentService:
|
||||
返回:
|
||||
- PaymentCreateOut: 支付创建结果(支付URL/二维码)
|
||||
"""
|
||||
from app.api.v1.module_platform.package.model import PackageModel
|
||||
|
||||
order = await OrderCRUD(auth, db).get_by_id(order_id)
|
||||
if not order:
|
||||
raise CustomException(msg="该数据不存在")
|
||||
@@ -305,17 +310,12 @@ class PaymentService:
|
||||
),
|
||||
)
|
||||
|
||||
order.package_id = pid
|
||||
order.tenant_id = tid
|
||||
order.order_type = otype
|
||||
# order 已被 update refresh,直接传给激活方法
|
||||
await PaymentService._activate_tenant_package(auth, db, order)
|
||||
|
||||
logger.info(f"支付回调处理完成: order_id={oid} method={method} tenant_id={tid} type={otype}")
|
||||
|
||||
# SSE 推送支付成功通知
|
||||
from app.api.v1.module_platform.package.model import PackageModel
|
||||
from app.core.event_bus import EventBus
|
||||
|
||||
_pkg = await db.get(PackageModel, pid)
|
||||
await EventBus.publish_tenant(
|
||||
tid,
|
||||
@@ -340,9 +340,6 @@ class PaymentService:
|
||||
返回:
|
||||
- None
|
||||
"""
|
||||
from app.api.v1.module_platform.package.model import PackageModel
|
||||
from app.api.v1.module_platform.tenant.model import TenantModel
|
||||
|
||||
pkg = await db.get(PackageModel, order.package_id)
|
||||
if not pkg:
|
||||
logger.warning(f"支付回调:套餐 {order.package_id} 不存在,跳过激活")
|
||||
@@ -391,12 +388,6 @@ class PaymentService:
|
||||
返回:
|
||||
- None
|
||||
"""
|
||||
from sqlalchemy import func
|
||||
|
||||
from app.api.v1.module_system.dept.model import DeptModel
|
||||
from app.api.v1.module_system.role.model import RoleModel
|
||||
from app.api.v1.module_system.user.model import UserModel
|
||||
|
||||
checks = {
|
||||
"用户": (UserModel, new_pkg.max_users),
|
||||
"角色": (RoleModel, new_pkg.max_roles),
|
||||
|
||||
Reference in New Issue
Block a user