15个文件已修改
4 文件已重命名
3 文件已复制
6个文件已添加
New file |
| | |
| | | """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 ### |
New file |
| | |
| | | """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 ### |
New file |
| | |
| | | """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 ### |
copy from app/service/common/__init__.py
copy to app/__init__.py
| | |
| | | if agent.agent_type == AgentType.RAGFLOW: |
| | | ragflow_service = RagflowService(base_url=settings.fwr_base_url) |
| | | try: |
| | | token = get_ragflow_token(db, current_user.id) |
| | | token = await get_ragflow_token(db, current_user.id) |
| | | result = await ragflow_service.get_chat_sessions(token, agent_id) |
| | | if not result: |
| | | result = await get_session_history(db, current_user.id, agent_id) |
| | |
| | | elif agent.agent_type == AgentType.BISHENG: |
| | | bisheng_service = BishengService(base_url=settings.sgb_base_url) |
| | | try: |
| | | token = get_bisheng_token(db, current_user.id) |
| | | token = await get_bisheng_token(db, current_user.id) |
| | | result = await bisheng_service.get_chat_sessions(token, agent_id, page, limit) |
| | | except Exception as e: |
| | | raise HTTPException(status_code=500, detail=str(e)) |
| | |
| | | if agent.agent_type == AgentType.RAGFLOW: |
| | | ragflow_service = RagflowService(base_url=settings.fwr_base_url) |
| | | try: |
| | | token = get_ragflow_token(db, current_user.id) |
| | | token = await get_ragflow_token(db, current_user.id) |
| | | result = await ragflow_service.get_session_log(token, conversation_id) |
| | | if 'session_log' in result and 'reference' in result: |
| | | combined_logs = [] |
| | |
| | | is_join = True |
| | | bisheng_service = BishengService(base_url=settings.sgb_base_url) |
| | | try: |
| | | token = get_bisheng_token(db, current_user.id) |
| | | token = await get_bisheng_token(db, current_user.id) |
| | | result = await bisheng_service.get_session_log(token, agent_id, conversation_id) |
| | | combined_logs = [] |
| | | last_question = None |
| | |
| | | from app.service.auth import authenticate_user, create_access_token, is_valid_password, save_register_user, \ |
| | | update_user_token, UserAppDao |
| | | from app.service.bisheng import BishengService |
| | | from app.service.common.app_register import AppRegisterDao |
| | | from app.service.v2.app_register import AppRegisterDao |
| | | from app.service.difyService import DifyService |
| | | from app.service.ragflow import RagflowService |
| | | from sqlalchemy.future import select |
| | |
| | | @router.get("/token", response_model=Response) |
| | | async def token_api(db: Session = Depends(get_db), current_user: UserModel = Depends(get_current_user)): |
| | | # 查询现有记录 |
| | | token = get_token(db, current_user.id) |
| | | token = await get_token(db, current_user.id) |
| | | if token is None: |
| | | return Response(code=400, msg="token not found") |
| | | return Response(code=200, msg="success", data={ |
| | | "ragflow_token": token.ragflow_token, |
| | | "bisheng_token": token.bisheng_token, |
| | | }) |
| | | return Response(code=200, msg="success", data=token) |
| | | |
| | | |
| | | @router.post("/v2/login", response_model=Response) |
| | |
| | | logger.error("未知注册应用---") |
| | | continue |
| | | try: |
| | | user_app = UserAppDao(db).get_data_by_id(user.id, app["id"]) |
| | | user_app = await UserAppDao(db).get_data_by_id(user.id, app["id"]) |
| | | if user_app: |
| | | name = user_app.username |
| | | token = await service.login(name, login_data.password) |
| | |
| | | # 创建本地token |
| | | access_token = create_access_token(data={"sub": user.username, "user_id": user.id}) |
| | | |
| | | await update_token(db, user.id, access_token, token_dict) |
| | | # await update_token(db, user.id, access_token, token_dict) |
| | | await update_user_token(db, user.id, token_dict) |
| | | result = await pdb.execute(select(AppToken).where(AppToken.id == user.id)) |
| | | db_app_token = result.scalars().first() |
| | |
| | | try: |
| | | name = app["id"] + str(int(time.time())) |
| | | register_info = await service.register(name, user.password) |
| | | print(register_info) |
| | | # 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)}") |
| | |
| | | from app.models.agent_model import AgentModel, AgentType |
| | | from app.models.base_model import get_db |
| | | from app.models.user_model import UserModel |
| | | from app.service.common.api_token import DfTokenDao |
| | | from app.service.v2.api_token import DfTokenDao |
| | | from app.service.dialog import update_session_history |
| | | from app.service.basic import BasicService |
| | | from app.service.difyService import DifyService |
| | |
| | | |
| | | if agent_type == AgentType.RAGFLOW: |
| | | ragflow_service = RagflowService(settings.fwr_base_url) |
| | | token = get_ragflow_token(db, current_user.id) |
| | | token = await get_ragflow_token(db, current_user.id) |
| | | try: |
| | | async def forward_to_ragflow(): |
| | | while True: |
| | |
| | | pass |
| | | |
| | | elif agent_type == AgentType.BISHENG: |
| | | token = get_bisheng_token(db, current_user.id) |
| | | token = await get_bisheng_token(db, current_user.id) |
| | | service_uri = f"{settings.sgb_websocket_url}/api/v1/assistant/chat/{agent_id}?t=&chat_id={chat_id}" |
| | | headers = {'cookie': f"access_token_cookie={token};"} |
| | | |
| | |
| | | from app.models.user_model import UserModel |
| | | from app.service.basic import BasicService |
| | | from app.service.bisheng import BishengService |
| | | from app.service.common.api_token import DfTokenDao |
| | | from app.service.v2.api_token import DfTokenDao |
| | | from app.service.difyService import DifyService |
| | | from app.service.ragflow import RagflowService |
| | | from app.service.service_token import get_ragflow_token, get_bisheng_token |
| | |
| | | return Response(code=400, msg=str(e)) |
| | | |
| | | if agent.agent_type == AgentType.RAGFLOW: |
| | | token = get_ragflow_token(db, current_user.id) |
| | | token = await get_ragflow_token(db, current_user.id) |
| | | ragflow_service = RagflowService(base_url=settings.fwr_base_url) |
| | | # 查询会话是否存在,不存在先创建会话 |
| | | history = await ragflow_service.get_session_history(token, chat_id) |
| | |
| | | elif agent.agent_type == AgentType.BISHENG: |
| | | bisheng_service = BishengService(base_url=settings.sgb_base_url) |
| | | try: |
| | | token = get_bisheng_token(db, current_user.id) |
| | | token = await get_bisheng_token(db, current_user.id) |
| | | result = await bisheng_service.upload(token, file.filename, file_content) |
| | | except Exception as e: |
| | | raise HTTPException(status_code=500, detail=str(e)) |
| | |
| | | ret = {"message": "Agent error", "type": "close"} |
| | | return websocket.send_json(ret) |
| | | |
| | | token = get_bisheng_token(db, current_user.id) |
| | | token = await get_bisheng_token(db, current_user.id) |
| | | service_uri = f"{settings.sgb_websocket_url}/api/v1/chat/{agent_id}?type=L1&t=&chat_id={chat_id}" |
| | | headers = {'cookie': f"access_token_cookie={token};"} |
| | | |
| | |
| | | return ResponseList(code=404, msg="Agent not found") |
| | | bisheng_service = BishengService(base_url=settings.sgb_base_url) |
| | | try: |
| | | token = get_bisheng_token(db, current_user.id) |
| | | token = await get_bisheng_token(db, current_user.id) |
| | | result = await bisheng_service.variable_list(token, agent_id) |
| | | except Exception as e: |
| | | raise HTTPException(status_code=500, detail=str(e)) |
| | |
| | | from fastapi import APIRouter, Depends |
| | | from app.api import Response, pwd_context, get_current_user |
| | | from app.api import Response, pwd_context, get_current_user, ResponseList |
| | | from app.models.public_api_model import AppRegisterModel |
| | | 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.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 |
| | | edit_user_pwd, get_user_info, get_user_routers, get_user_menus |
| | | |
| | | user_router = APIRouter() |
| | | |
| | |
| | | routers = await get_user_routers(db, current_user.id) |
| | | if not routers: |
| | | return Response(code=500, msg="user get failure", data={}) |
| | | return Response(code=200, msg="successfully", data=routers) |
| | | return Response(code=200, msg="successfully", data=routers) |
| | | |
| | | |
| | | @user_router.get("/menus", response_model=ResponseList) |
| | | async def user_menus(current_user: UserModel = Depends(get_current_user),db=Depends(get_db)): |
| | | 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) |
copy from app/service/common/__init__.py
copy to app/api/v2/__init__.py
copy from app/service/common/__init__.py
copy to app/api/v2/conversation.py
File was renamed from app/api/public_api.py |
| | |
| | | from app.config.const import IMAGE_TO_TEXT, DOCUMENT_TO_CLEANING, DOCUMENT_TO_REPORT, DIFY, BISHENG, RAGFLOW |
| | | from app.models.base_model import get_db |
| | | from app.models.public_api_model import DfToken, AppRegister |
| | | from app.service.common.api_token import DfTokenDao |
| | | from app.service.common.app_register import AppRegisterDao |
| | | from app.service.v2.api_token import DfTokenDao |
| | | from app.service.v2.app_register import AppRegisterDao |
| | | from app.service.v2.initialize_data import dialog_menu_sync |
| | | from app.task.sync_resources import sync_knowledge, sync_dialog, sync_agent, sync_llm, sync_resource |
| | | |
| | | public_api = APIRouter() |
| | |
| | | |
| | | |
| | | @public_api.get("/sync/resource", response_model=Response) |
| | | async def user_group_list(resource_type:int, db=Depends(get_db)): |
| | | async def sync_resource_data(resource_type:int, db=Depends(get_db)): |
| | | if resource_type == 1: |
| | | await sync_knowledge() |
| | | elif resource_type == 2: |
| | |
| | | else: |
| | | await sync_resource() |
| | | |
| | | return Response(code=200, msg="", data={}) |
| | | return Response(code=200, msg="", data={}) |
| | | |
| | | |
| | | @public_api.get("/sync/dialog_menu", response_model=Response) |
| | | async def sync_dialog_menu(db=Depends(get_db)): |
| | | try: |
| | | await dialog_menu_sync(db) |
| | | except Exception as e: |
| | | logger.error(e) |
| | | return Response(code=500, msg="failed", data={}) |
| | | |
| | | return Response(code=200, msg="success", data={}) |
| | |
| | | from .token_model import * |
| | | from .session_model import SessionModel |
| | | from .public_api_model import * |
| | | from .menu_model import * |
| | | |
| | | |
| | | # 获取当前时区的时间 |
| | |
| | | created_at = Column(DateTime, default=datetime.now()) |
| | | updated_at = Column(DateTime, default=datetime.now(), onupdate=datetime.now()) |
| | | creator = Column(Integer) |
| | | group_type = Column(Integer, default=1) |
| | | |
| | | |
| | | knowledges = relationship('KnowledgeModel', |
New file |
| | |
| | | from datetime import datetime |
| | | from sqlalchemy import Column, Integer, String, DateTime, Table, ForeignKey, UniqueConstraint |
| | | from app.models.base_model import Base |
| | | |
| | | |
| | | |
| | | class WebMenuModel(Base): |
| | | __tablename__ = 'web_menu' |
| | | id = Column(Integer, primary_key=True, index=True) |
| | | title = Column(String(128)) |
| | | describe = Column(String(1000)) |
| | | desc = Column(String(1000)) |
| | | icon = Column(String(16)) |
| | | img = Column(String(255)) |
| | | |
| | | |
| | | def to_dict(self): |
| | | return { |
| | | 'id': self.id, |
| | | 'title': self.title, |
| | | 'icon': self.icon, |
| | | 'img': self.img, |
| | | 'desc': self.desc, |
| | | 'dialog': self.describe |
| | | } |
| | | |
| | | def __repr__(self): |
| | | return '<Role name:%r description:%r iconCls:%r seq:%r>\n' \ |
| | | % (self.NAME, self.DESCRIPTION, self.ICONCLS, self.SEQ) |
| | | |
| | | |
| | | class MenuCapacityModel(Base): |
| | | __tablename__ = 'menu_capacity' |
| | | __table_args__ = (UniqueConstraint('menu_id', 'capacity_id', name='menu_capacity_id_ix'),) |
| | | id = Column(Integer, primary_key=True, index=True) |
| | | menu_id = Column(Integer) |
| | | capacity_id = Column(String(36)) |
| | | capacity_type = Column(Integer) |
| | | |
| | |
| | | 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): |
| | |
| | | if not isinstance(user_id, int) or user_id <= 0: |
| | | return |
| | | db_token = None |
| | | print(token) |
| | | # print(token) |
| | | try: |
| | | # 查询现有记录 |
| | | db_token = db.query(TokenModel).filter_by(user_id=user_id).first() |
| | |
| | | db.rollback() # 回滚事务 |
| | | |
| | | |
| | | def get_token(db: Session, user_id: int) -> Type[TokenModel] | None: |
| | | return db.query(TokenModel).filter_by(user_id=user_id).first() |
| | | async def get_token(db: Session, user_id: int): |
| | | # return db.query(TokenModel).filter_by(user_id=user_id).first() |
| | | |
| | | return {i.app_type.replace("app", "token"): i.access_token for i in await UserAppDao(db).get_user_datas(user_id)} |
| | |
| | | db.refresh(db_user) |
| | | user_id = db_user.id |
| | | for k, v in register_dict.items(): |
| | | UserAppDao(db).update_and_insert_token(v.get("name"), pwd, v.get("email"), user_id, str(v.get("id")), k) |
| | | await UserAppDao(db).update_and_insert_data(v.get("name"), pwd, v.get("email"), user_id, str(v.get("id")), k) |
| | | |
| | | except Exception as e: |
| | | logger.error(e) |
| | |
| | | |
| | | |
| | | async def update_user_token(db, user_id, token_dict): |
| | | |
| | | try: |
| | | for k, v in token_dict.items(): |
| | | UserAppDao(db).update_user_app_data({"user_id": user_id, "app_type": k}, |
| | | {"access_token": v, "token_at": datetime.now()}) |
| | | await UserAppDao(db).update_user_app_data({"user_id": user_id, "app_type": k}, |
| | | {"access_token": v, "token_at": datetime.now()}) |
| | | |
| | | except Exception as e: |
| | | logger.error(e) |
| | |
| | | def __init__(self, db: Session): |
| | | self.db = db |
| | | |
| | | def get_data_by_id(self, user_id: int, app_type: int) -> Type[UserAppModel] | None: |
| | | async def get_data_by_id(self, user_id: int, app_type: int) -> Type[UserAppModel] | None: |
| | | session = self.db.query(UserAppModel).filter_by(user_id=user_id, app_type=app_type).first() |
| | | return session |
| | | |
| | | def update_user_app_data(self, query: int, update_data: str): |
| | | async def update_user_app_data(self, query: dict, update_data: dict): |
| | | |
| | | logger.error("更新数据df update_app_data---------------------------") |
| | | try: |
| | |
| | | self.db.rollback() |
| | | raise Exception("更新失败!") |
| | | |
| | | def insert_user_app_data(self, username: str, password: str, email: str, user_id: int, app_id: str, app_type: int): |
| | | async def insert_user_app_data(self, username: str, password: str, email: str, user_id: int, app_id: str, |
| | | app_type: int): |
| | | logger.error("新增数据df insert_user_app_data---------------------------") |
| | | new_session = UserAppModel( |
| | | username=username, |
| | |
| | | self.db.refresh(new_session) |
| | | return new_session |
| | | |
| | | def update_and_insert_token(self, username: str, password: str, email: str, user_id: int, app_id: str, |
| | | app_type: int): |
| | | async def update_and_insert_data(self, username: str, password: str, email: str, user_id: int, app_id: str, |
| | | app_type: int): |
| | | |
| | | logger.error("更新或者添加数据 update_and_insert_token---------------------------") |
| | | token_boj = self.get_data_by_id(user_id, app_type) |
| | | token_boj = await self.get_data_by_id(user_id, app_type) |
| | | if token_boj: |
| | | self.update_user_app_data({"id": token_boj.id}, {"username": username, |
| | | "password": password, "email": email, "username": username, |
| | | "updated_at": datetime.now(), |
| | | }) |
| | | await self.update_user_app_data({"id": token_boj.id}, {"username": username, |
| | | "password": password, "email": email, |
| | | "updated_at": datetime.now(), |
| | | }) |
| | | else: |
| | | self.insert_user_app_data(username, password, email, user_id, app_id, app_type) |
| | | await self.insert_user_app_data(username, password, email, user_id, app_id, app_type) |
| | | |
| | | async def get_user_datas(self, user_id: int): |
| | | return self.db.query(UserAppModel).filter_by(user_id=user_id).all() |
| | |
| | | UserModel.id.in_(user_list)).all()} |
| | | print(user_dict) |
| | | ragflow_service = RagflowService(settings.fwr_base_url) |
| | | token = get_ragflow_token(db, user_id) |
| | | token = await get_ragflow_token(db, user_id) |
| | | |
| | | try: |
| | | for old_user in group_user_list: |
| | |
| | | from Log import logger |
| | | from app.config.config import settings |
| | | from app.config.const import BISHENG, RAGFLOW |
| | | from app.models import UserModel |
| | | from app.models.token_model import TokenModel |
| | | from app.service.auth import UserAppDao |
| | | from app.service.bisheng import BishengService |
| | | from app.service.ragflow import RagflowService |
| | | |
| | | |
| | | def get_bisheng_token(db, user_id: int): |
| | | token = db.query(TokenModel).filter(TokenModel.user_id == user_id).first() |
| | | async def get_bisheng_token(db, user_id: int): |
| | | # token = db.query(TokenModel).filter(TokenModel.user_id == user_id).first() |
| | | token = await UserAppDao.get_data_by_id(user_id, BISHENG) |
| | | if not token: |
| | | return None |
| | | return token.bisheng_token |
| | | return token.access_token |
| | | |
| | | |
| | | def get_ragflow_token(db, user_id: int): |
| | | token = db.query(TokenModel).filter(TokenModel.user_id == user_id).first() |
| | | async def get_ragflow_token(db, user_id: int): |
| | | token = await UserAppDao.get_data_by_id(user_id, RAGFLOW) |
| | | if not token: |
| | | return None |
| | | return token.ragflow_token |
| | | return token.access_token |
| | | |
| | | |
| | | async def get_ragflow_new_token(db, user_id: int, app_type): |
| | |
| | | import time |
| | | from datetime import datetime |
| | | |
| | | from app.api import pwd_context |
| | | 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.menu_model import WebMenuModel, MenuCapacityModel |
| | | from app.models.user_model import UserModel |
| | | from Log import logger |
| | | from app.service.auth import UserAppDao |
| | | from app.service.bisheng import BishengService |
| | | from app.service.common.app_register import AppRegisterDao |
| | | 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 |
| | | |
| | | |
| | | async def get_user_list(db, page_index: int, page_size: int, keyword: str, role_key:str, user_id): |
| | | query = db.query(UserModel).filter(UserModel.permission!="admin") |
| | | async def get_user_list(db, page_index: int, page_size: int, keyword: str, role_key: str, user_id): |
| | | query = db.query(UserModel).filter(UserModel.permission != "admin") |
| | | # if role_key != "admin": |
| | | # query.filter(UserModel.creator==user_id) |
| | | if keyword: |
| | | query = query.filter(UserModel.group_name.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]} |
| | | return {"total": query.count(), "rows": [user.to_json() for user in users]} |
| | | |
| | | |
| | | async def edit_user_status(db, status: str, user_id: int): |
| | | try: |
| | | db.query(UserModel).filter(UserModel.id == user_id).update({"status":status}) |
| | | db.query(UserModel).filter(UserModel.id == user_id).update({"status": status}) |
| | | db.commit() |
| | | except Exception as e: |
| | | logger.error(e) |
| | |
| | | |
| | | async def delete_user_data(db, user_id: str): |
| | | try: |
| | | db.query(UserModel).filter(UserModel.id == user_id, UserModel.permission!="admin").delete() |
| | | db.query(UserModel).filter(UserModel.id == user_id, UserModel.permission != "admin").delete() |
| | | db.commit() |
| | | except Exception as e: |
| | | logger.error(e) |
| | |
| | | |
| | | async def create_user(db, user_name, email, phone, login_name, password, roles, groups, user_id): |
| | | try: |
| | | bisheng_service = BishengService(settings.sgb_base_url) |
| | | ragflow_service = RagflowService(settings.fwr_base_url) |
| | | |
| | | # 注册到毕昇 |
| | | try: |
| | | bisheng_info = await bisheng_service.register(user_name, password) |
| | | except Exception as e: |
| | | logger.error(f"Failed to register with Bisheng: {str(e)}") |
| | | return False |
| | | |
| | | # 注册到ragflow |
| | | try: |
| | | ragflow_info = await ragflow_service.register(user_name, password) |
| | | except Exception as e: |
| | | logger.error(f"Failed to register with Ragflow: {str(e)}") |
| | | return False |
| | | # bisheng_service = BishengService(settings.sgb_base_url) |
| | | # ragflow_service = RagflowService(settings.fwr_base_url) |
| | | # |
| | | # # 注册到毕昇 |
| | | # try: |
| | | # bisheng_info = await bisheng_service.register(user_name, password) |
| | | # except Exception as e: |
| | | # logger.error(f"Failed to register with Bisheng: {str(e)}") |
| | | # return False |
| | | # |
| | | # # 注册到ragflow |
| | | # try: |
| | | # ragflow_info = await ragflow_service.register(user_name, password) |
| | | # except Exception as e: |
| | | # logger.error(f"Failed to register with Ragflow: {str(e)}") |
| | | # return False |
| | | app_register = AppRegisterDao(db).get_apps() |
| | | register_dict = {} |
| | | 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: |
| | | 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) |
| | | # print(register_info) |
| | | register_dict[app['id']] = {"id": register_info.get("id"), "name": name, |
| | | "email": register_info.get("email")} |
| | | except Exception as e: |
| | | logger.error(e) |
| | | return False |
| | | |
| | | # 存储用户信息 |
| | | hashed_password = pwd_context.hash(password) |
| | | user_model = UserModel(username=user_name, hashed_password=hashed_password, email=email,ragflow_id=ragflow_info.get("id"),bisheng_id=bisheng_info.get("user_id"), |
| | | phone=phone,login_name=login_name) |
| | | |
| | | user_model = UserModel(username=user_name, hashed_password=hashed_password, email=email, |
| | | ## ragflow_id=ragflow_info.get("id"),bisheng_id=bisheng_info.get("user_id"), |
| | | phone=phone, login_name=login_name) |
| | | pwd = user_model.encrypted_password(password) |
| | | user_model.roles = [db.get(RoleModel, roleId) for roleId in roles] |
| | | user_model.password = pwd |
| | | if groups: |
| | | user_model.groups = [db.get(GroupModel, groupId) for groupId in groups] |
| | | user_model.creator = user_id |
| | | db.add(user_model) |
| | | db.commit() |
| | | db.refresh(user_model) |
| | | u_id = user_model.id |
| | | for k, v in register_dict.items(): |
| | | await UserAppDao(db).update_and_insert_data(v.get("name"), pwd, v.get("email"), u_id, str(v.get("id")), k) |
| | | except Exception as e: |
| | | logger.error(e) |
| | | db.rollback() |
| | | # db.rollback() |
| | | return False |
| | | return True |
| | | |
| | |
| | | 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="000000"): |
| | | try: |
| | | user = db.query(UserModel).filter(UserModel.id == user_id).first() |
| | | pwd = user.decrypted_password() |
| | | for app_type in AppRegisterDao(db).get_app(): |
| | | if app_type == AgentType.RAGFLOW: |
| | | token = await get_ragflow_new_token(db, user_id, app_type) |
| | | for app in AppRegisterDao(db).get_apps(): |
| | | if app.get("id") == RAGFLOW: |
| | | token = await get_ragflow_new_token(db, user_id, 1) |
| | | ragflow_service = RagflowService(settings.fwr_base_url) |
| | | await ragflow_service.set_user_password(token, pwd, new_password) |
| | | elif app_type == AgentType.BISHENG: |
| | | token = get_bisheng_token(db, current_user_id) |
| | | elif app.get("id") == BISHENG: |
| | | token = await get_bisheng_token(db, current_user_id) |
| | | bisheng_service = BishengService(settings.sgb_base_url) |
| | | await bisheng_service.change_password_public(token, user.username, pwd, new_password) |
| | | else: |
| | | logger.error("注册未知应用:{}".format(app_type)) |
| | | logger.error("注册未知应用:{}".format(app.get("id"))) |
| | | # hashed_password = pwd_context.hash(password) |
| | | hashed_password = user.encrypted_password(new_password) |
| | | |
| | |
| | | if user.permission == "admin": |
| | | permissions = ["*:*:*"] |
| | | |
| | | return {"permissions": list(permissions), "dept": dept , "roles": roles, "user": user.to_dict()} |
| | | return {"permissions": list(permissions), "dept": dept, "roles": roles, "user": user.to_dict()} |
| | | |
| | | |
| | | async def role_resource(role_set, role_list, permissions, roles): |
| | |
| | | dept_set = set() |
| | | user = db.query(UserModel).filter_by(id=user_id).first() |
| | | parent_id = "" |
| | | |
| | | async def role_resource(role_set, permissions, roles): |
| | | nonlocal parent_id |
| | | for role in roles: |
| | |
| | | parent_ogt = parent_ogt.parent |
| | | tmp_dit = {} |
| | | for permission in permissions.values(): |
| | | tmp_dit[permission["parentId"]] = tmp_dit.get(permission["parentId"], []) +[permission] |
| | | 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 |
| | | |
| | | print(parent_id) |
| | | print(tmp_dit) |
| | | return {"routers": [get_child(i["id"]) for i in tmp_dit.get(parent_id, [])]} |
| | | |
| | | |
| | | async def get_user_menus(db, user_id): |
| | | dialog_list = [] |
| | | agent_list = [] |
| | | menu_dict = {} |
| | | res = [] |
| | | user = db.query(UserModel).filter_by(id=user_id).first() |
| | | for group in user.groups: |
| | | for dialog in group.dialogs: |
| | | dialog_list.append(dialog.id) |
| | | 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() |
| | | |
| | | for menu in menu_list: |
| | | menu_dict[menu.id] = menu_dict.get(menu.id, []) + [menu] |
| | | # print(dialog_list) |
| | | for menus in menu_dict.values(): |
| | | |
| | | for m in menus: |
| | | if user.permission == "admin": |
| | | continue |
| | | elif not m.capacity_type or m.capacity_type == 1 and m.capacity_id not in dialog_list: |
| | | break |
| | | elif not m.capacity_type or m.capacity_type == 2 and m.capacity_id not in agent_list: |
| | | break |
| | | else: |
| | | res.append({ |
| | | 'id': menus[0].id, |
| | | 'title': menus[0].title, |
| | | 'icon': menus[0].icon, |
| | | 'img': menus[0].img, |
| | | 'desc': menus[0].desc, |
| | | 'dialog': menus[0].describe |
| | | }) |
| | | return res |
New file |
| | |
| | | import json |
| | | |
| | | from Log import logger |
| | | from app.models import MenuCapacityModel, WebMenuModel, GroupModel |
| | | |
| | | |
| | | async def dialog_menu_sync(db): |
| | | menu_list = [] |
| | | with open("env_conf/menu_conf.json", 'r', encoding='utf-8') as file: |
| | | # 加载JSON数据 |
| | | data = json.load(file) |
| | | menu_list = data.get("data", []) |
| | | |
| | | db.query(WebMenuModel).delete() |
| | | db.query(MenuCapacityModel).delete() |
| | | db.commit() |
| | | |
| | | for menu in menu_list: |
| | | # print(menu) |
| | | agent = menu.pop("agent", []) |
| | | for i in agent: |
| | | capacity = MenuCapacityModel(menu_id=menu["id"], capacity_id=i, capacity_type=2) |
| | | db.add(capacity) |
| | | dialog = menu.pop("dialog", []) |
| | | for i in dialog: |
| | | capacity = MenuCapacityModel(menu_id=menu["id"], capacity_id=i, capacity_type=1) |
| | | db.add(capacity) |
| | | menu_obj = WebMenuModel(**menu) |
| | | db.add(menu_obj) |
| | | db.commit() |
| | | |
| | | |
| | | async def default_group_sync(db): |
| | | group = db.query(GroupModel).filter_by(group_type=2).first() |
| | | if not group: |
| | | logger.error("未初始化") |
| | |
| | | from typing import Dict, List, Tuple |
| | | |
| | | from sqlalchemy import create_engine, Column, String, Integer |
| | | from sqlalchemy.dialects.postgresql import array |
| | | from sqlalchemy.exc import IntegrityError |
| | | from sqlalchemy.orm import sessionmaker |
| | | |
| | | from app.config.config import settings |
| | | from app.models.agent_model import AgentModel |
| | | from app.models.base_model import SessionLocal, Base |
| | | from app.service.v2.initialize_data import dialog_menu_sync |
| | | |
| | | # 创建数据库引擎和会话工厂 |
| | | engine_bisheng = create_engine(settings.sgb_db_url) |
| | |
| | | print("Agents synchronized successfully") |
| | | except Exception as e: |
| | | print(f"Failed to sync agents: {str(e)}") |
| | | |
| | | |
| | | async def sync_web_menu(): |
| | | db = SessionLocal() |
| | | await dialog_menu_sync(db) |
| | | |
| | | |
| | | async def sync_default_group(): |
| | | db = SessionLocal() |
| | | await dialog_menu_sync(db) |
New file |
| | |
| | | { |
| | | "data": [ |
| | | { |
| | | "id": 10, |
| | | "title": "报告生成", |
| | | "icon": "2", |
| | | "img": "/src/assets/index/2.png", |
| | | "desc": "基于您创建的报告格式和知识库中的文档内容,快速生成定制报告,并支持一键下载。", |
| | | "describe": "基于您创建的报告格式和知识库中的文档内容,快速生成定制报告,并支持一键下载。", |
| | | "agent" : [], |
| | | "dialog": ["1"] |
| | | }, |
| | | { |
| | | "id": 1, |
| | | "title": "报表合并", |
| | | "icon": "6", |
| | | "img": "/src/assets/index/6.png", |
| | | "desc": "基于您上传的报表进行合并,助您快速完成报表整合与分析", |
| | | "describe": "基于您上传的报表进行合并,助您快速完成报表整合与分析", |
| | | "agent" : [], |
| | | "dialog": ["2"] |
| | | }, |
| | | { |
| | | "id": 2, |
| | | "title": "知识问答", |
| | | "icon": "5", |
| | | "img": "/src/assets/index/5.png", |
| | | "desc": "遍历已创建的文档知识库,生成完整和准确的答案,同时显示来源文档供您参考", |
| | | "describe": "垂域知识的问答助手,针对你的提问,我们将遍历已创建的文档知识库,生成完整和准确的答案,同时显示来源文档供您参考。", |
| | | "agent" : [], |
| | | "dialog": [] |
| | | }, |
| | | { |
| | | "id": 3, |
| | | "title": "文档智能", |
| | | "icon": "7", |
| | | "img": "/src/assets/index/7.png", |
| | | "desc": "个人知识库的问答助手,基于您上传的文档进行问答,支持多文档", |
| | | "describe": "个人知识库的问答助手,基于您上传的文档进行问答,支持多文档,大小在30M以内。", |
| | | "agent" : [], |
| | | "dialog": ["3"] |
| | | }, |
| | | { |
| | | "id": 4, |
| | | "title": "智能问答", |
| | | "icon": "1", |
| | | "img": "/src/assets/index/1.png", |
| | | "desc": "能够理解和学习人类的语言,具备多轮对话的能力", |
| | | "describe": "我可以理解和学习人类的语言,具备多轮对话的能力,现在和我开始交流吧~", |
| | | "agent" : [], |
| | | "dialog": [] |
| | | }, |
| | | { |
| | | "id": 5, |
| | | "title": "智能数据", |
| | | "icon": "8", |
| | | "img": "/src/assets/index/8.png", |
| | | "desc": "您可以上传文档或添加数据库地址,小数可针对你文档的数据进行分析,并生成指定的图表", |
| | | "describe": "您可以上传文档或添加数据库地址,小数可针对你文档的数据进行分析,并生成指定的图表", |
| | | "agent" : ["3", "4"], |
| | | "dialog": [] |
| | | }, |
| | | { |
| | | "id": 6, |
| | | "title": "小数绘图", |
| | | "icon": "7", |
| | | "img": "/src/assets/index/7.png", |
| | | "desc": "基于您上传的图片,生成对应的文字描述并基于图片内容实现问答。", |
| | | "describe": "基于您上传的图片,生成对应的文字描述并基于图片内容实现问答。", |
| | | "agent" : ["3"], |
| | | "dialog": [] |
| | | }, |
| | | { |
| | | "id": 7, |
| | | "title": "文档出卷", |
| | | "icon": "6", |
| | | "img": "/src/assets/index/6.png", |
| | | "desc": "您可以上传文档,小数能针对单文档或多个文档内容自动出题,高效便捷的帮助你建立私人题库。", |
| | | "describe": "您可以上传文档,小数能针对单文档或多个文档内容自动出题,高效便捷的帮助你建立私人题库。", |
| | | "agent" : [], |
| | | "dialog": [] |
| | | }, |
| | | { |
| | | "id": 8, |
| | | "title": "出题组卷", |
| | | "icon": "6", |
| | | "img": "/src/assets/index/6.png", |
| | | "desc": "您可以上传文档,小数能针对单文档或多个文档内容自动出题,高效便捷的帮助你建立私人题库。", |
| | | "describe": "您可以上传文档,小数能针对单文档或多个文档内容自动出题,高效便捷的帮助你建立私人题库。", |
| | | "agent" : ["4"], |
| | | "dialog": [] |
| | | }, |
| | | { |
| | | "id": 9, |
| | | "title": "文档报告", |
| | | "icon": "2", |
| | | "img": "/src/assets/index/2.png", |
| | | "desc": "基于您创建的报告格式和上传的文档内容,快速生成定制报告,并支持一键下载。", |
| | | "describe": "基于您创建的报告格式和上传的文档内容,快速生成定制报告,并支持一键下载。", |
| | | "agent" : [], |
| | | "dialog": [] |
| | | } |
| | | ] |
| | | } |
| | |
| | | from app.api.knowledge import knowledge_router |
| | | from app.api.llm import llm_router |
| | | from app.api.organization import dept_router |
| | | from app.api.public_api import public_api |
| | | from app.api.v2.public_api import public_api |
| | | from app.api.report import router as report_router |
| | | from app.api.resource import menu_router |
| | | # from app.api.sync_data import sync_router |
| | | from app.api.user import user_router |
| | | from app.api.group import group_router |
| | | from app.api.role import role_router |
| | | from app.models.base_model import init_db |
| | | from app.task.fetch_agent import sync_agents, initialize_agents |
| | | from app.task.sync_resources import sync_resource |
| | | from app.task.fetch_agent import sync_agents, initialize_agents, sync_web_menu |
| | | |
| | | |
| | | # 使用 Lifespan 事件处理程序 |
| | |
| | | initialize_agents() |
| | | # 在应用启动时同步代理 |
| | | sync_agents() |
| | | await sync_default_group() |
| | | await sync_web_menu() |
| | | yield |
| | | # 在应用关闭时执行清理操作(如果需要) |
| | | pass |