mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-21 20:55:14 +00:00
@@ -0,0 +1,3 @@
|
|||||||
|
*.js linguist-language=Python
|
||||||
|
*.css linguist-language=Python
|
||||||
|
*.html linguist-language=Python
|
||||||
@@ -12,7 +12,6 @@ backend/venv
|
|||||||
backend/logs
|
backend/logs
|
||||||
backend/*.db
|
backend/*.db
|
||||||
backend/site
|
backend/site
|
||||||
backend/app/alembic/versions/*
|
|
||||||
|
|
||||||
frontend/__pycache__
|
frontend/__pycache__
|
||||||
frontend/.vscode
|
frontend/.vscode
|
||||||
|
|||||||
@@ -0,0 +1,419 @@
|
|||||||
|
"""'Change config_value from String to JSON'
|
||||||
|
|
||||||
|
Revision ID: d5460b04e5ce
|
||||||
|
Revises:
|
||||||
|
Create Date: 2025-10-08 15:38:49.199390
|
||||||
|
|
||||||
|
"""
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import sqlite
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = 'd5460b04e5ce'
|
||||||
|
down_revision: Union[str, None] = None
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_index('ix_system_dict_data_creator_id', table_name='system_dict_data')
|
||||||
|
op.drop_table('system_dict_data')
|
||||||
|
op.drop_index('ix_app_job_creator_id', table_name='app_job')
|
||||||
|
op.drop_table('app_job')
|
||||||
|
op.drop_index('ix_gen_table_column_creator_id', table_name='gen_table_column')
|
||||||
|
op.drop_table('gen_table_column')
|
||||||
|
op.drop_index('ix_system_position_creator_id', table_name='system_position')
|
||||||
|
op.drop_table('system_position')
|
||||||
|
op.drop_table('system_role_depts')
|
||||||
|
op.drop_table('system_role_menus')
|
||||||
|
op.drop_table('system_user_positions')
|
||||||
|
op.drop_index('ix_app_myapp_creator_id', table_name='app_myapp')
|
||||||
|
op.drop_table('app_myapp')
|
||||||
|
op.drop_index('ix_system_dict_type_creator_id', table_name='system_dict_type')
|
||||||
|
op.drop_table('system_dict_type')
|
||||||
|
op.drop_table('app_job_log')
|
||||||
|
op.drop_index('ix_system_role_creator_id', table_name='system_role')
|
||||||
|
op.drop_table('system_role')
|
||||||
|
op.drop_index('ix_system_users_creator_id', table_name='system_users')
|
||||||
|
op.drop_index('ix_system_users_dept_id', table_name='system_users')
|
||||||
|
op.drop_table('system_users')
|
||||||
|
op.drop_index('ix_system_log_creator_id', table_name='system_log')
|
||||||
|
op.drop_table('system_log')
|
||||||
|
op.drop_index('ix_system_menu_parent_id', table_name='system_menu')
|
||||||
|
op.drop_table('system_menu')
|
||||||
|
op.drop_index('ix_system_notice_creator_id', table_name='system_notice')
|
||||||
|
op.drop_table('system_notice')
|
||||||
|
op.drop_index('ix_system_dept_parent_id', table_name='system_dept')
|
||||||
|
op.drop_table('system_dept')
|
||||||
|
op.drop_index('ix_app_ai_mcp_creator_id', table_name='app_ai_mcp')
|
||||||
|
op.drop_table('app_ai_mcp')
|
||||||
|
op.drop_index('ix_system_param_creator_id', table_name='system_param')
|
||||||
|
op.drop_table('system_param')
|
||||||
|
op.drop_index('ix_gen_demo_creator_id', table_name='gen_demo')
|
||||||
|
op.drop_table('gen_demo')
|
||||||
|
op.drop_table('system_user_roles')
|
||||||
|
op.drop_index('ix_gen_table_creator_id', table_name='gen_table')
|
||||||
|
op.drop_table('gen_table')
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table('gen_table',
|
||||||
|
sa.Column('table_name', sa.VARCHAR(length=200), nullable=True),
|
||||||
|
sa.Column('table_comment', sa.VARCHAR(length=500), nullable=True),
|
||||||
|
sa.Column('sub_table_name', sa.VARCHAR(length=64), nullable=True),
|
||||||
|
sa.Column('sub_table_fk_name', sa.VARCHAR(length=64), nullable=True),
|
||||||
|
sa.Column('class_name', sa.VARCHAR(length=100), nullable=True),
|
||||||
|
sa.Column('tpl_category', sa.VARCHAR(length=200), nullable=True),
|
||||||
|
sa.Column('tpl_web_type', sa.VARCHAR(length=30), nullable=True),
|
||||||
|
sa.Column('package_name', sa.VARCHAR(length=100), nullable=True),
|
||||||
|
sa.Column('module_name', sa.VARCHAR(length=30), nullable=True),
|
||||||
|
sa.Column('business_name', sa.VARCHAR(length=30), nullable=True),
|
||||||
|
sa.Column('function_name', sa.VARCHAR(length=100), nullable=True),
|
||||||
|
sa.Column('function_author', sa.VARCHAR(length=100), nullable=True),
|
||||||
|
sa.Column('gen_type', sa.VARCHAR(length=1), nullable=True),
|
||||||
|
sa.Column('gen_path', sa.VARCHAR(length=200), nullable=True),
|
||||||
|
sa.Column('options', sa.VARCHAR(length=1000), nullable=True),
|
||||||
|
sa.Column('creator_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['creator_id'], ['system_users.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index('ix_gen_table_creator_id', 'gen_table', ['creator_id'], unique=False)
|
||||||
|
op.create_table('system_user_roles',
|
||||||
|
sa.Column('user_id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('role_id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['role_id'], ['system_role.id'], onupdate='CASCADE', ondelete='CASCADE'),
|
||||||
|
sa.ForeignKeyConstraint(['user_id'], ['system_users.id'], onupdate='CASCADE', ondelete='CASCADE'),
|
||||||
|
sa.PrimaryKeyConstraint('user_id', 'role_id')
|
||||||
|
)
|
||||||
|
op.create_table('gen_demo',
|
||||||
|
sa.Column('name', sa.VARCHAR(length=64), nullable=True),
|
||||||
|
sa.Column('status', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('creator_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['creator_id'], ['system_users.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index('ix_gen_demo_creator_id', 'gen_demo', ['creator_id'], unique=False)
|
||||||
|
op.create_table('system_param',
|
||||||
|
sa.Column('config_name', sa.VARCHAR(length=500), nullable=False),
|
||||||
|
sa.Column('config_key', sa.VARCHAR(length=500), nullable=False),
|
||||||
|
sa.Column('config_value', sa.VARCHAR(length=500), nullable=True),
|
||||||
|
sa.Column('config_type', sa.BOOLEAN(), nullable=True),
|
||||||
|
sa.Column('status', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('creator_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['creator_id'], ['system_users.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('config_key'),
|
||||||
|
sa.UniqueConstraint('config_name')
|
||||||
|
)
|
||||||
|
op.create_index('ix_system_param_creator_id', 'system_param', ['creator_id'], unique=False)
|
||||||
|
op.create_table('app_ai_mcp',
|
||||||
|
sa.Column('name', sa.VARCHAR(length=50), nullable=False),
|
||||||
|
sa.Column('type', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('url', sa.VARCHAR(length=255), nullable=True),
|
||||||
|
sa.Column('command', sa.VARCHAR(length=255), nullable=True),
|
||||||
|
sa.Column('args', sa.VARCHAR(length=255), nullable=True),
|
||||||
|
sa.Column('env', sqlite.JSON(), nullable=True),
|
||||||
|
sa.Column('creator_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['creator_id'], ['system_users.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('name')
|
||||||
|
)
|
||||||
|
op.create_index('ix_app_ai_mcp_creator_id', 'app_ai_mcp', ['creator_id'], unique=False)
|
||||||
|
op.create_table('system_dept',
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('name', sa.VARCHAR(length=40), nullable=False),
|
||||||
|
sa.Column('order', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('code', sa.VARCHAR(length=20), nullable=True),
|
||||||
|
sa.Column('status', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('parent_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['parent_id'], ['system_dept.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('code'),
|
||||||
|
sa.UniqueConstraint('name')
|
||||||
|
)
|
||||||
|
op.create_index('ix_system_dept_parent_id', 'system_dept', ['parent_id'], unique=False)
|
||||||
|
op.create_table('system_notice',
|
||||||
|
sa.Column('notice_title', sa.VARCHAR(length=50), nullable=False),
|
||||||
|
sa.Column('notice_type', sa.VARCHAR(length=50), nullable=False),
|
||||||
|
sa.Column('notice_content', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('status', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('creator_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['creator_id'], ['system_users.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index('ix_system_notice_creator_id', 'system_notice', ['creator_id'], unique=False)
|
||||||
|
op.create_table('system_menu',
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('name', sa.VARCHAR(length=50), nullable=False),
|
||||||
|
sa.Column('type', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('order', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('status', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('permission', sa.VARCHAR(length=100), nullable=True),
|
||||||
|
sa.Column('icon', sa.VARCHAR(length=50), nullable=True),
|
||||||
|
sa.Column('route_name', sa.VARCHAR(length=100), nullable=True),
|
||||||
|
sa.Column('route_path', sa.VARCHAR(length=200), nullable=True),
|
||||||
|
sa.Column('component_path', sa.VARCHAR(length=200), nullable=True),
|
||||||
|
sa.Column('redirect', sa.VARCHAR(length=200), nullable=True),
|
||||||
|
sa.Column('hidden', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('keep_alive', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('always_show', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('title', sa.VARCHAR(length=50), nullable=True),
|
||||||
|
sa.Column('params', sqlite.JSON(), nullable=True),
|
||||||
|
sa.Column('affix', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('parent_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['parent_id'], ['system_menu.id'], ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('name')
|
||||||
|
)
|
||||||
|
op.create_index('ix_system_menu_parent_id', 'system_menu', ['parent_id'], unique=False)
|
||||||
|
op.create_table('system_log',
|
||||||
|
sa.Column('type', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('request_path', sa.VARCHAR(length=255), nullable=False),
|
||||||
|
sa.Column('request_method', sa.VARCHAR(length=10), nullable=False),
|
||||||
|
sa.Column('request_payload', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('request_ip', sa.VARCHAR(length=50), nullable=True),
|
||||||
|
sa.Column('login_location', sa.VARCHAR(length=255), nullable=True),
|
||||||
|
sa.Column('request_os', sa.VARCHAR(length=64), nullable=True),
|
||||||
|
sa.Column('request_browser', sa.VARCHAR(length=64), nullable=True),
|
||||||
|
sa.Column('response_code', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('response_json', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('process_time', sa.VARCHAR(length=20), nullable=True),
|
||||||
|
sa.Column('creator_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['creator_id'], ['system_users.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index('ix_system_log_creator_id', 'system_log', ['creator_id'], unique=False)
|
||||||
|
op.create_table('system_users',
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('username', sa.VARCHAR(length=32), nullable=False),
|
||||||
|
sa.Column('password', sa.VARCHAR(length=255), nullable=False),
|
||||||
|
sa.Column('name', sa.VARCHAR(length=32), nullable=False),
|
||||||
|
sa.Column('status', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('mobile', sa.VARCHAR(length=20), nullable=True),
|
||||||
|
sa.Column('email', sa.VARCHAR(length=64), nullable=True),
|
||||||
|
sa.Column('gender', sa.VARCHAR(length=1), nullable=True),
|
||||||
|
sa.Column('avatar', sa.VARCHAR(length=500), nullable=True),
|
||||||
|
sa.Column('is_superuser', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('last_login', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('dept_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('creator_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['creator_id'], ['system_users.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.ForeignKeyConstraint(['dept_id'], ['system_dept.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('email'),
|
||||||
|
sa.UniqueConstraint('mobile'),
|
||||||
|
sa.UniqueConstraint('username')
|
||||||
|
)
|
||||||
|
op.create_index('ix_system_users_dept_id', 'system_users', ['dept_id'], unique=False)
|
||||||
|
op.create_index('ix_system_users_creator_id', 'system_users', ['creator_id'], unique=False)
|
||||||
|
op.create_table('system_role',
|
||||||
|
sa.Column('name', sa.VARCHAR(length=40), nullable=False),
|
||||||
|
sa.Column('code', sa.VARCHAR(length=20), nullable=True),
|
||||||
|
sa.Column('order', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('status', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('data_scope', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('creator_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['creator_id'], ['system_users.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('code'),
|
||||||
|
sa.UniqueConstraint('name')
|
||||||
|
)
|
||||||
|
op.create_index('ix_system_role_creator_id', 'system_role', ['creator_id'], unique=False)
|
||||||
|
op.create_table('app_job_log',
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('job_name', sa.VARCHAR(length=64), nullable=False),
|
||||||
|
sa.Column('job_group', sa.VARCHAR(length=64), nullable=False),
|
||||||
|
sa.Column('job_executor', sa.VARCHAR(length=64), nullable=False),
|
||||||
|
sa.Column('invoke_target', sa.VARCHAR(length=500), nullable=False),
|
||||||
|
sa.Column('job_args', sa.VARCHAR(length=255), nullable=True),
|
||||||
|
sa.Column('job_kwargs', sa.VARCHAR(length=255), nullable=True),
|
||||||
|
sa.Column('job_trigger', sa.VARCHAR(length=255), nullable=True),
|
||||||
|
sa.Column('job_message', sa.VARCHAR(length=500), nullable=True),
|
||||||
|
sa.Column('exception_info', sa.VARCHAR(length=2000), nullable=True),
|
||||||
|
sa.Column('job_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('status', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('create_time', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['job_id'], ['app_job.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_table('system_dict_type',
|
||||||
|
sa.Column('dict_name', sa.VARCHAR(length=100), nullable=False),
|
||||||
|
sa.Column('dict_type', sa.VARCHAR(length=100), nullable=False),
|
||||||
|
sa.Column('status', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('creator_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['creator_id'], ['system_users.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('dict_name'),
|
||||||
|
sa.UniqueConstraint('dict_type')
|
||||||
|
)
|
||||||
|
op.create_index('ix_system_dict_type_creator_id', 'system_dict_type', ['creator_id'], unique=False)
|
||||||
|
op.create_table('app_myapp',
|
||||||
|
sa.Column('name', sa.VARCHAR(length=64), nullable=False),
|
||||||
|
sa.Column('status', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('access_url', sa.VARCHAR(length=500), nullable=False),
|
||||||
|
sa.Column('icon_url', sa.VARCHAR(length=300), nullable=True),
|
||||||
|
sa.Column('creator_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['creator_id'], ['system_users.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('name')
|
||||||
|
)
|
||||||
|
op.create_index('ix_app_myapp_creator_id', 'app_myapp', ['creator_id'], unique=False)
|
||||||
|
op.create_table('system_user_positions',
|
||||||
|
sa.Column('user_id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('position_id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['position_id'], ['system_position.id'], onupdate='CASCADE', ondelete='CASCADE'),
|
||||||
|
sa.ForeignKeyConstraint(['user_id'], ['system_users.id'], onupdate='CASCADE', ondelete='CASCADE'),
|
||||||
|
sa.PrimaryKeyConstraint('user_id', 'position_id')
|
||||||
|
)
|
||||||
|
op.create_table('system_role_menus',
|
||||||
|
sa.Column('role_id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('menu_id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['menu_id'], ['system_menu.id'], onupdate='CASCADE', ondelete='CASCADE'),
|
||||||
|
sa.ForeignKeyConstraint(['role_id'], ['system_role.id'], onupdate='CASCADE', ondelete='CASCADE'),
|
||||||
|
sa.PrimaryKeyConstraint('role_id', 'menu_id')
|
||||||
|
)
|
||||||
|
op.create_table('system_role_depts',
|
||||||
|
sa.Column('role_id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('dept_id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['dept_id'], ['system_dept.id'], onupdate='CASCADE', ondelete='CASCADE'),
|
||||||
|
sa.ForeignKeyConstraint(['role_id'], ['system_role.id'], onupdate='CASCADE', ondelete='CASCADE'),
|
||||||
|
sa.PrimaryKeyConstraint('role_id', 'dept_id')
|
||||||
|
)
|
||||||
|
op.create_table('system_position',
|
||||||
|
sa.Column('name', sa.VARCHAR(length=40), nullable=False),
|
||||||
|
sa.Column('order', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('status', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('creator_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['creator_id'], ['system_users.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('name')
|
||||||
|
)
|
||||||
|
op.create_index('ix_system_position_creator_id', 'system_position', ['creator_id'], unique=False)
|
||||||
|
op.create_table('gen_table_column',
|
||||||
|
sa.Column('column_name', sa.VARCHAR(length=200), nullable=True),
|
||||||
|
sa.Column('column_comment', sa.VARCHAR(length=500), nullable=True),
|
||||||
|
sa.Column('column_type', sa.VARCHAR(length=100), nullable=True),
|
||||||
|
sa.Column('python_type', sa.VARCHAR(length=500), nullable=True),
|
||||||
|
sa.Column('python_field', sa.VARCHAR(length=200), nullable=True),
|
||||||
|
sa.Column('is_pk', sa.VARCHAR(length=1), nullable=True),
|
||||||
|
sa.Column('is_increment', sa.VARCHAR(length=1), nullable=True),
|
||||||
|
sa.Column('is_required', sa.VARCHAR(length=1), nullable=True),
|
||||||
|
sa.Column('is_unique', sa.VARCHAR(length=1), nullable=True),
|
||||||
|
sa.Column('is_insert', sa.VARCHAR(length=1), nullable=True),
|
||||||
|
sa.Column('is_edit', sa.VARCHAR(length=1), nullable=True),
|
||||||
|
sa.Column('is_list', sa.VARCHAR(length=1), nullable=True),
|
||||||
|
sa.Column('is_query', sa.VARCHAR(length=1), nullable=True),
|
||||||
|
sa.Column('query_type', sa.VARCHAR(length=200), nullable=True),
|
||||||
|
sa.Column('html_type', sa.VARCHAR(length=200), nullable=True),
|
||||||
|
sa.Column('dict_type', sa.VARCHAR(length=200), nullable=True),
|
||||||
|
sa.Column('sort', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('table_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('creator_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['creator_id'], ['system_users.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.ForeignKeyConstraint(['table_id'], ['gen_table.id'], ondelete='CASCADE'),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index('ix_gen_table_column_creator_id', 'gen_table_column', ['creator_id'], unique=False)
|
||||||
|
op.create_table('app_job',
|
||||||
|
sa.Column('name', sa.VARCHAR(length=64), nullable=True),
|
||||||
|
sa.Column('jobstore', sa.VARCHAR(length=64), nullable=True),
|
||||||
|
sa.Column('executor', sa.VARCHAR(length=64), nullable=True),
|
||||||
|
sa.Column('trigger', sa.VARCHAR(length=64), nullable=False),
|
||||||
|
sa.Column('trigger_args', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('func', sa.TEXT(), nullable=False),
|
||||||
|
sa.Column('args', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('kwargs', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('coalesce', sa.BOOLEAN(), nullable=True),
|
||||||
|
sa.Column('max_instances', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('start_date', sa.VARCHAR(length=64), nullable=True),
|
||||||
|
sa.Column('end_date', sa.VARCHAR(length=64), nullable=True),
|
||||||
|
sa.Column('status', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('creator_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['creator_id'], ['system_users.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index('ix_app_job_creator_id', 'app_job', ['creator_id'], unique=False)
|
||||||
|
op.create_table('system_dict_data',
|
||||||
|
sa.Column('dict_sort', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('dict_label', sa.VARCHAR(length=100), nullable=False),
|
||||||
|
sa.Column('dict_value', sa.VARCHAR(length=100), nullable=False),
|
||||||
|
sa.Column('dict_type', sa.VARCHAR(length=100), nullable=False),
|
||||||
|
sa.Column('status', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('css_class', sa.VARCHAR(length=100), nullable=True),
|
||||||
|
sa.Column('list_class', sa.VARCHAR(length=100), nullable=True),
|
||||||
|
sa.Column('is_default', sa.BOOLEAN(), nullable=False),
|
||||||
|
sa.Column('dict_type_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('creator_id', sa.INTEGER(), nullable=True),
|
||||||
|
sa.Column('id', sa.INTEGER(), nullable=False),
|
||||||
|
sa.Column('description', sa.TEXT(), nullable=True),
|
||||||
|
sa.Column('created_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DATETIME(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['creator_id'], ['system_users.id'], onupdate='CASCADE', ondelete='SET NULL'),
|
||||||
|
sa.ForeignKeyConstraint(['dict_type_id'], ['system_dict_type.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index('ix_system_dict_data_creator_id', 'system_dict_data', ['creator_id'], unique=False)
|
||||||
|
# ### end Alembic commands ###
|
||||||
@@ -12,7 +12,7 @@ from app.common.request import PaginationService
|
|||||||
from app.api.v1.module_system.auth.schema import AuthSchema
|
from app.api.v1.module_system.auth.schema import AuthSchema
|
||||||
from app.common.constant import RET
|
from app.common.constant import RET
|
||||||
from .param import GenTableQueryParam
|
from .param import GenTableQueryParam
|
||||||
from .schema import GenTableDeleteSchema, GenTableSchema, GenTableOutSchema
|
from .schema import GenTableSchema, GenTableOutSchema
|
||||||
from .service import GenTableColumnService, GenTableService
|
from .service import GenTableColumnService, GenTableService
|
||||||
from app.utils.common_util import bytes2file_response
|
from app.utils.common_util import bytes2file_response
|
||||||
from app.core.logger import logger
|
from app.core.logger import logger
|
||||||
@@ -47,7 +47,7 @@ async def get_gen_db_table_list_controller(
|
|||||||
|
|
||||||
@GenRouter.post("/import", summary="导入表结构", description="导入表结构")
|
@GenRouter.post("/import", summary="导入表结构", description="导入表结构")
|
||||||
async def import_gen_table_controller(
|
async def import_gen_table_controller(
|
||||||
table_names: List[str] = Query(..., description="表名列表"),
|
table_names: List[str] = Body(..., description="表名列表"),
|
||||||
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:import"])),
|
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:import"])),
|
||||||
) -> JSONResponse:
|
) -> JSONResponse:
|
||||||
add_gen_table_list = await GenTableService.get_gen_db_table_list_by_name_service(auth, table_names)
|
add_gen_table_list = await GenTableService.get_gen_db_table_list_by_name_service(auth, table_names)
|
||||||
@@ -70,7 +70,7 @@ async def gen_table_detail_controller(
|
|||||||
|
|
||||||
@GenRouter.post("/create", summary="创建表结构", description="创建表结构")
|
@GenRouter.post("/create", summary="创建表结构", description="创建表结构")
|
||||||
async def create_table_controller(
|
async def create_table_controller(
|
||||||
sql: str = Query(..., description="SQL语句:CREATE TABLE user_demo (\n id INTEGER NOT NULL PRIMARY KEY,\n username VARCHAR(64) NOT NULL UNIQUE,\n);"),
|
sql: str = Body(..., description="SQL语句:CREATE TABLE user_demo (\n id INTEGER NOT NULL PRIMARY KEY,\n username VARCHAR(64) NOT NULL UNIQUE,\n);"),
|
||||||
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:create"])),
|
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:create"])),
|
||||||
) -> JSONResponse:
|
) -> JSONResponse:
|
||||||
result = await GenTableService.create_table_service(auth, sql)
|
result = await GenTableService.create_table_service(auth, sql)
|
||||||
@@ -92,17 +92,17 @@ async def update_gen_table_controller(
|
|||||||
|
|
||||||
@GenRouter.delete("/delete", summary="删除业务表信息", description="删除业务表信息")
|
@GenRouter.delete("/delete", summary="删除业务表信息", description="删除业务表信息")
|
||||||
async def delete_gen_table_controller(
|
async def delete_gen_table_controller(
|
||||||
data: GenTableDeleteSchema = Body(..., description="业务表ID列表"),
|
ids: List[int] = Body(..., description="业务表ID列表"),
|
||||||
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:delete"]))
|
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:delete"]))
|
||||||
) -> JSONResponse:
|
) -> JSONResponse:
|
||||||
result = await GenTableService.delete_gen_table_service(auth, data)
|
result = await GenTableService.delete_gen_table_service(auth, ids)
|
||||||
logger.info('删除业务表信息成功')
|
logger.info('删除业务表信息成功')
|
||||||
return SuccessResponse(msg="删除业务表信息成功", data=result)
|
return SuccessResponse(msg="删除业务表信息成功", data=result)
|
||||||
|
|
||||||
|
|
||||||
@GenRouter.patch("/batch/output", summary="批量生成代码", description="批量生成代码")
|
@GenRouter.patch("/batch/output", summary="批量生成代码", description="批量生成代码")
|
||||||
async def batch_gen_code_controller(
|
async def batch_gen_code_controller(
|
||||||
table_names: List[str] = Query(..., description="表名列表"),
|
table_names: List[str] = Body(..., description="表名列表"),
|
||||||
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:operate"]))
|
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:operate"]))
|
||||||
) -> StreamResponse:
|
) -> StreamResponse:
|
||||||
# 检查table_names是否为空
|
# 检查table_names是否为空
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ from .model import GenTableModel, GenTableColumnModel
|
|||||||
from .schema import (
|
from .schema import (
|
||||||
GenTableSchema,
|
GenTableSchema,
|
||||||
GenTableOutSchema,
|
GenTableOutSchema,
|
||||||
GenTableDeleteSchema,
|
|
||||||
GenTableColumnSchema,
|
GenTableColumnSchema,
|
||||||
GenTableColumnOutSchema,
|
GenTableColumnOutSchema,
|
||||||
GenTableColumnDeleteSchema,
|
GenTableColumnDeleteSchema,
|
||||||
@@ -137,12 +136,12 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
|
|||||||
await self.db.commit()
|
await self.db.commit()
|
||||||
return edit_model
|
return edit_model
|
||||||
|
|
||||||
async def delete_gen_table(self, data: GenTableDeleteSchema) -> None:
|
async def delete_gen_table(self, ids: List[int]) -> None:
|
||||||
"""
|
"""
|
||||||
删除
|
删除
|
||||||
"""
|
"""
|
||||||
await self.db.execute(
|
await self.db.execute(
|
||||||
delete(GenTableModel).where(GenTableModel.id.in_(data.table_ids))
|
delete(GenTableModel).where(GenTableModel.id.in_(ids))
|
||||||
)
|
)
|
||||||
await self.db.flush()
|
await self.db.flush()
|
||||||
|
|
||||||
@@ -459,10 +458,10 @@ class GenTableColumnCRUD(CRUDBase[GenTableColumnModel, GenTableColumnSchema, Gen
|
|||||||
"""更新业务表字段"""
|
"""更新业务表字段"""
|
||||||
return await self.update(id=id, data=data)
|
return await self.update(id=id, data=data)
|
||||||
|
|
||||||
async def delete_gen_table_column_by_table_id_dao(self, data: GenTableDeleteSchema) -> None:
|
async def delete_gen_table_column_by_table_id_dao(self, table_ids: List[int]) -> None:
|
||||||
"""根据业务表ID批量删除"""
|
"""根据业务表ID批量删除"""
|
||||||
# 先查询出这些表ID对应的所有字段ID
|
# 先查询出这些表ID对应的所有字段ID
|
||||||
query = select(GenTableColumnModel.id).where(GenTableColumnModel.table_id.in_(data.table_ids))
|
query = select(GenTableColumnModel.id).where(GenTableColumnModel.table_id.in_(table_ids))
|
||||||
result = await self.db.execute(query)
|
result = await self.db.execute(query)
|
||||||
column_ids = [row[0] for row in result.fetchall()]
|
column_ids = [row[0] for row in result.fetchall()]
|
||||||
|
|
||||||
|
|||||||
@@ -108,15 +108,6 @@ class GenTableOutSchema(GenTableSchema, BaseSchema):
|
|||||||
return values
|
return values
|
||||||
|
|
||||||
|
|
||||||
class GenTableDeleteSchema(BaseModel):
|
|
||||||
"""
|
|
||||||
删除代码生成业务表模型
|
|
||||||
"""
|
|
||||||
model_config = ConfigDict(alias_generator=to_camel)
|
|
||||||
|
|
||||||
table_ids: List[int] = Field(..., description='需要删除的代码生成业务表ID列表')
|
|
||||||
|
|
||||||
|
|
||||||
class GenTableColumnSchema(BaseModel):
|
class GenTableColumnSchema(BaseModel):
|
||||||
"""
|
"""
|
||||||
代码生成业务表字段创建模型
|
代码生成业务表字段创建模型
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from app.api.v1.module_system.auth.schema import AuthSchema
|
|||||||
from app.utils.common_util import CamelCaseUtil
|
from app.utils.common_util import CamelCaseUtil
|
||||||
from app.utils.gen_util import GenUtils
|
from app.utils.gen_util import GenUtils
|
||||||
from app.utils.jinja2_template_util import Jinja2TemplateInitializerUtil, Jinja2TemplateUtil
|
from app.utils.jinja2_template_util import Jinja2TemplateInitializerUtil, Jinja2TemplateUtil
|
||||||
from .schema import GenTableSchema, GenTableOutSchema, GenTableOutSchema, GenTableDeleteSchema, GenTableColumnSchema, GenTableColumnOutSchema, GenTableColumnDeleteSchema
|
from .schema import GenTableSchema, GenTableOutSchema, GenTableOutSchema, GenTableColumnSchema, GenTableColumnOutSchema, GenTableColumnDeleteSchema
|
||||||
from .param import GenTableQueryParam
|
from .param import GenTableQueryParam
|
||||||
from .crud import GenTableColumnCRUD, GenTableCRUD
|
from .crud import GenTableColumnCRUD, GenTableCRUD
|
||||||
|
|
||||||
@@ -211,13 +211,13 @@ class GenTableService:
|
|||||||
raise CustomException(msg='业务表不存在')
|
raise CustomException(msg='业务表不存在')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def delete_gen_table_service(cls, auth: AuthSchema, data: GenTableDeleteSchema) -> None:
|
async def delete_gen_table_service(cls, auth: AuthSchema, ids: List[int]) -> None:
|
||||||
"""删除业务表信息"""
|
"""删除业务表信息"""
|
||||||
try:
|
try:
|
||||||
# 先删除相关的字段信息
|
# 先删除相关的字段信息
|
||||||
await GenTableColumnCRUD(auth=auth).delete_gen_table_column_by_table_id_dao(data)
|
await GenTableColumnCRUD(auth=auth).delete_gen_table_column_by_table_id_dao(ids)
|
||||||
# 再删除表信息
|
# 再删除表信息
|
||||||
await GenTableCRUD(auth=auth).delete_gen_table(data)
|
await GenTableCRUD(auth=auth).delete_gen_table(ids)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise CustomException(msg=f'删除失败: {str(e)}')
|
raise CustomException(msg=f'删除失败: {str(e)}')
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from datetime import datetime
|
|||||||
|
|
||||||
from app.core.base_crud import CRUDBase
|
from app.core.base_crud import CRUDBase
|
||||||
from .model import UserModel
|
from .model import UserModel
|
||||||
from .schema import UserCreateSchema,UserForgetPasswordSchema,UserUpdateSchema
|
from .schema import UserCreateSchema, UserForgetPasswordSchema, UserUpdateSchema
|
||||||
from ..role.crud import RoleCRUD
|
from ..role.crud import RoleCRUD
|
||||||
from ..position.crud import PositionCRUD
|
from ..position.crud import PositionCRUD
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class UserCreateSchema(CurrentUserUpdateSchema):
|
|||||||
"""新增"""
|
"""新增"""
|
||||||
model_config = ConfigDict(from_attributes=True)
|
model_config = ConfigDict(from_attributes=True)
|
||||||
|
|
||||||
username: str = Field(default=..., max_length=32, description="用户名")
|
username: Optional[str] = Field(default=None, max_length=32, description="用户名")
|
||||||
password: Optional[str] = Field(default=None, max_length=128, description="密码哈希值")
|
password: Optional[str] = Field(default=None, max_length=128, description="密码哈希值")
|
||||||
status: bool = Field(default=True, description="是否可用")
|
status: bool = Field(default=True, description="是否可用")
|
||||||
is_superuser: bool = Field(default=False, description="是否超管")
|
is_superuser: bool = Field(default=False, description="是否超管")
|
||||||
@@ -82,6 +82,7 @@ class UserUpdateSchema(UserCreateSchema):
|
|||||||
|
|
||||||
last_login: Optional[DateTimeStr] = Field(default=None, description="最后登录时间")
|
last_login: Optional[DateTimeStr] = Field(default=None, description="最后登录时间")
|
||||||
|
|
||||||
|
|
||||||
class UserOutSchema(UserCreateSchema, BaseSchema):
|
class UserOutSchema(UserCreateSchema, BaseSchema):
|
||||||
"""响应"""
|
"""响应"""
|
||||||
model_config = ConfigDict(arbitrary_types_allowed=True, from_attributes=True)
|
model_config = ConfigDict(arbitrary_types_allowed=True, from_attributes=True)
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ class UserService:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def create_user_service(cls, data: UserCreateSchema, auth: AuthSchema) -> Dict:
|
async def create_user_service(cls, data: UserCreateSchema, auth: AuthSchema) -> Dict:
|
||||||
|
if not data.username:
|
||||||
|
raise CustomException(msg="用户名不能为空")
|
||||||
# 检查用户名是否存在
|
# 检查用户名是否存在
|
||||||
user = await UserCRUD(auth).get_by_username_crud(username=data.username)
|
user = await UserCRUD(auth).get_by_username_crud(username=data.username)
|
||||||
if user:
|
if user:
|
||||||
@@ -97,6 +99,8 @@ class UserService:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def update_user_service(cls, id: int, data: UserUpdateSchema, auth: AuthSchema) -> Dict:
|
async def update_user_service(cls, id: int, data: UserUpdateSchema, auth: AuthSchema) -> Dict:
|
||||||
|
if not data.username:
|
||||||
|
raise CustomException(msg="用户名不能为空")
|
||||||
# 检查用户是否存在
|
# 检查用户是否存在
|
||||||
user = await UserCRUD(auth).get_by_id_crud(id=id)
|
user = await UserCRUD(auth).get_by_id_crud(id=id)
|
||||||
if not user:
|
if not user:
|
||||||
|
|||||||
@@ -162,29 +162,6 @@ class Settings(BaseSettings):
|
|||||||
GZIP_MIN_SIZE: int = 1000 # 最小压缩大小(字节)
|
GZIP_MIN_SIZE: int = 1000 # 最小压缩大小(字节)
|
||||||
GZIP_COMPRESS_LEVEL: int = 9 # 压缩级别(1-9)
|
GZIP_COMPRESS_LEVEL: int = 9 # 压缩级别(1-9)
|
||||||
|
|
||||||
# # ================================================= #
|
|
||||||
# # ***************** 演示模型配置 ***************** #
|
|
||||||
# # ================================================= #
|
|
||||||
# DEMO_ENABLE: bool # 是否开启演示模式
|
|
||||||
# DEMO_WHITE_LIST_PATH: List[str] = [ # 演示白名单
|
|
||||||
# "/api/v1/system/auth/login",
|
|
||||||
# "/api/v1/system/auth/token/refresh",
|
|
||||||
# "/api/v1/system/auth/captcha/get",
|
|
||||||
# "/api/v1/system/auth/logout",
|
|
||||||
# "/api/v1/system/config/info",
|
|
||||||
# "/api/v1/system/user/current/info",
|
|
||||||
# "/api/v1/system/notice/available",
|
|
||||||
# ]
|
|
||||||
# DEMO_BLACK_LIST_PATH: List[str] = [ # 演示黑名单
|
|
||||||
# "/auth/login"
|
|
||||||
# ]
|
|
||||||
# DEMO_IP_WHITE_LIST: List[str] = [ # 演示白名单IP
|
|
||||||
# "127.0.0.1",
|
|
||||||
# "117.10.167.220",
|
|
||||||
# "223.104.208.30",
|
|
||||||
# "42.80.102.171"
|
|
||||||
# ]
|
|
||||||
|
|
||||||
# ================================================= #
|
# ================================================= #
|
||||||
# ***************** 静态文件配置 ***************** #
|
# ***************** 静态文件配置 ***************** #
|
||||||
# ================================================= #
|
# ================================================= #
|
||||||
@@ -202,7 +179,7 @@ class Settings(BaseSettings):
|
|||||||
# ================================================= #
|
# ================================================= #
|
||||||
# ***************** 动态文件配置 ***************** #
|
# ***************** 动态文件配置 ***************** #
|
||||||
# ================================================= #
|
# ================================================= #
|
||||||
UPLOAD_FILE_PATH: Path = BASE_DIR.joinpath('static/upload') # 上传目录
|
UPLOAD_FILE_PATH: Path = Path('static/upload') # 上传目录
|
||||||
UPLOAD_MACHINE: str = 'A' # 上传机器标识
|
UPLOAD_MACHINE: str = 'A' # 上传机器标识
|
||||||
ALLOWED_EXTENSIONS: list[str] = [ # 允许的文件类型
|
ALLOWED_EXTENSIONS: list[str] = [ # 允许的文件类型
|
||||||
# 图片
|
# 图片
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ from app.api.v1.module_generator.gencode.schema import (
|
|||||||
GenTableBaseSchema,
|
GenTableBaseSchema,
|
||||||
GenTableSchema,
|
GenTableSchema,
|
||||||
GenTableOutSchema,
|
GenTableOutSchema,
|
||||||
GenTableDeleteSchema,
|
|
||||||
GenTableColumnSchema,
|
GenTableColumnSchema,
|
||||||
GenTableColumnOutSchema,
|
GenTableColumnOutSchema,
|
||||||
GenTableColumnDeleteSchema
|
GenTableColumnDeleteSchema
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ class Jinja2TemplateUtil:
|
|||||||
# Vue相关模板
|
# Vue相关模板
|
||||||
f'{use_web_type}/api.ts.j2',
|
f'{use_web_type}/api.ts.j2',
|
||||||
# SQL脚本模板
|
# SQL脚本模板
|
||||||
'sql/sql.j2',
|
'sql/sql.sql.j2',
|
||||||
]
|
]
|
||||||
if category == GenConstant.TPL_CRUD:
|
if category == GenConstant.TPL_CRUD:
|
||||||
templates.append(f'{use_web_type}/index.vue.j2')
|
templates.append(f'{use_web_type}/index.vue.j2')
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ pydantic-settings==2.5.2 # 配置设置
|
|||||||
psutil==6.1.0 # 系统信息
|
psutil==6.1.0 # 系统信息
|
||||||
python-multipart==0.0.9 # request.form() 对表单进行「解析」时安装
|
python-multipart==0.0.9 # request.form() 对表单进行「解析」时安装
|
||||||
greenlet==3.1.1 # 协程框架
|
greenlet==3.1.1 # 协程框架
|
||||||
bcrypt==4.0.1 # 密码加密解析
|
bcrypt==4.3.0 # 密码加密解析
|
||||||
itsdangerous==2.2.0 # 用于安全处理各种数据,如密码、密钥等
|
itsdangerous==2.2.0 # 用于安全处理各种数据,如密码、密钥等
|
||||||
aiofiles==24.1.0 # 文件操作
|
aiofiles==24.1.0 # 文件操作
|
||||||
redis==5.2.1 # redis 同步操作数据库(用户celery配套使用)redis 异步操作数据库 redis已经完全具备了aioredis的功能,无需重复安全,且aioredis已经不再维护也不兼容3.10+的版本
|
redis==5.2.1 # redis 同步操作数据库(用户celery配套使用)redis 异步操作数据库 redis已经完全具备了aioredis的功能,无需重复安全,且aioredis已经不再维护也不兼容3.10+的版本
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const API_PATH = "/generator/gencode";
|
|||||||
|
|
||||||
const GencodeAPI = {
|
const GencodeAPI = {
|
||||||
// 查询生成表数据
|
// 查询生成表数据
|
||||||
listTable(query: TablePageQuery) {
|
listTable(query: GenTableQueryParam) {
|
||||||
return request<ApiResponse<PageResult<GenTableOutVO[]>>>({
|
return request<ApiResponse<PageResult<GenTableOutVO[]>>>({
|
||||||
url: `${API_PATH}/list`,
|
url: `${API_PATH}/list`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
@@ -13,25 +13,20 @@ const GencodeAPI = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// 查询db数据库列表
|
// 查询db数据库列表
|
||||||
listDbTable(query: TablePageQuery) {
|
listDbTable(query: GenTableQueryParam) {
|
||||||
return request<ApiResponse<PageResult<TablePageVO[]>>>({
|
return request<ApiResponse<PageResult<DatabaseTable[]>>>({
|
||||||
url: `${API_PATH}/db/list`,
|
url: `${API_PATH}/db/list`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: query
|
params: query
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 导入表 - 将数组转换为适合FastAPI解析的格式
|
// 导入表
|
||||||
importTable(table_names: string[]) {
|
importTable(table_names: string[]) {
|
||||||
// 构建符合FastAPI期望的查询字符串
|
|
||||||
let queryString = '';
|
|
||||||
table_names.forEach((name, index) => {
|
|
||||||
queryString += `${index === 0 ? '?' : '&'}table_names=${encodeURIComponent(name)}`;
|
|
||||||
});
|
|
||||||
|
|
||||||
return request<ApiResponse>({
|
return request<ApiResponse>({
|
||||||
url: `${API_PATH}/import${queryString}`,
|
url: `${API_PATH}/import`,
|
||||||
method: 'post'
|
method: 'post',
|
||||||
|
data: table_names
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -48,25 +43,25 @@ const GencodeAPI = {
|
|||||||
return request<ApiResponse>({
|
return request<ApiResponse>({
|
||||||
url: `${API_PATH}/create`,
|
url: `${API_PATH}/create`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
params: { sql }
|
data: sql
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 修改代码生成信息
|
// 更新表信息
|
||||||
updateGenTable(table_id: number, body: GenTableSchema) {
|
updateTable(data: GenTableSchema, table_id: number) {
|
||||||
return request<ApiResponse>({
|
return request<ApiResponse>({
|
||||||
url: `${API_PATH}/update/${table_id}`,
|
url: `${API_PATH}/update/${table_id}`,
|
||||||
method: 'put',
|
method: 'put',
|
||||||
data: body,
|
data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 删除表数据
|
// 删除表数据
|
||||||
deleteTable(data: GenTableDeleteSchema) {
|
deleteTable(table_ids: number[]) {
|
||||||
return request<ApiResponse>({
|
return request<ApiResponse>({
|
||||||
url: `${API_PATH}/delete`,
|
url: `${API_PATH}/delete`,
|
||||||
method: 'delete',
|
method: 'delete',
|
||||||
data
|
data: table_ids
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -75,7 +70,7 @@ const GencodeAPI = {
|
|||||||
return request<Blob>({
|
return request<Blob>({
|
||||||
url: `${API_PATH}/batch/output`,
|
url: `${API_PATH}/batch/output`,
|
||||||
method: 'patch',
|
method: 'patch',
|
||||||
params: { table_names },
|
data: table_names,
|
||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -89,9 +84,9 @@ const GencodeAPI = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// 预览生成代码
|
// 预览生成代码
|
||||||
previewTable(table_id: number) {
|
previewTable(id: number) {
|
||||||
return request<ApiResponse<GeneratorPreviewVO[]>>({
|
return request<ApiResponse<Record<string, string>>>({
|
||||||
url: `${API_PATH}/preview/${table_id}`,
|
url: `${API_PATH}/preview/${id}`,
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -118,6 +113,15 @@ export interface GeneratorPreviewVO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 数据表分页查询参数 */
|
/** 数据表分页查询参数 */
|
||||||
|
export interface GenTableQueryParam {
|
||||||
|
page_no: number;
|
||||||
|
page_size: number;
|
||||||
|
table_name?: string;
|
||||||
|
table_comment?: string;
|
||||||
|
start_time?: string;
|
||||||
|
end_time?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface TablePageQuery extends PageQuery {
|
export interface TablePageQuery extends PageQuery {
|
||||||
/** 表名称 */
|
/** 表名称 */
|
||||||
table_name?: string;
|
table_name?: string;
|
||||||
@@ -146,27 +150,27 @@ export interface GenTableOutVO {
|
|||||||
/** 主键 */
|
/** 主键 */
|
||||||
id?: number;
|
id?: number;
|
||||||
/** 表名称 */
|
/** 表名称 */
|
||||||
table_name: string;
|
table_name?: string;
|
||||||
/** 表描述 */
|
/** 表描述 */
|
||||||
table_comment: string;
|
table_comment?: string;
|
||||||
/** 关联子表的表名 */
|
/** 关联子表的表名 */
|
||||||
sub_table_name?: string;
|
sub_table_name?: string;
|
||||||
/** 子表关联的外键名 */
|
/** 子表关联的外键名 */
|
||||||
sub_table_fk_name: string;
|
sub_table_fk_name?: string;
|
||||||
/** 实体类名称 */
|
/** 实体类名称 */
|
||||||
class_name: string;
|
class_name?: string;
|
||||||
/** 使用的模板(crud单表操作 tree树表操作) */
|
/** 使用的模板(crud单表操作 tree树表操作) */
|
||||||
tpl_category?: string;
|
tpl_category?: string;
|
||||||
/** 前端模板类型(element-ui模版 element-plus模版) */
|
/** 前端模板类型(element-ui模版 element-plus模版) */
|
||||||
tpl_web_type?: string;
|
tpl_web_type?: string;
|
||||||
/** 生成包路径 */
|
/** 生成包路径 */
|
||||||
package_name: string;
|
package_name?: string;
|
||||||
/** 生成模块名 */
|
/** 生成模块名 */
|
||||||
module_name: string;
|
module_name?: string;
|
||||||
/** 生成业务名 */
|
/** 生成业务名 */
|
||||||
business_name: string;
|
business_name?: string;
|
||||||
/** 生成功能名 */
|
/** 生成功能名 */
|
||||||
function_name: string;
|
function_name?: string;
|
||||||
/** 生成功能作者 */
|
/** 生成功能作者 */
|
||||||
function_author?: string;
|
function_author?: string;
|
||||||
/** 生成代码方式(0zip压缩包 1自定义路径) */
|
/** 生成代码方式(0zip压缩包 1自定义路径) */
|
||||||
@@ -191,6 +195,24 @@ export interface GenTableOutVO {
|
|||||||
tree?: boolean;
|
tree?: boolean;
|
||||||
/** 是否为单表 */
|
/** 是否为单表 */
|
||||||
crud?: boolean;
|
crud?: boolean;
|
||||||
|
/** 表描述 */
|
||||||
|
description?: string;
|
||||||
|
/** 列列表 */
|
||||||
|
columns?: GenTableColumnOutSchema[];
|
||||||
|
/** 参数选项 */
|
||||||
|
params?: GenTableOptionModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表选项模型 */
|
||||||
|
export interface GenTableOptionModel {
|
||||||
|
/** 所属父级分类 */
|
||||||
|
parent_menu_id?: number;
|
||||||
|
/** 树编码 */
|
||||||
|
tree_code?: string;
|
||||||
|
/** 树名称 */
|
||||||
|
tree_name?: string;
|
||||||
|
/** 树父编码 */
|
||||||
|
tree_parent_code?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 代码生成业务表模型 */
|
/** 代码生成业务表模型 */
|
||||||
@@ -214,11 +236,11 @@ export interface GenTableColumnSchema {
|
|||||||
/** 列描述 */
|
/** 列描述 */
|
||||||
column_comment?: string;
|
column_comment?: string;
|
||||||
/** 列类型 */
|
/** 列类型 */
|
||||||
column_type: string;
|
column_type?: string;
|
||||||
/** PYTHON类型 */
|
/** PYTHON类型 */
|
||||||
python_type?: string;
|
python_type?: string;
|
||||||
/** PYTHON字段名 */
|
/** PYTHON字段名 */
|
||||||
python_field: string;
|
python_field?: string;
|
||||||
/** 是否主键(1是) */
|
/** 是否主键(1是) */
|
||||||
is_pk?: string;
|
is_pk?: string;
|
||||||
/** 是否自增(1是) */
|
/** 是否自增(1是) */
|
||||||
@@ -238,9 +260,9 @@ export interface GenTableColumnSchema {
|
|||||||
/** 查询方式(等于、不等于、大于、小于、范围) */
|
/** 查询方式(等于、不等于、大于、小于、范围) */
|
||||||
query_type?: string;
|
query_type?: string;
|
||||||
/** 显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件) */
|
/** 显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件) */
|
||||||
html_type: string;
|
html_type?: string;
|
||||||
/** 字典类型 */
|
/** 字典类型 */
|
||||||
dict_type: string;
|
dict_type?: string;
|
||||||
/** 排序 */
|
/** 排序 */
|
||||||
sort?: number;
|
sort?: number;
|
||||||
/** 功能描述 */
|
/** 功能描述 */
|
||||||
@@ -273,12 +295,6 @@ export interface GenTableColumnOutSchema extends GenTableColumnSchema {
|
|||||||
usable_column?: boolean;
|
usable_column?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 删除代码生成业务表模型 */
|
|
||||||
export interface GenTableDeleteSchema {
|
|
||||||
/** 需要删除的代码生成业务表ID列表 */
|
|
||||||
table_ids: number[];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 表详情查询结果 */
|
/** 表详情查询结果 */
|
||||||
export interface GenTableDetailResult {
|
export interface GenTableDetailResult {
|
||||||
/** 表信息 */
|
/** 表信息 */
|
||||||
@@ -288,3 +304,59 @@ export interface GenTableDetailResult {
|
|||||||
/** 所有表信息 */
|
/** 所有表信息 */
|
||||||
tables: GenTableOutVO[];
|
tables: GenTableOutVO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据库表基本信息接口
|
||||||
|
*/
|
||||||
|
export interface DatabaseTable {
|
||||||
|
database_name?: string;
|
||||||
|
table_name?: string;
|
||||||
|
table_comment?: string;
|
||||||
|
table_type?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表列基本信息接口
|
||||||
|
*/
|
||||||
|
export interface TableColumn {
|
||||||
|
column_name: string;
|
||||||
|
column_comment: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表基本信息接口
|
||||||
|
*/
|
||||||
|
export interface TableInfo {
|
||||||
|
table_name?: string;
|
||||||
|
table_comment?: string;
|
||||||
|
columns?: TableColumn[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典选项接口
|
||||||
|
*/
|
||||||
|
export interface DictOption {
|
||||||
|
dict_type: string;
|
||||||
|
dict_name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入表查询表单数据接口
|
||||||
|
*/
|
||||||
|
export interface ImportTableQueryForm {
|
||||||
|
page_no: number;
|
||||||
|
page_size: number;
|
||||||
|
table_name?: string;
|
||||||
|
table_comment?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基本信息表单数据接口
|
||||||
|
*/
|
||||||
|
export interface BasicInfoFormData {
|
||||||
|
table_name?: string;
|
||||||
|
table_comment?: string;
|
||||||
|
class_name?: string;
|
||||||
|
function_author?: string;
|
||||||
|
remark?: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -220,17 +220,17 @@ export interface positionSelectorType {
|
|||||||
|
|
||||||
export interface InfoFormState {
|
export interface InfoFormState {
|
||||||
id?: number;
|
id?: number;
|
||||||
name: string;
|
name?: string;
|
||||||
gender: number;
|
gender?: number;
|
||||||
mobile: string;
|
mobile?: string;
|
||||||
email: string;
|
email?: string;
|
||||||
username: string;
|
username?: string;
|
||||||
dept_name: string;
|
dept_name?: string;
|
||||||
dept: deptTreeType;
|
dept?: deptTreeType;
|
||||||
positions: positionSelectorType[];
|
positions?: positionSelectorType[];
|
||||||
roles: roleSelectorType[];
|
roles?: roleSelectorType[];
|
||||||
avatar: string;
|
avatar?: string;
|
||||||
created_at: string;
|
created_at?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PasswordFormState {
|
export interface PasswordFormState {
|
||||||
@@ -262,3 +262,11 @@ export interface UserForm {
|
|||||||
status?: boolean;
|
status?: boolean;
|
||||||
description?: string;
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CurrentUserFormState {
|
||||||
|
name?: string;
|
||||||
|
gender?: number;
|
||||||
|
mobile?: string;
|
||||||
|
email?: string;
|
||||||
|
avatar?: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1760263323196" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1502" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M420.693333 85.333333C353.28 85.333333 298.666667 139.946667 298.666667 207.36v71.68h183.04c16.64 0 30.293333 24.32 30.293333 40.96H207.36C139.946667 320 85.333333 374.613333 85.333333 442.026667v161.322666c0 67.413333 54.613333 122.026667 122.026667 122.026667h50.346667v-114.346667c0-67.413333 54.186667-122.026667 121.6-122.026666h224c67.413333 0 122.026667-54.229333 122.026666-121.642667V207.36C725.333333 139.946667 670.72 85.333333 603.306667 85.333333z m-30.72 68.693334c17.066667 0 30.72 5.12 30.72 30.293333s-13.653333 38.016-30.72 38.016c-16.64 0-30.293333-12.8-30.293333-37.973333s13.653333-30.336 30.293333-30.336z" fill="#3C78AA" p-id="1503"></path><path d="M766.250667 298.666667v114.346666a121.6 121.6 0 0 1-121.6 121.984H420.693333A121.6 121.6 0 0 0 298.666667 656.597333v160a122.026667 122.026667 0 0 0 122.026666 122.026667h182.613334A122.026667 122.026667 0 0 0 725.333333 816.64v-71.68h-183.082666c-16.64 0-30.250667-24.32-30.250667-40.96h304.64A122.026667 122.026667 0 0 0 938.666667 581.973333v-161.28a122.026667 122.026667 0 0 0-122.026667-122.026666zM354.986667 491.221333l-0.170667 0.170667c0.512-0.085333 1.066667-0.042667 1.621333-0.170667z m279.04 310.442667c16.64 0 30.293333 12.8 30.293333 37.973333a30.293333 30.293333 0 0 1-30.293333 30.293334c-17.066667 0-30.72-5.12-30.72-30.293334s13.653333-37.973333 30.72-37.973333z" fill="#FDD835" p-id="1504"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1760263428378" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5841" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M33.792 631.808c0 84.992 214.016 153.6 478.208 153.6 263.168 0 477.184-68.608 478.208-153.6V509.952C891.904 580.608 701.44 614.4 512 614.4c-189.44 0-379.904-33.792-478.208-105.472v122.88z" fill="#00CCFF" p-id="5842"></path><path d="M990.208 747.52C891.904 819.2 701.44 852.992 512 852.992 322.56 852.992 132.096 819.2 33.792 747.52v139.264C60.416 964.608 266.24 1024 512 1024s451.584-59.392 478.208-136.192V747.52zM33.792 392.192c0 84.992 214.016 153.6 478.208 153.6 263.168 0 477.184-68.608 478.208-153.6V270.336c-98.304 71.68-288.768 105.472-478.208 105.472-189.44 0-379.904-33.792-478.208-105.472v121.856z" fill="#00CCFF" p-id="5843"></path><path d="M33.792 153.6a478.208 153.6 0 1 0 956.416 0 478.208 153.6 0 1 0-956.416 0Z" fill="#00CCFF" p-id="5844"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -116,6 +116,6 @@ html.sidebar-color-blue .layout-mix .layout__sidebar--left .el-menu {
|
|||||||
// 分页区域
|
// 分页区域
|
||||||
.el-pagination {
|
.el-pagination {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
// margin-top: 1px;
|
// margin-top: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
{{ infoFormState.name }}
|
{{ infoFormState.name }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<el-text>{{infoFormState.roles.map(item => item.name).join('、')}}</el-text>
|
<el-text>{{infoFormState.roles?.map(item => item.name).join('、')}}</el-text>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-divider />
|
<el-divider />
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
</el-icon>
|
</el-icon>
|
||||||
<span style="vertical-align: middle;">部门</span>
|
<span style="vertical-align: middle;">部门</span>
|
||||||
</template>
|
</template>
|
||||||
<span style="vertical-align: middle;">{{ infoFormState.dept.name }}</span>
|
<span style="vertical-align: middle;">{{ infoFormState.dept?.name }}</span>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item>
|
<el-descriptions-item>
|
||||||
<template #label>
|
<template #label>
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
</el-icon>
|
</el-icon>
|
||||||
<span style="vertical-align: middle;">岗位</span>
|
<span style="vertical-align: middle;">岗位</span>
|
||||||
</template>
|
</template>
|
||||||
<span style="vertical-align: middle;">{{infoFormState.positions.map(item => item.name).join('、')}}</span>
|
<span style="vertical-align: middle;">{{infoFormState.positions?.map(item => item.name).join('、')}}</span>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item>
|
<el-descriptions-item>
|
||||||
<template #label>
|
<template #label>
|
||||||
@@ -176,7 +176,7 @@
|
|||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="确认新密码" name="confirm_password">
|
<el-form-item label="确认密码" name="confirm_password">
|
||||||
<el-input v-model.trim="passwordFormState.confirm_password" type="password" :placeholder="t('login.message.password.confirm')" show-password clearable style="width: 240px;">
|
<el-input v-model.trim="passwordFormState.confirm_password" type="password" :placeholder="t('login.message.password.confirm')" show-password clearable style="width: 240px;">
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<Check />
|
<Check />
|
||||||
@@ -227,17 +227,17 @@ const infoSubmitting = ref(false);
|
|||||||
|
|
||||||
// 用户基础信息表单
|
// 用户基础信息表单
|
||||||
const infoFormState = reactive<InfoFormState>({
|
const infoFormState = reactive<InfoFormState>({
|
||||||
name: '',
|
name: undefined,
|
||||||
gender: 1,
|
gender: 1,
|
||||||
mobile: '',
|
mobile: undefined,
|
||||||
email: '',
|
email: undefined,
|
||||||
username: '',
|
username: undefined,
|
||||||
dept_name: '',
|
dept_name: undefined,
|
||||||
dept: {},
|
dept: {},
|
||||||
positions: [],
|
positions: [],
|
||||||
roles: [],
|
roles: [],
|
||||||
avatar: '',
|
avatar: undefined,
|
||||||
created_at: ''
|
created_at: undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
// 修改密码表单
|
// 修改密码表单
|
||||||
@@ -421,9 +421,6 @@ const handleSave = async () => {
|
|||||||
// 确保avatar字段被正确处理
|
// 确保avatar字段被正确处理
|
||||||
const response = await UserAPI.updateCurrentUserInfo({...infoFormState});
|
const response = await UserAPI.updateCurrentUserInfo({...infoFormState});
|
||||||
await userStore.setUserInfo(response.data.data);
|
await userStore.setUserInfo(response.data.data);
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
ElMessage.error('保存失败,请重试');
|
|
||||||
} finally {
|
} finally {
|
||||||
infoSubmitting.value = false;
|
infoSubmitting.value = false;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,48 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-form ref="basicInfoForm" :model="info" :rules="rules" label-width="150px">
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="表名称" prop="tableName">
|
|
||||||
<el-input v-model="info.table_name" placeholder="请输入仓库名称"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="表描述" prop="tableComment">
|
|
||||||
<el-input v-model="info.table_comment" placeholder="请输入"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="实体类名称" prop="className">
|
|
||||||
<el-input v-model="info.class_name" placeholder="请输入"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="作者" prop="functionAuthor">
|
|
||||||
<el-input v-model="info.function_author" placeholder="请输入"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item label="备注" prop="remark">
|
|
||||||
<el-input v-model="info.remark" type="textarea" :rows="3"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
defineProps({
|
|
||||||
info: {
|
|
||||||
type: Object,
|
|
||||||
default: null
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 表单校验
|
|
||||||
const rules = ref({
|
|
||||||
table_name: [{ required: true, message: "请输入表名称", trigger: "blur" }],
|
|
||||||
table_comment: [{ required: true, message: "请输入表描述", trigger: "blur" }],
|
|
||||||
class_name: [{ required: true, message: "请输入实体类名称", trigger: "blur" }],
|
|
||||||
function_author: [{ required: true, message: "请输入作者", trigger: "blur" }]
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
<template>
|
|
||||||
<!-- 创建表 -->
|
|
||||||
<el-dialog v-model="visible" title="创建表" width="800px" top="5vh" append-to-body>
|
|
||||||
<span>创建表语句(支持多个建表语句):</span>
|
|
||||||
<el-input v-model="content" type="textarea" :rows="10" placeholder="请输入文本"></el-input>
|
|
||||||
<template #footer>
|
|
||||||
<div class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="handleImportTable">确 定</el-button>
|
|
||||||
<el-button @click="visible = false">取 消</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import GencodeAPI from "@/api/generator/gencode";
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
|
|
||||||
const visible = ref(false);
|
|
||||||
const content = ref("");
|
|
||||||
const emit = defineEmits(["ok"]);
|
|
||||||
|
|
||||||
/** 显示弹框 */
|
|
||||||
function show() {
|
|
||||||
visible.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 导入按钮操作 */
|
|
||||||
function handleImportTable() {
|
|
||||||
if (content.value === "") {
|
|
||||||
ElMessage.error("请输入建表语句");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
GencodeAPI.createTable(content.value).then(res => {
|
|
||||||
ElMessage.success(res.data.msg || "创建成功");
|
|
||||||
if (res.data.code === 200) {
|
|
||||||
visible.value = false;
|
|
||||||
emit("ok");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
show,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,235 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-card>
|
|
||||||
<el-tabs v-model="activeName">
|
|
||||||
<el-tab-pane label="基本信息" name="basic">
|
|
||||||
<basic-info-form ref="basicInfo" :info="info" />
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane label="字段信息" name="columnInfo">
|
|
||||||
<el-table ref="dragTable" :data="columns" row-key="columnId" :max-height="tableHeight">
|
|
||||||
<el-table-column label="序号" type="index" min-width="5%"/>
|
|
||||||
<el-table-column
|
|
||||||
label="字段列名"
|
|
||||||
prop="columnName"
|
|
||||||
min-width="10%"
|
|
||||||
:show-overflow-tooltip="true"
|
|
||||||
/>
|
|
||||||
<el-table-column label="字段描述" min-width="10%">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-input v-model="scope.row.columnComment"></el-input>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
label="物理类型"
|
|
||||||
prop="columnType"
|
|
||||||
min-width="10%"
|
|
||||||
:show-overflow-tooltip="true"
|
|
||||||
/>
|
|
||||||
<el-table-column label="Python类型" min-width="11%">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-select v-model="scope.row.pythonType">
|
|
||||||
<el-option label="str" value="str" />
|
|
||||||
<el-option label="int" value="int" />
|
|
||||||
<el-option label="float" value="float" />
|
|
||||||
<el-option label="Decimal" value="Decimal" />
|
|
||||||
<el-option label="date" value="date" />
|
|
||||||
<el-option label="time" value="time" />
|
|
||||||
<el-option label="datetime" value="datetime" />
|
|
||||||
<el-option label="bytes" value="bytes" />
|
|
||||||
<el-option label="dict" value="dict" />
|
|
||||||
<el-option label="list" value="list" />
|
|
||||||
</el-select>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="Python属性" min-width="10%">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-input v-model="scope.row.pythonField"></el-input>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column label="插入" min-width="5%">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-checkbox v-model="scope.row.isInsert" true-label="1" false-label="0"></el-checkbox>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="编辑" min-width="5%">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-checkbox v-model="scope.row.isEdit" true-label="1" false-label="0"></el-checkbox>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="列表" min-width="5%">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-checkbox v-model="scope.row.isList" true-label="1" false-label="0"></el-checkbox>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="查询" min-width="5%">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-checkbox v-model="scope.row.isQuery" true-label="1" false-label="0"></el-checkbox>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="查询方式" min-width="10%">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-select v-model="scope.row.queryType">
|
|
||||||
<el-option label="=" value="EQ" />
|
|
||||||
<el-option label="!=" value="NE" />
|
|
||||||
<el-option label=">" value="GT" />
|
|
||||||
<el-option label=">=" value="GTE" />
|
|
||||||
<el-option label="<" value="LT" />
|
|
||||||
<el-option label="<=" value="LTE" />
|
|
||||||
<el-option label="LIKE" value="LIKE" />
|
|
||||||
<el-option label="BETWEEN" value="BETWEEN" />
|
|
||||||
</el-select>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="必填" min-width="5%">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-checkbox v-model="scope.row.isRequired" true-label="1" false-label="0"></el-checkbox>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="唯一" min-width="5%">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-checkbox v-model="scope.row.isUnique" true-label="1" false-label="0"></el-checkbox>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="显示类型" min-width="12%">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-select v-model="scope.row.htmlType">
|
|
||||||
<el-option label="文本框" value="input" />
|
|
||||||
<el-option label="文本域" value="textarea" />
|
|
||||||
<el-option label="下拉框" value="select" />
|
|
||||||
<el-option label="单选框" value="radio" />
|
|
||||||
<el-option label="复选框" value="checkbox" />
|
|
||||||
<el-option label="日期控件" value="datetime" />
|
|
||||||
<el-option label="图片上传" value="imageUpload" />
|
|
||||||
<el-option label="文件上传" value="fileUpload" />
|
|
||||||
<el-option label="富文本控件" value="editor" />
|
|
||||||
</el-select>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="字典类型" min-width="12%">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-select v-model="scope.row.dictType" clearable filterable placeholder="请选择">
|
|
||||||
<el-option
|
|
||||||
v-for="dict in dictOptions"
|
|
||||||
:key="dict.dictType"
|
|
||||||
:label="dict.dictName"
|
|
||||||
:value="dict.dictType">
|
|
||||||
<span style="float: left">{{ dict.dictName }}</span>
|
|
||||||
<span style="float: right; color: #8492a6; font-size: 13px">{{ dict.dictType }}</span>
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane label="生成信息" name="genInfo">
|
|
||||||
<!-- 将GenTableSchema类型转换为GenInfo类型 -->
|
|
||||||
<gen-info-form
|
|
||||||
ref="genInfo"
|
|
||||||
:info="convertToGenInfo(info)"
|
|
||||||
:tables="tables"
|
|
||||||
/>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
<el-form label-width="100px">
|
|
||||||
<div style="text-align: center;margin-left:-100px;margin-top:10px;">
|
|
||||||
<el-button type="primary" @click="submitForm()">提交</el-button>
|
|
||||||
<el-button @click="close()">返回</el-button>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
|
||||||
</el-card>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="GenEdit">
|
|
||||||
import GencodeAPI from "@/api/generator/gencode";
|
|
||||||
import DictAPI from "@/api/system/dict";
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
import router from '@/router';
|
|
||||||
import type { GenTableSchema, GenTableDetailResult } from '@/api/generator/gencode';
|
|
||||||
|
|
||||||
const route = useRoute();
|
|
||||||
const basicInfoRef = ref();
|
|
||||||
const genInfoRef = ref();
|
|
||||||
|
|
||||||
const activeName = ref("columnInfo");
|
|
||||||
const tableHeight = ref(document.documentElement.scrollHeight - 245 + "px");
|
|
||||||
const tables = ref<Array<any>>([]);
|
|
||||||
const columns = ref<Array<any>>([]);
|
|
||||||
const dictOptions = ref<Array<any>>([]);
|
|
||||||
const info = ref<GenTableSchema>({} as GenTableSchema);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将对象转换为GenInfo类型
|
|
||||||
*/
|
|
||||||
function convertToGenInfo(tableSchema: any): any {
|
|
||||||
if (!tableSchema) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
tplCategory: tableSchema.tpl_category,
|
|
||||||
tplWebType: tableSchema.tpl_web_type,
|
|
||||||
packageName: tableSchema.package_name,
|
|
||||||
moduleName: tableSchema.module_name,
|
|
||||||
businessName: tableSchema.business_name,
|
|
||||||
functionName: tableSchema.function_name,
|
|
||||||
genType: tableSchema.gen_type,
|
|
||||||
parentMenuId: tableSchema.parent_menu_id,
|
|
||||||
genPath: tableSchema.gen_path,
|
|
||||||
subTableName: tableSchema.sub_table_name,
|
|
||||||
subTableFkName: tableSchema.sub_table_fk_name,
|
|
||||||
treeCode: tableSchema.tree_code,
|
|
||||||
treeParentCode: tableSchema.tree_parent_code,
|
|
||||||
treeName: tableSchema.tree_name
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 提交按钮 */
|
|
||||||
function submitForm() {
|
|
||||||
// 简化表单验证逻辑
|
|
||||||
const genTable = Object.assign({}, info.value);
|
|
||||||
genTable.columns = columns.value;
|
|
||||||
genTable.tree_code = info.value.tree_code;
|
|
||||||
genTable.tree_name = info.value.tree_name;
|
|
||||||
genTable.tree_parent_code = info.value.tree_parent_code;
|
|
||||||
genTable.parent_menu_id = info.value.parent_menu_id;
|
|
||||||
|
|
||||||
// 确保id存在且为number类型
|
|
||||||
if (info.value && info.value.id !== undefined) {
|
|
||||||
GencodeAPI.updateGenTable(Number(info.value.id), genTable).then((res: any) => {
|
|
||||||
ElMessage.success(res.data.message || "更新成功");
|
|
||||||
if (res.data.code === 200) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
ElMessage.error("表ID不存在,无法更新");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function close() {
|
|
||||||
const pageNum = route.query.page_no || route.query.pageNum;
|
|
||||||
router.push({ path: "/tool/gen", query: { t: Date.now(), page_no: pageNum } });
|
|
||||||
}
|
|
||||||
|
|
||||||
(() => {
|
|
||||||
const tableId = route.params && route.params.tableId;
|
|
||||||
if (tableId) {
|
|
||||||
// 获取表详细信息
|
|
||||||
GencodeAPI.getGenTableDetail(Number(tableId)).then(res => {
|
|
||||||
if (res.data && res.data.data) {
|
|
||||||
columns.value = res.data.data.rows || [];
|
|
||||||
// 确保info包含所有必要的字段,特别是columns
|
|
||||||
const tableInfo = res.data.data.info || {};
|
|
||||||
info.value = {
|
|
||||||
...tableInfo,
|
|
||||||
columns: columns.value
|
|
||||||
};
|
|
||||||
tables.value = res.data.data.tables || [];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
/** 查询字典下拉列表 */
|
|
||||||
DictAPI.getDictTypeOptionselect().then((response: any) => {
|
|
||||||
dictOptions.value = response.data.data || [];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
@@ -1,424 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-form ref="genInfoForm" :model="info" :rules="rules" label-width="150px">
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item prop="tplCategory">
|
|
||||||
<template #label>生成模板</template>
|
|
||||||
<el-select v-model="info.tplCategory" @change="tplSelectChange">
|
|
||||||
<el-option label="单表(增删改查)" value="crud" />
|
|
||||||
<el-option label="树表(增删改查)" value="tree" />
|
|
||||||
<el-option label="主子表(增删改查)" value="sub" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item prop="tplWebType">
|
|
||||||
<template #label>前端类型</template>
|
|
||||||
<el-select v-model="info.tplWebType">
|
|
||||||
<el-option label="Vue2 Element UI 模版" value="element-ui" />
|
|
||||||
<el-option label="Vue3 Element Plus 模版" value="element-plus" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item prop="packageName">
|
|
||||||
<template #label>
|
|
||||||
生成包路径
|
|
||||||
<el-tooltip content="生成在哪个java包下,例如 com.ruoyi.system" placement="top">
|
|
||||||
<el-icon><question-filled /></el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<el-input v-model="info.packageName" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item prop="moduleName">
|
|
||||||
<template #label>
|
|
||||||
生成模块名
|
|
||||||
<el-tooltip content="可理解为子系统名,例如 system" placement="top">
|
|
||||||
<el-icon><question-filled /></el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<el-input v-model="info.moduleName" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item prop="businessName">
|
|
||||||
<template #label>
|
|
||||||
生成业务名
|
|
||||||
<el-tooltip content="可理解为功能英文名,例如 user" placement="top">
|
|
||||||
<el-icon><question-filled /></el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<el-input v-model="info.businessName" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item prop="functionName">
|
|
||||||
<template #label>
|
|
||||||
生成功能名
|
|
||||||
<el-tooltip content="用作类描述,例如 用户" placement="top">
|
|
||||||
<el-icon><question-filled /></el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<el-input v-model="info.functionName" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item prop="genType">
|
|
||||||
<template #label>
|
|
||||||
生成代码方式
|
|
||||||
<el-tooltip content="默认为zip压缩包下载,也可以自定义生成路径" placement="top">
|
|
||||||
<el-icon><question-filled /></el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<el-radio v-model="info.genType" value="0">zip压缩包</el-radio>
|
|
||||||
<el-radio v-model="info.genType" value="1">自定义路径</el-radio>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item>
|
|
||||||
<template #label>
|
|
||||||
上级菜单
|
|
||||||
<el-tooltip content="分配到指定菜单下,例如 系统管理" placement="top">
|
|
||||||
<el-icon><question-filled /></el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<el-tree-select
|
|
||||||
v-model="info.parentMenuId"
|
|
||||||
:data="menuOptions"
|
|
||||||
:props="{ value: 'menuId', label: 'menuName', children: 'children' }"
|
|
||||||
value-key="menuId"
|
|
||||||
placeholder="请选择系统菜单"
|
|
||||||
check-strictly
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col v-if="info.genType == '1'" :span="24">
|
|
||||||
<el-form-item prop="genPath">
|
|
||||||
<template #label>
|
|
||||||
自定义路径
|
|
||||||
<el-tooltip content="填写磁盘绝对路径,若不填写,则生成到当前Web项目下" placement="top">
|
|
||||||
<el-icon><question-filled /></el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<el-input v-model="info.genPath">
|
|
||||||
<template #append>
|
|
||||||
<el-dropdown>
|
|
||||||
<el-button type="primary">
|
|
||||||
最近路径快速选择
|
|
||||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
|
||||||
</el-button>
|
|
||||||
<template #dropdown>
|
|
||||||
<el-dropdown-menu>
|
|
||||||
<el-dropdown-item @click="handleResetGenPath">恢复默认的生成基础路径</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
</el-dropdown>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<template v-if="info.tplCategory == 'tree'">
|
|
||||||
<h4 class="form-header">其他信息</h4>
|
|
||||||
<el-row v-show="info.tplCategory == 'tree'">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item>
|
|
||||||
<template #label>
|
|
||||||
树编码字段
|
|
||||||
<el-tooltip content="树显示的编码字段名, 如:dept_id" placement="top">
|
|
||||||
<el-icon><question-filled /></el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="info.treeCode" placeholder="请选择">
|
|
||||||
<el-option
|
|
||||||
v-for="(column, index) in info.columns || []"
|
|
||||||
:key="index"
|
|
||||||
:label="column.columnName + ':' + column.columnComment"
|
|
||||||
:value="column.columnName"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item>
|
|
||||||
<template #label>
|
|
||||||
树父编码字段
|
|
||||||
<el-tooltip content="树显示的父编码字段名, 如:parent_Id" placement="top">
|
|
||||||
<el-icon><question-filled /></el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="info.treeParentCode" placeholder="请选择">
|
|
||||||
<el-option
|
|
||||||
v-for="(column, index) in info.columns || []"
|
|
||||||
:key="index"
|
|
||||||
:label="column.columnName + ':' + column.columnComment"
|
|
||||||
:value="column.columnName"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item>
|
|
||||||
<template #label>
|
|
||||||
树名称字段
|
|
||||||
<el-tooltip content="树节点的显示名称字段名, 如:dept_name" placement="top">
|
|
||||||
<el-icon><question-filled /></el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="info.treeName" placeholder="请选择">
|
|
||||||
<el-option
|
|
||||||
v-for="(column, index) in info.columns || []"
|
|
||||||
:key="index"
|
|
||||||
:label="column.columnName + ':' + column.columnComment"
|
|
||||||
:value="column.columnName"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="info.tplCategory == 'sub'">
|
|
||||||
<h4 class="form-header">关联信息</h4>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item>
|
|
||||||
<template #label>
|
|
||||||
关联子表的表名
|
|
||||||
<el-tooltip content="关联子表的表名, 如:sys_user" placement="top">
|
|
||||||
<el-icon><question-filled /></el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="info.subTableName" placeholder="请选择" @change="subSelectChange">
|
|
||||||
<el-option
|
|
||||||
v-for="(table, index) in tables || []"
|
|
||||||
:key="index"
|
|
||||||
:label="(table.tableName || '') + ':' + (table.tableComment || '')"
|
|
||||||
:value="table.tableName || ''"
|
|
||||||
:disabled="!table.tableName"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item>
|
|
||||||
<template #label>
|
|
||||||
子表关联的外键名
|
|
||||||
<el-tooltip content="子表关联的外键名, 如:user_id" placement="top">
|
|
||||||
<el-icon><question-filled /></el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<el-select v-model="info.subTableFkName" placeholder="请选择">
|
|
||||||
<el-option
|
|
||||||
v-for="(column, index) in subColumns"
|
|
||||||
:key="index"
|
|
||||||
:label="column.columnName + ':' + column.columnComment"
|
|
||||||
:value="column.columnName"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
</el-form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import MenuAPI from "@/api/system/menu";
|
|
||||||
import { ref, computed, onMounted, watch } from 'vue';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
|
|
||||||
const subColumns = ref<Array<{ columnName: string; columnComment: string }>>([]);
|
|
||||||
const menuOptions = ref<Array<{ id: number; menuId: number; menuName: string; parent_id: number; children: Array<any> }>>([]);
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
// 定义类型接口
|
|
||||||
interface TableColumn {
|
|
||||||
columnName: string;
|
|
||||||
columnComment: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TableInfo {
|
|
||||||
tableName?: string;
|
|
||||||
tableComment?: string;
|
|
||||||
columns?: TableColumn[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface GenInfo {
|
|
||||||
tplCategory?: string;
|
|
||||||
tplWebType?: string;
|
|
||||||
packageName?: string;
|
|
||||||
moduleName?: string;
|
|
||||||
businessName?: string;
|
|
||||||
functionName?: string;
|
|
||||||
genType?: string;
|
|
||||||
parentMenuId?: number;
|
|
||||||
genPath?: string;
|
|
||||||
subTableName?: string;
|
|
||||||
subTableFkName?: string;
|
|
||||||
columns?: TableColumn[];
|
|
||||||
treeCode?: string;
|
|
||||||
treeParentCode?: string;
|
|
||||||
treeName?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
info?: GenInfo;
|
|
||||||
tables?: TableInfo[];
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: 'update:info', value: GenInfo): void;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
// 使用computed创建一个安全的info对象,确保所有属性都有默认值
|
|
||||||
const info = computed<GenInfo>({
|
|
||||||
get() {
|
|
||||||
return {
|
|
||||||
tplCategory: '',
|
|
||||||
tplWebType: 'element-plus',
|
|
||||||
packageName: '',
|
|
||||||
moduleName: '',
|
|
||||||
businessName: '',
|
|
||||||
functionName: '',
|
|
||||||
genType: '0',
|
|
||||||
parentMenuId: undefined,
|
|
||||||
genPath: '',
|
|
||||||
subTableName: '',
|
|
||||||
subTableFkName: '',
|
|
||||||
columns: [],
|
|
||||||
treeCode: '',
|
|
||||||
treeParentCode: '',
|
|
||||||
treeName: '',
|
|
||||||
...props.info
|
|
||||||
};
|
|
||||||
},
|
|
||||||
set(newValue: GenInfo) {
|
|
||||||
emit('update:info', newValue);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 表单校验
|
|
||||||
const rules = ref({
|
|
||||||
tplCategory: [{ required: true, message: "请选择生成模板", trigger: "blur" }],
|
|
||||||
packageName: [{ required: true, message: "请输入生成包路径", trigger: "blur" }],
|
|
||||||
moduleName: [{ required: true, message: "请输入生成模块名", trigger: "blur" }],
|
|
||||||
businessName: [{ required: true, message: "请输入生成业务名", trigger: "blur" }],
|
|
||||||
functionName: [{ required: true, message: "请输入生成功能名", trigger: "blur" }]
|
|
||||||
});
|
|
||||||
|
|
||||||
function subSelectChange() {
|
|
||||||
emit('update:info', {
|
|
||||||
...info.value,
|
|
||||||
subTableFkName: ""
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function tplSelectChange(value: string) {
|
|
||||||
if (value !== "sub") {
|
|
||||||
emit('update:info', {
|
|
||||||
...info.value,
|
|
||||||
subTableName: "",
|
|
||||||
subTableFkName: ""
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSubTableColumns(value?: string) {
|
|
||||||
if (!value || !props.tables) {
|
|
||||||
subColumns.value = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const item of props.tables) {
|
|
||||||
if (item.tableName === value && item.columns) {
|
|
||||||
subColumns.value = item.columns;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 恢复默认生成路径的方法
|
|
||||||
function handleResetGenPath() {
|
|
||||||
emit('update:info', {
|
|
||||||
...info.value,
|
|
||||||
genPath: '/'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 查询菜单下拉树结构 */
|
|
||||||
function getMenuTreeselect() {
|
|
||||||
MenuAPI.getMenuList().then((response: any) => {
|
|
||||||
// 简单的树形结构处理逻辑
|
|
||||||
function buildTree(data: any[], idField: string): any[] {
|
|
||||||
const result: any[] = [];
|
|
||||||
const map: Record<string, any> = {};
|
|
||||||
|
|
||||||
// 构建id映射
|
|
||||||
data.forEach(item => {
|
|
||||||
map[item[idField]] = item;
|
|
||||||
item.children = [];
|
|
||||||
// 转换属性名以匹配tree-select的期望格式
|
|
||||||
if (item.id !== undefined) {
|
|
||||||
item.menuId = item.id;
|
|
||||||
}
|
|
||||||
if (item.menu_name !== undefined) {
|
|
||||||
item.menuName = item.menu_name;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 构建树
|
|
||||||
data.forEach(item => {
|
|
||||||
if (item.parent_id === 0 || !map[item.parent_id]) {
|
|
||||||
result.push(item);
|
|
||||||
} else {
|
|
||||||
map[item.parent_id].children.push(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response && response.data && response.data.data) {
|
|
||||||
menuOptions.value = buildTree(response.data.data, "id");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
getMenuTreeselect();
|
|
||||||
// 初始化时检查tplWebType是否为空
|
|
||||||
if (!props.info?.tplWebType) {
|
|
||||||
emit('update:info', {
|
|
||||||
...info.value,
|
|
||||||
tplWebType: "element-plus"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(() => props.info?.subTableName, (val) => {
|
|
||||||
setSubTableColumns(val);
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(() => props.info?.tplWebType, (val) => {
|
|
||||||
if (val === '' || val === undefined) {
|
|
||||||
emit('update:info', {
|
|
||||||
...info.value,
|
|
||||||
tplWebType: "element-plus"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
<template>
|
|
||||||
<!-- 导入表 -->
|
|
||||||
<el-dialog v-model="visible" title="导入表" width="800px" top="5vh" append-to-body>
|
|
||||||
<el-form ref="queryRef" :model="queryFormData" :inline="true">
|
|
||||||
<el-form-item label="表名称" prop="tableName">
|
|
||||||
<el-input
|
|
||||||
v-model="queryFormData.table_name"
|
|
||||||
placeholder="请输入表名称"
|
|
||||||
clearable
|
|
||||||
style="width: 180px"
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="表描述" prop="tableComment">
|
|
||||||
<el-input
|
|
||||||
v-model="queryFormData.table_comment"
|
|
||||||
placeholder="请输入表描述"
|
|
||||||
clearable
|
|
||||||
style="width: 180px"
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<el-row>
|
|
||||||
<el-table ref="table" :data="dbTableList" height="300px" @row-click="clickRow" @selection-change="handleSelectionChange">
|
|
||||||
<template #empty>
|
|
||||||
<el-empty :image-size="80" description="暂无数据" />
|
|
||||||
</template>
|
|
||||||
<el-table-column type="selection" width="55"></el-table-column>
|
|
||||||
<el-table-column label="序号" type="index" min-width="55" align="center" fixed>
|
|
||||||
<template #default="scope">
|
|
||||||
<span>{{(queryFormData.page_no - 1) * queryFormData.page_size + scope.$index + 1}}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="database_name" label="数据库名称" :show-overflow-tooltip="true"></el-table-column>
|
|
||||||
<el-table-column prop="table_name" label="表名称" :show-overflow-tooltip="true"></el-table-column>
|
|
||||||
<el-table-column prop="table_comment" label="表描述" :show-overflow-tooltip="true"></el-table-column>
|
|
||||||
<el-table-column prop="table_type" label="表类型"></el-table-column>
|
|
||||||
</el-table>
|
|
||||||
<pagination
|
|
||||||
v-model:page="queryFormData.page_no"
|
|
||||||
v-model:limit="queryFormData.page_size"
|
|
||||||
:total="total"
|
|
||||||
@pagination="getList"
|
|
||||||
/>
|
|
||||||
</el-row>
|
|
||||||
<template #footer>
|
|
||||||
<div class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="handleImportTable">确 定</el-button>
|
|
||||||
<el-button @click="visible = false">取 消</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import GencodeAPI from "@/api/generator/gencode";
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
|
|
||||||
const total = ref(0);
|
|
||||||
const visible = ref(false);
|
|
||||||
const tables = ref<Array<string>>([]);
|
|
||||||
const dbTableList = ref<Array<any>>([]);
|
|
||||||
const queryRef = ref();
|
|
||||||
const table = ref();
|
|
||||||
|
|
||||||
const queryFormData = reactive({
|
|
||||||
page_no: 1,
|
|
||||||
page_size: 10,
|
|
||||||
table_name: undefined,
|
|
||||||
table_comment: undefined
|
|
||||||
});
|
|
||||||
|
|
||||||
const emit = defineEmits(["ok"]);
|
|
||||||
|
|
||||||
/** 查询参数列表 */
|
|
||||||
function show() {
|
|
||||||
getList();
|
|
||||||
visible.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 单击选择行 */
|
|
||||||
function clickRow(row: any) {
|
|
||||||
table.value?.toggleRowSelection(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 多选框选中数据 */
|
|
||||||
function handleSelectionChange(selection: Array<any>) {
|
|
||||||
tables.value = selection.map(item => item.table_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 查询表数据 */
|
|
||||||
function getList() {
|
|
||||||
GencodeAPI.listDbTable(queryFormData).then(res => {
|
|
||||||
console.log(res.data);
|
|
||||||
dbTableList.value = res.data.data.items;
|
|
||||||
total.value = res.data.data.total;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 搜索按钮操作 */
|
|
||||||
function handleQuery() {
|
|
||||||
queryFormData.page_no = 1;
|
|
||||||
getList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 重置按钮操作 */
|
|
||||||
function resetQuery() {
|
|
||||||
if (queryRef.value) {
|
|
||||||
queryRef.value.resetFields();
|
|
||||||
}
|
|
||||||
handleQuery();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 导入按钮操作 */
|
|
||||||
function handleImportTable() {
|
|
||||||
const tableNames = tables.value.join(",");
|
|
||||||
if (tableNames == "") {
|
|
||||||
ElMessage.error("请选择要导入的表");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 传递逗号分隔的字符串格式
|
|
||||||
GencodeAPI.importTable(tableNames.split(",")).then((res: any) => {
|
|
||||||
ElMessage.success(res.data.message);
|
|
||||||
if (res.data.code === 200) {
|
|
||||||
visible.value = false;
|
|
||||||
emit("ok");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
show,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -191,7 +191,8 @@ export default defineConfig(({ mode }: ConfigEnv) => {
|
|||||||
"element-plus/es/components/header/style/index",
|
"element-plus/es/components/header/style/index",
|
||||||
"element-plus/es/components/slider/style/index",
|
"element-plus/es/components/slider/style/index",
|
||||||
"element-plus/es/components/button-group/style/index",
|
"element-plus/es/components/button-group/style/index",
|
||||||
"element-plus/es/components/result/style/index"
|
"element-plus/es/components/result/style/index",
|
||||||
|
"element-plus/es/components/checkbox-button/style/index"
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
// 构建配置
|
// 构建配置
|
||||||
|
|||||||
Reference in New Issue
Block a user