权限管理系统-0.2.0

三、菜单管理接口

3.1 创建SysMenu类及相关类

首先创建sys_menu表:

CREATE TABLE `sys_menu` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `parent_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '所属上级',
  `name` varchar(20) NOT NULL DEFAULT '' COMMENT '名称',
  `type` tinyint(3) NOT NULL DEFAULT '0' COMMENT '类型(0:目录,1:菜单,2:按钮)',
  `path` varchar(100) DEFAULT NULL COMMENT '路由地址',
  `component` varchar(100) DEFAULT NULL COMMENT '组件路径',
  `perms` varchar(100) DEFAULT NULL COMMENT '权限标识',
  `icon` varchar(100) DEFAULT NULL COMMENT '图标',
  `sort_value` int(11) DEFAULT NULL COMMENT '排序',
  `status` tinyint(4) DEFAULT NULL COMMENT '状态(0:禁止,1:正常)',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `is_deleted` tinyint(3) NOT NULL DEFAULT '0' COMMENT '删除标记(0:不可用 1:可用)',
  PRIMARY KEY (`id`),
  KEY `idx_parent_id` (`parent_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='菜单表';
INSERT INTO `sys_menu` VALUES (2,0,'系统管理',0,'system','Layout',NULL,'el-icon-s-tools',1,1,'2021-05-31 18:05:37','2022-06-09 09:23:24',0),(3,2,'用户管理',1,'sysUser','system/sysUser/list','','el-icon-s-custom',1,1,'2021-05-31 18:05:37','2022-06-09 09:22:47',0),(4,2,'角色管理',1,'sysRole','system/sysRole/list','','el-icon-user-solid',2,1,'2021-05-31 18:05:37','2022-06-09 09:37:18',0),(5,2,'菜单管理',1,'sysMenu','system/sysMenu/list','','el-icon-s-unfold',3,1,'2021-05-31 18:05:37','2022-06-09 09:37:21',0),(6,3,'查看',2,NULL,NULL,'bnt.sysUser.list',NULL,1,1,'2021-05-31 18:05:37','2022-06-09 09:22:38',0),(7,3,'添加',2,NULL,NULL,'bnt.sysUser.add',NULL,1,1,'2021-05-31 18:05:37','2022-06-09 09:22:38',0),(8,3,'修改',2,NULL,NULL,'bnt.sysUser.update',NULL,1,1,'2021-05-31 18:05:37','2022-06-09 09:22:38',0),(9,3,'删除',2,NULL,NULL,'bnt.sysUser.remove',NULL,1,1,'2021-05-31 18:05:37','2022-06-09 09:22:38',0),(10,4,'查看',2,NULL,NULL,'bnt.sysRole.list',NULL,1,1,'2021-05-31 18:05:37','2022-06-09 09:22:38',0),(11,4,'添加',2,NULL,NULL,'bnt.sysRole.add',NULL,1,1,'2021-05-31 18:05:37','2022-06-09 09:22:38',0),(12,4,'修改',2,NULL,NULL,'bnt.sysRole.update',NULL,1,1,'2021-05-31 18:05:37','2022-06-09 09:22:38',0),(13,4,'删除',2,NULL,NULL,'bnt.sysRole.remove',NULL,1,1,'2021-05-31 18:05:37','2022-06-09 09:22:38',0),(14,5,'查看',2,NULL,NULL,'bnt.sysMenu.list',NULL,1,1,'2021-05-31 18:05:37','2022-06-09 09:22:38',0),(15,5,'添加',2,NULL,NULL,'bnt.sysMenu.add',NULL,1,1,'2021-05-31 18:05:37','2022-06-09 09:22:38',0),(16,5,'修改',2,NULL,NULL,'bnt.sysMenu.update',NULL,1,1,'2021-05-31 18:05:37','2022-06-09 09:22:38',0),(17,5,'删除',2,NULL,NULL,'bnt.sysMenu.remove',NULL,1,1,'2021-05-31 18:05:37','2022-06-09 09:22:38',0),(18,3,'分配角色',2,NULL,NULL,'bnt.sysUser.assignRole',NULL,1,1,'2022-05-23 17:14:32','2022-06-09 09:22:38',0),(19,4,'分配权限',2,'assignAuth','system/sysRole/assignAuth','bnt.sysRole.assignAuth',NULL,1,1,'2022-05-23 17:18:14','2022-06-09 09:22:38',0),(20,2,'部门管理',1,'sysDept','system/sysDept/list','','el-icon-s-operation',4,1,'2022-05-24 10:07:05','2022-06-09 09:38:12',0),(21,20,'查看',2,NULL,NULL,'bnt.sysDept.list',NULL,1,1,'2022-05-24 10:07:44','2022-06-09 09:22:38',0),(22,2,'岗位管理',1,'sysPost','system/sysPost/list','','el-icon-more-outline',5,1,'2022-05-24 10:25:30','2022-06-09 09:38:13',0),(23,22,'查看',2,NULL,NULL,'bnt.sysPost.list',NULL,1,1,'2022-05-24 10:25:45','2022-06-09 09:22:38',0),(24,20,'添加',2,NULL,NULL,'bnt.sysDept.add',NULL,1,1,'2022-05-25 15:31:27','2022-06-09 09:22:38',0),(25,20,'修改',2,NULL,NULL,'bnt.sysDept.update',NULL,1,1,'2022-05-25 15:31:41','2022-06-09 09:22:38',0),(26,20,'删除',2,NULL,NULL,'bnt.sysDept.remove',NULL,1,1,'2022-05-25 15:31:59','2022-06-09 09:22:38',0),(27,22,'添加',2,NULL,NULL,'bnt.sysPost.add',NULL,1,1,'2022-05-25 15:32:44','2022-06-09 09:22:38',0),(28,22,'修改',2,NULL,NULL,'bnt.sysPost.update',NULL,1,1,'2022-05-25 15:32:58','2022-06-09 09:22:38',0),(29,22,'删除',2,NULL,NULL,'bnt.sysPost.remove',NULL,1,1,'2022-05-25 15:33:11','2022-06-09 09:22:38',0),(30,34,'操作日志',1,'sysOperLog','system/sysOperLog/list','','el-icon-document-remove',7,1,'2022-05-26 16:09:59','2022-06-09 09:39:23',0),(31,30,'查看',2,NULL,NULL,'bnt.sysOperLog.list',NULL,1,1,'2022-05-26 16:10:17','2022-06-09 09:22:38',0),(32,34,'登录日志',1,'sysLoginLog','system/sysLoginLog/list','','el-icon-s-goods',8,1,'2022-05-26 16:36:13','2022-06-09 09:39:24',0),(33,32,'查看',2,NULL,NULL,'bnt.sysLoginLog.list',NULL,1,1,'2022-05-26 16:36:31','2022-06-09 09:36:36',0),(34,2,'日志管理',0,'log','ParentView','','el-icon-tickets',6,1,'2022-05-31 13:23:07','2022-06-09 09:39:22',0),(35,0,'审批设置',0,'processSet','Layout','','el-icon-setting',1,1,'2022-12-01 09:32:46','2022-12-01 09:32:46',0),(36,35,'审批模板',1,'processTemplate','processSet/processTemplate/list','','el-icon-s-help',2,1,'2022-12-01 09:37:08','2022-12-19 14:10:48',0),(37,36,'查看',2,'','','bnt.processTemplate.list','',1,1,'2022-12-01 09:37:49','2022-12-01 09:37:49',0),(38,36,'审批模板设置',2,'templateSet','processSet/processTemplate/templateSet','bnt.processTemplate.templateSet','',1,1,'2022-12-01 14:52:08','2022-12-13 18:11:56',0),(39,35,'审批类型',1,'processType','processSet/processType/list','','el-icon-s-unfold',1,1,'2022-12-02 14:46:18','2022-12-13 18:12:24',0),(40,39,'查看',2,'','','bnt.processType.list','',1,1,'2022-12-02 14:46:41','2022-12-02 14:46:41',0),(41,0,'审批管理',0,'processMgr','Layout','','el-icon-more-outline',1,1,'2022-12-02 14:48:11','2022-12-20 09:29:30',0),(42,41,'审批列表',1,'process','processMgr/process/list','','el-icon-document-remove',1,1,'2022-12-02 14:49:06','2022-12-02 14:59:17',0),(43,42,'查看',2,'','','bnt.process.list','',1,1,'2022-12-02 14:49:24','2022-12-02 14:49:24',0),(44,36,'在线流程设置',2,'onlineProcessSet','processSet/processTemplate/onlineProcessSet','bnt.processTemplate.onlineProcessSet','',1,1,'2022-12-08 10:13:15','2022-12-19 18:57:35',0),(45,39,'添加',2,'','','bnt.processType.add','',1,1,'2022-12-09 09:14:53','2022-12-09 09:14:53',0),(46,39,'修改',2,'','','bnt.processType.update','',1,1,'2022-12-09 09:15:10','2022-12-09 09:15:10',0),(47,39,'删除',2,'','','bnt.processType.remove','',1,1,'2022-12-09 09:15:25','2022-12-09 09:15:25',0),(48,36,'删除',2,'','','bnt.processTemplate.remove','',1,1,'2022-12-09 09:22:29','2022-12-09 09:22:29',0),(49,36,'发布',2,'','','bnt.processTemplate.publish','',1,1,'2022-12-09 09:24:47','2022-12-09 09:24:47',0),(50,0,'公众号菜单',0,'wechat','Layout','','el-icon-s-operation',1,1,'2022-12-13 09:06:58','2022-12-21 11:20:55',0),(51,50,'菜单列表',1,'menu','wechat/menu/list','','el-icon-s-help',1,1,'2022-12-13 09:07:52','2022-12-13 09:09:49',0),(52,51,'查看',2,'','','bnt.menu.list','',1,1,'2022-12-13 09:08:48','2022-12-13 17:58:23',0),(53,51,'添加',2,'','','bnt.menu.add','',1,1,'2022-12-13 16:29:25','2022-12-13 17:58:34',0),(54,51,'修改',2,'','','bnt.menu.update','',1,1,'2022-12-13 16:29:41','2022-12-13 17:58:42',0),(55,51,'删除',2,'','','bnt.menu.remove','',1,1,'2022-12-13 16:29:59','2022-12-13 17:58:47',0),(56,51,'删除微信菜单',2,'','','bnt.menu.removeMenu','',1,1,'2022-12-13 16:30:36','2022-12-13 17:58:54',0),(57,51,'同步微信菜单',2,'','','bnt.menu.syncMenu','',1,1,'2022-12-13 16:31:00','2022-12-13 17:59:01',0);

通过MyBatisPlus的代码生成器创建SysMenu相关类,前面已经使用多次,这里就不再说明。
创建好文件后,删除mapper目录下的xml文件和entity文件夹,在model模块中创建SysMenu实体类:

package pers.beiluo.yunshangoffice.model.system;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.List;

@ApiModel("菜单")
@Data
@TableName("sys_menu")
public class SysMenu extends BaseEntity {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "所属上级")
    @TableField("parent_id")
    private Long parentId;

    @ApiModelProperty(value = "名称")
    @TableField("name")
    private String name;

    @ApiModelProperty(value = "类型(1:菜单,2:按钮)")
    @TableField("type")
    private Integer type;

    @ApiModelProperty(value = "路由地址")
    @TableField("path")
    private String path;

    @ApiModelProperty(value = "组件路径")
    @TableField("component")
    private String component;

    @ApiModelProperty(value = "权限标识")
    @TableField("perms")
    private String perms;

    @ApiModelProperty(value = "图标")
    @TableField("icon")
    private String icon;

    @ApiModelProperty(value = "排序")
    @TableField("sort_value")
    private Integer sortValue;

    @ApiModelProperty(value = "状态(0:禁止,1:正常)")
    @TableField("status")
    private Integer status;

    // 下级列表
    @TableField(exist = false)
    private List<SysMenu> children;
    //是否选中
    @TableField(exist = false)
    private boolean isSelect;

}

3.2 SysMenuController

/**
 * <p>
 * 菜单表 前端控制器
 * </p>
 *
 * @author beiluo
 * @since 2024-03-04
 */
@Api(tags = "菜单管理")
@RestController
@RequestMapping("/admin/system/sysMenu")
public class SysMenuController {

    @Autowired
    private SysMenuService sysMenuService;

}

3.3 获取树形菜单

//SysMenuController
    /**
     * 这个方法以树形结构返回所有菜单,返回列表中的对象为根节点
     * 通过递归的方法完成查询
     * @return
     */
    @Override
    public List<SysMenu> getMenu() {
        //首先查询所有目录
        List<SysMenu> sysMenus = baseMapper.selectList(null);
        //接着建立目录结构
        List<SysMenu> sysMenus1 = MyUtils.buildMenu(sysMenus);
        return sysMenus1;
    }
//SysMenuServiceImpl
    public List<SysMenu> getMenu() {
        //首先查询所有目录
        List<SysMenu> sysMenus = baseMapper.selectList(null);
        //接着建立目录结构
        List<SysMenu> sysMenus1 = MyUtils.buildMenu(sysMenus);
        return sysMenus1;
    }
//MyUtils.buildMenu
    /**
     * 构建树形菜单的工具方法,通过递归构建树形结构
     * @param list 所有目录数据
     * @return
     */
    public static List<SysMenu> buildMenu(List<SysMenu> list){
        List<SysMenu> sysMenus = new ArrayList<>();
        for (SysMenu sysMenu : list) {
            if(sysMenu.getParentId() == 0){
                sysMenus.add(buildTree(sysMenu,list));
            }
        }
        return sysMenus;
    }
//buildTree
    public static SysMenu buildTree(SysMenu sysMenu,List<SysMenu> list){
        sysMenu.setChildren(new ArrayList<SysMenu>());
        for (SysMenu menu : list) {
            if(menu.getParentId()==sysMenu.getId()){
                sysMenu.getChildren().add(buildTree(menu,list));
            }
        }
        return sysMenu;
    }

在这里插入图片描述

3.4 新增菜单

    @ApiOperation("新增菜单")
    @PostMapping("/save")
    public Result save(@RequestBody SysMenu sysMenu){
        sysMenuService.save(sysMenu);
        return Result.ok();
    }

3.5 通过id修改菜单

    @ApiOperation("通过id修改菜单")
    @PutMapping("/updateMenu")
    public Result updateMenuById(@RequestBody SysMenu sysMenu){
        sysMenuService.updateById(sysMenu);
        return Result.ok();
    }

3.6 删除菜单

    @ApiOperation("删除菜单")
    @DeleteMapping("/remove/{id}")
    public Result removeMenu(@PathVariable Long id){
        return Result.ok();
    }

3.7 根据角色查询菜单

//SysMenuController
    @ApiOperation("根据角色查询菜单")
    @GetMapping("/getMenuByRole/{roleId}")
    public Result getMenuByRole(@PathVariable("roleId") Long id){
        List<SysMenu> menuByRole = sysMenuService.getMenuByRole(id);
        return Result.ok(menuByRole);
    }
//SysMenuServiceImpl
    @Override
    public List<SysMenu> getMenuByRole(Long id) {
        //查询所有有效(状态为1)的菜单
        LambdaQueryWrapper<SysMenu> sysMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysMenuLambdaQueryWrapper.eq(SysMenu::getStatus,1);
        List<SysMenu> sysMenus = baseMapper.selectList(sysMenuLambdaQueryWrapper);
        //查询角色菜单表
        LambdaQueryWrapper<SysRoleMenu> sysRoleMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysRoleMenuLambdaQueryWrapper.eq(SysRoleMenu::getRoleId, id);
        List<SysRoleMenu> sysRoleMenus = sysRoleMenuMapper.selectList(sysRoleMenuLambdaQueryWrapper);
        //取出当前角色拥有的菜单
        List<Long> collect =
                sysRoleMenus.stream().map(sysRoleMenu -> sysRoleMenu.getMenuId()).collect(Collectors.toList());
        //遍历菜单列表,得到角色拥有的菜单
        sysMenus.forEach(sysMenu -> {
            if(collect.contains(sysMenu.getId())){
                sysMenu.setSelect(true);
            }else{
                sysMenu.setSelect(false);
            }
        });
        return MyUtils.buildMenu(sysMenus);
    }

在这里插入图片描述

3.8 给角色添加菜单

//首先需要一个分配菜单的条件类
@Data
@ApiModel("角色分配条件类")
public class AssignRoleVo {

    @ApiModelProperty("用户id")
    private Long userId;

    @ApiModelProperty("角色id列表")
    private List<Long> roleIdList;

}
//SysMenuController
    @ApiOperation("给角色添加菜单")
    @PostMapping("/assignMenuForRole")
    public Result assignMenuForRole(@RequestBody AssignMenuVo assignMenuVo){
        sysMenuService.assignMenuForRole(assignMenuVo);
        return Result.ok();
    }
//SysMenuServiceImpl
    @Override
    public void assignMenuForRole(AssignMenuVo assignMenuVo) {
        //首先删除角色菜单信息
        LambdaQueryWrapper<SysRoleMenu> sysRoleMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysRoleMenuLambdaQueryWrapper.eq(SysRoleMenu::getRoleId,assignMenuVo.getRoleId());
        sysRoleMenuMapper.delete(sysRoleMenuLambdaQueryWrapper);
        //向角色添加菜单
        SysRoleMenu sysRoleMenu = new SysRoleMenu();
        assignMenuVo.getMenuIdList().forEach(menuId -> {
            sysRoleMenu.setRoleId(assignMenuVo.getRoleId());
            sysRoleMenu.setMenuId(menuId);
            sysRoleMenuMapper.insert(sysRoleMenu);
        });
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/445863.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【脚本玩漆黑的魅影】寂雨镇全自动练级

文章目录 原理全部代码 原理 老样子。 治疗路径&#xff0c;练级路径。 def zhi_liao(): # 去治疗walk(RIGHT)walk(RIGHT)press(UP, 0.4)for i in [1, 2, 3, 4]:press(A)for i in [1, 2, 3, 4]:press(B)press(DOWN, 0.4)press(LEFT) def chu_qu(): # 右逛c.press(B)press(…

力扣同类题:重排链表

很明显做过一次 class Solution { public:void reorderList(ListNode* head) {if(!head||!head->next)return;ListNode *fasthead,*lowhead;ListNode *prenullptr,*curnullptr,*nextnullptr;while(fast->next!nullptr){fastfast->next;if(fast->next)fastfast->…

风控规则决策树可视化(升级版)

上一篇我们介绍了如何通过交叉表来生成规则&#xff0c;本篇我们来介绍一种可以生成多规则的方法&#xff0c;决策树。除了做模型以外&#xff0c;也可以用来挖掘规则&#xff0c;原理是一样的。 下面通过sklearn的决策树方法来实现风控规则的发现&#xff0c;同时分享一种可以…

【联邦学习综述:概念、技术】

出自——联邦学习综述&#xff1a;概念、技术、应用与挑战。梁天恺 1*&#xff0c;曾 碧 2&#xff0c;陈 光 1 从两个方面保护隐私数据 硬件层面 可 信 执 行 环 境 &#xff08;Trusted Execution Environment&#xff0c;TEE&#xff09;边 缘 计 算&#xff08;Edge Com…

电动车窗开关中MOS管的应用解析

随着科技的不断发展&#xff0c;电动车窗系统已经成为现代汽车中不可或缺的一部分。而MOS&#xff08;金属氧化物半导体&#xff09;管的应用&#xff0c;为电动车窗开关注入了新的活力&#xff0c;极大地提高了其使用寿命和安全性。 一、MOS的优越性能 MOS管以其卓越的开关…

磁盘无法访问?别慌,这里有解决之道!

电脑中&#xff0c;那块储存着重要文件与数据的磁盘&#xff0c;突然之间无法访问&#xff0c;是不是让你感到惊慌失措&#xff1f;面对这样的突发状况&#xff0c;很多人可能会感到手足无措。但别担心&#xff0c;本文将为你解析磁盘无法访问的原因&#xff0c;并提供实用的数…

小文件问题及GlusterFS的瓶颈

01海量小文件存储的挑战 为了解决海量小文件的存储问题&#xff0c;必须采用分布式存储&#xff0c;目前分布式存储主要采用两种架构&#xff1a;集中式元数据管理架构和去中心化架构。 (1)集中式元数据架构&#xff1a; 典型的集中式元数据架构的分布式存储有GFS&#xff0…

代码讲解:如何把3D数据转换成旋转的视频?

目录 3D数据集下载 读取binvox文件 使用matplotlib创建图 动画效果 完整代码 3D数据集下载 这里以shapenet数据集为例&#xff0c;可以访问外网的可以去直接申请下载&#xff1b;我也准备了一个备份在百度网盘的数据集&#xff0c;可以参考&#xff1a; ShapeNet简介和下…

Leetcode 54. 螺旋矩阵

题目描述&#xff1a; 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5] 示例 2&#xff1a; 输入&a…

Linux文件系列: 深入理解缓冲区和C标准库的简单模拟实现

Linux文件系列: 深入理解缓冲区和C标准库的简易模拟实现 一.缓冲区的概念和作用二.一个样例三.理解样例1.样例解释2.什么是刷新? 四.简易模拟实现C标准库1.我们要实现的大致框架2.mylib.h的实现1.文件结构体的定义2.myfopen等等函数的声明3.完整mylib.h代码 3.myfopen函数的实…

备战蓝桥杯Day25 - 二叉搜索树

一、基本概念 二叉搜索树&#xff08;Binary Search Tree&#xff09;&#xff0c;又称为二叉查找树或二叉排序树&#xff0c;是一种具有特定性质的二叉树。 定义&#xff1a;二叉搜索树可以是一棵空树&#xff0c;也可以是具有以下特性的非空二叉树&#xff1a; 若其左子树不…

MAC OS 14.2.1 ASP.NET Core 调试遇到的端口占用的问题

一、问题描述 在调试 ASP.NET Core 项目时&#xff0c;遇到一个很奇怪的问题&#xff0c;不管项目是否已经运行&#xff0c;使用 Postman 测试接口时&#xff0c;都返回 403 Forbidden。重启电脑&#xff0c;刚开始还好好的&#xff0c;过一会儿就返回 403 Forbidden。 二、问…

AOP切面编程,以及自定义注解实现切面

AOP切面编程 通知类型表达式重用表达式切面优先级使用注解开发&#xff0c;加上注解实现某些功能 简介 动态代理分为JDK动态代理和cglib动态代理当目标类有接口的情况使用JDK动态代理和cglib动态代理&#xff0c;没有接口时只能使用cglib动态代理JDK动态代理动态生成的代理类…

2024蓝桥杯每日一题(双指针)

一、第一题&#xff1a;牛的学术圈 解题思路&#xff1a;双指针贪心 仔细思考可以知道&#xff0c;写一篇综述最多在原来的H指数的基础上1&#xff0c;所以基本方法可以是先求出原始的H指数&#xff0c;然后分类讨论怎么样提升H指数。 【Python程序代码】 n,l map(int,…

一篇文章搞定数字电桥

大家好&#xff0c;我是砖一。 最近做项目过程中&#xff0c;有一个应届生问我怎么测电容和电感&#xff0c;我推荐他使用数字电桥&#xff08;也叫LCR表&#xff09;&#xff0c;他不会用&#xff0c;今天我写了一篇文章供小白们参考一下&#xff0c;包学会~ 一&#xff0c;…

WebRTC简介及实战应用 — 从0到1实现实时音视频聊天等功能

一、WebRTC简介 WebRTC 是由一家名为 Gobal IP Solutions,简称 GIPS 的瑞典公司开发的。Google 在 2011 年收购了 GIPS,并将其源代码开源。然后又与 IETF 和 W3C 的相关标准机构合作,以确保行业达成共识。其中: Web Real-Time Communications (WEBRTC) W3C 组织:定义浏览…

【npm】node包管理工具npm的介绍和基础使用

简言 npm 是 Node.js 的 包管理器&#xff08;Package Manager&#xff09;&#xff0c;它是专门用于管理 Node.js 项目中第三方库的工具。 本文介绍下npm和其使用方法。 npm介绍 npm 是世界上最大的软件注册中心。各大洲的开源开发者都使用 npm 共享和借用软件包&#xff…

开源组件安全风险及应对

在软件开发的过程中&#xff0c;为了提升开发效率、软件质量和稳定性&#xff0c;并降低开发成本&#xff0c;使用开源组件是开发人员的不二选择&#xff08;实际上&#xff0c;所有软件开发技术的演进都是为了能够更短时间、更低成本地构建软件&#xff09;。这里的开源组件指…

Spring事件发布监听器ApplicationListener原理- 观察者模式

据说监听器模式也是mq实现的原理, 不过mq我还没来得及深入学习, 先用spring来理解一下吧 Spring事件发布监听器ApplicationListener原理- 观察者模式 什么是观察者模式一个Demo深入认识一下观察者模式Spring中的事件发布监听ps 什么是观察者模式 大家都听过一个故事叫做烽火戏…

Git学习笔记(流程图+示例)

概念 图中左侧为工作区&#xff0c;右侧为版本库。Git 的版本库里存了很多东西&#xff0c;其中最重要的就是暂存区。 • 在创建 Git 版本库时&#xff0c;Git 会为我们自动创建一个唯一的 master 分支&#xff0c;以及指向 master 的一个指 针叫 HEAD。&#xff08;分支和HEAD…