Files
FastapiAdmin/backend/app/api/v1/module_platform/package/model.py
T
zhangtao 73f2823692 refactor: 大规模代码整理与功能优化
1. 重构后端API路由、CRUD与模块结构,整合日志管理,移除废弃demo代码
2. 优化前端组件类型定义、样式与路由配置,修复权限判断逻辑
3. 调整默认排序规则、滚动条样式与工具类函数,更新依赖与配置文件
4. 修复多处类型不匹配与默认值问题,完善表单与菜单验证逻辑
2026-06-17 01:56:31 +08:00

103 lines
3.9 KiB
Python

from sqlalchemy import ForeignKey, Integer, String, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, validates
from app.core.base_model import MappedBase, ModelMixin
class PackageModel(ModelMixin):
"""
套餐模型 - 定义租户可用的功能套餐
status: 0=正常 1=禁用
"""
__tablename__: str = "platform_package"
__table_args__: dict[str, str] = {"comment": "租户套餐表"}
name: Mapped[str] = mapped_column(String(100), nullable=False, unique=True, comment="套餐名称")
code: Mapped[str] = mapped_column(String(100), nullable=False, unique=True, comment="套餐编码")
sort: Mapped[int] = mapped_column(Integer, nullable=False, default=0, comment="排序")
# ─── 定价与计费 ───
price: Mapped[int] = mapped_column(Integer, nullable=False, default=0, comment="价格(分)")
period: Mapped[str] = mapped_column(String(10), nullable=False, default="month", comment="计费周期(month/year)")
trial_days: Mapped[int] = mapped_column(Integer, nullable=False, default=0, comment="免费试用天数")
# ─── 配额限制 ───
max_users: Mapped[int] = mapped_column(Integer, nullable=False, default=10, comment="最大用户数")
max_roles: Mapped[int] = mapped_column(Integer, nullable=False, default=5, comment="最大角色数")
max_depts: Mapped[int] = mapped_column(Integer, nullable=False, default=10, comment="最大部门数")
max_storage_mb: Mapped[int] = mapped_column(Integer, nullable=False, default=1024, comment="最大存储(MB)")
# ─── 速率限制 ───
rate_limit: Mapped[int] = mapped_column(
Integer, nullable=False, default=60, comment="API速率限制(请求/10秒)"
)
@validates("name")
def validate_name(self, key: str, name: str) -> str:
if not name or not name.strip():
raise ValueError("套餐名称不能为空")
return name
@validates("code")
def validate_code(self, key: str, code: str) -> str:
if not code or not code.strip():
raise ValueError("套餐编码不能为空")
if not code.isalnum():
raise ValueError("套餐编码只能包含字母和数字")
return code
class PackageMenuModel(MappedBase):
"""
套餐-菜单关联表 — 定义套餐包含的菜单资源
"""
__tablename__: str = "platform_package_menu"
__table_args__ = (
UniqueConstraint("package_id", "menu_id", name="uq_package_menu"),
{"comment": "套餐菜单关联表"},
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True, comment="主键ID")
package_id: Mapped[int] = mapped_column(
Integer,
ForeignKey("platform_package.id", ondelete="CASCADE", onupdate="CASCADE"),
nullable=False,
index=True,
comment="套餐ID",
)
menu_id: Mapped[int] = mapped_column(
Integer,
ForeignKey("platform_menu.id", ondelete="CASCADE", onupdate="CASCADE"),
nullable=False,
index=True,
comment="菜单ID",
)
class PackagePluginModel(MappedBase):
"""
套餐-插件关联表 — 定义套餐包含的插件资源
"""
__tablename__: str = "platform_package_plugin"
__table_args__ = (
UniqueConstraint("package_id", "plugin_id", name="uq_package_plugin"),
{"comment": "套餐插件关联表"},
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True, comment="主键ID")
package_id: Mapped[int] = mapped_column(
Integer,
ForeignKey("platform_package.id", ondelete="CASCADE", onupdate="CASCADE"),
nullable=False,
index=True,
comment="套餐ID",
)
plugin_id: Mapped[int] = mapped_column(
Integer,
ForeignKey("platform_plugin.id", ondelete="CASCADE", onupdate="CASCADE"),
nullable=False,
index=True,
comment="插件ID",
)