当前位置: 首页 > article >正文

使用AI一步一步实现若依(23)

功能23:从后端获取路由/菜单数据

功能22:用户管理
功能21:使用axios发送请求
功能20:使用分页插件
功能19:集成MyBatis-Plus
功能18:创建后端工程
功能17:菜单管理
功能16:角色管理
功能15:用户管理
功能14:使用本地SVG图标库
功能13:侧边栏加入Logo
功能12:折叠/展开侧边栏
功能11:实现面包屑功能
功能10:添加首页菜单项
功能9:退出登录功能
功能8:页面权限控制
功能7:路由全局前置守卫
功能6:动态添加路由记录
功能5:侧边栏菜单动态显示
功能4:首页使用Layout布局
功能3:点击登录按钮实现页面跳转
功能2:静态登录界面
功能1:创建前端项目

前言

drop table if exists sys_menu;
create table sys_menu (menu_id           bigint(20)      not null auto_increment    comment '菜单ID',menu_name         varchar(50)     not null                   comment '菜单名称',parent_id         bigint(20)      default 0                  comment '父菜单ID',order_num         int(4)          default 0                  comment '显示顺序',path              varchar(200)    default ''                 comment '路由地址',component         varchar(255)    default null               comment '组件路径',query             varchar(255)    default null               comment '路由参数',route_name        varchar(50)     default ''                 comment '路由名称',is_frame          int(1)          default 1                  comment '是否为外链(0是 1否)',is_cache          int(1)          default 0                  comment '是否缓存(0缓存 1不缓存)',menu_type         char(1)         default ''                 comment '菜单类型(M目录 C菜单 F按钮)',visible           char(1)         default 0                  comment '菜单状态(0显示 1隐藏)',status            char(1)         default 0                  comment '菜单状态(0正常 1停用)',perms             varchar(100)    default null               comment '权限标识',icon              varchar(100)    default '#'                comment '菜单图标',create_by         varchar(64)     default ''                 comment '创建者',create_time       datetime                                   comment '创建时间',update_by         varchar(64)     default ''                 comment '更新者',update_time       datetime                                   comment '更新时间',remark            varchar(500)    default ''                 comment '备注',primary key (menu_id)
) engine=innodb auto_increment=2000 comment = '菜单权限表';

一.操作步骤(后端)

1.SysLoginController

src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
监听接口/getRouters

@RestController
public class SysLoginController {@Autowiredprivate ISysMenuService menuService;/*** 获取路由信息** @return 路由信息*/@GetMapping("getRouters")public AjaxResult getRouters() {return AjaxResult.success(menuService.buildMenus(1L));}
}

2.Service接口和实现

src/main/java/com/ruoyi/system/service/ISysMenuService.java

public interface ISysMenuService extends IService<SysMenu> {List<RouterVo> buildMenus(Long userId);
}

src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
复杂的逻辑将数据库表中的数据进行转换后返回(具体逻辑到后续菜单管理功能也实现后再统一梳理)

@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu>implements ISysMenuService {@Overridepublic List<RouterVo> buildMenus(Long userId) {List<SysMenu> menus = list();List<SysMenu> menuTree = getChildPerms(menus, 0);return menu2Router(menuTree);}private List<RouterVo> menu2Router(List<SysMenu> menus) {List<RouterVo> routers = new LinkedList<>();for (SysMenu menu : menus) {RouterVo router = buildBaseRouter(menu);handleChildrenRoutes(menu, router);routers.add(router);}return routers;}/*** 根据父ID获取所有子菜单(递归构建树形结构)** @param list     菜单列表(平铺结构)* @param parentId 目标父菜单ID(需与菜单ID类型一致,此处假设为long)* @return 树形结构子菜单列表*/private List<SysMenu> getChildPerms(List<SysMenu> list, long parentId) {// 1. 预构建父节点到子节点的映射(提升查找效率)Map<Long, List<SysMenu>> parentIdToChildrenMap = list.stream().collect(Collectors.groupingBy(SysMenu::getParentId));// 2. 直接获取父节点的子节点列表,并递归构建树List<SysMenu> returnList = new ArrayList<>();for (SysMenu menu : list) {if (menu.getParentId() == parentId) {buildTree(parentIdToChildrenMap, menu);returnList.add(menu);}}return returnList;}/*** 递归构建菜单树形结构(基于预生成的映射)** @param parentMap   父节点到子节点的映射* @param currentNode 当前处理节点*/private void buildTree(Map<Long, List<SysMenu>> parentMap, SysMenu currentNode) {List<SysMenu> childList = parentMap.getOrDefault(currentNode.getMenuId(), new ArrayList<>());currentNode.setChildren(childList);for (SysMenu child : childList) {buildTree(parentMap, child); // 递归处理子节点}}/*** 构建基础路由信息*/private RouterVo buildBaseRouter(SysMenu menu) {RouterVo router = new RouterVo();router.setHidden("1".equals(menu.getVisible()));router.setName(getRouteName(menu));router.setPath(getRouterPath(menu));router.setComponent(getComponent(menu));router.setQuery(menu.getQuery());router.setMeta(buildMetaData(menu));return router;}/*** 处理子路由的特殊情况*/private void handleChildrenRoutes(SysMenu menu, RouterVo router) {List<SysMenu> childMenus = menu.getChildren();// 处理目录类型if (isDirectoryWithChildren(menu, childMenus)) {router.setAlwaysShow(true);router.setRedirect("noRedirect");router.setChildren(menu2Router(childMenus));return;}// 处理根菜单if (isRootMenu(menu)) {handleRootMenu(menu, router);return;}// 处理根菜单的内部链接if (isRootInnerLink(menu)) {handleRootInnerLink(menu, router);}}/*** 构建元数据信息*/private MetaVo buildMetaData(SysMenu menu) {return new MetaVo(menu.getMenuName(),menu.getIcon(),"1".equals(menu.getIsCache()),menu.getPath());}/*** 处理菜单框架的特殊情况*/private void handleRootMenu(SysMenu menu, RouterVo router) {router.setMeta(null);RouterVo child = buildBaseRouter(menu);child.setPath(menu.getPath()); // 覆盖路径child.setComponent(menu.getComponent());child.setName(getRouteName(menu.getRouteName(), menu.getPath()));router.setChildren(Collections.singletonList(child));}/*** 处理内部链接的特殊情况*/private void handleRootInnerLink(SysMenu menu, RouterVo router) {router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));router.setPath("/");RouterVo child = new RouterVo();child.setPath(innerLinkReplaceEach(menu.getPath()));child.setComponent(UserConstants.INNER_LINK);child.setName(getRouteName(menu.getRouteName(), child.getPath()));child.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath()));router.setChildren(Collections.singletonList(child));}/* 以下为辅助方法 *//*** 判断是否为目录类型且包含子菜单*/private boolean isDirectoryWithChildren(SysMenu menu, List<SysMenu> childMenus) {return CollectionUtils.isNotEmpty(childMenus)&& UserConstants.TYPE_DIR.equals(menu.getMenuType());}/*** 判断是否为根菜单*/private boolean isRootMenu(SysMenu menu) {return isRoot(menu)&& UserConstants.TYPE_MENU.equals(menu.getMenuType())&& UserConstants.NO_FRAME.equals(menu.getIsFrame());}/*** 判断是否为根内部链接*/private boolean isRootInnerLink(SysMenu menu) {return isRoot(menu) && isInnerLink(menu);}/*** 判断是否内部展示的地址*/private boolean isInnerLink(SysMenu menu) {return UserConstants.NO_FRAME.equals(menu.getIsFrame())&& StringUtils.ishttp(menu.getPath());}/*** 判断是否为根菜单(parentId为0)*/private boolean isRoot(SysMenu menu) {return menu.getParentId() != null && menu.getParentId().intValue() == 0;}/*** 获取路由名称(优先使用配置的路由名)*/private String getRouteName(SysMenu menu) {return isRootMenu(menu)? StringUtils.EMPTY: getRouteName(menu.getRouteName(), menu.getPath());}/*** 生成最终路由名称(首字母大写)*/private String getRouteName(String routeName, String path) {return StringUtils.capitalize(StringUtils.defaultIfEmpty(routeName, path));}/*** 获取路由路径(处理特殊路径情况)*/private String getRouterPath(SysMenu menu) {if (isNonRootInnerLink(menu)) {return innerLinkReplaceEach(menu.getPath());}if (isRootDirectoryFrame(menu)) {return "/" + menu.getPath();}return isRootMenu(menu) ? "/" : menu.getPath();}/*** 判断非根菜单的内部链接*/private boolean isNonRootInnerLink(SysMenu menu) {return !isRoot(menu) && isInnerLink(menu);}/*** 判断是否为根目录框架*/private boolean isRootDirectoryFrame(SysMenu menu) {return isRoot(menu)&& UserConstants.TYPE_DIR.equals(menu.getMenuType())&& UserConstants.NO_FRAME.equals(menu.getIsFrame());}/*** 获取组件路径(智能处理不同情况)*/private String getComponent(SysMenu menu) {if (StringUtils.isNotEmpty(menu.getComponent()) && !isRootMenu(menu)) {return menu.getComponent();}if (isInnerLinkComponent(menu)) {return UserConstants.INNER_LINK;}if (isParentView(menu)) {return UserConstants.PARENT_VIEW;}return UserConstants.LAYOUT;}private boolean isInnerLinkComponent(SysMenu menu) {return StringUtils.isEmpty(menu.getComponent())&& menu.getParentId().intValue() != 0&& isInnerLink(menu);}/*** 判断是否需要父视图组件*/private boolean isParentView(SysMenu menu) {return !isRoot(menu) && UserConstants.TYPE_DIR.equals(menu.getMenuType());}/*** 处理内部链接路径格式转换(使用正则表达式优化)*/private String innerLinkReplaceEach(String path) {return path.replaceAll("^(http|https|www)([.:])+", "").replaceAll("[.:]", "/");}
}

3.Mapper

src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java

public interface SysMenuMapper extends BaseMapper<SysMenu> {
}

4.实体类SysMenu

src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java

@TableName("sys_menu")
public class SysMenu {/*** 菜单ID*/@TableId(type = IdType.AUTO)  // 主键自增private Long menuId;/*** 菜单名称*/private String menuName;/*** 父菜单名称*/@TableField(exist = false)private String parentName;/*** 父菜单ID*/private Long parentId;/*** 显示顺序*/private Integer orderNum;/*** 路由地址*/private String path;/*** 组件路径*/private String component;/*** 路由参数*/private String query;/*** 路由名称,默认和路由地址相同的驼峰格式(注意:因为vue3版本的router会删除名称相同路由,为避免名字的冲突,特殊情况可以自定义)*/private String routeName;/*** 是否为外链(0是 1否)*/private String isFrame;/*** 是否缓存(0缓存 1不缓存)*/private String isCache;/*** 类型(M目录 C菜单 F按钮)*/private String menuType;/*** 显示状态(0显示 1隐藏)*/private String visible;/*** 菜单状态(0正常 1停用)*/private String status;/*** 权限字符串*/private String perms;/*** 菜单图标*/private String icon;/*** 创建者*/private String createBy;/*** 创建时间*/private Date createTime;/*** 更新者*/private String updateBy;/*** 更新时间*/private Date updateTime;/*** 备注*/private String remark;/*** 子菜单*/@TableField(exist = false)private List<SysMenu> children = new ArrayList<>();public List<SysMenu> getChildren() {return children;}public void setChildren(List<SysMenu> children) {this.children = children;}public Long getMenuId() {return menuId;}public void setMenuId(Long menuId) {this.menuId = menuId;}public String getMenuName() {return menuName;}public void setMenuName(String menuName) {this.menuName = menuName;}public String getParentName() {return parentName;}public void setParentName(String parentName) {this.parentName = parentName;}public Long getParentId() {return parentId;}public void setParentId(Long parentId) {this.parentId = parentId;}public Integer getOrderNum() {return orderNum;}public void setOrderNum(Integer orderNum) {this.orderNum = orderNum;}public String getPath() {return path;}public void setPath(String path) {this.path = path;}public String getComponent() {return component;}public void setComponent(String component) {this.component = component;}public String getQuery() {return query;}public void setQuery(String query) {this.query = query;}public String getRouteName() {return routeName;}public void setRouteName(String routeName) {this.routeName = routeName;}public String getIsFrame() {return isFrame;}public void setIsFrame(String isFrame) {this.isFrame = isFrame;}public String getIsCache() {return isCache;}public void setIsCache(String isCache) {this.isCache = isCache;}public String getMenuType() {return menuType;}public void setMenuType(String menuType) {this.menuType = menuType;}public String getVisible() {return visible;}public void setVisible(String visible) {this.visible = visible;}public String getStatus() {return status;}public void setStatus(String status) {this.status = status;}public String getPerms() {return perms;}public void setPerms(String perms) {this.perms = perms;}public String getIcon() {return icon;}public void setIcon(String icon) {this.icon = icon;}public String getCreateBy() {return createBy;}public void setCreateBy(String createBy) {this.createBy = createBy;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime = createTime;}public String getUpdateBy() {return updateBy;}public void setUpdateBy(String updateBy) {this.updateBy = updateBy;}public Date getUpdateTime() {return updateTime;}public void setUpdateTime(Date updateTime) {this.updateTime = updateTime;}public String getRemark() {return remark;}public void setRemark(String remark) {this.remark = remark;}
}

5.工具类StringUtils

src/main/java/com/ruoyi/common/utils/StringUtils.java

public class StringUtils extends org.apache.commons.lang3.StringUtils {/*** 空字符串*/private static final String NULLSTR = "";/*** * 判断一个字符串是否为空串** @param str String* @return true:为空 false:非空*/public static boolean isEmpty(String str) {return isNull(str) || NULLSTR.equals(str.trim());}/*** * 判断一个字符串是否为非空串** @param str String* @return true:非空串 false:空串*/public static boolean isNotEmpty(String str) {return !isEmpty(str);}/*** * 判断一个对象是否为空** @param object Object* @return true:为空 false:非空*/public static boolean isNull(Object object) {return object == null;}/*** 是否为http(s)://开头** @param link 链接* @return 结果*/public static boolean ishttp(String link) {return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS);}
}

6.VO

src/main/java/com/ruoyi/system/domain/vo/RouterVo.java

public class RouterVo {/*** 路由名字*/private String name;/*** 路由地址*/private String path;/*** 是否隐藏路由,当设置 true 的时候该路由不会再侧边栏出现*/private boolean hidden;/*** 重定向地址,当设置 noRedirect 的时候该路由在面包屑导航中不可被点击*/private String redirect;/*** 组件地址*/private String component;/*** 路由参数:如 {"id": 1, "name": "ry"}*/private String query;/*** 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面*/private Boolean alwaysShow;/*** 其他元素*/private MetaVo meta;/*** 子路由*/private List<RouterVo> children;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPath() {return path;}public void setPath(String path) {this.path = path;}public boolean getHidden() {return hidden;}public void setHidden(boolean hidden) {this.hidden = hidden;}public String getRedirect() {return redirect;}public void setRedirect(String redirect) {this.redirect = redirect;}public String getComponent() {return component;}public void setComponent(String component) {this.component = component;}public String getQuery() {return query;}public void setQuery(String query) {this.query = query;}public Boolean getAlwaysShow() {return alwaysShow;}public void setAlwaysShow(Boolean alwaysShow) {this.alwaysShow = alwaysShow;}public MetaVo getMeta() {return meta;}public void setMeta(MetaVo meta) {this.meta = meta;}public List<RouterVo> getChildren() {return children;}public void setChildren(List<RouterVo> children) {this.children = children;}
}

src/main/java/com/ruoyi/system/domain/vo/MetaVo.java

public class MetaVo {/*** 设置该路由在侧边栏和面包屑中展示的名字*/private String title;/*** 设置该路由的图标,对应路径src/assets/icons/svg*/private String icon;/*** 设置为true,则不会被 <keep-alive>缓存*/private boolean noCache;/*** 内链地址(http(s)://开头)*/private String link;public MetaVo() {}public MetaVo(String title, String icon) {this.title = title;this.icon = icon;}public MetaVo(String title, String icon, boolean noCache) {this.title = title;this.icon = icon;this.noCache = noCache;}public MetaVo(String title, String icon, String link) {this.title = title;this.icon = icon;this.link = link;}public MetaVo(String title, String icon, boolean noCache, String link) {this.title = title;this.icon = icon;this.noCache = noCache;if (StringUtils.ishttp(link)) {this.link = link;}}public boolean isNoCache() {return noCache;}public void setNoCache(boolean noCache) {this.noCache = noCache;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getIcon() {return icon;}public void setIcon(String icon) {this.icon = icon;}public String getLink() {return link;}public void setLink(String link) {this.link = link;}
}

7.pom

引入工具依赖

        <!--常用工具类 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency>

8.配置文件

src/main/resources/application.yml

spring:jackson:default-property-inclusion: NON_EMPTY

9.常量类

src/main/java/com/ruoyi/common/constant/Constants.java

public class Constants {/*** http请求*/public static final String HTTP = "http://";/*** https请求*/public static final String HTTPS = "https://";
}

src/main/java/com/ruoyi/common/constant/UserConstants.java

public class UserConstants {public static final String YES_FRAME = "0";public static final String NO_FRAME = "1";/*** 菜单类型(目录)*/public static final String TYPE_DIR = "M";/*** 菜单类型(菜单)*/public static final String TYPE_MENU = "C";/*** 菜单类型(按钮)*/public static final String TYPE_BUTTON = "F";/*** Layout组件标识*/public final static String LAYOUT = "Layout";/*** ParentView组件标识*/public final static String PARENT_VIEW = "ParentView";/*** InnerLink组件标识*/public final static String INNER_LINK = "InnerLink";
}

操作步骤(前端)

10.API

src\api\login.js

import request from '@/utils/request'// 获取路由
export const getRouters = () => {return request({url: '/getRouters',method: 'get'})
}

11.前置守卫

src\permission.js

import router from './router'
import { getToken } from '@/utils/auth'
import usePermissionStore from '@/stores/permission'const whiteList = ['/login']
const whiteListDict = whiteList.reduce((acc, cur) => {acc[cur] = true;return acc;
}, {});router.beforeEach(async (to, from, next) => {if (getToken()) {if (whiteListDict[to.path]) {next({ path: '/' })} else {if (router.getRoutes().length <= 3) {try {const newRouteRecord = await usePermissionStore().generateRoutes()newRouteRecord.forEach(route => {router.addRoute(route) // 动态添加可访问路由表})next({ ...to, replace: true })} catch (error) {console.error(error)}} else {next()}}} else {// 没有tokenif (whiteListDict[to.path]) {// 在免登录白名单,直接进入next()} else {next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页}}
})

12.permissionStore

src\stores\permission.js
调用新增的API接口,并处理返回结果。

import { ref } from 'vue'
import { defineStore } from 'pinia'
import Layout from '@/layout/index.vue'
import { constantRoutes } from '@/router'
import { getRouters } from '@/api/login'
import { isHttp } from '@/utils/ruoyi'// 匹配views里面所有的.vue文件
const modules = import.meta.glob('@/views/**/*.vue')const usePermissionStore = defineStore('permission', () => {const arrayForMenu = ref([])const arrayForRouter = ref([])// 异步操作const generateRoutes = async () => {const res = await getRouters()const menuData = JSON.parse(JSON.stringify(res.data))const routeData = JSON.parse(JSON.stringify(res.data))arrayForMenu.value = constantRoutes.concat(menuData)const routeDataFilter = filterAsyncRouter(routeData)arrayForRouter.value = routeDataFilterreturn routeDataFilter}return {arrayForMenu,arrayForRouter,generateRoutes}
})/*** 异步路由过滤器 - 核心路由配置处理器* 功能: * 1. 递归处理路由配置树,动态加载Vue组件* 2. 特殊处理Layout组件和ParentView结构* 3. 规范化路由配置结构* * @param {Array} asyncRouterArr - 原始异步路由配置数组* @returns {Array} 处理后的标准化路由配置数组* * 处理逻辑:* 1. 遍历路由配置,处理子路由配置* 2. 动态加载组件(转换字符串路径为真实组件)* 3. 递归处理嵌套子路由* 4. 清理空children和redirect属性*/
const filterAsyncRouter = (asyncRouterArr) => {return asyncRouterArr.filter(routeMap => {if (isHttp(routeMap.path)) {return false;}// 处理子路由if (routeMap.children) {routeMap.children = filterChildrenForRouter(routeMap.children);}if (routeMap.component) {// Layout 组件特殊处理if (routeMap.component === 'Layout') {routeMap.component = Layout} else {routeMap.component = loadView(routeMap.component)}}// 递归处理子路由if (routeMap.children?.length) {filterAsyncRouter(routeMap.children);} else {delete routeMap.children;delete routeMap.redirect;}return true;});
}/*** 子路由结构转换器 - 路由层级扁平化处理器* 功能:* 1. 处理ParentView类型的路由结构* 2. 合并嵌套子路由路径* 3. 将多级路由转换为扁平结构* * @param {Array} childrenArr - 原子路由配置数组* @returns {Array} 转换后的扁平化子路由数组* * 处理逻辑:* 1. 当遇到ParentView组件时,将其子路由提升到当前层级* 2. 合并父级路径到子路由path* 3. 保留普通路由配置*/
const filterChildrenForRouter = (childrenArr) => {let children = [];childrenArr.forEach(el => {if (el.children?.length && el.component === 'ParentView') {children.push(...el.children.map(c => ({...c,path: `${el.path}/${c.path}`})));return;}children.push(el);});return children;
}/*** 动态组件加载器 - 模块解析器* 功能:* 根据组件路径字符串动态加载Vue组件* * @param {string} view - 组件路径字符串(例: "system/user/index")* @returns {Component} Vue组件* * 处理逻辑:* 1. 遍历预编译的模块集合(modules)* 2. 匹配views目录下的对应组件文件* 3. 返回组件异步加载函数*/
const loadView = (view) => {let res;for (const path in modules) {const dir = path.split('views/')[1].split('.vue')[0];if (dir === view) {res = () => modules[path]();}}return res;
}export default usePermissionStore

13.工具类

src\utils\ruoyi.js

/*** 判断url是否是http或https * @param {string} url* @returns {Boolean}*/
export function isHttp(url) {return typeof url === 'string' && url.startsWith('http');
}

二.功能验证

运行项目,浏览器访问http://localhost:5173/index
在这里插入图片描述
侧边栏显示正常。

相关文章:

使用AI一步一步实现若依(23)

功能23&#xff1a;从后端获取路由/菜单数据 功能22&#xff1a;用户管理 功能21&#xff1a;使用axios发送请求 功能20&#xff1a;使用分页插件 功能19&#xff1a;集成MyBatis-Plus 功能18&#xff1a;创建后端工程 功能17&#xff1a;菜单管理 功能16&#xff1a;角色管理…...

C语言的内存模型 (堆区,栈区,静态区,常量区,代码区 )概念讲解

C语言的内存模型分为5个区&#xff1a; 堆区&#xff0c;栈区&#xff0c;静态区&#xff0c;常量区&#xff0c;代码区 。 1、栈区 存放函数的参数值&#xff0c;局部变量等。 由编译器自动分配和释放。通常在函数执行完了就释放了。其操作方式类似于数据结构中的栈。栈内存…...

Vue3 知识点总结

Vue3 知识点总结 1. 核心概念 1.1 Composition API 1.1.1 setup 函数 setup是Vue3中的新的配置项&#xff0c;是组件内使用Composition API的入口在setup中定义的变量和方法需要return才能在模板中使用setup执行时机在beforeCreate之前&#xff0c;this不可用 export defa…...

第一天学爬虫

阅读提示&#xff1a;我今天才开始尝试爬虫&#xff0c;写的不好请见谅。 一、准备工具 requests库&#xff1a;发送HTTP请求并获取网页内容。BeautifulSoup库&#xff1a;解析HTML页面并提取数据。pandas库&#xff1a;保存抓取到的数据到CSV文件中。 二、爬取步骤 发送请求…...

W、M、C练题笔记(持续更新中)

web here are the flag 点击&#xff0c;页面跳转404.php&#xff0c;用bp抓包访问/flag.php页面&#xff0c;得到flag用base64解码 TryToFindFlag 打开后查看源代码 发现是robots协议&#xff0c;访问robots.txt 访问flllaaa......&#xff0c;得到空白页面&#xff0c;查看…...

CVE-2021-45232未授权接口练习笔记

CVE-2021-45232 是 Apache APISIX Dashboard 中的一个严重权限漏洞&#xff0c;类似于攻击者无需密码即可拿到整个网关系统的“万能钥匙”。攻击者利用此漏洞&#xff0c;可直接操控网关流量转发规则&#xff0c;甚至远程执行代码&#xff0c;引发服务器沦陷。 默认账户密码导致…...

贪心算法——c#

贪心算法通俗解释 贪心算法是一种"每一步都选择当前最优解"的算法策略。它不关心全局是否最优&#xff0c;而是通过局部最优的累积来逼近最终解。优点是简单高效&#xff0c;缺点是可能无法得到全局最优解。 一句话秒懂 自动售货机找零钱&#xff1a;用最少数量的…...

Retrofit中scalars转换html为字符串

简介 在Retrofit中&#xff0c;如果你想直接获取HTML或其他文本格式的响应内容而不是将其映射到一个模型类&#xff0c;ScalarsConverterFactory 就派上用场了。ScalarsConverterFactory 是一个转换器工厂&#xff0c;它能够将响应体转换为Java基本类型如String、Integer或Byte…...

【微服务架构】SpringCloud(七):配置中心 Spring Cloud Config

文章目录 配置中心为什么需要配置中心配置中心介绍 服务搭建基于GITHUB1.创建仓库2.新建微服务作为配置中心服务3.启动测试拉取 匹配规则分支读取 客户端配置配置文件引入依赖使用远程配置 刷新配置手动配置热更新自动刷新erlang安装RabbitMQ安装环境变量管理界面服务配置测试 …...

突破次元壁:基于Unity的MCP方案,用Claude一键生成完整游戏

在当今快速发展的技术领域,AI与游戏开发的结合正带来前所未有的创新。今天,我们将介绍一种革命性的解决方案——基于Unity的MCP(Model-Code-Pipeline)方案,通过Claude的强大自然语言处理能力,直接生成可玩的游戏!只需简单输入提示词,AI就能自动打开Unity并为你开发出一…...

Linux学习笔记(应用篇二)

基于I.MX6ULL.MINI开发板 开发板与电脑相互通信电脑与开发板互传文件 开发板与电脑相互通信 用网线将电脑与开发板连接 本人使用的是Ubuntu系统&#xff0c;不是虚拟机 一般来说刚开始电脑和开发板是ping不通的 首先查看电脑的 IP WinR&#xff0c;cmd调出终端 我使用的是…...

记录一次部署k3s后,服务404 page not found,nginx显示正常

服务部署k3s后&#xff0c;正常入口端怎么返回都是80&#xff0c;且返回错误 TRAEFIK DEFAULT CERT ERR_CERT_AUTHORITY_INVALID ngnix显示也是正常&#xff0c;怎么找也找不到问题 后来通过 iptables -L -n -t nat|grep 80 发现入口端流量被DNAT转到新的服务 而k3s中&#…...

mac上安装nvm及nvm的基本语法使用!!

种一棵树&#xff0c;最好是十年前&#xff0c;其次是现在&#xff01;想要改变&#xff0c;从此刻开始&#xff0c;一切都不晚&#xff01; 目录 nvm是什么&#xff1f;前提条件&#xff1a;安装homebrew如果系统已经有node版本&#xff1a;在mac上安装nvm&#xff1a;用nvm安…...

(基本常识)C++中const与引用——面试常问

作者&#xff1a;求一个demo 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 内容通俗易懂&#xff0c;没有废话&#xff0c;文章最后是面试常问内容&#xff08;建议通过标题目录学习&#xff09; 废话不多…...

ES 加入高亮设置

searchTextQueryOne new MatchQuery.Builder().field(searchFieldOne).query(searchText).build();// 帮助中心文档切分 只查询6条Integer finalTopK 10;List<String> newReturnFileds returnFields;newReturnFileds.add("kid"); // 需要返回kidHighlight h…...

dfs(深度优先)——太抽象了

1. 两种方法 #include<bits/stdc.h> using namespace std; //void dfs(int index,int n,vector<int> current) //{ // if(index>n){ // for(int i0;i<current.size();i){ // cout<<current[i]<<" "; // } // cout<<endl;…...

5分钟学会interface(纯标题党)

Golang中的interface&#xff08;接口&#xff09; 接口的定义 在 Go 语言中&#xff0c;接口&#xff08;interface&#xff09; 是一种特殊的类型&#xff0c;它定义了一组方法&#xff0c;而不关心具体的实现。任何类型只要实现了这些方法&#xff0c;就可以被认为满足这个…...

deepseek实战教程-第五篇支持deepseek的大模型应用安装及使用

目录 一.AnythingLLM 1.2 设置管理 1.3 关联知识库到对话 二.Cherrystudio 2.1 添加知识库文件 2.1.1 cherrystudio 2.1.2 anythingLLM 2.2 和知识库对话 三.AI产品落地之DIFY 3.1 安装Docker 3.2 下载dify压缩包 3.3 文件解压缩 3.4 文件重命名 3.5 设置模型 …...

嵌入式Linux RK3399启动模式及分区技术详解

嵌入式Linux RK3399启动模式及分区技术详解 一、RK3399启动模式分析 RK3399作为瑞芯微推出的高性能嵌入式处理器&#xff0c;其启动模式分为闭源与开源两种方案&#xff0c;核心区别在于前级Loader的实现方式。 1. 闭源启动流程 采用瑞芯微官方提供的闭源固件&#xff0c;流…...

python --face_recognition(人脸识别,检测,特征提取,绘制鼻子,眼睛,嘴巴,眉毛)/活体检测

dlib 安装方法 之前博文 https://blog.csdn.net/weixin_44634704/article/details/141332644 环境: python3.8 opencv-python4.11.0.86 face_recognition1.3.0 dlib19.24.6人脸检测 import cv2 import face_recognition# 读取人脸图片 img cv2.imread(r"C:\Users\123\…...

redis解决缓存穿透/击穿/雪崩

文章目录 1.缓存穿透1.1 概念1.2 解决方案1.2.1 缓存空对象1.2.2 布隆过滤 1.2 店铺查询使用缓存穿透解决方案1.2.1 流程 2.缓存雪崩2.1 什么是缓存雪崩&#xff1f;2.2 雪崩解决方案 3.缓存击穿3.1 什么是缓存击穿&#xff1f;3.2解决方案3.2.1 基于互斥锁解决缓存击穿问题&am…...

特征工程自动化(FeatureTools实战)

目录 特征工程自动化(FeatureTools实战)1. 引言2. 项目背景与意义2.1 特征工程的重要性2.2 自动化特征工程的优势2.3 工业级数据处理需求3. 数据集生成与介绍3.1 数据集构成3.2 数据生成方法4. 自动化特征工程理论基础4.1 特征工程的基本概念4.2 FeatureTools库简介4.3 关键公…...

哈希表简单例子

一、题意 给定一个整数数组&#xff0c;判断数组中是否存在重复的元素。如果存在一值在数组中出现至少两次&#xff0c;函数返回 True &#xff1b;如果数组中每个元素都不相同&#xff0c;则返回 False 。 输入: [1, 2, 3, 1] 输出: True 输入: [1, 2, 3, 4] 输出: False …...

利用GitHub Pages快速部署前端框架静态网页

文章目录 前言GitHub Pages 来部署前端框架&#xff08;Vue 3 Vite&#xff09;项目1、配置 GitHub Pages 部署2、将项目推送到 GitHub3、部署到 GitHub Pages4、访问部署页面5、修改代码后的更新部署顺序 前言 可以先参考&#xff1a; 使用 GitHub Pages 快速部署静态网页: …...

《TCP/IP网络编程》学习笔记 | Chapter 22:重叠 I/O 模型

《TCP/IP网络编程》学习笔记 | Chapter 22&#xff1a;重叠 I/O 模型 《TCP/IP网络编程》学习笔记 | Chapter 22&#xff1a;重叠 I/O 模型理解重叠 I/O 模型重叠 I/O本章讨论的重叠 I/O 的重点不在于 I/O 创建重叠 I/O 套接字执行重叠 I/O 的 WSASend 函数进行重叠 I/O 的 WSA…...

Skynet 中 snlua 服务启动整体流程分析

前言&#xff1a; 在 Skynet 中&#xff0c;Lua 扮演了极其重要的角色。Skynet 大多数业务逻辑都跑在一个个 Lua 服务里&#xff0c;而能够将 Lua 环境嵌入到 Skynet 框架下&#xff0c;并与 Skynet 消息调度机制完美结合&#xff0c;正是 snlua 服务所承担的核心功能。 本文将…...

python每日十题(10)

在Python语言中&#xff0c;源文件的扩展名&#xff08;后缀名&#xff09;一般使用.py。 保留字&#xff0c;也称关键字&#xff0c;是指被编程语言内部定义并保留使用的标识符。Python 3.x有35个关键字&#xff0c;分别为&#xff1a;and&#xff0c;as&#xff0c;assert&am…...

基于大模型预测的初治菌阳肺结核诊疗方案研究报告

目录 一、引言 1.1 研究背景与意义 1.2 研究目的 二、初治菌阳肺结核概述 2.1 疾病定义与病理机制 2.2 流行病学特征 2.3 传统诊疗方法与局限性 三、大模型在初治菌阳肺结核预测中的应用原理 3.1 大模型技术简介 3.2 数据收集与预处理 3.3 模型构建与训练 3.4 模型…...

嵌入式系统应用-音乐播放器-按键版本

音乐播放器-按键版本 1 背景介绍1.1 导入音乐播放器1.2 导入按键扫描按键包 2 功能设计2.1 需求分析2.2 程序架构设计2.3 相关知识储备 3 代码编写3.1 led代码实现3.2 按键扫描3.3 音乐播放线程 4 低功耗设计4.1 睡眠模式4.2 停止模式4.3 待机模式 1 背景介绍 这个音乐播放器分…...

LabVIEW液压振动锤控制系统

在现代工程机械领域&#xff0c;液压振动锤的高效与精准控制日益显得重要。本文通过LabVIEW软件&#xff0c;展开液压振动锤启停共振控制技术的研究与应用&#xff0c;探讨如何通过改进控制系统来优化液压振动锤的工作性能&#xff0c;确保其在复杂工况下的稳定性与效率。 ​ …...