from tortoise import fields from tortoise import fields as Fields from app.schemas.menus import MenuType from .base import BaseModel, TimestampMixin from .enums import MethodType class User(BaseModel, TimestampMixin): username = fields.CharField(max_length=20, unique=True, description="用户名称", index=True) alias = fields.CharField(max_length=30, null=True, description="姓名", index=True) email = fields.CharField(max_length=255, unique=True, description="邮箱", index=True) phone = fields.CharField(max_length=20, null=True, description="电话", index=True) password = fields.CharField(max_length=128, null=True, description="密码") is_active = fields.BooleanField(default=True, description="是否激活", index=True) is_superuser = fields.BooleanField(default=False, description="是否为超级管理员", index=True) last_login = fields.DatetimeField(null=True, description="最后登录时间", index=True) roles = fields.ManyToManyField("models.Role", related_name="user_roles") dept_id = fields.IntField(null=True, description="部门ID", index=True) class Meta: table = "user" class Role(BaseModel, TimestampMixin): name = fields.CharField(max_length=20, unique=True, description="角色名称", index=True) desc = fields.CharField(max_length=500, null=True, description="角色描述") menus = fields.ManyToManyField("models.Menu", related_name="role_menus") apis = fields.ManyToManyField("models.Api", related_name="role_apis") class Meta: table = "role" class Api(BaseModel, TimestampMixin): path = fields.CharField(max_length=100, description="API路径", index=True) method = fields.CharEnumField(MethodType, description="请求方法", index=True) summary = fields.CharField(max_length=500, description="请求简介", index=True) tags = fields.CharField(max_length=100, description="API标签", index=True) class Meta: table = "api" class Menu(BaseModel, TimestampMixin): name = fields.CharField(max_length=20, description="菜单名称", index=True) remark = fields.JSONField(null=True, description="保留字段") menu_type = fields.CharEnumField(MenuType, null=True, description="菜单类型") icon = fields.CharField(max_length=100, null=True, description="菜单图标") path = fields.CharField(max_length=100, description="菜单路径", index=True) order = fields.IntField(default=0, description="排序", index=True) parent_id = fields.IntField(default=0, description="父菜单ID", index=True) is_hidden = fields.BooleanField(default=False, description="是否隐藏") component = fields.CharField(max_length=100, description="组件") keepalive = fields.BooleanField(default=True, description="存活") redirect = fields.CharField(max_length=100, null=True, description="重定向") class Meta: table = "menu" class Dept(BaseModel, TimestampMixin): name = fields.CharField(max_length=20, unique=True, description="部门名称", index=True) desc = fields.CharField(max_length=500, null=True, description="备注") is_deleted = fields.BooleanField(default=False, description="软删除标记", index=True) order = fields.IntField(default=0, description="排序", index=True) parent_id = fields.IntField(default=0, max_length=10, description="父部门ID", index=True) class Meta: table = "dept" class DeptClosure(BaseModel, TimestampMixin): ancestor = fields.IntField(description="父代", index=True) descendant = fields.IntField(description="子代", index=True) level = fields.IntField(default=0, description="深度", index=True) class AuditLog(BaseModel, TimestampMixin): user_id = fields.IntField(description="用户ID", index=True) username = fields.CharField(max_length=64, default="", description="用户名称", index=True) module = fields.CharField(max_length=64, default="", description="功能模块", index=True) summary = fields.CharField(max_length=128, default="", description="请求描述", index=True) method = fields.CharField(max_length=10, default="", description="请求方法", index=True) path = fields.CharField(max_length=255, default="", description="请求路径", index=True) status = fields.IntField(default=-1, description="状态码", index=True) response_time = fields.IntField(default=0, description="响应时间(单位ms)", index=True) request_args = fields.JSONField(null=True, description="请求参数") response_body = fields.JSONField(null=True, description="返回数据") class Codegen(BaseModel, TimestampMixin): """ { "name": "user", "author": "Ly997", "description": "系统用户管理", "version": "1.0.0", "fields": [ { "name": "id", "type": "Long", "primary_key": true, "description": "用户ID", "required": true, "editable": true, "listable": true, "detailable": true, "sortable": true, "filterable": true, "filter_operator": "equal", "display_type": "text" }, { "name": "username", "type": "String", "length": 50, "description": "用户名", "required": true, "unique": true, "validations": [ { "type": "min_length", "value": 4 }, { "type": "max_length", "value": 20 } ], "editable": true, "listable": true, "detailable": true, "sortable": true, "filterable": true, "filter_operator": "equal", "display_type": "text" }, { "name": "email", "type": "String", "description": "电子邮箱", "required": true, "validations": [ { "type": "email" } ], "editable": true, "listable": true, "detailable": true, "sortable": true, "filterable": true, "filter_operator": "equal", "display_type": "text" }, { "name": "password_hash", "type": "String", "description": "密码哈希", "required": true, "secret": true, "editable": true, "listable": true, "detailable": true, "sortable": true, "filterable": true, "filter_operator": "equal", "display_type": "text" }, { "name": "is_active", "type": "Boolean", "description": "是否激活", "default": true, "editable": true, "listable": true, "detailable": true, "sortable": true, "filterable": true, "filter_operator": "equal", "display_type": "text" }, { "name": "created_at", "type": "DateTime", "description": "创建时间", "auto_now_add": true, "editable": true, "listable": true, "detailable": true, "sortable": true, "filterable": true, "filter_operator": "equal", "display_type": "text" }, { "name": "updated_at", "type": "DateTime", "description": "更新时间", "auto_now": true, "editable": true, "listable": true, "detailable": true, "sortable": true, "filterable": true, "filter_operator": "equal", "display_type": "text" } ], "relations": [ { "name": "roles", "type": "many-to-many", "target": "role", "through": "user_roles", "description": "用户角色关联" }, { "name": "posts", "type": "one-to-many", "target": "post", "description": "用户发表的文章" } ], "api": { "operations": [ "create", "read", "update", "delete", "list" ], "base_path": "/users", "auth_required": true, "permissions": { "create": [ "admin", "manager" ], "delete": [ "admin" ] } }, "menu": { "label": "用户管理", "icon": "user", "order": 10, "submenu": [ { "label": "用户列表", "path": "/users", "icon": "list" }, { "label": "角色管理", "path": "/roles" } ] } } """ name = Fields.CharField(max_length=64, description="名称", index=True) author = Fields.CharField(max_length=64, description="作者", index=True) description = Fields.CharField(max_length=500, description="描述") version = Fields.CharField(max_length=64, description="版本", index=True) fields = Fields.JSONField(description="字段") relations = Fields.JSONField(description="关系") api = Fields.JSONField(description="API", null=True) menu = Fields.JSONField(description="菜单", null=True) class Meta: table = "codegen" async def dumps(self, output_type='pydantic'): from app.schemas.codegen import BaseCodegen obj_dict = await self.to_dict() # print('type(obj_dict["fields"])', type(obj_dict["fields"])) # print('type(obj_dict["relations"])', type(obj_dict["relations"])) # print('type(obj_dict["api"])', type(obj_dict["api"])) # obj_dict['fields'] = json.loads(obj_dict['fields']) # obj_dict['relations'] = json.loads(obj_dict['relations']) # obj_dict['api'] = json.loads(obj_dict['api']) # obj_dict['menu'] = json.loads(obj_dict['menu']) if output_type == 'pydantic': return BaseCodegen(**obj_dict) else : return obj_dict class Datasource(BaseModel, TimestampMixin): tableName = Fields.CharField(max_length=32, description="名称", index=True) tableComment = Fields.CharField(max_length=64, description="注释", index=True) class Meta: table = "datasource"