async def edit_type_item(request: Request, edit_item: CMDBItemBase, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/cmdb/edit_type_item'))): type_id = int(edit_item.item_id) old_item = db.query(CMDBItem).filter(CMDBItem.item_id == type_id).first() if not old_item: raise HTTPException(status_code=406, detail="要修改的属性不存在") # 判断是否存在 if old_item.item_name != edit_item.item_name: if db.query(CMDBItem).filter( and_(CMDBItem.cmdb_type_id == int(edit_item.cmdb_type_id), CMDBItem.item_name == edit_item.item_name)).first(): raise HTTPException(status_code=406, detail="要修改的属性名已存在") if old_item.item_label != edit_item.item_label: if db.query(CMDBItem).filter( and_(CMDBItem.cmdb_type_id == int(edit_item.cmdb_type_id), CMDBItem.item_label == edit_item.item_label)).first(): raise HTTPException(status_code=406, detail="要修改的标签名已存在") old_record = deepcopy(old_item) old_item.item_name = edit_item.item_name old_item.item_label = edit_item.item_label new_record = deepcopy(old_item) db.add(old_item) db.commit() Record.create_operate_record(username=current_user.username, new_object=new_record, old_object=old_record, ip=request.client.host) return {"message": "属性修改成功"}
async def create_user(user: NewUser, request: Request, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/users/create_user'))): old_user = db.query(User).filter( or_(User.username == user.username, User.email == user.email)).first() if old_user: raise HTTPException(status_code=406, detail="创建的用户已经存在") user_dict = { "username": user.username, "email": user.email, "nick_name": user.nick_name, "is_active": user.is_active } new_user = User(**user_dict) new_record = deepcopy(new_user) new_user.convert_pass_to_hash(user.password) db.add(new_user) db.commit() # 调用数据修改记录器 Record.create_operate_record(new_object=new_record, username=current_user.username, ip=request.client.host) return {"message": "用户创建成功"}
async def role_edit_user(role_users: RoleEditUsers, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/role/edit_users'))): role_id = int(role_users.role_id) # 判断role是否存在 role = db.query(Role.role_id == role_id).first() if not role: raise HTTPException(status_code=406, detail="角色不存在") # TODO 此处是否要判断user_id是否正确? # 处理关联表 # 清除所有数据 db.query(RoleUserRelation).filter( RoleUserRelation.role_id == role_id).delete() for user_id in role_users.users: user_id = int(user_id) db.query(RoleUserRelation).filter( RoleUserRelation.user_id == user_id).delete() role_user_relation = RoleUserRelation(**{ "role_id": role_id, "user_id": user_id }) db.add(role_user_relation) db.commit() return {"message": "成员修改成功"}
async def all_users(page_no: int, page_size: int, search_username: str = '', db: Session = Depends(get_db), current_user: User = Depends( check_perm('/users/all_users'))): # 分页查询,前端需要传递页数,和每页多少个 # 数据分页与list切片格式保持一致 if search_username: total = db.query(func.count( User.user_id)).filter(User.username == search_username).scalar() users = db.query(User).filter(User.username == search_username).slice( page_size * (page_no - 1), page_size * page_no) else: total = db.query(func.count(User.user_id)).scalar() users = db.query(User).slice(page_size * (page_no - 1), page_size * page_no) all_users_dict = { "total": total, "users": [ UserBase( **{ "username": user.username, "email": user.email, "is_active": user.is_active, "nick_name": user.nick_name }) for user in users ] } return AllUser(**all_users_dict)
async def update_user(request: Request, modify_user: ModifyUser, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/users/update_user'))): """ 用户名不可以修改 """ user = db.query(User).filter(User.username == modify_user.username).first() if user: old_user = deepcopy(user) if modify_user.password: user.convert_pass_to_hash(modify_user.password) user.is_active = modify_user.is_active user.email = modify_user.email user.nick_name = modify_user.nick_name new_user = deepcopy(user) db.add(user) db.commit() # 调用数据修改记录器 Record.create_operate_record(old_object=old_user, new_object=new_user, username=current_user.username, ip=request.client.host) return {"message": "用户信息更新成功"} else: raise HTTPException(status_code=406, detail="用户不存在")
async def cmdb_edit_type(edit_type: CMDBBase, request: Request, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/cmdb/edit_type'))): old_type = db.query(CMDBType).filter( CMDBType.cmdb_type_id == int(edit_type.type_id)).first() if not old_type: raise HTTPException(status_code=406, detail="要修改的类型不存在") if old_type.cmdb_type_name != edit_type.type_name: # 说明修改了类型名,需要判断修改后的类型是否已经存在 if db.query(CMDBType).filter( CMDBType.cmdb_type_name == edit_type.type_name).first(): raise HTTPException(status_code=406, detail="修改的类型已存在") old_record = deepcopy(old_type) old_type.cmdb_type_name = edit_type.type_name old_type.cmdb_type_icon = edit_type.type_icon old_type.cmdb_type_label = edit_type.type_label new_record = deepcopy(old_type) db.add(old_type) db.commit() Record.create_operate_record(username=current_user.username, old_object=old_record, new_object=new_record, ip=request.client.host) return {"message": "类型修改成功"}
async def get_record_details(record_id: str, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/cmdb/record_details'))): record_item = db.query(CMDBRecord).filter( CMDBRecord.cmdb_record_id == int(record_id)).first() if not record_item: raise HTTPException(status_code=406, detail="此ID信息不存在") return {"message": "ok", "record_details": record_item.cmdb_record_detail}
def item_info(item_id: str, db: Session = Depends(get_db), current_user: User = Depends(check_perm('/cmdb/item_info'))): item = db.query(CMDBItem).filter(CMDBItem.item_id == int(item_id)).first() if not item: raise HTTPException(status_code=406, detail="查询ID不存在") return CMDBItemBase(item_id=item_id, cmdb_type_id=str(item.cmdb_type_id), item_label=item.item_label, item_name=item.item_name)
async def cmdb_type_list(db: Session = Depends(get_db), current_user: User = Depends( check_perm('/cmdb/type_list'))): cmdb_types = db.query(CMDBType).all() return CMDBTypeList(types=[{ "type_id": str(cmdb_type.cmdb_type_id), "type_name": cmdb_type.cmdb_type_name, "type_label": cmdb_type.cmdb_type_label, "type_icon": cmdb_type.cmdb_type_icon } for cmdb_type in cmdb_types])
async def get_type_desc(type_id: str, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/cmdb/get_type_items'))): cmdb_type_items = db.query(CMDBItem).filter( CMDBItem.cmdb_type_id == int(type_id)).all() return CMDBItemList(items=[{ "item_id": cmdb_type_item.item_id, "item_label": cmdb_type_item.item_label, "item_name": cmdb_type_item.item_name } for cmdb_type_item in cmdb_type_items])
async def type_info(type_id: str, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/cmdb/type_info'))): search_type = db.query(CMDBType).filter( CMDBType.cmdb_type_id == int(type_id)).first() if not search_type: raise HTTPException(status_code=406, detail="查询ID不存在") return CMDBBase(type_id=type_id, type_name=search_type.cmdb_type_name, type_label=search_type.cmdb_type_label, type_icon=search_type.cmdb_type_icon)
async def menu_lists(db: Session = Depends(get_db), current_user: User = Depends(check_perm('/menu/menu_lists'))): # 查询一级菜单 menu_list = [] all_menus = db.query(Menu).all() parent_menus = db.query(Menu).filter(Menu.parent_id == 0).all() all_parent_ids = [menu.parent_id for menu in db.query(Menu.parent_id).distinct().all()] for parent_menu in parent_menus: # 递归获得子菜单 parent_menu_dict = {"menu_id": str(parent_menu.menu_id), "menu_name": parent_menu.menu_name} if parent_menu.menu_id in all_parent_ids: parent_menu_dict["children"] = get_menus(parent_menu.menu_id, all_menus, all_parent_ids) menu_list.append(parent_menu_dict) return JSONResponse({"menus": menu_list})
async def add_menu(menu: MenuBase, request: Request, db: Session = Depends(get_db), current_user: User = Depends(check_perm('/menu/add_menu'))): # 确认menu不存在 old_menu = db.query(Menu).filter(or_(Menu.menu_name == menu.menu_name, Menu.menu_flag == menu.menu_flag)).first() if old_menu: raise HTTPException(status_code=406, detail="菜单已存在") new_menu = Menu(menu_name=menu.menu_name, menu_flag=menu.menu_flag, parent_id="0" if not menu.parent_id else int(menu.parent_id)) new_record = deepcopy(new_menu) db.add(new_menu) db.commit() Record.create_operate_record(username=current_user.username, new_object=new_record, ip=request.client.host) settings.logger.info(f"新增菜单{menu.menu_name}") return {"message": "菜单新增成功"}
async def menu_lists(role_id: str, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/role/menu_lists'))): # 通过role查询菜单 menus = db.query(Menu.menu_id).join( MenuRoleRelation, MenuRoleRelation.menu_id == Menu.menu_id).filter( MenuRoleRelation.role_id == int(role_id)).all() all_menus = db.query(Menu).all() role_menus = [{ "key": str(menu.menu_id), "label": menu.menu_name } for menu in all_menus] return RoleMenus(menus=role_menus, choose_menus=[str(menu.menu_id) for menu in menus])
async def role_user_lists(role_id: str, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/role/user_lists'))): # 通过role去查询所有用户 users = db.query(User.user_id).join( RoleUserRelation, RoleUserRelation.user_id == User.user_id).filter( RoleUserRelation.role_id == int(role_id)).all() all_users = db.query(User).all() role_users = [{ "key": str(user.user_id), "label": user.username } for user in all_users] return RoleUsers(users=role_users, choose_users=[str(member.user_id) for member in users])
async def get_user_info(username: str, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/users/get_user_info'))): user = db.query(User).filter(User.username == username).first() if user: user_dict = { "username": user.username, "email": user.email, "is_active": user.is_active, "nick_name": user.nick_name } return UserBase(**user_dict) else: raise HTTPException(status_code=406, detail="用户不存在")
async def add_role(role: RoleBase, request: Request, db: Session = Depends(get_db), current_user: User = Depends(check_perm('/role/add_role'))): old_role = db.query(Role).filter(Role.role_name == role.role_name).first() if old_role: raise HTTPException(status_code=406, detail="创建的角色已存在") new_role = Role(role_name=role.role_name, role_desc=role.role_desc) new_record = deepcopy(new_role) db.add(new_role) db.commit() Record.create_operate_record(username=current_user.username, new_object=new_record, ip=request.client.host) return {"message": "角色添加成功"}
async def instance_lists(type_id: str, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/cmdb/instance_lists'))): # 获取所有实例 instances = db.query(CMDBRecord).filter( CMDBRecord.cmdb_type_id == int(type_id)).all() # id转为str for instance in instances: instance.cmdb_record_id = str(instance.cmdb_record_id) instance.cmdb_type_id = str(instance.cmdb_type_id) # 获取类型下面所有属性 items = db.query(CMDBItem).filter( CMDBItem.cmdb_type_id == int(type_id)).all() return {"instances": instances, "items": items}
async def delete_record(request: Request, record_id: str, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/cmdb/delete_record'))): record = db.query(CMDBRecord).filter( CMDBRecord.cmdb_record_id == int(record_id)).first() if not record: raise HTTPException(status_code=406, detail="要删除的ID不存在") old_record = deepcopy(record) db.delete(record) db.commit() Record.create_operate_record(username=current_user.username, old_object=old_record, ip=request.client.host) return {"message": "记录删除成功"}
async def perm_lists(role_id: str, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/role/perm_lists'))): # 通过role查询权限 perms = db.query(Permission.perm_id).join( PermRoleRelation, PermRoleRelation.perm_id == Permission.perm_id).filter( PermRoleRelation.role_id == int(role_id)).all() all_perms = db.query(Permission).all() role_perms = [{ "key": str(perm.perm_id), "label": perm.perm_name } for perm in all_perms] return RolePerms(perms=role_perms, choose_perms=[str(perm.perm_id) for perm in perms])
async def all_records(page_no: int, page_size: int, search_info: str, db: Session = Depends(get_db), current_user: User = Depends(check_perm('/record/all_records'))): if search_info: total = db.query(func.count(OperateRecords.record_id)).filter( OperateRecords.operate_detail.like(f"%{search_info}%")).scalar() records = db.query(OperateRecords).filter(OperateRecords.operate_detail.like(f"%{search_info}%")).order_by( OperateRecords.operate_time.desc()).slice(page_size * (page_no - 1), page_size * page_no) else: total = db.query(func.count(OperateRecords.record_id)).scalar() records = db.query(OperateRecords).order_by(OperateRecords.operate_time.desc()).slice(page_size * (page_no - 1), page_size * page_no) record_lists = {"total": total, "records": [Record( **{"operate_object": record.operate_object, "operate_type": record.operate_type, "operate_detail": record.operate_detail, "operate_ip": record.operate_ip, "operate_username": record.operate_username, "operate_time": record.operate_time}) for record in records]} return AllRecords(**record_lists)
async def cmdb_add_type(new_type: CMDBBase, request: Request, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/cmdb/add_type'))): # type_name唯一 old_type = db.query(CMDBType).filter( CMDBType.cmdb_type_name == new_type.type_name).first() if old_type: raise HTTPException(status_code=406, detail="创建的类型已经存在") cmdb_type = CMDBType(cmdb_type_name=new_type.type_name, cmdb_type_icon=new_type.type_icon, cmdb_type_label=new_type.type_label) new_record = deepcopy(cmdb_type) db.add(cmdb_type) db.commit() Record.create_operate_record(username=current_user.username, new_object=new_record, ip=request.client.host) return {"message": "类型创建成功"}
async def add_record(request: Request, new_record: Dict[str, str], db: Session = Depends(get_db), current_user: User = Depends( check_perm('/cmdb/add_record'))): type_id = int(new_record.get("cmdb_type_id", "0")) if type_id == 0: raise HTTPException(status_code=406, detail="请传入cmdb_type_id") # 删除id就是记录详情了 del new_record['cmdb_type_id'] cmdb_record = CMDBRecord() cmdb_record.cmdb_type_id = type_id cmdb_record.cmdb_record_detail = new_record record = deepcopy(cmdb_record) db.add(cmdb_record) db.commit() Record.create_operate_record(username=current_user.username, new_object=record, ip=request.client.host) return {"message": "实例添加成功"}
async def create_cmdb_template(type_id: str, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/cmdb/create_cmdb_template'))): type_id = int(type_id) cmdb_type = db.query(CMDBType).filter( CMDBType.cmdb_type_id == type_id).first() if not cmdb_type: raise HTTPException(status_code=406, detail="上传的类型不存在") # 获取所有属性 cmdb_items = db.query( CMDBItem.item_name).filter(CMDBItem.cmdb_type_id == type_id).all() keys = [cmdb_item.item_name for cmdb_item in cmdb_items] # 文件命名规则: {type_name}模板.xlsx filename = f"{cmdb_type.cmdb_type_name}模板.xlsx" filepath = os.path.join(Settings.CMDB_FOLDER, filename) excel = Excel(filepath=filepath) # 根据最新数据生成模板 excel.create_cmdb_template(keys=keys) return FileResponse(filepath, filename=filename)
async def role_list(db: Session = Depends(get_db), current_user: User = Depends(check_perm('/role/list'))): roles = db.query( Role, func.count(RoleUserRelation.user_id).label('user_count')).outerjoin( RoleUserRelation, RoleUserRelation.role_id == Role.role_id).group_by( Role.role_name).all() role_lists = { "roles": [ RoleBase( **{ "role_name": role.Role.role_name, "role_desc": role.Role.role_desc, "role_id": role.Role.role_id, "user_count": role.user_count }) for role in roles ] } return role_lists
async def import_record(request: Request, type_id: str, file: UploadFile = File(...), db: Session = Depends(get_db), current_user: User = Depends( check_perm('/cmdb/import_record'))): # 获取用户上传的文件并存储,命名规则:{type_name}-{username}-{时间戳} type_id = int(type_id) cmdb_type = db.query(CMDBType).filter( CMDBType.cmdb_type_id == type_id).first() if not cmdb_type: raise HTTPException(status_code=406, detail="上传的类型不存在") # 上传文件必须为Excel if not file.content_type == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": raise HTTPException(status_code=406, detail="请上传Excel文件") cmdb_type_name = cmdb_type.cmdb_type_name total_miles = str(int(round(time.time() * 1000))) store_filename = f"{cmdb_type_name}-{total_miles}-{file.filename}" content = await file.read() # 保存用户上传的文件 with open(os.path.join(Settings.UPLOAD_FOLDER, store_filename), "wb+") as f: f.write(content) # 解析Excel excel = Excel( filepath=os.path.join(Settings.UPLOAD_FOLDER, store_filename)) all_records = excel.import_cmdb_record() if len(all_records) == 0: raise HTTPException(status_code=406, detail="请填入具体数据") # record插入数据库 for record in all_records: cmdb_record = CMDBRecord() cmdb_record.cmdb_type_id = type_id cmdb_record.cmdb_record_detail = record new_record = deepcopy(cmdb_record) db.add(cmdb_record) db.commit() Record.create_operate_record(username=current_user.username, new_object=new_record, ip=request.client.host) return {"all_records": all_records}
async def role_edit_perms(edit_perms: RoleEditPerms, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/role/edit_perms'))): role_id = int(edit_perms.role_id) # 判断role是否存在 role = db.query(Role.role_id == role_id).first() if not role: raise HTTPException(status_code=406, detail="角色不存在") # 处理关联表 # 清除所有数据 db.query(PermRoleRelation).filter( PermRoleRelation.role_id == role_id).delete() for perm_id in edit_perms.perms: perm_id = int(perm_id) role_perm_relation = PermRoleRelation(**{ "role_id": role_id, "perm_id": perm_id }) db.add(role_perm_relation) db.commit() return {"message": "接口权限修改成功"}
async def edit_menu(menu: MenuBase, request: Request, db: Session = Depends(get_db), current_user: User = Depends(check_perm('/menu/edit_menu'))): # 确认menu不存在 old_menu = db.query(Menu).filter(Menu.menu_id == int(menu.menu_id)).first() if not old_menu: raise HTTPException(status_code=406, detail="要修改的菜单不存在") # 确认菜单是否重复 old_record = deepcopy(old_menu) if menu.menu_name != old_menu.menu_name: if db.query(Menu).filter(Menu.menu_name == menu.menu_name).first(): raise HTTPException(status_code=406, detail="菜单名已存在") if menu.menu_flag != old_menu.menu_flag: if db.query(Menu).filter(Menu.menu_flag == menu.menu_flag).first(): raise HTTPException(status_code=406, detail="菜单标识已存在") old_menu.menu_name = menu.menu_name old_menu.menu_flag = menu.menu_flag old_menu.parent_id = int(menu.parent_id) new_record = deepcopy(old_menu) db.add(old_menu) db.commit() Record.create_operate_record(username=current_user.username, old_object=old_record, new_object=new_record, ip=request.client.host) return {"message": "菜单修改成功"}
async def add_type_desc(request: Request, new_item: CMDBItemBase, db: Session = Depends(get_db), current_user: User = Depends( check_perm('/cmdb/add_type_item'))): # 确认属性是否重复 old_item = db.query(CMDBItem).filter( and_( CMDBItem.cmdb_type_id == new_item.cmdb_type_id, or_(CMDBItem.item_name == new_item.item_name, CMDBItem.item_label == new_item.item_label))).first() if old_item: raise HTTPException(status_code=406, detail="此属性已存在") item = CMDBItem(cmdb_type_id=int(new_item.cmdb_type_id), item_name=new_item.item_name, item_label=new_item.item_label) new_record = deepcopy(item) db.add(item) db.commit() Record.create_operate_record(username=current_user.username, new_object=new_record, ip=request.client.host) return {"message": "属性新增成功"}
async def instance_lists(type_id: str, page_no: int, page_size: int, search_str: str = '', db: Session = Depends(get_db), current_user: User = Depends( check_perm('/cmdb/instance_lists'))): # 获取所有实例 if search_str: total = db.query(func.count(CMDBRecord.cmdb_record_id)).filter( and_(CMDBRecord.cmdb_type_id == int(type_id), CMDBRecord.cmdb_record_detail.like( f"%{search_str}%"))).scalar() instances = db.query(CMDBRecord).filter( and_(CMDBRecord.cmdb_type_id == int(type_id), CMDBRecord.cmdb_record_detail.like(f"%{search_str}%"))).slice( page_size * (page_no - 1), page_size * page_no) else: total = db.query(func.count(CMDBRecord.cmdb_record_id)).filter( CMDBRecord.cmdb_type_id == int(type_id)).scalar() instances = db.query(CMDBRecord).filter( CMDBRecord.cmdb_type_id == int(type_id)).slice( page_size * (page_no - 1), page_size * page_no) # 获取类型下面所有属性 items = db.query(CMDBItem).filter( CMDBItem.cmdb_type_id == int(type_id)).all() return { "total": total, "instances": [{ "cmdb_record_id": str(instance.cmdb_record_id), "cmdb_type_id": str(instance.cmdb_type_id), "cmdb_record_detail": instance.cmdb_record_detail } for instance in instances], "items": items }