SpringBoot2+Vue2实战(十)权限管理

一、父子菜单实现

新建数据库表

sys_menu

 sys_role

 实体类

Role

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;

import lombok.Getter;
import lombok.Setter;

/**
 * <p>
 *
 * </p>
 *
 */
@Getter
@Setter
@TableName("sys_role")
public class Role implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 名称
     */
    private String name;

    /**
     * 描述
     */
    private String description;


}

Menu 


import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;
import java.util.List;

import lombok.Getter;
import lombok.Setter;

/**
 * <p>
 *
 * </p>
 *
 * 
 */
@Getter
@Setter
@TableName("sys_menu")
public class Menu implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 名称
     */
    private String name;

    /**
     * 路径
     */
    private String path;

    /**
     * 图片
     */
    private String icon;

    /**
     * 描述
     */
    private String description;


    @TableField(exist = false)
    private List<Menu> children;


    private Integer pid;


}

RoleController

package com.example.springboot.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.springboot.common.Result;
import com.example.springboot.entity.Role;
import com.example.springboot.service.RoleService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/role")
public class RoleController {

    @Resource
    private RoleService roleService;


    //修改或增加
    @PostMapping("/saveRole")
    public Result saveRole(@RequestBody Role role) {
        //新增或修改
        return Result.success(roleService.saveOrUpdate(role));
    }

    @GetMapping("/findAll")
    public Result findAll() {
        return Result.success(roleService.list());
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable("id") Integer id) {
        return Result.success(roleService.removeById(id));
    }

    //批量删除
    @PostMapping("/del/batch")
    public Result deleteBatch(@RequestBody List<Integer> ids) {
        return Result.success(roleService.removeBatchByIds(ids));
    }

    //分页查询 mybatis-plus方式
    @GetMapping("/selectPage")
    public Result selectPage(@RequestParam(defaultValue = "") String name,
                             @RequestParam Integer pageSize,
                             @RequestParam Integer pageNum) {

        IPage<Role> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        if (!"".equals(name)) {
            queryWrapper.like("name", name);
        }
        return Result.success(roleService.page(page, queryWrapper));
    }

}

MneuController


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.springboot.common.Result;
import com.example.springboot.entity.Menu;
import com.example.springboot.service.MenuService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 */
@RestController
@RequestMapping("/menu")
public class MenuController {

    @Resource
    private MenuService menuService;


    //修改或增加
    @PostMapping("/saveMenu")
    public Result saveRole(@RequestBody Menu menu) {
        //新增或修改
        return Result.success(menuService.saveOrUpdate(menu));
    }

    @GetMapping("/findAll")
    public Result findAll(@RequestParam(defaultValue = "") String name) {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        if (!"".equals(name)) {
            queryWrapper.like("name", name);
        }
        //查询所有数据
        List<Menu> list = menuService.list(queryWrapper);
        List<Menu> parentNode = list.stream().filter(menu -> menu.getPid() == null).collect(Collectors.toList());
        //找出一级菜单的子菜单
        for (Menu menu:parentNode){
            //筛选所有数据中pid等于父级id的数据就是二级菜单
            menu.setChildren(list.stream().filter(m -> menu.getId().equals(m.getPid())).collect(Collectors.toList()));
        }
        return Result.success(parentNode);
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable("id") Integer id) {
        return Result.success(menuService.removeById(id));
    }

    //批量删除
    @PostMapping("/del/batch")
    public Result deleteBatch(@RequestBody List<Integer> ids) {
        return Result.success(menuService.removeBatchByIds(ids));
    }

    //分页查询 mybatis-plus方式
    @GetMapping("/selectPage")
    public Result selectPage(@RequestParam(defaultValue = "") String name,
                             @RequestParam Integer pageSize,
                             @RequestParam Integer pageNum) {

        IPage<Menu> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        if (!"".equals(name)) {
            queryWrapper.like("name", name);
        }
        return Result.success(menuService.page(page, queryWrapper));
    }
}

router/index.js

{
        path: '/',
        component: () => import('../views/Manage.vue'),
        redirect: "/home",
        children: [
            {path: 'user', name: '用户管理', component: () => import('../views/User.vue'),},
            {path: 'home', name: '首页', component: () => import('../views/Home.vue'),},
            {path: 'role', name: '角色管理', component: () => import('../views/Role.vue'),},
            {path: 'menu', name: '菜单管理', component: () => import('../views/Menu.vue'),},
            {path: 'person', name: '个人信息', component: () => import('../views/Person.vue'),},
            {path: 'file', name: '文件管理', component: () => import('../views/Files.vue'),}
        ]
    },

Role.vue

<template>
  <div>
    <div style="margin: 10px 0">
      <el-input style="width: 200px" placeholder="请输入名称" suffix-icon="el-icon-search"
                v-model="name"></el-input>
      <el-button class="ml-5" type="primary" @click="load">搜索</el-button>
      <el-button type="warning" @click="reset">重置</el-button>
    </div>

    <div style="margin: 10px 0">
      <el-button type="primary" @click="handleAdd">新增 <i class="el-icon-circle-plus-outline"></i></el-button>
      <el-popconfirm
          class="ml-5"
          confirm-button-text='确定'
          cancel-button-text='我再想想'
          icon="el-icon-info"
          icon-color="red"
          title="您确定批量删除这些数据吗?"
          @confirm="delBatch"
      >
        <el-button type="danger" slot="reference">批量删除 <i class="el-icon-remove-outline"></i></el-button>
      </el-popconfirm>
    </div>

    <el-table :data="tableData" border stripe :header-cell-class-name="'headerBg'"
              @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55"></el-table-column>
      <el-table-column prop="id" label="ID" width="80"></el-table-column>
      <el-table-column prop="name" label="名称"></el-table-column>
      <el-table-column prop="description" label="描述"></el-table-column>
      <el-table-column label="操作" width="280" align="center">
        <template slot-scope="scope">
          <el-button type="info" @click="selectMenu(scope.row.id)">分配菜单<i class="el-icon-menu"></i></el-button>
          <el-button type="success" @click="handleEdit(scope.row)">编辑 <i class="el-icon-edit"></i></el-button>
          <el-popconfirm
              class="ml-5"
              confirm-button-text='确定'
              cancel-button-text='我再想想'
              icon="el-icon-info"
              icon-color="red"
              title="您确定删除吗?"
              @confirm="del(scope.row.id)"
          >
            <el-button type="danger" slot="reference">删除<i class="el-icon-remove-outline"></i></el-button>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
    <div style="padding: 10px 0">
      <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="pageNum"
          :page-sizes="[2, 5, 10, 20]"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total">
      </el-pagination>
    </div>

    <el-dialog title="菜单信息" :visible.sync="dialogFormVisible" width="30%">
      <el-form label-width="80px" size="small">
        <el-form-item label="用户名">
          <el-input v-model="form.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="form.description" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="save">确 定</el-button>
      </div>
    </el-dialog>


    <el-dialog title="菜单分配" :visible.sync="menuDialogVis" width="30%" style="padding: 0 50px">
      <el-tree
          //使用props进行数据绑定
          :props="props"
          :data="menuData"
          :default-expanded-keys="[1]"
          :default-checked-keys="[4]"
          node-key="id"
          show-checkbox
          @check-change="handleCheckChange">
      </el-tree>
      <div slot="footer" class="dialog-footer">
        <el-button @click="menuDialogVis = false">取 消</el-button>
        <el-button type="primary" @click="save">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: "Role",
  data() {
    return {
      tableData: [],
      total: 0,
      pageNum: 1,
      pageSize: 2,
      name: "",
      form: {},
      dialogFormVisible: false,
      menuDialogVis: false,
      multipleSelection: [],
      menuData: [],
      props:{
        label:'name'
      }
    }
  },
  created() {
    this.load()
  },
  methods: {
    load() {
      this.request.get("/role/selectPage", {
        params: {
          pageNum: this.pageNum,
          pageSize: this.pageSize,
          name: this.name,
        }
      }).then(res => {
        //注意data
        this.tableData = res.data.records
        this.total = res.data.total
      })

    },


    save() {
      this.request.post("/role/saveRole", this.form).then(res => {
        if (res.code === '200') {
          this.$message.success("保存成功")
          this.dialogFormVisible = false
          this.load()
        } else {
          this.$message.error("保存失败")
        }
      })
    },
    handleAdd() {
      this.dialogFormVisible = true
      this.form = {}
    },
    handleEdit(row) {
      this.form = JSON.parse(JSON.stringify(row))
      this.dialogFormVisible = true
    },
    del(id) {
      this.request.delete("/role/" + id).then(res => {
        if (res.code === '200') {
          this.$message.success("删除成功")
          this.load()
        } else {
          this.$message.error("删除失败")
        }
      })
    },
    handleSelectionChange(val) {
      console.log(val)
      this.multipleSelection = val
    },
    delBatch() {
      let ids = this.multipleSelection.map(v => v.id)  // [{}, {}, {}] => [1,2,3]
      this.request.post("/role/del/batch", ids).then(res => {
        if (res.code === '200') {
          this.$message.success("批量删除成功")
          this.load()
        } else {
          this.$message.error("批量删除失败")
        }
      })
    },
    reset() {
      this.name = ""
      this.load()
    },
    handleSizeChange(pageSize) {
      console.log(pageSize)
      this.pageSize = pageSize
      this.load()
    },
    handleCurrentChange(pageNum) {
      console.log(pageNum)
      this.pageNum = pageNum
      this.load()
    },
    //分配菜单
    selectMenu(roleId) {
      this.menuDialogVis = true

      //请求菜单数据
      this.request.get("/menu/findAll").then(res => {
        //注意data
        this.menuData = res.data
      })

    },
    handleCheckChange(data, checked, indeterminate) {
      console.log(data, checked, indeterminate);
    },
  },

}
</script>


<style>
.headerBg {
  background: #eee !important;
}
</style>

Mneu.vue

<template>
  <div>
    <div style="margin: 10px 0">
      <el-input style="width: 200px" placeholder="请输入名称" suffix-icon="el-icon-search"
                v-model="name"></el-input>
      <el-button class="ml-5" type="primary" @click="load">搜索</el-button>
      <el-button type="warning" @click="reset">重置</el-button>
    </div>

    <div style="margin: 10px 0">
      <el-button type="primary" @click="handleAdd()">新增<i class="el-icon-circle-plus-outline"></i></el-button>
      <el-popconfirm
          class="ml-5"
          confirm-button-text='确定'
          cancel-button-text='我再想想'
          icon="el-icon-info"
          icon-color="red"
          title="您确定批量删除这些数据吗?"
          @confirm="delBatch"
      >
        <el-button type="danger" slot="reference">批量删除 <i class="el-icon-remove-outline"></i></el-button>
      </el-popconfirm>
    </div>

    <el-table :data="tableData" row-key="id" default-expand-all border stripe :header-cell-class-name="'headerBg'"
              @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55"></el-table-column>
      <el-table-column prop="id" label="ID" width="80"></el-table-column>
      <el-table-column prop="name" label="名称"></el-table-column>
      <el-table-column prop="path" label="路径"></el-table-column>
      <el-table-column prop="icon" label="图片"></el-table-column>
      <el-table-column prop="description" label="描述"></el-table-column>
      <el-table-column label="操作" width="280" align="center">
        <template slot-scope="scope">
          <el-button type="primary" @click="handleAdd(scope.row.id)" v-if="!scope.row.pid && !scope.row.path">新增子菜单<i class="el-icon-plus"></i></el-button>
          <el-button type="success" @click="handleEdit(scope.row)">编辑 <i class="el-icon-edit"></i></el-button>
          <el-popconfirm
              class="ml-5"
              confirm-button-text='确定'
              cancel-button-text='我再想想'
              icon="el-icon-info"
              icon-color="red"
              title="您确定删除吗?"
              @confirm="del(scope.row.id)"
          >
            <el-button type="danger" slot="reference">删除<i class="el-icon-remove-outline"></i></el-button>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>

    <el-dialog title="角色信息" :visible.sync="dialogFormVisible" width="30%">
      <el-form label-width="80px" size="small">
        <el-form-item label="菜单名">
          <el-input v-model="form.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="路径">
          <el-input v-model="form.path" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="图片">
          <el-input v-model="form.icon" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="form.description" autocomplete="off"></el-input>
        </el-form-item>

      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="save">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: "Menu",
  data() {
    return {
      tableData: [],
      total: 0,
      pageNum: 1,
      pageSize: 2,
      name: "",
      form: {},
      dialogFormVisible: false,
      multipleSelection: []
    }
  },
  created() {
    this.load()
  },
  methods: {
    load() {
      this.request.get("/menu/findAll", {
        params: {
          name: this.name,
        }
      }).then(res => {
        //注意data
        this.tableData = res.data
      })
    },


    save() {
      this.request.post("/menu/saveMenu", this.form).then(res => {
        if (res.code === '200') {
          this.$message.success("保存成功")
          this.dialogFormVisible = false
          this.load()
        } else {
          this.$message.error("保存失败")
        }
      })
    },
    handleAdd(pid) {
      this.dialogFormVisible = true
      this.form = {}
      if (pid) {
        this.form.pid = pid
      }
    },
    handleEdit(row) {
      this.form = JSON.parse(JSON.stringify(row))
      this.dialogFormVisible = true
    },
    del(id) {
      this.request.delete("/menu/" + id).then(res => {
        if (res.code === '200') {
          this.$message.success("删除成功")
          this.load()
        } else {
          this.$message.error("删除失败")
        }
      })
    },
    handleSelectionChange(val) {
      console.log(val)
      this.multipleSelection = val
    },
    delBatch() {
      let ids = this.multipleSelection.map(v => v.id)  // [{}, {}, {}] => [1,2,3]
      this.request.post("/menu/del/batch", ids).then(res => {
        if (res.code === '200') {
          this.$message.success("批量删除成功")
          this.load()
        } else {
          this.$message.error("批量删除失败")
        }
      })
    },
    reset() {
      this.name = ""
      this.load()
    },
    handleSizeChange(pageSize) {
      console.log(pageSize)
      this.pageSize = pageSize
      this.load()
    },
    handleCurrentChange(pageNum) {
      console.log(pageNum)
      this.pageNum = pageNum
      this.load()
    }
  }
}
</script>


<style>
.headerBg {
  background: #eee !important;
}
</style>

二、图标功能

新建数sys_dict

 Dict


import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;

/**
 * <p>
 *
 * </p>
 *
 * @author 
 * @since 2023-07-05
 */
@Data
@TableName("sys_dict")
public class Dict implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 名称
     */
    private String name;

    /**
     * 内容
     */
    private String value;

    /**
     * 类型
     */
    private String type;


}

MenuController

@Resource
    private DictMapper dictMapper;




 @GetMapping("/icons")
    public Result getIcons(){
        QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type", Constants.DICT_TYPE_ICON);
        return Result.success(dictMapper.selectList(queryWrapper));
    }

Menu.vue


//修改表格图标显示
<el-table-column label="图标" class-name="fontSize18" align="center" label-class-name="fontSize12">
        <template slot-scope="scope">
          <i :class="scope.row.icon"></i>
        </template>
      </el-table-column>


//修改弹窗图标选择显示
<el-form-item label="图标">
          <template slot-scope="scope">
            <el-select clearable v-model="form.icon" placeholder="请选择" style="width: 80%">
              <el-option v-for="item in options" :key="item.name" :label="item.name" :value="item.value">
                <i :class="item.value"/>{{ item.name }}
              </el-option>
            </el-select>
          </template>
        </el-form-item>

//data中添加参数

options: []


//修改方法

handleEdit(row) {
      this.form = JSON.parse(JSON.stringify(row))
      this.dialogFormVisible = true

      //请求图标的数据
      this.request.get("/menu/icons").then(res => {
        this.options = res.data
      })

    },

 查询菜单时展开功能实现

Role

<el-tree
          :props="props"
          :data="menuData"
          :default-expanded-keys="expends"
          :default-checked-keys="checks"
          node-key="id"
          show-checkbox
          @check-change="handleCheckChange">
         <span class="custom-tree-node" slot-scope="{ node, data }">
           <span><i :class="data.icon"></i>{{ data.name }}</span>
         </span>
      </el-tree>

//data添加变量
 expends: [],
      checks: [],



//分配菜单
    selectMenu(roleId) {
      this.menuDialogVis = true

      //请求菜单数据
      this.request.get("/menu/findAll").then(res => {
        //注意data
        this.menuData = res.data

        //把后台返回的菜单数据处理成id数组
        this.expends = this.menuData.map(v => v.id);
      })

    },




 三、菜单分配功能实现

1.添加功能

新建数据库表

sys_role_menu

 RoleMenu

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("sys_role_menu")
public class RoleMenu {

    private Integer roleId;

    private Integer menuId;
}

RoleController

@PostMapping("/setRoleMenu/{roleId}")
    public Result setRoleMenu(@PathVariable Integer roleId, @RequestBody List<Integer> menuIds) {
        roleService.setRoleMenu(roleId, menuIds);
        return Result.success();
    }

RoleService

void setRoleMenu(Integer roleId, List<Integer> menuIds);

RoleServiceImpl

@Resource
    private RoleMenuMapper roleMenuMapper;

    @Override
    @Transactional
    public void setRoleMenu(Integer roleId, List<Integer> menuIds) {
        /**
         * 第一种方法
         * */
        /*QueryWrapper<RoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id",roleId);
        roleMenuMapper.delete(queryWrapper);*/

        /**
         * 第二种方法
         * */
        //先删除当前角色id所有的绑定关系
        roleMenuMapper.deleteMenuByRoleId(roleId);

        //再把前端传过来的菜单id数组绑定到当前这个角色id上
        for (Integer menuId: menuIds){
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setRoleId(roleId);
            roleMenu.setMenuId(menuId);
            roleMenuMapper.insert(roleMenu);
        }
    }

RoleMenuMapper

 @Delete("delete from sys_role_menu where role_id = #{roleId}")
    Integer deleteMenuByRoleId(@Param("roleId") Integer roleId);

Role.vue

<el-button type="info" @click="selectMenu(scope.row.id)">分配菜单<i class="el-icon-menu"></i></el-button>


<el-dialog title="菜单分配" :visible.sync="menuDialogVis" width="30%" style="padding: 0 50px">
      <el-tree
          :props="props"
          :data="menuData"
          :default-expanded-keys="expends"
          :default-checked-keys="checks"
          node-key="id"
          show-checkbox
          ref="tree"
      >
         <span class="custom-tree-node" slot-scope="{ node, data }">
           <span><i :class="data.icon"></i>{{ data.name }}</span>
         </span>
      </el-tree>
      <div slot="footer" class="dialog-footer">
        <el-button @click="menuDialogVis = false">取 消</el-button>
        <el-button type="primary" @click="saveRoleMenu">确 定</el-button>
      </div>
    </el-dialog>






saveRoleMenu() {
      this.request.post("/role/setRoleMenu/" + this.roleId, this.$refs.tree.getCheckedKeys()).then(res => {
        if (res.code === '200') {
          this.$message.success("绑定成功")
          this.menuDialogVis = false
        } else {
          this.$message.error(res.msg)
        }
      })
    },

2.点击菜单分配时的查询已有权限菜单功能

RoleController

@GetMapping("/getRoleMenu/{roleId}")
    public Result getRoleMenu(@PathVariable Integer roleId) {
        return Result.success(roleService.getRoleMenu(roleId));
    }

RoleService

List<Integer> getRoleMenu(Integer roleId);

RoleServiceImpl

@Override
    public List<Integer> getRoleMenu(Integer roleId) {
        return roleMenuMapper.selectByRoleId(roleId);
    }

RoleMenuMapper

 @Select("select menu_id from sys_role_menu where role_id = #{roleId}")
    List<Integer> selectByRoleId(@Param("roleId") Integer roleId);

Role.vue

roleId: 0





//分配菜单
    selectMenu(roleId) {
      this.menuDialogVis = true
      this.roleId = roleId
      //请求菜单数据
      this.request.get("/menu/findAll").then(res => {
        //注意data
        this.menuData = res.data

        //把后台返回的菜单数据处理成id数组
        this.expends = this.menuData.map(v => v.id);
      })

      this.request.get("/role/getRoleMenu/" + roleId).then(res => {
        this.checks = res.data
      })

    },

 

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

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

相关文章

博客相关推荐在线排序学习实践

现有固定槽位的填充召回策略在相关线上推荐服务中缺乏有效的相关性排序&#xff0c;存在较硬的排列顺序&#xff0c;各个策略之间互相影响&#xff0c;导致线上基于规则的拓扑图比较复杂&#xff0c;因此设计在线推理服务&#xff0c;通过学习用户行为完成在线排序。 1. 博客相…

【计算机网络】数据链路层之随机接入-CSMA/CD协议(总线局域网)

1.概念 2.信号碰撞&#xff08;冲突&#xff09; 3.解决方案 CSMA/CD 4.争用期&#xff08;端到端往返时延&#xff09; 5.最小帧长 6.最大帧长 7.指数退避算法 8.信道利用率 9.帧发送流程 10.帧接受流程 12.题目1 13.题目2 14.题目3 15 小结

数字IC后端学习笔记:等效性检查和ECO

1.形式验证工具 对于某些电路的移植&#xff0c;一般不需要对新电路进行仿真验证&#xff0c;而可以直接通过EDA工具来分析该电路的功能是否与原电路一致&#xff0c;此种验证方法可以大量减少验证时间&#xff0c;提高电路的效率。 等效性检查&#xff08;Equivalence Check&a…

给LLM装上知识:从LangChain+LLM的本地知识库问答到LLM与知识图谱的结合

第一部分 什么是LangChain&#xff1a;连接本地知识库与LLM的桥梁 作为一个 LLM 应用框架&#xff0c;LangChain 支持调用多种不同模型&#xff0c;提供相对统一、便捷的操作接口&#xff0c;让模型即插即用&#xff0c;这是其GitHub地址&#xff0c;其架构如下图所示 (点此查…

状态检测防火墙

状态检测防火墙原理 对于已经存在会话表的报文的检测过程比没有会话表的报文要短很多。通过对一条连接的首包进行检测并建立会话后,该条连接的绝大部分报文都不再需要重新检测。这就是状态检测防火墙的“状态检测机制”,相对于包过滤防火墙的“逐包检测机制”的改进之处。这种…

ChatLaw:中文法律大模型

论文题目&#xff1a;ChatLaw: Open-Source Legal Large Language Model with Integrated External Knowledge Bases   论文日期&#xff1a;2023/06/28   官网地址&#xff1a;https://www.chatlaw.cloud   论文地址&#xff1a;https://arxiv.org/abs/2306.16092   G…

Compose编排工具应用

补充&#xff1a; Docker Compose 文件&#xff1a;Docker Compose 是一个用于定义和运行多个 Docker 容器的工具。它使用 YAML 文件格式来描述应用程序的各个组件和其配置。以下是一个简单的示例&#xff1a; 在上面的示例中&#xff0c;我们定义了两个服务&#xff1a;web 和…

浅谈金融场景的风控策略

随着互联网垂直电商、消费金融等领域的快速崛起&#xff0c;用户及互联网、金融平台受到欺诈的风险也急剧增加。网络黑灰产已形成完整的、成熟的产业链&#xff0c;每年千亿级别的投入规模&#xff0c;超过1000万的“从业者”&#xff0c;其专业度也高于大多数技术人员&#xf…

Ubuntu 23.10 现在由Linux内核6.3提供支持

对于那些希望在Ubuntu上尝试最新的Linux 6.3内核系列的人来说&#xff0c;今天有一个好消息&#xff0c;因为即将发布的Ubuntu 23.10&#xff08;Mantic Minotaur&#xff09;已经重新基于Linux内核6.3。 Ubuntu 23.10的开发工作于4月底开始&#xff0c;基于目前的临时版本Ubu…

通过ioctl函数选择不同硬件的控制,LED 蜂鸣器 马达 风扇

通过ioctl函数选择不同硬件的控制&#xff0c;LED 蜂鸣器 马达 风扇 实验现象 head.h #ifndef __HEAD_H__ #define __HEAD_H__ typedef struct{volatile unsigned int MODER; // 0x00volatile unsigned int OTYPER; // 0x04volatile unsigned int OSPEEDR; // 0x08volati…

【Linux】gcc编译过程、make和makefile的概念与区别、Linux简单进度条实现

文章目录 1.gcc编译过程1.1预处理1.2编译1.3汇编1.4链接 2.自动化构建工具-make和makefile2.1使用背景2.2两者的概念和区别2.3项目清理 3.Linux简单进度条的实现 1.gcc编译过程 1. 预处理&#xff08;进行宏替换)   2. 编译&#xff08;生成汇编)   3. 汇编&#xff08;生成…

【NX】NXOpen::BlockStyler::Tree的个人使用类分享

网上关于NXOpen::BlockStyler::Tree的例子不是太多&#xff0c;控件默认id名称为tree_control01&#xff0c;因为例子不多很多功能得自己写&#xff0c;虽然NXOpen::BlockStyler::Tree的封装已经不错了&#xff0c;但是实际使用起来也不是很方便&#xff0c;比如像获取所有节点…

【Git】 Git初相识

文章目录 1. Git的必要性1.1 提出问题1.2 解决问题1.3 注意事项 2. Git的安装2.1 kali下的安装2.3 Windows下的安装 3. Git的配置 1. Git的必要性 1.1 提出问题 在我们的学习或者工作中&#xff0c;经常会遇到一些比较难搞的上司或者老师&#xff0c;让我们交上去的文档改了又…

【UI设计】新拟态风格

新拟态风格 1.有且只有一个光源照射 那作者在追波上按钮也好还是卡片处理也好&#xff0c;仔细观察不难发现&#xff0c;它定了一个光源&#xff0c;是从左上向右下照射的&#xff0c;所以&#xff0c;越靠近光源的部分&#xff0c;越亮&#xff0c;远离光源的越暗&#xff08;…

Linux进程OOM-kill 监控和规避

目录 一、proc目录简介 二、Linux OOM机制说明 1、OOM killer机制 2、寻找系统中最先被OOM kill的进程 3、修改 oom_score_adj 一、proc目录简介 proc是linux系统中的一个虚拟文件系统&#xff0c;它实际上不含有任何真正的文件&#xff0c;/proc中的文件如同linux内核中的…

Elasticsearch Dump的详细安装和迁移es索引和数据的使用教程

前言 如果希望将数据导出到本地文件而不是通过编程方式处理&#xff0c;可以考虑使用Elasticsearch的导出工具&#xff0c;如Elasticsearch Dump&#xff08;Elasticdump&#xff09;或Elasticsearch Exporter。这些工具可以将Elasticsearch索引中的数据导出为可用于后续处理的…

通付盾发布UIAM白皮书,利用区块链、大模型AI,以及无证书分布式身份认证赋能工业互联网

简介 UIAM白皮书结合各行业与国内外IAM发展状况&#xff0c;对IAM发展历程、核心能力以及现代增强型IAM技术的演进路线进行探讨。探索身份和信息安全管理与区块链、大模型AI、无证书分布式身份认证等技术趋势&#xff0c;以及UIAM技术在工业互联网的应用。期望能够帮助企业组织…

Vue3使用element-plus实现弹窗效果-demo

使用 <ShareDialog v-model"isShow" onChangeDialog"onChangeDialog" /> import ShareDialog from ./ShareDialog.vue; const isShow ref(false); const onShowDialog (show) > {isShow.value show; }; const onChangeDialog (val) > {co…

mysql的两种安装方式(yum在线安装和通用二进制)

文章目录 msqly的安装一、yum在线安装二、通用二进制安装mysql msqly的安装 一、yum在线安装 yum是一种在线安装方式&#xff0c;通过官网网址在linux下载安装 首先是配置一个yum安装源 yum install http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm也…

使用Jetpack Compose中的LazyRow

在Jetpack Compose中&#xff0c;我们可以使用LazyRow来创建一个水平滚动的列表&#xff0c;类似于传统Android开发中的HorizontalScrollView。在这篇博客中&#xff0c;我们将探讨如何在Jetpack Compose中使用LazyRow。 创建LazyRow 要创建一个LazyRow&#xff0c;我们需要创…