From 057f034d4cd728c1bd0284e7c6b4a47739d5220d Mon Sep 17 00:00:00 2001 From: zhaoqingang <zhaoqg0118@163.com> Date: 星期四, 12 十二月 2024 19:57:41 +0800 Subject: [PATCH] yonghu --- app/service/bisheng.py | 2 app/models/organization_model.py | 22 ++ app/service/label.py | 13 app/service/ragflow.py | 2 app/service/service_token.py | 64 +++++ app/service/group.py | 66 +++--- app/service/user.py | 98 +++++++- app/service/difyService.py | 39 +- app/service/knowledge.py | 14 + app/api/user.py | 22 + app/api/auth.py | 31 +- app/service/auth.py | 11 alembic/versions/0366cf835bba_dialog_agent_id_add.py | 16 /dev/null | 30 -- app/models/user_model.py | 36 ++ app/api/knowledge.py | 20 + app/api/canvas.py | 3 app/service/dialog.py | 28 ++ app/models/knowledge_model.py | 22 + app/api/dialog.py | 32 ++ app/api/label.py | 4 app/models/dialog_model.py | 29 ++ app/models/token_model.py | 9 23 files changed, 431 insertions(+), 182 deletions(-) diff --git a/alembic/versions/07b5185945e0_token_table.py b/alembic/versions/0366cf835bba_dialog_agent_id_add.py similarity index 61% rename from alembic/versions/07b5185945e0_token_table.py rename to alembic/versions/0366cf835bba_dialog_agent_id_add.py index 06fbf7e..c7afc62 100644 --- a/alembic/versions/07b5185945e0_token_table.py +++ b/alembic/versions/0366cf835bba_dialog_agent_id_add.py @@ -1,8 +1,8 @@ -"""token table +"""dialog agent id add 銆� -Revision ID: 07b5185945e0 -Revises: 4b3a7c69ceac -Create Date: 2024-12-06 16:27:30.329519 +Revision ID: 0366cf835bba +Revises: +Create Date: 2024-12-12 18:50:43.195483 """ from typing import Sequence, Union @@ -12,19 +12,19 @@ # revision identifiers, used by Alembic. -revision: str = '07b5185945e0' -down_revision: Union[str, None] = '4b3a7c69ceac' +revision: str = '0366cf835bba' +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! ### - pass + op.add_column('dialogs', sa.Column('agent_id', sa.String(length=32), nullable=True)) # ### end Alembic commands ### def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### - pass + op.drop_column('dialogs', 'agent_id') # ### end Alembic commands ### diff --git a/alembic/versions/2f304d60542b_zhishiku_type_add.py b/alembic/versions/2f304d60542b_zhishiku_type_add.py deleted file mode 100644 index dc82894..0000000 --- a/alembic/versions/2f304d60542b_zhishiku_type_add.py +++ /dev/null @@ -1,32 +0,0 @@ -"""ZHISHIKU type add - -Revision ID: 2f304d60542b -Revises: d8f96e825884 -Create Date: 2024-12-10 18:04:36.301693 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision: str = '2f304d60542b' -down_revision: Union[str, None] = 'd8f96e825884' -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.add_column('knowledgebase', sa.Column('documents', sa.Integer(), nullable=True)) - op.add_column('knowledgebase', sa.Column('icon', sa.String(length=128), nullable=True)) - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.drop_column('knowledgebase', 'icon') - op.drop_column('knowledgebase', 'documents') - # ### end Alembic commands ### diff --git a/alembic/versions/3845dc998475_menu_table_add.py b/alembic/versions/3845dc998475_menu_table_add.py deleted file mode 100644 index 570d716..0000000 --- a/alembic/versions/3845dc998475_menu_table_add.py +++ /dev/null @@ -1,53 +0,0 @@ -"""menu table add - -Revision ID: 3845dc998475 -Revises: abc6bb9129ed -Create Date: 2024-12-10 14:22:03.798597 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa -from sqlalchemy.dialects import mysql - -# revision identifiers, used by Alembic. -revision: str = '3845dc998475' -down_revision: Union[str, None] = 'abc6bb9129ed' -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.create_table('menu_capacity', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('menu_id', sa.Integer(), nullable=True), - sa.Column('capacity_id', sa.String(length=36), nullable=True), - sa.Column('capacity_type', sa.Integer(), nullable=True), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('menu_id', 'capacity_id', name='menu_capacity_id_ix') - ) - op.create_index(op.f('ix_menu_capacity_id'), 'menu_capacity', ['id'], unique=False) - op.create_table('web_menu', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('title', sa.String(length=128), nullable=True), - sa.Column('dialog', sa.String(length=1000), nullable=True), - sa.Column('desc', sa.String(length=1000), nullable=True), - sa.Column('icon', sa.String(length=16), nullable=True), - sa.Column('img', sa.String(length=255), nullable=True), - sa.PrimaryKeyConstraint('id') - ) - op.create_index(op.f('ix_web_menu_id'), 'web_menu', ['id'], unique=False) - op.drop_column('knowledgebase', 'count') - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.add_column('knowledgebase', sa.Column('count', mysql.VARCHAR(length=32), nullable=True)) - op.drop_index(op.f('ix_web_menu_id'), table_name='web_menu') - op.drop_table('web_menu') - op.drop_index(op.f('ix_menu_capacity_id'), table_name='menu_capacity') - op.drop_table('menu_capacity') - # ### end Alembic commands ### diff --git a/alembic/versions/4b3a7c69ceac_init_table.py b/alembic/versions/4b3a7c69ceac_init_table.py deleted file mode 100644 index 9deba7e..0000000 --- a/alembic/versions/4b3a7c69ceac_init_table.py +++ /dev/null @@ -1,79 +0,0 @@ -"""init table - -Revision ID: 4b3a7c69ceac -Revises: -Create Date: 2024-12-06 16:12:04.760402 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa -from sqlalchemy.dialects import mysql - -# revision identifiers, used by Alembic. -revision: str = '4b3a7c69ceac' -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_user_test_id', table_name='user_test') - op.drop_index('ix_user_test_username', table_name='user_test') - op.drop_table('user_test') - op.alter_column('user', 'ragflow_id', - existing_type=mysql.VARCHAR(length=32), - nullable=True) - op.alter_column('user', 'bisheng_id', - existing_type=mysql.INTEGER(), - nullable=True) - op.alter_column('user', 'status', - existing_type=mysql.VARCHAR(length=10), - nullable=True, - existing_server_default=sa.text("'1'")) - op.alter_column('user', 'permission', - existing_type=mysql.VARCHAR(length=16), - nullable=True, - existing_server_default=sa.text("'general'")) - op.drop_column('user', 'updated_at11') - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.add_column('user', sa.Column('updated_at11', mysql.INTEGER(), autoincrement=False, nullable=True)) - op.alter_column('user', 'permission', - existing_type=mysql.VARCHAR(length=16), - nullable=False, - existing_server_default=sa.text("'general'")) - op.alter_column('user', 'status', - existing_type=mysql.VARCHAR(length=10), - nullable=False, - existing_server_default=sa.text("'1'")) - op.alter_column('user', 'bisheng_id', - existing_type=mysql.INTEGER(), - nullable=False) - op.alter_column('user', 'ragflow_id', - existing_type=mysql.VARCHAR(length=32), - nullable=False) - op.create_table('user_test', - sa.Column('id', mysql.INTEGER(), autoincrement=True, nullable=False), - sa.Column('username', mysql.VARCHAR(length=255), nullable=True), - sa.Column('hashed_password', mysql.VARCHAR(length=255), nullable=True), - sa.Column('password', mysql.VARCHAR(length=255), nullable=True), - sa.Column('compellation', mysql.VARCHAR(length=255), nullable=False), - sa.Column('phone', mysql.VARCHAR(length=255), nullable=False), - sa.Column('email', mysql.VARCHAR(length=255), nullable=False), - sa.Column('description', mysql.VARCHAR(length=255), nullable=False), - sa.Column('ragflow_id', mysql.VARCHAR(length=32), nullable=True), - sa.Column('bisheng_id', mysql.INTEGER(), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint('id'), - mysql_collate='utf8mb4_0900_ai_ci', - mysql_default_charset='utf8mb4', - mysql_engine='InnoDB' - ) - op.create_index('ix_user_test_username', 'user_test', ['username'], unique=True) - op.create_index('ix_user_test_id', 'user_test', ['id'], unique=False) - # ### end Alembic commands ### diff --git a/alembic/versions/92ece82bc5a4_menu_table_update.py b/alembic/versions/92ece82bc5a4_menu_table_update.py deleted file mode 100644 index d33aab6..0000000 --- a/alembic/versions/92ece82bc5a4_menu_table_update.py +++ /dev/null @@ -1,32 +0,0 @@ -"""menu table update - -Revision ID: 92ece82bc5a4 -Revises: 3845dc998475 -Create Date: 2024-12-10 16:00:04.324833 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa -from sqlalchemy.dialects import mysql - -# revision identifiers, used by Alembic. -revision: str = '92ece82bc5a4' -down_revision: Union[str, None] = '3845dc998475' -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.add_column('web_menu', sa.Column('describe', sa.String(length=1000), nullable=True)) - op.drop_column('web_menu', 'dialog') - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.add_column('web_menu', sa.Column('dialog', mysql.VARCHAR(length=1000), nullable=True)) - op.drop_column('web_menu', 'describe') - # ### end Alembic commands ### diff --git a/alembic/versions/abc6bb9129ed_user_app_update.py b/alembic/versions/abc6bb9129ed_user_app_update.py deleted file mode 100644 index 9ea28aa..0000000 --- a/alembic/versions/abc6bb9129ed_user_app_update.py +++ /dev/null @@ -1,44 +0,0 @@ -"""user app update - -Revision ID: abc6bb9129ed -Revises: d4c8f204280f -Create Date: 2024-12-09 16:57:06.559644 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa -from sqlalchemy.dialects import mysql - -# revision identifiers, used by Alembic. -revision: str = 'abc6bb9129ed' -down_revision: Union[str, None] = 'd4c8f204280f' -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.add_column('user_app', sa.Column('access_token', sa.String(length=1000), nullable=True)) - op.add_column('user_app', sa.Column('refresh_token', sa.String(length=1000), nullable=True)) - op.add_column('user_app', sa.Column('token_at', sa.DateTime(), nullable=True)) - op.alter_column('user_app', 'app_type', - existing_type=mysql.INTEGER(), - type_=sa.String(length=16), - existing_nullable=True) - op.drop_index('ix_user_app_username', table_name='user_app') - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.create_index('ix_user_app_username', 'user_app', ['username'], unique=True) - op.alter_column('user_app', 'app_type', - existing_type=sa.String(length=16), - type_=mysql.INTEGER(), - existing_nullable=True) - op.drop_column('user_app', 'token_at') - op.drop_column('user_app', 'refresh_token') - op.drop_column('user_app', 'access_token') - # ### end Alembic commands ### diff --git a/alembic/versions/b2f03e852b6e_agent_type_add.py b/alembic/versions/b2f03e852b6e_agent_type_add.py deleted file mode 100644 index a19c34c..0000000 --- a/alembic/versions/b2f03e852b6e_agent_type_add.py +++ /dev/null @@ -1,30 +0,0 @@ -"""agent type add - -Revision ID: b2f03e852b6e -Revises: c437168c1da4 -Create Date: 2024-12-11 17:56:12.125274 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision: str = 'b2f03e852b6e' -down_revision: Union[str, None] = 'c437168c1da4' -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.add_column('dialogs', sa.Column('dialog_type', sa.String(length=1), nullable=True)) - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.drop_column('dialogs', 'dialog_type') - # ### end Alembic commands ### diff --git a/alembic/versions/c437168c1da4_label_tabel_add.py b/alembic/versions/c437168c1da4_label_tabel_add.py deleted file mode 100644 index 91026a3..0000000 --- a/alembic/versions/c437168c1da4_label_tabel_add.py +++ /dev/null @@ -1,53 +0,0 @@ -"""label tabel add - -Revision ID: c437168c1da4 -Revises: 2f304d60542b -Create Date: 2024-12-11 15:01:45.049315 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision: str = 'c437168c1da4' -down_revision: Union[str, None] = '2f304d60542b' -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.create_table('label', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('created_at', sa.DateTime(), nullable=True), - sa.Column('updated_at', sa.DateTime(), nullable=True), - sa.Column('name', sa.String(length=128), nullable=False), - sa.Column('status', sa.String(length=10), nullable=True), - sa.Column('creator', sa.Integer(), nullable=True), - sa.Column('label_type', sa.Integer(), nullable=True), - sa.PrimaryKeyConstraint('id') - ) - op.create_index(op.f('ix_label_id'), 'label', ['id'], unique=False) - op.create_index(op.f('ix_label_name'), 'label', ['name'], unique=True) - op.create_table('label_worker', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('label_id', sa.Integer(), nullable=True), - sa.Column('object_id', sa.String(length=36), nullable=True), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('label_id', 'object_id', name='label_object_id_ix') - ) - op.create_index(op.f('ix_label_worker_id'), 'label_worker', ['id'], unique=False) - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.drop_index(op.f('ix_label_worker_id'), table_name='label_worker') - op.drop_table('label_worker') - op.drop_index(op.f('ix_label_name'), table_name='label') - op.drop_index(op.f('ix_label_id'), table_name='label') - op.drop_table('label') - # ### end Alembic commands ### diff --git a/alembic/versions/d4c8f204280f_user_app_add.py b/alembic/versions/d4c8f204280f_user_app_add.py deleted file mode 100644 index 6d78333..0000000 --- a/alembic/versions/d4c8f204280f_user_app_add.py +++ /dev/null @@ -1,67 +0,0 @@ -"""user app add - -Revision ID: d4c8f204280f -Revises: 07b5185945e0 -Create Date: 2024-12-09 15:43:14.470291 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa -from sqlalchemy.dialects import mysql - -# revision identifiers, used by Alembic. -revision: str = 'd4c8f204280f' -down_revision: Union[str, None] = '07b5185945e0' -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.create_table('user_app', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('username', sa.String(length=255), nullable=True), - sa.Column('password', sa.String(length=255), nullable=True), - sa.Column('email', sa.String(length=255), nullable=True), - sa.Column('user_id', sa.Integer(), nullable=True), - sa.Column('app_id', sa.String(length=36), nullable=True), - sa.Column('app_type', sa.Integer(), nullable=True), - sa.Column('status', sa.String(length=10), nullable=True), - sa.Column('created_at', sa.DateTime(), nullable=True), - sa.Column('updated_at', sa.DateTime(), nullable=True), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('user_id', 'app_type', name='user_app_id_ix') - ) - op.create_index(op.f('ix_user_app_id'), 'user_app', ['id'], unique=False) - op.create_index(op.f('ix_user_app_username'), 'user_app', ['username'], unique=True) - op.drop_table('dialog') - op.drop_table('flow') - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('flow', - sa.Column('id', mysql.VARCHAR(length=255), nullable=False), - sa.Column('name', mysql.VARCHAR(length=255), nullable=False), - sa.Column('status', mysql.INTEGER(), autoincrement=False, nullable=False), - sa.PrimaryKeyConstraint('id'), - mysql_collate='utf8mb4_0900_ai_ci', - mysql_default_charset='utf8mb4', - mysql_engine='InnoDB' - ) - op.create_table('dialog', - sa.Column('id', mysql.VARCHAR(length=255), nullable=False), - sa.Column('name', mysql.VARCHAR(length=255), nullable=False), - sa.Column('status', mysql.VARCHAR(length=1), nullable=False), - sa.PrimaryKeyConstraint('id'), - mysql_collate='utf8mb4_0900_ai_ci', - mysql_default_charset='utf8mb4', - mysql_engine='InnoDB' - ) - op.drop_index(op.f('ix_user_app_username'), table_name='user_app') - op.drop_index(op.f('ix_user_app_id'), table_name='user_app') - op.drop_table('user_app') - # ### end Alembic commands ### diff --git a/alembic/versions/d8f96e825884_role_type_add.py b/alembic/versions/d8f96e825884_role_type_add.py deleted file mode 100644 index 948594c..0000000 --- a/alembic/versions/d8f96e825884_role_type_add.py +++ /dev/null @@ -1,30 +0,0 @@ -"""role type add - -Revision ID: d8f96e825884 -Revises: f49ae5b5f2c8 -Create Date: 2024-12-10 17:03:38.366156 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision: str = 'd8f96e825884' -down_revision: Union[str, None] = 'f49ae5b5f2c8' -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.add_column('role', sa.Column('role_type', sa.Integer(), nullable=True)) - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.drop_column('role', 'role_type') - # ### end Alembic commands ### diff --git a/alembic/versions/f49ae5b5f2c8_group_type_add.py b/alembic/versions/f49ae5b5f2c8_group_type_add.py deleted file mode 100644 index c7ba5d9..0000000 --- a/alembic/versions/f49ae5b5f2c8_group_type_add.py +++ /dev/null @@ -1,30 +0,0 @@ -"""group type add - -Revision ID: f49ae5b5f2c8 -Revises: 92ece82bc5a4 -Create Date: 2024-12-10 16:26:34.371685 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision: str = 'f49ae5b5f2c8' -down_revision: Union[str, None] = '92ece82bc5a4' -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.add_column('group', sa.Column('group_type', sa.Integer(), nullable=True)) - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.drop_column('group', 'group_type') - # ### end Alembic commands ### diff --git a/app/api/auth.py b/app/api/auth.py index ba86a89..116d9e2 100644 --- a/app/api/auth.py +++ b/app/api/auth.py @@ -12,12 +12,13 @@ from app.models.app_token_model import AppToken from app.models.base_model import get_db from app.models.postgresql_base_model import get_pdb -from app.models.token_model import upsert_token, get_token, update_token +from app.models.token_model import upsert_token from app.models.user import UserCreate, LoginData -from app.models.user_model import UserModel +from app.models.user_model import UserModel, UserAppModel from app.service.auth import authenticate_user, create_access_token, is_valid_password, save_register_user, \ update_user_token, UserAppDao, update_user_info from app.service.bisheng import BishengService +from app.service.service_token import get_new_token, get_token, update_user_group from app.service.v2.app_register import AppRegisterDao from app.service.difyService import DifyService from app.service.ragflow import RagflowService @@ -115,7 +116,7 @@ elif app["id"] == BISHENG: service = BishengService(settings.sgb_base_url) elif app["id"] == DIFY: - continue + service = DifyService(settings.dify_base_url) else: logger.error("鏈煡娉ㄥ唽搴旂敤---") continue @@ -171,35 +172,31 @@ return Response(code=200, msg="Username already registered") app_register = AppRegisterDao(db).get_apps() register_dict = {} + token = "" for app in app_register: if app["id"] == RAGFLOW: service = RagflowService(settings.fwr_base_url) elif app["id"] == BISHENG: service = BishengService(settings.sgb_base_url) elif app["id"] == DIFY: + admin_user = db.query(UserModel).filter(UserModel.permission == "admin").first() + token = await get_new_token(db, admin_user.id, DIFY) + if not token: + logger.error("鐢ㄦ埛娉ㄥ唽鑾峰彇dftoken澶辫触锛�") + return Response(code=500, msg=f"Failed to register with app") service = DifyService(settings.dify_base_url) else: logger.error("鏈煡娉ㄥ唽搴旂敤---") continue try: name = app["id"] + str(int(time.time())) - register_info = await service.register(name, user.password) + register_info = await service.register(name, user.password, token) # print(register_info) register_dict[app['id']] = {"id":register_info.get("id"), "name": name, "email": register_info.get("email")} except Exception as e: return Response(code=500, msg=f"Failed to register with {app['id']}: {str(e)}") - - # 瀛樺偍鐢ㄦ埛淇℃伅 - # hashed_password = pwd_context.hash(user.password) - # db_user = UserModel(username=user.username, hashed_password=hashed_password, email=user.email) - # db_user.password = db_user.encrypted_password(user.password) - # for k, v in register_dict.items(): - # setattr(db_user, k.replace("app", "id"), v) - # db.add(db_user) - # db.commit() - # db.refresh(db_user) - - is_sava = await save_register_user(db, user.username, user.password, user.email, register_dict) - if not is_sava: + user_id = await save_register_user(db, user.username, user.password, user.email, register_dict) + if not user_id: return Response(code=500, msg=f"Failed to register with app") + is_update = await update_user_group(db, user_id) return Response(code=200, msg="User registered successfully",data={"username": user.username}) \ No newline at end of file diff --git a/app/api/canvas.py b/app/api/canvas.py index df214a0..f45597a 100644 --- a/app/api/canvas.py +++ b/app/api/canvas.py @@ -1,8 +1,7 @@ # coding:utf-8 from fastapi import APIRouter, Depends -from app.api import Response, get_current_user, ResponseList -from app.models import RoleParameter, GroupModel, KnowledgeModel +from app.api import Response, get_current_user from app.models.base_model import get_db from app.models.user_model import UserModel from app.service.canvas import get_canvas_list diff --git a/app/api/dialog.py b/app/api/dialog.py index cb2b1e4..44030a2 100644 --- a/app/api/dialog.py +++ b/app/api/dialog.py @@ -2,10 +2,10 @@ from fastapi import APIRouter, Depends from app.api import Response, get_current_user, ResponseList -from app.models import RoleParameter, GroupModel, KnowledgeModel +from app.models.dialog_model import dialogData, dialogDataUpdate from app.models.base_model import get_db from app.models.user_model import UserModel -from app.service.dialog import get_dialog_list +from app.service.dialog import get_dialog_list, create_dialog_service, update_dialog_status_service dialog_router = APIRouter() @@ -14,10 +14,36 @@ async def dialog_list(current: int, pageSize: int, keyword: str = "", - label: int =0, + label: int = 0, status: str ="", current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): if current and not pageSize: return ResponseList(code=400, msg="缂哄皯鍙傛暟") return Response(code=200, msg="", data=await get_dialog_list(db, current_user.id, keyword, label, status, pageSize, current)) + + +@dialog_router.post("/create", response_model=Response) +async def create_dialog_api(dialog: dialogData, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + is_create = await create_dialog_service(db, dialog.id, dialog.name, dialog.description, dialog.icon, dialog.dialogType, current_user.id) + if not is_create: + return Response(code=500, msg="role create failure", data={}) + return Response(code=200, msg="role create success", data={}) + + +@dialog_router.get("/update", response_model=Response) +async def change_dialog_data(dialog: dialogDataUpdate, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + # is_create = await create_dialog_service(db, dialog.id, dialog.name, dialog.description, dialog.icon, dialog.dialogType) + # if not is_create: + # return Response(code=500, msg="role create failure", data={}) + return Response(code=200, msg="role create success", data={}) + + +@dialog_router.put("/status", response_model=Response) +async def change_dialog_status(dialog: dialogDataUpdate, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + if dialog.status not in ["0", "1"]: + return Response(code=400, msg="invalid parameter value", data={}) + is_create = await update_dialog_status_service(db, dialog.id, dialog.status) + if not is_create: + return Response(code=500, msg="dialog update failure", data={}) + return Response(code=200, msg="dialog update success", data={}) \ No newline at end of file diff --git a/app/api/knowledge.py b/app/api/knowledge.py index 32a12f0..53c047a 100644 --- a/app/api/knowledge.py +++ b/app/api/knowledge.py @@ -2,10 +2,10 @@ from fastapi import APIRouter, Depends, Query, HTTPException from app.api import Response, get_current_user, ResponseList -from app.models import RoleParameter, GroupModel, KnowledgeModel +from app.models import klgParameter from app.models.base_model import get_db from app.models.user_model import UserModel -from app.service.knowledge import get_knowledge_list +from app.service.knowledge import get_knowledge_list, create_knowledge_service from typing import Optional knowledge_router = APIRouter() @@ -21,3 +21,19 @@ getknowledgelist = await get_knowledge_list(db, current_user.id, keyword, pageSize, current) return Response(code=200, msg="", data=getknowledgelist) + + +@knowledge_router.post("/create", response_model=Response) +async def create_knowledge_api(klg: klgParameter, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + is_create = await create_knowledge_service(db, klg.id, klg.name, klg.description, klg.icon, klg.klgType, current_user.id) + if not is_create: + return Response(code=500, msg="role create failure", data={}) + return Response(code=200, msg="role create success", data={}) + + +@knowledge_router.get("/update", response_model=Response) +async def change_knowledge_api(knowledgeId: str, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + # is_create = await update_dialog_status_service(db, dialog.id, dialog.status) + # if not is_create: + # return Response(code=500, msg="dialog update failure", data={}) + return Response(code=200, msg="dialog update success", data={}) \ No newline at end of file diff --git a/app/api/label.py b/app/api/label.py index 85744a5..52d3ff7 100644 --- a/app/api/label.py +++ b/app/api/label.py @@ -10,10 +10,10 @@ label_router = APIRouter() @label_router.get("/list", response_model=Response) -async def get_label_list(keyword="", labelType=1,current_user: UserModel = Depends(get_current_user), +async def get_label_list(keyword="", labelType=1, objectId="",current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): - return Response(code=200, msg="", data=await label_list_service(db, keyword,labelType)) + return Response(code=200, msg="", data=await label_list_service(db, keyword, labelType, objectId)) @label_router.post("/add_label", response_model=Response) diff --git a/app/api/user.py b/app/api/user.py index b442af8..506c1b4 100644 --- a/app/api/user.py +++ b/app/api/user.py @@ -4,8 +4,9 @@ from app.models.base_model import get_db from app.models.user import PageParameter, UserStatus, UserInfo, LoginData from app.models.user_model import UserModel +from app.service.auth import is_valid_password from app.service.user import get_user_list, edit_user_status, delete_user_data, create_user, edit_user_data, \ - edit_user_pwd, get_user_info, get_user_routers, get_user_menus + edit_user_pwd, get_user_info, get_user_routers, get_user_menus, get_user_permission, get_user_dept user_router = APIRouter() @@ -21,12 +22,15 @@ async def add_user(user: UserInfo, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): if not user.userName: return Response(code=400, msg="The userName cannot be empty!") + if user.pwd: + if not is_valid_password(user.pwd): + return Response(code=400, msg="The password must be at least 8 and contain both numbers and letters") db_user = db.query(UserModel).filter(UserModel.username == user.userName).first() if db_user: return Response(code=200, msg="user already created") pwd = user.pwd if not pwd: - pwd = "000000" + pwd = "basic123456" is_create = await create_user(db, user.userName, user.email, user.phone, user.loginName, pwd, user.roles, user.groups, current_user.id) if not is_create: @@ -103,4 +107,16 @@ menus = await get_user_menus(db, current_user.id) # return Response(code=200, msg="successfully", data=menus) # result = [item.to_dict() for item in agents] - return ResponseList(code=200, msg="successfully", data=menus) \ No newline at end of file + return ResponseList(code=200, msg="successfully", data=menus) + + +@user_router.get("/permission", response_model=Response) +async def user_permission(userId:int, current_user: UserModel = Depends(get_current_user),db=Depends(get_db)): + menus = await get_user_permission(db, userId) + return Response(code=200, msg="successfully", data=menus) + + +@user_router.get("/dept", response_model=Response) +async def user_dept_api(userId:int, current_user: UserModel = Depends(get_current_user),db=Depends(get_db)): + menus = await get_user_dept(db, userId) + return Response(code=200, msg="successfully", data=menus) \ No newline at end of file diff --git a/app/models/dialog_model.py b/app/models/dialog_model.py index f08ca78..1934388 100644 --- a/app/models/dialog_model.py +++ b/app/models/dialog_model.py @@ -1,5 +1,7 @@ from datetime import datetime +from typing import Optional +from pydantic import BaseModel from sqlalchemy import Column, Integer, String, BigInteger, ForeignKey, DateTime, Text, JSON from sqlalchemy.orm import relationship, backref @@ -11,14 +13,15 @@ # "order_by": 'SEQ' } id = Column(String(32), primary_key=True) # id - create_date = Column(DateTime) # 鍒涘缓鏃堕棿 - update_date = Column(DateTime) # 鏇存柊鏃堕棿 + create_date = Column(DateTime, default=datetime.now()) # 鍒涘缓鏃堕棿 + update_date = Column(DateTime, default=datetime.now(), onupdate=datetime.now()) # 鏇存柊鏃堕棿 tenant_id = Column(String(32)) # 鍒涘缓浜� name = Column(String(255)) # 鍚嶇О description = Column(Text) # 璇存槑 icon = Column(Text) # 鍥炬爣 - status = Column(String(1)) # 鐘舵�� + status = Column(String(1), default="1") # 鐘舵�� dialog_type = Column(String(1)) # # 骞冲彴 + agent_id = Column(String(32)) def get_id(self): return str(self.id) @@ -26,14 +29,15 @@ def to_json(self): return { 'id': self.id, - 'create_date': self.create_date, - 'update_date': self.update_date, + 'create_date': self.create_date.strftime('%Y-%m-%d %H:%M:%S'), + 'update_date': self.update_date.strftime('%Y-%m-%d %H:%M:%S'), 'user_id': self.tenant_id, 'name': self.name, 'description': self.description, 'icon': self.icon, 'status': self.status, 'agentType': self.dialog_type, + 'agentId': self.agent_id, } @@ -60,4 +64,17 @@ 'updated_time': self.update_time, 'update_date': datetime.fromtimestamp(self.update_time / 1000.0).strftime('%Y-%m-%d %H:%M:%S'), 'name': self.name, - } \ No newline at end of file + } + + +class dialogData(BaseModel): + id: str + name: str + description: Optional[str] = "" + dialogType: str + icon: str + + +class dialogDataUpdate(BaseModel): + id: str + status: Optional[str] = "1" \ No newline at end of file diff --git a/app/models/knowledge_model.py b/app/models/knowledge_model.py index 487e91d..afc89e5 100644 --- a/app/models/knowledge_model.py +++ b/app/models/knowledge_model.py @@ -15,15 +15,15 @@ } id = Column(String(32), primary_key=True) # id name = Column(String(128)) # 鍚嶇О - create_date = Column(DateTime) # 鍒涘缓鏃堕棿 - update_date = Column(DateTime) # 鏇存柊鏃堕棿 - avatar = Column(Text) # 鍥炬爣 + create_date = Column(DateTime, default=datetime.now()) # 鍒涘缓鏃堕棿 + update_date = Column(DateTime, default=datetime.now(), onupdate=datetime.now()) # 鏇存柊鏃堕棿 + # avatar = Column(Text) # 鍥炬爣 tenant_id = Column(String(32)) # 鍒涘缓浜篿d description = Column(Text) # 璇存槑 status = Column(String(1)) # 鐘舵�� documents = Column(Integer, default=0) # 鏂囨。 icon = Column(String(128)) # 鏂囨。 - # kld_type = Column(String(1)) # 鐭ヨ瘑搴撳钩鍙� + knowledge_type = Column(String(1)) # 鐭ヨ瘑搴撳钩鍙� def get_id(self): @@ -33,9 +33,9 @@ return { 'id': self.id, 'name': self.name, - 'create_time': self.create_date, - 'update_time': self.update_date, - 'avatar': self.avatar, + 'create_time': self.create_date.strftime('%Y-%m-%d %H:%M:%S'), + 'update_time': self.update_date.strftime('%Y-%m-%d %H:%M:%S'), + # 'avatar': self.avatar, 'user_id': self.tenant_id, 'description': self.description, 'status': self.status, @@ -46,5 +46,9 @@ return '<Knowledge name:%r url:%r>\n' % (self.name, self.id) -class RoleParameter(BaseModel): - role: str \ No newline at end of file +class klgParameter(BaseModel): + id: str + name: str + description: Optional[str] = "" + icon: str + klgType: str \ No newline at end of file diff --git a/app/models/organization_model.py b/app/models/organization_model.py index 950ba32..30f670a 100644 --- a/app/models/organization_model.py +++ b/app/models/organization_model.py @@ -71,6 +71,28 @@ return json + def to_dict(self): + json = { + 'deptId': self.id, + 'createTime': self.created_at, + 'updateTime': self.updated_at, + 'deptName': self.name, + 'address': self.address, + 'code': self.code, + 'iconCls': self.iconcls, + 'orderNum': self.seq, + 'parentId': self.get_pid(), + 'parentName': self.get_pName(), + 'leader': self.leader, + 'phone': self.phone, + 'email': self.email, + 'status': self.status, + 'roles': [self.role_json(role) for role in self.roles], + } + + return json + + def role_json(self, role): return { 'roleId': role.id, diff --git a/app/models/token_model.py b/app/models/token_model.py index febe111..aa37d12 100644 --- a/app/models/token_model.py +++ b/app/models/token_model.py @@ -5,9 +5,7 @@ from sqlalchemy.orm import Session from Log import logger -from app.config.const import RAGFLOW from app.models.base_model import Base -from app.service.auth import UserAppDao class TokenModel(Base): @@ -89,9 +87,4 @@ db.rollback() # 鍥炴粴浜嬪姟 -async def get_token(db: Session, user_id: int): - res = {i.app_type.replace("app", "token"): i.access_token for i in await UserAppDao(db).get_user_datas(user_id)} - if not res: - token = db.query(TokenModel).filter_by(user_id=user_id).first() - res = {"ragflow_token": token.ragflow_token, "bisheng_token": token.bisheng_token} - return res + diff --git a/app/models/user_model.py b/app/models/user_model.py index a1d61dd..eeaf3e6 100644 --- a/app/models/user_model.py +++ b/app/models/user_model.py @@ -102,22 +102,32 @@ # 'phoneNumber': self.phone_number } - if len(self.organizations) > 0: - json['dept'] = [organization.to_json() for organization in self.organizations] + + # json['dept'] = [organization.to_json() for organization in self.organizations] json['groups'] = [group.to_dict() for group in self.groups] - roles = [] + # if len(self.roles) > 0: - roles = [role.to_json() for role in self.roles] - organization_roles = [role.to_json() for organization in self.organizations for role in - organization.roles] - for role in organization_roles: - if role not in roles: - roles.append(role) - json['roles'] = roles + roles = {role.id: role.to_dict() for role in self.roles} + ogt_set = set() + for ogt in self.organizations: + if ogt.id in ogt_set: + continue + ogt_set.add(ogt.id) + for role in ogt.roles: + roles[role.id] = role.to_dict() + parent_ogt = ogt.parent + while parent_ogt: + if parent_ogt.id not in ogt_set: + ogt_set.add(ogt.id) + for role in ogt.roles: + roles[role.id] = role.to_dict() + parent_ogt = ogt.parent + json['roles'] = list(roles.values()) return json + def to_login_json(self): json = { @@ -210,3 +220,9 @@ "app_type": self.app_type, 'status': self.status, } + + def encrypted_password(self, password): + return cipher_suite.encrypt(password.encode("utf-8")).decode("utf-8") + + def decrypted_password(self): + return cipher_suite.decrypt(self.password).decode("utf-8") \ No newline at end of file diff --git a/app/service/auth.py b/app/service/auth.py index a0a1952..4353fcd 100644 --- a/app/service/auth.py +++ b/app/service/auth.py @@ -10,8 +10,10 @@ from Log import logger from app.config.config import settings from app.config.const import RAGFLOW, BISHENG, DIFY -from app.models import RoleModel, GroupModel +from app.models import RoleModel, GroupModel, TokenModel from app.models.user_model import UserModel, UserAppModel +# from app.service.ragflow import RagflowService +# from app.service.service_token import get_new_token from app.service.v2.app_register import AppRegisterDao SECRET_KEY = settings.secret_key @@ -90,7 +92,7 @@ db.query(UserModel).filter(UserModel.id == user_id).delete() db.commit return False - return True + return user_id async def update_user_token(db, user_id, token_dict): @@ -189,3 +191,8 @@ async def get_user_datas(self, user_id: int): return self.db.query(UserAppModel).filter_by(user_id=user_id).all() + + + + + diff --git a/app/service/bisheng.py b/app/service/bisheng.py index ff1accc..51db4f8 100644 --- a/app/service/bisheng.py +++ b/app/service/bisheng.py @@ -26,7 +26,7 @@ else: return {} - async def register(self, username: str, password: str): + async def register(self, username: str, password: str, token:str=""): public_key = await self.get_public_key_api() password = BishengCrypto(public_key, settings.PRIVATE_KEY).encrypt(password) async with httpx.AsyncClient() as client: diff --git a/app/service/dialog.py b/app/service/dialog.py index 623477a..fa678ce 100644 --- a/app/service/dialog.py +++ b/app/service/dialog.py @@ -27,8 +27,9 @@ query = query.filter(DialogModel.name.like('%{}%'.format(keyword))) if status: - print(status) + # print(status) query = query.filter(DialogModel.status == status) + query = query.order_by(DialogModel.update_date.desc()) total = query.count() if page_size: query = query.limit(page_size).offset((page_index - 1) * page_size) @@ -86,3 +87,28 @@ ConversationModel.dialog_id.__eq__(dialog_id)).order_by( ConversationModel.update_time.desc()).all() return [i.to_json() for i in session_list] + + + +async def create_dialog_service(db, dialog_id, dialog_name, description, icon, dialog_type, user_id): + try: + dialog_model = DialogModel(id=dialog_id,name=dialog_name, description=description,icon=icon, dialog_type=dialog_type, tenant_id=user_id, agent_id=dialog_id) + db.add(dialog_model) + db.commit() + db.refresh(dialog_model) + except Exception as e: + logger.error(e) + db.rollback() + return False + return True + + +async def update_dialog_status_service(db, dialog_id, status): + try: + DialogModel(id=dialog_id).update({"status":status}) + db.commit() + except Exception as e: + logger.error(e) + db.rollback() + return False + return True \ No newline at end of file diff --git a/app/service/difyService.py b/app/service/difyService.py index 7329640..c51719e 100644 --- a/app/service/difyService.py +++ b/app/service/difyService.py @@ -9,6 +9,7 @@ # from Log import logger from app.config.config import settings +# from app.service.service_token import get_admin_token from app.utils.rsa_crypto import RagflowCrypto @@ -41,9 +42,9 @@ return data async def register(self, username: str, password: str, token=None): - if not token: - token = await get_df_token() - email = f"{username}@df.com" + # if not token: + # token = await get_admin_token() + email = f"{username}@basic.com" invite_res = await self.invite_workspaces_member(token, [email], "admin") # print(invite_res) if invite_res.get("result") != "success" or not invite_res.get("invitation_results"): @@ -54,7 +55,7 @@ # print(invite_token) if not invite_token: return {} - await self.login(email, password, True, invite_token) + await self.login(username, password, True, invite_token) activate_res = await self.activate(email, username, invite_token, "", "") activate_res["email"] = email activate_res["id"] = invite_token @@ -68,12 +69,12 @@ headers={'Content-Type': 'application/json',"Authorization": f'Bearer {token}'}, json={"emails": emails, "language": "zh-Hans", "role": role} ) - print(response.text) + # print(response.text) return self._handle_response(response) - async def login(self, email: str, password: str, remember_me,invite_token:str="") -> str: + async def login(self, username: str, password: str, remember_me=True, invite_token:str="") -> str: # password = RagflowCrypto(settings.PUBLIC_KEY, settings.PRIVATE_KEY).encrypt(password) - data = {"email": email, "password": password, "remember_me": remember_me, "invite_token": invite_token, + data = {"email": f"{username}@basic.com", "password": password, "remember_me": remember_me, "invite_token": invite_token, "language": "zh-Hans"} async with httpx.AsyncClient() as client: @@ -84,7 +85,8 @@ ) if response.status_code != 200: raise Exception(f"df login failed: {response.text}") - return self._handle_response(response) + data = self._handle_response(response) + return data.get('access_token') async def email_check(self, token, email: str): async with httpx.AsyncClient() as client: @@ -98,7 +100,7 @@ # password = RagflowCrypto(settings.PUBLIC_KEY, settings.PRIVATE_KEY).encrypt(password) data = {"email": email, "name": name, "token": token, # "workspace_id": workspace_id, "interface_language": "en-US", "timezone": "Asia/Shanghai"} - print(data) + # print(data) async with httpx.AsyncClient() as client: response = await client.post( f"{self.base_url}/console/api/activate", @@ -111,7 +113,7 @@ async def invite_member_activate(self, token:str, email: str, name: str, password:str) -> str: invite_res = await self.invite_workspaces_member(token, [email], "admin") - print(invite_res) + # print(invite_res) if invite_res.get("result") != "success" or not invite_res.get("invitation_results"): # logger.error(invite_res) return {} @@ -252,10 +254,9 @@ # b = await a.email_check( # "ebd36739-0272-4b3f-95ab-0c6ac1639831", # "test05@163.com") - # b = await a.login( - # "test05@163.com", - # "zhaoqg123456", - # True, "ebd36739-0272-4b3f-95ab-0c6ac1639831") + b = await a.login( + "zhao1234567", + "zhaoqg123456") @@ -263,11 +264,11 @@ # "test05@163.com", # "test05", "ebd36739-0272-4b3f-95ab-0c6ac1639831", "", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiNzg5OWUzOGQtNzczOS00NGNmLTgyODItZmFlMGZhNDJlZDYwIiwiZXhwIjoxNzMzNzI5NjQyLCJpc3MiOiJTRUxGX0hPU1RFRCIsInN1YiI6IkNvbnNvbGUgQVBJIFBhc3Nwb3J0In0.YMvypPnrvvUIfqzcESj820nP46IsFdTpF_YPz8_Exso") - b = await a.invite_member_activate( - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMDE2NTcxNjAtZTllYi00NzVhLWIzMzYtZjlmZWJlY2I5YjczIiwiZXhwIjoxNzMzNzM0ODE0LCJpc3MiOiJTRUxGX0hPU1RFRCIsInN1YiI6IkNvbnNvbGUgQVBJIFBhc3Nwb3J0In0.khaXX3ndDe_pccEHcyTUcO2sgBCEfXCR74ZniP_b54Y", - "zhao1@df.com", - "zhao1Q", - "ZHAOQG123456") + # b = await a.invite_member_activate( + # "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMDE2NTcxNjAtZTllYi00NzVhLWIzMzYtZjlmZWJlY2I5YjczIiwiZXhwIjoxNzMzNzM0ODE0LCJpc3MiOiJTRUxGX0hPU1RFRCIsInN1YiI6IkNvbnNvbGUgQVBJIFBhc3Nwb3J0In0.khaXX3ndDe_pccEHcyTUcO2sgBCEfXCR74ZniP_b54Y", + # "zhao1@df.com", + # "zhao1Q", + # "ZHAOQG123456") print(b) import asyncio diff --git a/app/service/group.py b/app/service/group.py index b142c84..0c6eb77 100644 --- a/app/service/group.py +++ b/app/service/group.py @@ -69,39 +69,39 @@ async def save_user_to_group(db, user_id, group_id, user_list): - group_user_list = [u.id for i in - db.query(GroupModel).filter(GroupModel.id.__eq__(group_id)).all() for u in i.users] - new_users = set([i for i in user_list if i not in group_user_list]) - delete_user = [i for i in group_user_list if i not in user_list] - print(new_users) - if new_users: - - user_dict = {i.id: {"rg_id": i.ragflow_id, "email": i.email} for i in - db.query(UserModel.id, UserModel.email, UserModel.ragflow_id).filter( - UserModel.id.in_(user_list)).all()} - print(user_dict) - ragflow_service = RagflowService(settings.fwr_base_url) - token = await get_ragflow_token(db, user_id) - - try: - for old_user in group_user_list: - if old_user in delete_user: - continue - for new_user in new_users: - await ragflow_service.add_user_tenant(token, user_dict[old_user]["rg_id"], user_dict[new_user]["email"], - user_dict[new_user]["rg_id"]) - await ragflow_service.add_user_tenant(token, user_dict[new_user]["rg_id"], user_dict[old_user]["email"], - user_dict[old_user]["rg_id"]) - for user1 in new_users: - for user2 in new_users: - if user1 != user2: - print(user1, user2) - await ragflow_service.add_user_tenant(token, user_dict[user1]["rg_id"], - user_dict[user2]["email"], - user_dict[user2]["rg_id"]) - except Exception as e: - logger.error(e) - return False + # group_user_list = [u.id for i in + # db.query(GroupModel).filter(GroupModel.id.__eq__(group_id)).all() for u in i.users] + # new_users = set([i for i in user_list if i not in group_user_list]) + # delete_user = [i for i in group_user_list if i not in user_list] + # print(new_users) + # if new_users: + # + # user_dict = {i.id: {"rg_id": i.ragflow_id, "email": i.email} for i in + # db.query(UserModel.id, UserModel.email, UserModel.ragflow_id).filter( + # UserModel.id.in_(user_list)).all()} + # # print(user_dict) + # ragflow_service = RagflowService(settings.fwr_base_url) + # token = await get_ragflow_token(db, user_id) + # + # try: + # for old_user in group_user_list: + # if old_user in delete_user: + # continue + # for new_user in new_users: + # await ragflow_service.add_user_tenant(token, user_dict[old_user]["rg_id"], user_dict[new_user]["email"], + # user_dict[new_user]["rg_id"]) + # await ragflow_service.add_user_tenant(token, user_dict[new_user]["rg_id"], user_dict[old_user]["email"], + # user_dict[old_user]["rg_id"]) + # for user1 in new_users: + # for user2 in new_users: + # if user1 != user2: + # print(user1, user2) + # await ragflow_service.add_user_tenant(token, user_dict[user1]["rg_id"], + # user_dict[user2]["email"], + # user_dict[user2]["rg_id"]) + # except Exception as e: + # logger.error(e) + # return False try: group = db.query(GroupModel).filter(GroupModel.id.__eq__(group_id)).first() diff --git a/app/service/knowledge.py b/app/service/knowledge.py index b927feb..66634a6 100644 --- a/app/service/knowledge.py +++ b/app/service/knowledge.py @@ -19,3 +19,17 @@ if page_size: query = query.limit(page_size).offset((page_index - 1) * page_size) return {"total": total, "rows": [kld.to_json() for kld in query.all()]} + + +async def create_knowledge_service(db, klg_id, name, description, icon, klg_type, user_id): + try: + dialog_model = KnowledgeModel(id=klg_id,name=name, description=description,icon=icon, knowledge_type=klg_type, tenant_id=user_id) + db.add(dialog_model) + db.commit() + db.refresh(dialog_model) + except Exception as e: + logger.error(e) + db.rollback() + return False + return True + diff --git a/app/service/label.py b/app/service/label.py index 54448b5..3e52196 100644 --- a/app/service/label.py +++ b/app/service/label.py @@ -1,18 +1,19 @@ import uuid -from streamlit.time_util import adjust_years - from Log import logger from app.models.label_model import LabelModel, LabelWorkerModel from app.models.role_model import RoleModel -async def label_list_service(db, keyword: str, label_type): +async def label_list_service(db, keyword: str, label_type, object_id): query = db.query(LabelModel) if keyword: query = query.filter(LabelModel.name.like('%{}%'.format(keyword))) if label_type: query = query.filter(LabelModel.label_type==label_type) + if object_id: + label_id = [i.label_id for i in db.query(LabelWorkerModel).filter(LabelWorkerModel.object_id==object_id).all()] + query = query.filter(LabelModel.id.in_(label_id)) labels = query.order_by(LabelModel.id.desc()).all() return {"total": query.count(), "rows": [label.to_json() for label in labels]} @@ -61,4 +62,10 @@ logger.error(e) db.rollback() # return False + for label_id in delete_list: + try: + LabelWorkerModel(label_id=label_id, object_id=object_id).delete() + except Exception as e: + logger.error(e) + db.rollback() return True \ No newline at end of file diff --git a/app/service/ragflow.py b/app/service/ragflow.py index ac24e47..d45806d 100644 --- a/app/service/ragflow.py +++ b/app/service/ragflow.py @@ -36,7 +36,7 @@ else: return {} - async def register(self, username: str, password: str): + async def register(self, username: str, password: str, token:str=""): password = RagflowCrypto(settings.PUBLIC_KEY, settings.PRIVATE_KEY).encrypt(password) async with httpx.AsyncClient() as client: response = await client.post( diff --git a/app/service/service_token.py b/app/service/service_token.py index 215353b..dd6b1e3 100644 --- a/app/service/service_token.py +++ b/app/service/service_token.py @@ -1,10 +1,12 @@ from Log import logger from app.config.config import settings -from app.config.const import BISHENG, RAGFLOW -from app.models import UserModel +from app.config.const import BISHENG, RAGFLOW, DIFY +from app.models import UserModel, UserAppModel +from app.models.base_model import SessionLocal from app.models.token_model import TokenModel from app.service.auth import UserAppDao from app.service.bisheng import BishengService +from app.service.difyService import DifyService from app.service.ragflow import RagflowService @@ -28,11 +30,19 @@ return token.access_token return token.ragflow_token -async def get_ragflow_new_token(db, user_id: int, app_type): - user = db.query(UserModel).filter(UserModel.id == user_id).first() +async def get_dify_token(db, user_id: int): + + token = await UserAppDao(db).get_data_by_id(user_id, DIFY) + if not token: + return None + return token.access_token + +async def get_new_token(db, user_id: int, app_type): + # user = db.query(UserModel).filter(UserModel.id == user_id).first() + user = db.query(UserAppModel).filter(UserAppModel.user_id == user_id, UserAppModel.app_type==app_type).first() if not user: return None - if app_type == 1: + if app_type == RAGFLOW: ragflow_service = RagflowService(settings.fwr_base_url) # 鐧诲綍鍒皉agflow try: @@ -42,7 +52,7 @@ logger.error(e) # return Response(code=500, msg=f"Failed to login with Ragflow: {str(e)}") return None - elif app_type == 2: + elif app_type == BISHENG: bisheng_service = BishengService(settings.sgb_base_url) # 鐧诲綍鍒版瘯鏄� try: @@ -53,6 +63,48 @@ # return Response(code=500, msg=f"Failed to login with Ragflow: {str(e)}") return None + elif app_type == DIFY: + dify_service = DifyService(settings.dify_base_url) + # 鐧诲綍鍒版瘯鏄� + try: + dify_token = await dify_service.login(user.username, user.decrypted_password()) + return dify_token + except Exception as e: + logger.error(e) + # return Response(code=500, msg=f"Failed to login with Ragflow: {str(e)}") + return None + else: logger.error("閿欒鐨勫簲鐢ㄧ被鍨媨}".format(app_type)) + +async def get_token(db, user_id: int): + res = {i.app_type.replace("app", "token"): i.access_token for i in await UserAppDao(db).get_user_datas(user_id)} + if not res: + token = db.query(TokenModel).filter_by(user_id=user_id).first() + res = {"ragflow_token": token.ragflow_token, "bisheng_token": token.bisheng_token} + return res + + +async def update_user_group(db, user_id): + admin_user = db.query(UserModel).filter(UserModel.permission == "admin").first() + token = await get_new_token(db, admin_user.id, RAGFLOW) + # print(token) + if not token: + logger.error("娉ㄥ唽鐢ㄦ埛鑾峰彇token澶辫触锛�") + return False + user_list = db.query(UserAppModel).filter(UserAppModel.app_type==RAGFLOW).all() + user = db.query(UserAppModel).filter(UserAppModel.user_id==user_id, UserAppModel.app_type == RAGFLOW).first() + if not user: + logger.error("娉ㄥ唽鐢ㄦ埛鑾峰彇淇℃伅澶辫触锛�") + return False + ragflow_service = RagflowService(settings.fwr_base_url) + for u in user_list: + if u.id and user.id != u.id: + # print(user.id, u.id) + await ragflow_service.add_user_tenant(token,u.app_id, + user.email, + user.app_id) + await ragflow_service.add_user_tenant(token, user.app_id, + u.email, + u.app_id) \ No newline at end of file diff --git a/app/service/user.py b/app/service/user.py index 21d2869..a86047f 100644 --- a/app/service/user.py +++ b/app/service/user.py @@ -2,18 +2,19 @@ from datetime import datetime from app.api import pwd_context +from app.api.dialog import dialog_list from app.config.config import settings from app.config.const import RAGFLOW, BISHENG, DIFY -from app.models import RoleModel, GroupModel, AgentType, role_resource_table +from app.models import RoleModel, GroupModel, AgentType, role_resource_table, DialogModel from app.models.menu_model import WebMenuModel, MenuCapacityModel -from app.models.user_model import UserModel +from app.models.user_model import UserModel, UserAppModel from Log import logger from app.service.auth import UserAppDao from app.service.bisheng import BishengService from app.service.v2.app_register import AppRegisterDao from app.service.difyService import DifyService from app.service.ragflow import RagflowService -from app.service.service_token import get_ragflow_token, get_bisheng_token, get_ragflow_new_token +from app.service.service_token import get_ragflow_token, get_bisheng_token, get_new_token, get_dify_token async def get_user_list(db, page_index: int, page_size: int, keyword: str, role_key: str, user_id): @@ -21,7 +22,7 @@ # if role_key != "admin": # query.filter(UserModel.creator==user_id) if keyword: - query = query.filter(UserModel.group_name.like('%{}%'.format(keyword))) + query = query.filter(UserModel.username.like('%{}%'.format(keyword))) users = query.order_by(UserModel.id.desc()).limit(page_size).offset( (page_index - 1) * page_size).all() return {"total": query.count(), "rows": [user.to_json() for user in users]} @@ -69,19 +70,21 @@ # return False app_register = AppRegisterDao(db).get_apps() register_dict = {} + token = "" for app in app_register: if app["id"] == RAGFLOW: service = RagflowService(settings.fwr_base_url) elif app["id"] == BISHENG: service = BishengService(settings.sgb_base_url) elif app["id"] == DIFY: + token = await get_dify_token() service = DifyService(settings.dify_base_url) else: logger.error("鏈煡娉ㄥ唽搴旂敤---") continue try: name = app["id"] + str(int(time.time())) - register_info = await service.register(name, password) + register_info = await service.register(name, password, token) # print(register_info) register_dict[app['id']] = {"id": register_info.get("id"), "name": name, "email": register_info.get("email")} @@ -132,13 +135,13 @@ return True -async def edit_user_pwd(db, user_id, current_user_id, new_password="000000"): +async def edit_user_pwd(db, user_id, current_user_id, new_password="basic123456"): try: user = db.query(UserModel).filter(UserModel.id == user_id).first() pwd = user.decrypted_password() for app in AppRegisterDao(db).get_apps(): if app.get("id") == RAGFLOW: - token = await get_ragflow_new_token(db, user_id, 1) + token = await get_new_token(db, user_id, app.get("id")) ragflow_service = RagflowService(settings.fwr_base_url) await ragflow_service.set_user_password(token, pwd, new_password) elif app.get("id") == BISHENG: @@ -147,10 +150,8 @@ await bisheng_service.change_password_public(token, user.username, pwd, new_password) else: logger.error("娉ㄥ唽鏈煡搴旂敤锛歿}".format(app.get("id"))) - # hashed_password = pwd_context.hash(password) - hashed_password = user.encrypted_password(new_password) - - user.password = hashed_password + user.hashed_password = pwd_context.hash(new_password) + user.password = user.encrypted_password(new_password) db.commit() except Exception as e: logger.error(e) @@ -176,7 +177,7 @@ if parent_ogt.id not in dept_set: await role_resource(role_set, roles, permissions, parent_ogt.roles) dept_set.add(parent_ogt.id) - parent_ogt = parent_ogt.parent + parent_ogt = parent_ogt.parent if user.permission == "admin": permissions = ["*:*:*"] @@ -222,7 +223,7 @@ if parent_ogt.id not in dept_set: await role_resource(role_set, permissions, parent_ogt.roles) dept_set.add(parent_ogt.id) - parent_ogt = parent_ogt.parent + parent_ogt = parent_ogt.parent tmp_dit = {} for permission in permissions.values(): tmp_dit[permission["parentId"]] = tmp_dit.get(permission["parentId"], []) + [permission] @@ -247,8 +248,9 @@ for agent in group.agents: agent_list.append(agent.id) menu_list = db.query(WebMenuModel.id, WebMenuModel.title, WebMenuModel.describe, WebMenuModel.icon, WebMenuModel.desc, - WebMenuModel.img, MenuCapacityModel.capacity_id, MenuCapacityModel.capacity_type).outerjoin( - MenuCapacityModel, WebMenuModel.id == MenuCapacityModel.menu_id).all() + WebMenuModel.img, MenuCapacityModel.capacity_id, MenuCapacityModel.capacity_type, DialogModel.agent_id.label("agentId")).outerjoin( + MenuCapacityModel, WebMenuModel.id == MenuCapacityModel.menu_id).outerjoin( + DialogModel, MenuCapacityModel.capacity_id == DialogModel.id).filter(DialogModel.status=="1").all() for menu in menu_list: menu_dict[menu.id] = menu_dict.get(menu.id, []) + [menu] @@ -269,6 +271,70 @@ 'icon': menus[0].icon, 'img': menus[0].img, 'desc': menus[0].desc, - 'dialog': menus[0].describe + 'dialog': menus[0].describe, + 'agentId': menus[0].agentId }) return res + + +async def get_user_permission(db, user_id): + res = {} + permissions = {} + role_set = set() + dept_set = set() + agent_dict = {} + knowledge_dict = {} + user = db.query(UserModel).filter_by(id=user_id).first() + parent_id = "" + print(111111111111111) + async def role_resource(role_set, permissions, roles): + nonlocal parent_id + for role in roles: + if role.id not in role_set: + role_set.add(role.id) + + for r in role.resources: + if r.resource_type_id != "1": + if not r.resource_id: + parent_id = r.id + continue + permissions[r.id] = r.to_router_dict() + + await role_resource(role_set, permissions, user.roles) + for ogt in user.organizations: + if ogt.roles: + await role_resource(role_set, permissions, user.roles) + parent_ogt = ogt.parent + while parent_ogt: + + if parent_ogt.id not in dept_set: + await role_resource(role_set, permissions, parent_ogt.roles) + dept_set.add(parent_ogt.id) + + parent_ogt = parent_ogt.parent + + tmp_dit = {} + for permission in permissions.values(): + tmp_dit[permission["parentId"]] = tmp_dit.get(permission["parentId"], []) + [permission] + + def get_child(parent_id): + res = permissions[parent_id] + res["children"] = [get_child(i["id"]) for i in tmp_dit.get(parent_id, [])] + return res + + res["menus"] = [get_child(i["id"]) for i in tmp_dit.get(parent_id, [])] + for group in user.groups: + for klg in group.knowledges: + knowledge_dict[klg.id] = klg.to_json() + for dialog in group.dialogs: + agent_dict[dialog.id] = dialog.to_json() + res["knowledge"] = list(knowledge_dict.values()) + res["dialog"] = list(agent_dict.values()) + return res + + +async def get_user_dept(db, user_id): + res = {} + user = db.query(UserModel).filter_by(id=user_id).first() + res["rows"] = [i.to_dict() for i in user.organizations] + return res \ No newline at end of file -- Gitblit v1.8.0