Optimize and normalize the code generator (#430)

This commit is contained in:
Wu Clan
2024-09-24 13:50:02 +08:00
committed by GitHub
parent 1d3b0e7d13
commit ab4495ce65
11 changed files with 230 additions and 193 deletions

View File

@ -33,7 +33,7 @@ async def get_all_businesses() -> ResponseModel:
@router.get('/businesses/{pk}', summary='获取代码生成业务详情', dependencies=[DependsJwtAuth])
async def get_business(pk: Annotated[int, Path(...)]) -> ResponseModel:
business = await gen_service.get_business_with_model(pk=pk)
business = await gen_business_service.get(pk=pk)
data = GetGenBusinessListDetails(**select_as_dict(business))
return response_base.success(data=data)
@ -89,6 +89,12 @@ async def delete_business(pk: Annotated[int, Path(...)]) -> ResponseModel:
return response_base.fail()
@router.get('/models/types', summary='获取代码生成模型列类型', dependencies=[DependsJwtAuth])
async def get_model_types() -> ResponseModel:
model_types = await gen_model_service.get_types()
return response_base.success(data=model_types)
@router.get('/models/{pk}', summary='获取代码生成模型详情', dependencies=[DependsJwtAuth])
async def get_model(pk: Annotated[int, Path(...)]) -> ResponseModel:
model = await gen_model_service.get(pk=pk)

View File

@ -2,21 +2,11 @@
# -*- coding: utf-8 -*-
from typing import Sequence
from sqlalchemy import Row, select, text
from sqlalchemy import Row, text
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from backend.app.generator.model import GenBusiness
class CRUDGen:
@staticmethod
async def get_business_with_model(db: AsyncSession, business_id: int) -> GenBusiness:
stmt = select(GenBusiness).options(selectinload(GenBusiness.gen_model)).where(GenBusiness.id == business_id)
result = await db.execute(stmt)
data = result.scalars().first()
return data
@staticmethod
async def get_all_tables(db: AsyncSession, table_schema: str) -> Sequence[str]:
stmt = text(

View File

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
from typing import Sequence
from sqlalchemy import update
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy_crud_plus import CRUDPlus
@ -34,6 +35,7 @@ class CRUDGenModel(CRUDPlus[GenModel]):
:param db:
:param obj_in:
:param pd_type:
:return:
"""
await self.create_model(db, obj_in, pd_type=pd_type)
@ -45,9 +47,12 @@ class CRUDGenModel(CRUDPlus[GenModel]):
:param db:
:param pk:
:param obj_in:
:param pd_type:
:return:
"""
return await self.update_model_by_column(db, obj_in, id=pk, pd_type=pd_type)
stmt = update(self.model).where(self.model.id == pk).values(**obj_in.model_dump(), pd_type=pd_type)
result = await db.execute(stmt)
return result.rowcount
async def delete(self, db: AsyncSession, pk: int) -> int:
"""

View File

@ -2,7 +2,6 @@
# -*- coding: utf-8 -*-
from pydantic import ConfigDict, Field, field_validator
from backend.common.enums import GenModelColumnType
from backend.common.schema import SchemaBase
from backend.utils.type_conversion import sql_type_to_sqlalchemy
@ -10,7 +9,7 @@ from backend.utils.type_conversion import sql_type_to_sqlalchemy
class GenModelSchemaBase(SchemaBase):
name: str
comment: str | None = None
type: GenModelColumnType = Field(GenModelColumnType.VARCHAR)
type: str
default: str | None = None
sort: int
length: int

View File

@ -5,6 +5,7 @@ from typing import Sequence
from backend.app.generator.crud.crud_gen_model import gen_model_dao
from backend.app.generator.model import GenModel
from backend.app.generator.schema.gen_model import CreateGenModelParam, UpdateGenModelParam
from backend.common.enums import GenModelMySQLColumnType
from backend.common.exception import errors
from backend.database.db_mysql import async_db_session
from backend.utils.type_conversion import sql_type_to_pydantic
@ -17,6 +18,12 @@ class GenModelService:
gen_model = await gen_model_dao.get(db, pk)
return gen_model
@staticmethod
async def get_types() -> list[str]:
types = GenModelMySQLColumnType.get_member_keys()
types.sort()
return types
@staticmethod
async def get_by_business(*, business_id: int) -> Sequence[GenModel]:
async with async_db_session() as db:

View File

@ -18,20 +18,14 @@ from backend.app.generator.model import GenBusiness
from backend.app.generator.schema.gen_business import CreateGenBusinessParam
from backend.app.generator.schema.gen_model import CreateGenModelParam
from backend.app.generator.service.gen_model_service import gen_model_service
from backend.common.enums import GenModelColumnType
from backend.common.exception import errors
from backend.core.path_conf import BasePath
from backend.database.db_mysql import async_db_session
from backend.utils.gen_template import gen_template
from backend.utils.type_conversion import sql_type_to_pydantic
class GenService:
@staticmethod
async def get_business_with_model(*, pk: int) -> GenBusiness:
async with async_db_session() as db:
business = await gen_dao.get_business_with_model(db, pk)
return business
@staticmethod
async def get_tables(*, table_schema: str) -> Sequence[str]:
async with async_db_session() as db:
@ -60,19 +54,18 @@ class GenService:
column_info = await gen_dao.get_all_columns(db, table_schema, table_name)
for column in column_info:
column_type = column[-1].split('(')[0].upper()
pd_type = sql_type_to_pydantic(column_type)
model_data = {
'name': column[0],
'comment': column[-2],
'type': column_type,
'sort': column[-3],
'length': column[-1].split('(')[1][:-1]
if column_type == GenModelColumnType.CHAR or column_type == GenModelColumnType.VARCHAR
else 0,
'length': column[-1].split('(')[1][:-1] if pd_type == 'str' and '(' in column[-1] else 0,
'is_pk': column[1],
'is_nullable': column[2],
'gen_business_id': new_business.id,
}
await gen_model_dao.create(db, CreateGenModelParam(**model_data))
await gen_model_dao.create(db, CreateGenModelParam(**model_data), pd_type=pd_type)
@staticmethod
async def render_tpl_code(*, business: GenBusiness) -> dict:

View File

@ -90,50 +90,151 @@ class UserSocialType(StrEnum):
linuxdo = 'LinuxDo'
class GenModelColumnType(StrEnum):
"""代码生成模型列类型"""
class GenModelMySQLColumnType(StrEnum):
"""代码生成模型列类型MySQL"""
BIGINT = 'BIGINT'
BINARY = 'BINARY'
BIT = 'BIT'
BLOB = 'BLOB'
BOOL = 'BOOL'
BOOLEAN = 'BOOLEAN'
CHAR = 'CHAR'
DATE = 'DATE'
DATETIME = 'DATETIME'
DECIMAL = 'DECIMAL'
DOUBLE = 'DOUBLE'
DOUBLE_PRECISION = 'DOUBLE PRECISION'
ENUM = 'ENUM'
FLOAT = 'FLOAT'
GEOMETRY = 'GEOMETRY'
GEOMETRYCOLLECTION = 'GEOMETRYCOLLECTION'
INT = 'INT'
INTEGER = 'INTEGER'
JSON = 'JSON'
LINESTRING = 'LINESTRING'
LONGBLOB = 'LONGBLOB'
LONGTEXT = 'LONGTEXT'
MEDIUMBLOB = 'MEDIUMBLOB'
MEDIUMINT = 'MEDIUMINT'
MEDIUMTEXT = 'MEDIUMTEXT'
MULTILINESTRING = 'MULTILINESTRING'
MULTIPOINT = 'MULTIPOINT'
MULTIPOLYGON = 'MULTIPOLYGON'
NUMERIC = 'NUMERIC'
POINT = 'POINT'
POLYGON = 'POLYGON'
REAL = 'REAL'
SERIAL = 'SERIAL'
SET = 'SET'
SMALLINT = 'SMALLINT'
TEXT = 'TEXT'
TIME = 'TIME'
TIMESTAMP = 'TIMESTAMP'
TINYBLOB = 'TINYBLOB'
TINYINT = 'TINYINT'
TINYTEXT = 'TINYTEXT'
VARBINARY = 'VARBINARY'
VARCHAR = 'VARCHAR'
YEAR = 'YEAR'
# Python 类型映射
BIGINT = 'int'
BigInteger = 'int' # BIGINT
BINARY = 'bytes'
BLOB = 'bytes'
BOOLEAN = 'bool' # BOOL
Boolean = 'bool' # BOOL
CHAR = 'str'
CLOB = 'str'
DATE = 'date'
Date = 'date' # DATE
DATETIME = 'datetime'
DateTime = 'datetime' # DATETIME
DECIMAL = 'Decimal'
DOUBLE = 'float'
Double = 'float' # DOUBLE
DOUBLE_PRECISION = 'float'
Enum = 'Enum' # Enum()
FLOAT = 'float'
Float = 'float' # FLOAT
INT = 'int' # INTEGER
INTEGER = 'int'
Integer = 'int' # INTEGER
Interval = 'timedelta' # DATETIME
JSON = 'dict'
LargeBinary = 'bytes' # BLOB
NCHAR = 'str'
NUMERIC = 'Decimal'
Numeric = 'Decimal' # NUMERIC
NVARCHAR = 'str' # String
PickleType = 'bytes' # BLOB
REAL = 'float'
SMALLINT = 'int'
SmallInteger = 'int' # SMALLINT
String = 'str' # String
TEXT = 'str'
Text = 'str' # TEXT
TIME = 'time'
Time = 'time' # TIME
TIMESTAMP = 'datetime'
Unicode = 'str' # String
UnicodeText = 'str' # TEXT
UUID = 'str | UUID'
Uuid = 'str' # CHAR(32)
VARBINARY = 'bytes'
VARCHAR = 'str' # String
# sa.dialects.mysql 导入
BIT = 'bool'
ENUM = 'Enum'
LONGBLOB = 'bytes'
LONGTEXT = 'str'
MEDIUMBLOB = 'bytes'
MEDIUMINT = 'int'
MEDIUMTEXT = 'str'
SET = 'list[str]'
TINYBLOB = 'bytes'
TINYINT = 'int'
TINYTEXT = 'str'
YEAR = 'int'
class GenModelPostgreSQLColumnType(StrEnum):
"""代码生成模型列类型PostgreSQL仅作为数据保留并未实施"""
# Python 类型映射
BIGINT = 'int'
BigInteger = 'int' # BIGINT
BINARY = 'bytes'
BLOB = 'bytes'
BOOLEAN = 'bool'
Boolean = 'bool' # BOOLEAN
CHAR = 'str'
CLOB = 'str'
DATE = 'date'
Date = 'date' # DATE
DATETIME = 'datetime'
DateTime = 'datetime' # TIMESTAMP WITHOUT TIME ZONE
DECIMAL = 'Decimal'
DOUBLE = 'float'
Double = 'float' # DOUBLE PRECISION
DOUBLE_PRECISION = 'float' # DOUBLE PRECISION
Enum = 'Enum' # Enum(name='enum')
FLOAT = 'float'
Float = 'float' # FLOAT
INT = 'int' # INTEGER
INTEGER = 'int'
Integer = 'int' # INTEGER
Interval = 'timedelta' # INTERVAL
JSON = 'dict'
LargeBinary = 'bytes' # BYTEA
NCHAR = 'str'
NUMERIC = 'Decimal'
Numeric = 'Decimal' # NUMERIC
NVARCHAR = 'str' # String
PickleType = 'bytes' # BYTEA
REAL = 'float'
SMALLINT = 'int'
SmallInteger = 'int' # SMALLINT
String = 'str' # String
TEXT = 'str'
Text = 'str' # TEXT
TIME = 'time' # TIME WITHOUT TIME ZONE
Time = 'time' # TIME WITHOUT TIME ZONE
TIMESTAMP = 'datetime' # TIMESTAMP WITHOUT TIME ZONE
Unicode = 'str' # String
UnicodeText = 'str' # TEXT
UUID = 'str | UUID'
Uuid = 'str'
VARBINARY = 'bytes'
VARCHAR = 'str' # String
# sa.dialects.postgresql 导入
ARRAY = 'list'
BIT = 'bool'
BYTEA = 'bytes'
CIDR = 'str'
CITEXT = 'str'
DATEMULTIRANGE = 'list[date]'
DATERANGE = 'tuple[date, date]'
DOMAIN = 'str'
ENUM = 'Enum'
HSTORE = 'dict'
INET = 'str'
INT4MULTIRANGE = 'list[int]'
INT4RANGE = 'tuple[int, int]'
INT8MULTIRANGE = 'list[int]'
INT8RANGE = 'tuple[int, int]'
INTERVAL = 'timedelta'
JSONB = 'dict'
JSONPATH = 'str'
MACADDR = 'str'
MACADDR8 = 'str'
MONEY = 'Decimal'
NUMMULTIRANGE = 'list[Decimal]'
NUMRANGE = 'tuple[Decimal, Decimal]'
OID = 'int'
REGCLASS = 'str'
REGCONFIG = 'str'
TSMULTIRANGE = 'list[datetime]'
TSQUERY = 'str'
TSRANGE = 'tuple[datetime, datetime]'
TSTZMULTIRANGE = 'list[datetime]'
TSTZRANGE = 'tuple[datetime, datetime]'
TSVECTOR = 'str'

View File

@ -5,47 +5,45 @@ INSERT INTO fba.sys_menu (id, title, name, level, sort, icon, path, menu_type, c
VALUES (1, '测试', 'test', 0, 0, '', null, 0, null, null, 0, 0, 1, null, null, '2023-07-27 19:14:10', null),
(2, '仪表盘', 'dashboard', 0, 0, 'IconDashboard', 'dashboard', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:15:45', null),
(3, '工作台', 'Workplace', 0, 0, null, 'workplace', 1, '/dashboard/workplace/index.vue', null, 1, 1, 1, null, 2, '2023-07-27 19:17:59', null),
(4, 'arco官网', 'arcoWebsite', 0, 888, 'IconLink', 'https://arco.design', 1, null, null, 1, 1, 1, null, null, '2023-07-27 19:19:23', null),
(5, '日志', 'log', 0, 66, 'IconBug', 'log', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:19:59', null),
(6, '登录日志', 'Login', 0, 0, null, 'login', 1, '/log/login/index.vue', null, 1, 1, 1, null, 5, '2023-07-27 19:20:56', null),
(7, '操作日志', 'Opera', 0, 0, null, 'opera', 1, '/log/opera/index.vue', null, 1, 1, 1, null, 5, '2023-07-27 19:21:28', null),
(8, '常见问题', 'faq', 0, 999, 'IconQuestion', 'https://arco.design/vue/docs/pro/faq', 1, null, null, 1, 1, 1, null, null, '2023-07-27 19:22:24', null),
(9, '系统管理', 'admin', 0, 6, 'IconSettings', 'admin', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:23:00', null),
(10, '部门管理', 'SysDept', 0, 0, null, 'sys-dept', 1, '/admin/dept/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:23:42', null),
(11, '新增', '', 0, 0, null, null, 2, null, 'sys:dept:add', 1, 1, 1, null, 10, '2024-01-07 11:37:00', null),
(12, '编辑', '', 0, 0, null, null, 2, null, 'sys:dept:edit', 1, 1, 1, null, 10, '2024-01-07 11:37:29', null),
(13, '删除', '', 0, 0, null, null, 2, null, 'sys:dept:del', 1, 1, 1, null, 10, '2024-01-07 11:37:44', null),
(14, 'API管理', 'SysApi', 0, 1, null, 'sys-api', 1, '/admin/api/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:24:12', null),
(15, '新增', '', 0, 0, null, null, 2, null, 'sys:api:add', 1, 1, 1, null, 14, '2024-01-07 11:57:09', null),
(16, '编辑', '', 0, 0, null, null, 2, null, 'sys:api:edit', 1, 1, 1, null, 14, '2024-01-07 11:57:44', null),
(17, '删除', '', 0, 0, null, null, 2, null, 'sys:api:del', 1, 1, 1, null, 14, '2024-01-07 11:57:56', null),
(18, '用户管理', 'SysUser', 0, 0, null, 'sys-user', 1, '/admin/user/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:25:13', null),
(19, '编辑用户角色', '', 0, 0, null, null, 2, null, 'sys:user:role:edit', 1, 1, 1, null, 18, '2024-01-07 12:04:20', null),
(20, '注销', '', 0, 0, null, null, 2, null, 'sys:user:del', 1, 1, 1, '用户注销 != 用户登出,注销之后用户将从数据库删除', 18, '2024-01-07 02:28:09', null),
(21, '角色管理', 'SysRole', 0, 2, null, 'sys-role', 1, '/admin/role/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:25:45', null),
(22, '新增', '', 0, 0, null, null, 2, null, 'sys:role:add', 1, 1, 1, null, 21, '2024-01-07 11:58:37', null),
(23, '编辑', '', 0, 0, null, null, 2, null, 'sys:role:edit', 1, 1, 1, null, 21, '2024-01-07 11:58:52', null),
(24, '删除', '', 0, 0, null, null, 2, null, 'sys:role:del', 1, 1, 1, null, 21, '2024-01-07 11:59:07', null),
(25, '编辑角色菜单', '', 0, 0, null, null, 2, null, 'sys:role:menu:edit', 1, 1, 1, null, 21, '2024-01-07 01:59:39', null),
(26, '菜单管理', 'SysMenu', 0, 2, null, 'sys-menu', 1, '/admin/menu/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:45:29', null),
(27, '新增', '', 0, 0, null, null, 2, null, 'sys:menu:add', 1, 1, 1, null, 26, '2024-01-07 12:01:24', null),
(28, '编辑', '', 0, 0, null, null, 2, null, 'sys:menu:edit', 1, 1, 1, null, 26, '2024-01-07 12:01:34', null),
(29, '删除', '', 0, 0, null, null, 2, null, 'sys:menu:del', 1, 1, 1, null, 26, '2024-01-07 12:01:48', null),
(30, '系统监控', 'monitor', 0, 88, 'IconComputer', 'monitor', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:27:08', null),
(31, 'Redis监控', 'Redis', 0, 0, null, 'redis', 1, '/monitor/redis/index.vue', 'sys:monitor:redis', 1, 1, 1, null, 30, '2023-07-27 19:28:03', null),
(32, '服务器监控', 'Server', 0, 0, null, 'server', 1, '/monitor/server/index.vue', 'sys:monitor:server', 1, 1, 1, null, 30, '2023-07-27 19:28:29', null),
(33, '系统自动化', 'automation', 0, 777, 'IconCodeSquare', 'automation', 0, null, null, 1, 1, 1, null, null, '2024-07-27 02:06:20', '2024-07-27 02:18:52'),
(34, '代码生成', 'CodeGenerator', 0, 0, null, 'code-generator', 1, '/automation/generator/index.vue', null, 1, 1, 1, null, 33, '2024-07-27 12:24:54', null),
(35, '导入', '', 0, 0, null, null, 2, null, 'gen:code:import', 1, 1, 1, null, 34, '2024-08-04 12:49:58', null),
(36, '新增业务', '', 0, 0, null, null, 2, null, 'gen:code:business:add', 1, 1, 1, null, 34, '2024-08-04 12:51:29', null),
(37, '编辑业务', '', 0, 0, null, null, 2, null, 'gen:code:business:edit', 1, 1, 1, null, 34, '2024-08-04 12:51:45', null),
(48, '删除业务', '', 0, 0, null, null, 2, null, 'gen:code:business:del', 1, 1, 1, null, 34, '2024-08-04 12:52:05', null),
(49, '新增模型', '', 0, 0, null, null, 2, null, 'gen:code:model:add', 1, 1, 1, null, 34, '2024-08-04 12:52:28', null),
(50, '编辑模型', '', 0, 0, null, null, 2, null, 'gen:code:model:edit', 1, 1, 1, null, 34, '2024-08-04 12:52:45', null),
(51, '删除模型', '', 0, 0, null, null, 2, null, 'gen:code:model:del', 1, 1, 1, null, 34, '2024-08-04 12:52:59', null),
(52, '生成', '', 0, 0, null, null, 2, null, 'gen:code:generate', 1, 1, 1, null, 34, '2024-08-04 12:55:03', null),
(53, 'GitHub', 'github', 0, 8888, 'IconGithub', 'https://github.com/wu-clan', 0, null, null, 1, 1, 1, null, null, '2024-07-27 12:32:46', null),
(54, '赞助', 'sponsor', 0, 9999, 'IconFire', 'https://wu-clan.github.io/sponsor/', 0, null, null, 1, 1, 1, null, null, '2024-07-27 12:39:57', null);
(4, '日志', 'log', 0, 66, 'IconBug', 'log', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:19:59', null),
(5, '登录日志', 'Login', 0, 0, null, 'login', 1, '/log/login/index.vue', null, 1, 1, 1, null, 4, '2023-07-27 19:20:56', null),
(6, '操作日志', 'Opera', 0, 0, null, 'opera', 1, '/log/opera/index.vue', null, 1, 1, 1, null, 4, '2023-07-27 19:21:28', null),
(7, '系统管理', 'admin', 0, 6, 'IconSettings', 'admin', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:23:00', null),
(8, '部门管理', 'SysDept', 0, 0, null, 'sys-dept', 1, '/admin/dept/index.vue', null, 1, 1, 1, null, 7, '2023-07-27 19:23:42', null),
(9, '新增', '', 0, 0, null, null, 2, null, 'sys:dept:add', 1, 1, 1, null, 8, '2024-01-07 11:37:00', null),
(10, '编辑', '', 0, 0, null, null, 2, null, 'sys:dept:edit', 1, 1, 1, null, 8, '2024-01-07 11:37:29', null),
(11, '删除', '', 0, 0, null, null, 2, null, 'sys:dept:del', 1, 1, 1, null, 8, '2024-01-07 11:37:44', null),
(12, 'API管理', 'SysApi', 0, 1, null, 'sys-api', 1, '/admin/api/index.vue', null, 1, 1, 1, null, 7, '2023-07-27 19:24:12', null),
(13, '新增', '', 0, 0, null, null, 2, null, 'sys:api:add', 1, 1, 1, null, 12, '2024-01-07 11:57:09', null),
(14, '编辑', '', 0, 0, null, null, 2, null, 'sys:api:edit', 1, 1, 1, null, 12, '2024-01-07 11:57:44', null),
(15, '删除', '', 0, 0, null, null, 2, null, 'sys:api:del', 1, 1, 1, null, 12, '2024-01-07 11:57:56', null),
(16, '用户管理', 'SysUser', 0, 0, null, 'sys-user', 1, '/admin/user/index.vue', null, 1, 1, 1, null, 7, '2023-07-27 19:25:13', null),
(17, '编辑用户角色', '', 0, 0, null, null, 2, null, 'sys:user:role:edit', 1, 1, 1, null, 16, '2024-01-07 12:04:20', null),
(18, '注销', '', 0, 0, null, null, 2, null, 'sys:user:del', 1, 1, 1, '用户注销 != 用户登出,注销之后用户将从数据库删除', 16, '2024-01-07 02:28:09', null),
(19, '角色管理', 'SysRole', 0, 2, null, 'sys-role', 1, '/admin/role/index.vue', null, 1, 1, 1, null, 7, '2023-07-27 19:25:45', null),
(20, '新增', '', 0, 0, null, null, 2, null, 'sys:role:add', 1, 1, 1, null, 19, '2024-01-07 11:58:37', null),
(21, '编辑', '', 0, 0, null, null, 2, null, 'sys:role:edit', 1, 1, 1, null, 19, '2024-01-07 11:58:52', null),
(22, '删除', '', 0, 0, null, null, 2, null, 'sys:role:del', 1, 1, 1, null, 19, '2024-01-07 11:59:07', null),
(23, '编辑角色菜单', '', 0, 0, null, null, 2, null, 'sys:role:menu:edit', 1, 1, 1, null, 19, '2024-01-07 01:59:39', null),
(24, '菜单管理', 'SysMenu', 0, 2, null, 'sys-menu', 1, '/admin/menu/index.vue', null, 1, 1, 1, null, 7, '2023-07-27 19:45:29', null),
(25, '新增', '', 0, 0, null, null, 2, null, 'sys:menu:add', 1, 1, 1, null, 24, '2024-01-07 12:01:24', null),
(26, '编辑', '', 0, 0, null, null, 2, null, 'sys:menu:edit', 1, 1, 1, null, 24, '2024-01-07 12:01:34', null),
(27, '删除', '', 0, 0, null, null, 2, null, 'sys:menu:del', 1, 1, 1, null, 24, '2024-01-07 12:01:48', null),
(28, '系统监控', 'monitor', 0, 88, 'IconComputer', 'monitor', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:27:08', null),
(29, 'Redis监控', 'Redis', 0, 0, null, 'redis', 1, '/monitor/redis/index.vue', 'sys:monitor:redis', 1, 1, 1, null, 28, '2023-07-27 19:28:03', null),
(30, '服务器监控', 'Server', 0, 0, null, 'server', 1, '/monitor/server/index.vue', 'sys:monitor:server', 1, 1, 1, null, 28, '2023-07-27 19:28:29', null),
(31, '系统自动化', 'automation', 0, 777, 'IconCodeSquare', 'automation', 0, null, null, 1, 1, 1, null, null, '2024-07-27 02:06:20', '2024-07-27 02:18:52'),
(32, '代码生成', 'CodeGenerator', 0, 0, null, 'code-generator', 1, '/automation/generator/index.vue', null, 1, 1, 1, null, 31, '2024-07-27 12:24:54', null),
(33, '导入', '', 0, 0, null, null, 2, null, 'gen:code:import', 1, 1, 1, null, 31, '2024-08-04 12:49:58', null),
(34, '新增业务', '', 0, 0, null, null, 2, null, 'gen:code:business:add', 1, 1, 1, null, 31, '2024-08-04 12:51:29', null),
(35, '编辑业务', '', 0, 0, null, null, 2, null, 'gen:code:business:edit', 1, 1, 1, null, 31, '2024-08-04 12:51:45', null),
(36, '删除业务', '', 0, 0, null, null, 2, null, 'gen:code:business:del', 1, 1, 1, null, 31, '2024-08-04 12:52:05', null),
(37, '新增模型', '', 0, 0, null, null, 2, null, 'gen:code:model:add', 1, 1, 1, null, 31, '2024-08-04 12:52:28', null),
(38, '编辑模型', '', 0, 0, null, null, 2, null, 'gen:code:model:edit', 1, 1, 1, null, 31, '2024-08-04 12:52:45', null),
(39, '删除模型', '', 0, 0, null, null, 2, null, 'gen:code:model:del', 1, 1, 1, null, 31, '2024-08-04 12:52:59', null),
(40, '生成', '', 0, 0, null, null, 2, null, 'gen:code:generate', 1, 1, 1, null, 31, '2024-08-04 12:55:03', null),
(41, 'GitHub', 'github', 0, 8888, 'IconGithub', 'https://github.com/wu-clan', 0, null, null, 1, 1, 1, null, null, '2024-07-27 12:32:46', null),
(42, '赞助', 'sponsor', 0, 9999, 'IconFire', 'https://wu-clan.github.io/sponsor/', 0, null, null, 1, 1, 1, null, null, '2024-07-27 12:39:57', null);
INSERT INTO fba.sys_role (id, name, data_scope, status, remark, created_time, updated_time)
VALUES (1, 'test', 2, 1, null, '2023-06-26 17:13:45', null);

View File

@ -60,7 +60,7 @@ async def create_{{ table_name_en }}(obj: Create{{ schema_name }}Param) -> Respo
async def update_{{ table_name_en }}(pk: Annotated[int, Path(...)], obj: Update{{ schema_name }}Param) -> ResponseModel:
count = await {{ table_name_en }}_service.update(pk=pk, obj=obj)
if count > 0:
return await response_base.success()
return response_base.success()
return response_base.fail()
@ -75,5 +75,5 @@ async def update_{{ table_name_en }}(pk: Annotated[int, Path(...)], obj: Update{
async def delete_{{ table_name_en }}(pk: Annotated[list[int], Query(...)]) -> ResponseModel:
count = await {{ table_name_en }}_service.delete(pk=pk)
if count > 0:
return await response_base.success()
return response_base.success()
return response_base.fail()

View File

@ -1,5 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from uuid import UUID
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
@ -19,10 +21,13 @@ class {{ table_name_class }}({% if have_datetime_column %}Base{% else %}MappedBa
{%- if model.is_nullable %} Mapped[{{ model.pd_type }} | None]
{%- else %} Mapped[{{ model.pd_type }}]
{%- endif %} = mapped_column(
{%- if model.type == 'VARCHAR' -%}
{%- if model.type in ['NVARCHAR', 'String', 'Unicode', 'VARCHAR'] -%}
sa.String({{ model.length }})
{%- else -%}
{%- elif model.type in ['BIT', 'ENUM', 'LONGBLOB', 'LONGTEXT', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'SET',
'TINYBLOB', 'TINYINT', 'TINYTEXT', 'YEAR'] -%}
mysql.{{ model.type }}()
{%- else -%}
sa.{{ model.type }}()
{%- endif -%}, default=
{%- if model.is_nullable and model.default == None -%}
None
@ -44,7 +49,7 @@ class {{ table_name_class }}({% if have_datetime_column %}Base{% else %}MappedBa
{}
{%- elif model.pd_type == 'date' or model.pd_type == 'datetime' -%}
timezone.now()
{%- elif model.pd_type == 'List[str]' -%}
{%- elif model.pd_type == 'list[str]' -%}
()
{%- else -%}
''

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from backend.common.enums import GenModelColumnType
from backend.common.enums import GenModelMySQLColumnType
def sql_type_to_sqlalchemy(typing: str) -> str:
@ -10,43 +10,9 @@ def sql_type_to_sqlalchemy(typing: str) -> str:
:param typing:
:return:
"""
type_mapping = {
GenModelColumnType.BIGINT: 'BIGINT',
GenModelColumnType.BINARY: 'BINARY',
GenModelColumnType.BIT: 'BIT',
GenModelColumnType.BLOB: 'BLOG',
GenModelColumnType.BOOL: 'BOOLEAN',
GenModelColumnType.BOOLEAN: 'BOOLEAN',
GenModelColumnType.CHAR: 'CHAR',
GenModelColumnType.DATE: 'DATE',
GenModelColumnType.DATETIME: 'DATETIME',
GenModelColumnType.DECIMAL: 'DECIMAL',
GenModelColumnType.DOUBLE: 'DOUBLE',
GenModelColumnType.ENUM: 'ENUM',
GenModelColumnType.FLOAT: 'FLOAT',
GenModelColumnType.INT: 'INT',
GenModelColumnType.INTEGER: 'INTEGER',
GenModelColumnType.JSON: 'JSON',
GenModelColumnType.LONGBLOB: 'LONGBLOB',
GenModelColumnType.LONGTEXT: 'LONGTEXT',
GenModelColumnType.MEDIUMBLOB: 'MEDIUMBLOB',
GenModelColumnType.MEDIUMINT: 'MEDIUMINT',
GenModelColumnType.MEDIUMTEXT: 'MEDIUMTEXT',
GenModelColumnType.NUMERIC: 'NUMERIC',
GenModelColumnType.SET: 'SET',
GenModelColumnType.SMALLINT: 'SMALLINT',
GenModelColumnType.REAL: 'REAL',
GenModelColumnType.TEXT: 'TEXT',
GenModelColumnType.TIME: 'TIME',
GenModelColumnType.TIMESTAMP: 'TIMESTAMP',
GenModelColumnType.TINYBLOB: 'TINYBLOB',
GenModelColumnType.TINYINT: 'TINYINT',
GenModelColumnType.TINYTEXT: 'TINYTEXT',
GenModelColumnType.VARBINARY: 'VARBINARY',
GenModelColumnType.VARCHAR: 'VARCHAR',
GenModelColumnType.YEAR: 'YEAR',
}
return type_mapping.get(typing, 'VARCHAR')
if typing in GenModelMySQLColumnType.get_member_keys():
return typing
return 'String'
def sql_type_to_pydantic(typing: str) -> str:
@ -56,40 +22,7 @@ def sql_type_to_pydantic(typing: str) -> str:
:param typing:
:return:
"""
type_mapping = {
GenModelColumnType.BIGINT: 'int',
GenModelColumnType.BINARY: 'bytes',
GenModelColumnType.BIT: 'bool',
GenModelColumnType.BLOB: 'bytes',
GenModelColumnType.BOOL: 'bool',
GenModelColumnType.BOOLEAN: 'bool',
GenModelColumnType.CHAR: 'str',
GenModelColumnType.DATE: 'date',
GenModelColumnType.DATETIME: 'datetime',
GenModelColumnType.DECIMAL: 'Decimal',
GenModelColumnType.DOUBLE: 'float',
GenModelColumnType.ENUM: 'Enum',
GenModelColumnType.FLOAT: 'float',
GenModelColumnType.INT: 'int',
GenModelColumnType.INTEGER: 'int',
GenModelColumnType.JSON: 'dict',
GenModelColumnType.LONGBLOB: 'bytes',
GenModelColumnType.LONGTEXT: 'str',
GenModelColumnType.MEDIUMBLOB: 'bytes',
GenModelColumnType.MEDIUMINT: 'int',
GenModelColumnType.MEDIUMTEXT: 'str',
GenModelColumnType.NUMERIC: 'NUMERIC',
GenModelColumnType.SET: 'List[str]',
GenModelColumnType.SMALLINT: 'int',
GenModelColumnType.REAL: 'float',
GenModelColumnType.TEXT: 'str',
GenModelColumnType.TIME: 'time',
GenModelColumnType.TIMESTAMP: 'datetime',
GenModelColumnType.TINYBLOB: 'bytes',
GenModelColumnType.TINYINT: 'int',
GenModelColumnType.TINYTEXT: 'str',
GenModelColumnType.VARBINARY: 'bytes',
GenModelColumnType.VARCHAR: 'str',
GenModelColumnType.YEAR: 'int',
}
return type_mapping.get(typing, 'str')
try:
return GenModelMySQLColumnType[typing].value
except KeyError:
return 'str'