From 2669d0e0a93e06983dade724146bd0e1b6da6ba7 Mon Sep 17 00:00:00 2001 From: zhaoqingang <zhaoqg0118@163.com> Date: 星期二, 12 十一月 2024 18:42:05 +0800 Subject: [PATCH] 增加接口 --- app/api/role.py | 18 app/models/agent_model.py | 19 app/models/organization_model.py | 59 +++- .gitignore | 1 app/models/resource_model.py | 19 + app/service/organization.py | 89 ++++++ app/Log/log.log | 53 ++++ app/service/ragflow.py | 2 app/service/user.py | 111 ++++++++ app/api/group.py | 2 app/api/user.py | 69 +++++ app/service/resource.py | 29 ++ app/api/auth.py | 1 app/models/user.py | 19 + app/api/resource.py | 37 ++ app/models/role_model.py | 4 app/models/user_model.py | 29 +- app/api/organization.py | 68 +++++ app/models/knowledge_model.py | 32 - app/Log/__init__.py | 4 main.py | 6 app/models/group_model.py | 20 app/models/dialog_model.py | 32 - 23 files changed, 604 insertions(+), 119 deletions(-) diff --git a/.gitignore b/.gitignore index cba8701..52d2d3f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ .vscode .ipynb_checkpoints .pytest +*.log diff --git a/app/Log/__init__.py b/app/Log/__init__.py index ebc086b..2a2c7cb 100644 --- a/app/Log/__init__.py +++ b/app/Log/__init__.py @@ -5,9 +5,9 @@ logger = logging.getLogger() logger.setLevel(logging.INFO) # ch = logging.StreamHandler() - fh = logging.handlers.RotatingFileHandler("app/Log/log.log",mode="a",maxBytes = 100*1024, backupCount = 10) + fh = logging.handlers.RotatingFileHandler("app/Log/log.log",mode="a",maxBytes = 100*1024, backupCount = 10, encoding='utf-8') formatter = logging.Formatter( - "%(asctime)s - %(module)s - %(funcName)s - line:%(lineno)d - %(levelname)s - %(message)s" + "%(asctime)s - %(module)s - %(funcName)s - line:%(lineno)d - %(levelname)s -: %(message)s" ) fh.setFormatter(formatter) logger.addHandler(fh) # 灏嗘棩蹇楄緭鍑鸿嚦鏂囦欢 diff --git a/app/Log/log.log b/app/Log/log.log index 09ff359..a12c025 100644 --- a/app/Log/log.log +++ b/app/Log/log.log @@ -1 +1,54 @@ 2024-11-11 16:33:10,255 - user - get_user_list - line:5 - ERROR - ffffffff +2024-11-12 09:39:26,980 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: GET http://192.168.20.119:13001/api/v1/user/public_key "HTTP/1.1 200 OK" +2024-11-12 09:39:27,541 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:13001/api/v1/user/regist "HTTP/1.1 201 Created" +2024-11-12 09:39:27,544 - user - create_user - line:61 - ERROR -: Failed to register with Ragflow: RagflowService.register() takes 3 positional arguments but 4 were given +2024-11-12 09:40:40,106 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: GET http://192.168.20.119:13001/api/v1/user/public_key "HTTP/1.1 200 OK" +2024-11-12 09:40:40,236 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:13001/api/v1/user/regist "HTTP/1.1 200 OK" +2024-11-12 09:40:40,237 - user - create_user - line:54 - ERROR -: Failed to register with Bisheng: Failed to fetch data from Bisheng API: {"status_code":500,"status_message":"??????????"} +2024-11-12 09:42:02,264 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: GET http://192.168.20.119:13001/api/v1/user/public_key "HTTP/1.1 200 OK" +2024-11-12 09:42:02,660 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:13001/api/v1/user/regist "HTTP/1.1 201 Created" +2024-11-12 09:42:04,209 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:11080/v1/user/register "HTTP/1.1 200 OK" +2024-11-12 11:45:21,621 - organization - create_dept - line:30 - ERROR -: 'orderNum' is an invalid keyword argument for OrganizationModel +2024-11-12 11:47:09,151 - organization - create_dept - line:30 - ERROR -: 'OrganizationModel' object has no attribute 'NAME' +2024-11-12 11:57:15,151 - organization - create_dept - line:30 - ERROR -: Can't flush None value found in collection OrganizationModel.groups +2024-11-12 15:59:58,270 - organization - delete_organization_info - line:87 - ERROR -: (pymysql.err.IntegrityError) (1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`rag_basic`.`organization_group`, CONSTRAINT `organization_group_ibfk_2` FOREIGN KEY (`organization_id`) REFERENCES `organization` (`id`))') +[SQL: DELETE FROM organization WHERE organization.id = %(id_1)s] +[parameters: {'id_1': 'e12a1067-cda5-4045-8479-a02c89ab9147'}] +(Background on this error at: https://sqlalche.me/e/20/gkpj) +2024-11-12 16:02:08,772 - organization - delete_organization_info - line:87 - ERROR -: (pymysql.err.IntegrityError) (1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`rag_basic`.`organization_role`, CONSTRAINT `organization_role_ibfk_2` FOREIGN KEY (`organization_id`) REFERENCES `organization` (`id`))') +[SQL: DELETE FROM organization WHERE organization.id = %(id_1)s] +[parameters: {'id_1': 'e12a1067-cda5-4045-8479-a02c89ab9147'}] +(Background on this error at: https://sqlalche.me/e/20/gkpj) +2024-11-12 16:05:07,805 - organization - delete_organization_info - line:87 - ERROR -: (pymysql.err.IntegrityError) (1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`rag_basic`.`organization_role`, CONSTRAINT `organization_role_ibfk_2` FOREIGN KEY (`organization_id`) REFERENCES `organization` (`id`))') +[SQL: DELETE FROM organization WHERE organization.id = %(id_1)s] +[parameters: {'id_1': 'e12a1067-cda5-4045-8479-a02c89ab9147'}] +(Background on this error at: https://sqlalche.me/e/20/gkpj) +2024-11-12 16:17:25,385 - organization - delete_organization_info - line:87 - ERROR -: (pymysql.err.IntegrityError) (1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`rag_basic`.`organization_role`, CONSTRAINT `organization_role_ibfk_2` FOREIGN KEY (`organization_id`) REFERENCES `organization` (`id`))') +[SQL: DELETE FROM organization WHERE organization.id = %(id_1)s] +[parameters: {'id_1': 'e12a1067-cda5-4045-8479-a02c89ab9147'}] +(Background on this error at: https://sqlalche.me/e/20/gkpj) +2024-11-12 18:04:30,742 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: GET http://192.168.20.119:13001/api/v1/user/public_key "HTTP/1.1 200 OK" +2024-11-12 18:04:31,217 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:13001/api/v1/user/login "HTTP/1.1 201 Created" +2024-11-12 18:04:31,679 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:11080/v1/user/login "HTTP/1.1 200 OK" +2024-11-12 18:05:55,757 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: GET http://192.168.20.119:13001/api/v1/user/public_key "HTTP/1.1 200 OK" +2024-11-12 18:05:56,206 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:13001/api/v1/user/login "HTTP/1.1 201 Created" +2024-11-12 18:05:56,684 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:11080/v1/user/login "HTTP/1.1 200 OK" +2024-11-12 18:09:19,985 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: GET http://192.168.20.119:13001/api/v1/user/public_key "HTTP/1.1 200 OK" +2024-11-12 18:09:20,395 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:13001/api/v1/user/regist "HTTP/1.1 201 Created" +2024-11-12 18:09:22,252 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:11080/v1/user/register "HTTP/1.1 200 OK" +2024-11-12 18:13:37,826 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: GET http://192.168.20.119:13001/api/v1/user/public_key "HTTP/1.1 200 OK" +2024-11-12 18:13:38,274 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:13001/api/v1/user/login "HTTP/1.1 201 Created" +2024-11-12 18:13:38,830 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:11080/v1/user/login "HTTP/1.1 200 OK" +2024-11-12 18:14:27,990 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: GET http://192.168.20.119:13001/api/v1/user/public_key "HTTP/1.1 200 OK" +2024-11-12 18:14:28,054 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:13001/api/v1/user/login "HTTP/1.1 201 Created" +2024-11-12 18:15:48,707 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: GET http://192.168.20.119:13001/api/v1/user/public_key "HTTP/1.1 200 OK" +2024-11-12 18:15:48,785 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:13001/api/v1/user/login "HTTP/1.1 201 Created" +2024-11-12 18:16:33,452 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: GET http://192.168.20.119:13001/api/v1/user/public_key "HTTP/1.1 200 OK" +2024-11-12 18:16:33,520 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:13001/api/v1/user/regist "HTTP/1.1 200 OK" +2024-11-12 18:16:33,521 - user - create_user - line:54 - ERROR -: Failed to register with Bisheng: Failed to fetch data from Bisheng API: {"status_code":500,"status_message":"??????????"} +2024-11-12 18:19:41,638 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: GET http://192.168.20.119:13001/api/v1/user/public_key "HTTP/1.1 200 OK" +2024-11-12 18:19:42,088 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:13001/api/v1/user/regist "HTTP/1.1 201 Created" +2024-11-12 18:19:43,242 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:11080/v1/user/register "HTTP/1.1 200 OK" +2024-11-12 18:19:56,167 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: GET http://192.168.20.119:13001/api/v1/user/public_key "HTTP/1.1 200 OK" +2024-11-12 18:19:56,420 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:13001/api/v1/user/login "HTTP/1.1 201 Created" +2024-11-12 18:19:56,815 - _client - _send_single_request - line:1786 - INFO -: HTTP Request: POST http://192.168.20.119:11080/v1/user/login "HTTP/1.1 200 OK" diff --git a/app/api/auth.py b/app/api/auth.py index 860fca7..0011ee9 100644 --- a/app/api/auth.py +++ b/app/api/auth.py @@ -77,6 +77,7 @@ "token_type": "bearer", "username": user.username, "nickname": "", + "user": user.to_json() }) diff --git a/app/api/group.py b/app/api/group.py index 4d0826e..e931fc3 100644 --- a/app/api/group.py +++ b/app/api/group.py @@ -1,5 +1,5 @@ from fastapi import APIRouter, Depends -from win32ctypes.pywin32.pywintypes import datetime +from datetime import datetime from app.api import Response, get_current_user from app.models.base_model import get_db diff --git a/app/api/organization.py b/app/api/organization.py index e69de29..3589c07 100644 --- a/app/api/organization.py +++ b/app/api/organization.py @@ -0,0 +1,68 @@ +from fastapi import APIRouter, Depends +from app.api import Response, pwd_context, get_current_user +from app.models import DeptList, DeptInfo, DeptParent +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.organization import get_organization_list, create_dept, edit_dept_data, edit_dept_parent, \ + get_organization_info, delete_organization_info + +dept_router = APIRouter() + + +@dept_router.get("/list", response_model=Response) +async def organization_list(paras: DeptList,current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + return Response(code=200, msg="", data=await get_organization_list(db, paras.deptName)) + + +@dept_router.post("/add_dept", response_model=Response) +async def add_dept(dept: DeptInfo, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + if not dept.deptName: + return Response(code=400, msg="The deptName cannot be empty!") + if dept.status not in ["0", "1"]: + return Response(code=400, msg="The status cannot be {}!".format(dept.status)) + is_create = await create_dept(db, dept.deptName, dept.leader, dept.phone, dept.address, dept.status, dept.orderNum, dept.roles, dept.groups, dept.parentId) + if not is_create: + return Response(code=500, msg="dept create failure", data={}) + return Response(code=200, msg="dept create successfully", data={}) + + +@dept_router.put("/edit_dept", response_model=Response) +async def edit_dept(dept: DeptInfo, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + if not dept.deptName: + return Response(code=400, msg="The deptName cannot be empty!") + if dept.status not in ["0", "1"]: + return Response(code=400, msg="The status cannot be {}!".format(dept.status)) + is_create = await edit_dept_data(db, dept.deptId, dept.deptName, dept.leader, dept.phone, dept.address, dept.status, dept.orderNum, dept.roles, dept.groups, dept.parentId) + if not is_create: + return Response(code=500, msg="dept edit failure", data={}) + return Response(code=200, msg="dept edit successfully", data={}) + +@dept_router.put("/dept_parent", response_model=Response) +async def dept_parent(dept: DeptParent, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + is_create = await edit_dept_parent(db, dept.deptId, dept.parentId, dept.orderNum) + if not is_create: + return Response(code=500, msg="dept edit failure", data={}) + return Response(code=200, msg="dept edit successfully", data={}) + + +@dept_router.get("/{deptId}", response_model=Response) +async def dept_info(deptId, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + + return Response(code=200, msg="", data=await get_organization_info(db, deptId)) + + +@dept_router.delete("/{deptId}", response_model=Response) +async def delete_dept(deptId, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + is_edit = await delete_organization_info(db, deptId) + if not is_edit: + return Response(code=500, msg="dept delete failure", data={}) + return Response(code=200, msg="dept delete successfully", data={}) + + +@dept_router.delete("/{deptId}", response_model=Response) +async def delete_dept(deptId, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + is_edit = await delete_organization_info(db, deptId) + if not is_edit: + return Response(code=500, msg="dept delete failure", data={}) + return Response(code=200, msg="dept delete successfully", data={}) diff --git a/app/api/resource.py b/app/api/resource.py new file mode 100644 index 0000000..c3abb75 --- /dev/null +++ b/app/api/resource.py @@ -0,0 +1,37 @@ +from fastapi import APIRouter, Depends +from app.api import Response, pwd_context, get_current_user +from app.models.base_model import get_db +from app.models.user_model import UserModel +from app.service.resource import get_resource_tree, get_resource_info, delete_resource_info + +menu_router = APIRouter() + + +@menu_router.get("/tree_select", response_model=Response) +async def resource_tree_select(current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + return Response(code=200, msg="", data=await get_resource_tree(db)) + +@menu_router.get("/{menuId}", response_model=Response) +async def resource_info(menuId, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + + return Response(code=200, msg="", data=await get_resource_info(db, menuId)) + + +@menu_router.delete("/{menuId}", response_model=Response) +async def delete_resource(menuId, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + is_edit = await delete_resource_info(db, menuId) + if not is_edit: + return Response(code=500, msg="menu delete failure", data={}) + return Response(code=200, msg="menu delete successfully", data={}) + + +@menu_router.post("/add_menu", response_model=Response) +async def add_dept(dept: DeptInfo, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + if not dept.deptName: + return Response(code=400, msg="The deptName cannot be empty!") + if dept.status not in ["0", "1"]: + return Response(code=400, msg="The status cannot be {}!".format(dept.status)) + is_create = await create_dept(db, dept.deptName, dept.leader, dept.phone, dept.address, dept.status, dept.orderNum, dept.roles, dept.groups, dept.parentId) + if not is_create: + return Response(code=500, msg="dept create failure", data={}) + return Response(code=200, msg="dept create successfully", data={}) diff --git a/app/api/role.py b/app/api/role.py index dfcc7bb..1d54a6f 100644 --- a/app/api/role.py +++ b/app/api/role.py @@ -25,7 +25,7 @@ return Response(code=200, msg="role already created") is_create = await create_role(db, role.roleName, role.remark, current_user.id) if not is_create: - return Response(code=200, msg="role create failure", data={}) + return Response(code=500, msg="role create failure", data={}) return Response(code=200, msg="role create successfully", data={"roleName": role.roleName}) @role_router.delete("/delete_role/{role_id}", response_model=Response) @@ -35,7 +35,7 @@ return Response(code=200, msg="role does not exist") is_edit = await delete_role_data(db, role_id) if not is_edit: - return Response(code=200, msg="role delete failure", data={}) + return Response(code=500, msg="role delete failure", data={}) return Response(code=200, msg="role delete successfully", data={}) @@ -48,19 +48,21 @@ return Response(code=200, msg="role does not exist") is_edit = await edit_role_status(db, role.status,role.role_id) if not is_edit: - return Response(code=200, msg="role status edit failure", data={}) + return Response(code=500, msg="role status edit failure", data={}) return Response(code=200, msg="role status edit successfully", data={}) @role_router.put("/edit_role", response_model=Response) async def edit_role_data(role: RoleEdit, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + if not role.roleName: + return Response(code=400, msg="The roleName cannot be empty!") db_role = db.query(RoleModel).filter(RoleModel.id == role.role_id).first() if not db_role: return Response(code=200, msg="role does not exist") - if role.roleName: - db_role = db.query(RoleModel).filter(RoleModel.name == role.roleName).first() - if db_role: - return Response(code=200, msg="role already created") + + db_role = db.query(RoleModel).filter(RoleModel.name == role.roleName).first() + if db_role and db_role.id != role.role_id: + return Response(code=200, msg="role already created") is_edit = await edit_role_resource(db, role.role_id,role.roleName, role.remark, role.resources) if not is_edit: - return Response(code=200, msg="role edit failure", data={}) + return Response(code=500, msg="role edit failure", data={}) return Response(code=200, msg="role edit successfully", data={}) \ No newline at end of file diff --git a/app/api/user.py b/app/api/user.py index 6f98233..4390296 100644 --- a/app/api/user.py +++ b/app/api/user.py @@ -1,9 +1,10 @@ from fastapi import APIRouter, Depends from app.api import Response, pwd_context, get_current_user from app.models.base_model import get_db -from app.models.user import PageParameter +from app.models.user import PageParameter, UserStatus, UserInfo, LoginData from app.models.user_model import UserModel -from app.service.user import get_user_list +from app.service.user import get_user_list, edit_user_status, delete_user_data, create_user, edit_user_data, \ + edit_user_pwd user_router = APIRouter() @@ -13,4 +14,68 @@ return Response(code=200, msg="", data=await get_user_list(db, paras.page_size, paras.page_index, paras.keyword)) +@user_router.post("/add_user", response_model=Response) +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!") + 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" + is_create = await create_user(db, user.userName, user.email, user.phone, user.loginName, pwd, user.roles, user.groups) + if not is_create: + return Response(code=500, msg="user create failure", data={}) + return Response(code=200, msg="user create successfully", data={}) + +@user_router.put("/edit_user", response_model=Response) +async def edit_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!") + user_info = db.query(UserModel).filter(UserModel.id == user.userId).first() + if not user_info: + return Response(code=200, msg="user does not exist") + # db_user = db.query(UserModel).filter(UserModel.username == user.userName).first() + # if db_user and db_user.id != user.userId: + # return Response(code=200, msg="user already created") + is_edit = await edit_user_data(db, user.userId, user.email, user.phone, user.loginName, user.roles, user.groups) + if not is_edit: + return Response(code=500, msg="user edit failure", data={}) + return Response(code=200, msg="user edit successfully", data={}) + + +@user_router.put("/change_status", response_model=Response) +async def change_user_status(user: UserStatus, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + if user.status not in ["0", "1"]: + return Response(code=400, msg="The status cannot be {}!".format(user.status)) + db_user = db.query(UserModel).filter(UserModel.id == user.userId).first() + if not db_user: + return Response(code=200, msg="user does not exist") + is_edit = await edit_user_status(db, user.status,user.userId) + if not is_edit: + return Response(code=500, msg="user status edit failure", data={}) + return Response(code=200, msg="user status edit successfully", data={}) + + +@user_router.delete("/delete_user/{user_id}", response_model=Response) +async def delete_user(user_id, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + db_user = db.query(UserModel).filter(UserModel.id == user_id).first() + if not db_user: + return Response(code=200, msg="user does not exist") + is_edit = await delete_user_data(db, user_id) + if not is_edit: + return Response(code=500, msg="user delete failure", data={}) + return Response(code=200, msg="user delete successfully", data={}) + + +@user_router.put("/reset_pwd", response_model=Response) +async def reset_user_pwd(user: UserStatus, current_user: UserModel = Depends(get_current_user), db=Depends(get_db)): + db_user = db.query(UserModel).filter(UserModel.id == user.userId).first() + if not db_user: + return Response(code=200, msg="user does not exist") + is_edit = await edit_user_pwd(db, user.userId) + if not is_edit: + return Response(code=500, msg="user pwd reset failure", data={}) + return Response(code=200, msg="user pwd reset successfully", data={}) \ No newline at end of file diff --git a/app/models/agent_model.py b/app/models/agent_model.py index 1b1cb00..e2151fc 100644 --- a/app/models/agent_model.py +++ b/app/models/agent_model.py @@ -31,20 +31,17 @@ class CanvasModel(Base): __tablename__ = 'user_canvas' - __mapper_args__ = { - # "order_by": 'SEQ' - } - id = Column(String(32), primary_key=True) - create_time = Column(BigInteger) + + id = Column(String(32), primary_key=True) # id create_date = Column(DateTime, default=datetime.now) - update_time = Column(BigInteger) update_date = Column(DateTime, default=datetime.now) - avatar = Column(Text) - user_id = Column(String(255)) - title = Column(String(255)) - description = Column(Text) - canvas_type = Column(String(32)) + avatar = Column(Text) # 鍥炬爣 + user_id = Column(String(255)) # 鐢ㄦ埛id + title = Column(String(255)) # 鏍囬 + description = Column(Text) # 璇存槑 + canvas_type = Column(String(32)) # agent绫诲瀷 dsl = Column(Text) + agent_type = Column(String(2)) # agent骞冲彴 diff --git a/app/models/dialog_model.py b/app/models/dialog_model.py index bfa4a8c..2ac706f 100644 --- a/app/models/dialog_model.py +++ b/app/models/dialog_model.py @@ -10,29 +10,15 @@ __mapper_args__ = { # "order_by": 'SEQ' } - id = Column(String(32), primary_key=True) - create_time = Column(BigInteger) - create_date = Column(DateTime) - update_time = Column(BigInteger) - update_date = Column(DateTime) - tenant_id = Column(String(32)) - name = Column(String(255)) - description = Column(Text) - icon = Column(Text) - language = Column(String(32)) - llm_id = Column(String(128)) - llm_setting = Column(Text) - prompt_type = Column(String(16)) - prompt_config = Column(Text) - similarity_threshold = Column(Float) - vector_similarity_weight = Column(Float) - top_n = Column(Integer) - top_k = Column(Integer) - do_refer = Column(String(1)) - rerank_id = Column(String(128)) - kb_ids = Column(Text) - status = Column(String(1)) - hide = Column(Boolean) + id = Column(String(32), primary_key=True) # id + create_date = Column(DateTime) # 鍒涘缓鏃堕棿 + update_date = Column(DateTime) # 鏇存柊鏃堕棿 + tenant_id = Column(String(32)) # 鍒涘缓浜� + name = Column(String(255)) # 鍚嶇О + description = Column(Text) # 璇存槑 + icon = Column(Text) # 鍥炬爣 + status = Column(String(1)) # 鐘舵�� + dialog_type = Column(String(1)) # # 骞冲彴 def get_id(self): return str(self.id) diff --git a/app/models/group_model.py b/app/models/group_model.py index 52e05a8..a1ac287 100644 --- a/app/models/group_model.py +++ b/app/models/group_model.py @@ -10,24 +10,24 @@ group_knowledge_table = Table('group_Knowledge', Base.metadata - , Column('group_id', Integer, ForeignKey('group.id')) - , Column('knowledge_id', String(32), ForeignKey('knowledgebase.id'))) + , Column('group_id', Integer, ForeignKey('group.id', ondelete='CASCADE')) + , Column('knowledge_id', String(32), ForeignKey('knowledgebase.id', ondelete='CASCADE'))) group_dialog_table = Table('group_dialogs', Base.metadata - , Column('group_id', Integer, ForeignKey('group.id')) - , Column('dialog_id', String(36), ForeignKey('dialogs.id'))) + , Column('group_id', Integer, ForeignKey('group.id', ondelete='CASCADE')) + , Column('dialog_id', String(36), ForeignKey('dialogs.id', ondelete='CASCADE'))) group_agent_table = Table('group_agent', Base.metadata - , Column('group_id', Integer, ForeignKey('group.id')) - , Column('agent_id', String(36), ForeignKey('user_canvas.id'))) + , Column('group_id', Integer, ForeignKey('group.id', ondelete='CASCADE')) + , Column('agent_id', String(36), ForeignKey('user_canvas.id', ondelete='CASCADE'))) group_llm_table = Table('group_llm', Base.metadata - , Column('group_id', Integer, ForeignKey('group.id')) - , Column('llm_id', String(36), ForeignKey('common_llm.id'))) + , Column('group_id', Integer, ForeignKey('group.id', ondelete='CASCADE')) + , Column('llm_id', String(36), ForeignKey('common_llm.id', ondelete='CASCADE'))) group_unified_agent_table = Table('group_unified_agent', Base.metadata - , Column('group_id', Integer, ForeignKey('group.id')) - ,Column('unified_agent_id', String(36), ForeignKey('unified_agent.id'))) + , Column('group_id', Integer, ForeignKey('group.id', ondelete='CASCADE')) + ,Column('unified_agent_id', String(36), ForeignKey('unified_agent.id', ondelete='CASCADE'))) class GroupModel(Base): diff --git a/app/models/knowledge_model.py b/app/models/knowledge_model.py index cc8d1b8..bde8241 100644 --- a/app/models/knowledge_model.py +++ b/app/models/knowledge_model.py @@ -10,28 +10,16 @@ __mapper_args__ = { # "order_by": 'SEQ' } - id = Column(String(32), primary_key=True) - name = Column(String(128)) - create_time = Column(BigInteger) - create_date = Column(DateTime) - update_time = Column(BigInteger) - update_date = Column(DateTime) - avatar = Column(Text) - tenant_id = Column(String(32)) - language = Column(String(32)) - description = Column(Text) - embd_id = Column(String(128)) - permission = Column(String(16)) - created_by = Column(String(32)) - doc_num = Column(Integer) - token_num = Column(Integer) - chunk_num = Column(Integer) - similarity_threshold = Column(Float) - vector_similarity_weight = Column(Float) - parser_id = Column(String(32)) - parser_config = Column(Text) - status = Column(String(1)) - hide = Column(Boolean) + id = Column(String(32), primary_key=True) # id + name = Column(String(128)) # 鍚嶇О + create_date = Column(DateTime) # 鍒涘缓鏃堕棿 + update_date = Column(DateTime) # 鏇存柊鏃堕棿 + avatar = Column(Text) # 鍥炬爣 + tenant_id = Column(String(32)) # 鍒涘缓浜篿d + description = Column(Text) # 璇存槑 + status = Column(String(1)) # 鐘舵�� + kld_type = Column(String(1)) # 鐭ヨ瘑搴撳钩鍙� + def get_id(self): return str(self.id) diff --git a/app/models/organization_model.py b/app/models/organization_model.py index ae7a1de..f0c2f55 100644 --- a/app/models/organization_model.py +++ b/app/models/organization_model.py @@ -1,18 +1,20 @@ from datetime import datetime +from typing import Optional +from pydantic import BaseModel from sqlalchemy import Column, Integer, String, Table, ForeignKey, DateTime from sqlalchemy.orm import relationship, backref from app.models.base_model import Base -organization_group_table = Table('organization_group', Base.metadata, - Column('group_id', Integer, ForeignKey('group.id')), - Column('organization_id', String(36), ForeignKey('organization.id'))) +# organization_group_table = Table('organization_group', Base.metadata, +# Column('group_id', Integer, ForeignKey('group.id')), +# Column('organization_id', String(36), ForeignKey('organization.id'))) # #鏋勫缓瀵箁ole琛ㄧ殑鍏崇郴 organization_role_table = Table('organization_role', Base.metadata, - Column('role_id', String(36), ForeignKey('role.id')), - Column('organization_id', String(36), ForeignKey('organization.id'))) + Column('role_id', String(36), ForeignKey('role.id', ondelete='CASCADE')), + Column('organization_id', String(36), ForeignKey('organization.id', ondelete='CASCADE'))) class OrganizationModel(Base): __tablename__ = 'organization' @@ -25,13 +27,13 @@ iconcls = Column(String(255)) seq = Column(Integer) leader = Column(String(255)) - phone = Column(String(11)) + phone = Column(String(32)) email = Column(String(64)) status = Column(String(10), nullable=False, default="0") - groups = relationship('GroupModel', - secondary=organization_group_table, - backref=backref('organizations', lazy='dynamic')) + # groups = relationship('GroupModel', + # secondary=organization_group_table, + # backref=backref('organizations', lazy='dynamic')) roles = relationship('RoleModel', secondary=organization_role_table, @@ -61,13 +63,11 @@ 'email': self.email, 'status': self.status, 'roles': [self.role_json(role) for role in self.roles], - 'groups': [self.group_json(group) for group in self.groups], + # 'groups': [self.group_json(group) for group in self.groups], 'children': [ org.to_json() for org in self.children ] } - - return json @@ -87,25 +87,48 @@ def to_tree_select_json(self): return { - 'id': self.ID, - 'label': self.NAME, + 'id': self.id, + 'label': self.name, 'children': [org.to_tree_select_json() for org in self.children] } def get_pid(self): if self.parent: - return self.parent.ID + return self.parent.id return '' def get_pName(self): if self.parent: - return self.parent.NAME + return self.parent.name return '' def get_id(self): - return str(self.ID) + return str(self.id) def __repr__(self): - return '<Organization %r>\n' %(self.NAME) \ No newline at end of file + return '<Organization %r>\n' %(self.name) + + +class DeptList(BaseModel): + deptName: Optional[str] = "" + + +class DeptInfo(BaseModel): + deptId: Optional[str] = "" + deptName: Optional[str] = "" + leader: Optional[str] = "" + phone: Optional[str] = "" + orderNum: int + address: Optional[str] = "" + parentId: Optional[str] = "" + status: str + roles: list + groups: Optional[list] = [] + + +class DeptParent(BaseModel): + deptId: str + parentId: str + orderNum: int diff --git a/app/models/resource_model.py b/app/models/resource_model.py index 3aeff5a..61e1bc9 100644 --- a/app/models/resource_model.py +++ b/app/models/resource_model.py @@ -1,4 +1,7 @@ from datetime import datetime +from typing import Optional + +from pydantic import BaseModel from sqlalchemy import Column, Integer, String, DateTime, Table, ForeignKey from sqlalchemy.orm import relationship, backref @@ -137,4 +140,18 @@ } def __repr__(self): - return '<ResourceTypeModel %r>\n' %(self.name) \ No newline at end of file + return '<ResourceTypeModel %r>\n' %(self.name) + +class MenuInfo(BaseModel): + menuId: Optional[str] = "" + menuName: Optional[str] = "" + component: Optional[str] = "" + path: Optional[str] = "" + orderNum: int + perms: Optional[str] = "" + menuType: Optional[str] = "" + description: Optional[str] = "" + parentId: str + status: str + roles: list + groups: Optional[list] = [] \ No newline at end of file diff --git a/app/models/role_model.py b/app/models/role_model.py index 3121054..e9b80bf 100644 --- a/app/models/role_model.py +++ b/app/models/role_model.py @@ -9,8 +9,8 @@ # 瑙掕壊璧勬簮鍏宠仈琛� role_resource_table = Table('role_resource', Base.metadata, - Column('role_id', String(36), ForeignKey('role.id')), - Column('resource_id', String(36), ForeignKey('resource.id'))) + Column('role_id', String(36), ForeignKey('role.id', ondelete='CASCADE')), + Column('resource_id', String(36), ForeignKey('resource.id', ondelete='CASCADE'))) diff --git a/app/models/user.py b/app/models/user.py index 45874f7..ab53067 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -27,4 +27,21 @@ class PageParameter(BaseModel): page_index: int page_size: int - keyword: Optional[str] = "" \ No newline at end of file + keyword: Optional[str] = "" + +class UserStatus(BaseModel): + userId: int + status: Optional[str] = "" + pwd: Optional[str] = "" + +class UserInfo(BaseModel): + userId: Optional[int] = 0 + userName: Optional[str] = "" + loginName: Optional[str] = "" + phone: Optional[str] = "" + pwd: Optional[str] = "" + email: str + roles: list + groups: Optional[list] = [] + + diff --git a/app/models/user_model.py b/app/models/user_model.py index 81715df..aea4cbd 100644 --- a/app/models/user_model.py +++ b/app/models/user_model.py @@ -6,16 +6,16 @@ from app.models.base_model import Base user_organization_table = Table('user_organization',Base.metadata - , Column('user_id', Integer, ForeignKey('user.id')) - , Column('organization_id', String(36), ForeignKey('organization.id'))) + , Column('user_id', Integer, ForeignKey('user.id', ondelete='CASCADE')) + , Column('organization_id', String(36), ForeignKey('organization.id', ondelete='CASCADE'))) user_role_table = Table('user_role', Base.metadata - , Column('user_id', Integer, ForeignKey('user.id')) - , Column('role_id', String(36), ForeignKey('role.id'))) + , Column('user_id', Integer, ForeignKey('user.id', ondelete='CASCADE')) + , Column('role_id', String(36), ForeignKey('role.id', ondelete='CASCADE'))) user_group_table = Table('user_group', Base.metadata - , Column('user_id', Integer, ForeignKey('user.id')) - , Column('group_id', Integer, ForeignKey('group.id'))) + , Column('user_id', Integer, ForeignKey('user.id', ondelete='CASCADE')) + , Column('group_id', Integer, ForeignKey('group.id', ondelete='CASCADE'))) @@ -89,7 +89,7 @@ 'sex': self.sex, 'age': self.age, "status": self.status, - 'photo': self.phone, + 'phone': self.phone, 'email': self.email, # 'phoneNumber': self.phone_number } @@ -101,16 +101,17 @@ json['groups'] = [group.to_dict() for group in self.groups] roles = [] - # if len(self.roles.all()) > 0: - # roles = [role.to_json() for role in self.roles] - # organization_roles = [role.to_json() for organization in self.organizations for role in - # organization.role_list] - # for role in organization_roles: - # if role not in roles: - # roles.append(role) + # 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 return json + def get_children(self): """閫掑綊鑾峰彇鎸囧畾鐢ㄦ埛鐨勫瓙鐢ㄦ埛ID鍒楄〃""" users = UserModel.query.filter_by(CREATOR=self.ID).all() diff --git a/app/service/organization.py b/app/service/organization.py index e69de29..67f59a9 100644 --- a/app/service/organization.py +++ b/app/service/organization.py @@ -0,0 +1,89 @@ +import uuid + +from app.Log import logger +from app.models import OrganizationModel, GroupModel +from app.models.role_model import RoleModel + + + +async def get_organization_list(db, deptName: str): + query = db.query(OrganizationModel).filter(OrganizationModel.organization_id == None) + if deptName: + query = query.filter(OrganizationModel.name.like('%{}%'.format(deptName))) + depts = query.order_by(OrganizationModel.seq.desc()).all() + return {"total": query.count(), "rows": [dept.to_json() for dept in depts]} + + +async def create_dept(db, dept_name, leader, phone, address, status, order_num, roles, groups,parent_id): + try: + dept_model = OrganizationModel(id=str(uuid.uuid4()),name=dept_name, address=address,leader=leader,phone=phone,seq=order_num,status=status) + if parent_id: + dept_model.parent = db.get(OrganizationModel, parent_id) + if roles: + dept_model.roles = [db.get(RoleModel, roleId) for roleId in roles] + # if groups: + # dept_model.groups = [db.get(GroupModel, groupId) for groupId in groups] + db.add(dept_model) + db.commit() + db.refresh(dept_model) + except Exception as e: + logger.error(e) + db.rollback() + return False + return True + + +async def edit_dept_data(db, dept_id, dept_name, leader, phone, address, status, order_num, roles, groups,parent_id): + try: + dept_model = db.query(OrganizationModel).filter(OrganizationModel.id == dept_id).first() + dept_model.name = dept_name + dept_model.address = address + dept_model.phone = phone + dept_model.leader = leader + dept_model.status = status + dept_model.seq = order_num + # if parent_id: + # dept_model.parent = db.get(OrganizationModel, parent_id) + if roles: + dept_model.roles = [db.get(RoleModel, roleId) for roleId in roles] + # if groups: + # dept_model.groups = [db.get(GroupModel, groupId) for groupId in groups] + # db.add(dept_model) + db.commit() + db.refresh(dept_model) + except Exception as e: + logger.error(e) + db.rollback() + return False + return True + + +async def edit_dept_parent(db, dept_id, parent_id, order_num): + try: + dept_model = db.query(OrganizationModel).filter(OrganizationModel.id == dept_id).first() + dept_model.parent = db.get(OrganizationModel, parent_id) + dept_model.seq = order_num + db.commit() + db.refresh(dept_model) + except Exception as e: + logger.error(e) + db.rollback() + return False + return True + + +async def get_organization_info(db, dept_id: str): + dept = db.query(OrganizationModel).filter(OrganizationModel.id.__eq__(dept_id)).first() + + return {"total": 0, "data": dept.to_json()} + + +async def delete_organization_info(db, dept_id: str): + try: + db.query(OrganizationModel).filter(OrganizationModel.id.__eq__(dept_id)).delete() + 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/ragflow.py b/app/service/ragflow.py index 1677ed5..d5d4726 100644 --- a/app/service/ragflow.py +++ b/app/service/ragflow.py @@ -39,7 +39,7 @@ response = await client.post( f"{self.base_url}/v1/user/register", headers={'Content-Type': 'application/json'}, - json={"nickname": username, "email": f"{username}@example.com", "password": password} + json={"nickname": username, "email": f"{username}@example.com", "password": password} ) if response.status_code != 200: raise Exception(f"Ragflow registration failed: {response.text}") diff --git a/app/service/resource.py b/app/service/resource.py new file mode 100644 index 0000000..572c55e --- /dev/null +++ b/app/service/resource.py @@ -0,0 +1,29 @@ +import uuid + +from app.Log import logger +from app.models import OrganizationModel, GroupModel, ResourceModel +from app.models.role_model import RoleModel + + + +async def get_resource_tree(db): + resource = db.query(ResourceModel).filter(ResourceModel.resource_id == None).order_by(ResourceModel.seq.desc()).all() + + return {"total": 0, "rows": [dept.to_tree_select_json() for dept in resource]} + + +async def get_resource_info(db, menu_id: str): + dept = db.query(ResourceModel).filter(ResourceModel.id.__eq__(menu_id)).first() + + return {"total": 0, "data": dept.to_json()} + + +async def delete_resource_info(db, menu_id): + try: + db.query(ResourceModel).filter(ResourceModel.id.__eq__(menu_id)).delete() + 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/user.py b/app/service/user.py index 472c77a..061d9b9 100644 --- a/app/service/user.py +++ b/app/service/user.py @@ -1,11 +1,120 @@ +import base64 + +from datetime import datetime + +from app.api import pwd_context +from app.config.config import settings +from app.models import RoleModel, GroupModel from app.models.user_model import UserModel from app.Log import logger +from app.service.bisheng import BishengService +from app.service.ragflow import RagflowService + async def get_user_list(db, page_size: int, page_index: int, keyword: str): - logger.error("ffffffff") query = db.query(UserModel) 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]} + + +async def edit_user_status(db, status: str, user_id: int): + try: + db.query(UserModel).filter(UserModel.id == user_id).update({"status":status}) + db.commit() + except Exception as e: + logger.error(e) + db.rollback() + return False + return True + + +async def delete_user_data(db, user_id: str): + try: + db.query(UserModel).filter(UserModel.id == user_id).delete() + db.commit() + except Exception as e: + logger.error(e) + db.rollback() + return False + return True + + +async def create_user(db, user_name, email, phone, login_name, password, roles, groups): + 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 + + # 娉ㄥ唽鍒皉agflow + 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 + + # 瀛樺偍鐢ㄦ埛淇℃伅 + 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.roles = [db.get(RoleModel, roleId) for roleId in roles] + if groups: + user_model.groups = [db.get(GroupModel, groupId) for groupId in groups] + db.add(user_model) + db.commit() + db.refresh(user_model) + except Exception as e: + logger.error(e) + db.rollback() + return False + return True + + +async def edit_user_data(db, user_id, email, phone, login_name, roles, groups): + try: + user = db.query(UserModel).filter(UserModel.id == user_id).first() + user.email = email + user.phone = phone + user.login_name = login_name + user.email = email + user.updated_at = datetime.now() + user.roles = [db.get(RoleModel, roleId) for roleId in roles] + user.groups = [db.get(GroupModel, groupId) for groupId in groups] + db.commit() + except Exception as e: + logger.error(e) + db.rollback() + return False + return True + + +async def edit_user_pwd(db, user_id, password="000000"): + try: + #TODO + hashed_password = pwd_context.hash(password) + user = db.query(UserModel).filter(UserModel.id == user_id).first() + user.hashed_password = hashed_password + db.commit() + except Exception as e: + logger.error(e) + db.rollback() + return False + return True + + +async def get_user_info(db, page_size: int, page_index: int, keyword: str): + query = db.query(UserModel) + 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]} \ No newline at end of file diff --git a/main.py b/main.py index 5826d6f..b183845 100644 --- a/main.py +++ b/main.py @@ -1,13 +1,13 @@ from contextlib import asynccontextmanager from fastapi import FastAPI - -from app.Log import init_log from app.api.auth import router as auth_router from app.api.chat import router as chat_router from app.api.agent import router as agent_router from app.api.excel import router as excel_router from app.api.files import router as files_router +from app.api.organization import dept_router from app.api.report import router as report_router +from app.api.resource import menu_router from app.api.user import user_router from app.api.group import group_router from app.api.role import role_router @@ -44,6 +44,8 @@ app.include_router(user_router, prefix='/api/user', tags=["user"]) app.include_router(group_router, prefix='/api/group', tags=["group"]) app.include_router(role_router, prefix='/api/role', tags=["role"]) +app.include_router(dept_router, prefix='/api/dept', tags=["dept"]) +app.include_router(menu_router, prefix='/api/menu', tags=["menu"]) if __name__ == "__main__": import uvicorn -- Gitblit v1.8.0