Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions backend/.env.example
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Env
ENVIRONMENT='dev'
# Database
DATABASE_TYPE='mysql'
DATABASE_TYPE='postgresql'
DATABASE_HOST='127.0.0.1'
DATABASE_PORT=3306
DATABASE_USER='root'
DATABASE_PORT=5432
DATABASE_USER='postgres'
DATABASE_PASSWORD='123456'
# Redis
REDIS_HOST='127.0.0.1'
Expand Down
1 change: 0 additions & 1 deletion backend/app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ def get_app_models() -> list[type]:
apps = [d for d in list_dirs if os.path.isdir(os.path.join(app_path, d)) and d != '__pycache__']

objs = []

for app in apps:
module_path = f'backend.app.{app}.model'
obj = get_model_objects(module_path)
Expand Down
11 changes: 6 additions & 5 deletions backend/app/admin/model/data_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

from typing import TYPE_CHECKING

from sqlalchemy import String
import sqlalchemy as sa

from sqlalchemy.orm import Mapped, mapped_column, relationship

from backend.app.admin.model.m2m import sys_data_scope_rule
Expand All @@ -18,14 +19,14 @@ class DataRule(Base):
__tablename__ = 'sys_data_rule'

id: Mapped[id_key] = mapped_column(init=False)
name: Mapped[str] = mapped_column(String(500), unique=True, comment='名称')
model: Mapped[str] = mapped_column(String(50), comment='SQLA 模型名,对应 DATA_PERMISSION_MODELS 键名')
column: Mapped[str] = mapped_column(String(20), comment='模型字段名')
name: Mapped[str] = mapped_column(sa.String(500), unique=True, comment='名称')
model: Mapped[str] = mapped_column(sa.String(50), comment='SQLA 模型名,对应 DATA_PERMISSION_MODELS 键名')
column: Mapped[str] = mapped_column(sa.String(20), comment='模型字段名')
operator: Mapped[int] = mapped_column(comment='运算符(0:and、1:or)')
expression: Mapped[int] = mapped_column(
comment='表达式(0:==、1:!=、2:>、3:>=、4:<、5:<=、6:in、7:not_in)',
)
value: Mapped[str] = mapped_column(String(255), comment='规则值')
value: Mapped[str] = mapped_column(sa.String(255), comment='规则值')

# 数据范围规则多对多
scopes: Mapped[list[DataScope]] = relationship(init=False, secondary=sys_data_scope_rule, back_populates='rules')
5 changes: 3 additions & 2 deletions backend/app/admin/model/data_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

from typing import TYPE_CHECKING

from sqlalchemy import String
import sqlalchemy as sa

from sqlalchemy.orm import Mapped, mapped_column, relationship

from backend.app.admin.model.m2m import sys_data_scope_rule, sys_role_data_scope
Expand All @@ -18,7 +19,7 @@ class DataScope(Base):
__tablename__ = 'sys_data_scope'

id: Mapped[id_key] = mapped_column(init=False)
name: Mapped[str] = mapped_column(String(50), unique=True, comment='名称')
name: Mapped[str] = mapped_column(sa.String(50), unique=True, comment='名称')
status: Mapped[int] = mapped_column(default=1, comment='状态(0停用 1正常)')

# 数据范围规则多对多
Expand Down
23 changes: 9 additions & 14 deletions backend/app/admin/model/dept.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

from typing import TYPE_CHECKING

from sqlalchemy import BigInteger, Boolean, ForeignKey, String
from sqlalchemy.dialects.postgresql import INTEGER
import sqlalchemy as sa

from sqlalchemy.dialects.mysql import TINYINT
from sqlalchemy.orm import Mapped, mapped_column, relationship

from backend.common.model import Base, id_key
Expand All @@ -18,25 +19,19 @@ class Dept(Base):
__tablename__ = 'sys_dept'

id: Mapped[id_key] = mapped_column(init=False)
name: Mapped[str] = mapped_column(String(50), comment='部门名称')
name: Mapped[str] = mapped_column(sa.String(50), comment='部门名称')
sort: Mapped[int] = mapped_column(default=0, comment='排序')
leader: Mapped[str | None] = mapped_column(String(20), default=None, comment='负责人')
phone: Mapped[str | None] = mapped_column(String(11), default=None, comment='手机')
email: Mapped[str | None] = mapped_column(String(50), default=None, comment='邮箱')
leader: Mapped[str | None] = mapped_column(sa.String(20), default=None, comment='负责人')
phone: Mapped[str | None] = mapped_column(sa.String(11), default=None, comment='手机')
email: Mapped[str | None] = mapped_column(sa.String(50), default=None, comment='邮箱')
status: Mapped[int] = mapped_column(default=1, comment='部门状态(0停用 1正常)')
del_flag: Mapped[bool] = mapped_column(
Boolean().with_variant(INTEGER, 'postgresql'),
default=False,
comment='删除标志(0删除 1存在)',
sa.INTEGER().with_variant(TINYINT, 'mysql'), default=False, comment='删除标志(0删除 1存在)'
)

# 父级部门一对多
parent_id: Mapped[int | None] = mapped_column(
BigInteger,
ForeignKey('sys_dept.id', ondelete='SET NULL'),
default=None,
index=True,
comment='父部门ID',
sa.BigInteger, sa.ForeignKey('sys_dept.id', ondelete='SET NULL'), default=None, index=True, comment='父部门ID'
)
parent: Mapped[Dept | None] = relationship(init=False, back_populates='children', remote_side=[id])
children: Mapped[list[Dept] | None] = relationship(init=False, back_populates='parent')
Expand Down
26 changes: 13 additions & 13 deletions backend/app/admin/model/login_log.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from datetime import datetime

from sqlalchemy import String
import sqlalchemy as sa

from sqlalchemy.dialects.mysql import LONGTEXT
from sqlalchemy.dialects.postgresql import TEXT
from sqlalchemy.orm import Mapped, mapped_column

from backend.common.model import DataClassBase, TimeZone, id_key
Expand All @@ -15,18 +15,18 @@ class LoginLog(DataClassBase):
__tablename__ = 'sys_login_log'

id: Mapped[id_key] = mapped_column(init=False)
user_uuid: Mapped[str] = mapped_column(String(50), comment='用户UUID')
username: Mapped[str] = mapped_column(String(20), comment='用户名')
user_uuid: Mapped[str] = mapped_column(sa.String(50), comment='用户UUID')
username: Mapped[str] = mapped_column(sa.String(20), comment='用户名')
status: Mapped[int] = mapped_column(insert_default=0, comment='登录状态(0失败 1成功)')
ip: Mapped[str] = mapped_column(String(50), comment='登录IP地址')
country: Mapped[str | None] = mapped_column(String(50), comment='国家')
region: Mapped[str | None] = mapped_column(String(50), comment='地区')
city: Mapped[str | None] = mapped_column(String(50), comment='城市')
user_agent: Mapped[str] = mapped_column(String(255), comment='请求头')
os: Mapped[str | None] = mapped_column(String(50), comment='操作系统')
browser: Mapped[str | None] = mapped_column(String(50), comment='浏览器')
device: Mapped[str | None] = mapped_column(String(50), comment='设备')
msg: Mapped[str] = mapped_column(LONGTEXT().with_variant(TEXT, 'postgresql'), comment='提示消息')
ip: Mapped[str] = mapped_column(sa.String(50), comment='登录IP地址')
country: Mapped[str | None] = mapped_column(sa.String(50), comment='国家')
region: Mapped[str | None] = mapped_column(sa.String(50), comment='地区')
city: Mapped[str | None] = mapped_column(sa.String(50), comment='城市')
user_agent: Mapped[str] = mapped_column(sa.String(255), comment='请求头')
os: Mapped[str | None] = mapped_column(sa.String(50), comment='操作系统')
browser: Mapped[str | None] = mapped_column(sa.String(50), comment='浏览器')
device: Mapped[str | None] = mapped_column(sa.String(50), comment='设备')
msg: Mapped[str] = mapped_column(sa.TEXT().with_variant(LONGTEXT, 'mysql'), comment='提示消息')
login_time: Mapped[datetime] = mapped_column(TimeZone, comment='登录时间')
created_time: Mapped[datetime] = mapped_column(
TimeZone,
Expand Down
56 changes: 33 additions & 23 deletions backend/app/admin/model/m2m.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,62 @@
from sqlalchemy import BigInteger, Column, ForeignKey, Table
import sqlalchemy as sa

from backend.common.model import MappedBase

sys_user_role = Table(
sys_user_role = sa.Table(
'sys_user_role',
MappedBase.metadata,
Column('id', BigInteger, primary_key=True, unique=True, index=True, autoincrement=True, comment='主键ID'),
Column('user_id', BigInteger, ForeignKey('sys_user.id', ondelete='CASCADE'), primary_key=True, comment='用户ID'),
Column('role_id', BigInteger, ForeignKey('sys_role.id', ondelete='CASCADE'), primary_key=True, comment='角色ID'),
sa.Column('id', sa.BigInteger, primary_key=True, unique=True, index=True, autoincrement=True, comment='主键ID'),
sa.Column(
'user_id', sa.BigInteger, sa.ForeignKey('sys_user.id', ondelete='CASCADE'), primary_key=True, comment='用户ID'
),
sa.Column(
'role_id', sa.BigInteger, sa.ForeignKey('sys_role.id', ondelete='CASCADE'), primary_key=True, comment='角色ID'
),
)

sys_role_menu = Table(
sys_role_menu = sa.Table(
'sys_role_menu',
MappedBase.metadata,
Column('id', BigInteger, primary_key=True, unique=True, index=True, autoincrement=True, comment='主键ID'),
Column('role_id', BigInteger, ForeignKey('sys_role.id', ondelete='CASCADE'), primary_key=True, comment='角色ID'),
Column('menu_id', BigInteger, ForeignKey('sys_menu.id', ondelete='CASCADE'), primary_key=True, comment='菜单ID'),
sa.Column('id', sa.BigInteger, primary_key=True, unique=True, index=True, autoincrement=True, comment='主键ID'),
sa.Column(
'role_id', sa.BigInteger, sa.ForeignKey('sys_role.id', ondelete='CASCADE'), primary_key=True, comment='角色ID'
),
sa.Column(
'menu_id', sa.BigInteger, sa.ForeignKey('sys_menu.id', ondelete='CASCADE'), primary_key=True, comment='菜单ID'
),
)

sys_role_data_scope = Table(
sys_role_data_scope = sa.Table(
'sys_role_data_scope',
MappedBase.metadata,
Column('id', BigInteger, primary_key=True, unique=True, index=True, autoincrement=True, comment='主键 ID'),
Column('role_id', BigInteger, ForeignKey('sys_role.id', ondelete='CASCADE'), primary_key=True, comment='角色 ID'),
Column(
sa.Column('id', sa.BigInteger, primary_key=True, unique=True, index=True, autoincrement=True, comment='主键 ID'),
sa.Column(
'role_id', sa.BigInteger, sa.ForeignKey('sys_role.id', ondelete='CASCADE'), primary_key=True, comment='角色 ID'
),
sa.Column(
'data_scope_id',
BigInteger,
ForeignKey('sys_data_scope.id', ondelete='CASCADE'),
sa.BigInteger,
sa.ForeignKey('sys_data_scope.id', ondelete='CASCADE'),
primary_key=True,
comment='数据范围 ID',
),
)

sys_data_scope_rule = Table(
sys_data_scope_rule = sa.Table(
'sys_data_scope_rule',
MappedBase.metadata,
Column('id', BigInteger, primary_key=True, unique=True, index=True, autoincrement=True, comment='主键ID'),
Column(
sa.Column('id', sa.BigInteger, primary_key=True, unique=True, index=True, autoincrement=True, comment='主键ID'),
sa.Column(
'data_scope_id',
BigInteger,
ForeignKey('sys_data_scope.id', ondelete='CASCADE'),
sa.BigInteger,
sa.ForeignKey('sys_data_scope.id', ondelete='CASCADE'),
primary_key=True,
comment='数据范围 ID',
),
Column(
sa.Column(
'data_rule_id',
BigInteger,
ForeignKey('sys_data_rule.id', ondelete='CASCADE'),
sa.BigInteger,
sa.ForeignKey('sys_data_rule.id', ondelete='CASCADE'),
primary_key=True,
comment='数据规则 ID',
),
Expand Down
32 changes: 11 additions & 21 deletions backend/app/admin/model/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

from typing import TYPE_CHECKING

from sqlalchemy import BigInteger, ForeignKey, String
import sqlalchemy as sa

from sqlalchemy.dialects.mysql import LONGTEXT
from sqlalchemy.dialects.postgresql import TEXT
from sqlalchemy.orm import Mapped, mapped_column, relationship

from backend.app.admin.model.m2m import sys_role_menu
Expand All @@ -20,35 +20,25 @@ class Menu(Base):
__tablename__ = 'sys_menu'

id: Mapped[id_key] = mapped_column(init=False)
title: Mapped[str] = mapped_column(String(50), comment='菜单标题')
name: Mapped[str] = mapped_column(String(50), comment='菜单名称')
path: Mapped[str | None] = mapped_column(String(200), comment='路由地址')
title: Mapped[str] = mapped_column(sa.String(50), comment='菜单标题')
name: Mapped[str] = mapped_column(sa.String(50), comment='菜单名称')
path: Mapped[str | None] = mapped_column(sa.String(200), comment='路由地址')
sort: Mapped[int] = mapped_column(default=0, comment='排序')
icon: Mapped[str | None] = mapped_column(String(100), default=None, comment='菜单图标')
icon: Mapped[str | None] = mapped_column(sa.String(100), default=None, comment='菜单图标')
type: Mapped[int] = mapped_column(default=0, comment='菜单类型(0目录 1菜单 2按钮 3内嵌 4外链)')
component: Mapped[str | None] = mapped_column(String(255), default=None, comment='组件路径')
perms: Mapped[str | None] = mapped_column(String(100), default=None, comment='权限标识')
component: Mapped[str | None] = mapped_column(sa.String(255), default=None, comment='组件路径')
perms: Mapped[str | None] = mapped_column(sa.String(100), default=None, comment='权限标识')
status: Mapped[int] = mapped_column(default=1, comment='菜单状态(0停用 1正常)')
display: Mapped[int] = mapped_column(default=1, comment='是否显示(0否 1是)')
cache: Mapped[int] = mapped_column(default=1, comment='是否缓存(0否 1是)')
link: Mapped[str | None] = mapped_column(
LONGTEXT().with_variant(TEXT, 'postgresql'),
default=None,
comment='外链地址',
)
remark: Mapped[str | None] = mapped_column(
LONGTEXT().with_variant(TEXT, 'postgresql'),
default=None,
comment='备注',
sa.TEXT().with_variant(LONGTEXT, 'mysql'), default=None, comment='外链地址'
)
remark: Mapped[str | None] = mapped_column(sa.TEXT().with_variant(LONGTEXT, 'mysql'), default=None, comment='备注')

# 父级菜单一对多
parent_id: Mapped[int | None] = mapped_column(
BigInteger,
ForeignKey('sys_menu.id', ondelete='SET NULL'),
default=None,
index=True,
comment='父菜单ID',
sa.BigInteger, sa.ForeignKey('sys_menu.id', ondelete='SET NULL'), default=None, index=True, comment='父菜单ID'
)
parent: Mapped[Menu | None] = relationship(init=False, back_populates='children', remote_side=[id])
children: Mapped[list[Menu] | None] = relationship(init=False, back_populates='parent')
Expand Down
43 changes: 20 additions & 23 deletions backend/app/admin/model/opera_log.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from datetime import datetime

from sqlalchemy import String
from sqlalchemy.dialects.mysql import JSON, LONGTEXT
from sqlalchemy.dialects.postgresql import TEXT
import sqlalchemy as sa

from sqlalchemy.dialects.mysql import LONGTEXT
from sqlalchemy.orm import Mapped, mapped_column

from backend.common.model import DataClassBase, TimeZone, id_key
Expand All @@ -15,28 +15,25 @@ class OperaLog(DataClassBase):
__tablename__ = 'sys_opera_log'

id: Mapped[id_key] = mapped_column(init=False)
trace_id: Mapped[str] = mapped_column(String(32), comment='请求跟踪 ID')
username: Mapped[str | None] = mapped_column(String(20), comment='用户名')
method: Mapped[str] = mapped_column(String(20), comment='请求类型')
title: Mapped[str] = mapped_column(String(255), comment='操作模块')
path: Mapped[str] = mapped_column(String(500), comment='请求路径')
ip: Mapped[str] = mapped_column(String(50), comment='IP地址')
country: Mapped[str | None] = mapped_column(String(50), comment='国家')
region: Mapped[str | None] = mapped_column(String(50), comment='地区')
city: Mapped[str | None] = mapped_column(String(50), comment='城市')
user_agent: Mapped[str] = mapped_column(LONGTEXT().with_variant(TEXT, 'postgresql'), comment='请求头')
os: Mapped[str | None] = mapped_column(String(50), comment='操作系统')
browser: Mapped[str | None] = mapped_column(String(50), comment='浏览器')
device: Mapped[str | None] = mapped_column(String(50), comment='设备')
args: Mapped[str | None] = mapped_column(JSON(), comment='请求参数')
trace_id: Mapped[str] = mapped_column(sa.String(32), comment='请求跟踪 ID')
username: Mapped[str | None] = mapped_column(sa.String(20), comment='用户名')
method: Mapped[str] = mapped_column(sa.String(20), comment='请求类型')
title: Mapped[str] = mapped_column(sa.String(255), comment='操作模块')
path: Mapped[str] = mapped_column(sa.String(500), comment='请求路径')
ip: Mapped[str] = mapped_column(sa.String(50), comment='IP地址')
country: Mapped[str | None] = mapped_column(sa.String(50), comment='国家')
region: Mapped[str | None] = mapped_column(sa.String(50), comment='地区')
city: Mapped[str | None] = mapped_column(sa.String(50), comment='城市')
user_agent: Mapped[str] = mapped_column(sa.String(255), comment='请求头')
os: Mapped[str | None] = mapped_column(sa.String(50), comment='操作系统')
browser: Mapped[str | None] = mapped_column(sa.String(50), comment='浏览器')
device: Mapped[str | None] = mapped_column(sa.String(50), comment='设备')
args: Mapped[str | None] = mapped_column(sa.JSON(), comment='请求参数')
status: Mapped[int] = mapped_column(comment='操作状态(0异常 1正常)')
code: Mapped[str] = mapped_column(String(20), insert_default='200', comment='操作状态码')
msg: Mapped[str | None] = mapped_column(LONGTEXT().with_variant(TEXT, 'postgresql'), comment='提示消息')
code: Mapped[str] = mapped_column(sa.String(20), insert_default='200', comment='操作状态码')
msg: Mapped[str | None] = mapped_column(sa.TEXT().with_variant(LONGTEXT, 'mysql'), comment='提示消息')
cost_time: Mapped[float] = mapped_column(insert_default=0.0, comment='请求耗时(ms)')
opera_time: Mapped[datetime] = mapped_column(TimeZone, comment='操作时间')
created_time: Mapped[datetime] = mapped_column(
TimeZone,
init=False,
default_factory=timezone.now,
comment='创建时间',
TimeZone, init=False, default_factory=timezone.now, comment='创建时间'
)
18 changes: 6 additions & 12 deletions backend/app/admin/model/role.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

from typing import TYPE_CHECKING

from sqlalchemy import Boolean, String
from sqlalchemy.dialects.mysql import LONGTEXT
from sqlalchemy.dialects.postgresql import INTEGER, TEXT
import sqlalchemy as sa

from sqlalchemy.dialects.mysql import LONGTEXT, TINYINT
from sqlalchemy.orm import Mapped, mapped_column, relationship

from backend.app.admin.model.m2m import sys_role_data_scope, sys_role_menu, sys_user_role
Expand All @@ -20,18 +20,12 @@ class Role(Base):
__tablename__ = 'sys_role'

id: Mapped[id_key] = mapped_column(init=False)
name: Mapped[str] = mapped_column(String(20), unique=True, comment='角色名称')
name: Mapped[str] = mapped_column(sa.String(20), unique=True, comment='角色名称')
status: Mapped[int] = mapped_column(default=1, comment='角色状态(0停用 1正常)')
is_filter_scopes: Mapped[bool] = mapped_column(
Boolean().with_variant(INTEGER, 'postgresql'),
default=True,
comment='过滤数据权限(0否 1是)',
)
remark: Mapped[str | None] = mapped_column(
LONGTEXT().with_variant(TEXT, 'postgresql'),
default=None,
comment='备注',
sa.INTEGER().with_variant(TINYINT, 'mysql'), default=True, comment='过滤数据权限(0否 1是)'
)
remark: Mapped[str | None] = mapped_column(sa.TEXT().with_variant(LONGTEXT, 'mysql'), default=None, comment='备注')

# 角色用户多对多
users: Mapped[list[User]] = relationship(init=False, secondary=sys_user_role, back_populates='roles')
Expand Down
Loading