福田瑞沃轻卡/上海有实力的seo推广咨询
目录
1、角色后端接口
2、角色列表查询
2.1 效果图
2.2页面原型代码
2.3 角色api代码 role.js
2.4 查询角色列表代码
4、 新增和编辑角色
5、删除角色
6、分配权限
6.1 分配权限思路
6.2 分配权限回显接口
6.3 分配权限回显前端实现
6.4分配权限后端接口
6.4.1 RolePermissionDTO
6.4.2 RoleMapper
6.4.3 RoleMapper.xml
6.4.4 RoleService
6.4.5 RoleServiceImp
6.4.6 RoleController
6.5分配权限回显前端实现
1、角色后端接口
package com.cizhu.vo.query;import com.cizhu.entity.Permission;
import lombok.Data;@Data
public class RoleQueryVo extends Permission {private Long pageNo = 1L;//当前页码private Long pageSize = 10L;//每页显示数量private Long userId;//用户ID
}
package com.cizhu.mapper;import com.cizhu.entity.Role;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Select;import java.util.List;/*** <p>* Mapper 接口* </p>** @author cizhu* @since 2023-12-14*/
public interface RoleMapper extends BaseMapper<Role> {@Select("select count(1) from sys_user_role where role_id = #{roleId}")int getRoleCountByRoleId(Long roleId);@Delete("delete from sys_role_permission where role_id = #{roleId}")void deleteRolePermissionByRoleId(Long roleId);/*** 保存角色权限关系* @param roleId* @param permissionIds* @return*/int saveRolePermission(Long roleId, List<Long> permissionIds);/*** 根据用户ID查询该用户拥有的角色ID* @param userId* @return*/@Select("select role_id from `sys_user_role` where user_id = #{userId}")List<Long> findRoleIdByUserId(Long userId);}
package com.cizhu.service;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cizhu.entity.Role;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cizhu.vo.query.RoleQueryVo;import java.util.List;/*** <p>* 服务类* </p>** @author cizhu* @since 2023-12-14*/
public interface IRoleService extends IService<Role> {/*** 根据用户查询角色列表* @param page* @param roleQueryVo* @return*/IPage<Role> findRoleListByUserId(IPage<Role> page, RoleQueryVo roleQueryVo);/**** 检查该角色是否已被使用* @param id:* @return boolean*/boolean hasRoleCount(Long id);/**** 删除角色* @param id:* @return boolean*/boolean deleteRoleById(Long id);/*** 保存角色权限关系* @param roleId* @param permissionIds* @return*/boolean saveRolePermission(Long roleId, List<Long> permissionIds);/*** 根据用户ID查询该用户拥有的角色ID* @param userId* @return*/List<Long> findRoleIdByUserId(Long userId);
}
package com.cizhu.service.impl;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.cizhu.entity.Role;
import com.cizhu.entity.User;
import com.cizhu.mapper.RoleMapper;
import com.cizhu.mapper.UserMapper;
import com.cizhu.service.IPermissionService;
import com.cizhu.service.IRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cizhu.utils.Result;
import com.cizhu.vo.query.RoleQueryVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import java.util.List;/*** <p>* 服务实现类* </p>** @author cizhu* @since 2023-12-14*/
@Service
@Transactional
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {@Resourceprivate UserMapper userMapper;/*** 根据用户查询角色列表** @param page* @param roleQueryVo* @return*/@Overridepublic IPage<Role> findRoleListByUserId(IPage<Role> page, RoleQueryVo roleQueryVo) {//创建条件构造器QueryWrapper<Role> queryWrapper = new QueryWrapper<Role>();//角色名称queryWrapper.like(!ObjectUtils.isEmpty(roleQueryVo.getRoleName()),"role_name",roleQueryVo.getRoleName());//排序queryWrapper.orderByAsc("id");//根据用户ID查询用户信息User user = userMapper.selectById(roleQueryVo.getUserId());//如果用户不为空、且不是管理员,则只能查询自己创建的角色if(user!=null && !ObjectUtils.isEmpty(user.getIsAdmin()) && user.getIsAdmin() !=1){queryWrapper.eq("create_user",roleQueryVo.getUserId());}return baseMapper.selectPage(page,queryWrapper);}/**** 检查该角色是否已被使用* @param id :* @return boolean*/@Overridepublic boolean hasRoleCount(Long id) {return baseMapper.getRoleCountByRoleId(id) > 0 ;}/**** 删除角色* @param id :* @return boolean*/@Overridepublic boolean deleteRoleById(Long id) {// 删除角色权限关系baseMapper.deleteRolePermissionByRoleId(id);// 删除角色return baseMapper.deleteById(id) > 0 ;}/*** 保存角色权限关系** @param roleId* @param permissionIds* @return*/@Overridepublic boolean saveRolePermission(Long roleId, List<Long> permissionIds) {//删除该角色对应的权限信息baseMapper.deleteRolePermissionByRoleId(roleId);//保存角色权限return baseMapper.saveRolePermission(roleId,permissionIds)>0;}/*** 根据用户ID查询该用户拥有的角色ID** @param userId* @return*/@Overridepublic List<Long> findRoleIdByUserId(Long userId) {return baseMapper.findRoleIdByUserId(userId);}
}
package com.cizhu.controller;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cizhu.dto.RolePermissionDTO;
import com.cizhu.entity.Role;
import com.cizhu.service.IPermissionService;
import com.cizhu.service.IRoleService;
import com.cizhu.utils.Result;
import com.cizhu.vo.query.RolePermissionVo;
import com.cizhu.vo.query.RoleQueryVo;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;/*** <p>* 前端控制器* </p>** @author cizhu* @since 2023-12-14*/
@RestController
@RequestMapping("/api/role")
public class RoleController {@Resourceprivate IRoleService roleService;@Resourceprivate IPermissionService permissionService;/*** 分页查询角色列表* @param roleQueryVo* @return*/@GetMapping("/list")public Result list(RoleQueryVo roleQueryVo){//创建分页对象IPage<Role> page = new Page<Role>(roleQueryVo.getPageNo(),roleQueryVo.getPageSize());//调用分页查询方法roleService.findRoleListByUserId(page,roleQueryVo);//返回数据return Result.ok(page);}/*** 添加角色* @param role* @return*/@PostMapping("/add")public Result add(@RequestBody Role role){if(roleService.save(role)){return Result.ok().message("角色添加成功");}return Result.error().message("角色添加失败");}/*** 修改角色* @param role* @return*/@PutMapping("/update")public Result update(@RequestBody Role role){if(roleService.updateById(role)){return Result.ok().message("角色修改成功");}return Result.error().message("角色修改失败");}/*** 删除角色* @param id* @return*/@DeleteMapping("/delete/{id}")public Result delete(@PathVariable Long id){if(roleService.deleteRoleById(id)){return Result.ok().message("角色删除成功");}return Result.error().message("角色删除失败");}/*** 检查该角色是否已被使用* @param id* @return*/@GetMapping("/check/{id}")public Result check(@PathVariable Long id){//检查该角色是否已被使用if(roleService.hasRoleCount(id)){return Result.exist().message("该角色已分配给其他用户使用,无法删除");}return Result.ok();}/*** 分配权限-查询权限树数据* @param userId* @param roleId* @return*/@GetMapping("/getAssignPermissionTree")public Result getAssignPermissionTree(Long userId, Long roleId) {//调用查询权限树数据的方法RolePermissionVo permissionTree = permissionService.findPermissionTree(userId, roleId);//返回数据return Result.ok(permissionTree);}/*** 分配权限-保存权限数据** @param rolePermissionDTO* @return*/@PostMapping("/saveRoleAssign")public Result saveRoleAssign(@RequestBody RolePermissionDTO rolePermissionDTO) {if (roleService.saveRolePermission(rolePermissionDTO.getRoleId(),rolePermissionDTO.getList())) {return Result.ok().message("权限分配成功");} else {return Result.error().message("权限分配失败");}}}
2、角色列表查询
2.1 效果图
2.2页面原型代码
<template><el-main><!-- 查询条件 --><el-form :model="searchModel" ref="searchForm" label-width="80px" :inline="true" size="small"><el-form-item><el-input v-model="searchModel.roleName" placeholder="请输入角色名称"/></el-form-item><el-form-item><el-button type="primary" icon="el-icon-search" @click="search(pageNo,pageSize)">查询</el-button><el-button icon="el-icon-refresh-right" @click="resetValue()">重置</el-button><el-button type="success" icon="el-icon-plus" @click="openAddWindow()">新增</el-button></el-form-item></el-form><!-- 数据表格 --><el-table :data="roleList" :height="tableHeight" border stripe style="width: 100%; margin-bottom: 10px"><el-table-column prop="roleCode" label="角色编码" width="160" align="center"></el-table-column><el-table-column prop="roleName" label="角色名称"></el-table-column><el-table-column prop="remark" label="角色备注"></el-table-column><el-table-column label="操作" align="center" width="290"><template slot-scope="scope"><el-button icon="el-icon-edit" type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button><el-button icon="el-icon-delete" type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button><el-button icon="el-icon-setting" type="primary" size="small" @click="assignRole(scope.row)">分配权限</el-button></template></el-table-column></el-table><!-- 分页工具栏 --><el-paginationbackground@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="pageNo":page-sizes="[10, 20, 30, 40, 50]":page-size="10"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination><!-- 添加和修改角色窗口 --><system-dialog:title="roleDialog.title":visible="roleDialog.visible":width="roleDialog.width":height="roleDialog.height"@onClose="onClose"@onConfirm="onConfirm"><div slot="content"><el-form :model="role" ref="roleForm" :rules="rules" label-width="80px" :inline="false" size="small"><el-form-item label="角色编码" prop="roleCode"><el-input v-model="role.roleCode"></el-input></el-form-item><el-form-item label="角色名称" prop="roleName"><el-input v-model="role.roleName"></el-input></el-form-item><el-form-item label="角色描述"><el-input type="textarea" v-model="role.remark" :rows="5"></el-input></el-form-item></el-form></div></system-dialog><!-- 分配权限树窗口 --><system-dialog:title="assignDialog.title":visible="assignDialog.visible":width="assignDialog.width":height="assignDialog.height"@onClose="onAssignClose"@onConfirm="onAssignConfirm"><div slot="content"><el-tree ref="assignTree" :data="assignTreeData" node-key="id":props="defaultProps" empty-text="暂无数据" :show-checkbox="true":highlight-current="true" default-expand-all></el-tree></div></system-dialog></el-main>
</template>
2.3 角色api代码 role.js
import http from '@/utils/request'export function getRoutes() {// return request({// url: '/vue-element-admin/routes',// method: 'get'// })
}/**
* 查询角色列表
* @returns
*/
export async function getRoles(params) {return await http.get("/api/role/list", params)
}/*** 新增角色* @param {*} data * @returns */
export async function addRole(data) {return await http.post("/api/role/add", data)
}/*** 修改角色* @param {*} data * @returns */
export async function updateRole(data) {return await http.put("/api/role/update", data)
}/**
* 查询角色是否已被使用
* @returns
*/
export async function checkRole(params) {return await http.getRestApi("/api/role/check", params)
}/*** 删除角色* @param {*} id */
export async function deleteRole(params) {return await http.delete("/api/role/delete", params)
}/*** 查询分配权限树列表
* @returns*/
export async function getAssignTree(params) {return await http.get("/api/role/getAssignPermissionTree", params)
}/**
* 分配权限
* @returns
*/
export async function assignSave(params) {return await http.post("/api/role/saveRoleAssign", params)
}
2.4 查询角色列表代码
<script>
//导入role.js脚本
import {getRoles, addRole, updateRole, deleteRole, checkRole, getAssignTree, assignSave} from '@/api/role';
// 导入对话框组件
import SystemDialog from '@/components/system/SystemDialog.vue'
//导入末级节点脚本
import leafUtils from '@/utils/leaf'export default {name: 'roleList',//注册组件components:{ SystemDialog },data() {return {//查询条件searchModel: {roleName: '',pageNo:1,pageSize:10,userId:this.$store.getters.userId //用户ID},roleList: [], //数据列表tableHeight: 0, //表格高度pageNo: 1, //当前页码pageSize: 10, //每页显示数量total: 0, //总数量rules: {roleCode: [{ required: true, trigger: 'blur', message: '请输入角色编码' }],roleName: [{ required: true, trigger: 'blur', message: '请输入角色名称' }]},//添加和修改角色窗口属性roleDialog: {title: '',visible: false,height: 230,width: 500},//角色对象role: {id:"",roleCode:"",roleName:"",remark:"",createUser:this.$store.getters.userId},//分配权限窗口属性assignDialog: {title: '',visible: false,height: 450,width: 300},roleId: '', //角色IDassignTreeData: [], //树节点数据//树节点属性defaultProps: {children: 'children',label: 'label'}}},created() {//调用查询角色列表的方法this.search();},mounted() {this.$nextTick(() => {this.tableHeight = window.innerHeight - 220})},methods: {/*** 查询*/async search(pageNo=1,pageSize=10) {this.searchModel.pageNo = pageNothis.searchModel.pageSize = pageSizelet res = await getRoles(this.searchModel)if (res.success){//console.log(res)this.roleList = res.data.recordsthis.total = res.data.total}},/*** 每页显示数量发生变化*/handleSizeChange(size){this.pageSize = size// 查询数据this.search(this.pageNo, size)},/*** 显示第几页*/handleCurrentChange(page){this.pageNo = page// 查询数据this.search(page, this.pageSize)},/*** 重置查询条件*/resetValue(){//重置查询条件this.searchModel.roleName = ""this.search()},
获取当前用户ID store/user.js
import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken, setTokenTime } from '@/utils/auth'
import router, { resetRouter } from '@/router'const state = {token: getToken(), // 获取token信息name: '',avatar: '',introduction: '',roles: []
}const mutations = {SET_TOKEN: (state, token) => {state.token = token},SET_INTRODUCTION: (state, introduction) => {state.introduction = introduction},SET_NAME: (state, name) => {state.name = name},SET_AVATAR: (state, avatar) => {state.avatar = avatar},SET_ROLES: (state, roles) => {state.roles = roles},SET_USERUID: (state, userId) => {state.userId = userId},
}const actions = {// user loginlogin({ commit }, userInfo) {const { username, password } = userInforeturn new Promise((resolve, reject) => {login({ username: username.trim(), password: password }).then(response => {const { token, expireTime } = responsecommit('SET_TOKEN', token)setToken(token)// 设置token过期时间setTokenTime(expireTime)resolve()}).catch(error => {reject(error)})})},// get user infogetInfo({ commit, state }) {return new Promise((resolve, reject) => {getInfo(state.token).then(response => {const { data } = responseif (!data) {reject('Verification failed, please Login again.')}// 从后端反馈的data数据中解构出用户相关信息const { roles, name, avatar, introduction, id } = data// roles must be a non-empty arrayif (!roles || roles.length <= 0) {reject('getInfo: roles must be a non-null array!')}commit('SET_ROLES', roles)commit('SET_NAME', name)commit('SET_AVATAR', avatar)commit('SET_INTRODUCTION', introduction)commit('SET_USERUID', id)//将权限字段保存到sessionStorage中sessionStorage.setItem("codeList",JSON.stringify(roles));resolve(data)}).catch(error => {reject(error)})})},// user logoutlogout({ commit, state, dispatch }) {return new Promise((resolve, reject) => {logout(state.token).then(() => {commit('SET_TOKEN', '')commit('SET_ROLES', [])removeToken()resetRouter()// reset visited views and cached views// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485dispatch('tagsView/delAllViews', null, { root: true })resolve()}).catch(error => {reject(error)})})},// remove tokenresetToken({ commit }) {return new Promise(resolve => {commit('SET_TOKEN', '')commit('SET_ROLES', [])removeToken()resolve()})},// dynamically modify permissionsasync changeRoles({ commit, dispatch }, role) {const token = role + '-token'commit('SET_TOKEN', token)setToken(token)const { roles } = await dispatch('getInfo')resetRouter()// generate accessible routes map based on rolesconst accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true })// dynamically add accessible routesrouter.addRoutes(accessRoutes)// reset visited views and cached viewsdispatch('tagsView/delAllViews', null, { root: true })}
}export default {namespaced: true,state,mutations,actions
}
4、 新增和编辑角色
/*** 打开添加窗口*/openAddWindow() {//清空表单数据this.$resetForm("roleForm",this.role);this.roleDialog.title = '新增角色'//设置窗口标题this.roleDialog.visible = true//显示窗口},/*** 窗口取消事件*/onClose() {this.roleDialog.visible = false},/*** 窗口确认事件*/onConfirm() {//表单验证this.$refs.roleForm.validate(async (valid)=>{// 验证通过if (valid) {let res = null// 判断是新增还是修改操作(role.id是否为空)if (this.role.id === ""){// 发送新增角色请求res = await addRole(this.role)}else{// 发送修改角色请求res = await updateRole(this.role)}if (res.success){// 提示成功this.$message.success(res.message)// 刷新数据//this.search(this.pageNo, this.pageSize)window.location.reload();//关闭窗口this.roleDialog.visible = false;}else{this.$message.error(res.message)}}});},/*** 编辑角色*/handleEdit(row){//数据回显this.$objCopy(row, this.role); //将当前编辑的数据复制到role对象中//设置窗口标题this.roleDialog.title = "编辑角色";//显示编辑角色窗口this.roleDialog.visible = true;}
5、删除角色
/*** 删除角色*/async handleDelete(row){//查询角色是否已被使用let result = await checkRole({ id: row.id })//判断是否可以删除if (!result.success) {//提示不能删除this.$message.warning(result.message);} else {//确认是否删除let confirm = await this.$myconfirm("确定要删除该数据吗?")if (confirm) {//发送删除请求let res = await deleteRole({ id: row.id })//判断是否成功if (res.success) {//成功提示this.$message.success(res.message)//刷新this.search(this.pageNo, this.pageSize)} else {//失败提示this.$message.error(res.message)}}}},
6、分配权限
6.1 分配权限思路
6.2 分配权限回显接口
PermissionService
/*** 查询分配权限树列表* @param userId* @param roleId* @return*/RolePermissionVo findPermissionTree(Long userId, Long roleId);
PermissionServiceImp
/*** 查询分配权限树列表** @param userId* @param roleId* @return*/@Overridepublic RolePermissionVo findPermissionTree(Long userId, Long roleId) {// 1.查询当前用户信息User user = userService.getById(userId);List<Permission> list = null;//2.判断当前用户角色,如果是管理员,则查询所有权限;如果不是管理员,则只查询自己所拥有的的权限if (!ObjectUtils.isEmpty(user) && user.getIsAdmin() == 1){//查询所有权限list = baseMapper.selectList(null);}else{//根据用户ID查询list = baseMapper.findPermissionListByUserId(userId);}//3.组装成树数据List<Permission> permissionList = MenuTree.makeMenuTree(list, 0L);//4.查询要分配角色的原有权限List<Permission> rolePermissions = baseMapper.findPermissionListByRoleId(roleId);//5.找出该角色存在的数据List<Long> listIds = new ArrayList<Long>();Optional.ofNullable(list).orElse(new ArrayList<>()).stream().filter(item -> item != null).forEach(item -> {Optional.ofNullable(rolePermissions).orElse(new ArrayList<>()).stream().filter(Objects::nonNull).forEach(obj -> {// 判断两者的权限id是否一致if(item.getId().equals(obj.getId())){listIds.add(obj.getId());return;}});});//创建RolePermissionVo vo = new RolePermissionVo();vo.setPermissionList(permissionList);vo.setCheckList(listIds.toArray());return vo;}
RoleController
6.3 分配权限回显前端实现
/*** 分配权限*/async assignRole(row){this.roleId = row.id// 构建查询参数let params = {roleId: row.id, // 角色iduserId: this.$store.getters.userId // 用户id}// 发送查询分配权限菜单请求let res = await getAssignTree(params)if (res.success){//获取当前登录用户所拥有的所有菜单权限let {permissionList} = res.data//获取当前被分配角色的已经拥有的菜单权限let { checkList } = res.data//判断当前菜单是否是最后一级let { setLeaf } = leafUtils()//设置权限菜单列表let newPermissionList = setLeaf(permissionList)//设置树节点菜单数据this.assignTreeData = newPermissionList//将回调延迟到下次DOM更新循环之后执行,在修改数据之后立即使用它,然后等待DOM更新。this.$nextTick(() => {//获取树菜单的节点数据let nodes = this.$refs.assignTree.children//设置子节点this.setChild(nodes, checkList)})}//显示窗口this.assignDialog.visible = true//设置窗口标题this.assignDialog.title = `给【${row.roleName}】分配权限`},/*** 设置子节点*/setChild(childNodes, checkList) {//判断是否存在子节点if (childNodes && childNodes.length > 0){//循环所有权限for (let i=0; i< childNodes.length; i++) {//根据data或key获取树组件中的node节点let node = this.$refs.assignTree.getNode(childNodes[i])//判断使用已经拥有对应的角色权限数据if (checkList && checkList.length > 0) {//循环遍历已有的权限集合for (let j = 0; j < checkList.length; j++) {//找到已经存在的菜单权限节点if (checkList[j] == childNodes[i].id) {//如果节点是展开状态,则将树节点选中if (childNodes[i].open) {this.$refs.assignTree.setChecked(node, true)break}}}}//如果存在子节点,则递归选中if (childNodes[i].children) {this.setChild(childNodes[i].children, checkList)}}}},/*** 分配权限窗口取消事件*/onAssignClose() {this.assignDialog.visible = false},
6.4分配权限后端接口
6.4.1 RolePermissionDTO
6.4.2 RoleMapper
6.4.3 RoleMapper.xml
6.4.4 RoleService
/*** 保存角色权限关系* @param roleId* @param permissionIds* @return*/boolean saveRolePermission(Long roleId, List<Long> permissionIds);
6.4.5 RoleServiceImp
/*** 保存角色权限关系** @param roleId* @param permissionIds* @return*/@Overridepublic boolean saveRolePermission(Long roleId, List<Long> permissionIds) {//删除该角色对应的权限信息baseMapper.deleteRolePermissionByRoleId(roleId);//保存角色权限return baseMapper.saveRolePermission(roleId,permissionIds)>0;}
6.4.6 RoleController
/*** 分配权限-保存权限数据** @param rolePermissionDTO* @return*/@PostMapping("/saveRoleAssign")public Result saveRoleAssign(@RequestBody RolePermissionDTO rolePermissionDTO) {if (roleService.saveRolePermission(rolePermissionDTO.getRoleId(),rolePermissionDTO.getList())) {return Result.ok().message("权限分配成功");} else {return Result.error().message("权限分配失败");}}
6.5分配权限回显前端实现
/*** 分配权限窗口确认事件*/async onAssignConfirm() {//获取选中的节点keylet ids = this.$refs.assignTree.getCheckedKeys()//获取选中节点的父节点idlet pids = this.$refs.assignTree.getHalfCheckedKeys()//组装选中的节点ID数据let listId = ids.concat(pids)//组装参数let params = {roleId: this.roleId,list: listId}//发送请求let res = await assignSave(params)//判断是否成功if (res.success) {//关闭窗口this.assignDialog.visible = false//提示成功this.$message.success(res.message)} else {//提示失败this.$message.error(res.data)}}
相关文章:

实战10 角色管理
目录 1、角色后端接口 2、角色列表查询 2.1 效果图 2.2页面原型代码 2.3 角色api代码 role.js 2.4 查询角色列表代码 4、 新增和编辑角色 5、删除角色 6、分配权限 6.1 分配权限思路 6.2 分配权限回显接口 6.3 分配权限回显前端实现 6.4分配权限后端接口 6.4.1 R…...

Lua的底层原理与C#交互原理浅析【更新中】
目录 lua底层原理浅析 table底层原理浅析 Lua表的C语言定义 原理和实现 userdata lua和C#的交互机制(更新中) 基本介绍 Lua 与 C/C 的数据交互 Lua 调用 C/C 函数 C/C 调用 Lua 函数 基元类型传递 对象类型传递 Lua 调用 C# 总结 网上有很…...

鸿蒙项目二—— 注册和登录
此部分和上篇文章是连续剧 ,如果需要,请查看 一、注册 import http from ohos.net.http; Entry Component struct Reg {// 定义数据:State username: string "";State userpass: string "";State userpass2: string …...

Dijkstra(迪杰斯特拉)算法总结
知识概览 Dijkstra算法适用于解决所有边权都是正数的最短路问题。Dijkstra算法分为朴素的Dijkstra算法和堆优化版的Dijkstra算法。朴素的Dijkstra算法时间复杂度为,适用于稠密图。堆优化版的Dijkstra算法时间复杂度为,适用于稀疏图。稠密图的边数m和是一…...

设计模式?!
如何解决复杂性 链接:不同的设计模式实例代码(更新中) 分解 人们面对复杂性有一个常见的做法:即分而治之,将大问题分解为多个小问题,将复杂问题分解为多个简单问题。 抽象 更高层次来讲,人们处…...

Pytorch项目,肺癌检测项目之三
成功获取到数据之后,我们需要将数据放到Pytorch里面去处理,我们需要将其转换成Dataset数据集,方便去使用相同的API。要转换成Dataset数据集需要实现两个方法,方法一: 方法二: 运行比较慢的话,…...

深圳鼎信|输电线路防山火视频监控预警装置:森林火灾来袭,安全不留白!
受线路走廊制约和环保要求影响,输电线路大多建立在高山上,不仅可以减少地面障碍物和人类活动的干扰,还能提高线路的抗灾能力和可靠性。但同时也会面临其它的难题,例如森林火灾预防。今天,深圳鼎信智慧将从不同角度分析…...

【Bash/Shell】知识总结
文章目录 1. 总体认识1.1. Shell概述1.2. 第一个Shell脚本1.3. 注释 2. 变量2.1. 定义变量2.2. 使用变量2.3. 只读变量2.4. 删除变量2.5. 变量类型2.5.1. 字符串变量2.5.2. 整数变量2.5.3. 数组变量2.5.4. 环境变量2.5.5. 特殊变量 3. 输出3.1. echo命令3.2. printf命令 4. 运算…...

单例模式(C++实现)
RAII运用 只能在栈上创建对象 只能在堆上创建的对象 单例模式 设计模式 懒汉模式 解决线程安全 优化 饿汉模式 饿汉和懒汉的区别 线程安全与STL与其他锁...

ElasticSearch 聚合统计
聚合统计 度量聚合:求字段的平均值,最小值,最大值,总和等 桶聚合:将文档分成不同的桶,桶的划分可以根据字段的值,范围,日期间隔 管道聚合:在桶聚合的结果上执行进一步计…...

SpringIOC之MethodBasedEvaluationContext
博主介绍:✌全网粉丝5W+,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验✌ 博主作品:《Java项目案例》主要基于SpringBoot+MyBatis/MyBatis-plus+…...

【网络安全 | 网络协议】结合Wireshark讲解TCP三次握手
前言 TCP(传输控制协议)是一种面向连接的、可靠的传输层协议。在建立 TCP 连接时,需要进行三次握手,防止因为网络延迟、拥塞等原因导致的数据丢失或错误传输,确保双方都能够正常通信。 TCP三次握手在Wireshark数据包中…...

钦丰科技(安徽)股份有限公司携卫生级阀门管件盛装亮相2024发酵展
钦丰科技(安徽)股份有限公司携卫生级阀门管件盛装亮相2024济南生物发酵展! 展位号:2号馆A65展位 2024第12届国际生物发酵产品与技术装备展览会(济南)于3月5-7日在山东国际会展中心盛大召开,展会同期将举办30余场高质…...

Python模拟动态星空
前言 今天,我们来用Python做个星空。 一、模拟星空 1,.首先导入所需要的库: from turtle import * from random import random, randint 2.初始画面: screen Screen() width, height 800, 600 screen.setup(width, height) screen.tit…...

最新技术整理3款开源免费直播推流工具,实现实时视频推流、视频拉流,目标端可以是服务器、云平台、移动设备等(附源码)
最新技术整理3款开源免费直播推流工具,实现实时视频推流、视频拉流,目标端可以是服务器、云平台、移动设备等(附源码)。 什么是推流? 视频推流是指将实时的视频数据从一个源端发送到一个或多个目标端的过程。推流的源…...

shell ——数组
数组中可以存放多个值,Bash Shell只能支持以为数字,初始化时不需要定义数组大小。 数组中元素下标从0开始。 数组的定义 shell数组用括号来表示,元素用空格分割开。 array_name(value1 value2 value3 ...) 给一个简单数组例子 cat firs…...

GO语言基础笔记(五):包的介绍
在Go语言中,包(package)是代码组织和重用的基本单位。Go的标准库中包含了许多实用的包,它们提供了从基础数据处理到复杂网络编程等各种功能。下面是一些常用的Go标准库包及其作用的介绍: 目录 1. fmt 2. net/http …...

【Unity6.0+AI】Sentis加载模型识别手写数字案例实现
按照国际惯例,看效果: 素材准备: 自己在PS中绘制黑底白字手写字体,导出jpg,尺寸28*28! 素材设置 基本步骤 准备工作:从 ONNX Model Zoo 下载手写识别 ONNX 模型文件 【下载模型】MNIST 手写数字识别模型 mnist-12.onnx,并将其拖入项目窗口的 Assets 文件夹。 【下载模…...

VScode跑通Remix.js官方的contact程序开发过程
目录 1 引言 2 安装并跑起来 3 设置根路由 4 用links来添加风格资源 5 联系人路由的UI 6 添加联系人的UI组件 7 嵌套路由和出口 8 类型推理 9 Loader里的URL参数 10 验证参数并抛出响应 书接上回,我们已经跑通了remix的quick start项目,接下…...

讲座思考 | 周志华教授:新型机器学习神经元模型的探索
12月22日,有幸听了南京大学周志华教授题为“新型机器学习神经元模型的探索”的讲座。现场热闹非凡,大家像追星一样拿着“西瓜书”找周教授签名。周教授讲得依旧循循善诱,由浅入深,听得我很入迷,故作此记。 周教授首先就…...

docker构建镜像及项目部署
文章目录 练习资料下载一、docker基础1. 基本概念2. docker常见命令3. 命令别名4. 数据卷 二、docker自定义镜像1. 了解镜像结构2. 了解Dockerfile3. 构建Dockerfile文件,完成自定义镜像 三、网络1. docker常见网络命令2. docker自带虚拟网络3. 自定义网络 四、dock…...

ARM串口通信编程实验
完成:从终端输入选项,完成点灯关灯,打开风扇关闭风扇等操作 #include "gpio.h" int main() {char a;//char buf[128];uart4_config();gpio_config();while(1){//接收一个字符数据a getchar();//发送接收的字符putchar(a);switch(…...

MyBatis的延迟加载(懒加载)
MyBatis 中的延迟加载是指在需要时才加载对象的某些属性或关联对象,而不是在初始查询时就加载所有数据。这对于性能优化和减少不必要的数据库查询非常有用。 1. 基于配置文件的延迟加载 在 MyBatis 的 XML 映射文件中,你可以使用 lazyLoadingEnabled 和…...

嵌入式-stm32-用PWM点亮LED实现呼吸灯
一:知识前置 1.1、LED灯怎么才能亮? 答:LED需要低电平才能亮,高电平是灯灭。 1.2、LED灯为什么可以越来越亮,越来越暗? 答:这是用到不同占空比来实现的,控制LED实现呼吸灯&…...

C语言初学7:循环
while 循环 一、while 循环语法: while(condition) {statement(s); } condition 为任意非零值时都为 true。当条件为 true 时执行循环。 当条件为 false 时,退出循环,程序流将继续执行紧接着循环的下一条语句。 二、while 循环举例 #inc…...

力扣69. x 的平方根
二分查找 思路: 设置 left 指针为 0,right 指针为 x;如果 mid (right - left) / 2 left 的平方小于或等于 x,此时移动 left mid 1,并缓存当前 mid 值,可能这个 mid 就是结果,或者 x 的平方…...

go语言学习计划。
第1周:Go语言概述与环境搭建 内容:了解Go语言的历史、特点和应用场景。安装Go环境,配置工作区。实践:编写第一个Go程序,了解Go的编译运行流程。 第2周:基本语法与数据类型 内容:学习基本数据…...

设计模式之-3种常见的工厂模式简单工厂模式、工厂方法模式和抽象工厂模式,每一种模式的概念、使用场景和优缺点。
系列文章目录 设计模式之-6大设计原则简单易懂的理解以及它们的适用场景和代码示列 设计模式之-单列设计模式,5种单例设计模式使用场景以及它们的优缺点 设计模式之-3种常见的工厂模式简单工厂模式、工厂方法模式和抽象工厂模式,每一种模式的概念、使用…...

docker run --help帮助文档
文章目录 基础环境docker run --helpdocker run --help中文翻译 基础环境 环境:ubuntu20.04 x64 使用apt install docker.io安装docker docker版本: rootky:/userdata/testOnebuttonDeploy/shsany_ai/kyai_arm_ubuntu# docker -v Docker version 24.0…...

【Qt-Timer】
Qt编程指南 ■ QTimeEvent■ Qtimer■ QDateTimeEdit■ QDateTime■■ ■ QTimeEvent 1.启动定时器 定时器ID startTimer (时间间隔); int idt startTimer (250); 每隔指定的时间间隔,触发一次定时器事件。 2.定时器事件处理 virtual void timerEvent (QTimeEvent…...